@spfn/core 0.1.0-alpha.88 → 0.2.0-beta.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 (71) hide show
  1. package/README.md +1046 -384
  2. package/dist/boss-D-fGtVgM.d.ts +187 -0
  3. package/dist/cache/index.d.ts +13 -33
  4. package/dist/cache/index.js +14 -703
  5. package/dist/cache/index.js.map +1 -1
  6. package/dist/codegen/index.d.ts +167 -17
  7. package/dist/codegen/index.js +76 -1419
  8. package/dist/codegen/index.js.map +1 -1
  9. package/dist/config/index.d.ts +1191 -0
  10. package/dist/config/index.js +264 -0
  11. package/dist/config/index.js.map +1 -0
  12. package/dist/db/index.d.ts +728 -59
  13. package/dist/db/index.js +1028 -1225
  14. package/dist/db/index.js.map +1 -1
  15. package/dist/env/index.d.ts +579 -308
  16. package/dist/env/index.js +438 -930
  17. package/dist/env/index.js.map +1 -1
  18. package/dist/errors/index.d.ts +417 -29
  19. package/dist/errors/index.js +359 -98
  20. package/dist/errors/index.js.map +1 -1
  21. package/dist/event/index.d.ts +108 -0
  22. package/dist/event/index.js +122 -0
  23. package/dist/event/index.js.map +1 -0
  24. package/dist/job/index.d.ts +172 -0
  25. package/dist/job/index.js +361 -0
  26. package/dist/job/index.js.map +1 -0
  27. package/dist/logger/index.d.ts +20 -79
  28. package/dist/logger/index.js +82 -387
  29. package/dist/logger/index.js.map +1 -1
  30. package/dist/middleware/index.d.ts +2 -11
  31. package/dist/middleware/index.js +49 -703
  32. package/dist/middleware/index.js.map +1 -1
  33. package/dist/nextjs/index.d.ts +120 -0
  34. package/dist/nextjs/index.js +416 -0
  35. package/dist/nextjs/index.js.map +1 -0
  36. package/dist/{client/nextjs/index.d.ts → nextjs/server.d.ts} +288 -262
  37. package/dist/nextjs/server.js +568 -0
  38. package/dist/nextjs/server.js.map +1 -0
  39. package/dist/route/index.d.ts +667 -25
  40. package/dist/route/index.js +437 -1287
  41. package/dist/route/index.js.map +1 -1
  42. package/dist/route/types.d.ts +38 -0
  43. package/dist/route/types.js +3 -0
  44. package/dist/route/types.js.map +1 -0
  45. package/dist/server/index.d.ts +201 -67
  46. package/dist/server/index.js +921 -3182
  47. package/dist/server/index.js.map +1 -1
  48. package/dist/types-BGl4QL1w.d.ts +77 -0
  49. package/dist/types-DRG2XMTR.d.ts +157 -0
  50. package/package.json +52 -47
  51. package/dist/auto-loader-JFaZ9gON.d.ts +0 -80
  52. package/dist/client/index.d.ts +0 -358
  53. package/dist/client/index.js +0 -357
  54. package/dist/client/index.js.map +0 -1
  55. package/dist/client/nextjs/index.js +0 -371
  56. package/dist/client/nextjs/index.js.map +0 -1
  57. package/dist/codegen/generators/index.d.ts +0 -19
  58. package/dist/codegen/generators/index.js +0 -1404
  59. package/dist/codegen/generators/index.js.map +0 -1
  60. package/dist/database-errors-BNNmLTJE.d.ts +0 -86
  61. package/dist/events/index.d.ts +0 -183
  62. package/dist/events/index.js +0 -77
  63. package/dist/events/index.js.map +0 -1
  64. package/dist/index-DHiAqhKv.d.ts +0 -101
  65. package/dist/index.d.ts +0 -8
  66. package/dist/index.js +0 -3674
  67. package/dist/index.js.map +0 -1
  68. package/dist/types/index.d.ts +0 -121
  69. package/dist/types/index.js +0 -38
  70. package/dist/types/index.js.map +0 -1
  71. package/dist/types-BXibIEyj.d.ts +0 -60
@@ -1,508 +1,779 @@
1
+ export { L as LogLevel } from '../types-BGl4QL1w.js';
2
+
1
3
  /**
2
- * Environment Variable Management - Configuration Types
4
+ * Environment Variable Management - Parsers
3
5
  *
4
- * Type definitions for centralized environment variable loading
6
+ * Parser functions that transform and validate environment variable strings.
7
+ * All parsers follow the pattern: (value: string) => T or throw Error
5
8
  */
6
9
  /**
7
- * Options for loading environment variables
10
+ * Parser function that transforms and validates a string value
11
+ * @throws Error if validation fails
8
12
  */
9
- interface LoadEnvironmentOptions {
10
- /**
11
- * Base directory for .env files
12
- * @default process.cwd()
13
- */
14
- basePath?: string;
15
- /**
16
- * Additional custom paths to load
17
- * Loaded after standard files
18
- * @default []
19
- */
20
- customPaths?: string[];
21
- /**
22
- * Enable debug logging
23
- * @default false
24
- */
25
- debug?: boolean;
26
- /**
27
- * Override NODE_ENV for file selection
28
- * @default process.env.NODE_ENV
29
- */
30
- nodeEnv?: string;
31
- /**
32
- * Required environment variables
33
- * Throws error if any are missing after loading
34
- * @default []
35
- */
36
- required?: string[];
37
- /**
38
- * Skip loading if environment already loaded
39
- * Set to false to force reload (useful for testing)
40
- * @default true
41
- */
42
- useCache?: boolean;
43
- }
13
+ type Parser<T> = (value: string) => T;
44
14
  /**
45
- * Result of environment loading operation
15
+ * Parse a non-empty string
16
+ *
17
+ * @param value - Value to parse
18
+ * @returns Trimmed string
19
+ * @throws Error if string is empty after trimming
20
+ *
21
+ * @example
22
+ * ```typescript
23
+ * const name = getEnvVar('APP_NAME', {
24
+ * validator: parseString,
25
+ * });
26
+ * ```
46
27
  */
