@ethisyscore/eslint-plugin-coreconnect 1.69.1 → 1.71.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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ethisyscore/eslint-plugin-coreconnect",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.71.0",
|
|
4
4
|
"description": "ESLint rules enforcing EthisysCore plugin frontend conventions. Published so a new rule reaches every plugin on a version bump, rather than being copied into each scaffold and drifting.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "src/index.js",
|
|
@@ -24,6 +24,26 @@ export function isHookName(name) {
|
|
|
24
24
|
return /^use[A-Z]/.test(name);
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
+
/**
|
|
28
|
+
* A component, by name.
|
|
29
|
+
*
|
|
30
|
+
* These rules match on a name SUFFIX, so anything ending in the suffix is a candidate - including
|
|
31
|
+
* plain conversion helpers that are not components at all. Measured on origin/develop: `finance`
|
|
32
|
+
* and `projects` and `timesheets` all declare `isoToDateInput` and `isoUtcToLocalDateTimeInput` in
|
|
33
|
+
* `utils/dateUtils.ts` (six), and `finance` a local `toDateInput` (one). Seven reports across three
|
|
34
|
+
* repos, none of them a component, each telling the author to replace an ISO-string converter with
|
|
35
|
+
* a React date field.
|
|
36
|
+
*
|
|
37
|
+
* React's own convention is what makes this safe to detect by name: a component MUST start with an
|
|
38
|
+
* uppercase letter or JSX treats it as an HTML tag, so `<toDateInput />` cannot be the thing these
|
|
39
|
+
* rules exist to catch. That makes the guard free - it cannot mask a real duplicate.
|
|
40
|
+
*
|
|
41
|
+
* @param {string} name
|
|
42
|
+
*/
|
|
43
|
+
export function isComponentName(name) {
|
|
44
|
+
return /^[A-Z]/.test(name);
|
|
45
|
+
}
|
|
46
|
+
|
|
27
47
|
/**
|
|
28
48
|
* Is this initializer a component definition rather than a string, config object or hook result?
|
|
29
49
|
*
|
|
@@ -80,8 +100,7 @@ export function createNoLocalComponentRule({ pattern, messageId, description, me
|
|
|
80
100
|
if (!idNode || idNode.type !== "Identifier") {
|
|
81
101
|
return;
|
|
82
102
|
}
|
|
83
|
-
|
|
84
|
-
if (isHookName(idNode.name) || !pattern.test(idNode.name)) {
|
|
103
|
+
if (isHookName(idNode.name) || !isComponentName(idNode.name) || !pattern.test(idNode.name)) {
|
|
85
104
|
return;
|
|
86
105
|
}
|
|
87
106
|
|
|
@@ -8,7 +8,12 @@
|
|
|
8
8
|
* copies is six places for either to be dropped, and nothing would have noticed.
|
|
9
9
|
*
|
|
10
10
|
* Fires on a DECLARATION, never a use, so importing `DateInput` from
|
|
11
|
-
* `@ethisyscore/plugin-ui/components/
|
|
11
|
+
* `@ethisyscore/plugin-ui/components/date` and rendering it is what the rule wants.
|
|
12
|
+
*
|
|
13
|
+
* The sub-path is `/date`, not `/components/ui`: the component needs `@mui/x-date-pickers` and
|
|
14
|
+
* `dayjs`, which are optional peers, so it has a barrel of its own that a plugin without date
|
|
15
|
+
* fields never imports. That also means the `@/components/ui/<name>` file-existence alias does not
|
|
16
|
+
* reach it - a plugin deleting its local `date-input.tsx` changes the import to the package.
|
|
12
17
|
*
|
|
13
18
|
* @type {import("eslint").Rule.RuleModule}
|
|
14
19
|
*/
|
|
@@ -20,7 +25,7 @@ export default createNoLocalComponentRule({
|
|
|
20
25
|
pattern: /Date(Time)?(Input|Picker|Field)$/,
|
|
21
26
|
messageId: "noLocalDateInput",
|
|
22
27
|
description:
|
|
23
|
-
"Disallow a locally-declared date input - import DateInput from @ethisyscore/plugin-ui",
|
|
28
|
+
"Disallow a locally-declared date input - import DateInput from @ethisyscore/plugin-ui/components/date",
|
|
24
29
|
message:
|
|
25
|
-
"'{{name}}' looks like a local date input. Date fields must come from one implementation or the popper and bounds fixes drift: import { DateInput } from '@ethisyscore/plugin-ui/components/
|
|
30
|
+
"'{{name}}' looks like a local date input. Date fields must come from one implementation or the popper and bounds fixes drift: import { DateInput } from '@ethisyscore/plugin-ui/components/date' instead. If this is genuinely something else, rename it so it does not end in Input/Picker/Field.",
|
|
26
31
|
});
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* can, and this stops a fifth.
|
|
8
8
|
*
|
|
9
9
|
* Fires on a DECLARATION, never a use, so importing `EmptyState` from
|
|
10
|
-
* `@ethisyscore/plugin-ui/shared` and rendering it is what the rule wants.
|
|
10
|
+
* `@ethisyscore/plugin-ui/components/shared` and rendering it is what the rule wants.
|
|
11
11
|
*
|
|
12
12
|
* @type {import("eslint").Rule.RuleModule}
|
|
13
13
|
*/
|
|
@@ -19,7 +19,7 @@ export default createNoLocalComponentRule({
|
|
|
19
19
|
pattern: /(EmptyState|NoResults|NoData|BlankSlate)$/,
|
|
20
20
|
messageId: "noLocalEmptyState",
|
|
21
21
|
description:
|
|
22
|
-
"Disallow a locally-declared empty state - import EmptyState from @ethisyscore/plugin-ui/shared",
|
|
22
|
+
"Disallow a locally-declared empty state - import EmptyState from @ethisyscore/plugin-ui/components/shared",
|
|
23
23
|
message:
|
|
24
|
-
"'{{name}}' looks like a local empty state. Import { EmptyState } from '@ethisyscore/plugin-ui/shared' instead, so every app's empty state matches. It takes icon, title, description and fill; pass description=\"\" for a heading only.",
|
|
24
|
+
"'{{name}}' looks like a local empty state. Import { EmptyState } from '@ethisyscore/plugin-ui/components/shared' instead, so every app's empty state matches. It takes icon, title, description and fill; pass description=\"\" for a heading only.",
|
|
25
25
|
});
|