openapi-metadata
Version:
Auto-Generate OpenAPI specifications from Typescript decorators
108 lines (104 loc) • 3.21 kB
JavaScript
;
const _enum = require('../utils/enum.cjs');
const property = require('../metadata/property.cjs');
const schema = require('../utils/schema.cjs');
const metadata = require('../utils/metadata.cjs');
const PrimitiveTypeLoader = async (_context, value) => {
if (typeof value === "string") {
return { type: value };
}
if (value == String) {
return { type: "string" };
}
if (value == Boolean) {
return { type: "boolean" };
}
if (value == Number) {
return { type: "number" };
}
};
const ArrayTypeLoader = async (context, value) => {
if (!Array.isArray(value)) {
return;
}
if (value.length <= 0) {
context.logger.warn("You tried to specify an array type without any item");
return;
}
if (value.length > 1) {
context.logger.warn(
"You tried to specify an array type with multiple items. Please use the 'enum' option if you want to specify an enum."
);
return;
}
const itemsSchema = await loadType(context, { type: value[0] });
if (!itemsSchema) {
context.logger.warn("You tried to specify an array type with an item that resolves to undefined.");
return;
}
return {
type: "array",
items: itemsSchema
};
};
const ClassTypeLoader = async (context, value) => {
if (typeof value !== "function" || !value.prototype) {
return;
}
const model = value.name;
if (context.schemas[model]) {
return { $ref: schema.getSchemaPath(model) };
}
const schema$1 = {
type: "object",
properties: {},
required: []
};
const properties = property.PropertyMetadataStorage.getMetadata(value.prototype);
if (!properties) {
context.logger.warn(`You tried to use '${model}' as a type but it does not contain any ApiProperty.`);
}
context.schemas[model] = schema$1;
for (const [key, property] of Object.entries(properties)) {
const { required, type, name, enum: e, schema: s, ...metadata } = property;
schema$1.properties[key] = {
...await loadType(context, property),
...metadata
};
if (property.required) {
schema$1.required.push(key);
}
}
return { $ref: schema.getSchemaPath(model) };
};
async function loadType(context, options) {
if (options.schema) {
return options.schema;
}
if (options.enum) {
const enumValues = _enum.getEnumValues(options.enum);
const enumType = _enum.getEnumType(enumValues);
return {
type: enumType,
enum: enumValues
};
}
if (!options.type) {
context.logger.warn("Failed to infer type from property");
return;
}
const thunk = metadata.isThunk(options.type);
const value = thunk ? options.type(context) : options.type;
for (const loader of [PrimitiveTypeLoader, ArrayTypeLoader, ...context.typeLoaders, ClassTypeLoader]) {
const result = await loader(context, value, options.type);
if (result) {
return result;
}
}
context.logger.warn(`You tried to use '${options.type.toString()}' as a type but no loader supports it ${thunk}`);
}
exports.ArrayTypeLoader = ArrayTypeLoader;
exports.ClassTypeLoader = ClassTypeLoader;
exports.PrimitiveTypeLoader = PrimitiveTypeLoader;
exports.loadType = loadType;
//# sourceMappingURL=type.cjs.map