timbenniks

openapi-typescript-sdk-generator

0
0
# Install this skill:
npx skills add timbenniks/timbenniks-agent-skills --skill "openapi-typescript-sdk-generator"

Install specific skill from multi-skill repository

# Description

Generate a production TypeScript SDK from an OpenAPI 3.0/3.1 spec (URL or local file), with human-friendly method names, interactive confirmation, and deterministic output. Use when the user wants a type-safe, fetch-based SDK or a drop-in client. Do not use for streaming/SSE/WebSockets or interactive OAuth flows.

# SKILL.md


name: openapi-typescript-sdk-generator
description: Generate a production TypeScript SDK from an OpenAPI 3.0/3.1 spec (URL or local file), with human-friendly method names, interactive confirmation, and deterministic output. Use when the user wants a type-safe, fetch-based SDK or a drop-in client. Do not use for streaming/SSE/WebSockets or interactive OAuth flows.


OpenAPI TypeScript SDK generator

Generate a production-quality TypeScript SDK from an OpenAPI specification.
Behave like a real SDK generator, not a thin OpenAPI wrapper.

Scope and guarantees

  • Propose sensible defaults
  • Ask required questions and require explicit confirmation
  • Derive human-friendly method names from context, not OpenAPI identifiers
  • Produce deterministic output
  • Support OpenAPI 3.0 and 3.1
  • Generate a typed ApiError and runtime features (retries, rate limiting, caching)
  • Explain spec issues and tolerate non-blocking drift

Inputs (prefill only)

If the user provides JSON, treat it as prefilled answers.
Still show defaults and require explicit confirmation before generating.

Example prefill:

{
  "openapi_url": "https://api.example.com/openapi.yaml",
  "openapi_path": "C:/specs/openapi.yaml",
  "output_mode": "standalone_package | folder_only",
  "output_path": "sdk",
  "package_name": "@example/api-sdk",
  "client_name": "ExampleClient",
  "runtime_target": "node_and_browser",
  "node_version": "22",
  "auth_method": "bearer"
}

Either openapi_url or openapi_path must be provided or collected.

Mandatory interaction flow

  1. Ask all required intake questions in one concise block.
  2. Show defaults for every question.
  3. Require explicit confirmation of answers or defaults.
  4. Show a naming preview and allow overrides.
  5. Ask for a final confirmation gate before any code generation.

Do not generate code until the user explicitly confirms.

Required intake questions (always ask)

Ask these questions in a single block and show defaults.

  1. SDK identity
  2. Package name
    Default: openapi-sdk
  3. Exported client name
    Default: ApiClient

  4. Output

  5. Output mode: folder_only or standalone_package
    Default: folder_only
  6. Output path (folder)
    Default: sdk/

  7. Spec source

  8. OpenAPI URL or local file path
    Default: use provided value; otherwise ask
  9. If URL: does it require auth headers?
    Default: no

  10. Base URL

  11. Default: first entry in OpenAPI servers
  12. If no servers exist, default to empty string and warn

  13. Naming style

  14. Verb-first (listPlants, getPlant)
  15. Resource-first (plantsList, plantsGet)
    Default: verb-first

  16. Runtime target

  17. node_only, browser_only, or node_and_browser
    Default: node_and_browser
  18. Node version (if Node is included)
    Default: 22

  19. Primary authentication method

  20. API key
  21. Bearer token
  22. OAuth2 access token (passthrough only)
  23. Basic auth
  24. None
    Default: first security scheme in the spec, or none if none exist

  25. Integration tests

  26. Yes, generate real integration tests (env-based, disabled by default)
  27. No, generate mock-only tests
    Default: no

Naming preview step (mandatory)

Before generation:

  • Show a preview of representative endpoints with proposed names.
  • Allow user overrides.
  • Proceed only after confirmation.
  • Record overrides in sdk-decisions.md.

Confirmation gate (mandatory)

After collecting answers and naming overrides, present a final summary and ask for explicit confirmation.

Example:

Here is what I am going to generate:

  • Package name: openapi-sdk
  • Client name: ApiClient
  • Output mode: folder_only
  • Output path: sdk/
  • Base URL: https://api.example.com
  • Naming style: verb-first
  • Runtime target: node_and_browser (Node 22)
  • Auth method: bearer token
  • Integration tests: disabled

Reply with:

  • confirm to proceed
  • or list any changes you want

Do not generate code until the user confirms.

Decision recording (mandatory)

After confirmation, write:

sdk-decisions.md

Record all final decisions and whether each one was explicit or default.

Example:

- package_name: openapi-sdk (default, confirmed)
- client_name: ApiClient (default, confirmed)
- output_mode: folder_only (explicit)
- output_path: sdk/ (default, confirmed)
- naming_style: verb-first (default, confirmed)
- runtime_target: node_and_browser (default, confirmed)
- node_version: 22 (default, confirmed)
- integration_tests: false (default, confirmed)

Output modes

folder_only

Generate a minimal SDK folder suitable for copying into an existing codebase.

