Skip to content

feat: integrate Zod schemas for opt-in runtime validation#126

Merged
benminer merged 4 commits intomainfrom
feat/schema-integration
Mar 24, 2026
Merged

feat: integrate Zod schemas for opt-in runtime validation#126
benminer merged 4 commits intomainfrom
feat/schema-integration

Conversation

@benminer
Copy link
Copy Markdown
Collaborator

@benminer benminer commented Mar 20, 2026

Wires the auto-generated Zod schemas (from #124) into the SDK's resource layer for runtime validation.

Usage

Validation is enabled by default. No config changes needed — all SDK methods that have matching schemas will validate inputs and responses automatically.

// Validation is on by default
const client = new Scope3Client({ apiKey: 'sk_xxx', persona: 'buyer' });

// Opt out if needed
const client = new Scope3Client({
  apiKey: 'sk_xxx',
  persona: 'buyer',
  validate: false,        // disable all validation
  // validate: 'input'    // validate request bodies only
  // validate: 'response' // validate API responses only
});

When enabled, invalid inputs throw Scope3ApiError(400) and unexpected API response shapes throw Scope3ApiError(502) with structured Zod validation details.

Changes

  • src/validation.ts — Validation utility (validateInput, validateResponse, mode helpers)
  • src/schemas/registry.ts — Hand-maintained mapping from resource operations to auto-generated Zod schemas
  • src/types/index.ts — Add validate option to Scope3ClientConfig
  • src/adapters/base.ts — Add validate to BaseAdapter interface
  • src/adapters/rest.ts, src/adapters/mcp.ts — Thread validate config through adapters (default: true)
  • Resource files — Wire validation into campaigns, reporting, sales-agents, and products; validated data is used (not discarded) so Zod defaults/transforms apply
  • Tests — 14 new validation tests, all 239 tests pass

Design Decisions

  • Validation on by default — schemas are generated from the OpenAPI spec and represent the correct API contract. Consumers who hit issues can opt out.
  • Validate at the resource layer, not the adapter — each method knows its schemas
  • Keep hand-written types as the public API surface; schemas are runtime guards only
  • Schema registry bridges auto-generated schemas to SDK methods without modifying generated code
  • Validated data is used — return values from validateInput/validateResponse are sent to the API / returned to consumers, so Zod defaults and transforms are applied
  • Bundles resource has no validation yet — schemas have diverged significantly from SDK types (advertiserId: number vs string, discoveryId vs bundleId)

Add opt-in runtime validation using auto-generated Zod schemas from
the OpenAPI spec. Validation is controlled via a new 'validate' option
on Scope3ClientConfig:

  - false/undefined (default): no validation, zero overhead
  - true: validate both inputs and responses
  - 'input': validate request bodies only
  - 'response': validate API responses only

Changes:
- Add ValidateMode type and validation utilities (src/validation.ts)
- Add schema registry mapping operations to Zod schemas (src/schemas/registry.ts)
- Thread validate config through BaseAdapter interface to resources
- Wire response validation into campaigns, reporting, sales-agents,
  bundles, and products resources
- Wire input validation into sales-agents, bundles, and products
- Add validation unit tests (14 new tests)
- Export validateInput/validateResponse for consumer use

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@benminer benminer requested a review from a team March 20, 2026 18:37
Change validate config default from undefined (off) to true. The
schemas are generated from the OpenAPI spec and represent the correct
API contract - validation should be on by default. Consumers can
opt out with validate: false.
- Use return value from validateInput/validateResponse instead of
  discarding it, so Zod defaults and transforms are applied
- Remove validation from bundles resource: schemas have diverged
  significantly (advertiserId: number vs string, discoveryId vs bundleId)
- Remove input validation from bundles.create() which used the wrong
  schema (DiscoverProductsBody instead of a bundle creation schema)
- Keep reporting validateResponse as check-only (generic T prevents
  reassignment)
Copy link
Copy Markdown
Collaborator

@nastassiafulconis nastassiafulconis left a comment

Choose a reason for hiding this comment

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

nice!

@benminer benminer merged commit cae0893 into main Mar 24, 2026
6 checks passed
@benminer benminer deleted the feat/schema-integration branch March 24, 2026 15:48
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