
Security News
AI Has Taken Over Open Source
Vibe coding at scale is reshaping how packages are created, contributed, and selected across the software supply chain
Dynamic and Adaptable Model Validator Using Zod, Interoperable with OpenAPI
adaptate is a dynamic and adaptable model validator that leverages Zod for schema validation and is interoperable with OpenAPI. Define a single optional Zod schema for your data model, then use configuration objects to declare which fields each consumer requires — at runtime.
| Package | Description |
|---|---|
@adaptate/core | Schema transformation engine — make fields required based on config |
@adaptate/utils | OpenAPI ↔ Zod conversion, YAML spec loading with $ref resolution |
pnpm add @adaptate/core
# or
npm install @adaptate/core
For OpenAPI utilities:
pnpm add @adaptate/utils
# or
npm install @adaptate/utils
Peer dependency: zod@^3.23.8 || ^4.0.0
In component-oriented applications, different components consume different subsets of the same data model. One component needs name and age, another needs address.city, and a third needs everything. The data often comes from different API endpoints with varying completeness.
Without runtime validation per consumer, you either:
Adaptate solves this: define one schema with all fields optional, then use a config object to declare what each consumer requires.
There are two common ways to create a fully optional schema:
1. Using .deepPartial() (recommended)
import { z } from 'zod';
import { transformSchema, type Config } from '@adaptate/core';
const schema = z.object({
name: z.string(),
age: z.number(),
address: z.object({
street: z.string(),
city: z.string(),
}),
}).deepPartial();
const config = {
name: true,
age: true,
address: { city: true },
} satisfies Config<z.infer<typeof schema>>;
const updatedSchema = transformSchema(schema, config);
updatedSchema.parse({ name: 'Davin', age: 30, address: { city: 'Pettit' } }); // passes
updatedSchema.parse({ name: 'Davin', age: 30, address: { street: 'Main St' } }); // throws
2. Manual .optional() (still works)
import { z } from 'zod';
import { transformSchema } from '@adaptate/core';
const schema = z.object({
name: z.string().optional(),
age: z.number().optional(),
address: z.object({
street: z.string().optional(),
city: z.string().optional(),
}).optional(),
});
// ... same config and usage as above
import { z } from 'zod';
import { makeConditionalSchemaTransformer } from '@adaptate/core';
const schema = z.object({
parentContactNumber: z.number().optional(),
age: z.number().optional(),
});
const config = {
parentContactNumber: { requiredIf: (data: any) => data.age < 18 },
age: true,
};
const data = { age: 17 };
const transformer = makeConditionalSchemaTransformer(data)(schema, config);
transformer.run(); // throws — parentContactNumber required because age < 18
Load and dereference an OpenAPI spec:
import { getDereferencedOpenAPIDocument } from '@adaptate/utils';
const doc = await getDereferencedOpenAPIDocument({
location: 'filesystem',
callSiteURL: import.meta.url,
relativePathToSpecFile: './api-spec.yml',
});
Convert OpenAPI schema to Zod:
import { openAPISchemaToZod } from '@adaptate/utils';
const zodSchema = openAPISchemaToZod({
type: 'object',
required: ['age'],
properties: {
name: { type: 'string', minLength: 2 },
age: { type: 'integer', minimum: 0 },
},
});
Convert Zod to OpenAPI schema:
import { z } from 'zod';
import { zodToOpenAPISchema } from '@adaptate/utils';
const openAPISchema = zodToOpenAPISchema(
z.object({ name: z.string().min(2), age: z.number().int() })
);
See @adaptate/utils README for full documentation.
Compact & Powerful: The core transformation logic is intentionally compact — fewer than 100 lines of code. Complex nested transformations (deep objects, arrays with wildcards, conditional requirements) are handled elegantly through recursion. This keeps the API surface small while delivering sophisticated behavior with minimal cognitive overhead.
For a deeper dive, see DESIGN.md which covers:
This is a pnpm monorepo orchestrated with Turborepo.
Package manager: Use pnpm only when working in this repository (pnpm install). This repo’s install/build safety posture is defined for pnpm (.npmrc, pnpm-workspace.yaml: lifecycle restrictions, store integrity, release-age gates, etc.). npm install at the root is unsupported — npm ignores or mishandles several of those controls and may resolve dependencies differently than CI, weakening protections against supply-chain attacks that the config is meant to mitigate. Root package.json pins packageManager. The Installation section above (pnpm add / npm install for @adaptate/*) applies to consumers installing published packages from the npm registry.
Requirements: Node.js ≥ 20, pnpm 9.12.3
pnpm install # Install dependencies
pnpm build # Full pipeline: check-types → test → build
pnpm test # Run Vitest in watch mode
npx vitest run # Single test run
npx turbo run check-types # TypeScript type checking
├── .devcontainer/ # optional Dev Container (Node 24 + pnpm)
├── packages/
│ ├── core/ # @adaptate/core — schema transformation
│ └── utils/ # @adaptate/utils — OpenAPI utilities
├── skills/ # Tool-agnostic agent SOPs
├── AGENTS.md # Agent guidelines
├── CODING_STYLE.md # Coding conventions
└── turbo.json # Turborepo task graph
See AGENTS.md and skills/ for development guidelines and operational procedures. Optional dev container: .devcontainer/README.md, .devcontainer/devcontainer.json.
This library recreates and generalizes a pattern originally observed at Oneflow AB, where the same data model was consumed by different components with varying required fields depending on context.
Development note: Initial prototype was created with ChatGPT Canvas. All important caveats and refinements were manually corrected by the author. The PR (#21) marks the first use of AI coding agents (Grok) in the project. Cursor Cloud Agent prepared the repo for agentic development workflows.
MIT
FAQs
Dynamic and Adaptable Model Validator Using Zod, Interoperable with OpenAPI
The npm package adaptate receives a total of 69 weekly downloads. As such, adaptate popularity was classified as not popular.
We found that adaptate demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Vibe coding at scale is reshaping how packages are created, contributed, and selected across the software supply chain

Security News
npm invalidated all granular access tokens that bypass 2FA after a fresh Mini Shai-Hulud wave compromised 323 npm packages. Staged publishing also entered public preview.

Research
/Security News
Compromised npm package art-template delivered a Coruna-like iOS Safari exploit framework through a watering-hole attack.