- Models are looking good!

This commit is contained in:
Ferdi Koomen 2019-11-21 23:19:22 +01:00
parent d75a7e5eb6
commit 7167c97c1d
36 changed files with 274 additions and 336 deletions

View File

@ -14,6 +14,7 @@
"@typescript-eslint/no-explicit-any": 0,
"@typescript-eslint/no-inferrable-types": 0,
"@typescript-eslint/no-non-null-assertion": 0,
"@typescript-eslint/ban-ts-ignore": 0,
"@typescript-eslint/explicit-function-return-type": 0,
"prettier/prettier": [
"error"

View File

@ -1,13 +1,7 @@
export interface OperationParameter {
import { Model } from './Model';
export interface OperationParameter extends Model {
prop: string;
in: 'path' | 'query' | 'header' | 'formData' | 'body';
name: string;
type: string;
base: string;
template: string | null;
description: string | null;
default: any;
required: boolean;
nullable: boolean;
imports: string[];
}

View File

@ -1,5 +1,6 @@
import { OpenApiItems } from './OpenApiItems';
import { OpenApiSchema } from './OpenApiSchema';
import { OpenApiReference } from './OpenApiReference';
/**
* https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#parameterObject

View File

@ -49,7 +49,7 @@ export function getModel(openApi: OpenApi, definition: OpenApiSchema, name: stri
}
}
if (definition.type === 'int' && definition.description) {
if ((definition.type === 'int' || definition.type === 'integer') && definition.description) {
const enumerators = getEnumFromDescription(definition.description);
if (enumerators.length) {
result.export = 'enum';
@ -119,6 +119,9 @@ export function getModel(openApi: OpenApi, definition: OpenApiSchema, name: stri
properties.forEach(property => {
result.properties.push(property);
result.imports.push(...property.imports);
if (property.export === 'enum') {
result.enums.push(property);
}
});
}
});
@ -129,6 +132,9 @@ export function getModel(openApi: OpenApi, definition: OpenApiSchema, name: stri
properties.forEach(property => {
result.properties.push(property);
result.imports.push(...property.imports);
if (property.export === 'enum') {
result.enums.push(property);
}
});
}

View File

@ -3,12 +3,8 @@ import { getServiceClassName } from './getServiceClassName';
import { OpenApiOperation } from '../interfaces/OpenApiOperation';
import { getOperationName } from './getOperationName';
import { getOperationPath } from './getOperationPath';
import { getOperationParameters } from './getOperationParameters';
import { OpenApi } from '../interfaces/OpenApi';
import { getComment } from './getComment';
import { getOperationResponses } from './getOperationResponses';
import { getOperationResponse } from './getOperationResponse';
import { getOperationErrors } from './getOperationErrors';
import { Operation } from '../../../client/interfaces/Operation';
import { PrimaryType } from './constants';
@ -41,24 +37,24 @@ export function getOperation(openApi: OpenApi, url: string, method: string, op:
// Parse the operation parameters (path, query, body, etc).
if (op.parameters) {
const parameters = getOperationParameters(openApi, op.parameters);
result.imports.push(...parameters.imports);
result.parameters.push(...parameters.parameters);
result.parametersPath.push(...parameters.parametersPath);
result.parametersQuery.push(...parameters.parametersQuery);
result.parametersForm.push(...parameters.parametersForm);
result.parametersHeader.push(...parameters.parametersHeader);
result.parametersBody = parameters.parametersBody;
// const parameters = getOperationParameters(openApi, op.parameters);
// result.imports.push(...parameters.imports);
// result.parameters.push(...parameters.parameters);
// result.parametersPath.push(...parameters.parametersPath);
// result.parametersQuery.push(...parameters.parametersQuery);
// result.parametersForm.push(...parameters.parametersForm);
// result.parametersHeader.push(...parameters.parametersHeader);
// result.parametersBody = parameters.parametersBody;
}
// Parse the operation responses.
if (op.responses) {
const responses = getOperationResponses(openApi, op.responses);
const response = getOperationResponse(responses);
const errors = getOperationErrors(responses);
result.imports.push(...response.imports);
result.errors = errors;
result.result = response.type;
// const responses = getOperationResponses(openApi, op.responses);
// const response = getOperationResponse(responses);
// const errors = getOperationErrors(responses);
// result.imports.push(...response.imports);
// result.errors = errors;
// result.result = response.type;
}
return result;

View File

@ -1,76 +1,30 @@
import { OpenApiParameter } from '../interfaces/OpenApiParameter';
import { getType } from './getType';
import { OpenApi } from '../interfaces/OpenApi';
import { getComment } from './getComment';
import { getOperationParameterName } from './getOperationParameterName';
import { OperationParameter } from '../../../client/interfaces/OperationParameter';
import { PrimaryType } from './constants';
export function getOperationParameter(openApi: OpenApi, parameter: OpenApiParameter): OperationParameter {
const result: OperationParameter = {
in: parameter.in,
prop: parameter.name,
name: getOperationParameterName(parameter.name),
type: 'any',
base: 'any',
export: 'interface',
type: PrimaryType.OBJECT,
base: PrimaryType.OBJECT,
template: null,
link: null,
description: getComment(parameter.description),
default: parameter.default,
required: parameter.required || false,
readOnly: false,
required: false,
nullable: false,
imports: [],
extends: [],
enum: [],
enums: [],
properties: [],
default: null,
};
// If the parameter has a type than it can be a basic or generic type.
if (parameter.type) {
const parameterType = getType(parameter.type);
result.type = parameterType.type;
result.base = parameterType.base;
result.template = parameterType.template;
result.imports.push(...parameterType.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[]".
if (parameter.type === 'array' && parameter.items) {
// TODO: Check getSchema
// const arrayType: ArrayType = getArrayType(parameter.items);
// result.type = `${arrayType.type}[]`;
// result.base = arrayType.base;
// result.template = arrayType.template;
// result.imports.push(...arrayType.imports);
}
}
// 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: 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.
if (parameter.enum && parameter.description && parameter.type === 'int') {
// TODO: Check getSchema
// const enumType: string | null = getEnumTypeFromDescription(parameter.description);
// if (enumType) {
// result.type = enumType;
// result.base = 'number';
// result.imports = [];
// }
}
// 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 = [];
}
return result;
}

View File

@ -20,13 +20,13 @@ export function getOperationResponses(openApi: OpenApi, responses: OpenApiRespon
// if there is no typed data, we just return <any> so the user is still
// free to do their own casting if needed.
if (responseCode) {
const result: OperationResponse = {
code: responseCode,
text: response.description || '',
type: 'any',
base: 'any',
imports: [],
};
// const result: OperationResponse = {
// code: responseCode,
// text: response.description || '',
// type: 'any',
// base: 'any',
// imports: [],
// };
// If this response has a schema, then we need to check two things:
// if this is a reference then the parameter is just the 'name' of
@ -40,7 +40,7 @@ export function getOperationResponses(openApi: OpenApi, responses: OpenApiRespon
// result.imports.push(...responseSchema.imports);
}
results.push(result);
// results.push(result);
}
}
}

View File

@ -1,6 +1,7 @@
import { Service } from '../../../client/interfaces/Service';
import { OpenApi } from '../interfaces/OpenApi';
import { Method } from './constants';
import { getOperation } from './getOperation';
/**
* Get the OpenAPI services
@ -21,23 +22,23 @@ export function getServices(openApi: OpenApi): Map<string, Service> {
case Method.HEAD:
case Method.PATCH:
// Each method contains an OpenAPI operation, we parse the operation
// const op: OpenApiOperation = path[method]!;
// const operation: Operation = getOperation(openApi, url, method, op);
const op = path[method]!;
const operation = getOperation(openApi, url, method, op);
// If we have already declared a service, then we should fetch that and
// append the new method to it. Otherwise we should create a new service object.
// const service =
// services.get(operation.service) ||
// ({
// name: operation.service,
// operations: [],
// imports: [],
// } as Service);
const service =
services.get(operation.service) ||
({
name: operation.service,
operations: [],
imports: [],
} as Service);
// Push the operation in the service
// service.operations.push(operation);
// service.imports.push(...operation.imports);
// services.set(operation.service, service);
service.operations.push(operation);
service.imports.push(...operation.imports);
services.set(operation.service, service);
break;
}
}

View File

@ -1,12 +1,12 @@
{{~#if description}}
{{#if description}}
/**
* {{{description}}}
*/
{{~/if}}
{{/if}}
export type {{{name}}} = {{>type}}{{#if nullable}} | null{{/if}};
export namespace {{{name}}} {
{{#indent}}
export const schema = {{>validation}};
export async function validate(value: any): Promise<{{{name}}}{{#if nullable}} | null{{/if}}> {
@ -16,5 +16,4 @@ export namespace {{{name}}} {
export function validateSync(value: any): {{{name}}}{{#if nullable}} | null{{/if}} {
return schema.validateSync(value, { strict: true });
}
{{/indent}}
}

View File

@ -1,12 +1,12 @@
{{~#if description}}
{{#if description}}
/**
* {{{description}}}
*/
{{~/if}}
{{/if}}
export type {{{name}}} = {{>type}}{{#if nullable}} | null{{/if}};
export namespace {{{name}}} {
{{#indent}}
export const schema = {{>validation}};
export async function validate(value: any): Promise<{{{name}}}{{#if nullable}} | null{{/if}}> {
@ -16,5 +16,4 @@ export namespace {{{name}}} {
export function validateSync(value: any): {{{name}}}{{#if nullable}} | null{{/if}} {
return schema.validateSync(value, { strict: true });
}
{{/indent}}
}

View File

@ -1,16 +1,16 @@
{{~#if description}}
{{#if description}}
/**
* {{{description}}}
*/
{{~/if}}
{{/if}}
export enum {{{name}}} {
{{~#each enum}}
{{#each enum}}
{{{name}}} = {{{value}}},
{{~/each}}
{{/each}}
}
export namespace {{{name}}} {
{{#indent}}
export const schema = {{>validation}};
export async function validate(value: any): Promise<{{{name}}}> {
@ -20,5 +20,4 @@ export namespace {{{name}}} {
export function validateSync(value: any): {{{name}}} {
return schema.validateSync(value, { strict: true });
}
{{/indent}}
}

View File

@ -1,12 +1,12 @@
{{~#if description}}
{{#if description}}
/**
* {{{description}}}
*/
{{~/if}}
{{/if}}
export type {{{name}}} = {{>type}}{{#if nullable}} | null{{/if}};
export namespace {{{name}}} {
{{#indent}}
export const schema = {{>validation}};
export async function validate(value: any): Promise<{{{name}}}{{#if nullable}} | null{{/if}}> {
@ -16,5 +16,4 @@ export namespace {{{name}}} {
export function validateSync(value: any): {{{name}}}{{#if nullable}} | null{{/if}} {
return schema.validateSync(value, { strict: true });
}
{{/indent}}
}

View File

@ -1,47 +1,41 @@
{{~#if description}}
{{#if description}}
/**
* {{{description}}}
*/
{{~/if}}
export interface {{{name}}}{{{template}}}{{#if extends}} extends {{#each extends}}{{{this}}}{{#unless @last}}, {{/unless}}{{/each}}{{/if}} {
{{~#indent}}
{{~#each properties}}
{{~#if description}}
{{/if}}
export interface {{{name}}}{{#if extends}} extends {{#each extends}}{{{this}}}{{#unless @last}}, {{/unless}}{{/each}}{{/if}} {
{{#each properties}}
{{#if description}}
/**
* {{{description}}}
*/
{{~/if}}
{{#if readOnly}}readonly {{/if}}{{{name}}}{{#unless required}}?{{/unless}}: {{>type}}{{#if nullable}} | null{{/if}};
{{~/each}}
{{~/indent}}
{{/if}}
{{#if readOnly}}readonly {{/if}}{{{name}}}{{#unless required}}?{{/unless}}: {{>type parent=../name}}{{#if nullable}} | null{{/if}};
{{/each}}
}
export namespace {{{name}}} {
{{#indent}}
{{~#each enums}}
{{~#if description}}
{{#each enums}}
{{#if description}}
/**
* {{{description}}}
*/
{{~/if}}
{{/if}}
export enum {{{name}}} {
{{~#each values}}
{{#each enum}}
{{{name}}} = {{{value}}},
{{~/each}}
{{/each}}
}
{{/each}}
export const schema: yup.ObjectSchema<{{{name}}}{{{template}}}> = (
{{~#indent}}
{{>validation}}
{{~/indent}}
);
export async function validate(value: any): Promise<{{{name}}}{{{template}}}> {
{{/each}}
export const schema: yup.ObjectSchema<{{{name}}}> = {{>validation}};
export async function validate(value: any): Promise<{{{name}}}> {
return schema.validate(value, { strict: true });
}
export function validateSync(value: any): {{{name}}}{{{template}}} {
export function validateSync(value: any): {{{name}}} {
return schema.validateSync(value, { strict: true });
}
{{/indent}}
}

View File

@ -1,12 +1,12 @@
{{~#if description}}
{{#if description}}
/**
* {{{description}}}
*/
{{~/if}}
{{/if}}
export type {{{name}}} = {{>type}}{{#if nullable}} | null{{/if}};
export namespace {{{name}}} {
{{#indent}}
export const schema = {{>validation}};
export async function validate(value: any): Promise<{{{name}}}{{#if nullable}} | null{{/if}}> {
@ -16,5 +16,4 @@ export namespace {{{name}}} {
export function validateSync(value: any): {{{name}}}{{#if nullable}} | null{{/if}} {
return schema.validateSync(value, { strict: true });
}
{{/indent}}
}

View File

@ -7,12 +7,14 @@ export { ApiError } from './core/ApiError';
export { isSuccess } from './core/isSuccess';
export { OpenAPI } from './core/OpenAPI';
{{#if models}}
{{~#each models}}
{{#each models}}
export { {{{this}}} } from './models/{{{this}}}';
{{~/each}}
{{~/if}}
{{/each}}
{{/if}}
{{#if services}}
{{~#each services}}
{{#each services}}
export { {{{this}}} } from './services/{{{this}}}';
{{~/each}}
{{~/if}}
{{/each}}
{{/if}}

View File

@ -3,21 +3,23 @@
/* eslint-disable */
/* prettier-ignore */
{{#if imports}}
{{~#each imports}}
{{#each imports}}
import { {{{this}}} } from '../models/{{{this}}}';
{{~/each}}
{{~/if}}
{{/each}}
{{/if}}
import * as yup from 'yup';
{{#eq export 'reference'}}
{{~>exportReference}}
{{~else eq export 'generic'}}
{{~>exportGeneric}}
{{~else eq export 'enum'}}
{{~>exportEnum}}
{{~else eq export 'array'}}
{{~>exportArray}}
{{~else eq export 'dictionary'}}
{{~>exportDictionary}}
{{~else eq export 'interface'}}
{{~>exportInterface}}
{{~/eq}}
{{>exportReference}}
{{else eq export 'generic'}}
{{>exportGeneric}}
{{else eq export 'enum'}}
{{>exportEnum}}
{{else eq export 'array'}}
{{>exportArray}}
{{else eq export 'dictionary'}}
{{>exportDictionary}}
{{else eq export 'interface'}}
{{>exportInterface}}
{{/eq}}

View File

@ -3,10 +3,11 @@
/* eslint-disable */
/* prettier-ignore */
{{#if imports}}
{{~#each imports}}
{{#each imports}}
import { {{{this}}} } from '../models/{{{this}}}';
{{~/each}}
{{~/if}}
{{/each}}
{{/if}}
import { ApiError, catchGenericError } from '../core/ApiError';
import { request } from '../core/request';
import { isValidRequiredParam } from '../core/isValidRequiredParam';
@ -14,60 +15,60 @@ import { OpenAPI } from '../core/OpenAPI';
import { Result } from '../core/Result';
export class {{{name}}} {
{{~#each operations}}
{{#each operations}}
/**
{{~#if deprecated}}
{{#if deprecated}}
* @deprecated
{{~/if}}
{{~#if summary}}
{{/if}}
{{#if summary}}
* {{{summary}}}
{{~/if}}
{{~#if description}}
{{/if}}
{{#if description}}
* {{{description}}}
{{~/if}}
{{~#if parameters}}
{{~#each parameters}}
{{/if}}
{{#if parameters}}
{{#each parameters}}
* @param {{{name}}} {{{description}}}
{{~/each}}
{{~/if}}
{{/each}}
{{/if}}
*/
public static async {{{name}}}({{#each parameters}}{{{name}}}{{#unless required}}?{{/unless}}: {{{type}}}{{#if nullable}} | null{{/if}}{{#unless @last}}, {{/unless}}{{/each}}): Promise<{{{result}}}> {
{{#if parameters}}
{{~#each parameters}}
{{~#if required}}
{{#each parameters}}
{{#if required}}
isValidRequiredParam({{{name}}}, '{{{name}}}');
{{~/if}}
{{~/each}}
{{/if}}
{{/each}}
{{/if}}
const result = await request({
method: '{{{method}}}',
path: `{{{path}}}`,
{{~#if parametersHeader~}}
{{#if parametersHeader}}
headers: {
{{~#each parametersHeader}}
{{#each parametersHeader}}
'{{{prop}}}': {{{name}}},
{{~/each}}
{{/each}}
},
{{~/if}}
{{~#if parametersQuery}}
{{/if}}
{{#if parametersQuery}}
query: {
{{~#each parametersQuery}}
{{#each parametersQuery}}
'{{{prop}}}': {{{name}}},
{{~/each}}
{{/each}}
},
{{~/if}}
{{~#if parametersForm}}
{{/if}}
{{#if parametersForm}}
formData: {
{{~#each parametersForm}}
{{#each parametersForm}}
'{{{prop}}}': {{{name}}},
{{~/each}}
{{/each}}
},
{{~/if}}
{{~#if parametersBody}}
{{/if}}
{{#if parametersBody}}
body: {{{parametersBody.name}}},
{{~/if}}
{{/if}}
});
{{~#if errors}}
{{#if errors}}
if (!result.ok) {
switch (result.status) {
{{#each errors}}
@ -75,10 +76,10 @@ export class {{{name}}} {
{{/each}}
}
}
{{~/if}}
{{/if}}
catchGenericError(result);
return result.body;
}
{{~/each}}
{{/each}}
}

View File

@ -1,13 +1,13 @@
{{~#eq export 'reference'}}
{{~>typeForReference}}
{{~else eq export 'generic'}}
{{~>typeForGeneric}}
{{~else eq export 'enum'}}
{{~>typeForEnum}}
{{~else eq export 'array'}}
{{~>typeForArray}}
{{~else eq export 'dictionary'}}
{{~>typeForDictionary}}
{{~else eq export 'interface'}}
{{~>typeForInterface}}
{{~/eq}}
{{#eq export 'reference'}}
{{>typeForReference}}
{{else eq export 'generic'}}
{{>typeForGeneric}}
{{else eq export 'enum'}}
{{>typeForEnum}}
{{else eq export 'array'}}
{{>typeForArray}}
{{else eq export 'dictionary'}}
{{>typeForDictionary}}
{{else eq export 'interface'}}
{{>typeForInterface}}
{{/eq}}

View File

@ -1,5 +1,5 @@
{{~#if link~}}
Array<{{>type link}}>
Array<{{>type link child=true}}>
{{~else~}}
Array<{{{type}}}>
{{~/if~}}

View File

@ -1,5 +1,5 @@
{{~#if link~}}
Dictionary<{{>type link}}>
Dictionary<{{>type link child=true}}>
{{~else~}}
Dictionary<{{{type}}}>
{{~/if~}}

View File

@ -1 +1,5 @@
any
{{~#if parent~}}
{{{parent}}}.{{{name}}}
{{~else~}}
{{{type}}}
{{~/if~}}

View File

@ -1,12 +1,14 @@
{{~#if properties~}}
{
{{#indent}}
{{~#each properties}}
{{~#if description}}
/**
* {{{description}}}
*/
{{~/if}}
{{#if readOnly}}readonly {{/if}}{{{name}}}{{#unless required}}?{{/unless}}: {{>type}}{{#if nullable}} | null{{/if}},
{{~/each}}
{{/indent}}
{{#each properties}}
{{#if description}}
/**
* {{{description}}}
*/
{{/if}}
{{#if readOnly}}readonly {{/if}}{{{name}}}{{#unless required}}?{{/unless}}: {{>type child=true}}{{#if nullable}} | null{{/if}},
{{/each}}
}
{{else~}}
any
{{~/if~}}

View File

@ -1,13 +1,13 @@
{{~#eq export 'reference'~}}
{{#eq export 'reference'}}
{{>validationForReference}}
{{~else eq export 'generic'~}}
{{else eq export 'generic'}}
{{>validationForGeneric}}
{{~else eq export 'enum'~}}
{{else eq export 'enum'}}
{{>validationForEnum}}
{{~else eq export 'array'~}}
{{else eq export 'array'}}
{{>validationForArray}}
{{~else eq export 'dictionary'~}}
{{else eq export 'dictionary'}}
{{>validationForDictionary}}
{{~else eq export 'interface'~}}
{{else eq export 'interface'}}
{{>validationForInterface}}
{{~/eq~}}
{{/eq}}

View File

@ -1,5 +1,5 @@
{{~#if link~}}
yup.array<{{>type link}}>().of({{>validation link}})
yup.array<{{>type link child=true}}>().of({{>validation link child=true}})
{{~else~}}
yup.array<{{{type}}}>().of({{{base}}}.schema)
{{~/if~}}

View File

@ -1,31 +1,19 @@
{{~#if link}}
yup.lazy<Dictionary<{{>type link}}>>(value =>
{{#indent}}
yup.object<Dictionary<{{>type link}}>>().shape(
{{#indent}}
{{~#if link~}}
yup.lazy<Dictionary<{{>type link child=true}}>>(value => {
return yup.object<Dictionary<{{>type link child=true}}>>().shape(
Object.entries(value).reduce((obj, item) => ({
{{#indent}}
...obj,
[item[0]]: {{>validation link}},
{{/indent}}
[item[0]]: {{>validation link child=true}},
}), {})
{{/indent}}
)
{{/indent}}
)
{{~else}}
yup.lazy<Dictionary<{{{type}}}>>(value =>
{{#indent}}
yup.object<Dictionary<{{{type}}}>>().shape(
{{#indent}}
);
})
{{~else~}}
yup.lazy<Dictionary<{{{type}}}>>(value => {
return yup.object<Dictionary<{{{type}}}>>().shape(
Object.entries(value).reduce((obj, item) => ({
{{#indent}}
...obj,
[item[0]]: {{{base}}}.schema,
{{/indent}}
}), {})
{{/indent}}
)
{{/indent}}
)
{{~/if}}
);
})
{{~/if~}}

View File

@ -1,9 +1,9 @@
yup.mixed{{#if name}}<{{{name}}}>{{/if}}().oneOf([
{{~#each enum}}
{{~#if ../name}}
yup.mixed<{{{name}}}>().oneOf([
{{#each enum}}
{{#unless child}}
{{{../name}}}.{{{name}}},
{{~else}}
{{else}}
{{{value}}},
{{~/if}}
{{~/each}}
{{/unless}}
{{/each}}
])

View File

@ -1,17 +1,21 @@
{{~#if extends}}
{{~#each extends}}
(
{{#if extends}}
{{#each extends}}
{{{this}}}.schema.concat(
{{~/each}}
{{~/if}}
yup.object{{#if name}}<{{{name}}}>{{/if}}().shape({
{{#indent}}
{{~#each properties}}
{{{name}}}: yup.lazy(() => {{>validation}}.default(undefined)){{#if required}}.required(){{/if}}{{#if nullable}}.nullable(){{/if}},
{{~/each}}
{{/indent}}
{{/each}}
{{/if}}
{{#if properties}}
yup.object{{#unless child}}<{{{name}}}>{{/unless}}().shape({
{{#each properties}}
{{{name}}}: yup.lazy(() => {{>validation child=true}}.default(undefined){{#if required}}.required(){{/if}}{{#if nullable}}.nullable(){{/if}}),
{{/each}}
}).noUnknown()
{{~#if extends}}
{{~#each extends}}
{{else}}
yup.object<any>()
{{/if}}
{{#if extends}}
{{#each extends}}
)
{{/each}}
{{/if}}
)
{{~/each}}
{{~/if}}

View File

@ -1,10 +0,0 @@
// Replace " /**/}" with "}"
// Replace " /**/)" with ")"
// Replace " /**/]" with "]"
export function fixIndentation(s: string): string {
return s
.replace(/\s{4}\/\*\*\/\}/g, '}')
.replace(/\s{4}\/\*\*\/\)/g, ')')
.replace(/\s{4}\/\*\*\/\]/g, ']');
}

19
src/utils/format.ts Normal file
View File

@ -0,0 +1,19 @@
import { EOL } from 'os';
export function format(s: string): string {
let indent: number = 0;
let lines = s.split(EOL);
lines = lines.map(line => {
line = line.trim().replace(/^\*/g, ' *');
let i = indent;
if (line.endsWith('(') || line.endsWith('{') || line.endsWith('[')) {
indent++;
}
if (line.startsWith(')') || line.startsWith('}') || line.startsWith(']')) {
indent--;
i--;
}
return `${' '.repeat(i)}${line}`;
});
return lines.join(EOL);
}

View File

@ -16,7 +16,6 @@ export function readHandlebarsTemplate(filePath: string): Handlebars.TemplateDel
strict: true,
noEscape: true,
preventIndent: true,
ignoreStandalone: true,
knownHelpersOnly: true,
knownHelpers: {
indent: true,

View File

@ -1,22 +1,7 @@
import * as Handlebars from 'handlebars';
import {EOL} from 'os';
export function registerHandlebarHelpers(): void {
Handlebars.registerHelper('indent', function (options: Handlebars.HelperOptions): string {
// eslint-disable
// prettier-ignore
// @ts-ignore
return options.fn(this)
.split(EOL)
.map(line => line.replace(/^\s{4}/g, ''))
.map(line => `/**/${line}`)
.join(EOL);
});
Handlebars.registerHelper('eq', function (a: string, b: string, options: Handlebars.HelperOptions): string {
// eslint-disable
// prettier-ignore
Handlebars.registerHelper('eq', function(a: string, b: string, options: Handlebars.HelperOptions): string {
// @ts-ignore
return a === b ? options.fn(this) : options.inverse(this);
});

View File

@ -1,12 +1,12 @@
import {writeClientModels} from './writeClientModels';
import {writeClientServices} from './writeClientServices';
import {Client} from '../client/interfaces/Client';
import { writeClientModels } from './writeClientModels';
import { writeClientServices } from './writeClientServices';
import { Client } from '../client/interfaces/Client';
import * as path from 'path';
import * as mkdirp from 'mkdirp';
import * as rimraf from 'rimraf';
import {Templates} from './readHandlebarsTemplates';
import {writeClientIndex} from './writeClientIndex';
import {Language} from '../index';
import { Templates } from './readHandlebarsTemplates';
import { writeClientIndex } from './writeClientIndex';
import { Language } from '../index';
import * as fs from 'fs';
import * as glob from 'glob';
@ -41,7 +41,7 @@ export function writeClient(client: Client, language: Language, templates: Templ
// Copy all support files
const supportFiles = path.resolve(__dirname, `../../src/templates/${language}/`);
const supportFilesList = glob.sync('**/*.{ts,js}', {cwd: supportFiles});
const supportFilesList = glob.sync('**/*.{ts,js}', { cwd: supportFiles });
supportFilesList.forEach(file =>
fs.copyFileSync(
path.resolve(supportFiles, file), // From input path

View File

@ -5,7 +5,7 @@ import { Language } from '../index';
import { getFileName } from './getFileName';
import { exportModel } from './exportModel';
import { Templates } from './readHandlebarsTemplates';
import { fixIndentation } from './fixIndentation';
import { format } from './format';
/**
* Generate Models using the Handlebar template and write to disk.
@ -20,7 +20,7 @@ export function writeClientModels(models: Map<string, Model>, language: Language
try {
const templateData = exportModel(model);
const templateResult = templates.model(templateData);
fs.writeFileSync(path.resolve(outputPath, fileName), fixIndentation(templateResult));
fs.writeFileSync(path.resolve(outputPath, fileName), format(templateResult));
} catch (e) {
throw new Error(`Could not write model: "${fileName}"`);
}

View File

@ -5,7 +5,7 @@ import { Language } from '../index';
import { getFileName } from './getFileName';
import { exportService } from './exportService';
import { Templates } from './readHandlebarsTemplates';
import { fixIndentation } from './fixIndentation';
import { format } from './format';
/**
* Generate Services using the Handlebar template and write to disk.
@ -20,7 +20,7 @@ export function writeClientServices(services: Map<string, Service>, language: La
try {
const templateData = exportService(service);
const templateResult = templates.model(templateData);
fs.writeFileSync(path.resolve(outputPath, fileName), fixIndentation(templateResult));
fs.writeFileSync(path.resolve(outputPath, fileName), format(templateResult));
} catch (e) {
throw new Error(`Could not write service: "${fileName}"`);
}

View File

@ -6,7 +6,7 @@ const OpenAPI = require('../dist');
OpenAPI.generate(
'./test/mock/v2/spec.json',
'./test/tmp/v2/spec',
'./test/tmp/v2/ts/spec',
OpenAPI.Language.TYPESCRIPT,
OpenAPI.HttpClient.FETCH,
);
@ -25,16 +25,16 @@ OpenAPI.generate(
// OpenAPI.HttpClient.FETCH,
// );
//
// OpenAPI.generate(
// './test/mock/v2/test-sites.json',
// './test/tmp/v2/ts/test-sites',
// OpenAPI.Language.TYPESCRIPT,
// OpenAPI.HttpClient.FETCH,
// );
OpenAPI.generate(
'./test/mock/v2/test-sites.json',
'./test/tmp/v2/ts/test-sites',
OpenAPI.Language.TYPESCRIPT,
OpenAPI.HttpClient.FETCH,
);
//
// OpenAPI.generate(
// './test/mock/v2/test-petstore.yaml',
// './test/tmp/v2/test-petstore-yaml',
// './test/tmp/v2/ts/test-petstore-yaml',
// OpenAPI.Language.TYPESCRIPT,
// OpenAPI.HttpClient.FETCH,
// );

View File

@ -188,7 +188,7 @@
"description": "This is a model with one enum",
"type": "object",
"properties": {
"prop": {
"Test": {
"description": "This is a simple enum with strings",
"enum": [
"Success",
@ -202,7 +202,7 @@
"description": "This is a model with one enum",
"type": "object",
"properties": {
"prop": {
"Test": {
"type": "integer",
"description": "Success=1,Warning=2,Error=3"
}