envguard-ts 1.0.0

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.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"core.js","sourceRoot":"","sources":["../../src/core.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.EnvValidationError = void 0;
4
+ /**
5
+ * Thrown when one or more environment variables fail validation.
6
+ * Provides a structured list of field errors and a formatted human-readable message.
7
+ */
8
+ class EnvValidationError extends Error {
9
+ constructor(errors) {
10
+ const lines = [
11
+ '',
12
+ ' ✖ Environment validation failed',
13
+ '',
14
+ ...errors.map((e) => ` ${e.field}: ${e.message}` +
15
+ (e.received !== undefined ? ` (received: ${JSON.stringify(e.received)})` : '')),
16
+ '',
17
+ ];
18
+ super(lines.join('\n'));
19
+ this.name = 'EnvValidationError';
20
+ this.errors = errors;
21
+ // Maintain proper prototype chain in transpiled CJS
22
+ Object.setPrototypeOf(this, new.target.prototype);
23
+ }
24
+ }
25
+ exports.EnvValidationError = EnvValidationError;
26
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/errors.ts"],"names":[],"mappings":";;;AAUA;;;GAGG;AACH,MAAa,kBAAmB,SAAQ,KAAK;IAI3C,YAAY,MAAoB;QAC9B,MAAM,KAAK,GAAG;YACZ,EAAE;YACF,4CAA4C;YAC5C,EAAE;YACF,GAAG,MAAM,CAAC,GAAG,CACX,CAAC,CAAC,EAAE,EAAE,CACJ,UAAU,CAAC,CAAC,KAAK,SAAS,CAAC,CAAC,OAAO,EAAE;gBACrC,CAAC,CAAC,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,oBAAoB,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAC1F;YACD,EAAE;SACH,CAAA;QACD,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAA;QACvB,IAAI,CAAC,IAAI,GAAG,oBAAoB,CAAA;QAChC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAA;QACpB,oDAAoD;QACpD,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,CAAA;IACnD,CAAC;CACF;AAtBD,gDAsBC"}
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ /**
3
+ * envx — Zero-dependency TypeScript env variable validator
4
+ * @module envx
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.EnvValidationError = exports.enums = exports.json = exports.email = exports.port = exports.url = exports.bool = exports.num = exports.str = exports.validateEnvFile = exports.generateExample = exports.createEnv = void 0;
8
+ // Core
9
+ var core_js_1 = require("./core.js");
10
+ Object.defineProperty(exports, "createEnv", { enumerable: true, get: function () { return core_js_1.createEnv; } });
11
+ Object.defineProperty(exports, "generateExample", { enumerable: true, get: function () { return core_js_1.generateExample; } });
12
+ Object.defineProperty(exports, "validateEnvFile", { enumerable: true, get: function () { return core_js_1.validateEnvFile; } });
13
+ // Validators
14
+ var validators_js_1 = require("./validators.js");
15
+ Object.defineProperty(exports, "str", { enumerable: true, get: function () { return validators_js_1.str; } });
16
+ Object.defineProperty(exports, "num", { enumerable: true, get: function () { return validators_js_1.num; } });
17
+ Object.defineProperty(exports, "bool", { enumerable: true, get: function () { return validators_js_1.bool; } });
18
+ Object.defineProperty(exports, "url", { enumerable: true, get: function () { return validators_js_1.url; } });
19
+ Object.defineProperty(exports, "port", { enumerable: true, get: function () { return validators_js_1.port; } });
20
+ Object.defineProperty(exports, "email", { enumerable: true, get: function () { return validators_js_1.email; } });
21
+ Object.defineProperty(exports, "json", { enumerable: true, get: function () { return validators_js_1.json; } });
22
+ Object.defineProperty(exports, "enums", { enumerable: true, get: function () { return validators_js_1.enums; } });
23
+ // Errors
24
+ var errors_js_1 = require("./errors.js");
25
+ Object.defineProperty(exports, "EnvValidationError", { enumerable: true, get: function () { return errors_js_1.EnvValidationError; } });
26
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH,OAAO;AACP,qCAAuE;AAA9D,oGAAA,SAAS,OAAA;AAAE,0GAAA,eAAe,OAAA;AAAE,0GAAA,eAAe,OAAA;AAGpD,aAAa;AACb,iDAA+E;AAAtE,oGAAA,GAAG,OAAA;AAAE,oGAAA,GAAG,OAAA;AAAE,qGAAA,IAAI,OAAA;AAAE,oGAAA,GAAG,OAAA;AAAE,qGAAA,IAAI,OAAA;AAAE,sGAAA,KAAK,OAAA;AAAE,qGAAA,IAAI,OAAA;AAAE,sGAAA,KAAK,OAAA;AAatD,SAAS;AACT,yCAAgD;AAAvC,+GAAA,kBAAkB,OAAA"}
@@ -0,0 +1,134 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.str = str;
4
+ exports.num = num;
5
+ exports.bool = bool;
6
+ exports.url = url;
7
+ exports.port = port;
8
+ exports.email = email;
9
+ exports.json = json;
10
+ exports.enums = enums;
11
+ function makeSpec(parse, validate, opts) {
12
+ return {
13
+ _type: undefined,
14
+ _required: opts.required,
15
+ _default: opts.default,
16
+ _secret: opts.secret ?? false,
17
+ _description: opts.description,
18
+ _parse: parse,
19
+ _validate: validate,
20
+ };
21
+ }
22
+ function str(opts = {}) {
23
+ return makeSpec((raw) => raw, (value, field) => {
24
+ if (opts.choices && !opts.choices.includes(value)) {
25
+ throw new Error(`must be one of [${opts.choices.map((c) => JSON.stringify(c)).join(', ')}], got ${JSON.stringify(value)} for ${field}`);
26
+ }
27
+ if (opts.minLength !== undefined && value.length < opts.minLength) {
28
+ throw new Error(`must be at least ${opts.minLength} characters for ${field}`);
29
+ }
30
+ if (opts.maxLength !== undefined && value.length > opts.maxLength) {
31
+ throw new Error(`must be at most ${opts.maxLength} characters for ${field}`);
32
+ }
33
+ if (opts.pattern && !opts.pattern.test(value)) {
34
+ throw new Error(`must match pattern ${opts.pattern} for ${field}`);
35
+ }
36
+ }, { ...opts, required: opts.default === undefined });
37
+ }
38
+ function num(opts = {}) {
39
+ return makeSpec((raw, field) => {
40
+ const n = Number(raw);
41
+ if (!Number.isFinite(n))
42
+ throw new Error(`must be a finite number for ${field}`);
43
+ return n;
44
+ }, (value, field) => {
45
+ if (opts.min !== undefined && value < opts.min) {
46
+ throw new Error(`must be >= ${opts.min} for ${field}`);
47
+ }
48
+ if (opts.max !== undefined && value > opts.max) {
49
+ throw new Error(`must be <= ${opts.max} for ${field}`);
50
+ }
51
+ }, { ...opts, required: opts.default === undefined });
52
+ }
53
+ const TRUTHY = new Set(['true', '1', 'yes', 'on']);
54
+ const FALSY = new Set(['false', '0', 'no', 'off']);
55
+ function bool(opts = {}) {
56
+ return makeSpec((raw, field) => {
57
+ const lower = raw.toLowerCase();
58
+ if (TRUTHY.has(lower))
59
+ return true;
60
+ if (FALSY.has(lower))
61
+ return false;
62
+ throw new Error(`must be a boolean (true/false/1/0/yes/no/on/off) for ${field}, got ${JSON.stringify(raw)}`);
63
+ }, () => { }, { ...opts, required: opts.default === undefined });
64
+ }
65
+ function url(opts = {}) {
66
+ return makeSpec((raw, field) => {
67
+ try {
68
+ const parsed = new URL(raw);
69
+ if (opts.protocols && !opts.protocols.includes(parsed.protocol)) {
70
+ throw new Error(`protocol must be one of [${opts.protocols.join(', ')}] for ${field}, got ${parsed.protocol}`);
71
+ }
72
+ return raw;
73
+ }
74
+ catch (e) {
75
+ if (e instanceof Error && e.message.includes('for ' + field))
76
+ throw e;
77
+ throw new Error(`must be a valid URL for ${field}`);
78
+ }
79
+ }, () => { }, { ...opts, required: opts.default === undefined });
80
+ }
81
+ function port(opts = {}) {
82
+ return makeSpec((raw, field) => {
83
+ const n = parseInt(raw, 10);
84
+ if (Number.isNaN(n) || String(n) !== raw.trim()) {
85
+ throw new Error(`must be an integer port number for ${field}`);
86
+ }
87
+ if (n < 1 || n > 65535) {
88
+ throw new Error(`must be between 1 and 65535 for ${field}`);
89
+ }
90
+ return n;
91
+ }, () => { }, { ...opts, required: opts.default === undefined });
92
+ }
93
+ // RFC-5321-compatible simplified regex — fast and covers 99%+ real addresses
94
+ const EMAIL_RE = /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*\.[a-zA-Z]{2,}$/;
95
+ function email(opts = {}) {
96
+ return makeSpec((raw, field) => {
97
+ if (!EMAIL_RE.test(raw)) {
98
+ throw new Error(`must be a valid email address for ${field}`);
99
+ }
100
+ return raw;
101
+ }, () => { }, { ...opts, required: opts.default === undefined });
102
+ }
103
+ function json(opts = {}) {
104
+ return makeSpec((raw, field) => {
105
+ try {
106
+ return JSON.parse(raw);
107
+ }
108
+ catch {
109
+ throw new Error(`must be valid JSON for ${field}`);
110
+ }
111
+ }, () => { }, { ...opts, required: opts.default === undefined });
112
+ }
113
+ // ---------------------------------------------------------------------------
114
+ // enums (string union)
115
+ // ---------------------------------------------------------------------------
116
+ /**
117
+ * Validates that a variable matches one value from a const-asserted tuple.
118
+ * Provides a narrower return type than `str({ choices })`.
119
+ *
120
+ * @example
121
+ * ```ts
122
+ * LOG_LEVEL: enums(['debug', 'info', 'warn', 'error'] as const)
123
+ * ```
124
+ */
125
+ function enums(values, opts) {
126
+ const base = opts ?? {};
127
+ return makeSpec((raw, field) => {
128
+ if (!values.includes(raw)) {
129
+ throw new Error(`must be one of [${values.map((v) => JSON.stringify(v)).join(', ')}] for ${field}`);
130
+ }
131
+ return raw;
132
+ }, () => { }, { ...base, required: base.default === undefined });
133
+ }
134
+ //# sourceMappingURL=validators.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validators.js","sourceRoot":"","sources":["../../src/validators.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,151 @@
1
+ /**
2
+ * envx CLI — validate and generate .env files
3
+ *
4
+ * Commands:
5
+ * envx check [--env <file>] [--schema <file>]
6
+ * envx generate [--schema <file>] [--out <file>]
7
+ */
8
+ import * as fs from 'node:fs';
9
+ import * as path from 'node:path';
10
+ import { validateEnvFile, generateExample } from './core.js';
11
+ // ---------------------------------------------------------------------------
12
+ // Tiny .env parser (no dependency)
13
+ // ---------------------------------------------------------------------------
14
+ function parseEnvFile(content) {
15
+ const result = {};
16
+ for (const rawLine of content.split(/\r?\n/)) {
17
+ const line = rawLine.trim();
18
+ if (!line || line.startsWith('#'))
19
+ continue;
20
+ const eqIdx = line.indexOf('=');
21
+ if (eqIdx === -1)
22
+ continue;
23
+ const key = line.slice(0, eqIdx).trim();
24
+ let value = line.slice(eqIdx + 1).trim();
25
+ // Strip surrounding quotes
26
+ if ((value.startsWith('"') && value.endsWith('"')) ||
27
+ (value.startsWith("'") && value.endsWith("'"))) {
28
+ value = value.slice(1, -1);
29
+ }
30
+ result[key] = value;
31
+ }
32
+ return result;
33
+ }
34
+ // ---------------------------------------------------------------------------
35
+ // Arg parser
36
+ // ---------------------------------------------------------------------------
37
+ function parseArgs(argv) {
38
+ const args = {};
39
+ for (let i = 0; i < argv.length; i++) {
40
+ const arg = argv[i];
41
+ if (arg !== undefined && arg.startsWith('--')) {
42
+ const key = arg.slice(2);
43
+ const next = argv[i + 1];
44
+ if (next !== undefined && !next.startsWith('--')) {
45
+ args[key] = next;
46
+ i++;
47
+ }
48
+ else {
49
+ args[key] = true;
50
+ }
51
+ }
52
+ }
53
+ return args;
54
+ }
55
+ // ---------------------------------------------------------------------------
56
+ // Commands
57
+ // ---------------------------------------------------------------------------
58
+ async function loadSchema(schemaPath) {
59
+ const resolved = path.resolve(process.cwd(), schemaPath);
60
+ if (!fs.existsSync(resolved)) {
61
+ console.error(`[envx] schema file not found: ${resolved}`);
62
+ process.exit(1);
63
+ }
64
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
65
+ const mod = await import(resolved);
66
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
67
+ const schema = (mod.default ?? mod.schema ?? mod);
68
+ if (typeof schema !== 'object' || schema === null) {
69
+ console.error('[envx] schema file must export a default schema object');
70
+ process.exit(1);
71
+ }
72
+ return schema;
73
+ }
74
+ async function cmdCheck(args) {
75
+ const envFile = typeof args['env'] === 'string' ? args['env'] : '.env';
76
+ const schemaFile = typeof args['schema'] === 'string' ? args['schema'] : 'envguard.schema.js';
77
+ const envPath = path.resolve(process.cwd(), envFile);
78
+ if (!fs.existsSync(envPath)) {
79
+ console.error(`[envx] env file not found: ${envPath}`);
80
+ process.exit(1);
81
+ }
82
+ const schema = await loadSchema(schemaFile);
83
+ const parsed = parseEnvFile(fs.readFileSync(envPath, 'utf8'));
84
+ const errors = validateEnvFile(parsed, schema);
85
+ if (errors.length === 0) {
86
+ console.log(`\x1b[32m✔ ${envFile} is valid\x1b[0m`);
87
+ return;
88
+ }
89
+ console.error(`\x1b[31m✖ ${envFile} has ${errors.length} error(s):\x1b[0m\n`);
90
+ for (const err of errors) {
91
+ const received = err.received !== undefined ? ` (received: \x1b[90m${JSON.stringify(err.received)}\x1b[0m)` : '';
92
+ console.error(` \x1b[33m${err.field}\x1b[0m: ${err.message}${received}`);
93
+ }
94
+ console.error('');
95
+ process.exit(1);
96
+ }
97
+ async function cmdGenerate(args) {
98
+ const schemaFile = typeof args['schema'] === 'string' ? args['schema'] : 'envguard.schema.js';
99
+ const outFile = typeof args['out'] === 'string' ? args['out'] : '.env.example';
100
+ const schema = await loadSchema(schemaFile);
101
+ const content = generateExample(schema);
102
+ fs.writeFileSync(path.resolve(process.cwd(), outFile), content, 'utf8');
103
+ console.log(`\x1b[32m✔ Generated ${outFile}\x1b[0m`);
104
+ }
105
+ function printHelp() {
106
+ console.log(`
107
+ \x1b[1menvx\x1b[0m — Environment variable validator
108
+
109
+ \x1b[1mUsage:\x1b[0m
110
+ envx check [--env <file>] [--schema <file>]
111
+ envx generate [--schema <file>] [--out <file>]
112
+
113
+ \x1b[1mCommands:\x1b[0m
114
+ check Validate a .env file against a schema (default: .env / envx.schema.js)
115
+ generate Generate a .env.example from a schema (default output: .env.example)
116
+
117
+ \x1b[1mOptions:\x1b[0m
118
+ --env Path to the .env file (default: .env)
119
+ --schema Path to the schema JS/TS file (default: envx.schema.js)
120
+ --out Output path for generate (default: .env.example)
121
+ --help Show this help message
122
+ `);
123
+ }
124
+ // ---------------------------------------------------------------------------
125
+ // Entry point
126
+ // ---------------------------------------------------------------------------
127
+ async function main() {
128
+ const [, , command, ...rest] = process.argv;
129
+ const args = parseArgs(rest);
130
+ if (args['help'] || !command) {
131
+ printHelp();
132
+ return;
133
+ }
134
+ switch (command) {
135
+ case 'check':
136
+ await cmdCheck(args);
137
+ break;
138
+ case 'generate':
139
+ await cmdGenerate(args);
140
+ break;
141
+ default:
142
+ console.error(`[envx] Unknown command: ${command}`);
143
+ printHelp();
144
+ process.exit(1);
145
+ }
146
+ }
147
+ main().catch((err) => {
148
+ console.error('[envx] Unexpected error:', err);
149
+ process.exit(1);
150
+ });
151
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,129 @@
1
+ import { EnvValidationError } from './errors.js';
2
+ // ---------------------------------------------------------------------------
3
+ // createEnv
4
+ // ---------------------------------------------------------------------------
5
+ /**
6
+ * Validates environment variables against the provided schema and returns a
7
+ * fully-typed, frozen object. Throws {@link EnvValidationError} on failure.
8
+ *
9
+ * @example
10
+ * ```ts
11
+ * export const env = createEnv({
12
+ * schema: {
13
+ * DATABASE_URL: url(),
14
+ * PORT: port({ default: 3000 }),
15
+ * NODE_ENV: str({ choices: ['development', 'production', 'test'], default: 'development' }),
16
+ * DEBUG: bool({ default: false }),
17
+ * API_KEY: str({ secret: true }),
18
+ * },
19
+ * })
20
+ * ```
21
+ */
22
+ export function createEnv(options) {
23
+ const { schema, env = process.env, skipValidation = false, onError } = options;
24
+ const errors = [];
25
+ const result = {};
26
+ for (const [field, spec] of Object.entries(schema)) {
27
+ const raw = env[field];
28
+ if (raw === undefined || raw === '') {
29
+ if (spec._default !== undefined) {
30
+ result[field] = spec._default;
31
+ continue;
32
+ }
33
+ if (!spec._required) {
34
+ // optional with no default → undefined (shouldn't happen given the overloads, but be safe)
35
+ result[field] = undefined;
36
+ continue;
37
+ }
38
+ errors.push({ field, message: 'is required but missing', received: undefined });
39
+ continue;
40
+ }
41
+ try {
42
+ const parsed = spec._parse(raw, field);
43
+ spec._validate(parsed, field);
44
+ result[field] = parsed;
45
+ }
46
+ catch (e) {
47
+ errors.push({
48
+ field,
49
+ message: e instanceof Error ? e.message : String(e),
50
+ received: spec._secret ? '[secret]' : raw,
51
+ });
52
+ }
53
+ }
54
+ if (errors.length > 0 && !skipValidation) {
55
+ onError?.(errors);
56
+ throw new EnvValidationError(errors);
57
+ }
58
+ return Object.freeze(result);
59
+ }
60
+ // ---------------------------------------------------------------------------
61
+ // generateExample
62
+ // ---------------------------------------------------------------------------
63
+ /**
64
+ * Generates the text content of a `.env.example` file from a schema.
65
+ * Variables without defaults are left blank; those with defaults show the default.
66
+ * Secrets are shown as `[secret]`.
67
+ *
68
+ * @example
69
+ * ```ts
70
+ * import { schema } from './env'
71
+ * import { generateExample } from 'envx'
72
+ * fs.writeFileSync('.env.example', generateExample(schema))
73
+ * ```
74
+ */
75
+ export function generateExample(schema) {
76
+ const lines = [
77
+ '# Auto-generated by envx — do not commit real secrets',
78
+ '',
79
+ ];
80
+ for (const [field, spec] of Object.entries(schema)) {
81
+ if (spec._description) {
82
+ lines.push(`# ${spec._description}`);
83
+ }
84
+ let value;
85
+ if (spec._secret) {
86
+ value = '[secret]';
87
+ }
88
+ else if (spec._default !== undefined) {
89
+ value = String(spec._default);
90
+ }
91
+ else {
92
+ value = '';
93
+ }
94
+ lines.push(`${field}=${value}`);
95
+ }
96
+ return lines.join('\n') + '\n';
97
+ }
98
+ // ---------------------------------------------------------------------------
99
+ // validateEnvFile
100
+ // ---------------------------------------------------------------------------
101
+ /**
102
+ * Given the parsed key=value pairs from a `.env` file and a schema, returns
103
+ * any validation errors without throwing. Useful in CI/pre-deploy checks.
104
+ */
105
+ export function validateEnvFile(parsed, schema) {
106
+ const errors = [];
107
+ for (const [field, spec] of Object.entries(schema)) {
108
+ const raw = parsed[field];
109
+ if (raw === undefined || raw === '') {
110
+ if (spec._default !== undefined || !spec._required)
111
+ continue;
112
+ errors.push({ field, message: 'is required but missing', received: undefined });
113
+ continue;
114
+ }
115
+ try {
116
+ const parsed2 = spec._parse(raw, field);
117
+ spec._validate(parsed2, field);
118
+ }
119
+ catch (e) {
120
+ errors.push({
121
+ field,
122
+ message: e instanceof Error ? e.message : String(e),
123
+ received: spec._secret ? '[secret]' : raw,
124
+ });
125
+ }
126
+ }
127
+ return errors;
128
+ }
129
+ //# sourceMappingURL=core.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"core.js","sourceRoot":"","sources":["../../src/core.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Thrown when one or more environment variables fail validation.
3
+ * Provides a structured list of field errors and a formatted human-readable message.
4
+ */
5
+ export class EnvValidationError extends Error {
6
+ constructor(errors) {
7
+ const lines = [
8
+ '',
9
+ ' ✖ Environment validation failed',
10
+ '',
11
+ ...errors.map((e) => ` ${e.field}: ${e.message}` +
12
+ (e.received !== undefined ? ` (received: ${JSON.stringify(e.received)})` : '')),
13
+ '',
14
+ ];
15
+ super(lines.join('\n'));
16
+ this.name = 'EnvValidationError';
17
+ this.errors = errors;
18
+ // Maintain proper prototype chain in transpiled CJS
19
+ Object.setPrototypeOf(this, new.target.prototype);
20
+ }
21
+ }
22
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/errors.ts"],"names":[],"mappings":"AAUA;;;GAGG;AACH,MAAM,OAAO,kBAAmB,SAAQ,KAAK;IAI3C,YAAY,MAAoB;QAC9B,MAAM,KAAK,GAAG;YACZ,EAAE;YACF,4CAA4C;YAC5C,EAAE;YACF,GAAG,MAAM,CAAC,GAAG,CACX,CAAC,CAAC,EAAE,EAAE,CACJ,UAAU,CAAC,CAAC,KAAK,SAAS,CAAC,CAAC,OAAO,EAAE;gBACrC,CAAC,CAAC,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,oBAAoB,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAC1F;YACD,EAAE;SACH,CAAA;QACD,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAA;QACvB,IAAI,CAAC,IAAI,GAAG,oBAAoB,CAAA;QAChC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAA;QACpB,oDAAoD;QACpD,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,CAAA;IACnD,CAAC;CACF"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * envx — Zero-dependency TypeScript env variable validator
3
+ * @module envx
4
+ */
5
+ // Core
6
+ export { createEnv, generateExample, validateEnvFile } from './core.js';
7
+ // Validators
8
+ export { str, num, bool, url, port, email, json, enums } from './validators.js';
9
+ // Errors
10
+ export { EnvValidationError } from './errors.js';
11
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO;AACP,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,WAAW,CAAA;AAGvE,aAAa;AACb,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAA;AAa/E,SAAS;AACT,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAA"}