@arkenv/nextjs 0.0.5 → 0.0.7

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/README.md CHANGED
@@ -32,13 +32,13 @@ export default withArkEnv(nextConfig);
32
32
 
33
33
  ### 2. Define your schema in `env.ts`
34
34
 
35
- Import `createEnv` from the generated `./generated/env.gen` file instead of the package:
35
+ Import `arkenv` from the generated `./generated/env.gen` file instead of the package:
36
36
 
37
37
  ```typescript
38
38
  // src/env.ts
39
- import { createEnv } from "./generated/env.gen";
39
+ import arkenv from "./generated/env.gen";
40
40
 
41
- export const env = createEnv({
41
+ export const env = arkenv({
42
42
  server: {
43
43
  DATABASE_URL: "string",
44
44
  STRIPE_API_KEY: "string",
@@ -79,11 +79,28 @@ Then, import from the custom location:
79
79
 
80
80
  ```typescript
81
81
  // src/env.ts
82
- import { createEnv } from "./generated/env.gen";
82
+ import arkenv from "./generated/env.gen";
83
83
 
84
- export const env = createEnv({
84
+ export const env = arkenv({
85
85
  client: {
86
86
  NEXT_PUBLIC_API_URL: "string",
87
87
  }
88
88
  });
89
89
  ```
90
+
91
+ ---
92
+
93
+ ## The Danger of Shared Variables
94
+
95
+ > [!WARNING]
96
+ > Restrict the `shared` block only to `NODE_ENV`. Avoid placing custom variables (like `PORT` or other custom configuration) in the `shared` block.
97
+
98
+ ### The Undefined Fallback Bug
99
+
100
+ Next.js statically strips `process.env` references from client-side bundles unless they are prefixed with `NEXT_PUBLIC_`.
101
+ If you define a custom variable in `shared` with a default value (e.g., `PORT` defaulting to `3000` or `THEME` defaulting to `'dark'`), the environment behaves asymmetrically:
102
+
103
+ - On the **server**, ArkEnv reads the actual value from the environment (e.g. `PORT = 8080`).
104
+ - On the **client**, Next.js strips `process.env.PORT` to `undefined`, causing ArkEnv to fall back to the default value (`3000`).
105
+
106
+ This asymmetry causes React hydration mismatches and corrupts client-side state. Always place non-prefixed variables under `server` so they are strictly server-only.
package/dist/config.cjs CHANGED
@@ -1,7 +1,7 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});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));let c=require(`node:fs`);c=s(c,1);let l=require(`node:path`);l=s(l,1);let u=require(`chokidar`),d=!1;function f(e,t){let n=t?.schemaPath?l.default.resolve(t.schemaPath):m(),r=!1;if(n)if(c.default.existsSync(n))r=!0;else{let e=l.default.extname(n);if(e){let t=n.slice(0,-e.length);c.default.existsSync(t)&&(r=!0)}}if(!n||!r)throw Error(`[ArkEnv] Could not find schema file at ${t?.schemaPath||`src/env.ts or env.ts`}. Please specify 'schemaPath' in withArkEnv options.`);let{layout:i,baseDir:a}=p(n,t?.layout),o=i===`strict`&&a?a:l.default.dirname(n),s=l.default.join(o,`generated`,`env.gen.ts`),u=t?.outputPath?l.default.resolve(t.outputPath):s;try{g(n,u,i)}catch(e){let t=e instanceof Error?e.message:String(e);throw Error(`[ArkEnv] Failed to generate env.gen.ts: ${t}`)}return(process.env.NODE_ENV===`development`||process.env.NEXT_PHASE===`phase-development-server`)&&h(i===`strict`&&a?[l.default.join(a,`internal`,`shared.ts`),l.default.join(a,`client.ts`),l.default.join(a,`server.ts`)].filter(c.default.existsSync):[n],u,i),e}function p(e,t){let n=e=>c.default.existsSync(l.default.join(e,`internal`,`shared.ts`))&&c.default.existsSync(l.default.join(e,`client.ts`))&&c.default.existsSync(l.default.join(e,`server.ts`)),r=e=>{let t=l.default.extname(e),n=t?e.slice(0,-t.length):e;return c.default.existsSync(n)&&c.default.statSync(n).isDirectory()?n:e};if(!t){let t=r(e);if(c.default.existsSync(t)&&c.default.statSync(t).isDirectory())return n(t)?{layout:`strict`,baseDir:t}:{layout:`simple`,baseDir:t};let i=l.default.dirname(e),a=l.default.extname(e),o=a?e.slice(0,-a.length):e;return c.default.existsSync(o)&&c.default.statSync(o).isDirectory()&&n(o)?{layout:`strict`,baseDir:o}:n(i)?{layout:`strict`,baseDir:i}:l.default.basename(i)===`internal`&&n(l.default.dirname(i))?{layout:`strict`,baseDir:l.default.dirname(i)}:{layout:`simple`,baseDir:e}}if(t===`strict`){let t,n=r(e);if(c.default.existsSync(n)&&c.default.statSync(n).isDirectory())t=n;else{let n=l.default.dirname(e);t=l.default.basename(n)===`internal`?l.default.dirname(n):n}let i=l.default.join(t,`client.ts`),a=l.default.join(t,`internal`,`shared.ts`);if(!c.default.existsSync(i)||!c.default.existsSync(a))throw Error(`[ArkEnv] Strict layout requires "${i}" and "${a}" to exist. Ensure both files are present or remove the 'layout: "strict"' option to let ArkEnv auto-detect.`);return{layout:`strict`,baseDir:t}}return{layout:`simple`,baseDir:e}}function m(){let e=[l.default.join(process.cwd(),`src`,`env.ts`),l.default.join(process.cwd(),`env.ts`)];for(let t of e)if(c.default.existsSync(t))return t;let t=[l.default.join(process.cwd(),`src`,`env`),l.default.join(process.cwd(),`env`)];for(let e of t)if(c.default.existsSync(e)&&c.default.existsSync(l.default.join(e,`internal`,`shared.ts`))&&c.default.existsSync(l.default.join(e,`client.ts`))&&c.default.existsSync(l.default.join(e,`server.ts`)))return e;return null}function h(e,t,n){if(!d){d=!0;try{(0,u.watch)(e,{ignoreInitial:!0}).on(`change`,()=>{try{g(Array.isArray(e)?e[0]:e,t,n)}catch(e){let t=e instanceof Error?e.message:String(e);console.error(`[ArkEnv Watcher] Failed to regenerate env.gen.ts: ${t}`)}})}catch(t){let n=t instanceof Error?t.message:String(t);console.error(`[ArkEnv Watcher] Failed to start watch on ${e}: ${n}`)}}}function g(e,t,n){let{layout:r,baseDir:i}=p(e,n),a=``;if(r===`strict`){let e=l.default.join(i,`client.ts`),t=l.default.join(i,`internal`,`shared.ts`),n=c.default.existsSync(e)?c.default.readFileSync(e,`utf-8`):``,r=c.default.existsSync(t)?c.default.readFileSync(t,`utf-8`):``;a=x(S(n),C(r))}else{let{clientKeys:t,sharedKeys:n}=_(c.default.readFileSync(e,`utf-8`));a=b(t,n)}let o=l.default.dirname(t);c.default.existsSync(o)||c.default.mkdirSync(o,{recursive:!0});let s=!0;c.default.existsSync(t)&&c.default.readFileSync(t,`utf-8`)===a&&(s=!1),s&&c.default.writeFileSync(t,a,`utf-8`)}function _(e){let t=[],n=[],r=v(e,`client`);r&&t.push(...y(r));let i=v(e,`shared`);return i&&n.push(...y(i)),{clientKeys:t,sharedKeys:n}}function v(e,t){let n=RegExp(`\\b${t}\\s*:\\s*(?:[a-zA-Z0-9_$.]+\\s*\\(\\s*)?\\{`,`g`);if(!n.exec(e))return null;let r=n.lastIndex,i=1,a=r,o=null,s=null;for(;a<e.length&&i>0;){let t=e[a],n=e[a+1];if(s===`single`){(t===`
2
- `||t===`\r`)&&(s=null),a++;continue}if(s===`multi`){if(t===`*`&&n===`/`){s=null,a+=2;continue}a++;continue}if(o){t===o&&e[a-1]!==`\\`&&(o=null),a++;continue}if(t===`/`&&n===`/`){s=`single`,a+=2;continue}if(t===`/`&&n===`*`){s=`multi`,a+=2;continue}if(t===`'`||t===`"`||t==="`"){o=t,a++;continue}t===`{`?i++:t===`}`&&i--,a++}return i===0?e.slice(r,a-1):null}function y(e){let t=[],n=null,r=null,i=``,a=``,o=0;for(let s=0;s<e.length;s++){let c=e[s],l=e[s+1];if(r===`single`){(c===`
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});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));let c=require(`node:fs`);c=s(c,1);let l=require(`node:path`);l=s(l,1);let u=require(`chokidar`);function d(e,t){let n=t?.schemaPath?l.default.resolve(t.schemaPath):p(),r=!1;if(n)if(c.default.existsSync(n))r=!0;else{let e=l.default.extname(n);if(e){let t=n.slice(0,-e.length);c.default.existsSync(t)&&(r=!0)}}if(!n||!r)throw Error(`[ArkEnv] Could not find schema file at ${t?.schemaPath||`src/env.ts or env.ts`}. Please specify 'schemaPath' in withArkEnv options.`);let{layout:i,baseDir:a}=f(n,t?.layout),o=i===`strict`&&a?a:l.default.dirname(n),s=l.default.join(o,`generated`,`env.gen.ts`),u=t?.outputPath?l.default.resolve(t.outputPath):s;try{h(n,u,i)}catch(e){let t=e instanceof Error?e.message:String(e);throw Error(`[ArkEnv] Failed to generate env.gen.ts: ${t}`)}return(process.env.NODE_ENV===`development`||process.env.NEXT_PHASE===`phase-development-server`)&&m(i===`strict`&&a?[l.default.join(a,`internal`,`shared.ts`),l.default.join(a,`client.ts`),l.default.join(a,`server.ts`)].filter(c.default.existsSync):[n],u,i),e}function f(e,t){let n=e=>c.default.existsSync(l.default.join(e,`internal`,`shared.ts`))&&c.default.existsSync(l.default.join(e,`client.ts`))&&c.default.existsSync(l.default.join(e,`server.ts`)),r=e=>{let t=l.default.extname(e),n=t?e.slice(0,-t.length):e;return c.default.existsSync(n)&&c.default.statSync(n).isDirectory()?n:e};if(!t){let t=r(e);if(c.default.existsSync(t)&&c.default.statSync(t).isDirectory())return n(t)?{layout:`strict`,baseDir:t}:{layout:`simple`,baseDir:t};let i=l.default.dirname(e),a=l.default.extname(e),o=a?e.slice(0,-a.length):e;return c.default.existsSync(o)&&c.default.statSync(o).isDirectory()&&n(o)?{layout:`strict`,baseDir:o}:n(i)?{layout:`strict`,baseDir:i}:l.default.basename(i)===`internal`&&n(l.default.dirname(i))?{layout:`strict`,baseDir:l.default.dirname(i)}:{layout:`simple`,baseDir:e}}if(t===`strict`){let t,n=r(e);if(c.default.existsSync(n)&&c.default.statSync(n).isDirectory())t=n;else{let n=l.default.dirname(e);t=l.default.basename(n)===`internal`?l.default.dirname(n):n}let i=l.default.join(t,`client.ts`),a=l.default.join(t,`internal`,`shared.ts`);if(!c.default.existsSync(i)||!c.default.existsSync(a))throw Error(`[ArkEnv] Strict layout requires "${i}" and "${a}" to exist. Ensure both files are present or remove the 'layout: "strict"' option to let ArkEnv auto-detect.`);return{layout:`strict`,baseDir:t}}return{layout:`simple`,baseDir:e}}function p(){let e=[l.default.join(process.cwd(),`src`,`env.ts`),l.default.join(process.cwd(),`env.ts`)];for(let t of e)if(c.default.existsSync(t))return t;let t=[l.default.join(process.cwd(),`src`,`env`),l.default.join(process.cwd(),`env`)];for(let e of t)if(c.default.existsSync(e)&&c.default.existsSync(l.default.join(e,`internal`,`shared.ts`))&&c.default.existsSync(l.default.join(e,`client.ts`))&&c.default.existsSync(l.default.join(e,`server.ts`)))return e;return null}function m(e,t,n){let r=globalThis.__arkenv_watcher__;r&&typeof r.close==`function`&&r.close().catch(e=>{let t=e instanceof Error?e.message:String(e);console.error(`[ArkEnv Watcher] Failed to close previous watcher: ${t}`)});try{let r=(0,u.watch)(e,{ignoreInitial:!0});globalThis.__arkenv_watcher__=r,r.on(`change`,()=>{try{h(Array.isArray(e)?e[0]:e,t,n)}catch(e){let t=e instanceof Error?e.message:String(e);console.error(`[ArkEnv Watcher] Failed to regenerate env.gen.ts: ${t}`)}})}catch(t){let n=t instanceof Error?t.message:String(t);console.error(`[ArkEnv Watcher] Failed to start watch on ${e}: ${n}`)}}function h(e,t,n){let{layout:r,baseDir:i}=f(e,n),a=``;if(r===`strict`){let e=l.default.join(i,`client.ts`),t=l.default.join(i,`internal`,`shared.ts`),n=c.default.existsSync(e)?c.default.readFileSync(e,`utf-8`):``,r=c.default.existsSync(t)?c.default.readFileSync(t,`utf-8`):``;a=b(x(n),S(r))}else{let{clientKeys:t,sharedKeys:n}=g(c.default.readFileSync(e,`utf-8`));a=y(t,n)}let o=l.default.dirname(t);c.default.existsSync(o)||c.default.mkdirSync(o,{recursive:!0});let s=!0;c.default.existsSync(t)&&c.default.readFileSync(t,`utf-8`)===a&&(s=!1),s&&c.default.writeFileSync(t,a,`utf-8`)}function g(e){let t=[],n=[],r=_(e,`client`);r&&t.push(...v(r));let i=_(e,`shared`);return i&&n.push(...v(i)),{clientKeys:t,sharedKeys:n}}function _(e,t){let n=RegExp(`\\b${t}\\s*:\\s*(?:[a-zA-Z0-9_$.]+\\s*\\(\\s*)?\\{`,`g`);if(!n.exec(e))return null;let r=n.lastIndex,i=1,a=r,o=null,s=null;for(;a<e.length&&i>0;){let t=e[a],n=e[a+1];if(s===`single`){(t===`
2
+ `||t===`\r`)&&(s=null),a++;continue}if(s===`multi`){if(t===`*`&&n===`/`){s=null,a+=2;continue}a++;continue}if(o){t===o&&e[a-1]!==`\\`&&(o=null),a++;continue}if(t===`/`&&n===`/`){s=`single`,a+=2;continue}if(t===`/`&&n===`*`){s=`multi`,a+=2;continue}if(t===`'`||t===`"`||t==="`"){o=t,a++;continue}t===`{`?i++:t===`}`&&i--,a++}return i===0?e.slice(r,a-1):null}function v(e){let t=[],n=null,r=null,i=``,a=``,o=0;for(let s=0;s<e.length;s++){let c=e[s],l=e[s+1];if(r===`single`){(c===`
3
3
  `||c===`\r`)&&(r=null);continue}if(r===`multi`){c===`*`&&l===`/`&&(r=null,s++);continue}if(n){c===n&&e[s-1]!==`\\`?(n=null,a=i,i=``):i+=c;continue}if(c===`/`&&l===`/`){r=`single`,s++;continue}if(c===`/`&&l===`*`){r=`multi`,s++;continue}if(c===`'`||c===`"`||c==="`"){n=c,i=``;continue}if(c===`{`){o++,i=``,a=``;continue}if(c===`}`){o--,i=``,a=``;continue}if(c===`:`){if(o===0){let e=i.trim()||a.trim();e&&t.push(e)}i=``,a=``;continue}/[a-zA-Z0-9_$]/.test(c)?i+=c:(c===`,`||c===`
4
- `||c===`\r`)&&(i=``,a=``)}return t}function b(e,t){return`/* eslint-disable */
4
+ `||c===`\r`)&&(i=``,a=``)}return t}function y(e,t){return`/* eslint-disable */
5
5
  // prettier-ignore
6
6
  // biome-ignore format: auto-generated
7
7
  /**
@@ -34,7 +34,10 @@ ${Array.from(new Set([...e,...t])).map(e=>`\t\t\t${e}: process.env.${e},`).join(
34
34
  },
35
35
  } as any) as any;
36
36
  }
37
- `}function x(e,t){return`/* eslint-disable */
37
+
38
+ const arkenv = createEnv;
39
+ export default arkenv;
40
+ `}function b(e,t){return`/* eslint-disable */
38
41
  // prettier-ignore
39
42
  // biome-ignore format: auto-generated
40
43
  /**
@@ -66,7 +69,10 @@ ${Array.from(new Set([...e,...t])).map(e=>`\t\t\t${e}: process.env.${e},`).join(
66
69
  },
67
70
  } as any);
68
71
  }
69
- `}function S(e){let t=w(e);return t?y(t):[]}function C(e){let t=T(e);return t?y(t):[]}function w(e){let t=/\barkenv\s*\(\s*(?:[a-zA-Z0-9_$.]+\s*\(\s*)*\{/g;if(!t.exec(e))return null;let n=t.lastIndex,r=1,i=n,a=null,o=null;for(;i<e.length&&r>0;){let t=e[i],n=e[i+1];if(o===`single`){(t===`
70
- `||t===`\r`)&&(o=null),i++;continue}if(o===`multi`){if(t===`*`&&n===`/`){o=null,i+=2;continue}i++;continue}if(a){t===a&&e[i-1]!==`\\`&&(a=null),i++;continue}if(t===`/`&&n===`/`){o=`single`,i+=2;continue}if(t===`/`&&n===`*`){o=`multi`,i+=2;continue}if(t===`'`||t===`"`||t==="`"){a=t,i++;continue}t===`{`?r++:t===`}`&&r--,i++}return r===0?e.slice(n,i-1):null}function T(e){let t=/\bSharedSchema\s*=\s*(?:[a-zA-Z0-9_$.]+\s*\(\s*)*\{/g;if(!t.exec(e))return null;let n=t.lastIndex,r=1,i=n,a=null,o=null;for(;i<e.length&&r>0;){let t=e[i],n=e[i+1];if(o===`single`){(t===`
71
- `||t===`\r`)&&(o=null),i++;continue}if(o===`multi`){if(t===`*`&&n===`/`){o=null,i+=2;continue}i++;continue}if(a){t===a&&e[i-1]!==`\\`&&(a=null),i++;continue}if(t===`/`&&n===`/`){o=`single`,i+=2;continue}if(t===`/`&&n===`*`){o=`multi`,i+=2;continue}if(t===`'`||t===`"`||t==="`"){a=t,i++;continue}t===`{`?r++:t===`}`&&r--,i++}return r===0?e.slice(n,i-1):null}exports.extractClientKeys=S,exports.extractKeys=_,exports.extractSharedKeys=C,exports.runCodegen=g,exports.t=s,exports.withArkEnv=f;
72
+
73
+ const arkenv = createEnv;
74
+ export default arkenv;
75
+ `}function x(e){let t=C(e);return t?v(t):[]}function S(e){let t=w(e);return t?v(t):[]}function C(e){let t=/\barkenv\s*\(\s*(?:[a-zA-Z0-9_$.]+\s*\(\s*)*\{/g;if(!t.exec(e))return null;let n=t.lastIndex,r=1,i=n,a=null,o=null;for(;i<e.length&&r>0;){let t=e[i],n=e[i+1];if(o===`single`){(t===`
76
+ `||t===`\r`)&&(o=null),i++;continue}if(o===`multi`){if(t===`*`&&n===`/`){o=null,i+=2;continue}i++;continue}if(a){t===a&&e[i-1]!==`\\`&&(a=null),i++;continue}if(t===`/`&&n===`/`){o=`single`,i+=2;continue}if(t===`/`&&n===`*`){o=`multi`,i+=2;continue}if(t===`'`||t===`"`||t==="`"){a=t,i++;continue}t===`{`?r++:t===`}`&&r--,i++}return r===0?e.slice(n,i-1):null}function w(e){let t=/\bSharedSchema\s*=\s*(?:[a-zA-Z0-9_$.]+\s*\(\s*)*\{/g;if(!t.exec(e))return null;let n=t.lastIndex,r=1,i=n,a=null,o=null;for(;i<e.length&&r>0;){let t=e[i],n=e[i+1];if(o===`single`){(t===`
77
+ `||t===`\r`)&&(o=null),i++;continue}if(o===`multi`){if(t===`*`&&n===`/`){o=null,i+=2;continue}i++;continue}if(a){t===a&&e[i-1]!==`\\`&&(a=null),i++;continue}if(t===`/`&&n===`/`){o=`single`,i+=2;continue}if(t===`/`&&n===`*`){o=`multi`,i+=2;continue}if(t===`'`||t===`"`||t==="`"){a=t,i++;continue}t===`{`?r++:t===`}`&&r--,i++}return r===0?e.slice(n,i-1):null}exports.extractClientKeys=x,exports.extractKeys=g,exports.extractSharedKeys=S,exports.runCodegen=h,exports.t=s,exports.withArkEnv=d;
72
78
  //# sourceMappingURL=config.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"config.cjs","names":["path","fs"],"sources":["../src/config.ts"],"sourcesContent":["import fs from \"node:fs\";\nimport path from \"node:path\";\nimport { watch as chokidarWatch } from \"chokidar\";\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 * - `\"simple\"` (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 \"simple\"\n\t */\n\tlayout?: \"simple\" | \"strict\";\n};\n\nlet watcherInitialized = false;\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\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 withArkEnv options.`,\n\t\t);\n\t}\n\n\tconst { layout: resolvedLayout, baseDir } = resolveLayout(\n\t\tschemaPath,\n\t\toptions?.layout,\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\n\ttry {\n\t\trunCodegen(schemaPath, outputPath, resolvedLayout);\n\t} catch (error: unknown) {\n\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\tthrow new Error(`[ArkEnv] Failed to generate env.gen.ts: ${message}`);\n\t}\n\n\t// 4. Initialize development file watcher if in dev mode\n\tconst isDev =\n\t\tprocess.env.NODE_ENV === \"development\" ||\n\t\tprocess.env.NEXT_PHASE === \"phase-development-server\";\n\tif (isDev) {\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, outputPath, resolvedLayout);\n\t}\n\n\treturn nextConfig;\n}\n\n/**\n * Find the path to the schema file in the project.\n *\n * @returns The absolute path to the schema file, or null if not found\n */\n/**\n * Resolve the layout (simple vs strict) and the base directory from a schema path.\n *\n * Auto-detects layout when `layoutOption` is not provided. When `layoutOption`\n * is `\"strict\"`, validates that the required split files exist and throws a\n * descriptive error if either is missing.\n *\n * @param schemaPath The absolute path to the schema file or directory\n * @param layoutOption The explicit layout option, if provided\n * @returns The resolved layout and base directory\n * @throws An error if strict layout files are missing\n */\nfunction resolveLayout(\n\tschemaPath: string,\n\tlayoutOption?: \"simple\" | \"strict\",\n): { layout: \"simple\" | \"strict\"; baseDir: string } {\n\tconst checkStrict = (dir: string) =>\n\t\tfs.existsSync(path.join(dir, \"internal\", \"shared.ts\")) &&\n\t\tfs.existsSync(path.join(dir, \"client.ts\")) &&\n\t\tfs.existsSync(path.join(dir, \"server.ts\"));\n\n\tconst resolveBaseDir = (p: string): string => {\n\t\t// Normalize: if schemaPath has an extension, try the extensionless form as a dir\n\t\tconst ext = path.extname(p);\n\t\tconst baseWithoutExt = ext ? p.slice(0, -ext.length) : p;\n\t\tif (\n\t\t\tfs.existsSync(baseWithoutExt) &&\n\t\t\tfs.statSync(baseWithoutExt).isDirectory()\n\t\t) {\n\t\t\treturn baseWithoutExt;\n\t\t}\n\t\treturn p;\n\t};\n\n\tif (!layoutOption) {\n\t\t// Auto-detect\n\t\tconst resolved = resolveBaseDir(schemaPath);\n\t\tif (fs.existsSync(resolved) && fs.statSync(resolved).isDirectory()) {\n\t\t\tif (checkStrict(resolved)) {\n\t\t\t\treturn { layout: \"strict\", baseDir: resolved };\n\t\t\t}\n\t\t\treturn { layout: \"simple\", baseDir: resolved };\n\t\t}\n\n\t\t// schemaPath is a file — check surrounding dirs\n\t\tconst parent = path.dirname(schemaPath);\n\t\tconst ext = path.extname(schemaPath);\n\t\tconst baseWithoutExt = ext ? schemaPath.slice(0, -ext.length) : schemaPath;\n\t\tif (\n\t\t\tfs.existsSync(baseWithoutExt) &&\n\t\t\tfs.statSync(baseWithoutExt).isDirectory() &&\n\t\t\tcheckStrict(baseWithoutExt)\n\t\t) {\n\t\t\treturn { layout: \"strict\", baseDir: baseWithoutExt };\n\t\t}\n\t\tif (checkStrict(parent)) {\n\t\t\treturn { layout: \"strict\", baseDir: parent };\n\t\t}\n\t\tif (\n\t\t\tpath.basename(parent) === \"internal\" &&\n\t\t\tcheckStrict(path.dirname(parent))\n\t\t) {\n\t\t\treturn { layout: \"strict\", baseDir: path.dirname(parent) };\n\t\t}\n\t\treturn { layout: \"simple\", baseDir: schemaPath };\n\t}\n\n\tif (layoutOption === \"strict\") {\n\t\t// Resolve baseDir for an explicit strict layout\n\t\tlet baseDir: string;\n\t\tconst resolved = resolveBaseDir(schemaPath);\n\t\tif (fs.existsSync(resolved) && fs.statSync(resolved).isDirectory()) {\n\t\t\tbaseDir = resolved;\n\t\t} else {\n\t\t\tconst parent = path.dirname(schemaPath);\n\t\t\tif (path.basename(parent) === \"internal\") {\n\t\t\t\tbaseDir = path.dirname(parent);\n\t\t\t} else {\n\t\t\t\tbaseDir = parent;\n\t\t\t}\n\t\t}\n\n\t\t// Validate that required split files exist\n\t\tconst clientPath = path.join(baseDir, \"client.ts\");\n\t\tconst sharedPath = path.join(baseDir, \"internal\", \"shared.ts\");\n\t\tif (!fs.existsSync(clientPath) || !fs.existsSync(sharedPath)) {\n\t\t\tthrow new Error(\n\t\t\t\t`[ArkEnv] Strict layout requires \"${clientPath}\" and \"${sharedPath}\" to exist. ` +\n\t\t\t\t\t`Ensure both files are present or remove the 'layout: \"strict\"' option to let ArkEnv auto-detect.`,\n\t\t\t);\n\t\t}\n\n\t\treturn { layout: \"strict\", baseDir };\n\t}\n\n\t// layoutOption === \"simple\"\n\treturn { layout: \"simple\", baseDir: schemaPath };\n}\n\nfunction findSchemaPath(): string | null {\n\tconst possiblePaths = [\n\t\tpath.join(process.cwd(), \"src\", \"env.ts\"),\n\t\tpath.join(process.cwd(), \"env.ts\"),\n\t];\n\tfor (const p of possiblePaths) {\n\t\tif (fs.existsSync(p)) return p;\n\t}\n\n\tconst possibleDirs = [\n\t\tpath.join(process.cwd(), \"src\", \"env\"),\n\t\tpath.join(process.cwd(), \"env\"),\n\t];\n\tfor (const d of possibleDirs) {\n\t\tif (\n\t\t\tfs.existsSync(d) &&\n\t\t\tfs.existsSync(path.join(d, \"internal\", \"shared.ts\")) &&\n\t\t\tfs.existsSync(path.join(d, \"client.ts\")) &&\n\t\t\tfs.existsSync(path.join(d, \"server.ts\"))\n\t\t) {\n\t\t\treturn d;\n\t\t}\n\t}\n\treturn null;\n}\n\n/**\n * Watch the schema file for changes and trigger codegen.\n *\n * @param schemaPath The absolute path to the schema file, or an array of paths to watch\n * @param outputPath The absolute path to the generated output file\n * @param layout The resolved layout to pass through to codegen on each change\n */\nfunction watchSchema(\n\tschemaPath: string | string[],\n\toutputPath: string,\n\tlayout?: \"simple\" | \"strict\",\n) {\n\tif (watcherInitialized) return;\n\twatcherInitialized = true;\n\n\ttry {\n\t\tchokidarWatch(schemaPath, { ignoreInitial: true }).on(\"change\", () => {\n\t\t\ttry {\n\t\t\t\tconst mainSchemaPath = Array.isArray(schemaPath)\n\t\t\t\t\t? schemaPath[0]\n\t\t\t\t\t: schemaPath;\n\t\t\t\trunCodegen(mainSchemaPath, outputPath, layout);\n\t\t\t} catch (err: unknown) {\n\t\t\t\tconst message = err instanceof Error ? err.message : String(err);\n\t\t\t\t// biome-ignore lint/suspicious/noConsole: watcher errors must be logged\n\t\t\t\tconsole.error(\n\t\t\t\t\t`[ArkEnv Watcher] Failed to regenerate env.gen.ts: ${message}`,\n\t\t\t\t);\n\t\t\t}\n\t\t});\n\t} catch (err: unknown) {\n\t\tconst message = err instanceof Error ? err.message : String(err);\n\t\t// biome-ignore lint/suspicious/noConsole: watcher errors must be logged\n\t\tconsole.error(\n\t\t\t`[ArkEnv Watcher] Failed to start watch on ${schemaPath}: ${message}`,\n\t\t);\n\t}\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 * @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?: \"simple\" | \"strict\",\n) {\n\tconst { layout: resolvedLayout, baseDir } = resolveLayout(\n\t\tschemaPath,\n\t\tlayoutOption,\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 clientKeys = extractClientKeys(clientContent);\n\t\tconst sharedKeys = extractSharedKeys(sharedContent);\n\n\t\tgeneratedCode = generateClientFactoryCode(clientKeys, sharedKeys);\n\t} else {\n\t\tconst fileContent = fs.readFileSync(schemaPath, \"utf-8\");\n\t\tconst { clientKeys, sharedKeys } = extractKeys(fileContent);\n\t\tgeneratedCode = generateFactoryCode(clientKeys, sharedKeys);\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\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} {\n\tconst clientKeys: string[] = [];\n\tconst sharedKeys: string[] = [];\n\n\t// Extract client block\n\tconst clientBlock = extractBlock(content, \"client\");\n\tif (clientBlock) {\n\t\tclientKeys.push(...parseBlockKeys(clientBlock));\n\t}\n\n\t// Extract shared block\n\tconst sharedBlock = extractBlock(content, \"shared\");\n\tif (sharedBlock) {\n\t\tsharedKeys.push(...parseBlockKeys(sharedBlock));\n\t}\n\n\treturn { clientKeys, sharedKeys };\n}\n\n/**\n * Extract a specific block from the schema content by name.\n *\n * @param content The schema file string content\n * @param blockName The name of the block to extract (e.g., 'client' or 'shared')\n * @returns The contents of the block, or null if not found\n */\nfunction extractBlock(content: string, blockName: string): string | null {\n\t// Find \"\\bblockName\\s*:\\s*{\" or \"\\bblockName\\s*:\\s*type({\"\n\tconst regex = new RegExp(\n\t\t`\\\\b${blockName}\\\\s*:\\\\s*(?:[a-zA-Z0-9_$.]+\\\\s*\\\\(\\\\s*)?\\\\{`,\n\t\t\"g\",\n\t);\n\tconst match = regex.exec(content);\n\tif (!match) return null;\n\n\tconst startIndex = regex.lastIndex;\n\tlet braceCount = 1;\n\tlet index = startIndex;\n\tlet inString: string | null = null;\n\tlet inComment: \"single\" | \"multi\" | null = null;\n\n\twhile (index < content.length && braceCount > 0) {\n\t\tconst char = content[index];\n\t\tconst nextChar = content[index + 1];\n\n\t\tif (inComment === \"single\") {\n\t\t\tif (char === \"\\n\" || char === \"\\r\") inComment = null;\n\t\t\tindex++;\n\t\t\tcontinue;\n\t\t}\n\t\tif (inComment === \"multi\") {\n\t\t\tif (char === \"*\" && nextChar === \"/\") {\n\t\t\t\tinComment = null;\n\t\t\t\tindex += 2;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tindex++;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (inString) {\n\t\t\tif (char === inString && content[index - 1] !== \"\\\\\") {\n\t\t\t\tinString = null;\n\t\t\t}\n\t\t\tindex++;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (char === \"/\" && nextChar === \"/\") {\n\t\t\tinComment = \"single\";\n\t\t\tindex += 2;\n\t\t\tcontinue;\n\t\t}\n\t\tif (char === \"/\" && nextChar === \"*\") {\n\t\t\tinComment = \"multi\";\n\t\t\tindex += 2;\n\t\t\tcontinue;\n\t\t}\n\t\tif (char === \"'\" || char === '\"' || char === \"`\") {\n\t\t\tinString = char;\n\t\t\tindex++;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (char === \"{\") {\n\t\t\tbraceCount++;\n\t\t} else if (char === \"}\") {\n\t\t\tbraceCount--;\n\t\t}\n\t\tindex++;\n\t}\n\n\tif (braceCount === 0) {\n\t\treturn content.slice(startIndex, index - 1);\n\t}\n\n\treturn null;\n}\n\n/**\n * Parse environment variable keys from a block's content.\n *\n * @param blockContent The raw content of the block\n * @returns An array of parsed environment variable keys\n */\nfunction parseBlockKeys(blockContent: string): string[] {\n\tconst keys: string[] = [];\n\tlet inString: string | null = null;\n\tlet inComment: \"single\" | \"multi\" | null = null;\n\tlet currentToken = \"\";\n\tlet lastStringContent = \"\";\n\tlet braceDepth = 0;\n\n\tfor (let i = 0; i < blockContent.length; i++) {\n\t\tconst char = blockContent[i];\n\t\tconst nextChar = blockContent[i + 1];\n\n\t\tif (inComment === \"single\") {\n\t\t\tif (char === \"\\n\" || char === \"\\r\") inComment = null;\n\t\t\tcontinue;\n\t\t}\n\t\tif (inComment === \"multi\") {\n\t\t\tif (char === \"*\" && nextChar === \"/\") {\n\t\t\t\tinComment = null;\n\t\t\t\ti++;\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (inString) {\n\t\t\tif (char === inString && blockContent[i - 1] !== \"\\\\\") {\n\t\t\t\tinString = null;\n\t\t\t\tlastStringContent = currentToken;\n\t\t\t\tcurrentToken = \"\";\n\t\t\t} else {\n\t\t\t\tcurrentToken += char;\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Start comments/strings\n\t\tif (char === \"/\" && nextChar === \"/\") {\n\t\t\tinComment = \"single\";\n\t\t\ti++;\n\t\t\tcontinue;\n\t\t}\n\t\tif (char === \"/\" && nextChar === \"*\") {\n\t\t\tinComment = \"multi\";\n\t\t\ti++;\n\t\t\tcontinue;\n\t\t}\n\t\tif (char === \"'\" || char === '\"' || char === \"`\") {\n\t\t\tinString = char;\n\t\t\tcurrentToken = \"\";\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (char === \"{\") {\n\t\t\tbraceDepth++;\n\t\t\tcurrentToken = \"\";\n\t\t\tlastStringContent = \"\";\n\t\t\tcontinue;\n\t\t}\n\t\tif (char === \"}\") {\n\t\t\tbraceDepth--;\n\t\t\tcurrentToken = \"\";\n\t\t\tlastStringContent = \"\";\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (char === \":\") {\n\t\t\tif (braceDepth === 0) {\n\t\t\t\tconst key = currentToken.trim() || lastStringContent.trim();\n\t\t\t\tif (key) {\n\t\t\t\t\tkeys.push(key);\n\t\t\t\t}\n\t\t\t}\n\t\t\tcurrentToken = \"\";\n\t\t\tlastStringContent = \"\";\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (/[a-zA-Z0-9_$]/.test(char)) {\n\t\t\tcurrentToken += char;\n\t\t} else if (char === \",\" || char === \"\\n\" || char === \"\\r\") {\n\t\t\tcurrentToken = \"\";\n\t\t\tlastStringContent = \"\";\n\t\t}\n\t}\n\n\treturn keys;\n}\n\n/**\n * Generate the TypeScript factory code for the tailored createEnv helper.\n *\n * @param clientKeys The client environment variable keys\n * @param sharedKeys The shared environment variable keys\n * @returns The generated TypeScript source code string\n */\nfunction generateFactoryCode(\n\tclientKeys: string[],\n\tsharedKeys: string[],\n): string {\n\tconst allKeys = Array.from(new Set([...clientKeys, ...sharedKeys]));\n\tconst runtimeEnvLines = allKeys\n\t\t.map((key) => `\\t\\t\\t${key}: process.env.${key},`)\n\t\t.join(\"\\n\");\n\n\treturn `/* eslint-disable */\n// prettier-ignore\n// biome-ignore format: auto-generated\n/**\n * @file env.gen.ts\n * @note This file is auto-generated by ArkEnv. DO NOT EDIT DIRECTLY.\n * @see https://arkenv.js.org\n */\n\nimport { createEnv as coreCreateEnv } from \"@arkenv/nextjs\";\nimport type { Infer } from \"@arkenv/nextjs\";\n\nexport { type } from \"@arkenv/nextjs\";\n\nexport function createEnv<\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}): Readonly<Infer<TServer & TClient & TShared>> {\n\treturn coreCreateEnv({\n\t\t...options,\n\t\truntimeEnv: {\n${runtimeEnvLines}\n\t\t},\n\t} as any) as any;\n}\n`;\n}\n\n/**\n * Generate the TypeScript factory code for the strict-layout `createEnv` 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 * @returns The generated TypeScript source code string\n */\nfunction generateClientFactoryCode(\n\tclientKeys: string[],\n\tsharedKeys: string[],\n): string {\n\tconst allKeys = Array.from(new Set([...clientKeys, ...sharedKeys]));\n\tconst runtimeEnvLines = allKeys\n\t\t.map((key) => `\\t\\t\\t${key}: process.env.${key},`)\n\t\t.join(\"\\n\");\n\n\treturn `/* eslint-disable */\n// prettier-ignore\n// biome-ignore format: auto-generated\n/**\n * @file env.gen.ts\n * @note This file is auto-generated by ArkEnv. DO NOT EDIT DIRECTLY.\n * @see https://arkenv.js.org\n */\n\nimport { createEnv as coreCreateEnv } from \"@arkenv/nextjs/client\";\n\nexport { type } from \"@arkenv/nextjs/client\";\n\nexport function createEnv<\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) {\n\treturn coreCreateEnv<TSchema, TExtends>(schema as any, {\n\t\t...options,\n\t\truntimeEnv: {\n${runtimeEnvLines}\n\t\t},\n\t} as any);\n}\n`;\n}\n\n/**\n * Extract env var keys from a strict-layout `client.ts` file.\n *\n * Locates the first `arkenv({...})` call and delegates to `parseBlockKeys`\n * to enumerate the keys defined in the schema object.\n *\n * @param content The source text of `client.ts`\n * @returns An array of env var key names found in the client schema\n */\nexport function extractClientKeys(content: string): string[] {\n\tconst block = extractClientBlock(content);\n\treturn block ? parseBlockKeys(block) : [];\n}\n\n/**\n * Extract env var keys from a strict-layout `internal/shared.ts` file.\n *\n * Locates the `SharedSchema = ...({...})` assignment and delegates to\n * `parseBlockKeys` to enumerate the keys defined in the schema object.\n *\n * @param content The source text of `internal/shared.ts`\n * @returns An array of env var key names found in the shared schema\n */\nexport function extractSharedKeys(content: string): string[] {\n\tconst block = extractSharedBlock(content);\n\treturn block ? parseBlockKeys(block) : [];\n}\n\n/**\n * Extract the schema object body from a strict-layout `client.ts` file.\n *\n * Matches the first `arkenv(...)` call, then performs brace-balanced\n * traversal while respecting strings and comments to find the boundaries\n * of the first argument object.\n *\n * @param content The source text of `client.ts`\n * @returns The raw text inside the first `{...}` argument, or `null` if not found\n */\nfunction extractClientBlock(content: string): string | null {\n\tconst regex = /\\barkenv\\s*\\(\\s*(?:[a-zA-Z0-9_$.]+\\s*\\(\\s*)*\\{/g;\n\tconst match = regex.exec(content);\n\tif (!match) return null;\n\n\tconst startIndex = regex.lastIndex;\n\tlet braceCount = 1;\n\tlet index = startIndex;\n\tlet inString: string | null = null;\n\tlet inComment: \"single\" | \"multi\" | null = null;\n\n\twhile (index < content.length && braceCount > 0) {\n\t\tconst char = content[index];\n\t\tconst nextChar = content[index + 1];\n\n\t\tif (inComment === \"single\") {\n\t\t\tif (char === \"\\n\" || char === \"\\r\") inComment = null;\n\t\t\tindex++;\n\t\t\tcontinue;\n\t\t}\n\t\tif (inComment === \"multi\") {\n\t\t\tif (char === \"*\" && nextChar === \"/\") {\n\t\t\t\tinComment = null;\n\t\t\t\tindex += 2;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tindex++;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (inString) {\n\t\t\tif (char === inString && content[index - 1] !== \"\\\\\") {\n\t\t\t\tinString = null;\n\t\t\t}\n\t\t\tindex++;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (char === \"/\" && nextChar === \"/\") {\n\t\t\tinComment = \"single\";\n\t\t\tindex += 2;\n\t\t\tcontinue;\n\t\t}\n\t\tif (char === \"/\" && nextChar === \"*\") {\n\t\t\tinComment = \"multi\";\n\t\t\tindex += 2;\n\t\t\tcontinue;\n\t\t}\n\t\tif (char === \"'\" || char === '\"' || char === \"`\") {\n\t\t\tinString = char;\n\t\t\tindex++;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (char === \"{\") {\n\t\t\tbraceCount++;\n\t\t} else if (char === \"}\") {\n\t\t\tbraceCount--;\n\t\t}\n\t\tindex++;\n\t}\n\n\tif (braceCount === 0) {\n\t\treturn content.slice(startIndex, index - 1);\n\t}\n\n\treturn null;\n}\n\n/**\n * Extract the schema object body from a strict-layout `internal/shared.ts` file.\n *\n * Matches the `SharedSchema = ...({...})` assignment, then performs\n * brace-balanced traversal while respecting strings and comments to find\n * the boundaries of the schema object.\n *\n * @param content The source text of `internal/shared.ts`\n * @returns The raw text inside the `{...}` schema object, or `null` if not found\n */\nfunction extractSharedBlock(content: string): string | null {\n\tconst regex = /\\bSharedSchema\\s*=\\s*(?:[a-zA-Z0-9_$.]+\\s*\\(\\s*)*\\{/g;\n\tconst match = regex.exec(content);\n\tif (!match) return null;\n\n\tconst startIndex = regex.lastIndex;\n\tlet braceCount = 1;\n\tlet index = startIndex;\n\tlet inString: string | null = null;\n\tlet inComment: \"single\" | \"multi\" | null = null;\n\n\twhile (index < content.length && braceCount > 0) {\n\t\tconst char = content[index];\n\t\tconst nextChar = content[index + 1];\n\n\t\tif (inComment === \"single\") {\n\t\t\tif (char === \"\\n\" || char === \"\\r\") inComment = null;\n\t\t\tindex++;\n\t\t\tcontinue;\n\t\t}\n\t\tif (inComment === \"multi\") {\n\t\t\tif (char === \"*\" && nextChar === \"/\") {\n\t\t\t\tinComment = null;\n\t\t\t\tindex += 2;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tindex++;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (inString) {\n\t\t\tif (char === inString && content[index - 1] !== \"\\\\\") {\n\t\t\t\tinString = null;\n\t\t\t}\n\t\t\tindex++;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (char === \"/\" && nextChar === \"/\") {\n\t\t\tinComment = \"single\";\n\t\t\tindex += 2;\n\t\t\tcontinue;\n\t\t}\n\t\tif (char === \"/\" && nextChar === \"*\") {\n\t\t\tinComment = \"multi\";\n\t\t\tindex += 2;\n\t\t\tcontinue;\n\t\t}\n\t\tif (char === \"'\" || char === '\"' || char === \"`\") {\n\t\t\tinString = char;\n\t\t\tindex++;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (char === \"{\") {\n\t\t\tbraceCount++;\n\t\t} else if (char === \"}\") {\n\t\t\tbraceCount--;\n\t\t}\n\t\tindex++;\n\t}\n\n\tif (braceCount === 0) {\n\t\treturn content.slice(startIndex, index - 1);\n\t}\n\n\treturn null;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"config.cjs","names":["path","fs"],"sources":["../src/config.ts"],"sourcesContent":["import fs from \"node:fs\";\nimport path from \"node:path\";\nimport { watch as chokidarWatch } from \"chokidar\";\n\ndeclare global {\n\t// eslint-disable-next-line no-var\n\tvar __arkenv_watcher__: import(\"chokidar\").FSWatcher | undefined;\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 * - `\"simple\"` (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 \"simple\"\n\t */\n\tlayout?: \"simple\" | \"strict\";\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\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 withArkEnv options.`,\n\t\t);\n\t}\n\n\tconst { layout: resolvedLayout, baseDir } = resolveLayout(\n\t\tschemaPath,\n\t\toptions?.layout,\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\n\ttry {\n\t\trunCodegen(schemaPath, outputPath, resolvedLayout);\n\t} catch (error: unknown) {\n\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\tthrow new Error(`[ArkEnv] Failed to generate env.gen.ts: ${message}`);\n\t}\n\n\t// 4. Initialize development file watcher if in dev mode\n\tconst isDev =\n\t\tprocess.env.NODE_ENV === \"development\" ||\n\t\tprocess.env.NEXT_PHASE === \"phase-development-server\";\n\tif (isDev) {\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, outputPath, resolvedLayout);\n\t}\n\n\treturn nextConfig;\n}\n\n/**\n * Find the path to the schema file in the project.\n *\n * @returns The absolute path to the schema file, or null if not found\n */\n/**\n * Resolve the layout (simple vs strict) and the base directory from a schema path.\n *\n * Auto-detects layout when `layoutOption` is not provided. When `layoutOption`\n * is `\"strict\"`, validates that the required split files exist and throws a\n * descriptive error if either is missing.\n *\n * @param schemaPath The absolute path to the schema file or directory\n * @param layoutOption The explicit layout option, if provided\n * @returns The resolved layout and base directory\n * @throws An error if strict layout files are missing\n */\nfunction resolveLayout(\n\tschemaPath: string,\n\tlayoutOption?: \"simple\" | \"strict\",\n): { layout: \"simple\" | \"strict\"; baseDir: string } {\n\tconst checkStrict = (dir: string) =>\n\t\tfs.existsSync(path.join(dir, \"internal\", \"shared.ts\")) &&\n\t\tfs.existsSync(path.join(dir, \"client.ts\")) &&\n\t\tfs.existsSync(path.join(dir, \"server.ts\"));\n\n\tconst resolveBaseDir = (p: string): string => {\n\t\t// Normalize: if schemaPath has an extension, try the extensionless form as a dir\n\t\tconst ext = path.extname(p);\n\t\tconst baseWithoutExt = ext ? p.slice(0, -ext.length) : p;\n\t\tif (\n\t\t\tfs.existsSync(baseWithoutExt) &&\n\t\t\tfs.statSync(baseWithoutExt).isDirectory()\n\t\t) {\n\t\t\treturn baseWithoutExt;\n\t\t}\n\t\treturn p;\n\t};\n\n\tif (!layoutOption) {\n\t\t// Auto-detect\n\t\tconst resolved = resolveBaseDir(schemaPath);\n\t\tif (fs.existsSync(resolved) && fs.statSync(resolved).isDirectory()) {\n\t\t\tif (checkStrict(resolved)) {\n\t\t\t\treturn { layout: \"strict\", baseDir: resolved };\n\t\t\t}\n\t\t\treturn { layout: \"simple\", baseDir: resolved };\n\t\t}\n\n\t\t// schemaPath is a file — check surrounding dirs\n\t\tconst parent = path.dirname(schemaPath);\n\t\tconst ext = path.extname(schemaPath);\n\t\tconst baseWithoutExt = ext ? schemaPath.slice(0, -ext.length) : schemaPath;\n\t\tif (\n\t\t\tfs.existsSync(baseWithoutExt) &&\n\t\t\tfs.statSync(baseWithoutExt).isDirectory() &&\n\t\t\tcheckStrict(baseWithoutExt)\n\t\t) {\n\t\t\treturn { layout: \"strict\", baseDir: baseWithoutExt };\n\t\t}\n\t\tif (checkStrict(parent)) {\n\t\t\treturn { layout: \"strict\", baseDir: parent };\n\t\t}\n\t\tif (\n\t\t\tpath.basename(parent) === \"internal\" &&\n\t\t\tcheckStrict(path.dirname(parent))\n\t\t) {\n\t\t\treturn { layout: \"strict\", baseDir: path.dirname(parent) };\n\t\t}\n\t\treturn { layout: \"simple\", baseDir: schemaPath };\n\t}\n\n\tif (layoutOption === \"strict\") {\n\t\t// Resolve baseDir for an explicit strict layout\n\t\tlet baseDir: string;\n\t\tconst resolved = resolveBaseDir(schemaPath);\n\t\tif (fs.existsSync(resolved) && fs.statSync(resolved).isDirectory()) {\n\t\t\tbaseDir = resolved;\n\t\t} else {\n\t\t\tconst parent = path.dirname(schemaPath);\n\t\t\tif (path.basename(parent) === \"internal\") {\n\t\t\t\tbaseDir = path.dirname(parent);\n\t\t\t} else {\n\t\t\t\tbaseDir = parent;\n\t\t\t}\n\t\t}\n\n\t\t// Validate that required split files exist\n\t\tconst clientPath = path.join(baseDir, \"client.ts\");\n\t\tconst sharedPath = path.join(baseDir, \"internal\", \"shared.ts\");\n\t\tif (!fs.existsSync(clientPath) || !fs.existsSync(sharedPath)) {\n\t\t\tthrow new Error(\n\t\t\t\t`[ArkEnv] Strict layout requires \"${clientPath}\" and \"${sharedPath}\" to exist. ` +\n\t\t\t\t\t`Ensure both files are present or remove the 'layout: \"strict\"' option to let ArkEnv auto-detect.`,\n\t\t\t);\n\t\t}\n\n\t\treturn { layout: \"strict\", baseDir };\n\t}\n\n\t// layoutOption === \"simple\"\n\treturn { layout: \"simple\", baseDir: schemaPath };\n}\n\nfunction findSchemaPath(): string | null {\n\tconst possiblePaths = [\n\t\tpath.join(process.cwd(), \"src\", \"env.ts\"),\n\t\tpath.join(process.cwd(), \"env.ts\"),\n\t];\n\tfor (const p of possiblePaths) {\n\t\tif (fs.existsSync(p)) return p;\n\t}\n\n\tconst possibleDirs = [\n\t\tpath.join(process.cwd(), \"src\", \"env\"),\n\t\tpath.join(process.cwd(), \"env\"),\n\t];\n\tfor (const d of possibleDirs) {\n\t\tif (\n\t\t\tfs.existsSync(d) &&\n\t\t\tfs.existsSync(path.join(d, \"internal\", \"shared.ts\")) &&\n\t\t\tfs.existsSync(path.join(d, \"client.ts\")) &&\n\t\t\tfs.existsSync(path.join(d, \"server.ts\"))\n\t\t) {\n\t\t\treturn d;\n\t\t}\n\t}\n\treturn null;\n}\n\n/**\n * Watch the schema file for changes and trigger codegen.\n *\n * @param schemaPath The absolute path to the schema file, or an array of paths to watch\n * @param outputPath The absolute path to the generated output file\n * @param layout The resolved layout to pass through to codegen on each change\n */\nfunction watchSchema(\n\tschemaPath: string | string[],\n\toutputPath: string,\n\tlayout?: \"simple\" | \"strict\",\n) {\n\tconst previousWatcher = globalThis.__arkenv_watcher__;\n\tif (previousWatcher && typeof previousWatcher.close === \"function\") {\n\t\tpreviousWatcher.close().catch((err: unknown) => {\n\t\t\tconst message = err instanceof Error ? err.message : String(err);\n\t\t\t// biome-ignore lint/suspicious/noConsole: watcher errors must be logged\n\t\t\tconsole.error(\n\t\t\t\t`[ArkEnv Watcher] Failed to close previous watcher: ${message}`,\n\t\t\t);\n\t\t});\n\t}\n\n\ttry {\n\t\tconst watcher = chokidarWatch(schemaPath, { ignoreInitial: true });\n\t\tglobalThis.__arkenv_watcher__ = watcher;\n\n\t\twatcher.on(\"change\", () => {\n\t\t\ttry {\n\t\t\t\tconst mainSchemaPath = Array.isArray(schemaPath)\n\t\t\t\t\t? schemaPath[0]\n\t\t\t\t\t: schemaPath;\n\t\t\t\trunCodegen(mainSchemaPath, outputPath, layout);\n\t\t\t} catch (err: unknown) {\n\t\t\t\tconst message = err instanceof Error ? err.message : String(err);\n\t\t\t\t// biome-ignore lint/suspicious/noConsole: watcher errors must be logged\n\t\t\t\tconsole.error(\n\t\t\t\t\t`[ArkEnv Watcher] Failed to regenerate env.gen.ts: ${message}`,\n\t\t\t\t);\n\t\t\t}\n\t\t});\n\t} catch (err: unknown) {\n\t\tconst message = err instanceof Error ? err.message : String(err);\n\t\t// biome-ignore lint/suspicious/noConsole: watcher errors must be logged\n\t\tconsole.error(\n\t\t\t`[ArkEnv Watcher] Failed to start watch on ${schemaPath}: ${message}`,\n\t\t);\n\t}\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 * @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?: \"simple\" | \"strict\",\n) {\n\tconst { layout: resolvedLayout, baseDir } = resolveLayout(\n\t\tschemaPath,\n\t\tlayoutOption,\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 clientKeys = extractClientKeys(clientContent);\n\t\tconst sharedKeys = extractSharedKeys(sharedContent);\n\n\t\tgeneratedCode = generateClientFactoryCode(clientKeys, sharedKeys);\n\t} else {\n\t\tconst fileContent = fs.readFileSync(schemaPath, \"utf-8\");\n\t\tconst { clientKeys, sharedKeys } = extractKeys(fileContent);\n\t\tgeneratedCode = generateFactoryCode(clientKeys, sharedKeys);\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\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} {\n\tconst clientKeys: string[] = [];\n\tconst sharedKeys: string[] = [];\n\n\t// Extract client block\n\tconst clientBlock = extractBlock(content, \"client\");\n\tif (clientBlock) {\n\t\tclientKeys.push(...parseBlockKeys(clientBlock));\n\t}\n\n\t// Extract shared block\n\tconst sharedBlock = extractBlock(content, \"shared\");\n\tif (sharedBlock) {\n\t\tsharedKeys.push(...parseBlockKeys(sharedBlock));\n\t}\n\n\treturn { clientKeys, sharedKeys };\n}\n\n/**\n * Extract a specific block from the schema content by name.\n *\n * @param content The schema file string content\n * @param blockName The name of the block to extract (e.g., 'client' or 'shared')\n * @returns The contents of the block, or null if not found\n */\nfunction extractBlock(content: string, blockName: string): string | null {\n\t// Find \"\\bblockName\\s*:\\s*{\" or \"\\bblockName\\s*:\\s*type({\"\n\tconst regex = new RegExp(\n\t\t`\\\\b${blockName}\\\\s*:\\\\s*(?:[a-zA-Z0-9_$.]+\\\\s*\\\\(\\\\s*)?\\\\{`,\n\t\t\"g\",\n\t);\n\tconst match = regex.exec(content);\n\tif (!match) return null;\n\n\tconst startIndex = regex.lastIndex;\n\tlet braceCount = 1;\n\tlet index = startIndex;\n\tlet inString: string | null = null;\n\tlet inComment: \"single\" | \"multi\" | null = null;\n\n\twhile (index < content.length && braceCount > 0) {\n\t\tconst char = content[index];\n\t\tconst nextChar = content[index + 1];\n\n\t\tif (inComment === \"single\") {\n\t\t\tif (char === \"\\n\" || char === \"\\r\") inComment = null;\n\t\t\tindex++;\n\t\t\tcontinue;\n\t\t}\n\t\tif (inComment === \"multi\") {\n\t\t\tif (char === \"*\" && nextChar === \"/\") {\n\t\t\t\tinComment = null;\n\t\t\t\tindex += 2;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tindex++;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (inString) {\n\t\t\tif (char === inString && content[index - 1] !== \"\\\\\") {\n\t\t\t\tinString = null;\n\t\t\t}\n\t\t\tindex++;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (char === \"/\" && nextChar === \"/\") {\n\t\t\tinComment = \"single\";\n\t\t\tindex += 2;\n\t\t\tcontinue;\n\t\t}\n\t\tif (char === \"/\" && nextChar === \"*\") {\n\t\t\tinComment = \"multi\";\n\t\t\tindex += 2;\n\t\t\tcontinue;\n\t\t}\n\t\tif (char === \"'\" || char === '\"' || char === \"`\") {\n\t\t\tinString = char;\n\t\t\tindex++;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (char === \"{\") {\n\t\t\tbraceCount++;\n\t\t} else if (char === \"}\") {\n\t\t\tbraceCount--;\n\t\t}\n\t\tindex++;\n\t}\n\n\tif (braceCount === 0) {\n\t\treturn content.slice(startIndex, index - 1);\n\t}\n\n\treturn null;\n}\n\n/**\n * Parse environment variable keys from a block's content.\n *\n * @param blockContent The raw content of the block\n * @returns An array of parsed environment variable keys\n */\nfunction parseBlockKeys(blockContent: string): string[] {\n\tconst keys: string[] = [];\n\tlet inString: string | null = null;\n\tlet inComment: \"single\" | \"multi\" | null = null;\n\tlet currentToken = \"\";\n\tlet lastStringContent = \"\";\n\tlet braceDepth = 0;\n\n\tfor (let i = 0; i < blockContent.length; i++) {\n\t\tconst char = blockContent[i];\n\t\tconst nextChar = blockContent[i + 1];\n\n\t\tif (inComment === \"single\") {\n\t\t\tif (char === \"\\n\" || char === \"\\r\") inComment = null;\n\t\t\tcontinue;\n\t\t}\n\t\tif (inComment === \"multi\") {\n\t\t\tif (char === \"*\" && nextChar === \"/\") {\n\t\t\t\tinComment = null;\n\t\t\t\ti++;\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (inString) {\n\t\t\tif (char === inString && blockContent[i - 1] !== \"\\\\\") {\n\t\t\t\tinString = null;\n\t\t\t\tlastStringContent = currentToken;\n\t\t\t\tcurrentToken = \"\";\n\t\t\t} else {\n\t\t\t\tcurrentToken += char;\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Start comments/strings\n\t\tif (char === \"/\" && nextChar === \"/\") {\n\t\t\tinComment = \"single\";\n\t\t\ti++;\n\t\t\tcontinue;\n\t\t}\n\t\tif (char === \"/\" && nextChar === \"*\") {\n\t\t\tinComment = \"multi\";\n\t\t\ti++;\n\t\t\tcontinue;\n\t\t}\n\t\tif (char === \"'\" || char === '\"' || char === \"`\") {\n\t\t\tinString = char;\n\t\t\tcurrentToken = \"\";\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (char === \"{\") {\n\t\t\tbraceDepth++;\n\t\t\tcurrentToken = \"\";\n\t\t\tlastStringContent = \"\";\n\t\t\tcontinue;\n\t\t}\n\t\tif (char === \"}\") {\n\t\t\tbraceDepth--;\n\t\t\tcurrentToken = \"\";\n\t\t\tlastStringContent = \"\";\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (char === \":\") {\n\t\t\tif (braceDepth === 0) {\n\t\t\t\tconst key = currentToken.trim() || lastStringContent.trim();\n\t\t\t\tif (key) {\n\t\t\t\t\tkeys.push(key);\n\t\t\t\t}\n\t\t\t}\n\t\t\tcurrentToken = \"\";\n\t\t\tlastStringContent = \"\";\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (/[a-zA-Z0-9_$]/.test(char)) {\n\t\t\tcurrentToken += char;\n\t\t} else if (char === \",\" || char === \"\\n\" || char === \"\\r\") {\n\t\t\tcurrentToken = \"\";\n\t\t\tlastStringContent = \"\";\n\t\t}\n\t}\n\n\treturn keys;\n}\n\n/**\n * Generate the TypeScript factory code for the tailored createEnv helper.\n *\n * @param clientKeys The client environment variable keys\n * @param sharedKeys The shared environment variable keys\n * @returns The generated TypeScript source code string\n */\nfunction generateFactoryCode(\n\tclientKeys: string[],\n\tsharedKeys: string[],\n): string {\n\tconst allKeys = Array.from(new Set([...clientKeys, ...sharedKeys]));\n\tconst runtimeEnvLines = allKeys\n\t\t.map((key) => `\\t\\t\\t${key}: process.env.${key},`)\n\t\t.join(\"\\n\");\n\n\treturn `/* eslint-disable */\n// prettier-ignore\n// biome-ignore format: auto-generated\n/**\n * @file env.gen.ts\n * @note This file is auto-generated by ArkEnv. DO NOT EDIT DIRECTLY.\n * @see https://arkenv.js.org\n */\n\nimport { createEnv as coreCreateEnv } from \"@arkenv/nextjs\";\nimport type { Infer } from \"@arkenv/nextjs\";\n\nexport { type } from \"@arkenv/nextjs\";\n\nexport function createEnv<\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}): Readonly<Infer<TServer & TClient & TShared>> {\n\treturn coreCreateEnv({\n\t\t...options,\n\t\truntimeEnv: {\n${runtimeEnvLines}\n\t\t},\n\t} as any) as any;\n}\n\nconst arkenv = createEnv;\nexport default arkenv;\n`;\n}\n\n/**\n * Generate the TypeScript factory code for the strict-layout `createEnv` 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 * @returns The generated TypeScript source code string\n */\nfunction generateClientFactoryCode(\n\tclientKeys: string[],\n\tsharedKeys: string[],\n): string {\n\tconst allKeys = Array.from(new Set([...clientKeys, ...sharedKeys]));\n\tconst runtimeEnvLines = allKeys\n\t\t.map((key) => `\\t\\t\\t${key}: process.env.${key},`)\n\t\t.join(\"\\n\");\n\n\treturn `/* eslint-disable */\n// prettier-ignore\n// biome-ignore format: auto-generated\n/**\n * @file env.gen.ts\n * @note This file is auto-generated by ArkEnv. DO NOT EDIT DIRECTLY.\n * @see https://arkenv.js.org\n */\n\nimport { createEnv as coreCreateEnv } from \"@arkenv/nextjs/client\";\n\nexport { type } from \"@arkenv/nextjs/client\";\n\nexport function createEnv<\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) {\n\treturn coreCreateEnv<TSchema, TExtends>(schema as any, {\n\t\t...options,\n\t\truntimeEnv: {\n${runtimeEnvLines}\n\t\t},\n\t} as any);\n}\n\nconst arkenv = createEnv;\nexport default arkenv;\n`;\n}\n\n/**\n * Extract env var keys from a strict-layout `client.ts` file.\n *\n * Locates the first `arkenv({...})` call and delegates to `parseBlockKeys`\n * to enumerate the keys defined in the schema object.\n *\n * @param content The source text of `client.ts`\n * @returns An array of env var key names found in the client schema\n */\nexport function extractClientKeys(content: string): string[] {\n\tconst block = extractClientBlock(content);\n\treturn block ? parseBlockKeys(block) : [];\n}\n\n/**\n * Extract env var keys from a strict-layout `internal/shared.ts` file.\n *\n * Locates the `SharedSchema = ...({...})` assignment and delegates to\n * `parseBlockKeys` to enumerate the keys defined in the schema object.\n *\n * @param content The source text of `internal/shared.ts`\n * @returns An array of env var key names found in the shared schema\n */\nexport function extractSharedKeys(content: string): string[] {\n\tconst block = extractSharedBlock(content);\n\treturn block ? parseBlockKeys(block) : [];\n}\n\n/**\n * Extract the schema object body from a strict-layout `client.ts` file.\n *\n * Matches the first `arkenv(...)` call, then performs brace-balanced\n * traversal while respecting strings and comments to find the boundaries\n * of the first argument object.\n *\n * @param content The source text of `client.ts`\n * @returns The raw text inside the first `{...}` argument, or `null` if not found\n */\nfunction extractClientBlock(content: string): string | null {\n\tconst regex = /\\barkenv\\s*\\(\\s*(?:[a-zA-Z0-9_$.]+\\s*\\(\\s*)*\\{/g;\n\tconst match = regex.exec(content);\n\tif (!match) return null;\n\n\tconst startIndex = regex.lastIndex;\n\tlet braceCount = 1;\n\tlet index = startIndex;\n\tlet inString: string | null = null;\n\tlet inComment: \"single\" | \"multi\" | null = null;\n\n\twhile (index < content.length && braceCount > 0) {\n\t\tconst char = content[index];\n\t\tconst nextChar = content[index + 1];\n\n\t\tif (inComment === \"single\") {\n\t\t\tif (char === \"\\n\" || char === \"\\r\") inComment = null;\n\t\t\tindex++;\n\t\t\tcontinue;\n\t\t}\n\t\tif (inComment === \"multi\") {\n\t\t\tif (char === \"*\" && nextChar === \"/\") {\n\t\t\t\tinComment = null;\n\t\t\t\tindex += 2;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tindex++;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (inString) {\n\t\t\tif (char === inString && content[index - 1] !== \"\\\\\") {\n\t\t\t\tinString = null;\n\t\t\t}\n\t\t\tindex++;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (char === \"/\" && nextChar === \"/\") {\n\t\t\tinComment = \"single\";\n\t\t\tindex += 2;\n\t\t\tcontinue;\n\t\t}\n\t\tif (char === \"/\" && nextChar === \"*\") {\n\t\t\tinComment = \"multi\";\n\t\t\tindex += 2;\n\t\t\tcontinue;\n\t\t}\n\t\tif (char === \"'\" || char === '\"' || char === \"`\") {\n\t\t\tinString = char;\n\t\t\tindex++;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (char === \"{\") {\n\t\t\tbraceCount++;\n\t\t} else if (char === \"}\") {\n\t\t\tbraceCount--;\n\t\t}\n\t\tindex++;\n\t}\n\n\tif (braceCount === 0) {\n\t\treturn content.slice(startIndex, index - 1);\n\t}\n\n\treturn null;\n}\n\n/**\n * Extract the schema object body from a strict-layout `internal/shared.ts` file.\n *\n * Matches the `SharedSchema = ...({...})` assignment, then performs\n * brace-balanced traversal while respecting strings and comments to find\n * the boundaries of the schema object.\n *\n * @param content The source text of `internal/shared.ts`\n * @returns The raw text inside the `{...}` schema object, or `null` if not found\n */\nfunction extractSharedBlock(content: string): string | null {\n\tconst regex = /\\bSharedSchema\\s*=\\s*(?:[a-zA-Z0-9_$.]+\\s*\\(\\s*)*\\{/g;\n\tconst match = regex.exec(content);\n\tif (!match) return null;\n\n\tconst startIndex = regex.lastIndex;\n\tlet braceCount = 1;\n\tlet index = startIndex;\n\tlet inString: string | null = null;\n\tlet inComment: \"single\" | \"multi\" | null = null;\n\n\twhile (index < content.length && braceCount > 0) {\n\t\tconst char = content[index];\n\t\tconst nextChar = content[index + 1];\n\n\t\tif (inComment === \"single\") {\n\t\t\tif (char === \"\\n\" || char === \"\\r\") inComment = null;\n\t\t\tindex++;\n\t\t\tcontinue;\n\t\t}\n\t\tif (inComment === \"multi\") {\n\t\t\tif (char === \"*\" && nextChar === \"/\") {\n\t\t\t\tinComment = null;\n\t\t\t\tindex += 2;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tindex++;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (inString) {\n\t\t\tif (char === inString && content[index - 1] !== \"\\\\\") {\n\t\t\t\tinString = null;\n\t\t\t}\n\t\t\tindex++;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (char === \"/\" && nextChar === \"/\") {\n\t\t\tinComment = \"single\";\n\t\t\tindex += 2;\n\t\t\tcontinue;\n\t\t}\n\t\tif (char === \"/\" && nextChar === \"*\") {\n\t\t\tinComment = \"multi\";\n\t\t\tindex += 2;\n\t\t\tcontinue;\n\t\t}\n\t\tif (char === \"'\" || char === '\"' || char === \"`\") {\n\t\t\tinString = char;\n\t\t\tindex++;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (char === \"{\") {\n\t\t\tbraceCount++;\n\t\t} else if (char === \"}\") {\n\t\t\tbraceCount--;\n\t\t}\n\t\tindex++;\n\t}\n\n\tif (braceCount === 0) {\n\t\treturn content.slice(startIndex, index - 1);\n\t}\n\n\treturn null;\n}\n"],"mappings":"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"}
package/dist/config.d.cts CHANGED
@@ -1,4 +1,9 @@
1
+ import * as _$chokidar from "chokidar";
2
+
1
3
  //#region src/config.d.ts
4
+ declare global {
5
+ var __arkenv_watcher__: _$chokidar.FSWatcher | undefined;
6
+ }
2
7
  /**
3
8
  * Configuration options for the ArkEnv Next.js integration.
4
9
  *
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.cts","names":[],"sources":["../src/config.ts"],"mappings":";;AAeA;;;;;;;;;AAoDA;KApDY,mBAAA;EAoDc;;;;;;;;;;;;;EAtCzB,UAAA;EAiSe;;;;;;;;;AA0DhB;;;;EA5UC,UAAA;EA6UA;;;;AAoTD;;;;EAvnBC,MAAA;AAAA;;;;;;;;;iBAae,UAAA,GAAA,CAAc,UAAA,EAAY,CAAA,EAAG,OAAA,GAAU,mBAAA,GAAsB,CAAA;;;;;;;;;iBA2P7D,UAAA,CACf,UAAA,UACA,UAAA,UACA,YAAA;;;;;;;iBAuDe,WAAA,CAAY,OAAA;EAC3B,UAAA;EACA,UAAA;AAAA;;;;;;;;;;iBAmTe,iBAAA,CAAkB,OAAA;;;;;;;;;;iBAclB,iBAAA,CAAkB,OAAA"}
1
+ {"version":3,"file":"config.d.cts","names":[],"sources":["../src/config.ts"],"mappings":";;;QAIQ,MAAA;EAAA,IAEH,kBAAA,EAAqC,UAAA,CAAE,SAAA;AAAA;AAAF;;;;;;;;;;AAc1C;AAd0C,KAc9B,mBAAA;;;;;;;;AAkDZ;;;;;;EApCC,UAAA;EAoC6E;;;;;;;;;AAsQ9E;;;;EA3RC,UAAA;EA6RA;;;;AAwDD;;;;EA3UC,MAAA;AAAA;;;;AAsoBD;;;;;iBA3nBgB,UAAA,GAAA,CAAc,UAAA,EAAY,CAAA,EAAG,OAAA,GAAU,mBAAA,GAAsB,CAAA;;;;;;;;;iBAsQ7D,UAAA,CACf,UAAA,UACA,UAAA,UACA,YAAA;;;;;;;iBAuDe,WAAA,CAAY,OAAA;EAC3B,UAAA;EACA,UAAA;AAAA;;;;;;;;;;iBAyTe,iBAAA,CAAkB,OAAA;;;;;;;;;;iBAclB,iBAAA,CAAkB,OAAA"}
package/dist/config.d.ts CHANGED
@@ -1,4 +1,9 @@
1
+ import * as _$chokidar from "chokidar";
2
+
1
3
  //#region src/config.d.ts
4
+ declare global {
5
+ var __arkenv_watcher__: _$chokidar.FSWatcher | undefined;
6
+ }
2
7
  /**
3
8
  * Configuration options for the ArkEnv Next.js integration.
4
9
  *
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","names":[],"sources":["../src/config.ts"],"mappings":";;AAeA;;;;;;;;;AAoDA;KApDY,mBAAA;EAoDc;;;;;;;;;;;;;EAtCzB,UAAA;EAiSe;;;;;;;;;AA0DhB;;;;EA5UC,UAAA;EA6UA;;;;AAoTD;;;;EAvnBC,MAAA;AAAA;;;;;;;;;iBAae,UAAA,GAAA,CAAc,UAAA,EAAY,CAAA,EAAG,OAAA,GAAU,mBAAA,GAAsB,CAAA;;;;;;;;;iBA2P7D,UAAA,CACf,UAAA,UACA,UAAA,UACA,YAAA;;;;;;;iBAuDe,WAAA,CAAY,OAAA;EAC3B,UAAA;EACA,UAAA;AAAA;;;;;;;;;;iBAmTe,iBAAA,CAAkB,OAAA;;;;;;;;;;iBAclB,iBAAA,CAAkB,OAAA"}
1
+ {"version":3,"file":"config.d.ts","names":[],"sources":["../src/config.ts"],"mappings":";;;QAIQ,MAAA;EAAA,IAEH,kBAAA,EAAqC,UAAA,CAAE,SAAA;AAAA;AAAF;;;;;;;;;;AAc1C;AAd0C,KAc9B,mBAAA;;;;;;;;AAkDZ;;;;;;EApCC,UAAA;EAoC6E;;;;;;;;;AAsQ9E;;;;EA3RC,UAAA;EA6RA;;;;AAwDD;;;;EA3UC,MAAA;AAAA;;;;AAsoBD;;;;;iBA3nBgB,UAAA,GAAA,CAAc,UAAA,EAAY,CAAA,EAAG,OAAA,GAAU,mBAAA,GAAsB,CAAA;;;;;;;;;iBAsQ7D,UAAA,CACf,UAAA,UACA,UAAA,UACA,YAAA;;;;;;;iBAuDe,WAAA,CAAY,OAAA;EAC3B,UAAA;EACA,UAAA;AAAA;;;;;;;;;;iBAyTe,iBAAA,CAAkB,OAAA;;;;;;;;;;iBAclB,iBAAA,CAAkB,OAAA"}
package/dist/config.js CHANGED
@@ -1,7 +1,7 @@
1
- import e from"node:fs";import t from"node:path";import{watch as n}from"chokidar";let r=!1;function i(n,r){let i=r?.schemaPath?t.resolve(r.schemaPath):o(),l=!1;if(i)if(e.existsSync(i))l=!0;else{let n=t.extname(i);if(n){let t=i.slice(0,-n.length);e.existsSync(t)&&(l=!0)}}if(!i||!l)throw Error(`[ArkEnv] Could not find schema file at ${r?.schemaPath||`src/env.ts or env.ts`}. Please specify 'schemaPath' in withArkEnv options.`);let{layout:u,baseDir:d}=a(i,r?.layout),f=u===`strict`&&d?d:t.dirname(i),p=t.join(f,`generated`,`env.gen.ts`),m=r?.outputPath?t.resolve(r.outputPath):p;try{c(i,m,u)}catch(e){let t=e instanceof Error?e.message:String(e);throw Error(`[ArkEnv] Failed to generate env.gen.ts: ${t}`)}return(process.env.NODE_ENV===`development`||process.env.NEXT_PHASE===`phase-development-server`)&&s(u===`strict`&&d?[t.join(d,`internal`,`shared.ts`),t.join(d,`client.ts`),t.join(d,`server.ts`)].filter(e.existsSync):[i],m,u),n}function a(n,r){let i=n=>e.existsSync(t.join(n,`internal`,`shared.ts`))&&e.existsSync(t.join(n,`client.ts`))&&e.existsSync(t.join(n,`server.ts`)),a=n=>{let r=t.extname(n),i=r?n.slice(0,-r.length):n;return e.existsSync(i)&&e.statSync(i).isDirectory()?i:n};if(!r){let r=a(n);if(e.existsSync(r)&&e.statSync(r).isDirectory())return i(r)?{layout:`strict`,baseDir:r}:{layout:`simple`,baseDir:r};let o=t.dirname(n),s=t.extname(n),c=s?n.slice(0,-s.length):n;return e.existsSync(c)&&e.statSync(c).isDirectory()&&i(c)?{layout:`strict`,baseDir:c}:i(o)?{layout:`strict`,baseDir:o}:t.basename(o)===`internal`&&i(t.dirname(o))?{layout:`strict`,baseDir:t.dirname(o)}:{layout:`simple`,baseDir:n}}if(r===`strict`){let r,i=a(n);if(e.existsSync(i)&&e.statSync(i).isDirectory())r=i;else{let e=t.dirname(n);r=t.basename(e)===`internal`?t.dirname(e):e}let o=t.join(r,`client.ts`),s=t.join(r,`internal`,`shared.ts`);if(!e.existsSync(o)||!e.existsSync(s))throw Error(`[ArkEnv] Strict layout requires "${o}" and "${s}" to exist. Ensure both files are present or remove the 'layout: "strict"' option to let ArkEnv auto-detect.`);return{layout:`strict`,baseDir:r}}return{layout:`simple`,baseDir:n}}function o(){let n=[t.join(process.cwd(),`src`,`env.ts`),t.join(process.cwd(),`env.ts`)];for(let t of n)if(e.existsSync(t))return t;let r=[t.join(process.cwd(),`src`,`env`),t.join(process.cwd(),`env`)];for(let n of r)if(e.existsSync(n)&&e.existsSync(t.join(n,`internal`,`shared.ts`))&&e.existsSync(t.join(n,`client.ts`))&&e.existsSync(t.join(n,`server.ts`)))return n;return null}function s(e,t,i){if(!r){r=!0;try{n(e,{ignoreInitial:!0}).on(`change`,()=>{try{c(Array.isArray(e)?e[0]:e,t,i)}catch(e){let t=e instanceof Error?e.message:String(e);console.error(`[ArkEnv Watcher] Failed to regenerate env.gen.ts: ${t}`)}})}catch(t){let n=t instanceof Error?t.message:String(t);console.error(`[ArkEnv Watcher] Failed to start watch on ${e}: ${n}`)}}}function c(n,r,i){let{layout:o,baseDir:s}=a(n,i),c=``;if(o===`strict`){let n=t.join(s,`client.ts`),r=t.join(s,`internal`,`shared.ts`),i=e.existsSync(n)?e.readFileSync(n,`utf-8`):``,a=e.existsSync(r)?e.readFileSync(r,`utf-8`):``;c=p(m(i),h(a))}else{let{clientKeys:t,sharedKeys:r}=l(e.readFileSync(n,`utf-8`));c=f(t,r)}let u=t.dirname(r);e.existsSync(u)||e.mkdirSync(u,{recursive:!0});let d=!0;e.existsSync(r)&&e.readFileSync(r,`utf-8`)===c&&(d=!1),d&&e.writeFileSync(r,c,`utf-8`)}function l(e){let t=[],n=[],r=u(e,`client`);r&&t.push(...d(r));let i=u(e,`shared`);return i&&n.push(...d(i)),{clientKeys:t,sharedKeys:n}}function u(e,t){let n=RegExp(`\\b${t}\\s*:\\s*(?:[a-zA-Z0-9_$.]+\\s*\\(\\s*)?\\{`,`g`);if(!n.exec(e))return null;let r=n.lastIndex,i=1,a=r,o=null,s=null;for(;a<e.length&&i>0;){let t=e[a],n=e[a+1];if(s===`single`){(t===`
2
- `||t===`\r`)&&(s=null),a++;continue}if(s===`multi`){if(t===`*`&&n===`/`){s=null,a+=2;continue}a++;continue}if(o){t===o&&e[a-1]!==`\\`&&(o=null),a++;continue}if(t===`/`&&n===`/`){s=`single`,a+=2;continue}if(t===`/`&&n===`*`){s=`multi`,a+=2;continue}if(t===`'`||t===`"`||t==="`"){o=t,a++;continue}t===`{`?i++:t===`}`&&i--,a++}return i===0?e.slice(r,a-1):null}function d(e){let t=[],n=null,r=null,i=``,a=``,o=0;for(let s=0;s<e.length;s++){let c=e[s],l=e[s+1];if(r===`single`){(c===`
1
+ import e from"node:fs";import t from"node:path";import{watch as n}from"chokidar";function r(n,r){let c=r?.schemaPath?t.resolve(r.schemaPath):a(),l=!1;if(c)if(e.existsSync(c))l=!0;else{let n=t.extname(c);if(n){let t=c.slice(0,-n.length);e.existsSync(t)&&(l=!0)}}if(!c||!l)throw Error(`[ArkEnv] Could not find schema file at ${r?.schemaPath||`src/env.ts or env.ts`}. Please specify 'schemaPath' in withArkEnv options.`);let{layout:u,baseDir:d}=i(c,r?.layout),f=u===`strict`&&d?d:t.dirname(c),p=t.join(f,`generated`,`env.gen.ts`),m=r?.outputPath?t.resolve(r.outputPath):p;try{s(c,m,u)}catch(e){let t=e instanceof Error?e.message:String(e);throw Error(`[ArkEnv] Failed to generate env.gen.ts: ${t}`)}return(process.env.NODE_ENV===`development`||process.env.NEXT_PHASE===`phase-development-server`)&&o(u===`strict`&&d?[t.join(d,`internal`,`shared.ts`),t.join(d,`client.ts`),t.join(d,`server.ts`)].filter(e.existsSync):[c],m,u),n}function i(n,r){let i=n=>e.existsSync(t.join(n,`internal`,`shared.ts`))&&e.existsSync(t.join(n,`client.ts`))&&e.existsSync(t.join(n,`server.ts`)),a=n=>{let r=t.extname(n),i=r?n.slice(0,-r.length):n;return e.existsSync(i)&&e.statSync(i).isDirectory()?i:n};if(!r){let r=a(n);if(e.existsSync(r)&&e.statSync(r).isDirectory())return i(r)?{layout:`strict`,baseDir:r}:{layout:`simple`,baseDir:r};let o=t.dirname(n),s=t.extname(n),c=s?n.slice(0,-s.length):n;return e.existsSync(c)&&e.statSync(c).isDirectory()&&i(c)?{layout:`strict`,baseDir:c}:i(o)?{layout:`strict`,baseDir:o}:t.basename(o)===`internal`&&i(t.dirname(o))?{layout:`strict`,baseDir:t.dirname(o)}:{layout:`simple`,baseDir:n}}if(r===`strict`){let r,i=a(n);if(e.existsSync(i)&&e.statSync(i).isDirectory())r=i;else{let e=t.dirname(n);r=t.basename(e)===`internal`?t.dirname(e):e}let o=t.join(r,`client.ts`),s=t.join(r,`internal`,`shared.ts`);if(!e.existsSync(o)||!e.existsSync(s))throw Error(`[ArkEnv] Strict layout requires "${o}" and "${s}" to exist. Ensure both files are present or remove the 'layout: "strict"' option to let ArkEnv auto-detect.`);return{layout:`strict`,baseDir:r}}return{layout:`simple`,baseDir:n}}function a(){let n=[t.join(process.cwd(),`src`,`env.ts`),t.join(process.cwd(),`env.ts`)];for(let t of n)if(e.existsSync(t))return t;let r=[t.join(process.cwd(),`src`,`env`),t.join(process.cwd(),`env`)];for(let n of r)if(e.existsSync(n)&&e.existsSync(t.join(n,`internal`,`shared.ts`))&&e.existsSync(t.join(n,`client.ts`))&&e.existsSync(t.join(n,`server.ts`)))return n;return null}function o(e,t,r){let i=globalThis.__arkenv_watcher__;i&&typeof i.close==`function`&&i.close().catch(e=>{let t=e instanceof Error?e.message:String(e);console.error(`[ArkEnv Watcher] Failed to close previous watcher: ${t}`)});try{let i=n(e,{ignoreInitial:!0});globalThis.__arkenv_watcher__=i,i.on(`change`,()=>{try{s(Array.isArray(e)?e[0]:e,t,r)}catch(e){let t=e instanceof Error?e.message:String(e);console.error(`[ArkEnv Watcher] Failed to regenerate env.gen.ts: ${t}`)}})}catch(t){let n=t instanceof Error?t.message:String(t);console.error(`[ArkEnv Watcher] Failed to start watch on ${e}: ${n}`)}}function s(n,r,a){let{layout:o,baseDir:s}=i(n,a),l=``;if(o===`strict`){let n=t.join(s,`client.ts`),r=t.join(s,`internal`,`shared.ts`),i=e.existsSync(n)?e.readFileSync(n,`utf-8`):``,a=e.existsSync(r)?e.readFileSync(r,`utf-8`):``;l=f(p(i),m(a))}else{let{clientKeys:t,sharedKeys:r}=c(e.readFileSync(n,`utf-8`));l=d(t,r)}let u=t.dirname(r);e.existsSync(u)||e.mkdirSync(u,{recursive:!0});let h=!0;e.existsSync(r)&&e.readFileSync(r,`utf-8`)===l&&(h=!1),h&&e.writeFileSync(r,l,`utf-8`)}function c(e){let t=[],n=[],r=l(e,`client`);r&&t.push(...u(r));let i=l(e,`shared`);return i&&n.push(...u(i)),{clientKeys:t,sharedKeys:n}}function l(e,t){let n=RegExp(`\\b${t}\\s*:\\s*(?:[a-zA-Z0-9_$.]+\\s*\\(\\s*)?\\{`,`g`);if(!n.exec(e))return null;let r=n.lastIndex,i=1,a=r,o=null,s=null;for(;a<e.length&&i>0;){let t=e[a],n=e[a+1];if(s===`single`){(t===`
2
+ `||t===`\r`)&&(s=null),a++;continue}if(s===`multi`){if(t===`*`&&n===`/`){s=null,a+=2;continue}a++;continue}if(o){t===o&&e[a-1]!==`\\`&&(o=null),a++;continue}if(t===`/`&&n===`/`){s=`single`,a+=2;continue}if(t===`/`&&n===`*`){s=`multi`,a+=2;continue}if(t===`'`||t===`"`||t==="`"){o=t,a++;continue}t===`{`?i++:t===`}`&&i--,a++}return i===0?e.slice(r,a-1):null}function u(e){let t=[],n=null,r=null,i=``,a=``,o=0;for(let s=0;s<e.length;s++){let c=e[s],l=e[s+1];if(r===`single`){(c===`
3
3
  `||c===`\r`)&&(r=null);continue}if(r===`multi`){c===`*`&&l===`/`&&(r=null,s++);continue}if(n){c===n&&e[s-1]!==`\\`?(n=null,a=i,i=``):i+=c;continue}if(c===`/`&&l===`/`){r=`single`,s++;continue}if(c===`/`&&l===`*`){r=`multi`,s++;continue}if(c===`'`||c===`"`||c==="`"){n=c,i=``;continue}if(c===`{`){o++,i=``,a=``;continue}if(c===`}`){o--,i=``,a=``;continue}if(c===`:`){if(o===0){let e=i.trim()||a.trim();e&&t.push(e)}i=``,a=``;continue}/[a-zA-Z0-9_$]/.test(c)?i+=c:(c===`,`||c===`
4
- `||c===`\r`)&&(i=``,a=``)}return t}function f(e,t){return`/* eslint-disable */
4
+ `||c===`\r`)&&(i=``,a=``)}return t}function d(e,t){return`/* eslint-disable */
5
5
  // prettier-ignore
6
6
  // biome-ignore format: auto-generated
7
7
  /**
@@ -34,7 +34,10 @@ ${Array.from(new Set([...e,...t])).map(e=>`\t\t\t${e}: process.env.${e},`).join(
34
34
  },
35
35
  } as any) as any;
36
36
  }
37
- `}function p(e,t){return`/* eslint-disable */
37
+
38
+ const arkenv = createEnv;
39
+ export default arkenv;
40
+ `}function f(e,t){return`/* eslint-disable */
38
41
  // prettier-ignore
39
42
  // biome-ignore format: auto-generated
40
43
  /**
@@ -66,7 +69,10 @@ ${Array.from(new Set([...e,...t])).map(e=>`\t\t\t${e}: process.env.${e},`).join(
66
69
  },
67
70
  } as any);
68
71
  }
69
- `}function m(e){let t=g(e);return t?d(t):[]}function h(e){let t=_(e);return t?d(t):[]}function g(e){let t=/\barkenv\s*\(\s*(?:[a-zA-Z0-9_$.]+\s*\(\s*)*\{/g;if(!t.exec(e))return null;let n=t.lastIndex,r=1,i=n,a=null,o=null;for(;i<e.length&&r>0;){let t=e[i],n=e[i+1];if(o===`single`){(t===`
70
- `||t===`\r`)&&(o=null),i++;continue}if(o===`multi`){if(t===`*`&&n===`/`){o=null,i+=2;continue}i++;continue}if(a){t===a&&e[i-1]!==`\\`&&(a=null),i++;continue}if(t===`/`&&n===`/`){o=`single`,i+=2;continue}if(t===`/`&&n===`*`){o=`multi`,i+=2;continue}if(t===`'`||t===`"`||t==="`"){a=t,i++;continue}t===`{`?r++:t===`}`&&r--,i++}return r===0?e.slice(n,i-1):null}function _(e){let t=/\bSharedSchema\s*=\s*(?:[a-zA-Z0-9_$.]+\s*\(\s*)*\{/g;if(!t.exec(e))return null;let n=t.lastIndex,r=1,i=n,a=null,o=null;for(;i<e.length&&r>0;){let t=e[i],n=e[i+1];if(o===`single`){(t===`
71
- `||t===`\r`)&&(o=null),i++;continue}if(o===`multi`){if(t===`*`&&n===`/`){o=null,i+=2;continue}i++;continue}if(a){t===a&&e[i-1]!==`\\`&&(a=null),i++;continue}if(t===`/`&&n===`/`){o=`single`,i+=2;continue}if(t===`/`&&n===`*`){o=`multi`,i+=2;continue}if(t===`'`||t===`"`||t==="`"){a=t,i++;continue}t===`{`?r++:t===`}`&&r--,i++}return r===0?e.slice(n,i-1):null}export{m as extractClientKeys,l as extractKeys,h as extractSharedKeys,c as runCodegen,i as withArkEnv};
72
+
73
+ const arkenv = createEnv;
74
+ export default arkenv;
75
+ `}function p(e){let t=h(e);return t?u(t):[]}function m(e){let t=g(e);return t?u(t):[]}function h(e){let t=/\barkenv\s*\(\s*(?:[a-zA-Z0-9_$.]+\s*\(\s*)*\{/g;if(!t.exec(e))return null;let n=t.lastIndex,r=1,i=n,a=null,o=null;for(;i<e.length&&r>0;){let t=e[i],n=e[i+1];if(o===`single`){(t===`
76
+ `||t===`\r`)&&(o=null),i++;continue}if(o===`multi`){if(t===`*`&&n===`/`){o=null,i+=2;continue}i++;continue}if(a){t===a&&e[i-1]!==`\\`&&(a=null),i++;continue}if(t===`/`&&n===`/`){o=`single`,i+=2;continue}if(t===`/`&&n===`*`){o=`multi`,i+=2;continue}if(t===`'`||t===`"`||t==="`"){a=t,i++;continue}t===`{`?r++:t===`}`&&r--,i++}return r===0?e.slice(n,i-1):null}function g(e){let t=/\bSharedSchema\s*=\s*(?:[a-zA-Z0-9_$.]+\s*\(\s*)*\{/g;if(!t.exec(e))return null;let n=t.lastIndex,r=1,i=n,a=null,o=null;for(;i<e.length&&r>0;){let t=e[i],n=e[i+1];if(o===`single`){(t===`
77
+ `||t===`\r`)&&(o=null),i++;continue}if(o===`multi`){if(t===`*`&&n===`/`){o=null,i+=2;continue}i++;continue}if(a){t===a&&e[i-1]!==`\\`&&(a=null),i++;continue}if(t===`/`&&n===`/`){o=`single`,i+=2;continue}if(t===`/`&&n===`*`){o=`multi`,i+=2;continue}if(t===`'`||t===`"`||t==="`"){a=t,i++;continue}t===`{`?r++:t===`}`&&r--,i++}return r===0?e.slice(n,i-1):null}export{p as extractClientKeys,c as extractKeys,m as extractSharedKeys,s as runCodegen,r as withArkEnv};
72
78
  //# sourceMappingURL=config.js.map
@@ -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 { watch as chokidarWatch } from \"chokidar\";\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 * - `\"simple\"` (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 \"simple\"\n\t */\n\tlayout?: \"simple\" | \"strict\";\n};\n\nlet watcherInitialized = false;\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\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 withArkEnv options.`,\n\t\t);\n\t}\n\n\tconst { layout: resolvedLayout, baseDir } = resolveLayout(\n\t\tschemaPath,\n\t\toptions?.layout,\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\n\ttry {\n\t\trunCodegen(schemaPath, outputPath, resolvedLayout);\n\t} catch (error: unknown) {\n\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\tthrow new Error(`[ArkEnv] Failed to generate env.gen.ts: ${message}`);\n\t}\n\n\t// 4. Initialize development file watcher if in dev mode\n\tconst isDev =\n\t\tprocess.env.NODE_ENV === \"development\" ||\n\t\tprocess.env.NEXT_PHASE === \"phase-development-server\";\n\tif (isDev) {\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, outputPath, resolvedLayout);\n\t}\n\n\treturn nextConfig;\n}\n\n/**\n * Find the path to the schema file in the project.\n *\n * @returns The absolute path to the schema file, or null if not found\n */\n/**\n * Resolve the layout (simple vs strict) and the base directory from a schema path.\n *\n * Auto-detects layout when `layoutOption` is not provided. When `layoutOption`\n * is `\"strict\"`, validates that the required split files exist and throws a\n * descriptive error if either is missing.\n *\n * @param schemaPath The absolute path to the schema file or directory\n * @param layoutOption The explicit layout option, if provided\n * @returns The resolved layout and base directory\n * @throws An error if strict layout files are missing\n */\nfunction resolveLayout(\n\tschemaPath: string,\n\tlayoutOption?: \"simple\" | \"strict\",\n): { layout: \"simple\" | \"strict\"; baseDir: string } {\n\tconst checkStrict = (dir: string) =>\n\t\tfs.existsSync(path.join(dir, \"internal\", \"shared.ts\")) &&\n\t\tfs.existsSync(path.join(dir, \"client.ts\")) &&\n\t\tfs.existsSync(path.join(dir, \"server.ts\"));\n\n\tconst resolveBaseDir = (p: string): string => {\n\t\t// Normalize: if schemaPath has an extension, try the extensionless form as a dir\n\t\tconst ext = path.extname(p);\n\t\tconst baseWithoutExt = ext ? p.slice(0, -ext.length) : p;\n\t\tif (\n\t\t\tfs.existsSync(baseWithoutExt) &&\n\t\t\tfs.statSync(baseWithoutExt).isDirectory()\n\t\t) {\n\t\t\treturn baseWithoutExt;\n\t\t}\n\t\treturn p;\n\t};\n\n\tif (!layoutOption) {\n\t\t// Auto-detect\n\t\tconst resolved = resolveBaseDir(schemaPath);\n\t\tif (fs.existsSync(resolved) && fs.statSync(resolved).isDirectory()) {\n\t\t\tif (checkStrict(resolved)) {\n\t\t\t\treturn { layout: \"strict\", baseDir: resolved };\n\t\t\t}\n\t\t\treturn { layout: \"simple\", baseDir: resolved };\n\t\t}\n\n\t\t// schemaPath is a file — check surrounding dirs\n\t\tconst parent = path.dirname(schemaPath);\n\t\tconst ext = path.extname(schemaPath);\n\t\tconst baseWithoutExt = ext ? schemaPath.slice(0, -ext.length) : schemaPath;\n\t\tif (\n\t\t\tfs.existsSync(baseWithoutExt) &&\n\t\t\tfs.statSync(baseWithoutExt).isDirectory() &&\n\t\t\tcheckStrict(baseWithoutExt)\n\t\t) {\n\t\t\treturn { layout: \"strict\", baseDir: baseWithoutExt };\n\t\t}\n\t\tif (checkStrict(parent)) {\n\t\t\treturn { layout: \"strict\", baseDir: parent };\n\t\t}\n\t\tif (\n\t\t\tpath.basename(parent) === \"internal\" &&\n\t\t\tcheckStrict(path.dirname(parent))\n\t\t) {\n\t\t\treturn { layout: \"strict\", baseDir: path.dirname(parent) };\n\t\t}\n\t\treturn { layout: \"simple\", baseDir: schemaPath };\n\t}\n\n\tif (layoutOption === \"strict\") {\n\t\t// Resolve baseDir for an explicit strict layout\n\t\tlet baseDir: string;\n\t\tconst resolved = resolveBaseDir(schemaPath);\n\t\tif (fs.existsSync(resolved) && fs.statSync(resolved).isDirectory()) {\n\t\t\tbaseDir = resolved;\n\t\t} else {\n\t\t\tconst parent = path.dirname(schemaPath);\n\t\t\tif (path.basename(parent) === \"internal\") {\n\t\t\t\tbaseDir = path.dirname(parent);\n\t\t\t} else {\n\t\t\t\tbaseDir = parent;\n\t\t\t}\n\t\t}\n\n\t\t// Validate that required split files exist\n\t\tconst clientPath = path.join(baseDir, \"client.ts\");\n\t\tconst sharedPath = path.join(baseDir, \"internal\", \"shared.ts\");\n\t\tif (!fs.existsSync(clientPath) || !fs.existsSync(sharedPath)) {\n\t\t\tthrow new Error(\n\t\t\t\t`[ArkEnv] Strict layout requires \"${clientPath}\" and \"${sharedPath}\" to exist. ` +\n\t\t\t\t\t`Ensure both files are present or remove the 'layout: \"strict\"' option to let ArkEnv auto-detect.`,\n\t\t\t);\n\t\t}\n\n\t\treturn { layout: \"strict\", baseDir };\n\t}\n\n\t// layoutOption === \"simple\"\n\treturn { layout: \"simple\", baseDir: schemaPath };\n}\n\nfunction findSchemaPath(): string | null {\n\tconst possiblePaths = [\n\t\tpath.join(process.cwd(), \"src\", \"env.ts\"),\n\t\tpath.join(process.cwd(), \"env.ts\"),\n\t];\n\tfor (const p of possiblePaths) {\n\t\tif (fs.existsSync(p)) return p;\n\t}\n\n\tconst possibleDirs = [\n\t\tpath.join(process.cwd(), \"src\", \"env\"),\n\t\tpath.join(process.cwd(), \"env\"),\n\t];\n\tfor (const d of possibleDirs) {\n\t\tif (\n\t\t\tfs.existsSync(d) &&\n\t\t\tfs.existsSync(path.join(d, \"internal\", \"shared.ts\")) &&\n\t\t\tfs.existsSync(path.join(d, \"client.ts\")) &&\n\t\t\tfs.existsSync(path.join(d, \"server.ts\"))\n\t\t) {\n\t\t\treturn d;\n\t\t}\n\t}\n\treturn null;\n}\n\n/**\n * Watch the schema file for changes and trigger codegen.\n *\n * @param schemaPath The absolute path to the schema file, or an array of paths to watch\n * @param outputPath The absolute path to the generated output file\n * @param layout The resolved layout to pass through to codegen on each change\n */\nfunction watchSchema(\n\tschemaPath: string | string[],\n\toutputPath: string,\n\tlayout?: \"simple\" | \"strict\",\n) {\n\tif (watcherInitialized) return;\n\twatcherInitialized = true;\n\n\ttry {\n\t\tchokidarWatch(schemaPath, { ignoreInitial: true }).on(\"change\", () => {\n\t\t\ttry {\n\t\t\t\tconst mainSchemaPath = Array.isArray(schemaPath)\n\t\t\t\t\t? schemaPath[0]\n\t\t\t\t\t: schemaPath;\n\t\t\t\trunCodegen(mainSchemaPath, outputPath, layout);\n\t\t\t} catch (err: unknown) {\n\t\t\t\tconst message = err instanceof Error ? err.message : String(err);\n\t\t\t\t// biome-ignore lint/suspicious/noConsole: watcher errors must be logged\n\t\t\t\tconsole.error(\n\t\t\t\t\t`[ArkEnv Watcher] Failed to regenerate env.gen.ts: ${message}`,\n\t\t\t\t);\n\t\t\t}\n\t\t});\n\t} catch (err: unknown) {\n\t\tconst message = err instanceof Error ? err.message : String(err);\n\t\t// biome-ignore lint/suspicious/noConsole: watcher errors must be logged\n\t\tconsole.error(\n\t\t\t`[ArkEnv Watcher] Failed to start watch on ${schemaPath}: ${message}`,\n\t\t);\n\t}\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 * @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?: \"simple\" | \"strict\",\n) {\n\tconst { layout: resolvedLayout, baseDir } = resolveLayout(\n\t\tschemaPath,\n\t\tlayoutOption,\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 clientKeys = extractClientKeys(clientContent);\n\t\tconst sharedKeys = extractSharedKeys(sharedContent);\n\n\t\tgeneratedCode = generateClientFactoryCode(clientKeys, sharedKeys);\n\t} else {\n\t\tconst fileContent = fs.readFileSync(schemaPath, \"utf-8\");\n\t\tconst { clientKeys, sharedKeys } = extractKeys(fileContent);\n\t\tgeneratedCode = generateFactoryCode(clientKeys, sharedKeys);\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\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} {\n\tconst clientKeys: string[] = [];\n\tconst sharedKeys: string[] = [];\n\n\t// Extract client block\n\tconst clientBlock = extractBlock(content, \"client\");\n\tif (clientBlock) {\n\t\tclientKeys.push(...parseBlockKeys(clientBlock));\n\t}\n\n\t// Extract shared block\n\tconst sharedBlock = extractBlock(content, \"shared\");\n\tif (sharedBlock) {\n\t\tsharedKeys.push(...parseBlockKeys(sharedBlock));\n\t}\n\n\treturn { clientKeys, sharedKeys };\n}\n\n/**\n * Extract a specific block from the schema content by name.\n *\n * @param content The schema file string content\n * @param blockName The name of the block to extract (e.g., 'client' or 'shared')\n * @returns The contents of the block, or null if not found\n */\nfunction extractBlock(content: string, blockName: string): string | null {\n\t// Find \"\\bblockName\\s*:\\s*{\" or \"\\bblockName\\s*:\\s*type({\"\n\tconst regex = new RegExp(\n\t\t`\\\\b${blockName}\\\\s*:\\\\s*(?:[a-zA-Z0-9_$.]+\\\\s*\\\\(\\\\s*)?\\\\{`,\n\t\t\"g\",\n\t);\n\tconst match = regex.exec(content);\n\tif (!match) return null;\n\n\tconst startIndex = regex.lastIndex;\n\tlet braceCount = 1;\n\tlet index = startIndex;\n\tlet inString: string | null = null;\n\tlet inComment: \"single\" | \"multi\" | null = null;\n\n\twhile (index < content.length && braceCount > 0) {\n\t\tconst char = content[index];\n\t\tconst nextChar = content[index + 1];\n\n\t\tif (inComment === \"single\") {\n\t\t\tif (char === \"\\n\" || char === \"\\r\") inComment = null;\n\t\t\tindex++;\n\t\t\tcontinue;\n\t\t}\n\t\tif (inComment === \"multi\") {\n\t\t\tif (char === \"*\" && nextChar === \"/\") {\n\t\t\t\tinComment = null;\n\t\t\t\tindex += 2;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tindex++;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (inString) {\n\t\t\tif (char === inString && content[index - 1] !== \"\\\\\") {\n\t\t\t\tinString = null;\n\t\t\t}\n\t\t\tindex++;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (char === \"/\" && nextChar === \"/\") {\n\t\t\tinComment = \"single\";\n\t\t\tindex += 2;\n\t\t\tcontinue;\n\t\t}\n\t\tif (char === \"/\" && nextChar === \"*\") {\n\t\t\tinComment = \"multi\";\n\t\t\tindex += 2;\n\t\t\tcontinue;\n\t\t}\n\t\tif (char === \"'\" || char === '\"' || char === \"`\") {\n\t\t\tinString = char;\n\t\t\tindex++;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (char === \"{\") {\n\t\t\tbraceCount++;\n\t\t} else if (char === \"}\") {\n\t\t\tbraceCount--;\n\t\t}\n\t\tindex++;\n\t}\n\n\tif (braceCount === 0) {\n\t\treturn content.slice(startIndex, index - 1);\n\t}\n\n\treturn null;\n}\n\n/**\n * Parse environment variable keys from a block's content.\n *\n * @param blockContent The raw content of the block\n * @returns An array of parsed environment variable keys\n */\nfunction parseBlockKeys(blockContent: string): string[] {\n\tconst keys: string[] = [];\n\tlet inString: string | null = null;\n\tlet inComment: \"single\" | \"multi\" | null = null;\n\tlet currentToken = \"\";\n\tlet lastStringContent = \"\";\n\tlet braceDepth = 0;\n\n\tfor (let i = 0; i < blockContent.length; i++) {\n\t\tconst char = blockContent[i];\n\t\tconst nextChar = blockContent[i + 1];\n\n\t\tif (inComment === \"single\") {\n\t\t\tif (char === \"\\n\" || char === \"\\r\") inComment = null;\n\t\t\tcontinue;\n\t\t}\n\t\tif (inComment === \"multi\") {\n\t\t\tif (char === \"*\" && nextChar === \"/\") {\n\t\t\t\tinComment = null;\n\t\t\t\ti++;\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (inString) {\n\t\t\tif (char === inString && blockContent[i - 1] !== \"\\\\\") {\n\t\t\t\tinString = null;\n\t\t\t\tlastStringContent = currentToken;\n\t\t\t\tcurrentToken = \"\";\n\t\t\t} else {\n\t\t\t\tcurrentToken += char;\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Start comments/strings\n\t\tif (char === \"/\" && nextChar === \"/\") {\n\t\t\tinComment = \"single\";\n\t\t\ti++;\n\t\t\tcontinue;\n\t\t}\n\t\tif (char === \"/\" && nextChar === \"*\") {\n\t\t\tinComment = \"multi\";\n\t\t\ti++;\n\t\t\tcontinue;\n\t\t}\n\t\tif (char === \"'\" || char === '\"' || char === \"`\") {\n\t\t\tinString = char;\n\t\t\tcurrentToken = \"\";\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (char === \"{\") {\n\t\t\tbraceDepth++;\n\t\t\tcurrentToken = \"\";\n\t\t\tlastStringContent = \"\";\n\t\t\tcontinue;\n\t\t}\n\t\tif (char === \"}\") {\n\t\t\tbraceDepth--;\n\t\t\tcurrentToken = \"\";\n\t\t\tlastStringContent = \"\";\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (char === \":\") {\n\t\t\tif (braceDepth === 0) {\n\t\t\t\tconst key = currentToken.trim() || lastStringContent.trim();\n\t\t\t\tif (key) {\n\t\t\t\t\tkeys.push(key);\n\t\t\t\t}\n\t\t\t}\n\t\t\tcurrentToken = \"\";\n\t\t\tlastStringContent = \"\";\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (/[a-zA-Z0-9_$]/.test(char)) {\n\t\t\tcurrentToken += char;\n\t\t} else if (char === \",\" || char === \"\\n\" || char === \"\\r\") {\n\t\t\tcurrentToken = \"\";\n\t\t\tlastStringContent = \"\";\n\t\t}\n\t}\n\n\treturn keys;\n}\n\n/**\n * Generate the TypeScript factory code for the tailored createEnv helper.\n *\n * @param clientKeys The client environment variable keys\n * @param sharedKeys The shared environment variable keys\n * @returns The generated TypeScript source code string\n */\nfunction generateFactoryCode(\n\tclientKeys: string[],\n\tsharedKeys: string[],\n): string {\n\tconst allKeys = Array.from(new Set([...clientKeys, ...sharedKeys]));\n\tconst runtimeEnvLines = allKeys\n\t\t.map((key) => `\\t\\t\\t${key}: process.env.${key},`)\n\t\t.join(\"\\n\");\n\n\treturn `/* eslint-disable */\n// prettier-ignore\n// biome-ignore format: auto-generated\n/**\n * @file env.gen.ts\n * @note This file is auto-generated by ArkEnv. DO NOT EDIT DIRECTLY.\n * @see https://arkenv.js.org\n */\n\nimport { createEnv as coreCreateEnv } from \"@arkenv/nextjs\";\nimport type { Infer } from \"@arkenv/nextjs\";\n\nexport { type } from \"@arkenv/nextjs\";\n\nexport function createEnv<\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}): Readonly<Infer<TServer & TClient & TShared>> {\n\treturn coreCreateEnv({\n\t\t...options,\n\t\truntimeEnv: {\n${runtimeEnvLines}\n\t\t},\n\t} as any) as any;\n}\n`;\n}\n\n/**\n * Generate the TypeScript factory code for the strict-layout `createEnv` 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 * @returns The generated TypeScript source code string\n */\nfunction generateClientFactoryCode(\n\tclientKeys: string[],\n\tsharedKeys: string[],\n): string {\n\tconst allKeys = Array.from(new Set([...clientKeys, ...sharedKeys]));\n\tconst runtimeEnvLines = allKeys\n\t\t.map((key) => `\\t\\t\\t${key}: process.env.${key},`)\n\t\t.join(\"\\n\");\n\n\treturn `/* eslint-disable */\n// prettier-ignore\n// biome-ignore format: auto-generated\n/**\n * @file env.gen.ts\n * @note This file is auto-generated by ArkEnv. DO NOT EDIT DIRECTLY.\n * @see https://arkenv.js.org\n */\n\nimport { createEnv as coreCreateEnv } from \"@arkenv/nextjs/client\";\n\nexport { type } from \"@arkenv/nextjs/client\";\n\nexport function createEnv<\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) {\n\treturn coreCreateEnv<TSchema, TExtends>(schema as any, {\n\t\t...options,\n\t\truntimeEnv: {\n${runtimeEnvLines}\n\t\t},\n\t} as any);\n}\n`;\n}\n\n/**\n * Extract env var keys from a strict-layout `client.ts` file.\n *\n * Locates the first `arkenv({...})` call and delegates to `parseBlockKeys`\n * to enumerate the keys defined in the schema object.\n *\n * @param content The source text of `client.ts`\n * @returns An array of env var key names found in the client schema\n */\nexport function extractClientKeys(content: string): string[] {\n\tconst block = extractClientBlock(content);\n\treturn block ? parseBlockKeys(block) : [];\n}\n\n/**\n * Extract env var keys from a strict-layout `internal/shared.ts` file.\n *\n * Locates the `SharedSchema = ...({...})` assignment and delegates to\n * `parseBlockKeys` to enumerate the keys defined in the schema object.\n *\n * @param content The source text of `internal/shared.ts`\n * @returns An array of env var key names found in the shared schema\n */\nexport function extractSharedKeys(content: string): string[] {\n\tconst block = extractSharedBlock(content);\n\treturn block ? parseBlockKeys(block) : [];\n}\n\n/**\n * Extract the schema object body from a strict-layout `client.ts` file.\n *\n * Matches the first `arkenv(...)` call, then performs brace-balanced\n * traversal while respecting strings and comments to find the boundaries\n * of the first argument object.\n *\n * @param content The source text of `client.ts`\n * @returns The raw text inside the first `{...}` argument, or `null` if not found\n */\nfunction extractClientBlock(content: string): string | null {\n\tconst regex = /\\barkenv\\s*\\(\\s*(?:[a-zA-Z0-9_$.]+\\s*\\(\\s*)*\\{/g;\n\tconst match = regex.exec(content);\n\tif (!match) return null;\n\n\tconst startIndex = regex.lastIndex;\n\tlet braceCount = 1;\n\tlet index = startIndex;\n\tlet inString: string | null = null;\n\tlet inComment: \"single\" | \"multi\" | null = null;\n\n\twhile (index < content.length && braceCount > 0) {\n\t\tconst char = content[index];\n\t\tconst nextChar = content[index + 1];\n\n\t\tif (inComment === \"single\") {\n\t\t\tif (char === \"\\n\" || char === \"\\r\") inComment = null;\n\t\t\tindex++;\n\t\t\tcontinue;\n\t\t}\n\t\tif (inComment === \"multi\") {\n\t\t\tif (char === \"*\" && nextChar === \"/\") {\n\t\t\t\tinComment = null;\n\t\t\t\tindex += 2;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tindex++;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (inString) {\n\t\t\tif (char === inString && content[index - 1] !== \"\\\\\") {\n\t\t\t\tinString = null;\n\t\t\t}\n\t\t\tindex++;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (char === \"/\" && nextChar === \"/\") {\n\t\t\tinComment = \"single\";\n\t\t\tindex += 2;\n\t\t\tcontinue;\n\t\t}\n\t\tif (char === \"/\" && nextChar === \"*\") {\n\t\t\tinComment = \"multi\";\n\t\t\tindex += 2;\n\t\t\tcontinue;\n\t\t}\n\t\tif (char === \"'\" || char === '\"' || char === \"`\") {\n\t\t\tinString = char;\n\t\t\tindex++;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (char === \"{\") {\n\t\t\tbraceCount++;\n\t\t} else if (char === \"}\") {\n\t\t\tbraceCount--;\n\t\t}\n\t\tindex++;\n\t}\n\n\tif (braceCount === 0) {\n\t\treturn content.slice(startIndex, index - 1);\n\t}\n\n\treturn null;\n}\n\n/**\n * Extract the schema object body from a strict-layout `internal/shared.ts` file.\n *\n * Matches the `SharedSchema = ...({...})` assignment, then performs\n * brace-balanced traversal while respecting strings and comments to find\n * the boundaries of the schema object.\n *\n * @param content The source text of `internal/shared.ts`\n * @returns The raw text inside the `{...}` schema object, or `null` if not found\n */\nfunction extractSharedBlock(content: string): string | null {\n\tconst regex = /\\bSharedSchema\\s*=\\s*(?:[a-zA-Z0-9_$.]+\\s*\\(\\s*)*\\{/g;\n\tconst match = regex.exec(content);\n\tif (!match) return null;\n\n\tconst startIndex = regex.lastIndex;\n\tlet braceCount = 1;\n\tlet index = startIndex;\n\tlet inString: string | null = null;\n\tlet inComment: \"single\" | \"multi\" | null = null;\n\n\twhile (index < content.length && braceCount > 0) {\n\t\tconst char = content[index];\n\t\tconst nextChar = content[index + 1];\n\n\t\tif (inComment === \"single\") {\n\t\t\tif (char === \"\\n\" || char === \"\\r\") inComment = null;\n\t\t\tindex++;\n\t\t\tcontinue;\n\t\t}\n\t\tif (inComment === \"multi\") {\n\t\t\tif (char === \"*\" && nextChar === \"/\") {\n\t\t\t\tinComment = null;\n\t\t\t\tindex += 2;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tindex++;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (inString) {\n\t\t\tif (char === inString && content[index - 1] !== \"\\\\\") {\n\t\t\t\tinString = null;\n\t\t\t}\n\t\t\tindex++;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (char === \"/\" && nextChar === \"/\") {\n\t\t\tinComment = \"single\";\n\t\t\tindex += 2;\n\t\t\tcontinue;\n\t\t}\n\t\tif (char === \"/\" && nextChar === \"*\") {\n\t\t\tinComment = \"multi\";\n\t\t\tindex += 2;\n\t\t\tcontinue;\n\t\t}\n\t\tif (char === \"'\" || char === '\"' || char === \"`\") {\n\t\t\tinString = char;\n\t\t\tindex++;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (char === \"{\") {\n\t\t\tbraceCount++;\n\t\t} else if (char === \"}\") {\n\t\t\tbraceCount--;\n\t\t}\n\t\tindex++;\n\t}\n\n\tif (braceCount === 0) {\n\t\treturn content.slice(startIndex, index - 1);\n\t}\n\n\treturn null;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"config.js","names":["chokidarWatch"],"sources":["../src/config.ts"],"sourcesContent":["import fs from \"node:fs\";\nimport path from \"node:path\";\nimport { watch as chokidarWatch } from \"chokidar\";\n\ndeclare global {\n\t// eslint-disable-next-line no-var\n\tvar __arkenv_watcher__: import(\"chokidar\").FSWatcher | undefined;\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 * - `\"simple\"` (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 \"simple\"\n\t */\n\tlayout?: \"simple\" | \"strict\";\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\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 withArkEnv options.`,\n\t\t);\n\t}\n\n\tconst { layout: resolvedLayout, baseDir } = resolveLayout(\n\t\tschemaPath,\n\t\toptions?.layout,\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\n\ttry {\n\t\trunCodegen(schemaPath, outputPath, resolvedLayout);\n\t} catch (error: unknown) {\n\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\tthrow new Error(`[ArkEnv] Failed to generate env.gen.ts: ${message}`);\n\t}\n\n\t// 4. Initialize development file watcher if in dev mode\n\tconst isDev =\n\t\tprocess.env.NODE_ENV === \"development\" ||\n\t\tprocess.env.NEXT_PHASE === \"phase-development-server\";\n\tif (isDev) {\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, outputPath, resolvedLayout);\n\t}\n\n\treturn nextConfig;\n}\n\n/**\n * Find the path to the schema file in the project.\n *\n * @returns The absolute path to the schema file, or null if not found\n */\n/**\n * Resolve the layout (simple vs strict) and the base directory from a schema path.\n *\n * Auto-detects layout when `layoutOption` is not provided. When `layoutOption`\n * is `\"strict\"`, validates that the required split files exist and throws a\n * descriptive error if either is missing.\n *\n * @param schemaPath The absolute path to the schema file or directory\n * @param layoutOption The explicit layout option, if provided\n * @returns The resolved layout and base directory\n * @throws An error if strict layout files are missing\n */\nfunction resolveLayout(\n\tschemaPath: string,\n\tlayoutOption?: \"simple\" | \"strict\",\n): { layout: \"simple\" | \"strict\"; baseDir: string } {\n\tconst checkStrict = (dir: string) =>\n\t\tfs.existsSync(path.join(dir, \"internal\", \"shared.ts\")) &&\n\t\tfs.existsSync(path.join(dir, \"client.ts\")) &&\n\t\tfs.existsSync(path.join(dir, \"server.ts\"));\n\n\tconst resolveBaseDir = (p: string): string => {\n\t\t// Normalize: if schemaPath has an extension, try the extensionless form as a dir\n\t\tconst ext = path.extname(p);\n\t\tconst baseWithoutExt = ext ? p.slice(0, -ext.length) : p;\n\t\tif (\n\t\t\tfs.existsSync(baseWithoutExt) &&\n\t\t\tfs.statSync(baseWithoutExt).isDirectory()\n\t\t) {\n\t\t\treturn baseWithoutExt;\n\t\t}\n\t\treturn p;\n\t};\n\n\tif (!layoutOption) {\n\t\t// Auto-detect\n\t\tconst resolved = resolveBaseDir(schemaPath);\n\t\tif (fs.existsSync(resolved) && fs.statSync(resolved).isDirectory()) {\n\t\t\tif (checkStrict(resolved)) {\n\t\t\t\treturn { layout: \"strict\", baseDir: resolved };\n\t\t\t}\n\t\t\treturn { layout: \"simple\", baseDir: resolved };\n\t\t}\n\n\t\t// schemaPath is a file — check surrounding dirs\n\t\tconst parent = path.dirname(schemaPath);\n\t\tconst ext = path.extname(schemaPath);\n\t\tconst baseWithoutExt = ext ? schemaPath.slice(0, -ext.length) : schemaPath;\n\t\tif (\n\t\t\tfs.existsSync(baseWithoutExt) &&\n\t\t\tfs.statSync(baseWithoutExt).isDirectory() &&\n\t\t\tcheckStrict(baseWithoutExt)\n\t\t) {\n\t\t\treturn { layout: \"strict\", baseDir: baseWithoutExt };\n\t\t}\n\t\tif (checkStrict(parent)) {\n\t\t\treturn { layout: \"strict\", baseDir: parent };\n\t\t}\n\t\tif (\n\t\t\tpath.basename(parent) === \"internal\" &&\n\t\t\tcheckStrict(path.dirname(parent))\n\t\t) {\n\t\t\treturn { layout: \"strict\", baseDir: path.dirname(parent) };\n\t\t}\n\t\treturn { layout: \"simple\", baseDir: schemaPath };\n\t}\n\n\tif (layoutOption === \"strict\") {\n\t\t// Resolve baseDir for an explicit strict layout\n\t\tlet baseDir: string;\n\t\tconst resolved = resolveBaseDir(schemaPath);\n\t\tif (fs.existsSync(resolved) && fs.statSync(resolved).isDirectory()) {\n\t\t\tbaseDir = resolved;\n\t\t} else {\n\t\t\tconst parent = path.dirname(schemaPath);\n\t\t\tif (path.basename(parent) === \"internal\") {\n\t\t\t\tbaseDir = path.dirname(parent);\n\t\t\t} else {\n\t\t\t\tbaseDir = parent;\n\t\t\t}\n\t\t}\n\n\t\t// Validate that required split files exist\n\t\tconst clientPath = path.join(baseDir, \"client.ts\");\n\t\tconst sharedPath = path.join(baseDir, \"internal\", \"shared.ts\");\n\t\tif (!fs.existsSync(clientPath) || !fs.existsSync(sharedPath)) {\n\t\t\tthrow new Error(\n\t\t\t\t`[ArkEnv] Strict layout requires \"${clientPath}\" and \"${sharedPath}\" to exist. ` +\n\t\t\t\t\t`Ensure both files are present or remove the 'layout: \"strict\"' option to let ArkEnv auto-detect.`,\n\t\t\t);\n\t\t}\n\n\t\treturn { layout: \"strict\", baseDir };\n\t}\n\n\t// layoutOption === \"simple\"\n\treturn { layout: \"simple\", baseDir: schemaPath };\n}\n\nfunction findSchemaPath(): string | null {\n\tconst possiblePaths = [\n\t\tpath.join(process.cwd(), \"src\", \"env.ts\"),\n\t\tpath.join(process.cwd(), \"env.ts\"),\n\t];\n\tfor (const p of possiblePaths) {\n\t\tif (fs.existsSync(p)) return p;\n\t}\n\n\tconst possibleDirs = [\n\t\tpath.join(process.cwd(), \"src\", \"env\"),\n\t\tpath.join(process.cwd(), \"env\"),\n\t];\n\tfor (const d of possibleDirs) {\n\t\tif (\n\t\t\tfs.existsSync(d) &&\n\t\t\tfs.existsSync(path.join(d, \"internal\", \"shared.ts\")) &&\n\t\t\tfs.existsSync(path.join(d, \"client.ts\")) &&\n\t\t\tfs.existsSync(path.join(d, \"server.ts\"))\n\t\t) {\n\t\t\treturn d;\n\t\t}\n\t}\n\treturn null;\n}\n\n/**\n * Watch the schema file for changes and trigger codegen.\n *\n * @param schemaPath The absolute path to the schema file, or an array of paths to watch\n * @param outputPath The absolute path to the generated output file\n * @param layout The resolved layout to pass through to codegen on each change\n */\nfunction watchSchema(\n\tschemaPath: string | string[],\n\toutputPath: string,\n\tlayout?: \"simple\" | \"strict\",\n) {\n\tconst previousWatcher = globalThis.__arkenv_watcher__;\n\tif (previousWatcher && typeof previousWatcher.close === \"function\") {\n\t\tpreviousWatcher.close().catch((err: unknown) => {\n\t\t\tconst message = err instanceof Error ? err.message : String(err);\n\t\t\t// biome-ignore lint/suspicious/noConsole: watcher errors must be logged\n\t\t\tconsole.error(\n\t\t\t\t`[ArkEnv Watcher] Failed to close previous watcher: ${message}`,\n\t\t\t);\n\t\t});\n\t}\n\n\ttry {\n\t\tconst watcher = chokidarWatch(schemaPath, { ignoreInitial: true });\n\t\tglobalThis.__arkenv_watcher__ = watcher;\n\n\t\twatcher.on(\"change\", () => {\n\t\t\ttry {\n\t\t\t\tconst mainSchemaPath = Array.isArray(schemaPath)\n\t\t\t\t\t? schemaPath[0]\n\t\t\t\t\t: schemaPath;\n\t\t\t\trunCodegen(mainSchemaPath, outputPath, layout);\n\t\t\t} catch (err: unknown) {\n\t\t\t\tconst message = err instanceof Error ? err.message : String(err);\n\t\t\t\t// biome-ignore lint/suspicious/noConsole: watcher errors must be logged\n\t\t\t\tconsole.error(\n\t\t\t\t\t`[ArkEnv Watcher] Failed to regenerate env.gen.ts: ${message}`,\n\t\t\t\t);\n\t\t\t}\n\t\t});\n\t} catch (err: unknown) {\n\t\tconst message = err instanceof Error ? err.message : String(err);\n\t\t// biome-ignore lint/suspicious/noConsole: watcher errors must be logged\n\t\tconsole.error(\n\t\t\t`[ArkEnv Watcher] Failed to start watch on ${schemaPath}: ${message}`,\n\t\t);\n\t}\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 * @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?: \"simple\" | \"strict\",\n) {\n\tconst { layout: resolvedLayout, baseDir } = resolveLayout(\n\t\tschemaPath,\n\t\tlayoutOption,\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 clientKeys = extractClientKeys(clientContent);\n\t\tconst sharedKeys = extractSharedKeys(sharedContent);\n\n\t\tgeneratedCode = generateClientFactoryCode(clientKeys, sharedKeys);\n\t} else {\n\t\tconst fileContent = fs.readFileSync(schemaPath, \"utf-8\");\n\t\tconst { clientKeys, sharedKeys } = extractKeys(fileContent);\n\t\tgeneratedCode = generateFactoryCode(clientKeys, sharedKeys);\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\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} {\n\tconst clientKeys: string[] = [];\n\tconst sharedKeys: string[] = [];\n\n\t// Extract client block\n\tconst clientBlock = extractBlock(content, \"client\");\n\tif (clientBlock) {\n\t\tclientKeys.push(...parseBlockKeys(clientBlock));\n\t}\n\n\t// Extract shared block\n\tconst sharedBlock = extractBlock(content, \"shared\");\n\tif (sharedBlock) {\n\t\tsharedKeys.push(...parseBlockKeys(sharedBlock));\n\t}\n\n\treturn { clientKeys, sharedKeys };\n}\n\n/**\n * Extract a specific block from the schema content by name.\n *\n * @param content The schema file string content\n * @param blockName The name of the block to extract (e.g., 'client' or 'shared')\n * @returns The contents of the block, or null if not found\n */\nfunction extractBlock(content: string, blockName: string): string | null {\n\t// Find \"\\bblockName\\s*:\\s*{\" or \"\\bblockName\\s*:\\s*type({\"\n\tconst regex = new RegExp(\n\t\t`\\\\b${blockName}\\\\s*:\\\\s*(?:[a-zA-Z0-9_$.]+\\\\s*\\\\(\\\\s*)?\\\\{`,\n\t\t\"g\",\n\t);\n\tconst match = regex.exec(content);\n\tif (!match) return null;\n\n\tconst startIndex = regex.lastIndex;\n\tlet braceCount = 1;\n\tlet index = startIndex;\n\tlet inString: string | null = null;\n\tlet inComment: \"single\" | \"multi\" | null = null;\n\n\twhile (index < content.length && braceCount > 0) {\n\t\tconst char = content[index];\n\t\tconst nextChar = content[index + 1];\n\n\t\tif (inComment === \"single\") {\n\t\t\tif (char === \"\\n\" || char === \"\\r\") inComment = null;\n\t\t\tindex++;\n\t\t\tcontinue;\n\t\t}\n\t\tif (inComment === \"multi\") {\n\t\t\tif (char === \"*\" && nextChar === \"/\") {\n\t\t\t\tinComment = null;\n\t\t\t\tindex += 2;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tindex++;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (inString) {\n\t\t\tif (char === inString && content[index - 1] !== \"\\\\\") {\n\t\t\t\tinString = null;\n\t\t\t}\n\t\t\tindex++;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (char === \"/\" && nextChar === \"/\") {\n\t\t\tinComment = \"single\";\n\t\t\tindex += 2;\n\t\t\tcontinue;\n\t\t}\n\t\tif (char === \"/\" && nextChar === \"*\") {\n\t\t\tinComment = \"multi\";\n\t\t\tindex += 2;\n\t\t\tcontinue;\n\t\t}\n\t\tif (char === \"'\" || char === '\"' || char === \"`\") {\n\t\t\tinString = char;\n\t\t\tindex++;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (char === \"{\") {\n\t\t\tbraceCount++;\n\t\t} else if (char === \"}\") {\n\t\t\tbraceCount--;\n\t\t}\n\t\tindex++;\n\t}\n\n\tif (braceCount === 0) {\n\t\treturn content.slice(startIndex, index - 1);\n\t}\n\n\treturn null;\n}\n\n/**\n * Parse environment variable keys from a block's content.\n *\n * @param blockContent The raw content of the block\n * @returns An array of parsed environment variable keys\n */\nfunction parseBlockKeys(blockContent: string): string[] {\n\tconst keys: string[] = [];\n\tlet inString: string | null = null;\n\tlet inComment: \"single\" | \"multi\" | null = null;\n\tlet currentToken = \"\";\n\tlet lastStringContent = \"\";\n\tlet braceDepth = 0;\n\n\tfor (let i = 0; i < blockContent.length; i++) {\n\t\tconst char = blockContent[i];\n\t\tconst nextChar = blockContent[i + 1];\n\n\t\tif (inComment === \"single\") {\n\t\t\tif (char === \"\\n\" || char === \"\\r\") inComment = null;\n\t\t\tcontinue;\n\t\t}\n\t\tif (inComment === \"multi\") {\n\t\t\tif (char === \"*\" && nextChar === \"/\") {\n\t\t\t\tinComment = null;\n\t\t\t\ti++;\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (inString) {\n\t\t\tif (char === inString && blockContent[i - 1] !== \"\\\\\") {\n\t\t\t\tinString = null;\n\t\t\t\tlastStringContent = currentToken;\n\t\t\t\tcurrentToken = \"\";\n\t\t\t} else {\n\t\t\t\tcurrentToken += char;\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Start comments/strings\n\t\tif (char === \"/\" && nextChar === \"/\") {\n\t\t\tinComment = \"single\";\n\t\t\ti++;\n\t\t\tcontinue;\n\t\t}\n\t\tif (char === \"/\" && nextChar === \"*\") {\n\t\t\tinComment = \"multi\";\n\t\t\ti++;\n\t\t\tcontinue;\n\t\t}\n\t\tif (char === \"'\" || char === '\"' || char === \"`\") {\n\t\t\tinString = char;\n\t\t\tcurrentToken = \"\";\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (char === \"{\") {\n\t\t\tbraceDepth++;\n\t\t\tcurrentToken = \"\";\n\t\t\tlastStringContent = \"\";\n\t\t\tcontinue;\n\t\t}\n\t\tif (char === \"}\") {\n\t\t\tbraceDepth--;\n\t\t\tcurrentToken = \"\";\n\t\t\tlastStringContent = \"\";\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (char === \":\") {\n\t\t\tif (braceDepth === 0) {\n\t\t\t\tconst key = currentToken.trim() || lastStringContent.trim();\n\t\t\t\tif (key) {\n\t\t\t\t\tkeys.push(key);\n\t\t\t\t}\n\t\t\t}\n\t\t\tcurrentToken = \"\";\n\t\t\tlastStringContent = \"\";\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (/[a-zA-Z0-9_$]/.test(char)) {\n\t\t\tcurrentToken += char;\n\t\t} else if (char === \",\" || char === \"\\n\" || char === \"\\r\") {\n\t\t\tcurrentToken = \"\";\n\t\t\tlastStringContent = \"\";\n\t\t}\n\t}\n\n\treturn keys;\n}\n\n/**\n * Generate the TypeScript factory code for the tailored createEnv helper.\n *\n * @param clientKeys The client environment variable keys\n * @param sharedKeys The shared environment variable keys\n * @returns The generated TypeScript source code string\n */\nfunction generateFactoryCode(\n\tclientKeys: string[],\n\tsharedKeys: string[],\n): string {\n\tconst allKeys = Array.from(new Set([...clientKeys, ...sharedKeys]));\n\tconst runtimeEnvLines = allKeys\n\t\t.map((key) => `\\t\\t\\t${key}: process.env.${key},`)\n\t\t.join(\"\\n\");\n\n\treturn `/* eslint-disable */\n// prettier-ignore\n// biome-ignore format: auto-generated\n/**\n * @file env.gen.ts\n * @note This file is auto-generated by ArkEnv. DO NOT EDIT DIRECTLY.\n * @see https://arkenv.js.org\n */\n\nimport { createEnv as coreCreateEnv } from \"@arkenv/nextjs\";\nimport type { Infer } from \"@arkenv/nextjs\";\n\nexport { type } from \"@arkenv/nextjs\";\n\nexport function createEnv<\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}): Readonly<Infer<TServer & TClient & TShared>> {\n\treturn coreCreateEnv({\n\t\t...options,\n\t\truntimeEnv: {\n${runtimeEnvLines}\n\t\t},\n\t} as any) as any;\n}\n\nconst arkenv = createEnv;\nexport default arkenv;\n`;\n}\n\n/**\n * Generate the TypeScript factory code for the strict-layout `createEnv` 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 * @returns The generated TypeScript source code string\n */\nfunction generateClientFactoryCode(\n\tclientKeys: string[],\n\tsharedKeys: string[],\n): string {\n\tconst allKeys = Array.from(new Set([...clientKeys, ...sharedKeys]));\n\tconst runtimeEnvLines = allKeys\n\t\t.map((key) => `\\t\\t\\t${key}: process.env.${key},`)\n\t\t.join(\"\\n\");\n\n\treturn `/* eslint-disable */\n// prettier-ignore\n// biome-ignore format: auto-generated\n/**\n * @file env.gen.ts\n * @note This file is auto-generated by ArkEnv. DO NOT EDIT DIRECTLY.\n * @see https://arkenv.js.org\n */\n\nimport { createEnv as coreCreateEnv } from \"@arkenv/nextjs/client\";\n\nexport { type } from \"@arkenv/nextjs/client\";\n\nexport function createEnv<\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) {\n\treturn coreCreateEnv<TSchema, TExtends>(schema as any, {\n\t\t...options,\n\t\truntimeEnv: {\n${runtimeEnvLines}\n\t\t},\n\t} as any);\n}\n\nconst arkenv = createEnv;\nexport default arkenv;\n`;\n}\n\n/**\n * Extract env var keys from a strict-layout `client.ts` file.\n *\n * Locates the first `arkenv({...})` call and delegates to `parseBlockKeys`\n * to enumerate the keys defined in the schema object.\n *\n * @param content The source text of `client.ts`\n * @returns An array of env var key names found in the client schema\n */\nexport function extractClientKeys(content: string): string[] {\n\tconst block = extractClientBlock(content);\n\treturn block ? parseBlockKeys(block) : [];\n}\n\n/**\n * Extract env var keys from a strict-layout `internal/shared.ts` file.\n *\n * Locates the `SharedSchema = ...({...})` assignment and delegates to\n * `parseBlockKeys` to enumerate the keys defined in the schema object.\n *\n * @param content The source text of `internal/shared.ts`\n * @returns An array of env var key names found in the shared schema\n */\nexport function extractSharedKeys(content: string): string[] {\n\tconst block = extractSharedBlock(content);\n\treturn block ? parseBlockKeys(block) : [];\n}\n\n/**\n * Extract the schema object body from a strict-layout `client.ts` file.\n *\n * Matches the first `arkenv(...)` call, then performs brace-balanced\n * traversal while respecting strings and comments to find the boundaries\n * of the first argument object.\n *\n * @param content The source text of `client.ts`\n * @returns The raw text inside the first `{...}` argument, or `null` if not found\n */\nfunction extractClientBlock(content: string): string | null {\n\tconst regex = /\\barkenv\\s*\\(\\s*(?:[a-zA-Z0-9_$.]+\\s*\\(\\s*)*\\{/g;\n\tconst match = regex.exec(content);\n\tif (!match) return null;\n\n\tconst startIndex = regex.lastIndex;\n\tlet braceCount = 1;\n\tlet index = startIndex;\n\tlet inString: string | null = null;\n\tlet inComment: \"single\" | \"multi\" | null = null;\n\n\twhile (index < content.length && braceCount > 0) {\n\t\tconst char = content[index];\n\t\tconst nextChar = content[index + 1];\n\n\t\tif (inComment === \"single\") {\n\t\t\tif (char === \"\\n\" || char === \"\\r\") inComment = null;\n\t\t\tindex++;\n\t\t\tcontinue;\n\t\t}\n\t\tif (inComment === \"multi\") {\n\t\t\tif (char === \"*\" && nextChar === \"/\") {\n\t\t\t\tinComment = null;\n\t\t\t\tindex += 2;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tindex++;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (inString) {\n\t\t\tif (char === inString && content[index - 1] !== \"\\\\\") {\n\t\t\t\tinString = null;\n\t\t\t}\n\t\t\tindex++;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (char === \"/\" && nextChar === \"/\") {\n\t\t\tinComment = \"single\";\n\t\t\tindex += 2;\n\t\t\tcontinue;\n\t\t}\n\t\tif (char === \"/\" && nextChar === \"*\") {\n\t\t\tinComment = \"multi\";\n\t\t\tindex += 2;\n\t\t\tcontinue;\n\t\t}\n\t\tif (char === \"'\" || char === '\"' || char === \"`\") {\n\t\t\tinString = char;\n\t\t\tindex++;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (char === \"{\") {\n\t\t\tbraceCount++;\n\t\t} else if (char === \"}\") {\n\t\t\tbraceCount--;\n\t\t}\n\t\tindex++;\n\t}\n\n\tif (braceCount === 0) {\n\t\treturn content.slice(startIndex, index - 1);\n\t}\n\n\treturn null;\n}\n\n/**\n * Extract the schema object body from a strict-layout `internal/shared.ts` file.\n *\n * Matches the `SharedSchema = ...({...})` assignment, then performs\n * brace-balanced traversal while respecting strings and comments to find\n * the boundaries of the schema object.\n *\n * @param content The source text of `internal/shared.ts`\n * @returns The raw text inside the `{...}` schema object, or `null` if not found\n */\nfunction extractSharedBlock(content: string): string | null {\n\tconst regex = /\\bSharedSchema\\s*=\\s*(?:[a-zA-Z0-9_$.]+\\s*\\(\\s*)*\\{/g;\n\tconst match = regex.exec(content);\n\tif (!match) return null;\n\n\tconst startIndex = regex.lastIndex;\n\tlet braceCount = 1;\n\tlet index = startIndex;\n\tlet inString: string | null = null;\n\tlet inComment: \"single\" | \"multi\" | null = null;\n\n\twhile (index < content.length && braceCount > 0) {\n\t\tconst char = content[index];\n\t\tconst nextChar = content[index + 1];\n\n\t\tif (inComment === \"single\") {\n\t\t\tif (char === \"\\n\" || char === \"\\r\") inComment = null;\n\t\t\tindex++;\n\t\t\tcontinue;\n\t\t}\n\t\tif (inComment === \"multi\") {\n\t\t\tif (char === \"*\" && nextChar === \"/\") {\n\t\t\t\tinComment = null;\n\t\t\t\tindex += 2;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tindex++;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (inString) {\n\t\t\tif (char === inString && content[index - 1] !== \"\\\\\") {\n\t\t\t\tinString = null;\n\t\t\t}\n\t\t\tindex++;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (char === \"/\" && nextChar === \"/\") {\n\t\t\tinComment = \"single\";\n\t\t\tindex += 2;\n\t\t\tcontinue;\n\t\t}\n\t\tif (char === \"/\" && nextChar === \"*\") {\n\t\t\tinComment = \"multi\";\n\t\t\tindex += 2;\n\t\t\tcontinue;\n\t\t}\n\t\tif (char === \"'\" || char === '\"' || char === \"`\") {\n\t\t\tinString = char;\n\t\t\tindex++;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (char === \"{\") {\n\t\t\tbraceCount++;\n\t\t} else if (char === \"}\") {\n\t\t\tbraceCount--;\n\t\t}\n\t\tindex++;\n\t}\n\n\tif (braceCount === 0) {\n\t\treturn content.slice(startIndex, index - 1);\n\t}\n\n\treturn null;\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","names":["createEnvInternal","arkenv"],"sources":["../src/index.ts"],"sourcesContent":["import type { SchemaShape } from \"@repo/types\";\nimport type { EnvSchema, Infer } from \"arkenv\";\nimport { createEnvInternal } from \"./create-env\";\n\n/**\n * Create a validated, type-safe environment configuration for Next.js applications (Client-side / SSR entry point).\n *\n * @param options The environment validation configuration options\n * @returns A validated, readonly environment variables object wrapped in a security proxy\n * @throws An error if any client-side variable is not prefixed with `NEXT_PUBLIC_`\n * @throws An error if any client or shared variable is missing from `runtimeEnv`\n * @deprecated Use the codegen workflow by wrapping your config with `withArkEnv` from `@arkenv/nextjs/config` and importing `createEnv` from `./env.gen.ts`.\n */\nexport function createEnv<\n\tconst TServer extends SchemaShape = {},\n\tconst TClient extends SchemaShape = {},\n\tconst TShared extends SchemaShape = {},\n>(options: {\n\tserver?: EnvSchema<TServer>;\n\tclient?: EnvSchema<TClient> & {\n\t\t[K in keyof TClient]: K extends `NEXT_PUBLIC_${string}` ? unknown : never;\n\t};\n\tshared?: EnvSchema<TShared>;\n\truntimeEnv: Record<keyof TClient | keyof TShared, unknown> &\n\t\tRecord<string, unknown>;\n}): Readonly<Infer<TServer & TClient & TShared>> {\n\ttype ReturnType = Readonly<Infer<TServer & TClient & TShared>>;\n\treturn createEnvInternal(options, false) as ReturnType;\n}\n\nexport type { Infer } from \"arkenv\";\nexport { type } from \"arkenv\";\n\n/**\n * ArkEnv's Next.js integration export, an alias for {@link createEnv}\n *\n * {@link https://arkenv.js.org | ArkEnv} is a typesafe environment variables validator from editor to runtime.\n *\n * @deprecated Use the codegen workflow by wrapping your config with `withArkEnv` from `@arkenv/nextjs/config` and importing `createEnv` from `./env.gen.ts`.\n */\nconst arkenv = createEnv;\nexport default arkenv;\n"],"mappings":"4LAaA,SAAgB,EAId,EAQ+C,CAEhD,OAAOA,EAAAA,EAAkB,EAAS,GAAM,CAazC,MAAMC,EAAS"}
1
+ {"version":3,"file":"index.cjs","names":["createEnvInternal","arkenv"],"sources":["../src/index.ts"],"sourcesContent":["import type { SchemaShape } from \"@repo/types\";\nimport type { EnvSchema, Infer } from \"arkenv\";\nimport { createEnvInternal } from \"./create-env\";\n\n/**\n * Create a validated, type-safe environment configuration for Next.js applications (Client-side / SSR entry point).\n *\n * @param options The environment validation configuration options\n * @returns A validated, readonly environment variables object wrapped in a security proxy\n * @throws An error if any client-side variable is not prefixed with `NEXT_PUBLIC_`\n * @throws An error if any client or shared variable is missing from `runtimeEnv`\n */\nexport function createEnv<\n\tconst TServer extends SchemaShape = {},\n\tconst TClient extends SchemaShape = {},\n\tconst TShared extends SchemaShape = {},\n>(options: {\n\tserver?: EnvSchema<TServer>;\n\tclient?: EnvSchema<TClient> & {\n\t\t[K in keyof TClient]: K extends `NEXT_PUBLIC_${string}` ? unknown : never;\n\t};\n\tshared?: EnvSchema<TShared>;\n\truntimeEnv: Record<keyof TClient | keyof TShared, unknown> &\n\t\tRecord<string, unknown>;\n}): Readonly<Infer<TServer & TClient & TShared>> {\n\ttype ReturnType = Readonly<Infer<TServer & TClient & TShared>>;\n\treturn createEnvInternal(options, false) as ReturnType;\n}\n\nexport type { Infer } from \"arkenv\";\nexport { type } from \"arkenv\";\n\n/**\n * ArkEnv's Next.js integration export, an alias for {@link createEnv}\n *\n * {@link https://arkenv.js.org | ArkEnv} is a typesafe environment variables validator from editor to runtime.\n */\nconst arkenv = createEnv;\nexport default arkenv;\n"],"mappings":"4LAYA,SAAgB,EAId,EAQ+C,CAEhD,OAAOA,EAAAA,EAAkB,EAAS,GAAM,CAWzC,MAAMC,EAAS"}
package/dist/index.d.cts CHANGED
@@ -9,7 +9,6 @@ import { EnvSchema, Infer, Infer as Infer$1, type } from "arkenv";
9
9
  * @returns A validated, readonly environment variables object wrapped in a security proxy
10
10
  * @throws An error if any client-side variable is not prefixed with `NEXT_PUBLIC_`
11
11
  * @throws An error if any client or shared variable is missing from `runtimeEnv`
12
- * @deprecated Use the codegen workflow by wrapping your config with `withArkEnv` from `@arkenv/nextjs/config` and importing `createEnv` from `./env.gen.ts`.
13
12
  */
14
13
  declare function createEnv<const TServer extends SchemaShape = {}, const TClient extends SchemaShape = {}, const TShared extends SchemaShape = {}>(options: {
15
14
  server?: EnvSchema<TServer>;
@@ -21,8 +20,6 @@ declare function createEnv<const TServer extends SchemaShape = {}, const TClient
21
20
  * ArkEnv's Next.js integration export, an alias for {@link createEnv}
22
21
  *
23
22
  * {@link https://arkenv.js.org | ArkEnv} is a typesafe environment variables validator from editor to runtime.
24
- *
25
- * @deprecated Use the codegen workflow by wrapping your config with `withArkEnv` from `@arkenv/nextjs/config` and importing `createEnv` from `./env.gen.ts`.
26
23
  */
27
24
  declare const arkenv: typeof createEnv;
28
25
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.cts","names":[],"sources":["../src/index.ts"],"mappings":";;;;;;AAaA;;;;;;;iBAAgB,SAAA,uBACO,WAAA,6BACA,WAAA,6BACA,WAAA,MAAA,CACrB,OAAA;EACD,MAAA,GAAS,SAAA,CAAU,OAAA;EACnB,MAAA,GAAS,SAAA,CAAU,OAAA,kBACN,OAAA,GAAU,CAAA;EAEvB,MAAA,GAAS,SAAA,CAAU,OAAA;EACnB,UAAA,EAAY,MAAA,OAAa,OAAA,SAAgB,OAAA,aACxC,MAAA;AAAA,IACE,QAAA,CAAS,OAAA,CAAM,OAAA,GAAU,OAAA,GAAU,OAAA;;;;;;;;cAejC,MAAA,SAAM,SAAA"}
1
+ {"version":3,"file":"index.d.cts","names":[],"sources":["../src/index.ts"],"mappings":";;;;;;AAYA;;;;;;iBAAgB,SAAA,uBACO,WAAA,6BACA,WAAA,6BACA,WAAA,MAAA,CACrB,OAAA;EACD,MAAA,GAAS,SAAA,CAAU,OAAA;EACnB,MAAA,GAAS,SAAA,CAAU,OAAA,kBACN,OAAA,GAAU,CAAA;EAEvB,MAAA,GAAS,SAAA,CAAU,OAAA;EACnB,UAAA,EAAY,MAAA,OAAa,OAAA,SAAgB,OAAA,aACxC,MAAA;AAAA,IACE,QAAA,CAAS,OAAA,CAAM,OAAA,GAAU,OAAA,GAAU,OAAA;;;;;;cAajC,MAAA,SAAM,SAAA"}
package/dist/index.d.ts CHANGED
@@ -9,7 +9,6 @@ import { EnvSchema, Infer, Infer as Infer$1, type } from "arkenv";
9
9
  * @returns A validated, readonly environment variables object wrapped in a security proxy
10
10
  * @throws An error if any client-side variable is not prefixed with `NEXT_PUBLIC_`
11
11
  * @throws An error if any client or shared variable is missing from `runtimeEnv`
12
- * @deprecated Use the codegen workflow by wrapping your config with `withArkEnv` from `@arkenv/nextjs/config` and importing `createEnv` from `./env.gen.ts`.
13
12
  */
14
13
  declare function createEnv<const TServer extends SchemaShape = {}, const TClient extends SchemaShape = {}, const TShared extends SchemaShape = {}>(options: {
15
14
  server?: EnvSchema<TServer>;
@@ -21,8 +20,6 @@ declare function createEnv<const TServer extends SchemaShape = {}, const TClient
21
20
  * ArkEnv's Next.js integration export, an alias for {@link createEnv}
22
21
  *
23
22
  * {@link https://arkenv.js.org | ArkEnv} is a typesafe environment variables validator from editor to runtime.
24
- *
25
- * @deprecated Use the codegen workflow by wrapping your config with `withArkEnv` from `@arkenv/nextjs/config` and importing `createEnv` from `./env.gen.ts`.
26
23
  */
27
24
  declare const arkenv: typeof createEnv;
28
25
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../src/index.ts"],"mappings":";;;;;;AAaA;;;;;;;iBAAgB,SAAA,uBACO,WAAA,6BACA,WAAA,6BACA,WAAA,MAAA,CACrB,OAAA;EACD,MAAA,GAAS,SAAA,CAAU,OAAA;EACnB,MAAA,GAAS,SAAA,CAAU,OAAA,kBACN,OAAA,GAAU,CAAA;EAEvB,MAAA,GAAS,SAAA,CAAU,OAAA;EACnB,UAAA,EAAY,MAAA,OAAa,OAAA,SAAgB,OAAA,aACxC,MAAA;AAAA,IACE,QAAA,CAAS,OAAA,CAAM,OAAA,GAAU,OAAA,GAAU,OAAA;;;;;;;;cAejC,MAAA,SAAM,SAAA"}
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../src/index.ts"],"mappings":";;;;;;AAYA;;;;;;iBAAgB,SAAA,uBACO,WAAA,6BACA,WAAA,6BACA,WAAA,MAAA,CACrB,OAAA;EACD,MAAA,GAAS,SAAA,CAAU,OAAA;EACnB,MAAA,GAAS,SAAA,CAAU,OAAA,kBACN,OAAA,GAAU,CAAA;EAEvB,MAAA,GAAS,SAAA,CAAU,OAAA;EACnB,UAAA,EAAY,MAAA,OAAa,OAAA,SAAgB,OAAA,aACxC,MAAA;AAAA,IACE,QAAA,CAAS,OAAA,CAAM,OAAA,GAAU,OAAA,GAAU,OAAA;;;;;;cAajC,MAAA,SAAM,SAAA"}
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../src/index.ts"],"sourcesContent":["import type { SchemaShape } from \"@repo/types\";\nimport type { EnvSchema, Infer } from \"arkenv\";\nimport { createEnvInternal } from \"./create-env\";\n\n/**\n * Create a validated, type-safe environment configuration for Next.js applications (Client-side / SSR entry point).\n *\n * @param options The environment validation configuration options\n * @returns A validated, readonly environment variables object wrapped in a security proxy\n * @throws An error if any client-side variable is not prefixed with `NEXT_PUBLIC_`\n * @throws An error if any client or shared variable is missing from `runtimeEnv`\n * @deprecated Use the codegen workflow by wrapping your config with `withArkEnv` from `@arkenv/nextjs/config` and importing `createEnv` from `./env.gen.ts`.\n */\nexport function createEnv<\n\tconst TServer extends SchemaShape = {},\n\tconst TClient extends SchemaShape = {},\n\tconst TShared extends SchemaShape = {},\n>(options: {\n\tserver?: EnvSchema<TServer>;\n\tclient?: EnvSchema<TClient> & {\n\t\t[K in keyof TClient]: K extends `NEXT_PUBLIC_${string}` ? unknown : never;\n\t};\n\tshared?: EnvSchema<TShared>;\n\truntimeEnv: Record<keyof TClient | keyof TShared, unknown> &\n\t\tRecord<string, unknown>;\n}): Readonly<Infer<TServer & TClient & TShared>> {\n\ttype ReturnType = Readonly<Infer<TServer & TClient & TShared>>;\n\treturn createEnvInternal(options, false) as ReturnType;\n}\n\nexport type { Infer } from \"arkenv\";\nexport { type } from \"arkenv\";\n\n/**\n * ArkEnv's Next.js integration export, an alias for {@link createEnv}\n *\n * {@link https://arkenv.js.org | ArkEnv} is a typesafe environment variables validator from editor to runtime.\n *\n * @deprecated Use the codegen workflow by wrapping your config with `withArkEnv` from `@arkenv/nextjs/config` and importing `createEnv` from `./env.gen.ts`.\n */\nconst arkenv = createEnv;\nexport default arkenv;\n"],"mappings":"2EAaA,SAAgB,EAId,EAQ+C,CAEhD,OAAO,EAAkB,EAAS,GAAM,CAazC,MAAM,EAAS"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../src/index.ts"],"sourcesContent":["import type { SchemaShape } from \"@repo/types\";\nimport type { EnvSchema, Infer } from \"arkenv\";\nimport { createEnvInternal } from \"./create-env\";\n\n/**\n * Create a validated, type-safe environment configuration for Next.js applications (Client-side / SSR entry point).\n *\n * @param options The environment validation configuration options\n * @returns A validated, readonly environment variables object wrapped in a security proxy\n * @throws An error if any client-side variable is not prefixed with `NEXT_PUBLIC_`\n * @throws An error if any client or shared variable is missing from `runtimeEnv`\n */\nexport function createEnv<\n\tconst TServer extends SchemaShape = {},\n\tconst TClient extends SchemaShape = {},\n\tconst TShared extends SchemaShape = {},\n>(options: {\n\tserver?: EnvSchema<TServer>;\n\tclient?: EnvSchema<TClient> & {\n\t\t[K in keyof TClient]: K extends `NEXT_PUBLIC_${string}` ? unknown : never;\n\t};\n\tshared?: EnvSchema<TShared>;\n\truntimeEnv: Record<keyof TClient | keyof TShared, unknown> &\n\t\tRecord<string, unknown>;\n}): Readonly<Infer<TServer & TClient & TShared>> {\n\ttype ReturnType = Readonly<Infer<TServer & TClient & TShared>>;\n\treturn createEnvInternal(options, false) as ReturnType;\n}\n\nexport type { Infer } from \"arkenv\";\nexport { type } from \"arkenv\";\n\n/**\n * ArkEnv's Next.js integration export, an alias for {@link createEnv}\n *\n * {@link https://arkenv.js.org | ArkEnv} is a typesafe environment variables validator from editor to runtime.\n */\nconst arkenv = createEnv;\nexport default arkenv;\n"],"mappings":"2EAYA,SAAgB,EAId,EAQ+C,CAEhD,OAAO,EAAkB,EAAS,GAAM,CAWzC,MAAM,EAAS"}
@@ -1 +1 @@
1
- {"version":3,"file":"react-server.cjs","names":["createEnvInternal","arkenv"],"sources":["../src/react-server.ts"],"sourcesContent":["import type { SchemaShape } from \"@repo/types\";\nimport type { EnvSchema, Infer } from \"arkenv\";\nimport { createEnvInternal } from \"./create-env\";\n\n/**\n * Create a validated, type-safe environment configuration for Next.js applications (Server-side RSC entry point).\n *\n * @param options The environment validation configuration options\n * @returns A validated, readonly environment variables object wrapped in a security proxy\n * @throws An error if any client-side variable is not prefixed with `NEXT_PUBLIC_`\n * @throws An error if any client or shared variable is missing from `runtimeEnv`\n * @deprecated Use the codegen workflow by wrapping your config with `withArkEnv` from `@arkenv/nextjs/config` and importing `createEnv` from `./env.gen.ts`.\n */\nexport function createEnv<\n\tconst TServer extends SchemaShape = {},\n\tconst TClient extends SchemaShape = {},\n\tconst TShared extends SchemaShape = {},\n>(options: {\n\tserver?: EnvSchema<TServer>;\n\tclient?: EnvSchema<TClient> & {\n\t\t[K in keyof TClient]: K extends `NEXT_PUBLIC_${string}` ? unknown : never;\n\t};\n\tshared?: EnvSchema<TShared>;\n\truntimeEnv: Record<keyof TClient | keyof TShared, unknown> &\n\t\tRecord<string, unknown>;\n}): Readonly<Infer<TServer & TClient & TShared>> {\n\ttype ReturnType = Readonly<Infer<TServer & TClient & TShared>>;\n\treturn createEnvInternal(options, true) as ReturnType;\n}\n\nexport type { Infer } from \"arkenv\";\nexport { type } from \"arkenv\";\n\n/**\n * ArkEnv's Next.js integration export, an alias for {@link createEnv}\n *\n * {@link https://arkenv.js.org | ArkEnv} is a typesafe environment variables validator from editor to runtime.\n *\n * @deprecated Use the codegen workflow by wrapping your config with `withArkEnv` from `@arkenv/nextjs/config` and importing `createEnv` from `./env.gen.ts`.\n */\nconst arkenv = createEnv;\nexport default arkenv;\n"],"mappings":"4LAaA,SAAgB,EAId,EAQ+C,CAEhD,OAAOA,EAAAA,EAAkB,EAAS,GAAK,CAaxC,MAAMC,EAAS"}
1
+ {"version":3,"file":"react-server.cjs","names":["createEnvInternal","arkenv"],"sources":["../src/react-server.ts"],"sourcesContent":["import type { SchemaShape } from \"@repo/types\";\nimport type { EnvSchema, Infer } from \"arkenv\";\nimport { createEnvInternal } from \"./create-env\";\n\n/**\n * Create a validated, type-safe environment configuration for Next.js applications (Server-side RSC entry point).\n *\n * @param options The environment validation configuration options\n * @returns A validated, readonly environment variables object wrapped in a security proxy\n * @throws An error if any client-side variable is not prefixed with `NEXT_PUBLIC_`\n * @throws An error if any client or shared variable is missing from `runtimeEnv`\n */\nexport function createEnv<\n\tconst TServer extends SchemaShape = {},\n\tconst TClient extends SchemaShape = {},\n\tconst TShared extends SchemaShape = {},\n>(options: {\n\tserver?: EnvSchema<TServer>;\n\tclient?: EnvSchema<TClient> & {\n\t\t[K in keyof TClient]: K extends `NEXT_PUBLIC_${string}` ? unknown : never;\n\t};\n\tshared?: EnvSchema<TShared>;\n\truntimeEnv: Record<keyof TClient | keyof TShared, unknown> &\n\t\tRecord<string, unknown>;\n}): Readonly<Infer<TServer & TClient & TShared>> {\n\ttype ReturnType = Readonly<Infer<TServer & TClient & TShared>>;\n\treturn createEnvInternal(options, true) as ReturnType;\n}\n\nexport type { Infer } from \"arkenv\";\nexport { type } from \"arkenv\";\n\n/**\n * ArkEnv's Next.js integration export, an alias for {@link createEnv}\n *\n * {@link https://arkenv.js.org | ArkEnv} is a typesafe environment variables validator from editor to runtime.\n */\nconst arkenv = createEnv;\nexport default arkenv;\n"],"mappings":"4LAYA,SAAgB,EAId,EAQ+C,CAEhD,OAAOA,EAAAA,EAAkB,EAAS,GAAK,CAWxC,MAAMC,EAAS"}
@@ -9,7 +9,6 @@ import { EnvSchema, Infer, Infer as Infer$1, type } from "arkenv";
9
9
  * @returns A validated, readonly environment variables object wrapped in a security proxy
10
10
  * @throws An error if any client-side variable is not prefixed with `NEXT_PUBLIC_`
11
11
  * @throws An error if any client or shared variable is missing from `runtimeEnv`
12
- * @deprecated Use the codegen workflow by wrapping your config with `withArkEnv` from `@arkenv/nextjs/config` and importing `createEnv` from `./env.gen.ts`.
13
12
  */
14
13
  declare function createEnv<const TServer extends SchemaShape = {}, const TClient extends SchemaShape = {}, const TShared extends SchemaShape = {}>(options: {
15
14
  server?: EnvSchema<TServer>;
@@ -21,8 +20,6 @@ declare function createEnv<const TServer extends SchemaShape = {}, const TClient
21
20
  * ArkEnv's Next.js integration export, an alias for {@link createEnv}
22
21
  *
23
22
  * {@link https://arkenv.js.org | ArkEnv} is a typesafe environment variables validator from editor to runtime.
24
- *
25
- * @deprecated Use the codegen workflow by wrapping your config with `withArkEnv` from `@arkenv/nextjs/config` and importing `createEnv` from `./env.gen.ts`.
26
23
  */
27
24
  declare const arkenv: typeof createEnv;
28
25
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"react-server.d.cts","names":[],"sources":["../src/react-server.ts"],"mappings":";;;;;;AAaA;;;;;;;iBAAgB,SAAA,uBACO,WAAA,6BACA,WAAA,6BACA,WAAA,MAAA,CACrB,OAAA;EACD,MAAA,GAAS,SAAA,CAAU,OAAA;EACnB,MAAA,GAAS,SAAA,CAAU,OAAA,kBACN,OAAA,GAAU,CAAA;EAEvB,MAAA,GAAS,SAAA,CAAU,OAAA;EACnB,UAAA,EAAY,MAAA,OAAa,OAAA,SAAgB,OAAA,aACxC,MAAA;AAAA,IACE,QAAA,CAAS,OAAA,CAAM,OAAA,GAAU,OAAA,GAAU,OAAA;;;;;;;;cAejC,MAAA,SAAM,SAAA"}
1
+ {"version":3,"file":"react-server.d.cts","names":[],"sources":["../src/react-server.ts"],"mappings":";;;;;;AAYA;;;;;;iBAAgB,SAAA,uBACO,WAAA,6BACA,WAAA,6BACA,WAAA,MAAA,CACrB,OAAA;EACD,MAAA,GAAS,SAAA,CAAU,OAAA;EACnB,MAAA,GAAS,SAAA,CAAU,OAAA,kBACN,OAAA,GAAU,CAAA;EAEvB,MAAA,GAAS,SAAA,CAAU,OAAA;EACnB,UAAA,EAAY,MAAA,OAAa,OAAA,SAAgB,OAAA,aACxC,MAAA;AAAA,IACE,QAAA,CAAS,OAAA,CAAM,OAAA,GAAU,OAAA,GAAU,OAAA;;;;;;cAajC,MAAA,SAAM,SAAA"}
@@ -9,7 +9,6 @@ import { EnvSchema, Infer, Infer as Infer$1, type } from "arkenv";
9
9
  * @returns A validated, readonly environment variables object wrapped in a security proxy
10
10
  * @throws An error if any client-side variable is not prefixed with `NEXT_PUBLIC_`
11
11
  * @throws An error if any client or shared variable is missing from `runtimeEnv`
12
- * @deprecated Use the codegen workflow by wrapping your config with `withArkEnv` from `@arkenv/nextjs/config` and importing `createEnv` from `./env.gen.ts`.
13
12
  */
14
13
  declare function createEnv<const TServer extends SchemaShape = {}, const TClient extends SchemaShape = {}, const TShared extends SchemaShape = {}>(options: {
15
14
  server?: EnvSchema<TServer>;
@@ -21,8 +20,6 @@ declare function createEnv<const TServer extends SchemaShape = {}, const TClient
21
20
  * ArkEnv's Next.js integration export, an alias for {@link createEnv}
22
21
  *
23
22
  * {@link https://arkenv.js.org | ArkEnv} is a typesafe environment variables validator from editor to runtime.
24
- *
25
- * @deprecated Use the codegen workflow by wrapping your config with `withArkEnv` from `@arkenv/nextjs/config` and importing `createEnv` from `./env.gen.ts`.
26
23
  */
27
24
  declare const arkenv: typeof createEnv;
28
25
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"react-server.d.ts","names":[],"sources":["../src/react-server.ts"],"mappings":";;;;;;AAaA;;;;;;;iBAAgB,SAAA,uBACO,WAAA,6BACA,WAAA,6BACA,WAAA,MAAA,CACrB,OAAA;EACD,MAAA,GAAS,SAAA,CAAU,OAAA;EACnB,MAAA,GAAS,SAAA,CAAU,OAAA,kBACN,OAAA,GAAU,CAAA;EAEvB,MAAA,GAAS,SAAA,CAAU,OAAA;EACnB,UAAA,EAAY,MAAA,OAAa,OAAA,SAAgB,OAAA,aACxC,MAAA;AAAA,IACE,QAAA,CAAS,OAAA,CAAM,OAAA,GAAU,OAAA,GAAU,OAAA;;;;;;;;cAejC,MAAA,SAAM,SAAA"}
1
+ {"version":3,"file":"react-server.d.ts","names":[],"sources":["../src/react-server.ts"],"mappings":";;;;;;AAYA;;;;;;iBAAgB,SAAA,uBACO,WAAA,6BACA,WAAA,6BACA,WAAA,MAAA,CACrB,OAAA;EACD,MAAA,GAAS,SAAA,CAAU,OAAA;EACnB,MAAA,GAAS,SAAA,CAAU,OAAA,kBACN,OAAA,GAAU,CAAA;EAEvB,MAAA,GAAS,SAAA,CAAU,OAAA;EACnB,UAAA,EAAY,MAAA,OAAa,OAAA,SAAgB,OAAA,aACxC,MAAA;AAAA,IACE,QAAA,CAAS,OAAA,CAAM,OAAA,GAAU,OAAA,GAAU,OAAA;;;;;;cAajC,MAAA,SAAM,SAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"react-server.js","names":[],"sources":["../src/react-server.ts"],"sourcesContent":["import type { SchemaShape } from \"@repo/types\";\nimport type { EnvSchema, Infer } from \"arkenv\";\nimport { createEnvInternal } from \"./create-env\";\n\n/**\n * Create a validated, type-safe environment configuration for Next.js applications (Server-side RSC entry point).\n *\n * @param options The environment validation configuration options\n * @returns A validated, readonly environment variables object wrapped in a security proxy\n * @throws An error if any client-side variable is not prefixed with `NEXT_PUBLIC_`\n * @throws An error if any client or shared variable is missing from `runtimeEnv`\n * @deprecated Use the codegen workflow by wrapping your config with `withArkEnv` from `@arkenv/nextjs/config` and importing `createEnv` from `./env.gen.ts`.\n */\nexport function createEnv<\n\tconst TServer extends SchemaShape = {},\n\tconst TClient extends SchemaShape = {},\n\tconst TShared extends SchemaShape = {},\n>(options: {\n\tserver?: EnvSchema<TServer>;\n\tclient?: EnvSchema<TClient> & {\n\t\t[K in keyof TClient]: K extends `NEXT_PUBLIC_${string}` ? unknown : never;\n\t};\n\tshared?: EnvSchema<TShared>;\n\truntimeEnv: Record<keyof TClient | keyof TShared, unknown> &\n\t\tRecord<string, unknown>;\n}): Readonly<Infer<TServer & TClient & TShared>> {\n\ttype ReturnType = Readonly<Infer<TServer & TClient & TShared>>;\n\treturn createEnvInternal(options, true) as ReturnType;\n}\n\nexport type { Infer } from \"arkenv\";\nexport { type } from \"arkenv\";\n\n/**\n * ArkEnv's Next.js integration export, an alias for {@link createEnv}\n *\n * {@link https://arkenv.js.org | ArkEnv} is a typesafe environment variables validator from editor to runtime.\n *\n * @deprecated Use the codegen workflow by wrapping your config with `withArkEnv` from `@arkenv/nextjs/config` and importing `createEnv` from `./env.gen.ts`.\n */\nconst arkenv = createEnv;\nexport default arkenv;\n"],"mappings":"2EAaA,SAAgB,EAId,EAQ+C,CAEhD,OAAO,EAAkB,EAAS,GAAK,CAaxC,MAAM,EAAS"}
1
+ {"version":3,"file":"react-server.js","names":[],"sources":["../src/react-server.ts"],"sourcesContent":["import type { SchemaShape } from \"@repo/types\";\nimport type { EnvSchema, Infer } from \"arkenv\";\nimport { createEnvInternal } from \"./create-env\";\n\n/**\n * Create a validated, type-safe environment configuration for Next.js applications (Server-side RSC entry point).\n *\n * @param options The environment validation configuration options\n * @returns A validated, readonly environment variables object wrapped in a security proxy\n * @throws An error if any client-side variable is not prefixed with `NEXT_PUBLIC_`\n * @throws An error if any client or shared variable is missing from `runtimeEnv`\n */\nexport function createEnv<\n\tconst TServer extends SchemaShape = {},\n\tconst TClient extends SchemaShape = {},\n\tconst TShared extends SchemaShape = {},\n>(options: {\n\tserver?: EnvSchema<TServer>;\n\tclient?: EnvSchema<TClient> & {\n\t\t[K in keyof TClient]: K extends `NEXT_PUBLIC_${string}` ? unknown : never;\n\t};\n\tshared?: EnvSchema<TShared>;\n\truntimeEnv: Record<keyof TClient | keyof TShared, unknown> &\n\t\tRecord<string, unknown>;\n}): Readonly<Infer<TServer & TClient & TShared>> {\n\ttype ReturnType = Readonly<Infer<TServer & TClient & TShared>>;\n\treturn createEnvInternal(options, true) as ReturnType;\n}\n\nexport type { Infer } from \"arkenv\";\nexport { type } from \"arkenv\";\n\n/**\n * ArkEnv's Next.js integration export, an alias for {@link createEnv}\n *\n * {@link https://arkenv.js.org | ArkEnv} is a typesafe environment variables validator from editor to runtime.\n */\nconst arkenv = createEnv;\nexport default arkenv;\n"],"mappings":"2EAYA,SAAgB,EAId,EAQ+C,CAEhD,OAAO,EAAkB,EAAS,GAAK,CAWxC,MAAM,EAAS"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@arkenv/nextjs",
3
- "version": "0.0.5",
3
+ "version": "0.0.7",
4
4
  "author": "Yam Borodetsky <yam@yam.codes>",
5
5
  "repository": {
6
6
  "type": "git",