@efebia/one-env 1.0.0

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 (52) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +296 -0
  3. package/bin/one-env +2 -0
  4. package/lib/cli/commands/generate.d.ts +11 -0
  5. package/lib/cli/commands/generate.d.ts.map +1 -0
  6. package/lib/cli/commands/generate.js +57 -0
  7. package/lib/cli/commands/generate.js.map +1 -0
  8. package/lib/cli/commands/validate-aws.d.ts +11 -0
  9. package/lib/cli/commands/validate-aws.d.ts.map +1 -0
  10. package/lib/cli/commands/validate-aws.js +64 -0
  11. package/lib/cli/commands/validate-aws.js.map +1 -0
  12. package/lib/cli/commands/validate.d.ts +7 -0
  13. package/lib/cli/commands/validate.d.ts.map +1 -0
  14. package/lib/cli/commands/validate.js +60 -0
  15. package/lib/cli/commands/validate.js.map +1 -0
  16. package/lib/cli/env-tool.d.ts +11 -0
  17. package/lib/cli/env-tool.d.ts.map +1 -0
  18. package/lib/cli/env-tool.js +60 -0
  19. package/lib/cli/env-tool.js.map +1 -0
  20. package/lib/cli/types.d.ts +70 -0
  21. package/lib/cli/types.d.ts.map +1 -0
  22. package/lib/cli/types.js +5 -0
  23. package/lib/cli/types.js.map +1 -0
  24. package/lib/cli/utils/aws.d.ts +20 -0
  25. package/lib/cli/utils/aws.d.ts.map +1 -0
  26. package/lib/cli/utils/aws.js +50 -0
  27. package/lib/cli/utils/aws.js.map +1 -0
  28. package/lib/cli/utils/file.d.ts +35 -0
  29. package/lib/cli/utils/file.d.ts.map +1 -0
  30. package/lib/cli/utils/file.js +72 -0
  31. package/lib/cli/utils/file.js.map +1 -0
  32. package/lib/cli/utils/formatting.d.ts +50 -0
  33. package/lib/cli/utils/formatting.d.ts.map +1 -0
  34. package/lib/cli/utils/formatting.js +136 -0
  35. package/lib/cli/utils/formatting.js.map +1 -0
  36. package/lib/cli/utils/schema-loader.d.ts +40 -0
  37. package/lib/cli/utils/schema-loader.d.ts.map +1 -0
  38. package/lib/cli/utils/schema-loader.js +119 -0
  39. package/lib/cli/utils/schema-loader.js.map +1 -0
  40. package/lib/cli/utils/validation.d.ts +40 -0
  41. package/lib/cli/utils/validation.d.ts.map +1 -0
  42. package/lib/cli/utils/validation.js +116 -0
  43. package/lib/cli/utils/validation.js.map +1 -0
  44. package/lib/env-loader.d.ts +97 -0
  45. package/lib/env-loader.d.ts.map +1 -0
  46. package/lib/env-loader.js +199 -0
  47. package/lib/env-loader.js.map +1 -0
  48. package/lib/index.d.ts +2 -0
  49. package/lib/index.d.ts.map +1 -0
  50. package/lib/index.js +3 -0
  51. package/lib/index.js.map +1 -0
  52. package/package.json +55 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 one-env contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,296 @@
1
+ # one-env
2
+
3
+ Type-safe environment configuration management for Node.js applications with runtime validation and CLI tools.
4
+
5
+ ## Features
6
+
7
+ - 🔒 **Type-safe** environment variables with full TypeScript support
8
+ - ✅ **Runtime validation** using Zod schemas
9
+ - 🛠️ **CLI tools** for generating, validating, and managing environment files
10
+ - 🌍 **Multiple sources**: Load from YAML files or JSON environment variables
11
+ - 🚀 **Production ready**: Validate AWS Secrets Manager configurations
12
+ - 💡 **Developer friendly**: Autocomplete for all environment variables
13
+
14
+ ## Installation
15
+
16
+ ```bash
17
+ # Using npm
18
+ npm install one-env zod
19
+
20
+ # Using yarn
21
+ yarn add one-env zod
22
+
23
+ # Using pnpm
24
+ pnpm add one-env zod
25
+ ```
26
+
27
+ Note: `zod` v4 is a peer dependency and must be installed separately.
28
+
29
+ ## Quick Start
30
+
31
+ ### 1. Define your environment schema
32
+
33
+ ```typescript
34
+ // env-schema.ts
35
+ import { z } from 'zod/v4';
36
+
37
+ const EnvSchema = z.object({
38
+ // Application
39
+ port: z.coerce.number().positive().default(3000),
40
+ nodeEnv: z.enum(['development', 'production', 'test']).default('development'),
41
+
42
+ // Database
43
+ databaseUrl: z.string().url().describe('PostgreSQL connection URL'),
44
+
45
+ // API Keys
46
+ apiKey: z.string().min(32).describe('External API key'),
47
+
48
+ // Feature flags
49
+ enableCache: z.boolean().default(true),
50
+ cacheTimeout: z.coerce.number().positive().optional().default(3600),
51
+ });
52
+
53
+ export default EnvSchema;
54
+ ```
55
+
56
+ ### 2. Use in your application
57
+
58
+ ```typescript
59
+ // config.ts
60
+ import { createEnvWithInit } from 'one-env';
61
+ import EnvSchema from './env-schema';
62
+
63
+ // Create env instance
64
+ const env = createEnvWithInit(EnvSchema);
65
+
66
+ // Initialize with YAML file
67
+ env.init({ file: './env.local.yml' });
68
+
69
+ // Or initialize with JSON from environment variable
70
+ env.init({ env: 'APP_CONFIG' });
71
+
72
+ // Use with full type safety
73
+ export const config = {
74
+ port: env.get('port'),
75
+ database: env.get('databaseUrl'),
76
+ cache: {
77
+ enabled: env.get('enableCache'),
78
+ timeout: env.get('cacheTimeout'),
79
+ }
80
+ };
81
+ ```
82
+
83
+ ### 3. Alternative: Immediate initialization
84
+
85
+ ```typescript
86
+ import { createEnv } from 'one-env';
87
+ import EnvSchema from './env-schema';
88
+
89
+ // Initialize immediately
90
+ const env = createEnv({
91
+ schema: EnvSchema,
92
+ file: './env.local.yml'
93
+ });
94
+
95
+ // Use directly
96
+ const port = env.get('port');
97
+ ```
98
+
99
+ ## CLI Tools
100
+
101
+ one-env includes powerful CLI tools for managing your environment configuration:
102
+
103
+ ### Generate environment file
104
+
105
+ Create a new environment file with default values from your schema:
106
+
107
+ ```bash
108
+ # Generate env.local.yml with defaults
109
+ one-env generate -s ./env-schema.js
110
+
111
+ # Generate with custom output
112
+ one-env generate -s ./env-schema.js -o env.example.yml
113
+
114
+ # Force overwrite existing file
115
+ one-env generate -s ./env-schema.js --force
116
+ ```
117
+
118
+ ### Validate environment file
119
+
120
+ Check if your environment file is valid:
121
+
122
+ ```bash
123
+ # Validate env.local.yml
124
+ one-env validate -s ./env-schema.js
125
+
126
+ # Validate specific file
127
+ one-env validate -s ./env-schema.js --file env.prod.yml
128
+
129
+ # Output as JSON (for CI/CD)
130
+ one-env validate -s ./env-schema.js --json
131
+ ```
132
+
133
+ ### Validate AWS Secrets
134
+
135
+ Validate environment variables stored in AWS Secrets Manager:
136
+
137
+ ```bash
138
+ # Validate AWS secrets
139
+ one-env validate-aws -s ./env-schema.js --secret-name my-app/prod
140
+
141
+ # With specific AWS profile
142
+ one-env validate-aws -s ./env-schema.js --secret-name my-app/prod --profile production
143
+
144
+ # With specific region
145
+ one-env validate-aws -s ./env-schema.js --secret-name my-app/prod --region us-east-1
146
+ ```
147
+
148
+ ## API Reference
149
+
150
+ ### `createEnv(options)`
151
+
152
+ Creates and immediately initializes an environment loader.
153
+
154
+ ```typescript
155
+ const env = createEnv({
156
+ schema: ZodSchema,
157
+ file: './env.yml' // or
158
+ env: 'CONFIG_JSON' // for JSON from environment variable
159
+ });
160
+ ```
161
+
162
+ ### `createEnvWithInit(schema)`
163
+
164
+ Creates an environment loader with deferred initialization.
165
+
166
+ ```typescript
167
+ const env = createEnvWithInit(schema);
168
+
169
+ // Initialize later
170
+ env.init({ file: './env.yml' });
171
+ // or
172
+ env.init({ env: 'CONFIG_JSON' });
173
+ ```
174
+
175
+ ### Methods
176
+
177
+ #### `get(key)` / `get(...keys)`
178
+
179
+ Get one or multiple environment values with type safety:
180
+
181
+ ```typescript
182
+ // Single value
183
+ const port = env.get('port'); // number
184
+
185
+ // Multiple values
186
+ const { port, nodeEnv } = env.get('port', 'nodeEnv');
187
+ ```
188
+
189
+ #### `getOptional(key)` / `getOptional(...keys)`
190
+
191
+ Get optional environment values:
192
+
193
+ ```typescript
194
+ const timeout = env.getOptional('cacheTimeout'); // number | undefined
195
+ ```
196
+
197
+ #### `getAll()`
198
+
199
+ Get all validated environment variables:
200
+
201
+ ```typescript
202
+ const config = env.getAll(); // Fully typed object
203
+ ```
204
+
205
+ ## Best Practices
206
+
207
+ ### 1. Schema Organization
208
+
209
+ Keep your schema in a separate file for reusability:
210
+
211
+ ```typescript
212
+ // env-schema.ts
213
+ export default z.object({
214
+ // Group related variables
215
+ // Database
216
+ dbHost: z.string(),
217
+ dbPort: z.coerce.number(),
218
+ dbName: z.string(),
219
+
220
+ // Add descriptions for documentation
221
+ apiKey: z.string().describe('API key for external service'),
222
+
223
+ // Use defaults for development
224
+ logLevel: z.enum(['debug', 'info', 'warn', 'error']).default('info'),
225
+ });
226
+ ```
227
+
228
+ ### 2. Environment-specific Files
229
+
230
+ Use different files for different environments:
231
+
232
+ ```
233
+ env.local.yml # Local development (gitignored)
234
+ env.test.yml # Test environment
235
+ env.example.yml # Example file (committed)
236
+ ```
237
+
238
+ ### 3. CI/CD Integration
239
+
240
+ ```yaml
241
+ # .github/workflows/validate.yml
242
+ - name: Validate environment
243
+ run: |
244
+ npx one-env validate -s ./env-schema.js --json
245
+
246
+ - name: Validate production secrets
247
+ run: |
248
+ npx one-env validate-aws \
249
+ -s ./env-schema.js \
250
+ --secret-name prod/myapp \
251
+ --profile production
252
+ ```
253
+
254
+ ### 4. Type Exports
255
+
256
+ Export types for use across your application:
257
+
258
+ ```typescript
259
+ // config.ts
260
+ import { createEnvWithInit } from 'one-env';
261
+ import { z } from 'zod/v4';
262
+ import EnvSchema from './env-schema';
263
+
264
+ export type Config = z.infer<typeof EnvSchema>;
265
+
266
+ const env = createEnvWithInit(EnvSchema);
267
+ export default env;
268
+ ```
269
+
270
+ ## Error Handling
271
+
272
+ one-env provides clear error messages for configuration issues:
273
+
274
+ ```
275
+ Environment validation failed:
276
+ - port: Expected number, received string
277
+ - databaseUrl: Invalid URL
278
+ - apiKey: String must contain at least 32 characters
279
+ ```
280
+
281
+ ## Requirements
282
+
283
+ - Node.js >= 18.0.0
284
+ - Zod v4 (peer dependency)
285
+
286
+ ## License
287
+
288
+ MIT
289
+
290
+ ## Contributing
291
+
292
+ Contributions are welcome! Please feel free to submit a Pull Request.
293
+
294
+ ## Support
295
+
296
+ For bugs and feature requests, please [create an issue](https://github.com/yourusername/one-env/issues).
package/bin/one-env ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ import '../lib/cli/env-tool.js';
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Generate command implementation
3
+ * Creates new environment files with default values from schema
4
+ */
5
+ import { GenerateOptions } from '../types.js';
6
+ /**
7
+ * Handles the generate command
8
+ * @param options - Command options
9
+ */
10
+ export declare function handleGenerateCommand(options: GenerateOptions): Promise<void>;
11
+ //# sourceMappingURL=generate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generate.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/generate.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAK9C;;;GAGG;AACH,wBAAsB,qBAAqB,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAoDnF"}
@@ -0,0 +1,57 @@
1
+ /**
2
+ * Generate command implementation
3
+ * Creates new environment files with default values from schema
4
+ */
5
+ import chalk from 'chalk';
6
+ import { resolvePath, fileExists, writeFile, createYamlContent } from '../utils/file.js';
7
+ import { printSuccess, printError, printStatus } from '../utils/formatting.js';
8
+ import { loadSchema, extractSchemaDefaults, formatSchemaSource } from '../utils/schema-loader.js';
9
+ /**
10
+ * Handles the generate command
11
+ * @param options - Command options
12
+ */
13
+ export async function handleGenerateCommand(options) {
14
+ const outputPath = resolvePath(options.output);
15
+ try {
16
+ // Check if file exists and prompt for confirmation
17
+ if (fileExists(outputPath) && !options.force) {
18
+ console.log(chalk.yellow('Warning:') + ` File '${options.output}' already exists.`);
19
+ console.log('Use --force to overwrite, or specify a different output file.');
20
+ process.exit(1);
21
+ }
22
+ // Load schema dynamically
23
+ printStatus(`Loading schema from ${formatSchemaSource(options.schema)}...`, 'info');
24
+ const schema = await loadSchema(options.schema);
25
+ printStatus('Generating environment file from schema defaults...', 'info');
26
+ // Generate default values from schema
27
+ const envData = extractSchemaDefaults(schema);
28
+ // Create YAML content with proper formatting and comments
29
+ const yamlContent = createYamlContent(envData);
30
+ // Write to file
31
+ writeFile(outputPath, yamlContent);
32
+ // Show success message with details
33
+ const fieldCount = Object.keys(envData).length;
34
+ printSuccess('generated', {
35
+ 'File': options.output,
36
+ 'Location': outputPath,
37
+ 'Fields generated': fieldCount,
38
+ });
39
+ // Show next steps
40
+ console.log(`\n${chalk.yellow('Next steps:')}`);
41
+ console.log(`1. Review and customize the generated values`);
42
+ console.log(`2. Update sensitive fields like API keys and secrets`);
43
+ console.log(`3. Validate with: ${chalk.cyan('yarn env:validate')}`);
44
+ }
45
+ catch (error) {
46
+ const tips = [];
47
+ if (error.code === 'ENOENT') {
48
+ tips.push("Make sure you're running this from the backend directory.");
49
+ }
50
+ else if (error.message.includes('permission')) {
51
+ tips.push('Check file permissions for the output directory.');
52
+ }
53
+ printError(error, tips);
54
+ process.exit(1);
55
+ }
56
+ }
57
+ //# sourceMappingURL=generate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generate.js","sourceRoot":"","sources":["../../../src/cli/commands/generate.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACzF,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAC/E,OAAO,EAAE,UAAU,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAElG;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CAAC,OAAwB;IAChE,MAAM,UAAU,GAAG,WAAW,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IAE/C,IAAI,CAAC;QACD,mDAAmD;QACnD,IAAI,UAAU,CAAC,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;YAC3C,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,UAAU,CAAC,GAAG,UAAU,OAAO,CAAC,MAAM,mBAAmB,CAAC,CAAC;YACpF,OAAO,CAAC,GAAG,CAAC,+DAA+D,CAAC,CAAC;YAC7E,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACpB,CAAC;QAED,0BAA0B;QAC1B,WAAW,CAAC,uBAAuB,kBAAkB,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;QACpF,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QAEhD,WAAW,CAAC,qDAAqD,EAAE,MAAM,CAAC,CAAC;QAE3E,sCAAsC;QACtC,MAAM,OAAO,GAAG,qBAAqB,CAAC,MAAM,CAAC,CAAC;QAE9C,0DAA0D;QAC1D,MAAM,WAAW,GAAG,iBAAiB,CAAC,OAAO,CAAC,CAAC;QAE/C,gBAAgB;QAChB,SAAS,CAAC,UAAU,EAAE,WAAW,CAAC,CAAC;QAEnC,oCAAoC;QACpC,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC;QAC/C,YAAY,CAAC,WAAW,EAAE;YACtB,MAAM,EAAE,OAAO,CAAC,MAAM;YACtB,UAAU,EAAE,UAAU;YACtB,kBAAkB,EAAE,UAAU;SACjC,CAAC,CAAC;QAEH,kBAAkB;QAClB,OAAO,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,MAAM,CAAC,aAAa,CAAC,EAAE,CAAC,CAAC;QAChD,OAAO,CAAC,GAAG,CAAC,8CAA8C,CAAC,CAAC;QAC5D,OAAO,CAAC,GAAG,CAAC,sDAAsD,CAAC,CAAC;QACpE,OAAO,CAAC,GAAG,CAAC,qBAAqB,KAAK,CAAC,IAAI,CAAC,mBAAmB,CAAC,EAAE,CAAC,CAAC;IAExE,CAAC;IAAC,OAAO,KAAU,EAAE,CAAC;QAClB,MAAM,IAAI,GAAa,EAAE,CAAC;QAE1B,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YAC1B,IAAI,CAAC,IAAI,CAAC,2DAA2D,CAAC,CAAC;QAC3E,CAAC;aAAM,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC;YAC9C,IAAI,CAAC,IAAI,CAAC,kDAAkD,CAAC,CAAC;QAClE,CAAC;QAED,UAAU,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QACxB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACpB,CAAC;AACL,CAAC"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Validate AWS command implementation
3
+ * Validates AWS Secrets Manager secrets against the schema
4
+ */
5
+ import { ValidateAwsOptions } from '../types.js';
6
+ /**
7
+ * Handles the validate-aws command
8
+ * @param options - Command options
9
+ */
10
+ export declare function handleValidateAwsCommand(options: ValidateAwsOptions): Promise<void>;
11
+ //# sourceMappingURL=validate-aws.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate-aws.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/validate-aws.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAMjD;;;GAGG;AACH,wBAAsB,wBAAwB,CAAC,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,CAwDzF"}
@@ -0,0 +1,64 @@
1
+ /**
2
+ * Validate AWS command implementation
3
+ * Validates AWS Secrets Manager secrets against the schema
4
+ */
5
+ import chalk from 'chalk';
6
+ import { createSecretsManagerClient, getSecretValue } from '../utils/aws.js';
7
+ import { validateEnvData } from '../utils/validation.js';
8
+ import { printValidationResults, formatJsonOutput, formatJsonError, printStatus } from '../utils/formatting.js';
9
+ import { loadSchema, formatSchemaSource } from '../utils/schema-loader.js';
10
+ /**
11
+ * Handles the validate-aws command
12
+ * @param options - Command options
13
+ */
14
+ export async function handleValidateAwsCommand(options) {
15
+ // Configure AWS client
16
+ const client = createSecretsManagerClient(options.region, options.profile);
17
+ try {
18
+ // Load schema dynamically
19
+ if (!options.json) {
20
+ printStatus(`Loading schema from ${formatSchemaSource(options.schema)}...`, 'info');
21
+ }
22
+ const schema = await loadSchema(options.schema);
23
+ // Fetch secret from AWS
24
+ if (!options.json) {
25
+ printStatus(`Fetching secret '${options.secretName}' from AWS Secrets Manager...`, 'info');
26
+ }
27
+ const secretData = await getSecretValue(client, options.secretName);
28
+ // Validate against schema
29
+ const results = validateEnvData(secretData, schema, options.secretName, options.region);
30
+ if (options.json) {
31
+ // JSON output for automation
32
+ const jsonOutput = formatJsonOutput(results);
33
+ console.log(JSON.stringify(jsonOutput, null, 2));
34
+ }
35
+ else {
36
+ // Human-readable output
37
+ printValidationResults(results);
38
+ }
39
+ // Exit with appropriate code
40
+ process.exit(results.success ? 0 : 1);
41
+ }
42
+ catch (error) {
43
+ if (options.json) {
44
+ const jsonError = formatJsonError(error, 'aws_error', options.secretName, options.region);
45
+ console.log(JSON.stringify(jsonError, null, 2));
46
+ }
47
+ else {
48
+ const tips = [];
49
+ if (error.message.includes('not found')) {
50
+ tips.push('Check that the secret name and region are correct.');
51
+ tips.push('Ensure you have AWS credentials configured.');
52
+ }
53
+ else if (error.message.includes('credentials')) {
54
+ tips.push("Configure AWS credentials using 'aws configure' or environment variables.");
55
+ }
56
+ console.error(`\n${chalk.red.bold('Error:')} ${error.message}\n`);
57
+ tips.forEach(tip => {
58
+ console.log(`${chalk.yellow('Tip:')} ${tip}`);
59
+ });
60
+ }
61
+ process.exit(1);
62
+ }
63
+ }
64
+ //# sourceMappingURL=validate-aws.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate-aws.js","sourceRoot":"","sources":["../../../src/cli/commands/validate-aws.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import { ValidateOptions } from '../types.js';
2
+ /**
3
+ * Handles the validate command
4
+ * @param options - Command options
5
+ */
6
+ export declare function handleValidateCommand(options: ValidateOptions): Promise<void>;
7
+ //# sourceMappingURL=validate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/validate.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAM9C;;;GAGG;AACH,wBAAsB,qBAAqB,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAoDnF"}
@@ -0,0 +1,60 @@
1
+ /**
2
+ * Validate command implementation
3
+ * Validates existing environment files against the schema
4
+ */
5
+ import chalk from 'chalk';
6
+ import { resolvePath, loadYamlFile } from '../utils/file.js';
7
+ import { validateEnvData } from '../utils/validation.js';
8
+ import { printValidationResults, formatJsonOutput, formatJsonError, printStatus } from '../utils/formatting.js';
9
+ import { loadSchema, formatSchemaSource } from '../utils/schema-loader.js';
10
+ /**
11
+ * Handles the validate command
12
+ * @param options - Command options
13
+ */
14
+ export async function handleValidateCommand(options) {
15
+ try {
16
+ // Load schema dynamically
17
+ if (!options.json) {
18
+ printStatus(`Loading schema from ${formatSchemaSource(options.schema)}...`, 'info');
19
+ }
20
+ const schema = await loadSchema(options.schema);
21
+ // Load YAML file
22
+ if (!options.json) {
23
+ printStatus(`Loading environment file '${options.file}'...`, 'info');
24
+ }
25
+ const filePath = resolvePath(options.file);
26
+ const envData = loadYamlFile(filePath);
27
+ // Validate against schema
28
+ const results = validateEnvData(envData, schema, options.file);
29
+ if (options.json) {
30
+ // JSON output for automation
31
+ const jsonOutput = formatJsonOutput(results);
32
+ console.log(JSON.stringify(jsonOutput, null, 2));
33
+ }
34
+ else {
35
+ // Human-readable output
36
+ printValidationResults(results);
37
+ }
38
+ // Exit with appropriate code
39
+ process.exit(results.success ? 0 : 1);
40
+ }
41
+ catch (error) {
42
+ if (options.json) {
43
+ const jsonError = formatJsonError(error, 'file_error', options.file);
44
+ console.log(JSON.stringify(jsonError, null, 2));
45
+ }
46
+ else {
47
+ const tips = [];
48
+ if (error.message.includes('not found')) {
49
+ tips.push("Make sure you're running this from the backend directory.");
50
+ tips.push(`Current directory: ${process.cwd()}`);
51
+ }
52
+ console.error(`\n${chalk.red.bold('Error:')} ${error.message}\n`);
53
+ tips.forEach(tip => {
54
+ console.log(`${chalk.yellow('Tip:')} ${tip}`);
55
+ });
56
+ }
57
+ process.exit(1);
58
+ }
59
+ }
60
+ //# sourceMappingURL=validate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate.js","sourceRoot":"","sources":["../../../src/cli/commands/validate.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAC7D,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,sBAAsB,EAAE,gBAAgB,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAChH,OAAO,EAAE,UAAU,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAE3E;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CAAC,OAAwB;IAChE,IAAI,CAAC;QACD,0BAA0B;QAC1B,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;YAChB,WAAW,CAAC,uBAAuB,kBAAkB,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;QACxF,CAAC;QAED,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QAEhD,iBAAiB;QACjB,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;YAChB,WAAW,CAAC,6BAA6B,OAAO,CAAC,IAAI,MAAM,EAAE,MAAM,CAAC,CAAC;QACzE,CAAC;QAED,MAAM,QAAQ,GAAG,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAC3C,MAAM,OAAO,GAAG,YAAY,CAAC,QAAQ,CAAC,CAAC;QAEvC,0BAA0B;QAC1B,MAAM,OAAO,GAAG,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;QAE/D,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;YACf,6BAA6B;YAC7B,MAAM,UAAU,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAC;YAC7C,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QACrD,CAAC;aAAM,CAAC;YACJ,wBAAwB;YACxB,sBAAsB,CAAC,OAAO,CAAC,CAAC;QACpC,CAAC;QAED,6BAA6B;QAC7B,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAE1C,CAAC;IAAC,OAAO,KAAU,EAAE,CAAC;QAClB,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;YACf,MAAM,SAAS,GAAG,eAAe,CAAC,KAAK,EAAE,YAAY,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;YACrE,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QACpD,CAAC;aAAM,CAAC;YACJ,MAAM,IAAI,GAAa,EAAE,CAAC;YAE1B,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC;gBACtC,IAAI,CAAC,IAAI,CAAC,2DAA2D,CAAC,CAAC;gBACvE,IAAI,CAAC,IAAI,CAAC,sBAAsB,OAAO,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;YACrD,CAAC;YAED,OAAO,CAAC,KAAK,CAAC,KAAK,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,KAAK,CAAC,OAAO,IAAI,CAAC,CAAC;YAClE,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE;gBACf,OAAO,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,GAAG,EAAE,CAAC,CAAC;YAClD,CAAC,CAAC,CAAC;QACP,CAAC;QAED,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACpB,CAAC;AACL,CAAC"}
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Environment Tool - Unified TypeScript CLI for Environment Management
4
+ *
5
+ * This unified tool provides comprehensive environment management capabilities:
6
+ * - generate: Creates new environment files with default values from schema
7
+ * - validate: Validates existing environment files against the schema
8
+ * - validate-aws: Validates AWS Secrets Manager secrets against the schema
9
+ */
10
+ export {};
11
+ //# sourceMappingURL=env-tool.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"env-tool.d.ts","sourceRoot":"","sources":["../../src/cli/env-tool.ts"],"names":[],"mappings":";AAEA;;;;;;;GAOG"}
@@ -0,0 +1,60 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Environment Tool - Unified TypeScript CLI for Environment Management
4
+ *
5
+ * This unified tool provides comprehensive environment management capabilities:
6
+ * - generate: Creates new environment files with default values from schema
7
+ * - validate: Validates existing environment files against the schema
8
+ * - validate-aws: Validates AWS Secrets Manager secrets against the schema
9
+ */
10
+ import { Command } from 'commander';
11
+ import chalk from 'chalk';
12
+ import { handleGenerateCommand } from './commands/generate.js';
13
+ import { handleValidateCommand } from './commands/validate.js';
14
+ import { handleValidateAwsCommand } from './commands/validate-aws.js';
15
+ // ============================================================================
16
+ // MAIN CLI SETUP
17
+ // ============================================================================
18
+ const program = new Command();
19
+ program
20
+ .name('env-tool')
21
+ .description('Unified CLI for Environment Management')
22
+ .version('1.0.0');
23
+ // Generate command
24
+ program
25
+ .command('generate')
26
+ .description('Generate new environment file with default values from schema')
27
+ .requiredOption('-s, --schema <path>', 'Path to schema file (TypeScript or JavaScript)')
28
+ .option('-o, --output <file>', 'Output file name', 'env.local.yml')
29
+ .option('-f, --force', 'Overwrite existing file without confirmation', false)
30
+ .action(handleGenerateCommand);
31
+ // Validate command
32
+ program
33
+ .command('validate')
34
+ .description('Validate existing environment file against schema')
35
+ .requiredOption('-s, --schema <path>', 'Path to schema file (TypeScript or JavaScript)')
36
+ .option('--file <filename>', 'Path to the environment file', 'env.local.yml')
37
+ .option('--json', 'Output results in JSON format', false)
38
+ .action(handleValidateCommand);
39
+ // Validate AWS command
40
+ program
41
+ .command('validate-aws')
42
+ .description('Validate AWS Secrets Manager secrets against schema')
43
+ .requiredOption('-s, --schema <path>', 'Path to schema file (TypeScript or JavaScript)')
44
+ .option('--secret-name <name>', 'Name of the secret in AWS Secrets Manager', 'envs')
45
+ .option('--region <region>', 'AWS region', process.env['AWS_REGION'] || 'eu-west-1')
46
+ .option('--profile <profile>', 'AWS profile to use (optional)')
47
+ .option('--json', 'Output results in JSON format', false)
48
+ .action(handleValidateAwsCommand);
49
+ // Check dependencies before running
50
+ try {
51
+ await import('js-yaml');
52
+ }
53
+ catch (error) {
54
+ console.error(`\n${chalk.red('Error:')} js-yaml package is not installed.`);
55
+ console.error(`Run: ${chalk.cyan('yarn add js-yaml')}\n`);
56
+ process.exit(1);
57
+ }
58
+ // Run the CLI
59
+ program.parse();
60
+ //# sourceMappingURL=env-tool.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"env-tool.js","sourceRoot":"","sources":["../../src/cli/env-tool.ts"],"names":[],"mappings":";AAEA;;;;;;;GAOG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAC/D,OAAO,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAC/D,OAAO,EAAE,wBAAwB,EAAE,MAAM,4BAA4B,CAAC;AAEtE,+EAA+E;AAC/E,iBAAiB;AACjB,+EAA+E;AAE/E,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACF,IAAI,CAAC,UAAU,CAAC;KAChB,WAAW,CAAC,wCAAwC,CAAC;KACrD,OAAO,CAAC,OAAO,CAAC,CAAC;AAEtB,mBAAmB;AACnB,OAAO;KACF,OAAO,CAAC,UAAU,CAAC;KACnB,WAAW,CAAC,+DAA+D,CAAC;KAC5E,cAAc,CAAC,qBAAqB,EAAE,gDAAgD,CAAC;KACvF,MAAM,CAAC,qBAAqB,EAAE,kBAAkB,EAAE,eAAe,CAAC;KAClE,MAAM,CAAC,aAAa,EAAE,8CAA8C,EAAE,KAAK,CAAC;KAC5E,MAAM,CAAC,qBAAqB,CAAC,CAAC;AAEnC,mBAAmB;AACnB,OAAO;KACF,OAAO,CAAC,UAAU,CAAC;KACnB,WAAW,CAAC,mDAAmD,CAAC;KAChE,cAAc,CAAC,qBAAqB,EAAE,gDAAgD,CAAC;KACvF,MAAM,CAAC,mBAAmB,EAAE,8BAA8B,EAAE,eAAe,CAAC;KAC5E,MAAM,CAAC,QAAQ,EAAE,+BAA+B,EAAE,KAAK,CAAC;KACxD,MAAM,CAAC,qBAAqB,CAAC,CAAC;AAEnC,uBAAuB;AACvB,OAAO;KACF,OAAO,CAAC,cAAc,CAAC;KACvB,WAAW,CAAC,qDAAqD,CAAC;KAClE,cAAc,CAAC,qBAAqB,EAAE,gDAAgD,CAAC;KACvF,MAAM,CAAC,sBAAsB,EAAE,2CAA2C,EAAE,MAAM,CAAC;KACnF,MAAM,CAAC,mBAAmB,EAAE,YAAY,EAAE,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,IAAI,WAAW,CAAC;KACnF,MAAM,CAAC,qBAAqB,EAAE,+BAA+B,CAAC;KAC9D,MAAM,CAAC,QAAQ,EAAE,+BAA+B,EAAE,KAAK,CAAC;KACxD,MAAM,CAAC,wBAAwB,CAAC,CAAC;AAEtC,oCAAoC;AACpC,IAAI,CAAC;IACD,MAAM,MAAM,CAAC,SAAS,CAAC,CAAC;AAC5B,CAAC;AAAC,OAAO,KAAK,EAAE,CAAC;IACb,OAAO,CAAC,KAAK,CAAC,KAAK,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,oCAAoC,CAAC,CAAC;IAC5E,OAAO,CAAC,KAAK,CAAC,QAAQ,KAAK,CAAC,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC;IAC1D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACpB,CAAC;AAED,cAAc;AACd,OAAO,CAAC,KAAK,EAAE,CAAC"}