@vite-env/core 0.5.4 → 0.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/README.md +33 -17
  2. package/dist/chunk-CKQMccvm.cjs +28 -0
  3. package/dist/config.cjs +1 -1
  4. package/dist/config.cjs.map +1 -1
  5. package/dist/config.d.cts +1 -1
  6. package/dist/config.d.mts +1 -1
  7. package/dist/config.mjs.map +1 -1
  8. package/dist/dts.cjs +102 -3
  9. package/dist/dts.cjs.map +1 -0
  10. package/dist/dts.d.cts +1 -1
  11. package/dist/dts.d.mts +1 -1
  12. package/dist/dts.mjs +1 -1
  13. package/dist/dts.mjs.map +1 -1
  14. package/dist/format.cjs.map +1 -1
  15. package/dist/format.d.cts +2 -2
  16. package/dist/format.d.mts +2 -2
  17. package/dist/format.mjs.map +1 -1
  18. package/dist/index.d.cts +1 -1
  19. package/dist/index.d.mts +1 -1
  20. package/dist/leak.cjs +11 -10
  21. package/dist/leak.cjs.map +1 -1
  22. package/dist/leak.d.cts +4 -7
  23. package/dist/leak.d.mts +4 -7
  24. package/dist/leak.mjs +11 -10
  25. package/dist/leak.mjs.map +1 -1
  26. package/dist/load.cjs +50 -0
  27. package/dist/load.cjs.map +1 -0
  28. package/dist/load.d.cts +29 -0
  29. package/dist/load.d.mts +29 -0
  30. package/dist/load.mjs +46 -0
  31. package/dist/load.mjs.map +1 -0
  32. package/dist/plugin.cjs +5 -4
  33. package/dist/plugin.cjs.map +1 -1
  34. package/dist/plugin.d.cts +1 -1
  35. package/dist/plugin.d.mts +1 -1
  36. package/dist/plugin.mjs.map +1 -1
  37. package/dist/presets/index.cjs +1 -1
  38. package/dist/presets/index.cjs.map +1 -1
  39. package/dist/presets/index.mjs.map +1 -1
  40. package/dist/schema.cjs +1 -1
  41. package/dist/schema.cjs.map +1 -1
  42. package/dist/schema.d.cts +2 -2
  43. package/dist/schema.d.mts +2 -2
  44. package/dist/schema.mjs.map +1 -1
  45. package/dist/standard.cjs.map +1 -1
  46. package/dist/standard.d.cts +2 -2
  47. package/dist/standard.d.mts +2 -2
  48. package/dist/standard.mjs.map +1 -1
  49. package/dist/{types-B61nsO8q.d.cts → types-Ctg8aeXQ.d.mts} +4 -4
  50. package/dist/{types-KniR_Oqf.d.mts → types-DudMh278.d.cts} +4 -4
  51. package/package.json +47 -36
  52. package/dist/dts-BX0Cnqo-.cjs +0 -139
  53. package/dist/dts-BX0Cnqo-.cjs.map +0 -1
package/README.md CHANGED
@@ -7,6 +7,7 @@ The `env.ts` layer for Vite — define once, validate everywhere, import with ty
7
7
  - Typed virtual modules (`virtual:env/client`, `virtual:env/server`)
8
8
  - Server/client split with build-time leak detection
9
9
  - Runtime access protection — warns or errors when `virtual:env/server` is imported from a client environment
10
+ - Standalone runtime loader — `loadEnv(config)` from `@vite-env/core/load` for scripts outside Vite
10
11
  - Auto-coercion via Zod v4 (`z.stringbool()`, `z.coerce.number()`)
11
12
  - Standard Schema support — use Valibot, ArkType, or any compliant validator
12
13
  - Platform presets — pre-built schemas for Vercel, Railway, and Netlify
@@ -24,8 +25,8 @@ npm install @vite-env/core zod
24
25
  **1. Define your schema** — `env.ts`
25
26
 
26
27
  ```ts
27
- import { defineEnv } from '@vite-env/core'
28
- import { z } from 'zod'
28
+ import { defineEnv } from "@vite-env/core";
29
+ import { z } from "zod";
29
30
 
30
31
  export default defineEnv({
31
32
  server: {
@@ -35,50 +36,65 @@ export default defineEnv({
35
36
  client: {
36
37
  VITE_API_URL: z.url(),
37
38
  VITE_DARK_MODE: z.stringbool().default(false),
38
- VITE_NODE_ENV: z
39
- .enum(['development', 'test', 'production'])
40
- .default('development'),
39
+ VITE_NODE_ENV: z.enum(["development", "test", "production"]).default("development"),
41
40
  },
42
- })
41
+ });
43
42
  ```
44
43
 
45
44
  **2. Add the plugin** — `vite.config.ts`
46
45
 
47
46
  ```ts
48
- import ViteEnv from '@vite-env/core/plugin'
49
- import { defineConfig } from 'vite'
47
+ import ViteEnv from "@vite-env/core/plugin";
48
+ import { defineConfig } from "vite";
50
49
 
51
50
  export default defineConfig({
52
51
  plugins: [ViteEnv()],
53
- })
52
+ });
54
53
  ```
55
54
 
56
55
  **3. Import typed env**
57
56
 
58
57
  ```ts
59
- import { env } from 'virtual:env/client'
58
+ import { env } from "virtual:env/client";
60
59
 
61
- env.VITE_API_URL // string
62
- env.VITE_DARK_MODE // boolean
63
- env.VITE_NODE_ENV // 'development' | 'test' | 'production'
60
+ env.VITE_API_URL; // string
61
+ env.VITE_DARK_MODE; // boolean
62
+ env.VITE_NODE_ENV; // 'development' | 'test' | 'production'
64
63
  ```
65
64
 
66
65
  ### Platform presets
67
66
 
68
67
  ```ts
69
- import { defineEnv } from '@vite-env/core'
70
- import { vercel } from '@vite-env/core/presets'
71
- import { z } from 'zod'
68
+ import { defineEnv } from "@vite-env/core";
69
+ import { vercel } from "@vite-env/core/presets";
70
+ import { z } from "zod";
72
71
 
73
72
  export default defineEnv({
74
73
  presets: [vercel],
75
74
  server: { DATABASE_URL: z.url() },
76
75
  client: { VITE_API_URL: z.url() },
77
- })
76
+ });
78
77
  ```
79
78
 
80
79
  Available presets: `vercel`, `railway`, `netlify`.
81
80
 
81
+ ### Standalone runtime loader
82
+
83
+ Use the same validated env in Node/Bun scripts outside of Vite:
84
+
85
+ ```ts
86
+ // scripts/seed.ts
87
+ import { loadEnv } from "@vite-env/core/load";
88
+ import config from "../env";
89
+
90
+ const { server, client } = await loadEnv(config);
91
+
92
+ server.DATABASE_URL; // string
93
+ client.VITE_API_URL; // string
94
+ ```
95
+
96
+ Returns `{ server, client, all }`. Accepts an optional second argument `{ mode?, envDir? }`.
97
+
82
98
  See the [full documentation](https://pyyupsk.github.io/vite-env/) for server/client split details, CLI tools, and more.
83
99
 
84
100
  ## License
@@ -0,0 +1,28 @@
1
+ //#region \0rolldown/runtime.js
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __copyProps = (to, from, except, desc) => {
9
+ if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
10
+ key = keys[i];
11
+ if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
12
+ get: ((k) => from[k]).bind(null, key),
13
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
14
+ });
15
+ }
16
+ return to;
17
+ };
18
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
19
+ value: mod,
20
+ enumerable: true
21
+ }) : target, mod));
22
+ //#endregion
23
+ Object.defineProperty(exports, "__toESM", {
24
+ enumerable: true,
25
+ get: function() {
26
+ return __toESM;
27
+ }
28
+ });
package/dist/config.cjs CHANGED
@@ -1,5 +1,5 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- require("./dts-BX0Cnqo-.cjs");
2
+ require("./chunk-CKQMccvm.cjs");
3
3
  let jiti = require("jiti");
4
4
  //#region src/config.ts
