diff --git a/.changeset/modern-dots-study.md b/.changeset/modern-dots-study.md new file mode 100644 index 000000000..327d92991 --- /dev/null +++ b/.changeset/modern-dots-study.md @@ -0,0 +1,5 @@ +--- +"@hey-api/openapi-ts": minor +--- + +fix: generate enums into their own file diff --git a/.changeset/young-moles-enjoy.md b/.changeset/young-moles-enjoy.md new file mode 100644 index 000000000..76ec4b239 --- /dev/null +++ b/.changeset/young-moles-enjoy.md @@ -0,0 +1,5 @@ +--- +"openapi-ts-docs": patch +--- + +docs: add enums migration diff --git a/docs/openapi-ts/migrating.md b/docs/openapi-ts/migrating.md index b28c09f26..60506770d 100644 --- a/docs/openapi-ts/migrating.md +++ b/docs/openapi-ts/migrating.md @@ -5,7 +5,7 @@ description: Migrating to @hey-api/openapi-ts. # Migrating -While we try to avoid breaking changes, sometimes it's unavoidable in order to offer you the latest features. This page lists changes that require updates to your code. +While we try to avoid breaking changes, sometimes it's unavoidable in order to offer you the latest features. This page lists changes that require updates to your code. If you run into an issue with migration, please [open an issue](https://github.com/hey-api/openapi-ts/issues). ## @next @@ -50,6 +50,25 @@ This config option is deprecated and will be removed. This config option is deprecated and will be removed. +## v0.39.0 + +### Single `enums.gen.ts` file + +Enums are now exported from a single file. If you used imports from `model.ts`, you can change it to `enums.gen.ts`. + +```js +import { Enum } from 'client/models' // [!code --] +import { Enum } from 'client/enums.gen.ts' // [!code ++] +``` + +Enums are no longer exported from `index.ts`. If you used imports from index file, you will need to move enums into their own import statement. + +```js +import { Enum, DefaultService } from 'client' // [!code --] +import { Enum } from 'client/enums.gen.ts' // [!code ++] +import { DefaultService } from 'client/services' // [!code ++] +``` + ## v0.38.0 ### Renamed `write` @@ -140,15 +159,4 @@ This config option has been removed. Generated types will behave the same as `us ## OpenAPI TypeScript Codegen -`openapi-ts` was originally forked from Ferdi Koomen's [openapi-typescript-codegen](https://github.com/ferdikoomen/openapi-typescript-codegen). Therefore, we want you to be able to migrate your openapi-typescript-codegen projects. Migration should be relatively straightforward if you follow the release notes on this page. If you run into an issue with migration, please [open an issue](https://github.com/hey-api/openapi-ts/issues). - -### Changed - -- `exportSchemas` is `true` by default (see [v0.27.36](#v0-27-36)) -- `useOptions` is `true` by default (see [v0.27.38](#v0-27-38)) - -### Removed - -- `useUnionTypes` has been removed (see [v0.27.24](#v0-27-24)) -- `indent` has been removed (see [v0.27.26](#v0-27-26)) -- `postfixModels` has been removed (see [v0.35.0](#v0-35-0)) +`openapi-ts` was originally forked from Ferdi Koomen's [openapi-typescript-codegen](https://github.com/ferdikoomen/openapi-typescript-codegen). Therefore, we want you to be able to migrate your projects. Migration should be relatively straightforward if you follow the release notes on this page. Start here and scroll up to the release you're migrating to. diff --git a/packages/openapi-ts/src/compiler/index.ts b/packages/openapi-ts/src/compiler/index.ts index 0546d4113..61630dcc5 100644 --- a/packages/openapi-ts/src/compiler/index.ts +++ b/packages/openapi-ts/src/compiler/index.ts @@ -1,4 +1,4 @@ -import { type PathOrFileDescriptor, writeFileSync } from 'node:fs'; +import { writeFileSync } from 'node:fs'; import ts from 'typescript'; @@ -15,6 +15,7 @@ export class TypeScriptFile { private _headers: Array = []; private _imports: Array = []; private _items: Array = []; + private _path: string = ''; public add(...nodes: Array): void { this._items = [...this._items, ...nodes]; @@ -31,6 +32,11 @@ export class TypeScriptFile { this._imports = [...this._imports, compiler.import.named(...params)]; } + public setPath(path: string) { + this._path = path; + return this; + } + public toString(seperator: string = '\n') { let output: string[] = []; if (this._headers.length) { @@ -43,11 +49,12 @@ export class TypeScriptFile { return output.join(seperator); } - public write(file: PathOrFileDescriptor, seperator: string = '\n') { - if (!this._items.length) { + public write(seperator = '\n') { + // TODO: throw if path is not set. do not throw if items are empty + if (!this._items.length || !this._path) { return; } - writeFileSync(file, this.toString(seperator)); + writeFileSync(this._path, this.toString(seperator)); } } diff --git a/packages/openapi-ts/src/compiler/types.ts b/packages/openapi-ts/src/compiler/types.ts index d3c865a60..f0a61719c 100644 --- a/packages/openapi-ts/src/compiler/types.ts +++ b/packages/openapi-ts/src/compiler/types.ts @@ -9,11 +9,11 @@ import { addLeadingComment, type Comments, isType, ots } from './utils'; */ export const toExpression = (value: unknown, unescape = false): ts.Expression | undefined => { if (Array.isArray(value)) { - return createArrayType(value); + return createArrayType({ arr: value }); } if (typeof value === 'object' && value !== null) { - return createObjectType(value); + return createObjectType({ obj: value }); } if (typeof value === 'number') { @@ -39,7 +39,13 @@ export const toExpression = (value: unknown, unescape = false): ts.Expression | * @param multiLine - if the array should be multiline. * @returns ts.ArrayLiteralExpression */ -export const createArrayType = (arr: T[], multiLine: boolean = false): ts.ArrayLiteralExpression => +export const createArrayType = ({ + arr, + multiLine = false, +}: { + arr: T[]; + multiLine?: boolean; +}): ts.ArrayLiteralExpression => ts.factory.createArrayLiteralExpression( arr.map(v => toExpression(v)).filter(isType), // Multiline if the array contains objects, or if specified by the user. @@ -48,42 +54,38 @@ export const createArrayType = (arr: T[], multiLine: boolean = false): ts.Arr /** * Create Object type expression. - * @param obj - the object to create. * @param options - options to use when creating type. * @returns ts.ObjectLiteralExpression */ -export const createObjectType = ( - obj: T, - options: { - multiLine?: boolean; - unescape?: boolean; - comments?: Record; - } = { - comments: {}, - multiLine: true, - unescape: false, - } -): ts.ObjectLiteralExpression => { - const expression = ts.factory.createObjectLiteralExpression( - Object.entries(obj) - .map(([key, value]) => { - const initializer = toExpression(value, options.unescape); - if (!initializer) { - return undefined; - } - const c = options.comments?.[key]; - if (key.match(/\W/g) && !key.startsWith("'") && !key.endsWith("'")) { - key = `'${key}'`; - } - const assignment = ts.factory.createPropertyAssignment(key, initializer); - if (c?.length) { - addLeadingComment(assignment, c); - } - return assignment; - }) - .filter(isType), - options.multiLine - ); +export const createObjectType = ({ + comments = {}, + multiLine = true, + obj, + unescape = false, +}: { + obj: T; + multiLine?: boolean; + unescape?: boolean; + comments?: Record; +}): ts.ObjectLiteralExpression => { + const properties = Object.entries(obj) + .map(([key, value]) => { + const initializer = toExpression(value, unescape); + if (!initializer) { + return undefined; + } + if (key.match(/\W/g) && !key.startsWith("'") && !key.endsWith("'")) { + key = `'${key}'`; + } + const assignment = ts.factory.createPropertyAssignment(key, initializer); + const c = comments?.[key]; + if (c?.length) { + addLeadingComment(assignment, c); + } + return assignment; + }) + .filter(isType); + const expression = ts.factory.createObjectLiteralExpression(properties, multiLine); return expression; }; @@ -91,16 +93,21 @@ export const createObjectType = ( * Create enum declaration. Example `export enum T = { X, Y };` * @param name - the name of the enum. * @param obj - the object representing the enum. - * @param comment - comment to add to enum. + * @param leadingComment - leading comment to add to enum. * @param comments - comments to add to each property of enum. * @returns */ -export const createEnumDeclaration = ( - name: string, - obj: T, - comment: Comments = [], - comments: Record = {} -): ts.EnumDeclaration => { +export const createEnumDeclaration = ({ + name, + obj, + leadingComment = [], + comments = {}, +}: { + name: string; + obj: T; + leadingComment: Comments; + comments: Record; +}): ts.EnumDeclaration => { const declaration = ts.factory.createEnumDeclaration( [ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)], ts.factory.createIdentifier(name), @@ -114,8 +121,8 @@ export const createEnumDeclaration = ( return assignment; }) ); - if (comment.length) { - addLeadingComment(declaration, comment); + if (leadingComment.length) { + addLeadingComment(declaration, leadingComment); } return declaration; }; diff --git a/packages/openapi-ts/src/utils/enum.ts b/packages/openapi-ts/src/utils/enum.ts index 74fecbf11..80f8f36fa 100644 --- a/packages/openapi-ts/src/utils/enum.ts +++ b/packages/openapi-ts/src/utils/enum.ts @@ -43,17 +43,12 @@ export const enumKey = (value?: string | number, customName?: string) => { */ export const enumName = (client: Client, name?: string) => { if (!name) { - return name; + return null; } const escapedName = unescapeName(name).replace(/[-_]([a-z])/gi, ($0, $1: string) => $1.toLocaleUpperCase()); - let result = `${escapedName.charAt(0).toLocaleUpperCase() + escapedName.slice(1)}Enum`; - let index = 1; - while (client.enumNames.includes(result)) { - if (result.endsWith(index.toString())) { - result = result.slice(0, result.length - index.toString().length); - } - index += 1; - result = result + index.toString(); + const result = `${escapedName.charAt(0).toLocaleUpperCase() + escapedName.slice(1)}Enum`; + if (client.enumNames.includes(result)) { + return null; } client.enumNames = [...client.enumNames, result]; return result; diff --git a/packages/openapi-ts/src/utils/write/__tests__/core.spec.ts b/packages/openapi-ts/src/utils/write/__tests__/core.spec.ts index a1fa12599..8fc791094 100644 --- a/packages/openapi-ts/src/utils/write/__tests__/core.spec.ts +++ b/packages/openapi-ts/src/utils/write/__tests__/core.spec.ts @@ -4,20 +4,20 @@ import path from 'node:path'; import { beforeEach, describe, expect, it, vi } from 'vitest'; import { setConfig } from '../../config'; -import { writeClientCore } from '../core'; +import { writeCore } from '../core'; import { mockTemplates } from './mocks'; import { openApi } from './models'; vi.mock('node:fs'); -describe('writeClientCore', () => { - let templates: Parameters[3]; +describe('writeCore', () => { + let templates: Parameters[3]; beforeEach(() => { templates = mockTemplates; }); it('writes to filesystem', async () => { - const client: Parameters[2] = { + const client: Parameters[2] = { enumNames: [], models: [], server: 'http://localhost:8080', @@ -46,7 +46,7 @@ describe('writeClientCore', () => { useOptions: true, }); - await writeClientCore(openApi, '/', client, templates); + await writeCore(openApi, '/', client, templates); expect(writeFileSync).toHaveBeenCalledWith(path.resolve('/', '/OpenAPI.ts'), 'settings'); expect(writeFileSync).toHaveBeenCalledWith(path.resolve('/', '/ApiError.ts'), 'apiError'); @@ -57,7 +57,7 @@ describe('writeClientCore', () => { }); it('uses client server value for base', async () => { - const client: Parameters[2] = { + const client: Parameters[2] = { enumNames: [], models: [], server: 'http://localhost:8080', @@ -86,7 +86,7 @@ describe('writeClientCore', () => { useOptions: true, }); - await writeClientCore(openApi, '/', client, templates); + await writeCore(openApi, '/', client, templates); expect(templates.core.settings).toHaveBeenCalledWith({ $config: config, @@ -97,7 +97,7 @@ describe('writeClientCore', () => { }); it('uses custom value for base', async () => { - const client: Parameters[2] = { + const client: Parameters[2] = { enumNames: [], models: [], server: 'http://localhost:8080', @@ -127,7 +127,7 @@ describe('writeClientCore', () => { useOptions: true, }); - await writeClientCore(openApi, '/', client, templates); + await writeCore(openApi, '/', client, templates); expect(templates.core.settings).toHaveBeenCalledWith({ $config: config, diff --git a/packages/openapi-ts/src/utils/write/__tests__/models.spec.ts b/packages/openapi-ts/src/utils/write/__tests__/models.spec.ts index 81fe41a0e..d58a812fc 100644 --- a/packages/openapi-ts/src/utils/write/__tests__/models.spec.ts +++ b/packages/openapi-ts/src/utils/write/__tests__/models.spec.ts @@ -4,12 +4,12 @@ import path from 'node:path'; import { describe, expect, it, vi } from 'vitest'; import { setConfig } from '../../config'; -import { writeClientModels } from '../models'; +import { writeTypesAndEnums } from '../models'; import { openApi } from './models'; vi.mock('node:fs'); -describe('writeClientModels', () => { +describe('writeTypesAndEnums', () => { it('writes to filesystem', async () => { setConfig({ client: 'fetch', @@ -32,7 +32,7 @@ describe('writeClientModels', () => { useOptions: true, }); - const client: Parameters[2] = { + const client: Parameters[2] = { enumNames: [], models: [ { @@ -59,7 +59,7 @@ describe('writeClientModels', () => { version: 'v1', }; - await writeClientModels(openApi, '/', client); + await writeTypesAndEnums(openApi, '/', client); expect(writeFileSync).toHaveBeenCalledWith(path.resolve('/', '/models.ts'), expect.anything()); }); diff --git a/packages/openapi-ts/src/utils/write/__tests__/schemas.spec.ts b/packages/openapi-ts/src/utils/write/__tests__/schemas.spec.ts index 20a171157..fb5815789 100644 --- a/packages/openapi-ts/src/utils/write/__tests__/schemas.spec.ts +++ b/packages/openapi-ts/src/utils/write/__tests__/schemas.spec.ts @@ -3,13 +3,35 @@ import path from 'node:path'; import { describe, expect, it, vi } from 'vitest'; -import { writeClientSchemas } from '../schemas'; +import { setConfig } from '../../config'; +import { writeSchemas } from '../schemas'; import { openApi } from './models'; vi.mock('node:fs'); -describe('writeClientSchemas', () => { +describe('writeSchemas', () => { it('writes to filesystem', async () => { + setConfig({ + client: 'fetch', + debug: false, + dryRun: false, + enums: 'javascript', + exportCore: true, + exportModels: true, + exportServices: true, + format: false, + input: '', + lint: false, + name: 'AppClient', + operationId: true, + output: '', + postfixServices: '', + schemas: true, + serviceResponse: 'body', + useDateType: false, + useOptions: true, + }); + if ('openapi' in openApi) { openApi.components = { schemas: { @@ -20,7 +42,7 @@ describe('writeClientSchemas', () => { }; } - await writeClientSchemas(openApi, '/'); + await writeSchemas(openApi, '/'); expect(writeFileSync).toHaveBeenCalledWith(path.resolve('/', '/schemas.ts'), expect.anything()); }); diff --git a/packages/openapi-ts/src/utils/write/__tests__/services.spec.ts b/packages/openapi-ts/src/utils/write/__tests__/services.spec.ts index 2968bbb59..62903131d 100644 --- a/packages/openapi-ts/src/utils/write/__tests__/services.spec.ts +++ b/packages/openapi-ts/src/utils/write/__tests__/services.spec.ts @@ -3,13 +3,13 @@ import { writeFileSync } from 'node:fs'; import { describe, expect, it, vi } from 'vitest'; import { setConfig } from '../../config'; -import { writeClientServices } from '../services'; +import { writeServices } from '../services'; import { mockTemplates } from './mocks'; import { openApi } from './models'; vi.mock('node:fs'); -describe('writeClientServices', () => { +describe('writeServices', () => { it('writes to filesystem', async () => { setConfig({ client: 'fetch', @@ -31,7 +31,7 @@ describe('writeClientServices', () => { useOptions: false, }); - const client: Parameters[2] = { + const client: Parameters[2] = { enumNames: [], models: [], server: 'http://localhost:8080', @@ -46,7 +46,7 @@ describe('writeClientServices', () => { version: 'v1', }; - await writeClientServices(openApi, '/', client, mockTemplates); + await writeServices(openApi, '/', client, mockTemplates); expect(writeFileSync).toHaveBeenCalled(); }); diff --git a/packages/openapi-ts/src/utils/write/class.ts b/packages/openapi-ts/src/utils/write/class.ts index 073bd21bd..7e0fbd43f 100644 --- a/packages/openapi-ts/src/utils/write/class.ts +++ b/packages/openapi-ts/src/utils/write/class.ts @@ -24,6 +24,7 @@ export const writeClientClass = async ( templates: Templates ): Promise => { const config = getConfig(); + const templateResult = templates.client({ $config: config, ...client, @@ -32,5 +33,7 @@ export const writeClientClass = async ( services: sortByName(client.services), }); - await writeFileSync(path.resolve(outputPath, `${config.name}.ts`), templateResult); + if (config.name) { + await writeFileSync(path.resolve(outputPath, `${config.name}.ts`), templateResult); + } }; diff --git a/packages/openapi-ts/src/utils/write/client.ts b/packages/openapi-ts/src/utils/write/client.ts index 53fd6d933..8a2c4ecb6 100644 --- a/packages/openapi-ts/src/utils/write/client.ts +++ b/packages/openapi-ts/src/utils/write/client.ts @@ -6,11 +6,11 @@ import type { Client } from '../../types/client'; import { getConfig } from '../config'; import type { Templates } from '../handlebars'; import { writeClientClass } from './class'; -import { writeClientCore } from './core'; +import { writeCore } from './core'; import { writeClientIndex } from './index'; -import { writeClientModels } from './models'; -import { writeClientSchemas } from './schemas'; -import { writeClientServices } from './services'; +import { writeTypesAndEnums } from './models'; +import { writeSchemas } from './schemas'; +import { writeServices } from './services'; /** * Write our OpenAPI client, using the given templates at the given output @@ -38,48 +38,39 @@ export const writeClient = async (openApi: OpenApi, client: Client, templates: T const sections = [ { dir: 'core', - enabled: config.exportCore, - fn: writeClientCore, + fn: writeCore, }, { dir: '', - enabled: config.schemas, - fn: writeClientSchemas, + fn: writeSchemas, }, { dir: '', - enabled: config.exportModels, - fn: writeClientModels, + fn: writeTypesAndEnums, }, { dir: '', - enabled: config.exportServices, - fn: writeClientServices, + fn: writeServices, }, { dir: '', - enabled: config.name, fn: writeClientClass, }, ] as const; for (const section of sections) { - if (section.enabled) { - const sectionPath = path.resolve(config.output, section.dir); - if (section.dir) { - await rmSync(sectionPath, { - force: true, - recursive: true, - }); - } - await mkdirSync(sectionPath, { + const sectionPath = path.resolve(config.output, section.dir); + if (section.dir) { + await rmSync(sectionPath, { + force: true, recursive: true, }); - await section.fn(openApi, sectionPath, client, templates); } + await mkdirSync(sectionPath, { + recursive: true, + }); + await section.fn(openApi, sectionPath, client, templates); } - if (sections.some(section => section.enabled)) { - await writeClientIndex(client, config.output); - } + await writeClientIndex(client, config.output); }; diff --git a/packages/openapi-ts/src/utils/write/core.ts b/packages/openapi-ts/src/utils/write/core.ts index 85595df84..bc3ba3326 100644 --- a/packages/openapi-ts/src/utils/write/core.ts +++ b/packages/openapi-ts/src/utils/write/core.ts @@ -14,87 +14,90 @@ import type { Templates } from '../handlebars'; * @param client Client containing models, schemas, and services * @param templates The loaded handlebar templates */ -export const writeClientCore = async ( +export const writeCore = async ( openApi: OpenApi, outputPath: string, client: Client, templates: Templates ): Promise => { const config = getConfig(); + const context = { httpRequest: getHttpRequestName(config.client), server: config.base !== undefined ? config.base : client.server, version: client.version, }; - await writeFileSync( - path.resolve(outputPath, 'OpenAPI.ts'), - templates.core.settings({ - $config: config, - ...context, - }) - ); - await writeFileSync( - path.resolve(outputPath, 'ApiError.ts'), - templates.core.apiError({ - $config: config, - ...context, - }) - ); - await writeFileSync( - path.resolve(outputPath, 'ApiRequestOptions.ts'), - templates.core.apiRequestOptions({ - $config: config, - ...context, - }) - ); - await writeFileSync( - path.resolve(outputPath, 'ApiResult.ts'), - templates.core.apiResult({ - $config: config, - ...context, - }) - ); - if (config.client !== 'angular') { + if (config.exportCore) { await writeFileSync( - path.resolve(outputPath, 'CancelablePromise.ts'), - templates.core.cancelablePromise({ + path.resolve(outputPath, 'OpenAPI.ts'), + templates.core.settings({ $config: config, ...context, }) ); - } - await writeFileSync( - path.resolve(outputPath, 'request.ts'), - templates.core.request({ - $config: config, - ...context, - }) - ); - - if (config.name) { await writeFileSync( - path.resolve(outputPath, 'BaseHttpRequest.ts'), - templates.core.baseHttpRequest({ + path.resolve(outputPath, 'ApiError.ts'), + templates.core.apiError({ $config: config, ...context, }) ); await writeFileSync( - path.resolve(outputPath, `${context.httpRequest}.ts`), - templates.core.httpRequest({ + path.resolve(outputPath, 'ApiRequestOptions.ts'), + templates.core.apiRequestOptions({ $config: config, ...context, }) ); - } + await writeFileSync( + path.resolve(outputPath, 'ApiResult.ts'), + templates.core.apiResult({ + $config: config, + ...context, + }) + ); + if (config.client !== 'angular') { + await writeFileSync( + path.resolve(outputPath, 'CancelablePromise.ts'), + templates.core.cancelablePromise({ + $config: config, + ...context, + }) + ); + } + await writeFileSync( + path.resolve(outputPath, 'request.ts'), + templates.core.request({ + $config: config, + ...context, + }) + ); + + if (config.name) { + await writeFileSync( + path.resolve(outputPath, 'BaseHttpRequest.ts'), + templates.core.baseHttpRequest({ + $config: config, + ...context, + }) + ); + await writeFileSync( + path.resolve(outputPath, `${context.httpRequest}.ts`), + templates.core.httpRequest({ + $config: config, + ...context, + }) + ); + } - if (config.request) { - const requestFile = path.resolve(process.cwd(), config.request); - const requestFileExists = await existsSync(requestFile); - if (!requestFileExists) { - throw new Error(`Custom request file "${requestFile}" does not exists`); + if (config.request) { + const requestFile = path.resolve(process.cwd(), config.request); + const requestFileExists = await existsSync(requestFile); + if (!requestFileExists) { + throw new Error(`Custom request file "${requestFile}" does not exists`); + } + await copyFileSync(requestFile, path.resolve(outputPath, 'request.ts')); } - await copyFileSync(requestFile, path.resolve(outputPath, 'request.ts')); } }; diff --git a/packages/openapi-ts/src/utils/write/index.ts b/packages/openapi-ts/src/utils/write/index.ts index 4a3de6886..d5d926457 100644 --- a/packages/openapi-ts/src/utils/write/index.ts +++ b/packages/openapi-ts/src/utils/write/index.ts @@ -13,34 +13,40 @@ import { getConfig } from '../config'; export const writeClientIndex = async (client: Client, outputPath: string): Promise => { const config = getConfig(); - const file = new TypeScriptFile().addHeader(); + const fileIndex = new TypeScriptFile().setPath(path.resolve(outputPath, 'index.ts')).addHeader(); if (config.name) { - file.add(compiler.export.named([config.name], `./${config.name}`)); + fileIndex.add(compiler.export.named([config.name], `./${config.name}`)); } + if (config.exportCore) { - file.add(compiler.export.named('ApiError', './core/ApiError')); + fileIndex.add(compiler.export.named('ApiError', './core/ApiError')); if (config.serviceResponse === 'response') { - file.add(compiler.export.named({ isTypeOnly: true, name: 'ApiResult' }, './core/ApiResult')); + fileIndex.add(compiler.export.named({ isTypeOnly: true, name: 'ApiResult' }, './core/ApiResult')); } if (config.name) { - file.add(compiler.export.named('BaseHttpRequest', './core/BaseHttpRequest')); + fileIndex.add(compiler.export.named('BaseHttpRequest', './core/BaseHttpRequest')); } if (config.client !== 'angular') { - file.add(compiler.export.named(['CancelablePromise', 'CancelError'], './core/CancelablePromise')); + fileIndex.add(compiler.export.named(['CancelablePromise', 'CancelError'], './core/CancelablePromise')); } - file.add(compiler.export.named(['OpenAPI', { isTypeOnly: true, name: 'OpenAPIConfig' }], './core/OpenAPI')); + fileIndex.add( + compiler.export.named(['OpenAPI', { isTypeOnly: true, name: 'OpenAPIConfig' }], './core/OpenAPI') + ); } + if (client.models.length) { if (config.exportModels) { - file.add(compiler.export.all('./models')); + fileIndex.add(compiler.export.all('./models')); } if (config.schemas) { - file.add(compiler.export.all('./schemas')); + fileIndex.add(compiler.export.all('./schemas')); } } + if (client.services.length && config.exportServices) { - file.add(compiler.export.all('./services')); + fileIndex.add(compiler.export.all('./services')); } - file.write(path.resolve(outputPath, 'index.ts')); + + fileIndex.write(); }; diff --git a/packages/openapi-ts/src/utils/write/models.ts b/packages/openapi-ts/src/utils/write/models.ts index 312e1b53a..dfe7d8d79 100644 --- a/packages/openapi-ts/src/utils/write/models.ts +++ b/packages/openapi-ts/src/utils/write/models.ts @@ -1,7 +1,9 @@ import path from 'node:path'; import { type Comments, compiler, type Node, TypeScriptFile } from '../../compiler'; +import { addLeadingComment } from '../../compiler/utils'; import type { Model, OpenApi, OperationParameter, Service } from '../../openApi'; +import { ensureValidTypeScriptJavaScriptIdentifier } from '../../openApi/common/parser/sanitize'; import type { Client } from '../../types/client'; import { getConfig } from '../config'; import { enumKey, enumName, enumUnionType, enumValue } from '../enum'; @@ -10,6 +12,8 @@ import { serviceExportedNamespace } from '../handlebars'; import { sortByName } from '../sort'; import { toType } from './type'; +type OnNode = (node: Node, type?: 'enum') => void; + const emptyModel: Model = { $refs: [], base: '', @@ -29,14 +33,13 @@ const emptyModel: Model = { type: '', }; -const processComposition = (client: Client, model: Model) => [ - processType(client, model), - ...model.enums.flatMap(enumerator => processEnum(client, enumerator, false)), -]; +const processComposition = (client: Client, model: Model, onNode: OnNode) => { + processType(client, model, onNode); + model.enums.forEach(enumerator => processEnum(client, enumerator, onNode)); +}; -const processEnum = (client: Client, model: Model, exportType: boolean) => { +const processEnum = (client: Client, model: Model, onNode: OnNode, exportType = false) => { const config = getConfig(); - let nodes: Array = []; const properties: Record = {}; const comments: Record = {}; @@ -50,53 +53,67 @@ const processEnum = (client: Client, model: Model, exportType: boolean) => { } }); + // ignore duplicate enum names + const name = enumName(client, model.name)!; + if (name === null) { + return; + } + + const comment = [model.description && escapeComment(model.description), model.deprecated && '@deprecated']; + if (exportType) { - const comment: Comments = [ - model.description && escapeComment(model.description), - model.deprecated && '@deprecated', - ]; - if (config.enums === 'typescript') { - nodes = [...nodes, compiler.types.enum(model.name, properties, comment, comments)]; - } else { - nodes = [...nodes, compiler.typedef.alias(model.name, enumUnionType(model.enum), comment)]; - } + const node = compiler.typedef.alias( + ensureValidTypeScriptJavaScriptIdentifier(model.name), + enumUnionType(model.enum), + comment + ); + onNode(node); + } + + if (config.enums === 'typescript') { + const node = compiler.types.enum({ + comments, + leadingComment: comment, + name, + obj: properties, + }); + onNode(node, 'enum'); } if (config.enums === 'javascript') { - const expression = compiler.types.object(properties, { + const expression = compiler.types.object({ comments, multiLine: true, + obj: properties, unescape: true, }); - nodes = [...nodes, compiler.export.asConst(enumName(client, model.name)!, expression)]; + const node = compiler.export.asConst(name, expression); + addLeadingComment(node, comment); + onNode(node, 'enum'); } - - return nodes; }; -const processType = (client: Client, model: Model) => { - const comment: Comments = [ - model.description && escapeComment(model.description), - model.deprecated && '@deprecated', - ]; - return compiler.typedef.alias(model.name, toType(model), comment); +const processType = (client: Client, model: Model, onNode: OnNode) => { + const comment = [model.description && escapeComment(model.description), model.deprecated && '@deprecated']; + const node = compiler.typedef.alias(model.name, toType(model), comment); + onNode(node); }; -const processModel = (client: Client, model: Model) => { +const processModel = (client: Client, model: Model, onNode: OnNode) => { switch (model.export) { case 'all-of': case 'any-of': case 'one-of': case 'interface': - return processComposition(client, model); + return processComposition(client, model, onNode); case 'enum': - return processEnum(client, model, true); + return processEnum(client, model, onNode, true); default: - return processType(client, model); + return processType(client, model, onNode); } }; -const processServiceTypes = (services: Service[]) => { +const processServiceTypes = (services: Service[], onNode: OnNode) => { type ResMap = Map; type MethodMap = Map<'req' | 'res', ResMap | OperationParameter[]>; type MethodKey = Service['operations'][number]['method']; @@ -195,7 +212,8 @@ const processServiceTypes = (services: Service[]) => { properties, }); const namespace = serviceExportedNamespace(); - return compiler.typedef.alias(namespace, type); + const node = compiler.typedef.alias(namespace, type); + onNode(node); }; /** @@ -204,19 +222,30 @@ const processServiceTypes = (services: Service[]) => { * @param outputPath Directory to write the generated files to * @param client Client containing models, schemas, and services */ -export const writeClientModels = async (openApi: OpenApi, outputPath: string, client: Client): Promise => { - const file = new TypeScriptFile().addHeader(); +export const writeTypesAndEnums = async (openApi: OpenApi, outputPath: string, client: Client): Promise => { + const config = getConfig(); + + const fileEnums = new TypeScriptFile().setPath(path.resolve(outputPath, 'enums.gen.ts')).addHeader(); + const fileModels = new TypeScriptFile().setPath(path.resolve(outputPath, 'models.ts')).addHeader(); for (const model of client.models) { - const nodes = processModel(client, model); - const n = Array.isArray(nodes) ? nodes : [nodes]; - file.add(...n); + processModel(client, model, (node, type) => { + if (type === 'enum') { + fileEnums.add(node); + } else { + fileModels.add(node); + } + }); } if (client.services.length) { - const serviceTypes = processServiceTypes(client.services); - file.add(serviceTypes); + processServiceTypes(client.services, node => { + fileModels.add(node); + }); } - file.write(path.resolve(outputPath, 'models.ts'), '\n\n'); + if (config.exportModels) { + fileEnums.write('\n\n'); + fileModels.write('\n\n'); + } }; diff --git a/packages/openapi-ts/src/utils/write/schemas.ts b/packages/openapi-ts/src/utils/write/schemas.ts index ddae47151..33c42a3a4 100644 --- a/packages/openapi-ts/src/utils/write/schemas.ts +++ b/packages/openapi-ts/src/utils/write/schemas.ts @@ -3,20 +3,23 @@ import path from 'node:path'; import { compiler, TypeScriptFile } from '../../compiler'; import type { OpenApi } from '../../openApi'; import { ensureValidTypeScriptJavaScriptIdentifier } from '../../openApi/common/parser/sanitize'; +import { getConfig } from '../config'; /** * Generate Schemas using the Handlebar template and write to disk. * @param openApi {@link OpenApi} Dereferenced OpenAPI specification * @param outputPath Directory to write the generated files to */ -export const writeClientSchemas = async (openApi: OpenApi, outputPath: string): Promise => { - const file = new TypeScriptFile().addHeader(); +export const writeSchemas = async (openApi: OpenApi, outputPath: string): Promise => { + const config = getConfig(); + + const fileSchemas = new TypeScriptFile().setPath(path.resolve(outputPath, 'schemas.ts')).addHeader(); const addSchema = (name: string, obj: any) => { const validName = `$${ensureValidTypeScriptJavaScriptIdentifier(name)}`; - const expression = compiler.types.object(obj); + const expression = compiler.types.object({ obj }); const statement = compiler.export.asConst(validName, expression); - file.add(statement); + fileSchemas.add(statement); }; // OpenAPI 2.0 @@ -47,5 +50,7 @@ export const writeClientSchemas = async (openApi: OpenApi, outputPath: string): } } - file.write(path.resolve(outputPath, 'schemas.ts'), '\n\n'); + if (config.schemas) { + fileSchemas.write('\n\n'); + } }; diff --git a/packages/openapi-ts/src/utils/write/services.ts b/packages/openapi-ts/src/utils/write/services.ts index 39ec1cd7d..768c70eea 100644 --- a/packages/openapi-ts/src/utils/write/services.ts +++ b/packages/openapi-ts/src/utils/write/services.ts @@ -1,4 +1,3 @@ -import { writeFileSync } from 'node:fs'; import path from 'node:path'; import { TypeScriptFile } from '../../compiler'; @@ -15,14 +14,15 @@ import { unique } from '../unique'; * @param client Client containing models, schemas, and services * @param templates The loaded handlebar templates */ -export const writeClientServices = async ( +export const writeServices = async ( openApi: OpenApi, outputPath: string, client: Client, templates: Templates ): Promise => { const config = getConfig(); - const file = new TypeScriptFile().addHeader(); + + const fileServices = new TypeScriptFile().setPath(path.resolve(outputPath, 'services.ts')).addHeader(); let imports: string[] = []; let results: string[] = []; @@ -39,32 +39,34 @@ export const writeClientServices = async ( // Import required packages and core files. if (config.client === 'angular') { - file.addNamedImport('Injectable', '@angular/core'); + fileServices.addNamedImport('Injectable', '@angular/core'); if (config.name === undefined) { - file.addNamedImport('HttpClient', '@angular/common/http'); + fileServices.addNamedImport('HttpClient', '@angular/common/http'); } - file.addNamedImport({ isTypeOnly: true, name: 'Observable' }, 'rxjs'); + fileServices.addNamedImport({ isTypeOnly: true, name: 'Observable' }, 'rxjs'); } else { - file.addNamedImport({ isTypeOnly: true, name: 'CancelablePromise' }, './core/CancelablePromise'); + fileServices.addNamedImport({ isTypeOnly: true, name: 'CancelablePromise' }, './core/CancelablePromise'); } if (config.serviceResponse === 'response') { - file.addNamedImport({ isTypeOnly: true, name: 'ApiResult' }, './core/ApiResult'); + fileServices.addNamedImport({ isTypeOnly: true, name: 'ApiResult' }, './core/ApiResult'); } if (config.name) { - file.addNamedImport( + fileServices.addNamedImport( { isTypeOnly: config.client !== 'angular', name: 'BaseHttpRequest' }, './core/BaseHttpRequest' ); } else { - file.addNamedImport('OpenAPI', './core/OpenAPI'); - file.addNamedImport({ alias: '__request', name: 'request' }, './core/request'); + fileServices.addNamedImport('OpenAPI', './core/OpenAPI'); + fileServices.addNamedImport({ alias: '__request', name: 'request' }, './core/request'); } // Import all models required by the services. const models = imports.filter(unique).map(imp => ({ isTypeOnly: true, name: imp })); - file.addNamedImport(models, './models'); + fileServices.addNamedImport(models, './models'); - const data = [file.toString(), ...results].join('\n\n'); + fileServices.add(...results); - await writeFileSync(path.resolve(outputPath, 'services.ts'), data); + if (config.exportServices) { + fileServices.write('\n\n'); + } }; diff --git a/packages/openapi-ts/test/__snapshots__/test/generated/v2/enums.gen.ts.snap b/packages/openapi-ts/test/__snapshots__/test/generated/v2/enums.gen.ts.snap new file mode 100644 index 000000000..0e939b049 --- /dev/null +++ b/packages/openapi-ts/test/__snapshots__/test/generated/v2/enums.gen.ts.snap @@ -0,0 +1,74 @@ +// This file is auto-generated by @hey-api/openapi-ts + +/** + * This is a simple enum with strings + */ +export const EnumWithStringsEnum = { + SUCCESS: 'Success', + WARNING: 'Warning', + ERROR: 'Error', + _SINGLE_QUOTE_: "'Single Quote'", + _DOUBLE_QUOTES_: '"Double Quotes"', + NON_ASCII__ØÆÅÔÖ_ØÆÅÔÖ字符串: 'Non-ascii: øæåôöØÆÅÔÖ字符串', +} as const; + +/** + * This is a simple enum with numbers + */ +export const EnumWithNumbersEnum = { + _1: 1, + _2: 2, + _3: 3, + '_1.1': 1.1, + '_1.2': 1.2, + '_1.3': 1.3, + _100: 100, + _200: 200, + _300: 300, + '_-100': -100, + '_-200': -200, + '_-300': -300, + '_-1.1': -1.1, + '_-1.2': -1.2, + '_-1.3': -1.3, +} as const; + +/** + * This is a simple enum with numbers + */ +export const EnumWithExtensionsEnum = { + /** + * Used when the status of something is successful + */ + CUSTOM_SUCCESS: 200, + /** + * Used when the status of something has a warning + */ + CUSTOM_WARNING: 400, + /** + * Used when the status of something has an error + */ + CUSTOM_ERROR: 500, +} as const; + +/** + * This is a simple enum with strings + */ +export const TestEnum = { + SUCCESS: 'Success', + WARNING: 'Warning', + ERROR: 'Error', + ØÆÅ字符串: 'ØÆÅ字符串', +} as const; + +/** + * These are the HTTP error code enums + */ +export const StatusCodeEnum = { + _100: '100', + _200_FOO: '200 FOO', + _300_FOO_BAR: '300 FOO_BAR', + _400_FOO_BAR: '400 foo-bar', + _500_FOO_BAR: '500 foo.bar', + _600_FOO_BAR: '600 foo&bar', +} as const; diff --git a/packages/openapi-ts/test/__snapshots__/test/generated/v2/models.ts.snap b/packages/openapi-ts/test/__snapshots__/test/generated/v2/models.ts.snap index 82639e745..14d84855b 100644 --- a/packages/openapi-ts/test/__snapshots__/test/generated/v2/models.ts.snap +++ b/packages/openapi-ts/test/__snapshots__/test/generated/v2/models.ts.snap @@ -84,38 +84,11 @@ export type EnumWithStrings = | '"Double Quotes"' | 'Non-ascii: øæåôöØÆÅÔÖ字符串'; -export const EnumWithStringsEnum = { - SUCCESS: 'Success', - WARNING: 'Warning', - ERROR: 'Error', - _SINGLE_QUOTE_: "'Single Quote'", - _DOUBLE_QUOTES_: '"Double Quotes"', - NON_ASCII__ØÆÅÔÖ_ØÆÅÔÖ字符串: 'Non-ascii: øæåôöØÆÅÔÖ字符串', -} as const; - /** * This is a simple enum with numbers */ export type EnumWithNumbers = 1 | 2 | 3 | 1.1 | 1.2 | 1.3 | 100 | 200 | 300 | -100 | -200 | -300 | -1.1 | -1.2 | -1.3; -export const EnumWithNumbersEnum = { - _1: 1, - _2: 2, - _3: 3, - '_1.1': 1.1, - '_1.2': 1.2, - '_1.3': 1.3, - _100: 100, - _200: 200, - _300: 300, - '_-100': -100, - '_-200': -200, - '_-300': -300, - '_-1.1': -1.1, - '_-1.2': -1.2, - '_-1.3': -1.3, -} as const; - /** * Success=1,Warning=2,Error=3 */ @@ -126,21 +99,6 @@ export type EnumFromDescription = number; */ export type EnumWithExtensions = 200 | 400 | 500; -export const EnumWithExtensionsEnum = { - /** - * Used when the status of something is successful - */ - CUSTOM_SUCCESS: 200, - /** - * Used when the status of something has a warning - */ - CUSTOM_WARNING: 400, - /** - * Used when the status of something has an error - */ - CUSTOM_ERROR: 500, -} as const; - /** * This is a simple array with numbers */ @@ -272,22 +230,6 @@ export type ModelWithEnum = { bool?: boolean; }; -export const TestEnum = { - SUCCESS: 'Success', - WARNING: 'Warning', - ERROR: 'Error', - ØÆÅ字符串: 'ØÆÅ字符串', -} as const; - -export const StatusCodeEnum = { - _100: '100', - _200_FOO: '200 FOO', - _300_FOO_BAR: '300 FOO_BAR', - _400_FOO_BAR: '400 foo-bar', - _500_FOO_BAR: '500 foo.bar', - _600_FOO_BAR: '600 foo&bar', -} as const; - /** * This is a model with one enum */ diff --git a/packages/openapi-ts/test/__snapshots__/test/generated/v3/enums.gen.ts.snap b/packages/openapi-ts/test/__snapshots__/test/generated/v3/enums.gen.ts.snap new file mode 100644 index 000000000..5c355399f --- /dev/null +++ b/packages/openapi-ts/test/__snapshots__/test/generated/v3/enums.gen.ts.snap @@ -0,0 +1,111 @@ +// This file is auto-generated by @hey-api/openapi-ts + +/** + * This is a simple enum with strings + */ +export const EnumWithStringsEnum = { + SUCCESS: 'Success', + WARNING: 'Warning', + ERROR: 'Error', + _SINGLE_QUOTE_: "'Single Quote'", + _DOUBLE_QUOTES_: '"Double Quotes"', + NON_ASCII__ØÆÅÔÖ_ØÆÅÔÖ字符串: 'Non-ascii: øæåôöØÆÅÔÖ字符串', +} as const; + +export const EnumWithReplacedCharactersEnum = { + _SINGLE_QUOTE_: "'Single Quote'", + _DOUBLE_QUOTES_: '"Double Quotes"', + ØÆÅÔÖ_ØÆÅÔÖ字符串: 'øæåôöØÆÅÔÖ字符串', + '_3.1': 3.1, + EMPTY_STRING: '', +} as const; + +/** + * This is a simple enum with numbers + */ +export const EnumWithNumbersEnum = { + _1: 1, + _2: 2, + _3: 3, + '_1.1': 1.1, + '_1.2': 1.2, + '_1.3': 1.3, + _100: 100, + _200: 200, + _300: 300, + '_-100': -100, + '_-200': -200, + '_-300': -300, + '_-1.1': -1.1, + '_-1.2': -1.2, + '_-1.3': -1.3, +} as const; + +/** + * This is a simple enum with numbers + */ +export const EnumWithExtensionsEnum = { + /** + * Used when the status of something is successful + */ + CUSTOM_SUCCESS: 200, + /** + * Used when the status of something has a warning + */ + CUSTOM_WARNING: 400, + /** + * Used when the status of something has an error + */ + CUSTOM_ERROR: 500, +} as const; + +export const EnumWithXEnumNamesEnum = { + zero: 0, + one: 1, + two: 2, +} as const; + +/** + * This is a simple enum with strings + */ +export const FooBarEnumEnum = { + SUCCESS: 'Success', + WARNING: 'Warning', + ERROR: 'Error', + ØÆÅ字符串: 'ØÆÅ字符串', +} as const; + +/** + * These are the HTTP error code enums + */ +export const StatusCodeEnum = { + _100: '100', + _200_FOO: '200 FOO', + _300_FOO_BAR: '300 FOO_BAR', + _400_FOO_BAR: '400 foo-bar', + _500_FOO_BAR: '500 foo.bar', + _600_FOO_BAR: '600 foo&bar', +} as const; + +export const FooBarBazQuxEnum = { + _3_0: '3.0', +} as const; + +export const Enum1Enum = { + BIRD: 'Bird', + DOG: 'Dog', +} as const; + +export const FooEnum = { + BAR: 'Bar', +} as const; + +export const ModelWithNestedArrayEnumsDataFooEnum = { + FOO: 'foo', + BAR: 'bar', +} as const; + +export const ModelWithNestedArrayEnumsDataBarEnum = { + BAZ: 'baz', + QUX: 'qux', +} as const; diff --git a/packages/openapi-ts/test/__snapshots__/test/generated/v3/models.ts.snap b/packages/openapi-ts/test/__snapshots__/test/generated/v3/models.ts.snap index 61e9914f8..b4fdd5a5c 100644 --- a/packages/openapi-ts/test/__snapshots__/test/generated/v3/models.ts.snap +++ b/packages/openapi-ts/test/__snapshots__/test/generated/v3/models.ts.snap @@ -84,48 +84,13 @@ export type EnumWithStrings = | '"Double Quotes"' | 'Non-ascii: øæåôöØÆÅÔÖ字符串'; -export const EnumWithStringsEnum = { - SUCCESS: 'Success', - WARNING: 'Warning', - ERROR: 'Error', - _SINGLE_QUOTE_: "'Single Quote'", - _DOUBLE_QUOTES_: '"Double Quotes"', - NON_ASCII__ØÆÅÔÖ_ØÆÅÔÖ字符串: 'Non-ascii: øæåôöØÆÅÔÖ字符串', -} as const; - export type EnumWithReplacedCharacters = "'Single Quote'" | '"Double Quotes"' | 'øæåôöØÆÅÔÖ字符串' | 3.1 | ''; -export const EnumWithReplacedCharactersEnum = { - _SINGLE_QUOTE_: "'Single Quote'", - _DOUBLE_QUOTES_: '"Double Quotes"', - ØÆÅÔÖ_ØÆÅÔÖ字符串: 'øæåôöØÆÅÔÖ字符串', - '_3.1': 3.1, - EMPTY_STRING: '', -} as const; - /** * This is a simple enum with numbers */ export type EnumWithNumbers = 1 | 2 | 3 | 1.1 | 1.2 | 1.3 | 100 | 200 | 300 | -100 | -200 | -300 | -1.1 | -1.2 | -1.3; -export const EnumWithNumbersEnum = { - _1: 1, - _2: 2, - _3: 3, - '_1.1': 1.1, - '_1.2': 1.2, - '_1.3': 1.3, - _100: 100, - _200: 200, - _300: 300, - '_-100': -100, - '_-200': -200, - '_-300': -300, - '_-1.1': -1.1, - '_-1.2': -1.2, - '_-1.3': -1.3, -} as const; - /** * Success=1,Warning=2,Error=3 */ @@ -136,29 +101,8 @@ export type EnumFromDescription = number; */ export type EnumWithExtensions = 200 | 400 | 500; -export const EnumWithExtensionsEnum = { - /** - * Used when the status of something is successful - */ - CUSTOM_SUCCESS: 200, - /** - * Used when the status of something has a warning - */ - CUSTOM_WARNING: 400, - /** - * Used when the status of something has an error - */ - CUSTOM_ERROR: 500, -} as const; - export type EnumWithXEnumNames = 0 | 1 | 2; -export const EnumWithXEnumNamesEnum = { - zero: 0, - one: 1, - two: 2, -} as const; - /** * This is a simple array with numbers */ @@ -319,13 +263,6 @@ export type ModelWithNullableString = { 'foo_bar-enum'?: 'Success' | 'Warning' | 'Error' | 'ØÆÅ字符串'; }; -export const FooBarEnumEnum = { - SUCCESS: 'Success', - WARNING: 'Warning', - ERROR: 'Error', - ØÆÅ字符串: 'ØÆÅ字符串', -} as const; - /** * This is a model with one enum */ @@ -344,22 +281,6 @@ export type ModelWithEnum = { bool?: boolean; }; -export const FooBarEnumEnum2 = { - SUCCESS: 'Success', - WARNING: 'Warning', - ERROR: 'Error', - ØÆÅ字符串: 'ØÆÅ字符串', -} as const; - -export const StatusCodeEnum = { - _100: '100', - _200_FOO: '200 FOO', - _300_FOO_BAR: '300 FOO_BAR', - _400_FOO_BAR: '400 foo-bar', - _500_FOO_BAR: '500 foo.bar', - _600_FOO_BAR: '600 foo&bar', -} as const; - /** * This is a model with one enum with escaped name */ @@ -367,10 +288,6 @@ export type ModelWithEnumWithHyphen = { 'foo-bar-baz-qux'?: '3.0'; }; -export const FooBarBazQuxEnum = { - _3_0: '3.0', -} as const; - /** * This is a model with one enum */ @@ -395,13 +312,6 @@ export type ModelWithNestedEnums = { 'foo_bar-enum'?: 'Success' | 'Warning' | 'Error' | 'ØÆÅ字符串'; }; -export const FooBarEnumEnum3 = { - SUCCESS: 'Success', - WARNING: 'Warning', - ERROR: 'Error', - ØÆÅ字符串: 'ØÆÅ字符串', -} as const; - /** * This is a model with one property containing a reference */ @@ -521,11 +431,6 @@ export type CompositionWithNestedAnyAndTypeNull = { export type Enum1 = 'Bird' | 'Dog'; -export const Enum1Enum = { - BIRD: 'Bird', - DOG: 'Dog', -} as const; - export type ConstValue = 'ConstValue'; /** @@ -797,24 +702,10 @@ export type ModelWithOneOfEnum = foo: 'Corge'; }; -export const FooEnum = { - BAR: 'Bar', -} as const; - export type ModelWithNestedArrayEnumsDataFoo = 'foo' | 'bar'; -export const ModelWithNestedArrayEnumsDataFooEnum = { - FOO: 'foo', - BAR: 'bar', -} as const; - export type ModelWithNestedArrayEnumsDataBar = 'baz' | 'qux'; -export const ModelWithNestedArrayEnumsDataBarEnum = { - BAZ: 'baz', - QUX: 'qux', -} as const; - export type ModelWithNestedArrayEnumsData = { foo?: Array; bar?: Array; diff --git a/packages/openapi-ts/test/__snapshots__/test/generated/v3_client/enums.gen.ts.snap b/packages/openapi-ts/test/__snapshots__/test/generated/v3_client/enums.gen.ts.snap new file mode 100644 index 000000000..5c355399f --- /dev/null +++ b/packages/openapi-ts/test/__snapshots__/test/generated/v3_client/enums.gen.ts.snap @@ -0,0 +1,111 @@ +// This file is auto-generated by @hey-api/openapi-ts + +/** + * This is a simple enum with strings + */ +export const EnumWithStringsEnum = { + SUCCESS: 'Success', + WARNING: 'Warning', + ERROR: 'Error', + _SINGLE_QUOTE_: "'Single Quote'", + _DOUBLE_QUOTES_: '"Double Quotes"', + NON_ASCII__ØÆÅÔÖ_ØÆÅÔÖ字符串: 'Non-ascii: øæåôöØÆÅÔÖ字符串', +} as const; + +export const EnumWithReplacedCharactersEnum = { + _SINGLE_QUOTE_: "'Single Quote'", + _DOUBLE_QUOTES_: '"Double Quotes"', + ØÆÅÔÖ_ØÆÅÔÖ字符串: 'øæåôöØÆÅÔÖ字符串', + '_3.1': 3.1, + EMPTY_STRING: '', +} as const; + +/** + * This is a simple enum with numbers + */ +export const EnumWithNumbersEnum = { + _1: 1, + _2: 2, + _3: 3, + '_1.1': 1.1, + '_1.2': 1.2, + '_1.3': 1.3, + _100: 100, + _200: 200, + _300: 300, + '_-100': -100, + '_-200': -200, + '_-300': -300, + '_-1.1': -1.1, + '_-1.2': -1.2, + '_-1.3': -1.3, +} as const; + +/** + * This is a simple enum with numbers + */ +export const EnumWithExtensionsEnum = { + /** + * Used when the status of something is successful + */ + CUSTOM_SUCCESS: 200, + /** + * Used when the status of something has a warning + */ + CUSTOM_WARNING: 400, + /** + * Used when the status of something has an error + */ + CUSTOM_ERROR: 500, +} as const; + +export const EnumWithXEnumNamesEnum = { + zero: 0, + one: 1, + two: 2, +} as const; + +/** + * This is a simple enum with strings + */ +export const FooBarEnumEnum = { + SUCCESS: 'Success', + WARNING: 'Warning', + ERROR: 'Error', + ØÆÅ字符串: 'ØÆÅ字符串', +} as const; + +/** + * These are the HTTP error code enums + */ +export const StatusCodeEnum = { + _100: '100', + _200_FOO: '200 FOO', + _300_FOO_BAR: '300 FOO_BAR', + _400_FOO_BAR: '400 foo-bar', + _500_FOO_BAR: '500 foo.bar', + _600_FOO_BAR: '600 foo&bar', +} as const; + +export const FooBarBazQuxEnum = { + _3_0: '3.0', +} as const; + +export const Enum1Enum = { + BIRD: 'Bird', + DOG: 'Dog', +} as const; + +export const FooEnum = { + BAR: 'Bar', +} as const; + +export const ModelWithNestedArrayEnumsDataFooEnum = { + FOO: 'foo', + BAR: 'bar', +} as const; + +export const ModelWithNestedArrayEnumsDataBarEnum = { + BAZ: 'baz', + QUX: 'qux', +} as const; diff --git a/packages/openapi-ts/test/__snapshots__/test/generated/v3_client/models.ts.snap b/packages/openapi-ts/test/__snapshots__/test/generated/v3_client/models.ts.snap index 233caa54d..178a51eb7 100644 --- a/packages/openapi-ts/test/__snapshots__/test/generated/v3_client/models.ts.snap +++ b/packages/openapi-ts/test/__snapshots__/test/generated/v3_client/models.ts.snap @@ -84,48 +84,13 @@ export type EnumWithStrings = | '"Double Quotes"' | 'Non-ascii: øæåôöØÆÅÔÖ字符串'; -export const EnumWithStringsEnum = { - SUCCESS: 'Success', - WARNING: 'Warning', - ERROR: 'Error', - _SINGLE_QUOTE_: "'Single Quote'", - _DOUBLE_QUOTES_: '"Double Quotes"', - NON_ASCII__ØÆÅÔÖ_ØÆÅÔÖ字符串: 'Non-ascii: øæåôöØÆÅÔÖ字符串', -} as const; - export type EnumWithReplacedCharacters = "'Single Quote'" | '"Double Quotes"' | 'øæåôöØÆÅÔÖ字符串' | 3.1 | ''; -export const EnumWithReplacedCharactersEnum = { - _SINGLE_QUOTE_: "'Single Quote'", - _DOUBLE_QUOTES_: '"Double Quotes"', - ØÆÅÔÖ_ØÆÅÔÖ字符串: 'øæåôöØÆÅÔÖ字符串', - '_3.1': 3.1, - EMPTY_STRING: '', -} as const; - /** * This is a simple enum with numbers */ export type EnumWithNumbers = 1 | 2 | 3 | 1.1 | 1.2 | 1.3 | 100 | 200 | 300 | -100 | -200 | -300 | -1.1 | -1.2 | -1.3; -export const EnumWithNumbersEnum = { - _1: 1, - _2: 2, - _3: 3, - '_1.1': 1.1, - '_1.2': 1.2, - '_1.3': 1.3, - _100: 100, - _200: 200, - _300: 300, - '_-100': -100, - '_-200': -200, - '_-300': -300, - '_-1.1': -1.1, - '_-1.2': -1.2, - '_-1.3': -1.3, -} as const; - /** * Success=1,Warning=2,Error=3 */ @@ -136,29 +101,8 @@ export type EnumFromDescription = number; */ export type EnumWithExtensions = 200 | 400 | 500; -export const EnumWithExtensionsEnum = { - /** - * Used when the status of something is successful - */ - CUSTOM_SUCCESS: 200, - /** - * Used when the status of something has a warning - */ - CUSTOM_WARNING: 400, - /** - * Used when the status of something has an error - */ - CUSTOM_ERROR: 500, -} as const; - export type EnumWithXEnumNames = 0 | 1 | 2; -export const EnumWithXEnumNamesEnum = { - zero: 0, - one: 1, - two: 2, -} as const; - /** * This is a simple array with numbers */ @@ -319,13 +263,6 @@ export type ModelWithNullableString = { 'foo_bar-enum'?: 'Success' | 'Warning' | 'Error' | 'ØÆÅ字符串'; }; -export const FooBarEnumEnum = { - SUCCESS: 'Success', - WARNING: 'Warning', - ERROR: 'Error', - ØÆÅ字符串: 'ØÆÅ字符串', -} as const; - /** * This is a model with one enum */ @@ -344,22 +281,6 @@ export type ModelWithEnum = { bool?: boolean; }; -export const FooBarEnumEnum2 = { - SUCCESS: 'Success', - WARNING: 'Warning', - ERROR: 'Error', - ØÆÅ字符串: 'ØÆÅ字符串', -} as const; - -export const StatusCodeEnum = { - _100: '100', - _200_FOO: '200 FOO', - _300_FOO_BAR: '300 FOO_BAR', - _400_FOO_BAR: '400 foo-bar', - _500_FOO_BAR: '500 foo.bar', - _600_FOO_BAR: '600 foo&bar', -} as const; - /** * This is a model with one enum with escaped name */ @@ -367,10 +288,6 @@ export type ModelWithEnumWithHyphen = { 'foo-bar-baz-qux'?: '3.0'; }; -export const FooBarBazQuxEnum = { - _3_0: '3.0', -} as const; - /** * This is a model with one enum */ @@ -395,13 +312,6 @@ export type ModelWithNestedEnums = { 'foo_bar-enum'?: 'Success' | 'Warning' | 'Error' | 'ØÆÅ字符串'; }; -export const FooBarEnumEnum3 = { - SUCCESS: 'Success', - WARNING: 'Warning', - ERROR: 'Error', - ØÆÅ字符串: 'ØÆÅ字符串', -} as const; - /** * This is a model with one property containing a reference */ @@ -521,11 +431,6 @@ export type CompositionWithNestedAnyAndTypeNull = { export type Enum1 = 'Bird' | 'Dog'; -export const Enum1Enum = { - BIRD: 'Bird', - DOG: 'Dog', -} as const; - export type ConstValue = 'ConstValue'; /** @@ -797,24 +702,10 @@ export type ModelWithOneOfEnum = foo: 'Corge'; }; -export const FooEnum = { - BAR: 'Bar', -} as const; - export type ModelWithNestedArrayEnumsDataFoo = 'foo' | 'bar'; -export const ModelWithNestedArrayEnumsDataFooEnum = { - FOO: 'foo', - BAR: 'bar', -} as const; - export type ModelWithNestedArrayEnumsDataBar = 'baz' | 'qux'; -export const ModelWithNestedArrayEnumsDataBarEnum = { - BAZ: 'baz', - QUX: 'qux', -} as const; - export type ModelWithNestedArrayEnumsData = { foo?: Array; bar?: Array; diff --git a/packages/openapi-ts/test/__snapshots__/test/generated/v3_enums_typescript/enums.gen.ts.snap b/packages/openapi-ts/test/__snapshots__/test/generated/v3_enums_typescript/enums.gen.ts.snap new file mode 100644 index 000000000..dfb108b6e --- /dev/null +++ b/packages/openapi-ts/test/__snapshots__/test/generated/v3_enums_typescript/enums.gen.ts.snap @@ -0,0 +1,111 @@ +// This file is auto-generated by @hey-api/openapi-ts + +/** + * This is a simple enum with strings + */ +export enum EnumWithStringsEnum { + SUCCESS = 'Success', + WARNING = 'Warning', + ERROR = 'Error', + _SINGLE_QUOTE_ = "'Single Quote'", + _DOUBLE_QUOTES_ = '"Double Quotes"', + NON_ASCII__ØÆÅÔÖ_ØÆÅÔÖ字符串 = 'Non-ascii: øæåôöØÆÅÔÖ字符串', +} + +export enum EnumWithReplacedCharactersEnum { + _SINGLE_QUOTE_ = "'Single Quote'", + _DOUBLE_QUOTES_ = '"Double Quotes"', + ØÆÅÔÖ_ØÆÅÔÖ字符串 = 'øæåôöØÆÅÔÖ字符串', + '_3.1' = 3.1, + EMPTY_STRING = '', +} + +/** + * This is a simple enum with numbers + */ +export enum EnumWithNumbersEnum { + '_1' = 1, + '_2' = 2, + '_3' = 3, + '_1.1' = 1.1, + '_1.2' = 1.2, + '_1.3' = 1.3, + '_100' = 100, + '_200' = 200, + '_300' = 300, + '_-100' = -100, + '_-200' = -200, + '_-300' = -300, + '_-1.1' = -1.1, + '_-1.2' = -1.2, + '_-1.3' = -1.3, +} + +/** + * This is a simple enum with numbers + */ +export enum EnumWithExtensionsEnum { + /** + * Used when the status of something is successful + */ + CUSTOM_SUCCESS = 200, + /** + * Used when the status of something has a warning + */ + CUSTOM_WARNING = 400, + /** + * Used when the status of something has an error + */ + CUSTOM_ERROR = 500, +} + +export enum EnumWithXEnumNamesEnum { + zero = 0, + one = 1, + two = 2, +} + +/** + * This is a simple enum with strings + */ +export enum FooBarEnumEnum { + SUCCESS = 'Success', + WARNING = 'Warning', + ERROR = 'Error', + ØÆÅ字符串 = 'ØÆÅ字符串', +} + +/** + * These are the HTTP error code enums + */ +export enum StatusCodeEnum { + _100 = '100', + _200_FOO = '200 FOO', + _300_FOO_BAR = '300 FOO_BAR', + _400_FOO_BAR = '400 foo-bar', + _500_FOO_BAR = '500 foo.bar', + _600_FOO_BAR = '600 foo&bar', +} + +export enum FooBarBazQuxEnum { + _3_0 = '3.0', +} + +export enum Enum1Enum { + BIRD = 'Bird', + DOG = 'Dog', +} + +export enum FooEnum { + BAR = 'Bar', +} + +export enum ModelWithNestedArrayEnumsDataFooEnum { + FOO = 'foo', + BAR = 'bar', +} + +export enum ModelWithNestedArrayEnumsDataBarEnum { + BAZ = 'baz', + QUX = 'qux', +} diff --git a/packages/openapi-ts/test/__snapshots__/test/generated/v3_enums_typescript/models.ts.snap b/packages/openapi-ts/test/__snapshots__/test/generated/v3_enums_typescript/models.ts.snap index 20111fad2..b4fdd5a5c 100644 --- a/packages/openapi-ts/test/__snapshots__/test/generated/v3_enums_typescript/models.ts.snap +++ b/packages/openapi-ts/test/__snapshots__/test/generated/v3_enums_typescript/models.ts.snap @@ -76,43 +76,20 @@ export type SimpleStringWithPattern = string | null; /** * This is a simple enum with strings */ -export enum EnumWithStrings { - SUCCESS = 'Success', - WARNING = 'Warning', - ERROR = 'Error', - _SINGLE_QUOTE_ = "'Single Quote'", - _DOUBLE_QUOTES_ = '"Double Quotes"', - NON_ASCII__ØÆÅÔÖ_ØÆÅÔÖ字符串 = 'Non-ascii: øæåôöØÆÅÔÖ字符串', -} - -export enum EnumWithReplacedCharacters { - _SINGLE_QUOTE_ = "'Single Quote'", - _DOUBLE_QUOTES_ = '"Double Quotes"', - ØÆÅÔÖ_ØÆÅÔÖ字符串 = 'øæåôöØÆÅÔÖ字符串', - '_3.1' = 3.1, - EMPTY_STRING = '', -} +export type EnumWithStrings = + | 'Success' + | 'Warning' + | 'Error' + | "'Single Quote'" + | '"Double Quotes"' + | 'Non-ascii: øæåôöØÆÅÔÖ字符串'; + +export type EnumWithReplacedCharacters = "'Single Quote'" | '"Double Quotes"' | 'øæåôöØÆÅÔÖ字符串' | 3.1 | ''; /** * This is a simple enum with numbers */ -export enum EnumWithNumbers { - '_1' = 1, - '_2' = 2, - '_3' = 3, - '_1.1' = 1.1, - '_1.2' = 1.2, - '_1.3' = 1.3, - '_100' = 100, - '_200' = 200, - '_300' = 300, - '_-100' = -100, - '_-200' = -200, - '_-300' = -300, - '_-1.1' = -1.1, - '_-1.2' = -1.2, - '_-1.3' = -1.3, -} +export type EnumWithNumbers = 1 | 2 | 3 | 1.1 | 1.2 | 1.3 | 100 | 200 | 300 | -100 | -200 | -300 | -1.1 | -1.2 | -1.3; /** * Success=1,Warning=2,Error=3 @@ -122,26 +99,9 @@ export type EnumFromDescription = number; /** * This is a simple enum with numbers */ -export enum EnumWithExtensions { - /** - * Used when the status of something is successful - */ - CUSTOM_SUCCESS = 200, - /** - * Used when the status of something has a warning - */ - CUSTOM_WARNING = 400, - /** - * Used when the status of something has an error - */ - CUSTOM_ERROR = 500, -} +export type EnumWithExtensions = 200 | 400 | 500; -export enum EnumWithXEnumNames { - zero = 0, - one = 1, - two = 2, -} +export type EnumWithXEnumNames = 0 | 1 | 2; /** * This is a simple array with numbers @@ -469,10 +429,7 @@ export type CompositionWithNestedAnyAndTypeNull = { propA?: Array | Array; }; -export enum Enum1 { - BIRD = 'Bird', - DOG = 'Dog', -} +export type Enum1 = 'Bird' | 'Dog'; export type ConstValue = 'ConstValue'; @@ -745,15 +702,9 @@ export type ModelWithOneOfEnum = foo: 'Corge'; }; -export enum ModelWithNestedArrayEnumsDataFoo { - FOO = 'foo', - BAR = 'bar', -} +export type ModelWithNestedArrayEnumsDataFoo = 'foo' | 'bar'; -export enum ModelWithNestedArrayEnumsDataBar { - BAZ = 'baz', - QUX = 'qux', -} +export type ModelWithNestedArrayEnumsDataBar = 'baz' | 'qux'; export type ModelWithNestedArrayEnumsData = { foo?: Array; diff --git a/packages/openapi-ts/test/__snapshots__/test/generated/v3_experimental/core/ApiError.ts.snap b/packages/openapi-ts/test/__snapshots__/test/generated/v3_experimental/core/ApiError.ts.snap deleted file mode 100644 index 2c11b4136..000000000 --- a/packages/openapi-ts/test/__snapshots__/test/generated/v3_experimental/core/ApiError.ts.snap +++ /dev/null @@ -1,21 +0,0 @@ -import type { ApiRequestOptions } from './ApiRequestOptions'; -import type { ApiResult } from './ApiResult'; - -export class ApiError extends Error { - public readonly url: string; - public readonly status: number; - public readonly statusText: string; - public readonly body: unknown; - public readonly request: ApiRequestOptions; - - constructor(request: ApiRequestOptions, response: ApiResult, message: string) { - super(message); - - this.name = 'ApiError'; - this.url = response.url; - this.status = response.status; - this.statusText = response.statusText; - this.body = response.body; - this.request = request; - } -} diff --git a/packages/openapi-ts/test/__snapshots__/test/generated/v3_experimental/core/ApiRequestOptions.ts.snap b/packages/openapi-ts/test/__snapshots__/test/generated/v3_experimental/core/ApiRequestOptions.ts.snap deleted file mode 100644 index e93003ee7..000000000 --- a/packages/openapi-ts/test/__snapshots__/test/generated/v3_experimental/core/ApiRequestOptions.ts.snap +++ /dev/null @@ -1,13 +0,0 @@ -export type ApiRequestOptions = { - readonly method: 'GET' | 'PUT' | 'POST' | 'DELETE' | 'OPTIONS' | 'HEAD' | 'PATCH'; - readonly url: string; - readonly path?: Record; - readonly cookies?: Record; - readonly headers?: Record; - readonly query?: Record; - readonly formData?: Record; - readonly body?: any; - readonly mediaType?: string; - readonly responseHeader?: string; - readonly errors?: Record; -}; diff --git a/packages/openapi-ts/test/__snapshots__/test/generated/v3_experimental/core/ApiResult.ts.snap b/packages/openapi-ts/test/__snapshots__/test/generated/v3_experimental/core/ApiResult.ts.snap deleted file mode 100644 index caa79c2ea..000000000 --- a/packages/openapi-ts/test/__snapshots__/test/generated/v3_experimental/core/ApiResult.ts.snap +++ /dev/null @@ -1,7 +0,0 @@ -export type ApiResult = { - readonly body: TData; - readonly ok: boolean; - readonly status: number; - readonly statusText: string; - readonly url: string; -}; diff --git a/packages/openapi-ts/test/__snapshots__/test/generated/v3_experimental/core/CancelablePromise.ts.snap b/packages/openapi-ts/test/__snapshots__/test/generated/v3_experimental/core/CancelablePromise.ts.snap deleted file mode 100644 index e6b03b6a2..000000000 --- a/packages/openapi-ts/test/__snapshots__/test/generated/v3_experimental/core/CancelablePromise.ts.snap +++ /dev/null @@ -1,126 +0,0 @@ -export class CancelError extends Error { - constructor(message: string) { - super(message); - this.name = 'CancelError'; - } - - public get isCancelled(): boolean { - return true; - } -} - -export interface OnCancel { - readonly isResolved: boolean; - readonly isRejected: boolean; - readonly isCancelled: boolean; - - (cancelHandler: () => void): void; -} - -export class CancelablePromise implements Promise { - private _isResolved: boolean; - private _isRejected: boolean; - private _isCancelled: boolean; - readonly cancelHandlers: (() => void)[]; - readonly promise: Promise; - private _resolve?: (value: T | PromiseLike) => void; - private _reject?: (reason?: unknown) => void; - - constructor( - executor: ( - resolve: (value: T | PromiseLike) => void, - reject: (reason?: unknown) => void, - onCancel: OnCancel - ) => void - ) { - this._isResolved = false; - this._isRejected = false; - this._isCancelled = false; - this.cancelHandlers = []; - this.promise = new Promise((resolve, reject) => { - this._resolve = resolve; - this._reject = reject; - - const onResolve = (value: T | PromiseLike): void => { - if (this._isResolved || this._isRejected || this._isCancelled) { - return; - } - this._isResolved = true; - if (this._resolve) this._resolve(value); - }; - - const onReject = (reason?: unknown): void => { - if (this._isResolved || this._isRejected || this._isCancelled) { - return; - } - this._isRejected = true; - if (this._reject) this._reject(reason); - }; - - const onCancel = (cancelHandler: () => void): void => { - if (this._isResolved || this._isRejected || this._isCancelled) { - return; - } - this.cancelHandlers.push(cancelHandler); - }; - - Object.defineProperty(onCancel, 'isResolved', { - get: (): boolean => this._isResolved, - }); - - Object.defineProperty(onCancel, 'isRejected', { - get: (): boolean => this._isRejected, - }); - - Object.defineProperty(onCancel, 'isCancelled', { - get: (): boolean => this._isCancelled, - }); - - return executor(onResolve, onReject, onCancel as OnCancel); - }); - } - - get [Symbol.toStringTag]() { - return 'Cancellable Promise'; - } - - public then( - onFulfilled?: ((value: T) => TResult1 | PromiseLike) | null, - onRejected?: ((reason: unknown) => TResult2 | PromiseLike) | null - ): Promise { - return this.promise.then(onFulfilled, onRejected); - } - - public catch( - onRejected?: ((reason: unknown) => TResult | PromiseLike) | null - ): Promise { - return this.promise.catch(onRejected); - } - - public finally(onFinally?: (() => void) | null): Promise { - return this.promise.finally(onFinally); - } - - public cancel(): void { - if (this._isResolved || this._isRejected || this._isCancelled) { - return; - } - this._isCancelled = true; - if (this.cancelHandlers.length) { - try { - for (const cancelHandler of this.cancelHandlers) { - cancelHandler(); - } - } catch (error) { - console.warn('Cancellation threw an error', error); - return; - } - } - this.cancelHandlers.length = 0; - if (this._reject) this._reject(new CancelError('Request aborted')); - } - - public get isCancelled(): boolean { - return this._isCancelled; - } -} diff --git a/packages/openapi-ts/test/__snapshots__/test/generated/v3_experimental/core/OpenAPI.ts.snap b/packages/openapi-ts/test/__snapshots__/test/generated/v3_experimental/core/OpenAPI.ts.snap deleted file mode 100644 index 64be05544..000000000 --- a/packages/openapi-ts/test/__snapshots__/test/generated/v3_experimental/core/OpenAPI.ts.snap +++ /dev/null @@ -1,50 +0,0 @@ -import type { ApiRequestOptions } from './ApiRequestOptions'; - -type Headers = Record; -type Middleware = (value: T) => T | Promise; -type Resolver = (options: ApiRequestOptions) => Promise; - -export class Interceptors { - _fns: Middleware[]; - - constructor() { - this._fns = []; - } - - eject(fn: Middleware) { - const index = this._fns.indexOf(fn); - if (index !== -1) { - this._fns = [...this._fns.slice(0, index), ...this._fns.slice(index + 1)]; - } - } - - use(fn: Middleware) { - this._fns = [...this._fns, fn]; - } -} - -export type OpenAPIConfig = { - BASE: string; - CREDENTIALS: 'include' | 'omit' | 'same-origin'; - ENCODE_PATH?: ((path: string) => string) | undefined; - HEADERS?: Headers | Resolver | undefined; - PASSWORD?: string | Resolver | undefined; - TOKEN?: string | Resolver | undefined; - USERNAME?: string | Resolver | undefined; - VERSION: string; - WITH_CREDENTIALS: boolean; - interceptors: { request: Interceptors; response: Interceptors }; -}; - -export const OpenAPI: OpenAPIConfig = { - BASE: 'http://localhost:3000/base', - CREDENTIALS: 'include', - ENCODE_PATH: undefined, - HEADERS: undefined, - PASSWORD: undefined, - TOKEN: undefined, - USERNAME: undefined, - VERSION: '1.0', - WITH_CREDENTIALS: false, - interceptors: { request: new Interceptors(), response: new Interceptors() }, -}; diff --git a/packages/openapi-ts/test/__snapshots__/test/generated/v3_experimental/core/request.ts.snap b/packages/openapi-ts/test/__snapshots__/test/generated/v3_experimental/core/request.ts.snap deleted file mode 100644 index bee3d3694..000000000 --- a/packages/openapi-ts/test/__snapshots__/test/generated/v3_experimental/core/request.ts.snap +++ /dev/null @@ -1,351 +0,0 @@ -import { ApiError } from './ApiError'; -import type { ApiRequestOptions } from './ApiRequestOptions'; -import type { ApiResult } from './ApiResult'; -import { CancelablePromise } from './CancelablePromise'; -import type { OnCancel } from './CancelablePromise'; -import type { OpenAPIConfig } from './OpenAPI'; - -export const isString = (value: unknown): value is string => { - return typeof value === 'string'; -}; - -export const isStringWithValue = (value: unknown): value is string => { - return isString(value) && value !== ''; -}; - -export const isBlob = (value: any): value is Blob => { - return value instanceof Blob; -}; - -export const isFormData = (value: unknown): value is FormData => { - return value instanceof FormData; -}; - -export const base64 = (str: string): string => { - try { - return btoa(str); - } catch (err) { - // @ts-ignore - return Buffer.from(str).toString('base64'); - } -}; - -export const getQueryString = (params: Record): string => { - const qs: string[] = []; - - const append = (key: string, value: unknown) => { - qs.push(`${encodeURIComponent(key)}=${encodeURIComponent(String(value))}`); - }; - - const encodePair = (key: string, value: unknown) => { - if (value === undefined || value === null) { - return; - } - - if (Array.isArray(value)) { - value.forEach(v => encodePair(key, v)); - } else if (typeof value === 'object') { - Object.entries(value).forEach(([k, v]) => encodePair(`${key}[${k}]`, v)); - } else { - append(key, value); - } - }; - - Object.entries(params).forEach(([key, value]) => encodePair(key, value)); - - return qs.length ? `?${qs.join('&')}` : ''; -}; - -const getUrl = (config: OpenAPIConfig, options: ApiRequestOptions): string => { - const encoder = config.ENCODE_PATH || encodeURI; - - const path = options.url - .replace('{api-version}', config.VERSION) - .replace(/{(.*?)}/g, (substring: string, group: string) => { - if (options.path?.hasOwnProperty(group)) { - return encoder(String(options.path[group])); - } - return substring; - }); - - const url = config.BASE + path; - return options.query ? url + getQueryString(options.query) : url; -}; - -export const getFormData = (options: ApiRequestOptions): FormData | undefined => { - if (options.formData) { - const formData = new FormData(); - - const process = (key: string, value: unknown) => { - if (isString(value) || isBlob(value)) { - formData.append(key, value); - } else { - formData.append(key, JSON.stringify(value)); - } - }; - - Object.entries(options.formData) - .filter(([, value]) => value !== undefined && value !== null) - .forEach(([key, value]) => { - if (Array.isArray(value)) { - value.forEach(v => process(key, v)); - } else { - process(key, value); - } - }); - - return formData; - } - return undefined; -}; - -type Resolver = (options: ApiRequestOptions) => Promise; - -export const resolve = async (options: ApiRequestOptions, resolver?: T | Resolver): Promise => { - if (typeof resolver === 'function') { - return (resolver as Resolver)(options); - } - return resolver; -}; - -export const getHeaders = async (config: OpenAPIConfig, options: ApiRequestOptions): Promise => { - const [token, username, password, additionalHeaders] = await Promise.all([ - resolve(options, config.TOKEN), - resolve(options, config.USERNAME), - resolve(options, config.PASSWORD), - resolve(options, config.HEADERS), - ]); - - const headers = Object.entries({ - Accept: 'application/json', - ...additionalHeaders, - ...options.headers, - }) - .filter(([, value]) => value !== undefined && value !== null) - .reduce( - (headers, [key, value]) => ({ - ...headers, - [key]: String(value), - }), - {} as Record - ); - - if (isStringWithValue(token)) { - headers['Authorization'] = `Bearer ${token}`; - } - - if (isStringWithValue(username) && isStringWithValue(password)) { - const credentials = base64(`${username}:${password}`); - headers['Authorization'] = `Basic ${credentials}`; - } - - if (options.body !== undefined) { - if (options.mediaType) { - headers['Content-Type'] = options.mediaType; - } else if (isBlob(options.body)) { - headers['Content-Type'] = options.body.type || 'application/octet-stream'; - } else if (isString(options.body)) { - headers['Content-Type'] = 'text/plain'; - } else if (!isFormData(options.body)) { - headers['Content-Type'] = 'application/json'; - } - } - - return new Headers(headers); -}; - -export const getRequestBody = (options: ApiRequestOptions): unknown => { - if (options.body !== undefined) { - if (options.mediaType?.includes('application/json') || options.mediaType?.includes('+json')) { - return JSON.stringify(options.body); - } else if (isString(options.body) || isBlob(options.body) || isFormData(options.body)) { - return options.body; - } else { - return JSON.stringify(options.body); - } - } - return undefined; -}; - -export const sendRequest = async ( - config: OpenAPIConfig, - options: ApiRequestOptions, - url: string, - body: any, - formData: FormData | undefined, - headers: Headers, - onCancel: OnCancel -): Promise => { - const controller = new AbortController(); - - let request: RequestInit = { - headers, - body: body ?? formData, - method: options.method, - signal: controller.signal, - }; - - if (config.WITH_CREDENTIALS) { - request.credentials = config.CREDENTIALS; - } - - for (const fn of config.interceptors.request._fns) { - request = await fn(request); - } - - onCancel(() => controller.abort()); - - return await fetch(url, request); -}; - -export const getResponseHeader = (response: Response, responseHeader?: string): string | undefined => { - if (responseHeader) { - const content = response.headers.get(responseHeader); - if (isString(content)) { - return content; - } - } - return undefined; -}; - -export const getResponseBody = async (response: Response): Promise => { - if (response.status !== 204) { - try { - const contentType = response.headers.get('Content-Type'); - if (contentType) { - const binaryTypes = [ - 'application/octet-stream', - 'application/pdf', - 'application/zip', - 'audio/', - 'image/', - 'video/', - ]; - if (contentType.includes('application/json') || contentType.includes('+json')) { - return await response.json(); - } else if (binaryTypes.some(type => contentType.includes(type))) { - return await response.blob(); - } else if (contentType.includes('multipart/form-data')) { - return await response.formData(); - } else if (contentType.includes('text/')) { - return await response.text(); - } - } - } catch (error) { - console.error(error); - } - } - return undefined; -}; - -export const catchErrorCodes = (options: ApiRequestOptions, result: ApiResult): void => { - const errors: Record = { - 400: 'Bad Request', - 401: 'Unauthorized', - 402: 'Payment Required', - 403: 'Forbidden', - 404: 'Not Found', - 405: 'Method Not Allowed', - 406: 'Not Acceptable', - 407: 'Proxy Authentication Required', - 408: 'Request Timeout', - 409: 'Conflict', - 410: 'Gone', - 411: 'Length Required', - 412: 'Precondition Failed', - 413: 'Payload Too Large', - 414: 'URI Too Long', - 415: 'Unsupported Media Type', - 416: 'Range Not Satisfiable', - 417: 'Expectation Failed', - 418: 'Im a teapot', - 421: 'Misdirected Request', - 422: 'Unprocessable Content', - 423: 'Locked', - 424: 'Failed Dependency', - 425: 'Too Early', - 426: 'Upgrade Required', - 428: 'Precondition Required', - 429: 'Too Many Requests', - 431: 'Request Header Fields Too Large', - 451: 'Unavailable For Legal Reasons', - 500: 'Internal Server Error', - 501: 'Not Implemented', - 502: 'Bad Gateway', - 503: 'Service Unavailable', - 504: 'Gateway Timeout', - 505: 'HTTP Version Not Supported', - 506: 'Variant Also Negotiates', - 507: 'Insufficient Storage', - 508: 'Loop Detected', - 510: 'Not Extended', - 511: 'Network Authentication Required', - ...options.errors, - }; - - const error = errors[result.status]; - if (error) { - throw new ApiError(options, result, error); - } - - if (!result.ok) { - const errorStatus = result.status ?? 'unknown'; - const errorStatusText = result.statusText ?? 'unknown'; - const errorBody = (() => { - try { - return JSON.stringify(result.body, null, 2); - } catch (e) { - return undefined; - } - })(); - - throw new ApiError( - options, - result, - `Generic Error: status: ${errorStatus}; status text: ${errorStatusText}; body: ${errorBody}` - ); - } -}; - -/** - * Request method - * @param config The OpenAPI configuration object - * @param options The request options from the service - * @returns CancelablePromise - * @throws ApiError - */ -export const request = (config: OpenAPIConfig, options: ApiRequestOptions): CancelablePromise => { - return new CancelablePromise(async (resolve, reject, onCancel) => { - try { - const url = getUrl(config, options); - const formData = getFormData(options); - const body = getRequestBody(options); - const headers = await getHeaders(config, options); - - if (!onCancel.isCancelled) { - let response = await sendRequest(config, options, url, body, formData, headers, onCancel); - - for (const fn of config.interceptors.response._fns) { - response = await fn(response); - } - - const responseBody = await getResponseBody(response); - const responseHeader = getResponseHeader(response, options.responseHeader); - - const result: ApiResult = { - url, - ok: response.ok, - status: response.status, - statusText: response.statusText, - body: responseHeader ?? responseBody, - }; - - catchErrorCodes(options, result); - - resolve(result.body); - } - } catch (error) { - reject(error); - } - }); -}; diff --git a/packages/openapi-ts/test/__snapshots__/test/generated/v3_experimental/index.ts.snap b/packages/openapi-ts/test/__snapshots__/test/generated/v3_experimental/index.ts.snap deleted file mode 100644 index 61a05bfe7..000000000 --- a/packages/openapi-ts/test/__snapshots__/test/generated/v3_experimental/index.ts.snap +++ /dev/null @@ -1,6 +0,0 @@ -export { ApiError } from './core/ApiError'; -export { CancelablePromise, CancelError } from './core/CancelablePromise'; -export { OpenAPI, type OpenAPIConfig } from './core/OpenAPI'; -export * from './models'; -export * from './schemas'; -export * from './services'; diff --git a/packages/openapi-ts/test/__snapshots__/test/generated/v3_experimental/models.ts.snap b/packages/openapi-ts/test/__snapshots__/test/generated/v3_experimental/models.ts.snap deleted file mode 100644 index 6860edf61..000000000 --- a/packages/openapi-ts/test/__snapshots__/test/generated/v3_experimental/models.ts.snap +++ /dev/null @@ -1,1233 +0,0 @@ -/** - * Testing multiline comments in string: First line - * Second line - * - * Fourth line - */ -export type CommentWithBreaks = number; - -/** - * Testing backticks in string: `backticks` and ```multiple backticks``` should work - */ -export type CommentWithBackticks = number; - -/** - * Testing backticks and quotes in string: `backticks`, 'quotes', "double quotes" and ```multiple backticks``` should work - */ -export type CommentWithBackticksAndQuotes = number; - -/** - * Testing slashes in string: \backwards\\\ and /forwards/// should work - */ -export type CommentWithSlashes = number; - -/** - * Testing expression placeholders in string: ${expression} should work - */ -export type CommentWithExpressionPlaceholders = number; - -/** - * Testing quotes in string: 'single quote''' and "double quotes""" should work - */ -export type CommentWithQuotes = number; - -/** - * Testing reserved characters in string: * inline * and ** inline ** should work - */ -export type CommentWithReservedCharacters = number; - -/** - * This is a simple number - */ -export type SimpleInteger = number; - -/** - * This is a simple boolean - */ -export type SimpleBoolean = boolean; - -/** - * This is a simple string - */ -export type SimpleString = string; - -/** - * A string with non-ascii (unicode) characters valid in typescript identifiers (æøåÆØÅöÔèÈ字符串) - */ -export type NonAsciiStringæøåÆØÅöôêÊ字符串 = string; - -/** - * This is a simple file - */ -export type SimpleFile = Blob | File; - -/** - * This is a simple reference - */ -export type SimpleReference = ModelWithString; - -/** - * This is a simple string - */ -export type SimpleStringWithPattern = string | null; - -/** - * This is a simple enum with strings - */ -export type EnumWithStrings = - | 'Success' - | 'Warning' - | 'Error' - | "'Single Quote'" - | '"Double Quotes"' - | 'Non-ascii: øæåôöØÆÅÔÖ字符串'; - -export type EnumWithReplacedCharacters = "'Single Quote'" | '"Double Quotes"' | 'øæåôöØÆÅÔÖ字符串' | 3.1 | ''; - -/** - * This is a simple enum with numbers - */ -export type EnumWithNumbers = 1 | 2 | 3 | 1.1 | 1.2 | 1.3 | 100 | 200 | 300 | -100 | -200 | -300 | -1.1 | -1.2 | -1.3; - -/** - * Success=1,Warning=2,Error=3 - */ -export type EnumFromDescription = number; - -/** - * This is a simple enum with numbers - */ -export type EnumWithExtensions = 200 | 400 | 500; - -export type EnumWithXEnumNames = 0 | 1 | 2; - -/** - * This is a simple array with numbers - */ -export type ArrayWithNumbers = Array; - -/** - * This is a simple array with booleans - */ -export type ArrayWithBooleans = Array; - -/** - * This is a simple array with strings - */ -export type ArrayWithStrings = Array; - -/** - * This is a simple array with references - */ -export type ArrayWithReferences = Array; - -/** - * This is a simple array containing an array - */ -export type ArrayWithArray = Array>; - -/** - * This is a simple array with properties - */ -export type ArrayWithProperties = Array<{ - foo?: string; - bar?: string; -}>; - -/** - * This is a simple array with any of properties - */ -export type ArrayWithAnyOfProperties = Array< - | { - foo?: string; - } - | { - bar?: string; - } ->; - -export type AnyOfAnyAndNull = { - data?: unknown | null; -}; - -/** - * This is a simple array with any of properties - */ -export type AnyOfArrays = { - results?: Array< - | { - foo?: string; - } - | { - bar?: string; - } - >; -}; - -/** - * This is a string dictionary - */ -export type DictionaryWithString = Record; - -export type DictionaryWithPropertiesAndAdditionalProperties = { - foo?: string; - [key: string]: string | undefined; -}; - -/** - * This is a string reference - */ -export type DictionaryWithReference = Record; - -/** - * This is a complex dictionary - */ -export type DictionaryWithArray = Record>; - -/** - * This is a string dictionary - */ -export type DictionaryWithDictionary = Record>; - -/** - * This is a complex dictionary - */ -export type DictionaryWithProperties = Record< - string, - { - foo?: string; - bar?: string; - } ->; - -/** - * This is a model with one number property - */ -export type ModelWithInteger = { - /** - * This is a simple number property - */ - prop?: number; -}; - -/** - * This is a model with one boolean property - */ -export type ModelWithBoolean = { - /** - * This is a simple boolean property - */ - prop?: boolean; -}; - -/** - * This is a model with one string property - */ -export type ModelWithString = { - /** - * This is a simple string property - */ - prop?: string; -}; - -/** - * `Comment` or `VoiceComment`. The JSON object for adding voice comments to tickets is different. See [Adding voice comments to tickets](/documentation/ticketing/managing-tickets/adding-voice-comments-to-tickets) - */ -export type Model_From_Zendesk = string; - -/** - * This is a model with one string property - */ -export type ModelWithNullableString = { - /** - * This is a simple string property - */ - nullableProp1?: string | null; - /** - * This is a simple string property - */ - nullableRequiredProp1: string | null; - /** - * This is a simple string property - */ - nullableProp2?: string | null; - /** - * This is a simple string property - */ - nullableRequiredProp2: string | null; - /** - * This is a simple enum with strings - */ - 'foo_bar-enum'?: 'Success' | 'Warning' | 'Error' | 'ØÆÅ字符串'; -}; - -/** - * This is a model with one enum - */ -export type ModelWithEnum = { - /** - * This is a simple enum with strings - */ - 'foo_bar-enum'?: 'Success' | 'Warning' | 'Error' | 'ØÆÅ字符串'; - /** - * These are the HTTP error code enums - */ - statusCode?: '100' | '200 FOO' | '300 FOO_BAR' | '400 foo-bar' | '500 foo.bar' | '600 foo&bar'; - /** - * Simple boolean enum - */ - bool?: boolean; -}; - -/** - * This is a model with one enum with escaped name - */ -export type ModelWithEnumWithHyphen = { - 'foo-bar-baz-qux'?: '3.0'; -}; - -/** - * This is a model with one enum - */ -export type ModelWithEnumFromDescription = { - /** - * Success=1,Warning=2,Error=3 - */ - test?: number; -}; - -/** - * This is a model with nested enums - */ -export type ModelWithNestedEnums = { - dictionaryWithEnum?: Record; - dictionaryWithEnumFromDescription?: Record; - arrayWithEnum?: Array<'Success' | 'Warning' | 'Error'>; - arrayWithDescription?: Array; - /** - * This is a simple enum with strings - */ - 'foo_bar-enum'?: 'Success' | 'Warning' | 'Error' | 'ØÆÅ字符串'; -}; - -/** - * This is a model with one property containing a reference - */ -export type ModelWithReference = { - prop?: ModelWithProperties; -}; - -/** - * This is a model with one property containing an array - */ -export type ModelWithArrayReadOnlyAndWriteOnly = { - prop?: Array; - propWithFile?: Array; - propWithNumber?: Array; -}; - -/** - * This is a model with one property containing an array - */ -export type ModelWithArray = { - prop?: Array; - propWithFile?: Array; - propWithNumber?: Array; -}; - -/** - * This is a model with one property containing a dictionary - */ -export type ModelWithDictionary = { - prop?: Record; -}; - -/** - * This is a deprecated model with a deprecated property - * @deprecated - */ -export type DeprecatedModel = { - /** - * This is a deprecated property - * @deprecated - */ - prop?: string; -}; - -/** - * This is a model with one property containing a circular reference - */ -export type ModelWithCircularReference = { - prop?: ModelWithCircularReference; -}; - -/** - * This is a model with one property with a 'one of' relationship - */ -export type CompositionWithOneOf = { - propA?: ModelWithString | ModelWithEnum | ModelWithArray | ModelWithDictionary; -}; - -/** - * This is a model with one property with a 'one of' relationship where the options are not $ref - */ -export type CompositionWithOneOfAnonymous = { - propA?: - | { - propA?: string; - } - | string - | number; -}; - -/** - * Circle - */ -export type ModelCircle = { - kind: 'circle'; - radius?: number; -}; - -/** - * Square - */ -export type ModelSquare = { - kind: 'square'; - sideLength?: number; -}; - -/** - * This is a model with one property with a 'one of' relationship where the options are not $ref - */ -export type CompositionWithOneOfDiscriminator = ModelCircle | ModelSquare; - -/** - * This is a model with one property with a 'any of' relationship - */ -export type CompositionWithAnyOf = { - propA?: ModelWithString | ModelWithEnum | ModelWithArray | ModelWithDictionary; -}; - -/** - * This is a model with one property with a 'any of' relationship where the options are not $ref - */ -export type CompositionWithAnyOfAnonymous = { - propA?: - | { - propA?: string; - } - | string - | number; -}; - -/** - * This is a model with nested 'any of' property with a type null - */ -export type CompositionWithNestedAnyAndTypeNull = { - propA?: Array | Array; -}; - -export type Enum1 = 'Bird' | 'Dog'; - -export type ConstValue = 'ConstValue'; - -/** - * This is a model with one property with a 'any of' relationship where the options are not $ref - */ -export type CompositionWithNestedAnyOfAndNull = { - propA?: Array | null; -}; - -/** - * This is a model with one property with a 'one of' relationship - */ -export type CompositionWithOneOfAndNullable = { - propA?: - | { - boolean?: boolean; - } - | ModelWithEnum - | ModelWithArray - | ModelWithDictionary - | null; -}; - -/** - * This is a model that contains a simple dictionary within composition - */ -export type CompositionWithOneOfAndSimpleDictionary = { - propA?: boolean | Record; -}; - -/** - * This is a model that contains a dictionary of simple arrays within composition - */ -export type CompositionWithOneOfAndSimpleArrayDictionary = { - propA?: boolean | Record>; -}; - -/** - * This is a model that contains a dictionary of complex arrays (composited) within composition - */ -export type CompositionWithOneOfAndComplexArrayDictionary = { - propA?: boolean | Record>; -}; - -/** - * This is a model with one property with a 'all of' relationship - */ -export type CompositionWithAllOfAndNullable = { - propA?: - | ({ - boolean?: boolean; - } & ModelWithEnum & - ModelWithArray & - ModelWithDictionary) - | null; -}; - -/** - * This is a model with one property with a 'any of' relationship - */ -export type CompositionWithAnyOfAndNullable = { - propA?: - | { - boolean?: boolean; - } - | ModelWithEnum - | ModelWithArray - | ModelWithDictionary - | null; -}; - -/** - * This is a base model with two simple optional properties - */ -export type CompositionBaseModel = { - firstName?: string; - lastname?: string; -}; - -/** - * This is a model that extends the base model - */ -export type CompositionExtendedModel = CompositionBaseModel & { - firstName: string; - lastname: string; - age: number; -}; - -/** - * This is a model with one nested property - */ -export type ModelWithProperties = { - required: string; - readonly requiredAndReadOnly: string; - requiredAndNullable: string | null; - string?: string; - number?: number; - boolean?: boolean; - reference?: ModelWithString; - 'property with space'?: string; - default?: string; - try?: string; - readonly '@namespace.string'?: string; - readonly '@namespace.integer'?: number; -}; - -/** - * This is a model with one nested property - */ -export type ModelWithNestedProperties = { - readonly first: { - readonly second: { - readonly third: string | null; - } | null; - } | null; -}; - -/** - * This is a model with duplicated properties - */ -export type ModelWithDuplicateProperties = { - prop?: ModelWithString; -}; - -/** - * This is a model with ordered properties - */ -export type ModelWithOrderedProperties = { - zebra?: string; - apple?: string; - hawaii?: string; -}; - -/** - * This is a model with duplicated imports - */ -export type ModelWithDuplicateImports = { - propA?: ModelWithString; - propB?: ModelWithString; - propC?: ModelWithString; -}; - -/** - * This is a model that extends another model - */ -export type ModelThatExtends = ModelWithString & { - propExtendsA?: string; - propExtendsB?: ModelWithString; -}; - -/** - * This is a model that extends another model - */ -export type ModelThatExtendsExtends = ModelWithString & - ModelThatExtends & { - propExtendsC?: string; - propExtendsD?: ModelWithString; - }; - -/** - * This is a model that contains a some patterns - */ -export type ModelWithPattern = { - key: string; - name: string; - readonly enabled?: boolean; - readonly modified?: string; - id?: string; - text?: string; - patternWithSingleQuotes?: string; - patternWithNewline?: string; - patternWithBacktick?: string; -}; - -export type File = { - readonly id?: string; - readonly updated_at?: string; - readonly created_at?: string; - mime: string; - readonly file?: string; -}; - -export type _default = { - name?: string; -}; - -export type Pageable = { - page?: number; - size?: number; - sort?: Array; -}; - -/** - * This is a free-form object without additionalProperties. - */ -export type FreeFormObjectWithoutAdditionalProperties = Record; - -/** - * This is a free-form object with additionalProperties: true. - */ -export type FreeFormObjectWithAdditionalPropertiesEqTrue = Record; - -/** - * This is a free-form object with additionalProperties: {}. - */ -export type FreeFormObjectWithAdditionalPropertiesEqEmptyObject = Record; - -export type ModelWithConst = { - String?: 'String'; - number?: 0; - null?: null; - withType?: 'Some string'; -}; - -/** - * This is a model with one property and additionalProperties: true - */ -export type ModelWithAdditionalPropertiesEqTrue = { - /** - * This is a simple string property - */ - prop?: string; - [key: string]: unknown; -}; - -export type NestedAnyOfArraysNullable = { - nullableArray?: Array | null; -}; - -export type CompositionWithOneOfAndProperties = - | { - foo: SimpleParameter; - baz: number | null; - qux: number; - } - | { - bar: NonAsciiStringæøåÆØÅöôêÊ字符串; - baz: number | null; - qux: number; - }; - -/** - * An object that can be null - */ -export type NullableObject = { - foo?: string; -} | null; - -export type ModelWithNullableObject = { - data?: NullableObject; -}; - -export type ModelWithOneOfEnum = - | { - foo: 'Bar'; - } - | { - foo: 'Baz'; - } - | { - foo: 'Qux'; - } - | { - content: string; - foo: 'Quux'; - } - | { - content: [string, string]; - foo: 'Corge'; - }; - -export type ModelWithNestedArrayEnumsDataFoo = 'foo' | 'bar'; - -export type ModelWithNestedArrayEnumsDataBar = 'baz' | 'qux'; - -export type ModelWithNestedArrayEnumsData = { - foo?: Array; - bar?: Array; -}; - -export type ModelWithNestedArrayEnums = { - array_strings?: Array; - data?: ModelWithNestedArrayEnumsData; -}; - -export type ModelWithNestedCompositionEnums = { - foo?: ModelWithNestedArrayEnumsDataFoo; -}; - -export type ModelWithReadOnlyAndWriteOnly = { - foo: string; - readonly bar: string; - baz: string; -}; - -export type ModelWithConstantSizeArray = [number, number]; - -export type ModelWithAnyOfConstantSizeArray = [number | string, number | string, number | string]; - -/** - * This is a reusable parameter - */ -export type SimpleParameter = string; - -export type $OpenApiTsDefault = { - '/api/v{api-version}/no-tag': { - post: { - req: { - 200: { - requestBody: ModelWithReadOnlyAndWriteOnly | ModelWithArrayReadOnlyAndWriteOnly; - }; - }; - res: ModelWithReadOnlyAndWriteOnly; - }; - get: { - res: void; - }; - }; -}; - -export type $OpenApiTsSimple = { - '/api/v{api-version}/simple/$count': { - get: { - res: Model_From_Zendesk; - }; - }; - '/api/v{api-version}/simple': { - get: { - res: void; - }; - put: { - res: void; - }; - post: { - res: void; - }; - delete: { - res: void; - }; - options: { - res: void; - }; - head: { - res: void; - }; - patch: { - res: void; - }; - }; -}; - -export type $OpenApiTsParameters = { - '/api/v{api-version}/foo/{foo}/bar/{bar}': { - delete: { - res: void; - }; - }; - '/api/v{api-version}/parameters/{parameterPath}': { - post: { - res: void; - }; - }; - '/api/v{api-version}/parameters/{parameter.path.1}/{parameter-path-2}/{PARAMETER-PATH-3}': { - post: { - res: void; - }; - }; - '/api/v{api-version}/parameters/': { - get: { - res: void; - }; - post: { - res: void; - }; - }; -}; - -export type $OpenApiTsDescriptions = { - '/api/v{api-version}/descriptions/': { - post: { - res: void; - }; - }; -}; - -export type $OpenApiTsDeprecated = { - '/api/v{api-version}/parameters/deprecated': { - post: { - res: void; - }; - }; -}; - -export type $OpenApiTsRequestBody = { - '/api/v{api-version}/requestBody/': { - post: { - res: void; - }; - }; -}; - -export type $OpenApiTsFormData = { - '/api/v{api-version}/formData/': { - post: { - res: void; - }; - }; -}; - -export type $OpenApiTsDefaults = { - '/api/v{api-version}/defaults': { - get: { - res: void; - }; - post: { - res: void; - }; - put: { - res: void; - }; - }; -}; - -export type $OpenApiTsDuplicate = { - '/api/v{api-version}/duplicate': { - get: { - res: void; - }; - post: { - res: void; - }; - put: { - res: void; - }; - delete: { - res: void; - }; - }; -}; - -export type $OpenApiTsNoContent = { - '/api/v{api-version}/no-content': { - get: { - res: void; - }; - }; - '/api/v{api-version}/multiple-tags/response-and-no-content': { - get: { - res: number | void; - }; - }; -}; - -export type $OpenApiTsResponse = { - '/api/v{api-version}/multiple-tags/response-and-no-content': { - get: { - res: number | void; - }; - }; - '/api/v{api-version}/response': { - get: { - res: ModelWithString; - }; - post: { - res: ModelWithString; - }; - put: { - res: - | { - readonly '@namespace.string'?: string; - readonly '@namespace.integer'?: number; - readonly value?: Array; - } - | ModelWithString - | ModelThatExtends - | ModelThatExtendsExtends; - }; - }; -}; - -export type $OpenApiTsMultipleTags1 = { - '/api/v{api-version}/multiple-tags/a': { - get: { - res: void; - }; - }; - '/api/v{api-version}/multiple-tags/b': { - get: { - res: void; - }; - }; -}; - -export type $OpenApiTsMultipleTags2 = { - '/api/v{api-version}/multiple-tags/a': { - get: { - res: void; - }; - }; - '/api/v{api-version}/multiple-tags/b': { - get: { - res: void; - }; - }; -}; - -export type $OpenApiTsMultipleTags3 = { - '/api/v{api-version}/multiple-tags/b': { - get: { - res: void; - }; - }; -}; - -export type $OpenApiTsCollectionFormat = { - '/api/v{api-version}/collectionFormat': { - get: { - res: void; - }; - }; -}; - -export type $OpenApiTsTypes = { - '/api/v{api-version}/types': { - get: { - req: { - 200: { - /** - * This is a number parameter - */ - id?: number; - /** - * This is an array parameter - */ - parameterArray: Array | null; - /** - * This is a boolean parameter - */ - parameterBoolean: boolean | null; - /** - * This is a dictionary parameter - */ - parameterDictionary: Record | null; - /** - * This is an enum parameter - */ - parameterEnum: 'Success' | 'Warning' | 'Error' | null; - /** - * This is a number parameter - */ - parameterNumber: number; - /** - * This is an object parameter - */ - parameterObject: Record | null; - /** - * This is a string parameter - */ - parameterString: string | null; - }; - 201: { - /** - * This is a number parameter - */ - id?: number; - /** - * This is an array parameter - */ - parameterArray: Array | null; - /** - * This is a boolean parameter - */ - parameterBoolean: boolean | null; - /** - * This is a dictionary parameter - */ - parameterDictionary: Record | null; - /** - * This is an enum parameter - */ - parameterEnum: 'Success' | 'Warning' | 'Error' | null; - /** - * This is a number parameter - */ - parameterNumber: number; - /** - * This is an object parameter - */ - parameterObject: Record | null; - /** - * This is a string parameter - */ - parameterString: string | null; - }; - 202: { - /** - * This is a number parameter - */ - id?: number; - /** - * This is an array parameter - */ - parameterArray: Array | null; - /** - * This is a boolean parameter - */ - parameterBoolean: boolean | null; - /** - * This is a dictionary parameter - */ - parameterDictionary: Record | null; - /** - * This is an enum parameter - */ - parameterEnum: 'Success' | 'Warning' | 'Error' | null; - /** - * This is a number parameter - */ - parameterNumber: number; - /** - * This is an object parameter - */ - parameterObject: Record | null; - /** - * This is a string parameter - */ - parameterString: string | null; - }; - 203: { - /** - * This is a number parameter - */ - id?: number; - /** - * This is an array parameter - */ - parameterArray: Array | null; - /** - * This is a boolean parameter - */ - parameterBoolean: boolean | null; - /** - * This is a dictionary parameter - */ - parameterDictionary: Record | null; - /** - * This is an enum parameter - */ - parameterEnum: 'Success' | 'Warning' | 'Error' | null; - /** - * This is a number parameter - */ - parameterNumber: number; - /** - * This is an object parameter - */ - parameterObject: Record | null; - /** - * This is a string parameter - */ - parameterString: string | null; - }; - }; - res: number | string | boolean | Record; - }; - }; -}; - -export type $OpenApiTsUpload = { - '/api/v{api-version}/upload': { - post: { - req: { - 200: { - /** - * Supply a file reference for upload - */ - file: Blob | File; - }; - }; - res: boolean; - }; - }; -}; - -export type $OpenApiTsFileResponse = { - '/api/v{api-version}/file/{id}': { - get: { - req: { - 200: { - id: string; - }; - }; - res: Blob | File; - }; - }; -}; - -export type $OpenApiTsComplex = { - '/api/v{api-version}/complex': { - get: { - req: { - 200: { - /** - * Parameter containing object - */ - parameterObject: { - first?: { - second?: { - third?: string; - }; - }; - }; - /** - * Parameter containing reference - */ - parameterReference: ModelWithString; - }; - }; - res: Array; - }; - }; - '/api/v{api-version}/complex/{id}': { - put: { - req: { - 200: { - id: number; - requestBody?: { - readonly key: string | null; - name: string | null; - enabled?: boolean; - readonly type: 'Monkey' | 'Horse' | 'Bird'; - listOfModels?: Array | null; - listOfStrings?: Array | null; - parameters: ModelWithString | ModelWithEnum | ModelWithArray | ModelWithDictionary; - readonly user?: { - readonly id?: number; - readonly name?: string | null; - }; - }; - }; - }; - res: ModelWithString; - }; - }; -}; - -export type $OpenApiTsMultipart = { - '/api/v{api-version}/multipart': { - post: { - res: void; - }; - get: { - res: { - file?: Blob | File; - metadata?: { - foo?: string; - bar?: string; - }; - }; - }; - }; -}; - -export type $OpenApiTsHeader = { - '/api/v{api-version}/header': { - post: { - res: string; - }; - }; -}; - -export type $OpenApiTsError = { - '/api/v{api-version}/error': { - post: { - req: { - 200: { - /** - * Status code to return - */ - status: number; - }; - }; - res: any; - }; - }; -}; - -export type $OpenApiTsNonAsciiÆøåÆøÅöôêÊ = { - '/api/v{api-version}/non-ascii-æøåÆØÅöôêÊ字符串': { - post: { - req: { - 200: { - /** - * Dummy input param - */ - nonAsciiParamæøåÆøÅöôêÊ: number; - }; - }; - res: Array; - }; - }; -}; diff --git a/packages/openapi-ts/test/__snapshots__/test/generated/v3_experimental/schemas.ts.snap b/packages/openapi-ts/test/__snapshots__/test/generated/v3_experimental/schemas.ts.snap deleted file mode 100644 index 83429f186..000000000 --- a/packages/openapi-ts/test/__snapshots__/test/generated/v3_experimental/schemas.ts.snap +++ /dev/null @@ -1,1577 +0,0 @@ -export const $CommentWithBreaks = { - description: `Testing multiline comments in string: First line -Second line - -Fourth line`, - type: 'integer', -} as const; - -export const $CommentWithBackticks = { - description: 'Testing backticks in string: `backticks` and ```multiple backticks``` should work', - type: 'integer', -} as const; - -export const $CommentWithBackticksAndQuotes = { - description: `Testing backticks and quotes in string: \`backticks\`, 'quotes', "double quotes" and \`\`\`multiple backticks\`\`\` should work`, - type: 'integer', -} as const; - -export const $CommentWithSlashes = { - description: 'Testing slashes in string: \backwards\\ and /forwards/// should work', - type: 'integer', -} as const; - -export const $CommentWithExpressionPlaceholders = { - description: 'Testing expression placeholders in string: ${expression} should work', - type: 'integer', -} as const; - -export const $CommentWithQuotes = { - description: `Testing quotes in string: 'single quote''' and "double quotes""" should work`, - type: 'integer', -} as const; - -export const $CommentWithReservedCharacters = { - description: 'Testing reserved characters in string: /* inline */ and /** inline **/ should work', - type: 'integer', -} as const; - -export const $SimpleInteger = { - description: 'This is a simple number', - type: 'integer', -} as const; - -export const $SimpleBoolean = { - description: 'This is a simple boolean', - type: 'boolean', -} as const; - -export const $SimpleString = { - description: 'This is a simple string', - type: 'string', -} as const; - -export const $NonAsciiStringæøåÆØÅöôêÊ字符串 = { - description: 'A string with non-ascii (unicode) characters valid in typescript identifiers (æøåÆØÅöÔèÈ字符串)', - type: 'string', -} as const; - -export const $SimpleFile = { - description: 'This is a simple file', - type: 'file', -} as const; - -export const $SimpleReference = { - description: 'This is a simple reference', - $ref: '#/components/schemas/ModelWithString', -} as const; - -export const $SimpleStringWithPattern = { - description: 'This is a simple string', - type: 'string', - nullable: true, - maxLength: 64, - pattern: '^[a-zA-Z0-9_]*$', -} as const; - -export const $EnumWithStrings = { - description: 'This is a simple enum with strings', - enum: ['Success', 'Warning', 'Error', "'Single Quote'", '"Double Quotes"', 'Non-ascii: øæåôöØÆÅÔÖ字符串'], -} as const; - -export const $EnumWithReplacedCharacters = { - enum: ["'Single Quote'", '"Double Quotes"', 'øæåôöØÆÅÔÖ字符串', 3.1, ''], - type: 'string', -} as const; - -export const $EnumWithNumbers = { - description: 'This is a simple enum with numbers', - enum: [1, 2, 3, 1.1, 1.2, 1.3, 100, 200, 300, -100, -200, -300, -1.1, -1.2, -1.3], - default: 200, -} as const; - -export const $EnumFromDescription = { - description: 'Success=1,Warning=2,Error=3', - type: 'number', -} as const; - -export const $EnumWithExtensions = { - description: 'This is a simple enum with numbers', - enum: [200, 400, 500], - 'x-enum-varnames': ['CUSTOM_SUCCESS', 'CUSTOM_WARNING', 'CUSTOM_ERROR'], - 'x-enum-descriptions': [ - 'Used when the status of something is successful', - 'Used when the status of something has a warning', - 'Used when the status of something has an error', - ], -} as const; - -export const $EnumWithXEnumNames = { - enum: [0, 1, 2], - 'x-enumNames': ['zero', 'one', 'two'], -} as const; - -export const $ArrayWithNumbers = { - description: 'This is a simple array with numbers', - type: 'array', - items: { - type: 'integer', - }, -} as const; - -export const $ArrayWithBooleans = { - description: 'This is a simple array with booleans', - type: 'array', - items: { - type: 'boolean', - }, -} as const; - -export const $ArrayWithStrings = { - description: 'This is a simple array with strings', - type: 'array', - items: { - type: 'string', - }, - default: ['test'], -} as const; - -export const $ArrayWithReferences = { - description: 'This is a simple array with references', - type: 'array', - items: { - $ref: '#/components/schemas/ModelWithString', - }, -} as const; - -export const $ArrayWithArray = { - description: 'This is a simple array containing an array', - type: 'array', - items: { - type: 'array', - items: { - $ref: '#/components/schemas/ModelWithString', - }, - }, -} as const; - -export const $ArrayWithProperties = { - description: 'This is a simple array with properties', - type: 'array', - items: { - type: 'object', - properties: { - foo: { - type: 'string', - }, - bar: { - type: 'string', - }, - }, - }, -} as const; - -export const $ArrayWithAnyOfProperties = { - description: 'This is a simple array with any of properties', - type: 'array', - items: { - anyOf: [ - { - type: 'object', - properties: { - foo: { - type: 'string', - default: 'test', - }, - }, - }, - { - type: 'object', - properties: { - bar: { - type: 'string', - }, - }, - }, - ], - }, -} as const; - -export const $AnyOfAnyAndNull = { - type: 'object', - properties: { - data: { - anyOf: [ - {}, - { - type: 'null', - }, - ], - }, - }, -} as const; - -export const $AnyOfArrays = { - description: 'This is a simple array with any of properties', - type: 'object', - properties: { - results: { - items: { - anyOf: [ - { - type: 'object', - properties: { - foo: { - type: 'string', - }, - }, - }, - { - type: 'object', - properties: { - bar: { - type: 'string', - }, - }, - }, - ], - }, - type: 'array', - }, - }, -} as const; - -export const $DictionaryWithString = { - description: 'This is a string dictionary', - type: 'object', - additionalProperties: { - type: 'string', - }, -} as const; - -export const $DictionaryWithPropertiesAndAdditionalProperties = { - type: 'object', - properties: { - foo: { - type: 'string', - }, - }, - additionalProperties: { - type: 'string', - }, -} as const; - -export const $DictionaryWithReference = { - description: 'This is a string reference', - type: 'object', - additionalProperties: { - $ref: '#/components/schemas/ModelWithString', - }, -} as const; - -export const $DictionaryWithArray = { - description: 'This is a complex dictionary', - type: 'object', - additionalProperties: { - type: 'array', - items: { - $ref: '#/components/schemas/ModelWithString', - }, - }, -} as const; - -export const $DictionaryWithDictionary = { - description: 'This is a string dictionary', - type: 'object', - additionalProperties: { - type: 'object', - additionalProperties: { - type: 'string', - }, - }, -} as const; - -export const $DictionaryWithProperties = { - description: 'This is a complex dictionary', - type: 'object', - additionalProperties: { - type: 'object', - properties: { - foo: { - type: 'string', - }, - bar: { - type: 'string', - }, - }, - }, -} as const; - -export const $ModelWithInteger = { - description: 'This is a model with one number property', - type: 'object', - properties: { - prop: { - description: 'This is a simple number property', - type: 'integer', - }, - }, -} as const; - -export const $ModelWithBoolean = { - description: 'This is a model with one boolean property', - type: 'object', - properties: { - prop: { - description: 'This is a simple boolean property', - type: 'boolean', - }, - }, -} as const; - -export const $ModelWithString = { - description: 'This is a model with one string property', - type: 'object', - properties: { - prop: { - description: 'This is a simple string property', - type: 'string', - }, - }, -} as const; - -export const $Model_From_Zendesk = { - description: `\`Comment\` or \`VoiceComment\`. The JSON object for adding voice comments to tickets is different. See [Adding voice comments to tickets](/documentation/ticketing/managing-tickets/adding-voice-comments-to-tickets)`, - type: 'string', -} as const; - -export const $ModelWithNullableString = { - description: 'This is a model with one string property', - type: 'object', - required: ['nullableRequiredProp1', 'nullableRequiredProp2'], - properties: { - nullableProp1: { - description: 'This is a simple string property', - type: 'string', - nullable: true, - }, - nullableRequiredProp1: { - description: 'This is a simple string property', - type: 'string', - nullable: true, - }, - nullableProp2: { - description: 'This is a simple string property', - type: ['string', 'null'], - }, - nullableRequiredProp2: { - description: 'This is a simple string property', - type: ['string', 'null'], - }, - 'foo_bar-enum': { - description: 'This is a simple enum with strings', - enum: ['Success', 'Warning', 'Error', 'ØÆÅ字符串'], - }, - }, -} as const; - -export const $ModelWithEnum = { - description: 'This is a model with one enum', - type: 'object', - properties: { - 'foo_bar-enum': { - description: 'This is a simple enum with strings', - enum: ['Success', 'Warning', 'Error', 'ØÆÅ字符串'], - }, - statusCode: { - description: 'These are the HTTP error code enums', - enum: ['100', '200 FOO', '300 FOO_BAR', '400 foo-bar', '500 foo.bar', '600 foo&bar'], - }, - bool: { - description: 'Simple boolean enum', - type: 'boolean', - enum: [true], - }, - }, -} as const; - -export const $ModelWithEnumWithHyphen = { - description: 'This is a model with one enum with escaped name', - type: 'object', - properties: { - 'foo-bar-baz-qux': { - type: 'string', - enum: ['3.0'], - title: 'Foo-Bar-Baz-Qux', - default: '3.0', - }, - }, -} as const; - -export const $ModelWithEnumFromDescription = { - description: 'This is a model with one enum', - type: 'object', - properties: { - test: { - type: 'integer', - description: 'Success=1,Warning=2,Error=3', - }, - }, -} as const; - -export const $ModelWithNestedEnums = { - description: 'This is a model with nested enums', - type: 'object', - properties: { - dictionaryWithEnum: { - type: 'object', - additionalProperties: { - enum: ['Success', 'Warning', 'Error'], - }, - }, - dictionaryWithEnumFromDescription: { - type: 'object', - additionalProperties: { - type: 'integer', - description: 'Success=1,Warning=2,Error=3', - }, - }, - arrayWithEnum: { - type: 'array', - items: { - enum: ['Success', 'Warning', 'Error'], - }, - }, - arrayWithDescription: { - type: 'array', - items: { - type: 'integer', - description: 'Success=1,Warning=2,Error=3', - }, - }, - 'foo_bar-enum': { - description: 'This is a simple enum with strings', - enum: ['Success', 'Warning', 'Error', 'ØÆÅ字符串'], - }, - }, -} as const; - -export const $ModelWithReference = { - description: 'This is a model with one property containing a reference', - type: 'object', - properties: { - prop: { - $ref: '#/components/schemas/ModelWithProperties', - }, - }, -} as const; - -export const $ModelWithArrayReadOnlyAndWriteOnly = { - description: 'This is a model with one property containing an array', - type: 'object', - properties: { - prop: { - type: 'array', - items: { - $ref: '#/components/schemas/ModelWithReadOnlyAndWriteOnly', - }, - }, - propWithFile: { - type: 'array', - items: { - type: 'file', - }, - }, - propWithNumber: { - type: 'array', - items: { - type: 'number', - }, - }, - }, -} as const; - -export const $ModelWithArray = { - description: 'This is a model with one property containing an array', - type: 'object', - properties: { - prop: { - type: 'array', - items: { - $ref: '#/components/schemas/ModelWithString', - }, - }, - propWithFile: { - type: 'array', - items: { - type: 'file', - }, - }, - propWithNumber: { - type: 'array', - items: { - type: 'number', - }, - }, - }, -} as const; - -export const $ModelWithDictionary = { - description: 'This is a model with one property containing a dictionary', - type: 'object', - properties: { - prop: { - type: 'object', - additionalProperties: { - type: 'string', - }, - }, - }, -} as const; - -export const $DeprecatedModel = { - deprecated: true, - description: 'This is a deprecated model with a deprecated property', - type: 'object', - properties: { - prop: { - deprecated: true, - description: 'This is a deprecated property', - type: 'string', - }, - }, -} as const; - -export const $ModelWithCircularReference = { - description: 'This is a model with one property containing a circular reference', - type: 'object', - properties: { - prop: { - $ref: '#/components/schemas/ModelWithCircularReference', - }, - }, -} as const; - -export const $CompositionWithOneOf = { - description: "This is a model with one property with a 'one of' relationship", - type: 'object', - properties: { - propA: { - type: 'object', - oneOf: [ - { - $ref: '#/components/schemas/ModelWithString', - }, - { - $ref: '#/components/schemas/ModelWithEnum', - }, - { - $ref: '#/components/schemas/ModelWithArray', - }, - { - $ref: '#/components/schemas/ModelWithDictionary', - }, - ], - }, - }, -} as const; - -export const $CompositionWithOneOfAnonymous = { - description: "This is a model with one property with a 'one of' relationship where the options are not $ref", - type: 'object', - properties: { - propA: { - type: 'object', - oneOf: [ - { - description: 'Anonymous object type', - type: 'object', - properties: { - propA: { - type: 'string', - }, - }, - }, - { - description: 'Anonymous string type', - type: 'string', - }, - { - description: 'Anonymous integer type', - type: 'integer', - }, - ], - }, - }, -} as const; - -export const $ModelCircle = { - description: 'Circle', - type: 'object', - required: ['kind'], - properties: { - kind: { - type: 'string', - }, - radius: { - type: 'number', - }, - }, -} as const; - -export const $ModelSquare = { - description: 'Square', - type: 'object', - required: ['kind'], - properties: { - kind: { - type: 'string', - }, - sideLength: { - type: 'number', - }, - }, -} as const; - -export const $CompositionWithOneOfDiscriminator = { - description: "This is a model with one property with a 'one of' relationship where the options are not $ref", - type: 'object', - oneOf: [ - { - $ref: '#/components/schemas/ModelCircle', - }, - { - $ref: '#/components/schemas/ModelSquare', - }, - ], - discriminator: { - propertyName: 'kind', - mapping: { - circle: '#/components/schemas/ModelCircle', - square: '#/components/schemas/ModelSquare', - }, - }, -} as const; - -export const $CompositionWithAnyOf = { - description: "This is a model with one property with a 'any of' relationship", - type: 'object', - properties: { - propA: { - type: 'object', - anyOf: [ - { - $ref: '#/components/schemas/ModelWithString', - }, - { - $ref: '#/components/schemas/ModelWithEnum', - }, - { - $ref: '#/components/schemas/ModelWithArray', - }, - { - $ref: '#/components/schemas/ModelWithDictionary', - }, - ], - }, - }, -} as const; - -export const $CompositionWithAnyOfAnonymous = { - description: "This is a model with one property with a 'any of' relationship where the options are not $ref", - type: 'object', - properties: { - propA: { - type: 'object', - anyOf: [ - { - description: 'Anonymous object type', - type: 'object', - properties: { - propA: { - type: 'string', - }, - }, - }, - { - description: 'Anonymous string type', - type: 'string', - }, - { - description: 'Anonymous integer type', - type: 'integer', - }, - ], - }, - }, -} as const; - -export const $CompositionWithNestedAnyAndTypeNull = { - description: "This is a model with nested 'any of' property with a type null", - type: 'object', - properties: { - propA: { - type: 'object', - anyOf: [ - { - items: { - anyOf: [ - { - $ref: '#/components/schemas/ModelWithDictionary', - }, - { - type: 'null', - }, - ], - }, - type: 'array', - }, - { - items: { - anyOf: [ - { - $ref: '#/components/schemas/ModelWithArray', - }, - { - type: 'null', - }, - ], - }, - type: 'array', - }, - ], - }, - }, -} as const; - -export const $Enum1 = { - enum: ['Bird', 'Dog'], - type: 'string', -} as const; - -export const $ConstValue = { - type: 'string', - const: 'ConstValue', -} as const; - -export const $CompositionWithNestedAnyOfAndNull = { - description: "This is a model with one property with a 'any of' relationship where the options are not $ref", - type: 'object', - properties: { - propA: { - anyOf: [ - { - items: { - anyOf: [ - { - $ref: '#/components/schemas/Enum1', - }, - { - $ref: '#/components/schemas/ConstValue', - }, - ], - }, - type: 'array', - }, - { - type: 'null', - }, - ], - title: 'Scopes', - }, - }, -} as const; - -export const $CompositionWithOneOfAndNullable = { - description: "This is a model with one property with a 'one of' relationship", - type: 'object', - properties: { - propA: { - nullable: true, - type: 'object', - oneOf: [ - { - type: 'object', - properties: { - boolean: { - type: 'boolean', - }, - }, - }, - { - $ref: '#/components/schemas/ModelWithEnum', - }, - { - $ref: '#/components/schemas/ModelWithArray', - }, - { - $ref: '#/components/schemas/ModelWithDictionary', - }, - ], - }, - }, -} as const; - -export const $CompositionWithOneOfAndSimpleDictionary = { - description: 'This is a model that contains a simple dictionary within composition', - type: 'object', - properties: { - propA: { - oneOf: [ - { - type: 'boolean', - }, - { - type: 'object', - additionalProperties: { - type: 'number', - }, - }, - ], - }, - }, -} as const; - -export const $CompositionWithOneOfAndSimpleArrayDictionary = { - description: 'This is a model that contains a dictionary of simple arrays within composition', - type: 'object', - properties: { - propA: { - oneOf: [ - { - type: 'boolean', - }, - { - type: 'object', - additionalProperties: { - type: 'array', - items: { - type: 'boolean', - }, - }, - }, - ], - }, - }, -} as const; - -export const $CompositionWithOneOfAndComplexArrayDictionary = { - description: 'This is a model that contains a dictionary of complex arrays (composited) within composition', - type: 'object', - properties: { - propA: { - oneOf: [ - { - type: 'boolean', - }, - { - type: 'object', - additionalProperties: { - type: 'array', - items: { - oneOf: [ - { - type: 'number', - }, - { - type: 'string', - }, - ], - }, - }, - }, - ], - }, - }, -} as const; - -export const $CompositionWithAllOfAndNullable = { - description: "This is a model with one property with a 'all of' relationship", - type: 'object', - properties: { - propA: { - nullable: true, - type: 'object', - allOf: [ - { - type: 'object', - properties: { - boolean: { - type: 'boolean', - }, - }, - }, - { - $ref: '#/components/schemas/ModelWithEnum', - }, - { - $ref: '#/components/schemas/ModelWithArray', - }, - { - $ref: '#/components/schemas/ModelWithDictionary', - }, - ], - }, - }, -} as const; - -export const $CompositionWithAnyOfAndNullable = { - description: "This is a model with one property with a 'any of' relationship", - type: 'object', - properties: { - propA: { - nullable: true, - type: 'object', - anyOf: [ - { - type: 'object', - properties: { - boolean: { - type: 'boolean', - }, - }, - }, - { - $ref: '#/components/schemas/ModelWithEnum', - }, - { - $ref: '#/components/schemas/ModelWithArray', - }, - { - $ref: '#/components/schemas/ModelWithDictionary', - }, - ], - }, - }, -} as const; - -export const $CompositionBaseModel = { - description: 'This is a base model with two simple optional properties', - type: 'object', - properties: { - firstName: { - type: 'string', - }, - lastname: { - type: 'string', - }, - }, -} as const; - -export const $CompositionExtendedModel = { - description: 'This is a model that extends the base model', - type: 'object', - allOf: [ - { - $ref: '#/components/schemas/CompositionBaseModel', - }, - ], - properties: { - age: { - type: 'number', - }, - }, - required: ['firstName', 'lastname', 'age'], -} as const; - -export const $ModelWithProperties = { - description: 'This is a model with one nested property', - type: 'object', - required: ['required', 'requiredAndReadOnly', 'requiredAndNullable'], - properties: { - required: { - type: 'string', - }, - requiredAndReadOnly: { - type: 'string', - readOnly: true, - }, - requiredAndNullable: { - type: 'string', - nullable: true, - }, - string: { - type: 'string', - }, - number: { - type: 'number', - }, - boolean: { - type: 'boolean', - }, - reference: { - $ref: '#/components/schemas/ModelWithString', - }, - 'property with space': { - type: 'string', - }, - default: { - type: 'string', - }, - try: { - type: 'string', - }, - '@namespace.string': { - type: 'string', - readOnly: true, - }, - '@namespace.integer': { - type: 'integer', - readOnly: true, - }, - }, -} as const; - -export const $ModelWithNestedProperties = { - description: 'This is a model with one nested property', - type: 'object', - required: ['first'], - properties: { - first: { - type: 'object', - required: ['second'], - readOnly: true, - nullable: true, - properties: { - second: { - type: 'object', - required: ['third'], - readOnly: true, - nullable: true, - properties: { - third: { - type: 'string', - required: true, - readOnly: true, - nullable: true, - }, - }, - }, - }, - }, - }, -} as const; - -export const $ModelWithDuplicateProperties = { - description: 'This is a model with duplicated properties', - type: 'object', - properties: { - prop: { - $ref: '#/components/schemas/ModelWithString', - }, - }, -} as const; - -export const $ModelWithOrderedProperties = { - description: 'This is a model with ordered properties', - type: 'object', - properties: { - zebra: { - type: 'string', - }, - apple: { - type: 'string', - }, - hawaii: { - type: 'string', - }, - }, -} as const; - -export const $ModelWithDuplicateImports = { - description: 'This is a model with duplicated imports', - type: 'object', - properties: { - propA: { - $ref: '#/components/schemas/ModelWithString', - }, - propB: { - $ref: '#/components/schemas/ModelWithString', - }, - propC: { - $ref: '#/components/schemas/ModelWithString', - }, - }, -} as const; - -export const $ModelThatExtends = { - description: 'This is a model that extends another model', - type: 'object', - allOf: [ - { - $ref: '#/components/schemas/ModelWithString', - }, - { - type: 'object', - properties: { - propExtendsA: { - type: 'string', - }, - propExtendsB: { - $ref: '#/components/schemas/ModelWithString', - }, - }, - }, - ], -} as const; - -export const $ModelThatExtendsExtends = { - description: 'This is a model that extends another model', - type: 'object', - allOf: [ - { - $ref: '#/components/schemas/ModelWithString', - }, - { - $ref: '#/components/schemas/ModelThatExtends', - }, - { - type: 'object', - properties: { - propExtendsC: { - type: 'string', - }, - propExtendsD: { - $ref: '#/components/schemas/ModelWithString', - }, - }, - }, - ], -} as const; - -export const $ModelWithPattern = { - description: 'This is a model that contains a some patterns', - type: 'object', - required: ['key', 'name'], - properties: { - key: { - maxLength: 64, - pattern: '^[a-zA-Z0-9_]*$', - type: 'string', - }, - name: { - maxLength: 255, - type: 'string', - }, - enabled: { - type: 'boolean', - readOnly: true, - }, - modified: { - type: 'string', - format: 'date-time', - readOnly: true, - }, - id: { - type: 'string', - pattern: '^d{2}-d{3}-d{4}$', - }, - text: { - type: 'string', - pattern: '^w+$', - }, - patternWithSingleQuotes: { - type: 'string', - pattern: "^[a-zA-Z0-9']*$", - }, - patternWithNewline: { - type: 'string', - pattern: `aaa -bbb`, - }, - patternWithBacktick: { - type: 'string', - pattern: 'aaa`bbb', - }, - }, -} as const; - -export const $File = { - required: ['mime'], - type: 'object', - properties: { - id: { - title: 'Id', - type: 'string', - readOnly: true, - minLength: 1, - }, - updated_at: { - title: 'Updated at', - type: 'string', - format: 'date-time', - readOnly: true, - }, - created_at: { - title: 'Created at', - type: 'string', - format: 'date-time', - readOnly: true, - }, - mime: { - title: 'Mime', - type: 'string', - maxLength: 24, - minLength: 1, - }, - file: { - title: 'File', - type: 'string', - readOnly: true, - format: 'uri', - }, - }, -} as const; - -export const $default = { - type: 'object', - properties: { - name: { - type: 'string', - }, - }, -} as const; - -export const $Pageable = { - type: 'object', - properties: { - page: { - minimum: 0, - type: 'integer', - format: 'int32', - default: 0, - }, - size: { - minimum: 1, - type: 'integer', - format: 'int32', - }, - sort: { - type: 'array', - items: { - type: 'string', - }, - }, - }, -} as const; - -export const $FreeFormObjectWithoutAdditionalProperties = { - description: 'This is a free-form object without additionalProperties.', - type: 'object', -} as const; - -export const $FreeFormObjectWithAdditionalPropertiesEqTrue = { - description: 'This is a free-form object with additionalProperties: true.', - type: 'object', - additionalProperties: true, -} as const; - -export const $FreeFormObjectWithAdditionalPropertiesEqEmptyObject = { - description: 'This is a free-form object with additionalProperties: {}.', - type: 'object', - additionalProperties: {}, -} as const; - -export const $ModelWithConst = { - type: 'object', - properties: { - String: { - const: 'String', - }, - number: { - const: 0, - }, - null: { - const: null, - }, - withType: { - type: 'string', - const: 'Some string', - }, - }, -} as const; - -export const $ModelWithAdditionalPropertiesEqTrue = { - description: 'This is a model with one property and additionalProperties: true', - type: 'object', - properties: { - prop: { - description: 'This is a simple string property', - type: 'string', - }, - }, - additionalProperties: true, -} as const; - -export const $NestedAnyOfArraysNullable = { - properties: { - nullableArray: { - anyOf: [ - { - items: { - anyOf: [ - { - type: 'string', - }, - { - type: 'boolean', - }, - ], - }, - type: 'array', - }, - { - type: 'null', - }, - ], - }, - }, - type: 'object', -} as const; - -export const $CompositionWithOneOfAndProperties = { - type: 'object', - oneOf: [ - { - type: 'object', - required: ['foo'], - properties: { - foo: { - $ref: '#/components/parameters/SimpleParameter', - }, - }, - additionalProperties: false, - }, - { - type: 'object', - required: ['bar'], - properties: { - bar: { - $ref: '#/components/schemas/NonAsciiString%C3%A6%C3%B8%C3%A5%C3%86%C3%98%C3%85%C3%B6%C3%B4%C3%AA%C3%8A%E5%AD%97%E7%AC%A6%E4%B8%B2', - }, - }, - additionalProperties: false, - }, - ], - required: ['baz', 'qux'], - properties: { - baz: { - type: 'integer', - format: 'uint16', - minimum: 0, - nullable: true, - }, - qux: { - type: 'integer', - format: 'uint8', - minimum: 0, - }, - }, -} as const; - -export const $NullableObject = { - type: 'object', - nullable: true, - description: 'An object that can be null', - properties: { - foo: { - type: 'string', - }, - }, - default: null, -} as const; - -export const $ModelWithNullableObject = { - type: 'object', - properties: { - data: { - $ref: '#/components/schemas/NullableObject', - }, - }, -} as const; - -export const $ModelWithOneOfEnum = { - oneOf: [ - { - type: 'object', - required: ['foo'], - properties: { - foo: { - type: 'string', - enum: ['Bar'], - }, - }, - }, - { - type: 'object', - required: ['foo'], - properties: { - foo: { - type: 'string', - enum: ['Baz'], - }, - }, - }, - { - type: 'object', - required: ['foo'], - properties: { - foo: { - type: 'string', - enum: ['Qux'], - }, - }, - }, - { - type: 'object', - required: ['content', 'foo'], - properties: { - content: { - type: 'string', - format: 'date-time', - }, - foo: { - type: 'string', - enum: ['Quux'], - }, - }, - }, - { - type: 'object', - required: ['content', 'foo'], - properties: { - content: { - type: 'array', - items: [ - { - type: 'string', - format: 'date-time', - }, - { - type: 'string', - }, - ], - maxItems: 2, - minItems: 2, - }, - foo: { - type: 'string', - enum: ['Corge'], - }, - }, - }, - ], -} as const; - -export const $ModelWithNestedArrayEnumsDataFoo = { - enum: ['foo', 'bar'], - type: 'string', -} as const; - -export const $ModelWithNestedArrayEnumsDataBar = { - enum: ['baz', 'qux'], - type: 'string', -} as const; - -export const $ModelWithNestedArrayEnumsData = { - type: 'object', - properties: { - foo: { - type: 'array', - items: { - $ref: '#/components/schemas/ModelWithNestedArrayEnumsDataFoo', - }, - }, - bar: { - type: 'array', - items: { - $ref: '#/components/schemas/ModelWithNestedArrayEnumsDataBar', - }, - }, - }, -} as const; - -export const $ModelWithNestedArrayEnums = { - type: 'object', - properties: { - array_strings: { - type: 'array', - items: { - type: 'string', - }, - }, - data: { - allOf: [ - { - $ref: '#/components/schemas/ModelWithNestedArrayEnumsData', - }, - ], - }, - }, -} as const; - -export const $ModelWithNestedCompositionEnums = { - type: 'object', - properties: { - foo: { - allOf: [ - { - $ref: '#/components/schemas/ModelWithNestedArrayEnumsDataFoo', - }, - ], - }, - }, -} as const; - -export const $ModelWithReadOnlyAndWriteOnly = { - type: 'object', - required: ['foo', 'bar', 'baz'], - properties: { - foo: { - type: 'string', - }, - bar: { - readOnly: true, - type: 'string', - }, - baz: { - type: 'string', - writeOnly: true, - }, - }, -} as const; - -export const $ModelWithConstantSizeArray = { - type: 'array', - items: { - type: 'number', - }, - minItems: 2, - maxItems: 2, -} as const; - -export const $ModelWithAnyOfConstantSizeArray = { - type: 'array', - items: { - oneOf: [ - { - type: 'number', - }, - { - type: 'string', - }, - ], - }, - minItems: 3, - maxItems: 3, -} as const; - -export const $SimpleParameter = { - description: 'This is a reusable parameter', - name: 'parameter', - in: 'query', - required: false, - schema: { - type: 'string', - }, -} as const; diff --git a/packages/openapi-ts/test/__snapshots__/test/generated/v3_experimental/services.ts.snap b/packages/openapi-ts/test/__snapshots__/test/generated/v3_experimental/services.ts.snap deleted file mode 100644 index cac820c7a..000000000 --- a/packages/openapi-ts/test/__snapshots__/test/generated/v3_experimental/services.ts.snap +++ /dev/null @@ -1,807 +0,0 @@ -import type { CancelablePromise } from './core/CancelablePromise'; -import { OpenAPI } from './core/OpenAPI'; -import { request as __request } from './core/request'; -import type { - $OpenApiTsDefault, - $OpenApiTsSimple, - $OpenApiTsParameters, - $OpenApiTsDescriptions, - $OpenApiTsDeprecated, - $OpenApiTsRequestBody, - $OpenApiTsFormData, - $OpenApiTsDefaults, - $OpenApiTsDuplicate, - $OpenApiTsNoContent, - $OpenApiTsResponse, - $OpenApiTsMultipleTags1, - $OpenApiTsMultipleTags2, - $OpenApiTsMultipleTags3, - $OpenApiTsCollectionFormat, - $OpenApiTsTypes, - $OpenApiTsUpload, - $OpenApiTsFileResponse, - $OpenApiTsComplex, - $OpenApiTsMultipart, - $OpenApiTsHeader, - $OpenApiTsError, - $OpenApiTsNonAsciiÆøåÆøÅöôêÊ, -} from './models'; - -export class DefaultService { - /** - * @throws ApiError - */ - public static serviceWithEmptyTag(): CancelablePromise<$OpenApiTsDefault['res']['ServiceWithEmptyTag']> { - return __request(OpenAPI, { - method: 'GET', - url: '/api/v{api-version}/no-tag', - }); - } - - /** - * @returns ModelWithReadOnlyAndWriteOnly - * @throws ApiError - */ - public static postServiceWithEmptyTag( - data: $OpenApiTsDefault['req']['PostServiceWithEmptyTag'] - ): CancelablePromise<$OpenApiTsDefault['res']['PostServiceWithEmptyTag']> { - const { query, requestBody } = data; - return __request(OpenAPI, { - method: 'POST', - url: '/api/v{api-version}/no-tag', - body: requestBody, - mediaType: 'application/json', - }); - } -} - -export class SimpleService { - /** - * @returns Model_From_Zendesk Success - * @throws ApiError - */ - public static apiVVersionOdataControllerCount(): CancelablePromise< - $OpenApiTsSimple['res']['ApiVversionOdataControllerCount'] - > { - return __request(OpenAPI, { - method: 'GET', - url: '/api/v{api-version}/simple/$count', - }); - } - - /** - * @throws ApiError - */ - public static getCallWithoutParametersAndResponse(): CancelablePromise< - $OpenApiTsSimple['res']['GetCallWithoutParametersAndResponse'] - > { - return __request(OpenAPI, { - method: 'GET', - url: '/api/v{api-version}/simple', - }); - } - - /** - * @throws ApiError - */ - public static putCallWithoutParametersAndResponse(): CancelablePromise< - $OpenApiTsSimple['res']['PutCallWithoutParametersAndResponse'] - > { - return __request(OpenAPI, { - method: 'PUT', - url: '/api/v{api-version}/simple', - }); - } - - /** - * @throws ApiError - */ - public static postCallWithoutParametersAndResponse(): CancelablePromise< - $OpenApiTsSimple['res']['PostCallWithoutParametersAndResponse'] - > { - return __request(OpenAPI, { - method: 'POST', - url: '/api/v{api-version}/simple', - }); - } - - /** - * @throws ApiError - */ - public static deleteCallWithoutParametersAndResponse(): CancelablePromise< - $OpenApiTsSimple['res']['DeleteCallWithoutParametersAndResponse'] - > { - return __request(OpenAPI, { - method: 'DELETE', - url: '/api/v{api-version}/simple', - }); - } - - /** - * @throws ApiError - */ - public static optionsCallWithoutParametersAndResponse(): CancelablePromise< - $OpenApiTsSimple['res']['OptionsCallWithoutParametersAndResponse'] - > { - return __request(OpenAPI, { - method: 'OPTIONS', - url: '/api/v{api-version}/simple', - }); - } - - /** - * @throws ApiError - */ - public static headCallWithoutParametersAndResponse(): CancelablePromise< - $OpenApiTsSimple['res']['HeadCallWithoutParametersAndResponse'] - > { - return __request(OpenAPI, { - method: 'HEAD', - url: '/api/v{api-version}/simple', - }); - } - - /** - * @throws ApiError - */ - public static patchCallWithoutParametersAndResponse(): CancelablePromise< - $OpenApiTsSimple['res']['PatchCallWithoutParametersAndResponse'] - > { - return __request(OpenAPI, { - method: 'PATCH', - url: '/api/v{api-version}/simple', - }); - } -} - -export class ParametersService { - /** - * @throws ApiError - */ - public static deleteFoo( - data: $OpenApiTsParameters['req']['DeleteFoo'] - ): CancelablePromise<$OpenApiTsParameters['res']['DeleteFoo']> { - const { query, foo, bar } = data; - return __request(OpenAPI, { - method: 'DELETE', - url: '/api/v{api-version}/foo/{foo}/bar/{bar}', - path: {}, - }); - } - - /** - * @throws ApiError - */ - public static callWithParameters( - data: $OpenApiTsParameters['req']['CallWithParameters'] - ): CancelablePromise<$OpenApiTsParameters['res']['CallWithParameters']> { - const { query, parameterHeader, parameterForm, parameterCookie, parameterPath, requestBody } = data; - return __request(OpenAPI, { - method: 'POST', - url: '/api/v{api-version}/parameters/{parameterPath}', - path: {}, - cookies: {}, - headers: {}, - query: { - ...query, - }, - formData: {}, - body: requestBody, - mediaType: 'application/json', - }); - } - - /** - * @throws ApiError - */ - public static callWithWeirdParameterNames( - data: $OpenApiTsParameters['req']['CallWithWeirdParameterNames'] - ): CancelablePromise<$OpenApiTsParameters['res']['CallWithWeirdParameterNames']> { - const { - query, - parameterHeader, - parameterForm, - parameterCookie, - requestBody, - parameterPath1, - parameterPath2, - parameterPath3, - } = data; - return __request(OpenAPI, { - method: 'POST', - url: '/api/v{api-version}/parameters/{parameter.path.1}/{parameter-path-2}/{PARAMETER-PATH-3}', - path: {}, - cookies: {}, - headers: {}, - query: { - ...query, - }, - formData: {}, - body: requestBody, - mediaType: 'application/json', - }); - } - - /** - * @throws ApiError - */ - public static getCallWithOptionalParam( - data: $OpenApiTsParameters['req']['GetCallWithOptionalParam'] - ): CancelablePromise<$OpenApiTsParameters['res']['GetCallWithOptionalParam']> { - const { query, requestBody } = data; - return __request(OpenAPI, { - method: 'GET', - url: '/api/v{api-version}/parameters/', - query: { - ...query, - }, - body: requestBody, - mediaType: 'application/json', - }); - } - - /** - * @throws ApiError - */ - public static postCallWithOptionalParam( - data: $OpenApiTsParameters['req']['PostCallWithOptionalParam'] - ): CancelablePromise<$OpenApiTsParameters['res']['PostCallWithOptionalParam']> { - const { query, requestBody } = data; - return __request(OpenAPI, { - method: 'POST', - url: '/api/v{api-version}/parameters/', - query: { - ...query, - }, - body: requestBody, - mediaType: 'application/json', - }); - } -} - -export class DescriptionsService { - /** - * @throws ApiError - */ - public static callWithDescriptions( - data: $OpenApiTsDescriptions['req']['CallWithDescriptions'] = {} - ): CancelablePromise<$OpenApiTsDescriptions['res']['CallWithDescriptions']> { - const { query } = data; - return __request(OpenAPI, { - method: 'POST', - url: '/api/v{api-version}/descriptions/', - query: { - ...query, - }, - }); - } -} - -export class DeprecatedService { - /** - * @deprecated - * @throws ApiError - */ - public static deprecatedCall( - data: $OpenApiTsDeprecated['req']['DeprecatedCall'] - ): CancelablePromise<$OpenApiTsDeprecated['res']['DeprecatedCall']> { - const { query, parameter } = data; - return __request(OpenAPI, { - method: 'POST', - url: '/api/v{api-version}/parameters/deprecated', - headers: {}, - }); - } -} - -export class RequestBodyService { - /** - * @throws ApiError - */ - public static postApiRequestBody( - data: $OpenApiTsRequestBody['req']['PostApiRequestBody'] = {} - ): CancelablePromise<$OpenApiTsRequestBody['res']['PostApiRequestBody']> { - const { query, foo } = data; - return __request(OpenAPI, { - method: 'POST', - url: '/api/v{api-version}/requestBody/', - query: { - ...query, - }, - body: foo, - mediaType: 'application/json', - }); - } -} - -export class FormDataService { - /** - * @throws ApiError - */ - public static postApiFormData( - data: $OpenApiTsFormData['req']['PostApiFormData'] = {} - ): CancelablePromise<$OpenApiTsFormData['res']['PostApiFormData']> { - const { query, formData } = data; - return __request(OpenAPI, { - method: 'POST', - url: '/api/v{api-version}/formData/', - query: { - ...query, - }, - formData: formData, - mediaType: 'multipart/form-data', - }); - } -} - -export class DefaultsService { - /** - * @throws ApiError - */ - public static callWithDefaultParameters( - data: $OpenApiTsDefaults['req']['CallWithDefaultParameters'] = {} - ): CancelablePromise<$OpenApiTsDefaults['res']['CallWithDefaultParameters']> { - const { query } = data; - return __request(OpenAPI, { - method: 'GET', - url: '/api/v{api-version}/defaults', - query: { - parameterString: 'Hello World!', - parameterNumber: 123, - parameterBoolean: true, - parameterEnum: 'Success', - parameterModel: { - prop: 'Hello World!', - }, - ...query, - }, - }); - } - - /** - * @throws ApiError - */ - public static callWithDefaultOptionalParameters( - data: $OpenApiTsDefaults['req']['CallWithDefaultOptionalParameters'] = {} - ): CancelablePromise<$OpenApiTsDefaults['res']['CallWithDefaultOptionalParameters']> { - const { query } = data; - return __request(OpenAPI, { - method: 'POST', - url: '/api/v{api-version}/defaults', - query: { - parameterString: 'Hello World!', - parameterNumber: 123, - parameterBoolean: true, - parameterEnum: 'Success', - parameterModel: { - prop: 'Hello World!', - }, - ...query, - }, - }); - } - - /** - * @throws ApiError - */ - public static callToTestOrderOfParams( - data: $OpenApiTsDefaults['req']['CallToTestOrderOfParams'] - ): CancelablePromise<$OpenApiTsDefaults['res']['CallToTestOrderOfParams']> { - const { query } = data; - return __request(OpenAPI, { - method: 'PUT', - url: '/api/v{api-version}/defaults', - query: { - parameterOptionalStringWithDefault: 'Hello World!', - parameterOptionalStringWithEmptyDefault: '', - parameterStringWithDefault: 'Hello World!', - parameterStringWithEmptyDefault: '', - parameterStringNullableWithDefault: null, - ...query, - }, - }); - } -} - -export class DuplicateService { - /** - * @throws ApiError - */ - public static duplicateName(): CancelablePromise<$OpenApiTsDuplicate['res']['DuplicateName']> { - return __request(OpenAPI, { - method: 'GET', - url: '/api/v{api-version}/duplicate', - }); - } - - /** - * @throws ApiError - */ - public static duplicateName1(): CancelablePromise<$OpenApiTsDuplicate['res']['DuplicateName1']> { - return __request(OpenAPI, { - method: 'POST', - url: '/api/v{api-version}/duplicate', - }); - } - - /** - * @throws ApiError - */ - public static duplicateName2(): CancelablePromise<$OpenApiTsDuplicate['res']['DuplicateName2']> { - return __request(OpenAPI, { - method: 'PUT', - url: '/api/v{api-version}/duplicate', - }); - } - - /** - * @throws ApiError - */ - public static duplicateName3(): CancelablePromise<$OpenApiTsDuplicate['res']['DuplicateName3']> { - return __request(OpenAPI, { - method: 'DELETE', - url: '/api/v{api-version}/duplicate', - }); - } -} - -export class NoContentService { - /** - * @returns void Success - * @throws ApiError - */ - public static callWithNoContentResponse(): CancelablePromise< - $OpenApiTsNoContent['res']['CallWithNoContentResponse'] - > { - return __request(OpenAPI, { - method: 'GET', - url: '/api/v{api-version}/no-content', - }); - } - - /** - * @returns number Response is a simple number - * @returns void Success - * @throws ApiError - */ - public static callWithResponseAndNoContentResponse(): CancelablePromise< - $OpenApiTsNoContent['res']['CallWithResponseAndNoContentResponse'] - > { - return __request(OpenAPI, { - method: 'GET', - url: '/api/v{api-version}/multiple-tags/response-and-no-content', - }); - } -} - -export class ResponseService { - /** - * @returns number Response is a simple number - * @returns void Success - * @throws ApiError - */ - public static callWithResponseAndNoContentResponse(): CancelablePromise< - $OpenApiTsResponse['res']['CallWithResponseAndNoContentResponse'] - > { - return __request(OpenAPI, { - method: 'GET', - url: '/api/v{api-version}/multiple-tags/response-and-no-content', - }); - } - - /** - * @returns ModelWithString - * @throws ApiError - */ - public static callWithResponse(): CancelablePromise<$OpenApiTsResponse['res']['CallWithResponse']> { - return __request(OpenAPI, { - method: 'GET', - url: '/api/v{api-version}/response', - }); - } - - /** - * @returns ModelWithString Message for default response - * @throws ApiError - */ - public static callWithDuplicateResponses(): CancelablePromise< - $OpenApiTsResponse['res']['CallWithDuplicateResponses'] - > { - return __request(OpenAPI, { - method: 'POST', - url: '/api/v{api-version}/response', - errors: { - 500: `Message for 500 error`, - 501: `Message for 501 error`, - 502: `Message for 502 error`, - }, - }); - } - - /** - * @returns any Message for 200 response - * @returns ModelWithString Message for default response - * @returns ModelThatExtends Message for 201 response - * @returns ModelThatExtendsExtends Message for 202 response - * @throws ApiError - */ - public static callWithResponses(): CancelablePromise<$OpenApiTsResponse['res']['CallWithResponses']> { - return __request(OpenAPI, { - method: 'PUT', - url: '/api/v{api-version}/response', - errors: { - 500: `Message for 500 error`, - 501: `Message for 501 error`, - 502: `Message for 502 error`, - }, - }); - } -} - -export class MultipleTags1Service { - /** - * @returns void Success - * @throws ApiError - */ - public static dummyA(): CancelablePromise<$OpenApiTsMultipleTags1['res']['DummyA']> { - return __request(OpenAPI, { - method: 'GET', - url: '/api/v{api-version}/multiple-tags/a', - }); - } - - /** - * @returns void Success - * @throws ApiError - */ - public static dummyB(): CancelablePromise<$OpenApiTsMultipleTags1['res']['DummyB']> { - return __request(OpenAPI, { - method: 'GET', - url: '/api/v{api-version}/multiple-tags/b', - }); - } -} - -export class MultipleTags2Service { - /** - * @returns void Success - * @throws ApiError - */ - public static dummyA(): CancelablePromise<$OpenApiTsMultipleTags2['res']['DummyA']> { - return __request(OpenAPI, { - method: 'GET', - url: '/api/v{api-version}/multiple-tags/a', - }); - } - - /** - * @returns void Success - * @throws ApiError - */ - public static dummyB(): CancelablePromise<$OpenApiTsMultipleTags2['res']['DummyB']> { - return __request(OpenAPI, { - method: 'GET', - url: '/api/v{api-version}/multiple-tags/b', - }); - } -} - -export class MultipleTags3Service { - /** - * @returns void Success - * @throws ApiError - */ - public static dummyB(): CancelablePromise<$OpenApiTsMultipleTags3['res']['DummyB']> { - return __request(OpenAPI, { - method: 'GET', - url: '/api/v{api-version}/multiple-tags/b', - }); - } -} - -export class CollectionFormatService { - /** - * @throws ApiError - */ - public static collectionFormat( - data: $OpenApiTsCollectionFormat['req']['CollectionFormat'] - ): CancelablePromise<$OpenApiTsCollectionFormat['res']['CollectionFormat']> { - const { query } = data; - return __request(OpenAPI, { - method: 'GET', - url: '/api/v{api-version}/collectionFormat', - query: { - ...query, - }, - }); - } -} - -export class TypesService { - /** - * @returns number Response is a simple number - * @returns string Response is a simple string - * @returns boolean Response is a simple boolean - * @returns unknown Response is a simple object - * @throws ApiError - */ - public static types(data: $OpenApiTsTypes['req']['Types']): CancelablePromise<$OpenApiTsTypes['res']['Types']> { - const { query, id } = data; - return __request(OpenAPI, { - method: 'GET', - url: '/api/v{api-version}/types', - path: {}, - query: { - parameterNumber: 123, - parameterString: 'default', - parameterBoolean: true, - parameterObject: null, - ...query, - }, - }); - } -} - -export class UploadService { - /** - * @returns boolean - * @throws ApiError - */ - public static uploadFile( - data: $OpenApiTsUpload['req']['UploadFile'] - ): CancelablePromise<$OpenApiTsUpload['res']['UploadFile']> { - const { query, file } = data; - return __request(OpenAPI, { - method: 'POST', - url: '/api/v{api-version}/upload', - formData: {}, - }); - } -} - -export class FileResponseService { - /** - * @returns binary Success - * @throws ApiError - */ - public static fileResponse( - data: $OpenApiTsFileResponse['req']['FileResponse'] - ): CancelablePromise<$OpenApiTsFileResponse['res']['FileResponse']> { - const { query, id } = data; - return __request(OpenAPI, { - method: 'GET', - url: '/api/v{api-version}/file/{id}', - path: {}, - }); - } -} - -export class ComplexService { - /** - * @returns ModelWithString Successful response - * @throws ApiError - */ - public static complexTypes( - data: $OpenApiTsComplex['req']['ComplexTypes'] - ): CancelablePromise<$OpenApiTsComplex['res']['ComplexTypes']> { - const { query } = data; - return __request(OpenAPI, { - method: 'GET', - url: '/api/v{api-version}/complex', - query: { - ...query, - }, - errors: { - 400: `400 server error`, - 500: `500 server error`, - }, - }); - } - - /** - * @returns ModelWithString Success - * @throws ApiError - */ - public static complexParams( - data: $OpenApiTsComplex['req']['ComplexParams'] - ): CancelablePromise<$OpenApiTsComplex['res']['ComplexParams']> { - const { query, id, requestBody } = data; - return __request(OpenAPI, { - method: 'PUT', - url: '/api/v{api-version}/complex/{id}', - path: {}, - body: requestBody, - mediaType: 'application/json-patch+json', - }); - } -} - -export class MultipartService { - /** - * @throws ApiError - */ - public static multipartRequest( - data: $OpenApiTsMultipart['req']['MultipartRequest'] = {} - ): CancelablePromise<$OpenApiTsMultipart['res']['MultipartRequest']> { - const { query, formData } = data; - return __request(OpenAPI, { - method: 'POST', - url: '/api/v{api-version}/multipart', - formData: formData, - mediaType: 'multipart/form-data', - }); - } - - /** - * @returns any OK - * @throws ApiError - */ - public static multipartResponse(): CancelablePromise<$OpenApiTsMultipart['res']['MultipartResponse']> { - return __request(OpenAPI, { - method: 'GET', - url: '/api/v{api-version}/multipart', - }); - } -} - -export class HeaderService { - /** - * @returns string Successful response - * @throws ApiError - */ - public static callWithResultFromHeader(): CancelablePromise<$OpenApiTsHeader['res']['CallWithResultFromHeader']> { - return __request(OpenAPI, { - method: 'POST', - url: '/api/v{api-version}/header', - responseHeader: 'operation-location', - errors: { - 400: `400 server error`, - 500: `500 server error`, - }, - }); - } -} - -export class ErrorService { - /** - * @returns any Custom message: Successful response - * @throws ApiError - */ - public static testErrorCode( - data: $OpenApiTsError['req']['TestErrorCode'] - ): CancelablePromise<$OpenApiTsError['res']['TestErrorCode']> { - const { query } = data; - return __request(OpenAPI, { - method: 'POST', - url: '/api/v{api-version}/error', - query: { - ...query, - }, - errors: { - 500: `Custom message: Internal Server Error`, - 501: `Custom message: Not Implemented`, - 502: `Custom message: Bad Gateway`, - 503: `Custom message: Service Unavailable`, - }, - }); - } -} - -export class NonAsciiÆøåÆøÅöôêÊService { - /** - * @returns NonAsciiStringæøåÆØÅöôêÊ字符串 Successful response - * @throws ApiError - */ - public static nonAsciiæøåÆøÅöôêÊ字符串( - data: $OpenApiTsNonAsciiÆøåÆøÅöôêÊ['req']['NonAsciiæøåÆøÅöôêÊ字符串'] - ): CancelablePromise<$OpenApiTsNonAsciiÆøåÆøÅöôêÊ['res']['NonAsciiæøåÆøÅöôêÊ字符串']> { - const { query } = data; - return __request(OpenAPI, { - method: 'POST', - url: '/api/v{api-version}/non-ascii-æøåÆØÅöôêÊ字符串', - query: { - ...query, - }, - }); - } -}