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
@@ -0,0 +1,91 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/core/tx.ts
21
+ var tx_exports = {};
22
+ __export(tx_exports, {
23
+ tx: () => tx
24
+ });
25
+ module.exports = __toCommonJS(tx_exports);
26
+ var import_zod = require("zod");
27
+ var SEMVER_REGEX = /^\d+\.\d+\.\d+(-[0-9A-Za-z-.]+)?$/;
28
+ var tx = {
29
+ /**
30
+ * STRICT STRING:
31
+ * Rejects purely numeric strings (e.g. "12345").
32
+ * Good for API Keys.
33
+ */
34
+ string: (message = "Value should be text, but looks like a number.") => import_zod.z.string().trim().regex(/^(?!\d+$).+$/, { error: message }).describe("Non-numeric string"),
35
+ /**
36
+ * SMART NUMBER:
37
+ * Automatically converts "3000" -> 3000.
38
+ * Fails if the value is not a valid number (e.g. "abc").
39
+ */
40
+ number: (message = "Must be a number") => import_zod.z.coerce.number({ error: message }).finite().describe("Numeric value"),
41
+ /**
42
+ * PORT VALIDATOR:
43
+ * Coerces to number and ensures it is between 1 and 65535.
44
+ */
45
+ port: (message = "Must be a valid port (1\u201365535)") => import_zod.z.coerce.number({ error: message }).int().min(1).max(65535).describe("TCP/UDP port number (1\u201365535)"),
46
+ /**
47
+ * SMART BOOLEAN:
48
+ * Handles "true", "TRUE", "1" -> true
49
+ * Handles "false", "FALSE", "0" -> false
50
+ * Throws error on anything else.
51
+ */
52
+ bool: (message) => {
53
+ return import_zod.z.union([import_zod.z.string(), import_zod.z.boolean()]).transform((val, ctx) => {
54
+ if (typeof val === "boolean") return val;
55
+ const v = val.toLowerCase();
56
+ if (v === "true" || v === "1") return true;
57
+ if (v === "false" || v === "0") return false;
58
+ ctx.addIssue({
59
+ code: import_zod.z.ZodIssueCode.custom,
60
+ message: message || 'Must be a boolean ("true"/"false"/"1"/"0")'
61
+ });
62
+ return import_zod.z.NEVER;
63
+ });
64
+ },
65
+ /**
66
+ * URL:
67
+ * Strict URL checking.
68
+ */
69
+ url: (message = "Must be a valid URL (e.g. https://...)") => import_zod.z.url({ error: message }).describe("A valid URL including protocol"),
70
+ email: (message = "Must be a valid email address") => import_zod.z.email({ error: message }).describe("A valid email address"),
71
+ positiveNumber: (message = "Must be > 0") => import_zod.z.coerce.number().gt(0, { error: message }).describe("A positive number"),
72
+ nonEmptyString: (message = "Cannot be empty") => import_zod.z.string().trim().min(1, { error: message }).describe("A non-empty string"),
73
+ semver: (message = "Must be valid semver") => import_zod.z.string().regex(SEMVER_REGEX, { error: message }).describe("Semantic version (x.y.z)"),
74
+ path: (message = "Must be a valid path") => import_zod.z.string().trim().min(1, { error: message }).describe("Filesystem path"),
75
+ enum: (values, message = `Must be one of: ${values.join(", ")}`) => import_zod.z.enum(values, { error: message }).describe(`One of: ${values.join(", ")}`),
76
+ json: (message = "Must be valid JSON") => import_zod.z.string().transform((val, ctx) => {
77
+ try {
78
+ return JSON.parse(val);
79
+ } catch {
80
+ ctx.addIssue({
81
+ code: "custom",
82
+ error: message
83
+ });
84
+ return import_zod.z.NEVER;
85
+ }
86
+ }).describe("JSON-encoded value")
87
+ };
88
+ // Annotate the CommonJS export names for ESM import in node:
89
+ 0 && (module.exports = {
90
+ tx
91
+ });
@@ -0,0 +1,42 @@
1
+ import { z } from 'zod';
2
+
3
+ declare const tx: {
4
+ /**
5
+ * STRICT STRING:
6
+ * Rejects purely numeric strings (e.g. "12345").
7
+ * Good for API Keys.
8
+ */
9
+ string: (message?: string) => z.ZodString;
10
+ /**
11
+ * SMART NUMBER:
12
+ * Automatically converts "3000" -> 3000.
13
+ * Fails if the value is not a valid number (e.g. "abc").
14
+ */
15
+ number: (message?: string) => z.ZodCoercedNumber<unknown>;
16
+ /**
17
+ * PORT VALIDATOR:
18
+ * Coerces to number and ensures it is between 1 and 65535.
19
+ */
20
+ port: (message?: string) => z.ZodCoercedNumber<unknown>;
21
+ /**
22
+ * SMART BOOLEAN:
23
+ * Handles "true", "TRUE", "1" -> true
24
+ * Handles "false", "FALSE", "0" -> false
25
+ * Throws error on anything else.
26
+ */
27
+ bool: (message?: string) => z.ZodPipe<z.ZodUnion<readonly [z.ZodString, z.ZodBoolean]>, z.ZodTransform<boolean, string | boolean>>;
28
+ /**
29
+ * URL:
30
+ * Strict URL checking.
31
+ */
32
+ url: (message?: string) => z.ZodURL;
33
+ email: (message?: string) => z.ZodEmail;
34
+ positiveNumber: (message?: string) => z.ZodCoercedNumber<unknown>;
35
+ nonEmptyString: (message?: string) => z.ZodString;
36
+ semver: (message?: string) => z.ZodString;
37
+ path: (message?: string) => z.ZodString;
38
+ enum: <T extends readonly [string, ...string[]]>(values: T, message?: string) => z.ZodEnum<{ [k_1 in T[number]]: k_1; } extends infer T_1 ? { [k in keyof T_1]: T_1[k]; } : never>;
39
+ json: <T = unknown>(message?: string) => z.ZodPipe<z.ZodString, z.ZodTransform<Awaited<T>, string>>;
40
+ };
41
+
42
+ export { tx };
@@ -0,0 +1,42 @@
1
+ import { z } from 'zod';
2
+
3
+ declare const tx: {
4
+ /**
5
+ * STRICT STRING:
6
+ * Rejects purely numeric strings (e.g. "12345").
7
+ * Good for API Keys.
8
+ */
9
+ string: (message?: string) => z.ZodString;
10
+ /**
11
+ * SMART NUMBER:
12
+ * Automatically converts "3000" -> 3000.
13
+ * Fails if the value is not a valid number (e.g. "abc").
14
+ */
15
+ number: (message?: string) => z.ZodCoercedNumber<unknown>;
16
+ /**
17
+ * PORT VALIDATOR:
18
+ * Coerces to number and ensures it is between 1 and 65535.
19
+ */
20
+ port: (message?: string) => z.ZodCoercedNumber<unknown>;
21
+ /**
22
+ * SMART BOOLEAN:
23
+ * Handles "true", "TRUE", "1" -> true
24
+ * Handles "false", "FALSE", "0" -> false
25
+ * Throws error on anything else.
26
+ */
27
+ bool: (message?: string) => z.ZodPipe<z.ZodUnion<readonly [z.ZodString, z.ZodBoolean]>, z.ZodTransform<boolean, string | boolean>>;
28
+ /**
29
+ * URL:
30
+ * Strict URL checking.
31
+ */
32
+ url: (message?: string) => z.ZodURL;
33
+ email: (message?: string) => z.ZodEmail;
34
+ positiveNumber: (message?: string) => z.ZodCoercedNumber<unknown>;
35
+ nonEmptyString: (message?: string) => z.ZodString;
36
+ semver: (message?: string) => z.ZodString;
37
+ path: (message?: string) => z.ZodString;
38
+ enum: <T extends readonly [string, ...string[]]>(values: T, message?: string) => z.ZodEnum<{ [k_1 in T[number]]: k_1; } extends infer T_1 ? { [k in keyof T_1]: T_1[k]; } : never>;
39
+ json: <T = unknown>(message?: string) => z.ZodPipe<z.ZodString, z.ZodTransform<Awaited<T>, string>>;
40
+ };
41
+
42
+ export { tx };
@@ -0,0 +1,6 @@
1
+ import {
2
+ tx
3
+ } from "../chunk-E7OYVDFC.js";
4
+ export {
5
+ tx
6
+ };
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __copyProps = (to, from, except, desc) => {
7
+ if (from && typeof from === "object" || typeof from === "function") {
8
+ for (let key of __getOwnPropNames(from))
9
+ if (!__hasOwnProp.call(to, key) && key !== except)
10
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
11
+ }
12
+ return to;
13
+ };
14
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
15
+
16
+ // src/core/types.ts
17
+ var types_exports = {};
18
+ module.exports = __toCommonJS(types_exports);
@@ -0,0 +1,8 @@
1
+ type ValidationMode = "runtime" | "build";
2
+ interface DefineEnvOptions {
3
+ path?: string;
4
+ mode?: ValidationMode;
5
+ generateExample?: boolean;
6
+ }
7
+
8
+ export type { DefineEnvOptions, ValidationMode };
@@ -0,0 +1,8 @@
1
+ type ValidationMode = "runtime" | "build";
2
+ interface DefineEnvOptions {
3
+ path?: string;
4
+ mode?: ValidationMode;
5
+ generateExample?: boolean;
6
+ }
7
+
8
+ export type { DefineEnvOptions, ValidationMode };
File without changes
package/dist/index.cjs CHANGED
@@ -34,89 +34,28 @@ __export(index_exports, {
34
34
  tx: () => tx
35
35
  });
