envilder 0.5.0 → 0.5.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,12 +1,9 @@
1
1
  <h1 align="center">
2
2
  <br>
3
3
  <img src="https://github.com/user-attachments/assets/96bf1efa-7d21-440a-a414-3a20e7f9a1f1" alt="Envilder">
4
- <br>
5
- Envilder
6
- <br>
7
4
  </h1>
8
5
 
9
- <h4 align="center">Secure Your Environment Variables with AWS SSM Parameter Store</h4>
6
+ <h4 align="center">A CLI that securely centralizes your environment variables from AWS SSM as a single source of truth</h4>
10
7
 
11
8
  <p align="center">
12
9
  <a href="https://www.npmjs.com/package/envilder">
@@ -20,11 +17,16 @@
20
17
  </a>
21
18
  </p>
22
19
 
23
- <p align="center">
24
- <b>Stop committing secrets to your repo! Start using AWS SSM Parameter Store to secure your credentials.</b>
25
- </p>
20
+ ## 🌟 Key benefits
21
+
22
+ - **🔒 Strict access control** - AWS IAM policies control who accesses which secrets (dev vs prod)
23
+ - **📊 Full audit trail** - All parameter access is logged in CloudTrail for compliance requirements
24
+ - **ðŸ§Đ Single source of truth** - No more copying .env files from Notion or emails - SSM is your only source
25
+ - **🔁 Idempotent operations** - Won't overwrite your local values - safe for automation
26
+ - **⚙ïļ Environment-aware** - Use templates like `/project/${ENV}/DB_PASSWORD` to dynamically fetch the right secrets
27
+ - **ðŸ§ą No extra infrastructure** - Uses AWS SSM's existing reliability instead of additional secret managers
26
28
 
27
- ## ⚡ Quick Start
29
+ ## ⚡ Quick start
28
30
 
29
31
  ```bash
30
32
  # Install globally
@@ -37,7 +39,7 @@ echo '{"DB_PASSWORD": "/my-app/db/password"}' > param-map.json
37
39
  envilder --map=param-map.json --envfile=.env
38
40
  ```
39
41
 
40
- ## ðŸĪ” What Problem Does Envilder Solve?
42
+ ## ðŸĪ” What problem does Envilder solve?
41
43
 
42
44
  <table>
43
45
  <tr>
@@ -72,23 +74,23 @@ envilder --map=param-map.json --envfile=.env
72
74
 
73
75
  ## ðŸ’Ą Why Envilder?
74
76
 
75
- - 🔐 **No More Secrets in Git** - Store credentials in AWS SSM Parameter Store instead of version control
76
- - ðŸĪ– **Automate Everything** - One command to generate your `.env` files across all environments
77
- - 🔄 **Always in Sync** - Keep your local, dev, and production environments consistent
78
- - 🏎ïļ **Fast to Set Up** - Configure once, then generate `.env` files with a single command
79
- - ðŸŠķ **Simple but Powerful** - Easy interface with support for encrypted parameters and multiple AWS profiles
77
+ - 🔐 **No more secrets in git** - Store credentials in AWS SSM Parameter Store instead of version control
78
+ - ðŸĪ– **Automate everything** - One command to generate your `.env` files across all environments
79
+ - 🔄 **Always in sync** - Keep your local, dev, and production environments consistent
80
+ - 🏎ïļ **Fast to set up** - Configure once, then generate `.env` files with a single command
81
+ - ðŸŠķ **Simple but powerful** - Easy interface with support for encrypted parameters and multiple AWS profiles
80
82
 
81
- ## ðŸŽŊ Perfect for Teams
83
+ ## ðŸŽŊ Perfect for teams
82
84
 
83
85
  Envilder is the tool you need if you:
84
86
 
85
- - ðŸ‘Ĩ **Work in a Development Team** - Ensure everyone has the same environment without sharing raw secrets
86
- - 🔑 **Deal with API Keys & Tokens** - Securely store and retrieve sensitive credentials
87
- - ⚙ïļ **Run CI/CD Pipelines** - Automatically generate environment files during deployments
88
- - ☁ïļ **Use AWS Already** - Leverage your existing AWS infrastructure more effectively
89
- - 🌐 **Manage Multiple Environments** - Switch easily between dev, staging, and production
87
+ - ðŸ‘Ĩ **Work in a development team** - Ensure everyone has the same environment without sharing raw secrets
88
+ - 🔑 **Deal with API keys & tokens** - Securely store and retrieve sensitive credentials
89
+ - ⚙ïļ **Run CI/CD pipelines** - Automatically generate environment files during deployments
90
+ - ☁ïļ **Use AWS already** - Leverage your existing AWS infrastructure more effectively
91
+ - 🌐 **Manage multiple environments** - Switch easily between dev, staging, and production
90
92
 
