@starci/eslint-canon-fe 9.2.0 → 9.4.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/CHANGELOG.md +14 -0
- package/README.md +5 -1
- package/dist/brand-values.d.ts +28 -0
- package/dist/brand-values.js +172 -0
- package/dist/button-intent.d.ts +11 -0
- package/dist/button-intent.js +361 -0
- package/dist/callback-shape.d.ts +7 -0
- package/dist/callback-shape.js +396 -0
- package/dist/class-names.d.ts +19 -0
- package/dist/class-names.js +170 -0
- package/dist/client-boundary.d.ts +42 -0
- package/dist/client-boundary.js +404 -0
- package/dist/comments.d.ts +47 -0
- package/dist/comments.js +156 -0
- package/dist/control-height.d.ts +7 -0
- package/dist/control-height.js +83 -0
- package/dist/drawing.d.ts +31 -0
- package/dist/drawing.js +376 -0
- package/dist/env-owner.d.ts +22 -0
- package/dist/env-owner.js +291 -0
- package/dist/fe-stack.d.ts +10 -0
- package/dist/fe-stack.js +73 -0
- package/dist/file-layout.d.ts +71 -0
- package/dist/file-layout.js +465 -0
- package/dist/formatting.d.ts +25 -0
- package/dist/formatting.js +104 -0
- package/dist/function-budget.d.ts +9 -0
- package/dist/function-budget.js +48 -0
- package/dist/grammar-shim.d.ts +5 -0
- package/dist/grammar-shim.js +126 -0
- package/dist/hooks-folder.d.ts +34 -0
- package/dist/hooks-folder.js +320 -0
- package/dist/hygiene.d.ts +39 -0
- package/dist/hygiene.js +540 -0
- package/dist/index.d.ts +105 -0
- package/dist/index.js +310 -0
- package/{landmark.mjs → dist/landmark.d.ts} +4 -6
- package/dist/landmark.js +6 -0
- package/dist/lib/ast.d.ts +36 -0
- package/dist/lib/ast.js +94 -0
- package/dist/lib/bindings.d.ts +84 -0
- package/dist/lib/bindings.js +168 -0
- package/dist/lib/class-text.d.ts +3 -0
- package/dist/lib/class-text.js +30 -0
- package/dist/lib/config.d.ts +81 -0
- package/dist/lib/config.js +141 -0
- package/dist/lib/drawing-scope.d.ts +5 -0
- package/{lib/drawing-scope.mjs → dist/lib/drawing-scope.js} +6 -11
- package/dist/lib/eslint-boundary.d.ts +23 -0
- package/dist/lib/eslint-boundary.js +6 -0
- package/dist/lib/fe-stack.d.ts +49 -0
- package/dist/lib/fe-stack.js +98 -0
- package/dist/lib/hfs-view.d.ts +74 -0
- package/dist/lib/hfs-view.js +6 -0
- package/dist/lib/hfs.d.ts +34 -0
- package/dist/lib/hfs.js +72 -0
- package/dist/lib/next.d.ts +4 -0
- package/dist/lib/next.js +10 -0
- package/dist/lib/own-hook-origin.d.ts +17 -0
- package/dist/lib/own-hook-origin.js +52 -0
- package/dist/lib/package-root.d.ts +4 -0
- package/dist/lib/package-root.js +10 -0
- package/dist/lib/path.d.ts +2 -0
- package/{lib/path.mjs → dist/lib/path.js} +1 -1
- package/dist/lib/platform.d.ts +26 -0
- package/{lib/platform.mjs → dist/lib/platform.js} +38 -35
- package/dist/lib/program-for.d.ts +5 -0
- package/dist/lib/program-for.js +23 -0
- package/dist/lib/pure-owner-helper.d.ts +10 -0
- package/dist/lib/pure-owner-helper.js +156 -0
- package/dist/lib/react.d.ts +16 -0
- package/dist/lib/react.js +22 -0
- package/dist/lib/redux-hook-origin.d.ts +4 -0
- package/dist/lib/redux-hook-origin.js +50 -0
- package/dist/lib/rule.d.ts +28 -0
- package/dist/lib/rule.js +5 -0
- package/dist/lib/scope.d.ts +88 -0
- package/{lib/scope.mjs → dist/lib/scope.js} +83 -93
- package/dist/lib/typed-class-values.d.ts +13 -0
- package/dist/lib/typed-class-values.js +92 -0
- package/dist/lib/types.d.ts +44 -0
- package/dist/lib/types.js +64 -0
- package/dist/lib/why.d.ts +350 -0
- package/dist/lib/why.js +350 -0
- package/dist/lint-escape-hatch.d.ts +24 -0
- package/{lint-escape-hatch.mjs → dist/lint-escape-hatch.js} +38 -45
- package/dist/lists.d.ts +31 -0
- package/dist/lists.js +202 -0
- package/dist/loading.d.ts +34 -0
- package/dist/loading.js +157 -0
- package/dist/naming.d.ts +33 -0
- package/dist/naming.js +176 -0
- package/dist/native-controls.d.ts +24 -0
- package/dist/native-controls.js +105 -0
- package/dist/next-conventions.d.ts +48 -0
- package/dist/next-conventions.js +452 -0
- package/dist/project-graph.d.ts +5 -0
- package/{project-graph.mjs → dist/project-graph.js} +8 -12
- package/dist/props-and-slots.d.ts +19 -0
- package/dist/props-and-slots.js +320 -0
- package/dist/served-locale.d.ts +38 -0
- package/dist/served-locale.js +263 -0
- package/dist/shape-slot.d.ts +18 -0
- package/dist/shape-slot.js +324 -0
- package/dist/size-and-state-budget.d.ts +46 -0
- package/dist/size-and-state-budget.js +424 -0
- package/dist/size-growth.d.ts +24 -0
- package/dist/size-growth.js +64 -0
- package/dist/sonar-parity.d.ts +5 -0
- package/{sonar-parity.mjs → dist/sonar-parity.js} +11 -7
- package/dist/surface-rules.d.ts +18 -0
- package/dist/surface-rules.js +491 -0
- package/dist/swr-family.d.ts +15 -0
- package/dist/swr-family.js +419 -0
- package/dist/the-split.d.ts +27 -0
- package/dist/the-split.js +157 -0
- package/dist/tokens.d.ts +9 -0
- package/dist/tokens.js +35 -0
- package/dist/translation.d.ts +51 -0
- package/dist/translation.js +403 -0
- package/dist/transport.d.ts +73 -0
- package/dist/transport.js +885 -0
- package/dist/type-safety.d.ts +43 -0
- package/dist/type-safety.js +139 -0
- package/dist/ui-rulings.d.ts +11 -0
- package/dist/ui-rulings.js +121 -0
- package/package.json +31 -9
- package/runtime/knowledge/hfs/canon-pins.yaml +22 -14
- package/runtime/scripts/lib/package-at.mjs +5 -5
- package/brand-values.mjs +0 -172
- package/button-intent.mjs +0 -320
- package/callback-shape.mjs +0 -332
- package/class-names.mjs +0 -149
- package/client-boundary.mjs +0 -400
- package/comments.mjs +0 -159
- package/control-height.mjs +0 -77
- package/drawing.mjs +0 -315
- package/env-owner.mjs +0 -244
- package/fe-stack.mjs +0 -86
- package/file-layout.mjs +0 -472
- package/formatting.mjs +0 -110
- package/function-budget.mjs +0 -49
- package/grammar-shim.mjs +0 -123
- package/hooks-folder.mjs +0 -300
- package/hygiene.mjs +0 -513
- package/index.mjs +0 -317
- package/lib/ast.mjs +0 -97
- package/lib/bindings.mjs +0 -159
- package/lib/class-text.mjs +0 -29
- package/lib/config.mjs +0 -142
- package/lib/fe-stack.mjs +0 -77
- package/lib/hfs.mjs +0 -49
- package/lib/next.mjs +0 -6
- package/lib/own-hook-origin.mjs +0 -53
- package/lib/program-for.mjs +0 -22
- package/lib/pure-owner-helper.mjs +0 -148
- package/lib/react.mjs +0 -28
- package/lib/redux-hook-origin.mjs +0 -44
- package/lib/typed-class-values.mjs +0 -81
- package/lib/types.mjs +0 -63
- package/lib/why.mjs +0 -352
- package/lists.mjs +0 -193
- package/loading.mjs +0 -156
- package/naming.mjs +0 -185
- package/native-controls.mjs +0 -108
- package/next-conventions.mjs +0 -447
- package/props-and-slots.mjs +0 -276
- package/served-locale.mjs +0 -243
- package/size-and-state-budget.mjs +0 -376
- package/size-growth.mjs +0 -62
- package/surface-rules.mjs +0 -443
- package/swr-family.mjs +0 -326
- package/the-split.mjs +0 -155
- package/tokens.mjs +0 -39
- package/translation.mjs +0 -392
- package/transport.mjs +0 -830
- package/type-safety.mjs +0 -147
- package/ui-rulings.mjs +0 -134
package/type-safety.mjs
DELETED
|
@@ -1,147 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The rules that hold `type-safety.md`.
|
|
3
|
-
*
|
|
4
|
-
* FOUR RULES, ONE IDEA: the compiler is told the truth or it is not told at all. The double cast, the
|
|
5
|
-
* plain assertion, the non-null assertion and `any` are the four spellings of "trust me". They live
|
|
6
|
-
* here rather than in a repository's own `eslint.config.mjs` because a repository carries no rule of
|
|
7
|
-
* its own: a rule that exists only in one repository's config is a rule the next repository forgets.
|
|
8
|
-
* The array spelling is a formatting question and stays with the formatter.
|
|
9
|
-
*
|
|
10
|
-
* THE EXEMPTION IS A SPEC, and it has to be. Proving a closed API refuses bad input means building
|
|
11
|
-
* bad input, and there is no way to construct a value the types forbid without telling the compiler
|
|
12
|
-
* to forget them. A judgement-based exemption would be argued at every call site; a spec is decided
|
|
13
|
-
* once, by its name.
|
|
14
|
-
*/
|
|
15
|
-
|
|
16
|
-
import { isProductSource } from "./lib/scope.mjs"
|
|
17
|
-
|
|
18
|
-
/** True when a type node is the `unknown` keyword. */
|
|
19
|
-
const isUnknown = (node) => Boolean(node) && node.type === "TSUnknownKeyword"
|
|
20
|
-
|
|
21
|
-
// -- TYPE-SAFETY-1 ---------------------------------------------------------------------------------
|
|
22
|
-
|
|
23
|
-
/** A cast through `unknown` erases what the compiler knew, at the seam where it mattered. */
|
|
24
|
-
export const noDoubleCast = {
|
|
25
|
-
meta: {
|
|
26
|
-
type: "problem",
|
|
27
|
-
docs: { description: "No cast through `unknown`; it turns checking off at the boundary." },
|
|
28
|
-
schema: [],
|
|
29
|
-
messages: {
|
|
30
|
-
double:
|
|
31
|
-
"Casting through `unknown` tells the compiler to forget everything it knew about this value, because the two types have nothing in common. That is not a narrowing - a narrowing is a claim the compiler can still partly check - it is an erasure, and the seam it erases is the one worth checking: where a value crosses from outside the program to inside it. Narrow from `unknown` with a check the compiler can follow, or fix the shape.",
|
|
32
|
-
},
|
|
33
|
-
},
|
|
34
|
-
create(context) {
|
|
35
|
-
if (!isProductSource(context)) return {}
|
|
36
|
-
return {
|
|
37
|
-
TSAsExpression(node) {
|
|
38
|
-
// The outer cast of a `x as unknown as T` pair: its operand is itself a cast to `unknown`.
|
|
39
|
-
const inner = node.expression
|
|
40
|
-
if (!inner || inner.type !== "TSAsExpression") return
|
|
41
|
-
if (!isUnknown(inner.typeAnnotation)) return
|
|
42
|
-
context.report({ node, messageId: "double" })
|
|
43
|
-
},
|
|
44
|
-
}
|
|
45
|
-
},
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
// -- TYPE-SAFETY-2 ---------------------------------------------------------------------------------
|
|
49
|
-
|
|
50
|
-
/** True for `as const`, the one assertion that narrows without claiming anything. */
|
|
51
|
-
const isConstAssertion = (type) => type.type === "TSTypeReference" && type.typeName.type === "Identifier" && type.typeName.name === "const"
|
|
52
|
-
|
|
53
|
-
/**
|
|
54
|
-
* A type assertion is a claim the compiler cannot check, made at the place it was going to check.
|
|
55
|
-
*
|
|
56
|
-
* WHAT IS LEFT ALLOWED. `as const` (it narrows), `as unknown` (it widens, and everything is assignable
|
|
57
|
-
* to it), and `satisfies` (it checks). The cast through `unknown` to a real type is refused by
|
|
58
|
-
* `no-double-cast`, so this rule leaves the outer half of that pair to it and reports each once.
|
|
59
|
-
*/
|
|
60
|
-
export const noTypeAssertion = {
|
|
61
|
-
meta: {
|
|
62
|
-
type: "problem",
|
|
63
|
-
docs: { description: "No `as T` or `<T>x`; narrow with a check, a guard or a parser." },
|
|
64
|
-
schema: [],
|
|
65
|
-
messages: {
|
|
66
|
-
assertion:
|
|
67
|
-
"`as {{type}}` tells the compiler to believe something it could not verify. When the claim is wrong the type system keeps saying it is right and the failure moves to a reader. Narrow with a check the compiler can follow (a type guard, `in`, a discriminant), parse the value where it enters, or use `satisfies` when the goal is only to check a literal.",
|
|
68
|
-
},
|
|
69
|
-
},
|
|
70
|
-
create(context) {
|
|
71
|
-
if (!isProductSource(context)) return {}
|
|
72
|
-
const source = context.sourceCode ?? context.getSourceCode()
|
|
73
|
-
const report = (node) =>
|
|
74
|
-
context.report({ node, messageId: "assertion", data: { type: source.getText(node.typeAnnotation) } })
|
|
75
|
-
return {
|
|
76
|
-
TSAsExpression(node) {
|
|
77
|
-
if (isConstAssertion(node.typeAnnotation) || isUnknown(node.typeAnnotation)) return
|
|
78
|
-
const inner = node.expression
|
|
79
|
-
if (inner && inner.type === "TSAsExpression" && isUnknown(inner.typeAnnotation)) return
|
|
80
|
-
report(node)
|
|
81
|
-
},
|
|
82
|
-
TSTypeAssertion(node) {
|
|
83
|
-
if (isConstAssertion(node.typeAnnotation)) return
|
|
84
|
-
report(node)
|
|
85
|
-
},
|
|
86
|
-
}
|
|
87
|
-
},
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
// -- TYPE-SAFETY-3 ---------------------------------------------------------------------------------
|
|
91
|
-
|
|
92
|
-
/** `x!` says a value is present without proving it. */
|
|
93
|
-
export const noNonNullAssertion = {
|
|
94
|
-
meta: {
|
|
95
|
-
type: "problem",
|
|
96
|
-
docs: { description: "No non-null assertion (`x!`); prove the value is there." },
|
|
97
|
-
schema: [],
|
|
98
|
-
messages: {
|
|
99
|
-
bang:
|
|
100
|
-
"`!` asserts the value is not null or undefined and proves nothing: the day it is one, the failure is a TypeError in a reader's browser rather than a branch in the code. Handle the absent case (`if`, `??`, an early return) or make the type say it cannot be absent.",
|
|
101
|
-
},
|
|
102
|
-
},
|
|
103
|
-
create(context) {
|
|
104
|
-
if (!isProductSource(context)) return {}
|
|
105
|
-
return { TSNonNullExpression: (node) => context.report({ node, messageId: "bang" }) }
|
|
106
|
-
},
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
// -- TYPE-SAFETY-4 ---------------------------------------------------------------------------------
|
|
110
|
-
|
|
111
|
-
/** `any` switches checking off for everything it touches. */
|
|
112
|
-
export const noExplicitAny = {
|
|
113
|
-
meta: {
|
|
114
|
-
type: "problem",
|
|
115
|
-
docs: { description: "No `any`; use a real type or `unknown` and narrow." },
|
|
116
|
-
schema: [],
|
|
117
|
-
messages: {
|
|
118
|
-
any:
|
|
119
|
-
"`any` turns type checking off for this value and everything derived from it, silently. Use the real type, a generic, or `unknown` and narrow it where it is used.",
|
|
120
|
-
},
|
|
121
|
-
},
|
|
122
|
-
create(context) {
|
|
123
|
-
if (!isProductSource(context)) return {}
|
|
124
|
-
return { TSAnyKeyword: (node) => context.report({ node, messageId: "any" }) }
|
|
125
|
-
},
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
/** The rules this law contributes to the plugin. */
|
|
129
|
-
export const rules = {
|
|
130
|
-
"no-double-cast": noDoubleCast,
|
|
131
|
-
"no-type-assertion": noTypeAssertion,
|
|
132
|
-
"no-non-null-assertion": noNonNullAssertion,
|
|
133
|
-
"no-explicit-any": noExplicitAny,
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
/**
|
|
137
|
-
* The level this law asks for, as the plugin's own opinion.
|
|
138
|
-
*
|
|
139
|
-
* Exact - it matches one syntactic shape - but a repository adopting it with history should expect
|
|
140
|
-
* each report to be real work: a double cast is usually load-bearing by the time anybody notices,
|
|
141
|
-
* and removing one means giving the value a shape it did not have.
|
|
142
|
-
*
|
|
143
|
-
* `any` and the array spelling are NOT published here. They belong to the TypeScript plugin's own
|
|
144
|
-
* rules, which a consuming repository already has: `@typescript-eslint/no-explicit-any` and
|
|
145
|
-
* `@typescript-eslint/array-type` with the generic default.
|
|
146
|
-
*/
|
|
147
|
-
export const recommended = Object.fromEntries(Object.keys(rules).map((name) => [`starci-fe/${name}`, "error"]))
|
package/ui-rulings.mjs
DELETED
|
@@ -1,134 +0,0 @@
|
|
|
1
|
-
/** Owner UI rulings: selection uses fill, and applications respect Grammar styling ownership. */
|
|
2
|
-
import { attribute, attributeValue, staticText } from "./lib/ast.mjs";
|
|
3
|
-
import { importOf } from "./lib/bindings.mjs";
|
|
4
|
-
import { isProductSource } from "./lib/scope.mjs";
|
|
5
|
-
import { typedClassStrings } from "./lib/typed-class-values.mjs";
|
|
6
|
-
|
|
7
|
-
/** Resolve a named or namespace import at its use, preserving lexical shadowing. */
|
|
8
|
-
const grammarComponent = (context, opening, expected) => {
|
|
9
|
-
const name = opening.name;
|
|
10
|
-
const root = name.type === "JSXMemberExpression" ? name.object : name;
|
|
11
|
-
if (root.type !== "JSXIdentifier") return false;
|
|
12
|
-
const binding = importOf(context, root);
|
|
13
|
-
if (
|
|
14
|
-
!binding ||
|
|
15
|
-
!/^@starci\/grammar(?:\/(?:common|core|offset-pop))?$/.test(
|
|
16
|
-
binding.source,
|
|
17
|
-
)
|
|
18
|
-
)
|
|
19
|
-
return false;
|
|
20
|
-
return name.type === "JSXMemberExpression"
|
|
21
|
-
? binding.imported === null && name.property.name === expected
|
|
22
|
-
: binding.imported === expected;
|
|
23
|
-
};
|
|
24
|
-
|
|
25
|
-
/** Only a final explicit attribute is proof when an opaque spread could override a value. */
|
|
26
|
-
const propText = (opening, key) => {
|
|
27
|
-
let value = null;
|
|
28
|
-
for (const entry of opening.attributes) {
|
|
29
|
-
if (entry.type === "JSXSpreadAttribute") value = null;
|
|
30
|
-
else if (entry.name.name === key) value = staticText(entry.value);
|
|
31
|
-
}
|
|
32
|
-
return value;
|
|
33
|
-
};
|
|
34
|
-
|
|
35
|
-
/** Navigation and rail/list placement are structurally identifiable without guessing from product names. */
|
|
36
|
-
const navigationList = (context, opening) => {
|
|
37
|
-
for (let node = opening.parent; node; node = node.parent) {
|
|
38
|
-
if (node.type !== "JSXElement") continue;
|
|
39
|
-
const parent = node.openingElement;
|
|
40
|
-
if (
|
|
41
|
-
["nav", "ul", "ol"].includes(parent.name.name) ||
|
|
42
|
-
["navigation", "list"].includes(propText(parent, "role"))
|
|
43
|
-
)
|
|
44
|
-
return true;
|
|
45
|
-
if (
|
|
46
|
-
["Rail", "Sidebar"].some((role) =>
|
|
47
|
-
grammarComponent(context, parent, role),
|
|
48
|
-
)
|
|
49
|
-
)
|
|
50
|
-
return true;
|
|
51
|
-
}
|
|
52
|
-
return false;
|
|
53
|
-
};
|
|
54
|
-
|
|
55
|
-
/** Navigation-like single selection uses the row fill instead of a second check indicator. */
|
|
56
|
-
export const selectionFillNoCheck = {
|
|
57
|
-
meta: {
|
|
58
|
-
type: "problem",
|
|
59
|
-
docs: {
|
|
60
|
-
description:
|
|
61
|
-
"Navigation-like single-select ListBox rows use selectionIndicator=none.",
|
|
62
|
-
},
|
|
63
|
-
schema: [],
|
|
64
|
-
messages: {
|
|
65
|
-
indicator:
|
|
66
|
-
'Use selectionIndicator="none" on this navigation-like single-select ListBox; the row fill carries selection.',
|
|
67
|
-
},
|
|
68
|
-
},
|
|
69
|
-
create(context) {
|
|
70
|
-
return {
|
|
71
|
-
JSXOpeningElement(node) {
|
|
72
|
-
if (
|
|
73
|
-
!grammarComponent(context, node, "ListBox") ||
|
|
74
|
-
!navigationList(context, node)
|
|
75
|
-
)
|
|
76
|
-
return;
|
|
77
|
-
if (["none", "multiple"].includes(propText(node, "selectionMode")))
|
|
78
|
-
return;
|
|
79
|
-
if (propText(node, "selectionIndicator") !== "none")
|
|
80
|
-
context.report({ node, messageId: "indicator" });
|
|
81
|
-
},
|
|
82
|
-
};
|
|
83
|
-
},
|
|
84
|
-
};
|
|
85
|
-
|
|
86
|
-
/** Grammar internal selectors belong to Grammar, including selectors in colocated class declarations. */
|
|
87
|
-
export const noGrammarInternalSelector = {
|
|
88
|
-
meta: {
|
|
89
|
-
type: "problem",
|
|
90
|
-
docs: {
|
|
91
|
-
description: "Application styles cannot target starci-core internals.",
|
|
92
|
-
},
|
|
93
|
-
schema: [],
|
|
94
|
-
messages: {
|
|
95
|
-
internal:
|
|
96
|
-
"Remove this starci-core- selector. Compose the Grammar public API; message actions belong in the ChatBubble floating toolbar.",
|
|
97
|
-
},
|
|
98
|
-
},
|
|
99
|
-
create(context) {
|
|
100
|
-
if (!isProductSource(context)) return {};
|
|
101
|
-
const selector = /(?:\.|_|\[class[^\]]*)starci-core-/;
|
|
102
|
-
const report = (node, text) => {
|
|
103
|
-
if (text && selector.test(text))
|
|
104
|
-
context.report({ node, messageId: "internal" });
|
|
105
|
-
};
|
|
106
|
-
return {
|
|
107
|
-
Literal(node) {
|
|
108
|
-
if (typeof node.value === "string") report(node, node.value);
|
|
109
|
-
},
|
|
110
|
-
TemplateElement(node) {
|
|
111
|
-
report(node, node.value.cooked);
|
|
112
|
-
},
|
|
113
|
-
JSXAttribute(node) {
|
|
114
|
-
if (node.name.name !== "className") return;
|
|
115
|
-
const value = attributeValue(attribute(node.parent, "className"));
|
|
116
|
-
if (value?.type !== "Identifier" && value?.type !== "MemberExpression")
|
|
117
|
-
return;
|
|
118
|
-
const strings = typedClassStrings(context, value, "classes");
|
|
119
|
-
if (strings.some((entry) => selector.test(entry.text)))
|
|
120
|
-
context.report({ node, messageId: "internal" });
|
|
121
|
-
},
|
|
122
|
-
};
|
|
123
|
-
},
|
|
124
|
-
};
|
|
125
|
-
|
|
126
|
-
export const rules = {
|
|
127
|
-
"selection-fill-no-check": selectionFillNoCheck,
|
|
128
|
-
"no-grammar-internal-selector": noGrammarInternalSelector,
|
|
129
|
-
};
|
|
130
|
-
|
|
131
|
-
/** Both owner rulings are universal errors in the frontend canon. */
|
|
132
|
-
export const recommended = Object.fromEntries(
|
|
133
|
-
Object.keys(rules).map((name) => [`starci-fe/${name}`, "error"]),
|
|
134
|
-
);
|