@arkenv/nextjs 1.0.0-alpha.5 → 1.0.0-alpha.6
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/arkenv-internal-Bb4lYS5z.js +2 -0
- package/dist/arkenv-internal-Bb4lYS5z.js.map +1 -0
- package/dist/arkenv-internal-Chq1WyT3.cjs +2 -0
- package/dist/arkenv-internal-Chq1WyT3.cjs.map +1 -0
- package/dist/client.cjs +1 -1
- package/dist/client.d.ts +2 -2
- package/dist/client.js +1 -1
- package/dist/{config-DNJIS9zz.cjs → config-DcFFlKts.cjs} +9 -10
- package/dist/config-DcFFlKts.cjs.map +1 -0
- package/dist/config.cjs +1 -1
- package/dist/config.d.cts.map +1 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +8 -9
- package/dist/config.js.map +1 -1
- package/dist/dist-BGE7U5kQ.cjs +5 -0
- package/dist/dist-BGE7U5kQ.cjs.map +1 -0
- package/dist/dist-Ce46CxRV.js +5 -0
- package/dist/dist-Ce46CxRV.js.map +1 -0
- package/dist/{index-Dypl5Zzg.d.ts → index-NK75Fy2k.d.ts} +1 -1
- package/dist/{index-Dypl5Zzg.d.ts.map → index-NK75Fy2k.d.ts.map} +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.js +1 -1
- package/dist/mock-server-only.cjs +2 -0
- package/dist/mock-server-only.cjs.map +1 -0
- package/dist/mock-server-only.d.cts +1 -0
- package/dist/mock-server-only.d.ts +1 -0
- package/dist/mock-server-only.js +2 -0
- package/dist/mock-server-only.js.map +1 -0
- package/dist/react-server.cjs +1 -1
- package/dist/react-server.d.ts +3 -3
- package/dist/react-server.js +1 -1
- package/dist/{script-DB7wIIvT.js → script-CZOPkAw3.js} +1 -1
- package/dist/{script-DB7wIIvT.js.map → script-CZOPkAw3.js.map} +1 -1
- package/dist/{script-CUpLLTKJ.cjs → script-Dl-R0B9J.cjs} +2 -2
- package/dist/{script-CUpLLTKJ.cjs.map → script-Dl-R0B9J.cjs.map} +1 -1
- package/dist/{script-Ii42Y-xZ.d.ts → script-p6jmwLil.d.ts} +1 -1
- package/dist/{script-Ii42Y-xZ.d.ts.map → script-p6jmwLil.d.ts.map} +1 -1
- package/dist/server.cjs +1 -1
- package/dist/server.d.ts +2 -2
- package/dist/server.js +1 -1
- package/dist/standard/client.cjs +1 -1
- package/dist/standard/client.d.ts +1 -1
- package/dist/standard/client.js +1 -1
- package/dist/standard/config.cjs +1 -1
- package/dist/standard/index.cjs +1 -1
- package/dist/standard/index.d.ts +2 -2
- package/dist/standard/index.js +1 -1
- package/dist/standard/server.cjs +1 -1
- package/dist/standard/server.d.ts +1 -1
- package/dist/standard/server.js +1 -1
- package/dist/standard/shared.cjs +1 -1
- package/dist/standard/shared.d.ts +1 -1
- package/dist/standard/shared.js +1 -1
- package/dist/{types-gP-eTDyz.d.ts → types-BVAJERPl.d.ts} +2 -2
- package/dist/{types-gP-eTDyz.d.ts.map → types-BVAJERPl.d.ts.map} +1 -1
- package/package.json +6 -21
- package/dist/arkenv-internal-Do5bRP26.js +0 -2
- package/dist/arkenv-internal-Do5bRP26.js.map +0 -1
- package/dist/arkenv-internal-Dz0mDRKT.cjs +0 -2
- package/dist/arkenv-internal-Dz0mDRKT.cjs.map +0 -1
- package/dist/config-DNJIS9zz.cjs.map +0 -1
- package/dist/shared.cjs +0 -2
- package/dist/shared.cjs.map +0 -1
- package/dist/shared.d.cts +0 -16
- package/dist/shared.d.cts.map +0 -1
- package/dist/shared.d.ts +0 -16
- package/dist/shared.d.ts.map +0 -1
- package/dist/shared.js +0 -2
- package/dist/shared.js.map +0 -1
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{r as e}from"./dist-Ce46CxRV.js";const t=Symbol.for(`arkenv.extended_env`),n=Symbol.for(`arkenv.keys`),r=Symbol.for(`arkenv.server_only_keys`);let i=!1;function a(a,o,s,c,l){let u={},d={},f={},p=[],m={},h=!1;if(typeof o==`boolean`){process.env.NODE_ENV===`development`&&!i&&(i=!0,e(`Deprecated: The nested layout structure (specifying 'server', 'client', or 'shared' keys in arkenv) is deprecated and will be removed in the next major version. Please migrate to the flat layout. See guide: https://arkenv.js.org/docs/nextjs/faq#how-do-i-define-client-side-variables`));let t=a;u=t?.server||{},d=t?.client||{},f=t?.shared||{},p=t?.extends||[],m=t?.runtimeEnv||{},h=globalThis.__arkenv_force_server__===!0||!!o}else{let e=a||{},t=o||{};if(p=t.extends||[],m=t.runtimeEnv||{},h=globalThis.__arkenv_force_server__===!0||!!s?.isServer,s?.isShared)f=e;else if(s?.strictLayout===`client`)d=e;else if(s?.strictLayout===`server`)u=e;else{let n=t.exposeToClient||t.expose||t.shared||[];for(let t of Object.keys(e))n.includes(t)||t===`NODE_ENV`?f[t]=e[t]:t.startsWith(`NEXT_PUBLIC_`)?d[t]=e[t]:u[t]=e[t]}}let g={},_=new Set,v=new Set;for(let e of Object.keys(u))_.add(e),!(e in d)&&!(e in f)&&v.add(e);for(let e of Object.keys(d))_.add(e);for(let e of Object.keys(f))_.add(e);let y={};if(p&&Array.isArray(p)){for(let e of p)if(e&&(typeof e==`object`||typeof e==`function`)){let i=e[t];if(i){g={...g,...i};let t=e[n];if(t instanceof Set)for(let e of t)_.add(e);let a=e[r];if(a instanceof Set)for(let e of a)v.add(e)}else{for(let e of Object.keys(g))g[e]!==void 0&&(y[e]=g[e]);for(let e of Object.keys(m))m[e]!==void 0&&(y[e]=m[e]);if(h)for(let e of Object.keys(u))y[e]===void 0&&process.env[e]!==void 0&&(y[e]=process.env[e]);let t=c(e,{env:y,safe:!1});g={...g,...t};let n=l(e);for(let e of n)_.add(e),h&&!e.startsWith(`NEXT_PUBLIC_`)&&!s?.isShared&&v.add(e)}}}for(let e of Object.keys(d))v.delete(e);for(let e of Object.keys(f))v.delete(e);for(let e of Object.keys(d))if(!e.startsWith(`NEXT_PUBLIC_`))throw Error(`Client-side environment variables must be prefixed with 'NEXT_PUBLIC_'. Found invalid key: ${e}`);let b=[...Object.keys(d),...Object.keys(f)];for(let e of b)if(!(e in m))throw Error(`Missing key in runtimeEnv: ${e}. All client and shared environment variables must be explicitly destructured in runtimeEnv.`);for(let e of Object.keys(m))if(!_.has(e))throw Error(`Environment variable '${e}' is passed to runtimeEnv but is not defined in the schema.`);for(let e of Object.keys(g))g[e]!==void 0&&(y[e]=g[e]);let x=typeof globalThis<`u`?globalThis.__arkenv_env__:void 0;for(let e of Object.keys(m))m[e]!==void 0&&(y[e]=m[e]),x&&x[e]!==void 0&&(e.startsWith(`NEXT_PUBLIC_`)||e in d||e in f)&&(y[e]=x[e]);if(h)for(let e of Object.keys(u))y[e]===void 0&&process.env[e]!==void 0&&(y[e]=process.env[e]);let S=c(h?{...u,...d,...f}:{...d,...f},{env:y,safe:!1}),C={...g,...S};return new Proxy(C,{get(e,i,a){if(i===t)return e;if(i===n)return _;if(i===r)return v;if(typeof i==`symbol`)return Reflect.get(e,i,a);if(typeof i==`string`){if(v.has(i)&&!h)throw Error(`ArkEnv Error: Attempted to access server environment variable '${i}' on the client.`);if(!_.has(i)&&!(i in Object.prototype)&&!(i===`__esModule`||i===`$$typeof`||i===`toJSON`||i===`inspect`))throw Error(`Environment variable '${i}' is not defined in the schema.`)}return Reflect.get(e,i,a)}})}export{a as t};
|
|
2
|
+
//# sourceMappingURL=arkenv-internal-Bb4lYS5z.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"arkenv-internal-Bb4lYS5z.js","names":[],"sources":["../src/arkenv-internal.ts"],"sourcesContent":["import type { Dict, SchemaShape } from \"@repo/types\";\nimport { logBuildWarning } from \"@repo/utils\";\n\nexport const EXTENDED_ENV = Symbol.for(\"arkenv.extended_env\");\nexport const ENV_KEYS = Symbol.for(\"arkenv.keys\");\nexport const SERVER_ONLY_KEYS = Symbol.for(\"arkenv.server_only_keys\");\n\nexport type LegacyNestedSchema = {\n\tserver?: SchemaShape;\n\tclient?: SchemaShape;\n\tshared?: SchemaShape;\n\textends?: readonly unknown[];\n\truntimeEnv?: Dict<string>;\n};\n\nexport type FlatSchemaOptions = {\n\textends?: readonly unknown[];\n\truntimeEnv?: Dict<string>;\n\t/** @deprecated Use `exposeToClient` instead. */\n\texpose?: readonly string[];\n\t/** @deprecated Use `exposeToClient` instead. */\n\tshared?: readonly string[];\n\texposeToClient?: readonly string[];\n};\n\nlet hasWarnedLegacy = false;\n\n/**\n * Validate and wrap environment variables in a security proxy.\n *\n * @internal\n */\nexport function arkenvInternal(\n\tschemaOrOptions: SchemaShape | LegacyNestedSchema | null | undefined,\n\toptionsOrIsServer: FlatSchemaOptions | boolean | null | undefined,\n\tcontext:\n\t\t| {\n\t\t\t\tisServer: boolean;\n\t\t\t\tisShared?: boolean;\n\t\t\t\tstrictLayout?: \"client\" | \"server\";\n\t\t }\n\t\t| undefined,\n\t/** The core arkenv validation function (either `@arkenv/core` or `@arkenv/standard`). */\n\tcoreArkenv: (schema: any, config?: any) => Record<string, unknown>,\n\t/** Extracts the declared key names from a schema object. */\n\tgetSchemaKeysArg: (schema: SchemaShape) => string[],\n): unknown {\n\tlet server: SchemaShape = {};\n\tlet client: SchemaShape = {};\n\tlet shared: SchemaShape = {};\n\tlet extendsList: readonly unknown[] = [];\n\tlet runtimeEnv: Dict<string> = {};\n\tlet isServer = false;\n\n\tif (typeof optionsOrIsServer === \"boolean\") {\n\t\tif (process.env.NODE_ENV === \"development\" && !hasWarnedLegacy) {\n\t\t\thasWarnedLegacy = true;\n\t\t\tlogBuildWarning(\n\t\t\t\t\"Deprecated: The nested layout structure (specifying 'server', 'client', or 'shared' keys in arkenv) is deprecated and will be removed in the next major version. Please migrate to the flat layout. See guide: https://arkenv.js.org/docs/nextjs/faq#how-do-i-define-client-side-variables\",\n\t\t\t);\n\t\t}\n\t\t// Old nested schema behavior (backward compatible)\n\t\tconst legacySchema = schemaOrOptions as\n\t\t\t| LegacyNestedSchema\n\t\t\t| null\n\t\t\t| undefined;\n\t\tserver = (legacySchema?.server || {}) as SchemaShape;\n\t\tclient = (legacySchema?.client || {}) as SchemaShape;\n\t\tshared = (legacySchema?.shared || {}) as SchemaShape;\n\t\textendsList = legacySchema?.extends || [];\n\t\truntimeEnv = (legacySchema?.runtimeEnv || {}) as Dict<string>;\n\t\tisServer =\n\t\t\t(globalThis as any).__arkenv_force_server__ === true ||\n\t\t\t!!optionsOrIsServer;\n\t} else {\n\t\t// New flat schema behavior\n\t\tconst flatSchema = (schemaOrOptions || {}) as SchemaShape;\n\t\tconst options = optionsOrIsServer || {};\n\t\textendsList = options.extends || [];\n\t\truntimeEnv = (options.runtimeEnv || {}) as Dict<string>;\n\t\tisServer =\n\t\t\t(globalThis as any).__arkenv_force_server__ === true ||\n\t\t\t!!context?.isServer;\n\n\t\tif (context?.isShared) {\n\t\t\tshared = flatSchema;\n\t\t} else if (context?.strictLayout === \"client\") {\n\t\t\tclient = flatSchema;\n\t\t} else if (context?.strictLayout === \"server\") {\n\t\t\tserver = flatSchema;\n\t\t} else {\n\t\t\tconst exposedKeys =\n\t\t\t\toptions.exposeToClient || options.expose || options.shared || [];\n\t\t\tfor (const key of Object.keys(flatSchema)) {\n\t\t\t\t// NODE_ENV is implicitly shared as Next.js automatically inlines and replaces references to process.env.NODE_ENV in browser bundles.\n\t\t\t\t// See: https://nextjs.org/docs/app/guides/environment-variables\n\t\t\t\tif (exposedKeys.includes(key) || key === \"NODE_ENV\") {\n\t\t\t\t\tshared[key] = flatSchema[key];\n\t\t\t\t} else if (key.startsWith(\"NEXT_PUBLIC_\")) {\n\t\t\t\t\tclient[key] = flatSchema[key];\n\t\t\t\t} else {\n\t\t\t\t\tserver[key] = flatSchema[key];\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tlet extendedEnvValues: Record<string, unknown> = {};\n\tconst allKeys = new Set<string>();\n\tconst serverOnlyKeys = new Set<string>();\n\n\t// Add local keys\n\tfor (const key of Object.keys(server)) {\n\t\tallKeys.add(key);\n\t\tif (!(key in client) && !(key in shared)) {\n\t\t\tserverOnlyKeys.add(key);\n\t\t}\n\t}\n\tfor (const key of Object.keys(client)) {\n\t\tallKeys.add(key);\n\t}\n\tfor (const key of Object.keys(shared)) {\n\t\tallKeys.add(key);\n\t}\n\n\t// Prepare combined environment for core validation\n\tconst combinedEnv: Record<string, unknown> = {};\n\n\t// Process extended environments\n\tif (extendsList && Array.isArray(extendsList)) {\n\t\tfor (const ext of extendsList) {\n\t\t\tif (ext && (typeof ext === \"object\" || typeof ext === \"function\")) {\n\t\t\t\tconst raw = (ext as Record<string | symbol, unknown>)[EXTENDED_ENV];\n\t\t\t\tif (raw) {\n\t\t\t\t\textendedEnvValues = {\n\t\t\t\t\t\t...extendedEnvValues,\n\t\t\t\t\t\t...(raw as Record<string, unknown>),\n\t\t\t\t\t};\n\n\t\t\t\t\tconst extKeys = (ext as Record<string | symbol, unknown>)[ENV_KEYS];\n\t\t\t\t\tif (extKeys instanceof Set) {\n\t\t\t\t\t\tfor (const key of extKeys) allKeys.add(key);\n\t\t\t\t\t}\n\n\t\t\t\t\tconst extServerOnly = (ext as Record<string | symbol, unknown>)[\n\t\t\t\t\t\tSERVER_ONLY_KEYS\n\t\t\t\t\t];\n\t\t\t\t\tif (extServerOnly instanceof Set) {\n\t\t\t\t\t\tfor (const key of extServerOnly) serverOnlyKeys.add(key);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// Prepare what we have so far for validating the extended schema\n\t\t\t\t\tfor (const key of Object.keys(extendedEnvValues)) {\n\t\t\t\t\t\tif (extendedEnvValues[key] !== undefined) {\n\t\t\t\t\t\t\tcombinedEnv[key] = extendedEnvValues[key];\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tfor (const key of Object.keys(runtimeEnv)) {\n\t\t\t\t\t\tif (runtimeEnv[key] !== undefined) {\n\t\t\t\t\t\t\tcombinedEnv[key] = runtimeEnv[key];\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif (isServer) {\n\t\t\t\t\t\tfor (const key of Object.keys(server)) {\n\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\tcombinedEnv[key] === undefined &&\n\t\t\t\t\t\t\t\tprocess.env[key] !== undefined\n\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\tcombinedEnv[key] = process.env[key];\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\tconst validated = coreArkenv(ext as SchemaShape, {\n\t\t\t\t\t\tenv: combinedEnv as Dict<string>,\n\t\t\t\t\t\tsafe: false,\n\t\t\t\t\t});\n\t\t\t\t\textendedEnvValues = { ...extendedEnvValues, ...validated };\n\n\t\t\t\t\tconst extKeys = getSchemaKeysArg(ext);\n\t\t\t\t\tfor (const key of extKeys) {\n\t\t\t\t\t\tallKeys.add(key);\n\t\t\t\t\t\t// Only classify as server-only when running on the server and the key is not public.\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\tisServer &&\n\t\t\t\t\t\t\t!key.startsWith(\"NEXT_PUBLIC_\") &&\n\t\t\t\t\t\t\t!context?.isShared\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\tserverOnlyKeys.add(key);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Remove keys from serverOnlyKeys if they are defined as client or shared locally\n\tfor (const key of Object.keys(client)) {\n\t\tserverOnlyKeys.delete(key);\n\t}\n\tfor (const key of Object.keys(shared)) {\n\t\tserverOnlyKeys.delete(key);\n\t}\n\n\t// Validate options\n\t// For client keys, check prefix\n\tfor (const key of Object.keys(client)) {\n\t\tif (!key.startsWith(\"NEXT_PUBLIC_\")) {\n\t\t\tthrow new Error(\n\t\t\t\t`Client-side environment variables must be prefixed with 'NEXT_PUBLIC_'. Found invalid key: ${key}`,\n\t\t\t);\n\t\t}\n\t}\n\n\t// Check runtimeEnv has all local client and shared keys\n\tconst requiredKeys = [...Object.keys(client), ...Object.keys(shared)];\n\tfor (const key of requiredKeys) {\n\t\tif (!(key in runtimeEnv)) {\n\t\t\tthrow new Error(\n\t\t\t\t`Missing key in runtimeEnv: ${key}. All client and shared environment variables must be explicitly destructured in runtimeEnv.`,\n\t\t\t);\n\t\t}\n\t}\n\n\t// Check runtimeEnv does not have any keys not defined in the schema (allKeys)\n\tfor (const key of Object.keys(runtimeEnv)) {\n\t\tif (!allKeys.has(key)) {\n\t\t\tthrow new Error(\n\t\t\t\t`Environment variable '${key}' is passed to runtimeEnv but is not defined in the schema.`,\n\t\t\t);\n\t\t}\n\t}\n\n\t// Build final combinedEnv\n\tfor (const key of Object.keys(extendedEnvValues)) {\n\t\tif (extendedEnvValues[key] !== undefined) {\n\t\t\tcombinedEnv[key] = extendedEnvValues[key];\n\t\t}\n\t}\n\n\tconst globalEnv =\n\t\ttypeof globalThis !== \"undefined\"\n\t\t\t? (globalThis as any).__arkenv_env__\n\t\t\t: undefined;\n\n\tfor (const key of Object.keys(runtimeEnv)) {\n\t\tif (runtimeEnv[key] !== undefined) {\n\t\t\tcombinedEnv[key] = runtimeEnv[key];\n\t\t}\n\t\tif (globalEnv && globalEnv[key] !== undefined) {\n\t\t\tif (key.startsWith(\"NEXT_PUBLIC_\") || key in client || key in shared) {\n\t\t\t\tcombinedEnv[key] = globalEnv[key];\n\t\t\t}\n\t\t}\n\t}\n\n\tif (isServer) {\n\t\t// Fallback server keys to process.env if omitted or undefined\n\t\tfor (const key of Object.keys(server)) {\n\t\t\tif (combinedEnv[key] === undefined && process.env[key] !== undefined) {\n\t\t\t\tcombinedEnv[key] = process.env[key];\n\t\t\t}\n\t\t}\n\t}\n\n\t// Select schema based on environment\n\tconst schema = isServer\n\t\t? { ...server, ...client, ...shared }\n\t\t: { ...client, ...shared };\n\n\t// Run core validation\n\tconst validated = coreArkenv(schema as SchemaShape, {\n\t\tenv: combinedEnv as Dict<string>,\n\t\tsafe: false,\n\t});\n\n\tconst mergedValidated = { ...extendedEnvValues, ...validated };\n\n\t// Return a Proxy wrapper\n\treturn new Proxy(mergedValidated, {\n\t\tget(target, prop, receiver) {\n\t\t\tif (prop === EXTENDED_ENV) {\n\t\t\t\treturn target;\n\t\t\t}\n\t\t\tif (prop === ENV_KEYS) {\n\t\t\t\treturn allKeys;\n\t\t\t}\n\t\t\tif (prop === SERVER_ONLY_KEYS) {\n\t\t\t\treturn serverOnlyKeys;\n\t\t\t}\n\n\t\t\t// Always allow symbol properties (Symbol.iterator, Symbol.toStringTag, etc.)\n\t\t\tif (typeof prop === \"symbol\") {\n\t\t\t\treturn Reflect.get(target, prop, receiver);\n\t\t\t}\n\n\t\t\tif (typeof prop === \"string\") {\n\t\t\t\tif (serverOnlyKeys.has(prop) && !isServer) {\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t`ArkEnv Error: Attempted to access server environment variable '${prop}' on the client.`,\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\t// Allow schema keys and standard Object prototype properties\n\t\t\t\tif (!allKeys.has(prop) && !(prop in Object.prototype)) {\n\t\t\t\t\t// Fallback for bundler/framework-specific properties that bypass the prototype\n\t\t\t\t\tconst isCommonKey =\n\t\t\t\t\t\tprop === \"__esModule\" ||\n\t\t\t\t\t\tprop === \"$$typeof\" ||\n\t\t\t\t\t\tprop === \"toJSON\" ||\n\t\t\t\t\t\tprop === \"inspect\";\n\n\t\t\t\t\tif (!isCommonKey) {\n\t\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t\t`Environment variable '${prop}' is not defined in the schema.`,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn Reflect.get(target, prop, receiver);\n\t\t},\n\t});\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
const e=require(`./dist-BGE7U5kQ.cjs`),t=Symbol.for(`arkenv.extended_env`),n=Symbol.for(`arkenv.keys`),r=Symbol.for(`arkenv.server_only_keys`);let i=!1;function a(a,o,s,c,l){let u={},d={},f={},p=[],m={},h=!1;if(typeof o==`boolean`){process.env.NODE_ENV===`development`&&!i&&(i=!0,e.r(`Deprecated: The nested layout structure (specifying 'server', 'client', or 'shared' keys in arkenv) is deprecated and will be removed in the next major version. Please migrate to the flat layout. See guide: https://arkenv.js.org/docs/nextjs/faq#how-do-i-define-client-side-variables`));let t=a;u=t?.server||{},d=t?.client||{},f=t?.shared||{},p=t?.extends||[],m=t?.runtimeEnv||{},h=globalThis.__arkenv_force_server__===!0||!!o}else{let e=a||{},t=o||{};if(p=t.extends||[],m=t.runtimeEnv||{},h=globalThis.__arkenv_force_server__===!0||!!s?.isServer,s?.isShared)f=e;else if(s?.strictLayout===`client`)d=e;else if(s?.strictLayout===`server`)u=e;else{let n=t.exposeToClient||t.expose||t.shared||[];for(let t of Object.keys(e))n.includes(t)||t===`NODE_ENV`?f[t]=e[t]:t.startsWith(`NEXT_PUBLIC_`)?d[t]=e[t]:u[t]=e[t]}}let g={},_=new Set,v=new Set;for(let e of Object.keys(u))_.add(e),!(e in d)&&!(e in f)&&v.add(e);for(let e of Object.keys(d))_.add(e);for(let e of Object.keys(f))_.add(e);let y={};if(p&&Array.isArray(p)){for(let e of p)if(e&&(typeof e==`object`||typeof e==`function`)){let i=e[t];if(i){g={...g,...i};let t=e[n];if(t instanceof Set)for(let e of t)_.add(e);let a=e[r];if(a instanceof Set)for(let e of a)v.add(e)}else{for(let e of Object.keys(g))g[e]!==void 0&&(y[e]=g[e]);for(let e of Object.keys(m))m[e]!==void 0&&(y[e]=m[e]);if(h)for(let e of Object.keys(u))y[e]===void 0&&process.env[e]!==void 0&&(y[e]=process.env[e]);let t=c(e,{env:y,safe:!1});g={...g,...t};let n=l(e);for(let e of n)_.add(e),h&&!e.startsWith(`NEXT_PUBLIC_`)&&!s?.isShared&&v.add(e)}}}for(let e of Object.keys(d))v.delete(e);for(let e of Object.keys(f))v.delete(e);for(let e of Object.keys(d))if(!e.startsWith(`NEXT_PUBLIC_`))throw Error(`Client-side environment variables must be prefixed with 'NEXT_PUBLIC_'. Found invalid key: ${e}`);let b=[...Object.keys(d),...Object.keys(f)];for(let e of b)if(!(e in m))throw Error(`Missing key in runtimeEnv: ${e}. All client and shared environment variables must be explicitly destructured in runtimeEnv.`);for(let e of Object.keys(m))if(!_.has(e))throw Error(`Environment variable '${e}' is passed to runtimeEnv but is not defined in the schema.`);for(let e of Object.keys(g))g[e]!==void 0&&(y[e]=g[e]);let x=typeof globalThis<`u`?globalThis.__arkenv_env__:void 0;for(let e of Object.keys(m))m[e]!==void 0&&(y[e]=m[e]),x&&x[e]!==void 0&&(e.startsWith(`NEXT_PUBLIC_`)||e in d||e in f)&&(y[e]=x[e]);if(h)for(let e of Object.keys(u))y[e]===void 0&&process.env[e]!==void 0&&(y[e]=process.env[e]);let S=c(h?{...u,...d,...f}:{...d,...f},{env:y,safe:!1}),C={...g,...S};return new Proxy(C,{get(e,i,a){if(i===t)return e;if(i===n)return _;if(i===r)return v;if(typeof i==`symbol`)return Reflect.get(e,i,a);if(typeof i==`string`){if(v.has(i)&&!h)throw Error(`ArkEnv Error: Attempted to access server environment variable '${i}' on the client.`);if(!_.has(i)&&!(i in Object.prototype)&&!(i===`__esModule`||i===`$$typeof`||i===`toJSON`||i===`inspect`))throw Error(`Environment variable '${i}' is not defined in the schema.`)}return Reflect.get(e,i,a)}})}Object.defineProperty(exports,`t`,{enumerable:!0,get:function(){return a}});
|
|
2
|
+
//# sourceMappingURL=arkenv-internal-Chq1WyT3.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"arkenv-internal-Chq1WyT3.cjs","names":[],"sources":["../src/arkenv-internal.ts"],"sourcesContent":["import type { Dict, SchemaShape } from \"@repo/types\";\nimport { logBuildWarning } from \"@repo/utils\";\n\nexport const EXTENDED_ENV = Symbol.for(\"arkenv.extended_env\");\nexport const ENV_KEYS = Symbol.for(\"arkenv.keys\");\nexport const SERVER_ONLY_KEYS = Symbol.for(\"arkenv.server_only_keys\");\n\nexport type LegacyNestedSchema = {\n\tserver?: SchemaShape;\n\tclient?: SchemaShape;\n\tshared?: SchemaShape;\n\textends?: readonly unknown[];\n\truntimeEnv?: Dict<string>;\n};\n\nexport type FlatSchemaOptions = {\n\textends?: readonly unknown[];\n\truntimeEnv?: Dict<string>;\n\t/** @deprecated Use `exposeToClient` instead. */\n\texpose?: readonly string[];\n\t/** @deprecated Use `exposeToClient` instead. */\n\tshared?: readonly string[];\n\texposeToClient?: readonly string[];\n};\n\nlet hasWarnedLegacy = false;\n\n/**\n * Validate and wrap environment variables in a security proxy.\n *\n * @internal\n */\nexport function arkenvInternal(\n\tschemaOrOptions: SchemaShape | LegacyNestedSchema | null | undefined,\n\toptionsOrIsServer: FlatSchemaOptions | boolean | null | undefined,\n\tcontext:\n\t\t| {\n\t\t\t\tisServer: boolean;\n\t\t\t\tisShared?: boolean;\n\t\t\t\tstrictLayout?: \"client\" | \"server\";\n\t\t }\n\t\t| undefined,\n\t/** The core arkenv validation function (either `@arkenv/core` or `@arkenv/standard`). */\n\tcoreArkenv: (schema: any, config?: any) => Record<string, unknown>,\n\t/** Extracts the declared key names from a schema object. */\n\tgetSchemaKeysArg: (schema: SchemaShape) => string[],\n): unknown {\n\tlet server: SchemaShape = {};\n\tlet client: SchemaShape = {};\n\tlet shared: SchemaShape = {};\n\tlet extendsList: readonly unknown[] = [];\n\tlet runtimeEnv: Dict<string> = {};\n\tlet isServer = false;\n\n\tif (typeof optionsOrIsServer === \"boolean\") {\n\t\tif (process.env.NODE_ENV === \"development\" && !hasWarnedLegacy) {\n\t\t\thasWarnedLegacy = true;\n\t\t\tlogBuildWarning(\n\t\t\t\t\"Deprecated: The nested layout structure (specifying 'server', 'client', or 'shared' keys in arkenv) is deprecated and will be removed in the next major version. Please migrate to the flat layout. See guide: https://arkenv.js.org/docs/nextjs/faq#how-do-i-define-client-side-variables\",\n\t\t\t);\n\t\t}\n\t\t// Old nested schema behavior (backward compatible)\n\t\tconst legacySchema = schemaOrOptions as\n\t\t\t| LegacyNestedSchema\n\t\t\t| null\n\t\t\t| undefined;\n\t\tserver = (legacySchema?.server || {}) as SchemaShape;\n\t\tclient = (legacySchema?.client || {}) as SchemaShape;\n\t\tshared = (legacySchema?.shared || {}) as SchemaShape;\n\t\textendsList = legacySchema?.extends || [];\n\t\truntimeEnv = (legacySchema?.runtimeEnv || {}) as Dict<string>;\n\t\tisServer =\n\t\t\t(globalThis as any).__arkenv_force_server__ === true ||\n\t\t\t!!optionsOrIsServer;\n\t} else {\n\t\t// New flat schema behavior\n\t\tconst flatSchema = (schemaOrOptions || {}) as SchemaShape;\n\t\tconst options = optionsOrIsServer || {};\n\t\textendsList = options.extends || [];\n\t\truntimeEnv = (options.runtimeEnv || {}) as Dict<string>;\n\t\tisServer =\n\t\t\t(globalThis as any).__arkenv_force_server__ === true ||\n\t\t\t!!context?.isServer;\n\n\t\tif (context?.isShared) {\n\t\t\tshared = flatSchema;\n\t\t} else if (context?.strictLayout === \"client\") {\n\t\t\tclient = flatSchema;\n\t\t} else if (context?.strictLayout === \"server\") {\n\t\t\tserver = flatSchema;\n\t\t} else {\n\t\t\tconst exposedKeys =\n\t\t\t\toptions.exposeToClient || options.expose || options.shared || [];\n\t\t\tfor (const key of Object.keys(flatSchema)) {\n\t\t\t\t// NODE_ENV is implicitly shared as Next.js automatically inlines and replaces references to process.env.NODE_ENV in browser bundles.\n\t\t\t\t// See: https://nextjs.org/docs/app/guides/environment-variables\n\t\t\t\tif (exposedKeys.includes(key) || key === \"NODE_ENV\") {\n\t\t\t\t\tshared[key] = flatSchema[key];\n\t\t\t\t} else if (key.startsWith(\"NEXT_PUBLIC_\")) {\n\t\t\t\t\tclient[key] = flatSchema[key];\n\t\t\t\t} else {\n\t\t\t\t\tserver[key] = flatSchema[key];\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tlet extendedEnvValues: Record<string, unknown> = {};\n\tconst allKeys = new Set<string>();\n\tconst serverOnlyKeys = new Set<string>();\n\n\t// Add local keys\n\tfor (const key of Object.keys(server)) {\n\t\tallKeys.add(key);\n\t\tif (!(key in client) && !(key in shared)) {\n\t\t\tserverOnlyKeys.add(key);\n\t\t}\n\t}\n\tfor (const key of Object.keys(client)) {\n\t\tallKeys.add(key);\n\t}\n\tfor (const key of Object.keys(shared)) {\n\t\tallKeys.add(key);\n\t}\n\n\t// Prepare combined environment for core validation\n\tconst combinedEnv: Record<string, unknown> = {};\n\n\t// Process extended environments\n\tif (extendsList && Array.isArray(extendsList)) {\n\t\tfor (const ext of extendsList) {\n\t\t\tif (ext && (typeof ext === \"object\" || typeof ext === \"function\")) {\n\t\t\t\tconst raw = (ext as Record<string | symbol, unknown>)[EXTENDED_ENV];\n\t\t\t\tif (raw) {\n\t\t\t\t\textendedEnvValues = {\n\t\t\t\t\t\t...extendedEnvValues,\n\t\t\t\t\t\t...(raw as Record<string, unknown>),\n\t\t\t\t\t};\n\n\t\t\t\t\tconst extKeys = (ext as Record<string | symbol, unknown>)[ENV_KEYS];\n\t\t\t\t\tif (extKeys instanceof Set) {\n\t\t\t\t\t\tfor (const key of extKeys) allKeys.add(key);\n\t\t\t\t\t}\n\n\t\t\t\t\tconst extServerOnly = (ext as Record<string | symbol, unknown>)[\n\t\t\t\t\t\tSERVER_ONLY_KEYS\n\t\t\t\t\t];\n\t\t\t\t\tif (extServerOnly instanceof Set) {\n\t\t\t\t\t\tfor (const key of extServerOnly) serverOnlyKeys.add(key);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// Prepare what we have so far for validating the extended schema\n\t\t\t\t\tfor (const key of Object.keys(extendedEnvValues)) {\n\t\t\t\t\t\tif (extendedEnvValues[key] !== undefined) {\n\t\t\t\t\t\t\tcombinedEnv[key] = extendedEnvValues[key];\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tfor (const key of Object.keys(runtimeEnv)) {\n\t\t\t\t\t\tif (runtimeEnv[key] !== undefined) {\n\t\t\t\t\t\t\tcombinedEnv[key] = runtimeEnv[key];\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif (isServer) {\n\t\t\t\t\t\tfor (const key of Object.keys(server)) {\n\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\tcombinedEnv[key] === undefined &&\n\t\t\t\t\t\t\t\tprocess.env[key] !== undefined\n\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\tcombinedEnv[key] = process.env[key];\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\tconst validated = coreArkenv(ext as SchemaShape, {\n\t\t\t\t\t\tenv: combinedEnv as Dict<string>,\n\t\t\t\t\t\tsafe: false,\n\t\t\t\t\t});\n\t\t\t\t\textendedEnvValues = { ...extendedEnvValues, ...validated };\n\n\t\t\t\t\tconst extKeys = getSchemaKeysArg(ext);\n\t\t\t\t\tfor (const key of extKeys) {\n\t\t\t\t\t\tallKeys.add(key);\n\t\t\t\t\t\t// Only classify as server-only when running on the server and the key is not public.\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\tisServer &&\n\t\t\t\t\t\t\t!key.startsWith(\"NEXT_PUBLIC_\") &&\n\t\t\t\t\t\t\t!context?.isShared\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\tserverOnlyKeys.add(key);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Remove keys from serverOnlyKeys if they are defined as client or shared locally\n\tfor (const key of Object.keys(client)) {\n\t\tserverOnlyKeys.delete(key);\n\t}\n\tfor (const key of Object.keys(shared)) {\n\t\tserverOnlyKeys.delete(key);\n\t}\n\n\t// Validate options\n\t// For client keys, check prefix\n\tfor (const key of Object.keys(client)) {\n\t\tif (!key.startsWith(\"NEXT_PUBLIC_\")) {\n\t\t\tthrow new Error(\n\t\t\t\t`Client-side environment variables must be prefixed with 'NEXT_PUBLIC_'. Found invalid key: ${key}`,\n\t\t\t);\n\t\t}\n\t}\n\n\t// Check runtimeEnv has all local client and shared keys\n\tconst requiredKeys = [...Object.keys(client), ...Object.keys(shared)];\n\tfor (const key of requiredKeys) {\n\t\tif (!(key in runtimeEnv)) {\n\t\t\tthrow new Error(\n\t\t\t\t`Missing key in runtimeEnv: ${key}. All client and shared environment variables must be explicitly destructured in runtimeEnv.`,\n\t\t\t);\n\t\t}\n\t}\n\n\t// Check runtimeEnv does not have any keys not defined in the schema (allKeys)\n\tfor (const key of Object.keys(runtimeEnv)) {\n\t\tif (!allKeys.has(key)) {\n\t\t\tthrow new Error(\n\t\t\t\t`Environment variable '${key}' is passed to runtimeEnv but is not defined in the schema.`,\n\t\t\t);\n\t\t}\n\t}\n\n\t// Build final combinedEnv\n\tfor (const key of Object.keys(extendedEnvValues)) {\n\t\tif (extendedEnvValues[key] !== undefined) {\n\t\t\tcombinedEnv[key] = extendedEnvValues[key];\n\t\t}\n\t}\n\n\tconst globalEnv =\n\t\ttypeof globalThis !== \"undefined\"\n\t\t\t? (globalThis as any).__arkenv_env__\n\t\t\t: undefined;\n\n\tfor (const key of Object.keys(runtimeEnv)) {\n\t\tif (runtimeEnv[key] !== undefined) {\n\t\t\tcombinedEnv[key] = runtimeEnv[key];\n\t\t}\n\t\tif (globalEnv && globalEnv[key] !== undefined) {\n\t\t\tif (key.startsWith(\"NEXT_PUBLIC_\") || key in client || key in shared) {\n\t\t\t\tcombinedEnv[key] = globalEnv[key];\n\t\t\t}\n\t\t}\n\t}\n\n\tif (isServer) {\n\t\t// Fallback server keys to process.env if omitted or undefined\n\t\tfor (const key of Object.keys(server)) {\n\t\t\tif (combinedEnv[key] === undefined && process.env[key] !== undefined) {\n\t\t\t\tcombinedEnv[key] = process.env[key];\n\t\t\t}\n\t\t}\n\t}\n\n\t// Select schema based on environment\n\tconst schema = isServer\n\t\t? { ...server, ...client, ...shared }\n\t\t: { ...client, ...shared };\n\n\t// Run core validation\n\tconst validated = coreArkenv(schema as SchemaShape, {\n\t\tenv: combinedEnv as Dict<string>,\n\t\tsafe: false,\n\t});\n\n\tconst mergedValidated = { ...extendedEnvValues, ...validated };\n\n\t// Return a Proxy wrapper\n\treturn new Proxy(mergedValidated, {\n\t\tget(target, prop, receiver) {\n\t\t\tif (prop === EXTENDED_ENV) {\n\t\t\t\treturn target;\n\t\t\t}\n\t\t\tif (prop === ENV_KEYS) {\n\t\t\t\treturn allKeys;\n\t\t\t}\n\t\t\tif (prop === SERVER_ONLY_KEYS) {\n\t\t\t\treturn serverOnlyKeys;\n\t\t\t}\n\n\t\t\t// Always allow symbol properties (Symbol.iterator, Symbol.toStringTag, etc.)\n\t\t\tif (typeof prop === \"symbol\") {\n\t\t\t\treturn Reflect.get(target, prop, receiver);\n\t\t\t}\n\n\t\t\tif (typeof prop === \"string\") {\n\t\t\t\tif (serverOnlyKeys.has(prop) && !isServer) {\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t`ArkEnv Error: Attempted to access server environment variable '${prop}' on the client.`,\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\t// Allow schema keys and standard Object prototype properties\n\t\t\t\tif (!allKeys.has(prop) && !(prop in Object.prototype)) {\n\t\t\t\t\t// Fallback for bundler/framework-specific properties that bypass the prototype\n\t\t\t\t\tconst isCommonKey =\n\t\t\t\t\t\tprop === \"__esModule\" ||\n\t\t\t\t\t\tprop === \"$$typeof\" ||\n\t\t\t\t\t\tprop === \"toJSON\" ||\n\t\t\t\t\t\tprop === \"inspect\";\n\n\t\t\t\t\tif (!isCommonKey) {\n\t\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t\t`Environment variable '${prop}' is not defined in the schema.`,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn Reflect.get(target, prop, receiver);\n\t\t},\n\t});\n}\n"],"mappings":"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"}
|
package/dist/client.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:`Module`}}),require(`./config-
|
|
1
|
+
Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:`Module`}}),require(`./config-DcFFlKts.cjs`);const e=require(`./arkenv-internal-Chq1WyT3.cjs`);let t=require(`@arkenv/core`);function n(n,r){if(n&&typeof n==`object`&&(`runtimeEnv`in n||`client`in n||`shared`in n)){if(`server`in n)throw Error(`client entry point only accepts 'client' and 'shared' schemas.`);return e.t(n,!1,void 0,t.arkenv,t.getSchemaKeys)}return e.t(n,r,{isServer:!1,strictLayout:`client`},t.arkenv,t.getSchemaKeys)}exports.arkenv=n,exports.default=n,Object.defineProperty(exports,`type`,{enumerable:!0,get:function(){return t.type}});
|
|
2
2
|
//# sourceMappingURL=client.cjs.map
|
package/dist/client.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { a as $, i as Dict, t as SchemaShape } from "./index-
|
|
2
|
-
import { t as MergeExtends } from "./types-
|
|
1
|
+
import { a as $, i as Dict, t as SchemaShape } from "./index-NK75Fy2k.js";
|
|
2
|
+
import { t as MergeExtends } from "./types-BVAJERPl.js";
|
|
3
3
|
import { EnvSchema, type } from "@arkenv/core";
|
|
4
4
|
import { distill, type as type$1 } from "arktype";
|
|
5
5
|
|
package/dist/client.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{t as e}from"./arkenv-internal-
|
|
1
|
+
import{t as e}from"./arkenv-internal-Bb4lYS5z.js";import{arkenv as t,getSchemaKeys as n,type as r}from"@arkenv/core";function i(r,i){if(r&&typeof r==`object`&&(`runtimeEnv`in r||`client`in r||`shared`in r)){if(`server`in r)throw Error(`client entry point only accepts 'client' and 'shared' schemas.`);return e(r,!1,void 0,t,n)}return e(r,i,{isServer:!1,strictLayout:`client`},t,n)}export{i as arkenv,i as default,r as type};
|
|
2
2
|
//# sourceMappingURL=client.js.map
|
|
@@ -1,12 +1,11 @@
|
|
|
1
|
-
var e=Object.create,t=Object.defineProperty,n=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,i=Object.getPrototypeOf,a=Object.prototype.hasOwnProperty,o=(e,i,o,s)=>{if(i&&typeof i==`object`||typeof i==`function`)for(var c=r(i),l=0,u=c.length,d;l<u;l++)d=c[l],!a.call(e,d)&&d!==o&&t(e,d,{get:(e=>i[e]).bind(null,d),enumerable:!(s=n(i,d))||s.enumerable});return e},s=(n,r,a)=>(a=n==null?{}:e(i(n)),o(r||!n||!n.__esModule?t(a,`default`,{value:n,enumerable:!0}):a,n));
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
`)}const x=`/* eslint-disable */
|
|
1
|
+
var e=Object.create,t=Object.defineProperty,n=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,i=Object.getPrototypeOf,a=Object.prototype.hasOwnProperty,o=(e,i,o,s)=>{if(i&&typeof i==`object`||typeof i==`function`)for(var c=r(i),l=0,u=c.length,d;l<u;l++)d=c[l],!a.call(e,d)&&d!==o&&t(e,d,{get:(e=>i[e]).bind(null,d),enumerable:!(s=n(i,d))||s.enumerable});return e},s=(n,r,a)=>(a=n==null?{}:e(i(n)),o(r||!n||!n.__esModule?t(a,`default`,{value:n,enumerable:!0}):a,n));const c=require(`./dist-BGE7U5kQ.cjs`);let l=require(`node:fs`);l=s(l,1);let u=require(`node:path`);u=s(u,1);let d=require(`node:url`),f=require(`@arkenv/build`),p=require(`jiti`),m=!1;function h(e){return e===`simple`?(process.env.NODE_ENV===`development`&&!m&&(m=!0,c.r(`The 'simple' layout option is deprecated and will be removed in the next major version. Use 'flat' instead.`)),`simple`):e===`flat`?`simple`:e}function g(e,t){let n=e?.schemaPath?u.default.resolve(e.schemaPath):(0,f.findSchemaPath)(),r=!1;if(n)if(l.default.existsSync(n))r=!0;else{let e=u.default.extname(n);if(e){let t=n.slice(0,-e.length);l.default.existsSync(t)&&(r=!0)}}if(!n||!r)throw Error(c.n(`Could not find schema file at ${e?.schemaPath||`src/env.ts or env.ts`}. Please specify 'schemaPath' in setupArkEnv options.`));let{layout:i,baseDir:a}=(0,f.resolveLayout)(n,h(e?.layout)),o=i===`strict`&&a?a:u.default.dirname(n),s=u.default.join(o,`generated`,`env.gen.ts`),m=e?.outputPath?u.default.resolve(e.outputPath):s,g=e?.codegen??!0;if(g)try{v(n,m,i,e?.standard)}catch(e){let t=e instanceof Error?e.message:String(e);throw Error(c.n(`Failed to generate env.gen.ts: ${t}`))}if(e?.validate??!0)try{globalThis.__arkenv_force_server__=!0;let e=i===`strict`&&a?u.default.join(a,`server.ts`):n,r=typeof __filename<`u`?__filename:require(`url`).pathToFileURL(__filename).href?(0,d.fileURLToPath)(require(`url`).pathToFileURL(__filename).href):``,o=u.default.dirname(r),s=l.default.existsSync(u.default.join(o,`mock-server-only.ts`))?u.default.join(o,`mock-server-only.ts`):u.default.join(o,`mock-server-only.js`);(0,p.createJiti)(e,{moduleCache:!1,fsCache:!1,tsconfigPaths:!0,alias:{"server-only":s,"./script":s,"./script.tsx":s,...t?._jitiAliases}})(e)}catch(e){c.a(`Environment validation failed:`),c.t(e instanceof Error?e.message:String(e)),c.i(),process.exit(1)}finally{delete globalThis.__arkenv_force_server__}(process.env.NODE_ENV===`development`||process.env.NEXT_PHASE===`phase-development-server`)&&g&&(0,f.watchSchema)(i===`strict`&&a?[u.default.join(a,`internal`,`shared.ts`),u.default.join(a,`client.ts`),u.default.join(a,`server.ts`)].filter(l.default.existsSync):[n],()=>{v(n,m,i,e?.standard)})}function _(e,t){return g(t),e}function v(e,t,n,r){let{layout:i,baseDir:a}=(0,f.resolveLayout)(e,h(n)),o=``;if(i===`strict`){let e=u.default.join(a,`client.ts`),t=u.default.join(a,`internal`,`shared.ts`),n=l.default.existsSync(e)?l.default.readFileSync(e,`utf-8`):``,i=l.default.existsSync(t)?l.default.readFileSync(t,`utf-8`):``,s=!!r||n.includes(`@arkenv/standard`)||n.includes(`arkenv/standard`)||i.includes(`@arkenv/standard`)||i.includes(`arkenv/standard`);o=E((0,f.extractClientKeys)(n),(0,f.extractSharedKeys)(i),s)}else{let t=l.default.readFileSync(e,`utf-8`),n=!!r||t.includes(`@arkenv/standard`)||t.includes(`arkenv/standard`),{clientKeys:i,sharedKeys:a,isLegacy:s}=b(t);o=s?w(i,a,n):T(i,a,n)}let s=u.default.dirname(t);l.default.existsSync(s)||l.default.mkdirSync(s,{recursive:!0});let c=!0;l.default.existsSync(t)&&l.default.readFileSync(t,`utf-8`)===o&&(c=!1),c&&l.default.writeFileSync(t,o,`utf-8`)}function y(e){let t=/\b(?:arkenv|createEnv)\s*\(/g;for(;t.exec(e)!==null;){let n=1,r=t.lastIndex,i=null,a=null,o=0,s=0,c=[],l=``;for(;r<e.length&&n>0;){let t=e[r],u=e[r+1];if(a===`single`){(t===`
|
|
2
|
+
`||t===`\r`)&&(a=null),l+=t,r++;continue}if(a===`multi`){if(t===`*`&&u===`/`){a=null,l+=`*/`,r+=2;continue}l+=t,r++;continue}if(i){t===i&&e[r-1]!==`\\`&&(i=null),l+=t,r++;continue}if(t===`/`&&u===`/`){a=`single`,l+=`//`,r+=2;continue}if(t===`/`&&u===`*`){a=`multi`,l+=`/*`,r+=2;continue}if(t===`'`||t===`"`||t==="`"){i=t,l+=t,r++;continue}if(t===`(`?n++:t===`)`?n--:t===`{`?o++:t===`}`?o--:t===`[`?s++:t===`]`&&s--,n===0){c.push(l);break}t===`,`&&n===1&&o===0&&s===0?(c.push(l),l=``):l+=t,r++}if(n===0&&c.length>0)return{schemaArg:c[0].trim(),optionsArg:c[1]?c[1].trim():null}}return null}function b(e){let t=[],n=[],r=y(e);if(!r)return{clientKeys:t,sharedKeys:n,isLegacy:!1};let i=(0,f.parseBlockKeys)(r.schemaArg.replace(/^\{/,``).replace(/\}$/,``).trim()),a=i.includes(`client`)||i.includes(`server`)||i.includes(`shared`);if(a){let e=(0,f.extractBlock)(r.schemaArg,`client`);e&&t.push(...(0,f.parseBlockKeys)(e));let i=(0,f.extractBlock)(r.schemaArg,`shared`);i&&n.push(...(0,f.parseBlockKeys)(i))}else{let e=[];if(r.optionsArg){let t=r.optionsArg.match(/exposeToClient\s*:\s*\[([\s\S]*?)\]/)||r.optionsArg.match(/expose\s*:\s*\[([\s\S]*?)\]/)||r.optionsArg.match(/shared\s*:\s*\[([\s\S]*?)\]/);if(t){let n=t[1].matchAll(/['"`](.*?)['"`]/g);for(let t of n)e.push(t[1])}}for(let r of i)e.includes(r)||r===`NODE_ENV`?n.push(r):r.startsWith(`NEXT_PUBLIC_`)&&t.push(r)}return{clientKeys:t,sharedKeys:n,isLegacy:a}}function x(e,t){return Array.from(new Set([...e,...t])).map(e=>`\t\t\t${e}: typeof window !== "undefined" ? (globalThis as any).__arkenv_env__?.${e} ?? process.env.${e} : process.env.${e},`).join(`
|
|
3
|
+
`)}const S=`/* eslint-disable */
|
|
5
4
|
// biome-ignore format: auto-generated
|
|
6
5
|
// Generated by ArkEnv. DO NOT EDIT DIRECTLY.
|
|
7
|
-
`,
|
|
6
|
+
`,C=`
|
|
8
7
|
export default arkenv;
|
|
9
|
-
`;function
|
|
8
|
+
`;function w(e,t,n){let r=x(e,t);return`${S}
|
|
10
9
|
import { arkenv as coreArkenv } from "${n?`@arkenv/nextjs/standard`:`@arkenv/nextjs`}";
|
|
11
10
|
${n?``:`
|
|
12
11
|
export { type } from "@arkenv/nextjs";
|
|
@@ -29,7 +28,7 @@ export function arkenv<
|
|
|
29
28
|
},
|
|
30
29
|
} as any) as any;
|
|
31
30
|
}
|
|
32
|
-
${
|
|
31
|
+
${C}`}function T(e,t,n){let r=x(e,t);return`${S}
|
|
33
32
|
import { arkenv as coreArkenv } from "${n?`@arkenv/nextjs/standard`:`@arkenv/nextjs`}";${n?``:`
|
|
34
33
|
import type { type as at, distill } from "arktype";`}
|
|
35
34
|
${n?``:`
|
|
@@ -62,7 +61,7 @@ export function arkenv<
|
|
|
62
61
|
} as any);
|
|
63
62
|
return env${n?``:` as unknown as Readonly<distill.Out<at.infer<TSchema>>>`};
|
|
64
63
|
}
|
|
65
|
-
${
|
|
64
|
+
${C}`}function E(e,t,n){let r=x(e,t);return`${S}
|
|
66
65
|
import { arkenv as coreArkenv } from "${n?`@arkenv/nextjs/standard/client`:`@arkenv/nextjs/client`}";${n?``:`
|
|
67
66
|
import type { Infer } from "@arkenv/core";`}
|
|
68
67
|
${n?``:`
|
|
@@ -99,5 +98,5 @@ export function arkenv<
|
|
|
99
98
|
},
|
|
100
99
|
} as any);
|
|
101
100
|
}
|
|
102
|
-
${
|
|
103
|
-
//# sourceMappingURL=config-
|
|
101
|
+
${C}`}Object.defineProperty(exports,`a`,{enumerable:!0,get:function(){return s}}),Object.defineProperty(exports,`i`,{enumerable:!0,get:function(){return _}}),Object.defineProperty(exports,`n`,{enumerable:!0,get:function(){return v}}),Object.defineProperty(exports,`r`,{enumerable:!0,get:function(){return g}}),Object.defineProperty(exports,`t`,{enumerable:!0,get:function(){return b}});
|
|
102
|
+
//# sourceMappingURL=config-DcFFlKts.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-DcFFlKts.cjs","names":["path","fs","formatBuildError"],"sources":["../src/config.ts"],"sourcesContent":["import fs from \"node:fs\";\nimport path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport {\n\textractBlock,\n\textractClientKeys,\n\textractSharedKeys,\n\tfindSchemaPath,\n\tparseBlockKeys,\n\tresolveLayout,\n\twatchSchema,\n} from \"@arkenv/build\";\nimport {\n\tformatBuildError,\n\tlogBuildError,\n\tlogBuildErrorBlankLine,\n\tlogBuildErrorDetail,\n\tlogBuildWarning,\n} from \"@repo/utils\";\nimport { createJiti } from \"jiti\";\n\nexport { extractClientKeys, extractSharedKeys };\n\nlet hasWarnedSimpleLayout = false;\n\nfunction normalizeLayout(\n\tlayout: ArkEnvConfigOptions[\"layout\"],\n): \"simple\" | \"strict\" | undefined {\n\tif (layout === \"simple\") {\n\t\tif (process.env.NODE_ENV === \"development\" && !hasWarnedSimpleLayout) {\n\t\t\thasWarnedSimpleLayout = true;\n\t\t\tlogBuildWarning(\n\t\t\t\t\"The 'simple' layout option is deprecated and will be removed in the next major version. Use 'flat' instead.\",\n\t\t\t);\n\t\t}\n\t\treturn \"simple\";\n\t}\n\tif (layout === \"flat\") {\n\t\treturn \"simple\";\n\t}\n\treturn layout;\n}\n\n/**\n * Configuration options for the ArkEnv Next.js integration.\n *\n * @example\n * ```ts\n * const configOptions: ArkEnvConfigOptions = {\n * schemaPath: \"./src/env.ts\",\n * outputPath: \"./src/generated/env.gen.ts\"\n * };\n * ```\n */\nexport type ArkEnvConfigOptions = {\n\t/**\n\t * Specify the path to the schema definition file.\n\t *\n\t * Defaults to searching for `\"src/env.ts\"` or `\"env.ts\"` in the project root.\n\t *\n\t * @default \"src/env.ts\"\n\t * @example\n\t * ```ts\n\t * export default withArkEnv(nextConfig, {\n\t * schemaPath: \"./src/env.ts\"\n\t * });\n\t * ```\n\t */\n\tschemaPath?: string;\n\n\t/**\n\t * Specify the path where the generated file (`env.gen.ts`) should be written.\n\t *\n\t * Defaults to `\"generated/env.gen.ts\"` in the same directory as the schema file.\n\t *\n\t * @default \"[schemaDirectory]/generated/env.gen.ts\"\n\t * @example\n\t * ```ts\n\t * export default withArkEnv(nextConfig, {\n\t * outputPath: \"./src/generated/env.gen.ts\"\n\t * });\n\t * ```\n\t */\n\toutputPath?: string;\n\n\t/**\n\t * Specify the configuration layout.\n\t *\n\t * - `\"flat\"` (default): A single `env.ts` schema file.\n\t * - `\"strict\"`: A 3-file split schema layout (`env/internal/shared.ts`, `env/client.ts`, `env/server.ts`).\n\t *\n\t * @default \"flat\"\n\t */\n\tlayout?:\n\t\t| \"flat\"\n\t\t| \"strict\"\n\t\t/** @deprecated Use `\"flat\"` instead. `\"simple\"` will be removed in the next major version. */\n\t\t| \"simple\";\n\n\t/**\n\t * Force standard mode code generation.\n\t *\n\t * When `true`, the generated `env.gen.ts` imports from `@arkenv/nextjs/standard/*`\n\t * instead of `@arkenv/nextjs/*`, ensuring the Standard Schema engine (`@arkenv/standard`)\n\t * is used and `arktype` is never bundled. This is set automatically when importing from\n\t * `@arkenv/nextjs/standard/config`, but can be toggled manually for custom setups.\n\t *\n\t * @default false\n\t */\n\tstandard?: boolean;\n\n\t/**\n\t * Enable or disable build-time environment variable validation during build/dev startup.\n\t *\n\t * @default true\n\t */\n\tvalidate?: boolean;\n\n\t/**\n\t * Enable or disable automatic code generation of the `env.gen.ts` file.\n\t *\n\t * @default true\n\t */\n\tcodegen?: boolean;\n};\n\n/**\n * Run ArkEnv codegen and setup without wrapping nextConfig.\n *\n * @param options Optional configuration paths for schema and output files\n * @param internalOptions Optional configuration for internal testing hooks\n * @throws An error if the schema file cannot be found or if code generation fails\n */\nexport function setupArkEnv(\n\toptions?: ArkEnvConfigOptions,\n\tinternalOptions?: { _jitiAliases?: Record<string, string> },\n): void {\n\t// 1. Locate the env.ts schema file or strict schema directory\n\tconst schemaPath = options?.schemaPath\n\t\t? path.resolve(options.schemaPath)\n\t\t: findSchemaPath();\n\n\t// Auto-detect layout if not specified\n\tlet exists = false;\n\tif (schemaPath) {\n\t\tif (fs.existsSync(schemaPath)) {\n\t\t\texists = true;\n\t\t} else {\n\t\t\tconst ext = path.extname(schemaPath);\n\t\t\tif (ext) {\n\t\t\t\tconst baseWithoutExt = schemaPath.slice(0, -ext.length);\n\t\t\t\tif (fs.existsSync(baseWithoutExt)) {\n\t\t\t\t\texists = true;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tif (!schemaPath || !exists) {\n\t\tthrow new Error(\n\t\t\tformatBuildError(\n\t\t\t\t`Could not find schema file at ${\n\t\t\t\t\toptions?.schemaPath || \"src/env.ts or env.ts\"\n\t\t\t\t}. Please specify 'schemaPath' in setupArkEnv options.`,\n\t\t\t),\n\t\t);\n\t}\n\n\tconst normalizedLayout = normalizeLayout(options?.layout);\n\n\tconst { layout: resolvedLayout, baseDir } = resolveLayout(\n\t\tschemaPath,\n\t\tnormalizedLayout,\n\t);\n\n\t// 2. Determine outputPath (defaults to generated/env.gen.ts in the same directory as schemaPath/baseDir)\n\tconst defaultOutputDir =\n\t\tresolvedLayout === \"strict\" && baseDir ? baseDir : path.dirname(schemaPath);\n\tconst defaultOutputPath = path.join(\n\t\tdefaultOutputDir,\n\t\t\"generated\",\n\t\t\"env.gen.ts\",\n\t);\n\tconst outputPath = options?.outputPath\n\t\t? path.resolve(options.outputPath)\n\t\t: defaultOutputPath;\n\n\t// 3. Run initial code generation if enabled\n\tconst codegen = options?.codegen ?? true;\n\tif (codegen) {\n\t\ttry {\n\t\t\trunCodegen(schemaPath, outputPath, resolvedLayout, options?.standard);\n\t\t} catch (error: unknown) {\n\t\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\t\tthrow new Error(\n\t\t\t\tformatBuildError(`Failed to generate env.gen.ts: ${message}`),\n\t\t\t);\n\t\t}\n\t}\n\n\t// 4. Validate schema against environment variables\n\tconst runValidation = options?.validate ?? true;\n\tif (runValidation) {\n\t\ttry {\n\t\t\t(globalThis as any).__arkenv_force_server__ = true;\n\t\t\tconst fileToEvaluate =\n\t\t\t\tresolvedLayout === \"strict\" && baseDir\n\t\t\t\t\t? path.join(baseDir, \"server.ts\")\n\t\t\t\t\t: schemaPath;\n\n\t\t\tconst filenameForJiti =\n\t\t\t\ttypeof __filename !== \"undefined\"\n\t\t\t\t\t? __filename\n\t\t\t\t\t: typeof import.meta !== \"undefined\" && import.meta.url\n\t\t\t\t\t\t? fileURLToPath(import.meta.url)\n\t\t\t\t\t\t: \"\";\n\t\t\tconst dir = path.dirname(filenameForJiti);\n\t\t\tconst mockServerOnlyPath = fs.existsSync(\n\t\t\t\tpath.join(dir, \"mock-server-only.ts\"),\n\t\t\t)\n\t\t\t\t? path.join(dir, \"mock-server-only.ts\")\n\t\t\t\t: path.join(dir, \"mock-server-only.js\");\n\n\t\t\tconst aliases: Record<string, string> = {\n\t\t\t\t\"server-only\": mockServerOnlyPath,\n\t\t\t\t\"./script\": mockServerOnlyPath,\n\t\t\t\t\"./script.tsx\": mockServerOnlyPath,\n\t\t\t\t...internalOptions?._jitiAliases,\n\t\t\t};\n\n\t\t\tconst jiti = createJiti(fileToEvaluate, {\n\t\t\t\tmoduleCache: false,\n\t\t\t\tfsCache: false,\n\t\t\t\ttsconfigPaths: true,\n\t\t\t\talias: aliases,\n\t\t\t});\n\t\t\tjiti(fileToEvaluate);\n\t\t} catch (error: unknown) {\n\t\t\tlogBuildError(\"Environment validation failed:\");\n\t\t\tlogBuildErrorDetail(\n\t\t\t\terror instanceof Error ? error.message : String(error),\n\t\t\t);\n\t\t\tlogBuildErrorBlankLine();\n\t\t\tprocess.exit(1);\n\t\t} finally {\n\t\t\tdelete (globalThis as any).__arkenv_force_server__;\n\t\t}\n\t}\n\n\t// 5. Initialize development file watcher if in dev mode and codegen is enabled\n\tconst isDev =\n\t\tprocess.env.NODE_ENV === \"development\" ||\n\t\tprocess.env.NEXT_PHASE === \"phase-development-server\";\n\tif (isDev && codegen) {\n\t\tconst watchPaths =\n\t\t\tresolvedLayout === \"strict\" && baseDir\n\t\t\t\t? [\n\t\t\t\t\t\tpath.join(baseDir, \"internal\", \"shared.ts\"),\n\t\t\t\t\t\tpath.join(baseDir, \"client.ts\"),\n\t\t\t\t\t\tpath.join(baseDir, \"server.ts\"),\n\t\t\t\t\t].filter(fs.existsSync)\n\t\t\t\t: [schemaPath];\n\t\twatchSchema(watchPaths, () => {\n\t\t\trunCodegen(schemaPath, outputPath, resolvedLayout, options?.standard);\n\t\t});\n\t}\n}\n\n/**\n * Wrap a Next.js configuration object to automatically generate the `runtimeEnv` block in `env.gen.ts`.\n *\n * @param nextConfig The Next.js configuration object or function\n * @param options Optional configuration paths for schema and output files\n * @returns The Next.js configuration object unchanged\n * @throws An error if the schema file cannot be found or if code generation fails\n */\nexport function withArkEnv<T>(nextConfig: T, options?: ArkEnvConfigOptions): T {\n\tsetupArkEnv(options);\n\treturn nextConfig;\n}\n\n/**\n * Run code generation to read the schema file and generate the env.gen.ts factory.\n *\n * @param schemaPath The absolute path to the schema file or directory\n * @param outputPath The absolute path to the generated output file\n * @param layoutOption The explicit layout to use; auto-detected from the filesystem when omitted\n * @param forceStandard Force standard mode code generation\n * @throws An error if strict layout files are missing when `layoutOption` is `\"strict\"`\n */\nexport function runCodegen(\n\tschemaPath: string,\n\toutputPath: string,\n\tlayoutOption?: ArkEnvConfigOptions[\"layout\"],\n\tforceStandard?: boolean,\n) {\n\tconst normalizedLayout = normalizeLayout(layoutOption);\n\n\tconst { layout: resolvedLayout, baseDir } = resolveLayout(\n\t\tschemaPath,\n\t\tnormalizedLayout,\n\t);\n\n\tlet generatedCode = \"\";\n\tif (resolvedLayout === \"strict\") {\n\t\tconst clientPath = path.join(baseDir, \"client.ts\");\n\t\tconst sharedPath = path.join(baseDir, \"internal\", \"shared.ts\");\n\n\t\tconst clientContent = fs.existsSync(clientPath)\n\t\t\t? fs.readFileSync(clientPath, \"utf-8\")\n\t\t\t: \"\";\n\t\tconst sharedContent = fs.existsSync(sharedPath)\n\t\t\t? fs.readFileSync(sharedPath, \"utf-8\")\n\t\t\t: \"\";\n\n\t\tconst isStandard =\n\t\t\t!!forceStandard ||\n\t\t\tclientContent.includes(\"@arkenv/standard\") ||\n\t\t\tclientContent.includes(\"arkenv/standard\") ||\n\t\t\tsharedContent.includes(\"@arkenv/standard\") ||\n\t\t\tsharedContent.includes(\"arkenv/standard\");\n\n\t\tconst clientKeys = extractClientKeys(clientContent);\n\t\tconst sharedKeys = extractSharedKeys(sharedContent);\n\n\t\tgeneratedCode = generateClientFactoryCode(\n\t\t\tclientKeys,\n\t\t\tsharedKeys,\n\t\t\tisStandard,\n\t\t);\n\t} else {\n\t\tconst fileContent = fs.readFileSync(schemaPath, \"utf-8\");\n\t\tconst isStandard =\n\t\t\t!!forceStandard ||\n\t\t\tfileContent.includes(\"@arkenv/standard\") ||\n\t\t\tfileContent.includes(\"arkenv/standard\");\n\n\t\tconst { clientKeys, sharedKeys, isLegacy } = extractKeys(fileContent);\n\t\tif (isLegacy) {\n\t\t\tgeneratedCode = generateFactoryCode(clientKeys, sharedKeys, isStandard);\n\t\t} else {\n\t\t\tgeneratedCode = generateFlatFactoryCode(\n\t\t\t\tclientKeys,\n\t\t\t\tsharedKeys,\n\t\t\t\tisStandard,\n\t\t\t);\n\t\t}\n\t}\n\n\t// Ensure parent directory exists\n\tconst outputDir = path.dirname(outputPath);\n\tif (!fs.existsSync(outputDir)) {\n\t\tfs.mkdirSync(outputDir, { recursive: true });\n\t}\n\n\t// Write if changed to avoid unnecessary filesystem/watcher triggers\n\tlet shouldWrite = true;\n\tif (fs.existsSync(outputPath)) {\n\t\tconst existingContent = fs.readFileSync(outputPath, \"utf-8\");\n\t\tif (existingContent === generatedCode) {\n\t\t\tshouldWrite = false;\n\t\t}\n\t}\n\n\tif (shouldWrite) {\n\t\tfs.writeFileSync(outputPath, generatedCode, \"utf-8\");\n\t}\n}\n\nfunction extractCallArguments(\n\tcontent: string,\n): { schemaArg: string; optionsArg: string | null } | null {\n\tconst regex = /\\b(?:arkenv|createEnv)\\s*\\(/g;\n\twhile (regex.exec(content) !== null) {\n\t\tlet parenCount = 1;\n\t\tlet index = regex.lastIndex;\n\t\tlet inString: string | null = null;\n\t\tlet inComment: \"single\" | \"multi\" | null = null;\n\t\tlet braceCount = 0;\n\t\tlet bracketCount = 0;\n\n\t\tconst args: string[] = [];\n\t\tlet currentArg = \"\";\n\n\t\twhile (index < content.length && parenCount > 0) {\n\t\t\tconst char = content[index];\n\t\t\tconst nextChar = content[index + 1];\n\n\t\t\tif (inComment === \"single\") {\n\t\t\t\tif (char === \"\\n\" || char === \"\\r\") inComment = null;\n\t\t\t\tcurrentArg += char;\n\t\t\t\tindex++;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (inComment === \"multi\") {\n\t\t\t\tif (char === \"*\" && nextChar === \"/\") {\n\t\t\t\t\tinComment = null;\n\t\t\t\t\tcurrentArg += \"*/\";\n\t\t\t\t\tindex += 2;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tcurrentArg += char;\n\t\t\t\tindex++;\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif (inString) {\n\t\t\t\tif (char === inString && content[index - 1] !== \"\\\\\") {\n\t\t\t\t\tinString = null;\n\t\t\t\t}\n\t\t\t\tcurrentArg += char;\n\t\t\t\tindex++;\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif (char === \"/\" && nextChar === \"/\") {\n\t\t\t\tinComment = \"single\";\n\t\t\t\tcurrentArg += \"//\";\n\t\t\t\tindex += 2;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (char === \"/\" && nextChar === \"*\") {\n\t\t\t\tinComment = \"multi\";\n\t\t\t\tcurrentArg += \"/*\";\n\t\t\t\tindex += 2;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (char === \"'\" || char === '\"' || char === \"`\") {\n\t\t\t\tinString = char;\n\t\t\t\tcurrentArg += char;\n\t\t\t\tindex++;\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif (char === \"(\") {\n\t\t\t\tparenCount++;\n\t\t\t} else if (char === \")\") {\n\t\t\t\tparenCount--;\n\t\t\t} else if (char === \"{\") {\n\t\t\t\tbraceCount++;\n\t\t\t} else if (char === \"}\") {\n\t\t\t\tbraceCount--;\n\t\t\t} else if (char === \"[\") {\n\t\t\t\tbracketCount++;\n\t\t\t} else if (char === \"]\") {\n\t\t\t\tbracketCount--;\n\t\t\t}\n\n\t\t\tif (parenCount === 0) {\n\t\t\t\targs.push(currentArg);\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tif (\n\t\t\t\tchar === \",\" &&\n\t\t\t\tparenCount === 1 &&\n\t\t\t\tbraceCount === 0 &&\n\t\t\t\tbracketCount === 0\n\t\t\t) {\n\t\t\t\targs.push(currentArg);\n\t\t\t\tcurrentArg = \"\";\n\t\t\t} else {\n\t\t\t\tcurrentArg += char;\n\t\t\t}\n\t\t\tindex++;\n\t\t}\n\n\t\tif (parenCount === 0 && args.length > 0) {\n\t\t\treturn {\n\t\t\t\tschemaArg: args[0].trim(),\n\t\t\t\toptionsArg: args[1] ? args[1].trim() : null,\n\t\t\t};\n\t\t}\n\t}\n\treturn null;\n}\n\n/**\n * Statically extract client and shared keys from the schema content.\n *\n * @param content The schema file string content\n * @returns An object containing the extracted client and shared keys\n */\nexport function extractKeys(content: string): {\n\tclientKeys: string[];\n\tsharedKeys: string[];\n\tisLegacy?: boolean;\n} {\n\tconst clientKeys: string[] = [];\n\tconst sharedKeys: string[] = [];\n\n\tconst args = extractCallArguments(content);\n\tif (!args) {\n\t\treturn { clientKeys, sharedKeys, isLegacy: false };\n\t}\n\n\t// Strip outer braces if present\n\tconst trimmedSchema = args.schemaArg\n\t\t.replace(/^\\{/, \"\")\n\t\t.replace(/\\}$/, \"\")\n\t\t.trim();\n\tconst topKeys = parseBlockKeys(trimmedSchema);\n\tconst isLegacy =\n\t\ttopKeys.includes(\"client\") ||\n\t\ttopKeys.includes(\"server\") ||\n\t\ttopKeys.includes(\"shared\");\n\n\tif (isLegacy) {\n\t\tconst clientBlock = extractBlock(args.schemaArg, \"client\");\n\t\tif (clientBlock) {\n\t\t\tclientKeys.push(...parseBlockKeys(clientBlock));\n\t\t}\n\t\tconst sharedBlock = extractBlock(args.schemaArg, \"shared\");\n\t\tif (sharedBlock) {\n\t\t\tsharedKeys.push(...parseBlockKeys(sharedBlock));\n\t\t}\n\t} else {\n\t\t// New flat layout\n\t\tconst optionExposedKeys: string[] = [];\n\t\tif (args.optionsArg) {\n\t\t\tconst exposeMatch =\n\t\t\t\targs.optionsArg.match(/exposeToClient\\s*:\\s*\\[([\\s\\S]*?)\\]/) ||\n\t\t\t\targs.optionsArg.match(/expose\\s*:\\s*\\[([\\s\\S]*?)\\]/) ||\n\t\t\t\targs.optionsArg.match(/shared\\s*:\\s*\\[([\\s\\S]*?)\\]/);\n\t\t\tif (exposeMatch) {\n\t\t\t\tconst matches = exposeMatch[1].matchAll(/['\"`](.*?)['\"`]/g);\n\t\t\t\tfor (const match of matches) {\n\t\t\t\t\toptionExposedKeys.push(match[1]);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tfor (const key of topKeys) {\n\t\t\t// NODE_ENV is implicitly shared as Next.js automatically inlines and replaces references to process.env.NODE_ENV in browser bundles.\n\t\t\t// See: https://nextjs.org/docs/app/guides/environment-variables\n\t\t\tif (optionExposedKeys.includes(key) || key === \"NODE_ENV\") {\n\t\t\t\tsharedKeys.push(key);\n\t\t\t} else if (key.startsWith(\"NEXT_PUBLIC_\")) {\n\t\t\t\tclientKeys.push(key);\n\t\t\t}\n\t\t}\n\t}\n\n\treturn { clientKeys, sharedKeys, isLegacy };\n}\n\n/**\n * Generate the triple-tab indented runtime environment variables mapping.\n */\nfunction generateRuntimeEnvLines(\n\tclientKeys: string[],\n\tsharedKeys: string[],\n): string {\n\tconst allKeys = Array.from(new Set([...clientKeys, ...sharedKeys]));\n\treturn allKeys\n\t\t.map(\n\t\t\t(key) =>\n\t\t\t\t`\\t\\t\\t${key}: typeof window !== \"undefined\" ? (globalThis as any).__arkenv_env__?.${key} ?? process.env.${key} : process.env.${key},`,\n\t\t)\n\t\t.join(\"\\n\");\n}\n\nconst GENERATED_HEADER = `/* eslint-disable */\n// biome-ignore format: auto-generated\n// Generated by ArkEnv. DO NOT EDIT DIRECTLY.\n`;\n\nconst GENERATED_FOOTER = `\nexport default arkenv;\n`;\n\n/**\n * Generate the TypeScript factory code for the tailored arkenv helper.\n *\n * @param clientKeys The client environment variable keys\n * @param sharedKeys The shared environment variable keys\n * @param isStandard Whether standard mode is used\n * @returns The generated TypeScript source code string\n */\nfunction generateFactoryCode(\n\tclientKeys: string[],\n\tsharedKeys: string[],\n\tisStandard?: boolean,\n): string {\n\tconst runtimeEnvLines = generateRuntimeEnvLines(clientKeys, sharedKeys);\n\tconst importPath = isStandard ? \"@arkenv/nextjs/standard\" : \"@arkenv/nextjs\";\n\tconst coreName = \"arkenv\";\n\tconst typeExport = isStandard\n\t\t? \"\"\n\t\t: '\\nexport { type } from \"@arkenv/nextjs\";\\n';\n\tconst callPrefix = \"coreArkenv\";\n\n\treturn `${GENERATED_HEADER}\nimport { ${coreName} as coreArkenv } from \"${importPath}\";\n${typeExport}\nexport function arkenv<\n\tconst TServer extends Record<string, any> = {},\n\tconst TClient extends Record<string, any> = {},\n\tconst TShared extends Record<string, any> = {},\n>(options: {\n\tserver?: TServer;\n\tclient?: TClient & {\n\t\t[K in keyof TClient]: K extends \\`NEXT_PUBLIC_\\${string}\\` ? unknown : never;\n\t};\n\tshared?: TShared;\n}) {\n\treturn ${callPrefix}({\n\t\t...options,\n\t\truntimeEnv: {\n\t\t\t${runtimeEnvLines}\n\t\t},\n\t} as any) as any;\n}\n${GENERATED_FOOTER}`;\n}\n\n/**\n * Generate the TypeScript factory code for the Flat Layout arkenv helper.\n *\n * @remarks\n * **Architecture tripwire:** Do not statically compile the schema here or\n * reference internal-only types (the `$` scope or `MergeExtends`).\n *\n * - **Generic wrapper:** The factory must stay generic because the concrete\n * schema is owned by the user-land `env.ts`.\n * - **Type strategy:** It intentionally returns the full schema type to ensure\n * flawless Server Component autocomplete.\n * - **Security boundary:** Client-side protection is deliberately deferred to\n * the runtime Proxy in `@arkenv/nextjs`, which throws on unauthorized access.\n * 📖 See ADR-0013: Flat layout codegen and type inference strategy\n * (`docs/adr/0013-flat-layout-codegen-type-strategy.md`).\n */\nfunction generateFlatFactoryCode(\n\tclientKeys: string[],\n\tsharedKeys: string[],\n\tisStandard?: boolean,\n): string {\n\tconst runtimeEnvLines = generateRuntimeEnvLines(clientKeys, sharedKeys);\n\tconst importPath = isStandard ? \"@arkenv/nextjs/standard\" : \"@arkenv/nextjs\";\n\tconst coreName = \"arkenv\";\n\tconst typeExport = isStandard\n\t\t? \"\"\n\t\t: '\\nexport { type } from \"@arkenv/nextjs\";\\n';\n\tconst typeImport = isStandard\n\t\t? \"\"\n\t\t: '\\nimport type { type as at, distill } from \"arktype\";';\n\tconst returnType = isStandard\n\t\t? \"Readonly<TSchema>\"\n\t\t: \"Readonly<distill.Out<at.infer<TSchema>>>\";\n\tconst castReturn = isStandard\n\t\t? \"\"\n\t\t: \" as unknown as Readonly<distill.Out<at.infer<TSchema>>>\";\n\tconst callPrefix = \"coreArkenv\";\n\n\treturn `${GENERATED_HEADER}\nimport { ${coreName} as coreArkenv } from \"${importPath}\";${typeImport}\n${typeExport}\nexport function arkenv<\n\tconst TSchema extends Record<string, unknown> & { runtimeEnv?: never } = {},\n\tconst TExpose extends keyof TSchema = never,\n\tconst TExtends extends readonly unknown[] = [],\n>(\n\tschema: TSchema,\n\toptions?: {\n\t\t/**\n\t\t * Custom environment variables to expose to the client bundle.\n\t\t * By default, variables prefixed with \\`NEXT_PUBLIC_\\` and \\`NODE_ENV\\` are exposed automatically.\n\t\t * Use this option to expose custom variables that do not have the \\`NEXT_PUBLIC_\\` prefix.\n\t\t */\n\t\texposeToClient?: readonly TExpose[];\n\t\textends?: [...TExtends];\n\t},\n): ${returnType} {\n\t// Types expose the full schema for a great DX on the server; the runtime\n\t// Proxy from \\`@arkenv/nextjs\\` enforces the security boundary by throwing\n\t// when a server-only variable is accessed on the client.\n\tconst env = ${callPrefix}(schema as any, {\n\t\t...options,\n\t\truntimeEnv: {\n\t\t\t${runtimeEnvLines}\n\t\t},\n\t} as any);\n\treturn env${castReturn};\n}\n${GENERATED_FOOTER}`;\n}\n\n/**\n * Generate the TypeScript factory code for the strict-layout `arkenv` helper.\n *\n * Unlike `generateFactoryCode`, this variant imports from `@arkenv/nextjs/client`\n * and exposes a positional-schema signature suited for split-file projects.\n *\n * @param clientKeys The env var keys extracted from `client.ts`\n * @param sharedKeys The env var keys extracted from `internal/shared.ts`\n * @param isStandard Whether standard mode is used\n * @returns The generated TypeScript source code string\n */\nfunction generateClientFactoryCode(\n\tclientKeys: string[],\n\tsharedKeys: string[],\n\tisStandard?: boolean,\n): string {\n\tconst runtimeEnvLines = generateRuntimeEnvLines(clientKeys, sharedKeys);\n\tconst importPath = isStandard\n\t\t? \"@arkenv/nextjs/standard/client\"\n\t\t: \"@arkenv/nextjs/client\";\n\tconst coreName = \"arkenv\";\n\tconst typeExport = isStandard\n\t\t? \"\"\n\t\t: '\\nexport { type } from \"@arkenv/nextjs/client\";\\n';\n\tconst typeImport = isStandard\n\t\t? \"\"\n\t\t: '\\nimport type { Infer } from \"@arkenv/core\";';\n\tconst callPrefix = \"coreArkenv\";\n\tconst returnType = isStandard\n\t\t? \"Readonly<TSchema & MergeExtends<TExtends>>\"\n\t\t: \"Readonly<Infer<TSchema> & MergeExtends<TExtends>>\";\n\n\treturn `${GENERATED_HEADER}\nimport { ${coreName} as coreArkenv } from \"${importPath}\";${typeImport}\n${typeExport}\ntype ResolveExtend<T> = [Infer<T>] extends [never] ? T : Infer<T>;\n\ntype UnionToIntersection<U> = (\n\tU extends any ? (k: U) => void : never\n) extends (k: infer I) => void\n\t? I\n\t: never;\n\ntype MergeExtends<TExtends extends readonly unknown[] | undefined> =\n\tTExtends extends readonly unknown[]\n\t\t? UnionToIntersection<ResolveExtend<TExtends[number]>>\n\t\t: {};\n\nexport function arkenv<\n\tconst TSchema extends Record<string, any> = {},\n\tconst TExtends extends readonly unknown[] = [],\n>(\n\tschema: TSchema & {\n\t\t[K in keyof TSchema]: K extends \\`NEXT_PUBLIC_\\${string}\\` ? unknown : never;\n\t},\n\toptions?: {\n\t\textends?: [...TExtends];\n\t},\n): ${returnType} {\n\treturn ${callPrefix}(schema as any, {\n\t\t...options,\n\t\truntimeEnv: {\n\t\t\t${runtimeEnvLines}\n\t\t},\n\t} as any);\n}\n${GENERATED_FOOTER}`;\n}\n"],"mappings":"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"}
|
package/dist/config.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./config-
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./config-DcFFlKts.cjs`);let t=require(`@arkenv/build`);exports.extractClientKeys=t.extractClientKeys,exports.extractKeys=e.t,exports.extractSharedKeys=t.extractSharedKeys,exports.runCodegen=e.n,exports.setupArkEnv=e.r,exports.withArkEnv=e.i;
|
package/dist/config.d.cts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.cts","names":[],"sources":["../src/config.ts"],"mappings":";;;;
|
|
1
|
+
{"version":3,"file":"config.d.cts","names":[],"sources":["../src/config.ts"],"mappings":";;;;AAsDA;;;;;;;;;;KAAY,mBAAA;EAqEJ;AAUR;;;;;;;;;;;AA+IA;EAhNC,UAAA;EAgNyB;;;;;;;;;;;;;EAjMzB,UAAA;EA+Me;;;;;;;;EArMf,MAAA,qBAyMuB;EA6LR;;;;;;;;;;EAtXf,QAAA;;;;;;EAOA,QAAA;;;;;;EAOA,OAAA;AAAA;;;;;;;;iBAUe,WAAA,CACf,OAAA,GAAU,mBAAA,EACV,eAAA;EAAoB,YAAA,GAAe,MAAA;AAAA;;;;;;;;;iBA6IpB,UAAA,GAAA,CAAc,UAAA,EAAY,CAAA,EAAG,OAAA,GAAU,mBAAA,GAAsB,CAAA;;;;;;;;;;iBAc7D,UAAA,CACf,UAAA,UACA,UAAA,UACA,YAAA,GAAe,mBAAA,YACf,aAAA;;;;;;;iBA6Le,WAAA,CAAY,OAAA;EAC3B,UAAA;EACA,UAAA;EACA,QAAA;AAAA"}
|
package/dist/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","names":[],"sources":["../src/config.ts"],"mappings":";;;;
|
|
1
|
+
{"version":3,"file":"config.d.ts","names":[],"sources":["../src/config.ts"],"mappings":";;;;AAsDA;;;;;;;;;;KAAY,mBAAA;EAqEJ;AAUR;;;;;;;;;;;AA+IA;EAhNC,UAAA;EAgNyB;;;;;;;;;;;;;EAjMzB,UAAA;EA+Me;;;;;;;;EArMf,MAAA,qBAyMuB;EA6LR;;;;;;;;;;EAtXf,QAAA;;;;;;EAOA,QAAA;;;;;;EAOA,OAAA;AAAA;;;;;;;;iBAUe,WAAA,CACf,OAAA,GAAU,mBAAA,EACV,eAAA;EAAoB,YAAA,GAAe,MAAA;AAAA;;;;;;;;;iBA6IpB,UAAA,GAAA,CAAc,UAAA,EAAY,CAAA,EAAG,OAAA,GAAU,mBAAA,GAAsB,CAAA;;;;;;;;;;iBAc7D,UAAA,CACf,UAAA,UACA,UAAA,UACA,YAAA,GAAe,mBAAA,YACf,aAAA;;;;;;;iBA6Le,WAAA,CAAY,OAAA;EAC3B,UAAA;EACA,UAAA;EACA,QAAA;AAAA"}
|
package/dist/config.js
CHANGED
|
@@ -1,12 +1,11 @@
|
|
|
1
|
-
import e from"node:fs";import
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
`)}const y=`/* eslint-disable */
|
|
1
|
+
import{a as e,i as t,n,r,t as i}from"./dist-Ce46CxRV.js";import a from"node:fs";import o from"node:path";import{fileURLToPath as s}from"node:url";import{extractBlock as c,extractClientKeys as l,extractSharedKeys as u,findSchemaPath as d,parseBlockKeys as f,resolveLayout as p,watchSchema as m}from"@arkenv/build";import{createJiti as h}from"jiti";let g=!1;function _(e){return e===`simple`?(process.env.NODE_ENV===`development`&&!g&&(g=!0,r(`The 'simple' layout option is deprecated and will be removed in the next major version. Use 'flat' instead.`)),`simple`):e===`flat`?`simple`:e}function v(r,c){let l=r?.schemaPath?o.resolve(r.schemaPath):d(),u=!1;if(l)if(a.existsSync(l))u=!0;else{let e=o.extname(l);if(e){let t=l.slice(0,-e.length);a.existsSync(t)&&(u=!0)}}if(!l||!u)throw Error(n(`Could not find schema file at ${r?.schemaPath||`src/env.ts or env.ts`}. Please specify 'schemaPath' in setupArkEnv options.`));let{layout:f,baseDir:g}=p(l,_(r?.layout)),v=f===`strict`&&g?g:o.dirname(l),y=o.join(v,`generated`,`env.gen.ts`),x=r?.outputPath?o.resolve(r.outputPath):y,S=r?.codegen??!0;if(S)try{b(l,x,f,r?.standard)}catch(e){let t=e instanceof Error?e.message:String(e);throw Error(n(`Failed to generate env.gen.ts: ${t}`))}if(r?.validate??!0)try{globalThis.__arkenv_force_server__=!0;let e=f===`strict`&&g?o.join(g,`server.ts`):l,t=typeof __filename<`u`?__filename:import.meta.url?s(import.meta.url):``,n=o.dirname(t),r=a.existsSync(o.join(n,`mock-server-only.ts`))?o.join(n,`mock-server-only.ts`):o.join(n,`mock-server-only.js`);h(e,{moduleCache:!1,fsCache:!1,tsconfigPaths:!0,alias:{"server-only":r,"./script":r,"./script.tsx":r,...c?._jitiAliases}})(e)}catch(n){e(`Environment validation failed:`),i(n instanceof Error?n.message:String(n)),t(),process.exit(1)}finally{delete globalThis.__arkenv_force_server__}(process.env.NODE_ENV===`development`||process.env.NEXT_PHASE===`phase-development-server`)&&S&&m(f===`strict`&&g?[o.join(g,`internal`,`shared.ts`),o.join(g,`client.ts`),o.join(g,`server.ts`)].filter(a.existsSync):[l],()=>{b(l,x,f,r?.standard)})}function y(e,t){return v(t),e}function b(e,t,n,r){let{layout:i,baseDir:s}=p(e,_(n)),c=``;if(i===`strict`){let e=o.join(s,`client.ts`),t=o.join(s,`internal`,`shared.ts`),n=a.existsSync(e)?a.readFileSync(e,`utf-8`):``,i=a.existsSync(t)?a.readFileSync(t,`utf-8`):``,d=!!r||n.includes(`@arkenv/standard`)||n.includes(`arkenv/standard`)||i.includes(`@arkenv/standard`)||i.includes(`arkenv/standard`);c=O(l(n),u(i),d)}else{let t=a.readFileSync(e,`utf-8`),n=!!r||t.includes(`@arkenv/standard`)||t.includes(`arkenv/standard`),{clientKeys:i,sharedKeys:o,isLegacy:s}=S(t);c=s?E(i,o,n):D(i,o,n)}let d=o.dirname(t);a.existsSync(d)||a.mkdirSync(d,{recursive:!0});let f=!0;a.existsSync(t)&&a.readFileSync(t,`utf-8`)===c&&(f=!1),f&&a.writeFileSync(t,c,`utf-8`)}function x(e){let t=/\b(?:arkenv|createEnv)\s*\(/g;for(;t.exec(e)!==null;){let n=1,r=t.lastIndex,i=null,a=null,o=0,s=0,c=[],l=``;for(;r<e.length&&n>0;){let t=e[r],u=e[r+1];if(a===`single`){(t===`
|
|
2
|
+
`||t===`\r`)&&(a=null),l+=t,r++;continue}if(a===`multi`){if(t===`*`&&u===`/`){a=null,l+=`*/`,r+=2;continue}l+=t,r++;continue}if(i){t===i&&e[r-1]!==`\\`&&(i=null),l+=t,r++;continue}if(t===`/`&&u===`/`){a=`single`,l+=`//`,r+=2;continue}if(t===`/`&&u===`*`){a=`multi`,l+=`/*`,r+=2;continue}if(t===`'`||t===`"`||t==="`"){i=t,l+=t,r++;continue}if(t===`(`?n++:t===`)`?n--:t===`{`?o++:t===`}`?o--:t===`[`?s++:t===`]`&&s--,n===0){c.push(l);break}t===`,`&&n===1&&o===0&&s===0?(c.push(l),l=``):l+=t,r++}if(n===0&&c.length>0)return{schemaArg:c[0].trim(),optionsArg:c[1]?c[1].trim():null}}return null}function S(e){let t=[],n=[],r=x(e);if(!r)return{clientKeys:t,sharedKeys:n,isLegacy:!1};let i=f(r.schemaArg.replace(/^\{/,``).replace(/\}$/,``).trim()),a=i.includes(`client`)||i.includes(`server`)||i.includes(`shared`);if(a){let e=c(r.schemaArg,`client`);e&&t.push(...f(e));let i=c(r.schemaArg,`shared`);i&&n.push(...f(i))}else{let e=[];if(r.optionsArg){let t=r.optionsArg.match(/exposeToClient\s*:\s*\[([\s\S]*?)\]/)||r.optionsArg.match(/expose\s*:\s*\[([\s\S]*?)\]/)||r.optionsArg.match(/shared\s*:\s*\[([\s\S]*?)\]/);if(t){let n=t[1].matchAll(/['"`](.*?)['"`]/g);for(let t of n)e.push(t[1])}}for(let r of i)e.includes(r)||r===`NODE_ENV`?n.push(r):r.startsWith(`NEXT_PUBLIC_`)&&t.push(r)}return{clientKeys:t,sharedKeys:n,isLegacy:a}}function C(e,t){return Array.from(new Set([...e,...t])).map(e=>`\t\t\t${e}: typeof window !== "undefined" ? (globalThis as any).__arkenv_env__?.${e} ?? process.env.${e} : process.env.${e},`).join(`
|
|
3
|
+
`)}const w=`/* eslint-disable */
|
|
5
4
|
// biome-ignore format: auto-generated
|
|
6
5
|
// Generated by ArkEnv. DO NOT EDIT DIRECTLY.
|
|
7
|
-
`,
|
|
6
|
+
`,T=`
|
|
8
7
|
export default arkenv;
|
|
9
|
-
`;function
|
|
8
|
+
`;function E(e,t,n){let r=C(e,t);return`${w}
|
|
10
9
|
import { arkenv as coreArkenv } from "${n?`@arkenv/nextjs/standard`:`@arkenv/nextjs`}";
|
|
11
10
|
${n?``:`
|
|
12
11
|
export { type } from "@arkenv/nextjs";
|
|
@@ -29,7 +28,7 @@ export function arkenv<
|
|
|
29
28
|
},
|
|
30
29
|
} as any) as any;
|
|
31
30
|
}
|
|
32
|
-
${
|
|
31
|
+
${T}`}function D(e,t,n){let r=C(e,t);return`${w}
|
|
33
32
|
import { arkenv as coreArkenv } from "${n?`@arkenv/nextjs/standard`:`@arkenv/nextjs`}";${n?``:`
|
|
34
33
|
import type { type as at, distill } from "arktype";`}
|
|
35
34
|
${n?``:`
|
|
@@ -62,7 +61,7 @@ export function arkenv<
|
|
|
62
61
|
} as any);
|
|
63
62
|
return env${n?``:` as unknown as Readonly<distill.Out<at.infer<TSchema>>>`};
|
|
64
63
|
}
|
|
65
|
-
${
|
|
64
|
+
${T}`}function O(e,t,n){let r=C(e,t);return`${w}
|
|
66
65
|
import { arkenv as coreArkenv } from "${n?`@arkenv/nextjs/standard/client`:`@arkenv/nextjs/client`}";${n?``:`
|
|
67
66
|
import type { Infer } from "@arkenv/core";`}
|
|
68
67
|
${n?``:`
|
|
@@ -99,5 +98,5 @@ export function arkenv<
|
|
|
99
98
|
},
|
|
100
99
|
} as any);
|
|
101
100
|
}
|
|
102
|
-
${
|
|
101
|
+
${T}`}export{l as extractClientKeys,S as extractKeys,u as extractSharedKeys,b as runCodegen,v as setupArkEnv,y as withArkEnv};
|
|
103
102
|
//# sourceMappingURL=config.js.map
|
package/dist/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","names":[],"sources":["../src/config.ts"],"sourcesContent":["import fs from \"node:fs\";\nimport path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport {\n\textractBlock,\n\textractClientKeys,\n\textractSharedKeys,\n\tfindSchemaPath,\n\tparseBlockKeys,\n\tresolveLayout,\n\twatchSchema,\n} from \"@arkenv/build\";\nimport { createJiti } from \"jiti\";\n\nexport { extractClientKeys, extractSharedKeys };\n\nlet hasWarnedSimpleLayout = false;\n\nfunction normalizeLayout(\n\tlayout: ArkEnvConfigOptions[\"layout\"],\n): \"simple\" | \"strict\" | undefined {\n\tif (layout === \"simple\") {\n\t\tif (process.env.NODE_ENV === \"development\" && !hasWarnedSimpleLayout) {\n\t\t\thasWarnedSimpleLayout = true;\n\t\t\tconsole.warn(\n\t\t\t\t\"⚠️ [arkenv] The 'simple' layout option is deprecated and will be removed in the next major version. Use 'flat' instead.\",\n\t\t\t);\n\t\t}\n\t\treturn \"simple\";\n\t}\n\tif (layout === \"flat\") {\n\t\treturn \"simple\";\n\t}\n\treturn layout;\n}\n\n/**\n * Configuration options for the ArkEnv Next.js integration.\n *\n * @example\n * ```ts\n * const configOptions: ArkEnvConfigOptions = {\n * schemaPath: \"./src/env.ts\",\n * outputPath: \"./src/generated/env.gen.ts\"\n * };\n * ```\n */\nexport type ArkEnvConfigOptions = {\n\t/**\n\t * Specify the path to the schema definition file.\n\t *\n\t * Defaults to searching for `\"src/env.ts\"` or `\"env.ts\"` in the project root.\n\t *\n\t * @default \"src/env.ts\"\n\t * @example\n\t * ```ts\n\t * export default withArkEnv(nextConfig, {\n\t * schemaPath: \"./src/env.ts\"\n\t * });\n\t * ```\n\t */\n\tschemaPath?: string;\n\n\t/**\n\t * Specify the path where the generated file (`env.gen.ts`) should be written.\n\t *\n\t * Defaults to `\"generated/env.gen.ts\"` in the same directory as the schema file.\n\t *\n\t * @default \"[schemaDirectory]/generated/env.gen.ts\"\n\t * @example\n\t * ```ts\n\t * export default withArkEnv(nextConfig, {\n\t * outputPath: \"./src/generated/env.gen.ts\"\n\t * });\n\t * ```\n\t */\n\toutputPath?: string;\n\n\t/**\n\t * Specify the configuration layout.\n\t *\n\t * - `\"flat\"` (default): A single `env.ts` schema file.\n\t * - `\"strict\"`: A 3-file split schema layout (`env/internal/shared.ts`, `env/client.ts`, `env/server.ts`).\n\t *\n\t * @default \"flat\"\n\t */\n\tlayout?:\n\t\t| \"flat\"\n\t\t| \"strict\"\n\t\t/** @deprecated Use `\"flat\"` instead. `\"simple\"` will be removed in the next major version. */\n\t\t| \"simple\";\n\n\t/**\n\t * Force standard mode code generation.\n\t *\n\t * When `true`, the generated `env.gen.ts` imports from `@arkenv/nextjs/standard/*`\n\t * instead of `@arkenv/nextjs/*`, ensuring the Standard Schema engine (`@arkenv/standard`)\n\t * is used and `arktype` is never bundled. This is set automatically when importing from\n\t * `@arkenv/nextjs/standard/config`, but can be toggled manually for custom setups.\n\t *\n\t * @default false\n\t */\n\tstandard?: boolean;\n\n\t/**\n\t * Enable or disable build-time environment variable validation during build/dev startup.\n\t *\n\t * @default true\n\t */\n\tvalidate?: boolean;\n\n\t/**\n\t * Enable or disable automatic code generation of the `env.gen.ts` file.\n\t *\n\t * @default true\n\t */\n\tcodegen?: boolean;\n};\n\n/**\n * Run ArkEnv codegen and setup without wrapping nextConfig.\n *\n * @param options Optional configuration paths for schema and output files\n * @param internalOptions Optional configuration for internal testing hooks\n * @throws An error if the schema file cannot be found or if code generation fails\n */\nexport function setupArkEnv(\n\toptions?: ArkEnvConfigOptions,\n\tinternalOptions?: { _jitiAliases?: Record<string, string> },\n): void {\n\t// 1. Locate the env.ts schema file or strict schema directory\n\tconst schemaPath = options?.schemaPath\n\t\t? path.resolve(options.schemaPath)\n\t\t: findSchemaPath();\n\n\t// Auto-detect layout if not specified\n\tlet exists = false;\n\tif (schemaPath) {\n\t\tif (fs.existsSync(schemaPath)) {\n\t\t\texists = true;\n\t\t} else {\n\t\t\tconst ext = path.extname(schemaPath);\n\t\t\tif (ext) {\n\t\t\t\tconst baseWithoutExt = schemaPath.slice(0, -ext.length);\n\t\t\t\tif (fs.existsSync(baseWithoutExt)) {\n\t\t\t\t\texists = true;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tif (!schemaPath || !exists) {\n\t\tthrow new Error(\n\t\t\t`[ArkEnv] Could not find schema file at ${\n\t\t\t\toptions?.schemaPath || \"src/env.ts or env.ts\"\n\t\t\t}. Please specify 'schemaPath' in setupArkEnv options.`,\n\t\t);\n\t}\n\n\tconst normalizedLayout = normalizeLayout(options?.layout);\n\n\tconst { layout: resolvedLayout, baseDir } = resolveLayout(\n\t\tschemaPath,\n\t\tnormalizedLayout,\n\t);\n\n\t// 2. Determine outputPath (defaults to generated/env.gen.ts in the same directory as schemaPath/baseDir)\n\tconst defaultOutputDir =\n\t\tresolvedLayout === \"strict\" && baseDir ? baseDir : path.dirname(schemaPath);\n\tconst defaultOutputPath = path.join(\n\t\tdefaultOutputDir,\n\t\t\"generated\",\n\t\t\"env.gen.ts\",\n\t);\n\tconst outputPath = options?.outputPath\n\t\t? path.resolve(options.outputPath)\n\t\t: defaultOutputPath;\n\n\t// 3. Run initial code generation if enabled\n\tconst codegen = options?.codegen ?? true;\n\tif (codegen) {\n\t\ttry {\n\t\t\trunCodegen(schemaPath, outputPath, resolvedLayout, options?.standard);\n\t\t} catch (error: unknown) {\n\t\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\t\tthrow new Error(`[ArkEnv] Failed to generate env.gen.ts: ${message}`);\n\t\t}\n\t}\n\n\t// 4. Validate schema against environment variables\n\tconst runValidation = options?.validate ?? true;\n\tif (runValidation) {\n\t\ttry {\n\t\t\t(globalThis as any).__arkenv_force_server__ = true;\n\t\t\tconst fileToEvaluate =\n\t\t\t\tresolvedLayout === \"strict\" && baseDir\n\t\t\t\t\t? path.join(baseDir, \"server.ts\")\n\t\t\t\t\t: schemaPath;\n\n\t\t\tconst filenameForJiti =\n\t\t\t\ttypeof __filename !== \"undefined\"\n\t\t\t\t\t? __filename\n\t\t\t\t\t: typeof import.meta !== \"undefined\" && import.meta.url\n\t\t\t\t\t\t? fileURLToPath(import.meta.url)\n\t\t\t\t\t\t: \"\";\n\t\t\tconst dir = path.dirname(filenameForJiti);\n\t\t\tconst sharedPath = fs.existsSync(path.join(dir, \"shared.ts\"))\n\t\t\t\t? path.join(dir, \"shared.ts\")\n\t\t\t\t: path.join(dir, \"shared.js\");\n\n\t\t\tconst aliases: Record<string, string> = {\n\t\t\t\t\"server-only\": sharedPath,\n\t\t\t\t\"./script\": sharedPath,\n\t\t\t\t\"./script.tsx\": sharedPath,\n\t\t\t\t...internalOptions?._jitiAliases,\n\t\t\t};\n\n\t\t\tconst jiti = createJiti(fileToEvaluate, {\n\t\t\t\tmoduleCache: false,\n\t\t\t\tfsCache: false,\n\t\t\t\ttsconfigPaths: true,\n\t\t\t\talias: aliases,\n\t\t\t});\n\t\t\tjiti(fileToEvaluate);\n\t\t} catch (error: unknown) {\n\t\t\tconsole.error(\"\\n❌ [ArkEnv] Environment validation failed:\");\n\t\t\tconsole.error(error instanceof Error ? error.message : String(error));\n\t\t\tconsole.error(\"\");\n\t\t\tprocess.exit(1);\n\t\t} finally {\n\t\t\tdelete (globalThis as any).__arkenv_force_server__;\n\t\t}\n\t}\n\n\t// 5. Initialize development file watcher if in dev mode and codegen is enabled\n\tconst isDev =\n\t\tprocess.env.NODE_ENV === \"development\" ||\n\t\tprocess.env.NEXT_PHASE === \"phase-development-server\";\n\tif (isDev && codegen) {\n\t\tconst watchPaths =\n\t\t\tresolvedLayout === \"strict\" && baseDir\n\t\t\t\t? [\n\t\t\t\t\t\tpath.join(baseDir, \"internal\", \"shared.ts\"),\n\t\t\t\t\t\tpath.join(baseDir, \"client.ts\"),\n\t\t\t\t\t\tpath.join(baseDir, \"server.ts\"),\n\t\t\t\t\t].filter(fs.existsSync)\n\t\t\t\t: [schemaPath];\n\t\twatchSchema(watchPaths, () => {\n\t\t\trunCodegen(schemaPath, outputPath, resolvedLayout, options?.standard);\n\t\t});\n\t}\n}\n\n/**\n * Wrap a Next.js configuration object to automatically generate the `runtimeEnv` block in `env.gen.ts`.\n *\n * @param nextConfig The Next.js configuration object or function\n * @param options Optional configuration paths for schema and output files\n * @returns The Next.js configuration object unchanged\n * @throws An error if the schema file cannot be found or if code generation fails\n */\nexport function withArkEnv<T>(nextConfig: T, options?: ArkEnvConfigOptions): T {\n\tsetupArkEnv(options);\n\treturn nextConfig;\n}\n\n/**\n * Run code generation to read the schema file and generate the env.gen.ts factory.\n *\n * @param schemaPath The absolute path to the schema file or directory\n * @param outputPath The absolute path to the generated output file\n * @param layoutOption The explicit layout to use; auto-detected from the filesystem when omitted\n * @param forceStandard Force standard mode code generation\n * @throws An error if strict layout files are missing when `layoutOption` is `\"strict\"`\n */\nexport function runCodegen(\n\tschemaPath: string,\n\toutputPath: string,\n\tlayoutOption?: ArkEnvConfigOptions[\"layout\"],\n\tforceStandard?: boolean,\n) {\n\tconst normalizedLayout = normalizeLayout(layoutOption);\n\n\tconst { layout: resolvedLayout, baseDir } = resolveLayout(\n\t\tschemaPath,\n\t\tnormalizedLayout,\n\t);\n\n\tlet generatedCode = \"\";\n\tif (resolvedLayout === \"strict\") {\n\t\tconst clientPath = path.join(baseDir, \"client.ts\");\n\t\tconst sharedPath = path.join(baseDir, \"internal\", \"shared.ts\");\n\n\t\tconst clientContent = fs.existsSync(clientPath)\n\t\t\t? fs.readFileSync(clientPath, \"utf-8\")\n\t\t\t: \"\";\n\t\tconst sharedContent = fs.existsSync(sharedPath)\n\t\t\t? fs.readFileSync(sharedPath, \"utf-8\")\n\t\t\t: \"\";\n\n\t\tconst isStandard =\n\t\t\t!!forceStandard ||\n\t\t\tclientContent.includes(\"@arkenv/standard\") ||\n\t\t\tclientContent.includes(\"arkenv/standard\") ||\n\t\t\tsharedContent.includes(\"@arkenv/standard\") ||\n\t\t\tsharedContent.includes(\"arkenv/standard\");\n\n\t\tconst clientKeys = extractClientKeys(clientContent);\n\t\tconst sharedKeys = extractSharedKeys(sharedContent);\n\n\t\tgeneratedCode = generateClientFactoryCode(\n\t\t\tclientKeys,\n\t\t\tsharedKeys,\n\t\t\tisStandard,\n\t\t);\n\t} else {\n\t\tconst fileContent = fs.readFileSync(schemaPath, \"utf-8\");\n\t\tconst isStandard =\n\t\t\t!!forceStandard ||\n\t\t\tfileContent.includes(\"@arkenv/standard\") ||\n\t\t\tfileContent.includes(\"arkenv/standard\");\n\n\t\tconst { clientKeys, sharedKeys, isLegacy } = extractKeys(fileContent);\n\t\tif (isLegacy) {\n\t\t\tgeneratedCode = generateFactoryCode(clientKeys, sharedKeys, isStandard);\n\t\t} else {\n\t\t\tgeneratedCode = generateFlatFactoryCode(\n\t\t\t\tclientKeys,\n\t\t\t\tsharedKeys,\n\t\t\t\tisStandard,\n\t\t\t);\n\t\t}\n\t}\n\n\t// Ensure parent directory exists\n\tconst outputDir = path.dirname(outputPath);\n\tif (!fs.existsSync(outputDir)) {\n\t\tfs.mkdirSync(outputDir, { recursive: true });\n\t}\n\n\t// Write if changed to avoid unnecessary filesystem/watcher triggers\n\tlet shouldWrite = true;\n\tif (fs.existsSync(outputPath)) {\n\t\tconst existingContent = fs.readFileSync(outputPath, \"utf-8\");\n\t\tif (existingContent === generatedCode) {\n\t\t\tshouldWrite = false;\n\t\t}\n\t}\n\n\tif (shouldWrite) {\n\t\tfs.writeFileSync(outputPath, generatedCode, \"utf-8\");\n\t}\n}\n\nfunction extractCallArguments(\n\tcontent: string,\n): { schemaArg: string; optionsArg: string | null } | null {\n\tconst regex = /\\b(?:arkenv|createEnv)\\s*\\(/g;\n\twhile (regex.exec(content) !== null) {\n\t\tlet parenCount = 1;\n\t\tlet index = regex.lastIndex;\n\t\tlet inString: string | null = null;\n\t\tlet inComment: \"single\" | \"multi\" | null = null;\n\t\tlet braceCount = 0;\n\t\tlet bracketCount = 0;\n\n\t\tconst args: string[] = [];\n\t\tlet currentArg = \"\";\n\n\t\twhile (index < content.length && parenCount > 0) {\n\t\t\tconst char = content[index];\n\t\t\tconst nextChar = content[index + 1];\n\n\t\t\tif (inComment === \"single\") {\n\t\t\t\tif (char === \"\\n\" || char === \"\\r\") inComment = null;\n\t\t\t\tcurrentArg += char;\n\t\t\t\tindex++;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (inComment === \"multi\") {\n\t\t\t\tif (char === \"*\" && nextChar === \"/\") {\n\t\t\t\t\tinComment = null;\n\t\t\t\t\tcurrentArg += \"*/\";\n\t\t\t\t\tindex += 2;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tcurrentArg += char;\n\t\t\t\tindex++;\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif (inString) {\n\t\t\t\tif (char === inString && content[index - 1] !== \"\\\\\") {\n\t\t\t\t\tinString = null;\n\t\t\t\t}\n\t\t\t\tcurrentArg += char;\n\t\t\t\tindex++;\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif (char === \"/\" && nextChar === \"/\") {\n\t\t\t\tinComment = \"single\";\n\t\t\t\tcurrentArg += \"//\";\n\t\t\t\tindex += 2;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (char === \"/\" && nextChar === \"*\") {\n\t\t\t\tinComment = \"multi\";\n\t\t\t\tcurrentArg += \"/*\";\n\t\t\t\tindex += 2;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (char === \"'\" || char === '\"' || char === \"`\") {\n\t\t\t\tinString = char;\n\t\t\t\tcurrentArg += char;\n\t\t\t\tindex++;\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif (char === \"(\") {\n\t\t\t\tparenCount++;\n\t\t\t} else if (char === \")\") {\n\t\t\t\tparenCount--;\n\t\t\t} else if (char === \"{\") {\n\t\t\t\tbraceCount++;\n\t\t\t} else if (char === \"}\") {\n\t\t\t\tbraceCount--;\n\t\t\t} else if (char === \"[\") {\n\t\t\t\tbracketCount++;\n\t\t\t} else if (char === \"]\") {\n\t\t\t\tbracketCount--;\n\t\t\t}\n\n\t\t\tif (parenCount === 0) {\n\t\t\t\targs.push(currentArg);\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tif (\n\t\t\t\tchar === \",\" &&\n\t\t\t\tparenCount === 1 &&\n\t\t\t\tbraceCount === 0 &&\n\t\t\t\tbracketCount === 0\n\t\t\t) {\n\t\t\t\targs.push(currentArg);\n\t\t\t\tcurrentArg = \"\";\n\t\t\t} else {\n\t\t\t\tcurrentArg += char;\n\t\t\t}\n\t\t\tindex++;\n\t\t}\n\n\t\tif (parenCount === 0 && args.length > 0) {\n\t\t\treturn {\n\t\t\t\tschemaArg: args[0].trim(),\n\t\t\t\toptionsArg: args[1] ? args[1].trim() : null,\n\t\t\t};\n\t\t}\n\t}\n\treturn null;\n}\n\n/**\n * Statically extract client and shared keys from the schema content.\n *\n * @param content The schema file string content\n * @returns An object containing the extracted client and shared keys\n */\nexport function extractKeys(content: string): {\n\tclientKeys: string[];\n\tsharedKeys: string[];\n\tisLegacy?: boolean;\n} {\n\tconst clientKeys: string[] = [];\n\tconst sharedKeys: string[] = [];\n\n\tconst args = extractCallArguments(content);\n\tif (!args) {\n\t\treturn { clientKeys, sharedKeys, isLegacy: false };\n\t}\n\n\t// Strip outer braces if present\n\tconst trimmedSchema = args.schemaArg\n\t\t.replace(/^\\{/, \"\")\n\t\t.replace(/\\}$/, \"\")\n\t\t.trim();\n\tconst topKeys = parseBlockKeys(trimmedSchema);\n\tconst isLegacy =\n\t\ttopKeys.includes(\"client\") ||\n\t\ttopKeys.includes(\"server\") ||\n\t\ttopKeys.includes(\"shared\");\n\n\tif (isLegacy) {\n\t\tconst clientBlock = extractBlock(args.schemaArg, \"client\");\n\t\tif (clientBlock) {\n\t\t\tclientKeys.push(...parseBlockKeys(clientBlock));\n\t\t}\n\t\tconst sharedBlock = extractBlock(args.schemaArg, \"shared\");\n\t\tif (sharedBlock) {\n\t\t\tsharedKeys.push(...parseBlockKeys(sharedBlock));\n\t\t}\n\t} else {\n\t\t// New flat layout\n\t\tconst optionExposedKeys: string[] = [];\n\t\tif (args.optionsArg) {\n\t\t\tconst exposeMatch =\n\t\t\t\targs.optionsArg.match(/exposeToClient\\s*:\\s*\\[([\\s\\S]*?)\\]/) ||\n\t\t\t\targs.optionsArg.match(/expose\\s*:\\s*\\[([\\s\\S]*?)\\]/) ||\n\t\t\t\targs.optionsArg.match(/shared\\s*:\\s*\\[([\\s\\S]*?)\\]/);\n\t\t\tif (exposeMatch) {\n\t\t\t\tconst matches = exposeMatch[1].matchAll(/['\"`](.*?)['\"`]/g);\n\t\t\t\tfor (const match of matches) {\n\t\t\t\t\toptionExposedKeys.push(match[1]);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tfor (const key of topKeys) {\n\t\t\t// NODE_ENV is implicitly shared as Next.js automatically inlines and replaces references to process.env.NODE_ENV in browser bundles.\n\t\t\t// See: https://nextjs.org/docs/app/guides/environment-variables\n\t\t\tif (optionExposedKeys.includes(key) || key === \"NODE_ENV\") {\n\t\t\t\tsharedKeys.push(key);\n\t\t\t} else if (key.startsWith(\"NEXT_PUBLIC_\")) {\n\t\t\t\tclientKeys.push(key);\n\t\t\t}\n\t\t}\n\t}\n\n\treturn { clientKeys, sharedKeys, isLegacy };\n}\n\n/**\n * Generate the triple-tab indented runtime environment variables mapping.\n */\nfunction generateRuntimeEnvLines(\n\tclientKeys: string[],\n\tsharedKeys: string[],\n): string {\n\tconst allKeys = Array.from(new Set([...clientKeys, ...sharedKeys]));\n\treturn allKeys\n\t\t.map(\n\t\t\t(key) =>\n\t\t\t\t`\\t\\t\\t${key}: typeof window !== \"undefined\" ? (globalThis as any).__arkenv_env__?.${key} ?? process.env.${key} : process.env.${key},`,\n\t\t)\n\t\t.join(\"\\n\");\n}\n\nconst GENERATED_HEADER = `/* eslint-disable */\n// biome-ignore format: auto-generated\n// Generated by ArkEnv. DO NOT EDIT DIRECTLY.\n`;\n\nconst GENERATED_FOOTER = `\nexport default arkenv;\n`;\n\n/**\n * Generate the TypeScript factory code for the tailored arkenv helper.\n *\n * @param clientKeys The client environment variable keys\n * @param sharedKeys The shared environment variable keys\n * @param isStandard Whether standard mode is used\n * @returns The generated TypeScript source code string\n */\nfunction generateFactoryCode(\n\tclientKeys: string[],\n\tsharedKeys: string[],\n\tisStandard?: boolean,\n): string {\n\tconst runtimeEnvLines = generateRuntimeEnvLines(clientKeys, sharedKeys);\n\tconst importPath = isStandard ? \"@arkenv/nextjs/standard\" : \"@arkenv/nextjs\";\n\tconst coreName = \"arkenv\";\n\tconst typeExport = isStandard\n\t\t? \"\"\n\t\t: '\\nexport { type } from \"@arkenv/nextjs\";\\n';\n\tconst callPrefix = \"coreArkenv\";\n\n\treturn `${GENERATED_HEADER}\nimport { ${coreName} as coreArkenv } from \"${importPath}\";\n${typeExport}\nexport function arkenv<\n\tconst TServer extends Record<string, any> = {},\n\tconst TClient extends Record<string, any> = {},\n\tconst TShared extends Record<string, any> = {},\n>(options: {\n\tserver?: TServer;\n\tclient?: TClient & {\n\t\t[K in keyof TClient]: K extends \\`NEXT_PUBLIC_\\${string}\\` ? unknown : never;\n\t};\n\tshared?: TShared;\n}) {\n\treturn ${callPrefix}({\n\t\t...options,\n\t\truntimeEnv: {\n\t\t\t${runtimeEnvLines}\n\t\t},\n\t} as any) as any;\n}\n${GENERATED_FOOTER}`;\n}\n\n/**\n * Generate the TypeScript factory code for the Flat Layout arkenv helper.\n *\n * @remarks\n * **Architecture tripwire:** Do not statically compile the schema here or\n * reference internal-only types (the `$` scope or `MergeExtends`).\n *\n * - **Generic wrapper:** The factory must stay generic because the concrete\n * schema is owned by the user-land `env.ts`.\n * - **Type strategy:** It intentionally returns the full schema type to ensure\n * flawless Server Component autocomplete.\n * - **Security boundary:** Client-side protection is deliberately deferred to\n * the runtime Proxy in `@arkenv/nextjs`, which throws on unauthorized access.\n *\n * 📖 See ADR-0010: Flat layout codegen and type inference strategy\n * (`docs/adr/0010-flat-layout-codegen-type-strategy.md`).\n */\nfunction generateFlatFactoryCode(\n\tclientKeys: string[],\n\tsharedKeys: string[],\n\tisStandard?: boolean,\n): string {\n\tconst runtimeEnvLines = generateRuntimeEnvLines(clientKeys, sharedKeys);\n\tconst importPath = isStandard ? \"@arkenv/nextjs/standard\" : \"@arkenv/nextjs\";\n\tconst coreName = \"arkenv\";\n\tconst typeExport = isStandard\n\t\t? \"\"\n\t\t: '\\nexport { type } from \"@arkenv/nextjs\";\\n';\n\tconst typeImport = isStandard\n\t\t? \"\"\n\t\t: '\\nimport type { type as at, distill } from \"arktype\";';\n\tconst returnType = isStandard\n\t\t? \"Readonly<TSchema>\"\n\t\t: \"Readonly<distill.Out<at.infer<TSchema>>>\";\n\tconst castReturn = isStandard\n\t\t? \"\"\n\t\t: \" as unknown as Readonly<distill.Out<at.infer<TSchema>>>\";\n\tconst callPrefix = \"coreArkenv\";\n\n\treturn `${GENERATED_HEADER}\nimport { ${coreName} as coreArkenv } from \"${importPath}\";${typeImport}\n${typeExport}\nexport function arkenv<\n\tconst TSchema extends Record<string, unknown> & { runtimeEnv?: never } = {},\n\tconst TExpose extends keyof TSchema = never,\n\tconst TExtends extends readonly unknown[] = [],\n>(\n\tschema: TSchema,\n\toptions?: {\n\t\t/**\n\t\t * Custom environment variables to expose to the client bundle.\n\t\t * By default, variables prefixed with \\`NEXT_PUBLIC_\\` and \\`NODE_ENV\\` are exposed automatically.\n\t\t * Use this option to expose custom variables that do not have the \\`NEXT_PUBLIC_\\` prefix.\n\t\t */\n\t\texposeToClient?: readonly TExpose[];\n\t\textends?: [...TExtends];\n\t},\n): ${returnType} {\n\t// Types expose the full schema for a great DX on the server; the runtime\n\t// Proxy from \\`@arkenv/nextjs\\` enforces the security boundary by throwing\n\t// when a server-only variable is accessed on the client.\n\tconst env = ${callPrefix}(schema as any, {\n\t\t...options,\n\t\truntimeEnv: {\n\t\t\t${runtimeEnvLines}\n\t\t},\n\t} as any);\n\treturn env${castReturn};\n}\n${GENERATED_FOOTER}`;\n}\n\n/**\n * Generate the TypeScript factory code for the strict-layout `arkenv` helper.\n *\n * Unlike `generateFactoryCode`, this variant imports from `@arkenv/nextjs/client`\n * and exposes a positional-schema signature suited for split-file projects.\n *\n * @param clientKeys The env var keys extracted from `client.ts`\n * @param sharedKeys The env var keys extracted from `internal/shared.ts`\n * @param isStandard Whether standard mode is used\n * @returns The generated TypeScript source code string\n */\nfunction generateClientFactoryCode(\n\tclientKeys: string[],\n\tsharedKeys: string[],\n\tisStandard?: boolean,\n): string {\n\tconst runtimeEnvLines = generateRuntimeEnvLines(clientKeys, sharedKeys);\n\tconst importPath = isStandard\n\t\t? \"@arkenv/nextjs/standard/client\"\n\t\t: \"@arkenv/nextjs/client\";\n\tconst coreName = \"arkenv\";\n\tconst typeExport = isStandard\n\t\t? \"\"\n\t\t: '\\nexport { type } from \"@arkenv/nextjs/client\";\\n';\n\tconst typeImport = isStandard\n\t\t? \"\"\n\t\t: '\\nimport type { Infer } from \"@arkenv/core\";';\n\tconst callPrefix = \"coreArkenv\";\n\tconst returnType = isStandard\n\t\t? \"Readonly<TSchema & MergeExtends<TExtends>>\"\n\t\t: \"Readonly<Infer<TSchema> & MergeExtends<TExtends>>\";\n\n\treturn `${GENERATED_HEADER}\nimport { ${coreName} as coreArkenv } from \"${importPath}\";${typeImport}\n${typeExport}\ntype ResolveExtend<T> = [Infer<T>] extends [never] ? T : Infer<T>;\n\ntype UnionToIntersection<U> = (\n\tU extends any ? (k: U) => void : never\n) extends (k: infer I) => void\n\t? I\n\t: never;\n\ntype MergeExtends<TExtends extends readonly unknown[] | undefined> =\n\tTExtends extends readonly unknown[]\n\t\t? UnionToIntersection<ResolveExtend<TExtends[number]>>\n\t\t: {};\n\nexport function arkenv<\n\tconst TSchema extends Record<string, any> = {},\n\tconst TExtends extends readonly unknown[] = [],\n>(\n\tschema: TSchema & {\n\t\t[K in keyof TSchema]: K extends \\`NEXT_PUBLIC_\\${string}\\` ? unknown : never;\n\t},\n\toptions?: {\n\t\textends?: [...TExtends];\n\t},\n): ${returnType} {\n\treturn ${callPrefix}(schema as any, {\n\t\t...options,\n\t\truntimeEnv: {\n\t\t\t${runtimeEnvLines}\n\t\t},\n\t} as any);\n}\n${GENERATED_FOOTER}`;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"config.js","names":["formatBuildError"],"sources":["../src/config.ts"],"sourcesContent":["import fs from \"node:fs\";\nimport path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport {\n\textractBlock,\n\textractClientKeys,\n\textractSharedKeys,\n\tfindSchemaPath,\n\tparseBlockKeys,\n\tresolveLayout,\n\twatchSchema,\n} from \"@arkenv/build\";\nimport {\n\tformatBuildError,\n\tlogBuildError,\n\tlogBuildErrorBlankLine,\n\tlogBuildErrorDetail,\n\tlogBuildWarning,\n} from \"@repo/utils\";\nimport { createJiti } from \"jiti\";\n\nexport { extractClientKeys, extractSharedKeys };\n\nlet hasWarnedSimpleLayout = false;\n\nfunction normalizeLayout(\n\tlayout: ArkEnvConfigOptions[\"layout\"],\n): \"simple\" | \"strict\" | undefined {\n\tif (layout === \"simple\") {\n\t\tif (process.env.NODE_ENV === \"development\" && !hasWarnedSimpleLayout) {\n\t\t\thasWarnedSimpleLayout = true;\n\t\t\tlogBuildWarning(\n\t\t\t\t\"The 'simple' layout option is deprecated and will be removed in the next major version. Use 'flat' instead.\",\n\t\t\t);\n\t\t}\n\t\treturn \"simple\";\n\t}\n\tif (layout === \"flat\") {\n\t\treturn \"simple\";\n\t}\n\treturn layout;\n}\n\n/**\n * Configuration options for the ArkEnv Next.js integration.\n *\n * @example\n * ```ts\n * const configOptions: ArkEnvConfigOptions = {\n * schemaPath: \"./src/env.ts\",\n * outputPath: \"./src/generated/env.gen.ts\"\n * };\n * ```\n */\nexport type ArkEnvConfigOptions = {\n\t/**\n\t * Specify the path to the schema definition file.\n\t *\n\t * Defaults to searching for `\"src/env.ts\"` or `\"env.ts\"` in the project root.\n\t *\n\t * @default \"src/env.ts\"\n\t * @example\n\t * ```ts\n\t * export default withArkEnv(nextConfig, {\n\t * schemaPath: \"./src/env.ts\"\n\t * });\n\t * ```\n\t */\n\tschemaPath?: string;\n\n\t/**\n\t * Specify the path where the generated file (`env.gen.ts`) should be written.\n\t *\n\t * Defaults to `\"generated/env.gen.ts\"` in the same directory as the schema file.\n\t *\n\t * @default \"[schemaDirectory]/generated/env.gen.ts\"\n\t * @example\n\t * ```ts\n\t * export default withArkEnv(nextConfig, {\n\t * outputPath: \"./src/generated/env.gen.ts\"\n\t * });\n\t * ```\n\t */\n\toutputPath?: string;\n\n\t/**\n\t * Specify the configuration layout.\n\t *\n\t * - `\"flat\"` (default): A single `env.ts` schema file.\n\t * - `\"strict\"`: A 3-file split schema layout (`env/internal/shared.ts`, `env/client.ts`, `env/server.ts`).\n\t *\n\t * @default \"flat\"\n\t */\n\tlayout?:\n\t\t| \"flat\"\n\t\t| \"strict\"\n\t\t/** @deprecated Use `\"flat\"` instead. `\"simple\"` will be removed in the next major version. */\n\t\t| \"simple\";\n\n\t/**\n\t * Force standard mode code generation.\n\t *\n\t * When `true`, the generated `env.gen.ts` imports from `@arkenv/nextjs/standard/*`\n\t * instead of `@arkenv/nextjs/*`, ensuring the Standard Schema engine (`@arkenv/standard`)\n\t * is used and `arktype` is never bundled. This is set automatically when importing from\n\t * `@arkenv/nextjs/standard/config`, but can be toggled manually for custom setups.\n\t *\n\t * @default false\n\t */\n\tstandard?: boolean;\n\n\t/**\n\t * Enable or disable build-time environment variable validation during build/dev startup.\n\t *\n\t * @default true\n\t */\n\tvalidate?: boolean;\n\n\t/**\n\t * Enable or disable automatic code generation of the `env.gen.ts` file.\n\t *\n\t * @default true\n\t */\n\tcodegen?: boolean;\n};\n\n/**\n * Run ArkEnv codegen and setup without wrapping nextConfig.\n *\n * @param options Optional configuration paths for schema and output files\n * @param internalOptions Optional configuration for internal testing hooks\n * @throws An error if the schema file cannot be found or if code generation fails\n */\nexport function setupArkEnv(\n\toptions?: ArkEnvConfigOptions,\n\tinternalOptions?: { _jitiAliases?: Record<string, string> },\n): void {\n\t// 1. Locate the env.ts schema file or strict schema directory\n\tconst schemaPath = options?.schemaPath\n\t\t? path.resolve(options.schemaPath)\n\t\t: findSchemaPath();\n\n\t// Auto-detect layout if not specified\n\tlet exists = false;\n\tif (schemaPath) {\n\t\tif (fs.existsSync(schemaPath)) {\n\t\t\texists = true;\n\t\t} else {\n\t\t\tconst ext = path.extname(schemaPath);\n\t\t\tif (ext) {\n\t\t\t\tconst baseWithoutExt = schemaPath.slice(0, -ext.length);\n\t\t\t\tif (fs.existsSync(baseWithoutExt)) {\n\t\t\t\t\texists = true;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tif (!schemaPath || !exists) {\n\t\tthrow new Error(\n\t\t\tformatBuildError(\n\t\t\t\t`Could not find schema file at ${\n\t\t\t\t\toptions?.schemaPath || \"src/env.ts or env.ts\"\n\t\t\t\t}. Please specify 'schemaPath' in setupArkEnv options.`,\n\t\t\t),\n\t\t);\n\t}\n\n\tconst normalizedLayout = normalizeLayout(options?.layout);\n\n\tconst { layout: resolvedLayout, baseDir } = resolveLayout(\n\t\tschemaPath,\n\t\tnormalizedLayout,\n\t);\n\n\t// 2. Determine outputPath (defaults to generated/env.gen.ts in the same directory as schemaPath/baseDir)\n\tconst defaultOutputDir =\n\t\tresolvedLayout === \"strict\" && baseDir ? baseDir : path.dirname(schemaPath);\n\tconst defaultOutputPath = path.join(\n\t\tdefaultOutputDir,\n\t\t\"generated\",\n\t\t\"env.gen.ts\",\n\t);\n\tconst outputPath = options?.outputPath\n\t\t? path.resolve(options.outputPath)\n\t\t: defaultOutputPath;\n\n\t// 3. Run initial code generation if enabled\n\tconst codegen = options?.codegen ?? true;\n\tif (codegen) {\n\t\ttry {\n\t\t\trunCodegen(schemaPath, outputPath, resolvedLayout, options?.standard);\n\t\t} catch (error: unknown) {\n\t\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\t\tthrow new Error(\n\t\t\t\tformatBuildError(`Failed to generate env.gen.ts: ${message}`),\n\t\t\t);\n\t\t}\n\t}\n\n\t// 4. Validate schema against environment variables\n\tconst runValidation = options?.validate ?? true;\n\tif (runValidation) {\n\t\ttry {\n\t\t\t(globalThis as any).__arkenv_force_server__ = true;\n\t\t\tconst fileToEvaluate =\n\t\t\t\tresolvedLayout === \"strict\" && baseDir\n\t\t\t\t\t? path.join(baseDir, \"server.ts\")\n\t\t\t\t\t: schemaPath;\n\n\t\t\tconst filenameForJiti =\n\t\t\t\ttypeof __filename !== \"undefined\"\n\t\t\t\t\t? __filename\n\t\t\t\t\t: typeof import.meta !== \"undefined\" && import.meta.url\n\t\t\t\t\t\t? fileURLToPath(import.meta.url)\n\t\t\t\t\t\t: \"\";\n\t\t\tconst dir = path.dirname(filenameForJiti);\n\t\t\tconst mockServerOnlyPath = fs.existsSync(\n\t\t\t\tpath.join(dir, \"mock-server-only.ts\"),\n\t\t\t)\n\t\t\t\t? path.join(dir, \"mock-server-only.ts\")\n\t\t\t\t: path.join(dir, \"mock-server-only.js\");\n\n\t\t\tconst aliases: Record<string, string> = {\n\t\t\t\t\"server-only\": mockServerOnlyPath,\n\t\t\t\t\"./script\": mockServerOnlyPath,\n\t\t\t\t\"./script.tsx\": mockServerOnlyPath,\n\t\t\t\t...internalOptions?._jitiAliases,\n\t\t\t};\n\n\t\t\tconst jiti = createJiti(fileToEvaluate, {\n\t\t\t\tmoduleCache: false,\n\t\t\t\tfsCache: false,\n\t\t\t\ttsconfigPaths: true,\n\t\t\t\talias: aliases,\n\t\t\t});\n\t\t\tjiti(fileToEvaluate);\n\t\t} catch (error: unknown) {\n\t\t\tlogBuildError(\"Environment validation failed:\");\n\t\t\tlogBuildErrorDetail(\n\t\t\t\terror instanceof Error ? error.message : String(error),\n\t\t\t);\n\t\t\tlogBuildErrorBlankLine();\n\t\t\tprocess.exit(1);\n\t\t} finally {\n\t\t\tdelete (globalThis as any).__arkenv_force_server__;\n\t\t}\n\t}\n\n\t// 5. Initialize development file watcher if in dev mode and codegen is enabled\n\tconst isDev =\n\t\tprocess.env.NODE_ENV === \"development\" ||\n\t\tprocess.env.NEXT_PHASE === \"phase-development-server\";\n\tif (isDev && codegen) {\n\t\tconst watchPaths =\n\t\t\tresolvedLayout === \"strict\" && baseDir\n\t\t\t\t? [\n\t\t\t\t\t\tpath.join(baseDir, \"internal\", \"shared.ts\"),\n\t\t\t\t\t\tpath.join(baseDir, \"client.ts\"),\n\t\t\t\t\t\tpath.join(baseDir, \"server.ts\"),\n\t\t\t\t\t].filter(fs.existsSync)\n\t\t\t\t: [schemaPath];\n\t\twatchSchema(watchPaths, () => {\n\t\t\trunCodegen(schemaPath, outputPath, resolvedLayout, options?.standard);\n\t\t});\n\t}\n}\n\n/**\n * Wrap a Next.js configuration object to automatically generate the `runtimeEnv` block in `env.gen.ts`.\n *\n * @param nextConfig The Next.js configuration object or function\n * @param options Optional configuration paths for schema and output files\n * @returns The Next.js configuration object unchanged\n * @throws An error if the schema file cannot be found or if code generation fails\n */\nexport function withArkEnv<T>(nextConfig: T, options?: ArkEnvConfigOptions): T {\n\tsetupArkEnv(options);\n\treturn nextConfig;\n}\n\n/**\n * Run code generation to read the schema file and generate the env.gen.ts factory.\n *\n * @param schemaPath The absolute path to the schema file or directory\n * @param outputPath The absolute path to the generated output file\n * @param layoutOption The explicit layout to use; auto-detected from the filesystem when omitted\n * @param forceStandard Force standard mode code generation\n * @throws An error if strict layout files are missing when `layoutOption` is `\"strict\"`\n */\nexport function runCodegen(\n\tschemaPath: string,\n\toutputPath: string,\n\tlayoutOption?: ArkEnvConfigOptions[\"layout\"],\n\tforceStandard?: boolean,\n) {\n\tconst normalizedLayout = normalizeLayout(layoutOption);\n\n\tconst { layout: resolvedLayout, baseDir } = resolveLayout(\n\t\tschemaPath,\n\t\tnormalizedLayout,\n\t);\n\n\tlet generatedCode = \"\";\n\tif (resolvedLayout === \"strict\") {\n\t\tconst clientPath = path.join(baseDir, \"client.ts\");\n\t\tconst sharedPath = path.join(baseDir, \"internal\", \"shared.ts\");\n\n\t\tconst clientContent = fs.existsSync(clientPath)\n\t\t\t? fs.readFileSync(clientPath, \"utf-8\")\n\t\t\t: \"\";\n\t\tconst sharedContent = fs.existsSync(sharedPath)\n\t\t\t? fs.readFileSync(sharedPath, \"utf-8\")\n\t\t\t: \"\";\n\n\t\tconst isStandard =\n\t\t\t!!forceStandard ||\n\t\t\tclientContent.includes(\"@arkenv/standard\") ||\n\t\t\tclientContent.includes(\"arkenv/standard\") ||\n\t\t\tsharedContent.includes(\"@arkenv/standard\") ||\n\t\t\tsharedContent.includes(\"arkenv/standard\");\n\n\t\tconst clientKeys = extractClientKeys(clientContent);\n\t\tconst sharedKeys = extractSharedKeys(sharedContent);\n\n\t\tgeneratedCode = generateClientFactoryCode(\n\t\t\tclientKeys,\n\t\t\tsharedKeys,\n\t\t\tisStandard,\n\t\t);\n\t} else {\n\t\tconst fileContent = fs.readFileSync(schemaPath, \"utf-8\");\n\t\tconst isStandard =\n\t\t\t!!forceStandard ||\n\t\t\tfileContent.includes(\"@arkenv/standard\") ||\n\t\t\tfileContent.includes(\"arkenv/standard\");\n\n\t\tconst { clientKeys, sharedKeys, isLegacy } = extractKeys(fileContent);\n\t\tif (isLegacy) {\n\t\t\tgeneratedCode = generateFactoryCode(clientKeys, sharedKeys, isStandard);\n\t\t} else {\n\t\t\tgeneratedCode = generateFlatFactoryCode(\n\t\t\t\tclientKeys,\n\t\t\t\tsharedKeys,\n\t\t\t\tisStandard,\n\t\t\t);\n\t\t}\n\t}\n\n\t// Ensure parent directory exists\n\tconst outputDir = path.dirname(outputPath);\n\tif (!fs.existsSync(outputDir)) {\n\t\tfs.mkdirSync(outputDir, { recursive: true });\n\t}\n\n\t// Write if changed to avoid unnecessary filesystem/watcher triggers\n\tlet shouldWrite = true;\n\tif (fs.existsSync(outputPath)) {\n\t\tconst existingContent = fs.readFileSync(outputPath, \"utf-8\");\n\t\tif (existingContent === generatedCode) {\n\t\t\tshouldWrite = false;\n\t\t}\n\t}\n\n\tif (shouldWrite) {\n\t\tfs.writeFileSync(outputPath, generatedCode, \"utf-8\");\n\t}\n}\n\nfunction extractCallArguments(\n\tcontent: string,\n): { schemaArg: string; optionsArg: string | null } | null {\n\tconst regex = /\\b(?:arkenv|createEnv)\\s*\\(/g;\n\twhile (regex.exec(content) !== null) {\n\t\tlet parenCount = 1;\n\t\tlet index = regex.lastIndex;\n\t\tlet inString: string | null = null;\n\t\tlet inComment: \"single\" | \"multi\" | null = null;\n\t\tlet braceCount = 0;\n\t\tlet bracketCount = 0;\n\n\t\tconst args: string[] = [];\n\t\tlet currentArg = \"\";\n\n\t\twhile (index < content.length && parenCount > 0) {\n\t\t\tconst char = content[index];\n\t\t\tconst nextChar = content[index + 1];\n\n\t\t\tif (inComment === \"single\") {\n\t\t\t\tif (char === \"\\n\" || char === \"\\r\") inComment = null;\n\t\t\t\tcurrentArg += char;\n\t\t\t\tindex++;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (inComment === \"multi\") {\n\t\t\t\tif (char === \"*\" && nextChar === \"/\") {\n\t\t\t\t\tinComment = null;\n\t\t\t\t\tcurrentArg += \"*/\";\n\t\t\t\t\tindex += 2;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tcurrentArg += char;\n\t\t\t\tindex++;\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif (inString) {\n\t\t\t\tif (char === inString && content[index - 1] !== \"\\\\\") {\n\t\t\t\t\tinString = null;\n\t\t\t\t}\n\t\t\t\tcurrentArg += char;\n\t\t\t\tindex++;\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif (char === \"/\" && nextChar === \"/\") {\n\t\t\t\tinComment = \"single\";\n\t\t\t\tcurrentArg += \"//\";\n\t\t\t\tindex += 2;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (char === \"/\" && nextChar === \"*\") {\n\t\t\t\tinComment = \"multi\";\n\t\t\t\tcurrentArg += \"/*\";\n\t\t\t\tindex += 2;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (char === \"'\" || char === '\"' || char === \"`\") {\n\t\t\t\tinString = char;\n\t\t\t\tcurrentArg += char;\n\t\t\t\tindex++;\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif (char === \"(\") {\n\t\t\t\tparenCount++;\n\t\t\t} else if (char === \")\") {\n\t\t\t\tparenCount--;\n\t\t\t} else if (char === \"{\") {\n\t\t\t\tbraceCount++;\n\t\t\t} else if (char === \"}\") {\n\t\t\t\tbraceCount--;\n\t\t\t} else if (char === \"[\") {\n\t\t\t\tbracketCount++;\n\t\t\t} else if (char === \"]\") {\n\t\t\t\tbracketCount--;\n\t\t\t}\n\n\t\t\tif (parenCount === 0) {\n\t\t\t\targs.push(currentArg);\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tif (\n\t\t\t\tchar === \",\" &&\n\t\t\t\tparenCount === 1 &&\n\t\t\t\tbraceCount === 0 &&\n\t\t\t\tbracketCount === 0\n\t\t\t) {\n\t\t\t\targs.push(currentArg);\n\t\t\t\tcurrentArg = \"\";\n\t\t\t} else {\n\t\t\t\tcurrentArg += char;\n\t\t\t}\n\t\t\tindex++;\n\t\t}\n\n\t\tif (parenCount === 0 && args.length > 0) {\n\t\t\treturn {\n\t\t\t\tschemaArg: args[0].trim(),\n\t\t\t\toptionsArg: args[1] ? args[1].trim() : null,\n\t\t\t};\n\t\t}\n\t}\n\treturn null;\n}\n\n/**\n * Statically extract client and shared keys from the schema content.\n *\n * @param content The schema file string content\n * @returns An object containing the extracted client and shared keys\n */\nexport function extractKeys(content: string): {\n\tclientKeys: string[];\n\tsharedKeys: string[];\n\tisLegacy?: boolean;\n} {\n\tconst clientKeys: string[] = [];\n\tconst sharedKeys: string[] = [];\n\n\tconst args = extractCallArguments(content);\n\tif (!args) {\n\t\treturn { clientKeys, sharedKeys, isLegacy: false };\n\t}\n\n\t// Strip outer braces if present\n\tconst trimmedSchema = args.schemaArg\n\t\t.replace(/^\\{/, \"\")\n\t\t.replace(/\\}$/, \"\")\n\t\t.trim();\n\tconst topKeys = parseBlockKeys(trimmedSchema);\n\tconst isLegacy =\n\t\ttopKeys.includes(\"client\") ||\n\t\ttopKeys.includes(\"server\") ||\n\t\ttopKeys.includes(\"shared\");\n\n\tif (isLegacy) {\n\t\tconst clientBlock = extractBlock(args.schemaArg, \"client\");\n\t\tif (clientBlock) {\n\t\t\tclientKeys.push(...parseBlockKeys(clientBlock));\n\t\t}\n\t\tconst sharedBlock = extractBlock(args.schemaArg, \"shared\");\n\t\tif (sharedBlock) {\n\t\t\tsharedKeys.push(...parseBlockKeys(sharedBlock));\n\t\t}\n\t} else {\n\t\t// New flat layout\n\t\tconst optionExposedKeys: string[] = [];\n\t\tif (args.optionsArg) {\n\t\t\tconst exposeMatch =\n\t\t\t\targs.optionsArg.match(/exposeToClient\\s*:\\s*\\[([\\s\\S]*?)\\]/) ||\n\t\t\t\targs.optionsArg.match(/expose\\s*:\\s*\\[([\\s\\S]*?)\\]/) ||\n\t\t\t\targs.optionsArg.match(/shared\\s*:\\s*\\[([\\s\\S]*?)\\]/);\n\t\t\tif (exposeMatch) {\n\t\t\t\tconst matches = exposeMatch[1].matchAll(/['\"`](.*?)['\"`]/g);\n\t\t\t\tfor (const match of matches) {\n\t\t\t\t\toptionExposedKeys.push(match[1]);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tfor (const key of topKeys) {\n\t\t\t// NODE_ENV is implicitly shared as Next.js automatically inlines and replaces references to process.env.NODE_ENV in browser bundles.\n\t\t\t// See: https://nextjs.org/docs/app/guides/environment-variables\n\t\t\tif (optionExposedKeys.includes(key) || key === \"NODE_ENV\") {\n\t\t\t\tsharedKeys.push(key);\n\t\t\t} else if (key.startsWith(\"NEXT_PUBLIC_\")) {\n\t\t\t\tclientKeys.push(key);\n\t\t\t}\n\t\t}\n\t}\n\n\treturn { clientKeys, sharedKeys, isLegacy };\n}\n\n/**\n * Generate the triple-tab indented runtime environment variables mapping.\n */\nfunction generateRuntimeEnvLines(\n\tclientKeys: string[],\n\tsharedKeys: string[],\n): string {\n\tconst allKeys = Array.from(new Set([...clientKeys, ...sharedKeys]));\n\treturn allKeys\n\t\t.map(\n\t\t\t(key) =>\n\t\t\t\t`\\t\\t\\t${key}: typeof window !== \"undefined\" ? (globalThis as any).__arkenv_env__?.${key} ?? process.env.${key} : process.env.${key},`,\n\t\t)\n\t\t.join(\"\\n\");\n}\n\nconst GENERATED_HEADER = `/* eslint-disable */\n// biome-ignore format: auto-generated\n// Generated by ArkEnv. DO NOT EDIT DIRECTLY.\n`;\n\nconst GENERATED_FOOTER = `\nexport default arkenv;\n`;\n\n/**\n * Generate the TypeScript factory code for the tailored arkenv helper.\n *\n * @param clientKeys The client environment variable keys\n * @param sharedKeys The shared environment variable keys\n * @param isStandard Whether standard mode is used\n * @returns The generated TypeScript source code string\n */\nfunction generateFactoryCode(\n\tclientKeys: string[],\n\tsharedKeys: string[],\n\tisStandard?: boolean,\n): string {\n\tconst runtimeEnvLines = generateRuntimeEnvLines(clientKeys, sharedKeys);\n\tconst importPath = isStandard ? \"@arkenv/nextjs/standard\" : \"@arkenv/nextjs\";\n\tconst coreName = \"arkenv\";\n\tconst typeExport = isStandard\n\t\t? \"\"\n\t\t: '\\nexport { type } from \"@arkenv/nextjs\";\\n';\n\tconst callPrefix = \"coreArkenv\";\n\n\treturn `${GENERATED_HEADER}\nimport { ${coreName} as coreArkenv } from \"${importPath}\";\n${typeExport}\nexport function arkenv<\n\tconst TServer extends Record<string, any> = {},\n\tconst TClient extends Record<string, any> = {},\n\tconst TShared extends Record<string, any> = {},\n>(options: {\n\tserver?: TServer;\n\tclient?: TClient & {\n\t\t[K in keyof TClient]: K extends \\`NEXT_PUBLIC_\\${string}\\` ? unknown : never;\n\t};\n\tshared?: TShared;\n}) {\n\treturn ${callPrefix}({\n\t\t...options,\n\t\truntimeEnv: {\n\t\t\t${runtimeEnvLines}\n\t\t},\n\t} as any) as any;\n}\n${GENERATED_FOOTER}`;\n}\n\n/**\n * Generate the TypeScript factory code for the Flat Layout arkenv helper.\n *\n * @remarks\n * **Architecture tripwire:** Do not statically compile the schema here or\n * reference internal-only types (the `$` scope or `MergeExtends`).\n *\n * - **Generic wrapper:** The factory must stay generic because the concrete\n * schema is owned by the user-land `env.ts`.\n * - **Type strategy:** It intentionally returns the full schema type to ensure\n * flawless Server Component autocomplete.\n * - **Security boundary:** Client-side protection is deliberately deferred to\n * the runtime Proxy in `@arkenv/nextjs`, which throws on unauthorized access.\n * 📖 See ADR-0013: Flat layout codegen and type inference strategy\n * (`docs/adr/0013-flat-layout-codegen-type-strategy.md`).\n */\nfunction generateFlatFactoryCode(\n\tclientKeys: string[],\n\tsharedKeys: string[],\n\tisStandard?: boolean,\n): string {\n\tconst runtimeEnvLines = generateRuntimeEnvLines(clientKeys, sharedKeys);\n\tconst importPath = isStandard ? \"@arkenv/nextjs/standard\" : \"@arkenv/nextjs\";\n\tconst coreName = \"arkenv\";\n\tconst typeExport = isStandard\n\t\t? \"\"\n\t\t: '\\nexport { type } from \"@arkenv/nextjs\";\\n';\n\tconst typeImport = isStandard\n\t\t? \"\"\n\t\t: '\\nimport type { type as at, distill } from \"arktype\";';\n\tconst returnType = isStandard\n\t\t? \"Readonly<TSchema>\"\n\t\t: \"Readonly<distill.Out<at.infer<TSchema>>>\";\n\tconst castReturn = isStandard\n\t\t? \"\"\n\t\t: \" as unknown as Readonly<distill.Out<at.infer<TSchema>>>\";\n\tconst callPrefix = \"coreArkenv\";\n\n\treturn `${GENERATED_HEADER}\nimport { ${coreName} as coreArkenv } from \"${importPath}\";${typeImport}\n${typeExport}\nexport function arkenv<\n\tconst TSchema extends Record<string, unknown> & { runtimeEnv?: never } = {},\n\tconst TExpose extends keyof TSchema = never,\n\tconst TExtends extends readonly unknown[] = [],\n>(\n\tschema: TSchema,\n\toptions?: {\n\t\t/**\n\t\t * Custom environment variables to expose to the client bundle.\n\t\t * By default, variables prefixed with \\`NEXT_PUBLIC_\\` and \\`NODE_ENV\\` are exposed automatically.\n\t\t * Use this option to expose custom variables that do not have the \\`NEXT_PUBLIC_\\` prefix.\n\t\t */\n\t\texposeToClient?: readonly TExpose[];\n\t\textends?: [...TExtends];\n\t},\n): ${returnType} {\n\t// Types expose the full schema for a great DX on the server; the runtime\n\t// Proxy from \\`@arkenv/nextjs\\` enforces the security boundary by throwing\n\t// when a server-only variable is accessed on the client.\n\tconst env = ${callPrefix}(schema as any, {\n\t\t...options,\n\t\truntimeEnv: {\n\t\t\t${runtimeEnvLines}\n\t\t},\n\t} as any);\n\treturn env${castReturn};\n}\n${GENERATED_FOOTER}`;\n}\n\n/**\n * Generate the TypeScript factory code for the strict-layout `arkenv` helper.\n *\n * Unlike `generateFactoryCode`, this variant imports from `@arkenv/nextjs/client`\n * and exposes a positional-schema signature suited for split-file projects.\n *\n * @param clientKeys The env var keys extracted from `client.ts`\n * @param sharedKeys The env var keys extracted from `internal/shared.ts`\n * @param isStandard Whether standard mode is used\n * @returns The generated TypeScript source code string\n */\nfunction generateClientFactoryCode(\n\tclientKeys: string[],\n\tsharedKeys: string[],\n\tisStandard?: boolean,\n): string {\n\tconst runtimeEnvLines = generateRuntimeEnvLines(clientKeys, sharedKeys);\n\tconst importPath = isStandard\n\t\t? \"@arkenv/nextjs/standard/client\"\n\t\t: \"@arkenv/nextjs/client\";\n\tconst coreName = \"arkenv\";\n\tconst typeExport = isStandard\n\t\t? \"\"\n\t\t: '\\nexport { type } from \"@arkenv/nextjs/client\";\\n';\n\tconst typeImport = isStandard\n\t\t? \"\"\n\t\t: '\\nimport type { Infer } from \"@arkenv/core\";';\n\tconst callPrefix = \"coreArkenv\";\n\tconst returnType = isStandard\n\t\t? \"Readonly<TSchema & MergeExtends<TExtends>>\"\n\t\t: \"Readonly<Infer<TSchema> & MergeExtends<TExtends>>\";\n\n\treturn `${GENERATED_HEADER}\nimport { ${coreName} as coreArkenv } from \"${importPath}\";${typeImport}\n${typeExport}\ntype ResolveExtend<T> = [Infer<T>] extends [never] ? T : Infer<T>;\n\ntype UnionToIntersection<U> = (\n\tU extends any ? (k: U) => void : never\n) extends (k: infer I) => void\n\t? I\n\t: never;\n\ntype MergeExtends<TExtends extends readonly unknown[] | undefined> =\n\tTExtends extends readonly unknown[]\n\t\t? UnionToIntersection<ResolveExtend<TExtends[number]>>\n\t\t: {};\n\nexport function arkenv<\n\tconst TSchema extends Record<string, any> = {},\n\tconst TExtends extends readonly unknown[] = [],\n>(\n\tschema: TSchema & {\n\t\t[K in keyof TSchema]: K extends \\`NEXT_PUBLIC_\\${string}\\` ? unknown : never;\n\t},\n\toptions?: {\n\t\textends?: [...TExtends];\n\t},\n): ${returnType} {\n\treturn ${callPrefix}(schema as any, {\n\t\t...options,\n\t\truntimeEnv: {\n\t\t\t${runtimeEnvLines}\n\t\t},\n\t} as any);\n}\n${GENERATED_FOOTER}`;\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
const e=(e,t=2,{dontDetectNewlines:n=!1}={})=>n?`${` `.repeat(t)}${e}`:e.split(`
|
|
2
|
+
`).map(e=>`${` `.repeat(t)}${e}`).join(`
|
|
3
|
+
`),t={red:`\x1B[31m`,yellow:`\x1B[33m`,cyan:`\x1B[36m`,reset:`\x1B[0m`},n=()=>typeof process<`u`&&process.versions!=null&&process.versions.node!=null,r=()=>!!(!n()||process.env.NO_COLOR!==void 0||process.env.CI!==void 0||process.stdout&&!process.stdout.isTTY),i=(e,i)=>n()&&!r()?`${t[e]}${i}${t.reset}`:i;function a(e){return e.map(e=>`${i(`yellow`,e.path)} ${e.message.trimStart()}`).join(`
|
|
4
|
+
`)}Object.defineProperty(class extends Error{constructor(t,n=`Errors found while validating environment variables`){let r=a(t);super(`${i(`red`,n)}\n${e(r)}\n`),this.name=`ArkEnvError`,this.issues=t}},`name`,{value:`ArkEnvError`});const o=`[ArkEnv]`;function s(e){return`${o} ${e}`}function c(e){console.warn(`⚠️ ${o} ${e}`)}function l(e){console.error(`❌ ${o} ${e}`)}function u(e){console.error(e)}function d(){console.error(``)}Object.defineProperty(exports,`a`,{enumerable:!0,get:function(){return l}}),Object.defineProperty(exports,`i`,{enumerable:!0,get:function(){return d}}),Object.defineProperty(exports,`n`,{enumerable:!0,get:function(){return s}}),Object.defineProperty(exports,`r`,{enumerable:!0,get:function(){return c}}),Object.defineProperty(exports,`t`,{enumerable:!0,get:function(){return u}});
|
|
5
|
+
//# sourceMappingURL=dist-BGE7U5kQ.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dist-BGE7U5kQ.cjs","names":[],"sources":["../../internal/utils/dist/index.js"],"sourcesContent":["const e=e=>{if(typeof e==`number`||typeof e!=`string`||!e.trim())return e;if(e.trim()===`NaN`)return NaN;let t=Number(e);return Number.isNaN(t)?e:t},t=e=>e===`true`?!0:e===`false`?!1:e,n=e=>{if(typeof e!=`string`)return e;let t=e.trim();if(t[0]!==`{`&&t[0]!==`[`)return e;try{return JSON.parse(t)}catch{return e}},r=e=>{if(e instanceof Date||typeof e!=`string`||!e.trim())return e;let t=new Date(e);return Number.isNaN(t.getTime())?e:t},i=e=>{let t={};for(let n in e){let r=e[n];r!==``&&(t[n]=r)}return t},a=`*`,o=(e,t=[])=>{let n=[];if(!e||typeof e!=`object`||Array.isArray(e))return n;let r=e;if(`const`in r){let e=typeof r.const;(e===`number`||e===`boolean`)&&n.push({path:[...t],type:`primitive`})}`enum`in r&&Array.isArray(r.enum)&&r.enum.some(e=>typeof e==`number`||typeof e==`boolean`)&&n.push({path:[...t],type:`primitive`});let i=r.type;if(i===`number`||i===`integer`||i===`boolean`)n.push({path:[...t],type:`primitive`});else if(i===`string`&&`format`in r&&(r.format===`date-time`||r.format===`date`))n.push({path:[...t],type:`date`});else if(i===`object`){if(r.properties&&Object.keys(r.properties).length>0){n.push({path:[...t],type:`object`});for(let e in r.properties)n.push(...o(r.properties[e],[...t,e]))}}else i===`array`&&(n.push({path:[...t],type:`array`}),r.items&&(Array.isArray(r.items)?r.items.forEach((e,r)=>{n.push(...o(e,[...t,String(r)]))}):n.push(...o(r.items,[...t,`*`]))));for(let e of[`anyOf`,`allOf`,`oneOf`])if(r[e]&&Array.isArray(r[e]))for(let i of r[e])n.push(...o(i,t));let a=new Set;return n.filter(e=>{let t=e.path.join(`/`)+`:`+e.type;return a.has(t)?!1:a.add(t)})},s=(i,a,o={})=>{let{arrayFormat:s=`comma`}=o,c=e=>{if(s===`json`)try{return JSON.parse(e)}catch{return e}return e.trim()?e.split(`,`).map(e=>e.trim()):[]},l=(i,a)=>{if(a===`array`&&typeof i==`string`)return c(i);if(a===`object`&&typeof i==`string`)return n(i);if(a===`date`&&typeof i==`string`)return r(i);if(a===`primitive`){if(Array.isArray(i))return i.map(n=>{if(typeof n!=`string`)return n;let r=e(n);return typeof r==`number`?r:t(n)});if(typeof i!=`string`)return i;let n=e(i);return typeof n==`number`?n:t(i)}return i};if(typeof i!=`object`||!i){let e=a.find(e=>e.path.length===0);return e?l(i,e.type):i}let u=[...a].sort((e,t)=>e.path.length-t.path.length),d=(e,t,n)=>{if(t.length===0)return n(e);let[r,...i]=t;if(r===`*`){if(Array.isArray(e)){let t=!1,r=e.map(e=>{let r=d(e,i,n);return r!==e&&(t=!0),r});return t?r:e}return e}if(!e||typeof e!=`object`)return e;if(Array.isArray(e)){let t=Number(r);if(!Number.isNaN(t)&&t>=0&&t<e.length){let r=d(e[t],i,n);if(r!==e[t]){let n=[...e];return n[t]=r,n}}return e}if(Object.hasOwn(e,r)){let t=d(e[r],i,n);if(t!==e[r])return{...e,[r]:t}}return e},f=i;for(let e of u)e.path.length>0&&(f=d(f,e.path,t=>l(t,e.type)));return f};function c(e,t,n,r){let a=t?i(e):e,c={...a},l=[];if(r){let e=r();l.push(...e.missingKeys||[]),e.hasSchema&&(c=s(c,o(e.schema),{arrayFormat:n}))}return{processedEnv:a,coercedEnv:c,missingKeys:l}}const l=(e,t=2,{dontDetectNewlines:n=!1}={})=>n?`${` `.repeat(t)}${e}`:e.split(`\n`).map(e=>`${` `.repeat(t)}${e}`).join(`\n`),u={red:`\\x1B[31m`,yellow:`\\x1B[33m`,cyan:`\\x1B[36m`,reset:`\\x1B[0m`},d=()=>typeof process<`u`&&process.versions!=null&&process.versions.node!=null,f=()=>!!(!d()||process.env.NO_COLOR!==void 0||process.env.CI!==void 0||process.stdout&&!process.stdout.isTTY),p=(e,t)=>d()&&!f()?`${u[e]}${t}${u.reset}`:t;function m(e){return e.map(e=>`${p(`yellow`,e.path)} ${e.message.trimStart()}`).join(`\n`)}var h=class extends Error{constructor(e,t=`Errors found while validating environment variables`){let n=m(e);super(`${p(`red`,t)}\\n${l(n)}\\n`),this.name=`ArkEnvError`,this.issues=e}};Object.defineProperty(h,`name`,{value:`ArkEnvError`});function g(e,t){if(typeof t==`string`)throw new h([{path:e,message:`ArkType DSL strings are not supported in \"standard\" mode. Use a Standard Schema validator (e.g., Zod, Valibot) or import from \"arkenv\" for ArkType schemas.`,code:`INVALID_SCHEMA`}])}function _(e,t){let n=t&&typeof t==`object`&&`~standard`in t&&t[`~standard`];if(!n||typeof n!=`object`||!(`validate`in n)||typeof n.validate!=`function`)throw new h([{path:e,message:`Invalid validator: expected a Standard Schema 1.0 validator (must have \"~standard\" property). Import from \"arkenv\" to use ArkType schemas.`,code:`INVALID_SCHEMA`}])}function v(e){if(!e||typeof e!=`object`||Array.isArray(e))throw new h([{path:``,message:`Invalid schema: expected an object mapping in \"standard\" mode.`,code:`INVALID_SCHEMA`}])}const y=/secret|(_|^)key(_|$)|token|(_|^)password(_|$)|(_|^)pass(_|$)|(_|^)auth(_|$)|jwt|cert|credential|database_url|db_url/i;function b(e){if(e!==void 0)return e;if(typeof process>`u`)return!1;let t=process.env.ARKENV_DEBUG_SECRETS;return t===`true`||t===`1`}function x(e){return y.test(e)&&!/public/i.test(e)}function S(e,t,n){let r=b(n?.debugSecrets);if(e===void 0)return`missing`;if(e===null)return`null`;if(!r&&x(t))return`[REDACTED]`;if(typeof e==`string`)return JSON.stringify(e);if(typeof e==`number`||typeof e==`boolean`||typeof e==`bigint`)return String(e);if(typeof e==`symbol`)return e.toString();if(typeof e==`function`)return`[Function]`;if(e&&typeof e==`object`)try{if(Array.isArray(e)){let r=e.slice(0,3).map(e=>S(e,t,n));return e.length>3&&r.push(`...(+${e.length-3} more)`),`[${r.join(`, `)}]`}let r=Object.keys(e),i=r.slice(0,3).map(r=>`${r}: ${S(e[r],t,n)}`);return r.length>3&&i.push(`...(+${r.length-3} more)`),`{ ${i.join(`, `)} }`}catch{return Object.prototype.toString.call(e)}return String(e)}const C={too_small:`VALUE_TOO_SMALL`,too_big:`VALUE_TOO_LARGE`,invalid_string:`INVALID_FORMAT`,invalid_date:`INVALID_FORMAT`,custom:`INVALID_FORMAT`};function w(e,t,n){let r=t.toLowerCase();return e===`invalid_type`&&(n===void 0||n===`undefined`)||r===`required`?`MISSING_VARIABLE`:e in C?C[e]:/regex|pattern|match/.test(r)?`PATTERN_MISMATCH`:`INVALID_TYPE`}function T(e){let t=e.minimum??e.min,n=e.maximum??e.max;return{...typeof t==`number`?{min:t}:{},...typeof n==`number`?{max:n}:{}}}function E(e){try{return{success:!0,data:e()}}catch(e){if(e instanceof h)return{success:!1,issues:e.issues};throw e}}function D(e,t,n,r,i,a){let o={path:e,message:t,code:n,meta:r??{}};return i&&(o.expected=i),a!==void 0&&(o.received=a),o}function O(e,t,n,r,i,a){if(t===`MISSING_VARIABLE`)return n?`must be ${n} (was missing)`:`is required`;if(e.includes(`(was `))return e;let o=`(was ${p(`cyan`,!b(a?.debugSecrets)&&x(i)?`[REDACTED]`:S(r,i,a))})`;return n&&!e.includes(`Expected`)?`must be ${n} ${o}`:`${e} ${o}`}function k(e){let t={type:`object`,properties:{}},n=!1,r=[];for(let i in e){let a=e[i];if(!a){r.push(i);continue}let o=a[`~standard`];if(typeof o?.jsonSchema?.input==`function`)try{let e=o.jsonSchema.input({target:`draft-07`});if(e){t.properties[i]=e,n=!0;continue}}catch{}if(typeof a.jsonSchema?.input==`function`)try{let e=a.jsonSchema.input({target:`draft-07`});if(e){t.properties[i]=e,n=!0;continue}}catch{}if(typeof a.toJSONSchema==`function`)try{let e=a.toJSONSchema();if(e){t.properties[i]=e,n=!0;continue}}catch{}if(typeof a.toStandardJSONSchema?.v1==`function`)try{let e=a.toStandardJSONSchema.v1();if(e){t.properties[i]=e,n=!0;continue}}catch{}r.push(i)}return{jsonSchema:t,hasJsonSchema:n,missingKeys:r}}function A(e){return typeof e==`object`&&e&&`key`in e?String(e.key):String(e)}function j(e,t){return!t||t.length===0?e:[e,...t.map(A)].join(`.`)}function M(e,t){let n=e,r;try{let i=e,a=e.trim();if(a[0]===`{`||a[0]===`[`)try{i=JSON.parse(e)}catch(e){r=`[Unparseable JSON: ${e.message}]`}if(!r){for(let e of t)i=i?.[A(e)];n=i}}catch(e){r=`[Traversal error: ${e.message}]`}return{receivedVal:n,traversalError:r}}function N(e,t){let{env:n=process.env,onUndeclaredKey:r=`delete`,coerce:i=!0,arrayFormat:a=`comma`,emptyAsUndefined:o=!1}=t,s={},l=[],{processedEnv:u,coercedEnv:d,missingKeys:f}=c(n,o,a,i?()=>{let{jsonSchema:t,hasJsonSchema:n,missingKeys:r}=k(e);return{schema:t,hasSchema:n,missingKeys:r}}:void 0),p=new Set(Object.keys(u));for(let n in e){let r=e[n],a=d[n];if(!r||typeof r!=`object`||!(`~standard`in r))throw new h([D(n,`Invalid schema: expected a Standard Schema 1.0 validator (e.g. Zod, Valibot) in 'standard' mode.`,`INVALID_SCHEMA`)]);let o=r[`~standard`].validate(a);if(o instanceof Promise)throw new h([D(n,`Async validation is not supported. ArkEnv is synchronous.`,`INVALID_SCHEMA`)]);if(o.issues)for(let e of o.issues){let r=j(n,e.path),a,o;if(n in u){let t=u[n];if(typeof t==`string`&&e.path?.length){let n=M(t,e.path);a=n.receivedVal,o=n.traversalError}else a=t}else a=e.received;let s=w(e.code||`invalid_type`,e.message||``,a),c=e.expected||void 0,d={...T(e)},p=e;p.validation!==void 0&&(d.validation=p.validation),o!==void 0&&(d.traversalError=o);let m=O(e.message||``,s,c,a,r,t);i&&f.includes(n)&&(m+=` (Hint: coercion is enabled by default, but the validator for '${n}' lacks Standard JSON Schema support.)`),l.push(D(r,m,s,d,c,a))}else s[n]=o.value;p.delete(n)}if(r!==`delete`)for(let e of p)r===`reject`?l.push(D(e,`Undeclared key`,`UNDECLARED_KEY`)):r===`ignore`&&(s[e]=d[e]);if(l.length>0)throw new h(l);return s}function P(e){if(!e||typeof e!=`object`&&typeof e!=`function`)return[];if(e.json&&typeof e.json==`object`&&e.json.domain===`object`){let t=[];if(Array.isArray(e.json.required))for(let n of e.json.required)n&&typeof n==`object`&&`key`in n&&t.push(n.key);if(Array.isArray(e.json.optional))for(let n of e.json.optional)n&&typeof n==`object`&&`key`in n&&t.push(n.key);return t}let t=e[`~standard`],n=typeof t?.jsonSchema?.input==`function`&&t.jsonSchema.input||typeof e.jsonSchema?.input==`function`&&e.jsonSchema.input;if(n)try{let e=n({target:`draft-07`});if(e&&typeof e==`object`&&e.properties)return Object.keys(e.properties)}catch{}if(typeof e.toJSONSchema==`function`)try{let t=e.toJSONSchema();if(t&&typeof t==`object`&&t.properties)return Object.keys(t.properties)}catch{}if(typeof e.toStandardJSONSchema?.v1==`function`)try{let t=e.toStandardJSONSchema.v1();if(t&&typeof t==`object`&&t.properties)return Object.keys(t.properties)}catch{}return Object.keys(e)}const F=`[ArkEnv]`,I=`[ArkEnv Watcher]`;function L(e){return`${F} ${e}`}function R(e){console.warn(`⚠️ ${F} ${e}`)}function z(e){console.error(`❌ ${F} ${e}`)}function B(e){console.error(e)}function V(){console.error(``)}function H(e){console.error(`${I} ${e}`)}function U(e){return e instanceof Error?e.stack??e.message:String(e)}function W(e,t){z(e),B(U(t))}function G(e,t){H(e),B(U(t))}function K(e,t,n){e(`${t}: ${n instanceof Error?n.message:String(n)}`),n instanceof Error&&n.stack&&e(n.stack)}export{a as ARRAY_ITEM_MARKER,h as ArkEnvError,F as BUILD_PREFIX,I as WATCHER_PREFIX,s as applyCoercion,g as assertNotArkTypeDsl,_ as assertStandardSchema,v as assertStandardSchemaMap,D as buildEnvIssue,t as coerceBoolean,r as coerceDate,c as coerceEnvironment,n as coerceJson,e as coerceNumber,k as extractJsonSchema,o as findCoercionPaths,L as formatBuildError,U as formatErrorCause,j as formatIssuePath,m as formatIssues,O as formatStandardIssueMessage,A as getProp,P as getSchemaKeys,T as getStandardMeta,l as indent,b as isDebugSecrets,z as logBuildError,V as logBuildErrorBlankLine,B as logBuildErrorDetail,W as logBuildErrorWithCause,R as logBuildWarning,K as logErrorWithCauseVia,H as logWatcherError,G as logWatcherErrorWithCause,w as mapStandardCode,N as parseStandard,E as safeExecute,S as safeStringify,x as shouldRedact,i as stripEmptyStrings,p as styleText,M as traverseReceivedValue};\n//# sourceMappingURL=index.js.map"],"mappings":"AAA45F,MAAM,GAAG,EAAE,EAAE,EAAE,CAAC,mBAAmB,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,OAAO,EAAE,GAAG,IAAI,EAAE,MAAM;EACz+F,CAAC,IAAI,GAAG,GAAG,IAAI,OAAO,EAAE,GAAG,IAAI,CAAC,KAAK;EACrC,CAAC,EAAE,CAAC,IAAI,WAAW,OAAO,WAAW,KAAK,WAAW,MAAM,UAAU,CAAC,MAAM,OAAO,QAAQ,KAAK,QAAQ,UAAU,MAAM,QAAQ,SAAS,MAAM,KAAK,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,QAAQ,IAAI,WAAW,IAAK,IAAG,QAAQ,IAAI,KAAK,IAAK,IAAG,QAAQ,QAAQ,CAAC,QAAQ,OAAO,OAAO,GAAG,EAAE,IAAI,GAAG,EAAE,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,EAAE,CAAC,OAAO,EAAE,IAAI,GAAG,GAAG,EAAE,SAAS,EAAE,KAAK,CAAC,GAAG,EAAE,QAAQ,WAAW,GAAG,CAAC,KAAK;EACpY,CAAuL,OAAO,eAAe,cAAxL,KAAK,CAAC,YAAY,EAAE,EAAE,sDAAsD,CAAC,IAAI,EAAE,EAAE,EAAE,CAAC,MAAM,GAAG,EAAE,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,KAAK,cAAc,KAAK,OAAO,IAA4B,OAAO,CAAC,MAAM,cAAc,CAAC,CAA+qM,MAAM,EAAE,WAAgC,SAAS,EAAE,EAAE,CAAC,MAAM,GAAG,EAAE,GAAG,IAAI,SAAS,EAAE,EAAE,CAAC,QAAQ,KAAK,MAAM,EAAE,GAAG,IAAI,CAAC,SAAS,EAAE,EAAE,CAAC,QAAQ,MAAM,KAAK,EAAE,GAAG,IAAI,CAAC,SAAS,EAAE,EAAE,CAAC,QAAQ,MAAM,EAAE,CAAC,SAAS,GAAG,CAAC,QAAQ,MAAM,GAAG"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
const e=(e,t=2,{dontDetectNewlines:n=!1}={})=>n?`${` `.repeat(t)}${e}`:e.split(`
|
|
2
|
+
`).map(e=>`${` `.repeat(t)}${e}`).join(`
|
|
3
|
+
`),t={red:`\x1B[31m`,yellow:`\x1B[33m`,cyan:`\x1B[36m`,reset:`\x1B[0m`},n=()=>typeof process<`u`&&process.versions!=null&&process.versions.node!=null,r=()=>!!(!n()||process.env.NO_COLOR!==void 0||process.env.CI!==void 0||process.stdout&&!process.stdout.isTTY),i=(e,i)=>n()&&!r()?`${t[e]}${i}${t.reset}`:i;function a(e){return e.map(e=>`${i(`yellow`,e.path)} ${e.message.trimStart()}`).join(`
|
|
4
|
+
`)}Object.defineProperty(class extends Error{constructor(t,n=`Errors found while validating environment variables`){let r=a(t);super(`${i(`red`,n)}\n${e(r)}\n`),this.name=`ArkEnvError`,this.issues=t}},`name`,{value:`ArkEnvError`});const o=`[ArkEnv]`;function s(e){return`${o} ${e}`}function c(e){console.warn(`⚠️ ${o} ${e}`)}function l(e){console.error(`❌ ${o} ${e}`)}function u(e){console.error(e)}function d(){console.error(``)}export{l as a,d as i,s as n,c as r,u as t};
|
|
5
|
+
//# sourceMappingURL=dist-Ce46CxRV.js.map
|