envilder 0.6.1 → 0.6.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.
Files changed (67) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +91 -289
  3. package/lib/apps/cli/Cli.d.ts +1 -0
  4. package/lib/apps/cli/Cli.d.ts.map +1 -1
  5. package/lib/apps/cli/Cli.js +12 -22
  6. package/lib/apps/cli/Cli.js.map +1 -1
  7. package/lib/apps/cli/Startup.d.ts +19 -0
  8. package/lib/apps/cli/Startup.d.ts.map +1 -0
  9. package/lib/apps/cli/Startup.js +75 -0
  10. package/lib/apps/cli/Startup.js.map +1 -0
  11. package/lib/envilder/application/dispatch/DispatchActionCommandHandler.d.ts.map +1 -1
  12. package/lib/envilder/application/dispatch/DispatchActionCommandHandler.js +24 -2
  13. package/lib/envilder/application/dispatch/DispatchActionCommandHandler.js.map +1 -1
  14. package/lib/envilder/application/pullSsmToEnv/PullSsmToEnvCommandHandler.d.ts +3 -3
  15. package/lib/envilder/application/pullSsmToEnv/PullSsmToEnvCommandHandler.d.ts.map +1 -1
  16. package/lib/envilder/application/pullSsmToEnv/PullSsmToEnvCommandHandler.js +35 -12
  17. package/lib/envilder/application/pullSsmToEnv/PullSsmToEnvCommandHandler.js.map +1 -1
  18. package/lib/envilder/application/pushEnvToSsm/PushEnvToSsmCommandHandler.d.ts +3 -3
  19. package/lib/envilder/application/pushEnvToSsm/PushEnvToSsmCommandHandler.d.ts.map +1 -1
  20. package/lib/envilder/application/pushEnvToSsm/PushEnvToSsmCommandHandler.js +28 -6
  21. package/lib/envilder/application/pushEnvToSsm/PushEnvToSsmCommandHandler.js.map +1 -1
  22. package/lib/envilder/application/pushSingle/PushSingleCommandHandler.d.ts.map +1 -1
  23. package/lib/envilder/application/pushSingle/PushSingleCommandHandler.js +23 -2
  24. package/lib/envilder/application/pushSingle/PushSingleCommandHandler.js.map +1 -1
  25. package/lib/envilder/domain/ports/IVariableStore.d.ts +6 -0
  26. package/lib/envilder/domain/ports/IVariableStore.d.ts.map +1 -0
  27. package/lib/envilder/domain/ports/IVariableStore.js +2 -0
  28. package/lib/envilder/domain/ports/IVariableStore.js.map +1 -0
  29. package/lib/envilder/infrastructure/{Aws → aws}/AwsSsmSecretProvider.d.ts +1 -1
  30. package/lib/envilder/infrastructure/{Aws → aws}/AwsSsmSecretProvider.d.ts.map +1 -1
  31. package/lib/envilder/infrastructure/{Aws → aws}/AwsSsmSecretProvider.js +17 -2
  32. package/lib/envilder/infrastructure/aws/AwsSsmSecretProvider.js.map +1 -0
  33. package/lib/envilder/infrastructure/{Logger → logger}/ConsoleLogger.d.ts +1 -1
  34. package/lib/envilder/infrastructure/logger/ConsoleLogger.d.ts.map +1 -0
  35. package/lib/envilder/infrastructure/logger/ConsoleLogger.js +23 -0
  36. package/lib/envilder/infrastructure/logger/ConsoleLogger.js.map +1 -0
  37. package/lib/envilder/infrastructure/package/PackageVersionReader.d.ts +5 -0
  38. package/lib/envilder/infrastructure/package/PackageVersionReader.d.ts.map +1 -0
  39. package/lib/envilder/infrastructure/{VersionFinder/PackageJsonFinder.js → package/PackageVersionReader.js} +3 -3
  40. package/lib/envilder/infrastructure/package/PackageVersionReader.js.map +1 -0
  41. package/lib/envilder/infrastructure/variableStore/FileVariableStore.d.ts +11 -0
  42. package/lib/envilder/infrastructure/variableStore/FileVariableStore.d.ts.map +1 -0
  43. package/lib/envilder/infrastructure/{EnvManager/EnvFileManager.js → variableStore/FileVariableStore.js} +33 -13
  44. package/lib/envilder/infrastructure/variableStore/FileVariableStore.js.map +1 -0
  45. package/lib/envilder/types.d.ts +22 -0
  46. package/lib/envilder/types.d.ts.map +1 -0
  47. package/lib/envilder/types.js +18 -0
  48. package/lib/envilder/types.js.map +1 -0
  49. package/package.json +4 -2
  50. package/lib/envilder/application/dispatch/builders/DispatchActionCommandHandlerBuilder.d.ts +0 -15
  51. package/lib/envilder/application/dispatch/builders/DispatchActionCommandHandlerBuilder.d.ts.map +0 -1
  52. package/lib/envilder/application/dispatch/builders/DispatchActionCommandHandlerBuilder.js +0 -38
  53. package/lib/envilder/application/dispatch/builders/DispatchActionCommandHandlerBuilder.js.map +0 -1
  54. package/lib/envilder/domain/ports/IEnvFileManager.d.ts +0 -6
  55. package/lib/envilder/domain/ports/IEnvFileManager.d.ts.map +0 -1
  56. package/lib/envilder/domain/ports/IEnvFileManager.js +0 -2
  57. package/lib/envilder/domain/ports/IEnvFileManager.js.map +0 -1
  58. package/lib/envilder/infrastructure/Aws/AwsSsmSecretProvider.js.map +0 -1
  59. package/lib/envilder/infrastructure/EnvManager/EnvFileManager.d.ts +0 -11
  60. package/lib/envilder/infrastructure/EnvManager/EnvFileManager.d.ts.map +0 -1
  61. package/lib/envilder/infrastructure/EnvManager/EnvFileManager.js.map +0 -1
  62. package/lib/envilder/infrastructure/Logger/ConsoleLogger.d.ts.map +0 -1
  63. package/lib/envilder/infrastructure/Logger/ConsoleLogger.js +0 -12
  64. package/lib/envilder/infrastructure/Logger/ConsoleLogger.js.map +0 -1
  65. package/lib/envilder/infrastructure/VersionFinder/PackageJsonFinder.d.ts +0 -5
  66. package/lib/envilder/infrastructure/VersionFinder/PackageJsonFinder.d.ts.map +0 -1
  67. package/lib/envilder/infrastructure/VersionFinder/PackageJsonFinder.js.map +0 -1
