0
0
mirror of https://github.com/honojs/hono.git synced 2024-11-24 19:26:56 +01:00

fix(service-worker): bind fetch to globalThis (#3500)

* fix(service-worker): bind fetch to `globalThis`

* chore: ignore lint error
This commit is contained in:
翠 / green 2024-10-11 10:11:52 +09:00 committed by GitHub
parent d5166dd851
commit de7827ee27
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 40 additions and 2 deletions

View File

@ -2,6 +2,31 @@ import { Hono } from '../../hono'
import { handle } from './handler'
import type { FetchEvent } from './types'
beforeAll(() => {
// fetch errors when it's not bound to globalThis in service worker
// set a fetch stub to emulate that behavior
vi.stubGlobal(
'fetch',
function fetch(this: undefined | typeof globalThis, arg0: string | Request) {
if (this !== globalThis) {
const error = new Error(
// eslint-disable-next-line quotes
"Failed to execute 'fetch' on 'WorkerGlobalScope': Illegal invocation"
)
error.name = 'TypeError'
throw error
}
if (arg0 instanceof Request && arg0.url === 'http://localhost/fallback') {
return new Response('hello world')
}
return Response.error()
}
)
})
afterAll(() => {
vi.unstubAllGlobals()
})
describe('handle', () => {
it('Success to fetch', async () => {
const app = new Hono()
@ -20,6 +45,19 @@ describe('handle', () => {
expect(json).toStrictEqual({ hello: 'world' })
})
it('Fallback 404', async () => {
const app = new Hono()
const handler = handle(app)
const text = await new Promise<Response>((resolve) => {
handler({
request: new Request('http://localhost/fallback'),
respondWith(res) {
resolve(res)
},
} as FetchEvent)
}).then((res) => res.text())
expect(text).toBe('hello world')
})
it('Fallback 404 with explicit fetch', async () => {
const app = new Hono()
const handler = handle(app, {
async fetch() {

View File

@ -16,8 +16,8 @@ export const handle = (
opts: {
fetch?: typeof fetch
} = {
// To use `fetch` on a Service Worker correctly, first refer to `self.fetch`.
fetch: globalThis.self !== undefined ? globalThis.self.fetch : fetch,
// To use `fetch` on a Service Worker correctly, bind it to `globalThis`.
fetch: globalThis.fetch.bind(globalThis),
}
): Handler => {
return (evt) => {