@@ -375,21 +375,15 @@ export function extractKeys(content: string): {
375375 if ( args . optionsArg ) {
376376 const sharedMatch = args . optionsArg . match ( / s h a r e d \s * : \s * \[ ( [ \s \S ] * ?) \] / ) ;
377377 if ( sharedMatch ) {
378- const arrayContent = sharedMatch [ 1 ] ;
379- const stringRegex =
380- / (?: " ( [ ^ " \\ ] * (?: \\ .[ ^ " \\ ] * ) * ) " | ' ( [ ^ ' \\ ] * (?: \\ .[ ^ ' \\ ] * ) * ) ' | ` ( [ ^ ` \\ ] * (?: \\ .[ ^ ` \\ ] * ) * ) ` ) / g;
381- const matches = arrayContent . matchAll ( stringRegex ) ;
378+ const matches = sharedMatch [ 1 ] . matchAll ( / [ ' " ` ] ( .* ?) [ ' " ` ] / g) ;
382379 for ( const match of matches ) {
383- const val = match [ 1 ] || match [ 2 ] || match [ 3 ] ;
384- if ( val ) {
385- optionSharedKeys . push ( val ) ;
386- }
380+ optionSharedKeys . push ( match [ 1 ] ) ;
387381 }
388382 }
389383 }
390384
391385 for ( const key of topKeys ) {
392- if ( optionSharedKeys . includes ( key ) ) {
386+ if ( optionSharedKeys . includes ( key ) || key === "NODE_ENV" ) {
393387 sharedKeys . push ( key ) ;
394388 } else if ( key . startsWith ( "NEXT_PUBLIC_" ) ) {
395389 clientKeys . push ( key ) ;
@@ -401,35 +395,45 @@ export function extractKeys(content: string): {
401395}
402396
403397/**
404- * Generate the TypeScript factory code for the tailored createEnv helper.
405- *
406- * @param clientKeys The client environment variable keys
407- * @param sharedKeys The shared environment variable keys
408- * @returns The generated TypeScript source code string
398+ * Generate the triple-tab indented runtime environment variables mapping.
409399 */
410- function generateFactoryCode (
400+ function generateRuntimeEnvLines (
411401 clientKeys : string [ ] ,
412402 sharedKeys : string [ ] ,
413403) : string {
414404 const allKeys = Array . from ( new Set ( [ ...clientKeys , ...sharedKeys ] ) ) ;
415- const runtimeEnvLines = allKeys
405+ return allKeys
416406 . map (
417407 ( key ) =>
418408 `\t\t\t${ key } : typeof window !== "undefined" ? (globalThis as any).__arkenv_env__?.${ key } ?? process.env.${ key } : process.env.${ key } ,` ,
419409 )
420410 . join ( "\n" ) ;
411+ }
421412
422- return `/* eslint-disable */
423- // prettier-ignore
413+ const GENERATED_HEADER = `/* eslint-disable */
424414// biome-ignore format: auto-generated
415+ // Generated by ArkEnv. DO NOT EDIT DIRECTLY.
416+ ` ;
417+
418+ const GENERATED_FOOTER = `
419+ export default createEnv;
420+ ` ;
421+
425422/**
426- * @file env.gen.ts
427- * @note This file is auto-generated by ArkEnv. DO NOT EDIT DIRECTLY.
428- * @see https://arkenv.js.org
423+ * Generate the TypeScript factory code for the tailored createEnv helper.
424+ *
425+ * @param clientKeys The client environment variable keys
426+ * @param sharedKeys The shared environment variable keys
427+ * @returns The generated TypeScript source code string
429428 */
429+ function generateFactoryCode (
430+ clientKeys : string [ ] ,
431+ sharedKeys : string [ ] ,
432+ ) : string {
433+ const runtimeEnvLines = generateRuntimeEnvLines ( clientKeys , sharedKeys ) ;
430434
435+ return `${ GENERATED_HEADER }
431436import { createEnv as coreCreateEnv } from "@arkenv/nextjs";
432- import type { Infer } from "@arkenv/nextjs";
433437
434438export { type } from "@arkenv/nextjs";
435439
@@ -443,18 +447,15 @@ export function createEnv<
443447 [K in keyof TClient]: K extends \`NEXT_PUBLIC_\${string}\` ? unknown : never;
444448 };
445449 shared?: TShared;
446- }): Readonly<Infer<TServer & TClient & TShared>> {
450+ }) {
447451 return coreCreateEnv({
448452 ...options,
449453 runtimeEnv: {
450454${ runtimeEnvLines }
451455 },
452456 } as any) as any;
453457}
454-
455- const arkenv = createEnv;
456- export default arkenv;
457- ` ;
458+ ${ GENERATED_FOOTER } `;
458459}
459460
460461/**
@@ -464,25 +465,10 @@ function generateFlatFactoryCode(
464465 clientKeys : string [ ] ,
465466 sharedKeys : string [ ] ,
466467) : string {
467- const allKeys = Array . from ( new Set ( [ ...clientKeys , ...sharedKeys ] ) ) ;
468- const runtimeEnvLines = allKeys
469- . map (
470- ( key ) =>
471- `\t\t\t${ key } : typeof window !== "undefined" ? (globalThis as any).__arkenv_env__?.${ key } ?? process.env.${ key } : process.env.${ key } ,` ,
472- )
473- . join ( "\n" ) ;
474-
475- return `/* eslint-disable */
476- // prettier-ignore
477- // biome-ignore format: auto-generated
478- /**
479- * @file env.gen.ts
480- * @note This file is auto-generated by ArkEnv. DO NOT EDIT DIRECTLY.
481- * @see https://arkenv.js.org
482- */
468+ const runtimeEnvLines = generateRuntimeEnvLines ( clientKeys , sharedKeys ) ;
483469
470+ return `${ GENERATED_HEADER }
484471import { createEnv as coreCreateEnv } from "@arkenv/nextjs";
485- import type { Infer } from "@arkenv/nextjs";
486472
487473export { type } from "@arkenv/nextjs";
488474
@@ -495,36 +481,15 @@ export function createEnv<
495481 shared?: readonly (keyof TSchema)[];
496482 extends?: [...TExtends];
497483 },
498- ): Readonly<Infer<TSchema>> {
499- const parsedEnv = coreCreateEnv(schema as any, {
484+ ) {
485+ return coreCreateEnv(schema as any, {
500486 ...options,
501487 runtimeEnv: {
502488${ runtimeEnvLines }
503489 },
504490 } as any) as any;
505-
506- return new Proxy(parsedEnv, {
507- get(target, prop, receiver) {
508- if (typeof prop === "string") {
509- const isSchemaKey = prop in schema;
510- const isServer = typeof window === "undefined";
511- const isClientVar = prop.startsWith("NEXT_PUBLIC_");
512- const isSharedVar = options?.shared?.includes(prop);
513-
514- if (isSchemaKey && !isServer && !isClientVar && !isSharedVar) {
515- throw new Error(
516- \`Accessing server-side environment variable '\${prop}' on the client is not allowed.\`
517- );
518- }
519- }
520- return Reflect.get(target, prop, receiver);
521- }
522- }) as any;
523491}
524-
525- const arkenv = createEnv;
526- export default arkenv;
527- ` ;
492+ ${ GENERATED_FOOTER } `;
528493}
529494
530495/**
@@ -541,23 +506,9 @@ function generateClientFactoryCode(
541506 clientKeys : string [ ] ,
542507 sharedKeys : string [ ] ,
543508) : string {
544- const allKeys = Array . from ( new Set ( [ ...clientKeys , ...sharedKeys ] ) ) ;
545- const runtimeEnvLines = allKeys
546- . map (
547- ( key ) =>
548- `\t\t\t${ key } : typeof window !== "undefined" ? (globalThis as any).__arkenv_env__?.${ key } ?? process.env.${ key } : process.env.${ key } ,` ,
549- )
550- . join ( "\n" ) ;
551-
552- return `/* eslint-disable */
553- // prettier-ignore
554- // biome-ignore format: auto-generated
555- /**
556- * @file env.gen.ts
557- * @note This file is auto-generated by ArkEnv. DO NOT EDIT DIRECTLY.
558- * @see https://arkenv.js.org
559- */
509+ const runtimeEnvLines = generateRuntimeEnvLines ( clientKeys , sharedKeys ) ;
560510
511+ return `${ GENERATED_HEADER }
561512import { createEnv as coreCreateEnv } from "@arkenv/nextjs/client";
562513
563514export { type } from "@arkenv/nextjs/client";
@@ -580,8 +531,5 @@ ${runtimeEnvLines}
580531 },
581532 } as any);
582533}
583-
584- const arkenv = createEnv;
585- export default arkenv;
586- ` ;
534+ ${ GENERATED_FOOTER } `;
587535}
0 commit comments