diff --git a/.env.example b/.env.example index 138249fc1..ae9250596 100644 --- a/.env.example +++ b/.env.example @@ -1,4 +1,6 @@ -PUBLIC_APPWRITE_ENDPOINT=https://localhost/v1 PUBLIC_CONSOLE_MODE=self-hosted +PUBLIC_APPWRITE_MULTI_REGION=false +PUBLIC_APPWRITE_ENDPOINT=http://localhost/v1 + PUBLIC_STRIPE_KEY= PUBLIC_GROWTH_ENDPOINT= \ No newline at end of file diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 91c98b81f..4c761e03e 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -39,6 +39,7 @@ jobs: labels: ${{ steps.meta.outputs.labels }} build-args: | "PUBLIC_CONSOLE_MODE=cloud" + "PUBLIC_APPWRITE_MULTI_REGION=true" "PUBLIC_GROWTH_ENDPOINT=${{ secrets.PUBLIC_GROWTH_ENDPOINT }}" "PUBLIC_STRIPE_KEY=${{ secrets.PUBLIC_STRIPE_KEY }}" "SENTRY_AUTH_TOKEN=${{ secrets.SENTRY_AUTH_TOKEN }}" @@ -77,6 +78,7 @@ jobs: labels: ${{ steps.meta.outputs.labels }} build-args: | "PUBLIC_CONSOLE_MODE=cloud" + "PUBLIC_APPWRITE_MULTI_REGION=true" "PUBLIC_GROWTH_ENDPOINT=${{ secrets.PUBLIC_GROWTH_ENDPOINT }}" "PUBLIC_STRIPE_KEY=${{ secrets.PUBLIC_STRIPE_KEY_STAGE }}" publish-self-hosted: @@ -113,4 +115,5 @@ jobs: labels: ${{ steps.meta.outputs.labels }} build-args: | "PUBLIC_CONSOLE_MODE=self-hosted" + "PUBLIC_APPWRITE_MULTI_REGION=false" "PUBLIC_GROWTH_ENDPOINT=${{ secrets.PUBLIC_GROWTH_ENDPOINT }}" diff --git a/Dockerfile b/Dockerfile index 45263f235..774fb6903 100644 --- a/Dockerfile +++ b/Dockerfile @@ -21,6 +21,7 @@ ADD ./src /app/src ADD ./static /app/static ARG PUBLIC_CONSOLE_MODE +ARG PUBLIC_APPWRITE_MULTI_REGION ARG PUBLIC_APPWRITE_ENDPOINT ARG PUBLIC_GROWTH_ENDPOINT ARG PUBLIC_STRIPE_KEY @@ -30,6 +31,7 @@ ARG SENTRY_RELEASE ENV PUBLIC_APPWRITE_ENDPOINT=$PUBLIC_APPWRITE_ENDPOINT ENV PUBLIC_GROWTH_ENDPOINT=$PUBLIC_GROWTH_ENDPOINT ENV PUBLIC_CONSOLE_MODE=$PUBLIC_CONSOLE_MODE +ENV PUBLIC_APPWRITE_MULTI_REGION=$PUBLIC_APPWRITE_MULTI_REGION ENV PUBLIC_STRIPE_KEY=$PUBLIC_STRIPE_KEY ENV SENTRY_AUTH_TOKEN=$SENTRY_AUTH_TOKEN ENV SENTRY_RELEASE=$SENTRY_RELEASE @@ -37,7 +39,7 @@ ENV NODE_OPTIONS=--max_old_space_size=8192 RUN pnpm run build -FROM nginx:1.25-alpine +FROM nginx:1.26.3-alpine EXPOSE 80 diff --git a/build.js b/build.js index 9753d0378..f56506dae 100644 --- a/build.js +++ b/build.js @@ -24,6 +24,7 @@ async function main() { log(bold().magenta('APPWRITE CONSOLE')); log(); logEnv('CONSOLE MODE', env?.PUBLIC_CONSOLE_MODE); + logEnv('MULTI REGION', env?.PUBLIC_APPWRITE_MULTI_REGION); logEnv('APPWRITE ENDPOINT', env?.PUBLIC_APPWRITE_ENDPOINT, 'relative'); logEnv('GROWTH ENDPOINT', env?.PUBLIC_GROWTH_ENDPOINT); log(); diff --git a/compose.yml b/compose.yml index cfbb54934..6166d3776 100644 --- a/compose.yml +++ b/compose.yml @@ -5,6 +5,7 @@ services: context: . args: PUBLIC_CONSOLE_MODE: ${PUBLIC_CONSOLE_MODE} + PUBLIC_APPWRITE_MULTI_REGION: ${PUBLIC_APPWRITE_MULTI_REGION} PUBLIC_APPWRITE_ENDPOINT: ${PUBLIC_APPWRITE_ENDPOINT} PUBLIC_GROWTH_ENDPOINT: ${PUBLIC_GROWTH_ENDPOINT} PUBLIC_STRIPE_KEY: ${PUBLIC_STRIPE_KEY} @@ -20,6 +21,7 @@ services: - build/ environment: - PUBLIC_CONSOLE_MODE + - PUBLIC_APPWRITE_MULTI_REGION - PUBLIC_APPWRITE_ENDPOINT - PUBLIC_GROWTH_ENDPOINT - PUBLIC_STRIPE_KEY diff --git a/docker/nginx.conf b/docker/nginx.conf index 7f7313e00..2f7987a9f 100644 --- a/docker/nginx.conf +++ b/docker/nginx.conf @@ -1,8 +1,6 @@ -map $sent_http_content_type $expires { - # cache everything for 1 year - default 1y; - # html files shouldn't be cached for single-page applications - text/html off; +map $sent_http_content_type $cc_header { + default "public, max-age=31536000"; + text/html "no-cache"; } server { @@ -12,15 +10,17 @@ server { # serve compressed file if filename.gz exists gzip_static on; + location = /console/service-worker.js { + root /usr/share/nginx/html; + add_header Cache-Control "public, max-age=30" always; + } + location /console { root /usr/share/nginx/html; index index.html index.htm; try_files $uri /console/index.html; - # Add cache headers - expires $expires; - add_header Pragma public; - add_header Cache-Control "public"; + add_header Cache-Control $cc_header always; # Deny IE browsers from going into quirks mode add_header X-UA-Compatible "IE=Edge"; diff --git a/package.json b/package.json index 9064448ef..f5877e2c0 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,8 @@ "e2e:ui": "playwright test --ui" }, "dependencies": { - "@appwrite.io/console": "https://pkg.pr.new/appwrite/appwrite/@appwrite.io/console@e2f082e", + "@ai-sdk/svelte": "^1.1.24", + "@appwrite.io/console": "https://pkg.pr.new/appwrite/appwrite/@appwrite.io/console@f76aff1", "@appwrite.io/pink": "0.25.0", "@appwrite.io/pink-icons": "0.25.0", "@appwrite.io/pink-icons-svelte": "https://pkg.pr.new/appwrite/pink/@appwrite.io/pink-icons-svelte@bd21ff7f", @@ -32,7 +33,6 @@ "@stripe/stripe-js": "^3.5.0", "ai": "^2.2.37", "analytics": "^0.8.16", - "@ai-sdk/svelte": "^1.1.24", "cron-parser": "^4.9.0", "dayjs": "^1.11.13", "deep-equal": "^2.2.3", diff --git a/playwright.config.ts b/playwright.config.ts index de119fa1f..fbd977757 100644 --- a/playwright.config.ts +++ b/playwright.config.ts @@ -15,6 +15,7 @@ const config: PlaywrightTestConfig = { env: { PUBLIC_APPWRITE_ENDPOINT: 'https://stage.cloud.appwrite.io/v1', PUBLIC_CONSOLE_MODE: 'cloud', + PUBLIC_APPWRITE_MULTI_REGION: 'true', PUBLIC_STRIPE_KEY: 'pk_test_51LT5nsGYD1ySxNCyd7b304wPD8Y1XKKWR6hqo6cu3GIRwgvcVNzoZv4vKt5DfYXL1gRGw4JOqE19afwkJYJq1g3K004eVfpdWn' }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 93acdd1ee..7e2b51ac4 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -12,8 +12,8 @@ importers: specifier: ^1.1.24 version: 1.1.24(svelte@5.25.3)(zod@3.24.3) '@appwrite.io/console': - specifier: https://pkg.pr.new/appwrite/appwrite/@appwrite.io/console@e2f082e - version: https://pkg.pr.new/appwrite/appwrite/@appwrite.io/console@e2f082e + specifier: https://pkg.pr.new/appwrite/appwrite/@appwrite.io/console@f76aff1 + version: https://pkg.pr.new/appwrite/appwrite/@appwrite.io/console@f76aff1 '@appwrite.io/pink': specifier: 0.25.0 version: 0.25.0 @@ -254,8 +254,8 @@ packages: '@analytics/type-utils@0.6.2': resolution: {integrity: sha512-TD+xbmsBLyYy/IxFimW/YL/9L2IEnM7/EoV9Aeh56U64Ify8o27HJcKjo38XY9Tcn0uOq1AX3thkKgvtWvwFQg==} - '@appwrite.io/console@https://pkg.pr.new/appwrite/appwrite/@appwrite.io/console@e2f082e': - resolution: {tarball: https://pkg.pr.new/appwrite/appwrite/@appwrite.io/console@e2f082e} + '@appwrite.io/console@https://pkg.pr.new/appwrite/appwrite/@appwrite.io/console@f76aff1': + resolution: {tarball: https://pkg.pr.new/appwrite/appwrite/@appwrite.io/console@f76aff1} version: 1.2.1 '@appwrite.io/pink-icons-svelte@https://pkg.pr.new/appwrite/pink/@appwrite.io/pink-icons-svelte@bd21ff7f': @@ -3625,7 +3625,7 @@ snapshots: '@analytics/type-utils@0.6.2': {} - '@appwrite.io/console@https://pkg.pr.new/appwrite/appwrite/@appwrite.io/console@e2f082e': {} + '@appwrite.io/console@https://pkg.pr.new/appwrite/appwrite/@appwrite.io/console@f76aff1': {} '@appwrite.io/pink-icons-svelte@https://pkg.pr.new/appwrite/pink/@appwrite.io/pink-icons-svelte@bd21ff7f(svelte@5.25.3)': dependencies: diff --git a/src/lib/components/support.svelte b/src/lib/components/support.svelte index 8c5ce20b8..2520ef032 100644 --- a/src/lib/components/support.svelte +++ b/src/lib/components/support.svelte @@ -5,18 +5,30 @@ import { isSupportOnline, showSupportModal } from '$routes/(console)/wizard/support/store'; import { Click, trackEvent } from '$lib/actions/analytics'; import { localeShortTimezoneName, utcHourToLocaleHour } from '$lib/helpers/date'; - import { upgradeURL } from '$lib/stores/billing'; + import { plansInfo } from '$lib/stores/billing'; import { Card } from '$lib/components/index'; import { app } from '$lib/stores/app'; - import { currentPlan } from '$lib/stores/organization'; + import { currentPlan, type Organization, organizationList } from '$lib/stores/organization'; import { isCloud } from '$lib/system'; import { Typography } from '@appwrite.io/pink-svelte'; + import { base } from '$app/paths'; export let show = false; export let showHeader = true; - $: hasPremiumSupport = $currentPlan?.premiumSupport ?? false; + $: hasPremiumSupport = $currentPlan?.premiumSupport ?? allOrgsHavePremiumSupport ?? false; + + $: allOrgsHavePremiumSupport = $organizationList.teams.every( + (team) => $plansInfo.get((team as Organization).billingPlan)?.premiumSupport + ); + + // there can only be one free organization + $: freeOrganization = $organizationList.teams.find( + (team) => !$plansInfo.get((team as Organization).billingPlan)?.premiumSupport + ); + + $: upgradeURL = `${base}/organization-${freeOrganization.$id}/change-plan`; $: supportTimings = `${utcHourToLocaleHour('16:00')} - ${utcHourToLocaleHour('00:00')} ${localeShortTimezoneName()}`; @@ -55,7 +67,7 @@ } ]; - const showCloudSupport = (index) => { + const showCloudSupport = (index: number) => { return (index === 0 && isCloud) || index > 0; }; @@ -79,7 +91,7 @@
{#if !hasPremiumSupport} diff --git a/src/routes/(console)/project-[region]-[project]/auth/(providers)/auth0OAuth.svelte b/src/routes/(console)/project-[region]-[project]/auth/(providers)/auth0OAuth.svelte index 710ba1e28..183e52f16 100644 --- a/src/routes/(console)/project-[region]-[project]/auth/(providers)/auth0OAuth.svelte +++ b/src/routes/(console)/project-[region]-[project]/auth/(providers)/auth0OAuth.svelte @@ -3,7 +3,7 @@ import { CopyInput, Modal } from '$lib/components'; import { Button, InputPassword, InputSwitch, InputText } from '$lib/elements/forms'; import { oAuthProviders, type Provider } from '$lib/stores/oauth-providers'; - import { sdk } from '$lib/stores/sdk'; + import { getApiEndpoint } from '$lib/stores/sdk'; import { onMount } from 'svelte'; import { updateOAuth } from '../updateOAuth'; import type { Models } from '@appwrite.io/console'; @@ -11,6 +11,8 @@ const projectId = page.params.project; export let provider: Models.AuthProvider; + export let show = false; + let clientSecret: string = null; let auth0Domain: string = null; let error: string; @@ -70,7 +72,7 @@

URI

+ value={`${getApiEndpoint(page.params.region)}/account/sessions/oauth2/callback/${provider.key}/${projectId}`} />
diff --git a/src/routes/(console)/project-[region]-[project]/auth/(providers)/authentikOAuth.svelte b/src/routes/(console)/project-[region]-[project]/auth/(providers)/authentikOAuth.svelte index b40245c26..49fb81c40 100644 --- a/src/routes/(console)/project-[region]-[project]/auth/(providers)/authentikOAuth.svelte +++ b/src/routes/(console)/project-[region]-[project]/auth/(providers)/authentikOAuth.svelte @@ -3,7 +3,7 @@ import { CopyInput, Modal } from '$lib/components'; import { Button, InputPassword, InputSwitch, InputText } from '$lib/elements/forms'; import { oAuthProviders, type Provider } from '$lib/stores/oauth-providers'; - import { sdk } from '$lib/stores/sdk'; + import { getApiEndpoint } from '$lib/stores/sdk'; import { onMount } from 'svelte'; import { updateOAuth } from '../updateOAuth'; import type { Models } from '@appwrite.io/console'; @@ -78,7 +78,7 @@

URI

+ value={`${getApiEndpoint(page.params.region)}/account/sessions/oauth2/callback/${provider.key}/${projectId}`} />
diff --git a/src/routes/(console)/project-[region]-[project]/auth/(providers)/gitlabOAuth.svelte b/src/routes/(console)/project-[region]-[project]/auth/(providers)/gitlabOAuth.svelte index 76e386e1c..481ce1e60 100644 --- a/src/routes/(console)/project-[region]-[project]/auth/(providers)/gitlabOAuth.svelte +++ b/src/routes/(console)/project-[region]-[project]/auth/(providers)/gitlabOAuth.svelte @@ -3,11 +3,11 @@ import { CopyInput, Modal } from '$lib/components'; import { Button, InputPassword, InputSwitch, InputText } from '$lib/elements/forms'; import { oAuthProviders, type Provider } from '$lib/stores/oauth-providers'; - import { sdk } from '$lib/stores/sdk'; import { onMount } from 'svelte'; import { updateOAuth } from '../updateOAuth'; import type { Models } from '@appwrite.io/console'; import { Link, Alert } from '@appwrite.io/pink-svelte'; + import { getApiEndpoint } from '$lib/stores/sdk'; const projectId = page.params.project; @@ -73,7 +73,7 @@

URI

+ value={`${getApiEndpoint(page.params.region)}/account/sessions/oauth2/callback/${provider.key}/${projectId}`} />
diff --git a/src/routes/(console)/project-[region]-[project]/auth/(providers)/googleOAuth.svelte b/src/routes/(console)/project-[region]-[project]/auth/(providers)/googleOAuth.svelte index 197325983..d80ee1672 100644 --- a/src/routes/(console)/project-[region]-[project]/auth/(providers)/googleOAuth.svelte +++ b/src/routes/(console)/project-[region]-[project]/auth/(providers)/googleOAuth.svelte @@ -3,7 +3,8 @@ import { CopyInput, Modal } from '$lib/components'; import { Button, InputPassword, InputSwitch, InputText } from '$lib/elements/forms'; import { oAuthProviders, type Provider } from '$lib/stores/oauth-providers'; - import { sdk } from '$lib/stores/sdk'; + import { getApiEndpoint } from '$lib/stores/sdk'; + import type { Models } from '@appwrite.io/console'; import { onMount } from 'svelte'; import { updateOAuth } from '../updateOAuth'; import type { Models } from '@appwrite.io/console'; @@ -68,9 +69,7 @@

URI

+ value={`${getApiEndpoint(page.params.region)}/account/sessions/oauth2/callback/${provider.key}/${projectId}`} />
diff --git a/src/routes/(console)/project-[region]-[project]/auth/(providers)/mainOAuth.svelte b/src/routes/(console)/project-[region]-[project]/auth/(providers)/mainOAuth.svelte index b2b425924..1e318f3ce 100644 --- a/src/routes/(console)/project-[region]-[project]/auth/(providers)/mainOAuth.svelte +++ b/src/routes/(console)/project-[region]-[project]/auth/(providers)/mainOAuth.svelte @@ -2,12 +2,12 @@ import { page } from '$app/state'; import { CopyInput, Modal } from '$lib/components'; import { Button, InputPassword, InputSwitch, InputText } from '$lib/elements/forms'; - import { sdk } from '$lib/stores/sdk'; import { onMount } from 'svelte'; import { updateOAuth } from '../updateOAuth'; import type { Models } from '@appwrite.io/console'; import { oAuthProviders, type Provider } from '$lib/stores/oauth-providers'; import { Link, Alert } from '@appwrite.io/pink-svelte'; + import { getApiEndpoint } from '$lib/stores/sdk'; const projectId = page.params.project; @@ -68,7 +68,7 @@

URI

+ value={`${getApiEndpoint(page.params.region)}/account/sessions/oauth2/callback/${provider.key}/${projectId}`} />
diff --git a/src/routes/(console)/project-[region]-[project]/auth/(providers)/microsoftOAuth.svelte b/src/routes/(console)/project-[region]-[project]/auth/(providers)/microsoftOAuth.svelte index 04dd375a5..a403cffac 100644 --- a/src/routes/(console)/project-[region]-[project]/auth/(providers)/microsoftOAuth.svelte +++ b/src/routes/(console)/project-[region]-[project]/auth/(providers)/microsoftOAuth.svelte @@ -3,7 +3,8 @@ import { CopyInput, Modal } from '$lib/components'; import { Button, InputPassword, InputSwitch, InputText } from '$lib/elements/forms'; import { oAuthProviders, type Provider } from '$lib/stores/oauth-providers'; - import { sdk } from '$lib/stores/sdk'; + import { getApiEndpoint } from '$lib/stores/sdk'; + import type { Models } from '@appwrite.io/console'; import { onMount } from 'svelte'; import { updateOAuth } from '../updateOAuth'; import type { Models } from '@appwrite.io/console'; @@ -75,7 +76,7 @@

URI

+ value={`${getApiEndpoint(page.params.region)}/account/sessions/oauth2/callback/${provider.key}/${projectId}`} />
diff --git a/src/routes/(console)/project-[region]-[project]/auth/(providers)/oidcOAuth.svelte b/src/routes/(console)/project-[region]-[project]/auth/(providers)/oidcOAuth.svelte index 5c7615255..d8094f854 100644 --- a/src/routes/(console)/project-[region]-[project]/auth/(providers)/oidcOAuth.svelte +++ b/src/routes/(console)/project-[region]-[project]/auth/(providers)/oidcOAuth.svelte @@ -3,7 +3,8 @@ import { CopyInput, Modal } from '$lib/components'; import { Button, InputPassword, InputSwitch, InputText } from '$lib/elements/forms'; import { oAuthProviders, type Provider } from '$lib/stores/oauth-providers'; - import { sdk } from '$lib/stores/sdk'; + import { getApiEndpoint } from '$lib/stores/sdk'; + import type { Models } from '@appwrite.io/console'; import { onMount } from 'svelte'; import { updateOAuth } from '../updateOAuth'; import type { Models } from '@appwrite.io/console'; @@ -113,7 +114,7 @@

URI

+ value={`${getApiEndpoint(page.params.region)}/account/sessions/oauth2/callback/${provider.key}/${projectId}`} />
diff --git a/src/routes/(console)/project-[region]-[project]/auth/(providers)/oktaOAuth.svelte b/src/routes/(console)/project-[region]-[project]/auth/(providers)/oktaOAuth.svelte index bce050d49..da66b7d5e 100644 --- a/src/routes/(console)/project-[region]-[project]/auth/(providers)/oktaOAuth.svelte +++ b/src/routes/(console)/project-[region]-[project]/auth/(providers)/oktaOAuth.svelte @@ -3,7 +3,8 @@ import { CopyInput, Modal } from '$lib/components'; import { Button, InputPassword, InputSwitch, InputText } from '$lib/elements/forms'; import { oAuthProviders, type Provider } from '$lib/stores/oauth-providers'; - import { sdk } from '$lib/stores/sdk'; + import { getApiEndpoint } from '$lib/stores/sdk'; + import type { Models } from '@appwrite.io/console'; import { onMount } from 'svelte'; import { updateOAuth } from '../updateOAuth'; import type { Models } from '@appwrite.io/console'; @@ -85,7 +86,7 @@

URI

+ value={`${getApiEndpoint(page.params.region)}/account/sessions/oauth2/callback/${provider.key}/${projectId}`} />
diff --git a/src/routes/(console)/project-[region]-[project]/auth/templates/+page.svelte b/src/routes/(console)/project-[region]-[project]/auth/templates/+page.svelte index 525e00491..a84edecd1 100644 --- a/src/routes/(console)/project-[region]-[project]/auth/templates/+page.svelte +++ b/src/routes/(console)/project-[region]-[project]/auth/templates/+page.svelte @@ -91,7 +91,7 @@ @@ -182,7 +182,9 @@ - diff --git a/src/routes/(console)/project-[region]-[project]/overview/platforms/[platform]/web.svelte b/src/routes/(console)/project-[region]-[project]/overview/platforms/[platform]/web.svelte index a1fdc9b10..9b7688de4 100644 --- a/src/routes/(console)/project-[region]-[project]/overview/platforms/[platform]/web.svelte +++ b/src/routes/(console)/project-[region]-[project]/overview/platforms/[platform]/web.svelte @@ -8,7 +8,7 @@ import { onMount } from 'svelte'; import { project } from '../../../store'; import { platform } from './store'; - import { hostnameRegex } from '$lib/helpers/string'; + import { extendedHostnameRegex } from '$lib/helpers/string'; let hostname: string = null; @@ -49,7 +49,7 @@ id="hostname" label="Hostname" bind:value={hostname} - pattern={hostnameRegex} + pattern={extendedHostnameRegex} patternError="Please enter a valid hostname" required placeholder="myapp.com" /> diff --git a/src/routes/(console)/project-[region]-[project]/settings/usage/[[invoice]]/+page.svelte b/src/routes/(console)/project-[region]-[project]/settings/usage/[[invoice]]/+page.svelte index a00376dcc..28cf51b1c 100644 --- a/src/routes/(console)/project-[region]-[project]/settings/usage/[[invoice]]/+page.svelte +++ b/src/routes/(console)/project-[region]-[project]/settings/usage/[[invoice]]/+page.svelte @@ -17,7 +17,7 @@ export let data; - $: baseRoute = `${base}/project-${data.project.$id}`; + $: baseRoute = `${base}/project-${data.project.region}-${data.project.$id}`; $: network = data.usage.network; $: users = data.usage.users; $: usersTotal = data.usage.usersTotal; diff --git a/src/routes/(console)/project-[region]-[project]/storage/bucket-[bucket]/+page.ts b/src/routes/(console)/project-[region]-[project]/storage/bucket-[bucket]/+page.ts index e95212ec0..5c1076987 100644 --- a/src/routes/(console)/project-[region]-[project]/storage/bucket-[bucket]/+page.ts +++ b/src/routes/(console)/project-[region]-[project]/storage/bucket-[bucket]/+page.ts @@ -3,31 +3,26 @@ import { sdk } from '$lib/stores/sdk'; import { getLimit, getPage, getSearch, pageToOffset } from '$lib/helpers/load'; import { Dependencies, PAGE_LIMIT } from '$lib/constants'; import type { PageLoad } from './$types'; -import { isCloud } from '$lib/system'; -export const load: PageLoad = async ({ params, depends, url, route, parent }) => { - const { organization } = await parent(); +export const load: PageLoad = async ({ params, depends, url, route }) => { depends(Dependencies.FILES); const page = getPage(url); const search = getSearch(url); const limit = getLimit(url, route, PAGE_LIMIT); const offset = pageToOffset(page, limit); - const [files, organizationUsage] = await Promise.all([ - sdk - .forProject(params.region, params.project) - .storage.listFiles( - params.bucket, - [Query.limit(limit), Query.offset(offset), Query.orderDesc('')], - search - ), - isCloud && organization?.$id ? sdk.forConsole.billing.listUsage(organization.$id) : null - ]); + const files = await sdk + .forProject(params.region, params.project) + .storage.listFiles( + params.bucket, + [Query.limit(limit), Query.offset(offset), Query.orderDesc('')], + search + ); + return { offset, limit, search, - files, - organizationUsage + files }; }; diff --git a/src/routes/+layout.svelte b/src/routes/+layout.svelte index dc87a9a44..f5bed4b86 100644 --- a/src/routes/+layout.svelte +++ b/src/routes/+layout.svelte @@ -293,14 +293,14 @@ input[type='radio'], input[type='checkbox']:not([class='switch']), input[type='switchbox'] { - .theme-dark &:not(:checked) { + .theme-dark &:not(:checked):not(:disabled) { background-color: transparent; /* take whatever color is behind */ border: 1px solid var(--color-mid-neutral-70, #56565c); } } input[type='checkbox'][class='switch'] { - .theme-dark &:not(:checked) { + .theme-dark &:not(:checked):not(:disabled) { background-color: var(--color-mid-neutral-70, #56565c); } } diff --git a/src/service-worker.ts b/src/service-worker.ts index b34bc0445..23f5988aa 100644 --- a/src/service-worker.ts +++ b/src/service-worker.ts @@ -3,88 +3,23 @@ /// /// -import { build, files, version, base } from '$service-worker'; +import { build, files } from '$service-worker'; const sw = self as unknown as ServiceWorkerGlobalScope; -// Create a unique cache name for this deployment -const CACHE = `cache-${version}`; - const ASSETS = [ ...build, // the app itself ...files // everything in `static` ]; +// Preload all assets sw.addEventListener('install', (event) => { - // Create a new cache and add all files to it - async function addFilesToCache() { - const cache = await caches.open(CACHE); - await cache.addAll(ASSETS); - } - - // Check if the page URL does not match the exclusion path - const shouldCache = !location.pathname.startsWith(`${base}/auth`); - if (shouldCache) { - event.waitUntil(addFilesToCache()); - } + event.waitUntil(Promise.allSettled(ASSETS.map((asset) => fetch(asset)))); }); +// Clean up all old caches left by previous service workers sw.addEventListener('activate', (event) => { - // Remove previous cached data from disk - async function deleteOldCaches() { - for (const key of await caches.keys()) { - if (key !== CACHE) await caches.delete(key); - } - } - - event.waitUntil(deleteOldCaches()); -}); - -sw.addEventListener('fetch', (event) => { - // ignore POST requests etc - if (event.request.method !== 'GET') return; - - async function respond() { - const url = new URL(event.request.url); - const cache = await caches.open(CACHE); - - // `build`/`files` can always be served from the cache - if (ASSETS.includes(url.pathname)) { - const response = await cache.match(url.pathname); - - if (response) { - return response; - } - } - - // for everything else, try the network first, but - // fall back to the cache if we're offline - try { - const response = await fetch(event.request); - - // if we're offline, fetch can return a value that is not a Response - // instead of throwing - and we can't pass this non-Response to respondWith - if (!(response instanceof Response)) { - throw new Error('invalid response from fetch'); - } - - if (response.status === 200) { - cache.put(event.request, response.clone()); - } - - return response; - } catch (err) { - const response = await cache.match(event.request); - - if (response) { - return response; - } - - // if there's no cache, then just error out - // as there is nothing we can do to respond to this request - throw err; - } - } - - event.respondWith(respond()); + event.waitUntil( + caches.keys().then((keys) => Promise.all(keys.map((key) => caches.delete(key)))) + ); }); diff --git a/static/legal/dpa.pdf b/static/legal/dpa.pdf index 41a3d0b42..554d12bb2 100644 Binary files a/static/legal/dpa.pdf and b/static/legal/dpa.pdf differ diff --git a/vitest-setup-client.ts b/vitest-setup-client.ts index a6d211c31..88edcb458 100644 --- a/vitest-setup-client.ts +++ b/vitest-setup-client.ts @@ -16,15 +16,21 @@ Object.defineProperty(window, 'matchMedia', { }); beforeAll(() => { + vi.mock('$app/environment', () => ({ + dev: true, + building: true, + browser: true, + page: { + params: { + project: 'tests', + region: 'tests' + } + } + })); vi.mock('$app/navigation', () => ({ goto: vi.fn(), beforeNavigate: vi.fn() })); - vi.mock('$app/environment', () => ({ - dev: true, - browser: true, - building: true - })); vi.mock('$env/static/public', () => import.meta.env); vi.mock('$env/dynamic/public', () => ({ env: import.meta.env