sdk/
β”œβ”€β”€ index.ts
β”œβ”€β”€ client.ts
β”œβ”€β”€ operations.ts
β”œβ”€β”€ errors.ts
β”œβ”€β”€ types/
β”œβ”€β”€ utils/
β”œβ”€β”€ openapi-report.md
└── sdk-decisions.md

standalone_package

Generate a full, publishable SDK project.

<package>/
β”œβ”€β”€ package.json
β”œβ”€β”€ tsconfig.json
β”œβ”€β”€ tsdown.config.ts
β”œβ”€β”€ README.md
β”œβ”€β”€ src/
β”‚   β”œβ”€β”€ index.ts
β”‚   β”œβ”€β”€ client.ts
β”‚   β”œβ”€β”€ operations.ts
β”‚   β”œβ”€β”€ errors.ts
β”‚   β”œβ”€β”€ types/
β”‚   └── utils/
β”œβ”€β”€ examples/
β”œβ”€β”€ tests/
β”œβ”€β”€ openapi-report.md
└── sdk-decisions.md

Naming strategy (critical)

Do not use raw OpenAPI operationId values.

Derive names deterministically from context.

Naming goals

  • Human-friendly
  • Stable across regenerations
  • Flat function surface
  • Predictable
  • Collision-free

Naming algorithm

  1. Extract the primary resource from the path
    Ignore version prefixes such as /v1 or /api.

Examples:

  • /plants β†’ plants
  • /plants/{id}/events β†’ primary plants, secondary events

  • Infer the action from HTTP method and path shape

Method Path shape Action
GET collection list
GET item get
POST collection create
PUT item update
PATCH item update
DELETE item remove
  1. Apply naming style

Verb-first:

  • listPlants
  • getPlant
  • updatePlant
  • removePlant
  • listPlantEvents
  • createPlantEvent

Resource-first:

  • plantsList
  • plantsGet
  • plantEventsList

  • Singularize item resources

  • Prefer getPlant over getPlants

  • Use a small irregular map (people β†’ person, children β†’ child)
  • If uncertain, keep plural and document it

  • Collision handling

  • Prefer param-based disambiguation (getPlantById, getPlantBySlug)

  • If unresolved, append a deterministic suffix (__get, __post)
  • Document all collisions and resolutions in openapi-report.md

OpenAPI validation and report

Validate the spec and tolerate non-blocking issues.

Generate:

openapi-report.md

Include:

  • Blocking issues
  • Non-blocking issues
  • Why each issue matters
  • What assumptions were made
  • A mapping table of generated method names to original operationId (if present)

SDK runtime behavior

Transport

  • Use native fetch
  • Isomorphic (Node and browser where possible)
  • ESM only

Errors

Generate a typed ApiError with:

  • status
  • code
  • message
  • body
  • headers
  • method
  • url

Throw ApiError for all non-2xx responses, except 304 handled by cache.

Retries

  • Retry on network errors, 429, and 5xx
  • Default max attempts: 3
  • Exponential backoff with jitter
  • Honor Retry-After
  • Allow per-request overrides
  • Default to idempotent methods only; require explicit opt-in for POST/PATCH

Rate limiting

  • In-memory limiter per client instance
  • Respect rate-limit headers and Retry-After

Caching

  • GET requests only by default
  • In-memory cache with TTL
  • Manual busting
  • ETag / If-None-Match support
  • Respect Cache-Control and Pragma
  • Do not cache when Authorization is present unless explicitly enabled

Integration tests (optional)

If enabled:

  • Generate real integration tests
  • Disabled by default in CI
  • Credentials loaded from environment variables
  • Tests perform simple read operations and validate response shape
  • Required env vars documented in README

If disabled:

  • Generate mock-based tests only

Generated API surface

Each operation exports a flat async function:

listPlants(params, options?): Promise<Plant[]>

Options allow:

  • Auth overrides
  • Retry overrides
  • Cache overrides
  • AbortSignal
  • Extra headers

Determinism

  • Sort operations by path + method for stable output
  • Keep naming stable across regenerations
  • Record decisions in sdk-decisions.md

Acceptance criteria

Output is correct only if:

  • All required questions were asked
  • Defaults were shown and explicitly confirmed
  • Code generation occurred only after confirmation
  • Names were derived from context, not operationId
  • Types compile under strict TypeScript
  • Retry, cache, and rate limiting work as specified
  • openapi-report.md and sdk-decisions.md exist
  • Optional integration tests are safe and documented
  • Output is deterministic

Defaults (if confirmed)

  • Naming style: verb-first
  • Output mode: folder_only
  • Output path: sdk/
  • Package name: openapi-sdk
  • Client name: ApiClient
  • Base URL: first OpenAPI server
  • Runtime target: node_and_browser
  • Node version: 22
  • Cache enabled for GET
  • Retries enabled for idempotent methods
  • Rate limiting enabled
  • Integration tests disabled

# Supported AI Coding Agents

This skill is compatible with the SKILL.md standard and works with all major AI coding agents:

Learn more about the SKILL.md standard and how to use these skills with your preferred AI coding agent.