Skip to content

feat(core-backend): spike OpenAPI→superstruct codegen for the Price API (ADR spike plan)#9446

Draft
Prithpal-Sooriya wants to merge 5 commits into
mainfrom
cursor/kubb-superstruct-spike-a32e
Draft

feat(core-backend): spike OpenAPI→superstruct codegen for the Price API (ADR spike plan)#9446
Prithpal-Sooriya wants to merge 5 commits into
mainfrom
cursor/kubb-superstruct-spike-a32e

Conversation

@Prithpal-Sooriya

@Prithpal-Sooriya Prithpal-Sooriya commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Explanation

Executes the spike plan from the "Generate Runtime Schema Validation and Mocks from OpenAPI Specs" ADR (MetaMask/decisions#234), prototyping Option A: Kubb + custom @metamask/kubb-plugin-superstruct against the Price API — plus two DX extras generated from the same pipeline (MSW handlers and query-core bindings, see below).

Spike plan → status

ADR spike step Status
1. Vendor the Price API spec, set up kubb.config.ts with plugin-oas + plugin-ts + plugin-faker Done — specs/price-api.json (see spec-quality finding below), config in codegen/kubb.config.ts
2. Prototype the superstruct generator (fork plugin-zod's parser/generator shape) Done — codegen/kubb-plugin-superstruct/
3. Wire generated structs into PricesApiClient's response path behind assert() Done — see below
4. Generate Faker mock data; replace a hand-written e2e fixture Mock data generated + exported via @metamask/core-backend/mocks; swapping an extension e2e fixture is the follow-up (different repo)
5. Report: effort actuals, spec-quality issues, bundle delta, A-vs-B recommendation See Findings below

1. The custom superstruct plugin (Option A)

packages/core-backend/codegen/kubb-plugin-superstruct/ is a full Kubb v4 plugin (built with definePlugin from @kubb/core, modeled on @kubb/plugin-zod):

  • parser.ts converts Kubb's keyword-based schema tree into superstruct expressions (type(), object() for additionalProperties: false, record(), enums(), tuple(), union(), intersection(), optional()/nullable()/defaulted(), min/max/pattern refinements, direct struct references for $refs).
  • generators/superstructGenerator.ts emits one file per component schema and one per operation, named <PascalCase>Struct per repo convention.
  • Per the ADR's "strict on shape, tolerant on additions" constraint: loose type() structs are the default; strict object() only when the spec says additionalProperties: false.
// src/generated/price-api/structs/coinGeckoSpotPriceStruct.ts
export const CoinGeckoSpotPriceStruct = type({
  id: string(),
  price: number(),
  marketCap: optional(number()),
  // ...
});

2. Structs wired into PricesApiClient (spike step 3 — the crash-prevention payoff)

The existing hand-written client now validates responses behind assert() for every endpoint covered by the vendored spec (supported networks, exchange rates ×3, v1/v2/v3 spot prices, v1 single-token + v3 historical prices). Malformed responses reject with a StructError at the fetch boundary — callers degrade gracefully instead of the wallet crashing on null.toLowerCase() later; benign additive backend changes still pass.

Notably, validation immediately caught a drifted test fixture: a fetchV1SpotPriceByCoinId test mocked { ethereum: { usd: 2500 } }, a shape the endpoint never returns — exactly the drift class the ADR describes.

3. Pinned spec snapshot + regeneration check (ADR constraints)

  • specs/price-api.json is the vendored snapshot; generation always runs offline (yarn codegen, also run by the package build scripts). Runs are deterministic (byte-identical output).
  • yarn codegen:check verifies regeneration is clean against the committed output — ready to wire into CI; the spec-vs-live docs-json diffing job is follow-up infra.
  • Generated output is committed under src/generated/price-api/ (ESLint-ignored, excluded from coverage).

4. Mocks + MSW, importable as @metamask/core-backend/mocks

  • mocks/ — seeded faker builders (createCoinGeckoSpotPrice(), ...) — the ADR's e2e-fixture feed (mockttp-compatible: mockServer.forGet(...).thenJson(200, createV3SpotPrices())).
  • msw/DX extra beyond the ADR's minimum ("not required", but free from the same pipeline): MSW request handlers serving the seeded mocks (getV3SpotPricesHandler(), aggregate handlers) for unit/integration tests in repos that use MSW.
  • msw and @faker-js/faker are optional peer dependencies, so runtime entry points stay free of test-only dependencies.

5. Query-core bindings — a working preview of the ADR's "Later" item

codegen/kubb-plugin-query-core/ generates, per operation, a query key factory, a query options factory, and a fetch* function whose queryFn validates with the generated struct — mirroring the hand-written getV3SpotPricesQueryOptions / fetchV3SpotPrices naming and consuming an injectable ApiRequestClient contract implemented by PricesApiRequestClient extends BaseApiClient. The ADR marks typed request functions/queryOptions as "Later"; this demonstrates the follow-up is mechanical once validation lands. (No @tanstack/react-query hooks are generated, per the ADR's hard "No".)

Everything is importable from @metamask/core-backend/price-api (types + structs + query bindings).

Findings (spike step 5)

  • Spec quality (biggest finding): the live Price API docs-json declares response DTOs for only 4 of ~27 endpoints. specs/price-api.json is therefore a curated snapshot enriched with response schemas matching the shapes the hand-written client already documents. Generation is only as good as the spec — upstream response-decorator coverage in the APIs is a prerequisite for rolling this out.
  • Generator effort (Option A): the plugin is a bounded artifact as the ADR predicted — a ~350-line parser plus a generator. The Price API needed: records (additionalProperties), nullable record values, tuples (prefixItems), enums, $ref graphs, defaults. Not yet exercised: discriminators, allOf merging, recursive $refs (kubb's plugin-oas normalizes most of this before the parser sees it).
  • Bundle impact: zero new runtime dependencies — structs import @metamask/superstruct, already a dependency; @tanstack/query-core was already a dependency. All codegen tooling is dev-only.
  • Recommendation evidence for A vs B: the superstruct emitter was a small, mostly mechanical mapping from the zod plugin's structure; kubb's plugin-oas did the heavy OpenAPI lifting. Nothing surfaced that would force adopting Zod (Option B).
  • Toolchain frictions (recorded): @faker-js/faker pinned to v9 (v10 is ESM-only, incompatible with the CJS build); msw pinned to ~2.10.5 (≥2.11 depends on ESM-only rettime, which Jest's CJS runtime can't load; peer range stays ^2.0.0); @kubb/plugin-faker emits {} for additionalProperties-only record schemas (can be papered over with transformers.schema later); MSW handlers need a small post-processing step for portable HttpHandler type annotations (codegen/annotate-msw-handlers.mjs).
  • Productionizing: move codegen/kubb-plugin-superstruct into its own workspace package (the ADR's @metamask/kubb-plugin-superstruct) or upstream to kubb-labs/plugins; kept in-package here for reviewability.

Tests

  • src/api/prices/client.test.ts — response-validation cases through the real PricesApiClient: malformed responses reject with precise StructErrors, additive fields pass, and generated mock data served as a response round-trips (mocks and structs share a source, so fixtures can't drift).
  • src/api/prices/query-client.test.ts — the generated pipeline end-to-end: faker mocks validate against structs; generated query bindings fetch through the generated MSW handlers with validation on the way out (failure, path-param interpolation, handler override, and QueryClient dedup cases).

Supply chain notes (Socket Security triage)

The Socket check needs a human sign-off; the alerts all come from transitive packages of two intentional dev-only additions and cannot be reduced further in code (dropping @kubb/cli already removed its alerts — codegen calls safeBuild from @kubb/core directly via codegen/run.ts).

Mitigations that apply to everything below:

  • All flagged packages are devDependencies (or optional test-only peers) — none are in the published runtime dependency tree or compiled into dist/.
  • Install scripts (es5-ext, msw postinstall) never execute in this repo: .yarnrc.yml sets enableScripts: false and yarn allow-scripts auto reports no allowlist changes needed.
  • Codegen runs offline against the vendored specs/price-api.json, so the OpenAPI toolchain's remote-$ref/URL-fetching code paths are never exercised.

Via @kubb/oas (kubb's OpenAPI parser — intrinsic to kubb, effectively part of the Option A/B decision): es5-ext (protestware console notice; postinstall inert here), es6-promise (minified bundle flagged as "obfuscated"), @apidevtools/json-schema-ref-parser / @redocly/openapi-core / oas-normalize / oas-resolver / swagger2openapi / http2-client / node-fetch-h2 (network-access alerts from remote-spec-fetching support we don't use), @redocly/ajv / mustache (AI anomaly heuristics), @readme/openapi-schemas / compute-gcd (publisher changed).

Via msw (test-only): msw postinstall (inert), @mswjs/interceptors (AI anomaly — request interception is msw's documented purpose), @bundled-es-modules/cookie / mute-stream (publisher changed).

Ready-to-paste triage comment for a reviewer who has verified the notes above (per internal guidelines this sign-off is a human decision, so it is intentionally not posted by the agent):

@SocketSecurity ignore npm/es5-ext@0.10.64
@SocketSecurity ignore npm/es6-promise@3.3.1
@SocketSecurity ignore npm/@apidevtools/json-schema-ref-parser@14.2.1
@SocketSecurity ignore npm/@redocly/openapi-core@2.37.0
@SocketSecurity ignore npm/@redocly/ajv@8.18.3
@SocketSecurity ignore npm/http2-client@1.3.5
@SocketSecurity ignore npm/node-fetch-h2@2.3.0
@SocketSecurity ignore npm/oas-normalize@16.1.1
@SocketSecurity ignore npm/oas-resolver@2.5.6
@SocketSecurity ignore npm/swagger2openapi@7.0.8
@SocketSecurity ignore npm/@readme/openapi-schemas@3.1.0
@SocketSecurity ignore npm/compute-gcd@1.2.1
@SocketSecurity ignore npm/mustache@4.2.0
@SocketSecurity ignore npm/msw@2.10.5
@SocketSecurity ignore npm/@mswjs/interceptors@0.39.8
@SocketSecurity ignore npm/@bundled-es-modules/cookie@2.0.1
@SocketSecurity ignore npm/mute-stream@2.0.0

Dev-only codegen (@kubb/oas transitive deps; offline against a vendored spec snapshot, install scripts disabled by enableScripts: false) and test-only msw tree (optional peer). Nothing ships in dist/ or the runtime dependency tree. See "Supply chain notes" in the PR description for per-package details.

References

Checklist

  • I've updated the test suite for new or updated code as appropriate
  • I've updated documentation (JSDoc, Markdown, etc.) for new or updated code as appropriate
  • I've communicated my changes to consumers by updating changelogs for packages I've changed
  • I've introduced breaking changes in this PR and have prepared draft pull requests for clients and consumer packages to resolve them
Open in Web Open in Cursor 

cursoragent and others added 2 commits July 9, 2026 12:06
…lugin

Adds a Kubb-based code generation pipeline to @metamask/core-backend,
spiked against the Price API:

- codegen/kubb-plugin-superstruct: a Kubb plugin that generates
  @metamask/superstruct structs from an OpenAPI document
- codegen/kubb-plugin-query-core: a Kubb plugin that generates TanStack
  query-core bindings (query keys, query options, fetchers) that validate
  responses with the generated structs
- codegen/openapi/price-api.json: curated Price API OpenAPI 3.1 document
  enriched with response schemas
- src/generated/price-api: generated types (plugin-ts), structs, faker
  mocks (plugin-faker), MSW handlers (plugin-msw) and query bindings
- new subpath exports: @metamask/core-backend/price-api and
  @metamask/core-backend/mocks
- yarn codegen script wired into the package build step

Co-authored-by: Prithpal Sooriya <prithpal.sooriya@gmail.com>
…stic formatted codegen

- Pin msw to ~2.10.5 (2.11+ depends on ESM-only rettime, breaking Jest CJS)
  and @faker-js/faker to ^9 (v10 is ESM-only)
- Add HttpHandler annotations to generated MSW handlers (fixes TS2742
  declaration emit)
- Format generated output with oxfmt as part of yarn codegen
- Register the core-backend build script variant in yarn constraints
- Fix ESLint violations in the codegen plugins and tests

Co-authored-by: Prithpal Sooriya <prithpal.sooriya@gmail.com>
@socket-security

socket-security Bot commented Jul 9, 2026

Copy link
Copy Markdown

@socket-security

socket-security Bot commented Jul 9, 2026

Copy link
Copy Markdown

Caution

MetaMask internal reviewing guidelines:

  • Do not ignore-all
  • Each alert has instructions on how to review if you don't know what it means. If lost, ask your Security Liaison or the supply-chain group
  • Copy-paste ignore lines for specific packages or a group of one kind with a note on what research you did to deem it safe.
    @SocketSecurity ignore npm/PACKAGE@VERSION
Action Severity Alert  (click "▶" to expand/collapse)
Block High
Protestware or unwanted behavior: npm es5-ext

Note: The script attempts to run a local post-install script, which could potentially contain malicious code. The error handling suggests that it is designed to fail silently, which is a common tactic in malicious scripts.

From: ?npm/@kubb/oas@4.39.2npm/es5-ext@0.10.64

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

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: Consider that consuming this package may come along with functionality unrelated to its primary purpose.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore npm/es5-ext@0.10.64. 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.

Block High
Obfuscated code: npm es6-promise is 90.0% likely obfuscated

Confidence: 0.90

Location: Package overview

From: ?npm/@kubb/oas@4.39.2npm/es6-promise@3.3.1

ℹ 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/es6-promise@3.3.1. 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.

Block Medium
Network access: npm @apidevtools/json-schema-ref-parser in module globalThis["fetch"]

Module: globalThis["fetch"]

Location: Package overview

From: ?npm/@kubb/oas@4.39.2npm/@apidevtools/json-schema-ref-parser@14.2.1

ℹ Read more on: This package | This alert | What is network access?

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 remove all network access that is functionally unnecessary. Consumers should audit network access to ensure legitimate use.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore npm/@apidevtools/json-schema-ref-parser@14.2.1. 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.

Block Medium
Network access: npm @redocly/openapi-core in module globalThis["fetch"]

Module: globalThis["fetch"]

Location: Package overview

From: ?npm/@kubb/oas@4.39.2npm/@redocly/openapi-core@2.37.0

ℹ Read more on: This package | This alert | What is network access?

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 remove all network access that is functionally unnecessary. Consumers should audit network access to ensure legitimate use.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore npm/@redocly/openapi-core@2.37.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.

Block Medium
Network access: npm http2-client in module http

Module: http

Location: Package overview

From: ?npm/@kubb/oas@4.39.2npm/http2-client@1.3.5

ℹ Read more on: This package | This alert | What is network access?

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 remove all network access that is functionally unnecessary. Consumers should audit network access to ensure legitimate use.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore npm/http2-client@1.3.5. 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.

Block Medium
Network access: npm http2-client in module https

Module: https

Location: Package overview

From: ?npm/@kubb/oas@4.39.2npm/http2-client@1.3.5

ℹ Read more on: This package | This alert | What is network access?

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 remove all network access that is functionally unnecessary. Consumers should audit network access to ensure legitimate use.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore npm/http2-client@1.3.5. 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.

Block Medium
Network access: npm http2-client in module tls

Module: tls

Location: Package overview

From: ?npm/@kubb/oas@4.39.2npm/http2-client@1.3.5

ℹ Read more on: This package | This alert | What is network access?

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 remove all network access that is functionally unnecessary. Consumers should audit network access to ensure legitimate use.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore npm/http2-client@1.3.5. 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.

Block Medium
Network access: npm http2-client in module net

Module: net

Location: Package overview

From: ?npm/@kubb/oas@4.39.2npm/http2-client@1.3.5

ℹ Read more on: This package | This alert | What is network access?

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 remove all network access that is functionally unnecessary. Consumers should audit network access to ensure legitimate use.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore npm/http2-client@1.3.5. 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.

Block Medium
Network access: npm http2-client in module http2

Module: http2

Location: Package overview

From: ?npm/@kubb/oas@4.39.2npm/http2-client@1.3.5

ℹ Read more on: This package | This alert | What is network access?

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 remove all network access that is functionally unnecessary. Consumers should audit network access to ensure legitimate use.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore npm/http2-client@1.3.5. 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.

Block Medium
Network access: npm node-fetch-h2 in module http

Module: http

Location: Package overview

From: ?npm/@kubb/oas@4.39.2npm/node-fetch-h2@2.3.0

ℹ Read more on: This package | This alert | What is network access?

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 remove all network access that is functionally unnecessary. Consumers should audit network access to ensure legitimate use.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore npm/node-fetch-h2@2.3.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.

Block Medium
Network access: npm node-fetch-h2 in module http2-client

Module: http2-client

Location: Package overview

From: ?npm/@kubb/oas@4.39.2npm/node-fetch-h2@2.3.0

ℹ Read more on: This package | This alert | What is network access?

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 remove all network access that is functionally unnecessary. Consumers should audit network access to ensure legitimate use.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore npm/node-fetch-h2@2.3.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.

Block Medium
Network access: npm node-fetch-h2 in module globalThis["fetch"]

Module: globalThis["fetch"]

Location: Package overview

From: ?npm/@kubb/oas@4.39.2npm/node-fetch-h2@2.3.0

ℹ Read more on: This package | This alert | What is network access?

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 remove all network access that is functionally unnecessary. Consumers should audit network access to ensure legitimate use.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore npm/node-fetch-h2@2.3.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.

Block Medium
Network access: npm oas-normalize in module globalThis["fetch"]

Module: globalThis["fetch"]

Location: Package overview

From: ?npm/@kubb/oas@4.39.2npm/oas-normalize@16.1.1

ℹ Read more on: This package | This alert | What is network access?

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 remove all network access that is functionally unnecessary. Consumers should audit network access to ensure legitimate use.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore npm/oas-normalize@16.1.1. 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.

Block Medium
Network access: npm oas-resolver in module globalThis["fetch"]

Module: globalThis["fetch"]

Location: Package overview

From: ?npm/@kubb/oas@4.39.2npm/oas-resolver@2.5.6

ℹ Read more on: This package | This alert | What is network access?

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 remove all network access that is functionally unnecessary. Consumers should audit network access to ensure legitimate use.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore npm/oas-resolver@2.5.6. 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.

Block Medium
Network access: npm swagger2openapi in module globalThis["fetch"]

Module: globalThis["fetch"]

Location: Package overview

From: ?npm/@kubb/oas@4.39.2npm/swagger2openapi@7.0.8

ℹ Read more on: This package | This alert | What is network access?

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 remove all network access that is functionally unnecessary. Consumers should audit network access to ensure legitimate use.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore npm/swagger2openapi@7.0.8. 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.

Block Medium
Network access: npm swagger2openapi in module http

Module: http

Location: Package overview

From: ?npm/@kubb/oas@4.39.2npm/swagger2openapi@7.0.8

ℹ Read more on: This package | This alert | What is network access?

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 remove all network access that is functionally unnecessary. Consumers should audit network access to ensure legitimate use.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore npm/swagger2openapi@7.0.8. 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.

Block Low
Publisher changed: npm @bundled-es-modules/cookie is now published by bashmish instead of passle

New Author: bashmish

Previous Author: passle

From: ?npm/msw@2.10.5npm/@bundled-es-modules/cookie@2.0.1

ℹ Read more on: This package | This alert | What is new author?

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: Scrutinize new collaborator additions to packages because they now have the ability to publish code into your dependency tree. Packages should avoid frequent or unnecessary additions or changes to publishing rights.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore npm/@bundled-es-modules/cookie@2.0.1. 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.

Block Low
Publisher changed: npm @readme/openapi-schemas is now published by darrenyong instead of jonursenbach

New Author: darrenyong

Previous Author: jonursenbach

From: ?npm/@kubb/oas@4.39.2npm/@readme/openapi-schemas@3.1.0

ℹ Read more on: This package | This alert | What is new author?

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: Scrutinize new collaborator additions to packages because they now have the ability to publish code into your dependency tree. Packages should avoid frequent or unnecessary additions or changes to publishing rights.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore npm/@readme/openapi-schemas@3.1.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.

Block Low
Publisher changed: npm compute-gcd is now published by planeshifter instead of kgryte

New Author: planeshifter

Previous Author: kgryte

From: ?npm/@kubb/oas@4.39.2npm/compute-gcd@1.2.1

ℹ Read more on: This package | This alert | What is new author?

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: Scrutinize new collaborator additions to packages because they now have the ability to publish code into your dependency tree. Packages should avoid frequent or unnecessary additions or changes to publishing rights.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore npm/compute-gcd@1.2.1. 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.

Block Low
Publisher changed: npm mute-stream is now published by npm-cli-ops instead of lukekarrys

New Author: npm-cli-ops

Previous Author: lukekarrys

From: ?npm/msw@2.10.5npm/mute-stream@2.0.0

ℹ Read more on: This package | This alert | What is new author?

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: Scrutinize new collaborator additions to packages because they now have the ability to publish code into your dependency tree. Packages should avoid frequent or unnecessary additions or changes to publishing rights.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore npm/mute-stream@2.0.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.

Warn Medium
Install-time scripts: npm es5-ext during postinstall

Install script: postinstall

Source: node -e "try{require('./_postinstall')}catch(e){}" || exit 0

From: ?npm/@kubb/oas@4.39.2npm/es5-ext@0.10.64

ℹ Read more on: This package | This alert | What is an install script?

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 be running non-essential scripts during install and there are often solutions to problems people solve with install scripts that can be run at publish time instead.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore npm/es5-ext@0.10.64. 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 Medium
Install-time scripts: npm msw during postinstall

Install script: postinstall

Source: node -e "import('./config/scripts/postinstall.js').catch(() => void 0)"

From: packages/core-backend/package.jsonnpm/msw@2.10.5

ℹ Read more on: This package | This alert | What is an install script?

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 be running non-essential scripts during install and there are often solutions to problems people solve with install scripts that can be run at publish time instead.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore npm/msw@2.10.5. 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 Low
Potential code anomaly (AI signal): npm @mswjs/interceptors is 63.0% likely to have a medium risk anomaly

Notes: This module is a legitimate-looking WebSocket interception/instrumentation framework that globally overrides the WebSocket constructor via Proxy and emits connection objects/metadata to subscribers. In the provided fragment, there is no direct evidence of overt malware (e.g., credential theft, reverse shells, or explicit exfiltration). However, the high-impact global behavior modification and the forwarding of live connection objects to external listeners create a meaningful supply-chain/runtime risk: if the surrounding implementation inspects or forwards message contents, it could enable traffic observation or manipulation. Error messages are propagated into close semantics and logs, which could also leak internal details. Overall risk is moderate and depends on the unseen implementations of WebSocketOverride/WebSocketServerConnection for message-level confidentiality/integrity impacts.

Confidence: 0.63

Severity: 0.58

From: ?npm/msw@2.10.5npm/@mswjs/interceptors@0.39.8

ℹ Read more on: This package | This alert | What is an AI-detected potential code anomaly?

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: An AI system found a low-risk anomaly in this package. It may still be fine to use, but you should check that it is safe before proceeding.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore npm/@mswjs/interceptors@0.39.8. 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 Low
Potential code anomaly (AI signal): npm @redocly/ajv is 68.0% likely to have a medium risk anomaly

Notes: The code implements standard timestamp validation with clear logic for normal and leap years and leap seconds. There is no network, file, or execution of external code within this isolated fragment. The only anomalous aspect is assigning a string to validTimestamp.code, which could enable external tooling to inject behavior in certain environments, but this does not constitute active malicious behavior in this isolated snippet. Overall, low to moderate security risk in typical usage; no malware detected within the shown code.

Confidence: 0.68

Severity: 0.50

From: ?npm/@kubb/oas@4.39.2npm/@redocly/ajv@8.18.3

ℹ Read more on: This package | This alert | What is an AI-detected potential code anomaly?

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: An AI system found a low-risk anomaly in this package. It may still be fine to use, but you should check that it is safe before proceeding.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore npm/@redocly/ajv@8.18.3. 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 Low
Potential code anomaly (AI signal): npm @redocly/ajv is 70.0% likely to have a medium risk anomaly

Notes: This module generates JavaScript code at runtime via standaloneCode(...) and then immediately executes it with require-from-string. Because the generated code can incorporate user-supplied schemas or custom keywords without sanitization or sandboxing, an attacker who controls those inputs could inject arbitrary code and achieve remote code execution in the Node process. Users should audit and lock down the standaloneCode output or replace dynamic evaluation with a safer, static bundling approach.

Confidence: 0.70

Severity: 0.62

From: ?npm/@kubb/oas@4.39.2npm/@redocly/ajv@8.18.3

ℹ Read more on: This package | This alert | What is an AI-detected potential code anomaly?

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: An AI system found a low-risk anomaly in this package. It may still be fine to use, but you should check that it is safe before proceeding.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore npm/@redocly/ajv@8.18.3. 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 Low
Potential code anomaly (AI signal): npm mustache is 65.0% likely to have a medium risk anomaly

Notes: The code is a functional Mustache CLI tool, but it deliberately executes user-supplied JavaScript views by requiring a .js/.cjs file, which constitutes a significant risk in untrusted environments. This behavior creates a clear source-to-sink path from untrusted input to arbitrary code execution. In trusted pipelines this is acceptable for flexibility; in open or supply-chain contexts, it should be restricted or sandboxed. Other aspects (reading files, parsing JSON views, handling partials) are standard for such tools but do not introduce additional malicious behavior.

Confidence: 0.65

Severity: 0.62

From: ?npm/@kubb/oas@4.39.2npm/mustache@4.2.0

ℹ Read more on: This package | This alert | What is an AI-detected potential code anomaly?

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: An AI system found a low-risk anomaly in this package. It may still be fine to use, but you should check that it is safe before proceeding.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore npm/mustache@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.

See 1 more row in the dashboard

View full report

cursoragent and others added 3 commits July 9, 2026 12:27
- Export ApiRequestClient / ApiRequestArgs and PricesApiRequestClient from
  the package root
- Add changelog entries for the generated Price API bindings, mocks entry
  point and request client

Co-authored-by: Prithpal Sooriya <prithpal.sooriya@gmail.com>
… tsx

Replaces the @kubb/cli invocation with a small tsx runner
(codegen/run.ts) that imports the Kubb config directly and calls
safeBuild from @kubb/core. This removes @kubb/cli and its extra
dependency surface (config discovery, jiti config loading, subprocess
runner) from the lockfile, addressing the Socket Security alerts that
targeted @kubb/cli itself. Generated output is unchanged.

Co-authored-by: Prithpal Sooriya <prithpal.sooriya@gmail.com>
Aligns the spike with the 'Generate Runtime Schema Validation and Mocks
from OpenAPI Specs' ADR (MetaMask/decisions#234) while keeping the DX
extras (MSW handlers, query-core bindings) generated from the same
pipeline:

- Wire generated structs into the existing PricesApiClient response path
  behind assert() (ADR spike step 3): supported networks, exchange rates,
  v1/v2/v3 spot prices, v1 single-token and v3 historical prices now
  reject malformed responses with StructError; unknown additional fields
  are still tolerated. One drifted test fixture surfaced by validation
  was corrected.
- Move the vendored spec to specs/price-api.json (ADR layout) and add the
  /v1/exchange-rates/crypto endpoint so all exchange-rate methods are
  validated.
- Rename the struct output directory from schemas/ to structs/ (ADR
  naming).
- Add a codegen:check script (regeneration-is-clean check per the ADR's
  committed-output constraint).
- Add response-validation tests, including one that serves generated mock
  data through the client to prove mocks and structs stay in sync.

Co-authored-by: Prithpal Sooriya <prithpal.sooriya@gmail.com>
@cursor cursor Bot changed the title feat(core-backend): spike Kubb codegen with a @metamask/superstruct plugin (Price API) feat(core-backend): spike OpenAPI→superstruct codegen for the Price API (ADR spike plan) Jul 9, 2026
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.

2 participants