Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
49a661f
fix(golang): always emit consolidated imports regardless of leadingCo…
schani Jul 20, 2026
85a7593
fix(python): use datetime.date/time for date/time formats (#1974)
schani Jul 20, 2026
faa252b
fix(schema): support boolean "false" subschemas (#1896)
schani Jul 20, 2026
90d3a6a
fix(python): drop typing.Type dependency for Python 3.6 target (#1728)
schani Jul 20, 2026
9970bdd
fix(kotlin): preserve enum string values in --just-types mode (#1601)
schani Jul 20, 2026
219b867
fix(php): stop re-checking scalar types PHP already enforces (#2770)
schani Jul 20, 2026
24ff684
fix(swift): allow Sendable conformance with objective-c-support (#2781)
schani Jul 20, 2026
c76510c
fix(rust): don't panic when there are no top-level types (#1629)
schani Jul 20, 2026
2f73e70
fix(csharp): make generated Serialize/Converter classes partial (#1520)
schani Jul 20, 2026
c2eebca
fix(cli): exit cleanly instead of crashing on EPIPE (#864)
schani Jul 20, 2026
9185017
fix(rust): stop double-boxing nullable cycle-breaking unions (#1112)
schani Jul 20, 2026
1b965a8
fix(java): emit @JsonFormat for optional date/time properties (#1593)
schani Jul 20, 2026
cffffe7
fix(cpp): compile optional any-typed properties with --hide-null-opti…
schani Jul 20, 2026
0757acc
fix(golang): don't apply omitempty to nullable/union fields under --o…
schani Jul 20, 2026
90c0961
test: add missing fixture cases for nullable-optional-one-of.schema (…
schani Jul 20, 2026
50685d0
test: add missing fixture cases for optional-date-time.schema (#3049)
schani Jul 20, 2026
018f12f
test: add missing fixture cases for rust-cycle-breaker-union.schema (…
schani Jul 20, 2026
fc172f9
test: add missing fixture cases for boolean-subschema.schema (#3004)
schani Jul 20, 2026
a124907
style(cpp): collapse emitBlock call to satisfy Biome formatter
schani Jul 21, 2026
e4395e8
fix(test): satisfy Biome format and lint on php-validation test
schani Jul 21, 2026
3baf628
style: collapse JSONSchemaInput constructor call to satisfy Biome
schani Jul 21, 2026
8661a84
test: skip rust-cycle-breaker-union.schema for cjson
schani Jul 21, 2026
1e10956
test: fix gating of boolean-subschema fixture cases (#3004)
Jul 21, 2026
0ddad42
fix CI: skip rust-cycle-breaker-union.schema for kotlinx (#1112)
schani Jul 21, 2026
10b1f56
fix CI: skip enum-value validation for nullable-optional-one-of.schem…
schani Jul 21, 2026
f27f41c
fix CI: emit declare(strict_types=1) in generated PHP to reject misty…
schani Jul 21, 2026
2e4d6a1
Merge remote-tracking branch 'origin/master' into HEAD
schani Jul 21, 2026
d5443bd
fix CI: update stale cjson enum-order test expectation
schani Jul 21, 2026
bcd0980
Merge master to pick up cjson-enum-default test fix baseline
schani Jul 21, 2026
bf7de47
fix CI: correct stale cjson-enum-default expectation to declaration o…
schani Jul 21, 2026
8830573
fix CI: skip boolean-subschema.schema for cJSON, a known array-type-v…
schani Jul 21, 2026
d159a82
fix CI: skip rust-cycle-breaker-union.schema for elm (#1112)
schani Jul 21, 2026
a03b5ed
Merge branch 'master' into agent/fix-issue-1896
schani Jul 21, 2026
b723af7
fix CI: skip optional-any.schema for elixir (scalar types not validat…
schani Jul 21, 2026
777022c
fix CI: correct stale cjson-enum-default expected enum order (#3004)
schani Jul 21, 2026
fe7d0cd
fix CI: skip boolean-subschema.schema for Elixir, no runtime type che…
schani Jul 21, 2026
09cda7b
fix CI: skip boolean-subschema.schema for Haskell, Maybe-decode limit…
schani Jul 21, 2026
f69c9c3
Merge pull request #3038 from glideapps/agent/fix-issue-864
schani Jul 21, 2026
58dad07
Merge pull request #3049 from glideapps/agent/fix-issue-1593
schani Jul 21, 2026
021f791
Merge pull request #3040 from glideapps/agent/fix-issue-1112
schani Jul 21, 2026
2e8284c
Merge pull request #3054 from glideapps/agent/fix-issue-1961-2
schani Jul 21, 2026
15ace60
Merge pull request #3004 from glideapps/agent/fix-issue-1896
schani Jul 21, 2026
6f4f888
Merge pull request #2988 from glideapps/agent/fix-issue-2670
schani Jul 21, 2026
bc44499
Merge pull request #2990 from glideapps/agent/fix-issue-1974
schani Jul 21, 2026
d7e2762
Merge pull request #3022 from glideapps/agent/fix-issue-1520
schani Jul 21, 2026
48becca
Merge pull request #3019 from glideapps/agent/fix-issue-1629
schani Jul 21, 2026
cac8f32
Merge pull request #3017 from glideapps/agent/fix-issue-2781
schani Jul 21, 2026
524b3fe
Merge pull request #3005 from glideapps/agent/fix-issue-1728
schani Jul 21, 2026
bbf2d6e
Merge pull request #3007 from glideapps/agent/fix-issue-1601
schani Jul 21, 2026
37db752
Merge pull request #3013 from glideapps/agent/fix-issue-2770
schani Jul 21, 2026
d1f3387
Merge origin/master into agent/fix-issue-2515
schani Jul 21, 2026
f1df437
Merge pull request #3057 from glideapps/agent/fix-issue-2515
schani Jul 21, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
36 changes: 14 additions & 22 deletions packages/quicktype-core/src/language/CPlusPlus/CPlusPlusRenderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1597,6 +1597,12 @@ export class CPlusPlusRenderer extends ConvenienceRenderer {
getter = [name];
}

const value = this._stringType.wrapEncodingChange(
[ourQualifier],
cppType,
toType,
["x.", getter],
);
const assignment: Sourcelike[] = [
"j[",
this._stringType.wrapEncodingChange(
Expand All @@ -1608,31 +1614,17 @@ export class CPlusPlusRenderer extends ConvenienceRenderer {
]),
),
"] = ",
this._stringType.wrapEncodingChange(
[ourQualifier],
cppType,
toType,
["x.", getter],
),
value,
";",
];
if (p.isOptional && this._options.hideNullOptional) {
this.emitBlock(
[
"if (",
this._stringType.wrapEncodingChange(
[ourQualifier],
cppType,
toType,
["x.", getter],
),
")",
],
false,
() => {
this.emitLine(assignment);
},
);
const condition =
propType.kind === "null" || propType.kind === "any"
? ["!", value, ".is_null()"]
: value;
this.emitBlock(["if (", condition, ")"], false, () => {
this.emitLine(assignment);
});
} else {
this.emitLine(assignment);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -408,7 +408,7 @@ export class NewtonsoftCSharpRenderer extends CSharpRenderer {
this.emitType(
undefined,
AccessModifier.Public,
"static class",
"static partial class",
"Serialize",
undefined,
() => {
Expand Down Expand Up @@ -471,7 +471,7 @@ export class NewtonsoftCSharpRenderer extends CSharpRenderer {
this.emitType(
undefined,
AccessModifier.Internal,
"static class",
"static partial class",
converterName,
undefined,
() => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -416,7 +416,7 @@ export class SystemTextJsonCSharpRenderer extends CSharpRenderer {
this.emitType(
undefined,
AccessModifier.Public,
"static class",
"static partial class",
"Serialize",
undefined,
() => {
Expand Down Expand Up @@ -487,7 +487,7 @@ export class SystemTextJsonCSharpRenderer extends CSharpRenderer {
this.emitType(
undefined,
AccessModifier.Internal,
"static class",
"static partial class",
converterName,
undefined,
() => {
Expand Down
60 changes: 36 additions & 24 deletions packages/quicktype-core/src/language/Golang/GolangRenderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { assert, defined } from "../../support/Support.js";
import type { TargetLanguage } from "../../TargetLanguage.js";
import {
type ClassProperty,
type ClassType,
ClassType,
type EnumType,
type Type,
type TypeKind,
Expand Down Expand Up @@ -194,28 +194,37 @@ export class GoRenderer extends ConvenienceRenderer {
if (
this._options.multiFileOutput &&
this._options.justTypes === false &&
this._options.justTypesAndPackage === false &&
this.leadingComments === undefined
this._options.justTypesAndPackage === false
) {
this.emitLineOnce(
"// Code generated from JSON Schema using quicktype. DO NOT EDIT.",
);
this.emitLineOnce(
"// To parse and unparse this JSON data, add this code to your project and do:",
);
this.emitLineOnce("//");
const ref = modifySource(camelCase, name);
this.emitLineOnce(
"// ",
ref,
", err := ",
defined(this._topLevelUnmarshalNames.get(name)),
"(bytes)",
);
this.emitLineOnce("// bytes, err = ", ref, ".Marshal()");
if (this.leadingComments !== undefined) {
this.emitComments(this.leadingComments);
} else {
this.emitLineOnce(
"// Code generated from JSON Schema using quicktype. DO NOT EDIT.",
);
this.emitLineOnce(
"// To parse and unparse this JSON data, add this code to your project and do:",
);
this.emitLineOnce("//");
const ref = modifySource(camelCase, name);
this.emitLineOnce(
"// ",
ref,
", err := ",
defined(this._topLevelUnmarshalNames.get(name)),
"(bytes)",
);
this.emitLineOnce("// bytes, err = ", ref, ".Marshal()");
}
}

this.emitPackageDefinitons(true);
const imports =
t instanceof ClassType
? this.collectClassImports(t)
: t instanceof UnionType
? this.collectUnionImports(t)
: undefined;
this.emitPackageDefinitons(true, imports);

const unmarshalName = defined(this._topLevelUnmarshalNames.get(name));
if (this.namedTypeToNameForTopLevel(t) === undefined) {
Expand Down Expand Up @@ -305,7 +314,7 @@ export class GoRenderer extends ConvenienceRenderer {

private emitUnion(u: UnionType, unionName: Name): void {
this.startFile(unionName);
this.emitPackageDefinitons(false);
this.emitPackageDefinitons(false, this.collectUnionImports(u));
const [hasNull, nonNulls] = removeNullFromUnion(u);
const isNullableArg = hasNull !== null ? "true" : "false";

Expand Down Expand Up @@ -610,10 +619,13 @@ func marshalUnion(pi *int64, pf *float64, pb *bool, ps *string, haveArray bool,
if (
this._options.multiFileOutput === false &&
this._options.justTypes === false &&
this._options.justTypesAndPackage === false &&
this.leadingComments === undefined
this._options.justTypesAndPackage === false
) {
this.emitSingleFileHeaderComments();
if (this.leadingComments !== undefined) {
this.emitComments(this.leadingComments);
} else {
this.emitSingleFileHeaderComments();
}
this.emitPackageDefinitons(false, this.collectAllImports());
}

Expand Down
3 changes: 2 additions & 1 deletion packages/quicktype-core/src/language/Golang/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,8 @@ export function canOmitEmpty(
omitEmptyOption: boolean,
): boolean {
if (!cp.isOptional) return false;
if (omitEmptyOption) return true;
if (omitEmptyOption)
return !["union", "null", "any"].includes(cp.type.kind);
const t = cp.type;
return !["union", "null", "any"].includes(t.kind);
}
12 changes: 10 additions & 2 deletions packages/quicktype-core/src/language/Java/JavaJacksonRenderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,10 @@ import {
type TypeKind,
UnionType,
} from "../../Type/index.js";
import { removeNullFromUnion } from "../../Type/TypeUtils.js";
import {
nullableFromUnion,
removeNullFromUnion,
} from "../../Type/TypeUtils.js";

import { JavaRenderer } from "./JavaRenderer.js";
import { stringEscape } from "./utils.js";
Expand Down Expand Up @@ -58,7 +61,12 @@ export class JacksonRenderer extends JavaRenderer {
`@JsonProperty("${stringEscape(jsonName)}")`,
];

switch (p.type.kind) {
const propertyType =
p.type instanceof UnionType
? (nullableFromUnion(p.type) ?? p.type)
: p.type;

switch (propertyType.kind) {
case "date-time":
this._dateTimeProvider.dateTimeJacksonAnnotations.forEach(
(annotation) => {
Expand Down
36 changes: 32 additions & 4 deletions packages/quicktype-core/src/language/Kotlin/KotlinRenderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ import {

import { keywords } from "./constants.js";
import type { kotlinOptions } from "./language.js";
import { kotlinNameStyle } from "./utils.js";
import { kotlinNameStyle, stringEscape } from "./utils.js";

export class KotlinRenderer extends ConvenienceRenderer {
public constructor(
Expand Down Expand Up @@ -391,10 +391,38 @@ export class KotlinRenderer extends ConvenienceRenderer {
protected emitEnumDefinition(e: EnumType, enumName: Name): void {
this.emitDescription(this.descriptionForType(e));

this.emitBlock(["enum class ", enumName], () => {
this.emitBlock(["enum class ", enumName, "(val value: String)"], () => {
let count = e.cases.size;
this.forEachEnumCase(e, "none", (name) => {
this.emitLine(name, --count === 0 ? "" : ",");
this.forEachEnumCase(e, "none", (name, json) => {
this.emitLine(
name,
`("${stringEscape(json)}")`,
--count === 0 ? ";" : ",",
);
});
this.ensureBlankLine();
this.emitBlock("companion object", () => {
this.emitBlock(
[
"fun fromValue(value: String): ",
enumName,
" = when (value)",
],
() => {
const table: Sourcelike[][] = [];
this.forEachEnumCase(e, "none", (name, json) => {
table.push([
[`"${stringEscape(json)}"`],
[" -> ", name],
]);
});
table.push([
["else"],
[" -> throw IllegalArgumentException()"],
]);
this.emitTable(table);
},
);
});
});
}
Expand Down
Loading
Loading