@geekmidas/envkit 10.0.0-alpha.2 → 10.0.0-alpha.21

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 (56) hide show
  1. package/dist/{EnvironmentBuilder-CoBQ9Xp2.d.mts → EnvironmentBuilder-DTZ8o3se.d.cts} +5 -5
  2. package/dist/EnvironmentBuilder-DTZ8o3se.d.cts.map +1 -0
  3. package/dist/{EnvironmentBuilder-DeIle4QN.d.cts → EnvironmentBuilder-DTZ8o3se.d.mts} +5 -5
  4. package/dist/EnvironmentBuilder-DTZ8o3se.d.mts.map +1 -0
  5. package/dist/{EnvironmentBuilder-C-2fViCT.mjs → EnvironmentBuilder-Rxq657gm.mjs} +4 -5
  6. package/dist/EnvironmentBuilder-Rxq657gm.mjs.map +1 -0
  7. package/dist/{EnvironmentBuilder-15SdFJdK.cjs → EnvironmentBuilder-wJH3EBbJ.cjs} +16 -16
  8. package/dist/EnvironmentBuilder-wJH3EBbJ.cjs.map +1 -0
  9. package/dist/{EnvironmentParser-DoooZm8n.d.cts → EnvironmentParser-BmJLlm5_.d.cts} +3 -15
  10. package/dist/EnvironmentParser-BmJLlm5_.d.cts.map +1 -0
  11. package/dist/{EnvironmentParser-BY1oCUsc.d.mts → EnvironmentParser-BmJLlm5_.d.mts} +3 -15
  12. package/dist/EnvironmentParser-BmJLlm5_.d.mts.map +1 -0
  13. package/dist/{EnvironmentParser-Bzg5yXG2.cjs → EnvironmentParser-CmhDxs77.cjs} +34 -34
  14. package/dist/EnvironmentParser-CmhDxs77.cjs.map +1 -0
  15. package/dist/{EnvironmentParser-taAKfzT7.mjs → EnvironmentParser-X6Z-jryw.mjs} +10 -12
  16. package/dist/EnvironmentParser-X6Z-jryw.mjs.map +1 -0
  17. package/dist/SnifferEnvironmentParser.cjs +5 -7
  18. package/dist/SnifferEnvironmentParser.cjs.map +1 -1
  19. package/dist/SnifferEnvironmentParser.d.cts +5 -9
  20. package/dist/SnifferEnvironmentParser.d.cts.map +1 -1
  21. package/dist/SnifferEnvironmentParser.d.mts +5 -9
  22. package/dist/SnifferEnvironmentParser.d.mts.map +1 -1
  23. package/dist/SnifferEnvironmentParser.mjs +3 -5
  24. package/dist/SnifferEnvironmentParser.mjs.map +1 -1
  25. package/dist/credentials.cjs +9 -11
  26. package/dist/credentials.cjs.map +1 -1
  27. package/dist/credentials.d.cts +3 -3
  28. package/dist/credentials.d.cts.map +1 -1
  29. package/dist/credentials.d.mts +3 -3
  30. package/dist/credentials.d.mts.map +1 -1
  31. package/dist/credentials.mjs +4 -8
  32. package/dist/credentials.mjs.map +1 -1
  33. package/dist/index.cjs +4 -4
  34. package/dist/index.d.cts +5 -7
  35. package/dist/index.d.cts.map +1 -1
  36. package/dist/index.d.mts +5 -7
  37. package/dist/index.d.mts.map +1 -1
  38. package/dist/index.mjs +3 -4
  39. package/dist/{chunk-CUT6urMc.cjs → rolldown-runtime-VH7oDXx4.cjs} +8 -10
  40. package/dist/sst.cjs +43 -51
  41. package/dist/sst.cjs.map +1 -1
  42. package/dist/sst.d.cts +19 -24
  43. package/dist/sst.d.cts.map +1 -1
  44. package/dist/sst.d.mts +19 -24
  45. package/dist/sst.d.mts.map +1 -1
  46. package/dist/sst.mjs +42 -51
  47. package/dist/sst.mjs.map +1 -1
  48. package/package.json +2 -2
  49. package/dist/EnvironmentBuilder-15SdFJdK.cjs.map +0 -1
  50. package/dist/EnvironmentBuilder-C-2fViCT.mjs.map +0 -1
  51. package/dist/EnvironmentBuilder-CoBQ9Xp2.d.mts.map +0 -1
  52. package/dist/EnvironmentBuilder-DeIle4QN.d.cts.map +0 -1
  53. package/dist/EnvironmentParser-BY1oCUsc.d.mts.map +0 -1
  54. package/dist/EnvironmentParser-Bzg5yXG2.cjs.map +0 -1
  55. package/dist/EnvironmentParser-DoooZm8n.d.cts.map +0 -1
  56. package/dist/EnvironmentParser-taAKfzT7.mjs.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"SnifferEnvironmentParser.cjs","names":["schema: z.ZodType","name: string","z","result: Record<string, unknown>","builder: (get: EnvFetcher) => TReturn","opts?: { markOptional?: boolean }","ConfigParser","config: T","result: EmptyObject","sniffer: SnifferEnvironmentParser","operation: () => unknown | Promise<unknown>","options: SniffOptions","unhandledRejections: Error[]","reason: unknown","error: Error | undefined"],"sources":["../src/SnifferEnvironmentParser.ts"],"sourcesContent":["import { z } from 'zod/v4';\nimport {\n\tConfigParser,\n\ttype EmptyObject,\n\ttype EnvFetcher,\n} from './EnvironmentParser';\n\n/**\n * A specialized EnvironmentParser for build-time analysis that tracks\n * which environment variables are accessed without requiring actual values.\n *\n * Unlike the regular EnvironmentParser, the sniffer:\n * - Always returns mock values from .parse() and .safeParse()\n * - Never throws validation errors\n * - Tracks all accessed environment variable names\n *\n * This allows service registration to succeed during build-time analysis\n * even when environment variables are not set.\n *\n * @example\n * ```typescript\n * const sniffer = new SnifferEnvironmentParser();\n * await service.register(sniffer); // Always succeeds\n * const envVars = sniffer.getEnvironmentVariables(); // ['DATABASE_URL', 'API_KEY']\n * ```\n */\nexport class SnifferEnvironmentParser<_T extends EmptyObject = EmptyObject> {\n\tprivate readonly accessedVars: Set<string> = new Set();\n\tprivate readonly optionalVars: Set<string> = new Set();\n\n\t/**\n\t * Wraps a Zod schema to always return mock values.\n\t * This ensures .parse() and .safeParse() never fail.\n\t * Also detects when .optional() or .default() is called to track optional vars.\n\t */\n\tprivate wrapSchema = (schema: z.ZodType, name: string): z.ZodType => {\n\t\treturn new Proxy(schema, {\n\t\t\tget: (target, prop) => {\n\t\t\t\tif (prop === 'parse') {\n\t\t\t\t\treturn () => this.getMockValue(target);\n\t\t\t\t}\n\n\t\t\t\tif (prop === 'safeParse') {\n\t\t\t\t\treturn () => ({\n\t\t\t\t\t\tsuccess: true as const,\n\t\t\t\t\t\tdata: this.getMockValue(target),\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\t// Detect .optional() or .default() — mark the variable as optional\n\t\t\t\tif (prop === 'optional' || prop === 'default') {\n\t\t\t\t\tthis.optionalVars.add(name);\n\t\t\t\t}\n\n\t\t\t\tconst originalProp = target[prop as keyof typeof target];\n\t\t\t\tif (typeof originalProp === 'function') {\n\t\t\t\t\treturn (...args: any[]) => {\n\t\t\t\t\t\tconst result = originalProp.apply(target, args);\n\t\t\t\t\t\tif (result && typeof result === 'object' && 'parse' in result) {\n\t\t\t\t\t\t\treturn this.wrapSchema(result, name);\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn result;\n\t\t\t\t\t};\n\t\t\t\t}\n\n\t\t\t\treturn originalProp;\n\t\t\t},\n\t\t});\n\t};\n\n\t/**\n\t * Returns a mock value based on the Zod schema type.\n\t */\n\tprivate getMockValue(schema: z.ZodType): unknown {\n\t\t// Return type-appropriate mock values\n\t\tif (schema instanceof z.ZodString) return '';\n\t\tif (schema instanceof z.ZodNumber) return 0;\n\t\tif (schema instanceof z.ZodBoolean) return false;\n\t\tif (schema instanceof z.ZodArray) return [];\n\t\tif (schema instanceof z.ZodOptional) return undefined;\n\t\tif (schema instanceof z.ZodNullable) return null;\n\n\t\t// For object schemas, build mock object from shape\n\t\tif (schema instanceof z.ZodObject && schema.shape) {\n\t\t\tconst result: Record<string, unknown> = {};\n\t\t\tfor (const [key, value] of Object.entries(schema.shape)) {\n\t\t\t\tif (value instanceof z.ZodType) {\n\t\t\t\t\tresult[key] = this.getMockValue(value);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn result;\n\t\t}\n\n\t\treturn '';\n\t}\n\n\t/**\n\t * Creates a proxied Zod getter that tracks environment variable access.\n\t */\n\tprivate getZodGetter = (name: string) => {\n\t\tthis.accessedVars.add(name);\n\n\t\treturn new Proxy(\n\t\t\t{ ...z },\n\t\t\t{\n\t\t\t\tget: (target, prop) => {\n\t\t\t\t\t// @ts-expect-error\n\t\t\t\t\tconst value = target[prop];\n\n\t\t\t\t\tif (typeof value === 'function') {\n\t\t\t\t\t\treturn (...args: any[]) => {\n\t\t\t\t\t\t\tconst schema = value(...args);\n\t\t\t\t\t\t\treturn this.wrapSchema(schema, name);\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\n\t\t\t\t\tif (value && typeof value === 'object') {\n\t\t\t\t\t\treturn new Proxy(value, {\n\t\t\t\t\t\t\tget: (nestedTarget, nestedProp) => {\n\t\t\t\t\t\t\t\tconst nestedValue =\n\t\t\t\t\t\t\t\t\tnestedTarget[nestedProp as keyof typeof nestedTarget];\n\t\t\t\t\t\t\t\tif (typeof nestedValue === 'function') {\n\t\t\t\t\t\t\t\t\treturn (...args: any[]) => {\n\t\t\t\t\t\t\t\t\t\tconst schema = nestedValue(...args);\n\t\t\t\t\t\t\t\t\t\treturn this.wrapSchema(schema, name);\n\t\t\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\treturn nestedValue;\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\treturn value;\n\t\t\t\t},\n\t\t\t},\n\t\t);\n\t};\n\n\t/**\n\t * Creates a ConfigParser that will return mock values when parsed.\n\t */\n\tcreate<TReturn extends EmptyObject>(\n\t\tbuilder: (get: EnvFetcher) => TReturn,\n\t): ConfigParser<TReturn> {\n\t\tconst config = builder(this.getZodGetter);\n\t\treturn new SnifferConfigParser(config, this.accessedVars);\n\t}\n\n\t/**\n\t * Returns all environment variable names that were accessed.\n\t *\n\t * @param opts.markOptional - When true, optional variables (those accessed\n\t * via `.optional()` or `.default()`) are suffixed with `?` (e.g. `PORT?`).\n\t */\n\tgetEnvironmentVariables(opts?: { markOptional?: boolean }): string[] {\n\t\tconst vars = Array.from(this.accessedVars).sort();\n\t\tif (!opts?.markOptional) return vars;\n\t\treturn vars.map((name) =>\n\t\t\tthis.optionalVars.has(name) ? `${name}?` : name,\n\t\t);\n\t}\n\n\t/**\n\t * Returns all environment variable names that were accessed via\n\t * `.optional()` or `.default()` — i.e. variables that are not required.\n\t */\n\tgetOptionalVariables(): string[] {\n\t\treturn Array.from(this.optionalVars).sort();\n\t}\n}\n\n/**\n * A ConfigParser that always succeeds with mock values.\n */\nclass SnifferConfigParser<\n\tTResponse extends EmptyObject,\n> extends ConfigParser<TResponse> {\n\toverride parse(): any {\n\t\treturn this.parseWithMocks(this.getConfig());\n\t}\n\n\tprivate getConfig(): TResponse {\n\t\t// Access the private config via any cast\n\t\treturn (this as any).config;\n\t}\n\n\tprivate parseWithMocks<T>(config: T): any {\n\t\tconst result: EmptyObject = {};\n\n\t\tif (config && typeof config !== 'object') {\n\t\t\treturn config;\n\t\t}\n\n\t\tfor (const key in config) {\n\t\t\tconst schema = config[key];\n\n\t\t\tif (schema instanceof z.ZodType) {\n\t\t\t\t// Use safeParse which will return mock values from our wrapped schema\n\t\t\t\tconst parsed = schema.safeParse(undefined);\n\t\t\t\tresult[key] = parsed.success\n\t\t\t\t\t? parsed.data\n\t\t\t\t\t: this.getDefaultForSchema(schema);\n\t\t\t} else if (schema && typeof schema === 'object') {\n\t\t\t\tresult[key] = this.parseWithMocks(schema as EmptyObject);\n\t\t\t}\n\t\t}\n\n\t\treturn result;\n\t}\n\n\tprivate getDefaultForSchema(schema: z.ZodType): unknown {\n\t\tif (schema instanceof z.ZodString) return '';\n\t\tif (schema instanceof z.ZodNumber) return 0;\n\t\tif (schema instanceof z.ZodBoolean) return false;\n\t\tif (schema instanceof z.ZodArray) return [];\n\t\tif (schema instanceof z.ZodOptional) return undefined;\n\t\tif (schema instanceof z.ZodNullable) return null;\n\n\t\tif (schema instanceof z.ZodObject && schema.shape) {\n\t\t\tconst result: Record<string, unknown> = {};\n\t\t\tfor (const [key, value] of Object.entries(schema.shape)) {\n\t\t\t\tif (value instanceof z.ZodType) {\n\t\t\t\t\tresult[key] = this.getDefaultForSchema(value);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn result;\n\t\t}\n\n\t\treturn '';\n\t}\n}\n\n/**\n * Result of sniffing with fire-and-forget handling.\n */\nexport interface SniffResult {\n\t/** All environment variable names that were accessed during sniffing */\n\tenvVars: string[];\n\t/**\n\t * Subset of envVars that are optional (accessed via `.optional()` or\n\t * `.default()`). These do not need to be present for the app to start.\n\t */\n\toptionalEnvVars: string[];\n\t/** Error thrown during sniffing (env vars may still be captured) */\n\terror?: Error;\n\t/** Unhandled promise rejections captured during sniffing */\n\tunhandledRejections: Error[];\n}\n\n/**\n * Options for sniffing with fire-and-forget handling.\n */\nexport interface SniffOptions {\n\t/**\n\t * Time in milliseconds to wait for fire-and-forget promises to settle.\n\t * Some libraries like better-auth create async operations that may reject\n\t * after the initial event loop tick.\n\t * @default 100\n\t */\n\tsettleTimeMs?: number;\n}\n\n/**\n * Executes a sniffing operation with fire-and-forget handling.\n *\n * This function:\n * 1. Captures unhandled promise rejections during the operation\n * 2. Waits for async operations to settle before returning\n * 3. Gracefully handles errors without throwing\n *\n * Use this when sniffing environment variables from code that may:\n * - Throw synchronous errors\n * - Create fire-and-forget promises that reject\n * - Have async initialization that may fail\n *\n * @param sniffer - The SnifferEnvironmentParser instance to use\n * @param operation - The async operation to execute (e.g., service.register)\n * @param options - Optional configuration\n * @returns SniffResult with env vars and any errors encountered\n *\n * @example\n * ```typescript\n * const sniffer = new SnifferEnvironmentParser();\n * const result = await sniffWithFireAndForget(sniffer, async () => {\n * await service.register({ envParser: sniffer });\n * });\n * console.log('Env vars:', result.envVars);\n * console.log('Error:', result.error);\n * console.log('Unhandled rejections:', result.unhandledRejections);\n * ```\n */\nexport async function sniffWithFireAndForget(\n\tsniffer: SnifferEnvironmentParser,\n\toperation: () => unknown | Promise<unknown>,\n\toptions: SniffOptions = {},\n): Promise<SniffResult> {\n\tconst { settleTimeMs = 100 } = options;\n\tconst unhandledRejections: Error[] = [];\n\n\t// Capture unhandled rejections during sniffing (fire-and-forget promises)\n\t// Libraries like better-auth create async operations that may reject after\n\t// the initial event loop tick\n\tconst captureRejection = (reason: unknown) => {\n\t\tconst err = reason instanceof Error ? reason : new Error(String(reason));\n\t\tunhandledRejections.push(err);\n\t};\n\tprocess.on('unhandledRejection', captureRejection);\n\n\tlet error: Error | undefined;\n\n\ttry {\n\t\tconst result = operation();\n\n\t\t// Handle async result\n\t\tif (result && typeof result === 'object' && 'then' in result) {\n\t\t\tawait Promise.resolve(result).catch((e) => {\n\t\t\t\terror = e instanceof Error ? e : new Error(String(e));\n\t\t\t});\n\t\t}\n\t} catch (e) {\n\t\terror = e instanceof Error ? e : new Error(String(e));\n\t} finally {\n\t\t// Wait for fire-and-forget promises to settle\n\t\tawait new Promise((resolve) => setTimeout(resolve, settleTimeMs));\n\t\tprocess.off('unhandledRejection', captureRejection);\n\t}\n\n\treturn {\n\t\tenvVars: sniffer.getEnvironmentVariables(),\n\t\toptionalEnvVars: sniffer.getOptionalVariables(),\n\t\terror,\n\t\tunhandledRejections,\n\t};\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"SnifferEnvironmentParser.cjs","names":["z","ConfigParser"],"sources":["../src/SnifferEnvironmentParser.ts"],"sourcesContent":["import { z } from 'zod/v4';\nimport {\n\tConfigParser,\n\ttype EmptyObject,\n\ttype EnvFetcher,\n} from './EnvironmentParser';\n\n/**\n * A specialized EnvironmentParser for build-time analysis that tracks\n * which environment variables are accessed without requiring actual values.\n *\n * Unlike the regular EnvironmentParser, the sniffer:\n * - Always returns mock values from .parse() and .safeParse()\n * - Never throws validation errors\n * - Tracks all accessed environment variable names\n *\n * This allows service registration to succeed during build-time analysis\n * even when environment variables are not set.\n *\n * @example\n * ```typescript\n * const sniffer = new SnifferEnvironmentParser();\n * await service.register(sniffer); // Always succeeds\n * const envVars = sniffer.getEnvironmentVariables(); // ['DATABASE_URL', 'API_KEY']\n * ```\n */\nexport class SnifferEnvironmentParser<_T extends EmptyObject = EmptyObject> {\n\tprivate readonly accessedVars: Set<string> = new Set();\n\tprivate readonly optionalVars: Set<string> = new Set();\n\n\t/**\n\t * Wraps a Zod schema to always return mock values.\n\t * This ensures .parse() and .safeParse() never fail.\n\t * Also detects when .optional() or .default() is called to track optional vars.\n\t */\n\tprivate wrapSchema = (schema: z.ZodType, name: string): z.ZodType => {\n\t\treturn new Proxy(schema, {\n\t\t\tget: (target, prop) => {\n\t\t\t\tif (prop === 'parse') {\n\t\t\t\t\treturn () => this.getMockValue(target);\n\t\t\t\t}\n\n\t\t\t\tif (prop === 'safeParse') {\n\t\t\t\t\treturn () => ({\n\t\t\t\t\t\tsuccess: true as const,\n\t\t\t\t\t\tdata: this.getMockValue(target),\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\t// Detect .optional() or .default() — mark the variable as optional\n\t\t\t\tif (prop === 'optional' || prop === 'default') {\n\t\t\t\t\tthis.optionalVars.add(name);\n\t\t\t\t}\n\n\t\t\t\tconst originalProp = target[prop as keyof typeof target];\n\t\t\t\tif (typeof originalProp === 'function') {\n\t\t\t\t\treturn (...args: any[]) => {\n\t\t\t\t\t\tconst result = originalProp.apply(target, args);\n\t\t\t\t\t\tif (result && typeof result === 'object' && 'parse' in result) {\n\t\t\t\t\t\t\treturn this.wrapSchema(result, name);\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn result;\n\t\t\t\t\t};\n\t\t\t\t}\n\n\t\t\t\treturn originalProp;\n\t\t\t},\n\t\t});\n\t};\n\n\t/**\n\t * Returns a mock value based on the Zod schema type.\n\t */\n\tprivate getMockValue(schema: z.ZodType): unknown {\n\t\t// Return type-appropriate mock values\n\t\tif (schema instanceof z.ZodString) return '';\n\t\tif (schema instanceof z.ZodNumber) return 0;\n\t\tif (schema instanceof z.ZodBoolean) return false;\n\t\tif (schema instanceof z.ZodArray) return [];\n\t\tif (schema instanceof z.ZodOptional) return undefined;\n\t\tif (schema instanceof z.ZodNullable) return null;\n\n\t\t// For object schemas, build mock object from shape\n\t\tif (schema instanceof z.ZodObject && schema.shape) {\n\t\t\tconst result: Record<string, unknown> = {};\n\t\t\tfor (const [key, value] of Object.entries(schema.shape)) {\n\t\t\t\tif (value instanceof z.ZodType) {\n\t\t\t\t\tresult[key] = this.getMockValue(value);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn result;\n\t\t}\n\n\t\treturn '';\n\t}\n\n\t/**\n\t * Creates a proxied Zod getter that tracks environment variable access.\n\t */\n\tprivate getZodGetter = (name: string) => {\n\t\tthis.accessedVars.add(name);\n\n\t\treturn new Proxy(\n\t\t\t{ ...z },\n\t\t\t{\n\t\t\t\tget: (target, prop) => {\n\t\t\t\t\t// @ts-expect-error\n\t\t\t\t\tconst value = target[prop];\n\n\t\t\t\t\tif (typeof value === 'function') {\n\t\t\t\t\t\treturn (...args: any[]) => {\n\t\t\t\t\t\t\tconst schema = value(...args);\n\t\t\t\t\t\t\treturn this.wrapSchema(schema, name);\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\n\t\t\t\t\tif (value && typeof value === 'object') {\n\t\t\t\t\t\treturn new Proxy(value, {\n\t\t\t\t\t\t\tget: (nestedTarget, nestedProp) => {\n\t\t\t\t\t\t\t\tconst nestedValue =\n\t\t\t\t\t\t\t\t\tnestedTarget[nestedProp as keyof typeof nestedTarget];\n\t\t\t\t\t\t\t\tif (typeof nestedValue === 'function') {\n\t\t\t\t\t\t\t\t\treturn (...args: any[]) => {\n\t\t\t\t\t\t\t\t\t\tconst schema = nestedValue(...args);\n\t\t\t\t\t\t\t\t\t\treturn this.wrapSchema(schema, name);\n\t\t\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\treturn nestedValue;\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\treturn value;\n\t\t\t\t},\n\t\t\t},\n\t\t);\n\t};\n\n\t/**\n\t * Creates a ConfigParser that will return mock values when parsed.\n\t */\n\tcreate<TReturn extends EmptyObject>(\n\t\tbuilder: (get: EnvFetcher) => TReturn,\n\t): ConfigParser<TReturn> {\n\t\tconst config = builder(this.getZodGetter);\n\t\treturn new SnifferConfigParser(config, this.accessedVars);\n\t}\n\n\t/**\n\t * Returns all environment variable names that were accessed.\n\t *\n\t * @param opts.markOptional - When true, optional variables (those accessed\n\t * via `.optional()` or `.default()`) are suffixed with `?` (e.g. `PORT?`).\n\t */\n\tgetEnvironmentVariables(opts?: { markOptional?: boolean }): string[] {\n\t\tconst vars = Array.from(this.accessedVars).sort();\n\t\tif (!opts?.markOptional) return vars;\n\t\treturn vars.map((name) =>\n\t\t\tthis.optionalVars.has(name) ? `${name}?` : name,\n\t\t);\n\t}\n\n\t/**\n\t * Returns all environment variable names that were accessed via\n\t * `.optional()` or `.default()` — i.e. variables that are not required.\n\t */\n\tgetOptionalVariables(): string[] {\n\t\treturn Array.from(this.optionalVars).sort();\n\t}\n}\n\n/**\n * A ConfigParser that always succeeds with mock values.\n */\nclass SnifferConfigParser<\n\tTResponse extends EmptyObject,\n> extends ConfigParser<TResponse> {\n\toverride parse(): any {\n\t\treturn this.parseWithMocks(this.getConfig());\n\t}\n\n\tprivate getConfig(): TResponse {\n\t\t// Access the private config via any cast\n\t\treturn (this as any).config;\n\t}\n\n\tprivate parseWithMocks<T>(config: T): any {\n\t\tconst result: EmptyObject = {};\n\n\t\tif (config && typeof config !== 'object') {\n\t\t\treturn config;\n\t\t}\n\n\t\tfor (const key in config) {\n\t\t\tconst schema = config[key];\n\n\t\t\tif (schema instanceof z.ZodType) {\n\t\t\t\t// Use safeParse which will return mock values from our wrapped schema\n\t\t\t\tconst parsed = schema.safeParse(undefined);\n\t\t\t\tresult[key] = parsed.success\n\t\t\t\t\t? parsed.data\n\t\t\t\t\t: this.getDefaultForSchema(schema);\n\t\t\t} else if (schema && typeof schema === 'object') {\n\t\t\t\tresult[key] = this.parseWithMocks(schema as EmptyObject);\n\t\t\t}\n\t\t}\n\n\t\treturn result;\n\t}\n\n\tprivate getDefaultForSchema(schema: z.ZodType): unknown {\n\t\tif (schema instanceof z.ZodString) return '';\n\t\tif (schema instanceof z.ZodNumber) return 0;\n\t\tif (schema instanceof z.ZodBoolean) return false;\n\t\tif (schema instanceof z.ZodArray) return [];\n\t\tif (schema instanceof z.ZodOptional) return undefined;\n\t\tif (schema instanceof z.ZodNullable) return null;\n\n\t\tif (schema instanceof z.ZodObject && schema.shape) {\n\t\t\tconst result: Record<string, unknown> = {};\n\t\t\tfor (const [key, value] of Object.entries(schema.shape)) {\n\t\t\t\tif (value instanceof z.ZodType) {\n\t\t\t\t\tresult[key] = this.getDefaultForSchema(value);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn result;\n\t\t}\n\n\t\treturn '';\n\t}\n}\n\n/**\n * Result of sniffing with fire-and-forget handling.\n */\nexport interface SniffResult {\n\t/** All environment variable names that were accessed during sniffing */\n\tenvVars: string[];\n\t/**\n\t * Subset of envVars that are optional (accessed via `.optional()` or\n\t * `.default()`). These do not need to be present for the app to start.\n\t */\n\toptionalEnvVars: string[];\n\t/** Error thrown during sniffing (env vars may still be captured) */\n\terror?: Error;\n\t/** Unhandled promise rejections captured during sniffing */\n\tunhandledRejections: Error[];\n}\n\n/**\n * Options for sniffing with fire-and-forget handling.\n */\nexport interface SniffOptions {\n\t/**\n\t * Time in milliseconds to wait for fire-and-forget promises to settle.\n\t * Some libraries like better-auth create async operations that may reject\n\t * after the initial event loop tick.\n\t * @default 100\n\t */\n\tsettleTimeMs?: number;\n}\n\n/**\n * Executes a sniffing operation with fire-and-forget handling.\n *\n * This function:\n * 1. Captures unhandled promise rejections during the operation\n * 2. Waits for async operations to settle before returning\n * 3. Gracefully handles errors without throwing\n *\n * Use this when sniffing environment variables from code that may:\n * - Throw synchronous errors\n * - Create fire-and-forget promises that reject\n * - Have async initialization that may fail\n *\n * @param sniffer - The SnifferEnvironmentParser instance to use\n * @param operation - The async operation to execute (e.g., service.register)\n * @param options - Optional configuration\n * @returns SniffResult with env vars and any errors encountered\n *\n * @example\n * ```typescript\n * const sniffer = new SnifferEnvironmentParser();\n * const result = await sniffWithFireAndForget(sniffer, async () => {\n * await service.register({ envParser: sniffer });\n * });\n * console.log('Env vars:', result.envVars);\n * console.log('Error:', result.error);\n * console.log('Unhandled rejections:', result.unhandledRejections);\n * ```\n */\nexport async function sniffWithFireAndForget(\n\tsniffer: SnifferEnvironmentParser,\n\toperation: () => unknown | Promise<unknown>,\n\toptions: SniffOptions = {},\n): Promise<SniffResult> {\n\tconst { settleTimeMs = 100 } = options;\n\tconst unhandledRejections: Error[] = [];\n\n\t// Capture unhandled rejections during sniffing (fire-and-forget promises)\n\t// Libraries like better-auth create async operations that may reject after\n\t// the initial event loop tick\n\tconst captureRejection = (reason: unknown) => {\n\t\tconst err = reason instanceof Error ? reason : new Error(String(reason));\n\t\tunhandledRejections.push(err);\n\t};\n\tprocess.on('unhandledRejection', captureRejection);\n\n\tlet error: Error | undefined;\n\n\ttry {\n\t\tconst result = operation();\n\n\t\t// Handle async result\n\t\tif (result && typeof result === 'object' && 'then' in result) {\n\t\t\tawait Promise.resolve(result).catch((e) => {\n\t\t\t\terror = e instanceof Error ? e : new Error(String(e));\n\t\t\t});\n\t\t}\n\t} catch (e) {\n\t\terror = e instanceof Error ? e : new Error(String(e));\n\t} finally {\n\t\t// Wait for fire-and-forget promises to settle\n\t\tawait new Promise((resolve) => setTimeout(resolve, settleTimeMs));\n\t\tprocess.off('unhandledRejection', captureRejection);\n\t}\n\n\treturn {\n\t\tenvVars: sniffer.getEnvironmentVariables(),\n\t\toptionalEnvVars: sniffer.getOptionalVariables(),\n\t\terror,\n\t\tunhandledRejections,\n\t};\n}\n"],"mappings":"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"}
@@ -1,7 +1,5 @@
1
- import { ConfigParser, EmptyObject, EnvFetcher } from "./EnvironmentParser-DoooZm8n.cjs";
2
-
1
+ import { n as EmptyObject, r as EnvFetcher, t as ConfigParser } from "./EnvironmentParser-BmJLlm5_.cjs";
3
2
  //#region src/SnifferEnvironmentParser.d.ts
4
-
5
3
  /**
6
4
  * A specialized EnvironmentParser for build-time analysis that tracks
7
5
  * which environment variables are accessed without requiring actual values.
@@ -21,7 +19,7 @@ import { ConfigParser, EmptyObject, EnvFetcher } from "./EnvironmentParser-DoooZ
21
19
  * const envVars = sniffer.getEnvironmentVariables(); // ['DATABASE_URL', 'API_KEY']
22
20
  * ```
23
21
  */
24
- declare class SnifferEnvironmentParser<_T extends EmptyObject = EmptyObject> {
22
+ export declare class SnifferEnvironmentParser<_T extends EmptyObject = EmptyObject> {
25
23
  private readonly accessedVars;
26
24
  private readonly optionalVars;
27
25
  /**
@@ -60,7 +58,7 @@ declare class SnifferEnvironmentParser<_T extends EmptyObject = EmptyObject> {
60
58
  /**
61
59
  * Result of sniffing with fire-and-forget handling.
62
60
  */
63
- interface SniffResult {
61
+ export interface SniffResult {
64
62
  /** All environment variable names that were accessed during sniffing */
65
63
  envVars: string[];
66
64
  /**
@@ -76,7 +74,7 @@ interface SniffResult {
76
74
  /**
77
75
  * Options for sniffing with fire-and-forget handling.
78
76
  */
79
- interface SniffOptions {
77
+ export interface SniffOptions {
80
78
  /**
81
79
  * Time in milliseconds to wait for fire-and-forget promises to settle.
82
80
  * Some libraries like better-auth create async operations that may reject
@@ -114,8 +112,6 @@ interface SniffOptions {
114
112
  * console.log('Unhandled rejections:', result.unhandledRejections);
115
113
  * ```
116
114
  */
117
- declare function sniffWithFireAndForget(sniffer: SnifferEnvironmentParser, operation: () => unknown | Promise<unknown>, options?: SniffOptions): Promise<SniffResult>;
118
- //# sourceMappingURL=SnifferEnvironmentParser.d.ts.map
115
+ export declare function sniffWithFireAndForget(sniffer: SnifferEnvironmentParser, operation: () => unknown | Promise<unknown>, options?: SniffOptions): Promise<SniffResult>;
119
116
  //#endregion
120
- export { SniffOptions, SniffResult, SnifferEnvironmentParser, sniffWithFireAndForget };
121
117
  //# sourceMappingURL=SnifferEnvironmentParser.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"SnifferEnvironmentParser.d.cts","names":[],"sources":["../src/SnifferEnvironmentParser.ts"],"sourcesContent":[],"mappings":";;;;;;AA0BA;;;;;;;;;AAqHgB;AA4FhB;;;;AAW2B;AAM3B;AAuCA;AAA4C,cAzQ/B,wBAyQ+B,CAAA,WAzQK,WAyQL,GAzQmB,WAyQnB,CAAA,CAAA;EAAA,iBAClC,YAAA;EAAwB,iBACN,YAAA;EAAO;;;AAEzB;;;;;;;;;;;;;;yBA1Jc,4BACP,eAAe,UAC5B,aAAa;;;;;;;;;;;;;;;;;;;UA4FA,WAAA;;;;;;;;;UASR;;uBAEa;;;;;UAML,YAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAuCK,sBAAA,UACZ,qDACkB,4BAClB,eACP,QAAQ"}
1
+ {"version":3,"file":"SnifferEnvironmentParser.d.cts","names":[],"sources":["../src/SnifferEnvironmentParser.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;qBA0Ba,yBAAyB,WAAW,cAAc;mBAC7C;mBACA;;;;;;UAOT;;;;UAsCA;;;;UA0BA;;;;EA0CR,OAAO,gBAAgB,aACtB,UAAU,KAAK,eAAe,UAC5B,aAAa;;;;;;;EAWhB,wBAAwB;IAAS;;;;;;EAYjC;;;;;iBAqEgB;;EAEhB;;;;;EAKA;;EAEA,QAAQ;;EAER,qBAAqB;;;;;iBAML;;;;;;;EAOhB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;wBAgCqB,uBACrB,SAAS,0BACT,2BAA2B,kBAC3B,UAAS,eACP,QAAQ"}
@@ -1,7 +1,5 @@
1
- import { ConfigParser, EmptyObject, EnvFetcher } from "./EnvironmentParser-BY1oCUsc.mjs";
2
-
1
+ import { n as EmptyObject, r as EnvFetcher, t as ConfigParser } from "./EnvironmentParser-BmJLlm5_.mjs";
3
2
  //#region src/SnifferEnvironmentParser.d.ts
4
-
5
3
  /**
6
4
  * A specialized EnvironmentParser for build-time analysis that tracks
7
5
  * which environment variables are accessed without requiring actual values.
@@ -21,7 +19,7 @@ import { ConfigParser, EmptyObject, EnvFetcher } from "./EnvironmentParser-BY1oC
21
19
  * const envVars = sniffer.getEnvironmentVariables(); // ['DATABASE_URL', 'API_KEY']
22
20
  * ```
23
21
  */
24
- declare class SnifferEnvironmentParser<_T extends EmptyObject = EmptyObject> {
22
+ export declare class SnifferEnvironmentParser<_T extends EmptyObject = EmptyObject> {
25
23
  private readonly accessedVars;
26
24
  private readonly optionalVars;
27
25
  /**
@@ -60,7 +58,7 @@ declare class SnifferEnvironmentParser<_T extends EmptyObject = EmptyObject> {
60
58
  /**
61
59
  * Result of sniffing with fire-and-forget handling.
62
60
  */
63
- interface SniffResult {
61
+ export interface SniffResult {
64
62
  /** All environment variable names that were accessed during sniffing */
65
63
  envVars: string[];
66
64
  /**
@@ -76,7 +74,7 @@ interface SniffResult {
76
74
  /**
77
75
  * Options for sniffing with fire-and-forget handling.
78
76
  */
79
- interface SniffOptions {
77
+ export interface SniffOptions {
80
78
  /**
81
79
  * Time in milliseconds to wait for fire-and-forget promises to settle.
82
80
  * Some libraries like better-auth create async operations that may reject
@@ -114,8 +112,6 @@ interface SniffOptions {
114
112
  * console.log('Unhandled rejections:', result.unhandledRejections);
115
113
  * ```
116
114
  */
117
- declare function sniffWithFireAndForget(sniffer: SnifferEnvironmentParser, operation: () => unknown | Promise<unknown>, options?: SniffOptions): Promise<SniffResult>;
118
- //# sourceMappingURL=SnifferEnvironmentParser.d.ts.map
115
+ export declare function sniffWithFireAndForget(sniffer: SnifferEnvironmentParser, operation: () => unknown | Promise<unknown>, options?: SniffOptions): Promise<SniffResult>;
119
116
  //#endregion
120
- export { SniffOptions, SniffResult, SnifferEnvironmentParser, sniffWithFireAndForget };
121
117
  //# sourceMappingURL=SnifferEnvironmentParser.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"SnifferEnvironmentParser.d.mts","names":[],"sources":["../src/SnifferEnvironmentParser.ts"],"sourcesContent":[],"mappings":";;;;;;AA0BA;;;;;;;;;AAqHgB;AA4FhB;;;;AAW2B;AAM3B;AAuCA;AAA4C,cAzQ/B,wBAyQ+B,CAAA,WAzQK,WAyQL,GAzQmB,WAyQnB,CAAA,CAAA;EAAA,iBAClC,YAAA;EAAwB,iBACN,YAAA;EAAO;;;AAEzB;;;;;;;;;;;;;;yBA1Jc,4BACP,eAAe,UAC5B,aAAa;;;;;;;;;;;;;;;;;;;UA4FA,WAAA;;;;;;;;;UASR;;uBAEa;;;;;UAML,YAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAuCK,sBAAA,UACZ,qDACkB,4BAClB,eACP,QAAQ"}
1
+ {"version":3,"file":"SnifferEnvironmentParser.d.mts","names":[],"sources":["../src/SnifferEnvironmentParser.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;qBA0Ba,yBAAyB,WAAW,cAAc;mBAC7C;mBACA;;;;;;UAOT;;;;UAsCA;;;;UA0BA;;;;EA0CR,OAAO,gBAAgB,aACtB,UAAU,KAAK,eAAe,UAC5B,aAAa;;;;;;;EAWhB,wBAAwB;IAAS;;;;;;EAYjC;;;;;iBAqEgB;;EAEhB;;;;;EAKA;;EAEA,QAAQ;;EAER,qBAAqB;;;;;iBAML;;;;;;;EAOhB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;wBAgCqB,uBACrB,SAAS,0BACT,2BAA2B,kBAC3B,UAAS,eACP,QAAQ"}
@@ -1,6 +1,5 @@
1
- import { ConfigParser } from "./EnvironmentParser-taAKfzT7.mjs";
1
+ import { t as ConfigParser } from "./EnvironmentParser-X6Z-jryw.mjs";
2
2
  import { z } from "zod/v4";
3
-
4
3
  //#region src/SnifferEnvironmentParser.ts
5
4
  /**
6
5
  * A specialized EnvironmentParser for build-time analysis that tracks
@@ -89,8 +88,7 @@ var SnifferEnvironmentParser = class {
89
88
  * Creates a ConfigParser that will return mock values when parsed.
90
89
  */
91
90
  create(builder) {
92
- const config = builder(this.getZodGetter);
93
- return new SnifferConfigParser(config, this.accessedVars);
91
+ return new SnifferConfigParser(builder(this.getZodGetter), this.accessedVars);
94
92
  }
95
93
  /**
96
94
  * Returns all environment variable names that were accessed.
@@ -204,7 +202,7 @@ async function sniffWithFireAndForget(sniffer, operation, options = {}) {
204
202
  unhandledRejections
205
203
  };
206
204
  }
207
-
208
205
  //#endregion
209
206
  export { SnifferEnvironmentParser, sniffWithFireAndForget };
207
+
210
208
  //# sourceMappingURL=SnifferEnvironmentParser.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"SnifferEnvironmentParser.mjs","names":["schema: z.ZodType","name: string","result: Record<string, unknown>","builder: (get: EnvFetcher) => TReturn","opts?: { markOptional?: boolean }","config: T","result: EmptyObject","sniffer: SnifferEnvironmentParser","operation: () => unknown | Promise<unknown>","options: SniffOptions","unhandledRejections: Error[]","reason: unknown","error: Error | undefined"],"sources":["../src/SnifferEnvironmentParser.ts"],"sourcesContent":["import { z } from 'zod/v4';\nimport {\n\tConfigParser,\n\ttype EmptyObject,\n\ttype EnvFetcher,\n} from './EnvironmentParser';\n\n/**\n * A specialized EnvironmentParser for build-time analysis that tracks\n * which environment variables are accessed without requiring actual values.\n *\n * Unlike the regular EnvironmentParser, the sniffer:\n * - Always returns mock values from .parse() and .safeParse()\n * - Never throws validation errors\n * - Tracks all accessed environment variable names\n *\n * This allows service registration to succeed during build-time analysis\n * even when environment variables are not set.\n *\n * @example\n * ```typescript\n * const sniffer = new SnifferEnvironmentParser();\n * await service.register(sniffer); // Always succeeds\n * const envVars = sniffer.getEnvironmentVariables(); // ['DATABASE_URL', 'API_KEY']\n * ```\n */\nexport class SnifferEnvironmentParser<_T extends EmptyObject = EmptyObject> {\n\tprivate readonly accessedVars: Set<string> = new Set();\n\tprivate readonly optionalVars: Set<string> = new Set();\n\n\t/**\n\t * Wraps a Zod schema to always return mock values.\n\t * This ensures .parse() and .safeParse() never fail.\n\t * Also detects when .optional() or .default() is called to track optional vars.\n\t */\n\tprivate wrapSchema = (schema: z.ZodType, name: string): z.ZodType => {\n\t\treturn new Proxy(schema, {\n\t\t\tget: (target, prop) => {\n\t\t\t\tif (prop === 'parse') {\n\t\t\t\t\treturn () => this.getMockValue(target);\n\t\t\t\t}\n\n\t\t\t\tif (prop === 'safeParse') {\n\t\t\t\t\treturn () => ({\n\t\t\t\t\t\tsuccess: true as const,\n\t\t\t\t\t\tdata: this.getMockValue(target),\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\t// Detect .optional() or .default() — mark the variable as optional\n\t\t\t\tif (prop === 'optional' || prop === 'default') {\n\t\t\t\t\tthis.optionalVars.add(name);\n\t\t\t\t}\n\n\t\t\t\tconst originalProp = target[prop as keyof typeof target];\n\t\t\t\tif (typeof originalProp === 'function') {\n\t\t\t\t\treturn (...args: any[]) => {\n\t\t\t\t\t\tconst result = originalProp.apply(target, args);\n\t\t\t\t\t\tif (result && typeof result === 'object' && 'parse' in result) {\n\t\t\t\t\t\t\treturn this.wrapSchema(result, name);\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn result;\n\t\t\t\t\t};\n\t\t\t\t}\n\n\t\t\t\treturn originalProp;\n\t\t\t},\n\t\t});\n\t};\n\n\t/**\n\t * Returns a mock value based on the Zod schema type.\n\t */\n\tprivate getMockValue(schema: z.ZodType): unknown {\n\t\t// Return type-appropriate mock values\n\t\tif (schema instanceof z.ZodString) return '';\n\t\tif (schema instanceof z.ZodNumber) return 0;\n\t\tif (schema instanceof z.ZodBoolean) return false;\n\t\tif (schema instanceof z.ZodArray) return [];\n\t\tif (schema instanceof z.ZodOptional) return undefined;\n\t\tif (schema instanceof z.ZodNullable) return null;\n\n\t\t// For object schemas, build mock object from shape\n\t\tif (schema instanceof z.ZodObject && schema.shape) {\n\t\t\tconst result: Record<string, unknown> = {};\n\t\t\tfor (const [key, value] of Object.entries(schema.shape)) {\n\t\t\t\tif (value instanceof z.ZodType) {\n\t\t\t\t\tresult[key] = this.getMockValue(value);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn result;\n\t\t}\n\n\t\treturn '';\n\t}\n\n\t/**\n\t * Creates a proxied Zod getter that tracks environment variable access.\n\t */\n\tprivate getZodGetter = (name: string) => {\n\t\tthis.accessedVars.add(name);\n\n\t\treturn new Proxy(\n\t\t\t{ ...z },\n\t\t\t{\n\t\t\t\tget: (target, prop) => {\n\t\t\t\t\t// @ts-expect-error\n\t\t\t\t\tconst value = target[prop];\n\n\t\t\t\t\tif (typeof value === 'function') {\n\t\t\t\t\t\treturn (...args: any[]) => {\n\t\t\t\t\t\t\tconst schema = value(...args);\n\t\t\t\t\t\t\treturn this.wrapSchema(schema, name);\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\n\t\t\t\t\tif (value && typeof value === 'object') {\n\t\t\t\t\t\treturn new Proxy(value, {\n\t\t\t\t\t\t\tget: (nestedTarget, nestedProp) => {\n\t\t\t\t\t\t\t\tconst nestedValue =\n\t\t\t\t\t\t\t\t\tnestedTarget[nestedProp as keyof typeof nestedTarget];\n\t\t\t\t\t\t\t\tif (typeof nestedValue === 'function') {\n\t\t\t\t\t\t\t\t\treturn (...args: any[]) => {\n\t\t\t\t\t\t\t\t\t\tconst schema = nestedValue(...args);\n\t\t\t\t\t\t\t\t\t\treturn this.wrapSchema(schema, name);\n\t\t\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\treturn nestedValue;\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\treturn value;\n\t\t\t\t},\n\t\t\t},\n\t\t);\n\t};\n\n\t/**\n\t * Creates a ConfigParser that will return mock values when parsed.\n\t */\n\tcreate<TReturn extends EmptyObject>(\n\t\tbuilder: (get: EnvFetcher) => TReturn,\n\t): ConfigParser<TReturn> {\n\t\tconst config = builder(this.getZodGetter);\n\t\treturn new SnifferConfigParser(config, this.accessedVars);\n\t}\n\n\t/**\n\t * Returns all environment variable names that were accessed.\n\t *\n\t * @param opts.markOptional - When true, optional variables (those accessed\n\t * via `.optional()` or `.default()`) are suffixed with `?` (e.g. `PORT?`).\n\t */\n\tgetEnvironmentVariables(opts?: { markOptional?: boolean }): string[] {\n\t\tconst vars = Array.from(this.accessedVars).sort();\n\t\tif (!opts?.markOptional) return vars;\n\t\treturn vars.map((name) =>\n\t\t\tthis.optionalVars.has(name) ? `${name}?` : name,\n\t\t);\n\t}\n\n\t/**\n\t * Returns all environment variable names that were accessed via\n\t * `.optional()` or `.default()` — i.e. variables that are not required.\n\t */\n\tgetOptionalVariables(): string[] {\n\t\treturn Array.from(this.optionalVars).sort();\n\t}\n}\n\n/**\n * A ConfigParser that always succeeds with mock values.\n */\nclass SnifferConfigParser<\n\tTResponse extends EmptyObject,\n> extends ConfigParser<TResponse> {\n\toverride parse(): any {\n\t\treturn this.parseWithMocks(this.getConfig());\n\t}\n\n\tprivate getConfig(): TResponse {\n\t\t// Access the private config via any cast\n\t\treturn (this as any).config;\n\t}\n\n\tprivate parseWithMocks<T>(config: T): any {\n\t\tconst result: EmptyObject = {};\n\n\t\tif (config && typeof config !== 'object') {\n\t\t\treturn config;\n\t\t}\n\n\t\tfor (const key in config) {\n\t\t\tconst schema = config[key];\n\n\t\t\tif (schema instanceof z.ZodType) {\n\t\t\t\t// Use safeParse which will return mock values from our wrapped schema\n\t\t\t\tconst parsed = schema.safeParse(undefined);\n\t\t\t\tresult[key] = parsed.success\n\t\t\t\t\t? parsed.data\n\t\t\t\t\t: this.getDefaultForSchema(schema);\n\t\t\t} else if (schema && typeof schema === 'object') {\n\t\t\t\tresult[key] = this.parseWithMocks(schema as EmptyObject);\n\t\t\t}\n\t\t}\n\n\t\treturn result;\n\t}\n\n\tprivate getDefaultForSchema(schema: z.ZodType): unknown {\n\t\tif (schema instanceof z.ZodString) return '';\n\t\tif (schema instanceof z.ZodNumber) return 0;\n\t\tif (schema instanceof z.ZodBoolean) return false;\n\t\tif (schema instanceof z.ZodArray) return [];\n\t\tif (schema instanceof z.ZodOptional) return undefined;\n\t\tif (schema instanceof z.ZodNullable) return null;\n\n\t\tif (schema instanceof z.ZodObject && schema.shape) {\n\t\t\tconst result: Record<string, unknown> = {};\n\t\t\tfor (const [key, value] of Object.entries(schema.shape)) {\n\t\t\t\tif (value instanceof z.ZodType) {\n\t\t\t\t\tresult[key] = this.getDefaultForSchema(value);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn result;\n\t\t}\n\n\t\treturn '';\n\t}\n}\n\n/**\n * Result of sniffing with fire-and-forget handling.\n */\nexport interface SniffResult {\n\t/** All environment variable names that were accessed during sniffing */\n\tenvVars: string[];\n\t/**\n\t * Subset of envVars that are optional (accessed via `.optional()` or\n\t * `.default()`). These do not need to be present for the app to start.\n\t */\n\toptionalEnvVars: string[];\n\t/** Error thrown during sniffing (env vars may still be captured) */\n\terror?: Error;\n\t/** Unhandled promise rejections captured during sniffing */\n\tunhandledRejections: Error[];\n}\n\n/**\n * Options for sniffing with fire-and-forget handling.\n */\nexport interface SniffOptions {\n\t/**\n\t * Time in milliseconds to wait for fire-and-forget promises to settle.\n\t * Some libraries like better-auth create async operations that may reject\n\t * after the initial event loop tick.\n\t * @default 100\n\t */\n\tsettleTimeMs?: number;\n}\n\n/**\n * Executes a sniffing operation with fire-and-forget handling.\n *\n * This function:\n * 1. Captures unhandled promise rejections during the operation\n * 2. Waits for async operations to settle before returning\n * 3. Gracefully handles errors without throwing\n *\n * Use this when sniffing environment variables from code that may:\n * - Throw synchronous errors\n * - Create fire-and-forget promises that reject\n * - Have async initialization that may fail\n *\n * @param sniffer - The SnifferEnvironmentParser instance to use\n * @param operation - The async operation to execute (e.g., service.register)\n * @param options - Optional configuration\n * @returns SniffResult with env vars and any errors encountered\n *\n * @example\n * ```typescript\n * const sniffer = new SnifferEnvironmentParser();\n * const result = await sniffWithFireAndForget(sniffer, async () => {\n * await service.register({ envParser: sniffer });\n * });\n * console.log('Env vars:', result.envVars);\n * console.log('Error:', result.error);\n * console.log('Unhandled rejections:', result.unhandledRejections);\n * ```\n */\nexport async function sniffWithFireAndForget(\n\tsniffer: SnifferEnvironmentParser,\n\toperation: () => unknown | Promise<unknown>,\n\toptions: SniffOptions = {},\n): Promise<SniffResult> {\n\tconst { settleTimeMs = 100 } = options;\n\tconst unhandledRejections: Error[] = [];\n\n\t// Capture unhandled rejections during sniffing (fire-and-forget promises)\n\t// Libraries like better-auth create async operations that may reject after\n\t// the initial event loop tick\n\tconst captureRejection = (reason: unknown) => {\n\t\tconst err = reason instanceof Error ? reason : new Error(String(reason));\n\t\tunhandledRejections.push(err);\n\t};\n\tprocess.on('unhandledRejection', captureRejection);\n\n\tlet error: Error | undefined;\n\n\ttry {\n\t\tconst result = operation();\n\n\t\t// Handle async result\n\t\tif (result && typeof result === 'object' && 'then' in result) {\n\t\t\tawait Promise.resolve(result).catch((e) => {\n\t\t\t\terror = e instanceof Error ? e : new Error(String(e));\n\t\t\t});\n\t\t}\n\t} catch (e) {\n\t\terror = e instanceof Error ? e : new Error(String(e));\n\t} finally {\n\t\t// Wait for fire-and-forget promises to settle\n\t\tawait new Promise((resolve) => setTimeout(resolve, settleTimeMs));\n\t\tprocess.off('unhandledRejection', captureRejection);\n\t}\n\n\treturn {\n\t\tenvVars: sniffer.getEnvironmentVariables(),\n\t\toptionalEnvVars: sniffer.getOptionalVariables(),\n\t\terror,\n\t\tunhandledRejections,\n\t};\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AA0BA,IAAa,2BAAb,MAA4E;CAC3E,AAAiB,+BAA4B,IAAI;CACjD,AAAiB,+BAA4B,IAAI;;;;;;CAOjD,AAAQ,aAAa,CAACA,QAAmBC,SAA4B;AACpE,SAAO,IAAI,MAAM,QAAQ,EACxB,KAAK,CAAC,QAAQ,SAAS;AACtB,OAAI,SAAS,QACZ,QAAO,MAAM,KAAK,aAAa,OAAO;AAGvC,OAAI,SAAS,YACZ,QAAO,OAAO;IACb,SAAS;IACT,MAAM,KAAK,aAAa,OAAO;GAC/B;AAIF,OAAI,SAAS,cAAc,SAAS,UACnC,MAAK,aAAa,IAAI,KAAK;GAG5B,MAAM,eAAe,OAAO;AAC5B,cAAW,iBAAiB,WAC3B,QAAO,CAAC,GAAG,SAAgB;IAC1B,MAAM,SAAS,aAAa,MAAM,QAAQ,KAAK;AAC/C,QAAI,iBAAiB,WAAW,YAAY,WAAW,OACtD,QAAO,KAAK,WAAW,QAAQ,KAAK;AAErC,WAAO;GACP;AAGF,UAAO;EACP,EACD;CACD;;;;CAKD,AAAQ,aAAaD,QAA4B;AAEhD,MAAI,kBAAkB,EAAE,UAAW,QAAO;AAC1C,MAAI,kBAAkB,EAAE,UAAW,QAAO;AAC1C,MAAI,kBAAkB,EAAE,WAAY,QAAO;AAC3C,MAAI,kBAAkB,EAAE,SAAU,QAAO,CAAE;AAC3C,MAAI,kBAAkB,EAAE,YAAa;AACrC,MAAI,kBAAkB,EAAE,YAAa,QAAO;AAG5C,MAAI,kBAAkB,EAAE,aAAa,OAAO,OAAO;GAClD,MAAME,SAAkC,CAAE;AAC1C,QAAK,MAAM,CAAC,KAAK,MAAM,IAAI,OAAO,QAAQ,OAAO,MAAM,CACtD,KAAI,iBAAiB,EAAE,QACtB,QAAO,OAAO,KAAK,aAAa,MAAM;AAGxC,UAAO;EACP;AAED,SAAO;CACP;;;;CAKD,AAAQ,eAAe,CAACD,SAAiB;AACxC,OAAK,aAAa,IAAI,KAAK;AAE3B,SAAO,IAAI,MACV,EAAE,GAAG,EAAG,GACR,EACC,KAAK,CAAC,QAAQ,SAAS;GAEtB,MAAM,QAAQ,OAAO;AAErB,cAAW,UAAU,WACpB,QAAO,CAAC,GAAG,SAAgB;IAC1B,MAAM,SAAS,MAAM,GAAG,KAAK;AAC7B,WAAO,KAAK,WAAW,QAAQ,KAAK;GACpC;AAGF,OAAI,gBAAgB,UAAU,SAC7B,QAAO,IAAI,MAAM,OAAO,EACvB,KAAK,CAAC,cAAc,eAAe;IAClC,MAAM,cACL,aAAa;AACd,eAAW,gBAAgB,WAC1B,QAAO,CAAC,GAAG,SAAgB;KAC1B,MAAM,SAAS,YAAY,GAAG,KAAK;AACnC,YAAO,KAAK,WAAW,QAAQ,KAAK;IACpC;AAEF,WAAO;GACP,EACD;AAGF,UAAO;EACP,EACD;CAEF;;;;CAKD,OACCE,SACwB;EACxB,MAAM,SAAS,QAAQ,KAAK,aAAa;AACzC,SAAO,IAAI,oBAAoB,QAAQ,KAAK;CAC5C;;;;;;;CAQD,wBAAwBC,MAA6C;EACpE,MAAM,OAAO,MAAM,KAAK,KAAK,aAAa,CAAC,MAAM;AACjD,OAAK,MAAM,aAAc,QAAO;AAChC,SAAO,KAAK,IAAI,CAAC,SAChB,KAAK,aAAa,IAAI,KAAK,IAAI,EAAE,KAAK,KAAK,KAC3C;CACD;;;;;CAMD,uBAAiC;AAChC,SAAO,MAAM,KAAK,KAAK,aAAa,CAAC,MAAM;CAC3C;AACD;;;;AAKD,IAAM,sBAAN,cAEU,aAAwB;CACjC,AAAS,QAAa;AACrB,SAAO,KAAK,eAAe,KAAK,WAAW,CAAC;CAC5C;CAED,AAAQ,YAAuB;AAE9B,SAAQ,KAAa;CACrB;CAED,AAAQ,eAAkBC,QAAgB;EACzC,MAAMC,SAAsB,CAAE;AAE9B,MAAI,iBAAiB,WAAW,SAC/B,QAAO;AAGR,OAAK,MAAM,OAAO,QAAQ;GACzB,MAAM,SAAS,OAAO;AAEtB,OAAI,kBAAkB,EAAE,SAAS;IAEhC,MAAM,SAAS,OAAO,iBAAoB;AAC1C,WAAO,OAAO,OAAO,UAClB,OAAO,OACP,KAAK,oBAAoB,OAAO;GACnC,WAAU,iBAAiB,WAAW,SACtC,QAAO,OAAO,KAAK,eAAe,OAAsB;EAEzD;AAED,SAAO;CACP;CAED,AAAQ,oBAAoBN,QAA4B;AACvD,MAAI,kBAAkB,EAAE,UAAW,QAAO;AAC1C,MAAI,kBAAkB,EAAE,UAAW,QAAO;AAC1C,MAAI,kBAAkB,EAAE,WAAY,QAAO;AAC3C,MAAI,kBAAkB,EAAE,SAAU,QAAO,CAAE;AAC3C,MAAI,kBAAkB,EAAE,YAAa;AACrC,MAAI,kBAAkB,EAAE,YAAa,QAAO;AAE5C,MAAI,kBAAkB,EAAE,aAAa,OAAO,OAAO;GAClD,MAAME,SAAkC,CAAE;AAC1C,QAAK,MAAM,CAAC,KAAK,MAAM,IAAI,OAAO,QAAQ,OAAO,MAAM,CACtD,KAAI,iBAAiB,EAAE,QACtB,QAAO,OAAO,KAAK,oBAAoB,MAAM;AAG/C,UAAO;EACP;AAED,SAAO;CACP;AACD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6DD,eAAsB,uBACrBK,SACAC,WACAC,UAAwB,CAAE,GACH;CACvB,MAAM,EAAE,eAAe,KAAK,GAAG;CAC/B,MAAMC,sBAA+B,CAAE;CAKvC,MAAM,mBAAmB,CAACC,WAAoB;EAC7C,MAAM,MAAM,kBAAkB,QAAQ,SAAS,IAAI,MAAM,OAAO,OAAO;AACvE,sBAAoB,KAAK,IAAI;CAC7B;AACD,SAAQ,GAAG,sBAAsB,iBAAiB;CAElD,IAAIC;AAEJ,KAAI;EACH,MAAM,SAAS,WAAW;AAG1B,MAAI,iBAAiB,WAAW,YAAY,UAAU,OACrD,OAAM,QAAQ,QAAQ,OAAO,CAAC,MAAM,CAAC,MAAM;AAC1C,WAAQ,aAAa,QAAQ,IAAI,IAAI,MAAM,OAAO,EAAE;EACpD,EAAC;CAEH,SAAQ,GAAG;AACX,UAAQ,aAAa,QAAQ,IAAI,IAAI,MAAM,OAAO,EAAE;CACpD,UAAS;AAET,QAAM,IAAI,QAAQ,CAAC,YAAY,WAAW,SAAS,aAAa;AAChE,UAAQ,IAAI,sBAAsB,iBAAiB;CACnD;AAED,QAAO;EACN,SAAS,QAAQ,yBAAyB;EAC1C,iBAAiB,QAAQ,sBAAsB;EAC/C;EACA;CACA;AACD"}
1
+ {"version":3,"file":"SnifferEnvironmentParser.mjs","names":[],"sources":["../src/SnifferEnvironmentParser.ts"],"sourcesContent":["import { z } from 'zod/v4';\nimport {\n\tConfigParser,\n\ttype EmptyObject,\n\ttype EnvFetcher,\n} from './EnvironmentParser';\n\n/**\n * A specialized EnvironmentParser for build-time analysis that tracks\n * which environment variables are accessed without requiring actual values.\n *\n * Unlike the regular EnvironmentParser, the sniffer:\n * - Always returns mock values from .parse() and .safeParse()\n * - Never throws validation errors\n * - Tracks all accessed environment variable names\n *\n * This allows service registration to succeed during build-time analysis\n * even when environment variables are not set.\n *\n * @example\n * ```typescript\n * const sniffer = new SnifferEnvironmentParser();\n * await service.register(sniffer); // Always succeeds\n * const envVars = sniffer.getEnvironmentVariables(); // ['DATABASE_URL', 'API_KEY']\n * ```\n */\nexport class SnifferEnvironmentParser<_T extends EmptyObject = EmptyObject> {\n\tprivate readonly accessedVars: Set<string> = new Set();\n\tprivate readonly optionalVars: Set<string> = new Set();\n\n\t/**\n\t * Wraps a Zod schema to always return mock values.\n\t * This ensures .parse() and .safeParse() never fail.\n\t * Also detects when .optional() or .default() is called to track optional vars.\n\t */\n\tprivate wrapSchema = (schema: z.ZodType, name: string): z.ZodType => {\n\t\treturn new Proxy(schema, {\n\t\t\tget: (target, prop) => {\n\t\t\t\tif (prop === 'parse') {\n\t\t\t\t\treturn () => this.getMockValue(target);\n\t\t\t\t}\n\n\t\t\t\tif (prop === 'safeParse') {\n\t\t\t\t\treturn () => ({\n\t\t\t\t\t\tsuccess: true as const,\n\t\t\t\t\t\tdata: this.getMockValue(target),\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\t// Detect .optional() or .default() — mark the variable as optional\n\t\t\t\tif (prop === 'optional' || prop === 'default') {\n\t\t\t\t\tthis.optionalVars.add(name);\n\t\t\t\t}\n\n\t\t\t\tconst originalProp = target[prop as keyof typeof target];\n\t\t\t\tif (typeof originalProp === 'function') {\n\t\t\t\t\treturn (...args: any[]) => {\n\t\t\t\t\t\tconst result = originalProp.apply(target, args);\n\t\t\t\t\t\tif (result && typeof result === 'object' && 'parse' in result) {\n\t\t\t\t\t\t\treturn this.wrapSchema(result, name);\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn result;\n\t\t\t\t\t};\n\t\t\t\t}\n\n\t\t\t\treturn originalProp;\n\t\t\t},\n\t\t});\n\t};\n\n\t/**\n\t * Returns a mock value based on the Zod schema type.\n\t */\n\tprivate getMockValue(schema: z.ZodType): unknown {\n\t\t// Return type-appropriate mock values\n\t\tif (schema instanceof z.ZodString) return '';\n\t\tif (schema instanceof z.ZodNumber) return 0;\n\t\tif (schema instanceof z.ZodBoolean) return false;\n\t\tif (schema instanceof z.ZodArray) return [];\n\t\tif (schema instanceof z.ZodOptional) return undefined;\n\t\tif (schema instanceof z.ZodNullable) return null;\n\n\t\t// For object schemas, build mock object from shape\n\t\tif (schema instanceof z.ZodObject && schema.shape) {\n\t\t\tconst result: Record<string, unknown> = {};\n\t\t\tfor (const [key, value] of Object.entries(schema.shape)) {\n\t\t\t\tif (value instanceof z.ZodType) {\n\t\t\t\t\tresult[key] = this.getMockValue(value);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn result;\n\t\t}\n\n\t\treturn '';\n\t}\n\n\t/**\n\t * Creates a proxied Zod getter that tracks environment variable access.\n\t */\n\tprivate getZodGetter = (name: string) => {\n\t\tthis.accessedVars.add(name);\n\n\t\treturn new Proxy(\n\t\t\t{ ...z },\n\t\t\t{\n\t\t\t\tget: (target, prop) => {\n\t\t\t\t\t// @ts-expect-error\n\t\t\t\t\tconst value = target[prop];\n\n\t\t\t\t\tif (typeof value === 'function') {\n\t\t\t\t\t\treturn (...args: any[]) => {\n\t\t\t\t\t\t\tconst schema = value(...args);\n\t\t\t\t\t\t\treturn this.wrapSchema(schema, name);\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\n\t\t\t\t\tif (value && typeof value === 'object') {\n\t\t\t\t\t\treturn new Proxy(value, {\n\t\t\t\t\t\t\tget: (nestedTarget, nestedProp) => {\n\t\t\t\t\t\t\t\tconst nestedValue =\n\t\t\t\t\t\t\t\t\tnestedTarget[nestedProp as keyof typeof nestedTarget];\n\t\t\t\t\t\t\t\tif (typeof nestedValue === 'function') {\n\t\t\t\t\t\t\t\t\treturn (...args: any[]) => {\n\t\t\t\t\t\t\t\t\t\tconst schema = nestedValue(...args);\n\t\t\t\t\t\t\t\t\t\treturn this.wrapSchema(schema, name);\n\t\t\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\treturn nestedValue;\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\treturn value;\n\t\t\t\t},\n\t\t\t},\n\t\t);\n\t};\n\n\t/**\n\t * Creates a ConfigParser that will return mock values when parsed.\n\t */\n\tcreate<TReturn extends EmptyObject>(\n\t\tbuilder: (get: EnvFetcher) => TReturn,\n\t): ConfigParser<TReturn> {\n\t\tconst config = builder(this.getZodGetter);\n\t\treturn new SnifferConfigParser(config, this.accessedVars);\n\t}\n\n\t/**\n\t * Returns all environment variable names that were accessed.\n\t *\n\t * @param opts.markOptional - When true, optional variables (those accessed\n\t * via `.optional()` or `.default()`) are suffixed with `?` (e.g. `PORT?`).\n\t */\n\tgetEnvironmentVariables(opts?: { markOptional?: boolean }): string[] {\n\t\tconst vars = Array.from(this.accessedVars).sort();\n\t\tif (!opts?.markOptional) return vars;\n\t\treturn vars.map((name) =>\n\t\t\tthis.optionalVars.has(name) ? `${name}?` : name,\n\t\t);\n\t}\n\n\t/**\n\t * Returns all environment variable names that were accessed via\n\t * `.optional()` or `.default()` — i.e. variables that are not required.\n\t */\n\tgetOptionalVariables(): string[] {\n\t\treturn Array.from(this.optionalVars).sort();\n\t}\n}\n\n/**\n * A ConfigParser that always succeeds with mock values.\n */\nclass SnifferConfigParser<\n\tTResponse extends EmptyObject,\n> extends ConfigParser<TResponse> {\n\toverride parse(): any {\n\t\treturn this.parseWithMocks(this.getConfig());\n\t}\n\n\tprivate getConfig(): TResponse {\n\t\t// Access the private config via any cast\n\t\treturn (this as any).config;\n\t}\n\n\tprivate parseWithMocks<T>(config: T): any {\n\t\tconst result: EmptyObject = {};\n\n\t\tif (config && typeof config !== 'object') {\n\t\t\treturn config;\n\t\t}\n\n\t\tfor (const key in config) {\n\t\t\tconst schema = config[key];\n\n\t\t\tif (schema instanceof z.ZodType) {\n\t\t\t\t// Use safeParse which will return mock values from our wrapped schema\n\t\t\t\tconst parsed = schema.safeParse(undefined);\n\t\t\t\tresult[key] = parsed.success\n\t\t\t\t\t? parsed.data\n\t\t\t\t\t: this.getDefaultForSchema(schema);\n\t\t\t} else if (schema && typeof schema === 'object') {\n\t\t\t\tresult[key] = this.parseWithMocks(schema as EmptyObject);\n\t\t\t}\n\t\t}\n\n\t\treturn result;\n\t}\n\n\tprivate getDefaultForSchema(schema: z.ZodType): unknown {\n\t\tif (schema instanceof z.ZodString) return '';\n\t\tif (schema instanceof z.ZodNumber) return 0;\n\t\tif (schema instanceof z.ZodBoolean) return false;\n\t\tif (schema instanceof z.ZodArray) return [];\n\t\tif (schema instanceof z.ZodOptional) return undefined;\n\t\tif (schema instanceof z.ZodNullable) return null;\n\n\t\tif (schema instanceof z.ZodObject && schema.shape) {\n\t\t\tconst result: Record<string, unknown> = {};\n\t\t\tfor (const [key, value] of Object.entries(schema.shape)) {\n\t\t\t\tif (value instanceof z.ZodType) {\n\t\t\t\t\tresult[key] = this.getDefaultForSchema(value);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn result;\n\t\t}\n\n\t\treturn '';\n\t}\n}\n\n/**\n * Result of sniffing with fire-and-forget handling.\n */\nexport interface SniffResult {\n\t/** All environment variable names that were accessed during sniffing */\n\tenvVars: string[];\n\t/**\n\t * Subset of envVars that are optional (accessed via `.optional()` or\n\t * `.default()`). These do not need to be present for the app to start.\n\t */\n\toptionalEnvVars: string[];\n\t/** Error thrown during sniffing (env vars may still be captured) */\n\terror?: Error;\n\t/** Unhandled promise rejections captured during sniffing */\n\tunhandledRejections: Error[];\n}\n\n/**\n * Options for sniffing with fire-and-forget handling.\n */\nexport interface SniffOptions {\n\t/**\n\t * Time in milliseconds to wait for fire-and-forget promises to settle.\n\t * Some libraries like better-auth create async operations that may reject\n\t * after the initial event loop tick.\n\t * @default 100\n\t */\n\tsettleTimeMs?: number;\n}\n\n/**\n * Executes a sniffing operation with fire-and-forget handling.\n *\n * This function:\n * 1. Captures unhandled promise rejections during the operation\n * 2. Waits for async operations to settle before returning\n * 3. Gracefully handles errors without throwing\n *\n * Use this when sniffing environment variables from code that may:\n * - Throw synchronous errors\n * - Create fire-and-forget promises that reject\n * - Have async initialization that may fail\n *\n * @param sniffer - The SnifferEnvironmentParser instance to use\n * @param operation - The async operation to execute (e.g., service.register)\n * @param options - Optional configuration\n * @returns SniffResult with env vars and any errors encountered\n *\n * @example\n * ```typescript\n * const sniffer = new SnifferEnvironmentParser();\n * const result = await sniffWithFireAndForget(sniffer, async () => {\n * await service.register({ envParser: sniffer });\n * });\n * console.log('Env vars:', result.envVars);\n * console.log('Error:', result.error);\n * console.log('Unhandled rejections:', result.unhandledRejections);\n * ```\n */\nexport async function sniffWithFireAndForget(\n\tsniffer: SnifferEnvironmentParser,\n\toperation: () => unknown | Promise<unknown>,\n\toptions: SniffOptions = {},\n): Promise<SniffResult> {\n\tconst { settleTimeMs = 100 } = options;\n\tconst unhandledRejections: Error[] = [];\n\n\t// Capture unhandled rejections during sniffing (fire-and-forget promises)\n\t// Libraries like better-auth create async operations that may reject after\n\t// the initial event loop tick\n\tconst captureRejection = (reason: unknown) => {\n\t\tconst err = reason instanceof Error ? reason : new Error(String(reason));\n\t\tunhandledRejections.push(err);\n\t};\n\tprocess.on('unhandledRejection', captureRejection);\n\n\tlet error: Error | undefined;\n\n\ttry {\n\t\tconst result = operation();\n\n\t\t// Handle async result\n\t\tif (result && typeof result === 'object' && 'then' in result) {\n\t\t\tawait Promise.resolve(result).catch((e) => {\n\t\t\t\terror = e instanceof Error ? e : new Error(String(e));\n\t\t\t});\n\t\t}\n\t} catch (e) {\n\t\terror = e instanceof Error ? e : new Error(String(e));\n\t} finally {\n\t\t// Wait for fire-and-forget promises to settle\n\t\tawait new Promise((resolve) => setTimeout(resolve, settleTimeMs));\n\t\tprocess.off('unhandledRejection', captureRejection);\n\t}\n\n\treturn {\n\t\tenvVars: sniffer.getEnvironmentVariables(),\n\t\toptionalEnvVars: sniffer.getOptionalVariables(),\n\t\terror,\n\t\tunhandledRejections,\n\t};\n}\n"],"mappings":"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"}
@@ -1,10 +1,9 @@
1
- Object.defineProperty(exports, '__esModule', { value: true });
2
- const require_chunk = require('./chunk-CUT6urMc.cjs');
3
- const node_crypto = require_chunk.__toESM(require("node:crypto"));
4
-
1
+ Object.defineProperties(exports, {
2
+ __esModule: { value: true },
3
+ [Symbol.toStringTag]: { value: "Module" }
4
+ });
5
+ let node_crypto = require("node:crypto");
5
6
  //#region src/credentials.ts
6
- /** AES-256-GCM auth tag length */
7
- const AUTH_TAG_LENGTH = 16;
8
7
  /**
9
8
  * Decrypt credentials from encrypted payload.
10
9
  * Exported for testing purposes.
@@ -13,8 +12,8 @@ function decryptCredentials(encrypted, iv, masterKey) {
13
12
  const key = Buffer.from(masterKey, "hex");
14
13
  const ivBuffer = Buffer.from(iv, "hex");
15
14
  const combined = Buffer.from(encrypted, "base64");
16
- const ciphertext = combined.subarray(0, -AUTH_TAG_LENGTH);
17
- const authTag = combined.subarray(-AUTH_TAG_LENGTH);
15
+ const ciphertext = combined.subarray(0, -16);
16
+ const authTag = combined.subarray(-16);
18
17
  const decipher = (0, node_crypto.createDecipheriv)("aes-256-gcm", key, ivBuffer);
19
18
  decipher.setAuthTag(authTag);
20
19
  const plaintext = Buffer.concat([decipher.update(ciphertext), decipher.final()]);
@@ -63,10 +62,9 @@ const Credentials = (() => {
63
62
  return {};
64
63
  }
65
64
  })();
66
- var credentials_default = Credentials;
67
-
68
65
  //#endregion
69
66
  exports.Credentials = Credentials;
67
+ exports.default = Credentials;
70
68
  exports.decryptCredentials = decryptCredentials;
71
- exports.default = credentials_default;
69
+
72
70
  //# sourceMappingURL=credentials.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"credentials.cjs","names":["encrypted: string","iv: string","masterKey: string","Credentials: Record<string, string>"],"sources":["../src/credentials.ts"],"sourcesContent":["import { createDecipheriv } from 'node:crypto';\n\n/**\n * Build-time injected encrypted credentials.\n * These are replaced by tsdown/esbuild --define at build time.\n */\ndeclare const __GKM_ENCRYPTED_CREDENTIALS__: string | undefined;\ndeclare const __GKM_CREDENTIALS_IV__: string | undefined;\n\n/** AES-256-GCM auth tag length */\nconst AUTH_TAG_LENGTH = 16;\n\n/**\n * Decrypt credentials from encrypted payload.\n * Exported for testing purposes.\n */\nexport function decryptCredentials(\n\tencrypted: string,\n\tiv: string,\n\tmasterKey: string,\n): Record<string, string> {\n\tconst key = Buffer.from(masterKey, 'hex');\n\tconst ivBuffer = Buffer.from(iv, 'hex');\n\tconst combined = Buffer.from(encrypted, 'base64');\n\n\t// Split ciphertext and auth tag\n\tconst ciphertext = combined.subarray(0, -AUTH_TAG_LENGTH);\n\tconst authTag = combined.subarray(-AUTH_TAG_LENGTH);\n\n\t// Decrypt using AES-256-GCM\n\tconst decipher = createDecipheriv('aes-256-gcm', key, ivBuffer);\n\tdecipher.setAuthTag(authTag);\n\n\tconst plaintext = Buffer.concat([\n\t\tdecipher.update(ciphertext),\n\t\tdecipher.final(),\n\t]);\n\n\treturn JSON.parse(plaintext.toString('utf-8'));\n}\n\n/**\n * Credentials object for use with EnvironmentParser.\n *\n * Resolution order:\n * 1. **Dev mode (gkm dev/exec)**: Checks `globalThis.__gkm_credentials__` for\n * credentials injected by the CLI preload script. This approach survives\n * CJS/ESM module duplication (where mutating the export would only affect one copy).\n * 2. **Production mode**: Decrypts build-time embedded credentials using the\n * `GKM_MASTER_KEY` environment variable (AES-256-GCM).\n * 3. **Fallback**: Returns empty object (allows graceful fallback to process.env).\n *\n * @example\n * ```typescript\n * import { EnvironmentParser } from '@geekmidas/envkit';\n * import { Credentials } from '@geekmidas/envkit/credentials';\n *\n * export const envParser = new EnvironmentParser({...process.env, ...Credentials})\n * .create((get) => ({\n * database: {\n * url: get('DATABASE_URL').string(),\n * },\n * }))\n * .parse();\n * ```\n */\nexport const Credentials: Record<string, string> = (() => {\n\t// Dev mode: check if gkm exec/dev preload injected credentials via globalThis\n\t// This survives CJS/ESM module duplication where Object.assign on the\n\t// export would only mutate one copy of the module's Credentials object.\n\tconst injected = (globalThis as Record<string, unknown>)\n\t\t.__gkm_credentials__ as Record<string, string> | undefined;\n\tif (injected) {\n\t\treturn injected;\n\t}\n\n\t// Development mode - no credentials embedded at build time\n\tif (\n\t\ttypeof __GKM_ENCRYPTED_CREDENTIALS__ === 'undefined' ||\n\t\ttypeof __GKM_CREDENTIALS_IV__ === 'undefined'\n\t) {\n\t\treturn {};\n\t}\n\n\t// Production mode - decrypt credentials using master key\n\tconst masterKey = process.env.GKM_MASTER_KEY;\n\n\tif (!masterKey) {\n\t\t// Log warning but don't throw - allows graceful fallback to env vars\n\t\tconsole.error(\n\t\t\t'[gkm] GKM_MASTER_KEY environment variable is required to decrypt credentials.',\n\t\t);\n\t\tconsole.error(\n\t\t\t'[gkm] Falling back to environment variables. Some secrets may be missing.',\n\t\t);\n\t\treturn {};\n\t}\n\n\ttry {\n\t\treturn decryptCredentials(\n\t\t\t__GKM_ENCRYPTED_CREDENTIALS__,\n\t\t\t__GKM_CREDENTIALS_IV__,\n\t\t\tmasterKey,\n\t\t);\n\t} catch (error) {\n\t\tconsole.error('[gkm] Failed to decrypt credentials:', error);\n\t\tconsole.error('[gkm] Falling back to environment variables.');\n\t\treturn {};\n\t}\n})();\n\nexport default Credentials;\n"],"mappings":";;;;;;AAUA,MAAM,kBAAkB;;;;;AAMxB,SAAgB,mBACfA,WACAC,IACAC,WACyB;CACzB,MAAM,MAAM,OAAO,KAAK,WAAW,MAAM;CACzC,MAAM,WAAW,OAAO,KAAK,IAAI,MAAM;CACvC,MAAM,WAAW,OAAO,KAAK,WAAW,SAAS;CAGjD,MAAM,aAAa,SAAS,SAAS,IAAI,gBAAgB;CACzD,MAAM,UAAU,SAAS,UAAU,gBAAgB;CAGnD,MAAM,WAAW,kCAAiB,eAAe,KAAK,SAAS;AAC/D,UAAS,WAAW,QAAQ;CAE5B,MAAM,YAAY,OAAO,OAAO,CAC/B,SAAS,OAAO,WAAW,EAC3B,SAAS,OAAO,AAChB,EAAC;AAEF,QAAO,KAAK,MAAM,UAAU,SAAS,QAAQ,CAAC;AAC9C;;;;;;;;;;;;;;;;;;;;;;;;;;AA2BD,MAAaC,cAAsC,CAAC,MAAM;CAIzD,MAAM,WAAY,WAChB;AACF,KAAI,SACH,QAAO;AAIR,YACQ,kCAAkC,sBAClC,2BAA2B,YAElC,QAAO,CAAE;CAIV,MAAM,YAAY,QAAQ,IAAI;AAE9B,MAAK,WAAW;AAEf,UAAQ,MACP,gFACA;AACD,UAAQ,MACP,4EACA;AACD,SAAO,CAAE;CACT;AAED,KAAI;AACH,SAAO,mBACN,+BACA,wBACA,UACA;CACD,SAAQ,OAAO;AACf,UAAQ,MAAM,wCAAwC,MAAM;AAC5D,UAAQ,MAAM,+CAA+C;AAC7D,SAAO,CAAE;CACT;AACD,IAAG;AAEJ,0BAAe"}
1
+ {"version":3,"file":"credentials.cjs","names":["createDecipheriv"],"sources":["../src/credentials.ts"],"sourcesContent":["import { createDecipheriv } from 'node:crypto';\n\n/**\n * Build-time injected encrypted credentials.\n * These are replaced by tsdown/esbuild --define at build time.\n */\ndeclare const __GKM_ENCRYPTED_CREDENTIALS__: string | undefined;\ndeclare const __GKM_CREDENTIALS_IV__: string | undefined;\n\n/** AES-256-GCM auth tag length */\nconst AUTH_TAG_LENGTH = 16;\n\n/**\n * Decrypt credentials from encrypted payload.\n * Exported for testing purposes.\n */\nexport function decryptCredentials(\n\tencrypted: string,\n\tiv: string,\n\tmasterKey: string,\n): Record<string, string> {\n\tconst key = Buffer.from(masterKey, 'hex');\n\tconst ivBuffer = Buffer.from(iv, 'hex');\n\tconst combined = Buffer.from(encrypted, 'base64');\n\n\t// Split ciphertext and auth tag\n\tconst ciphertext = combined.subarray(0, -AUTH_TAG_LENGTH);\n\tconst authTag = combined.subarray(-AUTH_TAG_LENGTH);\n\n\t// Decrypt using AES-256-GCM\n\tconst decipher = createDecipheriv('aes-256-gcm', key, ivBuffer);\n\tdecipher.setAuthTag(authTag);\n\n\tconst plaintext = Buffer.concat([\n\t\tdecipher.update(ciphertext),\n\t\tdecipher.final(),\n\t]);\n\n\treturn JSON.parse(plaintext.toString('utf-8'));\n}\n\n/**\n * Credentials object for use with EnvironmentParser.\n *\n * Resolution order:\n * 1. **Dev mode (gkm dev/exec)**: Checks `globalThis.__gkm_credentials__` for\n * credentials injected by the CLI preload script. This approach survives\n * CJS/ESM module duplication (where mutating the export would only affect one copy).\n * 2. **Production mode**: Decrypts build-time embedded credentials using the\n * `GKM_MASTER_KEY` environment variable (AES-256-GCM).\n * 3. **Fallback**: Returns empty object (allows graceful fallback to process.env).\n *\n * @example\n * ```typescript\n * import { EnvironmentParser } from '@geekmidas/envkit';\n * import { Credentials } from '@geekmidas/envkit/credentials';\n *\n * export const envParser = new EnvironmentParser({...process.env, ...Credentials})\n * .create((get) => ({\n * database: {\n * url: get('DATABASE_URL').string(),\n * },\n * }))\n * .parse();\n * ```\n */\nexport const Credentials: Record<string, string> = (() => {\n\t// Dev mode: check if gkm exec/dev preload injected credentials via globalThis\n\t// This survives CJS/ESM module duplication where Object.assign on the\n\t// export would only mutate one copy of the module's Credentials object.\n\tconst injected = (globalThis as Record<string, unknown>)\n\t\t.__gkm_credentials__ as Record<string, string> | undefined;\n\tif (injected) {\n\t\treturn injected;\n\t}\n\n\t// Development mode - no credentials embedded at build time\n\tif (\n\t\ttypeof __GKM_ENCRYPTED_CREDENTIALS__ === 'undefined' ||\n\t\ttypeof __GKM_CREDENTIALS_IV__ === 'undefined'\n\t) {\n\t\treturn {};\n\t}\n\n\t// Production mode - decrypt credentials using master key\n\tconst masterKey = process.env.GKM_MASTER_KEY;\n\n\tif (!masterKey) {\n\t\t// Log warning but don't throw - allows graceful fallback to env vars\n\t\tconsole.error(\n\t\t\t'[gkm] GKM_MASTER_KEY environment variable is required to decrypt credentials.',\n\t\t);\n\t\tconsole.error(\n\t\t\t'[gkm] Falling back to environment variables. Some secrets may be missing.',\n\t\t);\n\t\treturn {};\n\t}\n\n\ttry {\n\t\treturn decryptCredentials(\n\t\t\t__GKM_ENCRYPTED_CREDENTIALS__,\n\t\t\t__GKM_CREDENTIALS_IV__,\n\t\t\tmasterKey,\n\t\t);\n\t} catch (error) {\n\t\tconsole.error('[gkm] Failed to decrypt credentials:', error);\n\t\tconsole.error('[gkm] Falling back to environment variables.');\n\t\treturn {};\n\t}\n})();\n\nexport default Credentials;\n"],"mappings":";;;;;;;;;;AAgBA,SAAgB,mBACf,WACA,IACA,WACyB;CACzB,MAAM,MAAM,OAAO,KAAK,WAAW,KAAK;CACxC,MAAM,WAAW,OAAO,KAAK,IAAI,KAAK;CACtC,MAAM,WAAW,OAAO,KAAK,WAAW,QAAQ;CAGhD,MAAM,aAAa,SAAS,SAAS,GAAG,GAAgB;CACxD,MAAM,UAAU,SAAS,SAAS,GAAgB;CAGlD,MAAM,YAAA,GAAWA,YAAAA,iBAAAA,CAAiB,eAAe,KAAK,QAAQ;CAC9D,SAAS,WAAW,OAAO;CAE3B,MAAM,YAAY,OAAO,OAAO,CAC/B,SAAS,OAAO,UAAU,GAC1B,SAAS,MAAM,CAChB,CAAC;CAED,OAAO,KAAK,MAAM,UAAU,SAAS,OAAO,CAAC;AAC9C;;;;;;;;;;;;;;;;;;;;;;;;;;AA2BA,MAAa,qBAA6C;CAIzD,MAAM,WAAY,WAChB;CACF,IAAI,UACH,OAAO;CAIR,IACC,OAAO,kCAAkC,eACzC,OAAO,2BAA2B,aAElC,OAAO,CAAC;CAIT,MAAM,YAAY,QAAQ,IAAI;CAE9B,IAAI,CAAC,WAAW;EAEf,QAAQ,MACP,+EACD;EACA,QAAQ,MACP,2EACD;EACA,OAAO,CAAC;CACT;CAEA,IAAI;EACH,OAAO,mBACN,+BACA,wBACA,SACD;CACD,SAAS,OAAO;EACf,QAAQ,MAAM,wCAAwC,KAAK;EAC3D,QAAQ,MAAM,8CAA8C;EAC5D,OAAO,CAAC;CACT;AACD,EAAA,CAAG"}
@@ -3,7 +3,7 @@
3
3
  * Decrypt credentials from encrypted payload.
4
4
  * Exported for testing purposes.
5
5
  */
6
- declare function decryptCredentials(encrypted: string, iv: string, masterKey: string): Record<string, string>;
6
+ export declare function decryptCredentials(encrypted: string, iv: string, masterKey: string): Record<string, string>;
7
7
  /**
8
8
  * Credentials object for use with EnvironmentParser.
9
9
  *
@@ -29,7 +29,7 @@ declare function decryptCredentials(encrypted: string, iv: string, masterKey: st
29
29
  * .parse();
30
30
  * ```
31
31
  */
32
- declare const Credentials: Record<string, string>;
32
+ export declare const Credentials: Record<string, string>;
33
33
  //#endregion
34
- export { Credentials, Credentials as default, decryptCredentials };
34
+ export { Credentials as default };
35
35
  //# sourceMappingURL=credentials.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"credentials.d.cts","names":[],"sources":["../src/credentials.ts"],"sourcesContent":[],"mappings":";;AAgBA;AAkDA;;iBAlDgB,kBAAA,oDAIb;;;;;;;;;;;;;;;;;;;;;;;;;;cA8CU,aAAa"}
1
+ {"version":3,"file":"credentials.d.cts","names":[],"sources":["../src/credentials.ts"],"mappings":";;;;;wBAgBgB,mBACf,mBACA,YACA,oBACE;;;;;;;;;;;;;;;;;;;;;;;;;;qBA8CU,aAAa"}
@@ -3,7 +3,7 @@
3
3
  * Decrypt credentials from encrypted payload.
4
4
  * Exported for testing purposes.
5
5
  */
6
- declare function decryptCredentials(encrypted: string, iv: string, masterKey: string): Record<string, string>;
6
+ export declare function decryptCredentials(encrypted: string, iv: string, masterKey: string): Record<string, string>;
7
7
  /**
8
8
  * Credentials object for use with EnvironmentParser.
9
9
  *
@@ -29,7 +29,7 @@ declare function decryptCredentials(encrypted: string, iv: string, masterKey: st
29
29
  * .parse();
30
30
  * ```
31
31
  */
32
- declare const Credentials: Record<string, string>;
32
+ export declare const Credentials: Record<string, string>;
33
33
  //#endregion
34
- export { Credentials, Credentials as default, decryptCredentials };
34
+ export { Credentials as default };
35
35
  //# sourceMappingURL=credentials.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"credentials.d.mts","names":[],"sources":["../src/credentials.ts"],"sourcesContent":[],"mappings":";;AAgBA;AAkDA;;iBAlDgB,kBAAA,oDAIb;;;;;;;;;;;;;;;;;;;;;;;;;;cA8CU,aAAa"}
1
+ {"version":3,"file":"credentials.d.mts","names":[],"sources":["../src/credentials.ts"],"mappings":";;;;;wBAgBgB,mBACf,mBACA,YACA,oBACE;;;;;;;;;;;;;;;;;;;;;;;;;;qBA8CU,aAAa"}
@@ -1,8 +1,5 @@
1
1
  import { createDecipheriv } from "node:crypto";
2
-
3
2
  //#region src/credentials.ts
4
- /** AES-256-GCM auth tag length */
5
- const AUTH_TAG_LENGTH = 16;
6
3
  /**
7
4
  * Decrypt credentials from encrypted payload.
8
5
  * Exported for testing purposes.
@@ -11,8 +8,8 @@ function decryptCredentials(encrypted, iv, masterKey) {
11
8
  const key = Buffer.from(masterKey, "hex");
12
9
  const ivBuffer = Buffer.from(iv, "hex");
13
10
  const combined = Buffer.from(encrypted, "base64");
14
- const ciphertext = combined.subarray(0, -AUTH_TAG_LENGTH);
15
- const authTag = combined.subarray(-AUTH_TAG_LENGTH);
11
+ const ciphertext = combined.subarray(0, -16);
12
+ const authTag = combined.subarray(-16);
16
13
  const decipher = createDecipheriv("aes-256-gcm", key, ivBuffer);
17
14
  decipher.setAuthTag(authTag);
18
15
  const plaintext = Buffer.concat([decipher.update(ciphertext), decipher.final()]);
@@ -61,8 +58,7 @@ const Credentials = (() => {
61
58
  return {};
62
59
  }
63
60
  })();
64
- var credentials_default = Credentials;
65
-
66
61
  //#endregion
67
- export { Credentials, decryptCredentials, credentials_default as default };
62
+ export { Credentials, Credentials as default, decryptCredentials };
63
+
68
64
  //# sourceMappingURL=credentials.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"credentials.mjs","names":["encrypted: string","iv: string","masterKey: string","Credentials: Record<string, string>"],"sources":["../src/credentials.ts"],"sourcesContent":["import { createDecipheriv } from 'node:crypto';\n\n/**\n * Build-time injected encrypted credentials.\n * These are replaced by tsdown/esbuild --define at build time.\n */\ndeclare const __GKM_ENCRYPTED_CREDENTIALS__: string | undefined;\ndeclare const __GKM_CREDENTIALS_IV__: string | undefined;\n\n/** AES-256-GCM auth tag length */\nconst AUTH_TAG_LENGTH = 16;\n\n/**\n * Decrypt credentials from encrypted payload.\n * Exported for testing purposes.\n */\nexport function decryptCredentials(\n\tencrypted: string,\n\tiv: string,\n\tmasterKey: string,\n): Record<string, string> {\n\tconst key = Buffer.from(masterKey, 'hex');\n\tconst ivBuffer = Buffer.from(iv, 'hex');\n\tconst combined = Buffer.from(encrypted, 'base64');\n\n\t// Split ciphertext and auth tag\n\tconst ciphertext = combined.subarray(0, -AUTH_TAG_LENGTH);\n\tconst authTag = combined.subarray(-AUTH_TAG_LENGTH);\n\n\t// Decrypt using AES-256-GCM\n\tconst decipher = createDecipheriv('aes-256-gcm', key, ivBuffer);\n\tdecipher.setAuthTag(authTag);\n\n\tconst plaintext = Buffer.concat([\n\t\tdecipher.update(ciphertext),\n\t\tdecipher.final(),\n\t]);\n\n\treturn JSON.parse(plaintext.toString('utf-8'));\n}\n\n/**\n * Credentials object for use with EnvironmentParser.\n *\n * Resolution order:\n * 1. **Dev mode (gkm dev/exec)**: Checks `globalThis.__gkm_credentials__` for\n * credentials injected by the CLI preload script. This approach survives\n * CJS/ESM module duplication (where mutating the export would only affect one copy).\n * 2. **Production mode**: Decrypts build-time embedded credentials using the\n * `GKM_MASTER_KEY` environment variable (AES-256-GCM).\n * 3. **Fallback**: Returns empty object (allows graceful fallback to process.env).\n *\n * @example\n * ```typescript\n * import { EnvironmentParser } from '@geekmidas/envkit';\n * import { Credentials } from '@geekmidas/envkit/credentials';\n *\n * export const envParser = new EnvironmentParser({...process.env, ...Credentials})\n * .create((get) => ({\n * database: {\n * url: get('DATABASE_URL').string(),\n * },\n * }))\n * .parse();\n * ```\n */\nexport const Credentials: Record<string, string> = (() => {\n\t// Dev mode: check if gkm exec/dev preload injected credentials via globalThis\n\t// This survives CJS/ESM module duplication where Object.assign on the\n\t// export would only mutate one copy of the module's Credentials object.\n\tconst injected = (globalThis as Record<string, unknown>)\n\t\t.__gkm_credentials__ as Record<string, string> | undefined;\n\tif (injected) {\n\t\treturn injected;\n\t}\n\n\t// Development mode - no credentials embedded at build time\n\tif (\n\t\ttypeof __GKM_ENCRYPTED_CREDENTIALS__ === 'undefined' ||\n\t\ttypeof __GKM_CREDENTIALS_IV__ === 'undefined'\n\t) {\n\t\treturn {};\n\t}\n\n\t// Production mode - decrypt credentials using master key\n\tconst masterKey = process.env.GKM_MASTER_KEY;\n\n\tif (!masterKey) {\n\t\t// Log warning but don't throw - allows graceful fallback to env vars\n\t\tconsole.error(\n\t\t\t'[gkm] GKM_MASTER_KEY environment variable is required to decrypt credentials.',\n\t\t);\n\t\tconsole.error(\n\t\t\t'[gkm] Falling back to environment variables. Some secrets may be missing.',\n\t\t);\n\t\treturn {};\n\t}\n\n\ttry {\n\t\treturn decryptCredentials(\n\t\t\t__GKM_ENCRYPTED_CREDENTIALS__,\n\t\t\t__GKM_CREDENTIALS_IV__,\n\t\t\tmasterKey,\n\t\t);\n\t} catch (error) {\n\t\tconsole.error('[gkm] Failed to decrypt credentials:', error);\n\t\tconsole.error('[gkm] Falling back to environment variables.');\n\t\treturn {};\n\t}\n})();\n\nexport default Credentials;\n"],"mappings":";;;;AAUA,MAAM,kBAAkB;;;;;AAMxB,SAAgB,mBACfA,WACAC,IACAC,WACyB;CACzB,MAAM,MAAM,OAAO,KAAK,WAAW,MAAM;CACzC,MAAM,WAAW,OAAO,KAAK,IAAI,MAAM;CACvC,MAAM,WAAW,OAAO,KAAK,WAAW,SAAS;CAGjD,MAAM,aAAa,SAAS,SAAS,IAAI,gBAAgB;CACzD,MAAM,UAAU,SAAS,UAAU,gBAAgB;CAGnD,MAAM,WAAW,iBAAiB,eAAe,KAAK,SAAS;AAC/D,UAAS,WAAW,QAAQ;CAE5B,MAAM,YAAY,OAAO,OAAO,CAC/B,SAAS,OAAO,WAAW,EAC3B,SAAS,OAAO,AAChB,EAAC;AAEF,QAAO,KAAK,MAAM,UAAU,SAAS,QAAQ,CAAC;AAC9C;;;;;;;;;;;;;;;;;;;;;;;;;;AA2BD,MAAaC,cAAsC,CAAC,MAAM;CAIzD,MAAM,WAAY,WAChB;AACF,KAAI,SACH,QAAO;AAIR,YACQ,kCAAkC,sBAClC,2BAA2B,YAElC,QAAO,CAAE;CAIV,MAAM,YAAY,QAAQ,IAAI;AAE9B,MAAK,WAAW;AAEf,UAAQ,MACP,gFACA;AACD,UAAQ,MACP,4EACA;AACD,SAAO,CAAE;CACT;AAED,KAAI;AACH,SAAO,mBACN,+BACA,wBACA,UACA;CACD,SAAQ,OAAO;AACf,UAAQ,MAAM,wCAAwC,MAAM;AAC5D,UAAQ,MAAM,+CAA+C;AAC7D,SAAO,CAAE;CACT;AACD,IAAG;AAEJ,0BAAe"}
1
+ {"version":3,"file":"credentials.mjs","names":[],"sources":["../src/credentials.ts"],"sourcesContent":["import { createDecipheriv } from 'node:crypto';\n\n/**\n * Build-time injected encrypted credentials.\n * These are replaced by tsdown/esbuild --define at build time.\n */\ndeclare const __GKM_ENCRYPTED_CREDENTIALS__: string | undefined;\ndeclare const __GKM_CREDENTIALS_IV__: string | undefined;\n\n/** AES-256-GCM auth tag length */\nconst AUTH_TAG_LENGTH = 16;\n\n/**\n * Decrypt credentials from encrypted payload.\n * Exported for testing purposes.\n */\nexport function decryptCredentials(\n\tencrypted: string,\n\tiv: string,\n\tmasterKey: string,\n): Record<string, string> {\n\tconst key = Buffer.from(masterKey, 'hex');\n\tconst ivBuffer = Buffer.from(iv, 'hex');\n\tconst combined = Buffer.from(encrypted, 'base64');\n\n\t// Split ciphertext and auth tag\n\tconst ciphertext = combined.subarray(0, -AUTH_TAG_LENGTH);\n\tconst authTag = combined.subarray(-AUTH_TAG_LENGTH);\n\n\t// Decrypt using AES-256-GCM\n\tconst decipher = createDecipheriv('aes-256-gcm', key, ivBuffer);\n\tdecipher.setAuthTag(authTag);\n\n\tconst plaintext = Buffer.concat([\n\t\tdecipher.update(ciphertext),\n\t\tdecipher.final(),\n\t]);\n\n\treturn JSON.parse(plaintext.toString('utf-8'));\n}\n\n/**\n * Credentials object for use with EnvironmentParser.\n *\n * Resolution order:\n * 1. **Dev mode (gkm dev/exec)**: Checks `globalThis.__gkm_credentials__` for\n * credentials injected by the CLI preload script. This approach survives\n * CJS/ESM module duplication (where mutating the export would only affect one copy).\n * 2. **Production mode**: Decrypts build-time embedded credentials using the\n * `GKM_MASTER_KEY` environment variable (AES-256-GCM).\n * 3. **Fallback**: Returns empty object (allows graceful fallback to process.env).\n *\n * @example\n * ```typescript\n * import { EnvironmentParser } from '@geekmidas/envkit';\n * import { Credentials } from '@geekmidas/envkit/credentials';\n *\n * export const envParser = new EnvironmentParser({...process.env, ...Credentials})\n * .create((get) => ({\n * database: {\n * url: get('DATABASE_URL').string(),\n * },\n * }))\n * .parse();\n * ```\n */\nexport const Credentials: Record<string, string> = (() => {\n\t// Dev mode: check if gkm exec/dev preload injected credentials via globalThis\n\t// This survives CJS/ESM module duplication where Object.assign on the\n\t// export would only mutate one copy of the module's Credentials object.\n\tconst injected = (globalThis as Record<string, unknown>)\n\t\t.__gkm_credentials__ as Record<string, string> | undefined;\n\tif (injected) {\n\t\treturn injected;\n\t}\n\n\t// Development mode - no credentials embedded at build time\n\tif (\n\t\ttypeof __GKM_ENCRYPTED_CREDENTIALS__ === 'undefined' ||\n\t\ttypeof __GKM_CREDENTIALS_IV__ === 'undefined'\n\t) {\n\t\treturn {};\n\t}\n\n\t// Production mode - decrypt credentials using master key\n\tconst masterKey = process.env.GKM_MASTER_KEY;\n\n\tif (!masterKey) {\n\t\t// Log warning but don't throw - allows graceful fallback to env vars\n\t\tconsole.error(\n\t\t\t'[gkm] GKM_MASTER_KEY environment variable is required to decrypt credentials.',\n\t\t);\n\t\tconsole.error(\n\t\t\t'[gkm] Falling back to environment variables. Some secrets may be missing.',\n\t\t);\n\t\treturn {};\n\t}\n\n\ttry {\n\t\treturn decryptCredentials(\n\t\t\t__GKM_ENCRYPTED_CREDENTIALS__,\n\t\t\t__GKM_CREDENTIALS_IV__,\n\t\t\tmasterKey,\n\t\t);\n\t} catch (error) {\n\t\tconsole.error('[gkm] Failed to decrypt credentials:', error);\n\t\tconsole.error('[gkm] Falling back to environment variables.');\n\t\treturn {};\n\t}\n})();\n\nexport default Credentials;\n"],"mappings":";;;;;;AAgBA,SAAgB,mBACf,WACA,IACA,WACyB;CACzB,MAAM,MAAM,OAAO,KAAK,WAAW,KAAK;CACxC,MAAM,WAAW,OAAO,KAAK,IAAI,KAAK;CACtC,MAAM,WAAW,OAAO,KAAK,WAAW,QAAQ;CAGhD,MAAM,aAAa,SAAS,SAAS,GAAG,GAAgB;CACxD,MAAM,UAAU,SAAS,SAAS,GAAgB;CAGlD,MAAM,WAAW,iBAAiB,eAAe,KAAK,QAAQ;CAC9D,SAAS,WAAW,OAAO;CAE3B,MAAM,YAAY,OAAO,OAAO,CAC/B,SAAS,OAAO,UAAU,GAC1B,SAAS,MAAM,CAChB,CAAC;CAED,OAAO,KAAK,MAAM,UAAU,SAAS,OAAO,CAAC;AAC9C;;;;;;;;;;;;;;;;;;;;;;;;;;AA2BA,MAAa,qBAA6C;CAIzD,MAAM,WAAY,WAChB;CACF,IAAI,UACH,OAAO;CAIR,IACC,OAAO,kCAAkC,eACzC,OAAO,2BAA2B,aAElC,OAAO,CAAC;CAIT,MAAM,YAAY,QAAQ,IAAI;CAE9B,IAAI,CAAC,WAAW;EAEf,QAAQ,MACP,+EACD;EACA,QAAQ,MACP,2EACD;EACA,OAAO,CAAC;CACT;CAEA,IAAI;EACH,OAAO,mBACN,+BACA,wBACA,SACD;CACD,SAAS,OAAO;EACf,QAAQ,MAAM,wCAAwC,KAAK;EAC3D,QAAQ,MAAM,8CAA8C;EAC5D,OAAO,CAAC;CACT;AACD,EAAA,CAAG"}
package/dist/index.cjs CHANGED
@@ -1,9 +1,9 @@
1
- const require_EnvironmentParser = require('./EnvironmentParser-Bzg5yXG2.cjs');
2
- const require_EnvironmentBuilder = require('./EnvironmentBuilder-15SdFJdK.cjs');
3
-
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ const require_EnvironmentBuilder = require("./EnvironmentBuilder-wJH3EBbJ.cjs");
3
+ const require_EnvironmentParser = require("./EnvironmentParser-CmhDxs77.cjs");
4
4
  exports.ConfigParser = require_EnvironmentParser.ConfigParser;
5
5
  exports.EnvironmentBuilder = require_EnvironmentBuilder.EnvironmentBuilder;
6
6
  exports.EnvironmentParser = require_EnvironmentParser.EnvironmentParser;
7
7
  exports.environmentCase = require_EnvironmentBuilder.environmentCase;
8
8
  exports.formatParseError = require_EnvironmentParser.formatParseError;
9
- exports.isDevelopment = require_EnvironmentParser.isDevelopment;
9
+ exports.isDevelopment = require_EnvironmentParser.isDevelopment;
package/dist/index.d.cts CHANGED
@@ -1,7 +1,6 @@
1
- import { ConfigParser, EmptyObject, EnvFetcher, EnvironmentParser, InferConfig } from "./EnvironmentParser-DoooZm8n.cjs";
2
- import { EnvRecord, EnvValue, EnvironmentBuilder, EnvironmentBuilderOptions, EnvironmentResolver, InputValue, Resolvers, TypedInputValue, TypedResolvers, environmentCase } from "./EnvironmentBuilder-DeIle4QN.cjs";
1
+ import { a as InferConfig, i as EnvironmentParser, n as EmptyObject, r as EnvFetcher, t as ConfigParser } from "./EnvironmentParser-BmJLlm5_.cjs";
2
+ import { a as EnvironmentResolver, c as TypedInputValue, i as EnvironmentBuilderOptions, l as TypedResolvers, n as EnvValue, o as InputValue, r as EnvironmentBuilder, s as Resolvers, t as EnvRecord, u as environmentCase } from "./EnvironmentBuilder-DTZ8o3se.cjs";
3
3
  import { z } from "zod/v4";
4
-
5
4
  //#region src/formatter.d.ts
6
5
  /**
7
6
  * Options for formatting parse errors.
@@ -41,12 +40,11 @@ interface FormatOptions {
41
40
  * Expected: "development" | "staging" | "production"
42
41
  * ```
43
42
  */
44
- declare function formatParseError(error: z.ZodError, options?: FormatOptions): string;
43
+ export declare function formatParseError(error: z.ZodError, options?: FormatOptions): string;
45
44
  /**
46
45
  * Checks if the current environment is development.
47
46
  */
48
- declare function isDevelopment(): boolean;
49
- //# sourceMappingURL=formatter.d.ts.map
47
+ export declare function isDevelopment(): boolean;
50
48
  //#endregion
51
- export { ConfigParser, EmptyObject, EnvFetcher, EnvRecord, EnvValue, EnvironmentBuilder, EnvironmentBuilderOptions, EnvironmentParser, EnvironmentResolver, FormatOptions, InferConfig, InputValue, Resolvers, TypedInputValue, TypedResolvers, environmentCase, formatParseError, isDevelopment };
49
+ export { ConfigParser, type EmptyObject, type EnvFetcher, type EnvRecord, type EnvValue, EnvironmentBuilder, type EnvironmentBuilderOptions, EnvironmentParser, type EnvironmentResolver, type FormatOptions, type InferConfig, type InputValue, type Resolvers, type TypedInputValue, type TypedResolvers, environmentCase };
52
50
  //# sourceMappingURL=index.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.cts","names":[],"sources":["../src/formatter.ts"],"sourcesContent":[],"mappings":";;;;;;;;UAKiB,aAAA;EAAA;EAgDD,MAAA,CAAA,EAAA,OAAA;;;;AAEY;AAuF5B;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAzFgB,gBAAA,QACR,CAAA,CAAE,oBACA;;;;iBAuFM,aAAA,CAAA"}
1
+ {"version":3,"file":"index.d.cts","names":[],"sources":["../src/formatter.ts"],"mappings":";;;;;;;UAKiB;;EAEhB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;wBA8Ce,iBACf,OAAO,EAAE,UACT,UAAS;;;;wBAuFM"}
package/dist/index.d.mts CHANGED
@@ -1,7 +1,6 @@
1
- import { ConfigParser, EmptyObject, EnvFetcher, EnvironmentParser, InferConfig } from "./EnvironmentParser-BY1oCUsc.mjs";
2
- import { EnvRecord, EnvValue, EnvironmentBuilder, EnvironmentBuilderOptions, EnvironmentResolver, InputValue, Resolvers, TypedInputValue, TypedResolvers, environmentCase } from "./EnvironmentBuilder-CoBQ9Xp2.mjs";
1
+ import { a as InferConfig, i as EnvironmentParser, n as EmptyObject, r as EnvFetcher, t as ConfigParser } from "./EnvironmentParser-BmJLlm5_.mjs";
2
+ import { a as EnvironmentResolver, c as TypedInputValue, i as EnvironmentBuilderOptions, l as TypedResolvers, n as EnvValue, o as InputValue, r as EnvironmentBuilder, s as Resolvers, t as EnvRecord, u as environmentCase } from "./EnvironmentBuilder-DTZ8o3se.mjs";
3
3
  import { z } from "zod/v4";
4
-
5
4
  //#region src/formatter.d.ts
6
5
  /**
7
6
  * Options for formatting parse errors.
@@ -41,12 +40,11 @@ interface FormatOptions {
41
40
  * Expected: "development" | "staging" | "production"
42
41
  * ```
43
42
  */
44
- declare function formatParseError(error: z.ZodError, options?: FormatOptions): string;
43
+ export declare function formatParseError(error: z.ZodError, options?: FormatOptions): string;
45
44
  /**
46
45
  * Checks if the current environment is development.
47
46
  */
48
- declare function isDevelopment(): boolean;
49
- //# sourceMappingURL=formatter.d.ts.map
47
+ export declare function isDevelopment(): boolean;
50
48
  //#endregion
51
- export { ConfigParser, EmptyObject, EnvFetcher, EnvRecord, EnvValue, EnvironmentBuilder, EnvironmentBuilderOptions, EnvironmentParser, EnvironmentResolver, FormatOptions, InferConfig, InputValue, Resolvers, TypedInputValue, TypedResolvers, environmentCase, formatParseError, isDevelopment };
49
+ export { ConfigParser, type EmptyObject, type EnvFetcher, type EnvRecord, type EnvValue, EnvironmentBuilder, type EnvironmentBuilderOptions, EnvironmentParser, type EnvironmentResolver, type FormatOptions, type InferConfig, type InputValue, type Resolvers, type TypedInputValue, type TypedResolvers, environmentCase };
52
50
  //# sourceMappingURL=index.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../src/formatter.ts"],"sourcesContent":[],"mappings":";;;;;;;;UAKiB,aAAA;EAAA;EAgDD,MAAA,CAAA,EAAA,OAAA;;;;AAEY;AAuF5B;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAzFgB,gBAAA,QACR,CAAA,CAAE,oBACA;;;;iBAuFM,aAAA,CAAA"}
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../src/formatter.ts"],"mappings":";;;;;;;UAKiB;;EAEhB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;wBA8Ce,iBACf,OAAO,EAAE,UACT,UAAS;;;;wBAuFM"}
package/dist/index.mjs CHANGED
@@ -1,4 +1,3 @@
1
- import { ConfigParser, EnvironmentParser, formatParseError, isDevelopment } from "./EnvironmentParser-taAKfzT7.mjs";
2
- import { EnvironmentBuilder, environmentCase } from "./EnvironmentBuilder-C-2fViCT.mjs";
3
-
4
- export { ConfigParser, EnvironmentBuilder, EnvironmentParser, environmentCase, formatParseError, isDevelopment };
1
+ import { n as environmentCase, t as EnvironmentBuilder } from "./EnvironmentBuilder-Rxq657gm.mjs";
2
+ import { i as isDevelopment, n as EnvironmentParser, r as formatParseError, t as ConfigParser } from "./EnvironmentParser-X6Z-jryw.mjs";
3
+ export { ConfigParser, EnvironmentBuilder, EnvironmentParser, environmentCase, formatParseError, isDevelopment };
@@ -1,4 +1,4 @@
1
- //#region rolldown:runtime
1
+ //#region \0rolldown/runtime.js
2
2
  var __create = Object.create;
3
3
  var __defProp = Object.defineProperty;
4
4
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
@@ -15,16 +15,14 @@ var __copyProps = (to, from, except, desc) => {
15
15
  }
16
16
  return to;
17
17
  };
18
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
18
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule || !__hasOwnProp.call(mod, "default") ? __defProp(target, "default", {
19
19
  value: mod,
20
20
  enumerable: true
21
21
  }) : target, mod));
22
-
23
22
  //#endregion
24
-
25
- Object.defineProperty(exports, '__toESM', {
26
- enumerable: true,
27
- get: function () {
28
- return __toESM;
29
- }
30
- });
23
+ Object.defineProperty(exports, "__toESM", {
24
+ enumerable: true,
25
+ get: function() {
26
+ return __toESM;
27
+ }
28
+ });