mirror of
https://github.com/ferdikoomen/openapi-typescript-codegen.git
synced 2025-12-08 20:16:21 +00:00
- Working on large cleanup
This commit is contained in:
parent
35d7ac10c8
commit
6e82ff13a8
7
src/client/interfaces/ArrayType.d.ts
vendored
7
src/client/interfaces/ArrayType.d.ts
vendored
@ -1,7 +0,0 @@
|
||||
export interface ArrayType {
|
||||
type: string;
|
||||
base: string;
|
||||
template: string | null;
|
||||
default?: any;
|
||||
imports: string[];
|
||||
}
|
||||
4
src/client/interfaces/Client.d.ts
vendored
4
src/client/interfaces/Client.d.ts
vendored
@ -4,6 +4,6 @@ import { Service } from './Service';
|
||||
export interface Client {
|
||||
version: string;
|
||||
server: string;
|
||||
models: Map<string, Model>;
|
||||
services: Map<string, Service>;
|
||||
models: Model[];
|
||||
services: Service[];
|
||||
}
|
||||
|
||||
7
src/client/interfaces/Enum.d.ts
vendored
Normal file
7
src/client/interfaces/Enum.d.ts
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
import { EnumValue } from './EnumValue';
|
||||
|
||||
export interface Enum {
|
||||
name: string;
|
||||
type: string;
|
||||
values: EnumValue[];
|
||||
}
|
||||
@ -1,4 +1,4 @@
|
||||
export interface Shape {
|
||||
export interface EnumValue {
|
||||
name: string;
|
||||
value: string;
|
||||
}
|
||||
19
src/client/interfaces/Model.d.ts
vendored
19
src/client/interfaces/Model.d.ts
vendored
@ -1,5 +1,18 @@
|
||||
import { Schema } from './Schema';
|
||||
import { ModelProperty } from './ModelProperty';
|
||||
import { Enum } from './Enum';
|
||||
|
||||
export interface Model extends Schema {
|
||||
noop?: any;
|
||||
export interface Model {
|
||||
isInterface: boolean;
|
||||
isType: boolean;
|
||||
isEnum: boolean;
|
||||
name: string;
|
||||
type: string;
|
||||
base: string;
|
||||
template: string | null;
|
||||
validation: string | null;
|
||||
description: string | null;
|
||||
extends: string | null;
|
||||
imports: string[];
|
||||
enums: Enum[];
|
||||
properties: ModelProperty[];
|
||||
}
|
||||
|
||||
7
src/client/interfaces/ModelEnum.d.ts
vendored
7
src/client/interfaces/ModelEnum.d.ts
vendored
@ -1,7 +0,0 @@
|
||||
import { ModelEnumValue } from './ModelEnumValue';
|
||||
|
||||
export interface ModelEnum {
|
||||
name: string;
|
||||
value: string;
|
||||
values: ModelEnumValue[];
|
||||
}
|
||||
6
src/client/interfaces/ModelEnumValue.d.ts
vendored
6
src/client/interfaces/ModelEnumValue.d.ts
vendored
@ -1,6 +0,0 @@
|
||||
export interface ModelEnumValue {
|
||||
type: string;
|
||||
name: string;
|
||||
description?: string;
|
||||
value: string | number;
|
||||
}
|
||||
9
src/client/interfaces/ModelProperty.d.ts
vendored
9
src/client/interfaces/ModelProperty.d.ts
vendored
@ -1,14 +1,9 @@
|
||||
export interface ModelProperty {
|
||||
name: string;
|
||||
type: string;
|
||||
base: string;
|
||||
template: string | null;
|
||||
description?: string;
|
||||
default?: any;
|
||||
required: boolean;
|
||||
nullable: boolean;
|
||||
readOnly: boolean;
|
||||
extends: string[];
|
||||
imports: string[];
|
||||
properties: ModelProperty[];
|
||||
validation: string | null;
|
||||
description: string | null;
|
||||
}
|
||||
|
||||
11
src/client/interfaces/Operation.d.ts
vendored
11
src/client/interfaces/Operation.d.ts
vendored
@ -1,7 +1,7 @@
|
||||
import { OperationError } from './OperationError';
|
||||
import { Parameter } from './Parameter';
|
||||
import { OperationParameters } from './OperationParameters';
|
||||
|
||||
export interface Operation {
|
||||
export interface Operation extends OperationParameters {
|
||||
service: string;
|
||||
name: string;
|
||||
summary?: string;
|
||||
@ -9,13 +9,6 @@ export interface Operation {
|
||||
deprecated?: boolean;
|
||||
method: string;
|
||||
path: string;
|
||||
parameters: Parameter[];
|
||||
parametersPath: Parameter[];
|
||||
parametersQuery: Parameter[];
|
||||
parametersForm: Parameter[];
|
||||
parametersHeader: Parameter[];
|
||||
parametersBody: Parameter | null;
|
||||
errors: OperationError[];
|
||||
result: string;
|
||||
imports: string[];
|
||||
}
|
||||
|
||||
@ -1,12 +1,12 @@
|
||||
export interface Parameter {
|
||||
export interface OperationParameter {
|
||||
prop: string;
|
||||
in: 'path' | 'query' | 'header' | 'formData' | 'body';
|
||||
name: string;
|
||||
type: string;
|
||||
base: string;
|
||||
template: string | null;
|
||||
description?: string;
|
||||
default?: any;
|
||||
description: string | null;
|
||||
default: any | undefined;
|
||||
required: boolean;
|
||||
nullable: boolean;
|
||||
imports: string[];
|
||||
14
src/client/interfaces/OperationParameters.d.ts
vendored
14
src/client/interfaces/OperationParameters.d.ts
vendored
@ -1,11 +1,11 @@
|
||||
import { Parameter } from './Parameter';
|
||||
import { OperationParameter } from './OperationParameter';
|
||||
|
||||
export interface OperationParameters {
|
||||
imports: string[];
|
||||
parameters: Parameter[];
|
||||
parametersPath: Parameter[];
|
||||
parametersQuery: Parameter[];
|
||||
parametersForm: Parameter[];
|
||||
parametersHeader: Parameter[];
|
||||
parametersBody: Parameter | null;
|
||||
parameters: OperationParameter[];
|
||||
parametersPath: OperationParameter[];
|
||||
parametersQuery: OperationParameter[];
|
||||
parametersForm: OperationParameter[];
|
||||
parametersHeader: OperationParameter[];
|
||||
parametersBody: OperationParameter | null;
|
||||
}
|
||||
|
||||
17
src/client/interfaces/Schema.d.ts
vendored
17
src/client/interfaces/Schema.d.ts
vendored
@ -1,17 +0,0 @@
|
||||
import { Shape } from './Symbol';
|
||||
import { SchemaProperty } from './SchemaProperty';
|
||||
|
||||
export interface Schema {
|
||||
isInterface: boolean; // Schema is interface
|
||||
isType: boolean; // Schema is type
|
||||
isEnum: boolean; // Schema is enum
|
||||
name: string;
|
||||
type: string;
|
||||
base: string;
|
||||
template: string | null;
|
||||
description?: string;
|
||||
extends: string[];
|
||||
imports: string[];
|
||||
symbols: Shape[]; // TODO: Betere naam!
|
||||
properties: SchemaProperty[];
|
||||
}
|
||||
8
src/client/interfaces/SchemaProperty.d.ts
vendored
8
src/client/interfaces/SchemaProperty.d.ts
vendored
@ -1,8 +0,0 @@
|
||||
export interface SchemaProperty {
|
||||
name: string;
|
||||
type: string;
|
||||
required: boolean;
|
||||
nullable: boolean;
|
||||
readOnly: boolean;
|
||||
description?: string;
|
||||
}
|
||||
6
src/client/interfaces/SchemaReference.d.ts
vendored
6
src/client/interfaces/SchemaReference.d.ts
vendored
@ -1,6 +0,0 @@
|
||||
export interface SchemaReference {
|
||||
type: string;
|
||||
base: string;
|
||||
template: string | null;
|
||||
imports: string[];
|
||||
}
|
||||
@ -1,6 +1,7 @@
|
||||
export enum PrimaryType {
|
||||
FILE = 'File',
|
||||
OBJECT = 'any',
|
||||
ARRAY = 'any[]',
|
||||
BOOLEAN = 'boolean',
|
||||
NUMBER = 'number',
|
||||
STRING = 'string',
|
||||
@ -13,6 +14,8 @@ export const TYPE_MAPPINGS = new Map<string, PrimaryType>([
|
||||
['binary', PrimaryType.FILE],
|
||||
['any', PrimaryType.OBJECT],
|
||||
['object', PrimaryType.OBJECT],
|
||||
['list', PrimaryType.ARRAY],
|
||||
['array', PrimaryType.ARRAY],
|
||||
['boolean', PrimaryType.BOOLEAN],
|
||||
['byte', PrimaryType.NUMBER],
|
||||
['int', PrimaryType.NUMBER],
|
||||
|
||||
@ -2,7 +2,14 @@ import { getType } from './getType';
|
||||
import { PrimaryType } from './constants';
|
||||
import { Type } from '../../../client/interfaces/Type';
|
||||
import { OpenApiItems } from '../interfaces/OpenApiItems';
|
||||
import { ArrayType } from '../../../client/interfaces/ArrayType';
|
||||
|
||||
export interface ArrayType {
|
||||
type: string;
|
||||
base: string;
|
||||
template: string | null;
|
||||
default: any | undefined;
|
||||
imports: string[];
|
||||
}
|
||||
|
||||
export function getArrayType(items: OpenApiItems): ArrayType {
|
||||
const result: ArrayType = {
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { EOL } from 'os';
|
||||
|
||||
export function getComment(comment: string | undefined): string | undefined {
|
||||
export function getComment(comment: string | undefined): string | null {
|
||||
if (comment) {
|
||||
return comment
|
||||
.split(/(\r\n|\n|\r)+/g)
|
||||
@ -9,5 +9,5 @@ export function getComment(comment: string | undefined): string | undefined {
|
||||
.join(EOL)
|
||||
.replace(/(\r\n|\n|\r)+/g, '$1 * ');
|
||||
}
|
||||
return undefined;
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -1,13 +1,13 @@
|
||||
import { Shape } from '../../../client/interfaces/Shape';
|
||||
import { ModelEnumValue } from '../../../client/interfaces/ModelEnumValue';
|
||||
|
||||
export function getEnumSymbols(values?: (string | number)[]): Shape[] {
|
||||
export function getModelEnum(values?: (string | number)[]): ModelEnumValue[] {
|
||||
if (Array.isArray(values)) {
|
||||
return values
|
||||
.filter((value: string | number, index: number, arr: (string | number)[]) => {
|
||||
return arr.indexOf(value) === index;
|
||||
})
|
||||
.map(
|
||||
(value: string | number): Shape => {
|
||||
(value: string | number): ModelEnumValue => {
|
||||
if (typeof value === 'number') {
|
||||
return {
|
||||
name: `NUM_${value}`,
|
||||
@ -1,13 +1,13 @@
|
||||
import { Shape } from '../../../client/interfaces/Shape';
|
||||
import { ModelEnumValue } from '../../../client/interfaces/ModelEnumValue';
|
||||
|
||||
export function getEnumSymbolsFromDescription(description: string): Shape[] {
|
||||
export function getModelEnumFromDescription(description: string): ModelEnumValue[] {
|
||||
// Check if we can find this special format string:
|
||||
// None=0,Something=1,AnotherThing=2
|
||||
if (/^(\w+=[0-9]+,?)+$/g.test(description)) {
|
||||
const matches: RegExpMatchArray | null = description.match(/(\w+=[0-9]+,?)/g);
|
||||
if (matches) {
|
||||
// Grab the values from the description
|
||||
const symbols: Shape[] = [];
|
||||
const symbols: ModelEnumValue[] = [];
|
||||
matches.forEach((match: string): void => {
|
||||
const name: string = match.split('=')[0];
|
||||
const value: number = parseInt(match.split('=')[1].replace(/[^0-9]/g, ''));
|
||||
@ -20,7 +20,7 @@ export function getEnumSymbolsFromDescription(description: string): Shape[] {
|
||||
});
|
||||
|
||||
// Filter out any duplicate names
|
||||
return symbols.filter((symbol: Shape, index: number, arr: Shape[]): boolean => {
|
||||
return symbols.filter((symbol: ModelEnumValue, index: number, arr: ModelEnumValue[]): boolean => {
|
||||
return arr.map(item => item.name).indexOf(symbol.name) === index;
|
||||
});
|
||||
}
|
||||
@ -1,15 +1,8 @@
|
||||
import { Shape } from '../../../client/interfaces/Shape';
|
||||
|
||||
export function getEnumType(symbols: Shape[], addParentheses = false): string {
|
||||
export function getEnumType(symbols: ModelSymbol[], addParentheses = false): string {
|
||||
// Fetch values from the symbols, just to be sure we filter out
|
||||
// any double values and finally we sort them to make them easier
|
||||
// to read when we use them in our generated code.
|
||||
const entries: string[] = symbols
|
||||
.map(symbol => symbol.value)
|
||||
.filter((value: string, index: number, arr: string[]): boolean => {
|
||||
return arr.indexOf(value) === index;
|
||||
})
|
||||
.sort();
|
||||
const entries: string[] = getEnumValues(symbols);
|
||||
|
||||
// Add grouping parentheses if needed. This can be handy if enum values
|
||||
// are used in Arrays, so that you will get the following definition:
|
||||
|
||||
11
src/openApi/v2/parser/getEnumValues.ts
Normal file
11
src/openApi/v2/parser/getEnumValues.ts
Normal file
@ -0,0 +1,11 @@
|
||||
export function getEnumValues(symbols: ModelSymbol[]): string[] {
|
||||
// Fetch values from the symbols, just to be sure we filter out
|
||||
// any double values and finally we sort them to make them easier
|
||||
// to read when we use them in our generated code.
|
||||
return symbols
|
||||
.map(symbol => symbol.value)
|
||||
.filter((value: string, index: number, arr: string[]): boolean => {
|
||||
return arr.indexOf(value) === index;
|
||||
})
|
||||
.sort();
|
||||
}
|
||||
@ -1,54 +1,54 @@
|
||||
import { OpenApi } from '../interfaces/OpenApi';
|
||||
import { Schema } from '../../../client/interfaces/Schema';
|
||||
import { OpenApiSchema } from '../interfaces/OpenApiSchema';
|
||||
import { getComment } from './getComment';
|
||||
import { getType } from './getType';
|
||||
import { Type } from '../../../client/interfaces/Type';
|
||||
import { getEnumSymbolsFromDescription } from './getEnumSymbolsFromDescription';
|
||||
import { getEnumType } from './getEnumType';
|
||||
import { getEnumSymbols } from './getEnumSymbols';
|
||||
import { PrimaryType } from './constants';
|
||||
import { Shape } from '../../../client/interfaces/Shape';
|
||||
import { OpenApiReference } from '../interfaces/OpenApiReference';
|
||||
import { getRef } from './getRef';
|
||||
import { getSchemaType } from './getSchemaType';
|
||||
import { getEnumValues } from './getEnumValues';
|
||||
import { Model } from '../../../client/interfaces/Model';
|
||||
|
||||
export function getSchema(openApi: OpenApi, schema: OpenApiSchema, name: string): Schema {
|
||||
const result: Schema = {
|
||||
name, // TODO: kan weg zie maar waar deze gebruikt is, of kan model naam worden
|
||||
export function getModel(openApi: OpenApi, schema: OpenApiSchema, name: string): Model {
|
||||
const result: Model = {
|
||||
name,
|
||||
isInterface: false,
|
||||
isType: false,
|
||||
isEnum: false,
|
||||
type: 'any',
|
||||
base: 'any',
|
||||
template: null,
|
||||
validation: null,
|
||||
description: getComment(schema.description),
|
||||
extends: [],
|
||||
extends: null,
|
||||
imports: [],
|
||||
symbols: [],
|
||||
enums: [],
|
||||
properties: [],
|
||||
};
|
||||
|
||||
// If the param is a enum then return the values as an inline type.
|
||||
if (schema.enum) {
|
||||
const enumSymbols: Shape[] = getEnumSymbols(schema.enum);
|
||||
const enumSymbols: ModelSymbol[] = getEnumSymbols(schema.enum);
|
||||
if (enumSymbols.length) {
|
||||
result.isEnum = true;
|
||||
result.symbols = enumSymbols;
|
||||
result.type = getEnumType(result.symbols);
|
||||
result.type = getEnumType(enumSymbols);
|
||||
result.base = PrimaryType.STRING;
|
||||
result.validation = `yup.mixed<${name}>().oneOf([${getEnumValues(enumSymbols).join(', ')}])`;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
// If the param is a enum then return the values as an inline type.
|
||||
if (schema.type === 'int' && schema.description) {
|
||||
const enumSymbols: Shape[] = getEnumSymbolsFromDescription(schema.description);
|
||||
const enumSymbols: ModelSymbol[] = getEnumSymbolsFromDescription(schema.description);
|
||||
if (enumSymbols.length) {
|
||||
result.isEnum = true;
|
||||
result.symbols = enumSymbols;
|
||||
result.type = getEnumType(enumSymbols);
|
||||
result.base = PrimaryType.NUMBER;
|
||||
result.validation = `yup.mixed<${name}>().oneOf([${getEnumValues(enumSymbols).join(', ')}])`;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@ -56,9 +56,6 @@ export function getSchema(openApi: OpenApi, schema: OpenApiSchema, name: string)
|
||||
// If the schema is an Array type, we check for the child type,
|
||||
// so we can create a typed array, otherwise this will be a "any[]".
|
||||
if (schema.type === 'array' && schema.items) {
|
||||
// TODO: Ik gok dat we straks een lineare parser overhouden die in 1x een bestand kan wegschrijven
|
||||
// TODO: in plaats van losse tussen stappen, dat maakt het testen ook makkelijker omdat je direct een
|
||||
// TODO: typescript bestand / output kan valideren?
|
||||
if (schema.items.$ref) {
|
||||
const arrayType: Type = getType(schema.items.$ref);
|
||||
result.imports.push(...arrayType.imports);
|
||||
@ -66,6 +63,7 @@ export function getSchema(openApi: OpenApi, schema: OpenApiSchema, name: string)
|
||||
result.type = `${arrayType.type}[]`;
|
||||
result.base = arrayType.base;
|
||||
result.template = arrayType.template;
|
||||
result.validation = `yup.array<${result.name}>().of(${result.base}.schema)`; // TODO: Simple strings!
|
||||
result.imports.push(...arrayType.imports);
|
||||
} else {
|
||||
const array: Schema = getSchema(openApi, schema.items, 'unkown');
|
||||
@ -74,6 +72,7 @@ export function getSchema(openApi: OpenApi, schema: OpenApiSchema, name: string)
|
||||
result.type = `${arrayType}[]`;
|
||||
result.base = arrayType;
|
||||
result.template = null;
|
||||
result.validation = `yup.array<${result.name}>().of(${result.base}.schema)`; // TODO: Simple strings!
|
||||
result.imports.push(...array.imports);
|
||||
}
|
||||
return result;
|
||||
@ -1,7 +0,0 @@
|
||||
export function parseModelProperties(): any {
|
||||
return {
|
||||
imports: [],
|
||||
properties: [],
|
||||
enums: [],
|
||||
};
|
||||
}
|
||||
@ -1,4 +1,4 @@
|
||||
import { Schema } from '../../../client/interfaces/Schema';
|
||||
import { Model } from '../../../client/interfaces/Model';
|
||||
|
||||
// string
|
||||
// array[test]
|
||||
@ -6,13 +6,12 @@ import { Schema } from '../../../client/interfaces/Schema';
|
||||
// foo: string
|
||||
// bar: string
|
||||
// }]
|
||||
|
||||
export function getSchemaType(schema: Schema): string {
|
||||
export function getModelType(model: Model): string {
|
||||
// if (schema.properties) {
|
||||
// return schema.type
|
||||
// }
|
||||
if (schema.type) {
|
||||
return schema.type;
|
||||
if (model.type) {
|
||||
return model.type;
|
||||
}
|
||||
return 'any';
|
||||
}
|
||||
@ -1,19 +1,15 @@
|
||||
import { Model } from '../../../client/interfaces/Model';
|
||||
import { OpenApi } from '../interfaces/OpenApi';
|
||||
import { OpenApiSchema } from '../interfaces/OpenApiSchema';
|
||||
import { getSchema } from './getSchema';
|
||||
import { Schema } from '../../../client/interfaces/Schema';
|
||||
import { getModel } from './getModel';
|
||||
|
||||
/**
|
||||
* Get the OpenAPI models.
|
||||
*/
|
||||
export function getModels(openApi: OpenApi): Map<string, Model> {
|
||||
const models: Map<string, Model> = new Map<string, Model>();
|
||||
export function getModels(openApi: OpenApi): Model[] {
|
||||
const models: Model[] = [];
|
||||
for (const definitionName in openApi.definitions) {
|
||||
if (openApi.definitions.hasOwnProperty(definitionName)) {
|
||||
const definition: OpenApiSchema = openApi.definitions[definitionName];
|
||||
const definitionSchema: Schema = getSchema(openApi, definition, definitionName);
|
||||
models.set(definitionSchema.name, definitionSchema);
|
||||
const definitionModel: Model = getModel(openApi, definition, definitionName);
|
||||
models.push(definitionModel);
|
||||
}
|
||||
}
|
||||
return models;
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
import { Service } from '../../../client/interfaces/Service';
|
||||
import { getServiceClassName } from './getServiceClassName';
|
||||
import { Operation } from '../../../client/interfaces/Operation';
|
||||
import { OpenApiOperation } from '../interfaces/OpenApiOperation';
|
||||
import { getOperationName } from './getOperationName';
|
||||
import { getOperationPath } from './getOperationPath';
|
||||
@ -8,11 +7,8 @@ import { getOperationParameters } from './getOperationParameters';
|
||||
import { OpenApi } from '../interfaces/OpenApi';
|
||||
import { getComment } from './getComment';
|
||||
import { getOperationResponses } from './getOperationResponses';
|
||||
import { OperationParameters } from '../../../client/interfaces/OperationParameters';
|
||||
import { OperationResponse } from '../../../client/interfaces/OperationResponse';
|
||||
import { getOperationResponse } from './getOperationResponse';
|
||||
import { getOperationErrors } from './getOperationErrors';
|
||||
import { OperationError } from '../../../client/interfaces/OperationError';
|
||||
|
||||
export function getOperation(openApi: OpenApi, url: string, method: string, op: OpenApiOperation): Operation {
|
||||
const serviceName: string = (op.tags && op.tags[0]) || 'Service';
|
||||
|
||||
@ -1,6 +1,3 @@
|
||||
import { OperationResponse } from '../../../client/interfaces/OperationResponse';
|
||||
import { OperationError } from '../../../client/interfaces/OperationError';
|
||||
|
||||
export function getOperationErrors(responses: OperationResponse[]): OperationError[] {
|
||||
return responses
|
||||
.filter((response: OperationResponse): boolean => {
|
||||
|
||||
@ -1,12 +1,9 @@
|
||||
import { OpenApiParameter } from '../interfaces/OpenApiParameter';
|
||||
import { getType } from './getType';
|
||||
import { Parameter } from '../../../client/interfaces/Parameter';
|
||||
import { Type } from '../../../client/interfaces/Type';
|
||||
import { OpenApi } from '../interfaces/OpenApi';
|
||||
import { getParameterName } from './getParameterName';
|
||||
import { getComment } from './getComment';
|
||||
import { SchemaReference } from '../../../client/interfaces/SchemaReference';
|
||||
import { getSchemaReference } from './getSchemaReference';
|
||||
|
||||
export function getParameter(openApi: OpenApi, parameter: OpenApiParameter): Parameter {
|
||||
const result: Parameter = {
|
||||
@ -48,11 +45,12 @@ export function getParameter(openApi: OpenApi, parameter: OpenApiParameter): Par
|
||||
// this reference type. Otherwise it might be a complex schema and
|
||||
// then we need to parse the schema!
|
||||
if (parameter.schema) {
|
||||
const parameterSchema: SchemaReference = getSchemaReference(openApi, parameter.schema);
|
||||
result.type = parameterSchema.type;
|
||||
result.base = parameterSchema.base;
|
||||
result.template = parameterSchema.template;
|
||||
result.imports.push(...parameterSchema.imports);
|
||||
// TODO: Check getSchema
|
||||
// const parameterSchema: SchemaReference = getSchemaReference(openApi, parameter.schema);
|
||||
// result.type = parameterSchema.type;
|
||||
// result.base = parameterSchema.base;
|
||||
// result.template = parameterSchema.template;
|
||||
// result.imports.push(...parameterSchema.imports);
|
||||
}
|
||||
|
||||
// Check if this could be a special enum where values are documented in the description.
|
||||
@ -68,6 +66,7 @@ export function getParameter(openApi: OpenApi, parameter: OpenApiParameter): Par
|
||||
|
||||
// If the param is a enum then return the values as an inline type.
|
||||
if (parameter.enum) {
|
||||
// TODO: Check getSchema
|
||||
// result.type = getEnumType(parameter.enum);
|
||||
// result.base = 'string';
|
||||
// result.imports = [];
|
||||
@ -1,7 +1,5 @@
|
||||
import { OpenApiParameter } from '../interfaces/OpenApiParameter';
|
||||
import { OperationParameters } from '../../../client/interfaces/OperationParameters';
|
||||
import { OpenApiReference } from '../interfaces/OpenApiReference';
|
||||
import { Parameter } from '../../../client/interfaces/Parameter';
|
||||
import { getParameter } from './getParameter';
|
||||
import { OpenApi } from '../interfaces/OpenApi';
|
||||
import { getRef } from './getRef';
|
||||
|
||||
@ -1,4 +1,3 @@
|
||||
import { OperationResponse } from '../../../client/interfaces/OperationResponse';
|
||||
import { PrimaryType } from './constants';
|
||||
|
||||
export function getOperationResponse(responses: OperationResponse[]): OperationResponse {
|
||||
|
||||
@ -1,12 +1,9 @@
|
||||
import { OpenApiResponses } from '../interfaces/OpenApiResponses';
|
||||
import { getOperationResponseCode } from './getOperationResponseCode';
|
||||
import { OperationResponse } from '../../../client/interfaces/OperationResponse';
|
||||
import { OpenApiResponse } from '../interfaces/OpenApiResponse';
|
||||
import { OpenApiReference } from '../interfaces/OpenApiReference';
|
||||
import { getRef } from './getRef';
|
||||
import { OpenApi } from '../interfaces/OpenApi';
|
||||
import { getSchemaReference } from './getSchemaReference';
|
||||
import { SchemaReference } from '../../../client/interfaces/SchemaReference';
|
||||
|
||||
export function getOperationResponses(openApi: OpenApi, responses: OpenApiResponses): OperationResponse[] {
|
||||
const results: OperationResponse[] = [];
|
||||
@ -37,11 +34,11 @@ export function getOperationResponses(openApi: OpenApi, responses: OpenApiRespon
|
||||
// this reference type. Otherwise it might be a complex schema and
|
||||
// then we need to parse the schema!
|
||||
if (response.schema) {
|
||||
const responseSchema: SchemaReference = getSchemaReference(openApi, response.schema);
|
||||
result.type = responseSchema.type;
|
||||
result.base = responseSchema.base;
|
||||
result.template = responseSchema.template;
|
||||
result.imports.push(...responseSchema.imports);
|
||||
// const responseSchema: SchemaReference = getSchemaReference(openApi, response.schema);
|
||||
// result.type = responseSchema.type;
|
||||
// result.base = responseSchema.base;
|
||||
// result.template = responseSchema.template;
|
||||
// result.imports.push(...responseSchema.imports);
|
||||
}
|
||||
|
||||
results.push(result);
|
||||
|
||||
@ -1,30 +0,0 @@
|
||||
import { OpenApiSchema } from '../interfaces/OpenApiSchema';
|
||||
import { OpenApiReference } from '../interfaces/OpenApiReference';
|
||||
import { OpenApi } from '../interfaces/OpenApi';
|
||||
import { SchemaProperty } from '../../../client/interfaces/SchemaProperty';
|
||||
import { getComment } from './getComment';
|
||||
|
||||
export function getSchemaProperty(openApi: OpenApi, property: OpenApiSchema & OpenApiReference, name: string, required: boolean): SchemaProperty {
|
||||
const result: SchemaProperty = {
|
||||
name: name,
|
||||
type: 'any',
|
||||
base: 'any',
|
||||
template: null,
|
||||
description: getComment(property.description),
|
||||
required: required,
|
||||
nullable: false,
|
||||
readOnly: property.readOnly || false,
|
||||
extends: [],
|
||||
imports: [],
|
||||
properties: new Map<string, SchemaProperty>(),
|
||||
};
|
||||
|
||||
// console.log(name, property);
|
||||
|
||||
// const property: OpenApiSchema & OpenApiReference = schema.properties[propertyName];
|
||||
// const propertySchema: SchemaReference = getSchemaReference(openApi, property);
|
||||
// result.imports.push(...propertySchema.imports);
|
||||
// result.properties.set(propertyName, propertySchema);
|
||||
|
||||
return result;
|
||||
}
|
||||
@ -1,14 +1,15 @@
|
||||
import { getType } from './getType';
|
||||
import { Type } from '../../../client/interfaces/Type';
|
||||
import { OpenApiSchema } from '../interfaces/OpenApiSchema';
|
||||
import { OpenApiReference } from '../interfaces/OpenApiReference';
|
||||
import { getRef } from './getRef';
|
||||
import { Schema } from '../../../client/interfaces/Schema';
|
||||
import { getSchema } from './getSchema';
|
||||
import { SchemaReference } from '../../../client/interfaces/SchemaReference';
|
||||
import { OpenApi } from '../interfaces/OpenApi';
|
||||
import { PrimaryType } from './constants';
|
||||
|
||||
export interface SchemaReference {
|
||||
type: string;
|
||||
base: string;
|
||||
template: string | null;
|
||||
imports: string[];
|
||||
}
|
||||
|
||||
export function getSchemaReference(openApi: OpenApi, schema: OpenApiSchema & OpenApiReference): SchemaReference {
|
||||
const result: SchemaReference = {
|
||||
type: PrimaryType.OBJECT,
|
||||
@ -18,18 +19,18 @@ export function getSchemaReference(openApi: OpenApi, schema: OpenApiSchema & Ope
|
||||
};
|
||||
|
||||
if (schema.$ref) {
|
||||
const itemSchemaType: Type = getType(schema.$ref);
|
||||
result.type = itemSchemaType.type;
|
||||
result.base = itemSchemaType.base;
|
||||
result.template = itemSchemaType.template;
|
||||
result.imports.push(...itemSchemaType.imports);
|
||||
// const itemSchemaType: Type = getType(schema.$ref);
|
||||
// result.type = itemSchemaType.type;
|
||||
// result.base = itemSchemaType.base;
|
||||
// result.template = itemSchemaType.template;
|
||||
// result.imports.push(...itemSchemaType.imports);
|
||||
} else {
|
||||
const item: OpenApiSchema = getRef<OpenApiSchema>(openApi, schema);
|
||||
const itemSchema: Schema = getSchema(openApi, item, 'unknown');
|
||||
result.type = itemSchema.type;
|
||||
result.base = itemSchema.base;
|
||||
result.template = itemSchema.template;
|
||||
result.imports.push(...itemSchema.imports);
|
||||
// const item: OpenApiSchema = getRef<OpenApiSchema>(openApi, schema);
|
||||
// const itemSchema: Schema = getSchema(openApi, item, 'unknown');
|
||||
// result.type = itemSchema.type;
|
||||
// result.base = itemSchema.base;
|
||||
// result.template = itemSchema.template;
|
||||
// result.imports.push(...itemSchema.imports);
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
@ -1,15 +1,12 @@
|
||||
import { Service } from '../../../client/interfaces/Service';
|
||||
import { OpenApi } from '../interfaces/OpenApi';
|
||||
import { OpenApiPath } from '../interfaces/OpenApiPath';
|
||||
import { OpenApiOperation } from '../interfaces/OpenApiOperation';
|
||||
import { getOperation } from './getOperation';
|
||||
import { Operation } from '../../../client/interfaces/Operation';
|
||||
import { Method } from './constants';
|
||||
|
||||
/**
|
||||
* Get the OpenAPI services
|
||||
*/
|
||||
export function getServices(openApi: OpenApi): Map<string, Service> {
|
||||
export function getServices(openApi: OpenApi): Service[] {
|
||||
const services: Map<string, Service> = new Map<string, Service>();
|
||||
for (const url in openApi.paths) {
|
||||
if (openApi.paths.hasOwnProperty(url)) {
|
||||
@ -48,5 +45,5 @@ export function getServices(openApi: OpenApi): Map<string, Service> {
|
||||
}
|
||||
}
|
||||
}
|
||||
return services;
|
||||
return Array.from(services.values());
|
||||
}
|
||||
|
||||
@ -29,7 +29,7 @@ export function getType(value: string | undefined, template: string | null = nul
|
||||
|
||||
// If the first match is a generic array then construct a correct array type,
|
||||
// for example the type "Array[Model]" becomes "Model[]".
|
||||
if (match1.type === 'any[]') {
|
||||
if (match1.type === PrimaryType.ARRAY) {
|
||||
result.type = `${match2.type}[]`;
|
||||
result.base = `${match2.type}`;
|
||||
match1.imports = [];
|
||||
|
||||
@ -1,23 +0,0 @@
|
||||
import { getMappedType } from './getMappedType';
|
||||
|
||||
describe('getMappedType', () => {
|
||||
it('should map types to the basics', () => {
|
||||
expect(getMappedType('File')).toEqual('File');
|
||||
expect(getMappedType('Array')).toEqual('any[]');
|
||||
expect(getMappedType('List')).toEqual('any[]');
|
||||
expect(getMappedType('String')).toEqual('string');
|
||||
expect(getMappedType('date')).toEqual('string');
|
||||
expect(getMappedType('date-time')).toEqual('string');
|
||||
expect(getMappedType('float')).toEqual('number');
|
||||
expect(getMappedType('double')).toEqual('number');
|
||||
expect(getMappedType('short')).toEqual('number');
|
||||
expect(getMappedType('int')).toEqual('number');
|
||||
expect(getMappedType('boolean')).toEqual('boolean');
|
||||
expect(getMappedType('any')).toEqual('any');
|
||||
expect(getMappedType('object')).toEqual('any');
|
||||
expect(getMappedType('void')).toEqual('void');
|
||||
expect(getMappedType('null')).toEqual('null');
|
||||
expect(getMappedType('Unknown')).toEqual('Unknown');
|
||||
expect(getMappedType('')).toEqual('');
|
||||
});
|
||||
});
|
||||
@ -1,42 +0,0 @@
|
||||
const MAPPINGS = new Map<string, string>([
|
||||
['file', 'File'],
|
||||
['binary', 'File'],
|
||||
['array', 'any[]'],
|
||||
['list', 'any[]'],
|
||||
['object', 'any'],
|
||||
['any', 'any'],
|
||||
['boolean', 'boolean'],
|
||||
['byte', 'number'],
|
||||
['int', 'number'],
|
||||
['int32', 'number'],
|
||||
['int64', '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.
|
||||
* @param type
|
||||
*/
|
||||
export function getMappedType(type: string): string {
|
||||
const mapped: string | undefined = MAPPINGS.get(type.toLowerCase());
|
||||
if (mapped) {
|
||||
return mapped;
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
export function hasMappedType(type: string): boolean {
|
||||
return MAPPINGS.has(type.toLowerCase());
|
||||
}
|
||||
@ -5,7 +5,7 @@ import { OpenApi } from '../interfaces/OpenApi';
|
||||
* Parse and return the OpenAPI models.
|
||||
* @param openApi
|
||||
*/
|
||||
export function getModels(openApi: OpenApi): Map<string, Model> {
|
||||
const models: Map<string, Model> = new Map<string, Model>();
|
||||
export function getModels(openApi: OpenApi): Model[] {
|
||||
const models: Model[] = [];
|
||||
return models;
|
||||
}
|
||||
|
||||
@ -5,7 +5,7 @@ import { OpenApi } from '../interfaces/OpenApi';
|
||||
* Parse and return the OpenAPI services.
|
||||
* @param openApi
|
||||
*/
|
||||
export function getServices(openApi: OpenApi): Map<string, Service> {
|
||||
const services: Map<string, Service> = new Map<string, Service>();
|
||||
export function getServices(openApi: OpenApi): Service[] {
|
||||
const services: Service[] = [];
|
||||
return services;
|
||||
}
|
||||
|
||||
@ -1,51 +0,0 @@
|
||||
import { getType } from './getType';
|
||||
|
||||
describe('getType', () => {
|
||||
it('should convert int', () => {
|
||||
const type = getType('int', null);
|
||||
expect(type.type).toEqual('number');
|
||||
expect(type.base).toEqual('number');
|
||||
expect(type.template).toEqual(null);
|
||||
expect(type.imports).toEqual([]);
|
||||
});
|
||||
|
||||
it('should convert string', () => {
|
||||
const type = getType('String', null);
|
||||
expect(type.type).toEqual('string');
|
||||
expect(type.base).toEqual('string');
|
||||
expect(type.template).toEqual(null);
|
||||
expect(type.imports).toEqual([]);
|
||||
});
|
||||
|
||||
it('should convert string array', () => {
|
||||
const type = getType('Array[String]', null);
|
||||
expect(type.type).toEqual('string[]');
|
||||
expect(type.base).toEqual('string');
|
||||
expect(type.template).toEqual(null);
|
||||
expect(type.imports).toEqual([]);
|
||||
});
|
||||
|
||||
it('should convert template with primary', () => {
|
||||
const type = getType('#/components/schemas/Link[String]', null);
|
||||
expect(type.type).toEqual('Link<string>');
|
||||
expect(type.base).toEqual('Link');
|
||||
expect(type.template).toEqual('string');
|
||||
expect(type.imports).toEqual(['Link']);
|
||||
});
|
||||
|
||||
it('should convert template with model', () => {
|
||||
const type = getType('#/components/schemas/Link[Model]', null);
|
||||
expect(type.type).toEqual('Link<Model>');
|
||||
expect(type.base).toEqual('Link');
|
||||
expect(type.template).toEqual('Model');
|
||||
expect(type.imports).toEqual(['Link', 'Model']);
|
||||
});
|
||||
|
||||
it('should convert generic', () => {
|
||||
const type = getType('#/components/schemas/Link', 'Link');
|
||||
expect(type.type).toEqual('T');
|
||||
expect(type.base).toEqual('T');
|
||||
expect(type.template).toEqual(null);
|
||||
expect(type.imports).toEqual([]);
|
||||
});
|
||||
});
|
||||
@ -1,74 +0,0 @@
|
||||
import { stripNamespace } from './stripNamespace';
|
||||
import { Type } from '../../../client/interfaces/Type';
|
||||
import { getMappedType, hasMappedType } from './getMappedType';
|
||||
|
||||
/**
|
||||
* Parse any value into a type object.
|
||||
* @param value String value like "integer" or "Link[Model]".
|
||||
* @param template Optional template class from parent (needed to process generics)
|
||||
*/
|
||||
export function getType(value: string, template: string | null = null): Type {
|
||||
let propertyType = 'any';
|
||||
let propertyBase = 'any';
|
||||
let propertyTemplate: string | null = null;
|
||||
let propertyImports: string[] = [];
|
||||
|
||||
// Remove definitions prefix and cleanup string.
|
||||
const valueTrimmed: string = stripNamespace(value || '');
|
||||
|
||||
// Check of we have an Array type or generic type, for instance: "Link[Model]".
|
||||
if (/\[.*\]$/g.test(valueTrimmed)) {
|
||||
// Find the first and second type
|
||||
const match: RegExpMatchArray | null = valueTrimmed.match(/(.*?)\[(.*)\]$/);
|
||||
if (match) {
|
||||
// Both of the types can be complex types so parse each of them.
|
||||
const match1: Type = getType(match[1]);
|
||||
const match2: Type = getType(match[2]);
|
||||
|
||||
// If the first match is a generic array then construct a correct array type, for example:
|
||||
// The type "Array[Model]" becomes "Model[]".
|
||||
if (match1.type === 'any[]') {
|
||||
propertyType = `${match2.type}[]`;
|
||||
propertyBase = `${match2.type}`;
|
||||
match1.imports = [];
|
||||
} else if (match2.type === '') {
|
||||
// Primary types like number[] or string[]
|
||||
propertyType = match1.type;
|
||||
propertyBase = match1.type;
|
||||
propertyTemplate = match1.type;
|
||||
match2.imports = [];
|
||||
} else {
|
||||
propertyType = `${match1.type}<${match2.type}>`;
|
||||
propertyBase = match1.type;
|
||||
propertyTemplate = match2.type;
|
||||
}
|
||||
|
||||
// Either way we need to add the found imports
|
||||
propertyImports.push(...match1.imports);
|
||||
propertyImports.push(...match2.imports);
|
||||
}
|
||||
} else if (hasMappedType(valueTrimmed)) {
|
||||
const mapped: string = getMappedType(valueTrimmed);
|
||||
propertyType = mapped;
|
||||
propertyBase = mapped;
|
||||
} else {
|
||||
propertyType = valueTrimmed;
|
||||
propertyBase = valueTrimmed;
|
||||
propertyImports.push(valueTrimmed);
|
||||
}
|
||||
|
||||
// If the property that we found matched the parent template class
|
||||
// Then ignore this whole property and return it as a "T" template property.
|
||||
if (propertyType === template) {
|
||||
propertyType = 'T'; // Template;
|
||||
propertyBase = 'T'; // Template;
|
||||
propertyImports = [];
|
||||
}
|
||||
|
||||
return {
|
||||
type: propertyType,
|
||||
base: propertyBase,
|
||||
template: propertyTemplate,
|
||||
imports: propertyImports,
|
||||
};
|
||||
}
|
||||
@ -1,15 +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('object')).toBeTruthy();
|
||||
expect(isPrimaryType('void')).toBeTruthy();
|
||||
expect(isPrimaryType('null')).toBeTruthy();
|
||||
expect(isPrimaryType('Array')).toBeFalsy();
|
||||
expect(isPrimaryType('MyModel')).toBeFalsy();
|
||||
});
|
||||
});
|
||||
@ -1,17 +0,0 @@
|
||||
/**
|
||||
* Check if given type is a primary type.
|
||||
* @param type
|
||||
*/
|
||||
export function isPrimaryType(type: string): boolean {
|
||||
switch (type.toLowerCase()) {
|
||||
case 'number':
|
||||
case 'boolean':
|
||||
case 'string':
|
||||
case 'object':
|
||||
case 'any':
|
||||
case 'void':
|
||||
case 'null':
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@ -8,7 +8,9 @@
|
||||
import { {{{this}}} } from '../models/{{{this}}}';
|
||||
{{/each}}
|
||||
{{/if}}
|
||||
{{#if validation}}
|
||||
import * as yup from 'yup';
|
||||
{{/if}}
|
||||
{{#if description}}
|
||||
|
||||
/**
|
||||
@ -42,24 +44,25 @@ export namespace {{{name}}} {
|
||||
}
|
||||
|
||||
{{/each}}
|
||||
export const schema = yup.object<{{{name}}}{{{template}}}>().shape({
|
||||
// Add properties
|
||||
});
|
||||
{{#if validation}}
|
||||
export const schema = {{{validation}}};
|
||||
|
||||
export function validate(value: {{{name}}}{{{template}}}): Promise<{{{name}}}{{{template}}}> {
|
||||
export function validate(value: any): Promise<{{{name}}}{{{template}}}> {
|
||||
return schema.validate(value, { strict: true });
|
||||
}
|
||||
|
||||
export function validateSync(value: {{{name}}}{{{template}}}): {{{name}}}{{{template}}} {
|
||||
export function validateSync(value: any): {{{name}}}{{{template}}} {
|
||||
return schema.validateSync(value, { strict: true });
|
||||
}
|
||||
{{/if}}
|
||||
}
|
||||
{{/if}}
|
||||
{{#if isType}}
|
||||
export type {{{name}}} = {{{type}}}{{#if nullable}} | null{{/if}};
|
||||
{{#if validation}}
|
||||
|
||||
export namespace {{{name}}} {
|
||||
export const schema = yup.string();
|
||||
export const schema = {{{validation}}};
|
||||
|
||||
export function validate(value: any): Promise<{{{name}}}{{#if nullable}} | null{{/if}}> {
|
||||
return schema.validate(value, { strict: true });
|
||||
@ -70,15 +73,17 @@ export namespace {{{name}}} {
|
||||
}
|
||||
}
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
{{#if isEnum}}
|
||||
export enum {{{name}}} {
|
||||
{{#each symbols}}
|
||||
{{{name}}} = {{{value}}},
|
||||
{{/each}}
|
||||
}
|
||||
{{#if validation}}
|
||||
|
||||
export namespace {{{name}}} {
|
||||
export const schema = yup.string();
|
||||
export const schema = {{{validation}}};
|
||||
|
||||
export function validate(value: any): Promise<{{{name}}}> {
|
||||
return schema.validate(value, { strict: true });
|
||||
@ -89,3 +94,4 @@ export namespace {{{name}}} {
|
||||
}
|
||||
}
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
|
||||
9
src/utils/cleanupModels.ts
Normal file
9
src/utils/cleanupModels.ts
Normal file
@ -0,0 +1,9 @@
|
||||
import { getSortedImports } from './getSortedImports';
|
||||
import { Model } from '../client/interfaces/Model';
|
||||
|
||||
export function cleanupModels(models: Model[]): Model[] {
|
||||
models.forEach((models: Model): void => {
|
||||
models.imports = getSortedImports(models.imports);
|
||||
});
|
||||
return models;
|
||||
}
|
||||
@ -2,13 +2,12 @@ import { Service } from '../client/interfaces/Service';
|
||||
import { getSortedImports } from './getSortedImports';
|
||||
import { Operation } from '../client/interfaces/Operation';
|
||||
|
||||
export function cleanupServices(services: Map<string, Service>): Map<string, Service> {
|
||||
export function cleanupServices(services: Service[]): Service[] {
|
||||
services.forEach((service: Service): void => {
|
||||
const names: Map<string, number> = new Map<string, number>();
|
||||
|
||||
service.imports = getSortedImports(service.imports);
|
||||
|
||||
// Append postfix number to duplicate operation names and sort them.
|
||||
service.operations = service.operations
|
||||
.map(
|
||||
(operation: Operation): Operation => {
|
||||
|
||||
@ -3,39 +3,55 @@ import { Model } from '../client/interfaces/Model';
|
||||
|
||||
describe('getSortedModels', () => {
|
||||
it('should return sorted list', () => {
|
||||
const models = new Map<string, Model>();
|
||||
models.set('John', {
|
||||
name: 'John',
|
||||
base: 'John',
|
||||
type: '',
|
||||
template: null,
|
||||
extends: [],
|
||||
imports: [],
|
||||
properties: [],
|
||||
enums: [],
|
||||
});
|
||||
models.set('Jane', {
|
||||
name: 'Jane',
|
||||
base: 'Jane',
|
||||
type: '',
|
||||
template: null,
|
||||
extends: [],
|
||||
imports: [],
|
||||
properties: [],
|
||||
enums: [],
|
||||
});
|
||||
models.set('Doe', {
|
||||
name: 'Doe',
|
||||
base: 'Doe',
|
||||
type: '',
|
||||
template: null,
|
||||
extends: [],
|
||||
imports: [],
|
||||
properties: [],
|
||||
enums: [],
|
||||
});
|
||||
const models: Model[] = [
|
||||
{
|
||||
isInterface: false,
|
||||
isType: false,
|
||||
isEnum: false,
|
||||
name: 'John',
|
||||
type: 'John',
|
||||
base: 'John',
|
||||
template: null,
|
||||
validation: null,
|
||||
description: null,
|
||||
extends: null,
|
||||
imports: [],
|
||||
properties: [],
|
||||
enums: [],
|
||||
},
|
||||
{
|
||||
isInterface: false,
|
||||
isType: false,
|
||||
isEnum: false,
|
||||
name: 'Jane',
|
||||
type: 'Jane',
|
||||
base: 'Jane',
|
||||
template: null,
|
||||
validation: null,
|
||||
description: null,
|
||||
extends: null,
|
||||
imports: [],
|
||||
properties: [],
|
||||
enums: [],
|
||||
},
|
||||
{
|
||||
isInterface: false,
|
||||
isType: false,
|
||||
isEnum: false,
|
||||
name: 'Doe',
|
||||
type: 'Doe',
|
||||
base: 'Doe',
|
||||
template: null,
|
||||
validation: null,
|
||||
description: null,
|
||||
extends: null,
|
||||
imports: [],
|
||||
properties: [],
|
||||
enums: [],
|
||||
},
|
||||
];
|
||||
|
||||
expect(getSortedModels(new Map<string, Model>())).toEqual([]);
|
||||
expect(getSortedModels(models)).toEqual([models.get('Doe'), models.get('Jane'), models.get('John')]);
|
||||
expect(getSortedModels([])).toEqual([]);
|
||||
expect(getSortedModels(models)).toEqual(models.reverse());
|
||||
});
|
||||
});
|
||||
|
||||
@ -1,15 +1,9 @@
|
||||
import { Model } from '../client/interfaces/Model';
|
||||
|
||||
/**
|
||||
* Convert a given Map to an Array and sort the result the Model base name.
|
||||
* @param models Map of Model objects.
|
||||
*/
|
||||
export function getSortedModels(models: Map<string, Model>): Model[] {
|
||||
return (
|
||||
Array.from(models.values()).sort((a, b) => {
|
||||
const nameA: string = a.name.toLowerCase();
|
||||
const nameB: string = b.name.toLowerCase();
|
||||
return nameA.localeCompare(nameB, 'en');
|
||||
}) || []
|
||||
);
|
||||
export function getSortedModels(models: Model[]): Model[] {
|
||||
return models.sort((a, b) => {
|
||||
const nameA: string = a.name.toLowerCase();
|
||||
const nameB: string = b.name.toLowerCase();
|
||||
return nameA.localeCompare(nameB, 'en');
|
||||
});
|
||||
}
|
||||
|
||||
@ -3,24 +3,25 @@ import { Service } from '../client/interfaces/Service';
|
||||
|
||||
describe('getSortedServices', () => {
|
||||
it('should return sorted list', () => {
|
||||
const services = new Map<string, Service>();
|
||||
services.set('John', {
|
||||
name: 'John',
|
||||
operations: [],
|
||||
imports: [],
|
||||
});
|
||||
services.set('Jane', {
|
||||
name: 'Jane',
|
||||
operations: [],
|
||||
imports: [],
|
||||
});
|
||||
services.set('Doe', {
|
||||
name: 'Doe',
|
||||
operations: [],
|
||||
imports: [],
|
||||
});
|
||||
const services: Service[] = [
|
||||
{
|
||||
name: 'John',
|
||||
operations: [],
|
||||
imports: [],
|
||||
},
|
||||
{
|
||||
name: 'Jane',
|
||||
operations: [],
|
||||
imports: [],
|
||||
},
|
||||
{
|
||||
name: 'Doe',
|
||||
operations: [],
|
||||
imports: [],
|
||||
},
|
||||
];
|
||||
|
||||
expect(getSortedServices(new Map<string, Service>())).toEqual([]);
|
||||
expect(getSortedServices(services)).toEqual([services.get('Doe'), services.get('Jane'), services.get('John')]);
|
||||
expect(getSortedServices([])).toEqual([]);
|
||||
expect(getSortedServices(services)).toEqual(services.reverse());
|
||||
});
|
||||
});
|
||||
|
||||
@ -1,15 +1,9 @@
|
||||
import { Service } from '../client/interfaces/Service';
|
||||
|
||||
/**
|
||||
* Convert a given Map to an Array and sort the result the service base name.
|
||||
* @param services Map of Service objects.
|
||||
*/
|
||||
export function getSortedServices(services: Map<string, Service>): Service[] {
|
||||
return (
|
||||
Array.from(services.values()).sort((a, b) => {
|
||||
const nameA: string = a.name.toLowerCase();
|
||||
const nameB: string = b.name.toLowerCase();
|
||||
return nameA.localeCompare(nameB, 'en');
|
||||
}) || []
|
||||
);
|
||||
export function getSortedServices(services: Service[]): Service[] {
|
||||
return services.sort((a, b) => {
|
||||
const nameA: string = a.name.toLowerCase();
|
||||
const nameB: string = b.name.toLowerCase();
|
||||
return nameA.localeCompare(nameB, 'en');
|
||||
});
|
||||
}
|
||||
|
||||
@ -24,8 +24,8 @@ describe('writeClient', () => {
|
||||
const client: Client = {
|
||||
server: 'http://localhost:8080',
|
||||
version: 'v1',
|
||||
models: new Map<string, Model>(),
|
||||
services: new Map<string, Service>(),
|
||||
models: [],
|
||||
services: [],
|
||||
};
|
||||
|
||||
const templates: Templates = {
|
||||
|
||||
@ -13,6 +13,7 @@ import * as fs from 'fs';
|
||||
import { getFileName } from './getFileName';
|
||||
import * as glob from 'glob';
|
||||
import { cleanupServices } from './cleanupServices';
|
||||
import { cleanupModels } from './cleanupModels';
|
||||
|
||||
/**
|
||||
* Write our OpenAPI client, using the given templates at the given output path
|
||||
@ -58,7 +59,7 @@ export function writeClient(client: Client, language: Language, templates: Templ
|
||||
try {
|
||||
// TODO: Cleanup models
|
||||
writeClientIndex(client, language, templates.index, outputPath);
|
||||
writeClientModels(getSortedModels(client.models), language, templates.model, outputPathModels);
|
||||
writeClientModels(getSortedModels(cleanupModels(client.models)), language, templates.model, outputPathModels);
|
||||
writeClientServices(getSortedServices(cleanupServices(client.services)), language, templates.service, outputPathServices);
|
||||
} catch (e) {
|
||||
throw e;
|
||||
|
||||
@ -14,8 +14,8 @@ describe('writeClientIndex', () => {
|
||||
const client: Client = {
|
||||
server: 'http://localhost:8080',
|
||||
version: 'v1',
|
||||
models: new Map<string, Model>(),
|
||||
services: new Map<string, Service>(),
|
||||
models: [],
|
||||
services: [],
|
||||
};
|
||||
const template = () => 'dummy';
|
||||
writeClientIndex(client, Language.TYPESCRIPT, template, '/');
|
||||
|
||||
@ -11,11 +11,16 @@ describe('writeClientModels', () => {
|
||||
it('should write to filesystem', () => {
|
||||
const models: Model[] = [
|
||||
{
|
||||
isInterface: false,
|
||||
isType: false,
|
||||
isEnum: false,
|
||||
name: 'Item',
|
||||
type: 'Item',
|
||||
base: 'Item',
|
||||
type: '',
|
||||
template: '',
|
||||
extends: [],
|
||||
template: null,
|
||||
validation: null,
|
||||
description: null,
|
||||
extends: null,
|
||||
imports: [],
|
||||
properties: [],
|
||||
enums: [],
|
||||
|
||||
@ -16,13 +16,7 @@ export function writeClientModels(models: Model[], language: Language, template:
|
||||
models.forEach(model => {
|
||||
const fileName: string = getFileName(model.name, language);
|
||||
try {
|
||||
fs.writeFileSync(
|
||||
path.resolve(outputPath, fileName),
|
||||
template({
|
||||
...model,
|
||||
// properties: Array.from(model.properties.values()), // TODO in cleanup?
|
||||
})
|
||||
);
|
||||
fs.writeFileSync(path.resolve(outputPath, fileName), template(model));
|
||||
} catch (e) {
|
||||
throw new Error(`Could not write model: "${fileName}"`);
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user