@lark-apaas/fullstack-presets 1.1.5-beta.24 → 1.1.5-beta.25
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/lib/custom-eslint-rules/index.d.ts +3 -0
- package/lib/custom-eslint-rules/index.js +6 -0
- package/lib/custom-eslint-rules/no-duplicate-route-component.d.ts +14 -0
- package/lib/custom-eslint-rules/no-duplicate-route-component.js +87 -0
- package/lib/custom-eslint-rules/no-welcome-index-route.d.ts +12 -0
- package/lib/custom-eslint-rules/no-welcome-index-route.js +123 -0
- package/lib/custom-eslint-rules/require-index-route.d.ts +14 -0
- package/lib/custom-eslint-rules/require-index-route.js +98 -0
- package/lib/recommend/eslint/eslint-client.d.ts +3 -0
- package/lib/recommend/eslint/index.d.ts +3 -0
- package/lib/simple/recommend/eslint/eslint-client.d.ts +8 -2
- package/lib/simple/recommend/eslint/eslint-client.js +11 -4
- package/lib/simple/recommend/eslint/index.d.ts +8 -2
- package/package.json +1 -1
|
@@ -3,4 +3,7 @@ export declare const customRules: {
|
|
|
3
3
|
'require-app-container': import("eslint").Rule.RuleModule;
|
|
4
4
|
'no-direct-capability-api': import("eslint").Rule.RuleModule;
|
|
5
5
|
'require-scroll-reveal-hook': import("eslint").Rule.RuleModule;
|
|
6
|
+
'no-welcome-index-route': import("eslint").Rule.RuleModule;
|
|
7
|
+
'require-index-route': import("eslint").Rule.RuleModule;
|
|
8
|
+
'no-duplicate-route-component': import("eslint").Rule.RuleModule;
|
|
6
9
|
};
|
|
@@ -8,9 +8,15 @@ const no_nested_styled_jsx_1 = __importDefault(require("./no-nested-styled-jsx")
|
|
|
8
8
|
const require_app_container_1 = __importDefault(require("./require-app-container"));
|
|
9
9
|
const no_direct_capability_api_1 = __importDefault(require("./no-direct-capability-api"));
|
|
10
10
|
const require_scroll_reveal_hook_1 = __importDefault(require("./require-scroll-reveal-hook"));
|
|
11
|
+
const no_welcome_index_route_1 = __importDefault(require("./no-welcome-index-route"));
|
|
12
|
+
const require_index_route_1 = __importDefault(require("./require-index-route"));
|
|
13
|
+
const no_duplicate_route_component_1 = __importDefault(require("./no-duplicate-route-component"));
|
|
11
14
|
exports.customRules = {
|
|
12
15
|
'no-nested-styled-jsx': no_nested_styled_jsx_1.default,
|
|
13
16
|
'require-app-container': require_app_container_1.default,
|
|
14
17
|
'no-direct-capability-api': no_direct_capability_api_1.default,
|
|
15
18
|
'require-scroll-reveal-hook': require_scroll_reveal_hook_1.default,
|
|
19
|
+
'no-welcome-index-route': no_welcome_index_route_1.default,
|
|
20
|
+
'require-index-route': require_index_route_1.default,
|
|
21
|
+
'no-duplicate-route-component': no_duplicate_route_component_1.default,
|
|
16
22
|
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ESLint rule to disallow duplicate component usage across Route elements within a <Routes>.
|
|
3
|
+
*
|
|
4
|
+
* This rule enforces that within any <Routes> element, each JSX component used as the
|
|
5
|
+
* `element` prop of a <Route> must be unique. Reusing the same component across
|
|
6
|
+
* multiple routes leads to confusing routing logic.
|
|
7
|
+
*
|
|
8
|
+
* Skips:
|
|
9
|
+
* - Routes without an `element` attribute
|
|
10
|
+
* - element values that are not JSX elements (e.g., variables, null, false)
|
|
11
|
+
*/
|
|
12
|
+
import type { Rule } from 'eslint';
|
|
13
|
+
declare const rule: Rule.RuleModule;
|
|
14
|
+
export default rule;
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
// Serialize a JSXIdentifier or JSXMemberExpression to a stable string key.
|
|
4
|
+
// e.g. JSXIdentifier "Home" → "Home"
|
|
5
|
+
// JSXMemberExpression "Pages.Home" → "Pages.Home"
|
|
6
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
7
|
+
function getJSXName(node) {
|
|
8
|
+
if (!node)
|
|
9
|
+
return null;
|
|
10
|
+
if (node.type === 'JSXIdentifier')
|
|
11
|
+
return node.name;
|
|
12
|
+
if (node.type === 'JSXMemberExpression') {
|
|
13
|
+
const obj = getJSXName(node.object);
|
|
14
|
+
const prop = node.property?.name;
|
|
15
|
+
if (obj && prop)
|
|
16
|
+
return `${obj}.${prop}`;
|
|
17
|
+
}
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
20
|
+
const rule = {
|
|
21
|
+
meta: {
|
|
22
|
+
type: 'problem',
|
|
23
|
+
docs: {
|
|
24
|
+
description: 'Disallow the same component being used as the element of multiple Routes within a <Routes>',
|
|
25
|
+
category: 'Best Practices',
|
|
26
|
+
recommended: true,
|
|
27
|
+
},
|
|
28
|
+
messages: {
|
|
29
|
+
duplicateRouteComponent: "Component <{{componentName}} /> is already used in another Route's element. Remove the duplicate—keep the index Route if present.",
|
|
30
|
+
},
|
|
31
|
+
schema: [],
|
|
32
|
+
},
|
|
33
|
+
create(context) {
|
|
34
|
+
// Stack of seen-component maps, one entry per nested <Routes>
|
|
35
|
+
const routesStack = [];
|
|
36
|
+
return {
|
|
37
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
38
|
+
JSXElement(node) {
|
|
39
|
+
const tagName = node.openingElement?.name?.name;
|
|
40
|
+
if (tagName === 'Routes') {
|
|
41
|
+
routesStack.push(new Map());
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
if (tagName !== 'Route')
|
|
45
|
+
return;
|
|
46
|
+
if (routesStack.length === 0)
|
|
47
|
+
return;
|
|
48
|
+
const seenComponents = routesStack[routesStack.length - 1];
|
|
49
|
+
const attributes = node.openingElement?.attributes || [];
|
|
50
|
+
// Find the `element` attribute
|
|
51
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
52
|
+
const elementAttr = attributes.find(
|
|
53
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
54
|
+
(attr) => attr.type === 'JSXAttribute' && attr.name?.name === 'element');
|
|
55
|
+
if (!elementAttr)
|
|
56
|
+
return;
|
|
57
|
+
// element value must be a JSXExpressionContainer containing a JSXElement
|
|
58
|
+
const attrValue = elementAttr.value;
|
|
59
|
+
if (attrValue?.type !== 'JSXExpressionContainer')
|
|
60
|
+
return;
|
|
61
|
+
const expression = attrValue.expression;
|
|
62
|
+
if (!expression || expression.type !== 'JSXElement')
|
|
63
|
+
return;
|
|
64
|
+
const componentName = getJSXName(expression.openingElement?.name);
|
|
65
|
+
if (!componentName)
|
|
66
|
+
return;
|
|
67
|
+
if (seenComponents.has(componentName)) {
|
|
68
|
+
context.report({
|
|
69
|
+
node: elementAttr,
|
|
70
|
+
messageId: 'duplicateRouteComponent',
|
|
71
|
+
data: { componentName },
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
seenComponents.set(componentName, elementAttr);
|
|
76
|
+
}
|
|
77
|
+
},
|
|
78
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
79
|
+
'JSXElement:exit'(node) {
|
|
80
|
+
if (node.openingElement?.name?.name === 'Routes') {
|
|
81
|
+
routesStack.pop();
|
|
82
|
+
}
|
|
83
|
+
},
|
|
84
|
+
};
|
|
85
|
+
},
|
|
86
|
+
};
|
|
87
|
+
exports.default = rule;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ESLint rule to disallow Welcome or PagePlaceholder components as the default home page route.
|
|
3
|
+
*
|
|
4
|
+
* This rule enforces that the first-level index route (the actual home page at "/")
|
|
5
|
+
* should use an actual page component rather than placeholder components from the framework.
|
|
6
|
+
*
|
|
7
|
+
* Only checks the first-level index route nested directly under a parent Route (typically Layout).
|
|
8
|
+
* Only flags Welcome/PagePlaceholder if they are imported from @lark-apaas/client-toolkit.
|
|
9
|
+
*/
|
|
10
|
+
import type { Rule } from 'eslint';
|
|
11
|
+
declare const rule: Rule.RuleModule;
|
|
12
|
+
export default rule;
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const rule = {
|
|
4
|
+
meta: {
|
|
5
|
+
type: 'problem',
|
|
6
|
+
docs: {
|
|
7
|
+
description: 'Disallow Welcome or PagePlaceholder from @lark-apaas/client-toolkit as the default home page route element',
|
|
8
|
+
category: 'Best Practices',
|
|
9
|
+
recommended: true,
|
|
10
|
+
},
|
|
11
|
+
messages: {
|
|
12
|
+
noWelcomeIndex: 'Index route should not use {{componentName}} from @lark-apaas/client-toolkit as the element. Please create and use your own home page component (e.g., HomePage, Dashboard).',
|
|
13
|
+
},
|
|
14
|
+
schema: [],
|
|
15
|
+
},
|
|
16
|
+
create(context) {
|
|
17
|
+
// Track imports from @lark-apaas/client-toolkit
|
|
18
|
+
const toolkitImports = new Set();
|
|
19
|
+
return {
|
|
20
|
+
ImportDeclaration(node) {
|
|
21
|
+
const importNode = node;
|
|
22
|
+
const source = importNode.source?.value;
|
|
23
|
+
// Check if importing from @lark-apaas/client-toolkit (any subpath)
|
|
24
|
+
if (typeof source === 'string' &&
|
|
25
|
+
source.startsWith('@lark-apaas/client-toolkit')) {
|
|
26
|
+
// Collect all imported names
|
|
27
|
+
importNode.specifiers?.forEach(specifier => {
|
|
28
|
+
if (specifier.type === 'ImportSpecifier' &&
|
|
29
|
+
specifier.imported?.name) {
|
|
30
|
+
toolkitImports.add(specifier.imported.name);
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
JSXElement(node) {
|
|
36
|
+
const element = node;
|
|
37
|
+
const openingElement = element.openingElement;
|
|
38
|
+
if (!openingElement)
|
|
39
|
+
return;
|
|
40
|
+
const elementName = openingElement.name;
|
|
41
|
+
// Check if this is a <Route> element
|
|
42
|
+
if (elementName.type !== 'JSXIdentifier' ||
|
|
43
|
+
elementName.name !== 'Route') {
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
// Check if it has an index prop that is truthy
|
|
47
|
+
const indexAttr = openingElement.attributes.find(attr => attr.type === 'JSXAttribute' &&
|
|
48
|
+
attr.name?.type === 'JSXIdentifier' &&
|
|
49
|
+
attr.name?.name === 'index');
|
|
50
|
+
// If no index attribute, skip this route
|
|
51
|
+
if (!indexAttr) {
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
// Check if index={false} explicitly
|
|
55
|
+
const indexValue = indexAttr.value;
|
|
56
|
+
if (indexValue?.type === 'JSXExpressionContainer' &&
|
|
57
|
+
indexValue.expression?.type === 'Literal' &&
|
|
58
|
+
indexValue.expression.value === false) {
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
// Check if this is a first-level index route (nested under exactly one parent Route)
|
|
62
|
+
// The structure should be: <Routes> -> <Route element={<Layout />}> -> <Route index>
|
|
63
|
+
let routeParentCount = 0;
|
|
64
|
+
let current = element.parent;
|
|
65
|
+
while (current) {
|
|
66
|
+
if (current.type === 'JSXElement') {
|
|
67
|
+
const currentElement = current;
|
|
68
|
+
const currentOpeningElement = currentElement.openingElement;
|
|
69
|
+
const currentElementName = currentOpeningElement?.name;
|
|
70
|
+
if (currentElementName?.type === 'JSXIdentifier' &&
|
|
71
|
+
currentElementName.name === 'Route') {
|
|
72
|
+
routeParentCount++;
|
|
73
|
+
}
|
|
74
|
+
else if (currentElementName?.type === 'JSXIdentifier' &&
|
|
75
|
+
currentElementName.name === 'Routes') {
|
|
76
|
+
// Stop when we reach Routes
|
|
77
|
+
break;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
current = current.parent;
|
|
81
|
+
}
|
|
82
|
+
// Only check if this is a first-level route (exactly 1 parent Route)
|
|
83
|
+
// This corresponds to the default home page pattern:
|
|
84
|
+
// <Routes><Route element={<Layout />}><Route index /></Route></Routes>
|
|
85
|
+
if (routeParentCount !== 1) {
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
// Find the element prop
|
|
89
|
+
const elementProp = openingElement.attributes.find(attr => attr.type === 'JSXAttribute' &&
|
|
90
|
+
attr.name?.type === 'JSXIdentifier' &&
|
|
91
|
+
attr.name?.name === 'element');
|
|
92
|
+
if (!elementProp) {
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
// Check if the element prop value is a JSXExpressionContainer with a JSXElement
|
|
96
|
+
const propValue = elementProp.value;
|
|
97
|
+
if (propValue?.type === 'JSXExpressionContainer' &&
|
|
98
|
+
propValue.expression?.type === 'JSXElement') {
|
|
99
|
+
const jsxElement = propValue.expression;
|
|
100
|
+
const jsxOpeningElement = jsxElement.openingElement;
|
|
101
|
+
const jsxElementName = jsxOpeningElement?.name;
|
|
102
|
+
// Check if the component name is Welcome or PagePlaceholder
|
|
103
|
+
if (jsxElementName?.type === 'JSXIdentifier' &&
|
|
104
|
+
(jsxElementName.name === 'Welcome' ||
|
|
105
|
+
jsxElementName.name === 'PagePlaceholder')) {
|
|
106
|
+
const componentName = jsxElementName.name;
|
|
107
|
+
// Only report if this component was imported from @lark-apaas/client-toolkit
|
|
108
|
+
if (toolkitImports.has(componentName)) {
|
|
109
|
+
context.report({
|
|
110
|
+
node: elementProp,
|
|
111
|
+
messageId: 'noWelcomeIndex',
|
|
112
|
+
data: {
|
|
113
|
+
componentName,
|
|
114
|
+
},
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
},
|
|
120
|
+
};
|
|
121
|
+
},
|
|
122
|
+
};
|
|
123
|
+
exports.default = rule;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ESLint rule to require a default index route in RoutesComponent.
|
|
3
|
+
*
|
|
4
|
+
* This rule enforces that the RoutesComponent must have a first-level index route
|
|
5
|
+
* to handle the default "/" path. This ensures users don't see a 404 when visiting
|
|
6
|
+
* the application root.
|
|
7
|
+
*
|
|
8
|
+
* Valid configurations:
|
|
9
|
+
* 1. <Route index element={...} /> (first-level, nested under one parent Route)
|
|
10
|
+
* 2. <Route path="/" element={...} /> (first-level or top-level)
|
|
11
|
+
*/
|
|
12
|
+
import type { Rule } from 'eslint';
|
|
13
|
+
declare const rule: Rule.RuleModule;
|
|
14
|
+
export default rule;
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const rule = {
|
|
4
|
+
meta: {
|
|
5
|
+
type: 'problem',
|
|
6
|
+
docs: {
|
|
7
|
+
description: 'Require a default index route in RoutesComponent to handle the root path',
|
|
8
|
+
category: 'Best Practices',
|
|
9
|
+
recommended: true,
|
|
10
|
+
},
|
|
11
|
+
messages: {
|
|
12
|
+
missingIndexRoute: 'RoutesComponent is missing a default home page route. Add either:\n - <Route index element={<HomePage />} /> (nested under Layout)\n - <Route path="/" element={<HomePage />} /> (at any level)',
|
|
13
|
+
},
|
|
14
|
+
schema: [],
|
|
15
|
+
},
|
|
16
|
+
create(context) {
|
|
17
|
+
let inRoutesComponent = false;
|
|
18
|
+
let hasDefaultRoute = false;
|
|
19
|
+
let routeDepth = 0;
|
|
20
|
+
return {
|
|
21
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
22
|
+
VariableDeclarator(node) {
|
|
23
|
+
// Check if this is RoutesComponent
|
|
24
|
+
if (node.id?.name === 'RoutesComponent') {
|
|
25
|
+
inRoutesComponent = true;
|
|
26
|
+
hasDefaultRoute = false;
|
|
27
|
+
routeDepth = 0;
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
31
|
+
'VariableDeclarator:exit'(node) {
|
|
32
|
+
if (node.id?.name === 'RoutesComponent') {
|
|
33
|
+
if (!hasDefaultRoute) {
|
|
34
|
+
context.report({
|
|
35
|
+
node,
|
|
36
|
+
messageId: 'missingIndexRoute',
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
inRoutesComponent = false;
|
|
40
|
+
}
|
|
41
|
+
},
|
|
42
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
43
|
+
JSXElement(node) {
|
|
44
|
+
if (!inRoutesComponent)
|
|
45
|
+
return;
|
|
46
|
+
const elementName = node.openingElement?.name?.name;
|
|
47
|
+
// Track Route depth
|
|
48
|
+
if (elementName === 'Route') {
|
|
49
|
+
routeDepth++;
|
|
50
|
+
// Only check first-level routes (depth 1 or 2)
|
|
51
|
+
// depth 1: <Routes><Route index /></Routes>
|
|
52
|
+
// depth 2: <Routes><Route><Route index /></Route></Routes>
|
|
53
|
+
if (routeDepth <= 2) {
|
|
54
|
+
const attributes = node.openingElement?.attributes || [];
|
|
55
|
+
// Check for index attribute
|
|
56
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
57
|
+
const indexAttr = attributes.find((attr) => attr.type === 'JSXAttribute' && attr.name?.name === 'index');
|
|
58
|
+
if (indexAttr) {
|
|
59
|
+
// Make sure it's not index={false}
|
|
60
|
+
const isIndexFalse = indexAttr.value?.type === 'JSXExpressionContainer' &&
|
|
61
|
+
indexAttr.value.expression?.type === 'Literal' &&
|
|
62
|
+
indexAttr.value.expression.value === false;
|
|
63
|
+
if (!isIndexFalse) {
|
|
64
|
+
hasDefaultRoute = true;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
// Check for path="/"
|
|
68
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
69
|
+
const pathAttr = attributes.find((attr) => attr.type === 'JSXAttribute' && attr.name?.name === 'path');
|
|
70
|
+
if (pathAttr) {
|
|
71
|
+
const value = pathAttr.value;
|
|
72
|
+
// Handle path="/"
|
|
73
|
+
if (value?.type === 'Literal' && value.value === '/') {
|
|
74
|
+
hasDefaultRoute = true;
|
|
75
|
+
}
|
|
76
|
+
// Handle path={"/"}
|
|
77
|
+
if (value?.type === 'JSXExpressionContainer' &&
|
|
78
|
+
value.expression?.type === 'Literal' &&
|
|
79
|
+
value.expression.value === '/') {
|
|
80
|
+
hasDefaultRoute = true;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
},
|
|
86
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
87
|
+
'JSXElement:exit'(node) {
|
|
88
|
+
if (!inRoutesComponent)
|
|
89
|
+
return;
|
|
90
|
+
const elementName = node.openingElement?.name?.name;
|
|
91
|
+
if (elementName === 'Route') {
|
|
92
|
+
routeDepth--;
|
|
93
|
+
}
|
|
94
|
+
},
|
|
95
|
+
};
|
|
96
|
+
},
|
|
97
|
+
};
|
|
98
|
+
exports.default = rule;
|
|
@@ -19,6 +19,9 @@ declare const _default: {
|
|
|
19
19
|
'require-app-container': import("eslint").Rule.RuleModule;
|
|
20
20
|
'no-direct-capability-api': import("eslint").Rule.RuleModule;
|
|
21
21
|
'require-scroll-reveal-hook': import("eslint").Rule.RuleModule;
|
|
22
|
+
'no-welcome-index-route': import("eslint").Rule.RuleModule;
|
|
23
|
+
'require-index-route': import("eslint").Rule.RuleModule;
|
|
24
|
+
'no-duplicate-route-component': import("eslint").Rule.RuleModule;
|
|
22
25
|
};
|
|
23
26
|
};
|
|
24
27
|
};
|
|
@@ -22,6 +22,9 @@ export declare const eslintPresets: {
|
|
|
22
22
|
'require-app-container': import("eslint").Rule.RuleModule;
|
|
23
23
|
'no-direct-capability-api': import("eslint").Rule.RuleModule;
|
|
24
24
|
'require-scroll-reveal-hook': import("eslint").Rule.RuleModule;
|
|
25
|
+
'no-welcome-index-route': import("eslint").Rule.RuleModule;
|
|
26
|
+
'require-index-route': import("eslint").Rule.RuleModule;
|
|
27
|
+
'no-duplicate-route-component': import("eslint").Rule.RuleModule;
|
|
25
28
|
};
|
|
26
29
|
};
|
|
27
30
|
};
|
|
@@ -15,16 +15,19 @@ declare const _default: ({
|
|
|
15
15
|
globals: any;
|
|
16
16
|
};
|
|
17
17
|
plugins: {
|
|
18
|
+
'react-hooks': any;
|
|
19
|
+
import: any;
|
|
18
20
|
'@lark-apaas': {
|
|
19
21
|
rules: {
|
|
20
22
|
'no-nested-styled-jsx': import("eslint").Rule.RuleModule;
|
|
21
23
|
'require-app-container': import("eslint").Rule.RuleModule;
|
|
22
24
|
'no-direct-capability-api': import("eslint").Rule.RuleModule;
|
|
23
25
|
'require-scroll-reveal-hook': import("eslint").Rule.RuleModule;
|
|
26
|
+
'no-welcome-index-route': import("eslint").Rule.RuleModule;
|
|
27
|
+
'require-index-route': import("eslint").Rule.RuleModule;
|
|
28
|
+
'no-duplicate-route-component': import("eslint").Rule.RuleModule;
|
|
24
29
|
};
|
|
25
30
|
};
|
|
26
|
-
'react-hooks': any;
|
|
27
|
-
import: any;
|
|
28
31
|
};
|
|
29
32
|
settings: {
|
|
30
33
|
'import/resolver': {
|
|
@@ -45,6 +48,9 @@ declare const _default: ({
|
|
|
45
48
|
selector: string;
|
|
46
49
|
message: string;
|
|
47
50
|
})[];
|
|
51
|
+
'@lark-apaas/no-welcome-index-route': string;
|
|
52
|
+
'@lark-apaas/require-index-route': string;
|
|
53
|
+
'@lark-apaas/no-duplicate-route-component': string;
|
|
48
54
|
};
|
|
49
55
|
} | null)[];
|
|
50
56
|
export default _default;
|
|
@@ -114,10 +114,11 @@ const strictSyntaxRules = [
|
|
|
114
114
|
selector: "CallExpression[callee.name='confirm']",
|
|
115
115
|
},
|
|
116
116
|
];
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
117
|
+
// 宽松模式专用,请勿删除
|
|
118
|
+
const looseSpecificPlugins = {};
|
|
119
|
+
// 宽松模式专用,请勿删除
|
|
120
|
+
const looseSpecificRules = {};
|
|
121
|
+
// 宽松模式下覆盖的规则(关闭非关键规则)
|
|
121
122
|
const looseOverrideRules = isLooseMode
|
|
122
123
|
? {
|
|
123
124
|
'@typescript-eslint/no-unsafe-function-type': 'off',
|
|
@@ -148,6 +149,7 @@ const baseConfig = {
|
|
|
148
149
|
plugins: {
|
|
149
150
|
'react-hooks': reactHooks,
|
|
150
151
|
import: importPlugin,
|
|
152
|
+
'@lark-apaas': { rules: custom_eslint_rules_1.customRules },
|
|
151
153
|
...looseSpecificPlugins,
|
|
152
154
|
},
|
|
153
155
|
settings: {
|
|
@@ -209,6 +211,8 @@ const baseConfig = {
|
|
|
209
211
|
// 注意:严格模式的 strictSyntaxRules 仍然应用于所有文件
|
|
210
212
|
...(isLooseMode ? [] : strictSyntaxRules),
|
|
211
213
|
],
|
|
214
|
+
// 宽松模式专用规则
|
|
215
|
+
...looseSpecificRules,
|
|
212
216
|
// 宽松模式下覆盖上述规则
|
|
213
217
|
...looseOverrideRules,
|
|
214
218
|
},
|
|
@@ -225,6 +229,9 @@ const appTsxConfig = isLooseMode
|
|
|
225
229
|
...baseSyntaxRules,
|
|
226
230
|
...exports.looseRestrictSyntaxRules,
|
|
227
231
|
],
|
|
232
|
+
'@lark-apaas/no-welcome-index-route': 'error',
|
|
233
|
+
'@lark-apaas/require-index-route': 'error',
|
|
234
|
+
'@lark-apaas/no-duplicate-route-component': 'error',
|
|
228
235
|
},
|
|
229
236
|
}
|
|
230
237
|
: null;
|
|
@@ -14,16 +14,19 @@ export declare const eslintPresets: {
|
|
|
14
14
|
globals: any;
|
|
15
15
|
};
|
|
16
16
|
plugins: {
|
|
17
|
+
'react-hooks': any;
|
|
18
|
+
import: any;
|
|
17
19
|
'@lark-apaas': {
|
|
18
20
|
rules: {
|
|
19
21
|
'no-nested-styled-jsx': import("eslint").Rule.RuleModule;
|
|
20
22
|
'require-app-container': import("eslint").Rule.RuleModule;
|
|
21
23
|
'no-direct-capability-api': import("eslint").Rule.RuleModule;
|
|
22
24
|
'require-scroll-reveal-hook': import("eslint").Rule.RuleModule;
|
|
25
|
+
'no-welcome-index-route': import("eslint").Rule.RuleModule;
|
|
26
|
+
'require-index-route': import("eslint").Rule.RuleModule;
|
|
27
|
+
'no-duplicate-route-component': import("eslint").Rule.RuleModule;
|
|
23
28
|
};
|
|
24
29
|
};
|
|
25
|
-
'react-hooks': any;
|
|
26
|
-
import: any;
|
|
27
30
|
};
|
|
28
31
|
settings: {
|
|
29
32
|
'import/resolver': {
|
|
@@ -44,6 +47,9 @@ export declare const eslintPresets: {
|
|
|
44
47
|
selector: string;
|
|
45
48
|
message: string;
|
|
46
49
|
})[];
|
|
50
|
+
'@lark-apaas/no-welcome-index-route': string;
|
|
51
|
+
'@lark-apaas/require-index-route': string;
|
|
52
|
+
'@lark-apaas/no-duplicate-route-component': string;
|
|
47
53
|
};
|
|
48
54
|
} | null)[] | {
|
|
49
55
|
ignores: string[];
|