Skip to content

fix(lint): modernize string and array checks with prefer-includes and prefer-string-starts-ends-with - #11146

Open
joehan wants to merge 7 commits into
mainfrom
ai-improve-565073781-task-modernize-string-and-array-che
Open

joehan wants to merge 7 commits into
mainfrom
ai-improve-565073781-task-modernize-string-and-array-che

Conversation

@joehan

@joehan joehan commented Sep 23, 2026

Copy link
Copy Markdown
Member

Description

Modernizes legacy indexOf and RegExp membership and prefix checks across the codebase to use standard String.prototype.includes, Array.prototype.includes, and String.prototype.startsWith. Promotes @typescript-eslint/prefer-includes and @typescript-eslint/prefer-string-starts-ends-with from "warn" to "error" in .eslintrc.js.

Resolves b/565073781 (parent goal b/565072516).

Changes

  • src/apphosting/backend.ts: Converted regex test on error code to maybeNodeError?.cause?.code?.includes("HANDSHAKE_FAILURE").
  • src/deploy/firestore/prepare.ts: Converted 5 targets.indexOf(...) >= 0 checks to targets.includes(...).
  • src/emulator/apphosting/serve.ts: Converted firebaseUtilPaths.indexOf(...) === -1 to !firebaseUtilPaths.includes(...).
  • src/emulator/auth/utils.ts: Converted /^\+/.test(phoneNumber) to phoneNumber.startsWith("+").
  • src/emulator/dataconnect/pgliteServer.ts: Converted regex test to err.message.includes("Database already exists").
  • src/emulator/download.ts: Converted file.indexOf(...) < 0 to !file.includes(...).
  • src/emulator/downloadableEmulators.ts: Converted regex test to (err.message ?? "").includes("Unknown system error").
  • src/firestore/validator.ts: Converted valid.indexOf(...) < 0 to !valid.includes(...).
  • src/profileReport.ts: Converted regex prefix test to !line.startsWith("data: ") and cleaned up unused constant.
  • .eslintrc.js: Promoted @typescript-eslint/prefer-includes and @typescript-eslint/prefer-string-starts-ends-with to "error".

Verification

  • ESLint: verified with 0 errors with rules set to "error".
  • Prettier: formatting verified.
  • npm run build: passed.
  • Mocha unit tests across all modified modules: passed (64 passing, 0 failing).

… 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
@joehan joehan self-assigned this Sep 23, 2026

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request modernizes string and array checks across the codebase by replacing regular expression tests and indexOf calls with modern alternatives like includes and startsWith, and updates ESLint rules to enforce these practices. The review feedback identifies three key issues: a type assertion mismatch in backend.ts where optional chaining is used on supposedly non-nullable types, a redundant nullish coalescing operator in downloadableEmulators.ts where a type guard already guarantees a string, and an off-by-one substring index bug in profileReport.ts resulting from the change to startsWith.

Comment thread src/apphosting/backend.ts
Comment thread src/emulator/downloadableEmulators.ts Outdated
return (
hasMessage(err) &&
/Unknown system error/.test(err.message ?? "") &&
(err.message ?? "").includes("Unknown system error") &&

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Since hasMessage(err) is a type guard that guarantees err.message is a string, the nullish coalescing operator (?? "") is redundant. Removing it simplifies the expression and improves readability.

Suggested change
(err.message ?? "").includes("Unknown system error") &&
err.message.includes("Unknown system error") &&

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed, please fix

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in commit d6542d9: Removed the redundant ?? "" fallback since hasMessage(err) type guard already guarantees that err.message is a string.

Comment thread src/profileReport.ts

export function extractJSON(line: string, input: any): string | null {
if (!input && !DATA_LINE_REGEX.test(line)) {
if (!input && !line.startsWith("data: ")) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Since the prefix check has been modernized to line.startsWith('data: ') (which is 6 characters long), the subsequent line.substring(5) on line 30 is now inconsistent as it leaves a leading space in the string before parsing. Consider updating it to line.substring(6) or line.slice(6) to cleanly remove the entire prefix.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please fix

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in commit d6542d9: Updated line.substring(5) to line.substring(6) to correctly strip the 6-character "data: " prefix matching line.startsWith("data: "). Also added comprehensive unit tests for extractJSON covering SSE and non-SSE cases in src/profileReport.spec.ts.

Comment thread .eslintrc.js Outdated
"@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",

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove so that this just falls back to the default

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed @typescript-eslint/prefer-string-starts-ends-with from .eslintrc.js in commit 4abdb0b so that it falls back to the recommended default.

Comment thread .eslintrc.js Outdated
"@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",

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove so that this just falls back to the default

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed @typescript-eslint/prefer-includes from .eslintrc.js in commit 4abdb0b so that it falls back to the recommended default.

@joehan
joehan marked this pull request as ready for review October 1, 2026 23:15

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants