Skip to content

Upgrade eslint-config-expensify to 4.0.8 - #802

Draft
roryabraham wants to merge 39 commits into
mainfrom
rory-eslint-config-expensify-4
Draft

Upgrade eslint-config-expensify to 4.0.8#802
roryabraham wants to merge 39 commits into
mainfrom
rory-eslint-config-expensify-4

Conversation

@roryabraham

@roryabraham roryabraham commented Jun 19, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Upgrades eslint-config-expensify from 2.0.108 to 4.0.8 and replaces the monolithic import expensify from 'eslint-config-expensify' config with modular sub-configs (browser, react, typescript, jest, scripts), matching the pattern used in expensify-common.
  • Removes the hand-rolled @typescript-eslint plugin/parser block and ~40 per-rule overrides that duplicated what v4 now ships (type imports/exports, import extensions, redeclare handling, JSDoc disables, etc.).
  • Adds eslint-seatbelt with an initial baseline (eslint.seatbelt.tsv) to grandfather existing type-checked violations from the jump to recommendedTypeChecked, without blocking CI.
  • Removes unused direct ESLint plugin dependencies (eslint-plugin-import, eslint-plugin-jsx-a11y, eslint-plugin-react, @typescript-eslint/*, @lwc/eslint-plugin-lwc, @react-native-community/eslint-config) now provided transitively by eslint-config-expensify.
  • Removes stale eslint-disable comments for rules that v4 no longer reports (dot-notation, @typescript-eslint/no-empty-function).

Overrides retained (by category)

Onyx / project-structure specific (intentional):

Override Scope Why
rulesdir/no-multiple-onyx-in-file: off all source This repo is Onyx; tests and mocks intentionally create multiple instances
import/extensions: off tests/**, mocks Test utilities import without extensions
no-restricted-syntax (allow for...of / for...in) tests Tests use iteration patterns blocked by the default airbnb syntax rule
@typescript-eslint/no-require-imports: off **/*.native.ts(x) React Native platform files use require()
globals.jest MemoryOnlyProvider.ts Test-only provider accessed from Jest mocks
globalIgnores for .github/**, dist/**, cpp/**, etc. n/a Bundled GH Action output, build artifacts, and local bench/C++ dirs are not lint targets

Not Onyx-specific (generic library / TypeScript conventions — candidates to remove over time):

Override Why it exists
class-methods-use-this: off Same relaxation App uses for TS/React codebases
es/no-optional-chaining: off Expensify-wide relaxation (Hermes / toolchain compatibility)
es/no-nullish-coalescing-operators: off Expensify-wide relaxation
react/prop-types: off TypeScript project; prop-types are redundant
react/require-default-props: off TypeScript project; default props enforced via types
react/jsx-props-no-spreading: off Library hook/components (useOnyx) spread props intentionally

Deliberately not imported:

  • eslint-config-expensify/expensify — contains App-only rulesdir/* rules (prefer-onyx-connect-in-libs, no-onyx-connect, restricted react-native imports, etc.) that do not apply to this package.

Test plan

CI only.

Linked E/App PR

Expensify/App#95893

Adopt modular v4 flat config with eslint-seatbelt to grandfather
type-checked violations while removing the bespoke TypeScript plugin
setup and App-specific rulesdir overrides from the old monolithic config.

Co-authored-by: Cursor <cursoragent@cursor.com>
roryabraham and others added 18 commits June 19, 2026 11:45
Base config already allows ?? and ?. in TypeScript and bans them only
in JavaScript via file-scoped rules in es6.js.

Co-authored-by: Cursor <cursoragent@cursor.com>
Drop the local class-methods-use-this override now that react.js no
longer re-enables the rule disabled in style.js.

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
- Drop no-restricted-syntax from tests block (browserConfig already
  sets the same 3 restrictions globally)
- Drop react/jsx-props-no-spreading: off (not enabled by any upstream
  config; was a no-op)
- Drop rulesdir/no-multiple-onyx-in-file: off (not enabled by any
  upstream config; was a no-op)
- Drop @typescript-eslint/no-require-imports: off for .native.ts
  (tsExpensifyConfig already turns it off for all *.ts/*.tsx globally)

Co-authored-by: Cursor <cursoragent@cursor.com>
Autofixes applied:
- rulesdir/prefer-at: arr[N] → arr.at(N)
- @typescript-eslint/dot-notation: obj['prop'] → obj.prop
- @typescript-eslint/non-nullable-type-assertion-style: as NonNullable<T> → !
- @typescript-eslint/no-unnecessary-type-assertion: remove redundant casts
- @typescript-eslint/prefer-nullish-coalescing: || → ?? where applicable
- jsdoc/no-types: remove JSDoc type annotations in TS files

Follow-up fixes for autofix side-effects:
- Remove GenericCollection/OnyxInput unused imports made orphaned
  by the removal of type assertions that were their only usage
- Add no-non-null-assertion seatbelt entries for the four files
  where non-nullable-type-assertion-style converted as NonNullable<T> → !
- Update seatbelt for newly surfaced unbound-method and unsafe-*
  counts in OnyxConnectionManager and OnyxCache perf-test files

Co-authored-by: Cursor <cursoragent@cursor.com>
Configure Node globals for CJS config files, disable
no-use-before-define in OnyxUtils, and relax test naming
rules for collection key object properties.

Co-authored-by: Cursor <cursoragent@cursor.com>
Use lodash.bindall and inline noop instead of umbrella
lodash subpath imports that fail extraneous-deps.

Co-authored-by: Cursor <cursoragent@cursor.com>
Type getItem with void key usage and hoist handlers outside
the connect loop to satisfy no-loop-func.

Co-authored-by: Cursor <cursoragent@cursor.com>
Resolve template expressions, nullish coalescing, non-null
assertions in lib code, unbound-method in tests, and type
cleanup across OnyxUtils, merge, and utils. Update seatbelt
to drop fixed suppressions while keeping test-only allowances.

Co-authored-by: Cursor <cursoragent@cursor.com>
…pensify-4

Co-authored-by: Cursor <cursoragent@cursor.com>

# Conflicts:
#	lib/OnyxConnectionManager.ts
#	lib/OnyxUtils.ts
#	tests/unit/OnyxConnectionManagerTest.ts
#	tests/unit/collectionHydrationTest.ts
#	tests/unit/onyxTest.ts
#	tests/unit/onyxUtilsTest.ts
Restore variadic noop stubs for InstanceSync, correct the circuit
breaker halfOpen state check, guard indexed key lookups, and add
lodash.bindall type declarations so prepare/build succeeds in CI.

Co-authored-by: Cursor <cursoragent@cursor.com>
Remove stale seatbelt entries for dropped no-unsafe-argument rule,
restore CustomTypeOptions as an augmentable interface for test:types,
fix private property access and collection typing in tests, and restore
IDB abort mocks so write-error normalization tests propagate DOMException.

Co-authored-by: Cursor <cursoragent@cursor.com>
Sync seatbelt counts, add perf-test prefer-at override, restore
CustomTypeOptions interface augmentation, fix typecheck issues in perf
and storage provider tests, and resolve OnyxConnectionManager seatbelt rules.

Co-authored-by: Cursor <cursoragent@cursor.com>
Add seatbelt entries for new rule violations, disable dot-notation in
tests that access private APIs, and restore no-unsafe-argument budget.

Co-authored-by: Cursor <cursoragent@cursor.com>
Dot-notation is disabled for test files globally, so the per-line
directives were unused and caused lint to fail CI.

Co-authored-by: Cursor <cursoragent@cursor.com>
Replace the local lodash.bindall module shim with the official
DefinitelyTyped package now that imports use lodash.bindall directly.

Co-authored-by: Cursor <cursoragent@cursor.com>
Drop dot-notation and prefer-at disables for tests; use typed test
harnesses for private member access, getAtIndex for array indexing, and
restore useLiveRef deprecation with seatbelt-documented exceptions.

Co-authored-by: Cursor <cursoragent@cursor.com>
@roryabraham roryabraham changed the title Upgrade eslint-config-expensify to 4.0.5 Upgrade eslint-config-expensify to 4.0.6 Jul 3, 2026
roryabraham and others added 5 commits July 2, 2026 17:01
Use unknown intermediate casts and ConnectOptions for
generateConnectionID so test harness types match the real API.

Co-authored-by: Cursor <cursoragent@cursor.com>
Fix lint CI prettier diff check after typecheck harness changes.

Co-authored-by: Cursor <cursoragent@cursor.com>
The shared typescript config does not lint typeProperty, so the
snake_case exception had no effect. Document why the tests override
must repeat the base naming-convention rules.

Co-authored-by: Cursor <cursoragent@cursor.com>
Grandfather snake_case type properties (record_key, page_size, page_count)
that mirror SQLite column and PRAGMA result names after the
eslint-config-expensify 4 upgrade started linting typeProperty names.

Co-authored-by: Cursor <cursoragent@cursor.com>
@roryabraham

This comment was marked as resolved.

@roryabraham

This comment was marked as resolved.

chatgpt-codex-connector[bot]

This comment was marked as resolved.

Record<string, unknown> excluded interface-based CustomTypeOptions
values from deep nullish mapping, breaking partial nested Onyx.merge
updates. Revert to the object constraint (arrays/builtins still
excluded via NonTransformableTypes) and add a compile-time regression
test for interface-shaped settings updates.

Co-authored-by: Cursor <cursoragent@cursor.com>
Rewrite the shouldRemoveNestedNulls ternary so prettier does not strip
required parentheses around the nullish-coalescing expression.

Co-authored-by: Cursor <cursoragent@cursor.com>
@roryabraham
roryabraham requested a review from amyevans July 11, 2026 09:15
@roryabraham
roryabraham marked this pull request as ready for review July 11, 2026 09:15
@roryabraham
roryabraham requested a review from a team as a code owner July 11, 2026 09:15
@melvin-bot
melvin-bot Bot removed the request for review from a team July 11, 2026 09:15
@roryabraham
roryabraham marked this pull request as draft July 11, 2026 09:28
roryabraham and others added 3 commits July 11, 2026 02:44
Reverts the consumer-breaking parts of fa7a8d5 while keeping
collection-root snapshot delivery as the only runtime mode. OnyxDerived
and E/App depend on the optional sourceValue connect callback argument
and the waitForCollectionCallback / ResultMetadata<T> types from 3.0.86.

Co-authored-by: Cursor <cursoragent@cursor.com>
4.0.7 whitelists notation/annotation in no-negated-variables, so we can
restore test dot-notation/prefer-at overrides and drop the harness helpers.

Co-authored-by: Cursor <cursoragent@cursor.com>
@roryabraham roryabraham changed the title Upgrade eslint-config-expensify to 4.0.6 Upgrade eslint-config-expensify to 4.0.7 Jul 13, 2026
…pensify-4

# Conflicts:
#	lib/Onyx.ts
#	lib/OnyxUtils.ts
#	lib/storage/InstanceSync/index.web.ts
#	lib/utils.ts
#	tests/unit/mocks/sqliteMock.ts
#	tests/unit/useOnyxTest.ts
Drop useOnyx dependency-list tests removed on main
and refresh the seatbelt baseline for main's new lint.
@roryabraham roryabraham changed the title Upgrade eslint-config-expensify to 4.0.7 Upgrade eslint-config-expensify to 4.0.8 Aug 21, 2026
scriptsConfig already self-scopes; leave it as-is so
seatbelt baselines for buildDocs stay consistent.
@roryabraham

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. 🎉

Reviewed commit: 37a1825726

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Take the landed atomic PRs (#822#826). Keep this branch's
seatbelt OnyxUtils entries; drop the obsolete no-nested-ternary
allowance now that degradePerformance is flattened.
@roryabraham
roryabraham deleted the rory-eslint-config-expensify-4 branch August 23, 2026 15:33
@roryabraham
roryabraham restored the rory-eslint-config-expensify-4 branch August 23, 2026 15:33
@roryabraham roryabraham reopened this Aug 23, 2026
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.

1 participant