47
- interface LoadResult {
48
- /**
49
- * Whether loading was successful overall
50
- */
51
- success: boolean;
52
- /**
53
- * Files that were successfully loaded
54
- */
55
- loaded: string[];
56
- /**
57
- * Files that failed to load (with reasons)
58
- */
59
- failed: Array<{
60
- path: string;
61
- reason: string;
62
- }>;
63
- /**
64
- * Environment variables that were parsed from files
65
- */
66
- parsed: Record<string, string>;
67
- /**
68
- * Error messages if any critical errors occurred
69
- */
70
- errors?: string[];
71
- /**
72
- * Warning messages for non-critical issues
73
- */
74
- warnings: string[];
75
- }
28
+ declare function parseString(value: string): string;
76
29
  /**
77
- * Options for getting environment variables
30
+ * Create a string parser with validation rules
31
+ *
32
+ * @param options - Validation options
33
+ * @returns Parser function
34
+ *
35
+ * @example
36
+ * ```typescript
37
+ * const apiKey = getEnvVar('API_KEY', {
38
+ * validator: createStringParser({
39
+ * minLength: 32,
40
+ * pattern: /^[A-Za-z0-9_-]+$/,
41
+ * }),
42
+ * });
43
+ * ```
78
44
  */
79
- interface GetEnvOptions {
80
- /**
81
- * Throw error if variable not found
82
- * @default false
83
- */
84
- required?: boolean;
85
- /**
86
- * Default value if variable not found
87
- * Only used if required is false
88
- */
89
- default?: string;
90
- /**
91
- * Custom validation function
92
- * Return true if valid, false if invalid
93
- */
94
- validator?: (value: string) => boolean;
95
- /**
96
- * Custom error message for validation failure
97
- */
98
- validationError?: string;
99
- }
45
+ declare function createStringParser(options?: {
46
+ minLength?: number;
47
+ maxLength?: number;
48
+ pattern?: RegExp;
49
+ trim?: boolean;
50
+ }): Parser<string>;
100
51
  /**
101
- * Standard environment file names in priority order
52
+ * Parse a boolean environment variable
102
53
  *
103
- * Next.js-style loading behavior:
104
- * - development: .env.env.development → .env.local → .env.development.local
105
- * - production: .env → .env.production → .env.local → .env.production.local
106
- * - test: .env → .env.test → (skip .env.local) → .env.test.local
54
+ * Accepts: 'true', '1', 'yes' (case-insensitive) true
55
+ * 'false', '0', 'no' (case-insensitive)false
107
56
  *
108
- * Note: .env.local is excluded in test environment for proper test isolation
57
+ * @param value - Value to parse
58
+ * @returns Boolean value
59
+ * @throws Error if value is not a valid boolean string
60
+ *
61
+ * @example
62
+ * ```typescript
63
+ * const debug = getEnvVar('DEBUG', {
64
+ * default: 'false',
65
+ * validator: parseBoolean,
66
+ * });
67
+ * ```
109
68
  */
110
- declare const ENV_FILE_PRIORITY: readonly [".env", ".env.{NODE_ENV}", ".env.local", ".env.{NODE_ENV}.local"];
69
+ declare function parseBoolean(value: string): boolean;
111
70
  /**
112
- * Environment files that should only be loaded in test environment
71
+ * Parse and validate number
72
+ *
73
+ * @param value - Value to parse
74
+ * @param options - Validation options
75
+ * @returns Parsed number
76
+ * @throws Error if invalid number or constraint violation
77
+ *
78
+ * @example
79
+ * ```typescript
80
+ * const port = getEnvVar('PORT', {
81
+ * default: '3000',
82
+ * validator: (val) => parseNumber(val, { min: 1, max: 65535, integer: true }),
83
+ * });
84
+ * ```
113
85
  */
114
- declare const TEST_ONLY_FILES: readonly [".env.test", ".env.test.local"];
115
-
86
+ declare function parseNumber(value: string, options?: {
87
+ min?: number;
88
+ max?: number;
89
+ integer?: boolean;
90
+ }): number;
116
91
  /**
117
- * Environment Variable Management - Core Loader
92
+ * Create a number parser with specific constraints
93
+ *
94
+ * @param options - Validation constraints
95
+ * @returns Parser function
118
96
  *
119
- * Centralized singleton environment variable loader with dotenv priority support
97
+ * @example
98
+ * ```typescript
99
+ * const port = getEnvVar('PORT', {
100
+ * default: '3000',
101
+ * validator: createNumberParser({ min: 1, max: 65535, integer: true }),
102
+ * });
103
+ * ```
120
104
  */
121
-
105
+ declare function createNumberParser(options?: {
106
+ min?: number;
107
+ max?: number;
108
+ integer?: boolean;
109
+ }): Parser<number>;
122
110
  /**
123
- * Load environment variables from .env files with Next.js-style priority
111
+ * Parse integer with optional constraints
124
112
  *
125
- * Loading behavior by environment:
126
- * - (no NODE_ENV): .env → .env.local
127
- * - development: .env → .env.development → .env.local → .env.development.local
128
- * - production: .env .env.production .env.local .env.production.local
129
- * - test: .env → .env.test → (skip .env.local) → .env.test.local
130
- * - local: .env → .env.local → .env.local.local (duplicate .env.local prevented)
131
- * - staging/qa/etc: .env → .env.{NODE_ENV} → .env.local → .env.{NODE_ENV}.local
113
+ * @param value - Value to parse
114
+ * @param options - Min/max constraints
115
+ * @returns Parsed integer
116
+ * @throws Error if invalid or out of range
132
117
  *
133
- * Notes:
134
- * - .env.local is excluded in test environment for proper test isolation
135
- * - Any custom NODE_ENV value is supported (staging, qa, uat, preview, etc.)
136
- * - If NODE_ENV is not set, .env and .env.local are loaded
118
+ * @example
119
+ * ```typescript
120
+ * const retries = getEnvVar('MAX_RETRIES', {
121
+ * default: '3',
122
+ * validator: (val) => parseInteger(val, { min: 1, max: 10 }),
123
+ * });
124
+ * ```
125
+ */
126
+ declare function parseInteger(value: string, options?: {
127
+ min?: number;
128
+ max?: number;
129
+ }): number;
130
+ /**
131
+ * Parse float/decimal number with optional constraints
137
132
  *
138
- * @param options - Loading options
139
- * @returns Load result with success status and loaded variables
133
+ * @param value - Value to parse
134
+ * @param options - Min/max constraints
135
+ * @returns Parsed decimal number
136
+ * @throws Error if invalid or out of range
140
137
  *
141
138
  * @example
142
139
  * ```typescript
143
- * // Simple usage (no NODE_ENV set)
144
- * const result = loadEnvironment();
145
- *
146
- * // With NODE_ENV=local
147
- * process.env.NODE_ENV = 'local';
148
- * const result = loadEnvironment({
149
- * debug: true,
150
- * required: ['DATABASE_URL'],
140
+ * const ratio = getEnvVar('CACHE_RATIO', {
141
+ * default: '0.75',
142
+ * validator: (val) => parseDecimal(val, { min: 0, max: 1 }),
151
143
  * });
152
- *
153
- * // With custom environment
154
- * process.env.NODE_ENV = 'staging';
155
- * const result = loadEnvironment();
156
144
  * ```
157
145
  */
158
- declare function loadEnvironment(options?: LoadEnvironmentOptions): LoadResult;
146
+ declare function parseDecimal(value: string, options?: {
147
+ min?: number;
148
+ max?: number;
149
+ }): number;
159
150
  /**
160
- * Get an environment variable with optional validation
151
+ * Parse and validate URL
161
152
  *
162
- * @param key - Environment variable name
163
- * @param options - Get options (default, required, validator)
164
- * @returns Variable value or undefined
165
- * @throws Error if required and not found, or validation fails
153
+ * @param value - Value to parse
154
+ * @param options - Validation options
155
+ * @returns Validated URL string
156
+ * @throws Error if invalid URL or protocol mismatch
166
157
  *
167
158
  * @example
168
159
  * ```typescript
169
- * // Simple get
170
- * const dbUrl = getEnvVar('DATABASE_URL');
171
- *
172
- * // With default
173
- * const port = getEnvVar('PORT', { default: '3000' });
160
+ * const apiUrl = getEnvVar('API_URL', {
161
+ * validator: (val) => parseUrl(val, { protocol: 'https' }),
162
+ * });
163
+ * ```
164
+ */
165
+ declare function parseUrl(value: string, options?: {
166
+ protocol?: 'http' | 'https' | 'any';
167
+ }): string;
168
+ /**
169
+ * Create a URL parser with specific protocol requirement
174
170
  *
175
- * // Required
176
- * const apiKey = getEnvVar('API_KEY', { required: true });
171
+ * @param protocol - Required protocol ('http', 'https', or 'any')
172
+ * @returns Parser function
177
173
  *
178
- * // With validation
179
- * const url = getEnvVar('API_URL', {
180
- * validator: (val) => val.startsWith('https://'),
181
- * validationError: 'API_URL must use HTTPS',
174
+ * @example
175
+ * ```typescript
176
+ * const apiUrl = getEnvVar('API_URL', {
177
+ * validator: createUrlParser('https'),
182
178
  * });
183
179
  * ```
184
180
  */
185
- declare function getEnvVar(key: string, options?: GetEnvOptions): string | undefined;
181
+ declare function createUrlParser(protocol?: 'http' | 'https' | 'any'): Parser<string>;
186
182
  /**
187
- * Get a required environment variable
183
+ * Parse PostgreSQL connection string
188
184
  *
189
- * @param key - Environment variable name
190
- * @returns Variable value
191
- * @throws Error if not found
185
+ * @param value - Value to parse
186
+ * @returns Validated PostgreSQL URL string
187
+ * @throws Error if invalid PostgreSQL URL
192
188
  *
193
189
  * @example
194
190
  * ```typescript
195
- * const dbUrl = requireEnvVar('DATABASE_URL');
191
+ * const dbUrl = getEnvVar('DATABASE_URL', {
192
+ * required: true,
193
+ * validator: parsePostgresUrl,
194
+ * });
196
195
  * ```
197
196
  */
198
- declare function requireEnvVar(key: string): string;
197
+ declare function parsePostgresUrl(value: string): string;
199
198
  /**
200
- * Check if an environment variable exists
199
+ * Parse Redis connection string
201
200
  *
202
- * @param key - Environment variable name
203
- * @returns True if variable exists and is non-empty
201
+ * @param value - Value to parse
202
+ * @returns Validated Redis URL string
203
+ * @throws Error if invalid Redis URL
204
204
  *
205
205
  * @example
206
206
  * ```typescript
207
- * if (hasEnvVar('REDIS_URL')) {
208
- * // Use Redis
209
- * }
207
+ * const redisUrl = getEnvVar('REDIS_URL', {
208
+ * required: true,
209
+ * validator: parseRedisUrl,
210
+ * });
210
211
  * ```
211
212
  */
