1
0
mirror of https://github.com/bpatrik/pigallery2.git synced 2025-10-30 23:57:43 +02:00

updating eslint

This commit is contained in:
Patrik J. Braun
2025-07-28 23:45:01 +02:00
parent 1eb59f8e37
commit 8f9a00e0c8
11 changed files with 105 additions and 72 deletions

View File

@@ -2,6 +2,7 @@
import eslint from "@eslint/js";
import tseslint from "typescript-eslint";
import angular from "angular-eslint";
import chaiFriendly from 'eslint-plugin-chai-friendly';
export default tseslint.config(
{
@@ -39,5 +40,33 @@ export default tseslint.config(
...angular.configs.templateAccessibility,
],
rules: {},
}
},
{
files: ["src/common/*.ts", "src/backend/*.ts"],
extends: [
eslint.configs.recommended,
...tseslint.configs.recommended,
...tseslint.configs.stylistic,
],
rules: {
'@typescript-eslint/prefer-for-of': 'off'
}
},
{
files: ["test/*.ts"],
extends: [
eslint.configs.recommended,
...tseslint.configs.recommended,
...tseslint.configs.stylistic,
],
plugins: {
'chai-friendly': chaiFriendly
},
rules: {
// turn off the strict TS version
'@typescript-eslint/no-unused-expressions': 'off',
// and enable the chai-friendly version
'chai-friendly/no-unused-expressions': 'error'
}
},
);

58
package-lock.json generated
View File

