29
} from 'shared/ReactSerializationErrors';
30
31
import isArray from 'shared/isArray';
32
+import getPrototypeOf from 'shared/getPrototypeOf';
33
+
34
+const ObjectPrototype = Object.prototype;
35
36
import {usedWithSSR} from './ReactFlightClientConfig';
37
230
);
231
return serializePromiseID(promiseId);
232
}
233
+ if (isArray(value)) {
234
+ // $FlowFixMe[incompatible-return]
235
+ return value;
236
+ }
237
// TODO: Should we the Object.prototype.toString.call() to test for cross-realm objects?
238
if (value instanceof FormData) {
239
if (formData === null) {
270
formData.append(formFieldPrefix + setId, partJSON);
271
return serializeSetID(setId);
272
}
266
- if (!isArray(value)) {
267
- const iteratorFn = getIteratorFn(value);
268
- if (iteratorFn) {
269
- return Array.from((value: any));
270
- }
273
+ const iteratorFn = getIteratorFn(value);
274
+ if (iteratorFn) {
275
+ return Array.from((value: any));
276
}
277
278
+ // Verify that this is a simple plain object.
279
+ const proto = getPrototypeOf(value);
280
+ if (
281
+ proto !== ObjectPrototype &&
282
+ (proto === null || getPrototypeOf(proto) !== null)
283
+ ) {
284
+ throw new Error(
285
+ 'Only plain objects, and a few built-ins, can be passed to Server Actions. ' +
286
+ 'Classes or null prototypes are not supported.',
287
+ );
288
+ }
289
if (__DEV__) {
274
- if (value !== null && !isArray(value)) {
275
- // Verify that this is a simple plain object.
276
- if ((value: any).$$typeof === REACT_ELEMENT_TYPE) {
277
- console.error(
278
- 'React Element cannot be passed to Server Functions from the Client.%s',
279
- describeObjectForErrorMessage(parent, key),
280
- );
281
- } else if ((value: any).$$typeof === REACT_LAZY_TYPE) {
282
- console.error(
283
- 'React Lazy cannot be passed to Server Functions from the Client.%s',
284
- describeObjectForErrorMessage(parent, key),
285
- );
286
- } else if ((value: any).$$typeof === REACT_PROVIDER_TYPE) {
287
- console.error(
288
- 'React Context Providers cannot be passed to Server Functions from the Client.%s',
289
- describeObjectForErrorMessage(parent, key),
290
- );
291
- } else if (objectName(value) !== 'Object') {
292
- console.error(
293
- 'Only plain objects can be passed to Client Components from Server Components. ' +
294
- '%s objects are not supported.%s',
295
- objectName(value),
296
- describeObjectForErrorMessage(parent, key),
297
- );
298
- } else if (!isSimpleObject(value)) {
290
+ if ((value: any).$$typeof === REACT_ELEMENT_TYPE) {
291
+ console.error(
292
+ 'React Element cannot be passed to Server Functions from the Client.%s',
293
+ describeObjectForErrorMessage(parent, key),
294
+ );
295
+ } else if ((value: any).$$typeof === REACT_LAZY_TYPE) {
296
+ console.error(
297
+ 'React Lazy cannot be passed to Server Functions from the Client.%s',
298
+ describeObjectForErrorMessage(parent, key),
299
+ );
300
+ } else if ((value: any).$$typeof === REACT_PROVIDER_TYPE) {
301
+ console.error(
302
+ 'React Context Providers cannot be passed to Server Functions from the Client.%s',
303
+ describeObjectForErrorMessage(parent, key),
304
+ );
305
+ } else if (objectName(value) !== 'Object') {
306
+ console.error(
307
+ 'Only plain objects can be passed to Client Components from Server Components. ' +
308
+ '%s objects are not supported.%s',
309
+ objectName(value),
310
+ describeObjectForErrorMessage(parent, key),
311
+ );
312
+ } else if (!isSimpleObject(value)) {
313
+ console.error(
314
+ 'Only plain objects can be passed to Client Components from Server Components. ' +
315
+ 'Classes or other objects with methods are not supported.%s',
316
+ describeObjectForErrorMessage(parent, key),
317
+ );
318
+ } else if (Object.getOwnPropertySymbols) {
319
+ const symbols = Object.getOwnPropertySymbols(value);
320
+ if (symbols.length > 0) {
321
console.error(
322
'Only plain objects can be passed to Client Components from Server Components. ' +
301
- 'Classes or other objects with methods are not supported.%s',
323
+ 'Objects with symbol properties like %s are not supported.%s',
324
+ symbols[0].description,
325
describeObjectForErrorMessage(parent, key),
326
);
304
- } else if (Object.getOwnPropertySymbols) {
305
- const symbols = Object.getOwnPropertySymbols(value);
306
- if (symbols.length > 0) {
307
- console.error(
308
- 'Only plain objects can be passed to Client Components from Server Components. ' +
309
- 'Objects with symbol properties like %s are not supported.%s',
310
- symbols[0].description,
311
- describeObjectForErrorMessage(parent, key),
312
- );
313
- }
327
}
328
}
329
}