typed-settings 0.1.1 → 0.2.1

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 (83) hide show
  1. package/README.md +18 -9
  2. package/bin/typed-settings.mjs +5 -0
  3. package/dist/adapters/joi.cjs +1 -26
  4. package/dist/adapters/joi.d.cts +2 -1
  5. package/dist/adapters/joi.d.ts +2 -1
  6. package/dist/adapters/joi.js +1 -1
  7. package/dist/adapters/superstruct.cjs +1 -26
  8. package/dist/adapters/superstruct.js +1 -1
  9. package/dist/adapters/yup.cjs +1 -25
  10. package/dist/adapters/yup.js +1 -1
  11. package/dist/adapters/zod.cjs +3 -36
  12. package/dist/adapters/zod.d.cts +2 -0
  13. package/dist/adapters/zod.d.ts +2 -0
  14. package/dist/adapters/zod.js +1 -33
  15. package/dist/check-XVFZEVNV.js +1 -0
  16. package/dist/chunk-4EAMKDNK.js +3 -0
  17. package/dist/chunk-5D2AQWDG.js +1 -0
  18. package/dist/chunk-C6CG2D4B.js +2 -0
  19. package/dist/chunk-FQYD5ZKE.js +1 -0
  20. package/dist/chunk-NQDE3WLR.js +3 -0
  21. package/dist/chunk-RURPDXIJ.js +1 -0
  22. package/dist/cli/main.cjs +36 -2220
  23. package/dist/cli/main.js +32 -806
  24. package/dist/errors-JkkOM0u-.d.cts +25 -0
  25. package/dist/errors-JkkOM0u-.d.ts +25 -0
  26. package/dist/framework/next.cjs +5 -1153
  27. package/dist/framework/next.d.cts +5 -3
  28. package/dist/framework/next.d.ts +5 -3
  29. package/dist/framework/next.js +1 -15
  30. package/dist/framework/vite.cjs +5 -1151
  31. package/dist/framework/vite.d.cts +10 -3
  32. package/dist/framework/vite.d.ts +10 -3
  33. package/dist/framework/vite.js +1 -14
  34. package/dist/index.cjs +5 -1176
  35. package/dist/index.d.cts +46 -10
  36. package/dist/index.d.ts +46 -10
  37. package/dist/index.js +1 -6
  38. package/dist/node.cjs +6 -1236
  39. package/dist/node.d.cts +23 -9
  40. package/dist/node.d.ts +23 -9
  41. package/dist/node.js +1 -7
  42. package/dist/{types-CClP1lxq.d.ts → types-CcsYDAdO.d.cts} +27 -3
  43. package/dist/{types-CClP1lxq.d.cts → types-CcsYDAdO.d.ts} +27 -3
  44. package/dist/vault/aws.cjs +4 -217
  45. package/dist/vault/aws.d.cts +3 -1
  46. package/dist/vault/aws.d.ts +3 -1
  47. package/dist/vault/aws.js +2 -167
  48. package/dist/vault/hashicorp.cjs +4 -183
  49. package/dist/vault/hashicorp.d.cts +3 -1
  50. package/dist/vault/hashicorp.d.ts +3 -1
  51. package/dist/vault/hashicorp.js +2 -77
  52. package/dist/vault/http.cjs +4 -185
  53. package/dist/vault/http.d.cts +3 -1
  54. package/dist/vault/http.d.ts +3 -1
  55. package/dist/vault/http.js +2 -79
  56. package/package.json +10 -3
  57. package/dist/chunk-33M5GIKQ.js +0 -13
  58. package/dist/chunk-A5TCQJ7L.js +0 -65
  59. package/dist/chunk-EE6LXNJV.js +0 -34
  60. package/dist/chunk-F6DX3HXZ.js +0 -101
  61. package/dist/chunk-OVFMKC2O.js +0 -15
  62. package/dist/chunk-RCO6K3WQ.js +0 -984
  63. package/dist/chunk-RQC6OMVV.js +0 -86
  64. package/dist/chunk-UFUHHR2J.js +0 -38
  65. package/dist/chunk-VTIYOSG2.js +0 -233
  66. package/dist/errors-itGaU4Q8.d.cts +0 -17
  67. package/dist/errors-itGaU4Q8.d.ts +0 -17
  68. package/dist/formats/env.cjs +0 -103
  69. package/dist/formats/env.d.cts +0 -8
  70. package/dist/formats/env.d.ts +0 -8
  71. package/dist/formats/env.js +0 -1
  72. package/dist/formats/json.cjs +0 -15
  73. package/dist/formats/json.d.cts +0 -7
  74. package/dist/formats/json.d.ts +0 -7
  75. package/dist/formats/json.js +0 -1
  76. package/dist/formats/toml.cjs +0 -17
  77. package/dist/formats/toml.d.cts +0 -7
  78. package/dist/formats/toml.d.ts +0 -7
  79. package/dist/formats/toml.js +0 -1
  80. package/dist/formats/yaml.cjs +0 -40
  81. package/dist/formats/yaml.d.cts +0 -8
  82. package/dist/formats/yaml.d.ts +0 -8
  83. package/dist/formats/yaml.js +0 -1
package/dist/cli/main.js CHANGED
@@ -1,831 +1,57 @@
1
1
  #!/usr/bin/env node
