1 Commits
0.1.9 ... 0.1.4

Author SHA1 Message Date
Morten Olsen
64f6f6df6a docs: add compare section 2025-08-08 15:14:36 +02:00
8 changed files with 510 additions and 530 deletions

1
.env.with-ssm Normal file
View File

@@ -0,0 +1 @@
PASSWORD=SSM:/test/hfd/rds/DB_USER

View File

@@ -25,7 +25,7 @@ that get resolved at runtime.
## Installation ## Installation
```bash ```bash
npm install -g @morten-olsen/with-ssm npm install -g @0morten-olsen/with-ssm
``` ```
## Quick Start ## Quick Start
@@ -117,7 +117,7 @@ override the SSM-resolved values. To avoid this:
- Use `.env.with-ssm` instead of `.env` for SSM references - Use `.env.with-ssm` instead of `.env` for SSM references
- Or use environment variable substitution if your app supports it: - Or use environment variable substitution if your app supports it:
`API_KEY=${API_KEY:-SSM:/myapp/api-key}` `${API_KEY:-SSM:/myapp/api-key}`
### 🚀 Deployment Considerations ### 🚀 Deployment Considerations

View File

@@ -1,2 +1,2 @@
#!/usr/bin/env node #!/usr/bin/env node
import '../dist/index.js'; import '../dist/start.js';

View File

@@ -6,8 +6,8 @@
"license": "GPL-3.0", "license": "GPL-3.0",
"scripts": { "scripts": {
"test:lint": "eslint", "test:lint": "eslint",
"build": "ncc build src/start.ts -o dist", "build": "tsc --build",
"build:dev": "ncc build src/start.ts -o dist --watch", "build:dev": "tsc --build --watch",
"test:unit": "vitest --run --passWithNoTests", "test:unit": "vitest --run --passWithNoTests",
"test": "pnpm run \"/^test:/\"" "test": "pnpm run \"/^test:/\""
}, },
@@ -16,26 +16,27 @@
"dist" "dist"
], ],
"devDependencies": { "devDependencies": {
"@aws-sdk/client-ssm": "^3.863.0",
"@eslint/eslintrc": "3.3.1", "@eslint/eslintrc": "3.3.1",
"@eslint/js": "9.32.0", "@eslint/js": "9.32.0",
"@pnpm/find-workspace-packages": "6.0.9", "@pnpm/find-workspace-packages": "6.0.9",
"@types/node": "24.2.0", "@types/node": "24.2.0",
"@types/yargs": "^17.0.33", "@types/yargs": "^17.0.33",
"@vercel/ncc": "^0.38.3",
"@vitest/coverage-v8": "3.2.4", "@vitest/coverage-v8": "3.2.4",
"dotenv": "^17.2.1",
"eslint": "9.32.0", "eslint": "9.32.0",
"eslint-config-prettier": "10.1.8", "eslint-config-prettier": "10.1.8",
"eslint-plugin-import": "2.32.0", "eslint-plugin-import": "2.32.0",
"eslint-plugin-prettier": "5.5.4", "eslint-plugin-prettier": "5.5.4",
"execa": "^9.6.0",
"prettier": "3.6.2", "prettier": "3.6.2",
"typescript": "5.9.2", "typescript": "5.9.2",
"typescript-eslint": "8.39.0", "typescript-eslint": "8.39.0",
"vitest": "3.2.4", "vitest": "3.2.4"
"yargs": "^18.0.0"
}, },
"name": "@morten-olsen/with-ssm", "name": "@morten-olsen/with-ssm",
"version": "1.0.0" "version": "1.0.0",
"dependencies": {
"@aws-sdk/client-ssm": "^3.859.0",
"dotenv": "^17.2.1",
"execa": "^9.6.0",
"yargs": "^18.0.0"
}
} }

957
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

14
src/utils/cli.ts Normal file
View File

@@ -0,0 +1,14 @@
const splitArgs = (args: string[]) => {
const separatorIndex = args.indexOf('--');
const actionArgs = args.slice(0, separatorIndex);
const command = args[separatorIndex + 1];
const commandArgs = args.slice(separatorIndex + 2);
return {
actionArgs,
command,
commandArgs,
};
};
export { splitArgs };

View File

@@ -1,4 +1,4 @@
import { GetParametersCommand, SSMClient, type Parameter } from '@aws-sdk/client-ssm'; import { GetParametersCommand, SSMClient } from '@aws-sdk/client-ssm';
import { debug } from './debug.js'; import { debug } from './debug.js';
@@ -30,42 +30,18 @@ const replaceParams = async (
return env; return env;
} }
// Chunk names into groups of 10 (AWS SSM GetParametersCommand limit)
const chunks: string[][] = [];
debug(`Chunking ${names.length} names into groups of 10`);
for (let i = 0; i < names.length; i += 10) {
chunks.push(names.slice(i, i + 10));
}
debug(`Processing ${chunks.length} chunks`);
// Fetch parameters in chunks and combine results
const allParams: Parameter[] = [];
const allInvalidParams: string[] = [];
for (const chunk of chunks) {
const command = new GetParametersCommand({ const command = new GetParametersCommand({
Names: chunk, Names: names,
WithDecryption: true, WithDecryption: true,
}); });
const response = await ssm.send(command); const response = await ssm.send(command);
if (response.InvalidParameters?.length || 0 > 0) {
if (response.Parameters) { console.error('Invalid SSM parameters', response.InvalidParameters);
allParams.push(...response.Parameters);
}
if (response.InvalidParameters) {
allInvalidParams.push(...response.InvalidParameters);
}
}
if (allInvalidParams.length > 0) {
console.error('Invalid SSM parameters', allInvalidParams);
process.exit(1); process.exit(1);
} }
const params = allParams; const params = response.Parameters ?? [];
return Object.fromEntries( return Object.fromEntries(
Object.entries(env).map(([key, value]) => { Object.entries(env).map(([key, value]) => {

View File

@@ -10,7 +10,6 @@
"resolveJsonModule": true, "resolveJsonModule": true,
"allowSyntheticDefaultImports": true, "allowSyntheticDefaultImports": true,
"skipLibCheck": true, "skipLibCheck": true,
"noEmit": true,
"outDir": "dist", "outDir": "dist",
"jsx": "react-jsx", "jsx": "react-jsx",
"isolatedModules": true, "isolatedModules": true,