env-drift-check 0.1.5 â 0.1.7
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 +53 -48
- package/dist/cli.js +85 -46
- package/package.json +8 -3
package/README.md
CHANGED
|
@@ -1,58 +1,67 @@
|
|
|
1
|
-
# env-drift-check:
|
|
1
|
+
# env-drift-check: Interactive .env Sync & Validation for Teams
|
|
2
2
|
|
|
3
3
|
[](https://www.npmjs.com/package/env-drift-check)
|
|
4
|
+
[](https://www.npmjs.com/package/env-drift-check)
|
|
4
5
|
[](https://opensource.org/licenses/MIT)
|
|
5
6
|
|
|
6
|
-
> **
|
|
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
|
|
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
|

|
|
11
12
|
|
|
12
|
-
##
|
|
13
|
+
## đ Why Use env-drift-check?
|
|
13
14
|
|
|
14
|
-
|
|
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** |
|
|
17
|
-
| **
|
|
18
|
-
| **Onboarding** |
|
|
19
|
-
| **Drift
|
|
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
|
-
###
|
|
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
|
|
25
|
-
- **
|
|
26
|
-
- **
|
|
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) -
|
|
31
|
-
- [Configuration](./docs/Configuration.md) - Advanced
|
|
32
|
-
- [Programmatic API](./docs/API-Reference.md) -
|
|
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
|
-
|
|
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.
|
|
48
|
-
|
|
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
|
-
###
|
|
55
|
-
|
|
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.
|
|
56
65
|
|
|
57
66
|
```bash
|
|
58
67
|
npx env-drift-check --interactive
|
|
@@ -66,16 +75,17 @@ Once completed, your `.env` file is automatically updated!
|
|
|
66
75
|
|
|
67
76
|

|
|
68
77
|
|
|
69
|
-
###
|
|
70
|
-
|
|
71
|
-
|
|
78
|
+
### 4. CI/CD & Strict Mode
|
|
79
|
+
Fail your build or test suite if environment variables are out of sync.
|
|
72
80
|
```bash
|
|
73
81
|
npx env-drift-check --strict
|
|
74
82
|
```
|
|
75
83
|
|
|
76
|
-
|
|
84
|
+
---
|
|
85
|
+
|
|
86
|
+
## đ Advanced Configuration
|
|
77
87
|
|
|
78
|
-
|
|
88
|
+
Define validation rules in `envwise.config.json` to ensure data integrity across environments.
|
|
79
89
|
|
|
80
90
|
```json
|
|
81
91
|
{
|
|
@@ -98,31 +108,26 @@ Create a `envwise.config.json` file in your root directory to define validation
|
|
|
98
108
|
"ENVIRONMENT": {
|
|
99
109
|
"type": "enum",
|
|
100
110
|
"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
111
|
}
|
|
107
112
|
}
|
|
108
113
|
}
|
|
109
114
|
```
|
|
110
115
|
|
|
111
|
-
### Validation Types
|
|
116
|
+
### Supported Validation Types
|
|
112
117
|
|
|
113
|
-
| Type |
|
|
118
|
+
| Type | Description | Example Rule |
|
|
114
119
|
| :--- | :--- | :--- |
|
|
115
|
-
| `string` | `min
|
|
116
|
-
| `number` | `min
|
|
117
|
-
| `boolean` |
|
|
118
|
-
| `enum` |
|
|
119
|
-
| `email` |
|
|
120
|
-
| `url` |
|
|
121
|
-
| `regex` |
|
|
120
|
+
| `string` | Length validation | `{ "min": 5, "max": 20 }` |
|
|
121
|
+
| `number` | Range validation | `{ "min": 1, "max": 100 }` |
|
|
122
|
+
| `boolean` | Flag checks | `{ "mustBeFalseIn": ["production"] }` |
|
|
123
|
+
| `enum` | Restricted values | `{ "values": ["v1", "v2"] }` |
|
|
124
|
+
| `email` | Standard email format | `type: "email"` |
|
|
125
|
+
| `url` | Valid URL/URI structure | `type: "url"` |
|
|
126
|
+
| `regex` | Custom pattern matching | `{ "regex": "^sk_live_.*" }` |
|
|
122
127
|
|
|
123
128
|
## Contributing
|
|
124
129
|
|
|
125
|
-
We welcome contributions!
|
|
130
|
+
We welcome contributions! See the [issues](https://github.com/shashi089/env-drift-check/issues) for planned features or bug reports.
|
|
126
131
|
|
|
127
132
|
1. Fork the repository.
|
|
128
133
|
2. Create your feature branch (`git checkout -b feature/amazing-feature`).
|
|
@@ -130,6 +135,6 @@ We welcome contributions! Please follow these steps:
|
|
|
130
135
|
4. Push to the branch (`git push origin feature/amazing-feature`).
|
|
131
136
|
5. Open a Pull Request.
|
|
132
137
|
|
|
133
|
-
##
|
|
138
|
+
## License
|
|
134
139
|
|
|
135
|
-
|
|
140
|
+
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
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
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.7");
|
|
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
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
const
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
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 (
|
|
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 = [
|
|
68
|
+
allFiles = [file];
|
|
60
69
|
}
|
|
61
70
|
let overallSuccess = true;
|
|
62
|
-
for (const
|
|
63
|
-
const success = await runForFile(
|
|
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.
|
|
4
|
-
"description": "Interactive
|
|
3
|
+
"version": "0.1.7",
|
|
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",
|