file API

file

package

API reference for the file package.

S
struct

Provider

Provider implements configuration.Provider for JSON files.

core/configuration/source/file/provider.go:19-22
type Provider struct

Example

p := file.New("config.json")
data, err := p.Load(ctx)

Methods

Name
Method

Name returns "file".

Returns

string
func (*Provider) Name() string
{
	return "file"
}
Load
Method

Load reads and parses a JSON configuration file, returning a flat key-value map. Nested JSON objects are flattened with colon-separated keys (e.g. "db:host").

Parameters

Returns

map[string]any
error
func (*Provider) Load(ctx context.Context) (map[string]any, error)
{
	if err := ctx.Err(); err != nil {
		return nil, err
	}
	file, err := os.Open(p.Path)
	if err != nil {
		return nil, err
	}
	defer file.Close()
	data, err := io.ReadAll(io.LimitReader(file, maxFileSize+1))
	if err != nil {
		return nil, err
	}
	if len(data) > maxFileSize {
		return nil, errors.New("configuration: file exceeds 4 MiB limit")
	}

	var parsed map[string]any
	if err := json.Unmarshal(data, &parsed); err != nil {
		return nil, err
	}

	flat := make(map[string]any)
	flatten("", parsed, flat)
	return flat, nil
}

Fields

Name Type Description
Path string
F
function

New

New creates a new JSON file provider.

Parameters

path
string

Returns

core/configuration/source/file/provider.go:25-27
func New(path string) *Provider

{
	return &Provider{Path: path}
}
F
function

flatten

Parameters

prefix
string
src
map[string]any
dst
map[string]any
core/configuration/source/file/provider.go:63-75
func flatten(prefix string, src map[string]any, dst map[string]any)

{
	for k, v := range src {
		key := k
		if prefix != "" {
			key = prefix + ":" + k
		}
		if nested, ok := v.(map[string]any); ok {
			flatten(key, nested, dst)
		} else {
			dst[key] = v
		}
	}
}
F
function

TestProviderLoadFlattensJSON

Parameters

core/configuration/source/file/provider_test.go:10-26
func TestProviderLoadFlattensJSON(t *testing.T)

{
	path := filepath.Join(t.TempDir(), "config.json")
	if err := os.WriteFile(path, []byte(`{"db":{"host":"localhost","port":5432},"debug":true}`), 0644); err != nil {
		t.Fatalf("WriteFile() error = %v", err)
	}

	data, err := New(path).Load(context.Background())
	if err != nil {
		t.Fatalf("Load() error = %v", err)
	}
	if data["db:host"] != "localhost" {
		t.Fatalf("db:host = %v, want localhost", data["db:host"])
	}
	if data["debug"] != true {
		t.Fatalf("debug = %v, want true", data["debug"])
	}
}
F
function

TestProviderLoadMissingFile

Parameters

core/configuration/source/file/provider_test.go:28-33
func TestProviderLoadMissingFile(t *testing.T)

{
	_, err := New(filepath.Join(t.TempDir(), "missing.json")).Load(context.Background())
	if err == nil {
		t.Fatal("Load() error = nil, want error")
	}
}
F
function

TestProviderLoadRejectsOversizedFile

Parameters

core/configuration/source/file/provider_test.go:35-52
func TestProviderLoadRejectsOversizedFile(t *testing.T)

{
	path := filepath.Join(t.TempDir(), "large.json")
	file, err := os.Create(path)
	if err != nil {
		t.Fatal(err)
	}
	if err := file.Truncate(maxFileSize + 1); err != nil {
		file.Close()
		t.Fatal(err)
	}
	if err := file.Close(); err != nil {
		t.Fatal(err)
	}

	if _, err := New(path).Load(context.Background()); err == nil {
		t.Fatal("Load() accepted an oversized file")
	}
}