-
Notifications
You must be signed in to change notification settings - Fork 0
OpenAPI Compatibility
This page describes which OpenAPI features apijack's code generator handles, which are recognized but produce limited output, and which are not yet supported.
apijack targets OpenAPI 3.0.x and OpenAPI 3.1.x. Both versions are parsed from a JSON spec fetched at generate time. The generator reads paths and components.schemas from the root spec object; no version-gating logic exists — features from either version are handled as encountered.
✅ Supported | 🔶 Partial / recognized | ❌ Not supported
| Feature | Status | Notes |
|---|---|---|
string / integer / number / boolean
|
✅ |
integer and number both map to TypeScript number
|
object with properties
|
✅ | Emits a TypeScript interface for named schemas; inline object literals for nested schemas up to depth 3 |
array with items
|
✅ | Emits ItemType[]; union/intersection item types are wrapped in parens |
$ref references |
✅ | Resolved recursively through components/schemas; circular references are safely handled via a visited set |
Deeply nested $ref chains |
✅ | Chains like PostWithAuthorAndComments → Post → BaseUser → Address → Coordinates are fully resolved |
allOf (intersection / composition) |
✅ | Emits a TypeScript intersection type (A & B & { inline }); required arrays are merged across all parts; inline members with properties are expanded |
oneOf / anyOf (unions) |
✅ | Emits a TypeScript union type (A | B | C); single-variant unions are unwrapped |
Discriminated unions (oneOf + discriminator) |
✅ | Emits A & { discriminatorProp: "value" } | B & { ... }; discriminator mapping is used when present, falls back to schema name |
enum (string) |
✅ | Emits string literal union type |
enum (integer / mixed types) |
Supported (OAS 3.1) | Each value is rendered as a literal; null values in enums are handled |
nullable: true (OAS 3.0 style) |
✅ | Appends | null to the resolved type |
type as array, e.g. ["string", "null"] (OAS 3.1) |
✅ | Non-null types are unioned together; null in the array appends | null
|
const (OAS 3.1) |
✅ | Emits a literal type alias (e.g. export type Status = "active") |
prefixItems — tuple types (OAS 3.1) |
✅ | Emits [A, B, C]; open-ended tuples with items emit [A, B, ...C[]]
|
not — negation (OAS 3.1) |
✅ | Emits unknown for not-only schemas; @not annotation is added to the JSDoc |
patternProperties (OAS 3.1) |
✅ | Emits an index signature [key: string]: PatternType | undefined with a JSDoc comment identifying the pattern |
additionalProperties: true |
✅ | Emits [key: string]: unknown index signature |
additionalProperties: <schema> |
✅ | Emits [key: string]: ResolvedType | undefined
|
$defs (OAS 3.1) |
✅ | Flattened into the main schema map before type generation |
readOnly properties |
✅ | Flagged in JSDoc (@readonly); skipped entirely when generating CLI body flags so users cannot accidentally send server-generated fields |
writeOnly properties |
✅ | Flagged in JSDoc (@writeonly) |
deprecated (schema and operation level) |
✅ | Schemas get @deprecated in JSDoc; operations are prefixed with [DEPRECATED] in command descriptions and the client method gets @deprecated
|
default values |
✅ | Preserved in JSDoc (@default) on generated types; query parameter defaults appear in CLI help text |
Format hints (date-time, email, uuid, uri, password, int32, int64, float, double, date, binary, etc.) |
✅ | Preserved in JSDoc (@format); surfaced in CLI flag descriptions for query parameters |
minimum / maximum / exclusiveMinimum / exclusiveMaximum
|
✅ | Preserved in JSDoc; surfaced in CLI help for query params |
minLength / maxLength
|
✅ | Preserved in JSDoc |
pattern |
✅ | Preserved in JSDoc |
minItems / maxItems / uniqueItems
|
✅ | Preserved in JSDoc |
multipleOf |
✅ | Preserved in JSDoc |
minProperties / maxProperties
|
✅ | Preserved in JSDoc |
required fields |
✅ | Required body props become .requiredOption() in Commander; optional props become .option()
|
example values |
✅ | Preserved in JSDoc (@example) |
description |
✅ | Used in JSDoc for types and in Commander command/option descriptions |
title |
🔶 | Parsed and stored; not currently emitted in output |
| Feature | Status | Notes |
|---|---|---|
| Path parameters | ✅ | Typed positional arguments in the generated client method; positional <arg> in the Commander command |
| Query parameters | ✅ | Typed optional params object in the generated client; --flag options in Commander |
| Path-level parameters | ✅ | Parameters defined at the path object level (not inside an operation) are merged with operation parameters; operation-level params override by name+in |
Parameter style and explode
|
🔶 | Parsed and forwarded in JSDoc; not applied to serialization — query params are always serialized as simple strings via URLSearchParams
|
| Header parameters | ❌ | Parsed (in: 'header' is in the type definition) but not wired up to the generated client or CLI flags |
| Cookie parameters | ❌ | Type definition acknowledges in: 'cookie'; not generated |
deprecated parameters |
❌ | No special handling at the parameter level |
| Feature | Status | Notes |
|---|---|---|
JSON request bodies (application/json) |
✅ | Fully resolved; object schemas become individual --flag options; primitive bodies use a single -B flag |
Primitive body (string, number, boolean) |
✅ | Emits a single -B <value> flag; type conversion (to number or boolean) happens in the generated action |
Array-of-primitive body (string[], number[]) |
✅ | Emits -B <values> accepting comma-separated values |
Object body (via $ref, allOf, oneOf, anyOf) |
✅ | All schema composition forms are resolved into a flat list of --flag options; oneOf/anyOf variant props are hidden by default and shown with -V
|
| Array body (items are objects) | ✅ | The array is noted in the command description; flags build a single item and the action wraps it in an array |
multipart/form-data |
❌ | Only application/json is extracted from requestBody.content; multipart endpoints are treated as having no body |
application/x-www-form-urlencoded |
❌ | Same as multipart — only the JSON content type is read |
| Multiple content types per endpoint | 🔶 | Only application/json is used; other content types are silently ignored |
| Feature | Status | Notes |
|---|---|---|
| 200 / 201 / 202 / 204 responses | ✅ | The first matching response with an application/json schema (checked in order: 200, 201, 202, 204) becomes the return type |
| Inline response schemas | ✅ | Schemas defined directly in the response object are resolved; not extracted into a named type |
Response $ref
|
✅ | Resolved through the schema map |
void return for 204 / no content |
✅ | When no JSON schema is found in any successful response, the return type is void
|
| Multiple success codes with different schemas | 🔶 | Only the first matching response code (200 → 201 → 202 → 204) is used; other status codes are ignored |
| Error response codes (4xx / 5xx) | ❌ | Error schemas are not used for type generation; the generated client throws { status, body } on non-OK responses |
| Response headers | ❌ | Response header definitions are ignored |
| Feature | Status | Notes |
|---|---|---|
| Tag-based command grouping | ✅ | The first tag on each operation determines the command group; multi-token tags (split on whitespace, /, :) create nested sub-groups |
| Operations without tags | ✅ | Fall back to a default group |
| HTTP method → verb mapping | ✅ |
GET (no path param) → list, GET (with path param) → get, POST → create, PUT → update, DELETE → delete, PATCH → patch
|
| Verb deduplication | ✅ | When multiple operations under the same parent would get the same verb, the operationId is used as the command name instead |
operationId required |
✅ | Operations without an operationId are skipped silently |
HEAD / OPTIONS / TRACE methods |
❌ | Only GET, POST, PUT, DELETE, PATCH are processed |
| Feature | Notes |
|---|---|
multipart/form-data |
File upload and mixed-part requests are not generated; endpoints that only accept multipart will appear to have no body flags |
application/x-www-form-urlencoded |
Form-encoded bodies are ignored; only JSON bodies are generated |
| Multiple content types per endpoint | Only application/json is consumed from requestBody.content and response content; other media types are silently skipped |
| Response headers | Headers defined in response objects are parsed but not exposed in the client or CLI output |
Cookie parameters (in: cookie) |
Recognized in the type definitions but not generated |
Header parameters (in: header) |
Recognized in the type definitions but not generated |
| OAuth2 / OIDC security schemes | The securitySchemes section of the spec is not read; auth is configured separately via apijack's AuthStrategy system |
| Callbacks and webhooks |
callbacks defined on operations are not processed |
| XML content type |
application/xml bodies and responses are not generated |
Server variables (servers[].variables) |
The servers array is not used; the base URL comes from the apijack environment config |
externalDocs |
Parsed and ignored; not surfaced in generated output |
links in responses |
Not processed |
security per-operation overrides |
Not read; authentication is applied uniformly via the configured AuthStrategy
|
Parameter in: header and in: cookie
|
Not generated into client method signatures or CLI flags |
title on schemas |
Parsed but not emitted in generated output |
not with additional type constraints |
A not-only schema resolves to unknown; not combined with type constraints or properties is not evaluated semantically |
The examples/edge-cases-api/ directory contains a deliberately tricky REST API that exercises the trickiest patterns the generator must handle:
- Templated/paginated responses (
Page<T>pattern with three separate wrapper schemas) - Discriminated unions with three variants, a shared base via
allOf, and an explicit discriminator mapping - Deep three-way
allOfcomposition mixing two named schemas with an inline object (AdminUser) - Poorly-defined, all-optional specs with vague field names
- Conflicting and duplicate tag names using different separator characters (spaces, colons, slashes)
- Multiple
POSToperations under the same tag, triggering verb deduplication - Primitive and array-of-primitive request bodies
- Deeply nested
$refchains (five levels deep throughPostWithAuthorAndComments) - Enums on nearly every model field
- Empty endpoints with no params, no body, and a 204 response
- Multiple success response codes with different schemas on the same operation
- All constraint keywords (
minLength,maxLength,minimum,maximum,pattern,minItems,maxItems) -
readOnly,writeOnly,nullable,deprecated,default,example, andformaton every schema type -
additionalProperties: trueandadditionalProperties: <schema>side by side - Endpoints that intentionally use unsupported features (multipart, multiple content types, response headers) to verify they degrade gracefully
See examples/edge-cases-api/README.md for the full list of scenarios and examples/edge-cases-api/server.ts for the implementation.
Essentials
Using a CLI
Authoring Routines
- Writing Routines
- Variables
- Output Capture
- Conditions & Assertions
- Loops
- Error Handling
- Sub-Routines & Meta-Commands
- Routine Testing
Building a CLI
- Building a CLI
- Authentication Strategies
- Session Auth
- Project Mode
- MCP Server Integration
- Code Generation Internals
Reference