Skip to content

Commit

Permalink
Support next option for Request (#41614)
Browse files Browse the repository at this point in the history
Follow up for #41505. Addding `next` option to Request options
  • Loading branch information
huozhi committed Oct 24, 2022
1 parent 496b2eb commit 5de6f46
Show file tree
Hide file tree
Showing 5 changed files with 43 additions and 16 deletions.
20 changes: 10 additions & 10 deletions packages/next/server/app-render.tsx
Expand Up @@ -208,8 +208,8 @@ function patchFetch(ComponentMod: any) {

const staticGenerationAsyncStorage = ComponentMod.staticGenerationAsyncStorage

const origFetch = globalThis.fetch
globalThis.fetch = async (url, opts) => {
const originFetch = globalThis.fetch
globalThis.fetch = async (input, init) => {
const staticGenerationStore =
'getStore' in staticGenerationAsyncStorage
? staticGenerationAsyncStorage.getStore()
Expand All @@ -219,18 +219,18 @@ function patchFetch(ComponentMod: any) {
staticGenerationStore || {}

if (staticGenerationStore && isStaticGeneration) {
if (opts && typeof opts === 'object') {
if (opts.cache === 'no-store') {
if (init && typeof init === 'object') {
if (init.cache === 'no-store') {
staticGenerationStore.revalidate = 0
// TODO: ensure this error isn't logged to the user
// seems it's slipping through currently
throw new DynamicServerError(
`no-store fetch ${url}${pathname ? ` ${pathname}` : ''}`
`no-store fetch ${input}${pathname ? ` ${pathname}` : ''}`
)
}

const hasNextConfig = 'next' in opts
const next = (hasNextConfig && opts.next) || {}
const hasNextConfig = 'next' in init
const next = init.next || {}
if (
typeof next.revalidate === 'number' &&
(typeof fetchRevalidate === 'undefined' ||
Expand All @@ -241,15 +241,15 @@ function patchFetch(ComponentMod: any) {
// TODO: ensure this error isn't logged to the user
// seems it's slipping through currently
throw new DynamicServerError(
`revalidate: ${next.revalidate} fetch ${url}${
`revalidate: ${next.revalidate} fetch ${input}${
pathname ? ` ${pathname}` : ''
}`
)
}
if (hasNextConfig) delete opts.next
if (hasNextConfig) delete init.next
}
}
return origFetch(url, opts)
return originFetch(input, init)
}
}

Expand Down
13 changes: 12 additions & 1 deletion packages/next/server/node-polyfill-fetch.js
Expand Up @@ -6,6 +6,17 @@ if (!global.fetch) {
? require('next/dist/compiled/undici')
: require('next/dist/compiled/node-fetch')
}

function getRequestImpl() {
const OriginRequest = getFetchImpl().Request
return class Request extends OriginRequest {
constructor(input, init) {
super(input, init)
this.next = init?.next
}
}
}

// Due to limitation of global configuration, we have to do this resolution at runtime
global.fetch = (...args) => {
const fetchImpl = getFetchImpl()
Expand Down Expand Up @@ -44,7 +55,7 @@ if (!global.fetch) {
},
Request: {
get() {
return getFetchImpl().Request
return getRequestImpl()
},
},
Response: {
Expand Down
2 changes: 2 additions & 0 deletions packages/next/server/web/sandbox/context.ts
Expand Up @@ -265,13 +265,15 @@ Learn More: https://nextjs.org/docs/messages/edge-dynamic-code-evaluation`),

const __Request = context.Request
context.Request = class extends __Request {
next?: NextFetchRequestConfig | undefined
constructor(input: URL | RequestInfo, init?: RequestInit | undefined) {
const url =
typeof input !== 'string' && 'url' in input
? input.url
: String(input)
validateURL(url)
super(url, init)
this.next = init?.next
}
}

Expand Down
13 changes: 8 additions & 5 deletions packages/next/types/global.d.ts
Expand Up @@ -12,6 +12,10 @@ declare namespace NodeJS {
interface ProcessEnv {
readonly NODE_ENV: 'development' | 'production' | 'test'
}

interface RequestInit extends globalThis.RequestInit {
next?: NextFetchRequestConfig | undefined
}
}

declare module '*.module.css' {
Expand All @@ -34,11 +38,10 @@ interface Window {
__NEXT_HMR_CB?: null | ((message?: string) => void)
}

type NextFetchRequestConfig = {
interface NextFetchRequestConfig {
revalidate?: number
}

declare function fetch(
url: RequestInfo,
opts: RequestInit & { next?: NextFetchRequestConfig }
): Promise<Response>
interface RequestInit {
next?: NextFetchRequestConfig | undefined
}
11 changes: 11 additions & 0 deletions test/e2e/app-dir/app-alias/src/app/typing/page.tsx
@@ -0,0 +1,11 @@
// Typing test
// eslint-disable-next-line
function noop() {
fetch('/button', { next: { revalidate: 0 } })
const request = new Request('/button', { next: { revalidate: 0 } })
fetch(request)
}

export default function page() {
return 'typing'
}

0 comments on commit 5de6f46

Please sign in to comment.