From a48680d2464cdbb7a82e19c21dc6a74bab724c20 Mon Sep 17 00:00:00 2001 From: "Sebastian \"Sebbie\" Silbermann" Date: Fri, 11 Oct 2024 15:50:13 +0200 Subject: [PATCH] Don't warn on well-known properties in `searchParams` (#71142) --- .../next/src/server/request/search-params.ts | 76 +++++++------------ packages/next/src/server/request/utils.ts | 25 ++++++ 2 files changed, 51 insertions(+), 50 deletions(-) diff --git a/packages/next/src/server/request/search-params.ts b/packages/next/src/server/request/search-params.ts index ecabd44a96b41..899140643c38b 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,10 +616,11 @@ 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 - Reflect.has(target, prop) === false + !wellKnownProperties.has(prop) && + (proxiedProperties.has(prop) || + // We are accessing a property that doesn't exist on the promise nor + // the underlying searchParams. + Reflect.has(target, prop) === false) ) { const expression = describeStringPropertyAccess('searchParams', prop) warnForSyncAccess(store.route, expression) diff --git a/packages/next/src/server/request/utils.ts b/packages/next/src/server/request/utils.ts index 7f2e75f0b6617..6fa6ad4ac7a8c 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', +])