Merge branch 'master' into pr/419

# Conflicts:
#	src/openApi/v3/parser/getModel.ts
This commit is contained in:
Ferdi Koomen 2020-11-18 23:27:38 +01:00
commit 21c92eeb28
79 changed files with 1013 additions and 801 deletions

View File

@ -24,7 +24,8 @@
"@typescript-eslint/explicit-module-boundary-types": 0,
"sort-imports": "off",
"import/order": "off",
"simple-import-sort/sort": "error",
"simple-import-sort/imports": "error",
"simple-import-sort/exports": "error",
"prettier/prettier": ["error"]
}
}

View File

@ -441,6 +441,16 @@ npm install node-fetch --save-dev
npm install form-data --save-dev
```
In order to compile the project and resolve the imports, you will need to enable the `allowSyntheticDefaultImports`
in your `tsconfig.json` file.
```json
{
"allowSyntheticDefaultImports": true
}
```
[npm-url]: https://npmjs.org/package/openapi-typescript-codegen
[npm-image]: https://img.shields.io/npm/v/openapi-typescript-codegen.svg
[license-url]: LICENSE

View File

@ -1,6 +1,6 @@
{
"name": "openapi-typescript-codegen",
"version": "0.5.4",
"version": "0.6.0",
"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",
@ -77,18 +77,18 @@
"@babel/preset-typescript": "7.12.1",
"@rollup/plugin-commonjs": "16.0.0",
"@rollup/plugin-node-resolve": "10.0.0",
"@types/express": "4.17.8",
"@types/express": "4.17.9",
"@types/jest": "26.0.15",
"@types/js-yaml": "3.12.5",
"@types/node": "14.14.6",
"@types/node": "14.14.7",
"@types/node-fetch": "2.5.7",
"@typescript-eslint/eslint-plugin": "4.6.1",
"@typescript-eslint/parser": "4.6.1",
"@typescript-eslint/eslint-plugin": "4.7.0",
"@typescript-eslint/parser": "4.7.0",
"codecov": "3.8.1",
"eslint": "7.13.0",
"eslint-config-prettier": "6.15.0",
"eslint-plugin-prettier": "3.1.4",
"eslint-plugin-simple-import-sort": "5.0.3",
"eslint-plugin-simple-import-sort": "6.0.0",
"express": "4.17.1",
"form-data": "3.0.0",
"glob": "7.1.6",
@ -97,7 +97,7 @@
"node-fetch": "2.6.1",
"prettier": "2.1.2",
"puppeteer": "5.4.1",
"rollup": "2.33.1",
"rollup": "2.33.2",
"rollup-plugin-terser": "7.0.2",
"rollup-plugin-typescript2": "0.29.0",
"typescript": "4.0.5"

View File

@ -15,6 +15,4 @@ export interface Model extends Schema {
enum: Enum[];
enums: Model[];
properties: Model[];
extendedFrom?: string[];
extendedBy?: string[];
}

View File

@ -1,5 +1,5 @@
import type { WithEnumExtension } from './Extensions/WithEnumExtension';
import { WithNullableExtension } from './Extensions/WithNullableExtension';
import type { WithNullableExtension } from './Extensions/WithNullableExtension';
import type { OpenApiItems } from './OpenApiItems';
import type { OpenApiReference } from './OpenApiReference';
import type { OpenApiSchema } from './OpenApiSchema';

View File

@ -1,45 +0,0 @@
export enum PrimaryType {
FILE = 'File',
OBJECT = 'any',
ARRAY = 'any[]',
BOOLEAN = 'boolean',
NUMBER = 'number',
STRING = 'string',
VOID = 'void',
NULL = 'null',
}
export const TYPE_MAPPINGS = new Map<string, PrimaryType>([
['file', PrimaryType.FILE],
['any', PrimaryType.OBJECT],
['object', PrimaryType.OBJECT],
['array', PrimaryType.ARRAY],
['boolean', PrimaryType.BOOLEAN],
['byte', PrimaryType.NUMBER],
['int', PrimaryType.NUMBER],
['int32', PrimaryType.NUMBER],
['int64', PrimaryType.NUMBER],
['integer', PrimaryType.NUMBER],
['float', PrimaryType.NUMBER],
['double', PrimaryType.NUMBER],
['short', PrimaryType.NUMBER],
['long', PrimaryType.NUMBER],
['number', PrimaryType.NUMBER],
['char', PrimaryType.STRING],
['date', PrimaryType.STRING],
['date-time', PrimaryType.STRING],
['password', PrimaryType.STRING],
['string', PrimaryType.STRING],
['void', PrimaryType.VOID],
['null', PrimaryType.NULL],
]);
export enum Method {
GET = 'get',
PUT = 'put',
POST = 'post',
DELETE = 'delete',
OPTIONS = 'options',
HEAD = 'head',
PATCH = 'patch',
}

View File

@ -12,8 +12,8 @@ export function extendEnum(enumerators: Enum[], definition: WithEnumExtension):
const descriptions = definition['x-enum-descriptions'];
return enumerators.map((enumerator, index) => ({
name: (names && names[index]) || enumerator.name,
description: (descriptions && descriptions[index]) || enumerator.description,
name: names?.[index] || enumerator.name,
description: descriptions?.[index] || enumerator.description,
value: enumerator.value,
type: enumerator.type,
}));

View File

@ -1,5 +1,4 @@
import type { Enum } from '../../../client/interfaces/Enum';
import { PrimaryType } from './constants';
import { isDefined } from './isDefined';
export function getEnum(values?: (string | number)[]): Enum[] {
@ -14,7 +13,7 @@ export function getEnum(values?: (string | number)[]): Enum[] {
return {
name: `_${value}`,
value: String(value),
type: PrimaryType.NUMBER,
type: 'number',
description: null,
};
}
@ -25,7 +24,7 @@ export function getEnum(values?: (string | number)[]): Enum[] {
.replace(/([a-z])([A-Z]+)/g, '$1_$2')
.toUpperCase(),
value: `'${value}'`,
type: PrimaryType.STRING,
type: 'string',
description: null,
};
});

View File

@ -1,5 +1,4 @@
import type { Enum } from '../../../client/interfaces/Enum';
import { PrimaryType } from './constants';
export function getEnumFromDescription(description: string): Enum[] {
// Check if we can find this special format string:
@ -20,7 +19,7 @@ export function getEnumFromDescription(description: string): Enum[] {
.replace(/([a-z])([A-Z]+)/g, '$1_$2')
.toUpperCase(),
value: String(value),
type: PrimaryType.NUMBER,
type: 'number',
description: null,
});
}

View File

@ -3,7 +3,8 @@ import { getMappedType } from './getMappedType';
describe('getMappedType', () => {
it('should map types to the basics', () => {
expect(getMappedType('File')).toEqual('File');
expect(getMappedType('String')).toEqual('string');
expect(getMappedType('file')).toEqual('File');
expect(getMappedType('string')).toEqual('string');
expect(getMappedType('date')).toEqual('string');
expect(getMappedType('date-time')).toEqual('string');
expect(getMappedType('float')).toEqual('number');

View File

@ -1,12 +1,34 @@
import { PrimaryType, TYPE_MAPPINGS } from './constants';
export const TYPE_MAPPINGS = new Map<string, string>([
['File', 'File'],
['file', 'File'],
['any', 'any'],
['object', 'any'],
['array', 'any[]'],
['boolean', 'boolean'],
['byte', 'number'],
['int', 'number'],
['integer', 'number'],
['float', 'number'],
['double', 'number'],
['short', 'number'],
['long', 'number'],
['number', 'number'],
['char', 'string'],
['date', 'string'],
['date-time', 'string'],
['password', 'string'],
['string', 'string'],
['void', 'void'],
['null', 'null'],
]);
/**
* Get mapped type for given type to any basic Typescript/Javascript type.
*/
export function getMappedType(type: string): PrimaryType | undefined {
return TYPE_MAPPINGS.get(type.toLowerCase());
export function getMappedType(type: string): string | undefined {
return TYPE_MAPPINGS.get(type);
}
export function hasMappedType(type: string): boolean {
return TYPE_MAPPINGS.has(type.toLowerCase());
return TYPE_MAPPINGS.has(type);
}

View File

@ -1,7 +1,6 @@
import type { Model } from '../../../client/interfaces/Model';
import type { OpenApi } from '../interfaces/OpenApi';
import type { OpenApiSchema } from '../interfaces/OpenApiSchema';
import { PrimaryType } from './constants';
import { extendEnum } from './extendEnum';
import { getComment } from './getComment';
import { getEnum } from './getEnum';
@ -14,8 +13,8 @@ export function getModel(openApi: OpenApi, definition: OpenApiSchema, isDefiniti
const model: Model = {
name: name,
export: 'interface',
type: PrimaryType.OBJECT,
base: PrimaryType.OBJECT,
type: 'any',
base: 'any',
template: null,
link: null,
description: getComment(definition.description),
@ -59,8 +58,8 @@ export function getModel(openApi: OpenApi, definition: OpenApiSchema, isDefiniti
const extendedEnumerators = extendEnum(enumerators, definition);
if (extendedEnumerators.length) {
model.export = 'enum';
model.type = PrimaryType.STRING;
model.base = PrimaryType.STRING;
model.type = 'string';
model.base = 'string';
model.enum.push(...extendedEnumerators);
return model;
}
@ -70,8 +69,8 @@ export function getModel(openApi: OpenApi, definition: OpenApiSchema, isDefiniti
const enumerators = getEnumFromDescription(definition.description);
if (enumerators.length) {
model.export = 'enum';
model.type = PrimaryType.NUMBER;
model.base = PrimaryType.NUMBER;
model.type = 'number';
model.base = 'number';
model.enum.push(...enumerators);
return model;
}
@ -98,7 +97,7 @@ export function getModel(openApi: OpenApi, definition: OpenApiSchema, isDefiniti
}
}
if (definition.type === 'object' && definition.additionalProperties && typeof definition.additionalProperties === 'object') {
if (definition.type === 'object' && typeof definition.additionalProperties === 'object') {
if (definition.additionalProperties.$ref) {
const additionalProperties = getType(definition.additionalProperties.$ref);
model.export = 'dictionary';
@ -121,10 +120,10 @@ export function getModel(openApi: OpenApi, definition: OpenApiSchema, isDefiniti
if (definition.type === 'object' || definition.allOf) {
model.export = 'interface';
model.type = PrimaryType.OBJECT;
model.base = PrimaryType.OBJECT;
model.type = 'any';
model.base = 'any';
if (definition.allOf && definition.allOf.length) {
if (definition.allOf?.length) {
definition.allOf.forEach(parent => {
if (parent.$ref) {
const parentRef = getType(parent.$ref);

View File

@ -3,18 +3,19 @@ import type { OpenApi } from '../interfaces/OpenApi';
import type { OpenApiSchema } from '../interfaces/OpenApiSchema';
import { escapeName } from './escapeName';
import { getComment } from './getComment';
import type { getModel } from './getModel';
import { getPattern } from './getPattern';
import { getType } from './getType';
// Fix for circular dependency between getModel and getModelProperties
export type GetModel = (openApi: OpenApi, definition: OpenApiSchema, isDefinition?: boolean, name?: string) => Model;
// Fix for circular dependency
export type GetModelFn = typeof getModel;
export function getModelProperties(openApi: OpenApi, definition: OpenApiSchema, getModel: GetModel): Model[] {
export function getModelProperties(openApi: OpenApi, definition: OpenApiSchema, getModel: GetModelFn): Model[] {
const models: Model[] = [];
for (const propertyName in definition.properties) {
if (definition.properties.hasOwnProperty(propertyName)) {
const property = definition.properties[propertyName];
const propertyRequired = definition.required && definition.required.includes(propertyName);
const propertyRequired = definition.required?.includes(propertyName);
if (property.$ref) {
const model = getType(property.$ref);
models.push({

View File

@ -13,7 +13,7 @@ import { getOperationResults } from './getOperationResults';
import { getServiceClassName } from './getServiceClassName';
export function getOperation(openApi: OpenApi, url: string, method: string, op: OpenApiOperation, pathParams: OperationParameters): Operation {
const serviceName = (op.tags && op.tags[0]) || 'Service';
const serviceName = op.tags?.[0] || 'Service';
const serviceClassName = getServiceClassName(serviceName);
const operationNameFallback = `${method}${serviceClassName}`;
const operationName = getOperationName(op.operationId || operationNameFallback);

View File

@ -1,7 +1,6 @@
import type { OperationParameter } from '../../../client/interfaces/OperationParameter';
import type { OpenApi } from '../interfaces/OpenApi';
import type { OpenApiParameter } from '../interfaces/OpenApiParameter';
import { PrimaryType } from './constants';
import { extendEnum } from './extendEnum';
import { getComment } from './getComment';
import { getEnum } from './getEnum';
@ -18,8 +17,8 @@ export function getOperationParameter(openApi: OpenApi, parameter: OpenApiParame
prop: parameter.name,
export: 'interface',
name: getOperationParameterName(parameter.name),
type: PrimaryType.OBJECT,
base: PrimaryType.OBJECT,
type: 'any',
base: 'any',
template: null,
link: null,
description: getComment(parameter.description),
@ -62,8 +61,8 @@ export function getOperationParameter(openApi: OpenApi, parameter: OpenApiParame
const extendedEnumerators = extendEnum(enumerators, parameter);
if (extendedEnumerators.length) {
operationParameter.export = 'enum';
operationParameter.type = PrimaryType.STRING;
operationParameter.base = PrimaryType.STRING;
operationParameter.type = 'string';
operationParameter.base = 'string';
operationParameter.enum.push(...extendedEnumerators);
operationParameter.default = getOperationParameterDefault(parameter, operationParameter);
return operationParameter;
@ -74,8 +73,8 @@ export function getOperationParameter(openApi: OpenApi, parameter: OpenApiParame
const enumerators = getEnumFromDescription(parameter.description);
if (enumerators.length) {
operationParameter.export = 'enum';
operationParameter.type = PrimaryType.NUMBER;
operationParameter.base = PrimaryType.NUMBER;
operationParameter.type = 'number';
operationParameter.base = 'number';
operationParameter.enum.push(...enumerators);
operationParameter.default = getOperationParameterDefault(parameter, operationParameter);
return operationParameter;

View File

@ -16,7 +16,7 @@ export function getOperationParameterDefault(parameter: OpenApiParameter, operat
case 'int':
case 'integer':
case 'number':
if (operationParameter.export == 'enum' && operationParameter.enum.length && operationParameter.enum[parameter.default]) {
if (operationParameter.export == 'enum' && operationParameter.enum?.[parameter.default]) {
return operationParameter.enum[parameter.default].value;
}
return parameter.default;

View File

@ -1,7 +1,6 @@
import type { OperationResponse } from '../../../client/interfaces/OperationResponse';
import type { OpenApi } from '../interfaces/OpenApi';
import type { OpenApiResponse } from '../interfaces/OpenApiResponse';
import { PrimaryType } from './constants';
import { getComment } from './getComment';
import { getModel } from './getModel';
import { getPattern } from './getPattern';
@ -14,8 +13,8 @@ export function getOperationResponse(openApi: OpenApi, response: OpenApiResponse
code: responseCode,
description: getComment(response.description)!,
export: 'generic',
type: PrimaryType.OBJECT,
base: PrimaryType.OBJECT,
type: 'any',
base: 'any',
template: null,
link: null,
isDefinition: false,
@ -36,8 +35,8 @@ export function getOperationResponse(openApi: OpenApi, response: OpenApiResponse
if (response.headers.hasOwnProperty(name)) {
operationResponse.in = 'header';
operationResponse.name = name;
operationResponse.type = PrimaryType.STRING;
operationResponse.base = PrimaryType.STRING;
operationResponse.type = 'string';
operationResponse.base = 'string';
return operationResponse;
}
}

View File

@ -1,6 +1,5 @@
import type { Model } from '../../../client/interfaces/Model';
import type { OperationResponse } from '../../../client/interfaces/OperationResponse';
import { PrimaryType } from './constants';
function areEqual(a: Model, b: Model): boolean {
const equal = a.type === b.type && a.base === b.base && a.template === b.template;
@ -26,8 +25,8 @@ export function getOperationResults(operationResponses: OperationResponse[]): Op
code: 200,
description: '',
export: 'interface',
type: PrimaryType.OBJECT,
base: PrimaryType.OBJECT,
type: 'any',
base: 'any',
template: null,
link: null,
isDefinition: false,

View File

@ -5,7 +5,7 @@ import type { OpenApi } from '../interfaces/OpenApi';
* @param openApi
*/
export function getServer(openApi: OpenApi): string {
const scheme = (openApi.schemes && openApi.schemes[0]) || 'http';
const scheme = openApi.schemes?.[0] || 'http';
const host = openApi.host;
const basePath = openApi.basePath || '';
return host ? `${scheme}://${host}${basePath}` : basePath;