2
- import { watchSettings } from '../chunk-VTIYOSG2.js';
3
- import { settings } from '../chunk-RCO6K3WQ.js';
4
- import '../chunk-33M5GIKQ.js';
5
- import '../chunk-OVFMKC2O.js';
6
- import '../chunk-UFUHHR2J.js';
7
- import { ConfigError } from '../chunk-EE6LXNJV.js';
8
- import '../chunk-F6DX3HXZ.js';
9
- import { parseArgs } from 'util';
10
- import { resolve, join, dirname } from 'path';
11
- import { existsSync, mkdirSync, writeFileSync, chmodSync, readFileSync } from 'fs';
12
- import { spawn } from 'child_process';
13
-
14
- async function loadSchema(schemaPath, exportName) {
15
- const abs = resolve(schemaPath);
16
- let mod;
17
- try {
18
- const { createJiti } = await import('jiti');
19
- const jiti = createJiti(import.meta.url, { interopDefault: false, fsCache: false, moduleCache: false });
20
- mod = await jiti.import(abs);
21
- } catch (e) {
22
- const err2 = e;
23
- const wrapped = new Error(`SCHEMA_LOAD_ERROR: ${abs}: ${err2.message}`);
24
- wrapped.code = "SCHEMA_LOAD_ERROR";
25
- throw wrapped;
26
- }
27
- const pick = (name) => mod[name];
28
- const isStandard = (v) => {
29
- if (!v) return false;
30
- if (typeof v !== "object" && typeof v !== "function") return false;
31
- return "~standard" in v;
32
- };
33
- if (exportName) {
34
- const picked = pick(exportName);
35
- if (!isStandard(picked)) {
36
- const err2 = new Error(
37
- `SCHEMA_LOAD_ERROR: --schema-export ${JSON.stringify(exportName)} did not resolve to a Standard Schema in ${abs}`
38
- );
39
- err2.code = "SCHEMA_LOAD_ERROR";
40
- throw err2;
41
- }
42
- return picked;
43
- }
44
- for (const cand of ["schema", "settingsSchema", "default"]) {
45
- if (isStandard(pick(cand))) return pick(cand);
46
- }
47
- const first = Object.values(mod).find((v) => isStandard(v));
48
- if (first) return first;
49
- const err = new Error(`SCHEMA_LOAD_ERROR: no Standard Schema export in ${abs} (tried default/schema/settingsSchema)`);
50
- err.code = "SCHEMA_LOAD_ERROR";
51
- throw err;
52
- }
53
-
54
- // src/cli/check.ts
55
- async function runCheck(args) {
56
- let schema;
57
- try {
58
- schema = await loadSchema(args.schema, args.schemaExport);
59
- } catch (e) {
60
- const err = e;
61
- if (args.format === "json") console.log(JSON.stringify({ ok: false, error: err.message }));
62
- else console.error(err.message);
63
- return 2;
64
- }
65
- const sources = (args.config ?? ".env,env").split(",").map((s) => s.trim()).filter(Boolean);
66
- try {
67
- const cfg = settings({
68
- schema,
69
- sources: sources.length ? sources : [".env", "env"],
70
- strict: void 0,
71
- unknownKeys: args.strict ? "reject" : "strip",
72
- expand: args.expand ?? true,
73
- arrayStrategy: args.array ?? "replace",
74
- prefix: args.prefix
75
- });
76
- if (args.format === "json") console.log(JSON.stringify({ ok: true, config: cfg }));
77
- else console.log("OK: config valid");
78
- return 0;
79
- } catch (e) {
80
- if (e instanceof ConfigError) {
81
- if (args.format === "json") console.log(JSON.stringify({ ok: false, issues: e.issues }));
82
- else {
83
- console.error(e.message);
84
- }
85
- return 1;
86
- }
87
- const err = e;
88
- if (args.format === "json") console.log(JSON.stringify({ ok: false, error: err.message }));
89
- else console.error(`E_LOAD: ${err.message}`);
90
- return 2;
91
- }
92
- }
93
- var SETTINGS_TPL = {
94
- zod: `import { z } from 'zod';
2
+ import {b as b$1,a}from'../chunk-FQYD5ZKE.js';import {d}from'../chunk-C6CG2D4B.js';import'../chunk-4EAMKDNK.js';import'../chunk-NQDE3WLR.js';import {parseArgs}from'util';import {existsSync,mkdirSync,writeFileSync,chmodSync,readFileSync,lstatSync}from'fs';import {resolve,join,dirname}from'path';import {spawn}from'child_process';var w={zod:`import { z } from 'zod';
95
3
  import { settings } from 'typed-settings';
4
+ import 'typed-settings/node';
96
5
 
97
- const schema = z.object({
6
+ export const schema = z.object({
98
7
  port: z.coerce.number().default(3000),
99
8
  });
100
9
 
101
10
  export const cfg = settings({ schema, sources: ['.env', 'env'], prefix: 'APP_' });
102
- `,
103
- valibot: `import * as v from 'valibot';
11
+ `,valibot:`import * as v from 'valibot';
104
12
  import { settings } from 'typed-settings';
13
+ import 'typed-settings/node';
105
14
 
106
- const schema = v.object({ port: v.optional(v.pipe(v.unknown(), v.transform(Number)), 3000) });
15
+ export const schema = v.object({ port: v.optional(v.pipe(v.unknown(), v.transform(Number), v.number()), 3000) });
107
16
 
108
17
  export const cfg = settings({ schema: schema as never, sources: ['.env', 'env'], prefix: 'APP_' });
109
- `,
110
- arktype: `import { type } from 'arktype';
18
+ `,arktype:`import { type } from 'arktype';
111
19
  import { settings } from 'typed-settings';
20
+ import 'typed-settings/node';
112
21
 
113
- const schema = type({ 'port?: string.integer.parse = 3000' });
22
+ export const schema = type({ port: 'number = 3000' });
114
23
 
115
24
  export const cfg = settings({ schema: schema as never, sources: ['.env', 'env'], prefix: 'APP_' });
116
- `,
117
- yup: `import * as yup from 'yup';
25
+ `,yup:`// npm install yup
26
+ import * as yup from 'yup';
118
27
  import { settings } from 'typed-settings';
28
+ import 'typed-settings/node';
119
29
  import { yupAdapter } from 'typed-settings/yup';
120
30
 
121
- const schema = yup.object({ port: yup.number().default(3000) });
31
+ export const schema = yup.object({ port: yup.number().default(3000) });
122
32
 
123
33
  export const cfg = settings({ schema: yupAdapter(schema) as never, sources: ['.env', 'env'], prefix: 'APP_' });
124
- `,
125
- joi: `import Joi from 'joi';
34
+ `,joi:`// npm install joi
35
+ import Joi from 'joi';
126
36
  import { settings } from 'typed-settings';
37
+ import 'typed-settings/node';
127
38
  import { joiAdapter } from 'typed-settings/joi';
128
39
 
129
- const schema = Joi.object({ port: Joi.number().default(3000) });
40
+ export const schema = Joi.object({ port: Joi.number().default(3000) });
130
41
 
131
42
  export const cfg = settings({ schema: joiAdapter(schema as never) as never, sources: ['.env', 'env'], prefix: 'APP_' });
132
- `
133
- };
134
- var CONFIG_TPL = {
135
- env: "# APP_PORT=3000\nAPP_PORT=3000\n",
136
- yaml: "# config.yaml\nport: 3000\n",
137
- toml: "# config.toml\nport = 3000\n"
138
- };
139
- async function runInit(args) {
140
- const lib = args.lib ?? "zod";
141
- const format = args.format ?? "env";
142
- if (!(lib in SETTINGS_TPL)) {
143
- console.error(`E_USAGE: --lib must be ${Object.keys(SETTINGS_TPL).join("|")} (got ${JSON.stringify(lib)})`);
144
- return 2;
145
- }
146
- if (!(format in CONFIG_TPL)) {
147
- console.error(`E_USAGE: --format must be ${Object.keys(CONFIG_TPL).join("|")} (got ${JSON.stringify(format)})`);
148
- return 2;
149
- }
150
- const dir = resolve(args.dir ?? ".");
151
- const settingsTpl = SETTINGS_TPL[lib];
152
- const configName = format === "env" ? ".env.example" : `config.${format}`;
153
- const files = [
154
- { path: join(dir, "src", "settings.ts"), content: settingsTpl },
155
- { path: join(dir, configName), content: CONFIG_TPL[format] }
156
- ];
157
- const currentOf = (p) => {
158
- try {
159
- return readFileSync(p, "utf8");
160
- } catch {
161
- return null;
162
- }
163
- };
164
- const drifted = files.filter((f) => currentOf(f.path) !== f.content);
165
- if (args.dryRun || args.check) {
166
- for (const f of files) {
167
- const cur = currentOf(f.path);
168
- console.log(`${cur === null ? "create" : cur === f.content ? "exists" : "overwrite"} ${f.path}`);
169
- }
170
- if (args.check && drifted.length > 0) return 2;
171
- return 0;
172
- }
173
- let written = 0;
174
- for (const f of files) {
175
- if (currentOf(f.path) === f.content) {
176
- continue;
177
- }
178
- if (existsSync(f.path) && !args.force) {
179
- continue;
180
- }
181
- mkdirSync(dirname(f.path), { recursive: true });
182
- writeFileSync(f.path, f.content, { mode: 384 });
183
- try {
184
- chmodSync(f.path, 384);
185
- } catch {
186
- }
187
- written++;
188
- }
189
- console.log(`init: ${lib} + ${format} scaffolding ${written > 0 ? `written (${written} file${written === 1 ? "" : "s"})` : "already up to date"}`);
190
- return 0;
191
- }
192
-
193
- // src/cli/describe.ts
194
- function getShape(schema) {
195
- const s = schema;
196
- if (s && typeof s.shape === "object" && s.shape !== null) return s.shape;
197
- if (s && typeof s.shape === "function") {
198
- try {
199
- return s.shape();
200
- } catch {
201
- return null;
202
- }
203
- }
204
- const d = s?._def?.shape;
205
- if (typeof d === "function") {
206
- try {
207
- return d();
208
- } catch {
209
- return null;
210
- }
211
- }
212
- if (d && typeof d === "object") return d;
213
- return null;
214
- }
215
- function unwrapField(t) {
216
- let cur = t;
217
- let optional = false;
218
- let def;
219
- for (let i = 0; i < 10; i++) {
220
- const c = cur;
221
- const z4type = c?.type ?? c?.def?.type;
222
- if (z4type === "optional") {
223
- optional = true;
224
- cur = c?.def?.innerType ?? (typeof c?.unwrap === "function" ? safeUnwrap(c.unwrap) : void 0) ?? cur;
225
- if (cur === t) break;
226
- t = cur;
227
- continue;
228
- }
229
- if (z4type === "nullable") {
230
- cur = c?.def?.innerType ?? (typeof c?.unwrap === "function" ? safeUnwrap(c.unwrap) : void 0) ?? cur;
231
- if (cur === t) break;
232
- t = cur;
233
- continue;
234
- }
235
- if (z4type === "catch" || z4type === "prefault" || z4type === "pipe" || z4type === "brand" || z4type === "readonly") {
236
- const inner = c?.def?.innerType ?? (typeof c?.unwrap === "function" ? safeUnwrap(c.unwrap) : void 0);
237
- if (inner === void 0 || inner === cur) break;
238
- cur = inner;
239
- t = cur;
240
- continue;
241
- }
242
- if (z4type === "default") {
243
- const dv = c?.def?.defaultValue;
244
- if (def === void 0) def = typeof dv === "function" ? safeCall(dv) : dv;
245
- optional = true;
246
- cur = c?.def?.innerType ?? (typeof c?.unwrap === "function" ? safeUnwrap(c.unwrap) : void 0) ?? cur;
247
- continue;
248
- }
249
- if (z4type === "readonly" || z4type === "nonoptional" || z4type === "success") {
250
- cur = c?.def?.innerType ?? cur;
251
- continue;
252
- }
253
- const tn = c?._def?.typeName;
254
- if (tn === "ZodOptional") {
255
- optional = true;
256
- cur = c?._def?.innerType;
257
- continue;
258
- }
259
- if (tn === "ZodNullable") {
260
- cur = c?._def?.innerType;
261
- continue;
262
- }
263
- if (tn === "ZodDefault") {
264
- if (def === void 0) {
265
- const dv = c?._def?.defaultValue;
266
- def = typeof dv === "function" ? safeCall(dv) : dv;
267
- }
268
- optional = true;
269
- cur = c?._def?.innerType;
270
- continue;
271
- }
272
- if (tn === "ZodReadonly") {
273
- cur = c?._def?.innerType;
274
- continue;
275
- }
276
- break;
277
- }
278
- const desc = cur?.description ?? cur?.def?.description ?? t?.description;
279
- return { inner: cur, optional, def, desc };
280
- }
281
- function safeUnwrap(fn) {
282
- try {
283
- return fn();
284
- } catch {
285
- return void 0;
286
- }
287
- }
288
- function safeCall(fn) {
289
- try {
290
- return fn();
291
- } catch {
292
- return void 0;
293
- }
294
- }
295
- function enumMembers(def) {
296
- const d = def;
297
- if (Array.isArray(d?.values)) return d.values;
298
- if (d?.entries && typeof d.entries === "object") return Object.values(d.entries);
299
- return [];
300
- }
301
- function unwrapZod(t) {
302
- return unwrapField(t);
303
- }
304
- function zodTypeName(t) {
305
- const c = t;
306
- const z4 = c?.type ?? c?.def?.type;
307
- if (z4) {
308
- switch (z4) {
309
- case "string":
310
- return "string";
311
- case "number":
312
- return "number";
313
- case "boolean":
314
- return "boolean";
315
- case "array":
316
- return "array";
317
- case "object":
318
- return "object";
319
- // Zod 4 keeps enum members in `def.entries` (object); older shapes use `def.values`.
320
- case "enum":
321
- return `enum(${enumMembers(c?.def).join("|")})`;
322
- case "literal":
323
- return "literal";
324
- case "union":
325
- return "union";
326
- default:
327
- return z4;
328
- }
329
- }
330
- const tn = c?._def?.typeName ?? "unknown";
331
- switch (tn) {
332
- case "ZodString":
333
- return "string";
334
- case "ZodNumber":
335
- return "number";
336
- case "ZodBoolean":
337
- return "boolean";
338
- case "ZodArray":
339
- return "array";
340
- case "ZodObject":
341
- return "object";
342
- case "ZodEnum":
343
- return `enum(${(c?._def?.values ?? []).join("|")})`;
344
- case "ZodLiteral":
345
- return "literal";
346
- case "ZodUnion":
347
- return "union";
348
- default:
349
- return "string";
350
- }
351
- }
352
- function walkZod(prefix, t, out) {
353
- const { inner, optional, def, desc } = unwrapZod(t);
354
- const shape = getShape(inner);
355
- if (shape) {
356
- for (const [k, v] of Object.entries(shape)) {
357
- walkZod(prefix ? `${prefix}.${k}` : k, v, out);
358
- }
359
- return;
360
- }
361
- out.push({
362
- path: prefix || "<root>",
363
- type: zodTypeName(inner),
364
- required: !optional && def === void 0,
365
- default: def,
366
- description: desc
367
- });
368
- }
369
- function describeSchema(schema) {
370
- try {
371
- if (getShape(schema)) {
372
- const out = [];
373
- walkZod("", schema, out);
374
- return { fields: out, bestEffort: false };
375
- }
376
- } catch {
377
- }
378
- try {
379
- if (isValibotObject(schema)) {
380
- const out = [];
381
- walkValibot("", schema, out);
382
- return { fields: out, bestEffort: false };
383
- }
384
- } catch {
385
- }
386
- try {
387
- const j = arktypeJson(schema);
388
- if (j && j.domain === "object") {
389
- const out = [];
390
- walkArktype(j, out);
391
- return { fields: out, bestEffort: false };
392
- }
393
- } catch {
394
- }
395
- return { fields: [{ path: "<root>", type: "string", required: false, description: "GEN_BEST_EFFORT: unknown schema (Effect/others), fill manually" }], bestEffort: true };
396
- }
397
- function isValibotObject(schema) {
398
- const s = schema;
399
- return !!s && s.type === "object" && !!s.entries && typeof s.entries === "object";
400
- }
401
- function unwrapValibot(t) {
402
- let cur = t;
403
- let optional = false;
404
- let def;
405
- for (let i = 0; i < 10; i++) {
406
- const c = cur;
407
- const ty = c?.type;
408
- if (ty === "optional" || ty === "nullish") {
409
- optional = true;
410
- if (def === void 0 && c?.default !== void 0) def = c.default;
411
- if (!c?.wrapped) break;
412
- cur = c.wrapped;
413
- continue;
414
- }
415
- if (ty === "nullable") {
416
- if (!c?.wrapped) break;
417
- cur = c.wrapped;
418
- continue;
419
- }
420
- if (ty === "non_optional" || ty === "non_nullable" || ty === "non_nullish") {
421
- if (!c?.wrapped) break;
422
- cur = c.wrapped;
423
- continue;
424
- }
425
- break;
426
- }
427
- const leaf = cur;
428
- if (def === void 0 && leaf?.default !== void 0) def = leaf.default;
429
- return { inner: cur, optional, def, desc: leaf?.description };
430
- }
431
- function valibotTypeName(t) {
432
- const c = t;
433
- switch (c?.type) {
434
- case "string":
435
- return "string";
436
- case "number":
437
- return "number";
438
- case "boolean":
439
- return "boolean";
440
- case "bigint":
441
- return "bigint";
442
- case "date":
443
- return "date";
444
- case "array":
445
- return "array";
446
- case "object":
447
- return "object";
448
- case "record":
449
- return "object";
450
- case "tuple":
451
- return "array";
452
- case "map":
453
- return "object";
454
- case "picklist":
455
- case "enum_":
456
- return `enum(${(c.options ?? []).map((o) => JSON.stringify(o)).join("|")})`;
457
- case "literal":
458
- return `literal(${JSON.stringify(c.literal)})`;
459
- case "union":
460
- case "variant":
461
- case "intersect":
462
- return c.type;
463
- case "nan":
464
- return "number";
465
- default:
466
- return typeof c?.type === "string" ? c.type : "string";
467
- }
468
- }
469
- function walkValibot(prefix, t, out) {
470
- const { inner, optional, def, desc } = unwrapValibot(t);
471
- const c = inner;
472
- if (c?.type === "object" && c.entries && typeof c.entries === "object") {
473
- for (const [k, v] of Object.entries(c.entries)) {
474
- walkValibot(prefix ? `${prefix}.${k}` : k, v, out);
475
- }
476
- return;
477
- }
478
- out.push({
479
- path: prefix || "<root>",
480
- type: valibotTypeName(inner),
481
- required: !optional && def === void 0,
482
- default: def,
483
- description: desc
484
- });
485
- }
486
- function arktypeJson(schema) {
487
- const s = schema;
488
- const j = s?.json;
489
- if (typeof j === "function") {
490
- try {
491
- return j();
492
- } catch {
493
- return null;
494
- }
495
- }
496
- return j ?? null;
497
- }
498
- function arktypeTypeName(v) {
499
- if (typeof v === "string") return v;
500
- if (Array.isArray(v)) return "union";
501
- if (v && typeof v === "object") {
502
- const o = v;
503
- if ("sequence" in o) return "array";
504
- if (o["domain"] === "object") return "object";
505
- if (typeof o["proto"] === "string") return String(o["proto"]).toLowerCase();
506
- }
507
- return "string";
508
- }
509
- function walkArktype(node, out) {
510
- const n = node;
511
- if (n && n.domain === "object" && (Array.isArray(n.required) || Array.isArray(n.optional))) {
512
- for (const r of n.required ?? []) walkArktypeValue(r.key, r.value, true, void 0, out);
513
- for (const r of n.optional ?? []) walkArktypeValue(r.key, r.value, false, r.default, out);
514
- return;
515
- }
516
- out.push({ path: "<root>", type: arktypeTypeName(node), required: true, default: void 0 });
517
- }
518
- function walkArktypeValue(path, value, required, def, out) {
519
- if (value && typeof value === "object" && !Array.isArray(value) && value.domain === "object") {
520
- const n = value;
521
- if (Array.isArray(n.required) || Array.isArray(n.optional)) {
522
- for (const r of n.required ?? []) walkArktypeValue(`${path}.${r.key}`, r.value, true, void 0, out);
523
- for (const r of n.optional ?? []) walkArktypeValue(`${path}.${r.key}`, r.value, false, r.default, out);
524
- return;
525
- }
526
- }
527
- out.push({ path, type: arktypeTypeName(value), required: required && def === void 0, default: def });
528
- }
529
- function toEnvExample(fields, prefix = "") {
530
- const lines = ["# Generated by typed-settings gen \u2014 edit values, keep keys"];
531
- const sorted = [...fields].sort((a, b) => a.path.localeCompare(b.path));
532
- for (const f of sorted) {
533
- if (f.path === "<root>") {
534
- lines.push(`# ${f.description ?? "no fields discovered \u2014 fill manually"}`);
535
- continue;
536
- }
537
- const key = (prefix + f.path.replace(/\./g, "__")).toUpperCase();
538
- const val = f.default !== void 0 && typeof f.default !== "object" ? String(f.default) : f.type === "number" ? "0" : f.type === "boolean" ? "false" : "";
539
- const comment = f.required ? "required" : `default: ${f.default !== void 0 ? JSON.stringify(f.default) : "none"}`;
540
- if (f.description) lines.push(`# ${f.description}`);
541
- lines.push(`${key}=${val} # ${f.type} ${comment}`);
542
- }
543
- lines.push("");
544
- return lines.join("\n");
545
- }
546
- function toMarkdownDocs(fields, prefix = "") {
547
- const lines = ["# Configuration", "", "| Env | Path | Type | Required | Default |", "| --- | --- | --- | --- | --- |"];
548
- for (const f of [...fields].sort((a, b) => a.path.localeCompare(b.path))) {
549
- const env = (prefix + f.path.replace(/\./g, "__")).toUpperCase();
550
- lines.push(`| \`${env}\` | \`${f.path}\` | ${f.type} | ${f.required} | ${f.default !== void 0 ? `\`${JSON.stringify(f.default)}\`` : "-"} |`);
551
- }
552
- lines.push("");
553
- return lines.join("\n");
554
- }
555
-
556
- // src/cli/gen.ts
557
- async function runGen(args) {
558
- let schema;
559
- try {
560
- schema = await loadSchema(args.schema, args.schemaExport);
561
- } catch (e) {
562
- console.error(e.message);
563
- return 2;
564
- }
565
- const { fields, bestEffort } = describeSchema(schema);
566
- if (bestEffort) console.error("GEN_BEST_EFFORT: non-Zod schema, output is a starting point \u2014 verify types manually");
567
- const envText = toEnvExample(fields, args.prefix);
568
- const mdText = toMarkdownDocs(fields, args.prefix);
569
- const writeGuarded = (p, content) => {
570
- if (existsSync(p) && !args.force) {
571
- console.error(`E_EXISTS: ${p} exists \u2014 pass --force to overwrite`);
572
- return 2;
573
- }
574
- mkdirSync(dirname(p), { recursive: true });
575
- writeFileSync(p, content, { mode: 384 });
576
- console.log(`gen: wrote ${p}`);
577
- return 0;
578
- };
579
- if (args.out) {
580
- const code = writeGuarded(resolve(args.out), envText);
581
- if (code !== 0) return code;
582
- } else {
583
- console.log(envText);
584
- }
585
- if (args.docs) {
586
- const code = writeGuarded(resolve(args.docs), mdText);
587
- if (code !== 0) return code;
588
- } else if (!args.out) {
589
- console.log(mdText);
590
- }
591
- return 0;
592
- }
593
- async function runWatch(args) {
594
- if (!args.schema) {
595
- console.error("Usage: watch -s schema.ts -c base.yaml,.env [-- cmd...]");
596
- return 2;
597
- }
598
- const schema = await loadSchema(args.schema, args.schemaExport).catch((e) => {
599
- console.error(e.message);
600
- return null;
601
- });
602
- if (!schema) return 2;
603
- const sources = (args.config ?? ".env,env").split(",").map((s) => s.trim()).filter(Boolean);
604
- let child = null;
605
- const startChild = () => {
606
- if (!args.cmd?.length) return;
607
- stopChild();
608
- child = spawn(args.cmd[0], args.cmd.slice(1), { stdio: "inherit", shell: false });
609
- child.on("error", (e) => {
610
- console.error(`watch: child failed to start: ${e.message}`);
611
- child = null;
612
- });
613
- child.on("exit", () => {
614
- child = null;
615
- });
616
- };
617
- const stopChild = () => {
618
- try {
619
- child?.kill();
620
- } catch {
621
- }
622
- child = null;
623
- };
624
- if (args.once) {
625
- if (args.cmd?.length) console.error("watch: -- cmd is ignored with --once (single validation, nothing to supervise)");
626
- const { settings: settings2, ConfigError: ConfigError2 } = await import('../index.js');
627
- try {
628
- settings2({ schema, sources: sources.length ? sources : [".env", "env"], unknownKeys: args.strict ? "reject" : "strip", expand: args.expand ?? true, arrayStrategy: args.array ?? "replace", prefix: args.prefix });
629
- console.log("OK: config valid");
630
- return 0;
631
- } catch (e) {
632
- console.error(e.message);
633
- return e instanceof ConfigError2 ? 1 : 2;
634
- }
635
- }
636
- const sub = watchSettings(
637
- // NOTE: no `env` override — inherit process.env exactly like --once/check do.
638
- { schema, sources: sources.length ? sources : [".env", "env"], unknownKeys: args.strict ? "reject" : "strip", expand: args.expand ?? true, arrayStrategy: args.array ?? "replace", prefix: args.prefix },
639
- {
640
- onUpdate: (cfg, changed) => {
641
- console.log(`reload: ok changed=[${changed.join(",")}]`);
642
- if (args.cmd?.length) startChild();
643
- },
644
- onError: (e) => {
645
- console.error(`reload: invalid, kept old
646
- ${e.message}`);
647
- if (args.exitOnError) {
648
- void sub.dispose().then(() => {
649
- stopChild();
650
- process.exitCode = 1;
651
- });
652
- }
653
- }
654
- }
655
- );
656
- startChild();
657
- const shutdown = () => {
658
- void sub.dispose().then(() => {
659
- stopChild();
660
- });
661
- };
662
- process.once("SIGINT", shutdown);
663
- process.once("SIGTERM", shutdown);
664
- await new Promise((resolve4) => {
665
- const t = setInterval(() => {
666
- if ((process.exitCode ?? 0) !== 0) {
667
- clearInterval(t);
668
- resolve4();
669
- }
670
- }, 100);
671
- process.once("SIGINT", () => {
672
- clearInterval(t);
673
- resolve4();
674
- });
675
- process.once("SIGTERM", () => {
676
- clearInterval(t);
677
- resolve4();
678
- });
679
- });
680
- return Number(process.exitCode ?? 0);
681
- }
682
-
683
- // src/cli/main.ts
684
- async function main(argv = process.argv.slice(2)) {
685
- const [cmd, ...rest] = argv;
686
- if (!cmd || cmd === "--help" || cmd === "-h") {
687
- console.log(`typed-settings <check|init|gen|watch>
688
-
689
- check -s schema.ts -c base.yaml,.env [--strict] [--no-expand] [--array replace|concat|mergeIndex] [--format human|json]
690
- init --lib zod|valibot|arktype|yup|joi --format yaml|toml|env [--force|--dry-run|--check]
691
- gen --schema src/config.ts --out .env.example --docs CONFIG.md
692
- watch -s schema.ts -c base.yaml --once [--exit-on-error] [-- cmd...]`);
693
- return 0;
694
- }
695
- try {
696
- if (cmd === "check") {
697
- const { values } = parseArgs({
698
- args: rest,
699
- // allowNegative enables the advertised `--no-expand` negation flag.
700
- allowNegative: true,
701
- options: {
702
- schema: { type: "string", short: "s" },
703
- config: { type: "string", short: "c" },
704
- strict: { type: "boolean", default: false },
705
- expand: { type: "boolean", default: true },
706
- array: { type: "string", default: "replace" },
707
- format: { type: "string", default: "human" },
708
- "schema-export": { type: "string" },
709
- prefix: { type: "string" }
710
- }
711
- });
712
- if (!values.schema) {
713
- console.error("Usage: check -s schema.ts -c base.yaml,.env");
714
- return 2;
715
- }
716
- if (values.array !== void 0 && !["replace", "concat", "mergeIndex"].includes(values.array)) {
717
- console.error(`E_USAGE: --array must be replace|concat|mergeIndex (got ${JSON.stringify(values.array)})`);
718
- return 2;
719
- }
720
- if (values.format !== void 0 && !["human", "json"].includes(values.format)) {
721
- console.error(`E_USAGE: --format must be human|json (got ${JSON.stringify(values.format)})`);
722
- return 2;
723
- }
724
- return await runCheck({
725
- schema: values.schema,
726
- config: values.config,
727
- strict: values.strict,
728
- expand: values.expand,
729
- array: values.array,
730
- format: values.format,
731
- schemaExport: values["schema-export"],
732
- prefix: values.prefix
733
- });
734
- }
735
- if (cmd === "init") {
736
- const { values } = parseArgs({
737
- args: rest,
738
- options: {
739
- lib: { type: "string", default: "zod" },
740
- format: { type: "string", default: "env" },
741
- dir: { type: "string", default: "." },
742
- force: { type: "boolean", default: false },
743
- "dry-run": { type: "boolean", default: false },
744
- check: { type: "boolean", default: false }
745
- }
746
- });
747
- return await runInit({
748
- lib: values.lib,
749
- format: values.format,
750
- dir: values.dir,
751
- force: values.force,
752
- dryRun: values["dry-run"],
753
- check: values.check
754
- });
755
- }
756
- if (cmd === "gen") {
757
- const { values } = parseArgs({
758
- args: rest,
759
- options: {
760
- schema: { type: "string" },
761
- "schema-export": { type: "string" },
762
- out: { type: "string" },
763
- docs: { type: "string" },
764
- prefix: { type: "string" },
765
- force: { type: "boolean", default: false }
766
- }
767
- });
768
- if (!values.schema) {
769
- console.error("Usage: gen --schema src/config.ts --out .env.example --docs CONFIG.md");
770
- return 2;
771
- }
772
- return await runGen({
773
- schema: values.schema,
774
- schemaExport: values["schema-export"],
775
- out: values.out,
776
- docs: values.docs,
777
- prefix: values.prefix,
778
- force: values.force
779
- });
780
- }
781
- if (cmd === "watch") {
782
- const dashIdx = rest.indexOf("--");
783
- const watchArgs = dashIdx === -1 ? rest : rest.slice(0, dashIdx);
784
- const childCmd = dashIdx === -1 ? [] : rest.slice(dashIdx + 1);
785
- const { values } = parseArgs({
786
- args: watchArgs,
787
- allowNegative: true,
788
- options: {
789
- schema: { type: "string", short: "s" },
790
- config: { type: "string", short: "c" },
791
- strict: { type: "boolean", default: false },
792
- expand: { type: "boolean", default: true },
793
- array: { type: "string", default: "replace" },
794
- once: { type: "boolean", default: false },
795
- "exit-on-error": { type: "boolean", default: false },
796
- "schema-export": { type: "string" },
797
- prefix: { type: "string" }
798
- }
799
- });
800
- if (values.array !== void 0 && !["replace", "concat", "mergeIndex"].includes(values.array)) {
801
- console.error(`E_USAGE: --array must be replace|concat|mergeIndex (got ${JSON.stringify(values.array)})`);
802
- return 2;
803
- }
804
- return await runWatch({
805
- schema: values.schema,
806
- config: values.config,
807
- schemaExport: values["schema-export"],
808
- strict: values.strict,
809
- expand: values.expand,
810
- array: values.array,
811
- prefix: values.prefix,
812
- once: values.once,
813
- exitOnError: values["exit-on-error"],
814
- cmd: childCmd.length ? childCmd : void 0
815
- });
816
- }
817
- console.error(`unknown command: ${cmd}`);
818
- return 2;
819
- } catch (e) {
820
- console.error(e.message);
821
- return 2;
822
- }
823
- }
824
- var isDirect = process.argv[1]?.endsWith("main.js") || process.argv[1]?.endsWith("main.cjs");
825
- if (isDirect) {
826
- main().then((code) => {
827
- process.exitCode = code;
828
- });
829
- }
830
-
831
- export { main };
43
+ `},x={env:`# APP_PORT=3000
44
+ APP_PORT=3000
45
+ `,yaml:`# config.yaml
46
+ port: 3000
47
+ `,toml:`# config.toml
48
+ port = 3000
49
+ `};async function T(n){let e=n.lib??"zod",o=n.format??"env";if(!Object.hasOwn(w,e))return console.error(`E_USAGE: --lib must be ${Object.keys(w).join("|")} (got ${JSON.stringify(e)})`),2;if(!Object.hasOwn(x,o))return console.error(`E_USAGE: --format must be ${Object.keys(x).join("|")} (got ${JSON.stringify(o)})`),2;let t=resolve(n.dir??"."),i=w[e],c=o==="env"?".env.example":`config.${o}`,r=[{path:join(t,"src","settings.ts"),content:i},{path:join(t,c),content:x[o]}],a=f=>{try{return readFileSync(f,"utf8")}catch{return null}},l=r.filter(f=>a(f.path)!==f.content);if(n.dryRun||n.check){for(let f of r){let m=a(f.path);console.log(`${m===null?"create":m===f.content?"exists":"overwrite"} ${f.path}`);}return n.check&&l.length>0?2:0}let s=0;for(let f of r){if(a(f.path)===f.content){continue}if(existsSync(f.path)&&!n.force){continue}mkdirSync(dirname(f.path),{recursive:true}),writeFileSync(f.path,f.content,{mode:384});try{chmodSync(f.path,384);}catch{}s++;}return console.log(`init: ${e} + ${o} scaffolding ${s>0?`written (${s} file${s===1?"":"s"})`:"already up to date"}`),o==="env"&&s>0&&console.log("hint: copy .env.example to .env and fill in real values (example files are never loaded)"),0}function I(n){let e=n;if(e&&typeof e.shape=="object"&&e.shape!==null)return e.shape;if(e&&typeof e.shape=="function")try{return e.shape()}catch{return null}let o=e?._def?.shape;if(typeof o=="function")try{return o()}catch{return null}return o&&typeof o=="object"?o:null}function X(n){let e=n,o=false,t;for(let c=0;c<10;c++){let r=e,a=r?.type??r?.def?.type;if(a==="optional"){if(o=true,e=r?.def?.innerType??(typeof r?.unwrap=="function"?g(r.unwrap):void 0)??e,e===n)break;n=e;continue}if(a==="nullable"){if(e=r?.def?.innerType??(typeof r?.unwrap=="function"?g(r.unwrap):void 0)??e,e===n)break;n=e;continue}if(a==="catch"||a==="prefault"||a==="pipe"||a==="brand"||a==="readonly"){let s=r?.def?.innerType??(typeof r?.unwrap=="function"?g(r.unwrap):void 0);if(s===void 0||s===e)break;e=s,n=e;continue}if(a==="default"){let s=r?.def?.defaultValue;t===void 0&&(t=typeof s=="function"?O(s):s),o=true,e=r?.def?.innerType??(typeof r?.unwrap=="function"?g(r.unwrap):void 0)??e;continue}if(a==="nonoptional"||a==="success"){let s=r?.def?.innerType;if(s===void 0||s===e)break;e=s,n=e;continue}let l=r?._def?.typeName;if(l==="ZodOptional"){o=true,e=r?._def?.innerType;continue}if(l==="ZodNullable"){e=r?._def?.innerType;continue}if(l==="ZodDefault"){if(t===void 0){let s=r?._def?.defaultValue;t=typeof s=="function"?O(s):s;}o=true,e=r?._def?.innerType;continue}if(l==="ZodReadonly"){e=r?._def?.innerType;continue}break}let i=e?.description??e?.def?.description??n?.description;return {inner:e,optional:o,def:t,desc:i}}function g(n){try{return n()}catch{return}}function O(n){try{return n()}catch{return}}function Y(n){let e=n;return Array.isArray(e?.values)?e.values:e?.entries&&typeof e.entries=="object"?Object.values(e.entries):[]}function H(n){return X(n)}function Q(n){let e=n,o=e?.type??e?.def?.type;if(o)switch(o){case "string":return "string";case "number":return "number";case "boolean":return "boolean";case "array":return "array";case "object":return "object";case "enum":return `enum(${Y(e?.def).join("|")})`;case "literal":return "literal";case "union":return "union";default:return o}switch(e?._def?.typeName??"unknown"){case "ZodString":return "string";case "ZodNumber":return "number";case "ZodBoolean":return "boolean";case "ZodBigInt":return "bigint";case "ZodDate":return "date";case "ZodNaN":return "number";case "ZodArray":return "array";case "ZodObject":return "object";case "ZodEnum":return `enum(${(e?._def?.values??[]).join("|")})`;case "ZodLiteral":return "literal";case "ZodUnion":return "union";default:return "string"}}function F(n,e,o,t=false){let{inner:i,optional:c,def:r,desc:a}=H(e),l=t||c,s=I(i);if(s){for(let[p,f]of Object.entries(s))F(n?`${n}.${p}`:p,f,o,l);return}o.push({path:n||"<root>",type:Q(i),required:!l&&r===void 0,default:r,description:a});}function G(n){try{if(I(n)){let e=[];return F("",n,e),{fields:e,bestEffort:!1}}}catch{}try{if(ee(n)){let e=[];return P("",n,e),{fields:e,bestEffort:!1}}}catch{}try{let e=re(n);if(e&&e.domain==="object"){let o=[];return oe(e,o),{fields:o,bestEffort:!1}}}catch{}return {fields:[{path:"<root>",type:"string",required:false,description:"GEN_BEST_EFFORT: unknown schema (Effect/others), fill manually"}],bestEffort:true}}function ee(n){let e=n;return !!e&&e.type==="object"&&!!e.entries&&typeof e.entries=="object"}function ne(n){let e=n,o=false,t;for(let c=0;c<10;c++){let r=e,a=r?.type;if(a==="optional"||a==="nullish"){if(o=true,t===void 0&&r?.default!==void 0&&(t=r.default),!r?.wrapped)break;e=r.wrapped;continue}if(a==="nullable"){if(!r?.wrapped)break;e=r.wrapped;continue}if(a==="non_optional"||a==="non_nullable"||a==="non_nullish"){if(!r?.wrapped)break;e=r.wrapped;continue}break}let i=e;return t===void 0&&i?.default!==void 0&&(t=i.default),{inner:e,optional:o,def:t,desc:i?.description}}function te(n){let e=n;switch(e?.type){case "string":return "string";case "number":return "number";case "boolean":return "boolean";case "bigint":return "bigint";case "date":return "date";case "array":return "array";case "object":return "object";case "record":return "object";case "tuple":return "array";case "map":return "object";case "picklist":case "enum_":return `enum(${(e.options??[]).map(o=>JSON.stringify(o)).join("|")})`;case "literal":return `literal(${JSON.stringify(e.literal)})`;case "union":case "variant":case "intersect":return e.type;case "nan":return "number";default:return typeof e?.type=="string"?e.type:"string"}}function P(n,e,o,t=false){let{inner:i,optional:c,def:r,desc:a}=ne(e),l=t||c,s=i;if(s?.type==="object"&&s.entries&&typeof s.entries=="object"){for(let[p,f]of Object.entries(s.entries))P(n?`${n}.${p}`:p,f,o,l);return}o.push({path:n||"<root>",type:te(i),required:!l&&r===void 0,default:r,description:a});}function re(n){let o=n?.json;if(typeof o=="function")try{return o()}catch{return null}return o??null}function C(n){if(typeof n=="string")return n;if(Array.isArray(n))return "union";if(n&&typeof n=="object"){let e=n;if("sequence"in e)return "array";if(e.domain==="object")return "object";if(typeof e.proto=="string")return String(e.proto).toLowerCase()}return "string"}function oe(n,e){let o=n;if(o&&o.domain==="object"&&(Array.isArray(o.required)||Array.isArray(o.optional))){for(let t of o.required??[])b(t.key,t.value,true,void 0,e);for(let t of o.optional??[])b(t.key,t.value,false,t.default,e);return}e.push({path:"<root>",type:C(n),required:true,default:void 0});}function b(n,e,o,t,i){if(e&&typeof e=="object"&&!Array.isArray(e)&&e.domain==="object"){let c=e;if(Array.isArray(c.required)||Array.isArray(c.optional)){for(let r of c.required??[])b(`${n}.${r.key}`,r.value,true,void 0,i);for(let r of c.optional??[])b(`${n}.${r.key}`,r.value,false,r.default,i);return}}i.push({path:n,type:C(e),required:o&&t===void 0,default:t});}function R(n,e){return ((n&&!n.endsWith("_")?`${n}_`:n)+e.replace(/\./g,"__")).toUpperCase().replace(/[^A-Z0-9_]/g,"_")}function D(n,e=""){let o=["# Generated by typed-settings gen \u2014 edit values, keep keys"],t=[...n].sort((i,c)=>i.path.localeCompare(c.path));for(let i of t){if(i.path==="<root>"){o.push(`# ${i.description??"no fields discovered \u2014 fill manually"}`);continue}let c=R(e,i.path),r=i.default!==void 0&&typeof i.default!="object"?String(i.default):i.type==="number"?"0":i.type==="boolean"?"false":"",a=i.required?"required":`default: ${i.default!==void 0?JSON.stringify(i.default):"none"}`;i.description&&o.push(`# ${i.description}`),o.push(`${c}=${r} # ${i.type} ${a}`);}return o.push(""),o.join(`
50
+ `)}function Z(n,e=""){let o=["# Configuration","","| Env | Path | Type | Required | Default |","| --- | --- | --- | --- | --- |"];for(let t of [...n].sort((i,c)=>i.path.localeCompare(c.path))){if(t.path==="<root>")continue;let i=R(e,t.path);o.push(`| \`${i}\` | \`${t.path}\` | ${t.type} | ${t.required} | ${t.default!==void 0?`\`${JSON.stringify(t.default)}\``:"-"} |`);}return o.push(""),o.join(`
51
+ `)}function le(n){try{return lstatSync(n).isSymbolicLink()}catch{return false}}async function U(n){let e;try{e=await a(n.schema,n.schemaExport);}catch(s){return console.error(s.message),2}let{fields:o,bestEffort:t}=G(e);t&&console.error("GEN_BEST_EFFORT: non-Zod schema, output is a starting point \u2014 verify types manually");let i=D(o,n.prefix),c=Z(o,n.prefix),r=n.out?resolve(n.out):null,a$1=n.docs?resolve(n.docs):null;for(let s of [r,a$1])if(s){if(le(s))return console.error(`E_SYMLINK: ${s} is a symlink \u2014 refusing to write through it`),2;if(existsSync(s)&&!n.force)return console.error(`E_EXISTS: ${s} exists \u2014 pass --force to overwrite`),2}let l=(s,p)=>{mkdirSync(dirname(s),{recursive:true}),writeFileSync(s,p,{mode:384});try{chmodSync(s,384);}catch{}console.log(`gen: wrote ${s}`);};return r?l(r,i):console.log(i),a$1?l(a$1,c):r||(console.log("# ---- CONFIG.md below ----"),console.log(c)),0}async function V(n){if(!n.schema)return console.error("Usage: watch -s schema.ts -c base.yaml,.env [-- cmd...]"),2;let e=await a(n.schema,n.schemaExport).catch(u=>(console.error(u.message),null));if(!e)return 2;let o=(n.config??".env,env").split(",").map(u=>u.trim()).filter(Boolean),t=null,i=()=>{if(!n.cmd?.length)return;c();let u=spawn(n.cmd[0],n.cmd.slice(1),{stdio:"inherit",shell:false});t=u,u.on("error",d=>{console.error(`watch: child failed to start: ${d.message}`),t===u&&(t=null);}),u.on("exit",(d,$)=>{t===u&&(t=null,typeof d=="number"&&d!==0?(console.error(`watch: child exited with code ${d}`),n.exitOnChildError&&p(d)):typeof $=="string"&&(console.error(`watch: child exited on signal ${$}`),n.exitOnChildError&&p(1)));});},c=()=>{let u=t;if(t=null,!u)return;try{u.kill();}catch{}setTimeout(()=>{try{u.kill("SIGKILL");}catch{}},2e3).unref();};if(n.once){n.cmd?.length&&console.error("watch: -- cmd is ignored with --once (single validation, nothing to supervise)");let{runCheck:u}=await import('../check-XVFZEVNV.js');return u({schema:n.schema,config:n.config,schemaExport:n.schemaExport,strict:n.strict,expand:n.expand,array:n.array,prefix:n.prefix,format:n.format,secretKeys:n.secretKeys})}let r=d({schema:e,sources:o.length?o:[".env","env"],unknownKeys:n.strict?"reject":"strip",expand:n.expand??true,arrayStrategy:n.array??"replace",prefix:n.prefix},{onUpdate:(u,d)=>{d.length!==0&&(console.log(`reload: ok changed=[${d.join(",")}]`),n.cmd?.length&&i());},onError:u=>{console.error(`reload: invalid, kept old
52
+ ${u.message}`),n.exitOnError&&r.dispose().then(()=>{c(),process.exitCode=1,s(1);});}}),a$1,l=new Promise(u=>{a$1=u;}),s=u=>{process.removeListener("SIGINT",j),process.removeListener("SIGTERM",S),process.removeListener("SIGINT",y),process.removeListener("SIGTERM",y),clearInterval(E),a$1(u);},p=u=>{r.dispose().then(()=>{c(),process.exitCode=u,s(u);});};i();let f=null,m=new Promise(u=>{f=u;}),v=()=>{r.dispose().then(()=>{c(),f();});},E=setInterval(()=>{(process.exitCode??0)!==0&&s(Number(process.exitCode));},100),y=()=>{clearInterval(E),m.then(()=>s(Number(process.exitCode??0)));};function j(){v();}function S(){v();}return process.once("SIGINT",j),process.once("SIGTERM",S),process.once("SIGINT",y),process.once("SIGTERM",y),l}async function de(n=process.argv.slice(2)){let[e,...o]=n;if(!e||e==="--help"||e==="-h")return console.log(`typed-settings <check|init|gen|watch>
53
+
54
+ check -s schema.ts -c base.yaml,.env [--strict] [--no-expand] [--array replace|concat|mergeIndex] [--format human|json] [--schema-export NAME] [--prefix PFX] [--secret-keys a,b]
55
+ init --lib zod|valibot|arktype|yup|joi --format yaml|toml|env [--dir .] [--force|--dry-run|--check]
56
+ gen --schema src/config.ts --out .env.example --docs CONFIG.md [--schema-export NAME] [--prefix PFX] [--force]
57
+ watch -s schema.ts -c base.yaml [--strict] [--no-expand] [--array ...] [--format human|json] [--schema-export NAME] [--prefix PFX] [--secret-keys a,b] [--once] [--exit-on-error] [--exit-on-child-error] [-- cmd...]`),0;try{if(e==="check"){let{values:t}=parseArgs({args:o,allowNegative:!0,options:{schema:{type:"string",short:"s"},config:{type:"string",short:"c"},strict:{type:"boolean",default:!1},expand:{type:"boolean",default:!0},array:{type:"string",default:"replace"},format:{type:"string",default:"human"},"schema-export":{type:"string"},prefix:{type:"string"},"secret-keys":{type:"string"}}});return t.schema?t.array!==void 0&&!["replace","concat","mergeIndex"].includes(t.array)?(console.error(`E_USAGE: --array must be replace|concat|mergeIndex (got ${JSON.stringify(t.array)})`),2):t.format!==void 0&&!["human","json"].includes(t.format)?(console.error(`E_USAGE: --format must be human|json (got ${JSON.stringify(t.format)})`),2):await b$1({schema:t.schema,config:t.config,strict:t.strict,expand:t.expand,array:t.array,format:t.format,schemaExport:t["schema-export"],prefix:t.prefix,secretKeys:t["secret-keys"]?.split(",").map(i=>i.trim()).filter(Boolean)}):(console.error("E_USAGE: check -s schema.ts -c base.yaml,.env"),2)}if(e==="init"){let{values:t}=parseArgs({args:o,options:{lib:{type:"string",default:"zod"},format:{type:"string",default:"env"},dir:{type:"string",default:"."},force:{type:"boolean",default:!1},"dry-run":{type:"boolean",default:!1},check:{type:"boolean",default:!1}}});return await T({lib:t.lib,format:t.format,dir:t.dir,force:t.force,dryRun:t["dry-run"],check:t.check})}if(e==="gen"){let{values:t}=parseArgs({args:o,options:{schema:{type:"string",short:"s"},"schema-export":{type:"string"},out:{type:"string"},docs:{type:"string"},prefix:{type:"string"},force:{type:"boolean",default:!1}}});return t.schema?await U({schema:t.schema,schemaExport:t["schema-export"],out:t.out,docs:t.docs,prefix:t.prefix,force:t.force}):(console.error("E_USAGE: gen --schema src/config.ts --out .env.example --docs CONFIG.md"),2)}if(e==="watch"){let t=o.indexOf("--"),i=t===-1?o:o.slice(0,t),c=t===-1?[]:o.slice(t+1),{values:r}=parseArgs({args:i,allowNegative:!0,options:{schema:{type:"string",short:"s"},config:{type:"string",short:"c"},strict:{type:"boolean",default:!1},expand:{type:"boolean",default:!0},array:{type:"string",default:"replace"},format:{type:"string",default:"human"},once:{type:"boolean",default:!1},"exit-on-error":{type:"boolean",default:!1},"exit-on-child-error":{type:"boolean",default:!1},"schema-export":{type:"string"},prefix:{type:"string"},"secret-keys":{type:"string"}}});return r.array!==void 0&&!["replace","concat","mergeIndex"].includes(r.array)?(console.error(`E_USAGE: --array must be replace|concat|mergeIndex (got ${JSON.stringify(r.array)})`),2):r.format!==void 0&&!["human","json"].includes(r.format)?(console.error(`E_USAGE: --format must be human|json (got ${JSON.stringify(r.format)})`),2):await V({schema:r.schema,config:r.config,schemaExport:r["schema-export"],strict:r.strict,expand:r.expand,array:r.array,format:r.format,prefix:r.prefix,secretKeys:r["secret-keys"]?.split(",").map(a=>a.trim()).filter(Boolean),once:r.once,exitOnError:r["exit-on-error"],exitOnChildError:r["exit-on-child-error"],cmd:c.length?c:void 0})}return console.error(`E_USAGE: unknown command: ${e}`),2}catch(t){return console.error(`E_USAGE: ${t.message}`),2}}var me=process.argv[1]?.endsWith("main.js")||process.argv[1]?.endsWith("main.cjs");me&&de().then(n=>{process.exitCode=n;}).catch(n=>{console.error(n?.message??n),process.exitCode=2;});export{de as main};