91
- ## 🔍 How It Works (Simple!)
93
+ ## 🔍 How it works (simple!)
92
94
 
93
95
  ```mermaid
94
96
  graph LR
@@ -98,10 +100,10 @@ graph LR
98
100
  E[SSM Parameters] --> B
99
101
  ```
100
102
 
101
- 1. 📖 **Define Your Mapping** - Simple JSON mapping env vars to SSM paths
103
+ 1. 📖 **Define your mapping** - Simple JSON mapping env vars to SSM paths
102
104
  2. 🚀 **Run Envilder** - One command with your mapping file
103
- 3. 🔄 **Auto-Fetch from AWS** - Retrieves values using your AWS credentials
104
- 4. ðŸ’ū **Get Your .env File** - Ready to use in your project
105
+ 3. 🔄 **Auto-fetch from AWS** - Retrieves values using your AWS credentials
106
+ 4. ðŸ’ū **Get your .env file** - Ready to use in your project
105
107
 
106
108
  ## ⚙ïļ Prerequisites
107
109
 
@@ -110,7 +112,7 @@ You'll need:
110
112
  - ✅ **AWS CLI** - Installed and configured with proper permissions to access SSM Parameter Store
111
113
  - ✅ **Node.js** - Version 14 or higher
112
114
 
113
- ### AWS CLI Setup
115
+ ### AWS CLI setup
114
116
 
115
117
  1. Install the AWS CLI by following the [official instructions](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html).
116
118
  2. After installation, configure the AWS CLI:
@@ -149,7 +151,7 @@ envilder --map=<mapping-file> --envfile=<output-file> [--profile=<aws-profile>]
149
151
  | `--envfile` | Path to output .env file (required) |
150
152
  | `--profile` | AWS CLI profile to use (optional) |
151
153
 
152
- ## 🔧 Quick Example
154
+ ## 🔧 Quick example
153
155
 
154
156
  1. Create a mapping file `param-map.json`:
155
157
 
@@ -172,7 +174,7 @@ envilder --map=<mapping-file> --envfile=<output-file> [--profile=<aws-profile>]
172
174
  envilder --map=param-map.json --envfile=.env --profile=dev-account
173
175
  ```
174
176
 
175
- ## 🌐 Working with Multiple AWS Profiles
177
+ ## 🌐 Working with multiple AWS profiles
176
178
 
177
179
  For multiple AWS accounts or environments, configure different profiles in your AWS credentials file:
178
180
 
@@ -203,14 +205,63 @@ or `%USERPROFILE%\.aws\credentials` on Windows):
203
205
  envilder --map=param-map.json --envfile=.env.production --profile=prod-account
204
206
  ```
205
207
 
206
- ## 📂 Sample `.env` Output
208
+ ## 🛠ïļ Advanced usage: environment-specific parameters
209
+
210
+ Envilder works brilliantly with environment variables for dynamic parameter paths:
211
+
212
+ 1. Set up your SSM parameters with environment-specific paths:
213
+
214
+ ```text
215
+ /project/dev/DB_PASSWORD
216
+ /project/stage/DB_PASSWORD
217
+ /project/prod/DB_PASSWORD
218
+ ```
219
+
220
+ 2. Create a template-based mapping file `env-map.json`:
221
+
222
+ ```json
223
+ {
224
+ "DB_PASSWORD": "/project/${ENV}/DB_PASSWORD"
225
+ }
226
+ ```
227
+
228
+ 3. Generate environment-specific .env files:
229
+
230
+ ```powershell
231
+ # Development
232
+ $env:ENV = "dev"
233
+ envilder --map=env-map.json --envfile=.env.dev
234
+
235
+ # Staging
236
+ $env:ENV = "stage"
237
+ envilder --map=env-map.json --envfile=.env.stage
238
+
239
+ # Production
240
+ $env:ENV = "prod"
241
+ envilder --map=env-map.json --envfile=.env.prod --profile=prod-account
242
+ ```
243
+
244
+ This approach ensures the right variables are pulled for each environment with minimal configuration.
245
+
246
+ ## 📂 Sample `.env` output
207
247
 
