env-drift-check 0.1.5 → 0.1.6

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 (3) hide show
  1. package/README.md +53 -55
  2. package/dist/cli.js +85 -46
  3. package/package.json +8 -3
package/README.md CHANGED
@@ -1,81 +1,84 @@
1
- # env-drift-check: Automatic .env Sync & Validation
1
+ # env-drift-check: Interactive .env Sync & Validation for Teams
2
2
 
3
3
  [![npm version](https://img.shields.io/npm/v/env-drift-check.svg)](https://www.npmjs.com/package/env-drift-check)
4
+ [![npm downloads](https://img.shields.io/npm/dm/env-drift-check.svg)](https://www.npmjs.com/package/env-drift-check)
4
5
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
5
6
 
6
- > **Stop copy-pasting `.env` files.** Onboard developers in seconds with interactive prompts, smart schema validation, and drift detection.
7
+ > **Eliminate "It works on my machine" issues.** Synchronize `.env` files across your team with interactive prompts, smart schema validation, and real-time drift detection.
7
8
 
8
- **env-drift-check** is the ultimate CLI tool for managing environment variables in Node.js projects. It ensures your local `.env` file is always in sync with `.env.example`, preventing runtime errors caused by missing keys. Perfect for teams and CI/CD pipelines.
9
+ **env-drift-check** is a powerful CLI utility designed to manage environment variables in Node.js applications. It ensures your local `.env` remains in perfect sync with `.env.example`, preventing runtime crashes and streamlining developer onboarding.
9
10
 
10
11
  ![env-drift-check demo](https://github.com/shashi089/env-drift-check/raw/main/assets/env-drift-check.png)
11
12
 
12
- ## Why use this?
13
+ ## 🚀 Why Use env-drift-check?
13
14
 
14
- | Feature | Other Tools | **env-drift-check** |
15
+ Manually managing environment variables is error-prone. **env-drift-check** automates the process:
16
+
17
+ | Pain Point | Standard Approach | **env-drift-check** |
15
18
  | :--- | :--- | :--- |
16
- | **Missing Keys** | Crash & Exit | **Interactive Setup Wizard** |
17
- | **Validation** | Basic Existence Check | **Rich Types** (Email, URL, Regex, Number) |
18
- | **Onboarding** | Manual (Read docs → Copy → Paste) | **Automated** (Run command → Fill prompts) |
19
- | **Drift Detection** | Static | **Real-time** comparison with `.env.example` |
19
+ | **Missing Keys** | Application crashes at runtime | **Interactive Setup Wizard** fills them |
20
+ | **Type Safety** | String-only values, no validation | **Rich Validation** (Email, URL, Regex) |
21
+ | **Team Onboarding** | "Copy this file from Slack/Docs" | `npx env-drift-check init` & sync |
22
+ | **Configuration Drift** | Desync between dev/stage/prod | **Real-time Detection** against template |
20
23
 
21
- ### Features
24
+ ### Key Features
22
25
 
23
- - **Interactive Mode**: Automatically detects missing keys and prompts you to fill them in via CLI.
24
- - **Smart Schema Validation**: Enforce types like `email`, `url`, `number`, `boolean`, `enum`, and custom `regex`.
25
- - **Drift Detection**: Instantly compare your local environment against the team's `.env.example`.
26
- - **Zero Config**: Works out of the box, or add `envwise.config.json` for advanced validation rules.
26
+ - **Interactive Mode**: Automatically detects missing keys and prompts you to fill them in directly via the CLI.
27
+ - **Smart Schema Validation**: Enforce strict types including `email`, `url`, `number`, `boolean`, `enum`, and custom `regex`.
28
+ - **Zero Config Setup**: Works out of the box. Add an optional `envwise.config.json` for advanced rules.
29
+ - **CI/CD Ready**: Use `--strict` mode in your build pipeline to prevent deployments with missing variables.
27
30
 
28
31
  ## 📖 Documentation
29
32
 
30
- - [CLI Usage](./docs/CLI-Usage.md) - Command line flags and examples.
31
- - [Configuration](./docs/Configuration.md) - Advanced validation rules and `envwise.config.json`.
32
- - [Programmatic API](./docs/API-Reference.md) - Using the package in your code.
33
+ - [CLI Usage](./docs/CLI-Usage.md) - Detailed flags and command examples.
34
+ - [Configuration](./docs/Configuration.md) - Advanced types and `envwise.config.json` schema.
35
+ - [Programmatic API](./docs/API-Reference.md) - Integrating the validation engine into your code.
33
36
 
34
37
  ## Installation
35
38
 
36
-
37
- Install globally or as a dev dependency:
38
-
39
39
  ```bash
40
- npm install -g env-drift-check
41
- # OR
40
+ # Install as a dev dependency (Recommended)
42
41
  npm install --save-dev env-drift-check
42
+
43
+ # OR install globally
44
+ npm install -g env-drift-check
43
45
  ```
44
46
 
45
47
  ## Usage
46
48
 
47
- ### 1. Basic Check
48
- Check if your `.env` is missing any keys defined in `.env.example`. This is great for a quick status check.
49
+ ### 1. Initialize (New Setup)
50
+ Bootstrap your project by creating a configuration and an example environment file.
51
+ ```bash
52
+ npx env-drift-check init
53
+ ```
49
54
 
55
+ ### 2. Basic Check
56
+ Compare your `.env` against the reference (default: `.env.example`).
50
57
  ```bash
51
58
  npx env-drift-check
59
+ # Specify a custom reference file
60
+ npx env-drift-check --base .env.production
52
61
  ```
53
62
 
54
- ### 2. Interactive Setup (Recommended)
55
- The **interactive mode** is the star feature. If missing keys are found, it launches a wizard to help you fill them in without leaving your terminal.
56
-
63
+ ### 3. Interactive Sync (The "Magic" Feature)
64
+ If missing variables are found, launch the interactive wizard to fill them in without leaving your IDE.
57
65
  ```bash
58
66
  npx env-drift-check --interactive
59
67
  # OR
60
68
  npx env-drift-check -i
61
69
  ```
62
70
 
63
- ![Interactive update](https://github.com/shashi089/env-drift-check/raw/main/assets/env-drift-check-i-update.png)
64
-
65
- Once completed, your `.env` file is automatically updated!
66
-
67
- ![Interactive success](https://github.com/shashi089/env-drift-check/raw/main/assets/env-drift-check-i-final.png)
68
-
69
- ### 3. CI/CD Mode (Strict)
70
- Ensure no broken code hits production. Use strict mode in your build pipeline to fail if environment variables are missing.
71
-
71
+ ### 4. CI/CD & Strict Mode
72
+ Fail your build or test suite if environment variables are out of sync.
72
73
  ```bash
73
74
  npx env-drift-check --strict
74
75
  ```
75
76
 
76
- ## Configuration
77
+ ---
77
78
 
78
- Create a `envwise.config.json` file in your root directory to define validation rules and defaults. This acts as a schema for your environment variables.
79
+ ## 🛠 Advanced Configuration
80
+
81
+ Define validation rules in `envwise.config.json` to ensure data integrity across environments.
79
82
 
80
83
  ```json
81
84
  {
@@ -98,31 +101,26 @@ Create a `envwise.config.json` file in your root directory to define validation
98
101
  "ENVIRONMENT": {
99
102
  "type": "enum",
100
103
  "values": ["development", "production", "test"]
101
- },
102
- "API_KEY": {
103
- "type": "regex",
104
- "regex": "^[A-Z0-9]{32}$",
105
- "description": "32-character alphanumeric API key"
106
104
  }
107
105
  }
108
106
  }
109
107
  ```
110
108
 
111
- ### Validation Types
109
+ ### Supported Validation Types
112
110
 
113
- | Type | Options | Description |
111
+ | Type | Description | Example Rule |
114
112
  | :--- | :--- | :--- |
115
- | `string` | `min`, `max` | Validate string length. |
116
- | `number` | `min`, `max` | Validate numeric ranges. |
117
- | `boolean` | `mustBeFalseIn` | Ensure flags (like debug mode) are off in prod. |
118
- | `enum` | `values` (array) | Restrict to a set of allowed values. |
119
- | `email` | - | Validate standard email formats. |
120
- | `url` | - | Validate URL structure. |
121
- | `regex` | `regex` (string) | Custom pattern matching for keys, secrets, etc. |
113
+ | `string` | Length validation | `{ "min": 5, "max": 20 }` |
114
+ | `number` | Range validation | `{ "min": 1, "max": 100 }` |
115
+ | `boolean` | Flag checks | `{ "mustBeFalseIn": ["production"] }` |
116
+ | `enum` | Restricted values | `{ "values": ["v1", "v2"] }` |
117
+ | `email` | Standard email format | `type: "email"` |
118
+ | `url` | Valid URL/URI structure | `type: "url"` |
119
+ | `regex` | Custom pattern matching | `{ "regex": "^sk_live_.*" }` |
122
120
 
123
121
  ## Contributing
124
122
 
125
- We welcome contributions! Please follow these steps:
123
+ We welcome contributions! See the [issues](https://github.com/shashi089/env-drift-check/issues) for planned features or bug reports.
126
124
 
127
125
  1. Fork the repository.
128
126
  2. Create your feature branch (`git checkout -b feature/amazing-feature`).
@@ -130,6 +128,6 @@ We welcome contributions! Please follow these steps:
130
128
  4. Push to the branch (`git push origin feature/amazing-feature`).
131
129
  5. Open a Pull Request.
132
130
 
133
- ## License
131
+ ## License
134
132
 
135
- This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
133
+ MIT Š [Shashidhar Naik](https://github.com/shashi089)
package/dist/cli.js CHANGED
@@ -6,70 +6,109 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
6
6
  Object.defineProperty(exports, "__esModule", { value: true });
7
7
  const fs_1 = __importDefault(require("fs"));
8
8
  const path_1 = __importDefault(require("path"));
9
+ const commander_1 = require("commander");
9
10
  const envParser_1 = require("./engine/envParser");
10
11
  const driftChecker_1 = require("./engine/driftChecker");
11
12
  const consoleReporter_1 = require("./reporter/consoleReporter");
12
13
  const interactive_1 = require("./engine/interactive");
13
14
  const loadConfig_1 = require("./config/loadConfig");
14
- const args = process.argv.slice(2);
15
- const strict = args.includes("--strict");
16
- const interactive = args.includes("--interactive") || args.includes("-i");
17
- const checkAll = args.includes("--all");
18
- const positionalArgs = args.filter(a => !a.startsWith("-"));
19
- const config = (0, loadConfig_1.loadConfig)();
20
- const basePath = path_1.default.resolve(config.baseEnv || ".env.example");
21
- if (!fs_1.default.existsSync(basePath)) {
22
- console.error(`Reference file missing: ${basePath}`);
23
- process.exit(1);
24
- }
25
- const baseEnv = (0, envParser_1.parseEnv)(basePath);
26
- async function runForFile(targetFile) {
27
- const targetPath = path_1.default.resolve(targetFile);
28
- if (!fs_1.default.existsSync(targetPath)) {
29
- console.error(`File missing: ${targetFile}`);
30
- return false;
15
+ const program = new commander_1.Command();
16
+ program
17
+ .name("env-drift-check")
18
+ .description("Interactive .env synchronizer and validator")
19
+ .version("0.1.5");
20
+ program
21
+ .command("check", { isDefault: true })
22
+ .description("Check for environment drift (default command)")
23
+ .argument("[file]", "Target .env file to check", ".env")
24
+ .option("-b, --base <reference>", "Reference .env file to check against (e.g., .env.example)")
25
+ .option("-i, --interactive", "Launch interactive setup wizard for missing keys")
26
+ .option("-s, --strict", "Fail with non-zero exit code if issues are found")
27
+ .option("-a, --all", "Check all .env* files in the current directory")
28
+ .action(async (file, options) => {
29
+ const config = (0, loadConfig_1.loadConfig)();
30
+ const basePath = path_1.default.resolve(options.base || config.baseEnv || ".env.example");
31
+ if (!fs_1.default.existsSync(basePath)) {
32
+ console.error(`Reference file missing: ${basePath}`);
33
+ process.exit(1);
31
34
  }
32
- console.log(`\n Checking ${path_1.default.basename(targetPath)} against ${path_1.default.basename(basePath)}...`);
33
- const targetEnv = (0, envParser_1.parseEnv)(targetPath);
34
- let result = (0, driftChecker_1.checkDrift)(baseEnv, targetEnv, config);
35
- if (result.missing.length > 0 && interactive) {
36
- const newValues = await (0, interactive_1.interactiveSetup)(result.missing, baseEnv, config);
37
- // Merge new values into targetEnv
38
- const updatedEnv = { ...targetEnv, ...newValues };
39
- // Write back to file
40
- const newContent = Object.entries(updatedEnv)
41
- .map(([k, v]) => `${k}=${v}`)
42
- .join("\n");
43
- fs_1.default.writeFileSync(targetPath, newContent);
44
- console.log(`\n ✅ Updated ${path_1.default.basename(targetPath)} with new values.`);
45
- // Re-check drift
46
- result = (0, driftChecker_1.checkDrift)(baseEnv, updatedEnv, config);
35
+ const baseEnv = (0, envParser_1.parseEnv)(basePath);
36
+ async function runForFile(targetFile) {
37
+ const targetPath = path_1.default.resolve(targetFile);
38
+ if (!fs_1.default.existsSync(targetPath)) {
39
+ console.error(`File missing: ${targetFile}`);
40
+ return false;
41
+ }
42
+ console.log(`\n Checking ${path_1.default.basename(targetPath)} against ${path_1.default.basename(basePath)}...`);
43
+ const targetEnv = (0, envParser_1.parseEnv)(targetPath);
44
+ let result = (0, driftChecker_1.checkDrift)(baseEnv, targetEnv, config);
45
+ if (result.missing.length > 0 && options.interactive) {
46
+ const newValues = await (0, interactive_1.interactiveSetup)(result.missing, baseEnv, config);
47
+ // Merge new values into targetEnv
48
+ const updatedEnv = { ...targetEnv, ...newValues };
49
+ // Write back to file
50
+ const newContent = Object.entries(updatedEnv)
51
+ .map(([k, v]) => `${k}=${v}`)
52
+ .join("\n");
53
+ fs_1.default.writeFileSync(targetPath, newContent);
54
+ console.log(`\n ✅ Updated ${path_1.default.basename(targetPath)} with new values.`);
55
+ // Re-check drift
56
+ result = (0, driftChecker_1.checkDrift)(baseEnv, updatedEnv, config);
57
+ }
58
+ (0, consoleReporter_1.report)(result);
59
+ const hasIssues = result.missing.length || result.mismatches.length || result.errors.length;
60
+ return !hasIssues;
47
61
  }
48
- (0, consoleReporter_1.report)(result);
49
- const hasIssues = result.missing.length || result.mismatches.length || result.errors.length;
50
- return !hasIssues;
51
- }
52
- async function main() {
53
62
  let allFiles = [];
54
- if (checkAll) {
63
+ if (options.all) {
55
64
  allFiles = fs_1.default.readdirSync(process.cwd())
56
65
  .filter(f => f.startsWith(".env") && f !== path_1.default.basename(basePath));
57
66
  }
58
67
  else {
59
- allFiles = [positionalArgs[0] || ".env"];
68
+ allFiles = [file];
60
69
  }
61
70
  let overallSuccess = true;
62
- for (const file of allFiles) {
63
- const success = await runForFile(file);
71
+ for (const f of allFiles) {
72
+ const success = await runForFile(f);
64
73
  if (!success)
65
74
  overallSuccess = false;
66
75
  }
67
- if (strict && !overallSuccess) {
76
+ if (options.strict && !overallSuccess) {
68
77
  console.error("\n Strict mode failed for one or more files");
69
78
  process.exit(1);
70
79
  }
71
- }
72
- main().catch(err => {
73
- console.error(err);
74
- process.exit(1);
75
80
  });
81
+ program
82
+ .command("init")
83
+ .description("Initialize a new project with default configuration")
84
+ .action(() => {
85
+ const configPath = path_1.default.join(process.cwd(), "envwise.config.json");
86
+ const exampleEnvPath = path_1.default.join(process.cwd(), ".env.example");
87
+ if (fs_1.default.existsSync(configPath)) {
88
+ console.log("â„šī¸ envwise.config.json already exists.");
89
+ }
90
+ else {
91
+ const defaultConfig = {
92
+ baseEnv: ".env.example",
93
+ rules: {
94
+ PORT: {
95
+ type: "number",
96
+ min: 1024,
97
+ max: 65535,
98
+ description: "Application port"
99
+ }
100
+ }
101
+ };
102
+ fs_1.default.writeFileSync(configPath, JSON.stringify(defaultConfig, null, 2));
103
+ console.log("✅ Created envwise.config.json");
104
+ }
105
+ if (fs_1.default.existsSync(exampleEnvPath)) {
106
+ console.log("â„šī¸ .env.example already exists.");
107
+ }
108
+ else {
109
+ fs_1.default.writeFileSync(exampleEnvPath, "PORT=3000\n");
110
+ console.log("✅ Created .env.example");
111
+ }
112
+ console.log("\nSetup complete! Run 'npx env-drift-check -i' to sync your .env file.");
113
+ });
114
+ program.parse(process.argv);
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "env-drift-check",
3
- "version": "0.1.5",
4
- "description": "Interactive environment variable checker and setup wizard. Sync .env files with validation (Email, URL, Regex) and prompts.",
3
+ "version": "0.1.6",
4
+ "description": "Interactive .env synchronizer and validator. Detect environment drift, sync missing variables, and enforce schema validation for seamless developer onboarding.",
5
5
  "keywords": [
6
6
  "env",
7
7
  "dotenv",
@@ -16,7 +16,12 @@
16
16
  "setup",
17
17
  "onboarding",
18
18
  "drift",
19
- "checker"
19
+ "checker",
20
+ "cli-tool",
21
+ "dx",
22
+ "env-sync",
23
+ "security",
24
+ "workflow"
20
25
  ],
21
26
  "author": "Shashidhar Naik",
22
27
  "license": "MIT",