From 677d90063523d9c9afc0279380c99f40feed307c Mon Sep 17 00:00:00 2001 From: srakeshkumar1019 Date: Tue, 4 Jun 2024 11:30:27 +0530 Subject: [PATCH] NXP-32655: add lint & format setup --- .eslintrc.json | 47 ++++++++++++++ .github/workflows/lint.yaml | 45 +++++++++++++ .husky/pre-commit | 1 + .npmrc | 3 - angular.json | 64 ++++++++++++++----- package.json | 18 +++++- src/app/app.component.spec.ts | 5 +- src/app/app.component.ts | 2 +- src/app/app.module.ts | 4 +- .../SSO/hylandSSOManager.component.ts | 4 +- .../auth/services/auth-interceptor.service.ts | 1 - .../warning/warning.component.spec.ts | 3 +- src/app/features/warning/warning.component.ts | 2 +- .../backendErrorMessages.component.ts | 2 +- .../shared/services/common.service.spec.ts | 2 +- src/app/shared/services/common.service.ts | 2 +- .../services/persistence.service.spec.ts | 3 +- .../shared/services/persistence.service.ts | 4 +- 18 files changed, 172 insertions(+), 40 deletions(-) create mode 100644 .eslintrc.json create mode 100644 .github/workflows/lint.yaml create mode 100644 .husky/pre-commit delete mode 100644 .npmrc diff --git a/.eslintrc.json b/.eslintrc.json new file mode 100644 index 00000000..cb3286cb --- /dev/null +++ b/.eslintrc.json @@ -0,0 +1,47 @@ +{ + "root": true, + "ignorePatterns": [ + "projects/**/*" + ], + "overrides": [ + { + "files": [ + "*.ts" + ], + "extends": [ + "eslint:recommended", + "plugin:@typescript-eslint/recommended", + "plugin:@angular-eslint/recommended", + "plugin:@angular-eslint/template/process-inline-templates" + ], + "rules": { + "@angular-eslint/directive-selector": [ + "error", + { + "type": "attribute", + "prefix": "", + "style": "camelCase" + } + ], + "@angular-eslint/component-selector": [ + "error", + { + "type": "element", + "prefix": "", + "style": "kebab-case" + } + ] + } + }, + { + "files": [ + "*.html" + ], + "extends": [ + "plugin:@angular-eslint/template/recommended", + "plugin:@angular-eslint/template/accessibility" + ], + "rules": {} + } + ] + } \ No newline at end of file diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml new file mode 100644 index 00000000..e087365e --- /dev/null +++ b/.github/workflows/lint.yaml @@ -0,0 +1,45 @@ +name: Lint + +on: + pull_request: + branches: + - dev + workflow_call: + inputs: + branch: + description: 'The current branch' + default: dev + type: string + required: false + +env: + BRANCH_NAME: ${{ github.head_ref || inputs.branch || 'dev' }} + +jobs: + lint: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + with: + ref: ${{ env.BRANCH_NAME }} + + - uses: actions/setup-node@v3 + with: + registry-url: 'https://packages.nuxeo.com/repository/npm-public/' + node-version: 20 + scope: '@nuxeo' + + - name: Configure Additional Registries + run: | + npm config set @hylandsoftware:registry https://npm.pkg.github.com --global + npm config set //npm.pkg.github.com/:_authToken=${{ secrets.GIT_TOKEN }} --global + npm config set registry https://registry.npmjs.org/ --global + + - name: Install @angular/cli + run: npm install -g @angular/cli + + - name: Install + run: npm install + + - name: Lint + run: npm run lint diff --git a/.husky/pre-commit b/.husky/pre-commit new file mode 100644 index 00000000..2312dc58 --- /dev/null +++ b/.husky/pre-commit @@ -0,0 +1 @@ +npx lint-staged diff --git a/.npmrc b/.npmrc deleted file mode 100644 index fb2ceaa7..00000000 --- a/.npmrc +++ /dev/null @@ -1,3 +0,0 @@ -@hylandsoftware:registry=https://npm.pkg.github.com -//npm.pkg.github.com/:_authToken=ghp_your_authenticated_token -registry=https://registry.npmjs.org/ \ No newline at end of file diff --git a/angular.json b/angular.json index 8f3ba2f9..e2ce6a75 100644 --- a/angular.json +++ b/angular.json @@ -3,17 +3,17 @@ "version": 1, "newProjectRoot": "projects", "projects": { - "mediumclone_angular": { + "admin_console_ui": { "projectType": "application", "schematics": {}, - "root": "", + "root": "src", "sourceRoot": "src", "prefix": "app", "architect": { "build": { "builder": "@hylandsoftware/hy-ui-devkit:browser", "options": { - "outputPath": "dist/mediumclone_angular", + "outputPath": "dist/admin_console_ui", "index": "src/index.html", "main": "src/main.ts", "polyfills": "src/polyfills.ts", @@ -26,12 +26,21 @@ "output": "./" } ], - "styles": ["src/styles.scss"], + "styles": [ + "src/styles.scss" + ], "scripts": [], - "i18nPaths": ["src/app"], - "i18nModules": ["@hyland/ui", "@hyland/ui-shell"], + "i18nPaths": [ + "src/app" + ], + "i18nModules": [ + "@hyland/ui", + "@hyland/ui-shell" + ], "stylePreprocessorOptions": { - "includePaths": ["node_modules"] + "includePaths": [ + "node_modules" + ] } }, "configurations": { @@ -80,10 +89,10 @@ }, "configurations": { "production": { - "browserTarget": "mediumclone_angular:build:production" + "browserTarget": "admin_console_ui:build:production" }, "development": { - "browserTarget": "mediumclone_angular:build:development" + "browserTarget": "admin_console_ui:build:development" } }, "defaultConfiguration": "development" @@ -91,26 +100,49 @@ "extract-i18n": { "builder": "@angular-devkit/build-angular:extract-i18n", "options": { - "browserTarget": "mediumclone_angular:build" + "browserTarget": "admin_console_ui:build" } }, "test": { "builder": "@angular-devkit/build-angular:karma", "options": { - "polyfills": ["src/polyfills.ts", "zone.js", "zone.js/testing"], + "polyfills": [ + "src/polyfills.ts", + "zone.js", + "zone.js/testing" + ], "tsConfig": "tsconfig.spec.json", - "assets": ["src/favicon.ico", "src/assets"], - "styles": ["src/styles.scss"], + "assets": [ + "src/favicon.ico", + "src/assets" + ], + "styles": [ + "src/styles.scss" + ], "scripts": [], "stylePreprocessorOptions": { - "includePaths": ["node_modules"] + "includePaths": [ + "node_modules" + ] } } + }, + "lint": { + "builder": "@angular-eslint/builder:lint", + "options": { + "lintFilePatterns": [ + "src/**/*.ts", + "src/**/*.html" + ] + } } } + }, + "cli": { + "root": "src" } }, "cli": { - "analytics": "7fa2cc0e-3e82-45f7-bedc-bce83c5ba0d7" + "analytics": "bac8daa6-35ed-405f-89f7-031d9cd916f4" } -} +} \ No newline at end of file diff --git a/package.json b/package.json index 61f110b2..b049ce28 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,9 @@ "start": "ng serve", "build": "ng build", "watch": "ng build --watch --configuration development", - "test": "ng test --code-coverage" + "test": "ng test", + "lint": "ng lint", + "prepare": "husky" }, "private": true, "dependencies": { @@ -32,20 +34,32 @@ "tslib": "^2.3.0", "zone.js": "~0.13.0" }, + "lint-staged": { + "*.{ts,js,html}": "npm run lint" + }, "devDependencies": { "@angular-devkit/build-angular": "^16.2.14", + "@angular-eslint/builder": "16.3.1", + "@angular-eslint/eslint-plugin": "16.3.1", + "@angular-eslint/eslint-plugin-template": "16.3.1", + "@angular-eslint/schematics": "16.3.1", + "@angular-eslint/template-parser": "16.3.1", "@angular/cli": "^16.2.14", "@angular/compiler-cli": "^16.2.0", "@hylandsoftware/hy-ui-devkit": "^6.0.1", "@hylandsoftware/hy-ui-standards": "^6.0.1", "@types/jasmine": "~4.3.0", + "@typescript-eslint/eslint-plugin": "5.62.0", + "@typescript-eslint/parser": "5.62.0", + "eslint": "^8.51.0", + "husky": "^9.0.11", "jasmine-core": "~4.6.0", "karma": "~6.4.0", "karma-chrome-launcher": "~3.2.0", "karma-coverage": "~2.2.0", - "karma-coverage-istanbul-reporter": "^3.0.3", "karma-jasmine": "~5.1.0", "karma-jasmine-html-reporter": "~2.1.0", + "lint-staged": "^15.2.5", "typescript": "~5.1.3" } } diff --git a/src/app/app.component.spec.ts b/src/app/app.component.spec.ts index 1eb44773..10cfa029 100644 --- a/src/app/app.component.spec.ts +++ b/src/app/app.component.spec.ts @@ -19,11 +19,10 @@ describe("AppComponent", () => { get() { return null; } - set() {} } class commonServiceStub { - loadApp = new EventEmitter(); + loadApp = new EventEmitter(); } beforeEach(async () => { @@ -51,7 +50,7 @@ describe("AppComponent", () => { }); it("should open the warning dialog if warning preference is not set", () => { spyOn(component.persistenceService, "get").and.returnValue(null); - let loadAppSubscriptionSpy = spyOn( + const loadAppSubscriptionSpy = spyOn( component.commonService.loadApp, "subscribe" ).and.callThrough(); diff --git a/src/app/app.component.ts b/src/app/app.component.ts index 6bbb7fc6..858e011b 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -11,7 +11,7 @@ import { WarningComponent } from "./features/warning/warning.component"; styleUrls: ["./app.component.scss"], }) export class AppComponent implements OnInit, OnDestroy { - loadApp: Boolean = false; + loadApp = false; loadAppSubscription = new Subscription(); constructor( public dialogService: MatDialog, diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 33cfa6f8..a76e8c28 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -21,7 +21,7 @@ import { BulkActionMonitoringModule } from "./features/bulk-action-monitoring/bu import { HomeModule } from "./features/home/home.module"; import { WarningComponent } from "./features/warning/warning.component"; import { HylandSSOManagerComponent } from "./auth/components/SSO/hylandSSOManager.component"; -import { BackendErrorMessages } from "./shared/components/backendErrorMessages/backendErrorMessages.component"; +import { BackendErrorMessagesComponent } from "./shared/components/backendErrorMessages/backendErrorMessages.component"; import { AppComponent } from "./app.component"; import { AuthInterceptorService } from "./auth/services/auth-interceptor.service"; import { authReducer } from "./auth/store/reducers"; @@ -46,7 +46,7 @@ import * as HomeEffects from "./features/home/store/effects"; HeaderBarComponent, MenuBarComponent, WarningComponent, - BackendErrorMessages, + BackendErrorMessagesComponent, HylandSSOManagerComponent, BaseLayoutComponent, ], diff --git a/src/app/auth/components/SSO/hylandSSOManager.component.ts b/src/app/auth/components/SSO/hylandSSOManager.component.ts index 056cc82a..fb379429 100644 --- a/src/app/auth/components/SSO/hylandSSOManager.component.ts +++ b/src/app/auth/components/SSO/hylandSSOManager.component.ts @@ -1,4 +1,4 @@ -import { Component } from "@angular/core"; +import { Component, OnInit } from "@angular/core"; import { FormBuilder } from "@angular/forms"; import { Store } from "@ngrx/store"; import { combineLatest } from "rxjs"; @@ -13,7 +13,7 @@ import { HylandSSORequestInterface } from "../../types/hylandSSORequest.interfac selector: "ssomanager", templateUrl: "./hylandSSOManager.component.html", }) -export class HylandSSOManagerComponent { +export class HylandSSOManagerComponent implements OnInit { data$ = combineLatest({ isSubmitting: this.store.select(selectIsSubmitting), backendErrors: this.store.select(selectValidationErrors), diff --git a/src/app/auth/services/auth-interceptor.service.ts b/src/app/auth/services/auth-interceptor.service.ts index 1de251cb..e0b14e4a 100644 --- a/src/app/auth/services/auth-interceptor.service.ts +++ b/src/app/auth/services/auth-interceptor.service.ts @@ -16,7 +16,6 @@ export class AuthInterceptorService implements HttpInterceptor { request: HttpRequest, next: HttpHandler ): Observable> { - const token = this.persistenceService.get("accessToken"); const req = request.clone({ setHeaders: { //TODO: Remove this once proper authentication & login flow is implemented diff --git a/src/app/features/warning/warning.component.spec.ts b/src/app/features/warning/warning.component.spec.ts index ba80db68..fd217283 100644 --- a/src/app/features/warning/warning.component.spec.ts +++ b/src/app/features/warning/warning.component.spec.ts @@ -19,11 +19,10 @@ describe("WarningComponent", () => { get() { return null; } - set() {} } class commonServiceStub { - loadApp = new EventEmitter(); + loadApp = new EventEmitter(); } beforeEach(async () => { diff --git a/src/app/features/warning/warning.component.ts b/src/app/features/warning/warning.component.ts index 251f98a8..3f81e4c9 100644 --- a/src/app/features/warning/warning.component.ts +++ b/src/app/features/warning/warning.component.ts @@ -10,7 +10,7 @@ import { HyKeyboardFocusService } from "@hyland/ui/keyboard-focus"; styleUrls: ["./warning.component.scss"], }) export class WarningComponent implements OnInit { - public doNotWarn: boolean = false; + public doNotWarn = false; constructor( public dialogService: MatDialog, diff --git a/src/app/shared/components/backendErrorMessages/backendErrorMessages.component.ts b/src/app/shared/components/backendErrorMessages/backendErrorMessages.component.ts index e8360410..e0408747 100644 --- a/src/app/shared/components/backendErrorMessages/backendErrorMessages.component.ts +++ b/src/app/shared/components/backendErrorMessages/backendErrorMessages.component.ts @@ -5,7 +5,7 @@ import { BackendErrorsInterface } from "../../types/backendErrors.interface"; selector: "mc-backend-error-messages", templateUrl: "./backendErrorMessages.component.html", }) -export class BackendErrorMessages implements OnInit { +export class BackendErrorMessagesComponent implements OnInit { @Input() backendErrors: BackendErrorsInterface = {}; errorMessages: string[] = []; diff --git a/src/app/shared/services/common.service.spec.ts b/src/app/shared/services/common.service.spec.ts index 17a2f328..c236e1ee 100644 --- a/src/app/shared/services/common.service.spec.ts +++ b/src/app/shared/services/common.service.spec.ts @@ -15,6 +15,6 @@ describe("CommonService", () => { }); it("should test if loadApp is initialised", () => { - expect(service.loadApp).toBeInstanceOf(EventEmitter); + expect(service.loadApp).toBeInstanceOf(EventEmitter); }); }); diff --git a/src/app/shared/services/common.service.ts b/src/app/shared/services/common.service.ts index a52b7118..87490f0e 100644 --- a/src/app/shared/services/common.service.ts +++ b/src/app/shared/services/common.service.ts @@ -4,5 +4,5 @@ import { EventEmitter, Injectable } from "@angular/core"; providedIn: "root", }) export class CommonService { - loadApp = new EventEmitter(); + loadApp = new EventEmitter(); } diff --git a/src/app/shared/services/persistence.service.spec.ts b/src/app/shared/services/persistence.service.spec.ts index e48b73dd..b5b3dc54 100644 --- a/src/app/shared/services/persistence.service.spec.ts +++ b/src/app/shared/services/persistence.service.spec.ts @@ -3,7 +3,6 @@ import { TestBed } from "@angular/core/testing"; describe("PersistenceService", () => { let service: PersistenceService; - let getItemSpy: jasmine.Spy; beforeEach(() => { TestBed.configureTestingModule({ providers: [PersistenceService] }); @@ -16,7 +15,7 @@ describe("PersistenceService", () => { describe("should test getting & setting of key value pair in localstorage", () => { beforeEach(() => { - let store: { [key: string]: any } = {}; + const store: { [key: string]: any } = {}; const mockLocalStorage = { getItem: (key: string): string => { return key in store ? store[key] : null; diff --git a/src/app/shared/services/persistence.service.ts b/src/app/shared/services/persistence.service.ts index f807c11b..8a69f021 100644 --- a/src/app/shared/services/persistence.service.ts +++ b/src/app/shared/services/persistence.service.ts @@ -4,7 +4,7 @@ import { Injectable } from "@angular/core"; providedIn: "root", }) export class PersistenceService { - set(key: string, data: unknown): void { + set(key: string, data: any): void { try { localStorage.setItem(key, JSON.stringify(data)); } catch (e) { @@ -12,7 +12,7 @@ export class PersistenceService { } } - get(key: string): unknown { + get(key: string): any { try { const localStorageItem = localStorage.getItem(key); return localStorageItem ? JSON.parse(localStorageItem) : null;