Skip to content
16 changes: 6 additions & 10 deletions packages/quicktype-core/src/input/JSONSchemaInput.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1084,14 +1084,17 @@ async function addTypesInSchema(
emptyTypeAttributes,
new Set(itemTypes),
);
} else if (typeof items === "object") {
} else if (
typeof items === "object" ||
typeof items === "boolean"
) {
const itemsLoc = loc.push("items");
itemType = await toType(
checkJSONSchema(items, itemsLoc.canonicalRef),
itemsLoc,
singularAttributes,
);
} else if (items !== undefined && items !== true) {
} else if (items !== undefined) {
return messageError(
"SchemaArrayItemsMustBeStringOrArray",
withRef(loc, { actual: items }),
Expand Down Expand Up @@ -1396,14 +1399,7 @@ async function addTypesInSchema(

let result: TypeRef;
if (typeof schema === "boolean") {
// FIXME: Empty union. We'd have to check that it's supported everywhere,
// in particular in union flattening.
messageAssert(
schema === true,
"SchemaFalseNotSupported",
withRef(loc),
);
result = typeBuilder.getPrimitiveType("any");
result = typeBuilder.getPrimitiveType(schema ? "any" : "none");
} else {
loc = loc.updateWithID(schema.$id);
result = await convertToType(schema, loc, typeAttributes);
Expand Down
9 changes: 9 additions & 0 deletions packages/quicktype-core/src/rewrites/ResolveIntersections.ts
Original file line number Diff line number Diff line change
Expand Up @@ -471,6 +471,15 @@ export function resolveIntersections(
return t;
}

const noneType = iterableFind(members, (t) => t.kind === "none");
if (noneType !== undefined) {
return builder.reconstituteType(
noneType,
intersectionAttributes,
forwardingRef,
);
}

if (members.size === 1) {
return builder.reconstituteType(
defined(iterableFirst(members)),
Expand Down
4 changes: 4 additions & 0 deletions test/inputs/schema/boolean-subschema.1.fail.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"foo": "hello",
"empty": "not an array"
}
4 changes: 4 additions & 0 deletions test/inputs/schema/boolean-subschema.1.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"foo": "hello",
"empty": []
}
17 changes: 17 additions & 0 deletions test/inputs/schema/boolean-subschema.schema
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"foo": { "type": "string" },
"disallowed": false,
"empty": {
"type": "array",
"items": false
},
"impossible": {
"allOf": [false, { "type": "string" }]
}
},
"required": ["foo", "empty"],
"additionalProperties": false
}
3 changes: 3 additions & 0 deletions test/languages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -630,6 +630,7 @@ export const CJSONLanguage: Language = {
/* Enum with invalid values are not checked (for the current implementation, can be added later, should abord parsing and return NULL) */
...skipsEnumValueValidation,
/* Union, Map and Arrays with invalid types are not checked (for the current implementation, can be added later, should abord parsing and return NULL) */
"boolean-subschema.schema",
"class-with-additional.schema",
...skipsMapValueValidation,
"multi-type-enum.schema",
Expand Down Expand Up @@ -1857,6 +1858,7 @@ export const HaskellLanguage: Language = {
...skipsUntypedUnions,
// The test driver encodes the Maybe result, so a failed decode prints
// "null" and exits 0 — expected-failure samples cannot be detected.
"boolean-subschema.schema",
"nested-intersection-union.schema",
"prefix-items.schema",
"direct-union.schema",
Expand Down Expand Up @@ -2210,6 +2212,7 @@ export const ElixirLanguage: Language = {
// Struct keys cannot be enforced at runtime in Elixir and their values will just be set to null.
"strict-optional.schema",
"required.schema",
"boolean-subschema.schema",
"intersection.schema",

// The test incorrectly succeeds due to the emitter being permissive for unions that contain only primitives. A future enhancement
Expand Down
4 changes: 2 additions & 2 deletions test/unit/cjson-enum-default.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@ describe("cJSON enum invalid value", () => {
const output = await cJSONOutput();

expect(output).toContain(`enum Subscription {
SUBSCRIPTION_CONFIG = 1,
SUBSCRIPTION_STATE = 1,
SUBSCRIPTION_CONFIG,
SUBSCRIPTION_HEARTBEAT,
SUBSCRIPTION_STATE,
};`);
expect(output).toContain("enum Subscription x = 0;");
});
Expand Down
Loading