diff --git a/biome.json b/biome.json index 00d50f7c05..ec055d2a7c 100644 --- a/biome.json +++ b/biome.json @@ -18,10 +18,114 @@ "indentWidth": 4 }, "linter": { - "enabled": false + "enabled": true, + "rules": { + "preset": "recommended", + "correctness": { + "noUndeclaredDependencies": "on", + "noGlobalDirnameFilename": "on", + "noUnusedInstantiation": "on", + "useSingleJsDocAsterisk": "on", + "noConstructorReturn": "off", + "noVoidTypeReturn": "off" + }, + "complexity": { + "noUselessReturn": "on", + "noDivRegex": "on", + "noUselessCatchBinding": "on", + "noUselessStringConcat": "on", + "useArrayFind": "on", + "useWhile": "on", + "noRedundantDefaultExport": "on", + "noExcessiveNestedTestSuites": "on" + }, + "performance": { + "noDelete": "on" + }, + "style": { + "noUselessElse": "off", + "useCollapsedElseIf": "on", + "useCollapsedIf": "on", + "useThrowNewError": "on", + "useConsistentBuiltinInstantiation": "on", + "useObjectSpread": "on", + "noYodaExpression": "on", + "noSubstr": "on", + "useExplicitLengthCheck": "on", + "noMultiAssign": "on", + "useConsistentObjectDefinitions": "on", + "useForOf": "on", + "noUnusedTemplateLiteral": "on", + "useShorthandAssign": "on", + "noInferrableTypes": "on", + "useDefaultParameterLast": "on", + "useConsistentMethodSignatures": "on", + "useUnifiedTypeSignatures": "on", + "noNamespace": "on", + "useNodeAssertStrict": "on", + "useReadonlyClassProperties": "on", + "useThrowOnlyError": "on", + "useTrimStartEnd": "on", + "useSymbolDescription": "on", + "useSpreadOverApply": "on", + "useNumberNamespace": "on", + "useGlobalThis": "on", + "useErrorCause": "on" + }, + "suspicious": { + "noTemplateCurlyInString": "off", + "noEqualsToNull": "on", + "noUnusedExpressions": "on", + "useArraySortCompare": "on", + "noMisplacedAssertion": "on", + "noShadow": "on", + "noConstantBinaryExpressions": "on", + "noVar": "on", + "noFocusedTests": "on", + "noSkippedTests": "on", + "noReturnAssign": "on", + "noDuplicateTestHooks": "on", + "noDeprecatedImports": "on", + "noDuplicateDependencies": "on", + "useErrorMessage": "on", + "noEmptySource": "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": { + "rules": { + "suspicious": { + "noMisplacedAssertion": "off" + } + } + } + }, + { + "includes": ["packages/quicktype-core/src/**"], + "linter": { + "rules": { + "style": { + "useNodejsImportProtocol": "off" + } + } + } + }, { "includes": ["**/tsconfig.json", "**/tsconfig.*.json"], "json": { 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-core/src/ConvenienceRenderer.ts b/packages/quicktype-core/src/ConvenienceRenderer.ts index 77b09d3a56..de5901e6e2 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; } @@ -834,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, @@ -1275,7 +1266,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)}\\"`; 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; 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/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/MarkovChain.ts b/packages/quicktype-core/src/MarkovChain.ts index ff516d0361..ba45c1787d 100644 --- a/packages/quicktype-core/src/MarkovChain.ts +++ b/packages/quicktype-core/src/MarkovChain.ts @@ -69,7 +69,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") { @@ -116,10 +117,10 @@ export function evaluateFull( } scores.push(cp); - p = p * cp; + 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/Messages.ts b/packages/quicktype-core/src/Messages.ts index 92009589ce..902c3b187c 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 }; @@ -55,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 } } | { @@ -80,7 +83,7 @@ export type ErrorProperties = } | { kind: "SchemaSetOperationCasesIsNotArray"; - properties: { cases: any; operation: string; ref: Ref }; + properties: { cases: unknown; operation: string; ref: Ref }; } | { kind: "SchemaMoreThanOneUnionMemberName"; @@ -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 | { @@ -288,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/Renderer.ts b/packages/quicktype-core/src/Renderer.ts index 847db36ff5..f1ad5dd4f5 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) }; } } @@ -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/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/Source.ts b/packages/quicktype-core/src/Source.ts index 2f8deccdf3..15f155da8b 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), @@ -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); } @@ -304,7 +307,7 @@ export function serializeRenderResult( serializeToStringArray(rootSource); finishLine(); - return { lines, annotations: annotations }; + return { lines, annotations }; } export interface MultiWord { 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/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/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/TypeBuilder.ts b/packages/quicktype-core/src/Type/TypeBuilder.ts index d71b918908..bb2edba208 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); @@ -637,7 +641,5 @@ export class TypeBuilder { this.registerType(type); } - public setLostTypeAttributes(): void { - return; - } + public setLostTypeAttributes(): void {} } 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/Type/TypeUtils.ts b/packages/quicktype-core/src/Type/TypeUtils.ts index 5dc0099241..42e037fd30 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(), + ); } } @@ -111,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) { @@ -375,9 +371,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/UnifyClasses.ts b/packages/quicktype-core/src/UnifyClasses.ts index 9c90739220..b6a5a6efb9 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) { @@ -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/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..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); } @@ -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/attributes/TypeAttributes.ts b/packages/quicktype-core/src/attributes/TypeAttributes.ts index ef653e9724..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(); @@ -118,7 +116,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 +152,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/CompressedJSON.ts b/packages/quicktype-core/src/input/CompressedJSON.ts index d92828a29a..09e9193633 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, @@ -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]; } @@ -184,7 +185,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/Inference.ts b/packages/quicktype-core/src/input/Inference.ts index b10a13f9de..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( @@ -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); diff --git a/packages/quicktype-core/src/input/JSONSchemaInput.ts b/packages/quicktype-core/src/input/JSONSchemaInput.ts index ddccbf70e5..e9973ba7fc 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( @@ -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; @@ -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"'); @@ -398,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; @@ -925,8 +924,7 @@ async function addTypesInSchema( } const includedTypes = setFilter(schemaTypes, isTypeIncluded); - let producedAttributesForNoCases: JSONSchemaAttributes[] | undefined = - undefined; + let producedAttributesForNoCases: JSONSchemaAttributes[] | undefined; function forEachProducedAttribute( cases: JSONSchema[] | undefined, @@ -1443,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; @@ -1498,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(); @@ -1540,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/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..86b8fe8f32 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; } } @@ -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/input/io/get-stream/buffer-stream.ts b/packages/quicktype-core/src/input/io/get-stream/buffer-stream.ts index eab9283ee1..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 @@ -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; @@ -12,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; @@ -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 24d4fda8bc..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,13 +14,14 @@ 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; - let clean; + 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 @@ -55,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/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/CJSON/CJSONRenderer.ts b/packages/quicktype-core/src/language/CJSON/CJSONRenderer.ts index f8506ae980..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 @@ -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"; } @@ -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("}"); } } @@ -5783,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) { @@ -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 e6704b5aca..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(", "); } @@ -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; } } @@ -3088,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) => { @@ -3331,9 +3329,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/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; } diff --git a/packages/quicktype-core/src/language/CSharp/CSharpRenderer.ts b/packages/quicktype-core/src/language/CSharp/CSharpRenderer.ts index b0d55a653d..8dd10334da 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, @@ -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; @@ -537,8 +531,8 @@ export class CSharpRenderer extends ConvenienceRenderer { } protected emitDependencyUsings(): void { - let genericEmited: boolean = false; - let ensureGenericOnce = () => { + let genericEmited = false; + const ensureGenericOnce = () => { if (!genericEmited) { this.emitUsing("System.Collections.Generic"); genericEmited = 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 70c4c8762b..8eb22b14b6 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, @@ -704,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( @@ -948,9 +947,7 @@ export class SystemTextJsonCSharpRenderer extends CSharpRenderer { itemVariable, xfer.itemTransformer, xfer.itemTargetType, - () => { - return; - }, + () => {}, ); }); this.emitLine("writer.WriteEndArray();"); 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/Crystal/CrystalRenderer.ts b/packages/quicktype-core/src/language/Crystal/CrystalRenderer.ts index 4417d1dc90..e73996bb93 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; } @@ -211,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/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/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/Dart/DartRenderer.ts b/packages/quicktype-core/src/language/Dart/DartRenderer.ts index b158572c3b..f11f77f6f3 100644 --- a/packages/quicktype-core/src/language/Dart/DartRenderer.ts +++ b/packages/quicktype-core/src/language/Dart/DartRenderer.ts @@ -419,8 +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( + // biome-ignore lint/style/useDefaultParameterLast: part of the exported DartRenderer API; removing the default would break downstream subclasses isNullable = false, t: Type, ...dynamic: Sourcelike[] @@ -517,8 +517,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( + // biome-ignore lint/style/useDefaultParameterLast: part of the exported DartRenderer API; removing the default would break downstream subclasses isNullable = false, t: Type, ...dynamic: Sourcelike[] diff --git a/packages/quicktype-core/src/language/Elixir/ElixirRenderer.ts b/packages/quicktype-core/src/language/Elixir/ElixirRenderer.ts index 98d58336f7..6192e64f8e 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[] { @@ -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, "]"]); } @@ -942,7 +945,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`], @@ -1108,9 +1111,7 @@ end`); ); } - protected emitUnion(_u: UnionType, _unionName: Name): void { - return; - } + protected emitUnion(_u: UnionType, _unionName: Name): void {} protected emitSourceStructure(): void { if (this.leadingComments !== undefined) { @@ -1147,14 +1148,14 @@ 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"], () => { 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/Elm/ElmRenderer.ts b/packages/quicktype-core/src/language/Elm/ElmRenderer.ts index 386bd79633..72acf1b41e 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, @@ -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..72d50068e8 100644 --- a/packages/quicktype-core/src/language/Golang/GolangRenderer.ts +++ b/packages/quicktype-core/src/language/Golang/GolangRenderer.ts @@ -249,14 +249,16 @@ 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) ? ",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/JSONSchema/JSONSchemaRenderer.ts b/packages/quicktype-core/src/language/JSONSchema/JSONSchemaRenderer.ts index e7ed8f10dc..227a46da75 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; } @@ -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(); } @@ -181,10 +182,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/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/Java/JavaJacksonRenderer.ts b/packages/quicktype-core/src/language/Java/JavaJacksonRenderer.ts index 46d757ed48..673e44ad1f 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", @@ -73,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 ce0fc3b741..e126f10887 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, @@ -391,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) => { @@ -475,8 +476,11 @@ 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); + }); }); + // biome-ignore lint/suspicious/useArraySortCompare: sorting strings; default UTF-16 order is intended imports.sort(); return [...new Set(imports)]; } @@ -485,8 +489,11 @@ 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); + }); }); + // biome-ignore lint/suspicious/useArraySortCompare: sorting strings; default UTF-16 order is intended imports.sort(); return [...new Set(imports)]; } @@ -519,13 +526,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(", ")}})`, ); @@ -559,7 +566,9 @@ export class JavaRenderer extends ConvenienceRenderer { jsonName, p, false, - ).forEach((annotation) => this.emitLine(annotation)); + ).forEach((annotation) => { + this.emitLine(annotation); + }); this.emitLine( "public ", rendered, @@ -576,7 +585,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/JavaScript/JavaScriptRenderer.ts b/packages/quicktype-core/src/language/JavaScript/JavaScriptRenderer.ts index e6b2d9af6e..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, ");"); } }, ); @@ -497,9 +491,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/JavaScriptPropTypes/JavaScriptPropTypesRenderer.ts b/packages/quicktype-core/src/language/JavaScriptPropTypes/JavaScriptPropTypesRenderer.ts index 046a19744f..67b37614d4 100644 --- a/packages/quicktype-core/src/language/JavaScriptPropTypes/JavaScriptPropTypesRenderer.ts +++ b/packages/quicktype-core/src/language/JavaScriptPropTypes/JavaScriptPropTypesRenderer.ts @@ -265,25 +265,25 @@ 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) => { 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/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/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/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/Php/PhpRenderer.ts b/packages/quicktype-core/src/language/Php/PhpRenderer.ts index d6119fe408..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"'); }, ); } @@ -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, "*/", @@ -717,11 +717,11 @@ 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") { - const x = _.pad("" + (1 + (idx % 31)), 2, "0"); + const x = _.pad(`${1 + (idx % 31)}`, 2, "0"); this.emitLine( ...lhs, "DateTime::createFromFormat(DateTimeInterface::ISO8601, '", @@ -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 { 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, 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/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), diff --git a/packages/quicktype-core/src/language/Python/PythonRenderer.ts b/packages/quicktype-core/src/language/Python/PythonRenderer.ts index cd386f7ca5..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; @@ -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/Ruby/RubyRenderer.ts b/packages/quicktype-core/src/language/Ruby/RubyRenderer.ts index 957370d671..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[] { @@ -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([ @@ -863,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], () => { 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..7e17b2c1c3 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(""), }, @@ -103,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; @@ -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)}}`; } }; @@ -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/Scala3/CirceRenderer.ts b/packages/quicktype-core/src/language/Scala3/CirceRenderer.ts index a3a55883cb..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, @@ -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 7ae221c262..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 ", @@ -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..3c7258dc44 100644 --- a/packages/quicktype-core/src/language/Scala3/utils.ts +++ b/packages/quicktype-core/src/language/Scala3/utils.ts @@ -21,14 +21,14 @@ 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))) + !Number.isNaN(+Number.parseFloat(paramName)) || + !Number.isNaN(Number.parseInt(paramName.charAt(0), 10)) ); }; 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..e9c27f47c3 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 ", @@ -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/Smithy4s/utils.ts b/packages/quicktype-core/src/language/Smithy4s/utils.ts index 0291a67390..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))) + !Number.isNaN(Number.parseFloat(paramName)) || + !Number.isNaN(Number.parseInt(paramName.charAt(0), 10)) ); }; diff --git a/packages/quicktype-core/src/language/Swift/SwiftRenderer.ts b/packages/quicktype-core/src/language/Swift/SwiftRenderer.ts index b9fae90ee9..5b756f9d51 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 { @@ -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 => { @@ -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/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/language/TypeScriptEffectSchema/TypeScriptEffectSchemaRenderer.ts b/packages/quicktype-core/src/language/TypeScriptEffectSchema/TypeScriptEffectSchemaRenderer.ts index 56d3747536..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, @@ -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/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/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/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..43537b1464 100644 --- a/packages/quicktype-core/src/language/TypeScriptFlow/TypeScriptRenderer.ts +++ b/packages/quicktype-core/src/language/TypeScriptFlow/TypeScriptRenderer.ts @@ -45,12 +45,10 @@ export class TypeScriptRenderer extends TypeScriptFlowBaseRenderer { } protected get typeAnnotations(): JavaScriptTypeAnnotations { - return Object.assign({ never: ": never" }, tsFlowTypeAnnotations); + return { never: ": never", ...tsFlowTypeAnnotations }; } - protected emitModuleExports(): void { - return; - } + protected emitModuleExports(): void {} protected emitUsageImportComment(): void { const topLevelNames: Sourcelike[] = []; 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/packages/quicktype-core/src/language/TypeScriptZod/TypeScriptZodRenderer.ts b/packages/quicktype-core/src/language/TypeScriptZod/TypeScriptZodRenderer.ts index 3af7bc0e31..6406101476 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(); @@ -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; @@ -510,13 +507,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/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 {}; } diff --git a/packages/quicktype-core/src/rewrites/CombineClasses.ts b/packages/quicktype-core/src/rewrites/CombineClasses.ts index 8c5fa31cc5..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; @@ -142,7 +140,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..9987053070 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) { @@ -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; } @@ -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/Chance.ts b/packages/quicktype-core/src/support/Chance.ts index f4c553c5f8..fabbbcc072 100644 --- a/packages/quicktype-core/src/support/Chance.ts +++ b/packages/quicktype-core/src/support/Chance.ts @@ -45,14 +45,14 @@ class MersenneTwister { private readonly LOWER_MASK: number; - private mt: number[]; + private readonly mt: number[]; private mti: number; 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 */ @@ -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, */ diff --git a/packages/quicktype-core/src/support/Strings.ts b/packages/quicktype-core/src/support/Strings.ts index 280a8e867c..e9d9a82ed4 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(""); }; @@ -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); @@ -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; @@ -610,7 +610,8 @@ export function makeNameStyle( restWordStyle = firstUpperWordStyle; restAcronymStyle = allUpperWordStyle; } else { - restWordStyle = restAcronymStyle = firstUpperWordStyle; + restAcronymStyle = firstUpperWordStyle; + restWordStyle = restAcronymStyle; } } else { separator = "_"; @@ -619,32 +620,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); diff --git a/packages/quicktype-core/src/support/Support.ts b/packages/quicktype-core/src/support/Support.ts index cdb1f456da..88c18712db 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 0f5b61fe66..2ac6fcbad8 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; } @@ -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 = @@ -647,13 +649,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/packages/quicktype-vscode/src/extension.ts b/packages/quicktype-vscode/src/extension.ts index ff5a757d34..08f5e011d9 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, @@ -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"; @@ -34,7 +35,7 @@ enum Command { function jsonIsValid(json: string): boolean { try { JSON.parse(json); - } catch (e) { + } catch { return false; } @@ -147,7 +148,7 @@ async function runQuicktype( } const options: Partial = { - lang: lang, + lang, inputData, rendererOptions, indentation, @@ -186,7 +187,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", ); @@ -310,7 +311,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 { @@ -370,7 +371,7 @@ class CodeProvider implements vscode.TextDocumentContentProvider { if (!this._isOpen) return; this._onDidChange.fire(this.uri); - } catch (e) { + } catch { // FIXME } } @@ -411,12 +412,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, @@ -546,6 +547,4 @@ export async function activate( } } -export function deactivate(): void { - return; -} +export function deactivate(): void {} 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 a122614529..982adf627f 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( @@ -137,8 +138,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); @@ -241,7 +242,7 @@ async function samplesFromDirectory( schemaSources.length + graphQLSources.length > 0 ) { return messageError("DriverCannotMixJSONWithOtherSamples", { - dir: dir, + dir, }); } @@ -252,7 +253,7 @@ async function samplesFromDirectory( oneUnlessEmpty(schemaSources) + oneUnlessEmpty(graphQLSources) > 1 ) { - return messageError("DriverCannotMixNonJSONInputs", { dir: dir }); + return messageError("DriverCannotMixNonJSONInputs", { dir }); } if (jsonSamples.length > 0) { @@ -351,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, @@ -395,7 +396,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 +471,7 @@ function makeOptionDefinitions( return { name: dashedFromCamelCase(negatedInferenceFlagName(name)), optionType: "boolean" as const, - description: flag.negationDescription + ".", + description: `${flag.negationDescription}.`, kind: "cli" as const, }; }).values(), @@ -879,10 +880,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( @@ -987,11 +988,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; + case "graphql": { + let schemaString: string | undefined; let wroteSchemaToFile = false; if (options.graphqlIntrospect !== undefined) { schemaString = await introspectServer( @@ -1024,7 +1025,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"); @@ -1047,6 +1048,7 @@ export async function makeQuicktypeOptions( sources = gqlSources; break; + } case "json": case "schema": sources = await getSources(options); @@ -1063,12 +1065,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 0472762b33..33f9dd1c29 100644 --- a/test/fixtures.ts +++ b/test/fixtures.ts @@ -100,10 +100,10 @@ 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("-", "_")] = ( + newEnv[`QUICKTYPE_${option.toUpperCase().replace("-", "_")}`] = ( additionalRendererOptions[ option as keyof typeof additionalRendererOptions ] as Option @@ -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[]; @@ -216,10 +214,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) { @@ -873,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[] = [ @@ -1114,9 +1109,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 = [ @@ -1151,6 +1144,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 { @@ -1165,6 +1159,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[], @@ -1187,6 +1182,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/languages.ts b/test/languages.ts index 8878247828..5d971b30ca 100644 --- a/test/languages.ts +++ b/test/languages.ts @@ -1,7 +1,7 @@ import type { LanguageName } from "quicktype-core"; -import * as process from "process"; -// @ts-ignore +import * as process from "node:process"; +// @ts-expect-error: ../dist only exists after the root package is built import type { RendererOptions } from "../dist/quicktype-core/Run"; const easySampleJSONs = [ @@ -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`; }, @@ -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, diff --git a/test/lib/deepEquals.ts b/test/lib/deepEquals.ts index eaeb1209a5..2db4aa051c 100644 --- a/test/lib/deepEquals.ts +++ b/test/lib/deepEquals.ts @@ -3,12 +3,7 @@ import type { Moment } from "moment"; import type { ComparisonRelaxations } from "../utils"; function pathToString(path: string[]): string { - return "." + path.join("."); -} - -declare namespace Math { - // TypeScript cannot find this function - function fround(n: number): number; + return `.${path.join(".")}`; } function tryParseMoment(s: string): [Moment | undefined, boolean] { @@ -33,7 +28,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, @@ -42,7 +39,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 @@ -77,7 +74,7 @@ export default function deepEquals( return false; } if ( - !!relax.allowStringifiedIntegers && + relax.allowStringifiedIntegers && typeof x === "string" && typeof y === "number" ) { @@ -143,19 +140,17 @@ 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; } } 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( diff --git a/test/lib/multicore.ts b/test/lib/multicore.ts index e67e1b943d..9bf607675e 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 = ["👷🏻", "👷🏼", "👷🏽", "👷🏾", "👷🏿"]; @@ -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 { @@ -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 diff --git a/test/release-version.ts b/test/release-version.ts index c73ffd7aed..aabf7de1ea 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, 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; ////////////////////////////////////// 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] ?? ""; } 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]; }