Skip to content
14 changes: 11 additions & 3 deletions packages/quicktype-core/src/input/JSONSchemaInput.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1139,14 +1139,22 @@ async function addTypesInSchema(
}

let additionalProperties = schema.additionalProperties;
// This is an incorrect hack to fix an issue with a Go->Schema generator:
// This is an incorrect hack to treat a single pattern property as
// additional properties:
// https://github.com/quicktype/quicktype/issues/976
// https://github.com/quicktype/quicktype/issues/1464
if (
additionalProperties === undefined &&
typeof schema.patternProperties === "object" &&
hasOwnProperty(schema.patternProperties, ".*")
schema.patternProperties !== null
) {
additionalProperties = schema.patternProperties[".*"];
const patterns = Object.getOwnPropertyNames(
schema.patternProperties,
);
if (patterns.length === 1) {
additionalProperties =
schema.patternProperties[patterns[0]];
}
}

// Handle unevaluatedProperties if additionalProperties is not defined
Expand Down
3 changes: 3 additions & 0 deletions test/inputs/schema/pattern-properties.1.fail.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"enabled": {}
}
3 changes: 3 additions & 0 deletions test/inputs/schema/pattern-properties.1.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"enabled": true
}
9 changes: 9 additions & 0 deletions test/inputs/schema/pattern-properties.schema
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"patternProperties": {
"^[a-zA-Z]\\w*$": {
"type": "boolean"
}
}
}
12 changes: 12 additions & 0 deletions test/languages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,10 @@ const skipsUntypedUnions = [
const skipsMapValueValidation = [
"go-schema-pattern-properties.schema",
"unevaluated-properties.schema",
// These languages deserialize a map without validating the value type
// (unchecked generic casts, raw map readers, or no runtime type checks),
// so the `{"enabled": {}}` fail sample round-trips instead of failing.
"pattern-properties.schema",
];

// The generated deserializer for a top-level array of scalars uses a
Expand Down Expand Up @@ -263,6 +267,11 @@ export const JavaLanguage: Language = {
skipSchema: [
"integer-before-number.schema", // Python-specific union-order regression.
"keyword-unions.schema", // generates classes with names that are case-insensitively equal
// A top-level map deserializes via a raw `Map.class` reader
// (javaTypeWithoutGenerics drops the value type), so map value
// types are not validated on parse and the fail sample does not
// fail. Nested typed maps are still validated elsewhere.
"pattern-properties.schema",
// The generated converter deserializes a top-level array with a raw
// `List`, so a mistyped element round-trips instead of failing.
...skipsArrayElementValidation,
Expand Down Expand Up @@ -1976,6 +1985,9 @@ export const PHPLanguage: Language = {
"top-level-enum.schema",
// The driver does not support top-level arrays.
"union.schema",
// PHP has no type aliases, so a top-level map produces no named
// TopLevel class and the driver's TopLevel::from() call fails.
"pattern-properties.schema",
"issue2680-top-level-array.schema",
],
rendererOptions: {},
Expand Down
Loading