Skip to content

Commit e5d5b13

Browse files
committed
wip: implement parser
1 parent 54ac767 commit e5d5b13

8 files changed

Lines changed: 546 additions & 6 deletions

File tree

packages/openapi-code-generator/src/typescript/server/server-operation-builder.ts

Lines changed: 67 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import type {Input} from "../../core/input"
22
import {logger} from "../../core/logger"
3-
import type {IROperation} from "../../core/openapi-types-normalized"
3+
import type { IRModel, IROperation } from "../../core/openapi-types-normalized"
44
import {extractPlaceholders} from "../../core/openapi-utils"
55
import type {SchemaBuilder} from "../common/schema-builders/schema-builder"
66
import type {TypeBuilder} from "../common/type-builder"
@@ -33,6 +33,23 @@ export type ServerOperationResponseSchemas = {
3333
| undefined
3434
}
3535

36+
export type PrimitiveType = {type: "string" | "number" | "boolean" | "null"}
37+
export type ObjectSchema = {
38+
type: "object"
39+
properties: Record<string, SchemaStructure>
40+
}
41+
export type ArraySchema = {type: "array"; items: SchemaStructure}
42+
43+
export type SchemaStructure = PrimitiveType | ObjectSchema | ArraySchema
44+
export type Style = "deepObject" | "form" | "pipeDelimited" | "spaceDelimited"
45+
export interface QueryParameter {
46+
name: string
47+
schema: SchemaStructure
48+
style?: Style
49+
explode?: boolean
50+
// allowEmptyValue: boolean
51+
}
52+
3653
export type Parameters = {
3754
type: string
3855
path: {
@@ -44,6 +61,7 @@ export type Parameters = {
4461
name: string
4562
schema: string | undefined
4663
type: string
64+
parameters: QueryParameter[]
4765
}
4866
header: {
4967
name: string
@@ -191,7 +209,54 @@ export class ServerOperationBuilder {
191209
type = this.types.schemaObjectToType($ref)
192210
}
193211

194-
return {name: this.operation.parameters.query.name, schema: schema, type}
212+
213+
return {
214+
name: this.operation.parameters.query.name,
215+
schema: schema,
216+
type,
217+
parameters: this.operation.parameters.query.list.map((it) => ({
218+
name: it.name,
219+
// todo: only default true when style: form
220+
// todo: remove defaulting - normalization does this
221+
explode: it.explode ?? true,
222+
style: it.style ?? "form",
223+
schema: this.queryParameterRuntimeSchema(this.input.schema(it.schema)),
224+
})),
225+
}
226+
}
227+
228+
private queryParameterRuntimeSchema(schema: IRModel): SchemaStructure {
229+
const type = schema.type
230+
switch (type) {
231+
case "string":
232+
case "number":
233+
case "boolean":
234+
return {type}
235+
case "array":
236+
return {
237+
type: "array",
238+
items: this.queryParameterRuntimeSchema(
239+
this.input.schema(schema.items),
240+
),
241+
}
242+
case "object": {
243+
const properties: Record<string, SchemaStructure> = {}
244+
245+
for (const key in schema.properties) {
246+
properties[key] = this.queryParameterRuntimeSchema(
247+
this.input.schema(schema.properties[key] ?? {isIRModel: true, nullable: false, readOnly: false, type: "any"}),
248+
)
249+
}
250+
251+
return {
252+
type: "object",
253+
properties,
254+
}
255+
}
256+
default: {
257+
throw new Error(`unsupported query parameter type ${type}`)
258+
}
259+
}
195260
}
196261

197262
private headerParameters(): Parameters["header"] {

packages/openapi-code-generator/src/typescript/server/typescript-express/typescript-express-router-builder.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,11 @@ export class ExpressRouterBuilder extends AbstractRouterBuilder {
5252
"StatusCode5xx",
5353
)
5454

55+
// todo: move to common imports
56+
this.imports
57+
.from("@nahkies/typescript-koa-runtime/server")
58+
.add("parseQueryParameters")
59+
5560
this.imports
5661
.from("@nahkies/typescript-express-runtime/errors")
5762
.add("ExpressRuntimeError", "RequestInputType")
@@ -138,7 +143,7 @@ router.${builder.method.toLowerCase()}(\`${builder.route}\`, async (req: Request
138143
try {
139144
const input = {
140145
params: ${params.path.schema ? `parseRequestInput(${params.path.name}, req.params, RequestInputType.RouteParam)` : "undefined"},
141-
query: ${params.query.schema ? `parseRequestInput(${params.query.name}, req.query, RequestInputType.QueryString)` : "undefined"},
146+
query: ${params.query.schema ? `parseRequestInput(${params.query.name}, parseQueryParameters(new URL(\`http://localhost\${req.originalUrl}\`).search, ${JSON.stringify(params.query.parameters)}), RequestInputType.QueryString)` : "undefined"},
142147
${params.body.schema && !params.body.isSupported ? `// todo: request bodies with content-type '${params.body.contentType}' not yet supported\n` : ""}body: ${params.body.schema ? `parseRequestInput(${params.body.schema}, req.body, RequestInputType.RequestBody)${!params.body.isSupported ? " as never" : ""}` : "undefined"},
143148
headers: ${params.header.schema ? `parseRequestInput(${params.header.name}, req.headers, RequestInputType.RequestHeader)` : "undefined"}
144149
}

packages/openapi-code-generator/src/typescript/server/typescript-koa/typescript-koa-router-builder.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,14 @@ export class KoaRouterBuilder extends AbstractRouterBuilder {
3131
}
3232

3333
protected buildImports(): void {
34-
// todo: unsure why, but adding an export at `.` of index.ts doesn't work properly
3534
this.imports
3635
.from("@nahkies/typescript-koa-runtime/server")
37-
.add("KoaRuntimeResponse", "SkipResponse", "startServer")
36+
.add(
37+
"KoaRuntimeResponse",
38+
"SkipResponse",
39+
"startServer",
40+
"parseQueryParameters",
41+
)
3842
.addType(
3943
"KoaRuntimeResponder",
4044
"Params",
@@ -142,7 +146,7 @@ const ${symbols.responseBodyValidator} = ${builder.responseValidator()}
142146
router.${builder.method.toLowerCase()}('${symbols.implPropName}','${builder.route}', async (ctx, next) => {
143147
const input = {
144148
params: ${params.path.schema ? `parseRequestInput(${params.path.name}, ctx.params, RequestInputType.RouteParam)` : "undefined"},
145-
query: ${params.query.schema ? `parseRequestInput(${params.query.name}, ctx.query, RequestInputType.QueryString)` : "undefined"},
149+
query: ${params.query.schema ? `parseRequestInput(${params.query.name}, parseQueryParameters(ctx.querystring, ${JSON.stringify(params.query.parameters)}), RequestInputType.QueryString)` : "undefined"},
146150
${params.body.schema && !params.body.isSupported ? `// todo: request bodies with content-type '${params.body.contentType}' not yet supported\n` : ""}body: ${params.body.schema ? `parseRequestInput(${params.body.schema}, Reflect.get(ctx.request, "body"), RequestInputType.RequestBody)${!params.body.isSupported ? " as never" : ""}` : "undefined"},
147151
headers: ${params.header.schema ? `parseRequestInput(${params.header.name}, Reflect.get(ctx.request, "headers"), RequestInputType.RequestHeader)` : "undefined"}
148152
}

packages/typescript-koa-runtime/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@
7979
}
8080
},
8181
"devDependencies": {
82+
"@jest/globals": "^30.2.0",
8283
"@koa/cors": "^5.0.0",
8384
"@koa/router": "^14.0.0",
8485
"@types/koa": "^3.0.1",

0 commit comments

Comments
 (0)