Skip to content

Commit

Permalink
fix: asset versionning broken
Browse files Browse the repository at this point in the history
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
  • Loading branch information
Julien-R44 committed Dec 16, 2024
1 parent d9e3a3d commit 15f982b
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 6 deletions.
10 changes: 6 additions & 4 deletions src/inertia_middleware.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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'

/**
Expand Down Expand Up @@ -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
Expand All @@ -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)
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/version_cache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ export class VersionCache {
async #getManifestHash(): Promise<AssetsVersion> {
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
Expand Down
39 changes: 38 additions & 1 deletion tests/middleware.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down Expand Up @@ -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)
})

Expand Down Expand Up @@ -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,
}) => {
Expand Down

0 comments on commit 15f982b

Please sign in to comment.