Skip to content

Commit 68ed448

Browse files
authored
Fix Angular ESLint v13 (#22)
* Fix running this rule on Angular ESLint 13. * Fix CI.
1 parent ed457fe commit 68ed448

File tree

8 files changed

+85
-12
lines changed

8 files changed

+85
-12
lines changed

.cspell.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
"jerone",
2121
"lcov",
2222
"postpack",
23+
"rimraf",
2324
"SARIF",
2425
"Snyk",
2526
"sonarcloud",

.github/workflows/ci.yml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ jobs:
1212
runs-on: ubuntu-latest
1313
steps:
1414
- uses: actions/checkout@v4
15-
- uses: actions/setup-node@v3
15+
- uses: actions/setup-node@v4
1616
- run: npm ci --no-fund
1717
- run: npm run lint
1818

@@ -45,18 +45,18 @@ jobs:
4545
steps:
4646
- uses: actions/checkout@v4
4747
- name: Setup Node.js ${{ matrix.node-version }}
48-
uses: actions/setup-node@v3
48+
uses: actions/setup-node@v4
4949
with:
5050
node-version: ${{ matrix.node-version }}
5151
cache: "npm"
5252
# Cannot use `npm ci`, because this package uses ESLint plugins,
5353
# which conflict with the different installations below.
54-
# Also the package-lock file is to new for npm on older NodeJS versions.
54+
# Also the package-lock file is too new for npm on older NodeJS versions.
5555
- name: Install packages
56-
run: npm install rimraf typescript jest jest-junit ts-jest
56+
run: npm install rimraf typescript jest jest-junit ts-jest semver @types/semver
5757
- name: Install Angular ESLint ${{ matrix.angular-eslint-version[0] }}
5858
run: |
59-
npm install \
59+
npm install --legacy-peer-deps \
6060
@angular-eslint/template-parser@${{ matrix.angular-eslint-version[0] }} \
6161
@angular-eslint/utils@${{ matrix.angular-eslint-version[0] }} \
6262
@angular/compiler@${{ matrix.angular-eslint-version[0] }} \

package-lock.json

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@
5858
"jest-junit": "16.0.0",
5959
"lockfile-lint": "4.12.1",
6060
"rimraf": "5.0.1",
61-
"semver": "7.5.4",
61+
"semver": "7.6.0",
6262
"ts-jest": "29.1.1",
6363
"typescript": "5.1.6"
6464
},
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
// The method `ensureTemplateParser` is exported since ESLint Angular v14.4.0.
2+
// Any version before that requires the fallback.
3+
// See https://github.com/angular-eslint/angular-eslint/issues/888
4+
// Copied from https://github.com/angular-eslint/angular-eslint/blob/025ad9df4006ccd482b85df93ef52a0d5ebfa29d/packages/utils/src/eslint-plugin-template/parser-services.ts#L28-L45
5+
// Use `import { ensureTemplateParser } from "@angular-eslint/utils";` once ESLint Angular < v14.4.0 is dropped.
6+
7+
import type {
8+
ParseSourceSpan,
9+
TmplAstElement,
10+
} from "@angular-eslint/bundled-angular-compiler";
11+
import type { TSESLint, TSESTree } from "@typescript-eslint/utils";
12+
13+
export interface TemplateParserServices {
14+
convertNodeSourceSpanToLoc: (
15+
sourceSpan: ParseSourceSpan,
16+
) => TSESTree.SourceLocation;
17+
convertElementSourceSpanToLoc: (
18+
context: Readonly<TSESLint.RuleContext<string, ReadonlyArray<unknown>>>,
19+
node: TmplAstElement,
20+
) => TSESTree.SourceLocation;
21+
}
22+
23+
/**
24+
* Utility for rule authors to ensure that their rule is correctly being used with @angular-eslint/template-parser
25+
* If @angular-eslint/template-parser is not the configured parser when the function is invoked it will throw
26+
*/
27+
export function ensureTemplateParser(
28+
context: Readonly<TSESLint.RuleContext<string, ReadonlyArray<unknown>>>,
29+
): void {
30+
try {
31+
import("@angular-eslint/utils")
32+
.then(({ default: utils }) => {
33+
try {
34+
utils.ensureTemplateParser(context);
35+
} catch {
36+
ensureTemplateParserFallback(context);
37+
}
38+
})
39+
.catch(() => {
40+
ensureTemplateParserFallback(context);
41+
});
42+
} catch {
43+
ensureTemplateParserFallback(context);
44+
}
45+
}
46+
47+
function ensureTemplateParserFallback(
48+
context: Readonly<TSESLint.RuleContext<string, ReadonlyArray<unknown>>>,
49+
): void {
50+
if (
51+
!(context.parserServices as unknown as TemplateParserServices)
52+
?.convertNodeSourceSpanToLoc ||
53+
!(context.parserServices as unknown as TemplateParserServices)
54+
?.convertElementSourceSpanToLoc
55+
) {
56+
/**
57+
* The user needs to have configured "parser" in their eslint config and set it
58+
* to @angular-eslint/template-parser
59+
*/
60+
throw new Error(
61+
"You have used a rule which requires '@angular-eslint/template-parser' to be used as the 'parser' in your ESLint config.",
62+
);
63+
}
64+
}

src/lib/rules/eslint-plugin-angular-template-consistent-this.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,11 @@ import type {
55
TmplAstVariable,
66
PropertyRead,
77
} from "@angular-eslint/bundled-angular-compiler";
8-
import { ensureTemplateParser } from "@angular-eslint/utils";
98
import type { TSESLint, TSESTree } from "@typescript-eslint/utils";
109
import { MESSAGE_IDS } from "../message-ids";
1110
import type { MessageIds, AstWithParent, RuleOptions } from "../types";
1211
import Utils from "../utils";
12+
import { ensureTemplateParser } from "../external/ensure-template-parser";
1313

1414
export const RULE_NAME = "eslint-plugin-angular-template-consistent-this";
1515

tsconfig.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,5 @@
66
"compilerOptions": {
77
"sourceMap": true
88
},
9-
"include": ["src", "tests"]
9+
"include": ["src", "tests", "./typings.d.ts"]
1010
}

typings.d.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import type { TSESLint } from "@typescript-eslint/utils";
2+
3+
// See explanation in `./src/lib/external/ensure-template-parser.ts` why this typing is needed.
4+
declare module "@angular-eslint/utils" {
5+
export function ensureTemplateParser(
6+
context: Readonly<TSESLint.RuleContext<string, ReadonlyArray<unknown>>>,
7+
): void;
8+
}

0 commit comments

Comments
 (0)