Skip to content

Commit fc3f7f8

Browse files
StefanTerdellStefan Terdell
and
Stefan Terdell
authored
Fix boolean props (#2199)
* Add failing test case for boolean object props * Fix boolean object props * Add changeset --------- Co-authored-by: Stefan Terdell <stefan.terdell@cleura.com>
1 parent 7951d61 commit fc3f7f8

File tree

3 files changed

+43
-13
lines changed

3 files changed

+43
-13
lines changed

.changeset/clever-worms-smile.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"openapi-typescript": patch
3+
---
4+
5+
Fix boolean object property schemas

packages/openapi-typescript/src/transform/schema-object.ts

+21-13
Original file line numberDiff line numberDiff line change
@@ -453,38 +453,46 @@ function transformSchemaObjectCore(schemaObject: SchemaObject, options: Transfor
453453
// properties
454454
if (Object.keys(schemaObject.properties ?? {}).length) {
455455
for (const [k, v] of getEntries(schemaObject.properties ?? {}, options.ctx)) {
456-
if (typeof v !== "object" || Array.isArray(v)) {
456+
if ((typeof v !== "object" && typeof v !== "boolean") || Array.isArray(v)) {
457457
throw new Error(
458-
`${options.path}: invalid property ${k}. Expected Schema Object, got ${
458+
`${options.path}: invalid property ${k}. Expected Schema Object or boolean, got ${
459459
Array.isArray(v) ? "Array" : typeof v
460460
}`,
461461
);
462462
}
463463

464+
const { $ref, readOnly, hasDefault } =
465+
typeof v === "object"
466+
? {
467+
$ref: "$ref" in v && v.$ref,
468+
readOnly: "readOnly" in v && v.readOnly,
469+
hasDefault: "default" in v && v.default !== undefined,
470+
}
471+
: {};
472+
464473
// handle excludeDeprecated option
465474
if (options.ctx.excludeDeprecated) {
466-
const resolved = "$ref" in v ? options.ctx.resolve<SchemaObject>(v.$ref) : v;
467-
if (resolved?.deprecated) {
475+
const resolved = $ref ? options.ctx.resolve<SchemaObject>($ref) : v;
476+
if ((resolved as SchemaObject)?.deprecated) {
468477
continue;
469478
}
470479
}
471480
let optional =
472481
schemaObject.required?.includes(k) ||
473482
(schemaObject.required === undefined && options.ctx.propertiesRequiredByDefault) ||
474-
("default" in v &&
483+
(hasDefault &&
475484
options.ctx.defaultNonNullable &&
476485
!options.path?.includes("parameters") &&
477486
!options.path?.includes("requestBody") &&
478487
!options.path?.includes("requestBodies")) // can’t be required, even with defaults
479488
? undefined
480489
: QUESTION_TOKEN;
481-
let type =
482-
"$ref" in v
483-
? oapiRef(v.$ref)
484-
: transformSchemaObject(v, {
485-
...options,
486-
path: createRef([options.path, k]),
487-
});
490+
let type = $ref
491+
? oapiRef($ref)
492+
: transformSchemaObject(v, {
493+
...options,
494+
path: createRef([options.path, k]),
495+
});
488496

489497
if (typeof options.ctx.transform === "function") {
490498
const result = options.ctx.transform(v as SchemaObject, options);
@@ -500,7 +508,7 @@ function transformSchemaObjectCore(schemaObject: SchemaObject, options: Transfor
500508

501509
const property = ts.factory.createPropertySignature(
502510
/* modifiers */ tsModifiers({
503-
readonly: options.ctx.immutable || ("readOnly" in v && !!v.readOnly),
511+
readonly: options.ctx.immutable || readOnly,
504512
}),
505513
/* name */ tsPropertyIndex(k),
506514
/* questionToken */ optional,

packages/openapi-typescript/test/transform/schema-object/object.test.ts

+17
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,23 @@ describe("transformSchemaObject > object", () => {
2828
// options: DEFAULT_OPTIONS,
2929
},
3030
],
31+
[
32+
"property > boolean",
33+
{
34+
given: {
35+
type: "object",
36+
required: ["truthy", "falsy"],
37+
properties: {
38+
truthy: true,
39+
falsy: false,
40+
},
41+
},
42+
want: `{
43+
truthy: unknown;
44+
falsy: never;
45+
}`,
46+
},
47+
],
3148
[
3249
"empty",
3350
{

0 commit comments

Comments
 (0)