Documentation

OpenAPI Sync is a powerful developer tool that automates the generation of TypeScript types, runtime validation schemas (Zod, Yup, Joi), and endpoint definitions from your OpenAPI specifications in real-time.

Latest Version: 4.0.0 - Now with Zod, Yup & Joi validation support

Installation

Install OpenAPI Sync using your preferred package manager:

bash
# NPM
npm install openapi-sync

# Yarn
yarn add openapi-sync

# PNPM
pnpm add openapi-sync

# Global Installation
npm install -g openapi-sync

# Direct Usage (No Installation)
npx openapi-sync

Quick Start

1. Create Configuration

Create a configuration file in your project root:

json
// openapi.sync.json
{
  "refetchInterval": 5000,
  "folder": "./src/api",
  "api": {
    "petstore": "https://petstore3.swagger.io/api/v3/openapi.json"
  }
}

2. Run Sync Command

bash
npx openapi-sync

3. Use Generated Code

typescript
import { getPetById } from "./src/api/petstore/endpoints";
import { IPet } from "./src/api/petstore/types";

// Use the endpoint URL
const petUrl = getPetById("123"); // Returns: "/pet/123"

// Use the generated types
const pet: IPet = {
  id: 1,
  name: "Fluffy",
  status: "available"
};

Basic Configuration

OpenAPI Sync supports multiple configuration formats:

  • openapi.sync.json - JSON format
  • openapi.sync.ts - TypeScript format
  • openapi.sync.js - JavaScript format

Configuration Options

PropertyTypeDescription
refetchIntervalnumberMilliseconds between API refetches (dev only)
folderstringOutput directory for generated files
apiRecord<string, string>Map of API names to OpenAPI spec URLs
servernumber | stringServer index or custom server URL

Folder Splitting

Organize your generated code into folders based on tags or custom logic.

Split by Tags

typescript
folderSplit: {
  byTags: true  // Creates folders like admin/, user/, pet/
}

Custom Folder Logic

typescript
folderSplit: {
  customFolder: ({ method, path, tags, operationId }) => {
    // Admin endpoints go to admin folder
    if (tags?.includes("admin")) return "admin";
    
    // API versioning
    if (path.startsWith("/api/v1/")) return "v1";
    if (path.startsWith("/api/v2/")) return "v2";
    
    // Method-based organization
    if (method === "GET") return "read";
    if (method === "POST" || method === "PUT") return "write";
    
    return null; // Use default structure
  }
}

Generated Structure

text
src/api/
├── petstore/
│   ├── admin/
│   │   ├── endpoints.ts
│   │   └── types.ts
│   ├── user/
│   │   ├── endpoints.ts
│   │   └── types.ts
│   └── pet/
│       ├── endpoints.ts
│       └── types.ts
└── shared.ts

Validation Schemas

Generate runtime validation schemas using Zod, Yup, or Joi from your OpenAPI specification.

Configuration

typescript
validations: {
  library: "zod",  // "zod" | "yup" | "joi"
  generate: {
    query: true,   // Generate query parameter validations
    dto: true      // Generate request body validations
  },
  name: {
    prefix: "I",
    suffix: "Schema",
    useOperationId: true
  }
}

Installation

bash
# For Zod
npm install zod

# For Yup
npm install yup

# For Joi
npm install joi

Usage Example

typescript
import { IAddPetDTOSchema } from "./src/api/petstore/validation";
import { z } from "zod";

// Validate request body
try {
  const validatedData = IAddPetDTOSchema.parse(req.body);
  // Data is now validated and typed
} catch (error) {
  if (error instanceof z.ZodError) {
    console.error("Validation errors:", error.errors);
  }
}

Express Middleware

typescript
import { Request, Response, NextFunction } from "express";
import { z } from "zod";

