diff --git a/.forgejo/workflows/ci.yml b/.forgejo/workflows/ci.yml deleted file mode 100644 index c148849..0000000 --- a/.forgejo/workflows/ci.yml +++ /dev/null @@ -1,59 +0,0 @@ -name: CI - -# Lance lint + typecheck + tests + build sur push/PR. -# -# Workflow dormant tant qu'aucun runner Forgejo n'est enregistré. -# Pour activer : -# 1) Sur git.cosmolan.fr, générer un token runner : -# Admin → Actions → Runners → Create new Runner Token -# (ou pour ce repo seul : Settings → Actions → Runners → Create) -# 2) Sur la machine d'exécution : -# wget https://codeberg.org/forgejo/runner/releases/download/v6.7.0/forgejo-runner-6.7.0-linux-amd64 -# chmod +x forgejo-runner-6.7.0-linux-amd64 -# ./forgejo-runner-6.7.0-linux-amd64 register \ -# --instance https://git.cosmolan.fr \ -# --token \ -# --name karbe-ci \ -# --labels "ubuntu-latest:docker://node:20" -# 3) Démarrer : -# ./forgejo-runner-6.7.0-linux-amd64 daemon - -on: - push: - branches: [main] - pull_request: - -jobs: - test: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - - uses: actions/setup-node@v4 - with: - node-version: "20" - cache: "npm" - - - name: Install dependencies - run: npm ci --no-audit --no-fund - - - name: Generate Prisma client - run: npx prisma generate - - - name: Lint - run: npm run lint - - - name: Typecheck - run: npm run typecheck - - - name: Test - run: npm test - - - name: Build (smoke) - run: npm run build - env: - # Stubs nécessaires au build statique — pas de connexion réelle. - DATABASE_URL: "postgresql://stub:stub@localhost:5432/stub?schema=public" - NEXTAUTH_SECRET: "ci-secret-not-for-production" - AUTH_SECRET: "ci-secret-not-for-production" - NEXT_PUBLIC_SITE_URL: "https://example.invalid" diff --git a/package-lock.json b/package-lock.json index 7d8475d..f80d6c5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,23 +10,14 @@ "hasInstallScript": true, "dependencies": { "@aws-sdk/client-s3": "^3.1056.0", - "@aws-sdk/s3-request-presigner": "^3.1058.0", - "@dnd-kit/core": "^6.3.1", - "@dnd-kit/sortable": "^8.0.0", - "@dnd-kit/utilities": "^3.2.2", "@prisma/adapter-pg": "^7.8.0", "@prisma/client": "^7.8.0", - "@types/leaflet": "^1.9.21", "bcryptjs": "^3.0.3", - "leaflet": "^1.9.4", "next": "16.2.6", "next-auth": "^5.0.0-beta.31", "pg": "^8.21.0", "react": "19.2.4", "react-dom": "19.2.4", - "react-leaflet": "^5.0.0", - "resend": "^4.8.0", - "sharp": "^0.34.5", "stripe": "^18.3.0" }, "devDependencies": { @@ -34,14 +25,12 @@ "@types/node": "^20.19.41", "@types/react": "^19.2.15", "@types/react-dom": "^19.2.3", - "@vitest/coverage-v8": "^3.2.4", "dotenv": "^17.4.2", "eslint": "^9.39.4", "eslint-config-next": "^16.2.6", "prisma": "^7.8.0", "tailwindcss": "^4", - "typescript": "^5.9.3", - "vitest": "^3.2.4" + "typescript": "^5.9.3" } }, "node_modules/@alloc/quick-lru": { @@ -57,20 +46,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@ampproject/remapping": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", - "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.24" - }, - "engines": { - "node": ">=6.0.0" - } - }, "node_modules/@auth/core": { "version": "0.41.2", "resolved": "https://registry.npmjs.org/@auth/core/-/core-0.41.2.tgz", @@ -514,23 +489,6 @@ "node": ">=20.0.0" } }, - "node_modules/@aws-sdk/s3-request-presigner": { - "version": "3.1058.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/s3-request-presigner/-/s3-request-presigner-3.1058.0.tgz", - "integrity": "sha512-IRgNfn8U3zfsZ0JkpmwjS59R/XyHMHxpuwW6HVuJhik+FsbClhNkujEO0w1WqJvXrF4FX+7qIAwUrvlwNvaZ7Q==", - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/core": "^3.974.15", - "@aws-sdk/signature-v4-multi-region": "^3.996.30", - "@aws-sdk/types": "^3.973.9", - "@smithy/core": "^3.24.5", - "@smithy/types": "^4.14.2", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=20.0.0" - } - }, "node_modules/@aws-sdk/signature-v4-multi-region": { "version": "3.996.30", "resolved": "https://registry.npmjs.org/@aws-sdk/signature-v4-multi-region/-/signature-v4-multi-region-3.996.30.tgz", @@ -747,7 +705,7 @@ "version": "7.29.7", "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.29.7.tgz", "integrity": "sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==", - "devOptional": true, + "dev": true, "license": "MIT", "engines": { "node": ">=6.9.0" @@ -757,7 +715,7 @@ "version": "7.29.7", "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.29.7.tgz", "integrity": "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==", - "devOptional": true, + "dev": true, "license": "MIT", "engines": { "node": ">=6.9.0" @@ -791,7 +749,7 @@ "version": "7.29.7", "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.7.tgz", "integrity": "sha512-hnORnjP/1P/zFEndoeX+n+t1RwWRJiJpM/jO7FW32Kn9r5+sJB2JWOdYo4L6k78j15eCwY3Gm/7364B1EMwtNg==", - "devOptional": true, + "dev": true, "license": "MIT", "dependencies": { "@babel/types": "^7.29.7" @@ -841,7 +799,7 @@ "version": "7.29.7", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.7.tgz", "integrity": "sha512-4zBIxpPzowiZpusoFkyGVwakdRJUyuH5PxQ/PrqghfdFWWasvnCdPfQXHrenDai+gyLARulZjZowCOj6fjT4pA==", - "devOptional": true, + "dev": true, "license": "MIT", "dependencies": { "@babel/helper-string-parser": "^7.29.7", @@ -851,69 +809,6 @@ "node": ">=6.9.0" } }, - "node_modules/@bcoe/v8-coverage": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-1.0.2.tgz", - "integrity": "sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - } - }, - "node_modules/@dnd-kit/accessibility": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@dnd-kit/accessibility/-/accessibility-3.1.1.tgz", - "integrity": "sha512-2P+YgaXF+gRsIihwwY1gCsQSYnu9Zyj2py8kY5fFvUM1qm2WA2u639R6YNVfU4GWr+ZM5mqEsfHZZLoRONbemw==", - "license": "MIT", - "dependencies": { - "tslib": "^2.0.0" - }, - "peerDependencies": { - "react": ">=16.8.0" - } - }, - "node_modules/@dnd-kit/core": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/@dnd-kit/core/-/core-6.3.1.tgz", - "integrity": "sha512-xkGBRQQab4RLwgXxoqETICr6S5JlogafbhNsidmrkVv2YRs5MLwpjoF2qpiGjQt8S9AoxtIV603s0GIUpY5eYQ==", - "license": "MIT", - "dependencies": { - "@dnd-kit/accessibility": "^3.1.1", - "@dnd-kit/utilities": "^3.2.2", - "tslib": "^2.0.0" - }, - "peerDependencies": { - "react": ">=16.8.0", - "react-dom": ">=16.8.0" - } - }, - "node_modules/@dnd-kit/sortable": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@dnd-kit/sortable/-/sortable-8.0.0.tgz", - "integrity": "sha512-U3jk5ebVXe1Lr7c2wU7SBZjcWdQP+j7peHJfCspnA81enlu88Mgd7CC8Q+pub9ubP7eKVETzJW+IBAhsqbSu/g==", - "license": "MIT", - "dependencies": { - "@dnd-kit/utilities": "^3.2.2", - "tslib": "^2.0.0" - }, - "peerDependencies": { - "@dnd-kit/core": "^6.1.0", - "react": ">=16.8.0" - } - }, - "node_modules/@dnd-kit/utilities": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/@dnd-kit/utilities/-/utilities-3.2.2.tgz", - "integrity": "sha512-+MKAJEOfaBe5SmV6t34p80MMKhjvUz0vRrvVJbPT0WElzaOJ/1xs+D+KDv+tD/NE5ujfrChEcshd4fLn0wpiqg==", - "license": "MIT", - "dependencies": { - "tslib": "^2.0.0" - }, - "peerDependencies": { - "react": ">=16.8.0" - } - }, "node_modules/@electric-sql/pglite": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/@electric-sql/pglite/-/pglite-0.4.1.tgz", @@ -977,448 +872,6 @@ "tslib": "^2.4.0" } }, - "node_modules/@esbuild/aix-ppc64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.12.tgz", - "integrity": "sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "aix" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-arm": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.12.tgz", - "integrity": "sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.12.tgz", - "integrity": "sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.12.tgz", - "integrity": "sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/darwin-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.12.tgz", - "integrity": "sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/darwin-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.12.tgz", - "integrity": "sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/freebsd-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.12.tgz", - "integrity": "sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/freebsd-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.12.tgz", - "integrity": "sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-arm": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.12.tgz", - "integrity": "sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.12.tgz", - "integrity": "sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-ia32": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.12.tgz", - "integrity": "sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-loong64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.12.tgz", - "integrity": "sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==", - "cpu": [ - "loong64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-mips64el": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.12.tgz", - "integrity": "sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==", - "cpu": [ - "mips64el" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-ppc64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.12.tgz", - "integrity": "sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-riscv64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.12.tgz", - "integrity": "sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==", - "cpu": [ - "riscv64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-s390x": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.12.tgz", - "integrity": "sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==", - "cpu": [ - "s390x" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.12.tgz", - "integrity": "sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/netbsd-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.12.tgz", - "integrity": "sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/netbsd-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.12.tgz", - "integrity": "sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/openbsd-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.12.tgz", - "integrity": "sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/openbsd-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.12.tgz", - "integrity": "sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/openharmony-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.12.tgz", - "integrity": "sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openharmony" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/sunos-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.12.tgz", - "integrity": "sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/win32-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.12.tgz", - "integrity": "sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/win32-ia32": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.12.tgz", - "integrity": "sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/win32-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.12.tgz", - "integrity": "sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, "node_modules/@eslint-community/eslint-utils": { "version": "4.9.1", "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz", @@ -1647,6 +1100,7 @@ "resolved": "https://registry.npmjs.org/@img/colour/-/colour-1.1.0.tgz", "integrity": "sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ==", "license": "MIT", + "optional": true, "engines": { "node": ">=18" } @@ -2107,34 +1561,6 @@ "url": "https://opencollective.com/libvips" } }, - "node_modules/@isaacs/cliui": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", - "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", - "dev": true, - "license": "ISC", - "dependencies": { - "string-width": "^5.1.2", - "string-width-cjs": "npm:string-width@^4.2.0", - "strip-ansi": "^7.0.1", - "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", - "wrap-ansi": "^8.1.0", - "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@istanbuljs/schema": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.6.tgz", - "integrity": "sha512-+Sg6GCR/wy1oSmQDFq4LQDAhm3ETKnorxN+y5nbLULOR3P0c14f2Wurzj3/xqPXtasLFfHd5iRFQ7AJt4KH2cw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/@jridgewell/gen-mapping": { "version": "0.3.13", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", @@ -2424,17 +1850,6 @@ "url": "https://github.com/sponsors/panva" } }, - "node_modules/@pkgjs/parseargs": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", - "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", - "dev": true, - "license": "MIT", - "optional": true, - "engines": { - "node": ">=14" - } - }, "node_modules/@prisma/adapter-pg": { "version": "7.8.0", "resolved": "https://registry.npmjs.org/@prisma/adapter-pg/-/adapter-pg-7.8.0.tgz", @@ -2816,424 +2231,6 @@ } } }, - "node_modules/@react-email/render": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@react-email/render/-/render-1.1.2.tgz", - "integrity": "sha512-RnRehYN3v9gVlNMehHPHhyp2RQo7+pSkHDtXPvg3s0GbzM9SQMW4Qrf8GRNvtpLC4gsI+Wt0VatNRUFqjvevbw==", - "license": "MIT", - "dependencies": { - "html-to-text": "^9.0.5", - "prettier": "^3.5.3", - "react-promise-suspense": "^0.3.4" - }, - "engines": { - "node": ">=18.0.0" - }, - "peerDependencies": { - "react": "^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^18.0 || ^19.0 || ^19.0.0-rc" - } - }, - "node_modules/@react-leaflet/core": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@react-leaflet/core/-/core-3.0.0.tgz", - "integrity": "sha512-3EWmekh4Nz+pGcr+xjf0KNyYfC3U2JjnkWsh0zcqaexYqmmB5ZhH37kz41JXGmKzpaMZCnPofBBm64i+YrEvGQ==", - "license": "Hippocratic-2.1", - "peerDependencies": { - "leaflet": "^1.9.0", - "react": "^19.0.0", - "react-dom": "^19.0.0" - } - }, - "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.60.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.60.4.tgz", - "integrity": "sha512-F5QXMSiFebS9hKZj02XhWLLnRpJ3B3AROP0tWbFBSj+6kCbg5m9j5JoHKd4mmSVy5mS/IMQloYgYxCuJC0fxEQ==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@rollup/rollup-android-arm64": { - "version": "4.60.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.60.4.tgz", - "integrity": "sha512-GxxTKApUpzRhof7poWvCJHRF51C67u1R7D6DiluBE8wKU1u5GWE8t+v81JvJYtbawoBFX1hLv5Ei4eVjkWokaw==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.60.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.60.4.tgz", - "integrity": "sha512-tua0TaJxMOB1R0V0RS1jFZ/RpURFDJIOR2A6jWwQeawuFyS4gBW+rntLRaQd0EQ4bd6Vp44Z2rXW+YYDBsj6IA==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.60.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.60.4.tgz", - "integrity": "sha512-CSKq7MsP+5PFIcydhAiR1K0UhEI1A2jWXVKHPCBZ151yOutENwvnPocgVHkivu2kviURtCEB6zUQw0vs8RrhMg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@rollup/rollup-freebsd-arm64": { - "version": "4.60.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.60.4.tgz", - "integrity": "sha512-+O8OkVdyvXMtJEciu2wS/pzm1IxntEEQx3z5TAVy4l32G0etZn+RsA48ARRrFm6Ri8fvqPQfgrvNxSjKAbnd3g==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ] - }, - "node_modules/@rollup/rollup-freebsd-x64": { - "version": "4.60.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.60.4.tgz", - "integrity": "sha512-Iw3oMskH3AfNuhU0MSN7vNbdi4me/NiYo2azqPz/Le16zHSa+3RRmliCMWWQmh4lcndccU40xcJuTYJZxNo/lw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ] - }, - "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.60.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.60.4.tgz", - "integrity": "sha512-EIPRXTVQpHyF8WOo219AD2yEltPehLTcTMz2fn6JsatLYSzQf00hj3rulF+yauOlF9/FtM2WpkT/hJh/KJFGhA==", - "cpu": [ - "arm" - ], - "dev": true, - "libc": [ - "glibc" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.60.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.60.4.tgz", - "integrity": "sha512-J3Yh9PzzF1Ovah2At+lHiGQdsYgArxBbXv/zHfSyaiFQEqvNv7DcW98pCrmdjCZBrqBiKrKKe2V+aaSGWuBe/w==", - "cpu": [ - "arm" - ], - "dev": true, - "libc": [ - "musl" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.60.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.60.4.tgz", - "integrity": "sha512-BFDEZMYfUvLn37ONE1yMBojPxnMlTFsdyNoqncT0qFq1mAfllL+ATMMJd8TeuVMiX84s1KbcxcZbXInmcO2mRg==", - "cpu": [ - "arm64" - ], - "dev": true, - "libc": [ - "glibc" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.60.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.60.4.tgz", - "integrity": "sha512-pc9EYOSlOgdQ2uPl1o9PF6/kLSgaUosia7gOuS8mB69IxJvlclko1MECXysjs5ryez1/5zjYqx3+xYU0TU6R1A==", - "cpu": [ - "arm64" - ], - "dev": true, - "libc": [ - "musl" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-loong64-gnu": { - "version": "4.60.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.60.4.tgz", - "integrity": "sha512-NxnomyxYerDh5n4iLrNa+sH+Z+U4BMEE46V2PgQ/hoB909i8gV1M5wPojWg9fk1jWpO3IQnOs20K4wyZuFLEFQ==", - "cpu": [ - "loong64" - ], - "dev": true, - "libc": [ - "glibc" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-loong64-musl": { - "version": "4.60.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.60.4.tgz", - "integrity": "sha512-nbJnQ8a3z1mtmrwImCYhc6BGpThAyYVRQxw9uKSKG4wR6aAYno9sVjJ0zaZcW9BPJX1GbrDPf+SvdWjgTuDmnw==", - "cpu": [ - "loong64" - ], - "dev": true, - "libc": [ - "musl" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-ppc64-gnu": { - "version": "4.60.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.60.4.tgz", - "integrity": "sha512-2EU6acNrQLd8tYvo/LXW535wupT3m6fo7HKo6lr7ktQoItxTyOL1ZCR/GfGCuXl2vR+zmfI6eRXkSemafv+iVg==", - "cpu": [ - "ppc64" - ], - "dev": true, - "libc": [ - "glibc" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-ppc64-musl": { - "version": "4.60.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.60.4.tgz", - "integrity": "sha512-WeBtoMuaMxiiIrO2IYP3xs6GMWkJP2C0EoT8beTLkUPmzV1i/UcOSVw1d5r9KBODtHKilG5yFxsGRnBbK3wJ4A==", - "cpu": [ - "ppc64" - ], - "dev": true, - "libc": [ - "musl" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.60.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.60.4.tgz", - "integrity": "sha512-FJHFfqpKUI3A10WrWKiFbBZ7yVbGT4q4B5o1qKFFojqpaYoh9LrQgqWCmmcxQzVSXYtyB5bzkXrYzlHTs21MYA==", - "cpu": [ - "riscv64" - ], - "dev": true, - "libc": [ - "glibc" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-riscv64-musl": { - "version": "4.60.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.60.4.tgz", - "integrity": "sha512-mcEl6CUT5IAUmQf1m9FYSmVqCJlpQ8r8eyftFUHG8i9OhY7BkBXSUdnLH5DOf0wCOjcP9v/QO93zpmF1SptCCw==", - "cpu": [ - "riscv64" - ], - "dev": true, - "libc": [ - "musl" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.60.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.60.4.tgz", - "integrity": "sha512-ynt3JxVd2w2buzoKDWIyiV1pJW93xlQic1THVLXilz429oijRpSHivZAgp65KBu+cMcgf1eVVjdnTLvPxgCuoQ==", - "cpu": [ - "s390x" - ], - "dev": true, - "libc": [ - "glibc" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.60.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.60.4.tgz", - "integrity": "sha512-Boiz5+MsaROEWDf+GGEwF8VMHGhlUoQMtIPjOgA5fv4osupqTVnJteQNKJwUcnUog2G55jYXH7KZFFiJe0TEzQ==", - "cpu": [ - "x64" - ], - "dev": true, - "libc": [ - "glibc" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.60.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.60.4.tgz", - "integrity": "sha512-+qfSY27qIrFfI/Hom04KYFw3GKZSGU4lXus51wsb5EuySfFlWRwjkKWoE9emgRw/ukoT4Udsj4W/+xxG8VbPKg==", - "cpu": [ - "x64" - ], - "dev": true, - "libc": [ - "musl" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-openbsd-x64": { - "version": "4.60.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.60.4.tgz", - "integrity": "sha512-VpTfOPHgVXEBeeR8hZ2O0F3aSso+JDWqTWmTmzcQKted54IAdUVbxE+j/MVxUsKa8L20HJhv3vUezVPoquqWjA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ] - }, - "node_modules/@rollup/rollup-openharmony-arm64": { - "version": "4.60.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.60.4.tgz", - "integrity": "sha512-IPOsh5aRYuLv/nkU51X10Bf75Bsf6+gZdx1X+QP5QM6lIJFHHqbHLG0uJn/hWthzo13UAc2umiUorqZy3axoZg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openharmony" - ] - }, - "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.60.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.60.4.tgz", - "integrity": "sha512-4QzE9E81OohJ/HKzHhsqU+zcYYojVOXlFMs1DdyMT6qXl/niOH7AVElmmEdUNHHS/oRkc++d5k6Vy85zFs0DEw==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.60.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.60.4.tgz", - "integrity": "sha512-zTPgT1YuHHcd+Tmx7h8aml0FWFVelV5N54oHow9SLj+GfoDy/huQ+UV396N/C7KpMDMiPspRktzM1/0r1usYEA==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rollup/rollup-win32-x64-gnu": { - "version": "4.60.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.60.4.tgz", - "integrity": "sha512-DRS4G7mi9lJxqEDezIkKCaUIKCrLUUDCUaCsTPCi/rtqaC6D/jjwslMQyiDU50Ka0JKpeXeRBFBAXwArY52vBw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.60.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.60.4.tgz", - "integrity": "sha512-QVTUovf40zgTqlFVrKA1uXMVvU2QWEFWfAH8Wdc48IxLvrJMQVMBRjuQyUpzZCDkakImib9eVazbWlC6ksWtJw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, "node_modules/@rtsao/scc": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz", @@ -3241,19 +2238,6 @@ "dev": true, "license": "MIT" }, - "node_modules/@selderee/plugin-htmlparser2": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/@selderee/plugin-htmlparser2/-/plugin-htmlparser2-0.11.0.tgz", - "integrity": "sha512-P33hHGdldxGabLFjPPpaTxVolMrzrcegejx+0GxjrIb9Zv48D8yAIA/QTDR2dFl7Uz7urX8aX6+5bCZslr+gWQ==", - "license": "MIT", - "dependencies": { - "domhandler": "^5.0.3", - "selderee": "^0.11.0" - }, - "funding": { - "url": "https://ko-fi.com/killymxi" - } - }, "node_modules/@smithy/core": { "version": "3.24.5", "resolved": "https://registry.npmjs.org/@smithy/core/-/core-3.24.5.tgz", @@ -3672,24 +2656,6 @@ "tslib": "^2.4.0" } }, - "node_modules/@types/chai": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.2.3.tgz", - "integrity": "sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/deep-eql": "*", - "assertion-error": "^2.0.1" - } - }, - "node_modules/@types/deep-eql": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@types/deep-eql/-/deep-eql-4.0.2.tgz", - "integrity": "sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==", - "dev": true, - "license": "MIT" - }, "node_modules/@types/estree": { "version": "1.0.9", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.9.tgz", @@ -3697,12 +2663,6 @@ "dev": true, "license": "MIT" }, - "node_modules/@types/geojson": { - "version": "7946.0.16", - "resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.16.tgz", - "integrity": "sha512-6C8nqWur3j98U6+lXDfTUWIfgvZU+EumvpHKcYjujKH7woYyLj2sUmff0tRhrqM7BohUw7Pz3ZB1jj2gW9Fvmg==", - "license": "MIT" - }, "node_modules/@types/json-schema": { "version": "7.0.15", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", @@ -3717,15 +2677,6 @@ "dev": true, "license": "MIT" }, - "node_modules/@types/leaflet": { - "version": "1.9.21", - "resolved": "https://registry.npmjs.org/@types/leaflet/-/leaflet-1.9.21.tgz", - "integrity": "sha512-TbAd9DaPGSnzp6QvtYngntMZgcRk+igFELwR2N99XZn7RXUdKgsXMR+28bUO0rPsWp8MIu/f47luLIQuSLYv/w==", - "license": "MIT", - "dependencies": { - "@types/geojson": "*" - } - }, "node_modules/@types/node": { "version": "20.19.41", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.41.tgz", @@ -3760,7 +2711,7 @@ "version": "19.2.3", "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.2.3.tgz", "integrity": "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==", - "devOptional": true, + "dev": true, "license": "MIT", "peerDependencies": { "@types/react": "^19.2.0" @@ -4374,155 +3325,6 @@ "win32" ] }, - "node_modules/@vitest/coverage-v8": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-3.2.4.tgz", - "integrity": "sha512-EyF9SXU6kS5Ku/U82E259WSnvg6c8KTjppUncuNdm5QHpe17mwREHnjDzozC8x9MZ0xfBUFSaLkRv4TMA75ALQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@ampproject/remapping": "^2.3.0", - "@bcoe/v8-coverage": "^1.0.2", - "ast-v8-to-istanbul": "^0.3.3", - "debug": "^4.4.1", - "istanbul-lib-coverage": "^3.2.2", - "istanbul-lib-report": "^3.0.1", - "istanbul-lib-source-maps": "^5.0.6", - "istanbul-reports": "^3.1.7", - "magic-string": "^0.30.17", - "magicast": "^0.3.5", - "std-env": "^3.9.0", - "test-exclude": "^7.0.1", - "tinyrainbow": "^2.0.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" - }, - "peerDependencies": { - "@vitest/browser": "3.2.4", - "vitest": "3.2.4" - }, - "peerDependenciesMeta": { - "@vitest/browser": { - "optional": true - } - } - }, - "node_modules/@vitest/expect": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-3.2.4.tgz", - "integrity": "sha512-Io0yyORnB6sikFlt8QW5K7slY4OjqNX9jmJQ02QDda8lyM6B5oNgVWoSoKPac8/kgnCUzuHQKrSLtu/uOqqrig==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/chai": "^5.2.2", - "@vitest/spy": "3.2.4", - "@vitest/utils": "3.2.4", - "chai": "^5.2.0", - "tinyrainbow": "^2.0.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, - "node_modules/@vitest/mocker": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-3.2.4.tgz", - "integrity": "sha512-46ryTE9RZO/rfDd7pEqFl7etuyzekzEhUbTW3BvmeO/BcCMEgq59BKhek3dXDWgAj4oMK6OZi+vRr1wPW6qjEQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@vitest/spy": "3.2.4", - "estree-walker": "^3.0.3", - "magic-string": "^0.30.17" - }, - "funding": { - "url": "https://opencollective.com/vitest" - }, - "peerDependencies": { - "msw": "^2.4.9", - "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0" - }, - "peerDependenciesMeta": { - "msw": { - "optional": true - }, - "vite": { - "optional": true - } - } - }, - "node_modules/@vitest/pretty-format": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-3.2.4.tgz", - "integrity": "sha512-IVNZik8IVRJRTr9fxlitMKeJeXFFFN0JaB9PHPGQ8NKQbGpfjlTx9zO4RefN8gp7eqjNy8nyK3NZmBzOPeIxtA==", - "dev": true, - "license": "MIT", - "dependencies": { - "tinyrainbow": "^2.0.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, - "node_modules/@vitest/runner": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-3.2.4.tgz", - "integrity": "sha512-oukfKT9Mk41LreEW09vt45f8wx7DordoWUZMYdY/cyAk7w5TWkTRCNZYF7sX7n2wB7jyGAl74OxgwhPgKaqDMQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@vitest/utils": "3.2.4", - "pathe": "^2.0.3", - "strip-literal": "^3.0.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, - "node_modules/@vitest/snapshot": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-3.2.4.tgz", - "integrity": "sha512-dEYtS7qQP2CjU27QBC5oUOxLE/v5eLkGqPE0ZKEIDGMs4vKWe7IjgLOeauHsR0D5YuuycGRO5oSRXnwnmA78fQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@vitest/pretty-format": "3.2.4", - "magic-string": "^0.30.17", - "pathe": "^2.0.3" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, - "node_modules/@vitest/spy": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-3.2.4.tgz", - "integrity": "sha512-vAfasCOe6AIK70iP5UD11Ac4siNUNJ9i/9PZ3NKx07sG6sUxeag1LWdNrMWeKKYBLlzuK+Gn65Yd5nyL6ds+nw==", - "dev": true, - "license": "MIT", - "dependencies": { - "tinyspy": "^4.0.3" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, - "node_modules/@vitest/utils": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-3.2.4.tgz", - "integrity": "sha512-fB2V0JFrQSMsCo9HiSq3Ezpdv4iYaXRG1Sx8edX3MwxfyNn83mKiGzOcH+Fkxt4MHxr3y42fQi1oeAInqgX2QA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@vitest/pretty-format": "3.2.4", - "loupe": "^3.1.4", - "tinyrainbow": "^2.0.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, "node_modules/acorn": { "version": "8.16.0", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz", @@ -4563,19 +3365,6 @@ "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/ansi-regex": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", - "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, "node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", @@ -4769,16 +3558,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/assertion-error": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", - "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - } - }, "node_modules/ast-types-flow": { "version": "0.0.8", "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.8.tgz", @@ -4786,25 +3565,6 @@ "dev": true, "license": "MIT" }, - "node_modules/ast-v8-to-istanbul": { - "version": "0.3.12", - "resolved": "https://registry.npmjs.org/ast-v8-to-istanbul/-/ast-v8-to-istanbul-0.3.12.tgz", - "integrity": "sha512-BRRC8VRZY2R4Z4lFIL35MwNXmwVqBityvOIwETtsCSwvjl0IdgFsy9NhdaA6j74nUdtJJlIypeRhpDam19Wq3g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/trace-mapping": "^0.3.31", - "estree-walker": "^3.0.3", - "js-tokens": "^10.0.0" - } - }, - "node_modules/ast-v8-to-istanbul/node_modules/js-tokens": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-10.0.0.tgz", - "integrity": "sha512-lM/UBzQmfJRo9ABXbPWemivdCW8V2G8FHaHdypQaIy523snUjog0W71ayWXTjiR+ixeMyVHN2XcpnTd/liPg/Q==", - "dev": true, - "license": "MIT" - }, "node_modules/async-function": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/async-function/-/async-function-1.0.0.tgz", @@ -4989,16 +3749,6 @@ } } }, - "node_modules/cac": { - "version": "6.7.14", - "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", - "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/call-bind": { "version": "1.0.9", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.9.tgz", @@ -5077,23 +3827,6 @@ ], "license": "CC-BY-4.0" }, - "node_modules/chai": { - "version": "5.3.3", - "resolved": "https://registry.npmjs.org/chai/-/chai-5.3.3.tgz", - "integrity": "sha512-4zNhdJD/iOjSH0A05ea+Ke6MU5mmpQcbQsSOkgdaUMJ9zTlDTD/GYlwohmIE2u0gaxHYiVHEn1Fw9mZ/ktJWgw==", - "dev": true, - "license": "MIT", - "dependencies": { - "assertion-error": "^2.0.1", - "check-error": "^2.1.1", - "deep-eql": "^5.0.1", - "loupe": "^3.1.0", - "pathval": "^2.0.0" - }, - "engines": { - "node": ">=18" - } - }, "node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -5124,16 +3857,6 @@ "pnpm": ">=8" } }, - "node_modules/check-error": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.3.tgz", - "integrity": "sha512-PAJdDJusoxnwm1VwW07VWwUN1sl7smmC3OKggvndJFadxxDRyFJBX/ggnu/KE4kQAB7a3Dp8f/YXC1FlUprWmA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 16" - } - }, "node_modules/chokidar": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-5.0.0.tgz", @@ -5298,16 +4021,6 @@ } } }, - "node_modules/deep-eql": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz", - "integrity": "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, "node_modules/deep-is": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", @@ -5315,15 +4028,6 @@ "dev": true, "license": "MIT" }, - "node_modules/deepmerge": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", - "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/deepmerge-ts": { "version": "7.1.5", "resolved": "https://registry.npmjs.org/deepmerge-ts/-/deepmerge-ts-7.1.5.tgz", @@ -5398,6 +4102,7 @@ "version": "2.1.2", "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", + "devOptional": true, "license": "Apache-2.0", "engines": { "node": ">=8" @@ -5416,61 +4121,6 @@ "node": ">=0.10.0" } }, - "node_modules/dom-serializer": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", - "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", - "license": "MIT", - "dependencies": { - "domelementtype": "^2.3.0", - "domhandler": "^5.0.2", - "entities": "^4.2.0" - }, - "funding": { - "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" - } - }, - "node_modules/domelementtype": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", - "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/fb55" - } - ], - "license": "BSD-2-Clause" - }, - "node_modules/domhandler": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", - "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", - "license": "BSD-2-Clause", - "dependencies": { - "domelementtype": "^2.3.0" - }, - "engines": { - "node": ">= 4" - }, - "funding": { - "url": "https://github.com/fb55/domhandler?sponsor=1" - } - }, - "node_modules/domutils": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz", - "integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==", - "license": "BSD-2-Clause", - "dependencies": { - "dom-serializer": "^2.0.0", - "domelementtype": "^2.3.0", - "domhandler": "^5.0.3" - }, - "funding": { - "url": "https://github.com/fb55/domutils?sponsor=1" - } - }, "node_modules/dotenv": { "version": "17.4.2", "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-17.4.2.tgz", @@ -5498,13 +4148,6 @@ "node": ">= 0.4" } }, - "node_modules/eastasianwidth": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", - "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", - "dev": true, - "license": "MIT" - }, "node_modules/effect": { "version": "3.20.0", "resolved": "https://registry.npmjs.org/effect/-/effect-3.20.0.tgz", @@ -5554,18 +4197,6 @@ "node": ">=10.13.0" } }, - "node_modules/entities": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", - "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", - "license": "BSD-2-Clause", - "engines": { - "node": ">=0.12" - }, - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, "node_modules/env-paths": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-3.0.0.tgz", @@ -5694,13 +4325,6 @@ "node": ">= 0.4" } }, - "node_modules/es-module-lexer": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.7.0.tgz", - "integrity": "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==", - "dev": true, - "license": "MIT" - }, "node_modules/es-object-atoms": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.2.tgz", @@ -5760,48 +4384,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/esbuild": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.12.tgz", - "integrity": "sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=18" - }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.25.12", - "@esbuild/android-arm": "0.25.12", - "@esbuild/android-arm64": "0.25.12", - "@esbuild/android-x64": "0.25.12", - "@esbuild/darwin-arm64": "0.25.12", - "@esbuild/darwin-x64": "0.25.12", - "@esbuild/freebsd-arm64": "0.25.12", - "@esbuild/freebsd-x64": "0.25.12", - "@esbuild/linux-arm": "0.25.12", - "@esbuild/linux-arm64": "0.25.12", - "@esbuild/linux-ia32": "0.25.12", - "@esbuild/linux-loong64": "0.25.12", - "@esbuild/linux-mips64el": "0.25.12", - "@esbuild/linux-ppc64": "0.25.12", - "@esbuild/linux-riscv64": "0.25.12", - "@esbuild/linux-s390x": "0.25.12", - "@esbuild/linux-x64": "0.25.12", - "@esbuild/netbsd-arm64": "0.25.12", - "@esbuild/netbsd-x64": "0.25.12", - "@esbuild/openbsd-arm64": "0.25.12", - "@esbuild/openbsd-x64": "0.25.12", - "@esbuild/openharmony-arm64": "0.25.12", - "@esbuild/sunos-x64": "0.25.12", - "@esbuild/win32-arm64": "0.25.12", - "@esbuild/win32-ia32": "0.25.12", - "@esbuild/win32-x64": "0.25.12" - } - }, "node_modules/escalade": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", @@ -6221,16 +4803,6 @@ "node": ">=4.0" } }, - "node_modules/estree-walker": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", - "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/estree": "^1.0.0" - } - }, "node_modules/esutils": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", @@ -6241,16 +4813,6 @@ "node": ">=0.10.0" } }, - "node_modules/expect-type": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.3.0.tgz", - "integrity": "sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=12.0.0" - } - }, "node_modules/exsolve": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/exsolve/-/exsolve-1.0.8.tgz", @@ -6493,21 +5055,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, "node_modules/function-bind": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", @@ -6663,28 +5210,6 @@ "giget": "dist/cli.mjs" } }, - "node_modules/glob": { - "version": "10.5.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", - "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==", - "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", - "dev": true, - "license": "ISC", - "dependencies": { - "foreground-child": "^3.1.0", - "jackspeak": "^3.1.2", - "minimatch": "^9.0.4", - "minipass": "^7.1.2", - "package-json-from-dist": "^1.0.0", - "path-scurry": "^1.11.1" - }, - "bin": { - "glob": "dist/esm/bin.mjs" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/glob-parent": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", @@ -6698,32 +5223,6 @@ "node": ">=10.13.0" } }, - "node_modules/glob/node_modules/brace-expansion": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.1.tgz", - "integrity": "sha512-WR1cURNjuvBLMZBMbqM0UoE+WAfdUcEV1ccD8PVBVOI+Z3ND4+SZbN8RsfT2bMuG1qwz5RFvPukSZm5fF2D5eA==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/glob/node_modules/minimatch": { - "version": "9.0.9", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz", - "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^2.0.2" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/globals": { "version": "14.0.0", "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", @@ -6906,48 +5405,6 @@ "node": ">=16.9.0" } }, - "node_modules/html-escaper": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", - "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", - "dev": true, - "license": "MIT" - }, - "node_modules/html-to-text": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/html-to-text/-/html-to-text-9.0.5.tgz", - "integrity": "sha512-qY60FjREgVZL03vJU6IfMV4GDjGBIoOyvuFdpBDIX9yTlDw0TjxVBQp+P8NvpdIXNJvfWBTNul7fsAQJq2FNpg==", - "license": "MIT", - "dependencies": { - "@selderee/plugin-htmlparser2": "^0.11.0", - "deepmerge": "^4.3.1", - "dom-serializer": "^2.0.0", - "htmlparser2": "^8.0.2", - "selderee": "^0.11.0" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/htmlparser2": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.2.tgz", - "integrity": "sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==", - "funding": [ - "https://github.com/fb55/htmlparser2?sponsor=1", - { - "type": "github", - "url": "https://github.com/sponsors/fb55" - } - ], - "license": "MIT", - "dependencies": { - "domelementtype": "^2.3.0", - "domhandler": "^5.0.3", - "domutils": "^3.0.1", - "entities": "^4.4.0" - } - }, "node_modules/http-status-codes": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/http-status-codes/-/http-status-codes-2.3.0.tgz", @@ -7208,16 +5665,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/is-generator-function": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.2.tgz", @@ -7470,60 +5917,6 @@ "devOptional": true, "license": "ISC" }, - "node_modules/istanbul-lib-coverage": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", - "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", - "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-report": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", - "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "istanbul-lib-coverage": "^3.0.0", - "make-dir": "^4.0.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/istanbul-lib-source-maps": { - "version": "5.0.6", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-5.0.6.tgz", - "integrity": "sha512-yg2d+Em4KizZC5niWhQaIomgf5WlL4vOOjZ5xGCmF8SnPE/mDWWXgvRExdcpCgh9lLRRa1/fSYp2ymmbJ1pI+A==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "@jridgewell/trace-mapping": "^0.3.23", - "debug": "^4.1.1", - "istanbul-lib-coverage": "^3.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/istanbul-reports": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.2.0.tgz", - "integrity": "sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "html-escaper": "^2.0.0", - "istanbul-lib-report": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/iterator.prototype": { "version": "1.1.5", "resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.5.tgz", @@ -7542,22 +5935,6 @@ "node": ">= 0.4" } }, - "node_modules/jackspeak": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", - "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", - "dev": true, - "license": "BlueOak-1.0.0", - "dependencies": { - "@isaacs/cliui": "^8.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - }, - "optionalDependencies": { - "@pkgjs/parseargs": "^0.11.0" - } - }, "node_modules/jiti": { "version": "2.7.0", "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.7.0.tgz", @@ -7690,21 +6067,6 @@ "node": ">=0.10" } }, - "node_modules/leac": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/leac/-/leac-0.6.0.tgz", - "integrity": "sha512-y+SqErxb8h7nE/fiEX07jsbuhrpO9lL8eca7/Y1nuWV2moNlXhyd59iDGcRf6moVyDMbmTNzL40SUyrFU/yDpg==", - "license": "MIT", - "funding": { - "url": "https://ko-fi.com/killymxi" - } - }, - "node_modules/leaflet": { - "version": "1.9.4", - "resolved": "https://registry.npmjs.org/leaflet/-/leaflet-1.9.4.tgz", - "integrity": "sha512-nxS1ynzJOmOlHp+iL3FyWqK89GtNL8U8rvlMOsQdTTssxZwCXh8N2NB3GDQOL+YR3XnWyZAxwQixURb+FA74PA==", - "license": "BSD-2-Clause" - }, "node_modules/levn": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", @@ -8023,13 +6385,6 @@ "loose-envify": "cli.js" } }, - "node_modules/loupe": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.2.1.tgz", - "integrity": "sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ==", - "dev": true, - "license": "MIT" - }, "node_modules/lru-cache": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", @@ -8066,47 +6421,6 @@ "@jridgewell/sourcemap-codec": "^1.5.5" } }, - "node_modules/magicast": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/magicast/-/magicast-0.3.5.tgz", - "integrity": "sha512-L0WhttDl+2BOsybvEOLK7fW3UA0OQ0IQ2d6Zl2x/a6vVRs3bAY0ECOSHHeL5jD+SbOpOCUEi0y1DgHEn9Qn1AQ==", - "devOptional": true, - "license": "MIT", - "dependencies": { - "@babel/parser": "^7.25.4", - "@babel/types": "^7.25.4", - "source-map-js": "^1.2.0" - } - }, - "node_modules/make-dir": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", - "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", - "dev": true, - "license": "MIT", - "dependencies": { - "semver": "^7.5.3" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/make-dir/node_modules/semver": { - "version": "7.8.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.1.tgz", - "integrity": "sha512-rkVq3IXh+4FDGch+KwzX3aV9W3kO54GyEgpvBzSyctDA6Xtd7RJQV1xmXbeQp5v7+VzLOfVqiutSE6GICgPFvg==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/math-intrinsics": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", @@ -8163,16 +6477,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/minipass": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.3.tgz", - "integrity": "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==", - "dev": true, - "license": "BlueOak-1.0.0", - "engines": { - "node": ">=16 || 14 >=14.17" - } - }, "node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", @@ -8598,13 +6902,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/package-json-from-dist": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", - "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", - "dev": true, - "license": "BlueOak-1.0.0" - }, "node_modules/parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", @@ -8618,19 +6915,6 @@ "node": ">=6" } }, - "node_modules/parseley": { - "version": "0.12.1", - "resolved": "https://registry.npmjs.org/parseley/-/parseley-0.12.1.tgz", - "integrity": "sha512-e6qHKe3a9HWr0oMRVDTRhKce+bRO8VGQR3NyVwcjwrbhMmFCX9KszEV35+rn4AdilFAq9VPxP/Fe1wC9Qjd2lw==", - "license": "MIT", - "dependencies": { - "leac": "^0.6.0", - "peberminta": "^0.9.0" - }, - "funding": { - "url": "https://ko-fi.com/killymxi" - } - }, "node_modules/path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -8673,30 +6957,6 @@ "dev": true, "license": "MIT" }, - "node_modules/path-scurry": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", - "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", - "dev": true, - "license": "BlueOak-1.0.0", - "dependencies": { - "lru-cache": "^10.2.0", - "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" - }, - "engines": { - "node": ">=16 || 14 >=14.18" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/path-scurry/node_modules/lru-cache": { - "version": "10.4.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", - "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", - "dev": true, - "license": "ISC" - }, "node_modules/pathe": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", @@ -8704,25 +6964,6 @@ "devOptional": true, "license": "MIT" }, - "node_modules/pathval": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-2.0.1.tgz", - "integrity": "sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 14.16" - } - }, - "node_modules/peberminta": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/peberminta/-/peberminta-0.9.0.tgz", - "integrity": "sha512-XIxfHpEuSJbITd1H3EeQwpcZbTLHc+VVr8ANI9t5sit565tsI4/xK3KWTUFE2e6QiangUkh3B0jihzmGnNrRsQ==", - "license": "MIT", - "funding": { - "url": "https://ko-fi.com/killymxi" - } - }, "node_modules/perfect-debounce": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/perfect-debounce/-/perfect-debounce-2.1.0.tgz", @@ -8980,21 +7221,6 @@ "node": ">= 0.8.0" } }, - "node_modules/prettier": { - "version": "3.8.3", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.8.3.tgz", - "integrity": "sha512-7igPTM53cGHMW8xWuVTydi2KO233VFiTNyF5hLJqpilHfmn8C8gPf+PS7dUT64YcXFbiMGZxS9pCSxL/Dxm/Jw==", - "license": "MIT", - "bin": { - "prettier": "bin/prettier.cjs" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/prettier/prettier?sponsor=1" - } - }, "node_modules/prisma": { "version": "7.8.0", "resolved": "https://registry.npmjs.org/prisma/-/prisma-7.8.0.tgz", @@ -9162,35 +7388,6 @@ "dev": true, "license": "MIT" }, - "node_modules/react-leaflet": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/react-leaflet/-/react-leaflet-5.0.0.tgz", - "integrity": "sha512-CWbTpr5vcHw5bt9i4zSlPEVQdTVcML390TjeDG0cK59z1ylexpqC6M1PJFjV8jD7CF+ACBFsLIDs6DRMoLEofw==", - "license": "Hippocratic-2.1", - "dependencies": { - "@react-leaflet/core": "^3.0.0" - }, - "peerDependencies": { - "leaflet": "^1.9.0", - "react": "^19.0.0", - "react-dom": "^19.0.0" - } - }, - "node_modules/react-promise-suspense": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/react-promise-suspense/-/react-promise-suspense-0.3.4.tgz", - "integrity": "sha512-I42jl7L3Ze6kZaq+7zXWSunBa3b1on5yfvUW6Eo/3fFOj6dZ5Bqmcd264nJbTK/gn1HjjILAjSwnZbV4RpSaNQ==", - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^2.0.1" - } - }, - "node_modules/react-promise-suspense/node_modules/fast-deep-equal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", - "integrity": "sha512-bCK/2Z4zLidyB4ReuIsvALH6w31YfAQDmXMqMx6FyfHqvBxtjC0eRumeSu4Bs3XtXwpyIywtSTrVT99BxY1f9w==", - "license": "MIT" - }, "node_modules/readdirp": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-5.0.0.tgz", @@ -9269,18 +7466,6 @@ "node": ">=0.10.0" } }, - "node_modules/resend": { - "version": "4.8.0", - "resolved": "https://registry.npmjs.org/resend/-/resend-4.8.0.tgz", - "integrity": "sha512-R8eBOFQDO6dzRTDmaMEdpqrkmgSjPpVXt4nGfWsZdYOet0kqra0xgbvTES6HmCriZEXbmGk3e0DiGIaLFTFSHA==", - "license": "MIT", - "dependencies": { - "@react-email/render": "1.1.2" - }, - "engines": { - "node": ">=18" - } - }, "node_modules/resolve": { "version": "2.0.0-next.7", "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.7.tgz", @@ -9346,58 +7531,6 @@ "node": ">=0.10.0" } }, - "node_modules/rollup": { - "version": "4.60.4", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.60.4.tgz", - "integrity": "sha512-WHeFSbZYsPu3+bLoNRUuAO+wavNlocOPf3wSHTP7hcFKVnJeWsYlCDbr3mTS14FCizf9ccIxXA8sGL8zKeQN3g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/estree": "1.0.8" - }, - "bin": { - "rollup": "dist/bin/rollup" - }, - "engines": { - "node": ">=18.0.0", - "npm": ">=8.0.0" - }, - "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.60.4", - "@rollup/rollup-android-arm64": "4.60.4", - "@rollup/rollup-darwin-arm64": "4.60.4", - "@rollup/rollup-darwin-x64": "4.60.4", - "@rollup/rollup-freebsd-arm64": "4.60.4", - "@rollup/rollup-freebsd-x64": "4.60.4", - "@rollup/rollup-linux-arm-gnueabihf": "4.60.4", - "@rollup/rollup-linux-arm-musleabihf": "4.60.4", - "@rollup/rollup-linux-arm64-gnu": "4.60.4", - "@rollup/rollup-linux-arm64-musl": "4.60.4", - "@rollup/rollup-linux-loong64-gnu": "4.60.4", - "@rollup/rollup-linux-loong64-musl": "4.60.4", - "@rollup/rollup-linux-ppc64-gnu": "4.60.4", - "@rollup/rollup-linux-ppc64-musl": "4.60.4", - "@rollup/rollup-linux-riscv64-gnu": "4.60.4", - "@rollup/rollup-linux-riscv64-musl": "4.60.4", - "@rollup/rollup-linux-s390x-gnu": "4.60.4", - "@rollup/rollup-linux-x64-gnu": "4.60.4", - "@rollup/rollup-linux-x64-musl": "4.60.4", - "@rollup/rollup-openbsd-x64": "4.60.4", - "@rollup/rollup-openharmony-arm64": "4.60.4", - "@rollup/rollup-win32-arm64-msvc": "4.60.4", - "@rollup/rollup-win32-ia32-msvc": "4.60.4", - "@rollup/rollup-win32-x64-gnu": "4.60.4", - "@rollup/rollup-win32-x64-msvc": "4.60.4", - "fsevents": "~2.3.2" - } - }, - "node_modules/rollup/node_modules/@types/estree": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", - "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", - "dev": true, - "license": "MIT" - }, "node_modules/run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", @@ -9490,18 +7623,6 @@ "integrity": "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==", "license": "MIT" }, - "node_modules/selderee": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/selderee/-/selderee-0.11.0.tgz", - "integrity": "sha512-5TF+l7p4+OsnP8BCCvSyZiSPc4x4//p5uPwK8TCnVPJYRmU2aYKMpOXvw8zM5a5JvuuCGN1jmsMwuU2W02ukfA==", - "license": "MIT", - "dependencies": { - "parseley": "^0.12.0" - }, - "funding": { - "url": "https://ko-fi.com/killymxi" - } - }, "node_modules/semver": { "version": "6.3.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", @@ -9573,6 +7694,7 @@ "integrity": "sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg==", "hasInstallScript": true, "license": "Apache-2.0", + "optional": true, "dependencies": { "@img/colour": "^1.0.0", "detect-libc": "^2.1.2", @@ -9616,6 +7738,7 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.1.tgz", "integrity": "sha512-rkVq3IXh+4FDGch+KwzX3aV9W3kO54GyEgpvBzSyctDA6Xtd7RJQV1xmXbeQp5v7+VzLOfVqiutSE6GICgPFvg==", "license": "ISC", + "optional": true, "bin": { "semver": "bin/semver.js" }, @@ -9718,13 +7841,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/siginfo": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", - "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", - "dev": true, - "license": "ISC" - }, "node_modules/signal-exit": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", @@ -9773,13 +7889,6 @@ "dev": true, "license": "MIT" }, - "node_modules/stackback": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", - "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", - "dev": true, - "license": "MIT" - }, "node_modules/std-env": { "version": "3.10.0", "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.10.0.tgz", @@ -9801,70 +7910,6 @@ "node": ">= 0.4" } }, - "node_modules/string-width": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", - "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", - "dev": true, - "license": "MIT", - "dependencies": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/string-width-cjs": { - "name": "string-width", - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/string-width-cjs/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/string-width-cjs/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true, - "license": "MIT" - }, - "node_modules/string-width-cjs/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/string.prototype.includes": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/string.prototype.includes/-/string.prototype.includes-2.0.1.tgz", @@ -9978,46 +8023,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/strip-ansi": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", - "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^6.2.2" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, - "node_modules/strip-ansi-cjs": { - "name": "strip-ansi", - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-ansi-cjs/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/strip-bom": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", @@ -10041,26 +8046,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/strip-literal": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-3.1.0.tgz", - "integrity": "sha512-8r3mkIM/2+PpjHoOtiAW8Rg3jJLHaV7xPwG+YRGrv6FP0wwk/toTpATxWYOW0BKdWwl82VT2tFYi5DlROa0Mxg==", - "dev": true, - "license": "MIT", - "dependencies": { - "js-tokens": "^9.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/antfu" - } - }, - "node_modules/strip-literal/node_modules/js-tokens": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-9.0.1.tgz", - "integrity": "sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==", - "dev": true, - "license": "MIT" - }, "node_modules/stripe": { "version": "18.5.0", "resolved": "https://registry.npmjs.org/stripe/-/stripe-18.5.0.tgz", @@ -10163,74 +8148,6 @@ "url": "https://opencollective.com/webpack" } }, - "node_modules/test-exclude": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-7.0.2.tgz", - "integrity": "sha512-u9E6A+ZDYdp7a4WnarkXPZOx8Ilz46+kby6p1yZ8zsGTz9gYa6FIS7lj2oezzNKmtdyyJNNmmXDppga5GB7kSw==", - "dev": true, - "license": "ISC", - "dependencies": { - "@istanbuljs/schema": "^0.1.2", - "glob": "^10.4.1", - "minimatch": "^10.2.2" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/test-exclude/node_modules/balanced-match": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", - "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", - "dev": true, - "license": "MIT", - "engines": { - "node": "18 || 20 || >=22" - } - }, - "node_modules/test-exclude/node_modules/brace-expansion": { - "version": "5.0.6", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.6.tgz", - "integrity": "sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^4.0.2" - }, - "engines": { - "node": "18 || 20 || >=22" - } - }, - "node_modules/test-exclude/node_modules/minimatch": { - "version": "10.2.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", - "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", - "dev": true, - "license": "BlueOak-1.0.0", - "dependencies": { - "brace-expansion": "^5.0.5" - }, - "engines": { - "node": "18 || 20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/tinybench": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz", - "integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==", - "dev": true, - "license": "MIT" - }, - "node_modules/tinyexec": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.2.tgz", - "integrity": "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==", - "dev": true, - "license": "MIT" - }, "node_modules/tinyglobby": { "version": "0.2.16", "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.16.tgz", @@ -10279,36 +8196,6 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/tinypool": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-1.1.1.tgz", - "integrity": "sha512-Zba82s87IFq9A9XmjiX5uZA/ARWDrB03OHlq+Vw1fSdt0I+4/Kutwy8BP4Y/y/aORMo61FQ0vIb5j44vSo5Pkg==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^18.0.0 || >=20.0.0" - } - }, - "node_modules/tinyrainbow": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-2.0.0.tgz", - "integrity": "sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/tinyspy": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-4.0.4.tgz", - "integrity": "sha512-azl+t0z7pw/z958Gy9svOTuzqIk6xq+NSheJzn5MMWtWTFywIacg2wUlzKFGtt3cthx0r2SxMK0yzJOR0IES7Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=14.0.0" - } - }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -10615,221 +8502,6 @@ } } }, - "node_modules/vite": { - "version": "6.4.2", - "resolved": "https://registry.npmjs.org/vite/-/vite-6.4.2.tgz", - "integrity": "sha512-2N/55r4JDJ4gdrCvGgINMy+HH3iRpNIz8K6SFwVsA+JbQScLiC+clmAxBgwiSPgcG9U15QmvqCGWzMbqda5zGQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "esbuild": "^0.25.0", - "fdir": "^6.4.4", - "picomatch": "^4.0.2", - "postcss": "^8.5.3", - "rollup": "^4.34.9", - "tinyglobby": "^0.2.13" - }, - "bin": { - "vite": "bin/vite.js" - }, - "engines": { - "node": "^18.0.0 || ^20.0.0 || >=22.0.0" - }, - "funding": { - "url": "https://github.com/vitejs/vite?sponsor=1" - }, - "optionalDependencies": { - "fsevents": "~2.3.3" - }, - "peerDependencies": { - "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", - "jiti": ">=1.21.0", - "less": "*", - "lightningcss": "^1.21.0", - "sass": "*", - "sass-embedded": "*", - "stylus": "*", - "sugarss": "*", - "terser": "^5.16.0", - "tsx": "^4.8.1", - "yaml": "^2.4.2" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - }, - "jiti": { - "optional": true - }, - "less": { - "optional": true - }, - "lightningcss": { - "optional": true - }, - "sass": { - "optional": true - }, - "sass-embedded": { - "optional": true - }, - "stylus": { - "optional": true - }, - "sugarss": { - "optional": true - }, - "terser": { - "optional": true - }, - "tsx": { - "optional": true - }, - "yaml": { - "optional": true - } - } - }, - "node_modules/vite-node": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-3.2.4.tgz", - "integrity": "sha512-EbKSKh+bh1E1IFxeO0pg1n4dvoOTt0UDiXMd/qn++r98+jPO1xtJilvXldeuQ8giIB5IkpjCgMleHMNEsGH6pg==", - "dev": true, - "license": "MIT", - "dependencies": { - "cac": "^6.7.14", - "debug": "^4.4.1", - "es-module-lexer": "^1.7.0", - "pathe": "^2.0.3", - "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0" - }, - "bin": { - "vite-node": "vite-node.mjs" - }, - "engines": { - "node": "^18.0.0 || ^20.0.0 || >=22.0.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, - "node_modules/vite/node_modules/fdir": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", - "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12.0.0" - }, - "peerDependencies": { - "picomatch": "^3 || ^4" - }, - "peerDependenciesMeta": { - "picomatch": { - "optional": true - } - } - }, - "node_modules/vite/node_modules/picomatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", - "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/vitest": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/vitest/-/vitest-3.2.4.tgz", - "integrity": "sha512-LUCP5ev3GURDysTWiP47wRRUpLKMOfPh+yKTx3kVIEiu5KOMeqzpnYNsKyOoVrULivR8tLcks4+lga33Whn90A==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/chai": "^5.2.2", - "@vitest/expect": "3.2.4", - "@vitest/mocker": "3.2.4", - "@vitest/pretty-format": "^3.2.4", - "@vitest/runner": "3.2.4", - "@vitest/snapshot": "3.2.4", - "@vitest/spy": "3.2.4", - "@vitest/utils": "3.2.4", - "chai": "^5.2.0", - "debug": "^4.4.1", - "expect-type": "^1.2.1", - "magic-string": "^0.30.17", - "pathe": "^2.0.3", - "picomatch": "^4.0.2", - "std-env": "^3.9.0", - "tinybench": "^2.9.0", - "tinyexec": "^0.3.2", - "tinyglobby": "^0.2.14", - "tinypool": "^1.1.1", - "tinyrainbow": "^2.0.0", - "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0", - "vite-node": "3.2.4", - "why-is-node-running": "^2.3.0" - }, - "bin": { - "vitest": "vitest.mjs" - }, - "engines": { - "node": "^18.0.0 || ^20.0.0 || >=22.0.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" - }, - "peerDependencies": { - "@edge-runtime/vm": "*", - "@types/debug": "^4.1.12", - "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", - "@vitest/browser": "3.2.4", - "@vitest/ui": "3.2.4", - "happy-dom": "*", - "jsdom": "*" - }, - "peerDependenciesMeta": { - "@edge-runtime/vm": { - "optional": true - }, - "@types/debug": { - "optional": true - }, - "@types/node": { - "optional": true - }, - "@vitest/browser": { - "optional": true - }, - "@vitest/ui": { - "optional": true - }, - "happy-dom": { - "optional": true - }, - "jsdom": { - "optional": true - } - } - }, - "node_modules/vitest/node_modules/picomatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", - "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -10935,23 +8607,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/why-is-node-running": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz", - "integrity": "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==", - "dev": true, - "license": "MIT", - "dependencies": { - "siginfo": "^2.0.0", - "stackback": "0.0.2" - }, - "bin": { - "why-is-node-running": "cli.js" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/word-wrap": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", @@ -10962,101 +8617,6 @@ "node": ">=0.10.0" } }, - "node_modules/wrap-ansi": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", - "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^6.1.0", - "string-width": "^5.0.1", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/wrap-ansi-cjs": { - "name": "wrap-ansi", - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/wrap-ansi-cjs/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true, - "license": "MIT" - }, - "node_modules/wrap-ansi-cjs/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/wrap-ansi/node_modules/ansi-styles": { - "version": "6.2.3", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", - "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, "node_modules/xml-naming": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/xml-naming/-/xml-naming-0.1.0.tgz", diff --git a/package.json b/package.json index e0a10f1..4b2d77d 100644 --- a/package.json +++ b/package.json @@ -7,30 +7,18 @@ "build": "next build", "start": "next start", "lint": "eslint", - "postinstall": "prisma generate", - "test": "vitest run", - "test:watch": "vitest", - "typecheck": "tsc --noEmit" + "postinstall": "prisma generate" }, "dependencies": { "@aws-sdk/client-s3": "^3.1056.0", - "@aws-sdk/s3-request-presigner": "^3.1058.0", - "@dnd-kit/core": "^6.3.1", - "@dnd-kit/sortable": "^8.0.0", - "@dnd-kit/utilities": "^3.2.2", "@prisma/adapter-pg": "^7.8.0", "@prisma/client": "^7.8.0", - "@types/leaflet": "^1.9.21", "bcryptjs": "^3.0.3", - "leaflet": "^1.9.4", "next": "16.2.6", "next-auth": "^5.0.0-beta.31", "pg": "^8.21.0", "react": "19.2.4", "react-dom": "19.2.4", - "react-leaflet": "^5.0.0", - "resend": "^4.8.0", - "sharp": "^0.34.5", "stripe": "^18.3.0" }, "devDependencies": { @@ -38,13 +26,11 @@ "@types/node": "^20.19.41", "@types/react": "^19.2.15", "@types/react-dom": "^19.2.3", - "@vitest/coverage-v8": "^3.2.4", "dotenv": "^17.4.2", "eslint": "^9.39.4", "eslint-config-next": "^16.2.6", "prisma": "^7.8.0", "tailwindcss": "^4", - "typescript": "^5.9.3", - "vitest": "^3.2.4" + "typescript": "^5.9.3" } } diff --git a/prisma/migrations/20260601000000_audit_and_settings/migration.sql b/prisma/migrations/20260601000000_audit_and_settings/migration.sql deleted file mode 100644 index 15779de..0000000 --- a/prisma/migrations/20260601000000_audit_and_settings/migration.sql +++ /dev/null @@ -1,22 +0,0 @@ -CREATE TABLE "AuditLog" ( - "id" TEXT NOT NULL, - "scope" TEXT NOT NULL, - "event" TEXT NOT NULL, - "target" TEXT, - "actorEmail" TEXT, - "details" JSONB NOT NULL DEFAULT '{}', - "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, - CONSTRAINT "AuditLog_pkey" PRIMARY KEY ("id") -); -CREATE INDEX "AuditLog_scope_idx" ON "AuditLog"("scope"); -CREATE INDEX "AuditLog_event_idx" ON "AuditLog"("event"); -CREATE INDEX "AuditLog_actorEmail_idx" ON "AuditLog"("actorEmail"); -CREATE INDEX "AuditLog_createdAt_idx" ON "AuditLog"("createdAt"); - -CREATE TABLE "Setting" ( - "key" TEXT NOT NULL, - "value" JSONB NOT NULL DEFAULT '{}', - "updatedAt" TIMESTAMP(3) NOT NULL, - "updatedBy" TEXT, - CONSTRAINT "Setting_pkey" PRIMARY KEY ("key") -); diff --git a/prisma/migrations/20260601060000_password_reset_token/migration.sql b/prisma/migrations/20260601060000_password_reset_token/migration.sql deleted file mode 100644 index 50033de..0000000 --- a/prisma/migrations/20260601060000_password_reset_token/migration.sql +++ /dev/null @@ -1,9 +0,0 @@ -CREATE TABLE "PasswordResetToken" ( - "tokenHash" TEXT NOT NULL, - "userId" TEXT NOT NULL, - "expiresAt" TIMESTAMP(3) NOT NULL, - "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, - CONSTRAINT "PasswordResetToken_pkey" PRIMARY KEY ("tokenHash") -); -CREATE INDEX "PasswordResetToken_userId_idx" ON "PasswordResetToken"("userId"); -CREATE INDEX "PasswordResetToken_expiresAt_idx" ON "PasswordResetToken"("expiresAt"); diff --git a/prisma/migrations/20260601120000_translation_overrides/migration.sql b/prisma/migrations/20260601120000_translation_overrides/migration.sql deleted file mode 100644 index 5f3bfb5..0000000 --- a/prisma/migrations/20260601120000_translation_overrides/migration.sql +++ /dev/null @@ -1,9 +0,0 @@ -CREATE TABLE "Translation" ( - "key" TEXT NOT NULL, - "lang" TEXT NOT NULL, - "value" TEXT NOT NULL, - "updatedAt" TIMESTAMP(3) NOT NULL, - "updatedBy" TEXT, - CONSTRAINT "Translation_pkey" PRIMARY KEY ("key", "lang") -); -CREATE INDEX "Translation_lang_idx" ON "Translation"("lang"); diff --git a/prisma/migrations/20260601150000_carbet_nightly_price/migration.sql b/prisma/migrations/20260601150000_carbet_nightly_price/migration.sql deleted file mode 100644 index e53b6bf..0000000 --- a/prisma/migrations/20260601150000_carbet_nightly_price/migration.sql +++ /dev/null @@ -1,2 +0,0 @@ -ALTER TABLE "Carbet" ADD COLUMN "nightlyPrice" DECIMAL(10,2) NOT NULL DEFAULT 0; -UPDATE "Carbet" SET "nightlyPrice" = 80 WHERE "nightlyPrice" = 0; diff --git a/prisma/migrations/20260602030000_operational_criteria/migration.sql b/prisma/migrations/20260602030000_operational_criteria/migration.sql deleted file mode 100644 index 5bdca5f..0000000 --- a/prisma/migrations/20260602030000_operational_criteria/migration.sql +++ /dev/null @@ -1,15 +0,0 @@ -CREATE TYPE "RoadAccess" AS ENUM ('NONE', 'DRY_SEASON_ONLY', 'ALL_YEAR'); -CREATE TYPE "Electricity" AS ENUM ('NONE', 'SOLAR', 'GENERATOR_READY', 'EDF'); - -ALTER TABLE "Carbet" ADD COLUMN "roadAccess" "RoadAccess"; -ALTER TABLE "Carbet" ADD COLUMN "electricity" "Electricity"; -ALTER TABLE "Carbet" ADD COLUMN "gsmAtCarbet" BOOLEAN NOT NULL DEFAULT false; -ALTER TABLE "Carbet" ADD COLUMN "gsmExitDistanceKm" DECIMAL(4,2); - --- Seed des 6 carbets démo avec valeurs réalistes -UPDATE "Carbet" SET "roadAccess" = 'NONE', "electricity" = 'SOLAR', "gsmAtCarbet" = false, "gsmExitDistanceKm" = 1.5 WHERE id = 'demo-carbet-awara'; -UPDATE "Carbet" SET "roadAccess" = 'ALL_YEAR', "electricity" = 'EDF', "gsmAtCarbet" = true WHERE id = 'demo-carbet-kourou'; -UPDATE "Carbet" SET "roadAccess" = 'ALL_YEAR', "electricity" = 'EDF', "gsmAtCarbet" = true WHERE id = 'demo-carbet-mahury'; -UPDATE "Carbet" SET "roadAccess" = 'NONE', "electricity" = 'GENERATOR_READY', "gsmAtCarbet" = false, "gsmExitDistanceKm" = 4.0 WHERE id = 'demo-carbet-maripa'; -UPDATE "Carbet" SET "roadAccess" = 'DRY_SEASON_ONLY', "electricity" = 'SOLAR', "gsmAtCarbet" = false, "gsmExitDistanceKm" = 0.5 WHERE id = 'demo-carbet-paripou'; -UPDATE "Carbet" SET "roadAccess" = 'ALL_YEAR', "electricity" = 'EDF', "gsmAtCarbet" = true WHERE id = 'demo-carbet-wapa'; diff --git a/prisma/migrations/20260602100000_favorite/migration.sql b/prisma/migrations/20260602100000_favorite/migration.sql deleted file mode 100644 index 8abf012..0000000 --- a/prisma/migrations/20260602100000_favorite/migration.sql +++ /dev/null @@ -1,8 +0,0 @@ -CREATE TABLE "Favorite" ( - "userId" TEXT NOT NULL, - "carbetId" TEXT NOT NULL, - "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, - CONSTRAINT "Favorite_pkey" PRIMARY KEY ("userId", "carbetId") -); -CREATE INDEX "Favorite_userId_idx" ON "Favorite"("userId"); -CREATE INDEX "Favorite_carbetId_idx" ON "Favorite"("carbetId"); diff --git a/prisma/migrations/20260603000000_rental_marketplace/migration.sql b/prisma/migrations/20260603000000_rental_marketplace/migration.sql deleted file mode 100644 index 65b4eb1..0000000 --- a/prisma/migrations/20260603000000_rental_marketplace/migration.sql +++ /dev/null @@ -1,112 +0,0 @@ --- UserRole : ajouter RENTAL_PROVIDER -ALTER TYPE "UserRole" ADD VALUE IF NOT EXISTS 'RENTAL_PROVIDER'; - --- Enums dédiés -CREATE TYPE "RentalCategory" AS ENUM ('SLEEP', 'NAVIGATION', 'FISHING', 'COOKING', 'SAFETY'); -CREATE TYPE "RentalBookingStatus" AS ENUM ('PENDING', 'CONFIRMED', 'HANDED_OVER', 'RETURNED', 'CANCELLED'); - --- RentalProvider -CREATE TABLE "RentalProvider" ( - "id" TEXT NOT NULL, - "name" TEXT NOT NULL, - "isSystemD" BOOLEAN NOT NULL DEFAULT false, - "managedByUserId" TEXT, - "contactEmail" TEXT, - "contactPhone" TEXT, - "rivers" TEXT[] DEFAULT ARRAY[]::TEXT[], - "description" TEXT, - "commissionPct" DECIMAL(5,2) NOT NULL DEFAULT 0, - "active" BOOLEAN NOT NULL DEFAULT true, - "approved" BOOLEAN NOT NULL DEFAULT false, - "approvedAt" TIMESTAMP(3), - "approvedBy" TEXT, - "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, - "updatedAt" TIMESTAMP(3) NOT NULL, - CONSTRAINT "RentalProvider_pkey" PRIMARY KEY ("id"), - CONSTRAINT "RentalProvider_managedByUserId_fkey" FOREIGN KEY ("managedByUserId") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE -); -CREATE INDEX "RentalProvider_active_approved_idx" ON "RentalProvider"("active", "approved"); -CREATE INDEX "RentalProvider_managedByUserId_idx" ON "RentalProvider"("managedByUserId"); - --- RentalItem -CREATE TABLE "RentalItem" ( - "id" TEXT NOT NULL, - "providerId" TEXT NOT NULL, - "category" "RentalCategory" NOT NULL, - "name" TEXT NOT NULL, - "description" TEXT, - "imageUrl" TEXT, - "pricePerDay" DECIMAL(8,2) NOT NULL, - "pricePerWeek" DECIMAL(8,2), - "deposit" DECIMAL(8,2) NOT NULL DEFAULT 0, - "totalQty" INTEGER NOT NULL DEFAULT 1, - "withMotor" BOOLEAN NOT NULL DEFAULT false, - "fuelIncluded" BOOLEAN NOT NULL DEFAULT false, - "requiresLicense" BOOLEAN NOT NULL DEFAULT false, - "active" BOOLEAN NOT NULL DEFAULT true, - "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, - "updatedAt" TIMESTAMP(3) NOT NULL, - CONSTRAINT "RentalItem_pkey" PRIMARY KEY ("id"), - CONSTRAINT "RentalItem_providerId_fkey" FOREIGN KEY ("providerId") REFERENCES "RentalProvider"("id") ON DELETE CASCADE ON UPDATE CASCADE -); -CREATE INDEX "RentalItem_providerId_idx" ON "RentalItem"("providerId"); -CREATE INDEX "RentalItem_category_active_idx" ON "RentalItem"("category", "active"); - --- RentalItemAvailability -CREATE TABLE "RentalItemAvailability" ( - "id" TEXT NOT NULL, - "itemId" TEXT NOT NULL, - "startDate" TIMESTAMP(3) NOT NULL, - "endDate" TIMESTAMP(3) NOT NULL, - "qty" INTEGER NOT NULL, - "reason" TEXT NOT NULL, - "rentalBookingId" TEXT, - "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, - CONSTRAINT "RentalItemAvailability_pkey" PRIMARY KEY ("id"), - CONSTRAINT "RentalItemAvailability_itemId_fkey" FOREIGN KEY ("itemId") REFERENCES "RentalItem"("id") ON DELETE CASCADE ON UPDATE CASCADE -); -CREATE INDEX "RentalItemAvailability_itemId_startDate_endDate_idx" ON "RentalItemAvailability"("itemId", "startDate", "endDate"); -CREATE INDEX "RentalItemAvailability_rentalBookingId_idx" ON "RentalItemAvailability"("rentalBookingId"); - --- RentalBooking -CREATE TABLE "RentalBooking" ( - "id" TEXT NOT NULL, - "bookingId" TEXT, - "tenantId" TEXT NOT NULL, - "providerId" TEXT NOT NULL, - "startDate" TIMESTAMP(3) NOT NULL, - "endDate" TIMESTAMP(3) NOT NULL, - "status" "RentalBookingStatus" NOT NULL DEFAULT 'PENDING', - "paymentStatus" "PaymentStatus" NOT NULL DEFAULT 'PENDING', - "itemsTotal" DECIMAL(10,2) NOT NULL, - "depositTotal" DECIMAL(10,2) NOT NULL, - "commissionAmount" DECIMAL(10,2) NOT NULL DEFAULT 0, - "amount" DECIMAL(10,2) NOT NULL, - "currency" TEXT NOT NULL DEFAULT 'EUR', - "stripeSessionId" TEXT, - "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, - "updatedAt" TIMESTAMP(3) NOT NULL, - CONSTRAINT "RentalBooking_pkey" PRIMARY KEY ("id"), - CONSTRAINT "RentalBooking_bookingId_fkey" FOREIGN KEY ("bookingId") REFERENCES "Booking"("id") ON DELETE SET NULL ON UPDATE CASCADE, - CONSTRAINT "RentalBooking_tenantId_fkey" FOREIGN KEY ("tenantId") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE, - CONSTRAINT "RentalBooking_providerId_fkey" FOREIGN KEY ("providerId") REFERENCES "RentalProvider"("id") ON DELETE RESTRICT ON UPDATE CASCADE -); -CREATE INDEX "RentalBooking_tenantId_status_idx" ON "RentalBooking"("tenantId", "status"); -CREATE INDEX "RentalBooking_providerId_status_idx" ON "RentalBooking"("providerId", "status"); -CREATE INDEX "RentalBooking_bookingId_idx" ON "RentalBooking"("bookingId"); -CREATE INDEX "RentalBooking_startDate_endDate_idx" ON "RentalBooking"("startDate", "endDate"); - --- RentalLine -CREATE TABLE "RentalLine" ( - "id" TEXT NOT NULL, - "rentalBookingId" TEXT NOT NULL, - "itemId" TEXT NOT NULL, - "qty" INTEGER NOT NULL, - "pricePerDay" DECIMAL(8,2) NOT NULL, - "deposit" DECIMAL(8,2) NOT NULL DEFAULT 0, - "lineTotal" DECIMAL(10,2) NOT NULL, - CONSTRAINT "RentalLine_pkey" PRIMARY KEY ("id"), - CONSTRAINT "RentalLine_rentalBookingId_fkey" FOREIGN KEY ("rentalBookingId") REFERENCES "RentalBooking"("id") ON DELETE CASCADE ON UPDATE CASCADE, - CONSTRAINT "RentalLine_itemId_fkey" FOREIGN KEY ("itemId") REFERENCES "RentalItem"("id") ON DELETE RESTRICT ON UPDATE CASCADE -); -CREATE INDEX "RentalLine_rentalBookingId_idx" ON "RentalLine"("rentalBookingId"); diff --git a/prisma/migrations/20260603100000_rental_item_media/migration.sql b/prisma/migrations/20260603100000_rental_item_media/migration.sql deleted file mode 100644 index 67a2d76..0000000 --- a/prisma/migrations/20260603100000_rental_item_media/migration.sql +++ /dev/null @@ -1,22 +0,0 @@ --- Sprint F : RentalItemMedia (photos & vidéos pour items rental). --- Mêmes conventions que Media (carbet) : MediaType enum existant, s3Key/s3Url, --- sortOrder pour cover (0). Cascade sur RentalItem. - -CREATE TABLE "RentalItemMedia" ( - "id" TEXT NOT NULL, - "itemId" TEXT NOT NULL, - "type" "MediaType" NOT NULL, - "s3Key" TEXT NOT NULL, - "s3Url" TEXT NOT NULL, - "sortOrder" INTEGER NOT NULL DEFAULT 0, - "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, - CONSTRAINT "RentalItemMedia_pkey" PRIMARY KEY ("id") -); - -CREATE INDEX "RentalItemMedia_itemId_sortOrder_idx" - ON "RentalItemMedia"("itemId", "sortOrder"); - -ALTER TABLE "RentalItemMedia" - ADD CONSTRAINT "RentalItemMedia_itemId_fkey" - FOREIGN KEY ("itemId") REFERENCES "RentalItem"("id") - ON DELETE CASCADE ON UPDATE CASCADE; diff --git a/prisma/migrations/20260603200000_ce_management/migration.sql b/prisma/migrations/20260603200000_ce_management/migration.sql deleted file mode 100644 index eb2cc87..0000000 --- a/prisma/migrations/20260603200000_ce_management/migration.sql +++ /dev/null @@ -1,54 +0,0 @@ --- Sprint G : CE management. --- * Organization gagne le workflow d'approbation (approved + approvedAt + approvedBy) --- + un contactEmail dédié pour les notifications admin. --- * Nouveau modèle OrganizationCarbetMembership : co-gestion des carbets par les --- CE_MANAGERs d'une org liée. Pas de unique sur carbet → un Carbet pourrait être --- co-publié par plusieurs orgs (cas rare mais autorisé). --- * RentalProvider gagne organizationId (nullable) : un CE peut posséder son provider. - -ALTER TABLE "Organization" - ADD COLUMN "contactEmail" TEXT, - ADD COLUMN "approved" BOOLEAN NOT NULL DEFAULT FALSE, - ADD COLUMN "approvedAt" TIMESTAMP(3), - ADD COLUMN "approvedBy" TEXT; - -CREATE INDEX "Organization_approved_idx" ON "Organization"("approved"); - --- Backfill : toutes les orgs existantes sont considérées validées. --- (Aujourd'hui : CMCK uniquement. Les futures orgs créées via signup arriveront --- en approved=false par défaut.) -UPDATE "Organization" - SET "approved" = TRUE, - "approvedAt" = NOW() - WHERE "approved" = FALSE; - -CREATE TABLE "OrganizationCarbetMembership" ( - "organizationId" TEXT NOT NULL, - "carbetId" TEXT NOT NULL, - "addedByUserId" TEXT, - "addedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, - CONSTRAINT "OrganizationCarbetMembership_pkey" PRIMARY KEY ("organizationId", "carbetId") -); - -CREATE INDEX "OrganizationCarbetMembership_carbetId_idx" - ON "OrganizationCarbetMembership"("carbetId"); - -ALTER TABLE "OrganizationCarbetMembership" - ADD CONSTRAINT "OrganizationCarbetMembership_organizationId_fkey" - FOREIGN KEY ("organizationId") REFERENCES "Organization"("id") - ON DELETE CASCADE ON UPDATE CASCADE; - -ALTER TABLE "OrganizationCarbetMembership" - ADD CONSTRAINT "OrganizationCarbetMembership_carbetId_fkey" - FOREIGN KEY ("carbetId") REFERENCES "Carbet"("id") - ON DELETE CASCADE ON UPDATE CASCADE; - -ALTER TABLE "RentalProvider" - ADD COLUMN "organizationId" TEXT; - -CREATE INDEX "RentalProvider_organizationId_idx" ON "RentalProvider"("organizationId"); - -ALTER TABLE "RentalProvider" - ADD CONSTRAINT "RentalProvider_organizationId_fkey" - FOREIGN KEY ("organizationId") REFERENCES "Organization"("id") - ON DELETE SET NULL ON UPDATE CASCADE; diff --git a/prisma/migrations/20260603300000_org_invite_token/migration.sql b/prisma/migrations/20260603300000_org_invite_token/migration.sql deleted file mode 100644 index 7ce99e5..0000000 --- a/prisma/migrations/20260603300000_org_invite_token/migration.sql +++ /dev/null @@ -1,22 +0,0 @@ --- Sprint K : tokens d'invitation CE_MEMBER. --- Le CE_MANAGER génère un lien /inscription?invite=TOKEN, le destinataire s'inscrit --- automatiquement comme CE_MEMBER de l'organisation. usedAt à la consommation. - -CREATE TABLE "OrgInviteToken" ( - "tokenHash" TEXT NOT NULL, - "organizationId" TEXT NOT NULL, - "email" TEXT, - "createdByUserId" TEXT, - "expiresAt" TIMESTAMP(3) NOT NULL, - "usedAt" TIMESTAMP(3), - "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, - CONSTRAINT "OrgInviteToken_pkey" PRIMARY KEY ("tokenHash") -); - -CREATE INDEX "OrgInviteToken_organizationId_idx" ON "OrgInviteToken"("organizationId"); -CREATE INDEX "OrgInviteToken_expiresAt_idx" ON "OrgInviteToken"("expiresAt"); - -ALTER TABLE "OrgInviteToken" - ADD CONSTRAINT "OrgInviteToken_organizationId_fkey" - FOREIGN KEY ("organizationId") REFERENCES "Organization"("id") - ON DELETE CASCADE ON UPDATE CASCADE; diff --git a/prisma/migrations/20260603400000_rental_payout_mark/migration.sql b/prisma/migrations/20260603400000_rental_payout_mark/migration.sql deleted file mode 100644 index cff28de..0000000 --- a/prisma/migrations/20260603400000_rental_payout_mark/migration.sql +++ /dev/null @@ -1,28 +0,0 @@ --- Sprint O : reversements prestataires. --- RentalPayoutMark trace les virements bancaires manuels effectués par System D --- vers les RentalProvider tiers (le marketplace encaisse centralisé, redistribue --- hors plateforme une fois par mois). Unique (provider, mois) pour empêcher --- les marquages en doublon. - -CREATE TABLE "RentalPayoutMark" ( - "id" TEXT NOT NULL, - "providerId" TEXT NOT NULL, - "periodMonth" TIMESTAMP(3) NOT NULL, - "amount" DECIMAL(10, 2) NOT NULL, - "reference" TEXT, - "paidAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, - "paidByEmail" TEXT, - "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, - CONSTRAINT "RentalPayoutMark_pkey" PRIMARY KEY ("id") -); - -CREATE UNIQUE INDEX "RentalPayoutMark_providerId_periodMonth_key" - ON "RentalPayoutMark"("providerId", "periodMonth"); - -CREATE INDEX "RentalPayoutMark_periodMonth_idx" - ON "RentalPayoutMark"("periodMonth"); - -ALTER TABLE "RentalPayoutMark" - ADD CONSTRAINT "RentalPayoutMark_providerId_fkey" - FOREIGN KEY ("providerId") REFERENCES "RentalProvider"("id") - ON DELETE CASCADE ON UPDATE CASCADE; diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 6ae7e3f..63a3b1c 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -13,7 +13,6 @@ enum UserRole { CE_MEMBER TOURIST ADMIN - RENTAL_PROVIDER } enum CarbetStatus { @@ -72,59 +71,16 @@ enum TransportMode { } model Organization { - id String @id @default(cuid()) - name String - slug String @unique - description String? - contactEmail String? - approved Boolean @default(false) - approvedAt DateTime? - approvedBy String? - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt + id String @id @default(cuid()) + name String + slug String @unique + description String? + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt - members User[] - carbetMemberships OrganizationCarbetMembership[] - rentalProviders RentalProvider[] - invites OrgInviteToken[] + members User[] @@index([name]) - @@index([approved]) -} - -/// Token d'invitation pour rejoindre une organisation comme CE_MEMBER. -/// Le CE_MANAGER génère un lien, le destinataire s'inscrit via /inscription?invite=TOKEN. -/// Pas de unique sur email pour permettre plusieurs invites pendants par destinataire. -model OrgInviteToken { - tokenHash String @id - organizationId String - email String? - createdByUserId String? - expiresAt DateTime - usedAt DateTime? - createdAt DateTime @default(now()) - - organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade) - - @@index([organizationId]) - @@index([expiresAt]) -} - -/// Co-gestion des carbets côté CE. Un Carbet a toujours un ownerId (créateur initial), -/// et zéro ou plusieurs orgs liées : un CE_MANAGER d'une org liée peut gérer le carbet -/// en plus de l'owner. Pour un hôte individuel : aucune membership ; pour un carbet CE : -/// 1 membership pour l'org du créateur. Plusieurs orgs possibles si co-publication. -model OrganizationCarbetMembership { - organizationId String - carbetId String - addedByUserId String? - addedAt DateTime @default(now()) - - organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade) - carbet Carbet @relation(fields: [carbetId], references: [id], onDelete: Cascade) - - @@id([organizationId, carbetId]) - @@index([carbetId]) } model User { @@ -141,13 +97,11 @@ model User { createdAt DateTime @default(now()) updatedAt DateTime @updatedAt - organization Organization? @relation(fields: [organizationId], references: [id], onDelete: SetNull) - carbets Carbet[] @relation("CarbetOwner") - bookings Booking[] @relation("BookingTenant") - reviews Review[] @relation("ReviewAuthor") - subscriptions Subscription[] - rentalProviders RentalProvider[] - rentalBookings RentalBooking[] @relation("RentalBookingTenant") + organization Organization? @relation(fields: [organizationId], references: [id], onDelete: SetNull) + carbets Carbet[] @relation("CarbetOwner") + bookings Booking[] @relation("BookingTenant") + reviews Review[] @relation("ReviewAuthor") + subscriptions Subscription[] @@index([organizationId]) @@index([role]) @@ -170,13 +124,6 @@ model Carbet { // Détails d'accès route pour ROAD_AND_RIVER (GPS, distance, type de piste). roadAccessNote String? capacity Int - // 4 critères opérationnels dealbreakers (dispo en filtres + badges UI) - roadAccess RoadAccess? - electricity Electricity? - gsmAtCarbet Boolean @default(false) - gsmExitDistanceKm Decimal? @db.Decimal(4, 2) - // Prix par nuit pour le carbet entier (toute capacité). En euros. - nightlyPrice Decimal @db.Decimal(10, 2) @default(0) // Contraintes séjour (plugin min-stay). null = pas de contrainte. minStayNights Int? maxStayNights Int? @@ -200,7 +147,6 @@ model Carbet { bookings Booking[] reviews Review[] subscriptions Subscription[] - organizations OrganizationCarbetMembership[] @@index([ownerId]) @@index([status]) @@ -296,8 +242,7 @@ model Booking { carbet Carbet @relation(fields: [carbetId], references: [id], onDelete: Restrict) tenant User @relation("BookingTenant", fields: [tenantId], references: [id], onDelete: Restrict) - review Review? - rentalBookings RentalBooking[] + review Review? @@index([carbetId]) @@index([tenantId]) @@ -381,239 +326,3 @@ model ContentPage { @@index([category]) @@index([published]) } - -model AuditLog { - id String @id @default(cuid()) - scope String - event String - target String? - actorEmail String? - details Json @default("{}") - createdAt DateTime @default(now()) - - @@index([scope]) - @@index([event]) - @@index([actorEmail]) - @@index([createdAt]) -} - -model Setting { - key String @id - value Json @default("{}") - updatedAt DateTime @updatedAt - updatedBy String? -} - -model Translation { - key String - lang String - value String - updatedAt DateTime @updatedAt - updatedBy String? - - @@id([key, lang]) - @@index([lang]) -} - -model PasswordResetToken { - tokenHash String @id - userId String - expiresAt DateTime - createdAt DateTime @default(now()) - - @@index([userId]) - @@index([expiresAt]) -} - -model Favorite { - userId String - carbetId String - createdAt DateTime @default(now()) - - @@id([userId, carbetId]) - @@index([userId]) - @@index([carbetId]) -} - -enum RoadAccess { - NONE - DRY_SEASON_ONLY - ALL_YEAR -} - -enum Electricity { - NONE - SOLAR - GENERATOR_READY - EDF -} - -enum RentalCategory { - SLEEP - NAVIGATION - FISHING - COOKING - SAFETY -} - -enum RentalBookingStatus { - PENDING - CONFIRMED - HANDED_OVER - RETURNED - CANCELLED -} - -model RentalProvider { - id String @id @default(cuid()) - name String - isSystemD Boolean @default(false) - managedByUserId String? - /// Si renseigné, le provider appartient à une organisation (CE) ; tout CE_MANAGER - /// membre de l'org peut gérer items et réservations en plus du manager nominal. - organizationId String? - contactEmail String? - contactPhone String? - rivers String[] @default([]) - description String? - commissionPct Decimal @db.Decimal(5, 2) @default(0) - active Boolean @default(true) - approved Boolean @default(false) - approvedAt DateTime? - approvedBy String? - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt - - manager User? @relation(fields: [managedByUserId], references: [id], onDelete: SetNull) - organization Organization? @relation(fields: [organizationId], references: [id], onDelete: SetNull) - items RentalItem[] - rentalBookings RentalBooking[] - payoutMarks RentalPayoutMark[] - - @@index([active, approved]) - @@index([managedByUserId]) - @@index([organizationId]) -} - -/// Trace les reversements bancaires manuels (System D paie le provider hors plateforme). -/// La période est représentée par le mois (1er du mois minuit UTC) ; unique par -/// (provider, période) pour empêcher de marquer 2 fois le même mois. -model RentalPayoutMark { - id String @id @default(cuid()) - providerId String - /// 1er du mois minuit UTC — sert de clé de période. - periodMonth DateTime - /// Montant effectivement viré au provider, en euros. - amount Decimal @db.Decimal(10, 2) - /// Référence de virement (optionnelle, à coller depuis la banque). - reference String? - paidAt DateTime @default(now()) - paidByEmail String? - createdAt DateTime @default(now()) - - provider RentalProvider @relation(fields: [providerId], references: [id], onDelete: Cascade) - - @@unique([providerId, periodMonth]) - @@index([periodMonth]) -} - -model RentalItem { - id String @id @default(cuid()) - providerId String - category RentalCategory - name String - description String? - imageUrl String? - pricePerDay Decimal @db.Decimal(8, 2) - pricePerWeek Decimal? @db.Decimal(8, 2) - deposit Decimal @db.Decimal(8, 2) @default(0) - totalQty Int @default(1) - withMotor Boolean @default(false) - fuelIncluded Boolean @default(false) - requiresLicense Boolean @default(false) - active Boolean @default(true) - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt - - provider RentalProvider @relation(fields: [providerId], references: [id], onDelete: Cascade) - availabilities RentalItemAvailability[] - lines RentalLine[] - media RentalItemMedia[] - - @@index([providerId]) - @@index([category, active]) -} - -model RentalItemMedia { - id String @id @default(cuid()) - itemId String - type MediaType - s3Key String - s3Url String - sortOrder Int @default(0) - createdAt DateTime @default(now()) - - item RentalItem @relation(fields: [itemId], references: [id], onDelete: Cascade) - - @@index([itemId, sortOrder]) -} - -model RentalItemAvailability { - id String @id @default(cuid()) - itemId String - startDate DateTime - endDate DateTime - qty Int - reason String - rentalBookingId String? - createdAt DateTime @default(now()) - - item RentalItem @relation(fields: [itemId], references: [id], onDelete: Cascade) - - @@index([itemId, startDate, endDate]) - @@index([rentalBookingId]) -} - -model RentalBooking { - id String @id @default(cuid()) - bookingId String? - tenantId String - providerId String - startDate DateTime - endDate DateTime - status RentalBookingStatus @default(PENDING) - paymentStatus PaymentStatus @default(PENDING) - itemsTotal Decimal @db.Decimal(10, 2) - depositTotal Decimal @db.Decimal(10, 2) - commissionAmount Decimal @db.Decimal(10, 2) @default(0) - amount Decimal @db.Decimal(10, 2) - currency String @default("EUR") - stripeSessionId String? - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt - - booking Booking? @relation(fields: [bookingId], references: [id], onDelete: SetNull) - tenant User @relation("RentalBookingTenant", fields: [tenantId], references: [id], onDelete: Restrict) - provider RentalProvider @relation(fields: [providerId], references: [id], onDelete: Restrict) - lines RentalLine[] - - @@index([tenantId, status]) - @@index([providerId, status]) - @@index([bookingId]) - @@index([startDate, endDate]) -} - -model RentalLine { - id String @id @default(cuid()) - rentalBookingId String - itemId String - qty Int - pricePerDay Decimal @db.Decimal(8, 2) - deposit Decimal @db.Decimal(8, 2) @default(0) - lineTotal Decimal @db.Decimal(10, 2) - - rentalBooking RentalBooking @relation(fields: [rentalBookingId], references: [id], onDelete: Cascade) - item RentalItem @relation(fields: [itemId], references: [id], onDelete: Restrict) - - @@index([rentalBookingId]) -} diff --git a/public/icons/apple-touch-icon.png b/public/icons/apple-touch-icon.png deleted file mode 100644 index a185b67..0000000 Binary files a/public/icons/apple-touch-icon.png and /dev/null differ diff --git a/public/icons/favicon-32.png b/public/icons/favicon-32.png deleted file mode 100644 index c062acf..0000000 Binary files a/public/icons/favicon-32.png and /dev/null differ diff --git a/public/icons/icon-192-maskable.png b/public/icons/icon-192-maskable.png deleted file mode 100644 index e80f811..0000000 Binary files a/public/icons/icon-192-maskable.png and /dev/null differ diff --git a/public/icons/icon-192.png b/public/icons/icon-192.png deleted file mode 100644 index cb0fd13..0000000 Binary files a/public/icons/icon-192.png and /dev/null differ diff --git a/public/icons/icon-512-maskable.png b/public/icons/icon-512-maskable.png deleted file mode 100644 index 5041e00..0000000 Binary files a/public/icons/icon-512-maskable.png and /dev/null differ diff --git a/public/icons/icon-512.png b/public/icons/icon-512.png deleted file mode 100644 index abb04bf..0000000 Binary files a/public/icons/icon-512.png and /dev/null differ diff --git a/public/manifest.webmanifest b/public/manifest.webmanifest deleted file mode 100644 index 2f32e8d..0000000 --- a/public/manifest.webmanifest +++ /dev/null @@ -1,60 +0,0 @@ -{ - "name": "Karbé — carbets fluviaux de Guyane", - "short_name": "Karbé", - "description": "Au fil de l'eau : louez des carbets le long des fleuves de Guyane.", - "start_url": "/decouvrir", - "id": "/decouvrir", - "scope": "/", - "display": "standalone", - "orientation": "portrait", - "background_color": "#000000", - "theme_color": "#059669", - "lang": "fr", - "categories": ["travel", "lifestyle"], - "icons": [ - { - "src": "/icons/icon-192.png", - "sizes": "192x192", - "type": "image/png", - "purpose": "any" - }, - { - "src": "/icons/icon-512.png", - "sizes": "512x512", - "type": "image/png", - "purpose": "any" - }, - { - "src": "/icons/icon-192-maskable.png", - "sizes": "192x192", - "type": "image/png", - "purpose": "maskable" - }, - { - "src": "/icons/icon-512-maskable.png", - "sizes": "512x512", - "type": "image/png", - "purpose": "maskable" - } - ], - "shortcuts": [ - { - "name": "Au fil de l'eau", - "short_name": "Découvrir", - "url": "/decouvrir", - "icons": [{ "src": "/icons/icon-192.png", "sizes": "192x192" }] - }, - { - "name": "Mes favoris", - "short_name": "Favoris", - "url": "/mes-favoris", - "icons": [{ "src": "/icons/icon-192.png", "sizes": "192x192" }] - }, - { - "name": "Mon compte", - "short_name": "Compte", - "url": "/mon-compte", - "icons": [{ "src": "/icons/icon-192.png", "sizes": "192x192" }] - } - ] -} diff --git a/scripts/backup-postgres.sh b/scripts/backup-postgres.sh deleted file mode 100755 index abe63d4..0000000 --- a/scripts/backup-postgres.sh +++ /dev/null @@ -1,54 +0,0 @@ -#!/bin/bash -# -# Backup nightly du PostgreSQL Karbé vers MinIO. -# Lancé par un systemd timer (karbe-backup.timer). -# -# Rétention 30 jours côté MinIO (s'appuyer sur une lifecycle policy ou un -# nettoyage côté `mc rm` planifié — TODO si on veut être propre). - -set -euo pipefail - -STAMP=$(date -u +%Y%m%d-%H%M%S) -DUMP_DIR=/tmp/karbe-backup -DUMP_FILE="$DUMP_DIR/karbe-${STAMP}.sql.gz" -BUCKET_DEST="karbe-backups/postgres/karbe-${STAMP}.sql.gz" - -mkdir -p "$DUMP_DIR" - -# Dump compressé depuis le conteneur postgres -docker compose -f /home/ubuntu/karbe/docker-compose.prod.yml \ - -f /home/ubuntu/karbe/docker-compose.override.yml \ - exec -T postgres pg_dump -U karbe -d karbe \ - | gzip > "$DUMP_FILE" - -SIZE=$(stat -c %s "$DUMP_FILE") -echo "[$(date -u +%FT%TZ)] dump created size=${SIZE}B path=${DUMP_FILE}" - -# Push vers MinIO via mc Docker -docker run --rm --network karbe-net \ - --entrypoint /bin/sh \ - -v "$DUMP_DIR:/dump" \ - -e MINIO_ROOT_USER \ - -e MINIO_ROOT_PASSWORD \ - minio/mc:latest -c " - mc alias set karbe http://minio:9000 \"\$MINIO_ROOT_USER\" \"\$MINIO_ROOT_PASSWORD\" >/dev/null 2>&1 && \ - mc mb karbe/karbe-backups --ignore-existing >/dev/null 2>&1 && \ - mc cp /dump/karbe-${STAMP}.sql.gz karbe/${BUCKET_DEST} - " - -echo "[$(date -u +%FT%TZ)] uploaded to karbe/${BUCKET_DEST}" - -# Nettoyage local -rm -f "$DUMP_FILE" - -# Rétention : supprime les backups > 30 jours dans MinIO -docker run --rm --network karbe-net \ - --entrypoint /bin/sh \ - -e MINIO_ROOT_USER \ - -e MINIO_ROOT_PASSWORD \ - minio/mc:latest -c " - mc alias set karbe http://minio:9000 \"\$MINIO_ROOT_USER\" \"\$MINIO_ROOT_PASSWORD\" >/dev/null 2>&1 && \ - mc rm --recursive --force --older-than 30d karbe/karbe-backups/ 2>/dev/null || true - " - -echo "[$(date -u +%FT%TZ)] retention sweep done (>30d removed)" diff --git a/src/app/accueil/page.tsx b/src/app/accueil/page.tsx deleted file mode 100644 index 513e1ac..0000000 --- a/src/app/accueil/page.tsx +++ /dev/null @@ -1,60 +0,0 @@ -import Link from "next/link"; -import { IfPluginEnabled } from "@/components/IfPluginEnabled"; -import { HeroSection } from "@/components/landing/HeroSection"; -import { ExperiencesSection } from "@/components/landing/ExperiencesSection"; -import { HowItWorksSection } from "@/components/landing/HowItWorksSection"; -import { CESection } from "@/components/landing/CESection"; -import { TestimonialsSection } from "@/components/landing/TestimonialsSection"; -import { LandingFooter } from "@/components/landing/Footer"; - -export const metadata = { title: "Accueil — Karbé" }; - -/** - * Landing « marketing » historique (hero + sections + footer riche). Conservée - * à /accueil après la promotion de /decouvrir comme nouvelle page d'index. - */ -export default function LandingPage() { - return ( - <> - -
-