212
- declare function hasEnvVar(key: string): boolean;
213
+ declare function parseRedisUrl(value: string): string;
213
214
  /**
214
- * Get multiple environment variables at once
215
+ * Parse and validate enum value
215
216
  *
216
- * @param keys - Array of environment variable names
217
- * @returns Object mapping keys to values (undefined if not found)
217
+ * @param value - Value to parse
218
+ * @param allowed - Array of allowed values
219
+ * @param caseInsensitive - Whether to perform case-insensitive comparison
220
+ * @returns Validated enum value
221
+ * @throws Error if value not in allowed list
218
222
  *
219
223
  * @example
220
224
  * ```typescript
221
- * const { DATABASE_URL, REDIS_URL } = getEnvVars([
222
- * 'DATABASE_URL',
223
- * 'REDIS_URL',
224
- * ]);
225
+ * const env = getEnvVar('NODE_ENV', {
226
+ * validator: (val) => parseEnum(val, ['development', 'production', 'test']),
227
+ * });
225
228
  * ```
226
229
  */
227
- declare function getEnvVars(keys: string[]): Record<string, string | undefined>;
230
+ declare function parseEnum(value: string, allowed: string[], caseInsensitive?: boolean): string;
228
231
  /**
229
- * Check if environment has been loaded
232
+ * Create an enum parser with specific allowed values
230
233
  *
231
- * @returns True if loadEnvironment has been called successfully
234
+ * @param allowed - Array of allowed values
235
+ * @param caseInsensitive - Whether to perform case-insensitive comparison
236
+ * @returns Parser function
232
237
  *
233
238
  * @example
234
239
  * ```typescript
235
- * if (!isEnvironmentLoaded()) {
236
- * loadEnvironment();
237
- * }
240
+ * const logLevel = getEnvVar('LOG_LEVEL', {
241
+ * default: 'info',
242
+ * validator: createEnumParser(['debug', 'info', 'warn', 'error']),
243
+ * });
238
244
  * ```
239
245
  */
240
- declare function isEnvironmentLoaded(): boolean;
246
+ declare function createEnumParser(allowed: string[], caseInsensitive?: boolean): Parser<string>;
241
247
  /**
242
- * Reset environment loading state
243
- * FOR TESTING ONLY - DO NOT USE IN PRODUCTION
248
+ * Parse JSON string
249
+ *
250
+ * @param value - JSON string to parse
251
+ * @returns Parsed JSON value
252
+ * @throws Error if invalid JSON
244
253
  *
245
254
  * @example
246
255
  * ```typescript
247
- * // In test cleanup
248
- * afterEach(() => {
249
- * resetEnvironment();
256
+ * const config = getEnvVar('CONFIG_JSON', {
257
+ * validator: parseJson,
250
258
  * });
251
259
  * ```
252
260
  */
253
- declare function resetEnvironment(): void;
254
-
261
+ declare function parseJson<T = any>(value: string): T;
255
262
  /**
256
- * Environment Variable Management - Validators
263
+ * Create a typed JSON parser
264
+ *
265
+ * @returns Parser function
266
+ *
267
+ * @example
268
+ * ```typescript
269
+ * interface Config {
270
+ * host: string;
271
+ * port: number;
272
+ * }
257
273
  *
258
- * Common validation functions for environment variables
274
+ * const config = getEnvVar('CONFIG_JSON', {
275
+ * validator: createJsonParser<Config>(),
276
+ * });
277
+ * ```
259
278
  */
279
+ declare function createJsonParser<T>(): Parser<T>;
260
280
  /**
261
- * Validate that a value is a valid URL
281
+ * Parse comma-separated values into array
262
282
  *
263
- * @param value - Value to validate
264
- * @param options - Validation options
265
- * @returns True if valid URL, false otherwise
283
+ * @param value - Comma-separated string
284
+ * @param options - Parser options
285
+ * @returns Array of strings
266
286
  *
267
287
  * @example
268
288
  * ```typescript
269
- * const apiUrl = getEnvVar('API_URL', {
270
- * validator: validateUrl,
289
+ * const hosts = getEnvVar('ALLOWED_HOSTS', {
290
+ * validator: parseArray,
271
291
  * });
292
+ * // "localhost,example.com,api.example.com" → ['localhost', 'example.com', 'api.example.com']
272
293
  * ```
273
294
  */
274
- declare function validateUrl(value: string, options?: {
275
- protocol?: 'http' | 'https' | 'any';
276
- }): boolean;
295
+ declare function parseArray(value: string, options?: {
296
+ separator?: string;
297
+ trim?: boolean;
298
+ filter?: (item: string) => boolean;
299
+ }): string[];
277
300
  /**
278
- * Create a URL validator with specific protocol requirement
301
+ * Create an array parser with item parser
279
302
  *
280
- * @param protocol - Required protocol ('http', 'https', or 'any')
281
- * @returns Validator function
303
+ * @param itemParser - Parser to apply to each array item
304
+ * @param options - Array parsing options
305
+ * @returns Parser function
282
306
  *
283
307
  * @example
284
308
  * ```typescript
285
- * const apiUrl = getEnvVar('API_URL', {
286
- * validator: createUrlValidator('https'),
287
- * validationError: 'API_URL must use HTTPS',
309
+ * // Parse comma-separated ports
310
+ * const ports = getEnvVar('PORTS', {
311
+ * validator: createArrayParser(
312
+ * createNumberParser({ min: 1, max: 65535, integer: true })
313
+ * ),
288
314
  * });
315
+ * // "3000,4000,5000" → [3000, 4000, 5000]
289
316
  * ```
290
317
  */
291
- declare function createUrlValidator(protocol?: 'http' | 'https' | 'any'): (value: string) => boolean;
318
+ declare function createArrayParser<T>(itemParser: Parser<T>, options?: {
319
+ separator?: string;
320
+ }): Parser<T[]>;
292
321
  /**
293
- * Validate that a value is a valid number
322
+ * Create a secure secret parser with entropy validation
323
+ *
324
+ * Validates cryptographic secrets for sufficient length, character diversity, and randomness.
325
+ * Uses Shannon entropy to measure randomness quality.
294
326
  *
295
- * @param value - Value to validate
296
327
  * @param options - Validation options
297
- * @returns True if valid number, false otherwise
328
+ * @returns Parser function
298
329
  *
299
330
  * @example
300
331
  * ```typescript
301
- * const port = getEnvVar('PORT', {
302
- * validator: (val) => validateNumber(val, { min: 1, max: 65535 }),
332
+ * const sessionSecret = getEnvVar('SESSION_SECRET', {
333
+ * validator: createSecureSecretParser({
334
+ * minLength: 32, // Minimum 256-bit
335
+ * minUniqueChars: 16, // Character diversity
336
+ * minEntropy: 3.5, // Shannon entropy (bits/char)
337
+ * }),
303
338
  * });
304
339
  * ```
305
340
  */
