mirror of
https://github.com/pocket-id/pocket-id.git
synced 2026-02-27 15:33:54 +00:00
Compare commits
2 Commits
main
...
frontend-p
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
db0ab5efc7 | ||
|
|
4fa3f4b4fc |
@@ -8,8 +8,10 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
"io/fs"
|
||||
"mime"
|
||||
"net/http"
|
||||
"os"
|
||||
"path"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
@@ -58,9 +60,16 @@ func RegisterFrontend(router *gin.Engine, rateLimitMiddleware gin.HandlerFunc) e
|
||||
return fmt.Errorf("failed to create sub FS: %w", err)
|
||||
}
|
||||
|
||||
cacheMaxAge := time.Hour * 24
|
||||
fileServer := NewFileServerWithCaching(http.FS(distFS), int(cacheMaxAge.Seconds()))
|
||||
// Load a map of all files to see which ones are available pre-compressed
|
||||
preCompressed, err := listPreCompressedAssets(distFS)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to index pre-compressed frontend assets: %w", err)
|
||||
}
|
||||
|
||||
// Init the file server
|
||||
fileServer := NewFileServerWithCaching(http.FS(distFS), preCompressed)
|
||||
|
||||
// Handler for Gin
|
||||
handler := func(c *gin.Context) {
|
||||
path := strings.TrimPrefix(c.Request.URL.Path, "/")
|
||||
|
||||
@@ -108,34 +117,138 @@ func RegisterFrontend(router *gin.Engine, rateLimitMiddleware gin.HandlerFunc) e
|
||||
type FileServerWithCaching struct {
|
||||
root http.FileSystem
|
||||
lastModified time.Time
|
||||
cacheMaxAge int
|
||||
lastModifiedHeaderValue string
|
||||
cacheControlHeaderValue string
|
||||
preCompressed preCompressedMap
|
||||
}
|
||||
|
||||
func NewFileServerWithCaching(root http.FileSystem, maxAge int) *FileServerWithCaching {
|
||||
func NewFileServerWithCaching(root http.FileSystem, preCompressed preCompressedMap) *FileServerWithCaching {
|
||||
return &FileServerWithCaching{
|
||||
root: root,
|
||||
lastModified: time.Now(),
|
||||
cacheMaxAge: maxAge,
|
||||
lastModifiedHeaderValue: time.Now().UTC().Format(http.TimeFormat),
|
||||
cacheControlHeaderValue: fmt.Sprintf("public, max-age=%d", maxAge),
|
||||
preCompressed: preCompressed,
|
||||
}
|
||||
}
|
||||
|
||||
func (f *FileServerWithCaching) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
// Check if the client has a cached version
|
||||
if ifModifiedSince := r.Header.Get("If-Modified-Since"); ifModifiedSince != "" {
|
||||
ifModifiedSinceTime, err := time.Parse(http.TimeFormat, ifModifiedSince)
|
||||
if err == nil && f.lastModified.Before(ifModifiedSinceTime.Add(1*time.Second)) {
|
||||
// Client's cached version is up to date
|
||||
w.WriteHeader(http.StatusNotModified)
|
||||
return
|
||||
// First, set cache headers
|
||||
// Check if the request is for an immutable asset
|
||||
if isImmutableAsset(r) {
|
||||
// Set the cache control header as immutable with a long expiration
|
||||
w.Header().Set("Cache-Control", "public, max-age=31536000, immutable")
|
||||
} else {
|
||||
// Check if the client has a cached version
|
||||
ifModifiedSince := r.Header.Get("If-Modified-Since")
|
||||
if ifModifiedSince != "" {
|
||||
ifModifiedSinceTime, err := time.Parse(http.TimeFormat, ifModifiedSince)
|
||||
if err == nil && f.lastModified.Before(ifModifiedSinceTime.Add(1*time.Second)) {
|
||||
// Client's cached version is up to date
|
||||
w.WriteHeader(http.StatusNotModified)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// Cache other assets for up to 24 hours, but set Last-Modified too
|
||||
w.Header().Set("Last-Modified", f.lastModifiedHeaderValue)
|
||||
w.Header().Set("Cache-Control", "public, max-age=86400")
|
||||
}
|
||||
|
||||
// Check if the asset is available pre-compressed
|
||||
_, ok := f.preCompressed[r.URL.Path]
|
||||
if ok {
|
||||
// Add a "Vary" with "Accept-Encoding" so CDNs are aware that content is pre-compressed
|
||||
w.Header().Add("Vary", "Accept-Encoding")
|
||||
|
||||
// Select the encoding if any
|
||||
ext, ce := f.selectEncoding(r)
|
||||
if ext != "" {
|
||||
// Set the content type explicitly before changing the path
|
||||
ct := mime.TypeByExtension(path.Ext(r.URL.Path))
|
||||
if ct != "" {
|
||||
w.Header().Set("Content-Type", ct)
|
||||
}
|
||||
|
||||
// Make the serve return the encoded content
|
||||
w.Header().Set("Content-Encoding", ce)
|
||||
r.URL.Path += "." + ext
|
||||
}
|
||||
}
|
||||
|
||||
w.Header().Set("Last-Modified", f.lastModifiedHeaderValue)
|
||||
w.Header().Set("Cache-Control", f.cacheControlHeaderValue)
|
||||
|
||||
http.FileServer(f.root).ServeHTTP(w, r)
|
||||
}
|
||||
|
||||
func (f *FileServerWithCaching) selectEncoding(r *http.Request) (ext string, contentEnc string) {
|
||||
available, ok := f.preCompressed[r.URL.Path]
|
||||
if !ok {
|
||||
return "", ""
|
||||
}
|
||||
|
||||
// Check if the client accepts compressed files
|
||||
acceptEncoding := strings.TrimSpace(strings.ToLower(r.Header.Get("Accept-Encoding")))
|
||||
if acceptEncoding == "" {
|
||||
return "", ""
|
||||
}
|
||||
|
||||
// Prefer brotli over gzip when both are accepted.
|
||||
if available.br && (acceptEncoding == "*" || acceptEncoding == "br" || strings.Contains(acceptEncoding, "br")) {
|
||||
return "br", "br"
|
||||
}
|
||||
if available.gz && (acceptEncoding == "gzip" || strings.Contains(acceptEncoding, "gzip")) {
|
||||
return "gz", "gzip"
|
||||
}
|
||||
|
||||
return "", ""
|
||||
}
|
||||
|
||||
func isImmutableAsset(r *http.Request) bool {
|
||||
switch {
|
||||
// Fonts
|
||||
case strings.HasPrefix(r.URL.Path, "/fonts/"):
|
||||
return true
|
||||
|
||||
// Compiled SvelteKit assets
|
||||
case strings.HasPrefix(r.URL.Path, "/_app/immutable/"):
|
||||
return true
|
||||
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
type preCompressedMap map[string]struct {
|
||||
br bool
|
||||
gz bool
|
||||
}
|
||||
|
||||
func listPreCompressedAssets(distFS fs.FS) (preCompressedMap, error) {
|
||||
preCompressed := make(preCompressedMap, 0)
|
||||
err := fs.WalkDir(distFS, ".", func(path string, d fs.DirEntry, walkErr error) error {
|
||||
if walkErr != nil {
|
||||
return walkErr
|
||||
}
|
||||
|
||||
if d.IsDir() {
|
||||
return nil
|
||||
}
|
||||
|
||||
switch {
|
||||
case strings.HasSuffix(path, ".br"):
|
||||
originalPath := "/" + strings.TrimSuffix(path, ".br")
|
||||
entry := preCompressed[originalPath]
|
||||
entry.br = true
|
||||
preCompressed[originalPath] = entry
|
||||
case strings.HasSuffix(path, ".gz"):
|
||||
originalPath := "/" + strings.TrimSuffix(path, ".gz")
|
||||
entry := preCompressed[originalPath]
|
||||
entry.gz = true
|
||||
preCompressed[originalPath] = entry
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return preCompressed, nil
|
||||
}
|
||||
|
||||
@@ -5,4 +5,5 @@ yarn.lock
|
||||
|
||||
# Compiled files
|
||||
.svelte-kit/
|
||||
build/
|
||||
build/
|
||||
src/lib/paraglide/messages
|
||||
@@ -1,63 +1,64 @@
|
||||
{
|
||||
"name": "pocket-id-frontend",
|
||||
"version": "2.3.0",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"preinstall": "npx only-allow pnpm",
|
||||
"dev": "vite dev --port 3000",
|
||||
"build": "vite build",
|
||||
"preview": "vite preview --port 3000",
|
||||
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
|
||||
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
|
||||
"lint": "prettier --check . && eslint .",
|
||||
"format": "prettier --write ."
|
||||
},
|
||||
"dependencies": {
|
||||
"@simplewebauthn/browser": "^13.2.2",
|
||||
"@tailwindcss/vite": "^4.2.0",
|
||||
"axios": "^1.13.5",
|
||||
"clsx": "^2.1.1",
|
||||
"date-fns": "^4.1.0",
|
||||
"jose": "^6.1.3",
|
||||
"qrcode": "^1.5.4",
|
||||
"runed": "^0.37.1",
|
||||
"sveltekit-superforms": "^2.30.0",
|
||||
"tailwind-merge": "^3.5.0",
|
||||
"zod": "^4.3.6"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@inlang/paraglide-js": "^2.12.0",
|
||||
"@inlang/plugin-m-function-matcher": "^2.2.1",
|
||||
"@inlang/plugin-message-format": "^4.3.0",
|
||||
"@internationalized/date": "^3.11.0",
|
||||
"@lucide/svelte": "^0.559.0",
|
||||
"@sveltejs/adapter-static": "^3.0.10",
|
||||
"@sveltejs/kit": "^2.53.0",
|
||||
"@sveltejs/vite-plugin-svelte": "^6.2.4",
|
||||
"@types/eslint": "^9.6.1",
|
||||
"@types/node": "^24.10.13",
|
||||
"@types/qrcode": "^1.5.6",
|
||||
"bits-ui": "^2.16.2",
|
||||
"eslint": "^9.39.3",
|
||||
"eslint-config-prettier": "^10.1.8",
|
||||
"eslint-plugin-svelte": "^3.15.0",
|
||||
"formsnap": "^2.0.1",
|
||||
"globals": "^16.5.0",
|
||||
"mode-watcher": "^1.1.0",
|
||||
"prettier": "^3.8.1",
|
||||
"prettier-plugin-svelte": "^3.5.0",
|
||||
"prettier-plugin-tailwindcss": "^0.7.2",
|
||||
"rollup": "^4.59.0",
|
||||
"svelte": "^5.53.2",
|
||||
"svelte-check": "^4.4.3",
|
||||
"svelte-sonner": "^1.0.7",
|
||||
"tailwind-variants": "^3.2.2",
|
||||
"tailwindcss": "^4.2.0",
|
||||
"tslib": "^2.8.1",
|
||||
"tw-animate-css": "^1.4.0",
|
||||
"typescript": "^5.9.3",
|
||||
"typescript-eslint": "^8.56.0",
|
||||
"vite": "^7.3.1"
|
||||
}
|
||||
"name": "pocket-id-frontend",
|
||||
"version": "2.3.0",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"preinstall": "npx only-allow pnpm",
|
||||
"dev": "vite dev --port 3000",
|
||||
"build": "vite build",
|
||||
"preview": "vite preview --port 3000",
|
||||
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
|
||||
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
|
||||
"lint": "prettier --check . && eslint .",
|
||||
"format": "prettier --write ."
|
||||
},
|
||||
"dependencies": {
|
||||
"@simplewebauthn/browser": "^13.2.2",
|
||||
"@tailwindcss/vite": "^4.2.0",
|
||||
"axios": "^1.13.5",
|
||||
"clsx": "^2.1.1",
|
||||
"date-fns": "^4.1.0",
|
||||
"jose": "^6.1.3",
|
||||
"qrcode": "^1.5.4",
|
||||
"runed": "^0.37.1",
|
||||
"sveltekit-superforms": "^2.30.0",
|
||||
"tailwind-merge": "^3.5.0",
|
||||
"zod": "^4.3.6"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@inlang/paraglide-js": "^2.12.0",
|
||||
"@inlang/plugin-m-function-matcher": "^2.2.1",
|
||||
"@inlang/plugin-message-format": "^4.3.0",
|
||||
"@internationalized/date": "^3.11.0",
|
||||
"@lucide/svelte": "^0.559.0",
|
||||
"@sveltejs/adapter-static": "^3.0.10",
|
||||
"@sveltejs/kit": "^2.53.0",
|
||||
"@sveltejs/vite-plugin-svelte": "^6.2.4",
|
||||
"@types/eslint": "^9.6.1",
|
||||
"@types/node": "^24.10.13",
|
||||
"@types/qrcode": "^1.5.6",
|
||||
"bits-ui": "^2.16.2",
|
||||
"eslint": "^9.39.3",
|
||||
"eslint-config-prettier": "^10.1.8",
|
||||
"eslint-plugin-svelte": "^3.15.0",
|
||||
"formsnap": "^2.0.1",
|
||||
"globals": "^16.5.0",
|
||||
"mode-watcher": "^1.1.0",
|
||||
"prettier": "^3.8.1",
|
||||
"prettier-plugin-svelte": "^3.5.0",
|
||||
"prettier-plugin-tailwindcss": "^0.7.2",
|
||||
"rollup": "^4.59.0",
|
||||
"svelte": "^5.53.2",
|
||||
"svelte-check": "^4.4.3",
|
||||
"svelte-sonner": "^1.0.7",
|
||||
"tailwind-variants": "^3.2.2",
|
||||
"tailwindcss": "^4.2.0",
|
||||
"tslib": "^2.8.1",
|
||||
"tw-animate-css": "^1.4.0",
|
||||
"typescript": "^5.9.3",
|
||||
"typescript-eslint": "^8.56.0",
|
||||
"vite": "^7.3.1",
|
||||
"vite-plugin-compression": "^0.5.1"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,28 +2,47 @@ import { paraglideVitePlugin } from '@inlang/paraglide-js';
|
||||
import { sveltekit } from '@sveltejs/kit/vite';
|
||||
import tailwindcss from '@tailwindcss/vite';
|
||||
import { defineConfig } from 'vite';
|
||||
import viteCompression from 'vite-plugin-compression';
|
||||
|
||||
export default defineConfig({
|
||||
plugins: [
|
||||
sveltekit(),
|
||||
tailwindcss(),
|
||||
paraglideVitePlugin({
|
||||
project: './project.inlang',
|
||||
outdir: './src/lib/paraglide',
|
||||
cookieName: 'locale',
|
||||
strategy: ['cookie', 'preferredLanguage', 'baseLocale']
|
||||
})
|
||||
],
|
||||
export default defineConfig((mode) => {
|
||||
return {
|
||||
plugins: [
|
||||
sveltekit(),
|
||||
tailwindcss(),
|
||||
paraglideVitePlugin({
|
||||
project: './project.inlang',
|
||||
outdir: './src/lib/paraglide',
|
||||
cookieName: 'locale',
|
||||
strategy: ['cookie', 'preferredLanguage', 'baseLocale']
|
||||
}),
|
||||
|
||||
server: {
|
||||
host: process.env.HOST,
|
||||
proxy: {
|
||||
'/api': {
|
||||
target: process.env.DEVELOPMENT_BACKEND_URL || 'http://localhost:1411'
|
||||
},
|
||||
'/.well-known': {
|
||||
target: process.env.DEVELOPMENT_BACKEND_URL || 'http://localhost:1411'
|
||||
// Create gzip-compressed files
|
||||
viteCompression({
|
||||
disable: mode.isPreview,
|
||||
algorithm: 'gzip',
|
||||
ext: '.gz',
|
||||
filter: /\.(js|mjs|json|css)$/i
|
||||
}),
|
||||
|
||||
// Create brotli-compressed files
|
||||
viteCompression({
|
||||
disable: mode.isPreview,
|
||||
algorithm: 'brotliCompress',
|
||||
ext: '.br',
|
||||
filter: /\.(js|mjs|json|css)$/i
|
||||
})
|
||||
],
|
||||
|
||||
server: {
|
||||
host: process.env.HOST,
|
||||
proxy: {
|
||||
'/api': {
|
||||
target: process.env.DEVELOPMENT_BACKEND_URL || 'http://localhost:1411'
|
||||
},
|
||||
'/.well-known': {
|
||||
target: process.env.DEVELOPMENT_BACKEND_URL || 'http://localhost:1411'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
83
pnpm-lock.yaml
generated
83
pnpm-lock.yaml
generated
@@ -184,6 +184,9 @@ importers:
|
||||
vite:
|
||||
specifier: ^7.3.1
|
||||
version: 7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.1)
|
||||
vite-plugin-compression:
|
||||
specifier: ^0.5.1
|
||||
version: 0.5.1(vite@7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.1))
|
||||
|
||||
tests:
|
||||
dependencies:
|
||||
@@ -832,89 +835,105 @@ packages:
|
||||
resolution: {integrity: sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw==}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@img/sharp-libvips-linux-arm@1.2.4':
|
||||
resolution: {integrity: sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A==}
|
||||
cpu: [arm]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@img/sharp-libvips-linux-ppc64@1.2.4':
|
||||
resolution: {integrity: sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA==}
|
||||
cpu: [ppc64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@img/sharp-libvips-linux-riscv64@1.2.4':
|
||||
resolution: {integrity: sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA==}
|
||||
cpu: [riscv64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@img/sharp-libvips-linux-s390x@1.2.4':
|
||||
resolution: {integrity: sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ==}
|
||||
cpu: [s390x]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@img/sharp-libvips-linux-x64@1.2.4':
|
||||
resolution: {integrity: sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw==}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@img/sharp-libvips-linuxmusl-arm64@1.2.4':
|
||||
resolution: {integrity: sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw==}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@img/sharp-libvips-linuxmusl-x64@1.2.4':
|
||||
resolution: {integrity: sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg==}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@img/sharp-linux-arm64@0.34.5':
|
||||
resolution: {integrity: sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@img/sharp-linux-arm@0.34.5':
|
||||
resolution: {integrity: sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
cpu: [arm]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@img/sharp-linux-ppc64@0.34.5':
|
||||
resolution: {integrity: sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
cpu: [ppc64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@img/sharp-linux-riscv64@0.34.5':
|
||||
resolution: {integrity: sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
cpu: [riscv64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@img/sharp-linux-s390x@0.34.5':
|
||||
resolution: {integrity: sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
cpu: [s390x]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@img/sharp-linux-x64@0.34.5':
|
||||
resolution: {integrity: sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@img/sharp-linuxmusl-arm64@0.34.5':
|
||||
resolution: {integrity: sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@img/sharp-linuxmusl-x64@0.34.5':
|
||||
resolution: {integrity: sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@img/sharp-wasm32@0.34.5':
|
||||
resolution: {integrity: sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw==}
|
||||
@@ -1010,24 +1029,28 @@ packages:
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@next/swc-linux-arm64-musl@16.1.6':
|
||||
resolution: {integrity: sha512-S4J2v+8tT3NIO9u2q+S0G5KdvNDjXfAv06OhfOzNDaBn5rw84DGXWndOEB7d5/x852A20sW1M56vhC/tRVbccQ==}
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@next/swc-linux-x64-gnu@16.1.6':
|
||||
resolution: {integrity: sha512-2eEBDkFlMMNQnkTyPBhQOAyn2qMxyG2eE7GPH2WIDGEpEILcBPI/jdSv4t6xupSP+ot/jkfrCShLAa7+ZUPcJQ==}
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@next/swc-linux-x64-musl@16.1.6':
|
||||
resolution: {integrity: sha512-oicJwRlyOoZXVlxmIMaTq7f8pN9QNbdes0q2FXfRsPhfCi8n8JmOZJm5oo1pwDaFbnnD421rVU409M3evFbIqg==}
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@next/swc-win32-arm64-msvc@16.1.6':
|
||||
resolution: {integrity: sha512-gQmm8izDTPgs+DCWH22kcDmuUp7NyiJgEl18bcr8irXA5N2m2O+JQIr6f3ct42GOs9c0h8QF3L5SzIxcYAAXXw==}
|
||||
@@ -1246,66 +1269,79 @@ packages:
|
||||
resolution: {integrity: sha512-t4ONHboXi/3E0rT6OZl1pKbl2Vgxf9vJfWgmUoCEVQVxhW6Cw/c8I6hbbu7DAvgp82RKiH7TpLwxnJeKv2pbsw==}
|
||||
cpu: [arm]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@rollup/rollup-linux-arm-musleabihf@4.59.0':
|
||||
resolution: {integrity: sha512-CikFT7aYPA2ufMD086cVORBYGHffBo4K8MQ4uPS/ZnY54GKj36i196u8U+aDVT2LX4eSMbyHtyOh7D7Zvk2VvA==}
|
||||
cpu: [arm]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@rollup/rollup-linux-arm64-gnu@4.59.0':
|
||||
resolution: {integrity: sha512-jYgUGk5aLd1nUb1CtQ8E+t5JhLc9x5WdBKew9ZgAXg7DBk0ZHErLHdXM24rfX+bKrFe+Xp5YuJo54I5HFjGDAA==}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@rollup/rollup-linux-arm64-musl@4.59.0':
|
||||
resolution: {integrity: sha512-peZRVEdnFWZ5Bh2KeumKG9ty7aCXzzEsHShOZEFiCQlDEepP1dpUl/SrUNXNg13UmZl+gzVDPsiCwnV1uI0RUA==}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@rollup/rollup-linux-loong64-gnu@4.59.0':
|
||||
resolution: {integrity: sha512-gbUSW/97f7+r4gHy3Jlup8zDG190AuodsWnNiXErp9mT90iCy9NKKU0Xwx5k8VlRAIV2uU9CsMnEFg/xXaOfXg==}
|
||||
cpu: [loong64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@rollup/rollup-linux-loong64-musl@4.59.0':
|
||||
resolution: {integrity: sha512-yTRONe79E+o0FWFijasoTjtzG9EBedFXJMl888NBEDCDV9I2wGbFFfJQQe63OijbFCUZqxpHz1GzpbtSFikJ4Q==}
|
||||
cpu: [loong64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@rollup/rollup-linux-ppc64-gnu@4.59.0':
|
||||
resolution: {integrity: sha512-sw1o3tfyk12k3OEpRddF68a1unZ5VCN7zoTNtSn2KndUE+ea3m3ROOKRCZxEpmT9nsGnogpFP9x6mnLTCaoLkA==}
|
||||
cpu: [ppc64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@rollup/rollup-linux-ppc64-musl@4.59.0':
|
||||
resolution: {integrity: sha512-+2kLtQ4xT3AiIxkzFVFXfsmlZiG5FXYW7ZyIIvGA7Bdeuh9Z0aN4hVyXS/G1E9bTP/vqszNIN/pUKCk/BTHsKA==}
|
||||
cpu: [ppc64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@rollup/rollup-linux-riscv64-gnu@4.59.0':
|
||||
resolution: {integrity: sha512-NDYMpsXYJJaj+I7UdwIuHHNxXZ/b/N2hR15NyH3m2qAtb/hHPA4g4SuuvrdxetTdndfj9b1WOmy73kcPRoERUg==}
|
||||
cpu: [riscv64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@rollup/rollup-linux-riscv64-musl@4.59.0':
|
||||
resolution: {integrity: sha512-nLckB8WOqHIf1bhymk+oHxvM9D3tyPndZH8i8+35p/1YiVoVswPid2yLzgX7ZJP0KQvnkhM4H6QZ5m0LzbyIAg==}
|
||||
cpu: [riscv64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@rollup/rollup-linux-s390x-gnu@4.59.0':
|
||||
resolution: {integrity: sha512-oF87Ie3uAIvORFBpwnCvUzdeYUqi2wY6jRFWJAy1qus/udHFYIkplYRW+wo+GRUP4sKzYdmE1Y3+rY5Gc4ZO+w==}
|
||||
cpu: [s390x]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@rollup/rollup-linux-x64-gnu@4.59.0':
|
||||
resolution: {integrity: sha512-3AHmtQq/ppNuUspKAlvA8HtLybkDflkMuLK4DPo77DfthRb71V84/c4MlWJXixZz4uruIH4uaa07IqoAkG64fg==}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@rollup/rollup-linux-x64-musl@4.59.0':
|
||||
resolution: {integrity: sha512-2UdiwS/9cTAx7qIUZB/fWtToJwvt0Vbo0zmnYt7ED35KPg13Q0ym1g442THLC7VyI6JfYTP4PiSOWyoMdV2/xg==}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@rollup/rollup-openbsd-x64@4.59.0':
|
||||
resolution: {integrity: sha512-M3bLRAVk6GOwFlPTIxVBSYKUaqfLrn8l0psKinkCFxl4lQvOSz8ZrKDz2gxcBwHFpci0B6rttydI4IpS4IS/jQ==}
|
||||
@@ -1450,24 +1486,28 @@ packages:
|
||||
engines: {node: '>= 20'}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@tailwindcss/oxide-linux-arm64-musl@4.2.0':
|
||||
resolution: {integrity: sha512-XKcSStleEVnbH6W/9DHzZv1YhjE4eSS6zOu2eRtYAIh7aV4o3vIBs+t/B15xlqoxt6ef/0uiqJVB6hkHjWD/0A==}
|
||||
engines: {node: '>= 20'}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@tailwindcss/oxide-linux-x64-gnu@4.2.0':
|
||||
resolution: {integrity: sha512-/hlXCBqn9K6fi7eAM0RsobHwJYa5V/xzWspVTzxnX+Ft9v6n+30Pz8+RxCn7sQL/vRHHLS30iQPrHQunu6/vJA==}
|
||||
engines: {node: '>= 20'}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@tailwindcss/oxide-linux-x64-musl@4.2.0':
|
||||
resolution: {integrity: sha512-lKUaygq4G7sWkhQbfdRRBkaq4LY39IriqBQ+Gk6l5nKq6Ay2M2ZZb1tlIyRNgZKS8cbErTwuYSor0IIULC0SHw==}
|
||||
engines: {node: '>= 20'}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@tailwindcss/oxide-wasm32-wasi@4.2.0':
|
||||
resolution: {integrity: sha512-xuDjhAsFdUuFP5W9Ze4k/o4AskUtI8bcAGU4puTYprr89QaYFmhYOPfP+d1pH+k9ets6RoE23BXZM1X1jJqoyw==}
|
||||
@@ -2162,6 +2202,10 @@ packages:
|
||||
svelte: ^5.0.0
|
||||
sveltekit-superforms: ^2.19.0
|
||||
|
||||
fs-extra@10.1.0:
|
||||
resolution: {integrity: sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
fsevents@2.3.2:
|
||||
resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==}
|
||||
engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
|
||||
@@ -2346,6 +2390,9 @@ packages:
|
||||
engines: {node: '>=6'}
|
||||
hasBin: true
|
||||
|
||||
jsonfile@6.2.0:
|
||||
resolution: {integrity: sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==}
|
||||
|
||||
keyv@4.5.4:
|
||||
resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==}
|
||||
|
||||
@@ -2409,24 +2456,28 @@ packages:
|
||||
engines: {node: '>= 12.0.0'}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
lightningcss-linux-arm64-musl@1.31.1:
|
||||
resolution: {integrity: sha512-mVZ7Pg2zIbe3XlNbZJdjs86YViQFoJSpc41CbVmKBPiGmC4YrfeOyz65ms2qpAobVd7WQsbW4PdsSJEMymyIMg==}
|
||||
engines: {node: '>= 12.0.0'}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
lightningcss-linux-x64-gnu@1.31.1:
|
||||
resolution: {integrity: sha512-xGlFWRMl+0KvUhgySdIaReQdB4FNudfUTARn7q0hh/V67PVGCs3ADFjw+6++kG1RNd0zdGRlEKa+T13/tQjPMA==}
|
||||
engines: {node: '>= 12.0.0'}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
lightningcss-linux-x64-musl@1.31.1:
|
||||
resolution: {integrity: sha512-eowF8PrKHw9LpoZii5tdZwnBcYDxRw2rRCyvAXLi34iyeYfqCQNA9rmUM0ce62NlPhCvof1+9ivRaTY6pSKDaA==}
|
||||
engines: {node: '>= 12.0.0'}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
lightningcss-win32-arm64-msvc@1.31.1:
|
||||
resolution: {integrity: sha512-aJReEbSEQzx1uBlQizAOBSjcmr9dCdL3XuC/6HLXAxmtErsj2ICo5yYggg1qOODQMtnjNQv2UHb9NpOuFtYe4w==}
|
||||
@@ -3195,6 +3246,10 @@ packages:
|
||||
undici-types@7.16.0:
|
||||
resolution: {integrity: sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==}
|
||||
|
||||
universalify@2.0.1:
|
||||
resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==}
|
||||
engines: {node: '>= 10.0.0'}
|
||||
|
||||
unplugin@2.3.11:
|
||||
resolution: {integrity: sha512-5uKD0nqiYVzlmCRs01Fhs2BdkEgBS3SAVP6ndrBsuK42iC2+JHyxM05Rm9G8+5mkmRtzMZGY8Ct5+mliZxU/Ww==}
|
||||
engines: {node: '>=18.12.0'}
|
||||
@@ -3232,6 +3287,11 @@ packages:
|
||||
resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==}
|
||||
engines: {node: '>= 0.8'}
|
||||
|
||||
vite-plugin-compression@0.5.1:
|
||||
resolution: {integrity: sha512-5QJKBDc+gNYVqL/skgFAP81Yuzo9R+EAf19d+EtsMF/i8kFUpNi3J/H01QD3Oo8zBQn+NzoCIFkpPLynoOzaJg==}
|
||||
peerDependencies:
|
||||
vite: '>=2.0.0'
|
||||
|
||||
vite@7.3.1:
|
||||
resolution: {integrity: sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
@@ -5069,6 +5129,12 @@ snapshots:
|
||||
svelte-toolbelt: 0.5.0(svelte@5.53.2)
|
||||
sveltekit-superforms: 2.30.0(@sveltejs/kit@2.53.0(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.53.2)(vite@7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.1)))(svelte@5.53.2)(typescript@5.9.3)(vite@7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.1)))(@types/json-schema@7.0.15)(svelte@5.53.2)(typescript@5.9.3)
|
||||
|
||||
fs-extra@10.1.0:
|
||||
dependencies:
|
||||
graceful-fs: 4.2.11
|
||||
jsonfile: 6.2.0
|
||||
universalify: 2.0.1
|
||||
|
||||
fsevents@2.3.2:
|
||||
optional: true
|
||||
|
||||
@@ -5226,6 +5292,12 @@ snapshots:
|
||||
|
||||
json5@2.2.3: {}
|
||||
|
||||
jsonfile@6.2.0:
|
||||
dependencies:
|
||||
universalify: 2.0.1
|
||||
optionalDependencies:
|
||||
graceful-fs: 4.2.11
|
||||
|
||||
keyv@4.5.4:
|
||||
dependencies:
|
||||
json-buffer: 3.0.1
|
||||
@@ -6050,6 +6122,8 @@ snapshots:
|
||||
|
||||
undici-types@7.16.0: {}
|
||||
|
||||
universalify@2.0.1: {}
|
||||
|
||||
unplugin@2.3.11:
|
||||
dependencies:
|
||||
'@jridgewell/remapping': 2.3.5
|
||||
@@ -6079,6 +6153,15 @@ snapshots:
|
||||
|
||||
vary@1.1.2: {}
|
||||
|
||||
vite-plugin-compression@0.5.1(vite@7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.1)):
|
||||
dependencies:
|
||||
chalk: 4.1.2
|
||||
debug: 4.4.3
|
||||
fs-extra: 10.1.0
|
||||
vite: 7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.1)
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
vite@7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.1):
|
||||
dependencies:
|
||||
esbuild: 0.27.3
|
||||
|
||||
@@ -3,12 +3,16 @@ packages:
|
||||
- tests
|
||||
- email-templates
|
||||
|
||||
onlyBuiltDependencies:
|
||||
- esbuild
|
||||
- sharp
|
||||
|
||||
overrides:
|
||||
cookie@<0.7.0: ">=0.7.0"
|
||||
'@isaacs/brace-expansion': '>=5.0.1'
|
||||
cookie@<0.7.0: '>=0.7.0'
|
||||
devalue: ^5.6.2
|
||||
glob@>=11.0.0 <11.1.0: ">=11.1.0"
|
||||
js-yaml@>=4.0.0 <4.1.1: ">=4.1.1"
|
||||
valibot@>=0.31.0 <1.2.0: ">=1.2.0"
|
||||
validator@<13.15.20: ">=13.15.20"
|
||||
"@isaacs/brace-expansion": ">=5.0.1"
|
||||
next: ">=16.1.5"
|
||||
glob@>=11.0.0 <11.1.0: '>=11.1.0'
|
||||
js-yaml@>=4.0.0 <4.1.1: '>=4.1.1'
|
||||
next: '>=16.1.5'
|
||||
valibot@>=0.31.0 <1.2.0: '>=1.2.0'
|
||||
validator@<13.15.20: '>=13.15.20'
|
||||
|
||||
Reference in New Issue
Block a user