Big update to deploy scripts, and deploy prosecss

This commit is contained in:
Max committed 2026-10-28 11:54:19 -07:00
1 parent 2d5d23b104
commit 590ae01055
141 files changed
+8483 -53810

No files matched your search

+98
View File
@@ -0,0 +1,98 @@
import fs from 'node:fs'
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import tailwindcss from '@tailwindcss/vite'
import { VitePWA } from 'vite-plugin-pwa'
import { fileURLToPath, URL } from 'node:url'
// Opt-in HTTPS for the dev server, off by default so the usual
// http://localhost:5173 workflow is unchanged. Only needed if you want to test
// the installed PWA from a phone over the LAN *without* using
// chrome://flags/#unsafely-treat-insecure-origin-as-secure -- and note Chrome
// needs the mkcert root CA installed on the device for the origin to be
// service-worker eligible; clicking through a cert warning is not enough.
// DEV_HTTPS=1 pnpm dev
const certDir = fileURLToPath(new URL('./certs', import.meta.url))
const keyPath = `${certDir}/192.168.1.164+4-key.pem`
const certPath = `${certDir}/192.168.1.164+4.pem`
const useHttps =
process.env.DEV_HTTPS === '1' && fs.existsSync(keyPath) && fs.existsSync(certPath)
export default defineConfig({
plugins: [
vue({
template: {
transformAssetUrls: { includeAbsolute: false },
},
}),
tailwindcss(),
VitePWA({
// Updates are user-driven via the prompt in src/registerServiceWorker.js
registerType: 'prompt',
injectRegister: false,
// Lands at dist/sw.js -- root of the served directory, so the worker gets
// root scope without needing a Service-Worker-Allowed header.
filename: 'sw.js',
// We ship public/manifest.json by hand rather than generating one.
manifest: false,
workbox: {
//
// SECURITY INVARIANT -- do not relax without thinking it through.
//
// Solid Scribe is end-to-end encrypted. The service worker precaches
// ONLY static build output and is network-only for /api/*. Caching an
// API response would write decrypted note content into Cache Storage on
// disk, where it survives logout and sits outside the encryption model.
//
// Structurally this holds because globPatterns only ever reads dist/,
// and user content is served by Express from staticFiles/ at
// /api/static -- which never enters dist. The NetworkOnly rule below is
// belt-and-braces: it documents the invariant and stops a future
// runtimeCaching entry from silently widening the net.
//
// woff2 is NOT in Workbox's default globPatterns. Without it the Roboto
// files are skipped and the offline shell renders in a fallback face.
globPatterns: ['**/*.{js,css,html,woff2,png,svg,ico,json}'],
// Vendor chunks (fomantic, chart.js) exceed the 2MiB default. An
// oversized file is silently OMITTED from the precache, which half
// breaks the offline shell -- watch the build output for a warning.
maximumFileSizeToCacheInBytes: 5 * 1024 * 1024,
navigateFallback: '/index.html',
// Matters for top-level navigations to /api/static/<file> (clicking an
// attachment link) -- without this the worker answers with index.html.
navigateFallbackDenylist: [/^\/api\//, /^\/socket/],
cleanupOutdatedCaches: true,
// Let the user decide when to swap assets, rather than doing it
// mid-session underneath them.
clientsClaim: false,
skipWaiting: false,
runtimeCaching: [
{
urlPattern: ({ url }) =>
url.pathname.startsWith('/api/') || url.pathname.startsWith('/socket'),
handler: 'NetworkOnly',
},
],
},
// Flip to true temporarily to exercise the worker on the dev server.
// Remember to unregister it afterwards -- a lingering dev service worker
// is a classic "why is my phone showing an ancient build".
devOptions: { enabled: false, type: 'module' },
}),
],
resolve: {
alias: {
'@': fileURLToPath(new URL('./src', import.meta.url)),
},
},
server: {
host: '0.0.0.0',
...(useHttps
? { https: { key: fs.readFileSync(keyPath), cert: fs.readFileSync(certPath) } }
: {}),
proxy: {
'/api': 'http://localhost:3000',
'/socket': { target: 'http://localhost:3001', ws: true },
},
},
})