5
5
  async function loadEnvConfig(configPath) {
@@ -1 +1 @@
1
- {"version":3,"file":"config.cjs","names":[],"sources":["../src/config.ts"],"sourcesContent":["import type { EnvDefinition } from './types'\nimport { createJiti } from 'jiti'\n\nexport async function loadEnvConfig(configPath: string): Promise<EnvDefinition> {\n const jiti = createJiti(configPath)\n const mod = await jiti.import<Record<string, unknown>>(configPath)\n const def: unknown = mod.default ?? mod\n\n if (!def || typeof def !== 'object') {\n throw new Error(\n `[vite-env] env config at ${configPath} must export an object (got ${typeof def}).\\n`\n + ` Use: export default defineEnv({ ... })`,\n )\n }\n\n return def as EnvDefinition\n}\n"],"mappings":";;;;AAGA,eAAsB,cAAc,YAA4C;CAE9E,MAAM,MAAM,OAAA,GAAA,KAAA,YADY,WACF,CAAC,OAAgC,WAAW;CAClE,MAAM,MAAe,IAAI,WAAW;AAEpC,KAAI,CAAC,OAAO,OAAO,QAAQ,SACzB,OAAM,IAAI,MACR,4BAA4B,WAAW,8BAA8B,OAAO,IAAI,8CAEjF;AAGH,QAAO"}
1
+ {"version":3,"file":"config.cjs","names":[],"sources":["../src/config.ts"],"sourcesContent":["import type { EnvDefinition } from \"./types\";\nimport { createJiti } from \"jiti\";\n\nexport async function loadEnvConfig(configPath: string): Promise<EnvDefinition> {\n const jiti = createJiti(configPath);\n const mod = await jiti.import<Record<string, unknown>>(configPath);\n const def: unknown = mod.default ?? mod;\n\n if (!def || typeof def !== \"object\") {\n throw new Error(\n `[vite-env] env config at ${configPath} must export an object (got ${typeof def}).\\n` +\n ` Use: export default defineEnv({ ... })`,\n );\n }\n\n return def as EnvDefinition;\n}\n"],"mappings":";;;;AAGA,eAAsB,cAAc,YAA4C;CAE9E,MAAM,MAAM,OAAA,GAAA,KAAA,YADY,WACF,CAAC,OAAgC,WAAW;CAClE,MAAM,MAAe,IAAI,WAAW;AAEpC,KAAI,CAAC,OAAO,OAAO,QAAQ,SACzB,OAAM,IAAI,MACR,4BAA4B,WAAW,8BAA8B,OAAO,IAAI,8CAEjF;AAGH,QAAO"}
package/dist/config.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- import { n as EnvDefinition } from "./types-B61nsO8q.cjs";
1
+ import { n as EnvDefinition } from "./types-DudMh278.cjs";
2
2
 
3
3
  //#region src/config.d.ts
4
4
  declare function loadEnvConfig(configPath: string): Promise<EnvDefinition>;
package/dist/config.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import { n as EnvDefinition } from "./types-KniR_Oqf.mjs";
1
+ import { n as EnvDefinition } from "./types-Ctg8aeXQ.mjs";
2
2
 
3
3
  //#region src/config.d.ts
4
4
  declare function loadEnvConfig(configPath: string): Promise<EnvDefinition>;
@@ -1 +1 @@
1
- {"version":3,"file":"config.mjs","names":[],"sources":["../src/config.ts"],"sourcesContent":["import type { EnvDefinition } from './types'\nimport { createJiti } from 'jiti'\n\nexport async function loadEnvConfig(configPath: string): Promise<EnvDefinition> {\n const jiti = createJiti(configPath)\n const mod = await jiti.import<Record<string, unknown>>(configPath)\n const def: unknown = mod.default ?? mod\n\n if (!def || typeof def !== 'object') {\n throw new Error(\n `[vite-env] env config at ${configPath} must export an object (got ${typeof def}).\\n`\n + ` Use: export default defineEnv({ ... })`,\n )\n }\n\n return def as EnvDefinition\n}\n"],"mappings":";;AAGA,eAAsB,cAAc,YAA4C;CAE9E,MAAM,MAAM,MADC,WAAW,WACF,CAAC,OAAgC,WAAW;CAClE,MAAM,MAAe,IAAI,WAAW;AAEpC,KAAI,CAAC,OAAO,OAAO,QAAQ,SACzB,OAAM,IAAI,MACR,4BAA4B,WAAW,8BAA8B,OAAO,IAAI,8CAEjF;AAGH,QAAO"}
1
+ {"version":3,"file":"config.mjs","names":[],"sources":["../src/config.ts"],"sourcesContent":["import type { EnvDefinition } from \"./types\";\nimport { createJiti } from \"jiti\";\n\nexport async function loadEnvConfig(configPath: string): Promise<EnvDefinition> {\n const jiti = createJiti(configPath);\n const mod = await jiti.import<Record<string, unknown>>(configPath);\n const def: unknown = mod.default ?? mod;\n\n if (!def || typeof def !== \"object\") {\n throw new Error(\n `[vite-env] env config at ${configPath} must export an object (got ${typeof def}).\\n` +\n ` Use: export default defineEnv({ ... })`,\n );\n }\n\n return def as EnvDefinition;\n}\n"],"mappings":";;AAGA,eAAsB,cAAc,YAA4C;CAE9E,MAAM,MAAM,MADC,WAAW,WACF,CAAC,OAAgC,WAAW;CAClE,MAAM,MAAe,IAAI,WAAW;AAEpC,KAAI,CAAC,OAAO,OAAO,QAAQ,SACzB,OAAM,IAAI,MACR,4BAA4B,WAAW,8BAA8B,OAAO,IAAI,8CAEjF;AAGH,QAAO"}
package/dist/dts.cjs CHANGED
@@ -1,4 +1,103 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_dts = require("./dts-BX0Cnqo-.cjs");
3
- exports.generateDts = require_dts.generateDts;
4
- exports.generateStandardDts = require_dts.generateStandardDts;
2
+ const require_chunk = require("./chunk-CKQMccvm.cjs");
3
+ let node_path = require("node:path");
4
+ node_path = require_chunk.__toESM(node_path, 1);
5
+ let node_fs_promises = require("node:fs/promises");
6
+ node_fs_promises = require_chunk.__toESM(node_fs_promises, 1);
7
+ //#region src/dts.ts
8
+ /**
9
+ * Writes vite-env.d.ts for Zod definitions.
10
+ * Uses instanceof checks to infer TypeScript types from Zod schemas.
11
+ * Zod is loaded dynamically so this module can be imported without zod installed.
12
+ */
13
+ async function generateDts(def, root) {
14
+ const { z } = await import("zod");
15
+ const gatedKeys = gatedPresetKeys(def);
16
+ await writeDts(root, zodShapeToTsFields(z, { ...def.client }, gatedKeys), zodShapeToTsFields(z, {
17
+ ...def.server,
18
+ ...def.client
19
+ }, gatedKeys));
20
+ }
21
+ /**
22
+ * Detection-gated preset keys (not user-overridden) validate as optional
23
+ * off-platform — typing them required would lie during local dev.
24
+ */
25
+ function gatedPresetKeys(def) {
26
+ const keys = /* @__PURE__ */ new Set();
27
+ for (const preset of def.presets ?? []) {
28
+ if (!preset.detect) continue;
29
+ for (const side of ["server", "client"]) for (const [key, schema] of Object.entries(preset[side] ?? {})) if (def[side]?.[key] === schema) keys.add(key);
30
+ }
31
+ return keys;
32
+ }
33
+ /**
34
+ * Writes vite-env.d.ts for Standard Schema definitions.
35
+ * All fields are typed as `string` — Standard Schema has no runtime type introspection.
36
+ */
37
+ async function generateStandardDts(def, root) {
38
+ const clientKeys = Object.keys(def.client ?? {});
39
+ const serverKeys = [...Object.keys(def.server ?? {}), ...clientKeys];
40
+ await writeDts(root, keysToTsFields(clientKeys), keysToTsFields(serverKeys), "(Standard Schema)");
41
+ }
42
+ function buildHeader(tag = "") {
43
+ const lines = [
44
+ "/* oxlint-disable */",
45
+ "/* eslint-disable */",
46
+ "// @ts-nocheck",
47
+ "// biome-ignore-all lint: auto-generated",
48
+ tag ? `// Auto-generated by @vite-env/core ${tag}` : "// Auto-generated by @vite-env/core",
49
+ "// Do not edit manually — re-generated on every dev server start and build"
50
+ ];
51
+ if (tag) lines.push("// Tip: for richer types, use defineEnv() with Zod instead of defineStandardEnv()");
52
+ return lines.join("\n");
53
+ }
54
+ async function writeDts(root, clientFields, serverFields, tag = "") {
55
+ const dts = `${buildHeader(tag)}
56
+
57
+ declare module 'virtual:env/client' {
58
+ const env: {
59
+ ${clientFields}
60
+ }
61
+ export { env }
62
+ export default env
63
+ }
64
+
65
+ declare module 'virtual:env/server' {
66
+ const env: {
67
+ ${serverFields}
68
+ }
69
+ export { env }
70
+ export default env
71
+ }
72
+ `;
73
+ const filePath = node_path.default.join(root, "vite-env.d.ts");
74
+ try {
75
+ await node_fs_promises.default.writeFile(filePath, dts, "utf-8");
76
+ } catch (e) {
77
+ throw new Error(`[vite-env] Failed to write vite-env.d.ts to ${root}. Check file permissions.`, { cause: e });
78
+ }
79
+ }
80
+ function keysToTsFields(keys) {
81
+ return keys.map((key) => ` readonly ${key}: string`).join("\n");
82
+ }
83
+ function zodShapeToTsFields(z, shape, gatedKeys) {
84
+ return Object.entries(shape).map(([key, schema]) => {
85
+ const tsType = zodToTs(z, schema);
86
+ return ` readonly ${key}${schema instanceof z.ZodOptional || gatedKeys.has(key) ? "?" : ""}: ${tsType}`;
87
+ }).join("\n");
88
+ }
89
+ function zodToTs(z, schema) {
90
+ if (schema instanceof z.ZodOptional) return zodToTs(z, schema.unwrap());
91
+ if (schema instanceof z.ZodDefault) return zodToTs(z, schema.def.innerType);
92
+ if (schema instanceof z.ZodString) return "string";
93
+ if (schema instanceof z.ZodNumber) return "number";
94
+ if (schema instanceof z.ZodBoolean) return "boolean";
95
+ if (schema instanceof z.ZodEnum) return schema.options.map((o) => `'${o}'`).join(" | ");
96
+ if (schema instanceof z.ZodPipe) return zodToTs(z, schema.def.out);
97
+ return "string";
98
+ }
99
+ //#endregion
100
+ exports.generateDts = generateDts;
101
+ exports.generateStandardDts = generateStandardDts;
102
+
103
+ //# sourceMappingURL=dts.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dts.cjs","names":["path","fs"],"sources":["../src/dts.ts"],"sourcesContent":["// @env node\nimport type { EnvDefinition, StandardEnvDefinition } from \"./types\";\nimport type { z as ZodNs } from \"zod\";\nimport fs from \"node:fs/promises\";\nimport path from \"node:path\";\n\n/**\n * Writes vite-env.d.ts for Zod definitions.\n * Uses instanceof checks to infer TypeScript types from Zod schemas.\n * Zod is loaded dynamically so this module can be imported without zod installed.\n */\nexport async function generateDts(def: EnvDefinition, root: string): Promise<void> {\n const { z } = await import(\"zod\");\n\n const gatedKeys = gatedPresetKeys(def);\n const clientFields = zodShapeToTsFields(z, { ...def.client }, gatedKeys);\n const serverFields = zodShapeToTsFields(z, { ...def.server, ...def.client }, gatedKeys);\n\n await writeDts(root, clientFields, serverFields);\n}\n\n/**\n * Detection-gated preset keys (not user-overridden) validate as optional\n * off-platform — typing them required would lie during local dev.\n */\nfunction gatedPresetKeys(def: EnvDefinition): Set<string> {\n const keys = new Set<string>();\n for (const preset of def.presets ?? []) {\n if (!preset.detect) continue;\n for (const side of [\"server\", \"client\"] as const) {\n for (const [key, schema] of Object.entries(preset[side] ?? {})) {\n if (def[side]?.[key] === schema) keys.add(key);\n }\n }\n }\n return keys;\n}\n\n/**\n * Writes vite-env.d.ts for Standard Schema definitions.\n * All fields are typed as `string` — Standard Schema has no runtime type introspection.\n */\nexport async function generateStandardDts(def: StandardEnvDefinition, root: string): Promise<void> {\n const clientKeys = Object.keys(def.client ?? {});\n const serverKeys = [...Object.keys(def.server ?? {}), ...clientKeys];\n\n const clientFields = keysToTsFields(clientKeys);\n const serverFields = keysToTsFields(serverKeys);\n\n await writeDts(root, clientFields, serverFields, \"(Standard Schema)\");\n}\n\nfunction buildHeader(tag = \"\"): string {\n const lines = [\n \"/* oxlint-disable */\",\n \"/* eslint-disable */\",\n \"// @ts-nocheck\",\n \"// biome-ignore-all lint: auto-generated\",\n tag ? `// Auto-generated by @vite-env/core ${tag}` : \"// Auto-generated by @vite-env/core\",\n \"// Do not edit manually — re-generated on every dev server start and build\",\n ];\n if (tag) {\n lines.push(\"// Tip: for richer types, use defineEnv() with Zod instead of defineStandardEnv()\");\n }\n return lines.join(\"\\n\");\n}\n\nasync function writeDts(\n root: string,\n clientFields: string,\n serverFields: string,\n tag = \"\",\n): Promise<void> {\n const header = buildHeader(tag);\n\n const dts = `${header}\n\ndeclare module 'virtual:env/client' {\n const env: {\n${clientFields}\n }\n export { env }\n export default env\n}\n\ndeclare module 'virtual:env/server' {\n const env: {\n${serverFields}\n }\n export { env }\n export default env\n}\n`;\n\n const filePath = path.join(root, \"vite-env.d.ts\");\n try {\n await fs.writeFile(filePath, dts, \"utf-8\");\n } catch (e) {\n throw new Error(\n `[vite-env] Failed to write vite-env.d.ts to ${root}. Check file permissions.`,\n { cause: e },\n );\n }\n}\n\nfunction keysToTsFields(keys: string[]): string {\n return keys.map((key) => ` readonly ${key}: string`).join(\"\\n\");\n}\n\nfunction zodShapeToTsFields(\n z: typeof ZodNs,\n shape: Record<string, unknown>,\n gatedKeys: Set<string>,\n): string {\n return Object.entries(shape)\n .map(([key, schema]) => {\n const tsType = zodToTs(z, schema);\n const optional = schema instanceof z.ZodOptional || gatedKeys.has(key);\n return ` readonly ${key}${optional ? \"?\" : \"\"}: ${tsType}`;\n })\n .join(\"\\n\");\n}\n\nfunction zodToTs(z: typeof ZodNs, schema: unknown): string {\n if (schema instanceof z.ZodOptional) return zodToTs(z, schema.unwrap());\n if (schema instanceof z.ZodDefault) return zodToTs(z, schema.def.innerType);\n if (schema instanceof z.ZodString) return \"string\";\n if (schema instanceof z.ZodNumber) return \"number\";\n if (schema instanceof z.ZodBoolean) return \"boolean\";\n if (schema instanceof z.ZodEnum)\n return (schema.options as string[]).map((o) => `'${o}'`).join(\" | \");\n if (schema instanceof z.ZodPipe) return zodToTs(z, schema.def.out);\n return \"string\";\n}\n"],"mappings":";;;;;;;;;;;;AAWA,eAAsB,YAAY,KAAoB,MAA6B;CACjF,MAAM,EAAE,MAAM,MAAM,OAAO;CAE3B,MAAM,YAAY,gBAAgB,IAAI;AAItC,OAAM,SAAS,MAHM,mBAAmB,GAAG,EAAE,GAAG,IAAI,QAAQ,EAAE,UAG7B,EAFZ,mBAAmB,GAAG;EAAE,GAAG,IAAI;EAAQ,GAAG,IAAI;EAAQ,EAAE,UAE9B,CAAC;;;;;;AAOlD,SAAS,gBAAgB,KAAiC;CACxD,MAAM,uBAAO,IAAI,KAAa;AAC9B,MAAK,MAAM,UAAU,IAAI,WAAW,EAAE,EAAE;AACtC,MAAI,CAAC,OAAO,OAAQ;AACpB,OAAK,MAAM,QAAQ,CAAC,UAAU,SAAS,CACrC,MAAK,MAAM,CAAC,KAAK,WAAW,OAAO,QAAQ,OAAO,SAAS,EAAE,CAAC,CAC5D,KAAI,IAAI,QAAQ,SAAS,OAAQ,MAAK,IAAI,IAAI;;AAIpD,QAAO;;;;;;AAOT,eAAsB,oBAAoB,KAA4B,MAA6B;CACjG,MAAM,aAAa,OAAO,KAAK,IAAI,UAAU,EAAE,CAAC;CAChD,MAAM,aAAa,CAAC,GAAG,OAAO,KAAK,IAAI,UAAU,EAAE,CAAC,EAAE,GAAG,WAAW;AAKpE,OAAM,SAAS,MAHM,eAAe,WAGH,EAFZ,eAAe,WAEW,EAAE,oBAAoB;;AAGvE,SAAS,YAAY,MAAM,IAAY;CACrC,MAAM,QAAQ;EACZ;EACA;EACA;EACA;EACA,MAAM,uCAAuC,QAAQ;EACrD;EACD;AACD,KAAI,IACF,OAAM,KAAK,oFAAoF;AAEjG,QAAO,MAAM,KAAK,KAAK;;AAGzB,eAAe,SACb,MACA,cACA,cACA,MAAM,IACS;CAGf,MAAM,MAAM,GAFG,YAAY,IAEN,CAAC;;;;EAItB,aAAa;;;;;;;;EAQb,aAAa;;;;;;CAOb,MAAM,WAAWA,UAAAA,QAAK,KAAK,MAAM,gBAAgB;AACjD,KAAI;AACF,QAAMC,iBAAAA,QAAG,UAAU,UAAU,KAAK,QAAQ;UACnC,GAAG;AACV,QAAM,IAAI,MACR,+CAA+C,KAAK,4BACpD,EAAE,OAAO,GAAG,CACb;;;AAIL,SAAS,eAAe,MAAwB;AAC9C,QAAO,KAAK,KAAK,QAAQ,gBAAgB,IAAI,UAAU,CAAC,KAAK,KAAK;;AAGpE,SAAS,mBACP,GACA,OACA,WACQ;AACR,QAAO,OAAO,QAAQ,MAAM,CACzB,KAAK,CAAC,KAAK,YAAY;EACtB,MAAM,SAAS,QAAQ,GAAG,OAAO;AAEjC,SAAO,gBAAgB,MADN,kBAAkB,EAAE,eAAe,UAAU,IAAI,IAAI,GAC9B,MAAM,GAAG,IAAI;GACrD,CACD,KAAK,KAAK;;AAGf,SAAS,QAAQ,GAAiB,QAAyB;AACzD,KAAI,kBAAkB,EAAE,YAAa,QAAO,QAAQ,GAAG,OAAO,QAAQ,CAAC;AACvE,KAAI,kBAAkB,EAAE,WAAY,QAAO,QAAQ,GAAG,OAAO,IAAI,UAAU;AAC3E,KAAI,kBAAkB,EAAE,UAAW,QAAO;AAC1C,KAAI,kBAAkB,EAAE,UAAW,QAAO;AAC1C,KAAI,kBAAkB,EAAE,WAAY,QAAO;AAC3C,KAAI,kBAAkB,EAAE,QACtB,QAAQ,OAAO,QAAqB,KAAK,MAAM,IAAI,EAAE,GAAG,CAAC,KAAK,MAAM;AACtE,KAAI,kBAAkB,EAAE,QAAS,QAAO,QAAQ,GAAG,OAAO,IAAI,IAAI;AAClE,QAAO"}
package/dist/dts.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- import { n as EnvDefinition, o as StandardEnvDefinition } from "./types-B61nsO8q.cjs";
1
+ import { n as EnvDefinition, o as StandardEnvDefinition } from "./types-DudMh278.cjs";
2
2
 
3
3
  //#region src/dts.d.ts
4
4
  /**
package/dist/dts.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import { n as EnvDefinition, o as StandardEnvDefinition } from "./types-KniR_Oqf.mjs";
1
+ import { n as EnvDefinition, o as StandardEnvDefinition } from "./types-Ctg8aeXQ.mjs";
2
2
 
3
3
  //#region src/dts.d.ts
4
4
  /**
package/dist/dts.mjs CHANGED
@@ -41,7 +41,7 @@ function buildHeader(tag = "") {
41
41
  "/* eslint-disable */",
42
42
  "// @ts-nocheck",
43
43
  "// biome-ignore-all lint: auto-generated",
44
- `// Auto-generated by @vite-env/core${tag ? ` ${tag}` : ""}`,
44
+ tag ? `// Auto-generated by @vite-env/core ${tag}` : "// Auto-generated by @vite-env/core",
45
45
  "// Do not edit manually — re-generated on every dev server start and build"
46
46
  ];
