@ontrails/config 1.0.0-beta.14 → 1.0.0-beta.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (163) hide show
  1. package/CHANGELOG.md +41 -0
  2. package/README.md +20 -28
  3. package/package.json +10 -2
  4. package/src/app-config.ts +23 -12
  5. package/src/compose.ts +16 -22
  6. package/src/{config-provision.ts → config-resource.ts} +5 -5
  7. package/src/define-config.ts +18 -18
  8. package/src/{generate → derive}/env.ts +3 -3
  9. package/src/{generate → derive}/example.ts +1 -1
  10. package/src/{generate → derive}/helpers.ts +1 -1
  11. package/src/derive/index.ts +3 -0
  12. package/src/{generate → derive}/json-schema.ts +1 -1
  13. package/src/{describe.ts → derive-fields.ts} +1 -1
  14. package/src/{explain.ts → derive-provenance.ts} +6 -6
  15. package/src/extensions.ts +1 -1
  16. package/src/index.ts +12 -19
  17. package/src/registry.ts +2 -2
  18. package/src/resolve.ts +17 -15
  19. package/src/trails/config-check.ts +3 -3
  20. package/src/trails/config-describe.ts +5 -5
  21. package/src/trails/config-explain.ts +13 -13
  22. package/src/trails/config-init.ts +10 -10
  23. package/.turbo/turbo-build.log +0 -1
  24. package/.turbo/turbo-lint.log +0 -3
  25. package/.turbo/turbo-typecheck.log +0 -1
  26. package/dist/app-config.d.ts +0 -65
  27. package/dist/app-config.d.ts.map +0 -1
  28. package/dist/app-config.js +0 -172
  29. package/dist/app-config.js.map +0 -1
  30. package/dist/collect.d.ts +0 -11
  31. package/dist/collect.d.ts.map +0 -1
  32. package/dist/collect.js +0 -81
  33. package/dist/collect.js.map +0 -1
  34. package/dist/compose.d.ts +0 -30
  35. package/dist/compose.d.ts.map +0 -1
  36. package/dist/compose.js +0 -21
  37. package/dist/compose.js.map +0 -1
  38. package/dist/config-gate.d.ts +0 -11
  39. package/dist/config-gate.d.ts.map +0 -1
  40. package/dist/config-gate.js +0 -6
  41. package/dist/config-gate.js.map +0 -1
  42. package/dist/config-layer.d.ts +0 -11
  43. package/dist/config-layer.d.ts.map +0 -1
  44. package/dist/config-layer.js +0 -6
  45. package/dist/config-layer.js.map +0 -1
  46. package/dist/config-provision.d.ts +0 -3
  47. package/dist/config-provision.d.ts.map +0 -1
  48. package/dist/config-provision.js +0 -26
  49. package/dist/config-provision.js.map +0 -1
  50. package/dist/config-service.d.ts +0 -3
  51. package/dist/config-service.d.ts.map +0 -1
  52. package/dist/config-service.js +0 -26
  53. package/dist/config-service.js.map +0 -1
  54. package/dist/define-config.d.ts +0 -61
  55. package/dist/define-config.d.ts.map +0 -1
  56. package/dist/define-config.js +0 -90
  57. package/dist/define-config.js.map +0 -1
  58. package/dist/describe.d.ts +0 -25
  59. package/dist/describe.d.ts.map +0 -1
  60. package/dist/describe.js +0 -147
  61. package/dist/describe.js.map +0 -1
  62. package/dist/doctor.d.ts +0 -27
  63. package/dist/doctor.d.ts.map +0 -1
  64. package/dist/doctor.js +0 -131
  65. package/dist/doctor.js.map +0 -1
  66. package/dist/explain.d.ts +0 -30
  67. package/dist/explain.d.ts.map +0 -1
  68. package/dist/explain.js +0 -101
  69. package/dist/explain.js.map +0 -1
  70. package/dist/extensions.d.ts +0 -38
  71. package/dist/extensions.d.ts.map +0 -1
  72. package/dist/extensions.js +0 -35
  73. package/dist/extensions.js.map +0 -1
  74. package/dist/generate/env.d.ts +0 -15
  75. package/dist/generate/env.d.ts.map +0 -1
  76. package/dist/generate/env.js +0 -65
  77. package/dist/generate/env.js.map +0 -1
  78. package/dist/generate/example.d.ts +0 -16
  79. package/dist/generate/example.d.ts.map +0 -1
  80. package/dist/generate/example.js +0 -138
  81. package/dist/generate/example.js.map +0 -1
  82. package/dist/generate/helpers.d.ts +0 -35
  83. package/dist/generate/helpers.d.ts.map +0 -1
  84. package/dist/generate/helpers.js +0 -116
  85. package/dist/generate/helpers.js.map +0 -1
  86. package/dist/generate/index.d.ts +0 -4
  87. package/dist/generate/index.d.ts.map +0 -1
  88. package/dist/generate/index.js +0 -4
  89. package/dist/generate/index.js.map +0 -1
  90. package/dist/generate/json-schema.d.ts +0 -18
  91. package/dist/generate/json-schema.d.ts.map +0 -1
  92. package/dist/generate/json-schema.js +0 -97
  93. package/dist/generate/json-schema.js.map +0 -1
  94. package/dist/index.d.ts +0 -21
  95. package/dist/index.d.ts.map +0 -1
  96. package/dist/index.js +0 -21
  97. package/dist/index.js.map +0 -1
  98. package/dist/merge.d.ts +0 -16
  99. package/dist/merge.d.ts.map +0 -1
  100. package/dist/merge.js +0 -34
  101. package/dist/merge.js.map +0 -1
  102. package/dist/ref.d.ts +0 -29
  103. package/dist/ref.d.ts.map +0 -1
  104. package/dist/ref.js +0 -30
  105. package/dist/ref.js.map +0 -1
  106. package/dist/registry.d.ts +0 -24
  107. package/dist/registry.d.ts.map +0 -1
  108. package/dist/registry.js +0 -12
  109. package/dist/registry.js.map +0 -1
  110. package/dist/resolve.d.ts +0 -21
  111. package/dist/resolve.d.ts.map +0 -1
  112. package/dist/resolve.js +0 -177
  113. package/dist/resolve.js.map +0 -1
  114. package/dist/secret-heuristics.d.ts +0 -10
  115. package/dist/secret-heuristics.d.ts.map +0 -1
  116. package/dist/secret-heuristics.js +0 -11
  117. package/dist/secret-heuristics.js.map +0 -1
  118. package/dist/trails/config-check.d.ts +0 -11
  119. package/dist/trails/config-check.d.ts.map +0 -1
  120. package/dist/trails/config-check.js +0 -53
  121. package/dist/trails/config-check.js.map +0 -1
  122. package/dist/trails/config-describe.d.ts +0 -12
  123. package/dist/trails/config-describe.d.ts.map +0 -1
  124. package/dist/trails/config-describe.js +0 -41
  125. package/dist/trails/config-describe.js.map +0 -1
  126. package/dist/trails/config-explain.d.ts +0 -8
  127. package/dist/trails/config-explain.d.ts.map +0 -1
  128. package/dist/trails/config-explain.js +0 -74
  129. package/dist/trails/config-explain.js.map +0 -1
  130. package/dist/trails/config-init.d.ts +0 -9
  131. package/dist/trails/config-init.d.ts.map +0 -1
  132. package/dist/trails/config-init.js +0 -78
  133. package/dist/trails/config-init.js.map +0 -1
  134. package/dist/workspace.d.ts +0 -9
  135. package/dist/workspace.d.ts.map +0 -1
  136. package/dist/workspace.js +0 -49
  137. package/dist/workspace.js.map +0 -1
  138. package/dist/zod-utils.d.ts +0 -14
  139. package/dist/zod-utils.d.ts.map +0 -1
  140. package/dist/zod-utils.js +0 -41
  141. package/dist/zod-utils.js.map +0 -1
  142. package/src/__tests__/app-config.test.ts +0 -329
  143. package/src/__tests__/compose.test.ts +0 -59
  144. package/src/__tests__/config-check.test.ts +0 -171
  145. package/src/__tests__/config-describe.test.ts +0 -154
  146. package/src/__tests__/config-explain.test.ts +0 -167
  147. package/src/__tests__/config-gate.test.ts +0 -53
  148. package/src/__tests__/config-init.test.ts +0 -210
  149. package/src/__tests__/config-provision.test.ts +0 -87
  150. package/src/__tests__/define-config.test.ts +0 -263
  151. package/src/__tests__/describe.test.ts +0 -158
  152. package/src/__tests__/doctor.test.ts +0 -172
  153. package/src/__tests__/explain.test.ts +0 -139
  154. package/src/__tests__/extensions.test.ts +0 -134
  155. package/src/__tests__/generate.test.ts +0 -269
  156. package/src/__tests__/ref.test.ts +0 -35
  157. package/src/__tests__/resolve.test.ts +0 -246
  158. package/src/__tests__/workspace.test.ts +0 -64
  159. package/src/config-gate.ts +0 -15
  160. package/src/generate/index.ts +0 -3
  161. package/src/workspace.ts +0 -56
  162. package/tsconfig.json +0 -9
  163. package/tsconfig.tsbuildinfo +0 -1
