From 0cc51f505e1ef604dce73da77d9a5b24983bc3e5 Mon Sep 17 00:00:00 2001 From: Mark Probst Date: Mon, 13 Jul 2026 09:42:09 -0400 Subject: [PATCH 01/68] Enable Biome linter with the recommended preset Turn on Biome's linter using the recommended rule preset. Of the 218 recommended rules, 30 currently report diagnostics on this codebase; those 30 are explicitly set to "off" for now so that lint passes with no code changes, leaving 188 recommended rules active. The disabled rules will be re-evaluated and either adopted (with violations fixed) or rejected with rationale in follow-up commits. Co-Authored-By: Claude Fable 5 --- biome.json | 43 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/biome.json b/biome.json index 00d50f7c05..8d0fc21047 100644 --- a/biome.json +++ b/biome.json @@ -18,7 +18,48 @@ "indentWidth": 4 }, "linter": { - "enabled": false + "enabled": true, + "rules": { + "preset": "recommended", + "complexity": { + "noBannedTypes": "off", + "noExtraBooleanCast": "off", + "noUselessConstructor": "off", + "noUselessContinue": "off", + "noUselessSwitchCase": "off", + "noUselessTernary": "off", + "noUselessUndefinedInitialization": "off", + "useDateNow": "off", + "useOptionalChain": "off" + }, + "correctness": { + "noConstructorReturn": "off", + "noSwitchDeclarations": "off", + "noUnusedImports": "off", + "noUnusedVariables": "off", + "noVoidTypeReturn": "off", + "useParseIntRadix": "off" + }, + "style": { + "noNonNullAssertion": "off", + "useConst": "off", + "useExponentiationOperator": "off", + "useNodejsImportProtocol": "off", + "useTemplate": "off" + }, + "suspicious": { + "noExplicitAny": "off", + "noGlobalIsNan": "off", + "noImplicitAnyLet": "off", + "noPrototypeBuiltins": "off", + "noShadowRestrictedNames": "off", + "noTemplateCurlyInString": "off", + "noTsIgnore": "off", + "noUselessEscapeInString": "off", + "useIsArray": "off", + "useIterableCallbackReturn": "off" + } + } }, "assist": { "actions": { "source": { "organizeImports": "off" } } }, "overrides": [ From 54359c5f7458c34867f2a9fca6f1a3a0a0b4d148 Mon Sep 17 00:00:00 2001 From: Mark Probst Date: Mon, 13 Jul 2026 09:43:55 -0400 Subject: [PATCH 02/68] Biome: enable noUnusedImports and fix violations One violation: an unused lodash import in the PHP language utils. Co-Authored-By: Claude Fable 5 --- biome.json | 1 - packages/quicktype-core/src/language/Php/utils.ts | 2 -- 2 files changed, 3 deletions(-) diff --git a/biome.json b/biome.json index 8d0fc21047..a22572a915 100644 --- a/biome.json +++ b/biome.json @@ -35,7 +35,6 @@ "correctness": { "noConstructorReturn": "off", "noSwitchDeclarations": "off", - "noUnusedImports": "off", "noUnusedVariables": "off", "noVoidTypeReturn": "off", "useParseIntRadix": "off" diff --git a/packages/quicktype-core/src/language/Php/utils.ts b/packages/quicktype-core/src/language/Php/utils.ts index 388a7f2057..457b0dfe35 100644 --- a/packages/quicktype-core/src/language/Php/utils.ts +++ b/packages/quicktype-core/src/language/Php/utils.ts @@ -1,5 +1,3 @@ -import _ from "lodash"; - import { allLowerWordStyle, allUpperWordStyle, From a37e29f45c7af22d35a76b3cda124bae9f0309ae Mon Sep 17 00:00:00 2001 From: Mark Probst Date: Mon, 13 Jul 2026 09:44:42 -0400 Subject: [PATCH 03/68] Biome: enable noUnusedVariables and fix violations Five violations, all unused catch-clause bindings; converted to optional catch binding (catch without a parameter). Co-Authored-By: Claude Fable 5 --- biome.json | 1 - packages/quicktype-core/src/input/JSONSchemaStore.ts | 2 +- packages/quicktype-core/src/input/PostmanCollection.ts | 2 +- packages/quicktype-vscode/src/extension.ts | 6 +++--- 4 files changed, 5 insertions(+), 6 deletions(-) diff --git a/biome.json b/biome.json index a22572a915..c599c646fd 100644 --- a/biome.json +++ b/biome.json @@ -35,7 +35,6 @@ "correctness": { "noConstructorReturn": "off", "noSwitchDeclarations": "off", - "noUnusedVariables": "off", "noVoidTypeReturn": "off", "useParseIntRadix": "off" }, diff --git a/packages/quicktype-core/src/input/JSONSchemaStore.ts b/packages/quicktype-core/src/input/JSONSchemaStore.ts index 634b29a17c..64dff89581 100644 --- a/packages/quicktype-core/src/input/JSONSchemaStore.ts +++ b/packages/quicktype-core/src/input/JSONSchemaStore.ts @@ -31,7 +31,7 @@ export abstract class JSONSchemaStore { try { schema = await this.fetch(address); - } catch (e) { + } catch { // FIXME: handle or log this error } diff --git a/packages/quicktype-core/src/input/PostmanCollection.ts b/packages/quicktype-core/src/input/PostmanCollection.ts index b4050885ca..85506c205f 100644 --- a/packages/quicktype-core/src/input/PostmanCollection.ts +++ b/packages/quicktype-core/src/input/PostmanCollection.ts @@ -7,7 +7,7 @@ function isValidJSON(s: string): boolean { try { JSON.parse(s); return true; - } catch (error) { + } catch { return false; } } diff --git a/packages/quicktype-vscode/src/extension.ts b/packages/quicktype-vscode/src/extension.ts index ff5a757d34..6982101368 100644 --- a/packages/quicktype-vscode/src/extension.ts +++ b/packages/quicktype-vscode/src/extension.ts @@ -34,7 +34,7 @@ enum Command { function jsonIsValid(json: string): boolean { try { JSON.parse(json); - } catch (e) { + } catch { return false; } @@ -186,7 +186,7 @@ async function pasteAsTypes( let content: string; try { content = await vscode.env.clipboard.readText(); - } catch (e) { + } catch { return await vscode.window.showErrorMessage( "Could not get clipboard contents", ); @@ -370,7 +370,7 @@ class CodeProvider implements vscode.TextDocumentContentProvider { if (!this._isOpen) return; this._onDidChange.fire(this.uri); - } catch (e) { + } catch { // FIXME } } From 7cc89010e2d4a9f8418edeecb35dbbeaf11cb87c Mon Sep 17 00:00:00 2001 From: Mark Probst Date: Mon, 13 Jul 2026 09:46:39 -0400 Subject: [PATCH 04/68] Biome: enable useParseIntRadix and fix violations Three violations, all parsing a single character with Number.parseInt; added an explicit radix of 10, which preserves behavior. Co-Authored-By: Claude Fable 5 --- biome.json | 3 +-- packages/quicktype-core/src/language/Scala3/Scala3Renderer.ts | 4 +++- packages/quicktype-core/src/language/Scala3/utils.ts | 2 +- packages/quicktype-core/src/language/Smithy4s/utils.ts | 2 +- 4 files changed, 6 insertions(+), 5 deletions(-) diff --git a/biome.json b/biome.json index c599c646fd..a5fbcbd821 100644 --- a/biome.json +++ b/biome.json @@ -35,8 +35,7 @@ "correctness": { "noConstructorReturn": "off", "noSwitchDeclarations": "off", - "noVoidTypeReturn": "off", - "useParseIntRadix": "off" + "noVoidTypeReturn": "off" }, "style": { "noNonNullAssertion": "off", diff --git a/packages/quicktype-core/src/language/Scala3/Scala3Renderer.ts b/packages/quicktype-core/src/language/Scala3/Scala3Renderer.ts index 7ae221c262..29826a8319 100644 --- a/packages/quicktype-core/src/language/Scala3/Scala3Renderer.ts +++ b/packages/quicktype-core/src/language/Scala3/Scala3Renderer.ts @@ -311,7 +311,9 @@ export class Scala3Renderer extends ConvenienceRenderer { const backticks = shouldAddBacktick(jsonName) || jsonName.includes(" ") || - !Number.isNaN(Number.parseInt(jsonName.charAt(0))); + !Number.isNaN( + Number.parseInt(jsonName.charAt(0), 10), + ); if (backticks) { this.emitItem("`"); } diff --git a/packages/quicktype-core/src/language/Scala3/utils.ts b/packages/quicktype-core/src/language/Scala3/utils.ts index e4850e5aa6..b10fd47f2f 100644 --- a/packages/quicktype-core/src/language/Scala3/utils.ts +++ b/packages/quicktype-core/src/language/Scala3/utils.ts @@ -22,7 +22,7 @@ export const shouldAddBacktick = (paramName: string): boolean => { keywords.some((s) => paramName === s) || invalidSymbols.some((s) => paramName.includes(s)) || !isNaN(+Number.parseFloat(paramName)) || - !isNaN(Number.parseInt(paramName.charAt(0))) + !isNaN(Number.parseInt(paramName.charAt(0), 10)) ); }; diff --git a/packages/quicktype-core/src/language/Smithy4s/utils.ts b/packages/quicktype-core/src/language/Smithy4s/utils.ts index 0291a67390..f05b63c940 100644 --- a/packages/quicktype-core/src/language/Smithy4s/utils.ts +++ b/packages/quicktype-core/src/language/Smithy4s/utils.ts @@ -23,7 +23,7 @@ export const shouldAddBacktick = (paramName: string): boolean => { keywords.some((s) => paramName === s) || invalidSymbols.some((s) => paramName.includes(s)) || !isNaN(Number.parseFloat(paramName)) || - !isNaN(Number.parseInt(paramName.charAt(0))) + !isNaN(Number.parseInt(paramName.charAt(0), 10)) ); }; From 54ffb93f865fac48a7f316de6e50e0cd39408d03 Mon Sep 17 00:00:00 2001 From: Mark Probst Date: Mon, 13 Jul 2026 09:47:16 -0400 Subject: [PATCH 05/68] Biome: enable noSwitchDeclarations and fix violations Wrapped switch cases that declare variables in blocks so the declarations are properly scoped to their case. Safe fixes only. Co-Authored-By: Claude Fable 5 --- biome.json | 1 - packages/quicktype-core/src/Source.ts | 9 ++++++--- packages/quicktype-core/src/input/JSONSchemaInput.ts | 3 ++- packages/quicktype-graphql-input/src/index.ts | 6 ++++-- src/index.ts | 3 ++- 5 files changed, 14 insertions(+), 8 deletions(-) diff --git a/biome.json b/biome.json index a5fbcbd821..fa3cfde6bd 100644 --- a/biome.json +++ b/biome.json @@ -34,7 +34,6 @@ }, "correctness": { "noConstructorReturn": "off", - "noSwitchDeclarations": "off", "noVoidTypeReturn": "off" }, "style": { diff --git a/packages/quicktype-core/src/Source.ts b/packages/quicktype-core/src/Source.ts index 2f8deccdf3..745ff08dc0 100644 --- a/packages/quicktype-core/src/Source.ts +++ b/packages/quicktype-core/src/Source.ts @@ -224,7 +224,7 @@ export function serializeRenderResult( } break; - case "table": + case "table": { const t = source.table; const numRows = t.length; if (numRows === 0) break; @@ -270,7 +270,8 @@ export function serializeRenderResult( } break; - case "annotated": + } + case "annotated": { const start = currentLocation(); serializeToStringArray(source.source); const end = currentLocation(); @@ -279,12 +280,13 @@ export function serializeRenderResult( span: { start, end }, }); break; + } case "name": assert(names.has(source.named), "No name for Named"); indentIfNeeded(); currentLine.push(defined(names.get(source.named))); break; - case "modified": + case "modified": { indentIfNeeded(); const serialized = serializeRenderResult( source.source, @@ -297,6 +299,7 @@ export function serializeRenderResult( ); currentLine.push(source.modifier(serialized[0])); break; + } default: return assertNever(source); } diff --git a/packages/quicktype-core/src/input/JSONSchemaInput.ts b/packages/quicktype-core/src/input/JSONSchemaInput.ts index ddccbf70e5..68f43be337 100644 --- a/packages/quicktype-core/src/input/JSONSchemaInput.ts +++ b/packages/quicktype-core/src/input/JSONSchemaInput.ts @@ -347,7 +347,7 @@ export class Ref { switch (first.kind) { case PathElementKind.Root: return this.lookup(root, rest, root); - case PathElementKind.KeyOrIndex: + case PathElementKind.KeyOrIndex: { const key = first.key; if (Array.isArray(local)) { if (!/^\d+$/.test(key)) { @@ -380,6 +380,7 @@ export class Ref { rest, root, ); + } case PathElementKind.Type: return panic('Cannot look up path that indexes "type"'); diff --git a/packages/quicktype-graphql-input/src/index.ts b/packages/quicktype-graphql-input/src/index.ts index 0f5b61fe66..5d92a64a4c 100644 --- a/packages/quicktype-graphql-input/src/index.ts +++ b/packages/quicktype-graphql-input/src/index.ts @@ -254,7 +254,7 @@ class GQLQuery { null, containingTypeName, ); - case TypeKind.ENUM: + case TypeKind.ENUM: { if (!fieldType.enumValues) { return panic("Enum type doesn't have values"); } @@ -276,6 +276,7 @@ class GQLQuery { new Set(values), ); break; + } case TypeKind.INPUT_OBJECT: // FIXME: Support input objects return panic("Input objects not supported"); @@ -365,7 +366,7 @@ class GQLQuery { if (!nextItem) break; const { selection, optional, inType } = nextItem; switch (selection.kind) { - case Kind.FIELD: + case Kind.FIELD: { const fieldName = selection.name.value; const givenName = selection.alias ? selection.alias.value @@ -382,6 +383,7 @@ class GQLQuery { builder.makeClassProperty(fieldType, optional), ); break; + } case Kind.FRAGMENT_SPREAD: { const fragment = this.getFragment(selection.name.value); const fragmentType = diff --git a/src/index.ts b/src/index.ts index a122614529..179f1b6f50 100644 --- a/src/index.ts +++ b/src/index.ts @@ -990,7 +990,7 @@ export async function makeQuicktypeOptions( let leadingComments: string[] | undefined = undefined; let fixedTopLevels = false; switch (options.srcLang) { - case "graphql": + case "graphql": { let schemaString: string | undefined = undefined; let wroteSchemaToFile = false; if (options.graphqlIntrospect !== undefined) { @@ -1047,6 +1047,7 @@ export async function makeQuicktypeOptions( sources = gqlSources; break; + } case "json": case "schema": sources = await getSources(options); From 279491f9e442b16472121ca70a49291bcf7d1756 Mon Sep 17 00:00:00 2001 From: Mark Probst Date: Mon, 13 Jul 2026 09:48:51 -0400 Subject: [PATCH 06/68] Biome: enable noConstructorReturn and fix violations Six violations, all "return panic(...)" statements in the GQLSchemaFromJSON constructor. Since panic() returns never, dropping the "return" keyword preserves behavior, and TypeScript's control-flow analysis now sees the definite assignment of queryType, making the existing @ts-expect-error directive obsolete. Co-Authored-By: Claude Fable 5 --- biome.json | 1 - packages/quicktype-graphql-input/src/index.ts | 13 ++++++------- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/biome.json b/biome.json index fa3cfde6bd..13c8255b58 100644 --- a/biome.json +++ b/biome.json @@ -33,7 +33,6 @@ "useOptionalChain": "off" }, "correctness": { - "noConstructorReturn": "off", "noVoidTypeReturn": "off" }, "style": { diff --git a/packages/quicktype-graphql-input/src/index.ts b/packages/quicktype-graphql-input/src/index.ts index 5d92a64a4c..c929c668af 100644 --- a/packages/quicktype-graphql-input/src/index.ts +++ b/packages/quicktype-graphql-input/src/index.ts @@ -466,7 +466,6 @@ class GQLQuery { class GQLSchemaFromJSON implements GQLSchema { public readonly types: { [name: string]: GQLType } = {}; - // @ts-expect-error: The constructor can return early, but only by throwing. public readonly queryType: GQLType; public readonly mutationType?: GQLType; @@ -475,11 +474,11 @@ class GQLSchemaFromJSON implements GQLSchema { const schema: GraphQLSchema = json.data; if (schema.__schema.queryType.name === null) { - return panic("Query type doesn't have a name."); + panic("Query type doesn't have a name."); } for (const t of schema.__schema.types as GQLType[]) { - if (!t.name) return panic("No top-level type name given"); + if (!t.name) panic("No top-level type name given"); this.types[t.name] = { kind: t.kind, name: t.name, @@ -488,7 +487,7 @@ class GQLSchemaFromJSON implements GQLSchema { } for (const t of schema.__schema.types) { - if (!t.name) return panic("This cannot happen"); + if (!t.name) panic("This cannot happen"); const type = this.types[t.name]; this.addTypeFields(type, t as GQLType); // console.log(`type ${type.name} is ${type.kind}`); @@ -496,7 +495,7 @@ class GQLSchemaFromJSON implements GQLSchema { const queryType = this.types[schema.__schema.queryType.name]; if (queryType === undefined) { - return panic("Query type not found."); + panic("Query type not found."); } // console.log(`query type ${queryType.name} is ${queryType.kind}`); @@ -507,12 +506,12 @@ class GQLSchemaFromJSON implements GQLSchema { } if (schema.__schema.mutationType.name === null) { - return panic("Mutation type doesn't have a name."); + panic("Mutation type doesn't have a name."); } const mutationType = this.types[schema.__schema.mutationType.name]; if (mutationType === undefined) { - return panic("Mutation type not found."); + panic("Mutation type not found."); } this.mutationType = mutationType; From 4509283e435cdc50bacc66a9b0c1ff030678b00f Mon Sep 17 00:00:00 2001 From: Mark Probst Date: Mon, 13 Jul 2026 09:50:35 -0400 Subject: [PATCH 07/68] Biome: enable noVoidTypeReturn and fix violations Thirteen violations, all "return panic(...)", "return messageError(...)" or "return assertNever(...)" inside void-returning functions. All three helpers return never, so dropping the "return" keyword preserves behavior. Co-Authored-By: Claude Fable 5 --- biome.json | 3 --- packages/quicktype-core/src/MarkovChain.ts | 6 +++--- packages/quicktype-core/src/Messages.ts | 2 +- packages/quicktype-core/src/Source.ts | 2 +- packages/quicktype-core/src/Type/TypeBuilder.ts | 2 +- packages/quicktype-core/src/input/CompressedJSON.ts | 12 +++++------- packages/quicktype-core/src/support/Strings.ts | 2 +- packages/quicktype-core/src/support/Support.ts | 2 +- 8 files changed, 13 insertions(+), 18 deletions(-) diff --git a/biome.json b/biome.json index 13c8255b58..dd73a2266e 100644 --- a/biome.json +++ b/biome.json @@ -32,9 +32,6 @@ "useDateNow": "off", "useOptionalChain": "off" }, - "correctness": { - "noVoidTypeReturn": "off" - }, "style": { "noNonNullAssertion": "off", "useConst": "off", diff --git a/packages/quicktype-core/src/MarkovChain.ts b/packages/quicktype-core/src/MarkovChain.ts index ff516d0361..32903223c3 100644 --- a/packages/quicktype-core/src/MarkovChain.ts +++ b/packages/quicktype-core/src/MarkovChain.ts @@ -52,14 +52,14 @@ function increment(t: Trie, seq: string, i: number): void { if (i >= seq.length - 1) { if (typeof t !== "object") { - return panic("Malformed trie"); + panic("Malformed trie"); } let n = t.arr[first]; if (n === null) { n = 0; } else if (typeof n === "object") { - return panic("Malformed trie"); + panic("Malformed trie"); } t.arr[first] = n + 1; @@ -73,7 +73,7 @@ function increment(t: Trie, seq: string, i: number): void { } if (typeof st !== "object") { - return panic("Malformed trie"); + panic("Malformed trie"); } increment(st, seq, i + 1); diff --git a/packages/quicktype-core/src/Messages.ts b/packages/quicktype-core/src/Messages.ts index 92009589ce..cd5be05f82 100644 --- a/packages/quicktype-core/src/Messages.ts +++ b/packages/quicktype-core/src/Messages.ts @@ -305,5 +305,5 @@ export function messageAssert( properties: ErrorPropertiesForKind, ): void { if (assertion) return; - return messageError(kind, properties); + messageError(kind, properties); } diff --git a/packages/quicktype-core/src/Source.ts b/packages/quicktype-core/src/Source.ts index 745ff08dc0..657844e168 100644 --- a/packages/quicktype-core/src/Source.ts +++ b/packages/quicktype-core/src/Source.ts @@ -301,7 +301,7 @@ export function serializeRenderResult( break; } default: - return assertNever(source); + assertNever(source); } } diff --git a/packages/quicktype-core/src/Type/TypeBuilder.ts b/packages/quicktype-core/src/Type/TypeBuilder.ts index d71b918908..051e0dfae5 100644 --- a/packages/quicktype-core/src/Type/TypeBuilder.ts +++ b/packages/quicktype-core/src/Type/TypeBuilder.ts @@ -467,7 +467,7 @@ export class TypeBuilder { const type = derefTypeRef(ref, this.typeGraph); if (!(type instanceof ObjectType)) { - return panic("Tried to set properties of non-object type"); + panic("Tried to set properties of non-object type"); } type.setProperties( diff --git a/packages/quicktype-core/src/input/CompressedJSON.ts b/packages/quicktype-core/src/input/CompressedJSON.ts index d92828a29a..d05d2ea289 100644 --- a/packages/quicktype-core/src/input/CompressedJSON.ts +++ b/packages/quicktype-core/src/input/CompressedJSON.ts @@ -153,9 +153,7 @@ export abstract class CompressedJSON { this._rootValue = value; } else if (this._ctx.currentObject !== undefined) { if (this._ctx.currentKey === undefined) { - return panic( - "Must have key and can't have string when committing", - ); + panic("Must have key and can't have string when committing"); } this._ctx.currentObject.push( @@ -166,7 +164,7 @@ export abstract class CompressedJSON { } else if (this._ctx.currentArray !== undefined) { this._ctx.currentArray.push(value); } else { - return panic("Committing value but nowhere to commit to"); + panic("Committing value but nowhere to commit to"); } } @@ -257,7 +255,7 @@ export abstract class CompressedJSON { protected finishObject(): void { const obj = this.context.currentObject; if (obj === undefined) { - return panic("Object ended but not started"); + panic("Object ended but not started"); } this.popContext(); @@ -272,7 +270,7 @@ export abstract class CompressedJSON { protected finishArray(): void { const arr = this.context.currentArray; if (arr === undefined) { - return panic("Array ended but not started"); + panic("Array ended but not started"); } this.popContext(); @@ -360,7 +358,7 @@ export class CompressedJSONFromString extends CompressedJSON { this.finishObject(); } else { - return panic("Invalid JSON object"); + panic("Invalid JSON object"); } } } diff --git a/packages/quicktype-core/src/support/Strings.ts b/packages/quicktype-core/src/support/Strings.ts index 280a8e867c..a1fda25249 100644 --- a/packages/quicktype-core/src/support/Strings.ts +++ b/packages/quicktype-core/src/support/Strings.ts @@ -423,7 +423,7 @@ export function splitIntoWords(s: string): WordInName[] { function commitInterval(): void { if (intervalStart === undefined) { - return panic("Tried to commit interval without starting one"); + panic("Tried to commit interval without starting one"); } assert(i > intervalStart, "Interval must be non-empty"); diff --git a/packages/quicktype-core/src/support/Support.ts b/packages/quicktype-core/src/support/Support.ts index cdb1f456da..9968e160f9 100644 --- a/packages/quicktype-core/src/support/Support.ts +++ b/packages/quicktype-core/src/support/Support.ts @@ -98,7 +98,7 @@ export function assertNever(x: never): never { export function assert(condition: boolean, message = "Assertion failed"): void { if (!condition) { - return messageError("InternalError", { message }); + messageError("InternalError", { message }); } } From c552ebbe61a09327c737335d92c050dd9d0e55bb Mon Sep 17 00:00:00 2001 From: Mark Probst Date: Mon, 13 Jul 2026 09:51:11 -0400 Subject: [PATCH 08/68] Biome: enable noUselessContinue and fix violations One violation: a redundant trailing continue in breakCycles. Safe fix. Co-Authored-By: Claude Fable 5 --- biome.json | 1 - packages/quicktype-core/src/CycleBreaker.ts | 2 -- 2 files changed, 3 deletions(-) diff --git a/biome.json b/biome.json index dd73a2266e..6a21d2a2ce 100644 --- a/biome.json +++ b/biome.json @@ -25,7 +25,6 @@ "noBannedTypes": "off", "noExtraBooleanCast": "off", "noUselessConstructor": "off", - "noUselessContinue": "off", "noUselessSwitchCase": "off", "noUselessTernary": "off", "noUselessUndefinedInitialization": "off", diff --git a/packages/quicktype-core/src/CycleBreaker.ts b/packages/quicktype-core/src/CycleBreaker.ts index c070ed0229..64137ad96c 100644 --- a/packages/quicktype-core/src/CycleBreaker.ts +++ b/packages/quicktype-core/src/CycleBreaker.ts @@ -107,8 +107,6 @@ export function breakCycles( results.push([breakNode, info]); break; } - - continue; } return results; From cabd0454fc8a398eb2689670fbf3bebcf65ae40c Mon Sep 17 00:00:00 2001 From: Mark Probst Date: Mon, 13 Jul 2026 09:52:03 -0400 Subject: [PATCH 09/68] Biome: enable noUselessSwitchCase and fix violations One violation: a "java8" case clause that fell through to an adjacent default clause with the same body. Co-Authored-By: Claude Fable 5 --- biome.json | 1 - packages/quicktype-core/src/language/Java/JavaRenderer.ts | 1 - 2 files changed, 2 deletions(-) diff --git a/biome.json b/biome.json index 6a21d2a2ce..c6995bf49b 100644 --- a/biome.json +++ b/biome.json @@ -25,7 +25,6 @@ "noBannedTypes": "off", "noExtraBooleanCast": "off", "noUselessConstructor": "off", - "noUselessSwitchCase": "off", "noUselessTernary": "off", "noUselessUndefinedInitialization": "off", "useDateNow": "off", diff --git a/packages/quicktype-core/src/language/Java/JavaRenderer.ts b/packages/quicktype-core/src/language/Java/JavaRenderer.ts index ce0fc3b741..90cab266af 100644 --- a/packages/quicktype-core/src/language/Java/JavaRenderer.ts +++ b/packages/quicktype-core/src/language/Java/JavaRenderer.ts @@ -74,7 +74,6 @@ export class JavaRenderer extends ConvenienceRenderer { this._converterClassname, ); break; - case "java8": default: this._dateTimeProvider = new Java8DateTimeProvider( this, From 9a54dcf44e6713c083dabf1e1c7e17256867eee2 Mon Sep 17 00:00:00 2001 From: Mark Probst Date: Mon, 13 Jul 2026 09:52:48 -0400 Subject: [PATCH 10/68] Biome: enable noUselessTernary and fix violations One violation: "propCount ? false : true" simplified to "!propCount". Co-Authored-By: Claude Fable 5 --- biome.json | 1 - packages/quicktype-core/src/language/Elixir/ElixirRenderer.ts | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/biome.json b/biome.json index c6995bf49b..3a0e422295 100644 --- a/biome.json +++ b/biome.json @@ -25,7 +25,6 @@ "noBannedTypes": "off", "noExtraBooleanCast": "off", "noUselessConstructor": "off", - "noUselessTernary": "off", "noUselessUndefinedInitialization": "off", "useDateNow": "off", "useOptionalChain": "off" diff --git a/packages/quicktype-core/src/language/Elixir/ElixirRenderer.ts b/packages/quicktype-core/src/language/Elixir/ElixirRenderer.ts index 98d58336f7..ff09e39066 100644 --- a/packages/quicktype-core/src/language/Elixir/ElixirRenderer.ts +++ b/packages/quicktype-core/src/language/Elixir/ElixirRenderer.ts @@ -942,7 +942,7 @@ export class ElixirRenderer extends ConvenienceRenderer { this.forEachClassProperty(c, "none", (_name, _jsonName, _p) => { propCount++; }); - const isEmpty = propCount ? false : true; + const isEmpty = !propCount; this.ensureBlankLine(); this.emitBlock( [`def from_map(${isEmpty ? "_" : ""}m) do`], From e8f54045caf9efba110b13c9d2f51e8703580b83 Mon Sep 17 00:00:00 2001 From: Mark Probst Date: Mon, 13 Jul 2026 09:53:38 -0400 Subject: [PATCH 11/68] Biome: enable noExtraBooleanCast and fix violations Two violations: redundant double-negations in boolean conditions in the test helpers. Co-Authored-By: Claude Fable 5 --- biome.json | 1 - test/lib/deepEquals.ts | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/biome.json b/biome.json index 3a0e422295..82bae60652 100644 --- a/biome.json +++ b/biome.json @@ -23,7 +23,6 @@ "preset": "recommended", "complexity": { "noBannedTypes": "off", - "noExtraBooleanCast": "off", "noUselessConstructor": "off", "noUselessUndefinedInitialization": "off", "useDateNow": "off", diff --git a/test/lib/deepEquals.ts b/test/lib/deepEquals.ts index eaeb1209a5..c3b38b5df1 100644 --- a/test/lib/deepEquals.ts +++ b/test/lib/deepEquals.ts @@ -77,7 +77,7 @@ export default function deepEquals( return false; } if ( - !!relax.allowStringifiedIntegers && + relax.allowStringifiedIntegers && typeof x === "string" && typeof y === "number" ) { @@ -155,7 +155,7 @@ export default function deepEquals( for (const p of xKeys) { if (yKeys.indexOf(p) < 0) { - if (!!relax.allowMissingNull && x[p] === null) { + if (relax.allowMissingNull && x[p] === null) { continue; } console.error( From 19036540d7a98402ee7d41e5f35ff596367e4e8f Mon Sep 17 00:00:00 2001 From: Mark Probst Date: Mon, 13 Jul 2026 09:54:14 -0400 Subject: [PATCH 12/68] Biome: enable useDateNow and fix violations Two violations: "+new Date()" timing code in the test harness replaced with Date.now(). Co-Authored-By: Claude Fable 5 --- biome.json | 1 - test/utils.ts | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/biome.json b/biome.json index 82bae60652..a39ef4e4d8 100644 --- a/biome.json +++ b/biome.json @@ -25,7 +25,6 @@ "noBannedTypes": "off", "noUselessConstructor": "off", "noUselessUndefinedInitialization": "off", - "useDateNow": "off", "useOptionalChain": "off" }, "style": { diff --git a/test/utils.ts b/test/utils.ts index b532a2e8f5..db98e3101b 100644 --- a/test/utils.ts +++ b/test/utils.ts @@ -96,9 +96,9 @@ export function execAsync( } async function time(work: () => Promise): Promise<[T, number]> { - const start = +new Date(); + const start = Date.now(); const result = await work(); - const end = +new Date(); + const end = Date.now(); return [result, end - start]; } From 33af22f982f5cc152419743954899b9ad1432ad9 Mon Sep 17 00:00:00 2001 From: Mark Probst Date: Mon, 13 Jul 2026 09:55:18 -0400 Subject: [PATCH 13/68] Biome: enable useOptionalChain and fix violations One violation: an undefined-check-plus-method-call collapsed into an optional chain. Co-Authored-By: Claude Fable 5 --- biome.json | 3 +-- packages/quicktype-core/src/ConvenienceRenderer.ts | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/biome.json b/biome.json index a39ef4e4d8..f1d5dd1db5 100644 --- a/biome.json +++ b/biome.json @@ -24,8 +24,7 @@ "complexity": { "noBannedTypes": "off", "noUselessConstructor": "off", - "noUselessUndefinedInitialization": "off", - "useOptionalChain": "off" + "noUselessUndefinedInitialization": "off" }, "style": { "noNonNullAssertion": "off", diff --git a/packages/quicktype-core/src/ConvenienceRenderer.ts b/packages/quicktype-core/src/ConvenienceRenderer.ts index 77b09d3a56..6c697f02fb 100644 --- a/packages/quicktype-core/src/ConvenienceRenderer.ts +++ b/packages/quicktype-core/src/ConvenienceRenderer.ts @@ -1275,7 +1275,7 @@ export abstract class ConvenienceRenderer extends Renderer { // A quote at the end of the line would merge with a closing // `"""` emitted right after it. The quote needs escaping iff // it's preceded by an even number of backslashes. - if (lineEnd !== undefined && lineEnd.startsWith('"')) { + if (lineEnd?.startsWith('"')) { const trailing = /(\\*)"$/.exec(escaped); if (trailing !== null && trailing[1].length % 2 === 0) { escaped = `${escaped.slice(0, -1)}\\"`; From f1488077e2b2c9e7ab6af72af70ba73b5e736153 Mon Sep 17 00:00:00 2001 From: Mark Probst Date: Mon, 13 Jul 2026 09:56:20 -0400 Subject: [PATCH 14/68] Biome: enable noUselessConstructor and fix violations Seven violations: constructors that only forwarded their arguments to super with no other work. Removed them along with the type imports that only they used. Co-Authored-By: Claude Fable 5 --- biome.json | 1 - packages/quicktype-core/src/ConvenienceRenderer.ts | 9 --------- .../src/language/Crystal/CrystalRenderer.ts | 9 --------- .../src/language/Java/JavaJacksonRenderer.ts | 12 ------------ .../src/language/Kotlin/KotlinJacksonRenderer.ts | 12 ------------ .../src/language/Kotlin/KotlinKlaxonRenderer.ts | 12 ------------ .../src/language/Kotlin/KotlinXRenderer.ts | 12 ------------ test/fixtures.ts | 4 ---- 8 files changed, 71 deletions(-) diff --git a/biome.json b/biome.json index f1d5dd1db5..5df4c83a94 100644 --- a/biome.json +++ b/biome.json @@ -23,7 +23,6 @@ "preset": "recommended", "complexity": { "noBannedTypes": "off", - "noUselessConstructor": "off", "noUselessUndefinedInitialization": "off" }, "style": { diff --git a/packages/quicktype-core/src/ConvenienceRenderer.ts b/packages/quicktype-core/src/ConvenienceRenderer.ts index 6c697f02fb..666114e3a9 100644 --- a/packages/quicktype-core/src/ConvenienceRenderer.ts +++ b/packages/quicktype-core/src/ConvenienceRenderer.ts @@ -39,7 +39,6 @@ import { import { type BlankLineConfig, type ForEachPosition, - type RenderContext, Renderer, } from "./Renderer.js"; import { @@ -54,7 +53,6 @@ import { } from "./support/Comments.js"; import { trimEnd } from "./support/Strings.js"; import { assert, defined, nonNull, panic } from "./support/Support.js"; -import type { TargetLanguage } from "./TargetLanguage.js"; import { type Transformation, followTargetType, @@ -177,13 +175,6 @@ export abstract class ConvenienceRenderer extends Renderer { private _alphabetizeProperties = false; - public constructor( - targetLanguage: TargetLanguage, - renderContext: RenderContext, - ) { - super(targetLanguage, renderContext); - } - public get topLevels(): ReadonlyMap { return this.typeGraph.topLevels; } diff --git a/packages/quicktype-core/src/language/Crystal/CrystalRenderer.ts b/packages/quicktype-core/src/language/Crystal/CrystalRenderer.ts index 4417d1dc90..2d1b40640f 100644 --- a/packages/quicktype-core/src/language/Crystal/CrystalRenderer.ts +++ b/packages/quicktype-core/src/language/Crystal/CrystalRenderer.ts @@ -7,9 +7,7 @@ import { type ForbiddenWordsInfo, } from "../../ConvenienceRenderer.js"; import type { Name, Namer } from "../../Naming.js"; -import type { RenderContext } from "../../Renderer.js"; import { type Sourcelike, maybeAnnotated } from "../../Source.js"; -import type { TargetLanguage } from "../../TargetLanguage.js"; import { matchType, nullableFromUnion, @@ -25,13 +23,6 @@ import { } from "./utils.js"; export class CrystalRenderer extends ConvenienceRenderer { - public constructor( - targetLanguage: TargetLanguage, - renderContext: RenderContext, - ) { - super(targetLanguage, renderContext); - } - protected makeNamedTypeNamer(): Namer { return camelNamingFunction; } diff --git a/packages/quicktype-core/src/language/Java/JavaJacksonRenderer.ts b/packages/quicktype-core/src/language/Java/JavaJacksonRenderer.ts index 46d757ed48..934b1afa2b 100644 --- a/packages/quicktype-core/src/language/Java/JavaJacksonRenderer.ts +++ b/packages/quicktype-core/src/language/Java/JavaJacksonRenderer.ts @@ -1,9 +1,6 @@ import type { Name } from "../../Naming.js"; -import type { RenderContext } from "../../Renderer.js"; -import type { OptionValues } from "../../RendererOptions/index.js"; import type { Sourcelike } from "../../Source.js"; import { assertNever, panic } from "../../support/Support.js"; -import type { TargetLanguage } from "../../TargetLanguage.js"; import { ArrayType, type ClassProperty, @@ -16,18 +13,9 @@ import { import { removeNullFromUnion } from "../../Type/TypeUtils.js"; import { JavaRenderer } from "./JavaRenderer.js"; -import type { javaOptions } from "./language.js"; import { stringEscape } from "./utils.js"; export class JacksonRenderer extends JavaRenderer { - public constructor( - targetLanguage: TargetLanguage, - renderContext: RenderContext, - options: OptionValues, - ) { - super(targetLanguage, renderContext, options); - } - protected readonly _converterKeywords: string[] = [ "JsonProperty", "JsonDeserialize", diff --git a/packages/quicktype-core/src/language/Kotlin/KotlinJacksonRenderer.ts b/packages/quicktype-core/src/language/Kotlin/KotlinJacksonRenderer.ts index e9c9966413..356cc8acea 100644 --- a/packages/quicktype-core/src/language/Kotlin/KotlinJacksonRenderer.ts +++ b/packages/quicktype-core/src/language/Kotlin/KotlinJacksonRenderer.ts @@ -1,12 +1,9 @@ import { arrayIntercalate, iterableSome } from "collection-utils"; import type { Name } from "../../Naming.js"; -import type { RenderContext } from "../../Renderer.js"; -import type { OptionValues } from "../../RendererOptions/index.js"; import { type Sourcelike, modifySource } from "../../Source.js"; import { camelCase } from "../../support/Strings.js"; import { mustNotHappen } from "../../support/Support.js"; -import type { TargetLanguage } from "../../TargetLanguage.js"; import { type ArrayType, ClassType, @@ -19,18 +16,9 @@ import { import { matchType, nullableFromUnion } from "../../Type/TypeUtils.js"; import { KotlinRenderer } from "./KotlinRenderer.js"; -import type { kotlinOptions } from "./language.js"; import { stringEscape } from "./utils.js"; export class KotlinJacksonRenderer extends KotlinRenderer { - public constructor( - targetLanguage: TargetLanguage, - renderContext: RenderContext, - _kotlinOptions: OptionValues, - ) { - super(targetLanguage, renderContext, _kotlinOptions); - } - private unionMemberJsonValueGuard(t: Type, _e: Sourcelike): Sourcelike { return matchType( t, diff --git a/packages/quicktype-core/src/language/Kotlin/KotlinKlaxonRenderer.ts b/packages/quicktype-core/src/language/Kotlin/KotlinKlaxonRenderer.ts index 8b8ba8cd48..cb803f3e6d 100644 --- a/packages/quicktype-core/src/language/Kotlin/KotlinKlaxonRenderer.ts +++ b/packages/quicktype-core/src/language/Kotlin/KotlinKlaxonRenderer.ts @@ -1,12 +1,9 @@ import { arrayIntercalate, iterableSome } from "collection-utils"; import type { Name } from "../../Naming.js"; -import type { RenderContext } from "../../Renderer.js"; -import type { OptionValues } from "../../RendererOptions/index.js"; import { type Sourcelike, modifySource } from "../../Source.js"; import { camelCase } from "../../support/Strings.js"; import { mustNotHappen } from "../../support/Support.js"; -import type { TargetLanguage } from "../../TargetLanguage.js"; import { type ArrayType, ClassType, @@ -19,18 +16,9 @@ import { import { matchType, nullableFromUnion } from "../../Type/TypeUtils.js"; import { KotlinRenderer } from "./KotlinRenderer.js"; -import type { kotlinOptions } from "./language.js"; import { stringEscape } from "./utils.js"; export class KotlinKlaxonRenderer extends KotlinRenderer { - public constructor( - targetLanguage: TargetLanguage, - renderContext: RenderContext, - _kotlinOptions: OptionValues, - ) { - super(targetLanguage, renderContext, _kotlinOptions); - } - private unionMemberFromJsonValue(t: Type, e: Sourcelike): Sourcelike { return matchType( t, diff --git a/packages/quicktype-core/src/language/Kotlin/KotlinXRenderer.ts b/packages/quicktype-core/src/language/Kotlin/KotlinXRenderer.ts index ade481b9db..e358f23aaa 100644 --- a/packages/quicktype-core/src/language/Kotlin/KotlinXRenderer.ts +++ b/packages/quicktype-core/src/language/Kotlin/KotlinXRenderer.ts @@ -1,13 +1,9 @@ import type { Name } from "../../Naming.js"; -import type { RenderContext } from "../../Renderer.js"; -import type { OptionValues } from "../../RendererOptions/index.js"; import { type Sourcelike, modifySource } from "../../Source.js"; import { camelCase } from "../../support/Strings.js"; -import type { TargetLanguage } from "../../TargetLanguage.js"; import type { ArrayType, EnumType, MapType, Type } from "../../Type/index.js"; import { KotlinRenderer } from "./KotlinRenderer.js"; -import type { kotlinOptions } from "./language.js"; import { stringEscape } from "./utils.js"; /** @@ -15,14 +11,6 @@ import { stringEscape } from "./utils.js"; * TODO: Union, Any, Top Level Array, Top Level Map */ export class KotlinXRenderer extends KotlinRenderer { - public constructor( - targetLanguage: TargetLanguage, - renderContext: RenderContext, - _kotlinOptions: OptionValues, - ) { - super(targetLanguage, renderContext, _kotlinOptions); - } - protected anySourceType(optional: string): Sourcelike { return ["JsonElement", optional]; } diff --git a/test/fixtures.ts b/test/fixtures.ts index 0472762b33..bca6c4985d 100644 --- a/test/fixtures.ts +++ b/test/fixtures.ts @@ -216,10 +216,6 @@ export abstract class Fixture { } abstract class LanguageFixture extends Fixture { - constructor(language: languages.Language) { - super(language); - } - async setup() { const setupCommand = this.language.setupCommand; if (!setupCommand || ONLY_OUTPUT) { From 1de619b4d950867fbcdcbf2befde9b1d39b4a95c Mon Sep 17 00:00:00 2001 From: Mark Probst Date: Mon, 13 Jul 2026 09:57:10 -0400 Subject: [PATCH 15/68] Biome: enable noUselessUndefinedInitialization and fix violations 24 violations: "let x: T | undefined = undefined" initializers where the explicit "= undefined" is redundant. Co-Authored-By: Claude Fable 5 --- biome.json | 3 +-- packages/quicktype-core/src/MakeTransformations.ts | 2 +- packages/quicktype-core/src/UnifyClasses.ts | 2 +- packages/quicktype-core/src/UnionBuilder.ts | 2 +- packages/quicktype-core/src/attributes/Constraints.ts | 4 ++-- packages/quicktype-core/src/input/CompressedJSON.ts | 2 +- packages/quicktype-core/src/input/JSONSchemaInput.ts | 3 +-- packages/quicktype-core/src/input/PostmanCollection.ts | 2 +- .../src/language/CSharp/CSharpRenderer.ts | 2 +- .../quicktype-core/src/language/Elm/ElmRenderer.ts | 2 +- .../quicktype-core/src/language/Swift/SwiftRenderer.ts | 2 +- packages/quicktype-core/src/rewrites/CombineClasses.ts | 2 +- packages/quicktype-core/src/rewrites/InferMaps.ts | 4 ++-- packages/quicktype-core/src/support/Strings.ts | 4 ++-- packages/quicktype-vscode/src/extension.ts | 6 +++--- src/index.ts | 10 +++++----- 16 files changed, 25 insertions(+), 27 deletions(-) diff --git a/biome.json b/biome.json index 5df4c83a94..c35359e45e 100644 --- a/biome.json +++ b/biome.json @@ -22,8 +22,7 @@ "rules": { "preset": "recommended", "complexity": { - "noBannedTypes": "off", - "noUselessUndefinedInitialization": "off" + "noBannedTypes": "off" }, "style": { "noNonNullAssertion": "off", diff --git a/packages/quicktype-core/src/MakeTransformations.ts b/packages/quicktype-core/src/MakeTransformations.ts index 9fada44df6..664a8f7c96 100644 --- a/packages/quicktype-core/src/MakeTransformations.ts +++ b/packages/quicktype-core/src/MakeTransformations.ts @@ -175,7 +175,7 @@ function replaceUnion( ); } - let maybeStringType: TypeRef | undefined = undefined; + let maybeStringType: TypeRef | undefined; function getStringType(): TypeRef { if (maybeStringType === undefined) { maybeStringType = builder.getStringType( diff --git a/packages/quicktype-core/src/UnifyClasses.ts b/packages/quicktype-core/src/UnifyClasses.ts index 9c90739220..b3faa9638f 100644 --- a/packages/quicktype-core/src/UnifyClasses.ts +++ b/packages/quicktype-core/src/UnifyClasses.ts @@ -36,7 +36,7 @@ function getCliqueProperties( const properties = Array.from(propertyNames).map( (name) => [name, new Set(), false] as [string, Set, boolean], ); - let additionalProperties: Set | undefined = undefined; + let additionalProperties: Set | undefined; for (const o of clique) { const additional = o.getAdditionalProperties(); if (additional !== undefined) { diff --git a/packages/quicktype-core/src/UnionBuilder.ts b/packages/quicktype-core/src/UnionBuilder.ts index a5438ee7af..1e9f0229bd 100644 --- a/packages/quicktype-core/src/UnionBuilder.ts +++ b/packages/quicktype-core/src/UnionBuilder.ts @@ -153,7 +153,7 @@ export class UnionAccumulator attributes: TypeAttributes, stringTypes: StringTypes | undefined, ): void { - let stringTypesAttributes: TypeAttributes | undefined = undefined; + let stringTypesAttributes: TypeAttributes | undefined; if (stringTypes === undefined) { stringTypes = stringTypesTypeAttributeKind.tryGetInAttributes(attributes); diff --git a/packages/quicktype-core/src/attributes/Constraints.ts b/packages/quicktype-core/src/attributes/Constraints.ts index fca207276f..a4c11a4561 100644 --- a/packages/quicktype-core/src/attributes/Constraints.ts +++ b/packages/quicktype-core/src/attributes/Constraints.ts @@ -137,8 +137,8 @@ function producer( ): MinMaxConstraint | undefined { if (!(typeof schema === "object")) return undefined; - let min: number | undefined = undefined; - let max: number | undefined = undefined; + let min: number | undefined; + let max: number | undefined; if (typeof schema[minProperty] === "number") { min = schema[minProperty]; diff --git a/packages/quicktype-core/src/input/CompressedJSON.ts b/packages/quicktype-core/src/input/CompressedJSON.ts index d05d2ea289..56272edbe9 100644 --- a/packages/quicktype-core/src/input/CompressedJSON.ts +++ b/packages/quicktype-core/src/input/CompressedJSON.ts @@ -182,7 +182,7 @@ export abstract class CompressedJSON { } protected commitString(s: string): void { - let value: Value | undefined = undefined; + let value: Value | undefined; if (this.handleRefs && this.isExpectingRef) { value = this.makeString(s); } else { diff --git a/packages/quicktype-core/src/input/JSONSchemaInput.ts b/packages/quicktype-core/src/input/JSONSchemaInput.ts index 68f43be337..e29b29b658 100644 --- a/packages/quicktype-core/src/input/JSONSchemaInput.ts +++ b/packages/quicktype-core/src/input/JSONSchemaInput.ts @@ -926,8 +926,7 @@ async function addTypesInSchema( } const includedTypes = setFilter(schemaTypes, isTypeIncluded); - let producedAttributesForNoCases: JSONSchemaAttributes[] | undefined = - undefined; + let producedAttributesForNoCases: JSONSchemaAttributes[] | undefined; function forEachProducedAttribute( cases: JSONSchema[] | undefined, diff --git a/packages/quicktype-core/src/input/PostmanCollection.ts b/packages/quicktype-core/src/input/PostmanCollection.ts index 85506c205f..86b8fe8f32 100644 --- a/packages/quicktype-core/src/input/PostmanCollection.ts +++ b/packages/quicktype-core/src/input/PostmanCollection.ts @@ -96,7 +96,7 @@ export function sourcesFromPostmanCollection( ); const joinedDescription = descriptions.join("\n\n").trim(); - let description: string | undefined = undefined; + let description: string | undefined; if (joinedDescription !== "") { description = joinedDescription; } diff --git a/packages/quicktype-core/src/language/CSharp/CSharpRenderer.ts b/packages/quicktype-core/src/language/CSharp/CSharpRenderer.ts index b0d55a653d..7162c4938b 100644 --- a/packages/quicktype-core/src/language/CSharp/CSharpRenderer.ts +++ b/packages/quicktype-core/src/language/CSharp/CSharpRenderer.ts @@ -294,7 +294,7 @@ export class CSharpRenderer extends ConvenienceRenderer { : "none"; const columns: Sourcelike[][] = []; let isFirstProperty = true; - let previousDescription: string[] | undefined = undefined; + let previousDescription: string[] | undefined; this.forEachClassProperty( c, blankLines, diff --git a/packages/quicktype-core/src/language/Elm/ElmRenderer.ts b/packages/quicktype-core/src/language/Elm/ElmRenderer.ts index 386bd79633..6430743bd3 100644 --- a/packages/quicktype-core/src/language/Elm/ElmRenderer.ts +++ b/packages/quicktype-core/src/language/Elm/ElmRenderer.ts @@ -75,7 +75,7 @@ export class ElmRenderer extends ConvenienceRenderer { topLevelName.order, (lookup) => `${lookup(topLevelName)}_to_string`, ); - let decoder: DependencyName | undefined = undefined; + let decoder: DependencyName | undefined; if (this.namedTypeToNameForTopLevel(t) === undefined) { decoder = new DependencyName( lowerNamingFunction, diff --git a/packages/quicktype-core/src/language/Swift/SwiftRenderer.ts b/packages/quicktype-core/src/language/Swift/SwiftRenderer.ts index b9fae90ee9..2ec21da902 100644 --- a/packages/quicktype-core/src/language/Swift/SwiftRenderer.ts +++ b/packages/quicktype-core/src/language/Swift/SwiftRenderer.ts @@ -515,7 +515,7 @@ export class SwiftRenderer extends ConvenienceRenderer { ], () => { if (this._options.dense) { - let lastProperty: ClassProperty | undefined = undefined; + let lastProperty: ClassProperty | undefined; let lastNames: Name[] = []; const emitLastProperty = (): void => { diff --git a/packages/quicktype-core/src/rewrites/CombineClasses.ts b/packages/quicktype-core/src/rewrites/CombineClasses.ts index 8c5fa31cc5..37c45dc3ec 100644 --- a/packages/quicktype-core/src/rewrites/CombineClasses.ts +++ b/packages/quicktype-core/src/rewrites/CombineClasses.ts @@ -142,7 +142,7 @@ function findSimilarityCliques( const cliques: Clique[] = []; for (const c of classCandidates) { - let cliqueIndex: number | undefined = undefined; + let cliqueIndex: number | undefined; for (let i = 0; i < cliques.length; i++) { if (tryAddToClique(c, cliques[i], onlyWithSameProperties)) { cliqueIndex = i; diff --git a/packages/quicktype-core/src/rewrites/InferMaps.ts b/packages/quicktype-core/src/rewrites/InferMaps.ts index 734cccaafe..d7b763e962 100644 --- a/packages/quicktype-core/src/rewrites/InferMaps.ts +++ b/packages/quicktype-core/src/rewrites/InferMaps.ts @@ -19,7 +19,7 @@ import { unifyTypes, unionBuilderForUnification } from "../UnifyClasses.js"; const mapSizeThreshold = 20; const stringMapSizeThreshold = 50; -let markovChain: MarkovChain | undefined = undefined; +let markovChain: MarkovChain | undefined; function nameProbability(name: string): number { if (markovChain === undefined) { @@ -92,7 +92,7 @@ function shouldBeMap( // 1. All property types are null. // 2. Some property types are null or nullable. // 3. No property types are null or nullable. - let firstNonNullCases: ReadonlySet | undefined = undefined; + let firstNonNullCases: ReadonlySet | undefined; const allCases = new Set(); let canBeMap = true; // Check that all the property types are the same, modulo nullability. diff --git a/packages/quicktype-core/src/support/Strings.ts b/packages/quicktype-core/src/support/Strings.ts index a1fda25249..0cc3ff63a1 100644 --- a/packages/quicktype-core/src/support/Strings.ts +++ b/packages/quicktype-core/src/support/Strings.ts @@ -371,10 +371,10 @@ const fastIsDigit = precomputedCodePointPredicate(isDigit); export function splitIntoWords(s: string): WordInName[] { // [start, end, allUpper] const intervals: Array<[number, number, boolean]> = []; - let intervalStart: number | undefined = undefined; + let intervalStart: number | undefined; const len = s.length; let i = 0; - let lastLowerCaseIndex: number | undefined = undefined; + let lastLowerCaseIndex: number | undefined; function atEnd(): boolean { return i >= len; diff --git a/packages/quicktype-vscode/src/extension.ts b/packages/quicktype-vscode/src/extension.ts index 6982101368..256eb8e485 100644 --- a/packages/quicktype-vscode/src/extension.ts +++ b/packages/quicktype-vscode/src/extension.ts @@ -411,12 +411,12 @@ function deduceTargetLanguage(): TargetLanguage { const lastTargetLanguageUsedKey = "lastTargetLanguageUsed"; -let extensionContext: vscode.ExtensionContext | undefined = undefined; +let extensionContext: vscode.ExtensionContext | undefined; const codeProviders: Map = new Map(); -let lastCodeProvider: CodeProvider | undefined = undefined; -let explicitlySetTargetLanguage: TargetLanguage | undefined = undefined; +let lastCodeProvider: CodeProvider | undefined; +let explicitlySetTargetLanguage: TargetLanguage | undefined; async function openQuicktype( inputKind: InputKind, diff --git a/src/index.ts b/src/index.ts index 179f1b6f50..85c89f651e 100644 --- a/src/index.ts +++ b/src/index.ts @@ -137,8 +137,8 @@ async function samplesFromDirectory( // Each file is a (Name, JSON | URL) const sourcesInDir: TypeSource[] = []; const graphQLSources: GraphQLTypeSource[] = []; - let graphQLSchema: Readable | undefined = undefined; - let graphQLSchemaFileName: string | undefined = undefined; + let graphQLSchema: Readable | undefined; + let graphQLSchemaFileName: string | undefined; for (let file of files) { const name = typeNameFromFilename(file); @@ -987,11 +987,11 @@ export async function makeQuicktypeOptions( } let sources: TypeSource[] = []; - let leadingComments: string[] | undefined = undefined; + let leadingComments: string[] | undefined; let fixedTopLevels = false; switch (options.srcLang) { case "graphql": { - let schemaString: string | undefined = undefined; + let schemaString: string | undefined; let wroteSchemaToFile = false; if (options.graphqlIntrospect !== undefined) { schemaString = await introspectServer( @@ -1024,7 +1024,7 @@ export async function makeQuicktypeOptions( const gqlSources: GraphQLTypeSource[] = []; for (const queryFile of options.src) { - let schemaFileName: string | undefined = undefined; + let schemaFileName: string | undefined; if (schemaString === undefined) { schemaFileName = defined(options.graphqlSchema); schemaString = fs.readFileSync(schemaFileName, "utf8"); From aef7601039eb9d17ca97f010af187801e3c5378b Mon Sep 17 00:00:00 2001 From: Mark Probst Date: Mon, 13 Jul 2026 09:58:37 -0400 Subject: [PATCH 16/68] Biome: enable noBannedTypes and fix violations Thirteen violations of the banned "{}" type: eight "properties: {}" members in the ErrorProperties union and five "getOptions(): {}" signatures in option-less target languages. All replaced with the precise Record empty-object type. Co-Authored-By: Claude Fable 5 --- biome.json | 3 --- packages/quicktype-core/src/Messages.ts | 25 +++++++++++++------ .../src/language/Crystal/language.ts | 2 +- .../src/language/JSONSchema/language.ts | 2 +- .../src/language/Pike/language.ts | 2 +- .../TypeScriptEffectSchema/language.ts | 2 +- .../src/language/TypeScriptZod/language.ts | 2 +- 7 files changed, 22 insertions(+), 16 deletions(-) diff --git a/biome.json b/biome.json index c35359e45e..356fc3b741 100644 --- a/biome.json +++ b/biome.json @@ -21,9 +21,6 @@ "enabled": true, "rules": { "preset": "recommended", - "complexity": { - "noBannedTypes": "off" - }, "style": { "noNonNullAssertion": "off", "useConst": "off", diff --git a/packages/quicktype-core/src/Messages.ts b/packages/quicktype-core/src/Messages.ts index cd5be05f82..ea9aba3d6d 100644 --- a/packages/quicktype-core/src/Messages.ts +++ b/packages/quicktype-core/src/Messages.ts @@ -14,7 +14,10 @@ export type ErrorProperties = kind: "MiscReadError"; properties: { fileOrURL: string; message: string }; } - | { kind: "MiscUnicodeHighSurrogateWithoutLowSurrogate"; properties: {} } + | { + kind: "MiscUnicodeHighSurrogateWithoutLowSurrogate"; + properties: Record; + } | { kind: "MiscInvalidMinMaxConstraint"; properties: { max: number; min: number }; @@ -98,21 +101,24 @@ export type ErrorProperties = | { kind: "SchemaFetchErrorAdditional"; properties: { address: string } } // GraphQL input - | { kind: "GraphQLNoQueriesDefined"; properties: {} } + | { kind: "GraphQLNoQueriesDefined"; properties: Record } // Driver | { kind: "DriverUnknownSourceLanguage"; properties: { lang: string } } | { kind: "DriverUnknownOutputLanguage"; properties: { lang: string } } | { kind: "DriverMoreThanOneInputGiven"; properties: { topLevel: string } } | { kind: "DriverCannotInferNameForSchema"; properties: { uri: string } } - | { kind: "DriverNoGraphQLQueryGiven"; properties: {} } + | { kind: "DriverNoGraphQLQueryGiven"; properties: Record } | { kind: "DriverNoGraphQLSchemaInDir"; properties: { dir: string } } | { kind: "DriverMoreThanOneGraphQLSchemaInDir"; properties: { dir: string }; } - | { kind: "DriverSourceLangMustBeGraphQL"; properties: {} } - | { kind: "DriverGraphQLSchemaNeeded"; properties: {} } + | { + kind: "DriverSourceLangMustBeGraphQL"; + properties: Record; + } + | { kind: "DriverGraphQLSchemaNeeded"; properties: Record } | { kind: "DriverInputFileDoesNotExist"; properties: { filename: string } } | { kind: "DriverCannotMixJSONWithOtherSamples"; @@ -120,16 +126,19 @@ export type ErrorProperties = } | { kind: "DriverCannotMixNonJSONInputs"; properties: { dir: string } } | { kind: "DriverUnknownDebugOption"; properties: { option: string } } - | { kind: "DriverNoLanguageOrExtension"; properties: {} } + | { kind: "DriverNoLanguageOrExtension"; properties: Record } | { kind: "DriverCLIOptionParsingFailed"; properties: { message: string } } // IR - | { kind: "IRNoForwardDeclarableTypeInCycle"; properties: {} } + | { + kind: "IRNoForwardDeclarableTypeInCycle"; + properties: Record; + } | { kind: "IRTypeAttributesNotPropagated"; properties: { count: number; indexes: number[] }; } - | { kind: "IRNoEmptyUnions"; properties: {} } + | { kind: "IRNoEmptyUnions"; properties: Record } // Rendering | { diff --git a/packages/quicktype-core/src/language/Crystal/language.ts b/packages/quicktype-core/src/language/Crystal/language.ts index f59c87a508..921ab392c7 100644 --- a/packages/quicktype-core/src/language/Crystal/language.ts +++ b/packages/quicktype-core/src/language/Crystal/language.ts @@ -24,7 +24,7 @@ export class CrystalTargetLanguage extends TargetLanguage< return " "; } - public getOptions(): {} { + public getOptions(): Record { return {}; } } diff --git a/packages/quicktype-core/src/language/JSONSchema/language.ts b/packages/quicktype-core/src/language/JSONSchema/language.ts index 1e6d503fa3..01890ee8cf 100644 --- a/packages/quicktype-core/src/language/JSONSchema/language.ts +++ b/packages/quicktype-core/src/language/JSONSchema/language.ts @@ -21,7 +21,7 @@ export class JSONSchemaTargetLanguage extends TargetLanguage< super(JSONSchemaLanguageConfig); } - public getOptions(): {} { + public getOptions(): Record { return {}; } diff --git a/packages/quicktype-core/src/language/Pike/language.ts b/packages/quicktype-core/src/language/Pike/language.ts index f34100db97..7ecdd67917 100644 --- a/packages/quicktype-core/src/language/Pike/language.ts +++ b/packages/quicktype-core/src/language/Pike/language.ts @@ -18,7 +18,7 @@ export class PikeTargetLanguage extends TargetLanguage< super(pikeLanguageConfig); } - public getOptions(): {} { + public getOptions(): Record { return {}; } diff --git a/packages/quicktype-core/src/language/TypeScriptEffectSchema/language.ts b/packages/quicktype-core/src/language/TypeScriptEffectSchema/language.ts index 416487d7c7..9d4186722f 100644 --- a/packages/quicktype-core/src/language/TypeScriptEffectSchema/language.ts +++ b/packages/quicktype-core/src/language/TypeScriptEffectSchema/language.ts @@ -22,7 +22,7 @@ export class TypeScriptEffectSchemaTargetLanguage extends TargetLanguage< super(typeScriptEffectSchemaLanguageConfig); } - public getOptions(): {} { + public getOptions(): Record { return {}; } diff --git a/packages/quicktype-core/src/language/TypeScriptZod/language.ts b/packages/quicktype-core/src/language/TypeScriptZod/language.ts index 2e54bd4c10..22d5344204 100644 --- a/packages/quicktype-core/src/language/TypeScriptZod/language.ts +++ b/packages/quicktype-core/src/language/TypeScriptZod/language.ts @@ -27,7 +27,7 @@ export class TypeScriptZodTargetLanguage extends TargetLanguage< super(typeScriptZodLanguageConfig); } - public getOptions(): {} { + public getOptions(): Record { return {}; } From 1687b36a8686ffb35986c6d983b06bb26aa88d12 Mon Sep 17 00:00:00 2001 From: Mark Probst Date: Mon, 13 Jul 2026 09:59:14 -0400 Subject: [PATCH 17/68] Biome: enable useConst and fix violations One violation: a never-reassigned "let" arrow function changed to "const". Co-Authored-By: Claude Fable 5 --- biome.json | 1 - packages/quicktype-core/src/language/CSharp/CSharpRenderer.ts | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/biome.json b/biome.json index 356fc3b741..adc8fcb0e2 100644 --- a/biome.json +++ b/biome.json @@ -23,7 +23,6 @@ "preset": "recommended", "style": { "noNonNullAssertion": "off", - "useConst": "off", "useExponentiationOperator": "off", "useNodejsImportProtocol": "off", "useTemplate": "off" diff --git a/packages/quicktype-core/src/language/CSharp/CSharpRenderer.ts b/packages/quicktype-core/src/language/CSharp/CSharpRenderer.ts index 7162c4938b..00c6848b13 100644 --- a/packages/quicktype-core/src/language/CSharp/CSharpRenderer.ts +++ b/packages/quicktype-core/src/language/CSharp/CSharpRenderer.ts @@ -538,7 +538,7 @@ export class CSharpRenderer extends ConvenienceRenderer { protected emitDependencyUsings(): void { let genericEmited: boolean = false; - let ensureGenericOnce = () => { + const ensureGenericOnce = () => { if (!genericEmited) { this.emitUsing("System.Collections.Generic"); genericEmited = true; From b06415a66308802598579e2d4853cbbd40ae9e4a Mon Sep 17 00:00:00 2001 From: Mark Probst Date: Mon, 13 Jul 2026 09:59:52 -0400 Subject: [PATCH 18/68] Biome: enable useExponentiationOperator and fix violations Six violations: Math.pow calls replaced with the ** operator. Co-Authored-By: Claude Fable 5 --- biome.json | 1 - packages/quicktype-core/src/MarkovChain.ts | 2 +- packages/quicktype-core/src/rewrites/InferMaps.ts | 8 ++++---- packages/quicktype-core/src/support/Chance.ts | 2 +- 4 files changed, 6 insertions(+), 7 deletions(-) diff --git a/biome.json b/biome.json index adc8fcb0e2..170202735a 100644 --- a/biome.json +++ b/biome.json @@ -23,7 +23,6 @@ "preset": "recommended", "style": { "noNonNullAssertion": "off", - "useExponentiationOperator": "off", "useNodejsImportProtocol": "off", "useTemplate": "off" }, diff --git a/packages/quicktype-core/src/MarkovChain.ts b/packages/quicktype-core/src/MarkovChain.ts index 32903223c3..ca256a6def 100644 --- a/packages/quicktype-core/src/MarkovChain.ts +++ b/packages/quicktype-core/src/MarkovChain.ts @@ -119,7 +119,7 @@ export function evaluateFull( p = p * cp; } - return [Math.pow(p, 1 / (word.length - depth + 1)), scores]; + return [p ** (1 / (word.length - depth + 1)), scores]; } export function evaluate(mc: MarkovChain, word: string): number { diff --git a/packages/quicktype-core/src/rewrites/InferMaps.ts b/packages/quicktype-core/src/rewrites/InferMaps.ts index d7b763e962..9987053070 100644 --- a/packages/quicktype-core/src/rewrites/InferMaps.ts +++ b/packages/quicktype-core/src/rewrites/InferMaps.ts @@ -61,7 +61,7 @@ function shouldBeMap( const names = Array.from(properties.keys()); const probabilities = names.map(nameProbability); const product = probabilities.reduce((a, b) => a * b, 1); - const probability = Math.pow(product, 1 / numProperties); + const probability = product ** (1 / numProperties); // The idea behind this is to have a probability around 0.0025 for // n=1, up to around 1.0 for n=20. I.e. when we only have a few // properties, they need to look really weird to infer a map, but @@ -76,10 +76,10 @@ function shouldBeMap( // we want maybe 0.004 and 5, or maybe something even more // trigger-happy. const exponent = 5; - const scale = Math.pow(22, exponent); + const scale = 22 ** exponent; const limit = - Math.pow(numProperties + 2, exponent) / scale + - (0.0025 - Math.pow(3, exponent) / scale); + (numProperties + 2) ** exponent / scale + + (0.0025 - 3 ** exponent / scale); if (probability > limit) return undefined; } diff --git a/packages/quicktype-core/src/support/Chance.ts b/packages/quicktype-core/src/support/Chance.ts index f4c553c5f8..eee1e7e58e 100644 --- a/packages/quicktype-core/src/support/Chance.ts +++ b/packages/quicktype-core/src/support/Chance.ts @@ -52,7 +52,7 @@ class MersenneTwister { public constructor(seed: number) { if (seed === undefined) { // kept random number same size as time used previously to ensure no unexpected results downstream - seed = Math.floor(Math.random() * Math.pow(10, 13)); + seed = Math.floor(Math.random() * 10 ** 13); } /* Period parameters */ From ebea804cf22873c64a8ea5b53b06f39e3d85131a Mon Sep 17 00:00:00 2001 From: Mark Probst Date: Mon, 13 Jul 2026 10:02:56 -0400 Subject: [PATCH 19/68] Biome: enable useNodejsImportProtocol and fix violations Six violations: bare Node.js builtin imports now use the node: protocol in the VS Code extension and the test harness. quicktype-core is exempted via a config override because its "browser" package.json field only remaps bare builtin specifiers ("fs"), not "node:fs" -- an invariant already enforced by test/unit/core-package.test.ts. Co-Authored-By: Claude Fable 5 --- biome.json | 11 ++++++++++- packages/quicktype-vscode/src/extension.ts | 2 +- test/languages.ts | 2 +- test/lib/multicore.ts | 4 ++-- 4 files changed, 14 insertions(+), 5 deletions(-) diff --git a/biome.json b/biome.json index 170202735a..6c8fa06256 100644 --- a/biome.json +++ b/biome.json @@ -23,7 +23,6 @@ "preset": "recommended", "style": { "noNonNullAssertion": "off", - "useNodejsImportProtocol": "off", "useTemplate": "off" }, "suspicious": { @@ -42,6 +41,16 @@ }, "assist": { "actions": { "source": { "organizeImports": "off" } } }, "overrides": [ + { + "includes": ["packages/quicktype-core/src/**"], + "linter": { + "rules": { + "style": { + "useNodejsImportProtocol": "off" + } + } + } + }, { "includes": ["**/tsconfig.json", "**/tsconfig.*.json"], "json": { diff --git a/packages/quicktype-vscode/src/extension.ts b/packages/quicktype-vscode/src/extension.ts index 256eb8e485..5211ae5ec6 100644 --- a/packages/quicktype-vscode/src/extension.ts +++ b/packages/quicktype-vscode/src/extension.ts @@ -1,4 +1,4 @@ -import * as path from "path"; +import * as path from "node:path"; import { InputData, diff --git a/test/languages.ts b/test/languages.ts index 8878247828..e158b266f6 100644 --- a/test/languages.ts +++ b/test/languages.ts @@ -1,6 +1,6 @@ import type { LanguageName } from "quicktype-core"; -import * as process from "process"; +import * as process from "node:process"; // @ts-ignore import type { RendererOptions } from "../dist/quicktype-core/Run"; diff --git a/test/lib/multicore.ts b/test/lib/multicore.ts index e67e1b943d..358c725284 100644 --- a/test/lib/multicore.ts +++ b/test/lib/multicore.ts @@ -1,5 +1,5 @@ -import cluster from "cluster"; -import process from "process"; +import cluster from "node:cluster"; +import process from "node:process"; import * as _ from "lodash"; const WORKERS = ["👷🏻", "👷🏼", "👷🏽", "👷🏾", "👷🏿"]; From 14763c50df9998facf0f1911e8a8b713ca99cda5 Mon Sep 17 00:00:00 2001 From: Mark Probst Date: Mon, 13 Jul 2026 10:04:04 -0400 Subject: [PATCH 20/68] Biome: enable noNonNullAssertion and fix violations Two violations in the System.Text.Json C# renderer: the transformers were already guarded against undefined, but the narrowing was lost inside emitBlock closures. Destructuring them into consts before the guard preserves the narrowing without assertions, matching the existing nullTransformer pattern in the same function. Co-Authored-By: Claude Fable 5 --- biome.json | 1 - .../src/language/CSharp/SystemTextJsonCSharpRenderer.ts | 9 +++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/biome.json b/biome.json index 6c8fa06256..e10e1315d1 100644 --- a/biome.json +++ b/biome.json @@ -22,7 +22,6 @@ "rules": { "preset": "recommended", "style": { - "noNonNullAssertion": "off", "useTemplate": "off" }, "suspicious": { diff --git a/packages/quicktype-core/src/language/CSharp/SystemTextJsonCSharpRenderer.ts b/packages/quicktype-core/src/language/CSharp/SystemTextJsonCSharpRenderer.ts index 70c4c8762b..9e39c2f270 100644 --- a/packages/quicktype-core/src/language/CSharp/SystemTextJsonCSharpRenderer.ts +++ b/packages/quicktype-core/src/language/CSharp/SystemTextJsonCSharpRenderer.ts @@ -663,9 +663,10 @@ export class SystemTextJsonCSharpRenderer extends CSharpRenderer { } // Handle number (integer/double) union properly + const { integerTransformer, doubleTransformer } = xfer; if ( - xfer.integerTransformer !== undefined && - xfer.doubleTransformer !== undefined + integerTransformer !== undefined && + doubleTransformer !== undefined ) { varGen.counter++; const intTryVar = `intTryValue${varGen.counter}`; @@ -680,7 +681,7 @@ export class SystemTextJsonCSharpRenderer extends CSharpRenderer { ); this.emitBlock(() => { const allHandled = this.emitDecodeTransformer( - xfer.integerTransformer!, + integerTransformer, targetType, emitFinish, intVar, @@ -693,7 +694,7 @@ export class SystemTextJsonCSharpRenderer extends CSharpRenderer { this.emitLine("else"); this.emitBlock(() => { const allHandled = this.emitDecodeTransformer( - xfer.doubleTransformer!, + doubleTransformer, targetType, emitFinish, doubleVar, From 7b4c90ab85e72b7a5393c5545a60dc91553a688b Mon Sep 17 00:00:00 2001 From: Mark Probst Date: Mon, 13 Jul 2026 10:04:53 -0400 Subject: [PATCH 21/68] Biome: enable useTemplate and fix violations Forty violations: string concatenations converted to template literals. All conversions are straight stringifications; escapes for literal ${, backticks, and backslash sequences were verified by hand. Co-Authored-By: Claude Fable 5 --- biome.json | 3 --- .../quicktype-core/src/ConvenienceRenderer.ts | 4 +-- packages/quicktype-core/src/Messages.ts | 2 +- .../src/language/Crystal/utils.ts | 4 +-- .../src/language/Elm/ElmRenderer.ts | 2 +- .../src/language/Golang/GolangRenderer.ts | 2 +- .../src/language/Kotlin/utils.ts | 2 +- .../src/language/Php/PhpRenderer.ts | 26 +++++++++---------- .../quicktype-core/src/language/Ruby/utils.ts | 4 +-- .../quicktype-core/src/language/Rust/utils.ts | 4 +-- .../src/language/Scala3/CirceRenderer.ts | 2 +- .../src/language/Scala3/Scala3Renderer.ts | 2 +- .../src/language/Scala3/utils.ts | 2 +- .../src/language/Smithy4s/Smithy4sRenderer.ts | 6 ++--- .../src/language/Swift/SwiftRenderer.ts | 2 +- .../src/language/Swift/utils.ts | 2 +- .../quicktype-core/src/support/Strings.ts | 6 ++--- src/index.ts | 4 +-- test/fixtures.ts | 2 +- test/lib/deepEquals.ts | 2 +- 20 files changed, 40 insertions(+), 43 deletions(-) diff --git a/biome.json b/biome.json index e10e1315d1..f0b0dd6e25 100644 --- a/biome.json +++ b/biome.json @@ -21,9 +21,6 @@ "enabled": true, "rules": { "preset": "recommended", - "style": { - "useTemplate": "off" - }, "suspicious": { "noExplicitAny": "off", "noGlobalIsNan": "off", diff --git a/packages/quicktype-core/src/ConvenienceRenderer.ts b/packages/quicktype-core/src/ConvenienceRenderer.ts index 666114e3a9..de5901e6e2 100644 --- a/packages/quicktype-core/src/ConvenienceRenderer.ts +++ b/packages/quicktype-core/src/ConvenienceRenderer.ts @@ -825,9 +825,9 @@ export abstract class ConvenienceRenderer extends Renderer { (_doubleType) => "double", (_stringType) => "string", (arrayType) => - typeNameForUnionMember(arrayType.items) + "_array", + `${typeNameForUnionMember(arrayType.items)}_array`, (classType) => lookup(this.nameForNamedType(classType)), - (mapType) => typeNameForUnionMember(mapType.values) + "_map", + (mapType) => `${typeNameForUnionMember(mapType.values)}_map`, (objectType) => { assert( this.targetLanguage.supportsFullObjectType, diff --git a/packages/quicktype-core/src/Messages.ts b/packages/quicktype-core/src/Messages.ts index ea9aba3d6d..30032e4e7e 100644 --- a/packages/quicktype-core/src/Messages.ts +++ b/packages/quicktype-core/src/Messages.ts @@ -297,7 +297,7 @@ export function messageError( valueString = value; } - userMessage = userMessage.replace("${" + name + "}", valueString); + userMessage = userMessage.replace(`\${${name}}`, valueString); } throw new QuickTypeError( diff --git a/packages/quicktype-core/src/language/Crystal/utils.ts b/packages/quicktype-core/src/language/Crystal/utils.ts index 56e037d82b..5dc85b9e64 100644 --- a/packages/quicktype-core/src/language/Crystal/utils.ts +++ b/packages/quicktype-core/src/language/Crystal/utils.ts @@ -61,9 +61,9 @@ export const camelNamingFunction = funPrefixNamer("camel", (original: string) => function standardUnicodeCrystalEscape(codePoint: number): string { if (codePoint <= 0xffff) { - return "\\u{" + intToHex(codePoint, 4) + "}"; + return `\\u{${intToHex(codePoint, 4)}}`; } else { - return "\\u{" + intToHex(codePoint, 6) + "}"; + return `\\u{${intToHex(codePoint, 6)}}`; } } diff --git a/packages/quicktype-core/src/language/Elm/ElmRenderer.ts b/packages/quicktype-core/src/language/Elm/ElmRenderer.ts index 6430743bd3..72acf1b41e 100644 --- a/packages/quicktype-core/src/language/Elm/ElmRenderer.ts +++ b/packages/quicktype-core/src/language/Elm/ElmRenderer.ts @@ -564,7 +564,7 @@ export class ElmRenderer extends ConvenienceRenderer { return " xdouble"; } if (t.isPrimitive()) { - return " " + t.kind; + return ` ${t.kind}`; } return t.kind; diff --git a/packages/quicktype-core/src/language/Golang/GolangRenderer.ts b/packages/quicktype-core/src/language/Golang/GolangRenderer.ts index 6f05aa081d..98ccbd7677 100644 --- a/packages/quicktype-core/src/language/Golang/GolangRenderer.ts +++ b/packages/quicktype-core/src/language/Golang/GolangRenderer.ts @@ -249,7 +249,7 @@ export class GoRenderer extends ConvenienceRenderer { const description = this.descriptionForClassProperty(c, jsonName); const docStrings = description !== undefined && description.length > 0 - ? description.map((d) => "// " + d) + ? description.map((d) => `// ${d}`) : []; const goType = this.propertyGoType(p); const omitEmpty = canOmitEmpty(p, this._options.omitEmpty) diff --git a/packages/quicktype-core/src/language/Kotlin/utils.ts b/packages/quicktype-core/src/language/Kotlin/utils.ts index 927d21de80..0b667cfbea 100644 --- a/packages/quicktype-core/src/language/Kotlin/utils.ts +++ b/packages/quicktype-core/src/language/Kotlin/utils.ts @@ -43,7 +43,7 @@ export function kotlinNameStyle( } function unicodeEscape(codePoint: number): string { - return "\\u" + intToHex(codePoint, 4); + return `\\u${intToHex(codePoint, 4)}`; } // eslint-disable-next-line @typescript-eslint/naming-convention diff --git a/packages/quicktype-core/src/language/Php/PhpRenderer.ts b/packages/quicktype-core/src/language/Php/PhpRenderer.ts index d6119fe408..d2e7ba2825 100644 --- a/packages/quicktype-core/src/language/Php/PhpRenderer.ts +++ b/packages/quicktype-core/src/language/Php/PhpRenderer.ts @@ -588,11 +588,11 @@ export class PhpRenderer extends ConvenienceRenderer { className, "::", args, - "::" + idx, + `::${idx}`, "'", suffix, "/*", - "" + idx, + `${idx}`, ":", args, "*/", @@ -603,7 +603,7 @@ export class PhpRenderer extends ConvenienceRenderer { "null", suffix, " /*", - "" + idx, + `${idx}`, ":", args, "*/", @@ -614,7 +614,7 @@ export class PhpRenderer extends ConvenienceRenderer { "true", suffix, " /*", - "" + idx, + `${idx}`, ":", args, "*/", @@ -622,10 +622,10 @@ export class PhpRenderer extends ConvenienceRenderer { (_integerType) => this.emitLine( ...lhs, - "" + idx, + `${idx}`, suffix, " /*", - "" + idx, + `${idx}`, ":", args, "*/", @@ -633,10 +633,10 @@ export class PhpRenderer extends ConvenienceRenderer { (_doubleType) => this.emitLine( ...lhs, - "" + (idx + idx / 1000), + `${idx + idx / 1000}`, suffix, " /*", - "" + idx, + `${idx}`, ":", args, "*/", @@ -648,11 +648,11 @@ export class PhpRenderer extends ConvenienceRenderer { className, "::", args, - "::" + idx, + `::${idx}`, "'", suffix, " /*", - "" + idx, + `${idx}`, ":", args, "*/", @@ -669,7 +669,7 @@ export class PhpRenderer extends ConvenienceRenderer { "", ); }); - this.emitLine("); /* ", "" + idx, ":", args, "*/"); + this.emitLine("); /* ", `${idx}`, ":", args, "*/"); }, (classType) => this.emitLine( @@ -678,7 +678,7 @@ export class PhpRenderer extends ConvenienceRenderer { "::sample()", suffix, " /*", - "" + idx, + `${idx}`, ":", args, "*/", @@ -721,7 +721,7 @@ export class PhpRenderer extends ConvenienceRenderer { }, (transformedStringType) => { if (transformedStringType.kind === "date-time") { - const x = _.pad("" + (1 + (idx % 31)), 2, "0"); + const x = _.pad(`${1 + (idx % 31)}`, 2, "0"); this.emitLine( ...lhs, "DateTime::createFromFormat(DateTimeInterface::ISO8601, '", diff --git a/packages/quicktype-core/src/language/Ruby/utils.ts b/packages/quicktype-core/src/language/Ruby/utils.ts index 0d032ec774..a9914312f6 100644 --- a/packages/quicktype-core/src/language/Ruby/utils.ts +++ b/packages/quicktype-core/src/language/Ruby/utils.ts @@ -26,7 +26,7 @@ export const forbiddenForObjectProperties = Array.from( new Set([...keywords.keywords, ...keywords.reservedProperties]), ); function unicodeEscape(codePoint: number): string { - return "\\u{" + intToHex(codePoint, 0) + "}"; + return `\\u{${intToHex(codePoint, 0)}}`; } export const stringEscape = utf32ConcatMap( @@ -47,7 +47,7 @@ const legalizeName = legalizeCharacters(isPartCharacter); export function simpleNameStyle(original: string, uppercase: boolean): string { if (/^[0-9]+$/.test(original)) { - original = original + "N"; + original = `${original}N`; } const words = splitIntoWords(original); diff --git a/packages/quicktype-core/src/language/Rust/utils.ts b/packages/quicktype-core/src/language/Rust/utils.ts index a321d09f5b..8ceaadec98 100644 --- a/packages/quicktype-core/src/language/Rust/utils.ts +++ b/packages/quicktype-core/src/language/Rust/utils.ts @@ -154,9 +154,9 @@ export const camelNamingFunction = funPrefixNamer("camel", (original: string) => const standardUnicodeRustEscape = (codePoint: number): string => { if (codePoint <= 0xffff) { - return "\\u{" + intToHex(codePoint, 4) + "}"; + return `\\u{${intToHex(codePoint, 4)}}`; } else { - return "\\u{" + intToHex(codePoint, 6) + "}"; + return `\\u{${intToHex(codePoint, 6)}}`; } }; diff --git a/packages/quicktype-core/src/language/Scala3/CirceRenderer.ts b/packages/quicktype-core/src/language/Scala3/CirceRenderer.ts index a3a55883cb..47370e664b 100644 --- a/packages/quicktype-core/src/language/Scala3/CirceRenderer.ts +++ b/packages/quicktype-core/src/language/Scala3/CirceRenderer.ts @@ -180,7 +180,7 @@ export class CirceRenderer extends Scala3Renderer { function sortBy(t: Type): string { const kind = t.kind; if (kind === "class") return kind; - return "_" + kind; + return `_${kind}`; } this.emitDescription(this.descriptionForType(u)); diff --git a/packages/quicktype-core/src/language/Scala3/Scala3Renderer.ts b/packages/quicktype-core/src/language/Scala3/Scala3Renderer.ts index 29826a8319..34234f728e 100644 --- a/packages/quicktype-core/src/language/Scala3/Scala3Renderer.ts +++ b/packages/quicktype-core/src/language/Scala3/Scala3Renderer.ts @@ -265,7 +265,7 @@ export class Scala3Renderer extends ConvenienceRenderer { const nameNeedsBackticks = jsonName.endsWith("_") || shouldAddBacktick(jsonName); const nameWithBackticks = nameNeedsBackticks - ? "`" + jsonName + "`" + ? `\`${jsonName}\`` : jsonName; this.emitLine( "val ", diff --git a/packages/quicktype-core/src/language/Scala3/utils.ts b/packages/quicktype-core/src/language/Scala3/utils.ts index b10fd47f2f..91e3fefa16 100644 --- a/packages/quicktype-core/src/language/Scala3/utils.ts +++ b/packages/quicktype-core/src/language/Scala3/utils.ts @@ -28,7 +28,7 @@ export const shouldAddBacktick = (paramName: string): boolean => { export const wrapOption = (s: string, optional: boolean): string => { if (optional) { - return "Option[" + s + "]"; + return `Option[${s}]`; } else { return s; } diff --git a/packages/quicktype-core/src/language/Smithy4s/Smithy4sRenderer.ts b/packages/quicktype-core/src/language/Smithy4s/Smithy4sRenderer.ts index cc6d2c7a7e..17bd7f18cc 100644 --- a/packages/quicktype-core/src/language/Smithy4s/Smithy4sRenderer.ts +++ b/packages/quicktype-core/src/language/Smithy4s/Smithy4sRenderer.ts @@ -128,7 +128,7 @@ export class Smithy4sRenderer extends ConvenienceRenderer { // because some renderers, such as kotlinx, can cope with `any`, while some get mad. protected arrayType(arrayType: ArrayType, _ = false): Sourcelike { // this.emitTopLevelArray(arrayType, new Name(arrayType.getCombinedName().toString() + "List")) - return arrayType.getCombinedName().toString() + "List"; + return `${arrayType.getCombinedName().toString()}List`; } protected emitArrayType(_: ArrayType, smithyType: Sourcelike): void { @@ -136,7 +136,7 @@ export class Smithy4sRenderer extends ConvenienceRenderer { } protected mapType(mapType: MapType, _ = false): Sourcelike { - return mapType.getCombinedName().toString() + "Map"; + return `${mapType.getCombinedName().toString()}Map`; // return [this.scalaType(mapType.values, withIssues), "Map"]; } @@ -278,7 +278,7 @@ export class Smithy4sRenderer extends ConvenienceRenderer { const nameNeedsBackticks = jsonName.endsWith("_") || shouldAddBacktick(jsonName); const nameWithBackticks = nameNeedsBackticks - ? "`" + jsonName + "`" + ? `\`${jsonName}\`` : jsonName; this.emitLine( p.isOptional ? "" : nullableOrOptional ? "" : "@required ", diff --git a/packages/quicktype-core/src/language/Swift/SwiftRenderer.ts b/packages/quicktype-core/src/language/Swift/SwiftRenderer.ts index 2ec21da902..ff9bc58013 100644 --- a/packages/quicktype-core/src/language/Swift/SwiftRenderer.ts +++ b/packages/quicktype-core/src/language/Swift/SwiftRenderer.ts @@ -440,7 +440,7 @@ export class SwiftRenderer extends ConvenienceRenderer { private get accessLevel(): string { return this._options.accessLevel === "internal" ? "" // internal is default, so we don't have to emit it - : this._options.accessLevel + " "; + : `${this._options.accessLevel} `; } private get objcMembersDeclaration(): string { diff --git a/packages/quicktype-core/src/language/Swift/utils.ts b/packages/quicktype-core/src/language/Swift/utils.ts index 22f9162380..5c068a5a05 100644 --- a/packages/quicktype-core/src/language/Swift/utils.ts +++ b/packages/quicktype-core/src/language/Swift/utils.ts @@ -78,7 +78,7 @@ export function swiftNameStyle( } function unicodeEscape(codePoint: number): string { - return "\\u{" + intToHex(codePoint, 0) + "}"; + return `\\u{${intToHex(codePoint, 0)}}`; } export const stringEscape = utf32ConcatMap( diff --git a/packages/quicktype-core/src/support/Strings.ts b/packages/quicktype-core/src/support/Strings.ts index 0cc3ff63a1..16e011da17 100644 --- a/packages/quicktype-core/src/support/Strings.ts +++ b/packages/quicktype-core/src/support/Strings.ts @@ -189,9 +189,9 @@ export function intToHex(i: number, width: number): string { export function standardUnicodeHexEscape(codePoint: number): string { if (codePoint <= 0xffff) { - return "\\u" + intToHex(codePoint, 4); + return `\\u${intToHex(codePoint, 4)}`; } else { - return "\\U" + intToHex(codePoint, 8); + return `\\U${intToHex(codePoint, 8)}`; } } @@ -343,7 +343,7 @@ export function startWithLetter( const modify = upper ? capitalize : decapitalize; if (str === "") return modify("empty"); if (isAllowedStart(str.charCodeAt(0))) return modify(str); - return modify("the" + str); + return modify(`the${str}`); } const knownAcronyms = new Set(acronyms); diff --git a/src/index.ts b/src/index.ts index 85c89f651e..b7ea74ff4e 100644 --- a/src/index.ts +++ b/src/index.ts @@ -395,7 +395,7 @@ function negatedInferenceFlagName(name: string): string { name = name.slice(prefix.length); } - return "no" + capitalize(name); + return `no${capitalize(name)}`; } function dashedFromCamelCase(name: string): string { @@ -470,7 +470,7 @@ function makeOptionDefinitions( return { name: dashedFromCamelCase(negatedInferenceFlagName(name)), optionType: "boolean" as const, - description: flag.negationDescription + ".", + description: `${flag.negationDescription}.`, kind: "cli" as const, }; }).values(), diff --git a/test/fixtures.ts b/test/fixtures.ts index bca6c4985d..07837a05de 100644 --- a/test/fixtures.ts +++ b/test/fixtures.ts @@ -103,7 +103,7 @@ function runEnvForLanguage( const newEnv = Object.assign({}, process.env); for (const option of Object.keys(additionalRendererOptions)) { - newEnv["QUICKTYPE_" + option.toUpperCase().replace("-", "_")] = ( + newEnv[`QUICKTYPE_${option.toUpperCase().replace("-", "_")}`] = ( additionalRendererOptions[ option as keyof typeof additionalRendererOptions ] as Option diff --git a/test/lib/deepEquals.ts b/test/lib/deepEquals.ts index c3b38b5df1..0db7e29633 100644 --- a/test/lib/deepEquals.ts +++ b/test/lib/deepEquals.ts @@ -3,7 +3,7 @@ import type { Moment } from "moment"; import type { ComparisonRelaxations } from "../utils"; function pathToString(path: string[]): string { - return "." + path.join("."); + return `.${path.join(".")}`; } declare namespace Math { From a96ac4cc04173a58ea61e719ef2664eea06a60e5 Mon Sep 17 00:00:00 2001 From: Mark Probst Date: Mon, 13 Jul 2026 10:05:33 -0400 Subject: [PATCH 22/68] Biome: enable useIsArray and fix violations One violation: "sl instanceof Array" replaced with Array.isArray(sl), which is also correct across realms. Co-Authored-By: Claude Fable 5 --- biome.json | 1 - packages/quicktype-core/src/Source.ts | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/biome.json b/biome.json index f0b0dd6e25..8aa57731d8 100644 --- a/biome.json +++ b/biome.json @@ -30,7 +30,6 @@ "noTemplateCurlyInString": "off", "noTsIgnore": "off", "noUselessEscapeInString": "off", - "useIsArray": "off", "useIterableCallbackReturn": "off" } } diff --git a/packages/quicktype-core/src/Source.ts b/packages/quicktype-core/src/Source.ts index 657844e168..b290ee4ce0 100644 --- a/packages/quicktype-core/src/Source.ts +++ b/packages/quicktype-core/src/Source.ts @@ -66,7 +66,7 @@ export type Sourcelike = Source | string | Name | SourcelikeArray; export type SourcelikeArray = Sourcelike[]; export function sourcelikeToSource(sl: Sourcelike): Source { - if (sl instanceof Array) { + if (Array.isArray(sl)) { return { kind: "sequence", sequence: sl.map(sourcelikeToSource), From f1ca8182c630cf4ed50a144570e371f710ff6d18 Mon Sep 17 00:00:00 2001 From: Mark Probst Date: Mon, 13 Jul 2026 10:06:48 -0400 Subject: [PATCH 23/68] Biome: enable noTsIgnore and fix violations One violation: a @ts-ignore on a type-only import of a build artifact in test/languages.ts, replaced with @ts-expect-error and an explanation. Co-Authored-By: Claude Fable 5 --- biome.json | 1 - test/languages.ts | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/biome.json b/biome.json index 8aa57731d8..2d96233b0b 100644 --- a/biome.json +++ b/biome.json @@ -28,7 +28,6 @@ "noPrototypeBuiltins": "off", "noShadowRestrictedNames": "off", "noTemplateCurlyInString": "off", - "noTsIgnore": "off", "noUselessEscapeInString": "off", "useIterableCallbackReturn": "off" } diff --git a/test/languages.ts b/test/languages.ts index e158b266f6..93ea6f0039 100644 --- a/test/languages.ts +++ b/test/languages.ts @@ -1,7 +1,7 @@ import type { LanguageName } from "quicktype-core"; import * as process from "node:process"; -// @ts-ignore +// @ts-expect-error: ../dist only exists after the root package is built import type { RendererOptions } from "../dist/quicktype-core/Run"; const easySampleJSONs = [ From c369eeb9898b8fb7f138e612c4034fb08b4fb205 Mon Sep 17 00:00:00 2001 From: Mark Probst Date: Mon, 13 Jul 2026 10:07:50 -0400 Subject: [PATCH 24/68] Biome: enable noImplicitAnyLet and fix violations Three violations: added explicit type annotations to "let" bindings in the vendored get-stream helper and the Chance Mersenne Twister port. Co-Authored-By: Claude Fable 5 --- biome.json | 1 - packages/quicktype-core/src/input/io/get-stream/index.ts | 2 +- packages/quicktype-core/src/support/Chance.ts | 4 ++-- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/biome.json b/biome.json index 2d96233b0b..0d7b377bb2 100644 --- a/biome.json +++ b/biome.json @@ -24,7 +24,6 @@ "suspicious": { "noExplicitAny": "off", "noGlobalIsNan": "off", - "noImplicitAnyLet": "off", "noPrototypeBuiltins": "off", "noShadowRestrictedNames": "off", "noTemplateCurlyInString": "off", diff --git a/packages/quicktype-core/src/input/io/get-stream/index.ts b/packages/quicktype-core/src/input/io/get-stream/index.ts index 24d4fda8bc..ee27faa26f 100644 --- a/packages/quicktype-core/src/input/io/get-stream/index.ts +++ b/packages/quicktype-core/src/input/io/get-stream/index.ts @@ -18,7 +18,7 @@ export async function getStream(inputStream: Readable, opts: Options = {}) { const maxBuffer = opts.maxBuffer ?? Number.POSITIVE_INFINITY; let stream: BufferedPassThrough; - let clean; + let clean: (() => void) | undefined; const p = new Promise((resolve, reject) => { const error = (err: any) => { diff --git a/packages/quicktype-core/src/support/Chance.ts b/packages/quicktype-core/src/support/Chance.ts index eee1e7e58e..6b289ef59a 100644 --- a/packages/quicktype-core/src/support/Chance.ts +++ b/packages/quicktype-core/src/support/Chance.ts @@ -88,13 +88,13 @@ class MersenneTwister { /* generates a random number on [0,0xffffffff]-interval */ private genrand_int32() { - let y; + let y: number; const mag01 = [0x0, this.MATRIX_A]; /* mag01[x] = x * MATRIX_A for x=0,1 */ if (this.mti >= this.N) { /* generate N words at one time */ - let kk; + let kk: number; if (this.mti === this.N + 1) { /* if init_genrand() has not been called, */ From 3600d2275b1311fed644c710896811bfe6e11715 Mon Sep 17 00:00:00 2001 From: Mark Probst Date: Mon, 13 Jul 2026 10:10:20 -0400 Subject: [PATCH 25/68] Biome: enable noPrototypeBuiltins and fix violations Two violations, both already using the safe Object.prototype.hasOwnProperty.call pattern. The suggested Object.hasOwn is not available under quicktype-core's es6 lib (and would raise the package's runtime floor), so both sites carry a targeted suppression instead. Co-Authored-By: Claude Fable 5 --- biome.json | 1 - packages/quicktype-core/src/input/CompressedJSON.ts | 1 + packages/quicktype-core/src/input/Inference.ts | 1 + 3 files changed, 2 insertions(+), 1 deletion(-) diff --git a/biome.json b/biome.json index 0d7b377bb2..b2afdba75c 100644 --- a/biome.json +++ b/biome.json @@ -24,7 +24,6 @@ "suspicious": { "noExplicitAny": "off", "noGlobalIsNan": "off", - "noPrototypeBuiltins": "off", "noShadowRestrictedNames": "off", "noTemplateCurlyInString": "off", "noUselessEscapeInString": "off", diff --git a/packages/quicktype-core/src/input/CompressedJSON.ts b/packages/quicktype-core/src/input/CompressedJSON.ts index 56272edbe9..2afe56c832 100644 --- a/packages/quicktype-core/src/input/CompressedJSON.ts +++ b/packages/quicktype-core/src/input/CompressedJSON.ts @@ -105,6 +105,7 @@ export abstract class CompressedJSON { } protected internString(s: string): number { + // biome-ignore lint/suspicious/noPrototypeBuiltins: Object.hasOwn is not in quicktype-core's es6 lib if (Object.prototype.hasOwnProperty.call(this._stringIndexes, s)) { return this._stringIndexes[s]; } diff --git a/packages/quicktype-core/src/input/Inference.ts b/packages/quicktype-core/src/input/Inference.ts index b10a13f9de..85b9ebb180 100644 --- a/packages/quicktype-core/src/input/Inference.ts +++ b/packages/quicktype-core/src/input/Inference.ts @@ -363,6 +363,7 @@ export class TypeInference { const key = this._cjson.getStringForValue(arr[i]); const value = arr[i + 1]; if ( + // biome-ignore lint/suspicious/noPrototypeBuiltins: Object.hasOwn is not in quicktype-core's es6 lib !Object.prototype.hasOwnProperty.call(propertyValues, key) ) { propertyNames.push(key); From 24b743d1625c8a901a5dfdf27398d5f0fcb5098e Mon Sep 17 00:00:00 2001 From: Mark Probst Date: Mon, 13 Jul 2026 10:11:23 -0400 Subject: [PATCH 26/68] Biome: enable noShadowRestrictedNames and fix violations Two violations: a constructor parameter named toString in the C++ utils (renamed to toStringCode), and a hasOwnProperty import from collection-utils in TransformedStringType.ts, which now carries the same biome-ignore suppression used at the other import sites of that name (replacing a stale eslint-disable). Co-Authored-By: Claude Fable 5 --- biome.json | 1 - packages/quicktype-core/src/Type/TransformedStringType.ts | 2 +- packages/quicktype-core/src/language/CPlusPlus/utils.ts | 4 ++-- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/biome.json b/biome.json index b2afdba75c..cec11cae16 100644 --- a/biome.json +++ b/biome.json @@ -24,7 +24,6 @@ "suspicious": { "noExplicitAny": "off", "noGlobalIsNan": "off", - "noShadowRestrictedNames": "off", "noTemplateCurlyInString": "off", "noUselessEscapeInString": "off", "useIterableCallbackReturn": "off" diff --git a/packages/quicktype-core/src/Type/TransformedStringType.ts b/packages/quicktype-core/src/Type/TransformedStringType.ts index 93e6e5a190..cd0f9fc698 100644 --- a/packages/quicktype-core/src/Type/TransformedStringType.ts +++ b/packages/quicktype-core/src/Type/TransformedStringType.ts @@ -1,5 +1,5 @@ import { - // eslint-disable-next-line @typescript-eslint/no-redeclare + // biome-ignore lint/suspicious/noShadowRestrictedNames: collection-utils exports this name hasOwnProperty, mapFromObject, } from "collection-utils"; diff --git a/packages/quicktype-core/src/language/CPlusPlus/utils.ts b/packages/quicktype-core/src/language/CPlusPlus/utils.ts index bf73e9bdc5..897fdb8ad8 100644 --- a/packages/quicktype-core/src/language/CPlusPlus/utils.ts +++ b/packages/quicktype-core/src/language/CPlusPlus/utils.ts @@ -182,7 +182,7 @@ export class BaseString { smatch: string, regex: string, stringLiteralPrefix: string, - toString: WrappingCode, + toStringCode: WrappingCode, encodingClass: string, encodingFunction: string, ) { @@ -191,7 +191,7 @@ export class BaseString { this._smatch = smatch; this._regex = regex; this._stringLiteralPrefix = stringLiteralPrefix; - this._toString = toString; + this._toString = toStringCode; this._encodingClass = encodingClass; this._encodingFunction = encodingFunction; } From 49006580e2aaa4ec0a878befccb9ad8a6006d0a4 Mon Sep 17 00:00:00 2001 From: Mark Probst Date: Mon, 13 Jul 2026 10:12:26 -0400 Subject: [PATCH 27/68] Biome: enable noGlobalIsNan and fix violations Six violations converted to Number.isNaN. Every call site passes a value that is already a number (parseInt/parseFloat results, or values behind a typeof === "number" guard), so dropping the global isNaN coercion does not change behavior. Co-Authored-By: Claude Fable 5 --- biome.json | 1 - packages/quicktype-core/src/language/Scala3/utils.ts | 4 ++-- packages/quicktype-core/src/language/Smithy4s/utils.ts | 4 ++-- test/lib/deepEquals.ts | 2 +- 4 files changed, 5 insertions(+), 6 deletions(-) diff --git a/biome.json b/biome.json index cec11cae16..c324df992c 100644 --- a/biome.json +++ b/biome.json @@ -23,7 +23,6 @@ "preset": "recommended", "suspicious": { "noExplicitAny": "off", - "noGlobalIsNan": "off", "noTemplateCurlyInString": "off", "noUselessEscapeInString": "off", "useIterableCallbackReturn": "off" diff --git a/packages/quicktype-core/src/language/Scala3/utils.ts b/packages/quicktype-core/src/language/Scala3/utils.ts index 91e3fefa16..3c7258dc44 100644 --- a/packages/quicktype-core/src/language/Scala3/utils.ts +++ b/packages/quicktype-core/src/language/Scala3/utils.ts @@ -21,8 +21,8 @@ export const shouldAddBacktick = (paramName: string): boolean => { return ( keywords.some((s) => paramName === s) || invalidSymbols.some((s) => paramName.includes(s)) || - !isNaN(+Number.parseFloat(paramName)) || - !isNaN(Number.parseInt(paramName.charAt(0), 10)) + !Number.isNaN(+Number.parseFloat(paramName)) || + !Number.isNaN(Number.parseInt(paramName.charAt(0), 10)) ); }; diff --git a/packages/quicktype-core/src/language/Smithy4s/utils.ts b/packages/quicktype-core/src/language/Smithy4s/utils.ts index f05b63c940..7038e28021 100644 --- a/packages/quicktype-core/src/language/Smithy4s/utils.ts +++ b/packages/quicktype-core/src/language/Smithy4s/utils.ts @@ -22,8 +22,8 @@ export const shouldAddBacktick = (paramName: string): boolean => { return ( keywords.some((s) => paramName === s) || invalidSymbols.some((s) => paramName.includes(s)) || - !isNaN(Number.parseFloat(paramName)) || - !isNaN(Number.parseInt(paramName.charAt(0), 10)) + !Number.isNaN(Number.parseFloat(paramName)) || + !Number.isNaN(Number.parseInt(paramName.charAt(0), 10)) ); }; diff --git a/test/lib/deepEquals.ts b/test/lib/deepEquals.ts index 0db7e29633..9019010418 100644 --- a/test/lib/deepEquals.ts +++ b/test/lib/deepEquals.ts @@ -42,7 +42,7 @@ export default function deepEquals( // remember that NaN === NaN returns false // and isNaN(undefined) returns true if (typeof x === "number" && typeof y === "number") { - if (isNaN(x) && isNaN(y)) { + if (Number.isNaN(x) && Number.isNaN(y)) { return true; } // because sometimes Newtonsoft.JSON is not exact From 83184610eb9382529363e634f4fb9ece5829324f Mon Sep 17 00:00:00 2001 From: Mark Probst Date: Mon, 13 Jul 2026 10:13:21 -0400 Subject: [PATCH 28/68] Biome: enable noUselessEscapeInString and fix violations Seven violations in test/languages.ts: escaped double quotes inside template literals, where the backslash is a no-op. The resulting strings are byte-for-byte identical. Co-Authored-By: Claude Fable 5 --- biome.json | 1 - test/languages.ts | 14 +++++++------- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/biome.json b/biome.json index c324df992c..75a075fe6d 100644 --- a/biome.json +++ b/biome.json @@ -24,7 +24,6 @@ "suspicious": { "noExplicitAny": "off", "noTemplateCurlyInString": "off", - "noUselessEscapeInString": "off", "useIterableCallbackReturn": "off" } } diff --git a/test/languages.ts b/test/languages.ts index 93ea6f0039..e346160ac6 100644 --- a/test/languages.ts +++ b/test/languages.ts @@ -821,7 +821,7 @@ export const TypeScriptLanguage: Language = { // in the generated code compileCommand: "tsc -p .", runCommand(sample: string) { - return `tsx main.ts \"${sample}\"`; + return `tsx main.ts "${sample}"`; }, diffViaSchema: true, skipDiffViaSchema: [ @@ -865,7 +865,7 @@ export const JavaScriptLanguage: Language = { name: "javascript", base: "test/fixtures/javascript", runCommand(sample: string) { - return `node main.js \"${sample}\"`; + return `node main.js "${sample}"`; }, // FIXME: enable once TypeScript supports unions diffViaSchema: false, @@ -891,7 +891,7 @@ export const JavaScriptPropTypesLanguage: Language = { base: "test/fixtures/javascript-prop-types", setupCommand: "npm install", runCommand(sample: string) { - return `node main.js \"${sample}\"`; + return `node main.js "${sample}"`; }, copyInput: true, diffViaSchema: false, @@ -922,7 +922,7 @@ export const FlowLanguage: Language = { name: "flow", base: "test/fixtures/flow", runCommand(sample: string) { - return `flow check 1>&2 && flow-node main.js \"${sample}\"`; + return `flow check 1>&2 && flow-node main.js "${sample}"`; }, diffViaSchema: false, skipDiffViaSchema: [], @@ -1272,7 +1272,7 @@ export const DartLanguage: Language = { name: "dart", base: "test/fixtures/dart", runCommand(sample: string) { - return `dart --enable-experiment=non-nullable parser.dart \"${sample}\"`; + return `dart --enable-experiment=non-nullable parser.dart "${sample}"`; }, diffViaSchema: false, skipDiffViaSchema: [], @@ -1330,7 +1330,7 @@ export const PikeLanguage: Language = { name: "pike", base: "test/fixtures/pike", runCommand(sample: string) { - return `pike main.pike \"${sample}\"`; + return `pike main.pike "${sample}"`; }, diffViaSchema: false, skipDiffViaSchema: [], @@ -1469,7 +1469,7 @@ export const HaskellLanguage: Language = { export const PHPLanguage: Language = { name: "php", base: "test/fixtures/php", - runCommand: (sample) => `php main.php \"${sample}\"`, + runCommand: (sample) => `php main.php "${sample}"`, diffViaSchema: false, skipDiffViaSchema: [], allowMissingNull: true, From e1cbfcd297c03ff5cffa52958a68cf1ae249ad26 Mon Sep 17 00:00:00 2001 From: Mark Probst Date: Mon, 13 Jul 2026 10:15:35 -0400 Subject: [PATCH 29/68] Biome: enable useIterableCallbackReturn and fix violations Nineteen violations: forEach callbacks written as expression-bodied arrows that implicitly returned a value. Converted each to a statement body; no return values were ever consumed. Co-Authored-By: Claude Fable 5 --- biome.json | 3 +-- .../quicktype-core/src/Type/TypeBuilder.ts | 8 +++++-- .../src/input/JSONSchemaInput.ts | 6 ++--- .../src/language/Golang/GolangRenderer.ts | 4 +++- .../src/language/Java/JavaJacksonRenderer.ts | 12 +++++++--- .../src/language/Java/JavaRenderer.ts | 24 +++++++++++++------ .../JavaScriptPropTypesRenderer.ts | 4 +++- .../quicktype-core/src/language/Rust/utils.ts | 4 +++- .../TypeScriptEffectSchemaRenderer.ts | 12 +++++----- .../TypeScriptZod/TypeScriptZodRenderer.ts | 18 +++++++------- test/lib/multicore.ts | 6 ++--- 11 files changed, 63 insertions(+), 38 deletions(-) diff --git a/biome.json b/biome.json index 75a075fe6d..0cf4c88d0f 100644 --- a/biome.json +++ b/biome.json @@ -23,8 +23,7 @@ "preset": "recommended", "suspicious": { "noExplicitAny": "off", - "noTemplateCurlyInString": "off", - "useIterableCallbackReturn": "off" + "noTemplateCurlyInString": "off" } } }, diff --git a/packages/quicktype-core/src/Type/TypeBuilder.ts b/packages/quicktype-core/src/Type/TypeBuilder.ts index 051e0dfae5..88dcb97f37 100644 --- a/packages/quicktype-core/src/Type/TypeBuilder.ts +++ b/packages/quicktype-core/src/Type/TypeBuilder.ts @@ -129,7 +129,9 @@ export class TypeBuilder { trefs: ReadonlySet | undefined, ): void { if (trefs === undefined) return; - trefs.forEach((tref) => this.assertTypeRefGraph(tref)); + trefs.forEach((tref) => { + this.assertTypeRefGraph(tref); + }); } private filterTypeAttributes( @@ -515,7 +517,9 @@ export class TypeBuilder { public modifyPropertiesIfNecessary( properties: ReadonlyMap, ): ReadonlyMap { - properties.forEach((p) => this.assertTypeRefGraph(p.typeRef)); + properties.forEach((p) => { + this.assertTypeRefGraph(p.typeRef); + }); if (this.canonicalOrder) { properties = mapSortByKey(properties); diff --git a/packages/quicktype-core/src/input/JSONSchemaInput.ts b/packages/quicktype-core/src/input/JSONSchemaInput.ts index e29b29b658..b9d796d21f 100644 --- a/packages/quicktype-core/src/input/JSONSchemaInput.ts +++ b/packages/quicktype-core/src/input/JSONSchemaInput.ts @@ -166,9 +166,9 @@ export class Ref { if (path !== "") { const parts = path.split("/"); - parts.forEach((part) => - elements.push({ kind: PathElementKind.KeyOrIndex, key: part }), - ); + parts.forEach((part) => { + elements.push({ kind: PathElementKind.KeyOrIndex, key: part }); + }); } return elements; diff --git a/packages/quicktype-core/src/language/Golang/GolangRenderer.ts b/packages/quicktype-core/src/language/Golang/GolangRenderer.ts index 98ccbd7677..72d50068e8 100644 --- a/packages/quicktype-core/src/language/Golang/GolangRenderer.ts +++ b/packages/quicktype-core/src/language/Golang/GolangRenderer.ts @@ -256,7 +256,9 @@ export class GoRenderer extends ConvenienceRenderer { ? ",omitempty" : []; - docStrings.forEach((doc) => columns.push([doc])); + docStrings.forEach((doc) => { + columns.push([doc]); + }); const tags = this._options.fieldTags .split(",") .map((tag) => `${tag}:"${stringEscape(jsonName)}${omitEmpty}"`) diff --git a/packages/quicktype-core/src/language/Java/JavaJacksonRenderer.ts b/packages/quicktype-core/src/language/Java/JavaJacksonRenderer.ts index 934b1afa2b..673e44ad1f 100644 --- a/packages/quicktype-core/src/language/Java/JavaJacksonRenderer.ts +++ b/packages/quicktype-core/src/language/Java/JavaJacksonRenderer.ts @@ -61,17 +61,23 @@ export class JacksonRenderer extends JavaRenderer { switch (p.type.kind) { case "date-time": this._dateTimeProvider.dateTimeJacksonAnnotations.forEach( - (annotation) => annotations.push(annotation), + (annotation) => { + annotations.push(annotation); + }, ); break; case "date": this._dateTimeProvider.dateJacksonAnnotations.forEach( - (annotation) => annotations.push(annotation), + (annotation) => { + annotations.push(annotation); + }, ); break; case "time": this._dateTimeProvider.timeJacksonAnnotations.forEach( - (annotation) => annotations.push(annotation), + (annotation) => { + annotations.push(annotation); + }, ); break; default: diff --git a/packages/quicktype-core/src/language/Java/JavaRenderer.ts b/packages/quicktype-core/src/language/Java/JavaRenderer.ts index 90cab266af..d596083389 100644 --- a/packages/quicktype-core/src/language/Java/JavaRenderer.ts +++ b/packages/quicktype-core/src/language/Java/JavaRenderer.ts @@ -390,9 +390,11 @@ export class JavaRenderer extends ConvenienceRenderer { (_enumType) => [], (unionType) => { const imports: string[] = []; - unionType.members.forEach((type) => - this.javaImport(type).forEach((imp) => imports.push(imp)), - ); + unionType.members.forEach((type) => { + this.javaImport(type).forEach((imp) => { + imports.push(imp); + }); + }); return imports; }, (transformedStringType) => { @@ -474,7 +476,9 @@ export class JavaRenderer extends ConvenienceRenderer { protected importsForClass(c: ClassType): string[] { const imports: string[] = []; this.forEachClassProperty(c, "none", (_name, _jsonName, p) => { - this.javaImport(p.type).forEach((imp) => imports.push(imp)); + this.javaImport(p.type).forEach((imp) => { + imports.push(imp); + }); }); imports.sort(); return [...new Set(imports)]; @@ -484,7 +488,9 @@ export class JavaRenderer extends ConvenienceRenderer { const imports: string[] = []; const [, nonNulls] = removeNullFromUnion(u); this.forEachUnionMember(u, nonNulls, "none", null, (_fieldName, t) => { - this.javaImport(t).forEach((imp) => imports.push(imp)); + this.javaImport(t).forEach((imp) => { + imports.push(imp); + }); }); imports.sort(); return [...new Set(imports)]; @@ -558,7 +564,9 @@ export class JavaRenderer extends ConvenienceRenderer { jsonName, p, false, - ).forEach((annotation) => this.emitLine(annotation)); + ).forEach((annotation) => { + this.emitLine(annotation); + }); this.emitLine( "public ", rendered, @@ -575,7 +583,9 @@ export class JavaRenderer extends ConvenienceRenderer { jsonName, p, true, - ).forEach((annotation) => this.emitLine(annotation)); + ).forEach((annotation) => { + this.emitLine(annotation); + }); this.emitLine( "public void ", setterName, diff --git a/packages/quicktype-core/src/language/JavaScriptPropTypes/JavaScriptPropTypesRenderer.ts b/packages/quicktype-core/src/language/JavaScriptPropTypes/JavaScriptPropTypesRenderer.ts index 046a19744f..1ddec6e6a9 100644 --- a/packages/quicktype-core/src/language/JavaScriptPropTypes/JavaScriptPropTypesRenderer.ts +++ b/packages/quicktype-core/src/language/JavaScriptPropTypes/JavaScriptPropTypesRenderer.ts @@ -265,7 +265,9 @@ export class JavaScriptPropTypesRenderer extends ConvenienceRenderer { }); // now emit ordered source - order.forEach((i) => this.emitGatheredSource(mapValue[i])); + order.forEach((i) => { + this.emitGatheredSource(mapValue[i]); + }); // now emit top levels this.forEachTopLevel("none", (type, name) => { diff --git a/packages/quicktype-core/src/language/Rust/utils.ts b/packages/quicktype-core/src/language/Rust/utils.ts index 8ceaadec98..92cb7d3a96 100644 --- a/packages/quicktype-core/src/language/Rust/utils.ts +++ b/packages/quicktype-core/src/language/Rust/utils.ts @@ -171,7 +171,9 @@ export function getPreferredNamingStyle( const occurrences = Object.fromEntries( Object.keys(namingStyles).map((key) => [key, 0]), ); - namingStyleOccurences.forEach((style) => ++occurrences[style]); + namingStyleOccurences.forEach((style) => { + ++occurrences[style]; + }); const max = Math.max(...Object.values(occurrences)); const preferedStyles = Object.entries(occurrences).flatMap( ([style, num]) => (num === max ? [style] : []), diff --git a/packages/quicktype-core/src/language/TypeScriptEffectSchema/TypeScriptEffectSchemaRenderer.ts b/packages/quicktype-core/src/language/TypeScriptEffectSchema/TypeScriptEffectSchemaRenderer.ts index 56d3747536..7590bb37f4 100644 --- a/packages/quicktype-core/src/language/TypeScriptEffectSchema/TypeScriptEffectSchemaRenderer.ts +++ b/packages/quicktype-core/src/language/TypeScriptEffectSchema/TypeScriptEffectSchemaRenderer.ts @@ -286,13 +286,13 @@ export class TypeScriptEffectSchemaRenderer extends ConvenienceRenderer { }); // now emit ordered source - order.forEach((i) => + order.forEach((i) => { this.emitGatheredSource( - this.gatherSource(() => - this.emitObject(mapKey[i], mapValue[i]), - ), - ), - ); + this.gatherSource(() => { + this.emitObject(mapKey[i], mapValue[i]); + }), + ); + }); } protected emitSourceStructure(): void { diff --git a/packages/quicktype-core/src/language/TypeScriptZod/TypeScriptZodRenderer.ts b/packages/quicktype-core/src/language/TypeScriptZod/TypeScriptZodRenderer.ts index 3af7bc0e31..3d5b179840 100644 --- a/packages/quicktype-core/src/language/TypeScriptZod/TypeScriptZodRenderer.ts +++ b/packages/quicktype-core/src/language/TypeScriptZod/TypeScriptZodRenderer.ts @@ -413,9 +413,9 @@ export class TypeScriptZodRenderer extends ConvenienceRenderer { // which we can get back to the same type by following child type // references. Those can never be topologically ordered. const indexForTypeRef = new Map(); - mapTypeRef.forEach((typeRef, index) => - indexForTypeRef.set(typeRef, index), - ); + mapTypeRef.forEach((typeRef, index) => { + indexForTypeRef.set(typeRef, index); + }); this._recursiveTypeRefs = new Set(); mapType.forEach((_, startIndex) => { const visited = new Set(); @@ -510,13 +510,13 @@ export class TypeScriptZodRenderer extends ConvenienceRenderer { } while (indices.length > 0 && passNum <= MAX_PASSES); // now emit ordered source - order.forEach((i) => + order.forEach((i) => { this.emitGatheredSource( - this.gatherSource(() => - this.emitObject(mapName[i], mapType[i]), - ), - ), - ); + this.gatherSource(() => { + this.emitObject(mapName[i], mapType[i]); + }), + ); + }); } protected emitSourceStructure(): void { diff --git a/test/lib/multicore.ts b/test/lib/multicore.ts index 358c725284..4b304503da 100644 --- a/test/lib/multicore.ts +++ b/test/lib/multicore.ts @@ -61,11 +61,11 @@ export async function inParallel( await map(item, i); } } else { - _.range(workers).forEach((i) => + _.range(workers).forEach((i) => { cluster.fork({ worker: i, - }), - ); + }); + }); } } else { // Setup a worker From 0a63a2f10e2cafc64c5236704d9c28e1e79c51de Mon Sep 17 00:00:00 2001 From: Mark Probst Date: Mon, 13 Jul 2026 10:19:02 -0400 Subject: [PATCH 30/68] Biome: enable noExplicitAny and fix violations 25 violations. The six "any" members of the ErrorProperties union in Messages.ts became "unknown" (the values are only formatted into messages). The rest are deliberate anys -- heterogeneous attribute maps, arbitrary JSON containers, vendored get-stream code, untyped web-tree-sitter modules -- and now carry biome-ignore suppressions with reasons, replacing the stale eslint-disable comments where those existed. This also puts the two pre-existing noExplicitAny suppressions back into effect. Co-Authored-By: Claude Fable 5 --- biome.json | 1 - packages/quicktype-core/src/Messages.ts | 12 ++++++------ .../quicktype-core/src/attributes/TypeAttributes.ts | 4 ++-- packages/quicktype-core/src/input/Inference.ts | 2 +- .../src/input/io/get-stream/buffer-stream.ts | 3 +++ .../quicktype-core/src/input/io/get-stream/index.ts | 1 + .../src/language/JSONSchema/JSONSchemaRenderer.ts | 2 +- packages/quicktype-core/src/support/Support.ts | 1 + packages/quicktype-graphql-input/src/index.ts | 4 ++-- test/fixtures.ts | 3 +++ test/lib/deepEquals.ts | 2 ++ 11 files changed, 22 insertions(+), 13 deletions(-) diff --git a/biome.json b/biome.json index 0cf4c88d0f..7689fb7032 100644 --- a/biome.json +++ b/biome.json @@ -22,7 +22,6 @@ "rules": { "preset": "recommended", "suspicious": { - "noExplicitAny": "off", "noTemplateCurlyInString": "off" } } diff --git a/packages/quicktype-core/src/Messages.ts b/packages/quicktype-core/src/Messages.ts index 30032e4e7e..990e228c23 100644 --- a/packages/quicktype-core/src/Messages.ts +++ b/packages/quicktype-core/src/Messages.ts @@ -58,23 +58,23 @@ export type ErrorProperties = } | { kind: "SchemaRequiredMustBeStringOrStringArray"; - properties: { actual: any; ref: Ref }; + properties: { actual: unknown; ref: Ref }; } | { kind: "SchemaRequiredElementMustBeString"; - properties: { element: any; ref: Ref }; + properties: { element: unknown; ref: Ref }; } | { kind: "SchemaTypeMustBeStringOrStringArray"; - properties: { actual: any }; + properties: { actual: unknown }; } | { kind: "SchemaTypeElementMustBeString"; - properties: { element: any; ref: Ref }; + properties: { element: unknown; ref: Ref }; } | { kind: "SchemaArrayItemsMustBeStringOrArray"; - properties: { actual: any; ref: Ref }; + properties: { actual: unknown; ref: Ref }; } | { kind: "SchemaIDMustHaveAddress"; properties: { id: string; ref: Ref } } | { @@ -83,7 +83,7 @@ export type ErrorProperties = } | { kind: "SchemaSetOperationCasesIsNotArray"; - properties: { cases: any; operation: string; ref: Ref }; + properties: { cases: unknown; operation: string; ref: Ref }; } | { kind: "SchemaMoreThanOneUnionMemberName"; diff --git a/packages/quicktype-core/src/attributes/TypeAttributes.ts b/packages/quicktype-core/src/attributes/TypeAttributes.ts index ef653e9724..2f3e72e340 100644 --- a/packages/quicktype-core/src/attributes/TypeAttributes.ts +++ b/packages/quicktype-core/src/attributes/TypeAttributes.ts @@ -118,7 +118,7 @@ export class TypeAttributeKind { } // FIXME: strongly type this -// eslint-disable-next-line @typescript-eslint/no-explicit-any +// biome-ignore lint/suspicious/noExplicitAny: heterogeneous by design; attribute values are typed by their kind export type TypeAttributes = ReadonlyMap, any>; export const emptyTypeAttributes: TypeAttributes = new Map(); @@ -154,7 +154,7 @@ export function combineTypeAttributes( const attributesByKind = mapTranspose(attributeArray); // FIXME: strongly type this - // eslint-disable-next-line @typescript-eslint/no-explicit-any + // biome-ignore lint/suspicious/noExplicitAny: heterogeneous by design; attribute values are typed by their kind function combine(attrs: any[], kind: TypeAttributeKind): any { assert(attrs.length > 0, "Cannot combine zero type attributes"); if (attrs.length === 1) return attrs[0]; diff --git a/packages/quicktype-core/src/input/Inference.ts b/packages/quicktype-core/src/input/Inference.ts index 85b9ebb180..4efca3c4f2 100644 --- a/packages/quicktype-core/src/input/Inference.ts +++ b/packages/quicktype-core/src/input/Inference.ts @@ -32,7 +32,7 @@ import { // Value[] | NestedValueArray[] // but TypeScript doesn't support that. // FIXME: reactor this -// eslint-disable-next-line @typescript-eslint/no-explicit-any +// biome-ignore lint/suspicious/noExplicitAny: TypeScript cannot express this recursive type export type NestedValueArray = any; function forEachArrayInNestedValueArray( diff --git a/packages/quicktype-core/src/input/io/get-stream/buffer-stream.ts b/packages/quicktype-core/src/input/io/get-stream/buffer-stream.ts index eab9283ee1..4c15e25f73 100644 --- a/packages/quicktype-core/src/input/io/get-stream/buffer-stream.ts +++ b/packages/quicktype-core/src/input/io/get-stream/buffer-stream.ts @@ -4,6 +4,7 @@ import { PassThrough } from "readable-stream"; import type { Options } from "./index.js"; export interface BufferedPassThrough extends PassThrough { + // biome-ignore lint/suspicious/noExplicitAny: vendored from sindresorhus/get-stream getBufferedValue: () => any; getBufferedLength: () => number; @@ -30,6 +31,7 @@ export default function bufferStream(opts: Options) { } let len = 0; + // biome-ignore lint/suspicious/noExplicitAny: vendored from sindresorhus/get-stream const ret: any[] = []; const stream = new PassThrough({ objectMode, @@ -39,6 +41,7 @@ export default function bufferStream(opts: Options) { stream.setEncoding(encoding as BufferEncoding); } + // biome-ignore lint/suspicious/noExplicitAny: vendored from sindresorhus/get-stream stream.on("data", (chunk: any) => { ret.push(chunk); diff --git a/packages/quicktype-core/src/input/io/get-stream/index.ts b/packages/quicktype-core/src/input/io/get-stream/index.ts index ee27faa26f..c7bc8afe85 100644 --- a/packages/quicktype-core/src/input/io/get-stream/index.ts +++ b/packages/quicktype-core/src/input/io/get-stream/index.ts @@ -21,6 +21,7 @@ export async function getStream(inputStream: Readable, opts: Options = {}) { let clean: (() => void) | undefined; const p = new Promise((resolve, reject) => { + // biome-ignore lint/suspicious/noExplicitAny: vendored from sindresorhus/get-stream const error = (err: any) => { if (err) { // null check diff --git a/packages/quicktype-core/src/language/JSONSchema/JSONSchemaRenderer.ts b/packages/quicktype-core/src/language/JSONSchema/JSONSchemaRenderer.ts index e7ed8f10dc..4bc06e0784 100644 --- a/packages/quicktype-core/src/language/JSONSchema/JSONSchemaRenderer.ts +++ b/packages/quicktype-core/src/language/JSONSchema/JSONSchemaRenderer.ts @@ -16,7 +16,7 @@ import { matchTypeExhaustive } from "../../Type/TypeUtils.js"; import { namingFunction } from "./utils.js"; interface Schema { - // eslint-disable-next-line @typescript-eslint/no-explicit-any + // biome-ignore lint/suspicious/noExplicitAny: JSON Schema values are arbitrary JSON [name: string]: any; } diff --git a/packages/quicktype-core/src/support/Support.ts b/packages/quicktype-core/src/support/Support.ts index 9968e160f9..30fa6d6c9a 100644 --- a/packages/quicktype-core/src/support/Support.ts +++ b/packages/quicktype-core/src/support/Support.ts @@ -6,6 +6,7 @@ import type { JSONSchema } from "../input/JSONSchemaStore.js"; import { messageError } from "../Messages.js"; export interface StringMap { + // biome-ignore lint/suspicious/noExplicitAny: heterogeneous by design; holds arbitrary JSON values [name: string]: any; } diff --git a/packages/quicktype-graphql-input/src/index.ts b/packages/quicktype-graphql-input/src/index.ts index c929c668af..818ec73f93 100644 --- a/packages/quicktype-graphql-input/src/index.ts +++ b/packages/quicktype-graphql-input/src/index.ts @@ -648,13 +648,13 @@ function makeGraphQLQueryTypes( export interface GraphQLSourceData { name: string; query: string; - // eslint-disable-next-line @typescript-eslint/no-explicit-any + // biome-ignore lint/suspicious/noExplicitAny: raw GraphQL introspection JSON schema: any; } interface GraphQLTopLevel { query: string; - // eslint-disable-next-line @typescript-eslint/no-explicit-any + // biome-ignore lint/suspicious/noExplicitAny: raw GraphQL introspection JSON schema: any; } diff --git a/test/fixtures.ts b/test/fixtures.ts index 07837a05de..7ee9d0ee87 100644 --- a/test/fixtures.ts +++ b/test/fixtures.ts @@ -1147,6 +1147,7 @@ class CommentInjectionTreeSitterFixture extends Fixture { private readonly _treeSitterLanguages = new Map(); private async loadTreeSitterLanguage( + // biome-ignore lint/suspicious/noExplicitAny: web-tree-sitter is loaded dynamically without types TreeSitter: any, wasmModule: string, ): Promise { @@ -1161,6 +1162,7 @@ class CommentInjectionTreeSitterFixture extends Fixture { } private async parseGeneratedFiles( + // biome-ignore lint/suspicious/noExplicitAny: web-tree-sitter is loaded dynamically without types TreeSitter: any, target: TreeSitterTarget, generatedFiles: string[], @@ -1183,6 +1185,7 @@ class CommentInjectionTreeSitterFixture extends Fixture { const tree = parser.parse(source); const problems: TreeSitterParseProblem[] = []; + // biome-ignore lint/suspicious/noExplicitAny: web-tree-sitter is loaded dynamically without types function visit(node: any): void { if ( node.type === "ERROR" || diff --git a/test/lib/deepEquals.ts b/test/lib/deepEquals.ts index 9019010418..9a1a5f967c 100644 --- a/test/lib/deepEquals.ts +++ b/test/lib/deepEquals.ts @@ -33,7 +33,9 @@ function momentsEqual(x: Moment, y: Moment, isTime: boolean): boolean { // https://stackoverflow.com/questions/1068834/object-comparison-in-javascript export default function deepEquals( + // biome-ignore lint/suspicious/noExplicitAny: compares arbitrary parsed JSON values x: any, + // biome-ignore lint/suspicious/noExplicitAny: compares arbitrary parsed JSON values y: any, assumeStringsEqual: boolean, relax: ComparisonRelaxations, From f2d4102f87f2d4368db12b46268b879d713032a2 Mon Sep 17 00:00:00 2001 From: Mark Probst Date: Mon, 13 Jul 2026 10:24:36 -0400 Subject: [PATCH 31/68] Biome: enable noUselessReturn and fix violations 24 violations: bare "return;" statements at the end of void functions or branches, removed by the safe fix. Co-Authored-By: Claude Fable 5 --- biome.json | 3 +++ packages/quicktype-core/src/DeclarationIR.ts | 2 -- packages/quicktype-core/src/Transformers.ts | 4 +--- packages/quicktype-core/src/Type/TypeBuilder.ts | 4 +--- packages/quicktype-core/src/Type/TypeUtils.ts | 4 +--- .../quicktype-core/src/attributes/TypeAttributes.ts | 4 +--- .../src/language/CPlusPlus/CPlusPlusRenderer.ts | 4 +--- .../src/language/CSharp/CSharpRenderer.ts | 12 +++--------- .../src/language/CSharp/NewtonSoftCSharpRenderer.ts | 4 +--- .../language/CSharp/SystemTextJsonCSharpRenderer.ts | 4 +--- .../src/language/Crystal/CrystalRenderer.ts | 1 - .../src/language/Elixir/ElixirRenderer.ts | 4 +--- .../src/language/JavaScript/JavaScriptRenderer.ts | 4 +--- .../src/language/Python/PythonRenderer.ts | 12 +++--------- .../src/language/Smithy4s/Smithy4sRenderer.ts | 8 ++------ .../TypeScriptFlow/TypeScriptFlowBaseRenderer.ts | 1 - .../language/TypeScriptFlow/TypeScriptRenderer.ts | 4 +--- packages/quicktype-vscode/src/extension.ts | 4 +--- test/fixtures.ts | 8 ++------ 19 files changed, 24 insertions(+), 67 deletions(-) diff --git a/biome.json b/biome.json index 7689fb7032..5cd7aa06de 100644 --- a/biome.json +++ b/biome.json @@ -21,6 +21,9 @@ "enabled": true, "rules": { "preset": "recommended", + "complexity": { + "noUselessReturn": "on" + }, "suspicious": { "noTemplateCurlyInString": "off" } diff --git a/packages/quicktype-core/src/DeclarationIR.ts b/packages/quicktype-core/src/DeclarationIR.ts index 108e6c2eb7..887fc10982 100644 --- a/packages/quicktype-core/src/DeclarationIR.ts +++ b/packages/quicktype-core/src/DeclarationIR.ts @@ -195,8 +195,6 @@ export function declarationsForGraph( for (const t of forwardDeclarable) { declarations.push({ kind: "define", type: t }); } - - return; } /* diff --git a/packages/quicktype-core/src/Transformers.ts b/packages/quicktype-core/src/Transformers.ts index 2037a36c0f..4b27d92039 100644 --- a/packages/quicktype-core/src/Transformers.ts +++ b/packages/quicktype-core/src/Transformers.ts @@ -78,9 +78,7 @@ export abstract class Transformer { return `${debugStringForType(this.sourceType)} -> ${this.kind}`; } - protected debugPrintContinuations(_indent: number): void { - return; - } + protected debugPrintContinuations(_indent: number): void {} public debugPrint(indent: number): void { console.log(indentationString(indent) + this.debugDescription()); diff --git a/packages/quicktype-core/src/Type/TypeBuilder.ts b/packages/quicktype-core/src/Type/TypeBuilder.ts index 88dcb97f37..a3239caa57 100644 --- a/packages/quicktype-core/src/Type/TypeBuilder.ts +++ b/packages/quicktype-core/src/Type/TypeBuilder.ts @@ -641,7 +641,5 @@ export class TypeBuilder { this.registerType(type); } - public setLostTypeAttributes(): void { - return; - } + public setLostTypeAttributes(): void {} } diff --git a/packages/quicktype-core/src/Type/TypeUtils.ts b/packages/quicktype-core/src/Type/TypeUtils.ts index 5dc0099241..c8f9554098 100644 --- a/packages/quicktype-core/src/Type/TypeUtils.ts +++ b/packages/quicktype-core/src/Type/TypeUtils.ts @@ -375,9 +375,7 @@ export function matchCompoundType( objectType: (objectType: ObjectType) => void, unionType: (unionType: UnionType) => void, ): void { - function ignore(_: T): void { - return; - } + function ignore(_: T): void {} matchTypeExhaustive( t, diff --git a/packages/quicktype-core/src/attributes/TypeAttributes.ts b/packages/quicktype-core/src/attributes/TypeAttributes.ts index 2f3e72e340..6fe033d53b 100644 --- a/packages/quicktype-core/src/attributes/TypeAttributes.ts +++ b/packages/quicktype-core/src/attributes/TypeAttributes.ts @@ -36,9 +36,7 @@ export class TypeAttributeKind { _schema: { [name: string]: unknown }, _t: Type, _attrs: T, - ): void { - return; - } + ): void {} public children(_: T): ReadonlySet { return new Set(); diff --git a/packages/quicktype-core/src/language/CPlusPlus/CPlusPlusRenderer.ts b/packages/quicktype-core/src/language/CPlusPlus/CPlusPlusRenderer.ts index e6704b5aca..ac7490596c 100644 --- a/packages/quicktype-core/src/language/CPlusPlus/CPlusPlusRenderer.ts +++ b/packages/quicktype-core/src/language/CPlusPlus/CPlusPlusRenderer.ts @@ -3331,9 +3331,7 @@ export class CPlusPlusRenderer extends ConvenienceRenderer { return inner; } - public emitHelperFunctions(): void { - return; - } + public emitHelperFunctions(): void {} })(); public WideString = new (class extends BaseString implements StringType { diff --git a/packages/quicktype-core/src/language/CSharp/CSharpRenderer.ts b/packages/quicktype-core/src/language/CSharp/CSharpRenderer.ts index 00c6848b13..956d3f3901 100644 --- a/packages/quicktype-core/src/language/CSharp/CSharpRenderer.ts +++ b/packages/quicktype-core/src/language/CSharp/CSharpRenderer.ts @@ -484,9 +484,7 @@ export class CSharpRenderer extends ConvenienceRenderer { } } - protected emitRequiredHelpers(): void { - return; - } + protected emitRequiredHelpers(): void {} private emitTypesAndSupport(): void { this.forEachObject( @@ -502,13 +500,9 @@ export class CSharpRenderer extends ConvenienceRenderer { this.emitRequiredHelpers(); } - protected emitDefaultLeadingComments(): void { - return; - } + protected emitDefaultLeadingComments(): void {} - protected emitDefaultFollowingComments(): void { - return; - } + protected emitDefaultFollowingComments(): void {} protected needNamespace(): boolean { return true; diff --git a/packages/quicktype-core/src/language/CSharp/NewtonSoftCSharpRenderer.ts b/packages/quicktype-core/src/language/CSharp/NewtonSoftCSharpRenderer.ts index 1eace12608..0df4b758f2 100644 --- a/packages/quicktype-core/src/language/CSharp/NewtonSoftCSharpRenderer.ts +++ b/packages/quicktype-core/src/language/CSharp/NewtonSoftCSharpRenderer.ts @@ -824,9 +824,7 @@ export class NewtonsoftCSharpRenderer extends CSharpRenderer { itemVariable, xfer.itemTransformer, xfer.itemTargetType, - () => { - return; - }, + () => {}, ); }); this.emitLine("writer.WriteEndArray();"); diff --git a/packages/quicktype-core/src/language/CSharp/SystemTextJsonCSharpRenderer.ts b/packages/quicktype-core/src/language/CSharp/SystemTextJsonCSharpRenderer.ts index 9e39c2f270..420dfd6102 100644 --- a/packages/quicktype-core/src/language/CSharp/SystemTextJsonCSharpRenderer.ts +++ b/packages/quicktype-core/src/language/CSharp/SystemTextJsonCSharpRenderer.ts @@ -949,9 +949,7 @@ export class SystemTextJsonCSharpRenderer extends CSharpRenderer { itemVariable, xfer.itemTransformer, xfer.itemTargetType, - () => { - return; - }, + () => {}, ); }); this.emitLine("writer.WriteEndArray();"); diff --git a/packages/quicktype-core/src/language/Crystal/CrystalRenderer.ts b/packages/quicktype-core/src/language/Crystal/CrystalRenderer.ts index 2d1b40640f..e73996bb93 100644 --- a/packages/quicktype-core/src/language/Crystal/CrystalRenderer.ts +++ b/packages/quicktype-core/src/language/Crystal/CrystalRenderer.ts @@ -202,7 +202,6 @@ export class CrystalRenderer extends ConvenienceRenderer { protected emitLeadingComments(): void { if (this.leadingComments !== undefined) { this.emitComments(this.leadingComments); - return; } } diff --git a/packages/quicktype-core/src/language/Elixir/ElixirRenderer.ts b/packages/quicktype-core/src/language/Elixir/ElixirRenderer.ts index ff09e39066..5aed56f468 100644 --- a/packages/quicktype-core/src/language/Elixir/ElixirRenderer.ts +++ b/packages/quicktype-core/src/language/Elixir/ElixirRenderer.ts @@ -1108,9 +1108,7 @@ end`); ); } - protected emitUnion(_u: UnionType, _unionName: Name): void { - return; - } + protected emitUnion(_u: UnionType, _unionName: Name): void {} protected emitSourceStructure(): void { if (this.leadingComments !== undefined) { diff --git a/packages/quicktype-core/src/language/JavaScript/JavaScriptRenderer.ts b/packages/quicktype-core/src/language/JavaScript/JavaScriptRenderer.ts index e6b2d9af6e..3ad4d04ade 100644 --- a/packages/quicktype-core/src/language/JavaScript/JavaScriptRenderer.ts +++ b/packages/quicktype-core/src/language/JavaScript/JavaScriptRenderer.ts @@ -497,9 +497,7 @@ function r(name${stringAnnotation}) { } } - protected emitTypes(): void { - return; - } + protected emitTypes(): void {} protected emitUsageImportComment(): void { this.emitLine('// const Convert = require("./file");'); diff --git a/packages/quicktype-core/src/language/Python/PythonRenderer.ts b/packages/quicktype-core/src/language/Python/PythonRenderer.ts index cd386f7ca5..c2fdda6910 100644 --- a/packages/quicktype-core/src/language/Python/PythonRenderer.ts +++ b/packages/quicktype-core/src/language/Python/PythonRenderer.ts @@ -390,13 +390,9 @@ export class PythonRenderer extends ConvenienceRenderer { }); } - protected emitSupportCode(): void { - return; - } + protected emitSupportCode(): void {} - protected emitClosingCode(): void { - return; - } + protected emitClosingCode(): void {} protected emitSourceStructure(_givenOutputFilename: string): void { const declarationLines = this.gatherSource(() => { @@ -404,9 +400,7 @@ export class PythonRenderer extends ConvenienceRenderer { ["interposing", 2], (c: ClassType) => this.emitClass(c), (e) => this.emitEnum(e), - (_u) => { - return; - }, + (_u) => {}, ); }); diff --git a/packages/quicktype-core/src/language/Smithy4s/Smithy4sRenderer.ts b/packages/quicktype-core/src/language/Smithy4s/Smithy4sRenderer.ts index 17bd7f18cc..e9c27f47c3 100644 --- a/packages/quicktype-core/src/language/Smithy4s/Smithy4sRenderer.ts +++ b/packages/quicktype-core/src/language/Smithy4s/Smithy4sRenderer.ts @@ -302,9 +302,7 @@ export class Smithy4sRenderer extends ConvenienceRenderer { protected emitClassDefinitionMethods(arrayTypes: ClassProperty[]): void { this.emitLine("}"); arrayTypes.forEach((p) => { - function ignore(_: T): void { - return; - } + function ignore(_: T): void {} matchCompoundType( p.type, @@ -397,9 +395,7 @@ export class Smithy4sRenderer extends ConvenienceRenderer { this.ensureBlankLine(); emitLater.forEach((p) => { - function ignore(_: T): void { - return; - } + function ignore(_: T): void {} matchCompoundType( p, diff --git a/packages/quicktype-core/src/language/TypeScriptFlow/TypeScriptFlowBaseRenderer.ts b/packages/quicktype-core/src/language/TypeScriptFlow/TypeScriptFlowBaseRenderer.ts index e223aafb49..d4c2393d38 100644 --- a/packages/quicktype-core/src/language/TypeScriptFlow/TypeScriptFlowBaseRenderer.ts +++ b/packages/quicktype-core/src/language/TypeScriptFlow/TypeScriptFlowBaseRenderer.ts @@ -250,7 +250,6 @@ export abstract class TypeScriptFlowBaseRenderer extends JavaScriptRenderer { protected emitModuleExports(): void { if (this._tsFlowOptions.justTypes) { - return; } else { super.emitModuleExports(); } diff --git a/packages/quicktype-core/src/language/TypeScriptFlow/TypeScriptRenderer.ts b/packages/quicktype-core/src/language/TypeScriptFlow/TypeScriptRenderer.ts index 29937d67d2..e87a4d6d77 100644 --- a/packages/quicktype-core/src/language/TypeScriptFlow/TypeScriptRenderer.ts +++ b/packages/quicktype-core/src/language/TypeScriptFlow/TypeScriptRenderer.ts @@ -48,9 +48,7 @@ export class TypeScriptRenderer extends TypeScriptFlowBaseRenderer { return Object.assign({ never: ": never" }, tsFlowTypeAnnotations); } - protected emitModuleExports(): void { - return; - } + protected emitModuleExports(): void {} protected emitUsageImportComment(): void { const topLevelNames: Sourcelike[] = []; diff --git a/packages/quicktype-vscode/src/extension.ts b/packages/quicktype-vscode/src/extension.ts index 5211ae5ec6..3ac95364ba 100644 --- a/packages/quicktype-vscode/src/extension.ts +++ b/packages/quicktype-vscode/src/extension.ts @@ -546,6 +546,4 @@ export async function activate( } } -export function deactivate(): void { - return; -} +export function deactivate(): void {} diff --git a/test/fixtures.ts b/test/fixtures.ts index 7ee9d0ee87..e65729d2f9 100644 --- a/test/fixtures.ts +++ b/test/fixtures.ts @@ -159,9 +159,7 @@ export abstract class Fixture { return this.name === name; } - async setup(): Promise { - return; - } + async setup(): Promise {} abstract getSamples(sources: string[]): { priority: Sample[]; @@ -1110,9 +1108,7 @@ class CommentInjectionTreeSitterFixture extends Fixture { return this.name === name; } - async setup(): Promise { - return; - } + async setup(): Promise {} getSamples(sources: string[]): { priority: Sample[]; others: Sample[] } { const commentInjectionSamples = [ From e4df2f01769e1665a5c12c12ed74473908416a30 Mon Sep 17 00:00:00 2001 From: Mark Probst Date: Mon, 13 Jul 2026 10:25:22 -0400 Subject: [PATCH 32/68] Biome: enable noUselessElse and fix violations Twenty violations: else blocks following branches that end in return, flattened into straight-line code. Co-Authored-By: Claude Fable 5 --- biome.json | 3 + packages/quicktype-core/src/MarkovChain.ts | 3 +- .../quicktype-core/src/Type/TypeGraphUtils.ts | 11 ++-- packages/quicktype-core/src/UnifyClasses.ts | 61 +++++++++---------- packages/quicktype-core/src/UnionBuilder.ts | 11 ++-- .../src/attributes/AccessorNames.ts | 37 ++++++----- .../src/attributes/TypeAttributes.ts | 3 +- .../src/language/CSharp/CSharpRenderer.ts | 6 +- .../src/language/Crystal/utils.ts | 3 +- .../quicktype-core/src/language/Rust/utils.ts | 3 +- .../src/language/Scala3/utils.ts | 3 +- .../src/language/TypeScriptFlow/utils.ts | 12 ++-- .../quicktype-core/src/support/Strings.ts | 6 +- 13 files changed, 77 insertions(+), 85 deletions(-) diff --git a/biome.json b/biome.json index 5cd7aa06de..6ada8476df 100644 --- a/biome.json +++ b/biome.json @@ -24,6 +24,9 @@ "complexity": { "noUselessReturn": "on" }, + "style": { + "noUselessElse": "on" + }, "suspicious": { "noTemplateCurlyInString": "off" } diff --git a/packages/quicktype-core/src/MarkovChain.ts b/packages/quicktype-core/src/MarkovChain.ts index ca256a6def..ce9addf0cf 100644 --- a/packages/quicktype-core/src/MarkovChain.ts +++ b/packages/quicktype-core/src/MarkovChain.ts @@ -39,9 +39,8 @@ function lookup(t: Trie, seq: string, i: number): Trie | number | undefined { if (typeof n === "object") { return lookup(n, seq, i + 1); - } else { - return n / t.count; } + return n / t.count; } function increment(t: Trie, seq: string, i: number): void { diff --git a/packages/quicktype-core/src/Type/TypeGraphUtils.ts b/packages/quicktype-core/src/Type/TypeGraphUtils.ts index 66baa207be..732c3734ec 100644 --- a/packages/quicktype-core/src/Type/TypeGraphUtils.ts +++ b/packages/quicktype-core/src/Type/TypeGraphUtils.ts @@ -91,13 +91,12 @@ export function optionalToNullable( properties, forwardingRef, ); - } else { - return builder.getClassType( - c.getAttributes(), - properties, - forwardingRef, - ); } + return builder.getClassType( + c.getAttributes(), + properties, + forwardingRef, + ); } const classesWithOptional = setFilter( diff --git a/packages/quicktype-core/src/UnifyClasses.ts b/packages/quicktype-core/src/UnifyClasses.ts index b3faa9638f..563a92c493 100644 --- a/packages/quicktype-core/src/UnifyClasses.ts +++ b/packages/quicktype-core/src/UnifyClasses.ts @@ -193,38 +193,36 @@ export class UnifyUnionBuilder extends UnionBuilder< this._unifyTypes(Array.from(propertyTypes)), forwardingRef, ); - } else { - const [properties, additionalProperties, lostTypeAttributes] = - getCliqueProperties(objectTypes, this.typeBuilder, (types) => { - assert(types.size > 0, "Property has no type"); - return this._unifyTypes( - Array.from(types).map((t) => t.typeRef), - ); - }); - if (lostTypeAttributes) { - this.typeBuilder.setLostTypeAttributes(); - } - - if (this._makeObjectTypes) { - return this.typeBuilder.getUniqueObjectType( - typeAttributes, - properties, - additionalProperties, - forwardingRef, - ); - } else { - assert( - additionalProperties === undefined, - "We have additional properties but want to make a class", - ); - return this.typeBuilder.getUniqueClassType( - typeAttributes, - this._makeClassesFixed, - properties, - forwardingRef, + } + const [properties, additionalProperties, lostTypeAttributes] = + getCliqueProperties(objectTypes, this.typeBuilder, (types) => { + assert(types.size > 0, "Property has no type"); + return this._unifyTypes( + Array.from(types).map((t) => t.typeRef), ); - } + }); + if (lostTypeAttributes) { + this.typeBuilder.setLostTypeAttributes(); } + + if (this._makeObjectTypes) { + return this.typeBuilder.getUniqueObjectType( + typeAttributes, + properties, + additionalProperties, + forwardingRef, + ); + } + assert( + additionalProperties === undefined, + "We have additional properties but want to make a class", + ); + return this.typeBuilder.getUniqueClassType( + typeAttributes, + this._makeClassesFixed, + properties, + forwardingRef, + ); } protected makeArray( @@ -284,7 +282,8 @@ export function unifyTypes( typeAttributes = typeBuilder.reconstituteTypeAttributes(typeAttributes); if (types.size === 0) { return panic("Cannot unify empty set of types"); - } else if (types.size === 1) { + } + if (types.size === 1) { const first = defined(iterableFirst(types)); if (!(first instanceof UnionType)) { return typeBuilder.reconstituteTypeRef( diff --git a/packages/quicktype-core/src/UnionBuilder.ts b/packages/quicktype-core/src/UnionBuilder.ts index 1e9f0229bd..a79c952f7b 100644 --- a/packages/quicktype-core/src/UnionBuilder.ts +++ b/packages/quicktype-core/src/UnionBuilder.ts @@ -583,12 +583,11 @@ export abstract class UnionBuilder< if (union !== undefined) { this.typeBuilder.setSetOperationMembers(union, typesSet); return union; - } else { - return this.typeBuilder.getUnionType( - typeAttributes, - typesSet, - forwardingRef, - ); } + return this.typeBuilder.getUnionType( + typeAttributes, + typesSet, + forwardingRef, + ); } } diff --git a/packages/quicktype-core/src/attributes/AccessorNames.ts b/packages/quicktype-core/src/attributes/AccessorNames.ts index 6b3283cf71..0ab32123b6 100644 --- a/packages/quicktype-core/src/attributes/AccessorNames.ts +++ b/packages/quicktype-core/src/attributes/AccessorNames.ts @@ -260,24 +260,23 @@ export function accessorNamesAttributeProducer( makeAccessorNames(maybeAccessors), ), }; - } else { - const identifierAttribute = makeUnionIdentifierAttribute(); - - const accessors = checkArray(maybeAccessors, isAccessorEntry); - messageAssert( - cases.length === accessors.length, - "SchemaWrongAccessorEntryArrayLength", - { - operation: "oneOf", - ref: canonicalRef.push("oneOf"), - }, - ); - const caseAttributes = accessors.map((accessor) => - makeUnionMemberNamesAttribute( - identifierAttribute, - makeAccessorEntry(accessor), - ), - ); - return { forUnion: identifierAttribute, forCases: caseAttributes }; } + const identifierAttribute = makeUnionIdentifierAttribute(); + + const accessors = checkArray(maybeAccessors, isAccessorEntry); + messageAssert( + cases.length === accessors.length, + "SchemaWrongAccessorEntryArrayLength", + { + operation: "oneOf", + ref: canonicalRef.push("oneOf"), + }, + ); + const caseAttributes = accessors.map((accessor) => + makeUnionMemberNamesAttribute( + identifierAttribute, + makeAccessorEntry(accessor), + ), + ); + return { forUnion: identifierAttribute, forCases: caseAttributes }; } diff --git a/packages/quicktype-core/src/attributes/TypeAttributes.ts b/packages/quicktype-core/src/attributes/TypeAttributes.ts index 6fe033d53b..c9d1485fd9 100644 --- a/packages/quicktype-core/src/attributes/TypeAttributes.ts +++ b/packages/quicktype-core/src/attributes/TypeAttributes.ts @@ -158,9 +158,8 @@ export function combineTypeAttributes( if (attrs.length === 1) return attrs[0]; if (union) { return kind.combine(attrs); - } else { - return kind.intersect(attrs); } + return kind.intersect(attrs); } return mapFilterMap(attributesByKind, combine); diff --git a/packages/quicktype-core/src/language/CSharp/CSharpRenderer.ts b/packages/quicktype-core/src/language/CSharp/CSharpRenderer.ts index 956d3f3901..eae2af60c7 100644 --- a/packages/quicktype-core/src/language/CSharp/CSharpRenderer.ts +++ b/packages/quicktype-core/src/language/CSharp/CSharpRenderer.ts @@ -159,9 +159,8 @@ export class CSharpRenderer extends ConvenienceRenderer { ); if (this._csOptions.useList) { return ["List<", itemsType, ">"]; - } else { - return [itemsType, "[]"]; } + return [itemsType, "[]"]; }, (classType) => this.nameForNamedType(classType), (mapType) => [ @@ -190,9 +189,8 @@ export class CSharpRenderer extends ConvenienceRenderer { const csType = this.csType(t, follow, withIssues); if (isValueType(t)) { return [csType, "?"]; - } else { - return csType; } + return csType; } protected baseclassForType(_t: Type): Sourcelike | undefined { diff --git a/packages/quicktype-core/src/language/Crystal/utils.ts b/packages/quicktype-core/src/language/Crystal/utils.ts index 5dc85b9e64..a23c88512f 100644 --- a/packages/quicktype-core/src/language/Crystal/utils.ts +++ b/packages/quicktype-core/src/language/Crystal/utils.ts @@ -62,9 +62,8 @@ export const camelNamingFunction = funPrefixNamer("camel", (original: string) => function standardUnicodeCrystalEscape(codePoint: number): string { if (codePoint <= 0xffff) { return `\\u{${intToHex(codePoint, 4)}}`; - } else { - return `\\u{${intToHex(codePoint, 6)}}`; } + return `\\u{${intToHex(codePoint, 6)}}`; } export const crystalStringEscape = utf32ConcatMap( diff --git a/packages/quicktype-core/src/language/Rust/utils.ts b/packages/quicktype-core/src/language/Rust/utils.ts index 92cb7d3a96..a8a6473df4 100644 --- a/packages/quicktype-core/src/language/Rust/utils.ts +++ b/packages/quicktype-core/src/language/Rust/utils.ts @@ -155,9 +155,8 @@ export const camelNamingFunction = funPrefixNamer("camel", (original: string) => const standardUnicodeRustEscape = (codePoint: number): string => { if (codePoint <= 0xffff) { return `\\u{${intToHex(codePoint, 4)}}`; - } else { - return `\\u{${intToHex(codePoint, 6)}}`; } + return `\\u{${intToHex(codePoint, 6)}}`; }; export const rustStringEscape = utf32ConcatMap( diff --git a/packages/quicktype-core/src/language/Scala3/utils.ts b/packages/quicktype-core/src/language/Scala3/utils.ts index 3c7258dc44..ad237781e2 100644 --- a/packages/quicktype-core/src/language/Scala3/utils.ts +++ b/packages/quicktype-core/src/language/Scala3/utils.ts @@ -29,9 +29,8 @@ export const shouldAddBacktick = (paramName: string): boolean => { export const wrapOption = (s: string, optional: boolean): string => { if (optional) { return `Option[${s}]`; - } else { - return s; } + return s; }; function isPartCharacter(codePoint: number): boolean { diff --git a/packages/quicktype-core/src/language/TypeScriptFlow/utils.ts b/packages/quicktype-core/src/language/TypeScriptFlow/utils.ts index 01292966a1..7c64689f6a 100644 --- a/packages/quicktype-core/src/language/TypeScriptFlow/utils.ts +++ b/packages/quicktype-core/src/language/TypeScriptFlow/utils.ts @@ -17,13 +17,15 @@ export function quotePropertyName(original: string): string { if (original.length === 0) { return quoted; - } else if (!isES3IdentifierStart(original.codePointAt(0) as number)) { + } + if (!isES3IdentifierStart(original.codePointAt(0) as number)) { return quoted; - } else if (escaped !== original) { + } + if (escaped !== original) { return quoted; - } else if (legalizeName(original) !== original) { + } + if (legalizeName(original) !== original) { return quoted; - } else { - return original; } + return original; } diff --git a/packages/quicktype-core/src/support/Strings.ts b/packages/quicktype-core/src/support/Strings.ts index 16e011da17..2508b84f74 100644 --- a/packages/quicktype-core/src/support/Strings.ts +++ b/packages/quicktype-core/src/support/Strings.ts @@ -190,9 +190,8 @@ export function intToHex(i: number, width: number): string { export function standardUnicodeHexEscape(codePoint: number): string { if (codePoint <= 0xffff) { return `\\u${intToHex(codePoint, 4)}`; - } else { - return `\\U${intToHex(codePoint, 8)}`; } + return `\\U${intToHex(codePoint, 8)}`; } export function escapeNonPrintableMapper( @@ -672,8 +671,7 @@ export function makeNameStyle( if (prefix !== undefined) { return addPrefixIfNecessary(prefix, styledName); - } else { - return styledName; } + return styledName; }; } From 54e284c4a803afe3d4697815b72e1b090717df3e Mon Sep 17 00:00:00 2001 From: Mark Probst Date: Mon, 13 Jul 2026 10:27:27 -0400 Subject: [PATCH 33/68] Biome: enable useCollapsedElseIf and fix violations Sixteen violations: "else { if ... }" chains collapsed to "else if". One site in the System.Text.Json renderer was collapsed by hand to keep its explanatory comment. Co-Authored-By: Claude Fable 5 --- biome.json | 3 +- packages/quicktype-core/src/Type/TypeUtils.ts | 14 +- .../src/input/JSONSchemaInput.ts | 12 +- .../src/language/CJSON/CJSONRenderer.ts | 498 +++++++++--------- .../language/CPlusPlus/CPlusPlusRenderer.ts | 8 +- .../CSharp/SystemTextJsonCSharpRenderer.ts | 46 +- .../language/JavaScript/JavaScriptRenderer.ts | 12 +- .../JavaScriptPropTypesRenderer.ts | 20 +- .../src/rewrites/CombineClasses.ts | 12 +- 9 files changed, 293 insertions(+), 332 deletions(-) diff --git a/biome.json b/biome.json index 6ada8476df..0a8f13f152 100644 --- a/biome.json +++ b/biome.json @@ -25,7 +25,8 @@ "noUselessReturn": "on" }, "style": { - "noUselessElse": "on" + "noUselessElse": "on", + "useCollapsedElseIf": "on" }, "suspicious": { "noTemplateCurlyInString": "off" diff --git a/packages/quicktype-core/src/Type/TypeUtils.ts b/packages/quicktype-core/src/Type/TypeUtils.ts index c8f9554098..1cf806c3d2 100644 --- a/packages/quicktype-core/src/Type/TypeUtils.ts +++ b/packages/quicktype-core/src/Type/TypeUtils.ts @@ -81,14 +81,12 @@ export function setOperationMembersRecursively( } } else if (includeAny || t.kind !== "any") { members.add(t); - } else { - if (combinationKind !== undefined) { - attributes = combineTypeAttributes( - combinationKind, - attributes, - t.getAttributes(), - ); - } + } else if (combinationKind !== undefined) { + attributes = combineTypeAttributes( + combinationKind, + attributes, + t.getAttributes(), + ); } } diff --git a/packages/quicktype-core/src/input/JSONSchemaInput.ts b/packages/quicktype-core/src/input/JSONSchemaInput.ts index b9d796d21f..a4d3e359fe 100644 --- a/packages/quicktype-core/src/input/JSONSchemaInput.ts +++ b/packages/quicktype-core/src/input/JSONSchemaInput.ts @@ -399,13 +399,11 @@ export class Ref { if (!(other instanceof Ref)) return false; if (this.addressURI !== undefined && other.addressURI !== undefined) { if (!this.addressURI.equals(other.addressURI)) return false; - } else { - if ( - (this.addressURI === undefined) !== - (other.addressURI === undefined) - ) - return false; - } + } else if ( + (this.addressURI === undefined) !== + (other.addressURI === undefined) + ) + return false; const l = this.path.length; if (l !== other.path.length) return false; diff --git a/packages/quicktype-core/src/language/CJSON/CJSONRenderer.ts b/packages/quicktype-core/src/language/CJSON/CJSONRenderer.ts index f8506ae980..4624257da8 100644 --- a/packages/quicktype-core/src/language/CJSON/CJSONRenderer.ts +++ b/packages/quicktype-core/src/language/CJSON/CJSONRenderer.ts @@ -1716,39 +1716,35 @@ export class CJSONRenderer extends ConvenienceRenderer { "cJSON_NULL" ) { /* Nothing to do */ + } else if ( + cJSON.items?.isNullable + ) { + this.emitBlock( + [ + "if ((void *)0xDEADBEEF != x", + child_level.toString(), + ")", + ], + () => { + this.emitLine( + // @ts-expect-error awaiting refactor + cJSON.items + ?.deleteType, + "(x", + child_level.toString(), + ");", + ); + }, + ); } else { - if ( + this.emitLine( + // @ts-expect-error awaiting refactor cJSON.items - ?.isNullable - ) { - this.emitBlock( - [ - "if ((void *)0xDEADBEEF != x", - child_level.toString(), - ")", - ], - () => { - this.emitLine( - // @ts-expect-error awaiting refactor - cJSON - .items - ?.deleteType, - "(x", - child_level.toString(), - ");", - ); - }, - ); - } else { - this.emitLine( - // @ts-expect-error awaiting refactor - cJSON.items - ?.deleteType, - "(x", - child_level.toString(), - ");", - ); - } + ?.deleteType, + "(x", + child_level.toString(), + ");", + ); } this.emitLine( @@ -1894,41 +1890,39 @@ export class CJSONRenderer extends ConvenienceRenderer { "cJSON_NULL" ) { /* Nothing to do */ + } else if ( + cJSON + .items + ?.isNullable + ) { + this.emitBlock( + [ + "if ((void *)0xDEADBEEF != x", + child_level.toString(), + ")", + ], + () => { + this.emitLine( + // @ts-expect-error awaiting refactor + cJSON + .items + ?.deleteType, + "(x", + child_level.toString(), + ");", + ); + }, + ); } else { - if ( + this.emitLine( + // @ts-expect-error awaiting refactor cJSON .items - ?.isNullable - ) { - this.emitBlock( - [ - "if ((void *)0xDEADBEEF != x", - child_level.toString(), - ")", - ], - () => { - this.emitLine( - // @ts-expect-error awaiting refactor - cJSON - .items - ?.deleteType, - "(x", - child_level.toString(), - ");", - ); - }, - ); - } else { - this.emitLine( - // @ts-expect-error awaiting refactor - cJSON - .items - ?.deleteType, - "(x", - child_level.toString(), - ");", - ); - } + ?.deleteType, + "(x", + child_level.toString(), + ");", + ); } }, ); @@ -2991,64 +2985,60 @@ export class CJSONRenderer extends ConvenienceRenderer { jsonName, '"));', ); - } else { - if ( - property.isOptional || - cJSON.isNullable - ) { - this.emitBlock( - [ - "if (NULL != (x", - level > 0 - ? level.toString() - : "", - "->", - name, - " = cJSON_malloc(sizeof(", - cJSON.cType, - "))))", - ], - () => { - this.emitLine( - "*x", - level > - 0 - ? level.toString() - : "", - "->", - name, - " = ", - cJSON.getValue, - "(cJSON_GetObjectItemCaseSensitive(j", - level > - 0 - ? level.toString() - : "", - ', "', - jsonName, - '"));', - ); - }, - ); - } else { - this.emitLine( - "x", + } else if ( + property.isOptional || + cJSON.isNullable + ) { + this.emitBlock( + [ + "if (NULL != (x", level > 0 ? level.toString() : "", "->", name, - " = ", - cJSON.getValue, - "(cJSON_GetObjectItemCaseSensitive(j", - level > 0 - ? level.toString() - : "", - ', "', - jsonName, - '"));', - ); - } + " = cJSON_malloc(sizeof(", + cJSON.cType, + "))))", + ], + () => { + this.emitLine( + "*x", + level > 0 + ? level.toString() + : "", + "->", + name, + " = ", + cJSON.getValue, + "(cJSON_GetObjectItemCaseSensitive(j", + level > 0 + ? level.toString() + : "", + ', "', + jsonName, + '"));', + ); + }, + ); + } else { + this.emitLine( + "x", + level > 0 + ? level.toString() + : "", + "->", + name, + " = ", + cJSON.getValue, + "(cJSON_GetObjectItemCaseSensitive(j", + level > 0 + ? level.toString() + : "", + ', "', + jsonName, + '"));', + ); } }, ); @@ -4022,58 +4012,56 @@ export class CJSONRenderer extends ConvenienceRenderer { "));", ); } - } else { - if ( - property.isOptional || - cJSON.isNullable - ) { - this.emitBlock( - [ - "if (NULL != x", - level > 0 - ? level.toString() - : "", - "->", - name, - ")", - ], - () => { - this.emitLine( - cJSON.addToObject, - "(j", - level > 0 - ? level.toString() - : "", - ', "', - jsonName, - '", *x', - level > 0 - ? level.toString() - : "", - "->", - name, - ");", - ); - }, - ); - } else { - this.emitLine( - cJSON.addToObject, - "(j", - level > 0 - ? level.toString() - : "", - ', "', - jsonName, - '", x', + } else if ( + property.isOptional || + cJSON.isNullable + ) { + this.emitBlock( + [ + "if (NULL != x", level > 0 ? level.toString() : "", "->", name, - ");", - ); - } + ")", + ], + () => { + this.emitLine( + cJSON.addToObject, + "(j", + level > 0 + ? level.toString() + : "", + ', "', + jsonName, + '", *x', + level > 0 + ? level.toString() + : "", + "->", + name, + ");", + ); + }, + ); + } else { + this.emitLine( + cJSON.addToObject, + "(j", + level > 0 + ? level.toString() + : "", + ', "', + jsonName, + '", x', + level > 0 + ? level.toString() + : "", + "->", + name, + ");", + ); } if (cJSON.isNullable) { @@ -4283,39 +4271,37 @@ export class CJSONRenderer extends ConvenienceRenderer { "cJSON_NULL" ) { /* Nothing to do */ + } else if ( + cJSON.items + ?.isNullable + ) { + this.emitBlock( + [ + "if ((void *)0xDEADBEEF != x", + child_level.toString(), + ")", + ], + () => { + this.emitLine( + // @ts-expect-error awaiting refactor + cJSON + .items + ?.deleteType, + "(x", + child_level.toString(), + ");", + ); + }, + ); } else { - if ( + this.emitLine( + // @ts-expect-error awaiting refactor cJSON.items - ?.isNullable - ) { - this.emitBlock( - [ - "if ((void *)0xDEADBEEF != x", - child_level.toString(), - ")", - ], - () => { - this.emitLine( - // @ts-expect-error awaiting refactor - cJSON - .items - ?.deleteType, - "(x", - child_level.toString(), - ");", - ); - }, - ); - } else { - this.emitLine( - // @ts-expect-error awaiting refactor - cJSON.items - ?.deleteType, - "(x", - child_level.toString(), - ");", - ); - } + ?.deleteType, + "(x", + child_level.toString(), + ");", + ); } this.emitLine( @@ -4469,41 +4455,39 @@ export class CJSONRenderer extends ConvenienceRenderer { "cJSON_NULL" ) { /* Nothing to do */ + } else if ( + cJSON + .items + ?.isNullable + ) { + this.emitBlock( + [ + "if ((void *)0xDEADBEEF != x", + child_level.toString(), + ")", + ], + () => { + this.emitLine( + // @ts-expect-error awaiting refactor + cJSON + .items + ?.deleteType, + "(x", + child_level.toString(), + ");", + ); + }, + ); } else { - if ( + this.emitLine( + // @ts-expect-error awaiting refactor cJSON .items - ?.isNullable - ) { - this.emitBlock( - [ - "if ((void *)0xDEADBEEF != x", - child_level.toString(), - ")", - ], - () => { - this.emitLine( - // @ts-expect-error awaiting refactor - cJSON - .items - ?.deleteType, - "(x", - child_level.toString(), - ");", - ); - }, - ); - } else { - this.emitLine( - // @ts-expect-error awaiting refactor - cJSON - .items - ?.deleteType, - "(x", - child_level.toString(), - ");", - ); - } + ?.deleteType, + "(x", + child_level.toString(), + ");", + ); } }, ); @@ -4561,35 +4545,33 @@ export class CJSONRenderer extends ConvenienceRenderer { ); }, ); - } else { - if ( - property.isOptional || - cJSON.isNullable - ) { - this.emitBlock( - [ - "if (NULL != x", + } else if ( + property.isOptional || + cJSON.isNullable + ) { + this.emitBlock( + [ + "if (NULL != x", + level > 0 + ? level.toString() + : "", + "->", + name, + ")", + ], + () => { + this.emitLine( + cJSON.deleteType, + "(x", level > 0 ? level.toString() : "", "->", name, - ")", - ], - () => { - this.emitLine( - cJSON.deleteType, - "(x", - level > 0 - ? level.toString() - : "", - "->", - name, - ");", - ); - }, - ); - } + ");", + ); + }, + ); } }, ); @@ -5750,12 +5732,10 @@ export class CJSONRenderer extends ConvenienceRenderer { } else { this.emitLine("};"); } + } else if (withName !== "") { + this.emitLine("} ", withName); } else { - if (withName !== "") { - this.emitLine("} ", withName); - } else { - this.emitLine("}"); - } + this.emitLine("}"); } } @@ -5834,12 +5814,10 @@ export class CJSONRenderer extends ConvenienceRenderer { if (maybeNull !== undefined) { /* Houston this is a variant, include it */ propRecord.kind = IncludeKind.Include; + } else if (t.forceInclude) { + propRecord.kind = IncludeKind.Include; } else { - if (t.forceInclude) { - propRecord.kind = IncludeKind.Include; - } else { - propRecord.kind = IncludeKind.ForwardDeclare; - } + propRecord.kind = IncludeKind.ForwardDeclare; } } diff --git a/packages/quicktype-core/src/language/CPlusPlus/CPlusPlusRenderer.ts b/packages/quicktype-core/src/language/CPlusPlus/CPlusPlusRenderer.ts index ac7490596c..dc98805a28 100644 --- a/packages/quicktype-core/src/language/CPlusPlus/CPlusPlusRenderer.ts +++ b/packages/quicktype-core/src/language/CPlusPlus/CPlusPlusRenderer.ts @@ -3039,12 +3039,10 @@ export class CPlusPlusRenderer extends ConvenienceRenderer { if (maybeNull !== undefined) { /** Houston this is a variant, include it */ propRecord.kind = IncludeKind.Include; + } else if (t.forceInclude) { + propRecord.kind = IncludeKind.Include; } else { - if (t.forceInclude) { - propRecord.kind = IncludeKind.Include; - } else { - propRecord.kind = IncludeKind.ForwardDeclare; - } + propRecord.kind = IncludeKind.ForwardDeclare; } } diff --git a/packages/quicktype-core/src/language/CSharp/SystemTextJsonCSharpRenderer.ts b/packages/quicktype-core/src/language/CSharp/SystemTextJsonCSharpRenderer.ts index 420dfd6102..8eb22b14b6 100644 --- a/packages/quicktype-core/src/language/CSharp/SystemTextJsonCSharpRenderer.ts +++ b/packages/quicktype-core/src/language/CSharp/SystemTextJsonCSharpRenderer.ts @@ -705,31 +705,29 @@ export class SystemTextJsonCSharpRenderer extends CSharpRenderer { } }); }); - } else { + } else if (xfer.integerTransformer !== undefined) { // Only one present, emit as before - if (xfer.integerTransformer !== undefined) { - varGen.counter++; - const intVar = `intValue${varGen.counter}`; - this.emitDecoderTransformerCase( - ["Number"], - intVar, - xfer.integerTransformer, - targetType, - emitFinish, - varGen, - ); - } else if (xfer.doubleTransformer !== undefined) { - varGen.counter++; - const doubleVar = `doubleValue${varGen.counter}`; - this.emitDecoderTransformerCase( - ["Number"], - doubleVar, - xfer.doubleTransformer, - targetType, - emitFinish, - varGen, - ); - } + varGen.counter++; + const intVar = `intValue${varGen.counter}`; + this.emitDecoderTransformerCase( + ["Number"], + intVar, + xfer.integerTransformer, + targetType, + emitFinish, + varGen, + ); + } else if (xfer.doubleTransformer !== undefined) { + varGen.counter++; + const doubleVar = `doubleValue${varGen.counter}`; + this.emitDecoderTransformerCase( + ["Number"], + doubleVar, + xfer.doubleTransformer, + targetType, + emitFinish, + varGen, + ); } this.emitDecoderTransformerCase( diff --git a/packages/quicktype-core/src/language/JavaScript/JavaScriptRenderer.ts b/packages/quicktype-core/src/language/JavaScript/JavaScriptRenderer.ts index 3ad4d04ade..f03e41f27f 100644 --- a/packages/quicktype-core/src/language/JavaScript/JavaScriptRenderer.ts +++ b/packages/quicktype-core/src/language/JavaScript/JavaScriptRenderer.ts @@ -279,16 +279,10 @@ export class JavaScriptRenderer extends ConvenienceRenderer { "), null, 2);", ); } + } else if (!this._jsOptions.runtimeTypecheck) { + this.emitLine("return value;"); } else { - if (!this._jsOptions.runtimeTypecheck) { - this.emitLine("return value;"); - } else { - this.emitLine( - "return uncast(value, ", - typeMap, - ");", - ); - } + this.emitLine("return uncast(value, ", typeMap, ");"); } }, ); diff --git a/packages/quicktype-core/src/language/JavaScriptPropTypes/JavaScriptPropTypesRenderer.ts b/packages/quicktype-core/src/language/JavaScriptPropTypes/JavaScriptPropTypesRenderer.ts index 1ddec6e6a9..67b37614d4 100644 --- a/packages/quicktype-core/src/language/JavaScriptPropTypes/JavaScriptPropTypesRenderer.ts +++ b/packages/quicktype-core/src/language/JavaScriptPropTypes/JavaScriptPropTypesRenderer.ts @@ -274,18 +274,16 @@ export class JavaScriptPropTypesRenderer extends ConvenienceRenderer { if (type instanceof PrimitiveType) { this.ensureBlankLine(); this.emitExport(name, this.typeMapTypeFor(type)); + } else if (type.kind === "array") { + this.ensureBlankLine(); + this.emitExport(name, [ + "PropTypes.arrayOf(", + this.typeMapTypeFor((type as ArrayType).items), + ")", + ]); } else { - if (type.kind === "array") { - this.ensureBlankLine(); - this.emitExport(name, [ - "PropTypes.arrayOf(", - this.typeMapTypeFor((type as ArrayType).items), - ")", - ]); - } else { - this.ensureBlankLine(); - this.emitExport(name, ["_", name]); - } + this.ensureBlankLine(); + this.emitExport(name, ["_", name]); } }); } diff --git a/packages/quicktype-core/src/rewrites/CombineClasses.ts b/packages/quicktype-core/src/rewrites/CombineClasses.ts index 37c45dc3ec..df8540a2e0 100644 --- a/packages/quicktype-core/src/rewrites/CombineClasses.ts +++ b/packages/quicktype-core/src/rewrites/CombineClasses.ts @@ -45,13 +45,11 @@ function canBeCombined( if (p1.size !== p2.size) { return false; } - } else { - if ( - p1.size < p2.size * REQUIRED_OVERLAP || - p2.size < p1.size * REQUIRED_OVERLAP - ) { - return false; - } + } else if ( + p1.size < p2.size * REQUIRED_OVERLAP || + p2.size < p1.size * REQUIRED_OVERLAP + ) { + return false; } let larger: ReadonlyMap; From ecebb49ee99a38562ab294b7b8042f252a5cbd2f Mon Sep 17 00:00:00 2001 From: Mark Probst Date: Mon, 13 Jul 2026 10:28:30 -0400 Subject: [PATCH 34/68] Biome: enable useCollapsedIf and fix violations Five violations: nested if statements with no other content merged into a single condition. One site in the Swift renderer was collapsed by hand to keep its FIXME comment. Co-Authored-By: Claude Fable 5 --- biome.json | 3 ++- packages/quicktype-core/src/Type/Type.ts | 4 +--- packages/quicktype-core/src/Type/TypeUtils.ts | 4 +--- .../src/language/Ruby/RubyRenderer.ts | 12 +++++----- .../src/language/Swift/SwiftRenderer.ts | 22 +++++++++---------- test/lib/deepEquals.ts | 12 +++++----- 6 files changed, 24 insertions(+), 33 deletions(-) diff --git a/biome.json b/biome.json index 0a8f13f152..efa6372d5c 100644 --- a/biome.json +++ b/biome.json @@ -26,7 +26,8 @@ }, "style": { "noUselessElse": "on", - "useCollapsedElseIf": "on" + "useCollapsedElseIf": "on", + "useCollapsedIf": "on" }, "suspicious": { "noTemplateCurlyInString": "off" diff --git a/packages/quicktype-core/src/Type/Type.ts b/packages/quicktype-core/src/Type/Type.ts index e4d2f50395..f888f4033f 100644 --- a/packages/quicktype-core/src/Type/Type.ts +++ b/packages/quicktype-core/src/Type/Type.ts @@ -782,9 +782,7 @@ export function setOperationCasesEqual( if (ma.size !== mb.size) return false; return iterableEvery(ma, (ta) => { const tb = iterableFind(mb, (t) => t.kind === ta.kind); - if (tb !== undefined) { - if (membersEqual(ta, tb)) return true; - } + if (tb !== undefined && membersEqual(ta, tb)) return true; if (conflateNumbers) { if ( diff --git a/packages/quicktype-core/src/Type/TypeUtils.ts b/packages/quicktype-core/src/Type/TypeUtils.ts index 1cf806c3d2..42e037fd30 100644 --- a/packages/quicktype-core/src/Type/TypeUtils.ts +++ b/packages/quicktype-core/src/Type/TypeUtils.ts @@ -109,9 +109,7 @@ export function makeGroupsToFlatten( setOperationMembersRecursively(u, undefined)[0], ); - if (include !== undefined) { - if (!include(members)) continue; - } + if (include !== undefined && !include(members)) continue; let maybeSet = typeGroups.get(members); if (maybeSet === undefined) { diff --git a/packages/quicktype-core/src/language/Ruby/RubyRenderer.ts b/packages/quicktype-core/src/language/Ruby/RubyRenderer.ts index 957370d671..13266def0a 100644 --- a/packages/quicktype-core/src/language/Ruby/RubyRenderer.ts +++ b/packages/quicktype-core/src/language/Ruby/RubyRenderer.ts @@ -732,13 +732,11 @@ export class RubyRenderer extends ConvenienceRenderer { ["Integer"], [` = ${this._options.strictness}Integer`], ]); - if (this._options.strictness === Strictness.Strict) { - if (has.nil) - declarations.push([ - ["Nil"], - [` = ${this._options.strictness}Nil`], - ]); - } + if (this._options.strictness === Strictness.Strict && has.nil) + declarations.push([ + ["Nil"], + [` = ${this._options.strictness}Nil`], + ]); if (has.bool) declarations.push([ diff --git a/packages/quicktype-core/src/language/Swift/SwiftRenderer.ts b/packages/quicktype-core/src/language/Swift/SwiftRenderer.ts index ff9bc58013..5b756f9d51 100644 --- a/packages/quicktype-core/src/language/Swift/SwiftRenderer.ts +++ b/packages/quicktype-core/src/language/Swift/SwiftRenderer.ts @@ -684,18 +684,16 @@ export class SwiftRenderer extends ConvenienceRenderer { }, ); - if (!this._options.justTypes) { - // FIXME: We emit only the MARK line for top-level-enum.schema - if (this._options.convenienceInitializers) { - this.ensureBlankLine(); - this.emitMark( - this.sourcelikeToString(className) + - " convenience initializers and mutators", - ); - this.ensureBlankLine(); - this.emitConvenienceInitializersExtension(c, className); - this.ensureBlankLine(); - } + // FIXME: We emit only the MARK line for top-level-enum.schema + if (!this._options.justTypes && this._options.convenienceInitializers) { + this.ensureBlankLine(); + this.emitMark( + this.sourcelikeToString(className) + + " convenience initializers and mutators", + ); + this.ensureBlankLine(); + this.emitConvenienceInitializersExtension(c, className); + this.ensureBlankLine(); } this.endFile(); diff --git a/test/lib/deepEquals.ts b/test/lib/deepEquals.ts index 9a1a5f967c..6dd1338bc9 100644 --- a/test/lib/deepEquals.ts +++ b/test/lib/deepEquals.ts @@ -145,13 +145,11 @@ export default function deepEquals( for (const p of yKeys) { // We allow properties in y that aren't present in x // so long as they're null. - if (xKeys.indexOf(p) < 0) { - if (y[p] !== null) { - console.error( - `Non-null property ${p} is not expected at path ${pathToString(path)}.`, - ); - return false; - } + if (xKeys.indexOf(p) < 0 && y[p] !== null) { + console.error( + `Non-null property ${p} is not expected at path ${pathToString(path)}.`, + ); + return false; } } From 23d86306649b62d0c638f7f04f82870264ca3219 Mon Sep 17 00:00:00 2001 From: Mark Probst Date: Mon, 13 Jul 2026 10:29:09 -0400 Subject: [PATCH 35/68] Biome: enable useThrowNewError and fix violations Fifteen violations: "throw Error(...)" changed to "throw new Error(...)". Identical behavior; consistent with the rest of the codebase. Co-Authored-By: Claude Fable 5 --- biome.json | 3 +- .../src/language/Php/PhpRenderer.ts | 30 +++++++++---------- 2 files changed, 17 insertions(+), 16 deletions(-) diff --git a/biome.json b/biome.json index efa6372d5c..8afcad314e 100644 --- a/biome.json +++ b/biome.json @@ -27,7 +27,8 @@ "style": { "noUselessElse": "on", "useCollapsedElseIf": "on", - "useCollapsedIf": "on" + "useCollapsedIf": "on", + "useThrowNewError": "on" }, "suspicious": { "noTemplateCurlyInString": "off" diff --git a/packages/quicktype-core/src/language/Php/PhpRenderer.ts b/packages/quicktype-core/src/language/Php/PhpRenderer.ts index d2e7ba2825..16a1fd58d0 100644 --- a/packages/quicktype-core/src/language/Php/PhpRenderer.ts +++ b/packages/quicktype-core/src/language/Php/PhpRenderer.ts @@ -280,11 +280,11 @@ export class PhpRenderer extends ConvenienceRenderer { }, (transformedStringType) => { if (transformedStringType.kind === "time") { - throw Error('transformedStringType.kind === "time"'); + throw new Error('transformedStringType.kind === "time"'); } if (transformedStringType.kind === "date") { - throw Error('transformedStringType.kind === "date"'); + throw new Error('transformedStringType.kind === "date"'); } if (transformedStringType.kind === "date-time") { @@ -321,7 +321,7 @@ export class PhpRenderer extends ConvenienceRenderer { ]; } - throw Error("union are not supported"); + throw new Error("union are not supported"); }, (transformedStringType) => { if (transformedStringType.kind === "date-time") { @@ -332,7 +332,7 @@ export class PhpRenderer extends ConvenienceRenderer { return "string"; } - throw Error('transformedStringType.kind === "unknown"'); + throw new Error('transformedStringType.kind === "unknown"'); }, ); } @@ -356,7 +356,7 @@ export class PhpRenderer extends ConvenienceRenderer { return ["?", this.phpConvertType(className, nullable)]; } - throw Error("union are not supported"); + throw new Error("union are not supported"); }, (transformedStringType) => { if (transformedStringType.kind === "date-time") { @@ -367,7 +367,7 @@ export class PhpRenderer extends ConvenienceRenderer { return "string"; } - throw Error('transformedStringType.kind === "unknown"'); + throw new Error('transformedStringType.kind === "unknown"'); }, ); } @@ -435,7 +435,7 @@ export class PhpRenderer extends ConvenienceRenderer { return; } - throw Error("union are not supported"); + throw new Error("union are not supported"); }, (transformedStringType) => { if (transformedStringType.kind === "date-time") { @@ -452,7 +452,7 @@ export class PhpRenderer extends ConvenienceRenderer { return; } - throw Error('transformedStringType.kind === "unknown"'); + throw new Error('transformedStringType.kind === "unknown"'); }, ); } @@ -546,7 +546,7 @@ export class PhpRenderer extends ConvenienceRenderer { return; } - throw Error("union are not supported"); + throw new Error("union are not supported"); }, (transformedStringType) => { if (transformedStringType.kind === "date-time") { @@ -566,7 +566,7 @@ export class PhpRenderer extends ConvenienceRenderer { return; } - throw Error('transformedStringType.kind === "unknown"'); + throw new Error('transformedStringType.kind === "unknown"'); }, ); } @@ -717,7 +717,7 @@ export class PhpRenderer extends ConvenienceRenderer { return; } - throw Error(`union are not supported:${unionType}`); + throw new Error(`union are not supported:${unionType}`); }, (transformedStringType) => { if (transformedStringType.kind === "date-time") { @@ -747,7 +747,7 @@ export class PhpRenderer extends ConvenienceRenderer { return; } - throw Error('transformedStringType.kind === "unknown"'); + throw new Error('transformedStringType.kind === "unknown"'); }, ); } @@ -832,7 +832,7 @@ export class PhpRenderer extends ConvenienceRenderer { return; } - throw Error("not implemented"); + throw new Error("not implemented"); }, (transformedStringType) => { if (transformedStringType.kind === "date-time") { @@ -862,7 +862,7 @@ export class PhpRenderer extends ConvenienceRenderer { return; } - throw Error( + throw new Error( `transformedStringType.kind === ${transformedStringType.kind}`, ); }, @@ -1351,7 +1351,7 @@ export class PhpRenderer extends ConvenienceRenderer { } protected emitUnionDefinition(_u: UnionType, _unionName: Name): void { - throw Error("emitUnionDefinition not implemented"); + throw new Error("emitUnionDefinition not implemented"); } protected emitEnumSerializationAttributes(_e: EnumType): void { From cb8ef4f9b395a3119b65e71a7de0144ade3e65df Mon Sep 17 00:00:00 2001 From: Mark Probst Date: Mon, 13 Jul 2026 10:29:47 -0400 Subject: [PATCH 36/68] Biome: enable useConsistentBuiltinInstantiation All fifteen violations were the "throw Error(...)" sites already fixed for useThrowNewError, so this is a config-only enable that keeps builtin constructors consistently invoked with "new". Co-Authored-By: Claude Fable 5 --- biome.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/biome.json b/biome.json index 8afcad314e..98e710cb75 100644 --- a/biome.json +++ b/biome.json @@ -28,7 +28,8 @@ "noUselessElse": "on", "useCollapsedElseIf": "on", "useCollapsedIf": "on", - "useThrowNewError": "on" + "useThrowNewError": "on", + "useConsistentBuiltinInstantiation": "on" }, "suspicious": { "noTemplateCurlyInString": "off" From 1dbda5b9a0e77bdbf2c25fa98bc95daad038a2ea Mon Sep 17 00:00:00 2001 From: Mark Probst Date: Mon, 13 Jul 2026 10:31:50 -0400 Subject: [PATCH 37/68] Biome: enable useObjectSpread and fix violations Seventeen violations: Object.assign calls with object-literal targets converted to spread syntax. Semantics are identical; three sites needed a type annotation or assertion because spread infers a plain object type where Object.assign inferred an intersection. Co-Authored-By: Claude Fable 5 --- biome.json | 3 ++- .../src/RendererOptions/index.ts | 10 ++++++---- packages/quicktype-core/src/Run.ts | 6 +++--- .../src/input/JSONSchemaInput.ts | 2 +- .../src/input/io/get-stream/buffer-stream.ts | 2 +- .../src/input/io/get-stream/index.ts | 6 +++--- .../src/language/CSharp/language.ts | 4 ++-- .../language/JSONSchema/JSONSchemaRenderer.ts | 8 ++++---- .../language/TypeScriptFlow/FlowRenderer.ts | 2 +- .../TypeScriptFlow/TypeScriptRenderer.ts | 2 +- .../src/language/TypeScriptFlow/language.ts | 5 +++-- src/index.ts | 18 ++++++++---------- test/fixtures.ts | 2 +- 13 files changed, 36 insertions(+), 34 deletions(-) diff --git a/biome.json b/biome.json index 98e710cb75..2c1e305d67 100644 --- a/biome.json +++ b/biome.json @@ -29,7 +29,8 @@ "useCollapsedElseIf": "on", "useCollapsedIf": "on", "useThrowNewError": "on", - "useConsistentBuiltinInstantiation": "on" + "useConsistentBuiltinInstantiation": "on", + "useObjectSpread": "on" }, "suspicious": { "noTemplateCurlyInString": "off" diff --git a/packages/quicktype-core/src/RendererOptions/index.ts b/packages/quicktype-core/src/RendererOptions/index.ts index b7f204c1bf..5a29e0f705 100644 --- a/packages/quicktype-core/src/RendererOptions/index.ts +++ b/packages/quicktype-core/src/RendererOptions/index.ts @@ -87,14 +87,16 @@ export class BooleanOption extends Option { actual: Array>; display: Array>; } { - const negated = Object.assign({}, this.definition, { + const negated = { + ...this.definition, name: `no-${this.name}`, defaultValue: !this.definition.defaultValue, - }); - const display = Object.assign({}, this.definition, { + } as OptionDefinition; + const display = { + ...this.definition, name: `[no-]${this.name}`, description: `${this.definition.description} (${this.definition.defaultValue ? "on" : "off"} by default)`, - }); + } as OptionDefinition; return { display: [display], actual: [this.definition, negated], diff --git a/packages/quicktype-core/src/Run.ts b/packages/quicktype-core/src/Run.ts index 5457fd419d..b97436c9dc 100644 --- a/packages/quicktype-core/src/Run.ts +++ b/packages/quicktype-core/src/Run.ts @@ -162,9 +162,9 @@ class Run implements RunContext { // We must not overwrite defaults with undefined values, which // we sometimes get. this._options = Object.fromEntries( - Object.entries( - Object.assign({}, defaultOptions, defaultInferenceFlags), - ).map(([k, v]) => [k, options[k as keyof typeof options] ?? v]), + Object.entries({ ...defaultOptions, ...defaultInferenceFlags }).map( + ([k, v]) => [k, options[k as keyof typeof options] ?? v], + ), ) as Required; } diff --git a/packages/quicktype-core/src/input/JSONSchemaInput.ts b/packages/quicktype-core/src/input/JSONSchemaInput.ts index a4d3e359fe..cc4202ed68 100644 --- a/packages/quicktype-core/src/input/JSONSchemaInput.ts +++ b/packages/quicktype-core/src/input/JSONSchemaInput.ts @@ -105,7 +105,7 @@ function withRef( : refOrLoc instanceof Ref ? refOrLoc : refOrLoc.canonicalRef; - return Object.assign({ ref }, props ?? {}); + return { ref, ...(props ?? {}) }; } function checkJSONSchemaObject( diff --git a/packages/quicktype-core/src/input/io/get-stream/buffer-stream.ts b/packages/quicktype-core/src/input/io/get-stream/buffer-stream.ts index 4c15e25f73..9a779416a5 100644 --- a/packages/quicktype-core/src/input/io/get-stream/buffer-stream.ts +++ b/packages/quicktype-core/src/input/io/get-stream/buffer-stream.ts @@ -13,7 +13,7 @@ export interface BufferedPassThrough extends PassThrough { } export default function bufferStream(opts: Options) { - opts = Object.assign({}, opts); + opts = { ...opts }; const array = opts.array; let encoding: string | undefined = opts.encoding; diff --git a/packages/quicktype-core/src/input/io/get-stream/index.ts b/packages/quicktype-core/src/input/io/get-stream/index.ts index c7bc8afe85..ee97f673bf 100644 --- a/packages/quicktype-core/src/input/io/get-stream/index.ts +++ b/packages/quicktype-core/src/input/io/get-stream/index.ts @@ -14,7 +14,7 @@ export async function getStream(inputStream: Readable, opts: Options = {}) { return await Promise.reject(new Error("Expected a stream")); } - opts = Object.assign({ maxBuffer: Number.POSITIVE_INFINITY }, opts); + opts = { maxBuffer: Number.POSITIVE_INFINITY, ...opts }; const maxBuffer = opts.maxBuffer ?? Number.POSITIVE_INFINITY; let stream: BufferedPassThrough; @@ -56,10 +56,10 @@ export async function getStream(inputStream: Readable, opts: Options = {}) { // FIXME: should these be async ? export function buffer(stream: Readable, opts: Options = {}) { - void getStream(stream, Object.assign({}, opts, { encoding: "buffer" })); + void getStream(stream, { ...opts, encoding: "buffer" }); } // FIXME: should these be async ? export function array(stream: Readable, opts: Options = {}) { - void getStream(stream, Object.assign({}, opts, { array: true })); + void getStream(stream, { ...opts, array: true }); } diff --git a/packages/quicktype-core/src/language/CSharp/language.ts b/packages/quicktype-core/src/language/CSharp/language.ts index 814a58844f..d07785dd4a 100644 --- a/packages/quicktype-core/src/language/CSharp/language.ts +++ b/packages/quicktype-core/src/language/CSharp/language.ts @@ -139,9 +139,9 @@ export const cSharpOptions = { ), } as const; -export const newtonsoftCSharpOptions = Object.assign({}, cSharpOptions, {}); +export const newtonsoftCSharpOptions = { ...cSharpOptions }; -export const systemTextJsonCSharpOptions = Object.assign({}, cSharpOptions, {}); +export const systemTextJsonCSharpOptions = { ...cSharpOptions }; export const cSharpLanguageConfig = { displayName: "C#", diff --git a/packages/quicktype-core/src/language/JSONSchema/JSONSchemaRenderer.ts b/packages/quicktype-core/src/language/JSONSchema/JSONSchemaRenderer.ts index 4bc06e0784..8512135b0f 100644 --- a/packages/quicktype-core/src/language/JSONSchema/JSONSchemaRenderer.ts +++ b/packages/quicktype-core/src/language/JSONSchema/JSONSchemaRenderer.ts @@ -181,10 +181,10 @@ export class JSONSchemaRenderer extends ConvenienceRenderer { this.topLevels.size === 1 ? this.schemaForType(defined(mapFirst(this.topLevels))) : {}; - const schema = Object.assign( - { $schema: "http://json-schema.org/draft-06/schema#" }, - topLevelType, - ); + const schema: Schema = { + $schema: "http://json-schema.org/draft-06/schema#", + ...topLevelType, + }; const definitions: { [name: string]: Schema } = {}; this.forEachObject("none", (o: ObjectType, name: Name) => { const title = defined(this.names.get(name)); diff --git a/packages/quicktype-core/src/language/TypeScriptFlow/FlowRenderer.ts b/packages/quicktype-core/src/language/TypeScriptFlow/FlowRenderer.ts index 59cdaf89b7..76446d9b34 100644 --- a/packages/quicktype-core/src/language/TypeScriptFlow/FlowRenderer.ts +++ b/packages/quicktype-core/src/language/TypeScriptFlow/FlowRenderer.ts @@ -13,7 +13,7 @@ export class FlowRenderer extends TypeScriptFlowBaseRenderer { } protected get typeAnnotations(): JavaScriptTypeAnnotations { - return Object.assign({ never: "" }, tsFlowTypeAnnotations); + return { never: "", ...tsFlowTypeAnnotations }; } protected emitEnum(e: EnumType, enumName: Name): void { diff --git a/packages/quicktype-core/src/language/TypeScriptFlow/TypeScriptRenderer.ts b/packages/quicktype-core/src/language/TypeScriptFlow/TypeScriptRenderer.ts index e87a4d6d77..43537b1464 100644 --- a/packages/quicktype-core/src/language/TypeScriptFlow/TypeScriptRenderer.ts +++ b/packages/quicktype-core/src/language/TypeScriptFlow/TypeScriptRenderer.ts @@ -45,7 +45,7 @@ export class TypeScriptRenderer extends TypeScriptFlowBaseRenderer { } protected get typeAnnotations(): JavaScriptTypeAnnotations { - return Object.assign({ never: ": never" }, tsFlowTypeAnnotations); + return { never: ": never", ...tsFlowTypeAnnotations }; } protected emitModuleExports(): void {} diff --git a/packages/quicktype-core/src/language/TypeScriptFlow/language.ts b/packages/quicktype-core/src/language/TypeScriptFlow/language.ts index 3115444854..3401829555 100644 --- a/packages/quicktype-core/src/language/TypeScriptFlow/language.ts +++ b/packages/quicktype-core/src/language/TypeScriptFlow/language.ts @@ -12,7 +12,8 @@ import { javaScriptOptions } from "../JavaScript/index.js"; import { FlowRenderer } from "./FlowRenderer.js"; import { TypeScriptRenderer } from "./TypeScriptRenderer.js"; -export const tsFlowOptions = Object.assign({}, javaScriptOptions, { +export const tsFlowOptions = { + ...javaScriptOptions, justTypes: new BooleanOption("just-types", "Interfaces only", false), nicePropertyNames: new BooleanOption( "nice-property-names", @@ -40,7 +41,7 @@ export const tsFlowOptions = Object.assign({}, javaScriptOptions, { false, ), readonly: new BooleanOption("readonly", "Use readonly type members", false), -}); +}; export const typeScriptLanguageConfig = { displayName: "TypeScript", diff --git a/src/index.ts b/src/index.ts index b7ea74ff4e..dd84cc6bdb 100644 --- a/src/index.ts +++ b/src/index.ts @@ -879,10 +879,10 @@ async function getSources(options: CLIOptions): Promise { } function makeTypeScriptSource(fileNames: string[]): SchemaTypeSource { - return Object.assign( - { kind: "schema" }, - schemaForTypeScriptSources(fileNames), - ) as SchemaTypeSource; + return { + kind: "schema", + ...schemaForTypeScriptSources(fileNames), + } as SchemaTypeSource; } export function jsonInputForTargetLanguage( @@ -1064,12 +1064,10 @@ export async function makeQuicktypeOptions( collectionFile, ); for (const src of postmanSources) { - sources.push( - Object.assign( - { kind: "json" }, - stringSourceDataToStreamSourceData(src), - ) as JSONTypeSource, - ); + sources.push({ + kind: "json", + ...stringSourceDataToStreamSourceData(src), + } as JSONTypeSource); } if (postmanSources.length > 1) { diff --git a/test/fixtures.ts b/test/fixtures.ts index e65729d2f9..bd7c5f5da9 100644 --- a/test/fixtures.ts +++ b/test/fixtures.ts @@ -100,7 +100,7 @@ function additionalTestFiles( function runEnvForLanguage( additionalRendererOptions: RendererOptions, ): NodeJS.ProcessEnv { - const newEnv = Object.assign({}, process.env); + const newEnv = { ...process.env }; for (const option of Object.keys(additionalRendererOptions)) { newEnv[`QUICKTYPE_${option.toUpperCase().replace("-", "_")}`] = ( From 60227fa4567c422a772dd3869e0b37c9016a319d Mon Sep 17 00:00:00 2001 From: Mark Probst Date: Mon, 13 Jul 2026 10:32:27 -0400 Subject: [PATCH 38/68] Biome: enable noYodaExpression and fix violations Seven violations: yoda comparisons flipped to subject-first order. Co-Authored-By: Claude Fable 5 --- biome.json | 3 ++- packages/quicktype-core/src/language/CJSON/CJSONRenderer.ts | 4 ++-- packages/quicktype-core/src/language/Elixir/ElixirRenderer.ts | 4 ++-- .../src/language/Objective-C/ObjectiveCRenderer.ts | 2 +- packages/quicktype-core/src/language/Ruby/RubyRenderer.ts | 4 ++-- 5 files changed, 9 insertions(+), 8 deletions(-) diff --git a/biome.json b/biome.json index 2c1e305d67..88c8f59a54 100644 --- a/biome.json +++ b/biome.json @@ -30,7 +30,8 @@ "useCollapsedIf": "on", "useThrowNewError": "on", "useConsistentBuiltinInstantiation": "on", - "useObjectSpread": "on" + "useObjectSpread": "on", + "noYodaExpression": "on" }, "suspicious": { "noTemplateCurlyInString": "off" diff --git a/packages/quicktype-core/src/language/CJSON/CJSONRenderer.ts b/packages/quicktype-core/src/language/CJSON/CJSONRenderer.ts index 4624257da8..875f6c0d83 100644 --- a/packages/quicktype-core/src/language/CJSON/CJSONRenderer.ts +++ b/packages/quicktype-core/src/language/CJSON/CJSONRenderer.ts @@ -203,9 +203,9 @@ export class CJSONRenderer extends ConvenienceRenderer { fieldType, lookup, ); - if ("bool" === fieldName) { + if (fieldName === "bool") { fieldName = "boolean"; - } else if ("double" === fieldName) { + } else if (fieldName === "double") { fieldName = "number"; } diff --git a/packages/quicktype-core/src/language/Elixir/ElixirRenderer.ts b/packages/quicktype-core/src/language/Elixir/ElixirRenderer.ts index 5aed56f468..340065991e 100644 --- a/packages/quicktype-core/src/language/Elixir/ElixirRenderer.ts +++ b/packages/quicktype-core/src/language/Elixir/ElixirRenderer.ts @@ -47,7 +47,7 @@ export class ElixirRenderer extends ConvenienceRenderer { } protected canBeForwardDeclared(t: Type): boolean { - return "class" === t.kind; + return t.kind === "class"; } protected forbiddenNamesForGlobalNamespace(): string[] { @@ -1145,7 +1145,7 @@ end`); this.forEachTopLevel( "leading-and-interposing", (topLevel, name) => { - const isTopLevelArray = "array" === topLevel.kind; + const isTopLevelArray = topLevel.kind === "array"; this.emitBlock( ["defmodule ", this.nameWithNamespace(name), " do"], diff --git a/packages/quicktype-core/src/language/Objective-C/ObjectiveCRenderer.ts b/packages/quicktype-core/src/language/Objective-C/ObjectiveCRenderer.ts index f31ad0e120..f863c05a75 100644 --- a/packages/quicktype-core/src/language/Objective-C/ObjectiveCRenderer.ts +++ b/packages/quicktype-core/src/language/Objective-C/ObjectiveCRenderer.ts @@ -408,7 +408,7 @@ export class ObjectiveCRenderer extends ConvenienceRenderer { } protected implicitlyConvertsToJSON(t: Type): boolean { - return this.implicitlyConvertsFromJSON(t) && "bool" !== t.kind; + return this.implicitlyConvertsFromJSON(t) && t.kind !== "bool"; } protected emitPropertyAssignment( diff --git a/packages/quicktype-core/src/language/Ruby/RubyRenderer.ts b/packages/quicktype-core/src/language/Ruby/RubyRenderer.ts index 13266def0a..319948d291 100644 --- a/packages/quicktype-core/src/language/Ruby/RubyRenderer.ts +++ b/packages/quicktype-core/src/language/Ruby/RubyRenderer.ts @@ -51,7 +51,7 @@ export class RubyRenderer extends ConvenienceRenderer { } protected canBeForwardDeclared(t: Type): boolean { - return "class" === t.kind; + return t.kind === "class"; } protected forbiddenNamesForGlobalNamespace(): readonly string[] { @@ -861,7 +861,7 @@ export class RubyRenderer extends ConvenienceRenderer { // The json gem defines to_json on maps and primitives, so we only need to supply // it for arrays. - const needsToJsonDefined = "array" === topLevel.kind; + const needsToJsonDefined = topLevel.kind === "array"; const classDeclaration = (): void => { this.emitBlock(["class ", name], () => { From 9a8b8bbdd4ec8ec074fdaf91202636c1f5b032f0 Mon Sep 17 00:00:00 2001 From: Mark Probst Date: Mon, 13 Jul 2026 10:34:37 -0400 Subject: [PATCH 39/68] Biome: enable noSubstr and fix violations Eleven violations, all String.prototype.substring calls, converted to slice. Index arguments at every site are non-negative with start <= end, except typeNameFromFilename, which got an explicit lastIndexOf guard to preserve its behavior for extension-less filenames. Co-Authored-By: Claude Fable 5 --- biome.json | 3 ++- packages/quicktype-core/src/Renderer.ts | 2 +- packages/quicktype-core/src/language/Rust/utils.ts | 7 +++---- packages/quicktype-core/src/support/Strings.ts | 8 ++++---- packages/quicktype-vscode/src/extension.ts | 2 +- src/index.ts | 3 ++- 6 files changed, 13 insertions(+), 12 deletions(-) diff --git a/biome.json b/biome.json index 88c8f59a54..3633450c16 100644 --- a/biome.json +++ b/biome.json @@ -31,7 +31,8 @@ "useThrowNewError": "on", "useConsistentBuiltinInstantiation": "on", "useObjectSpread": "on", - "noYodaExpression": "on" + "noYodaExpression": "on", + "noSubstr": "on" }, "suspicious": { "noTemplateCurlyInString": "off" diff --git a/packages/quicktype-core/src/Renderer.ts b/packages/quicktype-core/src/Renderer.ts index 847db36ff5..ca384d0016 100644 --- a/packages/quicktype-core/src/Renderer.ts +++ b/packages/quicktype-core/src/Renderer.ts @@ -51,7 +51,7 @@ function lineIndentation(line: string): { } else if (c === "\t") { indent = (indent / 4 + 1) * 4; } else { - return { indent, text: line.substring(i) }; + return { indent, text: line.slice(i) }; } } diff --git a/packages/quicktype-core/src/language/Rust/utils.ts b/packages/quicktype-core/src/language/Rust/utils.ts index a8a6473df4..b4dc83e24c 100644 --- a/packages/quicktype-core/src/language/Rust/utils.ts +++ b/packages/quicktype-core/src/language/Rust/utils.ts @@ -57,8 +57,8 @@ export const namingStyles = { .map((p, i) => i === 0 ? p.toLowerCase() - : p.substring(0, 1).toUpperCase() + - p.substring(1).toLowerCase(), + : p.slice(0, 1).toUpperCase() + + p.slice(1).toLowerCase(), ) .join(""), }, @@ -72,8 +72,7 @@ export const namingStyles = { parts .map( (p) => - p.substring(0, 1).toUpperCase() + - p.substring(1).toLowerCase(), + p.slice(0, 1).toUpperCase() + p.slice(1).toLowerCase(), ) .join(""), }, diff --git a/packages/quicktype-core/src/support/Strings.ts b/packages/quicktype-core/src/support/Strings.ts index 2508b84f74..2ccfebecf7 100644 --- a/packages/quicktype-core/src/support/Strings.ts +++ b/packages/quicktype-core/src/support/Strings.ts @@ -63,7 +63,7 @@ export function utf16ConcatMap( const cc = s.charCodeAt(i); if (charNoEscapeMap[cc] !== 1) { if (cs === null) cs = []; - cs.push(s.substring(start, i)); + cs.push(s.slice(start, i)); const str = charStringMap[cc]; if (str === undefined) { @@ -80,7 +80,7 @@ export function utf16ConcatMap( if (cs === null) return s; - cs.push(s.substring(start, i)); + cs.push(s.slice(start, i)); return cs.join(""); }; @@ -108,7 +108,7 @@ export function utf32ConcatMap( let cc = s.charCodeAt(i); if (charNoEscapeMap[cc] !== 1) { if (cs === null) cs = []; - cs.push(s.substring(start, i)); + cs.push(s.slice(start, i)); if (isHighSurrogate(cc)) { const highSurrogate = cc; @@ -139,7 +139,7 @@ export function utf32ConcatMap( if (cs === null) return s; - cs.push(s.substring(start, i)); + cs.push(s.slice(start, i)); return cs.join(""); }; diff --git a/packages/quicktype-vscode/src/extension.ts b/packages/quicktype-vscode/src/extension.ts index 3ac95364ba..dd967a5b2f 100644 --- a/packages/quicktype-vscode/src/extension.ts +++ b/packages/quicktype-vscode/src/extension.ts @@ -310,7 +310,7 @@ class CodeProvider implements vscode.TextDocumentContentProvider { public get documentName(): string { const basename = path.basename(this.document.fileName); const extIndex = basename.lastIndexOf("."); - return extIndex === -1 ? basename : basename.substring(0, extIndex); + return extIndex === -1 ? basename : basename.slice(0, extIndex); } public setDocument(document: vscode.TextDocument): void { diff --git a/src/index.ts b/src/index.ts index dd84cc6bdb..d7533f0869 100644 --- a/src/index.ts +++ b/src/index.ts @@ -120,7 +120,8 @@ async function sourceFromFileOrUrlArray( function typeNameFromFilename(filename: string): string { const name = path.basename(filename); - return name.substring(0, name.lastIndexOf(".")); + const extIndex = name.lastIndexOf("."); + return extIndex === -1 ? "" : name.slice(0, extIndex); } async function samplesFromDirectory( From 8e6ee26c309b761199b7f5e95c703614f33d3ed8 Mon Sep 17 00:00:00 2001 From: Mark Probst Date: Mon, 13 Jul 2026 10:35:32 -0400 Subject: [PATCH 40/68] Biome: enable useExplicitLengthCheck and fix violations Eleven violations: truthiness and "!== 0" checks on .length/.size rewritten as "> 0". One site in test/test.ts uses length as a numeric fallback value, where the suggested fix would have changed the result type, so it carries a suppression instead. Co-Authored-By: Claude Fable 5 --- biome.json | 3 ++- .../quicktype-core/src/language/CJSON/CJSONRenderer.ts | 2 +- .../src/language/CPlusPlus/CPlusPlusRenderer.ts | 4 ++-- .../quicktype-core/src/language/Elixir/ElixirRenderer.ts | 9 ++++++--- .../quicktype-core/src/language/Java/JavaRenderer.ts | 4 ++-- packages/quicktype-graphql-input/src/index.ts | 2 +- test/test.ts | 1 + 7 files changed, 15 insertions(+), 10 deletions(-) diff --git a/biome.json b/biome.json index 3633450c16..9e249ee23f 100644 --- a/biome.json +++ b/biome.json @@ -32,7 +32,8 @@ "useConsistentBuiltinInstantiation": "on", "useObjectSpread": "on", "noYodaExpression": "on", - "noSubstr": "on" + "noSubstr": "on", + "useExplicitLengthCheck": "on" }, "suspicious": { "noTemplateCurlyInString": "off" diff --git a/packages/quicktype-core/src/language/CJSON/CJSONRenderer.ts b/packages/quicktype-core/src/language/CJSON/CJSONRenderer.ts index 875f6c0d83..d2d0be8af9 100644 --- a/packages/quicktype-core/src/language/CJSON/CJSONRenderer.ts +++ b/packages/quicktype-core/src/language/CJSON/CJSONRenderer.ts @@ -5763,7 +5763,7 @@ export class CJSONRenderer extends ConvenienceRenderer { } /* Emit includes */ - if (includes.size !== 0) { + if (includes.size > 0) { includes.forEach((_rec: IncludeRecord, name: string) => { name = name.concat(".h"); if (name !== filename) { diff --git a/packages/quicktype-core/src/language/CPlusPlus/CPlusPlusRenderer.ts b/packages/quicktype-core/src/language/CPlusPlus/CPlusPlusRenderer.ts index dc98805a28..289d2652ae 100644 --- a/packages/quicktype-core/src/language/CPlusPlus/CPlusPlusRenderer.ts +++ b/packages/quicktype-core/src/language/CPlusPlus/CPlusPlusRenderer.ts @@ -656,7 +656,7 @@ export class CPlusPlusRenderer extends ConvenienceRenderer { const typeList: Sourcelike = []; for (const t of nonNulls) { - if (typeList.length !== 0) { + if (typeList.length > 0) { typeList.push(", "); } @@ -3086,7 +3086,7 @@ export class CPlusPlusRenderer extends ConvenienceRenderer { ); } - if (includes.size !== 0) { + if (includes.size > 0) { let numForwards = 0; let numIncludes = 0; includes.forEach((rec: IncludeRecord, name: string) => { diff --git a/packages/quicktype-core/src/language/Elixir/ElixirRenderer.ts b/packages/quicktype-core/src/language/Elixir/ElixirRenderer.ts index 340065991e..6192e64f8e 100644 --- a/packages/quicktype-core/src/language/Elixir/ElixirRenderer.ts +++ b/packages/quicktype-core/src/language/Elixir/ElixirRenderer.ts @@ -798,7 +798,10 @@ export class ElixirRenderer extends ConvenienceRenderer { ]); } }); - if (structDescription.length || attributeDescriptions.length) { + if ( + structDescription.length > 0 || + attributeDescriptions.length > 0 + ) { this.emitDescription([ ...structDescription, ...attributeDescriptions, @@ -816,7 +819,7 @@ export class ElixirRenderer extends ConvenienceRenderer { } } }); - if (requiredAttributes.length) { + if (requiredAttributes.length > 0) { this.emitLine(["@enforce_keys [", requiredAttributes, "]"]); } @@ -1152,7 +1155,7 @@ end`); () => { const description = this.descriptionForType(topLevel) ?? []; - if (description.length) { + if (description.length > 0) { this.emitDescription([...description]); this.ensureBlankLine(); } diff --git a/packages/quicktype-core/src/language/Java/JavaRenderer.ts b/packages/quicktype-core/src/language/Java/JavaRenderer.ts index d596083389..60ba5e394b 100644 --- a/packages/quicktype-core/src/language/Java/JavaRenderer.ts +++ b/packages/quicktype-core/src/language/Java/JavaRenderer.ts @@ -524,13 +524,13 @@ export class JavaRenderer extends ConvenienceRenderer { p, true, ); - if (getter.length !== 0) { + if (getter.length > 0) { this.emitLine( `@lombok.Getter(onMethod_ = {${getter.join(", ")}})`, ); } - if (setter.length !== 0) { + if (setter.length > 0) { this.emitLine( `@lombok.Setter(onMethod_ = {${setter.join(", ")}})`, ); diff --git a/packages/quicktype-graphql-input/src/index.ts b/packages/quicktype-graphql-input/src/index.ts index 818ec73f93..4d53afeaa0 100644 --- a/packages/quicktype-graphql-input/src/index.ts +++ b/packages/quicktype-graphql-input/src/index.ts @@ -217,7 +217,7 @@ class GQLQuery { } } - messageAssert(queries.length >= 1, "GraphQLNoQueriesDefined", {}); + messageAssert(queries.length > 0, "GraphQLNoQueriesDefined", {}); this.queries = queries; } diff --git a/test/test.ts b/test/test.ts index 83b1f83164..dd9a1933a5 100755 --- a/test/test.ts +++ b/test/test.ts @@ -6,6 +6,7 @@ import { type Fixture, allFixtures } from "./fixtures"; import { inParallel } from "./lib/multicore"; import { type Sample, execAsync } from "./utils"; +// biome-ignore lint/style/useExplicitLengthCheck: length is used as a value here, not a boolean const CPUs = Number.parseInt(process.env.CPUs || "0", 10) || os.cpus().length; ////////////////////////////////////// From 61a830bac5140293a9f6c888cb316bdd0afa016b Mon Sep 17 00:00:00 2001 From: Mark Probst Date: Mon, 13 Jul 2026 10:36:46 -0400 Subject: [PATCH 41/68] Biome: enable noMultiAssign and fix violations Nine violations: chained assignments (a = b = value) split into separate statements with identical evaluation order. Co-Authored-By: Claude Fable 5 --- biome.json | 3 +- packages/quicktype-core/src/MarkovChain.ts | 3 +- packages/quicktype-core/src/Renderer.ts | 3 +- .../src/input/JSONSchemaInput.ts | 3 +- .../quicktype-core/src/support/Strings.ts | 36 +++++++++---------- 5 files changed, 26 insertions(+), 22 deletions(-) diff --git a/biome.json b/biome.json index 9e249ee23f..dd6d876254 100644 --- a/biome.json +++ b/biome.json @@ -33,7 +33,8 @@ "useObjectSpread": "on", "noYodaExpression": "on", "noSubstr": "on", - "useExplicitLengthCheck": "on" + "useExplicitLengthCheck": "on", + "noMultiAssign": "on" }, "suspicious": { "noTemplateCurlyInString": "off" diff --git a/packages/quicktype-core/src/MarkovChain.ts b/packages/quicktype-core/src/MarkovChain.ts index ce9addf0cf..91c33a0d6d 100644 --- a/packages/quicktype-core/src/MarkovChain.ts +++ b/packages/quicktype-core/src/MarkovChain.ts @@ -68,7 +68,8 @@ function increment(t: Trie, seq: string, i: number): void { let st = t.arr[first]; if (st === null) { - t.arr[first] = st = makeTrie(); + st = makeTrie(); + t.arr[first] = st; } if (typeof st !== "object") { diff --git a/packages/quicktype-core/src/Renderer.ts b/packages/quicktype-core/src/Renderer.ts index ca384d0016..f1ad5dd4f5 100644 --- a/packages/quicktype-core/src/Renderer.ts +++ b/packages/quicktype-core/src/Renderer.ts @@ -77,7 +77,8 @@ class EmitContext { private _preventBlankLine: boolean; public constructor() { - this._currentEmitTarget = this._emitted = []; + this._emitted = []; + this._currentEmitTarget = this._emitted; this._numBlankLinesNeeded = 0; this._preventBlankLine = true; // no blank lines at start of file } diff --git a/packages/quicktype-core/src/input/JSONSchemaInput.ts b/packages/quicktype-core/src/input/JSONSchemaInput.ts index cc4202ed68..2f224bf662 100644 --- a/packages/quicktype-core/src/input/JSONSchemaInput.ts +++ b/packages/quicktype-core/src/input/JSONSchemaInput.ts @@ -1538,10 +1538,11 @@ export class JSONSchemaInput implements Input { return panic("Must have a schema store to process JSON Schema"); } } else { - maybeSchemaStore = this._schemaStore = new InputJSONSchemaStore( + this._schemaStore = new InputJSONSchemaStore( this._schemaInputs, maybeSchemaStore, ); + maybeSchemaStore = this._schemaStore; } const schemaStore = maybeSchemaStore; diff --git a/packages/quicktype-core/src/support/Strings.ts b/packages/quicktype-core/src/support/Strings.ts index 2ccfebecf7..8d0bb0e594 100644 --- a/packages/quicktype-core/src/support/Strings.ts +++ b/packages/quicktype-core/src/support/Strings.ts @@ -609,7 +609,8 @@ export function makeNameStyle( restWordStyle = firstUpperWordStyle; restAcronymStyle = allUpperWordStyle; } else { - restWordStyle = restAcronymStyle = firstUpperWordStyle; + restAcronymStyle = firstUpperWordStyle; + restWordStyle = restAcronymStyle; } } else { separator = "_"; @@ -618,32 +619,31 @@ export function makeNameStyle( switch (namingStyle) { case "pascal": case "pascal-upper-acronyms": - firstWordStyle = firstWordAcronymStyle = firstUpperWordStyle; + firstWordAcronymStyle = firstUpperWordStyle; + firstWordStyle = firstWordAcronymStyle; break; case "camel": case "camel-upper-acronyms": - firstWordStyle = firstWordAcronymStyle = allLowerWordStyle; + firstWordAcronymStyle = allLowerWordStyle; + firstWordStyle = firstWordAcronymStyle; break; case "underscore": - firstWordStyle = - restWordStyle = - firstWordAcronymStyle = - restAcronymStyle = - allLowerWordStyle; + firstWordStyle = allLowerWordStyle; + restWordStyle = allLowerWordStyle; + firstWordAcronymStyle = allLowerWordStyle; + restAcronymStyle = allLowerWordStyle; break; case "upper-underscore": - firstWordStyle = - restWordStyle = - firstWordAcronymStyle = - restAcronymStyle = - allUpperWordStyle; + firstWordStyle = allUpperWordStyle; + restWordStyle = allUpperWordStyle; + firstWordAcronymStyle = allUpperWordStyle; + restAcronymStyle = allUpperWordStyle; break; case "original": - firstWordStyle = - restWordStyle = - firstWordAcronymStyle = - restAcronymStyle = - originalWord; + firstWordStyle = originalWord; + restWordStyle = originalWord; + firstWordAcronymStyle = originalWord; + restAcronymStyle = originalWord; break; default: return assertNever(namingStyle); From f01f8b270246d4f251d26296aeea128e93c36d5e Mon Sep 17 00:00:00 2001 From: Mark Probst Date: Mon, 13 Jul 2026 10:37:22 -0400 Subject: [PATCH 42/68] Biome: enable useConsistentObjectDefinitions and fix violations Six violations: redundant "key: key" object members converted to shorthand, matching the prevailing style. Co-Authored-By: Claude Fable 5 --- biome.json | 3 ++- packages/quicktype-core/src/Source.ts | 2 +- packages/quicktype-vscode/src/extension.ts | 2 +- src/GraphQLIntrospection.ts | 2 +- src/index.ts | 6 +++--- 5 files changed, 8 insertions(+), 7 deletions(-) diff --git a/biome.json b/biome.json index dd6d876254..239ad22087 100644 --- a/biome.json +++ b/biome.json @@ -34,7 +34,8 @@ "noYodaExpression": "on", "noSubstr": "on", "useExplicitLengthCheck": "on", - "noMultiAssign": "on" + "noMultiAssign": "on", + "useConsistentObjectDefinitions": "on" }, "suspicious": { "noTemplateCurlyInString": "off" diff --git a/packages/quicktype-core/src/Source.ts b/packages/quicktype-core/src/Source.ts index b290ee4ce0..df71824802 100644 --- a/packages/quicktype-core/src/Source.ts +++ b/packages/quicktype-core/src/Source.ts @@ -307,7 +307,7 @@ export function serializeRenderResult( serializeToStringArray(rootSource); finishLine(); - return { lines, annotations: annotations }; + return { lines, annotations }; } export interface MultiWord { diff --git a/packages/quicktype-vscode/src/extension.ts b/packages/quicktype-vscode/src/extension.ts index dd967a5b2f..9cef6841bd 100644 --- a/packages/quicktype-vscode/src/extension.ts +++ b/packages/quicktype-vscode/src/extension.ts @@ -147,7 +147,7 @@ async function runQuicktype( } const options: Partial = { - lang: lang, + lang, inputData, rendererOptions, indentation, diff --git a/src/GraphQLIntrospection.ts b/src/GraphQLIntrospection.ts index 1c60d07a7d..68ca8a39c5 100644 --- a/src/GraphQLIntrospection.ts +++ b/src/GraphQLIntrospection.ts @@ -40,7 +40,7 @@ export async function introspectServer( try { const response = await globalThis.fetch(url, { method, - headers: headers, + headers, body: JSON.stringify({ query: getIntrospectionQuery() }), }); diff --git a/src/index.ts b/src/index.ts index d7533f0869..982adf627f 100644 --- a/src/index.ts +++ b/src/index.ts @@ -242,7 +242,7 @@ async function samplesFromDirectory( schemaSources.length + graphQLSources.length > 0 ) { return messageError("DriverCannotMixJSONWithOtherSamples", { - dir: dir, + dir, }); } @@ -253,7 +253,7 @@ async function samplesFromDirectory( oneUnlessEmpty(schemaSources) + oneUnlessEmpty(graphQLSources) > 1 ) { - return messageError("DriverCannotMixNonJSONInputs", { dir: dir }); + return messageError("DriverCannotMixNonJSONInputs", { dir }); } if (jsonSamples.length > 0) { @@ -352,7 +352,7 @@ function inferCLIOptions( const options: CLIOptions = { src: opts.src ?? [], srcUrls: opts.srcUrls, - srcLang: srcLang, + srcLang, lang: language.name as LanguageName, topLevel: opts.topLevel ?? inferTopLevel(opts), noRender: !!opts.noRender, From fb746dd922abe2ac299082a630b6a3afededbeed Mon Sep 17 00:00:00 2001 From: Mark Probst Date: Mon, 13 Jul 2026 10:38:18 -0400 Subject: [PATCH 43/68] Biome: enable useForOf and fix violations Two violations, both index-only loops (previously waived with eslint prefer-for-of disables) converted to for-of. The UnifyClasses loop mutates the iterated tuple through the element reference, which is identical to the old index write. Co-Authored-By: Claude Fable 5 --- biome.json | 3 ++- packages/quicktype-core/src/UnifyClasses.ts | 8 +++----- .../src/language/TypeScriptZod/TypeScriptZodRenderer.ts | 5 +---- 3 files changed, 6 insertions(+), 10 deletions(-) diff --git a/biome.json b/biome.json index 239ad22087..4a1d4cb3f0 100644 --- a/biome.json +++ b/biome.json @@ -35,7 +35,8 @@ "noSubstr": "on", "useExplicitLengthCheck": "on", "noMultiAssign": "on", - "useConsistentObjectDefinitions": "on" + "useConsistentObjectDefinitions": "on", + "useForOf": "on" }, "suspicious": { "noTemplateCurlyInString": "off" diff --git a/packages/quicktype-core/src/UnifyClasses.ts b/packages/quicktype-core/src/UnifyClasses.ts index 563a92c493..7b2a9529a5 100644 --- a/packages/quicktype-core/src/UnifyClasses.ts +++ b/packages/quicktype-core/src/UnifyClasses.ts @@ -49,10 +49,8 @@ function getCliqueProperties( } } - // FIXME: refactor this - // eslint-disable-next-line @typescript-eslint/prefer-for-of - for (let i = 0; i < properties.length; i++) { - let [name, types, isOptional] = properties[i]; + for (const property of properties) { + let [name, types, isOptional] = property; const maybeProperty = o.getProperties().get(name); if (maybeProperty === undefined) { isOptional = true; @@ -67,7 +65,7 @@ function getCliqueProperties( types.add(maybeProperty.type); } - properties[i][2] = isOptional; + property[2] = isOptional; } } diff --git a/packages/quicktype-core/src/language/TypeScriptZod/TypeScriptZodRenderer.ts b/packages/quicktype-core/src/language/TypeScriptZod/TypeScriptZodRenderer.ts index 3d5b179840..6406101476 100644 --- a/packages/quicktype-core/src/language/TypeScriptZod/TypeScriptZodRenderer.ts +++ b/packages/quicktype-core/src/language/TypeScriptZod/TypeScriptZodRenderer.ts @@ -468,10 +468,7 @@ export class TypeScriptZodRenderer extends ConvenienceRenderer { // find this childs's ordinal, if it has already been added // faster to go through what we've defined so far than all definitions - // FIXME: refactor this - // eslint-disable-next-line @typescript-eslint/prefer-for-of - for (let j = 0; j < order.length; j++) { - const childIndex = order[j]; + for (const childIndex of order) { if (mapTypeRef[childIndex] === childRef) { found = true; break; From 30c91f6d6cbe1525f5fd7bb11b296059d86a98f7 Mon Sep 17 00:00:00 2001 From: Mark Probst Date: Mon, 13 Jul 2026 10:39:11 -0400 Subject: [PATCH 44/68] Biome: enable noUnusedTemplateLiteral and fix violations Two violations: template literals without interpolation converted to plain string literals. Co-Authored-By: Claude Fable 5 --- test/languages.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/languages.ts b/test/languages.ts index e346160ac6..5d971b30ca 100644 --- a/test/languages.ts +++ b/test/languages.ts @@ -700,7 +700,7 @@ export const ElmLanguage: Language = { export const SwiftLanguage: Language = { name: "swift", base: "test/fixtures/swift", - compileCommand: `swiftc -o quicktype main.swift quicktype.swift`, + compileCommand: "swiftc -o quicktype main.swift quicktype.swift", runCommand(sample: string) { return `./quicktype "${sample}"`; }, @@ -779,7 +779,7 @@ export const SwiftLanguage: Language = { export const ObjectiveCLanguage: Language = { name: "objective-c", base: "test/fixtures/objective-c", - compileCommand: `clang -Werror -framework Foundation *.m -o test`, + compileCommand: "clang -Werror -framework Foundation *.m -o test", runCommand(sample: string) { return `cp "${sample}" sample.json && ./test sample.json`; }, From 062c38f1360655e278aedf6a7b81c37f79ad63a8 Mon Sep 17 00:00:00 2001 From: Mark Probst Date: Mon, 13 Jul 2026 10:39:11 -0400 Subject: [PATCH 45/68] Biome: enable useShorthandAssign and fix violations One violation: "p = p * cp" changed to "p *= cp". Co-Authored-By: Claude Fable 5 --- packages/quicktype-core/src/MarkovChain.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/quicktype-core/src/MarkovChain.ts b/packages/quicktype-core/src/MarkovChain.ts index 91c33a0d6d..885d12b204 100644 --- a/packages/quicktype-core/src/MarkovChain.ts +++ b/packages/quicktype-core/src/MarkovChain.ts @@ -116,7 +116,7 @@ export function evaluateFull( } scores.push(cp); - p = p * cp; + p *= cp; } return [p ** (1 / (word.length - depth + 1)), scores]; From 3cd2a5d29cbf988f11945252dfff22b29a5fb71a Mon Sep 17 00:00:00 2001 From: Mark Probst Date: Mon, 13 Jul 2026 10:39:11 -0400 Subject: [PATCH 46/68] Biome: enable noInferrableTypes and fix violations One violation: a redundant ": boolean" annotation on an initialized variable removed. Co-Authored-By: Claude Fable 5 --- biome.json | 5 ++++- .../quicktype-core/src/language/CSharp/CSharpRenderer.ts | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/biome.json b/biome.json index 4a1d4cb3f0..82ef5c305b 100644 --- a/biome.json +++ b/biome.json @@ -36,7 +36,10 @@ "useExplicitLengthCheck": "on", "noMultiAssign": "on", "useConsistentObjectDefinitions": "on", - "useForOf": "on" + "useForOf": "on", + "noUnusedTemplateLiteral": "on", + "useShorthandAssign": "on", + "noInferrableTypes": "on" }, "suspicious": { "noTemplateCurlyInString": "off" diff --git a/packages/quicktype-core/src/language/CSharp/CSharpRenderer.ts b/packages/quicktype-core/src/language/CSharp/CSharpRenderer.ts index eae2af60c7..60f4d30333 100644 --- a/packages/quicktype-core/src/language/CSharp/CSharpRenderer.ts +++ b/packages/quicktype-core/src/language/CSharp/CSharpRenderer.ts @@ -529,7 +529,7 @@ export class CSharpRenderer extends ConvenienceRenderer { } protected emitDependencyUsings(): void { - let genericEmited: boolean = false; + let genericEmited = false; const ensureGenericOnce = () => { if (!genericEmited) { this.emitUsing("System.Collections.Generic"); From bb34cc2c6035f9c19e64641857bab47aa03b2045 Mon Sep 17 00:00:00 2001 From: Mark Probst Date: Mon, 13 Jul 2026 10:40:52 -0400 Subject: [PATCH 47/68] Biome: enable useDefaultParameterLast and fix violations Two violations in the Dart renderer: a leading "isNullable = false" default parameter followed by required parameters. A leading default can never be omitted, and every call site passes the argument explicitly, so it is now a required boolean parameter. Also drops the eslint-disable comments that waived the equivalent ESLint rule. Co-Authored-By: Claude Fable 5 --- biome.json | 3 ++- packages/quicktype-core/src/language/Dart/DartRenderer.ts | 6 ++---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/biome.json b/biome.json index 82ef5c305b..4bdf0aaf56 100644 --- a/biome.json +++ b/biome.json @@ -39,7 +39,8 @@ "useForOf": "on", "noUnusedTemplateLiteral": "on", "useShorthandAssign": "on", - "noInferrableTypes": "on" + "noInferrableTypes": "on", + "useDefaultParameterLast": "on" }, "suspicious": { "noTemplateCurlyInString": "off" diff --git a/packages/quicktype-core/src/language/Dart/DartRenderer.ts b/packages/quicktype-core/src/language/Dart/DartRenderer.ts index b158572c3b..203a15693d 100644 --- a/packages/quicktype-core/src/language/Dart/DartRenderer.ts +++ b/packages/quicktype-core/src/language/Dart/DartRenderer.ts @@ -419,9 +419,8 @@ export class DartRenderer extends ConvenienceRenderer { // If the first time is the unionType type, after nullableFromUnion conversion, // the isNullable property will become false, which is obviously wrong, // so add isNullable property - // eslint-disable-next-line @typescript-eslint/default-param-last protected fromDynamicExpression( - isNullable = false, + isNullable: boolean, t: Type, ...dynamic: Sourcelike[] ): Sourcelike { @@ -517,9 +516,8 @@ export class DartRenderer extends ConvenienceRenderer { // If the first time is the unionType type, after nullableFromUnion conversion, // the isNullable property will become false, which is obviously wrong, // so add isNullable property - // eslint-disable-next-line @typescript-eslint/default-param-last protected toDynamicExpression( - isNullable = false, + isNullable: boolean, t: Type, ...dynamic: Sourcelike[] ): Sourcelike { From 53987266ed16086d875d43cc3794ecd8ca37b078 Mon Sep 17 00:00:00 2001 From: Mark Probst Date: Mon, 13 Jul 2026 10:42:02 -0400 Subject: [PATCH 48/68] Biome: enable useConsistentMethodSignatures and fix violations Two violations in the multicore test helper: method-style interface signatures converted to property-style arrow signatures, which also get strict (non-bivariant) parameter checking. Co-Authored-By: Claude Fable 5 --- biome.json | 3 ++- test/lib/multicore.ts | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/biome.json b/biome.json index 4bdf0aaf56..efb80d750f 100644 --- a/biome.json +++ b/biome.json @@ -40,7 +40,8 @@ "noUnusedTemplateLiteral": "on", "useShorthandAssign": "on", "noInferrableTypes": "on", - "useDefaultParameterLast": "on" + "useDefaultParameterLast": "on", + "useConsistentMethodSignatures": "on" }, "suspicious": { "noTemplateCurlyInString": "off" diff --git a/test/lib/multicore.ts b/test/lib/multicore.ts index 4b304503da..9bf607675e 100644 --- a/test/lib/multicore.ts +++ b/test/lib/multicore.ts @@ -7,8 +7,8 @@ const WORKERS = ["👷🏻", "👷🏼", "👷🏽", "👷🏾", "👷🏿"]; export interface ParallelArgs { queue: Item[]; workers: number; - setup(): Promise; - map(item: Item, index: number): Promise; + setup: () => Promise; + map: (item: Item, index: number) => Promise; } function randomPick(arr: T[]): T { From 2d76dec5488e3fb417ac3e7b8d93252c1aa61bbb Mon Sep 17 00:00:00 2001 From: Mark Probst Date: Mon, 13 Jul 2026 10:43:36 -0400 Subject: [PATCH 49/68] Biome: enable useUnifiedTypeSignatures and fix violations One violation: the compose() overload pair in the Python renderer (previously waived with an eslint-disable) collapsed into the single union-typed signature the implementation already had. Co-Authored-By: Claude Fable 5 --- .../src/language/Python/JSONPythonRenderer.ts | 7 ------- 1 file changed, 7 deletions(-) diff --git a/packages/quicktype-core/src/language/Python/JSONPythonRenderer.ts b/packages/quicktype-core/src/language/Python/JSONPythonRenderer.ts index f4d0328362..59271b599c 100644 --- a/packages/quicktype-core/src/language/Python/JSONPythonRenderer.ts +++ b/packages/quicktype-core/src/language/Python/JSONPythonRenderer.ts @@ -66,13 +66,6 @@ export interface ValueOrLambda { // // * If `input` is a value, the result is `f(input)`. // * If `input` is a lambda, the result is `lambda x: f(input(x))` -function compose( - input: ValueOrLambda, - f: (arg: Sourcelike) => Sourcelike, -): ValueOrLambda; -// FIXME: refactor this -// eslint-disable-next-line @typescript-eslint/unified-signatures -function compose(input: ValueOrLambda, f: ValueOrLambda): ValueOrLambda; function compose( input: ValueOrLambda, f: ValueOrLambda | ((arg: Sourcelike) => Sourcelike), From 7d148fc1d7be3fa5b72a424aca2e39f2e5b8cfb0 Mon Sep 17 00:00:00 2001 From: Mark Probst Date: Mon, 13 Jul 2026 10:43:36 -0400 Subject: [PATCH 50/68] Biome: enable noNamespace and fix violations One violation: an ambient "declare namespace Math" in the deepEquals test helper that added Math.fround for an ancient TypeScript lib. Math.fround has been in the standard lib since ES2015, so the declaration is simply removed. Co-Authored-By: Claude Fable 5 --- test/lib/deepEquals.ts | 5 ----- 1 file changed, 5 deletions(-) diff --git a/test/lib/deepEquals.ts b/test/lib/deepEquals.ts index 6dd1338bc9..2db4aa051c 100644 --- a/test/lib/deepEquals.ts +++ b/test/lib/deepEquals.ts @@ -6,11 +6,6 @@ function pathToString(path: string[]): string { return `.${path.join(".")}`; } -declare namespace Math { - // TypeScript cannot find this function - function fround(n: number): number; -} - function tryParseMoment(s: string): [Moment | undefined, boolean] { let m = moment(s); if (m.isValid()) return [m, false]; From c91f43440a37aed75768eefe68904ae7f2e738ab Mon Sep 17 00:00:00 2001 From: Mark Probst Date: Mon, 13 Jul 2026 10:43:36 -0400 Subject: [PATCH 51/68] Biome: enable useNodeAssertStrict and fix violations One violation: "strict as assert" from node:assert now imports from node:assert/strict, which is the identical strict assert object. Co-Authored-By: Claude Fable 5 --- biome.json | 5 ++++- test/release-version.ts | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/biome.json b/biome.json index efb80d750f..dfb3808b48 100644 --- a/biome.json +++ b/biome.json @@ -41,7 +41,10 @@ "useShorthandAssign": "on", "noInferrableTypes": "on", "useDefaultParameterLast": "on", - "useConsistentMethodSignatures": "on" + "useConsistentMethodSignatures": "on", + "useUnifiedTypeSignatures": "on", + "noNamespace": "on", + "useNodeAssertStrict": "on" }, "suspicious": { "noTemplateCurlyInString": "off" diff --git a/test/release-version.ts b/test/release-version.ts index c2d6637200..33594fe6d1 100644 --- a/test/release-version.ts +++ b/test/release-version.ts @@ -1,4 +1,4 @@ -import { strict as assert } from "node:assert"; +import { strict as assert } from "node:assert/strict"; import { mkdirSync, mkdtempSync, From 426a4d824485601706baddd042945df3ad6efc4f Mon Sep 17 00:00:00 2001 From: Mark Probst Date: Mon, 13 Jul 2026 10:44:17 -0400 Subject: [PATCH 52/68] Biome: enable useReadonlyClassProperties and fix violations Thirteen violations: private class properties that are never reassigned marked readonly. Type-level only; verified by tsc. Co-Authored-By: Claude Fable 5 --- biome.json | 3 ++- packages/quicktype-core/src/Type/TypeGraph.ts | 2 +- packages/quicktype-core/src/attributes/Constraints.ts | 4 ++-- packages/quicktype-core/src/input/CompressedJSON.ts | 10 +++++----- packages/quicktype-core/src/input/JSONSchemaInput.ts | 2 +- .../quicktype-core/src/language/CJSON/CJSONRenderer.ts | 2 +- .../src/language/Scala3/CirceRenderer.ts | 2 +- .../TypeScriptEffectSchemaRenderer.ts | 2 +- packages/quicktype-core/src/support/Chance.ts | 2 +- 9 files changed, 15 insertions(+), 14 deletions(-) diff --git a/biome.json b/biome.json index dfb3808b48..98ee125e21 100644 --- a/biome.json +++ b/biome.json @@ -44,7 +44,8 @@ "useConsistentMethodSignatures": "on", "useUnifiedTypeSignatures": "on", "noNamespace": "on", - "useNodeAssertStrict": "on" + "useNodeAssertStrict": "on", + "useReadonlyClassProperties": "on" }, "suspicious": { "noTemplateCurlyInString": "off" diff --git a/packages/quicktype-core/src/Type/TypeGraph.ts b/packages/quicktype-core/src/Type/TypeGraph.ts index 905b434a68..959808cda7 100644 --- a/packages/quicktype-core/src/Type/TypeGraph.ts +++ b/packages/quicktype-core/src/Type/TypeGraph.ts @@ -39,7 +39,7 @@ export class TypeAttributeStore { public constructor( private readonly _typeGraph: TypeGraph, - private _values: Array, + private readonly _values: Array, ) {} private getTypeIndex(t: Type): number { diff --git a/packages/quicktype-core/src/attributes/Constraints.ts b/packages/quicktype-core/src/attributes/Constraints.ts index a4c11a4561..4ef6561866 100644 --- a/packages/quicktype-core/src/attributes/Constraints.ts +++ b/packages/quicktype-core/src/attributes/Constraints.ts @@ -34,8 +34,8 @@ export class MinMaxConstraintTypeAttributeKind extends TypeAttributeKind, - private _minSchemaProperty: string, - private _maxSchemaProperty: string, + private readonly _minSchemaProperty: string, + private readonly _maxSchemaProperty: string, ) { super(name); } diff --git a/packages/quicktype-core/src/input/CompressedJSON.ts b/packages/quicktype-core/src/input/CompressedJSON.ts index 2afe56c832..39748a97c9 100644 --- a/packages/quicktype-core/src/input/CompressedJSON.ts +++ b/packages/quicktype-core/src/input/CompressedJSON.ts @@ -56,15 +56,15 @@ export abstract class CompressedJSON { private _ctx: Context | undefined; - private _contextStack: Context[] = []; + private readonly _contextStack: Context[] = []; - private _strings: string[] = []; + private readonly _strings: string[] = []; - private _stringIndexes: { [str: string]: number } = {}; + private readonly _stringIndexes: { [str: string]: number } = {}; - private _objects: Value[][] = []; + private readonly _objects: Value[][] = []; - private _arrays: Value[][] = []; + private readonly _arrays: Value[][] = []; public constructor( public readonly dateTimeRecognizer: DateTimeRecognizer, diff --git a/packages/quicktype-core/src/input/JSONSchemaInput.ts b/packages/quicktype-core/src/input/JSONSchemaInput.ts index 2f224bf662..b3b3f4a951 100644 --- a/packages/quicktype-core/src/input/JSONSchemaInput.ts +++ b/packages/quicktype-core/src/input/JSONSchemaInput.ts @@ -1496,7 +1496,7 @@ export class JSONSchemaInput implements Input { private readonly _schemaInputs: Map = new Map(); - private _schemaSources: Array<[URI, JSONSchemaSourceData]> = []; + private readonly _schemaSources: Array<[URI, JSONSchemaSourceData]> = []; private readonly _topLevels: Map = new Map(); diff --git a/packages/quicktype-core/src/language/CJSON/CJSONRenderer.ts b/packages/quicktype-core/src/language/CJSON/CJSONRenderer.ts index d2d0be8af9..c1f3544657 100644 --- a/packages/quicktype-core/src/language/CJSON/CJSONRenderer.ts +++ b/packages/quicktype-core/src/language/CJSON/CJSONRenderer.ts @@ -73,7 +73,7 @@ export class CJSONRenderer extends ConvenienceRenderer { protected readonly enumeratorNamingStyle: NamingStyle; /* Enum naming style */ - private includes: string[]; + private readonly includes: string[]; /** * Constructor diff --git a/packages/quicktype-core/src/language/Scala3/CirceRenderer.ts b/packages/quicktype-core/src/language/Scala3/CirceRenderer.ts index 47370e664b..5f513c0c5f 100644 --- a/packages/quicktype-core/src/language/Scala3/CirceRenderer.ts +++ b/packages/quicktype-core/src/language/Scala3/CirceRenderer.ts @@ -18,7 +18,7 @@ import { Scala3Renderer } from "./Scala3Renderer.js"; import { wrapOption } from "./utils.js"; export class CirceRenderer extends Scala3Renderer { - private seenUnionTypes: string[] = []; + private readonly seenUnionTypes: string[] = []; protected circeEncoderForType( t: Type, diff --git a/packages/quicktype-core/src/language/TypeScriptEffectSchema/TypeScriptEffectSchemaRenderer.ts b/packages/quicktype-core/src/language/TypeScriptEffectSchema/TypeScriptEffectSchemaRenderer.ts index 7590bb37f4..db2397621c 100644 --- a/packages/quicktype-core/src/language/TypeScriptEffectSchema/TypeScriptEffectSchemaRenderer.ts +++ b/packages/quicktype-core/src/language/TypeScriptEffectSchema/TypeScriptEffectSchemaRenderer.ts @@ -32,7 +32,7 @@ import { legalizeName } from "../JavaScript/utils.js"; import type { typeScriptEffectSchemaOptions } from "./language.js"; export class TypeScriptEffectSchemaRenderer extends ConvenienceRenderer { - private emittedObjects = new Set(); + private readonly emittedObjects = new Set(); public constructor( targetLanguage: TargetLanguage, diff --git a/packages/quicktype-core/src/support/Chance.ts b/packages/quicktype-core/src/support/Chance.ts index 6b289ef59a..fabbbcc072 100644 --- a/packages/quicktype-core/src/support/Chance.ts +++ b/packages/quicktype-core/src/support/Chance.ts @@ -45,7 +45,7 @@ class MersenneTwister { private readonly LOWER_MASK: number; - private mt: number[]; + private readonly mt: number[]; private mti: number; From 46c7a0711c38f0b4242bece1b58a0e87a02f0751 Mon Sep 17 00:00:00 2001 From: Mark Probst Date: Mon, 13 Jul 2026 10:45:16 -0400 Subject: [PATCH 53/68] Biome: enable noEqualsToNull and fix violations One violation: "nullableFromUnion(...) != null" changed to "!== null". The function returns Type | null (never undefined), so the loose comparison was equivalent. Co-Authored-By: Claude Fable 5 --- biome.json | 3 ++- packages/quicktype-core/src/language/Python/PythonRenderer.ts | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/biome.json b/biome.json index 98ee125e21..7ac51f3c02 100644 --- a/biome.json +++ b/biome.json @@ -48,7 +48,8 @@ "useReadonlyClassProperties": "on" }, "suspicious": { - "noTemplateCurlyInString": "off" + "noTemplateCurlyInString": "off", + "noEqualsToNull": "on" } } }, diff --git a/packages/quicktype-core/src/language/Python/PythonRenderer.ts b/packages/quicktype-core/src/language/Python/PythonRenderer.ts index c2fdda6910..09072ca05f 100644 --- a/packages/quicktype-core/src/language/Python/PythonRenderer.ts +++ b/packages/quicktype-core/src/language/Python/PythonRenderer.ts @@ -323,7 +323,7 @@ export class PythonRenderer extends ConvenienceRenderer { ) { return mapSortBy(properties, (p: ClassProperty) => { return (p.type instanceof UnionType && - nullableFromUnion(p.type) != null) || + nullableFromUnion(p.type) !== null) || p.isOptional ? 1 : 0; From fa1e5a347264e30d612d8f32555d336488be7e6e Mon Sep 17 00:00:00 2001 From: Mark Probst Date: Mon, 13 Jul 2026 10:46:37 -0400 Subject: [PATCH 54/68] Biome: enable noUnusedExpressions and fix violations Two violations, both deliberate compile-time "satisfies" type checks; suppressed with explanations so the rule can guard against genuinely dead expressions. Co-Authored-By: Claude Fable 5 --- biome.json | 3 ++- packages/quicktype-core/src/language/All.ts | 1 + packages/quicktype-core/src/language/Rust/utils.ts | 1 + 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/biome.json b/biome.json index 7ac51f3c02..6343a52986 100644 --- a/biome.json +++ b/biome.json @@ -49,7 +49,8 @@ }, "suspicious": { "noTemplateCurlyInString": "off", - "noEqualsToNull": "on" + "noEqualsToNull": "on", + "noUnusedExpressions": "on" } } }, diff --git a/packages/quicktype-core/src/language/All.ts b/packages/quicktype-core/src/language/All.ts index 63856092a8..94359ae74a 100644 --- a/packages/quicktype-core/src/language/All.ts +++ b/packages/quicktype-core/src/language/All.ts @@ -65,6 +65,7 @@ export const all = [ new TypeScriptZodTargetLanguage(), ] as const; +// biome-ignore lint/suspicious/noUnusedExpressions: compile-time type check via satisfies all satisfies readonly TargetLanguage[]; /** diff --git a/packages/quicktype-core/src/language/Rust/utils.ts b/packages/quicktype-core/src/language/Rust/utils.ts index b4dc83e24c..4842ce6818 100644 --- a/packages/quicktype-core/src/language/Rust/utils.ts +++ b/packages/quicktype-core/src/language/Rust/utils.ts @@ -102,6 +102,7 @@ export const namingStyles = { }, } as const; +// biome-ignore lint/suspicious/noUnusedExpressions: compile-time type check via satisfies namingStyles satisfies Record; export type NamingStyleKey = keyof typeof namingStyles; From c527fc81006fcd9bf8657a9f0ce62b8039b2485b Mon Sep 17 00:00:00 2001 From: Mark Probst Date: Mon, 13 Jul 2026 10:47:26 -0400 Subject: [PATCH 55/68] Biome: enable useArraySortCompare and fix violations Three violations, all default-sorts of string arrays (JSON Schema required lists and Java imports) where UTF-16 code unit order is the intended, deterministic order for generated code. Suppressed with explanations; the rule now guards against comparator-less sorts of non-string arrays. Co-Authored-By: Claude Fable 5 --- biome.json | 3 ++- .../src/language/JSONSchema/JSONSchemaRenderer.ts | 1 + packages/quicktype-core/src/language/Java/JavaRenderer.ts | 2 ++ 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/biome.json b/biome.json index 6343a52986..d76f2b8d0b 100644 --- a/biome.json +++ b/biome.json @@ -50,7 +50,8 @@ "suspicious": { "noTemplateCurlyInString": "off", "noEqualsToNull": "on", - "noUnusedExpressions": "on" + "noUnusedExpressions": "on", + "useArraySortCompare": "on" } } }, diff --git a/packages/quicktype-core/src/language/JSONSchema/JSONSchemaRenderer.ts b/packages/quicktype-core/src/language/JSONSchema/JSONSchemaRenderer.ts index 8512135b0f..227a46da75 100644 --- a/packages/quicktype-core/src/language/JSONSchema/JSONSchemaRenderer.ts +++ b/packages/quicktype-core/src/language/JSONSchema/JSONSchemaRenderer.ts @@ -142,6 +142,7 @@ export class JSONSchemaRenderer extends ConvenienceRenderer { } properties = props; + // biome-ignore lint/suspicious/useArraySortCompare: sorting strings; default UTF-16 order is intended required = req.sort(); } diff --git a/packages/quicktype-core/src/language/Java/JavaRenderer.ts b/packages/quicktype-core/src/language/Java/JavaRenderer.ts index 60ba5e394b..e126f10887 100644 --- a/packages/quicktype-core/src/language/Java/JavaRenderer.ts +++ b/packages/quicktype-core/src/language/Java/JavaRenderer.ts @@ -480,6 +480,7 @@ export class JavaRenderer extends ConvenienceRenderer { imports.push(imp); }); }); + // biome-ignore lint/suspicious/useArraySortCompare: sorting strings; default UTF-16 order is intended imports.sort(); return [...new Set(imports)]; } @@ -492,6 +493,7 @@ export class JavaRenderer extends ConvenienceRenderer { imports.push(imp); }); }); + // biome-ignore lint/suspicious/useArraySortCompare: sorting strings; default UTF-16 order is intended imports.sort(); return [...new Set(imports)]; } From 1e870d780a3cd2f39191e1ce4c91bb7971111c67 Mon Sep 17 00:00:00 2001 From: Mark Probst Date: Mon, 13 Jul 2026 10:48:30 -0400 Subject: [PATCH 56/68] Biome: enable noMisplacedAssertion and fix violations Ten violations: nine in test/release-version.ts, a script-style test that runs its node:assert checks at module top level by design (now exempted via a config override), and one expect() in a test helper function, suppressed with an explanation. Co-Authored-By: Claude Fable 5 --- biome.json | 13 ++++++++++++- test/unit/java-acronym-names.test.ts | 1 + 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/biome.json b/biome.json index d76f2b8d0b..ef3fd3d406 100644 --- a/biome.json +++ b/biome.json @@ -51,12 +51,23 @@ "noTemplateCurlyInString": "off", "noEqualsToNull": "on", "noUnusedExpressions": "on", - "useArraySortCompare": "on" + "useArraySortCompare": "on", + "noMisplacedAssertion": "on" } } }, "assist": { "actions": { "source": { "organizeImports": "off" } } }, "overrides": [ + { + "includes": ["test/release-version.ts"], + "linter": { + "rules": { + "suspicious": { + "noMisplacedAssertion": "off" + } + } + } + }, { "includes": ["packages/quicktype-core/src/**"], "linter": { diff --git a/test/unit/java-acronym-names.test.ts b/test/unit/java-acronym-names.test.ts index ff3e2d2372..fcee1fefd0 100644 --- a/test/unit/java-acronym-names.test.ts +++ b/test/unit/java-acronym-names.test.ts @@ -54,6 +54,7 @@ async function javaEnumConstantIdentifier( new RegExp(`case (\\w+): return "${enumValue}";`), ); + // biome-ignore lint/suspicious/noMisplacedAssertion: helper is only called from within tests expect(match, `generated Java output:\n${output}`).not.toBeNull(); return match?.[1] ?? ""; } From 8909926869416bb4d4dacda5c8f333d0cd544ab8 Mon Sep 17 00:00:00 2001 From: Mark Probst Date: Mon, 13 Jul 2026 10:50:06 -0400 Subject: [PATCH 57/68] Biome: enable noShadow and fix violations 29 violations: one genuine shadow in JSONSchemaInput (a lambda parameter named "name" shadowing a function-scoped variable, renamed to "key"), and 28 in CJSONRenderer.ts, whose deeply nested emit closures reuse the same parameter names by design; that file is exempted via a config override because bulk-renaming those parameters would be high-risk churn. Co-Authored-By: Claude Fable 5 --- biome.json | 15 ++++++++++++++- .../quicktype-core/src/input/JSONSchemaInput.ts | 2 +- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/biome.json b/biome.json index ef3fd3d406..f1639af644 100644 --- a/biome.json +++ b/biome.json @@ -52,12 +52,25 @@ "noEqualsToNull": "on", "noUnusedExpressions": "on", "useArraySortCompare": "on", - "noMisplacedAssertion": "on" + "noMisplacedAssertion": "on", + "noShadow": "on" } } }, "assist": { "actions": { "source": { "organizeImports": "off" } } }, "overrides": [ + { + "includes": [ + "packages/quicktype-core/src/language/CJSON/CJSONRenderer.ts" + ], + "linter": { + "rules": { + "suspicious": { + "noShadow": "off" + } + } + } + }, { "includes": ["test/release-version.ts"], "linter": { diff --git a/packages/quicktype-core/src/input/JSONSchemaInput.ts b/packages/quicktype-core/src/input/JSONSchemaInput.ts index b3b3f4a951..e9973ba7fc 100644 --- a/packages/quicktype-core/src/input/JSONSchemaInput.ts +++ b/packages/quicktype-core/src/input/JSONSchemaInput.ts @@ -1441,7 +1441,7 @@ async function refsInSchemaForURI( }); } - return mapMap(mapFromObject(schema), (_, name) => ref.push(name)); + return mapMap(mapFromObject(schema), (_, key) => ref.push(key)); } let name: string; From 5ef7d2d92e56593aba1905710a4aff454062b022 Mon Sep 17 00:00:00 2001 From: Mark Probst Date: Mon, 13 Jul 2026 10:51:39 -0400 Subject: [PATCH 58/68] Biome: enable noUndeclaredDependencies and fix violations Two violations. A genuine catch: the quicktype CLI imports wordwrap but only had @types/wordwrap declared, relying on hoisting from quicktype-core; wordwrap is now a declared dependency (lockfile updated, no version changes to existing entries). The vscode import in the extension is provided by the VS Code host at runtime and carries a suppression. Co-Authored-By: Claude Fable 5 --- biome.json | 3 +++ package-lock.json | 3 ++- package.json | 3 ++- packages/quicktype-vscode/src/extension.ts | 1 + 4 files changed, 8 insertions(+), 2 deletions(-) diff --git a/biome.json b/biome.json index f1639af644..9d1efa8563 100644 --- a/biome.json +++ b/biome.json @@ -21,6 +21,9 @@ "enabled": true, "rules": { "preset": "recommended", + "correctness": { + "noUndeclaredDependencies": "on" + }, "complexity": { "noUselessReturn": "on" }, diff --git a/package-lock.json b/package-lock.json index e3f50504ae..96d053ddaf 100644 --- a/package-lock.json +++ b/package-lock.json @@ -29,7 +29,8 @@ "quicktype-typescript-input": "24.0.0", "readable-stream": "^4.5.2", "stream-json": "1.8.0", - "string-to-stream": "^3.0.1" + "string-to-stream": "^3.0.1", + "wordwrap": "^1.0.0" }, "bin": { "quicktype": "dist/index.js" diff --git a/package.json b/package.json index 0e473b43c5..f6835ed426 100644 --- a/package.json +++ b/package.json @@ -45,7 +45,8 @@ "quicktype-typescript-input": "24.0.0", "readable-stream": "^4.5.2", "stream-json": "1.8.0", - "string-to-stream": "^3.0.1" + "string-to-stream": "^3.0.1", + "wordwrap": "^1.0.0" }, "devDependencies": { "@biomejs/biome": "^2.5.3", diff --git a/packages/quicktype-vscode/src/extension.ts b/packages/quicktype-vscode/src/extension.ts index 9cef6841bd..08f5e011d9 100644 --- a/packages/quicktype-vscode/src/extension.ts +++ b/packages/quicktype-vscode/src/extension.ts @@ -15,6 +15,7 @@ import { quicktype, } from "quicktype-core"; import { schemaForTypeScriptSources } from "quicktype-typescript-input"; +// biome-ignore lint/correctness/noUndeclaredDependencies: the vscode module is provided by the VS Code host at runtime import * as vscode from "vscode"; const configurationSection = "quicktype"; From 75711a302093d56a9661f961131fb973d607455e Mon Sep 17 00:00:00 2001 From: Mark Probst Date: Mon, 13 Jul 2026 10:52:33 -0400 Subject: [PATCH 59/68] Biome: enable noGlobalDirnameFilename and fix violations One violation: __dirname in the CommonJS test harness, suppressed with an explanation. The rule now protects quicktype-core's dual CJS/ESM build from accidental __dirname/__filename usage, which would break the ES module leg. Co-Authored-By: Claude Fable 5 --- biome.json | 3 ++- test/fixtures.ts | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/biome.json b/biome.json index 9d1efa8563..8c26d6d6a5 100644 --- a/biome.json +++ b/biome.json @@ -22,7 +22,8 @@ "rules": { "preset": "recommended", "correctness": { - "noUndeclaredDependencies": "on" + "noUndeclaredDependencies": "on", + "noGlobalDirnameFilename": "on" }, "complexity": { "noUselessReturn": "on" diff --git a/test/fixtures.ts b/test/fixtures.ts index bd7c5f5da9..33f9dd1c29 100644 --- a/test/fixtures.ts +++ b/test/fixtures.ts @@ -867,6 +867,7 @@ const commentInjectionNestedCommentSchema = const commentInjectionEnumNestedCommentSchema = "test/inputs/schema/comment-injection-enum-nested-comment.schema"; const treeSitterWasm = (filename: string): string => + // biome-ignore lint/correctness/noGlobalDirnameFilename: the test harness runs as CommonJS path.join(__dirname, "tree-sitter-wasms", filename); const commentInjectionTreeSitterTargets: TreeSitterTarget[] = [ From 46bd87b6c5c0383dc7dca47006a1195ef79184f7 Mon Sep 17 00:00:00 2001 From: Mark Probst Date: Mon, 13 Jul 2026 10:53:28 -0400 Subject: [PATCH 60/68] Biome: enable zero-violation correctness guard rules Enables noUnusedInstantiation and useSingleJsDocAsterisk, which are already clean on the codebase, to guard against future violations. Co-Authored-By: Claude Fable 5 --- biome.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/biome.json b/biome.json index 8c26d6d6a5..4127fb3af8 100644 --- a/biome.json +++ b/biome.json @@ -23,7 +23,9 @@ "preset": "recommended", "correctness": { "noUndeclaredDependencies": "on", - "noGlobalDirnameFilename": "on" + "noGlobalDirnameFilename": "on", + "noUnusedInstantiation": "on", + "useSingleJsDocAsterisk": "on" }, "complexity": { "noUselessReturn": "on" From 4c9979662c980374c6d9a78e08e98b39c0d8ad24 Mon Sep 17 00:00:00 2001 From: Mark Probst Date: Mon, 13 Jul 2026 10:53:48 -0400 Subject: [PATCH 61/68] Biome: enable zero-violation complexity guard rules Enables noDivRegex, noUselessCatchBinding, noUselessStringConcat, useArrayFind, useWhile, noRedundantDefaultExport and noExcessiveNestedTestSuites, all already clean on the codebase. noUselessCatchBinding also locks in the optional-catch-binding cleanup done for noUnusedVariables. Co-Authored-By: Claude Fable 5 --- biome.json | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/biome.json b/biome.json index 4127fb3af8..911faf5745 100644 --- a/biome.json +++ b/biome.json @@ -28,7 +28,14 @@ "useSingleJsDocAsterisk": "on" }, "complexity": { - "noUselessReturn": "on" + "noUselessReturn": "on", + "noDivRegex": "on", + "noUselessCatchBinding": "on", + "noUselessStringConcat": "on", + "useArrayFind": "on", + "useWhile": "on", + "noRedundantDefaultExport": "on", + "noExcessiveNestedTestSuites": "on" }, "style": { "noUselessElse": "on", From d48cb1cf6a8236ae92e17a1035404aac0d2258b0 Mon Sep 17 00:00:00 2001 From: Mark Probst Date: Mon, 13 Jul 2026 10:54:16 -0400 Subject: [PATCH 62/68] Biome: enable zero-violation suspicious guard rules Enables noConstantBinaryExpressions, noVar, noFocusedTests, noSkippedTests, noReturnAssign, noDuplicateTestHooks, noDeprecatedImports, noDuplicateDependencies, useErrorMessage and noEmptySource, all already clean on the codebase. Co-Authored-By: Claude Fable 5 --- biome.json | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/biome.json b/biome.json index 911faf5745..4e7ef7d67b 100644 --- a/biome.json +++ b/biome.json @@ -66,7 +66,17 @@ "noUnusedExpressions": "on", "useArraySortCompare": "on", "noMisplacedAssertion": "on", - "noShadow": "on" + "noShadow": "on", + "noConstantBinaryExpressions": "on", + "noVar": "on", + "noFocusedTests": "on", + "noSkippedTests": "on", + "noReturnAssign": "on", + "noDuplicateTestHooks": "on", + "noDeprecatedImports": "on", + "noDuplicateDependencies": "on", + "useErrorMessage": "on", + "noEmptySource": "on" } } }, From 9e6718013ac124fdca0fc454f4995e6add84a926 Mon Sep 17 00:00:00 2001 From: Mark Probst Date: Mon, 13 Jul 2026 10:54:45 -0400 Subject: [PATCH 63/68] Biome: enable zero-violation style guard rules Enables useThrowOnlyError, useTrimStartEnd, useSymbolDescription, useSpreadOverApply, useNumberNamespace, useGlobalThis and useErrorCause, all already clean on the codebase. Co-Authored-By: Claude Fable 5 --- biome.json | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/biome.json b/biome.json index 4e7ef7d67b..25ba0a9ede 100644 --- a/biome.json +++ b/biome.json @@ -58,7 +58,14 @@ "useUnifiedTypeSignatures": "on", "noNamespace": "on", "useNodeAssertStrict": "on", - "useReadonlyClassProperties": "on" + "useReadonlyClassProperties": "on", + "useThrowOnlyError": "on", + "useTrimStartEnd": "on", + "useSymbolDescription": "on", + "useSpreadOverApply": "on", + "useNumberNamespace": "on", + "useGlobalThis": "on", + "useErrorCause": "on" }, "suspicious": { "noTemplateCurlyInString": "off", From 7f6a000abfa3af2afb9a44d5c27534c8a64cb672 Mon Sep 17 00:00:00 2001 From: Mark Probst Date: Mon, 13 Jul 2026 10:55:13 -0400 Subject: [PATCH 64/68] Biome: enable noDelete (performance), already clean The delete operator is not used anywhere in the codebase; enabling the rule keeps it that way. Co-Authored-By: Claude Fable 5 --- biome.json | 3 +++ 1 file changed, 3 insertions(+) diff --git a/biome.json b/biome.json index 25ba0a9ede..e13356669c 100644 --- a/biome.json +++ b/biome.json @@ -37,6 +37,9 @@ "noRedundantDefaultExport": "on", "noExcessiveNestedTestSuites": "on" }, + "performance": { + "noDelete": "on" + }, "style": { "noUselessElse": "on", "useCollapsedElseIf": "on", From d7918833c8e485a2f2935bdd8aa8ed4efba3fbd5 Mon Sep 17 00:00:00 2001 From: Mark Probst Date: Mon, 13 Jul 2026 14:13:13 -0400 Subject: [PATCH 65/68] Biome: disable noUselessElse per review and revert its changes The owner prefers explicit else blocks after returning branches; the flattened straight-line form loses the visual symmetry of the two arms. Rule set explicitly to "off" to document the deliberate rejection. Reverts commit e4df2f01. Co-Authored-By: Claude Fable 5 --- biome.json | 2 +- packages/quicktype-core/src/MarkovChain.ts | 3 +- .../quicktype-core/src/Type/TypeGraphUtils.ts | 11 ++-- packages/quicktype-core/src/UnifyClasses.ts | 61 ++++++++++--------- packages/quicktype-core/src/UnionBuilder.ts | 11 ++-- .../src/attributes/AccessorNames.ts | 37 +++++------ .../src/attributes/TypeAttributes.ts | 3 +- .../src/language/CSharp/CSharpRenderer.ts | 6 +- .../src/language/Crystal/utils.ts | 3 +- .../quicktype-core/src/language/Rust/utils.ts | 3 +- .../src/language/Scala3/utils.ts | 3 +- .../src/language/TypeScriptFlow/utils.ts | 12 ++-- .../quicktype-core/src/support/Strings.ts | 6 +- 13 files changed, 86 insertions(+), 75 deletions(-) diff --git a/biome.json b/biome.json index e13356669c..30d9c5b325 100644 --- a/biome.json +++ b/biome.json @@ -41,7 +41,7 @@ "noDelete": "on" }, "style": { - "noUselessElse": "on", + "noUselessElse": "off", "useCollapsedElseIf": "on", "useCollapsedIf": "on", "useThrowNewError": "on", diff --git a/packages/quicktype-core/src/MarkovChain.ts b/packages/quicktype-core/src/MarkovChain.ts index 885d12b204..cbdde4f076 100644 --- a/packages/quicktype-core/src/MarkovChain.ts +++ b/packages/quicktype-core/src/MarkovChain.ts @@ -39,8 +39,9 @@ function lookup(t: Trie, seq: string, i: number): Trie | number | undefined { if (typeof n === "object") { return lookup(n, seq, i + 1); + } else { + return n / t.count; } - return n / t.count; } function increment(t: Trie, seq: string, i: number): void { diff --git a/packages/quicktype-core/src/Type/TypeGraphUtils.ts b/packages/quicktype-core/src/Type/TypeGraphUtils.ts index 732c3734ec..66baa207be 100644 --- a/packages/quicktype-core/src/Type/TypeGraphUtils.ts +++ b/packages/quicktype-core/src/Type/TypeGraphUtils.ts @@ -91,12 +91,13 @@ export function optionalToNullable( properties, forwardingRef, ); + } else { + return builder.getClassType( + c.getAttributes(), + properties, + forwardingRef, + ); } - return builder.getClassType( - c.getAttributes(), - properties, - forwardingRef, - ); } const classesWithOptional = setFilter( diff --git a/packages/quicktype-core/src/UnifyClasses.ts b/packages/quicktype-core/src/UnifyClasses.ts index 7b2a9529a5..b6a5a6efb9 100644 --- a/packages/quicktype-core/src/UnifyClasses.ts +++ b/packages/quicktype-core/src/UnifyClasses.ts @@ -191,36 +191,38 @@ export class UnifyUnionBuilder extends UnionBuilder< this._unifyTypes(Array.from(propertyTypes)), forwardingRef, ); - } - const [properties, additionalProperties, lostTypeAttributes] = - getCliqueProperties(objectTypes, this.typeBuilder, (types) => { - assert(types.size > 0, "Property has no type"); - return this._unifyTypes( - Array.from(types).map((t) => t.typeRef), - ); - }); - if (lostTypeAttributes) { - this.typeBuilder.setLostTypeAttributes(); - } + } else { + const [properties, additionalProperties, lostTypeAttributes] = + getCliqueProperties(objectTypes, this.typeBuilder, (types) => { + assert(types.size > 0, "Property has no type"); + return this._unifyTypes( + Array.from(types).map((t) => t.typeRef), + ); + }); + if (lostTypeAttributes) { + this.typeBuilder.setLostTypeAttributes(); + } - if (this._makeObjectTypes) { - return this.typeBuilder.getUniqueObjectType( - typeAttributes, - properties, - additionalProperties, - forwardingRef, - ); + if (this._makeObjectTypes) { + return this.typeBuilder.getUniqueObjectType( + typeAttributes, + properties, + additionalProperties, + forwardingRef, + ); + } else { + assert( + additionalProperties === undefined, + "We have additional properties but want to make a class", + ); + return this.typeBuilder.getUniqueClassType( + typeAttributes, + this._makeClassesFixed, + properties, + forwardingRef, + ); + } } - assert( - additionalProperties === undefined, - "We have additional properties but want to make a class", - ); - return this.typeBuilder.getUniqueClassType( - typeAttributes, - this._makeClassesFixed, - properties, - forwardingRef, - ); } protected makeArray( @@ -280,8 +282,7 @@ export function unifyTypes( typeAttributes = typeBuilder.reconstituteTypeAttributes(typeAttributes); if (types.size === 0) { return panic("Cannot unify empty set of types"); - } - if (types.size === 1) { + } else if (types.size === 1) { const first = defined(iterableFirst(types)); if (!(first instanceof UnionType)) { return typeBuilder.reconstituteTypeRef( diff --git a/packages/quicktype-core/src/UnionBuilder.ts b/packages/quicktype-core/src/UnionBuilder.ts index a79c952f7b..1e9f0229bd 100644 --- a/packages/quicktype-core/src/UnionBuilder.ts +++ b/packages/quicktype-core/src/UnionBuilder.ts @@ -583,11 +583,12 @@ export abstract class UnionBuilder< if (union !== undefined) { this.typeBuilder.setSetOperationMembers(union, typesSet); return union; + } else { + return this.typeBuilder.getUnionType( + typeAttributes, + typesSet, + forwardingRef, + ); } - return this.typeBuilder.getUnionType( - typeAttributes, - typesSet, - forwardingRef, - ); } } diff --git a/packages/quicktype-core/src/attributes/AccessorNames.ts b/packages/quicktype-core/src/attributes/AccessorNames.ts index 0ab32123b6..6b3283cf71 100644 --- a/packages/quicktype-core/src/attributes/AccessorNames.ts +++ b/packages/quicktype-core/src/attributes/AccessorNames.ts @@ -260,23 +260,24 @@ export function accessorNamesAttributeProducer( makeAccessorNames(maybeAccessors), ), }; + } else { + const identifierAttribute = makeUnionIdentifierAttribute(); + + const accessors = checkArray(maybeAccessors, isAccessorEntry); + messageAssert( + cases.length === accessors.length, + "SchemaWrongAccessorEntryArrayLength", + { + operation: "oneOf", + ref: canonicalRef.push("oneOf"), + }, + ); + const caseAttributes = accessors.map((accessor) => + makeUnionMemberNamesAttribute( + identifierAttribute, + makeAccessorEntry(accessor), + ), + ); + return { forUnion: identifierAttribute, forCases: caseAttributes }; } - const identifierAttribute = makeUnionIdentifierAttribute(); - - const accessors = checkArray(maybeAccessors, isAccessorEntry); - messageAssert( - cases.length === accessors.length, - "SchemaWrongAccessorEntryArrayLength", - { - operation: "oneOf", - ref: canonicalRef.push("oneOf"), - }, - ); - const caseAttributes = accessors.map((accessor) => - makeUnionMemberNamesAttribute( - identifierAttribute, - makeAccessorEntry(accessor), - ), - ); - return { forUnion: identifierAttribute, forCases: caseAttributes }; } diff --git a/packages/quicktype-core/src/attributes/TypeAttributes.ts b/packages/quicktype-core/src/attributes/TypeAttributes.ts index c9d1485fd9..6fe033d53b 100644 --- a/packages/quicktype-core/src/attributes/TypeAttributes.ts +++ b/packages/quicktype-core/src/attributes/TypeAttributes.ts @@ -158,8 +158,9 @@ export function combineTypeAttributes( if (attrs.length === 1) return attrs[0]; if (union) { return kind.combine(attrs); + } else { + return kind.intersect(attrs); } - return kind.intersect(attrs); } return mapFilterMap(attributesByKind, combine); diff --git a/packages/quicktype-core/src/language/CSharp/CSharpRenderer.ts b/packages/quicktype-core/src/language/CSharp/CSharpRenderer.ts index 60f4d30333..8dd10334da 100644 --- a/packages/quicktype-core/src/language/CSharp/CSharpRenderer.ts +++ b/packages/quicktype-core/src/language/CSharp/CSharpRenderer.ts @@ -159,8 +159,9 @@ export class CSharpRenderer extends ConvenienceRenderer { ); if (this._csOptions.useList) { return ["List<", itemsType, ">"]; + } else { + return [itemsType, "[]"]; } - return [itemsType, "[]"]; }, (classType) => this.nameForNamedType(classType), (mapType) => [ @@ -189,8 +190,9 @@ export class CSharpRenderer extends ConvenienceRenderer { const csType = this.csType(t, follow, withIssues); if (isValueType(t)) { return [csType, "?"]; + } else { + return csType; } - return csType; } protected baseclassForType(_t: Type): Sourcelike | undefined { diff --git a/packages/quicktype-core/src/language/Crystal/utils.ts b/packages/quicktype-core/src/language/Crystal/utils.ts index a23c88512f..5dc85b9e64 100644 --- a/packages/quicktype-core/src/language/Crystal/utils.ts +++ b/packages/quicktype-core/src/language/Crystal/utils.ts @@ -62,8 +62,9 @@ export const camelNamingFunction = funPrefixNamer("camel", (original: string) => function standardUnicodeCrystalEscape(codePoint: number): string { if (codePoint <= 0xffff) { return `\\u{${intToHex(codePoint, 4)}}`; + } else { + return `\\u{${intToHex(codePoint, 6)}}`; } - return `\\u{${intToHex(codePoint, 6)}}`; } export const crystalStringEscape = utf32ConcatMap( diff --git a/packages/quicktype-core/src/language/Rust/utils.ts b/packages/quicktype-core/src/language/Rust/utils.ts index 4842ce6818..7e17b2c1c3 100644 --- a/packages/quicktype-core/src/language/Rust/utils.ts +++ b/packages/quicktype-core/src/language/Rust/utils.ts @@ -155,8 +155,9 @@ export const camelNamingFunction = funPrefixNamer("camel", (original: string) => const standardUnicodeRustEscape = (codePoint: number): string => { if (codePoint <= 0xffff) { return `\\u{${intToHex(codePoint, 4)}}`; + } else { + return `\\u{${intToHex(codePoint, 6)}}`; } - return `\\u{${intToHex(codePoint, 6)}}`; }; export const rustStringEscape = utf32ConcatMap( diff --git a/packages/quicktype-core/src/language/Scala3/utils.ts b/packages/quicktype-core/src/language/Scala3/utils.ts index ad237781e2..3c7258dc44 100644 --- a/packages/quicktype-core/src/language/Scala3/utils.ts +++ b/packages/quicktype-core/src/language/Scala3/utils.ts @@ -29,8 +29,9 @@ export const shouldAddBacktick = (paramName: string): boolean => { export const wrapOption = (s: string, optional: boolean): string => { if (optional) { return `Option[${s}]`; + } else { + return s; } - return s; }; function isPartCharacter(codePoint: number): boolean { diff --git a/packages/quicktype-core/src/language/TypeScriptFlow/utils.ts b/packages/quicktype-core/src/language/TypeScriptFlow/utils.ts index 7c64689f6a..01292966a1 100644 --- a/packages/quicktype-core/src/language/TypeScriptFlow/utils.ts +++ b/packages/quicktype-core/src/language/TypeScriptFlow/utils.ts @@ -17,15 +17,13 @@ export function quotePropertyName(original: string): string { if (original.length === 0) { return quoted; - } - if (!isES3IdentifierStart(original.codePointAt(0) as number)) { + } else if (!isES3IdentifierStart(original.codePointAt(0) as number)) { return quoted; - } - if (escaped !== original) { + } else if (escaped !== original) { return quoted; - } - if (legalizeName(original) !== original) { + } else if (legalizeName(original) !== original) { return quoted; + } else { + return original; } - return original; } diff --git a/packages/quicktype-core/src/support/Strings.ts b/packages/quicktype-core/src/support/Strings.ts index 8d0bb0e594..936fd92033 100644 --- a/packages/quicktype-core/src/support/Strings.ts +++ b/packages/quicktype-core/src/support/Strings.ts @@ -190,8 +190,9 @@ export function intToHex(i: number, width: number): string { export function standardUnicodeHexEscape(codePoint: number): string { if (codePoint <= 0xffff) { return `\\u${intToHex(codePoint, 4)}`; + } else { + return `\\U${intToHex(codePoint, 8)}`; } - return `\\U${intToHex(codePoint, 8)}`; } export function escapeNonPrintableMapper( @@ -671,7 +672,8 @@ export function makeNameStyle( if (prefix !== undefined) { return addPrefixIfNecessary(prefix, styledName); + } else { + return styledName; } - return styledName; }; } From 831388f0f9f8f52f29e0d082b089301c688e1ce6 Mon Sep 17 00:00:00 2001 From: Mark Probst Date: Mon, 13 Jul 2026 14:14:35 -0400 Subject: [PATCH 66/68] Biome: disable noVoidTypeReturn per review and revert its changes The owner prefers "return panic(...)" over a bare "panic(...)" statement in void-returning functions: the return makes the control-flow termination explicit at the call site. Rule set explicitly to "off" to document the deliberate rejection. Reverts commit 4509283e. Co-Authored-By: Claude Fable 5 --- biome.json | 3 ++- packages/quicktype-core/src/MarkovChain.ts | 6 +++--- packages/quicktype-core/src/Messages.ts | 2 +- packages/quicktype-core/src/Source.ts | 2 +- packages/quicktype-core/src/Type/TypeBuilder.ts | 2 +- packages/quicktype-core/src/input/CompressedJSON.ts | 12 +++++++----- packages/quicktype-core/src/support/Strings.ts | 2 +- packages/quicktype-core/src/support/Support.ts | 2 +- 8 files changed, 17 insertions(+), 14 deletions(-) diff --git a/biome.json b/biome.json index 30d9c5b325..c92b4e7517 100644 --- a/biome.json +++ b/biome.json @@ -25,7 +25,8 @@ "noUndeclaredDependencies": "on", "noGlobalDirnameFilename": "on", "noUnusedInstantiation": "on", - "useSingleJsDocAsterisk": "on" + "useSingleJsDocAsterisk": "on", + "noVoidTypeReturn": "off" }, "complexity": { "noUselessReturn": "on", diff --git a/packages/quicktype-core/src/MarkovChain.ts b/packages/quicktype-core/src/MarkovChain.ts index cbdde4f076..ba45c1787d 100644 --- a/packages/quicktype-core/src/MarkovChain.ts +++ b/packages/quicktype-core/src/MarkovChain.ts @@ -52,14 +52,14 @@ function increment(t: Trie, seq: string, i: number): void { if (i >= seq.length - 1) { if (typeof t !== "object") { - panic("Malformed trie"); + return panic("Malformed trie"); } let n = t.arr[first]; if (n === null) { n = 0; } else if (typeof n === "object") { - panic("Malformed trie"); + return panic("Malformed trie"); } t.arr[first] = n + 1; @@ -74,7 +74,7 @@ function increment(t: Trie, seq: string, i: number): void { } if (typeof st !== "object") { - panic("Malformed trie"); + return panic("Malformed trie"); } increment(st, seq, i + 1); diff --git a/packages/quicktype-core/src/Messages.ts b/packages/quicktype-core/src/Messages.ts index 990e228c23..902c3b187c 100644 --- a/packages/quicktype-core/src/Messages.ts +++ b/packages/quicktype-core/src/Messages.ts @@ -314,5 +314,5 @@ export function messageAssert( properties: ErrorPropertiesForKind, ): void { if (assertion) return; - messageError(kind, properties); + return messageError(kind, properties); } diff --git a/packages/quicktype-core/src/Source.ts b/packages/quicktype-core/src/Source.ts index df71824802..15f155da8b 100644 --- a/packages/quicktype-core/src/Source.ts +++ b/packages/quicktype-core/src/Source.ts @@ -301,7 +301,7 @@ export function serializeRenderResult( break; } default: - assertNever(source); + return assertNever(source); } } diff --git a/packages/quicktype-core/src/Type/TypeBuilder.ts b/packages/quicktype-core/src/Type/TypeBuilder.ts index a3239caa57..bb2edba208 100644 --- a/packages/quicktype-core/src/Type/TypeBuilder.ts +++ b/packages/quicktype-core/src/Type/TypeBuilder.ts @@ -469,7 +469,7 @@ export class TypeBuilder { const type = derefTypeRef(ref, this.typeGraph); if (!(type instanceof ObjectType)) { - panic("Tried to set properties of non-object type"); + return panic("Tried to set properties of non-object type"); } type.setProperties( diff --git a/packages/quicktype-core/src/input/CompressedJSON.ts b/packages/quicktype-core/src/input/CompressedJSON.ts index 39748a97c9..09e9193633 100644 --- a/packages/quicktype-core/src/input/CompressedJSON.ts +++ b/packages/quicktype-core/src/input/CompressedJSON.ts @@ -154,7 +154,9 @@ export abstract class CompressedJSON { this._rootValue = value; } else if (this._ctx.currentObject !== undefined) { if (this._ctx.currentKey === undefined) { - panic("Must have key and can't have string when committing"); + return panic( + "Must have key and can't have string when committing", + ); } this._ctx.currentObject.push( @@ -165,7 +167,7 @@ export abstract class CompressedJSON { } else if (this._ctx.currentArray !== undefined) { this._ctx.currentArray.push(value); } else { - panic("Committing value but nowhere to commit to"); + return panic("Committing value but nowhere to commit to"); } } @@ -256,7 +258,7 @@ export abstract class CompressedJSON { protected finishObject(): void { const obj = this.context.currentObject; if (obj === undefined) { - panic("Object ended but not started"); + return panic("Object ended but not started"); } this.popContext(); @@ -271,7 +273,7 @@ export abstract class CompressedJSON { protected finishArray(): void { const arr = this.context.currentArray; if (arr === undefined) { - panic("Array ended but not started"); + return panic("Array ended but not started"); } this.popContext(); @@ -359,7 +361,7 @@ export class CompressedJSONFromString extends CompressedJSON { this.finishObject(); } else { - panic("Invalid JSON object"); + return panic("Invalid JSON object"); } } } diff --git a/packages/quicktype-core/src/support/Strings.ts b/packages/quicktype-core/src/support/Strings.ts index 936fd92033..e9d9a82ed4 100644 --- a/packages/quicktype-core/src/support/Strings.ts +++ b/packages/quicktype-core/src/support/Strings.ts @@ -423,7 +423,7 @@ export function splitIntoWords(s: string): WordInName[] { function commitInterval(): void { if (intervalStart === undefined) { - panic("Tried to commit interval without starting one"); + return panic("Tried to commit interval without starting one"); } assert(i > intervalStart, "Interval must be non-empty"); diff --git a/packages/quicktype-core/src/support/Support.ts b/packages/quicktype-core/src/support/Support.ts index 30fa6d6c9a..88c18712db 100644 --- a/packages/quicktype-core/src/support/Support.ts +++ b/packages/quicktype-core/src/support/Support.ts @@ -99,7 +99,7 @@ export function assertNever(x: never): never { export function assert(condition: boolean, message = "Assertion failed"): void { if (!condition) { - messageError("InternalError", { message }); + return messageError("InternalError", { message }); } } From 889d31982aad227d06d09fb6d45e8fadf2990585 Mon Sep 17 00:00:00 2001 From: Mark Probst Date: Mon, 13 Jul 2026 15:51:48 -0400 Subject: [PATCH 67/68] Biome: disable noConstructorReturn per review and revert its changes Same idiom objection as noVoidTypeReturn: the owner prefers "return panic(...)" over a bare "panic(...)" statement. Restores the @ts-expect-error on queryType that the definite-assignment analysis had made obsolete. Rule set explicitly to "off" to document the deliberate rejection. Reverts commit 279491f9. Co-Authored-By: Claude Fable 5 --- biome.json | 1 + packages/quicktype-graphql-input/src/index.ts | 13 +++++++------ 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/biome.json b/biome.json index c92b4e7517..ec055d2a7c 100644 --- a/biome.json +++ b/biome.json @@ -26,6 +26,7 @@ "noGlobalDirnameFilename": "on", "noUnusedInstantiation": "on", "useSingleJsDocAsterisk": "on", + "noConstructorReturn": "off", "noVoidTypeReturn": "off" }, "complexity": { diff --git a/packages/quicktype-graphql-input/src/index.ts b/packages/quicktype-graphql-input/src/index.ts index 4d53afeaa0..2ac6fcbad8 100644 --- a/packages/quicktype-graphql-input/src/index.ts +++ b/packages/quicktype-graphql-input/src/index.ts @@ -466,6 +466,7 @@ class GQLQuery { class GQLSchemaFromJSON implements GQLSchema { public readonly types: { [name: string]: GQLType } = {}; + // @ts-expect-error: The constructor can return early, but only by throwing. public readonly queryType: GQLType; public readonly mutationType?: GQLType; @@ -474,11 +475,11 @@ class GQLSchemaFromJSON implements GQLSchema { const schema: GraphQLSchema = json.data; if (schema.__schema.queryType.name === null) { - panic("Query type doesn't have a name."); + return panic("Query type doesn't have a name."); } for (const t of schema.__schema.types as GQLType[]) { - if (!t.name) panic("No top-level type name given"); + if (!t.name) return panic("No top-level type name given"); this.types[t.name] = { kind: t.kind, name: t.name, @@ -487,7 +488,7 @@ class GQLSchemaFromJSON implements GQLSchema { } for (const t of schema.__schema.types) { - if (!t.name) panic("This cannot happen"); + if (!t.name) return panic("This cannot happen"); const type = this.types[t.name]; this.addTypeFields(type, t as GQLType); // console.log(`type ${type.name} is ${type.kind}`); @@ -495,7 +496,7 @@ class GQLSchemaFromJSON implements GQLSchema { const queryType = this.types[schema.__schema.queryType.name]; if (queryType === undefined) { - panic("Query type not found."); + return panic("Query type not found."); } // console.log(`query type ${queryType.name} is ${queryType.kind}`); @@ -506,12 +507,12 @@ class GQLSchemaFromJSON implements GQLSchema { } if (schema.__schema.mutationType.name === null) { - panic("Mutation type doesn't have a name."); + return panic("Mutation type doesn't have a name."); } const mutationType = this.types[schema.__schema.mutationType.name]; if (mutationType === undefined) { - panic("Mutation type not found."); + return panic("Mutation type not found."); } this.mutationType = mutationType; From 3738f48d9db1852211a03e057934096ec43154e8 Mon Sep 17 00:00:00 2001 From: Mark Probst Date: Mon, 13 Jul 2026 15:53:39 -0400 Subject: [PATCH 68/68] Biome: keep isNullable defaults in DartRenderer's dynamic-expression API DartRenderer is exported from quicktype-core, so fromDynamicExpression and toDynamicExpression are downstream-subclass API; dropping their "isNullable = false" defaults was a breaking signature change. Restore the defaults and suppress useDefaultParameterLast at the two parameters instead. These were the rule's only two violations, so no other API surface was affected. Co-Authored-By: Claude Fable 5 --- packages/quicktype-core/src/language/Dart/DartRenderer.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/quicktype-core/src/language/Dart/DartRenderer.ts b/packages/quicktype-core/src/language/Dart/DartRenderer.ts index 203a15693d..f11f77f6f3 100644 --- a/packages/quicktype-core/src/language/Dart/DartRenderer.ts +++ b/packages/quicktype-core/src/language/Dart/DartRenderer.ts @@ -420,7 +420,8 @@ export class DartRenderer extends ConvenienceRenderer { // the isNullable property will become false, which is obviously wrong, // so add isNullable property protected fromDynamicExpression( - isNullable: boolean, + // biome-ignore lint/style/useDefaultParameterLast: part of the exported DartRenderer API; removing the default would break downstream subclasses + isNullable = false, t: Type, ...dynamic: Sourcelike[] ): Sourcelike { @@ -517,7 +518,8 @@ export class DartRenderer extends ConvenienceRenderer { // the isNullable property will become false, which is obviously wrong, // so add isNullable property protected toDynamicExpression( - isNullable: boolean, + // biome-ignore lint/style/useDefaultParameterLast: part of the exported DartRenderer API; removing the default would break downstream subclasses + isNullable = false, t: Type, ...dynamic: Sourcelike[] ): Sourcelike {