@btravstack/config
@btravstack/config
Classes
ConfigFieldInvalid
Defined in: packages/config/src/config.ts:76
Why one variable's value is not the value a field wanted — the message ConfigInvalid reports against it.
Extends
TaggedErrorInstance<"ConfigFieldInvalid", {reason:string; }>
Constructors
Constructor
new ConfigFieldInvalid(args): ConfigFieldInvalid;Defined in: node_modules/.pnpm/unthrown@5.8.0/node_modules/unthrown/dist/index.d.mts:2034
Parameters
| Parameter | Type |
|---|---|
args | object & object |
Returns
Inherited from
TaggedError("ConfigFieldInvalid")<{
readonly reason: string;
}>.constructorProperties
| Property | Modifier | Type | Overrides | Inherited from | Defined in |
|---|---|---|---|---|---|
_tag | readonly | "ConfigFieldInvalid" | - | TaggedError("ConfigFieldInvalid")._tag | node_modules/.pnpm/unthrown@5.8.0/node_modules/unthrown/dist/index.d.mts:2011 |
cause? | public | unknown | - | TaggedError("ConfigFieldInvalid").cause | node_modules/.pnpm/typescript@6.0.3/node_modules/typescript/lib/lib.es2022.error.d.ts:24 |
message | public | string | TaggedError("ConfigFieldInvalid").message | - | packages/config/src/config.ts:79 |
name | public | string | - | TaggedError("ConfigFieldInvalid").name | node_modules/.pnpm/typescript@6.0.3/node_modules/typescript/lib/lib.es5.d.ts:1074 |
reason | readonly | string | - | TaggedError("ConfigFieldInvalid").reason | packages/config/src/config.ts:77 |
stack? | public | string | - | TaggedError("ConfigFieldInvalid").stack | node_modules/.pnpm/typescript@6.0.3/node_modules/typescript/lib/lib.es5.d.ts:1076 |
ConfigInvalid
Defined in: packages/config/src/config.ts:35
A configuration port could not be bound: the environment is wrong, not the code. runMain maps it to sysexits(3)'s EX_CONFIG (78) rather than the generic startup 1, and its message names every offending variable.
Extends
TaggedErrorInstance<"ConfigInvalid", {issues: readonlyConfigIssue[];port:string; }>
Constructors
Constructor
new ConfigInvalid(args): ConfigInvalid;Defined in: node_modules/.pnpm/unthrown@5.8.0/node_modules/unthrown/dist/index.d.mts:2034
Parameters
| Parameter | Type |
|---|---|
args | object & object |
Returns
Inherited from
TaggedError("ConfigInvalid")<{
readonly port: string;
readonly issues: readonly ConfigIssue[];
}>.constructorProperties
| Property | Modifier | Type | Overrides | Inherited from | Defined in |
|---|---|---|---|---|---|
_tag | readonly | "ConfigInvalid" | - | TaggedError("ConfigInvalid")._tag | node_modules/.pnpm/unthrown@5.8.0/node_modules/unthrown/dist/index.d.mts:2011 |
cause? | public | unknown | - | TaggedError("ConfigInvalid").cause | node_modules/.pnpm/typescript@6.0.3/node_modules/typescript/lib/lib.es2022.error.d.ts:24 |
issues | readonly | readonly ConfigIssue[] | - | TaggedError("ConfigInvalid").issues | packages/config/src/config.ts:37 |
message | public | string | TaggedError("ConfigInvalid").message | - | packages/config/src/config.ts:39 |
name | public | string | - | TaggedError("ConfigInvalid").name | node_modules/.pnpm/typescript@6.0.3/node_modules/typescript/lib/lib.es5.d.ts:1074 |
port | readonly | string | - | TaggedError("ConfigInvalid").port | packages/config/src/config.ts:36 |
stack? | public | string | - | TaggedError("ConfigInvalid").stack | node_modules/.pnpm/typescript@6.0.3/node_modules/typescript/lib/lib.es5.d.ts:1076 |
Env
Defined in: packages/config/src/config.ts:19
The environment, as a service. The kernel provides this port to every graph it boots — process.env by default, StartOptions.env for a test — so nothing else in an application touches process.env.
Extends
PortInstance<"Env",Readonly<Record<string,string|undefined>>>
Constructors
Constructor
new Env(): Env;Defined in: packages/di/dist/index.d.mts:16
Returns
Inherited from
Port("Env")<Environment>.constructorProperties
Type Aliases
ConfigField
type ConfigField<T> = object;Defined in: packages/config/src/config.ts:92
One environment variable, read into a value: parse receives the raw string (or undefined when unset) and answers the value or the reason it is not one. Compose them with Config.object.
check is the same field's rule applied to a value that is ALREADY a T — a pin, or a default — so the two routes into a configuration cannot disagree about what is valid. It is optional: a hand-written field keeps compiling and simply accepts whatever it is handed.
Type Parameters
| Type Parameter |
|---|
T |
Properties
| Property | Modifier | Type | Defined in |
|---|---|---|---|
check? | readonly | (value) => Result<T, ConfigFieldInvalid> | packages/config/src/config.ts:95 |
parse | readonly | (raw) => Result<T, ConfigFieldInvalid> | packages/config/src/config.ts:94 |
variable | readonly | string | packages/config/src/config.ts:93 |
ConfigIssue
type ConfigIssue = object;Defined in: packages/config/src/config.ts:25
The one issue shape a configuration schema reports: Standard Schema's Issue, restated structurally so this package depends on nothing.
Properties
| Property | Modifier | Type | Defined in |
|---|---|---|---|
message | readonly | string | packages/config/src/config.ts:26 |
path? | readonly | ReadonlyArray< | PropertyKey | { key: PropertyKey; }> | packages/config/src/config.ts:27 |
ConfigSchema
type ConfigSchema<Input, Output> = object;Defined in: packages/config/src/config.ts:58
The slice of Standard Schema (v1) this package speaks — structurally, so a zod, valibot or arktype schema is accepted with no adapter, and so is anything Config.object builds.
Type Parameters
| Type Parameter |
|---|
Input |
Output |
Properties
| Property | Modifier | Type | Defined in |
|---|---|---|---|
~standard | readonly | object | packages/config/src/config.ts:59 |
~standard.types? | readonly | object | packages/config/src/config.ts:71 |
~standard.types.input | readonly | Input | packages/config/src/config.ts:71 |
~standard.types.output | readonly | Output | packages/config/src/config.ts:71 |
~standard.validate | readonly | (value) => | { issues?: undefined; value: Output; } | { issues: readonly ConfigIssue[]; } | Promise< | { issues?: undefined; value: Output; } | { issues: readonly ConfigIssue[]; }> | packages/config/src/config.ts:62 |
~standard.vendor | readonly | string | packages/config/src/config.ts:61 |
~standard.version | readonly | 1 | packages/config/src/config.ts:60 |
Environment
type Environment = Readonly<Record<string, string | undefined>>;Defined in: packages/config/src/config.ts:12
The process environment as it actually arrives: flat, and every value a string or absent.
Variables
Config
const Config: object;Defined in: packages/config/src/config.ts:190
Configuration, the twelve-factor way: typed values bound from the environment, validated once as the graph is built, and injected like any other service.
Config.object({...}) describes a slice of the environment as a schema — any Standard Schema does as well — and Config.provider(Port)(schema) turns it into a provider that reads Env and answers ConfigInvalid.
Type Declaration
| Name | Type | Default value | Description | Defined in |
|---|---|---|---|---|
boolean() | (variable, options) => ConfigField<boolean> | - | A flag: true/false, 1/0, yes/no or on/off, case-insensitive. Anything else is an error rather than a falsy reading — a deployment that wrote HTTP_COMPRESSION=enabled meant to turn it on. | packages/config/src/config.ts:226 |
integer() | (variable, options) => ConfigField<number> | - | A whole number, optionally bounded (both bounds inclusive). | packages/config/src/config.ts:210 |
list() | (variable, options) => ConfigField<readonly string[]> | - | A comma-separated list, each entry trimmed and empty entries dropped, so "a, b," is ["a", "b"]. min (default 1) is the floor a shorter list is named against — a variable that lists nothing is a deployment mistake, not an empty list. | packages/config/src/config.ts:251 |
object() | <F>(fields) => ConfigSchema<Readonly<Record<string, string | undefined>>, { readonly [K in string | number | symbol]: F[K] extends ConfigField<T> ? T : never }> | - | A record of fields, as a Standard Schema over the environment. Every field is read, so one validation names every offending variable at once — an operator fixes the deployment in one round trip. | packages/config/src/config.ts:299 |
parse() | <Output>(port, schema) => (env) => AsyncResult<Output, ConfigInvalid> | - | Validates env against schema; the issues become one ConfigInvalid naming port. This is the step Config.provider performs, on its own — for a piece that is already its own provider and has no second port to hang a Config.provider on, such as a starter binding its options inside a make arm. | packages/config/src/config.ts:346 |
pinned() | <T>(value, field) => ConfigField<T> | - | field, unless value is given — then a field answering value and reading nothing. Explicit beats environment beats default, per field: http({ port: 0 }) still reads HOST. The pin is CHECKED against the field's own rule, so a value the deployment route would refuse is refused here too, with the same message. Without that, a pinned NaN body limit turned a trust boundary off in silence — size > NaN is false — and the composition root was the one input to the configuration system nothing validated. | packages/config/src/config.ts:285 |
port() | (variable, options) => ConfigField<number> | - | A TCP port: a whole number the OS will accept, 0 (an ephemeral bind) included. | packages/config/src/config.ts:271 |
provider() | { <P> (port): (schema) => Provider<InstanceType<P>, ConfigInvalid, Env> & object; <Name> (name): <Output>(schema) => Provider<PortInstance<Name, Output>, ConfigInvalid, Env> & object; } | configProvider | A provider binding a port from the environment through schema. Reads Env, so the port is built with the rest of the graph and a bad environment is a modeled startup Err rather than a silently wrong value. Two forms of the first call. Config.provider(Port)(schema) binds a port you declared — for a port that is public API another package names. Config.provider("RelayConfig")(schema) mints the port and hands back the provider carrying it, for a slice that is one application's own. | packages/config/src/config.ts:365 |
string() | (variable, options) => ConfigField<string> | - | A non-empty string — a rule about the RAW value, deliberately not a check: "set but empty" is a deployment mistake, where a pinned "" is a decision. http({ cors: false }) pins exactly that, and an off switch spelled as the empty string must not be refused as a blank variable. Remarks The bound value is trimmed. X=" abc " binds "abc", because every field parses the trimmed string — it is what makes a whitespace-only variable "set but empty" rather than a value, and what stops a stray space from turning a port into a parse error. A secret whose whitespace is significant is therefore the one value this field cannot carry: pin it through the composition root instead, where Config.pinned hands the value over untouched. | packages/config/src/config.ts:206 |
url() | (variable, options) => ConfigField<string> | - | A URL, kept as the string it was written as. The value is what a consumer hands to new URL, and this is what stops that construction from throwing: a malformed one is a ConfigInvalid naming the variable, at graph build, rather than a Defect from wherever the URL is finally needed. | packages/config/src/config.ts:242 |