env-safe-check 1.0.0 → 1.0.2

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.
package/README.md CHANGED
@@ -1,93 +1,255 @@
1
- # env-safe-check
2
-
3
- Reliable, minimal utility to validate required environment variables at runtime.
4
-
5
- This tiny library helps Node and TypeScript projects fail fast with a clear
6
- error message when required environment variables are missing or empty.
7
-
8
- **Highlights**
9
-
10
- - Zero runtime dependencies
11
- - Tiny API: a single `validateEnv()` function
12
- - Works in TypeScript and JavaScript projects (ESM)
13
- - Safe defaults for CI and production (exits with non-zero code on missing vars)
14
-
15
- ## Installation
16
-
17
- Install from npm (devs using this repo can also build locally):
18
-
19
- ```bash
20
- npm install env-safe-check
21
- ```
22
-
23
- For local development (this repository):
24
-
25
- ```bash
26
- npm install
27
- npm run build
28
- ```
29
-
30
- ## Quick usage
31
-
32
- TypeScript (recommended):
33
-
34
- ```ts
35
- import { validateEnv } from 'env-safe-check';
36
-
37
- // throw and exit if any required env var is missing or empty
38
- validateEnv(['DATABASE_URL', 'API_KEY']);
39
- ```
40
-
41
- JavaScript (ESM):
42
-
43
- ```js
44
- import { validateEnv } from 'env-safe-check';
45
-
46
- validateEnv(['DATABASE_URL', 'API_KEY']);
47
- ```
48
-
49
- When any required variable is missing the library prints a friendly list
50
- and exits the process with code `1`.
51
-
52
- ## API
53
-
54
- - `validateEnv(required: string[]): void`
55
- - `required` — array of environment variable names to verify.
56
- - Throws/terminates the process (with a console error) when any are
57
- missing or empty.
58
-
59
- ## Project specifics (for contributors / package authors)
60
-
61
- - Source files are TypeScript in `src/`.
62
- - Build emits ESM JavaScript into `dist/`.
63
- - Source imports are written without `.js` extensions for ergonomics in
64
- TypeScript; the build process rewrites emitted imports to include `.js`
65
- so the output is runnable under Node ESM (`node >= 12` with ESM support).
66
-
67
- Commands:
68
-
69
- ```bash
70
- # Build and patch emitted imports
71
- npm run build
72
-
73
- # Run TypeScript type-check only
74
- npx tsc --noEmit
75
- ```
76
-
77
- ## Publishing
78
-
79
- 1. Bump the package version in `package.json`.
80
- 2. Run `npm run build` to produce `dist/`.
81
- 3. Verify the `main`/`exports` fields point to built files (if applicable).
82
- 4. `npm publish --access public`
83
-
84
- ## Contributing
85
-
86
- Contributions are welcome. Open issues for bugs or small feature requests.
87
-
88
- Please run the tests (if added) and ensure linting/type-checks pass before
89
- submitting a PR.
90
-
91
- ## License
92
-
93
- MIT
1
+ # env-safe-check
2
+
3
+ Reliable, minimal utility to validate required environment variables at runtime.
4
+
5
+ This tiny library helps Node and TypeScript projects fail fast with a clear
6
+ error message when required environment variables are missing or empty.
7
+
8
+ **Highlights**
9
+
10
+ - Zero runtime dependencies
11
+ - Two APIs: simple (legacy array) or powerful (schema-based)
12
+ - Type-safe: automatic parsing for `string`, `number`, `boolean`, `json`
13
+ - Custom validators: add your own validation logic
14
+ - Defaults & optional vars: sensible config for each variable
15
+ - Colorful error messages with variable descriptions
16
+ - Works in TypeScript and JavaScript projects (ESM)
17
+ - Safe defaults for CI and production (exits with non-zero code on errors)
18
+
19
+ ## Installation
20
+
21
+ Install from npm (devs using this repo can also build locally):
22
+
23
+ ```bash
24
+ npm install env-safe-check
25
+ ```
26
+
27
+ For local development (this repository):
28
+
29
+ ```bash
30
+ npm install
31
+ npm run build
32
+ ```
33
+
34
+ ## Quick usage
35
+
36
+ ### Simple mode (Legacy)
37
+
38
+ Validate a list of required environment variables:
39
+
40
+ ```ts
41
+ import { validateEnv } from 'env-safe-check';
42
+
43
+ // Exits with code 1 if any are missing
44
+ validateEnv(['DATABASE_URL', 'API_KEY']);
45
+ ```
46
+
47
+ ### Schema mode (Recommended)
48
+
49
+ Validate with types, defaults, custom validators, and descriptions:
50
+
51
+ ```ts
52
+ import { validateEnv, type VariableSchema } from 'env-safe-check';
53
+
54
+ const env = validateEnv({
55
+ schema: {
56
+ DATABASE_URL: { type: 'string', description: 'PostgreSQL connection URL' },
57
+ PORT: { type: 'number', default: '3000' },
58
+ DEBUG: { type: 'boolean', default: 'false', required: false },
59
+ NODE_ENV: {
60
+ type: 'string',
61
+ validator: (value) =>
62
+ ['development', 'production', 'test'].includes(value)
63
+ ? true
64
+ : 'Must be one of: development, production, test',
65
+ },
66
+ FEATURE_CONFIG: { type: 'json', required: false },
67
+ },
68
+ throwError: false, // default: exits process on error
69
+ silent: false, // default: prints colorful output
70
+ });
71
+
72
+ // Returns parsed and validated env object:
73
+ // { DATABASE_URL: string, PORT: number, DEBUG: boolean, NODE_ENV: string, FEATURE_CONFIG?: any }
74
+ console.log(env.PORT); // 3000 (or parsed value from process.env.PORT)
75
+ ```
76
+
77
+ ## API
78
+
79
+ ### `validateEnv(required: string[]): void` (Legacy)
80
+
81
+ - **required** array of environment variable names to verify
82
+ - **Returns** void; exits process (code 1) if any are missing or empty
83
+ - **Console output** — colorful error/success messages
84
+
85
+ ### `validateEnv(config: ValidateEnvOptions): Record<string, any>` (Recommended)
86
+
87
+ - **config.schema** — Record of variable names to schema definitions
88
+ - Each value can be:
89
+ - A type string shorthand: `'string' | 'number' | 'boolean' | 'json'`
90
+ - A full `VariableSchema` object (see below)
91
+ - **config.throwError** (default: `false`) — throw `EnvValidationError` instead of exiting process
92
+ - **config.silent** (default: `false`) — suppress console output
93
+ - **Returns** — `Record<string, any>` with parsed env variables
94
+ - **Throws** — `EnvValidationError` if `throwError: true` and validation fails
95
+
96
+ ### `VariableSchema`
97
+
98
+ ```ts
99
+ interface VariableSchema {
100
+ // Type of the variable. Parsed and validated accordingly.
101
+ // 'string' | 'number' | 'boolean' | 'json'
102
+ type?: 'string' | 'number' | 'boolean' | 'json';
103
+
104
+ // Whether this variable is required (default: true)
105
+ required?: boolean;
106
+
107
+ // Default value if not set and not required
108
+ default?: string;
109
+
110
+ // Custom validation function
111
+ // Return true if valid, or an error string if invalid
112
+ validator?: (value: string) => boolean | string;
113
+
114
+ // Description for error messages
115
+ description?: string;
116
+ }
117
+ ```
118
+
119
+ ### `EnvValidationError`
120
+
121
+ Thrown when validation fails with `throwError: true`:
122
+
123
+ ```ts
124
+ try {
125
+ const env = validateEnv({ schema: { /* ... */ }, throwError: true });
126
+ } catch (err) {
127
+ if (err instanceof EnvValidationError) {
128
+ console.error('Missing:', err.missing); // string[]
129
+ console.error('Invalid:', err.invalid); // Record<string, string>
130
+ }
131
+ }
132
+ ```
133
+
134
+ ## Examples
135
+
136
+ ### Type parsing with defaults
137
+
138
+ ```ts
139
+ const env = validateEnv({
140
+ schema: {
141
+ PORT: { type: 'number', default: '3000' },
142
+ TIMEOUT: { type: 'number', required: false },
143
+ ENABLE_CACHE: { type: 'boolean', default: 'true' },
144
+ },
145
+ });
146
+
147
+ // PORT is always a number (parsed from env or default)
148
+ // TIMEOUT is optional; undefined if not set
149
+ // ENABLE_CACHE is always a boolean
150
+ ```
151
+
152
+ ### Custom validators
153
+
154
+ ```ts
155
+ const env = validateEnv({
156
+ schema: {
157
+ WORKER_THREADS: {
158
+ type: 'number',
159
+ validator: (val) => {
160
+ const num = Number(val);
161
+ if (num < 1 || num > 32) {
162
+ return 'Must be between 1 and 32';
163
+ }
164
+ return true;
165
+ },
166
+ },
167
+ },
168
+ });
169
+ ```
170
+
171
+ ### Throw errors instead of exiting
172
+
173
+ ```ts
174
+ try {
175
+ const env = validateEnv({
176
+ schema: { DB_URL: 'string' },
177
+ throwError: true,
178
+ });
179
+ } catch (err) {
180
+ if (err instanceof EnvValidationError) {
181
+ // Handle custom error; code continues (doesn't exit)
182
+ }
183
+ }
184
+ ```
185
+
186
+ ## Project specifics (for contributors / package authors)
187
+
188
+ - Source files are TypeScript in `src/`.
189
+ - Build emits ESM JavaScript into `dist/`.
190
+ - Source imports are written without `.js` extensions for ergonomics in
191
+ TypeScript; the build process rewrites emitted imports to include `.js`
192
+ so the output is runnable under Node ESM (`node >= 12` with ESM support).
193
+
194
+ Commands:
195
+
196
+ ```bash
197
+ # Build and patch emitted imports
198
+ npm run build
199
+
200
+ # Run TypeScript type-check only
201
+ npx tsc --noEmit
202
+ ```
203
+
204
+ ## Publishing
205
+
206
+ 1. Bump the package version in `package.json`.
207
+ 2. Run `npm run build` to produce `dist/`.
208
+ 3. Verify the `main`/`exports` fields point to built files (if applicable).
209
+ 4. `npm publish --access public`
210
+
211
+ ## Contributing
212
+
213
+ Contributions are welcome. Open issues for bugs or small feature requests.
214
+
215
+ Please run the tests (if added) and ensure linting/type-checks pass before submitting a PR.
216
+
217
+ ### Conventional Commits
218
+
219
+ This project uses [semantic-release](https://semantic-release.gitbook.io/) to automate versioning and publishing based on commit messages. Please follow the [Conventional Commits](https://www.conventionalcommits.org/) format:
220
+
221
+
222
+ ```
223
+ type(scope): subject
224
+
225
+ body
226
+
227
+ footer
228
+ ```
229
+
230
+ **Types:**
231
+ - `feat:` A new feature (bumps minor version)
232
+ - `fix:` A bug fix (bumps patch version)
233
+ - `docs:` Documentation changes
234
+ - `style:` Code style changes (no logic changes)
235
+ - `refactor:` Refactor code without changing behavior
236
+ - `perf:` Performance improvements
237
+ - `test:` Adding/updating tests
238
+ - `ci:` CI/CD changes
239
+ - `chore:` Build, dependencies, etc.
240
+
241
+ **Breaking Changes:**
242
+ - Add `BREAKING CHANGE: description` in the footer to bump major version
243
+ - Or use `feat!:` in the type to indicate a breaking change
244
+
245
+ **Examples:**
246
+ ```bash
247
+ npm run cz # Interactive prompt (recommended)
248
+ git commit -m "feat: add JSON type validation"
249
+ git commit -m "fix: correct boolean parsing"
250
+ git commit -m "feat!: change API to return parsed object"
251
+ ```
252
+
253
+ ## License
254
+
255
+ MIT
@@ -0,0 +1,71 @@
1
+ /**
2
+ * Variable type for validation and parsing.
3
+ */
4
+ type VariableType = 'string' | 'number' | 'boolean' | 'json';
5
+ /**
6
+ * Schema definition for a single environment variable.
7
+ */
8
+ interface VariableSchema {
9
+ /**
10
+ * Type of the variable. Parsed and validated accordingly.
11
+ * @default 'string'
12
+ */
13
+ type?: VariableType;
14
+ /**
15
+ * Whether this variable is required.
16
+ * @default true
17
+ */
18
+ required?: boolean;
19
+ /**
20
+ * Default value if the variable is not set (and not required).
21
+ */
22
+ default?: string;
23
+ /**
24
+ * Custom validator function. Return true if valid, or an error message string if invalid.
25
+ */
26
+ validator?: (value: string) => boolean | string;
27
+ /**
28
+ * Description of the variable (for error messages).
29
+ */
30
+ description?: string;
31
+ }
32
+ /**
33
+ * Options for validateEnv function.
34
+ */
35
+ interface ValidateEnvOptions {
36
+ /**
37
+ * Schema defining required/optional vars, types, defaults, and validators.
38
+ */
39
+ schema: Record<string, VariableSchema | VariableType>;
40
+ /**
41
+ * If true, throw a custom error instead of calling process.exit(1).
42
+ * @default false
43
+ */
44
+ throwError?: boolean;
45
+ /**
46
+ * If true, don't print console messages.
47
+ * @default false
48
+ */
49
+ silent?: boolean;
50
+ }
51
+ /**
52
+ * Custom error thrown when validation fails (if throwError option is true).
53
+ */
54
+ declare class EnvValidationError extends Error {
55
+ readonly missing: string[];
56
+ readonly invalid: Record<string, string>;
57
+ constructor(message: string, missing?: string[], invalid?: Record<string, string>);
58
+ }
59
+
60
+ /**
61
+ * Validate environment variables against a schema with type checking, defaults, and custom validators.
62
+ *
63
+ * @overload
64
+ * function validateEnv(config: ValidateEnvOptions): Record<string, any>
65
+ *
66
+ * @overload
67
+ * function validateEnv(required: string[]): void
68
+ */
69
+ declare function validateEnv(configOrRequired: ValidateEnvOptions | string[]): Record<string, any> | void;
70
+
71
+ export { EnvValidationError, ValidateEnvOptions, VariableSchema, VariableType, validateEnv };
package/dist/index.js ADDED
@@ -0,0 +1,163 @@
1
+ // src/types.ts
2
+ var EnvValidationError = class extends Error {
3
+ constructor(message, missing = [], invalid = {}) {
4
+ super(message);
5
+ this.missing = missing;
6
+ this.invalid = invalid;
7
+ this.name = "EnvValidationError";
8
+ }
9
+ };
10
+
11
+ // src/validate.ts
12
+ var colors = {
13
+ reset: "\x1B[0m",
14
+ bold: "\x1B[1m",
15
+ red: "\x1B[31m",
16
+ green: "\x1B[32m",
17
+ yellow: "\x1B[33m",
18
+ cyan: "\x1B[36m",
19
+ gray: "\x1B[90m"
20
+ };
21
+ function parseValue(value, type) {
22
+ switch (type) {
23
+ case "number":
24
+ const num = Number(value);
25
+ if (isNaN(num))
26
+ throw new Error("Invalid number");
27
+ return num;
28
+ case "boolean":
29
+ if (value.toLowerCase() === "true" || value === "1")
30
+ return true;
31
+ if (value.toLowerCase() === "false" || value === "0")
32
+ return false;
33
+ throw new Error("Invalid boolean (expected 'true', 'false', '1', or '0')");
34
+ case "json":
35
+ return JSON.parse(value);
36
+ case "string":
37
+ default:
38
+ return value;
39
+ }
40
+ }
41
+ function validateEnv(configOrRequired) {
42
+ if (Array.isArray(configOrRequired)) {
43
+ validateEnvLegacy(configOrRequired);
44
+ return;
45
+ }
46
+ const config = configOrRequired;
47
+ const { schema, throwError = false, silent = false } = config;
48
+ const missing = [];
49
+ const invalid = {};
50
+ const parsed = {};
51
+ for (const [key, schemaDef] of Object.entries(schema)) {
52
+ const varSchema = typeof schemaDef === "string" ? { type: schemaDef } : schemaDef;
53
+ const isRequired = varSchema.required !== false;
54
+ const type = varSchema.type || "string";
55
+ const value = process.env[key];
56
+ if (value === void 0 || value.trim() === "") {
57
+ if (isRequired) {
58
+ missing.push(key);
59
+ } else if (varSchema.default !== void 0) {
60
+ try {
61
+ parsed[key] = parseValue(varSchema.default, type);
62
+ } catch (err) {
63
+ invalid[key] = `Default value invalid: ${err.message}`;
64
+ }
65
+ }
66
+ continue;
67
+ }
68
+ try {
69
+ parsed[key] = parseValue(value, type);
70
+ } catch (err) {
71
+ invalid[key] = `${err.message}`;
72
+ continue;
73
+ }
74
+ if (varSchema.validator) {
75
+ const validationResult = varSchema.validator(value);
76
+ if (validationResult !== true) {
77
+ const errorMsg = typeof validationResult === "string" ? validationResult : "Validation failed";
78
+ invalid[key] = errorMsg;
79
+ }
80
+ }
81
+ }
82
+ const hasErrors = missing.length > 0 || Object.keys(invalid).length > 0;
83
+ if (hasErrors) {
84
+ const errorMsg = buildErrorMessage(missing, invalid, schema);
85
+ if (!silent) {
86
+ console.error(errorMsg);
87
+ }
88
+ if (throwError) {
89
+ throw new EnvValidationError(
90
+ "Environment variable validation failed",
91
+ missing,
92
+ invalid
93
+ );
94
+ } else {
95
+ process.exit(1);
96
+ }
97
+ }
98
+ if (!silent) {
99
+ console.log(`${colors.green}\u2705 All environment variables are valid.${colors.reset}`);
100
+ }
101
+ return parsed;
102
+ }
103
+ function validateEnvLegacy(required) {
104
+ const missing = required.filter((key) => {
105
+ const value = process.env[key];
106
+ return value === void 0 || value.trim() === "";
107
+ });
108
+ if (missing.length > 0) {
109
+ console.error(
110
+ `${colors.red}${colors.bold}\u274C Missing required environment variables:${colors.reset}
111
+ `
112
+ );
113
+ missing.forEach((key) => {
114
+ console.error(`${colors.yellow}- ${key}${colors.reset}`);
115
+ });
116
+ console.error(
117
+ `
118
+ ${colors.cyan}Tip:${colors.reset} define them in your .env file or environment config.`
119
+ );
120
+ process.exit(1);
121
+ }
122
+ console.log(
123
+ `${colors.green}\u2705 All required environment variables are present.${colors.reset}`
124
+ );
125
+ }
126
+ function buildErrorMessage(missing, invalid, schema) {
127
+ let msg = `${colors.red}${colors.bold}\u274C Environment validation failed${colors.reset}
128
+ `;
129
+ if (missing.length > 0) {
130
+ msg += `
131
+ ${colors.bold}Missing required variables:${colors.reset}
132
+ `;
133
+ missing.forEach((key) => {
134
+ const desc = getSchemaDescription(key, schema);
135
+ msg += ` ${colors.yellow}${key}${colors.reset}${desc ? ` - ${colors.gray}${desc}${colors.reset}` : ""}
136
+ `;
137
+ });
138
+ }
139
+ if (Object.keys(invalid).length > 0) {
140
+ msg += `
141
+ ${colors.bold}Invalid variables:${colors.reset}
142
+ `;
143
+ for (const [key, error] of Object.entries(invalid)) {
144
+ msg += ` ${colors.yellow}${key}${colors.reset}: ${error}
145
+ `;
146
+ }
147
+ }
148
+ msg += `
149
+ ${colors.cyan}Tip:${colors.reset} define/fix them in your .env file or environment config.`;
150
+ return msg;
151
+ }
152
+ function getSchemaDescription(key, schema) {
153
+ const def = schema[key];
154
+ if (!def)
155
+ return "";
156
+ if (typeof def === "string")
157
+ return "";
158
+ return def.description || "";
159
+ }
160
+ export {
161
+ EnvValidationError,
162
+ validateEnv
163
+ };
package/package.json CHANGED
@@ -1,18 +1,45 @@
1
1
  {
2
2
  "name": "env-safe-check",
3
- "version": "1.0.0",
3
+ "version": "1.0.2",
4
4
  "type": "module",
5
- "main": "index.js",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "files": [
8
+ "dist"
9
+ ],
6
10
  "scripts": {
7
11
  "test": "echo \"hello world\"",
8
- "build": "tsc && node ./scripts/patch-extensions.cjs"
12
+ "build": "tsup src/index.ts --format esm --dts --out-dir dist",
13
+ "prepare": "npm run build && husky install",
14
+ "cz": "cz"
9
15
  },
10
- "keywords": [],
11
- "author": "",
16
+ "keywords": [
17
+ "env",
18
+ "environment",
19
+ "validation",
20
+ "safe",
21
+ "check",
22
+ "typescript"
23
+ ],
24
+ "author": "Pushpak Kurella",
12
25
  "license": "ISC",
13
26
  "description": "",
14
27
  "devDependencies": {
15
- "typescript": "^5.9.3",
16
- "@types/node": "^20.6.5"
28
+ "@commitlint/config-conventional": "^20.4.1",
29
+ "@semantic-release/github": "^12.0.6",
30
+ "@semantic-release/npm": "^13.1.4",
31
+ "@types/node": "^20.6.5",
32
+ "commitizen": "^4.3.1",
33
+ "commitlint": "^20.4.1",
34
+ "cz-conventional-changelog": "^3.3.0",
35
+ "husky": "^9.1.7",
36
+ "semantic-release": "^25.0.3",
37
+ "tsup": "^6.6.0",
38
+ "typescript": "^5.9.3"
39
+ },
40
+ "config": {
41
+ "commitizen": {
42
+ "path": "./node_modules/cz-conventional-changelog"
43
+ }
17
44
  }
18
45
  }
@@ -1,38 +0,0 @@
1
- # This workflow will run tests using node and then publish a package to GitHub Packages when a release is created
2
- # For more information see: https://docs.github.com/en/actions/publishing-packages/publishing-nodejs-packages
3
-
4
- name: Node.js Package
5
-
6
- on:
7
- release:
8
- types: [created]
9
- workflow_dispatch: {}
10
-
11
- jobs:
12
- build:
13
- # Only run automatically for the `main` branch or when a release is created.
14
- if: github.ref == 'refs/heads/main' || github.event_name == 'release' || github.event_name == 'workflow_dispatch'
15
- runs-on: ubuntu-latest
16
- steps:
17
- - uses: actions/checkout@v4
18
- - uses: actions/setup-node@v4
19
- with:
20
- node-version: 20
21
- - run: npm ci
22
- - run: npm test
23
-
24
- publish-npm:
25
- needs: build
26
- # Only publish when the run is for `main` or a release (keeps publishes scoped to main).
27
- if: github.ref == 'refs/heads/main' || github.event_name == 'release' || github.event_name == 'workflow_dispatch'
28
- runs-on: ubuntu-latest
29
- steps:
30
- - uses: actions/checkout@v4
31
- - uses: actions/setup-node@v4
32
- with:
33
- node-version: 20
34
- registry-url: https://registry.npmjs.org/
35
- - run: npm ci
36
- - run: npm publish
37
- env:
38
- NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}}
@@ -1,32 +0,0 @@
1
- const fs = require('fs');
2
- const path = require('path');
3
-
4
- function walk(dir) {
5
- const entries = fs.readdirSync(dir, { withFileTypes: true });
6
- for (const entry of entries) {
7
- const full = path.join(dir, entry.name);
8
- if (entry.isDirectory()) walk(full);
9
- else if (entry.isFile() && full.endsWith('.js')) patchFile(full);
10
- }
11
- }
12
-
13
- function patchFile(file) {
14
- let src = fs.readFileSync(file, 'utf8');
15
- src = src.replace(/(from\s+|import\()(["'])(\.\/[^"'\)]+?)\2/g, (m, p1, q, p2) => {
16
- if (/\.[a-zA-Z0-9]+$/.test(p2)) return m;
17
- return `${p1}${q}${p2}.js${q}`;
18
- });
19
- src = src.replace(/(export\s+[^;]*?from\s+)(["'])(\.\/[^"']+?)\2/g, (m, p1, q, p2) => {
20
- if (/\.[a-zA-Z0-9]+$/.test(p2)) return m;
21
- return `${p1}${q}${p2}.js${q}`;
22
- });
23
- fs.writeFileSync(file, src, 'utf8');
24
- }
25
-
26
- const dist = path.join(__dirname, '..', 'dist');
27
- if (!fs.existsSync(dist)) {
28
- console.error('dist directory not found; run tsc first');
29
- process.exit(1);
30
- }
31
- walk(dist);
32
- console.log('Patched imports to include .js extensions in', dist);
@@ -1,38 +0,0 @@
1
- const fs = require('fs');
2
- const path = require('path');
3
-
4
- function walk(dir) {
5
- const entries = fs.readdirSync(dir, { withFileTypes: true });
6
- for (const entry of entries) {
7
- const full = path.join(dir, entry.name);
8
- if (entry.isDirectory()) walk(full);
9
- else if (entry.isFile() && full.endsWith('.js')) patchFile(full);
10
- }
11
- }
12
-
13
- function patchFile(file) {
14
- let src = fs.readFileSync(file, 'utf8');
15
- // Replace import/export specifiers that are relative and have no extension
16
- // Examples: import {x} from "./foo" -> ./foo.js
17
- // export * from './bar' -> ./bar.js
18
- src = src.replace(/(from\s+|import\()(["'])(\.\/[^"'\)]+?)\2/g, (m, p1, q, p2) => {
19
- // p2 is like ./module or ../module/sub
20
- // If it already ends with an extension, leave it
21
- if (/\.[a-zA-Z0-9]+$/.test(p2)) return m;
22
- return `${p1}${q}${p2}.js${q}`;
23
- });
24
- // also handle export ... from '...'
25
- src = src.replace(/(export\s+[^;]*?from\s+)(["'])(\.\/[^"']+?)\2/g, (m, p1, q, p2) => {
26
- if (/\.[a-zA-Z0-9]+$/.test(p2)) return m;
27
- return `${p1}${q}${p2}.js${q}`;
28
- });
29
- fs.writeFileSync(file, src, 'utf8');
30
- }
31
-
32
- const dist = path.join(__dirname, '..', 'dist');
33
- if (!fs.existsSync(dist)) {
34
- console.error('dist directory not found; run tsc first');
35
- process.exit(1);
36
- }
37
- walk(dist);
38
- console.log('Patched imports to include .js extensions in', dist);
package/src/index.ts DELETED
@@ -1 +0,0 @@
1
- export { validateEnv } from "./validate";
package/src/validate.ts DELETED
@@ -1,20 +0,0 @@
1
- export function validateEnv(required: string[]): void {
2
- const missing = required.filter((key) => {
3
- const value = process.env[key];
4
- return value === undefined || value.trim() === "";
5
- });
6
-
7
- if (missing.length > 0) {
8
- console.error("❌ Missing required environment variables:\n");
9
-
10
- missing.forEach((key) => {
11
- console.error(`- ${key}`);
12
- });
13
-
14
- console.error(
15
- "\nPlease define them in your .env file or environment config."
16
- );
17
-
18
- process.exit(1);
19
- }
20
- }
package/tsconfig.json DELETED
@@ -1,46 +0,0 @@
1
- {
2
- // Visit https://aka.ms/tsconfig to read more about this file
3
- "compilerOptions": {
4
- // File Layout
5
- // "rootDir": "./src",
6
- // "outDir": "./dist",
7
-
8
- // Environment Settings
9
- // See also https://aka.ms/tsconfig/module
10
- "module": "esnext",
11
- "moduleResolution": "node",
12
- "target": "esnext",
13
- "outDir": "./dist",
14
- "types": ["node"],
15
- // For nodejs:
16
- // "lib": ["esnext"],
17
- // "types": ["node"],
18
- // and npm install -D @types/node
19
-
20
- // Other Outputs
21
- "sourceMap": true,
22
- "declaration": true,
23
- "declarationMap": true,
24
-
25
- // Stricter Typechecking Options
26
- "noUncheckedIndexedAccess": true,
27
- "exactOptionalPropertyTypes": true,
28
-
29
- // Style Options
30
- // "noImplicitReturns": true,
31
- // "noImplicitOverride": true,
32
- // "noUnusedLocals": true,
33
- // "noUnusedParameters": true,
34
- // "noFallthroughCasesInSwitch": true,
35
- // "noPropertyAccessFromIndexSignature": true,
36
-
37
- // Recommended Options
38
- "strict": true,
39
- "jsx": "react-jsx",
40
- "verbatimModuleSyntax": true,
41
- "isolatedModules": true,
42
- "noUncheckedSideEffectImports": true,
43
- "moduleDetection": "force",
44
- "skipLibCheck": true,
45
- }
46
- }