306
- declare function validateNumber(value: string, options?: {
307
- min?: number;
308
- max?: number;
309
- integer?: boolean;
310
- }): boolean;
341
+ declare function createSecureSecretParser(options?: {
342
+ minLength?: number;
343
+ minUniqueChars?: number;
344
+ minEntropy?: number;
345
+ }): Parser<string>;
311
346
  /**
312
- * Create a number validator with specific constraints
347
+ * Create a password strength parser
313
348
  *
314
- * @param options - Validation constraints
315
- * @returns Validator function
349
+ * Validates password strength based on configurable requirements.
350
+ * Useful for enforcing password policies in environment variables or user input.
351
+ *
352
+ * @param options - Validation options
353
+ * @returns Parser function
316
354
  *
317
355
  * @example
318
356
  * ```typescript
319
- * const port = getEnvVar('PORT', {
320
- * validator: createNumberValidator({ min: 1, max: 65535, integer: true }),
321
- * validationError: 'PORT must be an integer between 1 and 65535',
357
+ * const adminPassword = getEnvVar('ADMIN_PASSWORD', {
358
+ * validator: createPasswordParser({
359
+ * minLength: 12,
360
+ * requireUppercase: true,
361
+ * requireLowercase: true,
362
+ * requireNumber: true,
363
+ * requireSpecial: true,
364
+ * }),
322
365
  * });
323
366
  * ```
324
367
  */
325
- declare function createNumberValidator(options?: {
326
- min?: number;
327
- max?: number;
328
- integer?: boolean;
329
- }): (value: string) => boolean;
368
+ declare function createPasswordParser(options?: {
369
+ minLength?: number;
370
+ requireUppercase?: boolean;
371
+ requireLowercase?: boolean;
372
+ requireNumber?: boolean;
373
+ requireSpecial?: boolean;
374
+ }): Parser<string>;
330
375
  /**
331
- * Validate that a value is a valid boolean string
376
+ * Chain multiple parsers sequentially
377
+ *
378
+ * Each parser receives the output of the previous parser.
379
+ * Useful for multi-step validation/transformation.
332
380
  *
333
- * @param value - Value to validate
334
- * @returns True if valid boolean string, false otherwise
381
+ * @param parsers - Array of parser functions
382
+ * @returns Combined parser function
335
383
  *
336
384
  * @example
337
385
  * ```typescript
338
- * const debugMode = getEnvVar('DEBUG', {
339
- * validator: validateBoolean,
386
+ * const apiKey = getEnvVar('API_KEY', {
387
+ * validator: chain(
388
+ * parseString,
389
+ * createStringParser({ minLength: 32, pattern: /^[A-Za-z0-9_-]+$/ }),
390
+ * ),
340
391
  * });
341
392
  * ```
342
393
  */
343
- declare function validateBoolean(value: string): boolean;
394
+ declare function chain<T>(...parsers: Array<Parser<T>>): Parser<T>;
344
395
  /**
345
- * Parse a boolean environment variable
396
+ * Apply parser with fallback value
346
397
  *
347
- * @param value - Value to parse
348
- * @returns Boolean value
398
+ * If parser throws, returns fallback instead.
399
+ * Useful for optional environment variables with complex parsing.
400
+ *
401
+ * @param parser - Parser to attempt
402
+ * @param fallback - Fallback value if parsing fails
403
+ * @returns Parser function
349
404
  *
350
405
  * @example
351
406
  * ```typescript
352
- * const debug = parseBoolean(getEnvVar('DEBUG', { default: 'false' })!);
407
+ * const config = getEnvVar('CONFIG_JSON', {
408
+ * validator: withFallback(parseJson, { host: 'localhost', port: 3000 }),
409
+ * });
353
410
  * ```
354
411
  */
355
- declare function parseBoolean(value: string): boolean;
412
+ declare function withFallback<T>(parser: Parser<T>, fallback: T): Parser<T>;
356
413
  /**
357
- * Validate that a value is one of allowed options
414
+ * Make parser optional
358
415
  *
359
- * @param value - Value to validate
360
- * @param allowed - Array of allowed values
361
- * @param caseInsensitive - Whether to perform case-insensitive comparison
362
- * @returns True if value is in allowed list, false otherwise
416
+ * Returns undefined for empty strings instead of throwing.
417
+ *
418
+ * @param parser - Parser to make optional
419
+ * @returns Parser function that returns T | undefined
363
420
  *
364
421
  * @example
365
422
  * ```typescript
366
- * const env = getEnvVar('NODE_ENV', {
367
- * validator: (val) => validateEnum(val, ['development', 'production', 'test']),
423
+ * const redisUrl = getEnvVar('REDIS_URL', {
424
+ * validator: optional(parseRedisUrl),
368
425
  * });
426
+ * // Empty string → undefined
427
+ * // Valid URL → parsed URL
428
+ * // Invalid URL → throws
369
429
  * ```
370
430
  */