package/src/registry.ts CHANGED
@@ -2,7 +2,7 @@
2
2
  * Module-level config state registry.
3
3
  *
4
4
  * Config is resolved once at bootstrap (two-phase init per ADR-010) and
5
- * registered here so `configProvision` can expose it to trailheads. This is
5
+ * registered here so `configResource` can expose it to surfaces. This is
6
6
  * a process-level singleton — config resolution is inherently global.
7
7
  */
8
8
  import type { z } from 'zod';
@@ -12,7 +12,7 @@ export interface ConfigState {
12
12
  readonly schema: z.ZodObject<Record<string, z.ZodType>>;
13
13
  readonly resolved: Record<string, unknown>;
14
14
  readonly base?: Record<string, unknown>;
15
- readonly loadout?: Record<string, unknown>;
15
+ readonly profile?: Record<string, unknown>;
16
16
  readonly local?: Record<string, unknown>;
17
17
  readonly env?: Record<string, string | undefined>;
18
18
  }
package/src/resolve.ts CHANGED
@@ -1,11 +1,11 @@
1
1
  /**
2
2
  * Config resolution engine — merges config from multiple sources through
3
- * a deterministic stack: defaults → base → loadout → local → env.
3
+ * a deterministic stack: defaults → base → profile → local → env.
4
4
  */
5
5
 
6
6
  import type { z } from 'zod';
7
7
 
8
- import { Result } from '@ontrails/core';
8
+ import { Result, ValidationError } from '@ontrails/core';
9
9
 
10
10
  import { collectConfigMeta } from './collect.js';
11
11
  import { deepMerge } from './merge.js';
@@ -16,11 +16,11 @@ import { zodDef } from './zod-utils.js';
16
16
  // ---------------------------------------------------------------------------
17
17
 
18
18
  /** Options for resolving config through the full stack. */
