zenvx 0.1.3 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/README.md +128 -17
  2. package/dist/adapters/next.cjs +151 -0
  3. package/dist/adapters/next.d.cts +6 -0
  4. package/dist/adapters/next.d.ts +6 -0
  5. package/dist/adapters/next.js +32 -0
  6. package/dist/adapters/node.cjs +135 -0
  7. package/dist/adapters/node.d.cts +5 -0
  8. package/dist/adapters/node.d.ts +5 -0
  9. package/dist/adapters/node.js +17 -0
  10. package/dist/adapters/vite.cjs +135 -0
  11. package/dist/adapters/vite.d.cts +5 -0
  12. package/dist/adapters/vite.d.ts +5 -0
  13. package/dist/adapters/vite.js +16 -0
  14. package/dist/chunk-3HCQKBTL.js +29 -0
  15. package/dist/chunk-DX3SLVGQ.js +18 -0
  16. package/dist/chunk-E7OYVDFC.js +67 -0
  17. package/dist/chunk-ELPQSMQJ.js +24 -0
  18. package/dist/chunk-KGVPNFG3.js +43 -0
  19. package/dist/chunk-R2XSSP2M.js +24 -0
  20. package/dist/core/define-env.cjs +125 -0
  21. package/dist/core/define-env.d.cts +6 -0
  22. package/dist/core/define-env.d.ts +6 -0
  23. package/dist/core/define-env.js +9 -0
  24. package/dist/core/generate-example.cjs +71 -0
  25. package/dist/core/generate-example.d.cts +5 -0
  26. package/dist/core/generate-example.d.ts +5 -0
  27. package/dist/core/generate-example.js +6 -0
  28. package/dist/core/parser.cjs +53 -0
  29. package/dist/core/parser.d.cts +6 -0
  30. package/dist/core/parser.d.ts +6 -0
  31. package/dist/core/parser.js +6 -0
  32. package/dist/core/proxy.cjs +42 -0
  33. package/dist/core/proxy.d.cts +3 -0
  34. package/dist/core/proxy.d.ts +3 -0
  35. package/dist/core/proxy.js +6 -0
  36. package/dist/core/tx.cjs +91 -0
  37. package/dist/core/tx.d.cts +42 -0
  38. package/dist/core/tx.d.ts +42 -0
  39. package/dist/core/tx.js +6 -0
  40. package/dist/core/types.cjs +18 -0
  41. package/dist/core/types.d.cts +8 -0
  42. package/dist/core/types.d.ts +8 -0
  43. package/dist/core/types.js +0 -0
  44. package/dist/index.cjs +111 -117
  45. package/dist/index.d.cts +4 -50
  46. package/dist/index.d.ts +4 -50
  47. package/dist/index.js +9 -159
  48. package/dist/types/vite-env.d.cjs +1 -0
  49. package/dist/types/vite-env.d.d.cts +2 -0
  50. package/dist/types/vite-env.d.d.ts +2 -0
  51. package/dist/types/vite-env.d.js +0 -0
  52. package/package.json +18 -6
package/README.md CHANGED
@@ -33,6 +33,9 @@ Standard Zod is great, but environment variables are always strings. This leads
33
33
  - ✅ Strict validation for strings, URLs, emails, JSON, enums
34
34
  - ✅ Beautiful, human-readable error reporting
35
35
  - ✅ Seamless TypeScript integration
36
+ - ✅ `.env.example` auto-generation
37
+ - ✅ Runtime **and** build-time validation modes
38
+ - ✅ Framework adapters: Node.js, Next.js (server + client), Vite
36
39
 
37
40
  ## Installation
38
41
 
@@ -76,6 +79,131 @@ console.log(`Server running on port ${env.PORT}`);
76
79
  // TypeScript knows env.PORT is a number!
