@geekmidas/envkit 10.0.0-alpha.11 → 10.0.0-alpha.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{EnvironmentBuilder-CoBQ9Xp2.d.mts → EnvironmentBuilder-DTZ8o3se.d.cts} +5 -5
- package/dist/EnvironmentBuilder-DTZ8o3se.d.cts.map +1 -0
- package/dist/{EnvironmentBuilder-DeIle4QN.d.cts → EnvironmentBuilder-DTZ8o3se.d.mts} +5 -5
- package/dist/EnvironmentBuilder-DTZ8o3se.d.mts.map +1 -0
- package/dist/{EnvironmentBuilder-C-2fViCT.mjs → EnvironmentBuilder-Rxq657gm.mjs} +4 -5
- package/dist/EnvironmentBuilder-Rxq657gm.mjs.map +1 -0
- package/dist/{EnvironmentBuilder-15SdFJdK.cjs → EnvironmentBuilder-wJH3EBbJ.cjs} +16 -16
- package/dist/EnvironmentBuilder-wJH3EBbJ.cjs.map +1 -0
- package/dist/{EnvironmentParser-DoooZm8n.d.cts → EnvironmentParser-BmJLlm5_.d.cts} +3 -15
- package/dist/EnvironmentParser-BmJLlm5_.d.cts.map +1 -0
- package/dist/{EnvironmentParser-BY1oCUsc.d.mts → EnvironmentParser-BmJLlm5_.d.mts} +3 -15
- package/dist/EnvironmentParser-BmJLlm5_.d.mts.map +1 -0
- package/dist/{EnvironmentParser-Bzg5yXG2.cjs → EnvironmentParser-CmhDxs77.cjs} +34 -34
- package/dist/EnvironmentParser-CmhDxs77.cjs.map +1 -0
- package/dist/{EnvironmentParser-taAKfzT7.mjs → EnvironmentParser-X6Z-jryw.mjs} +10 -12
- package/dist/EnvironmentParser-X6Z-jryw.mjs.map +1 -0
- package/dist/SnifferEnvironmentParser.cjs +5 -7
- package/dist/SnifferEnvironmentParser.cjs.map +1 -1
- package/dist/SnifferEnvironmentParser.d.cts +5 -9
- package/dist/SnifferEnvironmentParser.d.cts.map +1 -1
- package/dist/SnifferEnvironmentParser.d.mts +5 -9
- package/dist/SnifferEnvironmentParser.d.mts.map +1 -1
- package/dist/SnifferEnvironmentParser.mjs +3 -5
- package/dist/SnifferEnvironmentParser.mjs.map +1 -1
- package/dist/credentials.cjs +9 -11
- package/dist/credentials.cjs.map +1 -1
- package/dist/credentials.d.cts +3 -3
- package/dist/credentials.d.cts.map +1 -1
- package/dist/credentials.d.mts +3 -3
- package/dist/credentials.d.mts.map +1 -1
- package/dist/credentials.mjs +4 -8
- package/dist/credentials.mjs.map +1 -1
- package/dist/index.cjs +4 -4
- package/dist/index.d.cts +5 -7
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +5 -7
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +3 -4
- package/dist/{chunk-CUT6urMc.cjs → rolldown-runtime-VH7oDXx4.cjs} +8 -10
- package/dist/sst.cjs +43 -51
- package/dist/sst.cjs.map +1 -1
- package/dist/sst.d.cts +19 -24
- package/dist/sst.d.cts.map +1 -1
- package/dist/sst.d.mts +19 -24
- package/dist/sst.d.mts.map +1 -1
- package/dist/sst.mjs +42 -51
- package/dist/sst.mjs.map +1 -1
- package/package.json +1 -1
- package/dist/EnvironmentBuilder-15SdFJdK.cjs.map +0 -1
- package/dist/EnvironmentBuilder-C-2fViCT.mjs.map +0 -1
- package/dist/EnvironmentBuilder-CoBQ9Xp2.d.mts.map +0 -1
- package/dist/EnvironmentBuilder-DeIle4QN.d.cts.map +0 -1
- package/dist/EnvironmentParser-BY1oCUsc.d.mts.map +0 -1
- package/dist/EnvironmentParser-Bzg5yXG2.cjs.map +0 -1
- package/dist/EnvironmentParser-DoooZm8n.d.cts.map +0 -1
- 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 {
|
|
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"],"
|
|
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 {
|
|
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"],"
|
|
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-
|
|
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
|
-
|
|
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":"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"}
|
|
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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"}
|
package/dist/credentials.cjs
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
Object.
|
|
2
|
-
|
|
3
|
-
|
|
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, -
|
|
17
|
-
const authTag = combined.subarray(-
|
|
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
|
-
|
|
69
|
+
|
|
72
70
|
//# sourceMappingURL=credentials.cjs.map
|
package/dist/credentials.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"credentials.cjs","names":["
|
|
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"}
|
package/dist/credentials.d.cts
CHANGED
|
@@ -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
|
|
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"],"
|
|
1
|
+
{"version":3,"file":"credentials.d.cts","names":[],"sources":["../src/credentials.ts"],"mappings":";;;;;wBAgBgB,mBACf,mBACA,YACA,oBACE;;;;;;;;;;;;;;;;;;;;;;;;;;qBA8CU,aAAa"}
|
package/dist/credentials.d.mts
CHANGED
|
@@ -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
|
|
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"],"
|
|
1
|
+
{"version":3,"file":"credentials.d.mts","names":[],"sources":["../src/credentials.ts"],"mappings":";;;;;wBAgBgB,mBACf,mBACA,YACA,oBACE;;;;;;;;;;;;;;;;;;;;;;;;;;qBA8CU,aAAa"}
|
package/dist/credentials.mjs
CHANGED
|
@@ -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, -
|
|
15
|
-
const authTag = combined.subarray(-
|
|
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,
|
|
62
|
+
export { Credentials, Credentials as default, decryptCredentials };
|
|
63
|
+
|
|
68
64
|
//# sourceMappingURL=credentials.mjs.map
|
package/dist/credentials.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"credentials.mjs","names":[
|
|
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
|
-
|
|
2
|
-
const require_EnvironmentBuilder = require(
|
|
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 {
|
|
2
|
-
import {
|
|
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
|
|
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
|
package/dist/index.d.cts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.cts","names":[],"sources":["../src/formatter.ts"],"
|
|
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 {
|
|
2
|
-
import {
|
|
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
|
|
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
|
package/dist/index.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/formatter.ts"],"
|
|
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 {
|
|
2
|
-
import {
|
|
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
|
|
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
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
});
|
|
23
|
+
Object.defineProperty(exports, "__toESM", {
|
|
24
|
+
enumerable: true,
|
|
25
|
+
get: function() {
|
|
26
|
+
return __toESM;
|
|
27
|
+
}
|
|
28
|
+
});
|