package/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2024 Marçal Albert
3
+ Copyright (c) 2025 Marçal Albert Castellví <mac.albert@gmail.com>
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
package/README.md CHANGED
@@ -3,36 +3,59 @@
3
3
  <p align="center">
4
4
  <img src="https://github.com/user-attachments/assets/96bf1efa-7d21-440a-a414-3a20e7f9a1f1" alt="Envilder">
5
5
  </p>
6
- </p>
7
6
 
8
7
  <p align="center">
9
- <b>✨ A CLI that securely centralizes your environment variables from AWS SSM as a single source of truth ✨</b>
8
+ <b>Automate .env and secret management with Envilder</b><br>
9
+ <span>Streamline your environment setup with AWS Parameter Store</span>
10
10
  </p>
11
11
 
12
12
  <p align="center">
13
13
  <a href="https://www.npmjs.com/package/envilder">
14
14
  <img src="https://img.shields.io/npm/v/envilder.svg" alt="npm version">
15
15
  </a>
16
- <a href="./LICENSE">
17
- <img src="https://img.shields.io/badge/license-MIT-blue.svg" alt="MIT License">
16
+ <a href="https://img.shields.io/npm/dm/envilder.svg">
17
+ <img src="https://img.shields.io/npm/dm/envilder.svg" alt="npm downloads">
18
+ </a>
19
+ <a href="https://github.com/macalbert/envilder/actions/workflows/tests.yml">
20
+ <img src="https://github.com/macalbert/envilder/actions/workflows/tests.yml/badge.svg" alt="CI Tests">
18
21
  </a>
19
22
  <a href="https://macalbert.github.io/envilder/">
20
23
  <img src="https://img.shields.io/badge/coverage-report-green.svg" alt="Coverage Report">
21
24
  </a>
25
+ <a href="./LICENSE">
26
+ <img src="https://img.shields.io/badge/license-MIT-blue.svg" alt="MIT License">
27
+ </a>
22
28
  </p>
23
29
 
24
30
  ## Why centralize environment variables?
25
31
 
26
- Environment variables are crucial for configuring applications across different environments
27
- (development, production) or even projects. Without proper management, they become:
32
+ Envilder is a CLI tool for .env automation, AWS SSM secrets management, and secure environment variable sync.
33
+ Generating and maintaining consistent .env files is a real pain point for any development team. From outdated
34
+ secrets to insecure practices, the risks are tangible. Envilder eliminates these pitfalls by centralizing and
35
+ automating secret management across real-world environments (dev, test, production) in a simple, secure, and
36
+ efficient way. Use Envilder to automate .env files, sync secrets with AWS Parameter Store, and streamline
37
+ onboarding and CI/CD workflows.
38
+
39
+ ---
40
+
41
+ ## ❗ What Envilder solves
28
42
 
29
- - 🔐 **Security risks** when stored in code repositories
30
- - 🔄 **Out of sync** across team members and deployment environments
31
- - 🧩 **Scattered** across various documentation, chat messages, and emails
43
+ - Desync between environments (dev, prod)
44
+ - Secrets not properly propagated across team members
45
+ - CI/CD pipeline failures due to outdated or missing .env files
46
+ - Slow and manual onboarding processes
47
+ - Security risks from sharing secrets via Slack, email, or other channels
48
+ - Insecure .env practices and manual secret sharing
32
49
 
33
- **Envilder** solves these problems by using AWS SSM Parameter Store as a secure, centralized location for all your
34
- environment variables, ensuring everyone on your team works with the same configuration and no secrets are exposed
35
- in your codebase.
50
+ ## How Envilder makes life easier
51
+
52
+ - 🛡️ Centralizes secrets in AWS Parameter Store
53
+ - ⚙️ Generates .env files automatically for every environment
54
+ - 🔄 Applies changes idempotently and instantly
55
+ - 🔐 Improves security: no need to share secrets manually; everything is managed via AWS SSM
56
+ - 👥 Simplifies onboarding and internal rotations
57
+ - 🚀 Enables cloud-native, infrastructure-as-code secret management
58
+ - 🤖 Perfect for DevOps, CI/CD, and team sync
36
59
 
37
60
  ---
38
61
 
@@ -40,26 +63,18 @@ in your codebase.
40
63
 