47
47
  if (tag) lines.push("// Tip: for richer types, use defineEnv() with Zod instead of defineStandardEnv()");
package/dist/dts.mjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"dts.mjs","names":[],"sources":["../src/dts.ts"],"sourcesContent":["// @env node\nimport type { EnvDefinition, StandardEnvDefinition } from './types'\nimport type { z as ZodNs } from 'zod'\nimport fs from 'node:fs/promises'\nimport path from 'node:path'\n\n/**\n * Writes vite-env.d.ts for Zod definitions.\n * Uses instanceof checks to infer TypeScript types from Zod schemas.\n * Zod is loaded dynamically so this module can be imported without zod installed.\n */\nexport async function generateDts(\n def: EnvDefinition,\n root: string,\n): Promise<void> {\n const { z } = await import('zod')\n\n const gatedKeys = gatedPresetKeys(def)\n const clientFields = zodShapeToTsFields(z, { ...def.client }, gatedKeys)\n const serverFields = zodShapeToTsFields(z, { ...def.server, ...def.client }, gatedKeys)\n\n await writeDts(root, clientFields, serverFields)\n}\n\n/**\n * Detection-gated preset keys (not user-overridden) validate as optional\n * off-platform — typing them required would lie during local dev.\n */\nfunction gatedPresetKeys(def: EnvDefinition): Set<string> {\n const keys = new Set<string>()\n for (const preset of def.presets ?? []) {\n if (!preset.detect)\n continue\n for (const side of ['server', 'client'] as const) {\n for (const [key, schema] of Object.entries(preset[side] ?? {})) {\n if (def[side]?.[key] === schema)\n keys.add(key)\n }\n }\n }\n return keys\n}\n\n/**\n * Writes vite-env.d.ts for Standard Schema definitions.\n * All fields are typed as `string` — Standard Schema has no runtime type introspection.\n */\nexport async function generateStandardDts(\n def: StandardEnvDefinition,\n root: string,\n): Promise<void> {\n const clientKeys = Object.keys(def.client ?? {})\n const serverKeys = [...Object.keys(def.server ?? {}), ...clientKeys]\n\n const clientFields = keysToTsFields(clientKeys)\n const serverFields = keysToTsFields(serverKeys)\n\n await writeDts(root, clientFields, serverFields, '(Standard Schema)')\n}\n\nfunction buildHeader(tag = ''): string {\n const lines = [\n '/* oxlint-disable */',\n '/* eslint-disable */',\n '// @ts-nocheck',\n '// biome-ignore-all lint: auto-generated',\n `// Auto-generated by @vite-env/core${tag ? ` ${tag}` : ''}`,\n '// Do not edit manually — re-generated on every dev server start and build',\n ]\n if (tag) {\n lines.push('// Tip: for richer types, use defineEnv() with Zod instead of defineStandardEnv()')\n }\n return lines.join('\\n')\n}\n\nasync function writeDts(\n root: string,\n clientFields: string,\n serverFields: string,\n tag = '',\n): Promise<void> {\n const header = buildHeader(tag)\n\n const dts = `${header}\n\ndeclare module 'virtual:env/client' {\n const env: {\n${clientFields}\n }\n export { env }\n export default env\n}\n\ndeclare module 'virtual:env/server' {\n const env: {\n${serverFields}\n }\n export { env }\n export default env\n}\n`\n\n const filePath = path.join(root, 'vite-env.d.ts')\n try {\n await fs.writeFile(filePath, dts, 'utf-8')\n }\n catch (e) {\n throw new Error(\n `[vite-env] Failed to write vite-env.d.ts to ${root}. Check file permissions.`,\n { cause: e },\n )\n }\n}\n\nfunction keysToTsFields(keys: string[]): string {\n return keys\n .map(key => ` readonly ${key}: string`)\n .join('\\n')\n}\n\nfunction zodShapeToTsFields(z: typeof ZodNs, shape: Record<string, unknown>, gatedKeys: Set<string>): string {\n return Object.entries(shape)\n .map(([key, schema]) => {\n const tsType = zodToTs(z, schema)\n const optional = schema instanceof z.ZodOptional || gatedKeys.has(key)\n return ` readonly ${key}${optional ? '?' : ''}: ${tsType}`\n })\n .join('\\n')\n}\n\nfunction zodToTs(z: typeof ZodNs, schema: unknown): string {\n if (schema instanceof z.ZodOptional)\n return zodToTs(z, schema.unwrap())\n if (schema instanceof z.ZodDefault)\n return zodToTs(z, schema.def.innerType)\n if (schema instanceof z.ZodString)\n return 'string'\n if (schema instanceof z.ZodNumber)\n return 'number'\n if (schema instanceof z.ZodBoolean)\n return 'boolean'\n if (schema instanceof z.ZodEnum)\n return (schema.options as string[]).map(o => `'${o}'`).join(' | ')\n if (schema instanceof z.ZodPipe)\n return zodToTs(z, schema.def.out)\n return 'string'\n}\n"],"mappings":";;;;;;;;AAWA,eAAsB,YACpB,KACA,MACe;CACf,MAAM,EAAE,MAAM,MAAM,OAAO;CAE3B,MAAM,YAAY,gBAAgB,IAAI;AAItC,OAAM,SAAS,MAHM,mBAAmB,GAAG,EAAE,GAAG,IAAI,QAAQ,EAAE,UAG7B,EAFZ,mBAAmB,GAAG;EAAE,GAAG,IAAI;EAAQ,GAAG,IAAI;EAAQ,EAAE,UAE9B,CAAC;;;;;;AAOlD,SAAS,gBAAgB,KAAiC;CACxD,MAAM,uBAAO,IAAI,KAAa;AAC9B,MAAK,MAAM,UAAU,IAAI,WAAW,EAAE,EAAE;AACtC,MAAI,CAAC,OAAO,OACV;AACF,OAAK,MAAM,QAAQ,CAAC,UAAU,SAAS,CACrC,MAAK,MAAM,CAAC,KAAK,WAAW,OAAO,QAAQ,OAAO,SAAS,EAAE,CAAC,CAC5D,KAAI,IAAI,QAAQ,SAAS,OACvB,MAAK,IAAI,IAAI;;AAIrB,QAAO;;;;;;AAOT,eAAsB,oBACpB,KACA,MACe;CACf,MAAM,aAAa,OAAO,KAAK,IAAI,UAAU,EAAE,CAAC;CAChD,MAAM,aAAa,CAAC,GAAG,OAAO,KAAK,IAAI,UAAU,EAAE,CAAC,EAAE,GAAG,WAAW;AAKpE,OAAM,SAAS,MAHM,eAAe,WAGH,EAFZ,eAAe,WAEW,EAAE,oBAAoB;;AAGvE,SAAS,YAAY,MAAM,IAAY;CACrC,MAAM,QAAQ;EACZ;EACA;EACA;EACA;EACA,sCAAsC,MAAM,IAAI,QAAQ;EACxD;EACD;AACD,KAAI,IACF,OAAM,KAAK,oFAAoF;AAEjG,QAAO,MAAM,KAAK,KAAK;;AAGzB,eAAe,SACb,MACA,cACA,cACA,MAAM,IACS;CAGf,MAAM,MAAM,GAFG,YAAY,IAEN,CAAC;;;;EAItB,aAAa;;;;;;;;EAQb,aAAa;;;;;;CAOb,MAAM,WAAW,KAAK,KAAK,MAAM,gBAAgB;AACjD,KAAI;AACF,QAAM,GAAG,UAAU,UAAU,KAAK,QAAQ;UAErC,GAAG;AACR,QAAM,IAAI,MACR,+CAA+C,KAAK,4BACpD,EAAE,OAAO,GAAG,CACb;;;AAIL,SAAS,eAAe,MAAwB;AAC9C,QAAO,KACJ,KAAI,QAAO,gBAAgB,IAAI,UAAU,CACzC,KAAK,KAAK;;AAGf,SAAS,mBAAmB,GAAiB,OAAgC,WAAgC;AAC3G,QAAO,OAAO,QAAQ,MAAM,CACzB,KAAK,CAAC,KAAK,YAAY;EACtB,MAAM,SAAS,QAAQ,GAAG,OAAO;AAEjC,SAAO,gBAAgB,MADN,kBAAkB,EAAE,eAAe,UAAU,IAAI,IAAI,GAC9B,MAAM,GAAG,IAAI;GACrD,CACD,KAAK,KAAK;;AAGf,SAAS,QAAQ,GAAiB,QAAyB;AACzD,KAAI,kBAAkB,EAAE,YACtB,QAAO,QAAQ,GAAG,OAAO,QAAQ,CAAC;AACpC,KAAI,kBAAkB,EAAE,WACtB,QAAO,QAAQ,GAAG,OAAO,IAAI,UAAU;AACzC,KAAI,kBAAkB,EAAE,UACtB,QAAO;AACT,KAAI,kBAAkB,EAAE,UACtB,QAAO;AACT,KAAI,kBAAkB,EAAE,WACtB,QAAO;AACT,KAAI,kBAAkB,EAAE,QACtB,QAAQ,OAAO,QAAqB,KAAI,MAAK,IAAI,EAAE,GAAG,CAAC,KAAK,MAAM;AACpE,KAAI,kBAAkB,EAAE,QACtB,QAAO,QAAQ,GAAG,OAAO,IAAI,IAAI;AACnC,QAAO"}
1
+ {"version":3,"file":"dts.mjs","names":[],"sources":["../src/dts.ts"],"sourcesContent":["// @env node\nimport type { EnvDefinition, StandardEnvDefinition } from \"./types\";\nimport type { z as ZodNs } from \"zod\";\nimport fs from \"node:fs/promises\";\nimport path from \"node:path\";\n\n/**\n * Writes vite-env.d.ts for Zod definitions.\n * Uses instanceof checks to infer TypeScript types from Zod schemas.\n * Zod is loaded dynamically so this module can be imported without zod installed.\n */\nexport async function generateDts(def: EnvDefinition, root: string): Promise<void> {\n const { z } = await import(\"zod\");\n\n const gatedKeys = gatedPresetKeys(def);\n const clientFields = zodShapeToTsFields(z, { ...def.client }, gatedKeys);\n const serverFields = zodShapeToTsFields(z, { ...def.server, ...def.client }, gatedKeys);\n\n await writeDts(root, clientFields, serverFields);\n}\n\n/**\n * Detection-gated preset keys (not user-overridden) validate as optional\n * off-platform — typing them required would lie during local dev.\n */\nfunction gatedPresetKeys(def: EnvDefinition): Set<string> {\n const keys = new Set<string>();\n for (const preset of def.presets ?? []) {\n if (!preset.detect) continue;\n for (const side of [\"server\", \"client\"] as const) {\n for (const [key, schema] of Object.entries(preset[side] ?? {})) {\n if (def[side]?.[key] === schema) keys.add(key);\n }\n }\n }\n return keys;\n}\n\n/**\n * Writes vite-env.d.ts for Standard Schema definitions.\n * All fields are typed as `string` — Standard Schema has no runtime type introspection.\n */\nexport async function generateStandardDts(def: StandardEnvDefinition, root: string): Promise<void> {\n const clientKeys = Object.keys(def.client ?? {});\n const serverKeys = [...Object.keys(def.server ?? {}), ...clientKeys];\n\n const clientFields = keysToTsFields(clientKeys);\n const serverFields = keysToTsFields(serverKeys);\n\n await writeDts(root, clientFields, serverFields, \"(Standard Schema)\");\n}\n\nfunction buildHeader(tag = \"\"): string {\n const lines = [\n \"/* oxlint-disable */\",\n \"/* eslint-disable */\",\n \"// @ts-nocheck\",\n \"// biome-ignore-all lint: auto-generated\",\n tag ? `// Auto-generated by @vite-env/core ${tag}` : \"// Auto-generated by @vite-env/core\",\n \"// Do not edit manually — re-generated on every dev server start and build\",\n ];\n if (tag) {\n lines.push(\"// Tip: for richer types, use defineEnv() with Zod instead of defineStandardEnv()\");\n }\n return lines.join(\"\\n\");\n}\n\nasync function writeDts(\n root: string,\n clientFields: string,\n serverFields: string,\n tag = \"\",\n): Promise<void> {\n const header = buildHeader(tag);\n\n const dts = `${header}\n\ndeclare module 'virtual:env/client' {\n const env: {\n${clientFields}\n }\n export { env }\n export default env\n}\n\ndeclare module 'virtual:env/server' {\n const env: {\n${serverFields}\n }\n export { env }\n export default env\n}\n`;\n\n const filePath = path.join(root, \"vite-env.d.ts\");\n try {\n await fs.writeFile(filePath, dts, \"utf-8\");\n } catch (e) {\n throw new Error(\n `[vite-env] Failed to write vite-env.d.ts to ${root}. Check file permissions.`,\n { cause: e },\n );\n }\n}\n\nfunction keysToTsFields(keys: string[]): string {\n return keys.map((key) => ` readonly ${key}: string`).join(\"\\n\");\n}\n\nfunction zodShapeToTsFields(\n z: typeof ZodNs,\n shape: Record<string, unknown>,\n gatedKeys: Set<string>,\n): string {\n return Object.entries(shape)\n .map(([key, schema]) => {\n const tsType = zodToTs(z, schema);\n const optional = schema instanceof z.ZodOptional || gatedKeys.has(key);\n return ` readonly ${key}${optional ? \"?\" : \"\"}: ${tsType}`;\n })\n .join(\"\\n\");\n}\n\nfunction zodToTs(z: typeof ZodNs, schema: unknown): string {\n if (schema instanceof z.ZodOptional) return zodToTs(z, schema.unwrap());\n if (schema instanceof z.ZodDefault) return zodToTs(z, schema.def.innerType);\n if (schema instanceof z.ZodString) return \"string\";\n if (schema instanceof z.ZodNumber) return \"number\";\n if (schema instanceof z.ZodBoolean) return \"boolean\";\n if (schema instanceof z.ZodEnum)\n return (schema.options as string[]).map((o) => `'${o}'`).join(\" | \");\n if (schema instanceof z.ZodPipe) return zodToTs(z, schema.def.out);\n return \"string\";\n}\n"],"mappings":";;;;;;;;AAWA,eAAsB,YAAY,KAAoB,MAA6B;CACjF,MAAM,EAAE,MAAM,MAAM,OAAO;CAE3B,MAAM,YAAY,gBAAgB,IAAI;AAItC,OAAM,SAAS,MAHM,mBAAmB,GAAG,EAAE,GAAG,IAAI,QAAQ,EAAE,UAG7B,EAFZ,mBAAmB,GAAG;EAAE,GAAG,IAAI;EAAQ,GAAG,IAAI;EAAQ,EAAE,UAE9B,CAAC;;;;;;AAOlD,SAAS,gBAAgB,KAAiC;CACxD,MAAM,uBAAO,IAAI,KAAa;AAC9B,MAAK,MAAM,UAAU,IAAI,WAAW,EAAE,EAAE;AACtC,MAAI,CAAC,OAAO,OAAQ;AACpB,OAAK,MAAM,QAAQ,CAAC,UAAU,SAAS,CACrC,MAAK,MAAM,CAAC,KAAK,WAAW,OAAO,QAAQ,OAAO,SAAS,EAAE,CAAC,CAC5D,KAAI,IAAI,QAAQ,SAAS,OAAQ,MAAK,IAAI,IAAI;;AAIpD,QAAO;;;;;;AAOT,eAAsB,oBAAoB,KAA4B,MAA6B;CACjG,MAAM,aAAa,OAAO,KAAK,IAAI,UAAU,EAAE,CAAC;CAChD,MAAM,aAAa,CAAC,GAAG,OAAO,KAAK,IAAI,UAAU,EAAE,CAAC,EAAE,GAAG,WAAW;AAKpE,OAAM,SAAS,MAHM,eAAe,WAGH,EAFZ,eAAe,WAEW,EAAE,oBAAoB;;AAGvE,SAAS,YAAY,MAAM,IAAY;CACrC,MAAM,QAAQ;EACZ;EACA;EACA;EACA;EACA,MAAM,uCAAuC,QAAQ;EACrD;EACD;AACD,KAAI,IACF,OAAM,KAAK,oFAAoF;AAEjG,QAAO,MAAM,KAAK,KAAK;;AAGzB,eAAe,SACb,MACA,cACA,cACA,MAAM,IACS;CAGf,MAAM,MAAM,GAFG,YAAY,IAEN,CAAC;;;;EAItB,aAAa;;;;;;;;EAQb,aAAa;;;;;;CAOb,MAAM,WAAW,KAAK,KAAK,MAAM,gBAAgB;AACjD,KAAI;AACF,QAAM,GAAG,UAAU,UAAU,KAAK,QAAQ;UACnC,GAAG;AACV,QAAM,IAAI,MACR,+CAA+C,KAAK,4BACpD,EAAE,OAAO,GAAG,CACb;;;AAIL,SAAS,eAAe,MAAwB;AAC9C,QAAO,KAAK,KAAK,QAAQ,gBAAgB,IAAI,UAAU,CAAC,KAAK,KAAK;;AAGpE,SAAS,mBACP,GACA,OACA,WACQ;AACR,QAAO,OAAO,QAAQ,MAAM,CACzB,KAAK,CAAC,KAAK,YAAY;EACtB,MAAM,SAAS,QAAQ,GAAG,OAAO;AAEjC,SAAO,gBAAgB,MADN,kBAAkB,EAAE,eAAe,UAAU,IAAI,IAAI,GAC9B,MAAM,GAAG,IAAI;GACrD,CACD,KAAK,KAAK;;AAGf,SAAS,QAAQ,GAAiB,QAAyB;AACzD,KAAI,kBAAkB,EAAE,YAAa,QAAO,QAAQ,GAAG,OAAO,QAAQ,CAAC;AACvE,KAAI,kBAAkB,EAAE,WAAY,QAAO,QAAQ,GAAG,OAAO,IAAI,UAAU;AAC3E,KAAI,kBAAkB,EAAE,UAAW,QAAO;AAC1C,KAAI,kBAAkB,EAAE,UAAW,QAAO;AAC1C,KAAI,kBAAkB,EAAE,WAAY,QAAO;AAC3C,KAAI,kBAAkB,EAAE,QACtB,QAAQ,OAAO,QAAqB,KAAK,MAAM,IAAI,EAAE,GAAG,CAAC,KAAK,MAAM;AACtE,KAAI,kBAAkB,EAAE,QAAS,QAAO,QAAQ,GAAG,OAAO,IAAI,IAAI;AAClE,QAAO"}
@@ -1 +1 @@
1
- {"version":3,"file":"format.cjs","names":[],"sources":["../src/format.ts"],"sourcesContent":["import type { core } from 'zod'\nimport type { GuardFail } from './guard'\nimport type { StandardValidationIssue } from './types'\n\nexport function formatZodError(issues: core.$ZodIssue[]): string {\n return issues\n .map((issue) => {\n const path = issue.path.length > 0 ? issue.path.join('.') : '(root)'\n return ` \\x1B[31m✗\\x1B[0m ${path.padEnd(28)} ${issue.message}`\n })\n .join('\\n')\n}\n\nexport function formatStandardSchemaError(issues: StandardValidationIssue[]): string {\n return issues\n .map((issue) => {\n const path = issue.path.length > 0\n ? issue.path.map(seg => typeof seg === 'object' && seg !== null && 'key' in seg ? String(seg.key) : String(seg)).join('.')\n : '(root)'\n return ` \\x1B[31m✗\\x1B[0m ${path.padEnd(28)} ${issue.message}`\n })\n .join('\\n')\n}\n\nconst YELLOW = '\\x1B[33m'\nconst BOLD_YELLOW = '\\x1B[1;33m'\nconst CYAN = '\\x1B[36m'\nconst RESET = '\\x1B[0m'\n\nconst BOX_WIDTH = 66\n// 1 left border + 2 left spaces + content + 1 right border = BOX_WIDTH\n// content area = BOX_WIDTH - 4\nconst CONTENT_AREA = BOX_WIDTH - 4\n\n/** Maximum visible character length for an importer path inside the warning box. */\nexport const IMPORTER_MAX_LEN = CONTENT_AREA - 'Found in: '.length\n\n/**\n * Truncates an importer path to fit within maxLen visible characters.\n * Adds a leading '…' when truncation occurs so the rightmost (most specific) part is preserved.\n */\nexport function truncateImporter(importerPath: string, maxLen: number): string {\n if (importerPath.length <= maxLen)\n return importerPath\n return `\\u2026${importerPath.slice(-(maxLen - 1))}`\n}\n\nfunction boxTop(): string {\n return `${YELLOW}\\u250C${'─'.repeat(BOX_WIDTH - 2)}\\u2510${RESET}`\n}\n\nfunction boxBottom(): string {\n return `${YELLOW}\\u2514${'─'.repeat(BOX_WIDTH - 2)}\\u2518${RESET}`\n}\n\nfunction boxLine(visibleText: string, renderedText = visibleText): string {\n const rightPad = ' '.repeat(Math.max(0, CONTENT_AREA - visibleText.length))\n return `${YELLOW}\\u2502${RESET} ${renderedText}${rightPad}${YELLOW}\\u2502${RESET}`\n}\n\n/**\n * Renders the colored terminal warning box for 'warn' mode.\n * Every line is exactly 66 characters wide (visible chars, excluding ANSI codes),\n * assuming Vite environment names are short (≤19 chars). Longer names will extend\n * the line beyond 66 chars without crashing — Math.max(0) prevents negative padding.\n * Use in logger.warn() calls — not in log files.\n */\nexport function formatGuardWarning(fail: GuardFail): string {\n const importerDisplay = fail.importer === undefined\n ? '(unknown)'\n : truncateImporter(fail.importer, IMPORTER_MAX_LEN)\n\n const warnTitle = 'To enforce now: onClientAccessOfServerModule: \\'error\\''\n const stubTitle = 'To silence: onClientAccessOfServerModule: \\'stub\\''\n\n return [\n boxTop(),\n boxLine(\n '[vite-env] DEPRECATION WARNING',\n `${BOLD_YELLOW}[vite-env] DEPRECATION WARNING${RESET}`,\n ),\n boxLine(''),\n boxLine(`virtual:env/server was imported from the \"${fail.envName}\"`),\n boxLine('environment. This will be a hard build error in 1.0.0.'),\n boxLine(''),\n boxLine(warnTitle, `To enforce now: ${CYAN}onClientAccessOfServerModule: 'error'${RESET}`),\n boxLine(stubTitle, `To silence: ${CYAN}onClientAccessOfServerModule: 'stub'${RESET}`),\n boxLine(''),\n boxLine(`Found in: ${importerDisplay}`),\n boxBottom(),\n ].join('\\n')\n}\n\n/**\n * Renders the plain-text hard error message thrown in 'error' mode.\n * No ANSI — thrown as an Error message, not printed via logger.\n */\nexport function formatHardError(fail: GuardFail): string {\n const importerLine = fail.importer ?? '(unknown)'\n return [\n `[vite-env] virtual:env/server is not available in the \"${fail.envName}\" environment.`,\n ``,\n ` Server-only modules cannot be imported from client code.`,\n ` Add this environment to serverEnvironments if intentional:`,\n ``,\n ` ViteEnv({ serverEnvironments: ['ssr', '${fail.envName}'] })`,\n ``,\n ` Or change enforcement:`,\n ``,\n ` ViteEnv({ onClientAccessOfServerModule: 'stub' })`,\n ``,\n ` Imported from: ${importerLine}`,\n ].join('\\n')\n}\n\n/**\n * Renders a single ANSI-free log entry for vite-env-warnings.log.\n * Uses the same (unknown) convention as formatGuardWarning for missing importers.\n */\nexport function formatGuardLogEntry(fail: GuardFail, timestamp: string): string {\n const importerLine = fail.importer ?? '(unknown)'\n return [\n `[${timestamp}] virtual:env/server accessed from \"${fail.envName}\" environment`,\n ` Importer: ${importerLine}`,\n ].join('\\n')\n}\n"],"mappings":";;AAIA,SAAgB,eAAe,QAAkC;AAC/D,QAAO,OACJ,KAAK,UAAU;AAEd,SAAO,uBADM,MAAM,KAAK,SAAS,IAAI,MAAM,KAAK,KAAK,IAAI,GAAG,UAC1B,OAAO,GAAG,CAAC,GAAG,MAAM;GACtD,CACD,KAAK,KAAK;;AAGf,SAAgB,0BAA0B,QAA2C;AACnF,QAAO,OACJ,KAAK,UAAU;AAId,SAAO,uBAHM,MAAM,KAAK,SAAS,IAC7B,MAAM,KAAK,KAAI,QAAO,OAAO,QAAQ,YAAY,QAAQ,QAAQ,SAAS,MAAM,OAAO,IAAI,IAAI,GAAG,OAAO,IAAI,CAAC,CAAC,KAAK,IAAI,GACxH,UAC8B,OAAO,GAAG,CAAC,GAAG,MAAM;GACtD,CACD,KAAK,KAAK;;AAGf,MAAM,SAAS;AACf,MAAM,cAAc;AACpB,MAAM,OAAO;AACb,MAAM,QAAQ;AAEd,MAAM,YAAY;AAGlB,MAAM,eAAe,YAAY;;AAGjC,MAAa,mBAAmB,eAAe;;;;;AAM/C,SAAgB,iBAAiB,cAAsB,QAAwB;AAC7E,KAAI,aAAa,UAAU,OACzB,QAAO;AACT,QAAO,SAAS,aAAa,MAAM,EAAE,SAAS,GAAG;;AAGnD,SAAS,SAAiB;AACxB,QAAO,GAAG,OAAO,QAAQ,IAAI,OAAO,YAAY,EAAE,CAAC,QAAQ;;AAG7D,SAAS,YAAoB;AAC3B,QAAO,GAAG,OAAO,QAAQ,IAAI,OAAO,YAAY,EAAE,CAAC,QAAQ;;AAG7D,SAAS,QAAQ,aAAqB,eAAe,aAAqB;AAExE,QAAO,GAAG,OAAO,QAAQ,MAAM,IAAI,eADlB,IAAI,OAAO,KAAK,IAAI,GAAG,eAAe,YAAY,OAAO,CAChB,GAAG,OAAO,QAAQ;;;;;;;;;AAU9E,SAAgB,mBAAmB,MAAyB;CAC1D,MAAM,kBAAkB,KAAK,aAAa,KAAA,IACtC,cACA,iBAAiB,KAAK,UAAA,GAA2B;AAKrD,QAAO;EACL,QAAQ;EACR,QACE,kCACA,GAAG,YAAY,gCAAgC,QAChD;EACD,QAAQ,GAAG;EACX,QAAQ,6CAA6C,KAAK,QAAQ,GAAG;EACrE,QAAQ,yDAAyD;EACjE,QAAQ,GAAG;EACX,QAAQ,0DAAW,oBAAoB,KAAK,uCAAuC,QAAQ;EAC3F,QAAQ,yDAAW,oBAAoB,KAAK,sCAAsC,QAAQ;EAC1F,QAAQ,GAAG;EACX,QAAQ,aAAa,kBAAkB;EACvC,WAAW;EACZ,CAAC,KAAK,KAAK;;;;;;AAOd,SAAgB,gBAAgB,MAAyB;CACvD,MAAM,eAAe,KAAK,YAAY;AACtC,QAAO;EACL,0DAA0D,KAAK,QAAQ;EACvE;EACA;EACA;EACA;EACA,8CAA8C,KAAK,QAAQ;EAC3D;EACA;EACA;EACA;EACA;EACA,oBAAoB;EACrB,CAAC,KAAK,KAAK;;;;;;AAOd,SAAgB,oBAAoB,MAAiB,WAA2B;CAC9E,MAAM,eAAe,KAAK,YAAY;AACtC,QAAO,CACL,IAAI,UAAU,sCAAsC,KAAK,QAAQ,gBACjE,eAAe,eAChB,CAAC,KAAK,KAAK"}
1
+ {"version":3,"file":"format.cjs","names":[],"sources":["../src/format.ts"],"sourcesContent":["import type { core } from \"zod\";\nimport type { GuardFail } from \"./guard\";\nimport type { StandardValidationIssue } from \"./types\";\n\nexport function formatZodError(issues: core.$ZodIssue[]): string {\n return issues\n .map((issue) => {\n const path = issue.path.length > 0 ? issue.path.join(\".\") : \"(root)\";\n return ` \\x1B[31m✗\\x1B[0m ${path.padEnd(28)} ${issue.message}`;\n })\n .join(\"\\n\");\n}\n\nexport function formatStandardSchemaError(issues: StandardValidationIssue[]): string {\n return issues\n .map((issue) => {\n const path =\n issue.path.length > 0\n ? issue.path\n .map((seg) =>\n typeof seg === \"object\" && seg !== null && \"key\" in seg\n ? String(seg.key)\n : String(seg),\n )\n .join(\".\")\n : \"(root)\";\n return ` \\x1B[31m✗\\x1B[0m ${path.padEnd(28)} ${issue.message}`;\n })\n .join(\"\\n\");\n}\n\nconst YELLOW = \"\\x1B[33m\";\nconst BOLD_YELLOW = \"\\x1B[1;33m\";\nconst CYAN = \"\\x1B[36m\";\nconst RESET = \"\\x1B[0m\";\n\nconst BOX_WIDTH = 66;\n// 1 left border + 2 left spaces + content + 1 right border = BOX_WIDTH\n// content area = BOX_WIDTH - 4\nconst CONTENT_AREA = BOX_WIDTH - 4;\n\n/** Maximum visible character length for an importer path inside the warning box. */\nexport const IMPORTER_MAX_LEN = CONTENT_AREA - \"Found in: \".length;\n\n/**\n * Truncates an importer path to fit within maxLen visible characters.\n * Adds a leading '…' when truncation occurs so the rightmost (most specific) part is preserved.\n */\nexport function truncateImporter(importerPath: string, maxLen: number): string {\n if (importerPath.length <= maxLen) return importerPath;\n return `\\u2026${importerPath.slice(-(maxLen - 1))}`;\n}\n\nfunction boxTop(): string {\n return `${YELLOW}\\u250C${\"─\".repeat(BOX_WIDTH - 2)}\\u2510${RESET}`;\n}\n\nfunction boxBottom(): string {\n return `${YELLOW}\\u2514${\"─\".repeat(BOX_WIDTH - 2)}\\u2518${RESET}`;\n}\n\nfunction boxLine(visibleText: string, renderedText = visibleText): string {\n const rightPad = \" \".repeat(Math.max(0, CONTENT_AREA - visibleText.length));\n return `${YELLOW}\\u2502${RESET} ${renderedText}${rightPad}${YELLOW}\\u2502${RESET}`;\n}\n\n/**\n * Renders the colored terminal warning box for 'warn' mode.\n * Every line is exactly 66 characters wide (visible chars, excluding ANSI codes),\n * assuming Vite environment names are short (≤19 chars). Longer names will extend\n * the line beyond 66 chars without crashing — Math.max(0) prevents negative padding.\n * Use in logger.warn() calls — not in log files.\n */\nexport function formatGuardWarning(fail: GuardFail): string {\n const importerDisplay =\n fail.importer === undefined ? \"(unknown)\" : truncateImporter(fail.importer, IMPORTER_MAX_LEN);\n\n const warnTitle = \"To enforce now: onClientAccessOfServerModule: 'error'\";\n const stubTitle = \"To silence: onClientAccessOfServerModule: 'stub'\";\n\n return [\n boxTop(),\n boxLine(\n \"[vite-env] DEPRECATION WARNING\",\n `${BOLD_YELLOW}[vite-env] DEPRECATION WARNING${RESET}`,\n ),\n boxLine(\"\"),\n boxLine(`virtual:env/server was imported from the \"${fail.envName}\"`),\n boxLine(\"environment. This will be a hard build error in 1.0.0.\"),\n boxLine(\"\"),\n boxLine(warnTitle, `To enforce now: ${CYAN}onClientAccessOfServerModule: 'error'${RESET}`),\n boxLine(stubTitle, `To silence: ${CYAN}onClientAccessOfServerModule: 'stub'${RESET}`),\n boxLine(\"\"),\n boxLine(`Found in: ${importerDisplay}`),\n boxBottom(),\n ].join(\"\\n\");\n}\n\n/**\n * Renders the plain-text hard error message thrown in 'error' mode.\n * No ANSI — thrown as an Error message, not printed via logger.\n */\nexport function formatHardError(fail: GuardFail): string {\n const importerLine = fail.importer ?? \"(unknown)\";\n return [\n `[vite-env] virtual:env/server is not available in the \"${fail.envName}\" environment.`,\n ``,\n ` Server-only modules cannot be imported from client code.`,\n ` Add this environment to serverEnvironments if intentional:`,\n ``,\n ` ViteEnv({ serverEnvironments: ['ssr', '${fail.envName}'] })`,\n ``,\n ` Or change enforcement:`,\n ``,\n ` ViteEnv({ onClientAccessOfServerModule: 'stub' })`,\n ``,\n ` Imported from: ${importerLine}`,\n ].join(\"\\n\");\n}\n\n/**\n * Renders a single ANSI-free log entry for vite-env-warnings.log.\n * Uses the same (unknown) convention as formatGuardWarning for missing importers.\n */\nexport function formatGuardLogEntry(fail: GuardFail, timestamp: string): string {\n const importerLine = fail.importer ?? \"(unknown)\";\n return [\n `[${timestamp}] virtual:env/server accessed from \"${fail.envName}\" environment`,\n ` Importer: ${importerLine}`,\n ].join(\"\\n\");\n}\n"],"mappings":";;AAIA,SAAgB,eAAe,QAAkC;AAC/D,QAAO,OACJ,KAAK,UAAU;AAEd,SAAO,uBADM,MAAM,KAAK,SAAS,IAAI,MAAM,KAAK,KAAK,IAAI,GAAG,UAC1B,OAAO,GAAG,CAAC,GAAG,MAAM;GACtD,CACD,KAAK,KAAK;;AAGf,SAAgB,0BAA0B,QAA2C;AACnF,QAAO,OACJ,KAAK,UAAU;AAWd,SAAO,uBATL,MAAM,KAAK,SAAS,IAChB,MAAM,KACH,KAAK,QACJ,OAAO,QAAQ,YAAY,QAAQ,QAAQ,SAAS,MAChD,OAAO,IAAI,IAAI,GACf,OAAO,IAAI,CAChB,CACA,KAAK,IAAI,GACZ,UAC4B,OAAO,GAAG,CAAC,GAAG,MAAM;GACtD,CACD,KAAK,KAAK;;AAGf,MAAM,SAAS;AACf,MAAM,cAAc;AACpB,MAAM,OAAO;AACb,MAAM,QAAQ;AAEd,MAAM,YAAY;AAGlB,MAAM,eAAe,YAAY;;AAGjC,MAAa,mBAAmB,eAAe;;;;;AAM/C,SAAgB,iBAAiB,cAAsB,QAAwB;AAC7E,KAAI,aAAa,UAAU,OAAQ,QAAO;AAC1C,QAAO,SAAS,aAAa,MAAM,EAAE,SAAS,GAAG;;AAGnD,SAAS,SAAiB;AACxB,QAAO,GAAG,OAAO,QAAQ,IAAI,OAAO,YAAY,EAAE,CAAC,QAAQ;;AAG7D,SAAS,YAAoB;AAC3B,QAAO,GAAG,OAAO,QAAQ,IAAI,OAAO,YAAY,EAAE,CAAC,QAAQ;;AAG7D,SAAS,QAAQ,aAAqB,eAAe,aAAqB;AAExE,QAAO,GAAG,OAAO,QAAQ,MAAM,IAAI,eADlB,IAAI,OAAO,KAAK,IAAI,GAAG,eAAe,YAAY,OAAO,CAChB,GAAG,OAAO,QAAQ;;;;;;;;;AAU9E,SAAgB,mBAAmB,MAAyB;CAC1D,MAAM,kBACJ,KAAK,aAAa,KAAA,IAAY,cAAc,iBAAiB,KAAK,UAAA,GAA2B;AAK/F,QAAO;EACL,QAAQ;EACR,QACE,kCACA,GAAG,YAAY,gCAAgC,QAChD;EACD,QAAQ,GAAG;EACX,QAAQ,6CAA6C,KAAK,QAAQ,GAAG;EACrE,QAAQ,yDAAyD;EACjE,QAAQ,GAAG;EACX,QAAQ,0DAAW,oBAAoB,KAAK,uCAAuC,QAAQ;EAC3F,QAAQ,yDAAW,oBAAoB,KAAK,sCAAsC,QAAQ;EAC1F,QAAQ,GAAG;EACX,QAAQ,aAAa,kBAAkB;EACvC,WAAW;EACZ,CAAC,KAAK,KAAK;;;;;;AAOd,SAAgB,gBAAgB,MAAyB;CACvD,MAAM,eAAe,KAAK,YAAY;AACtC,QAAO;EACL,0DAA0D,KAAK,QAAQ;EACvE;EACA;EACA;EACA;EACA,8CAA8C,KAAK,QAAQ;EAC3D;EACA;EACA;EACA;EACA;EACA,oBAAoB;EACrB,CAAC,KAAK,KAAK;;;;;;AAOd,SAAgB,oBAAoB,MAAiB,WAA2B;CAC9E,MAAM,eAAe,KAAK,YAAY;AACtC,QAAO,CACL,IAAI,UAAU,sCAAsC,KAAK,QAAQ,gBACjE,eAAe,eAChB,CAAC,KAAK,KAAK"}
package/dist/format.d.cts CHANGED
@@ -1,8 +1,8 @@
1
- import { s as StandardValidationIssue } from "./types-B61nsO8q.cjs";
1
+ import { s as StandardValidationIssue } from "./types-DudMh278.cjs";
2
2
  import { core } from "zod";
