From 3990cc14df2047055a9d759f075b42d25cc5d4e5 Mon Sep 17 00:00:00 2001 From: Krystan HuffMenne Date: Wed, 10 Jan 2024 12:59:41 -0800 Subject: [PATCH] fix: Fetch handler hacks for Mirage (#9199) * Allow `store.request` to be intercepted by Mirage * Don't `cloneResponse` for Mirage mock responses Mirage mock responses don't properly include a body stream. --- packages/request/src/fetch.ts | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/packages/request/src/fetch.ts b/packages/request/src/fetch.ts index 7cbda6713ea..8f75a5d9ac9 100644 --- a/packages/request/src/fetch.ts +++ b/packages/request/src/fetch.ts @@ -11,14 +11,17 @@ * @module @ember-data/request/fetch * @main @ember-data/request/fetch */ +import { getOwnConfig, macroCondition } from '@embroider/macros'; + import { cloneResponseProperties, type Context } from './-private/context'; import type { HttpErrorProps } from './-private/utils'; +// Lazily close over fetch to avoid breaking Mirage const _fetch: typeof fetch = typeof fetch !== 'undefined' - ? fetch + ? (...args) => fetch(...args) : typeof FastBoot !== 'undefined' - ? (FastBoot.require('node-fetch') as typeof fetch) + ? (...args) => (FastBoot.require('node-fetch') as typeof fetch)(...args) : ((() => { throw new Error('No Fetch Implementation Found'); }) as typeof fetch); @@ -30,6 +33,12 @@ function cloneResponse(response: Response, overrides: Partial) { return new Response(response.body, Object.assign(props, overrides)); } +let IS_MAYBE_MIRAGE = () => false; +if (macroCondition(getOwnConfig<{ env: { TESTING: boolean } }>().env.TESTING)) { + IS_MAYBE_MIRAGE = () => + Boolean(typeof window !== 'undefined' && (window as { server?: { pretender: unknown } }).server?.pretender); +} + const MUTATION_OPS = new Set(['updateRecord', 'createRecord', 'deleteRecord']); const ERROR_STATUS_CODE_FOR = new Map([ [400, 'Bad Request'], @@ -115,9 +124,15 @@ const Fetch = { const isMutationOp = Boolean(op && MUTATION_OPS.has(op)); if (!isError && !isMutationOp && response.status !== 204 && !response.headers.has('date')) { - const headers = new Headers(response.headers); - headers.set('date', new Date().toUTCString()); - response = cloneResponse(response, { headers }); + if (IS_MAYBE_MIRAGE()) { + response.headers.set('date', new Date().toUTCString()); + } else { + const headers = new Headers(response.headers); + headers.set('date', new Date().toUTCString()); + response = cloneResponse(response, { + headers, + }); + } } context.setResponse(response);