From 15f982b4fb5dff06a5c0694a21ae949303d5ff9e Mon Sep 17 00:00:00 2001 From: Julien Date: Tue, 17 Dec 2024 00:23:12 +0100 Subject: [PATCH] fix: asset versionning broken Two things was incorrect : first the path to the Vite manifest has changed since latest version. Also, we should REMOVE the X-Inertia header when creating a Location response --- src/inertia_middleware.ts | 10 ++++++---- src/version_cache.ts | 2 +- tests/middleware.spec.ts | 39 ++++++++++++++++++++++++++++++++++++++- 3 files changed, 45 insertions(+), 6 deletions(-) diff --git a/src/inertia_middleware.ts b/src/inertia_middleware.ts index 5d23569..2c91c6d 100644 --- a/src/inertia_middleware.ts +++ b/src/inertia_middleware.ts @@ -12,6 +12,7 @@ import type { HttpContext } from '@adonisjs/core/http' import type { NextFn } from '@adonisjs/core/types/http' import { Inertia } from './inertia.js' +import { InertiaHeaders } from './headers.js' import type { ResolvedConfig } from './types.js' /** @@ -40,10 +41,10 @@ export default class InertiaMiddleware { await next() - const isInertiaRequest = !!request.header('x-inertia') + const isInertiaRequest = !!request.header(InertiaHeaders.Inertia) if (!isInertiaRequest) return - response.header('Vary', 'Accept') + response.header('Vary', InertiaHeaders.Inertia) /** * When redirecting a PUT/PATCH/DELETE request, we need to change the @@ -63,8 +64,9 @@ export default class InertiaMiddleware { * See https://inertiajs.com/the-protocol#asset-versioning */ const version = this.config.versionCache.getVersion().toString() - if (method === 'GET' && request.header('x-inertia-version', '') !== version) { - response.header('x-inertia-location', request.url()) + if (method === 'GET' && request.header(InertiaHeaders.Version, '') !== version) { + response.removeHeader(InertiaHeaders.Inertia) + response.header(InertiaHeaders.Location, request.url()) response.status(409) } } diff --git a/src/version_cache.ts b/src/version_cache.ts index 4835ddf..2df6b8c 100644 --- a/src/version_cache.ts +++ b/src/version_cache.ts @@ -34,7 +34,7 @@ export class VersionCache { async #getManifestHash(): Promise { try { const crc32 = await import('crc-32') - const manifestPath = new URL('public/assets/manifest.json', this.appRoot) + const manifestPath = new URL('public/assets/.vite/manifest.json', this.appRoot) const manifestFile = await readFile(manifestPath, 'utf-8') this.#cachedVersion = crc32.default.str(manifestFile) return this.#cachedVersion diff --git a/tests/middleware.spec.ts b/tests/middleware.spec.ts index 047ce79..b2c683b 100644 --- a/tests/middleware.spec.ts +++ b/tests/middleware.spec.ts @@ -12,6 +12,7 @@ import { test } from '@japa/runner' import { HttpContextFactory, RequestFactory, ResponseFactory } from '@adonisjs/core/factories/http' import { Inertia } from '../src/inertia.js' +import { InertiaHeaders } from '../src/headers.js' import { httpServer } from '../tests_helpers/index.js' import { VersionCache } from '../src/version_cache.js' import InertiaMiddleware from '../src/inertia_middleware.js' @@ -122,7 +123,7 @@ test.group('Middleware', () => { const r1 = await supertest(server).get('/').set('x-inertia', 'true') const r2 = await supertest(server).get('/') - assert.equal(r1.headers.vary, 'Accept') + assert.equal(r1.headers.vary, InertiaHeaders.Inertia) assert.isUndefined(r2.headers.vary) }) @@ -182,6 +183,42 @@ test.group('Middleware', () => { assert.equal(r1.headers['x-inertia-location'], '/') }) + test('if version has changed response should not includes x-inertia header', async ({ + assert, + }) => { + let requestCount = 1 + + const version = new VersionCache(new URL(import.meta.url), '1') + const middleware = new InertiaMiddleware({ + rootView: 'root', + sharedData: {}, + versionCache: version, + ssr: { enabled: false, bundle: '', entrypoint: '' }, + history: { encrypt: false }, + }) + + const server = httpServer.create(async (req, res) => { + const request = new RequestFactory().merge({ req, res }).create() + const response = new ResponseFactory().merge({ req, res }).create() + const ctx = new HttpContextFactory().merge({ request, response }).create() + + version.setVersion(requestCount.toString()) + + await middleware.handle(ctx, () => { + ctx.response.header('x-inertia', 'true') + ctx.response.redirect('/foo') + }) + + ctx.response.finish() + }) + + const r1 = await supertest(server).get('/').set('x-inertia', 'true') + + assert.equal(r1.status, 409) + assert.equal(r1.headers['x-inertia-location'], '/') + assert.isUndefined(r1.headers['x-inertia']) + }) + test('if version is provided as integer it should compare it using a toString', async ({ assert, }) => {