From eb6595fa5d5f8685ca8270f8e3f220ed7a1d1f2f Mon Sep 17 00:00:00 2001 From: Joe Hanley Date: Wed, 23 Sep 2026 00:09:17 +0000 Subject: [PATCH 1/2] fix(lint): modernize string and array checks with prefer-includes and prefer-string-starts-ends-with Modernizes legacy indexOf and RegExp membership/prefix checks to prefer-includes and prefer-string-starts-ends-with across 9 files. Promotes @typescript-eslint/prefer-includes and @typescript-eslint/prefer-string-starts-ends-with from 'warn' to 'error' in .eslintrc.js. b/565073781 --- .eslintrc.js | 4 ++-- src/apphosting/backend.ts | 2 +- src/deploy/firestore/prepare.ts | 10 +++++----- src/emulator/apphosting/serve.ts | 2 +- src/emulator/auth/utils.ts | 2 +- src/emulator/dataconnect/pgliteServer.ts | 2 +- src/emulator/download.ts | 2 +- src/emulator/downloadableEmulators.ts | 2 +- src/firestore/validator.ts | 2 +- src/profileReport.ts | 4 +--- 10 files changed, 15 insertions(+), 17 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index 29211759011..02b3f54753d 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -67,9 +67,9 @@ module.exports = { "@typescript-eslint/no-unsafe-return": "warn", // TODO(bkendall): remove, allow to error. "@typescript-eslint/no-use-before-define": ["warn", { functions: false, typedefs: false }], // TODO(bkendall): change to error. "@typescript-eslint/no-var-requires": "warn", // TODO(bkendall): remove, allow to error. - "@typescript-eslint/prefer-includes": "warn", // TODO(bkendall): remove, allow to error. + "@typescript-eslint/prefer-includes": "error", "@typescript-eslint/prefer-regexp-exec": "warn", // TODO(bkendall): remove, allow to error. - "@typescript-eslint/prefer-string-starts-ends-with": "warn", // TODO(bkendall): remove, allow to error. + "@typescript-eslint/prefer-string-starts-ends-with": "error", "@typescript-eslint/restrict-plus-operands": "warn", // TODO(bkendall): remove, allow to error. "@typescript-eslint/restrict-template-expressions": "warn", // TODO(bkendall): remove, allow to error. "no-case-declarations": "warn", // TODO(bkendall): remove, allow to error. diff --git a/src/apphosting/backend.ts b/src/apphosting/backend.ts index 2dccef1f1d1..2a298a0ef4e 100644 --- a/src/apphosting/backend.ts +++ b/src/apphosting/backend.ts @@ -50,7 +50,7 @@ async function tlsReady(url: string): Promise { // SSL. const maybeNodeError = err as { cause: { code: string }; code: string }; if ( - /HANDSHAKE_FAILURE/.test(maybeNodeError?.cause?.code) || + maybeNodeError?.cause?.code?.includes("HANDSHAKE_FAILURE") || "EPROTO" === maybeNodeError?.code ) { return false; diff --git a/src/deploy/firestore/prepare.ts b/src/deploy/firestore/prepare.ts index d562749bec1..8dee38dea71 100644 --- a/src/deploy/firestore/prepare.ts +++ b/src/deploy/firestore/prepare.ts @@ -156,15 +156,15 @@ export default async function (context: any, options: DeployOptions): Promise= 0; - const excludeIndexes = targets.indexOf("firestore:rules") >= 0; + const excludeRules = targets.includes("firestore:indexes"); + const excludeIndexes = targets.includes("firestore:rules"); // Used for edge case when deploying --only firestore:rules,firestore:indexes // https://github.com/firebase/firebase-tools/issues/6857 - const includeRules = targets.indexOf("firestore:rules") >= 0; - const includeIndexes = targets.indexOf("firestore:indexes") >= 0; + const includeRules = targets.includes("firestore:rules"); + const includeIndexes = targets.includes("firestore:indexes"); - const onlyFirestore = targets.indexOf("firestore") >= 0; + const onlyFirestore = targets.includes("firestore"); context.firestoreIndexes = !excludeIndexes || includeIndexes || onlyFirestore; context.firestoreRules = !excludeRules || includeRules || onlyFirestore; diff --git a/src/emulator/apphosting/serve.ts b/src/emulator/apphosting/serve.ts index 8f4a66d91fa..0fa41b74646 100644 --- a/src/emulator/apphosting/serve.ts +++ b/src/emulator/apphosting/serve.ts @@ -173,7 +173,7 @@ async function tripFirebasePostinstall( if ( dependency.name === "@firebase/util" && semverGte(dependency.version, "1.11.0") && - firebaseUtilPaths.indexOf(dependency.path) === -1 + !firebaseUtilPaths.includes(dependency.path) ) { firebaseUtilPaths.push(dependency.path); } diff --git a/src/emulator/auth/utils.ts b/src/emulator/auth/utils.ts index ae535d23349..fe1e26ecfda 100644 --- a/src/emulator/auth/utils.ts +++ b/src/emulator/auth/utils.ts @@ -57,7 +57,7 @@ export function isValidPhoneNumber(phoneNumber: string): boolean { // is not worth the effort and bloat (500+ kB). libphonenumber-js is not used // either since it has different behaviors and may block numbers that are // valid in production. - return /^\+/.test(phoneNumber); + return phoneNumber.startsWith("+"); } /** diff --git a/src/emulator/dataconnect/pgliteServer.ts b/src/emulator/dataconnect/pgliteServer.ts index ebc2bf729ec..1e8daf0a0fc 100644 --- a/src/emulator/dataconnect/pgliteServer.ts +++ b/src/emulator/dataconnect/pgliteServer.ts @@ -235,7 +235,7 @@ export class PostgresServer { await db.waitReady; return db; } catch (err: unknown) { - if (pg17Dir && hasMessage(err) && /Database already exists/.test(err.message)) { + if (pg17Dir && hasMessage(err) && err.message.includes("Database already exists")) { // Clear out the current pglite data fs.rmSync(pg17Dir, { force: true, recursive: true }); const db = new PGlite({ ...baseArgs, dataDir: pg17Dir }); diff --git a/src/emulator/download.ts b/src/emulator/download.ts index f8132a3e186..eb5b09bb255 100644 --- a/src/emulator/download.ts +++ b/src/emulator/download.ts @@ -112,7 +112,7 @@ function removeOldFiles( for (const file of files) { const fullFilePath = path.join(emulator.opts.cacheDir, file); - if (file.indexOf(emulator.opts.namePrefix) < 0) { + if (!file.includes(emulator.opts.namePrefix)) { // This file is not related to this emulator, could be a JAR // from a different emulator or just a random file. continue; diff --git a/src/emulator/downloadableEmulators.ts b/src/emulator/downloadableEmulators.ts index f36524999f1..6b76d070407 100755 --- a/src/emulator/downloadableEmulators.ts +++ b/src/emulator/downloadableEmulators.ts @@ -656,7 +656,7 @@ export async function start( export function isIncomaptibleArchError(err: unknown): boolean { return ( hasMessage(err) && - /Unknown system error/.test(err.message ?? "") && + (err.message ?? "").includes("Unknown system error") && process.platform === "darwin" ); } diff --git a/src/firestore/validator.ts b/src/firestore/validator.ts index b3d4a7a43a2..98d11a2494b 100644 --- a/src/firestore/validator.ts +++ b/src/firestore/validator.ts @@ -35,7 +35,7 @@ export function assertHasOneOf(obj: any, props: string[]): void { */ export function assertEnum(obj: any, prop: string, valid: any[]): void { const objString = clc.cyan(JSON.stringify(obj)); - if (valid.indexOf(obj[prop]) < 0) { + if (!valid.includes(obj[prop])) { throw new FirebaseError(`Field "${prop}" must be one of ${valid.join(", ")}: ${objString}`); } } diff --git a/src/profileReport.ts b/src/profileReport.ts index 61fa4d39486..0d3f650a17d 100644 --- a/src/profileReport.ts +++ b/src/profileReport.ts @@ -7,8 +7,6 @@ import * as readline from "readline"; import { FirebaseError } from "./error"; import { logger } from "./logger"; -const DATA_LINE_REGEX = /^data: /; - const BANDWIDTH_NOTE = "NOTE: The numbers reported here are only estimates of the data" + " payloads from read operations. They are NOT a valid measure of your bandwidth bill."; @@ -26,7 +24,7 @@ const COLLAPSE_WILDCARD = ["$wildcard"]; // 'static' helper methods export function extractJSON(line: string, input: any): string | null { - if (!input && !DATA_LINE_REGEX.test(line)) { + if (!input && !line.startsWith("data: ")) { return null; } else if (!input) { line = line.substring(5); From 4abdb0b132f6af483fe4efc6f8db3ee08bf1bb1c Mon Sep 17 00:00:00 2001 From: Joe Hanley Date: Thu, 1 Oct 2026 23:00:49 +0000 Subject: [PATCH 2/2] fix: remove prefer-includes and prefer-string-starts-ends-with overrides to use defaults (b/565073781) --- .eslintrc.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index 642494ee25d..df489d9ca48 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -66,9 +66,7 @@ module.exports = { "@typescript-eslint/no-unsafe-return": "warn", // TODO(bkendall): remove, allow to error. "@typescript-eslint/no-use-before-define": ["warn", { functions: false, typedefs: false }], // TODO(bkendall): change to error. "@typescript-eslint/no-var-requires": "warn", // TODO(bkendall): remove, allow to error. - "@typescript-eslint/prefer-includes": "error", "@typescript-eslint/prefer-regexp-exec": "warn", // TODO(bkendall): remove, allow to error. - "@typescript-eslint/prefer-string-starts-ends-with": "error", "@typescript-eslint/restrict-plus-operands": "warn", // TODO(bkendall): remove, allow to error. "@typescript-eslint/restrict-template-expressions": "warn", // TODO(bkendall): remove, allow to error. "no-constant-condition": "warn", // TODO(bkendall): remove, allow to error.