\ No newline at end of file
diff --git a/_next/static/k9KMQ5NiZ0HqgIMlfEGbN/_buildManifest.js b/_next/static/WV2_B9ikbonUyMhyHiA-O/_buildManifest.js
similarity index 100%
rename from _next/static/k9KMQ5NiZ0HqgIMlfEGbN/_buildManifest.js
rename to _next/static/WV2_B9ikbonUyMhyHiA-O/_buildManifest.js
diff --git a/_next/static/k9KMQ5NiZ0HqgIMlfEGbN/_ssgManifest.js b/_next/static/WV2_B9ikbonUyMhyHiA-O/_ssgManifest.js
similarity index 100%
rename from _next/static/k9KMQ5NiZ0HqgIMlfEGbN/_ssgManifest.js
rename to _next/static/WV2_B9ikbonUyMhyHiA-O/_ssgManifest.js
diff --git a/_next/static/chunks/nextra-data-en-US.json b/_next/static/chunks/nextra-data-en-US.json
index b1848646..549dcb2f 100644
--- a/_next/static/chunks/nextra-data-en-US.json
+++ b/_next/static/chunks/nextra-data-en-US.json
@@ -1 +1 @@
-{"/guides/concepts/authenticated-input-specifications":{"title":"Authenticated input specifications","data":{"":"Sometimes you want to generate using a URL as the input, but the URL requires some kind of authentication\nheader to be passed.A good example is Google cloud platforms IAP proxy,\nwhich was the original motivation for supporting this, where we must pass a Proxy-Authorization header.\nOr from private github repositories,\nwhere a Authorization header should be supplied.This can be achieved using the environment variable (preferred)) OPENAPI_REMOTE_SPEC_REQUEST_HEADERS,\nalso available as the --remote-spec-request-headers cli flag.","format#Format":"The format of the value is a JSON object keyed by URI, with values being either an object,\nor array of {name, value} pairs.For example:\n{\n \"https://example.com\": [\n {\"name\": \"X-Client-Id\", \"value\": \"my-client-id\"},\n {\"name\": \"X-Client-Secret\", \"value\": \"some-secret-value\"}\n ],\n \"https://example.org/some/path\": {\"name\": \"Proxy-Authorization\", \"value\": \"some token\"}\n}\nAs a typescript type:\ntype OPENAPI_REMOTE_SPEC_REQUEST_HEADERS = {\n [uri: string]: { name: string, value: string }[] | { name: string, value: string }\n}","hostname-matching#Hostname matching":"You should set the uris to the least specific uris you're happy for the header to be sent to -\na full match on the provided uri is required for the headers to be sent.Eg: given a uri of https://exmaple.com:8080/openapi.yaml the headers would not\nbe sent for requests to other ports, resource paths, or protocols, but a less specific\nuri like https://example.com will send headers on any (https) request to that domain,\nsuch as https://exmaple.com/some/path/openapi.yaml","tips-for-generating-the-json#Tips for generating the JSON":"Unfortunately it is a little annoying to formulate in shell scripts, so here's some examples to get you started.Typically, in any real use cases the secret values would be coming from other shell variables, eg: storing a\nshort-lived access token, etc.","use-jq#Use jq":"Using jq:\nOPENAPI_REMOTE_SPEC_REQUEST_HEADERS=$(jq --null-input --compact-output \\\n --arg domain \"https://example.com\" \\\n --arg name \"proxy-authorization\" \\\n --arg value \"some secret value\" '{$domain: {$name, $value}}')\necho $OPENAPI_REMOTE_SPEC_REQUEST_HEADERS\nOutputs:\n{\"https://example.com\":{\"name\":\"proxy-authorization\",\"value\":\"some secret value\"}}","use-node#Use node":"Using nodejs:\nOPENAPI_REMOTE_SPEC_REQUEST_HEADERS=$(node -p 'JSON.stringify({[process.argv[1]]: {name: process.argv[2], value: process.argv[3]}})' \\\n https://example.com \\\n proxy-authorization \\\n 'some secret value')\necho $OPENAPI_REMOTE_SPEC_REQUEST_HEADERS\nOutputs:\n{\"https://example.com\":{\"name\":\"proxy-authorization\",\"value\":\"some secret value\"}}","why-json#Why JSON":"Why JSON you ask? Simply put it has very well-defined semantics, and is easy to parse without\nfear of jumbling the pieces together.I started by trying to come up with a more ergonomic format, and then felt like I was re-inventing JSON\nwhen it came to dealing with all the edge cases correctly."}},"/guides/concepts/servers-object-handling":{"title":"Guide to servers object handling","data":{"":"OpenAPI 3 has a servers property that can be used to define the base url for the whole document, or\nspecific operations. This guide aims to explain how this is processed.You can find the specifications definition of the servers object hereThis is fully supported, including placeholder/variable substitution, and overriding.\nThe servers object is only used for client SDK templates.It doesn't really make sense in the context of a server template, and so is ignored.","overview#Overview":"Consider an example servers block:\nservers:\n - url: '{protocol}://{host}:{port}'\n variables:\n host:\n default: localhost\n protocol:\n enum: [http, https]\n default: http\n port:\n default: '8080'\nIt defines a single server, with three variables.This will generate a ApiClientServers object that you can use to create a basePath like so:\nconst client = new ApiClient({\n// basePath will be https://localhost:80\nbasePath: ApiClientServers\n .server(\"{protocol}://{host}:{port}\") // the url template determines the build function\n .build(\n \"https\", // string literal union to form the enum\n undefined, // pass undefined to take the default\n \"80\", // override defaults\n )\n})\nIf you pass no args to build, the defaults from the specification are used:\nconst client = new ApiClient({\n// basePath will be http://localhost:8080\nbasePath: ApiClientServers\n .server(\"{protocol}://{host}:{port}\")\n .build()\n})\nYou can also take the default (first) server like so:\nconst client = new ApiClient({\n// basePath will be http://localhost:8080\nbasePath: ApiClientServers\n .server()\n .build()\n})","operation-specific-overrides#Operation specific overrides":"You can specify servers overrides at the path, or individual operation level. The most specific servers block\nwill be used for a given operation.For example, override the url for all operations under the /attachments route:\npaths:\n /attachments:\n servers:\n - url: 'https://attachments.example.com'\nWhen overrides are specified, an additional basePath positional argument will be added to the operation, defaulting\nto the first overridden server with default placeholder values.\nexport class ApiClient {\n async uploadAttachment(\n p: { ... },\n // Overridden server param\n basePath:\n | Server<\"uploadAttachment_ApiClient\">\n | string = ApiClientServers.operations\n .uploadAttachment()\n .build(),\n timeout?: number,\n opts: RequestInit = {},\n ): Promise>> {\n ...\n }\n}\nAs you can see the overrides for each operation are exposed as ApiClientServers.operations.() following\nthe same pattern as the root servers.","configuration#Configuration":"This behavior is optional, and be turned off by passing:\n--enable-typed-base-paths=false\nWhen disabled basePath: string parameters will still be added to operations that have a servers override, but\nno code based on the url or variables will be generated.See also CLI reference"}},"/overview/compatibility":{"title":"Compatibility Tables","data":{"":"This page aims to document which parts of the openapi 3.1.0 specification is supported.\nIt may not be totally complete / accurate, but it should be broadly correct and give you\nan understanding of what does / doesn't work.\nIf something you need isn't supported yet, please raise a Github\nissue\ndetailing your use-case, and we can work together to get support added / extended.We will also accept pull requests where implemented functionality follows the OpenAPI\nspecification,\nand the output code is of a high quality in terms of developer experience and robustness. See\nCONTRIBUTING.md\nto get started","tldr#tldr;":"Most common functionality used by JSON based APIs should work.\nGreat support for paths using application/json request / response bodies\nComprehensive support for most schema properties, including json validation stuff like minLength,\nbut only for json content types. Notable exceptions:\nreadonly is currently implemented incorrectly\ndiscriminator is ignored, but union / intersection types will be generated based on anyOf / allOf so\nthis isn't often an issue in practice\nNo support for security schemes, you'll need to fudge these as header parameters, or implement out-of-band\nfor the specification for now.\nNo support for webhooks / callbacks yet","legend#Legend":"Symbol\tMeaning\t✅/🚧\tSupported in some way. May be incomplete\t🚫\tNot supported, likely to be supported eventually\tN/A\tIgnored, unlikely to be used for anything","root-openapi-object#Root OpenAPI Object":"Root object of openapi documents. A ✅ means at least some support for this field - click through to the table\nfor each attribute for further details.\nAttribute\tSupported\tNotes\topenapi\t✅\tEither 3.1.x or 3.0.x is supported\tinfo\tN/A\tIgnored\tjsonSchemaDialect\t🚫\tNot yet supported\tservers\t✅\tUsed by client SDK templates\tpaths\t✅\t\twebhooks\t🚫\tNot yet supported. Emulate by defining as normal paths.\tcomponents\t✅\t\tsecurity\t🚫\tNot yet supported. Implement out of band or using header parameters.\ttags\t✅\tOptionally used to split output into multiple files\texternalDocs\tN/A\tIgnored","sub-objects#Sub-objects":"","reference-object#Reference Object":"Reference objects are supported to be used in place of the actual object definition anywhere in the documents.\nThey can also cross files (and maybe urls - needs testing).\nIt's recommended to use $ref objects as much as possible. It both promotes re-use, and also allows control\nover the naming of the type / schema in the generated code.\nExample:\n requestBody:\n required: true\n content:\n application/json:\n schema:\n $ref: \"#/components/schemas/ExampleSchema\"\nAttribute\tSupported\tNotes\t$ref\t✅\t$ref support is robust, and works correctly across multiple input files.\tsummary\tN/A\tIgnored\tdescription\tN/A\tIgnored","server-object#Server Object":"Used by the client SDKs to generate builders for basePath's and override parameters.See servers object guide for detailed explanation\nof how this is handled.\nAttribute\tSupported\tNotes\turl\t✅\tOptionally used to type client SDK basePath configuration\tdescription\tN/A\tIgnored\tvariables\t✅","components-object#Components Object":"Technically you can define any \"components\" you like, and $refs to them will work, regardless\nof if they appear in the official specification.The table indicates what will actually typically be used for anything right now.\nAttribute\tSupported\tNotes\tschemas\t✅\t\tresponses\t✅\t\tparameters\t✅\t\texamples\tN/A\t\trequestBodies\t✅\t\theaders\t✅\t\tsecuritySchemes\t🚫\tNot yet supported\tlinks\t🚫\tNot yet supported\tcallbacks\t🚫\tNot yet supported\tpathItems\t✅","paths-object#Paths Object":"Paths are well supported.\nAttribute\tSupported\tNotes\t{path}\t✅","path-item-object#Path Item Object":"All common http methods are supported.\nAttribute\tSupported\tNotes\tsummary\tN/A\tIgnored\tdescription\tN/A\tIgnored\tget\t✅\t\tput\t✅\t\tpost\t✅\t\tdelete\t✅\t\thead\t✅\t\tpatch\t✅\t\ttrace\t🚫\tNot yet supported\tservers\t✅\tUsed by client SDK templates\tparameters\t✅","operation-object#Operation Object":"Most things are supported. It's recommended you supply an operationId as otherwise\none will be generated from the path / http method, which is often overly verbose.\nAttribute\tSupported\tNotes\ttags\t✅\tOptionally used to split output into multiple files\tsummary\tN/A\tIgnored\tdescription\tN/A\tIgnored\texternalDocs\tN/A\tIgnored\toperationId\t✅\tUsed to generate names on types / methods / interfaces\tparameters\t✅\t\trequestBody\t✅\t\tresponses\t✅\t\tcallbacks\t🚫\tNot yet supported\tdeprecated\t🚫\tNot yet supported\tsecurity\t🚫\tNot yet supported\tservers\t✅\tUsed by client SDK templates","parameter-object#Parameter Object":"Whilst attributes like style and explode are not yet supported, for most common parameter use-cases\neverything should just work as you'd guess/expect.\nAttribute\tSupported\tNotes\tname\t✅\t\tin\t✅/🚧\tEverything supported apart from \"cookie\".\tdescription\tN/A\tIgnored\trequired\t✅\t\tdeprecated\tN/A\tIgnored\tallowEmptyValue\t🚫\tUse schema minLength: 1 to prevent empty string values in query parameters\tstyle\t🚫\tNot yet supported\texplode\t🚫\tNot yet supported\tallowReserved\t🚫\tUse schema pattern to emulate\tschema\t✅\t\texample\tN/A\tIgnored\texamples\tN/A\tIgnored\tcontent\t🚫\tNot yet supported","request-body-object#Request Body Object":"Well-supported for application/json content types. Support for form data, and file uploads, etc\nplanned to come soon.\nAttribute\tSupported\tNotes\tdescription\tN/A\tIgnored\tcontent\t✅/🚧\tOnly media types of application/json work properly.\trequired\t✅","media-type-object#Media Type Object":"Attribute\tSupported\tNotes\tschema\t✅\t\texample\tN/A\tIgnored\texamples\tN/A\tIgnored\tencoding\t🚫\tNot yet supported","responses-object#Responses Object":"Well supported.\nAttribute\tSupported\tNotes\tdefault\t✅\t\t{http-status-code}\t✅","response-object#Response Object":"Generally well-supported for application/json content types.\nAttribute\tSupported\tNotes\tdescription\tN/A\tIgnored\theaders\t🚫\tNot yet supported\tcontent\t✅/🚧\tOnly media types of application/json work properly.\tlinks\t🚫\tNot yet supported","header-object#Header Object":"Attribute\tSupported\tNotes\tdescription\tN/A\tIgnored\tschema\t✅\tComplex schemas for headers may not work. Stick to string / number if possible.","tag-object#Tag Object":"Tags are only used for code organization purposes, when passing the --grouping-strategy first-tag\nCLI option.\nAttribute\tSupported\tNotes\tname\t✅\tOptionally used to split output into multiple files\tdescription\tN/A\tIgnored\texternalDocs\tN/A\tIgnored","schema-object#Schema Object":"The majority of attributes that can be specified by schema objects are supported, and accurately match the underlying\nopenapi specification / json schema validation specifications.Most notable exception is readOnly / writeOnly which are currently implemented incorrectly, planned to be addressed\nas a breaking change prior to v1.\nAttribute\tSupported\tNotes\ttitle\tN/A\t\tmultipleOf\t✅\tApplies to type: number\tmaximum\t✅\tApplies to type: number\texclusiveMaximum\t✅\tApplies to type: number\tminimum\t✅\tApplies to type: number\texclusiveMinimum\t✅\tApplies to type: number\tmaxLength\t✅\tApplies to type: string\tminLength\t✅\tApplies to type: string\tpattern\t✅\tSupport for type: string\tmaxItems\t✅\tApplies to type: array\tminItems\t✅\tApplies to type: array\tuniqueItems\t✅\tApplies to type: array\tmaxProperties\t🚫\tNot yet supported\tminProperties\t🚫\tNot yet supported\trequired\t✅\tControls whether undefined is allowed for each value in properties\tenum\t✅\tApplies to type: number and type: string\ttype\t✅\t\tnot\t🚫\tNot yet supported\tallOf\t✅\tProduces a intersection type like A & B\toneOf\t✅\tProduces a union type like A | B\tanyOf\t✅\tProduces a union type like A | B\titems\t✅\tApplies to type: array\tproperties\t✅\tApplies to type: object\tadditionalProperties\t✅/🚧\tFairly comprehensive support, produces Record or unknown/any (dependent on --ts-allow-any)\tformat\t✅/🚧\tLimited support for format email and date-time\tdefault\t✅\t\tnullable\t✅\tAlso supports type: null as an alternative\tdiscriminator\t🚫\tIgnored. Union / Intersection types are usd based on anyOf / allOf / oneOf.\treadOnly\t🚫\tProduces readonly modifiers, but this behavior is incorrect\twriteOnly\t🚫\tNot yet supported\texample\tN/A\tIgnored\texternalDocs\tN/A\tIgnored\tdeprecated\t🚫\tNot yet supported\txml\t🚫\tNot yet supported","completely-unsupported-things#Completely unsupported things":"The following objects are completely unsupported at this stage.","encoding-object#Encoding Object":"Attribute\tSupported\tNotes\tcontentType\t🚫\tNot yet supported\theaders\t🚫\tNot yet supported\tstyle\t🚫\tNot yet supported\texplode\t🚫\tNot yet supported\tallowReserved\t🚫\tNot yet supported","callback-object#Callback Object":"The callback object is completely unsupported.\nAttribute\tSupported\tNotes\t\\{expression\\}\t🚫","link-object#Link Object":"The link object is completely unsupported.\nAttribute\tSupported\tNotes\toperationRef\t🚫\t\toperationId\t🚫\t\tparameters\t🚫\t\trequestBody\t🚫\t\tdescription\tN/A\t\tserver\t🚫","discriminator-object#Discriminator Object":"The discriminator object is completely unsupported.\nAttribute\tSupported\tNotes\tpropertyName\t🚫\t\tmapping\t🚫","xml-object#XML Object":"The XML object is completely unsupported.\nAttribute\tSupported\tNotes\tname\t🚫\t\tnamespace\t🚫\t\tprefix\t🚫\t\tattribute\t🚫\t\twrapped\t🚫","security-scheme-object#Security Scheme Object":"The security scheme object is completely unsupported.\nAttribute\tSupported\tNotes\ttype\t🚫\t\tdescription\t🚫\t\tname\t🚫\t\tin\t🚫\t\tscheme\t🚫\t\tbearerFormat\t🚫\t\tflows\t🚫\t\topenIdConnectUrl\t🚫","oauth-flows-object#OAuth Flows Object":"The oauth flows object is completely unsupported.\nAttribute\tSupported\tNotes\timplicit\t🚫\t\tpassword\t🚫\t\tclientCredentials\t🚫\t\tauthorizationCode\t🚫","oauth-flow-object#OAuth Flow Object":"The oauth flow object is completely unsupported.\nAttribute\tSupported\tNotes\tauthorizationUrl\t🚫\t\ttokenUrl\t🚫\t\trefreshUrl\t🚫\t\tscopes\t🚫","security-requirement-object---patterned-fields#Security Requirement Object - Patterned Fields":"The security requirement object is completely unsupported.\nAttribute\tSupported\tNotes\t\\{name\\}\t🚫"}},"/overview/schema-first-design":{"title":"Why schema first","data":{"":"Broadly speaking there are two approaches people take to maintaining API specifications:\nSchema first, where you write the schema by hand\nCode first, where you generate the schema from your code\nThis project being a code generator from API specification files is on the schema first side of the debate, but why?Ultimately this is fairly subjective, but there are four primary motivators that lead us to believe schema first\nis the better approach.","longevity#Longevity":"APIs are forever,\nchanging them in backwards incompatible ways is hard/expensive, or sometimes not possible.With that in mind, we believe it's important to be thoughtful about your API design, and\nthat writing an explicit specification/contract is a great forcing function to accomplish this.Additionally, programming languages / frameworks come and go - they are an implementation detail,\nand subject to change as business requirements evolve.\nOpenAPI (originally Swagger) has been around for over a decade now, and we're confident it'll be around for a long time.","common-language#Common Language":"Many large projects / systems will involve multiple programming languages. For example, you might have a Java backend,\nKotlin Android app, Swift iOS app, and Typescript web frontend.For writing your API contracts using OpenAPI up front, you create a common ground for developers of all languages to discuss\nand hash out the details.","constraints#Constraints":"General purpose programming languages are very flexible. If you try hard enough, you can probably implement it.\nSpecifications like OpenAPI on the other hand are more rigid and constraining.We believe it's better to lean into this and design your system such that it can be represented fully by a\nspecification, rather than attempt to generate a specification from the implementation and lose\ninformation/nuance in the process.","separation#Separation":"A good specification not only defines the API contract, but also includes a lot of supplementary information such as examples,\nand documentation.Generating a good specification from your code, therefore requires including all this extra metadata in the code, which\ncan make the code more difficult to work with.We prefer to separate these concerns out into the specification, and keep the implementation code leaner and simpler."}},"/getting-started/quick-start":{"title":"Quick Start","data":{"":"Install the latest NodeJS LTS release, though any recent version of NodeJS will likely work.You'll also need either an OpenAPI v3 / v3.1, or TypeSpec API specification to generate from. You can\nprovide OpenAPI specifications as YAML or JSON, local files or remote urls - we'll load them all! 🚀Cross-file references are also supported, so don't worry about pre-processing the input.You can check the version we develop and test against here.\nFirst install the CLI and the required runtime packages to your project:\nnpm i --dev @nahkies/openapi-code-generator\nnpm i @nahkies/typescript-fetch-runtime\npnpm add --dev @nahkies/openapi-code-generator\npnpm add @nahkies/typescript-fetch-runtime\nyarn add --dev @nahkies/openapi-code-generator\nyarn add @nahkies/typescript-fetch-runtime\nbun add --dev @nahkies/openapi-code-generator\nbun add @nahkies/typescript-fetch-runtime\nYou could also install the CLI globally if you prefer, but it's best to version it per project.This will generate the client to ./src/generated/clients/some-serviceYou can provide either a local file path or url for the input file.\nnpm run openapi-code-generator \\\n--input ./openapi.yaml \\ # or https://example.com/openapi.{json,yaml}\n--output ./src/generated/clients/some-service \\\n--template typescript-fetch\npnpm run openapi-code-generator \\\n--input ./openapi.yaml \\ # or https://example.com/openapi.{json,yaml}\n--output ./src/generated/clients/some-service \\\n--template typescript-fetch\nyarn openapi-code-generator \\\n--input ./openapi.yaml \\ # or https://example.com/openapi.{json,yaml}\n--output ./src/generated/clients/some-service \\\n--template typescript-fetch\nbun run openapi-code-generator \\\n--input ./openapi.yaml \\ # or https://example.com/openapi.{json,yaml}\n--output ./src/generated/clients/some-service \\\n--template typescript-fetch\nUse your new type-safe client, and never worry about making a typo in a url or parameter name again.\nLet the typescript compiler take care of checking that for you.See Guide to typescript-fetch client template for more details.\nFirst install the CLI and the required runtime packages to your project:\nnpm i --dev @nahkies/openapi-code-generator\nnpm i axios @nahkies/typescript-axios-runtime\npnpm add --dev @nahkies/openapi-code-generator\npnpm add axios @nahkies/typescript-axios-runtime\nyarn add --dev @nahkies/openapi-code-generator\nyarn add axios @nahkies/typescript-axios-runtime\nbun add --dev @nahkies/openapi-code-generator\nbun add axios @nahkies/typescript-axios-runtime\nYou could also install the CLI globally if you prefer, but it's best to version it per project.This will generate the client to ./src/generated/clients/some-serviceYou can provide either a local file path or url for the input file.\nnpm run openapi-code-generator \\\n--input ./openapi.yaml \\ # or https://example.com/openapi.{json,yaml}\n--output ./src/generated/clients/some-service \\\n--template typescript-axios\npnpm run openapi-code-generator \\\n--input ./openapi.yaml \\ # or https://example.com/openapi.{json,yaml}\n--output ./src/generated/clients/some-service \\\n--template typescript-axios\nyarn openapi-code-generator \\\n--input ./openapi.yaml \\ # or https://example.com/openapi.{json,yaml}\n--output ./src/generated/clients/some-service \\\n--template typescript-axios\nbun run openapi-code-generator \\\n--input ./openapi.yaml \\ # or https://example.com/openapi.{json,yaml}\n--output ./src/generated/clients/some-service \\\n--template typescript-axios\nUse your new type-safe client, and never worry about making a typo in a url or parameter name again.\nLet the typescript compiler take care of checking that for you.See Guide to typescript-axios client template for more details.\nFirst install the CLI and the required runtime packages to your project:\nnpm i --dev @nahkies/openapi-code-generator @types/koa @types/koa__router\nnpm i @nahkies/typescript-koa-runtime @koa/cors @koa/router koa koa-body zod\npnpm add --dev @nahkies/openapi-code-generator @types/koa @types/koa__router\npnpm add @nahkies/typescript-koa-runtime @koa/cors @koa/router koa koa-body zod\nyarn add --dev @nahkies/openapi-code-generator @types/koa @types/koa__router\nyarn add @nahkies/typescript-koa-runtime @koa/cors @koa/router koa koa-body zod\nbun add --dev @nahkies/openapi-code-generator @types/koa @types/koa__router\nbun add @nahkies/typescript-koa-runtime @koa/cors @koa/router koa koa-body zod\nYou could also install the CLI globally if you prefer, but it's best to version it per project.You can provide either a local file path or url for the input file.This will generate the server router and validation logic to ./src/generated\nnpm run openapi-code-generator \\\n--input ./openapi.yaml \\ # or https://example.com/openapi.{json,yaml}\n--output ./src/generated \\\n--template typescript-koa\npnpm run openapi-code-generator \\\n--input ./openapi.yaml \\ # or https://example.com/openapi.{json,yaml}\n--output ./src/generated \\\n--template typescript-koa\nyarn openapi-code-generator \\\n--input ./openapi.yaml \\ # or https://example.com/openapi.{json,yaml}\n--output ./src/generated \\\n--template typescript-koa\nbun run openapi-code-generator \\\n--input ./openapi.yaml \\ # or https://example.com/openapi.{json,yaml}\n--output ./src/generated \\\n--template typescript-koa\nImplement handlers for your server, and be confident that they match what the client expects. Everything\nwill be strongly typed, so typos are surfaced at development time, not runtime.By default the runtime validation is using zod.See Guide to typescript-koa client template for more details.","cli-options#CLI options":"See the cli reference for the full range of supported options, or try\nnpm run openapi-code-generator --help\npnpm run openapi-code-generator --help\nyarn openapi-code-generator --help\nbun run openapi-code-generator --help","typespec-specifications#Typespec specifications":"If you want to use typespec instead of openapi3\nas your input specifications, additionally install the typespec compiler and supporting packages.\nnpm i --dev @typespec/compiler @typespec/http @typespec/openapi @typespec/openapi3 @typespec/versioning\npnpm add --dev @typespec/compiler @typespec/http @typespec/openapi @typespec/openapi3 @typespec/versioning\nyarn add --dev @typespec/compiler @typespec/http @typespec/openapi @typespec/openapi3 @typespec/versioning\nbun add --dev @typespec/compiler @typespec/http @typespec/openapi @typespec/openapi3 @typespec/versioning\nDepending on how your typespec specification is written, you may need to install additional packages such\nas @typespec/rest.You can then generate like so:\nnpm run openapi-code-generator \\\n --input ./some-service.tsp \\ # or https://example.com/some-service.tsp\n --input-type=typespec \\\n --output ./src/generated/clients/some-service \\\n --template typescript-fetch\npnpm run openapi-code-generator \\\n --input ./some-service.tsp \\ # or https://example.com/some-service.tsp\n --input-type=typespec \\\n --output ./src/generated/clients/some-service \\\n --template typescript-fetch\nyarn openapi-code-generator \\\n --input ./some-service.tsp \\ # or https://example.com/some-service.tsp\n --input-type=typespec \\\n --output ./src/generated/clients/some-service \\\n --template typescript-fetch\nbun run openapi-code-generator \\\n --input ./some-service.tsp \\ # or https://example.com/some-service.tsp\n --input-type=typespec \\\n --output ./src/generated/clients/some-service \\\n --template typescript-fetch\nYou can see examples of code generated from typespec specifications here"}},"/guides/client-templates/typescript-angular":{"title":"Using the typescript-angular template","data":{"":"this is the least battle tested of the templates and most likely to have critical bugs\nThe typescript-angular template outputs a client SDK based on the Angular HttpClient that gives the following:\nTyped methods to call each endpoint returning an RxJS Observable\nIt does not yet support runtime validation/parsing - compile time type safety only at this stage.See integration-tests/typescript-angular for more samples.","install-dependencies#Install dependencies":"First install the CLI to your project:\nnpm i --dev @nahkies/openapi-code-generator\npnpm add --dev @nahkies/openapi-code-generator\nyarn add --dev @nahkies/openapi-code-generator\nbun add --dev @nahkies/openapi-code-generator\nSee also quick start guide","run-generation#Run generation":"npm run openapi-code-generator \\\n --input ./openapi.yaml \\\n --input-type openapi3 \\\n --output ./src/app/clients/some-service \\\n --template typescript-angular \\\n --schema-builder zod\npnpm run openapi-code-generator \\\n --input ./openapi.yaml \\\n --input-type openapi3 \\\n --output ./src/app/clients/some-service \\\n --template typescript-angular \\\n --schema-builder zod\nyarn openapi-code-generator \\\n --input ./openapi.yaml \\\n --input-type openapi3 \\\n --output ./src/app/clients/some-service \\\n --template typescript-angular \\\n --schema-builder zod\nbun run openapi-code-generator \\\n --input ./openapi.yaml \\\n --input-type openapi3 \\\n --output ./src/app/clients/some-service \\\n --template typescript-angular \\\n --schema-builder zod\nnpm run openapi-code-generator \\\n --input ./typespec.tsp \\\n --input-type typespec \\\n --output ./src/app/clients/some-service \\\n --template typescript-angular \\\n --schema-builder zod\npnpm run openapi-code-generator \\\n --input ./typespec.tsp \\\n --input-type typespec \\\n --output ./src/app/clients/some-service \\\n --template typescript-angular \\\n --schema-builder zod\nyarn openapi-code-generator \\\n --input ./typespec.tsp \\\n --input-type typespec \\\n --output ./src/app/clients/some-service \\\n --template typescript-angular \\\n --schema-builder zod\nbun run openapi-code-generator \\\n --input ./typespec.tsp \\\n --input-type typespec \\\n --output ./src/app/clients/some-service \\\n --template typescript-angular \\\n --schema-builder zod","using-the-generated-code#Using the generated code":"Running the above will output these files into ./src/app/clients/some-service:\n./api.module.ts: exports a class ApiModule as an NgModule\n./client.service.ts: exports a class ApiClient as injectable Angular service\n./models.ts: exports typescript types\n./schemas.ts: exports runtime parsers using the chosen schema-builder (default zod)\nOnce generated usage should look something like this:\n// Root Angular module\n@NgModule({\n declarations: [AppComponent],\n imports: [BrowserModule, AppRoutingModule, ApiModule],\n providers: [],\n bootstrap: [AppComponent],\n})\nexport class AppModule {}\n@Component({\n selector: \"app-root\",\n templateUrl: \"./app.component.html\",\n styleUrls: [\"./app.component.css\"],\n})\nexport class AppComponent {\n // inject into your component\n constructor(client: ApiClient) {\n client.updateTodoListById({listId: \"1\", requestBody: {name: \"Foo\"}}).subscribe((next) => {\n if (next.status === 200) {\n // TODO: body is currently incorrectly `unknown` here\n console.log(next.body.id)\n }\n })\n }\n}"}},"/guides/client-templates/typescript-axios":{"title":"Using the typescript-axios template","data":{"":"The typescript-axios template outputs a client SDK based on the axios that gives the following:\nTyped methods to call each endpoint\nOptionally, runtime response validation\nIt follows the standard axios pattern of rejecting any response that isn't 2xx and thus can't provide typed\nerror responses. If you'd like to have strong typing over your error responses consider using the typescript-fetch template.Runtime request parameter validation is not currently supported.See integration-tests/typescript-axios for more samples.","install-dependencies#Install dependencies":"First install the CLI and the required runtime packages to your project:\nnpm i --dev @nahkies/openapi-code-generator\nnpm i axios @nahkies/typescript-axios-runtime\npnpm add --dev @nahkies/openapi-code-generator\npnpm add axios @nahkies/typescript-axios-runtime\nyarn add --dev @nahkies/openapi-code-generator\nyarn add axios @nahkies/typescript-axios-runtime\nbun add --dev @nahkies/openapi-code-generator\nbun add axios @nahkies/typescript-axios-runtime\nSee also quick start guide","run-generation#Run generation":"Experimental support for runtime response validation is available behind the --enable-runtime-response-validation\nflag.\nnpm run openapi-code-generator \\\n --input ./openapi.yaml \\\n --input-type openapi3 \\\n --output ./src/clients/some-service \\\n --template typescript-axios \\\n --schema-builder zod\npnpm run openapi-code-generator \\\n --input ./openapi.yaml \\\n --input-type openapi3 \\\n --output ./src/clients/some-service \\\n --template typescript-axios \\\n --schema-builder zod\nyarn openapi-code-generator \\\n --input ./openapi.yaml \\\n --input-type openapi3 \\\n --output ./src/clients/some-service \\\n --template typescript-axios \\\n --schema-builder zod\nbun run openapi-code-generator \\\n --input ./openapi.yaml \\\n --input-type openapi3 \\\n --output ./src/clients/some-service \\\n --template typescript-axios \\\n --schema-builder zod\nnpm run openapi-code-generator \\\n --input ./typespec.tsp \\\n --input-type typespec \\\n --output ./src/clients/some-service \\\n --template typescript-axios \\\n --schema-builder zod\npnpm run openapi-code-generator \\\n --input ./typespec.tsp \\\n --input-type typespec \\\n --output ./src/clients/some-service \\\n --template typescript-axios \\\n --schema-builder zod\nyarn openapi-code-generator \\\n --input ./typespec.tsp \\\n --input-type typespec \\\n --output ./src/clients/some-service \\\n --template typescript-axios \\\n --schema-builder zod\nbun run openapi-code-generator \\\n --input ./typespec.tsp \\\n --input-type typespec \\\n --output ./src/clients/some-service \\\n --template typescript-axios \\\n --schema-builder zod","using-the-generated-code#Using the generated code":"Running the above will output these files into ./src/clients/some-service:\n./client.ts: exports a class ApiClient that implements methods for calling each endpoint\n./models.ts: exports typescript types\n./schemas.ts: exports runtime parsers using the chosen schema-builder (default zod)\nOnce generated usage should look something like this:\nconst client = new ApiClient({\n // Pass a axios instance if you wish to use interceptors for auth, logging, etc\n // axios: axios.create({...}),\n basePath: `http://localhost:${address.port}`,\n defaultHeaders: {\n \"Content-Type\": \"application/json\",\n Authorisation: \"Bearer: \", // can pass auth headers here\n },\n})\n// rejects if status code isn't 2xx, following typical axios behavior\nconst res = await client.createTodoListItem({\n listId: list.id,\n requestBody: {content: \"test item\"},\n // optionally pass a timeout (ms), or any arbitrary axios options\n // timeout?: number,\n // opts?: AxiosRequestConfig\n})\n// data will be typed correctly\nconsole.log(`id is: ${res.data.id}`)"}},"/guides/concepts/extract-inline-schemas":{"title":"Extract inline schemas","data":{"":"We have experimental support for \"extracting inline schemas\" behind the\n--extract-inline-schemas / OPENAPI_EXTRACT_INLINE_SCHEMAS=true configuration flag.","what-does-this-mean#What does this mean?":"There are basically two ways you can define schemas in your openapi specifications:\nNamed schemas\nInline schemas\nThese are handled differently by code generation. Enabling --extract-inline-schemas aims to\nmake inline schemas emit similar code to named schemas.","named-schema-example#Named schema example":"Normally when writing openapi specifications it is desirable to make use of $ref and define your schemas as named\ncomponents.\npaths:\n /list/{listId}:\n parameters:\n - $ref: '#/components/parameters/listId'\n get:\n operationId: getTodoListById\n responses:\n 200:\n description: 'success'\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/TodoList'\ncomponents:\n schemas:\n TodoList:\n type: object\n required:\n - id\n - name\n - totalItemCount\n - incompleteItemCount\n - created\n properties:\n id:\n type: string\n format: uuid\n name:\n type: string\n totalItemCount:\n type: number\n incompleteItemCount:\n type: number\n created:\n type: string\n format: date-time\nWhen we run code generation for this, we expect a type and a schema for the TodoList to be generated, something like:\nimport {z} from 'zod'\nexport type t_TodoList = {\n id: string\n name: string\n totalItemCount: number\n incompleteItemCount: number\n created: string\n}\nexport const s_TodoList = z.object({\n id: z.string(),\n name: z.string(),\n totalItemCount: z.coerce.number(),\n incompleteItemCount: z.coerce.number(),\n created: z.string().datetime({ offset: true }),\n})\nThis is useful, as it means that we can easily reference the type, or use the schema as we require.","inline-schema-example#Inline Schema Example":"However, not everyone will write their specifications using named $refs, and instead inline schemas may be used.\nThis is especially prolific when generating the specification from implementation code in our experience.Consider the same example as above, but with the schema inlined:\npaths:\n /list/{listId}:\n parameters:\n - $ref: '#/components/parameters/listId'\n get:\n operationId: getTodoListById\n responses:\n 200:\n description: 'success'\n content:\n application/json:\n schema:\n type: object\n required:\n - id\n - name\n - totalItemCount\n - incompleteItemCount\n - created\n properties:\n id:\n type: string\n format: uuid\n name:\n type: string\n totalItemCount:\n type: number\n incompleteItemCount:\n type: number\n created:\n type: string\n format: date-time\ncomponents:\n schemas: {}\nBy default, this will be emitted as in-line types / schemas\nexport type GetTodoListById = (\n params: Params,\n respond: GetTodoListByIdResponder,\n ctx: RouterContext,\n) => Promise<\n | KoaRuntimeResponse\n | Response<\n 200,\n {\n id: string\n name: string\n totalItemCount: number\n incompleteItemCount: number\n created: string\n }\n >\n | Response\n | Response\n>\nconst getTodoListByIdResponseValidator = responseValidationFactory(\n [\n [\n \"200\",\n z.object({\n id: z.string(),\n name: z.string(),\n totalItemCount: z.coerce.number(),\n incompleteItemCount: z.coerce.number(),\n created: z.string().datetime({ offset: true }),\n }),\n ],\n [\"4XX\", s_Error],\n ],\n z.undefined(),\n)\nrouter.get(\"getTodoListById\", \"/list/:listId\", async (ctx, next) => {\n // ...\n const responder = {\n with200() {\n return new KoaRuntimeResponse<{\n id: string\n name: string\n totalItemCount: number\n incompleteItemCount: number\n created: string\n }>(200)\n }\n }\n // ...\n})","with---extract-inline-schemas-enabled#With --extract-inline-schemas enabled":"Notice how this:\nCreates a lot of duplication, we have to repeat the definition anytime it is used\nMakes it inconvenient, or impossible to reference the type/schema in our implementation code\nWith --extract-inline-schemas enabled, the code generator will synthesis a name for each inline schema based on\nits usage, and emit exported types/schemas, eg:\nexport type t_getTodoListByIdJson200Response = {\n id: string\n name: string\n totalItemCount: number\n incompleteItemCount: number\n created: string\n}\nexport const s_getTodoListByIdJson200Response = z.object({\n id: z.string(),\n name: z.string(),\n totalItemCount: z.coerce.number(),\n incompleteItemCount: z.coerce.number(),\n created: z.string().datetime({ offset: true }),\n})\nThis can be a handy trick to make the code generated from schemas you don't own/control easier to work with. In general\nyou should prefer to improve the specifications to be more suitable for code generation, which generally also improves\nthe result of documentation tools like Redoc"}},"/guides/client-templates/typescript-fetch":{"title":"Using the typescript-fetch template","data":{"":"The typescript-fetch template outputs a client SDK based on the fetch api that gives the following:\nTyped methods to call each endpoint\nSupport for passing a timeout, abort signals are still respected\nOptionally, runtime response validation\nRuntime request parameter validation is not currently supported.See integration-tests/typescript-fetch for more samples.Dependencies:","install-dependencies#Install dependencies":"First install the CLI and the required runtime packages to your project:\nnpm i --dev @nahkies/openapi-code-generator\nnpm i @nahkies/typescript-fetch-runtime\npnpm add --dev @nahkies/openapi-code-generator\npnpm add @nahkies/typescript-fetch-runtime\nyarn add --dev @nahkies/openapi-code-generator\nyarn add @nahkies/typescript-fetch-runtime\nbun add --dev @nahkies/openapi-code-generator\nbun add @nahkies/typescript-fetch-runtime\nSee also quick start guide\nIf you're using an older version of NodeJS, or targeting very old web browsers,\nyou may need a polyfill like node-fetch-native","run-generation#Run generation":"Experimental support for runtime response validation is available behind the --enable-runtime-response-validation\nflag.\nnpm run openapi-code-generator \\\n --input ./openapi.yaml \\\n --input-type openapi3 \\\n --output ./src/clients/some-service \\\n --template typescript-fetch \\\n --schema-builder zod\npnpm run openapi-code-generator \\\n --input ./openapi.yaml \\\n --input-type openapi3 \\\n --output ./src/clients/some-service \\\n --template typescript-fetch \\\n --schema-builder zod\nyarn openapi-code-generator \\\n --input ./openapi.yaml \\\n --input-type openapi3 \\\n --output ./src/clients/some-service \\\n --template typescript-fetch \\\n --schema-builder zod\nbun run openapi-code-generator \\\n --input ./openapi.yaml \\\n --input-type openapi3 \\\n --output ./src/clients/some-service \\\n --template typescript-fetch \\\n --schema-builder zod\nnpm run openapi-code-generator \\\n --input ./typespec.tsp \\\n --input-type typespec \\\n --output ./src/clients/some-service \\\n --template typescript-fetch \\\n --schema-builder zod\npnpm run openapi-code-generator \\\n --input ./typespec.tsp \\\n --input-type typespec \\\n --output ./src/clients/some-service \\\n --template typescript-fetch \\\n --schema-builder zod\nyarn openapi-code-generator \\\n --input ./typespec.tsp \\\n --input-type typespec \\\n --output ./src/clients/some-service \\\n --template typescript-fetch \\\n --schema-builder zod\nbun run openapi-code-generator \\\n --input ./typespec.tsp \\\n --input-type typespec \\\n --output ./src/clients/some-service \\\n --template typescript-fetch \\\n --schema-builder zod","using-the-generated-code#Using the generated code":"Running the above will output these files into ./src/clients/some-service:\n./client.ts: exports a class ApiClient that implements methods for calling each endpoint\n./models.ts: exports typescript types\n./schemas.ts: exports runtime parsers using the chosen schema-builder (default zod)\nOnce generated usage should look something like this:\nconst client = new ApiClient({\n basePath: `http://localhost:${address.port}`,\n defaultHeaders: {\n \"Content-Type\": \"application/json\",\n Authorisation: \"Bearer: \", // can pass auth headers here\n },\n})\nconst res = await client.createTodoListItem({\n listId: list.id,\n requestBody: {content: \"test item\"},\n // optionally pass a timeout (ms), or any arbitrary fetch options (eg: an abort signal)\n // timeout?: number,\n // opts?: RequestInit\n})\n// checking the status code narrows the response body types (ie: remove error types from the type union)\nif (res.status !== 200) {\n throw new Error(\"failed to create item\")\n}\n// body will be typed correctly\nconst body = await res.json()\nconsole.log(`id is: ${body.id}`)"}},"/guides/server-templates/typescript-koa":{"title":"Using the typescript-koa template","data":{"":"The typescript-koa template outputs scaffolding code that handles the following:\nBuilding a @koa/router instance with all routes in the openapi specification\nGenerating types and runtime schema parsers for all request parameters/bodies and response bodies\nGenerating types for route implementations that receive validated inputs, and have return types that are additionally\nvalidated at runtime prior to sending the response\n(Optionally) Actually starting the server and binding to a port\nSee integration-tests/typescript-koa for more samples.","install-dependencies#Install dependencies":"First install the CLI and the required runtime packages to your project:\nnpm i --dev @nahkies/openapi-code-generator @types/koa @types/koa__router\nnpm i @nahkies/typescript-koa-runtime @koa/cors @koa/router koa koa-body zod\npnpm add --dev @nahkies/openapi-code-generator @types/koa @types/koa__router\npnpm add @nahkies/typescript-koa-runtime @koa/cors @koa/router koa koa-body zod\nyarn add --dev @nahkies/openapi-code-generator @types/koa @types/koa__router\nyarn add @nahkies/typescript-koa-runtime @koa/cors @koa/router koa koa-body zod\nbun add --dev @nahkies/openapi-code-generator @types/koa @types/koa__router\nbun add @nahkies/typescript-koa-runtime @koa/cors @koa/router koa koa-body zod\nSee also quick start guide","run-generation#Run generation":"npm run openapi-code-generator \\\n --input ./openapi.yaml \\\n --input-type openapi3 \\\n --output ./src \\\n --template typescript-koa \\\n --schema-builder zod\npnpm run openapi-code-generator \\\n --input ./openapi.yaml \\\n --input-type openapi3 \\\n --output ./src \\\n --template typescript-koa \\\n --schema-builder zod\nyarn openapi-code-generator \\\n --input ./openapi.yaml \\\n --input-type openapi3 \\\n --output ./src \\\n --template typescript-koa \\\n --schema-builder zod\nbun run openapi-code-generator \\\n --input ./openapi.yaml \\\n --input-type openapi3 \\\n --output ./src \\\n --template typescript-koa \\\n --schema-builder zod\nnpm run openapi-code-generator \\\n --input ./typespec.tsp \\\n --input-type typespec \\\n --output ./src \\\n --template typescript-koa \\\n --schema-builder zod\npnpm run openapi-code-generator \\\n --input ./typespec.tsp \\\n --input-type typespec \\\n --output ./src \\\n --template typescript-koa \\\n --schema-builder zod\nyarn openapi-code-generator \\\n --input ./typespec.tsp \\\n --input-type typespec \\\n --output ./src \\\n --template typescript-koa \\\n --schema-builder zod\nbun run openapi-code-generator \\\n --input ./typespec.tsp \\\n --input-type typespec \\\n --output ./src \\\n --template typescript-koa \\\n --schema-builder zod","using-the-generated-code#Using the generated code":"Running the above will output three files into ./src:\ngenerated.ts - exports a createRouter and bootstrap function, along with associated types used to create your server\nmodels.ts - exports typescript types for schemas\nschemas.ts - exports runtime schema validators\nOnce generated usage should look something like this:\nimport {bootstrap, createRouter, CreateTodoList, GetTodoLists} from \"../generated\"\n// Define your route implementations as async functions implementing the types\n// exported from generated.ts\nconst createTodoList: CreateTodoList = async ({body}, respond) => {\n const list = await prisma.todoList.create({\n data: {\n // body is strongly typed and parsed at runtime\n name: body.name,\n },\n })\n // (recommended) the respond parameter is a strongly typed helper that\n // provides a better editor experience.\n // the response body is additionally validated against the response schema/status code at runtime\n return respond.with200().body(dbListToApiList(list))\n // (deprecated) alternatively, you can return a {status, body} object which is also strongly typed\n // pattern matching the status code against the response schema:\n // return {\n // status: 200 as const,\n // body: dbListToApiList(list)\n // }\n}\nconst getTodoLists: GetTodoLists = async ({query}) => {\n // omitted for brevity\n}\n// Starts a server listening on `port`\nbootstrap({\n router: createRouter({getTodoLists, createTodoList}),\n port: 8080,\n})","custom-koa-appconfig#Custom Koa app/config":"The provided bootstrap function has a limited range of options. For more advanced use-cases,\nsuch as https you will need to construct your own Koa app, and mount the router returned by createRouter.The only real requirement is that you provide a body parsing middleware before the router that places\na parsed request body on the ctx.body property.Eg:\nimport {createRouter} from \"../generated\"\nimport KoaBody from \"koa-body\"\nimport https from \"https\"\n// ...implement routes here\nconst app = new Koa()\n// it doesn't have to be koa-body, but it does need to put the parsed body on `ctx.body`\napp.use(KoaBody())\n// mount the generated router\nconst router = createRouter({getTodoLists, createTodoList})\napp.use(router.allowedMethods())\napp.use(router.routes())\nhttps\n .createServer(\n {\n key: \"...\",\n cert: \"...\",\n },\n app.callback(),\n )\n .listen(433)","error-handling#Error Handling":"Any errors thrown during the request processing will be wrapped in KoaRuntimeError objects,\nand tagged with the phase the error was thrown.\ninterface KoaRuntimeError extends Error {\n cause: unknown // the originally thrown exception\n phase: \"request_validation\" | \"request_handler\" | \"response_validation\"\n}\nThis allows for implementing catch-all error middleware for common concerns like failed request validation,\nor internal server errors.Eg:\nexport async function genericErrorMiddleware(ctx: Context, next: Next) {\n try {\n await next()\n } catch (err) {\n // if the request validation failed, return a 400 and include helpful\n // information about the problem\n if (KoaRuntimeError.isKoaError(err) && err.phase === \"request_validation\") {\n ctx.status = 400\n ctx.body = {\n message: \"request validation failed\",\n meta: err.cause instanceof ZodError ? {issues: err.cause.issues} : {},\n } satisfies t_Error\n return\n }\n // return a 500 and omit information from the response otherwise\n logger.error(\"internal server error\", err)\n ctx.status = 500\n ctx.body = {\n message: \"internal server error\",\n } satisfies t_Error\n }\n}"}},"/":{"title":"Index","data":{}},"/overview/about":{"title":"Welcome","data":{"":"@nahkies/openapi-code-generator is a CLI tool that aims to generate high quality typescript client SDK's,\nand API server scaffolding (routing, validation, serialization) from OpenAPI 3 specifications.Currently, OpenAPI 3.0, OpenAPI 3.1, and TypeSpec are supported an input specifications.This gives you amazing auto-complete, and compile-time safety. Typescripts expressive type system it used to\nmake the generated clients feel idomatic, and as close to handwritten as possible.\nAlready know that code generation will save you time? Jump straight in with the quick start guide","server-scaffolding-templates#Server Scaffolding Templates":"Server templates handle the routing setup, request and response validation/serialization so that you\ncan focus on the business logic.\ntypescript-koa","client-sdk-templates#Client SDK Templates":"Client templates give you a strongly typed interface to your remote server calls, ensuring that you\nnever misspell a field name or route again.\ntypescript-fetch\ntypescript-axios\ntypescript-angular","project-goal--principals#Project Goal / Principals":"To make it fun, easy and productive to generate both client and server \"glue\"\ncode from openapi 3 definitions. This is code that is tedious and error-prone to maintain by hand,\nby automating it we can reduce toil and frustration.The generated code output should be \"stable\" in the sense that it will not\narbitrarily change between generation without need (for a given version). For\nexample outputting entities in alphabetic order where possible.It should also be generated in a way that human would reasonably write it,\nthe intent is that the generated code can and should be committed to the consuming project\nrepositories, allowing it to be reviewed, and audited overtime.This is particularly useful in the case of mistakes in the generation or schemas, and also\nserves to reduce risk of adoption. There should be no lock-in - if you wish to stop using the\ncode generation, you can simply start maintaining the previously generated code by hand.The initial focus on typescript, with an intention to later support other languages. kotlin\nis the most likely candidate for a second language.","compatibility--completeness#Compatibility / Completeness":"This project should be considered beta quality, though it's getting close to a v1 release.It does not yet handle all aspects of the OpenAPI / JSON schema specification, but most common\nfeatures are implemented. In particular at the moment only JSON content types are supported properly.You can get a sense of what works by looking at the compatibility tables, or the Github issues (non-exhaustive).\nHowever often the best way is to just try it out with your API specification and see what happens!The integration tests also act as a good showcase of the sort of output you can expect.","compared-to-other-projects#Compared to other projects":"There are many similar projects out there, so why should you use this one?\nStrong emphasis on \"human like\" code output\nTackles the program space from both ends - client and server, for a single source of truth\nComprehensive runtime parsing/validation in addition to static compile time safety\nSo if you want a low risk, write-once, get strong build & runtime guarantees experience then we're worth giving a try."}},"/reference/cli-options":{"title":"CLI Options","data":{"cli-configuration-reference#CLI Configuration Reference":"All CLI options can be provided as command-line parameters, or environment variables as you prefer.","generate#Generate":"The default action is to run code generation.","required-parameters#Required Parameters":"","-i---input-value#-i --input ":"As environment variable OPENAPI_INPUTPath to the input specification to generate from. Either a local path, or a url may be provided, though not all\nspecifications will build correctly from a url.By default, this must be a OpenAPI 3.0 or OpenAPI 3.1\nspecification, in either YAML or JSON format.When used in conjunction with --input-type typespec then a TypeSpec specification can be\nsupplied instead.","-o---output-value#-o --output ":"As environment variable OPENAPI_OUTPUTdirectory to output generated code (env: )","-t---template-value#-t --template ":"As environment variable OPENAPI_TEMPLATEWhich template you wish to generate, one of:\ntypescript-koa\ntypescript-fetch\ntypescript-axios\ntypescript-angular","optional-parameters#Optional Parameters":"","--input-type-value#--input-type ":"As environment variable OPENAPI_INPUT_TYPEWhat type of input file is being provided, one of:\nopenapi3 (default)\ntypespec","--override-specification-title-value#--override-specification-title ":"As environment variable OPENAPI_OVERRIDE_SPECIFICATION_TITLEAllows overriding the info.title field of the input OpenAPI document. This field is used to generate\nsome symbol names, and so this is useful when you don't directly control the source specification, and\nwish to customize the output symbol names.","-s---schema-builder-value#-s --schema-builder ":"As environment variable OPENAPI_SCHEMA_BUILDERWhich runtime schema parsing library to use, one of:\nzod (default)\njoi","--grouping-strategy-value-experimental#--grouping-strategy (experimental)":"As environment variable OPENAPI_GROUPING_STRATEGYStrategy to use for splitting output into separate files. Set to none for a single generated.ts file, one of:\nnone don't split output, yield single generated.ts (default)\nfirst-tag group operations based on their first tag\nfirst-slug group operations based on their first route slug/segment","--enable-runtime-response-validation-experimental#--enable-runtime-response-validation (experimental)":"As environment variable whether to validate response bodies using the chosen runtime schema library.Default false\nNote: this is currently always true for server templates, and only applies to the client library templates.","--enable-typed-base-paths-client-sdks-only#--enable-typed-base-paths (client sdks only)":"As environment variable OPENAPI_ENABLE_TYPED_BASE_PATHSControls whether to generate a URL builder from the openapi specifications\narray of server urls and placeholder variables.When disabled a plain string type is used for these parameters.See servers object guide for detailed explanation\nof how this is handled.Default: true","--extract-inline-schemas-experimental#--extract-inline-schemas (experimental)":"As environment variable OPENAPI_EXTRACT_INLINE_SCHEMASGenerate names based on usage, and extract in-line schemas to be standalone types / schemas in the\ngenerated code. This is especially useful when dealing with input schemas that don't make good use\nof named $ref's.See extract-inline-schemas guide for details of how this works.Default false","--allow-unused-imports#--allow-unused-imports":"As environment variable OPENAPI_ALLOW_UNUSED_IMPORTSAllow unused imports to be emitted in generated code. Offered as an escape hatch if any bugs\nin the unused-import elimination occur.Default false","--ts-allow-any#--ts-allow-any":"As environment variable OPENAPI_TS_ALLOW_ANYDetermines whether to use any or unknown when generating types for schemas that don't have\nconcrete definitions. Eg: additionalProperties: true or {} schemas.Using unknown will push you towards using type guards / making runtime checks before interacting\nwith the model and should generally result in more robust code, whilst any may be more convenient\nduring rapid prototyping.Default: false (use unknown rather than any)\nInput schema\t--ts-allow-any\t(default)\t{}\tany\tunknown\t{additionalProperties: true}\tany\tunknown\t{additionalProperties: false}\t{ [key: string]: never }\t{ [key: string]: never }\t{type: \"object\", additionalProperties: true}\t{[key: string]: any}\t{[key: string]: unknown}\t{type: \"array\", items: {}}\tany[]\tunknown[]","--ts-server-implementation-method-experimental-server-sdks-only#--ts-server-implementation-method (experimental) (server sdks only)":"As environment variable OPENAPI_TS_SERVER_IMPLEMENTATION_METHODDetermines whether to represent server stubs / interfaces as type, interface, or abstract class entities.This is mostly a case of personal preference, but can be important for better integration with dependency injection\nframeworks, such as diod which rely on abstract class objects to define\ninterfaces for injection.\nOption\tExample Output\tinterface\texport interface Implementation { ... } `\ttype\texport type Implementation = { ... }\tabstract-class\texport abstract class Implementation { ... }\t\nDefault: type","--filename-convention-value#--filename-convention ":"As environment variable OPENAPI_FILENAME_CONVENTIONDetermines which naming convention to use for dynamically generated filenames\n(eg: those generated from tags or route prefixes).\nValue\tExample Filename\tkebab-case\tmy-file.ts\tcamel-case\tmyFile.ts\ttitle-case\tMyFile.ts\tsnake-case\tmy_file.ts\t\nDefault: kebab-case","misc#Misc":"","--remote-spec-request-headers-authenticated-remote-specifications#--remote-spec-request-headers (authenticated remote specifications)":"As environment variable OPENAPI_REMOTE_SPEC_REQUEST_HEADERSAllows providing request headers to use when fetching remote specifications. This allows for running\ngeneration against remote sources that require authentication.See authenticated-input-specifications guide for\ndetails of how to use.","-h---help#-h, --help":"Displays help text for command"}}}
\ No newline at end of file
+{"/guides/concepts/authenticated-input-specifications":{"title":"Authenticated input specifications","data":{"":"Sometimes you want to generate using a URL as the input, but the URL requires some kind of authentication\nheader to be passed.A good example is Google cloud platforms IAP proxy,\nwhich was the original motivation for supporting this, where we must pass a Proxy-Authorization header.\nOr from private github repositories,\nwhere a Authorization header should be supplied.This can be achieved using the environment variable (preferred)) OPENAPI_REMOTE_SPEC_REQUEST_HEADERS,\nalso available as the --remote-spec-request-headers cli flag.","format#Format":"The format of the value is a JSON object keyed by URI, with values being either an object,\nor array of {name, value} pairs.For example:\n{\n \"https://example.com\": [\n {\"name\": \"X-Client-Id\", \"value\": \"my-client-id\"},\n {\"name\": \"X-Client-Secret\", \"value\": \"some-secret-value\"}\n ],\n \"https://example.org/some/path\": {\"name\": \"Proxy-Authorization\", \"value\": \"some token\"}\n}\nAs a typescript type:\ntype OPENAPI_REMOTE_SPEC_REQUEST_HEADERS = {\n [uri: string]: { name: string, value: string }[] | { name: string, value: string }\n}","hostname-matching#Hostname matching":"You should set the uris to the least specific uris you're happy for the header to be sent to -\na full match on the provided uri is required for the headers to be sent.Eg: given a uri of https://exmaple.com:8080/openapi.yaml the headers would not\nbe sent for requests to other ports, resource paths, or protocols, but a less specific\nuri like https://example.com will send headers on any (https) request to that domain,\nsuch as https://exmaple.com/some/path/openapi.yaml","tips-for-generating-the-json#Tips for generating the JSON":"Unfortunately it is a little annoying to formulate in shell scripts, so here's some examples to get you started.Typically, in any real use cases the secret values would be coming from other shell variables, eg: storing a\nshort-lived access token, etc.","use-jq#Use jq":"Using jq:\nOPENAPI_REMOTE_SPEC_REQUEST_HEADERS=$(jq --null-input --compact-output \\\n --arg domain \"https://example.com\" \\\n --arg name \"proxy-authorization\" \\\n --arg value \"some secret value\" '{$domain: {$name, $value}}')\necho $OPENAPI_REMOTE_SPEC_REQUEST_HEADERS\nOutputs:\n{\"https://example.com\":{\"name\":\"proxy-authorization\",\"value\":\"some secret value\"}}","use-node#Use node":"Using nodejs:\nOPENAPI_REMOTE_SPEC_REQUEST_HEADERS=$(node -p 'JSON.stringify({[process.argv[1]]: {name: process.argv[2], value: process.argv[3]}})' \\\n https://example.com \\\n proxy-authorization \\\n 'some secret value')\necho $OPENAPI_REMOTE_SPEC_REQUEST_HEADERS\nOutputs:\n{\"https://example.com\":{\"name\":\"proxy-authorization\",\"value\":\"some secret value\"}}","why-json#Why JSON":"Why JSON you ask? Simply put it has very well-defined semantics, and is easy to parse without\nfear of jumbling the pieces together.I started by trying to come up with a more ergonomic format, and then felt like I was re-inventing JSON\nwhen it came to dealing with all the edge cases correctly."}},"/guides/concepts/servers-object-handling":{"title":"Guide to servers object handling","data":{"":"OpenAPI 3 has a servers property that can be used to define the base url for the whole document, or\nspecific operations. This guide aims to explain how this is processed.You can find the specifications definition of the servers object hereThis is fully supported, including placeholder/variable substitution, and overriding.\nThe servers object is only used for client SDK templates.It doesn't really make sense in the context of a server template, and so is ignored.","overview#Overview":"Consider an example servers block:\nservers:\n - url: '{protocol}://{host}:{port}'\n variables:\n host:\n default: localhost\n protocol:\n enum: [http, https]\n default: http\n port:\n default: '8080'\nIt defines a single server, with three variables.This will generate a ApiClientServers object that you can use to create a basePath like so:\nconst client = new ApiClient({\n// basePath will be https://localhost:80\nbasePath: ApiClientServers\n .server(\"{protocol}://{host}:{port}\") // the url template determines the build function\n .build(\n \"https\", // string literal union to form the enum\n undefined, // pass undefined to take the default\n \"80\", // override defaults\n )\n})\nIf you pass no args to build, the defaults from the specification are used:\nconst client = new ApiClient({\n// basePath will be http://localhost:8080\nbasePath: ApiClientServers\n .server(\"{protocol}://{host}:{port}\")\n .build()\n})\nYou can also take the default (first) server like so:\nconst client = new ApiClient({\n// basePath will be http://localhost:8080\nbasePath: ApiClientServers\n .server()\n .build()\n})","operation-specific-overrides#Operation specific overrides":"You can specify servers overrides at the path, or individual operation level. The most specific servers block\nwill be used for a given operation.For example, override the url for all operations under the /attachments route:\npaths:\n /attachments:\n servers:\n - url: 'https://attachments.example.com'\nWhen overrides are specified, an additional basePath positional argument will be added to the operation, defaulting\nto the first overridden server with default placeholder values.\nexport class ApiClient {\n async uploadAttachment(\n p: { ... },\n // Overridden server param\n basePath:\n | Server<\"uploadAttachment_ApiClient\">\n | string = ApiClientServers.operations\n .uploadAttachment()\n .build(),\n timeout?: number,\n opts: RequestInit = {},\n ): Promise>> {\n ...\n }\n}\nAs you can see the overrides for each operation are exposed as ApiClientServers.operations.() following\nthe same pattern as the root servers.","configuration#Configuration":"This behavior is optional, and be turned off by passing:\n--enable-typed-base-paths=false\nWhen disabled basePath: string parameters will still be added to operations that have a servers override, but\nno code based on the url or variables will be generated.See also CLI reference"}},"/overview/compatibility":{"title":"Compatibility Tables","data":{"":"This page aims to document which parts of the openapi 3.1.0 specification is supported.\nIt may not be totally complete / accurate, but it should be broadly correct and give you\nan understanding of what does / doesn't work.\nIf something you need isn't supported yet, please raise a Github\nissue\ndetailing your use-case, and we can work together to get support added / extended.We will also accept pull requests where implemented functionality follows the OpenAPI\nspecification,\nand the output code is of a high quality in terms of developer experience and robustness. See\nCONTRIBUTING.md\nto get started","tldr#tldr;":"Most common functionality used by JSON based APIs should work.\nGreat support for paths using application/json request / response bodies\nComprehensive support for most schema properties, including json validation stuff like minLength,\nbut only for json content types. Notable exceptions:\nreadonly is currently implemented incorrectly\ndiscriminator is ignored, but union / intersection types will be generated based on anyOf / allOf so\nthis isn't often an issue in practice\nNo support for security schemes, you'll need to fudge these as header parameters, or implement out-of-band\nfor the specification for now.\nNo support for webhooks / callbacks yet","legend#Legend":"Symbol\tMeaning\t✅/🚧\tSupported in some way. May be incomplete\t🚫\tNot supported, likely to be supported eventually\tN/A\tIgnored, unlikely to be used for anything","root-openapi-object#Root OpenAPI Object":"Root object of openapi documents. A ✅ means at least some support for this field - click through to the table\nfor each attribute for further details.\nAttribute\tSupported\tNotes\topenapi\t✅\tEither 3.1.x or 3.0.x is supported\tinfo\tN/A\tIgnored\tjsonSchemaDialect\t🚫\tNot yet supported\tservers\t✅\tUsed by client SDK templates\tpaths\t✅\t\twebhooks\t🚫\tNot yet supported. Emulate by defining as normal paths.\tcomponents\t✅\t\tsecurity\t🚫\tNot yet supported. Implement out of band or using header parameters.\ttags\t✅\tOptionally used to split output into multiple files\texternalDocs\tN/A\tIgnored","sub-objects#Sub-objects":"","reference-object#Reference Object":"Reference objects are supported to be used in place of the actual object definition anywhere in the documents.\nThey can also cross files (and maybe urls - needs testing).\nIt's recommended to use $ref objects as much as possible. It both promotes re-use, and also allows control\nover the naming of the type / schema in the generated code.\nExample:\n requestBody:\n required: true\n content:\n application/json:\n schema:\n $ref: \"#/components/schemas/ExampleSchema\"\nAttribute\tSupported\tNotes\t$ref\t✅\t$ref support is robust, and works correctly across multiple input files.\tsummary\tN/A\tIgnored\tdescription\tN/A\tIgnored","server-object#Server Object":"Used by the client SDKs to generate builders for basePath's and override parameters.See servers object guide for detailed explanation\nof how this is handled.\nAttribute\tSupported\tNotes\turl\t✅\tOptionally used to type client SDK basePath configuration\tdescription\tN/A\tIgnored\tvariables\t✅","components-object#Components Object":"Technically you can define any \"components\" you like, and $refs to them will work, regardless\nof if they appear in the official specification.The table indicates what will actually typically be used for anything right now.\nAttribute\tSupported\tNotes\tschemas\t✅\t\tresponses\t✅\t\tparameters\t✅\t\texamples\tN/A\t\trequestBodies\t✅\t\theaders\t✅\t\tsecuritySchemes\t🚫\tNot yet supported\tlinks\t🚫\tNot yet supported\tcallbacks\t🚫\tNot yet supported\tpathItems\t✅","paths-object#Paths Object":"Paths are well supported.\nAttribute\tSupported\tNotes\t{path}\t✅","path-item-object#Path Item Object":"All common http methods are supported.\nAttribute\tSupported\tNotes\tsummary\tN/A\tIgnored\tdescription\tN/A\tIgnored\tget\t✅\t\tput\t✅\t\tpost\t✅\t\tdelete\t✅\t\thead\t✅\t\tpatch\t✅\t\ttrace\t🚫\tNot yet supported\tservers\t✅\tUsed by client SDK templates\tparameters\t✅","operation-object#Operation Object":"Most things are supported. It's recommended you supply an operationId as otherwise\none will be generated from the path / http method, which is often overly verbose.\nAttribute\tSupported\tNotes\ttags\t✅\tOptionally used to split output into multiple files\tsummary\tN/A\tIgnored\tdescription\tN/A\tIgnored\texternalDocs\tN/A\tIgnored\toperationId\t✅\tUsed to generate names on types / methods / interfaces\tparameters\t✅\t\trequestBody\t✅\t\tresponses\t✅\t\tcallbacks\t🚫\tNot yet supported\tdeprecated\t🚫\tNot yet supported\tsecurity\t🚫\tNot yet supported\tservers\t✅\tUsed by client SDK templates","parameter-object#Parameter Object":"Whilst attributes like style and explode are not yet supported, for most common parameter use-cases\neverything should just work as you'd guess/expect.\nAttribute\tSupported\tNotes\tname\t✅\t\tin\t✅/🚧\tEverything supported apart from \"cookie\".\tdescription\tN/A\tIgnored\trequired\t✅\t\tdeprecated\tN/A\tIgnored\tallowEmptyValue\t🚫\tUse schema minLength: 1 to prevent empty string values in query parameters\tstyle\t🚫\tNot yet supported\texplode\t🚫\tNot yet supported\tallowReserved\t🚫\tUse schema pattern to emulate\tschema\t✅\t\texample\tN/A\tIgnored\texamples\tN/A\tIgnored\tcontent\t🚫\tNot yet supported","request-body-object#Request Body Object":"Well-supported for application/json content types. Support for form data, and file uploads, etc\nplanned to come soon.\nAttribute\tSupported\tNotes\tdescription\tN/A\tIgnored\tcontent\t✅/🚧\tOnly media types of application/json work properly.\trequired\t✅","media-type-object#Media Type Object":"Attribute\tSupported\tNotes\tschema\t✅\t\texample\tN/A\tIgnored\texamples\tN/A\tIgnored\tencoding\t🚫\tNot yet supported","responses-object#Responses Object":"Well supported.\nAttribute\tSupported\tNotes\tdefault\t✅\t\t{http-status-code}\t✅","response-object#Response Object":"Generally well-supported for application/json content types.\nAttribute\tSupported\tNotes\tdescription\tN/A\tIgnored\theaders\t🚫\tNot yet supported\tcontent\t✅/🚧\tOnly media types of application/json work properly.\tlinks\t🚫\tNot yet supported","header-object#Header Object":"Attribute\tSupported\tNotes\tdescription\tN/A\tIgnored\tschema\t✅\tComplex schemas for headers may not work. Stick to string / number if possible.","tag-object#Tag Object":"Tags are only used for code organization purposes, when passing the --grouping-strategy first-tag\nCLI option.\nAttribute\tSupported\tNotes\tname\t✅\tOptionally used to split output into multiple files\tdescription\tN/A\tIgnored\texternalDocs\tN/A\tIgnored","schema-object#Schema Object":"The majority of attributes that can be specified by schema objects are supported, and accurately match the underlying\nopenapi specification / json schema validation specifications.Most notable exception is readOnly / writeOnly which are currently implemented incorrectly, planned to be addressed\nas a breaking change prior to v1.\nAttribute\tSupported\tNotes\ttitle\tN/A\t\tmultipleOf\t✅\tApplies to type: number\tmaximum\t✅\tApplies to type: number\texclusiveMaximum\t✅\tApplies to type: number\tminimum\t✅\tApplies to type: number\texclusiveMinimum\t✅\tApplies to type: number\tmaxLength\t✅\tApplies to type: string\tminLength\t✅\tApplies to type: string\tpattern\t✅\tSupport for type: string\tmaxItems\t✅\tApplies to type: array\tminItems\t✅\tApplies to type: array\tuniqueItems\t✅\tApplies to type: array\tmaxProperties\t🚫\tNot yet supported\tminProperties\t🚫\tNot yet supported\trequired\t✅\tControls whether undefined is allowed for each value in properties\tenum\t✅\tApplies to type: number and type: string\ttype\t✅\t\tnot\t🚫\tNot yet supported\tallOf\t✅\tProduces a intersection type like A & B\toneOf\t✅\tProduces a union type like A | B\tanyOf\t✅\tProduces a union type like A | B\titems\t✅\tApplies to type: array\tproperties\t✅\tApplies to type: object\tadditionalProperties\t✅/🚧\tFairly comprehensive support, produces Record or unknown/any (dependent on --ts-allow-any)\tformat\t✅/🚧\tLimited support for format email and date-time\tdefault\t✅\t\tnullable\t✅\tAlso supports type: null as an alternative\tdiscriminator\t🚫\tIgnored. Union / Intersection types are usd based on anyOf / allOf / oneOf.\treadOnly\t🚫\tProduces readonly modifiers, but this behavior is incorrect\twriteOnly\t🚫\tNot yet supported\texample\tN/A\tIgnored\texternalDocs\tN/A\tIgnored\tdeprecated\t🚫\tNot yet supported\txml\t🚫\tNot yet supported","completely-unsupported-things#Completely unsupported things":"The following objects are completely unsupported at this stage.","encoding-object#Encoding Object":"Attribute\tSupported\tNotes\tcontentType\t🚫\tNot yet supported\theaders\t🚫\tNot yet supported\tstyle\t🚫\tNot yet supported\texplode\t🚫\tNot yet supported\tallowReserved\t🚫\tNot yet supported","callback-object#Callback Object":"The callback object is completely unsupported.\nAttribute\tSupported\tNotes\t\\{expression\\}\t🚫","link-object#Link Object":"The link object is completely unsupported.\nAttribute\tSupported\tNotes\toperationRef\t🚫\t\toperationId\t🚫\t\tparameters\t🚫\t\trequestBody\t🚫\t\tdescription\tN/A\t\tserver\t🚫","discriminator-object#Discriminator Object":"The discriminator object is completely unsupported.\nAttribute\tSupported\tNotes\tpropertyName\t🚫\t\tmapping\t🚫","xml-object#XML Object":"The XML object is completely unsupported.\nAttribute\tSupported\tNotes\tname\t🚫\t\tnamespace\t🚫\t\tprefix\t🚫\t\tattribute\t🚫\t\twrapped\t🚫","security-scheme-object#Security Scheme Object":"The security scheme object is completely unsupported.\nAttribute\tSupported\tNotes\ttype\t🚫\t\tdescription\t🚫\t\tname\t🚫\t\tin\t🚫\t\tscheme\t🚫\t\tbearerFormat\t🚫\t\tflows\t🚫\t\topenIdConnectUrl\t🚫","oauth-flows-object#OAuth Flows Object":"The oauth flows object is completely unsupported.\nAttribute\tSupported\tNotes\timplicit\t🚫\t\tpassword\t🚫\t\tclientCredentials\t🚫\t\tauthorizationCode\t🚫","oauth-flow-object#OAuth Flow Object":"The oauth flow object is completely unsupported.\nAttribute\tSupported\tNotes\tauthorizationUrl\t🚫\t\ttokenUrl\t🚫\t\trefreshUrl\t🚫\t\tscopes\t🚫","security-requirement-object---patterned-fields#Security Requirement Object - Patterned Fields":"The security requirement object is completely unsupported.\nAttribute\tSupported\tNotes\t\\{name\\}\t🚫"}},"/overview/schema-first-design":{"title":"Why schema first","data":{"":"Broadly speaking there are two approaches people take to maintaining API specifications:\nSchema first, where you write the schema by hand\nCode first, where you generate the schema from your code\nThis project being a code generator from API specification files is on the schema first side of the debate, but why?Ultimately this is fairly subjective, but there are four primary motivators that lead us to believe schema first\nis the better approach.","longevity#Longevity":"APIs are forever,\nchanging them in backwards incompatible ways is hard/expensive, or sometimes not possible.With that in mind, we believe it's important to be thoughtful about your API design, and\nthat writing an explicit specification/contract is a great forcing function to accomplish this.Additionally, programming languages / frameworks come and go - they are an implementation detail,\nand subject to change as business requirements evolve.\nOpenAPI (originally Swagger) has been around for over a decade now, and we're confident it'll be around for a long time.","common-language#Common Language":"Many large projects / systems will involve multiple programming languages. For example, you might have a Java backend,\nKotlin Android app, Swift iOS app, and Typescript web frontend.For writing your API contracts using OpenAPI up front, you create a common ground for developers of all languages to discuss\nand hash out the details.","constraints#Constraints":"General purpose programming languages are very flexible. If you try hard enough, you can probably implement it.\nSpecifications like OpenAPI on the other hand are more rigid and constraining.We believe it's better to lean into this and design your system such that it can be represented fully by a\nspecification, rather than attempt to generate a specification from the implementation and lose\ninformation/nuance in the process.","separation#Separation":"A good specification not only defines the API contract, but also includes a lot of supplementary information such as examples,\nand documentation.Generating a good specification from your code, therefore requires including all this extra metadata in the code, which\ncan make the code more difficult to work with.We prefer to separate these concerns out into the specification, and keep the implementation code leaner and simpler."}},"/getting-started/quick-start":{"title":"Quick Start","data":{"":"Install the latest NodeJS LTS release, though any recent version of NodeJS will likely work.You'll also need either an OpenAPI v3 / v3.1, or TypeSpec API specification to generate from. You can\nprovide OpenAPI specifications as YAML or JSON, local files or remote urls - we'll load them all! 🚀Cross-file references are also supported, so don't worry about pre-processing the input.You can check the version we develop and test against here.\nFirst install the CLI and the required runtime packages to your project:\nnpm i --dev @nahkies/openapi-code-generator\nnpm i @nahkies/typescript-fetch-runtime\npnpm add --dev @nahkies/openapi-code-generator\npnpm add @nahkies/typescript-fetch-runtime\nyarn add --dev @nahkies/openapi-code-generator\nyarn add @nahkies/typescript-fetch-runtime\nbun add --dev @nahkies/openapi-code-generator\nbun add @nahkies/typescript-fetch-runtime\nYou could also install the CLI globally if you prefer, but it's best to version it per project.This will generate the client to ./src/generated/clients/some-serviceYou can provide either a local file path or url for the input file.\nnpm run openapi-code-generator \\\n--input ./openapi.yaml \\ # or https://example.com/openapi.{json,yaml}\n--output ./src/generated/clients/some-service \\\n--template typescript-fetch\npnpm run openapi-code-generator \\\n--input ./openapi.yaml \\ # or https://example.com/openapi.{json,yaml}\n--output ./src/generated/clients/some-service \\\n--template typescript-fetch\nyarn openapi-code-generator \\\n--input ./openapi.yaml \\ # or https://example.com/openapi.{json,yaml}\n--output ./src/generated/clients/some-service \\\n--template typescript-fetch\nbun run openapi-code-generator \\\n--input ./openapi.yaml \\ # or https://example.com/openapi.{json,yaml}\n--output ./src/generated/clients/some-service \\\n--template typescript-fetch\nUse your new type-safe client, and never worry about making a typo in a url or parameter name again.\nLet the typescript compiler take care of checking that for you.See Guide to typescript-fetch client template for more details.\nFirst install the CLI and the required runtime packages to your project:\nnpm i --dev @nahkies/openapi-code-generator\nnpm i axios @nahkies/typescript-axios-runtime\npnpm add --dev @nahkies/openapi-code-generator\npnpm add axios @nahkies/typescript-axios-runtime\nyarn add --dev @nahkies/openapi-code-generator\nyarn add axios @nahkies/typescript-axios-runtime\nbun add --dev @nahkies/openapi-code-generator\nbun add axios @nahkies/typescript-axios-runtime\nYou could also install the CLI globally if you prefer, but it's best to version it per project.This will generate the client to ./src/generated/clients/some-serviceYou can provide either a local file path or url for the input file.\nnpm run openapi-code-generator \\\n--input ./openapi.yaml \\ # or https://example.com/openapi.{json,yaml}\n--output ./src/generated/clients/some-service \\\n--template typescript-axios\npnpm run openapi-code-generator \\\n--input ./openapi.yaml \\ # or https://example.com/openapi.{json,yaml}\n--output ./src/generated/clients/some-service \\\n--template typescript-axios\nyarn openapi-code-generator \\\n--input ./openapi.yaml \\ # or https://example.com/openapi.{json,yaml}\n--output ./src/generated/clients/some-service \\\n--template typescript-axios\nbun run openapi-code-generator \\\n--input ./openapi.yaml \\ # or https://example.com/openapi.{json,yaml}\n--output ./src/generated/clients/some-service \\\n--template typescript-axios\nUse your new type-safe client, and never worry about making a typo in a url or parameter name again.\nLet the typescript compiler take care of checking that for you.See Guide to typescript-axios client template for more details.\nFirst install the CLI and the required runtime packages to your project:\nnpm i --dev @nahkies/openapi-code-generator @types/koa @types/koa__router\nnpm i @nahkies/typescript-koa-runtime @koa/cors @koa/router koa koa-body zod\npnpm add --dev @nahkies/openapi-code-generator @types/koa @types/koa__router\npnpm add @nahkies/typescript-koa-runtime @koa/cors @koa/router koa koa-body zod\nyarn add --dev @nahkies/openapi-code-generator @types/koa @types/koa__router\nyarn add @nahkies/typescript-koa-runtime @koa/cors @koa/router koa koa-body zod\nbun add --dev @nahkies/openapi-code-generator @types/koa @types/koa__router\nbun add @nahkies/typescript-koa-runtime @koa/cors @koa/router koa koa-body zod\nYou could also install the CLI globally if you prefer, but it's best to version it per project.You can provide either a local file path or url for the input file.This will generate the server router and validation logic to ./src/generated\nnpm run openapi-code-generator \\\n--input ./openapi.yaml \\ # or https://example.com/openapi.{json,yaml}\n--output ./src/generated \\\n--template typescript-koa\npnpm run openapi-code-generator \\\n--input ./openapi.yaml \\ # or https://example.com/openapi.{json,yaml}\n--output ./src/generated \\\n--template typescript-koa\nyarn openapi-code-generator \\\n--input ./openapi.yaml \\ # or https://example.com/openapi.{json,yaml}\n--output ./src/generated \\\n--template typescript-koa\nbun run openapi-code-generator \\\n--input ./openapi.yaml \\ # or https://example.com/openapi.{json,yaml}\n--output ./src/generated \\\n--template typescript-koa\nImplement handlers for your server, and be confident that they match what the client expects. Everything\nwill be strongly typed, so typos are surfaced at development time, not runtime.By default the runtime validation is using zod.See Guide to typescript-koa client template for more details.","cli-options#CLI options":"See the cli reference for the full range of supported options, or try\nnpm run openapi-code-generator --help\npnpm run openapi-code-generator --help\nyarn openapi-code-generator --help\nbun run openapi-code-generator --help","typespec-specifications#Typespec specifications":"If you want to use typespec instead of openapi3\nas your input specifications, additionally install the typespec compiler and supporting packages.\nnpm i --dev @typespec/compiler @typespec/http @typespec/openapi @typespec/openapi3 @typespec/versioning\npnpm add --dev @typespec/compiler @typespec/http @typespec/openapi @typespec/openapi3 @typespec/versioning\nyarn add --dev @typespec/compiler @typespec/http @typespec/openapi @typespec/openapi3 @typespec/versioning\nbun add --dev @typespec/compiler @typespec/http @typespec/openapi @typespec/openapi3 @typespec/versioning\nDepending on how your typespec specification is written, you may need to install additional packages such\nas @typespec/rest.You can then generate like so:\nnpm run openapi-code-generator \\\n --input ./some-service.tsp \\ # or https://example.com/some-service.tsp\n --input-type=typespec \\\n --output ./src/generated/clients/some-service \\\n --template typescript-fetch\npnpm run openapi-code-generator \\\n --input ./some-service.tsp \\ # or https://example.com/some-service.tsp\n --input-type=typespec \\\n --output ./src/generated/clients/some-service \\\n --template typescript-fetch\nyarn openapi-code-generator \\\n --input ./some-service.tsp \\ # or https://example.com/some-service.tsp\n --input-type=typespec \\\n --output ./src/generated/clients/some-service \\\n --template typescript-fetch\nbun run openapi-code-generator \\\n --input ./some-service.tsp \\ # or https://example.com/some-service.tsp\n --input-type=typespec \\\n --output ./src/generated/clients/some-service \\\n --template typescript-fetch\nYou can see examples of code generated from typespec specifications here"}},"/guides/client-templates/typescript-angular":{"title":"Using the typescript-angular template","data":{"":"this is the least battle tested of the templates and most likely to have critical bugs\nThe typescript-angular template outputs a client SDK based on the Angular HttpClient that gives the following:\nTyped methods to call each endpoint returning an RxJS Observable\nIt does not yet support runtime validation/parsing - compile time type safety only at this stage.See integration-tests/typescript-angular for more samples.","install-dependencies#Install dependencies":"First install the CLI to your project:\nnpm i --dev @nahkies/openapi-code-generator\npnpm add --dev @nahkies/openapi-code-generator\nyarn add --dev @nahkies/openapi-code-generator\nbun add --dev @nahkies/openapi-code-generator\nSee also quick start guide","run-generation#Run generation":"npm run openapi-code-generator \\\n --input ./openapi.yaml \\\n --input-type openapi3 \\\n --output ./src/app/clients/some-service \\\n --template typescript-angular \\\n --schema-builder zod\npnpm run openapi-code-generator \\\n --input ./openapi.yaml \\\n --input-type openapi3 \\\n --output ./src/app/clients/some-service \\\n --template typescript-angular \\\n --schema-builder zod\nyarn openapi-code-generator \\\n --input ./openapi.yaml \\\n --input-type openapi3 \\\n --output ./src/app/clients/some-service \\\n --template typescript-angular \\\n --schema-builder zod\nbun run openapi-code-generator \\\n --input ./openapi.yaml \\\n --input-type openapi3 \\\n --output ./src/app/clients/some-service \\\n --template typescript-angular \\\n --schema-builder zod\nnpm run openapi-code-generator \\\n --input ./typespec.tsp \\\n --input-type typespec \\\n --output ./src/app/clients/some-service \\\n --template typescript-angular \\\n --schema-builder zod\npnpm run openapi-code-generator \\\n --input ./typespec.tsp \\\n --input-type typespec \\\n --output ./src/app/clients/some-service \\\n --template typescript-angular \\\n --schema-builder zod\nyarn openapi-code-generator \\\n --input ./typespec.tsp \\\n --input-type typespec \\\n --output ./src/app/clients/some-service \\\n --template typescript-angular \\\n --schema-builder zod\nbun run openapi-code-generator \\\n --input ./typespec.tsp \\\n --input-type typespec \\\n --output ./src/app/clients/some-service \\\n --template typescript-angular \\\n --schema-builder zod","using-the-generated-code#Using the generated code":"Running the above will output these files into ./src/app/clients/some-service:\n./api.module.ts: exports a class ApiModule as an NgModule\n./client.service.ts: exports a class ApiClient as injectable Angular service\n./models.ts: exports typescript types\n./schemas.ts: exports runtime parsers using the chosen schema-builder (default zod)\nOnce generated usage should look something like this:\n// Root Angular module\n@NgModule({\n declarations: [AppComponent],\n imports: [BrowserModule, AppRoutingModule, ApiModule],\n providers: [],\n bootstrap: [AppComponent],\n})\nexport class AppModule {}\n@Component({\n selector: \"app-root\",\n templateUrl: \"./app.component.html\",\n styleUrls: [\"./app.component.css\"],\n})\nexport class AppComponent {\n // inject into your component\n constructor(client: ApiClient) {\n client.updateTodoListById({listId: \"1\", requestBody: {name: \"Foo\"}}).subscribe((next) => {\n if (next.status === 200) {\n // TODO: body is currently incorrectly `unknown` here\n console.log(next.body.id)\n }\n })\n }\n}"}},"/guides/client-templates/typescript-fetch":{"title":"Using the typescript-fetch template","data":{"":"The typescript-fetch template outputs a client SDK based on the fetch api that gives the following:\nTyped methods to call each endpoint\nSupport for passing a timeout, abort signals are still respected\nOptionally, runtime response validation\nRuntime request parameter validation is not currently supported.See integration-tests/typescript-fetch for more samples.Dependencies:","install-dependencies#Install dependencies":"First install the CLI and the required runtime packages to your project:\nnpm i --dev @nahkies/openapi-code-generator\nnpm i @nahkies/typescript-fetch-runtime\npnpm add --dev @nahkies/openapi-code-generator\npnpm add @nahkies/typescript-fetch-runtime\nyarn add --dev @nahkies/openapi-code-generator\nyarn add @nahkies/typescript-fetch-runtime\nbun add --dev @nahkies/openapi-code-generator\nbun add @nahkies/typescript-fetch-runtime\nSee also quick start guide\nIf you're using an older version of NodeJS, or targeting very old web browsers,\nyou may need a polyfill like node-fetch-native","run-generation#Run generation":"Experimental support for runtime response validation is available behind the --enable-runtime-response-validation\nflag.\nnpm run openapi-code-generator \\\n --input ./openapi.yaml \\\n --input-type openapi3 \\\n --output ./src/clients/some-service \\\n --template typescript-fetch \\\n --schema-builder zod\npnpm run openapi-code-generator \\\n --input ./openapi.yaml \\\n --input-type openapi3 \\\n --output ./src/clients/some-service \\\n --template typescript-fetch \\\n --schema-builder zod\nyarn openapi-code-generator \\\n --input ./openapi.yaml \\\n --input-type openapi3 \\\n --output ./src/clients/some-service \\\n --template typescript-fetch \\\n --schema-builder zod\nbun run openapi-code-generator \\\n --input ./openapi.yaml \\\n --input-type openapi3 \\\n --output ./src/clients/some-service \\\n --template typescript-fetch \\\n --schema-builder zod\nnpm run openapi-code-generator \\\n --input ./typespec.tsp \\\n --input-type typespec \\\n --output ./src/clients/some-service \\\n --template typescript-fetch \\\n --schema-builder zod\npnpm run openapi-code-generator \\\n --input ./typespec.tsp \\\n --input-type typespec \\\n --output ./src/clients/some-service \\\n --template typescript-fetch \\\n --schema-builder zod\nyarn openapi-code-generator \\\n --input ./typespec.tsp \\\n --input-type typespec \\\n --output ./src/clients/some-service \\\n --template typescript-fetch \\\n --schema-builder zod\nbun run openapi-code-generator \\\n --input ./typespec.tsp \\\n --input-type typespec \\\n --output ./src/clients/some-service \\\n --template typescript-fetch \\\n --schema-builder zod","using-the-generated-code#Using the generated code":"Running the above will output these files into ./src/clients/some-service:\n./client.ts: exports a class ApiClient that implements methods for calling each endpoint\n./models.ts: exports typescript types\n./schemas.ts: exports runtime parsers using the chosen schema-builder (default zod)\nOnce generated usage should look something like this:\nconst client = new ApiClient({\n basePath: `http://localhost:${address.port}`,\n defaultHeaders: {\n \"Content-Type\": \"application/json\",\n Authorisation: \"Bearer: \", // can pass auth headers here\n },\n})\nconst res = await client.createTodoListItem({\n listId: list.id,\n requestBody: {content: \"test item\"},\n // optionally pass a timeout (ms), or any arbitrary fetch options (eg: an abort signal)\n // timeout?: number,\n // opts?: RequestInit\n})\n// checking the status code narrows the response body types (ie: remove error types from the type union)\nif (res.status !== 200) {\n throw new Error(\"failed to create item\")\n}\n// body will be typed correctly\nconst body = await res.json()\nconsole.log(`id is: ${body.id}`)"}},"/guides/client-templates/typescript-axios":{"title":"Using the typescript-axios template","data":{"":"The typescript-axios template outputs a client SDK based on the axios that gives the following:\nTyped methods to call each endpoint\nOptionally, runtime response validation\nIt follows the standard axios pattern of rejecting any response that isn't 2xx and thus can't provide typed\nerror responses. If you'd like to have strong typing over your error responses consider using the typescript-fetch template.Runtime request parameter validation is not currently supported.See integration-tests/typescript-axios for more samples.","install-dependencies#Install dependencies":"First install the CLI and the required runtime packages to your project:\nnpm i --dev @nahkies/openapi-code-generator\nnpm i axios @nahkies/typescript-axios-runtime\npnpm add --dev @nahkies/openapi-code-generator\npnpm add axios @nahkies/typescript-axios-runtime\nyarn add --dev @nahkies/openapi-code-generator\nyarn add axios @nahkies/typescript-axios-runtime\nbun add --dev @nahkies/openapi-code-generator\nbun add axios @nahkies/typescript-axios-runtime\nSee also quick start guide","run-generation#Run generation":"Experimental support for runtime response validation is available behind the --enable-runtime-response-validation\nflag.\nnpm run openapi-code-generator \\\n --input ./openapi.yaml \\\n --input-type openapi3 \\\n --output ./src/clients/some-service \\\n --template typescript-axios \\\n --schema-builder zod\npnpm run openapi-code-generator \\\n --input ./openapi.yaml \\\n --input-type openapi3 \\\n --output ./src/clients/some-service \\\n --template typescript-axios \\\n --schema-builder zod\nyarn openapi-code-generator \\\n --input ./openapi.yaml \\\n --input-type openapi3 \\\n --output ./src/clients/some-service \\\n --template typescript-axios \\\n --schema-builder zod\nbun run openapi-code-generator \\\n --input ./openapi.yaml \\\n --input-type openapi3 \\\n --output ./src/clients/some-service \\\n --template typescript-axios \\\n --schema-builder zod\nnpm run openapi-code-generator \\\n --input ./typespec.tsp \\\n --input-type typespec \\\n --output ./src/clients/some-service \\\n --template typescript-axios \\\n --schema-builder zod\npnpm run openapi-code-generator \\\n --input ./typespec.tsp \\\n --input-type typespec \\\n --output ./src/clients/some-service \\\n --template typescript-axios \\\n --schema-builder zod\nyarn openapi-code-generator \\\n --input ./typespec.tsp \\\n --input-type typespec \\\n --output ./src/clients/some-service \\\n --template typescript-axios \\\n --schema-builder zod\nbun run openapi-code-generator \\\n --input ./typespec.tsp \\\n --input-type typespec \\\n --output ./src/clients/some-service \\\n --template typescript-axios \\\n --schema-builder zod","using-the-generated-code#Using the generated code":"Running the above will output these files into ./src/clients/some-service:\n./client.ts: exports a class ApiClient that implements methods for calling each endpoint\n./models.ts: exports typescript types\n./schemas.ts: exports runtime parsers using the chosen schema-builder (default zod)\nOnce generated usage should look something like this:\nconst client = new ApiClient({\n // Pass a axios instance if you wish to use interceptors for auth, logging, etc\n // axios: axios.create({...}),\n basePath: `http://localhost:${address.port}`,\n defaultHeaders: {\n \"Content-Type\": \"application/json\",\n Authorisation: \"Bearer: \", // can pass auth headers here\n },\n})\n// rejects if status code isn't 2xx, following typical axios behavior\nconst res = await client.createTodoListItem({\n listId: list.id,\n requestBody: {content: \"test item\"},\n // optionally pass a timeout (ms), or any arbitrary axios options\n // timeout?: number,\n // opts?: AxiosRequestConfig\n})\n// data will be typed correctly\nconsole.log(`id is: ${res.data.id}`)"}},"/guides/concepts/extract-inline-schemas":{"title":"Extract inline schemas","data":{"":"We have experimental support for \"extracting inline schemas\" behind the\n--extract-inline-schemas / OPENAPI_EXTRACT_INLINE_SCHEMAS=true configuration flag.","what-does-this-mean#What does this mean?":"There are basically two ways you can define schemas in your openapi specifications:\nNamed schemas\nInline schemas\nThese are handled differently by code generation. Enabling --extract-inline-schemas aims to\nmake inline schemas emit similar code to named schemas.","named-schema-example#Named schema example":"Normally when writing openapi specifications it is desirable to make use of $ref and define your schemas as named\ncomponents.\npaths:\n /list/{listId}:\n parameters:\n - $ref: '#/components/parameters/listId'\n get:\n operationId: getTodoListById\n responses:\n 200:\n description: 'success'\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/TodoList'\ncomponents:\n schemas:\n TodoList:\n type: object\n required:\n - id\n - name\n - totalItemCount\n - incompleteItemCount\n - created\n properties:\n id:\n type: string\n format: uuid\n name:\n type: string\n totalItemCount:\n type: number\n incompleteItemCount:\n type: number\n created:\n type: string\n format: date-time\nWhen we run code generation for this, we expect a type and a schema for the TodoList to be generated, something like:\nimport {z} from 'zod'\nexport type t_TodoList = {\n id: string\n name: string\n totalItemCount: number\n incompleteItemCount: number\n created: string\n}\nexport const s_TodoList = z.object({\n id: z.string(),\n name: z.string(),\n totalItemCount: z.coerce.number(),\n incompleteItemCount: z.coerce.number(),\n created: z.string().datetime({ offset: true }),\n})\nThis is useful, as it means that we can easily reference the type, or use the schema as we require.","inline-schema-example#Inline Schema Example":"However, not everyone will write their specifications using named $refs, and instead inline schemas may be used.\nThis is especially prolific when generating the specification from implementation code in our experience.Consider the same example as above, but with the schema inlined:\npaths:\n /list/{listId}:\n parameters:\n - $ref: '#/components/parameters/listId'\n get:\n operationId: getTodoListById\n responses:\n 200:\n description: 'success'\n content:\n application/json:\n schema:\n type: object\n required:\n - id\n - name\n - totalItemCount\n - incompleteItemCount\n - created\n properties:\n id:\n type: string\n format: uuid\n name:\n type: string\n totalItemCount:\n type: number\n incompleteItemCount:\n type: number\n created:\n type: string\n format: date-time\ncomponents:\n schemas: {}\nBy default, this will be emitted as in-line types / schemas\nexport type GetTodoListById = (\n params: Params,\n respond: GetTodoListByIdResponder,\n ctx: RouterContext,\n) => Promise<\n | KoaRuntimeResponse\n | Response<\n 200,\n {\n id: string\n name: string\n totalItemCount: number\n incompleteItemCount: number\n created: string\n }\n >\n | Response\n | Response\n>\nconst getTodoListByIdResponseValidator = responseValidationFactory(\n [\n [\n \"200\",\n z.object({\n id: z.string(),\n name: z.string(),\n totalItemCount: z.coerce.number(),\n incompleteItemCount: z.coerce.number(),\n created: z.string().datetime({ offset: true }),\n }),\n ],\n [\"4XX\", s_Error],\n ],\n z.undefined(),\n)\nrouter.get(\"getTodoListById\", \"/list/:listId\", async (ctx, next) => {\n // ...\n const responder = {\n with200() {\n return new KoaRuntimeResponse<{\n id: string\n name: string\n totalItemCount: number\n incompleteItemCount: number\n created: string\n }>(200)\n }\n }\n // ...\n})","with---extract-inline-schemas-enabled#With --extract-inline-schemas enabled":"Notice how this:\nCreates a lot of duplication, we have to repeat the definition anytime it is used\nMakes it inconvenient, or impossible to reference the type/schema in our implementation code\nWith --extract-inline-schemas enabled, the code generator will synthesis a name for each inline schema based on\nits usage, and emit exported types/schemas, eg:\nexport type t_getTodoListByIdJson200Response = {\n id: string\n name: string\n totalItemCount: number\n incompleteItemCount: number\n created: string\n}\nexport const s_getTodoListByIdJson200Response = z.object({\n id: z.string(),\n name: z.string(),\n totalItemCount: z.coerce.number(),\n incompleteItemCount: z.coerce.number(),\n created: z.string().datetime({ offset: true }),\n})\nThis can be a handy trick to make the code generated from schemas you don't own/control easier to work with. In general\nyou should prefer to improve the specifications to be more suitable for code generation, which generally also improves\nthe result of documentation tools like Redoc"}},"/guides/server-templates/typescript-koa":{"title":"Using the typescript-koa template","data":{"":"The typescript-koa template outputs scaffolding code that handles the following:\nBuilding a @koa/router instance with all routes in the openapi specification\nGenerating types and runtime schema parsers for all request parameters/bodies and response bodies\nGenerating types for route implementations that receive validated inputs, and have return types that are additionally\nvalidated at runtime prior to sending the response\n(Optionally) Actually starting the server and binding to a port\nSee integration-tests/typescript-koa for more samples.","install-dependencies#Install dependencies":"First install the CLI and the required runtime packages to your project:\nnpm i --dev @nahkies/openapi-code-generator @types/koa @types/koa__router\nnpm i @nahkies/typescript-koa-runtime @koa/cors @koa/router koa koa-body zod\npnpm add --dev @nahkies/openapi-code-generator @types/koa @types/koa__router\npnpm add @nahkies/typescript-koa-runtime @koa/cors @koa/router koa koa-body zod\nyarn add --dev @nahkies/openapi-code-generator @types/koa @types/koa__router\nyarn add @nahkies/typescript-koa-runtime @koa/cors @koa/router koa koa-body zod\nbun add --dev @nahkies/openapi-code-generator @types/koa @types/koa__router\nbun add @nahkies/typescript-koa-runtime @koa/cors @koa/router koa koa-body zod\nSee also quick start guide","run-generation#Run generation":"npm run openapi-code-generator \\\n --input ./openapi.yaml \\\n --input-type openapi3 \\\n --output ./src \\\n --template typescript-koa \\\n --schema-builder zod\npnpm run openapi-code-generator \\\n --input ./openapi.yaml \\\n --input-type openapi3 \\\n --output ./src \\\n --template typescript-koa \\\n --schema-builder zod\nyarn openapi-code-generator \\\n --input ./openapi.yaml \\\n --input-type openapi3 \\\n --output ./src \\\n --template typescript-koa \\\n --schema-builder zod\nbun run openapi-code-generator \\\n --input ./openapi.yaml \\\n --input-type openapi3 \\\n --output ./src \\\n --template typescript-koa \\\n --schema-builder zod\nnpm run openapi-code-generator \\\n --input ./typespec.tsp \\\n --input-type typespec \\\n --output ./src \\\n --template typescript-koa \\\n --schema-builder zod\npnpm run openapi-code-generator \\\n --input ./typespec.tsp \\\n --input-type typespec \\\n --output ./src \\\n --template typescript-koa \\\n --schema-builder zod\nyarn openapi-code-generator \\\n --input ./typespec.tsp \\\n --input-type typespec \\\n --output ./src \\\n --template typescript-koa \\\n --schema-builder zod\nbun run openapi-code-generator \\\n --input ./typespec.tsp \\\n --input-type typespec \\\n --output ./src \\\n --template typescript-koa \\\n --schema-builder zod","using-the-generated-code#Using the generated code":"Running the above will output three files into ./src:\ngenerated.ts - exports a createRouter and bootstrap function, along with associated types used to create your server\nmodels.ts - exports typescript types for schemas\nschemas.ts - exports runtime schema validators\nOnce generated usage should look something like this:\nimport {bootstrap, createRouter, CreateTodoList, GetTodoLists} from \"../generated\"\n// Define your route implementations as async functions implementing the types\n// exported from generated.ts\nconst createTodoList: CreateTodoList = async ({body}, respond) => {\n const list = await prisma.todoList.create({\n data: {\n // body is strongly typed and parsed at runtime\n name: body.name,\n },\n })\n // (recommended) the respond parameter is a strongly typed helper that\n // provides a better editor experience.\n // the response body is additionally validated against the response schema/status code at runtime\n return respond.with200().body(dbListToApiList(list))\n // (deprecated) alternatively, you can return a {status, body} object which is also strongly typed\n // pattern matching the status code against the response schema:\n // return {\n // status: 200 as const,\n // body: dbListToApiList(list)\n // }\n}\nconst getTodoLists: GetTodoLists = async ({query}) => {\n // omitted for brevity\n}\n// Starts a server listening on `port`\nbootstrap({\n router: createRouter({getTodoLists, createTodoList}),\n port: 8080,\n})","custom-koa-appconfig#Custom Koa app/config":"The provided bootstrap function has a limited range of options. For more advanced use-cases,\nsuch as https you will need to construct your own Koa app, and mount the router returned by createRouter.The only real requirement is that you provide a body parsing middleware before the router that places\na parsed request body on the ctx.body property.Eg:\nimport {createRouter} from \"../generated\"\nimport KoaBody from \"koa-body\"\nimport https from \"https\"\n// ...implement routes here\nconst app = new Koa()\n// it doesn't have to be koa-body, but it does need to put the parsed body on `ctx.body`\napp.use(KoaBody())\n// mount the generated router\nconst router = createRouter({getTodoLists, createTodoList})\napp.use(router.allowedMethods())\napp.use(router.routes())\nhttps\n .createServer(\n {\n key: \"...\",\n cert: \"...\",\n },\n app.callback(),\n )\n .listen(433)","error-handling#Error Handling":"Any errors thrown during the request processing will be wrapped in KoaRuntimeError objects,\nand tagged with the phase the error was thrown.\ninterface KoaRuntimeError extends Error {\n cause: unknown // the originally thrown exception\n phase: \"request_validation\" | \"request_handler\" | \"response_validation\"\n}\nThis allows for implementing catch-all error middleware for common concerns like failed request validation,\nor internal server errors.Eg:\nexport async function genericErrorMiddleware(ctx: Context, next: Next) {\n try {\n await next()\n } catch (err) {\n // if the request validation failed, return a 400 and include helpful\n // information about the problem\n if (KoaRuntimeError.isKoaError(err) && err.phase === \"request_validation\") {\n ctx.status = 400\n ctx.body = {\n message: \"request validation failed\",\n meta: err.cause instanceof ZodError ? {issues: err.cause.issues} : {},\n } satisfies t_Error\n return\n }\n // return a 500 and omit information from the response otherwise\n logger.error(\"internal server error\", err)\n ctx.status = 500\n ctx.body = {\n message: \"internal server error\",\n } satisfies t_Error\n }\n}"}},"/overview/about":{"title":"Welcome","data":{"":"@nahkies/openapi-code-generator is a CLI tool that aims to generate high quality typescript client SDK's,\nand API server scaffolding (routing, validation, serialization) from OpenAPI 3 specifications.Currently, OpenAPI 3.0, OpenAPI 3.1, and TypeSpec are supported an input specifications.This gives you amazing auto-complete, and compile-time safety. Typescripts expressive type system it used to\nmake the generated clients feel idomatic, and as close to handwritten as possible.\nAlready know that code generation will save you time? Jump straight in with the quick start guide","server-scaffolding-templates#Server Scaffolding Templates":"Server templates handle the routing setup, request and response validation/serialization so that you\ncan focus on the business logic.\ntypescript-koa","client-sdk-templates#Client SDK Templates":"Client templates give you a strongly typed interface to your remote server calls, ensuring that you\nnever misspell a field name or route again.\ntypescript-fetch\ntypescript-axios\ntypescript-angular","project-goal--principals#Project Goal / Principals":"To make it fun, easy and productive to generate both client and server \"glue\"\ncode from openapi 3 definitions. This is code that is tedious and error-prone to maintain by hand,\nby automating it we can reduce toil and frustration.The generated code output should be \"stable\" in the sense that it will not\narbitrarily change between generation without need (for a given version). For\nexample outputting entities in alphabetic order where possible.It should also be generated in a way that human would reasonably write it,\nthe intent is that the generated code can and should be committed to the consuming project\nrepositories, allowing it to be reviewed, and audited overtime.This is particularly useful in the case of mistakes in the generation or schemas, and also\nserves to reduce risk of adoption. There should be no lock-in - if you wish to stop using the\ncode generation, you can simply start maintaining the previously generated code by hand.The initial focus on typescript, with an intention to later support other languages. kotlin\nis the most likely candidate for a second language.","compatibility--completeness#Compatibility / Completeness":"This project should be considered beta quality, though it's getting close to a v1 release.It does not yet handle all aspects of the OpenAPI / JSON schema specification, but most common\nfeatures are implemented. In particular at the moment only JSON content types are supported properly.You can get a sense of what works by looking at the compatibility tables, or the Github issues (non-exhaustive).\nHowever often the best way is to just try it out with your API specification and see what happens!The integration tests also act as a good showcase of the sort of output you can expect.","compared-to-other-projects#Compared to other projects":"There are many similar projects out there, so why should you use this one?\nStrong emphasis on \"human like\" code output\nTackles the program space from both ends - client and server, for a single source of truth\nComprehensive runtime parsing/validation in addition to static compile time safety\nSo if you want a low risk, write-once, get strong build & runtime guarantees experience then we're worth giving a try."}},"/":{"title":"Index","data":{}},"/reference/cli-options":{"title":"CLI Options","data":{"cli-configuration-reference#CLI Configuration Reference":"All CLI options can be provided as command-line parameters, or environment variables as you prefer.","generate#Generate":"The default action is to run code generation.","required-parameters#Required Parameters":"","-i---input-value#-i --input ":"As environment variable OPENAPI_INPUTPath to the input specification to generate from. Either a local path, or a url may be provided, though not all\nspecifications will build correctly from a url.By default, this must be a OpenAPI 3.0 or OpenAPI 3.1\nspecification, in either YAML or JSON format.When used in conjunction with --input-type typespec then a TypeSpec specification can be\nsupplied instead.","-o---output-value#-o --output ":"As environment variable OPENAPI_OUTPUTdirectory to output generated code (env: )","-t---template-value#-t --template ":"As environment variable OPENAPI_TEMPLATEWhich template you wish to generate, one of:\ntypescript-koa\ntypescript-fetch\ntypescript-axios\ntypescript-angular","optional-parameters#Optional Parameters":"","--input-type-value#--input-type ":"As environment variable OPENAPI_INPUT_TYPEWhat type of input file is being provided, one of:\nopenapi3 (default)\ntypespec","--override-specification-title-value#--override-specification-title ":"As environment variable OPENAPI_OVERRIDE_SPECIFICATION_TITLEAllows overriding the info.title field of the input OpenAPI document. This field is used to generate\nsome symbol names, and so this is useful when you don't directly control the source specification, and\nwish to customize the output symbol names.","-s---schema-builder-value#-s --schema-builder ":"As environment variable OPENAPI_SCHEMA_BUILDERWhich runtime schema parsing library to use, one of:\nzod (default)\njoi","--grouping-strategy-value-experimental#--grouping-strategy (experimental)":"As environment variable OPENAPI_GROUPING_STRATEGYStrategy to use for splitting output into separate files. Set to none for a single generated.ts file, one of:\nnone don't split output, yield single generated.ts (default)\nfirst-tag group operations based on their first tag\nfirst-slug group operations based on their first route slug/segment","--enable-runtime-response-validation-experimental#--enable-runtime-response-validation (experimental)":"As environment variable whether to validate response bodies using the chosen runtime schema library.Default false\nNote: this is currently always true for server templates, and only applies to the client library templates.","--enable-typed-base-paths-client-sdks-only#--enable-typed-base-paths (client sdks only)":"As environment variable OPENAPI_ENABLE_TYPED_BASE_PATHSControls whether to generate a URL builder from the openapi specifications\narray of server urls and placeholder variables.When disabled a plain string type is used for these parameters.See servers object guide for detailed explanation\nof how this is handled.Default: true","--extract-inline-schemas-experimental#--extract-inline-schemas (experimental)":"As environment variable OPENAPI_EXTRACT_INLINE_SCHEMASGenerate names based on usage, and extract in-line schemas to be standalone types / schemas in the\ngenerated code. This is especially useful when dealing with input schemas that don't make good use\nof named $ref's.See extract-inline-schemas guide for details of how this works.Default false","--allow-unused-imports#--allow-unused-imports":"As environment variable OPENAPI_ALLOW_UNUSED_IMPORTSAllow unused imports to be emitted in generated code. Offered as an escape hatch if any bugs\nin the unused-import elimination occur.Default false","--ts-allow-any#--ts-allow-any":"As environment variable OPENAPI_TS_ALLOW_ANYDetermines whether to use any or unknown when generating types for schemas that don't have\nconcrete definitions. Eg: additionalProperties: true or {} schemas.Using unknown will push you towards using type guards / making runtime checks before interacting\nwith the model and should generally result in more robust code, whilst any may be more convenient\nduring rapid prototyping.Default: false (use unknown rather than any)\nInput schema\t--ts-allow-any\t(default)\t{}\tany\tunknown\t{additionalProperties: true}\tany\tunknown\t{additionalProperties: false}\t{ [key: string]: never }\t{ [key: string]: never }\t{type: \"object\", additionalProperties: true}\t{[key: string]: any}\t{[key: string]: unknown}\t{type: \"array\", items: {}}\tany[]\tunknown[]","--ts-server-implementation-method-experimental-server-sdks-only#--ts-server-implementation-method (experimental) (server sdks only)":"As environment variable OPENAPI_TS_SERVER_IMPLEMENTATION_METHODDetermines whether to represent server stubs / interfaces as type, interface, or abstract class entities.This is mostly a case of personal preference, but can be important for better integration with dependency injection\nframeworks, such as diod which rely on abstract class objects to define\ninterfaces for injection.\nOption\tExample Output\tinterface\texport interface Implementation { ... } `\ttype\texport type Implementation = { ... }\tabstract-class\texport abstract class Implementation { ... }\t\nDefault: type","--filename-convention-value#--filename-convention ":"As environment variable OPENAPI_FILENAME_CONVENTIONDetermines which naming convention to use for dynamically generated filenames\n(eg: those generated from tags or route prefixes).\nValue\tExample Filename\tkebab-case\tmy-file.ts\tcamel-case\tmyFile.ts\ttitle-case\tMyFile.ts\tsnake-case\tmy_file.ts\t\nDefault: kebab-case","misc#Misc":"","--remote-spec-request-headers-authenticated-remote-specifications#--remote-spec-request-headers (authenticated remote specifications)":"As environment variable OPENAPI_REMOTE_SPEC_REQUEST_HEADERSAllows providing request headers to use when fetching remote specifications. This allows for running\ngeneration against remote sources that require authentication.See authenticated-input-specifications guide for\ndetails of how to use.","-h---help#-h, --help":"Displays help text for command"}}}
\ No newline at end of file
diff --git a/getting-started/quick-start.html b/getting-started/quick-start.html
index 5181f63d..a3cd45e6 100644
--- a/getting-started/quick-start.html
+++ b/getting-started/quick-start.html
@@ -1,4 +1,4 @@
-Quick Start – OpenAPI Code Generator
Getting StartedQuick Start
Quick Start
+Quick Start – OpenAPI Code Generator
Getting StartedQuick Start
Quick Start
Install the latest NodeJS LTS release, though any recent version of NodeJS will likely work.
You’ll also need either an OpenAPI v3 / v3.1, or TypeSpec API specification to generate from. You can
provide OpenAPI specifications as YAML or JSON, local files or remote urls - we’ll load them all! 🚀
\ No newline at end of file
diff --git a/guides/client-templates/typescript-angular.html b/guides/client-templates/typescript-angular.html
index 43de5cc6..b9cbf584 100644
--- a/guides/client-templates/typescript-angular.html
+++ b/guides/client-templates/typescript-angular.html
@@ -1,4 +1,4 @@
-Using the typescript-angular template – OpenAPI Code Generator
\ No newline at end of file
diff --git a/guides/client-templates/typescript-axios.html b/guides/client-templates/typescript-axios.html
index f05bce38..21edc5b3 100644
--- a/guides/client-templates/typescript-axios.html
+++ b/guides/client-templates/typescript-axios.html
@@ -1,4 +1,4 @@
-Using the typescript-axios template – OpenAPI Code Generator
\ No newline at end of file
diff --git a/guides/client-templates/typescript-fetch.html b/guides/client-templates/typescript-fetch.html
index 30751f1d..3416d412 100644
--- a/guides/client-templates/typescript-fetch.html
+++ b/guides/client-templates/typescript-fetch.html
@@ -1,4 +1,4 @@
-Using the typescript-fetch template – OpenAPI Code Generator
Why JSON you ask? Simply put it has very well-defined semantics, and is easy to parse without
fear of jumbling the pieces together.
I started by trying to come up with a more ergonomic format, and then felt like I was re-inventing JSON
-when it came to dealing with all the edge cases correctly.
We have experimental support for “extracting inline schemas” behind the
--extract-inline-schemas / OPENAPI_EXTRACT_INLINE_SCHEMAS=true configuration flag.
What does this mean?
@@ -184,4 +184,4 @@
})
This can be a handy trick to make the code generated from schemas you don’t own/control easier to work with. In general
you should prefer to improve the specifications to be more suitable for code generation, which generally also improves
-the result of documentation tools like Redoc
OpenAPI 3 has a servers property that can be used to define the base url for the whole document, or
specific operations. This guide aims to explain how this is processed.
You can find the specifications definition of the servers object here
@@ -74,4 +74,4 @@
--enable-typed-base-paths=false
When disabled basePath: string parameters will still be added to operations that have a servers override, but
no code based on the url or variables will be generated.
\ No newline at end of file
diff --git a/guides/server-templates/typescript-koa.html b/guides/server-templates/typescript-koa.html
index e324aafd..7c202ead 100644
--- a/guides/server-templates/typescript-koa.html
+++ b/guides/server-templates/typescript-koa.html
@@ -1,4 +1,4 @@
-Using the typescript-koa template – OpenAPI Code Generator
\ No newline at end of file
diff --git a/index.html b/index.html
index c487af63..340ec016 100644
--- a/index.html
+++ b/index.html
@@ -1 +1 @@
-OpenAPI Code Generator
\ No newline at end of file
diff --git a/overview/about.html b/overview/about.html
index f5bf6d4b..eeaac18d 100644
--- a/overview/about.html
+++ b/overview/about.html
@@ -1,4 +1,4 @@
-Welcome – OpenAPI Code Generator
OverviewAbout
Welcome
+Welcome – OpenAPI Code Generator
OverviewAbout
Welcome
@nahkies/openapi-code-generator is a CLI tool that aims to generate high quality typescript client SDK’s,
and API server scaffolding (routing, validation, serialization) from OpenAPI 3 specifications.
This page aims to document which parts of the openapi 3.1.0 specification is supported.
It may not be totally complete / accurate, but it should be broadly correct and give you
an understanding of what does / doesn’t work.
@@ -117,4 +117,4 @@
Attribute
Supported
Notes
authorizationUrl
🚫
tokenUrl
🚫
refreshUrl
🚫
scopes
🚫
Security Requirement Object - Patterned Fields
The security requirement object is completely unsupported.
\ No newline at end of file
diff --git a/overview/schema-first-design.html b/overview/schema-first-design.html
index 8435d6a9..c752a69f 100644
--- a/overview/schema-first-design.html
+++ b/overview/schema-first-design.html
@@ -1,4 +1,4 @@
-Why schema first – OpenAPI Code Generator
Broadly speaking there are two approaches people take to maintaining API specifications:
Schema first, where you write the schema by hand
@@ -31,4 +31,4 @@
Generating a good specification from your code, therefore requires including all this extra metadata in the code, which
can make the code more difficult to work with.
-
We prefer to separate these concerns out into the specification, and keep the implementation code leaner and simpler.