View File

@ -1,6 +1,5 @@
import type { Service } from '../../../client/interfaces/Service';
import type { OpenApi } from '../interfaces/OpenApi';
import { Method } from './constants';
import { getOperation } from './getOperation';
import { getOperationParameters } from './getOperationParameters';
@ -19,13 +18,13 @@ export function getServices(openApi: OpenApi): Service[] {
for (const method in path) {
if (path.hasOwnProperty(method)) {
switch (method) {
case Method.GET:
case Method.PUT:
case Method.POST:
case Method.DELETE:
case Method.OPTIONS:
case Method.HEAD:
case Method.PATCH:
case 'get':
case 'put':
case 'post':
case 'delete':
case 'options':
case 'head':
case 'patch':
// Each method contains an OpenAPI operation, we parse the operation
const op = path[method]!;
const operation = getOperation(openApi, url, method, op, pathParams);

View File

@ -10,7 +10,7 @@ describe('getType', () => {
});
it('should convert string', () => {
const type = getType('String');
const type = getType('string');
expect(type.type).toEqual('string');
expect(type.base).toEqual('string');
expect(type.template).toEqual(null);
@ -18,7 +18,7 @@ describe('getType', () => {
});
it('should convert string array', () => {
const type = getType('Array[String]');
const type = getType('array[string]');
expect(type.type).toEqual('string[]');
expect(type.base).toEqual('string');
expect(type.template).toEqual(null);
@ -26,7 +26,7 @@ describe('getType', () => {
});
it('should convert template with primary', () => {
const type = getType('#/definitions/Link[String]');
const type = getType('#/definitions/Link[string]');
expect(type.type).toEqual('Link<string>');
expect(type.base).toEqual('Link');
expect(type.template).toEqual('string');

View File

@ -1,5 +1,4 @@
import type { Type } from '../../../client/interfaces/Type';
import { PrimaryType } from './constants';
import { getMappedType, hasMappedType } from './getMappedType';
import { stripNamespace } from './stripNamespace';
@ -14,8 +13,8 @@ function encode(value: string): string {
*/
export function getType(value?: string, template?: string): Type {
const result: Type = {
type: PrimaryType.OBJECT,
base: PrimaryType.OBJECT,
type: 'any',
base: 'any',
template: null,
imports: [],
};
@ -24,11 +23,11 @@ export function getType(value?: string, template?: string): Type {
if (/\[.*\]$/g.test(valueClean)) {
const matches = valueClean.match(/(.*?)\[(.*)\]$/);
if (matches && matches.length) {
if (matches?.length) {
const match1 = getType(encode(matches[1]));
const match2 = getType(encode(matches[2]));
if (match1.type === PrimaryType.ARRAY) {
if (match1.type === 'any[]') {
result.type = `${match2.type}[]`;
result.base = match2.type;
match1.imports = [];

View File

@ -1,14 +0,0 @@
import { isPrimaryType } from './isPrimaryType';
describe('isPrimaryType', () => {
it('should return true for primary types', () => {
expect(isPrimaryType('number')).toBeTruthy();
expect(isPrimaryType('boolean')).toBeTruthy();
expect(isPrimaryType('string')).toBeTruthy();
expect(isPrimaryType('any')).toBeTruthy();
expect(isPrimaryType('void')).toBeTruthy();
expect(isPrimaryType('null')).toBeTruthy();
expect(isPrimaryType('Array')).toBeFalsy();
expect(isPrimaryType('MyModel')).toBeFalsy();
});
});

View File

@ -1,19 +0,0 @@
import { PrimaryType } from './constants';
/**
* Check if given type is a primary type.
* @param type
*/
export function isPrimaryType(type: string): type is PrimaryType {
switch (type.toLowerCase()) {
case PrimaryType.FILE:
case PrimaryType.OBJECT:
case PrimaryType.BOOLEAN:
case PrimaryType.NUMBER:
case PrimaryType.STRING:
case PrimaryType.VOID:
case PrimaryType.NULL:
return true;
}
return false;
}

View File

@ -1,55 +0,0 @@
export enum PrimaryType {
FILE = 'File',
OBJECT = 'any',
ARRAY = 'any[]',
BOOLEAN = 'boolean',
NUMBER = 'number',
STRING = 'string',
VOID = 'void',
NULL = 'null',
}
export const TYPE_MAPPINGS = new Map<string, PrimaryType>([
['file', PrimaryType.FILE],
['any', PrimaryType.OBJECT],
['object', PrimaryType.OBJECT],
['array', PrimaryType.ARRAY],
['boolean', PrimaryType.BOOLEAN],
['byte', PrimaryType.NUMBER],
['int', PrimaryType.NUMBER],
['int32', PrimaryType.NUMBER],
['int64', PrimaryType.NUMBER],
['integer', PrimaryType.NUMBER],
['float', PrimaryType.NUMBER],
['double', PrimaryType.NUMBER],
['short', PrimaryType.NUMBER],
['long', PrimaryType.NUMBER],
['number', PrimaryType.NUMBER],
['char', PrimaryType.STRING],
['date', PrimaryType.STRING],
['date-time', PrimaryType.STRING],
['password', PrimaryType.STRING],
['string', PrimaryType.STRING],
['void', PrimaryType.VOID],
['null', PrimaryType.NULL],
]);
export enum Method {
GET = 'get',
PUT = 'put',
POST = 'post',
DELETE = 'delete',
OPTIONS = 'options',
HEAD = 'head',
PATCH = 'patch',
}
export enum ContentType {
APPLICATION_JSON_PATCH = 'application/json-patch+json',
APPLICATION_JSON = 'application/json',
TEXT_JSON = 'text/json',
TEXT_PAIN = 'text/plain',
MULTIPART_MIXED = 'multipart/mixed',
MULTIPART_RELATED = 'multipart/related',
MULTIPART_BATCH = 'multipart/batch',
}

View File

@ -12,8 +12,8 @@ export function extendEnum(enumerators: Enum[], definition: WithEnumExtension):
const descriptions = definition['x-enum-descriptions'];
return enumerators.map((enumerator, index) => ({
name: (names && names[index]) || enumerator.name,
description: (descriptions && descriptions[index]) || enumerator.description,
name: names?.[index] || enumerator.name,
description: descriptions?.[index] || enumerator.description,
value: enumerator.value,
type: enumerator.type,
}));

View File

@ -2,30 +2,29 @@ import type { Dictionary } from '../../../utils/types';
import type { OpenApi } from '../interfaces/OpenApi';
import type { OpenApiMediaType } from '../interfaces/OpenApiMediaType';
import type { OpenApiSchema } from '../interfaces/OpenApiSchema';
import { ContentType } from './constants';
export function getContent(openApi: OpenApi, content: Dictionary<OpenApiMediaType>): OpenApiSchema | null {
/* prettier-ignore */
return (
content[ContentType.APPLICATION_JSON_PATCH] &&
content[ContentType.APPLICATION_JSON_PATCH].schema
content['application/json-patch+json'] &&
content['application/json-patch+json'].schema
) || (
content[ContentType.APPLICATION_JSON] &&
content[ContentType.APPLICATION_JSON].schema
content['application/json'] &&
content['application/json'].schema
) || (
content[ContentType.TEXT_JSON] &&
content[ContentType.TEXT_JSON].schema
content['text/json'] &&
content['text/json'].schema
) || (
content[ContentType.TEXT_PAIN] &&
content[ContentType.TEXT_PAIN].schema
content['text/plain'] &&
content['text/plain'].schema
) || (
content[ContentType.MULTIPART_MIXED] &&
content[ContentType.MULTIPART_MIXED].schema
content['multipart/mixed'] &&
content['multipart/mixed'].schema
) || (
content[ContentType.MULTIPART_RELATED] &&
content[ContentType.MULTIPART_RELATED].schema
content['multipart/related'] &&
content['multipart/related'].schema
) || (
content[ContentType.MULTIPART_BATCH] &&
content[ContentType.MULTIPART_BATCH].schema
content['multipart/batch'] &&
content['multipart/batch'].schema
) || null;
}

View File

@ -1,5 +1,4 @@
import type { Enum } from '../../../client/interfaces/Enum';
import { PrimaryType } from './constants';
import { isDefined } from './isDefined';
export function getEnum(values?: (string | number)[]): Enum[] {
@ -14,7 +13,7 @@ export function getEnum(values?: (string | number)[]): Enum[] {
return {
name: `_${value}`,
value: String(value),
type: PrimaryType.NUMBER,
type: 'number',
description: null,
};
}
@ -25,7 +24,7 @@ export function getEnum(values?: (string | number)[]): Enum[] {
.replace(/([a-z])([A-Z]+)/g, '$1_$2')
.toUpperCase(),
value: `'${value}'`,
type: PrimaryType.STRING,
type: 'string',
description: null,
};
});

View File

@ -1,5 +1,4 @@
import type { Enum } from '../../../client/interfaces/Enum';
import { PrimaryType } from './constants';
export function getEnumFromDescription(description: string): Enum[] {
// Check if we can find this special format string:
@ -20,7 +19,7 @@ export function getEnumFromDescription(description: string): Enum[] {
.replace(/([a-z])([A-Z]+)/g, '$1_$2')
.toUpperCase(),
value: String(value),
type: PrimaryType.NUMBER,
type: 'number',
description: null,
});
}

View File

@ -3,7 +3,8 @@ import { getMappedType } from './getMappedType';
describe('getMappedType', () => {
it('should map types to the basics', () => {
expect(getMappedType('File')).toEqual('File');
expect(getMappedType('String')).toEqual('string');
expect(getMappedType('file')).toEqual('File');
expect(getMappedType('string')).toEqual('string');
expect(getMappedType('date')).toEqual('string');
expect(getMappedType('date-time')).toEqual('string');
expect(getMappedType('float')).toEqual('number');

View File

@ -1,12 +1,34 @@
import { PrimaryType, TYPE_MAPPINGS } from './constants';
export const TYPE_MAPPINGS = new Map<string, string>([
['File', 'File'],
['file', 'File'],
['any', 'any'],
['object', 'any'],
['array', 'any[]'],
['boolean', 'boolean'],
['byte', 'number'],
['int', 'number'],
['integer', 'number'],
['float', 'number'],
['double', 'number'],
['short', 'number'],
['long', 'number'],
['number', 'number'],
['char', 'string'],
['date', 'string'],
['date-time', 'string'],
['password', 'string'],
['string', 'string'],
['void', 'void'],
['null', 'null'],
]);
/**
* Get mapped type for given type to any basic Typescript/Javascript type.
*/
export function getMappedType(type: string): PrimaryType | undefined {
return TYPE_MAPPINGS.get(type.toLowerCase());
export function getMappedType(type: string): string | undefined {
return TYPE_MAPPINGS.get(type);
}
export function hasMappedType(type: string): boolean {
return TYPE_MAPPINGS.has(type.toLowerCase());
return TYPE_MAPPINGS.has(type);
}

View File

@ -1,7 +1,6 @@
import type { Model } from '../../../client/interfaces/Model';
import type { OpenApi } from '../interfaces/OpenApi';
import type { OpenApiSchema } from '../interfaces/OpenApiSchema';
import { PrimaryType } from './constants';
import { extendEnum } from './extendEnum';
import { getComment } from './getComment';
import { getEnum } from './getEnum';
@ -15,8 +14,8 @@ export function getModel(openApi: OpenApi, definition: OpenApiSchema, isDefiniti
const model: Model = {
name: name,
export: 'interface',
type: PrimaryType.OBJECT,
base: PrimaryType.OBJECT,
type: 'any',
base: 'any',
template: null,
link: null,
description: getComment(definition.description),
@ -61,8 +60,8 @@ export function getModel(openApi: OpenApi, definition: OpenApiSchema, isDefiniti
const extendedEnumerators = extendEnum(enumerators, definition);
if (extendedEnumerators.length) {
model.export = 'enum';
model.type = PrimaryType.STRING;
model.base = PrimaryType.STRING;
model.type = 'string';
model.base = 'string';
model.enum.push(...extendedEnumerators);
model.default = getModelDefault(definition, model);
return model;
@ -73,8 +72,8 @@ export function getModel(openApi: OpenApi, definition: OpenApiSchema, isDefiniti
const enumerators = getEnumFromDescription(definition.description);
if (enumerators.length) {
model.export = 'enum';
model.type = PrimaryType.NUMBER;
model.base = PrimaryType.NUMBER;
model.type = 'number';
model.base = 'number';
model.enum.push(...enumerators);
model.default = getModelDefault(definition, model);
return model;
@ -126,9 +125,6 @@ export function getModel(openApi: OpenApi, definition: OpenApiSchema, isDefiniti
return model;
}
}
// TODO:
// Add correct support for oneOf
// https://swagger.io/docs/specification/data-models/oneof-anyof-allof-not/
if (definition.oneOf?.length || definition.anyOf?.length || definition.allOf?.length) {
let types: OpenApiSchema[] = [];
@ -151,8 +147,8 @@ export function getModel(openApi: OpenApi, definition: OpenApiSchema, isDefiniti
if (definition.type === 'object') {
model.export = 'interface';
model.type = PrimaryType.OBJECT;
model.base = PrimaryType.OBJECT;
model.type = 'any';
model.base = 'any';
model.default = getModelDefault(definition, model);
const properties = getModelProperties(openApi, definition, getModel);
properties.forEach(property => {

View File

@ -16,7 +16,7 @@ export function getModelDefault(definition: OpenApiSchema, model?: Model): strin
case 'int':
case 'integer':
case 'number':
if (model && model.export == 'enum' && model.enum.length && model.enum[definition.default]) {
if (model?.export == 'enum' && model.enum?.[definition.default]) {
return model.enum[definition.default].value;
}
return definition.default;

View File

@ -3,18 +3,19 @@ import type { OpenApi } from '../interfaces/OpenApi';
import type { OpenApiSchema } from '../interfaces/OpenApiSchema';
import { escapeName } from './escapeName';
import { getComment } from './getComment';
import type { getModel } from './getModel';
import { getPattern } from './getPattern';
import { getType } from './getType';
// Fix for circular dependency between getModel and getModelProperties
export type GetModel = (openApi: OpenApi, definition: OpenApiSchema, isDefinition?: boolean, name?: string) => Model;
// Fix for circular dependency
export type GetModelFn = typeof getModel;
export function getModelProperties(openApi: OpenApi, definition: OpenApiSchema, getModel: GetModel): Model[] {
export function getModelProperties(openApi: OpenApi, definition: OpenApiSchema, getModel: GetModelFn): Model[] {
const models: Model[] = [];
for (const propertyName in definition.properties) {
if (definition.properties.hasOwnProperty(propertyName)) {
const property = definition.properties[propertyName];
const propertyRequired = definition.required && definition.required.includes(propertyName);
const propertyRequired = definition.required?.includes(propertyName);
if (property.$ref) {
const model = getType(property.$ref);
models.push({

View File

@ -17,7 +17,7 @@ import { getServiceClassName } from './getServiceClassName';
import { sortByRequired } from './sortByRequired';
export function getOperation(openApi: OpenApi, url: string, method: string, op: OpenApiOperation, pathParams: OperationParameters): Operation {
const serviceName = (op.tags && op.tags[0]) || 'Service';
const serviceName = op.tags?.[0] || 'Service';
const serviceClassName = getServiceClassName(serviceName);
const operationNameFallback = `${method}${serviceClassName}`;
const operationName = getOperationName(op.operationId || operationNameFallback);

View File

@ -1,7 +1,6 @@
import type { OperationParameter } from '../../../client/interfaces/OperationParameter';
import type { OpenApi } from '../interfaces/OpenApi';
import type { OpenApiParameter } from '../interfaces/OpenApiParameter';
import { PrimaryType } from './constants';
import { getComment } from './getComment';
import { getModel } from './getModel';
import { getModelDefault } from './getModelDefault';
@ -15,8 +14,8 @@ export function getOperationParameter(openApi: OpenApi, parameter: OpenApiParame
prop: parameter.name,
export: 'interface',
name: getOperationParameterName(parameter.name),
type: PrimaryType.OBJECT,
base: PrimaryType.OBJECT,
type: 'any',
base: 'any',
template: null,
link: null,
description: getComment(parameter.description),

View File

@ -1,7 +1,6 @@
import type { OperationParameter } from '../../../client/interfaces/OperationParameter';
import type { OpenApi } from '../interfaces/OpenApi';
import type { OpenApiRequestBody } from '../interfaces/OpenApiRequestBody';
import { PrimaryType } from './constants';
import { getComment } from './getComment';
import { getContent } from './getContent';
import { getModel } from './getModel';
@ -14,8 +13,8 @@ export function getOperationRequestBody(openApi: OpenApi, parameter: OpenApiRequ
prop: 'body',
export: 'interface',
name: 'requestBody',
type: PrimaryType.OBJECT,
base: PrimaryType.OBJECT,
type: 'any',
base: 'any',
template: null,
link: null,
description: getComment(parameter.description),
@ -34,7 +33,7 @@ export function getOperationRequestBody(openApi: OpenApi, parameter: OpenApiRequ
if (parameter.content) {
const schema = getContent(openApi, parameter.content);
if (schema) {
if (schema && schema.$ref) {
if (schema?.$ref) {
const model = getType(schema.$ref);
requestBody.export = 'reference';
requestBody.type = model.type;

View File

@ -1,7 +1,6 @@
import type { OperationResponse } from '../../../client/interfaces/OperationResponse';
import type { OpenApi } from '../interfaces/OpenApi';
import type { OpenApiResponse } from '../interfaces/OpenApiResponse';
import { PrimaryType } from './constants';
import { getComment } from './getComment';
import { getContent } from './getContent';
import { getModel } from './getModel';
@ -15,8 +14,8 @@ export function getOperationResponse(openApi: OpenApi, response: OpenApiResponse
code: responseCode,
description: getComment(response.description)!,
export: 'generic',
type: PrimaryType.OBJECT,
base: PrimaryType.OBJECT,
type: 'any',
base: 'any',
template: null,
link: null,
isDefinition: false,
@ -37,8 +36,8 @@ export function getOperationResponse(openApi: OpenApi, response: OpenApiResponse
if (response.headers.hasOwnProperty(name)) {
operationResponse.in = 'header';
operationResponse.name = name;
operationResponse.type = PrimaryType.STRING;
operationResponse.base = PrimaryType.STRING;
operationResponse.type = 'string';
operationResponse.base = 'string';
return operationResponse;
}
}
@ -47,7 +46,7 @@ export function getOperationResponse(openApi: OpenApi, response: OpenApiResponse
if (response.content) {
const schema = getContent(openApi, response.content);
if (schema) {
if (schema && schema.$ref) {
if (schema?.$ref) {
const model = getType(schema.$ref);
operationResponse.export = 'reference';
operationResponse.type = model.type;

View File

@ -1,6 +1,5 @@
import type { Model } from '../../../client/interfaces/Model';
import type { OperationResponse } from '../../../client/interfaces/OperationResponse';
import { PrimaryType } from './constants';
function areEqual(a: Model, b: Model): boolean {
const equal = a.type === b.type && a.base === b.base && a.template === b.template;
@ -26,8 +25,8 @@ export function getOperationResults(operationResponses: OperationResponse[]): Op
code: 200,
description: '',
export: 'interface',
type: PrimaryType.OBJECT,
base: PrimaryType.OBJECT,
type: 'any',
base: 'any',
template: null,
link: null,
isDefinition: false,

View File

@ -1,9 +1,9 @@
import type { OpenApi } from '../interfaces/OpenApi';
export function getServer(openApi: OpenApi): string {
const server = openApi.servers && openApi.servers[0];
const variables = (server && server.variables) || {};
let url = (server && server.url) || '';
const server = openApi.servers?.[0];
const variables = server?.variables || {};
let url = server?.url || '';
for (const variable in variables) {
if (variables.hasOwnProperty(variable)) {
url = url.replace(`{${variable}}`, variables[variable].default);

View File

@ -1,6 +1,5 @@
import type { Service } from '../../../client/interfaces/Service';
import type { OpenApi } from '../interfaces/OpenApi';
import { Method } from './constants';
import { getOperation } from './getOperation';
import { getOperationParameters } from './getOperationParameters';
@ -19,13 +18,13 @@ export function getServices(openApi: OpenApi): Service[] {
for (const method in path) {
if (path.hasOwnProperty(method)) {
switch (method) {
case Method.GET:
case Method.PUT:
case Method.POST:
case Method.DELETE:
case Method.OPTIONS:
case Method.HEAD:
case Method.PATCH:
case 'get':
case 'put':
case 'post':
case 'delete':
case 'options':
case 'head':
case 'patch':
// Each method contains an OpenAPI operation, we parse the operation
const op = path[method]!;
const operation = getOperation(openApi, url, method, op, pathParams);

View File

@ -10,7 +10,7 @@ describe('getType', () => {
});
it('should convert string', () => {
const type = getType('String');
const type = getType('string');
expect(type.type).toEqual('string');
expect(type.base).toEqual('string');
expect(type.template).toEqual(null);
@ -18,7 +18,7 @@ describe('getType', () => {
});
it('should convert string array', () => {
const type = getType('Array[String]');
const type = getType('array[string]');
expect(type.type).toEqual('string[]');
expect(type.base).toEqual('string');
expect(type.template).toEqual(null);
@ -26,7 +26,7 @@ describe('getType', () => {
});
it('should convert template with primary', () => {
const type = getType('#/components/schemas/Link[String]');
const type = getType('#/components/schemas/Link[string]');
expect(type.type).toEqual('Link<string>');
expect(type.base).toEqual('Link');
expect(type.template).toEqual('string');

View File

@ -1,5 +1,4 @@
import type { Type } from '../../../client/interfaces/Type';
import { PrimaryType } from './constants';
import { getMappedType, hasMappedType } from './getMappedType';
import { stripNamespace } from './stripNamespace';
@ -14,8 +13,8 @@ function encode(value: string): string {
*/
export function getType(value?: string, template?: string): Type {
const result: Type = {
type: PrimaryType.OBJECT,
base: PrimaryType.OBJECT,
type: 'any',
base: 'any',
template: null,
imports: [],
};
@ -24,11 +23,11 @@ export function getType(value?: string, template?: string): Type {
if (/\[.*\]$/g.test(valueClean)) {
const matches = valueClean.match(/(.*?)\[(.*)\]$/);
if (matches && matches.length) {
if (matches?.length) {
const match1 = getType(encode(matches[1]));
const match2 = getType(encode(matches[2]));
if (match1.type === PrimaryType.ARRAY) {
if (match1.type === 'any[]') {
result.type = `${match2.type}[]`;
result.base = `${match2.type}`;
match1.imports = [];

View File

@ -1,14 +0,0 @@
import { isPrimaryType } from './isPrimaryType';
describe('isPrimaryType', () => {
it('should return true for primary types', () => {
expect(isPrimaryType('number')).toBeTruthy();
expect(isPrimaryType('boolean')).toBeTruthy();
expect(isPrimaryType('string')).toBeTruthy();
expect(isPrimaryType('any')).toBeTruthy();
expect(isPrimaryType('void')).toBeTruthy();
expect(isPrimaryType('null')).toBeTruthy();
expect(isPrimaryType('Array')).toBeFalsy();
expect(isPrimaryType('MyModel')).toBeFalsy();
});
});

View File

@ -1,19 +0,0 @@
import { PrimaryType } from './constants';
/**
* Check if given type is a primary type.
* @param type
*/
export function isPrimaryType(type: string): type is PrimaryType {
switch (type.toLowerCase()) {
case PrimaryType.FILE:
case PrimaryType.OBJECT:
case PrimaryType.BOOLEAN:
case PrimaryType.NUMBER:
case PrimaryType.STRING:
case PrimaryType.VOID:
case PrimaryType.NULL:
return true;
}
return false;
}

View File

@ -1,15 +1,24 @@
{{>header}}
type Resolver<T> = () => Promise<T>;
type Headers = Record<string, string>;
interface Config {
BASE: string;
VERSION: string;
WITH_CREDENTIALS: boolean;
TOKEN: string | (() => Promise<string>);
TOKEN?: string | Resolver<string>;
USERNAME?: string | Resolver<string>;
PASSWORD?: string | Resolver<string>;
HEADERS?: Headers | Resolver<Headers>;
}
export const OpenAPI: Config = {
BASE: '{{{server}}}',
VERSION: '{{{version}}}',
WITH_CREDENTIALS: false,
TOKEN: '',
TOKEN: undefined,
USERNAME: undefined,
PASSWORD: undefined,
HEADERS: undefined,
};

View File

@ -1,14 +1,23 @@
async function getHeaders(options: ApiRequestOptions): Promise<Headers> {
const headers = new Headers({
Accept: 'application/json',
...OpenAPI.HEADERS,
...options.headers,
});
const token = await getToken();
if (isDefined(token) && token !== '') {
const token = await resolve(OpenAPI.TOKEN);
const username = await resolve(OpenAPI.USERNAME);
const password = await resolve(OpenAPI.PASSWORD);
if (isStringWithValue(token)) {
headers.append('Authorization', `Bearer ${token}`);
}
if (isStringWithValue(username) && isStringWithValue(password)) {
const credentials = btoa(`${username}:${password}`);
headers.append('Authorization', `Basic ${credentials}`);
}
if (options.body) {
if (isBlob(options.body)) {
headers.append('Content-Type', options.body.type || 'application/octet-stream');

View File

@ -11,6 +11,9 @@ import { OpenAPI } from './OpenAPI';
{{>functions/isString}}
{{>functions/isStringWithValue}}
{{>functions/isBlob}}
@ -23,7 +26,7 @@ import { OpenAPI } from './OpenAPI';
{{>functions/getFormData}}
{{>functions/getToken}}
{{>functions/resolve}}
{{>fetch/getHeaders}}

View File

@ -1,6 +0,0 @@
async function getToken(): Promise<string> {
if (typeof OpenAPI.TOKEN === 'function') {
return OpenAPI.TOKEN();
}
return OpenAPI.TOKEN;
}

View File

@ -0,0 +1,3 @@
function isStringWithValue(value: any): value is string {
return isString(value) && value !== '';
}

View File

@ -0,0 +1,8 @@
type Resolver<T> = () => Promise<T>;
async function resolve<T>(resolver?: T | Resolver<T>): Promise<T | undefined> {
if (typeof resolver === 'function') {
return (resolver as Resolver<T>)();
}
return resolver;
}

View File

@ -1,14 +1,23 @@
async function getHeaders(options: ApiRequestOptions): Promise<Headers> {
const headers = new Headers({
Accept: 'application/json',
...OpenAPI.HEADERS,
...options.headers,
});
const token = await getToken();
if (isDefined(token) && token !== '') {
const token = await resolve(OpenAPI.TOKEN);
const username = await resolve(OpenAPI.USERNAME);
const password = await resolve(OpenAPI.PASSWORD);
if (isStringWithValue(token)) {
headers.append('Authorization', `Bearer ${token}`);
}
if (isStringWithValue(username) && isStringWithValue(password)) {
const credentials = Buffer.from(`${username}:${password}`).toString('base64');
headers.append('Authorization', `Basic ${credentials}`);
}
if (options.body) {
if (isBinary(options.body)) {
headers.append('Content-Type', 'application/octet-stream');

View File

@ -1,6 +1,6 @@
{{>header}}
import * as FormData from 'form-data';
import FormData from 'form-data';
import fetch, { BodyInit, Headers, RequestInit, Response } from 'node-fetch';
import { types } from 'util';
@ -15,6 +15,9 @@ import { OpenAPI } from './OpenAPI';
{{>functions/isString}}
{{>functions/isStringWithValue}}
{{>functions/isBinary}}
@ -27,7 +30,7 @@ import { OpenAPI } from './OpenAPI';
{{>functions/getFormData}}
{{>functions/getToken}}
{{>functions/resolve}}
{{>node/getHeaders}}

View File

@ -1,14 +1,23 @@
async function getHeaders(options: ApiRequestOptions): Promise<Headers> {
const headers = new Headers({
Accept: 'application/json',
...OpenAPI.HEADERS,
...options.headers,
});
const token = await getToken();
if (isDefined(token) && token !== '') {
const token = await resolve(OpenAPI.TOKEN);
const username = await resolve(OpenAPI.USERNAME);
const password = await resolve(OpenAPI.PASSWORD);
if (isStringWithValue(token)) {
headers.append('Authorization', `Bearer ${token}`);
}
if (isStringWithValue(username) && isStringWithValue(password)) {
const credentials = btoa(`${username}:${password}`);
headers.append('Authorization', `Basic ${credentials}`);
}
if (options.body) {
if (isBlob(options.body)) {
headers.append('Content-Type', options.body.type || 'application/octet-stream');

View File

@ -11,6 +11,9 @@ import { OpenAPI } from './OpenAPI';
{{>functions/isString}}
{{>functions/isStringWithValue}}
{{>functions/isBlob}}
@ -26,7 +29,7 @@ import { OpenAPI } from './OpenAPI';
{{>functions/getFormData}}
{{>functions/getToken}}
{{>functions/resolve}}
{{>fetch/getHeaders}}

View File

@ -23,11 +23,13 @@ export class {{{name}}} {
{{#if description}}
* {{{description}}}
{{/if}}
{{#unless @root.useOptions}}
{{#if parameters}}
{{#each parameters}}
* @param {{{name}}} {{{description}}}
{{/each}}
{{/if}}
{{/unless}}
{{#each results}}
* @result {{{type}}} {{{description}}}
{{/each}}

View File

@ -6,6 +6,7 @@
{{/each}}
}: {
{{#each parameters}}
/** {{{description}}} */
{{{name}}}{{>isRequired}}: {{>type}},
{{/each}}
}

View File

@ -1,6 +1,5 @@
{
type: '{{export}}',
contains: [{{#each properties}}{{>schema}}, {{/each}}]
{{#if isReadOnly}}
isReadOnly: {{{isReadOnly}}},

View File

@ -1 +1 @@
({{#each properties}} & {{>type}}{{/each}}){{>isNullable}}
({{#each properties}}{{>type}}{{#unless @last}} & {{/unless}}{{/each}}){{>isNullable}}

View File

@ -1 +1 @@
({{#each properties}} | {{>type}}{{/each}}){{>isNullable}}
({{#each properties}}{{>type}}{{#unless @last}} | {{/unless}}{{/each}}){{>isNullable}}

11
src/typings/hbs.d.ts vendored
View File

@ -7,11 +7,10 @@
* @see: build.js for more information
*/
declare module '*.hbs' {
export default {
compiler: [8, '>= 4.3.0'],
useData: true,
main: function () {
return '';
},
const template: {
compiler: [number, string];
useData: true;
main: () => void;
};
export default template;
}

View File

@ -11,7 +11,7 @@ export enum OpenApiVersion {
*/
export function getOpenApiVersion(openApi: any): OpenApiVersion {
const info: any = openApi.swagger || openApi.openapi;
if (info && typeof info === 'string') {
if (typeof info === 'string') {
const c = info.charAt(0);
const v = Number.parseInt(c);
if (v === OpenApiVersion.V2 || v === OpenApiVersion.V3) {

View File

@ -19,7 +19,7 @@ describe('getServiceNames', () => {
imports: [],
};
const services: Service[] = [john, jane, doe];
const services = [john, jane, doe];
expect(getServiceNames([])).toEqual([]);
expect(getServiceNames(services)).toEqual(['Doe', 'Jane', 'John']);

View File

@ -12,13 +12,14 @@ import fetchSendRequest from '../templates/core/fetch/sendRequest.hbs';
import functionCatchErrors from '../templates/core/functions/catchErrors.hbs';
import functionGetFormData from '../templates/core/functions/getFormData.hbs';
import functionGetQueryString from '../templates/core/functions/getQueryString.hbs';
import functionGetToken from '../templates/core/functions/getToken.hbs';
import functionGetUrl from '../templates/core/functions/getUrl.hbs';
import functionIsBinary from '../templates/core/functions/isBinary.hbs';
import functionIsBlob from '../templates/core/functions/isBlob.hbs';
import functionIsDefined from '../templates/core/functions/isDefined.hbs';
import functionIsString from '../templates/core/functions/isString.hbs';
import functionIsStringWithValue from '../templates/core/functions/isStringWithValue.hbs';
import functionIsSuccess from '../templates/core/functions/isSuccess.hbs';
import functionResolve from '../templates/core/functions/resolve.hbs';
import nodeGetHeaders from '../templates/core/node/getHeaders.hbs';
import nodeGetRequestBody from '../templates/core/node/getRequestBody.hbs';
import nodeGetResponseBody from '../templates/core/node/getResponseBody.hbs';
@ -138,14 +139,15 @@ export function registerHandlebarTemplates(): Templates {
// Generic functions used in 'request' file @see src/templates/core/request.hbs for more info
Handlebars.registerPartial('functions/catchErrors', Handlebars.template(functionCatchErrors));
Handlebars.registerPartial('functions/getFormData', Handlebars.template(functionGetFormData));
Handlebars.registerPartial('functions/getToken', Handlebars.template(functionGetToken));
Handlebars.registerPartial('functions/getQueryString', Handlebars.template(functionGetQueryString));
Handlebars.registerPartial('functions/getUrl', Handlebars.template(functionGetUrl));
Handlebars.registerPartial('functions/isBinary', Handlebars.template(functionIsBinary));
Handlebars.registerPartial('functions/isBlob', Handlebars.template(functionIsBlob));
Handlebars.registerPartial('functions/isDefined', Handlebars.template(functionIsDefined));
Handlebars.registerPartial('functions/isString', Handlebars.template(functionIsString));
Handlebars.registerPartial('functions/isStringWithValue', Handlebars.template(functionIsStringWithValue));
Handlebars.registerPartial('functions/isSuccess', Handlebars.template(functionIsSuccess));
Handlebars.registerPartial('functions/resolve', Handlebars.template(functionResolve));
// Specific files for the fetch client implementation
Handlebars.registerPartial('fetch/getHeaders', Handlebars.template(fetchGetHeaders));

View File

@ -46,28 +46,32 @@ export async function writeClient(
throw new Error(`Output folder is not a subdirectory of the current working directory`);
}
await rmdir(outputPath);
await mkdir(outputPath);
if (exportCore) {
await rmdir(outputPathCore);
await mkdir(outputPathCore);
await writeClientCore(client, templates, outputPathCore, httpClient);
}
if (exportServices) {
await rmdir(outputPathServices);
await mkdir(outputPathServices);
await writeClientServices(client.services, templates, outputPathServices, httpClient, useUnionTypes, useOptions);
}
if (exportSchemas) {
await rmdir(outputPathSchemas);
await mkdir(outputPathSchemas);
await writeClientSchemas(client.models, templates, outputPathSchemas, httpClient, useUnionTypes);
}
if (exportModels) {
await rmdir(outputPathModels);
await mkdir(outputPathModels);
await writeClientModels(client.models, templates, outputPathModels, httpClient, useUnionTypes);
}
await writeClientIndex(client, templates, outputPath, useUnionTypes, exportCore, exportServices, exportModels, exportSchemas);
if (exportCore || exportServices || exportSchemas || exportModels) {
await mkdir(outputPath);
await writeClientIndex(client, templates, outputPath, useUnionTypes, exportCore, exportServices, exportModels, exportSchemas);
}
}

View File

@ -30,7 +30,7 @@ describe('writeClientIndex', () => {
},
};
await writeClientIndex(client, templates, '/', true, true, true, true);
await writeClientIndex(client, templates, '/', true, true, true, true, true);
expect(writeFile).toBeCalledWith('/index.ts', 'index');
});

View File

@ -1,4 +1,5 @@
import type { Model } from '../client/interfaces/Model';
import { HttpClient } from '../index';
import { writeFile } from './fileSystem';
import { Templates } from './registerHandlebarTemplates';
import { writeClientModels } from './writeClientModels';
@ -44,7 +45,7 @@ describe('writeClientModels', () => {
},
};
await writeClientModels(models, templates, '/');
await writeClientModels(models, templates, '/', HttpClient.FETCH, false);
expect(writeFile).toBeCalledWith('/MyModel.ts', 'model');
});

View File

@ -1,4 +1,5 @@
import type { Model } from '../client/interfaces/Model';
import { HttpClient } from '../index';
import { writeFile } from './fileSystem';
import { Templates } from './registerHandlebarTemplates';
import { writeClientSchemas } from './writeClientSchemas';
@ -44,7 +45,7 @@ describe('writeClientSchemas', () => {
},
};
await writeClientSchemas(models, templates, '/');
await writeClientSchemas(models, templates, '/', HttpClient.FETCH, false);
expect(writeFile).toBeCalledWith('/$MyModel.ts', 'schema');
});

View File

@ -1,4 +1,5 @@
import type { Service } from '../client/interfaces/Service';
import { HttpClient } from '../index';
import { writeFile } from './fileSystem';
import { Templates } from './registerHandlebarTemplates';
import { writeClientServices } from './writeClientServices';
@ -31,7 +32,7 @@ describe('writeClientServices', () => {
},
};
await writeClientServices(services, templates, '/', false);
await writeClientServices(services, templates, '/', HttpClient.FETCH, false, false);
expect(writeFile).toBeCalledWith('/MyService.ts', 'service');
});

View File

@ -57,18 +57,27 @@ exports[`v2 should generate: ./test/generated/v2/core/OpenAPI.ts 1`] = `
"/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
type Resolver<T> = () => Promise<T>;
type Headers = Record<string, string>;
interface Config {
BASE: string;
VERSION: string;
WITH_CREDENTIALS: boolean;
TOKEN: string | (() => Promise<string>);
TOKEN?: string | Resolver<string>;
USERNAME?: string | Resolver<string>;
PASSWORD?: string | Resolver<string>;
HEADERS?: Headers | Resolver<Headers>;
}
export const OpenAPI: Config = {
BASE: 'http://localhost:3000/base',
VERSION: '1.0',
WITH_CREDENTIALS: false,
TOKEN: '',
TOKEN: undefined,
USERNAME: undefined,
PASSWORD: undefined,
HEADERS: undefined,
};"
`;
@ -89,6 +98,10 @@ function isString(value: any): value is string {
return typeof value === 'string';
}
function isStringWithValue(value: any): value is string {
return isString(value) && value !== '';
}
function isBlob(value: any): value is Blob {
return value instanceof Blob;
}
@ -134,24 +147,35 @@ function getFormData(params: Record<string, any>): FormData {
return formData;
}
async function getToken(): Promise<string> {
if (typeof OpenAPI.TOKEN === 'function') {
return OpenAPI.TOKEN();
type Resolver<T> = () => Promise<T>;
async function resolve<T>(resolver?: T | Resolver<T>): Promise<T | undefined> {
if (typeof resolver === 'function') {
return (resolver as Resolver<T>)();
}
return OpenAPI.TOKEN;
return resolver;
}
async function getHeaders(options: ApiRequestOptions): Promise<Headers> {
const headers = new Headers({
Accept: 'application/json',
...OpenAPI.HEADERS,
...options.headers,
});
const token = await getToken();
if (isDefined(token) && token !== '') {
const token = await resolve(OpenAPI.TOKEN);
const username = await resolve(OpenAPI.USERNAME);
const password = await resolve(OpenAPI.PASSWORD);
if (isStringWithValue(token)) {
headers.append('Authorization', \`Bearer \${token}\`);
}
if (isStringWithValue(username) && isStringWithValue(password)) {
const credentials = btoa(\`\${username}:\${password}\`);
headers.append('Authorization', \`Basic \${credentials}\`);
}
if (options.body) {
if (isBlob(options.body)) {
headers.append('Content-Type', options.body.type || 'application/octet-stream');
@ -276,6 +300,7 @@ export type { ArrayWithNumbers } from './models/ArrayWithNumbers';
export type { ArrayWithProperties } from './models/ArrayWithProperties';
export type { ArrayWithReferences } from './models/ArrayWithReferences';
export type { ArrayWithStrings } from './models/ArrayWithStrings';
export type { Date } from './models/Date';
export type { DictionaryWithArray } from './models/DictionaryWithArray';
export type { DictionaryWithDictionary } from './models/DictionaryWithDictionary';
export type { DictionaryWithProperties } from './models/DictionaryWithProperties';
@ -320,6 +345,7 @@ export { $ArrayWithNumbers } from './schemas/$ArrayWithNumbers';
export { $ArrayWithProperties } from './schemas/$ArrayWithProperties';
export { $ArrayWithReferences } from './schemas/$ArrayWithReferences';
export { $ArrayWithStrings } from './schemas/$ArrayWithStrings';
export { $Date } from './schemas/$Date';
export { $DictionaryWithArray } from './schemas/$DictionaryWithArray';
export { $DictionaryWithDictionary } from './schemas/$DictionaryWithDictionary';
export { $DictionaryWithProperties } from './schemas/$DictionaryWithProperties';
@ -442,6 +468,17 @@ exports[`v2 should generate: ./test/generated/v2/models/ArrayWithStrings.ts 1`]
export type ArrayWithStrings = Array<string>;"
`;
exports[`v2 should generate: ./test/generated/v2/models/Date.ts 1`] = `
"/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
/**
* This is a type-only model that defines Date as a string
*/
export type Date = string;"
`;
exports[`v2 should generate: ./test/generated/v2/models/DictionaryWithArray.ts 1`] = `
"/* istanbul ignore file */
/* tslint:disable */
@ -1148,6 +1185,16 @@ export const $ArrayWithStrings = {
};"
`;
exports[`v2 should generate: ./test/generated/v2/schemas/$Date.ts 1`] = `
"/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
export const $Date = {
type: 'string',
};"
`;
exports[`v2 should generate: ./test/generated/v2/schemas/$DictionaryWithArray.ts 1`] = `
"/* istanbul ignore file */
/* tslint:disable */
@ -2354,18 +2401,27 @@ exports[`v3 should generate: ./test/generated/v3/core/OpenAPI.ts 1`] = `
"/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
type Resolver<T> = () => Promise<T>;
type Headers = Record<string, string>;
interface Config {
BASE: string;
VERSION: string;
WITH_CREDENTIALS: boolean;
TOKEN: string | (() => Promise<string>);
TOKEN?: string | Resolver<string>;
USERNAME?: string | Resolver<string>;
PASSWORD?: string | Resolver<string>;
HEADERS?: Headers | Resolver<Headers>;
}
export const OpenAPI: Config = {
BASE: 'http://localhost:3000/base',
VERSION: '1.0',
WITH_CREDENTIALS: false,
TOKEN: '',
TOKEN: undefined,
USERNAME: undefined,
PASSWORD: undefined,
HEADERS: undefined,
};"
`;
@ -2386,6 +2442,10 @@ function isString(value: any): value is string {
return typeof value === 'string';
}
function isStringWithValue(value: any): value is string {
return isString(value) && value !== '';
}
function isBlob(value: any): value is Blob {
return value instanceof Blob;
}
@ -2431,24 +2491,35 @@ function getFormData(params: Record<string, any>): FormData {
return formData;
}
async function getToken(): Promise<string> {
if (typeof OpenAPI.TOKEN === 'function') {
return OpenAPI.TOKEN();
type Resolver<T> = () => Promise<T>;
async function resolve<T>(resolver?: T | Resolver<T>): Promise<T | undefined> {
if (typeof resolver === 'function') {
return (resolver as Resolver<T>)();
}
return OpenAPI.TOKEN;
return resolver;
}
async function getHeaders(options: ApiRequestOptions): Promise<Headers> {
const headers = new Headers({
Accept: 'application/json',
...OpenAPI.HEADERS,
...options.headers,
});
const token = await getToken();
if (isDefined(token) && token !== '') {
const token = await resolve(OpenAPI.TOKEN);
const username = await resolve(OpenAPI.USERNAME);
const password = await resolve(OpenAPI.PASSWORD);
if (isStringWithValue(token)) {
headers.append('Authorization', \`Bearer \${token}\`);
}
if (isStringWithValue(username) && isStringWithValue(password)) {
const credentials = btoa(\`\${username}:\${password}\`);
headers.append('Authorization', \`Basic \${credentials}\`);
}
if (options.body) {
if (isBlob(options.body)) {
headers.append('Content-Type', options.body.type || 'application/octet-stream');
@ -2573,6 +2644,13 @@ export type { ArrayWithNumbers } from './models/ArrayWithNumbers';
export type { ArrayWithProperties } from './models/ArrayWithProperties';
export type { ArrayWithReferences } from './models/ArrayWithReferences';
export type { ArrayWithStrings } from './models/ArrayWithStrings';
export type { CompositionWithAllOfAndNullable } from './models/CompositionWithAllOfAndNullable';
export type { CompositionWithAnyOf } from './models/CompositionWithAnyOf';
export type { CompositionWithAnyOfAndNullable } from './models/CompositionWithAnyOfAndNullable';
export type { CompositionWithAnyOfAnonymous } from './models/CompositionWithAnyOfAnonymous';
export type { CompositionWithOneOf } from './models/CompositionWithOneOf';
export type { CompositionWithOneOfAndNullable } from './models/CompositionWithOneOfAndNullable';
export type { CompositionWithOneOfAnonymous } from './models/CompositionWithOneOfAnonymous';
export type { DictionaryWithArray } from './models/DictionaryWithArray';
export type { DictionaryWithDictionary } from './models/DictionaryWithDictionary';
export type { DictionaryWithProperties } from './models/DictionaryWithProperties';
@ -2585,9 +2663,6 @@ export { EnumWithStrings } from './models/EnumWithStrings';
export type { ModelLink } from './models/ModelLink';
export type { ModelThatExtends } from './models/ModelThatExtends';
export type { ModelThatExtendsExtends } from './models/ModelThatExtendsExtends';
export type { ModelWithAllOfAndNullable } from './models/ModelWithAllOfAndNullable';
export type { ModelWithAnyOf } from './models/ModelWithAnyOf';
export type { ModelWithAnyOfAndNullable } from './models/ModelWithAnyOfAndNullable';
export type { ModelWithArray } from './models/ModelWithArray';
export type { ModelWithBoolean } from './models/ModelWithBoolean';
export type { ModelWithCircularReference } from './models/ModelWithCircularReference';
@ -2600,8 +2675,6 @@ export type { ModelWithInteger } from './models/ModelWithInteger';
export type { ModelWithLink } from './models/ModelWithLink';
export type { ModelWithNestedEnums } from './models/ModelWithNestedEnums';
export type { ModelWithNestedProperties } from './models/ModelWithNestedProperties';
export type { ModelWithOneOf } from './models/ModelWithOneOf';
export type { ModelWithOneOfAndNullable } from './models/ModelWithOneOfAndNullable';
export type { ModelWithOrderedProperties } from './models/ModelWithOrderedProperties';
export type { ModelWithPattern } from './models/ModelWithPattern';
export type { ModelWithProperties } from './models/ModelWithProperties';
@ -2621,6 +2694,13 @@ export { $ArrayWithNumbers } from './schemas/$ArrayWithNumbers';
export { $ArrayWithProperties } from './schemas/$ArrayWithProperties';
export { $ArrayWithReferences } from './schemas/$ArrayWithReferences';
export { $ArrayWithStrings } from './schemas/$ArrayWithStrings';
export { $CompositionWithAllOfAndNullable } from './schemas/$CompositionWithAllOfAndNullable';
export { $CompositionWithAnyOf } from './schemas/$CompositionWithAnyOf';
export { $CompositionWithAnyOfAndNullable } from './schemas/$CompositionWithAnyOfAndNullable';
export { $CompositionWithAnyOfAnonymous } from './schemas/$CompositionWithAnyOfAnonymous';
export { $CompositionWithOneOf } from './schemas/$CompositionWithOneOf';
export { $CompositionWithOneOfAndNullable } from './schemas/$CompositionWithOneOfAndNullable';
export { $CompositionWithOneOfAnonymous } from './schemas/$CompositionWithOneOfAnonymous';
export { $DictionaryWithArray } from './schemas/$DictionaryWithArray';
export { $DictionaryWithDictionary } from './schemas/$DictionaryWithDictionary';
export { $DictionaryWithProperties } from './schemas/$DictionaryWithProperties';
@ -2633,9 +2713,6 @@ export { $EnumWithStrings } from './schemas/$EnumWithStrings';
export { $ModelLink } from './schemas/$ModelLink';
export { $ModelThatExtends } from './schemas/$ModelThatExtends';
export { $ModelThatExtendsExtends } from './schemas/$ModelThatExtendsExtends';
export { $ModelWithAllOfAndNullable } from './schemas/$ModelWithAllOfAndNullable';
export { $ModelWithAnyOf } from './schemas/$ModelWithAnyOf';
export { $ModelWithAnyOfAndNullable } from './schemas/$ModelWithAnyOfAndNullable';
export { $ModelWithArray } from './schemas/$ModelWithArray';
export { $ModelWithBoolean } from './schemas/$ModelWithBoolean';
export { $ModelWithCircularReference } from './schemas/$ModelWithCircularReference';
@ -2648,8 +2725,6 @@ export { $ModelWithInteger } from './schemas/$ModelWithInteger';
export { $ModelWithLink } from './schemas/$ModelWithLink';
export { $ModelWithNestedEnums } from './schemas/$ModelWithNestedEnums';
export { $ModelWithNestedProperties } from './schemas/$ModelWithNestedProperties';
export { $ModelWithOneOf } from './schemas/$ModelWithOneOf';
export { $ModelWithOneOfAndNullable } from './schemas/$ModelWithOneOfAndNullable';
export { $ModelWithOrderedProperties } from './schemas/$ModelWithOrderedProperties';
export { $ModelWithPattern } from './schemas/$ModelWithPattern';
export { $ModelWithProperties } from './schemas/$ModelWithProperties';
@ -2750,6 +2825,136 @@ exports[`v3 should generate: ./test/generated/v3/models/ArrayWithStrings.ts 1`]
export type ArrayWithStrings = Array<string>;"
`;
exports[`v3 should generate: ./test/generated/v3/models/CompositionWithAllOfAndNullable.ts 1`] = `
"/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
import type { ModelWithArray } from './ModelWithArray';
import type { ModelWithDictionary } from './ModelWithDictionary';
import type { ModelWithEnum } from './ModelWithEnum';
/**
* This is a model with one property with a 'all of' relationship
*/
export interface CompositionWithAllOfAndNullable {
propA?: ({
boolean?: boolean,
} & ModelWithEnum & ModelWithArray & ModelWithDictionary) | null;
}
"
`;
exports[`v3 should generate: ./test/generated/v3/models/CompositionWithAnyOf.ts 1`] = `
"/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
import type { ModelWithArray } from './ModelWithArray';
import type { ModelWithDictionary } from './ModelWithDictionary';
import type { ModelWithEnum } from './ModelWithEnum';
import type { ModelWithString } from './ModelWithString';
/**
* This is a model with one property with a 'any of' relationship
*/
export interface CompositionWithAnyOf {
propA?: (ModelWithString | ModelWithEnum | ModelWithArray | ModelWithDictionary);
}
"
`;
exports[`v3 should generate: ./test/generated/v3/models/CompositionWithAnyOfAndNullable.ts 1`] = `
"/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
import type { ModelWithArray } from './ModelWithArray';
import type { ModelWithDictionary } from './ModelWithDictionary';
import type { ModelWithEnum } from './ModelWithEnum';
/**
* This is a model with one property with a 'any of' relationship
*/
export interface CompositionWithAnyOfAndNullable {
propA?: ({
boolean?: boolean,
} | ModelWithEnum | ModelWithArray | ModelWithDictionary) | null;
}
"
`;
exports[`v3 should generate: ./test/generated/v3/models/CompositionWithAnyOfAnonymous.ts 1`] = `
"/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
/**
* This is a model with one property with a 'any of' relationship where the options are not $ref
*/
export interface CompositionWithAnyOfAnonymous {
propA?: ({
propA?: any,
} | string | number);
}
"
`;
exports[`v3 should generate: ./test/generated/v3/models/CompositionWithOneOf.ts 1`] = `
"/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
import type { ModelWithArray } from './ModelWithArray';
import type { ModelWithDictionary } from './ModelWithDictionary';
import type { ModelWithEnum } from './ModelWithEnum';
import type { ModelWithString } from './ModelWithString';
/**
* This is a model with one property with a 'one of' relationship
*/
export interface CompositionWithOneOf {
propA?: (ModelWithString | ModelWithEnum | ModelWithArray | ModelWithDictionary);
}
"
`;
exports[`v3 should generate: ./test/generated/v3/models/CompositionWithOneOfAndNullable.ts 1`] = `
"/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
import type { ModelWithArray } from './ModelWithArray';
import type { ModelWithDictionary } from './ModelWithDictionary';
import type { ModelWithEnum } from './ModelWithEnum';
/**
* This is a model with one property with a 'one of' relationship
*/
export interface CompositionWithOneOfAndNullable {
propA?: ({
boolean?: boolean,
} | ModelWithEnum | ModelWithArray | ModelWithDictionary) | null;
}
"
`;
exports[`v3 should generate: ./test/generated/v3/models/CompositionWithOneOfAnonymous.ts 1`] = `
"/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
/**
* This is a model with one property with a 'one of' relationship where the options are not $ref
*/
export interface CompositionWithOneOfAnonymous {
propA?: ({
propA?: any,
} | string | number);
}
"
`;
exports[`v3 should generate: ./test/generated/v3/models/DictionaryWithArray.ts 1`] = `
"/* istanbul ignore file */
/* tslint:disable */
@ -2905,7 +3110,7 @@ import type { ModelWithString } from './ModelWithString';
/**
* This is a model that extends another model
*/
export type ModelThatExtends = ( & ModelWithString & {
export type ModelThatExtends = (ModelWithString & {
propExtendsA?: string,
propExtendsB?: ModelWithString,
});"
@ -2922,71 +3127,12 @@ import type { ModelWithString } from './ModelWithString';
/**
* This is a model that extends another model
*/
export type ModelThatExtendsExtends = ( & ModelWithString & ModelThatExtends & {
export type ModelThatExtendsExtends = (ModelWithString & ModelThatExtends & {
propExtendsC?: string,
propExtendsD?: ModelWithString,
});"
`;
exports[`v3 should generate: ./test/generated/v3/models/ModelWithAllOfAndNullable.ts 1`] = `
"/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
import type { ModelWithArray } from './ModelWithArray';
import type { ModelWithDictionary } from './ModelWithDictionary';
import type { ModelWithEnum } from './ModelWithEnum';
/**
* This is a model with one property with a 'all of' relationship
*/
export interface ModelWithAllOfAndNullable {
propA?: ( & {
boolean?: boolean,
} & ModelWithEnum & ModelWithArray & ModelWithDictionary) | null;
}
"
`;
exports[`v3 should generate: ./test/generated/v3/models/ModelWithAnyOf.ts 1`] = `
"/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
import type { ModelWithArray } from './ModelWithArray';
import type { ModelWithDictionary } from './ModelWithDictionary';
import type { ModelWithEnum } from './ModelWithEnum';
import type { ModelWithString } from './ModelWithString';
/**
* This is a model with one property with a 'any of' relationship
*/
export interface ModelWithAnyOf {
propA?: ( | ModelWithString | ModelWithEnum | ModelWithArray | ModelWithDictionary);
}
"
`;
exports[`v3 should generate: ./test/generated/v3/models/ModelWithAnyOfAndNullable.ts 1`] = `
"/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
import type { ModelWithArray } from './ModelWithArray';
import type { ModelWithDictionary } from './ModelWithDictionary';
import type { ModelWithEnum } from './ModelWithEnum';
/**
* This is a model with one property with a 'any of' relationship
*/
export interface ModelWithAnyOfAndNullable {
propA?: ( | {
boolean?: boolean,
} | ModelWithEnum | ModelWithArray | ModelWithDictionary) | null;
}
"
`;
exports[`v3 should generate: ./test/generated/v3/models/ModelWithArray.ts 1`] = `
"/* istanbul ignore file */
/* tslint:disable */
@ -3231,45 +3377,6 @@ export interface ModelWithNestedProperties {
"
`;
exports[`v3 should generate: ./test/generated/v3/models/ModelWithOneOf.ts 1`] = `
"/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
import type { ModelWithArray } from './ModelWithArray';
import type { ModelWithDictionary } from './ModelWithDictionary';
import type { ModelWithEnum } from './ModelWithEnum';
import type { ModelWithString } from './ModelWithString';
/**
* This is a model with one property with a 'one of' relationship
*/
export interface ModelWithOneOf {
propA?: ( | ModelWithString | ModelWithEnum | ModelWithArray | ModelWithDictionary);
}
"
`;
exports[`v3 should generate: ./test/generated/v3/models/ModelWithOneOfAndNullable.ts 1`] = `
"/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
import type { ModelWithArray } from './ModelWithArray';
import type { ModelWithDictionary } from './ModelWithDictionary';
import type { ModelWithEnum } from './ModelWithEnum';
/**
* This is a model with one property with a 'one of' relationship
*/
export interface ModelWithOneOfAndNullable {
propA?: ( | {
boolean?: boolean,
} | ModelWithEnum | ModelWithArray | ModelWithDictionary) | null;
}
"
`;
exports[`v3 should generate: ./test/generated/v3/models/ModelWithOrderedProperties.ts 1`] = `
"/* istanbul ignore file */
/* tslint:disable */
@ -3532,6 +3639,188 @@ export const $ArrayWithStrings = {
};"
`;
exports[`v3 should generate: ./test/generated/v3/schemas/$CompositionWithAllOfAndNullable.ts 1`] = `
"/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
export const $CompositionWithAllOfAndNullable = {
properties: {
propA: {
type: 'all-of',
contains: [{
properties: {
boolean: {
type: 'boolean',
},
},
}, {
type: 'ModelWithEnum',
}, {
type: 'ModelWithArray',
}, {
type: 'ModelWithDictionary',
}, ]
isNullable: true,
},
},
};"
`;
exports[`v3 should generate: ./test/generated/v3/schemas/$CompositionWithAnyOf.ts 1`] = `
"/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
export const $CompositionWithAnyOf = {
properties: {
propA: {
type: 'any-of',
contains: [{
type: 'ModelWithString',
}, {
type: 'ModelWithEnum',
}, {
type: 'ModelWithArray',
}, {
type: 'ModelWithDictionary',
}, ]
},
},
};"
`;
exports[`v3 should generate: ./test/generated/v3/schemas/$CompositionWithAnyOfAndNullable.ts 1`] = `
"/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
export const $CompositionWithAnyOfAndNullable = {
properties: {
propA: {
type: 'any-of',
contains: [{
properties: {
boolean: {
type: 'boolean',
},
},
}, {
type: 'ModelWithEnum',
}, {
type: 'ModelWithArray',
}, {
type: 'ModelWithDictionary',
}, ]
isNullable: true,
},
},
};"
`;
exports[`v3 should generate: ./test/generated/v3/schemas/$CompositionWithAnyOfAnonymous.ts 1`] = `
"/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
export const $CompositionWithAnyOfAnonymous = {
properties: {
propA: {
type: 'any-of',
contains: [{
properties: {
propA: {
properties: {
},
},
},
}, {
type: 'string',
}, {
type: 'number',
}, ]
},
},
};"
`;
exports[`v3 should generate: ./test/generated/v3/schemas/$CompositionWithOneOf.ts 1`] = `
"/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
export const $CompositionWithOneOf = {
properties: {
propA: {
type: 'one-of',
contains: [{
type: 'ModelWithString',
}, {
type: 'ModelWithEnum',
}, {
type: 'ModelWithArray',
}, {
type: 'ModelWithDictionary',
}, ]
},
},
};"
`;
exports[`v3 should generate: ./test/generated/v3/schemas/$CompositionWithOneOfAndNullable.ts 1`] = `
"/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
export const $CompositionWithOneOfAndNullable = {
properties: {
propA: {
type: 'one-of',
contains: [{
properties: {
boolean: {
type: 'boolean',
},
},
}, {
type: 'ModelWithEnum',
}, {
type: 'ModelWithArray',
}, {
type: 'ModelWithDictionary',
}, ]
isNullable: true,
},
},
};"
`;
exports[`v3 should generate: ./test/generated/v3/schemas/$CompositionWithOneOfAnonymous.ts 1`] = `
"/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
export const $CompositionWithOneOfAnonymous = {
properties: {
propA: {
type: 'one-of',
contains: [{
properties: {
propA: {
properties: {
},
},
},
}, {
type: 'string',
}, {
type: 'number',
}, ]
},
},
};"
`;
exports[`v3 should generate: ./test/generated/v3/schemas/$DictionaryWithArray.ts 1`] = `
"/* istanbul ignore file */
/* tslint:disable */
@ -3671,7 +3960,6 @@ exports[`v3 should generate: ./test/generated/v3/schemas/$ModelThatExtends.ts 1`
export const $ModelThatExtends = {
type: 'all-of',
contains: [{
type: 'ModelWithString',
}, {
@ -3694,7 +3982,6 @@ exports[`v3 should generate: ./test/generated/v3/schemas/$ModelThatExtendsExtend
export const $ModelThatExtendsExtends = {
type: 'all-of',
contains: [{
type: 'ModelWithString',
}, {
@ -3712,88 +3999,6 @@ export const $ModelThatExtendsExtends = {
};"
`;
exports[`v3 should generate: ./test/generated/v3/schemas/$ModelWithAllOfAndNullable.ts 1`] = `
"/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
export const $ModelWithAllOfAndNullable = {
properties: {
propA: {
type: 'all-of',
contains: [{
properties: {
boolean: {
type: 'boolean',
},
},
}, {
type: 'ModelWithEnum',
}, {
type: 'ModelWithArray',
}, {
type: 'ModelWithDictionary',
}, ]
isNullable: true,
},
},
};"
`;
exports[`v3 should generate: ./test/generated/v3/schemas/$ModelWithAnyOf.ts 1`] = `
"/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
export const $ModelWithAnyOf = {
properties: {
propA: {
type: 'any-of',
contains: [{
type: 'ModelWithString',
}, {
type: 'ModelWithEnum',
}, {
type: 'ModelWithArray',
}, {
type: 'ModelWithDictionary',
}, ]
},
},
};"
`;
exports[`v3 should generate: ./test/generated/v3/schemas/$ModelWithAnyOfAndNullable.ts 1`] = `
"/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
export const $ModelWithAnyOfAndNullable = {
properties: {
propA: {
type: 'any-of',
contains: [{
properties: {
boolean: {
type: 'boolean',
},
},
}, {
type: 'ModelWithEnum',
}, {
type: 'ModelWithArray',
}, {
type: 'ModelWithDictionary',
}, ]
isNullable: true,
},
},
};"
`;
exports[`v3 should generate: ./test/generated/v3/schemas/$ModelWithArray.ts 1`] = `
"/* istanbul ignore file */
/* tslint:disable */
@ -4027,59 +4232,6 @@ export const $ModelWithNestedProperties = {
};"
`;
exports[`v3 should generate: ./test/generated/v3/schemas/$ModelWithOneOf.ts 1`] = `
"/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
export const $ModelWithOneOf = {
properties: {
propA: {
type: 'one-of',
contains: [{
type: 'ModelWithString',
}, {
type: 'ModelWithEnum',
}, {
type: 'ModelWithArray',
}, {
type: 'ModelWithDictionary',
}, ]
},
},
};"
`;
exports[`v3 should generate: ./test/generated/v3/schemas/$ModelWithOneOfAndNullable.ts 1`] = `
"/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
export const $ModelWithOneOfAndNullable = {
properties: {
propA: {
type: 'one-of',
contains: [{
properties: {
boolean: {
type: 'boolean',
},
},
}, {
type: 'ModelWithEnum',
}, {
type: 'ModelWithArray',
}, {
type: 'ModelWithDictionary',
}, ]
isNullable: true,
},
},
};"
`;
exports[`v3 should generate: ./test/generated/v3/schemas/$ModelWithOrderedProperties.ts 1`] = `
"/* istanbul ignore file */
/* tslint:disable */
@ -4344,7 +4496,7 @@ export class ComplexService {
readonly type: 'Monkey' | 'Horse' | 'Bird',
listOfModels?: Array<ModelWithString> | null,
listOfStrings?: Array<string> | null,
parameters: ( | ModelWithString | ModelWithEnum | ModelWithArray | ModelWithDictionary),
parameters: (ModelWithString | ModelWithEnum | ModelWithArray | ModelWithDictionary),
readonly user?: {
readonly id?: number,
readonly name?: string | null,

View File

@ -12,6 +12,17 @@ function compileWithTypescript(dir) {
module: 'es6',
moduleResolution: 'node',
lib: ['es6', 'es2017', 'dom'],
declaration: false,
declarationMap: false,
sourceMap: false,
noImplicitReturns: true,
noImplicitThis: true,
noImplicitAny: true,
strict: true,
strictNullChecks: true,
strictFunctionTypes: true,
allowSyntheticDefaultImports: true,
skipLibCheck: true
},
include: ['./index.ts'],
};

View File

@ -26,11 +26,24 @@ describe('v3.fetch', () => {
const result = await browser.evaluate(async () => {
const { OpenAPI, SimpleService } = window.api;
OpenAPI.TOKEN = window.tokenRequest;
OpenAPI.USERNAME = undefined;
OpenAPI.PASSWORD = undefined;
return await SimpleService.getCallWithoutParametersAndResponse();
});
expect(result.headers.authorization).toBe('Bearer MY_TOKEN');
});
it('uses credentials', async () => {
const result = await browser.evaluate(async () => {
const { OpenAPI, SimpleService } = window.api;
OpenAPI.TOKEN = undefined;
OpenAPI.USERNAME = 'username';
OpenAPI.PASSWORD = 'password';
return await SimpleService.getCallWithoutParametersAndResponse();
});
expect(result.headers.authorization).toBe('Basic dXNlcm5hbWU6cGFzc3dvcmQ=');
});
it('complexService', async () => {
const result = await browser.evaluate(async () => {
const { ComplexService } = window.api;

View File

@ -26,11 +26,24 @@ describe('v3.fetch', () => {
const result = await browser.evaluate(async () => {
const { OpenAPI, SimpleService } = window.api;
OpenAPI.TOKEN = window.tokenRequest;
OpenAPI.USERNAME = undefined;
OpenAPI.PASSWORD = undefined;
return await SimpleService.getCallWithoutParametersAndResponse();
});
expect(result.headers.authorization).toBe('Bearer MY_TOKEN');
});
it('uses credentials', async () => {
const result = await browser.evaluate(async () => {
const { OpenAPI, SimpleService } = window.api;
OpenAPI.TOKEN = undefined;
OpenAPI.USERNAME = 'username';
OpenAPI.PASSWORD = 'password';
return await SimpleService.getCallWithoutParametersAndResponse();
});
expect(result.headers.authorization).toBe('Basic dXNlcm5hbWU6cGFzc3dvcmQ=');
});
it('complexService', async () => {
const result = await browser.evaluate(async () => {
const { ComplexService } = window.api;

View File

@ -20,11 +20,22 @@ describe('v3.node', () => {
const { OpenAPI, SimpleService } = require('./generated/v3/node/index.js');
const tokenRequest = jest.fn().mockResolvedValue('MY_TOKEN')
OpenAPI.TOKEN = tokenRequest;
OpenAPI.USERNAME = undefined;
OpenAPI.PASSWORD = undefined;
const result = await SimpleService.getCallWithoutParametersAndResponse();
expect(tokenRequest.mock.calls.length).toBe(1);
expect(result.headers.authorization).toBe('Bearer MY_TOKEN');
});
it('uses credentials', async () => {
const { OpenAPI, SimpleService } = require('./generated/v3/node/index.js');
OpenAPI.TOKEN = undefined;
OpenAPI.USERNAME = 'username';
OpenAPI.PASSWORD = 'password';
const result = await SimpleService.getCallWithoutParametersAndResponse();
expect(result.headers.authorization).toBe('Basic dXNlcm5hbWU6cGFzc3dvcmQ=');
});
it('complexService', async () => {
const { ComplexService } = require('./generated/v3/node/index.js');
const result = await ComplexService.complexTypes({

View File

@ -26,11 +26,24 @@ describe('v3.xhr', () => {
const result = await browser.evaluate(async () => {
const { OpenAPI, SimpleService } = window.api;
OpenAPI.TOKEN = window.tokenRequest;
OpenAPI.USERNAME = undefined;
OpenAPI.PASSWORD = undefined;
return await SimpleService.getCallWithoutParametersAndResponse();
});
expect(result.headers.authorization).toBe('Bearer MY_TOKEN');
});
it('uses credentials', async () => {
const result = await browser.evaluate(async () => {
const { OpenAPI, SimpleService } = window.api;
OpenAPI.TOKEN = undefined;
OpenAPI.USERNAME = 'username';
OpenAPI.PASSWORD = 'password';
return await SimpleService.getCallWithoutParametersAndResponse();
});
expect(result.headers.authorization).toBe('Basic dXNlcm5hbWU6cGFzc3dvcmQ=');
});
it('complexService', async () => {
const result = await browser.evaluate(async () => {
const { ComplexService } = window.api;

View File

@ -705,7 +705,7 @@
},
"SimpleFile": {
"description": "This is a simple file",
"type": "File"
"type": "file"
},
"SimpleReference": {
"description": "This is a simple reference",
@ -857,6 +857,10 @@
}
}
},
"Date": {
"description": "This is a type-only model that defines Date as a string",
"type": "string"
},
"ModelWithInteger": {
"description": "This is a model with one number property",
"type": "object",
@ -1003,7 +1007,7 @@
"propWithFile": {
"type": "array",
"items": {
"type": "File"
"type": "file"
}
},
"propWithNumber": {

View File

@ -1515,7 +1515,7 @@
}
}
},
"ModelWithOneOf": {
"CompositionWithOneOf": {
"description": "This is a model with one property with a 'one of' relationship",
"type": "object",
"properties": {
@ -1538,7 +1538,33 @@
}
}
},
"ModelWithAnyOf": {
"CompositionWithOneOfAnonymous": {
"description": "This is a model with one property with a 'one of' relationship where the options are not $ref",
"type": "object",
"properties": {
"propA": {
"type": "object",
"oneOf": [
{
"description": "Anonymous object type",
"type": "object",
"properties": {
"propA": "string"
}
},
{
"description": "Anonymous string type",
"type": "string"
},
{
"description": "Anonymous integer type",
"type": "integer"
}
]
}
}
},
"CompositionWithAnyOf": {
"description": "This is a model with one property with a 'any of' relationship",
"type": "object",
"properties": {
@ -1561,7 +1587,33 @@
}
}
},
"ModelWithOneOfAndNullable": {
"CompositionWithAnyOfAnonymous": {
"description": "This is a model with one property with a 'any of' relationship where the options are not $ref",
"type": "object",
"properties": {
"propA": {
"type": "object",
"anyOf": [
{
"description": "Anonymous object type",
"type": "object",
"properties": {
"propA": "string"
}
},
{
"description": "Anonymous string type",
"type": "string"
},
{
"description": "Anonymous integer type",
"type": "integer"
}
]
}
}
},
"CompositionWithOneOfAndNullable": {
"description": "This is a model with one property with a 'one of' relationship",
"type": "object",
"properties": {
@ -1590,7 +1642,7 @@
}
}
},
"ModelWithAllOfAndNullable": {
"CompositionWithAllOfAndNullable": {
"description": "This is a model with one property with a 'all of' relationship",
"type": "object",
"properties": {
@ -1619,7 +1671,7 @@
}
}
},
"ModelWithAnyOfAndNullable": {
"CompositionWithAnyOfAndNullable": {
"description": "This is a model with one property with a 'any of' relationship",
"type": "object",
"properties": {

View File

@ -14,7 +14,9 @@
"noImplicitAny": true,
"strict": true,
"strictNullChecks": true,
"strictFunctionTypes": true
"strictFunctionTypes": true,
"allowSyntheticDefaultImports": true,
"skipLibCheck": true
},
"files": [

355
yarn.lock
View File

@ -26,10 +26,10 @@
dependencies:
"@babel/highlight" "^7.10.4"
"@babel/compat-data@^7.12.1":
version "7.12.1"
resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.12.1.tgz#d7386a689aa0ddf06255005b4b991988021101a0"
integrity sha512-725AQupWJZ8ba0jbKceeFblZTY90McUBWMwHhkFQ9q1zKPJ95GUktljFcgcsIVwRnTnRKlcYzfiNImg5G9m6ZQ==
"@babel/compat-data@^7.12.1", "@babel/compat-data@^7.12.5":
version "7.12.5"
resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.12.5.tgz#f56db0c4bb1bbbf221b4e81345aab4141e7cb0e9"
integrity sha512-DTsS7cxrsH3by8nqQSpFSyjSfSYl57D6Cf4q8dW3LK83tBKBDCkfcay1nYkXq1nIHXnpX8WMMb/O25HOy3h1zg==
"@babel/core@7.12.3", "@babel/core@^7.1.0", "@babel/core@^7.7.5":
version "7.12.3"
@ -53,12 +53,12 @@
semver "^5.4.1"
source-map "^0.5.0"
"@babel/generator@^7.12.1":
version "7.12.1"
resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.12.1.tgz#0d70be32bdaa03d7c51c8597dda76e0df1f15468"
integrity sha512-DB+6rafIdc9o72Yc3/Ph5h+6hUjeOp66pF0naQBgUFFuPqzQwIlPTm3xZR7YNvduIMtkDIj2t21LSQwnbCrXvg==
"@babel/generator@^7.12.1", "@babel/generator@^7.12.5":
version "7.12.5"
resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.12.5.tgz#a2c50de5c8b6d708ab95be5e6053936c1884a4de"
integrity sha512-m16TQQJ8hPt7E+OS/XVQg/7U184MLXtvuGbCdA7na61vha+ImkyyNM/9DDA0unYCVZn3ZOhng+qz48/KBOT96A==
dependencies:
"@babel/types" "^7.12.1"
"@babel/types" "^7.12.5"
jsesc "^2.5.1"
source-map "^0.5.0"
@ -78,13 +78,13 @@
"@babel/types" "^7.10.4"
"@babel/helper-compilation-targets@^7.12.1":
version "7.12.1"
resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.12.1.tgz#310e352888fbdbdd8577be8dfdd2afb9e7adcf50"
integrity sha512-jtBEif7jsPwP27GPHs06v4WBV0KrE8a/P7n0N0sSvHn2hwUCYnolP/CLmz51IzAW4NlN+HuoBtb9QcwnRo9F/g==
version "7.12.5"
resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.12.5.tgz#cb470c76198db6a24e9dbc8987275631e5d29831"
integrity sha512-+qH6NrscMolUlzOYngSBMIOQpKUGPPsc61Bu5W10mg84LxZ7cmvnBHzARKbDoFxVvqqAbj6Tg6N7bSrWSPXMyw==
dependencies:
"@babel/compat-data" "^7.12.1"
"@babel/compat-data" "^7.12.5"
"@babel/helper-validator-option" "^7.12.1"
browserslist "^4.12.0"
browserslist "^4.14.5"
semver "^5.5.0"
"@babel/helper-create-class-features-plugin@^7.12.1":
@ -154,11 +154,11 @@
"@babel/types" "^7.12.1"
"@babel/helper-module-imports@^7.12.1":
version "7.12.1"
resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.12.1.tgz#1644c01591a15a2f084dd6d092d9430eb1d1216c"
integrity sha512-ZeC1TlMSvikvJNy1v/wPIazCu3NdOwgYZLIkmIyAsGhqkNpiDoQQRmaCK8YP4Pq3GPTLPV9WXaPCJKvx06JxKA==
version "7.12.5"
resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.12.5.tgz#1bfc0229f794988f76ed0a4d4e90860850b54dfb"
integrity sha512-SR713Ogqg6++uexFRORf/+nPXMmWIn80TALu0uaFb+iQIUoR7bOC7zBWyzBs5b3tBBJXuyD0cRu1F15GyzjOWA==
dependencies:
"@babel/types" "^7.12.1"
"@babel/types" "^7.12.5"
"@babel/helper-module-transforms@^7.12.1":
version "7.12.1"
@ -204,14 +204,14 @@
"@babel/types" "^7.12.1"
"@babel/helper-replace-supers@^7.12.1":
version "7.12.1"
resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.12.1.tgz#f15c9cc897439281891e11d5ce12562ac0cf3fa9"
integrity sha512-zJjTvtNJnCFsCXVi5rUInstLd/EIVNmIKA1Q9ynESmMBWPWd+7sdR+G4/wdu+Mppfep0XLyG2m7EBPvjCeFyrw==
version "7.12.5"
resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.12.5.tgz#f009a17543bbbbce16b06206ae73b63d3fca68d9"
integrity sha512-5YILoed0ZyIpF4gKcpZitEnXEJ9UoDRki1Ey6xz46rxOzfNMAhVIJMoune1hmPVxh40LRv1+oafz7UsWX+vyWA==
dependencies:
"@babel/helper-member-expression-to-functions" "^7.12.1"
"@babel/helper-optimise-call-expression" "^7.10.4"
"@babel/traverse" "^7.12.1"
"@babel/types" "^7.12.1"
"@babel/traverse" "^7.12.5"
"@babel/types" "^7.12.5"
"@babel/helper-simple-access@^7.12.1":
version "7.12.1"
@ -255,13 +255,13 @@
"@babel/types" "^7.10.4"
"@babel/helpers@^7.12.1":
version "7.12.1"
resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.12.1.tgz#8a8261c1d438ec18cb890434df4ec768734c1e79"
integrity sha512-9JoDSBGoWtmbay98efmT2+mySkwjzeFeAL9BuWNoVQpkPFQF8SIIFUfY5os9u8wVzglzoiPRSW7cuJmBDUt43g==
version "7.12.5"
resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.12.5.tgz#1a1ba4a768d9b58310eda516c449913fe647116e"
integrity sha512-lgKGMQlKqA8meJqKsW6rUnc4MdUk35Ln0ATDqdM1a/UpARODdI4j5Y5lVfUScnSNkJcdCRAaWkspykNoFg9sJA==
dependencies:
"@babel/template" "^7.10.4"
"@babel/traverse" "^7.12.1"
"@babel/types" "^7.12.1"
"@babel/traverse" "^7.12.5"
"@babel/types" "^7.12.5"
"@babel/highlight@^7.10.4":
version "7.10.4"
@ -272,10 +272,10 @@
chalk "^2.0.0"
js-tokens "^4.0.0"
"@babel/parser@^7.1.0", "@babel/parser@^7.10.4", "@babel/parser@^7.12.1", "@babel/parser@^7.12.3":
version "7.12.3"
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.12.3.tgz#a305415ebe7a6c7023b40b5122a0662d928334cd"
integrity sha512-kFsOS0IbsuhO5ojF8Hc8z/8vEIOkylVBrjiZUbLTE3XFe0Qi+uu6HjzQixkFaqr0ZPAMZcBVxEwmsnsLPZ2Xsw==
"@babel/parser@^7.1.0", "@babel/parser@^7.10.4", "@babel/parser@^7.12.3", "@babel/parser@^7.12.5":
version "7.12.5"
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.12.5.tgz#b4af32ddd473c0bfa643bd7ff0728b8e71b81ea0"
integrity sha512-FVM6RZQ0mn2KCf1VUED7KepYeUWoVShczewOCfm3nzoBybaih51h+sYVVGthW9M6lPByEPTQf+xm27PBdlpwmQ==
"@babel/plugin-proposal-async-generator-functions@^7.12.1":
version "7.12.1"
@ -335,9 +335,9 @@
"@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.0"
"@babel/plugin-proposal-numeric-separator@^7.12.1":
version "7.12.1"
resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.12.1.tgz#0e2c6774c4ce48be412119b4d693ac777f7685a6"
integrity sha512-MR7Ok+Af3OhNTCxYVjJZHS0t97ydnJZt/DbR4WISO39iDnhiD8XHrY12xuSJ90FFEGjir0Fzyyn7g/zY6hxbxA==
version "7.12.5"
resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.12.5.tgz#b1ce757156d40ed79d59d467cb2b154a5c4149ba"
integrity sha512-UiAnkKuOrCyjZ3sYNHlRlfuZJbBHknMQ9VMwVeX97Ofwx7RpD6gS2HfqTCh8KNUQgcOm8IKt103oR4KIjh7Q8g==
dependencies:
"@babel/helper-plugin-utils" "^7.10.4"
"@babel/plugin-syntax-numeric-separator" "^7.10.4"
@ -840,9 +840,9 @@
"@babel/plugin-transform-typescript" "^7.12.1"
"@babel/runtime@^7.8.4":
version "7.12.1"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.12.1.tgz#b4116a6b6711d010b2dad3b7b6e43bf1b9954740"
integrity sha512-J5AIf3vPj3UwXaAzb5j1xM4WAQDX3EMgemF8rjCP3SoW09LfRKAXQKt6CoVYl230P6iWdRcBbnLDDdnqWxZSCA==
version "7.12.5"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.12.5.tgz#410e7e487441e1b360c29be715d870d9b985882e"
integrity sha512-plcc+hbExy3McchJCEQG3knOsuh3HH+Prx1P6cLIkET/0dLuQDEnrT+s27Axgc9bqfsmNUNHfscgMUdBpC9xfg==
dependencies:
regenerator-runtime "^0.13.4"
@ -855,25 +855,25 @@
"@babel/parser" "^7.10.4"
"@babel/types" "^7.10.4"
"@babel/traverse@^7.1.0", "@babel/traverse@^7.10.4", "@babel/traverse@^7.12.1":
version "7.12.1"
resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.12.1.tgz#941395e0c5cc86d5d3e75caa095d3924526f0c1e"
integrity sha512-MA3WPoRt1ZHo2ZmoGKNqi20YnPt0B1S0GTZEPhhd+hw2KGUzBlHuVunj6K4sNuK+reEvyiPwtp0cpaqLzJDmAw==
"@babel/traverse@^7.1.0", "@babel/traverse@^7.10.4", "@babel/traverse@^7.12.1", "@babel/traverse@^7.12.5":
version "7.12.5"
resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.12.5.tgz#78a0c68c8e8a35e4cacfd31db8bb303d5606f095"
integrity sha512-xa15FbQnias7z9a62LwYAA5SZZPkHIXpd42C6uW68o8uTuua96FHZy1y61Va5P/i83FAAcMpW8+A/QayntzuqA==
dependencies:
"@babel/code-frame" "^7.10.4"
"@babel/generator" "^7.12.1"
"@babel/generator" "^7.12.5"
"@babel/helper-function-name" "^7.10.4"
"@babel/helper-split-export-declaration" "^7.11.0"
"@babel/parser" "^7.12.1"
"@babel/types" "^7.12.1"
"@babel/parser" "^7.12.5"
"@babel/types" "^7.12.5"
debug "^4.1.0"
globals "^11.1.0"
lodash "^4.17.19"
"@babel/types@^7.0.0", "@babel/types@^7.10.4", "@babel/types@^7.10.5", "@babel/types@^7.11.0", "@babel/types@^7.12.1", "@babel/types@^7.3.0", "@babel/types@^7.3.3", "@babel/types@^7.4.4":
version "7.12.1"
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.12.1.tgz#e109d9ab99a8de735be287ee3d6a9947a190c4ae"
integrity sha512-BzSY3NJBKM4kyatSOWh3D/JJ2O3CVzBybHWxtgxnggaxEuaSTTDqeiSb/xk9lrkw2Tbqyivw5ZU4rT+EfznQsA==
"@babel/types@^7.0.0", "@babel/types@^7.10.4", "@babel/types@^7.10.5", "@babel/types@^7.11.0", "@babel/types@^7.12.1", "@babel/types@^7.12.5", "@babel/types@^7.3.0", "@babel/types@^7.3.3", "@babel/types@^7.4.4":
version "7.12.6"
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.12.6.tgz#ae0e55ef1cce1fbc881cd26f8234eb3e657edc96"
integrity sha512-hwyjw6GvjBLiyy3W0YQf0Z5Zf4NpYejUnKFcfcUhZCSffoBBp30w6wP2Wn6pk31jMYZvcOrB/1b7cGXvEoKogA==
dependencies:
"@babel/helper-validator-identifier" "^7.10.4"
lodash "^4.17.19"
@ -1195,9 +1195,9 @@
"@babel/types" "^7.0.0"
"@types/babel__template@*":
version "7.0.3"
resolved "https://registry.yarnpkg.com/@types/babel__template/-/babel__template-7.0.3.tgz#b8aaeba0a45caca7b56a5de9459872dde3727214"
integrity sha512-uCoznIPDmnickEi6D0v11SBpW0OuVqHJCa7syXqQHy5uktSCreIlt0iglsCnmvz8yCb38hGcWeseA8cWJSwv5Q==
version "7.4.0"
resolved "https://registry.yarnpkg.com/@types/babel__template/-/babel__template-7.4.0.tgz#0c888dd70b3ee9eebb6e4f200e809da0076262be"
integrity sha512-NTPErx4/FiPCGScH7foPyr+/1Dkzkni+rHiYHHoTjvwou7AQzJkNeD60A9CXRy+ZEN2B1bggmkTMCDb+Mv5k+A==
dependencies:
"@babel/parser" "^7.1.0"
"@babel/types" "^7.0.0"
@ -1243,10 +1243,10 @@
"@types/qs" "*"
"@types/range-parser" "*"
"@types/express@4.17.8":
version "4.17.8"
resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.8.tgz#3df4293293317e61c60137d273a2e96cd8d5f27a"
integrity sha512-wLhcKh3PMlyA2cNAB9sjM1BntnhPMiM0JOBwPBqttjHev2428MLEB4AYVN+d8s2iyCVZac+o41Pflm/ZH5vLXQ==
"@types/express@4.17.9":
version "4.17.9"
resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.9.tgz#f5f2df6add703ff28428add52bdec8a1091b0a78"
integrity sha512-SDzEIZInC4sivGIFY4Sz1GG6J9UObPwCInYJjko2jzOf/Imx/dlpume6Xxwj1ORL82tBbmN4cPDIDkLbWHk9hw==
dependencies:
"@types/body-parser" "*"
"@types/express-serve-static-core" "*"
@ -1310,10 +1310,15 @@
"@types/node" "*"
form-data "^3.0.0"
"@types/node@*", "@types/node@14.14.6":
version "14.14.6"
resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.6.tgz#146d3da57b3c636cc0d1769396ce1cfa8991147f"
integrity sha512-6QlRuqsQ/Ox/aJEQWBEJG7A9+u7oSYl3mem/K8IzxXG/kAGbV1YPD9Bg9Zw3vyxC/YP+zONKwy8hGkSt1jxFMw==
"@types/node@*":
version "14.14.8"
resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.8.tgz#2127bd81949a95c8b7d3240f3254352d72563aec"
integrity sha512-z/5Yd59dCKI5kbxauAJgw6dLPzW+TNOItNE00PkpzNwUIEwdj/Lsqwq94H5DdYBX7C13aRA0CY32BK76+neEUA==
"@types/node@14.14.7":
version "14.14.7"
resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.7.tgz#8ea1e8f8eae2430cf440564b98c6dfce1ec5945d"
integrity sha512-Zw1vhUSQZYw+7u5dAwNbIA9TuTotpzY/OF7sJM9FqPOF3SPjKnxrjoTktXDZgUjybf4cWVBP7O8wvKdSaGHweg==
"@types/normalize-package-data@^2.4.0":
version "2.4.0"
@ -1343,9 +1348,9 @@
"@types/node" "*"
"@types/serve-static@*":
version "1.13.6"
resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.13.6.tgz#866b1b8dec41c36e28c7be40ac725b88be43c5c1"
integrity sha512-nuRJmv7jW7VmCVTn+IgYDkkbbDGyIINOeu/G0d74X3lm6E5KfMeQPJhxIt1ayQeQB3cSxvYs1RA/wipYoFB4EA==
version "1.13.8"
resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.13.8.tgz#851129d434433c7082148574ffec263d58309c46"
integrity sha512-MoJhSQreaVoL+/hurAZzIm8wafFR6ajiTM1m4A0kv6AGeVBl4r4pOV8bGFrjjq1sGxDTnCoF8i22o0/aE5XCyA==
dependencies:
"@types/mime" "*"
"@types/node" "*"
@ -1361,9 +1366,9 @@
integrity sha512-FA/BWv8t8ZWJ+gEOnLLd8ygxH/2UFbAvgEonyfN6yWGLKc7zVjbpl2Y4CTjid9h2RfgPP6SEt6uHwEOply00yw==
"@types/yargs@^15.0.0":
version "15.0.9"
resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-15.0.9.tgz#524cd7998fe810cdb02f26101b699cccd156ff19"
integrity sha512-HmU8SeIRhZCWcnRskCs36Q1Q00KBV6Cqh/ora8WN1+22dY07AZdn6Gel8QZ3t26XYPImtcL8WV/eqjhVmMEw4g==
version "15.0.10"
resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-15.0.10.tgz#0fe3c8173a0d5c3e780b389050140c3f5ea6ea74"
integrity sha512-z8PNtlhrj7eJNLmrAivM7rjBESG6JwC5xP3RVk12i/8HVP7Xnx/sEmERnRImyEuUaJfO942X0qMOYsoupaJbZQ==
dependencies:
"@types/yargs-parser" "*"
@ -1374,61 +1379,61 @@
dependencies:
"@types/node" "*"
"@typescript-eslint/eslint-plugin@4.6.1":
version "4.6.1"
resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.6.1.tgz#99d77eb7a016fd5a5e749d2c44a7e4c317eb7da3"
integrity sha512-SNZyflefTMK2JyrPfFFzzoy2asLmZvZJ6+/L5cIqg4HfKGiW2Gr1Go1OyEVqne/U4QwmoasuMwppoBHWBWF2nA==
"@typescript-eslint/eslint-plugin@4.7.0":
version "4.7.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.7.0.tgz#85c9bbda00c0cb604d3c241f7bc7fb171a2d3479"
integrity sha512-li9aiSVBBd7kU5VlQlT1AqP0uWGDK6JYKUQ9cVDnOg34VNnd9t4jr0Yqc/bKxJr/tDCPDaB4KzoSFN9fgVxe/Q==
dependencies:
"@typescript-eslint/experimental-utils" "4.6.1"
"@typescript-eslint/scope-manager" "4.6.1"
"@typescript-eslint/experimental-utils" "4.7.0"
"@typescript-eslint/scope-manager" "4.7.0"
debug "^4.1.1"
functional-red-black-tree "^1.0.1"
regexpp "^3.0.0"
semver "^7.3.2"
tsutils "^3.17.1"
"@typescript-eslint/experimental-utils@4.6.1":
version "4.6.1"
resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-4.6.1.tgz#a9c691dfd530a9570274fe68907c24c07a06c4aa"
integrity sha512-qyPqCFWlHZXkEBoV56UxHSoXW2qnTr4JrWVXOh3soBP3q0o7p4pUEMfInDwIa0dB/ypdtm7gLOS0hg0a73ijfg==
"@typescript-eslint/experimental-utils@4.7.0":
version "4.7.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-4.7.0.tgz#8d1058c38bec3d3bbd9c898a1c32318d80faf3c5"
integrity sha512-cymzovXAiD4EF+YoHAB5Oh02MpnXjvyaOb+v+BdpY7lsJXZQN34oIETeUwVT2XfV9rSNpXaIcknDLfupO/tUoA==
dependencies:
"@types/json-schema" "^7.0.3"
"@typescript-eslint/scope-manager" "4.6.1"
"@typescript-eslint/types" "4.6.1"
"@typescript-eslint/typescript-estree" "4.6.1"
"@typescript-eslint/scope-manager" "4.7.0"
"@typescript-eslint/types" "4.7.0"
"@typescript-eslint/typescript-estree" "4.7.0"
eslint-scope "^5.0.0"
eslint-utils "^2.0.0"
"@typescript-eslint/parser@4.6.1":
version "4.6.1"
resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-4.6.1.tgz#b801bff67b536ecc4a840ac9289ba2be57e02428"
integrity sha512-lScKRPt1wM9UwyKkGKyQDqf0bh6jm8DQ5iN37urRIXDm16GEv+HGEmum2Fc423xlk5NUOkOpfTnKZc/tqKZkDQ==
"@typescript-eslint/parser@4.7.0":
version "4.7.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-4.7.0.tgz#44bdab0f788b478178368baa65d3365fdc63da1c"
integrity sha512-+meGV8bMP1sJHBI2AFq1GeTwofcGiur8LoIr6v+rEmD9knyCqDlrQcFHR0KDDfldHIFDU/enZ53fla6ReF4wRw==
dependencies:
"@typescript-eslint/scope-manager" "4.6.1"
"@typescript-eslint/types" "4.6.1"
"@typescript-eslint/typescript-estree" "4.6.1"
"@typescript-eslint/scope-manager" "4.7.0"
"@typescript-eslint/types" "4.7.0"
"@typescript-eslint/typescript-estree" "4.7.0"
debug "^4.1.1"
"@typescript-eslint/scope-manager@4.6.1":
version "4.6.1"
resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-4.6.1.tgz#21872b91cbf7adfc7083f17b8041149148baf992"
integrity sha512-f95+80r6VdINYscJY1KDUEDcxZ3prAWHulL4qRDfNVD0I5QAVSGqFkwHERDoLYJJWmEAkUMdQVvx7/c2Hp+Bjg==
"@typescript-eslint/scope-manager@4.7.0":
version "4.7.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-4.7.0.tgz#2115526085fb72723ccdc1eeae75dec7126220ed"
integrity sha512-ILITvqwDJYbcDCROj6+Ob0oCKNg3SH46iWcNcTIT9B5aiVssoTYkhKjxOMNzR1F7WSJkik4zmuqve5MdnA0DyA==
dependencies:
"@typescript-eslint/types" "4.6.1"
"@typescript-eslint/visitor-keys" "4.6.1"
"@typescript-eslint/types" "4.7.0"
"@typescript-eslint/visitor-keys" "4.7.0"
"@typescript-eslint/types@4.6.1":
version "4.6.1"
resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.6.1.tgz#d3ad7478f53f22e7339dc006ab61aac131231552"
integrity sha512-k2ZCHhJ96YZyPIsykickez+OMHkz06xppVLfJ+DY90i532/Cx2Z+HiRMH8YZQo7a4zVd/TwNBuRCdXlGK4yo8w==
"@typescript-eslint/types@4.7.0":
version "4.7.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.7.0.tgz#5e95ef5c740f43d942542b35811f87b62fccca69"
integrity sha512-uLszFe0wExJc+I7q0Z/+BnP7wao/kzX0hB5vJn4LIgrfrMLgnB2UXoReV19lkJQS1a1mHWGGODSxnBx6JQC3Sg==
"@typescript-eslint/typescript-estree@4.6.1":
version "4.6.1"
resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.6.1.tgz#6025cce724329413f57e4959b2d676fceeca246f"
integrity sha512-/J/kxiyjQQKqEr5kuKLNQ1Finpfb8gf/NpbwqFFYEBjxOsZ621r9AqwS9UDRA1Rrr/eneX/YsbPAIhU2rFLjXQ==
"@typescript-eslint/typescript-estree@4.7.0":
version "4.7.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.7.0.tgz#539531167f05ba20eb0b6785567076679e29d393"
integrity sha512-5XZRQznD1MfUmxu1t8/j2Af4OxbA7EFU2rbo0No7meb46eHgGkSieFdfV6omiC/DGIBhH9H9gXn7okBbVOm8jw==
dependencies:
"@typescript-eslint/types" "4.6.1"
"@typescript-eslint/visitor-keys" "4.6.1"
"@typescript-eslint/types" "4.7.0"
"@typescript-eslint/visitor-keys" "4.7.0"
debug "^4.1.1"
globby "^11.0.1"
is-glob "^4.0.1"
@ -1436,12 +1441,12 @@
semver "^7.3.2"
tsutils "^3.17.1"
"@typescript-eslint/visitor-keys@4.6.1":
version "4.6.1"
resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.6.1.tgz#6b125883402d8939df7b54528d879e88f7ba3614"
integrity sha512-owABze4toX7QXwOLT3/D5a8NecZEjEWU1srqxENTfqsY3bwVnl3YYbOh6s1rp2wQKO9RTHFGjKes08FgE7SVMw==
"@typescript-eslint/visitor-keys@4.7.0":
version "4.7.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.7.0.tgz#6783824f22acfc49e754970ed21b88ac03b80e6f"
integrity sha512-aDJDWuCRsf1lXOtignlfiPODkzSxxop7D0rZ91L6ZuMlcMCSh0YyK+gAfo5zN/ih6WxMwhoXgJWC3cWQdaKC+A==
dependencies:
"@typescript-eslint/types" "4.6.1"
"@typescript-eslint/types" "4.7.0"
eslint-visitor-keys "^2.0.0"
abab@^2.0.3:
@ -1717,9 +1722,9 @@ balanced-match@^1.0.0:
integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c=
base64-js@^1.3.1:
version "1.3.1"
resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.3.1.tgz#58ece8cb75dd07e71ed08c736abc5fac4dbf8df1"
integrity sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==
version "1.5.1"
resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a"
integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==
base@^0.11.1:
version "0.11.2"
@ -1819,15 +1824,16 @@ browser-process-hrtime@^1.0.0:
resolved "https://registry.yarnpkg.com/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz#3c9b4b7d782c8121e56f10106d84c0d0ffc94626"
integrity sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==
browserslist@^4.12.0, browserslist@^4.8.5:
version "4.14.6"
resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.14.6.tgz#97702a9c212e0c6b6afefad913d3a1538e348457"
integrity sha512-zeFYcUo85ENhc/zxHbiIp0LGzzTrE2Pv2JhxvS7kpUb9Q9D38kUX6Bie7pGutJ/5iF5rOxE7CepAuWD56xJ33A==
browserslist@^4.14.5, browserslist@^4.14.6:
version "4.14.7"
resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.14.7.tgz#c071c1b3622c1c2e790799a37bb09473a4351cb6"
integrity sha512-BSVRLCeG3Xt/j/1cCGj1019Wbty0H+Yvu2AOuZSuoaUWn3RatbL33Cxk+Q4jRMRAbOm0p7SLravLjpnT6s0vzQ==
dependencies:
caniuse-lite "^1.0.30001154"
electron-to-chromium "^1.3.585"
caniuse-lite "^1.0.30001157"
colorette "^1.2.1"
electron-to-chromium "^1.3.591"
escalade "^3.1.1"
node-releases "^1.1.65"
node-releases "^1.1.66"
bser@2.1.1:
version "2.1.1"
@ -1847,9 +1853,9 @@ buffer-from@^1.0.0:
integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==
buffer@^5.2.1, buffer@^5.5.0:
version "5.7.0"
resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.0.tgz#88afbd29fc89fa7b58e82b39206f31f2cf34feed"
integrity sha512-cd+5r1VLBwUqTrmnzW+D7ABkJUM6mr7uv1dv+6jRw4Rcl7tFIFHDqHPL98LhpGFn3dbAt3gtLxtrWp4m1kFrqg==
version "5.7.1"
resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0"
integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==
dependencies:
base64-js "^1.3.1"
ieee754 "^1.1.13"
@ -1902,10 +1908,10 @@ 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.30001154:
version "1.0.30001154"
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001154.tgz#f3bbc245ce55e4c1cd20fa731b097880181a7f17"
integrity sha512-y9DvdSti8NnYB9Be92ddMZQrcOe04kcQtcxtBx4NkB04+qZ+JUWotnXBJTmxlKudhxNTQ3RRknMwNU2YQl/Org==
caniuse-lite@^1.0.30001157:
version "1.0.30001159"
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001159.tgz#bebde28f893fa9594dadcaa7d6b8e2aa0299df20"
integrity sha512-w9Ph56jOsS8RL20K9cLND3u/+5WASWdhC/PPrf+V3/HsM3uHOavWOR1Xzakbv4Puo/srmPHudkmCRWM7Aq+/UA==
capture-exit@^2.0.0:
version "2.0.0"
@ -2062,6 +2068,11 @@ color-name@~1.1.4:
resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2"
integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==
colorette@^1.2.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.2.1.tgz#4d0b921325c14faf92633086a536db6e89564b1b"
integrity sha512-puCDz0CzydiSYOrnXpz/PKd69zRrribezjtE9yd4zvytoRc8+RY/KJPvtPFKZS3E3wP6neGyMe0vOTlHO5L3Pw==
combined-stream@^1.0.6, combined-stream@^1.0.8, combined-stream@~1.0.6:
version "1.0.8"
resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f"
@ -2134,11 +2145,11 @@ copy-descriptor@^0.1.0:
integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=
core-js-compat@^3.6.2:
version "3.6.5"
resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.6.5.tgz#2a51d9a4e25dfd6e690251aa81f99e3c05481f1c"
integrity sha512-7ItTKOhOZbznhXAQ2g/slGg1PJV5zDO/WdkTwi7UEOJmkvsE32PWvx6mKtDjiMpjnR2CNf6BAD6sSxIlv7ptng==
version "3.7.0"
resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.7.0.tgz#8479c5d3d672d83f1f5ab94cf353e57113e065ed"
integrity sha512-V8yBI3+ZLDVomoWICO6kq/CD28Y4r1M7CWeO4AGpMdMfseu8bkSubBmUPySMGKRTS+su4XQ07zUkAsiu9FCWTg==
dependencies:
browserslist "^4.8.5"
browserslist "^4.14.6"
semver "7.0.0"
core-util-is@1.0.2, core-util-is@~1.0.0:
@ -2331,10 +2342,10 @@ ee-first@1.1.1:
resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d"
integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=
electron-to-chromium@^1.3.585:
version "1.3.586"
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.586.tgz#1484f59b2f820f5f3278f0c6ead71d05b19a1311"
integrity sha512-or8FCbQCRlPZHkOoqBULOI9hzTiStVIQqDLgAPt8pzY+swTrW+89vsqd24Zn+Iv4guAJLxRBD6OR5AmbpabGDA==
electron-to-chromium@^1.3.591:
version "1.3.599"
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.599.tgz#3fbb004733f3c0dcf59934c8644ddf800b94443a"
integrity sha512-u6VGpFsIzSCNrWJb1I72SUypz3EGoBaiEgygoMkd0IOcGR3WF3je5VTx9OIRI9Qd8UOMHinLImyJFkYHTq6nsg==
emittery@^0.7.1:
version "0.7.2"
@ -2423,10 +2434,10 @@ eslint-plugin-prettier@3.1.4:
dependencies:
prettier-linter-helpers "^1.0.0"
eslint-plugin-simple-import-sort@5.0.3:
version "5.0.3"
resolved "https://registry.yarnpkg.com/eslint-plugin-simple-import-sort/-/eslint-plugin-simple-import-sort-5.0.3.tgz#9ae258ddada6efffc55e47a134afbd279eb31fc6"
integrity sha512-1rf3AWiHeWNCQdAq0iXNnlccnH1UDnelGgrPbjBBHE8d2hXVtOudcmy0vTF4hri3iJ0MKz8jBhmH6lJ0ZWZLHQ==
eslint-plugin-simple-import-sort@6.0.0:
version "6.0.0"
resolved "https://registry.yarnpkg.com/eslint-plugin-simple-import-sort/-/eslint-plugin-simple-import-sort-6.0.0.tgz#036346edede70afab8928cc4c4b5ae3bd8db7f01"
integrity sha512-YEx+2Zli3mw4mzLzotZSeor4GqdjFWv6S7LcQeKsoXWD4GzMtP42WCz40kAlB35ehxf7PR5V/4f8g8l9aqWGsg==
eslint-scope@^5.0.0, eslint-scope@^5.1.1:
version "5.1.1"
@ -2912,9 +2923,9 @@ fsevents@^1.2.7:
nan "^2.12.1"
fsevents@^2.1.2:
version "2.2.0"
resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.2.0.tgz#4150396a427ecb5baa747725b70270a72b17bc17"
integrity sha512-pKnaUh2TNvk+/egJdBw1h46LwyLx8BzEq+MGCf/RMCVfEHHsGOCWG00dqk91kUPPArIIwMBg9T/virxwzP03cA==
version "2.2.1"
resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.2.1.tgz#1fb02ded2036a8ac288d507a65962bd87b97628d"
integrity sha512-bTLYHSeC0UH/EFXS9KqWnXuOl/wHK5Z/d+ghd5AsFMYN7wIGkUCOJyzy88+wJKkZPGON8u4Z9f6U4FdgURE9qA==
fsevents@~2.1.2:
version "2.1.3"
@ -3318,10 +3329,10 @@ is-ci@^2.0.0:
dependencies:
ci-info "^2.0.0"
is-core-module@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.0.0.tgz#58531b70aed1db7c0e8d4eb1a0a2d1ddd64bd12d"
integrity sha512-jq1AH6C8MuteOoBPwkxHafmByhL9j5q4OaPGdbuD+ZtQJVzH+i6E3BJDQcBA09k57i2Hh2yQbEG8yObZ0jdlWw==
is-core-module@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.1.0.tgz#a4cc031d9b1aca63eecbd18a650e13cb4eeab946"
integrity sha512-YcV7BgVMRFRua2FqQzKtTDMz8iCuLEyGKjr70q8Zm1yy2qKcurbFEd79PAdHV77oL3NrAaOVQIbMmiHQCHB7ZA==
dependencies:
has "^1.0.3"
@ -4329,10 +4340,10 @@ node-notifier@^8.0.0:
uuid "^8.3.0"
which "^2.0.2"
node-releases@^1.1.65:
version "1.1.65"
resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.65.tgz#52d9579176bd60f23eba05c4438583f341944b81"
integrity sha512-YpzJOe2WFIW0V4ZkJQd/DGR/zdVwc/pI4Nl1CZrBO19FdRcSTmsuhdttw9rsTzzJLrNcSloLiBbEYx1C4f6gpA==
node-releases@^1.1.66:
version "1.1.67"
resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.67.tgz#28ebfcccd0baa6aad8e8d4d8fe4cbc49ae239c12"
integrity sha512-V5QF9noGFl3EymEwUYzO+3NTDpGfQB4ve6Qfnzf3UNydMhjQRVPR1DZTuvWiLzaFJYw2fmDwAfnRNEVb64hSIg==
normalize-package-data@^2.5.0:
version "2.5.0"
@ -4967,11 +4978,11 @@ resolve@1.17.0:
path-parse "^1.0.6"
resolve@^1.10.0, resolve@^1.17.0, resolve@^1.18.1, resolve@^1.3.2:
version "1.18.1"
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.18.1.tgz#018fcb2c5b207d2a6424aee361c5a266da8f4130"
integrity sha512-lDfCPaMKfOJXjy0dPayzPdF1phampNWr3qFCjAu+rw/qbQmr5jWH5xN2hwh9QKfw9E5v4hwV7A+jrCmL8yjjqA==
version "1.19.0"
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.19.0.tgz#1af5bf630409734a067cae29318aac7fa29a267c"
integrity sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg==
dependencies:
is-core-module "^2.0.0"
is-core-module "^2.1.0"
path-parse "^1.0.6"
ret@~0.1.10:
@ -5019,10 +5030,10 @@ rollup-plugin-typescript2@0.29.0:
resolve "1.17.0"
tslib "2.0.1"
rollup@2.33.1:
version "2.33.1"
resolved "https://registry.yarnpkg.com/rollup/-/rollup-2.33.1.tgz#802795164164ee63cd47769d8879c33ec8ae0c40"
integrity sha512-uY4O/IoL9oNW8MMcbA5hcOaz6tZTMIh7qJHx/tzIJm+n1wLoY38BLn6fuy7DhR57oNFLMbDQtDeJoFURt5933w==
rollup@2.33.2:
version "2.33.2"
resolved "https://registry.yarnpkg.com/rollup/-/rollup-2.33.2.tgz#c4c76cd405a7605e6ebe90976398c46d4c2ea166"
integrity sha512-QPQ6/fWCrzHtSXkI269rhKaC7qXGghYBwXU04b1JsDZ6ibZa3DJ9D1SFAYRMgx1inDg0DaTbb3N4Z1NK/r3fhw==
optionalDependencies:
fsevents "~2.1.2"
@ -5342,9 +5353,9 @@ sshpk@^1.7.0:
tweetnacl "~0.14.0"
stack-utils@^2.0.2:
version "2.0.2"
resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-2.0.2.tgz#5cf48b4557becb4638d0bc4f21d23f5d19586593"
integrity sha512-0H7QK2ECz3fyZMzQ8rH0j2ykpfbnd20BFtfg/SqVC2+sCTtcw0aDTGB7dk+de4U4uUeuz6nOtJcrkFFLG1B0Rg==
version "2.0.3"
resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-2.0.3.tgz#cd5f030126ff116b78ccb3c027fe302713b61277"
integrity sha512-gL//fkxfWUsIlFL2Tl42Cl6+HFALEaB1FU76I/Fy+oZjRreP7OPMXFlGbxM7NQsI0ZpUfw76sHnv0WNYuTb7Iw==
dependencies:
escape-string-regexp "^2.0.0"
@ -5490,16 +5501,16 @@ table@^5.2.3:
string-width "^3.0.0"
tar-fs@^2.0.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-2.1.0.tgz#d1cdd121ab465ee0eb9ccde2d35049d3f3daf0d5"
integrity sha512-9uW5iDvrIMCVpvasdFHW0wJPez0K4JnMZtsuIeDI7HyMGJNxmDZDOCQROr7lXyS+iL/QMpj07qcjGYTSdRFXUg==
version "2.1.1"
resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-2.1.1.tgz#489a15ab85f1f0befabb370b7de4f9eb5cbe8784"
integrity sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==
dependencies:
chownr "^1.1.1"
mkdirp-classic "^0.5.2"
pump "^3.0.0"
tar-stream "^2.0.0"
tar-stream "^2.1.4"
tar-stream@^2.0.0:
tar-stream@^2.1.4:
version "2.1.4"
resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-2.1.4.tgz#c4fb1a11eb0da29b893a5b25476397ba2d053bfa"
integrity sha512-o3pS2zlG4gxr67GmFYBLlq+dM8gyRGUOvsrHclSkvtVtQbjV0s/+ZE8OpICbaj8clrX3tjeHngYGP7rweaBnuw==
@ -5530,9 +5541,9 @@ terminal-link@^2.0.0:
supports-hyperlinks "^2.0.0"
terser@^5.0.0:
version "5.3.8"
resolved "https://registry.yarnpkg.com/terser/-/terser-5.3.8.tgz#991ae8ba21a3d990579b54aa9af11586197a75dd"
integrity sha512-zVotuHoIfnYjtlurOouTazciEfL7V38QMAOhGqpXDEg6yT13cF4+fEP9b0rrCEQTn+tT46uxgFsTZzhygk+CzQ==
version "5.4.0"
resolved "https://registry.yarnpkg.com/terser/-/terser-5.4.0.tgz#9815c0839072d5c894e22c6fc508fbe9f5e7d7e8"
integrity sha512-3dZunFLbCJis9TAF2VnX+VrQLctRUmt1p3W2kCsJuZE4ZgWqh//+1MZ62EanewrqKoUf4zIaDGZAvml4UDc0OQ==
dependencies:
commander "^2.20.0"
source-map "~0.7.2"
@ -5717,9 +5728,9 @@ typescript@4.0.5:
integrity sha512-ywmr/VrTVCmNTJ6iV2LwIrfG1P+lv6luD8sUJs+2eI9NLGigaN+nUQc13iHqisq7bra9lnmUSYqbJvegraBOPQ==
uglify-js@^3.1.4:
version "3.11.5"
resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.11.5.tgz#d6788bc83cf35ff18ea78a65763e480803409bc6"
integrity sha512-btvv/baMqe7HxP7zJSF7Uc16h1mSfuuSplT0/qdjxseesDU+yYzH33eHBH+eMdeRXwujXspaCTooWHQVVBh09w==
version "3.11.6"
resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.11.6.tgz#144b50d3e05eadd3ad4dd047c60ca541a8cd4e9c"
integrity sha512-oASI1FOJ7BBFkSCNDZ446EgkSuHkOZBuqRFrwXIKWCoXw8ZXQETooTQjkAcBS03Acab7ubCKsXnwuV2svy061g==
unbzip2-stream@^1.3.3:
version "1.4.3"
@ -5983,9 +5994,9 @@ write@1.0.3:
mkdirp "^0.5.1"
ws@^7.2.3:
version "7.3.1"
resolved "https://registry.yarnpkg.com/ws/-/ws-7.3.1.tgz#d0547bf67f7ce4f12a72dfe31262c68d7dc551c8"
integrity sha512-D3RuNkynyHmEJIpD2qrgVkc9DQ23OrN/moAwZX4L8DfvszsJxpjQuUq3LMx6HoYji9fbIOBY18XWBsAux1ZZUA==
version "7.4.0"
resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.0.tgz#a5dd76a24197940d4a8bb9e0e152bb4503764da7"
integrity sha512-kyFwXuV/5ymf+IXhS6f0+eAFvydbaBW3zjpT6hUdAh/hbVjTIB5EHBGi0bPoCLSK2wcuz3BrEkB9LrYv1Nm4NQ==
xml-name-validator@^3.0.0:
version "3.0.0"