@@ -83,6 +83,7 @@
"deep-equal-in-any-order": "2.0.5",
"ejs-loader": "0.5.0",
"eslint": "9.32.0",
"eslint-plugin-chai-friendly": "^1.1.0",
"gulp": "4.0.2",
"gulp-json-editor": "2.5.6",
"gulp-sourcemaps": "3.0.0",
@@ -111,7 +112,7 @@
"ts-node": "10.9.2",
"typescript-eslint": "8.38.0",
"webpack-bundle-analyzer": "4.10.2",
"xlf-google-translate": "1.0.0-beta.23",
"xlf-google-translate": "1.0.1",
"zone.js": "0.15.1"
},
"engines": {
@@ -15596,6 +15597,19 @@
}
}
},
"node_modules/eslint-plugin-chai-friendly": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/eslint-plugin-chai-friendly/-/eslint-plugin-chai-friendly-1.1.0.tgz",
"integrity": "sha512-+T1rClpDdXkgBAhC16vRQMI5umiWojVqkj9oUTdpma50+uByCZM/oBfxitZiOkjMRlm725mwFfz/RVgyDRvCKA==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=0.10.0"
},
"peerDependencies": {
"eslint": ">=3.0.0"
}
},
"node_modules/eslint-scope": {
"version": "8.4.0",
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz",
@@ -30376,49 +30390,19 @@
}
},
"node_modules/xlf-google-translate": {
"version": "1.0.0-beta.23",
"resolved": "https://registry.npmjs.org/xlf-google-translate/-/xlf-google-translate-1.0.0-beta.23.tgz",
"integrity": "sha512-L8A78ZSicnSTyo0rXqtpr8Szg6geRCZ0Lgw8HfSADSDtJsAmuJzvhgE26mWDL5DL5s3bqetJv+R1uhoHrGELYA==",
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/xlf-google-translate/-/xlf-google-translate-1.0.1.tgz",
"integrity": "sha512-ueiwNXc8VayKSBNr5NrhkJntD9iyca1RdxdOvh8lZPu4l2nEES7xcTuJ2dxuhzrlF4plDLhcm0oFwJJ1axDqPw==",
"dev": true,
"dependencies": {
"typeconfig": "2.0.19",
"xml2js": "0.4.23"
"reflect-metadata": "0.2.2",
"typeconfig": "2.3.1",
"xml2js": "0.6.2"
},
"bin": {
"xlf-google-translate": "cli.js"
}
},
"node_modules/xlf-google-translate/node_modules/minimist": {
"version": "1.2.5",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==",
"dev": true,
"license": "MIT"
},
"node_modules/xlf-google-translate/node_modules/typeconfig": {
"version": "2.0.19",
"resolved": "https://registry.npmjs.org/typeconfig/-/typeconfig-2.0.19.tgz",
"integrity": "sha512-TIMZ0CFt5OB2e0oHBl1JuFtGtAFR/7GsJVdBaRehBgWb4USUni2KVUd2qqxQxpI6U+ZVw7uJsRij4U14QhXmPw==",
"dev": true,
"license": "MIT",
"dependencies": {
"minimist": "1.2.5"
}
},
"node_modules/xlf-google-translate/node_modules/xml2js": {
"version": "0.4.23",
"resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.23.tgz",
"integrity": "sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug==",
"dev": true,
"license": "MIT",
"dependencies": {
"sax": ">=0.6.0",
"xmlbuilder": "~11.0.0"
},
"engines": {
"node": ">=4.0.0"
}
},
"node_modules/xml2js": {
"version": "0.6.2",
"resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.6.2.tgz",

View File

@@ -60,7 +60,6 @@
},
"devDependencies": {
"@angular-builders/custom-webpack": "19.0.1",
"angular-eslint": "19.8.1",
"@angular/animations": "19.2.14",
"@angular/cli": "19.2.15",
"@angular/common": "19.2.14",
@@ -97,7 +96,7 @@
"@types/node-geocoder": "4.2.0",
"@types/nodemailer": "6.4.17",
"@types/xml2js": "0.4.14",
"typescript-eslint": "8.38.0",
"angular-eslint": "19.8.1",
"bootstrap": "5.3.1",
"chai": "5.2.1",
"chai-http": "5.1.2",
@@ -108,6 +107,7 @@
"deep-equal-in-any-order": "2.0.5",
"ejs-loader": "0.5.0",
"eslint": "9.32.0",
"eslint-plugin-chai-friendly": "^1.1.0",
"gulp": "4.0.2",
"gulp-json-editor": "2.5.6",
"gulp-sourcemaps": "3.0.0",
@@ -134,8 +134,9 @@
"rxjs": "7.8.0",
"ts-helpers": "1.1.2",
"ts-node": "10.9.2",
"typescript-eslint": "8.38.0",
"webpack-bundle-analyzer": "4.10.2",
"xlf-google-translate": "1.0.0-beta.23",
"xlf-google-translate": "1.0.1",
"zone.js": "0.15.1"
},
"optionalDependencies": {

View File

@@ -11,7 +11,7 @@ if (forcedDebug === true) {
);
}
export type LoggerArgs = (string | number | (() => string) | Record<any, unknown> | Error);
export type LoggerArgs = (string | number | (() => string) | Record<unknown, unknown> | Error);
export type LoggerFunction = (...args: LoggerArgs[]) => void;
export interface ILogger {

View File

@@ -1,6 +1,5 @@
import {Config} from '../common/config/private/Config';
import * as express from 'express';
import {Request} from 'express';
import * as cookieParser from 'cookie-parser';
import * as _http from 'http';
import {Server as HttpServer} from 'http';
@@ -20,9 +19,8 @@ import {QueryParams} from '../common/QueryParams';
import {ConfigClassBuilder} from 'typeconfig/node';
import {ConfigClassOptions} from 'typeconfig/src/decorators/class/IConfigClass';
import {ServerConfig} from '../common/config/private/PrivateConfig';
import {unless} from 'express-unless';
// eslint-disable-next-line @typescript-eslint/no-var-requires
// eslint-disable-next-line @typescript-eslint/no-require-imports
const session = require('cookie-session');
declare const process: NodeJS.Process;
@@ -139,17 +137,24 @@ export class Server {
}
}
private SIGTERM = () =>{
private SIGTERM = () => {
Logger.info(LOG_TAG, 'SIGTERM signal received');
this.server.close(() => {
process.exit(0);
});
}
};
/**
*
* Event listener for HTTP server "error" event.
*/
private onError = (error: any) => {
private onError = (error: {
errno?: number,
code?: string,
path?: string,
syscall?: string,
stack?: string
}) => {
if (error.syscall !== 'listen') {
Logger.error(LOG_TAG, 'Server error', error);
throw error;
@@ -192,7 +197,7 @@ export class Server {
public Stop(): Promise<void> {
return new Promise((resolve, reject) => {
if(!this.server.listening){
if (!this.server.listening) {
return resolve();
}
this.server.close((err) => {

View File

@@ -1,6 +1,4 @@
interface HTMLCharDictionary {
[key: string]: string;
}
type HTMLCharDictionary = Record<string, string>;
export const HTMLChar: HTMLCharDictionary = {
"&quot;": "\"",
@@ -115,4 +113,4 @@ export const HTMLChar: HTMLCharDictionary = {
"&yacute;": "ý",
"&ycirc;": "ŷ",
"&yuml;": "ÿ"
};
};

View File

@@ -5,7 +5,7 @@ import {Utils} from './Utils';
* This contains the action of the supported list of *.pg2conf files.
* These files are passed down to the client as metaFiles (like photos and directories)
*/
export const PG2ConfMap: { sorting: { [key: string]: SortingMethod } } = {
export const PG2ConfMap: { sorting: Record<string, SortingMethod> } = {
sorting: {}
};
@@ -28,7 +28,7 @@ export enum ServerSidePG2ConfAction {
SAVED_SEARCH = 1,
}
export const ServerPG2ConfMap: { [key: string]: ServerSidePG2ConfAction } = {
export const ServerPG2ConfMap: Record<string, ServerSidePG2ConfAction> = {
'.saved_searches.pg2conf': ServerSidePG2ConfAction.SAVED_SEARCH,
};

View File

@@ -146,6 +146,7 @@ export class SearchQueryParser {
if (parts && parts.length === 3) {
timestamp = Date.UTC(parts[0], parts[1] - 1, parts[2], 0, 0, 0, 0); // Note: months are 0-based
}
// eslint-disable-next-line @typescript-eslint/no-unused-vars
} catch (e) {
// ignoring errors
}
@@ -401,11 +402,11 @@ export class SearchQueryParser {
// parse text search
const tmp = TextSearchQueryTypes.map((type) => ({
key: (this.keywords as any)[SearchQueryTypes[type]] + ':',
key: (this.keywords as never)[SearchQueryTypes[type]] + ':',
queryTemplate: {type, text: ''} as TextSearch,
})).concat(
TextSearchQueryTypes.map((type) => ({
key: (this.keywords as any)[SearchQueryTypes[type]] + '!:',
key: (this.keywords as never)[SearchQueryTypes[type]] + '!:',
queryTemplate: {type, text: '', negate: true} as TextSearch,
}))
);
@@ -629,7 +630,7 @@ export class SearchQueryParser {
);
} else {
return (
(this.keywords as any)[SearchQueryTypes[query.type]] +
(this.keywords as never)[SearchQueryTypes[query.type]] +
colon +
SearchQueryParser.stringifyText(
(query as TextSearch).text,
@@ -648,7 +649,7 @@ export class SearchQueryParser {
return '';
}
return (
(this.keywords as any)[SearchQueryTypes[query.type]] +
(this.keywords as never)[SearchQueryTypes[query.type]] +
colon +
SearchQueryParser.stringifyText(
(query as TextSearch).text,

View File

@@ -3,17 +3,17 @@ import {ClientClass} from './config/public/Config';
let Config: ClientClass;
if (typeof window !== 'undefined') {
// eslint-disable-next-line @typescript-eslint/no-var-requires
// eslint-disable-next-line @typescript-eslint/no-require-imports
Config = require('./config/public/Config').Config;
} else {
// eslint-disable-next-line @typescript-eslint/no-var-requires
// eslint-disable-next-line @typescript-eslint/no-require-imports
Config = require('./config/private/Config').Config;
}
export class SupportedFormats {
static Photos = Config.Media.Photo.supportedFormats;
// Browser supported video formats
// Read more: https://www.w3schools.com/html/html5_video.asp
// Browser-supported video formats
// Read more: https://www.w3schools.com/html/html5_video.asp
static Videos = Config.Media.Video.supportedFormats;
static MetaFiles = Config.MetaFile.supportedFormats;
// These formats need to be transcoded (with the built-in ffmpeg support)

View File

@@ -24,7 +24,8 @@ export class Utils {
});
}
static removeNullOrEmptyObj<T extends { [key: string]: any }>(obj: T): T {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
static removeNullOrEmptyObj<T extends Record<string, any>>(obj: T): T {
if (typeof obj !== 'object' || obj == null) {
return obj;
}
@@ -49,13 +50,15 @@ export class Utils {
}
static shallowClone<T>(object: T): T {
const c: any = {};
const c: T = {} as T;
for (const e of Object.entries(object)) {
c[e[0]] = e[1];
// eslint-disable-next-line @typescript-eslint/no-explicit-any
(c as Record<string, any>)[e[0]] = e[1];
}
return c;
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
static zeroPrefix(number: any, length: number): string {
if (!isNaN(number)) {
const zerosToAdd = Math.max(length - String(number).length, 0);
@@ -69,6 +72,7 @@ export class Utils {
/**
* Checks if the two input (let them be objects or arrays or just primitives) are equal
*/
// eslint-disable-next-line @typescript-eslint/no-explicit-any
static equalsFilter(object: any, filter: any, skipProp: string[] = []): boolean {
if (typeof filter !== 'object' || filter == null) {
return object === filter;
@@ -184,6 +188,7 @@ export class Utils {
//function to calculate offset from exif.exif.gpsTimeStamp or exif.gps.GPSDateStamp + exif.gps.GPSTimestamp
// eslint-disable-next-line @typescript-eslint/no-explicit-any
static getTimeOffsetByGPSStamp(timestamp: string, gpsTimeStamp: string, gps: any) {
let UTCTimestamp = gpsTimeStamp;
if (!UTCTimestamp &&
@@ -191,10 +196,11 @@ export class Utils {
gps.GPSDateStamp &&
gps.GPSTimeStamp) { //else use exif.gps.GPS*Stamp if available
//GPS timestamp is always UTC (+00:00)
// eslint-disable-next-line @typescript-eslint/no-explicit-any
UTCTimestamp = gps.GPSDateStamp.replaceAll(':', '-') + " " + gps.GPSTimeStamp.map((num: any) => Utils.zeroPrefix(num ,2)).join(':');
}
if (UTCTimestamp && timestamp) {
//offset in minutes is the difference between gps timestamp and given timestamp
//offset in minutes is the difference between gps timestamp, and given timestamp
//to calculate this correctly, we have to work with the same offset
const offsetMinutes: number = Math.round((Utils.timestampToMS(timestamp, '+00:00')- Utils.timestampToMS(UTCTimestamp, '+00:00')) / 1000 / 60);
return Utils.getOffsetString(offsetMinutes);
@@ -241,7 +247,7 @@ export class Utils {
return creationDate;
}
}
static isLeapYear(year: number) {
return (0 == year % 4) && (0 != year % 100) || (0 == year % 400)
}
@@ -285,11 +291,12 @@ export class Utils {
return size.toFixed(2) + postFixes[index];
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
static getUnique(arr: any[]) {
return arr.filter((value, index, arr) => arr.indexOf(value) === index);
}
static createRange(from: number, to: number): Array<number> {
static createRange(from: number, to: number): number[] {
const arr = new Array(to - from + 1);
let c = to - from + 1;
while (c--) {
@@ -327,6 +334,7 @@ export class Utils {
return url.substring(0, url.length - 1);
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
public static updateKeys(targetObject: any, sourceObject: any): void {
Object.keys(sourceObject).forEach((key): void => {
if (typeof targetObject[key] === 'undefined') {
@@ -340,6 +348,7 @@ export class Utils {
});
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
public static setKeys(targetObject: any, sourceObject: any): void {
Object.keys(sourceObject).forEach((key): void => {
if (typeof targetObject[key] === 'object') {
@@ -350,6 +359,7 @@ export class Utils {
});
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
public static setKeysForced(targetObject: any, sourceObject: any): void {
Object.keys(sourceObject).forEach((key): void => {
if (typeof sourceObject[key] === 'object') {
@@ -363,12 +373,14 @@ export class Utils {
});
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
public static isValidEnumInt(EnumType: any, value: number) {
return typeof EnumType[value] === 'string';
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
public static enumToArray(EnumType: any): { key: number; value: string }[] {
const arr: Array<{ key: number; value: string }> = [];
const arr: { key: number; value: string }[] = [];
for (const enumMember in EnumType) {
// eslint-disable-next-line no-prototype-builtins
if (!EnumType.hasOwnProperty(enumMember)) {
@@ -458,16 +470,19 @@ export class Utils {
);
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
public static getAnyX(num: number, arr: any[], start = 0): any[][] {
if (num <= 0 || num > arr.length || start >= arr.length) {
return [];
}
if (num <= 1) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
return arr.slice(start).map((e): any[] => [e]);
}
if (num === arr.length - start) {
return [arr.slice(start)];
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const ret: any[][] = [];
for (let i = start; i < arr.length; ++i) {
Utils.getAnyX(num - 1, arr, i + 1).forEach((a): void => {
@@ -504,7 +519,7 @@ export class Utils {
}
export class LRU<V> {
data: { [key: string]: { value: V; usage: number } } = {};
data: Record<string, { value: V; usage: number }> = {};
constructor(public readonly size: number) {
}

View File

@@ -260,7 +260,7 @@ export class ContentWrapper {
name: (dir as DirectoryBaseDTO).cover.directory.name,
} as DirectoryPathDTO;
// make sure that it is not a same object as one of the photo in the media[]
// make sure that it is not the same object as one of the photo in the media[]
// as the next foreach would remove the directory
(dir as DirectoryBaseDTO).cover = Utils.clone((dir as DirectoryBaseDTO).cover);
}