@blumintinc/eslint-plugin-blumint 1.14.0 → 1.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +36 -14
- package/lib/index.js +20 -12
- package/lib/rules/avoid-utils-directory.js +0 -4
- package/lib/rules/consistent-callback-naming.js +68 -3
- package/lib/rules/dynamic-https-errors.d.ts +1 -1
- package/lib/rules/dynamic-https-errors.js +119 -49
- package/lib/rules/enforce-boolean-naming-prefixes.d.ts +1 -0
- package/lib/rules/enforce-boolean-naming-prefixes.js +86 -331
- package/lib/rules/enforce-date-ttime.d.ts +1 -0
- package/lib/rules/enforce-date-ttime.js +156 -0
- package/lib/rules/enforce-dynamic-firebase-imports.d.ts +2 -1
- package/lib/rules/enforce-dynamic-firebase-imports.js +3 -2
- package/lib/rules/enforce-dynamic-imports.d.ts +2 -1
- package/lib/rules/enforce-dynamic-imports.js +42 -21
- package/lib/rules/enforce-f-extension-for-entry-points.d.ts +8 -0
- package/lib/rules/enforce-f-extension-for-entry-points.js +283 -0
- package/lib/rules/enforce-global-constants.js +3 -3
- package/lib/rules/enforce-id-capitalization.js +1 -1
- package/lib/rules/enforce-memoize-async.js +66 -15
- package/lib/rules/enforce-mui-rounded-icons.js +42 -1
- package/lib/rules/enforce-props-argument-name.js +42 -16
- package/lib/rules/enforce-stable-hash-spread-props.js +3 -3
- package/lib/rules/enforce-transform-memoization.js +1 -1
- package/lib/rules/enforce-verb-noun-naming.js +3817 -4641
- package/lib/rules/global-const-style.js +25 -4
- package/lib/rules/logical-top-to-bottom-grouping.js +80 -2
- package/lib/rules/memo-compare-deeply-complex-props.js +183 -6
- package/lib/rules/memo-nested-react-components.js +243 -103
- package/lib/rules/no-array-length-in-deps.js +74 -3
- package/lib/rules/no-async-foreach.js +7 -2
- package/lib/rules/no-circular-references.d.ts +2 -1
- package/lib/rules/no-circular-references.js +150 -489
- package/lib/rules/no-compositing-layer-props.js +31 -0
- package/lib/rules/no-console-error.js +12 -10
- package/lib/rules/no-empty-dependency-use-callbacks.js +1 -1
- package/lib/rules/no-entire-object-hook-deps.js +147 -65
- package/lib/rules/no-excessive-parent-chain.js +3 -0
- package/lib/rules/no-explicit-return-type.js +6 -0
- package/lib/rules/no-hungarian.js +119 -24
- package/lib/rules/no-inline-component-prop.js +16 -7
- package/lib/rules/no-margin-properties.js +7 -38
- package/lib/rules/no-passthrough-getters.d.ts +2 -2
- package/lib/rules/no-passthrough-getters.js +83 -1
- package/lib/rules/no-redundant-this-params.js +50 -1
- package/lib/rules/no-unmemoized-memo-without-props.js +1 -1
- package/lib/rules/no-unnecessary-destructuring-rename.js +2 -5
- package/lib/rules/no-unnecessary-verb-suffix.js +79 -0
- package/lib/rules/no-unused-props.js +215 -37
- package/lib/rules/no-useless-fragment.js +10 -2
- package/lib/rules/parallelize-async-operations.js +117 -54
- package/lib/rules/prefer-nullish-coalescing-boolean-props.js +109 -4
- package/lib/rules/prefer-params-over-parent-id.js +1 -1
- package/lib/rules/prefer-settings-object.js +27 -10
- package/lib/rules/prefer-type-alias-over-typeof-constant.js +75 -4
- package/lib/rules/prefer-use-deep-compare-memo.js +8 -14
- package/lib/rules/prefer-usememo-over-useeffect-usestate.js +1 -1
- package/lib/rules/prevent-children-clobber.js +9 -5
- package/lib/rules/react-memoize-literals.js +218 -13
- package/lib/rules/require-https-error-cause.js +30 -11
- package/lib/rules/require-memo.js +17 -9
- package/lib/rules/require-migration-script-metadata.d.ts +9 -0
- package/lib/rules/require-migration-script-metadata.js +206 -0
- package/lib/rules/warn-https-error-message-user-friendly.d.ts +1 -0
- package/lib/rules/warn-https-error-message-user-friendly.js +239 -0
- package/lib/utils/ASTHelpers.d.ts +49 -1
- package/lib/utils/ASTHelpers.js +394 -112
- package/package.json +7 -6
- package/release-manifest.json +166 -0
package/README.md
CHANGED
|
@@ -47,6 +47,27 @@ Or use the recommended config:
|
|
|
47
47
|
}
|
|
48
48
|
```
|
|
49
49
|
|
|
50
|
+
## Autonomous maintenance
|
|
51
|
+
|
|
52
|
+
This repo is maintained by an autonomous loop, not a human cutting releases on
|
|
53
|
+
demand. See [.claude/skills/repo-maintenance/SKILL.md](.claude/skills/repo-maintenance/SKILL.md)
|
|
54
|
+
for the operating model. Two contracts make it safe and self-healing:
|
|
55
|
+
|
|
56
|
+
- **The maintainer** (`/maintainer`, backed by `scripts/maintainer.ts`) is the
|
|
57
|
+
sole operator: it drains the open-issue queue (bugs before features, oldest
|
|
58
|
+
first), self-merges fixes to `develop`, and on an empty queue promotes
|
|
59
|
+
`develop → main` (firing the release) then fast-forwards `develop`.
|
|
60
|
+
- **`release-manifest.json`** is a strict, published `version → fixed-rules` map
|
|
61
|
+
(`scripts/generate-release-manifest.js`, a `@semantic-release/exec` prepareCmd)
|
|
62
|
+
so consumers re-enable disabled rules by exact rule name — never by parsing the
|
|
63
|
+
changelog. It's only reliable because **every `fix`/`feat` commit's scope must
|
|
64
|
+
be a real rule name**: enforced by the `blumint-rule-scope` commitlint rule and
|
|
65
|
+
the `validate-commit-scopes` CI gate. One rule per fix/feat commit.
|
|
66
|
+
|
|
67
|
+
On publish, `scripts/dispatch-agora-release.js` fires a `repository_dispatch` to
|
|
68
|
+
agora, which bumps its pin and re-enables the now-fixed rules (FP-audited). The
|
|
69
|
+
full closed loop is documented in agora's `.claude/skills/eslint-autonomy/SKILL.md`.
|
|
70
|
+
|
|
50
71
|
## Rules
|
|
51
72
|
|
|
52
73
|
<!-- begin auto-generated rules list -->
|
|
@@ -74,22 +95,24 @@ Or use the recommended config:
|
|
|
74
95
|
| [enforce-centralized-mock-firestore](docs/rules/enforce-centralized-mock-firestore.md) | Enforce usage of centralized mockFirestore from predefined location | ✅ | | | 🔧 | | |
|
|
75
96
|
| [enforce-console-error](docs/rules/enforce-console-error.md) | Enforce proper logging for useAlertDialog based on severity. When severity is "error", console.error must be included. When severity is "warning", console.warn must be included. This ensures all user-facing errors and warnings are properly logged to observability systems. | ✅ | | | | | |
|
|
76
97
|
| [enforce-css-media-queries](docs/rules/enforce-css-media-queries.md) | Enforce CSS media queries over JS breakpoints | ✅ | | | | | |
|
|
98
|
+
| [enforce-date-ttime](docs/rules/enforce-date-ttime.md) | Enforce that any generic type parameter named TTime is explicitly set to Date in frontend code | ✅ | | | 🔧 | | |
|
|
77
99
|
| [enforce-dynamic-file-naming](docs/rules/enforce-dynamic-file-naming.md) | Enforce .dynamic.ts(x) file naming when @blumintinc/blumint/enforce-dynamic-imports or @blumintinc/blumint/require-dynamic-firebase-imports rule is disabled | | | | | | |
|
|
78
100
|
| [enforce-dynamic-firebase-imports](docs/rules/enforce-dynamic-firebase-imports.md) | Require firebaseCloud modules to be loaded via dynamic import so Firebase code stays out of the initial bundle and only loads when needed. | ✅ | | | 🔧 | 💡 | |
|
|
79
|
-
| [enforce-dynamic-imports](docs/rules/enforce-dynamic-imports.md) | Enforce dynamic imports for
|
|
101
|
+
| [enforce-dynamic-imports](docs/rules/enforce-dynamic-imports.md) | Enforce dynamic imports for external libraries by default to optimize bundle size, unless explicitly ignored | ✅ | | | | | |
|
|
80
102
|
| [enforce-early-destructuring](docs/rules/enforce-early-destructuring.md) | Hoist object destructuring out of React hooks so dependency arrays track the fields in use instead of the entire object. | ✅ | | | 🔧 | | |
|
|
81
103
|
| [enforce-empty-object-check](docs/rules/enforce-empty-object-check.md) | Ensure object existence checks also guard against empty objects so that empty payloads are treated like missing data. | ✅ | | | 🔧 | | |
|
|
82
104
|
| [enforce-exported-function-types](docs/rules/enforce-exported-function-types.md) | Enforce exporting types for function props and return values | ✅ | | | | | |
|
|
105
|
+
| [enforce-f-extension-for-entry-points](docs/rules/enforce-f-extension-for-entry-points.md) | Enforce .f.ts extension for entry points | ✅ | | | | | |
|
|
83
106
|
| [enforce-fieldpath-syntax-in-docsetter](docs/rules/enforce-fieldpath-syntax-in-docsetter.md) | Enforce the use of Firestore FieldPath syntax when passing documentData into DocSetter. Instead of using nested object syntax, developers should use dot notation for deeply nested fields. | ✅ | | | 🔧 | | |
|
|
84
107
|
| [enforce-firestore-doc-ref-generic](docs/rules/enforce-firestore-doc-ref-generic.md) | Enforce generic argument for Firestore DocumentReference, CollectionReference and CollectionGroup | ✅ | | | | | 💭 |
|
|
85
108
|
| [enforce-firestore-facade](docs/rules/enforce-firestore-facade.md) | Enforce usage of Firestore facades instead of direct Firestore methods | ✅ | | | | | |
|
|
86
109
|
| [enforce-firestore-path-utils](docs/rules/enforce-firestore-path-utils.md) | Enforce usage of utility functions for Firestore paths to ensure type safety, maintainability, and consistent path construction. This prevents errors from manual string concatenation and makes path changes easier to manage. | ✅ | | | | | |
|
|
87
110
|
| [enforce-firestore-rules-get-access](docs/rules/enforce-firestore-rules-get-access.md) | Ensure Firestore security rules use .get() with a default value instead of direct field access comparisons (e.g., resource.data.fieldX.fieldY != null). | ✅ | | | 🔧 | | |
|
|
88
111
|
| [enforce-firestore-set-merge](docs/rules/enforce-firestore-set-merge.md) | Enforce using set() with { merge: true } instead of update() for Firestore operations to ensure consistent behavior. The update() method fails if the document does not exist, while set() with { merge: true } creates the document if needed and safely merges fields, making it more reliable and predictable. | ✅ | | | 🔧 | | |
|
|
89
|
-
| [enforce-global-constants](docs/rules/enforce-global-constants.md) | Enforce
|
|
112
|
+
| [enforce-global-constants](docs/rules/enforce-global-constants.md) | Enforce global static constants for React components/hooks | ✅ | | | 🔧 | | |
|
|
90
113
|
| [enforce-id-capitalization](docs/rules/enforce-id-capitalization.md) | Enforce the use of "ID" instead of "id" in user-facing text | ✅ | | | 🔧 | | |
|
|
91
114
|
| [enforce-identifiable-firestore-type](docs/rules/enforce-identifiable-firestore-type.md) | Enforce that Firestore type definitions extend Identifiable and match their folder name | ✅ | | | | | |
|
|
92
|
-
| [enforce-memoize-async](docs/rules/enforce-memoize-async.md) | Enforce @Memoize() decorator on async methods with 0-1 parameters to cache results and prevent redundant API calls or expensive computations.
|
|
115
|
+
| [enforce-memoize-async](docs/rules/enforce-memoize-async.md) | Enforce @Memoize() decorator on async methods with 0-1 parameters to cache results and prevent redundant API calls or expensive computations. Without memoization, repeated calls trigger redundant requests or expensive computations, increasing latency. @Memoize() caches results by parameter, ensuring subsequent calls with identical inputs return immediately. | ✅ | | | 🔧 | | |
|
|
93
116
|
| [enforce-memoize-getters](docs/rules/enforce-memoize-getters.md) | Enforce @Memoize() decorator on private class getters to avoid re-instantiation and preserve state across accesses. | ✅ | | | 🔧 | | |
|
|
94
117
|
| [enforce-microdiff](docs/rules/enforce-microdiff.md) | Enforce using microdiff for object and array comparison operations | ✅ | | | 🔧 | | |
|
|
95
118
|
| [enforce-mock-firestore](docs/rules/enforce-mock-firestore.md) | Enforce using the standardized mockFirestore utility instead of manual Firestore mocking or third-party mocks. This ensures consistent test behavior across the codebase, reduces boilerplate, and provides type-safe mocking of Firestore operations. | ✅ | | | | | |
|
|
@@ -108,7 +131,7 @@ Or use the recommended config:
|
|
|
108
131
|
| [enforce-stable-hash-spread-props](docs/rules/enforce-stable-hash-spread-props.md) | Require stableHash wrapping when spread props rest objects are used in React hook dependency arrays to avoid re-renders triggered by new object references on every render. | ✅ | | | 🔧 | | |
|
|
109
132
|
| [enforce-storage-context](docs/rules/enforce-storage-context.md) | Require storage access to go through the LocalStorage and SessionStorage context providers instead of direct browser APIs | ✅ | | | | | |
|
|
110
133
|
| [enforce-timestamp-now](docs/rules/enforce-timestamp-now.md) | Enforce the use of Timestamp.now() for getting the current timestamp in backend code. This rule prevents using alternatives like Timestamp.fromDate(new Date()) or other date creation patterns that could lead to inconsistency. | ✅ | | | 🔧 | | |
|
|
111
|
-
| [enforce-transform-memoization](docs/rules/enforce-transform-memoization.md) | Enforce memoization of
|
|
134
|
+
| [enforce-transform-memoization](docs/rules/enforce-transform-memoization.md) | Enforce memoization of transformValue and transformOnChange in adaptValue | ✅ | | | | | |
|
|
112
135
|
| [enforce-typescript-markdown-code-blocks](docs/rules/enforce-typescript-markdown-code-blocks.md) | Ensure Markdown fenced code blocks without a language specifier default to typescript for consistent highlighting. | ✅ | | | 🔧 | | |
|
|
113
136
|
| [enforce-unique-cursor-headers](docs/rules/enforce-unique-cursor-headers.md) | Ensure files have exactly one cursor header containing required tags (e.g., @fileoverview) before any code | ✅ | | | 🔧 | | |
|
|
114
137
|
| [enforce-verb-noun-naming](docs/rules/enforce-verb-noun-naming.md) | Enforce verb phrases for functions and methods | ✅ | | | | | |
|
|
@@ -122,14 +145,14 @@ Or use the recommended config:
|
|
|
122
145
|
| [global-const-style](docs/rules/global-const-style.md) | Enforce UPPER_SNAKE_CASE and as const for global static constants | ✅ | | | 🔧 | | |
|
|
123
146
|
| [jsdoc-above-field](docs/rules/jsdoc-above-field.md) | Require JSDoc blocks to sit above fields instead of trailing inline so IDE hovers surface the documentation. | ✅ | | | 🔧 | | |
|
|
124
147
|
| [key-only-outermost-element](docs/rules/key-only-outermost-element.md) | Enforce that only the outermost element in list rendering has a key prop | ✅ | | | 🔧 | | |
|
|
125
|
-
| [logical-top-to-bottom-grouping](docs/rules/logical-top-to-bottom-grouping.md) |
|
|
148
|
+
| [logical-top-to-bottom-grouping](docs/rules/logical-top-to-bottom-grouping.md) | Enforce logical top-to-bottom grouping of related statements | ✅ | | | 🔧 | | |
|
|
126
149
|
| [memo-compare-deeply-complex-props](docs/rules/memo-compare-deeply-complex-props.md) | Suggest compareDeeply for memoized components that receive object/array props to avoid shallow comparison re-renders. | ✅ | | | 🔧 | | 💭 |
|
|
127
|
-
| [memo-nested-react-components](docs/rules/memo-nested-react-components.md) |
|
|
150
|
+
| [memo-nested-react-components](docs/rules/memo-nested-react-components.md) | Disallow React components defined in render bodies, hooks, or passed as props | ✅ | | | | | |
|
|
128
151
|
| [memoize-root-level-hocs](docs/rules/memoize-root-level-hocs.md) | Prevent creating Higher-Order Components at the root level of React components/hooks without wrapping them in useMemo to keep wrapped component identities stable across renders. | ✅ | | | | | |
|
|
129
152
|
| [no-always-true-false-conditions](docs/rules/no-always-true-false-conditions.md) | Detect conditions that are always truthy or always falsy | ✅ | | | | | |
|
|
130
153
|
| [no-array-length-in-deps](docs/rules/no-array-length-in-deps.md) | Detects array.length entries in React hook dependency arrays because length ignores content changes; auto-fixes by memoizing stableHash(array) with useMemo and depending on the hash instead. | ✅ | | | 🔧 | | |
|
|
131
154
|
| [no-async-array-filter](docs/rules/no-async-array-filter.md) | Disallow async callbacks in Array.filter(). Async predicates return Promises that are always truthy to the filter, so no element is ever removed. Resolve async checks first (Promise.all + map) or use a synchronous predicate to decide which items to keep. | ✅ | | | | | |
|
|
132
|
-
| [no-async-foreach](docs/rules/no-async-foreach.md) | Disallow async callbacks
|
|
155
|
+
| [no-async-foreach](docs/rules/no-async-foreach.md) | Disallow async callbacks to Array.forEach | ✅ | | | | | |
|
|
133
156
|
| [no-circular-references](docs/rules/no-circular-references.md) | Disallow circular references in objects | ✅ | | | | | |
|
|
134
157
|
| [no-class-instance-destructuring](docs/rules/no-class-instance-destructuring.md) | Disallow destructuring of class instances to prevent loss of `this` context | ✅ | | | 🔧 | | |
|
|
135
158
|
| [no-complex-cloud-params](docs/rules/no-complex-cloud-params.md) | Disallow passing complex objects to cloud functions | ✅ | | | | | |
|
|
@@ -195,20 +218,18 @@ Or use the recommended config:
|
|
|
195
218
|
| [prefer-fragment-shorthand](docs/rules/prefer-fragment-shorthand.md) | Prefer <> shorthand for <React.Fragment> | ✅ | | | 🔧 | | |
|
|
196
219
|
| [prefer-getter-over-parameterless-method](docs/rules/prefer-getter-over-parameterless-method.md) | Enforce getter syntax for synchronous parameterless methods that return values, improving semantic clarity and avoiding accidental method invocation without parentheses. | ✅ | | | 🔧 | | |
|
|
197
220
|
| [prefer-global-router-state-key](docs/rules/prefer-global-router-state-key.md) | Enforce using centralized router state key constants from queryKeys.ts for useRouterState key parameter | ✅ | | | 🔧 | | |
|
|
198
|
-
| [prefer-memoized-props](docs/rules/prefer-memoized-props.md) | Require memoizing reference props (objects, arrays, functions) inside React.memo components while avoiding unnecessary useMemo for pass-through values. | ✅ | | | | | |
|
|
199
221
|
| [prefer-next-dynamic](docs/rules/prefer-next-dynamic.md) | Prefer Next.js dynamic() over custom useDynamic() for component imports | ✅ | | | 🔧 | | |
|
|
200
222
|
| [prefer-nullish-coalescing-boolean-props](docs/rules/prefer-nullish-coalescing-boolean-props.md) | Prefer nullish coalescing over logical OR, but allow logical OR in boolean contexts | ✅ | | | 🔧 | | |
|
|
201
|
-
| [prefer-
|
|
202
|
-
| [prefer-params-over-parent-id](docs/rules/prefer-params-over-parent-id.md) | Prefer handler params for parent IDs instead of traversing ref.parent.id so Firebase triggers stay aligned with path templates and type-safe. | ✅ | | | 🔧 | | |
|
|
223
|
+
| [prefer-params-over-parent-id](docs/rules/prefer-params-over-parent-id.md) | Prefer event.params over ref.parent.id for type-safe Firebase trigger paths. | ✅ | | | 🔧 | | |
|
|
203
224
|
| [prefer-settings-object](docs/rules/prefer-settings-object.md) | Enforce using a settings object for functions with multiple parameters | ✅ | | | 🔧 | | |
|
|
204
225
|
| [prefer-type-alias-over-typeof-constant](docs/rules/prefer-type-alias-over-typeof-constant.md) | Prefer named type aliases over `typeof` on same-file global constants; ensure types are declared before constants. | ✅ | | | | | |
|
|
205
226
|
| [prefer-type-over-interface](docs/rules/prefer-type-over-interface.md) | Prefer using type alias over interface | ✅ | | | 🔧 | | |
|
|
206
227
|
| [prefer-url-tostring-over-tojson](docs/rules/prefer-url-tostring-over-tojson.md) | Enforce the use of toString() over toJSON() on URL objects. | ✅ | | | 🔧 | | |
|
|
207
|
-
| [prefer-use-deep-compare-memo](docs/rules/prefer-use-deep-compare-memo.md) | Enforce using useDeepCompareMemo when dependency array contains non-primitive values (objects, arrays
|
|
228
|
+
| [prefer-use-deep-compare-memo](docs/rules/prefer-use-deep-compare-memo.md) | Enforce using useDeepCompareMemo when dependency array contains non-primitive values (objects, arrays) that are not already memoized. This prevents unnecessary re-renders due to reference changes. | ✅ | | | 🔧 | | |
|
|
208
229
|
| [prefer-usecallback-over-usememo-for-functions](docs/rules/prefer-usecallback-over-usememo-for-functions.md) | Enforce using useCallback instead of useMemo for memoizing functions | ✅ | | | 🔧 | | |
|
|
209
230
|
| [prefer-usememo-over-useeffect-usestate](docs/rules/prefer-usememo-over-useeffect-usestate.md) | Prefer useMemo over useEffect + useState for pure computations to avoid extra render cycles and stale derived state. | ✅ | | | | | |
|
|
210
231
|
| [prefer-utility-function-over-private-static](docs/rules/prefer-utility-function-over-private-static.md) | Enforce abstraction of private static methods into utility functions | ✅ | | | | | |
|
|
211
|
-
| [prevent-children-clobber](docs/rules/prevent-children-clobber.md) | Prevent JSX spreads from silently discarding props.children
|
|
232
|
+
| [prevent-children-clobber](docs/rules/prevent-children-clobber.md) | Prevent JSX spreads from silently discarding props.children | ✅ | | | | | |
|
|
212
233
|
| [react-memoize-literals](docs/rules/react-memoize-literals.md) | Detect object, array, and function literals created in React components or hooks that create new references every render. Prefer memoized values (useMemo/useCallback) or module-level constants to keep referential stability. | ✅ | | | | 💡 | |
|
|
213
234
|
| [react-usememo-should-be-component](docs/rules/react-usememo-should-be-component.md) | Enforce that useMemo hooks explicitly returning JSX should be abstracted into separate React components | ✅ | | | | | |
|
|
214
235
|
| [require-dynamic-firebase-imports](docs/rules/require-dynamic-firebase-imports.md) | Enforce dynamic imports for Firebase dependencies | ✅ | | | 🔧 | | |
|
|
@@ -217,8 +238,8 @@ Or use the recommended config:
|
|
|
217
238
|
| [require-https-error-cause](docs/rules/require-https-error-cause.md) | Ensure HttpsError calls inside catch blocks pass the caught error as the fourth "cause" argument to preserve stack traces for monitoring. | ✅ | | | | | |
|
|
218
239
|
| [require-image-optimized](docs/rules/require-image-optimized.md) | Enforce using ImageOptimized component instead of next/image or img tags | ✅ | | | 🔧 | | |
|
|
219
240
|
| [require-memo](docs/rules/require-memo.md) | React components must be memoized | ✅ | | | 🔧 | | |
|
|
220
|
-
| [require-memoize-jsx-returners](docs/rules/require-memoize-jsx-returners.md) |
|
|
221
|
-
| [require-
|
|
241
|
+
| [require-memoize-jsx-returners](docs/rules/require-memoize-jsx-returners.md) | Require @Memoize() decorator on instance members that return JSX or JSX factories | ✅ | | | 🔧 | | |
|
|
242
|
+
| [require-migration-script-metadata](docs/rules/require-migration-script-metadata.md) | Enforce JSDoc migration metadata in callable scripts | ✅ | | | | | |
|
|
222
243
|
| [semantic-function-prefixes](docs/rules/semantic-function-prefixes.md) | Require semantic function prefixes instead of generic verbs so callers know whether a function fetches data, transforms input, or mutates state | ✅ | | | | | |
|
|
223
244
|
| [sync-onwrite-name-func](docs/rules/sync-onwrite-name-func.md) | Ensure that the name field matches the func field in onWrite handlers | ✅ | | | 🔧 | | |
|
|
224
245
|
| [test-file-location-enforcement](docs/rules/test-file-location-enforcement.md) | Enforce colocating *.test.ts or *.test.tsx files with the code they cover. | ✅ | | | | | |
|
|
@@ -227,6 +248,7 @@ Or use the recommended config:
|
|
|
227
248
|
| [use-custom-router](docs/rules/use-custom-router.md) | Enforce using src/hooks/routing/useRouter instead of next/router | ✅ | | | 🔧 | | |
|
|
228
249
|
| [use-latest-callback](docs/rules/use-latest-callback.md) | Enforce using useLatestCallback from use-latest-callback instead of React useCallback | ✅ | | | 🔧 | | |
|
|
229
250
|
| [vertically-group-related-functions](docs/rules/vertically-group-related-functions.md) | Keep top-level functions grouped vertically so callers, exports, and helpers read top-down. | ✅ | | | 🔧 | | |
|
|
251
|
+
| [warn-https-error-message-user-friendly](docs/rules/warn-https-error-message-user-friendly.md) | Warn when messageUserFriendly is used in HttpsError or toHttpsError to ensure it is truly a user-caused error. | | ✅ | | | | |
|
|
230
252
|
|
|
231
253
|
<!-- end auto-generated rules list -->
|
|
232
254
|
|
package/lib/index.js
CHANGED
|
@@ -3,6 +3,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const enforce_date_ttime_1 = require("./rules/enforce-date-ttime");
|
|
7
|
+
const enforce_f_extension_for_entry_points_1 = require("./rules/enforce-f-extension-for-entry-points");
|
|
6
8
|
const array_methods_this_context_1 = require("./rules/array-methods-this-context");
|
|
7
9
|
const class_methods_read_top_to_bottom_1 = require("./rules/class-methods-read-top-to-bottom");
|
|
8
10
|
const consistent_callback_naming_1 = __importDefault(require("./rules/consistent-callback-naming"));
|
|
@@ -15,7 +17,7 @@ const enforce_callback_memo_1 = __importDefault(require("./rules/enforce-callbac
|
|
|
15
17
|
const react_memoize_literals_1 = require("./rules/react-memoize-literals");
|
|
16
18
|
const enforce_callable_types_1 = require("./rules/enforce-callable-types");
|
|
17
19
|
const enforce_console_error_1 = require("./rules/enforce-console-error");
|
|
18
|
-
const enforce_dynamic_firebase_imports_1 = require("./rules/enforce-dynamic-firebase-imports");
|
|
20
|
+
const enforce_dynamic_firebase_imports_1 = __importDefault(require("./rules/enforce-dynamic-firebase-imports"));
|
|
19
21
|
const enforce_mui_rounded_icons_1 = require("./rules/enforce-mui-rounded-icons");
|
|
20
22
|
const enforce_querykey_ts_1 = require("./rules/enforce-querykey-ts");
|
|
21
23
|
const enforce_react_type_naming_1 = require("./rules/enforce-react-type-naming");
|
|
@@ -39,7 +41,6 @@ const prefer_fragment_shorthand_1 = require("./rules/prefer-fragment-shorthand")
|
|
|
39
41
|
const prefer_getter_over_parameterless_method_1 = require("./rules/prefer-getter-over-parameterless-method");
|
|
40
42
|
const prefer_type_over_interface_1 = require("./rules/prefer-type-over-interface");
|
|
41
43
|
const prefer_type_alias_over_typeof_constant_1 = require("./rules/prefer-type-alias-over-typeof-constant");
|
|
42
|
-
const prefer_memoized_props_1 = require("./rules/prefer-memoized-props");
|
|
43
44
|
const require_memo_1 = require("./rules/require-memo");
|
|
44
45
|
const require_memoize_jsx_returners_1 = require("./rules/require-memoize-jsx-returners");
|
|
45
46
|
const no_jsx_whitespace_literal_1 = require("./rules/no-jsx-whitespace-literal");
|
|
@@ -48,7 +49,6 @@ const require_https_error_1 = __importDefault(require("./rules/require-https-err
|
|
|
48
49
|
const require_https_error_cause_1 = require("./rules/require-https-error-cause");
|
|
49
50
|
const use_custom_router_1 = require("./rules/use-custom-router");
|
|
50
51
|
const require_image_optimized_1 = __importDefault(require("./rules/require-image-optimized"));
|
|
51
|
-
const require_usememo_object_literals_1 = require("./rules/require-usememo-object-literals");
|
|
52
52
|
const enforce_safe_stringify_1 = require("./rules/enforce-safe-stringify");
|
|
53
53
|
const enforce_storage_context_1 = require("./rules/enforce-storage-context");
|
|
54
54
|
const avoid_utils_directory_1 = require("./rules/avoid-utils-directory");
|
|
@@ -136,7 +136,6 @@ const prefer_block_comments_for_declarations_1 = require("./rules/prefer-block-c
|
|
|
136
136
|
const no_undefined_null_passthrough_1 = require("./rules/no-undefined-null-passthrough");
|
|
137
137
|
const firestore_transaction_reads_before_writes_1 = require("./rules/firestore-transaction-reads-before-writes");
|
|
138
138
|
const enforce_typescript_markdown_code_blocks_1 = require("./rules/enforce-typescript-markdown-code-blocks");
|
|
139
|
-
const prefer_nullish_coalescing_override_1 = require("./rules/prefer-nullish-coalescing-override");
|
|
140
139
|
const prefer_nullish_coalescing_boolean_props_1 = require("./rules/prefer-nullish-coalescing-boolean-props");
|
|
141
140
|
const no_restricted_properties_fix_1 = require("./rules/no-restricted-properties-fix");
|
|
142
141
|
const no_excessive_parent_chain_1 = require("./rules/no-excessive-parent-chain");
|
|
@@ -169,6 +168,8 @@ const vertically_group_related_functions_1 = require("./rules/vertically-group-r
|
|
|
169
168
|
const no_static_constants_in_dynamic_files_1 = __importDefault(require("./rules/no-static-constants-in-dynamic-files"));
|
|
170
169
|
const test_file_location_enforcement_1 = require("./rules/test-file-location-enforcement");
|
|
171
170
|
const prevent_children_clobber_1 = require("./rules/prevent-children-clobber");
|
|
171
|
+
const require_migration_script_metadata_1 = require("./rules/require-migration-script-metadata");
|
|
172
|
+
const warn_https_error_message_user_friendly_1 = require("./rules/warn-https-error-message-user-friendly");
|
|
172
173
|
const NO_FRONTEND_IMPORTS_FROM_FUNCTIONS_MESSAGE = 'Backend Cloud Functions (.f.ts under functions/) must not import frontend modules from the repo root src/**. Frontend code can depend on browser-only APIs and bundling it into Cloud Functions breaks server execution; move shared logic into functions/src or a shared package.';
|
|
173
174
|
function noFrontendImportsFromFunctionsPatterns(pattern) {
|
|
174
175
|
return [
|
|
@@ -195,7 +196,7 @@ function noFrontendImportsFromFunctionsPatterns(pattern) {
|
|
|
195
196
|
module.exports = {
|
|
196
197
|
meta: {
|
|
197
198
|
name: '@blumintinc/eslint-plugin-blumint',
|
|
198
|
-
version: '1.
|
|
199
|
+
version: '1.16.0',
|
|
199
200
|
},
|
|
200
201
|
parseOptions: {
|
|
201
202
|
ecmaVersion: 2020,
|
|
@@ -204,10 +205,10 @@ module.exports = {
|
|
|
204
205
|
recommended: {
|
|
205
206
|
plugins: ['@blumintinc/blumint'],
|
|
206
207
|
rules: {
|
|
208
|
+
'@blumintinc/blumint/enforce-f-extension-for-entry-points': 'error',
|
|
207
209
|
'@blumintinc/blumint/firestore-transaction-reads-before-writes': 'error',
|
|
208
210
|
// Override the @typescript-eslint/prefer-nullish-coalescing rule
|
|
209
211
|
'@typescript-eslint/prefer-nullish-coalescing': 'off',
|
|
210
|
-
'@blumintinc/blumint/prefer-nullish-coalescing-override': 'error',
|
|
211
212
|
'@blumintinc/blumint/prefer-block-comments-for-declarations': 'error',
|
|
212
213
|
'@blumintinc/blumint/key-only-outermost-element': 'error',
|
|
213
214
|
'@blumintinc/blumint/logical-top-to-bottom-grouping': 'error',
|
|
@@ -262,7 +263,6 @@ module.exports = {
|
|
|
262
263
|
'@blumintinc/blumint/require-https-error-cause': 'error',
|
|
263
264
|
'@blumintinc/blumint/use-custom-router': 'error',
|
|
264
265
|
'@blumintinc/blumint/require-image-optimized': 'error',
|
|
265
|
-
'@blumintinc/blumint/require-usememo-object-literals': 'error',
|
|
266
266
|
'@blumintinc/blumint/memoize-root-level-hocs': 'error',
|
|
267
267
|
'@blumintinc/blumint/enforce-safe-stringify': 'error',
|
|
268
268
|
'@blumintinc/blumint/enforce-early-destructuring': 'error',
|
|
@@ -324,7 +324,6 @@ module.exports = {
|
|
|
324
324
|
'@blumintinc/blumint/enforce-props-naming-consistency': 'error',
|
|
325
325
|
'@blumintinc/blumint/prefer-global-router-state-key': 'error',
|
|
326
326
|
'@blumintinc/blumint/prefer-usememo-over-useeffect-usestate': 'error',
|
|
327
|
-
'@blumintinc/blumint/prefer-memoized-props': 'error',
|
|
328
327
|
'@blumintinc/blumint/enforce-dynamic-imports': 'error',
|
|
329
328
|
'@blumintinc/blumint/ensure-pointer-events-none': 'error',
|
|
330
329
|
'@blumintinc/blumint/no-object-values-on-strings': 'error',
|
|
@@ -371,6 +370,8 @@ module.exports = {
|
|
|
371
370
|
'@blumintinc/blumint/vertically-group-related-functions': 'error',
|
|
372
371
|
'@blumintinc/blumint/no-static-constants-in-dynamic-files': 'error',
|
|
373
372
|
'@blumintinc/blumint/test-file-location-enforcement': 'error',
|
|
373
|
+
'@blumintinc/blumint/require-migration-script-metadata': 'error',
|
|
374
|
+
'@blumintinc/blumint/warn-https-error-message-user-friendly': 'warn',
|
|
374
375
|
},
|
|
375
376
|
/**
|
|
376
377
|
* Depth-specific overrides block only import strings that traverse to the
|
|
@@ -378,6 +379,12 @@ module.exports = {
|
|
|
378
379
|
* requires an additional override.
|
|
379
380
|
*/
|
|
380
381
|
overrides: [
|
|
382
|
+
{
|
|
383
|
+
files: ['src/**/*.{ts,tsx}'],
|
|
384
|
+
rules: {
|
|
385
|
+
'@blumintinc/blumint/enforce-date-ttime': 'error',
|
|
386
|
+
},
|
|
387
|
+
},
|
|
381
388
|
{
|
|
382
389
|
files: ['functions/*.f.ts'],
|
|
383
390
|
rules: {
|
|
@@ -448,8 +455,9 @@ module.exports = {
|
|
|
448
455
|
},
|
|
449
456
|
},
|
|
450
457
|
rules: {
|
|
458
|
+
'enforce-date-ttime': enforce_date_ttime_1.enforceDateTTime,
|
|
459
|
+
'enforce-f-extension-for-entry-points': enforce_f_extension_for_entry_points_1.enforceFExtensionForEntryPoints,
|
|
451
460
|
'firestore-transaction-reads-before-writes': firestore_transaction_reads_before_writes_1.firestoreTransactionReadsBeforeWrites,
|
|
452
|
-
'prefer-nullish-coalescing-override': prefer_nullish_coalescing_override_1.preferNullishCoalescingOverride,
|
|
453
461
|
'no-restricted-properties-fix': no_restricted_properties_fix_1.noRestrictedPropertiesFix,
|
|
454
462
|
'no-excessive-parent-chain': no_excessive_parent_chain_1.noExcessiveParentChain,
|
|
455
463
|
'prefer-document-flattening': prefer_document_flattening_1.preferDocumentFlattening,
|
|
@@ -469,7 +477,7 @@ module.exports = {
|
|
|
469
477
|
'enforce-firestore-rules-get-access': enforce_firestore_rules_get_access_1.enforceFirestoreRulesGetAccess,
|
|
470
478
|
'enforce-callable-types': enforce_callable_types_1.enforceCallableTypes,
|
|
471
479
|
'enforce-console-error': enforce_console_error_1.enforceConsoleError,
|
|
472
|
-
'enforce-dynamic-firebase-imports': enforce_dynamic_firebase_imports_1.
|
|
480
|
+
'enforce-dynamic-firebase-imports': enforce_dynamic_firebase_imports_1.default,
|
|
473
481
|
'enforce-mui-rounded-icons': enforce_mui_rounded_icons_1.enforceMuiRoundedIcons,
|
|
474
482
|
'export-if-in-doubt': export_if_in_doubt_1.exportIfInDoubt,
|
|
475
483
|
'extract-global-constants': extract_global_constants_1.extractGlobalConstants,
|
|
@@ -501,7 +509,6 @@ module.exports = {
|
|
|
501
509
|
'require-https-error-cause': require_https_error_cause_1.requireHttpsErrorCause,
|
|
502
510
|
'use-custom-router': use_custom_router_1.useCustomRouter,
|
|
503
511
|
'require-image-optimized': require_image_optimized_1.default,
|
|
504
|
-
'require-usememo-object-literals': require_usememo_object_literals_1.requireUseMemoObjectLiterals,
|
|
505
512
|
'memoize-root-level-hocs': memoize_root_level_hocs_1.memoizeRootLevelHocs,
|
|
506
513
|
'enforce-safe-stringify': enforce_safe_stringify_1.enforceStableStringify,
|
|
507
514
|
'enforce-early-destructuring': enforce_early_destructuring_1.enforceEarlyDestructuring,
|
|
@@ -602,7 +609,6 @@ module.exports = {
|
|
|
602
609
|
'no-redundant-usecallback-wrapper': no_redundant_usecallback_wrapper_1.default,
|
|
603
610
|
'no-res-error-status-in-onrequest': no_res_error_status_in_onrequest_1.requireHttpsErrorInOnRequestHandlers,
|
|
604
611
|
'no-array-length-in-deps': no_array_length_in_deps_1.noArrayLengthInDeps,
|
|
605
|
-
'prefer-memoized-props': prefer_memoized_props_1.preferMemoizedProps,
|
|
606
612
|
'prefer-use-deep-compare-memo': prefer_use_deep_compare_memo_1.preferUseDeepCompareMemo,
|
|
607
613
|
'memo-nested-react-components': memo_nested_react_components_1.memoNestedReactComponents,
|
|
608
614
|
'memo-compare-deeply-complex-props': memo_compare_deeply_complex_props_1.memoCompareDeeplyComplexProps,
|
|
@@ -614,6 +620,8 @@ module.exports = {
|
|
|
614
620
|
'vertically-group-related-functions': vertically_group_related_functions_1.verticallyGroupRelatedFunctions,
|
|
615
621
|
'no-static-constants-in-dynamic-files': no_static_constants_in_dynamic_files_1.default,
|
|
616
622
|
'test-file-location-enforcement': test_file_location_enforcement_1.testFileLocationEnforcement,
|
|
623
|
+
'require-migration-script-metadata': require_migration_script_metadata_1.requireMigrationScriptMetadata,
|
|
624
|
+
'warn-https-error-message-user-friendly': warn_https_error_message_user_friendly_1.warnHttpsErrorMessageUserFriendly,
|
|
617
625
|
},
|
|
618
626
|
};
|
|
619
627
|
//# sourceMappingURL=index.js.map
|
|
@@ -37,8 +37,12 @@ module.exports = (0, createRule_1.createRule)({
|
|
|
37
37
|
fixable: 'code',
|
|
38
38
|
schema: [],
|
|
39
39
|
messages: {
|
|
40
|
-
callbackPropPrefix: 'Callback
|
|
41
|
-
|
|
40
|
+
callbackPropPrefix: 'Callback prop "{{propName}}" is a function but lacks the "on" prefix. ' +
|
|
41
|
+
'Consistent "on" prefixes signal event handlers to consumers and distinguish callbacks from data props. ' +
|
|
42
|
+
'Rename to "on{{eventName}}".',
|
|
43
|
+
callbackFunctionPrefix: 'Function "{{functionName}}" uses the "handle" prefix. ' +
|
|
44
|
+
'The "handle" prefix is redundant and less descriptive than action-oriented verb phrases. ' +
|
|
45
|
+
'Rename using a descriptive verb (e.g., click instead of handleClick).',
|
|
42
46
|
},
|
|
43
47
|
},
|
|
44
48
|
defaultOptions: [],
|
|
@@ -91,6 +95,53 @@ module.exports = (0, createRule_1.createRule)({
|
|
|
91
95
|
const type = checker.getTypeAtLocation(tsNode);
|
|
92
96
|
return type.getCallSignatures().length > 0;
|
|
93
97
|
}
|
|
98
|
+
// A union counts as "mixed" when it pairs a callable member with a
|
|
99
|
+
// non-callable one (e.g. `Validate<T> | readonly T[]`). `undefined`/`null`
|
|
100
|
+
// members are ignored so plain optional callbacks (`(() => void) | undefined`)
|
|
101
|
+
// remain pure functions.
|
|
102
|
+
function isMixedFunctionUnion(type) {
|
|
103
|
+
if (!type || !type.isUnion()) {
|
|
104
|
+
return false;
|
|
105
|
+
}
|
|
106
|
+
const members = type.types.filter((member) => !(member.flags & (ts.TypeFlags.Undefined | ts.TypeFlags.Null)));
|
|
107
|
+
const hasFunctionMember = members.some((member) => member.getCallSignatures().length > 0);
|
|
108
|
+
const hasNonFunctionMember = members.some((member) => member.getCallSignatures().length === 0);
|
|
109
|
+
return hasFunctionMember && hasNonFunctionMember;
|
|
110
|
+
}
|
|
111
|
+
// The `on` prefix is only meaningful for props that are *exclusively*
|
|
112
|
+
// callbacks. A prop typed `Validate<T> | readonly T[]` is a configuration
|
|
113
|
+
// prop that merely accepts a function as one option, so it must be skipped.
|
|
114
|
+
// The passed value may be a plain function even when the prop legitimately
|
|
115
|
+
// accepts non-function values, so the prop's contextual (declared) type is
|
|
116
|
+
// inspected alongside the value's own type.
|
|
117
|
+
function acceptsNonFunctionValue(node) {
|
|
118
|
+
const tsNode = parserServices.esTreeNodeToTSNodeMap.get(node);
|
|
119
|
+
const valueType = checker.getTypeAtLocation(tsNode);
|
|
120
|
+
const contextualType = checker.getContextualType(tsNode);
|
|
121
|
+
return (isMixedFunctionUnion(valueType) || isMixedFunctionUnion(contextualType));
|
|
122
|
+
}
|
|
123
|
+
function isRenderFunction(node) {
|
|
124
|
+
const tsNode = parserServices.esTreeNodeToTSNodeMap.get(node);
|
|
125
|
+
const type = checker.getTypeAtLocation(tsNode);
|
|
126
|
+
const signatures = type.getCallSignatures();
|
|
127
|
+
if (signatures.length === 0)
|
|
128
|
+
return false;
|
|
129
|
+
const isReactType = (t) => {
|
|
130
|
+
const typeStr = checker.typeToString(t);
|
|
131
|
+
return (typeStr.includes('JSX.Element') ||
|
|
132
|
+
typeStr.includes('ReactElement') ||
|
|
133
|
+
typeStr.includes('ReactNode'));
|
|
134
|
+
};
|
|
135
|
+
return signatures.some((signature) => {
|
|
136
|
+
const returnType = checker.getReturnTypeOfSignature(signature);
|
|
137
|
+
if (isReactType(returnType))
|
|
138
|
+
return true;
|
|
139
|
+
if (returnType.isUnion()) {
|
|
140
|
+
return returnType.types.some((t) => isReactType(t));
|
|
141
|
+
}
|
|
142
|
+
return false;
|
|
143
|
+
});
|
|
144
|
+
}
|
|
94
145
|
return {
|
|
95
146
|
// Check JSX attributes for callback props
|
|
96
147
|
JSXAttribute(node) {
|
|
@@ -137,13 +188,20 @@ module.exports = (0, createRule_1.createRule)({
|
|
|
137
188
|
if (isFunctionType(node.value.expression) &&
|
|
138
189
|
propName &&
|
|
139
190
|
!propName.startsWith('on') &&
|
|
191
|
+
!propName.startsWith('render') &&
|
|
192
|
+
!acceptsNonFunctionValue(node.value.expression) &&
|
|
193
|
+
!isRenderFunction(node.value.expression) &&
|
|
140
194
|
!isReactComponentType(node.value.expression)) {
|
|
195
|
+
const eventName = propName.charAt(0).toUpperCase() + propName.slice(1);
|
|
141
196
|
context.report({
|
|
142
197
|
node,
|
|
143
198
|
messageId: 'callbackPropPrefix',
|
|
199
|
+
data: {
|
|
200
|
+
propName,
|
|
201
|
+
eventName,
|
|
202
|
+
},
|
|
144
203
|
fix(fixer) {
|
|
145
204
|
// Convert camelCase to PascalCase for the event name
|
|
146
|
-
const eventName = propName.charAt(0).toUpperCase() + propName.slice(1);
|
|
147
205
|
return fixer.replaceText(node.name, `on${eventName}`);
|
|
148
206
|
},
|
|
149
207
|
});
|
|
@@ -159,6 +217,7 @@ module.exports = (0, createRule_1.createRule)({
|
|
|
159
217
|
context.report({
|
|
160
218
|
node,
|
|
161
219
|
messageId: 'callbackFunctionPrefix',
|
|
220
|
+
data: { functionName },
|
|
162
221
|
});
|
|
163
222
|
return;
|
|
164
223
|
}
|
|
@@ -169,6 +228,7 @@ module.exports = (0, createRule_1.createRule)({
|
|
|
169
228
|
context.report({
|
|
170
229
|
node,
|
|
171
230
|
messageId: 'callbackFunctionPrefix',
|
|
231
|
+
data: { functionName },
|
|
172
232
|
});
|
|
173
233
|
return;
|
|
174
234
|
}
|
|
@@ -220,6 +280,7 @@ module.exports = (0, createRule_1.createRule)({
|
|
|
220
280
|
context.report({
|
|
221
281
|
node,
|
|
222
282
|
messageId: 'callbackFunctionPrefix',
|
|
283
|
+
data: { functionName },
|
|
223
284
|
fix(fixer) {
|
|
224
285
|
// Remove 'handle' prefix and convert first character to lowercase
|
|
225
286
|
const newName = functionName.slice(6).charAt(0).toLowerCase() +
|
|
@@ -248,6 +309,7 @@ module.exports = (0, createRule_1.createRule)({
|
|
|
248
309
|
context.report({
|
|
249
310
|
node: node.key,
|
|
250
311
|
messageId: 'callbackFunctionPrefix',
|
|
312
|
+
data: { functionName: name },
|
|
251
313
|
});
|
|
252
314
|
return;
|
|
253
315
|
}
|
|
@@ -256,12 +318,14 @@ module.exports = (0, createRule_1.createRule)({
|
|
|
256
318
|
context.report({
|
|
257
319
|
node: node.key,
|
|
258
320
|
messageId: 'callbackFunctionPrefix',
|
|
321
|
+
data: { functionName: name },
|
|
259
322
|
});
|
|
260
323
|
return;
|
|
261
324
|
}
|
|
262
325
|
context.report({
|
|
263
326
|
node: node.key,
|
|
264
327
|
messageId: 'callbackFunctionPrefix',
|
|
328
|
+
data: { functionName: name },
|
|
265
329
|
fix(fixer) {
|
|
266
330
|
// Remove 'handle' prefix and convert first character to lowercase
|
|
267
331
|
const newName = name.slice(6).charAt(0).toLowerCase() + name.slice(7);
|
|
@@ -277,6 +341,7 @@ module.exports = (0, createRule_1.createRule)({
|
|
|
277
341
|
context.report({
|
|
278
342
|
node,
|
|
279
343
|
messageId: 'callbackFunctionPrefix',
|
|
344
|
+
data: { functionName: node.parameter.name },
|
|
280
345
|
});
|
|
281
346
|
}
|
|
282
347
|
},
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { TSESLint } from '@typescript-eslint/utils';
|
|
2
|
-
type MessageIds = 'dynamicHttpsErrors' | 'missingThirdArgument';
|
|
2
|
+
type MessageIds = 'dynamicHttpsErrors' | 'missingThirdArgument' | 'missingDetailsProperty' | 'missingDetailsDueToSpread' | 'unexpectedExtraArgumentForObjectCall';
|
|
3
3
|
export declare const dynamicHttpsErrors: TSESLint.RuleModule<MessageIds, never[]>;
|
|
4
4
|
export {};
|