export const validate = <T extends z.ZodTypeAny>(schema: T) => {
  return (req: Request, res: Response, next: NextFunction) => {
    try {
      schema.parse(req.body);
      next();
    } catch (error) {
      if (error instanceof z.ZodError) {
        res.status(400).json({
          error: "Validation failed",
          details: error.errors
        });
      }
    }
  };
};

// Usage
import { IAddPetDTOSchema } from "./api/validation";
router.post("/pet", validate(IAddPetDTOSchema), handler);

Custom Code Preservation

Add your own custom code that will survive when files are regenerated.

Configuration

typescript
customCode: {
  enabled: true,              // Enable custom code preservation
  position: "bottom",         // "top" | "bottom" | "both"
  markerText: "CUSTOM CODE",  // Custom marker text
  includeInstructions: true   // Include helpful instructions
}

Usage

typescript
// endpoints.ts (after generation)
export const getPet = (petId: string) => `/pet/${petId}`;

// 🔒 CUSTOM CODE START
// Add your custom code here - it will be preserved
export const legacyGetPet = (id: string) => `/api/v1/pet/${id}`;

export const buildPetUrl = (petId: string, includePhotos: boolean) => {
  const base = getPet(petId);
  return includePhotos ? `${base}?include=photos` : base;
};
// 🔒 CUSTOM CODE END

export const updatePet = (petId: string) => `/pet/${petId}`;

Endpoint Filtering

Control which endpoints are included in code generation.

Exclude Endpoints

typescript
endpoints: {
  exclude: {
    // Exclude by tags
    tags: ["deprecated", "internal"],
    
    // Exclude specific endpoints
    endpoints: [
      { path: "/admin/users", method: "DELETE" },
      { regex: "^/internal/.*", method: "GET" },
      { path: "/debug" }  // All methods
    ]
  }
}

Include Only Specific Endpoints

typescript
endpoints: {
  include: {
    // Include only public endpoints
    tags: ["public"],
    
    // Include specific endpoints
    endpoints: [
      { path: "/public/users", method: "GET" },
      { regex: "^/public/.*" }
    ]
  }
}

CLI Usage

bash
# Run with default configuration
npx openapi-sync

# Run with custom refetch interval
npx openapi-sync --refreshinterval 30000
npx openapi-sync -ri 30000

# Get help
npx openapi-sync --help

Programmatic Usage

typescript
import { Init } from "openapi-sync";

// Initialize with default config
await Init();

// Initialize with custom options
await Init({
  refetchInterval: 30000
});

// With error handling
try {
  await Init({
    refetchInterval: process.env.NODE_ENV === "development" ? 5000 : 0
  });
  console.log("API types synchronized successfully");
} catch (error) {
  console.error("Failed to sync API types:", error);
}

Troubleshooting

Configuration File Not Found

Error: No config found

Solution: Ensure you have one of these files in your project root:openapi.sync.json, openapi.sync.ts, or openapi.sync.js

Network Timeout Errors

Error: timeout of 60000ms exceeded

Solution: The tool includes automatic retry with exponential backoff. Check your internet connection and verify the OpenAPI spec URL is accessible.

TypeScript Compilation Errors

Error: Cannot find module './src/api/petstore/types'

Solution: Ensure the sync process completed successfully and check that the folder path in config is correct.

API Reference

Init(options?: InitOptions)

Initializes OpenAPI sync with the specified configuration.

typescript
import { Init } from "openapi-sync";

await Init({ 
  refetchInterval: 10000 
});

Exported Types

typescript
import {
  IConfig,
  IOpenApiSpec,
  IOpenApSchemaSpec,
  IConfigReplaceWord,
  IConfigExclude,
  IConfigInclude,
  IConfigDoc
} from "openapi-sync/types";

Changelog

v4.0.0

Major release with validation schema generation support (Zod, Yup, Joi)

v2.1.13

Fix dts type fixes and Clean up tsup build config and introduction of unit testing

v2.1.11

Folder splitting configuration for organized code generation

v2.1.10

OperationId-based naming for types and endpoints, enhanced filtering and tag support