3
3
 
4
4
  //#region src/guard.d.ts
5
- type GuardMode = 'error' | 'stub' | 'warn';
5
+ type GuardMode = "error" | "stub" | "warn";
6
6
  type GuardResult = {
7
7
  allowed: true;
8
8
  } | {
package/dist/format.d.mts CHANGED
@@ -1,8 +1,8 @@
1
- import { s as StandardValidationIssue } from "./types-KniR_Oqf.mjs";
1
+ import { s as StandardValidationIssue } from "./types-Ctg8aeXQ.mjs";
2
2
  import { core } from "zod";
3
3
 
4
4
  //#region src/guard.d.ts
5
- type GuardMode = 'error' | 'stub' | 'warn';
5
+ type GuardMode = "error" | "stub" | "warn";
6
6
  type GuardResult = {
7
7
  allowed: true;
8
8
  } | {
@@ -1 +1 @@
1
- {"version":3,"file":"format.mjs","names":[],"sources":["../src/format.ts"],"sourcesContent":["import type { core } from 'zod'\nimport type { GuardFail } from './guard'\nimport type { StandardValidationIssue } from './types'\n\nexport function formatZodError(issues: core.$ZodIssue[]): string {\n return issues\n .map((issue) => {\n const path = issue.path.length > 0 ? issue.path.join('.') : '(root)'\n return ` \\x1B[31m✗\\x1B[0m ${path.padEnd(28)} ${issue.message}`\n })\n .join('\\n')\n}\n\nexport function formatStandardSchemaError(issues: StandardValidationIssue[]): string {\n return issues\n .map((issue) => {\n const path = issue.path.length > 0\n ? issue.path.map(seg => typeof seg === 'object' && seg !== null && 'key' in seg ? String(seg.key) : String(seg)).join('.')\n : '(root)'\n return ` \\x1B[31m✗\\x1B[0m ${path.padEnd(28)} ${issue.message}`\n })\n .join('\\n')\n}\n\nconst YELLOW = '\\x1B[33m'\nconst BOLD_YELLOW = '\\x1B[1;33m'\nconst CYAN = '\\x1B[36m'\nconst RESET = '\\x1B[0m'\n\nconst BOX_WIDTH = 66\n// 1 left border + 2 left spaces + content + 1 right border = BOX_WIDTH\n// content area = BOX_WIDTH - 4\nconst CONTENT_AREA = BOX_WIDTH - 4\n\n/** Maximum visible character length for an importer path inside the warning box. */\nexport const IMPORTER_MAX_LEN = CONTENT_AREA - 'Found in: '.length\n\n/**\n * Truncates an importer path to fit within maxLen visible characters.\n * Adds a leading '…' when truncation occurs so the rightmost (most specific) part is preserved.\n */\nexport function truncateImporter(importerPath: string, maxLen: number): string {\n if (importerPath.length <= maxLen)\n return importerPath\n return `\\u2026${importerPath.slice(-(maxLen - 1))}`\n}\n\nfunction boxTop(): string {\n return `${YELLOW}\\u250C${'─'.repeat(BOX_WIDTH - 2)}\\u2510${RESET}`\n}\n\nfunction boxBottom(): string {\n return `${YELLOW}\\u2514${'─'.repeat(BOX_WIDTH - 2)}\\u2518${RESET}`\n}\n\nfunction boxLine(visibleText: string, renderedText = visibleText): string {\n const rightPad = ' '.repeat(Math.max(0, CONTENT_AREA - visibleText.length))\n return `${YELLOW}\\u2502${RESET} ${renderedText}${rightPad}${YELLOW}\\u2502${RESET}`\n}\n\n/**\n * Renders the colored terminal warning box for 'warn' mode.\n * Every line is exactly 66 characters wide (visible chars, excluding ANSI codes),\n * assuming Vite environment names are short (≤19 chars). Longer names will extend\n * the line beyond 66 chars without crashing — Math.max(0) prevents negative padding.\n * Use in logger.warn() calls — not in log files.\n */\nexport function formatGuardWarning(fail: GuardFail): string {\n const importerDisplay = fail.importer === undefined\n ? '(unknown)'\n : truncateImporter(fail.importer, IMPORTER_MAX_LEN)\n\n const warnTitle = 'To enforce now: onClientAccessOfServerModule: \\'error\\''\n const stubTitle = 'To silence: onClientAccessOfServerModule: \\'stub\\''\n\n return [\n boxTop(),\n boxLine(\n '[vite-env] DEPRECATION WARNING',\n `${BOLD_YELLOW}[vite-env] DEPRECATION WARNING${RESET}`,\n ),\n boxLine(''),\n boxLine(`virtual:env/server was imported from the \"${fail.envName}\"`),\n boxLine('environment. This will be a hard build error in 1.0.0.'),\n boxLine(''),\n boxLine(warnTitle, `To enforce now: ${CYAN}onClientAccessOfServerModule: 'error'${RESET}`),\n boxLine(stubTitle, `To silence: ${CYAN}onClientAccessOfServerModule: 'stub'${RESET}`),\n boxLine(''),\n boxLine(`Found in: ${importerDisplay}`),\n boxBottom(),\n ].join('\\n')\n}\n\n/**\n * Renders the plain-text hard error message thrown in 'error' mode.\n * No ANSI — thrown as an Error message, not printed via logger.\n */\nexport function formatHardError(fail: GuardFail): string {\n const importerLine = fail.importer ?? '(unknown)'\n return [\n `[vite-env] virtual:env/server is not available in the \"${fail.envName}\" environment.`,\n ``,\n ` Server-only modules cannot be imported from client code.`,\n ` Add this environment to serverEnvironments if intentional:`,\n ``,\n ` ViteEnv({ serverEnvironments: ['ssr', '${fail.envName}'] })`,\n ``,\n ` Or change enforcement:`,\n ``,\n ` ViteEnv({ onClientAccessOfServerModule: 'stub' })`,\n ``,\n ` Imported from: ${importerLine}`,\n ].join('\\n')\n}\n\n/**\n * Renders a single ANSI-free log entry for vite-env-warnings.log.\n * Uses the same (unknown) convention as formatGuardWarning for missing importers.\n */\nexport function formatGuardLogEntry(fail: GuardFail, timestamp: string): string {\n const importerLine = fail.importer ?? '(unknown)'\n return [\n `[${timestamp}] virtual:env/server accessed from \"${fail.envName}\" environment`,\n ` Importer: ${importerLine}`,\n ].join('\\n')\n}\n"],"mappings":";AAIA,SAAgB,eAAe,QAAkC;AAC/D,QAAO,OACJ,KAAK,UAAU;AAEd,SAAO,uBADM,MAAM,KAAK,SAAS,IAAI,MAAM,KAAK,KAAK,IAAI,GAAG,UAC1B,OAAO,GAAG,CAAC,GAAG,MAAM;GACtD,CACD,KAAK,KAAK;;AAGf,SAAgB,0BAA0B,QAA2C;AACnF,QAAO,OACJ,KAAK,UAAU;AAId,SAAO,uBAHM,MAAM,KAAK,SAAS,IAC7B,MAAM,KAAK,KAAI,QAAO,OAAO,QAAQ,YAAY,QAAQ,QAAQ,SAAS,MAAM,OAAO,IAAI,IAAI,GAAG,OAAO,IAAI,CAAC,CAAC,KAAK,IAAI,GACxH,UAC8B,OAAO,GAAG,CAAC,GAAG,MAAM;GACtD,CACD,KAAK,KAAK;;AAGf,MAAM,SAAS;AACf,MAAM,cAAc;AACpB,MAAM,OAAO;AACb,MAAM,QAAQ;AAEd,MAAM,YAAY;AAGlB,MAAM,eAAe,YAAY;;AAGjC,MAAa,mBAAmB,eAAe;;;;;AAM/C,SAAgB,iBAAiB,cAAsB,QAAwB;AAC7E,KAAI,aAAa,UAAU,OACzB,QAAO;AACT,QAAO,SAAS,aAAa,MAAM,EAAE,SAAS,GAAG;;AAGnD,SAAS,SAAiB;AACxB,QAAO,GAAG,OAAO,QAAQ,IAAI,OAAO,YAAY,EAAE,CAAC,QAAQ;;AAG7D,SAAS,YAAoB;AAC3B,QAAO,GAAG,OAAO,QAAQ,IAAI,OAAO,YAAY,EAAE,CAAC,QAAQ;;AAG7D,SAAS,QAAQ,aAAqB,eAAe,aAAqB;AAExE,QAAO,GAAG,OAAO,QAAQ,MAAM,IAAI,eADlB,IAAI,OAAO,KAAK,IAAI,GAAG,eAAe,YAAY,OAAO,CAChB,GAAG,OAAO,QAAQ;;;;;;;;;AAU9E,SAAgB,mBAAmB,MAAyB;CAC1D,MAAM,kBAAkB,KAAK,aAAa,KAAA,IACtC,cACA,iBAAiB,KAAK,UAAA,GAA2B;AAKrD,QAAO;EACL,QAAQ;EACR,QACE,kCACA,GAAG,YAAY,gCAAgC,QAChD;EACD,QAAQ,GAAG;EACX,QAAQ,6CAA6C,KAAK,QAAQ,GAAG;EACrE,QAAQ,yDAAyD;EACjE,QAAQ,GAAG;EACX,QAAQ,0DAAW,oBAAoB,KAAK,uCAAuC,QAAQ;EAC3F,QAAQ,yDAAW,oBAAoB,KAAK,sCAAsC,QAAQ;EAC1F,QAAQ,GAAG;EACX,QAAQ,aAAa,kBAAkB;EACvC,WAAW;EACZ,CAAC,KAAK,KAAK;;;;;;AAOd,SAAgB,gBAAgB,MAAyB;CACvD,MAAM,eAAe,KAAK,YAAY;AACtC,QAAO;EACL,0DAA0D,KAAK,QAAQ;EACvE;EACA;EACA;EACA;EACA,8CAA8C,KAAK,QAAQ;EAC3D;EACA;EACA;EACA;EACA;EACA,oBAAoB;EACrB,CAAC,KAAK,KAAK;;;;;;AAOd,SAAgB,oBAAoB,MAAiB,WAA2B;CAC9E,MAAM,eAAe,KAAK,YAAY;AACtC,QAAO,CACL,IAAI,UAAU,sCAAsC,KAAK,QAAQ,gBACjE,eAAe,eAChB,CAAC,KAAK,KAAK"}
1
+ {"version":3,"file":"format.mjs","names":[],"sources":["../src/format.ts"],"sourcesContent":["import type { core } from \"zod\";\nimport type { GuardFail } from \"./guard\";\nimport type { StandardValidationIssue } from \"./types\";\n\nexport function formatZodError(issues: core.$ZodIssue[]): string {\n return issues\n .map((issue) => {\n const path = issue.path.length > 0 ? issue.path.join(\".\") : \"(root)\";\n return ` \\x1B[31m✗\\x1B[0m ${path.padEnd(28)} ${issue.message}`;\n })\n .join(\"\\n\");\n}\n\nexport function formatStandardSchemaError(issues: StandardValidationIssue[]): string {\n return issues\n .map((issue) => {\n const path =\n issue.path.length > 0\n ? issue.path\n .map((seg) =>\n typeof seg === \"object\" && seg !== null && \"key\" in seg\n ? String(seg.key)\n : String(seg),\n )\n .join(\".\")\n : \"(root)\";\n return ` \\x1B[31m✗\\x1B[0m ${path.padEnd(28)} ${issue.message}`;\n })\n .join(\"\\n\");\n}\n\nconst YELLOW = \"\\x1B[33m\";\nconst BOLD_YELLOW = \"\\x1B[1;33m\";\nconst CYAN = \"\\x1B[36m\";\nconst RESET = \"\\x1B[0m\";\n\nconst BOX_WIDTH = 66;\n// 1 left border + 2 left spaces + content + 1 right border = BOX_WIDTH\n// content area = BOX_WIDTH - 4\nconst CONTENT_AREA = BOX_WIDTH - 4;\n\n/** Maximum visible character length for an importer path inside the warning box. */\nexport const IMPORTER_MAX_LEN = CONTENT_AREA - \"Found in: \".length;\n\n/**\n * Truncates an importer path to fit within maxLen visible characters.\n * Adds a leading '…' when truncation occurs so the rightmost (most specific) part is preserved.\n */\nexport function truncateImporter(importerPath: string, maxLen: number): string {\n if (importerPath.length <= maxLen) return importerPath;\n return `\\u2026${importerPath.slice(-(maxLen - 1))}`;\n}\n\nfunction boxTop(): string {\n return `${YELLOW}\\u250C${\"─\".repeat(BOX_WIDTH - 2)}\\u2510${RESET}`;\n}\n\nfunction boxBottom(): string {\n return `${YELLOW}\\u2514${\"─\".repeat(BOX_WIDTH - 2)}\\u2518${RESET}`;\n}\n\nfunction boxLine(visibleText: string, renderedText = visibleText): string {\n const rightPad = \" \".repeat(Math.max(0, CONTENT_AREA - visibleText.length));\n return `${YELLOW}\\u2502${RESET} ${renderedText}${rightPad}${YELLOW}\\u2502${RESET}`;\n}\n\n/**\n * Renders the colored terminal warning box for 'warn' mode.\n * Every line is exactly 66 characters wide (visible chars, excluding ANSI codes),\n * assuming Vite environment names are short (≤19 chars). Longer names will extend\n * the line beyond 66 chars without crashing — Math.max(0) prevents negative padding.\n * Use in logger.warn() calls — not in log files.\n */\nexport function formatGuardWarning(fail: GuardFail): string {\n const importerDisplay =\n fail.importer === undefined ? \"(unknown)\" : truncateImporter(fail.importer, IMPORTER_MAX_LEN);\n\n const warnTitle = \"To enforce now: onClientAccessOfServerModule: 'error'\";\n const stubTitle = \"To silence: onClientAccessOfServerModule: 'stub'\";\n\n return [\n boxTop(),\n boxLine(\n \"[vite-env] DEPRECATION WARNING\",\n `${BOLD_YELLOW}[vite-env] DEPRECATION WARNING${RESET}`,\n ),\n boxLine(\"\"),\n boxLine(`virtual:env/server was imported from the \"${fail.envName}\"`),\n boxLine(\"environment. This will be a hard build error in 1.0.0.\"),\n boxLine(\"\"),\n boxLine(warnTitle, `To enforce now: ${CYAN}onClientAccessOfServerModule: 'error'${RESET}`),\n boxLine(stubTitle, `To silence: ${CYAN}onClientAccessOfServerModule: 'stub'${RESET}`),\n boxLine(\"\"),\n boxLine(`Found in: ${importerDisplay}`),\n boxBottom(),\n ].join(\"\\n\");\n}\n\n/**\n * Renders the plain-text hard error message thrown in 'error' mode.\n * No ANSI — thrown as an Error message, not printed via logger.\n */\nexport function formatHardError(fail: GuardFail): string {\n const importerLine = fail.importer ?? \"(unknown)\";\n return [\n `[vite-env] virtual:env/server is not available in the \"${fail.envName}\" environment.`,\n ``,\n ` Server-only modules cannot be imported from client code.`,\n ` Add this environment to serverEnvironments if intentional:`,\n ``,\n ` ViteEnv({ serverEnvironments: ['ssr', '${fail.envName}'] })`,\n ``,\n ` Or change enforcement:`,\n ``,\n ` ViteEnv({ onClientAccessOfServerModule: 'stub' })`,\n ``,\n ` Imported from: ${importerLine}`,\n ].join(\"\\n\");\n}\n\n/**\n * Renders a single ANSI-free log entry for vite-env-warnings.log.\n * Uses the same (unknown) convention as formatGuardWarning for missing importers.\n */\nexport function formatGuardLogEntry(fail: GuardFail, timestamp: string): string {\n const importerLine = fail.importer ?? \"(unknown)\";\n return [\n `[${timestamp}] virtual:env/server accessed from \"${fail.envName}\" environment`,\n ` Importer: ${importerLine}`,\n ].join(\"\\n\");\n}\n"],"mappings":";AAIA,SAAgB,eAAe,QAAkC;AAC/D,QAAO,OACJ,KAAK,UAAU;AAEd,SAAO,uBADM,MAAM,KAAK,SAAS,IAAI,MAAM,KAAK,KAAK,IAAI,GAAG,UAC1B,OAAO,GAAG,CAAC,GAAG,MAAM;GACtD,CACD,KAAK,KAAK;;AAGf,SAAgB,0BAA0B,QAA2C;AACnF,QAAO,OACJ,KAAK,UAAU;AAWd,SAAO,uBATL,MAAM,KAAK,SAAS,IAChB,MAAM,KACH,KAAK,QACJ,OAAO,QAAQ,YAAY,QAAQ,QAAQ,SAAS,MAChD,OAAO,IAAI,IAAI,GACf,OAAO,IAAI,CAChB,CACA,KAAK,IAAI,GACZ,UAC4B,OAAO,GAAG,CAAC,GAAG,MAAM;GACtD,CACD,KAAK,KAAK;;AAGf,MAAM,SAAS;AACf,MAAM,cAAc;AACpB,MAAM,OAAO;AACb,MAAM,QAAQ;AAEd,MAAM,YAAY;AAGlB,MAAM,eAAe,YAAY;;AAGjC,MAAa,mBAAmB,eAAe;;;;;AAM/C,SAAgB,iBAAiB,cAAsB,QAAwB;AAC7E,KAAI,aAAa,UAAU,OAAQ,QAAO;AAC1C,QAAO,SAAS,aAAa,MAAM,EAAE,SAAS,GAAG;;AAGnD,SAAS,SAAiB;AACxB,QAAO,GAAG,OAAO,QAAQ,IAAI,OAAO,YAAY,EAAE,CAAC,QAAQ;;AAG7D,SAAS,YAAoB;AAC3B,QAAO,GAAG,OAAO,QAAQ,IAAI,OAAO,YAAY,EAAE,CAAC,QAAQ;;AAG7D,SAAS,QAAQ,aAAqB,eAAe,aAAqB;AAExE,QAAO,GAAG,OAAO,QAAQ,MAAM,IAAI,eADlB,IAAI,OAAO,KAAK,IAAI,GAAG,eAAe,YAAY,OAAO,CAChB,GAAG,OAAO,QAAQ;;;;;;;;;AAU9E,SAAgB,mBAAmB,MAAyB;CAC1D,MAAM,kBACJ,KAAK,aAAa,KAAA,IAAY,cAAc,iBAAiB,KAAK,UAAA,GAA2B;AAK/F,QAAO;EACL,QAAQ;EACR,QACE,kCACA,GAAG,YAAY,gCAAgC,QAChD;EACD,QAAQ,GAAG;EACX,QAAQ,6CAA6C,KAAK,QAAQ,GAAG;EACrE,QAAQ,yDAAyD;EACjE,QAAQ,GAAG;EACX,QAAQ,0DAAW,oBAAoB,KAAK,uCAAuC,QAAQ;EAC3F,QAAQ,yDAAW,oBAAoB,KAAK,sCAAsC,QAAQ;EAC1F,QAAQ,GAAG;EACX,QAAQ,aAAa,kBAAkB;EACvC,WAAW;EACZ,CAAC,KAAK,KAAK;;;;;;AAOd,SAAgB,gBAAgB,MAAyB;CACvD,MAAM,eAAe,KAAK,YAAY;AACtC,QAAO;EACL,0DAA0D,KAAK,QAAQ;EACvE;EACA;EACA;EACA;EACA,8CAA8C,KAAK,QAAQ;EAC3D;EACA;EACA;EACA;EACA;EACA,oBAAoB;EACrB,CAAC,KAAK,KAAK;;;;;;AAOd,SAAgB,oBAAoB,MAAiB,WAA2B;CAC9E,MAAM,eAAe,KAAK,YAAY;AACtC,QAAO,CACL,IAAI,UAAU,sCAAsC,KAAK,QAAQ,gBACjE,eAAe,eAChB,CAAC,KAAK,KAAK"}
package/dist/index.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- import { a as InferServerEnv, i as InferClientEnv, n as EnvDefinition, o as StandardEnvDefinition, r as EnvPreset, t as AnyEnvDefinition } from "./types-B61nsO8q.cjs";
1
+ import { a as InferServerEnv, i as InferClientEnv, n as EnvDefinition, o as StandardEnvDefinition, r as EnvPreset, t as AnyEnvDefinition } from "./types-DudMh278.cjs";
2
2
  import { defineEnv } from "./schema.cjs";
3
3
  import { defineStandardEnv } from "./standard.cjs";
4
4
  export { type AnyEnvDefinition, type EnvDefinition, type EnvPreset, type InferClientEnv, type InferServerEnv, type StandardEnvDefinition, defineEnv, defineStandardEnv };
package/dist/index.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import { a as InferServerEnv, i as InferClientEnv, n as EnvDefinition, o as StandardEnvDefinition, r as EnvPreset, t as AnyEnvDefinition } from "./types-KniR_Oqf.mjs";
1
+ import { a as InferServerEnv, i as InferClientEnv, n as EnvDefinition, o as StandardEnvDefinition, r as EnvPreset, t as AnyEnvDefinition } from "./types-Ctg8aeXQ.mjs";
2
2
  import { defineEnv } from "./schema.mjs";
3
3
  import { defineStandardEnv } from "./standard.mjs";
4
4
  export { type AnyEnvDefinition, type EnvDefinition, type EnvPreset, type InferClientEnv, type InferServerEnv, type StandardEnvDefinition, defineEnv, defineStandardEnv };
package/dist/leak.cjs CHANGED
@@ -1,12 +1,9 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  //#region src/leak.ts
3
3
  /**
4
- * Scans all client-destined chunks for literal values of server-only vars.
5
- * Fires in generateBundle()Rolldown sequential hook, safe.
6
- *
7
- * Strategy: for each server-only key, check if its actual runtime value
8
- * appears as a literal string in any output chunk's source code.
9
- * Short/common values (< 8 chars) are skipped to avoid false positives.
4
+ * Scans client-destined chunks for server-only var values appearing as quoted
5
+ * string literals. Bare substring matches are ignored only quoted literals
6
+ * indicate a real bundler-inlined leak. Values < 8 chars are skipped.
10
7
  */
11
8
  function detectServerLeak(def, data, bundle, onSkipped) {
12
9
  const serverKeys = new Set(Object.keys(def.server ?? {}));
@@ -15,10 +12,14 @@ function detectServerLeak(def, data, bundle, onSkipped) {
15
12
  const serverSecrets = Object.entries(data).filter((entry) => serverKeys.has(entry[0]) && typeof entry[1] === "string" && entry[1].length >= 8);
16
13
  const chunks = Object.entries(bundle).filter(([, chunk]) => chunk.type === "chunk" && !!chunk.code);
17
14
  const leaks = [];
18
- for (const [key, value] of serverSecrets) for (const [chunkName, chunk] of chunks) if (chunk.code.includes(value)) leaks.push({
19
- key,
20
- chunk: chunkName
21
- });
15
+ for (const [key, value] of serverSecrets) {
16
+ const escaped = value.replace(/[.*+?^${}()|[\]\\]/g, String.raw`\$&`);
17
+ const pattern = new RegExp(`(["'\`])${escaped}\\1`);
18
+ for (const [chunkName, chunk] of chunks) if (pattern.test(chunk.code)) leaks.push({
19
+ key,
20
+ chunk: chunkName
21
+ });
22
+ }
22
23
  return leaks;
23
24
  }
24
25
  //#endregion
package/dist/leak.cjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"leak.cjs","names":[],"sources":["../src/leak.ts"],"sourcesContent":["import type { AnyEnvDefinition } from './types'\n\ntype LeakReport = {\n key: string\n chunk: string\n}\n\n/**\n * Scans all client-destined chunks for literal values of server-only vars.\n * Fires in generateBundle() — Rolldown sequential hook, safe.\n *\n * Strategy: for each server-only key, check if its actual runtime value\n * appears as a literal string in any output chunk's source code.\n * Short/common values (< 8 chars) are skipped to avoid false positives.\n */\nexport function detectServerLeak(\n def: AnyEnvDefinition,\n data: Record<string, unknown>,\n bundle: Record<string, { type: string, code?: string }>,\n onSkipped?: (keys: string[]) => void,\n): LeakReport[] {\n const serverKeys = new Set(Object.keys(def.server ?? {}))\n\n const shortSecrets = Object.entries(data).filter(\n (entry): entry is [string, string] =>\n serverKeys.has(entry[0])\n && typeof entry[1] === 'string'\n && entry[1].length < 8,\n )\n\n if (shortSecrets.length > 0 && onSkipped) {\n onSkipped(shortSecrets.map(([k]) => k))\n }\n\n const serverSecrets = Object.entries(data).filter(\n (entry): entry is [string, string] =>\n serverKeys.has(entry[0])\n && typeof entry[1] === 'string'\n && entry[1].length >= 8,\n )\n\n const chunks = Object.entries(bundle).filter(\n ([, chunk]) => chunk.type === 'chunk' && !!chunk.code,\n )\n\n const leaks: LeakReport[] = []\n for (const [key, value] of serverSecrets) {\n for (const [chunkName, chunk] of chunks) {\n if (chunk.code!.includes(value)) {\n leaks.push({ key, chunk: chunkName })\n }\n }\n }\n\n return leaks\n}\n"],"mappings":";;;;;;;;;;AAeA,SAAgB,iBACd,KACA,MACA,QACA,WACc;CACd,MAAM,aAAa,IAAI,IAAI,OAAO,KAAK,IAAI,UAAU,EAAE,CAAC,CAAC;CAEzD,MAAM,eAAe,OAAO,QAAQ,KAAK,CAAC,QACvC,UACC,WAAW,IAAI,MAAM,GAAG,IACrB,OAAO,MAAM,OAAO,YACpB,MAAM,GAAG,SAAS,EACxB;AAED,KAAI,aAAa,SAAS,KAAK,UAC7B,WAAU,aAAa,KAAK,CAAC,OAAO,EAAE,CAAC;CAGzC,MAAM,gBAAgB,OAAO,QAAQ,KAAK,CAAC,QACxC,UACC,WAAW,IAAI,MAAM,GAAG,IACrB,OAAO,MAAM,OAAO,YACpB,MAAM,GAAG,UAAU,EACzB;CAED,MAAM,SAAS,OAAO,QAAQ,OAAO,CAAC,QACnC,GAAG,WAAW,MAAM,SAAS,WAAW,CAAC,CAAC,MAAM,KAClD;CAED,MAAM,QAAsB,EAAE;AAC9B,MAAK,MAAM,CAAC,KAAK,UAAU,cACzB,MAAK,MAAM,CAAC,WAAW,UAAU,OAC/B,KAAI,MAAM,KAAM,SAAS,MAAM,CAC7B,OAAM,KAAK;EAAE;EAAK,OAAO;EAAW,CAAC;AAK3C,QAAO"}
1
+ {"version":3,"file":"leak.cjs","names":[],"sources":["../src/leak.ts"],"sourcesContent":["import type { AnyEnvDefinition } from \"./types\";\n\ntype LeakReport = {\n key: string;\n chunk: string;\n};\n\n/**\n * Scans client-destined chunks for server-only var values appearing as quoted\n * string literals. Bare substring matches are ignored only quoted literals\n * indicate a real bundler-inlined leak. Values < 8 chars are skipped.\n */\nexport function detectServerLeak(\n def: AnyEnvDefinition,\n data: Record<string, unknown>,\n bundle: Record<string, { type: string; code?: string }>,\n onSkipped?: (keys: string[]) => void,\n): LeakReport[] {\n const serverKeys = new Set(Object.keys(def.server ?? {}));\n\n const shortSecrets = Object.entries(data).filter(\n (entry): entry is [string, string] =>\n serverKeys.has(entry[0]) && typeof entry[1] === \"string\" && entry[1].length < 8,\n );\n\n if (shortSecrets.length > 0 && onSkipped) {\n onSkipped(shortSecrets.map(([k]) => k));\n }\n\n const serverSecrets = Object.entries(data).filter(\n (entry): entry is [string, string] =>\n serverKeys.has(entry[0]) && typeof entry[1] === \"string\" && entry[1].length >= 8,\n );\n\n const chunks = Object.entries(bundle).filter(\n ([, chunk]) => chunk.type === \"chunk\" && !!chunk.code,\n );\n\n const leaks: LeakReport[] = [];\n for (const [key, value] of serverSecrets) {\n const escaped = value.replace(/[.*+?^${}()|[\\]\\\\]/g, String.raw`\\$&`);\n const pattern = new RegExp(`([\"'\\`])${escaped}\\\\1`);\n for (const [chunkName, chunk] of chunks) {\n if (pattern.test(chunk.code!)) {\n leaks.push({ key, chunk: chunkName });\n }\n }\n }\n\n return leaks;\n}\n"],"mappings":";;;;;;;AAYA,SAAgB,iBACd,KACA,MACA,QACA,WACc;CACd,MAAM,aAAa,IAAI,IAAI,OAAO,KAAK,IAAI,UAAU,EAAE,CAAC,CAAC;CAEzD,MAAM,eAAe,OAAO,QAAQ,KAAK,CAAC,QACvC,UACC,WAAW,IAAI,MAAM,GAAG,IAAI,OAAO,MAAM,OAAO,YAAY,MAAM,GAAG,SAAS,EACjF;AAED,KAAI,aAAa,SAAS,KAAK,UAC7B,WAAU,aAAa,KAAK,CAAC,OAAO,EAAE,CAAC;CAGzC,MAAM,gBAAgB,OAAO,QAAQ,KAAK,CAAC,QACxC,UACC,WAAW,IAAI,MAAM,GAAG,IAAI,OAAO,MAAM,OAAO,YAAY,MAAM,GAAG,UAAU,EAClF;CAED,MAAM,SAAS,OAAO,QAAQ,OAAO,CAAC,QACnC,GAAG,WAAW,MAAM,SAAS,WAAW,CAAC,CAAC,MAAM,KAClD;CAED,MAAM,QAAsB,EAAE;AAC9B,MAAK,MAAM,CAAC,KAAK,UAAU,eAAe;EACxC,MAAM,UAAU,MAAM,QAAQ,uBAAuB,OAAO,GAAG,MAAM;EACrE,MAAM,UAAU,IAAI,OAAO,WAAW,QAAQ,KAAK;AACnD,OAAK,MAAM,CAAC,WAAW,UAAU,OAC/B,KAAI,QAAQ,KAAK,MAAM,KAAM,CAC3B,OAAM,KAAK;GAAE;GAAK,OAAO;GAAW,CAAC;;AAK3C,QAAO"}
package/dist/leak.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- import { t as AnyEnvDefinition } from "./types-B61nsO8q.cjs";
1
+ import { t as AnyEnvDefinition } from "./types-DudMh278.cjs";
2
2
 
3
3
  //#region src/leak.d.ts
4
4
  type LeakReport = {
@@ -6,12 +6,9 @@ type LeakReport = {
6
6
  chunk: string;
7
7
  };
8
8
  /**
9
- * Scans all client-destined chunks for literal values of server-only vars.
10
- * Fires in generateBundle()Rolldown sequential hook, safe.
11
- *
12
- * Strategy: for each server-only key, check if its actual runtime value
13
- * appears as a literal string in any output chunk's source code.
14
- * Short/common values (< 8 chars) are skipped to avoid false positives.
9
+ * Scans client-destined chunks for server-only var values appearing as quoted
10
+ * string literals. Bare substring matches are ignored only quoted literals
11
+ * indicate a real bundler-inlined leak. Values < 8 chars are skipped.
15
12
  */
16
13
  declare function detectServerLeak(def: AnyEnvDefinition, data: Record<string, unknown>, bundle: Record<string, {
17
14
  type: string;
package/dist/leak.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import { t as AnyEnvDefinition } from "./types-KniR_Oqf.mjs";
1
+ import { t as AnyEnvDefinition } from "./types-Ctg8aeXQ.mjs";
2
2
 
3
3
  //#region src/leak.d.ts
4
4
  type LeakReport = {
@@ -6,12 +6,9 @@ type LeakReport = {
6
6
  chunk: string;
7
7
  };
8
8
  /**
9
- * Scans all client-destined chunks for literal values of server-only vars.
10
- * Fires in generateBundle()Rolldown sequential hook, safe.
11
- *
12
- * Strategy: for each server-only key, check if its actual runtime value
13
- * appears as a literal string in any output chunk's source code.
14
- * Short/common values (< 8 chars) are skipped to avoid false positives.
9
+ * Scans client-destined chunks for server-only var values appearing as quoted
10
+ * string literals. Bare substring matches are ignored only quoted literals
11
+ * indicate a real bundler-inlined leak. Values < 8 chars are skipped.
15
12
  */
16
13
  declare function detectServerLeak(def: AnyEnvDefinition, data: Record<string, unknown>, bundle: Record<string, {
17
14
  type: string;
package/dist/leak.mjs CHANGED
@@ -1,11 +1,8 @@
1
1
  //#region src/leak.ts
2
2
  /**
3
- * Scans all client-destined chunks for literal values of server-only vars.
4
- * Fires in generateBundle()Rolldown sequential hook, safe.
5
- *
6
- * Strategy: for each server-only key, check if its actual runtime value
7
- * appears as a literal string in any output chunk's source code.
8
- * Short/common values (< 8 chars) are skipped to avoid false positives.
3
+ * Scans client-destined chunks for server-only var values appearing as quoted
4
+ * string literals. Bare substring matches are ignored only quoted literals
5
+ * indicate a real bundler-inlined leak. Values < 8 chars are skipped.
9
6
  */
10
7
  function detectServerLeak(def, data, bundle, onSkipped) {
11
8
  const serverKeys = new Set(Object.keys(def.server ?? {}));
@@ -14,10 +11,14 @@ function detectServerLeak(def, data, bundle, onSkipped) {
14
11
  const serverSecrets = Object.entries(data).filter((entry) => serverKeys.has(entry[0]) && typeof entry[1] === "string" && entry[1].length >= 8);
15
12
  const chunks = Object.entries(bundle).filter(([, chunk]) => chunk.type === "chunk" && !!chunk.code);
16
13
  const leaks = [];
17
- for (const [key, value] of serverSecrets) for (const [chunkName, chunk] of chunks) if (chunk.code.includes(value)) leaks.push({
18
- key,
19
- chunk: chunkName
20
- });
14
+ for (const [key, value] of serverSecrets) {
15
+ const escaped = value.replace(/[.*+?^${}()|[\]\\]/g, String.raw`\$&`);
16
+ const pattern = new RegExp(`(["'\`])${escaped}\\1`);
17
+ for (const [chunkName, chunk] of chunks) if (pattern.test(chunk.code)) leaks.push({
18
+ key,
19
+ chunk: chunkName
20
+ });
21
+ }
21
22
  return leaks;
22
23
  }
23
24
  //#endregion