openapi-typescript
Advanced tools
Comparing version 6.2.1 to 6.2.2
@@ -115,3 +115,7 @@ #!/usr/bin/env node | ||
const filename = pathToSpec.replace(EXT_RE, ".ts"); | ||
outputFilePath = new URL(filename, outputFilePath); | ||
const originalOutputFilePath = outputFilePath; | ||
outputFilePath = new URL(filename, originalOutputFilePath); | ||
if (outputFilePath.protocol !== 'file') { | ||
outputFilePath = new URL(outputFilePath.host.replace(EXT_RE, ".ts"), originalOutputFilePath); | ||
} | ||
} | ||
@@ -118,0 +122,0 @@ |
@@ -1,4 +0,4 @@ | ||
/// <reference types="node" /> | ||
/// <reference types="node" /> | ||
import type { OpenAPI3, OpenAPITSOptions } from "./types"; | ||
/// <reference types="node" resolution-mode="require"/> | ||
/// <reference types="node" resolution-mode="require"/> | ||
import type { OpenAPI3, OpenAPITSOptions } from "./types.js"; | ||
import type { Readable } from "node:stream"; | ||
@@ -5,0 +5,0 @@ import { URL } from "node:url"; |
@@ -1,4 +0,4 @@ | ||
/// <reference types="node" /> | ||
/// <reference types="node" /> | ||
import type { Fetch, GlobalContext, ParameterObject, Subschema } from "./types"; | ||
/// <reference types="node" resolution-mode="require"/> | ||
/// <reference types="node" resolution-mode="require"/> | ||
import type { Fetch, GlobalContext, ParameterObject, Subschema } from "./types.js"; | ||
import { Readable } from "node:stream"; | ||
@@ -5,0 +5,0 @@ import { URL } from "node:url"; |
@@ -1,2 +0,2 @@ | ||
import type { ComponentsObject, GlobalContext } from "../types"; | ||
import type { ComponentsObject, GlobalContext } from "../types.js"; | ||
export default function transformComponentsObject(components: ComponentsObject, ctx: GlobalContext): string; |
@@ -75,2 +75,5 @@ import { escObjKey, getEntries, getSchemaObjectComment, indent, tsOptionalProperty, tsReadonly } from "../utils.js"; | ||
else { | ||
if (parameterObject.in !== "path" && !parameterObject.required) { | ||
key = tsOptionalProperty(key); | ||
} | ||
const parameterType = transformParameterObject(parameterObject, { | ||
@@ -77,0 +80,0 @@ path: `#/components/parameters/${name}`, |
@@ -1,2 +0,2 @@ | ||
import type { GlobalContext, HeaderObject } from "../types"; | ||
import type { GlobalContext, HeaderObject } from "../types.js"; | ||
export interface TransformHeaderObjectOptions { | ||
@@ -3,0 +3,0 @@ path: string; |
@@ -1,2 +0,2 @@ | ||
import type { GlobalContext, OpenAPI3 } from "../types"; | ||
import type { GlobalContext, OpenAPI3 } from "../types.js"; | ||
export declare function transformSchema(schema: OpenAPI3, ctx: GlobalContext): Record<string, string>; |
@@ -1,2 +0,2 @@ | ||
import type { GlobalContext, MediaTypeObject } from "../types"; | ||
import type { GlobalContext, MediaTypeObject } from "../types.js"; | ||
export interface TransformMediaTypeObjectOptions { | ||
@@ -3,0 +3,0 @@ path: string; |
@@ -1,2 +0,2 @@ | ||
import type { GlobalContext, OperationObject } from "../types"; | ||
import type { GlobalContext, OperationObject } from "../types.js"; | ||
export interface TransformOperationObjectOptions { | ||
@@ -3,0 +3,0 @@ path: string; |
@@ -1,2 +0,2 @@ | ||
import type { GlobalContext, ParameterObject, ReferenceObject } from "types"; | ||
import type { GlobalContext, ParameterObject, ReferenceObject } from "../types.js"; | ||
export interface TransformParameterArrayOptions { | ||
@@ -3,0 +3,0 @@ path: string; |
@@ -1,2 +0,2 @@ | ||
import type { GlobalContext, ParameterObject } from "types"; | ||
import type { GlobalContext, ParameterObject } from "../types.js"; | ||
export interface TransformParameterObjectOptions { | ||
@@ -3,0 +3,0 @@ path: string; |
@@ -1,2 +0,2 @@ | ||
import type { GlobalContext, PathItemObject } from "../types"; | ||
import type { GlobalContext, PathItemObject } from "../types.js"; | ||
export interface TransformPathItemObjectOptions { | ||
@@ -3,0 +3,0 @@ path: string; |
@@ -1,2 +0,2 @@ | ||
import type { GlobalContext, PathsObject } from "../types"; | ||
import type { GlobalContext, PathsObject } from "../types.js"; | ||
export default function transformPathsObject(pathsObject: PathsObject, ctx: GlobalContext): string; |
@@ -1,2 +0,2 @@ | ||
import type { GlobalContext, RequestBodyObject } from "../types"; | ||
import type { GlobalContext, RequestBodyObject } from "../types.js"; | ||
export interface TransformRequestBodyObjectOptions { | ||
@@ -3,0 +3,0 @@ path: string; |
@@ -1,2 +0,2 @@ | ||
import type { GlobalContext, ResponseObject } from "../types"; | ||
import type { GlobalContext, ResponseObject } from "../types.js"; | ||
export interface TransformResponseObjectOptions { | ||
@@ -3,0 +3,0 @@ path: string; |
@@ -1,2 +0,2 @@ | ||
import type { GlobalContext, ReferenceObject, SchemaObject } from "../types"; | ||
import type { GlobalContext, ReferenceObject, SchemaObject } from "../types.js"; | ||
export interface TransformSchemaObjectOptions { | ||
@@ -3,0 +3,0 @@ path: string; |
@@ -73,5 +73,15 @@ import { escObjKey, escStr, getEntries, getSchemaObjectComment, indent, parseRef, tsArrayOf, tsIntersectionOf, tsOmit, tsOneOf, tsOptionalProperty, tsReadonly, tsTupleOf, tsUnionOf, tsWithRequired, } from "../utils.js"; | ||
indentLv++; | ||
let itemType = schemaObject.items | ||
? transformSchemaObject(schemaObject.items, { path, ctx: { ...ctx, indentLv } }) | ||
: "unknown"; | ||
let itemType = "unknown"; | ||
if (schemaObject.items) { | ||
if (Array.isArray(schemaObject.items)) { | ||
const result = []; | ||
schemaObject.items.forEach((item) => { | ||
result.push(transformSchemaObject(item, { path, ctx: { ...ctx, indentLv } })); | ||
}); | ||
itemType = `[${result.join(",")}]`; | ||
} | ||
else { | ||
itemType = transformSchemaObject(schemaObject.items, { path, ctx: { ...ctx, indentLv } }); | ||
} | ||
} | ||
const minItems = typeof schemaObject.minItems === "number" && schemaObject.minItems >= 0 ? schemaObject.minItems : 0; | ||
@@ -185,4 +195,6 @@ const maxItems = typeof schemaObject.maxItems === "number" && schemaObject.maxItems >= 0 && minItems <= schemaObject.maxItems | ||
return finalType; | ||
if (!("type" in schemaObject)) | ||
return "unknown"; | ||
return ctx.emptyObjectsUnknown ? "Record<string, unknown>" : "Record<string, never>"; | ||
} | ||
//# sourceMappingURL=schema-object.js.map |
@@ -1,2 +0,2 @@ | ||
import type { GlobalContext, WebhooksObject } from "../types"; | ||
import type { GlobalContext, WebhooksObject } from "../types.js"; | ||
export default function transformWebhooksObject(webhooksObject: WebhooksObject, ctx: GlobalContext): string; |
@@ -1,5 +0,5 @@ | ||
/// <reference types="node" /> | ||
/// <reference types="node" resolution-mode="require"/> | ||
import type { URL } from "node:url"; | ||
import type { TransformSchemaObjectOptions } from "./transform/schema-object"; | ||
import type { RequestInfo, RequestInit, Response } from "undici"; | ||
import type { TransformSchemaObjectOptions } from "./transform/schema-object.js"; | ||
export interface Extensable { | ||
@@ -225,3 +225,3 @@ [key: `x-${string}`]: any; | ||
prefixItems?: SchemaObject | ReferenceObject; | ||
items?: SchemaObject | ReferenceObject; | ||
items?: SchemaObject | ReferenceObject | (SchemaObject | ReferenceObject)[]; | ||
minItems?: number; | ||
@@ -250,3 +250,3 @@ maxItems?: number; | ||
required?: string[]; | ||
}); | ||
} | {}); | ||
export interface DiscriminatorObject { | ||
@@ -253,0 +253,0 @@ propertyName: string; |
import c from "ansi-colors"; | ||
import { Fetch } from "types"; | ||
import type { Fetch } from "./types.js"; | ||
export { c }; | ||
@@ -4,0 +4,0 @@ interface CommentObject { |
@@ -10,3 +10,3 @@ import c from "ansi-colors"; | ||
export const LB_RE = /\r?\n/g; | ||
export const DOUBLE_QUOTE_RE = /"/g; | ||
export const DOUBLE_QUOTE_RE = /(?<!\\)"/g; | ||
const ESC_0_RE = /~0/g; | ||
@@ -114,2 +114,5 @@ const ESC_1_RE = /~1/g; | ||
export function tsIntersectionOf(...types) { | ||
types = types.filter((t) => t !== "unknown"); | ||
if (types.length === 0) | ||
return "unknown"; | ||
if (types.length === 1) | ||
@@ -146,5 +149,25 @@ return String(types[0]); | ||
export function tsUnionOf(...types) { | ||
if (types.length === 1) | ||
return String(types[0]); | ||
return types.map((t) => (TS_UNION_INTERSECTION_RE.test(String(t)) ? `(${t})` : t)).join(" | "); | ||
if (types.length === 0) | ||
return "never"; | ||
const members = new Set(); | ||
for (const t of types) { | ||
if (t === "unknown") | ||
return "unknown"; | ||
members.add(String(t)); | ||
} | ||
if (members.has("never") && members.size === 1) | ||
return "never"; | ||
members.delete("never"); | ||
const memberArr = Array.from(members); | ||
if (members.size === 1) | ||
return memberArr[0]; | ||
let out = ""; | ||
for (let i = 0; i < memberArr.length; i++) { | ||
const t = memberArr[i]; | ||
const escaped = TS_UNION_INTERSECTION_RE.test(t) ? `(${t})` : t; | ||
out += escaped; | ||
if (i !== memberArr.length - 1) | ||
out += " | "; | ||
} | ||
return out; | ||
} | ||
@@ -151,0 +174,0 @@ export function escStr(input) { |
{ | ||
"name": "openapi-typescript", | ||
"description": "Generate TypeScript types from Swagger OpenAPI specs", | ||
"version": "6.2.1", | ||
"version": "6.2.2", | ||
"author": "drew@pow.rs", | ||
@@ -42,6 +42,7 @@ "license": "MIT", | ||
"format": "npm run prettier -w .", | ||
"lint": "eslint .", | ||
"lint": "eslint \"src/**/*.{js,ts}\"", | ||
"prepare": "npm run build", | ||
"test": "vitest run", | ||
"test:coverage": "vitest run --coverage", | ||
"test": "npm run test:ts && vitest run", | ||
"test:ts": "tsc --noEmit", | ||
"test:coverage": "npm run test:ts && vitest run --coverage", | ||
"update:examples": "vite-node ./scripts/update-examples.ts", | ||
@@ -55,3 +56,3 @@ "version": "npm run build" | ||
"supports-color": "^9.3.1", | ||
"undici": "^5.21.0", | ||
"undici": "^5.22.0", | ||
"yargs-parser": "^21.1.1" | ||
@@ -62,9 +63,9 @@ }, | ||
"@types/js-yaml": "^4.0.5", | ||
"@types/node": "^18.15.11", | ||
"@typescript-eslint/eslint-plugin": "^5.57.0", | ||
"@typescript-eslint/parser": "^5.57.0", | ||
"@types/node": "^18.15.12", | ||
"@typescript-eslint/eslint-plugin": "^5.59.0", | ||
"@typescript-eslint/parser": "^5.59.0", | ||
"@vitest/coverage-c8": "^0.29.8", | ||
"degit": "^2.8.4", | ||
"del-cli": "^5.0.0", | ||
"eslint": "^8.37.0", | ||
"eslint": "^8.38.0", | ||
"eslint-config-prettier": "^8.8.0", | ||
@@ -74,3 +75,4 @@ "eslint-plugin-prettier": "^4.2.1", | ||
"prettier": "^2.8.7", | ||
"typescript": "^5.0.3", | ||
"typescript": "^5.0.4", | ||
"vite": "^4.3.0", | ||
"vite-node": "^0.29.8", | ||
@@ -77,0 +79,0 @@ "vitest": "^0.29.8" |
102
README.md
@@ -6,3 +6,3 @@ [![version(scoped)](https://img.shields.io/npm/v/openapi-typescript.svg)](https://www.npmjs.com/package/openapi-typescript) | ||
<!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section --> | ||
[![All Contributors](https://img.shields.io/badge/all_contributors-67-orange.svg?style=flat-square)](#contributors-) | ||
[![All Contributors](https://img.shields.io/badge/all_contributors-69-orange.svg?style=flat-square)](#contributors-) | ||
<!-- ALL-CONTRIBUTORS-BADGE:END --> | ||
@@ -56,3 +56,2 @@ | ||
#### ☁️ Reading remote schemas | ||
@@ -95,45 +94,24 @@ | ||
##### Simple example | ||
Fetching data can be done simply and safely using an **automatically-typed fetch wrapper**: | ||
Any fetch call can be typed from the `paths` like so: | ||
- [openapi-fetch](https://github.com/drwpow/openapi-fetch) (recommended) | ||
- [openapi-typescript-fetch](https://www.npmjs.com/package/openapi-typescript-fetch) by [@ajaishankar](https://github.com/ajaishankar) | ||
```ts | ||
import { paths } from './my-types'; | ||
**Example** ([openapi-fetch](https://github.com/drwpow/openapi-fetch)) | ||
const response: paths["/api/v1/user/{user_id}"]["get"][200 | 500] = await fetch(`/api/v1/user/${user_id}`).then((res) => res.json()); | ||
``` | ||
Or if you add the `--path-params-as-types` CLI flag, you can take advantage of more automatic inference: | ||
```ts | ||
import { paths } from './my-types'; | ||
import createClient from "openapi-fetch"; | ||
import { paths } from "./v1"; // (generated from openapi-typescript) | ||
const url = `/api/v1/user/${user_id}`; | ||
const response: paths[url]["get"][200 | 500] = await fetch(url).then((res) => res.json()); | ||
``` | ||
##### openapi-typescript-fetch | ||
You can generate a fully-typed [Fetch API](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API) client from openapiTS types with the [openapi-typescript-fetch](https://www.npmjs.com/package/openapi-typescript-fetch) package: | ||
```ts | ||
import { paths } from "./petstore"; | ||
import { Fetcher } from "openapi-typescript-fetch"; | ||
const fetcher = Fetcher.for<paths>(); | ||
// GET | ||
const findPetsByStatus = fetcher.path("/pet/findByStatus").method("get").create(); | ||
const { status, data: pets } = await findPetsByStatus({ | ||
status: ["available", "pending"], | ||
const { get, post, put, patch, del } = createClient<paths>({ | ||
baseUrl: "https://myserver.com/api/v1/", | ||
headers: { | ||
Authorization: `Bearer ${import.meta.env.VITE_AUTH_TOKEN}`, | ||
}, | ||
}); | ||
// POST | ||
const addPet = fetcher.path("/pet").method("post").create(); | ||
await addPet({ ... }) | ||
``` | ||
[See docs](https://www.npmjs.com/package/openapi-typescript-fetch) | ||
See each project’s respective pages for usage & install instructions. | ||
_Thanks, [@ajaishankar](https://github.com/ajaishankar)!_ | ||
✨ **Tip**: Automatically-typed fetch wrappers are better to use than manually-assigned generics. The latter is not only more work, but it can be error-prone (which makes your OpenAPI typing worthless if it can’t catch all your errors!). | ||
@@ -144,19 +122,19 @@ ### 📖 Options | ||
| Option | Alias | Default | Description | | ||
| :----------------------------- | :---- | :------: | :--------------------------------------------------------------------------------------------------------------------------- | | ||
| `--help` | | | Display inline help message and exit | | ||
| `--version` | | | Display this library’s version and exit | | ||
| `--output [location]` | `-o` | (stdout) | Where should the output file be saved? | | ||
| `--auth [token]` | | | Provide an auth token to be passed along in the request (only if accessing a private schema) | | ||
| `--header` | `-x` | | Provide an array of or singular headers as an alternative to a JSON object. Each header must follow the `key: value` pattern | | ||
| `--headers-object="{…}"` | `-h` | | Provide a JSON object as string of HTTP headers for remote schema request. This will take priority over `--header` | | ||
| `--http-method` | `-m` | `GET` | Provide the HTTP Verb/Method for fetching a schema from a remote URL | | ||
| `--immutable-types` | | `false` | Generates immutable types (readonly properties and readonly array) | | ||
| `--additional-properties` | | `false` | Allow arbitrary properties for all schema objects without `additionalProperties: false` | | ||
| `--empty-objects-unknown` | | `false` | Allow arbitrary properties for schema objects with no specified properties, and no specified `additionalProperties` | | ||
| `--default-non-nullable` | | `false` | Treat schema objects with default values as non-nullable | | ||
| `--export-type` | `-t` | `false` | Export `type` instead of `interface` | | ||
| `--path-params-as-types` | | `false` | Allow dynamic string lookups on the `paths` object | | ||
| `--support-array-length` | | `false` | Generate tuples using array `minItems` / `maxItems` | | ||
| `--alphabetize` | | `false` | Sort types alphabetically | | ||
| Option | Alias | Default | Description | | ||
| :------------------------ | :---- | :------: | :--------------------------------------------------------------------------------------------------------------------------- | | ||
| `--help` | | | Display inline help message and exit | | ||
| `--version` | | | Display this library’s version and exit | | ||
| `--output [location]` | `-o` | (stdout) | Where should the output file be saved? | | ||
| `--auth [token]` | | | Provide an auth token to be passed along in the request (only if accessing a private schema) | | ||
| `--header` | `-x` | | Provide an array of or singular headers as an alternative to a JSON object. Each header must follow the `key: value` pattern | | ||
| `--headers-object="{…}"` | `-h` | | Provide a JSON object as string of HTTP headers for remote schema request. This will take priority over `--header` | | ||
| `--http-method` | `-m` | `GET` | Provide the HTTP Verb/Method for fetching a schema from a remote URL | | ||
| `--immutable-types` | | `false` | Generates immutable types (readonly properties and readonly array) | | ||
| `--additional-properties` | | `false` | Allow arbitrary properties for all schema objects without `additionalProperties: false` | | ||
| `--empty-objects-unknown` | | `false` | Allow arbitrary properties for schema objects with no specified properties, and no specified `additionalProperties` | | ||
| `--default-non-nullable` | | `false` | Treat schema objects with default values as non-nullable | | ||
| `--export-type` | `-t` | `false` | Export `type` instead of `interface` | | ||
| `--path-params-as-types` | | `false` | Allow dynamic string lookups on the `paths` object | | ||
| `--support-array-length` | | `false` | Generate tuples using array `minItems` / `maxItems` | | ||
| `--alphabetize` | | `false` | Sort types alphabetically | | ||
@@ -169,3 +147,3 @@ #### 🚩 `--path-params-as-types` | ||
export interface paths { | ||
'/user/{user_id}': components["schemas"]["User"]; | ||
"/user/{user_id}": components["schemas"]["User"]; | ||
} | ||
@@ -177,6 +155,6 @@ ``` | ||
```ts | ||
import { paths } from './my-schema'; | ||
import { paths } from "./my-schema"; | ||
const url = `/user/${id}`; | ||
type UserResponses = paths['/user/{user_id}']['responses']; | ||
type UserResponses = paths["/user/{user_id}"]["responses"]; | ||
``` | ||
@@ -187,6 +165,6 @@ | ||
```ts | ||
import { paths } from './my-schema'; | ||
import { paths } from "./my-schema"; | ||
const url = `/user/${id}`; | ||
type UserResponses = paths[url]['responses']; // automatically matches `paths['/user/{user_id}']` | ||
type UserResponses = paths[url]["responses"]; // automatically matches `paths['/user/{user_id}']` | ||
``` | ||
@@ -243,3 +221,3 @@ | ||
// example 1: load [object] as schema (JSON only) | ||
const schema = await fs.promises.readFile("spec.json", "utf8") // must be OpenAPI JSON | ||
const schema = await fs.promises.readFile("spec.json", "utf8"); // must be OpenAPI JSON | ||
const output = await openapiTS(JSON.parse(schema)); | ||
@@ -262,3 +240,3 @@ | ||
| Name | Type | Default | Description | | ||
|:----------------|:----------:|:--------|:---------------------------------------------------------------------------------| | ||
| :-------------- | :--------: | :------ | :------------------------------------------------------------------------------- | | ||
| `commentHeader` | `string` | | Override the default “This file was auto-generated …” file heading | | ||
@@ -403,3 +381,3 @@ | `inject` | `string` | | Inject arbitrary TypeScript types into the start of the file | | ||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/BTMPL"><img src="https://avatars.githubusercontent.com/u/247153?v=4?s=100" width="100px;" alt="Bartosz Szczeciński"/><br /><sub><b>Bartosz Szczeciński</b></sub></a><br /><a href="https://github.com/drwpow/openapi-typescript/commits?author=BTMPL" title="Code">💻</a> <a href="https://github.com/drwpow/openapi-typescript/issues?q=author%3ABTMPL" title="Bug reports">🐛</a> <a href="https://github.com/drwpow/openapi-typescript/commits?author=BTMPL" title="Tests">⚠️</a></td> | ||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/HiiiiD"><img src="https://avatars.githubusercontent.com/u/61231210?v=4?s=100" width="100px;" alt="Marco Salomone"/><br /><sub><b>Marco Salomone</b></sub></a><br /><a href="https://github.com/drwpow/openapi-typescript/commits?author=HiiiiD" title="Code">💻</a> <a href="https://github.com/drwpow/openapi-typescript/commits?author=HiiiiD" title="Tests">⚠️</a></td> | ||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/HiiiiD"><img src="https://avatars.githubusercontent.com/u/61231210?v=4?s=100" width="100px;" alt="Marco Salomone"/><br /><sub><b>Marco Salomone</b></sub></a><br /><a href="https://github.com/drwpow/openapi-typescript/commits?author=HiiiiD" title="Code">💻</a> <a href="https://github.com/drwpow/openapi-typescript/commits?author=HiiiiD" title="Tests">⚠️</a> <a href="https://github.com/drwpow/openapi-typescript/issues?q=author%3AHiiiiD" title="Bug reports">🐛</a></td> | ||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/yacinehmito"><img src="https://avatars.githubusercontent.com/u/6893840?v=4?s=100" width="100px;" alt="Yacine Hmito"/><br /><sub><b>Yacine Hmito</b></sub></a><br /><a href="https://github.com/drwpow/openapi-typescript/commits?author=yacinehmito" title="Code">💻</a> <a href="https://github.com/drwpow/openapi-typescript/commits?author=yacinehmito" title="Tests">⚠️</a> <a href="https://github.com/drwpow/openapi-typescript/issues?q=author%3Ayacinehmito" title="Bug reports">🐛</a></td> | ||
@@ -415,2 +393,4 @@ <td align="center" valign="top" width="14.28%"><a href="http://sajadtorkamani.com"><img src="https://avatars.githubusercontent.com/u/9380313?v=4?s=100" width="100px;" alt="Sajad Torkamani"/><br /><sub><b>Sajad Torkamani</b></sub></a><br /><a href="https://github.com/drwpow/openapi-typescript/commits?author=sajadtorkamani" title="Documentation">📖</a></td> | ||
<td align="center" valign="top" width="14.28%"><a href="http://www.francoisrisoud.com"><img src="https://avatars.githubusercontent.com/u/6012554?v=4?s=100" width="100px;" alt="François Risoud"/><br /><sub><b>François Risoud</b></sub></a><br /><a href="https://github.com/drwpow/openapi-typescript/commits?author=qnp" title="Code">💻</a> <a href="https://github.com/drwpow/openapi-typescript/issues?q=author%3Aqnp" title="Bug reports">🐛</a> <a href="https://github.com/drwpow/openapi-typescript/commits?author=qnp" title="Tests">⚠️</a></td> | ||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/shoffmeister"><img src="https://avatars.githubusercontent.com/u/3868036?v=4?s=100" width="100px;" alt="shoffmeister"/><br /><sub><b>shoffmeister</b></sub></a><br /><a href="https://github.com/drwpow/openapi-typescript/commits?author=shoffmeister" title="Documentation">📖</a></td> | ||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/liangskyli"><img src="https://avatars.githubusercontent.com/u/31531283?v=4?s=100" width="100px;" alt="liangsky"/><br /><sub><b>liangsky</b></sub></a><br /><a href="https://github.com/drwpow/openapi-typescript/commits?author=liangskyli" title="Code">💻</a> <a href="https://github.com/drwpow/openapi-typescript/issues?q=author%3Aliangskyli" title="Bug reports">🐛</a> <a href="https://github.com/drwpow/openapi-typescript/commits?author=liangskyli" title="Tests">⚠️</a></td> | ||
</tr> | ||
@@ -417,0 +397,0 @@ </tbody> |
@@ -1,2 +0,2 @@ | ||
import type { GlobalContext, OpenAPI3, OpenAPITSOptions, Subschema } from "./types"; | ||
import type { GlobalContext, OpenAPI3, OpenAPITSOptions, Subschema } from "./types.js"; | ||
import type { Readable } from "node:stream"; | ||
@@ -3,0 +3,0 @@ import { URL } from "node:url"; |
@@ -14,3 +14,3 @@ import type { | ||
Subschema, | ||
} from "./types"; | ||
} from "./types.js"; | ||
import fs from "node:fs"; | ||
@@ -17,0 +17,0 @@ import path from "node:path"; |
@@ -1,2 +0,2 @@ | ||
import type { ComponentsObject, GlobalContext } from "../types"; | ||
import type { ComponentsObject, GlobalContext } from "../types.js"; | ||
import { escObjKey, getEntries, getSchemaObjectComment, indent, tsOptionalProperty, tsReadonly } from "../utils.js"; | ||
@@ -83,2 +83,5 @@ import transformHeaderObject from "./header-object.js"; | ||
} else { | ||
if (parameterObject.in !== "path" && !parameterObject.required) { | ||
key = tsOptionalProperty(key); | ||
} | ||
const parameterType = transformParameterObject(parameterObject, { | ||
@@ -85,0 +88,0 @@ path: `#/components/parameters/${name}`, |
@@ -1,2 +0,2 @@ | ||
import type { GlobalContext, HeaderObject } from "../types"; | ||
import type { GlobalContext, HeaderObject } from "../types.js"; | ||
import { escStr, getEntries, getSchemaObjectComment, indent, tsReadonly } from "../utils.js"; | ||
@@ -3,0 +3,0 @@ import transformMediaTypeObject from "./media-type-object.js"; |
@@ -1,2 +0,2 @@ | ||
import type { GlobalContext, OpenAPI3 } from "../types"; | ||
import type { GlobalContext, OpenAPI3 } from "../types.js"; | ||
import transformComponentsObject from "./components-object.js"; | ||
@@ -3,0 +3,0 @@ import transformPathsObject from "./paths-object.js"; |
@@ -1,2 +0,2 @@ | ||
import type { GlobalContext, MediaTypeObject } from "../types"; | ||
import type { GlobalContext, MediaTypeObject } from "../types.js"; | ||
import transformSchemaObject from "./schema-object.js"; | ||
@@ -3,0 +3,0 @@ |
@@ -1,2 +0,2 @@ | ||
import type { GlobalContext, OperationObject, ParameterObject } from "../types"; | ||
import type { GlobalContext, OperationObject, ParameterObject } from "../types.js"; | ||
import { escObjKey, getEntries, getSchemaObjectComment, indent, tsOptionalProperty, tsReadonly } from "../utils.js"; | ||
@@ -3,0 +3,0 @@ import transformParameterObject from "./parameter-object.js"; |
@@ -1,2 +0,2 @@ | ||
import type { GlobalContext, ParameterObject, ReferenceObject } from "types"; | ||
import type { GlobalContext, ParameterObject, ReferenceObject } from "../types.js"; | ||
import { escObjKey, indent, tsOptionalProperty, tsReadonly } from "../utils.js"; | ||
@@ -3,0 +3,0 @@ import transformParameterObject from "./parameter-object.js"; |
@@ -1,2 +0,2 @@ | ||
import type { GlobalContext, ParameterObject } from "types"; | ||
import type { GlobalContext, ParameterObject } from "../types.js"; | ||
import transformSchemaObject from "./schema-object.js"; | ||
@@ -3,0 +3,0 @@ |
@@ -1,2 +0,2 @@ | ||
import type { GlobalContext, ParameterObject, PathItemObject, ReferenceObject } from "../types"; | ||
import type { GlobalContext, ParameterObject, PathItemObject, ReferenceObject } from "../types.js"; | ||
import { escStr, getSchemaObjectComment, indent } from "../utils.js"; | ||
@@ -3,0 +3,0 @@ import transformOperationObject from "./operation-object.js"; |
@@ -1,2 +0,2 @@ | ||
import type { GlobalContext, PathsObject } from "../types"; | ||
import type { GlobalContext, PathsObject } from "../types.js"; | ||
import { escStr, getEntries, indent } from "../utils.js"; | ||
@@ -3,0 +3,0 @@ import transformParameterObject from "./parameter-object.js"; |
@@ -1,2 +0,2 @@ | ||
import type { GlobalContext, RequestBodyObject } from "../types"; | ||
import type { GlobalContext, RequestBodyObject } from "../types.js"; | ||
import { escStr, getEntries, getSchemaObjectComment, indent, tsReadonly } from "../utils.js"; | ||
@@ -3,0 +3,0 @@ import transformMediaTypeObject from "./media-type-object.js"; |
@@ -1,2 +0,2 @@ | ||
import type { GlobalContext, ResponseObject } from "../types"; | ||
import type { GlobalContext, ResponseObject } from "../types.js"; | ||
import { | ||
@@ -3,0 +3,0 @@ escObjKey, |
@@ -1,2 +0,2 @@ | ||
import type { GlobalContext, ReferenceObject, SchemaObject } from "../types"; | ||
import type { GlobalContext, ReferenceObject, SchemaObject } from "../types.js"; | ||
import { | ||
@@ -129,5 +129,15 @@ escObjKey, | ||
indentLv++; | ||
let itemType = schemaObject.items | ||
? transformSchemaObject(schemaObject.items, { path, ctx: { ...ctx, indentLv } }) | ||
: "unknown"; | ||
let itemType = "unknown"; | ||
if (schemaObject.items) { | ||
if (Array.isArray(schemaObject.items)) { | ||
// tuple type support | ||
const result: string[] = []; | ||
schemaObject.items.forEach((item) => { | ||
result.push(transformSchemaObject(item, { path, ctx: { ...ctx, indentLv } })); | ||
}); | ||
itemType = `[${result.join(",")}]`; | ||
} else { | ||
itemType = transformSchemaObject(schemaObject.items, { path, ctx: { ...ctx, indentLv } }); | ||
} | ||
} | ||
const minItems: number = | ||
@@ -261,4 +271,7 @@ typeof schemaObject.minItems === "number" && schemaObject.minItems >= 0 ? schemaObject.minItems : 0; | ||
// any type | ||
if (!("type" in schemaObject)) return "unknown"; | ||
// if no type could be generated, fall back to “empty object” type | ||
return ctx.emptyObjectsUnknown ? "Record<string, unknown>" : "Record<string, never>"; | ||
} |
@@ -1,2 +0,2 @@ | ||
import type { GlobalContext, WebhooksObject } from "../types"; | ||
import type { GlobalContext, WebhooksObject } from "../types.js"; | ||
import { escStr, getEntries, indent } from "../utils.js"; | ||
@@ -3,0 +3,0 @@ import transformPathItemObject from "./path-item-object.js"; |
import type { URL } from "node:url"; | ||
import type { TransformSchemaObjectOptions } from "./transform/schema-object"; | ||
import type { RequestInfo, RequestInit, Response } from "undici"; | ||
import type { TransformSchemaObjectOptions } from "./transform/schema-object.js"; | ||
@@ -442,3 +442,3 @@ export interface Extensable { | ||
prefixItems?: SchemaObject | ReferenceObject; | ||
items?: SchemaObject | ReferenceObject; | ||
items?: SchemaObject | ReferenceObject | (SchemaObject | ReferenceObject)[]; | ||
minItems?: number; | ||
@@ -459,2 +459,3 @@ maxItems?: number; | ||
| { allOf?: (SchemaObject | ReferenceObject)[]; anyOf: (SchemaObject | ReferenceObject)[]; required?: string[] } | ||
| {} | ||
); | ||
@@ -461,0 +462,0 @@ |
@@ -5,3 +5,3 @@ import c from "ansi-colors"; | ||
import { fetch as unidiciFetch } from "undici"; | ||
import { Fetch } from "types"; | ||
import type { Fetch } from "./types.js"; | ||
@@ -29,3 +29,3 @@ // eslint-disable-next-line @typescript-eslint/no-unnecessary-boolean-literal-compare | ||
export const LB_RE = /\r?\n/g; | ||
export const DOUBLE_QUOTE_RE = /"/g; | ||
export const DOUBLE_QUOTE_RE = /(?<!\\)"/g; | ||
const ESC_0_RE = /~0/g; | ||
@@ -162,2 +162,4 @@ const ESC_1_RE = /~1/g; | ||
export function tsIntersectionOf(...types: string[]): string { | ||
types = types.filter((t) => t !== "unknown"); | ||
if (types.length === 0) return "unknown"; | ||
if (types.length === 1) return String(types[0]); // don’t add parentheses around one thing | ||
@@ -210,4 +212,37 @@ return types.map((t) => (TS_UNION_INTERSECTION_RE.test(t) ? `(${t})` : t)).join(" & "); | ||
export function tsUnionOf(...types: (string | number | boolean)[]): string { | ||
if (types.length === 1) return String(types[0]); // don’t add parentheses around one thing | ||
return types.map((t) => (TS_UNION_INTERSECTION_RE.test(String(t)) ? `(${t})` : t)).join(" | "); | ||
if (types.length === 0) return "never"; | ||
// de-duplicate the union | ||
const members = new Set<string>(); | ||
for (const t of types) { | ||
// unknown swallows everything else in the union | ||
if (t === "unknown") return "unknown"; | ||
members.add(String(t)); | ||
} | ||
// never gets swallowed by anything else, so only return never | ||
// if it is the only member | ||
if (members.has("never") && members.size === 1) return "never"; | ||
// (otherwise remove it) | ||
members.delete("never"); | ||
// return the only member without parentheses | ||
const memberArr = Array.from(members); | ||
if (members.size === 1) return memberArr[0]; | ||
// build the union string | ||
let out = ""; | ||
for (let i = 0; i < memberArr.length; i++) { | ||
const t = memberArr[i]; | ||
// if the type has & or | we should parenthesise it for safety | ||
const escaped = TS_UNION_INTERSECTION_RE.test(t) ? `(${t})` : t; | ||
out += escaped; | ||
if (i !== memberArr.length - 1) out += " | "; | ||
} | ||
return out; | ||
} | ||
@@ -214,0 +249,0 @@ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
316344
4623
17
396
Updatedundici@^5.22.0