From 2d678ef19fe831c4c3623065944eeb90eb64be93 Mon Sep 17 00:00:00 2001 From: Georges-Antoine Assi Date: Sat, 7 Feb 2026 21:27:24 -0500 Subject: [PATCH 1/7] [ROMM-2976] Fix no games displayed for status filter --- backend/handler/database/roms_handler.py | 33 +++++++++++++------ .../Dialog/CreateSmartCollection.vue | 6 +--- frontend/src/stores/galleryFilter.ts | 2 +- frontend/src/utils/index.ts | 11 ------- 4 files changed, 25 insertions(+), 27 deletions(-) diff --git a/backend/handler/database/roms_handler.py b/backend/handler/database/roms_handler.py index 9d03392f3..6afd252d8 100644 --- a/backend/handler/database/roms_handler.py +++ b/backend/handler/database/roms_handler.py @@ -424,13 +424,21 @@ class DBRomsHandler(DBBaseHandler): condition = op(RomMetadata.age_ratings, values, session=session) return query.filter(~condition) if match_none else query.filter(condition) - def _filter_by_status(self, query: Query, statuses: Sequence[str]): + def _filter_by_status( + self, + query: Query, + *, + session: Session, + values: Sequence[str], + match_all: bool = False, + match_none: bool = False, + ): """Filter by one or more user statuses using OR logic.""" - if not statuses: + if not values: return query status_filters = [] - for selected_status in statuses: + for selected_status in values: if selected_status == "now_playing": status_filters.append(RomUser.now_playing.is_(True)) elif selected_status == "backlogged": @@ -440,11 +448,17 @@ class DBRomsHandler(DBBaseHandler): else: status_filters.append(RomUser.status == selected_status) - # If hidden is in the list, don't apply the hidden filter at the end - if "hidden" in statuses: - return query.filter(or_(*status_filters)) + comb = and_ if match_all else or_ + condition = comb(*status_filters) - return query.filter(or_(*status_filters), RomUser.hidden.is_(False)) + # Apply negation if match_none, otherwise apply condition + query = query.filter(~condition) if match_none else query.filter(condition) + + # If hidden wasn't explicitly requested, always exclude hidden rows + if "hidden" not in values: + query = query.filter(RomUser.hidden.is_(False)) + + return query def _filter_by_regions( self, @@ -726,6 +740,7 @@ class DBRomsHandler(DBBaseHandler): (regions, regions_logic, self._filter_by_regions), (languages, languages_logic, self._filter_by_languages), (player_counts, player_counts_logic, self._filter_by_player_counts), + (statuses, statuses_logic, self._filter_by_status), ] for values, logic, filter_func in filters_to_apply: @@ -739,9 +754,7 @@ class DBRomsHandler(DBBaseHandler): ) # The RomUser table is already joined if user_id is set - if statuses and user_id: - query = self._filter_by_status(query, statuses) - elif user_id: + if user_id: query = query.filter( or_(RomUser.hidden.is_(False), RomUser.hidden.is_(None)) ) diff --git a/frontend/src/components/common/Collection/Dialog/CreateSmartCollection.vue b/frontend/src/components/common/Collection/Dialog/CreateSmartCollection.vue index 1ce4880d5..23225666b 100644 --- a/frontend/src/components/common/Collection/Dialog/CreateSmartCollection.vue +++ b/frontend/src/components/common/Collection/Dialog/CreateSmartCollection.vue @@ -13,7 +13,6 @@ import storeCollections from "@/stores/collections"; import storeGalleryFilter from "@/stores/galleryFilter"; import storeRoms from "@/stores/roms"; import type { Events } from "@/types/emitter"; -import { getStatusKeyForText } from "@/utils"; const { t } = useI18n(); const galleryFilterStore = storeGalleryFilter(); @@ -172,10 +171,7 @@ async function createSmartCollection() { filterCriteria.age_ratings_logic = ageRatingsLogic.value; } if (selectedStatuses.value && selectedStatuses.value.length > 0) { - const statusKeys = selectedStatuses.value - .filter((s): s is string => s !== null) - .map((s) => getStatusKeyForText(s)) - .filter((key) => key !== null); + const statusKeys = selectedStatuses.value; if (statusKeys.length > 0) { filterCriteria.selected_status = statusKeys; } diff --git a/frontend/src/stores/galleryFilter.ts b/frontend/src/stores/galleryFilter.ts index 90f75bc32..d198c82a3 100644 --- a/frontend/src/stores/galleryFilter.ts +++ b/frontend/src/stores/galleryFilter.ts @@ -29,7 +29,7 @@ const defaultFilterState = { filterRegions: [] as string[], filterLanguages: [] as string[], filterPlayerCounts: [] as string[], - filterStatuses: Object.values(romStatusMap).map((status) => status.text), + filterStatuses: Object.keys(romStatusMap), filterMatched: null as boolean | null, // null = all, true = matched, false = unmatched filterFavorites: null as boolean | null, // null = all, true = favorites, false = not favorites filterDuplicates: null as boolean | null, // null = all, true = duplicates, false = not duplicates diff --git a/frontend/src/utils/index.ts b/frontend/src/utils/index.ts index bbd45f328..d4d78d9ba 100644 --- a/frontend/src/utils/index.ts +++ b/frontend/src/utils/index.ts @@ -710,17 +710,6 @@ export function getI18nKeyForStatus(status: PlayingStatus): string | null { return romStatusMap[status]?.i18nKey ?? null; } -/** - * Get the status key for a given text. - * - * @param text The text to convert. - * @returns The corresponding status key. - */ -export function getStatusKeyForText(text: string | null) { - if (!text) return null; - return inverseRomStatusMap[text]; -} - export function isNintendoDSFile(rom: SimpleRom): boolean { return ["cia", "nds", "3ds", "dsi"].includes(rom.fs_extension.toLowerCase()); } From a29cb757677e0bf99b51c84b44f37b2f4430ea1b Mon Sep 17 00:00:00 2001 From: Georges-Antoine Assi Date: Sat, 7 Feb 2026 21:38:31 -0500 Subject: [PATCH 2/7] fix mapped value --- .trunk/trunk.yaml | 18 +++++++++--------- .../AppBar/common/FilterDrawer/Base.vue | 12 ++++++++++-- frontend/src/utils/index.ts | 6 +++++- 3 files changed, 24 insertions(+), 12 deletions(-) diff --git a/.trunk/trunk.yaml b/.trunk/trunk.yaml index d90f0818a..03793b957 100644 --- a/.trunk/trunk.yaml +++ b/.trunk/trunk.yaml @@ -25,25 +25,25 @@ lint: - dotenv-linter@4.0.0 - hadolint@2.14.0 - markdownlint@0.47.0 - - eslint@9.39.2 + - eslint@10.0.0 - actionlint@1.7.10 - - bandit@1.9.2 - - black@25.12.0 - - checkov@3.2.497 + - bandit@1.9.3 + - black@26.1.0 + - checkov@3.2.500 - git-diff-check - isort@7.0.0 - mypy@1.19.1 - osv-scanner@2.3.2 - - prettier@3.8.0: + - prettier@3.8.1: packages: - "@trivago/prettier-plugin-sort-imports@6.0.2" - - "@vue/compiler-sfc@3.5.26" - - ruff@0.14.13 + - "@vue/compiler-sfc@3.5.27" + - ruff@0.15.0 - shellcheck@0.11.0 - shfmt@3.6.0 - taplo@0.10.0 - - trivy@0.68.2 - - trufflehog@3.92.5 + - trivy@0.69.1 + - trufflehog@3.93.1 - yamllint@1.38.0 ignore: - linters: [ALL] diff --git a/frontend/src/components/Gallery/AppBar/common/FilterDrawer/Base.vue b/frontend/src/components/Gallery/AppBar/common/FilterDrawer/Base.vue index 484176d36..884dd5395 100644 --- a/frontend/src/components/Gallery/AppBar/common/FilterDrawer/Base.vue +++ b/frontend/src/components/Gallery/AppBar/common/FilterDrawer/Base.vue @@ -2,7 +2,7 @@ import { debounce } from "lodash"; import type { Emitter } from "mitt"; import { storeToRefs } from "pinia"; -import { inject, nextTick, onMounted } from "vue"; +import { inject, nextTick, onMounted, ref } from "vue"; import { useI18n } from "vue-i18n"; import { useRouter } from "vue-router"; import { useDisplay } from "vuetify"; @@ -21,6 +21,7 @@ import storeGalleryFilter, { import storePlatforms from "@/stores/platforms"; import storeRoms from "@/stores/roms"; import type { Events } from "@/types/emitter"; +import { romStatusMap, type PlayingStatus } from "@/utils"; withDefaults( defineProps<{ @@ -180,6 +181,13 @@ const onFilterChange = debounce( emitter?.on("filterRoms", onFilterChange); +const mappedStatuses = ref( + filterStatuses.value.map((s) => ({ + title: romStatusMap[s as PlayingStatus].text, + value: s, + })), +); + const filters = [ { label: t("platform.genre"), @@ -248,7 +256,7 @@ const filters = [ { label: t("platform.status"), selected: selectedStatuses, - items: filterStatuses, + items: mappedStatuses, logic: statusesLogic, setLogic: (logic: FilterLogicOperator) => galleryFilterStore.setStatusesLogic(logic), diff --git a/frontend/src/utils/index.ts b/frontend/src/utils/index.ts index d4d78d9ba..41198c934 100644 --- a/frontend/src/utils/index.ts +++ b/frontend/src/utils/index.ts @@ -630,7 +630,11 @@ export function isRuffleEmulationSupported( return ["flash", "browser"].includes(slug.toLowerCase()); } -type PlayingStatus = RomUserStatus | "backlogged" | "now_playing" | "hidden"; +export type PlayingStatus = + | RomUserStatus + | "backlogged" + | "now_playing" + | "hidden"; /** * Map of ROM statuses to their corresponding emoji, text, and i18n key. From 3e86e5599400a1dc24add69d718b96cb0b613da8 Mon Sep 17 00:00:00 2001 From: Georges-Antoine Assi Date: Sat, 7 Feb 2026 22:02:15 -0500 Subject: [PATCH 3/7] changes from bot review --- backend/handler/database/roms_handler.py | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/backend/handler/database/roms_handler.py b/backend/handler/database/roms_handler.py index 6afd252d8..ca7393454 100644 --- a/backend/handler/database/roms_handler.py +++ b/backend/handler/database/roms_handler.py @@ -452,13 +452,7 @@ class DBRomsHandler(DBBaseHandler): condition = comb(*status_filters) # Apply negation if match_none, otherwise apply condition - query = query.filter(~condition) if match_none else query.filter(condition) - - # If hidden wasn't explicitly requested, always exclude hidden rows - if "hidden" not in values: - query = query.filter(RomUser.hidden.is_(False)) - - return query + return query.filter(~condition) if match_none else query.filter(condition) def _filter_by_regions( self, @@ -754,7 +748,8 @@ class DBRomsHandler(DBBaseHandler): ) # The RomUser table is already joined if user_id is set - if user_id: + # If hidden wasn't explicitly requested, always exclude hidden rows + if user_id and (not statuses or "hidden" not in statuses): query = query.filter( or_(RomUser.hidden.is_(False), RomUser.hidden.is_(None)) ) From dc685911f02ba46abc099c552c1256da34a51177 Mon Sep 17 00:00:00 2001 From: Georges-Antoine Assi Date: Sat, 7 Feb 2026 22:07:15 -0500 Subject: [PATCH 4/7] fix trunk check --- .trunk/trunk.yaml | 2 +- frontend/package-lock.json | 441 ++++++++++-------------------------- frontend/package.json | 2 +- frontend/src/utils/index.ts | 7 - 4 files changed, 127 insertions(+), 325 deletions(-) diff --git a/.trunk/trunk.yaml b/.trunk/trunk.yaml index 03793b957..b88b1fa0e 100644 --- a/.trunk/trunk.yaml +++ b/.trunk/trunk.yaml @@ -25,7 +25,7 @@ lint: - dotenv-linter@4.0.0 - hadolint@2.14.0 - markdownlint@0.47.0 - - eslint@10.0.0 + - eslint@9.34.0 - actionlint@1.7.10 - bandit@1.9.3 - black@26.1.0 diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 30f829833..7443c5ed8 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -56,7 +56,7 @@ "vue-tsc": "^2.2.8" }, "engines": { - "node": "18" + "node": ">18" } }, "node_modules/@ampproject/remapping": { @@ -1925,7 +1925,6 @@ "cpu": [ "ppc64" ], - "dev": true, "optional": true, "os": [ "aix" @@ -1941,7 +1940,6 @@ "cpu": [ "arm" ], - "dev": true, "optional": true, "os": [ "android" @@ -1957,7 +1955,6 @@ "cpu": [ "arm64" ], - "dev": true, "optional": true, "os": [ "android" @@ -1973,7 +1970,6 @@ "cpu": [ "x64" ], - "dev": true, "optional": true, "os": [ "android" @@ -1989,7 +1985,6 @@ "cpu": [ "arm64" ], - "dev": true, "optional": true, "os": [ "darwin" @@ -2005,7 +2000,6 @@ "cpu": [ "x64" ], - "dev": true, "optional": true, "os": [ "darwin" @@ -2021,7 +2015,6 @@ "cpu": [ "arm64" ], - "dev": true, "optional": true, "os": [ "freebsd" @@ -2037,7 +2030,6 @@ "cpu": [ "x64" ], - "dev": true, "optional": true, "os": [ "freebsd" @@ -2053,7 +2045,6 @@ "cpu": [ "arm" ], - "dev": true, "optional": true, "os": [ "linux" @@ -2069,7 +2060,6 @@ "cpu": [ "arm64" ], - "dev": true, "optional": true, "os": [ "linux" @@ -2085,7 +2075,6 @@ "cpu": [ "ia32" ], - "dev": true, "optional": true, "os": [ "linux" @@ -2101,7 +2090,6 @@ "cpu": [ "loong64" ], - "dev": true, "optional": true, "os": [ "linux" @@ -2117,7 +2105,6 @@ "cpu": [ "mips64el" ], - "dev": true, "optional": true, "os": [ "linux" @@ -2133,7 +2120,6 @@ "cpu": [ "ppc64" ], - "dev": true, "optional": true, "os": [ "linux" @@ -2149,7 +2135,6 @@ "cpu": [ "riscv64" ], - "dev": true, "optional": true, "os": [ "linux" @@ -2165,7 +2150,6 @@ "cpu": [ "s390x" ], - "dev": true, "optional": true, "os": [ "linux" @@ -2181,7 +2165,6 @@ "cpu": [ "x64" ], - "dev": true, "optional": true, "os": [ "linux" @@ -2197,7 +2180,6 @@ "cpu": [ "arm64" ], - "dev": true, "optional": true, "os": [ "netbsd" @@ -2213,7 +2195,6 @@ "cpu": [ "x64" ], - "dev": true, "optional": true, "os": [ "netbsd" @@ -2229,7 +2210,6 @@ "cpu": [ "arm64" ], - "dev": true, "optional": true, "os": [ "openbsd" @@ -2245,7 +2225,6 @@ "cpu": [ "x64" ], - "dev": true, "optional": true, "os": [ "openbsd" @@ -2261,7 +2240,6 @@ "cpu": [ "x64" ], - "dev": true, "optional": true, "os": [ "sunos" @@ -2277,7 +2255,6 @@ "cpu": [ "arm64" ], - "dev": true, "optional": true, "os": [ "win32" @@ -2293,7 +2270,6 @@ "cpu": [ "ia32" ], - "dev": true, "optional": true, "os": [ "win32" @@ -2309,7 +2285,6 @@ "cpu": [ "x64" ], - "dev": true, "optional": true, "os": [ "win32" @@ -2319,10 +2294,11 @@ } }, "node_modules/@eslint-community/eslint-utils": { - "version": "4.8.0", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.8.0.tgz", - "integrity": "sha512-MJQFqrZgcW0UNYLGOuQpey/oTN59vyWwplvCGZztn1cKz9agZPPYpJB7h2OMmuu7VLqkvEjN8feFZJmxNF9D+Q==", + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz", + "integrity": "sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==", "dev": true, + "license": "MIT", "dependencies": { "eslint-visitor-keys": "^3.4.3" }, @@ -2337,10 +2313,11 @@ } }, "node_modules/@eslint-community/regexpp": { - "version": "4.12.1", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", - "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", + "version": "4.12.2", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz", + "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==", "dev": true, + "license": "MIT", "engines": { "node": "^12.0.0 || ^14.0.0 || >=16.0.0" } @@ -2608,7 +2585,7 @@ "version": "0.3.8", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz", "integrity": "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==", - "dev": true, + "devOptional": true, "dependencies": { "@jridgewell/set-array": "^1.2.1", "@jridgewell/sourcemap-codec": "^1.4.10", @@ -2633,7 +2610,7 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", - "dev": true, + "devOptional": true, "engines": { "node": ">=6.0.0" } @@ -2642,7 +2619,7 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", - "dev": true, + "devOptional": true, "engines": { "node": ">=6.0.0" } @@ -2651,7 +2628,7 @@ "version": "0.3.6", "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz", "integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==", - "dev": true, + "devOptional": true, "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.25" @@ -2666,7 +2643,7 @@ "version": "0.3.31", "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", - "dev": true, + "devOptional": true, "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" @@ -2848,41 +2825,6 @@ "resolved": "https://registry.npmjs.org/@mdi/font/-/font-7.4.47.tgz", "integrity": "sha512-43MtGpd585SNzHZPcYowu/84Vz2a2g31TvPMTm9uTiCSWzaheQySUcSyUH/46fPnuPQWof2yd0pGBtzee/IQWw==" }, - "node_modules/@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dev": true, - "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, - "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - }, - "engines": { - "node": ">= 8" - } - }, "node_modules/@rollup/plugin-node-resolve": { "version": "15.3.1", "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.3.1.tgz", @@ -2970,7 +2912,6 @@ "cpu": [ "arm" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -2984,7 +2925,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -2998,7 +2938,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -3012,7 +2951,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -3026,7 +2964,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -3040,7 +2977,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -3054,7 +2990,6 @@ "cpu": [ "arm" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -3068,7 +3003,6 @@ "cpu": [ "arm" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -3082,7 +3016,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -3096,7 +3029,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -3110,7 +3042,6 @@ "cpu": [ "loong64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -3124,7 +3055,6 @@ "cpu": [ "ppc64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -3138,7 +3068,6 @@ "cpu": [ "riscv64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -3152,7 +3081,6 @@ "cpu": [ "riscv64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -3166,7 +3094,6 @@ "cpu": [ "s390x" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -3180,7 +3107,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -3194,7 +3120,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -3208,7 +3133,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -3222,7 +3146,6 @@ "cpu": [ "ia32" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -3236,7 +3159,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -3665,7 +3587,7 @@ "version": "22.13.14", "resolved": "https://registry.npmjs.org/@types/node/-/node-22.13.14.tgz", "integrity": "sha512-Zs/Ollc1SJ8nKUAgc7ivOEdIBM8JAKgrqqUYi2J997JuKO7/tpQC+WCetQ1sypiKCQWHdvdg9wBNpUPEWZae7w==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "undici-types": "~6.20.0" @@ -3705,20 +3627,20 @@ "integrity": "sha512-oIQLCGWtcFZy2JW77j9k8nHzAOpqMHLQejDA48XXMWH6tjCQHz5RCFz1bzsmROyL6PUm+LLnUiI4BCn221inxA==" }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.42.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.42.0.tgz", - "integrity": "sha512-Aq2dPqsQkxHOLfb2OPv43RnIvfj05nw8v/6n3B2NABIPpHnjQnaLo9QGMTvml+tv4korl/Cjfrb/BYhoL8UUTQ==", + "version": "8.54.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.54.0.tgz", + "integrity": "sha512-hAAP5io/7csFStuOmR782YmTthKBJ9ND3WVL60hcOjvtGFb+HJxH4O5huAcmcZ9v9G8P+JETiZ/G1B8MALnWZQ==", "dev": true, + "license": "MIT", "dependencies": { - "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "8.42.0", - "@typescript-eslint/type-utils": "8.42.0", - "@typescript-eslint/utils": "8.42.0", - "@typescript-eslint/visitor-keys": "8.42.0", - "graphemer": "^1.4.0", - "ignore": "^7.0.0", + "@eslint-community/regexpp": "^4.12.2", + "@typescript-eslint/scope-manager": "8.54.0", + "@typescript-eslint/type-utils": "8.54.0", + "@typescript-eslint/utils": "8.54.0", + "@typescript-eslint/visitor-keys": "8.54.0", + "ignore": "^7.0.5", "natural-compare": "^1.4.0", - "ts-api-utils": "^2.1.0" + "ts-api-utils": "^2.4.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3728,7 +3650,7 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^8.42.0", + "@typescript-eslint/parser": "^8.54.0", "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } @@ -3738,21 +3660,23 @@ "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 4" } }, "node_modules/@typescript-eslint/parser": { - "version": "8.42.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.42.0.tgz", - "integrity": "sha512-r1XG74QgShUgXph1BYseJ+KZd17bKQib/yF3SR+demvytiRXrwd12Blnz5eYGm8tXaeRdd4x88MlfwldHoudGg==", + "version": "8.54.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.54.0.tgz", + "integrity": "sha512-BtE0k6cjwjLZoZixN0t5AKP0kSzlGu7FctRXYuPAm//aaiZhmfq1JwdYpYr1brzEspYyFeF+8XF5j2VK6oalrA==", "dev": true, + "license": "MIT", "dependencies": { - "@typescript-eslint/scope-manager": "8.42.0", - "@typescript-eslint/types": "8.42.0", - "@typescript-eslint/typescript-estree": "8.42.0", - "@typescript-eslint/visitor-keys": "8.42.0", - "debug": "^4.3.4" + "@typescript-eslint/scope-manager": "8.54.0", + "@typescript-eslint/types": "8.54.0", + "@typescript-eslint/typescript-estree": "8.54.0", + "@typescript-eslint/visitor-keys": "8.54.0", + "debug": "^4.4.3" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3767,14 +3691,15 @@ } }, "node_modules/@typescript-eslint/project-service": { - "version": "8.42.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.42.0.tgz", - "integrity": "sha512-vfVpLHAhbPjilrabtOSNcUDmBboQNrJUiNAGoImkZKnMjs2TIcWG33s4Ds0wY3/50aZmTMqJa6PiwkwezaAklg==", + "version": "8.54.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.54.0.tgz", + "integrity": "sha512-YPf+rvJ1s7MyiWM4uTRhE4DvBXrEV+d8oC3P9Y2eT7S+HBS0clybdMIPnhiATi9vZOYDc7OQ1L/i6ga6NFYK/g==", "dev": true, + "license": "MIT", "dependencies": { - "@typescript-eslint/tsconfig-utils": "^8.42.0", - "@typescript-eslint/types": "^8.42.0", - "debug": "^4.3.4" + "@typescript-eslint/tsconfig-utils": "^8.54.0", + "@typescript-eslint/types": "^8.54.0", + "debug": "^4.4.3" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3788,13 +3713,14 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "8.42.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.42.0.tgz", - "integrity": "sha512-51+x9o78NBAVgQzOPd17DkNTnIzJ8T/O2dmMBLoK9qbY0Gm52XJcdJcCl18ExBMiHo6jPMErUQWUv5RLE51zJw==", + "version": "8.54.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.54.0.tgz", + "integrity": "sha512-27rYVQku26j/PbHYcVfRPonmOlVI6gihHtXFbTdB5sb6qA0wdAQAbyXFVarQ5t4HRojIz64IV90YtsjQSSGlQg==", "dev": true, + "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.42.0", - "@typescript-eslint/visitor-keys": "8.42.0" + "@typescript-eslint/types": "8.54.0", + "@typescript-eslint/visitor-keys": "8.54.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3805,10 +3731,11 @@ } }, "node_modules/@typescript-eslint/tsconfig-utils": { - "version": "8.42.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.42.0.tgz", - "integrity": "sha512-kHeFUOdwAJfUmYKjR3CLgZSglGHjbNTi1H8sTYRYV2xX6eNz4RyJ2LIgsDLKf8Yi0/GL1WZAC/DgZBeBft8QAQ==", + "version": "8.54.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.54.0.tgz", + "integrity": "sha512-dRgOyT2hPk/JwxNMZDsIXDgyl9axdJI3ogZ2XWhBPsnZUv+hPesa5iuhdYt2gzwA9t8RE5ytOJ6xB0moV0Ujvw==", "dev": true, + "license": "MIT", "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, @@ -3821,16 +3748,17 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "8.42.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.42.0.tgz", - "integrity": "sha512-9KChw92sbPTYVFw3JLRH1ockhyR3zqqn9lQXol3/YbI6jVxzWoGcT3AsAW0mu1MY0gYtsXnUGV/AKpkAj5tVlQ==", + "version": "8.54.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.54.0.tgz", + "integrity": "sha512-hiLguxJWHjjwL6xMBwD903ciAwd7DmK30Y9Axs/etOkftC3ZNN9K44IuRD/EB08amu+Zw6W37x9RecLkOo3pMA==", "dev": true, + "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.42.0", - "@typescript-eslint/typescript-estree": "8.42.0", - "@typescript-eslint/utils": "8.42.0", - "debug": "^4.3.4", - "ts-api-utils": "^2.1.0" + "@typescript-eslint/types": "8.54.0", + "@typescript-eslint/typescript-estree": "8.54.0", + "@typescript-eslint/utils": "8.54.0", + "debug": "^4.4.3", + "ts-api-utils": "^2.4.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3845,10 +3773,11 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "8.42.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.42.0.tgz", - "integrity": "sha512-LdtAWMiFmbRLNP7JNeY0SqEtJvGMYSzfiWBSmx+VSZ1CH+1zyl8Mmw1TT39OrtsRvIYShjJWzTDMPWZJCpwBlw==", + "version": "8.54.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.54.0.tgz", + "integrity": "sha512-PDUI9R1BVjqu7AUDsRBbKMtwmjWcn4J3le+5LpcFgWULN3LvHC5rkc9gCVxbrsrGmO1jfPybN5s6h4Jy+OnkAA==", "dev": true, + "license": "MIT", "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, @@ -3858,21 +3787,21 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.42.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.42.0.tgz", - "integrity": "sha512-ku/uYtT4QXY8sl9EDJETD27o3Ewdi72hcXg1ah/kkUgBvAYHLwj2ofswFFNXS+FL5G+AGkxBtvGt8pFBHKlHsQ==", + "version": "8.54.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.54.0.tgz", + "integrity": "sha512-BUwcskRaPvTk6fzVWgDPdUndLjB87KYDrN5EYGetnktoeAvPtO4ONHlAZDnj5VFnUANg0Sjm7j4usBlnoVMHwA==", "dev": true, + "license": "MIT", "dependencies": { - "@typescript-eslint/project-service": "8.42.0", - "@typescript-eslint/tsconfig-utils": "8.42.0", - "@typescript-eslint/types": "8.42.0", - "@typescript-eslint/visitor-keys": "8.42.0", - "debug": "^4.3.4", - "fast-glob": "^3.3.2", - "is-glob": "^4.0.3", - "minimatch": "^9.0.4", - "semver": "^7.6.0", - "ts-api-utils": "^2.1.0" + "@typescript-eslint/project-service": "8.54.0", + "@typescript-eslint/tsconfig-utils": "8.54.0", + "@typescript-eslint/types": "8.54.0", + "@typescript-eslint/visitor-keys": "8.54.0", + "debug": "^4.4.3", + "minimatch": "^9.0.5", + "semver": "^7.7.3", + "tinyglobby": "^0.2.15", + "ts-api-utils": "^2.4.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3890,6 +3819,7 @@ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", "dev": true, + "license": "MIT", "dependencies": { "balanced-match": "^1.0.0" } @@ -3899,6 +3829,7 @@ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", "dev": true, + "license": "ISC", "dependencies": { "brace-expansion": "^2.0.1" }, @@ -3910,15 +3841,16 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "8.42.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.42.0.tgz", - "integrity": "sha512-JnIzu7H3RH5BrKC4NoZqRfmjqCIS1u3hGZltDYJgkVdqAezl4L9d1ZLw+36huCujtSBSAirGINF/S4UxOcR+/g==", + "version": "8.54.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.54.0.tgz", + "integrity": "sha512-9Cnda8GS57AQakvRyG0PTejJNlA2xhvyNtEVIMlDWOOeEyBkYWhGPnfrIAnqxLMTSTo6q8g12XVjjev5l1NvMA==", "dev": true, + "license": "MIT", "dependencies": { - "@eslint-community/eslint-utils": "^4.7.0", - "@typescript-eslint/scope-manager": "8.42.0", - "@typescript-eslint/types": "8.42.0", - "@typescript-eslint/typescript-estree": "8.42.0" + "@eslint-community/eslint-utils": "^4.9.1", + "@typescript-eslint/scope-manager": "8.54.0", + "@typescript-eslint/types": "8.54.0", + "@typescript-eslint/typescript-estree": "8.54.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3933,12 +3865,13 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.42.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.42.0.tgz", - "integrity": "sha512-3WbiuzoEowaEn8RSnhJBrxSwX8ULYE9CXaPepS2C2W3NSA5NNIvBaslpBSBElPq0UGr0xVJlXFWOAKIkyylydQ==", + "version": "8.54.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.54.0.tgz", + "integrity": "sha512-VFlhGSl4opC0bprJiItPQ1RfUhGDIBokcPwaFH4yiBCaNPeld/9VeXbiPO1cLyorQi1G1vL+ecBk1x8o1axORA==", "dev": true, + "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.42.0", + "@typescript-eslint/types": "8.54.0", "eslint-visitor-keys": "^4.2.1" }, "engines": { @@ -3954,6 +3887,7 @@ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", "dev": true, + "license": "Apache-2.0", "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, @@ -4263,7 +4197,7 @@ "version": "8.15.0", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", - "dev": true, + "devOptional": true, "bin": { "acorn": "bin/acorn" }, @@ -4586,7 +4520,7 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true + "devOptional": true }, "node_modules/call-bind": { "version": "1.0.8", @@ -4977,10 +4911,11 @@ "license": "MIT" }, "node_modules/debug": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", - "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", "devOptional": true, + "license": "MIT", "dependencies": { "ms": "^2.1.3" }, @@ -5062,7 +4997,7 @@ "version": "2.0.4", "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.4.tgz", "integrity": "sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==", - "dev": true, + "devOptional": true, "license": "Apache-2.0", "engines": { "node": ">=8" @@ -5632,34 +5567,6 @@ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "dev": true }, - "node_modules/fast-glob": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", - "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", - "dev": true, - "dependencies": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.8" - }, - "engines": { - "node": ">=8.6.0" - } - }, - "node_modules/fast-glob/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, "node_modules/fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", @@ -5688,15 +5595,6 @@ } ] }, - "node_modules/fastq": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", - "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", - "dev": true, - "dependencies": { - "reusify": "^1.0.4" - } - }, "node_modules/file-entry-cache": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", @@ -5863,7 +5761,6 @@ "version": "2.3.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "dev": true, "hasInstallScript": true, "optional": true, "os": [ @@ -6064,12 +5961,6 @@ "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", "dev": true }, - "node_modules/graphemer": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", - "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", - "dev": true - }, "node_modules/handlebars": { "version": "4.7.8", "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz", @@ -6849,7 +6740,7 @@ "version": "1.30.1", "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.30.1.tgz", "integrity": "sha512-xi6IyHML+c9+Q3W0S4fCQJOym42pyurFiJUHEcEyHS0CeKzia4yZDEsLlqOFykxOdHpNy0NmvVO31vcSqAxJCg==", - "dev": true, + "devOptional": true, "license": "MPL-2.0", "dependencies": { "detect-libc": "^2.0.3" @@ -6881,7 +6772,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MPL-2.0", "optional": true, "os": [ @@ -6902,7 +6792,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MPL-2.0", "optional": true, "os": [ @@ -6923,7 +6812,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MPL-2.0", "optional": true, "os": [ @@ -6944,7 +6832,6 @@ "cpu": [ "arm" ], - "dev": true, "license": "MPL-2.0", "optional": true, "os": [ @@ -6965,7 +6852,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MPL-2.0", "optional": true, "os": [ @@ -6986,7 +6872,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MPL-2.0", "optional": true, "os": [ @@ -7007,7 +6892,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MPL-2.0", "optional": true, "os": [ @@ -7028,7 +6912,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MPL-2.0", "optional": true, "os": [ @@ -7049,7 +6932,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MPL-2.0", "optional": true, "os": [ @@ -7070,7 +6952,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MPL-2.0", "optional": true, "os": [ @@ -7243,28 +7124,6 @@ "resolved": "https://registry.npmjs.org/medium-zoom/-/medium-zoom-1.1.0.tgz", "integrity": "sha512-ewyDsp7k4InCUp3jRmwHBRFGyjBimKps/AJLjRSox+2q/2H4p/PNpQf+pwONWlJiOudkBXtbdmVbFjqyybfTmQ==" }, - "node_modules/merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true, - "engines": { - "node": ">= 8" - } - }, - "node_modules/micromatch": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", - "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", - "dev": true, - "dependencies": { - "braces": "^3.0.3", - "picomatch": "^2.3.1" - }, - "engines": { - "node": ">=8.6" - } - }, "node_modules/mime-db": { "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", @@ -7774,26 +7633,6 @@ "node": ">=10.13.0" } }, - "node_modules/queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, "node_modules/randombytes": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", @@ -7984,16 +7823,6 @@ "node": ">=4" } }, - "node_modules/reusify": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", - "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", - "dev": true, - "engines": { - "iojs": ">=1.0.0", - "node": ">=0.10.0" - } - }, "node_modules/rfdc": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz", @@ -8059,29 +7888,6 @@ "node": ">=16" } }, - "node_modules/run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "queue-microtask": "^1.2.2" - } - }, "node_modules/safe-array-concat": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.3.tgz", @@ -8155,9 +7961,10 @@ } }, "node_modules/semver": { - "version": "7.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz", - "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "license": "ISC", "bin": { "semver": "bin/semver.js" }, @@ -8386,7 +8193,7 @@ "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, + "devOptional": true, "engines": { "node": ">=0.10.0" } @@ -8403,7 +8210,7 @@ "version": "0.5.21", "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", - "dev": true, + "devOptional": true, "dependencies": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" @@ -8682,7 +8489,7 @@ "version": "5.37.0", "resolved": "https://registry.npmjs.org/terser/-/terser-5.37.0.tgz", "integrity": "sha512-B8wRRkmre4ERucLM/uXx4MOV5cbnOlVAqUst+1+iLKPI0dOgFO28f84ptoQt9HEI537PMzfYa/d+GEPKTRXmYA==", - "dev": true, + "devOptional": true, "dependencies": { "@jridgewell/source-map": "^0.3.3", "acorn": "^8.8.2", @@ -8700,7 +8507,7 @@ "version": "2.20.3", "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true + "devOptional": true }, "node_modules/tinyglobby": { "version": "0.2.15", @@ -8772,10 +8579,11 @@ } }, "node_modules/ts-api-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.1.0.tgz", - "integrity": "sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==", + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.4.0.tgz", + "integrity": "sha512-3TaVTaAv2gTiMB35i3FiGJaRfwb3Pyn/j3m/bfAvGe8FB7CF6u+LMYqYlDh7reQf7UNvoTvdfAqHGmPGOSsPmA==", "dev": true, + "license": "MIT", "engines": { "node": ">=18.12" }, @@ -8895,15 +8703,16 @@ } }, "node_modules/typescript-eslint": { - "version": "8.42.0", - "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.42.0.tgz", - "integrity": "sha512-ozR/rQn+aQXQxh1YgbCzQWDFrsi9mcg+1PM3l/z5o1+20P7suOIaNg515bpr/OYt6FObz/NHcBstydDLHWeEKg==", + "version": "8.54.0", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.54.0.tgz", + "integrity": "sha512-CKsJ+g53QpsNPqbzUsfKVgd3Lny4yKZ1pP4qN3jdMOg/sisIDLGyDMezycquXLE5JsEU0wp3dGNdzig0/fmSVQ==", "dev": true, + "license": "MIT", "dependencies": { - "@typescript-eslint/eslint-plugin": "8.42.0", - "@typescript-eslint/parser": "8.42.0", - "@typescript-eslint/typescript-estree": "8.42.0", - "@typescript-eslint/utils": "8.42.0" + "@typescript-eslint/eslint-plugin": "8.54.0", + "@typescript-eslint/parser": "8.54.0", + "@typescript-eslint/typescript-estree": "8.54.0", + "@typescript-eslint/utils": "8.54.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -8957,7 +8766,7 @@ "version": "6.20.0", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz", "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==", - "dev": true + "devOptional": true }, "node_modules/unicode-canonical-property-names-ecmascript": { "version": "2.0.1", diff --git a/frontend/package.json b/frontend/package.json index e23fd39be..9b4893678 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -75,6 +75,6 @@ "vue-tsc": "^2.2.8" }, "engines": { - "node": "18" + "node": ">18" } } diff --git a/frontend/src/utils/index.ts b/frontend/src/utils/index.ts index 41198c934..657de0be2 100644 --- a/frontend/src/utils/index.ts +++ b/frontend/src/utils/index.ts @@ -673,13 +673,6 @@ export const romStatusMap: Record< hidden: { emoji: "👻", text: "Hidden", i18nKey: "rom.status-hidden" }, }; -/** - * Inverse map of ROM statuses from text to status key. - */ -const inverseRomStatusMap = Object.fromEntries( - Object.entries(romStatusMap).map(([key, value]) => [value.text, key]), -) as Record; - /** * Get the emoji for a given ROM status. * From eebb8926b39c496d57350132eae3ae836c88b434 Mon Sep 17 00:00:00 2001 From: Georges-Antoine Assi Date: Sat, 7 Feb 2026 22:18:35 -0500 Subject: [PATCH 5/7] bump ts eslint --- frontend/package-lock.json | 2 +- frontend/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 7443c5ed8..746565d15 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -47,7 +47,7 @@ "globals": "^16.0.0", "openapi-typescript-codegen": "^0.29.0", "typescript": "^5.7.3", - "typescript-eslint": "^8.42.0", + "typescript-eslint": "^8.54.0", "vite": "^6.4.1", "vite-plugin-mkcert": "^1.17.8", "vite-plugin-pwa": "^0.21.1", diff --git a/frontend/package.json b/frontend/package.json index 9b4893678..1fbb62bfc 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -66,7 +66,7 @@ "globals": "^16.0.0", "openapi-typescript-codegen": "^0.29.0", "typescript": "^5.7.3", - "typescript-eslint": "^8.42.0", + "typescript-eslint": "^8.54.0", "vite": "^6.4.1", "vite-plugin-mkcert": "^1.17.8", "vite-plugin-pwa": "^0.21.1", From cb85d70b8398cec0d1420043abad117c2040be11 Mon Sep 17 00:00:00 2001 From: Georges-Antoine Assi Date: Sat, 7 Feb 2026 22:27:44 -0500 Subject: [PATCH 6/7] extract filter into own block --- backend/handler/database/roms_handler.py | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/backend/handler/database/roms_handler.py b/backend/handler/database/roms_handler.py index ca7393454..a93eb7134 100644 --- a/backend/handler/database/roms_handler.py +++ b/backend/handler/database/roms_handler.py @@ -433,7 +433,6 @@ class DBRomsHandler(DBBaseHandler): match_all: bool = False, match_none: bool = False, ): - """Filter by one or more user statuses using OR logic.""" if not values: return query @@ -734,7 +733,6 @@ class DBRomsHandler(DBBaseHandler): (regions, regions_logic, self._filter_by_regions), (languages, languages_logic, self._filter_by_languages), (player_counts, player_counts_logic, self._filter_by_player_counts), - (statuses, statuses_logic, self._filter_by_status), ] for values, logic, filter_func in filters_to_apply: @@ -748,8 +746,15 @@ class DBRomsHandler(DBBaseHandler): ) # The RomUser table is already joined if user_id is set - # If hidden wasn't explicitly requested, always exclude hidden rows - if user_id and (not statuses or "hidden" not in statuses): + if statuses and user_id: + query = self._filter_by_status( + query, + session=session, + values=statuses, + match_all=(statuses_logic == "all"), + match_none=(statuses_logic == "none"), + ) + elif user_id: query = query.filter( or_(RomUser.hidden.is_(False), RomUser.hidden.is_(None)) ) From 5596999a3b81cd05519f7fc505a71e95bbcbdd64 Mon Sep 17 00:00:00 2001 From: Georges-Antoine Assi Date: Sat, 7 Feb 2026 22:46:09 -0500 Subject: [PATCH 7/7] one last regression --- backend/handler/database/roms_handler.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/backend/handler/database/roms_handler.py b/backend/handler/database/roms_handler.py index a93eb7134..c3334b367 100644 --- a/backend/handler/database/roms_handler.py +++ b/backend/handler/database/roms_handler.py @@ -451,7 +451,13 @@ class DBRomsHandler(DBBaseHandler): condition = comb(*status_filters) # Apply negation if match_none, otherwise apply condition - return query.filter(~condition) if match_none else query.filter(condition) + query = query.filter(~condition) if match_none else query.filter(condition) + + # Don't apply the hidden filter is hidden is set + if "hidden" in values: + return query + + return query.filter(or_(RomUser.hidden.is_(False), RomUser.hidden.is_(None))) def _filter_by_regions( self,