You're Invited:Meet the Socket Team at BlackHat and DEF CON in Las Vegas, Aug 4-6.RSVP
Socket
Book a DemoInstallSign in
Socket

swagger-typescript-api

Package Overview
Dependencies
Maintainers
1
Versions
154
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

swagger-typescript-api - npm Package Compare versions

Comparing version

to
13.0.0-experimental-1

src/schema-parser/schema-processor.js

2

index.d.ts

@@ -204,3 +204,3 @@ type HttpClientType = "axios" | "fetch";

| string
| ((schema: Record<string, any>, parser: import("./src/schema-parser/schema-parser").SchemaParser) => string);
| ((schema: Record<string, any>, parser: import("./src/schema-parser/schema-processor").SchemaProcessor) => string);

@@ -207,0 +207,0 @@ type PrimitiveTypeStruct = Record<

{
"name": "swagger-typescript-api",
"version": "12.0.1",
"version": "13.0.0-experimental-1",
"description": "Generate typescript/javascript api from swagger schema",

@@ -5,0 +5,0 @@ "scripts": {

@@ -402,12 +402,11 @@ # swagger-typescript-api

It is type mapper or translator swagger schema objects. `primitiveTypeConstructs` translates `type`/`format` schema fields to typescript structs.
This option has type
This option has type
```ts
type PrimitiveTypeStructValue =
| string
| ((schema: Record<string, any>, parser: import("./src/schema-parser/schema-parser").SchemaParser) => string);
| string
| ((schema: Record<string, any>, parser: import("./schema-parser-engine").SchemaProcessor) => string);
type PrimitiveTypeStruct = Record<
"integer" | "number" | "boolean" | "object" | "file" | "string" | "array",
string | ({ $default: PrimitiveTypeStructValue } & Record<string, PrimitiveTypeStructValue>)
>
type PrimitiveTypeStruct = Record<"integer" | "number" | "boolean" | "object" | "file" | "string" | "array",
string | ({ $default: PrimitiveTypeStructValue } & Record<string, PrimitiveTypeStructValue>)>

@@ -447,4 +446,4 @@ declare const primitiveTypeConstructs: (struct: PrimitiveTypeStruct) => Partial<PrimitiveTypeStruct>

},
array: (schema, parser) => {
const content = parser.getInlineParseContent(schema.items);
array: async (schema, parser) => {
const content = await parser.getInlineParseContent(schema.items);
return parser.safeAddNullToType(schema, `(${content})[]`);

@@ -451,0 +450,0 @@ },

@@ -5,5 +5,5 @@ const { SwaggerSchemaResolver } = require("./swagger-schema-resolver.js");

const { Logger } = require("./util/logger.js");
const { TypeName } = require("./type-name.js");
const { TypeNameFormatter } = require("./type-name-formatter.js");
const _ = require("lodash");
const { SchemaParser } = require("./schema-parser/schema-parser.js");
const { SchemaProcessor } = require("./schema-parser/schema-processor.js");
const { SchemaRoutes } = require("./schema-parser/schema-routes.js");

@@ -37,7 +37,7 @@ const { CodeGenConfig } = require("./configuration.js");

/**
* @type {TypeName}
* @type {TypeNameFormatter}
*/
typeName;
/**
* @type {SchemaParser}
* @type {SchemaProcessor}
*/

@@ -68,6 +68,6 @@ schemaParser;

this.schemaComponentMap = new SchemaComponentsMap(this.config);
this.typeName = new TypeName(this.config, this.logger);
this.typeName = new TypeNameFormatter(this.config, this.logger);
this.templates = new Templates(this.config, this.logger, this.fileSystem, this.getRenderTemplateData);
this.codeFormatter = new CodeFormatter(this.config);
this.schemaParser = new SchemaParser(
this.schemaParser = new SchemaProcessor(
this.config,

@@ -91,2 +91,3 @@ this.logger,

async start() {
await this.schemaRoutes.init();
this.config.update({ templatePaths: this.templates.getTemplatePaths(this.config) });

@@ -114,7 +115,9 @@ this.config.update({ templatesToRender: this.templates.getTemplates(this.config) });

const parsedSchemas = _.map(_.get(swagger.usageSchema.components, "schemas"), (schema, typeName) =>
this.schemaParser.parseSchema(schema, typeName),
const parsedSchemas = await Promise.all(
_.map(_.get(swagger.usageSchema.components, "schemas"), (schema, typeName) =>
this.schemaParser.parseSchema(schema, typeName),
),
);
this.schemaRoutes.attachSchema({
await this.schemaRoutes.attachSchema({
usageSchema: swagger.usageSchema,

@@ -158,6 +161,10 @@ parsedSchemas,

const modelTypes = (await Promise.all(_.map(sortSchemas(usageComponentSchemas), this.prepareModelType))).filter(
Boolean,
);
const rawConfiguration = {
apiConfig: this.createApiConfig(swagger.usageSchema),
config: this.config,
modelTypes: _.map(sortSchemas(usageComponentSchemas), this.prepareModelType).filter(Boolean),
modelTypes: modelTypes,
rawModelTypes: usageComponentSchemas,

@@ -187,3 +194,3 @@ hasSecurityRoutes: this.schemaRoutes.hasSecurityRoutes,

const files = this.generateOutputFiles({
const files = await this.generateOutputFiles({
configuration: configuration,

@@ -228,3 +235,3 @@ });

getTemplate: this.templates.getTemplate,
renderTemplate: this.templates.renderTemplate,
renderTemplate: await this.templates.renderTemplate,
createFile: this.fileSystem.createFile,

@@ -264,10 +271,11 @@ formatTSContent: this.codeFormatter.formatCode,

prepareModelType = (typeInfo) => {
prepareModelType = async (typeInfo) => {
if (!typeInfo.typeData) {
typeInfo.typeData = this.schemaParser.parseSchema(typeInfo.rawTypeData, typeInfo.typeName);
typeInfo.typeData = await this.schemaParser.parseSchema(typeInfo.rawTypeData, typeInfo.typeName);
}
const rawTypeData = typeInfo.typeData;
const typeData = this.schemaParser.schemaFormatters.base[rawTypeData.type]
? this.schemaParser.schemaFormatters.base[rawTypeData.type](rawTypeData)
: rawTypeData;
const typeData = await this.schemaParser.schemaFormatters.formatSchema(typeInfo.typeData, {
formatType: "base",
schemaType: typeInfo.typeData.type,
});
let { typeIdentifier, name: originalName, content, description } = typeData;

@@ -283,4 +291,4 @@ const name = this.typeName.format(originalName);

description,
$content: rawTypeData.content,
rawContent: rawTypeData.content,
$content: typeInfo.typeData.content,
rawContent: typeInfo.typeData.content,
content: content,

@@ -291,18 +299,23 @@ typeData,

generateOutputFiles = ({ configuration }) => {
generateOutputFiles = async ({ configuration }) => {
const { modular, templatesToRender } = this.config;
const output = modular
? this.createMultipleFileInfos(templatesToRender, configuration)
: this.createSingleFileInfo(templatesToRender, configuration);
? await this.createMultipleFileInfos(templatesToRender, configuration)
: await this.createSingleFileInfo(templatesToRender, configuration);
if (!_.isEmpty(configuration.extraTemplates)) {
output.push(
..._.map(configuration.extraTemplates, (extraTemplate) => {
return this.createOutputFileInfo(
configuration,
extraTemplate.name,
this.templates.renderTemplate(this.fileSystem.getFileContent(extraTemplate.path), configuration),
);
}),
...(await Promise.all(
_.map(configuration.extraTemplates, async (extraTemplate) => {
return this.createOutputFileInfo(
configuration,
extraTemplate.name,
await await this.templates.renderTemplate(
this.fileSystem.getFileContent(extraTemplate.path),
configuration,
),
);
}),
)),
);

@@ -314,3 +327,3 @@ }

createMultipleFileInfos = (templatesToRender, configuration) => {
createMultipleFileInfos = async (templatesToRender, configuration) => {
const { routes } = configuration;

@@ -322,3 +335,3 @@ const { fileNames, generateRouteTypes, generateClient } = configuration.config;

if (generateRouteTypes) {
const outOfModuleRouteContent = this.templates.renderTemplate(templatesToRender.routeTypes, {
const outOfModuleRouteContent = await this.templates.renderTemplate(templatesToRender.routeTypes, {
...configuration,

@@ -333,3 +346,3 @@ route: configuration.routes.$outOfModule,

if (generateClient) {
const outOfModuleApiContent = this.templates.renderTemplate(templatesToRender.api, {
const outOfModuleApiContent = await this.templates.renderTemplate(templatesToRender.api, {
...configuration,

@@ -346,33 +359,25 @@ route: configuration.routes.$outOfModule,

if (routes.combined) {
modularApiFileInfos.push(
..._.reduce(
routes.combined,
(apiFileInfos, route) => {
if (generateRouteTypes) {
const routeModuleContent = this.templates.renderTemplate(templatesToRender.routeTypes, {
...configuration,
route,
});
for await (const route of routes.combined) {
if (generateRouteTypes) {
const routeModuleContent = await this.templates.renderTemplate(templatesToRender.routeTypes, {
...configuration,
route,
});
apiFileInfos.push(
this.createOutputFileInfo(configuration, pascalCase(`${route.moduleName}_Route`), routeModuleContent),
);
}
modularApiFileInfos.push(
this.createOutputFileInfo(configuration, pascalCase(`${route.moduleName}_Route`), routeModuleContent),
);
}
if (generateClient) {
const apiModuleContent = this.templates.renderTemplate(templatesToRender.api, {
...configuration,
route,
});
if (generateClient) {
const apiModuleContent = await this.templates.renderTemplate(templatesToRender.api, {
...configuration,
route,
});
apiFileInfos.push(
this.createOutputFileInfo(configuration, pascalCase(route.moduleName), apiModuleContent),
);
}
return apiFileInfos;
},
[],
),
);
modularApiFileInfos.push(
this.createOutputFileInfo(configuration, pascalCase(route.moduleName), apiModuleContent),
);
}
}
}

@@ -384,3 +389,3 @@

fileNames.dataContracts,
this.templates.renderTemplate(templatesToRender.dataContracts, configuration),
await this.templates.renderTemplate(templatesToRender.dataContracts, configuration),
),

@@ -391,3 +396,3 @@ generateClient &&

fileNames.httpClient,
this.templates.renderTemplate(templatesToRender.httpClient, configuration),
await this.templates.renderTemplate(templatesToRender.httpClient, configuration),
),

@@ -398,3 +403,3 @@ ...modularApiFileInfos,

createSingleFileInfo = (templatesToRender, configuration) => {
createSingleFileInfo = async (templatesToRender, configuration) => {
const { generateRouteTypes, generateClient } = configuration.config;

@@ -407,6 +412,6 @@

_.compact([
this.templates.renderTemplate(templatesToRender.dataContracts, configuration),
generateRouteTypes && this.templates.renderTemplate(templatesToRender.routeTypes, configuration),
generateClient && this.templates.renderTemplate(templatesToRender.httpClient, configuration),
generateClient && this.templates.renderTemplate(templatesToRender.api, configuration),
await this.templates.renderTemplate(templatesToRender.dataContracts, configuration),
generateRouteTypes && (await this.templates.renderTemplate(templatesToRender.routeTypes, configuration)),
generateClient && (await this.templates.renderTemplate(templatesToRender.httpClient, configuration)),
generateClient && (await this.templates.renderTemplate(templatesToRender.api, configuration)),
]).join("\n"),

@@ -413,0 +418,0 @@ ),

@@ -266,3 +266,3 @@ const { objectAssign } = require("./util/object-assign");

* https://json-schema.org/understanding-json-schema/reference/string.html#dates-and-times
* @type {Record<string, string | ((schema: any, parser: SchemaParser) => string) | ({ $default: string } & Record<string, string | ((schema: any, parser: SchemaParser) => string)>)>}
* @type {Record<string, string | ((schema: any, parser: SchemaProcessor) => string) | ({ $default: string } & Record<string, string | ((schema: any, parser: SchemaParser) => string)>)>}
*/

@@ -298,6 +298,2 @@ primitiveTypes = {

},
array: ({ items, ...schemaPart }, parser) => {
const content = parser.getInlineParseContent(items);
return parser.schemaUtils.safeAddNullToType(schemaPart, this.Ts.ArrayType(content));
},
};

@@ -304,0 +300,0 @@

@@ -14,3 +14,3 @@ const { SCHEMA_TYPES } = require("../constants");

/**
* @type {SchemaParser}
* @type {SchemaProcessor}
*/

@@ -46,3 +46,3 @@ schemaParser;

},
[SCHEMA_TYPES.OBJECT]: (parsedSchema) => {
[SCHEMA_TYPES.OBJECT]: async (parsedSchema) => {
if (parsedSchema.nullable) return this.inline[SCHEMA_TYPES.OBJECT](parsedSchema);

@@ -52,3 +52,3 @@ return {

$content: parsedSchema.content,
content: this.formatObjectContent(parsedSchema.content),
content: await this.formatObjectContent(parsedSchema.content),
};

@@ -77,3 +77,3 @@ },

},
[SCHEMA_TYPES.OBJECT]: (parsedSchema) => {
[SCHEMA_TYPES.OBJECT]: async (parsedSchema) => {
if (_.isString(parsedSchema.content)) {

@@ -93,3 +93,3 @@ return {

parsedSchema.content.length
? this.config.Ts.ObjectWrapper(this.formatObjectContent(parsedSchema.content))
? this.config.Ts.ObjectWrapper(await this.formatObjectContent(parsedSchema.content))
: this.config.Ts.RecordType(Ts.Keyword.String, this.config.Ts.Keyword.Any),

@@ -103,8 +103,9 @@ ),

* @param parsedSchema {Record<string, any>}
* @param formatType {"base" | "inline"}
* @param cfg {{ formatType?: "base" | "inline", schemaType?: string } }
*/
formatSchema = (parsedSchema, formatType = "base") => {
const schemaType = _.get(parsedSchema, ["schemaType"]) || _.get(parsedSchema, ["$parsed", "schemaType"]);
formatSchema = async (parsedSchema, { schemaType: outerSchemaType, formatType = "base" } = {}) => {
const schemaType =
outerSchemaType || _.get(parsedSchema, ["schemaType"]) || _.get(parsedSchema, ["$parsed", "schemaType"]);
const formatterFn = _.get(this, [formatType, schemaType]);
return (formatterFn && formatterFn(parsedSchema)) || parsedSchema;
return (formatterFn && (await formatterFn(parsedSchema))) || parsedSchema;
};

@@ -135,20 +136,24 @@

formatObjectContent = (content) => {
return _.map(content, (part) => {
const extraSpace = " ";
const result = `${extraSpace}${part.field},\n`;
formatObjectContent = async (content) => {
return (
await Promise.all(
_.map(content, async (part) => {
const extraSpace = " ";
const result = `${extraSpace}${part.field},\n`;
const renderedJsDoc = this.templates.renderTemplate(this.config.templatesToRender.dataContractJsDoc, {
data: part,
});
const renderedJsDoc = await this.templates.renderTemplate(this.config.templatesToRender.dataContractJsDoc, {
data: part,
});
const routeNameFromTemplate = renderedJsDoc
.split("\n")
.map((c) => `${extraSpace}${c}`)
.join("\n");
const routeNameFromTemplate = renderedJsDoc
.split("\n")
.map((c) => `${extraSpace}${c}`)
.join("\n");
if (routeNameFromTemplate) return `${routeNameFromTemplate}${result}`;
if (routeNameFromTemplate) return `${routeNameFromTemplate}${result}`;
return `${result}`;
}).join("");
return `${result}`;
}),
)
).join("");
};

@@ -155,0 +160,0 @@ }

@@ -1,8 +0,7 @@

const { SCHEMA_TYPES } = require("../constants.js");
const { SchemaFormatters } = require("./schema-formatters");
const { SchemaUtils } = require("./schema-utils");
const { SCHEMA_TYPES } = require("../constants");
const _ = require("lodash");
const { SchemaFormatters } = require("./schema-formatters");
const { internalCase } = require("../util/internal-case");
const { SchemaUtils } = require("./schema-utils");
const { camelCase } = require("lodash");
const { pascalCase } = require("../util/pascal-case");

@@ -14,3 +13,2 @@ class SchemaParser {

config;
/**

@@ -21,5 +19,5 @@ * @type {SchemaComponentsMap}

/**
* @type {TypeName}
* @type {TypeNameFormatter}
*/
typeName;
typeNameFormatter;
/**

@@ -35,18 +33,39 @@ * @type {SchemaFormatters}

$processingSchemaPath = [];
schemaPath = [];
constructor(config, logger, templates, schemaComponentsMap, typeName) {
typeName;
schema;
constructor(
config,
schemaComponentsMap,
typeNameFormatter,
schemaFormatters,
schemaUtils,
schema,
typeName = null,
schemaPath = [],
) {
this.config = config;
this.schemaComponentsMap = schemaComponentsMap;
this.typeNameFormatter = typeNameFormatter;
this.schemaFormatters = schemaFormatters;
this.schemaUtils = schemaUtils;
this.schema = schema;
this.typeName = typeName;
this.schemaFormatters = new SchemaFormatters(config, logger, this, templates);
this.schemaUtils = new SchemaUtils(config, schemaComponentsMap);
this.schemaPath = schemaPath;
}
complexSchemaParsers = {
_complexSchemaParsers = {
// T1 | T2
[SCHEMA_TYPES.COMPLEX_ONE_OF]: (schema) => {
[SCHEMA_TYPES.COMPLEX_ONE_OF]: async (schema) => {
const ignoreTypes = [this.config.Ts.Keyword.Any];
const combined = _.map(schema.oneOf, (childSchema) =>
this.getInlineParseContent(this.schemaUtils.makeAddRequiredToChildSchema(schema, childSchema)),
const combined = await Promise.all(
_.map(schema.oneOf, (childSchema) =>
this.createParser(
this.schemaUtils.makeAddRequiredToChildSchema(schema, childSchema),
undefined,
this.schemaPath,
).getInlineContent(),
),
);

@@ -60,6 +79,12 @@ const filtered = this.schemaUtils.filterSchemaContents(combined, (content) => !ignoreTypes.includes(content));

// T1 & T2
[SCHEMA_TYPES.COMPLEX_ALL_OF]: (schema) => {
[SCHEMA_TYPES.COMPLEX_ALL_OF]: async (schema) => {
const ignoreTypes = [...this.config.jsPrimitiveTypes, this.config.Ts.Keyword.Any];
const combined = _.map(schema.allOf, (childSchema) =>
this.getInlineParseContent(this.schemaUtils.makeAddRequiredToChildSchema(schema, childSchema)),
const combined = await Promise.all(
_.map(schema.allOf, (childSchema) =>
this.createParser(
this.schemaUtils.makeAddRequiredToChildSchema(schema, childSchema),
undefined,
this.schemaPath,
).getInlineContent(),
),
);

@@ -73,6 +98,12 @@ const filtered = this.schemaUtils.filterSchemaContents(combined, (content) => !ignoreTypes.includes(content));

// T1 | T2 | (T1 & T2)
[SCHEMA_TYPES.COMPLEX_ANY_OF]: (schema) => {
[SCHEMA_TYPES.COMPLEX_ANY_OF]: async (schema) => {
const ignoreTypes = [...this.config.jsPrimitiveTypes, this.config.Ts.Keyword.Any];
const combined = _.map(schema.anyOf, (childSchema) =>
this.getInlineParseContent(this.schemaUtils.makeAddRequiredToChildSchema(schema, childSchema)),
const combined = await Promise.all(
_.map(schema.anyOf, (childSchema) =>
this.createParser(
this.schemaUtils.makeAddRequiredToChildSchema(schema, childSchema),
undefined,
this.schemaPath,
).getInlineContent(),
),
);

@@ -96,9 +127,9 @@ const filtered = this.schemaUtils.filterSchemaContents(combined, (content) => !ignoreTypes.includes(content));

};
baseSchemaParsers = {
[SCHEMA_TYPES.ENUM]: (schema, typeName) => {
_baseSchemaParsers = {
[SCHEMA_TYPES.ENUM]: async (schema, typeName) => {
if (this.config.extractEnums && !typeName) {
const generatedTypeName = this.config.componentTypeNameResolver.resolve([this.buildTypeNameFromPath()]);
const schemaComponent = this.schemaComponentsMap.createComponent("schemas", generatedTypeName, { ...schema });
return this.parseSchema(schemaComponent, generatedTypeName);
const parser = this.createParser(schemaComponent, generatedTypeName);
return await parser.parse();
}

@@ -110,3 +141,3 @@

if (Array.isArray(schema.enum) && Array.isArray(schema.enum[0])) {
return this.parseSchema(
return await this.createParser(
{

@@ -119,17 +150,18 @@ oneOf: schema.enum.map((enumNames) => ({

typeName,
);
this.schemaPath,
).parse();
}
const keyType = this.getSchemaType(schema);
const keyType = await this.schemaUtils.getSchemaType(schema);
const enumNames = this.schemaUtils.getEnumNames(schema);
let content = null;
const formatValue = (value) => {
const formatValue = async (value) => {
if (value === null) {
return this.config.Ts.NullValue(value);
}
if (keyType === this.getSchemaType({ type: "number" })) {
if (keyType === (await this.schemaUtils.getSchemaType({ type: "number" }))) {
return this.config.Ts.NumberValue(value);
}
if (keyType === this.getSchemaType({ type: "boolean" })) {
if (keyType === (await this.schemaUtils.getSchemaType({ type: "boolean" }))) {
return this.config.Ts.BooleanValue(value);

@@ -142,37 +174,41 @@ }

if (_.isArray(enumNames) && _.size(enumNames)) {
content = _.map(enumNames, (enumName, index) => {
const enumValue = _.get(schema.enum, index);
const formattedKey =
(enumName &&
this.typeName.format(enumName, {
content = await Promise.all(
_.map(enumNames, async (enumName, index) => {
const enumValue = _.get(schema.enum, index);
const formattedKey =
(enumName &&
this.typeNameFormatter.format(enumName, {
type: "enum-key",
})) ||
this.typeNameFormatter.format(`${enumValue}`, {
type: "enum-key",
})) ||
this.typeName.format(`${enumValue}`, {
type: "enum-key",
});
});
if (this.config.enumNamesAsValues || _.isUndefined(enumValue)) {
if (this.config.enumNamesAsValues || _.isUndefined(enumValue)) {
return {
key: formattedKey,
type: this.config.Ts.Keyword.String,
value: this.config.Ts.StringValue(enumName),
};
}
return {
key: formattedKey,
type: this.config.Ts.Keyword.String,
value: this.config.Ts.StringValue(enumName),
type: keyType,
value: await formatValue(enumValue),
};
}
return {
key: formattedKey,
type: keyType,
value: formatValue(enumValue),
};
});
}),
);
} else {
content = _.map(schema.enum, (key) => {
return {
key: this.typeName.format(`${key}`, {
type: "enum-key",
}),
type: keyType,
value: formatValue(key),
};
});
content = await Promise.all(
_.map(schema.enum, async (key) => {
return {
key: this.typeNameFormatter.format(`${key}`, {
type: "enum-key",
}),
type: keyType,
value: await formatValue(key),
};
}),
);
}

@@ -194,5 +230,51 @@

},
[SCHEMA_TYPES.OBJECT]: (schema, typeName) => {
const contentProperties = this.getObjectSchemaContent(schema);
[SCHEMA_TYPES.OBJECT]: async (schema, typeName) => {
const { properties, additionalProperties } = schema || {};
const contentProperties = [];
const propertyEntries = _.entries(properties);
for await (const [name, property] of propertyEntries) {
this.schemaPath.push(name);
const required = this.schemaUtils.isPropertyRequired(name, property, schema);
const rawTypeData = _.get(this.schemaUtils.getSchemaRefType(property), "rawTypeData", {});
const nullable = !!(rawTypeData.nullable || property.nullable);
const fieldName = this.typeNameFormatter.isValidName(name) ? name : this.config.Ts.StringValue(name);
const fieldValue = await this.createParser(property, null, this.schemaPath).getInlineContent();
const readOnly = property.readOnly;
this.schemaPath.pop();
contentProperties.push({
...property,
$$raw: property,
title: property.title,
description:
property.description ||
_.compact(_.map(property[this.schemaUtils.getComplexType(property)], "description"))[0] ||
rawTypeData.description ||
_.compact(_.map(rawTypeData[this.schemaUtils.getComplexType(rawTypeData)], "description"))[0] ||
"",
isRequired: required,
isNullable: nullable,
name: fieldName,
value: fieldValue,
field: this.config.Ts.TypeField({
readonly: readOnly && this.config.addReadonly,
optional: !required,
key: fieldName,
value: fieldValue,
}),
});
}
if (additionalProperties) {
contentProperties.push({
$$raw: { additionalProperties },
description: "",
isRequired: false,
field: this.config.Ts.InterfaceDynamicField(this.config.Ts.Keyword.String, this.config.Ts.Keyword.Any),
});
}
return {

@@ -210,6 +292,6 @@ ...(_.isObject(schema) ? schema : {}),

},
[SCHEMA_TYPES.COMPLEX]: (schema, typeName) => {
const complexType = this.getComplexType(schema);
const simpleSchema = _.omit(_.clone(schema), _.keys(this.complexSchemaParsers));
const complexSchemaContent = this.complexSchemaParsers[complexType](schema);
[SCHEMA_TYPES.COMPLEX]: async (schema, typeName) => {
const complexType = this.schemaUtils.getComplexType(schema);
const simpleSchema = _.omit(_.clone(schema), _.keys(this._complexSchemaParsers));
const complexSchemaContent = await this._complexSchemaParsers[complexType](schema);

@@ -230,4 +312,6 @@ return {

this.config.Ts.ExpressionGroup(complexSchemaContent),
this.getInternalSchemaType(simpleSchema) === SCHEMA_TYPES.OBJECT &&
this.config.Ts.ExpressionGroup(this.getInlineParseContent(simpleSchema)),
this.schemaUtils.getInternalSchemaType(simpleSchema) === SCHEMA_TYPES.OBJECT &&
this.config.Ts.ExpressionGroup(
await this.createParser(simpleSchema, null, this.schemaPath).getInlineContent(),
),
]),

@@ -237,3 +321,28 @@ ) || this.config.Ts.Keyword.Any,

},
[SCHEMA_TYPES.PRIMITIVE]: (schema, typeName) => {
[SCHEMA_TYPES.ARRAY]: async (schema, typeName) => {
let contentType;
const { type, description, items } = schema || {};
if (_.isArray(items) && type === SCHEMA_TYPES.ARRAY) {
const tupleContent = await Promise.all(
items.map((item) => this.createParser(item, null, this.schemaPath).getInlineContent()),
);
contentType = this.config.Ts.Tuple(tupleContent);
} else {
const content = await this.createParser(items, null, this.schemaPath).getInlineContent();
contentType = this.config.Ts.ArrayType(content);
}
return {
...(_.isObject(schema) ? schema : {}),
$parsedSchema: true,
schemaType: SCHEMA_TYPES.PRIMITIVE,
type: SCHEMA_TYPES.PRIMITIVE,
typeIdentifier: this.config.Ts.Keyword.Type,
name: typeName,
description: this.schemaFormatters.formatDescription(description),
content: this.schemaUtils.safeAddNullToType(schema, contentType),
};
},
[SCHEMA_TYPES.PRIMITIVE]: async (schema, typeName) => {
let contentType = null;

@@ -244,3 +353,3 @@ const { additionalProperties, type, description, items } = schema || {};

const fieldType = _.isObject(additionalProperties)
? this.getInlineParseContent(additionalProperties)
? await this.createParser(additionalProperties, null, this.schemaPath).getInlineContent()
: this.config.Ts.Keyword.Any;

@@ -251,3 +360,3 @@ contentType = this.config.Ts.RecordType(this.config.Ts.Keyword.String, fieldType);

if (_.isArray(type) && type.length) {
contentType = this.complexSchemaParsers.oneOf({
contentType = await this._complexSchemaParsers.oneOf({
...(_.isObject(schema) ? schema : {}),

@@ -259,3 +368,5 @@ oneOf: type.map((type) => ({ type })),

if (_.isArray(items) && type === SCHEMA_TYPES.ARRAY) {
contentType = this.config.Ts.Tuple(items.map((item) => this.getInlineParseContent(item)));
contentType = this.config.Ts.Tuple(
await Promise.all(items.map((item) => this.createParser(item, null, this.schemaPath).getInlineContent())),
);
}

@@ -272,3 +383,4 @@

// TODO: probably it should be refactored. `type === 'null'` is not flexible
content: type === this.config.Ts.Keyword.Null ? type : contentType || this.getSchemaType(schema),
content:
type === this.config.Ts.Keyword.Null ? type : contentType || (await this.schemaUtils.getSchemaType(schema)),
};

@@ -278,103 +390,10 @@ },

getInternalSchemaType = (schema) => {
if (!_.isEmpty(schema.enum) || !_.isEmpty(this.schemaUtils.getEnumNames(schema))) return SCHEMA_TYPES.ENUM;
if (schema.allOf || schema.oneOf || schema.anyOf || schema.not) return SCHEMA_TYPES.COMPLEX;
if (!_.isEmpty(schema.properties)) return SCHEMA_TYPES.OBJECT;
buildTypeNameFromPath = () => {
const schemaPath = _.uniq(_.compact(this.schemaPath));
return SCHEMA_TYPES.PRIMITIVE;
};
if (!schemaPath || !schemaPath[0]) return null;
getSchemaType = (schema) => {
if (!schema) return this.config.Ts.Keyword.Any;
const refTypeInfo = this.schemaUtils.getSchemaRefType(schema);
if (refTypeInfo) {
return this.schemaUtils.checkAndAddRequiredKeys(
schema,
this.schemaUtils.safeAddNullToType(schema, this.typeName.format(refTypeInfo.typeName)),
);
}
const primitiveType = this.schemaUtils.getSchemaPrimitiveType(schema);
if (primitiveType == null) return this.config.Ts.Keyword.Any;
let resultType;
const typeAlias =
_.get(this.config.primitiveTypes, [primitiveType, schema.format]) ||
_.get(this.config.primitiveTypes, [primitiveType, "$default"]) ||
this.config.primitiveTypes[primitiveType];
if (_.isFunction(typeAlias)) {
resultType = typeAlias(schema, this);
} else {
resultType = typeAlias || primitiveType;
}
if (!resultType) return this.config.Ts.Keyword.Any;
return this.schemaUtils.checkAndAddRequiredKeys(schema, this.schemaUtils.safeAddNullToType(schema, resultType));
return internalCase(camelCase(`${schemaPath[0]}_${schemaPath[schemaPath.length - 1]}`));
};
getObjectSchemaContent = (schema) => {
const { properties, additionalProperties } = schema || {};
const propertiesContent = _.map(properties, (property, name) => {
this.$processingSchemaPath.push(name);
const required = this.schemaUtils.isPropertyRequired(name, property, schema);
const rawTypeData = _.get(this.schemaUtils.getSchemaRefType(property), "rawTypeData", {});
const nullable = !!(rawTypeData.nullable || property.nullable);
const fieldName = this.typeName.isValidName(name) ? name : this.config.Ts.StringValue(name);
const fieldValue = this.getInlineParseContent(property);
const readOnly = property.readOnly;
this.$processingSchemaPath.pop();
return {
...property,
$$raw: property,
title: property.title,
description:
property.description ||
_.compact(_.map(property[this.getComplexType(property)], "description"))[0] ||
rawTypeData.description ||
_.compact(_.map(rawTypeData[this.getComplexType(rawTypeData)], "description"))[0] ||
"",
isRequired: required,
isNullable: nullable,
name: fieldName,
value: fieldValue,
field: this.config.Ts.TypeField({
readonly: readOnly && this.config.addReadonly,
optional: !required,
key: fieldName,
value: fieldValue,
}),
};
});
if (additionalProperties) {
propertiesContent.push({
$$raw: { additionalProperties },
description: "",
isRequired: false,
field: this.config.Ts.InterfaceDynamicField(this.config.Ts.Keyword.String, this.config.Ts.Keyword.Any),
});
}
return propertiesContent;
};
getComplexType = (schema) => {
if (schema.oneOf) return SCHEMA_TYPES.COMPLEX_ONE_OF;
if (schema.allOf) return SCHEMA_TYPES.COMPLEX_ALL_OF;
if (schema.anyOf) return SCHEMA_TYPES.COMPLEX_ANY_OF;
// TODO :(
if (schema.not) return SCHEMA_TYPES.COMPLEX_NOT;
return SCHEMA_TYPES.COMPLEX_UNKNOWN;
};
/**

@@ -385,6 +404,6 @@ *

* @param formatter {"inline" | "base"}
* @return {Record<string, any>}
* @return {Promise<Record<string, any>>}
*/
parseSchema = (schema, typeName = null) => {
if (!schema) return this.baseSchemaParsers[SCHEMA_TYPES.PRIMITIVE](null, typeName);
parse = async () => {
if (!this.schema) return await this._baseSchemaParsers[SCHEMA_TYPES.PRIMITIVE](null, this.typeName);

@@ -394,47 +413,98 @@ let schemaType = null;

if (typeof schema === "string") {
return schema;
if (typeof this.schema === "string") {
return this.schema;
}
if (!schema.$parsed) {
if (!typeName && this.schemaUtils.isRefSchema(schema)) {
typeName = this.getSchemaType(schema);
if (!this.schema.$parsed) {
if (!this.typeName && this.schemaUtils.isRefSchema(this.schema)) {
this.typeName = await this.schemaUtils.getSchemaType(this.schema);
}
if (schema.items && !Array.isArray(schema.items) && !schema.type) {
schema.type = SCHEMA_TYPES.ARRAY;
if (this.schema.items && !Array.isArray(this.schema.items) && !this.schema.type) {
this.schema.type = SCHEMA_TYPES.ARRAY;
}
schemaType = this.getInternalSchemaType(schema);
schemaType = this.schemaUtils.getInternalSchemaType(this.schema);
this.$processingSchemaPath.push(typeName);
this.schemaPath.push(this.typeName);
_.merge(schema, this.config.hooks.onPreParseSchema(schema, typeName, schemaType));
parsedSchema = this.baseSchemaParsers[schemaType](schema, typeName);
schema.$parsed = this.config.hooks.onParseSchema(schema, parsedSchema) || parsedSchema;
_.merge(this.schema, this.config.hooks.onPreParseSchema(this.schema, this.typeName, schemaType));
parsedSchema = await this._baseSchemaParsers[schemaType](this.schema, this.typeName);
this.schema.$parsed = this.config.hooks.onParseSchema(this.schema, parsedSchema) || parsedSchema;
}
this.$processingSchemaPath.pop();
this.schemaPath.pop();
return schema.$parsed;
return this.schema.$parsed;
};
getInlineParseContent = (rawTypeData, typeName) => {
const parsedSchema = this.parseSchema(rawTypeData, typeName);
const formattedSchema = this.schemaFormatters.formatSchema(parsedSchema, "inline");
return formattedSchema.content;
/**
* @param cfg {{ formatType?: "base" | "inline", schemaType?: string } }
* @return {Promise<Record<string, any>>}
*/
format = async (cfg) => {
const parsedSchema = await this.parse();
return await this.schemaFormatters.formatSchema(parsedSchema, cfg);
};
getParseContent = (rawTypeData, typeName) => {
const parsedSchema = this.parseSchema(rawTypeData, typeName);
const formattedSchema = this.schemaFormatters.formatSchema(parsedSchema, "base");
return formattedSchema.content;
getInlineContent = async () => {
const schema = await this.format({ formatType: "inline" });
return schema.content;
};
buildTypeNameFromPath = () => {
const schemaPath = _.uniq(_.compact(this.$processingSchemaPath));
getContent = async () => {
const schema = await this.format({ formatType: "base" });
return schema.content;
};
if (!schemaPath || !schemaPath[0]) return null;
/**
* @param {Record<string, any>} [schema]
* @param {string | null | undefined} [typeName]
* @param {string[] | undefined} [schemaPath]
* @return {SchemaParser}
*/
createParser = (schema, typeName, schemaPath) => {
return new SchemaParser(
this.config,
this.schemaComponentsMap,
this.typeNameFormatter,
this.schemaFormatters,
this.schemaUtils,
schema,
typeName,
schemaPath,
);
};
return internalCase(camelCase(`${schemaPath[0]}_${schemaPath[schemaPath.length - 1]}`));
};
/**
* @param config {CodeGenConfig}
* @param schemaComponentsMap {SchemaComponentsMap}
* @param typeNameFormatter {TypeNameFormatter}
* @param schemaFormatters {SchemaFormatters}
* @param schemaUtils {SchemaUtils}
* @param {Record<string, any>} [schema]
* @param {string | null | undefined} [typeName]
* @param {string[] | undefined} [schemaPath]
* @return {SchemaParser}
*/
static create(
config,
schemaComponentsMap,
typeNameFormatter,
schemaFormatters,
schemaUtils,
schema,
typeName,
schemaPath,
) {
return new SchemaParser(
config,
schemaComponentsMap,
typeNameFormatter,
schemaFormatters,
schemaUtils,
schema,
typeName,
schemaPath,
);
}
}

@@ -441,0 +511,0 @@

@@ -28,3 +28,3 @@ const _ = require("lodash");

/**
* @type {SchemaParser}
* @type {SchemaProcessor}
*/

@@ -37,3 +37,3 @@ schemaParser;

/**
* @type {TypeName}
* @type {TypeNameFormatter}
*/

@@ -69,6 +69,8 @@ typeName;

this.templates = templates;
}
async init() {
this.FORM_DATA_TYPES = _.uniq([
this.schemaParser.getSchemaType({ type: "string", format: "file" }),
this.schemaParser.getSchemaType({ type: "string", format: "binary" }),
await this.schemaUtils.getSchemaType({ type: "string", format: "file" }),
await this.schemaUtils.getSchemaType({ type: "string", format: "binary" }),
]);

@@ -314,3 +316,3 @@ }

getTypeFromRequestInfo = ({ requestInfo, parsedSchemas, operationId, defaultType, typeName }) => {
getTypeFromRequestInfo = async ({ requestInfo, parsedSchemas, operationId, defaultType, typeName }) => {
// TODO: make more flexible pick schema without content type

@@ -321,3 +323,3 @@ const schema = this.getSchemaFromRequestType(requestInfo);

if (schema) {
const content = this.schemaParser.getInlineParseContent(schema, typeName);
const content = await this.schemaParser.getInlineParseContent(schema, typeName);
const foundedSchemaByName = _.find(

@@ -349,3 +351,3 @@ parsedSchemas,

case "requestBodies":
return this.schemaParser.getInlineParseContent(
return await this.schemaParser.getInlineParseContent(
this.getSchemaFromRequestType(refTypeInfo.rawTypeData),

@@ -355,3 +357,3 @@ refTypeInfo.typeName || null,

default:
return this.schemaParser.getInlineParseContent(refTypeInfo.rawTypeData, refTypeInfo.typeName || null);
return await this.schemaParser.getInlineParseContent(refTypeInfo.rawTypeData, refTypeInfo.typeName || null);
}

@@ -363,33 +365,35 @@ }

getRequestInfoTypes = ({ requestInfos, parsedSchemas, operationId, defaultType }) =>
_.reduce(
requestInfos,
(acc, requestInfo, status) => {
const contentTypes = this.getContentTypes([requestInfo]);
getRequestInfoTypes = async ({ requestInfos, parsedSchemas, operationId, defaultType }) => {
const requestInfoTypes = [];
return [
...acc,
{
...(requestInfo || {}),
contentTypes: contentTypes,
contentKind: this.getContentKind(contentTypes),
type: this.schemaParser.schemaUtils.safeAddNullToType(
requestInfo,
this.getTypeFromRequestInfo({
requestInfo,
parsedSchemas,
operationId,
defaultType,
}),
),
description: this.schemaParser.schemaFormatters.formatDescription(requestInfo.description || "", true),
status: _.isNaN(+status) ? status : +status,
isSuccess: this.isSuccessStatus(status),
},
];
},
[],
);
const statuses = _.entries(requestInfos);
getResponseBodyInfo = (routeInfo, routeParams, parsedSchemas) => {
for await (const [status, requestInfo] of statuses) {
const contentTypes = this.getContentTypes([requestInfo]);
const requestInfoType = {
...(requestInfo || {}),
contentTypes: contentTypes,
contentKind: this.getContentKind(contentTypes),
type: this.schemaParser.schemaUtils.safeAddNullToType(
requestInfo,
await this.getTypeFromRequestInfo({
requestInfo,
parsedSchemas,
operationId,
defaultType,
}),
),
description: this.schemaParser.schemaFormatters.formatDescription(requestInfo.description || "", true),
status: _.isNaN(+status) ? status : +status,
isSuccess: this.isSuccessStatus(status),
};
requestInfoTypes.push(requestInfoType);
}
return requestInfoTypes;
};
getResponseBodyInfo = async (routeInfo, routeParams, parsedSchemas) => {
const { produces, operationId, responses } = routeInfo;

@@ -399,3 +403,3 @@

const responseInfos = this.getRequestInfoTypes({
const responseInfos = await this.getRequestInfoTypes({
requestInfos: responses,

@@ -412,3 +416,3 @@ parsedSchemas,

const handleResponseHeaders = (src) => {
const handleResponseHeaders = async (src) => {
if (!src) {

@@ -418,5 +422,7 @@ return "headers: {},";

const headerTypes = Object.fromEntries(
Object.entries(src).map(([k, v]) => {
return [k, this.schemaParser.getSchemaType(v)];
}),
await Promise.all(
Object.entries(src).map(async ([k, v]) => {
return [k, await this.schemaUtils.getSchemaType(v)];
}),
),
);

@@ -443,7 +449,9 @@ const r = `headers: { ${Object.entries(headerTypes)

this.config.Ts.UnionType(
responseInfos.map(
(response) => `{
await Promise.all(
responseInfos.map(
async (response) => `{
data: ${response.type}, status: ${response.status}, statusCode: ${response.status}, statusText: "${
response.description
}", ${handleResponseHeaders(response.headers)} config: {} }`,
response.description
}", ${await handleResponseHeaders(response.headers)} config: {} }`,
),
),

@@ -479,3 +487,3 @@ ) || this.config.Ts.Keyword.Any,

getRequestBodyInfo = (routeInfo, routeParams, parsedSchemas, routeName) => {
getRequestBodyInfo = async (routeInfo, routeParams, parsedSchemas, routeName) => {
const { requestBody, consumes, requestBodyName, operationId } = routeInfo;

@@ -501,6 +509,6 @@ let schema = null;

schema = this.convertRouteParamsIntoObject(routeParams.formData);
type = this.schemaParser.getInlineParseContent(schema, typeName);
type = await this.schemaParser.getInlineParseContent(schema, typeName);
} else if (contentKind === CONTENT_KIND.FORM_DATA) {
schema = this.getSchemaFromRequestType(requestBody);
type = this.schemaParser.getInlineParseContent(schema, typeName);
type = await this.schemaParser.getInlineParseContent(schema, typeName);
} else if (requestBody) {

@@ -510,3 +518,3 @@ schema = this.getSchemaFromRequestType(requestBody);

requestBody,
this.getTypeFromRequestInfo({
await this.getTypeFromRequestInfo({
requestInfo: requestBody,

@@ -529,3 +537,3 @@ parsedSchemas,

schema = this.schemaComponentMap.createComponent("schemas", typeName, { ...schema });
type = this.schemaParser.getInlineParseContent(schema);
type = await this.schemaParser.getInlineParseContent(schema);
}

@@ -607,3 +615,3 @@

extractResponseBodyIfItNeeded = (routeInfo, responseBodyInfo, routeName) => {
extractResponseBodyIfItNeeded = async (routeInfo, responseBodyInfo, routeName) => {
if (responseBodyInfo.responses.length && responseBodyInfo.success && responseBodyInfo.success.schema) {

@@ -623,3 +631,3 @@ const typeName = this.schemaUtils.resolveTypeName(

successResponse.schema = this.schemaComponentMap.createComponent("schemas", typeName, { ...schema });
successResponse.type = this.schemaParser.getInlineParseContent(successResponse.schema);
successResponse.type = await this.schemaParser.getInlineParseContent(successResponse.schema);

@@ -636,3 +644,3 @@ if (idx > -1) {

extractResponseErrorIfItNeeded = (routeInfo, responseBodyInfo, routeName) => {
extractResponseErrorIfItNeeded = async (routeInfo, responseBodyInfo, routeName) => {
if (responseBodyInfo.responses.length && responseBodyInfo.error.schemas && responseBodyInfo.error.schemas.length) {

@@ -649,3 +657,3 @@ const typeName = this.schemaUtils.resolveTypeName(

const schema = this.schemaParser.parseSchema({
const schema = await this.schemaParser.parseSchema({
oneOf: errorSchemas,

@@ -667,3 +675,3 @@ title: errorSchemas

getRouteName = (rawRouteInfo) => {
getRouteName = async (rawRouteInfo) => {
const { moduleName } = rawRouteInfo;

@@ -673,3 +681,3 @@ const { routeNameDuplicatesMap, templatesToRender } = this.config;

const routeNameFromTemplate = this.templates.renderTemplate(routeNameTemplate, {
const routeNameFromTemplate = await this.templates.renderTemplate(routeNameTemplate, {
routeInfo: rawRouteInfo,

@@ -706,3 +714,3 @@ });

parseRouteInfo = (rawRouteName, routeInfo, method, usageSchema, parsedSchemas) => {
parseRouteInfo = async (rawRouteName, routeInfo, method, usageSchema, parsedSchemas) => {
const { security: globalSecurity } = usageSchema;

@@ -743,11 +751,13 @@ const { moduleNameIndex, moduleNameFirstTag, extractRequestParams } = this.config;

const pathArgs = routeParams.path.map((pathArgSchema) => ({
name: pathArgSchema.name,
optional: !pathArgSchema.required,
type: this.schemaParser.getInlineParseContent(pathArgSchema.schema),
description: pathArgSchema.description,
}));
const pathArgs = await Promise.all(
routeParams.path.map(async (pathArgSchema) => ({
name: pathArgSchema.name,
optional: !pathArgSchema.required,
type: await this.schemaParser.getInlineParseContent(pathArgSchema.schema),
description: pathArgSchema.description,
})),
);
const pathArgsNames = pathArgs.map((arg) => arg.name);
const responseBodyInfo = this.getResponseBodyInfo(routeInfo, routeParams, parsedSchemas);
const responseBodyInfo = await this.getResponseBodyInfo(routeInfo, routeParams, parsedSchemas);

@@ -775,5 +785,5 @@ const rawRouteInfo = {

const routeName = this.getRouteName(rawRouteInfo);
const routeName = await this.getRouteName(rawRouteInfo);
const requestBodyInfo = this.getRequestBodyInfo(routeInfo, routeParams, parsedSchemas, routeName);
const requestBodyInfo = await this.getRequestBodyInfo(routeInfo, routeParams, parsedSchemas, routeName);

@@ -789,11 +799,15 @@ const requestParamsSchema = this.createRequestParamsSchema({

if (this.config.extractResponseBody) {
this.extractResponseBodyIfItNeeded(routeInfo, responseBodyInfo, routeName);
await this.extractResponseBodyIfItNeeded(routeInfo, responseBodyInfo, routeName);
}
if (this.config.extractResponseError) {
this.extractResponseErrorIfItNeeded(routeInfo, responseBodyInfo, routeName);
await this.extractResponseErrorIfItNeeded(routeInfo, responseBodyInfo, routeName);
}
const queryType = routeParams.query.length ? this.schemaParser.getInlineParseContent(queryObjectSchema) : null;
const pathType = routeParams.path.length ? this.schemaParser.getInlineParseContent(pathObjectSchema) : null;
const headersType = routeParams.header.length ? this.schemaParser.getInlineParseContent(headersObjectSchema) : null;
const queryType = routeParams.query.length
? await this.schemaParser.getInlineParseContent(queryObjectSchema)
: null;
const pathType = routeParams.path.length ? await this.schemaParser.getInlineParseContent(pathObjectSchema) : null;
const headersType = routeParams.header.length
? await this.schemaParser.getInlineParseContent(headersObjectSchema)
: null;

@@ -806,3 +820,3 @@ const nameResolver = new SpecificArgNameResolver(this.logger, pathArgsNames);

name: nameResolver.resolve(RESERVED_QUERY_ARG_NAMES),
optional: this.schemaParser.parseSchema(queryObjectSchema).allFieldsAreOptional,
optional: (await this.schemaParser.parseSchema(queryObjectSchema)).allFieldsAreOptional,
type: queryType,

@@ -821,3 +835,3 @@ }

name: nameResolver.resolve(RESERVED_PATH_ARG_NAMES),
optional: this.schemaParser.parseSchema(pathObjectSchema).allFieldsAreOptional,
optional: (await this.schemaParser.parseSchema(pathObjectSchema)).allFieldsAreOptional,
type: pathType,

@@ -829,3 +843,3 @@ }

name: nameResolver.resolve(RESERVED_HEADER_ARG_NAMES),
optional: this.schemaParser.parseSchema(headersObjectSchema).allFieldsAreOptional,
optional: (await this.schemaParser.parseSchema(headersObjectSchema)).allFieldsAreOptional,
type: headersType,

@@ -875,3 +889,3 @@ }

attachSchema = ({ usageSchema, parsedSchemas }) => {
attachSchema = async ({ usageSchema, parsedSchemas }) => {
this.config.routeNameDuplicatesMap.clear();

@@ -881,7 +895,7 @@

_.forEach(pathsEntries, ([rawRouteName, routeInfoByMethodsMap]) => {
for await (const [rawRouteName, routeInfoByMethodsMap] of pathsEntries) {
const routeInfosMap = this.createRequestsMap(routeInfoByMethodsMap);
_.forEach(routeInfosMap, (routeInfo, method) => {
const parsedRouteInfo = this.parseRouteInfo(rawRouteName, routeInfo, method, usageSchema, parsedSchemas);
for await (const [method, routeInfo] of _.entries(routeInfosMap)) {
const parsedRouteInfo = await this.parseRouteInfo(rawRouteName, routeInfo, method, usageSchema, parsedSchemas);
const processedRouteInfo = this.config.hooks.onCreateRoute(parsedRouteInfo);

@@ -901,4 +915,4 @@ const route = processedRouteInfo || parsedRouteInfo;

this.routes.push(route);
});
});
}
}
};

@@ -905,0 +919,0 @@

@@ -15,6 +15,11 @@ const _ = require("lodash");

schemaComponentsMap;
/**
* @type {TypeNameFormatter}
*/
typeNameFormatter;
constructor(config, schemaComponentsMap) {
constructor(config, schemaComponentsMap, typeNameFormatter) {
this.config = config;
this.schemaComponentsMap = schemaComponentsMap;
this.typeNameFormatter = typeNameFormatter;
}

@@ -145,2 +150,58 @@

getComplexType = (schema) => {
if (schema.oneOf) return SCHEMA_TYPES.COMPLEX_ONE_OF;
if (schema.allOf) return SCHEMA_TYPES.COMPLEX_ALL_OF;
if (schema.anyOf) return SCHEMA_TYPES.COMPLEX_ANY_OF;
// TODO :(
if (schema.not) return SCHEMA_TYPES.COMPLEX_NOT;
return SCHEMA_TYPES.COMPLEX_UNKNOWN;
};
getInternalSchemaType = (schema) => {
if (!_.isEmpty(schema.enum) || !_.isEmpty(this.getEnumNames(schema))) return SCHEMA_TYPES.ENUM;
if (schema.allOf || schema.oneOf || schema.anyOf || schema.not) return SCHEMA_TYPES.COMPLEX;
if (!_.isEmpty(schema.properties)) return SCHEMA_TYPES.OBJECT;
if (schema.type === SCHEMA_TYPES.ARRAY) return SCHEMA_TYPES.ARRAY;
return SCHEMA_TYPES.PRIMITIVE;
};
getSchemaType = async (schema) => {
if (!schema) return this.config.Ts.Keyword.Any;
const refTypeInfo = this.getSchemaRefType(schema);
if (refTypeInfo) {
return this.checkAndAddRequiredKeys(
schema,
this.safeAddNullToType(schema, this.typeNameFormatter.format(refTypeInfo.typeName)),
);
}
const primitiveType = this.getSchemaPrimitiveType(schema);
if (primitiveType == null) return this.config.Ts.Keyword.Any;
let resultType;
/**
* @type {string | (() => Promise<string>)}
*/
const typeAlias =
_.get(this.config.primitiveTypes, [primitiveType, schema.format]) ||
_.get(this.config.primitiveTypes, [primitiveType, "$default"]) ||
this.config.primitiveTypes[primitiveType];
if (_.isFunction(typeAlias)) {
resultType = await typeAlias(schema, this);
} else {
resultType = typeAlias || primitiveType;
}
if (!resultType) return this.config.Ts.Keyword.Any;
return this.checkAndAddRequiredKeys(schema, this.safeAddNullToType(schema, resultType));
};
filterSchemaContents = (contents, filterFn) => {

@@ -147,0 +208,0 @@ return _.uniq(_.filter(contents, (type) => filterFn(type)));

@@ -155,19 +155,24 @@ const { resolve } = require("path");

renderTemplate = (template, configuration, options) => {
renderTemplate = async (template, configuration, options) => {
if (!template) return "";
return Eta.render(
template,
{
...this.getRenderTemplateData(),
...configuration,
},
{
async: false,
...(options || {}),
includeFile: (path, configuration, options) => {
return this.renderTemplate(this.getTemplateContent(path), configuration, options);
try {
return await Eta.renderAsync(
template,
{
...this.getRenderTemplateData(),
...configuration,
},
},
);
{
async: true,
...(options || {}),
includeFile: async (path, configuration, options) => {
return await this.renderTemplate(this.getTemplateContent(path), configuration, options);
},
},
);
} catch (e) {
console.error("problem in this templates\n", template);
throw e;
}
};

@@ -174,0 +179,0 @@ }

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet