From 6cc816ebe40eb32a13f88abecd06d1ceaed1af38 Mon Sep 17 00:00:00 2001 From: Denis Pushkarev Date: Wed, 19 Apr 2023 01:34:23 +0300 Subject: [PATCH] add a fix for a NodeJS 20.0.0 bug with cloning `File` via `structuredClone` https://github.com/nodejs/node/issues/47612 --- CHANGELOG.md | 1 + .../core-js/modules/web.structured-clone.js | 30 +++++++++---------- 2 files changed, 16 insertions(+), 15 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 94ea75cfc652..8f8f9bc732fc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ ## Changelog ##### Unreleased +- Added a fix for a NodeJS 20.0.0 [bug](https://github.com/nodejs/node/issues/47612) with cloning `File` via `structuredClone` - Compat data improvements: - Added NodeJS 20.0 compat data mapping diff --git a/packages/core-js/modules/web.structured-clone.js b/packages/core-js/modules/web.structured-clone.js index 96df46f262e6..f1398fbb21d5 100644 --- a/packages/core-js/modules/web.structured-clone.js +++ b/packages/core-js/modules/web.structured-clone.js @@ -125,6 +125,11 @@ var throwUnpolyfillable = function (type, action) { throw new DOMException((action || 'Cloning') + ' of ' + type + ' cannot be properly polyfilled in this engine', DATA_CLONE_ERROR); }; +var tryNativeRestrictedStructuredClone = function (value, type) { + if (!nativeRestrictedStructuredClone) throwUnpolyfillable(type); + return nativeRestrictedStructuredClone(value); +}; + var createDataTransfer = function () { var dataTransfer; try { @@ -245,11 +250,16 @@ var structuredCloneInternal = function (value, map) { structuredCloneInternal(value.p4, map) ); } catch (error) { - if (nativeRestrictedStructuredClone) { - cloned = nativeRestrictedStructuredClone(value); - } else throwUnpolyfillable(type); + cloned = tryNativeRestrictedStructuredClone(value, type); } break; + // NodeJS 20.0.0 bug, https://github.com/nodejs/node/issues/47612 + case 'File': + try { + cloned = new File([value], value.name, value); + } catch (error) { + cloned = tryNativeRestrictedStructuredClone(value, type); + } break; case 'FileList': dataTransfer = createDataTransfer(); if (dataTransfer) { @@ -257,9 +267,7 @@ var structuredCloneInternal = function (value, map) { dataTransfer.items.add(structuredCloneInternal(value[i], map)); } cloned = dataTransfer.files; - } else if (nativeRestrictedStructuredClone) { - cloned = nativeRestrictedStructuredClone(value); - } else throwUnpolyfillable(type); + } else cloned = tryNativeRestrictedStructuredClone(value, type); break; case 'ImageData': // Safari 9 ImageData is a constructor, but typeof ImageData is 'object' @@ -271,9 +279,7 @@ var structuredCloneInternal = function (value, map) { { colorSpace: value.colorSpace } ); } catch (error) { - if (nativeRestrictedStructuredClone) { - cloned = nativeRestrictedStructuredClone(value); - } else throwUnpolyfillable(type); + cloned = tryNativeRestrictedStructuredClone(value, type); } break; default: if (nativeRestrictedStructuredClone) { @@ -365,12 +371,6 @@ var structuredCloneInternal = function (value, map) { } catch (error) { throwUncloneable(type); } break; - case 'File': - try { - cloned = new File([value], value.name, value); - } catch (error) { - throwUnpolyfillable(type); - } break; case 'CropTarget': case 'CryptoKey': case 'FileSystemDirectoryHandle':