371
- declare function validateEnum(value: string, allowed: string[], caseInsensitive?: boolean): boolean;
431
+ declare function optional<T>(parser: Parser<T>): Parser<T | undefined>;
432
+
372
433
  /**
373
- * Create an enum validator with specific allowed values
434
+ * Environment Variable Schema Definition System
374
435
  *
375
- * @param allowed - Array of allowed values
376
- * @param caseInsensitive - Whether to perform case-insensitive comparison
377
- * @returns Validator function
436
+ * 환경변수에 메타데이터를 정의하여 중앙 관리, 문서화, 검증을 지원합니다.
378
437
  *
379
438
  * @example
380
439
  * ```typescript
381
- * const logLevel = getEnvVar('LOG_LEVEL', {
382
- * validator: createEnumValidator(['debug', 'info', 'warn', 'error']),
383
- * validationError: 'LOG_LEVEL must be one of: debug, info, warn, error',
440
+ * const schema = defineEnvSchema({
441
+ * DATABASE_URL: envUrl({
442
+ * description: 'Database connection',
443
+ * required: true,
444
+ * validator: parsePostgresUrl,
445
+ * sensitive: true,
446
+ * })
384
447
  * });
385
448
  * ```
449
+ *
450
+ * @module env/schema
451
+ */
452
+ /**
453
+ * 환경변수 스키마 정의
454
+ */
455
+ interface EnvVarSchema<T = string> {
456
+ /** 환경변수 키 */
457
+ key: string;
458
+ /** 설명 (목적, 사용처) */
459
+ description: string;
460
+ /** 타입 */
461
+ type: 'string' | 'number' | 'boolean' | 'url' | 'enum' | 'json';
462
+ /** 필수 여부 */
463
+ required?: boolean;
464
+ /** 기본값 */
465
+ default?: T;
466
+ /** 검증/변환 함수 */
467
+ validator?: (value: string) => T;
468
+ /** Fallback 환경변수 키들 (backward compatibility) */
469
+ fallbackKeys?: string[];
470
+ /** 최소 길이 (문자열 타입) */
471
+ minLength?: number;
472
+ /** 민감정보 여부 (로깅 시 마스킹) */
473
+ sensitive?: boolean;
474
+ /** 예시 값들 (타입과 일치해야 함) */
475
+ examples?: T[];
476
+ }
477
+ /**
478
+ * 스키마 컬렉션 타입
479
+ */
480
+ type EnvSchemaCollection = Record<string, EnvVarSchema<any>>;
481
+ /**
482
+ * Helper type: Check if field has default value
483
+ */
484
+ type HasDefault<T> = T extends {
485
+ default: any;
486
+ } ? true : false;
487
+ /**
488
+ * Helper type: Check if field is explicitly required
489
+ */
490
+ type IsRequired<T> = T extends {
491
+ required: true;
492
+ } ? true : false;
493
+ /**
494
+ * Helper type: Check if field should be required (has default OR required: true)
495
+ */
496
+ type ShouldBeRequired<T> = HasDefault<T> extends true ? true : IsRequired<T>;
497
+ /**
498
+ * 스키마로부터 타입 추출
499
+ *
500
+ * required: true 또는 default가 있는 필드 → 필수
501
+ * required: false 또는 미지정 → optional (| undefined)
386
502
  */
387
- declare function createEnumValidator(allowed: string[], caseInsensitive?: boolean): (value: string) => boolean;
503
+ type InferEnvType<T extends EnvSchemaCollection> = {
504
+ [K in keyof T as ShouldBeRequired<T[K]> extends true ? K : never]: T[K] extends EnvVarSchema<infer U> ? U : string;
505
+ } & {
506
+ [K in keyof T as ShouldBeRequired<T[K]> extends true ? never : K]?: T[K] extends EnvVarSchema<infer U> ? U | undefined : string | undefined;
507
+ };
388
508
  /**
389
- * Validate that a value matches a regular expression
509
+ * 스키마 정의 헬퍼 (타입 추론 지원)
390
510
  *
391
- * @param value - Value to validate
392
- * @param pattern - Regular expression pattern
393
- * @returns True if value matches pattern, false otherwise
511
+ * Automatically fills in the `key` property from object keys.
394
512
  *
395
513
  * @example
396
514
  * ```typescript
397
- * const apiKey = getEnvVar('API_KEY', {
398
- * validator: (val) => validatePattern(val, /^[A-Za-z0-9_-]{32}$/),
515
+ * const schema = defineEnvSchema({
516
+ * DATABASE_URL: envString({ description: 'Database URL', required: true })
399
517
  * });
518
+ * // Automatically adds key: 'DATABASE_URL'
400
519
  * ```
401
520
  */
402
- declare function validatePattern(value: string, pattern: RegExp): boolean;
521
+ declare function defineEnvSchema<T extends Record<string, any>>(schema: T): {
522
+ [K in keyof T]: T[K] & {
523
+ key: K;
524
+ };
525
+ };
403
526
  /**
404
- * Create a pattern validator with specific regex
527
+ * 문자열 스키마 헬퍼
405
528
  *
406
- * @param pattern - Regular expression pattern
407
- * @returns Validator function
529
+ * @example
530
+ * ```typescript
531
+ * const schema = {
532
+ * API_KEY: {
533
+ * ...envString({
534
+ * description: 'API authentication key',
535
+ * required: true,
536
+ * sensitive: true,
537
+ * }),
538
+ * key: 'API_KEY',
539
+ * }
540
+ * };
541
+ * ```
542
+ */
543
+ declare function envString<T extends Omit<EnvVarSchema, 'key' | 'type'>>(options: T): T & {
544
+ type: 'string';
545
+ };
546
+ /**
547
+ * 숫자 스키마 헬퍼
408
548
  *
409
549
  * @example
410
550
  * ```typescript
411
- * const apiKey = getEnvVar('API_KEY', {
412
- * validator: createPatternValidator(/^[A-Za-z0-9_-]{32}$/),
413
- * validationError: 'API_KEY must be 32 alphanumeric characters',
414
- * });
551
+ * const schema = {
552
+ * PORT: {
553
+ * ...envNumber({
554
+ * description: 'Server port',
555
+ * default: 3000,
556
+ * validator: createNumberParser({ min: 1, max: 65535 }),
557
+ * }),
558
+ * key: 'PORT',
559
+ * }
560
+ * };
415
561
  * ```
416
562
  */