41
64
  - [🗝️ Envilder ☁️](#️-envilder-️)
42
65
  - [Why centralize environment variables?](#why-centralize-environment-variables)
66
+ - [❗ What Envilder solves](#-what-envilder-solves)
67
+ - [✅ How Envilder makes life easier](#-how-envilder-makes-life-easier)
43
68
  - [📚 Table of Contents](#-table-of-contents)
44
69
  - [⚙️ Features](#️-features)
45
70
  - [🧱 Feature Status](#-feature-status)
46
71
  - [💾 Installation](#-installation)
47
72
  - [🚀 Quick Start](#-quick-start)
48
- - [🎥 Video Demonstration](#-video-demonstration)
73
+ - [🎥 Video Demonstration](#-video-demonstration)
74
+ - [🏁 Get Started (3 steps)](#-get-started-3-steps)
75
+ - [📚 Quick Links](#-quick-links)
49
76
  - [🛠️ How it works](#️-how-it-works)
50
- - [🎮 Usage](#-usage)
51
- - [🚀 Push Mode (`--push`)](#-push-mode---push)
52
- - [🍄 Method 1: Push from .env file](#-method-1-push-from-env-file)
53
- - [⭐ Method 2: Push a single variable](#-method-2-push-a-single-variable)
54
- - [🧰 Push Mode options summary](#-push-mode-options-summary)
55
- - [🧪 Push Mode Examples](#-push-mode-examples)
56
- - [⬇️ Pull Mode (`--map` and `--envfile`)](#️-pull-mode---map-and---envfile)
57
- - [⚙️ Pull Mode Options](#️-pull-mode-options)
58
- - [🧪 Pull Mode Examples](#-pull-mode-examples)
59
- - [📜 Sample Output](#-sample-output)
60
- - [👥 Working with multiple AWS profiles](#-working-with-multiple-aws-profiles)
61
- - [⬇️ Pull Mode Example](#️-pull-mode-example)
62
- - [🚀 Push Mode Example](#-push-mode-example)
77
+ - [Frequently Asked Questions (FAQ)](#frequently-asked-questions-faq)
63
78
  - [🏁 Roadmap](#-roadmap)
64
79
  - [🤝 Contributing](#-contributing)
65
80
  - [📜 License](#-license)
@@ -94,7 +109,7 @@ in your codebase.
94
109
 
95
110
  🛠 Requirements:
96
111
 
97
- - Node.js **v20+**
112
+ - Node.js **v20+** (cloud-native compatible)
98
113
  - AWS CLI installed and configured
99
114
  - IAM user/role with `ssm:GetParameter`, `ssm:PutParameter`
100
115
 
@@ -112,36 +127,47 @@ npm install -g envilder
112
127
 
113
128
  ## 🚀 Quick Start
114
129
 
115
- Get started with **Envilder** in 3 simple steps. Remember to add `.env` to your `.gitignore` file for security.
130
+ ### 🎥 Video Demonstration
116
131
 
117
- Initial Setup
132
+ Watch how easy it is to automate your .env management in less than 1 minute:
118
133
 
119
- ```bash
120
- # Step 1: Create a parameter mapping file
121
- echo '{
122
- "DB_PASSWORD": "/my-app/db/password"
123
- }' > param-map.json
134
+ ![Watch the video](https://github.com/user-attachments/assets/9f194143-117d-49f3-a6fb-f400040ea514)
124
135
 
125
- # Step 2: Push a secret to AWS SSM Parameter Store
126
- envilder --push --key=DB_PASSWORD --value=12345 --ssm-path=/my-app/db/password
127
- ```
136
+ ### 🏁 Get Started (3 steps)
128
137
 
129
- Ongoing Usage
138
+ After configuring the AWS CLI and ensuring you have the necessary permissions to create SSM parameters,
139
+ you can begin pushing your first environment variables.
130
140
 
131
- ```bash
132
- # Step 3: Generate your .env file from AWS SSM
133
- envilder --map=param-map.json --envfile=.env
134
- ```
141
+ 1. **Create a mapping file:**
135
142
 
136
- 🎯 That’s it — your secrets are now managed and versioned from AWS SSM.
143
+ ```json
144
+ {
145
+ "DB_PASSWORD": "/my-app/db/password"
146
+ }
147
+ ```
137
148
 
138
- ---
149
+ 2. **Push a secret to AWS SSM:**
139
150
 
140
- ## 🎥 Video Demonstration
151
+ ```bash
152
+ envilder --push --key=DB_PASSWORD --value=12345 --ssm-path=/my-app/db/password
153
+ ```
141
154
 
142
- Watch how Envilder works in less than 1 minute:
155
+ Once your secrets are stored in AWS, you can easily generate or synchronize your local .env files:
143
156
 
144
- ![Watch the video](https://github.com/user-attachments/assets/2de7cac3-0c13-4706-96f6-bf2ef12b661a)
157
+ 1. **Generate your .env file from AWS SSM:**
158
+
159
+ ```bash
160
+ envilder --map=param-map.json --envfile=.env
161
+ ```
162
+
163
+ Your secrets are now managed and versioned from AWS SSM. Add `.env` to your `.gitignore` for security.
164
+ Envilder is designed for automation, onboarding, and secure cloud-native workflows.
165
+
166
+ ### 📚 Quick Links
167
+
168
+ - [Requirements & Installation](docs/requirements-installation.md)
169
+ - [Push Command Guide](docs/push-command.md)
170
+ - [Pull Command Guide](docs/pull-command.md)
145
171
 
146
172
  ---
147
173
 
@@ -159,255 +185,33 @@ graph LR
159
185
  classDef core fill:#1f3b57,color:#fff,stroke:#ccc,stroke-width:2px;
160
186
  ```
161
187
 
162
- 1. Define mappings in JSON: `{"ENV_VAR": "ssm/path"}`
163
- 2. Run Envilder: `--push` to upload, or `--map` + `--envfile` to generate
164
- 3. It talks to SSM using your AWS credentials
165
- 4. Result: your secrets synced
188
+ 1. Create a new `.env` file like `'ENV_VAR=12345'`
189
+ 2. Define mappings in a JSON file : `{"ENV_VAR": "ssm/path"}`
190
+ 3. Run Envilder: `--push` to upload, or `--map` + `--envfile` to generate
191
+ 4. Envilder syncs secrets securely with AWS SSM Parameter Store using your AWS credentials
192
+ 5. Result: your secrets are always up-to-date, secure, and ready for any environment
166
193
 
167
194
  ---
168
195
 
169
- ## 🎮 Usage
170
-
171
- ### 🚀 Push Mode (`--push`)
172
-
173
- Push Mode uploads environment variables to AWS SSM Parameter Store. It has two distinct operation methods:
174
-
175
- #### 🍄 Method 1: Push from .env file
176
-
177
- **Requirements:**
178
-
179
- - `--push` flag to enable Push Mode
180
- - `--envfile` pointing to your local .env file
181
- - `--map` pointing to your parameter mapping JSON file
182
-
183
- **How File-Based Push Works:**
184
-
185
- 1. Envilder reads your local `.env` file to get variable names and values
186
- 2. Envilder reads your `map` file to find the corresponding SSM paths
187
- 3. For each variable found in both files, Envilder pushes the value to AWS SSM
188
- 4. No modifications are made to your local files
189
-
190
- ```mermaid
191
- graph LR
192
- A[.env File] --> |Variables & Values| B[Envilder]:::core
193
- C[Mapping File] --> |SSM Paths| B
194
- D[AWS Profile]:::aws --> B
195
- B --> E[AWS SSM Parameter Store]:::aws
196
-
197
- classDef aws fill:#ffcc66,color:#000000,stroke:#333,stroke-width:1.5px;
198
- classDef core fill:#1f3b57,color:#fff,stroke:#ccc,stroke-width:2px;
199
- ```
200
-
201
- **Example:**
202
- If your `.env` file contains:
203
-
204
- ```text
205
- API_KEY=abc123
206
- DB_PASSWORD=secret456
207
- ```
208
-
209
- And your `param-map.json` file contains:
210
-
211
- ```json
212
- {
213
- "API_KEY": "/myapp/api/key",
214
- "DB_PASSWORD": "/myapp/db/password"
215
- }
216
- ```
217
-
218
- Running this command:
219
-
220
- ```bash
221
- envilder --push --envfile=.env --map=param-map.json
222
- ```
223
-
224
- Will push:
225
-
226
- - Value `abc123` to SSM path `/myapp/api/key`
227
- - Value `secret456` to SSM path `/myapp/db/password`
228
-
229
- ### ⭐ Method 2: Push a single variable
230
-
231
- **What it does:**
232
- Uploads a single environment variable directly to AWS SSM Parameter Store without using any files.
233
-
234
- **Required parameters:**
235
-
236
- - `--push`: Activates Push Mode
237
- - `--key=VAR_NAME`: The name of the environment variable
238
- - `--value=secret123`: The value to store in AWS SSM
239
- - `--ssm-path=/your/path`: The full AWS SSM parameter path
240
-
241
- **Important notes:**
242
-
243
- - NO files are read or modified
244
- - This is a direct command-to-SSM operation
245
- - Useful for quick updates or CI/CD pipelines
246
-
247
- ```mermaid
248
- graph LR
249
- A[Command Line Arguments] --> B[Envilder]:::core
250
- C[AWS Profile]:::aws --> B
251
- B --> D[AWS SSM Parameter Store]:::aws
252
-
253
- classDef aws fill:#ffcc66,color:#000000,stroke:#333,stroke-width:1.5px;
254
- classDef core fill:#1f3b57,color:#fff,stroke:#ccc,stroke-width:2px;
255
- ```
256
-
257
- **Example:**
258
-
259
- ```bash
260
- envilder --push --key=API_KEY --value=abc123 --ssm-path=/myapp/api/key
261
- ```
262
-
263
- Will push:
264
-
265
- - Value `abc123` to SSM path `/myapp/api/key`
196
+ ## Frequently Asked Questions (FAQ)
266
197
 
267
- ### 🧰 Push Mode options summary
198
+ **Q: What is Envilder?**
199
+ A: Envilder is a CLI tool for automating .env and secret management using AWS SSM Parameter Store.
268
200
 
269
- **Common Options:**
201
+ **Q: How does Envilder improve security?**
202
+ A: Secrets are never stored in code or shared via chat/email. All secrets are managed and synced securely via AWS SSM.
270
203
 
271
- | Option | Description |
272
- |------------- | ---------------------------------- |
273
- | `--push` | Required: Enables push mode |
274
- | `--profile` | Optional: AWS CLI profile to use |
204
+ **Q: Can I use Envilder in CI/CD pipelines?**
205
+ A: Yes! Envilder is designed for automation and works seamlessly in CI/CD workflows.
275
206
 
276
- **Method 1: File-Based Push Options:**
207
+ **Q: Does Envilder support multiple AWS profiles?**
208
+ A: Yes, you can use the `--profile` flag to select different AWS credentials.
277
209
 
278
- | Option | Description |
279
- |------------- | -------------------------------------------------- |
280
- | `--envfile` | Required: Path to your local .env file |
281
- | `--map` | Required: Path to your parameter mapping JSON file |
210
+ **Q: What environments does Envilder support?**
211
+ A: Any environment supported by AWS SSM—dev, test, staging, production, etc.
282
212
 
283
- **Method 2: Single-Variable Push Options:**
284
-
285
- | Option | Description |
286
- |------------- | ------------------------------------------- |
287
- | `--key` | Required: Environment variable name |
288
- | `--value` | Required: Value to store in AWS SSM |
289
- | `--ssm-path` | Required: Full SSM parameter path |
290
-
291
- ### 🧪 Push Mode Examples
292
-
293
- **Method 1: Push from .env file (multiple variables at once):**
294
-
295
- ```bash
296
- # Basic usage - pushes all variables found in both .env and map files
297
- envilder --push --envfile=.env --map=param-map.json
298
-
299
- # With AWS profile - for different environments
300
- envilder --push --envfile=.env.prod --map=param-map.json --profile=prod-account
301
- ```
302
-
303
- **Method 2: Push a single variable (no files needed):**
304
-
305
- ```bash
306
- # Basic usage - pushes one variable directly to SSM
307
- envilder --push --key=API_KEY --value=secret123 --ssm-path=/my/path
308
-
309
- # With AWS profile
310
- envilder --push --key=API_KEY --value=secret123 --ssm-path=/my/path --profile=dev
311
- ```
312
-
313
- ---
314
-
315
- ### ⬇️ Pull Mode (`--map` and `--envfile`)
316
-
317
- Downloads secrets from SSM and writes to `.env`.
318
-
319
- #### ⚙️ Pull Mode Options
320
-
321
- | Option | Description |
322
- | ----------- | ----------------------------------- |
323
- | `--map` | JSON mapping of env var to SSM path |
324
- | `--envfile` | Path to write `.env` |
325
- | `--profile` | AWS profile to use |
326
-
327
- #### 🧪 Pull Mode Examples
328
-
329
- ```bash
330
- envilder --map=param-map.json --envfile=.env
331
- ```
332
-
333
- With profile:
334
-
335
- ```bash
336
- envilder --map=param-map.json --envfile=.env --profile=dev-account
337
- ```
338
-
339
- #### 📜 Sample Output
340
-
341
- After running the pull command above with a `param-map.json` file containing:
342
-
343
- ```json
344
- {
345
- "API_KEY": "/myapp/api/key",
346
- "DB_PASSWORD": "/myapp/db/password",
347
- "SECRET_TOKEN": "/myapp/auth/token"
348
- }
349
- ```
350
-
351
- Your generated `.env` file would look like:
352
-
353
- ```dotenv
354
- # Generated by Envilder on 2025-07-13
355
- API_KEY=abc123
356
- DB_PASSWORD=secret456
357
- SECRET_TOKEN=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
358
- ```
359
-
360
- This keeps your sensitive values secure in AWS SSM while providing local access for development.
361
-
362
- ---
363
-
364
- ## 👥 Working with multiple AWS profiles
365
-
366
- Edit your `~/.aws/credentials`:
367
-
368
- ```ini
369
- [default]
370
- aws_access_key_id=DEFAULT_KEY
371
- aws_secret_access_key=DEFAULT_SECRET
372
-
373
- [dev-account]
374
- aws_access_key_id=DEV_KEY
375
- aws_secret_access_key=DEV_SECRET
376
-
377
- [prod-account]
378
- aws_access_key_id=PROD_KEY
379
- aws_secret_access_key=PROD_SECRET
380
- ```
381
-
382
- ---
383
-
384
- ### ⬇️ Pull Mode Example
385
-
386
- ```bash
387
- # Default
388
- envilder --map=param-map.json --envfile=.env.dev
389
-
390
- # Development
391
- envilder --map=param-map.json --envfile=.env.dev --profile=dev-account
392
-
393
- # Production
394
- envilder --map=param-map.json --envfile=.env.prod --profile=prod-account
395
- ```
396
-
397
- ---
398
-
399
- ### 🚀 Push Mode Example
400
-
401
- ```bash
402
- # Default
403
- envilder --push --key=API_KEY --value=secret123 --ssm-path=/dev/api/key
404
-
405
- # Development
406
- envilder --push --key=API_KEY --value=secret123 --ssm-path=/dev/api/key --profile=dev-account
407
-
408
- # Production
409
- envilder --push --key=API_KEY --value=secret123 --ssm-path=/prod/api/key --profile=prod-account
410
- ```
213
+ **Q: Is Envilder open source?**
214
+ A: Yes, licensed under MIT.
411
215
 
412
216
  ---
413
217
 
@@ -438,5 +242,3 @@ All help is welcome — PRs, issues, ideas!
438
242
 
439
243
  MIT © [Marçal Albert](https://github.com/macalbert)
440
244
  See [LICENSE](./LICENSE)
441
-
442
- ---
@@ -1,3 +1,4 @@
1
1
  #!/usr/bin/env node
2
+ import 'reflect-metadata';
2
3
  export declare function main(): Promise<void>;
3
4
  //# sourceMappingURL=Cli.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Cli.d.ts","sourceRoot":"","sources":["../../../src/apps/cli/Cli.ts"],"names":[],"mappings":";AAqCA,wBAAsB,IAAI,kBA2CzB"}
1
+ {"version":3,"file":"Cli.d.ts","sourceRoot":"","sources":["../../../src/apps/cli/Cli.ts"],"names":[],"mappings":";AACA,OAAO,kBAAkB,CAAC;AAwB1B,wBAAsB,IAAI,kBAgDzB"}
@@ -8,32 +8,18 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
8
8
  step((generator = generator.apply(thisArg, _arguments || [])).next());
9
9
  });
10
10
  };
11
+ import 'reflect-metadata';
11
12
  import { dirname, join } from 'node:path';
12
13
  import { fileURLToPath } from 'node:url';
13
- import { SSM } from '@aws-sdk/client-ssm';
14
- import { fromIni } from '@aws-sdk/credential-providers';
15
14
  import { Command } from 'commander';
16
- import { DispatchActionCommandHandlerBuilder } from '../../envilder/application/dispatch/builders/DispatchActionCommandHandlerBuilder.js';
17
15
  import { DispatchActionCommand } from '../../envilder/application/dispatch/DispatchActionCommand.js';
18
- import { AwsSsmSecretProvider } from '../../envilder/infrastructure/Aws/AwsSsmSecretProvider.js';
19
- import { EnvFileManager } from '../../envilder/infrastructure/EnvManager/EnvFileManager.js';
20
- import { ConsoleLogger } from '../../envilder/infrastructure/Logger/ConsoleLogger.js';
21
- import { PackageJsonFinder } from '../../envilder/infrastructure/VersionFinder/PackageJsonFinder.js';
16
+ import { PackageVersionReader } from '../../envilder/infrastructure/package/PackageVersionReader.js';
17
+ import { TYPES } from '../../envilder/types.js';
18
+ import { Startup } from './Startup.js';
19
+ let serviceProvider;
22
20
  function executeCommand(options) {
23
21
  return __awaiter(this, void 0, void 0, function* () {
24
- const logger = new ConsoleLogger();
25
- const fileManager = new EnvFileManager(logger);
26
- const ssm = options.profile
27
- ? new SSM({
28
- credentials: fromIni({ profile: options.profile }),
29
- })
30
- : new SSM();
31
- const secretProvider = new AwsSsmSecretProvider(ssm);
32
- const commandHandler = DispatchActionCommandHandlerBuilder.build()
33
- .withLogger(logger)
34
- .withEnvFileManager(fileManager)
35
- .withProvider(secretProvider)
36
- .create();
22
+ const commandHandler = serviceProvider.get(TYPES.DispatchActionCommandHandler);
37
23
  const command = DispatchActionCommand.fromCliOptions(options);
38
24
  yield commandHandler.handleCommand(command);
39
25
  });
@@ -60,6 +46,10 @@ export function main() {
60
46
  .option('--value <value>', 'Value of the single environment variable to push (only with --push)')
61
47
  .option('--ssm-path <path>', 'SSM path for the single environment variable (only with --push)')
62
48
  .action((options) => __awaiter(this, void 0, void 0, function* () {
49
+ serviceProvider = Startup.build()
50
+ .configureServices()
51
+ .configureInfrastructure(options.profile)
52
+ .create();
63
53
  yield executeCommand(options);
64
54
  }));
65
55
  yield program.parseAsync(process.argv);
@@ -69,10 +59,10 @@ function readPackageVersion() {
69
59
  const __filename = fileURLToPath(import.meta.url);
70
60
  const __dirname = dirname(__filename);
71
61
  const packageJsonPath = join(__dirname, '../../../package.json');
72
- return new PackageJsonFinder().readPackageJsonVersion(packageJsonPath);
62
+ return new PackageVersionReader().getVersion(packageJsonPath);
73
63
  }
74
64
  main().catch((error) => {
75
- const logger = new ConsoleLogger();
65
+ const logger = serviceProvider.get(TYPES.ILogger);
76
66
  logger.error('🚨 Uh-oh! Looks like Mario fell into the wrong pipe! 🍄💥');
77
67
  logger.error(error instanceof Error ? error.message : String(error));
78
68
  });
@@ -1 +1 @@
1
- {"version":3,"file":"Cli.js","sourceRoot":"","sources":["../../../src/apps/cli/Cli.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Cli.js","sourceRoot":"","sources":["../../../src/apps/cli/Cli.ts"],"names":[],"mappings":";;;;;;;;;;AACA,OAAO,kBAAkB,CAAC;AAC1B,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;AAEpC,OAAO,EAAE,qBAAqB,EAAE,MAAM,8DAA8D,CAAC;AAIrG,OAAO,EAAE,oBAAoB,EAAE,MAAM,+DAA+D,CAAC;AACrG,OAAO,EAAE,KAAK,EAAE,MAAM,yBAAyB,CAAC;AAChD,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAEvC,IAAI,eAA0B,CAAC;AAE/B,SAAe,cAAc,CAAC,OAAmB;;QAC/C,MAAM,cAAc,GAAG,eAAe,CAAC,GAAG,CACxC,KAAK,CAAC,4BAA4B,CACnC,CAAC;QAEF,MAAM,OAAO,GAAG,qBAAqB,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC;QAC9D,MAAM,cAAc,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;IAC9C,CAAC;CAAA;AAED,MAAM,UAAgB,IAAI;;QACxB,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;QAC9B,MAAM,OAAO,GAAG,MAAM,kBAAkB,EAAE,CAAC;QAE3C,OAAO;aACJ,IAAI,CAAC,UAAU,CAAC;aAChB,WAAW,CACV,+FAA+F;YAC7F,2BAA2B;YAC3B,6DAA6D;YAC7D,iDAAiD;YACjD,oEAAoE;YACpE,wCAAwC;YACxC,kFAAkF,CACrF;aACA,OAAO,CAAC,OAAO,CAAC;aAChB,MAAM,CACL,cAAc,EACd,sFAAsF,CACvF;aACA,MAAM,CACL,kBAAkB,EAClB,gFAAgF,CACjF;aACA,MAAM,CAAC,kBAAkB,EAAE,mCAAmC,CAAC;aAC/D,MAAM,CAAC,QAAQ,EAAE,sCAAsC,CAAC;aACxD,MAAM,CACL,cAAc,EACd,6DAA6D,CAC9D;aACA,MAAM,CACL,iBAAiB,EACjB,qEAAqE,CACtE;aACA,MAAM,CACL,mBAAmB,EACnB,iEAAiE,CAClE;aACA,MAAM,CAAC,CAAO,OAAmB,EAAE,EAAE;YACpC,eAAe,GAAG,OAAO,CAAC,KAAK,EAAE;iBAC9B,iBAAiB,EAAE;iBACnB,uBAAuB,CAAC,OAAO,CAAC,OAAO,CAAC;iBACxC,MAAM,EAAE,CAAC;YAEZ,MAAM,cAAc,CAAC,OAAO,CAAC,CAAC;QAChC,CAAC,CAAA,CAAC,CAAC;QAEL,MAAM,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IACzC,CAAC;CAAA;AAED,SAAS,kBAAkB;IACzB,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAClD,MAAM,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;IACtC,MAAM,eAAe,GAAG,IAAI,CAAC,SAAS,EAAE,uBAAuB,CAAC,CAAC;IAEjE,OAAO,IAAI,oBAAoB,EAAE,CAAC,UAAU,CAAC,eAAe,CAAC,CAAC;AAChE,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;IACrB,MAAM,MAAM,GAAG,eAAe,CAAC,GAAG,CAAU,KAAK,CAAC,OAAO,CAAC,CAAC;IAE3D,MAAM,CAAC,KAAK,CAAC,2DAA2D,CAAC,CAAC;IAC1E,MAAM,CAAC,KAAK,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;AACvE,CAAC,CAAC,CAAC"}
@@ -0,0 +1,19 @@
1
+ import { Container } from 'inversify';
2
+ export declare class Startup {
3
+ private readonly container;
4
+ constructor();
5
+ static build(): Startup;
6
+ configureServices(): this;
7
+ /**
8
+ * Configures infrastructure services for the application.
9
+ * Optionally accepts an AWS profile to use for service configuration.
10
+ * @param awsProfile - The AWS profile to use for configuring infrastructure services.
11
+ * @returns The current instance for method chaining.
12
+ */
13
+ configureInfrastructure(awsProfile?: string): this;
14
+ create(): Container;
15
+ getServiceProvider(): Container;
16
+ private configureInfrastructureServices;
17
+ private configureApplicationServices;
18
+ }
19
+ //# sourceMappingURL=Startup.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Startup.d.ts","sourceRoot":"","sources":["../../../src/apps/cli/Startup.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAgBtC,qBAAa,OAAO;IAClB,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAY;;IAMtC,MAAM,CAAC,KAAK,IAAI,OAAO;IAIvB,iBAAiB,IAAI,IAAI;IAKzB;;;;;OAKG;IACH,uBAAuB,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI;IAKlD,MAAM,IAAI,SAAS;IAInB,kBAAkB,IAAI,SAAS;IAI/B,OAAO,CAAC,+BAA+B;IAsBvC,OAAO,CAAC,4BAA4B;CAqBrC"}
@@ -0,0 +1,75 @@
1
+ import { SSM } from '@aws-sdk/client-ssm';
2
+ import { fromIni } from '@aws-sdk/credential-providers';
3
+ import { Container } from 'inversify';
4
+ import { DispatchActionCommandHandler } from '../../envilder/application/dispatch/DispatchActionCommandHandler.js';
5
+ import { PullSsmToEnvCommandHandler } from '../../envilder/application/pullSsmToEnv/PullSsmToEnvCommandHandler.js';
6
+ import { PushEnvToSsmCommandHandler } from '../../envilder/application/pushEnvToSsm/PushEnvToSsmCommandHandler.js';
7
+ import { PushSingleCommandHandler } from '../../envilder/application/pushSingle/PushSingleCommandHandler.js';
8
+ import { AwsSsmSecretProvider } from '../../envilder/infrastructure/aws/AwsSsmSecretProvider.js';
9
+ import { ConsoleLogger } from '../../envilder/infrastructure/logger/ConsoleLogger.js';
10
+ import { FileVariableStore } from '../../envilder/infrastructure/variableStore/FileVariableStore.js';
11
+ import { TYPES } from '../../envilder/types.js';
12
+ export class Startup {
13
+ constructor() {
14
+ this.container = new Container();
15
+ }
16
+ static build() {
17
+ return new Startup();
18
+ }
19
+ configureServices() {
20
+ this.configureApplicationServices();
21
+ return this;
22
+ }
23
+ /**
24
+ * Configures infrastructure services for the application.
25
+ * Optionally accepts an AWS profile to use for service configuration.
26
+ * @param awsProfile - The AWS profile to use for configuring infrastructure services.
27
+ * @returns The current instance for method chaining.
28
+ */
29
+ configureInfrastructure(awsProfile) {
30
+ this.configureInfrastructureServices(awsProfile);
31
+ return this;
32
+ }
33
+ create() {
34
+ return this.container;
35
+ }
36
+ getServiceProvider() {
37
+ return this.container;
38
+ }
39
+ configureInfrastructureServices(awsProfile) {
40
+ this.container
41
+ .bind(TYPES.ILogger)
42
+ .to(ConsoleLogger)
43
+ .inSingletonScope();
44
+ this.container
45
+ .bind(TYPES.IVariableStore)
46
+ .to(FileVariableStore)
47
+ .inSingletonScope();
48
+ const ssm = awsProfile
49
+ ? new SSM({ credentials: fromIni({ profile: awsProfile }) })
50
+ : new SSM();
51
+ const secretProvider = new AwsSsmSecretProvider(ssm);
52
+ this.container
53
+ .bind(TYPES.ISecretProvider)
54
+ .toConstantValue(secretProvider);
55
+ }
56
+ configureApplicationServices() {
57
+ this.container
58
+ .bind(TYPES.PullSsmToEnvCommandHandler)
59
+ .to(PullSsmToEnvCommandHandler)
60
+ .inTransientScope();
61
+ this.container
62
+ .bind(TYPES.PushEnvToSsmCommandHandler)
63
+ .to(PushEnvToSsmCommandHandler)
64
+ .inTransientScope();
65
+ this.container
66
+ .bind(TYPES.PushSingleCommandHandler)
67
+ .to(PushSingleCommandHandler)
68
+ .inTransientScope();
69
+ this.container
70
+ .bind(TYPES.DispatchActionCommandHandler)
71
+ .to(DispatchActionCommandHandler)
72
+ .inTransientScope();
73
+ }
74
+ }
75
+ //# sourceMappingURL=Startup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Startup.js","sourceRoot":"","sources":["../../../src/apps/cli/Startup.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,qBAAqB,CAAC;AAC1C,OAAO,EAAE,OAAO,EAAE,MAAM,+BAA+B,CAAC;AACxD,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAEtC,OAAO,EAAE,4BAA4B,EAAE,MAAM,qEAAqE,CAAC;AACnH,OAAO,EAAE,0BAA0B,EAAE,MAAM,uEAAuE,CAAC;AACnH,OAAO,EAAE,0BAA0B,EAAE,MAAM,uEAAuE,CAAC;AACnH,OAAO,EAAE,wBAAwB,EAAE,MAAM,mEAAmE,CAAC;AAM7G,OAAO,EAAE,oBAAoB,EAAE,MAAM,2DAA2D,CAAC;AACjG,OAAO,EAAE,aAAa,EAAE,MAAM,uDAAuD,CAAC;AACtF,OAAO,EAAE,iBAAiB,EAAE,MAAM,kEAAkE,CAAC;AACrG,OAAO,EAAE,KAAK,EAAE,MAAM,yBAAyB,CAAC;AAEhD,MAAM,OAAO,OAAO;IAGlB;QACE,IAAI,CAAC,SAAS,GAAG,IAAI,SAAS,EAAE,CAAC;IACnC,CAAC;IAED,MAAM,CAAC,KAAK;QACV,OAAO,IAAI,OAAO,EAAE,CAAC;IACvB,CAAC;IAED,iBAAiB;QACf,IAAI,CAAC,4BAA4B,EAAE,CAAC;QACpC,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;;OAKG;IACH,uBAAuB,CAAC,UAAmB;QACzC,IAAI,CAAC,+BAA+B,CAAC,UAAU,CAAC,CAAC;QACjD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM;QACJ,OAAO,IAAI,CAAC,SAAS,CAAC;IACxB,CAAC;IAED,kBAAkB;QAChB,OAAO,IAAI,CAAC,SAAS,CAAC;IACxB,CAAC;IAEO,+BAA+B,CAAC,UAAmB;QACzD,IAAI,CAAC,SAAS;aACX,IAAI,CAAU,KAAK,CAAC,OAAO,CAAC;aAC5B,EAAE,CAAC,aAAa,CAAC;aACjB,gBAAgB,EAAE,CAAC;QAEtB,IAAI,CAAC,SAAS;aACX,IAAI,CAAiB,KAAK,CAAC,cAAc,CAAC;aAC1C,EAAE,CAAC,iBAAiB,CAAC;aACrB,gBAAgB,EAAE,CAAC;QAEtB,MAAM,GAAG,GAAG,UAAU;YACpB,CAAC,CAAC,IAAI,GAAG,CAAC,EAAE,WAAW,EAAE,OAAO,CAAC,EAAE,OAAO,EAAE,UAAU,EAAE,CAAC,EAAE,CAAC;YAC5D,CAAC,CAAC,IAAI,GAAG,EAAE,CAAC;QAEd,MAAM,cAAc,GAAG,IAAI,oBAAoB,CAAC,GAAG,CAAC,CAAC;QAErD,IAAI,CAAC,SAAS;aACX,IAAI,CAAkB,KAAK,CAAC,eAAe,CAAC;aAC5C,eAAe,CAAC,cAAc,CAAC,CAAC;IACrC,CAAC;IAEO,4BAA4B;QAClC,IAAI,CAAC,SAAS;aACX,IAAI,CAA6B,KAAK,CAAC,0BAA0B,CAAC;aAClE,EAAE,CAAC,0BAA0B,CAAC;aAC9B,gBAAgB,EAAE,CAAC;QAEtB,IAAI,CAAC,SAAS;aACX,IAAI,CAA6B,KAAK,CAAC,0BAA0B,CAAC;aAClE,EAAE,CAAC,0BAA0B,CAAC;aAC9B,gBAAgB,EAAE,CAAC;QAEtB,IAAI,CAAC,SAAS;aACX,IAAI,CAA2B,KAAK,CAAC,wBAAwB,CAAC;aAC9D,EAAE,CAAC,wBAAwB,CAAC;aAC5B,gBAAgB,EAAE,CAAC;QAEtB,IAAI,CAAC,SAAS;aACX,IAAI,CAA+B,KAAK,CAAC,4BAA4B,CAAC;aACtE,EAAE,CAAC,4BAA4B,CAAC;aAChC,gBAAgB,EAAE,CAAC;IACxB,CAAC;CACF"}