openvibers/openvibe.games Commits

Games serves the shared page shell's web app manifest and touch icon (/steam, /updates and world pages logged a manifest 404) (#143)

OP OpenVibers committed 20 days ago · 81bbe33265 · 2 files, +30 −1

Changes

ddiff --git a/apps/server/src/net/sharedAssets.test.ts b/apps/server/src/net/sharedAssets.test.ts
iindex 3945fb2..c765083 100644
---- a/apps/server/src/net/sharedAssets.test.ts
++++ b/apps/server/src/net/sharedAssets.test.ts
@@@ -40,6 +40,24 @@ describe('/shared (D42)', () => {
expect(r.status).toBe(304)
})
++ it('serves the web app manifest and touch icon the shared page shell links (/steam, /updates, world pages)', async () => {
++ const shell = req('openvibe-shared/serve') as { manifestUrl(s: string): string | null }
++ const url = shell.manifestUrl('games')
++ expect(url).toMatch(/^\/shared\/manifest\/games\.webmanifest\?v=/)
++ const r = await fetch(base + url)
++ expect(r.status).toBe(200)
++ expect(r.headers.get('content-type')).toMatch(/manifest\+json/)
++ expect(r.headers.get('cache-control')).toMatch(/immutable/)
++ const m = (await r.json()) as { name?: string; icons?: { src: string }[] }
++ expect(m.name).toBeTruthy()
++ const icon = m.icons?.[0]?.src ?? ''
++ expect(icon).toMatch(/^\/shared\/icons\//)
++ const ir = await fetch(base + icon)
++ expect(ir.status).toBe(200)
++ expect(ir.headers.get('content-type')).toMatch(/image\/png/)
++ expect((await fetch(`${base}/shared/manifest/no-such-site.webmanifest`)).status).toBe(404)
++ })
++
it('serves only the browser files openvibe-shared lists', async () => {
for (const p of [
'/shared/serve.js',
ddiff --git a/apps/server/src/net/sharedAssets.ts b/apps/server/src/net/sharedAssets.ts
iindex 7f0ff50..d032cda 100644
---- a/apps/server/src/net/sharedAssets.ts
++++ b/apps/server/src/net/sharedAssets.ts
@@@ -16,17 +16,28 @@ interface SharedFiles {
}
interface SharedServe {
hashOf(name: string): string
++ handler(): (req: IncomingMessage & { path: string }, res: ServerResponse, next: (err?: unknown) => void) => void
}
export function sharedAssetsHandler(req: NodeRequire = createRequire(import.meta.url)) {
const files = req('openvibe-shared/files') as SharedFiles
const serve = req('openvibe-shared/serve') as SharedServe
++ const shared = serve.handler()
return (rq: IncomingMessage, res: ServerResponse): boolean => {
if (rq.method !== 'GET' && rq.method !== 'HEAD') return false
const url = new URL(rq.url ?? '/', 'http://games.local')
if (!url.pathname.startsWith('/shared/')) return false
const name = url.pathname.slice('/shared/'.length)
-- if (!files.isBrowserFile(name)) return false
++ // The rest openvibe-shared serves goes to its own handler: the web app manifest and touch icon its page shell links
++ // on /steam, /updates and world pages (manifest/games.webmanifest, icons/games-192.png), and the social cards.
++ if (!files.isBrowserFile(name)) {
++ let handled = true
++ shared(Object.assign(rq, { path: `/${name}` }), res, (err) => {
++ if (err) res.destroy()
++ else handled = false
++ })
++ return handled
++ }
const hash = serve.hashOf(name)
const headers = {
'content-type': 'application/javascript; charset=utf-8',