36
36
  module.exports = __toCommonJS(index_exports);
37
- var import_zod2 = require("zod");
38
-
39
- // src/loaders/dotenv.ts
40
- var import_dotenv = __toESM(require("dotenv"), 1);
41
- var import_fs = __toESM(require("fs"), 1);
42
- function loadDotEnv(path = ".env") {
43
- if (!import_fs.default.existsSync(path)) {
44
- throw new Error(
45
- `[envx] .env file not found at path "${path}"
46
- Tip: Set { dotenv: false } if you manage environment variables yourself.`
47
- );
48
- }
49
- const result = import_dotenv.default.config({ path });
50
- if (result.error) {
51
- throw result.error;
52
- }
53
- return result.parsed ?? {};
54
- }
55
37
 
56
- // src/core/parser.ts
38
+ // src/core/tx.ts
57
39
  var import_zod = require("zod");
58
- function parseEnv(schema, source) {
59
- const result = schema.safeParse(source);
60
- if (!result.success) {
61
- const issues = result.error.issues.map((i) => `\u274C ${i.path.join(".")}: ${i.message}`).join("\n");
62
- throw new Error(
63
- [
64
- "",
65
- "\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",
66
- "\u2502 \u274C INVALID ENVIRONMENT VARIABLES DETECTED \u2502",
67
- "\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",
68
- issues,
69
- ""
70
- ].join("\n")
71
- );
72
- }
73
- return result.data;
74
- }
75
-
76
- // src/core/proxy.ts
77
- function createTypedProxy(obj) {
78
- return new Proxy(obj, {
79
- get(target, prop) {
80
- if (!(prop in target)) {
81
- console.error(
82
- `\u274C Tried to access undefined environment variable "${prop}"`
83
- );
84
- process.exit(1);
85
- }
86
- return target[prop];
87
- }
88
- });
89
- }
90
-
91
- // src/index.ts
40
+ var SEMVER_REGEX = /^\d+\.\d+\.\d+(-[0-9A-Za-z-.]+)?$/;
92
41
  var tx = {
93
42
  /**
94
43
  * STRICT STRING:
95
44
  * Rejects purely numeric strings (e.g. "12345").
96
45
  * Good for API Keys.
97
46
  */
98
- string: (message) => {
99
- return import_zod2.z.string().refine((val) => !/^\d+$/.test(val), {
100
- error: message || "Value should be text, but looks like a number."
101
- });
102
- },
47
+ string: (message = "Value should be text, but looks like a number.") => import_zod.z.string().trim().regex(/^(?!\d+$).+$/, { error: message }).describe("Non-numeric string"),
103
48
  /**
104
49
  * SMART NUMBER:
105
50
  * Automatically converts "3000" -> 3000.
106
51
  * Fails if the value is not a valid number (e.g. "abc").
107
52
  */
108
- number: (message) => {
109
- return import_zod2.z.coerce.number({ error: message || "Must be a number" });
110
- },
53
+ number: (message = "Must be a number") => import_zod.z.coerce.number({ error: message }).finite().describe("Numeric value"),
111
54
  /**
112
55
  * PORT VALIDATOR:
113
56
  * Coerces to number and ensures it is between 1 and 65535.
114
57
  */
115
- port: (message) => {
116
- return import_zod2.z.coerce.number({
117
- error: message || "Must be a valid port (1-65535)"
118
- }).min(1, { error: message || "Port must be >= 1" }).max(65535, { error: message || "Port must be <= 65535" });
119
- },
58
+ port: (message = "Must be a valid port (1\u201365535)") => import_zod.z.coerce.number({ error: message }).int().min(1).max(65535).describe("TCP/UDP port number (1\u201365535)"),
120
59
  /**
121
60
  * SMART BOOLEAN:
122
61
  * Handles "true", "TRUE", "1" -> true
@@ -124,72 +63,127 @@ var tx = {
124
63
  * Throws error on anything else.
125
64
  */
126
65
  bool: (message) => {
127
- return import_zod2.z.union([import_zod2.z.string(), import_zod2.z.boolean()]).transform((val, ctx) => {
66
+ return import_zod.z.union([import_zod.z.string(), import_zod.z.boolean()]).transform((val, ctx) => {
128
67
  if (typeof val === "boolean") return val;
129
68
  const v = val.toLowerCase();
130
69
  if (v === "true" || v === "1") return true;
131
70
  if (v === "false" || v === "0") return false;
132
71
  ctx.addIssue({
133
- code: import_zod2.z.ZodIssueCode.custom,
72
+ code: import_zod.z.ZodIssueCode.custom,
134
73
  message: message || 'Must be a boolean ("true"/"false"/"1"/"0")'
135
74
  });
136
- return import_zod2.z.NEVER;
75
+ return import_zod.z.NEVER;
137
76
  });
138
77
  },
139
78
  /**
140
79
  * URL:
141
80
  * Strict URL checking.
142
81
  */
143
- url: (message) => {
144
- return import_zod2.z.url({
145
- error: message || "Must be a valid URL (e.g. https://...)"
146
- });
147
- },
148
- /**
149
- * EMAIL:
150
- * Strict Email checking.
151
- */
152
- email: (message) => {
153
- return import_zod2.z.email({ error: message || "Must be a valid email address." });
154
- },
155
- positiveNumber: (message) => {
156
- return import_zod2.z.coerce.number().gt(0, { message: message || "Must be > 0" });
157
- },
158
- nonEmptyString: (message) => {
159
- return import_zod2.z.string().trim().min(1, { message: message || "Cannot be empty" });
160
- },
161
- semver: (message) => {
162
- return import_zod2.z.string().refine((val) => /^\d+\.\d+\.\d+(-[0-9A-Za-z-.]+)?$/.test(val), {
163
- error: message || "Must be valid semver"
164
- });
165
- },
166
- path: (message) => {
167
- return import_zod2.z.string().min(1, { error: message || "Must be a valid path" });
168
- },
169
- enum: (values, message) => {
170
- return import_zod2.z.string().refine((val) => values.includes(val), {
171
- error: message || `Must be one of: ${values.join(", ")}`
172
- });
173
- },
174
- json: (message) => {
175
- return import_zod2.z.string().transform((val, ctx) => {
176
- try {
177
- return JSON.parse(val);
178
- } catch {
179
- ctx.addIssue({
180
- code: import_zod2.z.ZodIssueCode.custom,
181
- message: message || "Must be valid JSON"
182
- });
183
- return import_zod2.z.NEVER;
82
+ url: (message = "Must be a valid URL (e.g. https://...)") => import_zod.z.url({ error: message }).describe("A valid URL including protocol"),
83
+ email: (message = "Must be a valid email address") => import_zod.z.email({ error: message }).describe("A valid email address"),
84
+ positiveNumber: (message = "Must be > 0") => import_zod.z.coerce.number().gt(0, { error: message }).describe("A positive number"),
85
+ nonEmptyString: (message = "Cannot be empty") => import_zod.z.string().trim().min(1, { error: message }).describe("A non-empty string"),
86
+ semver: (message = "Must be valid semver") => import_zod.z.string().regex(SEMVER_REGEX, { error: message }).describe("Semantic version (x.y.z)"),
87
+ path: (message = "Must be a valid path") => import_zod.z.string().trim().min(1, { error: message }).describe("Filesystem path"),
88
+ enum: (values, message = `Must be one of: ${values.join(", ")}`) => import_zod.z.enum(values, { error: message }).describe(`One of: ${values.join(", ")}`),
89
+ json: (message = "Must be valid JSON") => import_zod.z.string().transform((val, ctx) => {
90
+ try {
91
+ return JSON.parse(val);
92
+ } catch {
93
+ ctx.addIssue({
94
+ code: "custom",
95
+ error: message
96
+ });
97
+ return import_zod.z.NEVER;
98
+ }
99
+ }).describe("JSON-encoded value")
100
+ };
101
+
102
+ // src/core/define-env.ts
103
+ var import_zod4 = require("zod");
104
+
105
+ // src/core/parser.ts
106
+ var import_zod2 = require("zod");
107
+ function parseEnv(schema, source, mode = "runtime") {
108
+ const result = schema.safeParse(source);
109
+ if (!result.success) {
110
+ const issues = result.error.issues.map((i) => `\u274C ${i.path.join(".")}: ${i.message}`).join("\n");
111
+ const header = mode === "build" ? [
112
+ "\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",
113
+ "\u2502 \u274C INVALID ENVIRONMENT VARIABLES DETECTED \u2502",
114
+ "\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"
115
+ ] : [
116
+ "\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",
117
+ "\u2502 \u26A0 WARNING INVALID ENVIRONMENT VARIABLES \u26A0 \u2502",
118
+ "\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"
119
+ ];
120
+ const box = ["", ...header, issues, ""].join("\n");
121
+ if (mode === "build") {
122
+ throw new Error(box);
123
+ } else {
124
+ console.warn(box);
125
+ process.exit(1);
126
+ }
127
+ }
128
+ return result.success ? result.data : {};
129
+ }
130
+
131
+ // src/core/proxy.ts
132
+ function createTypedProxy(obj) {
133
+ return new Proxy(obj, {
134
+ get(target, prop) {
135
+ if (!(prop in target)) {
136
+ console.error(
137
+ `\u274C Tried to access undefined environment variable "${prop}"`
138
+ );
139
+ process.exit(1);
184
140
  }
185
- });
141
+ return target[prop];
142
+ }
143
+ });
144
+ }
145
+
146
+ // src/core/generate-example.ts
147
+ var import_zod3 = require("zod");
148
+ var import_fs = __toESM(require("fs"), 1);
149
+ function getZodTypeName(schema) {
150
+ let type = "unknown";
151
+ if (schema instanceof import_zod3.ZodString) type = "string";
152
+ else if (schema instanceof import_zod3.ZodNumber) type = "number";
153
+ else if (schema instanceof import_zod3.ZodBoolean) type = "boolean";
154
+ return type;
155
+ }
156
+ function generateExample(schema, path = ".env.example") {
157
+ const header = [
158
+ "# Example environment variables",
159
+ "# Copy this file to .env and fill in the values",
160
+ ""
161
+ ];
162
+ const lines = Object.entries(schema.shape).map(([key, zodSchema]) => {
163
+ let placeholder = "";
164
+ let othertype = null;
165
+ let actualSchema = zodSchema;
166
+ if (zodSchema instanceof import_zod3.ZodOptional) actualSchema = zodSchema.unwrap();
167
+ if (zodSchema instanceof import_zod3.ZodDefault) {
168
+ actualSchema = zodSchema.def.innerType;
169
+ placeholder = zodSchema.def.defaultValue ?? "";
170
+ othertype = typeof zodSchema.def.defaultValue;
171
+ }
172
+ const type = getZodTypeName(actualSchema);
173
+ return `${key}=${placeholder ?? ""} # ${othertype ?? type}`;
174
+ });
175
+ const content = [...header, ...lines].join("\n") + "\n";
176
+ import_fs.default.writeFileSync(path, content);
177
+ console.log(`\u2705 .env.example generated at ${path}`);
178
+ }
179
+
180
+ // src/core/define-env.ts
181
+ function defineEnv(shape, source, options) {
182
+ const schema = import_zod4.z.object(shape);
183
+ const parsed = parseEnv(schema, source, options?.mode ?? "runtime");
184
+ if (options?.generateExample) {
185
+ generateExample(schema);
186
186
  }
187
- };
188
- function defineEnv(shape, options) {
189
- const fileEnv = loadDotEnv(options?.path);
190
- const merged = { ...fileEnv, ...process.env };
191
- const schema = import_zod2.z.object(shape);
192
- const parsed = parseEnv(schema, merged);
193
187
  return createTypedProxy(parsed);
194
188
  }
195
189
  // Annotate the CommonJS export names for ESM import in node:
package/dist/index.d.cts CHANGED
@@ -1,50 +1,4 @@
1
- import { z } from 'zod';
2
-
3
- interface DefineEnvOptions {
4
- path?: string;
5
- }
6
- declare const tx: {
7
- /**
8
- * STRICT STRING:
9
- * Rejects purely numeric strings (e.g. "12345").
10
- * Good for API Keys.
11
- */
12
- string: (message?: string) => z.ZodString;
13
- /**
14
- * SMART NUMBER:
15
- * Automatically converts "3000" -> 3000.
16
- * Fails if the value is not a valid number (e.g. "abc").
17
- */
18
- number: (message?: string) => z.ZodCoercedNumber<unknown>;
19
- /**
20
- * PORT VALIDATOR:
21
- * Coerces to number and ensures it is between 1 and 65535.
22
- */
23
- port: (message?: string) => z.ZodCoercedNumber<unknown>;
24
- /**
25
- * SMART BOOLEAN:
26
- * Handles "true", "TRUE", "1" -> true
27
- * Handles "false", "FALSE", "0" -> false
28
- * Throws error on anything else.
29
- */
30
- bool: (message?: string) => z.ZodPipe<z.ZodUnion<readonly [z.ZodString, z.ZodBoolean]>, z.ZodTransform<boolean, string | boolean>>;
31
- /**
32
- * URL:
33
- * Strict URL checking.
34
- */
35
- url: (message?: string) => z.ZodURL;
36
- /**
37
- * EMAIL:
38
- * Strict Email checking.
39
- */
40
- email: (message?: string) => z.ZodEmail;
41
- positiveNumber: (message?: string) => z.ZodCoercedNumber<unknown>;
42
- nonEmptyString: (message?: string) => z.ZodString;
43
- semver: (message?: string) => z.ZodString;
44
- path: (message?: string) => z.ZodString;
45
- enum: <T extends readonly [string, ...string[]]>(values: T, message?: string) => z.ZodString;
46
- json: (message?: string) => z.ZodPipe<z.ZodString, z.ZodTransform<any, string>>;
47
- };
48
- declare function defineEnv<T extends z.ZodRawShape>(shape: T, options?: DefineEnvOptions): { [K in keyof T]: z.core.output<T[K]>; };
49
-
50
- export { defineEnv, tx };
1
+ export { tx } from './core/tx.cjs';
2
+ export { defineEnv } from './core/define-env.cjs';
3
+ export { DefineEnvOptions } from './core/types.cjs';
4
+ import 'zod';
package/dist/index.d.ts CHANGED
@@ -1,50 +1,4 @@
1
- import { z } from 'zod';
2
-
3
- interface DefineEnvOptions {
4
- path?: string;
5
- }
6
- declare const tx: {
7
- /**
8
- * STRICT STRING:
9
- * Rejects purely numeric strings (e.g. "12345").
10
- * Good for API Keys.
11
- */
12
- string: (message?: string) => z.ZodString;
13
- /**
14
- * SMART NUMBER:
15
- * Automatically converts "3000" -> 3000.
16
- * Fails if the value is not a valid number (e.g. "abc").
17
- */
18
- number: (message?: string) => z.ZodCoercedNumber<unknown>;
19
- /**
20
- * PORT VALIDATOR:
21
- * Coerces to number and ensures it is between 1 and 65535.
22
- */
23
- port: (message?: string) => z.ZodCoercedNumber<unknown>;
24
- /**
25
- * SMART BOOLEAN:
26
- * Handles "true", "TRUE", "1" -> true
27
- * Handles "false", "FALSE", "0" -> false
28
- * Throws error on anything else.
29
- */
30
- bool: (message?: string) => z.ZodPipe<z.ZodUnion<readonly [z.ZodString, z.ZodBoolean]>, z.ZodTransform<boolean, string | boolean>>;
31
- /**
32
- * URL:
33
- * Strict URL checking.
34
- */
35
- url: (message?: string) => z.ZodURL;
36
- /**
37
- * EMAIL:
38
- * Strict Email checking.
39
- */
40
- email: (message?: string) => z.ZodEmail;
41
- positiveNumber: (message?: string) => z.ZodCoercedNumber<unknown>;
42
- nonEmptyString: (message?: string) => z.ZodString;
43
- semver: (message?: string) => z.ZodString;
44
- path: (message?: string) => z.ZodString;
45
- enum: <T extends readonly [string, ...string[]]>(values: T, message?: string) => z.ZodString;
46
- json: (message?: string) => z.ZodPipe<z.ZodString, z.ZodTransform<any, string>>;
47
- };
48
- declare function defineEnv<T extends z.ZodRawShape>(shape: T, options?: DefineEnvOptions): { [K in keyof T]: z.core.output<T[K]>; };
49
-
50
- export { defineEnv, tx };
1
+ export { tx } from './core/tx.js';
2
+ export { defineEnv } from './core/define-env.js';
3
+ export { DefineEnvOptions } from './core/types.js';
4
+ import 'zod';