mirror of
https://github.com/ferdikoomen/openapi-typescript-codegen.git
synced 2025-12-08 20:16:21 +00:00
- Moved to const definitions for functions
This commit is contained in:
parent
c6c9d2b879
commit
280d196f99
@ -36,6 +36,7 @@ const handlebarsPlugin = () => ({
|
||||
enumerator: true,
|
||||
escapeComment: true,
|
||||
escapeDescription: true,
|
||||
camelCase: true,
|
||||
},
|
||||
});
|
||||
return `export default ${templateSpec};`;
|
||||
|
||||
@ -48,7 +48,7 @@ export type Options = {
|
||||
* @param request: Path to custom request file
|
||||
* @param write Write the files to disk (true or false)
|
||||
*/
|
||||
export async function generate({
|
||||
export const generate = async ({
|
||||
input,
|
||||
output,
|
||||
httpClient = HttpClient.FETCH,
|
||||
@ -63,7 +63,7 @@ export async function generate({
|
||||
postfix = 'Service',
|
||||
request,
|
||||
write = true,
|
||||
}: Options): Promise<void> {
|
||||
}: Options): Promise<void> => {
|
||||
const openApi = isString(input) ? await getOpenApiSpec(input) : input;
|
||||
const openApiVersion = getOpenApiVersion(openApi);
|
||||
const templates = registerHandlebarTemplates({
|
||||
@ -119,7 +119,7 @@ export async function generate({
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export default {
|
||||
HttpClient,
|
||||
|
||||
@ -10,11 +10,11 @@ import { getServiceVersion } from './parser/getServiceVersion';
|
||||
* all the models, services and schema's we should output.
|
||||
* @param openApi The OpenAPI spec that we have loaded from disk.
|
||||
*/
|
||||
export function parse(openApi: OpenApi): Client {
|
||||
export const parse = (openApi: OpenApi): Client => {
|
||||
const version = getServiceVersion(openApi.info.version);
|
||||
const server = getServer(openApi);
|
||||
const models = getModels(openApi);
|
||||
const services = getServices(openApi);
|
||||
|
||||
return { version, server, models, services };
|
||||
}
|
||||
};
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
export function escapeName(value: string): string {
|
||||
export const escapeName = (value: string): string => {
|
||||
if (value) {
|
||||
const validName = /^[a-zA-Z_$][\w$]+$/g.test(value);
|
||||
if (!validName) {
|
||||
@ -6,4 +6,4 @@ export function escapeName(value: string): string {
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
};
|
||||
|
||||
@ -7,7 +7,7 @@ import type { WithEnumExtension } from '../interfaces/Extensions/WithEnumExtensi
|
||||
* @param enumerators
|
||||
* @param definition
|
||||
*/
|
||||
export function extendEnum(enumerators: Enum[], definition: WithEnumExtension): Enum[] {
|
||||
export const extendEnum = (enumerators: Enum[], definition: WithEnumExtension): Enum[] => {
|
||||
const names = definition['x-enum-varnames'];
|
||||
const descriptions = definition['x-enum-descriptions'];
|
||||
|
||||
@ -17,4 +17,4 @@ export function extendEnum(enumerators: Enum[], definition: WithEnumExtension):
|
||||
value: enumerator.value,
|
||||
type: enumerator.type,
|
||||
}));
|
||||
}
|
||||
};
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import type { Enum } from '../../../client/interfaces/Enum';
|
||||
import { isDefined } from '../../../utils/isDefined';
|
||||
|
||||
export function getEnum(values?: (string | number)[]): Enum[] {
|
||||
export const getEnum = (values?: (string | number)[]): Enum[] => {
|
||||
if (Array.isArray(values)) {
|
||||
return values
|
||||
.filter((value, index, arr) => {
|
||||
@ -30,4 +30,4 @@ export function getEnum(values?: (string | number)[]): Enum[] {
|
||||
});
|
||||
}
|
||||
return [];
|
||||
}
|
||||
};
|
||||
|
||||
@ -3,7 +3,7 @@ import type { Enum } from '../../../client/interfaces/Enum';
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
export function getEnumFromDescription(description: string): Enum[] {
|
||||
export const getEnumFromDescription = (description: string): Enum[] => {
|
||||
// Check if we can find this special format string:
|
||||
// None=0,Something=1,AnotherThing=2
|
||||
if (/^(\w+=[0-9]+)/g.test(description)) {
|
||||
@ -36,4 +36,4 @@ export function getEnumFromDescription(description: string): Enum[] {
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
};
|
||||
|
||||
@ -24,9 +24,9 @@ const TYPE_MAPPINGS = new Map<string, string>([
|
||||
/**
|
||||
* Get mapped type for given type to any basic Typescript/Javascript type.
|
||||
*/
|
||||
export function getMappedType(type: string, format?: string): string | undefined {
|
||||
export const getMappedType = (type: string, format?: string): string | undefined => {
|
||||
if (format === 'binary') {
|
||||
return 'binary';
|
||||
}
|
||||
return TYPE_MAPPINGS.get(type);
|
||||
}
|
||||
};
|
||||
|
||||
@ -9,12 +9,12 @@ import { getModelComposition } from './getModelComposition';
|
||||
import { getModelProperties } from './getModelProperties';
|
||||
import { getType } from './getType';
|
||||
|
||||
export function getModel(
|
||||
export const getModel = (
|
||||
openApi: OpenApi,
|
||||
definition: OpenApiSchema,
|
||||
isDefinition: boolean = false,
|
||||
name: string = ''
|
||||
): Model {
|
||||
): Model => {
|
||||
const model: Model = {
|
||||
name,
|
||||
export: 'interface',
|
||||
@ -162,4 +162,4 @@ export function getModel(
|
||||
}
|
||||
|
||||
return model;
|
||||
}
|
||||
};
|
||||
|
||||
@ -9,13 +9,13 @@ import { getRequiredPropertiesFromComposition } from './getRequiredPropertiesFro
|
||||
// Fix for circular dependency
|
||||
export type GetModelFn = typeof getModel;
|
||||
|
||||
export function getModelComposition(
|
||||
export const getModelComposition = (
|
||||
openApi: OpenApi,
|
||||
definition: OpenApiSchema,
|
||||
definitions: OpenApiSchema[],
|
||||
type: 'one-of' | 'any-of' | 'all-of',
|
||||
getModel: GetModelFn
|
||||
): ModelComposition {
|
||||
): ModelComposition => {
|
||||
const composition: ModelComposition = {
|
||||
type,
|
||||
imports: [],
|
||||
@ -87,4 +87,4 @@ export function getModelComposition(
|
||||
}
|
||||
|
||||
return composition;
|
||||
}
|
||||
};
|
||||
|
||||
@ -9,7 +9,7 @@ import { getType } from './getType';
|
||||
// Fix for circular dependency
|
||||
export type GetModelFn = typeof getModel;
|
||||
|
||||
export function getModelProperties(openApi: OpenApi, definition: OpenApiSchema, getModel: GetModelFn): Model[] {
|
||||
export const getModelProperties = (openApi: OpenApi, definition: OpenApiSchema, getModel: GetModelFn): Model[] => {
|
||||
const models: Model[] = [];
|
||||
for (const propertyName in definition.properties) {
|
||||
if (definition.properties.hasOwnProperty(propertyName)) {
|
||||
@ -85,4 +85,4 @@ export function getModelProperties(openApi: OpenApi, definition: OpenApiSchema,
|
||||
}
|
||||
}
|
||||
return models;
|
||||
}
|
||||
};
|
||||
|
||||
@ -6,6 +6,6 @@ import type { Type } from '../../../client/interfaces/Type';
|
||||
* @param modelClass The parsed model class type.
|
||||
* @returns The model template type (<T> or empty).
|
||||
*/
|
||||
export function getModelTemplate(modelClass: Type): string {
|
||||
export const getModelTemplate = (modelClass: Type): string => {
|
||||
return modelClass.template ? '<T>' : '';
|
||||
}
|
||||
};
|
||||
|
||||
@ -3,7 +3,7 @@ import type { OpenApi } from '../interfaces/OpenApi';
|
||||
import { getModel } from './getModel';
|
||||
import { getType } from './getType';
|
||||
|
||||
export function getModels(openApi: OpenApi): Model[] {
|
||||
export const getModels = (openApi: OpenApi): Model[] => {
|
||||
const models: Model[] = [];
|
||||
for (const definitionName in openApi.definitions) {
|
||||
if (openApi.definitions.hasOwnProperty(definitionName)) {
|
||||
@ -14,4 +14,4 @@ export function getModels(openApi: OpenApi): Model[] {
|
||||
}
|
||||
}
|
||||
return models;
|
||||
}
|
||||
};
|
||||
|
||||
@ -12,17 +12,16 @@ import { getOperationResults } from './getOperationResults';
|
||||
import { getServiceName } from './getServiceName';
|
||||
import { sortByRequired } from './sortByRequired';
|
||||
|
||||
export function getOperation(
|
||||
export const getOperation = (
|
||||
openApi: OpenApi,
|
||||
url: string,
|
||||
method: string,
|
||||
tag: string,
|
||||
op: OpenApiOperation,
|
||||
pathParams: OperationParameters
|
||||
): Operation {
|
||||
): Operation => {
|
||||
const serviceName = getServiceName(tag);
|
||||
const operationNameFallback = `${method}${serviceName}`;
|
||||
const operationName = getOperationName(op.operationId || operationNameFallback);
|
||||
const operationName = getOperationName(op.operationId || `${method}`);
|
||||
const operationPath = getOperationPath(url);
|
||||
|
||||
// Create a new operation object for this method.
|
||||
@ -76,4 +75,4 @@ export function getOperation(
|
||||
operation.parameters = operation.parameters.sort(sortByRequired);
|
||||
|
||||
return operation;
|
||||
}
|
||||
};
|
||||
|
||||
@ -5,7 +5,7 @@ import type { OperationResponse } from '../../../client/interfaces/OperationResp
|
||||
*
|
||||
* @param operationResponses
|
||||
*/
|
||||
export function getOperationErrors(operationResponses: OperationResponse[]): OperationError[] {
|
||||
export const getOperationErrors = (operationResponses: OperationResponse[]): OperationError[] => {
|
||||
return operationResponses
|
||||
.filter(operationResponse => {
|
||||
return operationResponse.code >= 300 && operationResponse.description;
|
||||
@ -14,4 +14,4 @@ export function getOperationErrors(operationResponses: OperationResponse[]): Ope
|
||||
code: response.code,
|
||||
description: response.description!,
|
||||
}));
|
||||
}
|
||||
};
|
||||
|
||||
@ -5,10 +5,10 @@ import camelCase from 'camelcase';
|
||||
* This converts the input string to camelCase, so the method name follows
|
||||
* the most popular Javascript and Typescript writing style.
|
||||
*/
|
||||
export function getOperationName(value: string): string {
|
||||
export const getOperationName = (value: string): string => {
|
||||
const clean = value
|
||||
.replace(/^[^a-zA-Z]+/g, '')
|
||||
.replace(/[^\w\-]+/g, '-')
|
||||
.trim();
|
||||
return camelCase(clean);
|
||||
}
|
||||
};
|
||||
|
||||
@ -12,7 +12,7 @@ import { getOperationParameterName } from './getOperationParameterName';
|
||||
import { getRef } from './getRef';
|
||||
import { getType } from './getType';
|
||||
|
||||
export function getOperationParameter(openApi: OpenApi, parameter: OpenApiParameter): OperationParameter {
|
||||
export const getOperationParameter = (openApi: OpenApi, parameter: OpenApiParameter): OperationParameter => {
|
||||
const operationParameter: OperationParameter = {
|
||||
in: parameter.in,
|
||||
prop: parameter.name,
|
||||
@ -147,4 +147,4 @@ export function getOperationParameter(openApi: OpenApi, parameter: OpenApiParame
|
||||
}
|
||||
|
||||
return operationParameter;
|
||||
}
|
||||
};
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
import type { OperationParameter } from '../../../client/interfaces/OperationParameter';
|
||||
import type { OpenApiParameter } from '../interfaces/OpenApiParameter';
|
||||
|
||||
export function getOperationParameterDefault(
|
||||
export const getOperationParameterDefault = (
|
||||
parameter: OpenApiParameter,
|
||||
operationParameter: OperationParameter
|
||||
): string | undefined {
|
||||
): string | undefined => {
|
||||
if (parameter.default === undefined) {
|
||||
return;
|
||||
}
|
||||
@ -39,4 +39,4 @@ export function getOperationParameterDefault(
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
@ -7,10 +7,10 @@ const reservedWords =
|
||||
* Replaces any invalid characters from a parameter name.
|
||||
* For example: 'filter.someProperty' becomes 'filterSomeProperty'.
|
||||
*/
|
||||
export function getOperationParameterName(value: string): string {
|
||||
export const getOperationParameterName = (value: string): string => {
|
||||
const clean = value
|
||||
.replace(/^[^a-zA-Z]+/g, '')
|
||||
.replace(/[^\w\-]+/g, '-')
|
||||
.trim();
|
||||
return camelCase(clean).replace(reservedWords, '_$1');
|
||||
}
|
||||
};
|
||||
|
||||
@ -4,7 +4,7 @@ import type { OpenApiParameter } from '../interfaces/OpenApiParameter';
|
||||
import { getOperationParameter } from './getOperationParameter';
|
||||
import { getRef } from './getRef';
|
||||
|
||||
export function getOperationParameters(openApi: OpenApi, parameters: OpenApiParameter[]): OperationParameters {
|
||||
export const getOperationParameters = (openApi: OpenApi, parameters: OpenApiParameter[]): OperationParameters => {
|
||||
const operationParameters: OperationParameters = {
|
||||
imports: [],
|
||||
parameters: [],
|
||||
@ -58,4 +58,4 @@ export function getOperationParameters(openApi: OpenApi, parameters: OpenApiPara
|
||||
}
|
||||
});
|
||||
return operationParameters;
|
||||
}
|
||||
};
|
||||
|
||||
@ -7,10 +7,10 @@ import { getOperationParameterName } from './getOperationParameterName';
|
||||
* Plus we return the correct parameter names to replace in the URL.
|
||||
* @param path
|
||||
*/
|
||||
export function getOperationPath(path: string): string {
|
||||
export const getOperationPath = (path: string): string => {
|
||||
return path
|
||||
.replace(/\{(.*?)\}/g, (_, w: string) => {
|
||||
return `\${${getOperationParameterName(w)}}`;
|
||||
})
|
||||
.replace('${apiVersion}', '${OpenAPI.VERSION}');
|
||||
}
|
||||
};
|
||||
|
||||
@ -7,11 +7,11 @@ import { getModel } from './getModel';
|
||||
import { getRef } from './getRef';
|
||||
import { getType } from './getType';
|
||||
|
||||
export function getOperationResponse(
|
||||
export const getOperationResponse = (
|
||||
openApi: OpenApi,
|
||||
response: OpenApiResponse,
|
||||
responseCode: number
|
||||
): OperationResponse {
|
||||
): OperationResponse => {
|
||||
const operationResponse: OperationResponse = {
|
||||
in: 'response',
|
||||
name: '',
|
||||
@ -96,4 +96,4 @@ export function getOperationResponse(
|
||||
}
|
||||
|
||||
return operationResponse;
|
||||
}
|
||||
};
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
export function getOperationResponseCode(value: string | 'default'): number | null {
|
||||
export const getOperationResponseCode = (value: string | 'default'): number | null => {
|
||||
// You can specify a "default" response, this is treated as HTTP code 200
|
||||
if (value === 'default') {
|
||||
return 200;
|
||||
@ -13,4 +13,4 @@ export function getOperationResponseCode(value: string | 'default'): number | nu
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import type { OperationResponse } from '../../../client/interfaces/OperationResponse';
|
||||
|
||||
export function getOperationResponseHeader(operationResponses: OperationResponse[]): string | null {
|
||||
export const getOperationResponseHeader = (operationResponses: OperationResponse[]): string | null => {
|
||||
const header = operationResponses.find(operationResponses => {
|
||||
return operationResponses.in === 'header';
|
||||
});
|
||||
@ -8,4 +8,4 @@ export function getOperationResponseHeader(operationResponses: OperationResponse
|
||||
return header.name;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
@ -6,7 +6,7 @@ import { getOperationResponse } from './getOperationResponse';
|
||||
import { getOperationResponseCode } from './getOperationResponseCode';
|
||||
import { getRef } from './getRef';
|
||||
|
||||
export function getOperationResponses(openApi: OpenApi, responses: OpenApiResponses): OperationResponse[] {
|
||||
export const getOperationResponses = (openApi: OpenApi, responses: OpenApiResponses): OperationResponse[] => {
|
||||
const operationResponses: OperationResponse[] = [];
|
||||
|
||||
// Iterate over each response code and get the
|
||||
@ -28,4 +28,4 @@ export function getOperationResponses(openApi: OpenApi, responses: OpenApiRespon
|
||||
return operationResponses.sort((a, b): number => {
|
||||
return a.code < b.code ? -1 : a.code > b.code ? 1 : 0;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
@ -1,15 +1,15 @@
|
||||
import type { Model } from '../../../client/interfaces/Model';
|
||||
import type { OperationResponse } from '../../../client/interfaces/OperationResponse';
|
||||
|
||||
function areEqual(a: Model, b: Model): boolean {
|
||||
const areEqual = (a: Model, b: Model): boolean => {
|
||||
const equal = a.type === b.type && a.base === b.base && a.template === b.template;
|
||||
if (equal && a.link && b.link) {
|
||||
return areEqual(a.link, b.link);
|
||||
}
|
||||
return equal;
|
||||
}
|
||||
};
|
||||
|
||||
export function getOperationResults(operationResponses: OperationResponse[]): OperationResponse[] {
|
||||
export const getOperationResults = (operationResponses: OperationResponse[]): OperationResponse[] => {
|
||||
const operationResults: OperationResponse[] = [];
|
||||
|
||||
// Filter out success response codes, but skip "204 No Content"
|
||||
@ -49,4 +49,4 @@ export function getOperationResults(operationResponses: OperationResponse[]): Op
|
||||
}) === index
|
||||
);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
@ -4,7 +4,7 @@ import type { OpenApiReference } from '../interfaces/OpenApiReference';
|
||||
const ESCAPED_REF_SLASH = /~1/g;
|
||||
const ESCAPED_REF_TILDE = /~0/g;
|
||||
|
||||
export function getRef<T>(openApi: OpenApi, item: T & OpenApiReference): T {
|
||||
export const getRef = <T>(openApi: OpenApi, item: T & OpenApiReference): T => {
|
||||
if (item.$ref) {
|
||||
// Fetch the paths to the definitions, this converts:
|
||||
// "#/definitions/Form" to ["definitions", "Form"]
|
||||
@ -29,4 +29,4 @@ export function getRef<T>(openApi: OpenApi, item: T & OpenApiReference): T {
|
||||
return result as T;
|
||||
}
|
||||
return item as T;
|
||||
}
|
||||
};
|
||||
|
||||
@ -7,12 +7,12 @@ import { getRef } from './getRef';
|
||||
// Fix for circular dependency
|
||||
export type GetModelFn = typeof getModel;
|
||||
|
||||
export function getRequiredPropertiesFromComposition(
|
||||
export const getRequiredPropertiesFromComposition = (
|
||||
openApi: OpenApi,
|
||||
required: string[],
|
||||
definitions: OpenApiSchema[],
|
||||
getModel: GetModelFn
|
||||
): Model[] {
|
||||
): Model[] => {
|
||||
return definitions
|
||||
.reduce((properties, definition) => {
|
||||
if (definition.$ref) {
|
||||
@ -30,4 +30,4 @@ export function getRequiredPropertiesFromComposition(
|
||||
isRequired: true,
|
||||
};
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
@ -4,10 +4,10 @@ import type { OpenApi } from '../interfaces/OpenApi';
|
||||
* Get the base server url.
|
||||
* @param openApi
|
||||
*/
|
||||
export function getServer(openApi: OpenApi): string {
|
||||
export const getServer = (openApi: OpenApi): string => {
|
||||
const scheme = openApi.schemes?.[0] || 'http';
|
||||
const host = openApi.host;
|
||||
const basePath = openApi.basePath || '';
|
||||
const url = host ? `${scheme}://${host}${basePath}` : basePath;
|
||||
return url.replace(/\/$/g, '');
|
||||
}
|
||||
};
|
||||
|
||||
@ -4,10 +4,10 @@ import camelCase from 'camelcase';
|
||||
* Convert the input value to a correct service name. This converts
|
||||
* the input string to PascalCase.
|
||||
*/
|
||||
export function getServiceName(value: string): string {
|
||||
export const getServiceName = (value: string): string => {
|
||||
const clean = value
|
||||
.replace(/^[^a-zA-Z]+/g, '')
|
||||
.replace(/[^\w\-]+/g, '-')
|
||||
.trim();
|
||||
return camelCase(clean, { pascalCase: true });
|
||||
}
|
||||
};
|
||||
|
||||
@ -3,6 +3,6 @@
|
||||
* This basically removes any "v" prefix from the version string.
|
||||
* @param version
|
||||
*/
|
||||
export function getServiceVersion(version = '1.0'): string {
|
||||
export const getServiceVersion = (version = '1.0'): string => {
|
||||
return String(version).replace(/^v/gi, '');
|
||||
}
|
||||
};
|
||||
|
||||
@ -7,7 +7,7 @@ import { getOperationParameters } from './getOperationParameters';
|
||||
/**
|
||||
* Get the OpenAPI services
|
||||
*/
|
||||
export function getServices(openApi: OpenApi): Service[] {
|
||||
export const getServices = (openApi: OpenApi): Service[] => {
|
||||
const services = new Map<string, Service>();
|
||||
for (const url in openApi.paths) {
|
||||
if (openApi.paths.hasOwnProperty(url)) {
|
||||
@ -28,7 +28,7 @@ export function getServices(openApi: OpenApi): Service[] {
|
||||
case 'patch':
|
||||
// Each method contains an OpenAPI operation, we parse the operation
|
||||
const op = path[method]!;
|
||||
const tags = op.tags?.length ? op.tags.filter(unique) : [''];
|
||||
const tags = op.tags?.length ? op.tags.filter(unique) : ['Default'];
|
||||
tags.forEach(tag => {
|
||||
const operation = getOperation(openApi, url, method, tag, op, pathParams);
|
||||
|
||||
@ -52,4 +52,4 @@ export function getServices(openApi: OpenApi): Service[] {
|
||||
}
|
||||
}
|
||||
return Array.from(services.values());
|
||||
}
|
||||
};
|
||||
|
||||
@ -2,16 +2,16 @@ import type { Type } from '../../../client/interfaces/Type';
|
||||
import { getMappedType } from './getMappedType';
|
||||
import { stripNamespace } from './stripNamespace';
|
||||
|
||||
function encode(value: string): string {
|
||||
const encode = (value: string): string => {
|
||||
return value.replace(/^[^a-zA-Z_$]+/g, '').replace(/[^\w$]+/g, '_');
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Parse any string value into a type object.
|
||||
* @param type String value like "integer" or "Link[Model]".
|
||||
* @param format String value like "binary" or "date".
|
||||
*/
|
||||
export function getType(type: string = 'any', format?: string): Type {
|
||||
export const getType = (type: string = 'any', format?: string): Type => {
|
||||
const result: Type = {
|
||||
type: 'any',
|
||||
base: 'any',
|
||||
@ -64,4 +64,4 @@ export function getType(type: string = 'any', format?: string): Type {
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
import type { OperationParameter } from '../../../client/interfaces/OperationParameter';
|
||||
|
||||
export function sortByRequired(a: OperationParameter, b: OperationParameter): number {
|
||||
export const sortByRequired = (a: OperationParameter, b: OperationParameter): number => {
|
||||
const aNeedsValue = a.isRequired && a.default === undefined;
|
||||
const bNeedsValue = b.isRequired && b.default === undefined;
|
||||
if (aNeedsValue && !bNeedsValue) return -1;
|
||||
if (bNeedsValue && !aNeedsValue) return 1;
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
@ -2,11 +2,11 @@
|
||||
* Strip (OpenAPI) namespaces fom values.
|
||||
* @param value
|
||||
*/
|
||||
export function stripNamespace(value: string): string {
|
||||
export const stripNamespace = (value: string): string => {
|
||||
return value
|
||||
.trim()
|
||||
.replace(/^#\/definitions\//, '')
|
||||
.replace(/^#\/parameters\//, '')
|
||||
.replace(/^#\/responses\//, '')
|
||||
.replace(/^#\/securityDefinitions\//, '');
|
||||
}
|
||||
};
|
||||
|
||||
@ -10,11 +10,11 @@ import { getServiceVersion } from './parser/getServiceVersion';
|
||||
* all the models, services and schema's we should output.
|
||||
* @param openApi The OpenAPI spec that we have loaded from disk.
|
||||
*/
|
||||
export function parse(openApi: OpenApi): Client {
|
||||
export const parse = (openApi: OpenApi): Client => {
|
||||
const version = getServiceVersion(openApi.info.version);
|
||||
const server = getServer(openApi);
|
||||
const models = getModels(openApi);
|
||||
const services = getServices(openApi);
|
||||
|
||||
return { version, server, models, services };
|
||||
}
|
||||
};
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
export function escapeName(value: string): string {
|
||||
export const escapeName = (value: string): string => {
|
||||
if (value) {
|
||||
const validName = /^[a-zA-Z_$][\w$]+$/g.test(value);
|
||||
if (!validName) {
|
||||
@ -6,4 +6,4 @@ export function escapeName(value: string): string {
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
};
|
||||
|
||||
@ -7,7 +7,7 @@ import type { WithEnumExtension } from '../interfaces/Extensions/WithEnumExtensi
|
||||
* @param enumerators
|
||||
* @param definition
|
||||
*/
|
||||
export function extendEnum(enumerators: Enum[], definition: WithEnumExtension): Enum[] {
|
||||
export const extendEnum = (enumerators: Enum[], definition: WithEnumExtension): Enum[] => {
|
||||
const names = definition['x-enum-varnames'];
|
||||
const descriptions = definition['x-enum-descriptions'];
|
||||
|
||||
@ -17,4 +17,4 @@ export function extendEnum(enumerators: Enum[], definition: WithEnumExtension):
|
||||
value: enumerator.value,
|
||||
type: enumerator.type,
|
||||
}));
|
||||
}
|
||||
};
|
||||
|
||||
@ -21,7 +21,7 @@ const BASIC_MEDIA_TYPES = [
|
||||
'multipart/batch',
|
||||
];
|
||||
|
||||
export function getContent(openApi: OpenApi, content: Dictionary<OpenApiMediaType>): Content | null {
|
||||
export const getContent = (openApi: OpenApi, content: Dictionary<OpenApiMediaType>): Content | null => {
|
||||
const basicMediaTypeWithSchema = Object.keys(content)
|
||||
.filter(mediaType => {
|
||||
const cleanMediaType = mediaType.split(';')[0].trim();
|
||||
@ -43,4 +43,4 @@ export function getContent(openApi: OpenApi, content: Dictionary<OpenApiMediaTyp
|
||||
};
|
||||
}
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import type { Enum } from '../../../client/interfaces/Enum';
|
||||
import { isDefined } from '../../../utils/isDefined';
|
||||
|
||||
export function getEnum(values?: (string | number)[]): Enum[] {
|
||||
export const getEnum = (values?: (string | number)[]): Enum[] => {
|
||||
if (Array.isArray(values)) {
|
||||
return values
|
||||
.filter((value, index, arr) => {
|
||||
@ -30,4 +30,4 @@ export function getEnum(values?: (string | number)[]): Enum[] {
|
||||
});
|
||||
}
|
||||
return [];
|
||||
}
|
||||
};
|
||||
|
||||
@ -3,7 +3,7 @@ import type { Enum } from '../../../client/interfaces/Enum';
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
export function getEnumFromDescription(description: string): Enum[] {
|
||||
export const getEnumFromDescription = (description: string): Enum[] => {
|
||||
// Check if we can find this special format string:
|
||||
// None=0,Something=1,AnotherThing=2
|
||||
if (/^(\w+=[0-9]+)/g.test(description)) {
|
||||
@ -36,4 +36,4 @@ export function getEnumFromDescription(description: string): Enum[] {
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
};
|
||||
|
||||
@ -24,9 +24,9 @@ const TYPE_MAPPINGS = new Map<string, string>([
|
||||
/**
|
||||
* Get mapped type for given type to any basic Typescript/Javascript type.
|
||||
*/
|
||||
export function getMappedType(type: string, format?: string): string | undefined {
|
||||
export const getMappedType = (type: string, format?: string): string | undefined => {
|
||||
if (format === 'binary') {
|
||||
return 'binary';
|
||||
}
|
||||
return TYPE_MAPPINGS.get(type);
|
||||
}
|
||||
};
|
||||
|
||||
@ -10,12 +10,12 @@ import { getModelDefault } from './getModelDefault';
|
||||
import { getModelProperties } from './getModelProperties';
|
||||
import { getType } from './getType';
|
||||
|
||||
export function getModel(
|
||||
export const getModel = (
|
||||
openApi: OpenApi,
|
||||
definition: OpenApiSchema,
|
||||
isDefinition: boolean = false,
|
||||
name: string = ''
|
||||
): Model {
|
||||
): Model => {
|
||||
const model: Model = {
|
||||
name,
|
||||
export: 'interface',
|
||||
@ -191,4 +191,4 @@ export function getModel(
|
||||
}
|
||||
|
||||
return model;
|
||||
}
|
||||
};
|
||||
|
||||
@ -9,13 +9,13 @@ import { getRequiredPropertiesFromComposition } from './getRequiredPropertiesFro
|
||||
// Fix for circular dependency
|
||||
export type GetModelFn = typeof getModel;
|
||||
|
||||
export function getModelComposition(
|
||||
export const getModelComposition = (
|
||||
openApi: OpenApi,
|
||||
definition: OpenApiSchema,
|
||||
definitions: OpenApiSchema[],
|
||||
type: 'one-of' | 'any-of' | 'all-of',
|
||||
getModel: GetModelFn
|
||||
): ModelComposition {
|
||||
): ModelComposition => {
|
||||
const composition: ModelComposition = {
|
||||
type,
|
||||
imports: [],
|
||||
@ -87,4 +87,4 @@ export function getModelComposition(
|
||||
}
|
||||
|
||||
return composition;
|
||||
}
|
||||
};
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import type { Model } from '../../../client/interfaces/Model';
|
||||
import type { OpenApiSchema } from '../interfaces/OpenApiSchema';
|
||||
|
||||
export function getModelDefault(definition: OpenApiSchema, model?: Model): string | undefined {
|
||||
export const getModelDefault = (definition: OpenApiSchema, model?: Model): string | undefined => {
|
||||
if (definition.default === undefined) {
|
||||
return;
|
||||
}
|
||||
@ -36,4 +36,4 @@ export function getModelDefault(definition: OpenApiSchema, model?: Model): strin
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
@ -10,12 +10,12 @@ import { getType } from './getType';
|
||||
// Fix for circular dependency
|
||||
export type GetModelFn = typeof getModel;
|
||||
|
||||
export function getModelProperties(
|
||||
export const getModelProperties = (
|
||||
openApi: OpenApi,
|
||||
definition: OpenApiSchema,
|
||||
getModel: GetModelFn,
|
||||
parent?: Model
|
||||
): Model[] {
|
||||
): Model[] => {
|
||||
const models: Model[] = [];
|
||||
const discriminator = findOneOfParentDiscriminator(openApi, parent);
|
||||
for (const propertyName in definition.properties) {
|
||||
@ -104,4 +104,4 @@ export function getModelProperties(
|
||||
}
|
||||
|
||||
return models;
|
||||
}
|
||||
};
|
||||
|
||||
@ -6,6 +6,6 @@ import type { Type } from '../../../client/interfaces/Type';
|
||||
* @param modelClass The parsed model class type.
|
||||
* @returns The model template type (<T> or empty).
|
||||
*/
|
||||
export function getModelTemplate(modelClass: Type): string {
|
||||
export const getModelTemplate = (modelClass: Type): string => {
|
||||
return modelClass.template ? '<T>' : '';
|
||||
}
|
||||
};
|
||||
|
||||
@ -3,7 +3,7 @@ import type { OpenApi } from '../interfaces/OpenApi';
|
||||
import { getModel } from './getModel';
|
||||
import { getType } from './getType';
|
||||
|
||||
export function getModels(openApi: OpenApi): Model[] {
|
||||
export const getModels = (openApi: OpenApi): Model[] => {
|
||||
const models: Model[] = [];
|
||||
if (openApi.components) {
|
||||
for (const definitionName in openApi.components.schemas) {
|
||||
@ -16,4 +16,4 @@ export function getModels(openApi: OpenApi): Model[] {
|
||||
}
|
||||
}
|
||||
return models;
|
||||
}
|
||||
};
|
||||
|
||||
@ -15,17 +15,16 @@ import { getRef } from './getRef';
|
||||
import { getServiceName } from './getServiceName';
|
||||
import { sortByRequired } from './sortByRequired';
|
||||
|
||||
export function getOperation(
|
||||
export const getOperation = (
|
||||
openApi: OpenApi,
|
||||
url: string,
|
||||
method: string,
|
||||
tag: string,
|
||||
op: OpenApiOperation,
|
||||
pathParams: OperationParameters
|
||||
): Operation {
|
||||
): Operation => {
|
||||
const serviceName = getServiceName(tag);
|
||||
const operationNameFallback = `${method}${serviceName}`;
|
||||
const operationName = getOperationName(op.operationId || operationNameFallback);
|
||||
const operationName = getOperationName(op.operationId || `${method}`);
|
||||
const operationPath = getOperationPath(url);
|
||||
|
||||
// Create a new operation object for this method.
|
||||
@ -87,4 +86,4 @@ export function getOperation(
|
||||
operation.parameters = operation.parameters.sort(sortByRequired);
|
||||
|
||||
return operation;
|
||||
}
|
||||
};
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import type { OperationError } from '../../../client/interfaces/OperationError';
|
||||
import type { OperationResponse } from '../../../client/interfaces/OperationResponse';
|
||||
|
||||
export function getOperationErrors(operationResponses: OperationResponse[]): OperationError[] {
|
||||
export const getOperationErrors = (operationResponses: OperationResponse[]): OperationError[] => {
|
||||
return operationResponses
|
||||
.filter(operationResponse => {
|
||||
return operationResponse.code >= 300 && operationResponse.description;
|
||||
@ -10,4 +10,4 @@ export function getOperationErrors(operationResponses: OperationResponse[]): Ope
|
||||
code: response.code,
|
||||
description: response.description!,
|
||||
}));
|
||||
}
|
||||
};
|
||||
|
||||
@ -5,10 +5,10 @@ import camelCase from 'camelcase';
|
||||
* This converts the input string to camelCase, so the method name follows
|
||||
* the most popular Javascript and Typescript writing style.
|
||||
*/
|
||||
export function getOperationName(value: string): string {
|
||||
export const getOperationName = (value: string): string => {
|
||||
const clean = value
|
||||
.replace(/^[^a-zA-Z]+/g, '')
|
||||
.replace(/[^\w\-]+/g, '-')
|
||||
.trim();
|
||||
return camelCase(clean);
|
||||
}
|
||||
};
|
||||
|
||||
@ -9,7 +9,7 @@ import { getOperationParameterName } from './getOperationParameterName';
|
||||
import { getRef } from './getRef';
|
||||
import { getType } from './getType';
|
||||
|
||||
export function getOperationParameter(openApi: OpenApi, parameter: OpenApiParameter): OperationParameter {
|
||||
export const getOperationParameter = (openApi: OpenApi, parameter: OpenApiParameter): OperationParameter => {
|
||||
const operationParameter: OperationParameter = {
|
||||
in: parameter.in,
|
||||
prop: parameter.name,
|
||||
@ -89,4 +89,4 @@ export function getOperationParameter(openApi: OpenApi, parameter: OpenApiParame
|
||||
}
|
||||
|
||||
return operationParameter;
|
||||
}
|
||||
};
|
||||
|
||||
@ -7,10 +7,10 @@ const reservedWords =
|
||||
* Replaces any invalid characters from a parameter name.
|
||||
* For example: 'filter.someProperty' becomes 'filterSomeProperty'.
|
||||
*/
|
||||
export function getOperationParameterName(value: string): string {
|
||||
export const getOperationParameterName = (value: string): string => {
|
||||
const clean = value
|
||||
.replace(/^[^a-zA-Z]+/g, '')
|
||||
.replace(/[^\w\-]+/g, '-')
|
||||
.trim();
|
||||
return camelCase(clean).replace(reservedWords, '_$1');
|
||||
}
|
||||
};
|
||||
|
||||
@ -4,7 +4,7 @@ import type { OpenApiParameter } from '../interfaces/OpenApiParameter';
|
||||
import { getOperationParameter } from './getOperationParameter';
|
||||
import { getRef } from './getRef';
|
||||
|
||||
export function getOperationParameters(openApi: OpenApi, parameters: OpenApiParameter[]): OperationParameters {
|
||||
export const getOperationParameters = (openApi: OpenApi, parameters: OpenApiParameter[]): OperationParameters => {
|
||||
const operationParameters: OperationParameters = {
|
||||
imports: [],
|
||||
parameters: [],
|
||||
@ -58,4 +58,4 @@ export function getOperationParameters(openApi: OpenApi, parameters: OpenApiPara
|
||||
}
|
||||
});
|
||||
return operationParameters;
|
||||
}
|
||||
};
|
||||
|
||||
@ -7,10 +7,10 @@ import { getOperationParameterName } from './getOperationParameterName';
|
||||
* Plus we return the correct parameter names to replace in the URL.
|
||||
* @param path
|
||||
*/
|
||||
export function getOperationPath(path: string): string {
|
||||
export const getOperationPath = (path: string): string => {
|
||||
return path
|
||||
.replace(/\{(.*?)\}/g, (_, w: string) => {
|
||||
return `\${${getOperationParameterName(w)}}`;
|
||||
})
|
||||
.replace('${apiVersion}', '${OpenAPI.VERSION}');
|
||||
}
|
||||
};
|
||||
|
||||
@ -6,7 +6,7 @@ import { getContent } from './getContent';
|
||||
import { getModel } from './getModel';
|
||||
import { getType } from './getType';
|
||||
|
||||
export function getOperationRequestBody(openApi: OpenApi, body: OpenApiRequestBody): OperationParameter {
|
||||
export const getOperationRequestBody = (openApi: OpenApi, body: OpenApiRequestBody): OperationParameter => {
|
||||
const requestBody: OperationParameter = {
|
||||
in: 'body',
|
||||
export: 'interface',
|
||||
@ -83,4 +83,4 @@ export function getOperationRequestBody(openApi: OpenApi, body: OpenApiRequestBo
|
||||
}
|
||||
|
||||
return requestBody;
|
||||
}
|
||||
};
|
||||
|
||||
@ -8,11 +8,11 @@ import { getModel } from './getModel';
|
||||
import { getRef } from './getRef';
|
||||
import { getType } from './getType';
|
||||
|
||||
export function getOperationResponse(
|
||||
export const getOperationResponse = (
|
||||
openApi: OpenApi,
|
||||
response: OpenApiResponse,
|
||||
responseCode: number
|
||||
): OperationResponse {
|
||||
): OperationResponse => {
|
||||
const operationResponse: OperationResponse = {
|
||||
in: 'response',
|
||||
name: '',
|
||||
@ -95,4 +95,4 @@ export function getOperationResponse(
|
||||
}
|
||||
|
||||
return operationResponse;
|
||||
}
|
||||
};
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
export function getOperationResponseCode(value: string | 'default'): number | null {
|
||||
export const getOperationResponseCode = (value: string | 'default'): number | null => {
|
||||
// You can specify a "default" response, this is treated as HTTP code 200
|
||||
if (value === 'default') {
|
||||
return 200;
|
||||
@ -13,4 +13,4 @@ export function getOperationResponseCode(value: string | 'default'): number | nu
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import type { OperationResponse } from '../../../client/interfaces/OperationResponse';
|
||||
|
||||
export function getOperationResponseHeader(operationResponses: OperationResponse[]): string | null {
|
||||
export const getOperationResponseHeader = (operationResponses: OperationResponse[]): string | null => {
|
||||
const header = operationResponses.find(operationResponses => {
|
||||
return operationResponses.in === 'header';
|
||||
});
|
||||
@ -8,4 +8,4 @@ export function getOperationResponseHeader(operationResponses: OperationResponse
|
||||
return header.name;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
@ -6,7 +6,7 @@ import { getOperationResponse } from './getOperationResponse';
|
||||
import { getOperationResponseCode } from './getOperationResponseCode';
|
||||
import { getRef } from './getRef';
|
||||
|
||||
export function getOperationResponses(openApi: OpenApi, responses: OpenApiResponses): OperationResponse[] {
|
||||
export const getOperationResponses = (openApi: OpenApi, responses: OpenApiResponses): OperationResponse[] => {
|
||||
const operationResponses: OperationResponse[] = [];
|
||||
|
||||
// Iterate over each response code and get the
|
||||
@ -28,4 +28,4 @@ export function getOperationResponses(openApi: OpenApi, responses: OpenApiRespon
|
||||
return operationResponses.sort((a, b): number => {
|
||||
return a.code < b.code ? -1 : a.code > b.code ? 1 : 0;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
@ -1,15 +1,15 @@
|
||||
import type { Model } from '../../../client/interfaces/Model';
|
||||
import type { OperationResponse } from '../../../client/interfaces/OperationResponse';
|
||||
|
||||
function areEqual(a: Model, b: Model): boolean {
|
||||
const areEqual = (a: Model, b: Model): boolean => {
|
||||
const equal = a.type === b.type && a.base === b.base && a.template === b.template;
|
||||
if (equal && a.link && b.link) {
|
||||
return areEqual(a.link, b.link);
|
||||
}
|
||||
return equal;
|
||||
}
|
||||
};
|
||||
|
||||
export function getOperationResults(operationResponses: OperationResponse[]): OperationResponse[] {
|
||||
export const getOperationResults = (operationResponses: OperationResponse[]): OperationResponse[] => {
|
||||
const operationResults: OperationResponse[] = [];
|
||||
|
||||
// Filter out success response codes, but skip "204 No Content"
|
||||
@ -49,4 +49,4 @@ export function getOperationResults(operationResponses: OperationResponse[]): Op
|
||||
}) === index
|
||||
);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
@ -4,7 +4,7 @@ import type { OpenApiReference } from '../interfaces/OpenApiReference';
|
||||
const ESCAPED_REF_SLASH = /~1/g;
|
||||
const ESCAPED_REF_TILDE = /~0/g;
|
||||
|
||||
export function getRef<T>(openApi: OpenApi, item: T & OpenApiReference): T {
|
||||
export const getRef = <T>(openApi: OpenApi, item: T & OpenApiReference): T => {
|
||||
if (item.$ref) {
|
||||
// Fetch the paths to the definitions, this converts:
|
||||
// "#/components/schemas/Form" to ["components", "schemas", "Form"]
|
||||
@ -29,4 +29,4 @@ export function getRef<T>(openApi: OpenApi, item: T & OpenApiReference): T {
|
||||
return result as T;
|
||||
}
|
||||
return item as T;
|
||||
}
|
||||
};
|
||||
|
||||
@ -7,12 +7,12 @@ import { getRef } from './getRef';
|
||||
// Fix for circular dependency
|
||||
export type GetModelFn = typeof getModel;
|
||||
|
||||
export function getRequiredPropertiesFromComposition(
|
||||
export const getRequiredPropertiesFromComposition = (
|
||||
openApi: OpenApi,
|
||||
required: string[],
|
||||
definitions: OpenApiSchema[],
|
||||
getModel: GetModelFn
|
||||
): Model[] {
|
||||
): Model[] => {
|
||||
return definitions
|
||||
.reduce((properties, definition) => {
|
||||
if (definition.$ref) {
|
||||
@ -30,4 +30,4 @@ export function getRequiredPropertiesFromComposition(
|
||||
isRequired: true,
|
||||
};
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import type { OpenApi } from '../interfaces/OpenApi';
|
||||
|
||||
export function getServer(openApi: OpenApi): string {
|
||||
export const getServer = (openApi: OpenApi): string => {
|
||||
const server = openApi.servers?.[0];
|
||||
const variables = server?.variables || {};
|
||||
let url = server?.url || '';
|
||||
@ -10,4 +10,4 @@ export function getServer(openApi: OpenApi): string {
|
||||
}
|
||||
}
|
||||
return url.replace(/\/$/g, '');
|
||||
}
|
||||
};
|
||||
|
||||
@ -4,10 +4,10 @@ import camelCase from 'camelcase';
|
||||
* Convert the input value to a correct service name. This converts
|
||||
* the input string to PascalCase.
|
||||
*/
|
||||
export function getServiceName(value: string): string {
|
||||
export const getServiceName = (value: string): string => {
|
||||
const clean = value
|
||||
.replace(/^[^a-zA-Z]+/g, '')
|
||||
.replace(/[^\w\-]+/g, '-')
|
||||
.trim();
|
||||
return camelCase(clean, { pascalCase: true });
|
||||
}
|
||||
};
|
||||
|
||||
@ -3,6 +3,6 @@
|
||||
* This basically removes any "v" prefix from the version string.
|
||||
* @param version
|
||||
*/
|
||||
export function getServiceVersion(version = '1.0'): string {
|
||||
export const getServiceVersion = (version = '1.0'): string => {
|
||||
return String(version).replace(/^v/gi, '');
|
||||
}
|
||||
};
|
||||
|
||||
@ -7,7 +7,7 @@ import { getOperationParameters } from './getOperationParameters';
|
||||
/**
|
||||
* Get the OpenAPI services
|
||||
*/
|
||||
export function getServices(openApi: OpenApi): Service[] {
|
||||
export const getServices = (openApi: OpenApi): Service[] => {
|
||||
const services = new Map<string, Service>();
|
||||
for (const url in openApi.paths) {
|
||||
if (openApi.paths.hasOwnProperty(url)) {
|
||||
@ -28,7 +28,7 @@ export function getServices(openApi: OpenApi): Service[] {
|
||||
case 'patch':
|
||||
// Each method contains an OpenAPI operation, we parse the operation
|
||||
const op = path[method]!;
|
||||
const tags = op.tags?.length ? op.tags.filter(unique) : [''];
|
||||
const tags = op.tags?.length ? op.tags.filter(unique) : ['Default'];
|
||||
tags.forEach(tag => {
|
||||
const operation = getOperation(openApi, url, method, tag, op, pathParams);
|
||||
|
||||
@ -52,4 +52,4 @@ export function getServices(openApi: OpenApi): Service[] {
|
||||
}
|
||||
}
|
||||
return Array.from(services.values());
|
||||
}
|
||||
};
|
||||
|
||||
@ -3,16 +3,16 @@ import { isDefined } from '../../../utils/isDefined';
|
||||
import { getMappedType } from './getMappedType';
|
||||
import { stripNamespace } from './stripNamespace';
|
||||
|
||||
function encode(value: string): string {
|
||||
const encode = (value: string): string => {
|
||||
return value.replace(/^[^a-zA-Z_$]+/g, '').replace(/[^\w$]+/g, '_');
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Parse any string value into a type object.
|
||||
* @param type String or String[] value like "integer", "Link[Model]" or ["string", "null"].
|
||||
* @param format String value like "binary" or "date".
|
||||
*/
|
||||
export function getType(type: string | string[] = 'any', format?: string): Type {
|
||||
export const getType = (type: string | string[] = 'any', format?: string): Type => {
|
||||
const result: Type = {
|
||||
type: 'any',
|
||||
base: 'any',
|
||||
@ -79,4 +79,4 @@ export function getType(type: string | string[] = 'any', format?: string): Type
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
import type { OperationParameter } from '../../../client/interfaces/OperationParameter';
|
||||
|
||||
export function sortByRequired(a: OperationParameter, b: OperationParameter): number {
|
||||
export const sortByRequired = (a: OperationParameter, b: OperationParameter): number => {
|
||||
const aNeedsValue = a.isRequired && a.default === undefined;
|
||||
const bNeedsValue = b.isRequired && b.default === undefined;
|
||||
if (aNeedsValue && !bNeedsValue) return -1;
|
||||
if (bNeedsValue && !aNeedsValue) return 1;
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
* Strip (OpenAPI) namespaces fom values.
|
||||
* @param value
|
||||
*/
|
||||
export function stripNamespace(value: string): string {
|
||||
export const stripNamespace = (value: string): string => {
|
||||
return value
|
||||
.trim()
|
||||
.replace(/^#\/components\/schemas\//, '')
|
||||
@ -14,4 +14,4 @@ export function stripNamespace(value: string): string {
|
||||
.replace(/^#\/components\/securitySchemes\//, '')
|
||||
.replace(/^#\/components\/links\//, '')
|
||||
.replace(/^#\/components\/callbacks\//, '');
|
||||
}
|
||||
};
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
export default {
|
||||
compiler: [8, '>= 4.3.0'],
|
||||
useData: true,
|
||||
main: function () {
|
||||
main: () => {
|
||||
return '';
|
||||
},
|
||||
};
|
||||
|
||||
@ -14,7 +14,7 @@ type HttpRequestConstructor = new (config: OpenAPIConfig) => BaseHttpRequest;
|
||||
export class {{{clientName}}} {
|
||||
|
||||
{{#each services}}
|
||||
public readonly {{{name}}}: {{{name}}}{{{@root.postfix}}};
|
||||
public readonly {{{camelCase name}}}: {{{name}}}{{{@root.postfix}}};
|
||||
{{/each}}
|
||||
|
||||
public readonly request: BaseHttpRequest;
|
||||
@ -33,7 +33,7 @@ export class {{{clientName}}} {
|
||||
});
|
||||
|
||||
{{#each services}}
|
||||
this.{{{name}}} = new {{{name}}}{{{@root.postfix}}}(this.request);
|
||||
this.{{{camelCase name}}} = new {{{name}}}{{{@root.postfix}}}(this.request);
|
||||
{{/each}}
|
||||
}
|
||||
}
|
||||
|
||||
@ -4,15 +4,15 @@ import type { OpenApiDiscriminator } from '../openApi/v3/interfaces/OpenApiDiscr
|
||||
import { stripNamespace } from '../openApi/v3/parser/stripNamespace';
|
||||
import type { Dictionary } from './types';
|
||||
|
||||
function inverseDictionary(map: Dictionary<string>): Dictionary<string> {
|
||||
const inverseDictionary = (map: Dictionary<string>): Dictionary<string> => {
|
||||
const m2: Dictionary<string> = {};
|
||||
for (const key in map) {
|
||||
m2[map[key]] = key;
|
||||
}
|
||||
return m2;
|
||||
}
|
||||
};
|
||||
|
||||
export function findOneOfParentDiscriminator(openApi: OpenApi, parent?: Model): OpenApiDiscriminator | undefined {
|
||||
export const findOneOfParentDiscriminator = (openApi: OpenApi, parent?: Model): OpenApiDiscriminator | undefined => {
|
||||
if (openApi.components && parent) {
|
||||
for (const definitionName in openApi.components.schemas) {
|
||||
if (openApi.components.schemas.hasOwnProperty(definitionName)) {
|
||||
@ -28,9 +28,9 @@ export function findOneOfParentDiscriminator(openApi: OpenApi, parent?: Model):
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
export function mapPropertyValue(discriminator: OpenApiDiscriminator, parent: Model): string {
|
||||
export const mapPropertyValue = (discriminator: OpenApiDiscriminator, parent: Model): string => {
|
||||
if (discriminator.mapping) {
|
||||
const mapping = inverseDictionary(discriminator.mapping);
|
||||
const key = Object.keys(mapping).find(item => stripNamespace(item) == parent.name);
|
||||
@ -39,4 +39,4 @@ export function mapPropertyValue(discriminator: OpenApiDiscriminator, parent: Mo
|
||||
}
|
||||
}
|
||||
return parent.name;
|
||||
}
|
||||
};
|
||||
|
||||
@ -1,11 +1,11 @@
|
||||
/**
|
||||
* Calls a defined callback function on each element of an array.
|
||||
* Calls a defined callback on each element of an array.
|
||||
* Then, flattens the result into a new array.
|
||||
*/
|
||||
export function flatMap<U, T>(array: T[], callback: (value: T, index: number, array: T[]) => U[]): U[] {
|
||||
export const flatMap = <U, T>(array: T[], callback: (value: T, index: number, array: T[]) => U[]): U[] => {
|
||||
const result: U[] = [];
|
||||
array.map<U[]>(callback).forEach(arr => {
|
||||
result.push(...arr);
|
||||
});
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { EOL } from 'os';
|
||||
|
||||
export function formatCode(s: string): string {
|
||||
export const formatCode = (s: string): string => {
|
||||
let indent: number = 0;
|
||||
let lines = s.split(EOL);
|
||||
lines = lines.map(line => {
|
||||
@ -20,4 +20,4 @@ export function formatCode(s: string): string {
|
||||
return result;
|
||||
});
|
||||
return lines.join(EOL);
|
||||
}
|
||||
};
|
||||
|
||||
@ -2,7 +2,7 @@ import { EOL } from 'os';
|
||||
|
||||
import { Indent } from '../Indent';
|
||||
|
||||
export function formatIndentation(s: string, indent: Indent): string {
|
||||
export const formatIndentation = (s: string, indent: Indent): string => {
|
||||
let lines = s.split(EOL);
|
||||
lines = lines.map(line => {
|
||||
switch (indent) {
|
||||
@ -15,4 +15,4 @@ export function formatIndentation(s: string, indent: Indent): string {
|
||||
}
|
||||
});
|
||||
return lines.join(EOL);
|
||||
}
|
||||
};
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import type { Model } from '../client/interfaces/Model';
|
||||
import { sort } from './sort';
|
||||
|
||||
export function getModelNames(models: Model[]): string[] {
|
||||
export const getModelNames = (models: Model[]): string[] => {
|
||||
return models.map(model => model.name).sort(sort);
|
||||
}
|
||||
};
|
||||
|
||||
@ -6,6 +6,6 @@ import RefParser from 'json-schema-ref-parser';
|
||||
* on parsing the file as JSON.
|
||||
* @param location: Path or url
|
||||
*/
|
||||
export async function getOpenApiSpec(location: string): Promise<any> {
|
||||
export const getOpenApiSpec = async (location: string): Promise<any> => {
|
||||
return await RefParser.bundle(location, location, {});
|
||||
}
|
||||
};
|
||||
|
||||
@ -9,7 +9,7 @@ export enum OpenApiVersion {
|
||||
* an incompatible type. Or if the type is missing...
|
||||
* @param openApi The loaded spec (can be any object)
|
||||
*/
|
||||
export function getOpenApiVersion(openApi: any): OpenApiVersion {
|
||||
export const getOpenApiVersion = (openApi: any): OpenApiVersion => {
|
||||
const info: any = openApi.swagger || openApi.openapi;
|
||||
if (typeof info === 'string') {
|
||||
const c = info.charAt(0);
|
||||
@ -19,4 +19,4 @@ export function getOpenApiVersion(openApi: any): OpenApiVersion {
|
||||
}
|
||||
}
|
||||
throw new Error(`Unsupported Open API version: "${String(info)}"`);
|
||||
}
|
||||
};
|
||||
|
||||
@ -5,6 +5,6 @@
|
||||
* to make it a valid regexp string.
|
||||
* @param pattern
|
||||
*/
|
||||
export function getPattern(pattern?: string): string | undefined {
|
||||
export const getPattern = (pattern?: string): string | undefined => {
|
||||
return pattern?.replace(/\\/g, '\\\\');
|
||||
}
|
||||
};
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import type { Service } from '../client/interfaces/Service';
|
||||
import { sort } from './sort';
|
||||
|
||||
export function getServiceNames(services: Service[]): string[] {
|
||||
export const getServiceNames = (services: Service[]): string[] => {
|
||||
return services.map(service => service.name).sort(sort);
|
||||
}
|
||||
};
|
||||
|
||||
@ -2,6 +2,6 @@
|
||||
* Check if a value is defined
|
||||
* @param value
|
||||
*/
|
||||
export function isDefined<T>(value: T | undefined | null | ''): value is Exclude<T, undefined | null | ''> {
|
||||
export const isDefined = <T>(value: T | undefined | null | ''): value is Exclude<T, undefined | null | ''> => {
|
||||
return value !== undefined && value !== null && value !== '';
|
||||
}
|
||||
};
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
export function isEqual(a: any, b: any): boolean {
|
||||
export const isEqual = (a: any, b: any): boolean => {
|
||||
if (a === b) {
|
||||
return true;
|
||||
}
|
||||
@ -35,4 +35,4 @@ export function isEqual(a: any, b: any): boolean {
|
||||
}
|
||||
|
||||
return a !== a && b !== b;
|
||||
}
|
||||
};
|
||||
|
||||
@ -1,3 +1,3 @@
|
||||
export function isString(val: any): val is string {
|
||||
export const isString = (val: any): val is string => {
|
||||
return typeof val === 'string';
|
||||
}
|
||||
};
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { relative } from 'path';
|
||||
|
||||
export function isSubDirectory(parent: string, child: string) {
|
||||
export const isSubDirectory = (parent: string, child: string) => {
|
||||
return relative(child, parent).startsWith('..');
|
||||
}
|
||||
};
|
||||
|
||||
@ -6,10 +6,10 @@ import { postProcessService } from './postProcessService';
|
||||
* Post process client
|
||||
* @param client Client object with all the models, services, etc.
|
||||
*/
|
||||
export function postProcessClient(client: Client): Client {
|
||||
export const postProcessClient = (client: Client): Client => {
|
||||
return {
|
||||
...client,
|
||||
models: client.models.map(model => postProcessModel(model)),
|
||||
services: client.services.map(service => postProcessService(service)),
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
@ -8,11 +8,11 @@ import { postProcessModelImports } from './postProcessModelImports';
|
||||
* This will cleanup any double imports or enum values.
|
||||
* @param model
|
||||
*/
|
||||
export function postProcessModel(model: Model): Model {
|
||||
export const postProcessModel = (model: Model): Model => {
|
||||
return {
|
||||
...model,
|
||||
imports: postProcessModelImports(model),
|
||||
enums: postProcessModelEnums(model),
|
||||
enum: postProcessModelEnum(model),
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
@ -5,8 +5,8 @@ import type { Model } from '../client/interfaces/Model';
|
||||
* Set unique enum values for the model
|
||||
* @param model
|
||||
*/
|
||||
export function postProcessModelEnum(model: Model): Enum[] {
|
||||
export const postProcessModelEnum = (model: Model): Enum[] => {
|
||||
return model.enum.filter((property, index, arr) => {
|
||||
return arr.findIndex(item => item.name === property.name) === index;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
@ -4,8 +4,8 @@ import type { Model } from '../client/interfaces/Model';
|
||||
* Set unique enum values for the model
|
||||
* @param model The model that is post-processed
|
||||
*/
|
||||
export function postProcessModelEnums(model: Model): Model[] {
|
||||
export const postProcessModelEnums = (model: Model): Model[] => {
|
||||
return model.enums.filter((property, index, arr) => {
|
||||
return arr.findIndex(item => item.name === property.name) === index;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
@ -6,9 +6,9 @@ import { unique } from './unique';
|
||||
* Set unique imports, sorted by name
|
||||
* @param model The model that is post-processed
|
||||
*/
|
||||
export function postProcessModelImports(model: Model): string[] {
|
||||
export const postProcessModelImports = (model: Model): string[] => {
|
||||
return model.imports
|
||||
.filter(unique)
|
||||
.sort(sort)
|
||||
.filter(name => model.name !== name);
|
||||
}
|
||||
};
|
||||
|
||||
@ -2,7 +2,7 @@ import type { Service } from '../client/interfaces/Service';
|
||||
import { postProcessServiceImports } from './postProcessServiceImports';
|
||||
import { postProcessServiceOperations } from './postProcessServiceOperations';
|
||||
|
||||
export function postProcessService(service: Service): Service {
|
||||
export const postProcessService = (service: Service): Service => {
|
||||
const clone = { ...service };
|
||||
clone.operations = postProcessServiceOperations(clone);
|
||||
clone.operations.forEach(operation => {
|
||||
@ -10,4 +10,4 @@ export function postProcessService(service: Service): Service {
|
||||
});
|
||||
clone.imports = postProcessServiceImports(clone);
|
||||
return clone;
|
||||
}
|
||||
};
|
||||
|
||||
@ -6,6 +6,6 @@ import { unique } from './unique';
|
||||
* Set unique imports, sorted by name
|
||||
* @param service
|
||||
*/
|
||||
export function postProcessServiceImports(service: Service): string[] {
|
||||
export const postProcessServiceImports = (service: Service): string[] => {
|
||||
return service.imports.filter(unique).sort(sort);
|
||||
}
|
||||
};
|
||||
|
||||
@ -2,7 +2,7 @@ import type { Operation } from '../client/interfaces/Operation';
|
||||
import type { Service } from '../client/interfaces/Service';
|
||||
import { flatMap } from './flatMap';
|
||||
|
||||
export function postProcessServiceOperations(service: Service): Operation[] {
|
||||
export const postProcessServiceOperations = (service: Service): Operation[] => {
|
||||
const names = new Map<string, number>();
|
||||
|
||||
return service.operations.map(operation => {
|
||||
@ -23,4 +23,4 @@ export function postProcessServiceOperations(service: Service): Operation[] {
|
||||
|
||||
return clone;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
@ -2,7 +2,7 @@ import { readSpecFromDisk } from './readSpecFromDisk';
|
||||
import { readSpecFromHttp } from './readSpecFromHttp';
|
||||
import { readSpecFromHttps } from './readSpecFromHttps';
|
||||
|
||||
export async function readSpec(input: string): Promise<string> {
|
||||
export const readSpec = async (input: string): Promise<string> => {
|
||||
if (input.startsWith('https://')) {
|
||||
return await readSpecFromHttps(input);
|
||||
}
|
||||
@ -10,4 +10,4 @@ export async function readSpec(input: string): Promise<string> {
|
||||
return await readSpecFromHttp(input);
|
||||
}
|
||||
return await readSpecFromDisk(input);
|
||||
}
|
||||
};
|
||||
|
||||
@ -6,7 +6,7 @@ import { exists, readFile } from './fileSystem';
|
||||
* Check if given file exists and try to read the content as string.
|
||||
* @param input
|
||||
*/
|
||||
export async function readSpecFromDisk(input: string): Promise<string> {
|
||||
export const readSpecFromDisk = async (input: string): Promise<string> => {
|
||||
const filePath = resolve(process.cwd(), input);
|
||||
const fileExists = await exists(filePath);
|
||||
if (fileExists) {
|
||||
@ -18,4 +18,4 @@ export async function readSpecFromDisk(input: string): Promise<string> {
|
||||
}
|
||||
}
|
||||
throw new Error(`Could not find OpenApi spec: "${filePath}"`);
|
||||
}
|
||||
};
|
||||
|
||||
@ -4,7 +4,7 @@ import { get } from 'http';
|
||||
* Download the spec file from a HTTP resource
|
||||
* @param url
|
||||
*/
|
||||
export async function readSpecFromHttp(url: string): Promise<string> {
|
||||
export const readSpecFromHttp = async (url: string): Promise<string> => {
|
||||
return new Promise<string>((resolve, reject) => {
|
||||
get(url, response => {
|
||||
let body = '';
|
||||
@ -19,4 +19,4 @@ export async function readSpecFromHttp(url: string): Promise<string> {
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
@ -4,7 +4,7 @@ import { get } from 'https';
|
||||
* Download the spec file from a HTTPS resource
|
||||
* @param url
|
||||
*/
|
||||
export async function readSpecFromHttps(url: string): Promise<string> {
|
||||
export const readSpecFromHttps = async (url: string): Promise<string> => {
|
||||
return new Promise<string>((resolve, reject) => {
|
||||
get(url, response => {
|
||||
let body = '';
|
||||
@ -19,4 +19,4 @@ export async function readSpecFromHttps(url: string): Promise<string> {
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
@ -19,5 +19,6 @@ describe('registerHandlebarHelpers', () => {
|
||||
expect(helpers).toContain('enumerator');
|
||||
expect(helpers).toContain('escapeComment');
|
||||
expect(helpers).toContain('escapeDescription');
|
||||
expect(helpers).toContain('camelCase');
|
||||
});
|
||||
});
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import camelCase from 'camelcase';
|
||||
import Handlebars from 'handlebars/runtime';
|
||||
import { EOL } from 'os';
|
||||
|
||||
@ -6,11 +7,11 @@ import { Model } from '../client/interfaces/Model';
|
||||
import { HttpClient } from '../HttpClient';
|
||||
import { unique } from './unique';
|
||||
|
||||
export function registerHandlebarHelpers(root: {
|
||||
export const registerHandlebarHelpers = (root: {
|
||||
httpClient: HttpClient;
|
||||
useOptions: boolean;
|
||||
useUnionTypes: boolean;
|
||||
}): void {
|
||||
}): void => {
|
||||
Handlebars.registerHelper(
|
||||
'equals',
|
||||
function (this: any, a: string, b: string, options: Handlebars.HelperOptions): string {
|
||||
@ -91,4 +92,8 @@ export function registerHandlebarHelpers(root: {
|
||||
Handlebars.registerHelper('escapeDescription', function (value: string): string {
|
||||
return value.replace(/\\/g, '\\\\').replace(/`/g, '\\`').replace(/\${/g, '\\${');
|
||||
});
|
||||
}
|
||||
|
||||
Handlebars.registerHelper('camelCase', function (value: string): string {
|
||||
return camelCase(value);
|
||||
});
|
||||
};
|
||||
|
||||
@ -103,11 +103,11 @@ export interface Templates {
|
||||
* Read all the Handlebar templates that we need and return on wrapper object
|
||||
* so we can easily access the templates in out generator / write functions.
|
||||
*/
|
||||
export function registerHandlebarTemplates(root: {
|
||||
export const registerHandlebarTemplates = (root: {
|
||||
httpClient: HttpClient;
|
||||
useOptions: boolean;
|
||||
useUnionTypes: boolean;
|
||||
}): Templates {
|
||||
}): Templates => {
|
||||
registerHandlebarHelpers(root);
|
||||
|
||||
// Main templates (entry points for the files we write to disk)
|
||||
@ -207,4 +207,4 @@ export function registerHandlebarTemplates(root: {
|
||||
Handlebars.registerPartial('axios/request', Handlebars.template(axiosRequest));
|
||||
|
||||
return templates;
|
||||
}
|
||||
};
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user