Merge remote-tracking branch 'origin/main' into feat/project-premium-geo-db-addon

# Conflicts:
#	bun.lock
#	package.json
This commit is contained in:
Damodar Lohani
2026-05-11 06:25:35 +00:00
114 changed files with 1620 additions and 903 deletions
+2 -2
View File
@@ -17,9 +17,9 @@ jobs:
permissions:
contents: read
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Setup Bun
uses: oven-sh/setup-bun@v2
uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0
with:
bun-version: 1.3.8
+6 -6
View File
@@ -14,20 +14,20 @@ jobs:
steps:
- name: Checkout the repo
uses: actions/checkout@v2
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Set up QEMU
uses: docker/setup-qemu-action@v2
uses: docker/setup-qemu-action@ce360397dd3f832beb865e1373c09c0e9f86d70a # v4.0.0
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4.0.0
- name: Log in to Docker Hub
uses: docker/login-action@v3
uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4.1.0
with:
username: ${{ vars.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Extract metadata (tags, labels) for Docker
id: meta
uses: docker/metadata-action@v5
uses: docker/metadata-action@030e881283bb7a6894de51c315a6bfe6a94e05cf # v6.0.0
with:
images: appwrite/console-profiles
tags: |
@@ -40,7 +40,7 @@ jobs:
- name: Build and push Docker image
id: push
uses: docker/build-push-action@v6
uses: docker/build-push-action@bcafcacb16a39f128d818304e6c9c0c18556b85f # v7.1.0
with:
context: .
push: true
+4 -4
View File
@@ -11,9 +11,9 @@ jobs:
e2e:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Setup Bun
uses: oven-sh/setup-bun@v2
uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0
with:
bun-version: 1.3.8
@@ -21,7 +21,7 @@ jobs:
run: bun install --frozen-lockfile
- name: Cache Playwright browsers
uses: actions/cache@v4
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
id: playwright-cache
with:
path: ~/.cache/ms-playwright
@@ -34,7 +34,7 @@ jobs:
- name: E2E Tests
run: bun test:e2e
- uses: actions/upload-artifact@v4
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
if: ${{ !cancelled() }}
with:
name: playwright-report
+24 -24
View File
@@ -9,19 +9,19 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout the repo
uses: actions/checkout@v2
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Set up QEMU
uses: docker/setup-qemu-action@v2
uses: docker/setup-qemu-action@ce360397dd3f832beb865e1373c09c0e9f86d70a # v4.0.0
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4.0.0
- name: Log in to Docker Hub
uses: docker/login-action@v3
uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4.1.0
with:
username: ${{ vars.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Extract metadata (tags, labels) for Docker
id: meta
uses: docker/metadata-action@v5
uses: docker/metadata-action@030e881283bb7a6894de51c315a6bfe6a94e05cf # v6.0.0
with:
images: appwrite/console-cloud
tags: |
@@ -30,7 +30,7 @@ jobs:
type=semver,pattern={{major}}
- name: Build and push Docker image
id: push
uses: docker/build-push-action@v6
uses: docker/build-push-action@bcafcacb16a39f128d818304e6c9c0c18556b85f # v7.1.0
with:
context: .
push: true
@@ -51,19 +51,19 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout the repo
uses: actions/checkout@v2
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Set up QEMU
uses: docker/setup-qemu-action@v2
uses: docker/setup-qemu-action@ce360397dd3f832beb865e1373c09c0e9f86d70a # v4.0.0
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4.0.0
- name: Log in to Docker Hub
uses: docker/login-action@v3
uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4.1.0
with:
username: ${{ vars.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Extract metadata (tags, labels) for Docker
id: meta
uses: docker/metadata-action@v5
uses: docker/metadata-action@030e881283bb7a6894de51c315a6bfe6a94e05cf # v6.0.0
with:
images: appwrite/console-cloud-stage
tags: |
@@ -72,7 +72,7 @@ jobs:
type=semver,pattern={{major}}
- name: Build and push Docker image
id: push
uses: docker/build-push-action@v6
uses: docker/build-push-action@bcafcacb16a39f128d818304e6c9c0c18556b85f # v7.1.0
with:
context: .
push: true
@@ -91,19 +91,19 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout the repo
uses: actions/checkout@v2
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Set up QEMU
uses: docker/setup-qemu-action@v2
uses: docker/setup-qemu-action@ce360397dd3f832beb865e1373c09c0e9f86d70a # v4.0.0
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4.0.0
- name: Log in to Docker Hub
uses: docker/login-action@v3
uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4.1.0
with:
username: ${{ vars.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Extract metadata (tags, labels) for Docker
id: meta
uses: docker/metadata-action@902fa8ec7d6ecbf8d84d538b9b233a880e428804 # v5.7.0
uses: docker/metadata-action@030e881283bb7a6894de51c315a6bfe6a94e05cf # v6.0.0
with:
images: appwrite/console
tags: |
@@ -112,7 +112,7 @@ jobs:
type=semver,pattern={{major}}
- name: Build and push Docker image
id: push
uses: docker/build-push-action@v6
uses: docker/build-push-action@bcafcacb16a39f128d818304e6c9c0c18556b85f # v7.1.0
with:
context: .
push: true
@@ -130,19 +130,19 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout the repo
uses: actions/checkout@v2
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Set up QEMU
uses: docker/setup-qemu-action@v2
uses: docker/setup-qemu-action@ce360397dd3f832beb865e1373c09c0e9f86d70a # v4.0.0
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4.0.0
- name: Log in to Docker Hub
uses: docker/login-action@v3
uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4.1.0
with:
username: ${{ vars.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Extract metadata (tags, labels) for Docker
id: meta
uses: docker/metadata-action@v5
uses: docker/metadata-action@030e881283bb7a6894de51c315a6bfe6a94e05cf # v6.0.0
with:
images: appwrite/console-cloud-no-regions
tags: |
@@ -151,7 +151,7 @@ jobs:
type=semver,pattern={{major}}
- name: Build and push Docker image
id: push
uses: docker/build-push-action@v6
uses: docker/build-push-action@bcafcacb16a39f128d818304e6c9c0c18556b85f # v7.1.0
with:
context: .
push: true
+1 -1
View File
@@ -9,7 +9,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/stale@v9
- uses: actions/stale@b5d41d4e1d5dceea10e7104786b73624c18a190f # v10.2.0
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
stale-issue-message: "This issue has been labeled as a 'question', indicating that it requires additional information from the requestor. It has been inactive for 7 days. If no further activity occurs, this issue will be closed in 14 days."
+2 -2
View File
@@ -14,9 +14,9 @@ jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Setup Bun
uses: oven-sh/setup-bun@v2
uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0
with:
bun-version: 1.3.8
+101 -107
View File
@@ -1,6 +1,6 @@
{
"lockfileVersion": 1,
"configVersion": 0,
"configVersion": 1,
"workspaces": {
"": {
"name": "@appwrite/console",
@@ -100,9 +100,9 @@
"packages": {
"@adobe/css-tools": ["@adobe/css-tools@4.4.4", "", {}, "sha512-Elp+iwUx5rN5+Y8xLt5/GRoG20WGoDCQ/1Fb+1LiGtvwbDavuSk0jhD/eZdckHAuzcDzccnkv+rEjyWfRx18gg=="],
"@ai-sdk/gateway": ["@ai-sdk/gateway@3.0.80", "", { "dependencies": { "@ai-sdk/provider": "3.0.8", "@ai-sdk/provider-utils": "4.0.21", "@vercel/oidc": "3.1.0" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-uM7kpZB5l977lW7+2X1+klBUxIZQ78+1a9jHlaHFEzcOcmmslTl3sdP0QqfuuBcO0YBM2gwOiqVdp8i4TRQYcw=="],
"@ai-sdk/gateway": ["@ai-sdk/gateway@3.0.112", "", { "dependencies": { "@ai-sdk/provider": "3.0.10", "@ai-sdk/provider-utils": "4.0.27", "@vercel/oidc": "3.2.0" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-jiBao9pR4owWyjo0BnuNc7WSQBGOD0thysE4AFgZXaG+zMFbISQXUkJr7ePw/phBvePy7jE5FSA2Lf7lwqUiiQ=="],
"@ai-sdk/provider": ["@ai-sdk/provider@3.0.8", "", { "dependencies": { "json-schema": "^0.4.0" } }, "sha512-oGMAgGoQdBXbZqNG0Ze56CHjDZ1IDYOwGYxYjO5KLSlz5HiNQ9udIXsPZ61VWaHGZ5XW/jyjmr6t2xz2jGVwbQ=="],
"@ai-sdk/provider": ["@ai-sdk/provider@3.0.10", "", { "dependencies": { "json-schema": "^0.4.0" } }, "sha512-Q3BZ27qfpYqnCYGvE3vt+Qi6LGOF9R5Nmzn+9JoM1lCRsD9mYaIhfJLkSunN48nfGXJ6n+XNV0J/XVpqGQl7Dw=="],
"@ai-sdk/provider-utils": ["@ai-sdk/provider-utils@2.1.13", "", { "dependencies": { "@ai-sdk/provider": "1.0.11", "eventsource-parser": "^3.0.0", "nanoid": "^3.3.8", "secure-json-parse": "^2.7.0" }, "peerDependencies": { "zod": "^3.0.0" }, "optionalPeers": ["zod"] }, "sha512-kLjqsfOdONr6DGcGEntFYM1niXz1H05vyZNf9OAzK+KKKc64izyP4/q/9HX7W4+6g8hm6BnmKxu8vkr6FSOqDg=="],
@@ -138,7 +138,7 @@
"@babel/code-frame": ["@babel/code-frame@7.29.0", "", { "dependencies": { "@babel/helper-validator-identifier": "^7.28.5", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" } }, "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw=="],
"@babel/compat-data": ["@babel/compat-data@7.29.0", "", {}, "sha512-T1NCJqT/j9+cn8fvkt7jtwbLBfLC/1y1c7NtCeXFRgzGTsafi68MRv8yzkYSapBnFA6L3U2VSc02ciDzoAJhJg=="],
"@babel/compat-data": ["@babel/compat-data@7.29.3", "", {}, "sha512-LIVqM46zQWZhj17qA8wb4nW/ixr2y1Nw+r1etiAWgRM6U1IqP+LNhL1yg440jYZR72jCWcWbLWzIosH+uP1fqg=="],
"@babel/core": ["@babel/core@7.29.0", "", { "dependencies": { "@babel/code-frame": "^7.29.0", "@babel/generator": "^7.29.0", "@babel/helper-compilation-targets": "^7.28.6", "@babel/helper-module-transforms": "^7.28.6", "@babel/helpers": "^7.28.6", "@babel/parser": "^7.29.0", "@babel/template": "^7.28.6", "@babel/traverse": "^7.29.0", "@babel/types": "^7.29.0", "@jridgewell/remapping": "^2.3.5", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", "json5": "^2.2.3", "semver": "^6.3.1" } }, "sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA=="],
@@ -158,11 +158,11 @@
"@babel/helper-validator-option": ["@babel/helper-validator-option@7.27.1", "", {}, "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg=="],
"@babel/helpers": ["@babel/helpers@7.28.6", "", { "dependencies": { "@babel/template": "^7.28.6", "@babel/types": "^7.28.6" } }, "sha512-xOBvwq86HHdB7WUDTfKfT/Vuxh7gElQ+Sfti2Cy6yIWNW05P8iUslOVcZ4/sKbE+/jQaukQAdz/gf3724kYdqw=="],
"@babel/helpers": ["@babel/helpers@7.29.2", "", { "dependencies": { "@babel/template": "^7.28.6", "@babel/types": "^7.29.0" } }, "sha512-HoGuUs4sCZNezVEKdVcwqmZN8GoHirLUcLaYVNBK2J0DadGtdcqgr3BCbvH8+XUo4NGjNl3VOtSjEKNzqfFgKw=="],
"@babel/parser": ["@babel/parser@7.29.0", "", { "dependencies": { "@babel/types": "^7.29.0" }, "bin": "./bin/babel-parser.js" }, "sha512-IyDgFV5GeDUVX4YdF/3CPULtVGSXXMLh1xVIgdCgxApktqnQV0r7/8Nqthg+8YLGaAtdyIlo2qIdZrbCv4+7ww=="],
"@babel/parser": ["@babel/parser@7.29.3", "", { "dependencies": { "@babel/types": "^7.29.0" }, "bin": "./bin/babel-parser.js" }, "sha512-b3ctpQwp+PROvU/cttc4OYl4MzfJUWy6FZg+PMXfzmt/+39iHVF0sDfqay8TQM3JA2EUOyKcFZt75jWriQijsA=="],
"@babel/runtime": ["@babel/runtime@7.28.6", "", {}, "sha512-05WQkdpL9COIMz4LjTxGpPNCdlpyimKppYNoJ5Di5EUObifl8t4tuLuUBBZEpoLYOmfvIWrsp9fCl0HoPRVTdA=="],
"@babel/runtime": ["@babel/runtime@7.29.2", "", {}, "sha512-JiDShH45zKHWyGe4ZNVRrCjBz8Nh9TMmZG1kh4QTK8hCBTWBi8Da+i7s1fJw7/lYpM4ccepSNfqzZ/QvABBi5g=="],
"@babel/template": ["@babel/template@7.28.6", "", { "dependencies": { "@babel/code-frame": "^7.28.6", "@babel/parser": "^7.28.6", "@babel/types": "^7.28.6" } }, "sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ=="],
@@ -170,19 +170,19 @@
"@babel/types": ["@babel/types@7.29.0", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.28.5" } }, "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A=="],
"@codemirror/autocomplete": ["@codemirror/autocomplete@6.20.1", "", { "dependencies": { "@codemirror/language": "^6.0.0", "@codemirror/state": "^6.0.0", "@codemirror/view": "^6.17.0", "@lezer/common": "^1.0.0" } }, "sha512-1cvg3Vz1dSSToCNlJfRA2WSI4ht3K+WplO0UMOgmUYPivCyy2oueZY6Lx7M9wThm7SDUBViRmuT+OG/i8+ON9A=="],
"@codemirror/autocomplete": ["@codemirror/autocomplete@6.20.2", "", { "dependencies": { "@codemirror/language": "^6.0.0", "@codemirror/state": "^6.0.0", "@codemirror/view": "^6.17.0", "@lezer/common": "^1.0.0" } }, "sha512-G5FPkgIiLjOgZMjqVjvuKQ1rGPtHogLldJr33eFJdVLtmwY+giGrlv/ewljLz6b9BSQLkjxuwBc6g6omDM+YxQ=="],
"@codemirror/commands": ["@codemirror/commands@6.10.3", "", { "dependencies": { "@codemirror/language": "^6.0.0", "@codemirror/state": "^6.6.0", "@codemirror/view": "^6.27.0", "@lezer/common": "^1.1.0" } }, "sha512-JFRiqhKu+bvSkDLI+rUhJwSxQxYb759W5GBezE8Uc8mHLqC9aV/9aTC7yJSqCtB3F00pylrLCwnyS91Ap5ej4Q=="],
"@codemirror/language": ["@codemirror/language@6.12.3", "", { "dependencies": { "@codemirror/state": "^6.0.0", "@codemirror/view": "^6.23.0", "@lezer/common": "^1.5.0", "@lezer/highlight": "^1.0.0", "@lezer/lr": "^1.0.0", "style-mod": "^4.0.0" } }, "sha512-QwCZW6Tt1siP37Jet9Tb02Zs81TQt6qQrZR2H+eGMcFsL1zMrk2/b9CLC7/9ieP1fjIUMgviLWMmgiHoJrj+ZA=="],
"@codemirror/lint": ["@codemirror/lint@6.9.5", "", { "dependencies": { "@codemirror/state": "^6.0.0", "@codemirror/view": "^6.35.0", "crelt": "^1.0.5" } }, "sha512-GElsbU9G7QT9xXhpUg1zWGmftA/7jamh+7+ydKRuT0ORpWS3wOSP0yT1FOlIZa7mIJjpVPipErsyvVqB9cfTFA=="],
"@codemirror/lint": ["@codemirror/lint@6.9.6", "", { "dependencies": { "@codemirror/state": "^6.0.0", "@codemirror/view": "^6.42.0", "crelt": "^1.0.5" } }, "sha512-6Kp7r6XfCi/D/5sdXieMfg9pJU1bUEx96WITuLU6ESaKizCz0QHFMjY/TaFSbigDdEAIgi93itLBIUETP4oK+A=="],
"@codemirror/search": ["@codemirror/search@6.6.0", "", { "dependencies": { "@codemirror/state": "^6.0.0", "@codemirror/view": "^6.37.0", "crelt": "^1.0.5" } }, "sha512-koFuNXcDvyyotWcgOnZGmY7LZqEOXZaaxD/j6n18TCLx2/9HieZJ5H6hs1g8FiRxBD0DNfs0nXn17g872RmYdw=="],
"@codemirror/search": ["@codemirror/search@6.7.0", "", { "dependencies": { "@codemirror/state": "^6.0.0", "@codemirror/view": "^6.37.0", "crelt": "^1.0.5" } }, "sha512-ZvGm99wc/s2cITtMT15LFdn8aH/aS+V+DqyGq/N5ZlV5vWtH+nILvC2nw0zX7ByNoHHDZ2IxxdW38O0tc5nVHg=="],
"@codemirror/state": ["@codemirror/state@6.6.0", "", { "dependencies": { "@marijn/find-cluster-break": "^1.0.0" } }, "sha512-4nbvra5R5EtiCzr9BTHiTLc+MLXK2QGiAVYMyi8PkQd3SR+6ixar/Q/01Fa21TBIDOZXgeWV4WppsQolSreAPQ=="],
"@codemirror/view": ["@codemirror/view@6.41.1", "", { "dependencies": { "@codemirror/state": "^6.6.0", "crelt": "^1.0.6", "style-mod": "^4.1.0", "w3c-keyname": "^2.2.4" } }, "sha512-ToDnWKbBnke+ZLrP6vgTTDScGi5H37YYuZGniQaBzxMVdtCxMrslsmtnOvbPZk4RX9bvkQqnWR/WS/35tJA0qg=="],
"@codemirror/view": ["@codemirror/view@6.42.1", "", { "dependencies": { "@codemirror/state": "^6.6.0", "crelt": "^1.0.6", "style-mod": "^4.1.0", "w3c-keyname": "^2.2.4" } }, "sha512-ToN3oFc0nsxNUYVF5P0ztLgbC4UPPjPtA9aKYhkOKQaZASpOUo6ISXyQLP66ctVwlDc+j6Jv0uK5IFALkiXztg=="],
"@csstools/color-helpers": ["@csstools/color-helpers@5.1.0", "", {}, "sha512-S11EXWJyy0Mz5SYvRmY8nJYTFFd1LCNV+7cXyAgQtOOuzb4EsgfqDufL+9esx72/eLhsRdGZwaldu/h+E4t4BA=="],
@@ -196,11 +196,11 @@
"@dimforge/rapier3d-compat": ["@dimforge/rapier3d-compat@0.12.0", "", {}, "sha512-uekIGetywIgopfD97oDL5PfeezkFpNhwlzlaEYNOA0N6ghdsOvh/HYjSMek5Q2O1PYvRSDFcqFVJl4r4ZBwOow=="],
"@emnapi/core": ["@emnapi/core@1.9.0", "", { "dependencies": { "@emnapi/wasi-threads": "1.2.0", "tslib": "^2.4.0" } }, "sha512-0DQ98G9ZQZOxfUcQn1waV2yS8aWdZ6kJMbYCJB3oUBecjWYO1fqJ+a1DRfPF3O5JEkwqwP1A9QEN/9mYm2Yd0w=="],
"@emnapi/core": ["@emnapi/core@1.10.0", "", { "dependencies": { "@emnapi/wasi-threads": "1.2.1", "tslib": "^2.4.0" } }, "sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw=="],
"@emnapi/runtime": ["@emnapi/runtime@1.9.0", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-QN75eB0IH2ywSpRpNddCRfQIhmJYBCJ1x5Lb3IscKAL8bMnVAKnRg8dCoXbHzVLLH7P38N2Z3mtulB7W0J0FKw=="],
"@emnapi/runtime": ["@emnapi/runtime@1.10.0", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA=="],
"@emnapi/wasi-threads": ["@emnapi/wasi-threads@1.2.0", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-N10dEJNSsUx41Z6pZsXU8FjPjpBEplgH24sfkmITrBED1/U2Esum9F3lfLrMjKHHjmi557zQn7kR9R+XWXu5Rg=="],
"@emnapi/wasi-threads": ["@emnapi/wasi-threads@1.2.1", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w=="],
"@eslint-community/eslint-utils": ["@eslint-community/eslint-utils@4.9.1", "", { "dependencies": { "eslint-visitor-keys": "^3.4.3" }, "peerDependencies": { "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" } }, "sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ=="],
@@ -230,15 +230,17 @@
"@floating-ui/utils": ["@floating-ui/utils@0.2.11", "", {}, "sha512-RiB/yIh78pcIxl6lLMG0CgBXAZ2Y0eVHqMPYugu+9U0AeT6YBeiJpf7lbdJNIugFP5SIjwNRgo4DhR1Qxi26Gg=="],
"@humanfs/core": ["@humanfs/core@0.19.1", "", {}, "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA=="],
"@humanfs/core": ["@humanfs/core@0.19.2", "", { "dependencies": { "@humanfs/types": "^0.15.0" } }, "sha512-UhXNm+CFMWcbChXywFwkmhqjs3PRCmcSa/hfBgLIb7oQ5HNb1wS0icWsGtSAUNgefHeI+eBrA8I1fxmbHsGdvA=="],
"@humanfs/node": ["@humanfs/node@0.16.7", "", { "dependencies": { "@humanfs/core": "^0.19.1", "@humanwhocodes/retry": "^0.4.0" } }, "sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ=="],
"@humanfs/node": ["@humanfs/node@0.16.8", "", { "dependencies": { "@humanfs/core": "^0.19.2", "@humanfs/types": "^0.15.0", "@humanwhocodes/retry": "^0.4.0" } }, "sha512-gE1eQNZ3R++kTzFUpdGlpmy8kDZD/MLyHqDwqjkVQI0JMdI1D51sy1H958PNXYkM2rAac7e5/CnIKZrHtPh3BQ=="],
"@humanfs/types": ["@humanfs/types@0.15.0", "", {}, "sha512-ZZ1w0aoQkwuUuC7Yf+7sdeaNfqQiiLcSRbfI08oAxqLtpXQr9AIVX7Ay7HLDuiLYAaFPu8oBYNq/QIi9URHJ3Q=="],
"@humanwhocodes/module-importer": ["@humanwhocodes/module-importer@1.0.1", "", {}, "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA=="],
"@humanwhocodes/retry": ["@humanwhocodes/retry@0.4.3", "", {}, "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ=="],
"@internationalized/date": ["@internationalized/date@3.12.0", "", { "dependencies": { "@swc/helpers": "^0.5.0" } }, "sha512-/PyIMzK29jtXaGU23qTvNZxvBXRtKbNnGDFD+PY6CZw/Y8Ex8pFUzkuCJCG9aOqmShjqhS9mPqP6Dk5onQY8rQ=="],
"@internationalized/date": ["@internationalized/date@3.12.1", "", { "dependencies": { "@swc/helpers": "^0.5.0" } }, "sha512-6IedsVWXyq4P9Tj+TxuU8WGWM70hYLl12nbYU8jkikVpa6WXapFazPUcHUMDMoWftIDE2ILDkFFte6W2nFCkRQ=="],
"@jridgewell/gen-mapping": ["@jridgewell/gen-mapping@0.3.13", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA=="],
@@ -262,7 +264,7 @@
"@melt-ui/svelte": ["@melt-ui/svelte@0.86.6", "", { "dependencies": { "@floating-ui/core": "^1.3.1", "@floating-ui/dom": "^1.4.5", "@internationalized/date": "^3.5.0", "dequal": "^2.0.3", "focus-trap": "^7.5.2", "nanoid": "^5.0.4" }, "peerDependencies": { "svelte": "^3.0.0 || ^4.0.0 || ^5.0.0-next.118" } }, "sha512-Jer+M7DgIwT5IHfTayb4Iw/fkkxWNmC/mqn/nMh9JrbPbkxmyabfLQnhJ+JDn5HK77f84j34lubO3iqFtYAfMg=="],
"@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@1.1.1", "", { "dependencies": { "@emnapi/core": "^1.7.1", "@emnapi/runtime": "^1.7.1", "@tybys/wasm-util": "^0.10.1" } }, "sha512-p64ah1M1ld8xjWv3qbvFwHiFVWrq1yFvV4f7w+mzaqiR4IlSgkqhcRdHwsGgomwzBH51sRY4NEowLxnaBjcW/A=="],
"@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@1.1.4", "", { "dependencies": { "@tybys/wasm-util": "^0.10.1" }, "peerDependencies": { "@emnapi/core": "^1.7.1", "@emnapi/runtime": "^1.7.1" } }, "sha512-3NQNNgA1YSlJb/kMH1ildASP9HW7/7kYnRI2szWJaofaS1hWmbGI4H+d3+22aGzXXN9IJ+n+GiFVcGipJP18ow=="],
"@opentelemetry/api": ["@opentelemetry/api@1.9.0", "", {}, "sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg=="],
@@ -364,9 +366,9 @@
"@parcel/watcher-win32-x64": ["@parcel/watcher-win32-x64@2.5.6", "", { "os": "win32", "cpu": "x64" }, "sha512-hbQlYcCq5dlAX9Qx+kFb0FHue6vbjlf0FrNzSKdYK2APUf7tGfGxQCk2ihEREmbR6ZMc0MVAD5RIX/41gpUzTw=="],
"@plausible-analytics/tracker": ["@plausible-analytics/tracker@0.4.4", "", {}, "sha512-fz0NOYUEYXtg1TBaPEEvtcBq3FfmLFuTe1VZw4M8sTWX129br5dguu3M15+plOQnc181ShYe67RfwhKgK89VnA=="],
"@plausible-analytics/tracker": ["@plausible-analytics/tracker@0.4.5", "", {}, "sha512-6BfAGejXY+YA3Cw6LYT2Zpn4hTxDtPQAawFsYUsQCOg78wIS5C4deAGXTfJffa5VleMWITv5lpJ/EYuQBl1tPA=="],
"@playwright/test": ["@playwright/test@1.58.2", "", { "dependencies": { "playwright": "1.58.2" }, "bin": { "playwright": "cli.js" } }, "sha512-akea+6bHYBBfA9uQqSYmlJXn61cTa+jbO87xVLCWbTqbWadRVmhxlXATaOjOgcBaWU4ePo0wB41KMFv3o35IXA=="],
"@playwright/test": ["@playwright/test@1.59.1", "", { "dependencies": { "playwright": "1.59.1" }, "bin": { "playwright": "cli.js" } }, "sha512-PG6q63nQg5c9rIi4/Z5lR5IVF7yU5MqmKaPOe0HSc0O2cX1fPi96sUQu5j7eo4gKCkB2AnNGoWt7y4/Xx3Kcqg=="],
"@polka/url": ["@polka/url@1.0.0-next.29", "", {}, "sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww=="],
@@ -402,17 +404,17 @@
"@rolldown/pluginutils": ["@rolldown/pluginutils@1.0.0-beta.53", "", {}, "sha512-vENRlFU4YbrwVqNDZ7fLvy+JR1CRkyr01jhSiDpE1u6py3OMzQfztQU2jxykW3ALNxO4kSlqIDeYyD0Y9RcQeQ=="],
"@sentry-internal/browser-utils": ["@sentry-internal/browser-utils@8.55.1", "", { "dependencies": { "@sentry/core": "8.55.1" } }, "sha512-SipXiwVhJrxzy3/4kf+YIFmpYlLKtGSRD+er7SBCcuSBtv31Fee8IXMDvk+bq24gRXxyjOLUmT//GGXjy2LL6w=="],
"@sentry-internal/browser-utils": ["@sentry-internal/browser-utils@8.55.2", "", { "dependencies": { "@sentry/core": "8.55.2" } }, "sha512-GnKod+gL/Y+1FUM/RGV8q6le1CoyiGbT40MitEK7eVwWe+bfTRq1gN7ioupyHFMUg1RlQkDQ4/sENmio/uow5A=="],
"@sentry-internal/feedback": ["@sentry-internal/feedback@8.55.1", "", { "dependencies": { "@sentry/core": "8.55.1" } }, "sha512-9iFHaT/ijtzB0ffZhXMnt2rPNIXO/dDiCL1G1Bc55rQMPXgawR9AIaAWciyqQjYcbL1DDOhWbzdVqB+kVs5gXw=="],
"@sentry-internal/feedback": ["@sentry-internal/feedback@8.55.2", "", { "dependencies": { "@sentry/core": "8.55.2" } }, "sha512-XQy//NWbL0mLLM5w8wNDWMNpXz39VUyW2397dUrH8++kR63WhUVAvTOtL0o0GMVadSAzl1b08oHP9zSUNFQwcg=="],
"@sentry-internal/replay": ["@sentry-internal/replay@8.55.1", "", { "dependencies": { "@sentry-internal/browser-utils": "8.55.1", "@sentry/core": "8.55.1" } }, "sha512-XaX6r8pXeX47rfiQrSQUwkgxHsDkOKzIT++zfTwrmveVlYSqAhp3x+AKhxAXGmKG62wlmAKQz54GJKcG4cgyKQ=="],
"@sentry-internal/replay": ["@sentry-internal/replay@8.55.2", "", { "dependencies": { "@sentry-internal/browser-utils": "8.55.2", "@sentry/core": "8.55.2" } }, "sha512-+W43Z697EVe/OgpGW07B773sa8xO1UbpnW0Cr+E+3FMDb6ZbXlaBUoagPTUkkQPdwBe35SDh6r8y2M3EOPGbxg=="],
"@sentry-internal/replay-canvas": ["@sentry-internal/replay-canvas@8.55.1", "", { "dependencies": { "@sentry-internal/replay": "8.55.1", "@sentry/core": "8.55.1" } }, "sha512-2sKRu96Qe70y6TiYdYbwkhg4um2prgzH/ZJRItuoSEAjPjoFYYlP+1qjE2CcBw4RPS8/PimV7SFheSaeZs2GCw=="],
"@sentry-internal/replay-canvas": ["@sentry-internal/replay-canvas@8.55.2", "", { "dependencies": { "@sentry-internal/replay": "8.55.2", "@sentry/core": "8.55.2" } }, "sha512-P/jGiuR7dRLG9IzD/463fLgiibyYceauav/9prRG0ZxJm1AtuO02OKball2Fs3bbzdzwHCTlcsUuL2ivDF4b5A=="],
"@sentry/babel-plugin-component-annotate": ["@sentry/babel-plugin-component-annotate@2.22.6", "", {}, "sha512-V2g1Y1I5eSe7dtUVMBvAJr8BaLRr4CLrgNgtPaZyMT4Rnps82SrZ5zqmEkLXPumlXhLUWR6qzoMNN2u+RXVXfQ=="],
"@sentry/browser": ["@sentry/browser@8.55.1", "", { "dependencies": { "@sentry-internal/browser-utils": "8.55.1", "@sentry-internal/feedback": "8.55.1", "@sentry-internal/replay": "8.55.1", "@sentry-internal/replay-canvas": "8.55.1", "@sentry/core": "8.55.1" } }, "sha512-OEn2eg8h3Mr7BmBGQ28BqbWehYA/NklZ0pAZB1FypPPl+kMd85AbaRdGTnaSjgmpc8bKbBO64edq4Y14sbCs5w=="],
"@sentry/browser": ["@sentry/browser@8.55.2", "", { "dependencies": { "@sentry-internal/browser-utils": "8.55.2", "@sentry-internal/feedback": "8.55.2", "@sentry-internal/replay": "8.55.2", "@sentry-internal/replay-canvas": "8.55.2", "@sentry/core": "8.55.2" } }, "sha512-xHuPIEKhx9zw5quWvv4YgZprnwoVMCfxIhmOIf6KJ9iizyUHeUDcKpLS59xERroqwX4RpvK+l/27AZu4zfZlzQ=="],
"@sentry/bundler-plugin-core": ["@sentry/bundler-plugin-core@2.22.6", "", { "dependencies": { "@babel/core": "^7.18.5", "@sentry/babel-plugin-component-annotate": "2.22.6", "@sentry/cli": "^2.36.1", "dotenv": "^16.3.1", "find-up": "^5.0.0", "glob": "^9.3.2", "magic-string": "0.30.8", "unplugin": "1.0.1" } }, "sha512-1esQdgSUCww9XAntO4pr7uAM5cfGhLsgTK9MEwAKNfvpMYJi9NUTYa3A7AZmdA8V6107Lo4OD7peIPrDRbaDCg=="],
@@ -434,15 +436,15 @@
"@sentry/cli-win32-x64": ["@sentry/cli-win32-x64@2.58.5", "", { "os": "win32", "cpu": "x64" }, "sha512-IZf+XIMiQwj+5NzqbOQfywlOitmCV424Vtf9c+ep61AaVScUFD1TSrQbOcJJv5xGxhlxNOMNgMeZhdexdzrKZg=="],
"@sentry/core": ["@sentry/core@8.55.1", "", {}, "sha512-0ea+yDOgaijR3ba2al1QZxY0bZ9MBZq2a0G+2A0uCBpBkiXnpLFGVAo9UAlEikN1C4M8ROZYiuFU7yZCqacgLQ=="],
"@sentry/core": ["@sentry/core@8.55.2", "", {}, "sha512-YlEBwybUcOQ/KjMHDmof1vwweVnBtBxYlQp7DE3fOdtW4pqqdHWTnTntQs4VgYfxzjJYgtkd9LHlGtg8qy+JVQ=="],
"@sentry/node": ["@sentry/node@8.55.1", "", { "dependencies": { "@opentelemetry/api": "^1.9.0", "@opentelemetry/context-async-hooks": "^1.30.1", "@opentelemetry/core": "^1.30.1", "@opentelemetry/instrumentation": "^0.57.1", "@opentelemetry/instrumentation-amqplib": "^0.46.0", "@opentelemetry/instrumentation-connect": "0.43.0", "@opentelemetry/instrumentation-dataloader": "0.16.0", "@opentelemetry/instrumentation-express": "0.47.0", "@opentelemetry/instrumentation-fastify": "0.44.1", "@opentelemetry/instrumentation-fs": "0.19.0", "@opentelemetry/instrumentation-generic-pool": "0.43.0", "@opentelemetry/instrumentation-graphql": "0.47.0", "@opentelemetry/instrumentation-hapi": "0.45.1", "@opentelemetry/instrumentation-http": "0.57.1", "@opentelemetry/instrumentation-ioredis": "0.47.0", "@opentelemetry/instrumentation-kafkajs": "0.7.0", "@opentelemetry/instrumentation-knex": "0.44.0", "@opentelemetry/instrumentation-koa": "0.47.0", "@opentelemetry/instrumentation-lru-memoizer": "0.44.0", "@opentelemetry/instrumentation-mongodb": "0.51.0", "@opentelemetry/instrumentation-mongoose": "0.46.0", "@opentelemetry/instrumentation-mysql": "0.45.0", "@opentelemetry/instrumentation-mysql2": "0.45.0", "@opentelemetry/instrumentation-nestjs-core": "0.44.0", "@opentelemetry/instrumentation-pg": "0.50.0", "@opentelemetry/instrumentation-redis-4": "0.46.0", "@opentelemetry/instrumentation-tedious": "0.18.0", "@opentelemetry/instrumentation-undici": "0.10.0", "@opentelemetry/resources": "^1.30.1", "@opentelemetry/sdk-trace-base": "^1.30.1", "@opentelemetry/semantic-conventions": "^1.28.0", "@prisma/instrumentation": "5.22.0", "@sentry/core": "8.55.1", "@sentry/opentelemetry": "8.55.1", "import-in-the-middle": "^1.11.2" } }, "sha512-s8ydn/OxZFIxc9Fvt23gJkrXkCvPnUu2bDKwjQBCx0M1b4DdNdp4FaimT6B9reya7buj+tsNkZAoT11KqFhG/g=="],
"@sentry/node": ["@sentry/node@8.55.2", "", { "dependencies": { "@opentelemetry/api": "^1.9.0", "@opentelemetry/context-async-hooks": "^1.30.1", "@opentelemetry/core": "^1.30.1", "@opentelemetry/instrumentation": "^0.57.1", "@opentelemetry/instrumentation-amqplib": "^0.46.0", "@opentelemetry/instrumentation-connect": "0.43.0", "@opentelemetry/instrumentation-dataloader": "0.16.0", "@opentelemetry/instrumentation-express": "0.47.0", "@opentelemetry/instrumentation-fastify": "0.44.1", "@opentelemetry/instrumentation-fs": "0.19.0", "@opentelemetry/instrumentation-generic-pool": "0.43.0", "@opentelemetry/instrumentation-graphql": "0.47.0", "@opentelemetry/instrumentation-hapi": "0.45.1", "@opentelemetry/instrumentation-http": "0.57.1", "@opentelemetry/instrumentation-ioredis": "0.47.0", "@opentelemetry/instrumentation-kafkajs": "0.7.0", "@opentelemetry/instrumentation-knex": "0.44.0", "@opentelemetry/instrumentation-koa": "0.47.0", "@opentelemetry/instrumentation-lru-memoizer": "0.44.0", "@opentelemetry/instrumentation-mongodb": "0.51.0", "@opentelemetry/instrumentation-mongoose": "0.46.0", "@opentelemetry/instrumentation-mysql": "0.45.0", "@opentelemetry/instrumentation-mysql2": "0.45.0", "@opentelemetry/instrumentation-nestjs-core": "0.44.0", "@opentelemetry/instrumentation-pg": "0.50.0", "@opentelemetry/instrumentation-redis-4": "0.46.0", "@opentelemetry/instrumentation-tedious": "0.18.0", "@opentelemetry/instrumentation-undici": "0.10.0", "@opentelemetry/resources": "^1.30.1", "@opentelemetry/sdk-trace-base": "^1.30.1", "@opentelemetry/semantic-conventions": "^1.28.0", "@prisma/instrumentation": "5.22.0", "@sentry/core": "8.55.2", "@sentry/opentelemetry": "8.55.2", "import-in-the-middle": "^1.11.2" } }, "sha512-x3Whryb4TytiIhH9ABLVuASfBvwA50v6PpJYvq0Y9dUMi9Eb0cfuqvRCB3e+oVntZHQpnXor2U/gRBIdG2jp4w=="],
"@sentry/opentelemetry": ["@sentry/opentelemetry@8.55.1", "", { "dependencies": { "@sentry/core": "8.55.1" }, "peerDependencies": { "@opentelemetry/api": "^1.9.0", "@opentelemetry/context-async-hooks": "^1.30.1", "@opentelemetry/core": "^1.30.1", "@opentelemetry/instrumentation": "^0.57.1", "@opentelemetry/sdk-trace-base": "^1.30.1", "@opentelemetry/semantic-conventions": "^1.28.0" } }, "sha512-ipiM/k3Hzt8visoBfkDb4AQBWHkJeou3SjoPec7NlDabH/Jj8x6VlK5Hex4z+WOv99rRy+5MUtga/CZnOjvh0A=="],
"@sentry/opentelemetry": ["@sentry/opentelemetry@8.55.2", "", { "dependencies": { "@sentry/core": "8.55.2" }, "peerDependencies": { "@opentelemetry/api": "^1.9.0", "@opentelemetry/context-async-hooks": "^1.30.1", "@opentelemetry/core": "^1.30.1", "@opentelemetry/instrumentation": "^0.57.1", "@opentelemetry/sdk-trace-base": "^1.30.1", "@opentelemetry/semantic-conventions": "^1.28.0" } }, "sha512-pbhXi4cS1W4l392yEfIx3UD28OYAl9JkYOmh/Cpm6cPTtRMPxi3hWeujGbcXV9T/RkWYjqd+JdUDJjqsWSww9A=="],
"@sentry/svelte": ["@sentry/svelte@8.55.1", "", { "dependencies": { "@sentry/browser": "8.55.1", "@sentry/core": "8.55.1", "magic-string": "^0.30.0" }, "peerDependencies": { "svelte": "3.x || 4.x || 5.x" } }, "sha512-INuwEscDDkHY3rnZyYiRCBtI8vz9qkTprTpegMC01W7mWE2vh9bNft8V/c41una8m8m6JLREy+1eYRvd/uDr3A=="],
"@sentry/svelte": ["@sentry/svelte@8.55.2", "", { "dependencies": { "@sentry/browser": "8.55.2", "@sentry/core": "8.55.2", "magic-string": "^0.30.0" }, "peerDependencies": { "svelte": "3.x || 4.x || 5.x" } }, "sha512-q5aN6lwYiReZcwQfzIQyipBVtfu5ZmE237ivKiTp1VZqPetWLZO4PMWzP9kzG+lz1OIdRhEGm6GBvJi4NBS/9A=="],
"@sentry/sveltekit": ["@sentry/sveltekit@8.55.1", "", { "dependencies": { "@sentry/core": "8.55.1", "@sentry/node": "8.55.1", "@sentry/opentelemetry": "8.55.1", "@sentry/svelte": "8.55.1", "@sentry/vite-plugin": "2.22.6", "magic-string": "0.30.7", "magicast": "0.2.8", "sorcery": "1.0.0" }, "peerDependencies": { "@sveltejs/kit": "1.x || 2.x", "vite": "*" }, "optionalPeers": ["vite"] }, "sha512-Kt05HMaWvbtvUYFF5gmZmNBY2Wn1kJnyTXDjYusTxsAtM9RfU05UbOSqedBcOqhSALohZUwHA4/QO3lqgXEsAg=="],
"@sentry/sveltekit": ["@sentry/sveltekit@8.55.2", "", { "dependencies": { "@sentry/core": "8.55.2", "@sentry/node": "8.55.2", "@sentry/opentelemetry": "8.55.2", "@sentry/svelte": "8.55.2", "@sentry/vite-plugin": "2.22.6", "magic-string": "0.30.7", "magicast": "0.2.8", "sorcery": "1.0.0" }, "peerDependencies": { "@sveltejs/kit": "1.x || 2.x", "vite": "*" }, "optionalPeers": ["vite"] }, "sha512-ypl/St8erGso2z2IBLiRv9nRdH1HQ3rXDaI71mkj9PjUhcdiC7k7COFUs6j8knmgPIsRc7ByU23vsfotyCxFvA=="],
"@sentry/vite-plugin": ["@sentry/vite-plugin@2.22.6", "", { "dependencies": { "@sentry/bundler-plugin-core": "2.22.6", "unplugin": "1.0.1" } }, "sha512-zIieP1VLWQb3wUjFJlwOAoaaJygJhXeUoGd0e/Ha2RLb2eW2S+4gjf6y6NqyY71tZ74LYVZKg/4prB6FAZSMXQ=="],
@@ -468,17 +470,17 @@
"@sveltejs/adapter-static": ["@sveltejs/adapter-static@3.0.10", "", { "peerDependencies": { "@sveltejs/kit": "^2.0.0" } }, "sha512-7D9lYFWJmB7zxZyTE/qxjksvMqzMuYrrsyh1f4AlZqeZeACPRySjbC3aFiY55wb1tWUaKOQG9PVbm74JcN2Iew=="],
"@sveltejs/kit": ["@sveltejs/kit@2.57.1", "", { "dependencies": { "@standard-schema/spec": "^1.0.0", "@sveltejs/acorn-typescript": "^1.0.5", "@types/cookie": "^0.6.0", "acorn": "^8.14.1", "cookie": "^0.6.0", "devalue": "^5.6.4", "esm-env": "^1.2.2", "kleur": "^4.1.5", "magic-string": "^0.30.5", "mrmime": "^2.0.0", "set-cookie-parser": "^3.0.0", "sirv": "^3.0.0" }, "peerDependencies": { "@opentelemetry/api": "^1.0.0", "@sveltejs/vite-plugin-svelte": "^3.0.0 || ^4.0.0-next.1 || ^5.0.0 || ^6.0.0-next.0 || ^7.0.0", "svelte": "^4.0.0 || ^5.0.0-next.0", "typescript": "^5.3.3 || ^6.0.0", "vite": "^5.0.3 || ^6.0.0 || ^7.0.0-beta.0 || ^8.0.0" }, "optionalPeers": ["@opentelemetry/api", "typescript"], "bin": { "svelte-kit": "svelte-kit.js" } }, "sha512-VRdSbB96cI1EnRh09CqmnQqP/YJvET5buj8S6k7CxaJqBJD4bw4fRKDjcarAj/eX9k2eHifQfDH8NtOh+ZxxPw=="],
"@sveltejs/kit": ["@sveltejs/kit@2.59.1", "", { "dependencies": { "@standard-schema/spec": "^1.0.0", "@sveltejs/acorn-typescript": "^1.0.5", "@types/cookie": "^0.6.0", "acorn": "^8.14.1", "cookie": "^0.6.0", "devalue": "^5.6.4", "esm-env": "^1.2.2", "kleur": "^4.1.5", "magic-string": "^0.30.5", "mrmime": "^2.0.0", "set-cookie-parser": "^3.0.0", "sirv": "^3.0.0" }, "peerDependencies": { "@opentelemetry/api": "^1.0.0", "@sveltejs/vite-plugin-svelte": "^3.0.0 || ^4.0.0-next.1 || ^5.0.0 || ^6.0.0-next.0 || ^7.0.0", "svelte": "^4.0.0 || ^5.0.0-next.0", "typescript": "^5.3.3 || ^6.0.0", "vite": "^5.0.3 || ^6.0.0 || ^7.0.0-beta.0 || ^8.0.0" }, "optionalPeers": ["@opentelemetry/api", "typescript"], "bin": { "svelte-kit": "svelte-kit.js" } }, "sha512-d8OON70AphLdDesuTIl//M2O6fRTIicX8aYv8vhCiYEhTTI2OboKqey0Hu1A4VFhqwgqtq0vKDmPFGkw8kKmgw=="],
"@sveltejs/vite-plugin-svelte": ["@sveltejs/vite-plugin-svelte@5.1.1", "", { "dependencies": { "@sveltejs/vite-plugin-svelte-inspector": "^4.0.1", "debug": "^4.4.1", "deepmerge": "^4.3.1", "kleur": "^4.1.5", "magic-string": "^0.30.17", "vitefu": "^1.0.6" }, "peerDependencies": { "svelte": "^5.0.0", "vite": "^6.0.0" } }, "sha512-Y1Cs7hhTc+a5E9Va/xwKlAJoariQyHY+5zBgCZg4PFWNYQ1nMN9sjK1zhw1gK69DuqVP++sht/1GZg1aRwmAXQ=="],
"@sveltejs/vite-plugin-svelte-inspector": ["@sveltejs/vite-plugin-svelte-inspector@4.0.1", "", { "dependencies": { "debug": "^4.3.7" }, "peerDependencies": { "@sveltejs/vite-plugin-svelte": "^5.0.0", "svelte": "^5.0.0", "vite": "^6.0.0" } }, "sha512-J/Nmb2Q2y7mck2hyCX4ckVHcR5tu2J+MtBEQqpDrrgELZ2uvraQcK/ioCV61AqkdXFgriksOKIceDcQmqnGhVw=="],
"@swc/helpers": ["@swc/helpers@0.5.19", "", { "dependencies": { "tslib": "^2.8.0" } }, "sha512-QamiFeIK3txNjgUTNppE6MiG3p7TdninpZu0E0PbqVh1a9FNLT2FRhisaa4NcaX52XVhA5l7Pk58Ft7Sqi/2sA=="],
"@swc/helpers": ["@swc/helpers@0.5.21", "", { "dependencies": { "tslib": "^2.8.0" } }, "sha512-jI/VAmtdjB/RnI8GTnokyX7Ug8c+g+ffD6QRLa6XQewtnGyukKkKSk3wLTM3b5cjt1jNh9x0jfVlagdN2gDKQg=="],
"@tanstack/svelte-virtual": ["@tanstack/svelte-virtual@3.13.22", "", { "dependencies": { "@tanstack/virtual-core": "3.13.22" }, "peerDependencies": { "svelte": "^3.48.0 || ^4.0.0 || ^5.0.0" } }, "sha512-ge1CUEbyWzJzuQnC+vtePEkO0vyA6lINCozpgXmCH39QCwCNC50MErang6n541vK4Poi8eADbDL4qb5afPv4rw=="],
"@tanstack/svelte-virtual": ["@tanstack/svelte-virtual@3.13.24", "", { "dependencies": { "@tanstack/virtual-core": "3.14.0" }, "peerDependencies": { "svelte": "^3.48.0 || ^4.0.0 || ^5.0.0" } }, "sha512-Up3LOD5Cj+oJ3GuKfM1Li06jzzZMIZnRPmu3aik9rJQgk7jq7LgPo4yumfUw4+I4edjYfyPKSZnXGwZ9Vjlebw=="],
"@tanstack/virtual-core": ["@tanstack/virtual-core@3.13.22", "", {}, "sha512-isuUGKsc5TAPDoHSbWTbl1SCil54zOS2MiWz/9GCWHPUQOvNTQx8qJEWC7UWR0lShhbK0Lmkcf0SZYxvch7G3g=="],
"@tanstack/virtual-core": ["@tanstack/virtual-core@3.14.0", "", {}, "sha512-JLANqGy/D6k4Ujmh8Tr25lGimuOXNiaVyXaCAZS0W+1390sADdGnyUdSWNIfd49gebtIxGMij4IktRVzrdr12Q=="],
"@testing-library/dom": ["@testing-library/dom@10.4.1", "", { "dependencies": { "@babel/code-frame": "^7.10.4", "@babel/runtime": "^7.12.5", "@types/aria-query": "^5.0.1", "aria-query": "5.3.0", "dom-accessibility-api": "^0.5.9", "lz-string": "^1.5.0", "picocolors": "1.1.1", "pretty-format": "^27.0.2" } }, "sha512-o4PXJQidqJl82ckFaXUeoAW+XysPLauYI43Abki5hABd853iMhitooc6znOnczgbTYmEP6U6/y1ZyKAIsvMKGg=="],
@@ -492,13 +494,13 @@
"@threejs-kit/instanced-sprite-mesh": ["@threejs-kit/instanced-sprite-mesh@2.5.1", "", { "dependencies": { "diet-sprite": "^0.0.1", "earcut": "^2.2.4", "maath": "^0.10.7", "three-instanced-uniforms-mesh": "^0.52.4", "troika-three-utils": "^0.52.4" }, "peerDependencies": { "three": ">=0.170.0" } }, "sha512-pmt1ALRhbHhCJQTj2FuthH6PeLIeaM4hOuS2JO3kWSwlnvx/9xuUkjFR3JOi/myMqsH7pSsLIROSaBxDfttjeA=="],
"@threlte/core": ["@threlte/core@8.5.2", "", { "dependencies": { "mitt": "^3.0.1" }, "peerDependencies": { "svelte": ">=5", "three": ">=0.160" } }, "sha512-noxIsYlEYRFBo0U3T8Z4PWkfe23VCDxaHIlSzSWlOlBgd+mhKrhyM8lFmeznmZQS78z4obkWUJeYxx/jauD+rw=="],
"@threlte/core": ["@threlte/core@8.5.14", "", { "peerDependencies": { "svelte": ">=5", "three": ">=0.160" } }, "sha512-9UPW8zgkXPk6zEaJSvNuL9mDa0fHqCBzDXioUDt6flRUEvhh+nR8Q6XMjea6s+frReFw7WnKcDobPsGNPbtdLg=="],
"@threlte/extras": ["@threlte/extras@9.13.0", "", { "dependencies": { "@threejs-kit/instanced-sprite-mesh": "^2.5.1", "camera-controls": "^3.1.2", "three-mesh-bvh": "^0.9.1", "three-perf": "^1.0.11", "three-viewport-gizmo": "^2.2.0", "troika-three-text": "^0.52.4" }, "peerDependencies": { "svelte": ">=5", "three": ">=0.160" } }, "sha512-fHt5VcOoXyBT+wuytRHlKa1SUxNEI15L/kpudVWE9Z0G+U5TWIf01mt0BdQBGJOqwVJYxwFzRJQxfS2/kLAl9Q=="],
"@threlte/extras": ["@threlte/extras@9.17.0", "", { "dependencies": { "@threejs-kit/instanced-sprite-mesh": "^2.5.1", "camera-controls": "^3.1.2", "three-mesh-bvh": "^0.9.1", "three-perf": "^1.0.11", "three-viewport-gizmo": "^2.2.0", "troika-three-text": "^0.52.4" }, "peerDependencies": { "svelte": ">=5", "three": ">=0.160" } }, "sha512-IOhXBU6fiac4jzEkCVdHIX0bwRdxfOgCd8QSeISAKv/qAks8xb3xIxS5P346oWXnL66isYuy1ockPJIL1geDmw=="],
"@tweenjs/tween.js": ["@tweenjs/tween.js@23.1.3", "", {}, "sha512-vJmvvwFxYuGnF2axRtPYocag6Clbb5YS7kLL+SO/TeVFzHqDIWrNKYtcsPMibjDx9O+bu+psAy9NKfWklassUA=="],
"@tybys/wasm-util": ["@tybys/wasm-util@0.10.1", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg=="],
"@tybys/wasm-util": ["@tybys/wasm-util@0.10.2", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-RoBvJ2X0wuKlWFIjrwffGw1IqZHKQqzIchKaadZZfnNpsAYp2mM0h36JtPCjNDAHGgYez/15uMBpfGwchhiMgg=="],
"@types/aria-query": ["@types/aria-query@5.0.4", "", {}, "sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw=="],
@@ -514,7 +516,7 @@
"@types/dlv": ["@types/dlv@1.1.5", "", {}, "sha512-JHOWNfiWepAhfwlSw17kiWrWrk6od2dEQgHltJw9AS0JPFoLZJBge5+Dnil2NfdjAvJ/+vGSX60/BRW20PpUXw=="],
"@types/estree": ["@types/estree@1.0.8", "", {}, "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w=="],
"@types/estree": ["@types/estree@1.0.9", "", {}, "sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg=="],
"@types/hast": ["@types/hast@3.0.4", "", { "dependencies": { "@types/unist": "*" } }, "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ=="],
@@ -524,7 +526,7 @@
"@types/mysql": ["@types/mysql@2.15.26", "", { "dependencies": { "@types/node": "*" } }, "sha512-DSLCOXhkvfS5WNNPbfn2KdICAmk8lLc+/PNvnPnF7gOdMZCxopXduqv0OQ13y/yA/zXTSikZZqVgybUxOEg6YQ=="],
"@types/node": ["@types/node@25.5.0", "", { "dependencies": { "undici-types": "~7.18.0" } }, "sha512-jp2P3tQMSxWugkCUKLRPVUpGaL5MVFwF8RDuSRztfwgN1wmqJeMSbKlnEtQqU8UrhTmzEmZdu2I6v2dpp7XIxw=="],
"@types/node": ["@types/node@25.6.2", "", { "dependencies": { "undici-types": "~7.19.0" } }, "sha512-sokuT28dxf9JT5Kady1fsXOvI4HVpjZa95NKT5y9PNTIrs2AsobR4GFAA90ZG8M+nxVRLysCXsVj6eGC7Vbrlw=="],
"@types/pg": ["@types/pg@8.6.1", "", { "dependencies": { "@types/node": "*", "pg-protocol": "*", "pg-types": "^2.2.0" } }, "sha512-1Kc4oAGzAl7uqUStZCDvaLFqZrW9qWSjXOmBfdgyBP5La7Us6Mg4GBvRlSoaZMhQF/zSj1C8CtKMBkoiT8eL8w=="],
@@ -550,29 +552,29 @@
"@types/webxr": ["@types/webxr@0.5.24", "", {}, "sha512-h8fgEd/DpoS9CBrjEQXR+dIDraopAEfu4wYVNY2tEPwk60stPWhvZMf4Foo5FakuQ7HFZoa8WceaWFervK2Ovg=="],
"@typescript-eslint/eslint-plugin": ["@typescript-eslint/eslint-plugin@8.57.2", "", { "dependencies": { "@eslint-community/regexpp": "^4.12.2", "@typescript-eslint/scope-manager": "8.57.2", "@typescript-eslint/type-utils": "8.57.2", "@typescript-eslint/utils": "8.57.2", "@typescript-eslint/visitor-keys": "8.57.2", "ignore": "^7.0.5", "natural-compare": "^1.4.0", "ts-api-utils": "^2.4.0" }, "peerDependencies": { "@typescript-eslint/parser": "^8.57.2", "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-NZZgp0Fm2IkD+La5PR81sd+g+8oS6JwJje+aRWsDocxHkjyRw0J5L5ZTlN3LI1LlOcGL7ph3eaIUmTXMIjLk0w=="],
"@typescript-eslint/eslint-plugin": ["@typescript-eslint/eslint-plugin@8.59.2", "", { "dependencies": { "@eslint-community/regexpp": "^4.12.2", "@typescript-eslint/scope-manager": "8.59.2", "@typescript-eslint/type-utils": "8.59.2", "@typescript-eslint/utils": "8.59.2", "@typescript-eslint/visitor-keys": "8.59.2", "ignore": "^7.0.5", "natural-compare": "^1.4.0", "ts-api-utils": "^2.5.0" }, "peerDependencies": { "@typescript-eslint/parser": "^8.59.2", "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.1.0" } }, "sha512-j/bwmkBvHUtPNxzuWe5z6BEk3q54YRyGlBXkSsmfoih7zNrBvl5A9A98anlp/7JbyZcWIJ8KXo/3Tq/DjFLtuQ=="],
"@typescript-eslint/parser": ["@typescript-eslint/parser@8.57.2", "", { "dependencies": { "@typescript-eslint/scope-manager": "8.57.2", "@typescript-eslint/types": "8.57.2", "@typescript-eslint/typescript-estree": "8.57.2", "@typescript-eslint/visitor-keys": "8.57.2", "debug": "^4.4.3" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-30ScMRHIAD33JJQkgfGW1t8CURZtjc2JpTrq5n2HFhOefbAhb7ucc7xJwdWcrEtqUIYJ73Nybpsggii6GtAHjA=="],
"@typescript-eslint/parser": ["@typescript-eslint/parser@8.59.2", "", { "dependencies": { "@typescript-eslint/scope-manager": "8.59.2", "@typescript-eslint/types": "8.59.2", "@typescript-eslint/typescript-estree": "8.59.2", "@typescript-eslint/visitor-keys": "8.59.2", "debug": "^4.4.3" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.1.0" } }, "sha512-plR3pp6D+SSUn1HM7xvSkx12/DhoHInI2YF35KAcVFNZvlC0gtrWqx7Qq1oH2Ssgi0vlFRCTbP+DZc7B9+TtsQ=="],
"@typescript-eslint/project-service": ["@typescript-eslint/project-service@8.57.2", "", { "dependencies": { "@typescript-eslint/tsconfig-utils": "^8.57.2", "@typescript-eslint/types": "^8.57.2", "debug": "^4.4.3" }, "peerDependencies": { "typescript": ">=4.8.4 <6.0.0" } }, "sha512-FuH0wipFywXRTHf+bTTjNyuNQQsQC3qh/dYzaM4I4W0jrCqjCVuUh99+xd9KamUfmCGPvbO8NDngo/vsnNVqgw=="],
"@typescript-eslint/project-service": ["@typescript-eslint/project-service@8.59.2", "", { "dependencies": { "@typescript-eslint/tsconfig-utils": "^8.59.2", "@typescript-eslint/types": "^8.59.2", "debug": "^4.4.3" }, "peerDependencies": { "typescript": ">=4.8.4 <6.1.0" } }, "sha512-+2hqvEkeyf/0FBor67duF0Ll7Ot8jyKzDQOSrxazF/danillRq2DwR9dLptsXpoZQqxE1UisSmoZewrlPas9Vw=="],
"@typescript-eslint/scope-manager": ["@typescript-eslint/scope-manager@8.57.2", "", { "dependencies": { "@typescript-eslint/types": "8.57.2", "@typescript-eslint/visitor-keys": "8.57.2" } }, "sha512-snZKH+W4WbWkrBqj4gUNRIGb/jipDW3qMqVJ4C9rzdFc+wLwruxk+2a5D+uoFcKPAqyqEnSb4l2ULuZf95eSkw=="],
"@typescript-eslint/scope-manager": ["@typescript-eslint/scope-manager@8.59.2", "", { "dependencies": { "@typescript-eslint/types": "8.59.2", "@typescript-eslint/visitor-keys": "8.59.2" } }, "sha512-JzfyEpEtOU89CcFSwyNS3mu4MLvLSXqnmX05+aKBDM+TdR5jzcGOEBwxwGNxrEQ7p/z6kK2WyioCGBf2zZBnvg=="],
"@typescript-eslint/tsconfig-utils": ["@typescript-eslint/tsconfig-utils@8.57.2", "", { "peerDependencies": { "typescript": ">=4.8.4 <6.0.0" } }, "sha512-3Lm5DSM+DCowsUOJC+YqHHnKEfFh5CoGkj5Z31NQSNF4l5wdOwqGn99wmwN/LImhfY3KJnmordBq/4+VDe2eKw=="],
"@typescript-eslint/tsconfig-utils": ["@typescript-eslint/tsconfig-utils@8.59.2", "", { "peerDependencies": { "typescript": ">=4.8.4 <6.1.0" } }, "sha512-BKK4alN7oi4C/zv4VqHQ+uRU+lTa6JGIZ7s1juw7b3RHo9OfKB+bKX3u0iVZetdsUCBBkSbdWbarJbmN0fTeSw=="],
"@typescript-eslint/type-utils": ["@typescript-eslint/type-utils@8.57.2", "", { "dependencies": { "@typescript-eslint/types": "8.57.2", "@typescript-eslint/typescript-estree": "8.57.2", "@typescript-eslint/utils": "8.57.2", "debug": "^4.4.3", "ts-api-utils": "^2.4.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-Co6ZCShm6kIbAM/s+oYVpKFfW7LBc6FXoPXjTRQ449PPNBY8U0KZXuevz5IFuuUj2H9ss40atTaf9dlGLzbWZg=="],
"@typescript-eslint/type-utils": ["@typescript-eslint/type-utils@8.59.2", "", { "dependencies": { "@typescript-eslint/types": "8.59.2", "@typescript-eslint/typescript-estree": "8.59.2", "@typescript-eslint/utils": "8.59.2", "debug": "^4.4.3", "ts-api-utils": "^2.5.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.1.0" } }, "sha512-nhqaj1nmTdVVl/BP5omXNRGO38jn5iosis2vbdmupF2txCf8ylWT8lx+JlvMYYVqzGVKtjojUFoQ3JRWK+mfzQ=="],
"@typescript-eslint/types": ["@typescript-eslint/types@8.57.2", "", {}, "sha512-/iZM6FnM4tnx9csuTxspMW4BOSegshwX5oBDznJ7S4WggL7Vczz5d2W11ecc4vRrQMQHXRSxzrCsyG5EsPPTbA=="],
"@typescript-eslint/types": ["@typescript-eslint/types@8.59.2", "", {}, "sha512-e82GVOE8Ps3E++Egvb6Y3Dw0S10u8NkQ9KXmtRhCWJJ8kDhOJTvtMAWnFL16kB1583goCWXsr0NieKCZMs2/0Q=="],
"@typescript-eslint/typescript-estree": ["@typescript-eslint/typescript-estree@8.57.2", "", { "dependencies": { "@typescript-eslint/project-service": "8.57.2", "@typescript-eslint/tsconfig-utils": "8.57.2", "@typescript-eslint/types": "8.57.2", "@typescript-eslint/visitor-keys": "8.57.2", "debug": "^4.4.3", "minimatch": "^10.2.2", "semver": "^7.7.3", "tinyglobby": "^0.2.15", "ts-api-utils": "^2.4.0" }, "peerDependencies": { "typescript": ">=4.8.4 <6.0.0" } }, "sha512-2MKM+I6g8tJxfSmFKOnHv2t8Sk3T6rF20A1Puk0svLK+uVapDZB/4pfAeB7nE83uAZrU6OxW+HmOd5wHVdXwXA=="],
"@typescript-eslint/typescript-estree": ["@typescript-eslint/typescript-estree@8.59.2", "", { "dependencies": { "@typescript-eslint/project-service": "8.59.2", "@typescript-eslint/tsconfig-utils": "8.59.2", "@typescript-eslint/types": "8.59.2", "@typescript-eslint/visitor-keys": "8.59.2", "debug": "^4.4.3", "minimatch": "^10.2.2", "semver": "^7.7.3", "tinyglobby": "^0.2.15", "ts-api-utils": "^2.5.0" }, "peerDependencies": { "typescript": ">=4.8.4 <6.1.0" } }, "sha512-o0XPGNwcWw+FIwStOWn+BwBuEmL6QXP0rsvAFg7ET1dey1Nr6Wb1ac8p5HEsK0ygO/6mUxlk+YWQD9xcb/nnXg=="],
"@typescript-eslint/utils": ["@typescript-eslint/utils@8.57.2", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.9.1", "@typescript-eslint/scope-manager": "8.57.2", "@typescript-eslint/types": "8.57.2", "@typescript-eslint/typescript-estree": "8.57.2" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-krRIbvPK1ju1WBKIefiX+bngPs+odIQUtR7kymzPfo1POVw3jlF+nLkmexdSSd4UCbDcQn+wMBATOOmpBbqgKg=="],
"@typescript-eslint/utils": ["@typescript-eslint/utils@8.59.2", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.9.1", "@typescript-eslint/scope-manager": "8.59.2", "@typescript-eslint/types": "8.59.2", "@typescript-eslint/typescript-estree": "8.59.2" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.1.0" } }, "sha512-Juw3EinkXqjaffxz6roowvV7GZT/kET5vSKKZT6upl5TXdWkLkYmNPXwDDL2Vkt2DPn0nODIS4egC/0AGxKo/Q=="],
"@typescript-eslint/visitor-keys": ["@typescript-eslint/visitor-keys@8.57.2", "", { "dependencies": { "@typescript-eslint/types": "8.57.2", "eslint-visitor-keys": "^5.0.0" } }, "sha512-zhahknjobV2FiD6Ee9iLbS7OV9zi10rG26odsQdfBO/hjSzUQbkIYgda+iNKK1zNiW2ey+Lf8MU5btN17V3dUw=="],
"@typescript-eslint/visitor-keys": ["@typescript-eslint/visitor-keys@8.59.2", "", { "dependencies": { "@typescript-eslint/types": "8.59.2", "eslint-visitor-keys": "^5.0.0" } }, "sha512-NwjLUnGy8/Zfx23fl50tRC8rYaYnM52xNRYFAXvmiil9yh1+K6aRVQMnzW6gQB/1DLgWt977lYQn7C+wtgXZiA=="],
"@ungap/structured-clone": ["@ungap/structured-clone@1.3.0", "", {}, "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g=="],
"@ungap/structured-clone": ["@ungap/structured-clone@1.3.1", "", {}, "sha512-mUFwbeTqrVgDQxFveS+df2yfap6iuP20NAKAsBt5jDEoOTDew+zwLAOilHCeQJOVSvmgCX4ogqIrA0mnyr08yQ=="],
"@vercel/oidc": ["@vercel/oidc@3.1.0", "", {}, "sha512-Fw28YZpRnA3cAHHDlkt7xQHiJ0fcL+NRcIqsocZQUSmbzeIKRpwttJjik5ZGanXP+vlA4SbTg+AbA3bP363l+w=="],
"@vercel/oidc": ["@vercel/oidc@3.2.0", "", {}, "sha512-UycprH3T6n3jH0k44NHMa7pnFHGu/N05MjojYr+Mc6I7obkoLIJujSWwin1pCvdy/eOxrI/l3uDLQsmcrOb4ug=="],
"@vitest/expect": ["@vitest/expect@3.2.4", "", { "dependencies": { "@types/chai": "^5.2.2", "@vitest/spy": "3.2.4", "@vitest/utils": "3.2.4", "chai": "^5.2.0", "tinyrainbow": "^2.0.0" } }, "sha512-Io0yyORnB6sikFlt8QW5K7slY4OjqNX9jmJQ02QDda8lyM6B5oNgVWoSoKPac8/kgnCUzuHQKrSLtu/uOqqrig=="],
@@ -600,9 +602,9 @@
"agent-base": ["agent-base@7.1.4", "", {}, "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ=="],
"ai": ["ai@6.0.138", "", { "dependencies": { "@ai-sdk/gateway": "3.0.80", "@ai-sdk/provider": "3.0.8", "@ai-sdk/provider-utils": "4.0.21", "@opentelemetry/api": "1.9.0" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-49OfPe0f5uxJ6jUdA5BBXjIinP6+ZdYfAtpF2aEH64GA5wPcxH2rf/TBUQQ0bbamBz/D+TLMV18xilZqOC+zaA=="],
"ai": ["ai@6.0.177", "", { "dependencies": { "@ai-sdk/gateway": "3.0.112", "@ai-sdk/provider": "3.0.10", "@ai-sdk/provider-utils": "4.0.27", "@opentelemetry/api": "1.9.0" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-1xQtbeWwNcLyyM86ixZhkKvT+WRXc1lvarIKqPVtsyn8F9NDikwUMBqYu+aQKDgMht50SMXh4qboYuU8MeHZZA=="],
"ajv": ["ajv@6.14.0", "", { "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", "json-schema-traverse": "^0.4.1", "uri-js": "^4.2.2" } }, "sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw=="],
"ajv": ["ajv@6.15.0", "", { "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", "json-schema-traverse": "^0.4.1", "uri-js": "^4.2.2" } }, "sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw=="],
"analytics": ["analytics@0.8.19", "", { "dependencies": { "@analytics/core": "^0.13.2", "@analytics/storage-utils": "^0.4.4" } }, "sha512-JFgasxpWFiAoqm5UHaGQv9j9OGz+f1KAeQkABYr3Z7YGhiqhQrBpPhIVAIEyttBRJZmew1QwMhN9/bOGGBnpJA=="],
@@ -634,7 +636,7 @@
"balanced-match": ["balanced-match@4.0.4", "", {}, "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA=="],
"baseline-browser-mapping": ["baseline-browser-mapping@2.10.8", "", { "bin": { "baseline-browser-mapping": "dist/cli.cjs" } }, "sha512-PCLz/LXGBsNTErbtB6i5u4eLpHeMfi93aUv5duMmj6caNu6IphS4q6UevDnL36sZQv9lrP11dbPKGMaXPwMKfQ=="],
"baseline-browser-mapping": ["baseline-browser-mapping@2.10.29", "", { "bin": { "baseline-browser-mapping": "dist/cli.cjs" } }, "sha512-Asa2krT+XTPZINCS+2QcyS8WTkObE77RwkydwF7h6DmnKqbvlalz93m/dnphUyCa6SWSP51VgtEUf2FN+gelFQ=="],
"bidi-js": ["bidi-js@1.0.3", "", { "dependencies": { "require-from-string": "^2.0.2" } }, "sha512-RKshQI1R3YQ+n9YJz2QQ147P66ELpa1FQEg20Dk8oW9t2KgLbpDLLp9aGZ7y8WHSshDknG0bknqGw5/tyCs5tw=="],
@@ -642,15 +644,15 @@
"binary-extensions": ["binary-extensions@2.3.0", "", {}, "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw=="],
"brace-expansion": ["brace-expansion@5.0.5", "", { "dependencies": { "balanced-match": "^4.0.2" } }, "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ=="],
"brace-expansion": ["brace-expansion@5.0.6", "", { "dependencies": { "balanced-match": "^4.0.2" } }, "sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g=="],
"braces": ["braces@3.0.3", "", { "dependencies": { "fill-range": "^7.1.1" } }, "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA=="],
"browserslist": ["browserslist@4.28.1", "", { "dependencies": { "baseline-browser-mapping": "^2.9.0", "caniuse-lite": "^1.0.30001759", "electron-to-chromium": "^1.5.263", "node-releases": "^2.0.27", "update-browserslist-db": "^1.2.0" }, "bin": { "browserslist": "cli.js" } }, "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA=="],
"browserslist": ["browserslist@4.28.2", "", { "dependencies": { "baseline-browser-mapping": "^2.10.12", "caniuse-lite": "^1.0.30001782", "electron-to-chromium": "^1.5.328", "node-releases": "^2.0.36", "update-browserslist-db": "^1.2.3" }, "bin": { "browserslist": "cli.js" } }, "sha512-48xSriZYYg+8qXna9kwqjIVzuQxi+KYWp2+5nCYnYKPTr0LvD89Jqk2Or5ogxz0NUMfIjhh2lIUX/LyX9B4oIg=="],
"cac": ["cac@6.7.14", "", {}, "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ=="],
"call-bind": ["call-bind@1.0.8", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.0", "es-define-property": "^1.0.0", "get-intrinsic": "^1.2.4", "set-function-length": "^1.2.2" } }, "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww=="],
"call-bind": ["call-bind@1.0.9", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.2", "es-define-property": "^1.0.1", "get-intrinsic": "^1.3.0", "set-function-length": "^1.2.2" } }, "sha512-a/hy+pNsFUTR+Iz8TCJvXudKVLAnz/DyeSUo10I5yvFDQJBFU2s9uqQpoSrJlroHUKoKqzg+epxyP9lqFdzfBQ=="],
"call-bind-apply-helpers": ["call-bind-apply-helpers@1.0.2", "", { "dependencies": { "es-errors": "^1.3.0", "function-bind": "^1.1.2" } }, "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ=="],
@@ -660,7 +662,7 @@
"camera-controls": ["camera-controls@3.1.2", "", { "peerDependencies": { "three": ">=0.126.1" } }, "sha512-xkxfpG2ECZ6Ww5/9+kf4mfg1VEYAoe9aDSY+IwF0UEs7qEzwy0aVRfs2grImIECs/PoBtWFrh7RXsQkwG922JA=="],
"caniuse-lite": ["caniuse-lite@1.0.30001779", "", {}, "sha512-U5og2PN7V4DMgF50YPNtnZJGWVLFjjsN3zb6uMT5VGYIewieDj1upwfuVNXf4Kor+89c3iCRJnSzMD5LmTvsfA=="],
"caniuse-lite": ["caniuse-lite@1.0.30001792", "", {}, "sha512-hVLMUZFgR4JJ6ACt1uEESvQN1/dBVqPAKY0hgrV70eN3391K6juAfTjKZLKvOMsx8PxA7gsY1/tLMMTcfFLLpw=="],
"ccount": ["ccount@2.0.1", "", {}, "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg=="],
@@ -794,13 +796,13 @@
"define-properties": ["define-properties@1.2.1", "", { "dependencies": { "define-data-property": "^1.0.1", "has-property-descriptors": "^1.0.0", "object-keys": "^1.1.1" } }, "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg=="],
"delaunator": ["delaunator@5.0.1", "", { "dependencies": { "robust-predicates": "^3.0.2" } }, "sha512-8nvh+XBe96aCESrGOqMp/84b13H9cdKbG5P2ejQCh4d4sK9RL4371qou9drQjMhvnPmhWl5hnmqbEE0fXr9Xnw=="],
"delaunator": ["delaunator@5.1.0", "", { "dependencies": { "robust-predicates": "^3.0.2" } }, "sha512-AGrQ4QSgssa1NGmWmLPqN5NY2KajF5MqxetNEO+o0n3ZwZZeTmt7bBnvzHWrmkZFxGgr4HdyFgelzgi06otLuQ=="],
"dequal": ["dequal@2.0.3", "", {}, "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA=="],
"detect-libc": ["detect-libc@2.1.2", "", {}, "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ=="],
"devalue": ["devalue@5.6.4", "", {}, "sha512-Gp6rDldRsFh/7XuouDbxMH3Mx8GMCcgzIb1pDTvNyn8pZGQ22u+Wa+lGV9dQCltFQ7uVw0MhRyb8XDskNFOReA=="],
"devalue": ["devalue@5.8.0", "", {}, "sha512-2zA9pFEsnp7vWBZbXF5JAgAq0fsUIt/1XPbRiAmRV3lp/2C3upzH+sADiyy66aFCihoLEsrQHxNM5w1gIDfsBg=="],
"devlop": ["devlop@1.1.0", "", { "dependencies": { "dequal": "^2.0.0" } }, "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA=="],
@@ -818,7 +820,7 @@
"echarts": ["echarts@5.6.0", "", { "dependencies": { "tslib": "2.3.0", "zrender": "5.6.1" } }, "sha512-oTbVTsXfKuEhxftHqL5xprgLoc0k7uScAwtryCgWF6hPYFLRwOUHiFmHGCBKP5NPFNkDVopOieyUqYGH8Fa3kA=="],
"electron-to-chromium": ["electron-to-chromium@1.5.313", "", {}, "sha512-QBMrTWEf00GXZmJyx2lbYD45jpI3TUFnNIzJ5BBc8piGUDwMPa1GV6HJWTZVvY/eiN3fSopl7NRbgGp9sZ9LTA=="],
"electron-to-chromium": ["electron-to-chromium@1.5.353", "", {}, "sha512-kOrWphBi8TOZyiJZqsgqIle0lw+tzmnQK83pV9dZUd01Nm2POECSyFQMAuarzZdYqQW7FH9RaYOuaRo3h+bQ3w=="],
"emoji-regex-xs": ["emoji-regex-xs@1.0.0", "", {}, "sha512-LRlerrMYoIDrT6jgpeZ2YYl/L8EulRTt5hQcYjy5AInh7HWXKimpqx68aknBFpGL2+/IcogTcaydJEgaTmOpDg=="],
@@ -842,7 +844,7 @@
"eslint-config-prettier": ["eslint-config-prettier@10.1.8", "", { "peerDependencies": { "eslint": ">=7.0.0" }, "bin": { "eslint-config-prettier": "bin/cli.js" } }, "sha512-82GZUjRS0p/jganf6q1rEO25VSoHH0hKPCTrgillPjdI/3bgBhAE1QzHrHTizjpRvy6pGAvKjDJtk2pF9NDq8w=="],
"eslint-plugin-svelte": ["eslint-plugin-svelte@3.16.0", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.6.1", "@jridgewell/sourcemap-codec": "^1.5.0", "esutils": "^2.0.3", "globals": "^16.0.0", "known-css-properties": "^0.37.0", "postcss": "^8.4.49", "postcss-load-config": "^3.1.4", "postcss-safe-parser": "^7.0.0", "semver": "^7.6.3", "svelte-eslint-parser": "^1.4.0" }, "peerDependencies": { "eslint": "^8.57.1 || ^9.0.0 || ^10.0.0", "svelte": "^3.37.0 || ^4.0.0 || ^5.0.0" }, "optionalPeers": ["svelte"] }, "sha512-DJXxqpYZUxcE0SfYo8EJzV2ZC+zAD7fJp1n1HwcEMRR1cOEUYvjT9GuzJeNghMjgb7uxuK3IJAzI+x6zzUxO5A=="],
"eslint-plugin-svelte": ["eslint-plugin-svelte@3.17.1", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.6.1", "@jridgewell/sourcemap-codec": "^1.5.0", "esutils": "^2.0.3", "globals": "^16.0.0", "known-css-properties": "^0.37.0", "postcss": "^8.4.49", "postcss-load-config": "^3.1.4", "postcss-safe-parser": "^7.0.0", "semver": "^7.6.3", "svelte-eslint-parser": "^1.4.0" }, "peerDependencies": { "eslint": "^8.57.1 || ^9.0.0 || ^10.0.0", "svelte": "^3.37.0 || ^4.0.0 || ^5.0.0" }, "optionalPeers": ["svelte"] }, "sha512-NyiXHtS3Ni7e532RBwS9OXlMKDIrENg3gY+/+ODjZzQx2xhU3NlJ+nIl1a93iUUQeiJL3lS8KLmY+W8hklzweQ=="],
"eslint-scope": ["eslint-scope@8.4.0", "", { "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^5.2.0" } }, "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg=="],
@@ -856,7 +858,7 @@
"esquery": ["esquery@1.7.0", "", { "dependencies": { "estraverse": "^5.1.0" } }, "sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g=="],
"esrap": ["esrap@2.2.4", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.4.15", "@typescript-eslint/types": "^8.2.0" } }, "sha512-suICpxAmZ9A8bzJjEl/+rLJiDKC0X4gYWUxT6URAWBLvlXmtbZd5ySMu/N2ZGEtMCAmflUDPSehrP9BQcsGcSg=="],
"esrap": ["esrap@2.2.6", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.4.15" }, "peerDependencies": { "@typescript-eslint/types": "^8.2.0" }, "optionalPeers": ["@typescript-eslint/types"] }, "sha512-WN0clHt0a4mzC780UBVVBpsj4vSSjOFNRd2WjYtduB9HeKxm1sjHMNUwLEHVjI3FdCQD/Hurgz9ftbKEzP79Ow=="],
"esrecurse": ["esrecurse@4.3.0", "", { "dependencies": { "estraverse": "^5.2.0" } }, "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag=="],
@@ -866,7 +868,7 @@
"esutils": ["esutils@2.0.3", "", {}, "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g=="],
"eventsource-parser": ["eventsource-parser@3.0.6", "", {}, "sha512-Vo1ab+QXPzZ4tCa8SwIHJFaSzy4R6SHf7BY79rFBDf0idraZWAkYrDjDj8uWaSm3S2TK+hJ7/t1CEmZ7jXw+pg=="],
"eventsource-parser": ["eventsource-parser@3.0.8", "", {}, "sha512-70QWGkr4snxr0OXLRWsFLeRBIRPuQOvt4s8QYjmUlmlkyTZkRqS7EDVRZtzU3TiyDbXSzaOeF0XUKy8PchzukQ=="],
"expect-type": ["expect-type@1.3.0", "", {}, "sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA=="],
@@ -906,7 +908,7 @@
"functions-have-names": ["functions-have-names@1.2.3", "", {}, "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ=="],
"fuse.js": ["fuse.js@7.1.0", "", {}, "sha512-trLf4SzuuUxfusZADLINj+dE8clK1frKdmqiJNb1Es75fmI5oY6X2mxLVUciLLjxqw/xr72Dhy+lER6dGd02FQ=="],
"fuse.js": ["fuse.js@7.3.0", "", {}, "sha512-plz8RVjfcDedTGfVngWH1jmJvBvAwi1v2jecfDerbEnMcmOYUEEwKFTHbNoCiYyzaK2Ws8lABkTCcRSqCY1q4w=="],
"gensync": ["gensync@1.0.0-beta.2", "", {}, "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg=="],
@@ -936,7 +938,7 @@
"has-tostringtag": ["has-tostringtag@1.0.2", "", { "dependencies": { "has-symbols": "^1.0.3" } }, "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw=="],
"hasown": ["hasown@2.0.2", "", { "dependencies": { "function-bind": "^1.1.2" } }, "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ=="],
"hasown": ["hasown@2.0.3", "", { "dependencies": { "function-bind": "^1.1.2" } }, "sha512-ej4AhfhfL2Q2zpMmLo7U1Uv9+PyhIZpgQLGT1F9miIGmiCJIoCgSmczFdrc97mWT4kVY72KA+WnnhJ5pghSvSg=="],
"hast-util-to-html": ["hast-util-to-html@9.0.5", "", { "dependencies": { "@types/hast": "^3.0.0", "@types/unist": "^3.0.0", "ccount": "^2.0.0", "comma-separated-tokens": "^2.0.0", "hast-util-whitespace": "^3.0.0", "html-void-elements": "^3.0.0", "mdast-util-to-hast": "^13.0.0", "property-information": "^7.0.0", "space-separated-tokens": "^2.0.0", "stringify-entities": "^4.0.0", "zwitch": "^2.0.4" } }, "sha512-OguPdidb+fbHQSU4Q4ZiLKnzWo8Wwsf5bZfbvu7//a9oTYoqD/fWpe96NuHkoS9h0ccGOTe0C4NGXdtS0iObOw=="],
@@ -982,7 +984,7 @@
"is-callable": ["is-callable@1.2.7", "", {}, "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA=="],
"is-core-module": ["is-core-module@2.16.1", "", { "dependencies": { "hasown": "^2.0.2" } }, "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w=="],
"is-core-module": ["is-core-module@2.16.2", "", { "dependencies": { "hasown": "^2.0.3" } }, "sha512-evOr8xfXKxE6qSR0hSXL2r3sd7ALj8+7jQEUvPYcm5sgZFdJ+AYzT6yNmJenvIYQBgIGwfwz08sL8zoL7yq2BA=="],
"is-date-object": ["is-date-object@1.1.0", "", { "dependencies": { "call-bound": "^1.0.2", "has-tostringtag": "^1.0.2" } }, "sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg=="],
@@ -1118,8 +1120,6 @@
"minipass": ["minipass@4.2.8", "", {}, "sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ=="],
"mitt": ["mitt@3.0.1", "", {}, "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw=="],
"module-details-from-path": ["module-details-from-path@1.0.4", "", {}, "sha512-EGWKgxALGMgzvxYF1UyGTy0HXX/2vHLkw6+NvDKW2jypWbHpjQuj4UMcqQWXHERJhVGKikolT06G3bcKe4fi7w=="],
"mri": ["mri@1.2.0", "", {}, "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA=="],
@@ -1128,7 +1128,7 @@
"ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="],
"nanoid": ["nanoid@5.1.7", "", { "bin": { "nanoid": "bin/nanoid.js" } }, "sha512-ua3NDgISf6jdwezAheMOk4mbE1LXjm1DfMUDMuJf4AqxLFK3ccGpgWizwa5YV7Yz9EpXwEaWoRXSb/BnV0t5dQ=="],
"nanoid": ["nanoid@5.1.11", "", { "bin": { "nanoid": "bin/nanoid.js" } }, "sha512-v+KEsUv2ps74PaSKv0gHTxTCgMXOIfBEbaqa6w6ISIGC7ZsvHN4N9oJ8d4cmf0n5oTzQz2SLmThbQWhjd/8eKg=="],
"nanotar": ["nanotar@0.3.0", "", {}, "sha512-Kv2JYYiCzt16Kt5QwAc9BFG89xfPNBx+oQL4GQXD9nLqPkZBiNaqaCWtwnbk/q7UVsTYevvM1b0UF8zmEI4pCg=="],
@@ -1138,7 +1138,7 @@
"node-fetch": ["node-fetch@2.7.0", "", { "dependencies": { "whatwg-url": "^5.0.0" }, "peerDependencies": { "encoding": "^0.1.0" }, "optionalPeers": ["encoding"] }, "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A=="],
"node-releases": ["node-releases@2.0.36", "", {}, "sha512-TdC8FSgHz8Mwtw9g5L4gR/Sh9XhSP/0DEkQxfEFXOpiul5IiHgHan2VhYYb6agDSfp4KuvltmGApc8HMgUrIkA=="],
"node-releases": ["node-releases@2.0.38", "", {}, "sha512-3qT/88Y3FbH/Kx4szpQQ4HzUbVrHPKTLVpVocKiLfoYvw9XSGOX2FmD2d6DrXbVYyAQTF2HeF6My8jmzx7/CRw=="],
"normalize-path": ["normalize-path@3.0.0", "", {}, "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA=="],
@@ -1186,15 +1186,15 @@
"picomatch": ["picomatch@4.0.4", "", {}, "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A=="],
"playwright": ["playwright@1.58.2", "", { "dependencies": { "playwright-core": "1.58.2" }, "optionalDependencies": { "fsevents": "2.3.2" }, "bin": { "playwright": "cli.js" } }, "sha512-vA30H8Nvkq/cPBnNw4Q8TWz1EJyqgpuinBcHET0YVJVFldr8JDNiU9LaWAE1KqSkRYazuaBhTpB5ZzShOezQ6A=="],
"playwright": ["playwright@1.59.1", "", { "dependencies": { "playwright-core": "1.59.1" }, "optionalDependencies": { "fsevents": "2.3.2" }, "bin": { "playwright": "cli.js" } }, "sha512-C8oWjPR3F81yljW9o5OxcWzfh6avkVwDD2VYdwIGqTkl+OGFISgypqzfu7dOe4QNLL2aqcWBmI3PMtLIK233lw=="],
"playwright-core": ["playwright-core@1.58.2", "", { "bin": { "playwright-core": "cli.js" } }, "sha512-yZkEtftgwS8CsfYo7nm0KE8jsvm6i/PTgVtB8DL726wNf6H2IMsDuxCpJj59KDaxCtSnrWan2AeDqM7JBaultg=="],
"playwright-core": ["playwright-core@1.59.1", "", { "bin": { "playwright-core": "cli.js" } }, "sha512-HBV/RJg81z5BiiZ9yPzIiClYV/QMsDCKUyogwH9p3MCP6IYjUFu/MActgYAvK0oWyV9NlwM3GLBjADyWgydVyg=="],
"popmotion": ["popmotion@11.0.5", "", { "dependencies": { "framesync": "6.1.2", "hey-listen": "^1.0.8", "style-value-types": "5.1.2", "tslib": "2.4.0" } }, "sha512-la8gPM1WYeFznb/JqF4GiTkRRPZsfaj2+kCxqQgr2MJylMmIKUwBfWW8Wa5fml/8gmtlD5yI01MP1QCZPWmppA=="],
"possible-typed-array-names": ["possible-typed-array-names@1.1.0", "", {}, "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg=="],
"postcss": ["postcss@8.5.8", "", { "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg=="],
"postcss": ["postcss@8.5.14", "", { "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-SoSL4+OSEtR99LHFZQiJLkT59C5B1amGO1NzTwj7TT1qCUgUO6hxOvzkOYxD+vMrXBM3XJIKzokoERdqQq/Zmg=="],
"postcss-load-config": ["postcss-load-config@3.1.4", "", { "dependencies": { "lilconfig": "^2.0.5", "yaml": "^1.10.2" }, "peerDependencies": { "postcss": ">=8.0.9", "ts-node": ">=9.0.0" }, "optionalPeers": ["postcss", "ts-node"] }, "sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg=="],
@@ -1214,7 +1214,7 @@
"prelude-ls": ["prelude-ls@1.2.1", "", {}, "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g=="],
"prettier": ["prettier@3.8.1", "", { "bin": { "prettier": "bin/prettier.cjs" } }, "sha512-UOnG6LftzbdaHZcKoPFtOcCKztrQ57WkHDeRD9t/PTQtmT0NHSeWWepj6pS0z/N7+08BHFDQVUrfmfMRcZwbMg=="],
"prettier": ["prettier@3.8.3", "", { "bin": { "prettier": "bin/prettier.cjs" } }, "sha512-7igPTM53cGHMW8xWuVTydi2KO233VFiTNyF5hLJqpilHfmn8C8gPf+PS7dUT64YcXFbiMGZxS9pCSxL/Dxm/Jw=="],
"prettier-plugin-svelte": ["prettier-plugin-svelte@3.5.1", "", { "peerDependencies": { "prettier": "^3.0.0", "svelte": "^3.2.0 || ^4.0.0-next.0 || ^5.0.0-next.0" } }, "sha512-65+fr5+cgIKWKiqM1Doum4uX6bY8iFCdztvvp2RcF+AJoieaw9kJOFMNcJo/bkmKYsxFaM9OsVZK/gWauG/5mg=="],
@@ -1252,11 +1252,11 @@
"require-in-the-middle": ["require-in-the-middle@7.5.2", "", { "dependencies": { "debug": "^4.3.5", "module-details-from-path": "^1.0.3", "resolve": "^1.22.8" } }, "sha512-gAZ+kLqBdHarXB64XpAe2VCjB7rIRv+mU8tfRWziHRJ5umKsIHN2tLLv6EtMw7WCdP19S0ERVMldNvxYCHnhSQ=="],
"resolve": ["resolve@1.22.11", "", { "dependencies": { "is-core-module": "^2.16.1", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": { "resolve": "bin/resolve" } }, "sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ=="],
"resolve": ["resolve@1.22.12", "", { "dependencies": { "es-errors": "^1.3.0", "is-core-module": "^2.16.1", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": { "resolve": "bin/resolve" } }, "sha512-TyeJ1zif53BPfHootBGwPRYT1RUt6oGWsaQr8UyZW/eAm9bKoijtvruSDEmZHm92CwS9nj7/fWttqPCgzep8CA=="],
"resolve-from": ["resolve-from@4.0.0", "", {}, "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g=="],
"robust-predicates": ["robust-predicates@3.0.2", "", {}, "sha512-IXgzBWvWQwE6PrDI05OvmXUIruQTcoMDzRsOd5CDvHCVLcLHMTSYvOK5Cm46kWqlV3yAbuSpBZdJ5oP5OUoStg=="],
"robust-predicates": ["robust-predicates@3.0.3", "", {}, "sha512-NS3levdsRIUOmiJ8FZWCP7LG3QpJyrs/TE0Zpf1yvZu8cAJJ6QMW92H1c7kWpdIHo8RvmLxN/o2JXTKHp74lUA=="],
"rolldown": ["rolldown@1.0.0-beta.53", "", { "dependencies": { "@oxc-project/types": "=0.101.0", "@rolldown/pluginutils": "1.0.0-beta.53" }, "optionalDependencies": { "@rolldown/binding-android-arm64": "1.0.0-beta.53", "@rolldown/binding-darwin-arm64": "1.0.0-beta.53", "@rolldown/binding-darwin-x64": "1.0.0-beta.53", "@rolldown/binding-freebsd-x64": "1.0.0-beta.53", "@rolldown/binding-linux-arm-gnueabihf": "1.0.0-beta.53", "@rolldown/binding-linux-arm64-gnu": "1.0.0-beta.53", "@rolldown/binding-linux-arm64-musl": "1.0.0-beta.53", "@rolldown/binding-linux-x64-gnu": "1.0.0-beta.53", "@rolldown/binding-linux-x64-musl": "1.0.0-beta.53", "@rolldown/binding-openharmony-arm64": "1.0.0-beta.53", "@rolldown/binding-wasm32-wasi": "1.0.0-beta.53", "@rolldown/binding-win32-arm64-msvc": "1.0.0-beta.53", "@rolldown/binding-win32-x64-msvc": "1.0.0-beta.53" }, "bin": { "rolldown": "bin/cli.mjs" } }, "sha512-Qd9c2p0XKZdgT5AYd+KgAMggJ8ZmCs3JnS9PTMWkyUfteKlfmKtxJbWTHkVakxwXs1Ub7jrRYVeFeF7N0sQxyw=="],
@@ -1270,15 +1270,15 @@
"safer-buffer": ["safer-buffer@2.1.2", "", {}, "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="],
"sass": ["sass@1.98.0", "", { "dependencies": { "chokidar": "^4.0.0", "immutable": "^5.1.5", "source-map-js": ">=0.6.2 <2.0.0" }, "optionalDependencies": { "@parcel/watcher": "^2.4.1" }, "bin": { "sass": "sass.js" } }, "sha512-+4N/u9dZ4PrgzGgPlKnaaRQx64RO0JBKs9sDhQ2pLgN6JQZ25uPQZKQYaBJU48Kd5BxgXoJ4e09Dq7nMcOUW3A=="],
"sass": ["sass@1.99.0", "", { "dependencies": { "chokidar": "^4.0.0", "immutable": "^5.1.5", "source-map-js": ">=0.6.2 <2.0.0" }, "optionalDependencies": { "@parcel/watcher": "^2.4.1" }, "bin": { "sass": "sass.js" } }, "sha512-kgW13M54DUB7IsIRM5LvJkNlpH+WhMpooUcaWGFARkF1Tc82v9mIWkCbCYf+MBvpIUBSeSOTilpZjEPr2VYE6Q=="],
"saxes": ["saxes@6.0.0", "", { "dependencies": { "xmlchars": "^2.2.0" } }, "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA=="],
"secure-json-parse": ["secure-json-parse@2.7.0", "", {}, "sha512-6aU+Rwsezw7VR8/nyvKTx8QpWH9FrcYiXXlqC4z5d5XQBDRqtbfsRjnwGyqbi3gddNtWHuEk9OANUotL26qKUw=="],
"semver": ["semver@7.7.4", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA=="],
"semver": ["semver@7.8.0", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-AcM7dV/5ul4EekoQ29Agm5vri8JNqRyj39o0qpX6vDF2GZrtutZl5RwgD1XnZjiTAfncsJhMI48QQH3sN87YNA=="],
"set-cookie-parser": ["set-cookie-parser@3.0.1", "", {}, "sha512-n7Z7dXZhJbwuAHhNzkTti6Aw9QDDjZtm3JTpTGATIdNzdQz5GuFs22w90BcvF4INfnrL5xrX3oGsuqO5Dx3A1Q=="],
"set-cookie-parser": ["set-cookie-parser@3.1.0", "", {}, "sha512-kjnC1DXBHcxaOaOXBHBeRtltsDG2nUiUni+jP92M9gYdW12rsmx92UsfpH7o5tDRs7I1ZZPSQJQGv3UaRfCiuw=="],
"set-function-length": ["set-function-length@1.2.2", "", { "dependencies": { "define-data-property": "^1.1.4", "es-errors": "^1.3.0", "function-bind": "^1.1.2", "get-intrinsic": "^1.2.4", "gopd": "^1.0.1", "has-property-descriptors": "^1.0.2" } }, "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg=="],
@@ -1294,7 +1294,7 @@
"side-channel": ["side-channel@1.1.0", "", { "dependencies": { "es-errors": "^1.3.0", "object-inspect": "^1.13.3", "side-channel-list": "^1.0.0", "side-channel-map": "^1.0.1", "side-channel-weakmap": "^1.0.2" } }, "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw=="],
"side-channel-list": ["side-channel-list@1.0.0", "", { "dependencies": { "es-errors": "^1.3.0", "object-inspect": "^1.13.3" } }, "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA=="],
"side-channel-list": ["side-channel-list@1.0.1", "", { "dependencies": { "es-errors": "^1.3.0", "object-inspect": "^1.13.4" } }, "sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w=="],
"side-channel-map": ["side-channel-map@1.0.1", "", { "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", "get-intrinsic": "^1.2.5", "object-inspect": "^1.13.3" } }, "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA=="],
@@ -1336,13 +1336,13 @@
"supports-preserve-symlinks-flag": ["supports-preserve-symlinks-flag@1.0.0", "", {}, "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w=="],
"svelte": ["svelte@5.55.0", "", { "dependencies": { "@jridgewell/remapping": "^2.3.4", "@jridgewell/sourcemap-codec": "^1.5.0", "@sveltejs/acorn-typescript": "^1.0.5", "@types/estree": "^1.0.5", "@types/trusted-types": "^2.0.7", "acorn": "^8.12.1", "aria-query": "5.3.1", "axobject-query": "^4.1.0", "clsx": "^2.1.1", "devalue": "^5.6.4", "esm-env": "^1.2.1", "esrap": "^2.2.2", "is-reference": "^3.0.3", "locate-character": "^3.0.0", "magic-string": "^0.30.11", "zimmerframe": "^1.1.2" } }, "sha512-SThllKq6TRMBwPtat7ASnm/9CDXnIhBR0NPGw0ujn2DVYx9rVwsPZxDaDQcYGdUz/3BYVsCzdq7pZarRQoGvtw=="],
"svelte": ["svelte@5.55.5", "", { "dependencies": { "@jridgewell/remapping": "^2.3.4", "@jridgewell/sourcemap-codec": "^1.5.0", "@sveltejs/acorn-typescript": "^1.0.5", "@types/estree": "^1.0.5", "@types/trusted-types": "^2.0.7", "acorn": "^8.12.1", "aria-query": "5.3.1", "axobject-query": "^4.1.0", "clsx": "^2.1.1", "devalue": "^5.6.4", "esm-env": "^1.2.1", "esrap": "^2.2.4", "is-reference": "^3.0.3", "locate-character": "^3.0.0", "magic-string": "^0.30.11", "zimmerframe": "^1.1.2" } }, "sha512-2uCs/LZ9us+AktdzYJM8OcxQ8qnPS1kpaO7syGT/MgO+6Qr1Ybl+TqPq+97u7PHqmmMlye5ZkoyXONy5mjjAbw=="],
"svelte-check": ["svelte-check@4.4.5", "", { "dependencies": { "@jridgewell/trace-mapping": "^0.3.25", "chokidar": "^4.0.1", "fdir": "^6.2.0", "picocolors": "^1.0.0", "sade": "^1.7.4" }, "peerDependencies": { "svelte": "^4.0.0 || ^5.0.0-next.0", "typescript": ">=5.0.0" }, "bin": { "svelte-check": "bin/svelte-check" } }, "sha512-1bSwIRCvvmSHrlK52fOlZmVtUZgil43jNL/2H18pRpa+eQjzGt6e3zayxhp1S7GajPFKNM/2PMCG+DZFHlG9fw=="],
"svelte-check": ["svelte-check@4.4.8", "", { "dependencies": { "@jridgewell/trace-mapping": "^0.3.25", "chokidar": "^4.0.1", "fdir": "^6.2.0", "picocolors": "^1.0.0", "sade": "^1.7.4" }, "peerDependencies": { "svelte": "^4.0.0 || ^5.0.0-next.0", "typescript": ">=5.0.0" }, "bin": { "svelte-check": "bin/svelte-check" } }, "sha512-67adfgBox5eNSNIvIIwgFizKGdcRrGpiMoNO2obHcYuLz7iTa8Xgm/NGU3ntMFnNm8K1grFOIG6HhMLX/vcN8w=="],
"svelte-confetti": ["svelte-confetti@1.4.0", "", { "peerDependencies": { "svelte": "^4.0.0" } }, "sha512-B0woNwpsFGwhkEoP48BIDQgvW0bMxPhavLVD+E+tsTWevlpr1aiz1S2wA8ArIXX957BiaZWHRHKmI5/pFRDbdg=="],
"svelte-eslint-parser": ["svelte-eslint-parser@1.6.0", "", { "dependencies": { "eslint-scope": "^8.2.0", "eslint-visitor-keys": "^4.0.0", "espree": "^10.0.0", "postcss": "^8.4.49", "postcss-scss": "^4.0.9", "postcss-selector-parser": "^7.0.0", "semver": "^7.7.2" }, "peerDependencies": { "svelte": "^3.37.0 || ^4.0.0 || ^5.0.0" }, "optionalPeers": ["svelte"] }, "sha512-qoB1ehychT6OxEtQAqc/guSqLS20SlA53Uijl7x375s8nlUT0lb9ol/gzraEEatQwsyPTJo87s2CmKL9Xab+Uw=="],
"svelte-eslint-parser": ["svelte-eslint-parser@1.6.1", "", { "dependencies": { "eslint-scope": "^8.2.0", "eslint-visitor-keys": "^4.0.0", "espree": "^10.0.0", "postcss": "^8.4.49", "postcss-scss": "^4.0.9", "postcss-selector-parser": "^7.0.0", "semver": "^7.7.2" }, "peerDependencies": { "svelte": "^3.37.0 || ^4.0.0 || ^5.0.0" }, "optionalPeers": ["svelte"] }, "sha512-hhvSH6kRj46UzrBVO5TaotD+Iuvruj5ccKBcO4wAhVcPTLmIc/c32D8UllBTYO0on4LzYuM0rNzf1lM/gBlkSQ=="],
"svelte-motion": ["svelte-motion@0.12.2", "", { "dependencies": { "@types/react": "^18.2.42", "framesync": "^6.1.2", "popmotion": "^11.0.5", "style-value-types": "5.1.2", "tslib": "^2.6.2" }, "peerDependencies": { "svelte": ">=3.35.0 || ^4.0.0 || ^5.0.0 || ^5.0.0-next.0" } }, "sha512-7RrdRz9iVP55B9HT/C0hYW3pyrKlF61kAby/AkDtOAP0uHFQDrfd0qQetDC81cEsK9b40jt+jfcqSAXcA7LPEw=="],
@@ -1376,7 +1376,7 @@
"tinyexec": ["tinyexec@0.3.2", "", {}, "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA=="],
"tinyglobby": ["tinyglobby@0.2.15", "", { "dependencies": { "fdir": "^6.5.0", "picomatch": "^4.0.3" } }, "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ=="],
"tinyglobby": ["tinyglobby@0.2.16", "", { "dependencies": { "fdir": "^6.5.0", "picomatch": "^4.0.4" } }, "sha512-pn99VhoACYR8nFHhxqix+uvsbXineAasWm5ojXoN8xEwK5Kd3/TrhNn1wByuD52UxWRLy8pu+kRMniEi6Eq9Zg=="],
"tinypool": ["tinypool@1.1.1", "", {}, "sha512-Zba82s87IFq9A9XmjiX5uZA/ARWDrB03OHlq+Vw1fSdt0I+4/Kutwy8BP4Y/y/aORMo61FQ0vIb5j44vSo5Pkg=="],
@@ -1386,9 +1386,9 @@
"tippy.js": ["tippy.js@6.3.7", "", { "dependencies": { "@popperjs/core": "^2.9.0" } }, "sha512-E1d3oP2emgJ9dRQZdf3Kkn0qJgI6ZLpyS5z6ZkY1DF3kaQaBsGZsndEpHwx+eC+tYM41HaSNvNtLx8tU57FzTQ=="],
"tldts": ["tldts@7.0.27", "", { "dependencies": { "tldts-core": "^7.0.27" }, "bin": { "tldts": "bin/cli.js" } }, "sha512-I4FZcVFcqCRuT0ph6dCDpPuO4Xgzvh+spkcTr1gK7peIvxWauoloVO0vuy1FQnijT63ss6AsHB6+OIM4aXHbPg=="],
"tldts": ["tldts@7.0.30", "", { "dependencies": { "tldts-core": "^7.0.30" }, "bin": { "tldts": "bin/cli.js" } }, "sha512-ELrFxuqsDdHUwoh0XxDbxuLD3Wnz49Z57IFvTtvWy1hJdcMZjXLIuonjilCiWHlT2GbE4Wlv1wKVTzDFnXH1aw=="],
"tldts-core": ["tldts-core@7.0.27", "", {}, "sha512-YQ7uPjgWUibIK6DW5lrKujGwUKhLevU4hcGbP5O6TcIUb+oTjJYJVWPS4nZsIHrEEEG6myk/oqAJUEQmpZrHsg=="],
"tldts-core": ["tldts-core@7.0.30", "", {}, "sha512-uiHN8PIB1VmWyS98eZYja4xzlYqeFZVjb4OuYlJQnZAuJhMw4PbKQOKgHKhBdJR3FE/t5mUQ1Kd80++B+qhD1Q=="],
"to-regex-range": ["to-regex-range@5.0.1", "", { "dependencies": { "is-number": "^7.0.0" } }, "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ=="],
@@ -1406,7 +1406,7 @@
"troika-worker-utils": ["troika-worker-utils@0.52.0", "", {}, "sha512-W1CpvTHykaPH5brv5VHLfQo9D1OYuo0cSBEUQFFT/nBUzM8iD6Lq2/tgG/f1OelbAS1WtaTPQzE5uM49egnngw=="],
"ts-api-utils": ["ts-api-utils@2.4.0", "", { "peerDependencies": { "typescript": ">=4.8.4" } }, "sha512-3TaVTaAv2gTiMB35i3FiGJaRfwb3Pyn/j3m/bfAvGe8FB7CF6u+LMYqYlDh7reQf7UNvoTvdfAqHGmPGOSsPmA=="],
"ts-api-utils": ["ts-api-utils@2.5.0", "", { "peerDependencies": { "typescript": ">=4.8.4" } }, "sha512-OJ/ibxhPlqrMM0UiNHJ/0CKQkoKF243/AEmplt3qpRgkW8VG7IfOS41h7V8TjITqdByHzrjcS/2si+y4lIh8NA=="],
"tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="],
@@ -1416,9 +1416,9 @@
"typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="],
"typescript-eslint": ["typescript-eslint@8.57.2", "", { "dependencies": { "@typescript-eslint/eslint-plugin": "8.57.2", "@typescript-eslint/parser": "8.57.2", "@typescript-eslint/typescript-estree": "8.57.2", "@typescript-eslint/utils": "8.57.2" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-VEPQ0iPgWO/sBaZOU1xo4nuNdODVOajPnTIbog2GKYr31nIlZ0fWPoCQgGfF3ETyBl1vn63F/p50Um9Z4J8O8A=="],
"typescript-eslint": ["typescript-eslint@8.59.2", "", { "dependencies": { "@typescript-eslint/eslint-plugin": "8.59.2", "@typescript-eslint/parser": "8.59.2", "@typescript-eslint/typescript-estree": "8.59.2", "@typescript-eslint/utils": "8.59.2" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.1.0" } }, "sha512-pJw051uomb3ZeCzGTpRb8RbEqB5Y4WWet8gl/GcTlU35BSx0PVdZ86/bqkQCyKKuraVQEK7r6kBHQXF+fBhkoQ=="],
"undici-types": ["undici-types@7.18.2", "", {}, "sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w=="],
"undici-types": ["undici-types@7.19.2", "", {}, "sha512-qYVnV5OEm2AW8cJMCpdV20CDyaN3g0AjDlOGf1OW4iaDEx8MwdtChUp4zu4H0VP3nDRF/8RKWH+IPp9uW0YGZg=="],
"unist-util-is": ["unist-util-is@6.0.1", "", { "dependencies": { "@types/unist": "^3.0.0" } }, "sha512-LsiILbtBETkDz8I9p1dQ0uyRUWuaQzd/cuEeS1hoRSyW5E5XGmTzlwY1OrNzzakGowI9Dr/I8HVaw4hTtnxy8g=="],
@@ -1446,7 +1446,7 @@
"vite-node": ["vite-node@3.2.4", "", { "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" } }, "sha512-EbKSKh+bh1E1IFxeO0pg1n4dvoOTt0UDiXMd/qn++r98+jPO1xtJilvXldeuQ8giIB5IkpjCgMleHMNEsGH6pg=="],
"vitefu": ["vitefu@1.1.2", "", { "peerDependencies": { "vite": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-beta.0" }, "optionalPeers": ["vite"] }, "sha512-zpKATdUbzbsycPFBN71nS2uzBUQiVnFoOrr2rvqv34S1lcAgMKKkjWleLGeiJlZ8lwCXvtWaRn7R3ZC16SYRuw=="],
"vitefu": ["vitefu@1.1.3", "", { "peerDependencies": { "vite": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0" }, "optionalPeers": ["vite"] }, "sha512-ub4okH7Z5KLjb6hDyjqrGXqWtWvoYdU3IGm/NorpgHncKoLTCfRIbvlhBm7r0YstIaQRYlp4yEbFqDcKSzXSSg=="],
"vitest": ["vitest@3.2.4", "", { "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" }, "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": "*" }, "optionalPeers": ["@edge-runtime/vm", "@types/debug", "@types/node", "@vitest/browser", "@vitest/ui", "happy-dom", "jsdom"], "bin": { "vitest": "vitest.mjs" } }, "sha512-LUCP5ev3GURDysTWiP47wRRUpLKMOfPh+yKTx3kVIEiu5KOMeqzpnYNsKyOoVrULivR8tLcks4+lga33Whn90A=="],
@@ -1458,7 +1458,7 @@
"webidl-conversions": ["webidl-conversions@7.0.0", "", {}, "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g=="],
"webpack-sources": ["webpack-sources@3.3.4", "", {}, "sha512-7tP1PdV4vF+lYPnkMR0jMY5/la2ub5Fc/8VQrrU+lXkiM6C4TjVfGw7iKfyhnTQOsD+6Q/iKw0eFciziRgD58Q=="],
"webpack-sources": ["webpack-sources@3.4.1", "", {}, "sha512-eACpxRN02yaawnt+uUNIF7Qje6A9zArxBbcAJjK1PK3S9Ycg5jIuJ8pW4q8EMnwNZCEGltcjkRx1QzOxOkKD8A=="],
"webpack-virtual-modules": ["webpack-virtual-modules@0.5.0", "", {}, "sha512-kyDivFZ7ZM0BVOUteVbDFhlRt7Ah/CSPwJdi8hBpkK7QLumUqdLtVfm/PX/hkcnrvr0i77fO5+TjZ94Pe+C9iw=="],
@@ -1480,7 +1480,7 @@
"word-wrap": ["word-wrap@1.2.5", "", {}, "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA=="],
"ws": ["ws@8.19.0", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg=="],
"ws": ["ws@8.20.0", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-sAt8BhgNbzCtgGbt2OxmpuryO63ZoDk/sqaB/znQm94T4fCEsy/yV+7CdC1kJhOU9lboAEU7R3kquuycDoibVA=="],
"xml-name-validator": ["xml-name-validator@5.0.0", "", {}, "sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg=="],
@@ -1496,19 +1496,19 @@
"zimmerframe": ["zimmerframe@1.1.4", "", {}, "sha512-B58NGBEoc8Y9MWWCQGl/gq9xBCe4IiKM0a2x7GZdQKOW5Exr8S1W24J6OgM1njK8xCRGvAJIL/MxXHf6SkmQKQ=="],
"zod": ["zod@4.3.6", "", {}, "sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg=="],
"zod": ["zod@4.4.3", "", {}, "sha512-ytENFjIJFl2UwYglde2jchW2Hwm4GJFLDiSXWdTrJQBIN9Fcyp7n4DhxJEiWNAJMV1/BqWfW/kkg71UDcHJyTQ=="],
"zod-to-json-schema": ["zod-to-json-schema@3.25.1", "", { "peerDependencies": { "zod": "^3.25 || ^4" } }, "sha512-pM/SU9d3YAggzi6MtR4h7ruuQlqKtad8e9S0fmxcMi+ueAK5Korys/aWcV9LIIHTVbj01NdzxcnXSN+O74ZIVA=="],
"zod-to-json-schema": ["zod-to-json-schema@3.25.2", "", { "peerDependencies": { "zod": "^3.25.28 || ^4" } }, "sha512-O/PgfnpT1xKSDeQYSCfRI5Gy3hPf91mKVDuYLUHZJMiDFptvP41MSnWofm8dnCm0256ZNfZIM7DSzuSMAFnjHA=="],
"zrender": ["zrender@5.6.1", "", { "dependencies": { "tslib": "2.3.0" } }, "sha512-OFXkDJKcrlx5su2XbzJvj/34Q3m6PvyCZkVPHGYpcCJ52ek4U/ymZyfuV1nKE23AyBJ51E/6Yr0mhZ7xGTO4ag=="],
"zwitch": ["zwitch@2.0.4", "", {}, "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A=="],
"@ai-sdk/gateway/@ai-sdk/provider-utils": ["@ai-sdk/provider-utils@4.0.21", "", { "dependencies": { "@ai-sdk/provider": "3.0.8", "@standard-schema/spec": "^1.1.0", "eventsource-parser": "^3.0.6" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-MtFUYI1/8mgDvRmaBDjbLJPFFrMG777AvSgyIFQtZHIMzm88R/12vYBBpnk7pfiWLFE1DSZzY4WDYzGbKAcmiw=="],
"@ai-sdk/gateway/@ai-sdk/provider-utils": ["@ai-sdk/provider-utils@4.0.27", "", { "dependencies": { "@ai-sdk/provider": "3.0.10", "@standard-schema/spec": "^1.1.0", "eventsource-parser": "^3.0.8" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-ubkAJ+xODouwtmN1tYlvTPphH1hPOBfZaEQe8U7skGvFAnIRs9PPpsq57bC2+Ky/MB4yzhd6YOsxTAx9sGpazw=="],
"@ai-sdk/provider-utils/@ai-sdk/provider": ["@ai-sdk/provider@1.0.11", "", { "dependencies": { "json-schema": "^0.4.0" } }, "sha512-CPyImHGiT3svyfmvPvAFTianZzWFtm0qK82XjwlQIA1C3IQ2iku/PMQXi7aFyrX0TyMh3VTkJPB03tjU2VXVrw=="],
"@ai-sdk/provider-utils/nanoid": ["nanoid@3.3.11", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w=="],
"@ai-sdk/provider-utils/nanoid": ["nanoid@3.3.12", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ=="],
"@ai-sdk/ui-utils/@ai-sdk/provider": ["@ai-sdk/provider@1.0.11", "", { "dependencies": { "json-schema": "^0.4.0" } }, "sha512-CPyImHGiT3svyfmvPvAFTianZzWFtm0qK82XjwlQIA1C3IQ2iku/PMQXi7aFyrX0TyMh3VTkJPB03tjU2VXVrw=="],
@@ -1548,13 +1548,15 @@
"@sentry/sveltekit/magic-string": ["magic-string@0.30.7", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.4.15" } }, "sha512-8vBuFF/I/+OSLRmdf2wwFCJCz+nSn0m6DPvGH1fS/KiQoSaR+sETbov0eIk9KhEKy8CYqIkIAnbohxT/4H0kuA=="],
"@testing-library/jest-dom/aria-query": ["aria-query@5.3.1", "", {}, "sha512-Z/ZeOgVl7bcSYZ/u/rh0fOpvEpq//LZmdbkXyc7syVzjPAhfOa9ebsdTSjEBDU4vs5nC98Kfduj1uFo0qyET3g=="],
"@testing-library/jest-dom/dom-accessibility-api": ["dom-accessibility-api@0.6.3", "", {}, "sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w=="],
"@typescript-eslint/eslint-plugin/ignore": ["ignore@7.0.5", "", {}, "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg=="],
"@typescript-eslint/visitor-keys/eslint-visitor-keys": ["eslint-visitor-keys@5.0.1", "", {}, "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA=="],
"ai/@ai-sdk/provider-utils": ["@ai-sdk/provider-utils@4.0.21", "", { "dependencies": { "@ai-sdk/provider": "3.0.8", "@standard-schema/spec": "^1.1.0", "eventsource-parser": "^3.0.6" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-MtFUYI1/8mgDvRmaBDjbLJPFFrMG777AvSgyIFQtZHIMzm88R/12vYBBpnk7pfiWLFE1DSZzY4WDYzGbKAcmiw=="],
"ai/@ai-sdk/provider-utils": ["@ai-sdk/provider-utils@4.0.27", "", { "dependencies": { "@ai-sdk/provider": "3.0.10", "@standard-schema/spec": "^1.1.0", "eventsource-parser": "^3.0.8" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-ubkAJ+xODouwtmN1tYlvTPphH1hPOBfZaEQe8U7skGvFAnIRs9PPpsq57bC2+Ky/MB4yzhd6YOsxTAx9sGpazw=="],
"chalk/ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="],
@@ -1562,8 +1564,6 @@
"eslint/ignore": ["ignore@5.3.2", "", {}, "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g=="],
"esrap/@typescript-eslint/types": ["@typescript-eslint/types@8.57.0", "", {}, "sha512-dTLI8PEXhjUC7B9Kre+u0XznO696BhXcTlOn0/6kf1fHaQW8+VjJAVHJ3eTI14ZapTxdkOmc80HblPQLaEeJdg=="],
"framesync/tslib": ["tslib@2.4.0", "", {}, "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ=="],
"js-yaml/argparse": ["argparse@2.0.1", "", {}, "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="],
@@ -1576,7 +1576,7 @@
"popmotion/tslib": ["tslib@2.4.0", "", {}, "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ=="],
"postcss/nanoid": ["nanoid@3.3.11", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w=="],
"postcss/nanoid": ["nanoid@3.3.12", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ=="],
"strip-literal/js-tokens": ["js-tokens@9.0.1", "", {}, "sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ=="],
@@ -1584,8 +1584,6 @@
"svelte/aria-query": ["aria-query@5.3.1", "", {}, "sha512-Z/ZeOgVl7bcSYZ/u/rh0fOpvEpq//LZmdbkXyc7syVzjPAhfOa9ebsdTSjEBDU4vs5nC98Kfduj1uFo0qyET3g=="],
"svelte-sequential-preprocessor/svelte": ["svelte@5.53.12", "", { "dependencies": { "@jridgewell/remapping": "^2.3.4", "@jridgewell/sourcemap-codec": "^1.5.0", "@sveltejs/acorn-typescript": "^1.0.5", "@types/estree": "^1.0.5", "@types/trusted-types": "^2.0.7", "acorn": "^8.12.1", "aria-query": "5.3.1", "axobject-query": "^4.1.0", "clsx": "^2.1.1", "devalue": "^5.6.4", "esm-env": "^1.2.1", "esrap": "^2.2.2", "is-reference": "^3.0.3", "locate-character": "^3.0.0", "magic-string": "^0.30.11", "zimmerframe": "^1.1.2" } }, "sha512-4x/uk4rQe/d7RhfvS8wemTfNjQ0bJbKvamIzRBfTe2eHHjzBZ7PZicUQrC2ryj83xxEacfA1zHKd1ephD1tAxA=="],
"tough-cookie/tldts": ["tldts@6.1.86", "", { "dependencies": { "tldts-core": "^6.1.86" }, "bin": { "tldts": "bin/cli.js" } }, "sha512-WMi/OQ2axVTf/ykqCQgXiIct+mSQDFdH2fkwhPwgEwvJ1kSzZRiinb0zF2Xb8u4+OqPChmyI6MEu4EezNJz+FQ=="],
"unplugin/chokidar": ["chokidar@3.6.0", "", { "dependencies": { "anymatch": "~3.1.2", "braces": "~3.0.2", "glob-parent": "~5.1.2", "is-binary-path": "~2.1.0", "is-glob": "~4.0.1", "normalize-path": "~3.0.0", "readdirp": "~3.6.0" }, "optionalDependencies": { "fsevents": "~2.3.2" } }, "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw=="],
@@ -1604,12 +1602,8 @@
"node-fetch/whatwg-url/webidl-conversions": ["webidl-conversions@3.0.1", "", {}, "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="],
"svelte-sequential-preprocessor/svelte/aria-query": ["aria-query@5.3.1", "", {}, "sha512-Z/ZeOgVl7bcSYZ/u/rh0fOpvEpq//LZmdbkXyc7syVzjPAhfOa9ebsdTSjEBDU4vs5nC98Kfduj1uFo0qyET3g=="],
"tough-cookie/tldts/tldts-core": ["tldts-core@6.1.86", "", {}, "sha512-Je6p7pkk+KMzMv2XXKmAE3McmolOQFdxkKw0R8EYNr7sELW46JqnNeTX8ybPiQgvg1ymCoF8LXs5fzFaZvJPTA=="],
"unplugin/chokidar/fsevents": ["fsevents@2.3.2", "", { "os": "darwin" }, "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA=="],
"unplugin/chokidar/glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="],
"unplugin/chokidar/readdirp": ["readdirp@3.6.0", "", { "dependencies": { "picomatch": "^2.2.1" } }, "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA=="],
-19
View File
@@ -936,42 +936,36 @@ packages:
engines: {node: '>= 10.0.0'}
cpu: [arm]
os: [linux]
libc: [glibc]
'@parcel/watcher-linux-arm-musl@2.5.6':
resolution: {integrity: sha512-Ve3gUCG57nuUUSyjBq/MAM0CzArtuIOxsBdQ+ftz6ho8n7s1i9E1Nmk/xmP323r2YL0SONs1EuwqBp2u1k5fxg==}
engines: {node: '>= 10.0.0'}
cpu: [arm]
os: [linux]
libc: [musl]
'@parcel/watcher-linux-arm64-glibc@2.5.6':
resolution: {integrity: sha512-f2g/DT3NhGPdBmMWYoxixqYr3v/UXcmLOYy16Bx0TM20Tchduwr4EaCbmxh1321TABqPGDpS8D/ggOTaljijOA==}
engines: {node: '>= 10.0.0'}
cpu: [arm64]
os: [linux]
libc: [glibc]
'@parcel/watcher-linux-arm64-musl@2.5.6':
resolution: {integrity: sha512-qb6naMDGlbCwdhLj6hgoVKJl2odL34z2sqkC7Z6kzir8b5W65WYDpLB6R06KabvZdgoHI/zxke4b3zR0wAbDTA==}
engines: {node: '>= 10.0.0'}
cpu: [arm64]
os: [linux]
libc: [musl]
'@parcel/watcher-linux-x64-glibc@2.5.6':
resolution: {integrity: sha512-kbT5wvNQlx7NaGjzPFu8nVIW1rWqV780O7ZtkjuWaPUgpv2NMFpjYERVi0UYj1msZNyCzGlaCWEtzc+exjMGbQ==}
engines: {node: '>= 10.0.0'}
cpu: [x64]
os: [linux]
libc: [glibc]
'@parcel/watcher-linux-x64-musl@2.5.6':
resolution: {integrity: sha512-1JRFeC+h7RdXwldHzTsmdtYR/Ku8SylLgTU/reMuqdVD7CtLwf0VR1FqeprZ0eHQkO0vqsbvFLXUmYm/uNKJBg==}
engines: {node: '>= 10.0.0'}
cpu: [x64]
os: [linux]
libc: [musl]
'@parcel/watcher-win32-arm64@2.5.6':
resolution: {integrity: sha512-3ukyebjc6eGlw9yRt678DxVF7rjXatWiHvTXqphZLvo7aC5NdEgFufVwjFfY51ijYEWpXbqF5jtrK275z52D4Q==}
@@ -1046,79 +1040,66 @@ packages:
resolution: {integrity: sha512-RzeBwv0B3qtVBWtcuABtSuCzToo2IEAIQrcyB/b2zMvBWVbjo8bZDjACUpnaafaxhTw2W+imQbP2BD1usasK4g==}
cpu: [arm]
os: [linux]
libc: [glibc]
'@rollup/rollup-linux-arm-musleabihf@4.60.0':
resolution: {integrity: sha512-Sf7zusNI2CIU1HLzuu9Tc5YGAHEZs5Lu7N1ssJG4Tkw6e0MEsN7NdjUDDfGNHy2IU+ENyWT+L2obgWiguWibWQ==}
cpu: [arm]
os: [linux]
libc: [musl]
'@rollup/rollup-linux-arm64-gnu@4.60.0':
resolution: {integrity: sha512-DX2x7CMcrJzsE91q7/O02IJQ5/aLkVtYFryqCjduJhUfGKG6yJV8hxaw8pZa93lLEpPTP/ohdN4wFz7yp/ry9A==}
cpu: [arm64]
os: [linux]
libc: [glibc]
'@rollup/rollup-linux-arm64-musl@4.60.0':
resolution: {integrity: sha512-09EL+yFVbJZlhcQfShpswwRZ0Rg+z/CsSELFCnPt3iK+iqwGsI4zht3secj5vLEs957QvFFXnzAT0FFPIxSrkQ==}
cpu: [arm64]
os: [linux]
libc: [musl]
'@rollup/rollup-linux-loong64-gnu@4.60.0':
resolution: {integrity: sha512-i9IcCMPr3EXm8EQg5jnja0Zyc1iFxJjZWlb4wr7U2Wx/GrddOuEafxRdMPRYVaXjgbhvqalp6np07hN1w9kAKw==}
cpu: [loong64]
os: [linux]
libc: [glibc]
'@rollup/rollup-linux-loong64-musl@4.60.0':
resolution: {integrity: sha512-DGzdJK9kyJ+B78MCkWeGnpXJ91tK/iKA6HwHxF4TAlPIY7GXEvMe8hBFRgdrR9Ly4qebR/7gfUs9y2IoaVEyog==}
cpu: [loong64]
os: [linux]
libc: [musl]
'@rollup/rollup-linux-ppc64-gnu@4.60.0':
resolution: {integrity: sha512-RwpnLsqC8qbS8z1H1AxBA1H6qknR4YpPR9w2XX0vo2Sz10miu57PkNcnHVaZkbqyw/kUWfKMI73jhmfi9BRMUQ==}
cpu: [ppc64]
os: [linux]
libc: [glibc]
'@rollup/rollup-linux-ppc64-musl@4.60.0':
resolution: {integrity: sha512-Z8pPf54Ly3aqtdWC3G4rFigZgNvd+qJlOE52fmko3KST9SoGfAdSRCwyoyG05q1HrrAblLbk1/PSIV+80/pxLg==}
cpu: [ppc64]
os: [linux]
libc: [musl]
'@rollup/rollup-linux-riscv64-gnu@4.60.0':
resolution: {integrity: sha512-3a3qQustp3COCGvnP4SvrMHnPQ9d1vzCakQVRTliaz8cIp/wULGjiGpbcqrkv0WrHTEp8bQD/B3HBjzujVWLOA==}
cpu: [riscv64]
os: [linux]
libc: [glibc]
'@rollup/rollup-linux-riscv64-musl@4.60.0':
resolution: {integrity: sha512-pjZDsVH/1VsghMJ2/kAaxt6dL0psT6ZexQVrijczOf+PeP2BUqTHYejk3l6TlPRydggINOeNRhvpLa0AYpCWSQ==}
cpu: [riscv64]
os: [linux]
libc: [musl]
'@rollup/rollup-linux-s390x-gnu@4.60.0':
resolution: {integrity: sha512-3ObQs0BhvPgiUVZrN7gqCSvmFuMWvWvsjG5ayJ3Lraqv+2KhOsp+pUbigqbeWqueGIsnn+09HBw27rJ+gYK4VQ==}
cpu: [s390x]
os: [linux]
libc: [glibc]
'@rollup/rollup-linux-x64-gnu@4.60.0':
resolution: {integrity: sha512-EtylprDtQPdS5rXvAayrNDYoJhIz1/vzN2fEubo3yLE7tfAw+948dO0g4M0vkTVFhKojnF+n6C8bDNe+gDRdTg==}
cpu: [x64]
os: [linux]
libc: [glibc]
'@rollup/rollup-linux-x64-musl@4.60.0':
resolution: {integrity: sha512-k09oiRCi/bHU9UVFqD17r3eJR9bn03TyKraCrlz5ULFJGdJGi7VOmm9jl44vOJvRJ6P7WuBi/s2A97LxxHGIdw==}
cpu: [x64]
os: [linux]
libc: [musl]
'@rollup/rollup-openbsd-x64@4.60.0':
resolution: {integrity: sha512-1o/0/pIhozoSaDJoDcec+IVLbnRtQmHwPV730+AOD29lHEEo4F5BEUB24H0OBdhbBBDwIOSuf7vgg0Ywxdfiiw==}
@@ -0,0 +1,13 @@
<script lang="ts">
import { page } from '$app/state';
import { HeaderAlert } from '$lib/layout';
import { hideBillingHeaderRoutes, teamStatusUpgrading } from '$lib/stores/billing';
import { organization } from '$lib/stores/organization';
</script>
{#if $organization?.$id && $organization?.status === teamStatusUpgrading && !hideBillingHeaderRoutes.includes(page.url.pathname)}
<HeaderAlert title="Payment is processing" type="info">
Your plan will activate within a few minutes. You can keep using {$organization.name} while we
confirm the charge with your bank.
</HeaderAlert>
{/if}
@@ -50,10 +50,10 @@
{#if selectedPaymentMethod?.country?.toLowerCase() === 'in'}
<Alert.Inline status="warning">
<svelte:fragment slot="title">Indian credit or debit card-holders</svelte:fragment>
To comply with RBI regulations in India, Appwrite will ask for verification to charge
up to $150 USD on your payment method. We will never charge more than the cost of your
plan and the resources you use, or your budget cap limit. For higher usage limits, please
contact us.
To comply with RBI regulations in India, you will be asked to authenticate the first charge
during checkout, and Appwrite will set up a mandate to charge up to $150 USD on your payment
method for future renewals. We will never charge more than the cost of your plan and the
resources you use, or your budget cap limit. For higher usage limits, please contact us.
</Alert.Inline>
{/if}
<InputSelect
@@ -1,5 +1,6 @@
<script lang="ts">
import { regionalConsoleVariables } from '$routes/(console)/project-[region]-[project]/store';
import { getProxyRuleStatusBadge } from './status';
import { Badge, Layout, Typography, Table, InteractiveText } from '@appwrite.io/pink-svelte';
@@ -24,16 +25,13 @@
{domain}
</Typography.Text>
{#if verified !== undefined}
{#if ruleStatus === 'created'}
<Badge variant="secondary" type="error" size="xs" content="Verification failed" />
{:else if ruleStatus === 'verifying'}
<Badge variant="secondary" size="xs" content="Generating certificate" />
{:else if ruleStatus === 'unverified'}
{@const statusBadge = getProxyRuleStatusBadge(ruleStatus)}
{#if statusBadge}
<Badge
variant="secondary"
type="error"
type={statusBadge.type}
size="xs"
content="Certificate generation failed" />
content={statusBadge.content} />
{:else if verified === true}
<Badge variant="secondary" type="success" size="xs" content="Verified" />
{/if}
+5 -11
View File
@@ -11,6 +11,7 @@
import { regionalConsoleVariables } from '$routes/(console)/project-[region]-[project]/store';
import { getSubdomain } from '$lib/helpers/tlds';
import { isCloud } from '$lib/system';
import { getProxyRuleStatusBadge } from './status';
let {
domain,
@@ -72,20 +73,13 @@
{domain}
</Typography.Text>
{#if verified !== undefined}
{#if ruleStatus === 'created'}
{@const statusBadge = getProxyRuleStatusBadge(ruleStatus)}
{#if statusBadge}
<Badge
variant="secondary"
type="error"
type={statusBadge.type}
size="xs"
content="Verification failed" />
{:else if ruleStatus === 'verifying'}
<Badge variant="secondary" size="xs" content="Generating certificate" />
{:else if ruleStatus === 'unverified'}
<Badge
variant="secondary"
type="error"
size="xs"
content="Certificate generation failed" />
content={statusBadge.content} />
{:else if verified === true}
<Badge variant="secondary" type="success" size="xs" content="Verified" />
{/if}
+69
View File
@@ -0,0 +1,69 @@
import { ProxyRuleStatus, type Models } from '@appwrite.io/console';
export type ProxyRuleStatusValue =
| 'created'
| 'verified'
| 'verifying'
| 'unverified'
| ProxyRuleStatus
| undefined;
export function isProxyRuleVerified(status: ProxyRuleStatusValue): boolean {
return status === ProxyRuleStatus.Verified;
}
export function normalizeProxyRuleStatus(status: ProxyRuleStatusValue): ProxyRuleStatusValue {
if (status === 'created') {
return ProxyRuleStatus.Unverified;
}
return status;
}
export function isProxyRuleRetryable(status: ProxyRuleStatusValue): boolean {
const normalizedStatus = normalizeProxyRuleStatus(status);
return normalizedStatus === ProxyRuleStatus.Unverified;
}
export function isProxyRuleLogsViewable(proxyRule: Models.ProxyRule): boolean {
return (
Boolean(proxyRule.logs?.length) &&
normalizeProxyRuleStatus(proxyRule.status) !== ProxyRuleStatus.Verified
);
}
export function getProxyRuleUpdatedPrefix(status: ProxyRuleStatusValue): string {
const normalizedStatus = normalizeProxyRuleStatus(status);
if (normalizedStatus === ProxyRuleStatus.Verifying) {
return 'Updated';
}
if (normalizedStatus === ProxyRuleStatus.Unverified) {
return 'Failed';
}
return '';
}
export function getProxyRuleStatusBadge(status: ProxyRuleStatusValue): {
content: string;
type?: 'error';
} | null {
const normalizedStatus = normalizeProxyRuleStatus(status);
if (normalizedStatus === ProxyRuleStatus.Verifying) {
return {
content: 'Generating certificate'
};
}
if (normalizedStatus === ProxyRuleStatus.Unverified) {
return {
content: 'Certificate generation failed',
type: 'error'
};
}
return null;
}
@@ -43,7 +43,7 @@
try {
selectedProxyRule = await sdk
.forProject(page.params.region, page.params.project)
.proxy.updateRuleVerification({ ruleId: selectedProxyRule.$id });
.proxy.updateRuleStatus({ ruleId: selectedProxyRule.$id });
await invalidate(Dependencies.DOMAINS);
show = false;
+135 -13
View File
@@ -1,17 +1,139 @@
<script lang="ts">
import { uploader } from '$lib/stores/uploader';
import { Upload } from '@appwrite.io/pink-svelte';
import { humanFileSize } from '$lib/helpers/sizeConvertion';
import {
getUploadGroupKey,
uploader,
type UploadGroupKey,
type UploaderFile
} from '$lib/stores/uploader';
import { Typography } from '@appwrite.io/pink-svelte';
type UploadBoxGroup = {
key: UploadGroupKey;
title: string;
files: UploaderFile[];
isOpen: boolean;
};
const groupTitles: Record<UploadGroupKey, string> = {
storage: 'File Uploads',
deployments: 'Deployment Uploads'
};
const groups = $derived.by<UploadBoxGroup[]>(() => {
return (Object.keys(groupTitles) as UploadGroupKey[])
.map((groupKey) => {
const files = $uploader.files.filter(
(file) => getUploadGroupKey(file.kind) === groupKey
);
return {
key: groupKey,
title: groupTitles[groupKey],
files,
isOpen: $uploader.groups[groupKey].isOpen
};
})
.filter((group) => group.files.length && $uploader.groups[group.key].isVisible);
});
function statusIcon(status: UploaderFile['status']) {
if (status === 'success') return 'icon-check';
if (status === 'failed') return 'icon-warning';
return 'icon-clock';
}
function statusClass(status: UploaderFile['status']) {
if (status === 'success') return 'is-success';
if (status === 'failed') return 'is-danger';
return '';
}
</script>
{#if $uploader?.isOpen}
<Upload.Box
files={$uploader.files.map((file) => {
return {
name: file.name,
size: file.size,
status: file.status,
progress: file.progress
};
})}
on:close={() => uploader.close()} />
{#if $uploader.isOpen}
<div class="box-holder u-flex u-flex-vertical u-gap-16" style="align-items: end">
{#each groups as group (group.key)}
<section class="upload-box">
<header class="upload-box-header">
<h4 class="upload-box-title">
<Typography.Text variant="m-500">
{group.title} ({group.files.length})
</Typography.Text>
</h4>
<button
class="upload-box-button"
class:is-open={group.isOpen}
aria-label={`toggle ${group.title.toLowerCase()}`}
onclick={() => uploader.toggleGroup(group.key)}>
<span class="icon-cheveron-up" aria-hidden="true"></span>
</button>
<button
class="upload-box-button"
aria-label={`close ${group.title.toLowerCase()}`}
onclick={() => uploader.hideGroup(group.key)}>
<span class="icon-x" aria-hidden="true"></span>
</button>
</header>
<div class="upload-box-content" class:is-open={group.isOpen}>
<ul class="upload-box-list">
{#each group.files as file (file.clientId)}
{@const readableSize = humanFileSize(file.size)}
<li class="upload-box-item">
<span class="icon-document" aria-hidden="true"></span>
<div class="file-name">
<Typography.Text>{file.name}</Typography.Text>
<Typography.Caption variant="400">
{readableSize.value + readableSize.unit}
</Typography.Caption>
</div>
<span
class={`upload-box-button ${statusClass(file.status)}`}
aria-hidden="true">
<span class={statusIcon(file.status)}></span>
</span>
</li>
{/each}
</ul>
</div>
</section>
{/each}
</div>
{/if}
<style lang="scss">
.upload-box-title {
font-size: 11px;
}
.upload-box-content {
min-width: 320px;
max-width: min(420px, calc(100vw - 2rem));
}
.upload-box-button {
display: flex;
align-items: center;
justify-content: center;
&.is-danger {
color: var(--fgcolor-error);
}
&.is-success {
color: var(--fgcolor-success);
}
}
.upload-box-item {
align-items: center;
}
.file-name {
display: flex;
min-width: 0;
flex: 1;
flex-direction: column;
gap: 0.25rem;
}
</style>
+4
View File
@@ -252,6 +252,10 @@ function generateSingleValue(field: Field): string | number | boolean | NestedNu
return faker.number.int({ min, max });
}
case 'bigint': {
return faker.number.bigInt().toString();
}
case 'double': {
const floatAttr = field as Models.ColumnFloat;
const min = isWithinSafeRange(floatAttr.min) ? floatAttr.min : 0;
+19
View File
@@ -80,6 +80,25 @@ export async function gzipUpload(files: FileList) {
return uploadFile;
}
export function getInvalidDeploymentArchiveReason(
files: FileList | File[] | null | undefined,
maxSize?: number
) {
if (!files) return null;
const normalizedFiles = Array.from(files);
if (!normalizedFiles.length) return null;
if (maxSize !== undefined && normalizedFiles.some((file) => file.size > maxSize)) {
return InvalidFileType.SIZE;
}
if (normalizedFiles.some((file) => !file.name.toLowerCase().endsWith('.tar.gz'))) {
return InvalidFileType.EXTENSION;
}
return null;
}
export function removeFile(file: File, files: FileList) {
const filteredFiles = Array.from(files).filter((f) => f.name !== file.name);
const dataTransfer = new DataTransfer();
+1
View File
@@ -32,6 +32,7 @@ const columnTypes = [
'text',
'mediumtext',
'longtext',
'bigint',
'integer',
'double',
'boolean',
+40 -19
View File
@@ -1,19 +1,47 @@
<script lang="ts">
import { BarChart, Legend, type LegendData } from '$lib/charts';
import { accumulateFromEndingTotal } from '$lib/layout/usage.svelte';
import { Card, SecondaryTabs, SecondaryTabsItem } from '$lib/components';
import { page } from '$app/state';
import { BarChart, Legend, type LegendData } from '$lib/charts';
import { Card, SecondaryTabs, SecondaryTabsItem } from '$lib/components';
import { clampMin, formatNumberWithCommas } from '$lib/helpers/numbers';
import { accumulateFromEndingTotal } from '$lib/layout/usage.svelte';
import { type Models } from '@appwrite.io/console';
import { formatNumberWithCommas, clampMin } from '$lib/helpers/numbers';
import { Layout, Typography } from '@appwrite.io/pink-svelte';
import type { EChartsOption } from 'echarts';
export let title: string;
export let total: number[];
export let path: string = null;
export let count: Models.Metric[][];
export let legendData: LegendData[];
export let showHeader: boolean = true;
export let legendNumberFormat: 'comma' | 'abbreviate' = 'comma';
type Props = {
title: string;
total: number[];
path?: string | null;
count: Models.Metric[][];
legendData: LegendData[];
showHeader?: boolean;
legendNumberFormat?: 'comma' | 'abbreviate';
isCumulative?: boolean;
options?: EChartsOption | null;
};
let {
title,
total,
path = null,
count,
legendData,
showHeader = true,
legendNumberFormat = 'comma',
isCumulative = true,
options = null
}: Props = $props();
const formatted = $derived(page.params.period === '24h' ? 'hours' : 'days');
const totalCount = $derived(clampMin(total.reduce((a, b) => a + b, 0)));
const series = $derived(
count.map((metrics, index) => ({
name: legendData[index].name,
data: isCumulative
? accumulateFromEndingTotal(metrics, total[index])
: metrics.map((metric) => [metric.date, metric.value])
}))
);
</script>
<div>
@@ -41,19 +69,12 @@
<Card>
{#if count}
{@const totalCount = clampMin(total.reduce((a, b) => a + b, 0))}
<Layout.Stack gap="xs">
<Typography.Title>{formatNumberWithCommas(totalCount)}</Typography.Title>
<Typography.Text>Total {title.toLocaleLowerCase()}</Typography.Text>
</Layout.Stack>
<div class="multiple-chart-container u-flex-vertical u-gap-16">
<BarChart
formatted={page.params.period === '24h' ? 'hours' : 'days'}
series={count.map((c, index) => ({
name: legendData[index].name,
data: accumulateFromEndingTotal(c, total[index])
}))} />
<BarChart {formatted} {options} {series} />
{#if legendData}
<Legend
+1 -1
View File
@@ -1,5 +1,5 @@
import { writable } from 'svelte/store';
import { type Models, MethodId } from '@appwrite.io/console';
import { type Models, AuthMethod as MethodId } from '@appwrite.io/console';
export type AuthMethod = {
label: string;
+13
View File
@@ -8,6 +8,7 @@ import MarkedForDeletion from '$lib/components/billing/alerts/markedForDeletion.
import MissingPaymentMethod from '$lib/components/billing/alerts/missingPaymentMethod.svelte';
import newDevUpgradePro from '$lib/components/billing/alerts/newDevUpgradePro.svelte';
import PaymentAuthRequired from '$lib/components/billing/alerts/paymentAuthRequired.svelte';
import PaymentProcessing from '$lib/components/billing/alerts/paymentProcessing.svelte';
import { NEW_DEV_PRO_UPGRADE_COUPON } from '$lib/constants';
import { cachedStore } from '$lib/helpers/cache';
@@ -57,6 +58,7 @@ export const roles = [
];
export const teamStatusReadonly = 'readonly';
export const teamStatusUpgrading = 'upgrading';
export const billingLimitOutstandingInvoice = 'outstanding_invoice';
export const paymentMethods = derived(
@@ -587,6 +589,17 @@ export function checkForMarkedForDeletion(org: Models.Organization) {
}
}
export function checkForUpgradingStatus(org: Models.Organization) {
if (org?.status === teamStatusUpgrading) {
headerAlert.add({
id: 'paymentProcessing',
component: PaymentProcessing,
show: true,
importance: 5
});
}
}
export async function checkForMissingPaymentMethod() {
const starterPlan = getBasePlanFromGroup(BillingPlanGroup.Starter);
if (!starterPlan?.$id) {
+11 -1
View File
@@ -47,6 +47,9 @@ const initialFormData = {
messaging: {
root: false,
messages: false
},
backups: {
root: false
}
};
@@ -84,7 +87,8 @@ export const ResourcesFriendly = {
provider: { singular: 'Provider', plural: 'Providers' },
topic: { singular: 'Topic', plural: 'Topics' },
subscriber: { singular: 'Subscriber', plural: 'Subscribers' },
message: { singular: 'Message', plural: 'Messages' }
message: { singular: 'Message', plural: 'Messages' },
'backup-policy': { singular: 'Backup Policy', plural: 'Backup Policies' }
};
export const providerResources: ProviderResourceMap = {
@@ -148,6 +152,9 @@ export const migrationFormToResources = <P extends Provider>(
if (formData.messaging.messages) {
addResource(MigrationResources.Message);
}
if (formData.backups.root) {
addResource(MigrationResources.Backuppolicy);
}
return resources as ProviderResourceMap[P];
};
@@ -224,6 +231,9 @@ export const resourcesToMigrationForm = (resources: MigrationResource[]): Migrat
if (resources.includes(MigrationResources.Message)) {
formData.messaging.messages = true;
}
if (resources.includes(MigrationResources.Backuppolicy)) {
formData.backups.root = true;
}
return formData;
};
+6
View File
@@ -1,3 +1,9 @@
import type { Models } from '@appwrite.io/console';
export type FrameworkAdapterWithStartCommand = Models.FrameworkAdapter & {
startCommand?: string;
};
export function getFrameworkIcon(framework: string) {
switch (true) {
case framework.toLocaleLowerCase().includes('sveltekit'):
+53 -8
View File
@@ -186,25 +186,61 @@ export async function setPaymentMethod(providerMethodId: string, name: string, s
}
}
export type ConfirmPaymentOutcome =
| { status: 'succeeded' | 'processing' | 'requires_action' }
| { status: 'error'; message: string };
export async function confirmPayment(config: {
clientSecret: string;
paymentMethodId: string;
orgId?: string;
route?: string;
}) {
const { clientSecret, paymentMethodId, orgId, route } = config;
redirectIfRequired?: boolean;
}): Promise<ConfirmPaymentOutcome | undefined> {
const { clientSecret, paymentMethodId, orgId, route, redirectIfRequired } = config;
try {
const resolvedUrl = resolve('/(console)/organization-[organization]/billing', {
organization: orgId
});
const url = window.location.origin + (route ? route : resolvedUrl);
const url =
window.location.origin +
(route ??
resolve('/(console)/organization-[organization]/billing', { organization: orgId }));
const paymentMethod = await sdk.forConsole.account.getPaymentMethod({ paymentMethodId });
if (redirectIfRequired) {
const { paymentIntent, error } = await get(stripe).confirmPayment({
clientSecret,
confirmParams: {
return_url: url,
payment_method: paymentMethod.providerMethodId
},
redirect: 'if_required'
});
if (error) {
addNotification({
title: 'Error',
message:
error.message ??
'There was an error processing your payment, try again later. If the problem persists, please contact support.',
type: 'error'
});
return { status: 'error', message: error.message ?? 'Payment confirmation failed' };
}
const status = paymentIntent?.status;
if (status === 'succeeded' || status === 'processing' || status === 'requires_action') {
return { status };
}
return {
status: 'error',
message: `Unexpected payment status: ${status ?? 'unknown'}`
};
}
const { error } = await get(stripe).confirmPayment({
clientSecret: clientSecret,
clientSecret,
confirmParams: {
return_url: url,
payment_method: paymentMethod.providerMethodId
@@ -215,12 +251,21 @@ export async function confirmPayment(config: {
throw error.message;
}
} catch (e) {
const underlying =
typeof e === 'string' ? e : ((e as { message?: string })?.message ?? null);
addNotification({
title: 'Error',
message:
underlying ??
'There was an error processing your payment, try again later. If the problem persists, please contact support.',
type: 'error'
});
if (redirectIfRequired) {
return {
status: 'error',
message: underlying ?? 'Payment confirmation failed'
};
}
}
}
+174 -109
View File
@@ -1,21 +1,39 @@
import { page } from '$app/state';
import { getApiEndpoint } from '$lib/stores/sdk';
import { Client, Functions, ID, type Models, Sites, Storage } from '@appwrite.io/console';
import { writable } from 'svelte/store';
import { getApiEndpoint } from '$lib/stores/sdk';
import { page } from '$app/state';
type UploaderFile = {
export type UploadKind = 'storage' | 'site-deployment' | 'function-deployment';
export type UploadGroupKey = 'storage' | 'deployments';
export type UploaderFile = {
$id: string;
clientId: string;
resourceId: string;
name: string;
progress: number;
size: number;
status: 'failed' | 'pending' | 'success';
kind: UploadKind;
error?: string;
};
export type UploadGroupState = {
isOpen: boolean;
isVisible: boolean;
};
type UploadGroups = Record<UploadGroupKey, UploadGroupState>;
export type Uploader = {
isOpen: boolean;
isCollapsed: boolean;
files: UploaderFile[];
groups: UploadGroups;
};
type UploadProgress = {
$id: string;
progress: number;
};
const temporaryStorage = (region: string, projectId: string) => {
@@ -41,22 +59,76 @@ const temporaryFunctions = (region: string, projectId: string) => {
const MAX_CONCURRENT_UPLOADS = 5;
const createInitialGroups = (): UploadGroups => ({
storage: {
isOpen: true,
isVisible: true
},
deployments: {
isOpen: true,
isVisible: true
}
});
export function getUploadGroupKey(kind: UploadKind): UploadGroupKey {
return kind === 'storage' ? 'storage' : 'deployments';
}
function hasFilesForGroup(files: UploaderFile[], groupKey: UploadGroupKey) {
return files.some((file) => getUploadGroupKey(file.kind) === groupKey);
}
function refreshUploaderState(state: Uploader) {
for (const groupKey of Object.keys(state.groups) as UploadGroupKey[]) {
if (!hasFilesForGroup(state.files, groupKey)) {
state.groups[groupKey] = {
...createInitialGroups()[groupKey]
};
}
}
state.isOpen = (Object.keys(state.groups) as UploadGroupKey[]).some(
(groupKey) => hasFilesForGroup(state.files, groupKey) && state.groups[groupKey].isVisible
);
return state;
}
const createUploader = () => {
const { subscribe, set, update } = writable<Uploader>({
isOpen: false,
isCollapsed: false,
files: []
files: [],
groups: createInitialGroups()
});
const updateFile = (id: string, file: Partial<UploaderFile>) => {
return update((n) => {
const index = n.files.findIndex((f) => f.$id === id);
n.files[index] = {
...n.files[index],
const updateFile = (clientId: string, file: Partial<UploaderFile>) => {
return update((state) => {
const index = state.files.findIndex((item) => item.clientId === clientId);
if (index === -1) {
return state;
}
state.files[index] = {
...state.files[index],
...file
};
return n;
return state;
});
};
const addFileToQueue = (file: UploaderFile) => {
update((state) => {
const groupKey = getUploadGroupKey(file.kind);
state.files.unshift(file);
state.groups[groupKey] = {
isOpen: true,
isVisible: true
};
return refreshUploaderState(state);
});
};
@@ -70,18 +142,17 @@ const createUploader = () => {
) => {
const newFile: UploaderFile = {
$id: id,
clientId: id,
resourceId: bucketId,
name: file.name,
size: file.size,
progress: 0,
status: 'pending'
status: 'pending',
kind: 'storage'
};
update((n) => {
n.isOpen = true;
n.isCollapsed = false;
n.files.unshift(newFile);
return n;
});
addFileToQueue(newFile);
try {
const uploadedFile = await temporaryStorage(region, projectId).createFile({
bucketId,
@@ -92,17 +163,17 @@ const createUploader = () => {
newFile.$id = progress.$id;
newFile.progress = progress.progress;
newFile.status = progress.progress === 100 ? 'success' : 'pending';
updateFile(progress.$id, newFile);
updateFile(newFile.clientId, newFile);
}
});
newFile.$id = uploadedFile.$id;
newFile.progress = 100;
newFile.status = 'success';
updateFile(newFile.$id, newFile);
updateFile(newFile.clientId, newFile);
} catch (e) {
newFile.status = 'failed';
newFile.error = e?.message ?? 'Upload failed';
updateFile(newFile.$id, newFile);
updateFile(newFile.clientId, newFile);
throw e;
}
};
@@ -139,25 +210,52 @@ const createUploader = () => {
return results;
};
const uploadDeployment = async (
kind: Extract<UploadKind, 'site-deployment' | 'function-deployment'>,
resourceId: string,
name: string,
size: number,
request: (onProgress: (progress: UploadProgress) => void) => Promise<Models.Deployment>
) => {
const newDeployment: UploaderFile = {
$id: '',
clientId: ID.unique(),
resourceId,
name,
size,
progress: 0,
status: 'pending',
kind
};
addFileToQueue(newDeployment);
try {
const uploadedFile = await request((progress) => {
newDeployment.$id = progress.$id;
newDeployment.progress = progress.progress;
newDeployment.status = progress.progress === 100 ? 'success' : 'pending';
updateFile(newDeployment.clientId, newDeployment);
});
newDeployment.$id = uploadedFile.$id;
newDeployment.progress = 100;
newDeployment.status = 'success';
updateFile(newDeployment.clientId, newDeployment);
} catch (e) {
newDeployment.status = 'failed';
newDeployment.error = e?.message ?? 'Upload failed';
updateFile(newDeployment.clientId, newDeployment);
throw e;
}
};
return {
subscribe,
close: () =>
update((n) => {
n.isOpen = !n.isOpen;
return n;
}),
toggle: () =>
update((n) => {
n.isCollapsed = !n.isCollapsed;
return n;
}),
reset: () =>
set({
isOpen: false,
isCollapsed: false,
files: []
files: [],
groups: createInitialGroups()
}),
uploadFile,
uploadFiles,
@@ -174,41 +272,17 @@ const createUploader = () => {
installCommand?: string;
outputDirectory?: string;
}) => {
const newDeployment: UploaderFile = {
$id: '',
resourceId: siteId,
name: code.name,
size: code.size,
progress: 0,
status: 'pending'
};
update((n) => {
n.isOpen = true;
n.isCollapsed = false;
n.files.unshift(newDeployment);
return n;
});
const uploadedFile = await temporarySites(
page.params.region,
page.params.project
).createDeployment({
siteId,
code,
activate: true,
buildCommand,
installCommand,
outputDirectory,
onProgress: (progress) => {
newDeployment.$id = progress.$id;
newDeployment.progress = progress.progress;
newDeployment.status = progress.progress === 100 ? 'success' : 'pending';
updateFile(progress.$id, newDeployment);
}
});
newDeployment.$id = uploadedFile.$id;
newDeployment.progress = 100;
newDeployment.status = 'success';
updateFile(newDeployment.$id, newDeployment);
return uploadDeployment('site-deployment', siteId, code.name, code.size, (onProgress) =>
temporarySites(page.params.region, page.params.project).createDeployment({
siteId,
code,
activate: true,
buildCommand,
installCommand,
onProgress,
outputDirectory
})
);
},
uploadFunctionDeployment: async ({
functionId,
@@ -217,52 +291,43 @@ const createUploader = () => {
functionId: string;
code: File;
}) => {
const newDeployment: UploaderFile = {
$id: '',
resourceId: functionId,
name: code.name,
size: code.size,
progress: 0,
status: 'pending'
};
update((n) => {
n.isOpen = true;
n.isCollapsed = false;
n.files.unshift(newDeployment);
return n;
});
const uploadedFile = await temporaryFunctions(
page.params.region,
page.params.project
).createDeployment({
return uploadDeployment(
'function-deployment',
functionId,
code,
activate: true,
onProgress: (progress) => {
newDeployment.$id = progress.$id;
newDeployment.progress = progress.progress;
newDeployment.status = progress.progress === 100 ? 'success' : 'pending';
updateFile(progress.$id, newDeployment);
}
code.name,
code.size,
(onProgress) =>
temporaryFunctions(page.params.region, page.params.project).createDeployment({
functionId,
code,
activate: true,
onProgress
})
);
},
toggleGroup: (groupKey: UploadGroupKey) => {
update((state) => {
state.groups[groupKey].isOpen = !state.groups[groupKey].isOpen;
return refreshUploaderState(state);
});
},
hideGroup: (groupKey: UploadGroupKey) => {
update((state) => {
state.groups[groupKey].isVisible = false;
return refreshUploaderState(state);
});
newDeployment.$id = uploadedFile.$id;
newDeployment.progress = 100;
newDeployment.status = 'success';
updateFile(newDeployment.$id, newDeployment);
},
removeFromQueue: (id: string) => {
update((n) => {
n.files = n.files.filter((f) => f.$id !== id);
n.isOpen = n.files.length !== 0;
return n;
update((state) => {
state.files = state.files.filter((file) => file.$id !== id && file.clientId !== id);
return refreshUploaderState(state);
});
},
removeFile: async (file: Models.File) => {
if (file.chunksTotal === file.chunksUploaded) {
return update((n) => {
n.files = n.files.filter((f) => f.$id !== file.$id);
return n;
return update((state) => {
state.files = state.files.filter((item) => item.$id !== file.$id);
return refreshUploaderState(state);
});
}
}
@@ -115,6 +115,10 @@
return resources.includes(MigrationResources.Provider);
}
if (groupKey === 'backups') {
return resources.includes(MigrationResources.Backuppolicy);
}
const groupToResource: Record<string, MigrationResource> = {
users: MigrationResources.User,
databases: MigrationResources.Database
@@ -135,7 +139,8 @@
functions: 'function',
storage: 'bucket',
sites: 'site',
messaging: 'provider'
messaging: 'provider',
backups: 'backup-policy'
};
return map[groupKey] || groupKey;
};
+2
View File
@@ -18,6 +18,7 @@
checkForMarkedForDeletion,
checkForMissingPaymentMethod,
checkForNewDevUpgradePro,
checkForUpgradingStatus,
checkForUsageLimit,
checkPaymentAuthorizationRequired,
paymentExpired,
@@ -295,6 +296,7 @@
checkForEnterpriseTrial(org);
await checkForUsageLimit(org);
checkForMarkedForDeletion(org);
checkForUpgradingStatus(org);
await checkForNewDevUpgradePro(org);
if (org?.billingPlanDetails.requiresPaymentMethod) {
@@ -11,7 +11,8 @@
import {
billingIdToPlan,
getBasePlanFromGroup,
isPaymentAuthenticationRequired
isPaymentAuthenticationRequired,
teamStatusUpgrading
} from '$lib/stores/billing';
import { addNotification } from '$lib/stores/notifications';
import { sdk } from '$lib/stores/sdk';
@@ -106,11 +107,21 @@
});
if (!isPaymentAuthenticationRequired(org)) {
await invalidate(Dependencies.ACCOUNT);
await preloadAndNavigate(org.$id);
addNotification({
type: 'success',
message: `${org.name ?? 'Organization'} has been created`
});
if (org.status === teamStatusUpgrading) {
addNotification({
type: 'info',
message:
'Payment is processing — your plan will activate within a few minutes.'
});
} else {
addNotification({
type: 'success',
message: `${org.name ?? 'Organization'} has been created`
});
}
}
} catch (e) {
addNotification({
@@ -144,8 +155,8 @@
});
if (isPaymentAuthenticationRequired(org)) {
let clientSecret = org.clientSecret;
let params = new URLSearchParams();
const clientSecret = org.clientSecret;
const params = new URLSearchParams();
params.append('type', 'payment_confirmed');
params.append('id', org.organizationId);
for (const [key, value] of page.url.searchParams.entries()) {
@@ -156,12 +167,29 @@
params.append('invites', collaborators.join(','));
const resolvedUrl = resolve('/(console)/create-organization');
await confirmPayment({
const outcome = await confirmPayment({
clientSecret,
paymentMethodId,
route: `${resolvedUrl}?${params}`
route: `${resolvedUrl}?${params}`,
redirectIfRequired: true
});
if (!outcome || outcome.status === 'error') {
try {
await sdk.forConsole.organizations.validatePayment({
organizationId: org.organizationId,
invites: []
});
} catch {
// expected: backend throws BILLING_PAYMENT_FAILED after deleting the draft team
}
return;
}
if (outcome.status === 'requires_action') {
return;
}
await validate(org.organizationId, collaborators);
}
}
@@ -12,7 +12,8 @@
import {
billingIdToPlan,
getBasePlanFromGroup,
isPaymentAuthenticationRequired
isPaymentAuthenticationRequired,
teamStatusUpgrading
} from '$lib/stores/billing';
import { addNotification } from '$lib/stores/notifications';
import { currentPlan, organization } from '$lib/stores/organization';
@@ -220,10 +221,19 @@
await invalidate(Dependencies.ORGANIZATION);
await goto(previousPage);
addNotification({
type: 'success',
message: 'Your organization has been upgraded'
});
if (org.status === teamStatusUpgrading) {
addNotification({
type: 'info',
message:
'Payment is processing — your plan will activate within a few minutes.'
});
} else {
addNotification({
type: 'success',
message: 'Your organization has been upgraded'
});
}
trackEvent(Submit.OrganizationUpgrade, {
plan: selectedPlan?.name
@@ -259,8 +269,8 @@
});
if (isPaymentAuthenticationRequired(org)) {
let clientSecret = org.clientSecret;
let params = new URLSearchParams();
const clientSecret = org.clientSecret;
const params = new URLSearchParams();
for (const [key, value] of page.url.searchParams.entries()) {
if (key !== 'type' && key !== 'id') {
params.append(key, value);
@@ -275,11 +285,29 @@
organization: org.organizationId
});
await confirmPayment({
const outcome = await confirmPayment({
clientSecret,
paymentMethodId,
route: `${resolvedUrl}?${params.toString()}`
route: `${resolvedUrl}?${params.toString()}`,
redirectIfRequired: true
});
if (!outcome || outcome.status === 'error') {
try {
await sdk.forConsole.organizations.validatePayment({
organizationId: org.organizationId,
invites: []
});
} catch {
// expected: backend throws BILLING_PAYMENT_FAILED and rolls back the upgrade
}
return;
}
if (outcome.status === 'requires_action') {
return;
}
await validate(org.organizationId, collaborators);
}
@@ -160,12 +160,48 @@
const settingsUrl = resolve('/(console)/organization-[organization]/settings', {
organization: $organization.$id
});
await confirmPayment({
const outcome = await confirmPayment({
clientSecret: paymentAuth.clientSecret,
paymentMethodId: $organization.paymentMethodId,
orgId: $organization.$id,
route: `${settingsUrl}?type=confirm-addon&addonId=${paymentAuth.addonId}`
route: `${settingsUrl}?type=confirm-addon&addonId=${paymentAuth.addonId}`,
redirectIfRequired: true
});
if (!outcome || outcome.status === 'error') {
trackError(
new Error(outcome?.status === 'error' ? outcome.message : 'Payment failed'),
Submit.BAAAddonEnable
);
return;
}
if (outcome.status === 'requires_action') {
return;
}
await sdk.forConsole.organizations.confirmAddonPayment({
organizationId: $organization.$id,
addonId: paymentAuth.addonId
});
await Promise.all([
invalidate(Dependencies.ADDONS),
invalidate(Dependencies.ORGANIZATION)
]);
if (outcome.status === 'processing') {
addNotification({
message: "BAA addon payment is processing — we'll activate it shortly.",
type: 'info'
});
} else {
addNotification({
message: 'BAA addon has been enabled',
type: 'success'
});
}
trackEvent(Submit.BAAAddonEnable);
return;
}
@@ -39,12 +39,49 @@
const settingsUrl = resolve('/(console)/organization-[organization]/settings', {
organization: $organization.$id
});
await confirmPayment({
const outcome = await confirmPayment({
clientSecret: paymentAuth.clientSecret,
paymentMethodId: $organization.paymentMethodId,
orgId: $organization.$id,
route: `${settingsUrl}?type=confirm-addon&addonId=${paymentAuth.addonId}`
route: `${settingsUrl}?type=confirm-addon&addonId=${paymentAuth.addonId}`,
redirectIfRequired: true
});
if (!outcome || outcome.status === 'error') {
if (outcome?.status === 'error') {
error = outcome.message;
trackError(new Error(outcome.message), Submit.BAAAddonEnable);
}
return;
}
if (outcome.status === 'requires_action') {
return;
}
await sdk.forConsole.organizations.confirmAddonPayment({
organizationId: $organization.$id,
addonId: paymentAuth.addonId
});
await Promise.all([
invalidate(Dependencies.ADDONS),
invalidate(Dependencies.ORGANIZATION)
]);
if (outcome.status === 'processing') {
addNotification({
message: "BAA addon payment is processing — we'll activate it shortly.",
type: 'info'
});
} else {
addNotification({
message: 'BAA addon has been enabled',
type: 'success'
});
}
trackEvent(Submit.BAAAddonEnable);
show = false;
return;
}
@@ -10,7 +10,7 @@
import { addNotification } from '$lib/stores/notifications';
import { oAuthProviders } from '$lib/stores/oauth-providers';
import { sdk } from '$lib/stores/sdk';
import { MethodId, type Models } from '@appwrite.io/console';
import { AuthMethod as MethodId, type Models } from '@appwrite.io/console';
import { base } from '$app/paths';
import {
Avatar,
@@ -218,8 +218,8 @@ async function updateProjectOAuth({
clientSecret: getSecret('clientSecret'),
wellKnownURL: getDetail('wellKnownURL'),
authorizationURL: getDetail('authorizationURL'),
tokenUrl: getDetail('tokenUrl'),
userInfoUrl: getDetail('userInfoUrl'),
tokenURL: getDetail('tokenUrl'),
userInfoURL: getDetail('userInfoUrl'),
enabled
});
case OAuthProvider.Okta:
@@ -15,6 +15,7 @@ export type Columns =
| Models.ColumnEmail
| Models.ColumnEnum
| Models.ColumnFloat
| Models.ColumnBigint
| Models.ColumnInteger
| Models.ColumnIp
| Models.ColumnString
@@ -65,7 +65,7 @@
import { hash } from '$lib/helpers/string';
import { preferences } from '$lib/stores/preferences';
import { buildFieldUrl } from '$database/(entity)/helpers/navigation';
import { isRelationship } from '$database/table-[table]/rows/store';
import { isRelationship, buildPayload } from '$database/table-[table]/rows/store';
import { chunks } from '$lib/helpers/array';
import { Submit, trackEvent } from '$lib/actions/analytics';
import {
@@ -357,7 +357,7 @@
databaseId: page.params.database,
tableId: page.params.table,
rowId: row.$id,
data: row
data: buildPayload(columns, row)
})
)
);
@@ -369,7 +369,7 @@
await tablesSDK.createRows({
databaseId: page.params.database,
tableId: page.params.table,
rows
rows: rows.map((row) => buildPayload(columns, row))
});
}
@@ -198,8 +198,15 @@
) {
const stringColumn = column as Models.ColumnString;
return { display: `Size: ${stringColumn.size}` };
} else if (column.type === 'integer' || column.type === 'double') {
const numbersColumn = column as Models.ColumnInteger | Models.ColumnFloat;
} else if (
column.type === 'bigint' ||
column.type === 'integer' ||
column.type === 'double'
) {
const numbersColumn = column as
| Models.ColumnBigint
| Models.ColumnInteger
| Models.ColumnFloat;
const { min, max } = numbersColumn;
const isMinBigInt = typeof min === 'bigint';
@@ -0,0 +1,160 @@
<script module lang="ts">
import { page } from '$app/state';
import type { Columns } from '$database/store';
import { sdk } from '$lib/stores/sdk';
import type { Models } from '@appwrite.io/console';
function normalizeBigInt(value, field: string) {
if (value === undefined) return undefined;
if (value === null) return null;
if (typeof value === 'number') {
if (!Number.isFinite(value) || Number.isNaN(value)) {
throw new Error(`${field} must be a finite integer`);
}
if (!Number.isInteger(value)) {
throw new Error(`${field} must be an integer`);
}
}
try {
return BigInt(value);
} catch {
throw new Error(`${field} must be a valid integer`);
}
}
export async function submitBigInt(
databaseId: string,
tableId: string,
key: string,
data: Partial<Columns>
) {
const bigintData = data as Partial<Models.ColumnBigint>;
await sdk.forProject(page.params.region, page.params.project).tablesDB.createBigIntColumn({
databaseId,
tableId,
key,
required: bigintData.required,
min: normalizeBigInt(bigintData.min, 'Min'),
max: normalizeBigInt(bigintData.max, 'Max'),
xdefault: normalizeBigInt(bigintData.default, 'Default value'),
array: bigintData.array
});
}
export async function updateBigInt(
databaseId: string,
tableId: string,
data: Partial<Columns>,
originalKey?: string
) {
const bigintData = data as Partial<Models.ColumnBigint>;
await sdk.forProject(page.params.region, page.params.project).tablesDB.updateBigIntColumn({
databaseId,
tableId,
key: originalKey,
required: bigintData.required,
xdefault: normalizeBigInt(bigintData.default, 'Default value'),
min: normalizeBigInt(bigintData.min, 'Min'),
max: normalizeBigInt(bigintData.max, 'Max'),
newKey: bigintData.key !== originalKey ? bigintData.key : undefined
});
}
</script>
<script lang="ts">
import { untrack } from 'svelte';
import { Layout } from '@appwrite.io/pink-svelte';
import { InputNumber } from '$lib/elements/forms';
import { createConservative } from '$lib/helpers/stores';
import RequiredArrayCheckboxes from './requiredArrayCheckboxes.svelte';
type Props = {
editing?: boolean;
disabled?: boolean;
data?: Partial<Models.ColumnBigint>;
};
let {
editing = false,
disabled = false,
data = $bindable({
required: false,
min: 0,
max: 0,
default: 0,
array: false
})
}: Props = $props();
let savedDefault = data.default;
function handleDefaultState(hideDefault: boolean) {
if (hideDefault) {
savedDefault = data.default;
data.default = null;
} else {
data.default = savedDefault;
}
}
const {
stores: { required, array },
listen
} = createConservative<Partial<Models.ColumnBigint>>({
required: false,
array: false,
...data
});
$effect(() => {
listen(data);
});
// untrack: handleDefaultState reads and writes data.default, which would make
// this effect depend on the state it writes and trigger an infinite update loop.
$effect(() => {
const hideDefault = $required || $array;
untrack(() => handleDefaultState(hideDefault));
});
</script>
<Layout.Stack direction="row" gap="s">
<InputNumber
id="min"
label="Min"
{disabled}
placeholder="Enter size"
step={1}
bind:value={data.min as number}
required={editing} />
<InputNumber
id="max"
label="Max"
{disabled}
placeholder="Enter size"
step={1}
bind:value={data.max as number}
required={editing} />
</Layout.Stack>
<InputNumber
id="default"
label="Default value"
placeholder="Enter value"
step={1}
min={data.min as number}
max={data.max as number}
bind:value={data.default as number}
disabled={data.required || data.array || disabled}
nullable={(!data.required && !data.array) || disabled} />
<RequiredArrayCheckboxes
{editing}
{disabled}
bind:array={data.array}
bind:required={data.required} />
@@ -4,6 +4,7 @@ import Boolean, { submitBoolean, updateBoolean } from './boolean.svelte';
import Email, { submitEmail, updateEmail } from './email.svelte';
import Enum, { submitEnum, updateEnum } from './enum.svelte';
import Float, { submitFloat, updateFloat } from './float.svelte';
import BigInt, { submitBigInt, updateBigInt } from './bigint.svelte';
import Integer, { submitInteger, updateInteger } from './integer.svelte';
import Ip, { submitIp, updateIp } from './ip.svelte';
import String, { submitString, updateString } from './string.svelte';
@@ -41,6 +42,7 @@ export type Option = {
| 'Mediumtext'
| 'Longtext'
| 'Varchar'
| 'BigInt'
| 'Integer'
| 'Float'
| 'Boolean'
@@ -62,6 +64,7 @@ export type Option = {
| 'mediumtext'
| 'longtext'
| 'varchar'
| 'bigint'
| 'integer'
| 'double'
| 'boolean'
@@ -125,6 +128,15 @@ export const columnOptions: Option[] = [
update: updateVarchar,
icon: IconText
},
{
name: 'BigInt',
sentenceName: 'bigint',
component: BigInt,
type: 'bigint',
create: submitBigInt,
update: updateBigInt,
icon: IconHashtag
},
{
name: 'Integer',
sentenceName: 'integer',
@@ -16,7 +16,16 @@
export let label: string;
export let array: boolean | undefined = undefined;
export let optionalText: string | undefined = undefined;
export let value: string | number | boolean | null | string[];
export let value:
| string
| number
| bigint
| boolean
| null
| string[]
| number[]
| bigint[]
| boolean[];
export let editing = false;
export let limited = false;
export let column:
@@ -24,6 +33,7 @@
| Models.ColumnEmail
| Models.ColumnEnum
| Models.ColumnFloat
| Models.ColumnBigint
| Models.ColumnInteger
| Models.ColumnIp
| Models.ColumnString
@@ -43,6 +53,7 @@
text: String,
mediumtext: String,
longtext: String,
bigint: Integer,
integer: Integer,
double: Integer,
boolean: Boolean,
@@ -24,6 +24,7 @@
| Models.ColumnText
| Models.ColumnMediumtext
| Models.ColumnLongtext
| Models.ColumnBigint
| Models.ColumnInteger
| Models.ColumnFloat
| Models.ColumnBoolean
@@ -51,6 +52,7 @@
if (!trimmed) return null;
switch (column.type) {
case 'bigint':
case 'integer': {
const int = parseInt(trimmed, 10);
return isNaN(int) ? null : int;
@@ -122,6 +124,7 @@
const getPlaceholder = () => {
if (!array) {
switch (column.type) {
case 'bigint':
case 'integer':
return 'Enter integer';
case 'double':
@@ -134,6 +137,7 @@
}
} else {
switch (column.type) {
case 'bigint':
case 'integer':
return 'Enter integers separated by commas';
case 'double':
@@ -14,7 +14,8 @@
import { invalidate } from '$app/navigation';
import { Dependencies } from '$lib/constants';
import { tick } from 'svelte';
import { isRelationship, isRelationshipToMany } from './store';
import { isRelationship, isRelationshipToMany, buildPayload } from './store';
import type { RowValue } from './store';
import { hash } from '$lib/helpers/string';
type CreateRow = {
@@ -70,7 +71,7 @@
function prepareRowPayload(createRowObject: CreateRow): object {
const { row, columns } = createRowObject;
const payload = structuredClone(row);
const payload = structuredClone(row) as Record<string, RowValue>;
for (const column of columns) {
if (isRelationship(column) && !isRelationshipToMany(column)) {
@@ -79,7 +80,13 @@
if (value && typeof value === 'object') {
if (Array.isArray(value)) {
payload[key] = value.map((item) => item?.$id).filter(Boolean);
payload[key] = value
.map((item) =>
item && typeof item === 'object' && '$id' in item
? (item.$id as string)
: null
)
.filter(Boolean);
} else {
payload[key] = (value as { $id: string })['$id'];
}
@@ -87,7 +94,7 @@
}
}
return payload;
return buildPayload(columns, payload);
}
async function create(): Promise<boolean> {
@@ -10,7 +10,7 @@
import { invalidate } from '$app/navigation';
import { PROHIBITED_ROW_KEYS } from '../store';
import ColumnItem from './columns/columnItem.svelte';
import { isRelationship, isRelationshipToMany, isSpatialType } from './store';
import { isRelationship, isRelationshipToMany, isSpatialType, buildPayload } from './store';
import { Layout, Skeleton } from '@appwrite.io/pink-svelte';
import { deepClone } from '$lib/helpers/object';
import { type Entity, toRelationalField } from '$database/(entity)';
@@ -138,11 +138,13 @@
if (!row || !work) return;
try {
const payload = buildPayload(table.fields, $work);
await sdk.forProject(page.params.region, page.params.project).tablesDB.updateRow({
databaseId: table.databaseId,
tableId: table.$id,
rowId: row.$id,
data: $work,
data: payload,
permissions: $work.$permissions
});
@@ -11,7 +11,7 @@
import { PROHIBITED_ROW_KEYS } from '../store';
import { type Columns, buildWildcardEntitiesQuery } from '$database/store';
import RelatedRowColumns from './relatedRowColumns.svelte';
import { isRelationship, isRelationshipToMany } from './store';
import { isRelationship, isRelationshipToMany, buildPayload } from './store';
import { Accordion, Layout, Skeleton } from '@appwrite.io/pink-svelte';
import { deepClone } from '$lib/helpers/object';
import { preferences } from '$lib/stores/preferences';
@@ -254,11 +254,12 @@
const work = workData.get(rowId);
const workValue = get(work);
const payload = buildPayload(relatedTable.fields, workValue);
await sdk.forProject(page.params.region, page.params.project).tablesDB.updateRow({
databaseId,
tableId: relatedTable.$id,
rowId: rowId,
data: workValue,
data: payload,
permissions: workValue.$permissions
});
@@ -272,13 +273,14 @@
if (!work) return;
const workValue = get(work);
const payload = buildPayload(relatedTable.fields, workValue);
return sdk
.forProject(page.params.region, page.params.project)
.tablesDB.updateRow({
databaseId,
tableId: relatedTable.$id,
rowId: row.$id,
data: workValue,
data: payload,
permissions: workValue.$permissions
});
});
@@ -3,6 +3,12 @@ import type { Column } from '$lib/helpers/types';
import { type Models } from '@appwrite.io/console';
import type { Attributes, Columns } from '../../store';
type RowPrimitive = string | number | bigint | boolean | null | undefined;
interface RowObject {
[key: string]: RowValue;
}
export type RowValue = RowPrimitive | RowValue[] | RowObject;
export function isRelationshipToMany(field: Field) {
if (!field) return false;
if (!isRelationship(field)) return false;
@@ -50,3 +56,35 @@ export function isSpatialType(
return spatialTypes.includes(field.type.toLowerCase());
}
function castBigIntValue(value: RowValue): RowValue {
if (value === null || value === undefined || value === '') {
return value;
}
return String(value);
}
export function buildPayload<T extends Record<string, RowValue>>(
fields: Field[] | undefined,
row: T
): T {
const payload = structuredClone(row) as Record<string, RowValue>;
for (const field of fields ?? []) {
if (field.type !== 'bigint') {
continue;
}
const value = payload[field.key];
if (field.array && Array.isArray(value)) {
payload[field.key] = value.map((item) => castBigIntValue(item));
continue;
}
payload[field.key] = castBigIntValue(value);
}
return payload as T;
}
@@ -15,6 +15,7 @@
import {
isRelationship,
isRelationshipToMany,
buildPayload,
isSpatialType,
isTextType
} from '$database/table-[table]/rows/store';
@@ -359,6 +360,7 @@
switch (type) {
case 'string':
return IconText;
case 'bigint':
case 'double':
case 'integer':
return IconHashtag;
@@ -683,11 +685,13 @@
async function updateRowContents(row: Models.Row) {
try {
const payload = buildPayload(table.fields, row);
await sdk.forProject(page.params.region, page.params.project).tablesDB.updateRow({
databaseId,
tableId: table.$id,
rowId: row.$id,
data: row,
data: payload,
permissions: row.$permissions
});
@@ -1,21 +1,38 @@
<script lang="ts">
import { base } from '$app/paths';
import { page } from '$app/state';
import { clampMin } from '$lib/helpers/numbers';
import { formatNum } from '$lib/helpers/string';
import { Container, UsageMultiple } from '$lib/layout';
import type { PageProps } from './$types';
export let data;
let { data }: PageProps = $props();
$: reads = data.databaseReads;
$: readsTotal = data.databaseReadsTotal;
const reads = $derived(data.databaseReads ?? []);
const readsTotal = $derived(clampMin(reads.reduce((sum, item) => sum + item.value, 0)));
$: writes = data.databaseWrites;
$: writesTotal = data.databaseWritesTotal;
const writes = $derived(data.databaseWrites ?? []);
const writesTotal = $derived(clampMin(writes.reduce((sum, item) => sum + item.value, 0)));
const usagePath = $derived(
`${base}/project-${page.params.region}-${page.params.project}/databases/database-${page.params.database}/usage`
);
</script>
<Container databasesMainScreen>
<UsageMultiple
title="Reads and writes"
showHeader={false}
path={usagePath}
total={[readsTotal, writesTotal]}
count={[reads, writes]}
isCumulative={false}
options={{
yAxis: {
axisLabel: {
formatter: formatNum
}
}
}}
legendNumberFormat="abbreviate"
legendData={[
{ name: 'Reads', value: readsTotal },
@@ -1,38 +1,65 @@
<script lang="ts">
import { goto } from '$app/navigation';
import { base } from '$app/paths';
import { page } from '$app/state';
import { Container, Usage, UsageMultiple } from '$lib/layout';
import { Container, UsageMultiple } from '$lib/layout';
import { InputSelect } from '$lib/elements/forms';
import { clampMin } from '$lib/helpers/numbers';
import { formatNum } from '$lib/helpers/string';
import { Layout } from '@appwrite.io/pink-svelte';
import type { PageData } from './$types';
import type { PageProps } from './$types';
export let data: PageData;
let { data }: PageProps = $props();
$: total = data.databasesTotal;
$: count = data.databases;
const reads = $derived(data.databasesReads ?? []);
const readsTotal = $derived(clampMin(reads.reduce((sum, item) => sum + item.value, 0)));
$: reads = data.databasesReads;
$: readsTotal = data.databasesReadsTotal;
const writes = $derived(data.databasesWrites ?? []);
const writesTotal = $derived(clampMin(writes.reduce((sum, item) => sum + item.value, 0)));
$: writes = data.databasesWrites;
$: writesTotal = data.databasesWritesTotal;
const usagePath = $derived(
`${base}/project-${page.params.region}-${page.params.project}/databases/usage`
);
</script>
<Container>
<Layout.Stack gap="l">
<Usage
path={`${base}/project-${page.params.region}-${page.params.project}/databases/usage`}
{total}
{count}
countMetadata={{
legend: 'Databases',
title: 'Total databases'
}} />
<div
style:max-width="250px"
style:--input-background-color="var(--bgcolor-neutral-primary)">
<InputSelect
on:change={(e) => goto(`${usagePath}/${e.detail}`)}
id="period"
options={[
{
label: '24 hours',
value: '24h'
},
{
label: '30 days',
value: '30d'
},
{
label: '90 days',
value: '90d'
}
]}
value={page.params.period ?? '30d'} />
</div>
<UsageMultiple
title="Reads and writes"
showHeader={false}
total={[readsTotal, writesTotal]}
count={[reads, writes]}
isCumulative={false}
options={{
yAxis: {
axisLabel: {
formatter: formatNum
}
}
}}
legendNumberFormat="abbreviate"
legendData={[
{ name: 'Reads', value: readsTotal },
@@ -121,6 +121,7 @@
const promises = variables.map((variable) =>
sdk.forProject(page.params.region, page.params.project).functions.createVariable({
functionId: func.$id,
variableId: ID.unique(),
key: variable.key,
value: variable.value,
secret: variable.secret
@@ -19,7 +19,11 @@
import Configuration from './configuration.svelte';
import { getIconFromRuntime } from '$lib/stores/runtimes';
import { regionalConsoleVariables } from '../../../store';
import { InvalidFileType, removeFile } from '$lib/helpers/files';
import {
getInvalidDeploymentArchiveReason,
InvalidFileType,
removeFile
} from '$lib/helpers/files';
import { isCloud } from '$lib/system';
import { humanFileSize } from '$lib/helpers/sizeConvertion';
import { currentPlan } from '$lib/stores/organization';
@@ -86,6 +90,7 @@
const promises = variables.map((variable) =>
sdk.forProject(page.params.region, page.params.project).functions.createVariable({
functionId: func.$id,
variableId: ID.unique(),
key: variable.key,
value: variable.value,
secret: variable?.secret ?? false
@@ -108,7 +113,9 @@
});
await promise;
const upload = $uploader.files.find((f) => f.resourceId === func.$id);
const upload = $uploader.files.find(
(f) => f.resourceId === func.$id && f.kind === 'function-deployment'
);
if (upload?.status === 'success') {
const deploymentId = upload.$id;
@@ -126,9 +133,11 @@
invalidate(Dependencies.FUNCTION);
} catch (e) {
const upload = $uploader.files.find((f) => f.resourceId === func?.$id);
const upload = $uploader.files.find(
(f) => f.resourceId === func?.$id && f.kind === 'function-deployment'
);
if (upload) {
uploader.removeFromQueue(upload.$id);
uploader.removeFromQueue(upload.clientId);
}
addNotification({
type: 'error',
@@ -148,7 +157,7 @@
} else if (reason === InvalidFileType.SIZE) {
addNotification({
type: 'error',
message: 'File size exceeds 10MB'
message: `File size exceeds ${readableMaxSize.value}${readableMaxSize.unit}`
});
} else {
addNotification({
@@ -158,6 +167,15 @@
}
}
$: if (files?.length) {
const reason = getInvalidDeploymentArchiveReason(files, maxSize);
if (reason) {
files = undefined;
handleInvalid(new CustomEvent('invalid', { detail: { reason } }));
}
}
$: filesList = files?.length
? Array.from(files).map((f) => {
return {
@@ -171,9 +189,9 @@
: [];
$: maxSize =
isCloud && $currentPlan
isCloud && $currentPlan?.deploymentSize
? $currentPlan.deploymentSize * 1000000
: $regionalConsoleVariables._APP_COMPUTE_SIZE_LIMIT; // already in MB
: $regionalConsoleVariables._APP_COMPUTE_SIZE_LIMIT;
$: readableMaxSize = humanFileSize(maxSize);
</script>
@@ -198,7 +216,7 @@
<Upload.Dropzone
bind:files
title="Upload function"
extensions={['gz', 'tar']}
extensions={['gz']}
{maxSize}
required
on:invalid={handleInvalid}>
@@ -132,6 +132,7 @@
const promises = variables.map((variable) =>
sdk.forProject(page.params.region, page.params.project).functions.createVariable({
functionId: func.$id,
variableId: ID.unique(),
key: variable.key,
value: variable.value,
secret: variable?.secret ?? false
@@ -190,6 +190,7 @@
.forProject(page.params.region, page.params.project)
.functions.createVariable({
functionId: func.$id,
variableId: ID.unique(),
key: variable.name,
value: variable.value,
secret: variable?.secret ?? false
@@ -4,7 +4,11 @@
import { Modal } from '$lib/components';
import { Dependencies } from '$lib/constants';
import { Button } from '$lib/elements/forms';
import { InvalidFileType, removeFile } from '$lib/helpers/files';
import {
getInvalidDeploymentArchiveReason,
InvalidFileType,
removeFile
} from '$lib/helpers/files';
import { addNotification } from '$lib/stores/notifications';
import { IconInfo } from '@appwrite.io/pink-icons-svelte';
import { Icon, Layout, Tooltip, Typography, Upload } from '@appwrite.io/pink-svelte';
@@ -23,7 +27,7 @@
$: maxSize =
isCloud && $currentPlan?.deploymentSize
? $currentPlan.deploymentSize * 1000000
: $consoleVariables._APP_COMPUTE_SIZE_LIMIT; // already in MB
: $consoleVariables._APP_COMPUTE_SIZE_LIMIT;
$: readableMaxSize = humanFileSize(maxSize);
@@ -54,12 +58,21 @@
if (reason === InvalidFileType.EXTENSION) {
error = 'Only .tar.gz files allowed';
} else if (reason === InvalidFileType.SIZE) {
error = 'File size exceeds 10MB';
error = `File size exceeds ${readableMaxSize.value}${readableMaxSize.unit}`;
} else {
error = 'Invalid file';
}
}
$: if (files?.length) {
const reason = getInvalidDeploymentArchiveReason(files, maxSize);
if (reason) {
files = undefined;
handleInvalid(new CustomEvent('invalid', { detail: { reason } }));
}
}
$: filesList = files?.length
? Array.from(files).map((f) => {
return {
@@ -80,7 +93,7 @@
Upload a tar.gz file containing your function source code
</Typography.Text>
<Upload.Dropzone
extensions={['gz', 'tar']}
extensions={['gz']}
bind:files
{maxSize}
required
@@ -30,9 +30,9 @@ export const load: PageLoad = async ({ depends, params, url, route, parent }) =>
Query.offset(offset),
Query.orderDesc(''),
Query.orderDesc('$updatedAt'),
...(search ? [Query.search('domain', search)] : []),
...parsedQueries.values()
],
search: search || undefined
]
});
const organizationDomains = await fetchOrganizationDomainsForRules(
@@ -25,6 +25,7 @@
import { isCloud } from '$lib/system';
import { getApexDomain } from '$lib/helpers/tlds';
import { resolveRoute } from '$lib/stores/navigation';
import { isProxyRuleVerified } from '$lib/components/domains/status';
let { data } = $props();
@@ -108,7 +109,7 @@
await invalidate(Dependencies.FUNCTION_DOMAINS);
const verified = rule?.status !== 'created';
const verified = isProxyRuleVerified(rule?.status);
if (verified) {
addNotification({
type: 'success',
@@ -73,7 +73,7 @@
try {
proxyRule = await sdk
.forProject(page.params.region, page.params.project)
.proxy.updateRuleVerification({ ruleId });
.proxy.updateRuleStatus({ ruleId });
await Promise.all([
invalidate(Dependencies.DOMAINS),
@@ -68,7 +68,7 @@
try {
selectedProxyRule = await sdk
.forProject(page.params.region, page.params.project)
.proxy.updateRuleVerification({ ruleId: selectedProxyRule.$id });
.proxy.updateRuleStatus({ ruleId: selectedProxyRule.$id });
await invalidate(Dependencies.FUNCTION_DOMAINS);
show = false;
@@ -24,6 +24,13 @@
import { columns } from './store';
import { regionalProtocol } from '$routes/(console)/project-[region]-[project]/store';
import DnsRecordsAction from '$lib/components/domains/dnsRecordsAction.svelte';
import {
getProxyRuleStatusBadge,
getProxyRuleUpdatedPrefix,
isProxyRuleLogsViewable,
isProxyRuleRetryable,
isProxyRuleVerified
} from '$lib/components/domains/status';
import ViewLogsModal from '$lib/components/domains/viewLogsModal.svelte';
import { timeFromNowShort } from '$lib/helpers/date';
@@ -49,7 +56,7 @@
};
function updatedLabel(proxyRule: Models.ProxyRule): string {
if (proxyRule.status === 'verified') {
if (isProxyRuleVerified(proxyRule.status)) {
return '';
}
@@ -58,14 +65,7 @@
return '';
}
const prefix =
proxyRule.status === 'created'
? 'Checked'
: proxyRule.status === 'verifying'
? 'Updated'
: proxyRule.status === 'unverified'
? 'Failed'
: '';
const prefix = getProxyRuleUpdatedPrefix(proxyRule.status);
return prefix + ' ' + timeStr;
}
@@ -81,10 +81,9 @@
<Table.Header.Cell column="actions" {root} />
</svelte:fragment>
{#each proxyRules.rules as proxyRule (proxyRule.$id)}
{@const isRetryable = proxyRule.status === 'created' || proxyRule.status === 'unverified'}
{@const isLogsViewable =
proxyRule.logs?.length > 0 &&
(proxyRule.status === 'verifying' || proxyRule.status === 'unverified')}
{@const isRetryable = isProxyRuleRetryable(proxyRule.status)}
{@const isLogsViewable = isProxyRuleLogsViewable(proxyRule)}
{@const statusBadge = getProxyRuleStatusBadge(proxyRule.status)}
<Table.Row.Base {root}>
{#each $columns as column}
<Table.Cell column={column.id} {root}>
@@ -99,17 +98,11 @@
</Typography.Text>
</Link>
<Layout.Stack direction="row" gap="s" alignItems="center">
{#if proxyRule.status !== 'verified'}
{#if statusBadge}
<Badge
variant="secondary"
type={proxyRule.status === 'verifying'
? undefined
: 'error'}
content={proxyRule.status === 'created'
? 'Verification failed'
: proxyRule.status === 'verifying'
? 'Generating certificate'
: 'Certificate generation failed'}
type={statusBadge.type}
content={statusBadge.content}
size="xs" />
{/if}
{#if isRetryable}
@@ -140,7 +133,7 @@
</Layout.Stack>
{:else if column.id === 'target'}
{proxyTarget(proxyRule)}
{:else if column.id === 'updated' && proxyRule.status !== 'verified'}
{:else if column.id === 'updated' && !isProxyRuleVerified(proxyRule.status)}
<Layout.Stack direction="row" justifyContent="flex-end">
<Typography.Text
variant="m-400"
@@ -211,7 +211,7 @@
<Layout.Stack gap="xs">
{#if headers}
{#each headers as [name, value], index}
{#each headers as _, index (index)}
<Layout.Stack direction="row" alignItems="flex-end">
<Input.ComboBox
fullWidth
@@ -221,14 +221,14 @@
hideEmpty
options={filteredKeyList}
id={`key-${index}`}
bind:value={name}
bind:search={name}>
bind:value={headers[index][0]}
bind:search={headers[index][0]}>
</Input.ComboBox>
<InputText
label={index === 0 ? 'Value' : ''}
placeholder="Enter value"
id={`value-${index}`}
bind:value>
bind:value={headers[index][1]}>
<span slot="info">
<Tooltip>
<Layout.Stack alignItems="center">
@@ -248,7 +248,9 @@
<Button
text
icon
disabled={(!name || !value) && index === 0}
disabled={(!headers[index][0] ||
!headers[index][1]) &&
index === 0}
on:click={() => {
if (index === 0) {
headers = [['', '']];
@@ -31,7 +31,7 @@
{
href: `${path}/usage`,
title: 'Usage',
event: 'sage',
event: 'usage',
hasChildren: true
},
{
@@ -24,6 +24,7 @@
import UpdateVariables from '$routes/(console)/project-[region]-[project]/updateVariables.svelte';
import { page } from '$app/state';
import { Link } from '$lib/elements';
import { ID } from '@appwrite.io/console';
export let data;
let showAlert = true;
@@ -31,6 +32,7 @@
const sdkCreateVariable = async (key: string, value: string, secret?: boolean) => {
await sdk.forProject(page.params.region, page.params.project).functions.createVariable({
functionId: data.function.$id,
variableId: ID.unique(),
key,
value,
secret
@@ -1,36 +1,46 @@
<script lang="ts">
import { Container, Usage } from '$lib/layout';
import { page } from '$app/state';
import { base } from '$app/paths';
import { page } from '$app/state';
import { clampMin } from '$lib/helpers/numbers';
import { Container, Usage } from '$lib/layout';
import { Layout } from '@appwrite.io/pink-svelte';
import type { PageProps } from './$types';
export let data;
$: total = data.executionsTotal;
$: count = data.executions;
$: gbHoursTotal = data.executionsMbSecondsTotal / 1000 / 3600;
$: mbSecondsCount = data.executionsMbSeconds;
$: gbHoursCount = data.executionsMbSeconds
?.map((metric) => ({
...metric,
value: metric.value / 1000 / 3600
}))
.filter(({ value }) => value);
let { data }: PageProps = $props();
const count = $derived(data.executions ?? []);
const total = $derived(clampMin(count.reduce((sum, metric) => sum + metric.value, 0)));
// Function compute time is returned as MB-seconds and displayed as GB-hours.
const executionsTime = $derived(data.executionsTime ?? []);
const gbHoursCount = $derived(
executionsTime
.map((metric) => ({
...metric,
value: metric.value / 1000 / 3600
}))
.filter(({ value }) => value)
);
const gbHoursTotal = $derived(
clampMin(gbHoursCount.reduce((sum, metric) => sum + metric.value, 0))
);
</script>
<Container>
<Layout.Stack gap="l">
{#if count}
{#if count.length}
<Usage
path={`${base}/project-${page.params.region}-${page.params.project}/functions/function-${page.params.function}/usage`}
countMetadata={{
legend: 'Executions',
title: 'Total executions'
}}
isCumulative
{total}
{count} />
{/if}
{#if mbSecondsCount}
{#if executionsTime.length}
<Usage
hidePeriodSelect
path={`${base}/project-${page.params.region}-${page.params.project}/functions/function-${page.params.function}/usage`}
@@ -38,6 +48,7 @@
legend: 'GB hours',
title: 'Total GB hours'
}}
isCumulative
total={gbHoursTotal}
count={gbHoursCount} />
{/if}
@@ -19,11 +19,6 @@
href: `${path}/templates`,
title: 'Templates',
event: 'templates'
},
{
href: `${path}/usage`,
title: 'Usage',
event: 'usage'
}
];
</script>
@@ -1,20 +1,5 @@
<script lang="ts">
import { base } from '$app/paths';
import { page } from '$app/state';
import { Container, Usage } from '$lib/layout';
export let data;
$: total = data.deploymentsTotal;
$: count = data.deployments;
import { Container } from '$lib/layout';
</script>
<Container>
<Usage
path={`${base}/project-${page.params.region}-${page.params.project}/functions/usage`}
countMetadata={{
legend: 'Functions',
title: 'Total functions'
}}
{total}
{count} />
</Container>
<Container></Container>
@@ -1,16 +1,3 @@
import { isValueOfStringEnum } from '$lib/helpers/types';
import { sdk } from '$lib/stores/sdk';
import { UsageRange } from '@appwrite.io/console';
import type { PageLoad } from './$types';
export const load: PageLoad = async ({ params }) => {
const period = isValueOfStringEnum(UsageRange, params.period)
? params.period
: UsageRange.ThirtyDays;
return {
...(await sdk
.forProject(params.region, params.project)
.functions.listUsage({ range: period }))
};
};
export const load: PageLoad = async () => ({});
@@ -142,23 +142,24 @@
routing.
</Typography.Text>
<Layout.Stack gap="s">
{#each $data as [key, value], index}
{#each $data as _, index (index)}
<Layout.Stack direction="row" alignItems="flex-end">
<InputText
id={`key-${index}`}
bind:value={key}
bind:value={$data[index][0]}
placeholder="Enter key"
label={index === 0 ? 'Key' : undefined} />
<Layout.Stack direction="row" alignItems="flex-end" gap="xs">
<InputText
id={`value-${index}`}
bind:value
bind:value={$data[index][1]}
placeholder="Enter value"
label={index === 0 ? 'Value' : undefined} />
<Button
icon
compact
disabled={(!key || !value) && index === 0}
disabled={(!$data[index][0] || !$data[index][1]) &&
index === 0}
on:click={() => {
if (index === 0 && $data?.length === 1) {
$data = [['', '']];
@@ -112,23 +112,24 @@
label="Media"
optionalText="(Optional)" />
<Layout.Stack gap="s">
{#each customData || [] as [key, value], index}
{#each customData || [] as _, index (index)}
<Layout.Stack direction="row" alignItems="flex-end">
<InputText
id={`key-${index}`}
bind:value={key}
bind:value={customData[index][0]}
placeholder="Enter key"
label={index === 0 ? 'Key' : undefined} />
<Layout.Stack direction="row" alignItems="flex-end" gap="xs">
<InputText
id={`value-${index}`}
bind:value
bind:value={customData[index][1]}
placeholder="Enter value"
label={index === 0 ? 'Value' : undefined} />
<Button
icon
compact
disabled={(!key || !value) && index === 0}
disabled={(!customData[index][0] || !customData[index][1]) &&
index === 0}
on:click={() => {
if (customData.length === 1) {
customData = [['', '']];
@@ -186,7 +186,7 @@
const { detail } = event;
if (detail === 'indeterminate') return;
filteredScopes.forEach((s) => {
if (s.category === category && !s.deprecated) {
if (s.category === category) {
activeScopes[s.scope] = detail;
}
});
@@ -217,7 +217,7 @@
{@const checked = categoryState(category, scopes)}
{@const isLastItem = index === categories.length - 1}
{@const scopesLength = filteredScopes.filter(
(n) => n.category === category && effectiveScopes.includes(n.scope)
(n) => n.category === category && activeScopes[n.scope]
).length}
<Accordion
selectable
@@ -1,13 +1,14 @@
<script lang="ts">
import { Button } from '$lib/elements/forms';
import { sdk } from '$lib/stores/sdk';
import { isSmallViewport } from '$lib/stores/viewport';
import { goto, invalidate } from '$app/navigation';
import { resolve } from '$app/paths';
import { Dependencies } from '$lib/constants';
import { addNotification } from '$lib/stores/notifications';
import { Submit, trackError } from '$lib/actions/analytics';
import { generateFingerprintToken } from '$lib/helpers/fingerprint';
import { Alert, Layout, Modal, Typography } from '@appwrite.io/pink-svelte';
import { Alert, Layout, Link, Modal, Typography } from '@appwrite.io/pink-svelte';
import { Status } from '@appwrite.io/console';
let {
@@ -73,14 +74,26 @@
})
);
}
const upgradeHref = $derived(
resolve('/(console)/organization-[organization]/change-plan', {
organization: teamId
})
);
</script>
<Modal title="Project paused" bind:open={show} size="m" dismissible={false}>
<Layout.Stack gap="m">
<Typography.Text>This project has been paused due to inactivity.</Typography.Text>
<Typography.Text>
Your data is safe and will remain intact. Upgrade your plan to keep your projects
active, or restore the project to continue using it.
Your data is safe and will remain intact.
{#if $isSmallViewport}
<Link.Anchor href={upgradeHref}>Upgrade your plan</Link.Anchor> to keep your projects
active, or restore the project to continue using it.
{:else}
Upgrade your plan to keep your projects active, or restore the project to continue
using it.
{/if}
</Typography.Text>
{#if error}
@@ -91,20 +104,35 @@
</Layout.Stack>
<svelte:fragment slot="footer">
<Layout.Stack direction="row" justifyContent="space-between">
<Button text disabled={loading} on:click={handleBackToOrganization}>
Back to organization
</Button>
<Layout.Stack direction="row" justifyContent="flex-end">
<Button secondary disabled={loading} on:click={handleResume}>
{#if $isSmallViewport}
<Layout.Stack gap="xs">
<Button disabled={loading} fullWidth on:click={handleResume}>
{#if loading}
Restoring...
{:else}
Restore project
{/if}
</Button>
<Button disabled={loading} on:click={handleUpgrade}>Upgrade</Button>
<Button text disabled={loading} fullWidth on:click={handleBackToOrganization}>
Go to organization
</Button>
</Layout.Stack>
</Layout.Stack>
{:else}
<Layout.Stack direction="row" justifyContent="space-between">
<Button text disabled={loading} on:click={handleBackToOrganization}>
Back to organization
</Button>
<Layout.Stack direction="row" justifyContent="flex-end">
<Button secondary disabled={loading} on:click={handleResume}>
{#if loading}
Restoring...
{:else}
Restore project
{/if}
</Button>
<Button disabled={loading} on:click={handleUpgrade}>Upgrade</Button>
</Layout.Stack>
</Layout.Stack>
{/if}
</svelte:fragment>
</Modal>
@@ -24,9 +24,9 @@ export const load: PageLoad = async ({ depends, url, route, params, parent }) =>
queries: [
Query.equal('type', RuleType.API),
Query.equal('trigger', RuleTrigger.MANUAL),
...(search ? [Query.search('domain', search)] : []),
Query.orderDesc('$updatedAt')
],
search: search || undefined
]
});
const organizationDomains = await fetchOrganizationDomainsForRules(rules, organization.$id);
@@ -13,6 +13,7 @@
import { project } from '$routes/(console)/project-[region]-[project]/store';
import { getApexDomain } from '$lib/helpers/tlds';
import type { Models } from '@appwrite.io/console';
import { isProxyRuleVerified } from '$lib/components/domains/status';
const routeBase = `${base}/project-${page.params.region}-${page.params.project}/settings/domains`;
@@ -58,7 +59,7 @@
await invalidate(Dependencies.DOMAINS);
const verified = rule?.status !== 'created';
const verified = isProxyRuleVerified(rule?.status);
if (verified) {
addNotification({
type: 'success',
@@ -72,7 +72,7 @@
try {
proxyRule = await sdk
.forProject(page.params.region, page.params.project)
.proxy.updateRuleVerification({ ruleId });
.proxy.updateRuleStatus({ ruleId });
await invalidate(Dependencies.DOMAINS);
await goto(routeBase);
@@ -68,7 +68,7 @@
try {
selectedProxyRule = await sdk
.forProject(page.params.region, page.params.project)
.proxy.updateRuleVerification({ ruleId: selectedProxyRule.$id });
.proxy.updateRuleStatus({ ruleId: selectedProxyRule.$id });
await invalidate(Dependencies.DOMAINS);
show = false;
@@ -23,6 +23,13 @@
import RetryDomainModal from './retryDomainModal.svelte';
import { regionalProtocol } from '../../store';
import DnsRecordsAction from '$lib/components/domains/dnsRecordsAction.svelte';
import {
getProxyRuleStatusBadge,
getProxyRuleUpdatedPrefix,
isProxyRuleLogsViewable,
isProxyRuleRetryable,
isProxyRuleVerified
} from '$lib/components/domains/status';
import ViewLogsModal from '$lib/components/domains/viewLogsModal.svelte';
import { timeFromNowShort } from '$lib/helpers/date';
@@ -56,7 +63,7 @@
];
function updatedLabel(proxyRule: Models.ProxyRule): string {
if (proxyRule.status === 'verified') {
if (isProxyRuleVerified(proxyRule.status)) {
return '';
}
@@ -65,14 +72,7 @@
return '';
}
const prefix =
proxyRule.status === 'created'
? 'Checked'
: proxyRule.status === 'verifying'
? 'Updated'
: proxyRule.status === 'unverified'
? 'Failed'
: '';
const prefix = getProxyRuleUpdatedPrefix(proxyRule.status);
return prefix + ' ' + timeStr;
}
@@ -88,10 +88,9 @@
<Table.Header.Cell column="actions" {root} />
</svelte:fragment>
{#each domains.rules as proxyRule (proxyRule.$id)}
{@const isRetryable = proxyRule.status === 'created' || proxyRule.status === 'unverified'}
{@const isLogsViewable =
proxyRule.logs?.length > 0 &&
(proxyRule.status === 'verifying' || proxyRule.status === 'unverified')}
{@const isRetryable = isProxyRuleRetryable(proxyRule.status)}
{@const isLogsViewable = isProxyRuleLogsViewable(proxyRule)}
{@const statusBadge = getProxyRuleStatusBadge(proxyRule.status)}
<Table.Row.Base {root}>
{#each columns as column}
<Table.Cell column={column.id} {root}>
@@ -106,17 +105,11 @@
</Typography.Text>
</Link>
<Layout.Stack direction="row" gap="s" alignItems="center">
{#if proxyRule.status !== 'verified'}
{#if statusBadge}
<Badge
variant="secondary"
type={proxyRule.status === 'verifying'
? undefined
: 'error'}
content={proxyRule.status === 'created'
? 'Verification failed'
: proxyRule.status === 'verifying'
? 'Generating certificate'
: 'Certificate generation failed'}
type={statusBadge.type}
content={statusBadge.content}
size="xs" />
{/if}
{#if isRetryable}
@@ -145,7 +138,7 @@
{/if}
</Layout.Stack>
</Layout.Stack>
{:else if column.id === 'updated' && proxyRule.status !== 'verified'}
{:else if column.id === 'updated' && !isProxyRuleVerified(proxyRule.status)}
<Layout.Stack direction="row" justifyContent="flex-end">
<Typography.Text
variant="m-400"
@@ -33,6 +33,9 @@
messaging: {
root: 'Messaging',
messages: 'Include messages'
},
backups: {
root: 'Backup policies'
}
};
@@ -56,6 +59,9 @@
messaging: {
root: 'Import all messaging providers, topics and subscribers',
messages: 'Import all messages'
},
backups: {
root: 'Import all backup policies'
}
};
@@ -162,7 +162,9 @@
</Button>
</Layout.Stack>
</div>
<Divider />
<div class="protocol-toolbar-divider">
<Divider />
</div>
<div class="protocol-list-content">
<Layout.Stack gap="xs">
{#each $protocols.list as protocol, index}
@@ -218,6 +220,11 @@
width: 100%;
}
.protocol-list-content {
max-width: 36rem;
padding-top: var(--space-6);
}
.protocol-toolbar {
display: flex;
justify-content: flex-end;
@@ -228,10 +235,6 @@
width: 100%;
}
.protocol-list-content {
padding-top: var(--space-6);
}
.protocol-control {
display: flex;
align-items: center;
@@ -3,34 +3,34 @@
import { Fieldset, Layout, Accordion } from '@appwrite.io/pink-svelte';
import type { Models } from '@appwrite.io/console';
import { iconPath } from '$lib/stores/app';
import { getFrameworkIcon } from '$lib/stores/sites';
import { getFrameworkIcon, type FrameworkAdapterWithStartCommand } from '$lib/stores/sites';
import { EnvironmentVariables } from '$lib/components/variables';
export let frameworks: Models.Framework[];
export let selectedFramework: Models.Framework;
$: frameworkData = frameworks.find((framework) => framework.key === selectedFramework?.key);
$: adapterData =
frameworkData?.adapters.find((adapter) => adapter.key === 'ssr') ??
frameworkData?.adapters.find((adapter) => adapter.key === 'static');
$: adapterData = (frameworkData?.adapters.find((adapter) => adapter.key === 'ssr') ??
frameworkData?.adapters.find(
(adapter) => adapter.key === 'static'
)) as FrameworkAdapterWithStartCommand;
export let variables: Partial<Models.Variable>[] = [];
export let isLoading = false;
export let installCommand = '';
export let buildCommand = '';
export let startCommand = '';
export let outputDirectory = '';
let frameworkId = selectedFramework.key;
let lastAdapterDefaultsKey = '';
$: if (!installCommand || !buildCommand || !outputDirectory) {
installCommand ||= adapterData?.installCommand;
buildCommand ||= adapterData?.buildCommand;
outputDirectory ||= adapterData?.outputDirectory;
}
$: if (frameworkData) {
installCommand = adapterData?.installCommand;
buildCommand = adapterData?.buildCommand;
outputDirectory = adapterData?.outputDirectory;
$: adapterDefaultsKey = `${frameworkData?.key ?? ''}:${adapterData?.key ?? ''}`;
$: if (frameworkData && adapterDefaultsKey !== lastAdapterDefaultsKey) {
installCommand = adapterData?.installCommand ?? '';
buildCommand = adapterData?.buildCommand ?? '';
startCommand = adapterData?.startCommand ?? '';
outputDirectory = adapterData?.outputDirectory ?? '';
lastAdapterDefaultsKey = adapterDefaultsKey;
}
</script>
@@ -65,7 +65,8 @@
<Button
secondary
size="s"
disabled={adapterData?.installCommand === installCommand}
disabled={(adapterData?.installCommand ?? '') ===
(installCommand ?? '')}
on:click={() => (installCommand = adapterData?.installCommand)}>
Reset
</Button>
@@ -79,11 +80,30 @@
<Button
secondary
size="s"
disabled={adapterData?.buildCommand === buildCommand}
disabled={(adapterData?.buildCommand ?? '') ===
(buildCommand ?? '')}
on:click={() => (buildCommand = adapterData?.buildCommand)}>
Reset
</Button>
</Layout.Stack>
{#if adapterData?.key === 'ssr'}
<Layout.Stack gap="s" direction="row" alignItems="flex-end">
<InputText
id="startCommand"
label="Start command"
bind:value={startCommand}
placeholder={adapterData?.startCommand ||
'Enter start command'} />
<Button
secondary
size="s"
disabled={(adapterData?.startCommand ?? '') ===
(startCommand ?? '')}
on:click={() => (startCommand = adapterData?.startCommand)}>
Reset
</Button>
</Layout.Stack>
{/if}
<Layout.Stack gap="s" direction="row" alignItems="flex-end">
<InputText
id="outputDirectory"
@@ -27,6 +27,7 @@
import { writable } from 'svelte/store';
import { getLatestTag } from '$lib/helpers/github';
import Link from '$lib/elements/link.svelte';
import type { FrameworkAdapterWithStartCommand } from '$lib/stores/sites';
let {
data
@@ -45,6 +46,7 @@
let domain = $state('');
let rootDir = $state(data.repository?.rootDirectory || '');
let buildCommand = $state('');
let startCommand = $state('');
let installCommand = $state('');
let outputDirectory = $state('');
let domainIsValid = $state(false);
@@ -80,6 +82,11 @@
}))
);
const primaryAdapter = $derived.by(
() => data.frameworks.frameworks.find((f) => f.key === framework)?.adapters?.[0]
);
const shouldShowStartCommand = $derived(primaryAdapter?.key === Adapter.Ssr);
$effect(() => {
if (framework && data.frameworks && !hasCustomCommands) {
const fw = data.frameworks.frameworks.find((f) => f.key === framework);
@@ -87,6 +94,7 @@
const adapter = fw.adapters[0];
installCommand = adapter.installCommand || '';
buildCommand = adapter.buildCommand || '';
startCommand = (adapter as FrameworkAdapterWithStartCommand).startCommand || '';
outputDirectory = adapter.outputDirectory || '';
}
}
@@ -103,10 +111,11 @@
// Build configuration - use from URL params or defaults
installCommand = page.url.searchParams.get('install') || '';
buildCommand = page.url.searchParams.get('build') || '';
startCommand = page.url.searchParams.get('start') || '';
outputDirectory = page.url.searchParams.get('output') || '';
// Check if custom commands were provided via URL
hasCustomCommands = !!(installCommand || buildCommand || outputDirectory);
hasCustomCommands = !!(installCommand || buildCommand || startCommand || outputDirectory);
// If no custom commands, auto-fill from framework defaults
if (!hasCustomCommands && data.frameworks) {
@@ -115,6 +124,7 @@
const adapter = fw.adapters[0];
installCommand = adapter.installCommand || '';
buildCommand = adapter.buildCommand || '';
startCommand = (adapter as FrameworkAdapterWithStartCommand).startCommand || '';
outputDirectory = adapter.outputDirectory || '';
}
}
@@ -145,6 +155,7 @@
buildRuntime: selectedFramework.buildRuntime,
installCommand: installCommand || undefined,
buildCommand: buildCommand || undefined,
startCommand: shouldShowStartCommand ? startCommand || undefined : undefined,
outputDirectory: outputDirectory || undefined,
adapter: framework === Framework.Other ? Adapter.Static : undefined,
providerSilentMode: false
@@ -160,6 +171,7 @@
const promises = variables.map((variable) =>
sdk.forProject(page.params.region, page.params.project).sites.createVariable({
siteId: site.$id,
variableId: ID.unique(),
key: variable.key,
value: variable.value,
secret: variable.secret
@@ -272,6 +284,12 @@
label="Build command"
placeholder={buildCommand || 'npm run build'}
bind:value={buildCommand} />
{#if shouldShowStartCommand}
<Input.Text
label="Start command"
placeholder={startCommand || 'npm run start'}
bind:value={startCommand} />
{/if}
<Input.Text
label="Output directory"
placeholder={outputDirectory || 'dist'}
@@ -56,6 +56,7 @@
timeout: data.site.timeout,
installCommand: data.site.installCommand,
buildCommand: data.site.buildCommand,
startCommand: data.site.startCommand,
outputDirectory: data.site.outputDirectory,
buildRuntime: data.site.buildRuntime as BuildRuntime,
adapter: data.site.adapter as Adapter,
@@ -16,12 +16,17 @@
import Configuration from '../configuration.svelte';
import { regionalConsoleVariables } from '../../../store';
import { IconInfo } from '@appwrite.io/pink-icons-svelte';
import { InvalidFileType, removeFile } from '$lib/helpers/files';
import {
getInvalidDeploymentArchiveReason,
InvalidFileType,
removeFile
} from '$lib/helpers/files';
import { humanFileSize } from '$lib/helpers/sizeConvertion';
import { isCloud } from '$lib/system';
import { currentPlan } from '$lib/stores/organization';
import Domain from '../domain.svelte';
import { uploader } from '$lib/stores/uploader';
import type { FrameworkAdapterWithStartCommand } from '$lib/stores/sites';
export let data;
let showExitModal = false;
@@ -36,17 +41,18 @@
let framework: Models.Framework =
data.frameworks.frameworks?.find((f) => f.key === 'other') ??
data.frameworks.frameworks?.[0];
let adapter = framework?.adapters[0];
let adapter = framework?.adapters[0] as FrameworkAdapterWithStartCommand;
let installCommand = adapter?.installCommand;
let buildCommand = adapter?.buildCommand;
let startCommand = adapter?.startCommand;
let outputDirectory = adapter?.outputDirectory;
let variables: Partial<Models.Variable>[] = [];
let files: FileList;
$: maxSize =
isCloud && $currentPlan
isCloud && $currentPlan?.deploymentSize
? $currentPlan.deploymentSize * 1000000
: $regionalConsoleVariables._APP_COMPUTE_SIZE_LIMIT; // already in MB
: $regionalConsoleVariables._APP_COMPUTE_SIZE_LIMIT;
$: readableMaxSize = humanFileSize(maxSize);
@@ -73,6 +79,7 @@
buildRuntime,
installCommand: installCommand || undefined,
buildCommand: buildCommand || undefined,
startCommand: startCommand || undefined,
outputDirectory: outputDirectory || undefined
});
@@ -86,6 +93,7 @@
const promises = variables.map((variable) =>
sdk.forProject(page.params.region, page.params.project).sites.createVariable({
siteId: site.$id,
variableId: ID.unique(),
key: variable.key,
value: variable.value,
secret: variable?.secret ?? false
@@ -111,7 +119,9 @@
});
await promise;
const upload = $uploader.files.find((f) => f.resourceId === site.$id);
const upload = $uploader.files.find(
(f) => f.resourceId === site.$id && f.kind === 'site-deployment'
);
if (upload?.status === 'success') {
const deploymentId = upload.$id;
@@ -125,9 +135,11 @@
await goto(`${resolvedPath}?site=${site.$id}&deployment=${deploymentId}`);
}
} catch (e) {
const upload = $uploader.files.find((f) => f.resourceId === site?.$id);
const upload = $uploader.files.find(
(f) => f.resourceId === site?.$id && f.kind === 'site-deployment'
);
if (upload) {
uploader.removeFromQueue(upload.$id);
uploader.removeFromQueue(upload.clientId);
}
addNotification({
type: 'error',
@@ -141,17 +153,7 @@
let reason = e.detail?.reason ?? '';
if (!reason) {
const nativeEvent = e.detail as Event | undefined;
const input = (nativeEvent?.currentTarget ?? nativeEvent?.target) as
| HTMLInputElement
| undefined;
const pickedFiles = Array.from(input?.files ?? []);
if (pickedFiles.some((file) => file.size > maxSize)) {
reason = InvalidFileType.SIZE;
} else if (pickedFiles.some((file) => !file.name.toLowerCase().endsWith('.tar.gz'))) {
reason = InvalidFileType.EXTENSION;
}
reason = getInvalidDeploymentArchiveReason(files, maxSize) ?? '';
}
if (reason === InvalidFileType.EXTENSION) {
@@ -172,6 +174,15 @@
}
}
$: if (files?.length) {
const reason = getInvalidDeploymentArchiveReason(files, maxSize);
if (reason) {
files = undefined;
handleInvalid(new CustomEvent('invalid', { detail: { reason } }));
}
}
$: filesList = files?.length
? Array.from(files).map((f) => {
return {
@@ -201,7 +212,7 @@
Upload a tar.gz containing your site source code
</Typography.Text>
<Upload.Dropzone
extensions={['gz', 'tar']}
extensions={['gz']}
bind:files
{maxSize}
required
@@ -243,6 +254,7 @@
<Configuration
bind:installCommand
bind:buildCommand
bind:startCommand
bind:outputDirectory
bind:selectedFramework={framework}
bind:variables
@@ -28,6 +28,7 @@
import Domain from '../../domain.svelte';
import { regionalConsoleVariables } from '$routes/(console)/project-[region]-[project]/store';
import { normalizeDetectedVariables, mergeVariables } from '$lib/helpers/variables';
import type { FrameworkAdapterWithStartCommand } from '$lib/stores/sites';
export let data;
let showExitModal = false;
@@ -38,11 +39,12 @@
let name = '';
let id = ID.unique();
let framework: Models.Framework = data.frameworks.frameworks.find((f) => f.key === 'other');
let adapter = framework?.adapters[0];
let adapter = framework?.adapters[0] as FrameworkAdapterWithStartCommand;
let branch: string;
let rootDir = './';
let installCommand = adapter?.installCommand;
let buildCommand = adapter?.buildCommand;
let startCommand = adapter?.startCommand;
let outputDirectory = adapter?.outputDirectory;
let variables: Partial<Models.Variable>[] = [];
let silentMode = false;
@@ -81,9 +83,10 @@
if (!framework) {
framework = data.frameworks.frameworks.find((f) => f.key === 'other');
}
adapter = framework?.adapters[0];
adapter = framework?.adapters[0] as FrameworkAdapterWithStartCommand;
installCommand = adapter?.installCommand;
buildCommand = adapter?.buildCommand;
startCommand = adapter?.startCommand;
outputDirectory = adapter?.outputDirectory;
const detectedVariables = normalizeDetectedVariables(response?.variables);
if (detectedVariables.length) {
@@ -119,9 +122,10 @@
name,
framework: fr,
buildRuntime,
installCommand,
buildCommand,
outputDirectory,
installCommand: installCommand || undefined,
buildCommand: buildCommand || undefined,
startCommand: startCommand || undefined,
outputDirectory: outputDirectory || undefined,
installationId: data.installation.$id,
providerRepositoryId: data.repository.id,
providerBranch: branch,
@@ -139,6 +143,7 @@
const promises = variables.map((variable) =>
sdk.forProject(page.params.region, page.params.project).sites.createVariable({
siteId: site.$id,
variableId: ID.unique(),
key: variable.key,
value: variable.value,
secret: variable?.secret ?? false
@@ -218,6 +223,7 @@
<Configuration
bind:installCommand
bind:buildCommand
bind:startCommand
bind:outputDirectory
bind:selectedFramework={framework}
bind:variables
@@ -151,6 +151,7 @@
const promises = variables.map((variable) =>
sdk.forProject(page.params.region, page.params.project).sites.createVariable({
siteId: site.$id,
variableId: ID.unique(),
key: variable.name,
value: variable.value,
secret: variable?.secret ?? false
@@ -13,11 +13,6 @@
title: 'Sites',
event: 'sites',
hasChildren: true
},
{
href: `${path}/usage`,
title: 'Usage',
event: 'usage'
}
];
</script>
@@ -68,6 +68,7 @@
timeout: data.site.timeout,
installCommand: data.site.installCommand,
buildCommand: data.site.buildCommand,
startCommand: data.site.startCommand,
outputDirectory: data.site.outputDirectory,
buildRuntime: data.site.buildRuntime as BuildRuntime,
adapter: data.site.adapter as Adapter,
@@ -90,6 +90,7 @@
timeout: site.timeout || undefined,
installCommand: site.installCommand || undefined,
buildCommand: site.buildCommand || undefined,
startCommand: site.startCommand || undefined,
outputDirectory: site.outputDirectory || undefined,
buildRuntime: (site?.buildRuntime as BuildRuntime) || undefined,
adapter: (site.adapter as Adapter) || undefined,
@@ -3,7 +3,11 @@
import { Modal } from '$lib/components';
import { Dependencies } from '$lib/constants';
import { Button } from '$lib/elements/forms';
import { InvalidFileType, removeFile } from '$lib/helpers/files';
import {
getInvalidDeploymentArchiveReason,
InvalidFileType,
removeFile
} from '$lib/helpers/files';
import { addNotification } from '$lib/stores/notifications';
import { uploader } from '$lib/stores/uploader';
import type { Models } from '@appwrite.io/console';
@@ -22,9 +26,9 @@
let error: string = '';
$: maxSize =
isCloud && $currentPlan
isCloud && $currentPlan?.deploymentSize
? $currentPlan.deploymentSize * 1000000
: $consoleVariables._APP_COMPUTE_SIZE_LIMIT; // already in MB
: $consoleVariables._APP_COMPUTE_SIZE_LIMIT;
$: readableMaxSize = humanFileSize(maxSize);
@@ -54,12 +58,21 @@
if (reason === InvalidFileType.EXTENSION) {
error = 'Only .tar.gz files allowed';
} else if (reason === InvalidFileType.SIZE) {
error = 'File size exceeds 10MB';
error = `File size exceeds ${readableMaxSize.value}${readableMaxSize.unit}`;
} else {
error = 'Invalid file';
}
}
$: if (files?.length) {
const reason = getInvalidDeploymentArchiveReason(files, maxSize);
if (reason) {
files = undefined;
handleInvalid(new CustomEvent('invalid', { detail: { reason } }));
}
}
$: filesList = files?.length
? Array.from(files).map((f) => {
return {
@@ -80,7 +93,7 @@
Upload a tar.gz file containing your site source code
</Typography.Text>
<Upload.Dropzone
extensions={['gz', 'tar']}
extensions={['gz']}
bind:files
{maxSize}
required
@@ -29,9 +29,9 @@ export const load = async ({ params, depends, url, route, parent }) => {
Query.offset(offset),
Query.orderDesc(''),
Query.orderDesc('$updatedAt'),
...(search ? [Query.search('domain', search)] : []),
...parsedQueries.values()
],
search: search || undefined
]
});
const organizationDomains = await fetchOrganizationDomainsForRules(
@@ -29,6 +29,7 @@
} from '$routes/(console)/project-[region]-[project]/store';
import { isCloud } from '$lib/system';
import { getApexDomain } from '$lib/helpers/tlds';
import { isProxyRuleVerified } from '$lib/components/domains/status';
const routeBase = `${base}/project-${page.params.region}-${page.params.project}/sites/site-${page.params.site}/domains`;
@@ -110,7 +111,7 @@
await invalidate(Dependencies.SITES_DOMAINS);
const verified = rule?.status !== 'created';
const verified = isProxyRuleVerified(rule?.status);
if (verified) {
addNotification({
type: 'success',
@@ -139,6 +140,7 @@
timeout: data.site.timeout,
installCommand: data.site.installCommand,
buildCommand: data.site.buildCommand,
startCommand: data.site.startCommand,
outputDirectory: data.site.outputDirectory,
buildRuntime: data.site.buildRuntime as BuildRuntime,
adapter: data.site.adapter as Adapter,
@@ -72,7 +72,7 @@
try {
proxyRule = await sdk
.forProject(page.params.region, page.params.project)
.proxy.updateRuleVerification({ ruleId });
.proxy.updateRuleStatus({ ruleId });
await Promise.all([
invalidate(Dependencies.DOMAINS),
@@ -68,7 +68,7 @@
try {
selectedProxyRule = await sdk
.forProject(page.params.region, page.params.project)
.proxy.updateRuleVerification({ ruleId: selectedProxyRule.$id });
.proxy.updateRuleStatus({ ruleId: selectedProxyRule.$id });
await invalidate(Dependencies.SITES_DOMAINS);
show = false;
@@ -24,6 +24,13 @@
import { columns } from './store';
import { regionalProtocol } from '$routes/(console)/project-[region]-[project]/store';
import DnsRecordsAction from '$lib/components/domains/dnsRecordsAction.svelte';
import {
getProxyRuleStatusBadge,
getProxyRuleUpdatedPrefix,
isProxyRuleLogsViewable,
isProxyRuleRetryable,
isProxyRuleVerified
} from '$lib/components/domains/status';
import ViewLogsModal from '$lib/components/domains/viewLogsModal.svelte';
import { timeFromNowShort } from '$lib/helpers/date';
@@ -49,7 +56,7 @@
};
function updatedLabel(proxyRule: Models.ProxyRule): string {
if (proxyRule.status === 'verified') {
if (isProxyRuleVerified(proxyRule.status)) {
return '';
}
@@ -58,14 +65,7 @@
return '';
}
const prefix =
proxyRule.status === 'created'
? 'Checked'
: proxyRule.status === 'verifying'
? 'Updated'
: proxyRule.status === 'unverified'
? 'Failed'
: '';
const prefix = getProxyRuleUpdatedPrefix(proxyRule.status);
return prefix + ' ' + timeStr;
}
@@ -81,10 +81,9 @@
<Table.Header.Cell column="actions" {root} />
</svelte:fragment>
{#each proxyRules.rules as proxyRule (proxyRule.$id)}
{@const isRetryable = proxyRule.status === 'created' || proxyRule.status === 'unverified'}
{@const isLogsViewable =
proxyRule.logs?.length > 0 &&
(proxyRule.status === 'verifying' || proxyRule.status === 'unverified')}
{@const isRetryable = isProxyRuleRetryable(proxyRule.status)}
{@const isLogsViewable = isProxyRuleLogsViewable(proxyRule)}
{@const statusBadge = getProxyRuleStatusBadge(proxyRule.status)}
<Table.Row.Base {root}>
{#each $columns as column}
<Table.Cell column={column.id} {root}>
@@ -99,17 +98,11 @@
</Typography.Text>
</Link>
<Layout.Stack direction="row" gap="s" alignItems="center">
{#if proxyRule.status !== 'verified'}
{#if statusBadge}
<Badge
variant="secondary"
type={proxyRule.status === 'verifying'
? undefined
: 'error'}
content={proxyRule.status === 'created'
? 'Verification failed'
: proxyRule.status === 'verifying'
? 'Generating certificate'
: 'Certificate generation failed'}
type={statusBadge.type}
content={statusBadge.content}
size="xs" />
{/if}
{#if isRetryable}
@@ -140,7 +133,7 @@
</Layout.Stack>
{:else if column.id === 'target'}
{proxyTarget(proxyRule)}
{:else if column.id === 'updated' && proxyRule.status !== 'verified'}
{:else if column.id === 'updated' && !isProxyRuleVerified(proxyRule.status)}
<Layout.Stack direction="row" justifyContent="flex-end">
<Typography.Text
variant="m-400"
@@ -28,11 +28,6 @@
title: 'Domains',
event: 'domains'
},
{
href: `${path}/usage`,
title: 'Usage',
event: 'usage'
},
{
href: `${path}/settings`,
title: 'Settings',
@@ -17,12 +17,14 @@
import UpdateVariables from '$routes/(console)/project-[region]-[project]/updateVariables.svelte';
import UpdateLogging from './updateLogging.svelte';
import UpdateDeploymentRetention from './updateDeploymentRetention.svelte';
import { ID } from '@appwrite.io/console';
export let data;
const sdkCreateVariable = async (key: string, value: string, secret: boolean) => {
await sdk.forProject(page.params.region, page.params.project).sites.createVariable({
siteId: page.params.site,
variableId: ID.unique(),
key,
value,
secret
@@ -27,6 +27,7 @@
timeout: site.timeout || undefined,
installCommand: site.installCommand || undefined,
buildCommand: site.buildCommand || undefined,
startCommand: site.startCommand || undefined,
outputDirectory: site.outputDirectory || undefined,
buildRuntime: (site?.buildRuntime as BuildRuntime) || undefined,
adapter: (site?.adapter as Adapter) || undefined,
@@ -12,7 +12,7 @@
import { Link } from '$lib/elements';
import { IconInfo } from '@appwrite.io/pink-icons-svelte';
import { adapterDataList } from './store';
import { getFrameworkIcon } from '$lib/stores/sites';
import { getFrameworkIcon, type FrameworkAdapterWithStartCommand } from '$lib/stores/sites';
import { page } from '$app/state';
let {
@@ -28,40 +28,37 @@
let frameworkKey = $state(site.framework);
let installCommand = $state(site?.installCommand);
let buildCommand = $state(site?.buildCommand);
let startCommand = $state(site?.startCommand);
let outputDirectory = $state(site?.outputDirectory);
let fallback = $state(site?.fallbackFile);
let adapter: Adapter = $state(site.adapter as Adapter);
let selectedFramework: Models.Framework = $derived(
let selectedFramework = $state(
frameworks.find((framework) => framework.key === site.framework)
);
let showFallback = $derived(adapter === Adapter.Static);
let lastFrameworkAdapterKey = $state('');
let isUntouched = $derived(
installCommand === site?.installCommand &&
buildCommand === site?.buildCommand &&
startCommand === site?.startCommand &&
outputDirectory === site?.outputDirectory &&
selectedFramework?.key === site?.framework &&
(fallback ?? '') === (site?.fallbackFile ?? '') &&
(adapter ?? '') === (site?.adapter ?? '')
);
let frameworkAdapterData = $derived(
selectedFramework.adapters.find((a) => a.key === adapter) ?? selectedFramework.adapters[0]
let frameworkAdapterData: FrameworkAdapterWithStartCommand = $derived(
(selectedFramework.adapters.find((a) => a.key === adapter) ??
selectedFramework.adapters[0]) as FrameworkAdapterWithStartCommand
);
$effect(() => {
if (adapter) {
const data = selectedFramework.adapters.find((a) => a.key === adapter);
if (data) {
installCommand = data.installCommand;
buildCommand = data.buildCommand;
outputDirectory = data.outputDirectory;
fallback = data.fallbackFile;
}
}
});
if (!selectedFramework) return;
const frameworkAdapterKey = `${selectedFramework.key}:${adapter ?? ''}`;
const hasFrameworkSelectionChanged = frameworkAdapterKey !== lastFrameworkAdapterKey;
$effect(() => {
if (selectedFramework?.key !== site.framework) {
// Update adapter
const singleAdapter = selectedFramework?.adapters?.length <= 1;
@@ -78,21 +75,37 @@
}
//Update values
const data =
selectedFramework.adapters.find((a) => a.key === adapter) ??
selectedFramework.adapters[0];
const data = (selectedFramework.adapters.find((a) => a.key === adapter) ??
selectedFramework.adapters[0]) as FrameworkAdapterWithStartCommand;
installCommand = data.installCommand;
buildCommand = data.buildCommand;
startCommand = data.startCommand;
outputDirectory = data.outputDirectory;
adapter = data.key as Adapter;
fallback = data.fallbackFile;
} else {
adapter = site.adapter as Adapter;
installCommand = site?.installCommand ?? frameworkAdapterData.installCommand;
buildCommand = site?.buildCommand ?? frameworkAdapterData.buildCommand;
outputDirectory = site?.outputDirectory ?? frameworkAdapterData.outputDirectory;
fallback = site?.fallbackFile ?? frameworkAdapterData.fallbackFile;
} else if (hasFrameworkSelectionChanged) {
const data = (selectedFramework.adapters.find((a) => a.key === adapter) ??
selectedFramework.adapters[0]) as FrameworkAdapterWithStartCommand;
const isOriginalAdapter = adapter === site.adapter;
installCommand = isOriginalAdapter
? (site?.installCommand ?? frameworkAdapterData.installCommand)
: data.installCommand;
buildCommand = isOriginalAdapter
? (site?.buildCommand ?? frameworkAdapterData.buildCommand)
: data.buildCommand;
startCommand = isOriginalAdapter
? (site?.startCommand ?? frameworkAdapterData.startCommand)
: data.startCommand;
outputDirectory = isOriginalAdapter
? (site?.outputDirectory ?? frameworkAdapterData.outputDirectory)
: data.outputDirectory;
fallback = isOriginalAdapter
? (site?.fallbackFile ?? data.fallbackFile)
: data.fallbackFile;
}
lastFrameworkAdapterKey = `${selectedFramework.key}:${adapter ?? ''}`;
});
$effect(() => {
@@ -149,6 +162,7 @@
timeout: site.timeout || undefined,
installCommand: installCommand || undefined,
buildCommand: buildCommand || undefined,
startCommand: startCommand || undefined,
outputDirectory: outputDirectory || undefined,
buildRuntime: (site?.buildRuntime as BuildRuntime) || undefined,
adapter: (adptr?.key as Adapter) || undefined,
@@ -178,13 +192,17 @@
}
}
function reset(type: 'installCommand' | 'buildCommand' | 'outputDirectory') {
const data = selectedFramework.adapters.find((a) => a.key === adapter);
function reset(type: 'installCommand' | 'buildCommand' | 'startCommand' | 'outputDirectory') {
const data = selectedFramework.adapters.find(
(a) => a.key === adapter
) as FrameworkAdapterWithStartCommand;
if (type === 'installCommand') {
installCommand = data.installCommand;
} else if (type === 'buildCommand') {
buildCommand = data.buildCommand;
} else if (type === 'startCommand') {
startCommand = data.startCommand;
} else if (type === 'outputDirectory') {
outputDirectory = data.outputDirectory;
}
@@ -292,7 +310,8 @@
secondary
size="s"
on:click={() => reset('installCommand')}
disabled={installCommand === frameworkAdapterData?.installCommand}>
disabled={(installCommand ?? '') ===
(frameworkAdapterData?.installCommand ?? '')}>
Reset
</Button>
</Layout.Stack>
@@ -306,11 +325,30 @@
<Button
secondary
size="s"
disabled={buildCommand === frameworkAdapterData?.buildCommand}
disabled={(buildCommand ?? '') ===
(frameworkAdapterData?.buildCommand ?? '')}
on:click={() => reset('buildCommand')}>
Reset
</Button>
</Layout.Stack>
{#if adapter === Adapter.Ssr}
<Layout.Stack gap="s" direction="row" alignItems="flex-end">
<InputText
id="startCommand"
label="Start command"
bind:value={startCommand}
placeholder={frameworkAdapterData?.startCommand ||
'Enter start command'} />
<Button
secondary
size="s"
disabled={(startCommand ?? '') ===
(frameworkAdapterData?.startCommand ?? '')}
on:click={() => reset('startCommand')}>
Reset
</Button>
</Layout.Stack>
{/if}
<Layout.Stack gap="s" direction="row" alignItems="flex-end">
<InputText
id="outputDirectory"
@@ -24,6 +24,7 @@
timeout: site?.timeout || undefined,
installCommand: site?.installCommand || undefined,
buildCommand: site?.buildCommand || undefined,
startCommand: site?.startCommand || undefined,
outputDirectory: site?.outputDirectory || undefined,
buildRuntime: (site?.buildRuntime as BuildRuntime) || undefined,
adapter: site?.adapter as Adapter,
@@ -28,6 +28,7 @@
timeout: site?.timeout || undefined,
installCommand: site?.installCommand || undefined,
buildCommand: site?.buildCommand || undefined,
startCommand: site?.startCommand || undefined,
outputDirectory: site?.outputDirectory || undefined,
buildRuntime: (site?.buildRuntime as BuildRuntime) || undefined,
adapter: site?.adapter as Adapter,
@@ -77,6 +77,7 @@
timeout: site?.timeout || undefined,
installCommand: site?.installCommand || undefined,
buildCommand: site?.buildCommand || undefined,
startCommand: site?.startCommand || undefined,
outputDirectory: site?.outputDirectory || undefined,
buildRuntime: (site?.buildRuntime as BuildRuntime) || undefined,
adapter: site?.adapter as Adapter,
@@ -143,6 +144,7 @@
timeout: site?.timeout,
installCommand: site?.installCommand,
buildCommand: site?.buildCommand,
startCommand: site?.startCommand,
outputDirectory: site?.outputDirectory,
buildRuntime: site?.buildRuntime as BuildRuntime,
adapter: site.adapter as Adapter,
@@ -45,6 +45,7 @@
timeout: site?.timeout || undefined,
installCommand: site?.installCommand || undefined,
buildCommand: site?.buildCommand || undefined,
startCommand: site?.startCommand || undefined,
outputDirectory: site?.outputDirectory || undefined,
buildRuntime: (site?.buildRuntime as BuildRuntime) || undefined,
adapter: site?.adapter as Adapter,
@@ -34,6 +34,7 @@
timeout: site?.timeout || undefined,
installCommand: site?.installCommand || undefined,
buildCommand: site?.buildCommand || undefined,
startCommand: site?.startCommand || undefined,
outputDirectory: site?.outputDirectory || undefined,
buildRuntime: (buildRuntime as BuildRuntime) || undefined,
adapter: site?.adapter as Adapter,
@@ -27,6 +27,7 @@
timeout: timeout || undefined,
installCommand: site?.installCommand || undefined,
buildCommand: site?.buildCommand || undefined,
startCommand: site?.startCommand || undefined,
outputDirectory: site?.outputDirectory || undefined,
buildRuntime: (site?.buildRuntime as BuildRuntime) || undefined,
adapter: site?.adapter as Adapter,

Some files were not shown because too many files have changed in this diff Show More