OpenAPI Rest Client generator — generates typed TypeScript API clients from OpenAPI specs with Zod validation.
- Generates typed TypeScript API clients from OpenAPI 3.x specs
- Zod schemas for all request/response types with full validation
- Resource-based architecture (
client.pets.getList(),client.pets.create()) - Automatic enum deduplication across schemas
- Pagination handling built-in
- Date transformation schemas (string ↔ Date via date-fns)
- Configurable via
orc.config.ts - Supports both URL and local file specs
npm install @moinax/orc zodnpx orc initThis creates orc.config.ts:
import { defineConfig } from '@moinax/orc/config';
export default defineConfig({
clients: [
{
name: 'MyApi',
spec: 'https://api.example.com/openapi.json',
output: 'src/lib/api/my-api-client',
},
],
});npx orc generateimport { MyApiClient } from './src/lib/api/my-api-client/generated';
const client = new MyApiClient('https://api.example.com', {
getAccessToken: async () => 'your-token',
});
// Typed, validated API calls
const { data, pagination } = await client.pet.getList({ page: 1, limit: 10 });
const pet = await client.pet.getDetail(petId);
const created = await client.pet.create({ name: 'Buddy', species: 'dog' });orc generate # Generate all clients
orc generate --client MyApi # Generate a specific client
orc generate --client MyApi --spec <url> # Override spec URL
orc init # Scaffold config file
import { defineConfig } from '@moinax/orc/config';
export default defineConfig({
// Optional: customize the import path for the runtime package
// Defaults to '@moinax/orc'
runtimePackage: '@moinax/orc',
clients: [
{
// Name used for the generated client class (e.g., MyApiClient)
name: 'MyApi',
// URL or local file path to the OpenAPI spec
spec: 'https://api.example.com/openapi.json',
// Output directory for generated files
output: 'src/lib/api/my-api-client',
// Optional: strip a prefix from all API paths
// Useful when the spec includes a base path like /public
stripPathPrefix: '/public',
// Optional: prefix all generated schema/type/enum names
// Useful when generating multiple clients to avoid naming collisions
// e.g., 'Charge' → chargePetSchema, ChargePet, ChargeContractStatus
schemaPrefix: 'Charge',
},
],
});For each client, orc generates:
output/generated/
├── schemas.ts # Zod schemas + TypeScript types
├── MyApiClient.ts # Client class extending Client
├── Resource.ts # Base resource class
├── index.ts # Barrel exports
└── resources/
├── index.ts # Resource exports
├── Pets.resource.ts # Resource with typed methods
└── Owners.resource.ts
The package also exports the runtime that generated code depends on:
import {
Client, // Base HTTP client
Resource, // Base resource class
parseSchema, // Zod parse with partial fallback
ClientError, // HTTP error class
ParseError, // Zod validation error class
// Date transform schemas
stringToDateSchema,
stringToDaySchema,
dateToStringSchema,
dayToStringSchema,
} from '@moinax/orc';const client = new MyApiClient('https://api.example.com', {
// Async function returning a bearer token
getAccessToken: async () => token,
// Custom response handler
responseHandler: async (response) => response,
// Logger (defaults to console)
logger: console,
// Number of retries for failed GET requests (5xx)
retries: 3,
});npm install
npm test # Run tests
npm run build # Build with tsup
npm run typecheck # Type check with tsc# Bump version (creates commit + git tag)
npm version patch # 0.1.0 → 0.1.1
npm version minor # 0.1.0 → 0.2.0
npm version major # 0.1.0 → 1.0.0
# Publish (prepublishOnly will run the build automatically)
npm publish --access public
# Push commit and tag to remote
git push --follow-tagsNote: --access public is required for scoped packages (@moinax/orc). You must be logged in via npm login.
MIT