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 ADDED
@@ -0,0 +1,3 @@
1
+ # eslint plugin for angular-typed-router
2
+
3
+ ## Attention: Still in experimental phase
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
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const tslib_1 = require("tslib");
4
+ tslib_1.__exportStar(require("./lib/plugin"), exports);
5
+ //# sourceMappingURL=index.js.map
@@ -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,3 @@
1
+ import { TSESLint } from '@typescript-eslint/utils';
2
+ declare const rule: TSESLint.RuleModule<'relativeTo', []>;
3
+ export default rule;
@@ -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,3 @@
1
+ import { TSESLint } from '@typescript-eslint/utils';
2
+ declare const rule: TSESLint.RuleModule<'navTrailing', []>;
3
+ export default rule;
@@ -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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"}