Bier.CLI.Config (bier v0.1.0)

Copy Markdown View Source

The PostgREST config dialect ↔ Bier boundary.

spec/0 is the single source of truth: one entry per PostgREST config key that Bier implements, carrying its PGRST_* env var, deprecated aliases, value type, and PostgREST default (used for --dump-config). Keys Bier does not implement are intentionally absent — their conformance cases stay deferred.

Summary

Functions

Coerce a raw value (string from env/file, or already-typed from the file parser) to the typed value for kind. :unset marks an absent optional value (falls back to default). Enum mismatches return PostgREST's message.

Postgrex connection options for a resolved config: the parsed db-uri fields, with missing fields filled from the libpq-style PG* environment variables — PostgREST connects through libpq, which applies exactly these fallbacks — then localhost/5432 defaults. Like libpq, a missing database name falls back to the user name.

The pgrst.* setting names the in-database config source accepts — the k = ANY(...) filter of the role-settings query (PostgREST Config/Database.hs dbSettingsNames).

Render a resolved config map as PostgREST --dump-config text: one key = value line per spec key plus one per app.settings.<name> entry, sorted by key for determinism (so the output is reparse-stable).

Resolve every spec key from flags > db > env > file > default, applying aliases and coercion, then run the shared semantic validators. Returns the resolved %{kebab_key => typed_value} map, or {:error, message} on a fatal problem.

The config key spec table (one entry per implemented PostgREST key).

Translate a resolved config map into a keyword list for Bier.start_link/1. :unset optional keys are omitted so Bier's own defaults apply. db-uri is parsed into discrete connection fields; server-port maps to router[:port].

Like to_start_opts/1, but additionally runs the options through Bier.Config.new/2 (Bier's full boot-time schema + semantic validators), returning {:error, message} instead of letting Bier.start_link/1 raise.

Types

kind()

@type kind() ::
  :string
  | :opt_string
  | :int
  | :opt_int
  | :bool
  | :csv
  | :csv_emptyable
  | {:enum_atom, atom()}
  | {:enum_str, atom()}

Functions

coerce(arg1, v)

@spec coerce(kind(), term()) :: {:ok, term()} | {:error, String.t()}

Coerce a raw value (string from env/file, or already-typed from the file parser) to the typed value for kind. :unset marks an absent optional value (falls back to default). Enum mismatches return PostgREST's message.

connection_opts(resolved, env)

@spec connection_opts(map(), map()) :: keyword()

Postgrex connection options for a resolved config: the parsed db-uri fields, with missing fields filled from the libpq-style PG* environment variables — PostgREST connects through libpq, which applies exactly these fallbacks — then localhost/5432 defaults. Like libpq, a missing database name falls back to the user name.

db_settings_names()

@spec db_settings_names() :: [String.t()]

The pgrst.* setting names the in-database config source accepts — the k = ANY(...) filter of the role-settings query (PostgREST Config/Database.hs dbSettingsNames).

dump(resolved)

@spec dump(map()) :: iodata()

Render a resolved config map as PostgREST --dump-config text: one key = value line per spec key plus one per app.settings.<name> entry, sorted by key for determinism (so the output is reparse-stable).

load(env, file, flags, db \\ %{})

@spec load(map(), map() | nil, map(), map()) :: {:ok, map()} | {:error, String.t()}

Resolve every spec key from flags > db > env > file > default, applying aliases and coercion, then run the shared semantic validators. Returns the resolved %{kebab_key => typed_value} map, or {:error, message} on a fatal problem.

env is a %{"PGRST_*" => string} map (the caller supplies it — the core never reads System.get_env/0). file is nil or a %{kebab_key => raw} map (already parsed). flags is a %{kebab_key => raw} map of command-line overrides. db is the in-database config source — a %{kebab_key => string} map read from ALTER ROLE ... SET pgrst.* (Bier.CLI.DbSettings); it beats env and file (PostgREST Config.hs overrideFromDbOrEnvironment: dbConf <|> env) but only for db_settings_names/0 keys.

spec()

@spec spec() :: [map()]

The config key spec table (one entry per implemented PostgREST key).

to_start_opts(resolved)

@spec to_start_opts(map()) :: keyword()

Translate a resolved config map into a keyword list for Bier.start_link/1. :unset optional keys are omitted so Bier's own defaults apply. db-uri is parsed into discrete connection fields; server-port maps to router[:port].

validated_start_opts(resolved)

@spec validated_start_opts(map()) :: {:ok, keyword()} | {:error, String.t()}

Like to_start_opts/1, but additionally runs the options through Bier.Config.new/2 (Bier's full boot-time schema + semantic validators), returning {:error, message} instead of letting Bier.start_link/1 raise.

The parse layer deliberately accepts values Bier's schema rejects — e.g. db-max-rows = 0 or a non-positive server-port (:pos_integer means ≥ 1) — because --dump-config must print whatever was parsed (conformance-pinned). Boot paths call this instead of to_start_opts/1 so those values become a clean fatal message rather than a raised MatchError/ArgumentError.