File size: 2,949 Bytes
4e23b01 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 | import { envelopeSchema } from '../protocol/envelope';
import { z } from 'zod';
export function jsonSchema(schema: z.ZodTypeAny): Record<string, unknown> {
return jsonSchemaForTarget(schema, 'input', 'draft-7');
}
export function outputJsonSchema(schema: z.ZodTypeAny): Record<string, unknown> {
return jsonSchemaForTarget(schema, 'output', 'draft-7');
}
export function openApiDocumentJsonSchema(
schema: z.ZodTypeAny,
io: 'input' | 'output' = 'input',
): Record<string, unknown> {
return jsonSchemaForTarget(schema, io, 'openapi-3.0');
}
function jsonSchemaForTarget(
schema: z.ZodTypeAny,
io: 'input' | 'output',
target: 'draft-7' | 'openapi-3.0',
): Record<string, unknown> {
const converted = z.toJSONSchema(schema, {
target,
io,
unrepresentable: 'any',
}) as Record<string, unknown>;
if (converted['$schema'] !== undefined) {
delete converted['$schema'];
}
return converted;
}
export function envelopeJsonSchema(
dataSchema: z.ZodTypeAny,
): Record<string, unknown> {
return outputJsonSchema(envelopeSchema(dataSchema));
}
export function openApiDocumentEnvelopeJsonSchema(
dataSchema: z.ZodTypeAny,
): Record<string, unknown> {
return openApiDocumentJsonSchema(envelopeSchema(dataSchema), 'output');
}
export interface RouteSchemaOptions {
body?: z.ZodTypeAny;
querystring?: z.ZodTypeAny;
params?: z.ZodTypeAny;
response?: Record<number, z.ZodTypeAny>;
rawResponse?: Record<number, Record<string, unknown>>;
description?: string;
summary?: string;
tags?: string[];
operationId?: string;
consumes?: string[];
produces?: string[];
}
export function buildRouteSchema(options: RouteSchemaOptions): Record<string, unknown> {
const schema: Record<string, unknown> = {};
if (options.body) {
schema['body'] = jsonSchema(options.body);
}
if (options.querystring) {
schema['querystring'] = jsonSchema(options.querystring);
}
if (options.params) {
schema['params'] = jsonSchema(options.params);
}
if (options.response || options.rawResponse) {
const responses: Record<string, unknown> = {};
if (options.response) {
for (const [code, zodSchema] of Object.entries(options.response)) {
responses[String(code)] = envelopeJsonSchema(zodSchema);
}
}
if (options.rawResponse) {
for (const [code, rawSchema] of Object.entries(options.rawResponse)) {
responses[String(code)] = rawSchema;
}
}
schema['response'] = responses;
}
if (options.description) {
schema['description'] = options.description;
}
if (options.summary) {
schema['summary'] = options.summary;
}
if (options.tags) {
schema['tags'] = options.tags;
}
if (options.operationId) {
schema['operationId'] = options.operationId;
}
if (options.consumes) {
schema['consumes'] = options.consumes;
}
if (options.produces) {
schema['produces'] = options.produces;
}
return schema;
}
|