You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
174 lines
5.4 KiB
174 lines
5.4 KiB
import react from '@vitejs/plugin-react' |
|
import { execSync } from 'child_process' |
|
import path from 'path' |
|
import { defineConfig } from 'vitest/config' |
|
import { VitePWA } from 'vite-plugin-pwa' |
|
import packageJson from './package.json' |
|
/// <reference types="vitest" /> |
|
|
|
const getGitHash = () => { |
|
try { |
|
return JSON.stringify(execSync('git rev-parse --short HEAD').toString().trim()) |
|
} catch (error) { |
|
console.warn('Failed to retrieve commit hash:', error) |
|
return '"unknown"' |
|
} |
|
} |
|
|
|
const getAppVersion = () => { |
|
try { |
|
return JSON.stringify(packageJson.version) |
|
} catch (error) { |
|
console.warn('Failed to retrieve app version:', error) |
|
return '"unknown"' |
|
} |
|
} |
|
|
|
// https://vite.dev/config/ |
|
export default defineConfig({ |
|
define: { |
|
'import.meta.env.GIT_COMMIT': getGitHash(), |
|
'import.meta.env.APP_VERSION': getAppVersion() |
|
}, |
|
resolve: { |
|
alias: { |
|
'@': path.resolve(__dirname, './src') |
|
} |
|
}, |
|
build: { |
|
rollupOptions: { |
|
onwarn(warning, warn) { |
|
// Suppress vite:reporter warnings about mixed static/dynamic imports |
|
// These are informational warnings about code splitting, not errors |
|
if (warning.plugin === 'vite:reporter' && warning.message.includes('dynamically imported') && warning.message.includes('statically imported')) { |
|
return |
|
} |
|
// Use default warning handler for other warnings |
|
warn(warning) |
|
} |
|
} |
|
}, |
|
test: { |
|
globals: true, |
|
environment: 'jsdom', |
|
setupFiles: './src/test/setup.ts' |
|
}, |
|
plugins: [ |
|
react(), |
|
VitePWA({ |
|
registerType: 'autoUpdate', |
|
workbox: { |
|
globPatterns: ['**/*.{js,css,html,png,jpg,svg,ico,webmanifest}'], |
|
globDirectory: 'dist/', |
|
maximumFileSizeToCacheInBytes: 5 * 1024 * 1024, |
|
cleanupOutdatedCaches: true, |
|
skipWaiting: true, |
|
clientsClaim: true, |
|
navigateFallback: '/index.html', |
|
navigateFallbackDenylist: [/^\/api\//, /^\/_/, /^\/admin/], |
|
// Exclude source files and development files from precaching |
|
globIgnores: [ |
|
'**/src/**', |
|
'**/node_modules/**', |
|
'**/*.map', |
|
'**/sw.js', |
|
'**/workbox-*.js' |
|
], |
|
runtimeCaching: [ |
|
{ |
|
// Exclude upload endpoints from service worker handling - use NetworkOnly to bypass cache |
|
// Match various upload URL patterns - comprehensive regex to catch all upload services |
|
// This ensures uploads (POST) and discovery endpoints (GET) bypass the service worker |
|
// Note: XMLHttpRequest should bypass service workers, but we add this as a safety measure |
|
urlPattern: ({ url, request }) => { |
|
const urlString = url.toString() |
|
const method = request.method?.toUpperCase() || 'GET' |
|
|
|
// Always bypass service worker for POST requests (uploads) |
|
if (method === 'POST') { |
|
return /(?:api\/v2\/nip96\/upload|\.well-known\/nostr\/nip96\.json|nostr\.build|nostrcheck\.me|void\.cat|\/upload|\/nip96\/)/i.test(urlString) |
|
} |
|
|
|
// Also bypass for GET requests to upload-related endpoints |
|
return /(?:\.well-known\/nostr\/nip96\.json|api\/v2\/nip96\/upload)/i.test(urlString) |
|
}, |
|
handler: 'NetworkOnly' |
|
}, |
|
{ |
|
urlPattern: /^https:\/\/image\.nostr\.build\/.*/i, |
|
handler: 'CacheFirst', |
|
options: { |
|
cacheName: 'nostr-images', |
|
expiration: { |
|
maxEntries: 100, |
|
maxAgeSeconds: 30 * 24 * 60 * 60 // 30 days |
|
} |
|
} |
|
}, |
|
{ |
|
urlPattern: /^https:\/\/cdn\.satellite\.earth\/.*/i, |
|
handler: 'CacheFirst', |
|
options: { |
|
cacheName: 'satellite-images', |
|
expiration: { |
|
maxEntries: 100, |
|
maxAgeSeconds: 30 * 24 * 60 * 60 // 30 days |
|
} |
|
} |
|
}, |
|
{ |
|
urlPattern: /^https:\/\/.*\.(?:png|jpg|jpeg|svg|gif|webp)$/i, |
|
handler: 'CacheFirst', |
|
options: { |
|
cacheName: 'external-images', |
|
expiration: { |
|
maxEntries: 200, |
|
maxAgeSeconds: 7 * 24 * 60 * 60 // 7 days |
|
} |
|
} |
|
} |
|
] |
|
}, |
|
devOptions: { |
|
enabled: true, |
|
type: 'module' |
|
}, |
|
manifest: { |
|
name: 'Jumble', |
|
short_name: 'Jumble', |
|
icons: [ |
|
{ |
|
src: '/pwa-192x192.png', |
|
sizes: '192x192', |
|
type: 'image/png', |
|
purpose: 'any' |
|
}, |
|
{ |
|
src: '/pwa-512x512.png', |
|
sizes: '512x512', |
|
type: 'image/png', |
|
purpose: 'any' |
|
}, |
|
{ |
|
src: '/pwa-maskable-192x192.png', |
|
sizes: '192x192', |
|
type: 'image/png', |
|
purpose: 'maskable' |
|
}, |
|
{ |
|
src: '/pwa-maskable-512x512.png', |
|
sizes: '512x512', |
|
type: 'image/png', |
|
purpose: 'maskable' |
|
} |
|
], |
|
start_url: '/', |
|
display: 'standalone', |
|
background_color: '#FFFFFF', |
|
theme_color: '#FFFFFF', |
|
description: |
|
'A user-friendly Nostr client focused on relay feed browsing and relay discovery' |
|
} |
|
}) |
|
] |
|
})
|
|
|