@infinite-debugger/swagger-to-ts
Version:
swagger-to-ts is a powerful library that allows you to generate TypeScript code from Swagger documentation or OpenAPI specifications. It simplifies the process of integrating API definitions into your TypeScript projects, saving you time and effort.
321 lines • 29.3 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.getModelsReferencedByPropertyType = exports.generatePropertySchemaCode = void 0;
const models_1 = require("../../models");
const Utils_1 = require("../Utils");
const BooleanSchemaCodeGenerator_1 = require("./BooleanSchemaCodeGenerator");
const NullSchemaCodeGenerator_1 = require("./NullSchemaCodeGenerator");
const NumberSchemaCodeGenerator_1 = require("./NumberSchemaCodeGenerator");
const StringSchemaCodeGenerator_1 = require("./StringSchemaCodeGenerator");
/**
* Generates string schema code for a given schema
*
* @param options The options to generate string schema code
* @returns The generated string schema code
*/
const generatePropertySchemaCode = (options) => {
const { propertySchema, schema, schemaName, propertyName, generateTsEDControllers, } = options;
const referencedSchemas = [];
const generatedVariables = {};
const imports = {
zod: ['z'],
};
const propertySchemaCodeConfiguration = {
openAPISpecification: propertySchema,
propertyName,
accessModifier: 'public',
decorators: [],
required: Boolean(schema.required?.includes(propertyName)),
isNullable: propertySchema.nullable,
zodCodeString: `z.any()`,
propertyModels: [],
propertyType: `any`,
};
if ('$ref' in propertySchema) {
const referencedSchemaName = propertySchema.$ref.replace('#/components/schemas/', '');
referencedSchemas.push(referencedSchemaName);
propertySchemaCodeConfiguration.propertyModels.push(referencedSchemaName);
propertySchemaCodeConfiguration.propertyType = referencedSchemaName;
propertySchemaCodeConfiguration.zodCodeString = `${referencedSchemaName}ValidationSchema`;
}
else if ('type' in propertySchema) {
const { decorators, ...rest } = (() => {
const baseOptions = {
generatedVariables,
generateTsEDControllers,
imports,
propertyName,
schemaName,
schema: propertySchema,
};
switch (propertySchema.type) {
case 'string':
return (0, StringSchemaCodeGenerator_1.generateStringSchemaCode)({
...baseOptions,
schema: propertySchema,
});
case 'boolean':
return (0, BooleanSchemaCodeGenerator_1.generateBooleanSchemaCode)({
...baseOptions,
schema: propertySchema,
});
case 'integer':
case 'number':
return (0, NumberSchemaCodeGenerator_1.generateNumberSchemaCode)({
...baseOptions,
schema: propertySchema,
});
case 'null':
return (0, NullSchemaCodeGenerator_1.generateNullSchemaCode)({
...baseOptions,
schema: propertySchema,
});
case 'object':
if ('additionalProperties' in propertySchema &&
typeof propertySchema.additionalProperties === 'object') {
const { propertyType, zodCodeString, imports: propertyImports, generatedVariables: propertyGeneratedVariables, } = (0, exports.generatePropertySchemaCode)({
...options,
propertySchema: propertySchema.additionalProperties,
});
Object.assign(generatedVariables, propertyGeneratedVariables);
Object.entries(propertyImports).forEach(([path, importVariables]) => {
if (!(path in imports)) {
imports[path] = [];
}
imports[path].push(...importVariables.filter((importVariable) => {
return !imports[path].includes(importVariable);
}));
});
const propertyModels = (0, exports.getModelsReferencedByPropertyType)(propertyType);
referencedSchemas.push(...propertyModels.filter((modelName) => {
return (!models_1.primitiveTypeModels.includes(modelName) &&
!referencedSchemas.includes(modelName));
}));
const decorators = [...propertySchemaCodeConfiguration.decorators];
if (generateTsEDControllers) {
(0, Utils_1.addModuleImport)({
imports,
importName: 'AdditionalProperties',
importFilePath: models_1.TSED_SCHEMA_LIBRARY_PATH,
});
}
if (typeof propertySchema.additionalProperties === 'object' &&
'$ref' in propertySchema.additionalProperties) {
const referencedSchemaName = propertySchema.additionalProperties.$ref.replace('#/components/schemas/', '');
decorators.push(`@AdditionalProperties(${referencedSchemaName})`);
}
else if (typeof propertySchema.additionalProperties === 'object' &&
'type' in propertySchema.additionalProperties &&
propertySchema.additionalProperties.type === 'array' &&
propertySchema.additionalProperties.items &&
'$ref' in propertySchema.additionalProperties.items) {
const referencedSchemaName = propertySchema.additionalProperties.items.$ref.replace('#/components/schemas/', '');
const serializedAdditionalProperties = JSON.stringify(propertySchema.additionalProperties, null, 2).replace(/"items"\:\s*\{[\s\S]*?\}/gm, `"items": { "type": ${referencedSchemaName}}`);
decorators.push(`@AdditionalProperties(${serializedAdditionalProperties})`);
}
else {
decorators.push(`@AdditionalProperties(${JSON.stringify(propertySchema.additionalProperties, null, 2)})`);
}
return {
...propertySchemaCodeConfiguration,
propertyType: `Record<string, ${propertyType}>`,
zodCodeString: `z.record(${zodCodeString})`,
decorators,
};
}
return propertySchemaCodeConfiguration;
case 'array':
if (propertySchema.items) {
const { propertyType, zodCodeString, decorators: itemDecorators, imports: propertyImports, generatedVariables: propertyGeneratedVariables, } = (0, exports.generatePropertySchemaCode)({
...options,
propertySchema: propertySchema.items,
});
Object.assign(generatedVariables, propertyGeneratedVariables);
Object.entries(propertyImports).forEach(([path, importVariables]) => {
if (!(path in imports)) {
imports[path] = [];
}
imports[path].push(...importVariables.filter((importVariable) => {
return !imports[path].includes(importVariable);
}));
});
const isEnum = 'enum' in propertySchema.items;
const decorators = [...propertySchemaCodeConfiguration.decorators];
decorators.push(...itemDecorators.filter((decorator) => {
return !decorators.includes(decorator);
}));
if (!isEnum) {
const propertyModels = (0, exports.getModelsReferencedByPropertyType)(propertyType);
referencedSchemas.push(...propertyModels.filter((modelName) => {
return (!models_1.primitiveTypeModels.includes(modelName) &&
!referencedSchemas.includes(modelName));
}));
if (propertyModels.length === 1) {
if (generateTsEDControllers) {
(0, Utils_1.addModuleImport)({
imports,
importName: 'ArrayOf',
importFilePath: models_1.TSED_SCHEMA_LIBRARY_PATH,
});
}
decorators.push(`@ArrayOf(${propertyModels[0]})`);
}
}
return {
...propertySchemaCodeConfiguration,
propertyType: `(${propertyType})[]`,
zodCodeString: `z.array(${zodCodeString})`,
decorators,
};
}
return {
...propertySchemaCodeConfiguration,
propertyType: `any[]`,
zodCodeString: `z.array(z.any())`,
};
}
})();
if (decorators) {
propertySchemaCodeConfiguration.decorators.push(...decorators);
}
Object.assign(propertySchemaCodeConfiguration, rest);
}
else if ('oneOf' in propertySchema) {
const propertySchemas = propertySchema.oneOf.map((oneOfPropertySchema) => {
return (0, exports.generatePropertySchemaCode)({
...options,
propertySchema: oneOfPropertySchema,
});
});
const propertyTypes = propertySchemas.map(({ propertyType }) => propertyType);
if (propertyTypes.includes('any')) {
propertySchemaCodeConfiguration.decorators.push(`@Any()`);
propertySchemaCodeConfiguration.propertyType = 'any';
if (generateTsEDControllers) {
(0, Utils_1.addModuleImport)({
imports,
importName: 'Any',
importFilePath: models_1.TSED_SCHEMA_LIBRARY_PATH,
});
}
propertySchemaCodeConfiguration.zodCodeString = `z.any()`;
propertySchemaCodeConfiguration.isNullable = false;
}
else {
const propertyModels = propertyTypes.flatMap((propertyType) => {
return (0, exports.getModelsReferencedByPropertyType)(propertyType);
});
propertySchemaCodeConfiguration.decorators.push(`@OneOf(${propertyModels.join(', ')})`);
propertySchemaCodeConfiguration.propertyType = propertyTypes.join(' | ');
referencedSchemas.push(...propertyModels.filter((modelName) => {
return (!models_1.primitiveTypeModels.includes(modelName) &&
!referencedSchemas.includes(modelName));
}));
if (generateTsEDControllers) {
(0, Utils_1.addModuleImport)({
imports,
importName: 'OneOf',
importFilePath: models_1.TSED_SCHEMA_LIBRARY_PATH,
});
}
propertySchemaCodeConfiguration.zodCodeString =
propertySchemas.length > 1
? `z.union([${propertySchemas
.map(({ zodCodeString }) => zodCodeString)
.join(',')}])`
: propertySchemas[0].zodCodeString;
propertySchemas.forEach(({ generatedVariables: propertyGeneratedVariables }) => {
Object.assign(generatedVariables, propertyGeneratedVariables);
});
}
}
else if ('anyOf' in propertySchema) {
const propertySchemas = propertySchema.anyOf.map((anyOfPropertySchema) => {
return (0, exports.generatePropertySchemaCode)({
...options,
propertySchema: anyOfPropertySchema,
});
});
const propertyTypes = propertySchemas.map(({ propertyType }) => propertyType);
if (propertyTypes.includes('any')) {
propertySchemaCodeConfiguration.decorators.push(`@Any()`);
propertySchemaCodeConfiguration.propertyType = 'any';
if (generateTsEDControllers) {
(0, Utils_1.addModuleImport)({
imports,
importName: 'Any',
importFilePath: models_1.TSED_SCHEMA_LIBRARY_PATH,
});
}
propertySchemaCodeConfiguration.zodCodeString = `z.any()`;
propertySchemaCodeConfiguration.isNullable = false;
}
else {
const propertyModels = propertyTypes.flatMap((propertyType) => {
return (0, exports.getModelsReferencedByPropertyType)(propertyType);
});
propertySchemaCodeConfiguration.decorators.push(`@AnyOf(${propertyModels.join(', ')})`);
propertySchemaCodeConfiguration.propertyType = propertyTypes.join(' | ');
referencedSchemas.push(...propertyModels.filter((modelName) => {
return (!models_1.primitiveTypeModels.includes(modelName) &&
!referencedSchemas.includes(modelName));
}));
if (generateTsEDControllers) {
(0, Utils_1.addModuleImport)({
imports,
importName: 'AnyOf',
importFilePath: models_1.TSED_SCHEMA_LIBRARY_PATH,
});
}
propertySchemaCodeConfiguration.zodCodeString =
propertySchemas.length > 1
? `z.any()`
: propertySchemas[0].zodCodeString;
propertySchemas.forEach(({ generatedVariables: propertyGeneratedVariables }) => {
Object.assign(generatedVariables, propertyGeneratedVariables);
});
}
}
if (propertySchemaCodeConfiguration.required) {
if (generateTsEDControllers) {
(0, Utils_1.addModuleImport)({
imports,
importName: 'Required',
importFilePath: models_1.TSED_SCHEMA_LIBRARY_PATH,
});
}
if (!propertySchemaCodeConfiguration.decorators.includes(`@Required()`)) {
propertySchemaCodeConfiguration.decorators.push(`@Required()`);
}
}
return {
...propertySchemaCodeConfiguration,
referencedSchemas,
imports,
generatedVariables,
};
};
exports.generatePropertySchemaCode = generatePropertySchemaCode;
/**
* Gets the models referenced by a property type
*
* @param propertyType The property type to get the models referenced by
* @returns The models referenced by the property type
*/
const getModelsReferencedByPropertyType = (propertyType) => {
return propertyType
.replace(/\[\]$/g, '')
.replace(/^\(|\)$/g, '')
.split(' | ')
.filter((propertyType) => {
return propertyType != 'any';
})
.map((propertyType) => {
if (propertyType.match(/".+"/g)) {
return 'String';
}
return models_1.primitiveTypeToModelMapping[propertyType] ?? propertyType;
});
};
exports.getModelsReferencedByPropertyType = getModelsReferencedByPropertyType;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiUHJvcGVydHlTY2hlbWFDb2RlR2VuZXJhdG9yLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2FwaS9Nb2RlbENvZGVHZW5lcmF0b3IvUHJvcGVydHlTY2hlbWFDb2RlR2VuZXJhdG9yLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLHlDQUtzQjtBQUV0QixvQ0FBMkM7QUFDM0MsNkVBQXlFO0FBS3pFLHVFQUFtRTtBQUNuRSwyRUFBdUU7QUFDdkUsMkVBQXVFO0FBNkJ2RTs7Ozs7R0FLRztBQUNJLE1BQU0sMEJBQTBCLEdBQUcsQ0FDeEMsT0FBMEMsRUFDMUMsRUFBRTtJQUNGLE1BQU0sRUFDSixjQUFjLEVBQ2QsTUFBTSxFQUNOLFVBQVUsRUFDVixZQUFZLEVBQ1osdUJBQXVCLEdBQ3hCLEdBQUcsT0FBTyxDQUFDO0lBQ1osTUFBTSxpQkFBaUIsR0FBYSxFQUFFLENBQUM7SUFDdkMsTUFBTSxrQkFBa0IsR0FBMkIsRUFBRSxDQUFDO0lBQ3RELE1BQU0sT0FBTyxHQUFrQjtRQUM3QixHQUFHLEVBQUUsQ0FBQyxHQUFHLENBQUM7S0FDWCxDQUFDO0lBQ0YsTUFBTSwrQkFBK0IsR0FBNEI7UUFDL0Qsb0JBQW9CLEVBQUUsY0FBYztRQUNwQyxZQUFZO1FBQ1osY0FBYyxFQUFFLFFBQVE7UUFDeEIsVUFBVSxFQUFFLEVBQUU7UUFDZCxRQUFRLEVBQUUsT0FBTyxDQUFDLE1BQU0sQ0FBQyxRQUFRLEVBQUUsUUFBUSxDQUFDLFlBQVksQ0FBQyxDQUFDO1FBQzFELFVBQVUsRUFBRSxjQUFjLENBQUMsUUFBUTtRQUNuQyxhQUFhLEVBQUUsU0FBUztRQUN4QixjQUFjLEVBQUUsRUFBRTtRQUNsQixZQUFZLEVBQUUsS0FBSztLQUNwQixDQUFDO0lBRUYsSUFBSSxNQUFNLElBQUksY0FBYyxFQUFFO1FBQzVCLE1BQU0sb0JBQW9CLEdBQUcsY0FBYyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQ3RELHVCQUF1QixFQUN2QixFQUFF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