envilder 0.4.0 → 0.5.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.
- package/.github/workflows/cli-validation.yml +58 -0
- package/.github/workflows/unit-tests.yml +1 -0
- package/biome.json +1 -1
- package/package.json +10 -12
- package/scripts/chmod-cli.js +24 -0
- package/scripts/validate-cli.ts +141 -0
- package/src/cli/cli.ts +76 -0
- package/tests/cli/{cliRunner.test.ts → cli.test.ts} +5 -5
- package/tests/sample/cli-validation.env +1 -0
- package/tsconfig.build.json +10 -3
- package/tsconfig.json +12 -4
- package/vite.config.ts +1 -1
- package/src/cli/cliRunner.ts +0 -35
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
name: 🍄 Test CLI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
workflow_dispatch: {}
|
|
5
|
+
|
|
6
|
+
pull_request:
|
|
7
|
+
branches:
|
|
8
|
+
- "*"
|
|
9
|
+
types:
|
|
10
|
+
- opened
|
|
11
|
+
- reopened
|
|
12
|
+
- synchronize
|
|
13
|
+
- ready_for_review
|
|
14
|
+
paths:
|
|
15
|
+
- ".github/workflows/cli-validation.yml"
|
|
16
|
+
- "src/**"
|
|
17
|
+
- "scripts/**"
|
|
18
|
+
- "tests/**"
|
|
19
|
+
|
|
20
|
+
jobs:
|
|
21
|
+
validate:
|
|
22
|
+
runs-on: ubuntu-24.04
|
|
23
|
+
if: ${{ !github.event.pull_request.draft }}
|
|
24
|
+
timeout-minutes: 30
|
|
25
|
+
|
|
26
|
+
steps:
|
|
27
|
+
- name: 🚀 ♂️ Checkout
|
|
28
|
+
uses: actions/checkout@v4
|
|
29
|
+
|
|
30
|
+
- name: 🛠️ Setup Node.js with Cache
|
|
31
|
+
uses: actions/setup-node@v4
|
|
32
|
+
with:
|
|
33
|
+
node-version: '20.x'
|
|
34
|
+
cache: 'yarn'
|
|
35
|
+
|
|
36
|
+
- name: 💉 Configure AWS credentials
|
|
37
|
+
uses: aws-actions/configure-aws-credentials@v4
|
|
38
|
+
with:
|
|
39
|
+
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
|
|
40
|
+
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
|
|
41
|
+
aws-region: "eu-west-1"
|
|
42
|
+
|
|
43
|
+
- name: 🪙 Collect dependencies
|
|
44
|
+
run: yarn install --frozen-lockfile
|
|
45
|
+
|
|
46
|
+
- name: 🏗️ Build the castle
|
|
47
|
+
run: yarn build
|
|
48
|
+
|
|
49
|
+
- name: 🧩 Ensure executable permissions
|
|
50
|
+
run: |
|
|
51
|
+
chmod +x ./lib/cli/cli.js
|
|
52
|
+
|
|
53
|
+
- name: 🌈 Install envilder globally (with npm)
|
|
54
|
+
run: |
|
|
55
|
+
sudo npm install -g .
|
|
56
|
+
|
|
57
|
+
- name: 🎮 Test cli envilder
|
|
58
|
+
run: yarn validate-cli
|
package/biome.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://biomejs.dev/schemas/1.8.3/schema.json",
|
|
3
3
|
"files": {
|
|
4
|
-
"include": ["./src/**", "./tests/**"],
|
|
4
|
+
"include": ["./src/**", "./tests/**", "./scripts/**"],
|
|
5
5
|
"ignore": ["**/node_modules/**", "**/lib/**", "**/dist/**", "**/coverage/**", "**/.lock", "**/.md"]
|
|
6
6
|
},
|
|
7
7
|
"organizeImports": {
|
package/package.json
CHANGED
|
@@ -1,19 +1,22 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "envilder",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "A CLI tool to generate .env files from AWS SSM parameters",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": {
|
|
7
|
+
"import": "./lib/index.js",
|
|
7
8
|
"types": "./lib/index.d.ts"
|
|
8
9
|
}
|
|
9
10
|
},
|
|
11
|
+
"main": "./lib/index.js",
|
|
10
12
|
"bin": {
|
|
11
|
-
"envilder": "lib/cli/
|
|
13
|
+
"envilder": "lib/cli/cli.js"
|
|
12
14
|
},
|
|
13
15
|
"scripts": {
|
|
14
16
|
"clean": "npx jest --clearCache && yarn cache clean --force && npx rimraf lib && npx rimraf node_modules && npx rimraf coverage && npx rimraf yarn.lock",
|
|
15
|
-
"test-run": "yarn build && node lib/cli/
|
|
16
|
-
"build": "tsc -p tsconfig.build.json --sourceMap --declaration",
|
|
17
|
+
"test-run": "yarn build && node lib/cli/cli.js --map=tests/sample/param-map.json --envfile=tests/sample/autogenerated.env",
|
|
18
|
+
"build": "tsc -p tsconfig.build.json --sourceMap --declaration && node --no-warnings scripts/chmod-cli.js",
|
|
19
|
+
"validate-cli": "node --no-warnings --loader ts-node/esm scripts/validate-cli.ts",
|
|
17
20
|
"format": "npx biome format",
|
|
18
21
|
"format:write": "npx biome format --write",
|
|
19
22
|
"lint": "npx secretlint \"**/*\" && biome lint --write && biome format --write && biome check --write && tsc --noEmit",
|
|
@@ -40,10 +43,8 @@
|
|
|
40
43
|
},
|
|
41
44
|
"type": "module",
|
|
42
45
|
"dependencies": {
|
|
43
|
-
"@aws-sdk/client-ssm": "^3.
|
|
46
|
+
"@aws-sdk/client-ssm": "^3.806.0",
|
|
44
47
|
"@aws-sdk/credential-providers": "^3.806.0",
|
|
45
|
-
"@secretlint/core": "^9.2.1",
|
|
46
|
-
"@secretlint/secretlint-rule-preset-recommend": "^9.0.0",
|
|
47
48
|
"@types/node": "^22.5.5",
|
|
48
49
|
"commander": "^13.1.0",
|
|
49
50
|
"dotenv": "^16.4.5",
|
|
@@ -51,17 +52,14 @@
|
|
|
51
52
|
},
|
|
52
53
|
"devDependencies": {
|
|
53
54
|
"@biomejs/biome": "^1.9.1",
|
|
55
|
+
"@secretlint/secretlint-rule-preset-recommend": "^9.3.2",
|
|
54
56
|
"@vitest/coverage-v8": "^3.1.1",
|
|
55
57
|
"rimraf": "^6.0.1",
|
|
56
|
-
"secretlint": "^9.
|
|
58
|
+
"secretlint": "^9.3.2",
|
|
57
59
|
"ts-node": "^10.9.2",
|
|
58
60
|
"typescript": "^5.6.2",
|
|
59
61
|
"vitest": "^3.1.1"
|
|
60
62
|
},
|
|
61
|
-
"resolutions": {
|
|
62
|
-
"string-width": "4.2.3",
|
|
63
|
-
"strip-ansi": "6.0.1"
|
|
64
|
-
},
|
|
65
63
|
"engines": {
|
|
66
64
|
"node": ">=20.0.0",
|
|
67
65
|
"yarn": ">=1.22"
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Simple script to set executable permissions on the CLI entry point.
|
|
4
|
+
* Only runs the chmod command on Unix-based systems.
|
|
5
|
+
*/
|
|
6
|
+
import { chmod } from 'node:fs/promises';
|
|
7
|
+
import { join } from 'node:path';
|
|
8
|
+
import { fileURLToPath } from 'node:url';
|
|
9
|
+
|
|
10
|
+
// Get the project root directory
|
|
11
|
+
const rootDir = join(fileURLToPath(new URL('.', import.meta.url)), '..');
|
|
12
|
+
const cliFilePath = join(rootDir, 'lib', 'cli', 'cli.js');
|
|
13
|
+
|
|
14
|
+
// Only run on non-Windows platforms
|
|
15
|
+
if (process.platform !== 'win32') {
|
|
16
|
+
chmod(cliFilePath, 0o755) // rwxr-xr-x permissions
|
|
17
|
+
.then(() => console.log(`✅ Set executable permissions for: ${cliFilePath}`))
|
|
18
|
+
.catch((error) => {
|
|
19
|
+
console.error(`❌ Error setting permissions: ${error.message}`);
|
|
20
|
+
process.exit(1);
|
|
21
|
+
});
|
|
22
|
+
} else {
|
|
23
|
+
console.log('📋 Skipping executable permissions on Windows platform');
|
|
24
|
+
}
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { spawn } from 'node:child_process';
|
|
3
|
+
import { existsSync } from 'node:fs';
|
|
4
|
+
import { dirname, join } from 'node:path';
|
|
5
|
+
import { fileURLToPath } from 'node:url';
|
|
6
|
+
|
|
7
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
8
|
+
const __dirname = dirname(__filename);
|
|
9
|
+
const rootDir = join(__dirname, '..');
|
|
10
|
+
const isGithubAction = process.env.GITHUB_ACTIONS === 'true';
|
|
11
|
+
const isWindows = process.platform === 'win32';
|
|
12
|
+
const findCommand = isWindows ? 'where' : 'which';
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Run a command with the given arguments
|
|
16
|
+
*/
|
|
17
|
+
function runCommand(command: string, args: string[]): Promise<{ code: number; output: string }> {
|
|
18
|
+
return new Promise((resolve) => {
|
|
19
|
+
const proc = spawn(command, args, { shell: true });
|
|
20
|
+
let output = '';
|
|
21
|
+
|
|
22
|
+
proc.stdout.on('data', (data) => {
|
|
23
|
+
output += data.toString();
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
proc.stderr.on('data', (data) => {
|
|
27
|
+
output += data.toString();
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
proc.on('close', (code) => {
|
|
31
|
+
resolve({ code: code ?? 0, output });
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Try to run a command with both global and local CLI approaches
|
|
38
|
+
*/
|
|
39
|
+
async function tryCommandWithFallback(
|
|
40
|
+
args: string[],
|
|
41
|
+
): Promise<{ code: number; output: string; usedFallback: boolean }> {
|
|
42
|
+
// Try global command first
|
|
43
|
+
const globalResult = await runCommand('envilder', args);
|
|
44
|
+
|
|
45
|
+
if (globalResult.code === 0) {
|
|
46
|
+
return { ...globalResult, usedFallback: false };
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// Fall back to direct node execution
|
|
50
|
+
console.log('Global envilder command failed, trying direct Node.js execution...');
|
|
51
|
+
const directResult = await runCommand('node', ['./lib/cli/cli.js', ...args]);
|
|
52
|
+
|
|
53
|
+
return {
|
|
54
|
+
...directResult,
|
|
55
|
+
usedFallback: true,
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
async function validateCLI() {
|
|
60
|
+
console.log(`🔍 Validating envilder CLI installation${isGithubAction ? ' in GitHub Actions' : ''}...`);
|
|
61
|
+
|
|
62
|
+
try {
|
|
63
|
+
// Test 1: Check CLI version and accessibility
|
|
64
|
+
console.log('Testing envilder version command...');
|
|
65
|
+
const versionResult = await tryCommandWithFallback(['--version']);
|
|
66
|
+
|
|
67
|
+
if (versionResult.code !== 0) {
|
|
68
|
+
throw new Error(`❌ envilder version command failed: ${versionResult.output}`);
|
|
69
|
+
}
|
|
70
|
+
console.log('✅ envilder version command works');
|
|
71
|
+
|
|
72
|
+
// Test 2: Check help command
|
|
73
|
+
console.log('Testing envilder help command...');
|
|
74
|
+
const helpResult = await tryCommandWithFallback(['--help']);
|
|
75
|
+
|
|
76
|
+
if (helpResult.code !== 0) {
|
|
77
|
+
throw new Error(`❌ envilder help command failed: ${helpResult.output}`);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
if (!helpResult.output.includes('--map') || !helpResult.output.includes('--envfile')) {
|
|
81
|
+
throw new Error('❌ envilder help command output is missing expected options');
|
|
82
|
+
}
|
|
83
|
+
console.log('✅ envilder help command works');
|
|
84
|
+
|
|
85
|
+
// Test 3: Check sample file generation
|
|
86
|
+
const testEnvFile = join(rootDir, 'tests', 'sample', 'cli-validation.env');
|
|
87
|
+
console.log('Testing envilder file generation...');
|
|
88
|
+
|
|
89
|
+
const sampleResult = await tryCommandWithFallback([
|
|
90
|
+
'--map',
|
|
91
|
+
join(rootDir, 'tests', 'sample', 'param-map.json'),
|
|
92
|
+
'--envfile',
|
|
93
|
+
testEnvFile,
|
|
94
|
+
]);
|
|
95
|
+
|
|
96
|
+
if (sampleResult.code !== 0) {
|
|
97
|
+
throw new Error(`❌ envilder failed to generate environment file: ${sampleResult.output}`);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
if (!sampleResult.output.includes('Environment File generated')) {
|
|
101
|
+
throw new Error('❌ envilder did not output expected success message');
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
if (!existsSync(testEnvFile)) {
|
|
105
|
+
throw new Error(`❌ envilder did not create the environment file at ${testEnvFile}`);
|
|
106
|
+
}
|
|
107
|
+
console.log('✅ envilder successfully generated environment file');
|
|
108
|
+
|
|
109
|
+
// Test 4: Check error handling for invalid arguments
|
|
110
|
+
console.log('Testing envilder with invalid arguments...');
|
|
111
|
+
const errorResult = await tryCommandWithFallback(['--invalid']);
|
|
112
|
+
|
|
113
|
+
if (errorResult.code === 0) {
|
|
114
|
+
throw new Error('❌ envilder should fail with invalid arguments');
|
|
115
|
+
}
|
|
116
|
+
console.log('✅ envilder properly handles invalid arguments');
|
|
117
|
+
|
|
118
|
+
// Test 5: Check error handling for missing required options
|
|
119
|
+
console.log('Testing envilder with missing required options...');
|
|
120
|
+
const missingResult = await tryCommandWithFallback([]);
|
|
121
|
+
|
|
122
|
+
if (missingResult.code === 0) {
|
|
123
|
+
throw new Error('❌ envilder should fail when required options are missing');
|
|
124
|
+
}
|
|
125
|
+
console.log('✅ envilder properly handles missing required options');
|
|
126
|
+
|
|
127
|
+
console.log('🎉 All CLI validation tests passed!');
|
|
128
|
+
} catch (error) {
|
|
129
|
+
if (error instanceof Error) {
|
|
130
|
+
console.error(error.message);
|
|
131
|
+
} else {
|
|
132
|
+
console.error('Unknown error occurred during CLI validation');
|
|
133
|
+
}
|
|
134
|
+
process.exit(1);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
validateCLI().catch((error) => {
|
|
139
|
+
console.error(error.message);
|
|
140
|
+
process.exit(1);
|
|
141
|
+
});
|
package/src/cli/cli.ts
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
3
|
+
import { dirname, join } from 'node:path';
|
|
4
|
+
import { fileURLToPath } from 'node:url';
|
|
5
|
+
import { Command } from 'commander';
|
|
6
|
+
import { run } from '../index.js';
|
|
7
|
+
|
|
8
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
9
|
+
const __dirname = dirname(__filename);
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Find the package.json file by traversing up directories
|
|
13
|
+
* @param startDir The directory to start searching from
|
|
14
|
+
* @param maxDepth Maximum number of parent directories to check
|
|
15
|
+
* @returns Path to package.json if found, or null if not found
|
|
16
|
+
*/
|
|
17
|
+
function findPackageJson(startDir: string, maxDepth = 5): string | null {
|
|
18
|
+
let currentDir = startDir;
|
|
19
|
+
let depth = 0;
|
|
20
|
+
|
|
21
|
+
while (depth < maxDepth) {
|
|
22
|
+
const packagePath = join(currentDir, 'package.json');
|
|
23
|
+
if (existsSync(packagePath)) {
|
|
24
|
+
return packagePath;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// Go up one directory
|
|
28
|
+
const parentDir = dirname(currentDir);
|
|
29
|
+
if (parentDir === currentDir) {
|
|
30
|
+
// We've reached the root
|
|
31
|
+
break;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
currentDir = parentDir;
|
|
35
|
+
depth++;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// Get package.json path by searching up from current file
|
|
42
|
+
const packageJsonPath = findPackageJson(__dirname) || join(__dirname, '..', '..', 'package.json');
|
|
43
|
+
const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf8'));
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Parses CLI arguments and runs the environment file generator.
|
|
47
|
+
*
|
|
48
|
+
* Expects `--map` and `--envfile` options to be provided, with an optional `--profile` for AWS CLI profile selection. Invokes the main process to generate a `.env` file from AWS SSM parameters based on the provided mapping.
|
|
49
|
+
*
|
|
50
|
+
* @throws {Error} If either `--map` or `--envfile` arguments are missing.
|
|
51
|
+
*/
|
|
52
|
+
export async function main() {
|
|
53
|
+
const program = new Command();
|
|
54
|
+
program
|
|
55
|
+
.name('envilder')
|
|
56
|
+
.description('A CLI tool to generate .env files from AWS SSM parameters')
|
|
57
|
+
.version(packageJson.version)
|
|
58
|
+
.requiredOption('--map <path>', 'Path to the JSON file with environment variable mapping')
|
|
59
|
+
.requiredOption('--envfile <path>', 'Path to the .env file to be generated')
|
|
60
|
+
.option('--profile <name>', 'AWS CLI profile to use');
|
|
61
|
+
|
|
62
|
+
await program.parseAsync(process.argv);
|
|
63
|
+
const options = program.opts();
|
|
64
|
+
|
|
65
|
+
if (!options.map || !options.envfile) {
|
|
66
|
+
throw new Error('Missing required arguments: --map and --envfile');
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
await run(options.map, options.envfile, options.profile);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// Execute the CLI
|
|
73
|
+
main().catch((error) => {
|
|
74
|
+
console.error('🚨 Uh-oh! Looks like Mario fell into the wrong pipe! 🍄💥');
|
|
75
|
+
console.error(error);
|
|
76
|
+
});
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
|
2
|
-
import {
|
|
2
|
+
import { main } from '../../src/cli/cli';
|
|
3
3
|
import { run } from '../../src/index';
|
|
4
4
|
|
|
5
5
|
vi.mock('../../src/index', () => ({
|
|
6
6
|
run: vi.fn(),
|
|
7
7
|
}));
|
|
8
8
|
|
|
9
|
-
describe('
|
|
9
|
+
describe('CLI', () => {
|
|
10
10
|
const originalArgv = process.argv;
|
|
11
11
|
|
|
12
12
|
beforeEach(() => {
|
|
@@ -24,7 +24,7 @@ describe('cliRunner', () => {
|
|
|
24
24
|
process.argv.push('--map', mockMapPath, '--envfile', mockEnvFilePath);
|
|
25
25
|
|
|
26
26
|
// Act
|
|
27
|
-
await
|
|
27
|
+
await main();
|
|
28
28
|
|
|
29
29
|
// Assert
|
|
30
30
|
expect(run).toHaveBeenCalledWith(mockMapPath, mockEnvFilePath, undefined);
|
|
@@ -37,7 +37,7 @@ describe('cliRunner', () => {
|
|
|
37
37
|
});
|
|
38
38
|
|
|
39
39
|
// Act
|
|
40
|
-
const action =
|
|
40
|
+
const action = main();
|
|
41
41
|
|
|
42
42
|
// Assert
|
|
43
43
|
await expect(action).rejects.toThrow('process.exit called');
|
|
@@ -51,7 +51,7 @@ describe('cliRunner', () => {
|
|
|
51
51
|
process.argv.push('--map', mockMapPath, '--envfile', mockEnvFilePath, '--profile', mockProfile);
|
|
52
52
|
|
|
53
53
|
// Act
|
|
54
|
-
await
|
|
54
|
+
await main();
|
|
55
55
|
|
|
56
56
|
// Assert
|
|
57
57
|
expect(run).toHaveBeenCalledWith(mockMapPath, mockEnvFilePath, mockProfile);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
TOKEN_SECRET=this_is_for_test
|
package/tsconfig.build.json
CHANGED
|
@@ -1,7 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"extends": "./tsconfig.json",
|
|
3
3
|
"compilerOptions": {
|
|
4
|
-
"rootDir": "./src"
|
|
4
|
+
"rootDir": "./src",
|
|
5
|
+
"outDir": "./lib",
|
|
6
|
+
"module": "ESNext",
|
|
7
|
+
"moduleResolution": "Node",
|
|
8
|
+
"preserveConstEnums": true,
|
|
9
|
+
"sourceMap": true
|
|
5
10
|
},
|
|
6
|
-
"include": [
|
|
7
|
-
|
|
11
|
+
"include": [
|
|
12
|
+
"./src/**/*"
|
|
13
|
+
]
|
|
14
|
+
}
|
package/tsconfig.json
CHANGED
|
@@ -10,13 +10,21 @@
|
|
|
10
10
|
"esModuleInterop": true,
|
|
11
11
|
"noImplicitAny": true,
|
|
12
12
|
"skipLibCheck": true,
|
|
13
|
-
"lib": [
|
|
13
|
+
"lib": [
|
|
14
|
+
"es2022"
|
|
15
|
+
],
|
|
14
16
|
"declaration": true,
|
|
15
17
|
"declarationMap": true,
|
|
16
18
|
"sourceMap": true,
|
|
17
19
|
"forceConsistentCasingInFileNames": true,
|
|
18
20
|
"resolveJsonModule": true,
|
|
19
|
-
"types": [
|
|
21
|
+
"types": [
|
|
22
|
+
"node",
|
|
23
|
+
"picocolors"
|
|
24
|
+
]
|
|
20
25
|
},
|
|
21
|
-
"include": [
|
|
22
|
-
|
|
26
|
+
"include": [
|
|
27
|
+
"src/**/*",
|
|
28
|
+
"scripts/**/*"
|
|
29
|
+
]
|
|
30
|
+
}
|
package/vite.config.ts
CHANGED
package/src/cli/cliRunner.ts
DELETED
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
import { Command } from 'commander';
|
|
3
|
-
import { run } from '../index.js';
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Parses CLI arguments and runs the environment file generator.
|
|
7
|
-
*
|
|
8
|
-
* Expects `--map` and `--envfile` options to be provided, with an optional `--profile` for AWS CLI profile selection. Invokes the main process to generate a `.env` file from AWS SSM parameters based on the provided mapping.
|
|
9
|
-
*
|
|
10
|
-
* @throws {Error} If either `--map` or `--envfile` arguments are missing.
|
|
11
|
-
*/
|
|
12
|
-
export async function cliRunner() {
|
|
13
|
-
const program = new Command();
|
|
14
|
-
|
|
15
|
-
program
|
|
16
|
-
.name('envilder')
|
|
17
|
-
.description('A CLI tool to generate .env files from AWS SSM parameters')
|
|
18
|
-
.version('0.1.0')
|
|
19
|
-
.requiredOption('--map <path>', 'Path to the JSON file with environment variable mapping')
|
|
20
|
-
.requiredOption('--envfile <path>', 'Path to the .env file to be generated')
|
|
21
|
-
.option('--profile <name>', 'AWS CLI profile to use');
|
|
22
|
-
|
|
23
|
-
await program.parseAsync(process.argv);
|
|
24
|
-
const options = program.opts();
|
|
25
|
-
|
|
26
|
-
if (!options.map || !options.envfile) {
|
|
27
|
-
throw new Error('Missing required arguments: --map and --envfile');
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
await run(options.map, options.envfile, options.profile);
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
cliRunner().catch((error) => {
|
|
34
|
-
console.error('🚨 Uh-oh! Looks like Mario fell into the wrong pipe! 🍄💥');
|
|
35
|
-
});
|