Skip to content

Commit aa74022

Browse files
committed
feat: add angular eslint into application/library
1 parent c8c5b36 commit aa74022

13 files changed

+235
-43
lines changed

angular.json

Lines changed: 63 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,20 @@
2828
"builder": "@angular-devkit/build-angular:karma",
2929
"options": {
3030
"tsConfig": "packages/angular-toaster/tsconfig.spec.json",
31-
"polyfills": ["zone.js", "zone.js/testing"]
31+
"polyfills": [
32+
"zone.js",
33+
"zone.js/testing"
34+
]
35+
}
36+
},
37+
"lint": {
38+
"builder": "@angular-eslint/builder:lint",
39+
"options": {
40+
"lintFilePatterns": [
41+
"packages/angular-toaster/**/*.ts",
42+
"packages/angular-toaster/**/*.html"
43+
],
44+
"eslintConfig": "packages/angular-toaster/eslint.config.js"
3245
}
3346
}
3447
}
@@ -50,14 +63,18 @@
5063
"outputPath": "dist/dev-app",
5164
"index": "packages/dev-app/src/index.html",
5265
"browser": "packages/dev-app/src/main.ts",
53-
"polyfills": ["zone.js"],
66+
"polyfills": [
67+
"zone.js"
68+
],
5469
"tsConfig": "packages/dev-app/tsconfig.app.json",
5570
"inlineStyleLanguage": "scss",
5671
"assets": [
5772
"packages/dev-app/src/favicon.ico",
5873
"packages/dev-app/src/assets"
5974
],
60-
"styles": ["packages/dev-app/src/styles.scss"],
75+
"styles": [
76+
"packages/dev-app/src/styles.scss"
77+
],
6178
"scripts": [],
6279
"server": "packages/dev-app/src/main.server.ts",
6380
"prerender": true,
@@ -110,14 +127,19 @@
110127
"test": {
111128
"builder": "@angular-devkit/build-angular:karma",
112129
"options": {
113-
"polyfills": ["zone.js", "zone.js/testing"],
130+
"polyfills": [
131+
"zone.js",
132+
"zone.js/testing"
133+
],
114134
"tsConfig": "packages/dev-app/tsconfig.spec.json",
115135
"inlineStyleLanguage": "scss",
116136
"assets": [
117137
"packages/dev-app/src/favicon.ico",
118138
"packages/dev-app/src/assets"
119139
],
120-
"styles": ["packages/dev-app/src/styles.scss"],
140+
"styles": [
141+
"packages/dev-app/src/styles.scss"
142+
],
121143
"scripts": []
122144
}
123145
},
@@ -128,6 +150,16 @@
128150
"name": "angular toaster dev app",
129151
"email": "[email protected]"
130152
}
153+
},
154+
"lint": {
155+
"builder": "@angular-eslint/builder:lint",
156+
"options": {
157+
"lintFilePatterns": [
158+
"packages/dev-app/**/*.ts",
159+
"packages/dev-app/**/*.html"
160+
],
161+
"eslintConfig": "packages/dev-app/eslint.config.js"
162+
}
131163
}
132164
}
133165
},
@@ -155,14 +187,18 @@
155187
"outputPath": "dist/dev-module-app",
156188
"index": "packages/dev-module-app/src/index.html",
157189
"browser": "packages/dev-module-app/src/main.ts",
158-
"polyfills": ["zone.js"],
190+
"polyfills": [
191+
"zone.js"
192+
],
159193
"tsConfig": "packages/dev-module-app/tsconfig.app.json",
160194
"inlineStyleLanguage": "scss",
161195
"assets": [
162196
"packages/dev-module-app/src/favicon.ico",
163197
"packages/dev-module-app/src/assets"
164198
],
165-
"styles": ["packages/dev-module-app/src/styles.scss"],
199+
"styles": [
200+
"packages/dev-module-app/src/styles.scss"
201+
],
166202
"scripts": [],
167203
"server": "packages/dev-module-app/src/main.server.ts",
168204
"prerender": true,
@@ -218,23 +254,40 @@
218254
"test": {
219255
"builder": "@angular-devkit/build-angular:karma",
220256
"options": {
221-
"polyfills": ["zone.js", "zone.js/testing"],
257+
"polyfills": [
258+
"zone.js",
259+
"zone.js/testing"
260+
],
222261
"tsConfig": "packages/dev-module-app/tsconfig.spec.json",
223262
"inlineStyleLanguage": "scss",
224263
"assets": [
225264
"packages/dev-module-app/src/favicon.ico",
226265
"packages/dev-module-app/src/assets"
227266
],
228-
"styles": ["packages/dev-module-app/src/styles.scss"],
267+
"styles": [
268+
"packages/dev-module-app/src/styles.scss"
269+
],
229270
"scripts": []
230271
}
272+
},
273+
"lint": {
274+
"builder": "@angular-eslint/builder:lint",
275+
"options": {
276+
"lintFilePatterns": [
277+
"packages/dev-module-app/**/*.ts",
278+
"packages/dev-module-app/**/*.html"
279+
],
280+
"eslintConfig": "packages/dev-module-app/eslint.config.js"
281+
}
231282
}
232283
}
233284
}
234285
},
235286
"cli": {
236287
"analytics": "10a22c2d-0a0a-46ae-a82a-cd74f58ee60e",
237-
"schematicCollections": ["@angular-eslint/schematics"]
288+
"schematicCollections": [
289+
"@angular-eslint/schematics"
290+
]
238291
},
239292
"schematics": {
240293
"@angular-eslint/schematics:application": {

eslint.config.js

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
// @ts-check
2+
const eslint = require("@eslint/js");
3+
const tseslint = require("typescript-eslint");
4+
const angular = require("angular-eslint");
5+
6+
module.exports = tseslint.config(
7+
{
8+
files: ["**/*.ts"],
9+
extends: [
10+
eslint.configs.recommended,
11+
...tseslint.configs.recommended,
12+
...tseslint.configs.stylistic,
13+
...angular.configs.tsRecommended,
14+
],
15+
processor: angular.processInlineTemplates,
16+
rules: {
17+
"@angular-eslint/directive-selector": [
18+
"error",
19+
{
20+
type: "attribute",
21+
prefix: "lib",
22+
style: "camelCase",
23+
},
24+
],
25+
"@angular-eslint/component-selector": [
26+
"error",
27+
{
28+
type: "element",
29+
prefix: "lib",
30+
style: "kebab-case",
31+
},
32+
],
33+
},
34+
},
35+
{
36+
files: ["**/*.html"],
37+
extends: [
38+
...angular.configs.templateRecommended,
39+
...angular.configs.templateAccessibility,
40+
],
41+
rules: {},
42+
}
43+
);
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// @ts-check
2+
const tseslint = require("typescript-eslint");
3+
const rootConfig = require("../../eslint.config.js");
4+
5+
module.exports = tseslint.config(
6+
...rootConfig,
7+
{
8+
files: ["**/*.ts"],
9+
rules: {
10+
"@angular-eslint/directive-selector": [
11+
"error",
12+
{
13+
type: "attribute",
14+
prefix: "lib",
15+
style: "camelCase",
16+
},
17+
],
18+
"@angular-eslint/component-selector": [
19+
"error",
20+
{
21+
type: "element",
22+
prefix: "lib",
23+
style: "kebab-case",
24+
},
25+
],
26+
},
27+
},
28+
{
29+
files: ["**/*.html"],
30+
rules: {},
31+
}
32+
);

packages/angular-toaster/schematics/ng-add/theming/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { getProjectFromWorkspace, getProjectTargetOptions } from '../../utils/pr
77
export function addThemeToAppStyles(options: Schema): Rule {
88
const themePath = './node_modules/angular-toaster/toaster.css';
99

10-
// eslint-disable-next-line no-unused-vars
10+
1111
return (_host: Tree, _context: SchematicContext) => {
1212
return chain([
1313
addThemeStyleToTarget(options.project, 'build', themePath),
@@ -31,7 +31,7 @@ function addThemeStyleToTarget(projectName: string, targetName: 'test' | 'build'
3131

3232
const existingStyles = styles.map(s => (typeof s === 'string' ? s : s.input));
3333

34-
for (let [, stylePath] of existingStyles.entries()) {
34+
for (const [, stylePath] of existingStyles.entries()) {
3535
if (stylePath === assetPath)
3636
return;
3737
}

packages/angular-toaster/schematics/utils/ng-module-imports.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ export function hasNgModuleImport(tree: Tree, modulePath: string, className: str
3131
throw new SchematicsException(`Could not find NgModule declaration inside: "${modulePath}"`);
3232
}
3333

34-
for (let property of ngModuleMetadata!.properties) {
34+
for (const property of ngModuleMetadata!.properties) {
3535
if (
3636
!ts.isPropertyAssignment(property) ||
3737
property.name.getText() !== 'imports' ||

packages/angular-toaster/schematics/utils/project.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ export function getProjectTestTargets(
4444
/** Gets all targets from the given project that pass a predicate check. */
4545
function getTargetsByBuilderName(
4646
project: ProjectDefinition,
47-
// eslint-disable-next-line no-unused-vars
47+
4848
predicate: (_name: string | undefined) => boolean
4949
): TargetDefinition[] {
5050
return Array.from(project.targets.keys())

packages/angular-toaster/src/angular-toaster-config.ts

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* eslint-disable no-unused-vars */
1+
22
import { InjectionToken } from "@angular/core";
33

44
export type ToastType = 'success' | 'info' | 'warning' | 'wait' | 'error';
@@ -34,15 +34,15 @@ export interface Toast {
3434
progressBarDirection?: ProgressBarDirection
3535
}
3636

37-
export const DefaultTypeClasses : { [key in ToastType]? : string } = {
37+
export const DefaultTypeClasses : Partial<Record<ToastType, string>> = {
3838
error: 'angular-toast-error',
3939
info: 'angular-toast-info',
4040
wait: 'angular-toast-wait',
4141
success: 'angular-toast-success',
4242
warning: 'angular-toast-warning'
4343
};
4444

45-
export const DefaultIconClasses : { [key in ToastType]? : string } = {
45+
export const DefaultIconClasses : Partial<Record<ToastType, string>> = {
4646
error: 'icon-error',
4747
info: 'icon-info',
4848
wait: 'icon-wait',
@@ -53,12 +53,12 @@ export const DefaultIconClasses : { [key in ToastType]? : string } = {
5353
export interface IToasterConfig {
5454
limit?: number|null;
5555
tapToDismiss?: boolean;
56-
showCloseButton?: boolean|{ [key in ToastType]?: boolean};
56+
showCloseButton?: boolean|Partial<Record<ToastType, boolean>>;
5757
closeHtml?: string;
5858
newestOnTop?: boolean;
59-
timeout?: number|{ [key in ToastType]?: number };
60-
typeClasses?: { [key in ToastType]?: string };
61-
iconClasses?: { [key in ToastType]?: string };
59+
timeout?: number|Partial<Record<ToastType, number>>;
60+
typeClasses?: Partial<Record<ToastType, string>>;
61+
iconClasses?: Partial<Record<ToastType, string>>;
6262
bodyOutputType?: BodyOutputType;
6363
bodyTemplate?: string;
6464
defaultToastType?: ToastType;
@@ -101,12 +101,12 @@ export const ToasterConfigInjectionToken: InjectionToken<IToasterConfig> = new I
101101
export class ToasterConfig implements IToasterConfig {
102102
limit?: number|null;
103103
tapToDismiss: boolean;
104-
showCloseButton: boolean|{ [key in ToastType]?: boolean };
104+
showCloseButton: boolean|Partial<Record<ToastType, boolean>>;
105105
closeHtml: string;
106106
newestOnTop: boolean;
107-
timeout: number|{ [key in ToastType]?: number };
108-
typeClasses: { [key in ToastType]?: string };
109-
iconClasses: { [key in ToastType]?: string };
107+
timeout: number|Partial<Record<ToastType, number>>;
108+
typeClasses: Partial<Record<ToastType, string>>;
109+
iconClasses: Partial<Record<ToastType, string>>;
110110
bodyOutputType: BodyOutputType;
111111
bodyTemplate: string;
112112
defaultToastType: ToastType;

packages/angular-toaster/src/angular-toaster-container.component.spec.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,7 @@ describe("ToasterContainerComponent with sync ToasterService", () => {
263263
it("addToast should use defaultTypeClass if type is empty string", () => {
264264
toasterContainer.ngOnInit();
265265

266-
toasterService.pop(<ExtendedToastType>"", "", "");
266+
toasterService.pop(("" as ExtendedToastType), "", "");
267267

268268
expect(toasterContainer.toasterconfig.defaultToastType).toBe("info");
269269
expect(toasterContainer.toasts.length).toBe(1);
@@ -339,7 +339,7 @@ describe("ToasterContainerComponent with sync ToasterService", () => {
339339
toasterContainer.toasterconfig = new ToasterConfig({
340340
showCloseButton: false,
341341
});
342-
(<any>toasterContainer.toasterconfig.showCloseButton) = "";
342+
(toasterContainer.toasterconfig.showCloseButton as any) = "";
343343
toasterContainer.ngOnInit();
344344
const toast: Toast = { type: "info" };
345345

@@ -564,21 +564,21 @@ describe("ToasterContainerComponent with sync ToasterService", () => {
564564
});
565565

566566
it("toastIdOrDefault should return empty string if toast.toastId is null", () => {
567-
let toast: Toast = { type: "info", toastId: undefined };
567+
const toast: Toast = { type: "info", toastId: undefined };
568568
const toastId = toasterContainer["toastIdOrDefault"](toast);
569569

570570
expect(toastId).toBe("");
571571
});
572572

573573
it("toastIdOrDefault should return empty string if toast.toastId is undefined", () => {
574-
let toast: Toast = { type: "info", toastId: undefined };
574+
const toast: Toast = { type: "info", toastId: undefined };
575575
const toastId = toasterContainer["toastIdOrDefault"](toast);
576576

577577
expect(toastId).toBe("");
578578
});
579579

580580
it("toastIdOrDefault should return empty string if toast.toastId is empty string", () => {
581-
let toast: Toast = { type: "info", toastId: "" };
581+
const toast: Toast = { type: "info", toastId: "" };
582582
const toastId = toasterContainer["toastIdOrDefault"](toast);
583583

584584
expect(toastId).toBe("");
@@ -587,7 +587,7 @@ describe("ToasterContainerComponent with sync ToasterService", () => {
587587
it("should use toast.toastId parameter if passed", () => {
588588
toasterContainer.ngOnInit();
589589

590-
let toast: Toast = {
590+
const toast: Toast = {
591591
type: "success",
592592
title: "",
593593
body: "",

packages/angular-toaster/src/angular-toaster-container.component.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ export class ToasterContainerComponent implements OnInit, OnDestroy {
3939
private clearToastsSubscriber!: Subscription;
4040

4141
constructor(
42-
// eslint-disable-next-line no-unused-vars
42+
4343
@Optional() @Inject(ToasterConfigInjectionToken) private _defaultToasterConfig: IToasterConfig
4444
) {
4545
this._toasterconfig = (this._defaultToasterConfig ? { ...defaultToasterConfig, ...this._defaultToasterConfig } : defaultToasterConfig) as Required<IToasterConfig>;

0 commit comments

Comments
 (0)