feat(sdk-node): add Node.js SDK - #170
Merged
Merged
Conversation
Domain types (ISecretProvider, MapFileConfig, EnvilderOptions, ParsedMapFile, SecretProviderType), application layer (Envilder facade, EnvilderClient, MapFileParser, validateSecrets), and infrastructure (AwsSsmSecretProvider, AzureKeyVaultSecretProvider, createSecretProvider factory). Async-first API with fluent builder pattern. Supports AWS SSM Parameter Store and Azure Key Vault. Published as @envilder/sdk.
46 tests covering MapFileParser (6), EnvilderClient (5), SecretValidation (5), AwsSsmSecretProvider (5), AzureKeyVaultSecretProvider (5), SecretProviderFactory (7), and Envilder facade (13) with environment routing and fluent builder. Vitest with vi.fn() mocks at port boundaries.
- Add TypeScript SDK to landing page (available status with code example and npm package link) - Add #sdk-typescript docs section with install, quick start, resolve, fluent builder, env routing, and validation examples - Add i18n translations for TypeScript SDK (en, ca, es) - Add changelog infrastructure (sdk-typescript.md, astro config, env.d.ts type declaration) - Move TypeScript SDK from Up Next to Shipped in ROADMAP.md - Add TypeScript SDK section to copilot-instructions.md
Set root to repo root and use relative include patterns so v8 coverage provider can instrument SDK source files. Also fix the resolve alias path (was 2 levels up, needed 3).
Replace !x || !x.trim() with !x?.trim() in 7 locations across facade, validation, providers, and factory modules.
Split all // Act & Assert combined comments into separate // Act and // Assert phases. Rewrite try/catch test to use expect().toThrow(). Add missing Should_ResolveFromMappedFile_When_EnvMappingProvided test for resolveFile with environment routing.
Add test-typescript-sdk job that runs vitest with v8 coverage and generates lcov report. Wire into publish-report needs array, failure check, and coverage-config.json gate (80% line threshold).
Add tests-typescript-sdk.yml: biome check, build, vitest run with junit reporter, and dorny/test-reporter for PR annotations. Add publish-npm-sdk.yml: version bump detection against npm registry, lint + build + test gate, pnpm publish, git tag, GitHub Release.
Replace NPM_TOKEN secret with npm publish --provenance to match the CLI publish workflow. OIDC is already configured via id-token permission and registry-url in setup-node.
Change pre-push biome-format from read-only 'pnpm format' to 'pnpm format:write' so formatting issues are fixed automatically instead of blocking the push.
The format:write in pre-push creates an infinite loop: it modifies files without committing, so the next push triggers the same fix. Pre-push must be read-only. Auto-fix belongs in pre-commit only.
vitest root is set to repo root in vitest.config.ts, so relative outputFile paths resolve from there. Use github.workspace to write test-results.xml at the repo root where dorny/test-reporter can find it.
coverage-v8 resolves reportsDirectory relative to cwd, not vitest root. Use github.workspace to write to a known absolute path.
Replace single-secret getSecret(name) with batch getSecrets(names[]) returning Map<string, string>. Missing secrets are silently omitted. - AWS SSM: uses GetParametersCommand with batches of 10 - Azure KV: fetches in parallel via Promise.all - EnvilderClient: single getSecrets() call instead of sequential loop - Tests updated with 4 new cases (batch, empty, omit, parallel)
Chain biome format --write after biome check --write in the pre-commit hook so formatting is always applied before commit. Prevents pre-push format check from rejecting already committed code.
Use plain npm install + npm run for examples. No pnpm-workspace.yaml needed — npm resolves @envilder/sdk from the registry independently.
…tion Trim and convert empty/whitespace-only strings to undefined before cross-provider validation checks and provider construction.
The options object is intentionally mutated by withProvider/withVaultUrl/ withProfile. Removing readonly to reflect actual usage.
Contributor
There was a problem hiding this comment.
🧹 Nitpick comments (1)
examples/sdk/nodejs/2_env_routing.ts (1)
13-15: ⚡ Quick winPrefer masked output in examples instead of raw secret values.
Printing raw values (
${value}) can leak secrets into terminal history and CI logs when users copy this sample.♻️ Suggested patch
for (const [key, value] of secrets) { - console.log(`${key} = ${value}`); + const masked = value.length > 3 ? `***${value.slice(-3)}` : '***'; + console.log(`${key} = ${masked}`); }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@examples/sdk/nodejs/2_env_routing.ts` around lines 13 - 15, The example currently logs raw secret values in the for loop iterating over secrets (for (const [key, value] of secrets) { ... }) which can leak sensitive data; change the console output to mask or redact the value (e.g., log `${key} = ****` or show only last4 chars) instead of printing `${value}` so examples never emit full secret values to terminal or CI logs.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@examples/sdk/nodejs/2_env_routing.ts`:
- Around line 13-15: The example currently logs raw secret values in the for
loop iterating over secrets (for (const [key, value] of secrets) { ... }) which
can leak sensitive data; change the console output to mask or redact the value
(e.g., log `${key} = ****` or show only last4 chars) instead of printing
`${value}` so examples never emit full secret values to terminal or CI logs.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 5f4a482b-b3e4-4a3d-b640-d2aa70c4bf4e
⛔ Files ignored due to path filters (2)
.github/workflows/coverage-report/extract-test-stats.mjsis excluded by none and included by noneexamples/sdk/nodejs/package-lock.jsonis excluded by!**/package-lock.json,!**/package-lock.jsonand included byexamples/**
📒 Files selected for processing (10)
examples/sdk/nodejs/1_fluent.tsexamples/sdk/nodejs/2_env_routing.tsexamples/sdk/nodejs/3_validation.tsexamples/sdk/nodejs/4_load.tsexamples/sdk/nodejs/5_resolve.tsexamples/sdk/nodejs/README.mdexamples/sdk/nodejs/package.jsonsrc/sdks/nodejs/package.jsonsrc/sdks/nodejs/src/application/envilder.tssrc/sdks/nodejs/src/infrastructure/secret-provider-factory.ts
✅ Files skipped from review due to trivial changes (5)
- examples/sdk/nodejs/4_load.ts
- examples/sdk/nodejs/5_resolve.ts
- examples/sdk/nodejs/README.md
- src/sdks/nodejs/package.json
- examples/sdk/nodejs/package.json
Ensures the workspace-locked Biome version is used, avoiding potential version mismatches from npx resolution.
This was referenced May 2, 2026
This was referenced May 31, 2026
4 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Add the Node.js SDK (
@envilder/sdk) — an independent, async-first runtime library that loads secrets from AWS SSM Parameter Store or Azure Key Vault directly intoprocess.env. No.envfiles, no intermediaries. Works with both JavaScript and TypeScript projects.Changes
SDK Source (
src/sdks/nodejs/)ISecretProviderinterface (batchgetSecrets),MapFileConfig,EnvilderOptions,ParsedMapFile,SecretProviderTypeenumEnvilderasync facade (load,resolveFile,fromMapFile+ env-routing overloads),EnvilderClientcore resolver,MapFileParser,validateSecretsopt-in validationAwsSsmSecretProvider(batchGetParametersCommand),AzureKeyVaultSecretProvider,createSecretProviderfactory (internal)Tests (
tests/sdks/nodejs/)Should_<Expected>_When_<Condition>naming, AAA patternCI & Workflows
tests-nodejs-sdk.yml— runs all tests (unit + acceptance) on every PR and push to mainpublish-npm-sdk.yml— publishes to npm with OIDC provenance onsdk-nodejs/v*tagscoverage-report.yml— Node.js SDK coverage section addedWebsite & Docs
Supporting
pnpm-workspace.yamlanddependabot.ymlupdatedTesting
pnpm buildpasses (SDK)typescript-sdkreferences in codebaseSummary by CodeRabbit