|
1 | 1 | import { getDeployStore, GetWithMetadataOptions, Store } from '@netlify/blobs'
|
2 | 2 |
|
3 |
| -const fetchBeforeNextPatchedIt = globalThis.fetch |
| 3 | +const FETCH_BEFORE_NEXT_PATCHED_IT = Symbol.for('nf-not-patched-fetch') |
| 4 | +const extendedGlobalThis = globalThis as typeof globalThis & { |
| 5 | + [FETCH_BEFORE_NEXT_PATCHED_IT]?: typeof globalThis.fetch |
| 6 | +} |
| 7 | + |
| 8 | +/** |
| 9 | + * Attempt to extract original fetch in case it was patched by Next.js already |
| 10 | + * |
| 11 | + * @see github.com/vercel/next.js/blob/fa214c74c1d8023098c0e94e57f917ef9f1afd1a/packages/next/src/server/lib/patch-fetch.ts#L986 |
| 12 | + */ |
| 13 | +function attemptToGetOriginalFetch( |
| 14 | + fetch: typeof globalThis.fetch & { |
| 15 | + _nextOriginalFetch?: typeof globalThis.fetch |
| 16 | + }, |
| 17 | +) { |
| 18 | + return fetch._nextOriginalFetch ?? fetch |
| 19 | +} |
| 20 | + |
| 21 | +function forceOptOutOfUsingDataCache(fetch: typeof globalThis.fetch): typeof globalThis.fetch { |
| 22 | + return (input, init) => { |
| 23 | + return fetch(input, { |
| 24 | + ...init, |
| 25 | + next: { |
| 26 | + ...init?.next, |
| 27 | + // setting next.internal = true should prevent from trying to use data cache |
| 28 | + // https://github.com/vercel/next.js/blob/fa214c74c1d8023098c0e94e57f917ef9f1afd1a/packages/next/src/server/lib/patch-fetch.ts#L174 |
| 29 | + // https://github.com/vercel/next.js/blob/fa214c74c1d8023098c0e94e57f917ef9f1afd1a/packages/next/src/server/lib/patch-fetch.ts#L210-L213 |
| 30 | + // this is last line of defense in case we didn't manage to get unpatched fetch that will not affect |
| 31 | + // fetch if it's unpatched so it should be safe to apply always if we aren't sure if we use patched fetch |
| 32 | + |
| 33 | + // @ts-expect-error - this is an internal field that Next.js doesn't add to its global |
| 34 | + // type overrides for RequestInit type (like `next.revalidate` or `next.tags`) |
| 35 | + internal: true, |
| 36 | + }, |
| 37 | + }) |
| 38 | + } |
| 39 | +} |
| 40 | + |
| 41 | +export const setFetchBeforeNextPatchedIt = (fetch: typeof globalThis.fetch) => { |
| 42 | + // we store in globalThis in case we have multiple copies of this module |
| 43 | + // just as precaution |
| 44 | + |
| 45 | + extendedGlobalThis[FETCH_BEFORE_NEXT_PATCHED_IT] = forceOptOutOfUsingDataCache( |
| 46 | + attemptToGetOriginalFetch(fetch), |
| 47 | + ) |
| 48 | +} |
| 49 | + |
| 50 | +const fetchBeforeNextPatchedItFallback = forceOptOutOfUsingDataCache( |
| 51 | + attemptToGetOriginalFetch(globalThis.fetch), |
| 52 | +) |
| 53 | +const getFetchBeforeNextPatchedIt = () => |
| 54 | + extendedGlobalThis[FETCH_BEFORE_NEXT_PATCHED_IT] ?? fetchBeforeNextPatchedItFallback |
4 | 55 |
|
5 | 56 | export const getRegionalBlobStore = (args: GetWithMetadataOptions = {}): Store => {
|
6 | 57 | return getDeployStore({
|
7 | 58 | ...args,
|
8 |
| - fetch: fetchBeforeNextPatchedIt, |
| 59 | + fetch: getFetchBeforeNextPatchedIt(), |
9 | 60 | region: process.env.USE_REGIONAL_BLOBS?.toUpperCase() === 'TRUE' ? undefined : 'us-east-2',
|
10 | 61 | })
|
11 | 62 | }
|
0 commit comments