angular-typed-router-eslint 0.1.1-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 +3 -0
- package/package.json +18 -0
- package/src/configs/flat-config.d.ts +23 -0
- package/src/configs/flat-config.js +31 -0
- package/src/configs/flat-config.js.map +1 -0
- package/src/index.d.ts +1 -0
- package/src/index.js +5 -0
- package/src/index.js.map +1 -0
- package/src/lib/plugin.d.ts +11 -0
- package/src/lib/plugin.js +11 -0
- package/src/lib/plugin.js.map +1 -0
- package/src/lib/rules/no-relative-to-navigation.d.ts +3 -0
- package/src/lib/rules/no-relative-to-navigation.js +44 -0
- package/src/lib/rules/no-relative-to-navigation.js.map +1 -0
- package/src/lib/rules/no-trailing-slash-navigation.d.ts +3 -0
- package/src/lib/rules/no-trailing-slash-navigation.js +94 -0
- package/src/lib/rules/no-trailing-slash-navigation.js.map +1 -0
package/README.md
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "angular-typed-router-eslint",
|
|
3
|
+
"version": "0.1.1-0",
|
|
4
|
+
"type": "commonjs",
|
|
5
|
+
"main": "./src/index.js",
|
|
6
|
+
"types": "./src/index.d.ts",
|
|
7
|
+
"dependencies": {
|
|
8
|
+
"tslib": "^2.3.0"
|
|
9
|
+
},
|
|
10
|
+
"exports": {
|
|
11
|
+
"./package.json": "./package.json",
|
|
12
|
+
".": {
|
|
13
|
+
"types": "./src/index.d.ts",
|
|
14
|
+
"default": "./src/index.js"
|
|
15
|
+
},
|
|
16
|
+
"./configs/flat-config": "./src/configs/flat-config.js"
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
declare const config: {
|
|
2
|
+
files: string[];
|
|
3
|
+
plugins: {
|
|
4
|
+
'angular-typed-router': {
|
|
5
|
+
rules: {
|
|
6
|
+
'no-relative-to-navigation': import("@typescript-eslint/utils/dist/ts-eslint").RuleModule<"relativeTo", [], unknown, import("@typescript-eslint/utils/dist/ts-eslint").RuleListener>;
|
|
7
|
+
'no-trailing-slash-navigation': import("@typescript-eslint/utils/dist/ts-eslint").RuleModule<"navTrailing", [], unknown, import("@typescript-eslint/utils/dist/ts-eslint").RuleListener>;
|
|
8
|
+
};
|
|
9
|
+
};
|
|
10
|
+
};
|
|
11
|
+
rules: {
|
|
12
|
+
'angular-typed-router/no-relative-to-navigation': string;
|
|
13
|
+
'angular-typed-router/no-trailing-slash-navigation': string;
|
|
14
|
+
'no-restricted-imports': (string | {
|
|
15
|
+
paths: {
|
|
16
|
+
name: string;
|
|
17
|
+
importNames: string[];
|
|
18
|
+
message: string;
|
|
19
|
+
}[];
|
|
20
|
+
})[];
|
|
21
|
+
};
|
|
22
|
+
}[];
|
|
23
|
+
export default config;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const plugin_1 = require("../lib/plugin");
|
|
4
|
+
const config = [
|
|
5
|
+
{
|
|
6
|
+
files: ['**/*.ts', '**/*.html'],
|
|
7
|
+
plugins: {
|
|
8
|
+
'angular-typed-router': plugin_1.default,
|
|
9
|
+
},
|
|
10
|
+
rules: {
|
|
11
|
+
'angular-typed-router/no-relative-to-navigation': 'error',
|
|
12
|
+
'angular-typed-router/no-trailing-slash-navigation': 'error',
|
|
13
|
+
// Forbid usage of Router and RouterLink from @angular/router
|
|
14
|
+
'no-restricted-imports': [
|
|
15
|
+
'error',
|
|
16
|
+
{
|
|
17
|
+
paths: [
|
|
18
|
+
{
|
|
19
|
+
name: '@angular/router',
|
|
20
|
+
importNames: ['Router', 'RouterLink'],
|
|
21
|
+
message: 'Use TypedRouter and TypedRouterLink from angular-typed-router instead of Router and RouterLink from @angular/router',
|
|
22
|
+
},
|
|
23
|
+
],
|
|
24
|
+
},
|
|
25
|
+
],
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
];
|
|
29
|
+
exports.default = config;
|
|
30
|
+
module.exports = config;
|
|
31
|
+
//# sourceMappingURL=flat-config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"flat-config.js","sourceRoot":"","sources":["../../../../../libs/eslint-plugin/src/configs/flat-config.ts"],"names":[],"mappings":";;AAAA,0CAAmC;AAEnC,MAAM,MAAM,GAAG;IACb;QACE,KAAK,EAAE,CAAC,SAAS,EAAE,WAAW,CAAC;QAC/B,OAAO,EAAE;YACP,sBAAsB,EAAE,gBAAM;SAC/B;QACD,KAAK,EAAE;YACL,gDAAgD,EAAE,OAAO;YACzD,mDAAmD,EAAE,OAAO;YAC5D,6DAA6D;YAC7D,uBAAuB,EAAE;gBACvB,OAAO;gBACP;oBACE,KAAK,EAAE;wBACL;4BACE,IAAI,EAAE,iBAAiB;4BACvB,WAAW,EAAE,CAAC,QAAQ,EAAE,YAAY,CAAC;4BACrC,OAAO,EAAE,qHAAqH;yBAC/H;qBACF;iBACF;aACF;SACF;KACF;CACF,CAAC;AAEF,kBAAe,MAAM,CAAC;AACtB,MAAM,CAAC,OAAO,GAAG,MAAM,CAAC"}
|
package/src/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './lib/plugin';
|
package/src/index.js
ADDED
package/src/index.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../libs/eslint-plugin/src/index.ts"],"names":[],"mappings":";;;AAAA,uDAA6B"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export declare const rules: {
|
|
2
|
+
'no-relative-to-navigation': import("@typescript-eslint/utils/dist/ts-eslint").RuleModule<"relativeTo", [], unknown, import("@typescript-eslint/utils/dist/ts-eslint").RuleListener>;
|
|
3
|
+
'no-trailing-slash-navigation': import("@typescript-eslint/utils/dist/ts-eslint").RuleModule<"navTrailing", [], unknown, import("@typescript-eslint/utils/dist/ts-eslint").RuleListener>;
|
|
4
|
+
};
|
|
5
|
+
declare const _default: {
|
|
6
|
+
rules: {
|
|
7
|
+
'no-relative-to-navigation': import("@typescript-eslint/utils/dist/ts-eslint").RuleModule<"relativeTo", [], unknown, import("@typescript-eslint/utils/dist/ts-eslint").RuleListener>;
|
|
8
|
+
'no-trailing-slash-navigation': import("@typescript-eslint/utils/dist/ts-eslint").RuleModule<"navTrailing", [], unknown, import("@typescript-eslint/utils/dist/ts-eslint").RuleListener>;
|
|
9
|
+
};
|
|
10
|
+
};
|
|
11
|
+
export default _default;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.rules = void 0;
|
|
4
|
+
const no_relative_to_navigation_1 = require("./rules/no-relative-to-navigation");
|
|
5
|
+
const no_trailing_slash_navigation_1 = require("./rules/no-trailing-slash-navigation");
|
|
6
|
+
exports.rules = {
|
|
7
|
+
'no-relative-to-navigation': no_relative_to_navigation_1.default,
|
|
8
|
+
'no-trailing-slash-navigation': no_trailing_slash_navigation_1.default,
|
|
9
|
+
};
|
|
10
|
+
exports.default = { rules: exports.rules };
|
|
11
|
+
//# sourceMappingURL=plugin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin.js","sourceRoot":"","sources":["../../../../../libs/eslint-plugin/src/lib/plugin.ts"],"names":[],"mappings":";;;AAAA,iFAAuE;AACvE,uFAA6E;AAEhE,QAAA,KAAK,GAAG;IACnB,2BAA2B,EAAE,mCAAsB;IACnD,8BAA8B,EAAE,sCAAyB;CAC1D,CAAC;AAEF,kBAAe,EAAE,KAAK,EAAL,aAAK,EAAE,CAAC"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const rule = {
|
|
4
|
+
meta: {
|
|
5
|
+
type: 'problem',
|
|
6
|
+
docs: {
|
|
7
|
+
description: 'Disallow usage of "relativeTo" in router navigation extras to enforce absolute typed navigation.',
|
|
8
|
+
},
|
|
9
|
+
schema: [],
|
|
10
|
+
messages: {
|
|
11
|
+
relativeTo: 'Usage of "relativeTo" is forbidden. Use absolute paths / commands instead.',
|
|
12
|
+
},
|
|
13
|
+
},
|
|
14
|
+
defaultOptions: [],
|
|
15
|
+
create(context) {
|
|
16
|
+
function isNavigationMember(node) {
|
|
17
|
+
if (node.computed)
|
|
18
|
+
return false;
|
|
19
|
+
if (node.property.type !== 'Identifier')
|
|
20
|
+
return false;
|
|
21
|
+
return ['navigate', 'createUrlTree', 'navigateByUrl'].includes(node.property.name);
|
|
22
|
+
}
|
|
23
|
+
return {
|
|
24
|
+
CallExpression(node) {
|
|
25
|
+
if (node.callee.type === 'MemberExpression' && isNavigationMember(node.callee)) {
|
|
26
|
+
for (const arg of node.arguments) {
|
|
27
|
+
if (arg.type === 'ObjectExpression') {
|
|
28
|
+
for (const prop of arg.properties) {
|
|
29
|
+
if (prop.type === 'Property' &&
|
|
30
|
+
!prop.computed &&
|
|
31
|
+
prop.key.type === 'Identifier' &&
|
|
32
|
+
prop.key.name === 'relativeTo') {
|
|
33
|
+
context.report({ node: prop.key, messageId: 'relativeTo' });
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
};
|
|
41
|
+
},
|
|
42
|
+
};
|
|
43
|
+
exports.default = rule;
|
|
44
|
+
//# sourceMappingURL=no-relative-to-navigation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"no-relative-to-navigation.js","sourceRoot":"","sources":["../../../../../../libs/eslint-plugin/src/lib/rules/no-relative-to-navigation.ts"],"names":[],"mappings":";;AAEA,MAAM,IAAI,GAA0C;IAClD,IAAI,EAAE;QACJ,IAAI,EAAE,SAAS;QACf,IAAI,EAAE;YACJ,WAAW,EAAE,kGAAkG;SAChH;QACD,MAAM,EAAE,EAAE;QACV,QAAQ,EAAE;YACR,UAAU,EAAE,4EAA4E;SACzF;KACF;IACD,cAAc,EAAE,EAAE;IAClB,MAAM,CAAC,OAAO;QACZ,SAAS,kBAAkB,CAAC,IAA+B;YACzD,IAAI,IAAI,CAAC,QAAQ;gBAAE,OAAO,KAAK,CAAC;YAChC,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,KAAK,YAAY;gBAAE,OAAO,KAAK,CAAC;YACtD,OAAO,CAAC,UAAU,EAAE,eAAe,EAAE,eAAe,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QACrF,CAAC;QAED,OAAO;YACL,cAAc,CAAC,IAAI;gBACjB,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,KAAK,kBAAkB,IAAI,kBAAkB,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;oBAC/E,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;wBACjC,IAAI,GAAG,CAAC,IAAI,KAAK,kBAAkB,EAAE,CAAC;4BACpC,KAAK,MAAM,IAAI,IAAI,GAAG,CAAC,UAAU,EAAE,CAAC;gCAClC,IACE,IAAI,CAAC,IAAI,KAAK,UAAU;oCACxB,CAAC,IAAI,CAAC,QAAQ;oCACd,IAAI,CAAC,GAAG,CAAC,IAAI,KAAK,YAAY;oCAC9B,IAAI,CAAC,GAAG,CAAC,IAAI,KAAK,YAAY,EAC9B,CAAC;oCACD,OAAO,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,GAAG,EAAE,SAAS,EAAE,YAAY,EAAE,CAAC,CAAC;gCAC9D,CAAC;4BACH,CAAC;wBACH,CAAC;oBACH,CAAC;gBACH,CAAC;YACH,CAAC;SACF,CAAC;IACJ,CAAC;CACF,CAAC;AAEF,kBAAe,IAAI,CAAC"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
// Forbids usage of trailing slashes in navigation usage sites:
|
|
4
|
+
// 1. <a routerLink="foo/bar/"> (plain attribute)
|
|
5
|
+
// 2. router.navigateByUrl('foo/bar/')
|
|
6
|
+
// 3. router.navigateByUrl('/foo/bar/')
|
|
7
|
+
// Root '/' is allowed.
|
|
8
|
+
const rule = {
|
|
9
|
+
meta: {
|
|
10
|
+
type: 'problem',
|
|
11
|
+
docs: {
|
|
12
|
+
description: 'Disallow trailing slash in routerLink attributes and navigateByUrl string arguments.',
|
|
13
|
+
},
|
|
14
|
+
fixable: 'code',
|
|
15
|
+
messages: {
|
|
16
|
+
navTrailing: 'Navigation target "{{path}}" must not end with a trailing slash.',
|
|
17
|
+
},
|
|
18
|
+
schema: [],
|
|
19
|
+
},
|
|
20
|
+
defaultOptions: [],
|
|
21
|
+
create(context) {
|
|
22
|
+
const sourceCode = context.getSourceCode();
|
|
23
|
+
function reportAndFixLiteral(node) {
|
|
24
|
+
const path = node.value;
|
|
25
|
+
if (typeof path !== 'string')
|
|
26
|
+
return;
|
|
27
|
+
if (path.length > 1 && path.endsWith('/')) {
|
|
28
|
+
context.report({
|
|
29
|
+
node,
|
|
30
|
+
messageId: 'navTrailing',
|
|
31
|
+
data: { path },
|
|
32
|
+
fix(fixer) {
|
|
33
|
+
const fixed = path.replace(/\/+$/g, '');
|
|
34
|
+
return fixer.replaceText(node, `'${fixed}'`);
|
|
35
|
+
},
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
function checkCallExpression(node) {
|
|
40
|
+
if (node.callee.type !== 'MemberExpression' || node.callee.computed)
|
|
41
|
+
return;
|
|
42
|
+
const prop = node.callee.property;
|
|
43
|
+
if (prop.type !== 'Identifier')
|
|
44
|
+
return;
|
|
45
|
+
if (prop.name !== 'navigateByUrl')
|
|
46
|
+
return;
|
|
47
|
+
const first = node.arguments[0];
|
|
48
|
+
if (first && first.type === 'Literal' && typeof first.value === 'string') {
|
|
49
|
+
reportAndFixLiteral(first);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
// Template (HTML) files: naive regex scan for routerLink=".../" occurrences (plain attribute only)
|
|
53
|
+
function scanTemplateTextOnce() {
|
|
54
|
+
const text = sourceCode.getText();
|
|
55
|
+
// regex matches routerLink=".../" capturing path group 1
|
|
56
|
+
const attrRegex = /routerLink\s*=\s*"([^"\n]*?)"/g; // simple attribute matcher
|
|
57
|
+
let match;
|
|
58
|
+
while ((match = attrRegex.exec(text))) {
|
|
59
|
+
const full = match[0];
|
|
60
|
+
const path = match[1];
|
|
61
|
+
if (path.length > 1 && path.endsWith('/')) {
|
|
62
|
+
// Location of the path literal inside the attribute
|
|
63
|
+
const pathStartIdx = match.index + full.indexOf('"') + 1;
|
|
64
|
+
const pathEndIdx = pathStartIdx + path.length; // exclusive
|
|
65
|
+
context.report({
|
|
66
|
+
loc: {
|
|
67
|
+
start: sourceCode.getLocFromIndex(pathStartIdx),
|
|
68
|
+
end: sourceCode.getLocFromIndex(pathEndIdx),
|
|
69
|
+
},
|
|
70
|
+
messageId: 'navTrailing',
|
|
71
|
+
data: { path },
|
|
72
|
+
fix(fixer) {
|
|
73
|
+
const fixed = path.replace(/\/+$/g, '');
|
|
74
|
+
return fixer.replaceTextRange([pathStartIdx, pathEndIdx], fixed);
|
|
75
|
+
},
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
let scanned = false;
|
|
81
|
+
return {
|
|
82
|
+
Program() {
|
|
83
|
+
// Run once per file; HTML templates also come through with Program root when using angular-eslint
|
|
84
|
+
if (!scanned) {
|
|
85
|
+
scanTemplateTextOnce();
|
|
86
|
+
scanned = true;
|
|
87
|
+
}
|
|
88
|
+
},
|
|
89
|
+
CallExpression: checkCallExpression,
|
|
90
|
+
};
|
|
91
|
+
},
|
|
92
|
+
};
|
|
93
|
+
exports.default = rule;
|
|
94
|
+
//# sourceMappingURL=no-trailing-slash-navigation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"no-trailing-slash-navigation.js","sourceRoot":"","sources":["../../../../../../libs/eslint-plugin/src/lib/rules/no-trailing-slash-navigation.ts"],"names":[],"mappings":"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"}
|