19
- export interface ResolveConfigOptions<T extends z.ZodType> {
19
+ export interface DeriveConfigOptions<T extends z.ZodType> {
20
20
  readonly schema: T;
21
21
  readonly base?: Record<string, unknown> | undefined;
22
- readonly loadouts?: Record<string, Record<string, unknown>> | undefined;
23
- readonly loadout?: string | undefined;
22
+ readonly profiles?: Record<string, Record<string, unknown>> | undefined;
23
+ readonly profile?: string | undefined;
24
24
  readonly localOverrides?: Record<string, unknown> | undefined;
25
25
  readonly env?: Record<string, string | undefined> | undefined;
26
26
  }
@@ -219,11 +219,11 @@ const applyEnvOverrides = (
219
219
  // Merge pipeline
220
220
  // ---------------------------------------------------------------------------
221
221
 
222
- /** Apply the layered merge: base → loadout → local overrides. */
222
+ /** Apply the layered merge: base → profile → local overrides. */
223
223
  const mergeLayers = (
224
224
  base: Record<string, unknown> | undefined,
225
- loadouts: Record<string, Record<string, unknown>> | undefined,
226
- loadout: string | undefined,
225
+ profiles: Record<string, Record<string, unknown>> | undefined,
226
+ profile: string | undefined,
227
227
  localOverrides: Record<string, unknown> | undefined
228
228
  ): Record<string, unknown> => {
229
229
  let merged: Record<string, unknown> = {};
@@ -231,7 +231,7 @@ const mergeLayers = (
231
231
  merged = deepMerge(merged, base);
232
232
  }
233
233
 
234
- const selected = loadout && loadouts ? loadouts[loadout] : undefined;
234
+ const selected = profile && profiles ? profiles[profile] : undefined;
235
235
  if (selected) {
236
236
  merged = deepMerge(merged, selected);
237
237
  }
@@ -253,16 +253,16 @@ const formatValidationError = (
253
253
  // ---------------------------------------------------------------------------
254
254
 
255
255
  /**
256
- * Resolve config through the full stack: defaults → base → loadout → local → env.
256
+ * Derive config through the full stack: defaults → base → profile → local → env.
257
257
  * Returns `Result.ok` with the validated config, or `Result.err` on validation failure.
258
258
  */
259
- export const resolveConfig = <T extends z.ZodType>(
260
- options: ResolveConfigOptions<T>
259
+ export const deriveConfig = <T extends z.ZodType>(
260
+ options: DeriveConfigOptions<T>
261
261
  ): Result<z.infer<T>, Error> => {
262
262
  let merged = mergeLayers(
263
263
  options.base,
264
- options.loadouts,
265
- options.loadout,
264
+ options.profiles,
265
+ options.profile,
266
266
  options.localOverrides
267
267
  );
268
268
 
@@ -275,5 +275,7 @@ export const resolveConfig = <T extends z.ZodType>(
275
275
  return Result.ok(parsed.data as z.infer<T>);
276
276
  }
277
277
 
278
- return Result.err(new Error(formatValidationError(parsed.error.issues)));
278
+ return Result.err(
279
+ new ValidationError(formatValidationError(parsed.error.issues))
280
+ );
279
281
  };
@@ -7,7 +7,7 @@
7
7
  import { Result, trail } from '@ontrails/core';
8
8
  import { z } from 'zod';
9
9
 
10
- import { configProvision } from '../config-provision.js';
10
+ import { configResource } from '../config-resource.js';
11
11
  import { checkConfig } from '../doctor.js';
12
12
  import { deepMerge } from '../merge.js';
13
13
 
@@ -33,7 +33,7 @@ const mergeValues = (
33
33
 
34
34
  export const configCheck = trail('config.check', {
35
35
  blaze: (input, ctx) => {
36
- const state = configProvision.from(ctx);
36
+ const state = configResource.from(ctx);
37
37
  const effective = mergeValues(state.resolved, input.values);
38
38
  const checked = checkConfig(state.schema, effective);
39
39
  return Result.ok({
@@ -56,5 +56,5 @@ export const configCheck = trail('config.check', {
56
56
  intent: 'read',
57
57
  meta: { category: 'infrastructure' },
58
58
  output: outputSchema,
59
- provisions: [configProvision],
59
+ resources: [configResource],
60
60
  });
@@ -7,8 +7,8 @@
7
7
  import { Result, trail } from '@ontrails/core';
8
8
  import { z } from 'zod';
9
9
 
10
- import { configProvision } from '../config-provision.js';
11
- import { describeConfig } from '../describe.js';
10
+ import { configResource } from '../config-resource.js';
11
+ import { deriveConfigFields } from '../derive-fields.js';
12
12
 
13
13
  const fieldSchema = z.object({
14
14
  deprecated: z.string().optional(),
@@ -26,8 +26,8 @@ const outputSchema = z.object({
26
26
 
27
27
  export const configDescribe = trail('config.describe', {
28
28
  blaze: (_input, ctx) => {
29
- const state = configProvision.from(ctx);
30
- const fields = describeConfig(state.schema);
29
+ const state = configResource.from(ctx);
30
+ const fields = deriveConfigFields(state.schema);
31
31
  return Result.ok({ fields: [...fields] });
32
32
  },
33
33
  examples: [
@@ -40,5 +40,5 @@ export const configDescribe = trail('config.describe', {
40
40
  intent: 'read',
41
41
  meta: { category: 'infrastructure' },
42
42
  output: outputSchema,
43
- provisions: [configProvision],
43
+ resources: [configResource],
44
44
  });
@@ -7,9 +7,9 @@
7
7
  import { Result, trail } from '@ontrails/core';
8
8
  import { z } from 'zod';
9
9
 
10
- import { configProvision } from '../config-provision.js';
11
- import type { ExplainConfigOptions } from '../explain.js';
12
- import { explainConfig } from '../explain.js';
10
+ import { configResource } from '../config-resource.js';
11
+ import type { DeriveConfigProvenanceOptions } from '../derive-provenance.js';
12
+ import { deriveConfigProvenance } from '../derive-provenance.js';
13
13
  import type { ConfigState } from '../registry.js';
14
14
 
15
15
  const provenanceEntrySchema = z.object({
@@ -34,11 +34,11 @@ const filterByPath = (
34
34
  )
35
35
  : entries;
36
36
 
37
- /** Build ExplainConfigOptions from ConfigState, omitting undefined source overrides. */
37
+ /** Build DeriveConfigProvenanceOptions from ConfigState, omitting undefined source overrides. */
38
38
  const toExplainOptions = (
39
39
  state: ConfigState
40
- ): ExplainConfigOptions<typeof state.schema> => {
41
- const base: ExplainConfigOptions<typeof state.schema> = {
40
+ ): DeriveConfigProvenanceOptions<typeof state.schema> => {
41
+ const base: DeriveConfigProvenanceOptions<typeof state.schema> = {
42
42
  resolved: state.resolved,
43
43
  schema: state.schema,
44
44
  };
@@ -51,14 +51,14 @@ const toExplainOptions = (
51
51
  /** Enrich explain options with env and source overrides from state. */
52
52
  const enrichOptions = (
53
53
  state: ConfigState,
54
- options: ExplainConfigOptions<typeof state.schema>
55
- ): ExplainConfigOptions<typeof state.schema> => {
54
+ options: DeriveConfigProvenanceOptions<typeof state.schema>
55
+ ): DeriveConfigProvenanceOptions<typeof state.schema> => {
56
56
  let enriched = options;
57
57
  if (state.env) {
58
58
  enriched = { ...enriched, env: state.env };
59
59
  }
60
- if (state.loadout) {
61
- enriched = { ...enriched, loadout: state.loadout };
60
+ if (state.profile) {
61
+ enriched = { ...enriched, profile: state.profile };
62
62
  }
63
63
  if (state.local) {
64
64
  enriched = { ...enriched, local: state.local };
@@ -68,9 +68,9 @@ const enrichOptions = (
68
68
 
69
69
  export const configExplain = trail('config.explain', {
70
70
  blaze: (input, ctx) => {
71
- const state = configProvision.from(ctx);
71
+ const state = configResource.from(ctx);
72
72
  const options = enrichOptions(state, toExplainOptions(state));
73
- const entries = explainConfig(options);
73
+ const entries = deriveConfigProvenance(options);
74
74
  const filtered = filterByPath(entries, input.path);
75
75
  return Result.ok({ entries: [...filtered] });
76
76
  },
@@ -89,5 +89,5 @@ export const configExplain = trail('config.explain', {
89
89
  intent: 'read',
90
90
  meta: { category: 'infrastructure' },
91
91
  output: outputSchema,
92
- provisions: [configProvision],
92
+ resources: [configResource],
93
93
  });
@@ -14,12 +14,12 @@ import { Result, trail } from '@ontrails/core';
14
14
  import type { z } from 'zod';
15
15
  import { z as zod } from 'zod';
16
16
 
17
- import { configProvision } from '../config-provision.js';
17
+ import { configResource } from '../config-resource.js';
18
18
  import {
19
- generateEnvExample,
20
- generateExample,
21
- generateJsonSchema,
22
- } from '../generate/index.js';
19
+ deriveConfigEnvExample,
20
+ deriveConfigExample,
21
+ deriveConfigJsonSchema,
22
+ } from '../derive/index.js';
23
23
 
24
24
  const formatEnum = zod.enum(['toml', 'json', 'jsonc', 'yaml']);
25
25
 
@@ -34,13 +34,13 @@ const collectArtifacts = (
34
34
  schema: z.ZodObject<Record<string, z.ZodType>>
35
35
  ): [string, string][] => {
36
36
  const artifacts: [string, string][] = [];
37
- const envContent = generateEnvExample(schema);
37
+ const envContent = deriveConfigEnvExample(schema);
38
38
  if (envContent.length > 0) {
39
39
  artifacts.push(['.env.example', envContent]);
40
40
  }
41
41
  artifacts.push([
42
42
  '.schema.json',
43
- JSON.stringify(generateJsonSchema(schema), null, 2),
43
+ JSON.stringify(deriveConfigJsonSchema(schema), null, 2),
44
44
  ]);
45
45
  return artifacts;
46
46
  };
@@ -63,9 +63,9 @@ const writeArtifacts = async (
63
63
 
64
64
  export const configInit = trail('config.init', {
65
65
  blaze: async (input, ctx) => {
66
- const state = configProvision.from(ctx);
66
+ const state = configResource.from(ctx);
67
67
  const schema = state.schema as z.ZodObject<Record<string, z.ZodType>>;
68
- const content = generateExample(schema, input.format);
68
+ const content = deriveConfigExample(schema, input.format);
69
69
 
70
70
  if (input.dir) {
71
71
  const writtenFiles = await writeArtifacts(input.dir, schema);
@@ -92,5 +92,5 @@ export const configInit = trail('config.init', {
92
92
  intent: 'write',
93
93
  meta: { category: 'infrastructure' },
94
94
  output: outputSchema,
95
- provisions: [configProvision],
95
+ resources: [configResource],
96
96
  });
@@ -1 +0,0 @@
1
- $ tsc -b
@@ -1,3 +0,0 @@
1
- $ oxlint ./src
2
- Found 0 warnings and 0 errors.
3
- Finished in 51ms on 44 files with 93 rules using 24 threads.
@@ -1 +0,0 @@
1
- $ tsc --noEmit
@@ -1,65 +0,0 @@
1
- /**
2
- * App config factory — declare a config contract once, discover and validate at runtime.
3
- */
4
- import { Result } from '@ontrails/core';
5
- import type { z } from 'zod';
6
- import type { CheckResult } from './doctor.js';
7
- import type { FieldDescription } from './describe.js';
8
- import type { ExplainConfigOptions, ProvenanceEntry } from './explain.js';
9
- import type { ConfigRef } from './ref.js';
10
- /** Supported config file formats. */
11
- export type ConfigFormat = 'toml' | 'json' | 'jsonc' | 'yaml';
12
- /** Options for creating an app config. */
13
- export interface AppConfigOptions<T extends z.ZodType> {
14
- readonly schema: T;
15
- readonly formats?: readonly ConfigFormat[];
16
- readonly dotfile?: boolean;
17
- }
18
- /** Options for resolving (discovering + parsing) a config file. */
19
- export interface ResolveOptions {
20
- /** Working directory for discovery. Defaults to `process.cwd()`. */
21
- readonly cwd?: string;
22
- /** Explicit file path — skips discovery when provided. */
23
- readonly path?: string;
24
- }
25
- /** Options for the `explain()` method on AppConfig, excluding schema. */
26
- export type AppConfigExplainOptions = Omit<ExplainConfigOptions<z.ZodType>, 'schema'>;
27
- /** The resolved config contract returned by `appConfig()`. */
28
- export interface AppConfig<T extends z.ZodType> {
29
- readonly name: string;
30
- readonly schema: T;
31
- readonly formats: readonly ConfigFormat[];
32
- readonly dotfile: boolean;
33
- resolve(options?: ResolveOptions): Promise<Result<z.infer<T>, Error>>;
34
- /** Describe all fields in the schema without needing values. */
35
- describe(): readonly FieldDescription[];
36
- /** Check a config object against the schema and return diagnostics. */
37
- check(values: Record<string, unknown>, options?: {
38
- readonly env?: Record<string, string | undefined>;
39
- }): CheckResult;
40
- /** Show which source won for each config field. */
41
- explain(options: AppConfigExplainOptions): readonly ProvenanceEntry[];
42
- /** Create a lazy reference to a config field for use as a trail input default. */
43
- ref(fieldPath: string): ConfigRef;
44
- }
45
- /**
46
- * Declare a config contract for an app.
47
- *
48
- * The returned `AppConfig` exposes `resolve()` to discover, parse, and validate
49
- * a config file matching the app name and format conventions.
50
- *
51
- * @example
52
- * ```ts
53
- * const config = appConfig('myapp', {
54
- * schema: z.object({
55
- * output: z.string().default('./output'),
56
- * verbose: z.boolean().default(false),
57
- * }),
58
- * });
59
- *
60
- * const result = await config.resolve();
61
- * if (result.isOk()) console.log(result.value.output);
62
- * ```
63
- */
64
- export declare const appConfig: <T extends z.ZodType>(name: string, options: AppConfigOptions<T>) => AppConfig<T>;
65
- //# sourceMappingURL=app-config.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"app-config.d.ts","sourceRoot":"","sources":["../src/app-config.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,EAAiB,MAAM,EAAmB,MAAM,gBAAgB,CAAC;AACxE,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAE7B,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE/C,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAEtD,OAAO,KAAK,EAAE,oBAAoB,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAE1E,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAO1C,qCAAqC;AACrC,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,CAAC;AAE9D,0CAA0C;AAC1C,MAAM,WAAW,gBAAgB,CAAC,CAAC,SAAS,CAAC,CAAC,OAAO;IACnD,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;IACnB,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,YAAY,EAAE,CAAC;IAC3C,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;CAC5B;AAED,mEAAmE;AACnE,MAAM,WAAW,cAAc;IAC7B,oEAAoE;IACpE,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IACtB,0DAA0D;IAC1D,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,yEAAyE;AACzE,MAAM,MAAM,uBAAuB,GAAG,IAAI,CACxC,oBAAoB,CAAC,CAAC,CAAC,OAAO,CAAC,EAC/B,QAAQ,CACT,CAAC;AAEF,8DAA8D;AAC9D,MAAM,WAAW,SAAS,CAAC,CAAC,SAAS,CAAC,CAAC,OAAO;IAC5C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;IACnB,QAAQ,CAAC,OAAO,EAAE,SAAS,YAAY,EAAE,CAAC;IAC1C,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,OAAO,CAAC,OAAO,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC;IAEtE,gEAAgE;IAChE,QAAQ,IAAI,SAAS,gBAAgB,EAAE,CAAC;IAExC,uEAAuE;IACvE,KAAK,CACH,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,OAAO,CAAC,EAAE;QAAE,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAA;KAAE,GAC9D,WAAW,CAAC;IAEf,mDAAmD;IACnD,OAAO,CAAC,OAAO,EAAE,uBAAuB,GAAG,SAAS,eAAe,EAAE,CAAC;IAEtE,kFAAkF;IAClF,GAAG,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC;CACnC;AAmMD;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,SAAS,GAAI,CAAC,SAAS,CAAC,CAAC,OAAO,EAC3C,MAAM,MAAM,EACZ,SAAS,gBAAgB,CAAC,CAAC,CAAC,KAC3B,SAAS,CAAC,CAAC,CAqBb,CAAC"}
@@ -1,172 +0,0 @@
1
- /**
2
- * App config factory — declare a config contract once, discover and validate at runtime.
3
- */
4
- import { dirname, join } from 'node:path';
5
- import { NotFoundError, Result, ValidationError } from '@ontrails/core';
6
- import { checkConfig } from './doctor.js';
7
- import { describeConfig } from './describe.js';
8
- import { explainConfig } from './explain.js';
9
- import { configRef } from './ref.js';
10
- // ---------------------------------------------------------------------------
11
- // Default values
12
- // ---------------------------------------------------------------------------
13
- const DEFAULT_FORMATS = ['toml', 'json', 'yaml'];
14
- // ---------------------------------------------------------------------------
15
- // Internal helpers (defined before consumers — no-use-before-define)
16
- // ---------------------------------------------------------------------------
17
- /** Build the config filename for a given format. */
18
- const configFileName = (name, format, dotfile) => (dotfile ? `.${name}rc.${format}` : `${name}.config.${format}`);
19
- /** Check whether a file exists at the given path. */
20
- const fileExists = (filePath) => Bun.file(filePath).exists();
21
- /** Known config suffixes, ordered to avoid `.json` matching `.jsonc`. */
22
- const FORMAT_SUFFIXES = [
23
- ['jsonc', '.jsonc'],
24
- ['json', '.json'],
25
- ['toml', '.toml'],
26
- ['yaml', '.yaml'],
27
- ];
28
- /** Detect the declared config format from a file path. */
29
- const detectFormat = (filePath) => {
30
- for (const [format, suffix] of FORMAT_SUFFIXES) {
31
- if (filePath.endsWith(suffix)) {
32
- return format;
33
- }
34
- }
35
- return undefined;
36
- };
37
- /** Parse config file text with Bun's native format parsers. */
38
- const parseConfigText = (filePath, text) => {
39
- const format = detectFormat(filePath);
40
- try {
41
- switch (format) {
42
- case 'json': {
43
- return Result.ok(JSON.parse(text));
44
- }
45
- case 'jsonc': {
46
- return Result.ok(Bun.JSONC.parse(text));
47
- }
48
- case 'toml': {
49
- return Result.ok(Bun.TOML.parse(text));
50
- }
51
- case 'yaml': {
52
- return Result.ok(Bun.YAML.parse(text));
53
- }
54
- default: {
55
- return Result.err(new ValidationError(`Unsupported config file format: ${filePath}`, {
56
- context: { path: filePath },
57
- }));
58
- }
59
- }
60
- }
61
- catch (error) {
62
- return Result.err(new ValidationError(`Failed to parse config file: ${filePath}`, {
63
- cause: error instanceof Error ? error : new Error(String(error)),
64
- context: { path: filePath },
65
- }));
66
- }
67
- };
68
- /** Read and parse a config file, always reflecting the latest on-disk content. */
69
- const readConfigFile = async (filePath) => {
70
- const exists = await fileExists(filePath);
71
- if (!exists) {
72
- return Result.err(new NotFoundError(`Config file not found: ${filePath}`, {
73
- context: { path: filePath },
74
- }));
75
- }
76
- const text = await Bun.file(filePath).text();
77
- return parseConfigText(filePath, text);
78
- };
79
- /** Validate parsed data against a Zod schema. */
80
- const validateConfig = (schema, data, filePath) => {
81
- const parsed = schema.safeParse(data);
82
- if (parsed.success) {
83
- return Result.ok(parsed.data);
84
- }
85
- return Result.err(new ValidationError(`Config validation failed: ${filePath}`, {
86
- context: {
87
- issues: parsed.error.issues,
88
- path: filePath,
89
- },
90
- }));
91
- };
92
- /** Check all format candidates in a single directory. */
93
- const findInDir = async (dir, name, formats, dotfile) => {
94
- for (const format of formats) {
95
- const candidate = join(dir, configFileName(name, format, dotfile));
96
- if (await fileExists(candidate)) {
97
- return candidate;
98
- }
99
- }
100
- return undefined;
101
- };
102
- /** Walk up from `startDir` looking for any matching config filename. */
103
- const discoverConfigFile = async (name, formats, dotfile, startDir) => {
104
- let dir = startDir;
105
- for (let depth = 0; depth < 64; depth += 1) {
106
- const found = await findInDir(dir, name, formats, dotfile);
107
- if (found !== undefined) {
108
- return found;
109
- }
110
- const parent = dirname(dir);
111
- // Reached filesystem root
112
- if (parent === dir) {
113
- break;
114
- }
115
- dir = parent;
116
- }
117
- return undefined;
118
- };
119
- /** Resolve a config file — either from an explicit path or via discovery. */
120
- const resolveConfig = async (name, schema, formats, dotfile, options) => {
121
- const filePath = options?.path ??
122
- (await discoverConfigFile(name, formats, dotfile, options?.cwd ?? process.cwd()));
123
- if (filePath === undefined) {
124
- return Result.err(new NotFoundError(`No config file found for "${name}"`, {
125
- context: { dotfile, formats: [...formats], name },
126
- }));
127
- }
128
- const readResult = await readConfigFile(filePath);
129
- if (readResult.isErr()) {
130
- return readResult;
131
- }
132
- return validateConfig(schema, readResult.value, filePath);
133
- };
134
- // ---------------------------------------------------------------------------
135
- // Factory
136
- // ---------------------------------------------------------------------------
137
- /**
138
- * Declare a config contract for an app.
139
- *
140
- * The returned `AppConfig` exposes `resolve()` to discover, parse, and validate
141
- * a config file matching the app name and format conventions.
142
- *
143
- * @example
144
- * ```ts
145
- * const config = appConfig('myapp', {
146
- * schema: z.object({
147
- * output: z.string().default('./output'),
148
- * verbose: z.boolean().default(false),
149
- * }),
150
- * });
151
- *
152
- * const result = await config.resolve();
153
- * if (result.isOk()) console.log(result.value.output);
154
- * ```
155
- */
156
- export const appConfig = (name, options) => {
157
- const formats = options.formats ?? DEFAULT_FORMATS;
158
- const dotfile = options.dotfile ?? false;
159
- const { schema } = options;
160
- return {
161
- check: (values, checkOpts) => checkConfig(schema, values, checkOpts),
162
- describe: () => describeConfig(schema),
163
- dotfile,
164
- explain: (explainOpts) => explainConfig({ ...explainOpts, schema }),
165
- formats,
166
- name,
167
- ref: (fieldPath) => configRef(fieldPath),
168
- resolve: (resolveOptions) => resolveConfig(name, schema, formats, dotfile, resolveOptions),
169
- schema,
170
- };
171
- };
172
- //# sourceMappingURL=app-config.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"app-config.js","sourceRoot":"","sources":["../src/app-config.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAE1C,OAAO,EAAE,aAAa,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAIxE,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE1C,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAE/C,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAE7C,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAsDrC,8EAA8E;AAC9E,iBAAiB;AACjB,8EAA8E;AAE9E,MAAM,eAAe,GAA4B,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;AAE1E,8EAA8E;AAC9E,qEAAqE;AACrE,8EAA8E;AAE9E,oDAAoD;AACpD,MAAM,cAAc,GAAG,CACrB,IAAY,EACZ,MAAoB,EACpB,OAAgB,EACR,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,IAAI,MAAM,MAAM,EAAE,CAAC,CAAC,CAAC,GAAG,IAAI,WAAW,MAAM,EAAE,CAAC,CAAC;AAE7E,qDAAqD;AACrD,MAAM,UAAU,GAAG,CAAC,QAAgB,EAAoB,EAAE,CACxD,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,MAAM,EAAE,CAAC;AAE9B,yEAAyE;AACzE,MAAM,eAAe,GAA4C;IAC/D,CAAC,OAAO,EAAE,QAAQ,CAAC;IACnB,CAAC,MAAM,EAAE,OAAO,CAAC;IACjB,CAAC,MAAM,EAAE,OAAO,CAAC;IACjB,CAAC,MAAM,EAAE,OAAO,CAAC;CAClB,CAAC;AAEF,0DAA0D;AAC1D,MAAM,YAAY,GAAG,CAAC,QAAgB,EAA4B,EAAE;IAClE,KAAK,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI,eAAe,EAAE,CAAC;QAC/C,IAAI,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;YAC9B,OAAO,MAAM,CAAC;QAChB,CAAC;IACH,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC,CAAC;AAEF,+DAA+D;AAC/D,MAAM,eAAe,GAAG,CACtB,QAAgB,EAChB,IAAY,EACY,EAAE;IAC1B,MAAM,MAAM,GAAG,YAAY,CAAC,QAAQ,CAAC,CAAC;IAEtC,IAAI,CAAC;QACH,QAAQ,MAAM,EAAE,CAAC;YACf,KAAK,MAAM,CAAC,CAAC,CAAC;gBACZ,OAAO,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;YACrC,CAAC;YACD,KAAK,OAAO,CAAC,CAAC,CAAC;gBACb,OAAO,MAAM,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;YAC1C,CAAC;YACD,KAAK,MAAM,CAAC,CAAC,CAAC;gBACZ,OAAO,MAAM,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;YACzC,CAAC;YACD,KAAK,MAAM,CAAC,CAAC,CAAC;gBACZ,OAAO,MAAM,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;YACzC,CAAC;YACD,OAAO,CAAC,CAAC,CAAC;gBACR,OAAO,MAAM,CAAC,GAAG,CACf,IAAI,eAAe,CAAC,mCAAmC,QAAQ,EAAE,EAAE;oBACjE,OAAO,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;iBAC5B,CAAC,CACH,CAAC;YACJ,CAAC;QACH,CAAC;IACH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,MAAM,CAAC,GAAG,CACf,IAAI,eAAe,CAAC,gCAAgC,QAAQ,EAAE,EAAE;YAC9D,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YAChE,OAAO,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;SAC5B,CAAC,CACH,CAAC;IACJ,CAAC;AACH,CAAC,CAAC;AAEF,kFAAkF;AAClF,MAAM,cAAc,GAAG,KAAK,EAC1B,QAAgB,EACiB,EAAE;IACnC,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,QAAQ,CAAC,CAAC;IAC1C,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO,MAAM,CAAC,GAAG,CACf,IAAI,aAAa,CAAC,0BAA0B,QAAQ,EAAE,EAAE;YACtD,OAAO,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;SAC5B,CAAC,CACH,CAAC;IACJ,CAAC;IAED,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,IAAI,EAAE,CAAC;IAC7C,OAAO,eAAe,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;AACzC,CAAC,CAAC;AAEF,iDAAiD;AACjD,MAAM,cAAc,GAAG,CACrB,MAAS,EACT,IAAa,EACb,QAAgB,EACW,EAAE;IAC7B,MAAM,MAAM,GAAG,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IACtC,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;QACnB,OAAO,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,IAAkB,CAAC,CAAC;IAC9C,CAAC;IACD,OAAO,MAAM,CAAC,GAAG,CACf,IAAI,eAAe,CAAC,6BAA6B,QAAQ,EAAE,EAAE;QAC3D,OAAO,EAAE;YACP,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,MAAM;YAC3B,IAAI,EAAE,QAAQ;SACf;KACF,CAAC,CACH,CAAC;AACJ,CAAC,CAAC;AAEF,yDAAyD;AACzD,MAAM,SAAS,GAAG,KAAK,EACrB,GAAW,EACX,IAAY,EACZ,OAAgC,EAChC,OAAgB,EACa,EAAE;IAC/B,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC7B,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;QACnE,IAAI,MAAM,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;YAChC,OAAO,SAAS,CAAC;QACnB,CAAC;IACH,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC,CAAC;AAEF,wEAAwE;AACxE,MAAM,kBAAkB,GAAG,KAAK,EAC9B,IAAY,EACZ,OAAgC,EAChC,OAAgB,EAChB,QAAgB,EACa,EAAE;IAC/B,IAAI,GAAG,GAAG,QAAQ,CAAC;IAEnB,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,EAAE,EAAE,KAAK,IAAI,CAAC,EAAE,CAAC;QAC3C,MAAM,KAAK,GAAG,MAAM,SAAS,CAAC,GAAG,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;QAC3D,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACxB,OAAO,KAAK,CAAC;QACf,CAAC;QACD,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;QAC5B,0BAA0B;QAC1B,IAAI,MAAM,KAAK,GAAG,EAAE,CAAC;YACnB,MAAM;QACR,CAAC;QACD,GAAG,GAAG,MAAM,CAAC;IACf,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC,CAAC;AAEF,6EAA6E;AAC7E,MAAM,aAAa,GAAG,KAAK,EACzB,IAAY,EACZ,MAAS,EACT,OAAgC,EAChC,OAAgB,EAChB,OAAwB,EACY,EAAE;IACtC,MAAM,QAAQ,GACZ,OAAO,EAAE,IAAI;QACb,CAAC,MAAM,kBAAkB,CACvB,IAAI,EACJ,OAAO,EACP,OAAO,EACP,OAAO,EAAE,GAAG,IAAI,OAAO,CAAC,GAAG,EAAE,CAC9B,CAAC,CAAC;IAEL,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;QAC3B,OAAO,MAAM,CAAC,GAAG,CACf,IAAI,aAAa,CAAC,6BAA6B,IAAI,GAAG,EAAE;YACtD,OAAO,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,GAAG,OAAO,CAAC,EAAE,IAAI,EAAE;SAClD,CAAC,CACH,CAAC;IACJ,CAAC;IAED,MAAM,UAAU,GAAG,MAAM,cAAc,CAAC,QAAQ,CAAC,CAAC;IAClD,IAAI,UAAU,CAAC,KAAK,EAAE,EAAE,CAAC;QACvB,OAAO,UAAU,CAAC;IACpB,CAAC;IAED,OAAO,cAAc,CAAC,MAAM,EAAE,UAAU,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;AAC5D,CAAC,CAAC;AAEF,8EAA8E;AAC9E,UAAU;AACV,8EAA8E;AAE9E;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,CAAC,MAAM,SAAS,GAAG,CACvB,IAAY,EACZ,OAA4B,EACd,EAAE;IAChB,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,eAAe,CAAC;IACnD,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,KAAK,CAAC;IAEzC,MAAM,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;IAE3B,OAAO;QACL,KAAK,EAAE,CAAC,MAAM,EAAE,SAAS,EAAE,EAAE,CAAC,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,CAAC;QACpE,QAAQ,EAAE,GAAG,EAAE,CACb,cAAc,CACZ,MAA2D,CAC5D;QACH,OAAO;QACP,OAAO,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC,aAAa,CAAC,EAAE,GAAG,WAAW,EAAE,MAAM,EAAE,CAAC;QACnE,OAAO;QACP,IAAI;QACJ,GAAG,EAAE,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,SAAS,CAAC;QACxC,OAAO,EAAE,CAAC,cAA+B,EAAE,EAAE,CAC3C,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,cAAc,CAAC;QAC/D,MAAM;KACP,CAAC;AACJ,CAAC,CAAC"}
package/dist/collect.d.ts DELETED
@@ -1,11 +0,0 @@
1
- import type { z } from 'zod';
2
- import type { ConfigFieldMeta } from './extensions.js';
3
- /**
4
- * Walk a Zod object schema and collect `ConfigFieldMeta` for each field.
5
- *
6
- * Handles unwrapping `.default()`, `.optional()`, `.nullable()` wrappers
7
- * that don't carry inner metadata forward. Recurses into nested `ZodObject`
8
- * fields using dot-separated paths.
9
- */
10
- export declare const collectConfigMeta: (schema: z.ZodObject<Record<string, z.ZodType>>, prefix?: string) => Map<string, ConfigFieldMeta>;
11
- //# sourceMappingURL=collect.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"collect.d.ts","sourceRoot":"","sources":["../src/collect.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAE7B,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AA+FvD;;;;;;GAMG;AACH,eAAO,MAAM,iBAAiB,GAC5B,QAAQ,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,EAC9C,eAAW,KACV,GAAG,CAAC,MAAM,EAAE,eAAe,CAS7B,CAAC"}
package/dist/collect.js DELETED
@@ -1,81 +0,0 @@
1
- import { globalRegistry } from 'zod';
2
- import { isZodObject, unwrapToBase } from './zod-utils.js';
3
- /** Config meta keys we look for in Zod registry entries. */
4
- const META_EXTRACTORS = [
5
- {
6
- extract: (r) => ({ env: r['env'] }),
7
- test: (r) => typeof r['env'] === 'string',
8
- },
9
- {
10
- extract: () => ({ secret: true }),
11
- test: (r) => r['secret'] === true,
12
- },
13
- {
14
- extract: (r) => ({ deprecated: r['deprecationMessage'] }),
15
- test: (r) => typeof r['deprecationMessage'] === 'string',
16
- },
17
- ];
18
- /**
19
- * Pick only `ConfigFieldMeta` keys from a raw registry entry.
20
- * Uses a lookup table to stay under the max-statements limit.
21
- */
22
- const pickConfigMeta = (raw) => {
23
- if (!raw) {
24
- return undefined;
25
- }
26
- const parts = META_EXTRACTORS.filter((e) => e.test(raw)).map((e) => e.extract(raw));
27
- return parts.length > 0
28
- ? Object.assign({}, ...parts)
29
- : undefined;
30
- };
31
- /**
32
- * Extract `ConfigFieldMeta` from a schema, unwrapping through
33
- * `.default()`, `.optional()`, `.nullable()` wrappers as needed.
34
- */
35
- const extractConfigMeta = (schema) => {
36
- let current = schema;
37
- while (current) {
38
- const meta = pickConfigMeta(globalRegistry.get(current));
39
- if (meta) {
40
- return meta;
41
- }
42
- const def = current.def;
43
- current = def['innerType'];
44
- }
45
- return undefined;
46
- };
47
- /** Process one level of an object schema, queuing nested objects. */
48
- const walkObjectShape = (schema, prefix, result, queue) => {
49
- const shape = schema.shape;
50
- for (const [key, fieldSchema] of Object.entries(shape)) {
51
- const path = prefix ? `${prefix}.${key}` : key;
52
- if (isZodObject(fieldSchema)) {
53
- queue.push({
54
- prefix: path,
55
- schema: unwrapToBase(fieldSchema),
56
- });
57
- }
58
- else {
59
- const meta = extractConfigMeta(fieldSchema);
60
- if (meta) {
61
- result.set(path, meta);
62
- }
63
- }
64
- }
65
- };
66
- /**
67
- * Walk a Zod object schema and collect `ConfigFieldMeta` for each field.
68
- *
69
- * Handles unwrapping `.default()`, `.optional()`, `.nullable()` wrappers
70
- * that don't carry inner metadata forward. Recurses into nested `ZodObject`
71
- * fields using dot-separated paths.
72
- */
73
- export const collectConfigMeta = (schema, prefix = '') => {
74
- const result = new Map();
75
- const queue = [{ prefix, schema }];
76
- for (let entry = queue.pop(); entry; entry = queue.pop()) {
77
- walkObjectShape(entry.schema, entry.prefix, result, queue);
78
- }
79
- return result;
80
- };
81
- //# sourceMappingURL=collect.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"collect.js","sourceRoot":"","sources":["../src/collect.ts"],"names":[],"mappings":"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"}