From 08d2e36ea755cb99a412245682c33565cf301935 Mon Sep 17 00:00:00 2001 From: Vincent Driessen Date: Mon, 20 Apr 2026 16:33:36 +0200 Subject: [PATCH] =?UTF-8?q?Upgrade=20ESLint=208=20=E2=86=92=209=20with=20f?= =?UTF-8?q?lat=20config=20(PR=201705)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Original commit: 52f3bb1d46709b24e35841652d28e42e73017039 --- packages/liveblocks-server/.eslintrc.cjs | 42 ----------- packages/liveblocks-server/eslint.config.mjs | 54 ++++++++++++++ packages/liveblocks-server/package.json | 10 ++- packages/liveblocks-server/src/Room.ts | 1 - packages/liveblocks-server/src/Storage.ts | 4 +- .../liveblocks-server/src/lib/DefaultMap.ts | 1 - packages/liveblocks-server/src/lib/Logger.ts | 2 - .../test/plugins/_generateFullTestSuite.ts | 26 ++----- .../test/storage/model-based/storage-model.ts | 1 - tools/liveblocks-cli/.eslintrc.cjs | 57 --------------- tools/liveblocks-cli/eslint.config.mjs | 71 +++++++++++++++++++ tools/liveblocks-cli/package.json | 10 ++- .../liveblocks-cli/src/dev-server/lib/ydoc.ts | 3 +- tools/liveblocks-cli/src/lib/args.ts | 1 - .../test/plugins/_generateFullTestSuite.ts | 25 ++----- 15 files changed, 144 insertions(+), 164 deletions(-) delete mode 100644 packages/liveblocks-server/.eslintrc.cjs create mode 100644 packages/liveblocks-server/eslint.config.mjs delete mode 100644 tools/liveblocks-cli/.eslintrc.cjs create mode 100644 tools/liveblocks-cli/eslint.config.mjs diff --git a/packages/liveblocks-server/.eslintrc.cjs b/packages/liveblocks-server/.eslintrc.cjs deleted file mode 100644 index 767149cefb1..00000000000 --- a/packages/liveblocks-server/.eslintrc.cjs +++ /dev/null @@ -1,42 +0,0 @@ -module.exports = { - root: true, - extends: ["@liveblocks/eslint-config"], - plugins: ["license-header"], - - rules: { - "license-header/header": ["error", "./resources/license-header.txt"], - - // ------------------------------- - // Custom syntax we want to forbid - // ------------------------------- - "no-restricted-syntax": [ - "error", - // Protocol types should be imported from ~/protocol - { - selector: - "ImportDeclaration[source.value='@liveblocks/core'] > ImportSpecifier[imported.name=/Op$/]", - message: "Import Op types from `~/protocol`, not core.", - }, - { - selector: - "ImportDeclaration[source.value='@liveblocks/core'] > ImportSpecifier[imported.name=/ClientMsg$/]", - message: "Import ClientMsg types from `~/protocol`, not core.", - }, - { - selector: - "ImportDeclaration[source.value='@liveblocks/core'] > ImportSpecifier[imported.name=/ServerMsg$/]", - message: "Import ServerMsg types from `~/protocol`, not core.", - }, - ], - }, - - overrides: [ - { - // Allow imports from @liveblocks/core in protocol files (they re-export) - files: ["src/protocol/**"], - rules: { - "no-restricted-syntax": "off", - }, - }, - ], -}; diff --git a/packages/liveblocks-server/eslint.config.mjs b/packages/liveblocks-server/eslint.config.mjs new file mode 100644 index 00000000000..b7b9960e425 --- /dev/null +++ b/packages/liveblocks-server/eslint.config.mjs @@ -0,0 +1,54 @@ +import { makeConfig } from "@liveblocks/eslint-config"; +import licenseHeader from "eslint-plugin-license-header"; + +export default [ + ...makeConfig(), + + { + plugins: { + "license-header": licenseHeader, + }, + rules: { + "license-header/header": ["error", "./resources/license-header.txt"], + + // ------------------------------- + // Custom syntax we want to forbid + // ------------------------------- + "no-restricted-syntax": [ + "error", + // Protocol types should be imported from ~/protocol + { + selector: + "ImportDeclaration[source.value='@liveblocks/core'] > ImportSpecifier[imported.name=/Op$/]", + message: "Import Op types from `~/protocol`, not core.", + }, + { + selector: + "ImportDeclaration[source.value='@liveblocks/core'] > ImportSpecifier[imported.name=/ClientMsg$/]", + message: "Import ClientMsg types from `~/protocol`, not core.", + }, + { + selector: + "ImportDeclaration[source.value='@liveblocks/core'] > ImportSpecifier[imported.name=/ServerMsg$/]", + message: "Import ServerMsg types from `~/protocol`, not core.", + }, + ], + }, + }, + + // Allow imports from @liveblocks/core in protocol files (they re-export) + { + files: ["src/protocol/**"], + rules: { + "no-restricted-syntax": "off", + }, + }, + + // Special config for test files + { + files: ["test/**", "**/*.test.ts", "**/*.test.tsx"], + rules: { + "@typescript-eslint/explicit-module-boundary-types": "off", + }, + }, +]; diff --git a/packages/liveblocks-server/package.json b/packages/liveblocks-server/package.json index 7e27704db13..28746be4d66 100644 --- a/packages/liveblocks-server/package.json +++ b/packages/liveblocks-server/package.json @@ -50,12 +50,10 @@ "@liveblocks/eslint-config": "workspace:*", "@liveblocks/jest-config": "workspace:*", "@types/node": "^24.12.2", - "@typescript-eslint/eslint-plugin": "^8.57.1", - "@typescript-eslint/parser": "^8.57.1", - "eslint": "^8.56.0", - "eslint-plugin-import": "^2.29.1", - "eslint-plugin-license-header": "^0.8.0", - "eslint-plugin-simple-import-sort": "^10.0.0", + "eslint": "^9.39.4", + "eslint-plugin-import": "^2.32.0", + "eslint-plugin-license-header": "^0.9.0", + "eslint-plugin-simple-import-sort": "^13.0.0", "fast-check": "^3.23.2", "prettier": "^3.3.2", "publint": "^0.3.17", diff --git a/packages/liveblocks-server/src/Room.ts b/packages/liveblocks-server/src/Room.ts index 6081a99206c..ed36f73e5f1 100644 --- a/packages/liveblocks-server/src/Room.ts +++ b/packages/liveblocks-server/src/Room.ts @@ -1467,7 +1467,6 @@ export class Room { * @internal * Handles an incoming ping, by sending a pong back. */ - // eslint-disable-next-line @typescript-eslint/require-await private async handlePing(sessionKey: SessionKey, ctx?: C): Promise { const session = this.sessions.get(sessionKey); if (session === undefined) { diff --git a/packages/liveblocks-server/src/Storage.ts b/packages/liveblocks-server/src/Storage.ts index 86dd775be51..fb3663decc2 100644 --- a/packages/liveblocks-server/src/Storage.ts +++ b/packages/liveblocks-server/src/Storage.ts @@ -266,9 +266,7 @@ export class Storage { // No conflict, node got inserted as intended return accept(op); - } - // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition - else if (intent === "set") { + } else if (intent === "set") { // The intent here is to "set", not insert, into the list, replacing the // existing item that diff --git a/packages/liveblocks-server/src/lib/DefaultMap.ts b/packages/liveblocks-server/src/lib/DefaultMap.ts index ef9697e58f7..4ffa1d82e9d 100644 --- a/packages/liveblocks-server/src/lib/DefaultMap.ts +++ b/packages/liveblocks-server/src/lib/DefaultMap.ts @@ -54,7 +54,6 @@ export class DefaultMap extends Map { */ getOrCreate(key: K, defaultFn?: (key: K) => V): V { if (super.has(key)) { - // eslint-disable-next-line no-restricted-syntax return super.get(key)!; } else { const fn = diff --git a/packages/liveblocks-server/src/lib/Logger.ts b/packages/liveblocks-server/src/lib/Logger.ts index 447290051ab..e1b5f94a3b3 100644 --- a/packages/liveblocks-server/src/lib/Logger.ts +++ b/packages/liveblocks-server/src/lib/Logger.ts @@ -183,13 +183,11 @@ export class Logger { }); this.o = { - /* eslint-disable @typescript-eslint/no-unsafe-enum-comparison */ debug: minLevel <= LogLevel.DEBUG ? makeLogFn(LogLevel.DEBUG) : undefined, info: minLevel <= LogLevel.INFO ? makeLogFn(LogLevel.INFO) : undefined, warn: minLevel <= LogLevel.WARNING ? makeLogFn(LogLevel.WARNING) : undefined, error: minLevel <= LogLevel.ERROR ? makeLogFn(LogLevel.ERROR) : undefined, - /* eslint-enable @typescript-eslint/no-unsafe-enum-comparison */ }; this.debug = this.o.debug ?? noop; diff --git a/packages/liveblocks-server/test/plugins/_generateFullTestSuite.ts b/packages/liveblocks-server/test/plugins/_generateFullTestSuite.ts index a75c1796b08..bed1561d27b 100644 --- a/packages/liveblocks-server/test/plugins/_generateFullTestSuite.ts +++ b/packages/liveblocks-server/test/plugins/_generateFullTestSuite.ts @@ -122,9 +122,8 @@ function expectToThrow(fn: () => Awaitable, errorPattern: RegExp) { } // SYNC-SLOT: directives -/* eslint-disable no-restricted-syntax */ -/* eslint-disable @typescript-eslint/explicit-module-boundary-types */ -/* eslint-disable @typescript-eslint/no-unnecessary-type-assertion */ +/* eslint-disable @typescript-eslint/no-unsafe-assignment */ +/* eslint-disable @typescript-eslint/await-thenable */ // SYNC-SLOT-END: directives const KNOWN_DOC_KEYS = ["root", "0:do", "0:dl", "0:dm"]; @@ -208,12 +207,9 @@ export async function selfCheck(storage: Storage): Promise { for (const [id, node] of inMemoryNodes) { if (id === "root") { assert(node.parentId === undefined, "Root node must have no parent ID", id, node); // prettier-ignore - - // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition assert(node.parentKey === undefined, "Root node must have no parent key", id, node); // prettier-ignore } else { assert(node.parentId !== undefined, `Node ${quote(id)} is missing parent ID`); // prettier-ignore - // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition assert(node.parentKey !== undefined, `Node ${quote(id)} is missing parent key`); // prettier-ignore const parentId = nn(node.parentId); @@ -356,7 +352,6 @@ function plainLsonTreeToNodeMap( plainLson.data.forEach((child) => { recurse(child, id, uniqPositions.next().value); }); - // eslint-disable-next-line } else if (plainLson.liveblocksType === "LiveMap") { result.push([id, { type: CrdtType.MAP, parentId, parentKey }]); @@ -1071,7 +1066,6 @@ export function generateFullTestSuite(config: { // Call next_actor 1000 times concurrently const actors = new Set( await Promise.all( - // eslint-disable-next-line @typescript-eslint/await-thenable -- Awaitable is fine with Promise.all Array.from({ length: 1000 }).map(() => driver.next_actor()) ) ); @@ -2157,8 +2151,9 @@ export function generateFullTestSuite(config: { // Snapshot should return the same data as the driver for (const [id] of entries) { - // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument - expect(snapshot.get_node(id)).toEqual(db.get_node(id) as any); + expect(snapshot.get_node(id)).toEqual( + db.get_node(id) as SerializedChild + ); } } ) @@ -2865,7 +2860,6 @@ export function generateFullTestSuite(config: { async (entries) => { // Write all the entries (can have dupes) await Promise.all( - // eslint-disable-next-line @typescript-eslint/await-thenable -- Awaitable is fine with Promise.all Array.from(entries).map(([key, value]) => driver.put_meta(key, value) ) @@ -3305,7 +3299,6 @@ export function generateFullTestSuite(config: { async (entries) => { // Put all sessions concurrently await Promise.all( - // eslint-disable-next-line @typescript-eslint/await-thenable -- Awaitable is fine with Promise.all Array.from(entries).map(([sessionId, session]) => { session.sessionId = sessionId; return driver.put_leased_session(session); @@ -3314,7 +3307,6 @@ export function generateFullTestSuite(config: { // Verify all sessions exist const results = await Promise.all( - // eslint-disable-next-line @typescript-eslint/await-thenable -- Awaitable is fine with Promise.all Array.from(entries.keys()).map((sessionId) => driver.get_leased_session(sessionId) ) @@ -3328,7 +3320,6 @@ export function generateFullTestSuite(config: { // Cleanup: delete all sessions added in this iteration await Promise.all( - // eslint-disable-next-line @typescript-eslint/await-thenable -- Awaitable is fine with Promise.all Array.from(entries.keys()).map((sessionId) => driver.delete_leased_session(sessionId) ) @@ -4582,7 +4573,6 @@ export function generateFullTestSuite(config: { parentKey: SECOND_POSITION, }, // NOTE: Fix ops are generated server-side and don't preserve the input opId - // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment fix: expect.objectContaining({ type: OpCode.SET_PARENT_KEY, id: "1:0", @@ -4735,7 +4725,6 @@ export function generateFullTestSuite(config: { parentKey: SECOND_POSITION, }, // NOTE: Fix ops are generated server-side and don't preserve the input opId - // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment fix: expect.objectContaining({ type: OpCode.SET_PARENT_KEY, id: "1:0", @@ -4821,7 +4810,6 @@ export function generateFullTestSuite(config: { parentKey: THIRD_POSITION, }, // NOTE: Fix ops are generated server-side and don't preserve the input opId - // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment fix: expect.objectContaining({ type: OpCode.SET_PARENT_KEY, id: "0:2", @@ -4986,7 +4974,6 @@ export function generateFullTestSuite(config: { parentKey: SECOND_POSITION, }, // NOTE: Fix ops are generated server-side and don't preserve the input opId - // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment fix: expect.objectContaining({ type: OpCode.SET_PARENT_KEY, id: "1:0", @@ -5078,7 +5065,6 @@ export function generateFullTestSuite(config: { parentKey: expectedPosition, }, // NOTE: Fix ops are generated server-side and don't preserve the input opId - // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment fix: expect.objectContaining({ type: OpCode.SET_PARENT_KEY, id: "1:0", @@ -5269,7 +5255,6 @@ export function generateFullTestSuite(config: { parentKey: SECOND_POSITION, }, // NOTE: Fix ops are generated server-side and don't preserve the input opId - // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment fix: expect.objectContaining({ type: OpCode.SET_PARENT_KEY, id: "1:0", @@ -5351,7 +5336,6 @@ export function generateFullTestSuite(config: { // make sure that it won't lead to two clients seeing different // state. // - // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment fix: expect.objectContaining({ type: OpCode.DELETE_CRDT, id: "0:2", diff --git a/packages/liveblocks-server/test/storage/model-based/storage-model.ts b/packages/liveblocks-server/test/storage/model-based/storage-model.ts index 3e9a4e1cdab..d83fd0a6e2f 100644 --- a/packages/liveblocks-server/test/storage/model-based/storage-model.ts +++ b/packages/liveblocks-server/test/storage/model-based/storage-model.ts @@ -15,7 +15,6 @@ * along with this program. If not, see . */ -/* eslint-disable @typescript-eslint/explicit-module-boundary-types */ import type { NodeStream, SerializedCrdt } from "@liveblocks/core"; import { assertNever, CrdtType, OpCode } from "@liveblocks/core"; import * as fc from "fast-check"; diff --git a/tools/liveblocks-cli/.eslintrc.cjs b/tools/liveblocks-cli/.eslintrc.cjs deleted file mode 100644 index 898c450354e..00000000000 --- a/tools/liveblocks-cli/.eslintrc.cjs +++ /dev/null @@ -1,57 +0,0 @@ -/** - * Copyright (c) Liveblocks Inc. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -module.exports = { - parser: "@typescript-eslint/parser", - plugins: ["license-header"], - rules: { - "license-header/header": ["error", "./resources/license-header.txt"], - }, - overrides: [ - { - files: ["src/**/*.ts", "test/**/*.ts"], - extends: ["@liveblocks/eslint-config"], - rules: { - // Import sorting - "import/no-duplicates": "error", - "@typescript-eslint/consistent-type-imports": "error", - "simple-import-sort/imports": "error", - "simple-import-sort/exports": "error", - - // Op/ClientMsg/ServerMsg imports should come from @liveblocks/server - "no-restricted-syntax": [ - "error", - { - selector: - "ImportDeclaration[source.value='@liveblocks/core'] > ImportSpecifier[imported.name=/Op$/]", - message: "Import Op types from `@liveblocks/server`, not core.", - }, - { - selector: - "ImportDeclaration[source.value='@liveblocks/core'] > ImportSpecifier[imported.name='ClientMsg']", - message: "Import `ClientMsg` from `@liveblocks/server`, not core.", - }, - { - selector: - "ImportDeclaration[source.value='@liveblocks/core'] > ImportSpecifier[imported.name='ServerMsg']", - message: "Import `ServerMsg` from `@liveblocks/server`, not core.", - }, - ], - }, - }, - ], -}; diff --git a/tools/liveblocks-cli/eslint.config.mjs b/tools/liveblocks-cli/eslint.config.mjs new file mode 100644 index 00000000000..6d568e8ac62 --- /dev/null +++ b/tools/liveblocks-cli/eslint.config.mjs @@ -0,0 +1,71 @@ +/** + * Copyright (c) Liveblocks Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +import { makeConfig } from "@liveblocks/eslint-config"; +import licenseHeader from "eslint-plugin-license-header"; + +export default [ + ...makeConfig(), + + { + plugins: { + "license-header": licenseHeader, + }, + rules: { + "license-header/header": ["error", "./resources/license-header.txt"], + }, + }, + + { + files: ["src/**/*.ts", "test/**/*.ts"], + rules: { + // Import sorting + "import/no-duplicates": "error", + "@typescript-eslint/consistent-type-imports": "error", + "simple-import-sort/imports": "error", + "simple-import-sort/exports": "error", + + // Op/ClientMsg/ServerMsg imports should come from @liveblocks/server + "no-restricted-syntax": [ + "error", + { + selector: + "ImportDeclaration[source.value='@liveblocks/core'] > ImportSpecifier[imported.name=/Op$/]", + message: "Import Op types from `@liveblocks/server`, not core.", + }, + { + selector: + "ImportDeclaration[source.value='@liveblocks/core'] > ImportSpecifier[imported.name='ClientMsg']", + message: "Import `ClientMsg` from `@liveblocks/server`, not core.", + }, + { + selector: + "ImportDeclaration[source.value='@liveblocks/core'] > ImportSpecifier[imported.name='ServerMsg']", + message: "Import `ServerMsg` from `@liveblocks/server`, not core.", + }, + ], + }, + }, + + // Special config for test files + { + files: ["test/**/*.ts", "**/*.test.ts", "**/*.test.tsx"], + rules: { + "@typescript-eslint/explicit-module-boundary-types": "off", + }, + }, +]; diff --git a/tools/liveblocks-cli/package.json b/tools/liveblocks-cli/package.json index 72a2f44713c..59ed2d5e65f 100644 --- a/tools/liveblocks-cli/package.json +++ b/tools/liveblocks-cli/package.json @@ -34,13 +34,11 @@ "devDependencies": { "@arethetypeswrong/cli": "^0.18.2", "@liveblocks/eslint-config": "workspace:*", - "@typescript-eslint/eslint-plugin": "^8.57.1", - "@typescript-eslint/parser": "^8.57.1", "bun-types": "^1.3.9", - "eslint": "^8.56.0", - "eslint-plugin-import": "^2.29.1", - "eslint-plugin-license-header": "^0.8.0", - "eslint-plugin-simple-import-sort": "^10.0.0", + "eslint": "^9.39.4", + "eslint-plugin-import": "^2.32.0", + "eslint-plugin-license-header": "^0.9.0", + "eslint-plugin-simple-import-sort": "^13.0.0", "fast-check": "^3.23.2", "itertools": "^2.3.2", "prettier": "^3.3.2", diff --git a/tools/liveblocks-cli/src/dev-server/lib/ydoc.ts b/tools/liveblocks-cli/src/dev-server/lib/ydoc.ts index 767485f3570..9533c0654c4 100644 --- a/tools/liveblocks-cli/src/dev-server/lib/ydoc.ts +++ b/tools/liveblocks-cli/src/dev-server/lib/ydoc.ts @@ -80,7 +80,7 @@ function getYTypedValue( return doc.getXmlFragment(key).toJSON(); } } - // eslint-disable-next-line @typescript-eslint/no-unsafe-return, @typescript-eslint/no-unsafe-call + // eslint-disable-next-line @typescript-eslint/no-unsafe-return return value.toJSON(); } @@ -115,7 +115,6 @@ export function yDocToJson( } } return { - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion [key]: getYTypedValue(doc, doc.share.get(key)!, key, formatting), }; } diff --git a/tools/liveblocks-cli/src/lib/args.ts b/tools/liveblocks-cli/src/lib/args.ts index 6734a86e347..8520642acb2 100644 --- a/tools/liveblocks-cli/src/lib/args.ts +++ b/tools/liveblocks-cli/src/lib/args.ts @@ -37,7 +37,6 @@ type OptionDef = Optional extends true type OptionDefs = { [K in keyof T]-?: OptionDef< NonNullable, - // eslint-disable-next-line @typescript-eslint/no-empty-object-type -- intentional {} extends Pick ? true : false >; }; diff --git a/tools/liveblocks-cli/test/plugins/_generateFullTestSuite.ts b/tools/liveblocks-cli/test/plugins/_generateFullTestSuite.ts index 0d79ef9fefc..135c6e189f0 100644 --- a/tools/liveblocks-cli/test/plugins/_generateFullTestSuite.ts +++ b/tools/liveblocks-cli/test/plugins/_generateFullTestSuite.ts @@ -128,9 +128,7 @@ function expectToThrow(fn: () => Awaitable, errorPattern: RegExp) { } // SYNC-SLOT: directives -/* eslint-disable no-restricted-syntax */ -/* eslint-disable @typescript-eslint/explicit-module-boundary-types */ -/* eslint-disable @typescript-eslint/no-unnecessary-type-assertion */ +/* eslint-disable @typescript-eslint/no-unsafe-assignment */ /* eslint-disable @typescript-eslint/await-thenable */ // SYNC-SLOT-END: directives @@ -215,12 +213,9 @@ export async function selfCheck(storage: Storage): Promise { for (const [id, node] of inMemoryNodes) { if (id === "root") { assert(node.parentId === undefined, "Root node must have no parent ID", id, node); // prettier-ignore - - // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition assert(node.parentKey === undefined, "Root node must have no parent key", id, node); // prettier-ignore } else { assert(node.parentId !== undefined, `Node ${quote(id)} is missing parent ID`); // prettier-ignore - // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition assert(node.parentKey !== undefined, `Node ${quote(id)} is missing parent key`); // prettier-ignore const parentId = nn(node.parentId); @@ -363,7 +358,6 @@ function plainLsonTreeToNodeMap( plainLson.data.forEach((child) => { recurse(child, id, uniqPositions.next().value); }); - // eslint-disable-next-line } else if (plainLson.liveblocksType === "LiveMap") { result.push([id, { type: CrdtType.MAP, parentId, parentKey }]); @@ -1078,7 +1072,6 @@ export function generateFullTestSuite(config: { // Call next_actor 1000 times concurrently const actors = new Set( await Promise.all( - // eslint-disable-next-line @typescript-eslint/await-thenable -- Awaitable is fine with Promise.all Array.from({ length: 1000 }).map(() => driver.next_actor()) ) ); @@ -2164,8 +2157,9 @@ export function generateFullTestSuite(config: { // Snapshot should return the same data as the driver for (const [id] of entries) { - // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument - expect(snapshot.get_node(id)).toEqual(db.get_node(id) as any); + expect(snapshot.get_node(id)).toEqual( + db.get_node(id) as SerializedChild + ); } } ) @@ -2872,7 +2866,6 @@ export function generateFullTestSuite(config: { async (entries) => { // Write all the entries (can have dupes) await Promise.all( - // eslint-disable-next-line @typescript-eslint/await-thenable -- Awaitable is fine with Promise.all Array.from(entries).map(([key, value]) => driver.put_meta(key, value) ) @@ -3312,7 +3305,6 @@ export function generateFullTestSuite(config: { async (entries) => { // Put all sessions concurrently await Promise.all( - // eslint-disable-next-line @typescript-eslint/await-thenable -- Awaitable is fine with Promise.all Array.from(entries).map(([sessionId, session]) => { session.sessionId = sessionId; return driver.put_leased_session(session); @@ -3321,7 +3313,6 @@ export function generateFullTestSuite(config: { // Verify all sessions exist const results = await Promise.all( - // eslint-disable-next-line @typescript-eslint/await-thenable -- Awaitable is fine with Promise.all Array.from(entries.keys()).map((sessionId) => driver.get_leased_session(sessionId) ) @@ -3335,7 +3326,6 @@ export function generateFullTestSuite(config: { // Cleanup: delete all sessions added in this iteration await Promise.all( - // eslint-disable-next-line @typescript-eslint/await-thenable -- Awaitable is fine with Promise.all Array.from(entries.keys()).map((sessionId) => driver.delete_leased_session(sessionId) ) @@ -4589,7 +4579,6 @@ export function generateFullTestSuite(config: { parentKey: SECOND_POSITION, }, // NOTE: Fix ops are generated server-side and don't preserve the input opId - // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment fix: expect.objectContaining({ type: OpCode.SET_PARENT_KEY, id: "1:0", @@ -4742,7 +4731,6 @@ export function generateFullTestSuite(config: { parentKey: SECOND_POSITION, }, // NOTE: Fix ops are generated server-side and don't preserve the input opId - // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment fix: expect.objectContaining({ type: OpCode.SET_PARENT_KEY, id: "1:0", @@ -4828,7 +4816,6 @@ export function generateFullTestSuite(config: { parentKey: THIRD_POSITION, }, // NOTE: Fix ops are generated server-side and don't preserve the input opId - // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment fix: expect.objectContaining({ type: OpCode.SET_PARENT_KEY, id: "0:2", @@ -4993,7 +4980,6 @@ export function generateFullTestSuite(config: { parentKey: SECOND_POSITION, }, // NOTE: Fix ops are generated server-side and don't preserve the input opId - // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment fix: expect.objectContaining({ type: OpCode.SET_PARENT_KEY, id: "1:0", @@ -5085,7 +5071,6 @@ export function generateFullTestSuite(config: { parentKey: expectedPosition, }, // NOTE: Fix ops are generated server-side and don't preserve the input opId - // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment fix: expect.objectContaining({ type: OpCode.SET_PARENT_KEY, id: "1:0", @@ -5276,7 +5261,6 @@ export function generateFullTestSuite(config: { parentKey: SECOND_POSITION, }, // NOTE: Fix ops are generated server-side and don't preserve the input opId - // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment fix: expect.objectContaining({ type: OpCode.SET_PARENT_KEY, id: "1:0", @@ -5358,7 +5342,6 @@ export function generateFullTestSuite(config: { // make sure that it won't lead to two clients seeing different // state. // - // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment fix: expect.objectContaining({ type: OpCode.DELETE_CRDT, id: "0:2",