Skip to content

feat: add remote Hyphen ENV loading - #151

Merged
osbornm merged 2 commits into
mainfrom
feat/remote-env-loading
Aug 27, 2026
Merged

feat: add remote Hyphen ENV loading#151
osbornm merged 2 commits into
mainfrom
feat/remote-env-loading

Conversation

@osbornm

@osbornm osbornm commented Aug 27, 2026

Copy link
Copy Markdown
Member

Summary

  • add an authenticated Env service that fetches encrypted ENV data from Horizon and keys from Vinz
  • reproduce HX AES-256-CFB compatibility, parse with Node parseEnv, and update process.env atomically
  • integrate hyphen.env, root exports, API-key propagation, and service event forwarding
  • support standard configuration variables plus Hyphen Deploy fallbacks
  • preserve the existing local env() and loadEnv() helpers

Usage

Load through Hyphen

import { Hyphen } from "@hyphen/sdk";

const hyphen = new Hyphen({
  apiKey: "private-api-key",
  env: {
    organizationId: "org_...",
    projectId: "project-id-or-alternate-id",
    applicationId: "app_...",
  },
});

const variables = await hyphen.env.load("production");

A named load fetches both the default and named ENV documents. Named values win, and remote values overwrite matching process.env entries after both documents have loaded, decrypted, and parsed successfully.

Use load options to change those defaults:

const variables = await hyphen.env.load("production", {
  includeDefault: false,
  override: false,
});

includeDefault: false fetches only the named environment. override: false preserves variables already present in process.env. The returned record still contains all fetched remote values.

Use Env directly

import { Env } from "@hyphen/sdk";

const remoteEnv = new Env({
  apiKey: "private-api-key",
  organizationId: "org_...",
  projectId: "project-id-or-alternate-id",
  applicationId: "app_...",
});

await remoteEnv.load("production");

Configure from environment variables

Options can be omitted when these variables are available:

HYPHEN_API_KEY=private-api-key
HYPHEN_ORGANIZATION_ID=org_...
HYPHEN_PROJECT_ID=project-id-or-alternate-id
HYPHEN_APPLICATION_ID=app_...
import { Hyphen } from "@hyphen/sdk";

const hyphen = new Hyphen();
await hyphen.env.load();

When running with Hyphen Deploy, the SDK also uses the automatically provided HYPHEN_PROJECT_NAME, HYPHEN_APP_NAME, and HYPHEN_APP_ENVIRONMENT variables as fallbacks. Explicit options and ID variables retain precedence, and default is used when no environment is supplied.

Bypass Vinz with an explicit decryption key

import { Env } from "@hyphen/sdk";

const remoteEnv = new Env({
  apiKey: "private-api-key",
  organizationId: "org_...",
  applicationId: "app_...",
  decryptionKey: {
    secretKeyId: 123,
    secretKey: "secret-from-your-secure-store",
  },
});

await remoteEnv.load("production");

Providing decryptionKey skips the Vinz request, so projectId is not required.

The synchronous local-file env() and loadEnv() helpers remain unchanged.

Testing

  • pnpm test — 295 tests passed with 100% statements, branches, functions, and lines
  • pnpm build — ESM, CJS, and type declarations built successfully

Comment thread test/env-service.test.ts
Comment thread test/env-service.test.ts
Comment thread src/env-service.ts Fixed
@codecov

codecov Bot commented Aug 27, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 100.00%. Comparing base (942aa4d) to head (b8c845a).

Additional details and impacted files
@@            Coverage Diff             @@
##              main      #151    +/-   ##
==========================================
  Coverage   100.00%   100.00%            
==========================================
  Files            8         9     +1     
  Lines          492       639   +147     
  Branches       105       146    +41     
==========================================
+ Hits           492       639   +147     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces the Env service to securely fetch, decrypt, and load environment variables from Hyphen into process.env, along with corresponding documentation, integration into the main Hyphen class, and comprehensive unit tests. The review feedback highlights a critical compatibility issue: importing parseEnv directly from node:util will cause runtime crashes on Node.js versions prior to v20.12.0 (such as Node.js 18). To resolve this, it is recommended to import the util namespace dynamically and implement a lightweight fallback parser for older Node.js environments.

Comment thread src/env-service.ts
Comment thread src/env-service.ts
Comment thread src/env-service.ts
@osbornm
osbornm requested a review from jaredwray August 27, 2026 14:52
@osbornm
osbornm merged commit 17be7d6 into main Aug 27, 2026
9 checks passed
@osbornm
osbornm deleted the feat/remote-env-loading branch August 27, 2026 19:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants