|
1 | 1 | import type {Input} from "../../../core/input" |
2 | 2 | import {isDefined, titleCase} from "../../../core/utils" |
3 | 3 | import type {ImportBuilder} from "../../common/import-builder" |
4 | | -import {JoiBuilder} from "../../common/schema-builders/joi-schema-builder" |
5 | 4 | import type {SchemaBuilder} from "../../common/schema-builders/schema-builder" |
6 | | -import {ZodBuilder} from "../../common/schema-builders/zod-schema-builder" |
7 | 5 | import type {TypeBuilder} from "../../common/type-builder" |
8 | 6 | import {constStatement} from "../../common/type-utils" |
9 | 7 | import {buildExport} from "../../common/typescript-common" |
10 | | -import { |
11 | | - AbstractRouterBuilder, |
12 | | - type ServerSymbols, |
13 | | -} from "../abstract-router-builder" |
14 | | -import type {ServerOperationBuilder} from "../server-operation-builder" |
| 8 | +import {AbstractRouterBuilder} from "../abstract-router-builder" |
| 9 | +import type { |
| 10 | + ServerOperationBuilder, |
| 11 | + ServerSymbols, |
| 12 | +} from "../server-operation-builder" |
15 | 13 |
|
16 | 14 | export class TypescriptNextjsRouterBuilder extends AbstractRouterBuilder { |
17 | 15 | private readonly operationTypes: { |
@@ -51,38 +49,44 @@ export class TypescriptNextjsRouterBuilder extends AbstractRouterBuilder { |
51 | 49 | .from("@nahkies/typescript-nextjs-runtime/errors") |
52 | 50 | .add("OpenAPIRuntimeError", "RequestInputType") |
53 | 51 |
|
54 | | - if (this.schemaBuilder instanceof ZodBuilder) { |
55 | | - this.imports |
56 | | - .from("@nahkies/typescript-nextjs-runtime/zod") |
57 | | - .add("parseRequestInput", "responseValidationFactory") |
58 | | - } else if (this.schemaBuilder instanceof JoiBuilder) { |
59 | | - this.imports |
60 | | - .from("@nahkies/typescript-nextjs-runtime/joi") |
61 | | - .add("parseRequestInput", "responseValidationFactory") |
| 52 | + const schemaBuilderType = this.schemaBuilder.type |
| 53 | + |
| 54 | + switch (schemaBuilderType) { |
| 55 | + case "joi": { |
| 56 | + this.imports |
| 57 | + .from("@nahkies/typescript-nextjs-runtime/joi") |
| 58 | + .add("parseRequestInput", "responseValidationFactory") |
| 59 | + break |
| 60 | + } |
| 61 | + case "zod-v3": |
| 62 | + case "zod-v4": { |
| 63 | + this.imports |
| 64 | + .from("@nahkies/typescript-nextjs-runtime/zod") |
| 65 | + .add("parseRequestInput", "responseValidationFactory") |
| 66 | + break |
| 67 | + } |
| 68 | + default: { |
| 69 | + throw new Error( |
| 70 | + `unsupported schema builder type '${schemaBuilderType satisfies never}'`, |
| 71 | + ) |
| 72 | + } |
62 | 73 | } |
63 | 74 | } |
64 | 75 |
|
65 | 76 | protected buildOperation(builder: ServerOperationBuilder): string { |
66 | 77 | const statements: string[] = [] |
67 | 78 |
|
68 | 79 | const symbols = this.operationSymbols(builder.operationId) |
69 | | - const params = builder.parameters(symbols) |
| 80 | + const params = builder.parameters() |
70 | 81 |
|
71 | 82 | if (params.path.schema) { |
72 | | - statements.push(constStatement(symbols.paramSchema, params.path.schema)) |
| 83 | + statements.push(constStatement(params.path.name, params.path.schema)) |
73 | 84 | } |
74 | 85 | if (params.query.schema) { |
75 | | - statements.push(constStatement(symbols.querySchema, params.query.schema)) |
| 86 | + statements.push(constStatement(params.query.name, params.query.schema)) |
76 | 87 | } |
77 | 88 | if (params.header.schema) { |
78 | | - statements.push( |
79 | | - constStatement(symbols.requestHeaderSchema, params.header.schema), |
80 | | - ) |
81 | | - } |
82 | | - if (params.body.schema) { |
83 | | - statements.push( |
84 | | - constStatement(symbols.requestBodySchema, params.body.schema), |
85 | | - ) |
| 89 | + statements.push(constStatement(params.header.name, params.header.schema)) |
86 | 90 | } |
87 | 91 |
|
88 | 92 | const responseSchemas = builder.responseSchemas() |
@@ -122,23 +126,24 @@ try { |
122 | 126 | const input = { |
123 | 127 | params: ${ |
124 | 128 | params.path.schema |
125 | | - ? `parseRequestInput(${symbols.paramSchema}, await params, RequestInputType.RouteParam)` |
| 129 | + ? `parseRequestInput(${params.path.name}, await params, RequestInputType.RouteParam)` |
126 | 130 | : "undefined" |
127 | 131 | }, |
128 | 132 | // TODO: this swallows repeated parameters |
129 | 133 | query: ${ |
130 | 134 | params.query.schema |
131 | | - ? `parseRequestInput(${symbols.querySchema}, Object.fromEntries(request.nextUrl.searchParams.entries()), RequestInputType.QueryString)` |
| 135 | + ? `parseRequestInput(${params.query.name}, Object.fromEntries(request.nextUrl.searchParams.entries()), RequestInputType.QueryString)` |
132 | 136 | : "undefined" |
133 | 137 | }, |
| 138 | + ${params.body.schema && !params.body.isSupported ? `// todo: request bodies with content-type '${params.body.contentType}' not yet supported\n` : ""} |
134 | 139 | body: ${ |
135 | 140 | params.body.schema |
136 | | - ? `parseRequestInput(${symbols.requestBodySchema}, await request.json(), RequestInputType.RequestBody)` |
| 141 | + ? `parseRequestInput(${params.body.schema}, await request.json(), RequestInputType.RequestBody)${!params.body.isSupported ? " as never" : ""}` |
137 | 142 | : "undefined" |
138 | 143 | }, |
139 | 144 | headers: ${ |
140 | 145 | params.header.schema |
141 | | - ? `parseRequestInput(${symbols.requestHeaderSchema}, Reflect.get(request, "headers"), RequestInputType.RequestHeader)` |
| 146 | + ? `parseRequestInput(${params.header.name}, Reflect.get(request, "headers"), RequestInputType.RequestHeader)` |
142 | 147 | : "undefined" |
143 | 148 | } |
144 | 149 | } |
@@ -172,10 +177,6 @@ try { |
172 | 177 | implPropName: operationId, |
173 | 178 | implTypeName: titleCase(operationId), |
174 | 179 | responderName: `${titleCase(operationId)}Responder`, |
175 | | - paramSchema: `${operationId}ParamSchema`, |
176 | | - querySchema: `${operationId}QuerySchema`, |
177 | | - requestBodySchema: `${operationId}BodySchema`, |
178 | | - requestHeaderSchema: `${operationId}HeaderSchema`, |
179 | 180 | responseBodyValidator: `${operationId}ResponseValidator`, |
180 | 181 | } |
181 | 182 | } |
|
0 commit comments