build / build (push) Successful in 3m11s
The inline script is built by its own rollup pass (build-inline-script),
not webpack, and that pass only substituted THEME_COLORS. The fork's
basepath.js (imported via themeEngine) put process.env.BASEPATH into the
inline bundle, so line 1 threw 'process is not defined' in the browser
and the ENTIRE inline script has been dead since the basepath feature
landed: no window.__themeColors, no boot theme (permanent royal-blue),
and every runtime switchToTheme() — theme radios, grayscale's color
half — threw on the missing global AFTER saving state. Caught live by
an instrumented headless-Firefox probe against the deployed bytes:
radio click saved instanceThemes correctly, then threw in
switchToTheme; typeof window.__themeColors === 'undefined'; eval of the
served inline script reproduced 'process is not defined' at line 1.
Fixes, all one build:
- build-inline-script: substitute process.env.BASEPATH (the fix)
- postprocess-nc: DROP the `/theme-${` text rewrite — theme URLs go
through compiled bp() now, so it had become a double-prefixer
- postprocess-nc: prune the 404-crawl wreckage tree export/apps/ — the
crawler follows bp()-prefixed links into dead 404 shells (error:1, no
router) whose links the attribute rewrite then double-prefixed; users
wandering in there found every control dead
- inline-script: one-time instanceThemes 'default'->'bawnet' migration
(marker store_themeMigratedToBawnet so a deliberate Royal pick sticks)
— pre-bawnet builds stamped 'default' at OAuth time
88 lines
3.8 KiB
JavaScript
88 lines
3.8 KiB
JavaScript
// Subpath adaptation for the Nextcloud-wrapped build (ops/features#30).
|
|
//
|
|
// Why this exists: the for-pinafore-26 sapper's `export --basepath` is broken —
|
|
// it lays files out under the basepath but prerenders every page through its
|
|
// 404 handler (__SAPPER__ carries error:1, baseUrl:"") — so we export at ROOT
|
|
// (the healthy, tunnel-proven mode) and adapt the artifacts here instead:
|
|
//
|
|
// 1. every absolute href=/... and src=/... in exported HTML gets the
|
|
// basepath prefix (covers the <base> tag, scripts, styles, manifest,
|
|
// icons — the lot),
|
|
// 2. the inline __SAPPER__ bootstrap gets baseUrl:"<BASEPATH>" so the
|
|
// client router matches routes under the subpath,
|
|
// 3. the service-worker registration is pointed under the basepath AND the
|
|
// worker itself is replaced with a self-unregistering stub — offline
|
|
// shell caching inside a Nextcloud iframe is pure liability (it serves
|
|
// stale builds after every upgrade and buys nothing).
|
|
//
|
|
// Webpack 5's default publicPath ("auto") makes dynamic chunk loading
|
|
// self-locating, so JS bundles need no rewriting.
|
|
|
|
import fs from 'fs'
|
|
import path from 'path'
|
|
import { fileURLToPath } from 'url'
|
|
|
|
const __dirname = path.dirname(fileURLToPath(import.meta.url))
|
|
|
|
const BASEPATH = process.env.BASEPATH
|
|
if (!BASEPATH || !BASEPATH.startsWith('/')) {
|
|
console.error('postprocess-nc: BASEPATH env var required (leading slash)')
|
|
process.exit(1)
|
|
}
|
|
|
|
const EXPORT_DIR = path.join(__dirname, '..', '__sapper__', 'export')
|
|
|
|
const SW_STUB = "self.addEventListener('install',function(){self.skipWaiting()});" +
|
|
"self.addEventListener('activate',function(){self.registration.unregister()});\n"
|
|
|
|
function walk (dir) {
|
|
return fs.readdirSync(dir, { withFileTypes: true }).flatMap(e => {
|
|
const p = path.join(dir, e.name)
|
|
return e.isDirectory() ? walk(p) : [p]
|
|
})
|
|
}
|
|
|
|
// The root-export crawl follows the bp()-prefixed internal links into
|
|
// /apps/<app>/client/... and exports them as 404 shells: dead copies of the
|
|
// app (error:1 baked in, router never starts) whose already-prefixed hrefs
|
|
// the attribute rewrite below would then DOUBLE-prefix — a self-contained
|
|
// graveyard the user can wander into and where nothing works. Never ship it.
|
|
const wreckage = path.join(EXPORT_DIR, 'apps')
|
|
if (fs.existsSync(wreckage)) {
|
|
fs.rmSync(wreckage, { recursive: true })
|
|
console.log('postprocess-nc: pruned the 404-crawl wreckage tree export/apps/')
|
|
}
|
|
|
|
let htmlCount = 0
|
|
let swCount = 0
|
|
for (const file of walk(EXPORT_DIR)) {
|
|
if (path.basename(file) === 'service-worker.js') {
|
|
fs.writeFileSync(file, SW_STUB)
|
|
swCount++
|
|
continue
|
|
}
|
|
if (!file.endsWith('.html')) continue
|
|
let html = fs.readFileSync(file, 'utf8')
|
|
const before = html
|
|
// absolute refs -> under the basepath ((?!\/) spares protocol-relative //)
|
|
html = html.replace(/(href|src)=(["']?)\/(?!\/)/g, `$1=$2${BASEPATH}/`)
|
|
// the client router's basepath
|
|
html = html.replace('baseUrl:""', `baseUrl:"${BASEPATH}"`)
|
|
// service-worker registration inside the inline bootstrap
|
|
html = html.replace(/register\('\/service-worker\.js'/g, `register('${BASEPATH}/service-worker.js'`)
|
|
// NOTE: no rewriting inside inline-script JS — its theme URLs go through
|
|
// the compiled bp() (BASEPATH is substituted by build-inline-script.js),
|
|
// so a text rewrite here would DOUBLE the prefix. The old `/theme-${`
|
|
// rewrite did exactly that; it was compensating for the inline script
|
|
// crashing wholesale on an unsubstituted process.env.BASEPATH, which is
|
|
// fixed at the source now.
|
|
if (html !== before) htmlCount++
|
|
fs.writeFileSync(file, html)
|
|
}
|
|
|
|
if (htmlCount === 0) {
|
|
console.error('postprocess-nc: rewrote 0 html files — export layout changed?')
|
|
process.exit(1)
|
|
}
|
|
console.log(`postprocess-nc: rewrote ${htmlCount} html files, stubbed ${swCount} service worker(s), basepath ${BASEPATH}`)
|