From dd1ada268ff3d9fe91343d25cc951eb48b705ba5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 10 Dec 2025 09:49:47 +0100 Subject: [PATCH 01/22] build(deps): bump actions/setup-node from 6.0.0 to 6.1.0 (#617) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/deploy.docs.yml | 2 +- .github/workflows/test.backend.seed.yml | 2 +- .github/workflows/test.build.lib.yml | 4 ++-- .github/workflows/test.docs.lib.yml | 4 ++-- .github/workflows/test.e2e.yml | 4 ++-- .github/workflows/test.lint.cypress.yml | 2 +- .github/workflows/test.lint.frontend.yml | 2 +- .github/workflows/test.lint.lib.examples.yml | 10 +++++----- .github/workflows/test.lint.lib.yml | 2 +- .github/workflows/test.unit.lib.yml | 2 +- 10 files changed, 17 insertions(+), 17 deletions(-) diff --git a/.github/workflows/deploy.docs.yml b/.github/workflows/deploy.docs.yml index 2c0ec25e..9d21e5c5 100644 --- a/.github/workflows/deploy.docs.yml +++ b/.github/workflows/deploy.docs.yml @@ -12,7 +12,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v4.1.7 - - uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v4.0.3 + - uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v4.0.3 with: node-version-file: '.tool-versions' - name: Install Dependencies & Build Library diff --git a/.github/workflows/test.backend.seed.yml b/.github/workflows/test.backend.seed.yml index 8bb77e5e..2ac02761 100644 --- a/.github/workflows/test.backend.seed.yml +++ b/.github/workflows/test.backend.seed.yml @@ -30,7 +30,7 @@ jobs: uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v4.1.7 - name: Setup Node.js - uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0 + uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.0 with: node-version-file: '.tool-versions' diff --git a/.github/workflows/test.build.lib.yml b/.github/workflows/test.build.lib.yml index fbf76fe4..f98ed1b1 100644 --- a/.github/workflows/test.build.lib.yml +++ b/.github/workflows/test.build.lib.yml @@ -25,7 +25,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v4.1.7 - - uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v4.0.3 + - uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v4.0.3 with: node-version-file: '.tool-versions' - name: Install Dependencies & Build Library @@ -45,7 +45,7 @@ jobs: steps: - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v4.1.7 - - uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v4.0.3 + - uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v4.0.3 with: node-version-file: '.tool-versions' - name: Link Utopia-UI in Example App diff --git a/.github/workflows/test.docs.lib.yml b/.github/workflows/test.docs.lib.yml index 66065d0c..eea57407 100644 --- a/.github/workflows/test.docs.lib.yml +++ b/.github/workflows/test.docs.lib.yml @@ -26,7 +26,7 @@ jobs: # runs-on: ubuntu-latest # steps: # - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v4.1.7 -# - uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v4.0.3 +# - uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v4.0.3 # with: # node-version-file: './.tool-versions' # - name: Frontend | Build @@ -42,7 +42,7 @@ jobs: COVERAGE_REQUIRED: 0 steps: - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v4.1.7 - - uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v4.0.3 + - uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v4.0.3 with: node-version-file: '.tool-versions' - name: Docs diff --git a/.github/workflows/test.e2e.yml b/.github/workflows/test.e2e.yml index 2952b2b5..872c521d 100644 --- a/.github/workflows/test.e2e.yml +++ b/.github/workflows/test.e2e.yml @@ -15,7 +15,7 @@ jobs: uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v5.0.0 - name: Set up Node.js - uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v5.0.0 + uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v5.0.0 with: node-version-file: ./.tool-versions cache: 'npm' @@ -159,7 +159,7 @@ jobs: uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v5.0.0 - name: Setup Node.js - uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v5.0.0 + uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v5.0.0 with: node-version: '20' cache: 'npm' diff --git a/.github/workflows/test.lint.cypress.yml b/.github/workflows/test.lint.cypress.yml index 59363675..bd826140 100644 --- a/.github/workflows/test.lint.cypress.yml +++ b/.github/workflows/test.lint.cypress.yml @@ -26,7 +26,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v5.0.0 - - uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v5.0.0 + - uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v5.0.0 with: node-version-file: '.tool-versions' - name: Lint diff --git a/.github/workflows/test.lint.frontend.yml b/.github/workflows/test.lint.frontend.yml index 79e7fd13..e86d96ea 100644 --- a/.github/workflows/test.lint.frontend.yml +++ b/.github/workflows/test.lint.frontend.yml @@ -25,7 +25,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v4.1.7 - - uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v4.0.3 + - uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v4.0.3 with: node-version-file: '.tool-versions' - name: Lint diff --git a/.github/workflows/test.lint.lib.examples.yml b/.github/workflows/test.lint.lib.examples.yml index 1fb853bf..ecbabcce 100644 --- a/.github/workflows/test.lint.lib.examples.yml +++ b/.github/workflows/test.lint.lib.examples.yml @@ -25,7 +25,7 @@ jobs: # runs-on: ubuntu-latest # steps: # - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v4.1.7 -# - uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v4.0.3 +# - uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v4.0.3 # with: # node-version-file: './.tool-versions' # - name: Frontend | Build @@ -39,7 +39,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v4.1.7 - - uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v4.0.3 + - uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v4.0.3 with: node-version-file: '.tool-versions' - name: Lint @@ -53,7 +53,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v4.1.7 - - uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v4.0.3 + - uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v4.0.3 with: node-version-file: '.tool-versions' - name: Lint @@ -67,7 +67,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v4.1.7 - - uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v4.0.3 + - uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v4.0.3 with: node-version-file: '.tool-versions' - name: Lint @@ -81,7 +81,7 @@ jobs: # runs-on: ubuntu-latest # steps: # - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v4.1.7 -# - uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v4.0.3 +# - uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v4.0.3 # with: # node-version-file: './.tool-versions' # - name: Frontend | Unit diff --git a/.github/workflows/test.lint.lib.yml b/.github/workflows/test.lint.lib.yml index 24e6e957..e66521ef 100644 --- a/.github/workflows/test.lint.lib.yml +++ b/.github/workflows/test.lint.lib.yml @@ -25,7 +25,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v4.1.7 - - uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v4.0.3 + - uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v4.0.3 with: node-version-file: '.tool-versions' - name: Lint diff --git a/.github/workflows/test.unit.lib.yml b/.github/workflows/test.unit.lib.yml index d9c75a9b..11edc747 100644 --- a/.github/workflows/test.unit.lib.yml +++ b/.github/workflows/test.unit.lib.yml @@ -25,7 +25,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v4.1.7 - - uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v4.0.3 + - uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v4.0.3 with: node-version-file: '.tool-versions' - name: Unit From 40ef048f88fb1a07987390a0af196db6e825a666 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 10 Dec 2025 09:09:53 +0000 Subject: [PATCH 02/22] build(deps-dev): bump prettier from 3.7.3 to 3.7.4 (#610) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- lib/package.json | 2 +- package-lock.json | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/package.json b/lib/package.json index 1f560316..ba77af8f 100644 --- a/lib/package.json +++ b/lib/package.json @@ -79,7 +79,7 @@ "eslint-plugin-yml": "^1.14.0", "happy-dom": "^20.0.11", "postcss": "^8.4.21", - "prettier": "^3.7.3", + "prettier": "^3.7.4", "react": "^18.3.1", "react-dom": "^18.3.1", "rollup": "^4.53.3", diff --git a/package-lock.json b/package-lock.json index 0d8c462f..f827717d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -136,7 +136,7 @@ "eslint-plugin-yml": "^1.14.0", "happy-dom": "^20.0.11", "postcss": "^8.4.21", - "prettier": "^3.7.3", + "prettier": "^3.7.4", "react": "^18.3.1", "react-dom": "^18.3.1", "rollup": "^4.53.3", @@ -13259,9 +13259,9 @@ } }, "node_modules/prettier": { - "version": "3.7.3", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.7.3.tgz", - "integrity": "sha512-QgODejq9K3OzoBbuyobZlUhznP5SKwPqp+6Q6xw6o8gnhr4O85L2U915iM2IDcfF2NPXVaM9zlo9tdwipnYwzg==", + "version": "3.7.4", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.7.4.tgz", + "integrity": "sha512-v6UNi1+3hSlVvv8fSaoUbggEM5VErKmmpGA7Pl3HF8V6uKY7rvClBOJlH6yNwQtfTueNkGVpOv/mtWL9L4bgRA==", "dev": true, "license": "MIT", "peer": true, From c7fe238b51c7ec6cda09571d3468991397e4f9c1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 10 Dec 2025 09:16:06 +0000 Subject: [PATCH 03/22] build(deps-dev): bump vite from 7.2.4 to 7.2.7 (#615) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- app/package.json | 2 +- lib/package.json | 2 +- package-lock.json | 10 +++++----- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/app/package.json b/app/package.json index 6615495a..7c94df45 100644 --- a/app/package.json +++ b/app/package.json @@ -52,7 +52,7 @@ "postcss": "^8.4.30", "tailwindcss": "^4.1.17", "typescript": "^5.9.3", - "vite": "^7.2.4", + "vite": "^7.2.7", "vite-plugin-pwa": "^1.1.0" } } diff --git a/lib/package.json b/lib/package.json index ba77af8f..142dfb5e 100644 --- a/lib/package.json +++ b/lib/package.json @@ -91,7 +91,7 @@ "typedoc-plugin-coverage": "^3.4.1", "typedoc-plugin-missing-exports": "^3.1.0", "typescript": "^5.9.3", - "vite": "^7.2.4", + "vite": "^7.2.7", "vite-plugin-svgr": "^4.3.0", "vitest": "^3.0.5" }, diff --git a/package-lock.json b/package-lock.json index f827717d..1709a735 100644 --- a/package-lock.json +++ b/package-lock.json @@ -53,7 +53,7 @@ "postcss": "^8.4.30", "tailwindcss": "^4.1.17", "typescript": "^5.9.3", - "vite": "^7.2.4", + "vite": "^7.2.7", "vite-plugin-pwa": "^1.1.0" }, "engines": { @@ -148,7 +148,7 @@ "typedoc-plugin-coverage": "^3.4.1", "typedoc-plugin-missing-exports": "^3.1.0", "typescript": "^5.9.3", - "vite": "^7.2.4", + "vite": "^7.2.7", "vite-plugin-svgr": "^4.3.0", "vitest": "^3.0.5" }, @@ -16403,9 +16403,9 @@ } }, "node_modules/vite": { - "version": "7.2.4", - "resolved": "https://registry.npmjs.org/vite/-/vite-7.2.4.tgz", - "integrity": "sha512-NL8jTlbo0Tn4dUEXEsUg8KeyG/Lkmc4Fnzb8JXN/Ykm9G4HNImjtABMJgkQoVjOBN/j2WAwDTRytdqJbZsah7w==", + "version": "7.2.7", + "resolved": "https://registry.npmjs.org/vite/-/vite-7.2.7.tgz", + "integrity": "sha512-ITcnkFeR3+fI8P1wMgItjGrR10170d8auB4EpMLPqmx6uxElH3a/hHGQabSHKdqd4FXWO1nFIp9rRn7JQ34ACQ==", "license": "MIT", "peer": true, "dependencies": { From 6fede959538306c67bef3458d73c6345233d447c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 10 Dec 2025 09:41:35 +0000 Subject: [PATCH 04/22] build(deps): bump yet-another-react-lightbox from 3.25.0 to 3.26.0 (#616) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- lib/package.json | 2 +- package-lock.json | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/package.json b/lib/package.json index 142dfb5e..910aa8ed 100644 --- a/lib/package.json +++ b/lib/package.json @@ -133,7 +133,7 @@ "react-toastify": "^9.1.3", "remark-breaks": "^4.0.0", "tiptap-markdown": "^0.9.0", - "yet-another-react-lightbox": "^3.21.7" + "yet-another-react-lightbox": "^3.26.0" }, "imports": { "#assets/*": "./src/assets/*", diff --git a/package-lock.json b/package-lock.json index 1709a735..7ff74bd4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -97,7 +97,7 @@ "react-toastify": "^9.1.3", "remark-breaks": "^4.0.0", "tiptap-markdown": "^0.9.0", - "yet-another-react-lightbox": "^3.21.7" + "yet-another-react-lightbox": "^3.26.0" }, "devDependencies": { "@eslint-community/eslint-plugin-eslint-comments": "^4.4.1", @@ -17371,9 +17371,9 @@ } }, "node_modules/yet-another-react-lightbox": { - "version": "3.25.0", - "resolved": "https://registry.npmjs.org/yet-another-react-lightbox/-/yet-another-react-lightbox-3.25.0.tgz", - "integrity": "sha512-NaCeEXCpdwoTvoOpxNK9gdW8+oHs79yVH+D2YeVQWRjH5i32e5CoXndAAFP2p8awzVYfSonherrE9JMTpfD3EA==", + "version": "3.26.0", + "resolved": "https://registry.npmjs.org/yet-another-react-lightbox/-/yet-another-react-lightbox-3.26.0.tgz", + "integrity": "sha512-/JQqrzh9gEjD7X8PcEmUHAT61Ga9Qf4FTUFJcvW/j40RE5OYKQjQfGhcy2XVyG3GshVZ42+boeKsK1EySIznNA==", "license": "MIT", "engines": { "node": ">=14" From bea6d8dde1e08007a778c9e8305dd8ba57853b53 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 10 Dec 2025 09:54:11 +0000 Subject: [PATCH 05/22] build(deps): bump amannn/action-semantic-pull-request from 5 to 6 (#446) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/test.lint.pr.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.lint.pr.yml b/.github/workflows/test.lint.pr.yml index 61cf293b..95888bd1 100644 --- a/.github/workflows/test.lint.pr.yml +++ b/.github/workflows/test.lint.pr.yml @@ -17,7 +17,7 @@ jobs: runs-on: ubuntu-latest if: ${{ github.actor != 'dependabot[bot]' }} steps: - - uses: amannn/action-semantic-pull-request@v5 + - uses: amannn/action-semantic-pull-request@v6 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: From 38950b8f3d0d58122e9e91c4ed8c157b1133b32d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 10 Dec 2025 10:02:00 +0000 Subject: [PATCH 06/22] build(deps-dev): bump vite-plugin-pwa from 1.1.0 to 1.2.0 (#601) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- app/package.json | 2 +- package-lock.json | 530 +++++++++++++++++++++++++++------------------- 2 files changed, 319 insertions(+), 213 deletions(-) diff --git a/app/package.json b/app/package.json index 7c94df45..c366d524 100644 --- a/app/package.json +++ b/app/package.json @@ -53,6 +53,6 @@ "tailwindcss": "^4.1.17", "typescript": "^5.9.3", "vite": "^7.2.7", - "vite-plugin-pwa": "^1.1.0" + "vite-plugin-pwa": "^1.2.0" } } diff --git a/package-lock.json b/package-lock.json index 7ff74bd4..dda7454b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -54,7 +54,7 @@ "tailwindcss": "^4.1.17", "typescript": "^5.9.3", "vite": "^7.2.7", - "vite-plugin-pwa": "^1.1.0" + "vite-plugin-pwa": "^1.2.0" }, "engines": { "node": ">=22.20.0" @@ -211,9 +211,9 @@ } }, "node_modules/@babel/compat-data": { - "version": "7.28.4", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.28.4.tgz", - "integrity": "sha512-YsmSKC29MJwf0gF8Rjjrg5LQCmyh+j/nD8/eP7f+BeoQTKYqs9RoWbjGOdy0+1Ekr68RJZMUOPVQaQisnIo4Rw==", + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.28.5.tgz", + "integrity": "sha512-6uFXyCayocRbqhZOB+6XcuZbkMNimwfVGFji8CTZnCzOHVGvDqzvitu1re2AU5LROliz7eQPhB8CpAMvnx9EjA==", "dev": true, "license": "MIT", "engines": { @@ -263,14 +263,14 @@ } }, "node_modules/@babel/generator": { - "version": "7.28.3", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.28.3.tgz", - "integrity": "sha512-3lSpxGgvnmZznmBkCRnVREPUFJv2wrv9iAoFDvADJc0ypmdOxdUtcLeBgBJ6zE0PMeTKnxeQzyk0xTBq4Ep7zw==", + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.28.5.tgz", + "integrity": "sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ==", "dev": true, "license": "MIT", "dependencies": { - "@babel/parser": "^7.28.3", - "@babel/types": "^7.28.2", + "@babel/parser": "^7.28.5", + "@babel/types": "^7.28.5", "@jridgewell/gen-mapping": "^0.3.12", "@jridgewell/trace-mapping": "^0.3.28", "jsesc": "^3.0.2" @@ -320,18 +320,18 @@ } }, "node_modules/@babel/helper-create-class-features-plugin": { - "version": "7.28.3", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.28.3.tgz", - "integrity": "sha512-V9f6ZFIYSLNEbuGA/92uOvYsGCJNsuA8ESZ4ldc09bWk/j8H8TKiPw8Mk1eG6olpnO0ALHJmYfZvF4MEE4gajg==", + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.28.5.tgz", + "integrity": "sha512-q3WC4JfdODypvxArsJQROfupPBq9+lMwjKq7C33GhbFYJsufD0yd/ziwD+hJucLeWsnFPWZjsU2DNFqBPE7jwQ==", "dev": true, "license": "MIT", "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", - "@babel/helper-member-expression-to-functions": "^7.27.1", + "@babel/helper-member-expression-to-functions": "^7.28.5", "@babel/helper-optimise-call-expression": "^7.27.1", "@babel/helper-replace-supers": "^7.27.1", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", - "@babel/traverse": "^7.28.3", + "@babel/traverse": "^7.28.5", "semver": "^6.3.1" }, "engines": { @@ -352,14 +352,14 @@ } }, "node_modules/@babel/helper-create-regexp-features-plugin": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.27.1.tgz", - "integrity": "sha512-uVDC72XVf8UbrH5qQTc18Agb8emwjTiZrQE11Nv3CuBEZmVvTwwE9CBUEvHku06gQCAyYf8Nv6ja1IN+6LMbxQ==", + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.28.5.tgz", + "integrity": "sha512-N1EhvLtHzOvj7QQOUCCS3NrPJP8c5W6ZXCHDn7Yialuy1iu4r5EmIYkXlKNqT99Ciw+W0mDqWoR6HWMZlFP3hw==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.27.1", - "regexpu-core": "^6.2.0", + "@babel/helper-annotate-as-pure": "^7.27.3", + "regexpu-core": "^6.3.1", "semver": "^6.3.1" }, "engines": { @@ -407,14 +407,14 @@ } }, "node_modules/@babel/helper-member-expression-to-functions": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.27.1.tgz", - "integrity": "sha512-E5chM8eWjTp/aNoVpcbfM7mLxu9XGLWYise2eBKGQomAk/Mb4XoxyqXTZbuTohbsl8EKqdlMhnDI2CCLfcs9wA==", + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.28.5.tgz", + "integrity": "sha512-cwM7SBRZcPCLgl8a7cY0soT1SptSzAlMH39vwiRpOQkJlh53r5hdHwLSCZpQdVLT39sZt+CRpNwYG4Y2v77atg==", "dev": true, "license": "MIT", "dependencies": { - "@babel/traverse": "^7.27.1", - "@babel/types": "^7.27.1" + "@babel/traverse": "^7.28.5", + "@babel/types": "^7.28.5" }, "engines": { "node": ">=6.9.0" @@ -536,9 +536,9 @@ } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz", - "integrity": "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==", + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", + "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", "dev": true, "license": "MIT", "engines": { @@ -585,13 +585,13 @@ } }, "node_modules/@babel/parser": { - "version": "7.28.4", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.4.tgz", - "integrity": "sha512-yZbBqeM6TkpP9du/I2pUZnJsRMGGvOuIrhjzC1AwHwW+6he4mni6Bp/m8ijn0iOuZuPI2BfkCoSRunpyjnrQKg==", + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.5.tgz", + "integrity": "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ==", "dev": true, "license": "MIT", "dependencies": { - "@babel/types": "^7.28.4" + "@babel/types": "^7.28.5" }, "bin": { "parser": "bin/babel-parser.js" @@ -601,14 +601,14 @@ } }, "node_modules/@babel/plugin-bugfix-firefox-class-in-computed-class-key": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.27.1.tgz", - "integrity": "sha512-QPG3C9cCVRQLxAVwmefEmwdTanECuUBMQZ/ym5kiw3XKCGA7qkuQLcjWWHcrD/GKbn/WmJwaezfuuAOcyKlRPA==", + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.28.5.tgz", + "integrity": "sha512-87GDMS3tsmMSi/3bWOte1UblL+YUTFMV8SZPZ2eSEL17s74Cw/l63rR6NmGVKMYW2GYi85nE+/d6Hw5N0bEk2Q==", "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", - "@babel/traverse": "^7.27.1" + "@babel/traverse": "^7.28.5" }, "engines": { "node": ">=6.9.0" @@ -815,9 +815,9 @@ } }, "node_modules/@babel/plugin-transform-block-scoping": { - "version": "7.28.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.28.4.tgz", - "integrity": "sha512-1yxmvN0MJHOhPVmAsmoW5liWwoILobu/d/ShymZmj867bAdxGbehIrew1DuLpw2Ukv+qDSSPQdYW1dLNE7t11A==", + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.28.5.tgz", + "integrity": "sha512-45DmULpySVvmq9Pj3X9B+62Xe+DJGov27QravQJU1LLcapR6/10i+gYVAucGGJpHBp5mYxIMK4nDAT/QDLr47g==", "dev": true, "license": "MIT", "dependencies": { @@ -903,14 +903,14 @@ } }, "node_modules/@babel/plugin-transform-destructuring": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.28.0.tgz", - "integrity": "sha512-v1nrSMBiKcodhsyJ4Gf+Z0U/yawmJDBOTpEB3mcQY52r9RIyPneGyAS/yM6seP/8I+mWI3elOMtT5dB8GJVs+A==", + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.28.5.tgz", + "integrity": "sha512-Kl9Bc6D0zTUcFUvkNuQh4eGXPKKNDOJQXVyyM4ZAQPMveniJdxi8XMJwLo+xSoW3MIq81bD33lcUe9kZpl0MCw==", "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", - "@babel/traverse": "^7.28.0" + "@babel/traverse": "^7.28.5" }, "engines": { "node": ">=6.9.0" @@ -1003,9 +1003,9 @@ } }, "node_modules/@babel/plugin-transform-exponentiation-operator": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.27.1.tgz", - "integrity": "sha512-uspvXnhHvGKf2r4VVtBpeFnuDWsJLQ6MF6lGJLC89jBR1uoVeqM416AZtTuhTezOfgHicpJQmoD5YUakO/YmXQ==", + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.28.5.tgz", + "integrity": "sha512-D4WIMaFtwa2NizOp+dnoFjRez/ClKiC2BqqImwKd1X28nqBtZEyCYJ2ozQrrzlxAFrcrjxo39S6khe9RNDlGzw==", "dev": true, "license": "MIT", "dependencies": { @@ -1102,9 +1102,9 @@ } }, "node_modules/@babel/plugin-transform-logical-assignment-operators": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.27.1.tgz", - "integrity": "sha512-SJvDs5dXxiae4FbSL1aBJlG4wvl594N6YEVVn9e3JGulwioy6z3oPjx/sQBO3Y4NwUu5HNix6KJ3wBZoewcdbw==", + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.28.5.tgz", + "integrity": "sha512-axUuqnUTBuXyHGcJEVVh9pORaN6wC5bYfE7FGzPiaWa3syib9m7g+/IT/4VgCOe2Upef43PHzeAvcrVek6QuuA==", "dev": true, "license": "MIT", "dependencies": { @@ -1168,16 +1168,16 @@ } }, "node_modules/@babel/plugin-transform-modules-systemjs": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.27.1.tgz", - "integrity": "sha512-w5N1XzsRbc0PQStASMksmUeqECuzKuTJer7kFagK8AXgpCMkeDMO5S+aaFb7A51ZYDF7XI34qsTX+fkHiIm5yA==", + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.28.5.tgz", + "integrity": "sha512-vn5Jma98LCOeBy/KpeQhXcV2WZgaRUtjwQmjoBuLNlOmkg0fB5pdvYVeWRYI69wWKwK2cD1QbMiUQnoujWvrew==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-module-transforms": "^7.27.1", + "@babel/helper-module-transforms": "^7.28.3", "@babel/helper-plugin-utils": "^7.27.1", - "@babel/helper-validator-identifier": "^7.27.1", - "@babel/traverse": "^7.27.1" + "@babel/helper-validator-identifier": "^7.28.5", + "@babel/traverse": "^7.28.5" }, "engines": { "node": ">=6.9.0" @@ -1322,9 +1322,9 @@ } }, "node_modules/@babel/plugin-transform-optional-chaining": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.27.1.tgz", - "integrity": "sha512-BQmKPPIuc8EkZgNKsv0X4bPmOoayeu4F1YCwx2/CfmDSXDbp7GnzlUH+/ul5VGfRg1AoFPsrIThlEBj2xb4CAg==", + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.28.5.tgz", + "integrity": "sha512-N6fut9IZlPnjPwgiQkXNhb+cT8wQKFlJNqcZkWlcTqkcqx6/kU4ynGmLFoa4LViBSirn05YAwk+sQBbPfxtYzQ==", "dev": true, "license": "MIT", "dependencies": { @@ -1635,17 +1635,17 @@ } }, "node_modules/@babel/preset-env": { - "version": "7.28.3", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.28.3.tgz", - "integrity": "sha512-ROiDcM+GbYVPYBOeCR6uBXKkQpBExLl8k9HO1ygXEyds39j+vCCsjmj7S8GOniZQlEs81QlkdJZe76IpLSiqpg==", + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.28.5.tgz", + "integrity": "sha512-S36mOoi1Sb6Fz98fBfE+UZSpYw5mJm0NUHtIKrOuNcqeFauy1J6dIvXm2KRVKobOSaGq4t/hBXdN4HGU3wL9Wg==", "dev": true, "license": "MIT", "dependencies": { - "@babel/compat-data": "^7.28.0", + "@babel/compat-data": "^7.28.5", "@babel/helper-compilation-targets": "^7.27.2", "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-validator-option": "^7.27.1", - "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.27.1", + "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.28.5", "@babel/plugin-bugfix-safari-class-field-initializer-scope": "^7.27.1", "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.27.1", "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.27.1", @@ -1658,42 +1658,42 @@ "@babel/plugin-transform-async-generator-functions": "^7.28.0", "@babel/plugin-transform-async-to-generator": "^7.27.1", "@babel/plugin-transform-block-scoped-functions": "^7.27.1", - "@babel/plugin-transform-block-scoping": "^7.28.0", + "@babel/plugin-transform-block-scoping": "^7.28.5", "@babel/plugin-transform-class-properties": "^7.27.1", "@babel/plugin-transform-class-static-block": "^7.28.3", - "@babel/plugin-transform-classes": "^7.28.3", + "@babel/plugin-transform-classes": "^7.28.4", "@babel/plugin-transform-computed-properties": "^7.27.1", - "@babel/plugin-transform-destructuring": "^7.28.0", + "@babel/plugin-transform-destructuring": "^7.28.5", "@babel/plugin-transform-dotall-regex": "^7.27.1", "@babel/plugin-transform-duplicate-keys": "^7.27.1", "@babel/plugin-transform-duplicate-named-capturing-groups-regex": "^7.27.1", "@babel/plugin-transform-dynamic-import": "^7.27.1", "@babel/plugin-transform-explicit-resource-management": "^7.28.0", - "@babel/plugin-transform-exponentiation-operator": "^7.27.1", + "@babel/plugin-transform-exponentiation-operator": "^7.28.5", "@babel/plugin-transform-export-namespace-from": "^7.27.1", "@babel/plugin-transform-for-of": "^7.27.1", "@babel/plugin-transform-function-name": "^7.27.1", "@babel/plugin-transform-json-strings": "^7.27.1", "@babel/plugin-transform-literals": "^7.27.1", - "@babel/plugin-transform-logical-assignment-operators": "^7.27.1", + "@babel/plugin-transform-logical-assignment-operators": "^7.28.5", "@babel/plugin-transform-member-expression-literals": "^7.27.1", "@babel/plugin-transform-modules-amd": "^7.27.1", "@babel/plugin-transform-modules-commonjs": "^7.27.1", - "@babel/plugin-transform-modules-systemjs": "^7.27.1", + "@babel/plugin-transform-modules-systemjs": "^7.28.5", "@babel/plugin-transform-modules-umd": "^7.27.1", "@babel/plugin-transform-named-capturing-groups-regex": "^7.27.1", "@babel/plugin-transform-new-target": "^7.27.1", "@babel/plugin-transform-nullish-coalescing-operator": "^7.27.1", "@babel/plugin-transform-numeric-separator": "^7.27.1", - "@babel/plugin-transform-object-rest-spread": "^7.28.0", + "@babel/plugin-transform-object-rest-spread": "^7.28.4", "@babel/plugin-transform-object-super": "^7.27.1", "@babel/plugin-transform-optional-catch-binding": "^7.27.1", - "@babel/plugin-transform-optional-chaining": "^7.27.1", + "@babel/plugin-transform-optional-chaining": "^7.28.5", "@babel/plugin-transform-parameters": "^7.27.7", "@babel/plugin-transform-private-methods": "^7.27.1", "@babel/plugin-transform-private-property-in-object": "^7.27.1", "@babel/plugin-transform-property-literals": "^7.27.1", - "@babel/plugin-transform-regenerator": "^7.28.3", + "@babel/plugin-transform-regenerator": "^7.28.4", "@babel/plugin-transform-regexp-modifiers": "^7.27.1", "@babel/plugin-transform-reserved-words": "^7.27.1", "@babel/plugin-transform-shorthand-properties": "^7.27.1", @@ -1770,18 +1770,18 @@ } }, "node_modules/@babel/traverse": { - "version": "7.28.4", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.4.tgz", - "integrity": "sha512-YEzuboP2qvQavAcjgQNVgsvHIDv6ZpwXvcvjmyySP2DIMuByS/6ioU5G9pYrWHM6T2YDfc7xga9iNzYOs12CFQ==", + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.5.tgz", + "integrity": "sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ==", "dev": true, "license": "MIT", "dependencies": { "@babel/code-frame": "^7.27.1", - "@babel/generator": "^7.28.3", + "@babel/generator": "^7.28.5", "@babel/helper-globals": "^7.28.0", - "@babel/parser": "^7.28.4", + "@babel/parser": "^7.28.5", "@babel/template": "^7.27.2", - "@babel/types": "^7.28.4", + "@babel/types": "^7.28.5", "debug": "^4.3.1" }, "engines": { @@ -1789,14 +1789,14 @@ } }, "node_modules/@babel/types": { - "version": "7.28.4", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.4.tgz", - "integrity": "sha512-bkFqkLhh3pMBUQQkpVgWDWq/lqzc2678eUyDlTBhRqhCHFguYYGM0Efga7tYk4TogG/3x0EEl66/OQ+WGbWB/Q==", + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.5.tgz", + "integrity": "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==", "dev": true, "license": "MIT", "dependencies": { "@babel/helper-string-parser": "^7.27.1", - "@babel/helper-validator-identifier": "^7.27.1" + "@babel/helper-validator-identifier": "^7.28.5" }, "engines": { "node": ">=6.9.0" @@ -2493,6 +2493,29 @@ "dev": true, "license": "BSD-3-Clause" }, + "node_modules/@isaacs/balanced-match": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@isaacs/balanced-match/-/balanced-match-4.0.1.tgz", + "integrity": "sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/@isaacs/brace-expansion": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@isaacs/brace-expansion/-/brace-expansion-5.0.0.tgz", + "integrity": "sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@isaacs/balanced-match": "^4.0.1" + }, + "engines": { + "node": "20 || >=22" + } + }, "node_modules/@isaacs/cliui": { "version": "8.0.2", "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", @@ -6065,9 +6088,9 @@ "license": "MIT" }, "node_modules/baseline-browser-mapping": { - "version": "2.8.15", - "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.8.15.tgz", - "integrity": "sha512-qsJ8/X+UypqxHXN75M7dF88jNK37dLBRW7LeUzCPz+TNs37G8cfWy9nWzS+LS//g600zrt2le9KuXt0rWfDz5Q==", + "version": "2.9.5", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.9.5.tgz", + "integrity": "sha512-D5vIoztZOq1XM54LUdttJVc96ggEsIfju2JBvht06pSzpckp3C7HReun67Bghzrtdsq9XdMGbSSB3v3GhMNmAA==", "dev": true, "license": "Apache-2.0", "bin": { @@ -6139,9 +6162,9 @@ } }, "node_modules/browserslist": { - "version": "4.26.3", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.26.3.tgz", - "integrity": "sha512-lAUU+02RFBuCKQPj/P6NgjlbCnLBMp4UtgTx7vNHd3XSIJF87s9a5rA3aH2yw3GS9DqZAUbOtZdCCiZeVRqt0w==", + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.1.tgz", + "integrity": "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==", "dev": true, "funding": [ { @@ -6160,11 +6183,11 @@ "license": "MIT", "peer": true, "dependencies": { - "baseline-browser-mapping": "^2.8.9", - "caniuse-lite": "^1.0.30001746", - "electron-to-chromium": "^1.5.227", - "node-releases": "^2.0.21", - "update-browserslist-db": "^1.1.3" + "baseline-browser-mapping": "^2.9.0", + "caniuse-lite": "^1.0.30001759", + "electron-to-chromium": "^1.5.263", + "node-releases": "^2.0.27", + "update-browserslist-db": "^1.2.0" }, "bin": { "browserslist": "cli.js" @@ -6321,9 +6344,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001749", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001749.tgz", - "integrity": "sha512-0rw2fJOmLfnzCRbkm8EyHL8SvI2Apu5UbnQuTsJ0ClgrH8hcwFooJ1s5R0EP8o8aVrFu8++ae29Kt9/gZAZp/Q==", + "version": "1.0.30001760", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001760.tgz", + "integrity": "sha512-7AAMPcueWELt1p3mi13HR/LHH0TJLT11cnwDJEs3xA4+CK/PLKeO9Kl1oru24htkyUKtkGCvAx4ohB0Ttry8Dw==", "dev": true, "funding": [ { @@ -6661,13 +6684,13 @@ "license": "MIT" }, "node_modules/core-js-compat": { - "version": "3.45.1", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.45.1.tgz", - "integrity": "sha512-tqTt5T4PzsMIZ430XGviK4vzYSoeNJ6CXODi6c/voxOT6IZqBht5/EKaSNnYiEjjRYxjVz7DQIsOsY0XNi8PIA==", + "version": "3.47.0", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.47.0.tgz", + "integrity": "sha512-IGfuznZ/n7Kp9+nypamBhvwdwLsW6KC8IOaURw2doAK5e98AG3acVLdh0woOnEqCfUtS+Vu882JE4k/DAm3ItQ==", "dev": true, "license": "MIT", "dependencies": { - "browserslist": "^4.25.3" + "browserslist": "^4.28.0" }, "funding": { "type": "opencollective", @@ -7384,9 +7407,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.5.233", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.233.tgz", - "integrity": "sha512-iUdTQSf7EFXsDdQsp8MwJz5SVk4APEFqXU/S47OtQ0YLqacSwPXdZ5vRlMX3neb07Cy2vgioNuRnWUXFwuslkg==", + "version": "1.5.267", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.267.tgz", + "integrity": "sha512-0Drusm6MVRXSOJpGbaSVgcQsuB4hEkMpHXaVstcPmhu5LIedxs1xNK/nIxmQIU/RPC0+1/o0AVZfBTkTNJOdUw==", "dev": true, "license": "ISC" }, @@ -12063,9 +12086,9 @@ } }, "node_modules/node-releases": { - "version": "2.0.23", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.23.tgz", - "integrity": "sha512-cCmFDMSm26S6tQSDpBCg/NR8NENrVPhAJSf+XbxBG4rPFaaonlEoE9wHQmun+cls499TQGSb7ZyPBRlzgKfpeg==", + "version": "2.0.27", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.27.tgz", + "integrity": "sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==", "dev": true, "license": "MIT" }, @@ -16279,9 +16302,9 @@ } }, "node_modules/update-browserslist-db": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz", - "integrity": "sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.2.tgz", + "integrity": "sha512-E85pfNzMQ9jpKkA7+TJAi4TJN+tBCuWh5rUcS/sv6cFi+1q9LYDwDI5dpUL0u/73EElyQ8d3TEaeW4sPedBqYA==", "dev": true, "funding": [ { @@ -16501,17 +16524,17 @@ } }, "node_modules/vite-plugin-pwa": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/vite-plugin-pwa/-/vite-plugin-pwa-1.1.0.tgz", - "integrity": "sha512-VsSpdubPzXhHWVINcSx6uHRMpOHVHQcHsef1QgkOlEoaIDAlssFEW88LBq1a59BuokAhsh2kUDJbaX1bZv4Bjw==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/vite-plugin-pwa/-/vite-plugin-pwa-1.2.0.tgz", + "integrity": "sha512-a2xld+SJshT9Lgcv8Ji4+srFJL4k/1bVbd1x06JIkvecpQkwkvCncD1+gSzcdm3s+owWLpMJerG3aN5jupJEVw==", "dev": true, "license": "MIT", "dependencies": { "debug": "^4.3.6", "pretty-bytes": "^6.1.1", "tinyglobby": "^0.2.10", - "workbox-build": "^7.3.0", - "workbox-window": "^7.3.0" + "workbox-build": "^7.4.0", + "workbox-window": "^7.4.0" }, "engines": { "node": ">=16.0.0" @@ -16522,8 +16545,8 @@ "peerDependencies": { "@vite-pwa/assets-generator": "^1.0.0", "vite": "^3.1.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0", - "workbox-build": "^7.3.0", - "workbox-window": "^7.3.0" + "workbox-build": "^7.4.0", + "workbox-window": "^7.4.0" }, "peerDependenciesMeta": { "@vite-pwa/assets-generator": { @@ -16700,6 +16723,13 @@ "integrity": "sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==", "license": "MIT" }, + "node_modules/webidl-conversions": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz", + "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==", + "dev": true, + "license": "BSD-2-Clause" + }, "node_modules/whatwg-mimetype": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-3.0.0.tgz", @@ -16722,13 +16752,6 @@ "webidl-conversions": "^4.0.2" } }, - "node_modules/whatwg-url/node_modules/webidl-conversions": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz", - "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==", - "dev": true, - "license": "BSD-2-Clause" - }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -16862,30 +16885,30 @@ } }, "node_modules/workbox-background-sync": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/workbox-background-sync/-/workbox-background-sync-7.3.0.tgz", - "integrity": "sha512-PCSk3eK7Mxeuyatb22pcSx9dlgWNv3+M8PqPaYDokks8Y5/FX4soaOqj3yhAZr5k6Q5JWTOMYgaJBpbw11G9Eg==", + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/workbox-background-sync/-/workbox-background-sync-7.4.0.tgz", + "integrity": "sha512-8CB9OxKAgKZKyNMwfGZ1XESx89GryWTfI+V5yEj8sHjFH8MFelUwYXEyldEK6M6oKMmn807GoJFUEA1sC4XS9w==", "dev": true, "license": "MIT", "dependencies": { "idb": "^7.0.1", - "workbox-core": "7.3.0" + "workbox-core": "7.4.0" } }, "node_modules/workbox-broadcast-update": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/workbox-broadcast-update/-/workbox-broadcast-update-7.3.0.tgz", - "integrity": "sha512-T9/F5VEdJVhwmrIAE+E/kq5at2OY6+OXXgOWQevnubal6sO92Gjo24v6dCVwQiclAF5NS3hlmsifRrpQzZCdUA==", + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/workbox-broadcast-update/-/workbox-broadcast-update-7.4.0.tgz", + "integrity": "sha512-+eZQwoktlvo62cI0b+QBr40v5XjighxPq3Fzo9AWMiAosmpG5gxRHgTbGGhaJv/q/MFVxwFNGh/UwHZ/8K88lA==", "dev": true, "license": "MIT", "dependencies": { - "workbox-core": "7.3.0" + "workbox-core": "7.4.0" } }, "node_modules/workbox-build": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/workbox-build/-/workbox-build-7.3.0.tgz", - "integrity": "sha512-JGL6vZTPlxnlqZRhR/K/msqg3wKP+m0wfEUVosK7gsYzSgeIxvZLi1ViJJzVL7CEeI8r7rGFV973RiEqkP3lWQ==", + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/workbox-build/-/workbox-build-7.4.0.tgz", + "integrity": "sha512-Ntk1pWb0caOFIvwz/hfgrov/OJ45wPEhI5PbTywQcYjyZiVhT3UrwwUPl6TRYbTm4moaFYithYnl1lvZ8UjxcA==", "dev": true, "license": "MIT", "dependencies": { @@ -16902,33 +16925,33 @@ "common-tags": "^1.8.0", "fast-json-stable-stringify": "^2.1.0", "fs-extra": "^9.0.1", - "glob": "^7.1.6", + "glob": "^11.0.1", "lodash": "^4.17.20", "pretty-bytes": "^5.3.0", - "rollup": "^2.43.1", + "rollup": "^2.79.2", "source-map": "^0.8.0-beta.0", "stringify-object": "^3.3.0", "strip-comments": "^2.0.1", "tempy": "^0.6.0", "upath": "^1.2.0", - "workbox-background-sync": "7.3.0", - "workbox-broadcast-update": "7.3.0", - "workbox-cacheable-response": "7.3.0", - "workbox-core": "7.3.0", - "workbox-expiration": "7.3.0", - "workbox-google-analytics": "7.3.0", - "workbox-navigation-preload": "7.3.0", - "workbox-precaching": "7.3.0", - "workbox-range-requests": "7.3.0", - "workbox-recipes": "7.3.0", - "workbox-routing": "7.3.0", - "workbox-strategies": "7.3.0", - "workbox-streams": "7.3.0", - "workbox-sw": "7.3.0", - "workbox-window": "7.3.0" + "workbox-background-sync": "7.4.0", + "workbox-broadcast-update": "7.4.0", + "workbox-cacheable-response": "7.4.0", + "workbox-core": "7.4.0", + "workbox-expiration": "7.4.0", + "workbox-google-analytics": "7.4.0", + "workbox-navigation-preload": "7.4.0", + "workbox-precaching": "7.4.0", + "workbox-range-requests": "7.4.0", + "workbox-recipes": "7.4.0", + "workbox-routing": "7.4.0", + "workbox-strategies": "7.4.0", + "workbox-streams": "7.4.0", + "workbox-sw": "7.4.0", + "workbox-window": "7.4.0" }, "engines": { - "node": ">=16.0.0" + "node": ">=20.0.0" } }, "node_modules/workbox-build/node_modules/@apideck/better-ajv-errors": { @@ -17080,6 +17103,46 @@ "dev": true, "license": "MIT" }, + "node_modules/workbox-build/node_modules/glob": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-11.1.0.tgz", + "integrity": "sha512-vuNwKSaKiqm7g0THUBu2x7ckSs3XJLXE+2ssL7/MfTGPLLcrJQ/4Uq1CjPTtO5cCIiRxqvN6Twy1qOwhL0Xjcw==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "foreground-child": "^3.3.1", + "jackspeak": "^4.1.1", + "minimatch": "^10.1.1", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^2.0.0" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/workbox-build/node_modules/jackspeak": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-4.1.1.tgz", + "integrity": "sha512-zptv57P3GpL+O0I7VdMJNBZCu+BPHVQUk55Ft8/QCJjTVxrnJHuVuX/0Bl2A6/+2oyR/ZMEuFKwmzqqZ/U5nPQ==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/workbox-build/node_modules/json-schema-traverse": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", @@ -17087,6 +17150,16 @@ "dev": true, "license": "MIT" }, + "node_modules/workbox-build/node_modules/lru-cache": { + "version": "11.2.4", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.4.tgz", + "integrity": "sha512-B5Y16Jr9LB9dHVkh6ZevG+vAbOsNOYCX+sXvFWFu7B3Iz5mijW3zdbMyhsh8ANd2mSWBYdJgnqi+mL7/LrOPYg==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": "20 || >=22" + } + }, "node_modules/workbox-build/node_modules/magic-string": { "version": "0.25.9", "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.9.tgz", @@ -17097,6 +17170,39 @@ "sourcemap-codec": "^1.4.8" } }, + "node_modules/workbox-build/node_modules/minimatch": { + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.1.1.tgz", + "integrity": "sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/brace-expansion": "^5.0.0" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/workbox-build/node_modules/path-scurry": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.1.tgz", + "integrity": "sha512-oWyT4gICAu+kaA7QWk/jvCHWarMKNs6pXOGWKDTr7cw4IGcUbW+PeTfbaQiLGheFRpjo6O9J0PmyMfQPjH71oA==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^11.0.0", + "minipass": "^7.1.2" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/workbox-build/node_modules/picomatch": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", @@ -17142,140 +17248,140 @@ } }, "node_modules/workbox-cacheable-response": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/workbox-cacheable-response/-/workbox-cacheable-response-7.3.0.tgz", - "integrity": "sha512-eAFERIg6J2LuyELhLlmeRcJFa5e16Mj8kL2yCDbhWE+HUun9skRQrGIFVUagqWj4DMaaPSMWfAolM7XZZxNmxA==", + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/workbox-cacheable-response/-/workbox-cacheable-response-7.4.0.tgz", + "integrity": "sha512-0Fb8795zg/x23ISFkAc7lbWes6vbw34DGFIMw31cwuHPgDEC/5EYm6m/ZkylLX0EnEbbOyOCLjKgFS/Z5g0HeQ==", "dev": true, "license": "MIT", "dependencies": { - "workbox-core": "7.3.0" + "workbox-core": "7.4.0" } }, "node_modules/workbox-core": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/workbox-core/-/workbox-core-7.3.0.tgz", - "integrity": "sha512-Z+mYrErfh4t3zi7NVTvOuACB0A/jA3bgxUN3PwtAVHvfEsZxV9Iju580VEETug3zYJRc0Dmii/aixI/Uxj8fmw==", + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/workbox-core/-/workbox-core-7.4.0.tgz", + "integrity": "sha512-6BMfd8tYEnN4baG4emG9U0hdXM4gGuDU3ectXuVHnj71vwxTFI7WOpQJC4siTOlVtGqCUtj0ZQNsrvi6kZZTAQ==", "dev": true, "license": "MIT" }, "node_modules/workbox-expiration": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/workbox-expiration/-/workbox-expiration-7.3.0.tgz", - "integrity": "sha512-lpnSSLp2BM+K6bgFCWc5bS1LR5pAwDWbcKt1iL87/eTSJRdLdAwGQznZE+1czLgn/X05YChsrEegTNxjM067vQ==", + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/workbox-expiration/-/workbox-expiration-7.4.0.tgz", + "integrity": "sha512-V50p4BxYhtA80eOvulu8xVfPBgZbkxJ1Jr8UUn0rvqjGhLDqKNtfrDfjJKnLz2U8fO2xGQJTx/SKXNTzHOjnHw==", "dev": true, "license": "MIT", "dependencies": { "idb": "^7.0.1", - "workbox-core": "7.3.0" + "workbox-core": "7.4.0" } }, "node_modules/workbox-google-analytics": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/workbox-google-analytics/-/workbox-google-analytics-7.3.0.tgz", - "integrity": "sha512-ii/tSfFdhjLHZ2BrYgFNTrb/yk04pw2hasgbM70jpZfLk0vdJAXgaiMAWsoE+wfJDNWoZmBYY0hMVI0v5wWDbg==", + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/workbox-google-analytics/-/workbox-google-analytics-7.4.0.tgz", + "integrity": "sha512-MVPXQslRF6YHkzGoFw1A4GIB8GrKym/A5+jYDUSL+AeJw4ytQGrozYdiZqUW1TPQHW8isBCBtyFJergUXyNoWQ==", "dev": true, "license": "MIT", "dependencies": { - "workbox-background-sync": "7.3.0", - "workbox-core": "7.3.0", - "workbox-routing": "7.3.0", - "workbox-strategies": "7.3.0" + "workbox-background-sync": "7.4.0", + "workbox-core": "7.4.0", + "workbox-routing": "7.4.0", + "workbox-strategies": "7.4.0" } }, "node_modules/workbox-navigation-preload": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/workbox-navigation-preload/-/workbox-navigation-preload-7.3.0.tgz", - "integrity": "sha512-fTJzogmFaTv4bShZ6aA7Bfj4Cewaq5rp30qcxl2iYM45YD79rKIhvzNHiFj1P+u5ZZldroqhASXwwoyusnr2cg==", + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/workbox-navigation-preload/-/workbox-navigation-preload-7.4.0.tgz", + "integrity": "sha512-etzftSgdQfjMcfPgbfaZCfM2QuR1P+4o8uCA2s4rf3chtKTq/Om7g/qvEOcZkG6v7JZOSOxVYQiOu6PbAZgU6w==", "dev": true, "license": "MIT", "dependencies": { - "workbox-core": "7.3.0" + "workbox-core": "7.4.0" } }, "node_modules/workbox-precaching": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/workbox-precaching/-/workbox-precaching-7.3.0.tgz", - "integrity": "sha512-ckp/3t0msgXclVAYaNndAGeAoWQUv7Rwc4fdhWL69CCAb2UHo3Cef0KIUctqfQj1p8h6aGyz3w8Cy3Ihq9OmIw==", + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/workbox-precaching/-/workbox-precaching-7.4.0.tgz", + "integrity": "sha512-VQs37T6jDqf1rTxUJZXRl3yjZMf5JX/vDPhmx2CPgDDKXATzEoqyRqhYnRoxl6Kr0rqaQlp32i9rtG5zTzIlNg==", "dev": true, "license": "MIT", "dependencies": { - "workbox-core": "7.3.0", - "workbox-routing": "7.3.0", - "workbox-strategies": "7.3.0" + "workbox-core": "7.4.0", + "workbox-routing": "7.4.0", + "workbox-strategies": "7.4.0" } }, "node_modules/workbox-range-requests": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/workbox-range-requests/-/workbox-range-requests-7.3.0.tgz", - "integrity": "sha512-EyFmM1KpDzzAouNF3+EWa15yDEenwxoeXu9bgxOEYnFfCxns7eAxA9WSSaVd8kujFFt3eIbShNqa4hLQNFvmVQ==", + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/workbox-range-requests/-/workbox-range-requests-7.4.0.tgz", + "integrity": "sha512-3Vq854ZNuP6Y0KZOQWLaLC9FfM7ZaE+iuQl4VhADXybwzr4z/sMmnLgTeUZLq5PaDlcJBxYXQ3U91V7dwAIfvw==", "dev": true, "license": "MIT", "dependencies": { - "workbox-core": "7.3.0" + "workbox-core": "7.4.0" } }, "node_modules/workbox-recipes": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/workbox-recipes/-/workbox-recipes-7.3.0.tgz", - "integrity": "sha512-BJro/MpuW35I/zjZQBcoxsctgeB+kyb2JAP5EB3EYzePg8wDGoQuUdyYQS+CheTb+GhqJeWmVs3QxLI8EBP1sg==", + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/workbox-recipes/-/workbox-recipes-7.4.0.tgz", + "integrity": "sha512-kOkWvsAn4H8GvAkwfJTbwINdv4voFoiE9hbezgB1sb/0NLyTG4rE7l6LvS8lLk5QIRIto+DjXLuAuG3Vmt3cxQ==", "dev": true, "license": "MIT", "dependencies": { - "workbox-cacheable-response": "7.3.0", - "workbox-core": "7.3.0", - "workbox-expiration": "7.3.0", - "workbox-precaching": "7.3.0", - "workbox-routing": "7.3.0", - "workbox-strategies": "7.3.0" + "workbox-cacheable-response": "7.4.0", + "workbox-core": "7.4.0", + "workbox-expiration": "7.4.0", + "workbox-precaching": "7.4.0", + "workbox-routing": "7.4.0", + "workbox-strategies": "7.4.0" } }, "node_modules/workbox-routing": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/workbox-routing/-/workbox-routing-7.3.0.tgz", - "integrity": "sha512-ZUlysUVn5ZUzMOmQN3bqu+gK98vNfgX/gSTZ127izJg/pMMy4LryAthnYtjuqcjkN4HEAx1mdgxNiKJMZQM76A==", + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/workbox-routing/-/workbox-routing-7.4.0.tgz", + "integrity": "sha512-C/ooj5uBWYAhAqwmU8HYQJdOjjDKBp9MzTQ+otpMmd+q0eF59K+NuXUek34wbL0RFrIXe/KKT+tUWcZcBqxbHQ==", "dev": true, "license": "MIT", "dependencies": { - "workbox-core": "7.3.0" + "workbox-core": "7.4.0" } }, "node_modules/workbox-strategies": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/workbox-strategies/-/workbox-strategies-7.3.0.tgz", - "integrity": "sha512-tmZydug+qzDFATwX7QiEL5Hdf7FrkhjaF9db1CbB39sDmEZJg3l9ayDvPxy8Y18C3Y66Nrr9kkN1f/RlkDgllg==", + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/workbox-strategies/-/workbox-strategies-7.4.0.tgz", + "integrity": "sha512-T4hVqIi5A4mHi92+5EppMX3cLaVywDp8nsyUgJhOZxcfSV/eQofcOA6/EMo5rnTNmNTpw0rUgjAI6LaVullPpg==", "dev": true, "license": "MIT", "dependencies": { - "workbox-core": "7.3.0" + "workbox-core": "7.4.0" } }, "node_modules/workbox-streams": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/workbox-streams/-/workbox-streams-7.3.0.tgz", - "integrity": "sha512-SZnXucyg8x2Y61VGtDjKPO5EgPUG5NDn/v86WYHX+9ZqvAsGOytP0Jxp1bl663YUuMoXSAtsGLL+byHzEuMRpw==", + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/workbox-streams/-/workbox-streams-7.4.0.tgz", + "integrity": "sha512-QHPBQrey7hQbnTs5GrEVoWz7RhHJXnPT+12qqWM378orDMo5VMJLCkCM1cnCk+8Eq92lccx/VgRZ7WAzZWbSLg==", "dev": true, "license": "MIT", "dependencies": { - "workbox-core": "7.3.0", - "workbox-routing": "7.3.0" + "workbox-core": "7.4.0", + "workbox-routing": "7.4.0" } }, "node_modules/workbox-sw": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/workbox-sw/-/workbox-sw-7.3.0.tgz", - "integrity": "sha512-aCUyoAZU9IZtH05mn0ACUpyHzPs0lMeJimAYkQkBsOWiqaJLgusfDCR+yllkPkFRxWpZKF8vSvgHYeG7LwhlmA==", + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/workbox-sw/-/workbox-sw-7.4.0.tgz", + "integrity": "sha512-ltU+Kr3qWR6BtbdlMnCjobZKzeV1hN+S6UvDywBrwM19TTyqA03X66dzw1tEIdJvQ4lYKkBFox6IAEhoSEZ8Xw==", "dev": true, "license": "MIT" }, "node_modules/workbox-window": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/workbox-window/-/workbox-window-7.3.0.tgz", - "integrity": "sha512-qW8PDy16OV1UBaUNGlTVcepzrlzyzNW/ZJvFQQs2j2TzGsg6IKjcpZC1RSquqQnTOafl5pCj5bGfAHlCjOOjdA==", + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/workbox-window/-/workbox-window-7.4.0.tgz", + "integrity": "sha512-/bIYdBLAVsNR3v7gYGaV4pQW3M3kEPx5E8vDxGvxo6khTrGtSSCS7QiFKv9ogzBgZiy0OXLP9zO28U/1nF1mfw==", "dev": true, "license": "MIT", "dependencies": { "@types/trusted-types": "^2.0.2", - "workbox-core": "7.3.0" + "workbox-core": "7.4.0" } }, "node_modules/wrap-ansi": { From ecea9dc4ad903ca7d02f9644913e8595178fd732 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 10 Dec 2025 10:16:30 +0000 Subject: [PATCH 07/22] build(deps-dev): bump @types/node from 24.10.1 to 24.10.2 (#612) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- app/package.json | 2 +- package-lock.json | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/app/package.json b/app/package.json index c366d524..a7fbb136 100644 --- a/app/package.json +++ b/app/package.json @@ -27,7 +27,7 @@ }, "devDependencies": { "@eslint-community/eslint-plugin-eslint-comments": "^4.4.1", - "@types/node": "^24.10.1", + "@types/node": "^24.10.2", "@types/react": "^18.2.79", "@types/react-dom": "^18.2.25", "@typescript-eslint/eslint-plugin": "^5.62.0", diff --git a/package-lock.json b/package-lock.json index dda7454b..506a36fe 100644 --- a/package-lock.json +++ b/package-lock.json @@ -28,7 +28,7 @@ }, "devDependencies": { "@eslint-community/eslint-plugin-eslint-comments": "^4.4.1", - "@types/node": "^24.10.1", + "@types/node": "^24.10.2", "@types/react": "^18.2.79", "@types/react-dom": "^18.2.25", "@typescript-eslint/eslint-plugin": "^5.62.0", @@ -4739,9 +4739,9 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "24.10.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-24.10.1.tgz", - "integrity": "sha512-GNWcUTRBgIRJD5zj+Tq0fKOJ5XZajIiBroOF0yvj2bSU1WvNdYS/dn9UxwsujGW4JX06dnHyjV2y9rRaybH0iQ==", + "version": "24.10.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-24.10.2.tgz", + "integrity": "sha512-WOhQTZ4G8xZ1tjJTvKOpyEVSGgOTvJAfDK3FNFgELyaTpzhdgHVHeqW8V+UJvzF5BT+/B54T/1S2K6gd9c7bbA==", "devOptional": true, "license": "MIT", "dependencies": { From e2721a141a764af674ac1e44652b5f0896e7709c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 10 Dec 2025 10:28:15 +0000 Subject: [PATCH 08/22] build(deps-dev): bump rollup-plugin-dts from 6.2.3 to 6.3.0 (#606) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: mahula --- lib/package.json | 2 +- package-lock.json | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/package.json b/lib/package.json index 910aa8ed..888159af 100644 --- a/lib/package.json +++ b/lib/package.json @@ -83,7 +83,7 @@ "react": "^18.3.1", "react-dom": "^18.3.1", "rollup": "^4.53.3", - "rollup-plugin-dts": "^6.1.1", + "rollup-plugin-dts": "^6.3.0", "rollup-plugin-postcss": "^4.0.2", "rollup-plugin-svg": "^2.0.0", "tailwindcss": "^4.1.17", diff --git a/package-lock.json b/package-lock.json index 506a36fe..a9dc82c3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -140,7 +140,7 @@ "react": "^18.3.1", "react-dom": "^18.3.1", "rollup": "^4.53.3", - "rollup-plugin-dts": "^6.1.1", + "rollup-plugin-dts": "^6.3.0", "rollup-plugin-postcss": "^4.0.2", "rollup-plugin-svg": "^2.0.0", "tailwindcss": "^4.1.17", @@ -14332,13 +14332,13 @@ } }, "node_modules/rollup-plugin-dts": { - "version": "6.2.3", - "resolved": "https://registry.npmjs.org/rollup-plugin-dts/-/rollup-plugin-dts-6.2.3.tgz", - "integrity": "sha512-UgnEsfciXSPpASuOelix7m4DrmyQgiaWBnvI0TM4GxuDh5FkqW8E5hu57bCxXB90VvR1WNfLV80yEDN18UogSA==", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/rollup-plugin-dts/-/rollup-plugin-dts-6.3.0.tgz", + "integrity": "sha512-d0UrqxYd8KyZ6i3M2Nx7WOMy708qsV/7fTHMHxCMCBOAe3V/U7OMPu5GkX8hC+cmkHhzGnfeYongl1IgiooddA==", "dev": true, "license": "LGPL-3.0-only", "dependencies": { - "magic-string": "^0.30.17" + "magic-string": "^0.30.21" }, "engines": { "node": ">=16" From a4d8bbeae88980b2847471dc5523d511b597dd65 Mon Sep 17 00:00:00 2001 From: Anton Tranelis <31516529+antontranelis@users.noreply.github.com> Date: Tue, 16 Dec 2025 20:20:30 +0100 Subject: [PATCH 09/22] fix(lib): fix tiptap crash in firefox (#608) --- lib/src/Components/Input/TextEditorMenu.tsx | 22 ++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/lib/src/Components/Input/TextEditorMenu.tsx b/lib/src/Components/Input/TextEditorMenu.tsx index 6bf6184e..8642cdae 100644 --- a/lib/src/Components/Input/TextEditorMenu.tsx +++ b/lib/src/Components/Input/TextEditorMenu.tsx @@ -16,14 +16,14 @@ export const TextEditorMenu = ({ editor }: { editor: Editor }) => { selector: (ctx) => { return { isBold: ctx.editor.isActive('bold'), - canBold: ctx.editor.can().chain().focus().toggleBold().run(), + canBold: ctx.editor.can().toggleBold(), isItalic: ctx.editor.isActive('italic'), - canItalic: ctx.editor.can().chain().focus().toggleItalic().run(), + canItalic: ctx.editor.can().toggleItalic(), isStrike: ctx.editor.isActive('strike'), - canStrike: ctx.editor.can().chain().focus().toggleStrike().run(), + canStrike: ctx.editor.can().toggleStrike(), isCode: ctx.editor.isActive('code'), - canCode: ctx.editor.can().chain().focus().toggleCode().run(), - canClearMarks: ctx.editor.can().chain().focus().unsetAllMarks().run(), + canCode: ctx.editor.can().toggleCode(), + canClearMarks: ctx.editor.can().unsetAllMarks(), isParagraph: ctx.editor.isActive('paragraph'), isHeading1: ctx.editor.isActive('heading', { level: 1 }), isHeading2: ctx.editor.isActive('heading', { level: 2 }), @@ -36,8 +36,8 @@ export const TextEditorMenu = ({ editor }: { editor: Editor }) => { isOrderedList: ctx.editor.isActive('orderedList'), isCodeBlock: ctx.editor.isActive('codeBlock'), isBlockquote: ctx.editor.isActive('blockquote'), - canUndo: ctx.editor.can().chain().focus().undo().run(), - canRedo: ctx.editor.can().chain().focus().redo().run(), + canUndo: ctx.editor.can().undo(), + canRedo: ctx.editor.can().redo(), } }, }) @@ -77,7 +77,7 @@ export const TextEditorMenu = ({ editor }: { editor: Editor }) => {
  • -
    +
  • {
  • -
    +
  • {
  • -
    +
  • {/*
  • @@ -135,7 +135,7 @@ export const TextEditorMenu = ({ editor }: { editor: Editor }) => {
  • -
    +
  • Date: Tue, 16 Dec 2025 21:12:08 +0100 Subject: [PATCH 10/22] fix(other): improve e2e test reliability with API mocking and race condition fixes (#621) --- .gitignore | 1 + backend/prepare-seed.js | 99 +++++++++++++++++++++++++++ backend/seed.sh | 3 + cypress/e2e/search/search-flows.cy.ts | 2 +- cypress/support/commands.ts | 6 ++ cypress/support/e2e.ts | 65 ++++++++++++++++++ 6 files changed, 175 insertions(+), 1 deletion(-) create mode 100644 backend/prepare-seed.js diff --git a/.gitignore b/.gitignore index 040520f3..10379bdf 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,4 @@ cypress/node_modules/ cypress/results/ cypress/runner-results/ cypress/screenshots/ + diff --git a/backend/prepare-seed.js b/backend/prepare-seed.js new file mode 100644 index 00000000..94f025df --- /dev/null +++ b/backend/prepare-seed.js @@ -0,0 +1,99 @@ +#!/usr/bin/env node + +/** + * Prepares seed data by updating event dates relative to the current date. + * + * This script modifies items.json in-place, updating all items with + * layer "layer-events" to have realistic start/end dates that ensure + * events are visible in the app (end dates in the future). + * + * Date strategy: + * - Event 1 (item-event-1): Long-running, started 30 days ago, ends in 365 days + * - Event 2 (item-event-2): Upcoming single-day event in 7 days + * - Event 3 (item-event-3): Ongoing event, started yesterday, ends tomorrow + * - Event 4 (item-event-4): Upcoming multi-day conference in 30 days + */ + +const fs = require('fs') +const path = require('path') + +const seedPath = path.join(__dirname, 'directus-config/development/seed/items.json') + +function addDays(date, days) { + const result = new Date(date) + result.setDate(result.getDate() + days) + return result +} + +function addHours(date, hours) { + const result = new Date(date) + result.setHours(result.getHours() + hours) + return result +} + +function formatDateTime(date) { + return date.toISOString().slice(0, 19) +} + +/** + * Calculate dynamic dates for each event based on current time + */ +function getEventDates(syncId, now) { + const dateConfigs = { + // "Some Event" - long-running, started in past, ends far in future + 'item-event-1': { + start: addDays(now, -30), + end: addDays(now, 365) + }, + // "Tech Meetup Munich" - upcoming single-day event (the one used in search tests) + 'item-event-2': { + start: addHours(addDays(now, 7), 18), + end: addHours(addDays(now, 7), 21) + }, + // "Sustainability Workshop NYC" - ongoing event (started yesterday, ends tomorrow) + 'item-event-3': { + start: addHours(addDays(now, -1), 14), + end: addHours(addDays(now, 1), 17) + }, + // "Open Source Conference" - upcoming multi-day conference + 'item-event-4': { + start: addHours(addDays(now, 30), 9), + end: addHours(addDays(now, 32), 18) + } + } + + return dateConfigs[syncId] || null +} + +function prepareSeedData() { + // Read the current items.json + const content = fs.readFileSync(seedPath, 'utf8') + const seedData = JSON.parse(content) + + const now = new Date() + let updatedCount = 0 + + // Update event items with dynamic dates + for (const item of seedData.data) { + if (item.layer === 'layer-events' && item._sync_id) { + const dates = getEventDates(item._sync_id, now) + if (dates) { + item.start = formatDateTime(dates.start) + item.end = formatDateTime(dates.end) + console.log(` ${item._sync_id} (${item.name}):`) + console.log(` start: ${item.start}`) + console.log(` end: ${item.end}`) + updatedCount++ + } + } + } + + // Write back to items.json + fs.writeFileSync(seedPath, JSON.stringify(seedData, null, 4)) + + console.log(`\nUpdated ${updatedCount} event(s) with dynamic dates.`) +} + +console.log('Preparing seed data with dynamic dates...\n') +prepareSeedData() + diff --git a/backend/seed.sh b/backend/seed.sh index b62384f6..52811ed7 100755 --- a/backend/seed.sh +++ b/backend/seed.sh @@ -15,6 +15,9 @@ PGDATABASE="${PGDATABASE:-'directus'}" PROJECT_NAME="${PROJECT:-development}" PROJECT_FOLDER=$SCRIPT_DIR/directus-config/$PROJECT_NAME +echo "Preparing seed data with dynamic dates" +node $SCRIPT_DIR/prepare-seed.js || exit 1 + echo "Seed data" npx directus-sync@3.4.0 seed push \ --seed-path $PROJECT_FOLDER/seed \ diff --git a/cypress/e2e/search/search-flows.cy.ts b/cypress/e2e/search/search-flows.cy.ts index 9b24b84e..fc16a276 100644 --- a/cypress/e2e/search/search-flows.cy.ts +++ b/cypress/e2e/search/search-flows.cy.ts @@ -74,7 +74,7 @@ describe('Utopia Map Search', () => { cy.contains('Wat Arun').first().click() }) - cy.get('.leaflet-popup').should('be.visible') + cy.get('.leaflet-popup', { timeout: 15000 }).should('exist') cy.get('.leaflet-popup-content').should('contain', 'Wat Arun') }) diff --git a/cypress/support/commands.ts b/cypress/support/commands.ts index 72832e81..10d7bd52 100644 --- a/cypress/support/commands.ts +++ b/cypress/support/commands.ts @@ -76,6 +76,12 @@ Cypress.Commands.add('searchFor', (query: string) => { Cypress.Commands.add('waitForMapReady', () => { cy.get('[data-cy="search-input"]', { timeout: 10000 }).should('be.visible') cy.get('.leaflet-container', { timeout: 10000 }).should('be.visible') + cy.wait('@getLayers', { timeout: 15000 }).then((interception) => { + const layerCount = interception.response?.body?.data?.length || 3 + for (let i = 0; i < layerCount; i++) { + cy.wait('@getLayerItems', { timeout: 15000 }) + } + }) cy.get('.leaflet-marker-icon', { timeout: 15000 }).should('have.length.at.least', 1) }) diff --git a/cypress/support/e2e.ts b/cypress/support/e2e.ts index fc990283..cafcadf7 100644 --- a/cypress/support/e2e.ts +++ b/cypress/support/e2e.ts @@ -5,6 +5,71 @@ import './commands' // for screenshot embedding import addContext from 'mochawesome/addContext' +const photonMockData: Record = { + berlin: { + type: 'FeatureCollection', + features: [ + { + type: 'Feature', + properties: { + osm_type: 'R', + osm_id: 62422, + osm_key: 'place', + osm_value: 'city', + type: 'city', + countrycode: 'DE', + name: 'Berlin', + country: 'Germany', + state: 'Berlin', + extent: [13.088345, 52.6755087, 13.7611609, 52.3382448], + }, + geometry: { type: 'Point', coordinates: [13.3951309, 52.5173885] }, + }, + ], + }, + 'wat arun': { + type: 'FeatureCollection', + features: [ + { + type: 'Feature', + properties: { + osm_type: 'W', + osm_id: 25867629, + osm_key: 'tourism', + osm_value: 'attraction', + type: 'attraction', + countrycode: 'TH', + name: 'Wat Arun', + country: 'Thailand', + city: 'Bangkok', + extent: [100.4882, 13.7437, 100.4912, 13.7407], + }, + geometry: { type: 'Point', coordinates: [100.4897, 13.7437] }, + }, + ], + }, +} + +beforeEach(() => { + cy.intercept('GET', 'https://photon.komoot.io/api/*', (req) => { + const url = new URL(req.url) + const query = (url.searchParams.get('q') || '').toLowerCase() + + const mockKey = Object.keys(photonMockData).find((key) => + query.includes(key.toLowerCase()), + ) + + if (mockKey) { + req.reply(photonMockData[mockKey]) + } else { + req.reply({ type: 'FeatureCollection', features: [] }) + } + }).as('photonApi') + + cy.intercept('GET', '**/items/layers*').as('getLayers') + cy.intercept('GET', '**/items/items*').as('getLayerItems') +}) + // Global exception handler Cypress.on('uncaught:exception', (err) => { // eslint-disable-next-line no-console From 279110f011d58844444637639432bac3f9d93725 Mon Sep 17 00:00:00 2001 From: mahula Date: Tue, 16 Dec 2025 21:21:28 +0100 Subject: [PATCH 11/22] refactor(other): update eslint to v9 with the flat configuration (#405) --- .gitignore | 2 + app/.eslintignore | 3 - app/.eslintrc.cjs | 223 -- app/.prettierrc.json | 2 +- app/eslint.config.js | 260 +++ app/package.json | 21 +- app/src/App.tsx | 4 +- app/src/ModalContent.tsx | 9 +- app/src/api/directus.ts | 7 +- app/src/api/inviteApi.ts | 1 - app/src/api/itemsApi.ts | 8 +- app/src/api/layersApi.ts | 1 + app/src/api/permissionsApi.ts | 1 - app/src/api/refiBcnApi.ts | 2 +- app/src/api/userApi.ts | 10 +- app/src/main.tsx | 3 +- app/src/pages/Landingpage.tsx | 2 +- app/src/pages/MapContainer.tsx | 4 +- app/src/pages/data.ts | 1 + app/tsconfig.json | 36 +- lib/.eslintignore | 5 - lib/.eslintrc.cjs | 221 -- lib/.prettierrc.json | 2 +- lib/cypress/support/component.ts | 2 +- lib/eslint.config.js | 260 +++ lib/package.json | 14 +- lib/postcss.config.cjs | 2 +- lib/setupTest.ts | 2 +- lib/src/Components/AppShell/NavBar.tsx | 8 +- lib/src/Components/AppShell/SideBar.tsx | 14 +- .../Components/AppShell/SidebarSubmenu.tsx | 10 +- .../Components/AppShell/hooks/useAppState.tsx | 1 - lib/src/Components/Auth/LoginPage.tsx | 11 +- .../Components/Auth/RequestPasswordPage.tsx | 6 +- .../Components/Auth/SetNewPasswordPage.tsx | 6 +- lib/src/Components/Auth/SignupPage.tsx | 15 +- lib/src/Components/Auth/useAuth.tsx | 8 +- lib/src/Components/Gaming/Quests.tsx | 4 +- lib/src/Components/Gaming/hooks/useQuests.tsx | 1 - lib/src/Components/Input/Autocomplete.tsx | 11 +- lib/src/Components/Item/PopupView.tsx | 2 + .../Map/Subcomponents/AddButton.tsx | 5 +- .../Subcomponents/Controls/FilterControl.tsx | 9 +- .../Subcomponents/Controls/LayerControl.tsx | 4 +- .../Controls/LocateControl.spec.tsx | 1 + .../Subcomponents/Controls/LocateControl.tsx | 14 +- .../Subcomponents/Controls/QuestControl.tsx | 8 +- .../Subcomponents/Controls/SearchControl.tsx | 9 +- .../Subcomponents/Controls/SidebarControl.tsx | 4 +- .../Subcomponents/Controls/TagsControl.tsx | 4 +- .../Map/Subcomponents/ItemFormPopup.tsx | 4 +- .../HeaderView/ConnectionStatus.tsx | 3 +- .../HeaderView/DeleteModal.tsx | 6 +- .../HeaderView/EditMenu.tsx | 11 +- .../HeaderView/ItemAvatar.tsx | 9 +- .../HeaderView/ItemTitle.tsx | 1 + .../HeaderView/QRModal.tsx | 7 +- .../ItemPopupComponents/HeaderView/hooks.ts | 1 + .../ItemPopupComponents/HeaderView/index.tsx | 20 +- .../ItemPopupComponents/HeaderView/types.ts | 2 +- .../ItemPopupComponents/PopupButton.tsx | 3 + .../PopupTextAreaInput.tsx | 1 + .../ItemPopupComponents/PopupTextInput.tsx | 1 + .../Map/Subcomponents/ItemViewPopup.tsx | 4 +- .../Map/Subcomponents/MapLibreLayer.tsx | 2 +- .../Map/Subcomponents/SelectPositionToast.tsx | 4 +- lib/src/Components/Map/UtopiaMapInner.tsx | 13 +- .../Components/Map/hooks/useClusterRef.tsx | 1 - lib/src/Components/Map/hooks/useFilter.tsx | 14 +- lib/src/Components/Map/hooks/useItems.tsx | 1 - lib/src/Components/Map/hooks/useLayers.tsx | 2 +- .../Components/Map/hooks/useLeafletRefs.tsx | 3 +- .../Components/Map/hooks/usePermissions.tsx | 2 +- .../Components/Map/hooks/useReverseGeocode.ts | 1 + .../Map/hooks/useSelectPosition.tsx | 2 +- lib/src/Components/Map/hooks/useTags.tsx | 1 - .../Map/hooks/useWindowDimension.tsx | 4 +- .../Components/Profile/ItemFunctions.spec.tsx | 13 +- lib/src/Components/Profile/ProfileForm.tsx | 2 + lib/src/Components/Profile/ProfileView.tsx | 6 +- .../Profile/Subcomponents/ActionsButton.tsx | 5 +- .../Profile/Subcomponents/AvatarWidget.tsx | 9 +- .../Profile/Subcomponents/ColorPicker.tsx | 21 +- .../Profile/Subcomponents/ContactInfoForm.tsx | 8 +- .../Subcomponents/CrowdfundingForm.tsx | 4 +- .../Profile/Subcomponents/FormHeader.tsx | 17 +- .../Subcomponents/GalleryForm.spec.tsx | 2 + .../Profile/Subcomponents/GalleryForm.tsx | 19 +- .../Profile/Subcomponents/GalleryView.tsx | 13 +- .../Subcomponents/GroupSubheaderForm.tsx | 9 +- .../Subcomponents/LinkedItemsHeaderView.tsx | 9 +- .../Profile/Subcomponents/MarkdownHint.tsx | 4 +- .../Subcomponents/ProfileStartEndForm.tsx | 8 +- .../Profile/Subcomponents/ProfileTextForm.tsx | 4 +- .../Profile/Subcomponents/SocialShareBar.tsx | 9 +- .../Profile/Subcomponents/TagsWidget.tsx | 9 +- .../Profile/Templates/OnepagerForm.tsx | 4 +- .../Profile/Templates/SimpleForm.tsx | 1 + .../Components/Profile/Templates/TabsForm.tsx | 5 +- .../Components/Profile/Templates/TabsView.tsx | 44 +- lib/src/Components/Profile/UserSettings.tsx | 15 +- lib/src/Components/Profile/itemFunctions.ts | 2 + .../Components/Templates/AttestationForm.tsx | 10 +- lib/src/Components/Templates/DateUserInfo.tsx | 12 +- lib/src/Components/Templates/DialogModal.tsx | 8 +- lib/src/Components/Templates/EmojiPicker.tsx | 12 +- lib/src/Components/Templates/ItemCard.tsx | 12 +- .../Components/Templates/MapOverlayPage.tsx | 4 +- lib/src/Components/Templates/MarketView.tsx | 9 +- .../Templates/OverlayItemsIndexPage.tsx | 5 +- lib/src/Components/Templates/SelectUser.tsx | 4 +- lib/src/Components/Templates/Tabs.tsx | 5 +- lib/src/Components/Templates/ThemeControl.tsx | 4 +- lib/src/Utils/MarkerIconFactory.ts | 3 +- lib/src/Utils/ReplaceURLs.ts | 2 +- lib/src/Utils/ReverseGeocoder.ts | 1 + lib/src/Utils/TimeAgo.ts | 1 + lib/src/Utils/getImageDimensions.ts | 5 +- lib/src/index.tsx | 2 +- lib/src/types/FormState.d.ts | 1 + lib/tsconfig.json | 62 +- package-lock.json | 1924 +++++++++++------ 122 files changed, 2337 insertions(+), 1377 deletions(-) delete mode 100644 app/.eslintignore delete mode 100644 app/.eslintrc.cjs create mode 100644 app/eslint.config.js delete mode 100644 lib/.eslintignore delete mode 100644 lib/.eslintrc.cjs create mode 100644 lib/eslint.config.js diff --git a/.gitignore b/.gitignore index 10379bdf..5a4915fb 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,6 @@ .claude/ +app/node_modules/ +lib/node_modules/ data/ node_modules/ cypress/node_modules/ diff --git a/app/.eslintignore b/app/.eslintignore deleted file mode 100644 index 2f3546e5..00000000 --- a/app/.eslintignore +++ /dev/null @@ -1,3 +0,0 @@ -node_modules/ -dist/ -data/ \ No newline at end of file diff --git a/app/.eslintrc.cjs b/app/.eslintrc.cjs deleted file mode 100644 index af43f19b..00000000 --- a/app/.eslintrc.cjs +++ /dev/null @@ -1,223 +0,0 @@ -// eslint-disable-next-line import/no-commonjs -module.exports = { - env: { - browser: true, - es2021: true, - }, - extends: [ - 'standard', - 'eslint:recommended', - 'plugin:@eslint-community/eslint-comments/recommended', - 'plugin:@typescript-eslint/recommended', - 'plugin:import/recommended', - 'plugin:import/typescript', - // 'plugin:promise/recommended', - 'plugin:security/recommended-legacy', - 'plugin:react/recommended', - ], - parserOptions: { - ecmaVersion: 'latest', - parser: '@typescript-eslint/parser', - sourceType: 'module', - }, - plugins: [ - '@typescript-eslint', - 'import', - 'promise', - 'security', - 'no-catch-all', - 'react', - 'react-hooks', - 'react-refresh', - ], - // TODO also parse this - ignorePatterns: ['vite.config.ts'], - settings: { - 'import/resolver': { - typescript: true, - node: { - extensions: ['.js', '.jsx', '.ts', '.tsx'], - }, - }, - react: { - version: '18.2.0', - }, - }, - rules: { - 'react-hooks/rules-of-hooks': 'error', // Checks rules of Hooks - 'react-hooks/exhaustive-deps': 'warn', // Checks effect dependencies - 'react/react-in-jsx-scope': 'off', // Disable requirement for React import - 'no-catch-all/no-catch-all': 'error', - 'no-console': 'error', - 'no-debugger': 'error', - camelcase: 'error', - indent: ['error', 2], - 'linebreak-style': ['error', 'unix'], - semi: ['error', 'never'], - // Optional eslint-comments rule - '@eslint-community/eslint-comments/no-unused-disable': 'error', - '@eslint-community/eslint-comments/disable-enable-pair': ['error', { allowWholeFile: true }], - // import - 'import/export': 'error', - 'import/no-deprecated': 'error', - 'import/no-empty-named-blocks': 'error', - 'import/no-extraneous-dependencies': 'error', - 'import/no-mutable-exports': 'error', - 'import/no-unused-modules': 'error', - 'import/no-named-as-default': 'error', - 'import/no-named-as-default-member': 'error', - 'import/no-amd': 'error', - 'import/no-commonjs': 'error', - 'import/no-import-module-exports': 'error', - 'import/no-nodejs-modules': 'off', - 'import/unambiguous': 'off', // not compatible with scriptless vue files - 'import/default': 'error', - 'import/named': 'error', - 'import/namespace': 'error', - 'import/no-absolute-path': 'error', - 'import/no-cycle': 'error', - 'import/no-dynamic-require': 'error', - 'import/no-internal-modules': 'off', - 'import/no-relative-packages': 'error', - 'import/no-relative-parent-imports': [ - 'error', - { - ignore: ['#[src,types,root,components,utils,assets]/*', '@/config/*'], - }, - ], - 'import/no-self-import': 'error', - 'import/no-unresolved': [ - 'error', - { - ignore: ['react'], - }, - ], - 'import/no-useless-path-segments': 'error', - 'import/no-webpack-loader-syntax': 'error', - 'import/consistent-type-specifier-style': 'error', - 'import/exports-last': 'off', - 'import/extensions': [ - 'error', - 'never', - { - json: 'always', - }, - ], - 'import/first': 'error', - 'import/group-exports': 'off', - 'import/newline-after-import': 'error', - 'import/no-anonymous-default-export': 'off', // todo - consider to enable again - 'import/no-default-export': 'off', // incompatible with vite & vike - 'import/no-duplicates': 'error', - 'import/no-named-default': 'error', - 'import/no-namespace': 'error', - 'import/no-unassigned-import': [ - 'error', - { - allow: ['**/*.css'], - }, - ], - 'import/order': [ - 'error', - { - groups: ['builtin', 'external', 'internal', 'parent', 'sibling', 'index', 'object', 'type'], - 'newlines-between': 'always', - alphabetize: { - order: 'asc', // sort in ascending order. Options: ["ignore", "asc", "desc"] - caseInsensitive: true, // ignore case. Options: [true, false] - }, - distinctGroup: true, - }, - ], - 'import/prefer-default-export': 'off', - // promise - 'promise/catch-or-return': 'error', - 'promise/no-return-wrap': 'error', - 'promise/param-names': 'error', - 'promise/always-return': 'error', - 'promise/no-native': 'off', - 'promise/no-nesting': 'warn', - 'promise/no-promise-in-callback': 'warn', - 'promise/no-callback-in-promise': 'warn', - 'promise/avoid-new': 'warn', - 'promise/no-new-statics': 'error', - 'promise/no-return-in-finally': 'warn', - 'promise/valid-params': 'warn', - 'promise/prefer-await-to-callbacks': 'error', - 'promise/no-multiple-resolved': 'error', - }, - overrides: [ - { - files: ['*.ts', '*.tsx'], - parser: '@typescript-eslint/parser', - parserOptions: { - tsconfigRootDir: __dirname, - project: ['./tsconfig.json', '**/tsconfig.json'], - ecmaVersion: 'latest', - parser: '@typescript-eslint/parser', - sourceType: 'module', - }, - plugins: ['@typescript-eslint'], - extends: [ - 'plugin:@typescript-eslint/recommended', - 'plugin:@typescript-eslint/recommended-requiring-type-checking', - 'plugin:@typescript-eslint/strict', - ], - rules: { - '@typescript-eslint/consistent-type-imports': 'error', - // allow explicitly defined dangling promises - '@typescript-eslint/no-floating-promises': ['error', { ignoreVoid: true }], - 'no-void': ['error', { allowAsStatement: true }], - }, - }, - { - files: ['!*.json'], - plugins: ['prettier'], - extends: ['plugin:prettier/recommended'], - rules: { - 'prettier/prettier': 'error', - }, - }, - { - files: ['*.json'], - plugins: ['json'], - extends: ['plugin:json/recommended-with-comments'], - }, - // { - // files: ['*.{test,spec}.[tj]s'], - // plugins: ['vitest'], - // extends: ['plugin:vitest/all'], - // rules: { - // 'vitest/prefer-lowercase-title': 'off', - // 'vitest/no-hooks': 'off', - // 'vitest/consistent-test-filename': 'off', - // 'vitest/prefer-expect-assertions': [ - // 'off', - // { - // onlyFunctionsWithExpectInLoop: true, - // onlyFunctionsWithExpectInCallback: true, - // }, - // ], - // 'vitest/prefer-strict-equal': 'off', - // 'vitest/prefer-to-be-falsy': 'off', - // 'vitest/prefer-to-be-truthy': 'off', - // 'vitest/require-hook': [ - // 'error', - // { - // allowedFunctionCalls: [ - // 'mockClient.setRequestHandler', - // 'setActivePinia', - // 'provideApolloClient', - // ], - // }, - // ], - // }, - // }, - { - files: ['*.yaml', '*.yml'], - parser: 'yaml-eslint-parser', - plugins: ['yml'], - extends: ['plugin:yml/prettier'], - }, - ], -} diff --git a/app/.prettierrc.json b/app/.prettierrc.json index 1db2a8cf..72e17590 100644 --- a/app/.prettierrc.json +++ b/app/.prettierrc.json @@ -11,4 +11,4 @@ "bracketSameLine": false, "arrowParens": "always", "endOfLine": "auto" -} \ No newline at end of file +} diff --git a/app/eslint.config.js b/app/eslint.config.js new file mode 100644 index 00000000..805ec2df --- /dev/null +++ b/app/eslint.config.js @@ -0,0 +1,260 @@ +// ESLint v9 flat config for Utopia Map App +import js from '@eslint/js' +import eslintCommentsConfigs from '@eslint-community/eslint-plugin-eslint-comments/configs' +import importXPlugin from 'eslint-plugin-import-x' +import jsonPlugin from 'eslint-plugin-json' +import noCatchAllPlugin from 'eslint-plugin-no-catch-all' +import eslintPluginPrettierRecommended from 'eslint-plugin-prettier/recommended' +import promisePlugin from 'eslint-plugin-promise' +import react from 'eslint-plugin-react' +import reactHooks from 'eslint-plugin-react-hooks' +import reactRefresh from 'eslint-plugin-react-refresh' +import securityPlugin from 'eslint-plugin-security' +import globals from 'globals' +import tseslint from 'typescript-eslint' + +export default tseslint.config( + // Ignore patterns + { + ignores: ['dist/**', 'node_modules/**', 'data/**', 'vite.config.ts'], + }, + + // Report unused eslint-disable directives (catches stale comments after rule renames) + { + linterOptions: { + reportUnusedDisableDirectives: 'error', + }, + }, + + // Base ESLint recommended config + js.configs.recommended, + + // ESLint comments recommended config + eslintCommentsConfigs.recommended, + + // Security recommended config + securityPlugin.configs.recommended, + + // React recommended configs + react.configs.flat.recommended, + react.configs.flat['jsx-runtime'], + + // Main configuration for JavaScript/TypeScript files + { + files: ['**/*.{js,jsx,ts,tsx,cjs,mjs}'], + languageOptions: { + ecmaVersion: 'latest', + sourceType: 'module', + globals: { + ...globals.browser, + ...globals.es2021, + }, + parserOptions: { + ecmaFeatures: { + jsx: true, + }, + }, + }, + plugins: { + react: react, + 'react-hooks': reactHooks, + 'react-refresh': reactRefresh, + 'import-x': importXPlugin, + promise: promisePlugin, + 'no-catch-all': noCatchAllPlugin, + }, + settings: { + react: { + version: '18.2.0', + }, + 'import-x/resolver': { + typescript: true, + node: { + extensions: ['.js', '.jsx', '.ts', '.tsx'], + }, + }, + }, + rules: { + // ESLint comments rules - allow whole-file disables without eslint-enable + '@eslint-community/eslint-comments/disable-enable-pair': ['error', { allowWholeFile: true }], + + // Basic rules + 'no-console': 'error', + 'no-debugger': 'error', + camelcase: 'error', + + // Standard JS rules (replacing eslint-config-standard) + semi: ['error', 'never'], + quotes: ['error', 'single', { avoidEscape: true }], + 'comma-dangle': ['error', 'always-multiline'], + // Disabled: conflicts with common TypeScript/React patterns + // 'space-before-function-paren': ['error', 'always'], + 'keyword-spacing': ['error', { before: true, after: true }], + 'space-infix-ops': 'error', + 'eol-last': ['error', 'always'], + 'no-trailing-spaces': 'error', + 'object-curly-spacing': ['error', 'always'], + 'array-bracket-spacing': ['error', 'never'], + 'computed-property-spacing': ['error', 'never'], + 'no-multiple-empty-lines': ['error', { max: 1, maxEOF: 0 }], + // Disable indent rule due to known issues with TypeScript/JSX + // 'indent': ['error', 2], + 'linebreak-style': ['error', 'unix'], + + // Additional standard rules that were missing + eqeqeq: ['error', 'always', { null: 'ignore' }], + 'new-cap': ['error', { newIsCap: true, capIsNew: false, properties: true }], + 'array-callback-return': ['error', { allowImplicit: false, checkForEach: false }], + + // React rules + 'react/react-in-jsx-scope': 'off', + 'react/no-unescaped-entities': 'error', + 'react-hooks/rules-of-hooks': 'error', + 'react-hooks/exhaustive-deps': 'warn', + 'react-refresh/only-export-components': ['warn', { allowConstantExport: true }], + + // Import rules + 'import-x/export': 'error', + 'import-x/no-deprecated': 'error', + 'import-x/no-empty-named-blocks': 'error', + 'import-x/no-extraneous-dependencies': 'error', + 'import-x/no-mutable-exports': 'error', + 'import-x/no-named-as-default': 'error', + 'import-x/no-named-as-default-member': 'error', + 'import-x/no-amd': 'error', + 'import-x/no-commonjs': 'error', + 'import-x/no-nodejs-modules': 'off', + 'import-x/default': 'error', + 'import-x/named': 'error', + 'import-x/namespace': 'error', + 'import-x/no-absolute-path': 'error', + 'import-x/no-cycle': 'error', + 'import-x/no-dynamic-require': 'error', + 'import-x/no-internal-modules': 'off', + 'import-x/no-relative-packages': 'error', + 'import-x/no-self-import': 'error', + 'import-x/no-unresolved': ['error', { ignore: ['react'] }], + 'import-x/no-useless-path-segments': 'error', + 'import-x/no-webpack-loader-syntax': 'error', + 'import-x/consistent-type-specifier-style': 'error', + 'import-x/exports-last': 'off', + 'import-x/extensions': ['error', 'never', { json: 'always' }], + 'import-x/first': 'error', + 'import-x/group-exports': 'off', + 'import-x/newline-after-import': 'error', + 'import-x/no-anonymous-default-export': 'off', + 'import-x/no-default-export': 'off', + 'import-x/no-duplicates': 'error', + 'import-x/no-named-default': 'error', + 'import-x/no-namespace': 'error', + 'import-x/no-unassigned-import': ['error', { allow: ['**/*.css'] }], + 'import-x/order': [ + 'error', + { + groups: [ + 'builtin', + 'external', + 'internal', + 'parent', + 'sibling', + 'index', + 'object', + 'type', + ], + 'newlines-between': 'always', + alphabetize: { + order: 'asc', + caseInsensitive: true, + }, + distinctGroup: true, + }, + ], + 'import-x/prefer-default-export': 'off', + + // Promise rules + 'promise/catch-or-return': 'error', + 'promise/no-return-wrap': 'error', + 'promise/param-names': 'error', + 'promise/always-return': 'error', + 'promise/no-native': 'off', + 'promise/no-nesting': 'warn', + 'promise/no-promise-in-callback': 'warn', + 'promise/no-callback-in-promise': 'warn', + 'promise/avoid-new': 'warn', + 'promise/no-new-statics': 'error', + 'promise/no-return-in-finally': 'warn', + 'promise/valid-params': 'warn', + 'promise/prefer-await-to-callbacks': 'error', + 'promise/no-multiple-resolved': 'error', + + // Security and other rules + 'no-catch-all/no-catch-all': 'error', + + // Additional import rules + 'import-x/no-unused-modules': 'error', + 'import-x/no-import-module-exports': 'error', + 'import-x/unambiguous': 'off', + 'import-x/no-relative-parent-imports': [ + 'error', + { + ignore: ['#[src,types,root,components,utils,assets]/*', '@/config/*'], + }, + ], + }, + }, + + // TypeScript configs (applied after main config) + ...tseslint.configs.recommended, + ...tseslint.configs.strict, + ...tseslint.configs.stylistic, + + // TypeScript type-checking configuration + { + files: ['**/*.{ts,tsx}'], + extends: [ + ...tseslint.configs.recommendedTypeChecked, + ...tseslint.configs.strictTypeChecked, + ...tseslint.configs.stylisticTypeChecked, + ], + languageOptions: { + parserOptions: { + project: ['./tsconfig.json'], + tsconfigRootDir: import.meta.dirname, + }, + }, + rules: { + '@typescript-eslint/consistent-type-imports': 'error', + '@typescript-eslint/no-floating-promises': ['error', { ignoreVoid: true }], + 'no-void': ['error', { allowAsStatement: true }], + + // Disable empty function rule - legitimate use in React contexts and empty constructors + '@typescript-eslint/no-empty-function': 'off', + + // Configure no-unused-expressions to allow logical AND and ternary patterns + '@typescript-eslint/no-unused-expressions': [ + 'error', + { + allowShortCircuit: true, + allowTernary: true, + }, + ], + }, + }, + + // JSON files configuration + { + files: ['**/*.json'], + plugins: { + json: jsonPlugin, + }, + rules: { + // Disable TypeScript-specific rules for JSON files + '@typescript-eslint/no-unused-expressions': 'off', + // JSON-specific rules + 'json/*': 'error', + }, + }, + + // Prettier recommended config (should be last to override other formatting rules) + eslintPluginPrettierRecommended, +) diff --git a/app/package.json b/app/package.json index a7fbb136..74eccabf 100644 --- a/app/package.json +++ b/app/package.json @@ -9,7 +9,7 @@ "scripts": { "dev": "vite --host", "build": "tsc && vite build", - "test:lint:eslint": "eslint --ext .ts,.tsx,.js,.jsx,.cjs,.mjs,.json,.yml,.yaml --max-warnings 0 .", + "test:lint:eslint": "eslint --max-warnings 0 .", "preview": "vite preview" }, "dependencies": { @@ -22,36 +22,33 @@ "react-dom": "^18.2.0", "react-rnd": "^10.4.1", "react-router-dom": "^6.23.0", - "vite-tsconfig-paths": "^5.1.4", - "utopia-ui": "^3.0.111" + "utopia-ui": "^3.0.111", + "vite-tsconfig-paths": "^5.1.4" }, "devDependencies": { "@eslint-community/eslint-plugin-eslint-comments": "^4.4.1", + "@eslint/js": "^9.36.0", "@types/node": "^24.10.2", "@types/react": "^18.2.79", "@types/react-dom": "^18.2.25", - "@typescript-eslint/eslint-plugin": "^5.62.0", - "@typescript-eslint/parser": "^5.62.0", "@vitejs/plugin-react": "^4.0.0", "daisyui": "^5.5.5", - "eslint": "^8.24.0", - "eslint-config-prettier": "^10.1.8", - "eslint-config-standard": "^17.1.0", + "eslint": "^9.36.0", "eslint-import-resolver-typescript": "^4.4.4", - "eslint-plugin-import": "^2.31.0", + "eslint-plugin-import-x": "^4.16.1", "eslint-plugin-json": "^3.1.0", - "eslint-plugin-n": "^17.23.1", "eslint-plugin-no-catch-all": "^1.1.0", - "eslint-plugin-prettier": "^5.2.1", + "eslint-plugin-prettier": "^5.5.4", "eslint-plugin-promise": "^7.2.1", "eslint-plugin-react": "^7.31.8", "eslint-plugin-react-hooks": "^7.0.1", "eslint-plugin-react-refresh": "^0.4.24", "eslint-plugin-security": "^3.0.1", - "eslint-plugin-yml": "^1.14.0", + "globals": "^16.3.0", "postcss": "^8.4.30", "tailwindcss": "^4.1.17", "typescript": "^5.9.3", + "typescript-eslint": "^8.9.0", "vite": "^7.2.7", "vite-plugin-pwa": "^1.2.0" } diff --git a/app/src/App.tsx b/app/src/App.tsx index 36a3de38..e21ef608 100644 --- a/app/src/App.tsx +++ b/app/src/App.tsx @@ -1,6 +1,6 @@ /* eslint-disable @typescript-eslint/no-unnecessary-condition */ /* eslint-disable @typescript-eslint/no-non-null-assertion */ -/* eslint-disable import/order */ +/* eslint-disable import-x/order */ /* eslint-disable eqeqeq */ /* eslint-disable @typescript-eslint/no-unsafe-argument */ /* eslint-disable react-hooks/exhaustive-deps */ @@ -8,6 +8,8 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ /* eslint-disable new-cap */ /* eslint-disable @typescript-eslint/prefer-optional-chain */ +/* eslint-disable @typescript-eslint/prefer-nullish-coalescing */ +/* eslint-disable @typescript-eslint/restrict-template-expressions */ /* eslint-disable @typescript-eslint/restrict-plus-operands */ /* eslint-disable @typescript-eslint/no-unsafe-assignment */ /* eslint-disable @typescript-eslint/no-unsafe-member-access */ diff --git a/app/src/ModalContent.tsx b/app/src/ModalContent.tsx index f501ddab..c79a850b 100644 --- a/app/src/ModalContent.tsx +++ b/app/src/ModalContent.tsx @@ -2,6 +2,7 @@ /* eslint-disable @typescript-eslint/restrict-plus-operands */ /* eslint-disable @typescript-eslint/no-unsafe-assignment */ /* eslint-disable @typescript-eslint/no-unsafe-member-access */ +/* eslint-disable @typescript-eslint/prefer-nullish-coalescing */ import { useEffect, useState } from 'react' import { TextView } from 'utopia-ui' @@ -22,7 +23,9 @@ export function Welcome1({ clickAction1, map }: ChapterProps) {
    @@ -45,7 +48,9 @@ export function Welcome1({ clickAction1, map }: ChapterProps) {
    diff --git a/app/src/api/directus.ts b/app/src/api/directus.ts index 140ca4ba..2e28ed01 100644 --- a/app/src/api/directus.ts +++ b/app/src/api/directus.ts @@ -4,7 +4,7 @@ /* eslint-disable @typescript-eslint/no-unsafe-return */ import { createDirectus, rest, authentication } from '@directus/sdk' -// eslint-disable-next-line import/no-relative-parent-imports +// eslint-disable-next-line import-x/no-relative-parent-imports import { config } from '../config' import type { AuthenticationData, AuthenticationStorage } from '@directus/sdk' @@ -86,9 +86,10 @@ export const authLocalStorage = (mainKey = 'directus_storage') => // implementation of set, here set the value at mainKey in localStorage, or remove it if value is null set: async (value: AuthenticationData | null) => { if (!value) { - return window.localStorage.removeItem(mainKey) + window.localStorage.removeItem(mainKey) + return } - return window.localStorage.setItem(mainKey, JSON.stringify(value)) + window.localStorage.setItem(mainKey, JSON.stringify(value)) }, }) as AuthenticationStorage diff --git a/app/src/api/inviteApi.ts b/app/src/api/inviteApi.ts index 7a6d2c24..8dcd8d8a 100644 --- a/app/src/api/inviteApi.ts +++ b/app/src/api/inviteApi.ts @@ -1,4 +1,3 @@ -/* @eslint-disable-next-line import/no-relative-parent-imports */ import { config } from '@/config' import type { UserApi } from 'utopia-ui' diff --git a/app/src/api/itemsApi.ts b/app/src/api/itemsApi.ts index defb7c99..7b60142f 100644 --- a/app/src/api/itemsApi.ts +++ b/app/src/api/itemsApi.ts @@ -20,8 +20,8 @@ export class itemsApi implements ItemsApi { constructor( collectionName: keyof MyCollections, - layerId?: string | undefined, - mapId?: string | undefined, + layerId?: string, + mapId?: string, filter?: any, customParameter?: any, ) { @@ -111,8 +111,8 @@ export class itemsApi implements ItemsApi { async deleteItem(id: string): Promise { try { - const result = await directusClient.request(deleteItem(this.collectionName, id)) - return result as unknown as boolean + await directusClient.request(deleteItem(this.collectionName, id)) + return true } catch (error: any) { console.log(error) if (error.errors[0].message) throw error.errors[0].message diff --git a/app/src/api/layersApi.ts b/app/src/api/layersApi.ts index b91e5881..fa779ecf 100644 --- a/app/src/api/layersApi.ts +++ b/app/src/api/layersApi.ts @@ -21,6 +21,7 @@ export class layersApi { { itemType: ['*.*', { profileTemplate: ['*', 'item.*.*.*.*'] }] }, { markerIcon: ['*'] } as any, ], + // eslint-disable-next-line camelcase filter: { maps: { maps_id: { id: { _eq: this.mapId } } } }, limit: 500, sort: ['sort'], diff --git a/app/src/api/permissionsApi.ts b/app/src/api/permissionsApi.ts index c0f42647..ed1c027e 100644 --- a/app/src/api/permissionsApi.ts +++ b/app/src/api/permissionsApi.ts @@ -1,6 +1,5 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ /* eslint-disable @typescript-eslint/no-useless-constructor */ -/* eslint-disable @typescript-eslint/no-empty-function */ /* eslint-disable @typescript-eslint/no-unsafe-member-access */ /* eslint-disable no-console */ import { readPermissions } from '@directus/sdk' diff --git a/app/src/api/refiBcnApi.ts b/app/src/api/refiBcnApi.ts index 5f685ed8..65717ad3 100644 --- a/app/src/api/refiBcnApi.ts +++ b/app/src/api/refiBcnApi.ts @@ -1,7 +1,7 @@ /* eslint-disable no-console */ -/* eslint-disable @typescript-eslint/no-unsafe-return */ /* eslint-disable @typescript-eslint/no-unsafe-member-access */ /* eslint-disable @typescript-eslint/no-explicit-any */ +/* eslint-disable @typescript-eslint/no-unsafe-return */ import axios from 'axios' import type { ItemsApi } from 'utopia-ui' diff --git a/app/src/api/userApi.ts b/app/src/api/userApi.ts index c63e1baa..ff8e7744 100644 --- a/app/src/api/userApi.ts +++ b/app/src/api/userApi.ts @@ -3,7 +3,6 @@ /* eslint-disable @typescript-eslint/no-unsafe-member-access */ /* eslint-disable no-console */ /* eslint-disable @typescript-eslint/no-explicit-any */ -/* eslint-disable @typescript-eslint/no-unsafe-return */ import { createUser, passwordRequest, passwordReset, readMe, updateMe } from '@directus/sdk' import { directusClient } from './directus' @@ -54,7 +53,8 @@ export class UserApi { async logout(): Promise { try { - return await directusClient.logout() + await directusClient.logout() + return } catch (error: any) { console.log(error) if (error.errors[0].message) throw error.errors[0].message @@ -98,7 +98,8 @@ export class UserApi { async requestPasswordReset(email: string, reset_url?: string): Promise { try { - return await directusClient.request(passwordRequest(email, reset_url)) + await directusClient.request(passwordRequest(email, reset_url)) + return } catch (error: any) { console.log(error) if (error.errors[0].message) throw error.errors[0].message @@ -108,7 +109,8 @@ export class UserApi { async passwordReset(reset_token: string, new_password: string): Promise { try { - return await directusClient.request(passwordReset(reset_token, new_password)) + await directusClient.request(passwordReset(reset_token, new_password)) + return } catch (error: any) { console.log(error) if (error.errors[0].message) throw error.errors[0].message diff --git a/app/src/main.tsx b/app/src/main.tsx index 86140f18..ccb66470 100644 --- a/app/src/main.tsx +++ b/app/src/main.tsx @@ -1,5 +1,4 @@ -/* eslint-disable import/extensions */ -/* eslint-disable import/no-named-as-default-member */ +/* eslint-disable import-x/extensions */ /* eslint-disable @typescript-eslint/no-non-null-assertion */ import React from 'react' import ReactDOM from 'react-dom/client' diff --git a/app/src/pages/Landingpage.tsx b/app/src/pages/Landingpage.tsx index a5d221fa..97c355c0 100644 --- a/app/src/pages/Landingpage.tsx +++ b/app/src/pages/Landingpage.tsx @@ -1,7 +1,7 @@ /* eslint-disable react/no-unescaped-entities */ /* eslint-disable @typescript-eslint/restrict-template-expressions */ /* eslint-disable @typescript-eslint/no-unsafe-member-access */ -/* eslint-disable import/no-relative-parent-imports */ +/* eslint-disable import-x/no-relative-parent-imports */ /* eslint-disable @typescript-eslint/no-explicit-any */ /* eslint-disable @typescript-eslint/no-unsafe-argument */ /* eslint-disable new-cap */ diff --git a/app/src/pages/MapContainer.tsx b/app/src/pages/MapContainer.tsx index 0d305d3d..f0b0cd9f 100644 --- a/app/src/pages/MapContainer.tsx +++ b/app/src/pages/MapContainer.tsx @@ -1,9 +1,9 @@ /* eslint-disable @typescript-eslint/no-unnecessary-condition */ /* eslint-disable @typescript-eslint/no-explicit-any */ -/* eslint-disable import/no-relative-parent-imports */ +/* eslint-disable import-x/no-relative-parent-imports */ /* eslint-disable new-cap */ -/* eslint-disable @typescript-eslint/no-empty-function */ /* eslint-disable @typescript-eslint/no-unsafe-assignment */ +/* eslint-disable @typescript-eslint/prefer-nullish-coalescing */ /* eslint-disable @typescript-eslint/no-unsafe-member-access */ import { useEffect, useState } from 'react' import { diff --git a/app/src/pages/data.ts b/app/src/pages/data.ts index f72437dc..cd36c415 100644 --- a/app/src/pages/data.ts +++ b/app/src/pages/data.ts @@ -1,3 +1,4 @@ +/* eslint-disable camelcase */ import type { Item, Tag } from 'utopia-ui' export const tags: Tag[] = [ diff --git a/app/tsconfig.json b/app/tsconfig.json index 95a0cf49..784becfb 100644 --- a/app/tsconfig.json +++ b/app/tsconfig.json @@ -12,35 +12,17 @@ "noFallthroughCasesInSwitch": true, "baseUrl": ".", "paths": { - "@/*": [ - "src/*" - ], - "utopia-ui": [ - "../lib/src" - ], - "#components/*": [ - "../lib/src/Components/*" - ], - "#utils/*": [ - "../lib/src/Utils/*" - ], - "#types/*": [ - "../lib/src/types/*" - ], - "#assets/*": [ - "../lib/src/assets/*" - ], - "#src/*": [ - "../lib/src/*" - ], - "#root/*": [ - "../lib/*" - ] + "@/*": ["src/*"], + "utopia-ui": ["../lib/src"], + "#components/*": ["../lib/src/Components/*"], + "#utils/*": ["../lib/src/Utils/*"], + "#types/*": ["../lib/src/types/*"], + "#assets/*": ["../lib/src/assets/*"], + "#src/*": ["../lib/src/*"], + "#root/*": ["../lib/*"] } }, - "include": [ - "src" - ], + "include": ["src"], "references": [ { "path": "./tsconfig.node.json" diff --git a/lib/.eslintignore b/lib/.eslintignore deleted file mode 100644 index c24c07ac..00000000 --- a/lib/.eslintignore +++ /dev/null @@ -1,5 +0,0 @@ -node_modules/ -dist/ -examples/ -docs/ -coverage/ \ No newline at end of file diff --git a/lib/.eslintrc.cjs b/lib/.eslintrc.cjs deleted file mode 100644 index e4a3299b..00000000 --- a/lib/.eslintrc.cjs +++ /dev/null @@ -1,221 +0,0 @@ -// eslint-disable-next-line import/no-commonjs -module.exports = { - env: { - browser: true, - es2021: true, - }, - extends: [ - 'standard', - 'eslint:recommended', - 'plugin:@eslint-community/eslint-comments/recommended', - 'plugin:@typescript-eslint/recommended', - 'plugin:import/recommended', - 'plugin:import/typescript', - // 'plugin:promise/recommended', - 'plugin:security/recommended-legacy', - 'plugin:react/recommended', - ], - parserOptions: { - ecmaVersion: 'latest', - parser: '@typescript-eslint/parser', - sourceType: 'module', - }, - plugins: [ - '@typescript-eslint', - 'import', - 'promise', - 'security', - 'no-catch-all', - 'react', - 'react-hooks', - 'react-refresh', - ], - settings: { - 'import/resolver': { - typescript: true, - node: { - extensions: ['.js', '.jsx', '.ts', '.tsx'], - }, - }, - react: { - version: '18.2.0', - }, - }, - rules: { - 'react-hooks/rules-of-hooks': 'error', // Checks rules of Hooks - 'react-hooks/exhaustive-deps': 'warn', // Checks effect dependencies - 'react/react-in-jsx-scope': 'off', // Disable requirement for React import - 'no-catch-all/no-catch-all': 'error', - 'no-console': 'error', - 'no-debugger': 'error', - camelcase: 'error', - indent: ['error', 2], - 'linebreak-style': ['error', 'unix'], - semi: ['error', 'never'], - // Optional eslint-comments rule - '@eslint-community/eslint-comments/no-unused-disable': 'error', - '@eslint-community/eslint-comments/disable-enable-pair': ['error', { allowWholeFile: true }], - // import - 'import/export': 'error', - 'import/no-deprecated': 'error', - 'import/no-empty-named-blocks': 'error', - 'import/no-extraneous-dependencies': 'error', - 'import/no-mutable-exports': 'error', - 'import/no-unused-modules': 'error', - 'import/no-named-as-default': 'error', - 'import/no-named-as-default-member': 'error', - 'import/no-amd': 'error', - 'import/no-commonjs': 'error', - 'import/no-import-module-exports': 'error', - 'import/no-nodejs-modules': 'off', - 'import/unambiguous': 'off', // not compatible with scriptless vue files - 'import/default': 'error', - 'import/named': 'error', - 'import/namespace': 'error', - 'import/no-absolute-path': 'error', - 'import/no-cycle': 'error', - 'import/no-dynamic-require': 'error', - 'import/no-internal-modules': 'off', - 'import/no-relative-packages': 'error', - 'import/no-relative-parent-imports': [ - 'error', - { - ignore: ['#[src,types,root,components,utils,assets]/*'], - }, - ], - 'import/no-self-import': 'error', - 'import/no-unresolved': [ - 'error', - { - ignore: ['react'], - }, - ], - 'import/no-useless-path-segments': 'error', - 'import/no-webpack-loader-syntax': 'error', - 'import/consistent-type-specifier-style': 'error', - 'import/exports-last': 'off', - 'import/extensions': [ - 'error', - 'never', - { - json: 'always', - }, - ], - 'import/first': 'error', - 'import/group-exports': 'off', - 'import/newline-after-import': 'error', - 'import/no-anonymous-default-export': 'off', // todo - consider to enable again - 'import/no-default-export': 'off', // incompatible with vite & vike - 'import/no-duplicates': 'error', - 'import/no-named-default': 'error', - 'import/no-namespace': 'error', - 'import/no-unassigned-import': [ - 'error', - { - allow: ['**/*.css'], - }, - ], - 'import/order': [ - 'error', - { - groups: ['builtin', 'external', 'internal', 'parent', 'sibling', 'index', 'object', 'type'], - 'newlines-between': 'always', - alphabetize: { - order: 'asc', // sort in ascending order. Options: ["ignore", "asc", "desc"] - caseInsensitive: true, // ignore case. Options: [true, false] - }, - distinctGroup: true, - }, - ], - 'import/prefer-default-export': 'off', - // promise - 'promise/catch-or-return': 'error', - 'promise/no-return-wrap': 'error', - 'promise/param-names': 'error', - 'promise/always-return': 'error', - 'promise/no-native': 'off', - 'promise/no-nesting': 'warn', - 'promise/no-promise-in-callback': 'warn', - 'promise/no-callback-in-promise': 'warn', - 'promise/avoid-new': 'warn', - 'promise/no-new-statics': 'error', - 'promise/no-return-in-finally': 'warn', - 'promise/valid-params': 'warn', - 'promise/prefer-await-to-callbacks': 'error', - 'promise/no-multiple-resolved': 'error', - }, - overrides: [ - { - files: ['*.ts', '*.tsx'], - parser: '@typescript-eslint/parser', - parserOptions: { - tsconfigRootDir: __dirname, - project: ['./tsconfig.json', '**/tsconfig.json'], - ecmaVersion: 'latest', - parser: '@typescript-eslint/parser', - sourceType: 'module', - }, - plugins: ['@typescript-eslint'], - extends: [ - 'plugin:@typescript-eslint/recommended', - 'plugin:@typescript-eslint/recommended-requiring-type-checking', - 'plugin:@typescript-eslint/strict', - ], - rules: { - '@typescript-eslint/consistent-type-imports': 'error', - // allow explicitly defined dangling promises - '@typescript-eslint/no-floating-promises': ['error', { ignoreVoid: true }], - 'no-void': ['error', { allowAsStatement: true }], - }, - }, - { - files: ['!*.json'], - plugins: ['prettier'], - extends: ['plugin:prettier/recommended'], - rules: { - 'prettier/prettier': 'error', - }, - }, - { - files: ['*.json'], - plugins: ['json'], - extends: ['plugin:json/recommended-with-comments'], - }, - // { - // files: ['*.{test,spec}.[tj]s'], - // plugins: ['vitest'], - // extends: ['plugin:vitest/all'], - // rules: { - // 'vitest/prefer-lowercase-title': 'off', - // 'vitest/no-hooks': 'off', - // 'vitest/consistent-test-filename': 'off', - // 'vitest/prefer-expect-assertions': [ - // 'off', - // { - // onlyFunctionsWithExpectInLoop: true, - // onlyFunctionsWithExpectInCallback: true, - // }, - // ], - // 'vitest/prefer-strict-equal': 'off', - // 'vitest/prefer-to-be-falsy': 'off', - // 'vitest/prefer-to-be-truthy': 'off', - // 'vitest/require-hook': [ - // 'error', - // { - // allowedFunctionCalls: [ - // 'mockClient.setRequestHandler', - // 'setActivePinia', - // 'provideApolloClient', - // ], - // }, - // ], - // }, - // }, - { - files: ['*.yaml', '*.yml'], - parser: 'yaml-eslint-parser', - plugins: ['yml'], - extends: ['plugin:yml/prettier'], - }, - ], -} diff --git a/lib/.prettierrc.json b/lib/.prettierrc.json index 1db2a8cf..72e17590 100644 --- a/lib/.prettierrc.json +++ b/lib/.prettierrc.json @@ -11,4 +11,4 @@ "bracketSameLine": false, "arrowParens": "always", "endOfLine": "auto" -} \ No newline at end of file +} diff --git a/lib/cypress/support/component.ts b/lib/cypress/support/component.ts index 13ea7ddf..86f1ddf0 100644 --- a/lib/cypress/support/component.ts +++ b/lib/cypress/support/component.ts @@ -14,7 +14,7 @@ // *********************************************************** // Import commands.js using ES2015 syntax: -// eslint-disable-next-line import/no-unassigned-import +// eslint-disable-next-line import-x/no-unassigned-import import './commands' import { mount } from 'cypress/react' diff --git a/lib/eslint.config.js b/lib/eslint.config.js new file mode 100644 index 00000000..855a03ad --- /dev/null +++ b/lib/eslint.config.js @@ -0,0 +1,260 @@ +// ESLint v9 flat config for Utopia UI Library +import js from '@eslint/js' +import eslintCommentsConfigs from '@eslint-community/eslint-plugin-eslint-comments/configs' +import importXPlugin from 'eslint-plugin-import-x' +import jsonPlugin from 'eslint-plugin-json' +import noCatchAllPlugin from 'eslint-plugin-no-catch-all' +import eslintPluginPrettierRecommended from 'eslint-plugin-prettier/recommended' +import promisePlugin from 'eslint-plugin-promise' +import react from 'eslint-plugin-react' +import reactHooks from 'eslint-plugin-react-hooks' +import reactRefresh from 'eslint-plugin-react-refresh' +import securityPlugin from 'eslint-plugin-security' +import globals from 'globals' +import tseslint from 'typescript-eslint' + +export default tseslint.config( + // Ignore patterns + { + ignores: ['dist/**', 'node_modules/**', 'coverage/**', 'docs/**', 'examples/**'], + }, + + // Report unused eslint-disable directives (catches stale comments after rule renames) + { + linterOptions: { + reportUnusedDisableDirectives: 'error', + }, + }, + + // Base ESLint recommended config + js.configs.recommended, + + // ESLint comments recommended config + eslintCommentsConfigs.recommended, + + // Security recommended config + securityPlugin.configs.recommended, + + // React recommended configs + react.configs.flat.recommended, + react.configs.flat['jsx-runtime'], + + // Main configuration for JavaScript/TypeScript files + { + files: ['**/*.{js,jsx,ts,tsx,cjs,mjs}'], + languageOptions: { + ecmaVersion: 'latest', + sourceType: 'module', + globals: { + ...globals.browser, + ...globals.es2021, + }, + parserOptions: { + ecmaFeatures: { + jsx: true, + }, + }, + }, + plugins: { + react: react, + 'react-hooks': reactHooks, + 'react-refresh': reactRefresh, + 'import-x': importXPlugin, + promise: promisePlugin, + 'no-catch-all': noCatchAllPlugin, + }, + settings: { + react: { + version: '18.2.0', + }, + 'import-x/resolver': { + typescript: true, + node: { + extensions: ['.js', '.jsx', '.ts', '.tsx'], + }, + }, + }, + rules: { + // ESLint comments rules - allow whole-file disables without eslint-enable + '@eslint-community/eslint-comments/disable-enable-pair': ['error', { allowWholeFile: true }], + + // Basic rules + 'no-console': 'error', + 'no-debugger': 'error', + camelcase: 'error', + + // Standard JS rules + semi: ['error', 'never'], + quotes: ['error', 'single', { avoidEscape: true }], + 'comma-dangle': ['error', 'always-multiline'], + 'keyword-spacing': ['error', { before: true, after: true }], + 'space-infix-ops': 'error', + 'eol-last': ['error', 'always'], + 'no-trailing-spaces': 'error', + 'object-curly-spacing': ['error', 'always'], + 'array-bracket-spacing': ['error', 'never'], + 'computed-property-spacing': ['error', 'never'], + 'no-multiple-empty-lines': ['error', { max: 1, maxEOF: 0 }], + indent: ['error', 2], + 'linebreak-style': ['error', 'unix'], + eqeqeq: ['error', 'always', { null: 'ignore' }], + 'new-cap': ['error', { newIsCap: true, capIsNew: false, properties: true }], + 'array-callback-return': ['error', { allowImplicit: false, checkForEach: false }], + + // React rules + 'react/react-in-jsx-scope': 'off', + 'react/no-unescaped-entities': 'error', + 'react-hooks/rules-of-hooks': 'error', + 'react-hooks/exhaustive-deps': 'warn', + + // Import rules + 'import-x/export': 'error', + 'import-x/no-deprecated': 'error', + 'import-x/no-empty-named-blocks': 'error', + 'import-x/no-extraneous-dependencies': 'error', + 'import-x/no-mutable-exports': 'error', + 'import-x/no-named-as-default': 'error', + 'import-x/no-named-as-default-member': 'error', + 'import-x/no-amd': 'error', + 'import-x/no-commonjs': 'error', + 'import-x/no-nodejs-modules': 'off', + 'import-x/default': 'error', + 'import-x/named': 'error', + 'import-x/namespace': 'error', + 'import-x/no-absolute-path': 'error', + 'import-x/no-cycle': 'error', + 'import-x/no-dynamic-require': 'error', + 'import-x/no-internal-modules': 'off', + 'import-x/no-relative-packages': 'error', + 'import-x/no-self-import': 'error', + 'import-x/no-unresolved': ['error', { ignore: ['react'] }], + 'import-x/no-useless-path-segments': 'error', + 'import-x/no-webpack-loader-syntax': 'error', + 'import-x/consistent-type-specifier-style': 'error', + 'import-x/exports-last': 'off', + 'import-x/extensions': ['error', 'never', { json: 'always' }], + 'import-x/first': 'error', + 'import-x/group-exports': 'off', + 'import-x/newline-after-import': 'error', + 'import-x/no-anonymous-default-export': 'off', + 'import-x/no-default-export': 'off', + 'import-x/no-duplicates': 'error', + 'import-x/no-named-default': 'error', + 'import-x/no-namespace': 'error', + 'import-x/no-unassigned-import': ['error', { allow: ['**/*.css'] }], + 'import-x/order': [ + 'error', + { + groups: [ + 'builtin', + 'external', + 'internal', + 'parent', + 'sibling', + 'index', + 'object', + 'type', + ], + 'newlines-between': 'always', + alphabetize: { order: 'asc', caseInsensitive: true }, + distinctGroup: true, + }, + ], + 'import-x/prefer-default-export': 'off', + 'import-x/no-unused-modules': 'error', + 'import-x/no-import-module-exports': 'error', + 'import-x/unambiguous': 'off', + 'import-x/no-relative-parent-imports': [ + 'error', + { ignore: ['#[src,types,root,components,utils,assets]/*'] }, + ], + + // Promise rules + 'promise/catch-or-return': 'error', + 'promise/no-return-wrap': 'error', + 'promise/param-names': 'error', + 'promise/always-return': 'error', + 'promise/no-native': 'off', + 'promise/no-nesting': 'warn', + 'promise/no-promise-in-callback': 'warn', + 'promise/no-callback-in-promise': 'warn', + 'promise/avoid-new': 'warn', + 'promise/no-new-statics': 'error', + 'promise/no-return-in-finally': 'warn', + 'promise/valid-params': 'warn', + 'promise/prefer-await-to-callbacks': 'error', + 'promise/no-multiple-resolved': 'error', + + // Security and other rules + 'no-catch-all/no-catch-all': 'error', + }, + }, + + // TypeScript configs (applied after main config) + ...tseslint.configs.recommended, + ...tseslint.configs.strict, + ...tseslint.configs.stylistic, + + // TypeScript type-checking configuration + { + files: ['**/*.{ts,tsx}'], + extends: [ + ...tseslint.configs.recommendedTypeChecked, + ...tseslint.configs.strictTypeChecked, + ...tseslint.configs.stylisticTypeChecked, + ], + languageOptions: { + parserOptions: { + project: ['./tsconfig.json'], + tsconfigRootDir: import.meta.dirname, + }, + }, + rules: { + '@typescript-eslint/consistent-type-imports': 'error', + '@typescript-eslint/no-floating-promises': ['error', { ignoreVoid: true }], + 'no-void': ['error', { allowAsStatement: true }], + + // Disable empty function rule - legitimate use in React contexts + '@typescript-eslint/no-empty-function': 'off', + + // Configure no-unused-expressions to allow logical AND and ternary patterns + '@typescript-eslint/no-unused-expressions': [ + 'error', + { + allowShortCircuit: true, + allowTernary: true, + }, + ], + }, + }, + + // JSON files configuration + { + files: ['**/*.json'], + plugins: { + json: jsonPlugin, + }, + rules: { + // Disable TypeScript-specific rules for JSON files + '@typescript-eslint/no-unused-expressions': 'off', + // JSON-specific rules + 'json/*': 'error', + }, + }, + + // CommonJS configuration files (e.g., postcss.config.cjs) + // Provides Node.js globals (module, require, etc.) that were previously + // included via eslint-config-standard in ESLint v8 + { + files: ['**/*.cjs'], + languageOptions: { + globals: { + ...globals.node, + }, + sourceType: 'commonjs', + }, + }, + + // Prettier recommended config (should be last to override other formatting rules) + eslintPluginPrettierRecommended, +) diff --git a/lib/package.json b/lib/package.json index 888159af..5eb4be30 100644 --- a/lib/package.json +++ b/lib/package.json @@ -26,7 +26,7 @@ "scripts": { "build": "rollup -c", "start": "rollup -c -w", - "test:lint:eslint": "eslint --ext .ts,.tsx,.js,.jsx,.cjs,.mjs,.json,.yml,.yaml --max-warnings 0 .", + "test:lint:eslint": "eslint --max-warnings 0 .", "lint": "npm run test:lint:eslint", "lintfix": "npm run test:lint:eslint -- --fix", "test:component": "cypress run --component --browser electron", @@ -44,6 +44,7 @@ "license": "GPL-3.0-only", "devDependencies": { "@eslint-community/eslint-plugin-eslint-comments": "^4.4.1", + "@eslint/js": "^9.36.0", "@rollup/plugin-alias": "^6.0.0", "@rollup/plugin-commonjs": "^29.0.0", "@rollup/plugin-node-resolve": "^16.0.3", @@ -56,19 +57,15 @@ "@types/leaflet.markercluster": "^1.5.5", "@types/react": "^18.2.0", "@types/react-dom": "^18.0.5", - "@typescript-eslint/eslint-plugin": "^5.62.0", - "@typescript-eslint/parser": "^5.62.0", "@vitejs/plugin-react": "^4.3.4", "@vitest/coverage-v8": "^3.0.5", "cypress": "^15.7.1", "daisyui": "^5.5.5", - "eslint": "^8.24.0", + "eslint": "^9.36.0", "eslint-config-prettier": "^10.1.8", - "eslint-config-standard": "^17.1.0", "eslint-import-resolver-typescript": "^4.4.4", - "eslint-plugin-import": "^2.31.0", + "eslint-plugin-import-x": "^4.16.1", "eslint-plugin-json": "^3.1.0", - "eslint-plugin-n": "^17.23.1", "eslint-plugin-no-catch-all": "^1.1.0", "eslint-plugin-prettier": "^5.2.1", "eslint-plugin-promise": "^7.2.1", @@ -76,7 +73,7 @@ "eslint-plugin-react-hooks": "^7.0.1", "eslint-plugin-react-refresh": "^0.4.24", "eslint-plugin-security": "^3.0.1", - "eslint-plugin-yml": "^1.14.0", + "globals": "^16.3.0", "happy-dom": "^20.0.11", "postcss": "^8.4.21", "prettier": "^3.7.4", @@ -91,6 +88,7 @@ "typedoc-plugin-coverage": "^3.4.1", "typedoc-plugin-missing-exports": "^3.1.0", "typescript": "^5.9.3", + "typescript-eslint": "^8.9.0", "vite": "^7.2.7", "vite-plugin-svgr": "^4.3.0", "vitest": "^3.0.5" diff --git a/lib/postcss.config.cjs b/lib/postcss.config.cjs index 6bb9c83c..4d0b5bd1 100644 --- a/lib/postcss.config.cjs +++ b/lib/postcss.config.cjs @@ -1,4 +1,4 @@ -// eslint-disable-next-line import/no-commonjs +// eslint-disable-next-line import-x/no-commonjs module.exports = { plugins: { '@tailwindcss/postcss': {}, diff --git a/lib/setupTest.ts b/lib/setupTest.ts index 3ed9ed03..0f35e917 100644 --- a/lib/setupTest.ts +++ b/lib/setupTest.ts @@ -1,2 +1,2 @@ -// eslint-disable-next-line import/no-unassigned-import +// eslint-disable-next-line import-x/no-unassigned-import import '@testing-library/jest-dom' diff --git a/lib/src/Components/AppShell/NavBar.tsx b/lib/src/Components/AppShell/NavBar.tsx index 51f521b9..17eecc01 100644 --- a/lib/src/Components/AppShell/NavBar.tsx +++ b/lib/src/Components/AppShell/NavBar.tsx @@ -31,7 +31,9 @@ export default function NavBar({ appName }: { appName: string }) { className='tw:btn tw:btn-square tw:btn-ghost tw:ml-3' aria-controls='#sidenav' aria-haspopup='true' - onClick={() => toggleSidebar()} + onClick={() => { + toggleSidebar() + }} > @@ -50,7 +52,9 @@ export default function NavBar({ appName }: { appName: string }) { diff --git a/lib/src/Components/AppShell/SideBar.tsx b/lib/src/Components/AppShell/SideBar.tsx index 4c7d6799..1e8a1747 100644 --- a/lib/src/Components/AppShell/SideBar.tsx +++ b/lib/src/Components/AppShell/SideBar.tsx @@ -6,7 +6,7 @@ import SidebarSubmenu from './SidebarSubmenu' export interface Route { path: string - icon: JSX.Element + icon: React.JSX.Element name: string submenu?: Route[] blank?: boolean @@ -57,7 +57,9 @@ export function SideBar({ routes, bottomRoutes }: { routes: Route[]; bottomRoute // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition to={`${route.path}${params && '?' + params.toString()}`} className={({ isActive }) => - `${isActive ? 'tw:font-semibold tw:bg-base-200 tw:rounded-none!' : 'tw:font-normal tw:rounded-none!'}` + isActive + ? 'tw:font-semibold tw:bg-base-200 tw:rounded-none!' + : 'tw:font-normal tw:rounded-none!' } onClick={() => { if (screen.width < 640 && !appState.sideBarSlim) toggleSidebarOpen() @@ -70,7 +72,7 @@ export function SideBar({ routes, bottomRoutes }: { routes: Route[]; bottomRoute {route.icon}
    {route.name} @@ -119,7 +121,7 @@ export function SideBar({ routes, bottomRoutes }: { routes: Route[]; bottomRoute > {route.icon} {route.name} @@ -143,7 +145,9 @@ export function SideBar({ routes, bottomRoutes }: { routes: Route[]; bottomRoute 'tw:w-5 tw:h-5 tw:mb-4 tw:mr-5 tw:mt-2 tw:cursor-pointer tw:float-right tw:delay-400 tw:duration-500 tw:transition-all ' + (!appState.sideBarSlim ? 'tw:rotate-180' : '') } - onClick={() => toggleSidebarSlim()} + onClick={() => { + toggleSidebarSlim() + }} />
    diff --git a/lib/src/Components/AppShell/SidebarSubmenu.tsx b/lib/src/Components/AppShell/SidebarSubmenu.tsx index 347d1323..a5f39ea0 100644 --- a/lib/src/Components/AppShell/SidebarSubmenu.tsx +++ b/lib/src/Components/AppShell/SidebarSubmenu.tsx @@ -1,3 +1,4 @@ +/* eslint-disable @typescript-eslint/prefer-find */ import ChevronDownIcon from '@heroicons/react/24/outline/ChevronDownIcon' import { useEffect, useState } from 'react' import { Link, useLocation } from 'react-router-dom' @@ -10,7 +11,7 @@ function SidebarSubmenu({ icon, }: { path: string - icon: JSX.Element + icon: React.JSX.Element name: string submenu?: Route[] }) { @@ -31,7 +32,12 @@ function SidebarSubmenu({ return (
    {/** Route header */} -
    setIsExpanded(!isExpanded)}> +
    { + setIsExpanded(!isExpanded) + }} + > {icon} {name} setEmail(e.target.value)} + onChange={(e) => { + setEmail(e.target.value) + }} className='tw:input tw:input-bordered tw:w-full tw:max-w-xs' /> setPassword(e.target.value)} + onChange={(e) => { + setPassword(e.target.value) + }} className='tw:input tw:input-bordered tw:w-full tw:max-w-xs' />
    diff --git a/lib/src/Components/Auth/RequestPasswordPage.tsx b/lib/src/Components/Auth/RequestPasswordPage.tsx index dcfb416f..713516c1 100644 --- a/lib/src/Components/Auth/RequestPasswordPage.tsx +++ b/lib/src/Components/Auth/RequestPasswordPage.tsx @@ -28,7 +28,7 @@ export function RequestPasswordPage({ resetUrl }: { resetUrl: string }) { }, error: { render({ data }) { - return `${data as string}` + return data as string }, }, pending: 'sending email ...', @@ -42,7 +42,9 @@ export function RequestPasswordPage({ resetUrl }: { resetUrl: string }) { type='email' placeholder='E-Mail' value={email} - onChange={(e) => setEmail(e.target.value)} + onChange={(e) => { + setEmail(e.target.value) + }} className='tw:input tw:input-bordered tw:w-full tw:max-w-xs' />
    diff --git a/lib/src/Components/Auth/SetNewPasswordPage.tsx b/lib/src/Components/Auth/SetNewPasswordPage.tsx index c8f59591..fc00649c 100644 --- a/lib/src/Components/Auth/SetNewPasswordPage.tsx +++ b/lib/src/Components/Auth/SetNewPasswordPage.tsx @@ -28,7 +28,7 @@ export function SetNewPasswordPage() { }, error: { render({ data }) { - return `${data as string}` + return data as string }, }, pending: 'setting password ...', @@ -41,7 +41,9 @@ export function SetNewPasswordPage() { setPassword(e.target.value)} + onChange={(e) => { + setPassword(e.target.value) + }} className='tw:input tw:input-bordered tw:w-full tw:max-w-xs' />
    diff --git a/lib/src/Components/Auth/SignupPage.tsx b/lib/src/Components/Auth/SignupPage.tsx index 1eb51ea9..13c0089f 100644 --- a/lib/src/Components/Auth/SignupPage.tsx +++ b/lib/src/Components/Auth/SignupPage.tsx @@ -1,3 +1,4 @@ +/* eslint-disable @typescript-eslint/prefer-nullish-coalescing */ import { useEffect, useState } from 'react' import { useNavigate } from 'react-router-dom' import { toast } from 'react-toastify' @@ -32,7 +33,7 @@ export function SignupPage() { }, error: { render({ data }) { - return `${data as string}` + return data as string }, autoClose: 10000, }, @@ -61,20 +62,26 @@ export function SignupPage() { type='text' placeholder='Name' value={userName} - onChange={(e) => setUserName(e.target.value)} + onChange={(e) => { + setUserName(e.target.value) + }} className='tw:input tw:input-bordered tw:w-full tw:max-w-xs' /> setEmail(e.target.value)} + onChange={(e) => { + setEmail(e.target.value) + }} className='tw:input tw:input-bordered tw:w-full tw:max-w-xs' /> setPassword(e.target.value)} + onChange={(e) => { + setPassword(e.target.value) + }} className='tw:input tw:input-bordered tw:w-full tw:max-w-xs' />
    diff --git a/lib/src/Components/Auth/useAuth.tsx b/lib/src/Components/Auth/useAuth.tsx index 413e88f5..fe332d80 100644 --- a/lib/src/Components/Auth/useAuth.tsx +++ b/lib/src/Components/Auth/useAuth.tsx @@ -67,7 +67,7 @@ export const AuthProvider = ({ userApi, children }: AuthProviderProps) => { return undefined } // eslint-disable-next-line no-catch-all/no-catch-all - } catch (error) { + } catch { setLoading(false) return undefined } finally { @@ -135,7 +135,8 @@ export const AuthProvider = ({ userApi, children }: AuthProviderProps) => { setLoading(true) try { await userApi.requestPasswordReset(email, resetUrl) - return setLoading(false) + setLoading(false) + return } catch (error) { setLoading(false) throw error @@ -146,7 +147,8 @@ export const AuthProvider = ({ userApi, children }: AuthProviderProps) => { setLoading(true) try { await userApi.passwordReset(token, newPassword) - return setLoading(false) + setLoading(false) + return } catch (error) { setLoading(false) throw error diff --git a/lib/src/Components/Gaming/Quests.tsx b/lib/src/Components/Gaming/Quests.tsx index 944a2633..35d512b6 100644 --- a/lib/src/Components/Gaming/Quests.tsx +++ b/lib/src/Components/Gaming/Quests.tsx @@ -44,7 +44,9 @@ export function Quests() {
    diff --git a/lib/src/Components/Gaming/hooks/useQuests.tsx b/lib/src/Components/Gaming/hooks/useQuests.tsx index 1b3cc1d4..6539a008 100644 --- a/lib/src/Components/Gaming/hooks/useQuests.tsx +++ b/lib/src/Components/Gaming/hooks/useQuests.tsx @@ -1,4 +1,3 @@ -/* eslint-disable @typescript-eslint/no-empty-function */ import { useCallback, useState, createContext, useContext } from 'react' type UseQuestManagerResult = ReturnType diff --git a/lib/src/Components/Input/Autocomplete.tsx b/lib/src/Components/Input/Autocomplete.tsx index 2bb97d2c..ae9be9c7 100644 --- a/lib/src/Components/Input/Autocomplete.tsx +++ b/lib/src/Components/Input/Autocomplete.tsx @@ -85,7 +85,9 @@ export const Autocomplete = ({ ref={inputRef} {...inputProps} type='text' - onChange={(e) => handleChange(e)} + onChange={(e) => { + handleChange(e) + }} tabIndex='-1' onKeyDown={handleKeyDown} className='tw:border-none tw:focus:outline-none tw:focus:ring-0 tw:mt-5' @@ -94,7 +96,12 @@ export const Autocomplete = ({ className={`tw:absolute tw:z-4000 ${filteredSuggestions.length > 0 && 'tw:bg-base-100 tw:rounded-xl tw:p-2'}`} > {filteredSuggestions.map((suggestion, index) => ( -
  • handleSuggestionClick(suggestion)}> +
  • { + handleSuggestionClick(suggestion) + }} + >
  • ))} diff --git a/lib/src/Components/Item/PopupView.tsx b/lib/src/Components/Item/PopupView.tsx index 98640f38..c73ac6a4 100644 --- a/lib/src/Components/Item/PopupView.tsx +++ b/lib/src/Components/Item/PopupView.tsx @@ -1,3 +1,5 @@ +/* eslint-disable @typescript-eslint/prefer-nullish-coalescing */ +/* eslint-disable @typescript-eslint/restrict-plus-operands */ import { useContext, useMemo, useState } from 'react' import { Marker, Tooltip } from 'react-leaflet' diff --git a/lib/src/Components/Map/Subcomponents/AddButton.tsx b/lib/src/Components/Map/Subcomponents/AddButton.tsx index ab0e744b..c1944827 100644 --- a/lib/src/Components/Map/Subcomponents/AddButton.tsx +++ b/lib/src/Components/Map/Subcomponents/AddButton.tsx @@ -1,5 +1,6 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ /* eslint-disable @typescript-eslint/no-non-null-assertion */ +/* eslint-disable @typescript-eslint/restrict-template-expressions */ import { MapPinIcon } from '@heroicons/react/24/solid' import { useState } from 'react' import SVG from 'react-inlinesvg' @@ -89,7 +90,9 @@ export default function AddButton({ tabIndex={0} className='tw:z-500 tw:border-0 tw:p-0 tw:w-10 tw:h-10 tw:cursor-pointer tw:rounded-full tw:mouse tw:drop-shadow-md tw:transition tw:ease-in tw:duration-200 tw:focus:outline-hidden tw:flex tw:items-center tw:justify-center' style={{ backgroundColor: layer.menuColor || '#777' }} - onClick={() => handleLayerClick(layer)} + onClick={() => { + handleLayerClick(layer) + }} onTouchEnd={(e) => { handleLayerClick(layer) e.preventDefault() diff --git a/lib/src/Components/Map/Subcomponents/Controls/FilterControl.tsx b/lib/src/Components/Map/Subcomponents/Controls/FilterControl.tsx index e5c6c340..03a6f8ce 100644 --- a/lib/src/Components/Map/Subcomponents/Controls/FilterControl.tsx +++ b/lib/src/Components/Map/Subcomponents/Controls/FilterControl.tsx @@ -1,3 +1,4 @@ +/* eslint-disable array-callback-return */ import FunnelIcon from '@heroicons/react/24/outline/FunnelIcon' import { useEffect, useState } from 'react' @@ -18,7 +19,9 @@ export function FilterControl() { ] useEffect(() => { - groupTypes.map((layer) => addVisibleGroupType(layer.value)) + groupTypes.map((layer) => { + addVisibleGroupType(layer.value) + }) // eslint-disable-next-line react-hooks/exhaustive-deps }, []) @@ -48,7 +51,9 @@ export function FilterControl() { > toggleVisibleGroupType(groupType.value)} + onChange={() => { + toggleVisibleGroupType(groupType.value) + }} type='checkbox' className='tw:checkbox tw:checkbox-xs tw:checkbox-success' checked={isGroupTypeVisible(groupType.value)} diff --git a/lib/src/Components/Map/Subcomponents/Controls/LayerControl.tsx b/lib/src/Components/Map/Subcomponents/Controls/LayerControl.tsx index 83a1a29d..6e40bd07 100644 --- a/lib/src/Components/Map/Subcomponents/Controls/LayerControl.tsx +++ b/lib/src/Components/Map/Subcomponents/Controls/LayerControl.tsx @@ -36,7 +36,9 @@ export function LayerControl({ expandLayerControl = false }: { expandLayerContro > toggleVisibleLayer(layer)} + onChange={() => { + toggleVisibleLayer(layer) + }} type='checkbox' className='tw:checkbox tw:checkbox-xs tw:checkbox-success tw:text-white' checked={isLayerVisible(layer)} diff --git a/lib/src/Components/Map/Subcomponents/Controls/LocateControl.spec.tsx b/lib/src/Components/Map/Subcomponents/Controls/LocateControl.spec.tsx index 8bfbfd5c..909a0238 100644 --- a/lib/src/Components/Map/Subcomponents/Controls/LocateControl.spec.tsx +++ b/lib/src/Components/Map/Subcomponents/Controls/LocateControl.spec.tsx @@ -1,3 +1,4 @@ +/* eslint-disable camelcase */ // Directus database fields use snake_case /* eslint-disable @typescript-eslint/no-unsafe-assignment */ /* eslint-disable @typescript-eslint/no-unsafe-member-access */ /* eslint-disable @typescript-eslint/no-unsafe-call */ diff --git a/lib/src/Components/Map/Subcomponents/Controls/LocateControl.tsx b/lib/src/Components/Map/Subcomponents/Controls/LocateControl.tsx index 536ee3e5..f0907f81 100644 --- a/lib/src/Components/Map/Subcomponents/Controls/LocateControl.tsx +++ b/lib/src/Components/Map/Subcomponents/Controls/LocateControl.tsx @@ -1,3 +1,5 @@ +/* eslint-disable camelcase */ // Directus database fields use snake_case +/* eslint-disable promise/always-return */ import { control } from 'leaflet' import { useCallback, useEffect, useRef, useState } from 'react' import SVG from 'react-inlinesvg' @@ -15,7 +17,7 @@ import DialogModal from '#components/Templates/DialogModal' import type { Item } from '#types/Item' import type { LatLng } from 'leaflet' -// eslint-disable-next-line import/no-unassigned-import +// eslint-disable-next-line import-x/no-unassigned-import import 'leaflet.locatecontrol' // Type definitions for leaflet.locatecontrol @@ -31,7 +33,7 @@ declare module 'leaflet' { * React wrapper for leaflet.locatecontrol that provides user geolocation functionality * @category Map Controls */ -export const LocateControl = (): JSX.Element => { +export const LocateControl = (): React.JSX.Element => { const map = useMap() const myProfile = useMyProfile() const updateItem = useUpdateItem() @@ -206,7 +208,9 @@ export const LocateControl = (): JSX.Element => { // eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access if (lc) lc.stop() // Reset flag after a delay to allow future updates - setTimeout(() => setHasUpdatedPosition(false), 5000) + setTimeout(() => { + setHasUpdatedPosition(false) + }, 5000) } catch (error: unknown) { if (error instanceof Error) { toast.update(toastId, { @@ -278,7 +282,9 @@ export const LocateControl = (): JSX.Element => {