Skip to content

Commit

Permalink
fix(runtime): support node 14+ (#135)
Browse files Browse the repository at this point in the history
  • Loading branch information
bakkot committed Jun 20, 2022
1 parent 36060cd commit 6a1c5a6
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 72 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
node: [16]
node: [14, 16, 18]
steps:
- uses: actions/checkout@v1
- uses: actions/setup-node@v1
Expand Down
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
"name": "@pkgjs/parseargs",
"version": "0.9.0",
"description": "Polyfill of future proposal for `util.parseArgs()`",
"engines": {
"node": ">=14"
},
"main": "index.js",
"exports": {
".": "./index.js",
Expand Down
103 changes: 32 additions & 71 deletions primordials.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,28 @@
/*
This file is copied from https://github.com/nodejs/node/blob/v14.19.3/lib/internal/per_context/primordials.js
under the following license:
Copyright Node.js contributors. All rights reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to
deal in the Software without restriction, including without limitation the
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
sell copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
IN THE SOFTWARE.
*/

'use strict';

/* eslint-disable node-core/prefer-primordials */
Expand Down Expand Up @@ -169,7 +194,6 @@ function copyPrototype(src, dest, prefix) {

// Create copies of intrinsic objects
[
'AggregateError',
'Array',
'ArrayBuffer',
'BigInt',
Expand All @@ -180,7 +204,6 @@ function copyPrototype(src, dest, prefix) {
'Date',
'Error',
'EvalError',
'FinalizationRegistry',
'Float32Array',
'Float64Array',
'Function',
Expand All @@ -204,7 +227,6 @@ function copyPrototype(src, dest, prefix) {
'Uint8Array',
'Uint8ClampedArray',
'WeakMap',
'WeakRef',
'WeakSet',
].forEach((name) => {
// eslint-disable-next-line no-restricted-globals
Expand Down Expand Up @@ -232,16 +254,12 @@ function copyPrototype(src, dest, prefix) {
// Refs: https://tc39.es/ecma262/#sec-%typedarray%-intrinsic-object
[
{ name: 'TypedArray', original: Reflect.getPrototypeOf(Uint8Array) },
{
name: 'ArrayIterator', original: {
prototype: Reflect.getPrototypeOf(Array.prototype[Symbol.iterator]()),
}
},
{
name: 'StringIterator', original: {
prototype: Reflect.getPrototypeOf(String.prototype[Symbol.iterator]()),
}
},
{ name: 'ArrayIterator', original: {
prototype: Reflect.getPrototypeOf(Array.prototype[Symbol.iterator]()),
} },
{ name: 'StringIterator', original: {
prototype: Reflect.getPrototypeOf(String.prototype[Symbol.iterator]()),
} },
].forEach(({ name, original }) => {
primordials[name] = original;
// The static %TypedArray% methods require a valid `this`, but can't be bound,
Expand All @@ -254,17 +272,13 @@ function copyPrototype(src, dest, prefix) {

const {
ArrayPrototypeForEach,
FinalizationRegistry,
FunctionPrototypeCall,
Map,
ObjectFreeze,
ObjectSetPrototypeOf,
Promise,
PromisePrototypeThen,
Set,
SymbolIterator,
WeakMap,
WeakRef,
WeakSet,
} = primordials;

Expand Down Expand Up @@ -309,9 +323,6 @@ const copyProps = (src, dest) => {
});
};

/**
* @type {typeof primordials.makeSafe}
*/
const makeSafe = (unsafe, safe) => {
if (SymbolIterator in unsafe.prototype) {
const dummy = new unsafe();
Expand All @@ -326,7 +337,7 @@ const makeSafe = (unsafe, safe) => {
SymbolIterator in (FunctionPrototypeCall(desc.value, dummy) ?? {})
) {
const createIterator = uncurryThis(desc.value);
next ??= uncurryThis(createIterator(dummy).next);
next = next ?? uncurryThis(createIterator(dummy).next);
const SafeIterator = createSafeIterator(createIterator, next);
desc.value = function() {
return new SafeIterator(this);
Expand Down Expand Up @@ -363,7 +374,6 @@ primordials.SafeWeakMap = makeSafe(
constructor(i) { super(i); } // eslint-disable-line no-useless-constructor
}
);

primordials.SafeSet = makeSafe(
Set,
class SafeSet extends Set {
Expand All @@ -377,55 +387,6 @@ primordials.SafeWeakSet = makeSafe(
}
);

primordials.SafeFinalizationRegistry = makeSafe(
FinalizationRegistry,
class SafeFinalizationRegistry extends FinalizationRegistry {
// eslint-disable-next-line no-useless-constructor
constructor(cleanupCallback) { super(cleanupCallback); }
}
);
primordials.SafeWeakRef = makeSafe(
WeakRef,
class SafeWeakRef extends WeakRef {
// eslint-disable-next-line no-useless-constructor
constructor(target) { super(target); }
}
);

const SafePromise = makeSafe(
Promise,
class SafePromise extends Promise {
// eslint-disable-next-line no-useless-constructor
constructor(executor) { super(executor); }
}
);

primordials.PromisePrototypeCatch = (thisPromise, onRejected) =>
PromisePrototypeThen(thisPromise, undefined, onRejected);

/**
* Attaches a callback that is invoked when the Promise is settled (fulfilled or
* rejected). The resolved value cannot be modified from the callback.
* Prefer using async functions when possible.
* @param {Promise<any>} thisPromise
* @param {() => void) | undefined | null} onFinally The callback to execute
* when the Promise is settled (fulfilled or rejected).
* @returns {Promise} A Promise for the completion of the callback.
*/
primordials.SafePromisePrototypeFinally = (thisPromise, onFinally) =>
// Wrapping on a new Promise is necessary to not expose the SafePromise
// prototype to user-land.
new Promise((a, b) =>
new SafePromise((a, b) => PromisePrototypeThen(thisPromise, a, b))
.finally(onFinally)
.then(a, b)
);

primordials.AsyncIteratorPrototype =
primordials.ReflectGetPrototypeOf(
primordials.ReflectGetPrototypeOf(
async function* () { }).prototype);

ObjectSetPrototypeOf(primordials, null);
ObjectFreeze(primordials);

Expand Down

0 comments on commit 6a1c5a6

Please sign in to comment.