diff --git a/.vscode/settings.json b/.vscode/settings.json index b386502a11..54c018259b 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -52,7 +52,7 @@ }, "cSpell.words": ["immich"], "editor.formatOnSave": true, - "eslint.validate": ["javascript", "svelte"], + "eslint.validate": ["javascript", "typescript", "svelte"], "explorer.fileNesting.enabled": true, "explorer.fileNesting.patterns": { "*.dart": "${capture}.g.dart,${capture}.gr.dart,${capture}.drift.dart", diff --git a/cli/package.json b/cli/package.json index eaa547764b..b64354ee4a 100644 --- a/cli/package.json +++ b/cli/package.json @@ -28,7 +28,7 @@ "eslint": "^9.14.0", "eslint-config-prettier": "^10.1.8", "eslint-plugin-prettier": "^5.1.3", - "eslint-plugin-unicorn": "^60.0.0", + "eslint-plugin-unicorn": "^62.0.0", "globals": "^16.0.0", "mock-fs": "^5.2.0", "prettier": "^3.2.5", diff --git a/cli/src/utils.spec.ts b/cli/src/utils.spec.ts index 5dd28a55e3..3924f9ecb9 100644 --- a/cli/src/utils.spec.ts +++ b/cli/src/utils.spec.ts @@ -299,7 +299,7 @@ describe('crawl', () => { .map(([file]) => file); // Compare file's content instead of path since a file can be represent in multiple ways. - expect(actual.map((path) => readContent(path)).sort()).toEqual(expected.sort()); + expect(actual.map((path) => readContent(path)).toSorted()).toEqual(expected.toSorted()); }); } }); diff --git a/cli/src/utils.ts b/cli/src/utils.ts index eae5164394..9ef20b3679 100644 --- a/cli/src/utils.ts +++ b/cli/src/utils.ts @@ -160,7 +160,7 @@ export const crawl = async (options: CrawlOptions): Promise => { ignore: [`**/${exclusionPattern}`], }); globbedFiles.push(...crawledFiles); - return globbedFiles.sort(); + return globbedFiles.toSorted(); }; export const sha1 = (filepath: string) => { diff --git a/cli/tsconfig.json b/cli/tsconfig.json index fcd01e01c0..d3a02a8257 100644 --- a/cli/tsconfig.json +++ b/cli/tsconfig.json @@ -9,7 +9,7 @@ "experimentalDecorators": true, "allowSyntheticDefaultImports": true, "resolveJsonModule": true, - "target": "es2022", + "target": "es2023", "sourceMap": true, "outDir": "./dist", "incremental": true, diff --git a/e2e/package.json b/e2e/package.json index 02f9a89dfe..7d886026e2 100644 --- a/e2e/package.json +++ b/e2e/package.json @@ -35,7 +35,7 @@ "eslint": "^9.14.0", "eslint-config-prettier": "^10.1.8", "eslint-plugin-prettier": "^5.1.3", - "eslint-plugin-unicorn": "^60.0.0", + "eslint-plugin-unicorn": "^62.0.0", "exiftool-vendored": "^31.1.0", "globals": "^16.0.0", "jose": "^5.6.3", diff --git a/e2e/src/generators/timeline/utils.ts b/e2e/src/generators/timeline/utils.ts index a0b7fbf175..686a8223ef 100644 --- a/e2e/src/generators/timeline/utils.ts +++ b/e2e/src/generators/timeline/utils.ts @@ -61,7 +61,7 @@ export function selectRandomDays(daysInMonth: number, numDays: number, rng: Seed } } - return [...selectedDays].sort((a, b) => b - a); + return [...selectedDays].toSorted((a, b) => b - a); } /** diff --git a/e2e/tsconfig.json b/e2e/tsconfig.json index 341d2ba189..1c7388b6ec 100644 --- a/e2e/tsconfig.json +++ b/e2e/tsconfig.json @@ -9,7 +9,7 @@ "experimentalDecorators": true, "allowSyntheticDefaultImports": true, "resolveJsonModule": true, - "target": "es2022", + "target": "es2023", "sourceMap": true, "outDir": "./dist", "incremental": true, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ead6b82a81..f8ca923af6 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -87,8 +87,8 @@ importers: specifier: ^5.1.3 version: 5.5.4(@types/eslint@9.6.1)(eslint-config-prettier@10.1.8(eslint@9.39.1(jiti@2.6.1)))(eslint@9.39.1(jiti@2.6.1))(prettier@3.6.2) eslint-plugin-unicorn: - specifier: ^60.0.0 - version: 60.0.0(eslint@9.39.1(jiti@2.6.1)) + specifier: ^62.0.0 + version: 62.0.0(eslint@9.39.1(jiti@2.6.1)) globals: specifier: ^16.0.0 version: 16.5.0 @@ -241,8 +241,8 @@ importers: specifier: ^5.1.3 version: 5.5.4(@types/eslint@9.6.1)(eslint-config-prettier@10.1.8(eslint@9.39.1(jiti@2.6.1)))(eslint@9.39.1(jiti@2.6.1))(prettier@3.6.2) eslint-plugin-unicorn: - specifier: ^60.0.0 - version: 60.0.0(eslint@9.39.1(jiti@2.6.1)) + specifier: ^62.0.0 + version: 62.0.0(eslint@9.39.1(jiti@2.6.1)) exiftool-vendored: specifier: ^31.1.0 version: 31.3.0 @@ -657,8 +657,8 @@ importers: specifier: ^5.1.3 version: 5.5.4(@types/eslint@9.6.1)(eslint-config-prettier@10.1.8(eslint@9.39.1(jiti@2.6.1)))(eslint@9.39.1(jiti@2.6.1))(prettier@3.6.2) eslint-plugin-unicorn: - specifier: ^60.0.0 - version: 60.0.0(eslint@9.39.1(jiti@2.6.1)) + specifier: ^62.0.0 + version: 62.0.0(eslint@9.39.1(jiti@2.6.1)) globals: specifier: ^16.0.0 version: 16.5.0 @@ -892,8 +892,8 @@ importers: specifier: ^3.12.4 version: 3.13.0(eslint@9.39.1(jiti@2.6.1))(svelte@5.43.12) eslint-plugin-unicorn: - specifier: ^61.0.2 - version: 61.0.2(eslint@9.39.1(jiti@2.6.1)) + specifier: ^62.0.0 + version: 62.0.0(eslint@9.39.1(jiti@2.6.1)) factory.ts: specifier: ^1.4.1 version: 1.4.2 @@ -2740,10 +2740,6 @@ packages: resolution: {integrity: sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/core@0.15.2': - resolution: {integrity: sha512-78Md3/Rrxh83gCxoUc0EiciuOHsIITzLy53m3d9UyiW8y9Dj2D29FeETqyKA+BRK76tnTp6RXWb3pCay8Oyomg==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/core@0.17.0': resolution: {integrity: sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -2760,10 +2756,6 @@ packages: resolution: {integrity: sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/plugin-kit@0.3.5': - resolution: {integrity: sha512-Z5kJ+wU3oA7MMIqVR9tyZRtjYPr4OC004Q4Rw7pgOKUOKkJfZ3O24nz3WYfGRpMDNmcOi3TwQOmgm7B7Tpii0w==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/plugin-kit@0.4.1': resolution: {integrity: sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -5777,8 +5769,8 @@ packages: resolution: {integrity: sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==} engines: {node: '>=8'} - ci-info@4.3.0: - resolution: {integrity: sha512-l+2bNRMiQgcfILUi33labAZYIWlH1kWDp+ecNo5iisRKrbm0xcRyCww71/YU0Fkw0mAFpz9bJayXPjey6vkmaQ==} + ci-info@4.3.1: + resolution: {integrity: sha512-Wdy2Igu8OcBpI2pZePZ5oWjPC38tmDVx5WKUXKwlLYkA0ozo85sLsLvkBbBn/sZaSCMFOGZJ14fvW9t5/d7kdA==} engines: {node: '>=8'} citty@0.1.6: @@ -6718,17 +6710,11 @@ packages: svelte: optional: true - eslint-plugin-unicorn@60.0.0: - resolution: {integrity: sha512-QUzTefvP8stfSXsqKQ+vBQSEsXIlAiCduS/V1Em+FKgL9c21U/IIm20/e3MFy1jyCf14tHAhqC1sX8OTy6VUCg==} + eslint-plugin-unicorn@62.0.0: + resolution: {integrity: sha512-HIlIkGLkvf29YEiS/ImuDZQbP12gWyx5i3C6XrRxMvVdqMroCI9qoVYCoIl17ChN+U89pn9sVwLxhIWj5nEc7g==} engines: {node: ^20.10.0 || >=21.0.0} peerDependencies: - eslint: '>=9.29.0' - - eslint-plugin-unicorn@61.0.2: - resolution: {integrity: sha512-zLihukvneYT7f74GNbVJXfWIiNQmkc/a9vYBTE4qPkQZswolWNdu+Wsp9sIXno1JOzdn6OUwLPd19ekXVkahRA==} - engines: {node: ^20.10.0 || >=21.0.0} - peerDependencies: - eslint: '>=9.29.0' + eslint: '>=9.38.0' eslint-scope@5.1.1: resolution: {integrity: sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==} @@ -7924,11 +7910,6 @@ packages: canvas: optional: true - jsesc@3.0.2: - resolution: {integrity: sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==} - engines: {node: '>=6'} - hasBin: true - jsesc@3.1.0: resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==} engines: {node: '>=6'} @@ -10090,10 +10071,6 @@ packages: regjsgen@0.8.0: resolution: {integrity: sha512-RvwtGe3d7LvWiDQXeQw8p5asZUmfU1G/l6WbUXeHta7Y2PEIvBTwH6E2EfmYUK8pxcxEdEmaomqyp0vZZ7C+3Q==} - regjsparser@0.12.0: - resolution: {integrity: sha512-cnE+y8bz4NhMjISKbgeVJtqNbtf5QpjZP+Bslo+UqkIt9QPnX9q095eiRRASJG1/tz6dlNr6Z5NsBiWYokp6EQ==} - hasBin: true - regjsparser@0.13.0: resolution: {integrity: sha512-NZQZdC5wOE/H3UT28fVGL+ikOZcEzfMGk/c3iN9UGxzWHMa1op7274oyiUVrAG4B2EuFhus8SvkaYnhvW92p9Q==} hasBin: true @@ -10668,8 +10645,8 @@ packages: resolution: {integrity: sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==} engines: {node: '>=8'} - strip-indent@4.0.0: - resolution: {integrity: sha512-mnVSV2l+Zv6BLpSD/8V87CW/y9EmmbYzGCIavsnsI6/nwn26DwffM/yztm30Z/I2DY9wdS3vXVCMnHDgZaVNoA==} + strip-indent@4.1.1: + resolution: {integrity: sha512-SlyRoSkdh1dYP0PzclLE7r0M9sgbFKKMFXpFRUMNuKhQSbC6VQIGzq3E0qsfvGJaUFJPGv6Ws1NZ/haTAjfbMA==} engines: {node: '>=12'} strip-json-comments@2.0.1: @@ -14501,10 +14478,6 @@ snapshots: dependencies: '@eslint/core': 0.17.0 - '@eslint/core@0.15.2': - dependencies: - '@types/json-schema': 7.0.15 - '@eslint/core@0.17.0': dependencies: '@types/json-schema': 7.0.15 @@ -14527,11 +14500,6 @@ snapshots: '@eslint/object-schema@2.1.7': {} - '@eslint/plugin-kit@0.3.5': - dependencies: - '@eslint/core': 0.15.2 - levn: 0.4.1 - '@eslint/plugin-kit@0.4.1': dependencies: '@eslint/core': 0.17.0 @@ -17954,7 +17922,7 @@ snapshots: ci-info@3.9.0: {} - ci-info@4.3.0: {} + ci-info@4.3.1: {} citty@0.1.6: dependencies: @@ -18971,13 +18939,13 @@ snapshots: transitivePeerDependencies: - ts-node - eslint-plugin-unicorn@60.0.0(eslint@9.39.1(jiti@2.6.1)): + eslint-plugin-unicorn@62.0.0(eslint@9.39.1(jiti@2.6.1)): dependencies: '@babel/helper-validator-identifier': 7.28.5 '@eslint-community/eslint-utils': 4.9.0(eslint@9.39.1(jiti@2.6.1)) - '@eslint/plugin-kit': 0.3.5 + '@eslint/plugin-kit': 0.4.1 change-case: 5.4.4 - ci-info: 4.3.0 + ci-info: 4.3.1 clean-regexp: 1.0.0 core-js-compat: 3.46.0 eslint: 9.39.1(jiti@2.6.1) @@ -18989,31 +18957,9 @@ snapshots: jsesc: 3.1.0 pluralize: 8.0.0 regexp-tree: 0.1.27 - regjsparser: 0.12.0 + regjsparser: 0.13.0 semver: 7.7.3 - strip-indent: 4.0.0 - - eslint-plugin-unicorn@61.0.2(eslint@9.39.1(jiti@2.6.1)): - dependencies: - '@babel/helper-validator-identifier': 7.28.5 - '@eslint-community/eslint-utils': 4.9.0(eslint@9.39.1(jiti@2.6.1)) - '@eslint/plugin-kit': 0.3.5 - change-case: 5.4.4 - ci-info: 4.3.0 - clean-regexp: 1.0.0 - core-js-compat: 3.46.0 - eslint: 9.39.1(jiti@2.6.1) - esquery: 1.6.0 - find-up-simple: 1.0.1 - globals: 16.5.0 - indent-string: 5.0.0 - is-builtin-module: 5.0.0 - jsesc: 3.1.0 - pluralize: 8.0.0 - regexp-tree: 0.1.27 - regjsparser: 0.12.0 - semver: 7.7.3 - strip-indent: 4.0.0 + strip-indent: 4.1.1 eslint-scope@5.1.1: dependencies: @@ -20527,8 +20473,6 @@ snapshots: - utf-8-validate optional: true - jsesc@3.0.2: {} - jsesc@3.1.0: {} json-buffer@3.0.1: {} @@ -23055,10 +22999,6 @@ snapshots: regjsgen@0.8.0: {} - regjsparser@0.12.0: - dependencies: - jsesc: 3.0.2 - regjsparser@0.13.0: dependencies: jsesc: 3.1.0 @@ -23832,9 +23772,7 @@ snapshots: dependencies: min-indent: 1.0.1 - strip-indent@4.0.0: - dependencies: - min-indent: 1.0.1 + strip-indent@4.1.1: {} strip-json-comments@2.0.1: {} diff --git a/server/package.json b/server/package.json index f9eb5990a7..ca911cd264 100644 --- a/server/package.json +++ b/server/package.json @@ -148,7 +148,7 @@ "eslint": "^9.14.0", "eslint-config-prettier": "^10.1.8", "eslint-plugin-prettier": "^5.1.3", - "eslint-plugin-unicorn": "^60.0.0", + "eslint-plugin-unicorn": "^62.0.0", "globals": "^16.0.0", "mock-fs": "^5.2.0", "node-gyp": "^12.0.0", diff --git a/server/src/dtos/sync.dto.ts b/server/src/dtos/sync.dto.ts index c936ec52cc..d6a557e2c5 100644 --- a/server/src/dtos/sync.dto.ts +++ b/server/src/dtos/sync.dto.ts @@ -50,6 +50,7 @@ export class AssetDeltaSyncResponseDto { export const extraSyncModels: Function[] = []; export const ExtraModel = (): ClassDecorator => { + // eslint-disable-next-line unicorn/consistent-function-scoping return (object: Function) => { extraSyncModels.push(object); }; diff --git a/server/src/repositories/config.repository.spec.ts b/server/src/repositories/config.repository.spec.ts index 99cba43b99..1641850583 100644 --- a/server/src/repositories/config.repository.spec.ts +++ b/server/src/repositories/config.repository.spec.ts @@ -257,7 +257,7 @@ describe('getEnv', () => { expect(telemetry).toEqual({ apiPort: 8081, microservicesPort: 8082, - metrics: new Set([]), + metrics: new Set(), }); }); diff --git a/server/src/services/album.service.spec.ts b/server/src/services/album.service.spec.ts index fa8a9c6450..03be834354 100644 --- a/server/src/services/album.service.spec.ts +++ b/server/src/services/album.service.spec.ts @@ -669,7 +669,7 @@ describe(AlbumService.name, () => { }); it('should not allow a shared user with viewer access to add assets', async () => { - mocks.access.album.checkSharedAlbumAccess.mockResolvedValue(new Set([])); + mocks.access.album.checkSharedAlbumAccess.mockResolvedValue(new Set()); mocks.album.getById.mockResolvedValue(_.cloneDeep(albumStub.sharedWithUser)); await expect( diff --git a/server/src/services/backup.service.ts b/server/src/services/backup.service.ts index 3731b1810f..2ff3e5dd3e 100644 --- a/server/src/services/backup.service.ts +++ b/server/src/services/backup.service.ts @@ -61,7 +61,7 @@ export class BackupService extends BaseService { const newBackupStyle = file.match(/immich-db-backup-\d{8}T\d{6}-v.*-pg.*\.sql\.gz$/); return oldBackupStyle || newBackupStyle; }) - .sort() + .toSorted() .toReversed(); const toDelete = backups.slice(config.keepLastAmount); diff --git a/server/src/services/library.service.spec.ts b/server/src/services/library.service.spec.ts index 64f0915698..dbff1ca467 100644 --- a/server/src/services/library.service.spec.ts +++ b/server/src/services/library.service.spec.ts @@ -278,7 +278,7 @@ describe(LibraryService.name, () => { mocks.library.get.mockResolvedValue(library); mocks.storage.walk.mockImplementation(async function* generator() {}); mocks.asset.getLibraryAssetCount.mockResolvedValue(1); - mocks.asset.detectOfflineExternalAssets.mockResolvedValue({ numUpdatedRows: BigInt(1) }); + mocks.asset.detectOfflineExternalAssets.mockResolvedValue({ numUpdatedRows: 1n }); const response = await sut.handleQueueSyncAssets({ id: library.id }); @@ -296,7 +296,7 @@ describe(LibraryService.name, () => { mocks.library.get.mockResolvedValue(library); mocks.storage.walk.mockImplementation(async function* generator() {}); mocks.asset.getLibraryAssetCount.mockResolvedValue(0); - mocks.asset.detectOfflineExternalAssets.mockResolvedValue({ numUpdatedRows: BigInt(1) }); + mocks.asset.detectOfflineExternalAssets.mockResolvedValue({ numUpdatedRows: 1n }); const response = await sut.handleQueueSyncAssets({ id: library.id }); @@ -311,7 +311,7 @@ describe(LibraryService.name, () => { mocks.storage.walk.mockImplementation(async function* generator() {}); mocks.library.streamAssetIds.mockReturnValue(makeStream([assetStub.external])); mocks.asset.getLibraryAssetCount.mockResolvedValue(1); - mocks.asset.detectOfflineExternalAssets.mockResolvedValue({ numUpdatedRows: BigInt(0) }); + mocks.asset.detectOfflineExternalAssets.mockResolvedValue({ numUpdatedRows: 0n }); mocks.library.streamAssetIds.mockReturnValue(makeStream([assetStub.external])); const response = await sut.handleQueueSyncAssets({ id: library.id }); diff --git a/server/src/services/media.service.ts b/server/src/services/media.service.ts index 82f041c111..54ddc0de48 100644 --- a/server/src/services/media.service.ts +++ b/server/src/services/media.service.ts @@ -561,7 +561,7 @@ export class MediaService extends BaseService { private getMainStream(streams: T[]): T { return streams .filter((stream) => stream.codecName !== 'unknown') - .sort((stream1, stream2) => stream2.bitrate - stream1.bitrate)[0]; + .toSorted((stream1, stream2) => stream2.bitrate - stream1.bitrate)[0]; } private getTranscodeTarget( diff --git a/server/src/services/tag.service.spec.ts b/server/src/services/tag.service.spec.ts index 6a630de6a1..6bb92abd8c 100644 --- a/server/src/services/tag.service.spec.ts +++ b/server/src/services/tag.service.spec.ts @@ -217,7 +217,7 @@ describe(TagService.name, () => { describe('addAssets', () => { it('should handle invalid ids', async () => { - mocks.tag.getAssetIds.mockResolvedValue(new Set([])); + mocks.tag.getAssetIds.mockResolvedValue(new Set()); await expect(sut.addAssets(authStub.admin, 'tag-1', { ids: ['asset-1'] })).resolves.toEqual([ { id: 'asset-1', success: false, error: 'no_permission' }, ]); diff --git a/server/src/sql-tools/helpers.ts b/server/src/sql-tools/helpers.ts index 12586f27b2..2ef35ce9ba 100644 --- a/server/src/sql-tools/helpers.ts +++ b/server/src/sql-tools/helpers.ts @@ -46,7 +46,7 @@ export const setIsEqual = (source: Set, target: Set) => source.size === target.size && [...source].every((x) => target.has(x)); export const haveEqualColumns = (sourceColumns?: string[], targetColumns?: string[]) => { - return setIsEqual(new Set(sourceColumns ?? []), new Set(targetColumns ?? [])); + return setIsEqual(new Set(sourceColumns), new Set(targetColumns)); }; export const haveEqualOverrides = (source: T, target: T) => { diff --git a/server/src/utils/media.ts b/server/src/utils/media.ts index f678a32b0f..b2ffb9ac8b 100644 --- a/server/src/utils/media.ts +++ b/server/src/utils/media.ts @@ -704,8 +704,7 @@ export class QsvSwDecodeConfig extends BaseHWConfig { } getBitrateOptions() { - const options = []; - options.push(`-${this.useCQP() ? 'q:v' : 'global_quality:v'} ${this.config.crf}`); + const options = [`-${this.useCQP() ? 'q:v' : 'global_quality:v'} ${this.config.crf}`]; const bitrates = this.getBitrateDistribution(); if (bitrates.max > 0) { options.push(`-maxrate ${bitrates.max}${bitrates.unit}`, `-bufsize ${bitrates.max * 2}${bitrates.unit}`); diff --git a/server/src/utils/misc.ts b/server/src/utils/misc.ts index eb548eab74..08f1401d50 100644 --- a/server/src/utils/misc.ts +++ b/server/src/utils/misc.ts @@ -139,7 +139,7 @@ function sortKeys(target: T): T { } const result: Partial = {}; - const keys = Object.keys(target).sort() as Array; + const keys = Object.keys(target).toSorted() as Array; for (const key of keys) { result[key] = sortKeys(target[key]); } @@ -178,10 +178,7 @@ const patchOpenAPI = (document: OpenAPIObject) => { throw new Error(`Invalid number format: ${schemaName}.${key}=float (use double instead). `); } } - - if (schema.required) { - schema.required = schema.required.sort(); - } + schema.required?.sort(); } } } diff --git a/server/test/medium/specs/sync/sync-partner-asset-exif.spec.ts b/server/test/medium/specs/sync/sync-partner-asset-exif.spec.ts index d44c088f17..d533afadf1 100644 --- a/server/test/medium/specs/sync/sync-partner-asset-exif.spec.ts +++ b/server/test/medium/specs/sync/sync-partner-asset-exif.spec.ts @@ -176,7 +176,7 @@ describe(SyncRequestType.PartnerAssetExifsV1, () => { const newResponse = await ctx.syncStream(auth, [SyncRequestType.PartnerAssetExifsV1]); expect(newResponse).toEqual([ { - ack: expect.stringMatching(new RegExp(`${SyncEntityType.PartnerAssetExifBackfillV1}\\|.+?\\|.+`)), + ack: expect.stringMatching(new RegExp(String.raw`${SyncEntityType.PartnerAssetExifBackfillV1}\|.+?\|.+`)), data: expect.objectContaining({ assetId: assetUser3.id, }), @@ -226,7 +226,7 @@ describe(SyncRequestType.PartnerAssetExifsV1, () => { const newResponse = await ctx.syncStream(auth, [SyncRequestType.PartnerAssetExifsV1]); expect(newResponse).toEqual([ { - ack: expect.stringMatching(new RegExp(`${SyncEntityType.PartnerAssetExifBackfillV1}\\|.+?\\|.+`)), + ack: expect.stringMatching(new RegExp(String.raw`${SyncEntityType.PartnerAssetExifBackfillV1}\|.+?\|.+`)), data: expect.objectContaining({ assetId: assetUser3.id, }), diff --git a/server/test/repositories/storage.repository.mock.ts b/server/test/repositories/storage.repository.mock.ts index 31451da82f..b45e93d8b9 100644 --- a/server/test/repositories/storage.repository.mock.ts +++ b/server/test/repositories/storage.repository.mock.ts @@ -38,6 +38,7 @@ export const makeMockWatcher = return () => close(); } + // eslint-disable-next-line unicorn/consistent-function-scoping return () => Promise.resolve(); }; diff --git a/web/package.json b/web/package.json index b7db849166..fca762ef34 100644 --- a/web/package.json +++ b/web/package.json @@ -88,7 +88,7 @@ "eslint-config-prettier": "^10.1.8", "eslint-plugin-compat": "^6.0.2", "eslint-plugin-svelte": "^3.12.4", - "eslint-plugin-unicorn": "^61.0.2", + "eslint-plugin-unicorn": "^62.0.0", "factory.ts": "^1.4.1", "globals": "^16.0.0", "happy-dom": "^20.0.0", diff --git a/web/src/lib/components/shared-components/album-selection/album-selection-utils.ts b/web/src/lib/components/shared-components/album-selection/album-selection-utils.ts index f016916f7f..e65d42b183 100644 --- a/web/src/lib/components/shared-components/album-selection/album-selection-utils.ts +++ b/web/src/lib/components/shared-components/album-selection/album-selection-utils.ts @@ -46,8 +46,7 @@ export class AlbumModalRowConverter { ): AlbumModalRow[] { // only show recent albums if no search was entered, or we're in the normal albums (non-shared) modal. const recentAlbumsToShow = !this.shared && search.length === 0 ? recentAlbums : []; - const rows: AlbumModalRow[] = []; - rows.push({ type: AlbumModalRowType.NEW_ALBUM, selected: selectedRowIndex === 0 }); + const rows: AlbumModalRow[] = [{ type: AlbumModalRowType.NEW_ALBUM, selected: selectedRowIndex === 0 }]; const filteredAlbums = sortAlbums( search.length > 0 && albums.length > 0