417
- declare function createPatternValidator(pattern: RegExp): (value: string) => boolean;
563
+ declare function envNumber<T extends Omit<EnvVarSchema<number>, 'key' | 'type'>>(options: T): T & {
564
+ type: 'number';
565
+ validator: (value: string) => number;
566
+ };
418
567
  /**
419
- * Validate that a value is not empty
568
+ * Boolean 스키마 헬퍼
420
569
  *
421
- * @param value - Value to validate
422
- * @returns True if not empty, false otherwise
570
+ * @example
571
+ * ```typescript
572
+ * const schema = {
573
+ * DEBUG: {
574
+ * ...envBoolean({
575
+ * description: 'Enable debug mode',
576
+ * default: false,
577
+ * }),
578
+ * key: 'DEBUG',
579
+ * }
580
+ * };
581
+ * ```
582
+ */
583
+ declare function envBoolean<T extends Omit<EnvVarSchema<boolean>, 'key' | 'type'>>(options: T): T & {
584
+ type: 'boolean';
585
+ validator: (value: string) => boolean;
586
+ };
587
+ /**
588
+ * URL 스키마 헬퍼
423
589
  *
424
590
  * @example
425
591
  * ```typescript
426
- * const name = getEnvVar('APP_NAME', {
427
- * validator: validateNotEmpty,
428
- * });
592
+ * const schema = {
593
+ * DATABASE_URL: {
594
+ * ...envUrl({
595
+ * description: 'Database connection URL',
596
+ * required: true,
597
+ * validator: parsePostgresUrl,
598
+ * }),
599
+ * key: 'DATABASE_URL',
600
+ * }
601
+ * };
429
602
  * ```
430
603
  */
431
- declare function validateNotEmpty(value: string): boolean;
604
+ declare function envUrl<T extends Omit<EnvVarSchema, 'key' | 'type'>>(options: T): T & {
605
+ type: 'url';
606
+ };
432
607
  /**
433
- * Validate that a value has minimum length
608
+ * Enum 스키마 헬퍼
434
609
  *
435
- * @param value - Value to validate
436
- * @param minLength - Minimum required length
437
- * @returns True if meets minimum length, false otherwise
610
+ * @example
611
+ * ```typescript
612
+ * const schema = {
613
+ * LOG_LEVEL: {
614
+ * ...envEnum(['debug', 'info', 'warn', 'error'] as const, {
615
+ * description: 'Logging level',
616
+ * default: 'info',
617
+ * }),
618
+ * key: 'LOG_LEVEL',
619
+ * }
620
+ * };
621
+ * ```
622
+ */
623
+ declare function envEnum<T extends string, O extends Omit<EnvVarSchema<T>, 'key' | 'type' | 'validator'>>(allowed: readonly T[], options: O): O & {
624
+ type: 'enum';
625
+ validator: (val: string) => T;
626
+ };
627
+ /**
628
+ * JSON 스키마 헬퍼
438
629
  *
439
630
  * @example
440
631
  * ```typescript
441
- * const password = getEnvVar('DB_PASSWORD', {
442
- * validator: (val) => validateMinLength(val, 8),
443
- * });
632
+ * const schema = {
633
+ * CONFIG_JSON: {
634
+ * ...envJson<{ host: string; port: number }>({
635
+ * description: 'JSON configuration object',
636
+ * required: true,
637
+ * }),
638
+ * key: 'CONFIG_JSON',
639
+ * }
640
+ * };
444
641
  * ```
445
642
  */
446
- declare function validateMinLength(value: string, minLength: number): boolean;
643
+ declare function envJson<T = any, O extends Omit<EnvVarSchema<T>, 'key' | 'type' | 'validator'> = Omit<EnvVarSchema<T>, 'key' | 'type' | 'validator'>>(options: O): O & {
644
+ type: 'json';
645
+ validator: (val: string) => T;
646
+ };
447
647
  /**
448
- * Create a minimum length validator
648
+ * 환경변수가 클라이언트에서 접근 가능한지 확인
649
+ * (NEXT_PUBLIC_ 접두사로 판단)
449
650
  *
450
- * @param minLength - Minimum required length
451
- * @returns Validator function
651
+ * @param key - 환경변수
652
+ * @returns 클라이언트에서 접근 가능하면 true
452
653
  *
453
654
  * @example
454
655
  * ```typescript
455
- * const password = getEnvVar('DB_PASSWORD', {
456
- * validator: createMinLengthValidator(8),
457
- * validationError: 'DB_PASSWORD must be at least 8 characters',
458
- * });
656
+ * isClientAccessible('NEXT_PUBLIC_API_URL'); // true
657
+ * isClientAccessible('DATABASE_URL'); // false
459
658
  * ```
460
659
  */
461
- declare function createMinLengthValidator(minLength: number): (value: string) => boolean;
660
+ declare function isClientAccessible(key: string): boolean;
462
661
  /**
463
- * Combine multiple validators with AND logic
662
+ * 환경변수가 서버 전용인지 확인
663
+ * (NEXT_PUBLIC_ 접두사가 없으면 서버 전용)
464
664
  *
465
- * @param validators - Array of validator functions
466
- * @returns Combined validator function
665
+ * @param key - 환경변수
666
+ * @returns 서버 전용이면 true
467
667
  *
468
668
  * @example
469
669
  * ```typescript
470
- * const port = getEnvVar('PORT', {
471
- * validator: combineValidators([
472
- * validateNotEmpty,
473
- * createNumberValidator({ min: 1, max: 65535, integer: true }),
474
- * ]),
475
- * });
670
+ * isServerOnly('DATABASE_URL'); // true
671
+ * isServerOnly('NEXT_PUBLIC_API_URL'); // false
476
672
  * ```
477
673
  */