208
248
  ```ini
209
249
  SECRET_TOKEN=mockedEmail@example.com
210
250
  SECRET_KEY=mockedPassword
211
251
  ```
212
252
 
213
- ## 🧊 Running Tests
253
+ ## ðŸŽŊ Why use Envilder in practice?
254
+
255
+ Envilder eliminates common problems in development teams:
256
+
257
+ - **🛑 No more "it works on my machine"** - Everyone uses the exact same environment variables from the same source
258
+ - **🔄 Always fresh credentials** - Update a secret in SSM and everyone gets it automatically on next run
259
+ - **ðŸ›Ąïļ Access control built-in** - Developers only see dev secrets, CI/CD systems see what they need
260
+ - **🧠 Zero mental overhead** - No need to remember which variables are needed - the mapping defines everything
261
+ - **ðŸšŦ No more sharing secrets** - Stop pasting credentials in Slack, email, or Notion documents
262
+ - **📋 Compliance ready** - All accesses are logged in AWS CloudTrail for auditing
263
+
264
+ ## 🧊 Running tests
214
265
 
215
266
  ```bash
216
267
  yarn test
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Parses CLI arguments and runs the environment file generator.
4
+ *
5
+ * Expects `--map` and `--envfile` options to be provided, with an optional `--profile` for AWS CLI profile selection. Invokes the main process to generate a `.env` file from AWS SSM parameters based on the provided mapping.
6
+ *
7
+ * @throws {Error} If either `--map` or `--envfile` arguments are missing.
8
+ */
9
+ export declare function main(): Promise<void>;
10
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../../src/cli/cli.ts"],"names":[],"mappings":";AA4CA;;;;;;GAMG;AACH,wBAAsB,IAAI,kBAkBzB"}
package/lib/cli/cli.js ADDED
@@ -0,0 +1,76 @@
1
+ #!/usr/bin/env node
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ import { existsSync, readFileSync } from 'node:fs';
12
+ import { dirname, join } from 'node:path';
13
+ import { fileURLToPath } from 'node:url';
14
+ import { Command } from 'commander';
15
+ import { run } from '../index.js';
16
+ const __filename = fileURLToPath(import.meta.url);
17
+ const __dirname = dirname(__filename);
18
+ /**
19
+ * Find the package.json file by traversing up directories
20
+ * @param startDir The directory to start searching from
21
+ * @param maxDepth Maximum number of parent directories to check
22
+ * @returns Path to package.json if found, or null if not found
23
+ */
24
+ function findPackageJson(startDir, maxDepth = 5) {
25
+ let currentDir = startDir;
26
+ let depth = 0;
27
+ while (depth < maxDepth) {
28
+ const packagePath = join(currentDir, 'package.json');
29
+ if (existsSync(packagePath)) {
30
+ return packagePath;
31
+ }
32
+ // Go up one directory
33
+ const parentDir = dirname(currentDir);
34
+ if (parentDir === currentDir) {
35
+ // We've reached the root
36
+ break;
37
+ }
38
+ currentDir = parentDir;
39
+ depth++;
40
+ }
41
+ return null;
42
+ }
43
+ // Get package.json path by searching up from current file
44
+ const packageJsonPath = findPackageJson(__dirname) || join(__dirname, '..', '..', 'package.json');
45
+ const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf8'));
46
+ /**
47
+ * Parses CLI arguments and runs the environment file generator.
48
+ *
49
+ * Expects `--map` and `--envfile` options to be provided, with an optional `--profile` for AWS CLI profile selection. Invokes the main process to generate a `.env` file from AWS SSM parameters based on the provided mapping.
50
+ *
51
+ * @throws {Error} If either `--map` or `--envfile` arguments are missing.
52
+ */
53
+ export function main() {
54
+ return __awaiter(this, void 0, void 0, function* () {
55
+ const program = new Command();
56
+ program
57
+ .name('envilder')
58
+ .description('A CLI tool to generate .env files from AWS SSM parameters')
59
+ .version(packageJson.version)
60
+ .requiredOption('--map <path>', 'Path to the JSON file with environment variable mapping')
61
+ .requiredOption('--envfile <path>', 'Path to the .env file to be generated')
62
+ .option('--profile <name>', 'AWS CLI profile to use');
63
+ yield program.parseAsync(process.argv);
64
+ const options = program.opts();
65
+ if (!options.map || !options.envfile) {
66
+ throw new Error('Missing required arguments: --map and --envfile');
67
+ }
68
+ yield run(options.map, options.envfile, options.profile);
69
+ });
70
+ }
71
+ // Execute the CLI
72
+ main().catch((error) => {
73
+ console.error('ðŸšĻ Uh-oh! Looks like Mario fell into the wrong pipe! 🍄ðŸ’Ĩ');
74
+ console.error(error);
75
+ });
76
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/cli/cli.ts"],"names":[],"mappings":";;;;;;;;;;AACA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,GAAG,EAAE,MAAM,aAAa,CAAC;AAElC,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAClD,MAAM,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;AAEtC;;;;;GAKG;AACH,SAAS,eAAe,CAAC,QAAgB,EAAE,QAAQ,GAAG,CAAC;IACrD,IAAI,UAAU,GAAG,QAAQ,CAAC;IAC1B,IAAI,KAAK,GAAG,CAAC,CAAC;IAEd,OAAO,KAAK,GAAG,QAAQ,EAAE,CAAC;QACxB,MAAM,WAAW,GAAG,IAAI,CAAC,UAAU,EAAE,cAAc,CAAC,CAAC;QACrD,IAAI,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;YAC5B,OAAO,WAAW,CAAC;QACrB,CAAC;QAED,sBAAsB;QACtB,MAAM,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;QACtC,IAAI,SAAS,KAAK,UAAU,EAAE,CAAC;YAC7B,yBAAyB;YACzB,MAAM;QACR,CAAC;QAED,UAAU,GAAG,SAAS,CAAC;QACvB,KAAK,EAAE,CAAC;IACV,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED,0DAA0D;AAC1D,MAAM,eAAe,GAAG,eAAe,CAAC,SAAS,CAAC,IAAI,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,cAAc,CAAC,CAAC;AAClG,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,eAAe,EAAE,MAAM,CAAC,CAAC,CAAC;AAEtE;;;;;;GAMG;AACH,MAAM,UAAgB,IAAI;;QACxB,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;QAC9B,OAAO;aACJ,IAAI,CAAC,UAAU,CAAC;aAChB,WAAW,CAAC,2DAA2D,CAAC;aACxE,OAAO,CAAC,WAAW,CAAC,OAAO,CAAC;aAC5B,cAAc,CAAC,cAAc,EAAE,yDAAyD,CAAC;aACzF,cAAc,CAAC,kBAAkB,EAAE,uCAAuC,CAAC;aAC3E,MAAM,CAAC,kBAAkB,EAAE,wBAAwB,CAAC,CAAC;QAExD,MAAM,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QACvC,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC;QAE/B,IAAI,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;YACrC,MAAM,IAAI,KAAK,CAAC,iDAAiD,CAAC,CAAC;QACrE,CAAC;QAED,MAAM,GAAG,CAAC,OAAO,CAAC,GAAG,EAAE,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;IAC3D,CAAC;CAAA;AAED,kBAAkB;AAClB,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;IACrB,OAAO,CAAC,KAAK,CAAC,2DAA2D,CAAC,CAAC;IAC3E,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;AACvB,CAAC,CAAC,CAAC"}
package/lib/index.d.ts ADDED
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Orchestrates the process of fetching environment variable values from AWS SSM Parameter Store and writing them to a local environment file.
3
+ *
4
+ * Loads a parameter mapping from a JSON file, retrieves existing environment variables, fetches updated values from SSM (optionally using a specified AWS profile), merges them, and writes the result to the specified environment file.
5
+ *
6
+ * @param mapPath - Path to the JSON file mapping environment variable names to SSM parameter names.
7
+ * @param envFilePath - Path to the local environment file to read and update.
8
+ * @param profile - Optional AWS profile name to use for credentials.
9
+ */
10
+ export declare function run(mapPath: string, envFilePath: string, profile?: string): Promise<void>;
11
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAKA;;;;;;;;GAQG;AACH,wBAAsB,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,iBAY/E"}
package/lib/index.js ADDED
@@ -0,0 +1,116 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ import * as fs from 'node:fs';
11
+ import { GetParameterCommand, SSM } from '@aws-sdk/client-ssm';
12
+ import { fromIni } from '@aws-sdk/credential-providers';
13
+ import * as dotenv from 'dotenv';
14
+ /**
15
+ * Orchestrates the process of fetching environment variable values from AWS SSM Parameter Store and writing them to a local environment file.
16
+ *
17
+ * Loads a parameter mapping from a JSON file, retrieves existing environment variables, fetches updated values from SSM (optionally using a specified AWS profile), merges them, and writes the result to the specified environment file.
18
+ *
19
+ * @param mapPath - Path to the JSON file mapping environment variable names to SSM parameter names.
20
+ * @param envFilePath - Path to the local environment file to read and update.
21
+ * @param profile - Optional AWS profile name to use for credentials.
22
+ */
23
+ export function run(mapPath, envFilePath, profile) {
24
+ return __awaiter(this, void 0, void 0, function* () {
25
+ const defaultAwsConfig = {};
26
+ const ssmClientConfig = profile ? { credentials: fromIni({ profile }) } : defaultAwsConfig;
27
+ const ssm = new SSM(ssmClientConfig);
28
+ const paramMap = loadParamMap(mapPath);
29
+ const existingEnvVariables = loadExistingEnvVariables(envFilePath);
30
+ const updatedEnvVariables = yield fetchAndUpdateEnvVariables(paramMap, existingEnvVariables, ssm);
31
+ writeEnvFile(envFilePath, updatedEnvVariables);
32
+ console.log(`Environment File generated at '${envFilePath}'`);
33
+ });
34
+ }
35
+ function loadParamMap(mapPath) {
36
+ const content = fs.readFileSync(mapPath, 'utf-8');
37
+ try {
38
+ return JSON.parse(content);
39
+ }
40
+ catch (error) {
41
+ console.error(`Error parsing JSON from ${mapPath}`);
42
+ throw new Error(`Invalid JSON in parameter map file: ${mapPath}`);
43
+ }
44
+ }
45
+ function loadExistingEnvVariables(envFilePath) {
46
+ const envVariables = {};
47
+ if (!fs.existsSync(envFilePath))
48
+ return envVariables;
49
+ const existingEnvContent = fs.readFileSync(envFilePath, 'utf-8');
50
+ const parsedEnv = dotenv.parse(existingEnvContent);
51
+ Object.assign(envVariables, parsedEnv);
52
+ return envVariables;
53
+ }
54
+ /**
55
+ * Fetches parameter values from AWS SSM for each environment variable in the map and updates the existing environment variables record.
56
+ *
57
+ * For each mapping, retrieves the corresponding SSM parameter value and updates the environment variable if found. Logs masked values and warnings for missing parameters. Throws an error if any parameters fail to fetch.
58
+ *
59
+ * @param paramMap - Mapping of environment variable names to SSM parameter names.
60
+ * @param existingEnvVariables - Current environment variables to be updated.
61
+ * @param ssm - AWS SSM client instance used for fetching parameters.
62
+ * @returns The updated environment variables record.
63
+ *
64
+ * @throws {Error} If any SSM parameters cannot be fetched.
65
+ */
66
+ function fetchAndUpdateEnvVariables(paramMap, existingEnvVariables, ssm) {
67
+ return __awaiter(this, void 0, void 0, function* () {
68
+ const errors = [];
69
+ for (const [envVar, ssmName] of Object.entries(paramMap)) {
70
+ try {
71
+ const value = yield fetchSSMParameter(ssmName, ssm);
72
+ if (value) {
73
+ existingEnvVariables[envVar] = value;
74
+ console.log(`${envVar}=${value.length > 3 ? '*'.repeat(value.length - 3) + value.slice(-3) : '*'.repeat(value.length)}`);
75
+ }
76
+ else {
77
+ console.error(`Warning: No value found for: '${ssmName}'`);
78
+ }
79
+ }
80
+ catch (error) {
81
+ console.error(`Error fetching parameter: '${ssmName}'`);
82
+ errors.push(`ParameterNotFound: ${ssmName}`);
83
+ }
84
+ }
85
+ if (errors.length > 0) {
86
+ throw new Error(`Some parameters could not be fetched:\n${errors.join('\n')}`);
87
+ }
88
+ return existingEnvVariables;
89
+ });
90
+ }
91
+ /**
92
+ * Retrieves the value of a parameter from AWS SSM Parameter Store with decryption enabled.
93
+ *
94
+ * @param ssmName - The name of the SSM parameter to retrieve.
95
+ * @returns The decrypted parameter value if found, or undefined if the parameter does not exist.
96
+ */
97
+ function fetchSSMParameter(ssmName, ssm) {
98
+ return __awaiter(this, void 0, void 0, function* () {
99
+ const command = new GetParameterCommand({
100
+ Name: ssmName,
101
+ WithDecryption: true,
102
+ });
103
+ const { Parameter } = yield ssm.send(command);
104
+ return Parameter === null || Parameter === void 0 ? void 0 : Parameter.Value;
105
+ });
106
+ }
107
+ function writeEnvFile(envFilePath, envVariables) {
108
+ const envContent = Object.entries(envVariables)
109
+ .map(([key, value]) => {
110
+ const escapedValue = value.replace(/(\n|\r|\n\r)/g, '\\n').replace(/"/g, '\\"');
111
+ return `${key}=${escapedValue}`;
112
+ })
113
+ .join('\n');
114
+ fs.writeFileSync(envFilePath, envContent);
115
+ }
116
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "envilder",
3
- "version": "0.5.0",
4
- "description": "A CLI tool to generate .env files from AWS SSM parameters",
3
+ "version": "0.5.2",
4
+ "description": "A CLI that securely centralizes your environment variables from AWS SSM as a single source of truth",
5
5
  "exports": {
6
6
  ".": {
7
7
  "import": "./lib/index.js",
@@ -13,9 +13,10 @@
13
13
  "envilder": "lib/cli/cli.js"
14
14
  },
15
15
  "scripts": {
16
- "clean": "npx jest --clearCache && yarn cache clean --force && npx rimraf lib && npx rimraf node_modules && npx rimraf coverage && npx rimraf yarn.lock",
16
+ "clean": "npx jest --clearCache && yarn cache clean --force && npx rimraf lib && npx rimraf node_modules && npx rimraf coverage",
17
17
  "test-run": "yarn build && node lib/cli/cli.js --map=tests/sample/param-map.json --envfile=tests/sample/autogenerated.env",
18
- "build": "tsc -p tsconfig.build.json --sourceMap --declaration && node --no-warnings scripts/chmod-cli.js",
18
+ "build": "tsc -p tsconfig.build.json --sourceMap --declaration",
19
+ "local-deploy": "yarn build && node --no-warnings scripts/pack-and-install.js",
19
20
  "validate-cli": "node --no-warnings --loader ts-node/esm scripts/validate-cli.ts",
20
21
  "format": "npx biome format",
21
22
  "format:write": "npx biome format --write",
@@ -23,12 +24,28 @@
23
24
  "lint:fix": "npx biome lint --fix",
24
25
  "test": "vitest run --reporter verbose --coverage",
25
26
  "cli-run": "yarn build && node --trace-warnings lib",
26
- "npm-publish": "yarn lint && yarn build && yarn publish",
27
+ "npm-publish": "yarn lint && yarn build && yarn test && npm pack --dry-run && yarn publish",
27
28
  "npm-release-patch": "yarn version --new-version patch",
28
29
  "npm-release-minor": "yarn version --new-version minor",
29
30
  "npm-release-prerelease": "yarn version --new-version prerelease"
30
31
  },
31
- "keywords": [],
32
+ "keywords": [
33
+ "env",
34
+ "dotenv",
35
+ "aws",
36
+ "ssm",
37
+ "parameter-store",
38
+ "cli",
39
+ "environment",
40
+ "secrets",
41
+ "automation",
42
+ "config",
43
+ "aws-cli",
44
+ "devops",
45
+ "ci-cd",
46
+ "secure",
47
+ "envfile"
48
+ ],
32
49
  "repository": {
33
50
  "type": "git",
34
51
  "url": "git://github.com/macalbert/envilder.git"
@@ -41,6 +58,12 @@
41
58
  "publishConfig": {
42
59
  "access": "public"
43
60
  },
61
+ "files": [
62
+ "lib/**/*",
63
+ "README.md",
64
+ "LICENSE",
65
+ "ROADMAP.md"
66
+ ],
44
67
  "type": "module",
45
68
  "dependencies": {
46
69
  "@aws-sdk/client-ssm": "^3.806.0",
package/.gitattributes DELETED
@@ -1,67 +0,0 @@
1
- ###############################################################################
2
- # Set default behavior to automatically normalize line endings.
3
- ###############################################################################
4
- * text=auto
5
-
6
- # Explicitly declare text files you want to always be normalized and converted
7
- # to native line endings on checkout.
8
- *.sh text eol=lf
9
-
10
- ###############################################################################
11
- # Set default behavior for command prompt diff.
12
- #
13
- # This is need for earlier builds of msysgit that does not have it on by
14
- # default for csharp files.
15
- # Note: This is only used by command line
16
- ###############################################################################
17
- #*.cs diff=csharp
18
-
19
- ###############################################################################
20
- # Set the merge driver for project and solution files
21
- #
22
- # Merging from the command prompt will add diff markers to the files if there
23
- # are conflicts (Merging from VS is not affected by the settings below, in VS
24
- # the diff markers are never inserted). Diff markers may cause the following
25
- # file extensions to fail to load in VS. An alternative would be to treat
26
- # these files as binary and thus will always conflict and require user
27
- # intervention with every merge. To do so, just uncomment the entries below
28
- ###############################################################################
29
- #*.sln merge=binary
30
- #*.csproj merge=binary
31
- #*.vbproj merge=binary
32
- #*.vcxproj merge=binary
33
- #*.vcproj merge=binary
34
- #*.dbproj merge=binary
35
- #*.fsproj merge=binary
36
- #*.lsproj merge=binary
37
- #*.wixproj merge=binary
38
- #*.modelproj merge=binary
39
- #*.sqlproj merge=binary
40
- #*.wwaproj merge=binary
41
-
42
- ###############################################################################
43
- # behavior for image files
44
- #
45
- # image files are treated as binary by default.
46
- ###############################################################################
47
- #*.jpg binary
48
- #*.png binary
49
- #*.gif binary
50
-
51
- ###############################################################################
52
- # diff behavior for common document formats
53
- #
54
- # Convert binary document formats to text before diffing them. This feature
55
- # is only available from the command line. Turn it on by uncommenting the
56
- # entries below.
57
- ###############################################################################
58
- #*.doc diff=astextplain
59
- #*.DOC diff=astextplain
60
- #*.docx diff=astextplain
61
- #*.DOCX diff=astextplain
62
- #*.dot diff=astextplain
63
- #*.DOT diff=astextplain
64
- #*.pdf diff=astextplain
65
- #*.PDF diff=astextplain
66
- #*.rtf diff=astextplain
67
- #*.RTF diff=astextplain
package/.gitconfig DELETED
@@ -1,2 +0,0 @@
1
- [core]
2
- longpaths = true
@@ -1,40 +0,0 @@
1
- # To get started with Dependabot version updates, you'll need to specify which
2
- # package ecosystems to update and where the package manifests are located.
3
- # Please see the documentation for all configuration options:
4
- # https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
5
-
6
- version: 2
7
- updates:
8
- - package-ecosystem: npm
9
- directory: "/"
10
- pull-request-branch-name:
11
- separator: "/"
12
- schedule:
13
- interval: monthly
14
- day: monday
15
- time: "10:00"
16
- timezone: Europe/Madrid
17
- labels:
18
- - "npm"
19
- - "dependencies"
20
- reviewers:
21
- - macalbert
22
- assignees:
23
- - macalbert
24
-
25
- - package-ecosystem: github-actions
26
- directory: "/"
27
- pull-request-branch-name:
28
- separator: "/"
29
- schedule:
30
- interval: monthly
31
- day: monday
32
- time: "10:00"
33
- timezone: Europe/Madrid
34
- labels:
35
- - "github-actions"
36
- - "dependencies"
37
- reviewers:
38
- - macalbert
39
- assignees:
40
- - macalbert
@@ -1,20 +0,0 @@
1
- # Description
2
-
3
- _Describe the problem or feature in addition to a link to the issues._
4
-
5
- ## Approach
6
-
7
- _How does this change address the problem?_
8
-
9
- ## Open Questions and Pre-Merge TODOs
10
-
11
- - [ ] Use github checklists. When solved, check the box and explain the answer.
12
-
13
- ## Learning
14
-
15
- _Describe the research stage_
16
- _Links to blog posts, patterns, libraries or addons used to solve this problem_
17
-
18
- ## Blog Posts
19
-
20
- - [How to Pull Request](https://github.com/flexyford/pull-request) Github Repo with Learning focused Pull Request Template.