- Cleanup of generator

This commit is contained in:
Ferdi Koomen 2019-11-07 01:54:52 +01:00
parent 8149bd21c5
commit 91dd581d85
13 changed files with 118 additions and 44 deletions

View File

@ -1,4 +1,8 @@
export interface OperationResponse {
code: number;
text: string;
type: string;
base: string;
template: string | null;
imports: string[];
}

View File

@ -8,7 +8,7 @@ export function getArrayType(items: OpenApiItems): ArrayType {
let itemsType = 'any';
let itemsBase = 'any';
let itemsTemplate: string | null = null;
const itemsImports: string[] = [];
let itemsImports: string[] = [];
// If the parameter has a type than it can be a basic or generic type.
if (items.type) {
@ -16,7 +16,7 @@ export function getArrayType(items: OpenApiItems): ArrayType {
itemsType = itemsData.type;
itemsBase = itemsData.base;
itemsTemplate = itemsData.template;
itemsImports.push(...itemsData.imports);
itemsImports = [...itemsData.imports];
// If the parameter is an Array type, we check for the child type,
// so we can create a typed array, otherwise this will be a "any[]".

View File

@ -10,6 +10,9 @@ 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 = (op.tags && op.tags[0]) || 'Service';
@ -53,11 +56,13 @@ export function getOperation(openApi: OpenApi, url: string, method: string, op:
// Parse the operation responses.
if (op.responses) {
const responses: OperationResponse[] = getOperationResponses(openApi, op.responses);
// const result: OperationResponse = getOperationResult(responses);
// const errors = getOperationErrors(responses);
// operation.imports.push(...result.imports);
// operation.errors = errors;
// operation.result = result.type;
const response: OperationResponse = getOperationResponse(responses);
const errors: OperationError[] = getOperationErrors(responses);
operation.imports.push(...response.imports);
operation.errors = errors;
operation.result = response.type;
console.log(operation.result);
}
return operation;

View File

@ -0,0 +1,31 @@
import { OperationResponse } from '../../../client/interfaces/OperationResponse';
export function getOperationResponse(responses: OperationResponse[]): OperationResponse {
let responseCode = 200;
let responseText = '';
let responseType = 'any';
let responseBase = 'any';
let responseTemplate: string | null = null;
let responseImports: string[] = [];
// Fetch the first valid (2XX range) response code and return that type.
const result: OperationResponse | undefined = responses.find(response => response.code && response.code >= 200 && response.code < 300);
if (result) {
responseCode = result.code;
responseText = result.text;
responseType = result.type;
responseBase = result.base;
responseTemplate = result.template;
responseImports = [...result.imports];
}
return {
code: responseCode,
text: responseText,
type: responseType,
base: responseBase,
template: responseTemplate,
imports: responseImports,
};
}

View File

@ -5,6 +5,11 @@ import { OpenApiResponse } from '../interfaces/OpenApiResponse';
import { OpenApiReference } from '../interfaces/OpenApiReference';
import { getRef } from './getRef';
import { OpenApi } from '../interfaces/OpenApi';
import { getType } from './getType';
import { Type } from '../../../client/interfaces/Type';
import { Schema } from '../../../client/interfaces/Schema';
import { getSchema } from './getSchema';
import { OpenApiSchema } from '../interfaces/OpenApiSchema';
export function getOperationResponses(openApi: OpenApi, responses: OpenApiResponses): OperationResponse[] {
const result: OperationResponse[] = [];
@ -17,16 +22,35 @@ export function getOperationResponses(openApi: OpenApi, responses: OpenApiRespon
const response: OpenApiResponse = getRef<OpenApiResponse>(openApi, responseOrReference);
const responseCode: number | null = getOperationResponseCode(code);
const responseText: string = response.description || '';
let responseType = 'any';
let responseBase = 'any';
let responseTemplate: string | null = null;
let responseImports: string[] = [];
// TODO:
if (response.schema) {
console.log('response.schema', response.schema);
if (response.schema.$ref) {
const schemaReference: Type = getType(response.schema.$ref);
responseType = schemaReference.type;
responseBase = schemaReference.base;
responseTemplate = schemaReference.template;
responseImports = [...schemaReference.imports];
} else {
const schema: Schema = getSchema(openApi, response.schema as OpenApiSchema);
responseType = schema.type;
responseBase = schema.base;
responseTemplate = schema.template;
responseImports = [...schema.imports];
}
}
if (responseCode) {
result.push({
code: responseCode,
text: responseText,
type: responseType,
base: responseBase,
template: responseTemplate,
imports: responseImports,
});
}
}

View File

@ -1,19 +0,0 @@
import { OperationResponse } from '../../../client/interfaces/OperationResponse';
export function getOperationResult(responses: OperationResponse[]): OperationResponse {
const resultCode = 200;
const resultTes: string[] = [];
// Fetch the first valid (2XX range) response code and return that type.
const result: OperationResponse | undefined = responses.find(response => response.code && response.code >= 200 && response.code < 300 && response.property);
if (result && result.property) {
resultType = result.property.type;
resultImports = [...result.property.imports];
}
return {
type: resultType,
imports: resultImports,
};
}

View File

@ -9,6 +9,9 @@ import { ArrayType } from '../../../client/interfaces/ArrayType';
import { getEnumType } from './getEnumType';
import { getEnumTypeFromDescription } from './getEnumTypeFromDescription';
import { getComment } from './getComment';
import { getSchema } from './getSchema';
import { Schema } from '../../../client/interfaces/Schema';
import { OpenApiSchema } from '../interfaces/OpenApiSchema';
export function getParameter(openApi: OpenApi, parameter: OpenApiParameter): Parameter {
let parameterType = 'any';
@ -35,10 +38,24 @@ export function getParameter(openApi: OpenApi, parameter: OpenApiParameter): Par
}
}
// If this parameter has a schema, then we should treat it as an embedded parameter.
// We can just parse the schema name ($ref) and use that as the parameter type.
// If this parameter has a schema, then we need to check two things:
// if this is a reference then the parameter is just the 'name' of
// this reference type. Otherwise it might be a complex schema and
// then we need to parse the schema!
if (parameter.schema) {
// TODO: console.log('parameter.schema', parameter.schema);
if (parameter.schema.$ref) {
const schemaReference: Type = getType(parameter.schema.$ref);
parameterType = schemaReference.type;
parameterBase = schemaReference.base;
parameterTemplate = schemaReference.template;
parameterImports.push(...schemaReference.imports);
} else {
const schema: Schema = getSchema(openApi, parameter.schema as OpenApiSchema);
parameterType = schema.type;
parameterBase = schema.base;
parameterTemplate = schema.template;
parameterImports.push(...schema.imports);
}
}
// If the param is a enum then return the values as an inline type.

View File

@ -0,0 +1,12 @@
import { OpenApi } from '../interfaces/OpenApi';
import { Schema } from '../../../client/interfaces/Schema';
import { OpenApiSchema } from '../interfaces/OpenApiSchema';
export function getSchema(openApi: OpenApi, schema: OpenApiSchema): Schema {
return {
type: 'todo',
base: 'todo',
template: null,
imports: [],
};
}

View File

@ -7,18 +7,18 @@ import { getMappedType, hasMappedType } from './getMappedType';
* @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 {
export function getType(value: string | undefined, 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 || '');
const valueClean: string = stripNamespace(value || '');
// Check of we have an Array type or generic type, for instance: "Link[Model]".
if (/\[.*\]$/g.test(valueTrimmed)) {
const matches: RegExpMatchArray | null = valueTrimmed.match(/(.*?)\[(.*)\]$/);
if (/\[.*\]$/g.test(valueClean)) {
const matches: RegExpMatchArray | null = valueClean.match(/(.*?)\[(.*)\]$/);
if (matches) {
// Both of the types can be complex types so parse each of them.
const match1: Type = getType(matches[1]);
@ -46,14 +46,14 @@ export function getType(value: string, template: string | null = null): Type {
propertyImports.push(...match1.imports);
propertyImports.push(...match2.imports);
}
} else if (hasMappedType(valueTrimmed)) {
const mapped: string = getMappedType(valueTrimmed);
} else if (hasMappedType(valueClean)) {
const mapped: string = getMappedType(valueClean);
propertyType = mapped;
propertyBase = mapped;
} else {
propertyType = valueTrimmed;
propertyBase = valueTrimmed;
propertyImports.push(valueTrimmed);
propertyType = valueClean;
propertyBase = valueClean;
propertyImports.push(valueClean);
}
// If the property that we found matched the parent template class

View File

@ -14,7 +14,7 @@ import { Result } from './Result';
* @param options Request method options.
* @returns Result object (see above)
*/
export async function request<T>(options: Readonly<RequestOptions>): Promise<Result<T>> {
export async function request<T = any>(options: Readonly<RequestOptions>): Promise<Result<T>> {
// Create the request URL
let url: string = `${OpenAPI.BASE}${options.path}`;

View File

@ -11,7 +11,7 @@ import { Result } from './Result';
* @param url The url to request.
* @param request The request object, containing method, headers, body, etc.
*/
export async function requestUsingFetch<T>(url: string, request: Readonly<RequestInit>): Promise<Result<T>> {
export async function requestUsingFetch<T = any>(url: string, request: Readonly<RequestInit>): Promise<Result<T>> {
// Fetch response using fetch API.
const response: Response = await fetch(url, request);

View File

@ -13,7 +13,7 @@ import { isSuccess } from './isSuccess';
* @param url The url to request.
* @param request The request object, containing method, headers, body, etc.
*/
export async function requestUsingXHR<T>(url: string, request: Readonly<RequestInit>): Promise<Result<T>> {
export async function requestUsingXHR<T = any>(url: string, request: Readonly<RequestInit>): Promise<Result<T>> {
return new Promise(resolve => {
const xhr: XMLHttpRequest = new XMLHttpRequest();

View File

@ -41,7 +41,7 @@ export class {{{name}}} {
{{/each}}
{{/if}}
const result: Result<{{{result}}}> = await request<{{{result}}}>({
const result: Result = await request({
method: '{{{method}}}',
path: `{{{path}}}`,{{#if parametersHeader}}
headers: {