diff --git a/.eslintrc.json b/.eslintrc.json index 6a378ecfe..9444b69e9 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -16,7 +16,7 @@ "@typescript-eslint/ban-ts-ignore": 0, "@typescript-eslint/explicit-function-return-type": 0, "@typescript-eslint/explicit-module-boundary-types": 0, - "@typescript-eslint/no-explicit-any": 0, + "@typescript-eslint/no-explicit-any": "error", "@typescript-eslint/no-inferrable-types": 0, "@typescript-eslint/no-non-null-assertion": 0, "@typescript-eslint/no-var-requires": 0, diff --git a/.github/workflows/unittest.yml b/.github/workflows/unittest.yml index 88d0fde35..4d79ce2c5 100644 --- a/.github/workflows/unittest.yml +++ b/.github/workflows/unittest.yml @@ -26,6 +26,9 @@ jobs: - name: Build library run: npm run release + - name: Run linter + run: npm run eslint + - name: Run unit tests run: npm run test diff --git a/bin/index.js b/bin/index.js index 216dac239..6e2bada19 100755 --- a/bin/index.js +++ b/bin/index.js @@ -12,7 +12,7 @@ const params = program .version(json.version) .requiredOption('-i, --input ', 'OpenAPI specification, can be a path, url or string content (required)') .requiredOption('-o, --output ', 'Output directory (required)') - .option('-c, --client ', 'HTTP client to generate [fetch, xhr, node, axios, angular]', 'fetch') + .option('-c, --client ', 'HTTP client to generate [fetch, xhr, node, axios, angular]') .option('--name ', 'Custom client class name') .option('--useOptions [value]', 'Use options instead of arguments', false) .option('--no-autoformat', 'Disable processing generated files with formatter') @@ -44,7 +44,6 @@ if (OpenAPI) { exportModels: parseBooleanOrString(params.exportModels), exportSchemas: JSON.parse(params.exportSchemas) === true, exportServices: parseBooleanOrString(params.exportServices), - httpClient: params.client, useDateType: JSON.parse(params.useDateType) === true, useOptions: JSON.parse(params.useOptions) === true, }) diff --git a/bin/index.spec.js b/bin/index.spec.js index 935aca28c..0864bfa54 100755 --- a/bin/index.spec.js +++ b/bin/index.spec.js @@ -1,7 +1,7 @@ const { sync } = require('cross-spawn'); describe('bin', () => { - it('it should support minimal params', async () => { + it('supports required parameters', async () => { const result = sync('node', [ './bin/index.js', '--input', @@ -10,11 +10,86 @@ describe('bin', () => { './test/generated/bin', '--no-write', ]); - expect(result.stdout.toString()).toBe(''); + expect(result.stdout.toString()).not.toContain('Prettier'); + expect(result.stdout.toString()).toContain('Done!'); expect(result.stderr.toString()).toBe(''); }); - it('it should support all params', async () => { + it('generates angular client', async () => { + const result = sync('node', [ + './bin/index.js', + '--input', + './test/spec/v3.json', + '--output', + './test/generated/bin', + '--client', + 'angular', + '--no-write', + ]); + expect(result.stdout.toString()).toContain('Angular'); + expect(result.stderr.toString()).toBe(''); + }); + + it('generates axios client', async () => { + const result = sync('node', [ + './bin/index.js', + '--input', + './test/spec/v3.json', + '--output', + './test/generated/bin', + '--client', + 'axios', + '--no-write', + ]); + expect(result.stdout.toString()).toContain('Axios'); + expect(result.stderr.toString()).toBe(''); + }); + + it('generates fetch client', async () => { + const result = sync('node', [ + './bin/index.js', + '--input', + './test/spec/v3.json', + '--output', + './test/generated/bin', + '--client', + 'fetch', + '--no-write', + ]); + expect(result.stdout.toString()).toContain('Fetch'); + expect(result.stderr.toString()).toBe(''); + }); + it('generates node client', async () => { + const result = sync('node', [ + './bin/index.js', + '--input', + './test/spec/v3.json', + '--output', + './test/generated/bin', + '--client', + 'node', + '--no-write', + ]); + expect(result.stdout.toString()).toContain('Node.js'); + expect(result.stderr.toString()).toBe(''); + }); + + it('generates xhr client', async () => { + const result = sync('node', [ + './bin/index.js', + '--input', + './test/spec/v3.json', + '--output', + './test/generated/bin', + '--client', + 'xhr', + '--no-write', + ]); + expect(result.stdout.toString()).toContain('XHR'); + expect(result.stderr.toString()).toBe(''); + }); + + it('supports all parameters', async () => { const result = sync('node', [ './bin/index.js', '--input', @@ -38,11 +113,11 @@ describe('bin', () => { 'Dto', '--no-write', ]); - expect(result.stdout.toString()).toBe(''); + expect(result.stdout.toString()).toContain('Done!'); expect(result.stderr.toString()).toBe(''); }); - it('it should support regexp params', async () => { + it('supports regexp parameters', async () => { const result = sync('node', [ './bin/index.js', '--input', @@ -55,30 +130,29 @@ describe('bin', () => { '^(Simple|Types)', '--no-write', ]); - expect(result.stdout.toString()).toBe(''); + expect(result.stdout.toString()).toContain('Done!'); expect(result.stderr.toString()).toBe(''); }); - it('should autoformat with Prettier', async () => { + it('autoformats output with Prettier', async () => { const result = sync('node', [ './bin/index.js', '--input', './test/spec/v3.json', '--output', './test/generated/bin', - '--no-write', ]); - expect(result.stdout.toString()).toBe(''); + expect(result.stdout.toString()).toContain('Prettier'); expect(result.stderr.toString()).toBe(''); }); - it('it should throw error without params', async () => { + it('throws error without parameters', async () => { const result = sync('node', ['./bin/index.js', '--no-write']); expect(result.stdout.toString()).toBe(''); expect(result.stderr.toString()).toContain(`error: required option '-i, --input ' not specified`); }); - it('it should throw error with wrong params', async () => { + it('throws error with wrong parameters', async () => { const result = sync('node', [ './bin/index.js', '--input', @@ -92,7 +166,7 @@ describe('bin', () => { expect(result.stderr.toString()).toContain(`error: unknown option '--unknown'`); }); - it('it should display help', async () => { + it('displays help', async () => { const result = sync('node', ['./bin/index.js', '--help', '--no-write']); expect(result.stdout.toString()).toContain(`Usage: openapi-ts [options]`); expect(result.stdout.toString()).toContain(`-i, --input `); diff --git a/src/HttpClient.ts b/src/HttpClient.ts deleted file mode 100644 index 40c77c7c9..000000000 --- a/src/HttpClient.ts +++ /dev/null @@ -1,7 +0,0 @@ -export enum HttpClient { - FETCH = 'fetch', - XHR = 'xhr', - NODE = 'node', - AXIOS = 'axios', - ANGULAR = 'angular', -} diff --git a/src/client/interfaces/Options.d.ts b/src/client/interfaces/Options.d.ts index 4af2f76cb..a38aea58a 100644 --- a/src/client/interfaces/Options.d.ts +++ b/src/client/interfaces/Options.d.ts @@ -1,4 +1,5 @@ -import { HttpClient } from '../../HttpClient'; +import type { OpenApi as OpenApiV2 } from '../../openApi/v2/interfaces/OpenApi'; +import type { OpenApi as OpenApiV3 } from '../../openApi/v3/interfaces/OpenApi'; export type ServiceResponse = 'body' | 'generics' | 'response'; @@ -11,6 +12,10 @@ export interface Options { * Manually set base in OpenAPI config instead of inferring from server value */ base?: string; + /** + * The selected HTTP client (fetch, xhr, node or axios) + */ + client?: 'angular' | 'axios' | 'fetch' | 'node' | 'xhr'; /** * Custom client class name */ @@ -35,14 +40,10 @@ export interface Options { * Generate services */ exportServices?: boolean | string; - /** - * The selected httpClient (fetch, xhr, node or axios) - */ - httpClient?: HttpClient; /** * The relative location of the OpenAPI spec */ - input: string | Record; + input: string | OpenApiV2 | OpenApiV3; /** * Use operation ID to generate operation names? */ diff --git a/src/index.spec.ts b/src/index.spec.ts index 1e42c68e4..7b365b261 100644 --- a/src/index.spec.ts +++ b/src/index.spec.ts @@ -1,8 +1,10 @@ -import OpenAPI from './index'; +import { generate, parseOpenApiSpecification } from './index'; +import * as parseV2 from './openApi/v2'; +import * as parseV3 from './openApi/v3'; describe('index', () => { it('parses v2 without issues', async () => { - await OpenAPI.generate({ + await generate({ input: './test/spec/v2.json', output: './generated/v2/', write: false, @@ -10,7 +12,7 @@ describe('index', () => { }); it('parses v3 without issues', async () => { - await OpenAPI.generate({ + await generate({ input: './test/spec/v3.json', output: './generated/v3/', write: false, @@ -18,7 +20,7 @@ describe('index', () => { }); it('downloads and parses v2 without issues', async () => { - await OpenAPI.generate({ + await generate({ input: 'https://raw.githubusercontent.com/ferdikoomen/openapi-typescript-codegen/master/test/spec/v2.json', output: './generated/v2-downloaded/', write: false, @@ -26,10 +28,105 @@ describe('index', () => { }); it('downloads and parses v3 without issues', async () => { - await OpenAPI.generate({ + await generate({ input: 'https://raw.githubusercontent.com/ferdikoomen/openapi-typescript-codegen/master/test/spec/v3.json', output: './generated/v3-downloaded/', write: false, }); }); }); + +describe('parseOpenApiSpecification', () => { + afterEach(() => { + jest.restoreAllMocks(); + }); + + const options: Parameters[1] = { + autoformat: true, + client: 'fetch', + enums: true, + exportCore: true, + exportModels: true, + exportSchemas: true, + exportServices: true, + input: '', + operationId: true, + output: '', + postfixModels: '', + postfixServices: '', + serviceResponse: 'body', + useDateType: false, + useOptions: true, + write: false, + }; + + it('uses v2 parser', () => { + const spy = jest.spyOn(parseV2, 'parse'); + + const spec: Parameters[0] = { + info: { + title: 'dummy', + version: '1.0', + }, + paths: {}, + swagger: '2', + }; + parseOpenApiSpecification(spec, options); + expect(spy).toHaveBeenCalledWith(spec, options); + + const spec2: Parameters[0] = { + info: { + title: 'dummy', + version: '1.0', + }, + paths: {}, + swagger: '2.0', + }; + parseOpenApiSpecification(spec2, options); + expect(spy).toHaveBeenCalledWith(spec2, options); + }); + + it('uses v3 parser', () => { + const spy = jest.spyOn(parseV3, 'parse'); + + const spec: Parameters[0] = { + info: { + title: 'dummy', + version: '1.0', + }, + openapi: '3', + paths: {}, + }; + parseOpenApiSpecification(spec, options); + expect(spy).toHaveBeenCalledWith(spec, options); + + const spec2: Parameters[0] = { + info: { + title: 'dummy', + version: '1.0', + }, + openapi: '3.0', + paths: {}, + }; + parseOpenApiSpecification(spec2, options); + expect(spy).toHaveBeenCalledWith(spec2, options); + + const spec3: Parameters[0] = { + info: { + title: 'dummy', + version: '1.0', + }, + openapi: '3.1.0', + paths: {}, + }; + parseOpenApiSpecification(spec3, options); + expect(spy).toHaveBeenCalledWith(spec3, options); + }); + + it('throws on unknown version', () => { + // @ts-ignore + expect(() => parseOpenApiSpecification({ foo: 'bar' }, options)).toThrow( + `Unsupported Open API specification: ${JSON.stringify({ foo: 'bar' }, null, 2)}` + ); + }); +}); diff --git a/src/index.ts b/src/index.ts index 206d716f2..e4c5860ab 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,12 +1,65 @@ +import { sync } from 'cross-spawn'; +import { createRequire } from 'module'; +import Path from 'path'; + import type { Options } from './client/interfaces/Options'; -import { HttpClient } from './HttpClient'; +import { parse as parseV2 } from './openApi/v2'; +import { parse as parseV3 } from './openApi/v3'; import { getOpenApiSpec } from './utils/getOpenApiSpec'; -import { getOpenApiSpecParser } from './utils/getOpenApiSpecParser'; import { postProcessClient } from './utils/postProcessClient'; import { registerHandlebarTemplates } from './utils/registerHandlebarTemplates'; import { writeClient } from './utils/write/client'; -export { HttpClient } from './HttpClient'; +type DefaultOptions = Omit, 'base' | 'clientName' | 'request'> & + Pick; + +export const parseOpenApiSpecification = (openApi: Exclude, options: DefaultOptions) => { + if ('swagger' in openApi) { + return parseV2(openApi, options); + } + if ('openapi' in openApi) { + return parseV3(openApi, options); + } + throw new Error(`Unsupported Open API specification: ${JSON.stringify(openApi, null, 2)}`); +}; + +const formatClient = (options: DefaultOptions, dependencies: Record) => { + if (!options.autoformat) { + return; + } + + if (dependencies.prettier) { + console.log('✨ Running Prettier'); + sync('prettier', ['--ignore-unknown', options.output, '--write', '--ignore-path', './.prettierignore']); + } +}; + +const getClientType = (options: Options, dependencies: Record): DefaultOptions['client'] => { + let { client } = options; + if (!client) { + if (dependencies.axios) { + client = 'axios'; + } + } + switch (client) { + case 'angular': + console.log('✨ Creating Angular client'); + return client; + case 'axios': + console.log('✨ Creating Axios client'); + return client; + case 'node': + console.log('✨ Creating Node.js client'); + return client; + case 'xhr': + console.log('✨ Creating XHR client'); + return client; + case 'fetch': + default: + console.log('✨ Creating Fetch client'); + return 'fetch'; + } +}; /** * Generate the OpenAPI client. This method will read the OpenAPI specification and based on the @@ -15,6 +68,18 @@ export { HttpClient } from './HttpClient'; * @param options Options passed to the generate method */ export const generate = async (options: Options): Promise => { + const pathPackageJson = Path.resolve(process.cwd(), 'package.json'); + const require = createRequire('/'); + const json = require(pathPackageJson); + + const dependencies = [json.dependencies, json.devDependencies].reduce( + (res, deps) => ({ + ...res, + ...deps, + }), + {} + ); + const { autoformat = true, base, @@ -24,7 +89,6 @@ export const generate = async (options: Options): Promise => { exportModels = true, exportSchemas = false, exportServices = true, - httpClient = HttpClient.FETCH, input, operationId = true, output, @@ -37,17 +101,18 @@ export const generate = async (options: Options): Promise => { write = true, } = options; - const defaultOptions: Omit, 'base' | 'clientName' | 'request'> & - Pick = { + const client = getClientType(options, dependencies); + + const defaultOptions: DefaultOptions = { autoformat, base, + client, clientName, enums, exportCore, exportModels, exportSchemas, exportServices, - httpClient, input, operationId, output, @@ -62,17 +127,19 @@ export const generate = async (options: Options): Promise => { const openApi = typeof defaultOptions.input === 'string' ? await getOpenApiSpec(defaultOptions.input) : defaultOptions.input; - const parser = getOpenApiSpecParser(openApi); const templates = registerHandlebarTemplates(openApi, defaultOptions); - const client = parser(openApi, defaultOptions); - const clientFinal = postProcessClient(client); + const parsedClient = parseOpenApiSpecification(openApi, defaultOptions); + const finalClient = postProcessClient(parsedClient); + if (write) { - await writeClient(clientFinal, templates, defaultOptions); + await writeClient(finalClient, templates, defaultOptions); + formatClient(defaultOptions, dependencies); } + + console.log('✨ Done! Your client is located in:', output); }; export default { - HttpClient, generate, }; diff --git a/src/openApi/v2/interfaces/OpenApi.d.ts b/src/openApi/v2/interfaces/OpenApi.d.ts index 1479c31ac..eea7f8660 100644 --- a/src/openApi/v2/interfaces/OpenApi.d.ts +++ b/src/openApi/v2/interfaces/OpenApi.d.ts @@ -13,19 +13,19 @@ import type { OpenApiTag } from './OpenApiTag'; * https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md */ export interface OpenApi { - swagger: string; - info: OpenApiInfo; - host?: string; basePath?: string; - schemes?: string[]; consumes?: string[]; - produces?: string[]; - paths: Dictionary; definitions?: Dictionary; + externalDocs?: OpenApiExternalDocs; + host?: string; + info: OpenApiInfo; parameters?: Dictionary; + paths: Dictionary; + produces?: string[]; responses?: Dictionary; - securityDefinitions?: Dictionary; + schemes?: string[]; security?: OpenApiSecurityRequirement[]; + securityDefinitions?: Dictionary; + swagger: string; tags?: OpenApiTag[]; - externalDocs?: OpenApiExternalDocs; } diff --git a/src/openApi/v2/interfaces/OpenApiExample.d.ts b/src/openApi/v2/interfaces/OpenApiExample.d.ts index 692752f5c..6af25277a 100644 --- a/src/openApi/v2/interfaces/OpenApiExample.d.ts +++ b/src/openApi/v2/interfaces/OpenApiExample.d.ts @@ -2,5 +2,5 @@ * https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#exampleObject */ export interface OpenApiExample { - [mimetype: string]: any; + [mimetype: string]: unknown; } diff --git a/src/openApi/v2/interfaces/OpenApiHeader.d.ts b/src/openApi/v2/interfaces/OpenApiHeader.d.ts index 81d2a74c9..42809f17b 100644 --- a/src/openApi/v2/interfaces/OpenApiHeader.d.ts +++ b/src/openApi/v2/interfaces/OpenApiHeader.d.ts @@ -21,7 +21,7 @@ export interface OpenApiHeader { | 'password'; items?: Dictionary; collectionFormat?: 'csv' | 'ssv' | 'tsv' | 'pipes'; - default?: any; + default?: unknown; maximum?: number; exclusiveMaximum?: boolean; minimum?: number; diff --git a/src/openApi/v2/interfaces/OpenApiItems.d.ts b/src/openApi/v2/interfaces/OpenApiItems.d.ts index 8f1a3be22..56940adb8 100644 --- a/src/openApi/v2/interfaces/OpenApiItems.d.ts +++ b/src/openApi/v2/interfaces/OpenApiItems.d.ts @@ -19,7 +19,7 @@ export interface OpenApiItems extends WithEnumExtension { | 'password'; items?: OpenApiItems; collectionFormat?: 'csv' | 'ssv' | 'tsv' | 'pipes'; - default?: any; + default?: unknown; maximum?: number; exclusiveMaximum?: number; minimum?: number; diff --git a/src/openApi/v2/interfaces/OpenApiParameter.d.ts b/src/openApi/v2/interfaces/OpenApiParameter.d.ts index 764055e0f..167df2c10 100644 --- a/src/openApi/v2/interfaces/OpenApiParameter.d.ts +++ b/src/openApi/v2/interfaces/OpenApiParameter.d.ts @@ -29,7 +29,7 @@ export interface OpenApiParameter extends OpenApiReference, WithEnumExtension, W allowEmptyValue?: boolean; items?: OpenApiItems; collectionFormat?: 'csv' | 'ssv' | 'tsv' | 'pipes' | 'multi'; - default?: any; + default?: number; maximum?: number; exclusiveMaximum?: boolean; minimum?: number; diff --git a/src/openApi/v2/interfaces/OpenApiSchema.d.ts b/src/openApi/v2/interfaces/OpenApiSchema.d.ts index 460de1864..b334ea9f6 100644 --- a/src/openApi/v2/interfaces/OpenApiSchema.d.ts +++ b/src/openApi/v2/interfaces/OpenApiSchema.d.ts @@ -11,7 +11,7 @@ import type { OpenApiXml } from './OpenApiXml'; export interface OpenApiSchema extends OpenApiReference, WithEnumExtension, WithNullableExtension { title?: string; description?: string; - default?: any; + default?: unknown; multipleOf?: number; maximum?: number; exclusiveMaximum?: boolean; @@ -48,5 +48,5 @@ export interface OpenApiSchema extends OpenApiReference, WithEnumExtension, With readOnly?: boolean; xml?: OpenApiXml; externalDocs?: OpenApiExternalDocs; - example?: any; + example?: unknown; } diff --git a/src/openApi/v2/parser/getMappedType.spec.ts b/src/openApi/v2/parser/getMappedType.spec.ts deleted file mode 100644 index 8dd847c91..000000000 --- a/src/openApi/v2/parser/getMappedType.spec.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { getMappedType } from './getMappedType'; - -describe('getMappedType', () => { - it('should map types to the basics', () => { - expect(getMappedType('file')).toEqual('binary'); - expect(getMappedType('string')).toEqual('string'); - expect(getMappedType('date')).toEqual('string'); - expect(getMappedType('date-time')).toEqual('string'); - expect(getMappedType('float')).toEqual('number'); - expect(getMappedType('double')).toEqual('number'); - expect(getMappedType('short')).toEqual('number'); - expect(getMappedType('int')).toEqual('number'); - expect(getMappedType('boolean')).toEqual('boolean'); - expect(getMappedType('any')).toEqual('any'); - expect(getMappedType('object')).toEqual('any'); - expect(getMappedType('void')).toEqual('void'); - expect(getMappedType('null')).toEqual('null'); - expect(getMappedType('unknown')).toEqual(undefined); - expect(getMappedType('')).toEqual(undefined); - }); -}); diff --git a/src/openApi/v2/parser/getMappedType.ts b/src/openApi/v2/parser/getMappedType.ts deleted file mode 100644 index a7c32fd84..000000000 --- a/src/openApi/v2/parser/getMappedType.ts +++ /dev/null @@ -1,32 +0,0 @@ -const TYPE_MAPPINGS = new Map([ - ['file', 'binary'], - ['any', 'any'], - ['object', 'any'], - ['array', 'any[]'], - ['boolean', 'boolean'], - ['byte', 'number'], - ['int', 'number'], - ['integer', 'number'], - ['float', 'number'], - ['double', 'number'], - ['short', 'number'], - ['long', 'number'], - ['number', 'number'], - ['char', 'string'], - ['date', 'string'], - ['date-time', 'string'], - ['password', 'string'], - ['string', 'string'], - ['void', 'void'], - ['null', 'null'], -]); - -/** - * Get mapped type for given type to any basic Typescript/Javascript type. - */ -export const getMappedType = (type: string, format?: string): string | undefined => { - if (format === 'binary') { - return 'binary'; - } - return TYPE_MAPPINGS.get(type); -}; diff --git a/src/openApi/v2/parser/getModel.ts b/src/openApi/v2/parser/getModel.ts index 4e798afc5..4a7c2d49c 100644 --- a/src/openApi/v2/parser/getModel.ts +++ b/src/openApi/v2/parser/getModel.ts @@ -1,11 +1,11 @@ import type { Model } from '../../../client/interfaces/Model'; import { getEnums } from '../../../utils/getEnums'; import { getPattern } from '../../../utils/getPattern'; +import { getType } from '../../../utils/type'; import type { OpenApi } from '../interfaces/OpenApi'; import type { OpenApiSchema } from '../interfaces/OpenApiSchema'; import { getModelComposition } from './getModelComposition'; import { getModelProperties } from './getModelProperties'; -import { getType } from './getType'; export const getModel = ( openApi: OpenApi, diff --git a/src/openApi/v2/parser/getModelProperties.ts b/src/openApi/v2/parser/getModelProperties.ts index 28c9f9691..0a7a53571 100644 --- a/src/openApi/v2/parser/getModelProperties.ts +++ b/src/openApi/v2/parser/getModelProperties.ts @@ -1,10 +1,10 @@ import type { Model } from '../../../client/interfaces/Model'; import { escapeName } from '../../../utils/escapeName'; import { getPattern } from '../../../utils/getPattern'; +import { getType } from '../../../utils/type'; import type { OpenApi } from '../interfaces/OpenApi'; import type { OpenApiSchema } from '../interfaces/OpenApiSchema'; import type { getModel } from './getModel'; -import { getType } from './getType'; // Fix for circular dependency export type GetModelFn = typeof getModel; diff --git a/src/openApi/v2/parser/getModelTemplate.ts b/src/openApi/v2/parser/getModelTemplate.ts index b2aa0b33a..492b3aca6 100644 --- a/src/openApi/v2/parser/getModelTemplate.ts +++ b/src/openApi/v2/parser/getModelTemplate.ts @@ -6,6 +6,4 @@ import type { Type } from '../../../client/interfaces/Type'; * @param modelClass The parsed model class type. * @returns The model template type ( or empty). */ -export const getModelTemplate = (modelClass: Type): string => { - return modelClass.template ? '' : ''; -}; +export const getModelTemplate = (modelClass: Type): string => (modelClass.template ? '' : ''); diff --git a/src/openApi/v2/parser/getModels.ts b/src/openApi/v2/parser/getModels.ts index 4ea4728cc..7d6613b76 100644 --- a/src/openApi/v2/parser/getModels.ts +++ b/src/openApi/v2/parser/getModels.ts @@ -1,8 +1,8 @@ import type { Model } from '../../../client/interfaces/Model'; import { reservedWords } from '../../../utils/reservedWords'; +import { getType } from '../../../utils/type'; import type { OpenApi } from '../interfaces/OpenApi'; import { getModel } from './getModel'; -import { getType } from './getType'; export const getModels = (openApi: OpenApi): Model[] => { const models: Model[] = []; diff --git a/src/openApi/v2/parser/getOperationErrors.ts b/src/openApi/v2/parser/getOperationErrors.ts index ef4c12e54..f963cf803 100644 --- a/src/openApi/v2/parser/getOperationErrors.ts +++ b/src/openApi/v2/parser/getOperationErrors.ts @@ -5,13 +5,10 @@ import type { OperationResponse } from '../../../client/interfaces/OperationResp * * @param operationResponses */ -export const getOperationErrors = (operationResponses: OperationResponse[]): OperationError[] => { - return operationResponses - .filter(operationResponse => { - return operationResponse.code >= 300 && operationResponse.description; - }) +export const getOperationErrors = (operationResponses: OperationResponse[]): OperationError[] => + operationResponses + .filter(operationResponse => operationResponse.code >= 300 && operationResponse.description) .map(response => ({ code: response.code, description: response.description!, })); -}; diff --git a/src/openApi/v2/parser/getOperationParameter.ts b/src/openApi/v2/parser/getOperationParameter.ts index a62a4615b..119b4d745 100644 --- a/src/openApi/v2/parser/getOperationParameter.ts +++ b/src/openApi/v2/parser/getOperationParameter.ts @@ -1,6 +1,7 @@ import type { OperationParameter } from '../../../client/interfaces/OperationParameter'; import { getEnums } from '../../../utils/getEnums'; import { getPattern } from '../../../utils/getPattern'; +import { getType } from '../../../utils/type'; import type { OpenApi } from '../interfaces/OpenApi'; import type { OpenApiParameter } from '../interfaces/OpenApiParameter'; import type { OpenApiSchema } from '../interfaces/OpenApiSchema'; @@ -8,7 +9,6 @@ import { getModel } from './getModel'; import { getOperationParameterDefault } from './getOperationParameterDefault'; import { getOperationParameterName } from './getOperationParameterName'; import { getRef } from './getRef'; -import { getType } from './getType'; export const getOperationParameter = (openApi: OpenApi, parameter: OpenApiParameter): OperationParameter => { const operationParameter: OperationParameter = { diff --git a/src/openApi/v2/parser/getOperationParameterDefault.ts b/src/openApi/v2/parser/getOperationParameterDefault.ts index cb1d6f26a..0677ab50d 100644 --- a/src/openApi/v2/parser/getOperationParameterDefault.ts +++ b/src/openApi/v2/parser/getOperationParameterDefault.ts @@ -23,7 +23,7 @@ export const getOperationParameterDefault = ( const { value } = operationParameter.enum[parameter.default]; return typeof value === 'string' ? `'${value}'` : String(value); } - return parameter.default; + return String(parameter.default); case 'boolean': return JSON.stringify(parameter.default); diff --git a/src/openApi/v2/parser/getOperationResponse.ts b/src/openApi/v2/parser/getOperationResponse.ts index b6967055d..d2c255373 100644 --- a/src/openApi/v2/parser/getOperationResponse.ts +++ b/src/openApi/v2/parser/getOperationResponse.ts @@ -1,11 +1,11 @@ import type { OperationResponse } from '../../../client/interfaces/OperationResponse'; import { getPattern } from '../../../utils/getPattern'; +import { getType } from '../../../utils/type'; import type { OpenApi } from '../interfaces/OpenApi'; import type { OpenApiResponse } from '../interfaces/OpenApiResponse'; import type { OpenApiSchema } from '../interfaces/OpenApiSchema'; import { getModel } from './getModel'; import { getRef } from './getRef'; -import { getType } from './getType'; export const getOperationResponse = ( openApi: OpenApi, diff --git a/src/openApi/v2/parser/getOperationResponseHeader.ts b/src/openApi/v2/parser/getOperationResponseHeader.ts index 09a810916..5424ab469 100644 --- a/src/openApi/v2/parser/getOperationResponseHeader.ts +++ b/src/openApi/v2/parser/getOperationResponseHeader.ts @@ -1,9 +1,7 @@ import type { OperationResponse } from '../../../client/interfaces/OperationResponse'; export const getOperationResponseHeader = (operationResponses: OperationResponse[]): string | null => { - const header = operationResponses.find(operationResponses => { - return operationResponses.in === 'header'; - }); + const header = operationResponses.find(operationResponses => operationResponses.in === 'header'); if (header) { return header.name; } diff --git a/src/openApi/v2/parser/getOperationResponses.ts b/src/openApi/v2/parser/getOperationResponses.ts index ed628e857..90bfc1410 100644 --- a/src/openApi/v2/parser/getOperationResponses.ts +++ b/src/openApi/v2/parser/getOperationResponses.ts @@ -10,7 +10,7 @@ export const getOperationResponses = (openApi: OpenApi, responses: OpenApiRespon const operationResponses: OperationResponse[] = []; // Iterate over each response code and get the - // status code and response message (if any). + // status code and response message for (const code in responses) { if (responses.hasOwnProperty(code)) { const responseOrReference = responses[code]; @@ -25,7 +25,5 @@ export const getOperationResponses = (openApi: OpenApi, responses: OpenApiRespon } // Sort the responses to 2XX success codes come before 4XX and 5XX error codes. - return operationResponses.sort((a, b): number => { - return a.code < b.code ? -1 : a.code > b.code ? 1 : 0; - }); + return operationResponses.sort((a, b): number => (a.code < b.code ? -1 : a.code > b.code ? 1 : 0)); }; diff --git a/src/openApi/v2/parser/getOperationResults.ts b/src/openApi/v2/parser/getOperationResults.ts index 997c2059c..00e1ccb17 100644 --- a/src/openApi/v2/parser/getOperationResults.ts +++ b/src/openApi/v2/parser/getOperationResults.ts @@ -20,11 +20,7 @@ export const getOperationResults = (operationResponses: OperationResponse[]): Op } }); - return operationResults.filter((operationResult, index, arr) => { - return ( - arr.findIndex(item => { - return areEqual(item, operationResult); - }) === index - ); - }); + return operationResults.filter( + (operationResult, index, arr) => arr.findIndex(item => areEqual(item, operationResult)) === index + ); }; diff --git a/src/openApi/v2/parser/getRef.ts b/src/openApi/v2/parser/getRef.ts index f92dfcf67..cab57f17f 100644 --- a/src/openApi/v2/parser/getRef.ts +++ b/src/openApi/v2/parser/getRef.ts @@ -15,12 +15,13 @@ export const getRef = (openApi: OpenApi, item: T & OpenApiReference): T => { // Try to find the reference by walking down the path, // if we cannot find it, then we throw an error. - let result: any = openApi; + let result = openApi; paths.forEach(path => { const decodedPath = decodeURIComponent( path.replace(ESCAPED_REF_SLASH, '/').replace(ESCAPED_REF_TILDE, '~') ); if (result.hasOwnProperty(decodedPath)) { + // @ts-ignore result = result[decodedPath]; } else { throw new Error(`Could not find reference: "${item.$ref}"`); diff --git a/src/openApi/v2/parser/getRequiredPropertiesFromComposition.ts b/src/openApi/v2/parser/getRequiredPropertiesFromComposition.ts index 0b1f1859f..682208b93 100644 --- a/src/openApi/v2/parser/getRequiredPropertiesFromComposition.ts +++ b/src/openApi/v2/parser/getRequiredPropertiesFromComposition.ts @@ -12,8 +12,8 @@ export const getRequiredPropertiesFromComposition = ( required: string[], definitions: OpenApiSchema[], getModel: GetModelFn -): Model[] => { - return definitions +): Model[] => + definitions .reduce((properties, definition) => { if (definition.$ref) { const schema = getRef(openApi, definition); @@ -21,13 +21,8 @@ export const getRequiredPropertiesFromComposition = ( } return [...properties, ...getModel(openApi, definition).properties]; }, [] as Model[]) - .filter(property => { - return !property.isRequired && required.includes(property.name); - }) - .map(property => { - return { - ...property, - isRequired: true, - }; - }); -}; + .filter(property => !property.isRequired && required.includes(property.name)) + .map(property => ({ + ...property, + isRequired: true, + })); diff --git a/src/openApi/v2/parser/getServiceVersion.ts b/src/openApi/v2/parser/getServiceVersion.ts index 9c7a8a04b..729a21530 100644 --- a/src/openApi/v2/parser/getServiceVersion.ts +++ b/src/openApi/v2/parser/getServiceVersion.ts @@ -3,6 +3,4 @@ * This basically removes any "v" prefix from the version string. * @param version */ -export const getServiceVersion = (version = '1.0'): string => { - return String(version).replace(/^v/gi, ''); -}; +export const getServiceVersion = (version = '1.0'): string => String(version).replace(/^v/gi, ''); diff --git a/src/openApi/v2/parser/getType.spec.ts b/src/openApi/v2/parser/getType.spec.ts deleted file mode 100644 index 575d2d46c..000000000 --- a/src/openApi/v2/parser/getType.spec.ts +++ /dev/null @@ -1,75 +0,0 @@ -import { getType } from './getType'; - -describe('getType', () => { - it('should convert int', () => { - const type = getType('int'); - expect(type.type).toEqual('number'); - expect(type.base).toEqual('number'); - expect(type.template).toEqual(null); - expect(type.imports).toEqual([]); - }); - - it('should convert string', () => { - const type = getType('string'); - expect(type.type).toEqual('string'); - expect(type.base).toEqual('string'); - expect(type.template).toEqual(null); - expect(type.imports).toEqual([]); - }); - - it('should convert string array', () => { - const type = getType('array[string]'); - expect(type.type).toEqual('string[]'); - expect(type.base).toEqual('string'); - expect(type.template).toEqual(null); - expect(type.imports).toEqual([]); - }); - - it('should convert template with primary', () => { - const type = getType('#/definitions/Link[string]'); - expect(type.type).toEqual('Link'); - expect(type.base).toEqual('Link'); - expect(type.template).toEqual('string'); - expect(type.imports).toEqual(['Link']); - }); - - it('should convert template with model', () => { - const type = getType('#/definitions/Link[Model]'); - expect(type.type).toEqual('Link'); - expect(type.base).toEqual('Link'); - expect(type.template).toEqual('Model'); - expect(type.imports).toEqual(['Link', 'Model']); - }); - - it('should have double imports', () => { - const type = getType('#/definitions/Link[Link]'); - expect(type.type).toEqual('Link'); - expect(type.base).toEqual('Link'); - expect(type.template).toEqual('Link'); - expect(type.imports).toEqual(['Link', 'Link']); - }); - - it('should support dot', () => { - const type = getType('#/definitions/model.000'); - expect(type.type).toEqual('model_000'); - expect(type.base).toEqual('model_000'); - expect(type.template).toEqual(null); - expect(type.imports).toEqual(['model_000']); - }); - - it('should support dashes', () => { - const type = getType('#/definitions/some_special-schema'); - expect(type.type).toEqual('some_special_schema'); - expect(type.base).toEqual('some_special_schema'); - expect(type.template).toEqual(null); - expect(type.imports).toEqual(['some_special_schema']); - }); - - it('should support dollar sign', () => { - const type = getType('#/definitions/$some+special+schema'); - expect(type.type).toEqual('$some_special_schema'); - expect(type.base).toEqual('$some_special_schema'); - expect(type.template).toEqual(null); - expect(type.imports).toEqual(['$some_special_schema']); - }); -}); diff --git a/src/openApi/v2/parser/getType.ts b/src/openApi/v2/parser/getType.ts deleted file mode 100644 index ae8ae4248..000000000 --- a/src/openApi/v2/parser/getType.ts +++ /dev/null @@ -1,67 +0,0 @@ -import type { Type } from '../../../client/interfaces/Type'; -import sanitizeTypeName from '../../../utils/sanitizeTypeName'; -import { getMappedType } from './getMappedType'; -import { stripNamespace } from './stripNamespace'; - -const encode = (value: string): string => sanitizeTypeName(value); - -/** - * Parse any string value into a type object. - * @param type String value like "integer" or "Link[Model]". - * @param format String value like "binary" or "date". - */ -export const getType = (type: string = 'any', format?: string): Type => { - const result: Type = { - $refs: [], - base: 'any', - imports: [], - isNullable: false, - template: null, - type: 'any', - }; - - const mapped = getMappedType(type, format); - if (mapped) { - result.type = mapped; - result.base = mapped; - return result; - } - - const typeWithoutNamespace = decodeURIComponent(stripNamespace(type)); - - if (/\[.*\]$/g.test(typeWithoutNamespace)) { - const matches = typeWithoutNamespace.match(/(.*?)\[(.*)\]$/); - if (matches?.length) { - const match1 = getType(encode(matches[1])); - const match2 = getType(encode(matches[2])); - - if (match1.type === 'any[]') { - result.type = `${match2.type}[]`; - result.base = match2.type; - match1.imports = []; - } else if (match2.type) { - result.type = `${match1.type}<${match2.type}>`; - result.base = match1.type; - result.template = match2.type; - } else { - result.type = match1.type; - result.base = match1.type; - result.template = match1.type; - } - - result.imports.push(...match1.imports); - result.imports.push(...match2.imports); - return result; - } - } - - if (typeWithoutNamespace) { - const type = encode(typeWithoutNamespace); - result.type = type; - result.base = type; - result.imports.push(type); - return result; - } - - return result; -}; diff --git a/src/openApi/v2/parser/stripNamespace.spec.ts b/src/openApi/v2/parser/stripNamespace.spec.ts deleted file mode 100644 index 103f08682..000000000 --- a/src/openApi/v2/parser/stripNamespace.spec.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { stripNamespace } from './stripNamespace'; - -describe('stripNamespace', () => { - it('should strip namespace', () => { - expect(stripNamespace('#/definitions/Item')).toEqual('Item'); - expect(stripNamespace('#/parameters/Item')).toEqual('Item'); - expect(stripNamespace('#/responses/Item')).toEqual('Item'); - expect(stripNamespace('#/securityDefinitions/Item')).toEqual('Item'); - }); -}); diff --git a/src/openApi/v2/parser/stripNamespace.ts b/src/openApi/v2/parser/stripNamespace.ts deleted file mode 100644 index ff543b3c9..000000000 --- a/src/openApi/v2/parser/stripNamespace.ts +++ /dev/null @@ -1,12 +0,0 @@ -/** - * Strip (OpenAPI) namespaces fom values. - * @param value - */ -export const stripNamespace = (value: string): string => { - return value - .trim() - .replace(/^#\/definitions\//, '') - .replace(/^#\/parameters\//, '') - .replace(/^#\/responses\//, '') - .replace(/^#\/securityDefinitions\//, ''); -}; diff --git a/src/openApi/v3/interfaces/OpenApiExample.d.ts b/src/openApi/v3/interfaces/OpenApiExample.d.ts index 228795790..89b05cea0 100644 --- a/src/openApi/v3/interfaces/OpenApiExample.d.ts +++ b/src/openApi/v3/interfaces/OpenApiExample.d.ts @@ -6,6 +6,6 @@ import type { OpenApiReference } from './OpenApiReference'; export interface OpenApiExample extends OpenApiReference { summary?: string; description?: string; - value?: any; + value?: unknown; externalValue?: string; } diff --git a/src/openApi/v3/interfaces/OpenApiHeader.d.ts b/src/openApi/v3/interfaces/OpenApiHeader.d.ts index 694c859ff..4bafccca5 100644 --- a/src/openApi/v3/interfaces/OpenApiHeader.d.ts +++ b/src/openApi/v3/interfaces/OpenApiHeader.d.ts @@ -15,6 +15,6 @@ export interface OpenApiHeader extends OpenApiReference { explode?: boolean; allowReserved?: boolean; schema?: OpenApiSchema; - example?: any; + example?: unknown; examples?: Dictionary; } diff --git a/src/openApi/v3/interfaces/OpenApiLink.d.ts b/src/openApi/v3/interfaces/OpenApiLink.d.ts index 31b9707ec..4b7708d3b 100644 --- a/src/openApi/v3/interfaces/OpenApiLink.d.ts +++ b/src/openApi/v3/interfaces/OpenApiLink.d.ts @@ -8,8 +8,8 @@ import type { OpenApiServer } from './OpenApiServer'; export interface OpenApiLink extends OpenApiReference { operationRef?: string; operationId?: string; - parameters?: Dictionary; - requestBody?: any; + parameters?: Dictionary; + requestBody?: unknown; description?: string; server?: OpenApiServer; } diff --git a/src/openApi/v3/interfaces/OpenApiMediaType.d.ts b/src/openApi/v3/interfaces/OpenApiMediaType.d.ts index 89f78c8ad..6bc1038c8 100644 --- a/src/openApi/v3/interfaces/OpenApiMediaType.d.ts +++ b/src/openApi/v3/interfaces/OpenApiMediaType.d.ts @@ -9,7 +9,7 @@ import type { OpenApiSchema } from './OpenApiSchema'; */ export interface OpenApiMediaType extends OpenApiReference { schema?: OpenApiSchema; - example?: any; + example?: unknown; examples?: Dictionary; encoding?: Dictionary; } diff --git a/src/openApi/v3/interfaces/OpenApiParameter.d.ts b/src/openApi/v3/interfaces/OpenApiParameter.d.ts index 7172feb7b..c1b61cdee 100644 --- a/src/openApi/v3/interfaces/OpenApiParameter.d.ts +++ b/src/openApi/v3/interfaces/OpenApiParameter.d.ts @@ -18,6 +18,6 @@ export interface OpenApiParameter extends OpenApiReference { explode?: boolean; allowReserved?: boolean; schema?: OpenApiSchema; - example?: any; + example?: unknown; examples?: Dictionary; } diff --git a/src/openApi/v3/interfaces/OpenApiSchema.d.ts b/src/openApi/v3/interfaces/OpenApiSchema.d.ts index c711e964a..426ff6dc8 100644 --- a/src/openApi/v3/interfaces/OpenApiSchema.d.ts +++ b/src/openApi/v3/interfaces/OpenApiSchema.d.ts @@ -13,12 +13,12 @@ export interface OpenApiSchema extends OpenApiReference, WithEnumExtension { allOf?: OpenApiSchema[]; anyOf?: OpenApiSchema[]; const?: string | number | boolean | null; - default?: any; + default?: number; deprecated?: boolean; description?: string; discriminator?: OpenApiDiscriminator; enum?: (string | number)[]; - example?: any; + example?: unknown; exclusiveMaximum?: boolean; exclusiveMinimum?: boolean; externalDocs?: OpenApiExternalDocs; diff --git a/src/openApi/v3/parser/getMappedType.spec.ts b/src/openApi/v3/parser/getMappedType.spec.ts deleted file mode 100644 index 8dd847c91..000000000 --- a/src/openApi/v3/parser/getMappedType.spec.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { getMappedType } from './getMappedType'; - -describe('getMappedType', () => { - it('should map types to the basics', () => { - expect(getMappedType('file')).toEqual('binary'); - expect(getMappedType('string')).toEqual('string'); - expect(getMappedType('date')).toEqual('string'); - expect(getMappedType('date-time')).toEqual('string'); - expect(getMappedType('float')).toEqual('number'); - expect(getMappedType('double')).toEqual('number'); - expect(getMappedType('short')).toEqual('number'); - expect(getMappedType('int')).toEqual('number'); - expect(getMappedType('boolean')).toEqual('boolean'); - expect(getMappedType('any')).toEqual('any'); - expect(getMappedType('object')).toEqual('any'); - expect(getMappedType('void')).toEqual('void'); - expect(getMappedType('null')).toEqual('null'); - expect(getMappedType('unknown')).toEqual(undefined); - expect(getMappedType('')).toEqual(undefined); - }); -}); diff --git a/src/openApi/v3/parser/getMappedType.ts b/src/openApi/v3/parser/getMappedType.ts deleted file mode 100644 index a7c32fd84..000000000 --- a/src/openApi/v3/parser/getMappedType.ts +++ /dev/null @@ -1,32 +0,0 @@ -const TYPE_MAPPINGS = new Map([ - ['file', 'binary'], - ['any', 'any'], - ['object', 'any'], - ['array', 'any[]'], - ['boolean', 'boolean'], - ['byte', 'number'], - ['int', 'number'], - ['integer', 'number'], - ['float', 'number'], - ['double', 'number'], - ['short', 'number'], - ['long', 'number'], - ['number', 'number'], - ['char', 'string'], - ['date', 'string'], - ['date-time', 'string'], - ['password', 'string'], - ['string', 'string'], - ['void', 'void'], - ['null', 'null'], -]); - -/** - * Get mapped type for given type to any basic Typescript/Javascript type. - */ -export const getMappedType = (type: string, format?: string): string | undefined => { - if (format === 'binary') { - return 'binary'; - } - return TYPE_MAPPINGS.get(type); -}; diff --git a/src/openApi/v3/parser/getModel.spec.ts b/src/openApi/v3/parser/getModel.spec.ts index efb720a40..4ebb5adb5 100644 --- a/src/openApi/v3/parser/getModel.spec.ts +++ b/src/openApi/v3/parser/getModel.spec.ts @@ -1,6 +1,6 @@ import { reservedWords } from '../../../utils/reservedWords'; +import { getType } from '../../../utils/type'; import { getModel } from './getModel'; -import { getType } from './getType'; const openApi = { openapi: '3.0', diff --git a/src/openApi/v3/parser/getModel.ts b/src/openApi/v3/parser/getModel.ts index 221a20cc9..348eed13f 100644 --- a/src/openApi/v3/parser/getModel.ts +++ b/src/openApi/v3/parser/getModel.ts @@ -1,12 +1,12 @@ import type { Model } from '../../../client/interfaces/Model'; import { getEnums } from '../../../utils/getEnums'; import { getPattern } from '../../../utils/getPattern'; +import { getType } from '../../../utils/type'; import type { OpenApi } from '../interfaces/OpenApi'; import type { OpenApiSchema } from '../interfaces/OpenApiSchema'; import { findModelComposition, getModelComposition } from './getModelComposition'; import { getModelDefault } from './getModelDefault'; import { getAdditionalPropertiesModel, getModelProperties } from './getModelProperties'; -import { getType } from './getType'; import { inferType } from './inferType'; export const getModel = ( @@ -19,7 +19,7 @@ export const getModel = ( const inferredType = inferType(definition); const model: Model = { $refs: [], - base: 'any', + base: 'unknown', deprecated: Boolean(definition.deprecated), description: definition.description || null, enum: [], @@ -47,7 +47,7 @@ export const getModel = ( pattern: getPattern(definition.pattern), properties: [], template: null, - type: 'any', + type: 'unknown', uniqueItems: definition.uniqueItems, }; diff --git a/src/openApi/v3/parser/getModelDefault.ts b/src/openApi/v3/parser/getModelDefault.ts index 0047dbca3..b8930f3a1 100644 --- a/src/openApi/v3/parser/getModelDefault.ts +++ b/src/openApi/v3/parser/getModelDefault.ts @@ -20,7 +20,7 @@ export const getModelDefault = (definition: OpenApiSchema, model?: Model): strin const { value } = model.enum[definition.default]; return typeof value === 'string' ? `'${value}'` : String(value); } - return definition.default; + return String(definition.default); case 'boolean': return JSON.stringify(definition.default); diff --git a/src/openApi/v3/parser/getModelProperties.ts b/src/openApi/v3/parser/getModelProperties.ts index 886c4fa82..fa2c940ac 100644 --- a/src/openApi/v3/parser/getModelProperties.ts +++ b/src/openApi/v3/parser/getModelProperties.ts @@ -2,11 +2,11 @@ import type { Model } from '../../../client/interfaces/Model'; import { findOneOfParentDiscriminator, mapPropertyValue } from '../../../utils/discriminator'; import { escapeName } from '../../../utils/escapeName'; import { getPattern } from '../../../utils/getPattern'; +import { getType } from '../../../utils/type'; import type { OpenApi } from '../interfaces/OpenApi'; import type { OpenApiSchema } from '../interfaces/OpenApiSchema'; import type { getModel } from './getModel'; import { getModelDefault } from './getModelDefault'; -import { getType } from './getType'; // Fix for circular dependency export type GetModelFn = typeof getModel; diff --git a/src/openApi/v3/parser/getModelTemplate.ts b/src/openApi/v3/parser/getModelTemplate.ts index b2aa0b33a..492b3aca6 100644 --- a/src/openApi/v3/parser/getModelTemplate.ts +++ b/src/openApi/v3/parser/getModelTemplate.ts @@ -6,6 +6,4 @@ import type { Type } from '../../../client/interfaces/Type'; * @param modelClass The parsed model class type. * @returns The model template type ( or empty). */ -export const getModelTemplate = (modelClass: Type): string => { - return modelClass.template ? '' : ''; -}; +export const getModelTemplate = (modelClass: Type): string => (modelClass.template ? '' : ''); diff --git a/src/openApi/v3/parser/getModels.ts b/src/openApi/v3/parser/getModels.ts index 6df7cf1e5..88596fa54 100644 --- a/src/openApi/v3/parser/getModels.ts +++ b/src/openApi/v3/parser/getModels.ts @@ -1,8 +1,8 @@ import type { Model } from '../../../client/interfaces/Model'; import { reservedWords } from '../../../utils/reservedWords'; +import { getType } from '../../../utils/type'; import type { OpenApi } from '../interfaces/OpenApi'; import { getModel } from './getModel'; -import { getType } from './getType'; export const getModels = (openApi: OpenApi): Model[] => { const models: Model[] = []; diff --git a/src/openApi/v3/parser/getOperationErrors.ts b/src/openApi/v3/parser/getOperationErrors.ts index e7624adb5..410547a89 100644 --- a/src/openApi/v3/parser/getOperationErrors.ts +++ b/src/openApi/v3/parser/getOperationErrors.ts @@ -1,13 +1,10 @@ import type { OperationError } from '../../../client/interfaces/OperationError'; import type { OperationResponse } from '../../../client/interfaces/OperationResponse'; -export const getOperationErrors = (operationResponses: OperationResponse[]): OperationError[] => { - return operationResponses - .filter(operationResponse => { - return operationResponse.code >= 300 && operationResponse.description; - }) +export const getOperationErrors = (operationResponses: OperationResponse[]): OperationError[] => + operationResponses + .filter(operationResponse => operationResponse.code >= 300 && operationResponse.description) .map(response => ({ code: response.code, description: response.description!, })); -}; diff --git a/src/openApi/v3/parser/getOperationParameter.ts b/src/openApi/v3/parser/getOperationParameter.ts index 7d81767e8..4d68d5f57 100644 --- a/src/openApi/v3/parser/getOperationParameter.ts +++ b/src/openApi/v3/parser/getOperationParameter.ts @@ -1,5 +1,6 @@ import type { OperationParameter } from '../../../client/interfaces/OperationParameter'; import { getPattern } from '../../../utils/getPattern'; +import { getType } from '../../../utils/type'; import type { OpenApi } from '../interfaces/OpenApi'; import type { OpenApiParameter } from '../interfaces/OpenApiParameter'; import type { OpenApiSchema } from '../interfaces/OpenApiSchema'; @@ -7,7 +8,6 @@ import { getModel } from './getModel'; import { getModelDefault } from './getModelDefault'; import { getOperationParameterName } from './getOperationParameterName'; import { getRef } from './getRef'; -import { getType } from './getType'; export const getOperationParameter = (openApi: OpenApi, parameter: OpenApiParameter): OperationParameter => { const operationParameter: OperationParameter = { diff --git a/src/openApi/v3/parser/getOperationRequestBody.ts b/src/openApi/v3/parser/getOperationRequestBody.ts index 2e81bc619..c392d9094 100644 --- a/src/openApi/v3/parser/getOperationRequestBody.ts +++ b/src/openApi/v3/parser/getOperationRequestBody.ts @@ -1,10 +1,10 @@ import type { OperationParameter } from '../../../client/interfaces/OperationParameter'; import { getPattern } from '../../../utils/getPattern'; +import { getType } from '../../../utils/type'; import type { OpenApi } from '../interfaces/OpenApi'; import type { OpenApiRequestBody } from '../interfaces/OpenApiRequestBody'; import { getContent } from './getContent'; import { getModel } from './getModel'; -import { getType } from './getType'; export const getOperationRequestBody = (openApi: OpenApi, body: OpenApiRequestBody): OperationParameter => { const requestBody: OperationParameter = { diff --git a/src/openApi/v3/parser/getOperationResponse.ts b/src/openApi/v3/parser/getOperationResponse.ts index 31ec9de50..08ea848ad 100644 --- a/src/openApi/v3/parser/getOperationResponse.ts +++ b/src/openApi/v3/parser/getOperationResponse.ts @@ -1,12 +1,12 @@ import type { OperationResponse } from '../../../client/interfaces/OperationResponse'; import { getPattern } from '../../../utils/getPattern'; +import { getType } from '../../../utils/type'; import type { OpenApi } from '../interfaces/OpenApi'; import type { OpenApiResponse } from '../interfaces/OpenApiResponse'; import type { OpenApiSchema } from '../interfaces/OpenApiSchema'; import { getContent } from './getContent'; import { getModel } from './getModel'; import { getRef } from './getRef'; -import { getType } from './getType'; export const getOperationResponse = ( openApi: OpenApi, diff --git a/src/openApi/v3/parser/getOperationResponseHeader.ts b/src/openApi/v3/parser/getOperationResponseHeader.ts index 09a810916..5424ab469 100644 --- a/src/openApi/v3/parser/getOperationResponseHeader.ts +++ b/src/openApi/v3/parser/getOperationResponseHeader.ts @@ -1,9 +1,7 @@ import type { OperationResponse } from '../../../client/interfaces/OperationResponse'; export const getOperationResponseHeader = (operationResponses: OperationResponse[]): string | null => { - const header = operationResponses.find(operationResponses => { - return operationResponses.in === 'header'; - }); + const header = operationResponses.find(operationResponses => operationResponses.in === 'header'); if (header) { return header.name; } diff --git a/src/openApi/v3/parser/getOperationResponses.ts b/src/openApi/v3/parser/getOperationResponses.ts index ed628e857..90bfc1410 100644 --- a/src/openApi/v3/parser/getOperationResponses.ts +++ b/src/openApi/v3/parser/getOperationResponses.ts @@ -10,7 +10,7 @@ export const getOperationResponses = (openApi: OpenApi, responses: OpenApiRespon const operationResponses: OperationResponse[] = []; // Iterate over each response code and get the - // status code and response message (if any). + // status code and response message for (const code in responses) { if (responses.hasOwnProperty(code)) { const responseOrReference = responses[code]; @@ -25,7 +25,5 @@ export const getOperationResponses = (openApi: OpenApi, responses: OpenApiRespon } // Sort the responses to 2XX success codes come before 4XX and 5XX error codes. - return operationResponses.sort((a, b): number => { - return a.code < b.code ? -1 : a.code > b.code ? 1 : 0; - }); + return operationResponses.sort((a, b): number => (a.code < b.code ? -1 : a.code > b.code ? 1 : 0)); }; diff --git a/src/openApi/v3/parser/getOperationResults.ts b/src/openApi/v3/parser/getOperationResults.ts index 997c2059c..00e1ccb17 100644 --- a/src/openApi/v3/parser/getOperationResults.ts +++ b/src/openApi/v3/parser/getOperationResults.ts @@ -20,11 +20,7 @@ export const getOperationResults = (operationResponses: OperationResponse[]): Op } }); - return operationResults.filter((operationResult, index, arr) => { - return ( - arr.findIndex(item => { - return areEqual(item, operationResult); - }) === index - ); - }); + return operationResults.filter( + (operationResult, index, arr) => arr.findIndex(item => areEqual(item, operationResult)) === index + ); }; diff --git a/src/openApi/v3/parser/getRef.ts b/src/openApi/v3/parser/getRef.ts index 2c42690ee..896212d3a 100644 --- a/src/openApi/v3/parser/getRef.ts +++ b/src/openApi/v3/parser/getRef.ts @@ -15,12 +15,13 @@ export const getRef = (openApi: OpenApi, item: T & OpenApiReference): T => { // Try to find the reference by walking down the path, // if we cannot find it, then we throw an error. - let result: any = openApi; + let result = openApi; paths.forEach(path => { const decodedPath = decodeURIComponent( path.replace(ESCAPED_REF_SLASH, '/').replace(ESCAPED_REF_TILDE, '~') ); if (result.hasOwnProperty(decodedPath)) { + // @ts-ignore result = result[decodedPath]; } else { throw new Error(`Could not find reference: "${item.$ref}"`); diff --git a/src/openApi/v3/parser/getRequiredPropertiesFromComposition.ts b/src/openApi/v3/parser/getRequiredPropertiesFromComposition.ts index 0b1f1859f..682208b93 100644 --- a/src/openApi/v3/parser/getRequiredPropertiesFromComposition.ts +++ b/src/openApi/v3/parser/getRequiredPropertiesFromComposition.ts @@ -12,8 +12,8 @@ export const getRequiredPropertiesFromComposition = ( required: string[], definitions: OpenApiSchema[], getModel: GetModelFn -): Model[] => { - return definitions +): Model[] => + definitions .reduce((properties, definition) => { if (definition.$ref) { const schema = getRef(openApi, definition); @@ -21,13 +21,8 @@ export const getRequiredPropertiesFromComposition = ( } return [...properties, ...getModel(openApi, definition).properties]; }, [] as Model[]) - .filter(property => { - return !property.isRequired && required.includes(property.name); - }) - .map(property => { - return { - ...property, - isRequired: true, - }; - }); -}; + .filter(property => !property.isRequired && required.includes(property.name)) + .map(property => ({ + ...property, + isRequired: true, + })); diff --git a/src/openApi/v3/parser/service.ts b/src/openApi/v3/parser/service.ts index 2c56b50b9..e10a52420 100644 --- a/src/openApi/v3/parser/service.ts +++ b/src/openApi/v3/parser/service.ts @@ -18,6 +18,4 @@ export const getServiceName = (value: string): string => { * This basically removes any "v" prefix from the version string. * @param version */ -export const getServiceVersion = (version = '1.0'): string => { - return String(version).replace(/^v/gi, ''); -}; +export const getServiceVersion = (version = '1.0'): string => String(version).replace(/^v/gi, ''); diff --git a/src/templates/__mocks__/index.ts b/src/templates/__mocks__/index.ts index 7f78e06f9..dd5bf7cf1 100644 --- a/src/templates/__mocks__/index.ts +++ b/src/templates/__mocks__/index.ts @@ -1,7 +1,5 @@ export default { compiler: [8, '>= 4.3.0'], useData: true, - main: () => { - return ''; - }, + main: () => '', }; diff --git a/src/templates/client.hbs b/src/templates/client.hbs index 13975f348..7082b3e67 100644 --- a/src/templates/client.hbs +++ b/src/templates/client.hbs @@ -1,4 +1,4 @@ -{{#equals @root.$config.httpClient 'angular'}} +{{#equals @root.$config.client 'angular'}} import { NgModule} from '@angular/core'; import { HttpClientModule } from '@angular/common/http'; @@ -18,7 +18,7 @@ import { {{{name}}}{{{@root.$config.postfixServices}}} } from './services/{{{nam {{/each}} {{/if}} -{{#equals @root.$config.httpClient 'angular'}} +{{#equals @root.$config.client 'angular'}} @NgModule({ imports: [HttpClientModule], providers: [ diff --git a/src/templates/core/ApiError.hbs b/src/templates/core/ApiError.hbs index fbeb5134b..9cf094969 100644 --- a/src/templates/core/ApiError.hbs +++ b/src/templates/core/ApiError.hbs @@ -5,7 +5,7 @@ export class ApiError extends Error { public readonly url: string; public readonly status: number; public readonly statusText: string; - public readonly body: any; + public readonly body: unknown; public readonly request: ApiRequestOptions; constructor(request: ApiRequestOptions, response: ApiResult, message: string) { diff --git a/src/templates/core/ApiRequestOptions.hbs b/src/templates/core/ApiRequestOptions.hbs index 82a5116e3..00a93cc87 100644 --- a/src/templates/core/ApiRequestOptions.hbs +++ b/src/templates/core/ApiRequestOptions.hbs @@ -1,11 +1,11 @@ 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 path?: Record; + readonly cookies?: Record; + readonly headers?: Record; + readonly query?: Record; + readonly formData?: Record; readonly body?: any; readonly mediaType?: string; readonly responseHeader?: string; diff --git a/src/templates/core/BaseHttpRequest.hbs b/src/templates/core/BaseHttpRequest.hbs index 90c974ae6..80625e6ec 100644 --- a/src/templates/core/BaseHttpRequest.hbs +++ b/src/templates/core/BaseHttpRequest.hbs @@ -1,4 +1,4 @@ -{{#equals @root.$config.httpClient 'angular'}} +{{#equals @root.$config.client 'angular'}} import type { HttpClient } from '@angular/common/http'; import type { Observable } from 'rxjs'; @@ -12,7 +12,7 @@ import type { OpenAPIConfig } from './OpenAPI'; export abstract class BaseHttpRequest { - {{#equals @root.$config.httpClient 'angular'}} + {{#equals @root.$config.client 'angular'}} constructor( public readonly config: OpenAPIConfig, public readonly http: HttpClient, @@ -21,7 +21,7 @@ export abstract class BaseHttpRequest { constructor(public readonly config: OpenAPIConfig) {} {{/equals}} - {{#equals @root.$config.httpClient 'angular'}} + {{#equals @root.$config.client 'angular'}} public abstract request(options: ApiRequestOptions): Observable; {{else}} public abstract request(options: ApiRequestOptions): CancelablePromise; diff --git a/src/templates/core/CancelablePromise.hbs b/src/templates/core/CancelablePromise.hbs index ed2a1a067..7d72441fd 100644 --- a/src/templates/core/CancelablePromise.hbs +++ b/src/templates/core/CancelablePromise.hbs @@ -25,12 +25,12 @@ export class CancelablePromise implements Promise { readonly #cancelHandlers: (() => void)[]; readonly #promise: Promise; #resolve?: (value: T | PromiseLike) => void; - #reject?: (reason?: any) => void; + #reject?: (reason?: unknown) => void; constructor( executor: ( resolve: (value: T | PromiseLike) => void, - reject: (reason?: any) => void, + reject: (reason?: unknown) => void, onCancel: OnCancel ) => void ) { @@ -50,7 +50,7 @@ export class CancelablePromise implements Promise { if (this.#resolve) this.#resolve(value); }; - const onReject = (reason?: any): void => { + const onReject = (reason?: unknown): void => { if (this.#isResolved || this.#isRejected || this.#isCancelled) { return; } @@ -87,13 +87,13 @@ export class CancelablePromise implements Promise { public then( onFulfilled?: ((value: T) => TResult1 | PromiseLike) | null, - onRejected?: ((reason: any) => TResult2 | PromiseLike) | null + onRejected?: ((reason: unknown) => TResult2 | PromiseLike) | null ): Promise { return this.#promise.then(onFulfilled, onRejected); } public catch( - onRejected?: ((reason: any) => TResult | PromiseLike) | null + onRejected?: ((reason: unknown) => TResult | PromiseLike) | null ): Promise { return this.#promise.catch(onRejected); } diff --git a/src/templates/core/HttpRequest.hbs b/src/templates/core/HttpRequest.hbs index 482c43ae9..aa400e86c 100644 --- a/src/templates/core/HttpRequest.hbs +++ b/src/templates/core/HttpRequest.hbs @@ -1,4 +1,4 @@ -{{#equals @root.$config.httpClient 'angular'}} +{{#equals @root.$config.client 'angular'}} import { Inject, Injectable } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import type { Observable } from 'rxjs'; @@ -16,12 +16,12 @@ import type { OpenAPIConfig } from './OpenAPI'; import { request as __request } from './request'; {{/equals}} -{{#equals @root.$config.httpClient 'angular'}} +{{#equals @root.$config.client 'angular'}} @Injectable() {{/equals}} export class {{httpRequest}} extends BaseHttpRequest { - {{#equals @root.$config.httpClient 'angular'}} + {{#equals @root.$config.client 'angular'}} constructor( @Inject(OpenAPI) config: OpenAPIConfig, @@ -35,7 +35,7 @@ export class {{httpRequest}} extends BaseHttpRequest { } {{/equals}} - {{#equals @root.$config.httpClient 'angular'}} + {{#equals @root.$config.client 'angular'}} /** * Request method * @param options The request options from the service diff --git a/src/templates/core/angular/getRequestBody.hbs b/src/templates/core/angular/getRequestBody.hbs index 891150edf..4ef908685 100644 --- a/src/templates/core/angular/getRequestBody.hbs +++ b/src/templates/core/angular/getRequestBody.hbs @@ -1,4 +1,4 @@ -export const getRequestBody = (options: ApiRequestOptions): any => { +export const getRequestBody = (options: ApiRequestOptions): unknown => { if (options.body) { if (options.mediaType?.includes('/json')) { return JSON.stringify(options.body) diff --git a/src/templates/core/angular/sendRequest.hbs b/src/templates/core/angular/sendRequest.hbs index ad73d8332..9411e330b 100644 --- a/src/templates/core/angular/sendRequest.hbs +++ b/src/templates/core/angular/sendRequest.hbs @@ -3,7 +3,7 @@ export const sendRequest = ( options: ApiRequestOptions, http: HttpClient, url: string, - body: any, + body: unknown, formData: FormData | undefined, headers: HttpHeaders ): Observable> => { diff --git a/src/templates/core/axios/getRequestBody.hbs b/src/templates/core/axios/getRequestBody.hbs index b61b468e1..1699e7b68 100644 --- a/src/templates/core/axios/getRequestBody.hbs +++ b/src/templates/core/axios/getRequestBody.hbs @@ -1,4 +1,4 @@ -export const getRequestBody = (options: ApiRequestOptions): any => { +export const getRequestBody = (options: ApiRequestOptions): unknown => { if (options.body) { return options.body; } diff --git a/src/templates/core/axios/getResponseBody.hbs b/src/templates/core/axios/getResponseBody.hbs index c73057c3c..5878045d0 100644 --- a/src/templates/core/axios/getResponseBody.hbs +++ b/src/templates/core/axios/getResponseBody.hbs @@ -1,4 +1,4 @@ -export const getResponseBody = (response: AxiosResponse): any => { +export const getResponseBody = (response: AxiosResponse): unknown => { if (response.status !== 204) { return response.data; } diff --git a/src/templates/core/axios/getResponseHeader.hbs b/src/templates/core/axios/getResponseHeader.hbs index 6a28e2f16..f191da9f3 100644 --- a/src/templates/core/axios/getResponseHeader.hbs +++ b/src/templates/core/axios/getResponseHeader.hbs @@ -1,4 +1,4 @@ -export const getResponseHeader = (response: AxiosResponse, responseHeader?: string): string | undefined => { +export const getResponseHeader = (response: AxiosResponse, responseHeader?: string): string | undefined => { if (responseHeader) { const content = response.headers[responseHeader]; if (isString(content)) { diff --git a/src/templates/core/axios/sendRequest.hbs b/src/templates/core/axios/sendRequest.hbs index 51492bf3f..32cf789c7 100644 --- a/src/templates/core/axios/sendRequest.hbs +++ b/src/templates/core/axios/sendRequest.hbs @@ -2,7 +2,7 @@ export const sendRequest = async ( config: OpenAPIConfig, options: ApiRequestOptions, url: string, - body: any, + body: unknown, formData: FormData | undefined, headers: Record, onCancel: OnCancel, diff --git a/src/templates/core/fetch/getRequestBody.hbs b/src/templates/core/fetch/getRequestBody.hbs index a82b2719d..a916e70db 100644 --- a/src/templates/core/fetch/getRequestBody.hbs +++ b/src/templates/core/fetch/getRequestBody.hbs @@ -1,4 +1,4 @@ -export const getRequestBody = (options: ApiRequestOptions): any => { +export const getRequestBody = (options: ApiRequestOptions): unknown => { if (options.body !== undefined) { if (options.mediaType?.includes('/json')) { return JSON.stringify(options.body) diff --git a/src/templates/core/fetch/getResponseBody.hbs b/src/templates/core/fetch/getResponseBody.hbs index 9c3d4bbd8..523a1ae3c 100644 --- a/src/templates/core/fetch/getResponseBody.hbs +++ b/src/templates/core/fetch/getResponseBody.hbs @@ -1,4 +1,4 @@ -export const getResponseBody = async (response: Response): Promise => { +export const getResponseBody = async (response: Response): Promise => { if (response.status !== 204) { try { const contentType = response.headers.get('Content-Type'); diff --git a/src/templates/core/functions/getQueryString.hbs b/src/templates/core/functions/getQueryString.hbs index 5a79d2d03..0f17d43ac 100644 --- a/src/templates/core/functions/getQueryString.hbs +++ b/src/templates/core/functions/getQueryString.hbs @@ -1,11 +1,11 @@ -export const getQueryString = (params: Record): string => { +export const getQueryString = (params: Record): string => { const qs: string[] = []; - const append = (key: string, value: any) => { + const append = (key: string, value: unknown) => { qs.push(`${encodeURIComponent(key)}=${encodeURIComponent(String(value))}`); }; - const process = (key: string, value: any) => { + const process = (key: string, value: unknown) => { if (value) { if (Array.isArray(value)) { value.forEach(v => { diff --git a/src/templates/core/functions/isBlob.hbs b/src/templates/core/functions/isBlob.hbs index d75c5b515..90233b580 100644 --- a/src/templates/core/functions/isBlob.hbs +++ b/src/templates/core/functions/isBlob.hbs @@ -1,5 +1,6 @@ export const isBlob = (value: any): value is Blob => { return ( + value !== null && typeof value === 'object' && typeof value.type === 'string' && typeof value.stream === 'function' && @@ -7,6 +8,7 @@ export const isBlob = (value: any): value is Blob => { typeof value.constructor === 'function' && typeof value.constructor.name === 'string' && /^(Blob|File)$/.test(value.constructor.name) && + // @ts-ignore /^(Blob|File)$/.test(value[Symbol.toStringTag]) ); }; diff --git a/src/templates/core/functions/isFormData.hbs b/src/templates/core/functions/isFormData.hbs index 98ec89ed5..3c8649575 100644 --- a/src/templates/core/functions/isFormData.hbs +++ b/src/templates/core/functions/isFormData.hbs @@ -1,3 +1,3 @@ -export const isFormData = (value: any): value is FormData => { +export const isFormData = (value: unknown): value is FormData => { return value instanceof FormData; }; diff --git a/src/templates/core/functions/isString.hbs b/src/templates/core/functions/isString.hbs index 71e1586af..1b70a8a7f 100644 --- a/src/templates/core/functions/isString.hbs +++ b/src/templates/core/functions/isString.hbs @@ -1,3 +1,3 @@ -export const isString = (value: any): value is string => { +export const isString = (value: unknown): value is string => { return typeof value === 'string'; }; diff --git a/src/templates/core/functions/isStringWithValue.hbs b/src/templates/core/functions/isStringWithValue.hbs index f5bd03a26..6e69d331c 100644 --- a/src/templates/core/functions/isStringWithValue.hbs +++ b/src/templates/core/functions/isStringWithValue.hbs @@ -1,3 +1,3 @@ -export const isStringWithValue = (value: any): value is string => { +export const isStringWithValue = (value: unknown): value is string => { return isString(value) && value !== ''; }; diff --git a/src/templates/core/node/getRequestBody.hbs b/src/templates/core/node/getRequestBody.hbs index a60421623..71a352a8f 100644 --- a/src/templates/core/node/getRequestBody.hbs +++ b/src/templates/core/node/getRequestBody.hbs @@ -1,9 +1,9 @@ -export const getRequestBody = (options: ApiRequestOptions): any => { +export const getRequestBody = (options: ApiRequestOptions): unknown => { if (options.body !== undefined) { if (options.mediaType?.includes('/json')) { return JSON.stringify(options.body) } else if (isString(options.body) || isBlob(options.body) || isFormData(options.body)) { - return options.body as any; + return options.body as unknown; } else { return JSON.stringify(options.body); } diff --git a/src/templates/core/node/getResponseBody.hbs b/src/templates/core/node/getResponseBody.hbs index b0fee2fc0..e0279c72d 100644 --- a/src/templates/core/node/getResponseBody.hbs +++ b/src/templates/core/node/getResponseBody.hbs @@ -1,4 +1,4 @@ -export const getResponseBody = async (response: Response): Promise => { +export const getResponseBody = async (response: Response): Promise => { if (response.status !== 204) { try { const contentType = response.headers.get('Content-Type'); diff --git a/src/templates/core/request.hbs b/src/templates/core/request.hbs index d6c3e6f5d..593798075 100644 --- a/src/templates/core/request.hbs +++ b/src/templates/core/request.hbs @@ -1,5 +1,5 @@ -{{~#equals @root.$config.httpClient 'angular'}}{{>angular/request}}{{/equals~}} -{{~#equals @root.$config.httpClient 'axios'}}{{>axios/request}}{{/equals~}} -{{~#equals @root.$config.httpClient 'fetch'}}{{>fetch/request}}{{/equals~}} -{{~#equals @root.$config.httpClient 'node'}}{{>node/request}}{{/equals~}} -{{~#equals @root.$config.httpClient 'xhr'}}{{>xhr/request}}{{/equals~}} +{{~#equals @root.$config.client 'angular'}}{{>angular/request}}{{/equals~}} +{{~#equals @root.$config.client 'axios'}}{{>axios/request}}{{/equals~}} +{{~#equals @root.$config.client 'fetch'}}{{>fetch/request}}{{/equals~}} +{{~#equals @root.$config.client 'node'}}{{>node/request}}{{/equals~}} +{{~#equals @root.$config.client 'xhr'}}{{>xhr/request}}{{/equals~}} diff --git a/src/templates/core/xhr/getRequestBody.hbs b/src/templates/core/xhr/getRequestBody.hbs index a82b2719d..a916e70db 100644 --- a/src/templates/core/xhr/getRequestBody.hbs +++ b/src/templates/core/xhr/getRequestBody.hbs @@ -1,4 +1,4 @@ -export const getRequestBody = (options: ApiRequestOptions): any => { +export const getRequestBody = (options: ApiRequestOptions): unknown => { if (options.body !== undefined) { if (options.mediaType?.includes('/json')) { return JSON.stringify(options.body) diff --git a/src/templates/core/xhr/getResponseBody.hbs b/src/templates/core/xhr/getResponseBody.hbs index 4b7398d7a..c7817fe18 100644 --- a/src/templates/core/xhr/getResponseBody.hbs +++ b/src/templates/core/xhr/getResponseBody.hbs @@ -1,4 +1,4 @@ -export const getResponseBody = (xhr: XMLHttpRequest): any => { +export const getResponseBody = (xhr: XMLHttpRequest): unknown => { if (xhr.status !== 204) { try { const contentType = xhr.getResponseHeader('Content-Type'); diff --git a/src/templates/exportService.hbs b/src/templates/exportService.hbs index 578c31d14..18b2e7b0c 100644 --- a/src/templates/exportService.hbs +++ b/src/templates/exportService.hbs @@ -1,4 +1,4 @@ -{{#equals @root.$config.httpClient 'angular'}} +{{#equals @root.$config.client 'angular'}} {{#if @root.$config.clientName}} import { Injectable } from '@angular/core'; import type { Observable } from 'rxjs'; @@ -12,11 +12,11 @@ import type { Observable } from 'rxjs'; {{#equals @root.$config.serviceResponse 'response'}} import type { ApiResult } from '../core/ApiResult'; {{/equals}} -{{#notEquals @root.$config.httpClient 'angular'}} +{{#notEquals @root.$config.client 'angular'}} import type { CancelablePromise } from '../core/CancelablePromise'; {{/notEquals}} {{#if @root.$config.clientName}} -{{#equals @root.$config.httpClient 'angular'}} +{{#equals @root.$config.client 'angular'}} import { BaseHttpRequest } from '../core/BaseHttpRequest'; {{else}} import type { BaseHttpRequest } from '../core/BaseHttpRequest'; @@ -54,7 +54,7 @@ export type {{{nameOperationDataType name}}} = { {{/each}} {{/if}} -{{#equals @root.$config.httpClient 'angular'}} +{{#equals @root.$config.client 'angular'}} @Injectable({ providedIn: 'root', }) @@ -64,7 +64,7 @@ export class {{{name}}}{{{@root.$config.postfixServices}}} { constructor(public readonly httpRequest: BaseHttpRequest) {} {{else}} - {{#equals @root.$config.httpClient 'angular'}} + {{#equals @root.$config.client 'angular'}} constructor(public readonly http: HttpClient) {} {{/equals}} @@ -94,7 +94,7 @@ export class {{{name}}}{{{@root.$config.postfixServices}}} { * @throws ApiError */ {{#if @root.$config.clientName}} - {{#equals @root.$config.httpClient 'angular'}} + {{#equals @root.$config.client 'angular'}} public {{{name}}}{{>operationTypes}}({{>operationParameters}}): Observable<{{>operationResult}}> { {{>dataDestructure}} return this.httpRequest.request({ @@ -104,7 +104,7 @@ export class {{{name}}}{{{@root.$config.postfixServices}}} { return this.httpRequest.request({ {{/equals}} {{else}} - {{#equals @root.$config.httpClient 'angular'}} + {{#equals @root.$config.client 'angular'}} public {{{name}}}{{>operationTypes}}({{>operationParameters}}): Observable<{{>operationResult}}> { {{>dataDestructure}} return __request({{>requestConfig}}, this.http, { diff --git a/src/templates/partials/base.hbs b/src/templates/partials/base.hbs index 5aa025a22..5afa5801c 100644 --- a/src/templates/partials/base.hbs +++ b/src/templates/partials/base.hbs @@ -1,9 +1,9 @@ {{~#equals base 'binary'~}} -{{~#equals @root.$config.httpClient 'fetch'}}Blob{{/equals~}} -{{~#equals @root.$config.httpClient 'xhr'}}Blob{{/equals~}} -{{~#equals @root.$config.httpClient 'axios'}}Blob{{/equals~}} -{{~#equals @root.$config.httpClient 'angular'}}Blob{{/equals~}} -{{~#equals @root.$config.httpClient 'node'}}Blob{{/equals~}} +{{~#equals @root.$config.client 'fetch'}}Blob{{/equals~}} +{{~#equals @root.$config.client 'xhr'}}Blob{{/equals~}} +{{~#equals @root.$config.client 'axios'}}Blob{{/equals~}} +{{~#equals @root.$config.client 'angular'}}Blob{{/equals~}} +{{~#equals @root.$config.client 'node'}}Blob{{/equals~}} {{~else~}} {{~#useDateType @root.$config format~}} Date diff --git a/src/templates/partials/schemaInterface.hbs b/src/templates/partials/schemaInterface.hbs index 3417c5fb9..d5a7def82 100644 --- a/src/templates/partials/schemaInterface.hbs +++ b/src/templates/partials/schemaInterface.hbs @@ -5,7 +5,9 @@ properties: { {{#if properties}} {{#each properties}} + {{#notEquals name "[key: string]"}} {{{name}}}: {{>schema}}, + {{/notEquals}} {{/each}} {{/if}} }, diff --git a/src/templates/partials/typeInterface.hbs b/src/templates/partials/typeInterface.hbs index 3d5acad07..c5da49b90 100644 --- a/src/templates/partials/typeInterface.hbs +++ b/src/templates/partials/typeInterface.hbs @@ -19,5 +19,5 @@ {{/each}} }{{>isNullable}} {{~else~}} -any +unknown {{~/if~}} diff --git a/src/utils/__tests__/getOpenApiSpecParser.spec.ts b/src/utils/__tests__/getOpenApiSpecParser.spec.ts deleted file mode 100644 index 702ebfd4f..000000000 --- a/src/utils/__tests__/getOpenApiSpecParser.spec.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { getOpenApiSpecParser } from '../getOpenApiSpecParser'; - -jest.mock('../../openApi/v2', () => ({ - parse: 'parseV2', -})); -jest.mock('../../openApi/v3', () => ({ - parse: 'parseV3', -})); - -describe('getOpenApiSpecParser', () => { - it('returns v2 parser', () => { - expect(getOpenApiSpecParser({ openapi: '2' })).toEqual('parseV2'); - expect(getOpenApiSpecParser({ openapi: '2.0' })).toEqual('parseV2'); - - expect(getOpenApiSpecParser({ swagger: '2' })).toEqual('parseV2'); - expect(getOpenApiSpecParser({ swagger: '2.0' })).toEqual('parseV2'); - }); - - it('returns v3 parser', () => { - expect(getOpenApiSpecParser({ openapi: '3' })).toEqual('parseV3'); - expect(getOpenApiSpecParser({ openapi: '3.0' })).toEqual('parseV3'); - expect(getOpenApiSpecParser({ openapi: '3.1.0' })).toEqual('parseV3'); - - expect(getOpenApiSpecParser({ swagger: '3' })).toEqual('parseV3'); - expect(getOpenApiSpecParser({ swagger: '3.0' })).toEqual('parseV3'); - expect(getOpenApiSpecParser({ swagger: '3.1.0' })).toEqual('parseV3'); - }); - - it('throws on unknown version', () => { - expect(() => getOpenApiSpecParser({})).toThrow('Unsupported Open API version: "undefined"'); - expect(() => getOpenApiSpecParser({ swagger: '4.0' })).toThrow('Unsupported Open API version: "4.0"'); - }); -}); diff --git a/src/utils/__tests__/registerHandlebarHelpers.spec.ts b/src/utils/__tests__/registerHandlebarHelpers.spec.ts index bc9d8de0a..80081c839 100644 --- a/src/utils/__tests__/registerHandlebarHelpers.spec.ts +++ b/src/utils/__tests__/registerHandlebarHelpers.spec.ts @@ -1,6 +1,5 @@ import Handlebars from 'handlebars/runtime'; -import { HttpClient } from '../../HttpClient'; import { registerHandlebarHelpers } from '../registerHandlebarHelpers'; describe('registerHandlebarHelpers', () => { @@ -16,12 +15,12 @@ describe('registerHandlebarHelpers', () => { }, { autoformat: true, + client: 'fetch', enums: true, exportCore: true, exportModels: true, exportSchemas: true, exportServices: true, - httpClient: HttpClient.FETCH, input: '', operationId: true, output: '', diff --git a/src/openApi/v3/parser/stripNamespace.spec.ts b/src/utils/__tests__/stripNamespace.spec.ts similarity index 70% rename from src/openApi/v3/parser/stripNamespace.spec.ts rename to src/utils/__tests__/stripNamespace.spec.ts index 5b3cc4a16..e362afe7a 100644 --- a/src/openApi/v3/parser/stripNamespace.spec.ts +++ b/src/utils/__tests__/stripNamespace.spec.ts @@ -1,7 +1,11 @@ -import { stripNamespace } from './stripNamespace'; +import { stripNamespace } from '../stripNamespace'; describe('stripNamespace', () => { it('should strip namespace', () => { + expect(stripNamespace('#/definitions/Item')).toEqual('Item'); + expect(stripNamespace('#/parameters/Item')).toEqual('Item'); + expect(stripNamespace('#/responses/Item')).toEqual('Item'); + expect(stripNamespace('#/securityDefinitions/Item')).toEqual('Item'); expect(stripNamespace('#/components/schemas/Item')).toEqual('Item'); expect(stripNamespace('#/components/responses/Item')).toEqual('Item'); expect(stripNamespace('#/components/parameters/Item')).toEqual('Item'); diff --git a/src/openApi/v3/parser/getType.spec.ts b/src/utils/__tests__/type.spec.ts similarity index 74% rename from src/openApi/v3/parser/getType.spec.ts rename to src/utils/__tests__/type.spec.ts index 06e23f374..25cc1f0c7 100644 --- a/src/openApi/v3/parser/getType.spec.ts +++ b/src/utils/__tests__/type.spec.ts @@ -1,4 +1,30 @@ -import { getType } from './getType'; +import { getMappedType, getType } from '../type'; + +describe('getMappedType', () => { + it('should map types to the basics', () => { + expect(getMappedType('')).toEqual(undefined); + expect(getMappedType('any')).toEqual('unknown'); + expect(getMappedType('array')).toEqual('unknown[]'); + expect(getMappedType('boolean')).toEqual('boolean'); + expect(getMappedType('byte')).toEqual('number'); + expect(getMappedType('char')).toEqual('string'); + expect(getMappedType('date-time')).toEqual('string'); + expect(getMappedType('date')).toEqual('string'); + expect(getMappedType('double')).toEqual('number'); + expect(getMappedType('file')).toEqual('binary'); + expect(getMappedType('float')).toEqual('number'); + expect(getMappedType('int')).toEqual('number'); + expect(getMappedType('integer')).toEqual('number'); + expect(getMappedType('long')).toEqual('number'); + expect(getMappedType('null')).toEqual('null'); + expect(getMappedType('number')).toEqual('number'); + expect(getMappedType('object')).toEqual('unknown'); + expect(getMappedType('password')).toEqual('string'); + expect(getMappedType('short')).toEqual('number'); + expect(getMappedType('string')).toEqual('string'); + expect(getMappedType('void')).toEqual('void'); + }); +}); describe('getType', () => { it('should convert int', () => { diff --git a/src/utils/discriminator.ts b/src/utils/discriminator.ts index 15e1ef510..bf1f7ecb6 100644 --- a/src/utils/discriminator.ts +++ b/src/utils/discriminator.ts @@ -1,7 +1,7 @@ import type { Model } from '../client/interfaces/Model'; import type { OpenApi } from '../openApi/v3/interfaces/OpenApi'; import type { OpenApiDiscriminator } from '../openApi/v3/interfaces/OpenApiDiscriminator'; -import { stripNamespace } from '../openApi/v3/parser/stripNamespace'; +import { stripNamespace } from './stripNamespace'; import type { Dictionary } from './types'; const inverseDictionary = (map: Dictionary): Dictionary => { diff --git a/src/utils/getHttpRequestName.ts b/src/utils/getHttpRequestName.ts index 53b7ad05a..6f59d317c 100644 --- a/src/utils/getHttpRequestName.ts +++ b/src/utils/getHttpRequestName.ts @@ -1,20 +1,21 @@ -import { HttpClient } from '../HttpClient'; +import type { Options } from '../client/interfaces/Options'; /** * Generate the HttpRequest filename based on the selected client - * @param httpClient The selected httpClient (fetch, xhr, node or axios) + * @param client The selected HTTP client (fetch, xhr, node or axios) */ -export const getHttpRequestName = (httpClient: HttpClient): string => { - switch (httpClient) { - case HttpClient.FETCH: - return 'FetchHttpRequest'; - case HttpClient.XHR: - return 'XHRHttpRequest'; - case HttpClient.NODE: - return 'NodeHttpRequest'; - case HttpClient.AXIOS: - return 'AxiosHttpRequest'; - case HttpClient.ANGULAR: +export const getHttpRequestName = (client: Options['client']): string => { + switch (client) { + case 'angular': return 'AngularHttpRequest'; + case 'axios': + return 'AxiosHttpRequest'; + case 'node': + return 'NodeHttpRequest'; + case 'xhr': + return 'XHRHttpRequest'; + case 'fetch': + default: + return 'FetchHttpRequest'; } }; diff --git a/src/utils/getModelNames.ts b/src/utils/getModelNames.ts index 26b76f713..5a049fc58 100644 --- a/src/utils/getModelNames.ts +++ b/src/utils/getModelNames.ts @@ -1,6 +1,4 @@ import type { Model } from '../client/interfaces/Model'; import { sort } from './sort'; -export const getModelNames = (models: Model[]): string[] => { - return models.map(model => model.name).sort(sort); -}; +export const getModelNames = (models: Model[]): string[] => models.map(model => model.name).sort(sort); diff --git a/src/utils/getOpenApiSpec.ts b/src/utils/getOpenApiSpec.ts index 42266ec2d..9d7aa5b57 100644 --- a/src/utils/getOpenApiSpec.ts +++ b/src/utils/getOpenApiSpec.ts @@ -1,6 +1,8 @@ import $RefParser from '@apidevtools/json-schema-ref-parser'; import { resolve } from 'path'; +import type { OpenApi as OpenApiV2 } from '../openApi/v2/interfaces/OpenApi'; +import type { OpenApi as OpenApiV3 } from '../openApi/v3/interfaces/OpenApi'; import { exists } from './fileSystem'; const fetch = require('node-fetch'); @@ -13,8 +15,8 @@ globalThis.fetch = fetch; * on parsing the file as JSON. * @param location: Path or url */ -export const getOpenApiSpec = async (location: string): Promise => { +export const getOpenApiSpec = async (location: string) => { const absolutePathOrUrl = (await exists(location)) ? resolve(location) : location; - const schema = await $RefParser.bundle(absolutePathOrUrl, absolutePathOrUrl, {}); + const schema = (await $RefParser.bundle(absolutePathOrUrl, absolutePathOrUrl, {})) as OpenApiV2 | OpenApiV3; return schema; }; diff --git a/src/utils/getOpenApiSpecParser.ts b/src/utils/getOpenApiSpecParser.ts deleted file mode 100644 index 9798ef7a9..000000000 --- a/src/utils/getOpenApiSpecParser.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { parse as parseV2 } from '../openApi/v2'; -import { parse as parseV3 } from '../openApi/v3'; - -type SupportedMajorVersions = '2' | '3'; - -/** - * @param openApi The loaded spec - */ -export const getOpenApiSpecParser = (openApi: Record): typeof parseV2 | typeof parseV3 => { - const versionString = openApi.swagger || openApi.openapi; - if (typeof versionString === 'string') { - const versionMajor = versionString.charAt(0) as SupportedMajorVersions; - switch (versionMajor) { - case '2': - return parseV2; - case '3': - return parseV3; - default: - break; - } - } - throw new Error(`Unsupported Open API version: "${String(versionString)}"`); -}; diff --git a/src/utils/getServiceNames.ts b/src/utils/getServiceNames.ts index 913b746cf..0a2a6e80b 100644 --- a/src/utils/getServiceNames.ts +++ b/src/utils/getServiceNames.ts @@ -1,6 +1,4 @@ import type { Service } from '../client/interfaces/Service'; import { sort } from './sort'; -export const getServiceNames = (services: Service[]): string[] => { - return services.map(service => service.name).sort(sort); -}; +export const getServiceNames = (services: Service[]): string[] => services.map(service => service.name).sort(sort); diff --git a/src/utils/isEqual.ts b/src/utils/isEqual.ts index f0d1c2a39..678071e33 100644 --- a/src/utils/isEqual.ts +++ b/src/utils/isEqual.ts @@ -1,4 +1,5 @@ -export const isEqual = (a: any, b: any): boolean => { +export const isEqual = (a: A, b: B): boolean => { + // @ts-ignore if (a === b) { return true; } @@ -27,6 +28,7 @@ export const isEqual = (a: any, b: any): boolean => { if (!Object.prototype.hasOwnProperty.call(b, key)) { return false; } + // @ts-ignore if (!isEqual(a[key], b[key])) { return false; } diff --git a/src/utils/isSubdirectory.ts b/src/utils/isSubdirectory.ts index 761eb89d0..40e0a8d73 100644 --- a/src/utils/isSubdirectory.ts +++ b/src/utils/isSubdirectory.ts @@ -1,5 +1,3 @@ import { relative } from 'path'; -export const isSubDirectory = (parent: string, child: string) => { - return relative(child, parent).startsWith('..'); -}; +export const isSubDirectory = (parent: string, child: string) => relative(child, parent).startsWith('..'); diff --git a/src/utils/postProcessClient.ts b/src/utils/postProcessClient.ts index 0033923d4..2a5e3f5ac 100644 --- a/src/utils/postProcessClient.ts +++ b/src/utils/postProcessClient.ts @@ -6,10 +6,8 @@ import { postProcessService } from './postProcessService'; * Post process client * @param client Client object with all the models, services, etc. */ -export const postProcessClient = (client: Client): Client => { - return { - ...client, - models: client.models.map(model => postProcessModel(model)), - services: client.services.map(service => postProcessService(service)), - }; -}; +export const postProcessClient = (client: Client): Client => ({ + ...client, + models: client.models.map(model => postProcessModel(model)), + services: client.services.map(service => postProcessService(service)), +}); diff --git a/src/utils/postProcessModel.ts b/src/utils/postProcessModel.ts index 195a94e4f..bdff88841 100644 --- a/src/utils/postProcessModel.ts +++ b/src/utils/postProcessModel.ts @@ -8,11 +8,9 @@ import { postProcessModelImports } from './postProcessModelImports'; * This will clean up any double imports or enum values. * @param model */ -export const postProcessModel = (model: Model): Model => { - return { - ...model, - imports: postProcessModelImports(model), - enums: postProcessModelEnums(model), - enum: postProcessModelEnum(model), - }; -}; +export const postProcessModel = (model: Model): Model => ({ + ...model, + imports: postProcessModelImports(model), + enums: postProcessModelEnums(model), + enum: postProcessModelEnum(model), +}); diff --git a/src/utils/postProcessModelEnum.ts b/src/utils/postProcessModelEnum.ts index cb4a99704..6de934a7f 100644 --- a/src/utils/postProcessModelEnum.ts +++ b/src/utils/postProcessModelEnum.ts @@ -4,8 +4,5 @@ import type { Model } from '../client/interfaces/Model'; * Set unique enum values for the model * @param model */ -export const postProcessModelEnum = (model: Model) => { - return model.enum.filter((property, index, arr) => { - return arr.findIndex(item => item.value === property.value) === index; - }); -}; +export const postProcessModelEnum = (model: Model) => + model.enum.filter((property, index, arr) => arr.findIndex(item => item.value === property.value) === index); diff --git a/src/utils/postProcessModelEnums.ts b/src/utils/postProcessModelEnums.ts index 2f06127aa..9aada1ac6 100644 --- a/src/utils/postProcessModelEnums.ts +++ b/src/utils/postProcessModelEnums.ts @@ -4,8 +4,5 @@ import type { Model } from '../client/interfaces/Model'; * Set unique enum values for the model * @param model The model that is post-processed */ -export const postProcessModelEnums = (model: Model): Model[] => { - return model.enums.filter((property, index, arr) => { - return arr.findIndex(item => item.name === property.name) === index; - }); -}; +export const postProcessModelEnums = (model: Model): Model[] => + model.enums.filter((property, index, arr) => arr.findIndex(item => item.name === property.name) === index); diff --git a/src/utils/postProcessModelImports.ts b/src/utils/postProcessModelImports.ts index 00c0d4539..bd489b7be 100644 --- a/src/utils/postProcessModelImports.ts +++ b/src/utils/postProcessModelImports.ts @@ -6,9 +6,8 @@ import { unique } from './unique'; * Set unique imports, sorted by name * @param model The model that is post-processed */ -export const postProcessModelImports = (model: Model): string[] => { - return model.imports +export const postProcessModelImports = (model: Model): string[] => + model.imports .filter(unique) .sort(sort) .filter(name => model.name !== name); -}; diff --git a/src/utils/postProcessServiceImports.ts b/src/utils/postProcessServiceImports.ts index b47cfe793..103d04eb6 100644 --- a/src/utils/postProcessServiceImports.ts +++ b/src/utils/postProcessServiceImports.ts @@ -6,6 +6,4 @@ import { unique } from './unique'; * Set unique imports, sorted by name * @param service */ -export const postProcessServiceImports = (service: Service): string[] => { - return service.imports.filter(unique).sort(sort); -}; +export const postProcessServiceImports = (service: Service): string[] => service.imports.filter(unique).sort(sort); diff --git a/src/utils/readSpecFromHttp.ts b/src/utils/readSpecFromHttp.ts index e4cc828a5..2c33728cf 100644 --- a/src/utils/readSpecFromHttp.ts +++ b/src/utils/readSpecFromHttp.ts @@ -4,8 +4,8 @@ import { get } from 'http'; * Download the spec file from a HTTP resource * @param url */ -export const readSpecFromHttp = async (url: string): Promise => { - return new Promise((resolve, reject) => { +export const readSpecFromHttp = async (url: string): Promise => + new Promise((resolve, reject) => { get(url, response => { let body = ''; response.on('data', chunk => { @@ -19,4 +19,3 @@ export const readSpecFromHttp = async (url: string): Promise => { }); }); }); -}; diff --git a/src/utils/readSpecFromHttps.ts b/src/utils/readSpecFromHttps.ts index 52cdc57db..984bd966d 100644 --- a/src/utils/readSpecFromHttps.ts +++ b/src/utils/readSpecFromHttps.ts @@ -4,8 +4,8 @@ import { get } from 'https'; * Download the spec file from a HTTPS resource * @param url */ -export const readSpecFromHttps = async (url: string): Promise => { - return new Promise((resolve, reject) => { +export const readSpecFromHttps = async (url: string): Promise => + new Promise((resolve, reject) => { get(url, response => { let body = ''; response.on('data', chunk => { @@ -19,4 +19,3 @@ export const readSpecFromHttps = async (url: string): Promise => { }); }); }); -}; diff --git a/src/utils/registerHandlebarHelpers.ts b/src/utils/registerHandlebarHelpers.ts index edd0b2169..2bee9ef5d 100644 --- a/src/utils/registerHandlebarHelpers.ts +++ b/src/utils/registerHandlebarHelpers.ts @@ -6,7 +6,8 @@ import type { Model } from '../client/interfaces/Model'; import type { OperationParameter } from '../client/interfaces/OperationParameter'; import type { Options } from '../client/interfaces/Options'; import type { Service } from '../client/interfaces/Service'; -import type { OpenApi } from '../openApi/v3/interfaces/OpenApi'; +import type { OpenApi as OpenApiV2 } from '../openApi/v2/interfaces/OpenApi'; +import type { OpenApi as OpenApiV3 } from '../openApi/v3/interfaces/OpenApi'; import { enumKey, enumName, enumUnionType, enumValue } from './enum'; import { escapeName } from './escapeName'; import { unique } from './unique'; @@ -51,13 +52,13 @@ const dataParameters = (parameters: OperationParameter[]) => { return output.join(', '); }; -const debugThis = (value: any) => { +const debugThis = (value: unknown) => { console.log(value); return ''; }; export const registerHandlebarHelpers = ( - openApi: OpenApi, + openApi: OpenApiV3 | OpenApiV2, config: Omit, 'base' | 'clientName' | 'request'> ): void => { Handlebars.registerHelper('camelCase', camelCase); @@ -68,9 +69,12 @@ export const registerHandlebarHelpers = ( Handlebars.registerHelper('enumUnionType', enumUnionType); Handlebars.registerHelper('enumValue', enumValue); - Handlebars.registerHelper('equals', function (this: any, a: string, b: string, options: Handlebars.HelperOptions) { - return a === b ? options.fn(this) : options.inverse(this); - }); + Handlebars.registerHelper( + 'equals', + function (this: unknown, a: string, b: string, options: Handlebars.HelperOptions) { + return a === b ? options.fn(this) : options.inverse(this); + } + ); Handlebars.registerHelper('escapeComment', function (value: string) { return value @@ -87,14 +91,14 @@ export const registerHandlebarHelpers = ( return value.replace(/\n/g, '\\n'); }); - Handlebars.registerHelper('exactArray', function (this: any, model: Model, options: Handlebars.HelperOptions) { + Handlebars.registerHelper('exactArray', function (this: unknown, model: Model, options: Handlebars.HelperOptions) { if (model.export === 'array' && model.maxItems && model.minItems && model.maxItems === model.minItems) { return options.fn(this); } return options.inverse(this); }); - Handlebars.registerHelper('ifdef', function (this: any, ...args): string { + Handlebars.registerHelper('ifdef', function (this: unknown, ...args): string { const options = args.pop(); if (!args.every(value => !value)) { return options.fn(this); @@ -104,14 +108,14 @@ export const registerHandlebarHelpers = ( Handlebars.registerHelper( 'ifOperationDataOptional', - function (this: any, parameters: OperationParameter[], options: Handlebars.HelperOptions) { + function (this: unknown, parameters: OperationParameter[], options: Handlebars.HelperOptions) { return parameters.every(parameter => !parameter.isRequired) ? options.fn(this) : options.inverse(this); } ); Handlebars.registerHelper( 'intersection', - function (this: any, models: Model[], parent: string | undefined, options: Handlebars.HelperOptions) { + function (this: unknown, models: Model[], parent: string | undefined, options: Handlebars.HelperOptions) { const partialType = Handlebars.partials['type']; const types = models.map(model => partialType({ $config: config, ...model, parent })); const uniqueTypes = types.filter(unique); @@ -144,14 +148,14 @@ export const registerHandlebarHelpers = ( Handlebars.registerHelper( 'notEquals', - function (this: any, a: string, b: string, options: Handlebars.HelperOptions) { + function (this: unknown, a: string, b: string, options: Handlebars.HelperOptions) { return a !== b ? options.fn(this) : options.inverse(this); } ); Handlebars.registerHelper( 'useDateType', - function (this: any, config: Options, format: string | undefined, options: Handlebars.HelperOptions) { + function (this: unknown, config: Options, format: string | undefined, options: Handlebars.HelperOptions) { return config.useDateType && format === 'date-time' ? options.fn(this) : options.inverse(this); } ); diff --git a/src/utils/registerHandlebarTemplates.spec.ts b/src/utils/registerHandlebarTemplates.spec.ts index 31ebd2636..d3d2b314f 100644 --- a/src/utils/registerHandlebarTemplates.spec.ts +++ b/src/utils/registerHandlebarTemplates.spec.ts @@ -1,4 +1,3 @@ -import { HttpClient } from '../HttpClient'; import { registerHandlebarTemplates } from './registerHandlebarTemplates'; describe('registerHandlebarTemplates', () => { @@ -14,12 +13,12 @@ describe('registerHandlebarTemplates', () => { }, { autoformat: true, + client: 'fetch', enums: true, exportCore: true, exportModels: true, exportSchemas: true, exportServices: true, - httpClient: HttpClient.FETCH, input: '', operationId: true, output: '', diff --git a/src/utils/registerHandlebarTemplates.ts b/src/utils/registerHandlebarTemplates.ts index 48738cc2f..524ef07d3 100644 --- a/src/utils/registerHandlebarTemplates.ts +++ b/src/utils/registerHandlebarTemplates.ts @@ -1,7 +1,8 @@ import Handlebars from 'handlebars/runtime'; import type { Options } from '../client/interfaces/Options'; -import type { OpenApi } from '../openApi/v3/interfaces/OpenApi'; +import type { OpenApi as OpenApiV2 } from '../openApi/v2/interfaces/OpenApi'; +import type { OpenApi as OpenApiV3 } from '../openApi/v3/interfaces/OpenApi'; import templateClient from '../templates/client.hbs'; import angularGetHeaders from '../templates/core/angular/getHeaders.hbs'; import angularGetRequestBody from '../templates/core/angular/getRequestBody.hbs'; @@ -114,7 +115,7 @@ export interface Templates { * so we can easily access the templates in our generator/write functions. */ export const registerHandlebarTemplates = ( - openApi: OpenApi, + openApi: OpenApiV3 | OpenApiV2, options: Omit, 'base' | 'clientName' | 'request'> ): Templates => { registerHandlebarHelpers(openApi, options); diff --git a/src/openApi/v3/parser/stripNamespace.ts b/src/utils/stripNamespace.ts similarity index 69% rename from src/openApi/v3/parser/stripNamespace.ts rename to src/utils/stripNamespace.ts index 76b9d02d2..b3c4ee0b6 100644 --- a/src/openApi/v3/parser/stripNamespace.ts +++ b/src/utils/stripNamespace.ts @@ -2,9 +2,13 @@ * Strip (OpenAPI) namespaces fom values. * @param value */ -export const stripNamespace = (value: string): string => { - return value +export const stripNamespace = (value: string): string => + value .trim() + .replace(/^#\/definitions\//, '') + .replace(/^#\/parameters\//, '') + .replace(/^#\/responses\//, '') + .replace(/^#\/securityDefinitions\//, '') .replace(/^#\/components\/schemas\//, '') .replace(/^#\/components\/responses\//, '') .replace(/^#\/components\/parameters\//, '') @@ -14,4 +18,3 @@ export const stripNamespace = (value: string): string => { .replace(/^#\/components\/securitySchemes\//, '') .replace(/^#\/components\/links\//, '') .replace(/^#\/components\/callbacks\//, ''); -}; diff --git a/src/openApi/v3/parser/getType.ts b/src/utils/type.ts similarity index 69% rename from src/openApi/v3/parser/getType.ts rename to src/utils/type.ts index 307c875df..d075232d5 100644 --- a/src/openApi/v3/parser/getType.ts +++ b/src/utils/type.ts @@ -1,8 +1,40 @@ -import type { Type } from '../../../client/interfaces/Type'; -import sanitizeTypeName from '../../../utils/sanitizeTypeName'; -import { getMappedType } from './getMappedType'; +import type { Type } from '../client/interfaces/Type'; +import sanitizeTypeName from './sanitizeTypeName'; import { stripNamespace } from './stripNamespace'; +const TYPE_MAPPINGS = new Map([ + ['any', 'unknown'], + ['array', 'unknown[]'], + ['boolean', 'boolean'], + ['byte', 'number'], + ['char', 'string'], + ['date-time', 'string'], + ['date', 'string'], + ['double', 'number'], + ['file', 'binary'], + ['float', 'number'], + ['int', 'number'], + ['integer', 'number'], + ['long', 'number'], + ['null', 'null'], + ['number', 'number'], + ['object', 'unknown'], + ['password', 'string'], + ['short', 'number'], + ['string', 'string'], + ['void', 'void'], +]); + +/** + * Get mapped type for given type to basic Typescript/Javascript type. + */ +export const getMappedType = (type: string, format?: string): string | undefined => { + if (format === 'binary') { + return 'binary'; + } + return TYPE_MAPPINGS.get(type); +}; + const encode = (value: string): string => sanitizeTypeName(value); /** @@ -10,14 +42,14 @@ const encode = (value: string): string => sanitizeTypeName(value); * @param type String or String[] value like "integer", "Link[Model]" or ["string", "null"]. * @param format String value like "binary" or "date". */ -export const getType = (type: string | string[] = 'any', format?: string): Type => { +export const getType = (type: string | string[] = 'unknown', format?: string): Type => { const result: Type = { $refs: [], - base: 'any', + base: 'unknown', imports: [], isNullable: false, template: null, - type: 'any', + type: 'unknown', }; // Special case for JSON Schema spec (december 2020, page 17), @@ -49,7 +81,7 @@ export const getType = (type: string | string[] = 'any', format?: string): Type const match1 = getType(encode(matches[1])); const match2 = getType(encode(matches[2])); - if (match1.type === 'any[]') { + if (match1.type === 'unknown[]') { result.type = `${match2.type}[]`; result.base = `${match2.type}`; match1.$refs = []; diff --git a/src/utils/types.d.ts b/src/utils/types.d.ts index c9785159e..aad1ce5ed 100644 --- a/src/utils/types.d.ts +++ b/src/utils/types.d.ts @@ -1,3 +1,3 @@ -export interface Dictionary { +export interface Dictionary { [key: string]: T; } diff --git a/src/utils/unique.ts b/src/utils/unique.ts index d71cb420c..e480107d2 100644 --- a/src/utils/unique.ts +++ b/src/utils/unique.ts @@ -1,3 +1 @@ -export const unique = (value: T, index: number, arr: T[]): boolean => { - return arr.indexOf(value) === index; -}; +export const unique = (value: T, index: number, arr: T[]): boolean => arr.indexOf(value) === index; diff --git a/src/utils/write/__tests__/class.spec.ts b/src/utils/write/__tests__/class.spec.ts index c723c2432..ed912b29f 100644 --- a/src/utils/write/__tests__/class.spec.ts +++ b/src/utils/write/__tests__/class.spec.ts @@ -1,4 +1,3 @@ -import { HttpClient } from '../../../HttpClient'; import { writeFile } from '../../fileSystem'; import { writeClientClass } from '../class'; @@ -35,9 +34,9 @@ describe('writeClientClass', () => { }; await writeClientClass(client, templates, './dist', { + client: 'fetch', clientName: 'AppClient', enums: true, - httpClient: HttpClient.FETCH, postfixServices: '', }); diff --git a/src/utils/write/__tests__/client.spec.ts b/src/utils/write/__tests__/client.spec.ts index 94fb7819d..a9dde6ae8 100644 --- a/src/utils/write/__tests__/client.spec.ts +++ b/src/utils/write/__tests__/client.spec.ts @@ -1,4 +1,3 @@ -import { HttpClient } from '../../../HttpClient'; import { mkdir, rmdir, writeFile } from '../../fileSystem'; import { writeClient } from '../client'; @@ -36,6 +35,7 @@ describe('writeClient', () => { await writeClient(client, templates, { autoformat: true, + client: 'fetch', enums: true, exportCore: true, exportModels: true, @@ -44,7 +44,6 @@ describe('writeClient', () => { input: '', operationId: true, output: './dist', - httpClient: HttpClient.FETCH, postfixModels: 'AppClient', postfixServices: 'Service', serviceResponse: 'body', diff --git a/src/utils/write/__tests__/core.spec.ts b/src/utils/write/__tests__/core.spec.ts index a87ee47d6..c904e4073 100644 --- a/src/utils/write/__tests__/core.spec.ts +++ b/src/utils/write/__tests__/core.spec.ts @@ -1,6 +1,5 @@ import { resolve } from 'path'; -import { HttpClient } from '../../../HttpClient'; import { writeFile } from '../../fileSystem'; import { writeClientCore } from '../core'; @@ -41,7 +40,7 @@ describe('writeClientCore', () => { }; const config: Parameters[3] = { - httpClient: HttpClient.FETCH, + client: 'fetch', input: '', output: '', serviceResponse: 'body', @@ -67,7 +66,7 @@ describe('writeClientCore', () => { }; const config: Parameters[3] = { - httpClient: HttpClient.FETCH, + client: 'fetch', input: '', output: '', serviceResponse: 'body', @@ -93,7 +92,7 @@ describe('writeClientCore', () => { const config: Parameters[3] = { base: 'foo', - httpClient: HttpClient.FETCH, + client: 'fetch', input: '', output: '', serviceResponse: 'body', diff --git a/src/utils/write/__tests__/models.spec.ts b/src/utils/write/__tests__/models.spec.ts index 3ae9788fa..f481b8d8a 100644 --- a/src/utils/write/__tests__/models.spec.ts +++ b/src/utils/write/__tests__/models.spec.ts @@ -1,6 +1,5 @@ import { resolve } from 'path'; -import { HttpClient } from '../../../HttpClient'; import { writeClientModels } from '../models'; import { writeFile } from './../../fileSystem'; @@ -56,8 +55,8 @@ describe('writeClientModels', () => { }; await writeClientModels(client, templates, '/', { + client: 'fetch', enums: true, - httpClient: HttpClient.FETCH, useDateType: false, }); diff --git a/src/utils/write/__tests__/schemas.spec.ts b/src/utils/write/__tests__/schemas.spec.ts index 2105be0e9..05794b3ea 100644 --- a/src/utils/write/__tests__/schemas.spec.ts +++ b/src/utils/write/__tests__/schemas.spec.ts @@ -1,6 +1,5 @@ import { resolve } from 'path'; -import { HttpClient } from '../../../HttpClient'; import { writeFile } from '../../fileSystem'; import { writeClientSchemas } from '../schemas'; @@ -56,8 +55,8 @@ describe('writeClientSchemas', () => { }; await writeClientSchemas(client, templates, '/', { + client: 'fetch', enums: true, - httpClient: HttpClient.FETCH, }); expect(writeFile).toHaveBeenCalledWith(resolve('/', '/$User.ts'), 'schema'); diff --git a/src/utils/write/__tests__/services.spec.ts b/src/utils/write/__tests__/services.spec.ts index 622f03b82..9ddb7371e 100644 --- a/src/utils/write/__tests__/services.spec.ts +++ b/src/utils/write/__tests__/services.spec.ts @@ -1,6 +1,5 @@ import { resolve } from 'path'; -import { HttpClient } from '../../../HttpClient'; import { writeFile } from '../../fileSystem'; import { writeClientServices } from '../services'; @@ -44,7 +43,7 @@ describe('writeClientServices', () => { }; await writeClientServices(client, templates, '/', { - httpClient: HttpClient.FETCH, + client: 'fetch', input: '', output: '', postfixServices: 'Service', diff --git a/src/utils/write/class.ts b/src/utils/write/class.ts index f57d61b76..fac8529a1 100644 --- a/src/utils/write/class.ts +++ b/src/utils/write/class.ts @@ -21,11 +21,11 @@ export const writeClientClass = async ( client: Client, templates: Templates, outputPath: string, - options: Pick, 'clientName' | 'enums' | 'httpClient' | 'postfixServices'> + options: Pick, 'client' | 'clientName' | 'enums' | 'postfixServices'> ): Promise => { const templateResult = templates.client({ $config: options, - httpRequest: getHttpRequestName(options.httpClient), + httpRequest: getHttpRequestName(options.client), models: sortModelsByName(client.models), server: client.server, services: sortServicesByName(client.services), diff --git a/src/utils/write/client.ts b/src/utils/write/client.ts index fc55d74fa..a5e669ec5 100644 --- a/src/utils/write/client.ts +++ b/src/utils/write/client.ts @@ -1,5 +1,3 @@ -import { sync } from 'cross-spawn'; -import { createRequire } from 'module'; import Path from 'path'; import type { Client } from '../../client/interfaces/Client'; @@ -82,22 +80,4 @@ export const writeClient = async ( await mkdir(outputPath); await writeClientIndex(client, templates, outputPath, options); } - - const pathPackageJson = Path.resolve(process.cwd(), 'package.json'); - const require = createRequire('/'); - const json = require(pathPackageJson); - - const allDependencies = [json.dependencies, json.devDependencies].reduce( - (res, deps) => ({ - ...res, - ...deps, - }), - {} - ); - - if (options.autoformat) { - if (allDependencies.prettier) { - sync('prettier', ['--ignore-unknown', options.output, '--write', '--ignore-path', './.prettierignore']); - } - } }; diff --git a/src/utils/write/core.ts b/src/utils/write/core.ts index 5832da049..92c42a3cc 100644 --- a/src/utils/write/core.ts +++ b/src/utils/write/core.ts @@ -17,10 +17,10 @@ export const writeClientCore = async ( client: Client, templates: Templates, outputPath: string, - options: Pick, 'httpClient' | 'serviceResponse'> & Omit + options: Pick, 'client' | 'serviceResponse'> & Omit ): Promise => { const context = { - httpRequest: getHttpRequestName(options.httpClient), + httpRequest: getHttpRequestName(options.client), server: options.base !== undefined ? options.base : client.server, version: client.version, }; diff --git a/src/utils/write/models.ts b/src/utils/write/models.ts index df2129926..dbe6093a7 100644 --- a/src/utils/write/models.ts +++ b/src/utils/write/models.ts @@ -16,7 +16,7 @@ export const writeClientModels = async ( client: Client, templates: Templates, outputPath: string, - options: Pick, 'enums' | 'httpClient' | 'useDateType'> + options: Pick, 'client' | 'enums' | 'useDateType'> ): Promise => { for (const model of client.models) { const file = resolve(outputPath, `${model.name}.ts`); diff --git a/src/utils/write/schemas.ts b/src/utils/write/schemas.ts index 6bf65cb4c..c48da1c13 100644 --- a/src/utils/write/schemas.ts +++ b/src/utils/write/schemas.ts @@ -16,7 +16,7 @@ export const writeClientSchemas = async ( client: Client, templates: Templates, outputPath: string, - options: Pick, 'enums' | 'httpClient'> + options: Pick, 'client' | 'enums'> ): Promise => { for (const model of client.models) { const file = resolve(outputPath, `$${model.name}.ts`); diff --git a/src/utils/write/services.ts b/src/utils/write/services.ts index 53fec5dac..8f508e93e 100644 --- a/src/utils/write/services.ts +++ b/src/utils/write/services.ts @@ -16,8 +16,8 @@ export const writeClientServices = async ( client: Client, templates: Templates, outputPath: string, - options: Pick, 'httpClient' | 'postfixServices' | 'serviceResponse' | 'useOptions'> & - Omit + options: Pick, 'client' | 'postfixServices' | 'serviceResponse' | 'useOptions'> & + Omit ): Promise => { for (const service of client.services) { const file = Path.resolve(outputPath, `${service.name}${options.postfixServices}.ts`); diff --git a/test/__snapshots__/index.spec.ts.snap b/test/__snapshots__/index.spec.ts.snap index 66d9f8a35..9363d7533 100644 --- a/test/__snapshots__/index.spec.ts.snap +++ b/test/__snapshots__/index.spec.ts.snap @@ -8,7 +8,7 @@ export class ApiError extends Error { public readonly url: string; public readonly status: number; public readonly statusText: string; - public readonly body: any; + public readonly body: unknown; public readonly request: ApiRequestOptions; constructor(request: ApiRequestOptions, response: ApiResult, message: string) { @@ -29,11 +29,11 @@ exports[`v2 should generate: test/generated/v2/core/ApiRequestOptions.ts 1`] = ` "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 path?: Record; + readonly cookies?: Record; + readonly headers?: Record; + readonly query?: Record; + readonly formData?: Record; readonly body?: any; readonly mediaType?: string; readonly responseHeader?: string; @@ -80,12 +80,12 @@ export class CancelablePromise implements Promise { readonly #cancelHandlers: (() => void)[]; readonly #promise: Promise; #resolve?: (value: T | PromiseLike) => void; - #reject?: (reason?: any) => void; + #reject?: (reason?: unknown) => void; constructor( executor: ( resolve: (value: T | PromiseLike) => void, - reject: (reason?: any) => void, + reject: (reason?: unknown) => void, onCancel: OnCancel ) => void ) { @@ -105,7 +105,7 @@ export class CancelablePromise implements Promise { if (this.#resolve) this.#resolve(value); }; - const onReject = (reason?: any): void => { + const onReject = (reason?: unknown): void => { if (this.#isResolved || this.#isRejected || this.#isCancelled) { return; } @@ -142,13 +142,13 @@ export class CancelablePromise implements Promise { public then( onFulfilled?: ((value: T) => TResult1 | PromiseLike) | null, - onRejected?: ((reason: any) => TResult2 | PromiseLike) | null + onRejected?: ((reason: unknown) => TResult2 | PromiseLike) | null ): Promise { return this.#promise.then(onFulfilled, onRejected); } public catch( - onRejected?: ((reason: any) => TResult | PromiseLike) | null + onRejected?: ((reason: unknown) => TResult | PromiseLike) | null ): Promise { return this.#promise.catch(onRejected); } @@ -240,16 +240,17 @@ import { CancelablePromise } from './CancelablePromise'; import type { OnCancel } from './CancelablePromise'; import type { OpenAPIConfig } from './OpenAPI'; -export const isString = (value: any): value is string => { +export const isString = (value: unknown): value is string => { return typeof value === 'string'; }; -export const isStringWithValue = (value: any): value is string => { +export const isStringWithValue = (value: unknown): value is string => { return isString(value) && value !== ''; }; export const isBlob = (value: any): value is Blob => { return ( + value !== null && typeof value === 'object' && typeof value.type === 'string' && typeof value.stream === 'function' && @@ -257,11 +258,12 @@ export const isBlob = (value: any): value is Blob => { typeof value.constructor === 'function' && typeof value.constructor.name === 'string' && /^(Blob|File)$/.test(value.constructor.name) && + // @ts-ignore /^(Blob|File)$/.test(value[Symbol.toStringTag]) ); }; -export const isFormData = (value: any): value is FormData => { +export const isFormData = (value: unknown): value is FormData => { return value instanceof FormData; }; @@ -274,14 +276,14 @@ export const base64 = (str: string): string => { } }; -export const getQueryString = (params: Record): string => { +export const getQueryString = (params: Record): string => { const qs: string[] = []; - const append = (key: string, value: any) => { + const append = (key: string, value: unknown) => { qs.push(\`\${encodeURIComponent(key)}=\${encodeURIComponent(String(value))}\`); }; - const process = (key: string, value: any) => { + const process = (key: string, value: unknown) => { if (value) { if (Array.isArray(value)) { value.forEach(v => { @@ -409,7 +411,7 @@ export const getHeaders = async (config: OpenAPIConfig, options: ApiRequestOptio return new Headers(headers); }; -export const getRequestBody = (options: ApiRequestOptions): any => { +export const getRequestBody = (options: ApiRequestOptions): unknown => { if (options.body !== undefined) { if (options.mediaType?.includes('/json')) { return JSON.stringify(options.body); @@ -459,7 +461,7 @@ export const getResponseHeader = (response: Response, responseHeader?: string): return undefined; }; -export const getResponseBody = async (response: Response): Promise => { +export const getResponseBody = async (response: Response): Promise => { if (response.status !== 204) { try { const contentType = response.headers.get('Content-Type'); @@ -2761,9 +2763,9 @@ export class TypesService { parameterNumber: number = 123, parameterString: string = 'default', parameterBoolean: boolean = true, - parameterObject: any = null, + parameterObject: unknown = null, id?: number - ): CancelablePromise { + ): CancelablePromise { return __request(OpenAPI, { method: 'GET', url: '/api/v{api-version}/types', @@ -2867,7 +2869,7 @@ export class ApiError extends Error { public readonly url: string; public readonly status: number; public readonly statusText: string; - public readonly body: any; + public readonly body: unknown; public readonly request: ApiRequestOptions; constructor(request: ApiRequestOptions, response: ApiResult, message: string) { @@ -2888,11 +2890,11 @@ exports[`v3 should generate optional argument: test/generated/v3_options/core/Ap "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 path?: Record; + readonly cookies?: Record; + readonly headers?: Record; + readonly query?: Record; + readonly formData?: Record; readonly body?: any; readonly mediaType?: string; readonly responseHeader?: string; @@ -2939,12 +2941,12 @@ export class CancelablePromise implements Promise { readonly #cancelHandlers: (() => void)[]; readonly #promise: Promise; #resolve?: (value: T | PromiseLike) => void; - #reject?: (reason?: any) => void; + #reject?: (reason?: unknown) => void; constructor( executor: ( resolve: (value: T | PromiseLike) => void, - reject: (reason?: any) => void, + reject: (reason?: unknown) => void, onCancel: OnCancel ) => void ) { @@ -2964,7 +2966,7 @@ export class CancelablePromise implements Promise { if (this.#resolve) this.#resolve(value); }; - const onReject = (reason?: any): void => { + const onReject = (reason?: unknown): void => { if (this.#isResolved || this.#isRejected || this.#isCancelled) { return; } @@ -3001,13 +3003,13 @@ export class CancelablePromise implements Promise { public then( onFulfilled?: ((value: T) => TResult1 | PromiseLike) | null, - onRejected?: ((reason: any) => TResult2 | PromiseLike) | null + onRejected?: ((reason: unknown) => TResult2 | PromiseLike) | null ): Promise { return this.#promise.then(onFulfilled, onRejected); } public catch( - onRejected?: ((reason: any) => TResult | PromiseLike) | null + onRejected?: ((reason: unknown) => TResult | PromiseLike) | null ): Promise { return this.#promise.catch(onRejected); } @@ -3099,16 +3101,17 @@ import { CancelablePromise } from './CancelablePromise'; import type { OnCancel } from './CancelablePromise'; import type { OpenAPIConfig } from './OpenAPI'; -export const isString = (value: any): value is string => { +export const isString = (value: unknown): value is string => { return typeof value === 'string'; }; -export const isStringWithValue = (value: any): value is string => { +export const isStringWithValue = (value: unknown): value is string => { return isString(value) && value !== ''; }; export const isBlob = (value: any): value is Blob => { return ( + value !== null && typeof value === 'object' && typeof value.type === 'string' && typeof value.stream === 'function' && @@ -3116,11 +3119,12 @@ export const isBlob = (value: any): value is Blob => { typeof value.constructor === 'function' && typeof value.constructor.name === 'string' && /^(Blob|File)$/.test(value.constructor.name) && + // @ts-ignore /^(Blob|File)$/.test(value[Symbol.toStringTag]) ); }; -export const isFormData = (value: any): value is FormData => { +export const isFormData = (value: unknown): value is FormData => { return value instanceof FormData; }; @@ -3133,14 +3137,14 @@ export const base64 = (str: string): string => { } }; -export const getQueryString = (params: Record): string => { +export const getQueryString = (params: Record): string => { const qs: string[] = []; - const append = (key: string, value: any) => { + const append = (key: string, value: unknown) => { qs.push(\`\${encodeURIComponent(key)}=\${encodeURIComponent(String(value))}\`); }; - const process = (key: string, value: any) => { + const process = (key: string, value: unknown) => { if (value) { if (Array.isArray(value)) { value.forEach(v => { @@ -3268,7 +3272,7 @@ export const getHeaders = async (config: OpenAPIConfig, options: ApiRequestOptio return new Headers(headers); }; -export const getRequestBody = (options: ApiRequestOptions): any => { +export const getRequestBody = (options: ApiRequestOptions): unknown => { if (options.body !== undefined) { if (options.mediaType?.includes('/json')) { return JSON.stringify(options.body); @@ -3318,7 +3322,7 @@ export const getResponseHeader = (response: Response, responseHeader?: string): return undefined; }; -export const getResponseBody = async (response: Response): Promise => { +export const getResponseBody = async (response: Response): Promise => { if (response.status !== 204) { try { const contentType = response.headers.get('Content-Type'); @@ -3638,7 +3642,7 @@ export class ApiError extends Error { public readonly url: string; public readonly status: number; public readonly statusText: string; - public readonly body: any; + public readonly body: unknown; public readonly request: ApiRequestOptions; constructor(request: ApiRequestOptions, response: ApiResult, message: string) { @@ -3659,11 +3663,11 @@ exports[`v3 should generate: test/generated/v3/core/ApiRequestOptions.ts 1`] = ` "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 path?: Record; + readonly cookies?: Record; + readonly headers?: Record; + readonly query?: Record; + readonly formData?: Record; readonly body?: any; readonly mediaType?: string; readonly responseHeader?: string; @@ -3710,12 +3714,12 @@ export class CancelablePromise implements Promise { readonly #cancelHandlers: (() => void)[]; readonly #promise: Promise; #resolve?: (value: T | PromiseLike) => void; - #reject?: (reason?: any) => void; + #reject?: (reason?: unknown) => void; constructor( executor: ( resolve: (value: T | PromiseLike) => void, - reject: (reason?: any) => void, + reject: (reason?: unknown) => void, onCancel: OnCancel ) => void ) { @@ -3735,7 +3739,7 @@ export class CancelablePromise implements Promise { if (this.#resolve) this.#resolve(value); }; - const onReject = (reason?: any): void => { + const onReject = (reason?: unknown): void => { if (this.#isResolved || this.#isRejected || this.#isCancelled) { return; } @@ -3772,13 +3776,13 @@ export class CancelablePromise implements Promise { public then( onFulfilled?: ((value: T) => TResult1 | PromiseLike) | null, - onRejected?: ((reason: any) => TResult2 | PromiseLike) | null + onRejected?: ((reason: unknown) => TResult2 | PromiseLike) | null ): Promise { return this.#promise.then(onFulfilled, onRejected); } public catch( - onRejected?: ((reason: any) => TResult | PromiseLike) | null + onRejected?: ((reason: unknown) => TResult | PromiseLike) | null ): Promise { return this.#promise.catch(onRejected); } @@ -3870,16 +3874,17 @@ import { CancelablePromise } from './CancelablePromise'; import type { OnCancel } from './CancelablePromise'; import type { OpenAPIConfig } from './OpenAPI'; -export const isString = (value: any): value is string => { +export const isString = (value: unknown): value is string => { return typeof value === 'string'; }; -export const isStringWithValue = (value: any): value is string => { +export const isStringWithValue = (value: unknown): value is string => { return isString(value) && value !== ''; }; export const isBlob = (value: any): value is Blob => { return ( + value !== null && typeof value === 'object' && typeof value.type === 'string' && typeof value.stream === 'function' && @@ -3887,11 +3892,12 @@ export const isBlob = (value: any): value is Blob => { typeof value.constructor === 'function' && typeof value.constructor.name === 'string' && /^(Blob|File)$/.test(value.constructor.name) && + // @ts-ignore /^(Blob|File)$/.test(value[Symbol.toStringTag]) ); }; -export const isFormData = (value: any): value is FormData => { +export const isFormData = (value: unknown): value is FormData => { return value instanceof FormData; }; @@ -3904,14 +3910,14 @@ export const base64 = (str: string): string => { } }; -export const getQueryString = (params: Record): string => { +export const getQueryString = (params: Record): string => { const qs: string[] = []; - const append = (key: string, value: any) => { + const append = (key: string, value: unknown) => { qs.push(\`\${encodeURIComponent(key)}=\${encodeURIComponent(String(value))}\`); }; - const process = (key: string, value: any) => { + const process = (key: string, value: unknown) => { if (value) { if (Array.isArray(value)) { value.forEach(v => { @@ -4039,7 +4045,7 @@ export const getHeaders = async (config: OpenAPIConfig, options: ApiRequestOptio return new Headers(headers); }; -export const getRequestBody = (options: ApiRequestOptions): any => { +export const getRequestBody = (options: ApiRequestOptions): unknown => { if (options.body !== undefined) { if (options.mediaType?.includes('/json')) { return JSON.stringify(options.body); @@ -4089,7 +4095,7 @@ export const getResponseHeader = (response: Response, responseHeader?: string): return undefined; }; -export const getResponseBody = async (response: Response): Promise => { +export const getResponseBody = async (response: Response): Promise => { if (response.status !== 204) { try { const contentType = response.headers.get('Content-Type'); @@ -4438,7 +4444,7 @@ exports[`v3 should generate: test/generated/v3/models/_default.ts 1`] = ` exports[`v3 should generate: test/generated/v3/models/AnyOfAnyAndNull.ts 1`] = ` "export type AnyOfAnyAndNull = { - data?: any | null; + data?: unknown | null; }; " `; @@ -5001,7 +5007,7 @@ exports[`v3 should generate: test/generated/v3/models/FreeFormObjectWithAddition "/** * This is a free-form object with additionalProperties: {}. */ -export type FreeFormObjectWithAdditionalPropertiesEqEmptyObject = Record; +export type FreeFormObjectWithAdditionalPropertiesEqEmptyObject = Record; " `; @@ -5009,7 +5015,7 @@ exports[`v3 should generate: test/generated/v3/models/FreeFormObjectWithAddition "/** * This is a free-form object with additionalProperties: true. */ -export type FreeFormObjectWithAdditionalPropertiesEqTrue = Record; +export type FreeFormObjectWithAdditionalPropertiesEqTrue = Record; " `; @@ -5017,7 +5023,7 @@ exports[`v3 should generate: test/generated/v3/models/FreeFormObjectWithoutAddit "/** * This is a free-form object without additionalProperties. */ -export type FreeFormObjectWithoutAdditionalProperties = Record; +export type FreeFormObjectWithoutAdditionalProperties = Record; " `; @@ -5080,7 +5086,7 @@ export type ModelWithAdditionalPropertiesEqTrue = { * This is a simple string property */ prop?: string; - [key: string]: any; + [key: string]: unknown; }; " `; @@ -6501,18 +6507,15 @@ exports[`v3 should generate: test/generated/v3/schemas/$ModelThatExtendsExtends. exports[`v3 should generate: test/generated/v3/schemas/$ModelWithAdditionalPropertiesEqTrue.ts 1`] = ` "export const $ModelWithAdditionalPropertiesEqTrue = { - description: \`This is a model with one property and additionalProperties: true\`, - properties: { - prop: { - type: 'string', - description: \`This is a simple string property\`, -}, - [key: string]: { - type: 'any', - isRequired: true, -}, - }, -} as const;" + description: \`This is a model with one property and additionalProperties: true\`, + properties: { + prop: { + type: 'string', + description: \`This is a simple string property\`, + }, + }, +} as const; +" `; exports[`v3 should generate: test/generated/v3/schemas/$ModelWithArray.ts 1`] = ` @@ -7497,12 +7500,12 @@ export class DescriptionsService { * @throws ApiError */ public static callWithDescriptions( - parameterWithBreaks?: any, - parameterWithBackticks?: any, - parameterWithSlashes?: any, - parameterWithExpressionPlaceholders?: any, - parameterWithQuotes?: any, - parameterWithReservedCharacters?: any + parameterWithBreaks?: unknown, + parameterWithBackticks?: unknown, + parameterWithSlashes?: unknown, + parameterWithExpressionPlaceholders?: unknown, + parameterWithQuotes?: unknown, + parameterWithReservedCharacters?: unknown ): CancelablePromise { return __request(OpenAPI, { method: 'POST', @@ -8227,19 +8230,19 @@ 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 any Response is a simple object + * @returns unknown Response is a simple object * @throws ApiError */ public static types( parameterArray: Array | null, - parameterDictionary: Record | null, + parameterDictionary: Record | null, parameterEnum: 'Success' | 'Warning' | 'Error' | null, parameterNumber: number = 123, parameterString: string | null = 'default', parameterBoolean: boolean | null = true, - parameterObject: Record | null = null, + parameterObject: Record | null = null, id?: number - ): CancelablePromise> { + ): CancelablePromise> { return __request(OpenAPI, { method: 'GET', url: '/api/v{api-version}/types', diff --git a/test/e2e/assets/main-angular-module.ts b/test/e2e/assets/main-angular-module.ts index f6529550e..87c26d836 100644 --- a/test/e2e/assets/main-angular-module.ts +++ b/test/e2e/assets/main-angular-module.ts @@ -43,7 +43,8 @@ export class AppComponent { private readonly simpleService: SimpleService, private readonly typesService: TypesService ) { - (window as any).api = { + // @ts-ignore + window.api = { OpenAPI, ApiModule, CollectionFormatService: this.collectionFormatService, diff --git a/test/e2e/assets/main-angular.ts b/test/e2e/assets/main-angular.ts index 1ed564d2f..fc01bf8d0 100644 --- a/test/e2e/assets/main-angular.ts +++ b/test/e2e/assets/main-angular.ts @@ -42,7 +42,8 @@ export class AppComponent { private readonly simpleService: SimpleService, private readonly typesService: TypesService ) { - (window as any).api = { + // @ts-ignore + window.api = { OpenAPI, CollectionFormatService: this.collectionFormatService, ComplexService: this.complexService, diff --git a/test/e2e/assets/main.ts b/test/e2e/assets/main.ts index 4bbf7cd3b..582c86850 100644 --- a/test/e2e/assets/main.ts +++ b/test/e2e/assets/main.ts @@ -1,3 +1,4 @@ import * as api from './index'; -(window as any).api = api; +// @ts-ignore +window.api = api; diff --git a/test/e2e/client.angular.spec.ts b/test/e2e/client.angular.spec.ts index f076b7d7e..18f9ac56c 100644 --- a/test/e2e/client.angular.spec.ts +++ b/test/e2e/client.angular.spec.ts @@ -24,86 +24,105 @@ describe('client.angular', () => { it('requests token', async () => { await browser.exposeFunction('tokenRequest', jest.fn().mockResolvedValue('MY_TOKEN')); - const result = await browser.evaluate(async () => { - return await new Promise(resolve => { - const { SimpleService } = (window as any).api; - SimpleService.httpRequest.config.TOKEN = (window as any).tokenRequest; - SimpleService.httpRequest.config.USERNAME = undefined; - SimpleService.httpRequest.config.PASSWORD = undefined; - SimpleService.getCallWithoutParametersAndResponse().subscribe(resolve); - }); - }); + const result = await browser.evaluate( + async () => + await new Promise(resolve => { + // @ts-ignore + const { SimpleService } = window.api; + // @ts-ignore + SimpleService.httpRequest.config.TOKEN = window.tokenRequest; + SimpleService.httpRequest.config.USERNAME = undefined; + SimpleService.httpRequest.config.PASSWORD = undefined; + SimpleService.getCallWithoutParametersAndResponse().subscribe(resolve); + }) + ); + // @ts-ignore expect(result.headers.authorization).toBe('Bearer MY_TOKEN'); }); it('uses credentials', async () => { - const result = await browser.evaluate(async () => { - return await new Promise(resolve => { - const { SimpleService } = (window as any).api; - SimpleService.httpRequest.config.TOKEN = undefined; - SimpleService.httpRequest.config.USERNAME = 'username'; - SimpleService.httpRequest.config.PASSWORD = 'password'; - SimpleService.getCallWithoutParametersAndResponse().subscribe(resolve); - }); - }); + const result = await browser.evaluate( + async () => + await new Promise(resolve => { + // @ts-ignore + const { SimpleService } = window.api; + SimpleService.httpRequest.config.TOKEN = undefined; + SimpleService.httpRequest.config.USERNAME = 'username'; + SimpleService.httpRequest.config.PASSWORD = 'password'; + SimpleService.getCallWithoutParametersAndResponse().subscribe(resolve); + }) + ); + // @ts-ignore expect(result.headers.authorization).toBe('Basic dXNlcm5hbWU6cGFzc3dvcmQ='); }); it('supports complex params', async () => { - const result = await browser.evaluate(async () => { - return await new Promise(resolve => { - const { ComplexService } = (window as any).api; - ComplexService.complexTypes({ - first: { - second: { - third: 'Hello World!', + const result = await browser.evaluate( + async () => + await new Promise(resolve => { + // @ts-ignore + const { ComplexService } = window.api; + ComplexService.complexTypes({ + first: { + second: { + third: 'Hello World!', + }, }, - }, - }).subscribe(resolve); - }); - }); + }).subscribe(resolve); + }) + ); expect(result).toBeDefined(); }); it('support form data', async () => { - const result = await browser.evaluate(async () => { - return await new Promise(resolve => { - const { ParametersService } = (window as any).api; - ParametersService.callWithParameters( - 'valueHeader', - 'valueQuery', - 'valueForm', - 'valueCookie', - 'valuePath', - { - prop: 'valueBody', - } - ).subscribe(resolve); - }); - }); + const result = await browser.evaluate( + async () => + await new Promise(resolve => { + // @ts-ignore + const { ParametersService } = window.api; + ParametersService.callWithParameters( + 'valueHeader', + 'valueQuery', + 'valueForm', + 'valueCookie', + 'valuePath', + { + prop: 'valueBody', + } + ).subscribe(resolve); + }) + ); expect(result).toBeDefined(); }); it('should throw known error (500)', async () => { - const error = await browser.evaluate(async () => { - return await new Promise(resolve => { - const { ErrorService } = (window as any).api; - ErrorService.testErrorCode(500).subscribe({ - error: (e: any) => { - resolve( - JSON.stringify({ - name: e.name, - message: e.message, - url: e.url, - status: e.status, - statusText: e.statusText, - body: e.body, - }) - ); - }, - }); - }); - }); + const error = await browser.evaluate( + async () => + await new Promise(resolve => { + // @ts-ignore + const { ErrorService } = window.api; + ErrorService.testErrorCode(500).subscribe({ + error: (e: unknown) => { + resolve( + JSON.stringify({ + // @ts-ignore + name: e.name, + // @ts-ignore + message: e.message, + // @ts-ignore + url: e.url, + // @ts-ignore + status: e.status, + // @ts-ignore + statusText: e.statusText, + // @ts-ignore + body: e.body, + }) + ); + }, + }); + }) + ); expect(error).toBe( JSON.stringify({ name: 'ApiError', @@ -120,25 +139,33 @@ describe('client.angular', () => { }); it('should throw unknown error (409)', async () => { - const error = await browser.evaluate(async () => { - return await new Promise(resolve => { - const { ErrorService } = (window as any).api; - ErrorService.testErrorCode(409).subscribe({ - error: (e: any) => { - resolve( - JSON.stringify({ - name: e.name, - message: e.message, - url: e.url, - status: e.status, - statusText: e.statusText, - body: e.body, - }) - ); - }, - }); - }); - }); + const error = await browser.evaluate( + async () => + await new Promise(resolve => { + // @ts-ignore + const { ErrorService } = window.api; + ErrorService.testErrorCode(409).subscribe({ + error: (e: unknown) => { + resolve( + JSON.stringify({ + // @ts-ignore + name: e.name, + // @ts-ignore + message: e.message, + // @ts-ignore + url: e.url, + // @ts-ignore + status: e.status, + // @ts-ignore + statusText: e.statusText, + // @ts-ignore + body: e.body, + }) + ); + }, + }); + }) + ); expect(error).toBe( JSON.stringify({ diff --git a/test/e2e/client.axios.spec.ts b/test/e2e/client.axios.spec.ts index 5d9d08632..22b3096ee 100644 --- a/test/e2e/client.axios.spec.ts +++ b/test/e2e/client.axios.spec.ts @@ -90,8 +90,7 @@ describe('client.axios', () => { const { ApiClient } = require('./generated/client/axios/index.js'); const client = new ApiClient(); await client.error.testErrorCode(500); - } catch (e) { - const err = e as any; + } catch (err) { error = JSON.stringify({ name: err.name, message: err.message, @@ -122,8 +121,7 @@ describe('client.axios', () => { const { ApiClient } = require('./generated/client/axios/index.js'); const client = new ApiClient(); await client.error.testErrorCode(409); - } catch (e) { - const err = e as any; + } catch (err) { error = JSON.stringify({ name: err.name, message: err.message, diff --git a/test/e2e/client.babel.spec.ts b/test/e2e/client.babel.spec.ts index b1175c358..41110aa1b 100644 --- a/test/e2e/client.babel.spec.ts +++ b/test/e2e/client.babel.spec.ts @@ -24,20 +24,24 @@ describe('client.babel', () => { it('requests token', async () => { await browser.exposeFunction('tokenRequest', jest.fn().mockResolvedValue('MY_TOKEN')); const result = await browser.evaluate(async () => { - const { ApiClient } = (window as any).api; + // @ts-ignore + const { ApiClient } = window.api; const client = new ApiClient({ - TOKEN: (window as any).tokenRequest, + // @ts-ignore + TOKEN: window.tokenRequest, USERNAME: undefined, PASSWORD: undefined, }); return await client.simple.getCallWithoutParametersAndResponse(); }); + // @ts-ignore expect(result.headers.authorization).toBe('Bearer MY_TOKEN'); }); it('uses credentials', async () => { const result = await browser.evaluate(async () => { - const { ApiClient } = (window as any).api; + // @ts-ignore + const { ApiClient } = window.api; const client = new ApiClient({ TOKEN: undefined, USERNAME: 'username', @@ -45,12 +49,14 @@ describe('client.babel', () => { }); return await client.simple.getCallWithoutParametersAndResponse(); }); + // @ts-ignore expect(result.headers.authorization).toBe('Basic dXNlcm5hbWU6cGFzc3dvcmQ='); }); it('supports complex params', async () => { const result = await browser.evaluate(async () => { - const { ApiClient } = (window as any).api; + // @ts-ignore + const { ApiClient } = window.api; const client = new ApiClient(); return await client.complex.complexTypes({ parameterObject: { @@ -67,7 +73,8 @@ describe('client.babel', () => { it('support form data', async () => { const result = await browser.evaluate(async () => { - const { ApiClient } = (window as any).api; + // @ts-ignore + const { ApiClient } = window.api; const client = new ApiClient(); return await client.parameters.callWithParameters({ parameterHeader: 'valueHeader', @@ -87,7 +94,8 @@ describe('client.babel', () => { let error; try { await browser.evaluate(async () => { - const { ApiClient } = (window as any).api; + // @ts-ignore + const { ApiClient } = window.api; const client = new ApiClient(); const promise = client.simple.getCallWithoutParametersAndResponse(); setTimeout(() => { @@ -104,13 +112,13 @@ describe('client.babel', () => { it('should throw known error (500)', async () => { const error = await browser.evaluate(async () => { try { - const { ApiClient } = (window as any).api; + // @ts-ignore + const { ApiClient } = window.api; const client = new ApiClient(); await client.error.testErrorCode({ status: 500, }); - } catch (e) { - const error = e as any; + } catch (error) { return JSON.stringify({ name: error.name, message: error.message, @@ -140,13 +148,13 @@ describe('client.babel', () => { it('should throw unknown error (409)', async () => { const error = await browser.evaluate(async () => { try { - const { ApiClient } = (window as any).api; + // @ts-ignore + const { ApiClient } = window.api; const client = new ApiClient(); await client.error.testErrorCode({ status: 409, }); - } catch (e) { - const error = e as any; + } catch (error) { return JSON.stringify({ name: error.name, message: error.message, diff --git a/test/e2e/client.fetch.spec.ts b/test/e2e/client.fetch.spec.ts index 0c7c645cc..82832faaa 100644 --- a/test/e2e/client.fetch.spec.ts +++ b/test/e2e/client.fetch.spec.ts @@ -24,20 +24,24 @@ describe('client.fetch', () => { it('requests token', async () => { await browser.exposeFunction('tokenRequest', jest.fn().mockResolvedValue('MY_TOKEN')); const result = await browser.evaluate(async () => { - const { ApiClient } = (window as any).api; + // @ts-ignore + const { ApiClient } = window.api; const client = new ApiClient({ - TOKEN: (window as any).tokenRequest, + // @ts-ignore + TOKEN: window.tokenRequest, USERNAME: undefined, PASSWORD: undefined, }); return await client.simple.getCallWithoutParametersAndResponse(); }); + // @ts-ignore expect(result.headers.authorization).toBe('Bearer MY_TOKEN'); }); it('uses credentials', async () => { const result = await browser.evaluate(async () => { - const { ApiClient } = (window as any).api; + // @ts-ignore + const { ApiClient } = window.api; const client = new ApiClient({ TOKEN: undefined, USERNAME: 'username', @@ -45,12 +49,14 @@ describe('client.fetch', () => { }); return await client.simple.getCallWithoutParametersAndResponse(); }); + // @ts-ignore expect(result.headers.authorization).toBe('Basic dXNlcm5hbWU6cGFzc3dvcmQ='); }); it('supports complex params', async () => { const result = await browser.evaluate(async () => { - const { ApiClient } = (window as any).api; + // @ts-ignore + const { ApiClient } = window.api; const client = new ApiClient(); return await client.complex.complexTypes({ first: { @@ -65,7 +71,8 @@ describe('client.fetch', () => { it('support form data', async () => { const result = await browser.evaluate(async () => { - const { ApiClient } = (window as any).api; + // @ts-ignore + const { ApiClient } = window.api; const client = new ApiClient(); return await client.parameters.callWithParameters( 'valueHeader', @@ -85,7 +92,8 @@ describe('client.fetch', () => { let error; try { await browser.evaluate(async () => { - const { ApiClient } = (window as any).api; + // @ts-ignore + const { ApiClient } = window.api; const client = new ApiClient(); const promise = client.simple.getCallWithoutParametersAndResponse(); setTimeout(() => { @@ -102,11 +110,11 @@ describe('client.fetch', () => { it('should throw known error (500)', async () => { const error = await browser.evaluate(async () => { try { - const { ApiClient } = (window as any).api; + // @ts-ignore + const { ApiClient } = window.api; const client = new ApiClient(); await client.error.testErrorCode(500); - } catch (e) { - const error = e as any; + } catch (error) { return JSON.stringify({ name: error.name, message: error.message, @@ -137,11 +145,11 @@ describe('client.fetch', () => { it('should throw unknown error (409)', async () => { const error = await browser.evaluate(async () => { try { - const { ApiClient } = (window as any).api; + // @ts-ignore + const { ApiClient } = window.api; const client = new ApiClient(); await client.error.testErrorCode(409); - } catch (e) { - const error = e as any; + } catch (error) { return JSON.stringify({ name: error.name, message: error.message, diff --git a/test/e2e/client.node.spec.ts b/test/e2e/client.node.spec.ts index 2af97fac2..79a628204 100644 --- a/test/e2e/client.node.spec.ts +++ b/test/e2e/client.node.spec.ts @@ -90,8 +90,7 @@ describe('client.node', () => { const { ApiClient } = require('./generated/client/node/index.js'); const client = new ApiClient(); await client.error.testErrorCode(500); - } catch (e) { - const err = e as any; + } catch (err) { error = JSON.stringify({ name: err.name, message: err.message, @@ -122,8 +121,7 @@ describe('client.node', () => { const { ApiClient } = require('./generated/client/node/index.js'); const client = new ApiClient(); await client.error.testErrorCode(409); - } catch (e) { - const err = e as any; + } catch (err) { error = JSON.stringify({ name: err.name, message: err.message, diff --git a/test/e2e/client.xhr.spec.ts b/test/e2e/client.xhr.spec.ts index f90177d31..771138319 100644 --- a/test/e2e/client.xhr.spec.ts +++ b/test/e2e/client.xhr.spec.ts @@ -24,20 +24,24 @@ describe('client.xhr', () => { it('requests token', async () => { await browser.exposeFunction('tokenRequest', jest.fn().mockResolvedValue('MY_TOKEN')); const result = await browser.evaluate(async () => { - const { ApiClient } = (window as any).api; + // @ts-ignore + const { ApiClient } = window.api; const client = new ApiClient({ - TOKEN: (window as any).tokenRequest, + // @ts-ignore + TOKEN: window.tokenRequest, USERNAME: undefined, PASSWORD: undefined, }); return await client.simple.getCallWithoutParametersAndResponse(); }); + // @ts-ignore expect(result.headers.authorization).toBe('Bearer MY_TOKEN'); }); it('uses credentials', async () => { const result = await browser.evaluate(async () => { - const { ApiClient } = (window as any).api; + // @ts-ignore + const { ApiClient } = window.api; const client = new ApiClient({ TOKEN: undefined, USERNAME: 'username', @@ -45,12 +49,14 @@ describe('client.xhr', () => { }); return await client.simple.getCallWithoutParametersAndResponse(); }); + // @ts-ignore expect(result.headers.authorization).toBe('Basic dXNlcm5hbWU6cGFzc3dvcmQ='); }); it('supports complex params', async () => { const result = await browser.evaluate(async () => { - const { ApiClient } = (window as any).api; + // @ts-ignore + const { ApiClient } = window.api; const client = new ApiClient(); return await client.complex.complexTypes({ first: { @@ -65,7 +71,8 @@ describe('client.xhr', () => { it('support form data', async () => { const result = await browser.evaluate(async () => { - const { ApiClient } = (window as any).api; + // @ts-ignore + const { ApiClient } = window.api; const client = new ApiClient(); return await client.parameters.callWithParameters( 'valueHeader', @@ -85,7 +92,8 @@ describe('client.xhr', () => { let error; try { await browser.evaluate(async () => { - const { ApiClient } = (window as any).api; + // @ts-ignore + const { ApiClient } = window.api; const client = new ApiClient(); const promise = client.simple.getCallWithoutParametersAndResponse(); setTimeout(() => { @@ -102,11 +110,11 @@ describe('client.xhr', () => { it('should throw known error (500)', async () => { const error = await browser.evaluate(async () => { try { - const { ApiClient } = (window as any).api; + // @ts-ignore + const { ApiClient } = window.api; const client = new ApiClient(); await client.error.testErrorCode(500); - } catch (e) { - const error = e as any; + } catch (error) { return JSON.stringify({ name: error.name, message: error.message, @@ -136,11 +144,11 @@ describe('client.xhr', () => { it('should throw unknown error (409)', async () => { const error = await browser.evaluate(async () => { try { - const { ApiClient } = (window as any).api; + // @ts-ignore + const { ApiClient } = window.api; const client = new ApiClient(); await client.error.testErrorCode(409); - } catch (e) { - const error = e as any; + } catch (error) { return JSON.stringify({ name: error.name, message: error.message, diff --git a/test/e2e/scripts/compileWithTypescript.ts b/test/e2e/scripts/compileWithTypescript.ts index 4a8ab1de5..54f15e644 100644 --- a/test/e2e/scripts/compileWithTypescript.ts +++ b/test/e2e/scripts/compileWithTypescript.ts @@ -45,7 +45,7 @@ export const compileWithTypescript = (dir: string) => { const compiler = createProgram(configFileResult.fileNames, configFileResult.options, compilerHost); const result = compiler.emit(); - // Show errors or warnings (if any) + // Show errors or warnings const diagnostics = getPreEmitDiagnostics(compiler).concat(result.diagnostics); if (diagnostics.length) { const message = formatDiagnosticsWithColorAndContext(diagnostics, { diff --git a/test/e2e/scripts/generateClient.ts b/test/e2e/scripts/generateClient.ts index 5c65251fd..d4163427a 100644 --- a/test/e2e/scripts/generateClient.ts +++ b/test/e2e/scripts/generateClient.ts @@ -8,10 +8,10 @@ export const generateClient = async ( clientName?: string ) => { await __generate({ + client, + clientName, input: `./test/spec/${version}.json`, output: `./test/e2e/generated/${dir}/`, - httpClient: client, useOptions, - clientName, }); }; diff --git a/test/e2e/v2.angular.spec.ts b/test/e2e/v2.angular.spec.ts index f9d761b9b..90d040559 100644 --- a/test/e2e/v2.angular.spec.ts +++ b/test/e2e/v2.angular.spec.ts @@ -24,29 +24,35 @@ describe('v2.angular', () => { it('requests token', async () => { await browser.exposeFunction('tokenRequest', jest.fn().mockResolvedValue('MY_TOKEN')); - const result = await browser.evaluate(async () => { - return await new Promise(resolve => { - const { OpenAPI, SimpleService } = (window as any).api; - OpenAPI.TOKEN = (window as any).tokenRequest; - SimpleService.getCallWithoutParametersAndResponse().subscribe(resolve); - }); - }); + const result = await browser.evaluate( + async () => + await new Promise(resolve => { + // @ts-ignore + const { OpenAPI, SimpleService } = window.api; + // @ts-ignore + OpenAPI.TOKEN = window.tokenRequest; + SimpleService.getCallWithoutParametersAndResponse().subscribe(resolve); + }) + ); + // @ts-ignore expect(result.headers.authorization).toBe('Bearer MY_TOKEN'); }); it('supports complex params', async () => { - const result = await browser.evaluate(async () => { - return await new Promise(resolve => { - const { ComplexService } = (window as any).api; - ComplexService.complexTypes({ - first: { - second: { - third: 'Hello World!', + const result = await browser.evaluate( + async () => + await new Promise(resolve => { + // @ts-ignore + const { ComplexService } = window.api; + ComplexService.complexTypes({ + first: { + second: { + third: 'Hello World!', + }, }, - }, - }).subscribe(resolve); - }); - }); + }).subscribe(resolve); + }) + ); expect(result).toBeDefined(); }); }); diff --git a/test/e2e/v2.babel.spec.ts b/test/e2e/v2.babel.spec.ts index 1bfd9e0ca..4821a4452 100644 --- a/test/e2e/v2.babel.spec.ts +++ b/test/e2e/v2.babel.spec.ts @@ -24,16 +24,20 @@ describe('v2.babel', () => { it('requests token', async () => { await browser.exposeFunction('tokenRequest', jest.fn().mockResolvedValue('MY_TOKEN')); const result = await browser.evaluate(async () => { - const { OpenAPI, SimpleService } = (window as any).api; - OpenAPI.TOKEN = (window as any).tokenRequest; + // @ts-ignore + const { OpenAPI, SimpleService } = window.api; + // @ts-ignore + OpenAPI.TOKEN = window.tokenRequest; return await SimpleService.getCallWithoutParametersAndResponse(); }); + // @ts-ignore expect(result.headers.authorization).toBe('Bearer MY_TOKEN'); }); it('supports complex params', async () => { const result = await browser.evaluate(async () => { - const { ComplexService } = (window as any).api; + // @ts-ignore + const { ComplexService } = window.api; return await ComplexService.complexTypes({ parameterObject: { first: { @@ -66,29 +70,35 @@ describe('v2.babel useOptions', () => { it('returns result body by default', async () => { const result = await browser.evaluate(async () => { - const { SimpleService } = (window as any).api; + // @ts-ignore + const { SimpleService } = window.api; return await SimpleService.getCallWithoutParametersAndResponse(); }); + // @ts-ignore expect(result.body).toBeUndefined(); }); it('returns result body', async () => { const result = await browser.evaluate(async () => { - const { SimpleService } = (window as any).api; + // @ts-ignore + const { SimpleService } = window.api; return await SimpleService.getCallWithoutParametersAndResponse({ _result: 'body', }); }); + // @ts-ignore expect(result.body).toBeUndefined(); }); it('returns raw result', async () => { const result = await browser.evaluate(async () => { - const { SimpleService } = (window as any).api; + // @ts-ignore + const { SimpleService } = window.api; return await SimpleService.getCallWithoutParametersAndResponse({ _result: 'raw', }); }); + // @ts-ignore expect(result.body).not.toBeUndefined(); }); }); diff --git a/test/e2e/v2.fetch.spec.ts b/test/e2e/v2.fetch.spec.ts index 94f052460..f680dc07d 100644 --- a/test/e2e/v2.fetch.spec.ts +++ b/test/e2e/v2.fetch.spec.ts @@ -24,16 +24,20 @@ describe('v2.fetch', () => { it('requests token', async () => { await browser.exposeFunction('tokenRequest', jest.fn().mockResolvedValue('MY_TOKEN')); const result = await browser.evaluate(async () => { - const { OpenAPI, SimpleService } = (window as any).api; - OpenAPI.TOKEN = (window as any).tokenRequest; + // @ts-ignore + const { OpenAPI, SimpleService } = window.api; + // @ts-ignore + OpenAPI.TOKEN = window.tokenRequest; return await SimpleService.getCallWithoutParametersAndResponse(); }); + // @ts-ignore expect(result.headers.authorization).toBe('Bearer MY_TOKEN'); }); it('supports complex params', async () => { const result = await browser.evaluate(async () => { - const { ComplexService } = (window as any).api; + // @ts-ignore + const { ComplexService } = window.api; return await ComplexService.complexTypes({ first: { second: { @@ -64,29 +68,35 @@ describe('v2.fetch useOptions', () => { it('returns result body by default', async () => { const result = await browser.evaluate(async () => { - const { SimpleService } = (window as any).api; + // @ts-ignore + const { SimpleService } = window.api; return await SimpleService.getCallWithoutParametersAndResponse(); }); + // @ts-ignore expect(result.body).toBeUndefined(); }); it('returns result body', async () => { const result = await browser.evaluate(async () => { - const { SimpleService } = (window as any).api; + // @ts-ignore + const { SimpleService } = window.api; return await SimpleService.getCallWithoutParametersAndResponse({ _result: 'body', }); }); + // @ts-ignore expect(result.body).toBeUndefined(); }); it('returns raw result', async () => { const result = await browser.evaluate(async () => { - const { SimpleService } = (window as any).api; + // @ts-ignore + const { SimpleService } = window.api; return await SimpleService.getCallWithoutParametersAndResponse({ _result: 'raw', }); }); + // @ts-ignore expect(result.body).not.toBeUndefined(); }); }); diff --git a/test/e2e/v2.xhr.spec.ts b/test/e2e/v2.xhr.spec.ts index 25f761dd8..8554f605d 100644 --- a/test/e2e/v2.xhr.spec.ts +++ b/test/e2e/v2.xhr.spec.ts @@ -24,16 +24,20 @@ describe('v2.xhr', () => { it('requests token', async () => { await browser.exposeFunction('tokenRequest', jest.fn().mockResolvedValue('MY_TOKEN')); const result = await browser.evaluate(async () => { - const { OpenAPI, SimpleService } = (window as any).api; - OpenAPI.TOKEN = (window as any).tokenRequest; + // @ts-ignore + const { OpenAPI, SimpleService } = window.api; + // @ts-ignore + OpenAPI.TOKEN = window.tokenRequest; return await SimpleService.getCallWithoutParametersAndResponse(); }); + // @ts-ignore expect(result.headers.authorization).toBe('Bearer MY_TOKEN'); }); it('supports complex params', async () => { const result = await browser.evaluate(async () => { - const { ComplexService } = (window as any).api; + // @ts-ignore + const { ComplexService } = window.api; return await ComplexService.complexTypes({ first: { second: { @@ -64,29 +68,35 @@ describe('v2.xhr useOptions', () => { it('returns result body by default', async () => { const result = await browser.evaluate(async () => { - const { SimpleService } = (window as any).api; + // @ts-ignore + const { SimpleService } = window.api; return await SimpleService.getCallWithoutParametersAndResponse(); }); + // @ts-ignore expect(result.body).toBeUndefined(); }); it('returns result body', async () => { const result = await browser.evaluate(async () => { - const { SimpleService } = (window as any).api; + // @ts-ignore + const { SimpleService } = window.api; return await SimpleService.getCallWithoutParametersAndResponse({ _result: 'body', }); }); + // @ts-ignore expect(result.body).toBeUndefined(); }); it('returns raw result', async () => { const result = await browser.evaluate(async () => { - const { SimpleService } = (window as any).api; + // @ts-ignore + const { SimpleService } = window.api; return await SimpleService.getCallWithoutParametersAndResponse({ _result: 'raw', }); }); + // @ts-ignore expect(result.body).not.toBeUndefined(); }); }); diff --git a/test/e2e/v3.angular.spec.ts b/test/e2e/v3.angular.spec.ts index b0d0fb104..6034839db 100644 --- a/test/e2e/v3.angular.spec.ts +++ b/test/e2e/v3.angular.spec.ts @@ -24,75 +24,86 @@ describe('v3.angular', () => { it('requests token', async () => { await browser.exposeFunction('tokenRequest', jest.fn().mockResolvedValue('MY_TOKEN')); - const result = await browser.evaluate(async () => { - return await new Promise(resolve => { - const { OpenAPI, SimpleService } = (window as any).api; - OpenAPI.TOKEN = (window as any).tokenRequest; - OpenAPI.USERNAME = undefined; - OpenAPI.PASSWORD = undefined; - SimpleService.getCallWithoutParametersAndResponse().subscribe(resolve); - }); - }); + const result = await browser.evaluate( + async () => + await new Promise(resolve => { + // @ts-ignore + const { OpenAPI, SimpleService } = window.api; + // @ts-ignore + OpenAPI.TOKEN = window.tokenRequest; + OpenAPI.USERNAME = undefined; + OpenAPI.PASSWORD = undefined; + SimpleService.getCallWithoutParametersAndResponse().subscribe(resolve); + }) + ); + // @ts-ignore expect(result.headers.authorization).toBe('Bearer MY_TOKEN'); }); it('uses credentials', async () => { - const result = await browser.evaluate(async () => { - return await new Promise(resolve => { - const { OpenAPI, SimpleService } = (window as any).api; - OpenAPI.TOKEN = undefined; - OpenAPI.USERNAME = 'username'; - OpenAPI.PASSWORD = 'password'; - SimpleService.getCallWithoutParametersAndResponse().subscribe(resolve); - }); - }); + const result = await browser.evaluate( + async () => + await new Promise(resolve => { + // @ts-ignore + const { OpenAPI, SimpleService } = window.api; + OpenAPI.TOKEN = undefined; + OpenAPI.USERNAME = 'username'; + OpenAPI.PASSWORD = 'password'; + SimpleService.getCallWithoutParametersAndResponse().subscribe(resolve); + }) + ); + // @ts-ignore expect(result.headers.authorization).toBe('Basic dXNlcm5hbWU6cGFzc3dvcmQ='); }); it('supports complex params', async () => { - const result = await browser.evaluate(async () => { - return await new Promise(resolve => { - const { ComplexService } = (window as any).api; - ComplexService.complexTypes({ - first: { - second: { - third: 'Hello World!', + const result = await browser.evaluate( + async () => + await new Promise(resolve => { + // @ts-ignore + const { ComplexService } = window.api; + ComplexService.complexTypes({ + first: { + second: { + third: 'Hello World!', + }, }, - }, - }).subscribe(resolve); - }); - }); + }).subscribe(resolve); + }) + ); expect(result).toBeDefined(); }); it('support form data', async () => { - const result = await browser.evaluate(async () => { - return await new Promise(resolve => { - const { ParametersService } = (window as any).api; - ParametersService.callWithParameters( - 'valueHeader', - 'valueQuery', - 'valueForm', - 'valueCookie', - 'valuePath', - { - prop: 'valueBody', - } - ).subscribe(resolve); - }); - }); + const result = await browser.evaluate( + async () => + await new Promise(resolve => { + // @ts-ignore + const { ParametersService } = window.api; + ParametersService.callWithParameters( + 'valueHeader', + 'valueQuery', + 'valueForm', + 'valueCookie', + 'valuePath', + { + prop: 'valueBody', + } + ).subscribe(resolve); + }) + ); expect(result).toBeDefined(); }); it('should throw known error (500)', async () => { const error = await browser.evaluate(async () => { try { - await new Promise((resolve, reject) => { - const { ErrorService } = (window as any).api; + await new Promise((resolve, reject) => { + // @ts-ignore + const { ErrorService } = window.api; ErrorService.testErrorCode(500).subscribe(resolve, reject); }); - } catch (e) { - const error = e as any; + } catch (error) { return JSON.stringify({ name: error.name, message: error.message, @@ -121,15 +132,15 @@ describe('v3.angular', () => { it('should throw unknown error (409)', async () => { const error = await browser.evaluate(async () => { - const { ErrorService } = (window as any).api; + // @ts-ignore + const { ErrorService } = window.api; ErrorService.testErrorCode(409).subscribe(console.log, console.log); try { - await new Promise((resolve, reject) => { - // const { ErrorService } = (window as any).api; + await new Promise((resolve, reject) => { + // const { ErrorService } = window.api; ErrorService.testErrorCode(409).subscribe(resolve, reject); }); - } catch (e) { - const error = e as any; + } catch (error) { return JSON.stringify({ name: error.name, message: error.message, diff --git a/test/e2e/v3.axios.spec.ts b/test/e2e/v3.axios.spec.ts index 108a69aaa..6c13eeda7 100644 --- a/test/e2e/v3.axios.spec.ts +++ b/test/e2e/v3.axios.spec.ts @@ -82,8 +82,7 @@ describe('v3.axios', () => { try { const { ErrorService } = require('./generated/v3/axios/index.js'); await ErrorService.testErrorCode(500); - } catch (e) { - const err = e as any; + } catch (err) { error = JSON.stringify({ name: err.name, message: err.message, @@ -113,8 +112,7 @@ describe('v3.axios', () => { try { const { ErrorService } = require('./generated/v3/axios/index.js'); await ErrorService.testErrorCode(409); - } catch (e) { - const err = e as any; + } catch (err) { error = JSON.stringify({ name: err.name, message: err.message, @@ -142,12 +140,12 @@ describe('v3.axios', () => { it('it should parse query params', async () => { const { ParametersService } = require('./generated/v3/axios/index.js'); - const result = (await ParametersService.postCallWithOptionalParam({ + const result = await ParametersService.postCallWithOptionalParam({ page: 0, size: 1, sort: ['location'], - })) as Promise; - expect((result as any).query).toStrictEqual({ parameter: { page: '0', size: '1', sort: 'location' } }); + }); + expect(result.query).toStrictEqual({ parameter: { page: '0', size: '1', sort: 'location' } }); }); }); diff --git a/test/e2e/v3.babel.spec.ts b/test/e2e/v3.babel.spec.ts index 4b8984697..9b347d089 100644 --- a/test/e2e/v3.babel.spec.ts +++ b/test/e2e/v3.babel.spec.ts @@ -24,29 +24,35 @@ describe('v3.babel', () => { it('requests token', async () => { await browser.exposeFunction('tokenRequest', jest.fn().mockResolvedValue('MY_TOKEN')); const result = await browser.evaluate(async () => { - const { OpenAPI, SimpleService } = (window as any).api; - OpenAPI.TOKEN = (window as any).tokenRequest; + // @ts-ignore + const { OpenAPI, SimpleService } = window.api; + // @ts-ignore + OpenAPI.TOKEN = window.tokenRequest; OpenAPI.USERNAME = undefined; OpenAPI.PASSWORD = undefined; return await SimpleService.getCallWithoutParametersAndResponse(); }); + // @ts-ignore expect(result.headers.authorization).toBe('Bearer MY_TOKEN'); }); it('uses credentials', async () => { const result = await browser.evaluate(async () => { - const { OpenAPI, SimpleService } = (window as any).api; + // @ts-ignore + const { OpenAPI, SimpleService } = window.api; OpenAPI.TOKEN = undefined; OpenAPI.USERNAME = 'username'; OpenAPI.PASSWORD = 'password'; return await SimpleService.getCallWithoutParametersAndResponse(); }); + // @ts-ignore expect(result.headers.authorization).toBe('Basic dXNlcm5hbWU6cGFzc3dvcmQ='); }); it('supports complex params', async () => { const result = await browser.evaluate(async () => { - const { ComplexService } = (window as any).api; + // @ts-ignore + const { ComplexService } = window.api; return await ComplexService.complexTypes({ parameterObject: { first: { @@ -62,7 +68,8 @@ describe('v3.babel', () => { it('support form data', async () => { const result = await browser.evaluate(async () => { - const { ParametersService } = (window as any).api; + // @ts-ignore + const { ParametersService } = window.api; return await ParametersService.callWithParameters({ parameterHeader: 'valueHeader', parameterQuery: 'valueQuery', @@ -81,7 +88,8 @@ describe('v3.babel', () => { let error; try { await browser.evaluate(async () => { - const { SimpleService } = (window as any).api; + // @ts-ignore + const { SimpleService } = window.api; const promise = SimpleService.getCallWithoutParametersAndResponse(); setTimeout(() => { promise.cancel(); @@ -97,12 +105,12 @@ describe('v3.babel', () => { it('should throw known error (500)', async () => { const error = await browser.evaluate(async () => { try { - const { ErrorService } = (window as any).api; + // @ts-ignore + const { ErrorService } = window.api; await ErrorService.testErrorCode({ status: 500, }); - } catch (e) { - const error = e as any; + } catch (error) { return JSON.stringify({ name: error.name, message: error.message, @@ -133,12 +141,12 @@ describe('v3.babel', () => { it('should throw unknown error (409)', async () => { const error = await browser.evaluate(async () => { try { - const { ErrorService } = (window as any).api; + // @ts-ignore + const { ErrorService } = window.api; await ErrorService.testErrorCode({ status: 409, }); - } catch (e) { - const error = e as any; + } catch (error) { return JSON.stringify({ name: error.name, message: error.message, @@ -168,15 +176,17 @@ describe('v3.babel', () => { it('it should parse query params', async () => { const result = await browser.evaluate(async () => { - const { ParametersService } = (window as any).api; - return (await ParametersService.postCallWithOptionalParam({ + // @ts-ignore + const { ParametersService } = window.api; + return await ParametersService.postCallWithOptionalParam({ parameter: { page: 0, size: 1, sort: ['location'], }, - })) as Promise; + }); }); + // @ts-ignore expect(result.query).toStrictEqual({ parameter: { page: '0', size: '1', sort: 'location' } }); }); }); @@ -199,29 +209,35 @@ describe('v3.babel useOptions', () => { it('returns result body by default', async () => { const result = await browser.evaluate(async () => { - const { SimpleService } = (window as any).api; + // @ts-ignore + const { SimpleService } = window.api; return await SimpleService.getCallWithoutParametersAndResponse(); }); + // @ts-ignore expect(result.body).toBeUndefined(); }); it('returns result body', async () => { const result = await browser.evaluate(async () => { - const { SimpleService } = (window as any).api; + // @ts-ignore + const { SimpleService } = window.api; return await SimpleService.getCallWithoutParametersAndResponse({ _result: 'body', }); }); + // @ts-ignore expect(result.body).toBeUndefined(); }); it('returns raw result', async () => { const result = await browser.evaluate(async () => { - const { SimpleService } = (window as any).api; + // @ts-ignore + const { SimpleService } = window.api; return await SimpleService.getCallWithoutParametersAndResponse({ _result: 'raw', }); }); + // @ts-ignore expect(result.body).not.toBeUndefined(); }); }); diff --git a/test/e2e/v3.fetch.spec.ts b/test/e2e/v3.fetch.spec.ts index 5b39ab9c4..84d9277a1 100644 --- a/test/e2e/v3.fetch.spec.ts +++ b/test/e2e/v3.fetch.spec.ts @@ -24,29 +24,35 @@ describe('v3.fetch', () => { it('requests token', async () => { await browser.exposeFunction('tokenRequest', jest.fn().mockResolvedValue('MY_TOKEN')); const result = await browser.evaluate(async () => { - const { OpenAPI, SimpleService } = (window as any).api; - OpenAPI.TOKEN = (window as any).tokenRequest; + // @ts-ignore + const { OpenAPI, SimpleService } = window.api; + // @ts-ignore + OpenAPI.TOKEN = window.tokenRequest; OpenAPI.USERNAME = undefined; OpenAPI.PASSWORD = undefined; return await SimpleService.getCallWithoutParametersAndResponse(); }); + // @ts-ignore expect(result.headers.authorization).toBe('Bearer MY_TOKEN'); }); it('uses credentials', async () => { const result = await browser.evaluate(async () => { - const { OpenAPI, SimpleService } = (window as any).api; + // @ts-ignore + const { OpenAPI, SimpleService } = window.api; OpenAPI.TOKEN = undefined; OpenAPI.USERNAME = 'username'; OpenAPI.PASSWORD = 'password'; return await SimpleService.getCallWithoutParametersAndResponse(); }); + // @ts-ignore expect(result.headers.authorization).toBe('Basic dXNlcm5hbWU6cGFzc3dvcmQ='); }); it('supports complex params', async () => { const result = await browser.evaluate(async () => { - const { ComplexService } = (window as any).api; + // @ts-ignore + const { ComplexService } = window.api; return await ComplexService.complexTypes({ first: { second: { @@ -60,7 +66,8 @@ describe('v3.fetch', () => { it('support form data', async () => { const result = await browser.evaluate(async () => { - const { ParametersService } = (window as any).api; + // @ts-ignore + const { ParametersService } = window.api; return await ParametersService.callWithParameters( 'valueHeader', 'valueQuery', @@ -77,7 +84,8 @@ describe('v3.fetch', () => { it('support blob response data', async () => { const result = await browser.evaluate(async () => { - const { FileResponseService } = (window as any).api; + // @ts-ignore + const { FileResponseService } = window.api; return await FileResponseService.fileResponse('test'); }); expect(result).toBeDefined(); @@ -87,7 +95,8 @@ describe('v3.fetch', () => { let error; try { await browser.evaluate(async () => { - const { SimpleService } = (window as any).api; + // @ts-ignore + const { SimpleService } = window.api; const promise = SimpleService.getCallWithoutParametersAndResponse(); setTimeout(() => { promise.cancel(); @@ -103,10 +112,10 @@ describe('v3.fetch', () => { it('should throw known error (500)', async () => { const error = await browser.evaluate(async () => { try { - const { ErrorService } = (window as any).api; + // @ts-ignore + const { ErrorService } = window.api; await ErrorService.testErrorCode(500); - } catch (e) { - const error = e as any; + } catch (error) { return JSON.stringify({ name: error.name, message: error.message, @@ -137,10 +146,10 @@ describe('v3.fetch', () => { it('should throw unknown error (409)', async () => { const error = await browser.evaluate(async () => { try { - const { ErrorService } = (window as any).api; + // @ts-ignore + const { ErrorService } = window.api; await ErrorService.testErrorCode(409); - } catch (e) { - const error = e as any; + } catch (error) { return JSON.stringify({ name: error.name, message: error.message, @@ -170,13 +179,15 @@ describe('v3.fetch', () => { it('it should parse query params', async () => { const result = await browser.evaluate(async () => { - const { ParametersService } = (window as any).api; - return (await ParametersService.postCallWithOptionalParam({ + // @ts-ignore + const { ParametersService } = window.api; + return await ParametersService.postCallWithOptionalParam({ page: 0, size: 1, sort: ['location'], - })) as Promise; + }); }); + // @ts-ignore expect(result.query).toStrictEqual({ parameter: { page: '0', size: '1', sort: 'location' } }); }); }); @@ -199,29 +210,35 @@ describe('v3.fetch useOptions', () => { it('returns result body by default', async () => { const result = await browser.evaluate(async () => { - const { SimpleService } = (window as any).api; + // @ts-ignore + const { SimpleService } = window.api; return await SimpleService.getCallWithoutParametersAndResponse(); }); + // @ts-ignore expect(result.body).toBeUndefined(); }); it('returns result body', async () => { const result = await browser.evaluate(async () => { - const { SimpleService } = (window as any).api; + // @ts-ignore + const { SimpleService } = window.api; return await SimpleService.getCallWithoutParametersAndResponse({ _result: 'body', }); }); + // @ts-ignore expect(result.body).toBeUndefined(); }); it('returns raw result', async () => { const result = await browser.evaluate(async () => { - const { SimpleService } = (window as any).api; + // @ts-ignore + const { SimpleService } = window.api; return await SimpleService.getCallWithoutParametersAndResponse({ _result: 'raw', }); }); + // @ts-ignore expect(result.body).not.toBeUndefined(); }); }); diff --git a/test/e2e/v3.node.spec.ts b/test/e2e/v3.node.spec.ts index ad45a26b9..beab3cedc 100644 --- a/test/e2e/v3.node.spec.ts +++ b/test/e2e/v3.node.spec.ts @@ -88,8 +88,7 @@ describe('v3.node', () => { try { const { ErrorService } = require('./generated/v3/node/index.js'); await ErrorService.testErrorCode(500); - } catch (e) { - const err = e as any; + } catch (err) { error = JSON.stringify({ name: err.name, message: err.message, @@ -119,8 +118,7 @@ describe('v3.node', () => { try { const { ErrorService } = require('./generated/v3/node/index.js'); await ErrorService.testErrorCode(409); - } catch (e) { - const err = e as any; + } catch (err) { error = JSON.stringify({ name: err.name, message: err.message, @@ -148,12 +146,12 @@ describe('v3.node', () => { it('it should parse query params', async () => { const { ParametersService } = require('./generated/v3/node/index.js'); - const result = (await ParametersService.postCallWithOptionalParam({ + const result = await ParametersService.postCallWithOptionalParam({ page: 0, size: 1, sort: ['location'], - })) as Promise; - expect((result as any).query).toStrictEqual({ parameter: { page: '0', size: '1', sort: 'location' } }); + }); + expect(result.query).toStrictEqual({ parameter: { page: '0', size: '1', sort: 'location' } }); }); }); diff --git a/test/e2e/v3.xhr.spec.ts b/test/e2e/v3.xhr.spec.ts index 3ef8b853d..be19e27db 100644 --- a/test/e2e/v3.xhr.spec.ts +++ b/test/e2e/v3.xhr.spec.ts @@ -24,29 +24,35 @@ describe('v3.xhr', () => { it('requests token', async () => { await browser.exposeFunction('tokenRequest', jest.fn().mockResolvedValue('MY_TOKEN')); const result = await browser.evaluate(async () => { - const { OpenAPI, SimpleService } = (window as any).api; - OpenAPI.TOKEN = (window as any).tokenRequest; + // @ts-ignore + const { OpenAPI, SimpleService } = window.api; + // @ts-ignore + OpenAPI.TOKEN = window.tokenRequest; OpenAPI.USERNAME = undefined; OpenAPI.PASSWORD = undefined; return await SimpleService.getCallWithoutParametersAndResponse(); }); + // @ts-ignore expect(result.headers.authorization).toBe('Bearer MY_TOKEN'); }); it('uses credentials', async () => { const result = await browser.evaluate(async () => { - const { OpenAPI, SimpleService } = (window as any).api; + // @ts-ignore + const { OpenAPI, SimpleService } = window.api; OpenAPI.TOKEN = undefined; OpenAPI.USERNAME = 'username'; OpenAPI.PASSWORD = 'password'; return await SimpleService.getCallWithoutParametersAndResponse(); }); + // @ts-ignore expect(result.headers.authorization).toBe('Basic dXNlcm5hbWU6cGFzc3dvcmQ='); }); it('supports complex params', async () => { const result = await browser.evaluate(async () => { - const { ComplexService } = (window as any).api; + // @ts-ignore + const { ComplexService } = window.api; return await ComplexService.complexTypes({ first: { second: { @@ -60,7 +66,8 @@ describe('v3.xhr', () => { it('support form data', async () => { const result = await browser.evaluate(async () => { - const { ParametersService } = (window as any).api; + // @ts-ignore + const { ParametersService } = window.api; return await ParametersService.callWithParameters( 'valueHeader', 'valueQuery', @@ -79,7 +86,8 @@ describe('v3.xhr', () => { let error; try { await browser.evaluate(async () => { - const { SimpleService } = (window as any).api; + // @ts-ignore + const { SimpleService } = window.api; const promise = SimpleService.getCallWithoutParametersAndResponse(); setTimeout(() => { promise.cancel(); @@ -95,10 +103,10 @@ describe('v3.xhr', () => { it('should throw known error (500)', async () => { const error = await browser.evaluate(async () => { try { - const { ErrorService } = (window as any).api; + // @ts-ignore + const { ErrorService } = window.api; await ErrorService.testErrorCode(500); - } catch (e) { - const error = e as any; + } catch (error) { return JSON.stringify({ name: error.name, message: error.message, @@ -128,10 +136,10 @@ describe('v3.xhr', () => { it('should throw unknown error (409)', async () => { const error = await browser.evaluate(async () => { try { - const { ErrorService } = (window as any).api; + // @ts-ignore + const { ErrorService } = window.api; await ErrorService.testErrorCode(409); - } catch (e) { - const error = e as any; + } catch (error) { return JSON.stringify({ name: error.name, message: error.message, @@ -161,13 +169,15 @@ describe('v3.xhr', () => { it('it should parse query params', async () => { const result = await browser.evaluate(async () => { - const { ParametersService } = (window as any).api; - return (await ParametersService.postCallWithOptionalParam({ + // @ts-ignore + const { ParametersService } = window.api; + return await ParametersService.postCallWithOptionalParam({ page: 0, size: 1, sort: ['location'], - })) as Promise; + }); }); + // @ts-ignore expect(result.query).toStrictEqual({ parameter: { page: '0', size: '1', sort: 'location' } }); }); }); @@ -190,29 +200,35 @@ describe('v3.xhr useOptions', () => { it('returns result body by default', async () => { const result = await browser.evaluate(async () => { - const { SimpleService } = (window as any).api; + // @ts-ignore + const { SimpleService } = window.api; return await SimpleService.getCallWithoutParametersAndResponse(); }); + // @ts-ignore expect(result.body).toBeUndefined(); }); it('returns result body', async () => { const result = await browser.evaluate(async () => { - const { SimpleService } = (window as any).api; + // @ts-ignore + const { SimpleService } = window.api; return await SimpleService.getCallWithoutParametersAndResponse({ _result: 'body', }); }); + // @ts-ignore expect(result.body).toBeUndefined(); }); it('returns raw result', async () => { const result = await browser.evaluate(async () => { - const { SimpleService } = (window as any).api; + // @ts-ignore + const { SimpleService } = window.api; return await SimpleService.getCallWithoutParametersAndResponse({ _result: 'raw', }); }); + // @ts-ignore expect(result.body).not.toBeUndefined(); }); }); diff --git a/test/index.js b/test/index.js index 0169247c5..001a490fc 100644 --- a/test/index.js +++ b/test/index.js @@ -5,13 +5,13 @@ const fetch = require('node-fetch'); const generate = async (input, output) => { await OpenAPI.generate({ + client: 'fetch', // clientName: 'Demo', enums: true, exportCore: true, exportModels: true, exportSchemas: true, exportServices: true, - httpClient: 'fetch', input, output, postfixModels: '', diff --git a/test/index.spec.ts b/test/index.spec.ts index 31c3b75c8..94456be77 100644 --- a/test/index.spec.ts +++ b/test/index.spec.ts @@ -1,17 +1,17 @@ import { readFileSync } from 'fs'; import { sync } from 'glob'; -import { generate, HttpClient } from '../'; +import { generate } from '../'; describe('v2', () => { it('should generate', async () => { await generate({ + client: 'fetch', enums: true, exportCore: true, exportModels: true, exportSchemas: true, exportServices: true, - httpClient: HttpClient.FETCH, input: './test/spec/v2.json', output: './test/generated/v2/', useOptions: false, @@ -27,12 +27,12 @@ describe('v2', () => { describe('v3', () => { it('should generate', async () => { await generate({ + client: 'fetch', enums: true, exportCore: true, exportModels: true, exportSchemas: true, exportServices: true, - httpClient: HttpClient.FETCH, input: './test/spec/v3.json', output: './test/generated/v3/', useOptions: false, @@ -46,12 +46,12 @@ describe('v3', () => { it('should generate Date types', async () => { await generate({ + client: 'fetch', enums: true, exportCore: false, exportModels: '^ModelWithPattern', exportSchemas: true, exportServices: false, - httpClient: HttpClient.FETCH, input: './test/spec/v3.json', output: './test/generated/v3_date/', useDateType: true, @@ -66,12 +66,12 @@ describe('v3', () => { it('should generate optional argument', async () => { await generate({ + client: 'fetch', enums: true, exportCore: true, exportModels: '^ModelWithString', exportSchemas: false, exportServices: '^Defaults', - httpClient: HttpClient.FETCH, input: './test/spec/v3.json', output: './test/generated/v3_options/', useDateType: true, diff --git a/types/index.d.ts b/types/index.d.ts index b1042f635..7c5b06e44 100644 --- a/types/index.d.ts +++ b/types/index.d.ts @@ -1,11 +1,3 @@ -export declare enum HttpClient { - FETCH = 'fetch', - XHR = 'xhr', - NODE = 'node', - AXIOS = 'axios', - ANGULAR = 'angular', -} - export type ServiceResponse = 'body' | 'generics' | 'response'; export type Options = { @@ -17,6 +9,10 @@ export type Options = { * Manually set base in OpenAPI config instead of inferring from server value */ base?: string; + /** + * The selected HTTP client (fetch, xhr, node or axios) + */ + client?: 'angular' | 'axios' | 'fetch' | 'node' | 'xhr'; /** * Custom client class name */ @@ -41,14 +37,10 @@ export type Options = { * Generate services */ exportServices?: boolean | string; - /** - * The selected httpClient (fetch, xhr, node or axios) - */ - httpClient?: HttpClient | 'fetch' | 'xhr' | 'node' | 'axios' | 'angular'; /** * The relative location of the OpenAPI spec */ - input: string | Record; + input: string | Record; /** * Use operation ID to generate operation names? */ @@ -90,7 +82,6 @@ export type Options = { export declare function generate(options: Options): Promise; declare type OpenAPI = { - HttpClient: HttpClient; generate: typeof generate; };