From aad25d7e921e08133722c0d0574096b8fc0026ab Mon Sep 17 00:00:00 2001 From: eps1lon Date: Fri, 11 Oct 2024 11:45:14 +0200 Subject: [PATCH] Don't warn on well-known properties in `searchParams` React is accessing these triggering sync-access warnings. --- .../next/src/server/request/search-params.ts | 73 ++++++------------- packages/next/src/server/request/utils.ts | 25 +++++++ 2 files changed, 49 insertions(+), 49 deletions(-) diff --git a/packages/next/src/server/request/search-params.ts b/packages/next/src/server/request/search-params.ts index ecabd44a96b416..59ae81a7692efd 100644 --- a/packages/next/src/server/request/search-params.ts +++ b/packages/next/src/server/request/search-params.ts @@ -22,6 +22,7 @@ import { describeStringPropertyAccess, describeHasCheckingStringProperty, throwWithStaticGenerationBailoutErrorWithDynamicError, + wellKnownProperties, } from './utils' export type SearchParams = { [key: string]: string | string[] | undefined } @@ -588,52 +589,26 @@ function makeDynamicallyTrackedExoticSearchParamsWithDevWarnings( }) Object.keys(underlyingSearchParams).forEach((prop) => { - switch (prop) { - // Object prototype - case 'hasOwnProperty': - case 'isPrototypeOf': - case 'propertyIsEnumerable': - case 'toString': - case 'valueOf': - case 'toLocaleString': - - // Promise prototype - // fallthrough - case 'then': - case 'catch': - case 'finally': - - // React Promise extension - // fallthrough - case 'status': - - // Common tested properties - // fallthrough - case 'toJSON': - case '$$typeof': - case '__esModule': { - // These properties cannot be shadowed because they need to be the - // true underlying value for Promises to work correctly at runtime - unproxiedProperties.push(prop) - break - } - default: { - proxiedProperties.add(prop) - Object.defineProperty(promise, prop, { - get() { - return proxiedUnderlying[prop] - }, - set(newValue) { - Object.defineProperty(promise, prop, { - value: newValue, - writable: true, - enumerable: true, - }) - }, - enumerable: true, - configurable: true, - }) - } + if (wellKnownProperties.has(prop)) { + // These properties cannot be shadowed because they need to be the + // true underlying value for Promises to work correctly at runtime + unproxiedProperties.push(prop) + } else { + proxiedProperties.add(prop) + Object.defineProperty(promise, prop, { + get() { + return proxiedUnderlying[prop] + }, + set(newValue) { + Object.defineProperty(promise, prop, { + value: newValue, + writable: true, + enumerable: true, + }) + }, + enumerable: true, + configurable: true, + }) } }) @@ -641,9 +616,9 @@ function makeDynamicallyTrackedExoticSearchParamsWithDevWarnings( get(target, prop, receiver) { if (typeof prop === 'string') { if ( - // We are accessing a property that was proxied to the promise instance - proxiedProperties.has(prop) || - // We are accessing a property that doesn't exist on the promise nor the underlying + // The property isn't part of the well known set that is never proxied + !wellKnownProperties.has(prop) && + // We aren't accessing a property defined directly on the promise like 'status' or 'value' written by React Reflect.has(target, prop) === false ) { const expression = describeStringPropertyAccess('searchParams', prop) diff --git a/packages/next/src/server/request/utils.ts b/packages/next/src/server/request/utils.ts index 7f2e75f0b6617a..6fa6ad4ac7a8c9 100644 --- a/packages/next/src/server/request/utils.ts +++ b/packages/next/src/server/request/utils.ts @@ -53,3 +53,28 @@ export function throwWithStaticGenerationBailoutErrorWithDynamicError( `Route ${route} with \`dynamic = "error"\` couldn't be rendered statically because it used ${expression}. See more info here: https://nextjs.org/docs/app/building-your-application/rendering/static-and-dynamic#dynamic-rendering` ) } + +export const wellKnownProperties = new Set([ + 'hasOwnProperty', + 'isPrototypeOf', + 'propertyIsEnumerable', + 'toString', + 'valueOf', + 'toLocaleString', + + // Promise prototype + // fallthrough + 'then', + 'catch', + 'finally', + + // React Promise extension + // fallthrough + 'status', + + // Common tested properties + // fallthrough + 'toJSON', + '$$typeof', + '__esModule', +])