envapt 8.2.0 → 8.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -15
- package/dist/node/config.cjs.map +1 -1
- package/dist/node/config.mjs.map +1 -1
- package/dist/node/converters/BuiltInConverters.cjs.map +1 -1
- package/dist/node/converters/BuiltInConverters.mjs.map +1 -1
- package/dist/node/converters/Converters.cjs.map +1 -1
- package/dist/node/converters/Converters.mjs.map +1 -1
- package/dist/node/converters/ListOfBuiltInConverters.cjs.map +1 -1
- package/dist/node/converters/ListOfBuiltInConverters.mjs.map +1 -1
- package/dist/node/converters/ValueConverter.cjs.map +1 -1
- package/dist/node/converters/ValueConverter.mjs.map +1 -1
- package/dist/node/core/AdvancedMethods.cjs.map +1 -1
- package/dist/node/core/AdvancedMethods.mjs.map +1 -1
- package/dist/node/core/EnvapterBase.cjs.map +1 -1
- package/dist/node/core/EnvapterBase.mjs.map +1 -1
- package/dist/node/core/EnvironmentMethods.cjs.map +1 -1
- package/dist/node/core/EnvironmentMethods.mjs.map +1 -1
- package/dist/node/core/PrimitiveMethods.cjs.map +1 -1
- package/dist/node/core/PrimitiveMethods.mjs.map +1 -1
- package/dist/node/core/engine.cjs.map +1 -1
- package/dist/node/core/engine.mjs.map +1 -1
- package/dist/node/core/missing.cjs.map +1 -1
- package/dist/node/core/missing.mjs.map +1 -1
- package/dist/node/core/paths.cjs.map +1 -1
- package/dist/node/core/paths.mjs.map +1 -1
- package/dist/node/core/state.cjs.map +1 -1
- package/dist/node/core/state.mjs.map +1 -1
- package/dist/node/decorators/legacy/Envapt.cjs.map +1 -1
- package/dist/node/decorators/legacy/Envapt.mjs.map +1 -1
- package/dist/node/decorators/legacy/SugarDecorators.cjs.map +1 -1
- package/dist/node/decorators/legacy/SugarDecorators.mjs.map +1 -1
- package/dist/node/decorators/modern/Envapt.cjs.map +1 -1
- package/dist/node/decorators/modern/Envapt.mjs.map +1 -1
- package/dist/node/decorators/modern/SugarDecorators.cjs.map +1 -1
- package/dist/node/decorators/modern/SugarDecorators.mjs.map +1 -1
- package/dist/node/decorators/modern/createAccessorDecorator.cjs.map +1 -1
- package/dist/node/decorators/modern/createAccessorDecorator.mjs.map +1 -1
- package/dist/node/decorators/resolveDecoratorValue.cjs.map +1 -1
- package/dist/node/decorators/resolveDecoratorValue.mjs.map +1 -1
- package/dist/node/engine/Envapter.cjs.map +1 -1
- package/dist/node/engine/Envapter.mjs.map +1 -1
- package/dist/node/engine/NodeEnvapter.cjs.map +1 -1
- package/dist/node/engine/NodeEnvapter.mjs.map +1 -1
- package/dist/node/engine/TemplateResolver.cjs.map +1 -1
- package/dist/node/engine/TemplateResolver.mjs.map +1 -1
- package/dist/node/engine/Validators.cjs.map +1 -1
- package/dist/node/engine/Validators.mjs.map +1 -1
- package/dist/node/infra/Debug.cjs.map +1 -1
- package/dist/node/infra/Debug.mjs.map +1 -1
- package/dist/node/infra/Dotenv.cjs.map +1 -1
- package/dist/node/infra/Dotenv.mjs.map +1 -1
- package/dist/node/infra/Error.cjs.map +1 -1
- package/dist/node/infra/Error.mjs.map +1 -1
- package/dist/node/infra/recase.cjs.map +1 -1
- package/dist/node/infra/recase.mjs.map +1 -1
- package/dist/node/infra/runtime.cjs.map +1 -1
- package/dist/node/infra/runtime.mjs.map +1 -1
- package/dist/node/sources/FileSource.cjs.map +1 -1
- package/dist/node/sources/FileSource.mjs.map +1 -1
- package/dist/node/sources/PortableSource.cjs.map +1 -1
- package/dist/node/sources/PortableSource.mjs.map +1 -1
- package/dist/node/sources/UnboundSource.cjs.map +1 -1
- package/dist/node/sources/UnboundSource.mjs.map +1 -1
- package/dist/node/sources/coerce.cjs.map +1 -1
- package/dist/node/sources/coerce.mjs.map +1 -1
- package/dist/node/sources/merge.cjs.map +1 -1
- package/dist/node/sources/merge.mjs.map +1 -1
- package/dist/portable/converters/BuiltInConverters.mjs.map +1 -1
- package/dist/portable/converters/Converters.mjs.map +1 -1
- package/dist/portable/converters/ListOfBuiltInConverters.mjs.map +1 -1
- package/dist/portable/converters/ValueConverter.mjs.map +1 -1
- package/dist/portable/core/AdvancedMethods.mjs.map +1 -1
- package/dist/portable/core/EnvapterBase.mjs.map +1 -1
- package/dist/portable/core/EnvironmentMethods.mjs.map +1 -1
- package/dist/portable/core/PrimitiveMethods.mjs.map +1 -1
- package/dist/portable/core/engine.mjs.map +1 -1
- package/dist/portable/core/missing.mjs.map +1 -1
- package/dist/portable/core/paths.mjs.map +1 -1
- package/dist/portable/core/state.mjs.map +1 -1
- package/dist/portable/decorators/legacy/Envapt.mjs.map +1 -1
- package/dist/portable/decorators/legacy/SugarDecorators.mjs.map +1 -1
- package/dist/portable/decorators/modern/Envapt.mjs.map +1 -1
- package/dist/portable/decorators/modern/SugarDecorators.mjs.map +1 -1
- package/dist/portable/decorators/modern/createAccessorDecorator.mjs.map +1 -1
- package/dist/portable/decorators/resolveDecoratorValue.mjs.map +1 -1
- package/dist/portable/engine/Envapter.mjs.map +1 -1
- package/dist/portable/engine/PortableEnvapter.mjs.map +1 -1
- package/dist/portable/engine/TemplateResolver.mjs.map +1 -1
- package/dist/portable/engine/Validators.mjs.map +1 -1
- package/dist/portable/engine/fileApiStub.mjs.map +1 -1
- package/dist/portable/infra/Debug.mjs.map +1 -1
- package/dist/portable/infra/Dotenv.mjs.map +1 -1
- package/dist/portable/infra/Error.mjs.map +1 -1
- package/dist/portable/infra/recase.mjs.map +1 -1
- package/dist/portable/infra/runtime.mjs.map +1 -1
- package/dist/portable/sources/PortableSource.mjs.map +1 -1
- package/dist/portable/sources/UnboundSource.mjs.map +1 -1
- package/dist/portable/sources/coerce.mjs.map +1 -1
- package/dist/portable/sources/merge.mjs.map +1 -1
- package/dist/types/converters/Converters.d.mts +4 -5
- package/dist/types/core/AdvancedMethods.d.mts +6 -12
- package/dist/types/core/EnvapterBase.d.mts +9 -12
- package/dist/types/core/Environment.d.mts +1 -2
- package/dist/types/core/EnvironmentMethods.d.mts +1 -6
- package/dist/types/core/PrimitiveMethods.d.mts +1 -5
- package/dist/types/decorators/legacy/Envapt.d.mts +17 -19
- package/dist/types/decorators/legacy/SugarDecorators.d.mts +12 -13
- package/dist/types/decorators/modern/Envapt.d.mts +17 -19
- package/dist/types/decorators/modern/SugarDecorators.d.mts +12 -13
- package/dist/types/engine/Envapter.d.mts +2 -2
- package/dist/types/engine/NodeEnvapter.d.mts +5 -6
- package/dist/types/engine/PortableEnvapter.d.mts +5 -7
- package/dist/types/infra/Debug.d.mts +3 -5
- package/dist/types/infra/Dotenv.d.mts +2 -4
- package/dist/types/infra/Error.d.mts +4 -5
- package/dist/types/infra/StandardSchema.d.mts +5 -7
- package/dist/types/sources/FileSource.d.mts +1 -2
- package/dist/types/sources/PortableSource.d.mts +7 -8
- package/dist/types/sources/merge.d.mts +1 -2
- package/dist/types/types/Conversion.d.mts +0 -4
- package/dist/types/types/Decorator.d.mts +2 -3
- package/dist/types/types/Options.d.mts +7 -7
- package/dist/types/types/Schema.d.mts +1 -1
- package/package.json +9 -11
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TemplateResolver.mjs","names":[],"sources":["../../../src/engine/TemplateResolver.ts"],"sourcesContent":["import { isMissing } from '../core/missing';\nimport { state } from '../core/state';\nimport { debugWarn } from '../infra/Debug';\nimport { EnvaptError, EnvaptErrorCodes } from '../infra/Error';\n\nimport type { EnvapterService } from '../types/Env';\n\
|
|
1
|
+
{"version":3,"file":"TemplateResolver.mjs","names":[],"sources":["../../../src/engine/TemplateResolver.ts"],"sourcesContent":["import { isMissing } from '../core/missing';\nimport { state } from '../core/state';\nimport { debugWarn } from '../infra/Debug';\nimport { EnvaptError, EnvaptErrorCodes } from '../infra/Error';\n\nimport type { EnvapterService } from '../types/Env';\n\nexport class TemplateResolver {\n private readonly TEMPLATE_REGEX = /\\${\\w*}/g;\n\n constructor(private readonly envService: EnvapterService) {}\n\n resolveTemplate(key: string, value: string, stack: Set<string> = new Set<string>()): string {\n stack.add(key);\n const strict = state.strict;\n\n const out = value.replace(this.TEMPLATE_REGEX, (template) => {\n const variable = template.slice(2, -1);\n\n if (stack.has(variable)) return template; // cycle, preserve\n\n const raw = this.envService.getRaw(variable);\n if (raw === undefined || isMissing(raw)) {\n if (strict) {\n throw new EnvaptError(\n EnvaptErrorCodes.MissingEnvValue,\n `Cannot resolve template variable \"\\${${variable}}\": value is missing or empty.`\n );\n }\n debugWarn(`unresolved template \\${${variable}} preserved as literal`);\n return template; // missing or empty, preserve\n }\n\n const resolved = this.resolveTemplate(variable, raw, new Set(stack));\n\n // indirect cycle\n if (resolved.includes(`\\${${key}}`)) return template;\n\n // the nested value still has unresolved placeholders\n if (resolved === raw && /\\$\\{[^}]*\\}/.test(resolved)) return template;\n\n return resolved;\n });\n\n stack.delete(key);\n return out;\n }\n}\n"],"mappings":"0LAOA,IAAa,EAAb,KAA8B,CAGG,WAF7B,eAAkC,WAElC,YAAY,EAA8C,CAA7B,KAAA,WAAA,CAA8B,CAE3D,gBAAgB,EAAa,EAAe,EAAqB,IAAI,IAAuB,CACxF,EAAM,IAAI,CAAG,EACb,IAAM,EAAS,EAAM,OAEf,EAAM,EAAM,QAAQ,KAAK,eAAiB,GAAa,CACzD,IAAM,EAAW,EAAS,MAAM,EAAG,EAAE,EAErC,GAAI,EAAM,IAAI,CAAQ,EAAG,OAAO,EAEhC,IAAM,EAAM,KAAK,WAAW,OAAO,CAAQ,EAC3C,GAAI,IAAQ,IAAA,IAAa,EAAU,CAAG,EAAG,CACrC,GAAI,EACA,MAAM,IAAI,EAAA,IAEN,wCAAwC,EAAS,+BACrD,EAGJ,OADA,EAAU,0BAA0B,EAAS,uBAAuB,EAC7D,CACX,CAEA,IAAM,EAAW,KAAK,gBAAgB,EAAU,EAAK,IAAI,IAAI,CAAK,CAAC,EAQnE,OALI,EAAS,SAAS,MAAM,EAAI,EAAE,GAG9B,IAAa,GAAO,cAAc,KAAK,CAAQ,EAAU,EAEtD,CACX,CAAC,EAGD,OADA,EAAM,OAAO,CAAG,EACT,CACX,CACJ"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Validators.mjs","names":[],"sources":["../../../src/engine/Validators.ts"],"sourcesContent":["// Import the converter modules directly, not via the `./converters` barrel: that barrel pulls in\n// ValueConverter, which imports this Validator, so a barrel import here would cycle.\nimport { isArrayOf } from '../converters/Converters';\nimport { ListOfBuiltInConverters, BuiltInConverterTypeCheckers } from '../converters/ListOfBuiltInConverters';\nimport { EnvaptError, EnvaptErrorCodes } from '../infra/Error';\n\nimport type { ArrayOf, ConverterToken } from '../converters/Converters';\nimport type { EnvFileOptions } from '../infra/Dotenv';\nimport type { StandardSchemaV1 } from '../infra/StandardSchema';\nimport type { BuiltInConverter, ConverterFunction, EnvaptConverter, FileApiMode } from '../types';\n\n// eslint-disable-next-line @typescript-eslint/no-extraneous-class -- cohesive dispatch of stateless type guards, same shape as BuiltInConverters\nexport class Validator {\n /**\n * Check if a value is a built-in scalar converter token\n */\n static isBuiltInConverter<TFallback>(value: EnvaptConverter<TFallback>): value is BuiltInConverter {\n if (typeof value === 'string') return ListOfBuiltInConverters.includes(value);\n return false;\n }\n\n /**\n * Check if a value is an `ArrayOf<...>` token produced by {@link Converters.array}.\n */\n static isArrayConverter(value: unknown): value is ArrayOf {\n return isArrayOf(value);\n }\n\n // Structural check: `version === 1` + callable `validate` is the minimum dispatchable\n // shape per the Standard Schema spec.\n static isStandardSchema(value: unknown): value is StandardSchemaV1 {\n if (typeof value !== 'object' || value === null) return false;\n if (!('~standard' in value)) return false;\n const slot = value['~standard'];\n if (typeof slot !== 'object' || slot === null) return false;\n const props = slot as { version?: unknown; validate?: unknown };\n return props.version === 1 && typeof props.validate === 'function';\n }\n\n static customConvertor<TFallback>(\n converter: EnvaptConverter<TFallback>\n ): asserts converter is ConverterFunction<TFallback> {\n if (typeof converter !== 'function') {\n throw new EnvaptError(\n EnvaptErrorCodes.InvalidCustomConverter,\n `Custom converter must be a function, got ${typeof converter}.`\n );\n }\n }\n\n /**\n * Runtime validation that the `ArrayOf<...>` configuration is well-formed.\n */\n static arrayConverter(value: unknown): asserts value is ArrayOf {\n if (!isArrayOf(value)) {\n throw new EnvaptError(\n EnvaptErrorCodes.InvalidArrayConverterType,\n 'Expected an ArrayOf<...> token produced by Converters.array(...)'\n );\n }\n\n if (typeof value.delimiter !== 'string' || value.delimiter.length === 0) {\n throw new EnvaptError(\n EnvaptErrorCodes.MissingDelimiter,\n `ArrayOf<...> requires a non-empty string delimiter, got ${typeof value.delimiter}`\n );\n }\n\n const elementOf = value.of;\n const isScalar = typeof elementOf === 'string' && ListOfBuiltInConverters.includes(elementOf);\n const isCustomFn = typeof elementOf === 'function';\n if (!isScalar && !isCustomFn) {\n throw new EnvaptError(\n EnvaptErrorCodes.InvalidArrayConverterType,\n `ArrayOf<...> element (\"of\") must be a built-in scalar token or a function, got ${typeof elementOf}`\n );\n }\n }\n\n /**\n * Validate that a string is a valid built-in scalar converter token\n */\n static builtInConverter(value: unknown): asserts value is BuiltInConverter {\n if (typeof value !== 'string') {\n throw new EnvaptError(EnvaptErrorCodes.InvalidConverterType, `Expected string, got ${typeof value}`);\n }\n\n if (!ListOfBuiltInConverters.includes(value as ConverterToken)) {\n throw new EnvaptError(\n EnvaptErrorCodes.InvalidBuiltInConverter,\n `\"${value}\" is not a valid converter type. Valid types are: ${ListOfBuiltInConverters.join(',')}`\n );\n }\n }\n\n /**\n * Validate that fallback type matches the converter's return type for built-in converters\n */\n static validateBuiltInConverterFallback(converter: BuiltInConverter, fallback: unknown): void {\n const typeChecker = BuiltInConverterTypeCheckers[converter];\n if (!typeChecker(fallback)) {\n throw new EnvaptError(\n EnvaptErrorCodes.FallbackConverterTypeMismatch,\n `Fallback type does not match converter \"${converter}\". Expected ${converter} compatible type.`\n );\n }\n }\n\n /**\n * Validate that all elements in an array fallback have consistent types\n */\n static validateArrayFallbackElementTypes(fallback: unknown[]): void {\n if (fallback.length === 0) return;\n\n const firstElementType = typeof fallback[0];\n const hasInconsistentTypes = fallback.some((element, index) => {\n if (index === 0) return false;\n return typeof element !== firstElementType;\n });\n\n if (hasInconsistentTypes) {\n throw new EnvaptError(\n EnvaptErrorCodes.ArrayFallbackElementTypeMismatch,\n `All elements in array fallback must have the same type. Found mixed types.`\n );\n }\n }\n\n /**\n * Validate that an `ArrayOf<...>` element converter matches the runtime types of its\n * fallback elements. For `Converters.Time` arrays the element-time-string format is also\n * checked here.\n */\n static validateArrayConverterElementTypeMatch(elementOf: ArrayOf['of'], fallback: unknown[]): void {\n if (fallback.length === 0) return;\n\n if (typeof elementOf === 'function') {\n // Custom element converters can return anything; we can't statically validate the fallback shape.\n return;\n }\n\n const elementToken = elementOf;\n\n // Time array fallbacks may be number[] OR string[] (TimeFallback[]).\n if (elementToken === 'time') {\n const everyNumber = fallback.every((v) => typeof v === 'number');\n const everyString = fallback.every((v) => typeof v === 'string');\n if (!everyNumber && !everyString) {\n throw new EnvaptError(\n EnvaptErrorCodes.ArrayFallbackElementTypeMismatch,\n 'Time array fallback must be all numbers or all time-string entries.'\n );\n }\n return;\n }\n\n const typeChecker = BuiltInConverterTypeCheckers[elementToken];\n const firstElement = fallback[0];\n if (!typeChecker(firstElement)) {\n throw new EnvaptError(\n EnvaptErrorCodes.ArrayFallbackElementTypeMismatch,\n `Array converter type \"${elementToken}\" does not match fallback element type. Expected ${elementToken} compatible elements.`\n );\n }\n }\n\n /**\n * Check if a value is a primitive constructor\n */\n static isPrimitiveConstructor(\n value: unknown\n ): value is typeof String | typeof Number | typeof Boolean | typeof BigInt | typeof Symbol {\n return value === String || value === Number || value === Boolean || value === BigInt || value === Symbol;\n }\n\n /**\n * Safely coerce a fallback value using a primitive constructor\n */\n static coercePrimitiveFallback<CoercedType>(\n converter: typeof String | typeof Number | typeof Boolean | typeof BigInt | typeof Symbol,\n fallback: unknown\n ): CoercedType {\n if (this.isCorrectPrimitiveType(converter, fallback)) return fallback as CoercedType;\n return this.performPrimitiveCoercion<CoercedType>(converter, fallback);\n }\n\n private static isCorrectPrimitiveType(\n converter: typeof String | typeof Number | typeof Boolean | typeof BigInt | typeof Symbol,\n fallback: unknown\n ): boolean {\n if (converter === String && typeof fallback === 'string') return true;\n if (converter === Number && typeof fallback === 'number') return true;\n if (converter === Boolean && typeof fallback === 'boolean') return true;\n if (converter === BigInt && typeof fallback === 'bigint') return true;\n if (converter === Symbol && typeof fallback === 'symbol') return true;\n return false;\n }\n\n private static performPrimitiveCoercion<CoercedType>(\n converter: typeof String | typeof Number | typeof Boolean | typeof BigInt | typeof Symbol,\n fallback: unknown\n ): CoercedType {\n try {\n if (converter === String) return String(fallback) as CoercedType;\n if (converter === Number) return Number(fallback) as CoercedType;\n if (converter === Boolean) return Boolean(fallback) as CoercedType;\n if (converter === BigInt) return BigInt(fallback as string | number | bigint) as CoercedType;\n /* v8 ignore next -- @preserve */\n if (converter === Symbol) return Symbol.for(String(fallback)) as CoercedType;\n } catch (error) {\n throw new EnvaptError(\n EnvaptErrorCodes.PrimitiveCoercionFailed,\n `Failed to coerce fallback value using ${converter.name}: ${(error as Error).message}`\n );\n }\n\n /* v8 ignore next -- @preserve */\n throw new EnvaptError(\n EnvaptErrorCodes.PrimitiveCoercionFailed,\n `Unknown primitive converter: ${converter.name}`\n );\n }\n\n /**\n * Reject non-boolean inputs to `Envapter.syncProcessEnv` so a truthy typo\n * (`'true'`, `1`, etc.) does not silently enable the mirror.\n */\n static validateSyncProcessEnv(value: unknown): asserts value is boolean {\n if (typeof value !== 'boolean') {\n throw new EnvaptError(\n EnvaptErrorCodes.InvalidUserDefinedConfig,\n `Envapter.syncProcessEnv must be a boolean, got ${typeof value}.`\n );\n }\n }\n\n static validateFileApiMode(value: unknown): asserts value is FileApiMode {\n if (value !== 'warn' && value !== 'throw') {\n const got = typeof value === 'string' ? `'${value}'` : typeof value;\n throw new EnvaptError(\n EnvaptErrorCodes.InvalidUserDefinedConfig,\n `Envapter.fileApiMode must be 'warn' or 'throw', got ${got}.`\n );\n }\n }\n\n /**\n * Make sure the user hasn't provided prohibited options in their dotenv config\n */\n static validateEnvFileOptions(config: object): config is EnvFileOptions {\n const validKeys = new Set(['encoding', 'override']);\n const invalidKeys = Object.keys(config).filter((key) => !validKeys.has(key));\n\n if (invalidKeys.length > 0) {\n throw new EnvaptError(\n EnvaptErrorCodes.InvalidUserDefinedConfig,\n `Invalid envFileOptions: ${invalidKeys.join(', ')}. Allowed options: ${Array.from(validKeys).join(', ')}. For debug output, use Envapter.debug or the ENVAPT_DEBUG env var.`\n );\n }\n\n return true;\n }\n\n // Existence is probed through the caller-supplied `fileExists` (backed by the bound source) so\n // this stays free of `node:fs`.\n static validateEnvFilesExist(paths: string[], fileExists: (path: string) => boolean): void {\n const missing = paths.filter((p) => !fileExists(p));\n\n if (missing.length > 0) {\n throw new EnvaptError(\n EnvaptErrorCodes.EnvFilesNotFound,\n `Environment file not found at path: ${missing.join(', ')}`\n );\n }\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Validators.mjs","names":[],"sources":["../../../src/engine/Validators.ts"],"sourcesContent":["// the ./converters barrel imports ValueConverter, which imports this file\nimport { isArrayOf } from '../converters/Converters';\nimport { ListOfBuiltInConverters, BuiltInConverterTypeCheckers } from '../converters/ListOfBuiltInConverters';\nimport { EnvaptError, EnvaptErrorCodes } from '../infra/Error';\n\nimport type { ArrayOf, ConverterToken } from '../converters/Converters';\nimport type { EnvFileOptions } from '../infra/Dotenv';\nimport type { StandardSchemaV1 } from '../infra/StandardSchema';\nimport type { BuiltInConverter, ConverterFunction, EnvaptConverter, FileApiMode } from '../types';\n\n// eslint-disable-next-line @typescript-eslint/no-extraneous-class -- cohesive dispatch of stateless type guards, same shape as BuiltInConverters\nexport class Validator {\n static isBuiltInConverter<TFallback>(value: EnvaptConverter<TFallback>): value is BuiltInConverter {\n if (typeof value === 'string') return ListOfBuiltInConverters.includes(value);\n return false;\n }\n\n static isArrayConverter(value: unknown): value is ArrayOf {\n return isArrayOf(value);\n }\n\n static isStandardSchema(value: unknown): value is StandardSchemaV1 {\n if (typeof value !== 'object' || value === null) return false;\n if (!('~standard' in value)) return false;\n const slot = value['~standard'];\n if (typeof slot !== 'object' || slot === null) return false;\n const props = slot as { version?: unknown; validate?: unknown };\n return props.version === 1 && typeof props.validate === 'function';\n }\n\n static customConvertor<TFallback>(\n converter: EnvaptConverter<TFallback>\n ): asserts converter is ConverterFunction<TFallback> {\n if (typeof converter !== 'function') {\n throw new EnvaptError(\n EnvaptErrorCodes.InvalidCustomConverter,\n `Custom converter must be a function, got ${typeof converter}.`\n );\n }\n }\n\n static arrayConverter(value: unknown): asserts value is ArrayOf {\n if (!isArrayOf(value)) {\n throw new EnvaptError(\n EnvaptErrorCodes.InvalidArrayConverterType,\n 'Expected an ArrayOf<...> token produced by Converters.array(...)'\n );\n }\n\n if (typeof value.delimiter !== 'string' || value.delimiter.length === 0) {\n throw new EnvaptError(\n EnvaptErrorCodes.MissingDelimiter,\n `ArrayOf<...> requires a non-empty string delimiter, got ${typeof value.delimiter}`\n );\n }\n\n const elementOf = value.of;\n const isScalar = typeof elementOf === 'string' && ListOfBuiltInConverters.includes(elementOf);\n const isCustomFn = typeof elementOf === 'function';\n if (!isScalar && !isCustomFn) {\n throw new EnvaptError(\n EnvaptErrorCodes.InvalidArrayConverterType,\n `ArrayOf<...> element (\"of\") must be a built-in scalar token or a function, got ${typeof elementOf}`\n );\n }\n }\n\n static builtInConverter(value: unknown): asserts value is BuiltInConverter {\n if (typeof value !== 'string') {\n throw new EnvaptError(EnvaptErrorCodes.InvalidConverterType, `Expected string, got ${typeof value}`);\n }\n\n if (!ListOfBuiltInConverters.includes(value as ConverterToken)) {\n throw new EnvaptError(\n EnvaptErrorCodes.InvalidBuiltInConverter,\n `\"${value}\" is not a valid converter type. Valid types are: ${ListOfBuiltInConverters.join(',')}`\n );\n }\n }\n\n static validateBuiltInConverterFallback(converter: BuiltInConverter, fallback: unknown): void {\n const typeChecker = BuiltInConverterTypeCheckers[converter];\n if (!typeChecker(fallback)) {\n throw new EnvaptError(\n EnvaptErrorCodes.FallbackConverterTypeMismatch,\n `Fallback type does not match converter \"${converter}\". Expected ${converter} compatible type.`\n );\n }\n }\n\n static validateArrayFallbackElementTypes(fallback: unknown[]): void {\n if (fallback.length === 0) return;\n\n const firstElementType = typeof fallback[0];\n const hasInconsistentTypes = fallback.some((element, index) => {\n if (index === 0) return false;\n return typeof element !== firstElementType;\n });\n\n if (hasInconsistentTypes) {\n throw new EnvaptError(\n EnvaptErrorCodes.ArrayFallbackElementTypeMismatch,\n `All elements in array fallback must have the same type. Found mixed types.`\n );\n }\n }\n\n static validateArrayConverterElementTypeMatch(elementOf: ArrayOf['of'], fallback: unknown[]): void {\n if (fallback.length === 0) return;\n\n if (typeof elementOf === 'function') {\n // a custom element converter can return any type\n return;\n }\n\n const elementToken = elementOf;\n\n if (elementToken === 'time') {\n const everyNumber = fallback.every((v) => typeof v === 'number');\n const everyString = fallback.every((v) => typeof v === 'string');\n if (!everyNumber && !everyString) {\n throw new EnvaptError(\n EnvaptErrorCodes.ArrayFallbackElementTypeMismatch,\n 'Time array fallback must be all numbers or all time-string entries.'\n );\n }\n return;\n }\n\n const typeChecker = BuiltInConverterTypeCheckers[elementToken];\n const firstElement = fallback[0];\n if (!typeChecker(firstElement)) {\n throw new EnvaptError(\n EnvaptErrorCodes.ArrayFallbackElementTypeMismatch,\n `Array converter type \"${elementToken}\" does not match fallback element type. Expected ${elementToken} compatible elements.`\n );\n }\n }\n\n static isPrimitiveConstructor(\n value: unknown\n ): value is typeof String | typeof Number | typeof Boolean | typeof BigInt | typeof Symbol {\n return value === String || value === Number || value === Boolean || value === BigInt || value === Symbol;\n }\n\n static coercePrimitiveFallback<CoercedType>(\n converter: typeof String | typeof Number | typeof Boolean | typeof BigInt | typeof Symbol,\n fallback: unknown\n ): CoercedType {\n if (this.isCorrectPrimitiveType(converter, fallback)) return fallback as CoercedType;\n return this.performPrimitiveCoercion<CoercedType>(converter, fallback);\n }\n\n private static isCorrectPrimitiveType(\n converter: typeof String | typeof Number | typeof Boolean | typeof BigInt | typeof Symbol,\n fallback: unknown\n ): boolean {\n if (converter === String && typeof fallback === 'string') return true;\n if (converter === Number && typeof fallback === 'number') return true;\n if (converter === Boolean && typeof fallback === 'boolean') return true;\n if (converter === BigInt && typeof fallback === 'bigint') return true;\n if (converter === Symbol && typeof fallback === 'symbol') return true;\n return false;\n }\n\n private static performPrimitiveCoercion<CoercedType>(\n converter: typeof String | typeof Number | typeof Boolean | typeof BigInt | typeof Symbol,\n fallback: unknown\n ): CoercedType {\n try {\n if (converter === String) return String(fallback) as CoercedType;\n if (converter === Number) return Number(fallback) as CoercedType;\n if (converter === Boolean) return Boolean(fallback) as CoercedType;\n if (converter === BigInt) return BigInt(fallback as string | number | bigint) as CoercedType;\n /* v8 ignore next -- @preserve */\n if (converter === Symbol) return Symbol.for(String(fallback)) as CoercedType;\n } catch (error) {\n throw new EnvaptError(\n EnvaptErrorCodes.PrimitiveCoercionFailed,\n `Failed to coerce fallback value using ${converter.name}: ${(error as Error).message}`\n );\n }\n\n /* v8 ignore next -- @preserve */\n throw new EnvaptError(\n EnvaptErrorCodes.PrimitiveCoercionFailed,\n `Unknown primitive converter: ${converter.name}`\n );\n }\n\n // a truthy typo like 'true' or 1 would turn the mirror on\n static validateSyncProcessEnv(value: unknown): asserts value is boolean {\n if (typeof value !== 'boolean') {\n throw new EnvaptError(\n EnvaptErrorCodes.InvalidUserDefinedConfig,\n `Envapter.syncProcessEnv must be a boolean, got ${typeof value}.`\n );\n }\n }\n\n static validateFileApiMode(value: unknown): asserts value is FileApiMode {\n if (value !== 'warn' && value !== 'throw') {\n const got = typeof value === 'string' ? `'${value}'` : typeof value;\n throw new EnvaptError(\n EnvaptErrorCodes.InvalidUserDefinedConfig,\n `Envapter.fileApiMode must be 'warn' or 'throw', got ${got}.`\n );\n }\n }\n\n static validateEnvFileOptions(config: object): config is EnvFileOptions {\n const validKeys = new Set(['encoding', 'override']);\n const invalidKeys = Object.keys(config).filter((key) => !validKeys.has(key));\n\n if (invalidKeys.length > 0) {\n throw new EnvaptError(\n EnvaptErrorCodes.InvalidUserDefinedConfig,\n `Invalid envFileOptions: ${invalidKeys.join(', ')}. Allowed options: ${Array.from(validKeys).join(', ')}. For debug output, use Envapter.debug or the ENVAPT_DEBUG env var.`\n );\n }\n\n return true;\n }\n\n // fileExists comes from the caller because this file must not import node:fs\n static validateEnvFilesExist(paths: string[], fileExists: (path: string) => boolean): void {\n const missing = paths.filter((p) => !fileExists(p));\n\n if (missing.length > 0) {\n throw new EnvaptError(\n EnvaptErrorCodes.EnvFilesNotFound,\n `Environment file not found at path: ${missing.join(', ')}`\n );\n }\n }\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fileApiStub.mjs","names":[],"sources":["../../../src/engine/fileApiStub.ts"],"sourcesContent":["import { EnvapterBase } from '../core/EnvapterBase';\nimport { EnvaptError, EnvaptErrorCodes } from '../infra/Error';\nimport { writeRuntimeLine } from '../infra/runtime';\n\n//
|
|
1
|
+
{"version":3,"file":"fileApiStub.mjs","names":[],"sources":["../../../src/engine/fileApiStub.ts"],"sourcesContent":["import { EnvapterBase } from '../core/EnvapterBase';\nimport { EnvaptError, EnvaptErrorCodes } from '../infra/Error';\nimport { writeRuntimeLine } from '../infra/runtime';\n\n// importing this from EnvapterBase would create an import cycle\nconst warned = new Set<string>();\n\nfunction fileApiUnsupported(api: string): never {\n throw new EnvaptError(\n EnvaptErrorCodes.FileApiUnsupported,\n `Envapter.${api} requires a filesystem-backed source and is not available in this build.`\n );\n}\n\n// writes even when Envapter.debug is silent\nfunction warnOnce(api: string): void {\n if (warned.has(api)) return;\n warned.add(api);\n writeRuntimeLine(\n `[envapt] Envapter.${api} is a filesystem-only API and has no effect in the portable build. ` +\n `Set Envapter.fileApiMode = 'throw' to throw instead.`\n );\n}\n\nexport function portableFileApiRead<Value>(api: string, fallback: Value): Value {\n if (EnvapterBase.fileApiMode === 'throw') fileApiUnsupported(api);\n warnOnce(api);\n return fallback;\n}\n\nexport function portableFileApiWrite(api: string): void {\n if (EnvapterBase.fileApiMode === 'throw') fileApiUnsupported(api);\n warnOnce(api);\n}\n"],"mappings":"iKAKA,MAAM,EAAS,IAAI,IAEnB,SAAS,EAAmB,EAAoB,CAC5C,MAAM,IAAI,EAAA,IAEN,YAAY,EAAI,yEACpB,CACJ,CAGA,SAAS,EAAS,EAAmB,CAC7B,EAAO,IAAI,CAAG,IAClB,EAAO,IAAI,CAAG,EACd,EACI,qBAAqB,EAAI,wHAE7B,EACJ,CAEA,SAAgB,EAA2B,EAAa,EAAwB,CAG5E,OAFI,EAAa,cAAgB,SAAS,EAAmB,CAAG,EAChE,EAAS,CAAG,EACL,CACX,CAEA,SAAgB,EAAqB,EAAmB,CAChD,EAAa,cAAgB,SAAS,EAAmB,CAAG,EAChE,EAAS,CAAG,CAChB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Debug.mjs","names":[],"sources":["../../../src/infra/Debug.ts"],"sourcesContent":["import { EnvaptError, EnvaptErrorCodes } from './Error';\nimport { readRuntimeVar, writeRuntimeLine } from './runtime';\n\n/**\n * Debug log levels for {@link Envapter.debug}. `silent` (default) emits nothing.\n * `warn`
|
|
1
|
+
{"version":3,"file":"Debug.mjs","names":[],"sources":["../../../src/infra/Debug.ts"],"sourcesContent":["import { EnvaptError, EnvaptErrorCodes } from './Error';\nimport { readRuntimeVar, writeRuntimeLine } from './runtime';\n\n/**\n * Debug log levels for {@link Envapter.debug}. `silent` (default) emits nothing.\n * `warn` logs failed file reads, unresolved templates (when not strict), and any read of a\n * missing or empty variable, whether it returns a fallback or `undefined`. `verbose` adds every loaded file,\n * per-file key count, per-key load lines, and effective-paths / cache-rebuild notices.\n * @public\n * @see {@link https://envapt.materwelon.dev/docs/configuration#debug-logging}\n */\nexport type DebugLevel = 'silent' | 'warn' | 'verbose';\n\nconst VALID_LEVELS: ReadonlySet<string> = new Set<DebugLevel>(['silent', 'warn', 'verbose']);\n\nlet currentLevel: DebugLevel = 'silent';\nlet initialized = false;\n\nfunction isDebugLevel(value: string | undefined): value is DebugLevel {\n return value !== undefined && VALID_LEVELS.has(value);\n}\n\n// Reads `ENVAPT_DEBUG` lazily on first access. Setter wins after that.\nfunction resolveLevel(): DebugLevel {\n if (!initialized) {\n const fromEnv = readRuntimeVar('ENVAPT_DEBUG');\n currentLevel = isDebugLevel(fromEnv) ? fromEnv : 'silent';\n initialized = true;\n }\n return currentLevel;\n}\n\nexport function setDebugLevel(level: DebugLevel): void {\n if (!isDebugLevel(level)) {\n throw new EnvaptError(\n EnvaptErrorCodes.InvalidUserDefinedConfig,\n `Invalid debug level \"${String(level)}\". Expected 'silent' | 'warn' | 'verbose'.`\n );\n }\n currentLevel = level;\n initialized = true;\n}\n\nexport function getDebugLevel(): DebugLevel {\n return resolveLevel();\n}\n\nexport function resetDebugForTesting(): void {\n currentLevel = 'silent';\n initialized = false;\n}\n\nexport function debugWarn(message: string): void {\n const level = resolveLevel();\n if (level === 'warn' || level === 'verbose') {\n writeRuntimeLine(`[envapt] ${message}`);\n }\n}\n\nexport function debugVerbose(message: string): void {\n if (resolveLevel() === 'verbose') {\n writeRuntimeLine(`[envapt] ${message}`);\n }\n}\n"],"mappings":"+GAaA,MAAM,EAAoC,IAAI,IAAgB,CAAC,SAAU,OAAQ,SAAS,CAAC,EAE3F,IAAI,EAA2B,SAC3B,EAAc,GAElB,SAAS,EAAa,EAAgD,CAClE,OAAO,IAAU,IAAA,IAAa,EAAa,IAAI,CAAK,CACxD,CAGA,SAAS,GAA2B,CAChC,GAAI,CAAC,EAAa,CACd,IAAM,EAAU,EAAe,cAAc,EAC7C,EAAe,EAAa,CAAO,EAAI,EAAU,SACjD,EAAc,EAClB,CACA,OAAO,CACX,CAEA,SAAgB,EAAc,EAAyB,CACnD,GAAI,CAAC,EAAa,CAAK,EACnB,MAAM,IAAI,EAAA,IAEN,wBAAwB,OAAO,CAAK,EAAE,2CAC1C,EAEJ,EAAe,EACf,EAAc,EAClB,CAEA,SAAgB,GAA4B,CACxC,OAAO,EAAa,CACxB,CAOA,SAAgB,EAAU,EAAuB,CAC7C,IAAM,EAAQ,EAAa,GACvB,IAAU,QAAU,IAAU,YAC9B,EAAiB,YAAY,GAAS,CAE9C,CAEA,SAAgB,EAAa,EAAuB,CAC5C,EAAa,IAAM,WACnB,EAAiB,YAAY,GAAS,CAE9C"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Dotenv.mjs","names":[],"sources":["../../../src/infra/Dotenv.ts"],"sourcesContent":["import { debugVerbose, debugWarn } from './Debug';\n\n/**\n * Public options for the internal `.env` loader. Mirrors the subset of dotenv's\n * `config()` options that envapt actually supports (no DOTENV_KEY, no quiet).\n * For debug output, use `Envapter.debug` (or the `ENVAPT_DEBUG` env var).\n *\n * @public\n * @see {@link https://envapt.materwelon.dev/docs/configuration#which-files-load}\n */\nexport interface EnvFileOptions {\n /** Encoding for reading .env files. Defaults to 'utf8'. */\n encoding?: string;\n /** When true, later files override earlier ones (and existing processEnv values). Default false (first-wins). */\n override?: boolean;\n}\n\n/**\n * Internal call signature used by `EnvapterBase`. The `path` and `processEnv`\n * fields are managed by envapt and never user-supplied.\n * @internal\n */\nexport interface LoadDotenvInput extends EnvFileOptions {\n path: string | string[];\n processEnv: Record<string, string>;\n // Injected so the loader stays free of `node:fs`. Returns `undefined` when the file is absent.\n readFile(path: string, encoding: string): string | undefined;\n}\n\n// Matches: optional `export`, KEY name, optional whitespace, `=`, optional whitespace, value tail.\n// Multi-line quoted values are handled by re-buffering subsequent lines below.\n// Bounded by anchors with linear-time quantifiers; no catastrophic backtracking risk -- justified\n// eslint-disable-next-line security/detect-unsafe-regex\nconst KEY_LINE_RE = /^\\s*(?:export\\s+)?([A-Za-z_][A-Za-z0-9_]*)\\s*=(.*)$/u;\n\n/**\n * Parse a `.env` text blob into a `Map<string, string>`.\n *\n * Supported syntax:\n * - `KEY=value` and `export KEY=value`\n * - blank lines and full-line `# comments`\n * - single-quoted `'literal'` values (no escape interpretation)\n * - double-quoted `\"value\"` values (interprets `\\n`, `\\r`, `\\t`, `\\\\`, `\\\"`)\n * - backtick-quoted values (literal, like single quotes)\n * - quoted values may span multiple lines\n * - inline `# comment` after an unquoted value (requires whitespace before `#`)\n * - empty values resolve to `\"\"`\n *\n * Mirrors dotenv's quirk where unescaped inner quotes inside a quoted value\n * are tolerated by greedy-matching to the rightmost matching quote on the\n * (possibly multi-line) value buffer. This is what lets a value like\n * `JSON=\"{\"name\":\"x\"}\"` round-trip without escaping.\n *\n * Does NOT perform `${VAR}` expansion — envapt's `Parser` handles that downstream.\n * @internal\n */\nexport function parseDotenv(src: string): Map<string, string> {\n const out = new Map<string, string>();\n const lines = src.split(/\\r?\\n/u);\n\n for (let i = 0; i < lines.length; i++) {\n const consumed = parseEntry(lines, i);\n i = consumed.endLine;\n if (consumed.entry) out.set(consumed.entry.key, consumed.entry.value);\n }\n\n return out;\n}\n\ninterface ParsedEntry {\n key: string;\n value: string;\n}\n\nfunction parseEntry(lines: string[], start: number): { entry: ParsedEntry | undefined; endLine: number } {\n /* v8 ignore next -- @preserve caller bounds-checks start so this never falls back */\n const line = lines[start] ?? '';\n const trimmedLine = line.trim();\n if (trimmedLine === '' || trimmedLine.startsWith('#')) return { entry: undefined, endLine: start };\n\n const match = line.match(KEY_LINE_RE);\n if (!match) return { entry: undefined, endLine: start };\n\n const key = match[1] as string;\n // Drop only leading whitespace before the value; trailing whitespace and inline comments\n // are dealt with below depending on whether the value is quoted.\n /* v8 ignore next -- @preserve regex group 2 always matches via `(.*)`, fallback is defensive */\n const rest = (match[2] ?? '').replace(/^\\s+/u, '');\n const firstChar = rest[0];\n\n if (firstChar === '\"' || firstChar === \"'\" || firstChar === '`') {\n const consumed = consumeQuotedValue(rest, lines, start, firstChar);\n return { entry: { key, value: consumed.value }, endLine: consumed.endLine };\n }\n\n return { entry: { key, value: stripInlineComment(rest) }, endLine: start };\n}\n\nfunction consumeQuotedValue(\n firstLineRest: string,\n lines: string[],\n startLine: number,\n quote: string\n): { value: string; endLine: number } {\n let buffer = firstLineRest;\n let cursor = startLine;\n let closeIdx = findLastUnescapedQuote(buffer, quote);\n\n while (closeIdx < 0 && cursor < lines.length - 1) {\n cursor++;\n /* v8 ignore next -- @preserve cursor is bounded by the while condition above */\n buffer += `\\n${lines[cursor] ?? ''}`;\n closeIdx = findLastUnescapedQuote(buffer, quote);\n }\n\n const inner = closeIdx > 0 ? buffer.slice(1, closeIdx) : buffer.slice(1);\n return { value: quote === '\"' ? unescapeDouble(inner) : inner, endLine: cursor };\n}\n\nfunction stripInlineComment(value: string): string {\n const hashIdx = findInlineCommentStart(value);\n const stripped = hashIdx === -1 ? value : value.slice(0, hashIdx);\n return stripped.trimEnd();\n}\n\nfunction findInlineCommentStart(value: string): number {\n for (let i = 0; i < value.length; i++) {\n if (value[i] === '#' && (i === 0 || /\\s/u.test(value[i - 1] as string))) return i;\n }\n return -1;\n}\n\n/**\n * Find the rightmost matching closing quote in `buffer` (skipping index 0 which is the\n * opening quote). For `\"`, a quote preceded by an odd number of backslashes is escaped\n * and ignored. Single and backtick quotes do not unescape.\n */\nfunction findLastUnescapedQuote(buffer: string, quote: string): number {\n for (let i = buffer.length - 1; i > 0; i--) {\n if (buffer[i] !== quote) continue;\n if (quote === '\"') {\n let backslashes = 0;\n let k = i - 1;\n while (k >= 0 && buffer[k] === '\\\\') {\n backslashes++;\n k--;\n }\n if (backslashes % 2 === 1) continue; // escaped\n }\n return i;\n }\n return -1;\n}\n\nfunction unescapeDouble(raw: string): string {\n let out = '';\n for (let i = 0; i < raw.length; i++) {\n const ch = raw[i];\n if (ch !== '\\\\' || i === raw.length - 1) {\n out += ch;\n continue;\n }\n const next = raw[i + 1];\n i++;\n switch (next) {\n case 'n':\n out += '\\n';\n break;\n case 'r':\n out += '\\r';\n break;\n case 't':\n out += '\\t';\n break;\n case '\\\\':\n out += '\\\\';\n break;\n case '\"':\n out += '\"';\n break;\n default:\n /* v8 ignore next -- @preserve `next` is always defined when this branch is reached (guarded above) */\n out += `\\\\${next ?? ''}`;\n }\n }\n return out;\n}\n\n/**\n * Load one or more `.env` files into a target `processEnv` map. Mirrors the\n * subset of dotenv's `config()` semantics that envapt depends on: first-wins\n * across multiple paths by default, optional `override: true`, optional\n * non-UTF8 encoding, missing files are skipped silently.\n *\n * Returns the set of keys actually written into `input.processEnv`. Skipped\n * collisions (under default `override: false`) are NOT included.\n * @internal\n */\nexport function loadDotenv(input: LoadDotenvInput): Set<string> {\n const paths = Array.isArray(input.path) ? input.path : [input.path];\n const encoding = input.encoding ?? 'utf8';\n const override = input.override ?? false;\n const written = new Set<string>();\n\n for (const filePath of paths) {\n const src = input.readFile(filePath, encoding);\n if (src === undefined) {\n debugWarn(`could not read ${filePath}`);\n continue;\n }\n\n const parsed = parseDotenv(src);\n debugVerbose(`loaded ${filePath}: ${parsed.size} ${parsed.size === 1 ? 'key' : 'keys'}`);\n for (const [key, value] of parsed) {\n const exists = Object.prototype.hasOwnProperty.call(input.processEnv, key);\n if (!exists || override) {\n input.processEnv[key] = value;\n written.add(key);\n debugVerbose(`${filePath} -> ${key}`);\n }\n }\n }\n\n return written;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Dotenv.mjs","names":[],"sources":["../../../src/infra/Dotenv.ts"],"sourcesContent":["import { debugVerbose, debugWarn } from './Debug';\n\n/**\n * Options for the `.env` loader, matching the dotenv `config()` options of the same name.\n * For debug output, use `Envapter.debug` (or the `ENVAPT_DEBUG` env var).\n *\n * @public\n * @see {@link https://envapt.materwelon.dev/docs/configuration#which-files-load}\n */\nexport interface EnvFileOptions {\n /** Encoding for reading .env files. Defaults to 'utf8'. */\n encoding?: string;\n /** When true, later files override earlier ones (and existing processEnv values). Default false (first-wins). */\n override?: boolean;\n}\n\nexport interface LoadDotenvInput extends EnvFileOptions {\n path: string | string[];\n processEnv: Record<string, string>;\n // passed in because this file must not import node:fs\n readFile(path: string, encoding: string): string | undefined;\n}\n\n// the anchors and linear quantifiers rule out catastrophic backtracking\n// eslint-disable-next-line security/detect-unsafe-regex\nconst KEY_LINE_RE = /^\\s*(?:export\\s+)?([A-Za-z_][A-Za-z0-9_]*)\\s*=(.*)$/u;\n\n// does not expand `${VAR}`, TemplateResolver does that on read\nexport function parseDotenv(src: string): Map<string, string> {\n const out = new Map<string, string>();\n const lines = src.split(/\\r?\\n/u);\n\n for (let i = 0; i < lines.length; i++) {\n const consumed = parseEntry(lines, i);\n i = consumed.endLine;\n if (consumed.entry) out.set(consumed.entry.key, consumed.entry.value);\n }\n\n return out;\n}\n\ninterface ParsedEntry {\n key: string;\n value: string;\n}\n\nfunction parseEntry(lines: string[], start: number): { entry: ParsedEntry | undefined; endLine: number } {\n /* v8 ignore next -- @preserve caller bounds-checks start so this never falls back */\n const line = lines[start] ?? '';\n const trimmedLine = line.trim();\n if (trimmedLine === '' || trimmedLine.startsWith('#')) return { entry: undefined, endLine: start };\n\n const match = line.match(KEY_LINE_RE);\n if (!match) return { entry: undefined, endLine: start };\n\n const key = match[1] as string;\n /* v8 ignore next -- @preserve regex group 2 always matches via `(.*)` */\n const rest = (match[2] ?? '').replace(/^\\s+/u, '');\n const firstChar = rest[0];\n\n if (firstChar === '\"' || firstChar === \"'\" || firstChar === '`') {\n const consumed = consumeQuotedValue(rest, lines, start, firstChar);\n return { entry: { key, value: consumed.value }, endLine: consumed.endLine };\n }\n\n return { entry: { key, value: stripInlineComment(rest) }, endLine: start };\n}\n\nfunction consumeQuotedValue(\n firstLineRest: string,\n lines: string[],\n startLine: number,\n quote: string\n): { value: string; endLine: number } {\n let buffer = firstLineRest;\n let cursor = startLine;\n let closeIdx = findLastUnescapedQuote(buffer, quote);\n\n while (closeIdx < 0 && cursor < lines.length - 1) {\n cursor++;\n /* v8 ignore next -- @preserve cursor is bounded by the while condition above */\n buffer += `\\n${lines[cursor] ?? ''}`;\n closeIdx = findLastUnescapedQuote(buffer, quote);\n }\n\n const inner = closeIdx > 0 ? buffer.slice(1, closeIdx) : buffer.slice(1);\n return { value: quote === '\"' ? unescapeDouble(inner) : inner, endLine: cursor };\n}\n\nfunction stripInlineComment(value: string): string {\n const hashIdx = findInlineCommentStart(value);\n const stripped = hashIdx === -1 ? value : value.slice(0, hashIdx);\n return stripped.trimEnd();\n}\n\nfunction findInlineCommentStart(value: string): number {\n for (let i = 0; i < value.length; i++) {\n if (value[i] === '#' && (i === 0 || /\\s/u.test(value[i - 1] as string))) return i;\n }\n return -1;\n}\n\n// closes on the last quote, like dotenv. JSON=\"{\"name\":\"x\"}\" parses without escaping.\nfunction findLastUnescapedQuote(buffer: string, quote: string): number {\n for (let i = buffer.length - 1; i > 0; i--) {\n if (buffer[i] !== quote) continue;\n if (quote === '\"') {\n let backslashes = 0;\n let k = i - 1;\n while (k >= 0 && buffer[k] === '\\\\') {\n backslashes++;\n k--;\n }\n if (backslashes % 2 === 1) continue; // escaped\n }\n return i;\n }\n return -1;\n}\n\nfunction unescapeDouble(raw: string): string {\n let out = '';\n for (let i = 0; i < raw.length; i++) {\n const ch = raw[i];\n if (ch !== '\\\\' || i === raw.length - 1) {\n out += ch;\n continue;\n }\n const next = raw[i + 1];\n i++;\n switch (next) {\n case 'n':\n out += '\\n';\n break;\n case 'r':\n out += '\\r';\n break;\n case 't':\n out += '\\t';\n break;\n case '\\\\':\n out += '\\\\';\n break;\n case '\"':\n out += '\"';\n break;\n default:\n /* v8 ignore next -- @preserve `next` is always defined when this branch is reached (guarded above) */\n out += `\\\\${next ?? ''}`;\n }\n }\n return out;\n}\n\nexport function loadDotenv(input: LoadDotenvInput): Set<string> {\n const paths = Array.isArray(input.path) ? input.path : [input.path];\n const encoding = input.encoding ?? 'utf8';\n const override = input.override ?? false;\n const written = new Set<string>();\n\n for (const filePath of paths) {\n const src = input.readFile(filePath, encoding);\n if (src === undefined) {\n debugWarn(`could not read ${filePath}`);\n continue;\n }\n\n const parsed = parseDotenv(src);\n debugVerbose(`loaded ${filePath}: ${parsed.size} ${parsed.size === 1 ? 'key' : 'keys'}`);\n for (const [key, value] of parsed) {\n const exists = Object.prototype.hasOwnProperty.call(input.processEnv, key);\n if (!exists || override) {\n input.processEnv[key] = value;\n written.add(key);\n debugVerbose(`${filePath} -> ${key}`);\n }\n }\n }\n\n return written;\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Error.mjs","names":[],"sources":["../../../src/infra/Error.ts"],"sourcesContent":["/* eslint-disable no-magic-numbers */\nimport type { StandardSchemaV1 } from './StandardSchema';\n\n/**\n * Numeric codes carried by {@link EnvaptError.code}, grouped by fallback (1xx), converter (2xx),\n * and configuration (3xx) failures.\n * @see {@link https://envapt.materwelon.dev/docs/errors#codes}\n */\nexport enum EnvaptErrorCodes {\n // Fallback related errors\n /** Thrown when an invalid fallback value is provided */\n InvalidFallback = 101,\n /** Thrown when fallback value type doesn't match expected converter type */\n InvalidFallbackType = 102,\n /** Thrown when array fallback contains elements of wrong type */\n ArrayFallbackElementTypeMismatch = 103,\n /** Thrown when fallback type doesn't match the specified converter */\n FallbackConverterTypeMismatch = 104,\n /** Thrown when a time-string fallback is malformed (does not match the required `<number><unit>` format) */\n MalformedTimeFallback = 105,\n\n // Converter related errors\n /** Thrown when invalid array converter configuration is provided */\n InvalidArrayConverterType = 201,\n /** Thrown when an invalid built-in converter is specified */\n InvalidBuiltInConverter = 202,\n /** Thrown when a custom converter is not a function */\n InvalidCustomConverter = 203,\n /** Thrown when converter type is not recognized */\n InvalidConverterType = 204,\n /** Thrown when primitive type coercion on fallback value fails */\n PrimitiveCoercionFailed = 205,\n /** Thrown when an array element fails to convert to the configured element type */\n ArrayElementConversionFailed = 206,\n /** Thrown under strict mode when an array element is empty or whitespace only */\n EmptyArrayElement = 207,\n /** Thrown when a Standard Schema returns issues for a non-empty env value */\n SchemaValidationFailed = 208,\n /** Thrown when a Standard Schema's `validate` itself throws (e.g. a refinement that crashes) */\n SchemaThrew = 209,\n\n // Other errors\n /** Thrown when delimiter is missing in array converter configuration */\n
|
|
1
|
+
{"version":3,"file":"Error.mjs","names":[],"sources":["../../../src/infra/Error.ts"],"sourcesContent":["/* eslint-disable no-magic-numbers */\nimport type { StandardSchemaV1 } from './StandardSchema';\n\n/**\n * Numeric codes carried by {@link EnvaptError.code}, grouped by fallback (1xx), converter (2xx),\n * and configuration (3xx) failures.\n * @see {@link https://envapt.materwelon.dev/docs/errors#codes}\n */\nexport enum EnvaptErrorCodes {\n // Fallback related errors\n /** Thrown when an invalid fallback value is provided */\n InvalidFallback = 101,\n /** Thrown when fallback value type doesn't match expected converter type */\n InvalidFallbackType = 102,\n /** Thrown when array fallback contains elements of wrong type */\n ArrayFallbackElementTypeMismatch = 103,\n /** Thrown when fallback type doesn't match the specified converter */\n FallbackConverterTypeMismatch = 104,\n /** Thrown when a time-string fallback is malformed (does not match the required `<number><unit>` format) */\n MalformedTimeFallback = 105,\n\n // Converter related errors\n /** Thrown when invalid array converter configuration is provided */\n InvalidArrayConverterType = 201,\n /** Thrown when an invalid built-in converter is specified */\n InvalidBuiltInConverter = 202,\n /** Thrown when a custom converter is not a function */\n InvalidCustomConverter = 203,\n /** Thrown when converter type is not recognized */\n InvalidConverterType = 204,\n /** Thrown when primitive type coercion on fallback value fails */\n PrimitiveCoercionFailed = 205,\n /** Thrown when an array element fails to convert to the configured element type */\n ArrayElementConversionFailed = 206,\n /** Thrown under strict mode when an array element is empty or whitespace only */\n EmptyArrayElement = 207,\n /** Thrown when a Standard Schema returns issues for a non-empty env value */\n SchemaValidationFailed = 208,\n /** Thrown when a Standard Schema's `validate` itself throws (e.g. a refinement that crashes) */\n SchemaThrew = 209,\n\n // Other errors\n /** Thrown when delimiter is missing in array converter configuration */\n MissingDelimiter = 301,\n /** Thrown when invalid user-defined configuration is provided */\n InvalidUserDefinedConfig = 302,\n /** Thrown when specified environment files don't exist */\n EnvFilesNotFound = 303,\n /** Thrown when no valid environment key is provided */\n InvalidKeyInput = 304,\n /** Thrown when a required environment value is missing or empty */\n MissingEnvValue = 305,\n /** Thrown when a file-based API (envPaths, baseDir, configureProfiles) is used on a source without filesystem support */\n FileApiUnsupported = 306,\n /** Thrown when an environment value is read before a source is bound via Envapter.useSource */\n NoSourceBound = 307,\n /** Thrown when `merge` is called with no members, or with more than one filesystem-backed source */\n InvalidMergedSource = 308\n}\n\ninterface EnvaptErrorOptions {\n issues?: readonly StandardSchemaV1.Issue[];\n cause?: unknown;\n}\n\n/**\n * The error envapt throws. Its `code` identifies the failure.\n *\n * @example\n * ```ts\n * throw new EnvaptError(EnvaptErrorCodes.InvalidFallback, \"Invalid fallback value provided for environment variable.\");\n * ```\n * @see {@link https://envapt.materwelon.dev/docs/errors#the-error-shape}\n */\nexport class EnvaptError extends Error {\n /** The {@link EnvaptErrorCodes} value identifying what failed. */\n public readonly code: EnvaptErrorCodes;\n /**\n * Populated only for {@link EnvaptErrorCodes.SchemaValidationFailed} (208). For every other\n * code this is `undefined`. Lets callers do `if (err.code === 208) err.issues?.forEach(...)`\n * without a type cast.\n */\n public readonly issues: readonly StandardSchemaV1.Issue[] | undefined;\n\n /** Create an error carrying an {@link EnvaptErrorCodes} code, a message, and optional `cause` / `issues`. */\n constructor(code: EnvaptErrorCodes, message: string, options?: EnvaptErrorOptions) {\n super(message, options?.cause !== undefined ? { cause: options.cause } : undefined);\n this.name = `EnvaptError [${code}]`;\n this.code = code;\n this.issues = options?.issues;\n }\n}\n"],"mappings":"AAQA,IAAY,EAAL,SAAA,EAAA,OAGH,GAAA,EAAA,gBAAA,KAAA,kBAEA,EAAA,EAAA,oBAAA,KAAA,sBAEA,EAAA,EAAA,iCAAA,KAAA,mCAEA,EAAA,EAAA,8BAAA,KAAA,gCAEA,EAAA,EAAA,sBAAA,KAAA,wBAIA,EAAA,EAAA,0BAAA,KAAA,4BAEA,EAAA,EAAA,wBAAA,KAAA,0BAEA,EAAA,EAAA,uBAAA,KAAA,yBAEA,EAAA,EAAA,qBAAA,KAAA,uBAEA,EAAA,EAAA,wBAAA,KAAA,0BAEA,EAAA,EAAA,6BAAA,KAAA,+BAEA,EAAA,EAAA,kBAAA,KAAA,oBAEA,EAAA,EAAA,uBAAA,KAAA,yBAEA,EAAA,EAAA,YAAA,KAAA,cAIA,EAAA,EAAA,iBAAA,KAAA,mBAEA,EAAA,EAAA,yBAAA,KAAA,2BAEA,EAAA,EAAA,iBAAA,KAAA,mBAEA,EAAA,EAAA,gBAAA,KAAA,kBAEA,EAAA,EAAA,gBAAA,KAAA,kBAEA,EAAA,EAAA,mBAAA,KAAA,qBAEA,EAAA,EAAA,cAAA,KAAA,gBAEA,EAAA,EAAA,oBAAA,KAAA,uBACJ,EAAA,CAAA,CAAA,EAgBA,IAAa,EAAb,cAAiC,KAAM,CAEnC,KAMA,OAGA,YAAY,EAAwB,EAAiB,EAA8B,CAC/E,MAAM,EAAS,GAAS,QAAU,IAAA,GAAuC,IAAA,GAA3B,CAAE,MAAO,EAAQ,KAAM,CAAa,EAClF,KAAK,KAAO,gBAAgB,EAAK,GACjC,KAAK,KAAO,EACZ,KAAK,OAAS,GAAS,MAC3B,CACJ"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"recase.mjs","names":[],"sources":["../../../src/infra/recase.ts"],"sourcesContent":["import type { KeyCasing } from '../types';\n\n//
|
|
1
|
+
{"version":3,"file":"recase.mjs","names":[],"sources":["../../../src/infra/recase.ts"],"sourcesContent":["import type { KeyCasing } from '../types';\n\n// if you change this, change the RecaseKey type in types/Casing.ts to match\nexport function recase(name: string, casing?: KeyCasing): string {\n if (casing === undefined) return name;\n const words = name.split('_').filter((word) => word.length > 0);\n if (casing === 'kebab-case') return words.map((word) => word.toLowerCase()).join('-');\n const pascal = words.map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()).join('');\n return casing === 'PascalCase' ? pascal : pascal.charAt(0).toLowerCase() + pascal.slice(1);\n}\n"],"mappings":"AAGA,SAAgB,EAAO,EAAc,EAA4B,CAC7D,GAAI,IAAW,IAAA,GAAW,OAAO,EACjC,IAAM,EAAQ,EAAK,MAAM,GAAG,CAAC,CAAC,OAAQ,GAAS,EAAK,OAAS,CAAC,EAC9D,GAAI,IAAW,aAAc,OAAO,EAAM,IAAK,GAAS,EAAK,YAAY,CAAC,CAAC,CAAC,KAAK,GAAG,EACpF,IAAM,EAAS,EAAM,IAAK,GAAS,EAAK,OAAO,CAAC,CAAC,CAAC,YAAY,EAAI,EAAK,MAAM,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,KAAK,EAAE,EACtG,OAAO,IAAW,aAAe,EAAS,EAAO,OAAO,CAAC,CAAC,CAAC,YAAY,EAAI,EAAO,MAAM,CAAC,CAC7F"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runtime.mjs","names":[],"sources":["../../../src/infra/runtime.ts"],"sourcesContent":["import type { Source } from '../types';\n\n
|
|
1
|
+
{"version":3,"file":"runtime.mjs","names":[],"sources":["../../../src/infra/runtime.ts"],"sourcesContent":["import type { Source } from '../types';\n\n/* v8 ignore start -- @preserve replaced at load on Node so the Node suite never runs these defaults */\nlet sink: (line: string) => void = (line) => {\n // eslint-disable-next-line no-console -- the off-Node fallback log sink\n console.error(line);\n};\nlet envReader: () => Record<string, string> = () => ({});\nlet varReader: ((key: string) => string | undefined) | undefined;\n/* v8 ignore stop */\n\nexport function setRuntimeSink(fn: (line: string) => void): void {\n sink = fn;\n}\n\nexport function writeRuntimeLine(line: string): void {\n sink(line);\n}\n\n// a reader source has an empty snapshot\nexport function readRuntimeVar(key: string): string | undefined {\n const fromSnapshot = envReader()[key];\n if (fromSnapshot !== undefined) return fromSnapshot;\n // ENVAPT_DEBUG reads go through here and must not throw during a config load\n try {\n return varReader?.(key);\n } catch {\n return undefined;\n }\n}\n\nexport function bindRuntimeFromSource(source: Source): void {\n envReader = (): Record<string, string> => source.readVars();\n const readVar = source.readVar;\n varReader = typeof readVar === 'function' ? readVar.bind(source) : undefined;\n}\n"],"mappings":"AAGA,IAAI,EAAgC,GAAS,CAEzC,QAAQ,MAAM,CAAI,CACtB,EACI,OAAiD,CAAC,GAClD,EAOJ,SAAgB,EAAiB,EAAoB,CACjD,EAAK,CAAI,CACb,CAGA,SAAgB,EAAe,EAAiC,CAC5D,IAAM,EAAe,EAAU,CAAC,CAAC,GACjC,GAAI,IAAiB,IAAA,GAAW,OAAO,EAEvC,GAAI,CACA,OAAO,IAAY,CAAG,CAC1B,MAAQ,CACJ,MACJ,CACJ,CAEA,SAAgB,EAAsB,EAAsB,CACxD,MAA0C,EAAO,SAAS,EAC1D,IAAM,EAAU,EAAO,QACvB,EAAY,OAAO,GAAY,WAAa,EAAQ,KAAK,CAAM,EAAI,IAAA,EACvE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PortableSource.mjs","names":[],"sources":["../../../src/sources/PortableSource.ts"],"sourcesContent":["import { coerceToStringRecord } from './coerce';\n\nimport type { BareSource } from '../types';\n\n/**\n * Environment source seeded from an object you provide, for every runtime without a filesystem.
|
|
1
|
+
{"version":3,"file":"PortableSource.mjs","names":[],"sources":["../../../src/sources/PortableSource.ts"],"sourcesContent":["import { coerceToStringRecord } from './coerce';\n\nimport type { BareSource } from '../types';\n\n/**\n * Environment source seeded from an object you provide, for every runtime without a filesystem. Pass\n * the object straight through, such as the config your bundler injects into a browser build (Vite's\n * `import.meta.env`, a webpack `DefinePlugin` global), the Cloudflare `env` binding, a Vercel Edge or\n * Fastly config object, a test fixture, or any plain object. Non-string values are JSON-stringified so\n * the converters still apply. Those values must be JSON-serializable. Without a filesystem the `.env`\n * cascade and file APIs do not apply.\n * @public\n * @see {@link https://envapt.materwelon.dev/docs/sources#the-providers}\n */\nexport class PortableSource implements BareSource {\n /** Always `false`. With no filesystem, the `.env` cascade and file APIs do not apply. */\n readonly supportsFiles = false;\n private readonly vars: Record<string, string>;\n\n /** Seed the source from `vars`. Non-string values are JSON-stringified so the converters still apply. */\n constructor(vars: object) {\n this.vars = coerceToStringRecord(vars);\n }\n\n /** Returns a snapshot clone of the provided object as plain strings. */\n readVars(): Record<string, string> {\n return { ...this.vars };\n }\n}\n"],"mappings":"oDAcA,IAAa,EAAb,KAAkD,CAE9C,cAAyB,GACzB,KAGA,YAAY,EAAc,CACtB,KAAK,KAAO,EAAqB,CAAI,CACzC,CAGA,UAAmC,CAC/B,MAAO,CAAE,GAAG,KAAK,IAAK,CAC1B,CACJ"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"UnboundSource.mjs","names":[],"sources":["../../../src/sources/UnboundSource.ts"],"sourcesContent":["import { EnvaptError, EnvaptErrorCodes } from '../infra/Error';\n\nimport type { BareSource } from '../types';\n\
|
|
1
|
+
{"version":3,"file":"UnboundSource.mjs","names":[],"sources":["../../../src/sources/UnboundSource.ts"],"sourcesContent":["import { EnvaptError, EnvaptErrorCodes } from '../infra/Error';\n\nimport type { BareSource } from '../types';\n\nexport class UnboundSource implements BareSource {\n readonly supportsFiles = false;\n\n readVars(): Record<string, string> {\n throw new EnvaptError(\n EnvaptErrorCodes.NoSourceBound,\n 'No environment source is bound. Call Envapter.useSource(...) with a source such as new PortableSource({...}) before reading.'\n );\n }\n}\n"],"mappings":"iDAIA,IAAa,EAAb,KAAiD,CAC7C,cAAyB,GAEzB,UAAmC,CAC/B,MAAM,IAAI,EAAA,IAEN,8HACJ,CACJ,CACJ"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"coerce.mjs","names":[],"sources":["../../../src/sources/coerce.ts"],"sourcesContent":["//
|
|
1
|
+
{"version":3,"file":"coerce.mjs","names":[],"sources":["../../../src/sources/coerce.ts"],"sourcesContent":["// copies the entries so a later change to the caller's object does not reach the source\nexport function coerceToStringRecord(env: object): Record<string, string> {\n const snapshot: Record<string, string> = {};\n // takes `object` because a Cloudflare Env interface has no index signature\n for (const [key, value] of Object.entries(env as Record<string, unknown>)) {\n if (typeof value === 'string') {\n snapshot[key] = value;\n continue;\n }\n const encoded = JSON.stringify(value);\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- TS lib mistypes JSON.stringify's return as always-string when it is string | undefined at runtime\n if (encoded !== undefined) snapshot[key] = encoded;\n }\n return snapshot;\n}\n"],"mappings":"AACA,SAAgB,EAAqB,EAAqC,CACtE,IAAM,EAAmC,CAAC,EAE1C,IAAK,GAAM,CAAC,EAAK,KAAU,OAAO,QAAQ,CAA8B,EAAG,CACvE,GAAI,OAAO,GAAU,SAAU,CAC3B,EAAS,GAAO,EAChB,QACJ,CACA,IAAM,EAAU,KAAK,UAAU,CAAK,EAEhC,IAAY,IAAA,KAAW,EAAS,GAAO,EAC/C,CACA,OAAO,CACX"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"merge.mjs","names":[],"sources":["../../../src/sources/merge.ts"],"sourcesContent":["import { normalizeSource } from './normalizeSource';\nimport { EnvaptError, EnvaptErrorCodes } from '../infra/Error';\n\nimport type { BareSource, FileCapableSource, Source } from '../types';\n\n/**\n * Compose several sources into one, read last-wins. A later member's `readVars()` value overrides an\n * earlier member's for the same key. A member may be a `(key) => string | undefined` reader for a\n * source that reads one key at a time, and it fills a key missing from every snapshot. Bind the result\n * with `Envapter.useSource`. Throws {@link EnvaptErrorCodes.InvalidMergedSource} with no members or with\n * more than one file-backed member.\n * @public\n * @see {@link https://envapt.materwelon.dev/docs/sources#combining-sources}\n */\nexport function merge(...members: (Source | ((key: string) => string | undefined))[]): Source {\n if (members.length === 0) {\n throw new EnvaptError(EnvaptErrorCodes.InvalidMergedSource, 'merge requires at least one source.');\n }\n\n const sources = members.map(normalizeSource);\n\n const fileMembers = sources.filter((m): m is FileCapableSource => m.supportsFiles === true);\n if (fileMembers.length > 1) {\n throw new EnvaptError(\n EnvaptErrorCodes.InvalidMergedSource,\n 'merge accepts at most one filesystem-backed source, so the .env cascade and file APIs route to a single member.'\n );\n }\n\n const readVars = (): Record<string, string> => {\n const merged: Record<string, string> = {};\n for (const m of sources) Object.assign(merged, m.readVars());\n return merged;\n };\n\n const readers = sources.filter(\n (m): m is Source & { readVar: (key: string) => string | undefined } => typeof m.readVar === 'function'\n );\n const readVar =\n readers.length === 0\n ? undefined\n : (key: string): string | undefined => {\n // last reader
|
|
1
|
+
{"version":3,"file":"merge.mjs","names":[],"sources":["../../../src/sources/merge.ts"],"sourcesContent":["import { normalizeSource } from './normalizeSource';\nimport { EnvaptError, EnvaptErrorCodes } from '../infra/Error';\n\nimport type { BareSource, FileCapableSource, Source } from '../types';\n\n/**\n * Compose several sources into one, read last-wins. A later member's `readVars()` value overrides an\n * earlier member's for the same key. A member may be a `(key) => string | undefined` reader for a\n * source that reads one key at a time, and it fills a key missing from every snapshot. Bind the result\n * with `Envapter.useSource`. Throws {@link EnvaptErrorCodes.InvalidMergedSource} with no members or with\n * more than one file-backed member.\n * @public\n * @see {@link https://envapt.materwelon.dev/docs/sources#combining-sources}\n */\nexport function merge(...members: (Source | ((key: string) => string | undefined))[]): Source {\n if (members.length === 0) {\n throw new EnvaptError(EnvaptErrorCodes.InvalidMergedSource, 'merge requires at least one source.');\n }\n\n const sources = members.map(normalizeSource);\n\n const fileMembers = sources.filter((m): m is FileCapableSource => m.supportsFiles === true);\n if (fileMembers.length > 1) {\n throw new EnvaptError(\n EnvaptErrorCodes.InvalidMergedSource,\n 'merge accepts at most one filesystem-backed source, so the .env cascade and file APIs route to a single member.'\n );\n }\n\n const readVars = (): Record<string, string> => {\n const merged: Record<string, string> = {};\n for (const m of sources) Object.assign(merged, m.readVars());\n return merged;\n };\n\n const readers = sources.filter(\n (m): m is Source & { readVar: (key: string) => string | undefined } => typeof m.readVar === 'function'\n );\n const readVar =\n readers.length === 0\n ? undefined\n : (key: string): string | undefined => {\n // the last reader with a value wins\n for (let i = readers.length - 1; i >= 0; i--) {\n const found = readers[i]?.readVar(key);\n if (found !== undefined) return found;\n }\n return undefined;\n };\n\n const fileMember = fileMembers[0];\n if (!fileMember) {\n const bare: BareSource = { readVars };\n if (readVar) bare.readVar = readVar;\n return bare;\n }\n\n const fileCapable: FileCapableSource = {\n readVars,\n supportsFiles: true,\n readFile: (path, encoding) => fileMember.readFile(path, encoding),\n resolvePath: (baseDir, candidate) => fileMember.resolvePath(baseDir, candidate),\n normalizeBaseDir: (value) => fileMember.normalizeBaseDir(value),\n writeVars: (vars) => fileMember.writeVars(vars)\n };\n if (readVar) fileCapable.readVar = readVar;\n return fileCapable;\n}\n"],"mappings":"yGAcA,SAAgB,EAAM,GAAG,EAAqE,CAC1F,GAAI,EAAQ,SAAW,EACnB,MAAM,IAAI,EAAA,IAAkD,qCAAqC,EAGrG,IAAM,EAAU,EAAQ,IAAI,CAAe,EAErC,EAAc,EAAQ,OAAQ,GAA8B,EAAE,gBAAkB,EAAI,EAC1F,GAAI,EAAY,OAAS,EACrB,MAAM,IAAI,EAAA,IAEN,iHACJ,EAGJ,IAAM,MAAyC,CAC3C,IAAM,EAAiC,CAAC,EACxC,IAAK,IAAM,KAAK,EAAS,OAAO,OAAO,EAAQ,EAAE,SAAS,CAAC,EAC3D,OAAO,CACX,EAEM,EAAU,EAAQ,OACnB,GAAsE,OAAO,EAAE,SAAY,UAChG,EACM,EACF,EAAQ,SAAW,EACb,IAAA,GACC,GAAoC,CAEjC,IAAK,IAAI,EAAI,EAAQ,OAAS,EAAG,GAAK,EAAG,IAAK,CAC1C,IAAM,EAAQ,EAAQ,EAAE,EAAE,QAAQ,CAAG,EACrC,GAAI,IAAU,IAAA,GAAW,OAAO,CACpC,CAEJ,EAEJ,EAAa,EAAY,GAC/B,GAAI,CAAC,EAAY,CACb,IAAM,EAAmB,CAAE,UAAS,EAEpC,OADI,IAAS,EAAK,QAAU,GACrB,CACX,CAEA,IAAM,EAAiC,CACnC,WACA,cAAe,GACf,UAAW,EAAM,IAAa,EAAW,SAAS,EAAM,CAAQ,EAChE,aAAc,EAAS,IAAc,EAAW,YAAY,EAAS,CAAS,EAC9E,iBAAmB,GAAU,EAAW,iBAAiB,CAAK,EAC9D,UAAY,GAAS,EAAW,UAAU,CAAI,CAClD,EAEA,OADI,IAAS,EAAY,QAAU,GAC5B,CACX"}
|
|
@@ -15,16 +15,16 @@ declare const SCALAR: {
|
|
|
15
15
|
readonly Port: "port";
|
|
16
16
|
readonly Email: "email";
|
|
17
17
|
};
|
|
18
|
-
type ConverterToken = (typeof SCALAR)[keyof typeof SCALAR];
|
|
18
|
+
export type ConverterToken = (typeof SCALAR)[keyof typeof SCALAR];
|
|
19
19
|
/**
|
|
20
20
|
* Custom element converter for use inside {@link Converters.array}. Receives the trimmed,
|
|
21
21
|
* non-empty raw string for one array slot and returns the parsed value.
|
|
22
22
|
* @public
|
|
23
23
|
* @see {@link https://envapt.materwelon.dev/docs/converters#custom-converters}
|
|
24
24
|
*/
|
|
25
|
-
type CustomElementConverter<TReturn = unknown> = (raw: string) => TReturn;
|
|
25
|
+
export type CustomElementConverter<TReturn = unknown> = (raw: string) => TReturn;
|
|
26
26
|
type ArrayElement = Exclude<ConverterToken, 'json' | 'regexp'> | CustomElementConverter;
|
|
27
|
-
interface ArrayOf<TElement extends ArrayElement = ArrayElement> {
|
|
27
|
+
export interface ArrayOf<TElement extends ArrayElement = ArrayElement> {
|
|
28
28
|
readonly __envaptKind: 'array';
|
|
29
29
|
readonly of: TElement;
|
|
30
30
|
readonly delimiter: string;
|
|
@@ -57,7 +57,7 @@ declare function buildArrayConverter(opts?: {
|
|
|
57
57
|
* @public
|
|
58
58
|
* @see {@link https://envapt.materwelon.dev/docs/converters#built-in-tokens}
|
|
59
59
|
*/
|
|
60
|
-
declare const Converters: {
|
|
60
|
+
export declare const Converters: {
|
|
61
61
|
readonly array: typeof buildArrayConverter;
|
|
62
62
|
readonly String: "string";
|
|
63
63
|
readonly Number: "number";
|
|
@@ -75,5 +75,4 @@ declare const Converters: {
|
|
|
75
75
|
readonly Email: "email";
|
|
76
76
|
};
|
|
77
77
|
//#endregion
|
|
78
|
-
export { ArrayElement, ArrayOf, ConverterToken, Converters, CustomElementConverter };
|
|
79
78
|
//# sourceMappingURL=Converters.d.mts.map
|
|
@@ -6,11 +6,7 @@ import { SchemaConstraint } from "../types/Schema.mjs";
|
|
|
6
6
|
import { EnvKeyInput } from "../types/Env.mjs";
|
|
7
7
|
import { PrimitiveMethods } from "./PrimitiveMethods.mjs";
|
|
8
8
|
//#region src/core/AdvancedMethods.d.ts
|
|
9
|
-
|
|
10
|
-
* Mixin for advanced methods for environment variable conversion using built-in and custom converters
|
|
11
|
-
* @internal
|
|
12
|
-
*/
|
|
13
|
-
declare class AdvancedMethods extends PrimitiveMethods {
|
|
9
|
+
export declare class AdvancedMethods extends PrimitiveMethods {
|
|
14
10
|
/**
|
|
15
11
|
* Get an environment variable using a built-in converter.
|
|
16
12
|
*
|
|
@@ -59,8 +55,8 @@ declare class AdvancedMethods extends PrimitiveMethods {
|
|
|
59
55
|
* converter (a token, an `array()` token, or a custom parser), and the returned record holds
|
|
60
56
|
* every converted value, all non-undefined. Collects every missing or empty key and throws one
|
|
61
57
|
* `MissingEnvValue` listing them all. Pass a `casing` (`'camelCase'`, `'PascalCase'`, or
|
|
62
|
-
* `'kebab-case'`) to rename the record keys
|
|
63
|
-
*
|
|
58
|
+
* `'kebab-case'`) to rename the record keys. The rename splits each key on underscores, as in
|
|
59
|
+
* SCREAMING_SNAKE env-var names. With no casing the keys stay as-is.
|
|
64
60
|
* @see {@link https://envapt.materwelon.dev/docs/envapter#fail-fast-on-missing-values}
|
|
65
61
|
* @see {@link https://envapt.materwelon.dev/docs/converters#require-a-converted-value}
|
|
66
62
|
*/
|
|
@@ -72,11 +68,10 @@ declare class AdvancedMethods extends PrimitiveMethods {
|
|
|
72
68
|
/**
|
|
73
69
|
* Validate an environment variable through a {@link StandardSchemaV1}-conformant schema
|
|
74
70
|
* (zod, valibot, arktype, etc). Throws `MissingEnvValue` if the env value is absent and
|
|
75
|
-
* no fallback is provided.
|
|
76
|
-
*
|
|
71
|
+
* no fallback is provided. When the value is missing, the fallback is returned as-is and does
|
|
72
|
+
* not pass through the schema.
|
|
77
73
|
*
|
|
78
|
-
* Synchronous schemas only. A
|
|
79
|
-
* `InvalidUserDefinedConfig` throw at the call site.
|
|
74
|
+
* Synchronous schemas only. A `validate` that returns a Promise throws `InvalidUserDefinedConfig`.
|
|
80
75
|
*
|
|
81
76
|
* @example
|
|
82
77
|
* ```ts
|
|
@@ -92,5 +87,4 @@ declare class AdvancedMethods extends PrimitiveMethods {
|
|
|
92
87
|
parse<Schema extends StandardSchemaV1>(key: EnvKeyInput, schema: SchemaConstraint<Schema>, fallback?: InferSchemaOutput<Schema>): InferSchemaOutput<Schema>;
|
|
93
88
|
}
|
|
94
89
|
//#endregion
|
|
95
|
-
export { AdvancedMethods };
|
|
96
90
|
//# sourceMappingURL=AdvancedMethods.d.mts.map
|
|
@@ -3,11 +3,9 @@ import { FileApiMode } from "../types/Options.mjs";
|
|
|
3
3
|
import { EnvKeyInput } from "../types/Env.mjs";
|
|
4
4
|
import { Source } from "../types/Source.mjs";
|
|
5
5
|
//#region src/core/EnvapterBase.d.ts
|
|
6
|
-
|
|
7
|
-
declare abstract class EnvapterBase {
|
|
6
|
+
export declare abstract class EnvapterBase {
|
|
8
7
|
/**
|
|
9
|
-
* Enable or disable strict mode. Default `false`. Setting
|
|
10
|
-
* previously-cached converted values get re-evaluated under the new rule.
|
|
8
|
+
* Enable or disable strict mode. Default `false`. Setting it clears and rebuilds the cache.
|
|
11
9
|
* @see {@link https://envapt.materwelon.dev/docs/strict-mode#what-strict-mode-changes}
|
|
12
10
|
*/
|
|
13
11
|
static set strict(value: boolean);
|
|
@@ -23,13 +21,13 @@ declare abstract class EnvapterBase {
|
|
|
23
21
|
/**
|
|
24
22
|
* Opt-in mirror of dotenv-loaded keys back to `process.env`. Default `false`.
|
|
25
23
|
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
24
|
+
* `envFileOptions.override` controls collisions because only keys the loader wrote are mirrored.
|
|
25
|
+
* With the default `false`, existing `process.env` values stay. With `true`, the file value
|
|
26
|
+
* wins in both the cache and the mirror.
|
|
29
27
|
*
|
|
30
|
-
* Flipping `false → true` mirrors the
|
|
31
|
-
*
|
|
32
|
-
*
|
|
28
|
+
* Flipping `false → true` mirrors the loaded keys immediately without a cache refresh.
|
|
29
|
+
* Flipping `true → false` does not remove anything. Mirrored keys stay in `process.env`
|
|
30
|
+
* until the process exits.
|
|
33
31
|
* @see {@link https://envapt.materwelon.dev/docs/configuration#mirroring-to-processenv}
|
|
34
32
|
*/
|
|
35
33
|
static set syncProcessEnv(value: boolean);
|
|
@@ -37,7 +35,7 @@ declare abstract class EnvapterBase {
|
|
|
37
35
|
/**
|
|
38
36
|
* On the portable build, this controls the filesystem-only config APIs (`envPaths`, `baseDir`,
|
|
39
37
|
* `envFileOptions`, `configureProfiles`, `resetProfiles`). `'warn'` (the default) warns once and
|
|
40
|
-
* no-ops
|
|
38
|
+
* no-ops. `'throw'` throws {@link EnvaptError} `FileApiUnsupported`. The node build runs these
|
|
41
39
|
* APIs normally and this value has no effect there.
|
|
42
40
|
* @see {@link https://envapt.materwelon.dev/docs/compatibility#binding-by-runtime}
|
|
43
41
|
*/
|
|
@@ -65,5 +63,4 @@ declare abstract class EnvapterBase {
|
|
|
65
63
|
getRaw(key: EnvKeyInput): string | undefined;
|
|
66
64
|
}
|
|
67
65
|
//#endregion
|
|
68
|
-
export { EnvapterBase };
|
|
69
66
|
//# sourceMappingURL=EnvapterBase.d.mts.map
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
* @public
|
|
12
12
|
* @see {@link https://envapt.materwelon.dev/docs/environment#detecting-the-environment}
|
|
13
13
|
*/
|
|
14
|
-
declare enum Environment {
|
|
14
|
+
export declare enum Environment {
|
|
15
15
|
/** The default when no environment variable names a known environment. */
|
|
16
16
|
Development = 0,
|
|
17
17
|
/** Selected when an environment variable reads `staging`. */
|
|
@@ -22,5 +22,4 @@ declare enum Environment {
|
|
|
22
22
|
Test = 3
|
|
23
23
|
}
|
|
24
24
|
//#endregion
|
|
25
|
-
export { Environment };
|
|
26
25
|
//# sourceMappingURL=Environment.d.mts.map
|
|
@@ -1,11 +1,7 @@
|
|
|
1
1
|
import { Environment } from "./Environment.mjs";
|
|
2
2
|
import { EnvapterBase } from "./EnvapterBase.mjs";
|
|
3
3
|
//#region src/core/EnvironmentMethods.d.ts
|
|
4
|
-
|
|
5
|
-
* Mixin for environment detection and checking methods
|
|
6
|
-
* @internal
|
|
7
|
-
*/
|
|
8
|
-
declare class EnvironmentMethods extends EnvapterBase {
|
|
4
|
+
export declare class EnvironmentMethods extends EnvapterBase {
|
|
9
5
|
/**
|
|
10
6
|
* Get the current application environment
|
|
11
7
|
* @see {@link https://envapt.materwelon.dev/docs/environment#detecting-the-environment}
|
|
@@ -62,5 +58,4 @@ declare class EnvironmentMethods extends EnvapterBase {
|
|
|
62
58
|
get isTest(): boolean;
|
|
63
59
|
}
|
|
64
60
|
//#endregion
|
|
65
|
-
export { EnvironmentMethods };
|
|
66
61
|
//# sourceMappingURL=EnvironmentMethods.d.mts.map
|
|
@@ -2,10 +2,7 @@ import { ConditionalReturn } from "../types/Conversion.mjs";
|
|
|
2
2
|
import { EnvKeyInput } from "../types/Env.mjs";
|
|
3
3
|
import { EnvironmentMethods } from "./EnvironmentMethods.mjs";
|
|
4
4
|
//#region src/core/PrimitiveMethods.d.ts
|
|
5
|
-
|
|
6
|
-
* @internal
|
|
7
|
-
*/
|
|
8
|
-
declare class PrimitiveMethods extends EnvironmentMethods {
|
|
5
|
+
export declare class PrimitiveMethods extends EnvironmentMethods {
|
|
9
6
|
/**
|
|
10
7
|
* Get a string environment variable with optional fallback.
|
|
11
8
|
* Supports template variable resolution using `${VAR}` syntax.
|
|
@@ -63,5 +60,4 @@ declare class PrimitiveMethods extends EnvironmentMethods {
|
|
|
63
60
|
getSymbol<Default extends symbol | undefined = undefined>(key: EnvKeyInput, def?: Default): ConditionalReturn<symbol, Default>;
|
|
64
61
|
}
|
|
65
62
|
//#endregion
|
|
66
|
-
export { PrimitiveMethods };
|
|
67
63
|
//# sourceMappingURL=PrimitiveMethods.d.mts.map
|
|
@@ -31,11 +31,11 @@ import { EnvaptFieldDecorator } from "../../types/Decorator.mjs";
|
|
|
31
31
|
* }
|
|
32
32
|
* ```
|
|
33
33
|
*/
|
|
34
|
-
declare function Envapt(key: EnvKeyInput, options?: {
|
|
34
|
+
export declare function Envapt(key: EnvKeyInput, options?: {
|
|
35
35
|
fallback: undefined;
|
|
36
36
|
converter?: undefined;
|
|
37
37
|
}): EnvaptFieldDecorator<string | undefined>;
|
|
38
|
-
declare function Envapt<TFallback>(key: EnvKeyInput, options: {
|
|
38
|
+
export declare function Envapt<TFallback>(key: EnvKeyInput, options: {
|
|
39
39
|
converter: (raw: string | undefined, fallback: TFallback) => TFallback;
|
|
40
40
|
fallback: TFallback;
|
|
41
41
|
} | {
|
|
@@ -66,7 +66,7 @@ declare function Envapt<TFallback>(key: EnvKeyInput, options: {
|
|
|
66
66
|
* }
|
|
67
67
|
* ```
|
|
68
68
|
*/
|
|
69
|
-
declare function Envapt<TReturnType>(key: EnvKeyInput, options: {
|
|
69
|
+
export declare function Envapt<TReturnType>(key: EnvKeyInput, options: {
|
|
70
70
|
converter: ConverterFunction<TReturnType>;
|
|
71
71
|
required?: false;
|
|
72
72
|
} | {
|
|
@@ -89,11 +89,11 @@ declare function Envapt<TReturnType>(key: EnvKeyInput, options: {
|
|
|
89
89
|
* \@Envapt('APP_PORT', { converter: Converters.Number, fallback: 3000 })
|
|
90
90
|
* static readonly port: number;
|
|
91
91
|
*
|
|
92
|
-
* // the Url fallback is a URL instance
|
|
92
|
+
* // the Url fallback is a URL instance
|
|
93
93
|
* \@Envapt('APP_URL', { converter: Converters.Url, fallback: new URL('http://localhost:3000') })
|
|
94
94
|
* static readonly url: URL;
|
|
95
95
|
*
|
|
96
|
-
* //
|
|
96
|
+
* // reads CANARY_URL when present, otherwise APP_URL
|
|
97
97
|
* \@Envapt(['CANARY_URL', 'APP_URL'], { converter: Converters.Url })
|
|
98
98
|
* static readonly canaryUrl: URL | undefined;
|
|
99
99
|
*
|
|
@@ -112,7 +112,7 @@ declare function Envapt<TReturnType>(key: EnvKeyInput, options: {
|
|
|
112
112
|
* }
|
|
113
113
|
* ```
|
|
114
114
|
*/
|
|
115
|
-
declare function Envapt<TConverter extends BuiltInConverter | ArrayOf>(key: EnvKeyInput, options: {
|
|
115
|
+
export declare function Envapt<TConverter extends BuiltInConverter | ArrayOf>(key: EnvKeyInput, options: {
|
|
116
116
|
converter: TConverter;
|
|
117
117
|
fallback: InferConverterFallbackType<TConverter>;
|
|
118
118
|
required?: false;
|
|
@@ -120,7 +120,7 @@ declare function Envapt<TConverter extends BuiltInConverter | ArrayOf>(key: EnvK
|
|
|
120
120
|
converter: TConverter;
|
|
121
121
|
required: true;
|
|
122
122
|
}): EnvaptFieldDecorator<InferConverterReturnType<TConverter>>;
|
|
123
|
-
declare function Envapt<TConverter extends BuiltInConverter | ArrayOf>(key: EnvKeyInput, options: {
|
|
123
|
+
export declare function Envapt<TConverter extends BuiltInConverter | ArrayOf>(key: EnvKeyInput, options: {
|
|
124
124
|
converter: TConverter;
|
|
125
125
|
fallback?: undefined;
|
|
126
126
|
required?: false;
|
|
@@ -142,7 +142,7 @@ declare function Envapt<TConverter extends BuiltInConverter | ArrayOf>(key: EnvK
|
|
|
142
142
|
* }
|
|
143
143
|
* ```
|
|
144
144
|
*/
|
|
145
|
-
declare function Envapt<TConstructor extends PrimitiveConstructor>(key: EnvKeyInput, options: {
|
|
145
|
+
export declare function Envapt<TConstructor extends PrimitiveConstructor>(key: EnvKeyInput, options: {
|
|
146
146
|
converter: TConstructor;
|
|
147
147
|
fallback: InferPrimitiveReturnType<TConstructor>;
|
|
148
148
|
required?: false;
|
|
@@ -150,16 +150,15 @@ declare function Envapt<TConstructor extends PrimitiveConstructor>(key: EnvKeyIn
|
|
|
150
150
|
converter: TConstructor;
|
|
151
151
|
required: true;
|
|
152
152
|
}): EnvaptFieldDecorator<InferPrimitiveReturnType<TConstructor>>;
|
|
153
|
-
declare function Envapt<TConstructor extends PrimitiveConstructor>(key: EnvKeyInput, options: {
|
|
153
|
+
export declare function Envapt<TConstructor extends PrimitiveConstructor>(key: EnvKeyInput, options: {
|
|
154
154
|
converter: TConstructor;
|
|
155
155
|
fallback?: undefined;
|
|
156
156
|
required?: false;
|
|
157
157
|
}): EnvaptFieldDecorator<InferPrimitiveReturnType<TConstructor> | undefined>;
|
|
158
158
|
/**
|
|
159
159
|
* Required, no converter (raw string). Throws `MissingEnvValue` on first access when the env
|
|
160
|
-
* value is missing or empty
|
|
161
|
-
*
|
|
162
|
-
* Validator rejects dynamic objects that bypass the types.
|
|
160
|
+
* value is missing or empty. Pairing `required: true` with `fallback` matches no overload at
|
|
161
|
+
* compile time, and a call that bypasses the types throws `InvalidUserDefinedConfig` at runtime.
|
|
163
162
|
*
|
|
164
163
|
* @param key - Environment variable name(s) to load
|
|
165
164
|
* @param options - `{ required: true }`
|
|
@@ -172,17 +171,17 @@ declare function Envapt<TConstructor extends PrimitiveConstructor>(key: EnvKeyIn
|
|
|
172
171
|
* }
|
|
173
172
|
* ```
|
|
174
173
|
*/
|
|
175
|
-
declare function Envapt(key: EnvKeyInput, options: {
|
|
174
|
+
export declare function Envapt(key: EnvKeyInput, options: {
|
|
176
175
|
required: true;
|
|
177
176
|
}): EnvaptFieldDecorator<string>;
|
|
178
177
|
/**
|
|
179
|
-
* A Standard Schema v1 adapter (zod, valibot, arktype, hand-rolled). Synchronous schemas only
|
|
180
|
-
*
|
|
181
|
-
* `schema` with `converter` matches no overload at compile time, and
|
|
182
|
-
*
|
|
178
|
+
* A Standard Schema v1 adapter (zod, valibot, arktype, hand-rolled). Synchronous schemas only.
|
|
179
|
+
* A `validate` that returns a Promise throws `InvalidUserDefinedConfig` at runtime. Pairing
|
|
180
|
+
* `schema` with `converter` matches no overload at compile time, and a call that bypasses the
|
|
181
|
+
* types throws `InvalidUserDefinedConfig` at runtime.
|
|
183
182
|
* @public
|
|
184
183
|
*/
|
|
185
|
-
declare function Envapt<Schema extends StandardSchemaV1>(key: EnvKeyInput, options: {
|
|
184
|
+
export declare function Envapt<Schema extends StandardSchemaV1>(key: EnvKeyInput, options: {
|
|
186
185
|
schema: SchemaConstraint<Schema>;
|
|
187
186
|
fallback?: InferSchemaOutput<Schema>;
|
|
188
187
|
required?: false;
|
|
@@ -191,5 +190,4 @@ declare function Envapt<Schema extends StandardSchemaV1>(key: EnvKeyInput, optio
|
|
|
191
190
|
required: true;
|
|
192
191
|
}): EnvaptFieldDecorator<InferSchemaOutput<Schema>>;
|
|
193
192
|
//#endregion
|
|
194
|
-
export { Envapt };
|
|
195
193
|
//# sourceMappingURL=Envapt.d.mts.map
|