mirror of
https://github.com/ferdikoomen/openapi-typescript-codegen.git
synced 2025-12-08 20:16:21 +00:00
- Added feature to use union types
This commit is contained in:
parent
7c6a226dee
commit
aa832a71dc
20
README.md
20
README.md
@ -54,10 +54,22 @@ openapi --input ./api/openapi.json --output ./dist
|
||||
```javascript
|
||||
const OpenAPI = require('openapi-typescript-codegen');
|
||||
|
||||
OpenAPI.generate(
|
||||
'./api/openapi.json',
|
||||
'./dist'
|
||||
);
|
||||
OpenAPI.generate({
|
||||
input: './api/openapi.json',
|
||||
output: './dist'
|
||||
});
|
||||
```
|
||||
|
||||
Or by providing the JSON directly:
|
||||
|
||||
```javascript
|
||||
const OpenAPI = require('openapi-typescript-codegen');
|
||||
const spec = require('./api/openapi.json');
|
||||
|
||||
OpenAPI.generate({
|
||||
input: spec,
|
||||
output: './dist'
|
||||
});
|
||||
```
|
||||
|
||||
## Features
|
||||
|
||||
14
bin/index.js
14
bin/index.js
@ -12,15 +12,17 @@ program
|
||||
.option('--output [value]', 'Output directory', './generated')
|
||||
.option('--client [value]', 'HTTP client to generate [fetch, xhr]', 'fetch')
|
||||
.option('--useOptions', 'Use options vs arguments style functions', false)
|
||||
.option('--useUnionTypes', 'Use inclusive union types', false)
|
||||
.parse(process.argv);
|
||||
|
||||
const OpenAPI = require(path.resolve(__dirname, '../dist/index.js'));
|
||||
|
||||
if (OpenAPI) {
|
||||
OpenAPI.generate(
|
||||
program.input,
|
||||
program.output,
|
||||
program.client,
|
||||
program.useOptions
|
||||
);
|
||||
OpenAPI.generate({
|
||||
input: program.input,
|
||||
output: program.output,
|
||||
httpClient: program.client,
|
||||
useOptions: program.useOptions,
|
||||
useUnionTypes: program.useUnionTypes
|
||||
});
|
||||
}
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "openapi-typescript-codegen",
|
||||
"version": "0.1.17",
|
||||
"version": "0.2.3",
|
||||
"description": "NodeJS library that generates Typescript or Javascript clients based on the OpenAPI specification.",
|
||||
"author": "Ferdi Koomen",
|
||||
"homepage": "https://github.com/ferdikoomen/openapi-typescript-codegen",
|
||||
|
||||
2
src/client/interfaces/Model.d.ts
vendored
2
src/client/interfaces/Model.d.ts
vendored
@ -15,4 +15,6 @@ export interface Model extends Schema {
|
||||
enum: Enum[];
|
||||
enums: Model[];
|
||||
properties: Model[];
|
||||
extendedFrom?: string[];
|
||||
extendedBy?: string[];
|
||||
}
|
||||
|
||||
1
src/client/interfaces/OperationResponse.d.ts
vendored
1
src/client/interfaces/OperationResponse.d.ts
vendored
@ -1,5 +1,6 @@
|
||||
import { Model } from './Model';
|
||||
|
||||
export interface OperationResponse extends Model {
|
||||
in: 'response' | 'header';
|
||||
code: number;
|
||||
}
|
||||
|
||||
2
src/client/interfaces/Schema.d.ts
vendored
2
src/client/interfaces/Schema.d.ts
vendored
@ -1,5 +1,5 @@
|
||||
export interface Schema {
|
||||
isProperty: boolean;
|
||||
isDefinition: boolean;
|
||||
isReadOnly: boolean;
|
||||
isRequired: boolean;
|
||||
isNullable: boolean;
|
||||
|
||||
@ -2,10 +2,18 @@ import * as OpenAPI from '.';
|
||||
|
||||
describe('index', () => {
|
||||
it('parses v2 without issues', () => {
|
||||
OpenAPI.generate('./test/mock/v2/spec.json', './test/result/v2/', OpenAPI.HttpClient.FETCH, false, false);
|
||||
OpenAPI.generate({
|
||||
input: './test/mock/v2/spec.json',
|
||||
output: './test/result/v2/',
|
||||
write: false,
|
||||
});
|
||||
});
|
||||
|
||||
it('parses v3 without issues', () => {
|
||||
OpenAPI.generate('./test/mock/v3/spec.json', './test/result/v3/', OpenAPI.HttpClient.FETCH, false, false);
|
||||
OpenAPI.generate({
|
||||
input: './test/mock/v3/spec.json',
|
||||
output: './test/result/v3/',
|
||||
write: false,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
55
src/index.ts
55
src/index.ts
@ -1,9 +1,9 @@
|
||||
import * as path from 'path';
|
||||
import * as ts from 'typescript';
|
||||
import { OpenApiVersion, getOpenApiVersion } from './utils/getOpenApiVersion';
|
||||
import { getOpenApiSpec } from './utils/getOpenApiSpec';
|
||||
import { isString } from './utils/isString';
|
||||
import { parse as parseV2 } from './openApi/v2';
|
||||
import { parse as parseV3 } from './openApi/v3';
|
||||
import { postProcessClient } from './utils/postProcessClient';
|
||||
import { readHandlebarsTemplates } from './utils/readHandlebarsTemplates';
|
||||
import { writeClient } from './utils/writeClient';
|
||||
|
||||
@ -12,6 +12,15 @@ export enum HttpClient {
|
||||
XHR = 'xhr',
|
||||
}
|
||||
|
||||
export interface Options {
|
||||
input: string | Record<string, any>;
|
||||
output: string;
|
||||
httpClient?: HttpClient;
|
||||
useOptions?: boolean;
|
||||
useUnionTypes?: boolean;
|
||||
write?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate the OpenAPI client. This method will read the OpenAPI specification and based on the
|
||||
* given language it will generate the client, including the typed models, validation schemas,
|
||||
@ -20,52 +29,38 @@ export enum HttpClient {
|
||||
* @param output The relative location of the output directory.
|
||||
* @param httpClient The selected httpClient (fetch or XHR).
|
||||
* @param useOptions Use options or arguments functions.
|
||||
* @param write Write the files to disk (true or false)
|
||||
* @param useUnionTypes Use inclusive union types.
|
||||
* @param write Write the files to disk (true or false).
|
||||
*/
|
||||
export function generate(input: string, output: string, httpClient: HttpClient = HttpClient.FETCH, useOptions: boolean = false, write: boolean = true): void {
|
||||
const inputPath = path.resolve(process.cwd(), input);
|
||||
const outputPath = path.resolve(process.cwd(), output);
|
||||
|
||||
export function generate({ input, output, httpClient = HttpClient.FETCH, useOptions = false, useUnionTypes = false, write = true }: Options): void {
|
||||
try {
|
||||
// Load the specification, read the OpenAPI version and load the
|
||||
// handlebar templates for the given language
|
||||
const openApi = getOpenApiSpec(inputPath);
|
||||
const openApi = isString(input) ? getOpenApiSpec(input) : input;
|
||||
const openApiVersion = getOpenApiVersion(openApi);
|
||||
const templates = readHandlebarsTemplates();
|
||||
|
||||
switch (openApiVersion) {
|
||||
case OpenApiVersion.V2:
|
||||
const clientV2 = parseV2(openApi);
|
||||
case OpenApiVersion.V2: {
|
||||
const client = parseV2(openApi);
|
||||
const clientFinal = postProcessClient(client, useUnionTypes);
|
||||
if (write) {
|
||||
writeClient(clientV2, httpClient, templates, outputPath, useOptions);
|
||||
writeClient(clientFinal, templates, output, httpClient, useOptions);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case OpenApiVersion.V3:
|
||||
const clientV3 = parseV3(openApi);
|
||||
case OpenApiVersion.V3: {
|
||||
const client = parseV3(openApi);
|
||||
const clientFinal = postProcessClient(client, useUnionTypes);
|
||||
if (write) {
|
||||
writeClient(clientV3, httpClient, templates, outputPath, useOptions);
|
||||
writeClient(clientFinal, templates, output, httpClient, useOptions);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
export function compile(dir: string): void {
|
||||
const config = {
|
||||
compilerOptions: {
|
||||
target: 'esnext',
|
||||
module: 'commonjs',
|
||||
moduleResolution: 'node',
|
||||
},
|
||||
include: ['./index.ts'],
|
||||
};
|
||||
const configFile = ts.parseConfigFileTextToJson('tsconfig.json', JSON.stringify(config));
|
||||
const configFileResult = ts.parseJsonConfigFileContent(configFile.config, ts.sys, path.resolve(process.cwd(), dir), undefined, 'tsconfig.json');
|
||||
const compilerHost = ts.createCompilerHost(configFileResult.options);
|
||||
const compiler = ts.createProgram(configFileResult.fileNames, configFileResult.options, compilerHost);
|
||||
compiler.emit();
|
||||
}
|
||||
|
||||
@ -11,10 +11,10 @@ import { getServices } from './parser/getServices';
|
||||
* @param openApi The OpenAPI spec that we have loaded from disk.
|
||||
*/
|
||||
export function parse(openApi: OpenApi): Client {
|
||||
return {
|
||||
version: getServiceVersion(openApi.info.version),
|
||||
server: getServer(openApi),
|
||||
models: getModels(openApi),
|
||||
services: getServices(openApi),
|
||||
};
|
||||
const version = getServiceVersion(openApi.info.version);
|
||||
const server = getServer(openApi);
|
||||
const models = getModels(openApi);
|
||||
const services = getServices(openApi);
|
||||
|
||||
return { version, server, models, services };
|
||||
}
|
||||
|
||||
@ -4,6 +4,12 @@ import { WithEnumExtension } from '../interfaces/Extensions/WithEnumExtension';
|
||||
const KEY_ENUM_NAMES = 'x-enum-varnames';
|
||||
const KEY_ENUM_DESCRIPTIONS = 'x-enum-descriptions';
|
||||
|
||||
/**
|
||||
* Extend the enum with the x-enum properties. This adds the capability
|
||||
* to use names and descriptions inside the generated enums.
|
||||
* @param enumerators
|
||||
* @param definition
|
||||
*/
|
||||
export function extendEnum(enumerators: Enum[], definition: WithEnumExtension): Enum[] {
|
||||
const names = definition[KEY_ENUM_NAMES];
|
||||
const descriptions = definition[KEY_ENUM_DESCRIPTIONS];
|
||||
|
||||
@ -1,5 +1,10 @@
|
||||
import { EOL } from 'os';
|
||||
|
||||
/**
|
||||
* Cleanup comment and prefix multiline comments with "*",
|
||||
* so they look a bit nicer when used in the generated code.
|
||||
* @param comment
|
||||
*/
|
||||
export function getComment(comment?: string): string | null {
|
||||
if (comment) {
|
||||
return comment.replace(/\r?\n(.*)/g, (_, w) => `${EOL} * ${w.trim()}`);
|
||||
|
||||
@ -9,7 +9,7 @@ import { getEnumFromDescription } from './getEnumFromDescription';
|
||||
import { getModelProperties } from './getModelProperties';
|
||||
import { getType } from './getType';
|
||||
|
||||
export function getModel(openApi: OpenApi, definition: OpenApiSchema, isProperty: boolean = false, name: string = ''): Model {
|
||||
export function getModel(openApi: OpenApi, definition: OpenApiSchema, isDefinition: boolean = false, name: string = ''): Model {
|
||||
const model: Model = {
|
||||
name: name,
|
||||
export: 'interface',
|
||||
@ -18,7 +18,7 @@ export function getModel(openApi: OpenApi, definition: OpenApiSchema, isProperty
|
||||
template: null,
|
||||
link: null,
|
||||
description: getComment(definition.description),
|
||||
isProperty: isProperty,
|
||||
isDefinition: isDefinition,
|
||||
isReadOnly: definition.readOnly === true,
|
||||
isNullable: false,
|
||||
isRequired: false,
|
||||
@ -86,7 +86,7 @@ export function getModel(openApi: OpenApi, definition: OpenApiSchema, isProperty
|
||||
model.imports.push(...arrayItems.imports);
|
||||
return model;
|
||||
} else {
|
||||
const arrayItems = getModel(openApi, definition.items, true);
|
||||
const arrayItems = getModel(openApi, definition.items);
|
||||
model.export = 'array';
|
||||
model.type = arrayItems.type;
|
||||
model.base = arrayItems.base;
|
||||
@ -129,7 +129,7 @@ export function getModel(openApi: OpenApi, definition: OpenApiSchema, isProperty
|
||||
definition.allOf.forEach(parent => {
|
||||
if (parent.$ref) {
|
||||
const parentRef = getType(parent.$ref);
|
||||
model.extends.push(parentRef.type);
|
||||
model.extends.push(parentRef.base);
|
||||
model.imports.push(parentRef.base);
|
||||
}
|
||||
if (parent.type === 'object' && parent.properties) {
|
||||
|
||||
@ -21,7 +21,7 @@ export function getModelProperties(openApi: OpenApi, definition: OpenApiSchema):
|
||||
template: model.template,
|
||||
link: null,
|
||||
description: getComment(property.description),
|
||||
isProperty: true,
|
||||
isDefinition: false,
|
||||
isReadOnly: property.readOnly === true,
|
||||
isRequired: propertyRequired === true,
|
||||
isNullable: false,
|
||||
@ -55,7 +55,7 @@ export function getModelProperties(openApi: OpenApi, definition: OpenApiSchema):
|
||||
template: model.template,
|
||||
link: model.link,
|
||||
description: getComment(property.description),
|
||||
isProperty: true,
|
||||
isDefinition: false,
|
||||
isReadOnly: property.readOnly === true,
|
||||
isRequired: propertyRequired === true,
|
||||
isNullable: false,
|
||||
|
||||
@ -4,14 +4,14 @@ import { getModel } from './getModel';
|
||||
import { getType } from './getType';
|
||||
|
||||
export function getModels(openApi: OpenApi): Model[] {
|
||||
const models = new Map<string, Model>();
|
||||
const models: Model[] = [];
|
||||
for (const definitionName in openApi.definitions) {
|
||||
if (openApi.definitions.hasOwnProperty(definitionName)) {
|
||||
const definition = openApi.definitions[definitionName];
|
||||
const definitionType = getType(definitionName);
|
||||
const model = getModel(openApi, definition, false, definitionType.base);
|
||||
models.set(definitionType.base, model);
|
||||
const model = getModel(openApi, definition, true, definitionType.base);
|
||||
models.push(model);
|
||||
}
|
||||
}
|
||||
return Array.from(models.values());
|
||||
return models;
|
||||
}
|
||||
|
||||
@ -22,7 +22,7 @@ export function getOperationParameter(openApi: OpenApi, parameter: OpenApiParame
|
||||
template: null,
|
||||
link: null,
|
||||
description: getComment(parameter.description),
|
||||
isProperty: false,
|
||||
isDefinition: false,
|
||||
isReadOnly: false,
|
||||
isRequired: parameter.required === true,
|
||||
isNullable: false,
|
||||
|
||||
@ -8,6 +8,7 @@ import { getType } from './getType';
|
||||
|
||||
export function getOperationResponse(openApi: OpenApi, response: OpenApiResponse, responseCode: number): OperationResponse {
|
||||
const operationResponse: OperationResponse = {
|
||||
in: 'response',
|
||||
name: '',
|
||||
code: responseCode,
|
||||
description: getComment(response.description)!,
|
||||
@ -16,7 +17,7 @@ export function getOperationResponse(openApi: OpenApi, response: OpenApiResponse
|
||||
base: PrimaryType.OBJECT,
|
||||
template: null,
|
||||
link: null,
|
||||
isProperty: false,
|
||||
isDefinition: false,
|
||||
isReadOnly: false,
|
||||
isRequired: false,
|
||||
isNullable: false,
|
||||
|
||||
@ -18,7 +18,8 @@ export function getOperationResponses(openApi: OpenApi, responses: OpenApiRespon
|
||||
const responseCode = getOperationResponseCode(code);
|
||||
|
||||
if (responseCode) {
|
||||
operationResponses.push(getOperationResponse(openApi, response, responseCode));
|
||||
const operationResponse = getOperationResponse(openApi, response, responseCode);
|
||||
operationResponses.push(operationResponse);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -21,6 +21,7 @@ export function getOperationResults(operationResponses: OperationResponse[]): Op
|
||||
|
||||
if (!operationResults.length) {
|
||||
operationResults.push({
|
||||
in: 'response',
|
||||
name: '',
|
||||
code: 200,
|
||||
description: '',
|
||||
@ -29,7 +30,7 @@ export function getOperationResults(operationResponses: OperationResponse[]): Op
|
||||
base: PrimaryType.OBJECT,
|
||||
template: null,
|
||||
link: null,
|
||||
isProperty: false,
|
||||
isDefinition: false,
|
||||
isReadOnly: false,
|
||||
isRequired: false,
|
||||
isNullable: false,
|
||||
|
||||
@ -27,13 +27,11 @@ export function getServices(openApi: OpenApi): Service[] {
|
||||
|
||||
// If we have already declared a service, then we should fetch that and
|
||||
// append the new method to it. Otherwise we should create a new service object.
|
||||
const service =
|
||||
services.get(operation.service) ||
|
||||
({
|
||||
name: operation.service,
|
||||
operations: [],
|
||||
imports: [],
|
||||
} as Service);
|
||||
const service: Service = services.get(operation.service) || {
|
||||
name: operation.service,
|
||||
operations: [],
|
||||
imports: [],
|
||||
};
|
||||
|
||||
// Push the operation in the service
|
||||
service.operations.push(operation);
|
||||
|
||||
@ -26,7 +26,7 @@ export function getType(value?: string, template?: string): Type {
|
||||
|
||||
if (match1.type === PrimaryType.ARRAY) {
|
||||
result.type = `${match2.type}[]`;
|
||||
result.base = `${match2.type}`;
|
||||
result.base = match2.type;
|
||||
match1.imports = [];
|
||||
} else if (match2.type) {
|
||||
result.type = `${match1.type}<${match2.type}>`;
|
||||
|
||||
@ -11,10 +11,10 @@ import { getServices } from './parser/getServices';
|
||||
* @param openApi The OpenAPI spec that we have loaded from disk.
|
||||
*/
|
||||
export function parse(openApi: OpenApi): Client {
|
||||
return {
|
||||
version: getServiceVersion(openApi.info.version),
|
||||
server: getServer(openApi),
|
||||
models: getModels(openApi),
|
||||
services: getServices(openApi),
|
||||
};
|
||||
const version = getServiceVersion(openApi.info.version);
|
||||
const server = getServer(openApi);
|
||||
const models = getModels(openApi);
|
||||
const services = getServices(openApi);
|
||||
|
||||
return { version, server, models, services };
|
||||
}
|
||||
|
||||
@ -4,6 +4,12 @@ import { WithEnumExtension } from '../interfaces/Extensions/WithEnumExtension';
|
||||
const KEY_ENUM_NAMES = 'x-enum-varnames';
|
||||
const KEY_ENUM_DESCRIPTIONS = 'x-enum-descriptions';
|
||||
|
||||
/**
|
||||
* Extend the enum with the x-enum properties. This adds the capability
|
||||
* to use names and descriptions inside the generated enums.
|
||||
* @param enumerators
|
||||
* @param definition
|
||||
*/
|
||||
export function extendEnum(enumerators: Enum[], definition: WithEnumExtension): Enum[] {
|
||||
const names = definition[KEY_ENUM_NAMES];
|
||||
const descriptions = definition[KEY_ENUM_DESCRIPTIONS];
|
||||
|
||||
@ -1,5 +1,10 @@
|
||||
import { EOL } from 'os';
|
||||
|
||||
/**
|
||||
* Cleanup comment and prefix multiline comments with "*",
|
||||
* so they look a bit nicer when used in the generated code.
|
||||
* @param comment
|
||||
*/
|
||||
export function getComment(comment?: string): string | null {
|
||||
if (comment) {
|
||||
return comment.replace(/\r?\n(.*)/g, (_, w) => `${EOL} * ${w.trim()}`);
|
||||
|
||||
@ -10,7 +10,7 @@ import { getModelDefault } from './getModelDefault';
|
||||
import { getModelProperties } from './getModelProperties';
|
||||
import { getType } from './getType';
|
||||
|
||||
export function getModel(openApi: OpenApi, definition: OpenApiSchema, isProperty: boolean = false, name: string = ''): Model {
|
||||
export function getModel(openApi: OpenApi, definition: OpenApiSchema, isDefinition: boolean = false, name: string = ''): Model {
|
||||
const model: Model = {
|
||||
name: name,
|
||||
export: 'interface',
|
||||
@ -19,7 +19,7 @@ export function getModel(openApi: OpenApi, definition: OpenApiSchema, isProperty
|
||||
template: null,
|
||||
link: null,
|
||||
description: getComment(definition.description),
|
||||
isProperty: isProperty,
|
||||
isDefinition: isDefinition,
|
||||
isReadOnly: definition.readOnly === true,
|
||||
isNullable: definition.nullable === true,
|
||||
isRequired: false,
|
||||
@ -77,7 +77,7 @@ export function getModel(openApi: OpenApi, definition: OpenApiSchema, isProperty
|
||||
model.default = getModelDefault(definition, model);
|
||||
return model;
|
||||
} else {
|
||||
const arrayItems = getModel(openApi, definition.items, true);
|
||||
const arrayItems = getModel(openApi, definition.items);
|
||||
model.export = 'array';
|
||||
model.type = arrayItems.type;
|
||||
model.base = arrayItems.base;
|
||||
@ -117,7 +117,10 @@ export function getModel(openApi: OpenApi, definition: OpenApiSchema, isProperty
|
||||
if (definition.anyOf && definition.anyOf.length) {
|
||||
model.export = 'generic';
|
||||
const compositionTypes = definition.anyOf.filter(type => type.$ref).map(type => getType(type.$ref));
|
||||
const composition = compositionTypes.map(type => type.type).join(' | ');
|
||||
const composition = compositionTypes
|
||||
.map(type => type.type)
|
||||
.sort()
|
||||
.join(' | ');
|
||||
model.imports.push(...compositionTypes.map(type => type.base));
|
||||
model.type = composition;
|
||||
model.base = composition;
|
||||
@ -127,7 +130,10 @@ export function getModel(openApi: OpenApi, definition: OpenApiSchema, isProperty
|
||||
if (definition.oneOf && definition.oneOf.length) {
|
||||
model.export = 'generic';
|
||||
const compositionTypes = definition.oneOf.filter(type => type.$ref).map(type => getType(type.$ref));
|
||||
const composition = compositionTypes.map(type => type.type).join(' | ');
|
||||
const composition = compositionTypes
|
||||
.map(type => type.type)
|
||||
.sort()
|
||||
.join(' | ');
|
||||
model.imports.push(...compositionTypes.map(type => type.base));
|
||||
model.type = composition;
|
||||
model.base = composition;
|
||||
@ -144,7 +150,7 @@ export function getModel(openApi: OpenApi, definition: OpenApiSchema, isProperty
|
||||
definition.allOf.forEach(parent => {
|
||||
if (parent.$ref) {
|
||||
const parentRef = getType(parent.$ref);
|
||||
model.extends.push(parentRef.type);
|
||||
model.extends.push(parentRef.base);
|
||||
model.imports.push(parentRef.base);
|
||||
}
|
||||
if (parent.type === 'object' && parent.properties) {
|
||||
|
||||
@ -21,7 +21,7 @@ export function getModelProperties(openApi: OpenApi, definition: OpenApiSchema):
|
||||
template: model.template,
|
||||
link: null,
|
||||
description: getComment(property.description),
|
||||
isProperty: true,
|
||||
isDefinition: false,
|
||||
isReadOnly: property.readOnly === true,
|
||||
isRequired: propertyRequired === true,
|
||||
isNullable: property.nullable === true,
|
||||
@ -55,7 +55,7 @@ export function getModelProperties(openApi: OpenApi, definition: OpenApiSchema):
|
||||
template: model.template,
|
||||
link: model.link,
|
||||
description: getComment(property.description),
|
||||
isProperty: true,
|
||||
isDefinition: false,
|
||||
isReadOnly: property.readOnly === true,
|
||||
isRequired: propertyRequired === true,
|
||||
isNullable: property.nullable === true,
|
||||
|
||||
@ -4,16 +4,16 @@ import { getModel } from './getModel';
|
||||
import { getType } from './getType';
|
||||
|
||||
export function getModels(openApi: OpenApi): Model[] {
|
||||
const models = new Map<string, Model>();
|
||||
const models: Model[] = [];
|
||||
if (openApi.components) {
|
||||
for (const definitionName in openApi.components.schemas) {
|
||||
if (openApi.components.schemas.hasOwnProperty(definitionName)) {
|
||||
const definition = openApi.components.schemas[definitionName];
|
||||
const definitionType = getType(definitionName);
|
||||
const model = getModel(openApi, definition, false, definitionType.base);
|
||||
models.set(definitionType.base, model);
|
||||
const model = getModel(openApi, definition, true, definitionType.base);
|
||||
models.push(model);
|
||||
}
|
||||
}
|
||||
}
|
||||
return Array.from(models.values());
|
||||
return models;
|
||||
}
|
||||
|
||||
@ -19,7 +19,7 @@ export function getOperationParameter(openApi: OpenApi, parameter: OpenApiParame
|
||||
template: null,
|
||||
link: null,
|
||||
description: getComment(parameter.description),
|
||||
isProperty: false,
|
||||
isDefinition: false,
|
||||
isReadOnly: false,
|
||||
isRequired: parameter.required === true,
|
||||
isNullable: parameter.nullable === true,
|
||||
|
||||
@ -19,7 +19,7 @@ export function getOperationRequestBody(openApi: OpenApi, parameter: OpenApiRequ
|
||||
link: null,
|
||||
description: getComment(parameter.description),
|
||||
default: undefined,
|
||||
isProperty: false,
|
||||
isDefinition: false,
|
||||
isReadOnly: false,
|
||||
isRequired: parameter.required === true,
|
||||
isNullable: parameter.nullable === true,
|
||||
|
||||
@ -9,6 +9,7 @@ import { getType } from './getType';
|
||||
|
||||
export function getOperationResponse(openApi: OpenApi, response: OpenApiResponse, responseCode: number): OperationResponse {
|
||||
const operationResponse: OperationResponse = {
|
||||
in: 'response',
|
||||
name: '',
|
||||
code: responseCode,
|
||||
description: getComment(response.description)!,
|
||||
@ -17,7 +18,7 @@ export function getOperationResponse(openApi: OpenApi, response: OpenApiResponse
|
||||
base: PrimaryType.OBJECT,
|
||||
template: null,
|
||||
link: null,
|
||||
isProperty: false,
|
||||
isDefinition: false,
|
||||
isReadOnly: false,
|
||||
isRequired: false,
|
||||
isNullable: false,
|
||||
|
||||
@ -21,6 +21,7 @@ export function getOperationResults(operationResponses: OperationResponse[]): Op
|
||||
|
||||
if (!operationResults.length) {
|
||||
operationResults.push({
|
||||
in: 'response',
|
||||
name: '',
|
||||
code: 200,
|
||||
description: '',
|
||||
@ -29,7 +30,7 @@ export function getOperationResults(operationResponses: OperationResponse[]): Op
|
||||
base: PrimaryType.OBJECT,
|
||||
template: null,
|
||||
link: null,
|
||||
isProperty: false,
|
||||
isDefinition: false,
|
||||
isReadOnly: false,
|
||||
isRequired: false,
|
||||
isNullable: false,
|
||||
|
||||
@ -3,9 +3,16 @@
|
||||
/* eslint-disable */
|
||||
/* prettier-ignore */
|
||||
|
||||
export namespace OpenAPI {
|
||||
export let BASE = '{{{server}}}';
|
||||
export let VERSION = '{{{version}}}';
|
||||
export let CLIENT = '{{{httpClient}}}';
|
||||
export let TOKEN = '';
|
||||
interface Config {
|
||||
BASE: string;
|
||||
VERSION: string;
|
||||
CLIENT: 'fetch' | 'xhr';
|
||||
TOKEN: string;
|
||||
}
|
||||
|
||||
export const OpenAPI: Config = {
|
||||
BASE: '{{{server}}}',
|
||||
VERSION: '{{{version}}}',
|
||||
CLIENT: '{{{httpClient}}}',
|
||||
TOKEN: '',
|
||||
};
|
||||
|
||||
@ -1,25 +0,0 @@
|
||||
import { Model } from '../client/interfaces/Model';
|
||||
|
||||
export function exportModel(model: Model): Model {
|
||||
return {
|
||||
...model,
|
||||
imports: model.imports
|
||||
.filter(name => {
|
||||
return model.name !== name;
|
||||
})
|
||||
.filter((name, index, arr) => {
|
||||
return arr.indexOf(name) === index;
|
||||
})
|
||||
.sort((a, b) => {
|
||||
const nameA = a.toLowerCase();
|
||||
const nameB = b.toLowerCase();
|
||||
return nameA.localeCompare(nameB);
|
||||
}),
|
||||
enums: model.enums.filter((property, index, arr) => {
|
||||
return arr.findIndex(item => item.name === property.name) === index;
|
||||
}),
|
||||
enum: model.enum.filter((enumerator, index, arr) => {
|
||||
return arr.findIndex(item => item.name === enumerator.name) === index;
|
||||
}),
|
||||
};
|
||||
}
|
||||
@ -1,29 +0,0 @@
|
||||
import { Service } from '../client/interfaces/Service';
|
||||
|
||||
export function exportService(service: Service): Service {
|
||||
const names = new Map<string, number>();
|
||||
return {
|
||||
...service,
|
||||
imports: service.imports
|
||||
.filter(name => {
|
||||
return service.name !== name;
|
||||
})
|
||||
.filter((name, index, arr) => {
|
||||
return arr.indexOf(name) === index;
|
||||
})
|
||||
.sort((a, b) => {
|
||||
const nameA = a.toLowerCase();
|
||||
const nameB = b.toLowerCase();
|
||||
return nameA.localeCompare(nameB);
|
||||
}),
|
||||
operations: service.operations.map(operation => {
|
||||
const name = operation.name;
|
||||
const index = names.get(name) || 0;
|
||||
if (index > 0) {
|
||||
operation.name = `${name}${index}`;
|
||||
}
|
||||
names.set(name, index + 1);
|
||||
return operation;
|
||||
}),
|
||||
};
|
||||
}
|
||||
23
src/utils/getExtendedByList.ts
Normal file
23
src/utils/getExtendedByList.ts
Normal file
@ -0,0 +1,23 @@
|
||||
import { Client } from '../client/interfaces/Client';
|
||||
import { Model } from '../client/interfaces/Model';
|
||||
import { unique } from './unique';
|
||||
|
||||
/**
|
||||
* Get the full list of models that are extended by the given model.
|
||||
* This list is used when we have the flag "useUnionTypes" enabled.
|
||||
* @param model
|
||||
* @param client
|
||||
*/
|
||||
export function getExtendedByList(model: Model, client: Client): Model[] {
|
||||
const extendedBy = client.models.filter(ref => {
|
||||
const names = model.isDefinition ? [model.name] : model.base.split(' | ');
|
||||
return names.find(name => {
|
||||
return ref.extends.includes(name);
|
||||
});
|
||||
});
|
||||
|
||||
if (extendedBy.length) {
|
||||
extendedBy.push(...extendedBy.flatMap(ref => getExtendedByList(ref, client)));
|
||||
}
|
||||
return extendedBy.filter(unique);
|
||||
}
|
||||
23
src/utils/getExtendedFromList.ts
Normal file
23
src/utils/getExtendedFromList.ts
Normal file
@ -0,0 +1,23 @@
|
||||
import { Client } from '../client/interfaces/Client';
|
||||
import { Model } from '../client/interfaces/Model';
|
||||
import { unique } from './unique';
|
||||
|
||||
/**
|
||||
* Get the full list of models that are extended from the given model.
|
||||
* This list is used when we have the flag "useUnionTypes" enabled.
|
||||
* @param model
|
||||
* @param client
|
||||
*/
|
||||
export function getExtendedFromList(model: Model, client: Client): Model[] {
|
||||
const extendedFrom = client.models.filter(ref => {
|
||||
const names = ref.isDefinition ? [ref.name] : ref.base.split(' | ');
|
||||
return names.find(name => {
|
||||
return model.extends.includes(name);
|
||||
});
|
||||
});
|
||||
|
||||
if (extendedFrom.length) {
|
||||
extendedFrom.push(...extendedFrom.flatMap(ref => getExtendedFromList(ref, client)));
|
||||
}
|
||||
return extendedFrom.filter(unique);
|
||||
}
|
||||
@ -12,7 +12,7 @@ describe('getModelNames', () => {
|
||||
template: null,
|
||||
link: null,
|
||||
description: null,
|
||||
isProperty: false,
|
||||
isDefinition: true,
|
||||
isReadOnly: false,
|
||||
isRequired: false,
|
||||
isNullable: false,
|
||||
@ -30,7 +30,7 @@ describe('getModelNames', () => {
|
||||
template: null,
|
||||
link: null,
|
||||
description: null,
|
||||
isProperty: false,
|
||||
isDefinition: true,
|
||||
isReadOnly: false,
|
||||
isRequired: false,
|
||||
isNullable: false,
|
||||
@ -48,7 +48,7 @@ describe('getModelNames', () => {
|
||||
template: null,
|
||||
link: null,
|
||||
description: null,
|
||||
isProperty: false,
|
||||
isDefinition: true,
|
||||
isReadOnly: false,
|
||||
isRequired: false,
|
||||
isNullable: false,
|
||||
|
||||
@ -1,11 +1,6 @@
|
||||
import { Model } from '../client/interfaces/Model';
|
||||
import { sort } from './sort';
|
||||
|
||||
export function getModelNames(models: Model[]): string[] {
|
||||
return models
|
||||
.map(model => model.name)
|
||||
.sort((a, b) => {
|
||||
const nameA = a.toLowerCase();
|
||||
const nameB = b.toLowerCase();
|
||||
return nameA.localeCompare(nameB, 'en');
|
||||
});
|
||||
return models.map(model => model.name).sort(sort);
|
||||
}
|
||||
|
||||
@ -21,25 +21,26 @@ function read(filePath: string): string {
|
||||
* Load and parse te open api spec. If the file extension is ".yml" or ".yaml"
|
||||
* we will try to parse the file as a YAML spec, otherwise we will fallback
|
||||
* on parsing the file as JSON.
|
||||
* @param filePath
|
||||
* @param input
|
||||
*/
|
||||
export function getOpenApiSpec(filePath: string): any {
|
||||
const content = read(filePath);
|
||||
const extname = path.extname(filePath).toLowerCase();
|
||||
export function getOpenApiSpec(input: string): any {
|
||||
const file = path.resolve(process.cwd(), input);
|
||||
const extname = path.extname(file).toLowerCase();
|
||||
const content = read(file);
|
||||
switch (extname) {
|
||||
case '.yml':
|
||||
case '.yaml':
|
||||
try {
|
||||
return yaml.safeLoad(content);
|
||||
} catch (e) {
|
||||
throw new Error(`Could not parse OpenApi YAML: "${filePath}"`);
|
||||
throw new Error(`Could not parse OpenApi YAML: "${file}"`);
|
||||
}
|
||||
|
||||
default:
|
||||
try {
|
||||
return JSON.parse(content);
|
||||
} catch (e) {
|
||||
throw new Error(`Could not parse OpenApi JSON: "${filePath}"`);
|
||||
throw new Error(`Could not parse OpenApi JSON: "${file}"`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,11 +1,6 @@
|
||||
import { Service } from '../client/interfaces/Service';
|
||||
import { sort } from './sort';
|
||||
|
||||
export function getServiceNames(services: Service[]): string[] {
|
||||
return services
|
||||
.map(service => service.name)
|
||||
.sort((a, b) => {
|
||||
const nameA = a.toLowerCase();
|
||||
const nameB = b.toLowerCase();
|
||||
return nameA.localeCompare(nameB, 'en');
|
||||
});
|
||||
return services.map(service => service.name).sort(sort);
|
||||
}
|
||||
|
||||
3
src/utils/isString.ts
Normal file
3
src/utils/isString.ts
Normal file
@ -0,0 +1,3 @@
|
||||
export function isString(val: any): val is string {
|
||||
return typeof val === 'string';
|
||||
}
|
||||
16
src/utils/postProcessClient.ts
Normal file
16
src/utils/postProcessClient.ts
Normal file
@ -0,0 +1,16 @@
|
||||
import { Client } from '../client/interfaces/Client';
|
||||
import { postProcessModel } from './postProcessModel';
|
||||
import { postProcessService } from './postProcessService';
|
||||
|
||||
/**
|
||||
* Post process client
|
||||
* @param client Client object with all the models, services, etc.
|
||||
* @param useUnionTypes Use inclusive union types.
|
||||
*/
|
||||
export function postProcessClient(client: Client, useUnionTypes: boolean): Client {
|
||||
return {
|
||||
...client,
|
||||
models: client.models.map(model => postProcessModel(model, client, useUnionTypes)),
|
||||
services: client.services.map(service => postProcessService(service, client, useUnionTypes)),
|
||||
};
|
||||
}
|
||||
24
src/utils/postProcessModel.ts
Normal file
24
src/utils/postProcessModel.ts
Normal file
@ -0,0 +1,24 @@
|
||||
import { Client } from '../client/interfaces/Client';
|
||||
import { Model } from '../client/interfaces/Model';
|
||||
import { postProcessModelEnum } from './postProcessModelEnum';
|
||||
import { postProcessModelEnums } from './postProcessModelEnums';
|
||||
import { postProcessModelImports } from './postProcessModelImports';
|
||||
import { postProcessUnionTypes } from './postProcessUnionTypes';
|
||||
|
||||
/**
|
||||
* Post process the model. If needed this will convert types to union types,
|
||||
* see the "useUnionTypes" flag in the documentation. Plus this will cleanup
|
||||
* any double imports or enum values.
|
||||
* @param model
|
||||
* @param client
|
||||
* @param useUnionTypes
|
||||
*/
|
||||
export function postProcessModel(model: Model, client: Client, useUnionTypes: boolean): Model {
|
||||
const clone = postProcessUnionTypes(model, client, useUnionTypes);
|
||||
return {
|
||||
...clone,
|
||||
imports: postProcessModelImports(clone),
|
||||
enums: postProcessModelEnums(clone),
|
||||
enum: postProcessModelEnum(clone),
|
||||
};
|
||||
}
|
||||
12
src/utils/postProcessModelEnum.ts
Normal file
12
src/utils/postProcessModelEnum.ts
Normal file
@ -0,0 +1,12 @@
|
||||
import { Enum } from '../client/interfaces/Enum';
|
||||
import { Model } from '../client/interfaces/Model';
|
||||
|
||||
/**
|
||||
* Set unique enum values for the model
|
||||
* @param model
|
||||
*/
|
||||
export function postProcessModelEnum(model: Model): Enum[] {
|
||||
return model.enum.filter((property, index, arr) => {
|
||||
return arr.findIndex(item => item.name === property.name) === index;
|
||||
});
|
||||
}
|
||||
11
src/utils/postProcessModelEnums.ts
Normal file
11
src/utils/postProcessModelEnums.ts
Normal file
@ -0,0 +1,11 @@
|
||||
import { Model } from '../client/interfaces/Model';
|
||||
|
||||
/**
|
||||
* Set unique enum values for the model
|
||||
* @param model The model that is post-processed
|
||||
*/
|
||||
export function postProcessModelEnums(model: Model): Model[] {
|
||||
return model.enums.filter((property, index, arr) => {
|
||||
return arr.findIndex(item => item.name === property.name) === index;
|
||||
});
|
||||
}
|
||||
14
src/utils/postProcessModelImports.ts
Normal file
14
src/utils/postProcessModelImports.ts
Normal file
@ -0,0 +1,14 @@
|
||||
import { Model } from '../client/interfaces/Model';
|
||||
import { sort } from './sort';
|
||||
import { unique } from './unique';
|
||||
|
||||
/**
|
||||
* Set unique imports, sorted by name
|
||||
* @param model The model that is post-processed
|
||||
*/
|
||||
export function postProcessModelImports(model: Model): string[] {
|
||||
return model.imports
|
||||
.filter(unique)
|
||||
.sort(sort)
|
||||
.filter(name => model.name !== name);
|
||||
}
|
||||
14
src/utils/postProcessService.ts
Normal file
14
src/utils/postProcessService.ts
Normal file
@ -0,0 +1,14 @@
|
||||
import { Client } from '../client/interfaces/Client';
|
||||
import { Service } from '../client/interfaces/Service';
|
||||
import { postProcessServiceImports } from './postProcessServiceImports';
|
||||
import { postProcessServiceOperations } from './postProcessServiceOperations';
|
||||
|
||||
export function postProcessService(service: Service, client: Client, useUnionTypes: boolean): Service {
|
||||
const clone = { ...service };
|
||||
clone.operations = postProcessServiceOperations(clone, client, useUnionTypes);
|
||||
clone.operations.forEach(operation => {
|
||||
clone.imports.push(...operation.imports);
|
||||
});
|
||||
clone.imports = postProcessServiceImports(clone);
|
||||
return clone;
|
||||
}
|
||||
14
src/utils/postProcessServiceImports.ts
Normal file
14
src/utils/postProcessServiceImports.ts
Normal file
@ -0,0 +1,14 @@
|
||||
import { Service } from '../client/interfaces/Service';
|
||||
import { sort } from './sort';
|
||||
import { unique } from './unique';
|
||||
|
||||
/**
|
||||
* Set unique imports, sorted by name
|
||||
* @param service
|
||||
*/
|
||||
export function postProcessServiceImports(service: Service): string[] {
|
||||
return service.imports
|
||||
.filter(unique)
|
||||
.sort(sort)
|
||||
.filter(name => service.name !== name);
|
||||
}
|
||||
30
src/utils/postProcessServiceOperations.ts
Normal file
30
src/utils/postProcessServiceOperations.ts
Normal file
@ -0,0 +1,30 @@
|
||||
import { Client } from '../client/interfaces/Client';
|
||||
import { Operation } from '../client/interfaces/Operation';
|
||||
import { Service } from '../client/interfaces/Service';
|
||||
import { postProcessUnionTypes } from './postProcessUnionTypes';
|
||||
|
||||
export function postProcessServiceOperations(service: Service, client: Client, useUnionTypes: boolean = false): Operation[] {
|
||||
const names = new Map<string, number>();
|
||||
|
||||
return service.operations.map(operation => {
|
||||
const clone = { ...operation };
|
||||
|
||||
// Parse the service parameters and results, very similar to how we parse
|
||||
// properties of models. These methods will extend the type if needed.
|
||||
clone.parameters = clone.parameters.map(parameter => postProcessUnionTypes(parameter, client, useUnionTypes));
|
||||
clone.results = clone.results.map(result => postProcessUnionTypes(result, client, useUnionTypes));
|
||||
clone.imports.push(...clone.parameters.flatMap(parameter => parameter.imports));
|
||||
clone.imports.push(...clone.results.flatMap(result => result.imports));
|
||||
|
||||
// Check of the operation name
|
||||
let name = clone.name;
|
||||
const index = names.get(name) || 0;
|
||||
if (index > 0) {
|
||||
clone.name = `${name}${index}`;
|
||||
name = `${name}${index}`;
|
||||
}
|
||||
names.set(name, index + 1);
|
||||
|
||||
return clone;
|
||||
});
|
||||
}
|
||||
41
src/utils/postProcessUnionTypes.ts
Normal file
41
src/utils/postProcessUnionTypes.ts
Normal file
@ -0,0 +1,41 @@
|
||||
import { Client } from '../client/interfaces/Client';
|
||||
import { Model } from '../client/interfaces/Model';
|
||||
import { getExtendedByList } from './getExtendedByList';
|
||||
|
||||
/**
|
||||
* This post processor will convert types to union types. For more information
|
||||
* please check the documentation. In a nutshell: By setting the "useUnionTypes"
|
||||
* flag we will convert base types to a union of types that are extended from
|
||||
* the base type.
|
||||
* @param model
|
||||
* @param client
|
||||
* @param useUnionTypes
|
||||
*/
|
||||
export function postProcessUnionTypes<T extends Model>(model: T, client: Client, useUnionTypes: boolean): T {
|
||||
const clone = { ...model };
|
||||
|
||||
if (useUnionTypes) {
|
||||
// If this is not a root definition, then new need to check the base type
|
||||
if (!clone.isDefinition) {
|
||||
const extendedBy = getExtendedByList(clone, client);
|
||||
const extendedByNames = extendedBy.map(m => m.name);
|
||||
clone.base = [clone.base, ...extendedByNames].sort().join(' | ');
|
||||
clone.imports = clone.imports.concat(...extendedByNames);
|
||||
}
|
||||
|
||||
// In any case we need to check the properties of a model.
|
||||
// When the types get extended, we also need to make sure we update the imports.
|
||||
clone.properties = clone.properties.map(property => postProcessUnionTypes(property, client, useUnionTypes));
|
||||
clone.properties.forEach(property => {
|
||||
clone.imports.push(...property.imports);
|
||||
});
|
||||
|
||||
// When the model has a link (in case of an Array or Dictionary),
|
||||
// then we also process this linked model and again update the imports.
|
||||
clone.link = clone.link ? postProcessUnionTypes(clone.link, client, useUnionTypes) : null;
|
||||
if (clone.link) {
|
||||
clone.imports.push(...clone.link.imports);
|
||||
}
|
||||
}
|
||||
return clone;
|
||||
}
|
||||
@ -12,6 +12,7 @@ export function readHandlebarsTemplate(filePath: string): Handlebars.TemplateDel
|
||||
.readFileSync(filePath, 'utf8')
|
||||
.toString()
|
||||
.trim();
|
||||
|
||||
return Handlebars.compile(template, {
|
||||
strict: true,
|
||||
noEscape: true,
|
||||
|
||||
@ -31,7 +31,9 @@ export function readHandlebarsTemplates(): Templates {
|
||||
const partials = path.resolve(__dirname, `../../src/templates/partials`);
|
||||
const partialsFiles = glob.sync('*.hbs', { cwd: partials });
|
||||
partialsFiles.forEach(partial => {
|
||||
Handlebars.registerPartial(path.basename(partial, '.hbs'), readHandlebarsTemplate(path.resolve(partials, partial)));
|
||||
const templateName = path.basename(partial, '.hbs');
|
||||
const template = readHandlebarsTemplate(path.resolve(partials, partial));
|
||||
Handlebars.registerPartial(templateName, template);
|
||||
});
|
||||
|
||||
return templates;
|
||||
|
||||
5
src/utils/sort.ts
Normal file
5
src/utils/sort.ts
Normal file
@ -0,0 +1,5 @@
|
||||
export function sort(a: string, b: string): number {
|
||||
const nameA = a.toLowerCase();
|
||||
const nameB = b.toLowerCase();
|
||||
return nameA.localeCompare(nameB, 'en');
|
||||
}
|
||||
3
src/utils/unique.ts
Normal file
3
src/utils/unique.ts
Normal file
@ -0,0 +1,3 @@
|
||||
export function unique<T>(val: T, index: number, arr: T[]): boolean {
|
||||
return arr.indexOf(val) === index;
|
||||
}
|
||||
@ -36,7 +36,7 @@ describe('writeClient', () => {
|
||||
|
||||
globSync.mockReturnValue([]);
|
||||
|
||||
writeClient(client, HttpClient.FETCH, templates, '/');
|
||||
writeClient(client, templates, '/', HttpClient.FETCH, false);
|
||||
|
||||
expect(rimrafSync).toBeCalled();
|
||||
expect(mkdirpSync).toBeCalled();
|
||||
|
||||
@ -15,12 +15,13 @@ import { writeClientSettings } from './writeClientSettings';
|
||||
/**
|
||||
* Write our OpenAPI client, using the given templates at the given output path.
|
||||
* @param client Client object with all the models, services, etc.
|
||||
* @param httpClient The selected httpClient (fetch or XHR).
|
||||
* @param templates Templates wrapper with all loaded Handlebars templates.
|
||||
* @param outputPath Directory to write the generated files to.
|
||||
* @param output Directory to write the generated files to.
|
||||
* @param httpClient The selected httpClient (fetch or XHR).
|
||||
* @param useOptions Use options or arguments functions.
|
||||
*/
|
||||
export function writeClient(client: Client, httpClient: HttpClient, templates: Templates, outputPath: string, useOptions: boolean): void {
|
||||
export function writeClient(client: Client, templates: Templates, output: string, httpClient: HttpClient, useOptions: boolean): void {
|
||||
const outputPath = path.resolve(process.cwd(), output);
|
||||
const outputPathCore = path.resolve(outputPath, 'core');
|
||||
const outputPathModels = path.resolve(outputPath, 'models');
|
||||
const outputPathSchemas = path.resolve(outputPath, 'schemas');
|
||||
@ -30,7 +31,7 @@ export function writeClient(client: Client, httpClient: HttpClient, templates: T
|
||||
try {
|
||||
rimraf.sync(outputPath);
|
||||
} catch (e) {
|
||||
throw new Error(`Could not clean output directory`);
|
||||
throw new Error('Could not clean output directory');
|
||||
}
|
||||
|
||||
// Create new directories
|
||||
@ -41,11 +42,11 @@ export function writeClient(client: Client, httpClient: HttpClient, templates: T
|
||||
mkdirp.sync(outputPathSchemas);
|
||||
mkdirp.sync(outputPathServices);
|
||||
} catch (e) {
|
||||
throw new Error(`Could not create output directories`);
|
||||
throw new Error('Could not create output directories');
|
||||
}
|
||||
|
||||
// Copy all support files
|
||||
const supportFiles = path.resolve(__dirname, `../../src/templates/`);
|
||||
const supportFiles = path.resolve(__dirname, '../../src/templates/');
|
||||
const supportFilesList = glob.sync('**/*.ts', { cwd: supportFiles });
|
||||
supportFilesList.forEach(file => {
|
||||
fs.copyFileSync(
|
||||
@ -58,6 +59,6 @@ export function writeClient(client: Client, httpClient: HttpClient, templates: T
|
||||
writeClientModels(client.models, templates, outputPathModels);
|
||||
writeClientSchemas(client.models, templates, outputPathSchemas);
|
||||
writeClientServices(client.services, templates, outputPathServices, useOptions);
|
||||
writeClientSettings(client, httpClient, templates, outputPathCore);
|
||||
writeClientSettings(client, templates, outputPathCore, httpClient);
|
||||
writeClientIndex(client, templates, outputPath);
|
||||
}
|
||||
|
||||
@ -9,25 +9,26 @@ const fsWriteFileSync = fs.writeFileSync as jest.MockedFunction<typeof fs.writeF
|
||||
|
||||
describe('writeClientModels', () => {
|
||||
it('should write to filesystem', () => {
|
||||
const models: Model[] = [];
|
||||
models.push({
|
||||
export: 'interface',
|
||||
name: 'Item',
|
||||
type: 'Item',
|
||||
base: 'Item',
|
||||
template: null,
|
||||
link: null,
|
||||
description: null,
|
||||
isProperty: false,
|
||||
isReadOnly: false,
|
||||
isRequired: false,
|
||||
isNullable: false,
|
||||
imports: [],
|
||||
extends: [],
|
||||
enum: [],
|
||||
enums: [],
|
||||
properties: [],
|
||||
});
|
||||
const models: Model[] = [
|
||||
{
|
||||
export: 'interface',
|
||||
name: 'Item',
|
||||
type: 'Item',
|
||||
base: 'Item',
|
||||
template: null,
|
||||
link: null,
|
||||
description: null,
|
||||
isDefinition: true,
|
||||
isReadOnly: false,
|
||||
isRequired: false,
|
||||
isNullable: false,
|
||||
imports: [],
|
||||
extends: [],
|
||||
enum: [],
|
||||
enums: [],
|
||||
properties: [],
|
||||
},
|
||||
];
|
||||
|
||||
const templates: Templates = {
|
||||
index: () => 'dummy',
|
||||
|
||||
@ -2,7 +2,6 @@ import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
import { Model } from '../client/interfaces/Model';
|
||||
import { Templates } from './readHandlebarsTemplates';
|
||||
import { exportModel } from './exportModel';
|
||||
import { format } from './format';
|
||||
|
||||
/**
|
||||
@ -14,8 +13,7 @@ import { format } from './format';
|
||||
export function writeClientModels(models: Model[], templates: Templates, outputPath: string): void {
|
||||
models.forEach(model => {
|
||||
const file = path.resolve(outputPath, `${model.name}.ts`);
|
||||
const templateData = exportModel(model);
|
||||
const templateResult = templates.model(templateData);
|
||||
const templateResult = templates.model(model);
|
||||
fs.writeFileSync(file, format(templateResult));
|
||||
});
|
||||
}
|
||||
|
||||
@ -9,25 +9,26 @@ const fsWriteFileSync = fs.writeFileSync as jest.MockedFunction<typeof fs.writeF
|
||||
|
||||
describe('writeClientModels', () => {
|
||||
it('should write to filesystem', () => {
|
||||
const models: Model[] = [];
|
||||
models.push({
|
||||
export: 'interface',
|
||||
name: 'Item',
|
||||
type: 'Item',
|
||||
base: 'Item',
|
||||
template: null,
|
||||
link: null,
|
||||
description: null,
|
||||
isProperty: false,
|
||||
isReadOnly: false,
|
||||
isRequired: false,
|
||||
isNullable: false,
|
||||
imports: [],
|
||||
extends: [],
|
||||
enum: [],
|
||||
enums: [],
|
||||
properties: [],
|
||||
});
|
||||
const models: Model[] = [
|
||||
{
|
||||
export: 'interface',
|
||||
name: 'Item',
|
||||
type: 'Item',
|
||||
base: 'Item',
|
||||
template: null,
|
||||
link: null,
|
||||
description: null,
|
||||
isDefinition: true,
|
||||
isReadOnly: false,
|
||||
isRequired: false,
|
||||
isNullable: false,
|
||||
imports: [],
|
||||
extends: [],
|
||||
enum: [],
|
||||
enums: [],
|
||||
properties: [],
|
||||
},
|
||||
];
|
||||
|
||||
const templates: Templates = {
|
||||
index: () => 'dummy',
|
||||
|
||||
@ -2,7 +2,6 @@ import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
import { Model } from '../client/interfaces/Model';
|
||||
import { Templates } from './readHandlebarsTemplates';
|
||||
import { exportModel } from './exportModel';
|
||||
import { format } from './format';
|
||||
|
||||
/**
|
||||
@ -14,8 +13,7 @@ import { format } from './format';
|
||||
export function writeClientSchemas(models: Model[], templates: Templates, outputPath: string): void {
|
||||
models.forEach(model => {
|
||||
const file = path.resolve(outputPath, `$${model.name}.ts`);
|
||||
const templateData = exportModel(model);
|
||||
const templateResult = templates.schema(templateData);
|
||||
const templateResult = templates.schema(model);
|
||||
fs.writeFileSync(file, format(templateResult));
|
||||
});
|
||||
}
|
||||
|
||||
@ -9,12 +9,13 @@ const fsWriteFileSync = fs.writeFileSync as jest.MockedFunction<typeof fs.writeF
|
||||
|
||||
describe('writeClientServices', () => {
|
||||
it('should write to filesystem', () => {
|
||||
const services: Service[] = [];
|
||||
services.push({
|
||||
name: 'Item',
|
||||
operations: [],
|
||||
imports: [],
|
||||
});
|
||||
const services: Service[] = [
|
||||
{
|
||||
name: 'Item',
|
||||
operations: [],
|
||||
imports: [],
|
||||
},
|
||||
];
|
||||
|
||||
const templates: Templates = {
|
||||
index: () => 'dummy',
|
||||
@ -24,7 +25,7 @@ describe('writeClientServices', () => {
|
||||
settings: () => 'dummy',
|
||||
};
|
||||
|
||||
writeClientServices(services, templates, '/');
|
||||
writeClientServices(services, templates, '/', false);
|
||||
|
||||
expect(fsWriteFileSync).toBeCalledWith('/Item.ts', 'dummy');
|
||||
});
|
||||
|
||||
@ -2,7 +2,6 @@ import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
import { Service } from '../client/interfaces/Service';
|
||||
import { Templates } from './readHandlebarsTemplates';
|
||||
import { exportService } from './exportService';
|
||||
import { format } from './format';
|
||||
|
||||
/**
|
||||
@ -15,9 +14,8 @@ import { format } from './format';
|
||||
export function writeClientServices(services: Service[], templates: Templates, outputPath: string, useOptions: boolean): void {
|
||||
services.forEach(service => {
|
||||
const file = path.resolve(outputPath, `${service.name}.ts`);
|
||||
const templateData = exportService(service);
|
||||
const templateResult = templates.service({
|
||||
...templateData,
|
||||
...service,
|
||||
useOptions,
|
||||
});
|
||||
fs.writeFileSync(file, format(templateResult));
|
||||
|
||||
@ -4,7 +4,14 @@ import { Client } from '../client/interfaces/Client';
|
||||
import { HttpClient } from '../index';
|
||||
import { Templates } from './readHandlebarsTemplates';
|
||||
|
||||
export function writeClientSettings(client: Client, httpClient: HttpClient, templates: Templates, outputPath: string): void {
|
||||
/**
|
||||
* Generate OpenAPI configuration file "OpenAPI.ts"
|
||||
* @param client Client object, containing, models, schemas and services.
|
||||
* @param templates The loaded handlebar templates.
|
||||
* @param outputPath Directory to write the generated files to.
|
||||
* @param httpClient The selected httpClient (fetch or XHR).
|
||||
*/
|
||||
export function writeClientSettings(client: Client, templates: Templates, outputPath: string, httpClient: HttpClient): void {
|
||||
fs.writeFileSync(
|
||||
path.resolve(outputPath, 'OpenAPI.ts'),
|
||||
templates.settings({
|
||||
|
||||
@ -67,12 +67,19 @@ exports[`generation v2 file(./test/result/v2/core/OpenAPI.ts): ./test/result/v2/
|
||||
/* eslint-disable */
|
||||
/* prettier-ignore */
|
||||
|
||||
export namespace OpenAPI {
|
||||
export let BASE = 'http://localhost:8080/api';
|
||||
export let VERSION = '9.0';
|
||||
export let CLIENT = 'fetch';
|
||||
export let TOKEN = '';
|
||||
}"
|
||||
interface Config {
|
||||
BASE: string;
|
||||
VERSION: string;
|
||||
CLIENT: 'fetch' | 'xhr';
|
||||
TOKEN: string;
|
||||
}
|
||||
|
||||
export const OpenAPI: Config = {
|
||||
BASE: 'http://localhost:8080/api',
|
||||
VERSION: '9.0',
|
||||
CLIENT: 'fetch',
|
||||
TOKEN: '',
|
||||
};"
|
||||
`;
|
||||
|
||||
exports[`generation v2 file(./test/result/v2/core/RequestOptions.ts): ./test/result/v2/core/RequestOptions.ts 1`] = `
|
||||
@ -520,12 +527,14 @@ exports[`generation v2 file(./test/result/v2/models/ArrayWithArray.ts): ./test/r
|
||||
/* eslint-disable */
|
||||
/* prettier-ignore */
|
||||
|
||||
import { ModelThatExtends } from './ModelThatExtends';
|
||||
import { ModelThatExtendsExtends } from './ModelThatExtendsExtends';
|
||||
import { ModelWithString } from './ModelWithString';
|
||||
|
||||
/**
|
||||
* This is a simple array containing an array
|
||||
*/
|
||||
export type ArrayWithArray = Array<Array<ModelWithString>>;"
|
||||
export type ArrayWithArray = Array<Array<ModelThatExtends | ModelThatExtendsExtends | ModelWithString>>;"
|
||||
`;
|
||||
|
||||
exports[`generation v2 file(./test/result/v2/models/ArrayWithBooleans.ts): ./test/result/v2/models/ArrayWithBooleans.ts 1`] = `
|
||||
@ -616,12 +625,14 @@ exports[`generation v2 file(./test/result/v2/models/DictionaryWithArray.ts): ./t
|
||||
/* prettier-ignore */
|
||||
|
||||
import { Dictionary } from './Dictionary';
|
||||
import { ModelThatExtends } from './ModelThatExtends';
|
||||
import { ModelThatExtendsExtends } from './ModelThatExtendsExtends';
|
||||
import { ModelWithString } from './ModelWithString';
|
||||
|
||||
/**
|
||||
* This is a complex dictionary
|
||||
*/
|
||||
export type DictionaryWithArray = Dictionary<Array<ModelWithString>>;"
|
||||
export type DictionaryWithArray = Dictionary<Array<ModelThatExtends | ModelThatExtendsExtends | ModelWithString>>;"
|
||||
`;
|
||||
|
||||
exports[`generation v2 file(./test/result/v2/models/DictionaryWithDictionary.ts): ./test/result/v2/models/DictionaryWithDictionary.ts 1`] = `
|
||||
@ -783,6 +794,7 @@ exports[`generation v2 file(./test/result/v2/models/ModelThatExtends.ts): ./test
|
||||
/* eslint-disable */
|
||||
/* prettier-ignore */
|
||||
|
||||
import { ModelThatExtendsExtends } from './ModelThatExtendsExtends';
|
||||
import { ModelWithString } from './ModelWithString';
|
||||
|
||||
/**
|
||||
@ -790,7 +802,7 @@ import { ModelWithString } from './ModelWithString';
|
||||
*/
|
||||
export interface ModelThatExtends extends ModelWithString {
|
||||
propExtendsA?: string;
|
||||
propExtendsB?: ModelWithString;
|
||||
propExtendsB?: ModelThatExtends | ModelThatExtendsExtends | ModelWithString;
|
||||
}
|
||||
"
|
||||
`;
|
||||
@ -809,7 +821,7 @@ import { ModelWithString } from './ModelWithString';
|
||||
*/
|
||||
export interface ModelThatExtendsExtends extends ModelWithString, ModelThatExtends {
|
||||
propExtendsC?: string;
|
||||
propExtendsD?: ModelWithString;
|
||||
propExtendsD?: ModelThatExtends | ModelThatExtendsExtends | ModelWithString;
|
||||
}
|
||||
"
|
||||
`;
|
||||
@ -820,13 +832,15 @@ exports[`generation v2 file(./test/result/v2/models/ModelWithArray.ts): ./test/r
|
||||
/* eslint-disable */
|
||||
/* prettier-ignore */
|
||||
|
||||
import { ModelThatExtends } from './ModelThatExtends';
|
||||
import { ModelThatExtendsExtends } from './ModelThatExtendsExtends';
|
||||
import { ModelWithString } from './ModelWithString';
|
||||
|
||||
/**
|
||||
* This is a model with one property containing an array
|
||||
*/
|
||||
export interface ModelWithArray {
|
||||
prop?: Array<ModelWithString>;
|
||||
prop?: Array<ModelThatExtends | ModelThatExtendsExtends | ModelWithString>;
|
||||
propWithFile?: Array<File>;
|
||||
propWithNumber?: Array<number>;
|
||||
}
|
||||
@ -891,15 +905,17 @@ exports[`generation v2 file(./test/result/v2/models/ModelWithDuplicateImports.ts
|
||||
/* eslint-disable */
|
||||
/* prettier-ignore */
|
||||
|
||||
import { ModelThatExtends } from './ModelThatExtends';
|
||||
import { ModelThatExtendsExtends } from './ModelThatExtendsExtends';
|
||||
import { ModelWithString } from './ModelWithString';
|
||||
|
||||
/**
|
||||
* This is a model with duplicated imports
|
||||
*/
|
||||
export interface ModelWithDuplicateImports {
|
||||
propA?: ModelWithString;
|
||||
propB?: ModelWithString;
|
||||
propC?: ModelWithString;
|
||||
propA?: ModelThatExtends | ModelThatExtendsExtends | ModelWithString;
|
||||
propB?: ModelThatExtends | ModelThatExtendsExtends | ModelWithString;
|
||||
propC?: ModelThatExtends | ModelThatExtendsExtends | ModelWithString;
|
||||
}
|
||||
"
|
||||
`;
|
||||
@ -910,13 +926,15 @@ exports[`generation v2 file(./test/result/v2/models/ModelWithDuplicateProperties
|
||||
/* eslint-disable */
|
||||
/* prettier-ignore */
|
||||
|
||||
import { ModelThatExtends } from './ModelThatExtends';
|
||||
import { ModelThatExtendsExtends } from './ModelThatExtendsExtends';
|
||||
import { ModelWithString } from './ModelWithString';
|
||||
|
||||
/**
|
||||
* This is a model with duplicated properties
|
||||
*/
|
||||
export interface ModelWithDuplicateProperties {
|
||||
prop?: ModelWithString;
|
||||
prop?: ModelThatExtends | ModelThatExtendsExtends | ModelWithString;
|
||||
}
|
||||
"
|
||||
`;
|
||||
@ -1088,6 +1106,8 @@ exports[`generation v2 file(./test/result/v2/models/ModelWithProperties.ts): ./t
|
||||
/* eslint-disable */
|
||||
/* prettier-ignore */
|
||||
|
||||
import { ModelThatExtends } from './ModelThatExtends';
|
||||
import { ModelThatExtendsExtends } from './ModelThatExtendsExtends';
|
||||
import { ModelWithString } from './ModelWithString';
|
||||
|
||||
/**
|
||||
@ -1099,7 +1119,7 @@ export interface ModelWithProperties {
|
||||
string?: string;
|
||||
number?: number;
|
||||
boolean?: boolean;
|
||||
reference?: ModelWithString;
|
||||
reference?: ModelThatExtends | ModelThatExtendsExtends | ModelWithString;
|
||||
}
|
||||
"
|
||||
`;
|
||||
@ -1417,7 +1437,7 @@ export const $ModelThatExtends = {
|
||||
type: 'string',
|
||||
},
|
||||
propExtendsB: {
|
||||
type: 'ModelWithString',
|
||||
type: 'ModelThatExtends | ModelThatExtendsExtends | ModelWithString',
|
||||
},
|
||||
},
|
||||
};"
|
||||
@ -1440,7 +1460,7 @@ export const $ModelThatExtendsExtends = {
|
||||
type: 'string',
|
||||
},
|
||||
propExtendsD: {
|
||||
type: 'ModelWithString',
|
||||
type: 'ModelThatExtends | ModelThatExtendsExtends | ModelWithString',
|
||||
},
|
||||
},
|
||||
};"
|
||||
@ -1521,13 +1541,13 @@ exports[`generation v2 file(./test/result/v2/schemas/$ModelWithDuplicateImports.
|
||||
export const $ModelWithDuplicateImports = {
|
||||
properties: {
|
||||
propA: {
|
||||
type: 'ModelWithString',
|
||||
type: 'ModelThatExtends | ModelThatExtendsExtends | ModelWithString',
|
||||
},
|
||||
propB: {
|
||||
type: 'ModelWithString',
|
||||
type: 'ModelThatExtends | ModelThatExtendsExtends | ModelWithString',
|
||||
},
|
||||
propC: {
|
||||
type: 'ModelWithString',
|
||||
type: 'ModelThatExtends | ModelThatExtendsExtends | ModelWithString',
|
||||
},
|
||||
},
|
||||
};"
|
||||
@ -1542,7 +1562,7 @@ exports[`generation v2 file(./test/result/v2/schemas/$ModelWithDuplicateProperti
|
||||
export const $ModelWithDuplicateProperties = {
|
||||
properties: {
|
||||
prop: {
|
||||
type: 'ModelWithString',
|
||||
type: 'ModelThatExtends | ModelThatExtendsExtends | ModelWithString',
|
||||
},
|
||||
},
|
||||
};"
|
||||
@ -1709,7 +1729,7 @@ export const $ModelWithProperties = {
|
||||
type: 'boolean',
|
||||
},
|
||||
reference: {
|
||||
type: 'ModelWithString',
|
||||
type: 'ModelThatExtends | ModelThatExtendsExtends | ModelWithString',
|
||||
},
|
||||
},
|
||||
};"
|
||||
@ -1817,6 +1837,8 @@ exports[`generation v2 file(./test/result/v2/services/ComplexService.ts): ./test
|
||||
/* eslint-disable */
|
||||
/* prettier-ignore */
|
||||
|
||||
import { ModelThatExtends } from '../models/ModelThatExtends';
|
||||
import { ModelThatExtendsExtends } from '../models/ModelThatExtendsExtends';
|
||||
import { ModelWithString } from '../models/ModelWithString';
|
||||
import { ApiError, catchGenericError } from '../core/ApiError';
|
||||
import { request as __request } from '../core/request';
|
||||
@ -1838,8 +1860,8 @@ export class ComplexService {
|
||||
},
|
||||
},
|
||||
},
|
||||
parameterReference: ModelWithString,
|
||||
): Promise<Array<ModelWithString>> {
|
||||
parameterReference: ModelThatExtends | ModelThatExtendsExtends | ModelWithString,
|
||||
): Promise<Array<ModelThatExtends | ModelThatExtendsExtends | ModelWithString>> {
|
||||
|
||||
const result = await __request({
|
||||
method: 'get',
|
||||
@ -1871,6 +1893,8 @@ exports[`generation v2 file(./test/result/v2/services/DefaultsService.ts): ./tes
|
||||
/* eslint-disable */
|
||||
/* prettier-ignore */
|
||||
|
||||
import { ModelThatExtends } from '../models/ModelThatExtends';
|
||||
import { ModelThatExtendsExtends } from '../models/ModelThatExtendsExtends';
|
||||
import { ModelWithString } from '../models/ModelWithString';
|
||||
import { ApiError, catchGenericError } from '../core/ApiError';
|
||||
import { request as __request } from '../core/request';
|
||||
@ -1891,7 +1915,7 @@ export class DefaultsService {
|
||||
parameterNumber: number = 123,
|
||||
parameterBoolean: boolean = true,
|
||||
parameterEnum: ('Success' | 'Warning' | 'Error') = 'Success',
|
||||
parameterModel: ModelWithString = {
|
||||
parameterModel: ModelThatExtends | ModelThatExtendsExtends | ModelWithString = {
|
||||
\\"prop\\": \\"Hello World\\"
|
||||
},
|
||||
): Promise<void> {
|
||||
@ -2024,7 +2048,7 @@ export class ResponseService {
|
||||
* @result ModelWithString Message for default response
|
||||
* @throws ApiError
|
||||
*/
|
||||
public static async callWithResponse(): Promise<ModelWithString> {
|
||||
public static async callWithResponse(): Promise<ModelThatExtends | ModelThatExtendsExtends | ModelWithString> {
|
||||
|
||||
const result = await __request({
|
||||
method: 'get',
|
||||
@ -2040,7 +2064,7 @@ export class ResponseService {
|
||||
* @result ModelWithString Message for default response
|
||||
* @throws ApiError
|
||||
*/
|
||||
public static async callWithDuplicateResponses(): Promise<ModelWithString> {
|
||||
public static async callWithDuplicateResponses(): Promise<ModelThatExtends | ModelThatExtendsExtends | ModelWithString> {
|
||||
|
||||
const result = await __request({
|
||||
method: 'post',
|
||||
@ -2066,7 +2090,7 @@ export class ResponseService {
|
||||
* @result ModelThatExtendsExtends Message for 202 response
|
||||
* @throws ApiError
|
||||
*/
|
||||
public static async callWithResponses(): Promise<ModelWithString | ModelThatExtends | ModelThatExtendsExtends> {
|
||||
public static async callWithResponses(): Promise<ModelThatExtends | ModelThatExtendsExtends | ModelWithString | ModelThatExtends | ModelThatExtendsExtends | ModelThatExtendsExtends> {
|
||||
|
||||
const result = await __request({
|
||||
method: 'put',
|
||||
@ -2337,12 +2361,19 @@ exports[`generation v3 file(./test/result/v3/core/OpenAPI.ts): ./test/result/v3/
|
||||
/* eslint-disable */
|
||||
/* prettier-ignore */
|
||||
|
||||
export namespace OpenAPI {
|
||||
export let BASE = '/api';
|
||||
export let VERSION = '1';
|
||||
export let CLIENT = 'fetch';
|
||||
export let TOKEN = '';
|
||||
}"
|
||||
interface Config {
|
||||
BASE: string;
|
||||
VERSION: string;
|
||||
CLIENT: 'fetch' | 'xhr';
|
||||
TOKEN: string;
|
||||
}
|
||||
|
||||
export const OpenAPI: Config = {
|
||||
BASE: '/api',
|
||||
VERSION: '1',
|
||||
CLIENT: 'fetch',
|
||||
TOKEN: '',
|
||||
};"
|
||||
`;
|
||||
|
||||
exports[`generation v3 file(./test/result/v3/core/RequestOptions.ts): ./test/result/v3/core/RequestOptions.ts 1`] = `
|
||||
@ -2796,12 +2827,14 @@ exports[`generation v3 file(./test/result/v3/models/ArrayWithArray.ts): ./test/r
|
||||
/* eslint-disable */
|
||||
/* prettier-ignore */
|
||||
|
||||
import { ModelThatExtends } from './ModelThatExtends';
|
||||
import { ModelThatExtendsExtends } from './ModelThatExtendsExtends';
|
||||
import { ModelWithString } from './ModelWithString';
|
||||
|
||||
/**
|
||||
* This is a simple array containing an array
|
||||
*/
|
||||
export type ArrayWithArray = Array<Array<ModelWithString>>;"
|
||||
export type ArrayWithArray = Array<Array<ModelThatExtends | ModelThatExtendsExtends | ModelWithString>>;"
|
||||
`;
|
||||
|
||||
exports[`generation v3 file(./test/result/v3/models/ArrayWithBooleans.ts): ./test/result/v3/models/ArrayWithBooleans.ts 1`] = `
|
||||
@ -2892,12 +2925,14 @@ exports[`generation v3 file(./test/result/v3/models/DictionaryWithArray.ts): ./t
|
||||
/* prettier-ignore */
|
||||
|
||||
import { Dictionary } from './Dictionary';
|
||||
import { ModelThatExtends } from './ModelThatExtends';
|
||||
import { ModelThatExtendsExtends } from './ModelThatExtendsExtends';
|
||||
import { ModelWithString } from './ModelWithString';
|
||||
|
||||
/**
|
||||
* This is a complex dictionary
|
||||
*/
|
||||
export type DictionaryWithArray = Dictionary<Array<ModelWithString>>;"
|
||||
export type DictionaryWithArray = Dictionary<Array<ModelThatExtends | ModelThatExtendsExtends | ModelWithString>>;"
|
||||
`;
|
||||
|
||||
exports[`generation v3 file(./test/result/v3/models/DictionaryWithDictionary.ts): ./test/result/v3/models/DictionaryWithDictionary.ts 1`] = `
|
||||
@ -3059,6 +3094,7 @@ exports[`generation v3 file(./test/result/v3/models/ModelThatExtends.ts): ./test
|
||||
/* eslint-disable */
|
||||
/* prettier-ignore */
|
||||
|
||||
import { ModelThatExtendsExtends } from './ModelThatExtendsExtends';
|
||||
import { ModelWithString } from './ModelWithString';
|
||||
|
||||
/**
|
||||
@ -3066,7 +3102,7 @@ import { ModelWithString } from './ModelWithString';
|
||||
*/
|
||||
export interface ModelThatExtends extends ModelWithString {
|
||||
propExtendsA?: string;
|
||||
propExtendsB?: ModelWithString;
|
||||
propExtendsB?: ModelThatExtends | ModelThatExtendsExtends | ModelWithString;
|
||||
}
|
||||
"
|
||||
`;
|
||||
@ -3085,7 +3121,7 @@ import { ModelWithString } from './ModelWithString';
|
||||
*/
|
||||
export interface ModelThatExtendsExtends extends ModelWithString, ModelThatExtends {
|
||||
propExtendsC?: string;
|
||||
propExtendsD?: ModelWithString;
|
||||
propExtendsD?: ModelThatExtends | ModelThatExtendsExtends | ModelWithString;
|
||||
}
|
||||
"
|
||||
`;
|
||||
@ -3096,6 +3132,8 @@ exports[`generation v3 file(./test/result/v3/models/ModelWithAnyOf.ts): ./test/r
|
||||
/* eslint-disable */
|
||||
/* prettier-ignore */
|
||||
|
||||
import { ModelThatExtends } from './ModelThatExtends';
|
||||
import { ModelThatExtendsExtends } from './ModelThatExtendsExtends';
|
||||
import { ModelWithArray } from './ModelWithArray';
|
||||
import { ModelWithDictionary } from './ModelWithDictionary';
|
||||
import { ModelWithEnum } from './ModelWithEnum';
|
||||
@ -3105,7 +3143,7 @@ import { ModelWithString } from './ModelWithString';
|
||||
* This is a model with one property with a 'any of' relationship
|
||||
*/
|
||||
export interface ModelWithAnyOf {
|
||||
propA?: ModelWithString | ModelWithEnum | ModelWithArray | ModelWithDictionary;
|
||||
propA?: ModelThatExtends | ModelThatExtendsExtends | ModelWithArray | ModelWithDictionary | ModelWithEnum | ModelWithString;
|
||||
}
|
||||
"
|
||||
`;
|
||||
@ -3116,13 +3154,15 @@ exports[`generation v3 file(./test/result/v3/models/ModelWithArray.ts): ./test/r
|
||||
/* eslint-disable */
|
||||
/* prettier-ignore */
|
||||
|
||||
import { ModelThatExtends } from './ModelThatExtends';
|
||||
import { ModelThatExtendsExtends } from './ModelThatExtendsExtends';
|
||||
import { ModelWithString } from './ModelWithString';
|
||||
|
||||
/**
|
||||
* This is a model with one property containing an array
|
||||
*/
|
||||
export interface ModelWithArray {
|
||||
prop?: Array<ModelWithString>;
|
||||
prop?: Array<ModelThatExtends | ModelThatExtendsExtends | ModelWithString>;
|
||||
propWithFile?: Array<File>;
|
||||
propWithNumber?: Array<number>;
|
||||
}
|
||||
@ -3187,15 +3227,17 @@ exports[`generation v3 file(./test/result/v3/models/ModelWithDuplicateImports.ts
|
||||
/* eslint-disable */
|
||||
/* prettier-ignore */
|
||||
|
||||
import { ModelThatExtends } from './ModelThatExtends';
|
||||
import { ModelThatExtendsExtends } from './ModelThatExtendsExtends';
|
||||
import { ModelWithString } from './ModelWithString';
|
||||
|
||||
/**
|
||||
* This is a model with duplicated imports
|
||||
*/
|
||||
export interface ModelWithDuplicateImports {
|
||||
propA?: ModelWithString;
|
||||
propB?: ModelWithString;
|
||||
propC?: ModelWithString;
|
||||
propA?: ModelThatExtends | ModelThatExtendsExtends | ModelWithString;
|
||||
propB?: ModelThatExtends | ModelThatExtendsExtends | ModelWithString;
|
||||
propC?: ModelThatExtends | ModelThatExtendsExtends | ModelWithString;
|
||||
}
|
||||
"
|
||||
`;
|
||||
@ -3206,13 +3248,15 @@ exports[`generation v3 file(./test/result/v3/models/ModelWithDuplicateProperties
|
||||
/* eslint-disable */
|
||||
/* prettier-ignore */
|
||||
|
||||
import { ModelThatExtends } from './ModelThatExtends';
|
||||
import { ModelThatExtendsExtends } from './ModelThatExtendsExtends';
|
||||
import { ModelWithString } from './ModelWithString';
|
||||
|
||||
/**
|
||||
* This is a model with duplicated properties
|
||||
*/
|
||||
export interface ModelWithDuplicateProperties {
|
||||
prop?: ModelWithString;
|
||||
prop?: ModelThatExtends | ModelThatExtendsExtends | ModelWithString;
|
||||
}
|
||||
"
|
||||
`;
|
||||
@ -3366,6 +3410,8 @@ exports[`generation v3 file(./test/result/v3/models/ModelWithOneOf.ts): ./test/r
|
||||
/* eslint-disable */
|
||||
/* prettier-ignore */
|
||||
|
||||
import { ModelThatExtends } from './ModelThatExtends';
|
||||
import { ModelThatExtendsExtends } from './ModelThatExtendsExtends';
|
||||
import { ModelWithArray } from './ModelWithArray';
|
||||
import { ModelWithDictionary } from './ModelWithDictionary';
|
||||
import { ModelWithEnum } from './ModelWithEnum';
|
||||
@ -3375,7 +3421,7 @@ import { ModelWithString } from './ModelWithString';
|
||||
* This is a model with one property with a 'one of' relationship
|
||||
*/
|
||||
export interface ModelWithOneOf {
|
||||
propA?: ModelWithString | ModelWithEnum | ModelWithArray | ModelWithDictionary;
|
||||
propA?: ModelThatExtends | ModelThatExtendsExtends | ModelWithArray | ModelWithDictionary | ModelWithEnum | ModelWithString;
|
||||
}
|
||||
"
|
||||
`;
|
||||
@ -3404,6 +3450,8 @@ exports[`generation v3 file(./test/result/v3/models/ModelWithProperties.ts): ./t
|
||||
/* eslint-disable */
|
||||
/* prettier-ignore */
|
||||
|
||||
import { ModelThatExtends } from './ModelThatExtends';
|
||||
import { ModelThatExtendsExtends } from './ModelThatExtendsExtends';
|
||||
import { ModelWithString } from './ModelWithString';
|
||||
|
||||
/**
|
||||
@ -3416,7 +3464,7 @@ export interface ModelWithProperties {
|
||||
string?: string;
|
||||
number?: number;
|
||||
boolean?: boolean;
|
||||
reference?: ModelWithString;
|
||||
reference?: ModelThatExtends | ModelThatExtendsExtends | ModelWithString;
|
||||
}
|
||||
"
|
||||
`;
|
||||
@ -3734,7 +3782,7 @@ export const $ModelThatExtends = {
|
||||
type: 'string',
|
||||
},
|
||||
propExtendsB: {
|
||||
type: 'ModelWithString',
|
||||
type: 'ModelThatExtends | ModelThatExtendsExtends | ModelWithString',
|
||||
},
|
||||
},
|
||||
};"
|
||||
@ -3757,7 +3805,7 @@ export const $ModelThatExtendsExtends = {
|
||||
type: 'string',
|
||||
},
|
||||
propExtendsD: {
|
||||
type: 'ModelWithString',
|
||||
type: 'ModelThatExtends | ModelThatExtendsExtends | ModelWithString',
|
||||
},
|
||||
},
|
||||
};"
|
||||
@ -3772,7 +3820,7 @@ exports[`generation v3 file(./test/result/v3/schemas/$ModelWithAnyOf.ts): ./test
|
||||
export const $ModelWithAnyOf = {
|
||||
properties: {
|
||||
propA: {
|
||||
type: 'ModelWithString | ModelWithEnum | ModelWithArray | ModelWithDictionary',
|
||||
type: 'ModelThatExtends | ModelThatExtendsExtends | ModelWithArray | ModelWithDictionary | ModelWithEnum | ModelWithString',
|
||||
},
|
||||
},
|
||||
};"
|
||||
@ -3853,13 +3901,13 @@ exports[`generation v3 file(./test/result/v3/schemas/$ModelWithDuplicateImports.
|
||||
export const $ModelWithDuplicateImports = {
|
||||
properties: {
|
||||
propA: {
|
||||
type: 'ModelWithString',
|
||||
type: 'ModelThatExtends | ModelThatExtendsExtends | ModelWithString',
|
||||
},
|
||||
propB: {
|
||||
type: 'ModelWithString',
|
||||
type: 'ModelThatExtends | ModelThatExtendsExtends | ModelWithString',
|
||||
},
|
||||
propC: {
|
||||
type: 'ModelWithString',
|
||||
type: 'ModelThatExtends | ModelThatExtendsExtends | ModelWithString',
|
||||
},
|
||||
},
|
||||
};"
|
||||
@ -3874,7 +3922,7 @@ exports[`generation v3 file(./test/result/v3/schemas/$ModelWithDuplicateProperti
|
||||
export const $ModelWithDuplicateProperties = {
|
||||
properties: {
|
||||
prop: {
|
||||
type: 'ModelWithString',
|
||||
type: 'ModelThatExtends | ModelThatExtendsExtends | ModelWithString',
|
||||
},
|
||||
},
|
||||
};"
|
||||
@ -4005,7 +4053,7 @@ exports[`generation v3 file(./test/result/v3/schemas/$ModelWithOneOf.ts): ./test
|
||||
export const $ModelWithOneOf = {
|
||||
properties: {
|
||||
propA: {
|
||||
type: 'ModelWithString | ModelWithEnum | ModelWithArray | ModelWithDictionary',
|
||||
type: 'ModelThatExtends | ModelThatExtendsExtends | ModelWithArray | ModelWithDictionary | ModelWithEnum | ModelWithString',
|
||||
},
|
||||
},
|
||||
};"
|
||||
@ -4064,7 +4112,7 @@ export const $ModelWithProperties = {
|
||||
type: 'boolean',
|
||||
},
|
||||
reference: {
|
||||
type: 'ModelWithString',
|
||||
type: 'ModelThatExtends | ModelThatExtendsExtends | ModelWithString',
|
||||
},
|
||||
},
|
||||
};"
|
||||
@ -4172,6 +4220,8 @@ exports[`generation v3 file(./test/result/v3/services/ComplexService.ts): ./test
|
||||
/* eslint-disable */
|
||||
/* prettier-ignore */
|
||||
|
||||
import { ModelThatExtends } from '../models/ModelThatExtends';
|
||||
import { ModelThatExtendsExtends } from '../models/ModelThatExtendsExtends';
|
||||
import { ModelWithArray } from '../models/ModelWithArray';
|
||||
import { ModelWithDictionary } from '../models/ModelWithDictionary';
|
||||
import { ModelWithEnum } from '../models/ModelWithEnum';
|
||||
@ -4188,10 +4238,7 @@ export class ComplexService {
|
||||
* @result ModelWithString Successful response
|
||||
* @throws ApiError
|
||||
*/
|
||||
public static async complexTypes({
|
||||
parameterObject,
|
||||
parameterReference,
|
||||
}: {
|
||||
public static async complexTypes(
|
||||
parameterObject: {
|
||||
first?: {
|
||||
second?: {
|
||||
@ -4199,8 +4246,8 @@ export class ComplexService {
|
||||
},
|
||||
},
|
||||
},
|
||||
parameterReference: ModelWithString,
|
||||
}): Promise<Array<ModelWithString>> {
|
||||
parameterReference: ModelThatExtends | ModelThatExtendsExtends | ModelWithString,
|
||||
): Promise<Array<ModelThatExtends | ModelThatExtendsExtends | ModelWithString>> {
|
||||
|
||||
const result = await __request({
|
||||
method: 'get',
|
||||
@ -4229,25 +4276,22 @@ export class ComplexService {
|
||||
* @result ModelWithString Success
|
||||
* @throws ApiError
|
||||
*/
|
||||
public static async complexParams({
|
||||
id,
|
||||
requestBody,
|
||||
}: {
|
||||
public static async complexParams(
|
||||
id: number,
|
||||
requestBody?: {
|
||||
readonly key: string | null,
|
||||
name: string | null,
|
||||
enabled?: boolean,
|
||||
readonly type: ('Monkey' | 'Horse' | 'Bird'),
|
||||
listOfModels?: Array<ModelWithString> | null,
|
||||
listOfModels?: Array<ModelThatExtends | ModelThatExtendsExtends | ModelWithString> | null,
|
||||
listOfStrings?: Array<string> | null,
|
||||
parameters: ModelWithString | ModelWithEnum | ModelWithArray | ModelWithDictionary,
|
||||
parameters: ModelThatExtends | ModelThatExtendsExtends | ModelWithArray | ModelWithDictionary | ModelWithEnum | ModelWithString,
|
||||
readonly user?: {
|
||||
readonly id?: number,
|
||||
readonly name?: string | null,
|
||||
},
|
||||
},
|
||||
}): Promise<ModelWithString> {
|
||||
): Promise<ModelThatExtends | ModelThatExtendsExtends | ModelWithString> {
|
||||
|
||||
const result = await __request({
|
||||
method: 'put',
|
||||
@ -4269,6 +4313,8 @@ exports[`generation v3 file(./test/result/v3/services/DefaultsService.ts): ./tes
|
||||
/* eslint-disable */
|
||||
/* prettier-ignore */
|
||||
|
||||
import { ModelThatExtends } from '../models/ModelThatExtends';
|
||||
import { ModelThatExtendsExtends } from '../models/ModelThatExtendsExtends';
|
||||
import { ModelWithString } from '../models/ModelWithString';
|
||||
import { ApiError, catchGenericError } from '../core/ApiError';
|
||||
import { request as __request } from '../core/request';
|
||||
@ -4284,21 +4330,15 @@ export class DefaultsService {
|
||||
* @param parameterModel This is a simple model
|
||||
* @throws ApiError
|
||||
*/
|
||||
public static async callWithDefaultParameters({
|
||||
parameterString = 'Hello World!',
|
||||
parameterNumber = 123,
|
||||
parameterBoolean = true,
|
||||
parameterEnum = 'Success',
|
||||
parameterModel = {
|
||||
public static async callWithDefaultParameters(
|
||||
parameterString: string | null = 'Hello World!',
|
||||
parameterNumber: number | null = 123,
|
||||
parameterBoolean: boolean | null = true,
|
||||
parameterEnum: ('Success' | 'Warning' | 'Error') = 'Success',
|
||||
parameterModel: ModelThatExtends | ModelThatExtendsExtends | ModelWithString | null = {
|
||||
\\"prop\\": \\"Hello World\\"
|
||||
},
|
||||
}: {
|
||||
parameterString: string | null,
|
||||
parameterNumber: number | null,
|
||||
parameterBoolean: boolean | null,
|
||||
parameterEnum: ('Success' | 'Warning' | 'Error'),
|
||||
parameterModel: ModelWithString | null,
|
||||
}): Promise<void> {
|
||||
): Promise<void> {
|
||||
|
||||
const result = await __request({
|
||||
method: 'get',
|
||||
@ -4363,6 +4403,8 @@ exports[`generation v3 file(./test/result/v3/services/ParametersService.ts): ./t
|
||||
/* eslint-disable */
|
||||
/* prettier-ignore */
|
||||
|
||||
import { ModelThatExtends } from '../models/ModelThatExtends';
|
||||
import { ModelThatExtendsExtends } from '../models/ModelThatExtendsExtends';
|
||||
import { ModelWithString } from '../models/ModelWithString';
|
||||
import { ApiError, catchGenericError } from '../core/ApiError';
|
||||
import { request as __request } from '../core/request';
|
||||
@ -4378,19 +4420,13 @@ export class ParametersService {
|
||||
* @param requestBody This is the parameter that goes into the body
|
||||
* @throws ApiError
|
||||
*/
|
||||
public static async callWithParameters({
|
||||
parameterHeader,
|
||||
parameterQuery,
|
||||
parameterForm,
|
||||
parameterCookie,
|
||||
requestBody,
|
||||
}: {
|
||||
public static async callWithParameters(
|
||||
parameterHeader: string | null,
|
||||
parameterQuery: string | null,
|
||||
parameterForm: string | null,
|
||||
parameterCookie: string | null,
|
||||
requestBody: ModelWithString | null,
|
||||
}): Promise<void> {
|
||||
requestBody: ModelThatExtends | ModelThatExtendsExtends | ModelWithString | null,
|
||||
): Promise<void> {
|
||||
|
||||
const result = await __request({
|
||||
method: 'get',
|
||||
@ -4426,25 +4462,16 @@ export class ParametersService {
|
||||
* @param parameterPath3 This is the parameter that goes into the path
|
||||
* @throws ApiError
|
||||
*/
|
||||
public static async callWithWeirdParameterNames({
|
||||
parameterHeader,
|
||||
parameterQuery,
|
||||
parameterForm,
|
||||
parameterCookie,
|
||||
requestBody,
|
||||
parameterPath1,
|
||||
parameterPath2,
|
||||
parameterPath3,
|
||||
}: {
|
||||
public static async callWithWeirdParameterNames(
|
||||
parameterHeader: string | null,
|
||||
parameterQuery: string | null,
|
||||
parameterForm: string | null,
|
||||
parameterCookie: string | null,
|
||||
requestBody: ModelWithString | null,
|
||||
requestBody: ModelThatExtends | ModelThatExtendsExtends | ModelWithString | null,
|
||||
parameterPath1?: string,
|
||||
parameterPath2?: string,
|
||||
parameterPath3?: string,
|
||||
}): Promise<void> {
|
||||
): Promise<void> {
|
||||
|
||||
const result = await __request({
|
||||
method: 'get',
|
||||
@ -4474,13 +4501,10 @@ export class ParametersService {
|
||||
* @param parameter This is an optional parameter
|
||||
* @throws ApiError
|
||||
*/
|
||||
public static async getCallWithOptionalParam({
|
||||
requestBody,
|
||||
parameter,
|
||||
}: {
|
||||
requestBody: ModelWithString,
|
||||
public static async getCallWithOptionalParam(
|
||||
requestBody: ModelThatExtends | ModelThatExtendsExtends | ModelWithString,
|
||||
parameter?: string,
|
||||
}): Promise<void> {
|
||||
): Promise<void> {
|
||||
|
||||
const result = await __request({
|
||||
method: 'get',
|
||||
@ -4501,13 +4525,10 @@ export class ParametersService {
|
||||
* @param requestBody This is an optional parameter
|
||||
* @throws ApiError
|
||||
*/
|
||||
public static async postCallWithOptionalParam({
|
||||
parameter,
|
||||
requestBody,
|
||||
}: {
|
||||
public static async postCallWithOptionalParam(
|
||||
parameter: string,
|
||||
requestBody?: ModelWithString,
|
||||
}): Promise<void> {
|
||||
requestBody?: ModelThatExtends | ModelThatExtendsExtends | ModelWithString,
|
||||
): Promise<void> {
|
||||
|
||||
const result = await __request({
|
||||
method: 'post',
|
||||
@ -4545,7 +4566,7 @@ export class ResponseService {
|
||||
* @result ModelWithString
|
||||
* @throws ApiError
|
||||
*/
|
||||
public static async callWithResponse(): Promise<ModelWithString> {
|
||||
public static async callWithResponse(): Promise<ModelThatExtends | ModelThatExtendsExtends | ModelWithString> {
|
||||
|
||||
const result = await __request({
|
||||
method: 'get',
|
||||
@ -4561,7 +4582,7 @@ export class ResponseService {
|
||||
* @result ModelWithString Message for default response
|
||||
* @throws ApiError
|
||||
*/
|
||||
public static async callWithDuplicateResponses(): Promise<ModelWithString> {
|
||||
public static async callWithDuplicateResponses(): Promise<ModelThatExtends | ModelThatExtendsExtends | ModelWithString> {
|
||||
|
||||
const result = await __request({
|
||||
method: 'post',
|
||||
@ -4587,7 +4608,7 @@ export class ResponseService {
|
||||
* @result ModelThatExtendsExtends Message for 202 response
|
||||
* @throws ApiError
|
||||
*/
|
||||
public static async callWithResponses(): Promise<ModelWithString | ModelThatExtends | ModelThatExtendsExtends> {
|
||||
public static async callWithResponses(): Promise<ModelThatExtends | ModelThatExtendsExtends | ModelWithString | ModelThatExtends | ModelThatExtendsExtends | ModelThatExtendsExtends> {
|
||||
|
||||
const result = await __request({
|
||||
method: 'put',
|
||||
@ -4757,25 +4778,16 @@ export class TypesService {
|
||||
* @result any Response is a simple object
|
||||
* @throws ApiError
|
||||
*/
|
||||
public static async types({
|
||||
parameterNumber = 123,
|
||||
parameterString = 'default',
|
||||
parameterBoolean = true,
|
||||
parameterObject = null,
|
||||
parameterArray,
|
||||
parameterDictionary,
|
||||
parameterEnum,
|
||||
id,
|
||||
}: {
|
||||
parameterNumber: number,
|
||||
parameterString: string | null,
|
||||
parameterBoolean: boolean | null,
|
||||
parameterObject: any,
|
||||
public static async types(
|
||||
parameterNumber: number = 123,
|
||||
parameterString: string | null = 'default',
|
||||
parameterBoolean: boolean | null = true,
|
||||
parameterObject: any = null,
|
||||
parameterArray: Array<string> | null,
|
||||
parameterDictionary: any,
|
||||
parameterEnum: ('Success' | 'Warning' | 'Error') | null,
|
||||
id?: number,
|
||||
}): Promise<number | string | boolean | any> {
|
||||
): Promise<number | string | boolean | any> {
|
||||
|
||||
const result = await __request({
|
||||
method: 'get',
|
||||
@ -4816,11 +4828,9 @@ export class UploadService {
|
||||
* @result boolean
|
||||
* @throws ApiError
|
||||
*/
|
||||
public static async uploadFile({
|
||||
file,
|
||||
}: {
|
||||
public static async uploadFile(
|
||||
file: File,
|
||||
}): Promise<boolean> {
|
||||
): Promise<boolean> {
|
||||
|
||||
const result = await __request({
|
||||
method: 'post',
|
||||
|
||||
@ -1,18 +1,38 @@
|
||||
const path = require('path');
|
||||
const ts = require('typescript');
|
||||
const OpenAPI = require('../dist');
|
||||
|
||||
OpenAPI.generate(
|
||||
'./test/mock/v2/spec.json',
|
||||
'./test/result/v2/',
|
||||
OpenAPI.HttpClient.FETCH,
|
||||
false,
|
||||
);
|
||||
function compile(dir) {
|
||||
const config = {
|
||||
compilerOptions: {
|
||||
target: 'esnext',
|
||||
module: 'commonjs',
|
||||
moduleResolution: 'node',
|
||||
},
|
||||
include: ['./index.ts'],
|
||||
};
|
||||
const configFile = ts.parseConfigFileTextToJson('tsconfig.json', JSON.stringify(config));
|
||||
const configFileResult = ts.parseJsonConfigFileContent(configFile.config, ts.sys, path.resolve(process.cwd(), dir), undefined, 'tsconfig.json');
|
||||
const compilerHost = ts.createCompilerHost(configFileResult.options);
|
||||
const compiler = ts.createProgram(configFileResult.fileNames, configFileResult.options, compilerHost);
|
||||
compiler.emit();
|
||||
}
|
||||
|
||||
OpenAPI.generate(
|
||||
'./test/mock/v3/spec.json',
|
||||
'./test/result/v3/',
|
||||
OpenAPI.HttpClient.FETCH,
|
||||
true,
|
||||
);
|
||||
OpenAPI.generate({
|
||||
input: './test/mock/v2/spec.json',
|
||||
output: './test/result/v2/',
|
||||
httpClient: OpenAPI.HttpClient.FETCH,
|
||||
useOptions: false,
|
||||
useUnionTypes: false,
|
||||
});
|
||||
|
||||
OpenAPI.compile('./test/result/v2/');
|
||||
OpenAPI.compile('./test/result/v3/');
|
||||
OpenAPI.generate({
|
||||
input: './test/mock/v3/spec.json',
|
||||
output: './test/result/v3/',
|
||||
httpClient: OpenAPI.HttpClient.FETCH,
|
||||
useOptions: false,
|
||||
useUnionTypes: false,
|
||||
});
|
||||
|
||||
compile('./test/result/v2/');
|
||||
compile('./test/result/v3/');
|
||||
|
||||
@ -6,12 +6,12 @@ describe('generation', () => {
|
||||
|
||||
describe('v2', () => {
|
||||
|
||||
OpenAPI.generate(
|
||||
'./test/mock/v2/spec.json',
|
||||
'./test/result/v2/',
|
||||
OpenAPI.HttpClient.FETCH,
|
||||
false,
|
||||
);
|
||||
OpenAPI.generate({
|
||||
input: './test/mock/v2/spec.json',
|
||||
output: './test/result/v2/',
|
||||
httpClient: OpenAPI.HttpClient.FETCH,
|
||||
write: false,
|
||||
});
|
||||
|
||||
test.each(glob
|
||||
.sync('./test/result/v2/**/*.ts')
|
||||
@ -24,12 +24,12 @@ describe('generation', () => {
|
||||
|
||||
describe('v3', () => {
|
||||
|
||||
OpenAPI.generate(
|
||||
'./test/mock/v3/spec.json',
|
||||
'./test/result/v3/',
|
||||
OpenAPI.HttpClient.FETCH,
|
||||
true,
|
||||
);
|
||||
OpenAPI.generate({
|
||||
input: './test/mock/v3/spec.json',
|
||||
output: './test/result/v3/',
|
||||
httpClient: OpenAPI.HttpClient.FETCH,
|
||||
write: false,
|
||||
});
|
||||
|
||||
test.each(glob
|
||||
.sync('./test/result/v3/**/*.ts')
|
||||
|
||||
62
tslint.json
62
tslint.json
@ -1,62 +0,0 @@
|
||||
{
|
||||
"extends": [
|
||||
"tslint:recommended",
|
||||
"tslint-config-airbnb"
|
||||
],
|
||||
"rules": {
|
||||
"align": false,
|
||||
"import-name": false,
|
||||
"ordered-imports": true,
|
||||
"object-literal-sort-keys": false,
|
||||
"no-boolean-literal-compare": false,
|
||||
"no-increment-decrement": false,
|
||||
"no-unused-variable": false,
|
||||
"no-namespace": false,
|
||||
"no-console": false,
|
||||
"no-bitwise": false,
|
||||
"no-var-requires": false,
|
||||
"radix": false,
|
||||
"member-access": true,
|
||||
"max-line-length": [false],
|
||||
"array-type": [true, "array"],
|
||||
"arrow-parens": [true, "ban-single-arg-parens"],
|
||||
"ter-arrow-parens": [true, "as-needed"],
|
||||
"no-submodule-imports": [true],
|
||||
"function-name": [true, {
|
||||
"function-regex": "^[a-zA-Z$][\\w\\d]*$",
|
||||
"method-regex": "^[a-z$][\\w\\d]*$",
|
||||
"private-method-regex": "^[a-z$][\\w\\d]*$",
|
||||
"protected-method-regex": "^[a-z$][\\w\\d]*$",
|
||||
"static-method-regex": "^[a-z$][\\w\\d]*$"
|
||||
}],
|
||||
"interface-name": [
|
||||
true,
|
||||
"never-prefix"
|
||||
],
|
||||
"variable-name": [
|
||||
true,
|
||||
"ban-keywords",
|
||||
"check-format",
|
||||
"allow-pascal-case",
|
||||
"allow-leading-underscore"
|
||||
],
|
||||
"typedef": [
|
||||
true,
|
||||
"call-signature",
|
||||
"parameter",
|
||||
"property-declaration",
|
||||
"member-variable-declaration"
|
||||
],
|
||||
"naming-convention": [true, {
|
||||
"type": "enumMember",
|
||||
"format": "UPPER_CASE"
|
||||
}],
|
||||
"ter-indent": [true, 4, {
|
||||
"SwitchCase": 1
|
||||
}],
|
||||
"jsx-no-lambda": false,
|
||||
"jsx-alignment": false,
|
||||
"jsx-wrap-multiline": false,
|
||||
"jsx-no-multiline-js": false
|
||||
}
|
||||
}
|
||||
119
yarn.lock
119
yarn.lock
@ -85,22 +85,23 @@
|
||||
semver "^5.5.0"
|
||||
|
||||
"@babel/helper-create-class-features-plugin@^7.8.3":
|
||||
version "7.8.3"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.8.3.tgz#5b94be88c255f140fd2c10dd151e7f98f4bff397"
|
||||
integrity sha512-qmp4pD7zeTxsv0JNecSBsEmG1ei2MqwJq4YQcK3ZWm/0t07QstWfvuV/vm3Qt5xNMFETn2SZqpMx2MQzbtq+KA==
|
||||
version "7.8.6"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.8.6.tgz#243a5b46e2f8f0f674dc1387631eb6b28b851de0"
|
||||
integrity sha512-klTBDdsr+VFFqaDHm5rR69OpEQtO2Qv8ECxHS1mNhJJvaHArR6a1xTf5K/eZW7eZpJbhCx3NW1Yt/sKsLXLblg==
|
||||
dependencies:
|
||||
"@babel/helper-function-name" "^7.8.3"
|
||||
"@babel/helper-member-expression-to-functions" "^7.8.3"
|
||||
"@babel/helper-optimise-call-expression" "^7.8.3"
|
||||
"@babel/helper-plugin-utils" "^7.8.3"
|
||||
"@babel/helper-replace-supers" "^7.8.3"
|
||||
"@babel/helper-replace-supers" "^7.8.6"
|
||||
"@babel/helper-split-export-declaration" "^7.8.3"
|
||||
|
||||
"@babel/helper-create-regexp-features-plugin@^7.8.3":
|
||||
version "7.8.3"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.8.3.tgz#c774268c95ec07ee92476a3862b75cc2839beb79"
|
||||
integrity sha512-Gcsm1OHCUr9o9TcJln57xhWHtdXbA2pgQ58S0Lxlks0WMGNXuki4+GLfX0p+L2ZkINUGZvfkz8rzoqJQSthI+Q==
|
||||
version "7.8.6"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.8.6.tgz#7fa040c97fb8aebe1247a5c645330c32d083066b"
|
||||
integrity sha512-bPyujWfsHhV/ztUkwGHz/RPV1T1TDEsSZDsN42JPehndA+p1KKTh3npvTadux0ZhCrytx9tvjpWNowKby3tM6A==
|
||||
dependencies:
|
||||
"@babel/helper-annotate-as-pure" "^7.8.3"
|
||||
"@babel/helper-regex" "^7.8.3"
|
||||
regexpu-core "^4.6.0"
|
||||
|
||||
@ -159,15 +160,16 @@
|
||||
"@babel/types" "^7.8.3"
|
||||
|
||||
"@babel/helper-module-transforms@^7.8.3":
|
||||
version "7.8.3"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.8.3.tgz#d305e35d02bee720fbc2c3c3623aa0c316c01590"
|
||||
integrity sha512-C7NG6B7vfBa/pwCOshpMbOYUmrYQDfCpVL/JCRu0ek8B5p8kue1+BCXpg2vOYs7w5ACB9GTOBYQ5U6NwrMg+3Q==
|
||||
version "7.8.6"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.8.6.tgz#6a13b5eecadc35692047073a64e42977b97654a4"
|
||||
integrity sha512-RDnGJSR5EFBJjG3deY0NiL0K9TO8SXxS9n/MPsbPK/s9LbQymuLNtlzvDiNS7IpecuL45cMeLVkA+HfmlrnkRg==
|
||||
dependencies:
|
||||
"@babel/helper-module-imports" "^7.8.3"
|
||||
"@babel/helper-replace-supers" "^7.8.6"
|
||||
"@babel/helper-simple-access" "^7.8.3"
|
||||
"@babel/helper-split-export-declaration" "^7.8.3"
|
||||
"@babel/template" "^7.8.3"
|
||||
"@babel/types" "^7.8.3"
|
||||
"@babel/template" "^7.8.6"
|
||||
"@babel/types" "^7.8.6"
|
||||
lodash "^4.17.13"
|
||||
|
||||
"@babel/helper-optimise-call-expression@^7.8.3":
|
||||
@ -200,17 +202,7 @@
|
||||
"@babel/traverse" "^7.8.3"
|
||||
"@babel/types" "^7.8.3"
|
||||
|
||||
"@babel/helper-replace-supers@^7.8.3":
|
||||
version "7.8.3"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.8.3.tgz#91192d25f6abbcd41da8a989d4492574fb1530bc"
|
||||
integrity sha512-xOUssL6ho41U81etpLoT2RTdvdus4VfHamCuAm4AHxGr+0it5fnwoVdwUJ7GFEqCsQYzJUhcbsN9wB9apcYKFA==
|
||||
dependencies:
|
||||
"@babel/helper-member-expression-to-functions" "^7.8.3"
|
||||
"@babel/helper-optimise-call-expression" "^7.8.3"
|
||||
"@babel/traverse" "^7.8.3"
|
||||
"@babel/types" "^7.8.3"
|
||||
|
||||
"@babel/helper-replace-supers@^7.8.6":
|
||||
"@babel/helper-replace-supers@^7.8.3", "@babel/helper-replace-supers@^7.8.6":
|
||||
version "7.8.6"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.8.6.tgz#5ada744fd5ad73203bf1d67459a27dcba67effc8"
|
||||
integrity sha512-PeMArdA4Sv/Wf4zXwBKPqVj7n9UF/xg6slNRtZW84FM7JpE1CbG8B612FyM4cxrf4fMAMGO0kR7voy1ForHHFA==
|
||||
@ -1153,7 +1145,7 @@ acorn-globals@^4.3.2:
|
||||
acorn "^6.0.1"
|
||||
acorn-walk "^6.0.1"
|
||||
|
||||
acorn-jsx@^5.1.0:
|
||||
acorn-jsx@^5.2.0:
|
||||
version "5.2.0"
|
||||
resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.2.0.tgz#4c66069173d6fdd68ed85239fc256226182b2ebe"
|
||||
integrity sha512-HiUX/+K2YpkpJ+SzBffkM/AQ2YE03S0U1kjTLVpoJdhZMOWy8qvXVN9JdLqv2QsaQ6MPYQIuNmwD8zOiYUofLQ==
|
||||
@ -1169,9 +1161,9 @@ acorn@^6.0.1:
|
||||
integrity sha512-gac8OEcQ2Li1dxIEWGZzsp2BitJxwkwcOm0zHAJLcPJaVvm58FRnk6RkuLRpU1EujipU2ZFODv2P9DLMfnV8mw==
|
||||
|
||||
acorn@^7.1.0:
|
||||
version "7.1.0"
|
||||
resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.1.0.tgz#949d36f2c292535da602283586c2477c57eb2d6c"
|
||||
integrity sha512-kL5CuoXA/dgxlBbVrflsflzQ3PAas7RYZB52NOm/6839iVYJgKMJ3cQJD+t2i5+qFa8h3MDpEOJiS64E8JLnSQ==
|
||||
version "7.1.1"
|
||||
resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.1.1.tgz#e35668de0b402f359de515c5482a1ab9f89a69bf"
|
||||
integrity sha512-add7dgA5ppRPxCFJoAGfMDi7PIBXq1RtGo7BhbLaxwrXPOmw8gq48Y9ozT01hUKy9byMjlR20EJhu5zlkErEkg==
|
||||
|
||||
agent-base@5:
|
||||
version "5.1.1"
|
||||
@ -1196,11 +1188,11 @@ ajv@^6.10.0, ajv@^6.10.2, ajv@^6.5.5:
|
||||
uri-js "^4.2.2"
|
||||
|
||||
ansi-escapes@^4.2.1:
|
||||
version "4.3.0"
|
||||
resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.0.tgz#a4ce2b33d6b214b7950d8595c212f12ac9cc569d"
|
||||
integrity sha512-EiYhwo0v255HUL6eDyuLrXEkTi7WwVCLAw+SeOQ7M7qdun1z1pum4DEm/nuqIVbPvi9RPPc9k9LbyBv6H0DwVg==
|
||||
version "4.3.1"
|
||||
resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.1.tgz#a5c47cc43181f1f38ffd7076837700d395522a61"
|
||||
integrity sha512-JWF7ocqNrp8u9oqpgV+wH5ftbt+cfvv+PTjOvKLT3AdYly/LmORARfEVT1iyjwN+4MqE5UmVKoAdIBqeoCHgLA==
|
||||
dependencies:
|
||||
type-fest "^0.8.1"
|
||||
type-fest "^0.11.0"
|
||||
|
||||
ansi-regex@^4.1.0:
|
||||
version "4.1.0"
|
||||
@ -1438,13 +1430,13 @@ browser-resolve@^1.11.3:
|
||||
resolve "1.1.7"
|
||||
|
||||
browserslist@^4.8.3, browserslist@^4.8.5:
|
||||
version "4.8.7"
|
||||
resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.8.7.tgz#ec8301ff415e6a42c949d0e66b405eb539c532d0"
|
||||
integrity sha512-gFOnZNYBHrEyUML0xr5NJ6edFaaKbTFX9S9kQHlYfCP0Rit/boRIz4G+Avq6/4haEKJXdGGUnoolx+5MWW2BoA==
|
||||
version "4.9.1"
|
||||
resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.9.1.tgz#01ffb9ca31a1aef7678128fc6a2253316aa7287c"
|
||||
integrity sha512-Q0DnKq20End3raFulq6Vfp1ecB9fh8yUNV55s8sekaDDeqBaCtWlRHCUdaWyUeSSBJM7IbM6HcsyaeYqgeDhnw==
|
||||
dependencies:
|
||||
caniuse-lite "^1.0.30001027"
|
||||
electron-to-chromium "^1.3.349"
|
||||
node-releases "^1.1.49"
|
||||
caniuse-lite "^1.0.30001030"
|
||||
electron-to-chromium "^1.3.363"
|
||||
node-releases "^1.1.50"
|
||||
|
||||
bser@2.1.1:
|
||||
version "2.1.1"
|
||||
@ -1483,10 +1475,10 @@ camelcase@5.3.1, camelcase@^5.0.0, camelcase@^5.3.1:
|
||||
resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320"
|
||||
integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==
|
||||
|
||||
caniuse-lite@^1.0.30001027:
|
||||
version "1.0.30001030"
|
||||
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001030.tgz#78076c4c6d67d3e41d6eb9399853fb27fe6e44ee"
|
||||
integrity sha512-QGK0W4Ft/Ac+zTjEiRJfwDNATvS3fodDczBXrH42784kcfqcDKpEPfN08N0HQjrAp8He/Jw8QiSS9QRn7XAbUw==
|
||||
caniuse-lite@^1.0.30001030:
|
||||
version "1.0.30001031"
|
||||
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001031.tgz#76f1bdd39e19567b855302f65102d9a8aaad5930"
|
||||
integrity sha512-DpAP5a1NGRLgYfaNCaXIRyGARi+3tJA2quZXNNA1Du26VyVkqvy2tznNu5ANyN1Y5aX44QDotZSVSUSi2uMGjg==
|
||||
|
||||
capture-exit@^2.0.0:
|
||||
version "2.0.0"
|
||||
@ -1500,7 +1492,7 @@ caseless@~0.12.0:
|
||||
resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc"
|
||||
integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=
|
||||
|
||||
chalk@^2.0.0, chalk@^2.1.0, chalk@^2.4.2:
|
||||
chalk@^2.0.0, chalk@^2.1.0:
|
||||
version "2.4.2"
|
||||
resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424"
|
||||
integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==
|
||||
@ -1811,10 +1803,10 @@ ecc-jsbn@~0.1.1:
|
||||
jsbn "~0.1.0"
|
||||
safer-buffer "^2.1.0"
|
||||
|
||||
electron-to-chromium@^1.3.349:
|
||||
version "1.3.361"
|
||||
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.361.tgz#a820bf52da171c0024314745462cfe0dc944373e"
|
||||
integrity sha512-OzSVjWpsRhJyr9PSAXkeloSe6e9viU2ToGt1wXlXFsGcxuI9vlsnalL+V/AM59Z2pEo3wRxIddtOGsT7Y6x/sQ==
|
||||
electron-to-chromium@^1.3.363:
|
||||
version "1.3.367"
|
||||
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.367.tgz#48abffcaa6591051b612ae70ddc657763ede2662"
|
||||
integrity sha512-GCHQreWs4zhKA48FNXCjvpV4kTnKoLu2PSAfKX394g34NPvTs2pPh1+jzWitNwhmOYI8zIqt36ulRVRZUgqlfA==
|
||||
|
||||
emoji-regex@^7.0.1:
|
||||
version "7.0.3"
|
||||
@ -1961,12 +1953,12 @@ eslint@6.8.0, eslint@^6.2.2:
|
||||
v8-compile-cache "^2.0.3"
|
||||
|
||||
espree@^6.1.2:
|
||||
version "6.1.2"
|
||||
resolved "https://registry.yarnpkg.com/espree/-/espree-6.1.2.tgz#6c272650932b4f91c3714e5e7b5f5e2ecf47262d"
|
||||
integrity sha512-2iUPuuPP+yW1PZaMSDM9eyVf8D5P0Hi8h83YtZ5bPc/zHYjII5khoixIUTMO794NOY8F/ThF1Bo8ncZILarUTA==
|
||||
version "6.2.0"
|
||||
resolved "https://registry.yarnpkg.com/espree/-/espree-6.2.0.tgz#349fef01a202bbab047748300deb37fa44da79d7"
|
||||
integrity sha512-Xs8airJ7RQolnDIbLtRutmfvSsAe0xqMMAantCN/GMoqf81TFbeI1T7Jpd56qYu1uuh32dOG5W/X9uO+ghPXzA==
|
||||
dependencies:
|
||||
acorn "^7.1.0"
|
||||
acorn-jsx "^5.1.0"
|
||||
acorn-jsx "^5.2.0"
|
||||
eslint-visitor-keys "^1.1.0"
|
||||
|
||||
esprima@^4.0.0, esprima@^4.0.1:
|
||||
@ -2502,22 +2494,22 @@ inherits@2.0.3:
|
||||
integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=
|
||||
|
||||
inquirer@^7.0.0:
|
||||
version "7.0.4"
|
||||
resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-7.0.4.tgz#99af5bde47153abca23f5c7fc30db247f39da703"
|
||||
integrity sha512-Bu5Td5+j11sCkqfqmUTiwv+tWisMtP0L7Q8WrqA2C/BbBhy1YTdFrvjjlrKq8oagA/tLQBski2Gcx/Sqyi2qSQ==
|
||||
version "7.0.5"
|
||||
resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-7.0.5.tgz#fb95b238ba19966c1a1f55db53c3f0ce5c9e4275"
|
||||
integrity sha512-6Z5cP+LAO0rzNE7xWjWtT84jxKa5ScLEGLgegPXeO3dGeU8lNe5Ii7SlXH6KVtLGlDuaEhsvsFjrjWjw8j5lFg==
|
||||
dependencies:
|
||||
ansi-escapes "^4.2.1"
|
||||
chalk "^2.4.2"
|
||||
chalk "^3.0.0"
|
||||
cli-cursor "^3.1.0"
|
||||
cli-width "^2.0.0"
|
||||
external-editor "^3.0.3"
|
||||
figures "^3.0.0"
|
||||
lodash "^4.17.15"
|
||||
mute-stream "0.0.8"
|
||||
run-async "^2.2.0"
|
||||
run-async "^2.4.0"
|
||||
rxjs "^6.5.3"
|
||||
string-width "^4.1.0"
|
||||
strip-ansi "^5.1.0"
|
||||
strip-ansi "^6.0.0"
|
||||
through "^2.3.6"
|
||||
|
||||
invariant@^2.2.2, invariant@^2.2.4:
|
||||
@ -3488,7 +3480,7 @@ node-notifier@^6.0.0:
|
||||
shellwords "^0.1.1"
|
||||
which "^1.3.1"
|
||||
|
||||
node-releases@^1.1.49:
|
||||
node-releases@^1.1.50:
|
||||
version "1.1.50"
|
||||
resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.50.tgz#803c40d2c45db172d0410e4efec83aa8c6ad0592"
|
||||
integrity sha512-lgAmPv9eYZ0bGwUYAKlr8MG6K4CvWliWqnkcT2P8mMAgVrH3lqfBPorFlxiG1pHQnqmavJZ9vbMXUTNyMLbrgQ==
|
||||
@ -4018,7 +4010,7 @@ rsvp@^4.8.4:
|
||||
resolved "https://registry.yarnpkg.com/rsvp/-/rsvp-4.8.5.tgz#c8f155311d167f68f21e168df71ec5b083113734"
|
||||
integrity sha512-nfMOlASu9OnRJo1mbEk2cz0D56a1MBNrJ7orjRZQG10XDyuvwksKbuXNp6qa+kbn839HwjwhBzhFmdsaEAfauA==
|
||||
|
||||
run-async@^2.2.0:
|
||||
run-async@^2.4.0:
|
||||
version "2.4.0"
|
||||
resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.4.0.tgz#e59054a5b86876cfae07f431d18cbaddc594f1e8"
|
||||
integrity sha512-xJTbh/d7Lm7SBhc1tNvTpeCHaEzoyxPrqNlvSdMfBTYwaY++UJFyXUOxAtsRUXjlqOfj8luNaR9vjCh4KeV+pg==
|
||||
@ -4520,9 +4512,9 @@ tr46@^1.0.1:
|
||||
punycode "^2.1.0"
|
||||
|
||||
tslib@^1.8.1, tslib@^1.9.0:
|
||||
version "1.11.0"
|
||||
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.11.0.tgz#f1f3528301621a53220d58373ae510ff747a66bc"
|
||||
integrity sha512-BmndXUtiTn/VDDrJzQE7Mm22Ix3PxgLltW9bSNLoeCY31gnG2OPx0QqJnuc9oMIKioYrz487i6K9o4Pdn0j+Kg==
|
||||
version "1.11.1"
|
||||
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.11.1.tgz#eb15d128827fbee2841549e171f45ed338ac7e35"
|
||||
integrity sha512-aZW88SY8kQbU7gpV19lN24LtXh/yD4ZZg6qieAJDDg+YBsJcSmLGK9QpnUjAKVG/xefmvJGd1WUmfpT/g6AJGA==
|
||||
|
||||
tsutils@^3.17.1:
|
||||
version "3.17.1"
|
||||
@ -4555,6 +4547,11 @@ type-detect@4.0.8:
|
||||
resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c"
|
||||
integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==
|
||||
|
||||
type-fest@^0.11.0:
|
||||
version "0.11.0"
|
||||
resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.11.0.tgz#97abf0872310fed88a5c466b25681576145e33f1"
|
||||
integrity sha512-OdjXJxnCN1AvyLSzeKIgXTXxV+99ZuXl3Hpo9XpJAv9MBcHrrJOQ5kV7ypXOuQie+AmWG25hLbiKdwYTifzcfQ==
|
||||
|
||||
type-fest@^0.8.1:
|
||||
version "0.8.1"
|
||||
resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d"
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user