UNPKG

turtle-express

Version:

`turtle-express` is kinda a framework or a library based on `express.js` with an opinionated express router with type safety and schema validation with zod. Also many [more features](https://github.com/mm-ninja-turtles/turtle-express/discussions/7) planni

163 lines 5.57 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.createOpenApiJsonElement = exports.zodToOpenApiJson = void 0; const zod_1 = require("zod"); const lodash_es_1 = require("lodash-es"); /** * Function to convert each ZodType schema to OpenAPI Request, Parameter, Response schemas. */ function zodToOpenApiJson(schema) { const { type } = schema._openApi; const openApiJsonElement = createOpenApiJsonElement(schema); if (type === 'Response') { const mediaType = schema._openApi.mediaType ?? 'application/json'; const response = { description: openApiJsonElement.description ?? '', content: { [mediaType]: { schema: openApiJsonElement, }, }, }; return response; } if (type === 'RequestQuery' || type === 'RequestParam') { const parameters = []; Object.keys(openApiJsonElement?.properties ?? {}).forEach((key) => { parameters.push({ name: key, in: type === 'RequestQuery' ? 'query' : 'path', schema: openApiJsonElement?.properties?.[key], }); }); return parameters; } if (type === 'RequestBody') { const mediaType = schema._openApi.mediaType ?? 'application/json'; const requestBody = { description: openApiJsonElement.description ?? '', content: { [mediaType]: { schema: openApiJsonElement, }, }, }; return requestBody; } return openApiJsonElement; } exports.zodToOpenApiJson = zodToOpenApiJson; /** * @Credit https://github.com/kbkk/abitia/blob/master/packages/zod-dto/src/OpenApi/zodTypeToOpenApi.ts * The following function code is inspired and reused some from the above package. * * Return the OpenAPI schema for a Zod type. */ function createOpenApiJsonElement(schema) { const schemaDef = schema._def; function createOpenApi(extendSchema) { const title = schema?._openApi?.title ?? ''; const type = schema?._openApi?.type ?? ''; const transformedTitle = (0, lodash_es_1.chain)(`${title} ${type}`) .camelCase() .upperFirst() .value(); return { required: true, ...extendSchema, operationId: transformedTitle ?? '', title: transformedTitle ?? '', description: schemaDef?.description ?? '', }; } switch (schema.constructor.name) { case zod_1.z.ZodObject.name: { const shape = schemaDef.shape(); const shapeKeys = Object.keys(shape); const properties = {}; shapeKeys.forEach((key) => { const property = createOpenApiJsonElement(shape[key]); properties[key] = property; }); return createOpenApi({ type: 'object', properties, }); } case zod_1.z.ZodOptional.name: { return createOpenApi({ ...createOpenApiJsonElement(schemaDef.innerType), required: false, }); } case zod_1.z.ZodNullable.name: { return createOpenApi({ ...createOpenApiJsonElement(schemaDef.innerType), nullable: true, }); } case zod_1.z.ZodTransformer.name: { return createOpenApi({ ...createOpenApiJsonElement(schemaDef.schema), }); } case zod_1.z.ZodEnum.name: { const enumValues = schemaDef.values; return createOpenApi({ type: 'string', enum: enumValues, }); } case zod_1.z.ZodLiteral.name: { return createOpenApi({ type: 'string', enum: [schemaDef.value], }); } case zod_1.z.ZodUnion.name: { const options = schemaDef.options; return createOpenApi({ oneOf: options.map((item) => createOpenApiJsonElement(item)), }); } case zod_1.z.ZodTuple.name: { const items = schemaDef.items; return createOpenApi({ type: 'array', items: { oneOf: items.map((item) => createOpenApiJsonElement(item)), }, minItems: items.length, maxItems: items.length, }); } case zod_1.z.ZodArray.name: { const type = schemaDef.type; return createOpenApi({ type: 'array', items: type ? createOpenApiJsonElement(type) : {}, }); } case zod_1.z.ZodBigInt.name: { return createOpenApi({ type: 'integer', format: 'int64', }); } case zod_1.z.ZodString.name: { return createOpenApi({ type: 'string' }); } case zod_1.z.ZodNumber.name: { return createOpenApi({ type: 'number' }); } case zod_1.z.ZodBoolean.name: { return createOpenApi({ type: 'boolean' }); } case zod_1.z.ZodDefault.name: default: { return createOpenApi({ type: 'string' }); } } } exports.createOpenApiJsonElement = createOpenApiJsonElement; //# sourceMappingURL=zod-to-open-api-json.js.map