Skip to content

Commit 39b5e3c

Browse files
authored
fix: filter invalid request bodies (#348)
whilst implementing better support for non-JSON content-types, I realized that the stripe api defines a bunch of meaningless requests bodies on their `GET` / `DELETE` requests that look like this: ```yaml requestBody: content: application/x-www-form-urlencoded: encoding: {} schema: additionalProperties: false properties: {} type: object required: false ``` which is basically an `object` with no `properties` and no `additionalProperties` allowed. I'd probably have just ignored this, but the combination of this with `application/x-www-form-urlencoded` meant it complicated adding support for encoding bodies using `URLSearchParams` I've raised stripe/openapi#170 but for now lets just skip these and log a warning.
1 parent 958c88b commit 39b5e3c

10 files changed

Lines changed: 2013 additions & 14590 deletions

File tree

integration-tests/typescript-angular/src/generated/stripe.yaml/client.service.ts

Lines changed: 4 additions & 1994 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

integration-tests/typescript-axios/src/generated/stripe.yaml/client.ts

Lines changed: 281 additions & 1967 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

integration-tests/typescript-express/src/generated/stripe.yaml/generated.ts

Lines changed: 562 additions & 3275 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

integration-tests/typescript-express/src/generated/stripe.yaml/models.ts

Lines changed: 0 additions & 606 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

integration-tests/typescript-fetch/src/generated/stripe.yaml/client.ts

Lines changed: 562 additions & 2991 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

integration-tests/typescript-koa/src/generated/stripe.yaml/generated.ts

Lines changed: 562 additions & 3169 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

integration-tests/typescript-koa/src/generated/stripe.yaml/models.ts

Lines changed: 0 additions & 582 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

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

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import {generationLib} from "../../core/generation-lib"
2+
import {logger} from "../../core/logger"
23
import type {
34
IROperation,
45
IRParameter,
@@ -99,7 +100,17 @@ export class ClientOperationBuilder {
99100
requestBodyParameter?: IRParameter
100101
requestBodyContentType?: string
101102
} {
102-
return requestBodyAsParameter(this.operation)
103+
const result = requestBodyAsParameter(this.operation)
104+
const schema = result.requestBodyParameter?.schema
105+
106+
if (schema && this.models.isEmptyObject(schema)) {
107+
logger.warn(
108+
`[${this.route}]: skipping requestBody parameter that resolves to EmptyObject`,
109+
)
110+
return {}
111+
}
112+
113+
return result
103114
}
104115

105116
queryString(): string {

packages/openapi-code-generator/src/typescript/common/type-builder.ts

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -233,11 +233,9 @@ export class TypeBuilder implements ICompilable {
233233
? `[key: string]: ${union(additionalPropertiesType, "undefined")}`
234234
: ""
235235

236-
const emptyObject =
237-
schemaObject.additionalProperties === false &&
238-
properties.length === 0
239-
? this.addStaticType("EmptyObject")
240-
: ""
236+
const emptyObject = this.isEmptyObject(schemaObject)
237+
? this.addStaticType("EmptyObject")
238+
: ""
241239

242240
properties.push(additionalProperties)
243241

@@ -263,4 +261,17 @@ export class TypeBuilder implements ICompilable {
263261
toCompilationUnit(): CompilationUnit {
264262
return new CompilationUnit(this.filename, this.imports, this.toString())
265263
}
264+
265+
isEmptyObject(schemaObject: MaybeIRModel) {
266+
const dereferenced = this.input.schema(schemaObject)
267+
268+
return (
269+
dereferenced.type === "object" &&
270+
dereferenced.allOf.length === 0 &&
271+
dereferenced.anyOf.length === 0 &&
272+
dereferenced.oneOf.length === 0 &&
273+
dereferenced.additionalProperties === false &&
274+
Object.keys(dereferenced.properties).length === 0
275+
)
276+
}
266277
}

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

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import type {Input} from "../../core/input"
2+
import {logger} from "../../core/logger"
23
import type {
34
IRModelObject,
45
IROperation,
@@ -265,14 +266,27 @@ export class ServerOperationBuilder {
265266

266267
private requestBodyParameter(schemaSymbolName: string): Parameters["body"] {
267268
const {requestBodyParameter} = requestBodyAsParameter(this.operation)
269+
268270
const isRequired = Boolean(requestBodyParameter?.required)
271+
269272
const schema = requestBodyParameter
270273
? this.schemaBuilder.fromModel(
271274
requestBodyParameter.schema,
272275
requestBodyParameter.required,
273276
true,
274277
)
275278
: undefined
279+
280+
if (
281+
requestBodyParameter &&
282+
this.types.isEmptyObject(requestBodyParameter.schema)
283+
) {
284+
logger.warn(
285+
`[${this.route}]: skipping requestBody parameter that resolves to EmptyObject`,
286+
)
287+
return {type: "void", schema: undefined, isRequired: false}
288+
}
289+
276290
let type = "void"
277291

278292
if (schema && requestBodyParameter) {

0 commit comments

Comments
 (0)