openapi-metadata
Version:
Auto-Generate OpenAPI specifications from Typescript decorators
1 lines • 7.41 kB
Source Map (JSON)
{"version":3,"file":"type.cjs","sources":["../../src/loaders/type.ts"],"sourcesContent":["import type { OpenAPIV3 } from \"openapi-types\";\nimport type { Context } from \"../context.js\";\nimport type { TypeLoaderFn, TypeOptions } from \"../types.js\";\nimport type { SetRequired } from \"type-fest\";\nimport { getEnumType, getEnumValues } from \"../utils/enum.js\";\nimport { PropertyMetadataStorage } from \"../metadata/property.js\";\nimport { getSchemaPath } from \"../utils/schema.js\";\nimport { isThunk } from \"../utils/metadata.js\";\n\n/**\n * Type loader to load primitive types.\n */\nexport const PrimitiveTypeLoader: TypeLoaderFn = async (_context, value) => {\n if (typeof value === \"string\") {\n return { type: value };\n }\n\n // biome-ignore lint/suspicious/noDoubleEquals: strict comparaison might fail to catch it\n if (value == String) {\n return { type: \"string\" };\n }\n\n // biome-ignore lint/suspicious/noDoubleEquals: strict comparaison might fail to catch it\n if (value == Boolean) {\n return { type: \"boolean\" };\n }\n\n // biome-ignore lint/suspicious/noDoubleEquals: strict comparaison might fail to catch it\n if (value == Number) {\n return { type: \"number\" };\n }\n};\n\n/**\n * Type loader to load array types.\n */\nexport const ArrayTypeLoader: TypeLoaderFn = async (context, value) => {\n if (!Array.isArray(value)) {\n return;\n }\n\n if (value.length <= 0) {\n context.logger.warn(\"You tried to specify an array type without any item\");\n return;\n }\n\n if (value.length > 1) {\n context.logger.warn(\n \"You tried to specify an array type with multiple items. Please use the 'enum' option if you want to specify an enum.\",\n );\n return;\n }\n\n const itemsSchema = await loadType(context, { type: value[0] });\n\n // TODO: Better warn stack trace\n if (!itemsSchema) {\n context.logger.warn(\"You tried to specify an array type with an item that resolves to undefined.\");\n return;\n }\n\n return {\n type: \"array\",\n items: itemsSchema,\n };\n};\n\n/**\n * Type loader to load classes as SchemaObject.\n */\nexport const ClassTypeLoader: TypeLoaderFn = async (context, value) => {\n if (typeof value !== \"function\" || !value.prototype) {\n return;\n }\n\n const model = value.name;\n\n if (context.schemas[model]) {\n return { $ref: getSchemaPath(model) };\n }\n\n const schema: SetRequired<OpenAPIV3.SchemaObject, \"properties\" | \"required\"> = {\n type: \"object\",\n properties: {},\n required: [],\n };\n\n const properties = PropertyMetadataStorage.getMetadata(value.prototype);\n\n if (!properties) {\n context.logger.warn(`You tried to use '${model}' as a type but it does not contain any ApiProperty.`);\n }\n\n context.schemas[model] = schema;\n\n for (const [key, property] of Object.entries(properties)) {\n const { required, type, name, enum: e, schema: s, ...metadata } = property as any;\n schema.properties[key] = {\n ...(await loadType(context, property)),\n ...metadata,\n };\n\n if (property.required) {\n schema.required.push(key);\n }\n }\n\n return { $ref: getSchemaPath(model) };\n};\n\n/**\n * Transforms a type option into a SchemaObject or ReferenceObject.\n */\nexport async function loadType(\n context: Context,\n options: TypeOptions,\n): Promise<OpenAPIV3.SchemaObject | OpenAPIV3.ReferenceObject | undefined> {\n if (options.schema) {\n return options.schema;\n }\n\n if (options.enum) {\n const enumValues = getEnumValues(options.enum);\n const enumType = getEnumType(enumValues);\n\n return {\n type: enumType,\n enum: enumValues,\n };\n }\n\n if (!options.type) {\n context.logger.warn(\"Failed to infer type from property\");\n return;\n }\n\n const thunk = isThunk(options.type);\n const value = thunk ? (options.type as Function)(context) : options.type;\n\n for (const loader of [PrimitiveTypeLoader, ArrayTypeLoader, ...context.typeLoaders, ClassTypeLoader]) {\n const result = await loader(context, value, options.type);\n if (result) {\n return result;\n }\n }\n\n context.logger.warn(`You tried to use '${options.type.toString()}' as a type but no loader supports it ${thunk}`);\n}\n"],"names":["getSchemaPath","schema","PropertyMetadataStorage","getEnumValues","getEnumType","isThunk"],"mappings":"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"}