77
80
  ```
78
81
 
82
+ ## Framework Adapters
83
+
84
+ zenvx supports different frameworks with adapters for proper environment handling.
85
+
86
+ ### Node.js
87
+
88
+ ```ts
89
+ import { loadNodeEnv } from "zenvx/node";
90
+
91
+ const env = loadNodeEnv({
92
+ PORT: tx.port(),
93
+ DEBUG: tx.bool(),
94
+ });
95
+ ```
96
+
97
+ > Note: In Node.js, you must install dotenv separately and load it (e.g., via import "dotenv/config" or dotenv.config()) before calling loadNodeEnv().
98
+
99
+ ### Next.js
100
+
101
+ Server-side
102
+
103
+ ```ts
104
+ import { loadServerEnv } from "zenvx/next";
105
+
106
+ const env = loadServerEnv({
107
+ PORT: tx.port(),
108
+ SECRET_KEY: tx.string(),
109
+ });
110
+ ```
111
+
112
+ Client-side (only NEXT*PUBLIC*\* allowed):
113
+
114
+ ```ts
115
+ import { loadClientEnv } from "zenvx/next";
116
+
117
+ const env = loadClientEnv({
118
+ NEXT_PUBLIC_API_URL: tx.string(),
119
+ NEXT_PUBLIC_DEBUG: tx.bool(),
120
+ });
121
+ ```
122
+
123
+ > Attempting to access a key without NEXT*PUBLIC* in client env throws an error.
124
+
125
+ ### Vite
126
+
127
+ ```ts
128
+ import { loadViteEnv } from "zenvx/vite";
129
+
130
+ const env = loadViteEnv({
131
+ VITE_API_URL: tx.string(),
132
+ VITE_DEBUG: tx.bool(),
133
+ });
134
+ ```
135
+
136
+ ## .env.example Auto-Generation
137
+
138
+ zenvx can automatically generate a .env.example file from your schema — keeping your documentation always in sync.
139
+
140
+ ```ts
141
+ defineEnv(
142
+ {
143
+ DATABASE_URL: tx.url(),
144
+ PORT: tx.port().default(3000),
145
+ DEBUG: tx.bool(),
146
+ },
147
+ {
148
+ generateExample: true,
149
+ },
150
+ );
151
+ ```
152
+
153
+ This produces:
154
+
155
+ ```
156
+ # Example environment variables
157
+ # Copy this file to .env and fill in the values
158
+
159
+ DATABASE_URL= #string
160
+ PORT=3000 # number
161
+ DEBUG_MODE= # boolean
162
+
163
+ ```
164
+
165
+ No more forgotten or outdated .env.example files.
166
+
167
+ ## Runtime vs Build-Time Validation
168
+
169
+ Different environments need different failure behavior. zenvx supports both.
170
+
171
+ ### Runtime Validation (default)
172
+
173
+ In runtime mode, environment variables are validated as soon as your application starts.
174
+
175
+ ```ts
176
+ defineEnv(schema, { mode: "runtime" });
177
+ ```
178
+
179
+ Behavior:
180
+
181
+ - Environment variables are loaded and validated immediately
182
+ - If validation fails:
183
+ - A formatted error message is printed to the console
184
+ - The process exits using process.exit(1)
185
+ - Prevents the application from running with invalid configuration
186
+
187
+ This mode ensures misconfigured environments are caught early and stop execution entirely.
188
+
189
+ ### Build-Time Validation
190
+
191
+ IIn build-time mode, validation errors are thrown instead of terminating the process.
192
+
193
+ ```ts
194
+ defineEnv(schema, { mode: "build" });
195
+ ```
196
+
197
+ Behavior:
198
+
199
+ - Environment variables are validated during execution
200
+ - If validation fails:
201
+ - An error is thrown
202
+ - process.exit() is not called
203
+ - Allows the calling environment (bundler, test runner, or script) to handle the failure
204
+
205
+ This mode avoids hard exits and lets external tooling decide how to respond to configuration errors.
206
+
79
207
  ## Beautiful Error Handling
80
208
 
81
209
  If your .env file is missing values or has invalid types, zenvx stops the process immediately and prints a clear message:
@@ -115,23 +243,6 @@ export const env = defineEnv({
115
243
  });
116
244
  ```
117
245
 
118
- ## Advanced Configuration
119
-
120
- Custom .env Path
121
-
122
- By default, zenvx looks for .env in your project root. You can change this:
123
-
124
- ```ts
125
- export const env = defineEnv(
126
- {
127
- PORT: tx.port(),
128
- },
129
- {
130
- path: "./config/.env.production",
131
- },
132
- );
133
- ```
134
-
135
246
  ## Mixing with Standard Zod
136
247
 
137
248
  You can mix tx helpers with standard Zod schemas if you need specific logic.
@@ -0,0 +1,151 @@
1
+ "use strict";
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 __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/adapters/next.ts
31
+ var next_exports = {};
32
+ __export(next_exports, {
33
+ loadClientEnv: () => loadClientEnv,
34
+ loadServerEnv: () => loadServerEnv
35
+ });
36
+ module.exports = __toCommonJS(next_exports);
37
+
38
+ // src/core/define-env.ts
39
+ var import_zod3 = require("zod");
40
+
41
+ // src/core/parser.ts
42
+ var import_zod = require("zod");
43
+ function parseEnv(schema, source, mode = "runtime") {
44
+ const result = schema.safeParse(source);
45
+ if (!result.success) {
46
+ const issues = result.error.issues.map((i) => `\u274C ${i.path.join(".")}: ${i.message}`).join("\n");
47
+ const header = mode === "build" ? [
48
+ "\u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510",
49
+ "\u2502 \u274C INVALID ENVIRONMENT VARIABLES DETECTED \u2502",
50
+ "\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518"
51
+ ] : [
52
+ "\u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510",
53
+ "\u2502 \u26A0 WARNING INVALID ENVIRONMENT VARIABLES \u26A0 \u2502",
54
+ "\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518"
55
+ ];
56
+ const box = ["", ...header, issues, ""].join("\n");
57
+ if (mode === "build") {
58
+ throw new Error(box);
59
+ } else {
60
+ console.warn(box);
61
+ process.exit(1);
62
+ }
63
+ }
64
+ return result.success ? result.data : {};
65
+ }
66
+
67
+ // src/core/proxy.ts
68
+ function createTypedProxy(obj) {
69
+ return new Proxy(obj, {
70
+ get(target, prop) {
71
+ if (!(prop in target)) {
72
+ console.error(
73
+ `\u274C Tried to access undefined environment variable "${prop}"`
74
+ );
75
+ process.exit(1);
76
+ }
77
+ return target[prop];
78
+ }
79
+ });
80
+ }
81
+
82
+ // src/core/generate-example.ts
83
+ var import_zod2 = require("zod");
84
+ var import_fs = __toESM(require("fs"), 1);
85
+ function getZodTypeName(schema) {
86
+ let type = "unknown";
87
+ if (schema instanceof import_zod2.ZodString) type = "string";
88
+ else if (schema instanceof import_zod2.ZodNumber) type = "number";
89
+ else if (schema instanceof import_zod2.ZodBoolean) type = "boolean";
90
+ return type;
91
+ }
92
+ function generateExample(schema, path = ".env.example") {
93
+ const header = [
94
+ "# Example environment variables",
95
+ "# Copy this file to .env and fill in the values",
96
+ ""
97
+ ];
98
+ const lines = Object.entries(schema.shape).map(([key, zodSchema]) => {
99
+ let placeholder = "";
100
+ let othertype = null;
101
+ let actualSchema = zodSchema;
102
+ if (zodSchema instanceof import_zod2.ZodOptional) actualSchema = zodSchema.unwrap();
103
+ if (zodSchema instanceof import_zod2.ZodDefault) {
104
+ actualSchema = zodSchema.def.innerType;
105
+ placeholder = zodSchema.def.defaultValue ?? "";
106
+ othertype = typeof zodSchema.def.defaultValue;
107
+ }
108
+ const type = getZodTypeName(actualSchema);
109
+ return `${key}=${placeholder ?? ""} # ${othertype ?? type}`;
110
+ });
111
+ const content = [...header, ...lines].join("\n") + "\n";
112
+ import_fs.default.writeFileSync(path, content);
113
+ console.log(`\u2705 .env.example generated at ${path}`);
114
+ }
115
+
116
+ // src/core/define-env.ts
117
+ function defineEnv(shape, source, options) {
118
+ const schema = import_zod3.z.object(shape);
119
+ const parsed = parseEnv(schema, source, options?.mode ?? "runtime");
120
+ if (options?.generateExample) {
121
+ generateExample(schema);
122
+ }
123
+ return createTypedProxy(parsed);
124
+ }
125
+
126
+ // src/adapters/next.ts
127
+ function loadServerEnv(shape) {
128
+ if (typeof window !== "undefined") {
129
+ throw new Error("Server env cannot be used in the browser");
130
+ }
131
+ return defineEnv(shape, process.env, {
132
+ mode: process.env.NEXT_PHASE === "phase-production-build" ? "build" : "runtime"
133
+ });
134
+ }
135
+ function loadClientEnv(shape) {
136
+ const clientEnv = {};
137
+ for (const key of Object.keys(shape)) {
138
+ if (!key.startsWith("NEXT_PUBLIC_")) {
139
+ throw new Error(`Client env "${key}" must start with NEXT_PUBLIC_`);
140
+ }
141
+ clientEnv[key] = process.env[key];
142
+ }
143
+ return defineEnv(shape, clientEnv, {
144
+ mode: "build"
145
+ });
146
+ }
147
+ // Annotate the CommonJS export names for ESM import in node:
148
+ 0 && (module.exports = {
149
+ loadClientEnv,
150
+ loadServerEnv
151
+ });
@@ -0,0 +1,6 @@
1
+ import * as zod from 'zod';
2
+
3
+ declare function loadServerEnv<T extends Record<string, any>>(shape: T): { [K in keyof T]: zod.infer<T[K]>; };
4
+ declare function loadClientEnv<T extends Record<string, any>>(shape: T): { [K in keyof T]: zod.infer<T[K]>; };
5
+
6
+ export { loadClientEnv, loadServerEnv };
@@ -0,0 +1,6 @@
1
+ import * as zod from 'zod';
2
+
3
+ declare function loadServerEnv<T extends Record<string, any>>(shape: T): { [K in keyof T]: zod.infer<T[K]>; };
4
+ declare function loadClientEnv<T extends Record<string, any>>(shape: T): { [K in keyof T]: zod.infer<T[K]>; };
5
+
6
+ export { loadClientEnv, loadServerEnv };
@@ -0,0 +1,32 @@
1
+ import {
2
+ defineEnv
3
+ } from "../chunk-ELPQSMQJ.js";
4
+ import "../chunk-KGVPNFG3.js";
5
+ import "../chunk-3HCQKBTL.js";
6
+ import "../chunk-DX3SLVGQ.js";
7
+
8
+ // src/adapters/next.ts
9
+ function loadServerEnv(shape) {
10
+ if (typeof window !== "undefined") {
11
+ throw new Error("Server env cannot be used in the browser");
12
+ }
13
+ return defineEnv(shape, process.env, {
14
+ mode: process.env.NEXT_PHASE === "phase-production-build" ? "build" : "runtime"
15
+ });
16
+ }
17
+ function loadClientEnv(shape) {
18
+ const clientEnv = {};
19
+ for (const key of Object.keys(shape)) {
20
+ if (!key.startsWith("NEXT_PUBLIC_")) {
21
+ throw new Error(`Client env "${key}" must start with NEXT_PUBLIC_`);
22
+ }
23
+ clientEnv[key] = process.env[key];
24
+ }
25
+ return defineEnv(shape, clientEnv, {
26
+ mode: "build"
27
+ });
28
+ }
29
+ export {
30
+ loadClientEnv,
31
+ loadServerEnv
32
+ };
@@ -0,0 +1,135 @@
1
+ "use strict";
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 __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/adapters/node.ts
31
+ var node_exports = {};
32
+ __export(node_exports, {
33
+ loadNodeEnv: () => loadNodeEnv
34
+ });
35
+ module.exports = __toCommonJS(node_exports);
36
+
37
+ // src/core/define-env.ts
38
+ var import_zod3 = require("zod");
39
+
40
+ // src/core/parser.ts
41
+ var import_zod = require("zod");
42
+ function parseEnv(schema, source, mode = "runtime") {
43
+ const result = schema.safeParse(source);
44
+ if (!result.success) {
45
+ const issues = result.error.issues.map((i) => `\u274C ${i.path.join(".")}: ${i.message}`).join("\n");
46
+ const header = mode === "build" ? [
47
+ "\u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510",
48
+ "\u2502 \u274C INVALID ENVIRONMENT VARIABLES DETECTED \u2502",
49
+ "\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518"
50
+ ] : [
51
+ "\u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510",
52
+ "\u2502 \u26A0 WARNING INVALID ENVIRONMENT VARIABLES \u26A0 \u2502",
53
+ "\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518"
54
+ ];
55
+ const box = ["", ...header, issues, ""].join("\n");
56
+ if (mode === "build") {
57
+ throw new Error(box);
58
+ } else {
59
+ console.warn(box);
60
+ process.exit(1);
61
+ }
62
+ }
63
+ return result.success ? result.data : {};
64
+ }
65
+
66
+ // src/core/proxy.ts
67
+ function createTypedProxy(obj) {
68
+ return new Proxy(obj, {
69
+ get(target, prop) {
70
+ if (!(prop in target)) {
71
+ console.error(
72
+ `\u274C Tried to access undefined environment variable "${prop}"`
73
+ );
74
+ process.exit(1);
75
+ }
76
+ return target[prop];
77
+ }
78
+ });
79
+ }
80
+
81
+ // src/core/generate-example.ts
82
+ var import_zod2 = require("zod");
83
+ var import_fs = __toESM(require("fs"), 1);
84
+ function getZodTypeName(schema) {
85
+ let type = "unknown";
86
+ if (schema instanceof import_zod2.ZodString) type = "string";
87
+ else if (schema instanceof import_zod2.ZodNumber) type = "number";
88
+ else if (schema instanceof import_zod2.ZodBoolean) type = "boolean";
89
+ return type;
90
+ }
91
+ function generateExample(schema, path = ".env.example") {
92
+ const header = [
93
+ "# Example environment variables",
94
+ "# Copy this file to .env and fill in the values",
95
+ ""
96
+ ];
97
+ const lines = Object.entries(schema.shape).map(([key, zodSchema]) => {
98
+ let placeholder = "";
99
+ let othertype = null;
100
+ let actualSchema = zodSchema;
101
+ if (zodSchema instanceof import_zod2.ZodOptional) actualSchema = zodSchema.unwrap();
102
+ if (zodSchema instanceof import_zod2.ZodDefault) {
103
+ actualSchema = zodSchema.def.innerType;
104
+ placeholder = zodSchema.def.defaultValue ?? "";
105
+ othertype = typeof zodSchema.def.defaultValue;
106
+ }
107
+ const type = getZodTypeName(actualSchema);
108
+ return `${key}=${placeholder ?? ""} # ${othertype ?? type}`;
109
+ });
110
+ const content = [...header, ...lines].join("\n") + "\n";
111
+ import_fs.default.writeFileSync(path, content);
112
+ console.log(`\u2705 .env.example generated at ${path}`);
113
+ }
114
+
115
+ // src/core/define-env.ts
116
+ function defineEnv(shape, source, options) {
117
+ const schema = import_zod3.z.object(shape);
118
+ const parsed = parseEnv(schema, source, options?.mode ?? "runtime");
119
+ if (options?.generateExample) {
120
+ generateExample(schema);
121
+ }
122
+ return createTypedProxy(parsed);
123
+ }
124
+
125
+ // src/adapters/node.ts
126
+ function loadNodeEnv(shape) {
127
+ return defineEnv(shape, process.env, {
128
+ mode: "runtime",
129
+ generateExample: true
130
+ });
131
+ }
132
+ // Annotate the CommonJS export names for ESM import in node:
133
+ 0 && (module.exports = {
134
+ loadNodeEnv
135
+ });
@@ -0,0 +1,5 @@
1
+ import * as zod from 'zod';
2
+
3
+ declare function loadNodeEnv<T extends Record<string, any>>(shape: T): { [K in keyof T]: zod.infer<T[K]>; };
4
+
5
+ export { loadNodeEnv };
@@ -0,0 +1,5 @@
1
+ import * as zod from 'zod';
2
+
3
+ declare function loadNodeEnv<T extends Record<string, any>>(shape: T): { [K in keyof T]: zod.infer<T[K]>; };
4
+
5
+ export { loadNodeEnv };
@@ -0,0 +1,17 @@
1
+ import {
2
+ defineEnv
3
+ } from "../chunk-ELPQSMQJ.js";
4
+ import "../chunk-KGVPNFG3.js";
5
+ import "../chunk-3HCQKBTL.js";
6
+ import "../chunk-DX3SLVGQ.js";
7
+
8
+ // src/adapters/node.ts
9
+ function loadNodeEnv(shape) {
10
+ return defineEnv(shape, process.env, {
11
+ mode: "runtime",
12
+ generateExample: true
13
+ });
14
+ }
15
+ export {
16
+ loadNodeEnv
17
+ };
@@ -0,0 +1,135 @@
1
+ "use strict";
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 __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/adapters/vite.ts
31
+ var vite_exports = {};
32
+ __export(vite_exports, {
33
+ loadViteEnv: () => loadViteEnv
34
+ });
35
+ module.exports = __toCommonJS(vite_exports);
36
+
37
+ // src/core/define-env.ts
38
+ var import_zod3 = require("zod");
39
+
40
+ // src/core/parser.ts
41
+ var import_zod = require("zod");
42
+ function parseEnv(schema, source, mode = "runtime") {
43
+ const result = schema.safeParse(source);
44
+ if (!result.success) {
45
+ const issues = result.error.issues.map((i) => `\u274C ${i.path.join(".")}: ${i.message}`).join("\n");
46
+ const header = mode === "build" ? [
47
+ "\u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510",
48
+ "\u2502 \u274C INVALID ENVIRONMENT VARIABLES DETECTED \u2502",
49
+ "\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518"
50
+ ] : [
51
+ "\u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510",
52
+ "\u2502 \u26A0 WARNING INVALID ENVIRONMENT VARIABLES \u26A0 \u2502",
53
+ "\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518"
54
+ ];
55
+ const box = ["", ...header, issues, ""].join("\n");
56
+ if (mode === "build") {
57
+ throw new Error(box);
58
+ } else {
59
+ console.warn(box);
60
+ process.exit(1);
61
+ }
62
+ }
63
+ return result.success ? result.data : {};
64
+ }
65
+
66
+ // src/core/proxy.ts
67
+ function createTypedProxy(obj) {
68
+ return new Proxy(obj, {
69
+ get(target, prop) {
70
+ if (!(prop in target)) {
71
+ console.error(
72
+ `\u274C Tried to access undefined environment variable "${prop}"`
73
+ );
74
+ process.exit(1);
75
+ }
76
+ return target[prop];
77
+ }
78
+ });
79
+ }
80
+
81
+ // src/core/generate-example.ts
82
+ var import_zod2 = require("zod");
83
+ var import_fs = __toESM(require("fs"), 1);
84
+ function getZodTypeName(schema) {
85
+ let type = "unknown";
86
+ if (schema instanceof import_zod2.ZodString) type = "string";
87
+ else if (schema instanceof import_zod2.ZodNumber) type = "number";
88
+ else if (schema instanceof import_zod2.ZodBoolean) type = "boolean";
89
+ return type;
90
+ }
91
+ function generateExample(schema, path = ".env.example") {
92
+ const header = [
93
+ "# Example environment variables",
94
+ "# Copy this file to .env and fill in the values",
95
+ ""
96
+ ];
97
+ const lines = Object.entries(schema.shape).map(([key, zodSchema]) => {
98
+ let placeholder = "";
99
+ let othertype = null;
100
+ let actualSchema = zodSchema;
101
+ if (zodSchema instanceof import_zod2.ZodOptional) actualSchema = zodSchema.unwrap();
102
+ if (zodSchema instanceof import_zod2.ZodDefault) {
103
+ actualSchema = zodSchema.def.innerType;
104
+ placeholder = zodSchema.def.defaultValue ?? "";
105
+ othertype = typeof zodSchema.def.defaultValue;
106
+ }
107
+ const type = getZodTypeName(actualSchema);
108
+ return `${key}=${placeholder ?? ""} # ${othertype ?? type}`;
109
+ });
110
+ const content = [...header, ...lines].join("\n") + "\n";
111
+ import_fs.default.writeFileSync(path, content);
112
+ console.log(`\u2705 .env.example generated at ${path}`);
113
+ }
114
+
115
+ // src/core/define-env.ts
116
+ function defineEnv(shape, source, options) {
117
+ const schema = import_zod3.z.object(shape);
118
+ const parsed = parseEnv(schema, source, options?.mode ?? "runtime");
119
+ if (options?.generateExample) {
120
+ generateExample(schema);
121
+ }
122
+ return createTypedProxy(parsed);
123
+ }
124
+
125
+ // src/adapters/vite.ts
126
+ var import_meta = {};
127
+ function loadViteEnv(shape) {
128
+ return defineEnv(shape, import_meta.env, {
129
+ mode: "build"
130
+ });
131
+ }
132
+ // Annotate the CommonJS export names for ESM import in node:
133
+ 0 && (module.exports = {
134
+ loadViteEnv
135
+ });
@@ -0,0 +1,5 @@
1
+ import * as zod from 'zod';
2
+
3
+ declare function loadViteEnv<T extends Record<string, any>>(shape: T): { [K in keyof T]: zod.infer<T[K]>; };
4
+
5
+ export { loadViteEnv };
@@ -0,0 +1,5 @@
1
+ import * as zod from 'zod';
2
+
3
+ declare function loadViteEnv<T extends Record<string, any>>(shape: T): { [K in keyof T]: zod.infer<T[K]>; };
4
+
5
+ export { loadViteEnv };