Skip to content

chore: migrate to pnpm, bump Node matrix to 22/24/26, fix audit vulns - #238

Open
Matt (matt-evervault) wants to merge 6 commits into
masterfrom
chore/migrate-to-pnpm-and-update-node
Open

chore: migrate to pnpm, bump Node matrix to 22/24/26, fix audit vulns#238
Matt (matt-evervault) wants to merge 6 commits into
masterfrom
chore/migrate-to-pnpm-and-update-node

Conversation

@matt-evervault

@matt-evervault Matt (matt-evervault) commented Jun 29, 2026

Copy link
Copy Markdown
Contributor

Summary

Migrates the repo from npm to pnpm 11.9.0, refreshes the CI Node matrix to 22 / 24 / 26, and clears all pnpm audit findings. Also adds a Nix flake for a reproducible dev toolchain.

Changes

npm → pnpm

  • Add packageManager: "pnpm@11.9.0"; replace package-lock.json with pnpm-lock.yaml.
  • All workflows now use pnpm/action-setup@v4 (before setup-node, with cache: 'pnpm') and pnpm install --frozen-lockfile.
  • Release workflow: pnpm publish --no-git-checks (the --no-git-checks replaces npm's lack of branch checks, since the publish job runs on a detached tag). The existing OIDC trusted publishing flow is preserved — pnpm 11.9.0 includes the fix from pnpm#11526 (merged 15 May 2026, before the 11.9.0 release) that drops the unresolved ${NODE_AUTH_TOKEN} placeholder and falls back to OIDC.
  • Husky hook and CONTRIBUTING.md updated to pnpm.

Nix flake

  • flake.nix / flake.lock provide a pinned Node.js + pnpm 11.9.0 dev shell (nix develop). Contributors without Nix can use Corepack (pinned via the packageManager field).

Node matrix

  • 18, 20, 2222, 24, 26. Dropped versions are all EOL (18, 20 since Mar 2026; 23, 25 also EOL). 22 & 24 are Active LTS, 26 is Current.

pnpm audit --fix

  • 0 vulnerabilities after the fix (was 1 high + 3 moderate: serialize-javascript, uuid, js-yaml).
  • Overrides consolidated into pnpm-workspace.yaml (pnpm's native location, where audit --fix writes). The old package.json overrides were removed — its js-yaml@4.1.1 pin had itself become the flagged vulnerable version; the lodash override was carried over.

Test/CI fixes required for green CI on current Node

  • Regenerated tests/utilities/ssl-cert-snakeoil.{key,pem} as a 2048-bit self-signed cert (was 1024-bit, expired Jul 2025). Modern OpenSSL rejects the 1024-bit key with ERR_SSL_EE_KEY_TOO_SMALL, which broke the HttpsProxyAgent before all hook and silently disabled ~16 tests. Suite now reports 208 passing (was 190 + 2 failing). Same CN; no test pins its identity.
  • Attestation CI step runs mocha directly instead of via pnpm run under LD_PRELOAD=libfaketime. pnpm run … hangs indefinitely when launched under libfaketime (CI log showed apt-get completing, then 30 min of silence); pnpm is a heavier Node process than the npm it replaced. Invoking ./node_modules/.bin/mocha … --grep attestGA wraps only the test process.

Verification — CI green ✅

  • Test workflow: pnpm install --frozen-lockfile, pnpm run lint, pnpm run test:coverage (208 passing) and the libfaketime attestation step all pass on Node 22, 24 and 26.
  • E2E workflow: passes on Node 22, 24 and 26.
  • ✅ Locally verified the full suite on Node 22 & 24 (208 passing), pnpm run generate-types, and pnpm audit (clean) via the flake.

Notes for reviewers

  • No consumer-facing change / no changeset. audit --fix hardened the dev tree via overrides (which don't propagate to consumers); dependencies.uuid is intentionally left at ^8.1.0. uuid is only used in e2e/ ({ v4 }, stable v8→v11), never in lib/, so consumers have no real exposure. Bumping/moving uuid to devDependencies is a reasonable separate follow-up.
  • First release on this branch should be watched to confirm the pnpm publish OIDC path (and provenance) behaves like the previous npm publish.

@changeset-bot

changeset-bot Bot commented Jun 29, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 71f3f9a

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@evervault/sdk Major

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@socket-security

socket-security Bot commented Jun 29, 2026

Copy link
Copy Markdown

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Addedproxyquire@​2.1.310010010075100
Added@​types/​async-retry@​1.4.91001009180100
Added@​types/​node@​22.20.11001008195100
Addedtsx@​4.23.01001008195100
Addedtsup@​8.5.1981009583100
Updatedmsgpackr@​1.11.12 ⏵ 1.12.1100 +1100100 +190 -3100
Updatedaxios@​1.18.0 ⏵ 1.18.198 +110010092100

View full report

@socket-security

socket-security Bot commented Jun 29, 2026

Copy link
Copy Markdown

Warning

Review the following alerts detected in dependencies.

According to your organization's Security Policy, it is recommended to resolve "Warn" alerts. Learn more about Socket for GitHub.

Action Severity Alert  (click "▶" to expand/collapse)
Warn High
License policy violation: npm caniuse-lite under CC-BY-4.0

License: CC-BY-4.0 - The applicable license policy does not permit this license (5) (npm metadata)

License: CC-BY-4.0 - The applicable license policy does not permit this license (5) (package/package.json)

License: CC-BY-4.0 - The applicable license policy does not permit this license (5) (package/LICENSE)

From: pnpm-lock.yamlnpm/nyc@17.1.0npm/caniuse-lite@1.0.30001799

ℹ Read more on: This package | This alert | What is a license policy violation?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at support@socket.dev.

Suggestion: Find a package that does not violate your license policy or adjust your policy to allow this package's license.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore npm/caniuse-lite@1.0.30001799. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

Warn High
Obfuscated code: npm js-yaml is 90.0% likely obfuscated

Confidence: 0.90

Location: Package overview

From: pnpm-lock.yamlnpm/@changesets/cli@2.31.0npm/nyc@17.1.0npm/mocha@10.8.2npm/js-yaml@4.2.0

ℹ Read more on: This package | This alert | What is obfuscated code?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at support@socket.dev.

Suggestion: Packages should not obfuscate their code. Consider not using packages with obfuscated code.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore npm/js-yaml@4.2.0. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

View full report

@matt-evervault Matt (matt-evervault) self-assigned this Jun 29, 2026
@matt-evervault
Matt (matt-evervault) requested a review from a team June 29, 2026 09:45
Comment thread .github/workflows/e2e.yml Outdated
Comment thread CONTRIBUTING.md
Comment thread package.json

@aNickPlx Bruno Rafael (aNickPlx) 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.

Approved pending removal of uuid package

Comment thread pnpm-workspace.yaml Outdated
msgpackr-extract: false
minimumReleaseAgeExclude:
- serialize-javascript@7.0.3 || 7.0.5
- uuid@11.1.1

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

remove usage of vulnerable uuid package

Matt (matt-evervault) and others added 6 commits August 20, 2026 17:01
- Migrate package manager from npm to pnpm 11.9.0: add packageManager
  field, replace package-lock.json with pnpm-lock.yaml, convert all
  workflows to pnpm/action-setup + `pnpm install --frozen-lockfile`,
  `pnpm publish --no-git-checks` (preserves OIDC trusted publishing),
  and update husky hook + CONTRIBUTING.
- Add flake.nix/flake.lock providing a pinned Node.js + pnpm 11.9.0 dev
  shell (`nix develop`).
- Update CI Node matrix from 18/20/22 to 22/24/26 (18/20/23/25 are EOL).
- `pnpm audit --fix`: 0 vulnerabilities. Overrides for js-yaml,
  serialize-javascript and uuid consolidated into pnpm-workspace.yaml
  (the stale package.json js-yaml@4.1.1 pin was itself flagged).
- Regenerate ssl-cert-snakeoil fixture as 2048-bit; the old 1024-bit key
  is rejected by modern OpenSSL (ERR_SSL_EE_KEY_TOO_SMALL), which had
  broken the HttpsProxyAgent suite on current Node (now 208 passing).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
`pnpm run test:filter attestGA` hangs indefinitely when launched under
LD_PRELOAD=libfaketime (CI log shows apt-get completing, then 30 min of
silence in the test command). pnpm is a heavier Node process than the npm
it replaced and deadlocks under faked time. Invoke the mocha binary
directly so only the test process is wrapped by libfaketime.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
* chore: remove dead code and reclassify test-only dependencies

Delete unused internal modules that were unreachable from the public API:
- lib/core/labs.js + lib/core/labs/index.js (legacy `proxy-cage` helper)
- lib/utils/dataHelper.js (imported `big.js`, which was never a declared
  dependency, and was referenced nowhere)
- lib/utils/environment.js (legacy Function env-var extraction, unused)

Move `crc-32` and `uuid` to devDependencies since they are only used by the
test suite, not by lib/. Remove the leftover EV_CAGE_RUN_URL reference from
the config test (the env var no longer exists in config).

Test baseline unchanged: 204 passing (the 5 pre-existing proxy.test.js
failures are environmental and unrelated to this change).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011HwoTRLdV2YMub47j88mv5

* feat!: convert SDK to TypeScript with a dual ESM/CJS build (#243)

* feat!: convert SDK to TypeScript with a dual ESM/CJS build

Rewrite the SDK source (lib/*.js -> lib/*.ts) in strict TypeScript,
preserving runtime behaviour and the on-the-wire encryption formats
exactly. Only module syntax and type annotations changed; the public
API is identical.

Build & packaging:
- Add tsconfig.json (strict) and build with tsup to dist/ as dual
  ESM (index.mjs) + CommonJS (index.js) with bundled .d.ts.
- Point package "main"/"module"/"types"/"exports" at dist and ship
  only dist; drop the tsc-based generate-types step.
- keepNames so error `type`/constructor names are preserved.
- require('@evervault/sdk') still returns the EvervaultClient class;
  `import Evervault from '@evervault/sdk'` works for ESM consumers.

Types & internals:
- Fold the hand-written types.d.ts / domainTargets.d.ts into source
  types; monkey-patched Node core modules use default imports so the
  mutable module.exports is patched (works in both CJS and ESM).

Tests & CI:
- Run the existing mocha suite against the TS source via tsx and
  replace rewire (incompatible with compiled TS) with proxyquire /
  shared-singleton config mutation. 204 passing, unchanged from the
  JS baseline (the 5 proxy.test.js failures are pre-existing and
  environmental).
- Add typecheck + build steps to CI; bump CodeQL to v3 with the
  javascript-typescript language.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011HwoTRLdV2YMub47j88mv5

* fix: don't clobber global https.request from non-relay clients; inject config in sdk tests

CI ran the suite against the real network and surfaced two test-infra
regressions from the TS migration that the local sandbox hid:

- EvervaultClient's constructor called `_shouldOverloadHttpModule`, whose
  else-branch unconditionally ran `https.request = originalRequest`. On every
  non-relay client this reset the global `https.request`, removing nock's
  interception (nock doesn't re-patch once "active"), which cascaded failures
  across client/http test files. Guard the restore so it only runs when this
  process actually overloaded `https.request` for Relay. This is also more
  correct: a plain client no longer disables another client's outbound Relay.

- sdk.test.js pointed the client at its mock server by mutating the config
  singleton. Under tsx the module-cache timing made that unreliable, so the
  client hit the real API. Inject the mutated config into the client with
  proxyquire (`{ './config': config }`), mirroring the old rewire `__set__`.

Local suite unchanged (204 passing; the 5 proxy.test.js failures are
environmental to this sandbox). Verified the guard preserves nock's patch and
that config injection reaches the client.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011HwoTRLdV2YMub47j88mv5

* test: run the suite against compiled CJS under plain Node instead of tsx

The nock-based tests passed locally but failed in CI only. Running the
suite through tsx (on-the-fly TS transpilation with a custom module
loader) interacted with nock/axios HTTP interception differently on the
CI runners, so requests bypassed nock and hit the network.

Compile lib/*.ts to CJS with `tsc -p tsconfig.build.json` and run mocha
against the emitted JS under plain Node — the same execution model the
JavaScript suite used before the TypeScript migration. The compiled
lib/*.js are build artifacts (git- and prettier-ignored); tsup still
builds the published dual-format bundle from the .ts sources, and
`tsc --noEmit` still type-checks.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011HwoTRLdV2YMub47j88mv5

* fix: stop mocharc spec from pulling the unit suite into the e2e run

Mocha concatenates the `spec` from `.mocharc.json` with any CLI
positional file arguments rather than letting the CLI override it. The
`test:e2e` script (run by the `e2e.yml` workflow) invokes
`mocha 'e2e/**/*.test.js'`, so once `.mocharc.json` declared
`spec: tests/**`, that job silently ran the entire unit suite alongside
the e2e tests. The e2e tests run first, call `enableOutboundRelay()`
which monkey-patches the global `https.request`, and that leaves nock
unable to intercept the unit tests — producing the CI-only failures.

Keep only `timeout` in `.mocharc.json` and pass the unit spec explicitly
on the CLI in `test` / `test:filter`, so each mocha invocation resolves
exactly one suite (matching the pre-TypeScript setup).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011HwoTRLdV2YMub47j88mv5

* feat: infer real types across the SDK, replacing any at the public API

Give consumers precise types instead of `any` on the client surface:

- encrypt<T> returns EncryptedData<T>, preserving input shape (objects keep
  their keys with encrypted string leaves, Buffers stay Buffers, primitives
  become strings) and rejecting non-encryptable inputs
- decrypt<T>, run<T> (-> FunctionRunResult<T>), createRunToken (-> RunToken)
  and createClientSideDecryptToken (-> ClientSideToken) now carry real types
- hidden ECDH fields typed as Buffer / crypto.ECDH / NodeJS.Timeout

Internally, export a reusable HttpClient type and thread it through
attestationDoc/relayOutboundConfig/httpsHelper; type the PCR store, the
attestation helpers, and the key/token/relay response shapes.

Also make Http.getAppKey throw mapResponseCodeToError on non-2xx (mirroring
getCageKey) instead of returning undefined and crashing downstream.

Genuinely dynamic/vendored surfaces (crypto key material that is Buffer|string,
the agent-base subclass, the asn1js DER encoder, the https.request/tls
monkeypatch paths) are left untyped with rationale comments.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* fix: raise e2e mocha timeout to 30s to absorb httpbin latency

The two path-filtering outbound-relay tests each make two httpbin.org
requests; the 5s timeout was too tight for slow-but-reachable httpbin,
causing intermittent timeouts. Align with the .mocharc.json default (30s).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* Format and fix

* Rename lint to format

---------

Co-authored-by: Claude <noreply@anthropic.com>

* Remove uuid dependency and cleanup changelog

---------

Co-authored-by: Claude <noreply@anthropic.com>
…JS consumers

`build:test` compiled every `lib/**/*.ts` to a `.js` sibling so mocha could
require the sources under plain Node, which meant carrying `lib/**/*.js`
ignore rules in both .gitignore and .prettierignore to hide the emitted
files. Run the suite directly against the TypeScript instead, via the tsx
loader in .mocharc.json. `tsup` remains the only thing that emits, into the
already-ignored `dist/`, so no compiled JS lands in `lib/` at all.

Also fixes a packaging regression the rewrite introduced. The runtime is
`module.exports = EvervaultClient`, but tsup's dts rollup emitted
`export { EvervaultClient as default }`, so `new Evervault(...)` failed to
type-check for consumers with TS2351 "not constructable" — the previous
`tsc`-generated `types/` correctly emitted `export = EvervaultClient`.
`cjsInterop` restores that form for the CJS declaration while leaving the
`.d.mts` as a default export, and the `exports` map now nests `types` under
each condition so ESM consumers stop resolving the CJS declaration.

Verified against a packed tarball: CJS require, ESM import, and declaration
resolution under node, node16, and bundler.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

3 participants