diff --git a/.husky/pre-commit b/.husky/pre-commit index 1c0ffde0..1dc40bae 100755 --- a/.husky/pre-commit +++ b/.husky/pre-commit @@ -1,5 +1,2 @@ -#!/usr/bin/env sh -. "$(dirname -- "$0")/_/husky.sh" - # npm test npx lint-staged diff --git a/eslint.config.mjs b/eslint.config.mjs new file mode 100644 index 00000000..1275a94f --- /dev/null +++ b/eslint.config.mjs @@ -0,0 +1,48 @@ +import { FlatCompat } from "@eslint/eslintrc"; +import js from "@eslint/js"; +import typescriptEslint from "@typescript-eslint/eslint-plugin"; +import tsParser from "@typescript-eslint/parser"; +import globals from "globals"; +import path from "node:path"; +import { fileURLToPath } from "node:url"; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); +const compat = new FlatCompat({ + baseDirectory: __dirname, + recommendedConfig: js.configs.recommended, + allConfig: js.configs.all +}); + +export default [ + ...compat.extends("eslint:recommended", "plugin:@typescript-eslint/recommended", "prettier"), + { + plugins: { + "@typescript-eslint": typescriptEslint, + }, + + languageOptions: { + globals: { + ...globals.browser, + ...globals.node, + }, + + parser: tsParser, + ecmaVersion: "latest", + sourceType: "module", + }, + + rules: { + indent: ["error", 4], + "linebreak-style": ["error", "unix"], + quotes: ["error", "double"], + semi: ["error", "always"], + "@typescript-eslint/no-explicit-any": "off", + "@typescript-eslint/no-unused-vars": "off", + "@typescript-eslint/no-inferrable-types": ["warn", { + ignoreParameters: true, + ignoreProperties: true, + }], + }, + }, +]; diff --git a/package-lock.json b/package-lock.json index fb1e1ac5..6efa5707 100644 --- a/package-lock.json +++ b/package-lock.json @@ -56,6 +56,8 @@ "@angular/cli": "^18.2.12", "@angular/compiler-cli": "^18.2.13", "@codecov/webpack-plugin": "^1.6.0", + "@eslint/eslintrc": "^3.2.0", + "@eslint/js": "^9.17.0", "@sentry/webpack-plugin": "^2.5.0", "@types/geojson": "^7946.0.14", "@types/jasmine": "~5.1.4", @@ -66,6 +68,7 @@ "eslint": "^9.17.0", "eslint-config-prettier": "^9.0.0", "eslint-plugin-json": "^4.0.0", + "globals": "^15.14.0", "gtfs-types": "^4.0.0", "husky": "^9.0.0", "jasmine-core": "~5.5.0", @@ -3229,6 +3232,16 @@ "node": ">=6.9.0" } }, + "node_modules/@babel/plugin-transform-classes/node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, "node_modules/@babel/plugin-transform-computed-properties": { "version": "7.25.9", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.25.9.tgz", @@ -4140,6 +4153,16 @@ "node": ">=6.9.0" } }, + "node_modules/@babel/traverse/node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, "node_modules/@babel/traverse/node_modules/jsesc": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", @@ -5669,18 +5692,6 @@ "mlly": "^1.7.3" } }, - "node_modules/@iconify/utils/node_modules/globals": { - "version": "15.14.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-15.14.0.tgz", - "integrity": "sha512-OkToC372DtlQeje9/zHIo5CT8lRP/FUgEOKBEhU4e0abL7J7CD24fD9ohiLN5hagG/kWCYj4K5oaxxtj2Z0Dig==", - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/@inquirer/checkbox": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/@inquirer/checkbox/-/checkbox-2.5.0.tgz", @@ -14267,13 +14278,15 @@ } }, "node_modules/globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true, + "version": "15.14.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-15.14.0.tgz", + "integrity": "sha512-OkToC372DtlQeje9/zHIo5CT8lRP/FUgEOKBEhU4e0abL7J7CD24fD9ohiLN5hagG/kWCYj4K5oaxxtj2Z0Dig==", "license": "MIT", "engines": { - "node": ">=4" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/globalthis": { diff --git a/package.json b/package.json index a98db985..7327271e 100644 --- a/package.json +++ b/package.json @@ -69,6 +69,8 @@ "@angular/cli": "^18.2.12", "@angular/compiler-cli": "^18.2.13", "@codecov/webpack-plugin": "^1.6.0", + "@eslint/eslintrc": "^3.2.0", + "@eslint/js": "^9.17.0", "@sentry/webpack-plugin": "^2.5.0", "@types/geojson": "^7946.0.14", "@types/jasmine": "~5.1.4", @@ -79,6 +81,7 @@ "eslint": "^9.17.0", "eslint-config-prettier": "^9.0.0", "eslint-plugin-json": "^4.0.0", + "globals": "^15.14.0", "gtfs-types": "^4.0.0", "husky": "^9.0.0", "jasmine-core": "~5.5.0", diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 9725b9e7..feed4939 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -5,7 +5,7 @@ import { RecaptchaFormsModule, RecaptchaV3Module, ReCaptchaV3Service, -} from "ng-recaptcha"; +} from "ng-recaptcha-2"; import { NzAlertModule } from "ng-zorro-antd/alert"; import { NzDrawerService } from "ng-zorro-antd/drawer"; import { en_US, NZ_I18N } from "ng-zorro-antd/i18n"; @@ -16,6 +16,7 @@ import { NzNotificationModule } from "ng-zorro-antd/notification"; import { MarkdownModule, provideMarkdown } from "ngx-markdown"; import { registerLocaleData } from "@angular/common"; +import { provideHttpClient } from "@angular/common/http"; import en from "@angular/common/locales/en"; import { APP_INITIALIZER, ErrorHandler, NgModule } from "@angular/core"; import { @@ -33,9 +34,8 @@ import { getStorage, provideStorage } from "@angular/fire/storage"; import { BrowserModule } from "@angular/platform-browser"; import { BrowserAnimationsModule } from "@angular/platform-browser/animations"; import { Router } from "@angular/router"; -import * as Sentry from "@sentry/angular-ivy"; +import * as Sentry from "@sentry/angular"; -// import build from "../build"; import { environment } from "../environments/environment"; import { FooterComponent } from "./@ui/footer/footer.component"; import { AppRoutingModule } from "./app-routing.module"; @@ -85,7 +85,7 @@ const providers: any[] = [ }, { provide: APP_INITIALIZER, - // eslint-disable-next-line @typescript-eslint/no-empty-function + useFactory: () => () => {}, deps: [Sentry.TraceService], multi: true, @@ -105,6 +105,7 @@ const providers: any[] = [ provideDatabase(() => getDatabase()), provideStorage(() => getStorage()), provideMarkdown(), + provideHttpClient(), NzModalService, NzImageService, NzDrawerService, diff --git a/src/app/console/events-table/events-table.component.ts b/src/app/console/events-table/events-table.component.ts index 7329b341..46dfc1c8 100644 --- a/src/app/console/events-table/events-table.component.ts +++ b/src/app/console/events-table/events-table.component.ts @@ -243,7 +243,7 @@ export class ConsoleEventsTableComponent implements OnInit, OnDestroy { return !rows.includes(elem.id); }); } - this.showLoading = loading; + this.showLoading = loading ?? false; }); } diff --git a/src/app/console/services/mark-read.service.ts b/src/app/console/services/mark-read.service.ts index 537f4900..7448a3a6 100644 --- a/src/app/console/services/mark-read.service.ts +++ b/src/app/console/services/mark-read.service.ts @@ -1,5 +1,5 @@ import { Apollo, gql } from "apollo-angular"; -import { ReCaptchaV3Service } from "ng-recaptcha"; +import { ReCaptchaV3Service } from "ng-recaptcha-2"; import { firstValueFrom } from "rxjs"; import { AuthService } from "src/app/services/auth.service"; diff --git a/src/app/header/menu/menu.component.ts b/src/app/header/menu/menu.component.ts index 490ad4b0..50d5a4d9 100644 --- a/src/app/header/menu/menu.component.ts +++ b/src/app/header/menu/menu.component.ts @@ -11,7 +11,7 @@ import { Output, } from "@angular/core"; import { Router } from "@angular/router"; -import * as Sentry from "@sentry/angular-ivy"; +import * as Sentry from "@sentry/angular"; @Component({ selector: "d-header-menu", @@ -29,8 +29,11 @@ export class MenuComponent implements OnInit, OnDestroy { hadUpload: boolean = false; - constructor(public router: Router, private themeService: ThemeService, - private imageUploadService: ImageUploadService) { + constructor( + public router: Router, + private themeService: ThemeService, + private imageUploadService: ImageUploadService + ) { return; } @@ -46,13 +49,13 @@ export class MenuComponent implements OnInit, OnDestroy { (count) => { this.countIcon = count; - if(!this.hadUpload && count > 0) { + if (!this.hadUpload && count > 0) { this.hadUpload = true; } } ); } - + ngOnDestroy(): void { this.$countIcon?.unsubscribe(); } @@ -72,12 +75,13 @@ export class MenuComponent implements OnInit, OnDestroy { this.curLanguage = lang; } - reportBug(): void { - const feedback = Sentry.feedbackIntegration(); - feedback.openDialog(); + async reportBug(): Promise { + const form = await Sentry.feedbackIntegration().createForm(); + form.appendToDom(); + form.open(); } - toggleTheme(): void{ + toggleTheme(): void { this.themeService.toggleTheme(); } } diff --git a/src/app/profile/spottings/spottings.component.ts b/src/app/profile/spottings/spottings.component.ts index 32111ba0..210beb2b 100644 --- a/src/app/profile/spottings/spottings.component.ts +++ b/src/app/profile/spottings/spottings.component.ts @@ -5,7 +5,7 @@ import { LoadingModule, TableWidthConfig, } from "ng-devui"; -import { ReCaptchaV3Service } from "ng-recaptcha"; +import { ReCaptchaV3Service } from "ng-recaptcha-2"; import { NzToolTipModule } from "ng-zorro-antd/tooltip"; import { firstValueFrom, lastValueFrom, Subscription } from "rxjs"; import { diff --git a/src/main.ts b/src/main.ts index 23029da3..d50e65dd 100644 --- a/src/main.ts +++ b/src/main.ts @@ -5,7 +5,7 @@ import { galaxyTheme, infinityTheme } from "ng-devui/theme-collection"; import { enableProdMode } from "@angular/core"; import { platformBrowserDynamic } from "@angular/platform-browser-dynamic"; -import * as Sentry from "@sentry/angular-ivy"; +import * as Sentry from "@sentry/angular"; import { AppModule } from "./app/app.module"; import { environment } from "./environments/environment"; @@ -15,13 +15,13 @@ Sentry.init({ tunnel: environment.sentry.tunnel, environment: environment.sentry.environment, integrations: [ - Sentry.browserTracingIntegration({ - tracingOrigins: environment.sentry.tracingOrigins, - _experiments: { - enableInteractions: true, - } - }), + Sentry.browserTracingIntegration(), Sentry.replayIntegration(), + Sentry.feedbackIntegration({ + // Additional SDK configuration goes in here, for example: + colorScheme: "system", + autoInject: false, + }), ], // Set tracesSampleRate to 1.0 to capture 100%