@outfitter/config 0.1.0-rc.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.
- package/README.md +334 -0
- package/dist/index.d.ts +469 -0
- package/dist/index.js +9289 -0
- package/package.json +53 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,469 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
/**
|
|
3
|
+
* Port number schema (1-65535) with string-to-number coercion.
|
|
4
|
+
*
|
|
5
|
+
* Validates that a string contains only digits, then transforms
|
|
6
|
+
* to a number and validates the port range.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```typescript
|
|
10
|
+
* const schema = z.object({ PORT: portSchema });
|
|
11
|
+
* schema.parse({ PORT: "3000" }); // { PORT: 3000 }
|
|
12
|
+
* schema.parse({ PORT: "invalid" }); // throws
|
|
13
|
+
* schema.parse({ PORT: "99999" }); // throws (out of range)
|
|
14
|
+
* ```
|
|
15
|
+
*/
|
|
16
|
+
declare const portSchema: z.ZodType<number, string>;
|
|
17
|
+
/**
|
|
18
|
+
* Boolean schema with proper string coercion.
|
|
19
|
+
*
|
|
20
|
+
* Accepts: "true", "false", "1", "0", ""
|
|
21
|
+
* - "true" or "1" -> true
|
|
22
|
+
* - "false", "0", or "" -> false
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* ```typescript
|
|
26
|
+
* const schema = z.object({ DEBUG: booleanSchema });
|
|
27
|
+
* schema.parse({ DEBUG: "true" }); // { DEBUG: true }
|
|
28
|
+
* schema.parse({ DEBUG: "1" }); // { DEBUG: true }
|
|
29
|
+
* schema.parse({ DEBUG: "false" }); // { DEBUG: false }
|
|
30
|
+
* schema.parse({ DEBUG: "" }); // { DEBUG: false }
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
declare const booleanSchema: z.ZodType<boolean, string>;
|
|
34
|
+
/**
|
|
35
|
+
* Optional boolean schema - returns undefined if not set.
|
|
36
|
+
*
|
|
37
|
+
* Unlike `booleanSchema`, this returns `undefined` for missing
|
|
38
|
+
* or empty values, allowing callers to distinguish between
|
|
39
|
+
* "explicitly set to false" and "not set".
|
|
40
|
+
*
|
|
41
|
+
* @example
|
|
42
|
+
* ```typescript
|
|
43
|
+
* const schema = z.object({ NO_COLOR: optionalBooleanSchema });
|
|
44
|
+
* schema.parse({ NO_COLOR: "true" }); // { NO_COLOR: true }
|
|
45
|
+
* schema.parse({ NO_COLOR: "" }); // { NO_COLOR: undefined }
|
|
46
|
+
* schema.parse({ NO_COLOR: undefined }); // { NO_COLOR: undefined }
|
|
47
|
+
* ```
|
|
48
|
+
*/
|
|
49
|
+
declare const optionalBooleanSchema: z.ZodType<boolean | undefined, string | undefined>;
|
|
50
|
+
/**
|
|
51
|
+
* Parse and validate environment variables against a Zod schema.
|
|
52
|
+
*
|
|
53
|
+
* By default reads from `process.env`, but accepts a custom env
|
|
54
|
+
* object for testing.
|
|
55
|
+
*
|
|
56
|
+
* @typeParam T - The Zod schema shape
|
|
57
|
+
* @param schema - Zod object schema to validate against
|
|
58
|
+
* @param envObj - Environment object (defaults to process.env)
|
|
59
|
+
* @returns Validated and transformed environment object
|
|
60
|
+
* @throws {z.ZodError} When validation fails
|
|
61
|
+
*
|
|
62
|
+
* @example
|
|
63
|
+
* ```typescript
|
|
64
|
+
* const AppEnv = z.object({
|
|
65
|
+
* PORT: portSchema,
|
|
66
|
+
* DEBUG: booleanSchema,
|
|
67
|
+
* });
|
|
68
|
+
*
|
|
69
|
+
* const env = parseEnv(AppEnv);
|
|
70
|
+
* console.log(env.PORT); // number
|
|
71
|
+
* console.log(env.DEBUG); // boolean
|
|
72
|
+
* ```
|
|
73
|
+
*/
|
|
74
|
+
declare function parseEnv<T extends z.ZodRawShape>(schema: z.ZodObject<T>, envObj?: Record<string, string | undefined>): z.infer<z.ZodObject<T>>;
|
|
75
|
+
type AppEnvShape = {
|
|
76
|
+
NODE_ENV: z.ZodDefault<z.ZodEnum<{
|
|
77
|
+
development: "development";
|
|
78
|
+
test: "test";
|
|
79
|
+
production: "production";
|
|
80
|
+
}>>;
|
|
81
|
+
NO_COLOR: typeof optionalBooleanSchema;
|
|
82
|
+
FORCE_COLOR: typeof optionalBooleanSchema;
|
|
83
|
+
CI: typeof optionalBooleanSchema;
|
|
84
|
+
TERM: z.ZodOptional<z.ZodString>;
|
|
85
|
+
XDG_CONFIG_HOME: z.ZodOptional<z.ZodString>;
|
|
86
|
+
XDG_DATA_HOME: z.ZodOptional<z.ZodString>;
|
|
87
|
+
XDG_STATE_HOME: z.ZodOptional<z.ZodString>;
|
|
88
|
+
XDG_CACHE_HOME: z.ZodOptional<z.ZodString>;
|
|
89
|
+
HOME: z.ZodOptional<z.ZodString>;
|
|
90
|
+
};
|
|
91
|
+
/**
|
|
92
|
+
* Schema for common application environment variables.
|
|
93
|
+
*/
|
|
94
|
+
declare const appEnvSchema: z.ZodObject<AppEnvShape>;
|
|
95
|
+
/**
|
|
96
|
+
* Type for the pre-parsed application environment.
|
|
97
|
+
*/
|
|
98
|
+
type Env = z.infer<typeof appEnvSchema>;
|
|
99
|
+
/**
|
|
100
|
+
* Pre-parsed application environment.
|
|
101
|
+
*
|
|
102
|
+
* Access common environment variables with proper typing:
|
|
103
|
+
* - `env.NODE_ENV`: "development" | "test" | "production"
|
|
104
|
+
* - `env.NO_COLOR`: boolean | undefined
|
|
105
|
+
* - `env.FORCE_COLOR`: boolean | undefined
|
|
106
|
+
* - `env.CI`: boolean | undefined
|
|
107
|
+
* - `env.TERM`: string | undefined
|
|
108
|
+
* - `env.XDG_*`: string | undefined
|
|
109
|
+
* - `env.HOME`: string | undefined
|
|
110
|
+
*
|
|
111
|
+
* @example
|
|
112
|
+
* ```typescript
|
|
113
|
+
* import { env } from "@outfitter/config";
|
|
114
|
+
*
|
|
115
|
+
* if (env.CI) {
|
|
116
|
+
* console.log("Running in CI environment");
|
|
117
|
+
* }
|
|
118
|
+
*
|
|
119
|
+
* if (env.NO_COLOR) {
|
|
120
|
+
* // Disable color output
|
|
121
|
+
* }
|
|
122
|
+
* ```
|
|
123
|
+
*/
|
|
124
|
+
declare const env: Env;
|
|
125
|
+
/**
|
|
126
|
+
* Reads an optional boolean from process.env at call time.
|
|
127
|
+
*
|
|
128
|
+
* Unlike `env.NO_COLOR` (which is static), this reads dynamically
|
|
129
|
+
* for use cases where env vars may change at runtime (e.g., tests).
|
|
130
|
+
*
|
|
131
|
+
* @param key - The environment variable name to read
|
|
132
|
+
* @returns `true` if "true"/"1", `false` if "false"/"0", `undefined` otherwise
|
|
133
|
+
*
|
|
134
|
+
* @example
|
|
135
|
+
* ```typescript
|
|
136
|
+
* // For terminal detection that needs dynamic behavior
|
|
137
|
+
* if (getEnvBoolean("NO_COLOR")) {
|
|
138
|
+
* // colors disabled
|
|
139
|
+
* }
|
|
140
|
+
* ```
|
|
141
|
+
*/
|
|
142
|
+
declare function getEnvBoolean(key: "NO_COLOR" | "FORCE_COLOR" | "CI"): boolean | undefined;
|
|
143
|
+
import { TaggedErrorClass } from "@outfitter/contracts";
|
|
144
|
+
import { NotFoundError, Result, ValidationError } from "@outfitter/contracts";
|
|
145
|
+
import { ZodSchema } from "zod";
|
|
146
|
+
type ParseErrorFields = {
|
|
147
|
+
/** Human-readable error message describing the parse failure */
|
|
148
|
+
message: string;
|
|
149
|
+
/** Name of the file that failed to parse */
|
|
150
|
+
filename: string;
|
|
151
|
+
/** Line number where the error occurred (if available) */
|
|
152
|
+
line?: number;
|
|
153
|
+
/** Column number where the error occurred (if available) */
|
|
154
|
+
column?: number;
|
|
155
|
+
};
|
|
156
|
+
declare const ParseErrorBase: TaggedErrorClass<"ParseError", ParseErrorFields>;
|
|
157
|
+
/**
|
|
158
|
+
* Error thrown when a configuration file cannot be parsed.
|
|
159
|
+
*
|
|
160
|
+
* Contains details about the parse failure including the filename
|
|
161
|
+
* and optionally the line/column where the error occurred.
|
|
162
|
+
*
|
|
163
|
+
* @example
|
|
164
|
+
* ```typescript
|
|
165
|
+
* const result = parseConfigFile("invalid toml [", "config.toml");
|
|
166
|
+
* if (result.isErr() && result.error._tag === "ParseError") {
|
|
167
|
+
* console.error(`Parse error in ${result.error.filename}: ${result.error.message}`);
|
|
168
|
+
* }
|
|
169
|
+
* ```
|
|
170
|
+
*/
|
|
171
|
+
declare class ParseError extends ParseErrorBase {
|
|
172
|
+
readonly category: "validation";
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Get the XDG config directory for an application.
|
|
176
|
+
*
|
|
177
|
+
* Uses `XDG_CONFIG_HOME` if set, otherwise defaults to `~/.config`.
|
|
178
|
+
* This follows the XDG Base Directory Specification for storing
|
|
179
|
+
* user-specific configuration files.
|
|
180
|
+
*
|
|
181
|
+
* @param appName - Application name used as subdirectory
|
|
182
|
+
* @returns Absolute path to the application's config directory
|
|
183
|
+
*
|
|
184
|
+
* @example
|
|
185
|
+
* ```typescript
|
|
186
|
+
* // With XDG_CONFIG_HOME="/custom/config"
|
|
187
|
+
* getConfigDir("myapp"); // "/custom/config/myapp"
|
|
188
|
+
*
|
|
189
|
+
* // Without XDG_CONFIG_HOME (uses default)
|
|
190
|
+
* getConfigDir("myapp"); // "/home/user/.config/myapp"
|
|
191
|
+
* ```
|
|
192
|
+
*/
|
|
193
|
+
declare function getConfigDir(appName: string): string;
|
|
194
|
+
/**
|
|
195
|
+
* Get the XDG data directory for an application.
|
|
196
|
+
*
|
|
197
|
+
* Uses `XDG_DATA_HOME` if set, otherwise defaults to `~/.local/share`.
|
|
198
|
+
* This follows the XDG Base Directory Specification for storing
|
|
199
|
+
* user-specific data files (databases, generated content, etc.).
|
|
200
|
+
*
|
|
201
|
+
* @param appName - Application name used as subdirectory
|
|
202
|
+
* @returns Absolute path to the application's data directory
|
|
203
|
+
*
|
|
204
|
+
* @example
|
|
205
|
+
* ```typescript
|
|
206
|
+
* // With XDG_DATA_HOME="/custom/data"
|
|
207
|
+
* getDataDir("myapp"); // "/custom/data/myapp"
|
|
208
|
+
*
|
|
209
|
+
* // Without XDG_DATA_HOME (uses default)
|
|
210
|
+
* getDataDir("myapp"); // "/home/user/.local/share/myapp"
|
|
211
|
+
* ```
|
|
212
|
+
*/
|
|
213
|
+
declare function getDataDir(appName: string): string;
|
|
214
|
+
/**
|
|
215
|
+
* Get the XDG cache directory for an application.
|
|
216
|
+
*
|
|
217
|
+
* Uses `XDG_CACHE_HOME` if set, otherwise defaults to `~/.cache`.
|
|
218
|
+
* This follows the XDG Base Directory Specification for storing
|
|
219
|
+
* non-essential cached data that can be regenerated.
|
|
220
|
+
*
|
|
221
|
+
* @param appName - Application name used as subdirectory
|
|
222
|
+
* @returns Absolute path to the application's cache directory
|
|
223
|
+
*
|
|
224
|
+
* @example
|
|
225
|
+
* ```typescript
|
|
226
|
+
* // With XDG_CACHE_HOME="/custom/cache"
|
|
227
|
+
* getCacheDir("myapp"); // "/custom/cache/myapp"
|
|
228
|
+
*
|
|
229
|
+
* // Without XDG_CACHE_HOME (uses default)
|
|
230
|
+
* getCacheDir("myapp"); // "/home/user/.cache/myapp"
|
|
231
|
+
* ```
|
|
232
|
+
*/
|
|
233
|
+
declare function getCacheDir(appName: string): string;
|
|
234
|
+
/**
|
|
235
|
+
* Get the XDG state directory for an application.
|
|
236
|
+
*
|
|
237
|
+
* Uses `XDG_STATE_HOME` if set, otherwise defaults to `~/.local/state`.
|
|
238
|
+
* This follows the XDG Base Directory Specification for storing
|
|
239
|
+
* state data that should persist between restarts (logs, history, etc.).
|
|
240
|
+
*
|
|
241
|
+
* @param appName - Application name used as subdirectory
|
|
242
|
+
* @returns Absolute path to the application's state directory
|
|
243
|
+
*
|
|
244
|
+
* @example
|
|
245
|
+
* ```typescript
|
|
246
|
+
* // With XDG_STATE_HOME="/custom/state"
|
|
247
|
+
* getStateDir("myapp"); // "/custom/state/myapp"
|
|
248
|
+
*
|
|
249
|
+
* // Without XDG_STATE_HOME (uses default)
|
|
250
|
+
* getStateDir("myapp"); // "/home/user/.local/state/myapp"
|
|
251
|
+
* ```
|
|
252
|
+
*/
|
|
253
|
+
declare function getStateDir(appName: string): string;
|
|
254
|
+
/**
|
|
255
|
+
* Deep merge two objects with configurable merge semantics.
|
|
256
|
+
*
|
|
257
|
+
* Merge behavior:
|
|
258
|
+
* - Recursively merges nested plain objects
|
|
259
|
+
* - Arrays are replaced (not concatenated)
|
|
260
|
+
* - `null` explicitly replaces the target value
|
|
261
|
+
* - `undefined` is skipped (does not override)
|
|
262
|
+
*
|
|
263
|
+
* @typeParam T - The type of the target object
|
|
264
|
+
* @param target - Base object to merge into (not mutated)
|
|
265
|
+
* @param source - Object with values to merge
|
|
266
|
+
* @returns New object with merged values
|
|
267
|
+
*
|
|
268
|
+
* @example
|
|
269
|
+
* ```typescript
|
|
270
|
+
* const defaults = { server: { port: 3000, host: "localhost" } };
|
|
271
|
+
* const overrides = { server: { port: 8080 } };
|
|
272
|
+
*
|
|
273
|
+
* const merged = deepMerge(defaults, overrides);
|
|
274
|
+
* // { server: { port: 8080, host: "localhost" } }
|
|
275
|
+
* ```
|
|
276
|
+
*
|
|
277
|
+
* @example
|
|
278
|
+
* ```typescript
|
|
279
|
+
* // Arrays replace, not merge
|
|
280
|
+
* const target = { tags: ["a", "b"] };
|
|
281
|
+
* const source = { tags: ["c"] };
|
|
282
|
+
* deepMerge(target, source); // { tags: ["c"] }
|
|
283
|
+
*
|
|
284
|
+
* // undefined is skipped
|
|
285
|
+
* const base = { a: 1, b: 2 };
|
|
286
|
+
* deepMerge(base, { a: undefined, b: 3 }); // { a: 1, b: 3 }
|
|
287
|
+
*
|
|
288
|
+
* // null explicitly replaces
|
|
289
|
+
* deepMerge(base, { a: null }); // { a: null, b: 2 }
|
|
290
|
+
* ```
|
|
291
|
+
*/
|
|
292
|
+
declare function deepMerge<T extends object>(target: T, source: Partial<T>): T;
|
|
293
|
+
/**
|
|
294
|
+
* Parse configuration file content based on filename extension.
|
|
295
|
+
*
|
|
296
|
+
* Supports multiple formats:
|
|
297
|
+
* - `.toml` - Parsed with smol-toml (preferred for config)
|
|
298
|
+
* - `.yaml`, `.yml` - Parsed with yaml (merge key support enabled)
|
|
299
|
+
* - `.json` - Parsed with strict JSON.parse
|
|
300
|
+
* - `.json5` - Parsed with json5 (comments and trailing commas allowed)
|
|
301
|
+
*
|
|
302
|
+
* @param content - Raw file content to parse
|
|
303
|
+
* @param filename - Filename used to determine format (by extension)
|
|
304
|
+
* @returns Result containing parsed object or ParseError
|
|
305
|
+
*
|
|
306
|
+
* @example
|
|
307
|
+
* ```typescript
|
|
308
|
+
* const toml = `
|
|
309
|
+
* [server]
|
|
310
|
+
* port = 3000
|
|
311
|
+
* host = "localhost"
|
|
312
|
+
* `;
|
|
313
|
+
*
|
|
314
|
+
* const result = parseConfigFile(toml, "config.toml");
|
|
315
|
+
* if (result.isOk()) {
|
|
316
|
+
* console.log(result.value.server.port); // 3000
|
|
317
|
+
* }
|
|
318
|
+
* ```
|
|
319
|
+
*
|
|
320
|
+
* @example
|
|
321
|
+
* ```typescript
|
|
322
|
+
* // YAML with anchors/aliases
|
|
323
|
+
* const yaml = `
|
|
324
|
+
* defaults: &defaults
|
|
325
|
+
* timeout: 5000
|
|
326
|
+
* server:
|
|
327
|
+
* <<: *defaults
|
|
328
|
+
* port: 3000
|
|
329
|
+
* `;
|
|
330
|
+
*
|
|
331
|
+
* const result = parseConfigFile(yaml, "config.yaml");
|
|
332
|
+
* if (result.isOk()) {
|
|
333
|
+
* console.log(result.value.server.timeout); // 5000
|
|
334
|
+
* }
|
|
335
|
+
* ```
|
|
336
|
+
*/
|
|
337
|
+
declare function parseConfigFile(content: string, filename: string): Result<Record<string, unknown>, InstanceType<typeof ParseError>>;
|
|
338
|
+
/**
|
|
339
|
+
* Configuration sources for multi-layer resolution.
|
|
340
|
+
*
|
|
341
|
+
* Sources are merged in precedence order (lowest to highest):
|
|
342
|
+
* `defaults` < `file` < `env` < `flags`
|
|
343
|
+
*
|
|
344
|
+
* @typeParam T - The configuration type
|
|
345
|
+
*
|
|
346
|
+
* @example
|
|
347
|
+
* ```typescript
|
|
348
|
+
* const sources: ConfigSources<AppConfig> = {
|
|
349
|
+
* defaults: { timeout: 5000, debug: false },
|
|
350
|
+
* file: loadedFromDisk,
|
|
351
|
+
* env: { timeout: parseInt(process.env.TIMEOUT!) },
|
|
352
|
+
* flags: { debug: cliArgs.debug },
|
|
353
|
+
* };
|
|
354
|
+
* ```
|
|
355
|
+
*/
|
|
356
|
+
interface ConfigSources<T> {
|
|
357
|
+
/** Default values (lowest precedence) */
|
|
358
|
+
defaults?: Partial<T>;
|
|
359
|
+
/** Values loaded from config file */
|
|
360
|
+
file?: Partial<T>;
|
|
361
|
+
/** Values from environment variables */
|
|
362
|
+
env?: Partial<T>;
|
|
363
|
+
/** CLI flag values (highest precedence) */
|
|
364
|
+
flags?: Partial<T>;
|
|
365
|
+
}
|
|
366
|
+
/**
|
|
367
|
+
* Resolve configuration from multiple sources with precedence.
|
|
368
|
+
*
|
|
369
|
+
* Merges sources in order: `defaults` < `file` < `env` < `flags`.
|
|
370
|
+
* Higher precedence sources override lower ones. Nested objects
|
|
371
|
+
* are deep-merged; arrays are replaced.
|
|
372
|
+
*
|
|
373
|
+
* The merged result is validated against the provided Zod schema.
|
|
374
|
+
*
|
|
375
|
+
* @typeParam T - The configuration type (inferred from schema)
|
|
376
|
+
* @param schema - Zod schema for validation
|
|
377
|
+
* @param sources - Configuration sources to merge
|
|
378
|
+
* @returns Result containing validated config or ValidationError/ParseError
|
|
379
|
+
*
|
|
380
|
+
* @example
|
|
381
|
+
* ```typescript
|
|
382
|
+
* const AppSchema = z.object({
|
|
383
|
+
* port: z.number().min(1).max(65535),
|
|
384
|
+
* host: z.string(),
|
|
385
|
+
* debug: z.boolean().default(false),
|
|
386
|
+
* });
|
|
387
|
+
*
|
|
388
|
+
* const result = resolveConfig(AppSchema, {
|
|
389
|
+
* defaults: { port: 3000, host: "localhost" },
|
|
390
|
+
* file: { port: 8080 },
|
|
391
|
+
* env: { debug: true },
|
|
392
|
+
* flags: { port: 9000 },
|
|
393
|
+
* });
|
|
394
|
+
*
|
|
395
|
+
* if (result.isOk()) {
|
|
396
|
+
* // { port: 9000, host: "localhost", debug: true }
|
|
397
|
+
* console.log(result.value);
|
|
398
|
+
* }
|
|
399
|
+
* ```
|
|
400
|
+
*/
|
|
401
|
+
declare function resolveConfig<T>(schema: ZodSchema<T>, sources: ConfigSources<T>): Result<T, InstanceType<typeof ValidationError> | InstanceType<typeof ParseError>>;
|
|
402
|
+
/**
|
|
403
|
+
* Options for the {@link loadConfig} function.
|
|
404
|
+
*
|
|
405
|
+
* @example
|
|
406
|
+
* ```typescript
|
|
407
|
+
* const options: LoadConfigOptions = {
|
|
408
|
+
* searchPaths: ["/etc/myapp", "/opt/myapp/config"],
|
|
409
|
+
* };
|
|
410
|
+
* ```
|
|
411
|
+
*/
|
|
412
|
+
interface LoadConfigOptions {
|
|
413
|
+
/**
|
|
414
|
+
* Custom search paths to check for config files.
|
|
415
|
+
* When provided, overrides the default XDG-based search paths.
|
|
416
|
+
* Paths are searched in order; first match wins.
|
|
417
|
+
*/
|
|
418
|
+
searchPaths?: string[];
|
|
419
|
+
}
|
|
420
|
+
/**
|
|
421
|
+
* Load configuration for an application from XDG-compliant paths.
|
|
422
|
+
*
|
|
423
|
+
* Search order (first found wins):
|
|
424
|
+
* 1. Custom `searchPaths` if provided in options
|
|
425
|
+
* 2. `$XDG_CONFIG_HOME/{appName}/config.{ext}`
|
|
426
|
+
* 3. `~/.config/{appName}/config.{ext}`
|
|
427
|
+
*
|
|
428
|
+
* File format preference: `.toml` > `.yaml` > `.yml` > `.json` > `.json5`
|
|
429
|
+
*
|
|
430
|
+
* @typeParam T - The configuration type (inferred from schema)
|
|
431
|
+
* @param appName - Application name for XDG directory lookup
|
|
432
|
+
* @param schema - Zod schema for validation
|
|
433
|
+
* @param options - Optional configuration (custom search paths)
|
|
434
|
+
* @returns Result containing validated config or NotFoundError/ValidationError/ParseError
|
|
435
|
+
*
|
|
436
|
+
* @example
|
|
437
|
+
* ```typescript
|
|
438
|
+
* import { loadConfig } from "@outfitter/config";
|
|
439
|
+
* import { z } from "zod";
|
|
440
|
+
*
|
|
441
|
+
* const AppConfigSchema = z.object({
|
|
442
|
+
* apiKey: z.string(),
|
|
443
|
+
* timeout: z.number().default(5000),
|
|
444
|
+
* features: z.object({
|
|
445
|
+
* darkMode: z.boolean().default(false),
|
|
446
|
+
* }),
|
|
447
|
+
* });
|
|
448
|
+
*
|
|
449
|
+
* // Searches ~/.config/myapp/config.{toml,yaml,json,...}
|
|
450
|
+
* const result = await loadConfig("myapp", AppConfigSchema);
|
|
451
|
+
*
|
|
452
|
+
* if (result.isOk()) {
|
|
453
|
+
* console.log("API Key:", result.value.apiKey);
|
|
454
|
+
* console.log("Timeout:", result.value.timeout);
|
|
455
|
+
* } else {
|
|
456
|
+
* console.error("Failed to load config:", result.error.message);
|
|
457
|
+
* }
|
|
458
|
+
* ```
|
|
459
|
+
*
|
|
460
|
+
* @example
|
|
461
|
+
* ```typescript
|
|
462
|
+
* // With custom search paths
|
|
463
|
+
* const result = await loadConfig("myapp", AppConfigSchema, {
|
|
464
|
+
* searchPaths: ["/etc/myapp", "/opt/myapp/config"],
|
|
465
|
+
* });
|
|
466
|
+
* ```
|
|
467
|
+
*/
|
|
468
|
+
declare function loadConfig<T>(appName: string, schema: ZodSchema<T>, options?: LoadConfigOptions): Result<T, InstanceType<typeof NotFoundError> | InstanceType<typeof ValidationError> | InstanceType<typeof ParseError>>;
|
|
469
|
+
export { resolveConfig, portSchema, parseEnv, parseConfigFile, optionalBooleanSchema, loadConfig, getStateDir, getEnvBoolean, getDataDir, getConfigDir, getCacheDir, env, deepMerge, booleanSchema, ParseError, LoadConfigOptions, Env, ConfigSources };
|