envilder 0.5.2 → 0.5.3
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 +4 -6
- package/lib/{cli/cli.d.ts → Cli.d.ts} +1 -1
- package/lib/Cli.d.ts.map +1 -0
- package/lib/{cli/cli.js → Cli.js} +7 -3
- package/lib/Cli.js.map +1 -0
- package/lib/cli/application/EnvilderHandler.d.ts +18 -0
- package/lib/cli/application/EnvilderHandler.d.ts.map +1 -0
- package/lib/cli/application/EnvilderHandler.js +64 -0
- package/lib/cli/application/EnvilderHandler.js.map +1 -0
- package/lib/cli/domain/EnvilderBuilder.d.ts +14 -0
- package/lib/cli/domain/EnvilderBuilder.d.ts.map +1 -0
- package/lib/cli/domain/EnvilderBuilder.js +41 -0
- package/lib/cli/domain/EnvilderBuilder.js.map +1 -0
- package/lib/cli/domain/ports/IEnvFileManager.d.ts +6 -0
- package/lib/cli/domain/ports/IEnvFileManager.d.ts.map +1 -0
- package/lib/cli/domain/ports/IEnvFileManager.js +2 -0
- package/lib/cli/domain/ports/IEnvFileManager.js.map +1 -0
- package/lib/cli/domain/ports/ISecretProvider.d.ts +4 -0
- package/lib/cli/domain/ports/ISecretProvider.d.ts.map +1 -0
- package/lib/cli/domain/ports/ISecretProvider.js +2 -0
- package/lib/cli/domain/ports/ISecretProvider.js.map +1 -0
- package/lib/cli/infrastructure/AwsSsmStoreSecrets.d.ts +8 -0
- package/lib/cli/infrastructure/AwsSsmStoreSecrets.d.ts.map +1 -0
- package/lib/cli/infrastructure/AwsSsmStoreSecrets.js +26 -0
- package/lib/cli/infrastructure/AwsSsmStoreSecrets.js.map +1 -0
- package/lib/cli/infrastructure/EnvFileManager.d.ts +7 -0
- package/lib/cli/infrastructure/EnvFileManager.d.ts.map +1 -0
- package/lib/cli/infrastructure/EnvFileManager.js +37 -0
- package/lib/cli/infrastructure/EnvFileManager.js.map +1 -0
- package/package.json +20 -26
- package/lib/cli/cli.d.ts.map +0 -1
- package/lib/cli/cli.js.map +0 -1
- package/lib/index.d.ts +0 -11
- package/lib/index.d.ts.map +0 -1
- package/lib/index.js +0 -116
- package/lib/index.js.map +0 -1
package/README.md
CHANGED
|
@@ -22,7 +22,8 @@
|
|
|
22
22
|
- **🔒 Strict access control** - AWS IAM policies control who accesses which secrets (dev vs prod)
|
|
23
23
|
- **📊 Full audit trail** - All parameter access is logged in CloudTrail for compliance requirements
|
|
24
24
|
- **🧩 Single source of truth** - No more copying .env files from Notion or emails - SSM is your only source
|
|
25
|
-
- **🔁 Idempotent operations** -
|
|
25
|
+
- **🔁 Idempotent operations** - Overwrites values in your `.env` file *only* for variables defined in your mapping
|
|
26
|
+
file, using the latest from SSM. Variables not in the mapping file are preserved. Safe for automation.
|
|
26
27
|
- **⚙️ Environment-aware** - Use templates like `/project/${ENV}/DB_PASSWORD` to dynamically fetch the right secrets
|
|
27
28
|
- **🧱 No extra infrastructure** - Uses AWS SSM's existing reliability instead of additional secret managers
|
|
28
29
|
|
|
@@ -110,7 +111,7 @@ graph LR
|
|
|
110
111
|
You'll need:
|
|
111
112
|
|
|
112
113
|
- ✅ **AWS CLI** - Installed and configured with proper permissions to access SSM Parameter Store
|
|
113
|
-
- ✅ **Node.js** - Version
|
|
114
|
+
- ✅ **Node.js** - Version 20.0.0 or higher (as specified in `package.json`)
|
|
114
115
|
|
|
115
116
|
### AWS CLI setup
|
|
116
117
|
|
|
@@ -134,9 +135,6 @@ You'll need:
|
|
|
134
135
|
```bash
|
|
135
136
|
# Using npm
|
|
136
137
|
npm install -g envilder
|
|
137
|
-
|
|
138
|
-
# Using yarn
|
|
139
|
-
yarn global add envilder
|
|
140
138
|
```
|
|
141
139
|
|
|
142
140
|
## 🚀 Usage
|
|
@@ -264,7 +262,7 @@ Envilder eliminates common problems in development teams:
|
|
|
264
262
|
## 🧪 Running tests
|
|
265
263
|
|
|
266
264
|
```bash
|
|
267
|
-
|
|
265
|
+
npm test
|
|
268
266
|
```
|
|
269
267
|
|
|
270
268
|
Check the current coverage report: [Coverage Report](https://macalbert.github.io/envilder/)
|
package/lib/Cli.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Cli.d.ts","sourceRoot":"","sources":["../src/Cli.ts"],"names":[],"mappings":";AA6CA;;;;;;GAMG;AACH,wBAAsB,IAAI,kBA0BzB"}
|
|
@@ -12,7 +12,7 @@ import { existsSync, readFileSync } from 'node:fs';
|
|
|
12
12
|
import { dirname, join } from 'node:path';
|
|
13
13
|
import { fileURLToPath } from 'node:url';
|
|
14
14
|
import { Command } from 'commander';
|
|
15
|
-
import {
|
|
15
|
+
import { EnvilderBuilder } from './cli/domain/EnvilderBuilder.js';
|
|
16
16
|
const __filename = fileURLToPath(import.meta.url);
|
|
17
17
|
const __dirname = dirname(__filename);
|
|
18
18
|
/**
|
|
@@ -65,7 +65,11 @@ export function main() {
|
|
|
65
65
|
if (!options.map || !options.envfile) {
|
|
66
66
|
throw new Error('Missing required arguments: --map and --envfile');
|
|
67
67
|
}
|
|
68
|
-
|
|
68
|
+
const envilder = EnvilderBuilder.build()
|
|
69
|
+
.withDefaultFileManager()
|
|
70
|
+
.withAwsProvider(options.profile)
|
|
71
|
+
.create();
|
|
72
|
+
yield envilder.run(options.map, options.envfile);
|
|
69
73
|
});
|
|
70
74
|
}
|
|
71
75
|
// Execute the CLI
|
|
@@ -73,4 +77,4 @@ main().catch((error) => {
|
|
|
73
77
|
console.error('🚨 Uh-oh! Looks like Mario fell into the wrong pipe! 🍄💥');
|
|
74
78
|
console.error(error);
|
|
75
79
|
});
|
|
76
|
-
//# sourceMappingURL=
|
|
80
|
+
//# sourceMappingURL=Cli.js.map
|
package/lib/Cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Cli.js","sourceRoot":"","sources":["../src/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,eAAe,EAAE,MAAM,iCAAiC,CAAC;AAElE,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,GACnB,eAAe,CAAC,SAAS,CAAC,IAAI,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,cAAc,CAAC,CAAC;AAC5E,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,CACb,cAAc,EACd,yDAAyD,CAC1D;aACA,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,QAAQ,GAAG,eAAe,CAAC,KAAK,EAAE;aACrC,sBAAsB,EAAE;aACxB,eAAe,CAAC,OAAO,CAAC,OAAO,CAAC;aAChC,MAAM,EAAE,CAAC;QAEZ,MAAM,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;IACnD,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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { IEnvFileManager } from '../domain/ports/IEnvFileManager';
|
|
2
|
+
import type { ISecretProvider } from '../domain/ports/ISecretProvider';
|
|
3
|
+
export declare class Envilder {
|
|
4
|
+
private keyVault;
|
|
5
|
+
private envFileManager;
|
|
6
|
+
constructor(keyVault: ISecretProvider, envFileManager: IEnvFileManager);
|
|
7
|
+
/**
|
|
8
|
+
* Orchestrates the process of fetching environment variable values from a key vault and writing them to a local environment file.
|
|
9
|
+
*
|
|
10
|
+
* Loads a parameter mapping from a JSON file, retrieves existing environment variables, fetches updated values from the key vault, merges them, and writes the result to the specified environment file.
|
|
11
|
+
*
|
|
12
|
+
* @param mapPath - Path to the JSON file mapping environment variable names to key vault parameter names.
|
|
13
|
+
* @param envFilePath - Path to the local environment file to read and update.
|
|
14
|
+
*/
|
|
15
|
+
run(mapPath: string, envFilePath: string): Promise<void>;
|
|
16
|
+
private fetchAndUpdateEnvVariables;
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=EnvilderHandler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EnvilderHandler.d.ts","sourceRoot":"","sources":["../../../src/cli/application/EnvilderHandler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AACvE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AAEvE,qBAAa,QAAQ;IACnB,OAAO,CAAC,QAAQ,CAAkB;IAClC,OAAO,CAAC,cAAc,CAAkB;gBAE5B,QAAQ,EAAE,eAAe,EAAE,cAAc,EAAE,eAAe;IAKtE;;;;;;;OAOG;IACG,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM;YAYhC,0BAA0B;CAoCzC"}
|
|
@@ -0,0 +1,64 @@
|
|
|
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
|
+
export class Envilder {
|
|
11
|
+
constructor(keyVault, envFileManager) {
|
|
12
|
+
this.keyVault = keyVault;
|
|
13
|
+
this.envFileManager = envFileManager;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Orchestrates the process of fetching environment variable values from a key vault and writing them to a local environment file.
|
|
17
|
+
*
|
|
18
|
+
* Loads a parameter mapping from a JSON file, retrieves existing environment variables, fetches updated values from the key vault, merges them, and writes the result to the specified environment file.
|
|
19
|
+
*
|
|
20
|
+
* @param mapPath - Path to the JSON file mapping environment variable names to key vault parameter names.
|
|
21
|
+
* @param envFilePath - Path to the local environment file to read and update.
|
|
22
|
+
*/
|
|
23
|
+
run(mapPath, envFilePath) {
|
|
24
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
25
|
+
const paramMap = this.envFileManager.loadParamMap(mapPath);
|
|
26
|
+
const existingEnvVariables = this.envFileManager.loadExistingEnvVariables(envFilePath);
|
|
27
|
+
const updatedEnvVariables = yield this.fetchAndUpdateEnvVariables(paramMap, existingEnvVariables);
|
|
28
|
+
this.envFileManager.writeEnvFile(envFilePath, updatedEnvVariables);
|
|
29
|
+
console.log(`Environment File generated at '${envFilePath}'`);
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
fetchAndUpdateEnvVariables(paramMap, existingEnvVariables) {
|
|
33
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
34
|
+
try {
|
|
35
|
+
const errors = [];
|
|
36
|
+
for (const [envVar, secretName] of Object.entries(paramMap)) {
|
|
37
|
+
try {
|
|
38
|
+
const value = yield this.keyVault.getSecret(secretName);
|
|
39
|
+
if (!value) {
|
|
40
|
+
console.error(`Warning: No value found for: '${secretName}'`);
|
|
41
|
+
continue;
|
|
42
|
+
}
|
|
43
|
+
existingEnvVariables[envVar] = value;
|
|
44
|
+
console.log(`${envVar}=${value.length > 10 ? '*'.repeat(value.length - 3) + value.slice(-3) : '*'.repeat(value.length)}`);
|
|
45
|
+
}
|
|
46
|
+
catch (error) {
|
|
47
|
+
console.error(`Error fetching parameter: '${secretName}'`);
|
|
48
|
+
errors.push(`ParameterNotFound: ${secretName}`);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
if (errors.length > 0) {
|
|
52
|
+
throw new Error(`Some parameters could not be fetched:\n${errors.join('\n')}`);
|
|
53
|
+
}
|
|
54
|
+
return existingEnvVariables;
|
|
55
|
+
}
|
|
56
|
+
catch (error) {
|
|
57
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
58
|
+
console.error(`Failed to generate environment file: ${errorMessage}`);
|
|
59
|
+
throw error;
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=EnvilderHandler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EnvilderHandler.js","sourceRoot":"","sources":["../../../src/cli/application/EnvilderHandler.ts"],"names":[],"mappings":";;;;;;;;;AAGA,MAAM,OAAO,QAAQ;IAInB,YAAY,QAAyB,EAAE,cAA+B;QACpE,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,cAAc,GAAG,cAAc,CAAC;IACvC,CAAC;IAED;;;;;;;OAOG;IACG,GAAG,CAAC,OAAe,EAAE,WAAmB;;YAC5C,MAAM,QAAQ,GAAG,IAAI,CAAC,cAAc,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;YAC3D,MAAM,oBAAoB,GACxB,IAAI,CAAC,cAAc,CAAC,wBAAwB,CAAC,WAAW,CAAC,CAAC;YAC5D,MAAM,mBAAmB,GAAG,MAAM,IAAI,CAAC,0BAA0B,CAC/D,QAAQ,EACR,oBAAoB,CACrB,CAAC;YACF,IAAI,CAAC,cAAc,CAAC,YAAY,CAAC,WAAW,EAAE,mBAAmB,CAAC,CAAC;YACnE,OAAO,CAAC,GAAG,CAAC,kCAAkC,WAAW,GAAG,CAAC,CAAC;QAChE,CAAC;KAAA;IAEa,0BAA0B,CACtC,QAAgC,EAChC,oBAA4C;;YAE5C,IAAI,CAAC;gBACH,MAAM,MAAM,GAAa,EAAE,CAAC;gBAC5B,KAAK,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;oBAC5D,IAAI,CAAC;wBACH,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;wBACxD,IAAI,CAAC,KAAK,EAAE,CAAC;4BACX,OAAO,CAAC,KAAK,CAAC,iCAAiC,UAAU,GAAG,CAAC,CAAC;4BAC9D,SAAS;wBACX,CAAC;wBACD,oBAAoB,CAAC,MAAM,CAAC,GAAG,KAAK,CAAC;wBACrC,OAAO,CAAC,GAAG,CACT,GAAG,MAAM,IAAI,KAAK,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAC7G,CAAC;oBACJ,CAAC;oBAAC,OAAO,KAAK,EAAE,CAAC;wBACf,OAAO,CAAC,KAAK,CAAC,8BAA8B,UAAU,GAAG,CAAC,CAAC;wBAC3D,MAAM,CAAC,IAAI,CAAC,sBAAsB,UAAU,EAAE,CAAC,CAAC;oBAClD,CAAC;gBACH,CAAC;gBACD,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBACtB,MAAM,IAAI,KAAK,CACb,0CAA0C,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAC9D,CAAC;gBACJ,CAAC;gBAED,OAAO,oBAAoB,CAAC;YAC9B,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,MAAM,YAAY,GAChB,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;gBACzD,OAAO,CAAC,KAAK,CAAC,wCAAwC,YAAY,EAAE,CAAC,CAAC;gBACtE,MAAM,KAAK,CAAC;YACd,CAAC;QACH,CAAC;KAAA;CACF"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Envilder } from '../application/EnvilderHandler.js';
|
|
2
|
+
import type { IEnvFileManager } from './ports/IEnvFileManager.js';
|
|
3
|
+
import type { ISecretProvider } from './ports/ISecretProvider.js';
|
|
4
|
+
export declare class EnvilderBuilder {
|
|
5
|
+
private provider?;
|
|
6
|
+
private fileManager?;
|
|
7
|
+
static build(): EnvilderBuilder;
|
|
8
|
+
withDefaultFileManager(): this;
|
|
9
|
+
withEnvFileManager(fileManager: IEnvFileManager): this;
|
|
10
|
+
withProvider(provider: ISecretProvider): this;
|
|
11
|
+
withAwsProvider(profile?: string): this;
|
|
12
|
+
create(): Envilder;
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=EnvilderBuilder.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EnvilderBuilder.d.ts","sourceRoot":"","sources":["../../../src/cli/domain/EnvilderBuilder.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,QAAQ,EAAE,MAAM,mCAAmC,CAAC;AAG7D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAClE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAElE,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAC,CAAkB;IACnC,OAAO,CAAC,WAAW,CAAC,CAAkB;IAEtC,MAAM,CAAC,KAAK,IAAI,eAAe;IAI/B,sBAAsB,IAAI,IAAI;IAK9B,kBAAkB,CAAC,WAAW,EAAE,eAAe,GAAG,IAAI;IAKtD,YAAY,CAAC,QAAQ,EAAE,eAAe,GAAG,IAAI;IAK7C,eAAe,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI;IAYvC,MAAM,IAAI,QAAQ;CAWnB"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { SSM } from '@aws-sdk/client-ssm';
|
|
2
|
+
import { fromIni } from '@aws-sdk/credential-providers';
|
|
3
|
+
import { Envilder } from '../application/EnvilderHandler.js';
|
|
4
|
+
import { AwsSsmSecretProvider } from '../infrastructure/AwsSsmStoreSecrets.js';
|
|
5
|
+
import { EnvFileManager } from '../infrastructure/EnvFileManager.js';
|
|
6
|
+
export class EnvilderBuilder {
|
|
7
|
+
static build() {
|
|
8
|
+
return new EnvilderBuilder();
|
|
9
|
+
}
|
|
10
|
+
withDefaultFileManager() {
|
|
11
|
+
this.fileManager = new EnvFileManager();
|
|
12
|
+
return this;
|
|
13
|
+
}
|
|
14
|
+
withEnvFileManager(fileManager) {
|
|
15
|
+
this.fileManager = fileManager;
|
|
16
|
+
return this;
|
|
17
|
+
}
|
|
18
|
+
withProvider(provider) {
|
|
19
|
+
this.provider = provider;
|
|
20
|
+
return this;
|
|
21
|
+
}
|
|
22
|
+
withAwsProvider(profile) {
|
|
23
|
+
const ssm = profile == null
|
|
24
|
+
? new SSM()
|
|
25
|
+
: new SSM({
|
|
26
|
+
credentials: fromIni({ profile: profile }),
|
|
27
|
+
});
|
|
28
|
+
this.provider = new AwsSsmSecretProvider(ssm);
|
|
29
|
+
return this;
|
|
30
|
+
}
|
|
31
|
+
create() {
|
|
32
|
+
if (!this.provider) {
|
|
33
|
+
throw new Error('Secret provider must be specified');
|
|
34
|
+
}
|
|
35
|
+
if (!this.fileManager) {
|
|
36
|
+
throw new Error('Env file manager must be specified');
|
|
37
|
+
}
|
|
38
|
+
return new Envilder(this.provider, this.fileManager);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=EnvilderBuilder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EnvilderBuilder.js","sourceRoot":"","sources":["../../../src/cli/domain/EnvilderBuilder.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,qBAAqB,CAAC;AAE1C,OAAO,EAAE,OAAO,EAAE,MAAM,+BAA+B,CAAC;AACxD,OAAO,EAAE,QAAQ,EAAE,MAAM,mCAAmC,CAAC;AAC7D,OAAO,EAAE,oBAAoB,EAAE,MAAM,yCAAyC,CAAC;AAC/E,OAAO,EAAE,cAAc,EAAE,MAAM,qCAAqC,CAAC;AAIrE,MAAM,OAAO,eAAe;IAI1B,MAAM,CAAC,KAAK;QACV,OAAO,IAAI,eAAe,EAAE,CAAC;IAC/B,CAAC;IAED,sBAAsB;QACpB,IAAI,CAAC,WAAW,GAAG,IAAI,cAAc,EAAE,CAAC;QACxC,OAAO,IAAI,CAAC;IACd,CAAC;IAED,kBAAkB,CAAC,WAA4B;QAC7C,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC;QAC/B,OAAO,IAAI,CAAC;IACd,CAAC;IAED,YAAY,CAAC,QAAyB;QACpC,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,eAAe,CAAC,OAAgB;QAC9B,MAAM,GAAG,GACP,OAAO,IAAI,IAAI;YACb,CAAC,CAAC,IAAI,GAAG,EAAE;YACX,CAAC,CAAC,IAAI,GAAG,CAAC;gBACN,WAAW,EAAE,OAAO,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC;aACxB,CAAC,CAAC;QAE5B,IAAI,CAAC,QAAQ,GAAG,IAAI,oBAAoB,CAAC,GAAG,CAAC,CAAC;QAC9C,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM;QACJ,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;YACnB,MAAM,IAAI,KAAK,CAAC,mCAAmC,CAAC,CAAC;QACvD,CAAC;QAED,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;YACtB,MAAM,IAAI,KAAK,CAAC,oCAAoC,CAAC,CAAC;QACxD,CAAC;QAED,OAAO,IAAI,QAAQ,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;IACvD,CAAC;CACF"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export interface IEnvFileManager {
|
|
2
|
+
loadParamMap(mapPath: string): Record<string, string>;
|
|
3
|
+
loadExistingEnvVariables(envFilePath: string): Record<string, string>;
|
|
4
|
+
writeEnvFile(envFilePath: string, envVariables: Record<string, string>): void;
|
|
5
|
+
}
|
|
6
|
+
//# sourceMappingURL=IEnvFileManager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"IEnvFileManager.d.ts","sourceRoot":"","sources":["../../../../src/cli/domain/ports/IEnvFileManager.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,eAAe;IAC9B,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtD,wBAAwB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtE,YAAY,CAAC,WAAW,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC;CAC/E"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"IEnvFileManager.js","sourceRoot":"","sources":["../../../../src/cli/domain/ports/IEnvFileManager.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ISecretProvider.d.ts","sourceRoot":"","sources":["../../../../src/cli/domain/ports/ISecretProvider.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,eAAe;IAC9B,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;CACtD"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ISecretProvider.js","sourceRoot":"","sources":["../../../../src/cli/domain/ports/ISecretProvider.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { type SSM } from '@aws-sdk/client-ssm';
|
|
2
|
+
import type { ISecretProvider } from '../domain/ports/ISecretProvider';
|
|
3
|
+
export declare class AwsSsmSecretProvider implements ISecretProvider {
|
|
4
|
+
private ssm;
|
|
5
|
+
constructor(ssm: SSM);
|
|
6
|
+
getSecret(name: string): Promise<string | undefined>;
|
|
7
|
+
}
|
|
8
|
+
//# sourceMappingURL=AwsSsmStoreSecrets.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AwsSsmStoreSecrets.d.ts","sourceRoot":"","sources":["../../../src/cli/infrastructure/AwsSsmStoreSecrets.ts"],"names":[],"mappings":"AAAA,OAAO,EAAuB,KAAK,GAAG,EAAE,MAAM,qBAAqB,CAAC;AACpE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AAEvE,qBAAa,oBAAqB,YAAW,eAAe;IAC1D,OAAO,CAAC,GAAG,CAAM;gBAEL,GAAG,EAAE,GAAG;IAId,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC;CAQ3D"}
|
|
@@ -0,0 +1,26 @@
|
|
|
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 { GetParameterCommand } from '@aws-sdk/client-ssm';
|
|
11
|
+
export class AwsSsmSecretProvider {
|
|
12
|
+
constructor(ssm) {
|
|
13
|
+
this.ssm = ssm;
|
|
14
|
+
}
|
|
15
|
+
getSecret(name) {
|
|
16
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
17
|
+
const command = new GetParameterCommand({
|
|
18
|
+
Name: name,
|
|
19
|
+
WithDecryption: true,
|
|
20
|
+
});
|
|
21
|
+
const { Parameter } = yield this.ssm.send(command);
|
|
22
|
+
return Parameter === null || Parameter === void 0 ? void 0 : Parameter.Value;
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=AwsSsmStoreSecrets.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AwsSsmStoreSecrets.js","sourceRoot":"","sources":["../../../src/cli/infrastructure/AwsSsmStoreSecrets.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAE,mBAAmB,EAAY,MAAM,qBAAqB,CAAC;AAGpE,MAAM,OAAO,oBAAoB;IAG/B,YAAY,GAAQ;QAClB,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC;IACjB,CAAC;IAEK,SAAS,CAAC,IAAY;;YAC1B,MAAM,OAAO,GAAG,IAAI,mBAAmB,CAAC;gBACtC,IAAI,EAAE,IAAI;gBACV,cAAc,EAAE,IAAI;aACrB,CAAC,CAAC;YACH,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YACnD,OAAO,SAAS,aAAT,SAAS,uBAAT,SAAS,CAAE,KAAK,CAAC;QAC1B,CAAC;KAAA;CACF"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { IEnvFileManager } from '../domain/ports/IEnvFileManager';
|
|
2
|
+
export declare class EnvFileManager implements IEnvFileManager {
|
|
3
|
+
loadParamMap(mapPath: string): Record<string, string>;
|
|
4
|
+
loadExistingEnvVariables(envFilePath: string): Record<string, string>;
|
|
5
|
+
writeEnvFile(envFilePath: string, envVariables: Record<string, string>): void;
|
|
6
|
+
}
|
|
7
|
+
//# sourceMappingURL=EnvFileManager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EnvFileManager.d.ts","sourceRoot":"","sources":["../../../src/cli/infrastructure/EnvFileManager.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AAEvE,qBAAa,cAAe,YAAW,eAAe;IACpD,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;IAUrD,wBAAwB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;IAWrE,YAAY,CACV,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GACnC,IAAI;CAYR"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import * as fs from 'node:fs';
|
|
2
|
+
import * as dotenv from 'dotenv';
|
|
3
|
+
export class EnvFileManager {
|
|
4
|
+
loadParamMap(mapPath) {
|
|
5
|
+
const content = fs.readFileSync(mapPath, 'utf-8');
|
|
6
|
+
try {
|
|
7
|
+
return JSON.parse(content);
|
|
8
|
+
}
|
|
9
|
+
catch (error) {
|
|
10
|
+
console.error(`Error parsing JSON from ${mapPath}`);
|
|
11
|
+
throw new Error(`Invalid JSON in parameter map file: ${mapPath}`);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
loadExistingEnvVariables(envFilePath) {
|
|
15
|
+
const envVariables = {};
|
|
16
|
+
if (!fs.existsSync(envFilePath)) {
|
|
17
|
+
return envVariables;
|
|
18
|
+
}
|
|
19
|
+
const existingEnvContent = fs.readFileSync(envFilePath, 'utf-8');
|
|
20
|
+
const parsedEnv = dotenv.parse(existingEnvContent);
|
|
21
|
+
Object.assign(envVariables, parsedEnv);
|
|
22
|
+
return envVariables;
|
|
23
|
+
}
|
|
24
|
+
writeEnvFile(envFilePath, envVariables) {
|
|
25
|
+
const envContent = Object.entries(envVariables)
|
|
26
|
+
.map(([key, value]) => {
|
|
27
|
+
const escapedValue = value
|
|
28
|
+
.replace(/\\/g, '\\\\')
|
|
29
|
+
.replace(/(\r\n|\n|\r)/g, '\\n')
|
|
30
|
+
.replace(/"/g, '\\"');
|
|
31
|
+
return `${key}=${escapedValue}`;
|
|
32
|
+
})
|
|
33
|
+
.join('\n');
|
|
34
|
+
fs.writeFileSync(envFilePath, envContent);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=EnvFileManager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EnvFileManager.js","sourceRoot":"","sources":["../../../src/cli/infrastructure/EnvFileManager.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,MAAM,MAAM,QAAQ,CAAC;AAGjC,MAAM,OAAO,cAAc;IACzB,YAAY,CAAC,OAAe;QAC1B,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QAClD,IAAI,CAAC;YACH,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAC7B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,2BAA2B,OAAO,EAAE,CAAC,CAAC;YACpD,MAAM,IAAI,KAAK,CAAC,uCAAuC,OAAO,EAAE,CAAC,CAAC;QACpE,CAAC;IACH,CAAC;IAED,wBAAwB,CAAC,WAAmB;QAC1C,MAAM,YAAY,GAA2B,EAAE,CAAC;QAChD,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;YAChC,OAAO,YAAY,CAAC;QACtB,CAAC;QACD,MAAM,kBAAkB,GAAG,EAAE,CAAC,YAAY,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;QACjE,MAAM,SAAS,GAAG,MAAM,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC;QACnD,MAAM,CAAC,MAAM,CAAC,YAAY,EAAE,SAAS,CAAC,CAAC;QACvC,OAAO,YAAY,CAAC;IACtB,CAAC;IAED,YAAY,CACV,WAAmB,EACnB,YAAoC;QAEpC,MAAM,UAAU,GAAG,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC;aAC5C,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE;YACpB,MAAM,YAAY,GAAG,KAAK;iBACvB,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC;iBACtB,OAAO,CAAC,eAAe,EAAE,KAAK,CAAC;iBAC/B,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;YACxB,OAAO,GAAG,GAAG,IAAI,YAAY,EAAE,CAAC;QAClC,CAAC,CAAC;aACD,IAAI,CAAC,IAAI,CAAC,CAAC;QACd,EAAE,CAAC,aAAa,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC;IAC5C,CAAC;CACF"}
|
package/package.json
CHANGED
|
@@ -1,33 +1,25 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "envilder",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.3",
|
|
4
4
|
"description": "A CLI that securely centralizes your environment variables from AWS SSM as a single source of truth",
|
|
5
|
-
"
|
|
6
|
-
".": {
|
|
7
|
-
"import": "./lib/index.js",
|
|
8
|
-
"types": "./lib/index.d.ts"
|
|
9
|
-
}
|
|
10
|
-
},
|
|
11
|
-
"main": "./lib/index.js",
|
|
5
|
+
"main": "./lib/Cli.js",
|
|
12
6
|
"bin": {
|
|
13
|
-
"envilder": "lib/
|
|
7
|
+
"envilder": "lib/Cli.js"
|
|
14
8
|
},
|
|
15
9
|
"scripts": {
|
|
16
|
-
"clean": "
|
|
17
|
-
"
|
|
18
|
-
"
|
|
19
|
-
"local-
|
|
20
|
-
"
|
|
21
|
-
"format": "
|
|
22
|
-
"
|
|
23
|
-
"lint": "
|
|
24
|
-
"lint:fix": "npx biome lint --fix",
|
|
10
|
+
"clean": "jest --clearCache && npm cache clean --force && rimraf lib && rimraf coverage && rimraf node_modules",
|
|
11
|
+
"build": "tsc",
|
|
12
|
+
"local:install": "npm run build && node --loader ts-node/esm scripts/pack-and-install.ts",
|
|
13
|
+
"local:test-run": "npm run build && node lib/cli/cli.js --map=tests/cli/sample/param-map.json --envfile=tests/cli/sample/autogenerated.env",
|
|
14
|
+
"format": "biome format",
|
|
15
|
+
"format:write": "biome format --write",
|
|
16
|
+
"lint": "secretlint \"**/*\" && biome check --write && tsc --noEmit",
|
|
17
|
+
"lint:fix": "biome lint --fix",
|
|
25
18
|
"test": "vitest run --reporter verbose --coverage",
|
|
26
|
-
"
|
|
27
|
-
"npm-
|
|
28
|
-
"npm-release-
|
|
29
|
-
"npm-release-
|
|
30
|
-
"npm-release-prerelease": "yarn version --new-version prerelease"
|
|
19
|
+
"npm-publish": "npm run lint && npm run build && npm run test && npm pack --dry-run && npm publish",
|
|
20
|
+
"npm-release-patch": "npm version patch",
|
|
21
|
+
"npm-release-minor": "npm version minor",
|
|
22
|
+
"npm-release-prerelease": "npm version prerelease"
|
|
31
23
|
},
|
|
32
24
|
"keywords": [
|
|
33
25
|
"env",
|
|
@@ -69,22 +61,24 @@
|
|
|
69
61
|
"@aws-sdk/client-ssm": "^3.806.0",
|
|
70
62
|
"@aws-sdk/credential-providers": "^3.806.0",
|
|
71
63
|
"@types/node": "^22.5.5",
|
|
72
|
-
"commander": "^
|
|
64
|
+
"commander": "^14.0.0",
|
|
73
65
|
"dotenv": "^16.4.5",
|
|
74
66
|
"picocolors": "^1.1.0"
|
|
75
67
|
},
|
|
76
68
|
"devDependencies": {
|
|
77
69
|
"@biomejs/biome": "^1.9.1",
|
|
78
70
|
"@secretlint/secretlint-rule-preset-recommend": "^9.3.2",
|
|
71
|
+
"@testcontainers/localstack": "^11.0.1",
|
|
79
72
|
"@vitest/coverage-v8": "^3.1.1",
|
|
73
|
+
"jest": "^29.7.0",
|
|
80
74
|
"rimraf": "^6.0.1",
|
|
81
75
|
"secretlint": "^9.3.2",
|
|
76
|
+
"testcontainers": "^11.0.1",
|
|
82
77
|
"ts-node": "^10.9.2",
|
|
83
78
|
"typescript": "^5.6.2",
|
|
84
79
|
"vitest": "^3.1.1"
|
|
85
80
|
},
|
|
86
81
|
"engines": {
|
|
87
|
-
"node": ">=20.0.0"
|
|
88
|
-
"yarn": ">=1.22"
|
|
82
|
+
"node": ">=20.0.0"
|
|
89
83
|
}
|
|
90
84
|
}
|
package/lib/cli/cli.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
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.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
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
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
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
|
package/lib/index.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
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
DELETED
|
@@ -1,116 +0,0 @@
|
|
|
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
|
package/lib/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|