478
- declare function combineValidators(validators: Array<(value: string) => boolean>): (value: string) => boolean;
674
+ declare function isServerOnly(key: string): boolean;
675
+
479
676
  /**
480
- * Validate PostgreSQL connection string
677
+ * Environment Variable Registry
481
678
  *
482
- * @param value - Value to validate
483
- * @returns True if valid PostgreSQL URL, false otherwise
679
+ * 환경변수 스키마를 등록하고 타입 안전하게 접근할 수 있는 레지스트리
484
680
  *
485
681
  * @example
486
682
  * ```typescript
487
- * const dbUrl = getEnvVar('DATABASE_URL', {
488
- * validator: validatePostgresUrl,
683
+ * const schema = defineEnvSchema({
684
+ * DATABASE_URL: envString({ description: 'Database URL', required: true })
489
685
  * });
686
+ *
687
+ * const registry = createEnvRegistry(schema);
688
+ * const env = registry.validate(); // 검증 + env 반환
689
+ * console.log(env.DATABASE_URL);
490
690
  * ```
691
+ *
692
+ * @module env/registry
491
693
  */
492
- declare function validatePostgresUrl(value: string): boolean;
694
+
493
695
  /**
494
- * Validate Redis connection string
696
+ * 환경변수 레지스트리
495
697
  *
496
- * @param value - Value to validate
497
- * @returns True if valid Redis URL, false otherwise
698
+ * 스키마 기반 환경변수 관리 검증
699
+ */
700
+ declare class EnvRegistry<T extends EnvSchemaCollection = EnvSchemaCollection> {
701
+ private schemas;
702
+ private hasValidated;
703
+ private valueCache;
704
+ constructor(schemas?: T);
705
+ /**
706
+ * 스키마 등록
707
+ */
708
+ register(schema: EnvVarSchema): void;
709
+ /**
710
+ * 여러 스키마 등록
711
+ */
712
+ registerMultiple(schemas: EnvSchemaCollection): void;
713
+ /**
714
+ * 캐시 및 검증 상태 리셋 (테스트용)
715
+ */
716
+ reset(): void;
717
+ /**
718
+ * 환경변수 원시값 가져오기 (fallback 지원)
719
+ */
720
+ private getRawValue;
721
+ /**
722
+ * 값에 validator 적용
723
+ */
724
+ private applyValidator;
725
+ /**
726
+ * 스키마 검증 수행 (값 읽기 없이)
727
+ *
728
+ * @internal
729
+ */
730
+ private validateSchemas;
731
+ /**
732
+ * 실제 접근 시점에 환경변수 값 가져오기 및 검증
733
+ *
734
+ * @internal
735
+ */
736
+ private getAndValidate;
737
+ /**
738
+ * 환경변수 검증 및 타입 안전한 env 객체 반환
739
+ *
740
+ * Proxy 기반으로 구현되어 실제 환경변수 접근 시점에 값을 읽고 검증합니다.
741
+ * 이를 통해 dotenv 로딩 타이밍과 무관하게 최신 환경변수 값을 가져올 수 있습니다.
742
+ *
743
+ * @returns 검증된 환경변수 객체 (Proxy)
744
+ * @throws {Error} 필수 변수 누락 또는 검증 실패 시
745
+ *
746
+ * @example
747
+ * ```typescript
748
+ * const registry = createEnvRegistry(schema);
749
+ * const env = registry.validate(); // 스키마만 검증
750
+ * // ... dotenv 로딩 ...
751
+ * console.log(env.DATABASE_URL); // 이 시점에 실제 값 읽기
752
+ * ```
753
+ */
754
+ validate(): InferEnvType<T>;
755
+ }
756
+ /**
757
+ * 레지스트리 생성 헬퍼
498
758
  *
499
759
  * @example
500
760
  * ```typescript
501
- * const redisUrl = getEnvVar('REDIS_URL', {
502
- * validator: validateRedisUrl,
761
+ * const schema = defineEnvSchema({
762
+ * DATABASE_URL: envString({ description: 'Database URL', required: true })
503
763
  * });
764
+ *
765
+ * const registry = createEnvRegistry(schema);
766
+ * const env = registry.validate();
504
767
  * ```
505
768
  */
506
- declare function validateRedisUrl(value: string): boolean;
769
+ declare function createEnvRegistry<T extends EnvSchemaCollection>(schemas: T): EnvRegistry<T>;
770
+
771
+ /**
772
+ * Environment Types
773
+ */
774
+ /**
775
+ * Node.js environment types
776
+ */
777
+ type NodeEnv = 'local' | 'development' | 'staging' | 'production' | 'test';
507
778
 
508
- export { ENV_FILE_PRIORITY, type GetEnvOptions, type LoadEnvironmentOptions, type LoadResult, TEST_ONLY_FILES, combineValidators, createEnumValidator, createMinLengthValidator, createNumberValidator, createPatternValidator, createUrlValidator, getEnvVar, getEnvVars, hasEnvVar, isEnvironmentLoaded, loadEnvironment, parseBoolean, requireEnvVar, resetEnvironment, validateBoolean, validateEnum, validateMinLength, validateNotEmpty, validateNumber, validatePattern, validatePostgresUrl, validateRedisUrl, validateUrl };
779
+ export { EnvRegistry, type EnvSchemaCollection, type EnvVarSchema, type InferEnvType, type NodeEnv, type Parser, chain, createArrayParser, createEnumParser, createEnvRegistry, createJsonParser, createNumberParser, createPasswordParser, createSecureSecretParser, createStringParser, createUrlParser, defineEnvSchema, envBoolean, envEnum, envJson, envNumber, envString, envUrl, isClientAccessible, isServerOnly, optional, parseArray, parseBoolean, parseDecimal, parseEnum, parseInteger, parseJson, parseNumber, parsePostgresUrl, parseRedisUrl, parseString, parseUrl, withFallback };