- Karbé — carbets fluviaux de Guyane -

-

- La marketplace pour louer des carbets le long des fleuves de Guyane. -

-
- - Au fil de l'eau - - - Catalogue - -
-
- - } - > - -
- - - - - - - - - - ); -} diff --git a/src/app/admin/analytics/page.tsx b/src/app/admin/analytics/page.tsx deleted file mode 100644 index 0ec2427..0000000 --- a/src/app/admin/analytics/page.tsx +++ /dev/null @@ -1,169 +0,0 @@ -import Link from "next/link"; - -import { MonthlyRevenueChart } from "@/components/analytics/MonthlyRevenueChart"; -import { getAdminGlobalKpis, getMonthlyRevenueSeries } from "@/lib/analytics"; - -export const dynamic = "force-dynamic"; -export const metadata = { title: "Analytics globaux — Karbé admin" }; - -const ROLE_LABEL: Record = { - ADMIN: "Admin", - OWNER: "Hôte", - RENTAL_PROVIDER: "Loueur matériel", - CE_MANAGER: "CE Manager", - CE_MEMBER: "CE Membre", - TOURIST: "Voyageur", -}; - -function fmtEur(n: number): string { - return n.toLocaleString("fr-FR", { style: "currency", currency: "EUR", maximumFractionDigits: 0 }); -} - -export default async function AdminAnalyticsPage() { - const [kpis, series] = await Promise.all([ - getAdminGlobalKpis(), - getMonthlyRevenueSeries({ monthsBack: 12 }), - ]); - - return ( -
-
-

Analytics globaux

-

- Vue d'ensemble plateforme : utilisateurs, activité 30 derniers jours, top performers. -

-
- -
- - - - -
- -
-
-

- Utilisateurs par rôle -

- {kpis.usersTotal === 0 ? ( -

Aucun utilisateur.

- ) : ( -
    - {Object.entries(kpis.usersByRole) - .sort((a, b) => b[1] - a[1]) - .map(([role, count]) => { - const pct = Math.round((count / kpis.usersTotal) * 100); - return ( -
  • -
    - {ROLE_LABEL[role] ?? role} - - {count} ({pct}%) - -
    -
    -
    -
    -
  • - ); - })} -
- )} -
- -
-

- Activité 30 derniers jours -

-
    -
  • - Bookings carbet - {kpis.bookings30d} -
  • -
  • - Locations matériel - {kpis.rentals30d} -
  • -
  • - Total CA 30j - - {fmtEur(kpis.revenue30d)} - -
  • -
-
-
- -
-

- Chiffre d'affaires mensuel -

- -
- -
-
-

- Top carbets (30j) -

- {kpis.topCarbets.length === 0 ? ( -

Aucune réservation sur les 30 derniers jours.

- ) : ( -
    - {kpis.topCarbets.map((c, i) => ( -
  • - - #{i + 1} - - {c.title} - - - {fmtEur(c.revenue)} -
  • - ))} -
- )} -
- -
-

- Top prestataires rental (30j) -

- {kpis.topProviders.length === 0 ? ( -

Aucune location sur les 30 derniers jours.

- ) : ( -
    - {kpis.topProviders.map((p, i) => ( -
  • - - #{i + 1} - - {p.name} - - - {fmtEur(p.revenue)} -
  • - ))} -
- )} -
-
-
- ); -} - -function KpiCard({ label, value }: { label: string; value: string | number }) { - return ( -
-
{label}
-
{value}
-
- ); -} diff --git a/src/app/admin/audit/page.tsx b/src/app/admin/audit/page.tsx deleted file mode 100644 index 52cc4fd..0000000 --- a/src/app/admin/audit/page.tsx +++ /dev/null @@ -1,134 +0,0 @@ -import Link from "next/link"; -import { listAuditAdmin, listAuditScopes } from "@/lib/admin/audit"; - -export const dynamic = "force-dynamic"; - -type PageProps = { - searchParams: Promise<{ - q?: string; - scope?: string; - actor?: string; - from?: string; - to?: string; - }>; -}; - -function parseDate(v?: string): Date | undefined { - if (!v) return undefined; - const d = new Date(v); - return isNaN(d.getTime()) ? undefined : d; -} - -export default async function AuditAdminPage({ searchParams }: PageProps) { - const sp = await searchParams; - const filters = { - q: sp.q?.trim() || undefined, - scope: sp.scope?.trim() || undefined, - actor: sp.actor?.trim() || undefined, - from: parseDate(sp.from), - to: parseDate(sp.to), - }; - const [rows, scopes] = await Promise.all([listAuditAdmin(filters), listAuditScopes()]); - const dateTimeFmt = new Intl.DateTimeFormat("fr-FR", { - day: "2-digit", month: "short", year: "2-digit", hour: "2-digit", minute: "2-digit", - }); - - return ( -
-
-
-

Audit log

-

- {rows.length} entrée{rows.length > 1 ? "s" : ""} - {rows.length === 300 ? " (limite atteinte — affinez les filtres)" : ""} -

-
-
- -
- - - - - - - {(filters.q || filters.scope || filters.actor || filters.from || filters.to) ? ( - - Réinit. - - ) : null} -
- -
- - - - - - - - - - - - - {rows.length === 0 ? ( - - - - ) : null} - {rows.map((r) => ( - - - - - - - - - ))} - -
QuandScopeÉvénementCibleActeurDétails
- Aucune entrée d'audit ne correspond aux filtres. -
- {dateTimeFmt.format(r.createdAt)} - {r.scope}{r.event} - {r.target ? r.target.slice(0, 24) + (r.target.length > 24 ? "…" : "") : "—"} - {r.actorEmail ?? "—"} - {r.details && typeof r.details === "object" && Object.keys(r.details as object).length > 0 - ? JSON.stringify(r.details) - : "—"} -
-
-
- ); -} diff --git a/src/app/admin/bookings/[id]/_components/BookingActions.tsx b/src/app/admin/bookings/[id]/_components/BookingActions.tsx deleted file mode 100644 index b220b27..0000000 --- a/src/app/admin/bookings/[id]/_components/BookingActions.tsx +++ /dev/null @@ -1,156 +0,0 @@ -"use client"; - -import { useState, useTransition } from "react"; -import { useRouter } from "next/navigation"; -import { BookingStatus, PaymentStatus } from "@/generated/prisma/enums"; -import { - refundBookingAction, - updateBookingPaymentAction, - updateBookingStatusAction, -} from "../../actions"; - -type Status = (typeof BookingStatus)[keyof typeof BookingStatus]; -type Payment = (typeof PaymentStatus)[keyof typeof PaymentStatus]; - -const btnBase = - "rounded-md px-3 py-1.5 text-xs font-semibold transition disabled:opacity-50"; - -export function BookingActions({ - id, - status, - paymentStatus, -}: { - id: string; - status: Status; - paymentStatus: Payment; -}) { - const router = useRouter(); - const [pending, startTransition] = useTransition(); - const [error, setError] = useState(null); - const [confirmRefund, setConfirmRefund] = useState(false); - - function setStatus(next: Status) { - setError(null); - startTransition(async () => { - const res = await updateBookingStatusAction(id, next); - if (res && res.ok === false) setError(res.error); - router.refresh(); - }); - } - - function setPayment(next: Payment) { - setError(null); - startTransition(async () => { - const res = await updateBookingPaymentAction(id, next); - if (res && res.ok === false) setError(res.error); - router.refresh(); - }); - } - - function refund() { - setError(null); - startTransition(async () => { - await refundBookingAction(id); - setConfirmRefund(false); - router.refresh(); - }); - } - - return ( -
-
- Statut résa : - {status === BookingStatus.PENDING ? ( - - ) : null} - {status === BookingStatus.CONFIRMED ? ( - - ) : null} - {status !== BookingStatus.CANCELLED && status !== BookingStatus.COMPLETED ? ( - - ) : null} -
- -
- Paiement : - {paymentStatus !== PaymentStatus.SUCCEEDED && paymentStatus !== PaymentStatus.REFUNDED ? ( - - ) : null} - {paymentStatus !== PaymentStatus.FAILED && paymentStatus !== PaymentStatus.REFUNDED ? ( - - ) : null} - {paymentStatus === PaymentStatus.SUCCEEDED ? ( - confirmRefund ? ( -
- Rembourser & annuler ? - - -
- ) : ( - - ) - ) : null} -
- - {error ? ( -
{error}
- ) : null} -
- ); -} diff --git a/src/app/admin/bookings/[id]/page.tsx b/src/app/admin/bookings/[id]/page.tsx deleted file mode 100644 index 185de60..0000000 --- a/src/app/admin/bookings/[id]/page.tsx +++ /dev/null @@ -1,121 +0,0 @@ -import { notFound } from "next/navigation"; -import Link from "next/link"; -import { getBookingForAdmin } from "@/lib/admin/bookings"; -import { StatusBadge } from "@/components/admin/StatusBadge"; -import { BookingActions } from "./_components/BookingActions"; - -export const dynamic = "force-dynamic"; - -type PageProps = { params: Promise<{ id: string }> }; - -export default async function BookingDetailPage({ params }: PageProps) { - const { id } = await params; - const booking = await getBookingForAdmin(id); - if (!booking) notFound(); - - const dateFmt = new Intl.DateTimeFormat("fr-FR", { day: "2-digit", month: "long", year: "numeric" }); - const dateTimeFmt = new Intl.DateTimeFormat("fr-FR", { - day: "2-digit", month: "short", year: "numeric", hour: "2-digit", minute: "2-digit", - }); - const nights = Math.max(1, Math.round((booking.endDate.getTime() - booking.startDate.getTime()) / 86400000)); - - return ( -
-
- - ← Toutes les réservations - -

- Réservation {booking.id.slice(0, 12)} - - -

-

- Créée le {dateTimeFmt.format(booking.createdAt)} · MAJ {dateTimeFmt.format(booking.updatedAt)} -

-
- -
-

Actions

- -
- -
-
-

Séjour

-
- - - 1 ? "s" : ""}`} /> - - -
-
- -
-

Carbet

-
- - {booking.carbet.title} - - } - /> - /{booking.carbet.slug}} /> - - - {booking.carbet.owner.firstName} {booking.carbet.owner.lastName} - - } - /> -
-
- -
-

Locataire

-
- - {booking.tenant.firstName} {booking.tenant.lastName} - - } - /> - - {booking.tenant.phone ? : null} - -
-
- -
-

Avis

- {booking.review ? ( -

- Note {booking.review.rating}/5 · déposé le {dateFmt.format(booking.review.createdAt)} ·{" "} - - Voir l'avis - -

- ) : ( -

Pas encore d'avis pour cette réservation.

- )} -
-
-
- ); -} - -function Row({ label, value }: { label: string; value: React.ReactNode }) { - return ( -
-
{label}
-
{value}
-
- ); -} diff --git a/src/app/admin/bookings/actions.ts b/src/app/admin/bookings/actions.ts deleted file mode 100644 index ca9e401..0000000 --- a/src/app/admin/bookings/actions.ts +++ /dev/null @@ -1,108 +0,0 @@ -"use server"; - -import { revalidatePath } from "next/cache"; -import { auth } from "@/auth"; -import { BookingStatus, PaymentStatus, UserRole } from "@/generated/prisma/enums"; -import { requireRole } from "@/lib/authorization"; -import { prisma } from "@/lib/prisma"; -import { recordAudit } from "@/lib/admin/audit"; -import { sendBookingConfirmed, sendBookingRefunded } from "@/lib/email"; - -async function audit(event: string, target: string, actor: string | null, details: Record) { - await recordAudit({ scope: "admin.bookings", event, target, actorEmail: actor, details }); -} - -const ALLOWED_STATUS = new Set([ - BookingStatus.PENDING, - BookingStatus.CONFIRMED, - BookingStatus.CANCELLED, - BookingStatus.COMPLETED, -]); -const ALLOWED_PAYMENT = new Set([ - PaymentStatus.PENDING, - PaymentStatus.AUTHORIZED, - PaymentStatus.SUCCEEDED, - PaymentStatus.FAILED, - PaymentStatus.REFUNDED, -]); - -export async function updateBookingStatusAction(id: string, status: string) { - await requireRole([UserRole.ADMIN]); - if (!ALLOWED_STATUS.has(status)) { - return { ok: false as const, error: "Statut invalide" }; - } - const session = await auth(); - const before = await prisma.booking.findUnique({ - where: { id }, - select: { status: true }, - }); - const updated = await prisma.booking.update({ - where: { id }, - data: { status: status as BookingStatus }, - include: { - tenant: { select: { email: true, firstName: true } }, - carbet: { select: { title: true } }, - }, - }); - await audit("booking.status.update", id, session?.user?.email ?? null, { status }); - if ( - before?.status !== BookingStatus.CONFIRMED && - updated.status === BookingStatus.CONFIRMED - ) { - sendBookingConfirmed( - updated.tenant.email, - updated.tenant.firstName, - updated.id, - updated.carbet.title, - updated.startDate, - updated.endDate, - ).catch(() => {}); - } - revalidatePath("/admin/bookings"); - revalidatePath(`/admin/bookings/${id}`); - return { ok: true as const }; -} - -export async function updateBookingPaymentAction(id: string, paymentStatus: string) { - await requireRole([UserRole.ADMIN]); - if (!ALLOWED_PAYMENT.has(paymentStatus)) { - return { ok: false as const, error: "Statut de paiement invalide" }; - } - const session = await auth(); - await prisma.booking.update({ - where: { id }, - data: { paymentStatus: paymentStatus as PaymentStatus }, - }); - await audit("booking.payment.update", id, session?.user?.email ?? null, { paymentStatus }); - revalidatePath("/admin/bookings"); - revalidatePath(`/admin/bookings/${id}`); - return { ok: true as const }; -} - -export async function refundBookingAction(id: string) { - await requireRole([UserRole.ADMIN]); - const session = await auth(); - const updated = await prisma.booking.update({ - where: { id }, - data: { - paymentStatus: PaymentStatus.REFUNDED, - status: BookingStatus.CANCELLED, - }, - include: { - tenant: { select: { email: true, firstName: true } }, - carbet: { select: { title: true } }, - }, - }); - await audit("booking.refund", id, session?.user?.email ?? null, {}); - sendBookingRefunded( - updated.tenant.email, - updated.tenant.firstName, - updated.id, - updated.carbet.title, - updated.amount.toString(), - updated.currency, - ).catch(() => {}); - revalidatePath("/admin/bookings"); - revalidatePath(`/admin/bookings/${id}`); - return { ok: true as const }; -} diff --git a/src/app/admin/bookings/page.tsx b/src/app/admin/bookings/page.tsx deleted file mode 100644 index c938c17..0000000 --- a/src/app/admin/bookings/page.tsx +++ /dev/null @@ -1,184 +0,0 @@ -import Link from "next/link"; -import { BookingStatus, PaymentStatus } from "@/generated/prisma/enums"; -import { listBookingsAdmin } from "@/lib/admin/bookings"; -import { StatusBadge } from "@/components/admin/StatusBadge"; - -export const dynamic = "force-dynamic"; - -type PageProps = { - searchParams: Promise<{ - q?: string; - status?: string; - paymentStatus?: string; - from?: string; - to?: string; - }>; -}; - -const STATUS_VALUES = new Set([ - BookingStatus.PENDING, - BookingStatus.CONFIRMED, - BookingStatus.CANCELLED, - BookingStatus.COMPLETED, -]); -const PAYMENT_VALUES = new Set([ - PaymentStatus.PENDING, - PaymentStatus.AUTHORIZED, - PaymentStatus.SUCCEEDED, - PaymentStatus.FAILED, - PaymentStatus.REFUNDED, -]); - -function parseDate(v?: string): Date | undefined { - if (!v) return undefined; - const d = new Date(v); - return isNaN(d.getTime()) ? undefined : d; -} - -export default async function BookingsAdminPage({ searchParams }: PageProps) { - const sp = await searchParams; - const filters = { - q: sp.q?.trim() || undefined, - status: STATUS_VALUES.has(sp.status ?? "") ? (sp.status as BookingStatus) : undefined, - paymentStatus: PAYMENT_VALUES.has(sp.paymentStatus ?? "") - ? (sp.paymentStatus as PaymentStatus) - : undefined, - from: parseDate(sp.from), - to: parseDate(sp.to), - }; - const bookings = await listBookingsAdmin(filters); - const dateFmt = new Intl.DateTimeFormat("fr-FR", { day: "2-digit", month: "short", year: "2-digit" }); - - return ( -
-
-
-

Réservations

-

- {bookings.length} résultat{bookings.length > 1 ? "s" : ""} - {bookings.length === 200 ? " (limite atteinte — affinez les filtres)" : ""} -

-
-
- -
- - - - - - - {(filters.q || filters.status || filters.paymentStatus || filters.from || filters.to) ? ( - - Réinit. - - ) : null} -
- -
- - - - - - - - - - - - - - - - {bookings.length === 0 ? ( - - - - ) : null} - {bookings.map((b) => ( - - - - - - - - - - - - ))} - -
IDCarbetLocataireSéjourPers.MontantStatutPaiementCréé
- Aucune réservation ne correspond aux filtres. -
- - {b.id.slice(0, 10)}… - - - - {b.carbet.title} - -
- /{b.carbet.slug} -
-
- {b.tenant.firstName} {b.tenant.lastName} -
{b.tenant.email}
-
- {dateFmt.format(b.startDate)} → {dateFmt.format(b.endDate)} - {b.guestCount} - {Number(b.amount).toFixed(2)} {b.currency} - - {dateFmt.format(b.createdAt)} -
-
-
- ); -} diff --git a/src/app/admin/carbets/[id]/_components/CarbetMemberships.tsx b/src/app/admin/carbets/[id]/_components/CarbetMemberships.tsx deleted file mode 100644 index 95bfc88..0000000 --- a/src/app/admin/carbets/[id]/_components/CarbetMemberships.tsx +++ /dev/null @@ -1,125 +0,0 @@ -"use client"; - -import { useState, useTransition } from "react"; - -type Org = { id: string; name: string; slug: string; approved: boolean }; -type LinkedOrg = Org & { addedAt: Date }; - -type Props = { - carbetId: string; - linked: LinkedOrg[]; - available: Org[]; - linkAction: (carbetId: string, orgId: string) => Promise<{ ok: true; alreadyLinked: boolean } | { ok: false; error?: string }>; - unlinkAction: (carbetId: string, orgId: string) => Promise<{ ok: true } | { ok: false; error?: string }>; -}; - -export function CarbetMemberships({ - carbetId, - linked, - available, - linkAction, - unlinkAction, -}: Props) { - const [pending, startTransition] = useTransition(); - const [selectedOrgId, setSelectedOrgId] = useState(""); - const [error, setError] = useState(null); - - // Filtre les orgs non encore liées - const linkedIds = new Set(linked.map((l) => l.id)); - const options = available.filter((o) => !linkedIds.has(o.id)); - - function link() { - if (!selectedOrgId) return; - setError(null); - startTransition(async () => { - const res = await linkAction(carbetId, selectedOrgId); - if (!res.ok) setError(res.error || "Échec de la liaison"); - else setSelectedOrgId(""); - }); - } - - function unlink(orgId: string) { - setError(null); - startTransition(async () => { - const res = await unlinkAction(carbetId, orgId); - if (!res.ok) setError(res.error || "Échec"); - }); - } - - return ( -
- {linked.length === 0 ? ( -

- Aucune organisation liée. Le carbet est géré uniquement par son propriétaire individuel. -

- ) : ( -
    - {linked.map((o) => ( -
  • -
    - {o.name} - /{o.slug} - {!o.approved ? ( - - Pending - - ) : null} -
    - -
  • - ))} -
- )} - - {options.length > 0 ? ( -
- - -
- ) : ( -

- Toutes les organisations existantes sont déjà liées à ce carbet. -

- )} - - {error ? ( -
- {error} -
- ) : null} - -

- Une organisation liée signifie que ses CE_MANAGERs peuvent éditer ce carbet en plus du - propriétaire nominal. -

-
- ); -} diff --git a/src/app/admin/carbets/[id]/_components/MediaManager.tsx b/src/app/admin/carbets/[id]/_components/MediaManager.tsx index ab91606..47947da 100644 --- a/src/app/admin/carbets/[id]/_components/MediaManager.tsx +++ b/src/app/admin/carbets/[id]/_components/MediaManager.tsx @@ -1,6 +1,7 @@ "use client"; import { useState, useTransition } from "react"; +import Image from "next/image"; import { addMediaAction, removeMediaAction, reorderMediaAction } from "../../actions"; import { FormField, inputCls, selectCls } from "@/components/admin/FormField"; @@ -124,7 +125,7 @@ export function MediaManager({ carbetId, media: initial }: { carbetId: string; m - {/* Le serveur calcule un s3Key déterministe à partir de l'URL si vide. */} + {error ?
{error}
: null}