{"version":3,"file":"type.mjs","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":[],"mappings":"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"}