From d628ccebb1a66b3db173939011dce3655ab99b2c Mon Sep 17 00:00:00 2001 From: Bhaskar Date: Thu, 29 Aug 2024 11:45:06 +0530 Subject: [PATCH 1/2] added notification stop --- src/controllers/tanksController.js | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/controllers/tanksController.js b/src/controllers/tanksController.js index a7a7252e..df3ac654 100644 --- a/src/controllers/tanksController.js +++ b/src/controllers/tanksController.js @@ -1499,9 +1499,14 @@ exports.motorAction = async (req, reply) => { } ); clearInterval(intervalId); - + + // Send notification after motor stops due to time threshold + if (fcmToken) { + await sendNotification(fcmToken, 'Motor Stopped After Time Threshold', `Motor ${motorId} has been stopped after reaching the set time threshold.`); + } + await delay(300000); - + const motorData = await MotorData.findOne({ customerId, motor_id: motorId, start_instance_id: start_instance_id }); if (motorData) { const receiverTank = await Tank.findOne({ customerId, tankName: motorData.receiverTank, tankLocation: motorData.receiver_type.toLowerCase() }); @@ -1513,9 +1518,9 @@ exports.motorAction = async (req, reply) => { { customerId, tankName: motorData.receiverTank, tankLocation: motorData.receiver_type.toLowerCase() }, { $set: { total_water_added_from_midnight: totalwaterpumped } } ); - + const stopTime = formatDate(new Date()); - + await MotorData.updateOne( { customerId, motor_id: motorId, start_instance_id: start_instance_id }, { @@ -1526,7 +1531,6 @@ exports.motorAction = async (req, reply) => { } } ); - // Send low water level notification if (receiverFinalWaterLevel / parseInt(receiverTank.capacity, 10) * 100 <= 20) { if (fcmToken) { @@ -1534,7 +1538,7 @@ exports.motorAction = async (req, reply) => { } } } - } + } }, 60000); } else if (req.body.threshold_type === "litres") { console.log("entered litres") From 0505300de9c7a549c6c055298594df20129277ba Mon Sep 17 00:00:00 2001 From: Varun Date: Thu, 29 Aug 2024 11:46:55 +0530 Subject: [PATCH 2/2] bcrypt --- node_modules/.bin/color-support | 17 +- node_modules/.bin/node-pre-gyp | 17 +- node_modules/.bin/nopt | 17 +- node_modules/.package-lock.json | 126 +- .../@mapbox/node-pre-gyp/CHANGELOG.md | 3 + .../node-pre-gyp/node_modules/.bin/semver | 17 +- .../node_modules/lru-cache/LICENSE | 15 - .../node_modules/lru-cache/README.md | 166 - .../node_modules/lru-cache/index.js | 334 - .../node_modules/lru-cache/package.json | 34 - .../make-dir/node_modules/.bin/semver | 17 +- .../make-dir/node_modules/semver/CHANGELOG.md | 70 - .../make-dir/node_modules/semver/package.json | 28 +- .../make-dir/node_modules/semver/semver.js | 95 +- .../node_modules/semver/README.md | 152 +- .../node_modules/semver/bin/semver.js | 35 +- .../node_modules/semver/classes/comparator.js | 73 +- .../node_modules/semver/classes/range.js | 106 +- .../node_modules/semver/classes/semver.js | 51 +- .../node_modules/semver/functions/coerce.js | 20 +- .../node_modules/semver/functions/diff.js | 74 +- .../node_modules/semver/functions/inc.js | 5 +- .../node_modules/semver/functions/parse.js | 27 +- .../node-pre-gyp/node_modules/semver/index.js | 1 + .../node_modules/semver/internal/constants.js | 22 +- .../semver/internal/parse-options.js | 24 +- .../node_modules/semver/internal/re.js | 47 +- .../node_modules/semver/package.json | 33 +- .../node_modules/semver/ranges/intersects.js | 2 +- .../node_modules/semver/ranges/subset.js | 9 +- .../node-pre-gyp/node_modules/yallist/LICENSE | 15 - .../node_modules/yallist/README.md | 204 - .../node_modules/yallist/iterator.js | 8 - .../node_modules/yallist/package.json | 29 - .../node_modules/yallist/yallist.js | 426 -- .../@mapbox/node-pre-gyp/package.json | 2 +- node_modules/bcrypt/.github/workflows/ci.yaml | 42 +- node_modules/bcrypt/CHANGELOG.md | 3 + node_modules/bcrypt/bcrypt-5.1.0.tgz | Bin 32939 -> 0 bytes node_modules/bcrypt/binding.gyp | 12 +- node_modules/bcrypt/examples/async_compare.js | 39 +- .../lib/binding/napi-v3/bcrypt_lib.node | Bin 88832 -> 190464 bytes node_modules/bcrypt/package.json | 6 +- node_modules/bcrypt/test_alpine.sh | 12 - node_modules/detect-libc/README.md | 5 +- node_modules/detect-libc/index.d.ts | 3 + node_modules/detect-libc/lib/detect-libc.js | 97 +- node_modules/detect-libc/lib/process.js | 14 +- node_modules/detect-libc/package.json | 10 +- node_modules/minipass/LICENSE | 2 +- node_modules/minipass/README.md | 551 +- node_modules/minipass/index.d.ts | 45 +- node_modules/minipass/index.js | 507 +- .../minipass/node_modules/yallist/LICENSE | 15 - .../minipass/node_modules/yallist/README.md | 204 - .../minipass/node_modules/yallist/iterator.js | 8 - .../node_modules/yallist/package.json | 29 - .../minipass/node_modules/yallist/yallist.js | 426 -- node_modules/minipass/package.json | 34 +- node_modules/node-addon-api/README.md | 48 +- node_modules/node-addon-api/index.js | 6 +- .../node-addon-api/napi-inl.deprecated.h | 248 +- node_modules/node-addon-api/napi-inl.h | 2288 +++---- node_modules/node-addon-api/napi.h | 5461 +++++++++-------- node_modules/node-addon-api/package.json | 43 +- .../node-addon-api/tools/check-napi.js | 27 +- .../node-addon-api/tools/conversion.js | 330 +- .../node-addon-api/tools/eslint-format.js | 10 +- node_modules/tar/README.md | 10 + node_modules/tar/lib/normalize-unicode.js | 2 +- node_modules/tar/lib/pack.js | 28 +- node_modules/tar/lib/parse.js | 49 +- node_modules/tar/lib/path-reservations.js | 2 +- node_modules/tar/lib/read-entry.js | 4 +- node_modules/tar/lib/replace.js | 2 +- node_modules/tar/lib/unpack.js | 29 +- node_modules/tar/lib/update.js | 2 +- node_modules/tar/lib/write-entry.js | 6 +- node_modules/tar/package.json | 17 +- package-lock.json | 206 +- package.json | 2 +- 81 files changed, 6047 insertions(+), 7158 deletions(-) delete mode 100644 node_modules/@mapbox/node-pre-gyp/node_modules/lru-cache/LICENSE delete mode 100644 node_modules/@mapbox/node-pre-gyp/node_modules/lru-cache/README.md delete mode 100644 node_modules/@mapbox/node-pre-gyp/node_modules/lru-cache/index.js delete mode 100644 node_modules/@mapbox/node-pre-gyp/node_modules/lru-cache/package.json delete mode 100644 node_modules/@mapbox/node-pre-gyp/node_modules/make-dir/node_modules/semver/CHANGELOG.md delete mode 100644 node_modules/@mapbox/node-pre-gyp/node_modules/yallist/LICENSE delete mode 100644 node_modules/@mapbox/node-pre-gyp/node_modules/yallist/README.md delete mode 100644 node_modules/@mapbox/node-pre-gyp/node_modules/yallist/iterator.js delete mode 100644 node_modules/@mapbox/node-pre-gyp/node_modules/yallist/package.json delete mode 100644 node_modules/@mapbox/node-pre-gyp/node_modules/yallist/yallist.js delete mode 100644 node_modules/bcrypt/bcrypt-5.1.0.tgz delete mode 100755 node_modules/bcrypt/test_alpine.sh delete mode 100644 node_modules/minipass/node_modules/yallist/LICENSE delete mode 100644 node_modules/minipass/node_modules/yallist/README.md delete mode 100644 node_modules/minipass/node_modules/yallist/iterator.js delete mode 100644 node_modules/minipass/node_modules/yallist/package.json delete mode 100644 node_modules/minipass/node_modules/yallist/yallist.js diff --git a/node_modules/.bin/color-support b/node_modules/.bin/color-support index fcbcb286..f77f9d5b 120000 --- a/node_modules/.bin/color-support +++ b/node_modules/.bin/color-support @@ -1 +1,16 @@ -../color-support/bin.js \ No newline at end of file +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*|*MINGW*|*MSYS*) + if command -v cygpath > /dev/null 2>&1; then + basedir=`cygpath -w "$basedir"` + fi + ;; +esac + +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../color-support/bin.js" "$@" +else + exec node "$basedir/../color-support/bin.js" "$@" +fi diff --git a/node_modules/.bin/node-pre-gyp b/node_modules/.bin/node-pre-gyp index 2946e6a5..d1619e49 120000 --- a/node_modules/.bin/node-pre-gyp +++ b/node_modules/.bin/node-pre-gyp @@ -1 +1,16 @@ -../@mapbox/node-pre-gyp/bin/node-pre-gyp \ No newline at end of file +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*|*MINGW*|*MSYS*) + if command -v cygpath > /dev/null 2>&1; then + basedir=`cygpath -w "$basedir"` + fi + ;; +esac + +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../@mapbox/node-pre-gyp/bin/node-pre-gyp" "$@" +else + exec node "$basedir/../@mapbox/node-pre-gyp/bin/node-pre-gyp" "$@" +fi diff --git a/node_modules/.bin/nopt b/node_modules/.bin/nopt index 6b6566ea..0808130f 120000 --- a/node_modules/.bin/nopt +++ b/node_modules/.bin/nopt @@ -1 +1,16 @@ -../nopt/bin/nopt.js \ No newline at end of file +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*|*MINGW*|*MSYS*) + if command -v cygpath > /dev/null 2>&1; then + basedir=`cygpath -w "$basedir"` + fi + ;; +esac + +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../nopt/bin/nopt.js" "$@" +else + exec node "$basedir/../nopt/bin/nopt.js" "$@" +fi diff --git a/node_modules/.package-lock.json b/node_modules/.package-lock.json index d53631c6..76558e09 100644 --- a/node_modules/.package-lock.json +++ b/node_modules/.package-lock.json @@ -2634,9 +2634,10 @@ } }, "node_modules/@mapbox/node-pre-gyp": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.10.tgz", - "integrity": "sha512-4ySo4CjzStuprMwk35H5pPbkymjv1SF3jGLj6rAHp/xT/RF7TL7bd9CTm1xDY49K2qF7jmR/g7k+SkLETP6opA==", + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.11.tgz", + "integrity": "sha512-Yhlar6v9WQgUp/He7BdgzOz8lqMQ8sU+jkCq7Wx8Myc5YFJLbEe7lgui/V7G1qB1DJykHSGwreceSaD60Y0PUQ==", + "license": "BSD-3-Clause", "dependencies": { "detect-libc": "^2.0.0", "https-proxy-agent": "^5.0.0", @@ -2652,21 +2653,11 @@ "node-pre-gyp": "bin/node-pre-gyp" } }, - "node_modules/@mapbox/node-pre-gyp/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/@mapbox/node-pre-gyp/node_modules/make-dir": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "license": "MIT", "dependencies": { "semver": "^6.0.0" }, @@ -2678,20 +2669,19 @@ } }, "node_modules/@mapbox/node-pre-gyp/node_modules/make-dir/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "license": "ISC", "bin": { "semver": "bin/semver.js" } }, "node_modules/@mapbox/node-pre-gyp/node_modules/semver": { - "version": "7.3.8", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", - "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", - "dependencies": { - "lru-cache": "^6.0.0" - }, + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "license": "ISC", "bin": { "semver": "bin/semver.js" }, @@ -2699,11 +2689,6 @@ "node": ">=10" } }, - "node_modules/@mapbox/node-pre-gyp/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - }, "node_modules/@popperjs/core": { "version": "2.11.6", "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.6.tgz", @@ -3941,7 +3926,8 @@ "node_modules/aproba": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", - "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==" + "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==", + "license": "ISC" }, "node_modules/archiver": { "version": "5.3.1", @@ -4021,6 +4007,8 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz", "integrity": "sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==", + "deprecated": "This package is no longer supported.", + "license": "ISC", "dependencies": { "delegates": "^1.0.0", "readable-stream": "^3.6.0" @@ -4255,12 +4243,13 @@ ] }, "node_modules/bcrypt": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/bcrypt/-/bcrypt-5.1.0.tgz", - "integrity": "sha512-RHBS7HI5N5tEnGTmtR/pppX0mmDSBpQ4aCBsj7CEQfYXDcO74A8sIBYcJMuCsis2E81zDxeENYhv66oZwLiA+Q==", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/bcrypt/-/bcrypt-5.1.1.tgz", + "integrity": "sha512-AGBHOG5hPYZ5Xl9KXzU5iKq9516yEmvCKDg3ecP5kX2aB6UqTeXZxk2ELnDgDm6BQSMlLt9rDB4LoSMx0rYwww==", "hasInstallScript": true, + "license": "MIT", "dependencies": { - "@mapbox/node-pre-gyp": "^1.0.10", + "@mapbox/node-pre-gyp": "^1.0.11", "node-addon-api": "^5.0.0" }, "engines": { @@ -4660,6 +4649,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "license": "ISC", "engines": { "node": ">=10" } @@ -4798,6 +4788,7 @@ "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", + "license": "ISC", "bin": { "color-support": "bin.js" } @@ -4873,7 +4864,8 @@ "node_modules/console-control-strings": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", - "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==" + "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==", + "license": "ISC" }, "node_modules/content-disposition": { "version": "0.5.4", @@ -5207,7 +5199,8 @@ "node_modules/delegates": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", - "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==" + "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==", + "license": "MIT" }, "node_modules/denque": { "version": "1.5.1", @@ -5240,9 +5233,10 @@ } }, "node_modules/detect-libc": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.1.tgz", - "integrity": "sha512-463v3ZeIrcWtdgIg6vI6XUncguvr2TnGl4SzDXinkt9mSLpBJKXT3mW6xT3VQdDN11+WVs29pgvivTc4Lp8v+w==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz", + "integrity": "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==", + "license": "Apache-2.0", "engines": { "node": ">=8" } @@ -6735,6 +6729,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "license": "ISC", "dependencies": { "minipass": "^3.0.0" }, @@ -6746,6 +6741,7 @@ "version": "3.3.6", "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "license": "ISC", "dependencies": { "yallist": "^4.0.0" }, @@ -6756,7 +6752,8 @@ "node_modules/fs-minipass/node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "license": "ISC" }, "node_modules/fs.realpath": { "version": "1.0.0", @@ -6847,6 +6844,8 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/gauge/-/gauge-3.0.2.tgz", "integrity": "sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==", + "deprecated": "This package is no longer supported.", + "license": "ISC", "dependencies": { "aproba": "^1.0.3 || ^2.0.0", "color-support": "^1.1.2", @@ -7443,7 +7442,8 @@ "node_modules/has-unicode": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", - "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==" + "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==", + "license": "ISC" }, "node_modules/hashlru": { "version": "2.3.0", @@ -8618,25 +8618,19 @@ } }, "node_modules/minipass": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-4.0.0.tgz", - "integrity": "sha512-g2Uuh2jEKoht+zvO6vJqXmYpflPqzRBT+Th2h01DKh5z7wbY/AZ2gCQ78cP70YoHPyFdY30YBV5WxgLOEwOykw==", - "dependencies": { - "yallist": "^4.0.0" - }, + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", + "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", + "license": "ISC", "engines": { "node": ">=8" } }, - "node_modules/minipass/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - }, "node_modules/minizlib": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "license": "MIT", "dependencies": { "minipass": "^3.0.0", "yallist": "^4.0.0" @@ -8649,6 +8643,7 @@ "version": "3.3.6", "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "license": "ISC", "dependencies": { "yallist": "^4.0.0" }, @@ -8659,7 +8654,8 @@ "node_modules/minizlib/node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "license": "ISC" }, "node_modules/mkdirp": { "version": "1.0.4", @@ -9061,9 +9057,10 @@ } }, "node_modules/node-addon-api": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-5.0.0.tgz", - "integrity": "sha512-CvkDw2OEnme7ybCykJpVcKH+uAOLV2qLqiyla128dN9TkEWfrYmxG6C2boDe5KcNQqZF3orkqzGgOMvZ/JNekA==" + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-5.1.0.tgz", + "integrity": "sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA==", + "license": "MIT" }, "node_modules/node-cron": { "version": "3.0.2", @@ -9196,6 +9193,7 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==", + "license": "ISC", "dependencies": { "abbrev": "1" }, @@ -9218,6 +9216,8 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-5.0.1.tgz", "integrity": "sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==", + "deprecated": "This package is no longer supported.", + "license": "ISC", "dependencies": { "are-we-there-yet": "^2.0.0", "console-control-strings": "^1.1.0", @@ -10913,7 +10913,8 @@ "node_modules/set-blocking": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==" + "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", + "license": "ISC" }, "node_modules/set-cookie-parser": { "version": "2.5.1", @@ -11395,13 +11396,14 @@ } }, "node_modules/tar": { - "version": "6.1.13", - "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.13.tgz", - "integrity": "sha512-jdIBIN6LTIe2jqzay/2vtYLlBHa3JF42ot3h1dW8Q0PaAG4v8rm0cvpVePtau5C6OKXGGcgO9q2AMNSWxiLqKw==", + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz", + "integrity": "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==", + "license": "ISC", "dependencies": { "chownr": "^2.0.0", "fs-minipass": "^2.0.0", - "minipass": "^4.0.0", + "minipass": "^5.0.0", "minizlib": "^2.1.1", "mkdirp": "^1.0.3", "yallist": "^4.0.0" @@ -11438,7 +11440,8 @@ "node_modules/tar/node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "license": "ISC" }, "node_modules/teeny-request": { "version": "8.0.3", @@ -12373,6 +12376,7 @@ "version": "1.1.5", "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz", "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==", + "license": "ISC", "dependencies": { "string-width": "^1.0.2 || 2 || 3 || 4" } diff --git a/node_modules/@mapbox/node-pre-gyp/CHANGELOG.md b/node_modules/@mapbox/node-pre-gyp/CHANGELOG.md index b07e75cb..990e9297 100644 --- a/node_modules/@mapbox/node-pre-gyp/CHANGELOG.md +++ b/node_modules/@mapbox/node-pre-gyp/CHANGELOG.md @@ -1,5 +1,8 @@ # node-pre-gyp changelog +## 1.0.11 +- Fixes dependabot alert [CVE-2021-44906](https://nvd.nist.gov/vuln/detail/CVE-2021-44906) + ## 1.0.10 - Upgraded minimist to 1.2.6 to address dependabot alert [CVE-2021-44906](https://nvd.nist.gov/vuln/detail/CVE-2021-44906) diff --git a/node_modules/@mapbox/node-pre-gyp/node_modules/.bin/semver b/node_modules/@mapbox/node-pre-gyp/node_modules/.bin/semver index 5aaadf42..97c53279 120000 --- a/node_modules/@mapbox/node-pre-gyp/node_modules/.bin/semver +++ b/node_modules/@mapbox/node-pre-gyp/node_modules/.bin/semver @@ -1 +1,16 @@ -../semver/bin/semver.js \ No newline at end of file +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*|*MINGW*|*MSYS*) + if command -v cygpath > /dev/null 2>&1; then + basedir=`cygpath -w "$basedir"` + fi + ;; +esac + +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../semver/bin/semver.js" "$@" +else + exec node "$basedir/../semver/bin/semver.js" "$@" +fi diff --git a/node_modules/@mapbox/node-pre-gyp/node_modules/lru-cache/LICENSE b/node_modules/@mapbox/node-pre-gyp/node_modules/lru-cache/LICENSE deleted file mode 100644 index 19129e31..00000000 --- a/node_modules/@mapbox/node-pre-gyp/node_modules/lru-cache/LICENSE +++ /dev/null @@ -1,15 +0,0 @@ -The ISC License - -Copyright (c) Isaac Z. Schlueter and Contributors - -Permission to use, copy, modify, and/or distribute this software for any -purpose with or without fee is hereby granted, provided that the above -copyright notice and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR -IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/node_modules/@mapbox/node-pre-gyp/node_modules/lru-cache/README.md b/node_modules/@mapbox/node-pre-gyp/node_modules/lru-cache/README.md deleted file mode 100644 index 435dfebb..00000000 --- a/node_modules/@mapbox/node-pre-gyp/node_modules/lru-cache/README.md +++ /dev/null @@ -1,166 +0,0 @@ -# lru cache - -A cache object that deletes the least-recently-used items. - -[![Build Status](https://travis-ci.org/isaacs/node-lru-cache.svg?branch=master)](https://travis-ci.org/isaacs/node-lru-cache) [![Coverage Status](https://coveralls.io/repos/isaacs/node-lru-cache/badge.svg?service=github)](https://coveralls.io/github/isaacs/node-lru-cache) - -## Installation: - -```javascript -npm install lru-cache --save -``` - -## Usage: - -```javascript -var LRU = require("lru-cache") - , options = { max: 500 - , length: function (n, key) { return n * 2 + key.length } - , dispose: function (key, n) { n.close() } - , maxAge: 1000 * 60 * 60 } - , cache = new LRU(options) - , otherCache = new LRU(50) // sets just the max size - -cache.set("key", "value") -cache.get("key") // "value" - -// non-string keys ARE fully supported -// but note that it must be THE SAME object, not -// just a JSON-equivalent object. -var someObject = { a: 1 } -cache.set(someObject, 'a value') -// Object keys are not toString()-ed -cache.set('[object Object]', 'a different value') -assert.equal(cache.get(someObject), 'a value') -// A similar object with same keys/values won't work, -// because it's a different object identity -assert.equal(cache.get({ a: 1 }), undefined) - -cache.reset() // empty the cache -``` - -If you put more stuff in it, then items will fall out. - -If you try to put an oversized thing in it, then it'll fall out right -away. - -## Options - -* `max` The maximum size of the cache, checked by applying the length - function to all values in the cache. Not setting this is kind of - silly, since that's the whole purpose of this lib, but it defaults - to `Infinity`. Setting it to a non-number or negative number will - throw a `TypeError`. Setting it to 0 makes it be `Infinity`. -* `maxAge` Maximum age in ms. Items are not pro-actively pruned out - as they age, but if you try to get an item that is too old, it'll - drop it and return undefined instead of giving it to you. - Setting this to a negative value will make everything seem old! - Setting it to a non-number will throw a `TypeError`. -* `length` Function that is used to calculate the length of stored - items. If you're storing strings or buffers, then you probably want - to do something like `function(n, key){return n.length}`. The default is - `function(){return 1}`, which is fine if you want to store `max` - like-sized things. The item is passed as the first argument, and - the key is passed as the second argumnet. -* `dispose` Function that is called on items when they are dropped - from the cache. This can be handy if you want to close file - descriptors or do other cleanup tasks when items are no longer - accessible. Called with `key, value`. It's called *before* - actually removing the item from the internal cache, so if you want - to immediately put it back in, you'll have to do that in a - `nextTick` or `setTimeout` callback or it won't do anything. -* `stale` By default, if you set a `maxAge`, it'll only actually pull - stale items out of the cache when you `get(key)`. (That is, it's - not pre-emptively doing a `setTimeout` or anything.) If you set - `stale:true`, it'll return the stale value before deleting it. If - you don't set this, then it'll return `undefined` when you try to - get a stale entry, as if it had already been deleted. -* `noDisposeOnSet` By default, if you set a `dispose()` method, then - it'll be called whenever a `set()` operation overwrites an existing - key. If you set this option, `dispose()` will only be called when a - key falls out of the cache, not when it is overwritten. -* `updateAgeOnGet` When using time-expiring entries with `maxAge`, - setting this to `true` will make each item's effective time update - to the current time whenever it is retrieved from cache, causing it - to not expire. (It can still fall out of cache based on recency of - use, of course.) - -## API - -* `set(key, value, maxAge)` -* `get(key) => value` - - Both of these will update the "recently used"-ness of the key. - They do what you think. `maxAge` is optional and overrides the - cache `maxAge` option if provided. - - If the key is not found, `get()` will return `undefined`. - - The key and val can be any value. - -* `peek(key)` - - Returns the key value (or `undefined` if not found) without - updating the "recently used"-ness of the key. - - (If you find yourself using this a lot, you *might* be using the - wrong sort of data structure, but there are some use cases where - it's handy.) - -* `del(key)` - - Deletes a key out of the cache. - -* `reset()` - - Clear the cache entirely, throwing away all values. - -* `has(key)` - - Check if a key is in the cache, without updating the recent-ness - or deleting it for being stale. - -* `forEach(function(value,key,cache), [thisp])` - - Just like `Array.prototype.forEach`. Iterates over all the keys - in the cache, in order of recent-ness. (Ie, more recently used - items are iterated over first.) - -* `rforEach(function(value,key,cache), [thisp])` - - The same as `cache.forEach(...)` but items are iterated over in - reverse order. (ie, less recently used items are iterated over - first.) - -* `keys()` - - Return an array of the keys in the cache. - -* `values()` - - Return an array of the values in the cache. - -* `length` - - Return total length of objects in cache taking into account - `length` options function. - -* `itemCount` - - Return total quantity of objects currently in cache. Note, that - `stale` (see options) items are returned as part of this item - count. - -* `dump()` - - Return an array of the cache entries ready for serialization and usage - with 'destinationCache.load(arr)`. - -* `load(cacheEntriesArray)` - - Loads another cache entries array, obtained with `sourceCache.dump()`, - into the cache. The destination cache is reset before loading new entries - -* `prune()` - - Manually iterates over the entire cache proactively pruning old entries diff --git a/node_modules/@mapbox/node-pre-gyp/node_modules/lru-cache/index.js b/node_modules/@mapbox/node-pre-gyp/node_modules/lru-cache/index.js deleted file mode 100644 index 573b6b85..00000000 --- a/node_modules/@mapbox/node-pre-gyp/node_modules/lru-cache/index.js +++ /dev/null @@ -1,334 +0,0 @@ -'use strict' - -// A linked list to keep track of recently-used-ness -const Yallist = require('yallist') - -const MAX = Symbol('max') -const LENGTH = Symbol('length') -const LENGTH_CALCULATOR = Symbol('lengthCalculator') -const ALLOW_STALE = Symbol('allowStale') -const MAX_AGE = Symbol('maxAge') -const DISPOSE = Symbol('dispose') -const NO_DISPOSE_ON_SET = Symbol('noDisposeOnSet') -const LRU_LIST = Symbol('lruList') -const CACHE = Symbol('cache') -const UPDATE_AGE_ON_GET = Symbol('updateAgeOnGet') - -const naiveLength = () => 1 - -// lruList is a yallist where the head is the youngest -// item, and the tail is the oldest. the list contains the Hit -// objects as the entries. -// Each Hit object has a reference to its Yallist.Node. This -// never changes. -// -// cache is a Map (or PseudoMap) that matches the keys to -// the Yallist.Node object. -class LRUCache { - constructor (options) { - if (typeof options === 'number') - options = { max: options } - - if (!options) - options = {} - - if (options.max && (typeof options.max !== 'number' || options.max < 0)) - throw new TypeError('max must be a non-negative number') - // Kind of weird to have a default max of Infinity, but oh well. - const max = this[MAX] = options.max || Infinity - - const lc = options.length || naiveLength - this[LENGTH_CALCULATOR] = (typeof lc !== 'function') ? naiveLength : lc - this[ALLOW_STALE] = options.stale || false - if (options.maxAge && typeof options.maxAge !== 'number') - throw new TypeError('maxAge must be a number') - this[MAX_AGE] = options.maxAge || 0 - this[DISPOSE] = options.dispose - this[NO_DISPOSE_ON_SET] = options.noDisposeOnSet || false - this[UPDATE_AGE_ON_GET] = options.updateAgeOnGet || false - this.reset() - } - - // resize the cache when the max changes. - set max (mL) { - if (typeof mL !== 'number' || mL < 0) - throw new TypeError('max must be a non-negative number') - - this[MAX] = mL || Infinity - trim(this) - } - get max () { - return this[MAX] - } - - set allowStale (allowStale) { - this[ALLOW_STALE] = !!allowStale - } - get allowStale () { - return this[ALLOW_STALE] - } - - set maxAge (mA) { - if (typeof mA !== 'number') - throw new TypeError('maxAge must be a non-negative number') - - this[MAX_AGE] = mA - trim(this) - } - get maxAge () { - return this[MAX_AGE] - } - - // resize the cache when the lengthCalculator changes. - set lengthCalculator (lC) { - if (typeof lC !== 'function') - lC = naiveLength - - if (lC !== this[LENGTH_CALCULATOR]) { - this[LENGTH_CALCULATOR] = lC - this[LENGTH] = 0 - this[LRU_LIST].forEach(hit => { - hit.length = this[LENGTH_CALCULATOR](hit.value, hit.key) - this[LENGTH] += hit.length - }) - } - trim(this) - } - get lengthCalculator () { return this[LENGTH_CALCULATOR] } - - get length () { return this[LENGTH] } - get itemCount () { return this[LRU_LIST].length } - - rforEach (fn, thisp) { - thisp = thisp || this - for (let walker = this[LRU_LIST].tail; walker !== null;) { - const prev = walker.prev - forEachStep(this, fn, walker, thisp) - walker = prev - } - } - - forEach (fn, thisp) { - thisp = thisp || this - for (let walker = this[LRU_LIST].head; walker !== null;) { - const next = walker.next - forEachStep(this, fn, walker, thisp) - walker = next - } - } - - keys () { - return this[LRU_LIST].toArray().map(k => k.key) - } - - values () { - return this[LRU_LIST].toArray().map(k => k.value) - } - - reset () { - if (this[DISPOSE] && - this[LRU_LIST] && - this[LRU_LIST].length) { - this[LRU_LIST].forEach(hit => this[DISPOSE](hit.key, hit.value)) - } - - this[CACHE] = new Map() // hash of items by key - this[LRU_LIST] = new Yallist() // list of items in order of use recency - this[LENGTH] = 0 // length of items in the list - } - - dump () { - return this[LRU_LIST].map(hit => - isStale(this, hit) ? false : { - k: hit.key, - v: hit.value, - e: hit.now + (hit.maxAge || 0) - }).toArray().filter(h => h) - } - - dumpLru () { - return this[LRU_LIST] - } - - set (key, value, maxAge) { - maxAge = maxAge || this[MAX_AGE] - - if (maxAge && typeof maxAge !== 'number') - throw new TypeError('maxAge must be a number') - - const now = maxAge ? Date.now() : 0 - const len = this[LENGTH_CALCULATOR](value, key) - - if (this[CACHE].has(key)) { - if (len > this[MAX]) { - del(this, this[CACHE].get(key)) - return false - } - - const node = this[CACHE].get(key) - const item = node.value - - // dispose of the old one before overwriting - // split out into 2 ifs for better coverage tracking - if (this[DISPOSE]) { - if (!this[NO_DISPOSE_ON_SET]) - this[DISPOSE](key, item.value) - } - - item.now = now - item.maxAge = maxAge - item.value = value - this[LENGTH] += len - item.length - item.length = len - this.get(key) - trim(this) - return true - } - - const hit = new Entry(key, value, len, now, maxAge) - - // oversized objects fall out of cache automatically. - if (hit.length > this[MAX]) { - if (this[DISPOSE]) - this[DISPOSE](key, value) - - return false - } - - this[LENGTH] += hit.length - this[LRU_LIST].unshift(hit) - this[CACHE].set(key, this[LRU_LIST].head) - trim(this) - return true - } - - has (key) { - if (!this[CACHE].has(key)) return false - const hit = this[CACHE].get(key).value - return !isStale(this, hit) - } - - get (key) { - return get(this, key, true) - } - - peek (key) { - return get(this, key, false) - } - - pop () { - const node = this[LRU_LIST].tail - if (!node) - return null - - del(this, node) - return node.value - } - - del (key) { - del(this, this[CACHE].get(key)) - } - - load (arr) { - // reset the cache - this.reset() - - const now = Date.now() - // A previous serialized cache has the most recent items first - for (let l = arr.length - 1; l >= 0; l--) { - const hit = arr[l] - const expiresAt = hit.e || 0 - if (expiresAt === 0) - // the item was created without expiration in a non aged cache - this.set(hit.k, hit.v) - else { - const maxAge = expiresAt - now - // dont add already expired items - if (maxAge > 0) { - this.set(hit.k, hit.v, maxAge) - } - } - } - } - - prune () { - this[CACHE].forEach((value, key) => get(this, key, false)) - } -} - -const get = (self, key, doUse) => { - const node = self[CACHE].get(key) - if (node) { - const hit = node.value - if (isStale(self, hit)) { - del(self, node) - if (!self[ALLOW_STALE]) - return undefined - } else { - if (doUse) { - if (self[UPDATE_AGE_ON_GET]) - node.value.now = Date.now() - self[LRU_LIST].unshiftNode(node) - } - } - return hit.value - } -} - -const isStale = (self, hit) => { - if (!hit || (!hit.maxAge && !self[MAX_AGE])) - return false - - const diff = Date.now() - hit.now - return hit.maxAge ? diff > hit.maxAge - : self[MAX_AGE] && (diff > self[MAX_AGE]) -} - -const trim = self => { - if (self[LENGTH] > self[MAX]) { - for (let walker = self[LRU_LIST].tail; - self[LENGTH] > self[MAX] && walker !== null;) { - // We know that we're about to delete this one, and also - // what the next least recently used key will be, so just - // go ahead and set it now. - const prev = walker.prev - del(self, walker) - walker = prev - } - } -} - -const del = (self, node) => { - if (node) { - const hit = node.value - if (self[DISPOSE]) - self[DISPOSE](hit.key, hit.value) - - self[LENGTH] -= hit.length - self[CACHE].delete(hit.key) - self[LRU_LIST].removeNode(node) - } -} - -class Entry { - constructor (key, value, length, now, maxAge) { - this.key = key - this.value = value - this.length = length - this.now = now - this.maxAge = maxAge || 0 - } -} - -const forEachStep = (self, fn, node, thisp) => { - let hit = node.value - if (isStale(self, hit)) { - del(self, node) - if (!self[ALLOW_STALE]) - hit = undefined - } - if (hit) - fn.call(thisp, hit.value, hit.key, self) -} - -module.exports = LRUCache diff --git a/node_modules/@mapbox/node-pre-gyp/node_modules/lru-cache/package.json b/node_modules/@mapbox/node-pre-gyp/node_modules/lru-cache/package.json deleted file mode 100644 index 43b7502c..00000000 --- a/node_modules/@mapbox/node-pre-gyp/node_modules/lru-cache/package.json +++ /dev/null @@ -1,34 +0,0 @@ -{ - "name": "lru-cache", - "description": "A cache object that deletes the least-recently-used items.", - "version": "6.0.0", - "author": "Isaac Z. Schlueter ", - "keywords": [ - "mru", - "lru", - "cache" - ], - "scripts": { - "test": "tap", - "snap": "tap", - "preversion": "npm test", - "postversion": "npm publish", - "prepublishOnly": "git push origin --follow-tags" - }, - "main": "index.js", - "repository": "git://github.com/isaacs/node-lru-cache.git", - "devDependencies": { - "benchmark": "^2.1.4", - "tap": "^14.10.7" - }, - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, - "files": [ - "index.js" - ], - "engines": { - "node": ">=10" - } -} diff --git a/node_modules/@mapbox/node-pre-gyp/node_modules/make-dir/node_modules/.bin/semver b/node_modules/@mapbox/node-pre-gyp/node_modules/make-dir/node_modules/.bin/semver index 5aaadf42..97c53279 120000 --- a/node_modules/@mapbox/node-pre-gyp/node_modules/make-dir/node_modules/.bin/semver +++ b/node_modules/@mapbox/node-pre-gyp/node_modules/make-dir/node_modules/.bin/semver @@ -1 +1,16 @@ -../semver/bin/semver.js \ No newline at end of file +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*|*MINGW*|*MSYS*) + if command -v cygpath > /dev/null 2>&1; then + basedir=`cygpath -w "$basedir"` + fi + ;; +esac + +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../semver/bin/semver.js" "$@" +else + exec node "$basedir/../semver/bin/semver.js" "$@" +fi diff --git a/node_modules/@mapbox/node-pre-gyp/node_modules/make-dir/node_modules/semver/CHANGELOG.md b/node_modules/@mapbox/node-pre-gyp/node_modules/make-dir/node_modules/semver/CHANGELOG.md deleted file mode 100644 index f567dd3f..00000000 --- a/node_modules/@mapbox/node-pre-gyp/node_modules/make-dir/node_modules/semver/CHANGELOG.md +++ /dev/null @@ -1,70 +0,0 @@ -# changes log - -## 6.2.0 - -* Coerce numbers to strings when passed to semver.coerce() -* Add `rtl` option to coerce from right to left - -## 6.1.3 - -* Handle X-ranges properly in includePrerelease mode - -## 6.1.2 - -* Do not throw when testing invalid version strings - -## 6.1.1 - -* Add options support for semver.coerce() -* Handle undefined version passed to Range.test - -## 6.1.0 - -* Add semver.compareBuild function -* Support `*` in semver.intersects - -## 6.0 - -* Fix `intersects` logic. - - This is technically a bug fix, but since it is also a change to behavior - that may require users updating their code, it is marked as a major - version increment. - -## 5.7 - -* Add `minVersion` method - -## 5.6 - -* Move boolean `loose` param to an options object, with - backwards-compatibility protection. -* Add ability to opt out of special prerelease version handling with - the `includePrerelease` option flag. - -## 5.5 - -* Add version coercion capabilities - -## 5.4 - -* Add intersection checking - -## 5.3 - -* Add `minSatisfying` method - -## 5.2 - -* Add `prerelease(v)` that returns prerelease components - -## 5.1 - -* Add Backus-Naur for ranges -* Remove excessively cute inspection methods - -## 5.0 - -* Remove AMD/Browserified build artifacts -* Fix ltr and gtr when using the `*` range -* Fix for range `*` with a prerelease identifier diff --git a/node_modules/@mapbox/node-pre-gyp/node_modules/make-dir/node_modules/semver/package.json b/node_modules/@mapbox/node-pre-gyp/node_modules/make-dir/node_modules/semver/package.json index bdd442f5..6b970a62 100644 --- a/node_modules/@mapbox/node-pre-gyp/node_modules/make-dir/node_modules/semver/package.json +++ b/node_modules/@mapbox/node-pre-gyp/node_modules/make-dir/node_modules/semver/package.json @@ -1,19 +1,26 @@ { "name": "semver", - "version": "6.3.0", + "version": "6.3.1", "description": "The semantic version parser used by npm.", "main": "semver.js", "scripts": { - "test": "tap", - "preversion": "npm test", - "postversion": "npm publish", - "postpublish": "git push origin --follow-tags" + "test": "tap test/ --100 --timeout=30", + "lint": "echo linting disabled", + "postlint": "template-oss-check", + "template-oss-apply": "template-oss-apply --force", + "lintfix": "npm run lint -- --fix", + "snap": "tap test/ --100 --timeout=30", + "posttest": "npm run lint" }, "devDependencies": { - "tap": "^14.3.1" + "@npmcli/template-oss": "4.17.0", + "tap": "^12.7.0" }, "license": "ISC", - "repository": "https://github.com/npm/node-semver", + "repository": { + "type": "git", + "url": "https://github.com/npm/node-semver.git" + }, "bin": { "semver": "./bin/semver.js" }, @@ -22,7 +29,10 @@ "range.bnf", "semver.js" ], - "tap": { - "check-coverage": true + "author": "GitHub Inc.", + "templateOSS": { + "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", + "content": "./scripts/template-oss", + "version": "4.17.0" } } diff --git a/node_modules/@mapbox/node-pre-gyp/node_modules/make-dir/node_modules/semver/semver.js b/node_modules/@mapbox/node-pre-gyp/node_modules/make-dir/node_modules/semver/semver.js index 636fa436..39319c13 100644 --- a/node_modules/@mapbox/node-pre-gyp/node_modules/make-dir/node_modules/semver/semver.js +++ b/node_modules/@mapbox/node-pre-gyp/node_modules/make-dir/node_modules/semver/semver.js @@ -26,8 +26,11 @@ var MAX_SAFE_INTEGER = Number.MAX_SAFE_INTEGER || // Max safe segment length for coercion. var MAX_SAFE_COMPONENT_LENGTH = 16 +var MAX_SAFE_BUILD_LENGTH = MAX_LENGTH - 6 + // The actual regexps go on exports.re var re = exports.re = [] +var safeRe = exports.safeRe = [] var src = exports.src = [] var t = exports.tokens = {} var R = 0 @@ -36,6 +39,31 @@ function tok (n) { t[n] = R++ } +var LETTERDASHNUMBER = '[a-zA-Z0-9-]' + +// Replace some greedy regex tokens to prevent regex dos issues. These regex are +// used internally via the safeRe object since all inputs in this library get +// normalized first to trim and collapse all extra whitespace. The original +// regexes are exported for userland consumption and lower level usage. A +// future breaking change could export the safer regex only with a note that +// all input should have extra whitespace removed. +var safeRegexReplacements = [ + ['\\s', 1], + ['\\d', MAX_LENGTH], + [LETTERDASHNUMBER, MAX_SAFE_BUILD_LENGTH], +] + +function makeSafeRe (value) { + for (var i = 0; i < safeRegexReplacements.length; i++) { + var token = safeRegexReplacements[i][0] + var max = safeRegexReplacements[i][1] + value = value + .split(token + '*').join(token + '{0,' + max + '}') + .split(token + '+').join(token + '{1,' + max + '}') + } + return value +} + // The following Regular Expressions can be used for tokenizing, // validating, and parsing SemVer version strings. @@ -45,14 +73,14 @@ function tok (n) { tok('NUMERICIDENTIFIER') src[t.NUMERICIDENTIFIER] = '0|[1-9]\\d*' tok('NUMERICIDENTIFIERLOOSE') -src[t.NUMERICIDENTIFIERLOOSE] = '[0-9]+' +src[t.NUMERICIDENTIFIERLOOSE] = '\\d+' // ## Non-numeric Identifier // Zero or more digits, followed by a letter or hyphen, and then zero or // more letters, digits, or hyphens. tok('NONNUMERICIDENTIFIER') -src[t.NONNUMERICIDENTIFIER] = '\\d*[a-zA-Z-][a-zA-Z0-9-]*' +src[t.NONNUMERICIDENTIFIER] = '\\d*[a-zA-Z-]' + LETTERDASHNUMBER + '*' // ## Main Version // Three dot-separated numeric identifiers. @@ -94,7 +122,7 @@ src[t.PRERELEASELOOSE] = '(?:-?(' + src[t.PRERELEASEIDENTIFIERLOOSE] + // Any combination of digits, letters, or hyphens. tok('BUILDIDENTIFIER') -src[t.BUILDIDENTIFIER] = '[0-9A-Za-z-]+' +src[t.BUILDIDENTIFIER] = LETTERDASHNUMBER + '+' // ## Build Metadata // Plus sign, followed by one or more period-separated build metadata @@ -174,6 +202,7 @@ src[t.COERCE] = '(^|[^\\d])' + '(?:$|[^\\d])' tok('COERCERTL') re[t.COERCERTL] = new RegExp(src[t.COERCE], 'g') +safeRe[t.COERCERTL] = new RegExp(makeSafeRe(src[t.COERCE]), 'g') // Tilde ranges. // Meaning is "reasonably at or greater than" @@ -183,6 +212,7 @@ src[t.LONETILDE] = '(?:~>?)' tok('TILDETRIM') src[t.TILDETRIM] = '(\\s*)' + src[t.LONETILDE] + '\\s+' re[t.TILDETRIM] = new RegExp(src[t.TILDETRIM], 'g') +safeRe[t.TILDETRIM] = new RegExp(makeSafeRe(src[t.TILDETRIM]), 'g') var tildeTrimReplace = '$1~' tok('TILDE') @@ -198,6 +228,7 @@ src[t.LONECARET] = '(?:\\^)' tok('CARETTRIM') src[t.CARETTRIM] = '(\\s*)' + src[t.LONECARET] + '\\s+' re[t.CARETTRIM] = new RegExp(src[t.CARETTRIM], 'g') +safeRe[t.CARETTRIM] = new RegExp(makeSafeRe(src[t.CARETTRIM]), 'g') var caretTrimReplace = '$1^' tok('CARET') @@ -219,6 +250,7 @@ src[t.COMPARATORTRIM] = '(\\s*)' + src[t.GTLT] + // this one has to use the /g flag re[t.COMPARATORTRIM] = new RegExp(src[t.COMPARATORTRIM], 'g') +safeRe[t.COMPARATORTRIM] = new RegExp(makeSafeRe(src[t.COMPARATORTRIM]), 'g') var comparatorTrimReplace = '$1$2$3' // Something like `1.2.3 - 1.2.4` @@ -247,6 +279,14 @@ for (var i = 0; i < R; i++) { debug(i, src[i]) if (!re[i]) { re[i] = new RegExp(src[i]) + + // Replace all greedy whitespace to prevent regex dos issues. These regex are + // used internally via the safeRe object since all inputs in this library get + // normalized first to trim and collapse all extra whitespace. The original + // regexes are exported for userland consumption and lower level usage. A + // future breaking change could export the safer regex only with a note that + // all input should have extra whitespace removed. + safeRe[i] = new RegExp(makeSafeRe(src[i])) } } @@ -271,7 +311,7 @@ function parse (version, options) { return null } - var r = options.loose ? re[t.LOOSE] : re[t.FULL] + var r = options.loose ? safeRe[t.LOOSE] : safeRe[t.FULL] if (!r.test(version)) { return null } @@ -326,7 +366,7 @@ function SemVer (version, options) { this.options = options this.loose = !!options.loose - var m = version.trim().match(options.loose ? re[t.LOOSE] : re[t.FULL]) + var m = version.trim().match(options.loose ? safeRe[t.LOOSE] : safeRe[t.FULL]) if (!m) { throw new TypeError('Invalid Version: ' + version) @@ -771,6 +811,7 @@ function Comparator (comp, options) { return new Comparator(comp, options) } + comp = comp.trim().split(/\s+/).join(' ') debug('comparator', comp, options) this.options = options this.loose = !!options.loose @@ -787,7 +828,7 @@ function Comparator (comp, options) { var ANY = {} Comparator.prototype.parse = function (comp) { - var r = this.options.loose ? re[t.COMPARATORLOOSE] : re[t.COMPARATOR] + var r = this.options.loose ? safeRe[t.COMPARATORLOOSE] : safeRe[t.COMPARATOR] var m = comp.match(r) if (!m) { @@ -911,9 +952,16 @@ function Range (range, options) { this.loose = !!options.loose this.includePrerelease = !!options.includePrerelease - // First, split based on boolean or || + // First reduce all whitespace as much as possible so we do not have to rely + // on potentially slow regexes like \s*. This is then stored and used for + // future error messages as well. this.raw = range - this.set = range.split(/\s*\|\|\s*/).map(function (range) { + .trim() + .split(/\s+/) + .join(' ') + + // First, split based on boolean or || + this.set = this.raw.split('||').map(function (range) { return this.parseRange(range.trim()) }, this).filter(function (c) { // throw out any that are not relevant for whatever reason @@ -921,7 +969,7 @@ function Range (range, options) { }) if (!this.set.length) { - throw new TypeError('Invalid SemVer Range: ' + range) + throw new TypeError('Invalid SemVer Range: ' + this.raw) } this.format() @@ -940,20 +988,19 @@ Range.prototype.toString = function () { Range.prototype.parseRange = function (range) { var loose = this.options.loose - range = range.trim() // `1.2.3 - 1.2.4` => `>=1.2.3 <=1.2.4` - var hr = loose ? re[t.HYPHENRANGELOOSE] : re[t.HYPHENRANGE] + var hr = loose ? safeRe[t.HYPHENRANGELOOSE] : safeRe[t.HYPHENRANGE] range = range.replace(hr, hyphenReplace) debug('hyphen replace', range) // `> 1.2.3 < 1.2.5` => `>1.2.3 <1.2.5` - range = range.replace(re[t.COMPARATORTRIM], comparatorTrimReplace) - debug('comparator trim', range, re[t.COMPARATORTRIM]) + range = range.replace(safeRe[t.COMPARATORTRIM], comparatorTrimReplace) + debug('comparator trim', range, safeRe[t.COMPARATORTRIM]) // `~ 1.2.3` => `~1.2.3` - range = range.replace(re[t.TILDETRIM], tildeTrimReplace) + range = range.replace(safeRe[t.TILDETRIM], tildeTrimReplace) // `^ 1.2.3` => `^1.2.3` - range = range.replace(re[t.CARETTRIM], caretTrimReplace) + range = range.replace(safeRe[t.CARETTRIM], caretTrimReplace) // normalize spaces range = range.split(/\s+/).join(' ') @@ -961,7 +1008,7 @@ Range.prototype.parseRange = function (range) { // At this point, the range is completely trimmed and // ready to be split into comparators. - var compRe = loose ? re[t.COMPARATORLOOSE] : re[t.COMPARATOR] + var compRe = loose ? safeRe[t.COMPARATORLOOSE] : safeRe[t.COMPARATOR] var set = range.split(' ').map(function (comp) { return parseComparator(comp, this.options) }, this).join(' ').split(/\s+/) @@ -1061,7 +1108,7 @@ function replaceTildes (comp, options) { } function replaceTilde (comp, options) { - var r = options.loose ? re[t.TILDELOOSE] : re[t.TILDE] + var r = options.loose ? safeRe[t.TILDELOOSE] : safeRe[t.TILDE] return comp.replace(r, function (_, M, m, p, pr) { debug('tilde', comp, _, M, m, p, pr) var ret @@ -1102,7 +1149,7 @@ function replaceCarets (comp, options) { function replaceCaret (comp, options) { debug('caret', comp, options) - var r = options.loose ? re[t.CARETLOOSE] : re[t.CARET] + var r = options.loose ? safeRe[t.CARETLOOSE] : safeRe[t.CARET] return comp.replace(r, function (_, M, m, p, pr) { debug('caret', comp, _, M, m, p, pr) var ret @@ -1161,7 +1208,7 @@ function replaceXRanges (comp, options) { function replaceXRange (comp, options) { comp = comp.trim() - var r = options.loose ? re[t.XRANGELOOSE] : re[t.XRANGE] + var r = options.loose ? safeRe[t.XRANGELOOSE] : safeRe[t.XRANGE] return comp.replace(r, function (ret, gtlt, M, m, p, pr) { debug('xRange', comp, ret, gtlt, M, m, p, pr) var xM = isX(M) @@ -1236,7 +1283,7 @@ function replaceXRange (comp, options) { function replaceStars (comp, options) { debug('replaceStars', comp, options) // Looseness is ignored here. star is always as loose as it gets! - return comp.trim().replace(re[t.STAR], '') + return comp.trim().replace(safeRe[t.STAR], '') } // This function is passed to string.replace(re[t.HYPHENRANGE]) @@ -1562,7 +1609,7 @@ function coerce (version, options) { var match = null if (!options.rtl) { - match = version.match(re[t.COERCE]) + match = version.match(safeRe[t.COERCE]) } else { // Find the right-most coercible string that does not share // a terminus with a more left-ward coercible string. @@ -1573,17 +1620,17 @@ function coerce (version, options) { // Stop when we get a match that ends at the string end, since no // coercible string can be more right-ward without the same terminus. var next - while ((next = re[t.COERCERTL].exec(version)) && + while ((next = safeRe[t.COERCERTL].exec(version)) && (!match || match.index + match[0].length !== version.length) ) { if (!match || next.index + next[0].length !== match.index + match[0].length) { match = next } - re[t.COERCERTL].lastIndex = next.index + next[1].length + next[2].length + safeRe[t.COERCERTL].lastIndex = next.index + next[1].length + next[2].length } // leave it in a clean state - re[t.COERCERTL].lastIndex = -1 + safeRe[t.COERCERTL].lastIndex = -1 } if (match === null) { diff --git a/node_modules/@mapbox/node-pre-gyp/node_modules/semver/README.md b/node_modules/@mapbox/node-pre-gyp/node_modules/semver/README.md index df54e7a0..ede7b7d0 100644 --- a/node_modules/@mapbox/node-pre-gyp/node_modules/semver/README.md +++ b/node_modules/@mapbox/node-pre-gyp/node_modules/semver/README.md @@ -25,7 +25,7 @@ semver.valid(semver.coerce('v2')) // '2.0.0' semver.valid(semver.coerce('42.6.7.9.3-alpha')) // '42.6.7' ``` -You can also just load the module for the function that you care about, if +You can also just load the module for the function that you care about if you'd like to minimize your footprint. ```js @@ -78,8 +78,8 @@ const semverOutside = require('semver/ranges/outside') const semverGtr = require('semver/ranges/gtr') const semverLtr = require('semver/ranges/ltr') const semverIntersects = require('semver/ranges/intersects') -const simplifyRange = require('semver/ranges/simplify') -const rangeSubset = require('semver/ranges/subset') +const semverSimplifyRange = require('semver/ranges/simplify') +const semverRangeSubset = require('semver/ranges/subset') ``` As a command-line utility: @@ -110,6 +110,9 @@ Options: -l --loose Interpret versions and ranges loosely +-n <0|1> + This is the base to be used for the prerelease identifier. + -p --include-prerelease Always include prerelease versions in range matching @@ -141,7 +144,7 @@ A leading `"="` or `"v"` character is stripped off and ignored. ## Ranges -A `version range` is a set of `comparators` which specify versions +A `version range` is a set of `comparators` that specify versions that satisfy the range. A `comparator` is composed of an `operator` and a `version`. The set @@ -152,11 +155,13 @@ of primitive `operators` is: * `>` Greater than * `>=` Greater than or equal to * `=` Equal. If no operator is specified, then equality is assumed, - so this operator is optional, but MAY be included. + so this operator is optional but MAY be included. For example, the comparator `>=1.2.7` would match the versions `1.2.7`, `1.2.8`, `2.5.3`, and `1.3.9`, but not the versions `1.2.6` -or `1.1.0`. +or `1.1.0`. The comparator `>1` is equivalent to `>=2.0.0` and +would match the versions `2.0.0` and `3.1.0`, but not the versions +`1.0.1` or `1.1.0`. Comparators can be joined by whitespace to form a `comparator set`, which is satisfied by the **intersection** of all of the comparators @@ -184,26 +189,26 @@ For example, the range `>1.2.3-alpha.3` would be allowed to match the version `1.2.3-alpha.7`, but it would *not* be satisfied by `3.4.5-alpha.9`, even though `3.4.5-alpha.9` is technically "greater than" `1.2.3-alpha.3` according to the SemVer sort rules. The version -range only accepts prerelease tags on the `1.2.3` version. The -version `3.4.5` *would* satisfy the range, because it does not have a +range only accepts prerelease tags on the `1.2.3` version. +Version `3.4.5` *would* satisfy the range because it does not have a prerelease flag, and `3.4.5` is greater than `1.2.3-alpha.7`. -The purpose for this behavior is twofold. First, prerelease versions +The purpose of this behavior is twofold. First, prerelease versions frequently are updated very quickly, and contain many breaking changes that are (by the author's design) not yet fit for public consumption. -Therefore, by default, they are excluded from range matching +Therefore, by default, they are excluded from range-matching semantics. Second, a user who has opted into using a prerelease version has -clearly indicated the intent to use *that specific* set of +indicated the intent to use *that specific* set of alpha/beta/rc versions. By including a prerelease tag in the range, the user is indicating that they are aware of the risk. However, it is still not appropriate to assume that they have opted into taking a similar risk on the *next* set of prerelease versions. Note that this behavior can be suppressed (treating all prerelease -versions as if they were normal versions, for the purpose of range -matching) by setting the `includePrerelease` flag on the options +versions as if they were normal versions, for range-matching) +by setting the `includePrerelease` flag on the options object to any [functions](https://github.com/npm/node-semver#functions) that do range matching. @@ -232,6 +237,35 @@ $ semver 1.2.4-beta.0 -i prerelease 1.2.4-beta.1 ``` +#### Prerelease Identifier Base + +The method `.inc` takes an optional parameter 'identifierBase' string +that will let you let your prerelease number as zero-based or one-based. +Set to `false` to omit the prerelease number altogether. +If you do not specify this parameter, it will default to zero-based. + +```javascript +semver.inc('1.2.3', 'prerelease', 'beta', '1') +// '1.2.4-beta.1' +``` + +```javascript +semver.inc('1.2.3', 'prerelease', 'beta', false) +// '1.2.4-beta' +``` + +command-line example: + +```bash +$ semver 1.2.3 -i prerelease --preid beta -n 1 +1.2.4-beta.1 +``` + +```bash +$ semver 1.2.3 -i prerelease --preid beta -n false +1.2.4-beta +``` + ### Advanced Range Syntax Advanced range syntax desugars to primitive comparators in @@ -367,12 +401,12 @@ All methods and classes take a final `options` object argument. All options in this object are `false` by default. The options supported are: -- `loose` Be more forgiving about not-quite-valid semver strings. +- `loose`: Be more forgiving about not-quite-valid semver strings. (Any resulting output will always be 100% strict compliant, of course.) For backwards compatibility reasons, if the `options` argument is a boolean value instead of an object, it is interpreted to be the `loose` param. -- `includePrerelease` Set to suppress the [default +- `includePrerelease`: Set to suppress the [default behavior](https://github.com/npm/node-semver#prerelease-tags) of excluding prerelease tagged versions from ranges unless they are explicitly opted into. @@ -381,16 +415,20 @@ Strict-mode Comparators and Ranges will be strict about the SemVer strings that they parse. * `valid(v)`: Return the parsed version, or null if it's not valid. -* `inc(v, release)`: Return the version incremented by the release - type (`major`, `premajor`, `minor`, `preminor`, `patch`, +* `inc(v, release, options, identifier, identifierBase)`: + Return the version incremented by the release + type (`major`, `premajor`, `minor`, `preminor`, `patch`, `prepatch`, or `prerelease`), or null if it's not valid * `premajor` in one call will bump the version up to the next major version and down to a prerelease of that major version. `preminor`, and `prepatch` work the same way. - * If called from a non-prerelease version, the `prerelease` will work the - same as `prepatch`. It increments the patch version, then makes a + * If called from a non-prerelease version, `prerelease` will work the + same as `prepatch`. It increments the patch version and then makes a prerelease. If the input version is already a prerelease it simply increments it. + * `identifier` can be used to prefix `premajor`, `preminor`, + `prepatch`, or `prerelease` version increments. `identifierBase` + is the base to be used for the `prerelease` identifier. * `prerelease(v)`: Returns an array of prerelease components, or null if none exist. Example: `prerelease('1.2.3-alpha.1') -> ['alpha', 1]` * `major(v)`: Return the major version number. @@ -408,7 +446,7 @@ strings that they parse. * `lt(v1, v2)`: `v1 < v2` * `lte(v1, v2)`: `v1 <= v2` * `eq(v1, v2)`: `v1 == v2` This is true if they're logically equivalent, - even if they're not the exact same string. You already know how to + even if they're not the same string. You already know how to compare strings. * `neq(v1, v2)`: `v1 != v2` The opposite of `eq`. * `cmp(v1, comparator, v2)`: Pass in a comparison string, and it'll call @@ -417,15 +455,22 @@ strings that they parse. invalid comparison string is provided. * `compare(v1, v2)`: Return `0` if `v1 == v2`, or `1` if `v1` is greater, or `-1` if `v2` is greater. Sorts in ascending order if passed to `Array.sort()`. -* `rcompare(v1, v2)`: The reverse of compare. Sorts an array of versions +* `rcompare(v1, v2)`: The reverse of `compare`. Sorts an array of versions in descending order when passed to `Array.sort()`. * `compareBuild(v1, v2)`: The same as `compare` but considers `build` when two versions are equal. Sorts in ascending order if passed to `Array.sort()`. - `v2` is greater. Sorts in ascending order if passed to `Array.sort()`. -* `diff(v1, v2)`: Returns difference between two versions by the release type +* `compareLoose(v1, v2)`: Short for `compare(v1, v2, { loose: true })`. +* `diff(v1, v2)`: Returns the difference between two versions by the release type (`major`, `premajor`, `minor`, `preminor`, `patch`, `prepatch`, or `prerelease`), or null if the versions are the same. +### Sorting + +* `sort(versions)`: Returns a sorted array of versions based on the `compareBuild` + function. +* `rsort(versions)`: The reverse of `sort`. Returns an array of versions based on + the `compareBuild` function in descending order. + ### Comparators * `intersects(comparator)`: Return true if the comparators intersect @@ -439,19 +484,19 @@ strings that they parse. that satisfies the range, or `null` if none of them do. * `minSatisfying(versions, range)`: Return the lowest version in the list that satisfies the range, or `null` if none of them do. -* `minVersion(range)`: Return the lowest version that can possibly match +* `minVersion(range)`: Return the lowest version that can match the given range. -* `gtr(version, range)`: Return `true` if version is greater than all the +* `gtr(version, range)`: Return `true` if the version is greater than all the versions possible in the range. -* `ltr(version, range)`: Return `true` if version is less than all the +* `ltr(version, range)`: Return `true` if the version is less than all the versions possible in the range. * `outside(version, range, hilo)`: Return true if the version is outside the bounds of the range in either the high or low direction. The `hilo` argument must be either the string `'>'` or `'<'`. (This is the function called by `gtr` and `ltr`.) -* `intersects(range)`: Return true if any of the ranges comparators intersect +* `intersects(range)`: Return true if any of the range comparators intersect. * `simplifyRange(versions, range)`: Return a "simplified" range that - matches the same items in `versions` list as the range specified. Note + matches the same items in the `versions` list as the range specified. Note that it does *not* guarantee that it would match the same versions in all cases, only for the set of versions provided. This is useful when generating ranges by joining together multiple versions with `||` @@ -464,7 +509,7 @@ strings that they parse. Note that, since ranges may be non-contiguous, a version might not be greater than a range, less than a range, *or* satisfy a range! For example, the range `1.2 <1.2.9 || >2.0.0` would have a hole from `1.2.9` -until `2.0.0`, so the version `1.2.10` would not be greater than the +until `2.0.0`, so version `1.2.10` would not be greater than the range (because `2.0.1` satisfies, which is higher), nor less than the range (since `1.2.8` satisfies, which is lower), and it also does not satisfy the range. @@ -477,13 +522,13 @@ range, use the `satisfies(version, range)` function. * `coerce(version, options)`: Coerces a string to semver if possible This aims to provide a very forgiving translation of a non-semver string to -semver. It looks for the first digit in a string, and consumes all +semver. It looks for the first digit in a string and consumes all remaining characters which satisfy at least a partial semver (e.g., `1`, `1.2`, `1.2.3`) up to the max permitted length (256 characters). Longer versions are simply truncated (`4.6.3.9.2-alpha2` becomes `4.6.3`). All surrounding text is simply ignored (`v3.4 replaces v3.3.1` becomes `3.4.0`). Only text which lacks digits will fail coercion (`version one` -is not valid). The maximum length for any semver component considered for +is not valid). The maximum length for any semver component considered for coercion is 16 characters; longer components will be ignored (`10000000000000000.4.7.4` becomes `4.7.4`). The maximum value for any semver component is `Number.MAX_SAFE_INTEGER || (2**53 - 1)`; higher value @@ -495,6 +540,10 @@ tuple. For example, `1.2.3.4` will return `2.3.4` in rtl mode, not `4.0.0`. `1.2.3/4` will return `4.0.0`, because the `4` is not a part of any other overlapping SemVer tuple. +If the `options.includePrerelease` flag is set, then the `coerce` result will contain +prerelease and build parts of a version. For example, `1.2.3.4-rc.1+rev.2` +will preserve prerelease `rc.1` and build `rev.2` in the result. + ### Clean * `clean(version)`: Clean a string to be a valid semver if possible @@ -509,10 +558,44 @@ ex. * `s.clean(' = v 2.1.5-foo')`: `null` * `s.clean(' = v 2.1.5-foo', { loose: true })`: `'2.1.5-foo'` * `s.clean('=v2.1.5')`: `'2.1.5'` -* `s.clean(' =v2.1.5')`: `2.1.5` +* `s.clean(' =v2.1.5')`: `'2.1.5'` * `s.clean(' 2.1.5 ')`: `'2.1.5'` * `s.clean('~1.0.0')`: `null` +## Constants + +As a convenience, helper constants are exported to provide information about what `node-semver` supports: + +### `RELEASE_TYPES` + +- major +- premajor +- minor +- preminor +- patch +- prepatch +- prerelease + +``` +const semver = require('semver'); + +if (semver.RELEASE_TYPES.includes(arbitraryUserInput)) { + console.log('This is a valid release type!'); +} else { + console.warn('This is NOT a valid release type!'); +} +``` + +### `SEMVER_SPEC_VERSION` + +2.0.0 + +``` +const semver = require('semver'); + +console.log('We are currently using the semver specification version:', semver.SEMVER_SPEC_VERSION); +``` + ## Exported Modules -You may pull in just the part of this semver utility that you need, if you +You may pull in just the part of this semver utility that you need if you are sensitive to packing and tree-shaking concerns. The main `require('semver')` export uses getter functions to lazily load the parts of the API that are used. @@ -564,5 +647,8 @@ The following modules are available: * `require('semver/ranges/min-satisfying')` * `require('semver/ranges/min-version')` * `require('semver/ranges/outside')` +* `require('semver/ranges/simplify')` +* `require('semver/ranges/subset')` * `require('semver/ranges/to-comparators')` * `require('semver/ranges/valid')` + diff --git a/node_modules/@mapbox/node-pre-gyp/node_modules/semver/bin/semver.js b/node_modules/@mapbox/node-pre-gyp/node_modules/semver/bin/semver.js index 8d1b5572..f62b566f 100755 --- a/node_modules/@mapbox/node-pre-gyp/node_modules/semver/bin/semver.js +++ b/node_modules/@mapbox/node-pre-gyp/node_modules/semver/bin/semver.js @@ -23,7 +23,10 @@ let rtl = false let identifier +let identifierBase + const semver = require('../') +const parseOptions = require('../internal/parse-options') let reverse = false @@ -71,6 +74,12 @@ const main = () => { case '-r': case '--range': range.push(argv.shift()) break + case '-n': + identifierBase = argv.shift() + if (identifierBase === 'false') { + identifierBase = false + } + break case '-c': case '--coerce': coerce = true break @@ -88,7 +97,7 @@ const main = () => { } } - options = { loose: loose, includePrerelease: includePrerelease, rtl: rtl } + options = parseOptions({ loose, includePrerelease, rtl }) versions = versions.map((v) => { return coerce ? (semver.coerce(v, options) || { version: v }).version : v @@ -110,7 +119,11 @@ const main = () => { return fail() } } - return success(versions) + versions + .sort((a, b) => semver[reverse ? 'rcompare' : 'compare'](a, b, options)) + .map(v => semver.clean(v, options)) + .map(v => inc ? semver.inc(v, inc, options, identifier, identifierBase) : v) + .forEach(v => console.log(v)) } const failInc = () => { @@ -120,19 +133,6 @@ const failInc = () => { const fail = () => process.exit(1) -const success = () => { - const compare = reverse ? 'rcompare' : 'compare' - versions.sort((a, b) => { - return semver[compare](a, b, options) - }).map((v) => { - return semver.clean(v, options) - }).map((v) => { - return inc ? semver.inc(v, inc, options, identifier) : v - }).forEach((v, i, _) => { - console.log(v) - }) -} - const help = () => console.log( `SemVer ${version} @@ -172,6 +172,11 @@ Options: --ltr Coerce version strings left to right (default) +-n + Base number to be used for the prerelease identifier. + Can be either 0 or 1, or false to omit the number altogether. + Defaults to 0. + Program exits successfully if any valid version satisfies all supplied ranges, and prints all satisfying versions. diff --git a/node_modules/@mapbox/node-pre-gyp/node_modules/semver/classes/comparator.js b/node_modules/@mapbox/node-pre-gyp/node_modules/semver/classes/comparator.js index 62cd204d..3d39c0ee 100644 --- a/node_modules/@mapbox/node-pre-gyp/node_modules/semver/classes/comparator.js +++ b/node_modules/@mapbox/node-pre-gyp/node_modules/semver/classes/comparator.js @@ -16,6 +16,7 @@ class Comparator { } } + comp = comp.trim().split(/\s+/).join(' ') debug('comparator', comp, options) this.options = options this.loose = !!options.loose @@ -78,13 +79,6 @@ class Comparator { throw new TypeError('a Comparator is required') } - if (!options || typeof options !== 'object') { - options = { - loose: !!options, - includePrerelease: false, - } - } - if (this.operator === '') { if (this.value === '') { return true @@ -97,39 +91,50 @@ class Comparator { return new Range(this.value, options).test(comp.semver) } - const sameDirectionIncreasing = - (this.operator === '>=' || this.operator === '>') && - (comp.operator === '>=' || comp.operator === '>') - const sameDirectionDecreasing = - (this.operator === '<=' || this.operator === '<') && - (comp.operator === '<=' || comp.operator === '<') - const sameSemVer = this.semver.version === comp.semver.version - const differentDirectionsInclusive = - (this.operator === '>=' || this.operator === '<=') && - (comp.operator === '>=' || comp.operator === '<=') - const oppositeDirectionsLessThan = - cmp(this.semver, '<', comp.semver, options) && - (this.operator === '>=' || this.operator === '>') && - (comp.operator === '<=' || comp.operator === '<') - const oppositeDirectionsGreaterThan = - cmp(this.semver, '>', comp.semver, options) && - (this.operator === '<=' || this.operator === '<') && - (comp.operator === '>=' || comp.operator === '>') - - return ( - sameDirectionIncreasing || - sameDirectionDecreasing || - (sameSemVer && differentDirectionsInclusive) || - oppositeDirectionsLessThan || - oppositeDirectionsGreaterThan - ) + options = parseOptions(options) + + // Special cases where nothing can possibly be lower + if (options.includePrerelease && + (this.value === '<0.0.0-0' || comp.value === '<0.0.0-0')) { + return false + } + if (!options.includePrerelease && + (this.value.startsWith('<0.0.0') || comp.value.startsWith('<0.0.0'))) { + return false + } + + // Same direction increasing (> or >=) + if (this.operator.startsWith('>') && comp.operator.startsWith('>')) { + return true + } + // Same direction decreasing (< or <=) + if (this.operator.startsWith('<') && comp.operator.startsWith('<')) { + return true + } + // same SemVer and both sides are inclusive (<= or >=) + if ( + (this.semver.version === comp.semver.version) && + this.operator.includes('=') && comp.operator.includes('=')) { + return true + } + // opposite directions less than + if (cmp(this.semver, '<', comp.semver, options) && + this.operator.startsWith('>') && comp.operator.startsWith('<')) { + return true + } + // opposite directions greater than + if (cmp(this.semver, '>', comp.semver, options) && + this.operator.startsWith('<') && comp.operator.startsWith('>')) { + return true + } + return false } } module.exports = Comparator const parseOptions = require('../internal/parse-options') -const { re, t } = require('../internal/re') +const { safeRe: re, t } = require('../internal/re') const cmp = require('../functions/cmp') const debug = require('../internal/debug') const SemVer = require('./semver') diff --git a/node_modules/@mapbox/node-pre-gyp/node_modules/semver/classes/range.js b/node_modules/@mapbox/node-pre-gyp/node_modules/semver/classes/range.js index a791d912..ceee2314 100644 --- a/node_modules/@mapbox/node-pre-gyp/node_modules/semver/classes/range.js +++ b/node_modules/@mapbox/node-pre-gyp/node_modules/semver/classes/range.js @@ -1,3 +1,5 @@ +const SPACE_CHARACTERS = /\s+/g + // hoisted class for cyclic dependency class Range { constructor (range, options) { @@ -18,7 +20,7 @@ class Range { // just put it in the set and return this.raw = range.value this.set = [[range]] - this.format() + this.formatted = undefined return this } @@ -26,9 +28,13 @@ class Range { this.loose = !!options.loose this.includePrerelease = !!options.includePrerelease - // First, split based on boolean or || - this.raw = range - this.set = range + // First reduce all whitespace as much as possible so we do not have to rely + // on potentially slow regexes like \s*. This is then stored and used for + // future error messages as well. + this.raw = range.trim().replace(SPACE_CHARACTERS, ' ') + + // First, split on || + this.set = this.raw .split('||') // map the range to a 2d array of comparators .map(r => this.parseRange(r.trim())) @@ -38,7 +44,7 @@ class Range { .filter(c => c.length) if (!this.set.length) { - throw new TypeError(`Invalid SemVer Range: ${range}`) + throw new TypeError(`Invalid SemVer Range: ${this.raw}`) } // if we have any that are not the null set, throw out null sets. @@ -59,16 +65,29 @@ class Range { } } - this.format() + this.formatted = undefined + } + + get range () { + if (this.formatted === undefined) { + this.formatted = '' + for (let i = 0; i < this.set.length; i++) { + if (i > 0) { + this.formatted += '||' + } + const comps = this.set[i] + for (let k = 0; k < comps.length; k++) { + if (k > 0) { + this.formatted += ' ' + } + this.formatted += comps[k].toString().trim() + } + } + } + return this.formatted } format () { - this.range = this.set - .map((comps) => { - return comps.join(' ').trim() - }) - .join('||') - .trim() return this.range } @@ -77,12 +96,12 @@ class Range { } parseRange (range) { - range = range.trim() - // memoize range parsing for performance. // this is a very hot path, and fully deterministic. - const memoOpts = Object.keys(this.options).join(',') - const memoKey = `parseRange:${memoOpts}:${range}` + const memoOpts = + (this.options.includePrerelease && FLAG_INCLUDE_PRERELEASE) | + (this.options.loose && FLAG_LOOSE) + const memoKey = memoOpts + ':' + range const cached = cache.get(memoKey) if (cached) { return cached @@ -93,18 +112,18 @@ class Range { const hr = loose ? re[t.HYPHENRANGELOOSE] : re[t.HYPHENRANGE] range = range.replace(hr, hyphenReplace(this.options.includePrerelease)) debug('hyphen replace', range) + // `> 1.2.3 < 1.2.5` => `>1.2.3 <1.2.5` range = range.replace(re[t.COMPARATORTRIM], comparatorTrimReplace) debug('comparator trim', range) // `~ 1.2.3` => `~1.2.3` range = range.replace(re[t.TILDETRIM], tildeTrimReplace) + debug('tilde trim', range) // `^ 1.2.3` => `^1.2.3` range = range.replace(re[t.CARETTRIM], caretTrimReplace) - - // normalize spaces - range = range.split(/\s+/).join(' ') + debug('caret trim', range) // At this point, the range is completely trimmed and // ready to be split into comparators. @@ -190,22 +209,24 @@ class Range { return false } } + module.exports = Range -const LRU = require('lru-cache') -const cache = new LRU({ max: 1000 }) +const LRU = require('../internal/lrucache') +const cache = new LRU() const parseOptions = require('../internal/parse-options') const Comparator = require('./comparator') const debug = require('../internal/debug') const SemVer = require('./semver') const { - re, + safeRe: re, t, comparatorTrimReplace, tildeTrimReplace, caretTrimReplace, } = require('../internal/re') +const { FLAG_INCLUDE_PRERELEASE, FLAG_LOOSE } = require('../internal/constants') const isNullSet = c => c.value === '<0.0.0-0' const isAny = c => c.value === '' @@ -253,10 +274,13 @@ const isX = id => !id || id.toLowerCase() === 'x' || id === '*' // ~1.2.3, ~>1.2.3 --> >=1.2.3 <1.3.0-0 // ~1.2.0, ~>1.2.0 --> >=1.2.0 <1.3.0-0 // ~0.0.1 --> >=0.0.1 <0.1.0-0 -const replaceTildes = (comp, options) => - comp.trim().split(/\s+/).map((c) => { - return replaceTilde(c, options) - }).join(' ') +const replaceTildes = (comp, options) => { + return comp + .trim() + .split(/\s+/) + .map((c) => replaceTilde(c, options)) + .join(' ') +} const replaceTilde = (comp, options) => { const r = options.loose ? re[t.TILDELOOSE] : re[t.TILDE] @@ -294,10 +318,13 @@ const replaceTilde = (comp, options) => { // ^1.2.0 --> >=1.2.0 <2.0.0-0 // ^0.0.1 --> >=0.0.1 <0.0.2-0 // ^0.1.0 --> >=0.1.0 <0.2.0-0 -const replaceCarets = (comp, options) => - comp.trim().split(/\s+/).map((c) => { - return replaceCaret(c, options) - }).join(' ') +const replaceCarets = (comp, options) => { + return comp + .trim() + .split(/\s+/) + .map((c) => replaceCaret(c, options)) + .join(' ') +} const replaceCaret = (comp, options) => { debug('caret', comp, options) @@ -354,9 +381,10 @@ const replaceCaret = (comp, options) => { const replaceXRanges = (comp, options) => { debug('replaceXRanges', comp, options) - return comp.split(/\s+/).map((c) => { - return replaceXRange(c, options) - }).join(' ') + return comp + .split(/\s+/) + .map((c) => replaceXRange(c, options)) + .join(' ') } const replaceXRange = (comp, options) => { @@ -439,12 +467,15 @@ const replaceXRange = (comp, options) => { const replaceStars = (comp, options) => { debug('replaceStars', comp, options) // Looseness is ignored here. star is always as loose as it gets! - return comp.trim().replace(re[t.STAR], '') + return comp + .trim() + .replace(re[t.STAR], '') } const replaceGTE0 = (comp, options) => { debug('replaceGTE0', comp, options) - return comp.trim() + return comp + .trim() .replace(re[options.includePrerelease ? t.GTE0PRE : t.GTE0], '') } @@ -453,9 +484,10 @@ const replaceGTE0 = (comp, options) => { // 1.2 - 3.4.5 => >=1.2.0 <=3.4.5 // 1.2.3 - 3.4 => >=1.2.0 <3.5.0-0 Any 3.4.x will do // 1.2 - 3.4 => >=1.2.0 <3.5.0-0 +// TODO build? const hyphenReplace = incPr => ($0, from, fM, fm, fp, fpr, fb, - to, tM, tm, tp, tpr, tb) => { + to, tM, tm, tp, tpr) => { if (isX(fM)) { from = '' } else if (isX(fm)) { @@ -482,7 +514,7 @@ const hyphenReplace = incPr => ($0, to = `<=${to}` } - return (`${from} ${to}`).trim() + return `${from} ${to}`.trim() } const testSet = (set, version, options) => { diff --git a/node_modules/@mapbox/node-pre-gyp/node_modules/semver/classes/semver.js b/node_modules/@mapbox/node-pre-gyp/node_modules/semver/classes/semver.js index af629551..13e66ce4 100644 --- a/node_modules/@mapbox/node-pre-gyp/node_modules/semver/classes/semver.js +++ b/node_modules/@mapbox/node-pre-gyp/node_modules/semver/classes/semver.js @@ -1,6 +1,6 @@ const debug = require('../internal/debug') const { MAX_LENGTH, MAX_SAFE_INTEGER } = require('../internal/constants') -const { re, t } = require('../internal/re') +const { safeRe: re, t } = require('../internal/re') const parseOptions = require('../internal/parse-options') const { compareIdentifiers } = require('../internal/identifiers') @@ -16,7 +16,7 @@ class SemVer { version = version.version } } else if (typeof version !== 'string') { - throw new TypeError(`Invalid Version: ${version}`) + throw new TypeError(`Invalid version. Must be a string. Got type "${typeof version}".`) } if (version.length > MAX_LENGTH) { @@ -158,7 +158,7 @@ class SemVer { do { const a = this.build[i] const b = other.build[i] - debug('prerelease compare', i, a, b) + debug('build compare', i, a, b) if (a === undefined && b === undefined) { return 0 } else if (b === undefined) { @@ -175,36 +175,36 @@ class SemVer { // preminor will bump the version up to the next minor release, and immediately // down to pre-release. premajor and prepatch work the same way. - inc (release, identifier) { + inc (release, identifier, identifierBase) { switch (release) { case 'premajor': this.prerelease.length = 0 this.patch = 0 this.minor = 0 this.major++ - this.inc('pre', identifier) + this.inc('pre', identifier, identifierBase) break case 'preminor': this.prerelease.length = 0 this.patch = 0 this.minor++ - this.inc('pre', identifier) + this.inc('pre', identifier, identifierBase) break case 'prepatch': // If this is already a prerelease, it will bump to the next version // drop any prereleases that might already exist, since they are not // relevant at this point. this.prerelease.length = 0 - this.inc('patch', identifier) - this.inc('pre', identifier) + this.inc('patch', identifier, identifierBase) + this.inc('pre', identifier, identifierBase) break // If the input is a non-prerelease version, this acts the same as // prepatch. case 'prerelease': if (this.prerelease.length === 0) { - this.inc('patch', identifier) + this.inc('patch', identifier, identifierBase) } - this.inc('pre', identifier) + this.inc('pre', identifier, identifierBase) break case 'major': @@ -246,9 +246,15 @@ class SemVer { break // This probably shouldn't be used publicly. // 1.0.0 'pre' would become 1.0.0-0 which is the wrong direction. - case 'pre': + case 'pre': { + const base = Number(identifierBase) ? 1 : 0 + + if (!identifier && identifierBase === false) { + throw new Error('invalid increment argument: identifier is empty') + } + if (this.prerelease.length === 0) { - this.prerelease = [0] + this.prerelease = [base] } else { let i = this.prerelease.length while (--i >= 0) { @@ -259,27 +265,36 @@ class SemVer { } if (i === -1) { // didn't increment anything - this.prerelease.push(0) + if (identifier === this.prerelease.join('.') && identifierBase === false) { + throw new Error('invalid increment argument: identifier already exists') + } + this.prerelease.push(base) } } if (identifier) { // 1.2.0-beta.1 bumps to 1.2.0-beta.2, // 1.2.0-beta.fooblz or 1.2.0-beta bumps to 1.2.0-beta.0 + let prerelease = [identifier, base] + if (identifierBase === false) { + prerelease = [identifier] + } if (compareIdentifiers(this.prerelease[0], identifier) === 0) { if (isNaN(this.prerelease[1])) { - this.prerelease = [identifier, 0] + this.prerelease = prerelease } } else { - this.prerelease = [identifier, 0] + this.prerelease = prerelease } } break - + } default: throw new Error(`invalid increment argument: ${release}`) } - this.format() - this.raw = this.version + this.raw = this.format() + if (this.build.length) { + this.raw += `+${this.build.join('.')}` + } return this } } diff --git a/node_modules/@mapbox/node-pre-gyp/node_modules/semver/functions/coerce.js b/node_modules/@mapbox/node-pre-gyp/node_modules/semver/functions/coerce.js index 2e01452f..b378dcea 100644 --- a/node_modules/@mapbox/node-pre-gyp/node_modules/semver/functions/coerce.js +++ b/node_modules/@mapbox/node-pre-gyp/node_modules/semver/functions/coerce.js @@ -1,6 +1,6 @@ const SemVer = require('../classes/semver') const parse = require('./parse') -const { re, t } = require('../internal/re') +const { safeRe: re, t } = require('../internal/re') const coerce = (version, options) => { if (version instanceof SemVer) { @@ -19,34 +19,42 @@ const coerce = (version, options) => { let match = null if (!options.rtl) { - match = version.match(re[t.COERCE]) + match = version.match(options.includePrerelease ? re[t.COERCEFULL] : re[t.COERCE]) } else { // Find the right-most coercible string that does not share // a terminus with a more left-ward coercible string. // Eg, '1.2.3.4' wants to coerce '2.3.4', not '3.4' or '4' + // With includePrerelease option set, '1.2.3.4-rc' wants to coerce '2.3.4-rc', not '2.3.4' // // Walk through the string checking with a /g regexp // Manually set the index so as to pick up overlapping matches. // Stop when we get a match that ends at the string end, since no // coercible string can be more right-ward without the same terminus. + const coerceRtlRegex = options.includePrerelease ? re[t.COERCERTLFULL] : re[t.COERCERTL] let next - while ((next = re[t.COERCERTL].exec(version)) && + while ((next = coerceRtlRegex.exec(version)) && (!match || match.index + match[0].length !== version.length) ) { if (!match || next.index + next[0].length !== match.index + match[0].length) { match = next } - re[t.COERCERTL].lastIndex = next.index + next[1].length + next[2].length + coerceRtlRegex.lastIndex = next.index + next[1].length + next[2].length } // leave it in a clean state - re[t.COERCERTL].lastIndex = -1 + coerceRtlRegex.lastIndex = -1 } if (match === null) { return null } - return parse(`${match[2]}.${match[3] || '0'}.${match[4] || '0'}`, options) + const major = match[2] + const minor = match[3] || '0' + const patch = match[4] || '0' + const prerelease = options.includePrerelease && match[5] ? `-${match[5]}` : '' + const build = options.includePrerelease && match[6] ? `+${match[6]}` : '' + + return parse(`${major}.${minor}.${patch}${prerelease}${build}`, options) } module.exports = coerce diff --git a/node_modules/@mapbox/node-pre-gyp/node_modules/semver/functions/diff.js b/node_modules/@mapbox/node-pre-gyp/node_modules/semver/functions/diff.js index 87200ef3..fc224e30 100644 --- a/node_modules/@mapbox/node-pre-gyp/node_modules/semver/functions/diff.js +++ b/node_modules/@mapbox/node-pre-gyp/node_modules/semver/functions/diff.js @@ -1,23 +1,65 @@ -const parse = require('./parse') -const eq = require('./eq') +const parse = require('./parse.js') const diff = (version1, version2) => { - if (eq(version1, version2)) { + const v1 = parse(version1, null, true) + const v2 = parse(version2, null, true) + const comparison = v1.compare(v2) + + if (comparison === 0) { return null - } else { - const v1 = parse(version1) - const v2 = parse(version2) - const hasPre = v1.prerelease.length || v2.prerelease.length - const prefix = hasPre ? 'pre' : '' - const defaultResult = hasPre ? 'prerelease' : '' - for (const key in v1) { - if (key === 'major' || key === 'minor' || key === 'patch') { - if (v1[key] !== v2[key]) { - return prefix + key - } - } + } + + const v1Higher = comparison > 0 + const highVersion = v1Higher ? v1 : v2 + const lowVersion = v1Higher ? v2 : v1 + const highHasPre = !!highVersion.prerelease.length + const lowHasPre = !!lowVersion.prerelease.length + + if (lowHasPre && !highHasPre) { + // Going from prerelease -> no prerelease requires some special casing + + // If the low version has only a major, then it will always be a major + // Some examples: + // 1.0.0-1 -> 1.0.0 + // 1.0.0-1 -> 1.1.1 + // 1.0.0-1 -> 2.0.0 + if (!lowVersion.patch && !lowVersion.minor) { + return 'major' + } + + // Otherwise it can be determined by checking the high version + + if (highVersion.patch) { + // anything higher than a patch bump would result in the wrong version + return 'patch' + } + + if (highVersion.minor) { + // anything higher than a minor bump would result in the wrong version + return 'minor' } - return defaultResult // may be undefined + + // bumping major/minor/patch all have same result + return 'major' + } + + // add the `pre` prefix if we are going to a prerelease version + const prefix = highHasPre ? 'pre' : '' + + if (v1.major !== v2.major) { + return prefix + 'major' + } + + if (v1.minor !== v2.minor) { + return prefix + 'minor' + } + + if (v1.patch !== v2.patch) { + return prefix + 'patch' } + + // high and low are preleases + return 'prerelease' } + module.exports = diff diff --git a/node_modules/@mapbox/node-pre-gyp/node_modules/semver/functions/inc.js b/node_modules/@mapbox/node-pre-gyp/node_modules/semver/functions/inc.js index 62d1da2c..7670b1be 100644 --- a/node_modules/@mapbox/node-pre-gyp/node_modules/semver/functions/inc.js +++ b/node_modules/@mapbox/node-pre-gyp/node_modules/semver/functions/inc.js @@ -1,7 +1,8 @@ const SemVer = require('../classes/semver') -const inc = (version, release, options, identifier) => { +const inc = (version, release, options, identifier, identifierBase) => { if (typeof (options) === 'string') { + identifierBase = identifier identifier = options options = undefined } @@ -10,7 +11,7 @@ const inc = (version, release, options, identifier) => { return new SemVer( version instanceof SemVer ? version.version : version, options - ).inc(release, identifier).version + ).inc(release, identifier, identifierBase).version } catch (er) { return null } diff --git a/node_modules/@mapbox/node-pre-gyp/node_modules/semver/functions/parse.js b/node_modules/@mapbox/node-pre-gyp/node_modules/semver/functions/parse.js index a66663aa..459b3b17 100644 --- a/node_modules/@mapbox/node-pre-gyp/node_modules/semver/functions/parse.js +++ b/node_modules/@mapbox/node-pre-gyp/node_modules/semver/functions/parse.js @@ -1,32 +1,15 @@ -const { MAX_LENGTH } = require('../internal/constants') -const { re, t } = require('../internal/re') const SemVer = require('../classes/semver') - -const parseOptions = require('../internal/parse-options') -const parse = (version, options) => { - options = parseOptions(options) - +const parse = (version, options, throwErrors = false) => { if (version instanceof SemVer) { return version } - - if (typeof version !== 'string') { - return null - } - - if (version.length > MAX_LENGTH) { - return null - } - - const r = options.loose ? re[t.LOOSE] : re[t.FULL] - if (!r.test(version)) { - return null - } - try { return new SemVer(version, options) } catch (er) { - return null + if (!throwErrors) { + return null + } + throw er } } diff --git a/node_modules/@mapbox/node-pre-gyp/node_modules/semver/index.js b/node_modules/@mapbox/node-pre-gyp/node_modules/semver/index.js index 4a342c6a..86d42ac1 100644 --- a/node_modules/@mapbox/node-pre-gyp/node_modules/semver/index.js +++ b/node_modules/@mapbox/node-pre-gyp/node_modules/semver/index.js @@ -83,6 +83,7 @@ module.exports = { src: internalRe.src, tokens: internalRe.t, SEMVER_SPEC_VERSION: constants.SEMVER_SPEC_VERSION, + RELEASE_TYPES: constants.RELEASE_TYPES, compareIdentifiers: identifiers.compareIdentifiers, rcompareIdentifiers: identifiers.rcompareIdentifiers, } diff --git a/node_modules/@mapbox/node-pre-gyp/node_modules/semver/internal/constants.js b/node_modules/@mapbox/node-pre-gyp/node_modules/semver/internal/constants.js index 4f0de59b..94be1c57 100644 --- a/node_modules/@mapbox/node-pre-gyp/node_modules/semver/internal/constants.js +++ b/node_modules/@mapbox/node-pre-gyp/node_modules/semver/internal/constants.js @@ -9,9 +9,27 @@ const MAX_SAFE_INTEGER = Number.MAX_SAFE_INTEGER || // Max safe segment length for coercion. const MAX_SAFE_COMPONENT_LENGTH = 16 +// Max safe length for a build identifier. The max length minus 6 characters for +// the shortest version with a build 0.0.0+BUILD. +const MAX_SAFE_BUILD_LENGTH = MAX_LENGTH - 6 + +const RELEASE_TYPES = [ + 'major', + 'premajor', + 'minor', + 'preminor', + 'patch', + 'prepatch', + 'prerelease', +] + module.exports = { - SEMVER_SPEC_VERSION, MAX_LENGTH, - MAX_SAFE_INTEGER, MAX_SAFE_COMPONENT_LENGTH, + MAX_SAFE_BUILD_LENGTH, + MAX_SAFE_INTEGER, + RELEASE_TYPES, + SEMVER_SPEC_VERSION, + FLAG_INCLUDE_PRERELEASE: 0b001, + FLAG_LOOSE: 0b010, } diff --git a/node_modules/@mapbox/node-pre-gyp/node_modules/semver/internal/parse-options.js b/node_modules/@mapbox/node-pre-gyp/node_modules/semver/internal/parse-options.js index bbd9ec77..10d64ce0 100644 --- a/node_modules/@mapbox/node-pre-gyp/node_modules/semver/internal/parse-options.js +++ b/node_modules/@mapbox/node-pre-gyp/node_modules/semver/internal/parse-options.js @@ -1,11 +1,15 @@ -// parse out just the options we care about so we always get a consistent -// obj with keys in a consistent order. -const opts = ['includePrerelease', 'loose', 'rtl'] -const parseOptions = options => - !options ? {} - : typeof options !== 'object' ? { loose: true } - : opts.filter(k => options[k]).reduce((o, k) => { - o[k] = true - return o - }, {}) +// parse out just the options we care about +const looseOption = Object.freeze({ loose: true }) +const emptyOpts = Object.freeze({ }) +const parseOptions = options => { + if (!options) { + return emptyOpts + } + + if (typeof options !== 'object') { + return looseOption + } + + return options +} module.exports = parseOptions diff --git a/node_modules/@mapbox/node-pre-gyp/node_modules/semver/internal/re.js b/node_modules/@mapbox/node-pre-gyp/node_modules/semver/internal/re.js index ed88398a..fd8920e7 100644 --- a/node_modules/@mapbox/node-pre-gyp/node_modules/semver/internal/re.js +++ b/node_modules/@mapbox/node-pre-gyp/node_modules/semver/internal/re.js @@ -1,19 +1,49 @@ -const { MAX_SAFE_COMPONENT_LENGTH } = require('./constants') +const { + MAX_SAFE_COMPONENT_LENGTH, + MAX_SAFE_BUILD_LENGTH, + MAX_LENGTH, +} = require('./constants') const debug = require('./debug') exports = module.exports = {} // The actual regexps go on exports.re const re = exports.re = [] +const safeRe = exports.safeRe = [] const src = exports.src = [] const t = exports.t = {} let R = 0 +const LETTERDASHNUMBER = '[a-zA-Z0-9-]' + +// Replace some greedy regex tokens to prevent regex dos issues. These regex are +// used internally via the safeRe object since all inputs in this library get +// normalized first to trim and collapse all extra whitespace. The original +// regexes are exported for userland consumption and lower level usage. A +// future breaking change could export the safer regex only with a note that +// all input should have extra whitespace removed. +const safeRegexReplacements = [ + ['\\s', 1], + ['\\d', MAX_LENGTH], + [LETTERDASHNUMBER, MAX_SAFE_BUILD_LENGTH], +] + +const makeSafeRegex = (value) => { + for (const [token, max] of safeRegexReplacements) { + value = value + .split(`${token}*`).join(`${token}{0,${max}}`) + .split(`${token}+`).join(`${token}{1,${max}}`) + } + return value +} + const createToken = (name, value, isGlobal) => { + const safe = makeSafeRegex(value) const index = R++ debug(name, index, value) t[name] = index src[index] = value re[index] = new RegExp(value, isGlobal ? 'g' : undefined) + safeRe[index] = new RegExp(safe, isGlobal ? 'g' : undefined) } // The following Regular Expressions can be used for tokenizing, @@ -23,13 +53,13 @@ const createToken = (name, value, isGlobal) => { // A single `0`, or a non-zero digit followed by zero or more digits. createToken('NUMERICIDENTIFIER', '0|[1-9]\\d*') -createToken('NUMERICIDENTIFIERLOOSE', '[0-9]+') +createToken('NUMERICIDENTIFIERLOOSE', '\\d+') // ## Non-numeric Identifier // Zero or more digits, followed by a letter or hyphen, and then zero or // more letters, digits, or hyphens. -createToken('NONNUMERICIDENTIFIER', '\\d*[a-zA-Z-][a-zA-Z0-9-]*') +createToken('NONNUMERICIDENTIFIER', `\\d*[a-zA-Z-]${LETTERDASHNUMBER}*`) // ## Main Version // Three dot-separated numeric identifiers. @@ -64,7 +94,7 @@ createToken('PRERELEASELOOSE', `(?:-?(${src[t.PRERELEASEIDENTIFIERLOOSE] // ## Build Metadata Identifier // Any combination of digits, letters, or hyphens. -createToken('BUILDIDENTIFIER', '[0-9A-Za-z-]+') +createToken('BUILDIDENTIFIER', `${LETTERDASHNUMBER}+`) // ## Build Metadata // Plus sign, followed by one or more period-separated build metadata @@ -124,12 +154,17 @@ createToken('XRANGELOOSE', `^${src[t.GTLT]}\\s*${src[t.XRANGEPLAINLOOSE]}$`) // Coercion. // Extract anything that could conceivably be a part of a valid semver -createToken('COERCE', `${'(^|[^\\d])' + +createToken('COERCEPLAIN', `${'(^|[^\\d])' + '(\\d{1,'}${MAX_SAFE_COMPONENT_LENGTH}})` + `(?:\\.(\\d{1,${MAX_SAFE_COMPONENT_LENGTH}}))?` + - `(?:\\.(\\d{1,${MAX_SAFE_COMPONENT_LENGTH}}))?` + + `(?:\\.(\\d{1,${MAX_SAFE_COMPONENT_LENGTH}}))?`) +createToken('COERCE', `${src[t.COERCEPLAIN]}(?:$|[^\\d])`) +createToken('COERCEFULL', src[t.COERCEPLAIN] + + `(?:${src[t.PRERELEASE]})?` + + `(?:${src[t.BUILD]})?` + `(?:$|[^\\d])`) createToken('COERCERTL', src[t.COERCE], true) +createToken('COERCERTLFULL', src[t.COERCEFULL], true) // Tilde ranges. // Meaning is "reasonably at or greater than" diff --git a/node_modules/@mapbox/node-pre-gyp/node_modules/semver/package.json b/node_modules/@mapbox/node-pre-gyp/node_modules/semver/package.json index 72d3f66e..663d3701 100644 --- a/node_modules/@mapbox/node-pre-gyp/node_modules/semver/package.json +++ b/node_modules/@mapbox/node-pre-gyp/node_modules/semver/package.json @@ -1,26 +1,27 @@ { "name": "semver", - "version": "7.3.8", + "version": "7.6.3", "description": "The semantic version parser used by npm.", "main": "index.js", "scripts": { "test": "tap", "snap": "tap", - "lint": "eslint \"**/*.js\"", + "lint": "eslint \"**/*.{js,cjs,ts,mjs,jsx,tsx}\"", "postlint": "template-oss-check", "lintfix": "npm run lint -- --fix", "posttest": "npm run lint", "template-oss-apply": "template-oss-apply --force" }, "devDependencies": { - "@npmcli/eslint-config": "^3.0.1", - "@npmcli/template-oss": "4.4.4", + "@npmcli/eslint-config": "^4.0.0", + "@npmcli/template-oss": "4.22.0", + "benchmark": "^2.1.4", "tap": "^16.0.0" }, "license": "ISC", "repository": { "type": "git", - "url": "https://github.com/npm/node-semver.git" + "url": "git+https://github.com/npm/node-semver.git" }, "bin": { "semver": "bin/semver.js" @@ -37,7 +38,7 @@ "range.bnf" ], "tap": { - "check-coverage": true, + "timeout": 30, "coverage-map": "map.js", "nyc-arg": [ "--exclude", @@ -47,23 +48,11 @@ "engines": { "node": ">=10" }, - "dependencies": { - "lru-cache": "^6.0.0" - }, "author": "GitHub Inc.", "templateOSS": { "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", - "version": "4.4.4", + "version": "4.22.0", "engines": ">=10", - "content": "./scripts", - "ciVersions": [ - "10.0.0", - "10.x", - "12.x", - "14.x", - "16.x", - "18.x" - ], "distPaths": [ "classes/", "functions/", @@ -80,7 +69,9 @@ "/ranges/", "/index.js", "/preload.js", - "/range.bnf" - ] + "/range.bnf", + "/benchmarks" + ], + "publish": "true" } } diff --git a/node_modules/@mapbox/node-pre-gyp/node_modules/semver/ranges/intersects.js b/node_modules/@mapbox/node-pre-gyp/node_modules/semver/ranges/intersects.js index 3d1a6f31..e0e9b7ce 100644 --- a/node_modules/@mapbox/node-pre-gyp/node_modules/semver/ranges/intersects.js +++ b/node_modules/@mapbox/node-pre-gyp/node_modules/semver/ranges/intersects.js @@ -2,6 +2,6 @@ const Range = require('../classes/range') const intersects = (r1, r2, options) => { r1 = new Range(r1, options) r2 = new Range(r2, options) - return r1.intersects(r2) + return r1.intersects(r2, options) } module.exports = intersects diff --git a/node_modules/@mapbox/node-pre-gyp/node_modules/semver/ranges/subset.js b/node_modules/@mapbox/node-pre-gyp/node_modules/semver/ranges/subset.js index e0dea43c..1e5c2683 100644 --- a/node_modules/@mapbox/node-pre-gyp/node_modules/semver/ranges/subset.js +++ b/node_modules/@mapbox/node-pre-gyp/node_modules/semver/ranges/subset.js @@ -68,6 +68,9 @@ const subset = (sub, dom, options = {}) => { return true } +const minimumVersionWithPreRelease = [new Comparator('>=0.0.0-0')] +const minimumVersion = [new Comparator('>=0.0.0')] + const simpleSubset = (sub, dom, options) => { if (sub === dom) { return true @@ -77,9 +80,9 @@ const simpleSubset = (sub, dom, options) => { if (dom.length === 1 && dom[0].semver === ANY) { return true } else if (options.includePrerelease) { - sub = [new Comparator('>=0.0.0-0')] + sub = minimumVersionWithPreRelease } else { - sub = [new Comparator('>=0.0.0')] + sub = minimumVersion } } @@ -87,7 +90,7 @@ const simpleSubset = (sub, dom, options) => { if (options.includePrerelease) { return true } else { - dom = [new Comparator('>=0.0.0')] + dom = minimumVersion } } diff --git a/node_modules/@mapbox/node-pre-gyp/node_modules/yallist/LICENSE b/node_modules/@mapbox/node-pre-gyp/node_modules/yallist/LICENSE deleted file mode 100644 index 19129e31..00000000 --- a/node_modules/@mapbox/node-pre-gyp/node_modules/yallist/LICENSE +++ /dev/null @@ -1,15 +0,0 @@ -The ISC License - -Copyright (c) Isaac Z. Schlueter and Contributors - -Permission to use, copy, modify, and/or distribute this software for any -purpose with or without fee is hereby granted, provided that the above -copyright notice and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR -IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/node_modules/@mapbox/node-pre-gyp/node_modules/yallist/README.md b/node_modules/@mapbox/node-pre-gyp/node_modules/yallist/README.md deleted file mode 100644 index f5861018..00000000 --- a/node_modules/@mapbox/node-pre-gyp/node_modules/yallist/README.md +++ /dev/null @@ -1,204 +0,0 @@ -# yallist - -Yet Another Linked List - -There are many doubly-linked list implementations like it, but this -one is mine. - -For when an array would be too big, and a Map can't be iterated in -reverse order. - - -[![Build Status](https://travis-ci.org/isaacs/yallist.svg?branch=master)](https://travis-ci.org/isaacs/yallist) [![Coverage Status](https://coveralls.io/repos/isaacs/yallist/badge.svg?service=github)](https://coveralls.io/github/isaacs/yallist) - -## basic usage - -```javascript -var yallist = require('yallist') -var myList = yallist.create([1, 2, 3]) -myList.push('foo') -myList.unshift('bar') -// of course pop() and shift() are there, too -console.log(myList.toArray()) // ['bar', 1, 2, 3, 'foo'] -myList.forEach(function (k) { - // walk the list head to tail -}) -myList.forEachReverse(function (k, index, list) { - // walk the list tail to head -}) -var myDoubledList = myList.map(function (k) { - return k + k -}) -// now myDoubledList contains ['barbar', 2, 4, 6, 'foofoo'] -// mapReverse is also a thing -var myDoubledListReverse = myList.mapReverse(function (k) { - return k + k -}) // ['foofoo', 6, 4, 2, 'barbar'] - -var reduced = myList.reduce(function (set, entry) { - set += entry - return set -}, 'start') -console.log(reduced) // 'startfoo123bar' -``` - -## api - -The whole API is considered "public". - -Functions with the same name as an Array method work more or less the -same way. - -There's reverse versions of most things because that's the point. - -### Yallist - -Default export, the class that holds and manages a list. - -Call it with either a forEach-able (like an array) or a set of -arguments, to initialize the list. - -The Array-ish methods all act like you'd expect. No magic length, -though, so if you change that it won't automatically prune or add -empty spots. - -### Yallist.create(..) - -Alias for Yallist function. Some people like factories. - -#### yallist.head - -The first node in the list - -#### yallist.tail - -The last node in the list - -#### yallist.length - -The number of nodes in the list. (Change this at your peril. It is -not magic like Array length.) - -#### yallist.toArray() - -Convert the list to an array. - -#### yallist.forEach(fn, [thisp]) - -Call a function on each item in the list. - -#### yallist.forEachReverse(fn, [thisp]) - -Call a function on each item in the list, in reverse order. - -#### yallist.get(n) - -Get the data at position `n` in the list. If you use this a lot, -probably better off just using an Array. - -#### yallist.getReverse(n) - -Get the data at position `n`, counting from the tail. - -#### yallist.map(fn, thisp) - -Create a new Yallist with the result of calling the function on each -item. - -#### yallist.mapReverse(fn, thisp) - -Same as `map`, but in reverse. - -#### yallist.pop() - -Get the data from the list tail, and remove the tail from the list. - -#### yallist.push(item, ...) - -Insert one or more items to the tail of the list. - -#### yallist.reduce(fn, initialValue) - -Like Array.reduce. - -#### yallist.reduceReverse - -Like Array.reduce, but in reverse. - -#### yallist.reverse - -Reverse the list in place. - -#### yallist.shift() - -Get the data from the list head, and remove the head from the list. - -#### yallist.slice([from], [to]) - -Just like Array.slice, but returns a new Yallist. - -#### yallist.sliceReverse([from], [to]) - -Just like yallist.slice, but the result is returned in reverse. - -#### yallist.toArray() - -Create an array representation of the list. - -#### yallist.toArrayReverse() - -Create a reversed array representation of the list. - -#### yallist.unshift(item, ...) - -Insert one or more items to the head of the list. - -#### yallist.unshiftNode(node) - -Move a Node object to the front of the list. (That is, pull it out of -wherever it lives, and make it the new head.) - -If the node belongs to a different list, then that list will remove it -first. - -#### yallist.pushNode(node) - -Move a Node object to the end of the list. (That is, pull it out of -wherever it lives, and make it the new tail.) - -If the node belongs to a list already, then that list will remove it -first. - -#### yallist.removeNode(node) - -Remove a node from the list, preserving referential integrity of head -and tail and other nodes. - -Will throw an error if you try to have a list remove a node that -doesn't belong to it. - -### Yallist.Node - -The class that holds the data and is actually the list. - -Call with `var n = new Node(value, previousNode, nextNode)` - -Note that if you do direct operations on Nodes themselves, it's very -easy to get into weird states where the list is broken. Be careful :) - -#### node.next - -The next node in the list. - -#### node.prev - -The previous node in the list. - -#### node.value - -The data the node contains. - -#### node.list - -The list to which this node belongs. (Null if it does not belong to -any list.) diff --git a/node_modules/@mapbox/node-pre-gyp/node_modules/yallist/iterator.js b/node_modules/@mapbox/node-pre-gyp/node_modules/yallist/iterator.js deleted file mode 100644 index d41c97a1..00000000 --- a/node_modules/@mapbox/node-pre-gyp/node_modules/yallist/iterator.js +++ /dev/null @@ -1,8 +0,0 @@ -'use strict' -module.exports = function (Yallist) { - Yallist.prototype[Symbol.iterator] = function* () { - for (let walker = this.head; walker; walker = walker.next) { - yield walker.value - } - } -} diff --git a/node_modules/@mapbox/node-pre-gyp/node_modules/yallist/package.json b/node_modules/@mapbox/node-pre-gyp/node_modules/yallist/package.json deleted file mode 100644 index 8a083867..00000000 --- a/node_modules/@mapbox/node-pre-gyp/node_modules/yallist/package.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "name": "yallist", - "version": "4.0.0", - "description": "Yet Another Linked List", - "main": "yallist.js", - "directories": { - "test": "test" - }, - "files": [ - "yallist.js", - "iterator.js" - ], - "dependencies": {}, - "devDependencies": { - "tap": "^12.1.0" - }, - "scripts": { - "test": "tap test/*.js --100", - "preversion": "npm test", - "postversion": "npm publish", - "postpublish": "git push origin --all; git push origin --tags" - }, - "repository": { - "type": "git", - "url": "git+https://github.com/isaacs/yallist.git" - }, - "author": "Isaac Z. Schlueter (http://blog.izs.me/)", - "license": "ISC" -} diff --git a/node_modules/@mapbox/node-pre-gyp/node_modules/yallist/yallist.js b/node_modules/@mapbox/node-pre-gyp/node_modules/yallist/yallist.js deleted file mode 100644 index 4e83ab1c..00000000 --- a/node_modules/@mapbox/node-pre-gyp/node_modules/yallist/yallist.js +++ /dev/null @@ -1,426 +0,0 @@ -'use strict' -module.exports = Yallist - -Yallist.Node = Node -Yallist.create = Yallist - -function Yallist (list) { - var self = this - if (!(self instanceof Yallist)) { - self = new Yallist() - } - - self.tail = null - self.head = null - self.length = 0 - - if (list && typeof list.forEach === 'function') { - list.forEach(function (item) { - self.push(item) - }) - } else if (arguments.length > 0) { - for (var i = 0, l = arguments.length; i < l; i++) { - self.push(arguments[i]) - } - } - - return self -} - -Yallist.prototype.removeNode = function (node) { - if (node.list !== this) { - throw new Error('removing node which does not belong to this list') - } - - var next = node.next - var prev = node.prev - - if (next) { - next.prev = prev - } - - if (prev) { - prev.next = next - } - - if (node === this.head) { - this.head = next - } - if (node === this.tail) { - this.tail = prev - } - - node.list.length-- - node.next = null - node.prev = null - node.list = null - - return next -} - -Yallist.prototype.unshiftNode = function (node) { - if (node === this.head) { - return - } - - if (node.list) { - node.list.removeNode(node) - } - - var head = this.head - node.list = this - node.next = head - if (head) { - head.prev = node - } - - this.head = node - if (!this.tail) { - this.tail = node - } - this.length++ -} - -Yallist.prototype.pushNode = function (node) { - if (node === this.tail) { - return - } - - if (node.list) { - node.list.removeNode(node) - } - - var tail = this.tail - node.list = this - node.prev = tail - if (tail) { - tail.next = node - } - - this.tail = node - if (!this.head) { - this.head = node - } - this.length++ -} - -Yallist.prototype.push = function () { - for (var i = 0, l = arguments.length; i < l; i++) { - push(this, arguments[i]) - } - return this.length -} - -Yallist.prototype.unshift = function () { - for (var i = 0, l = arguments.length; i < l; i++) { - unshift(this, arguments[i]) - } - return this.length -} - -Yallist.prototype.pop = function () { - if (!this.tail) { - return undefined - } - - var res = this.tail.value - this.tail = this.tail.prev - if (this.tail) { - this.tail.next = null - } else { - this.head = null - } - this.length-- - return res -} - -Yallist.prototype.shift = function () { - if (!this.head) { - return undefined - } - - var res = this.head.value - this.head = this.head.next - if (this.head) { - this.head.prev = null - } else { - this.tail = null - } - this.length-- - return res -} - -Yallist.prototype.forEach = function (fn, thisp) { - thisp = thisp || this - for (var walker = this.head, i = 0; walker !== null; i++) { - fn.call(thisp, walker.value, i, this) - walker = walker.next - } -} - -Yallist.prototype.forEachReverse = function (fn, thisp) { - thisp = thisp || this - for (var walker = this.tail, i = this.length - 1; walker !== null; i--) { - fn.call(thisp, walker.value, i, this) - walker = walker.prev - } -} - -Yallist.prototype.get = function (n) { - for (var i = 0, walker = this.head; walker !== null && i < n; i++) { - // abort out of the list early if we hit a cycle - walker = walker.next - } - if (i === n && walker !== null) { - return walker.value - } -} - -Yallist.prototype.getReverse = function (n) { - for (var i = 0, walker = this.tail; walker !== null && i < n; i++) { - // abort out of the list early if we hit a cycle - walker = walker.prev - } - if (i === n && walker !== null) { - return walker.value - } -} - -Yallist.prototype.map = function (fn, thisp) { - thisp = thisp || this - var res = new Yallist() - for (var walker = this.head; walker !== null;) { - res.push(fn.call(thisp, walker.value, this)) - walker = walker.next - } - return res -} - -Yallist.prototype.mapReverse = function (fn, thisp) { - thisp = thisp || this - var res = new Yallist() - for (var walker = this.tail; walker !== null;) { - res.push(fn.call(thisp, walker.value, this)) - walker = walker.prev - } - return res -} - -Yallist.prototype.reduce = function (fn, initial) { - var acc - var walker = this.head - if (arguments.length > 1) { - acc = initial - } else if (this.head) { - walker = this.head.next - acc = this.head.value - } else { - throw new TypeError('Reduce of empty list with no initial value') - } - - for (var i = 0; walker !== null; i++) { - acc = fn(acc, walker.value, i) - walker = walker.next - } - - return acc -} - -Yallist.prototype.reduceReverse = function (fn, initial) { - var acc - var walker = this.tail - if (arguments.length > 1) { - acc = initial - } else if (this.tail) { - walker = this.tail.prev - acc = this.tail.value - } else { - throw new TypeError('Reduce of empty list with no initial value') - } - - for (var i = this.length - 1; walker !== null; i--) { - acc = fn(acc, walker.value, i) - walker = walker.prev - } - - return acc -} - -Yallist.prototype.toArray = function () { - var arr = new Array(this.length) - for (var i = 0, walker = this.head; walker !== null; i++) { - arr[i] = walker.value - walker = walker.next - } - return arr -} - -Yallist.prototype.toArrayReverse = function () { - var arr = new Array(this.length) - for (var i = 0, walker = this.tail; walker !== null; i++) { - arr[i] = walker.value - walker = walker.prev - } - return arr -} - -Yallist.prototype.slice = function (from, to) { - to = to || this.length - if (to < 0) { - to += this.length - } - from = from || 0 - if (from < 0) { - from += this.length - } - var ret = new Yallist() - if (to < from || to < 0) { - return ret - } - if (from < 0) { - from = 0 - } - if (to > this.length) { - to = this.length - } - for (var i = 0, walker = this.head; walker !== null && i < from; i++) { - walker = walker.next - } - for (; walker !== null && i < to; i++, walker = walker.next) { - ret.push(walker.value) - } - return ret -} - -Yallist.prototype.sliceReverse = function (from, to) { - to = to || this.length - if (to < 0) { - to += this.length - } - from = from || 0 - if (from < 0) { - from += this.length - } - var ret = new Yallist() - if (to < from || to < 0) { - return ret - } - if (from < 0) { - from = 0 - } - if (to > this.length) { - to = this.length - } - for (var i = this.length, walker = this.tail; walker !== null && i > to; i--) { - walker = walker.prev - } - for (; walker !== null && i > from; i--, walker = walker.prev) { - ret.push(walker.value) - } - return ret -} - -Yallist.prototype.splice = function (start, deleteCount, ...nodes) { - if (start > this.length) { - start = this.length - 1 - } - if (start < 0) { - start = this.length + start; - } - - for (var i = 0, walker = this.head; walker !== null && i < start; i++) { - walker = walker.next - } - - var ret = [] - for (var i = 0; walker && i < deleteCount; i++) { - ret.push(walker.value) - walker = this.removeNode(walker) - } - if (walker === null) { - walker = this.tail - } - - if (walker !== this.head && walker !== this.tail) { - walker = walker.prev - } - - for (var i = 0; i < nodes.length; i++) { - walker = insert(this, walker, nodes[i]) - } - return ret; -} - -Yallist.prototype.reverse = function () { - var head = this.head - var tail = this.tail - for (var walker = head; walker !== null; walker = walker.prev) { - var p = walker.prev - walker.prev = walker.next - walker.next = p - } - this.head = tail - this.tail = head - return this -} - -function insert (self, node, value) { - var inserted = node === self.head ? - new Node(value, null, node, self) : - new Node(value, node, node.next, self) - - if (inserted.next === null) { - self.tail = inserted - } - if (inserted.prev === null) { - self.head = inserted - } - - self.length++ - - return inserted -} - -function push (self, item) { - self.tail = new Node(item, self.tail, null, self) - if (!self.head) { - self.head = self.tail - } - self.length++ -} - -function unshift (self, item) { - self.head = new Node(item, null, self.head, self) - if (!self.tail) { - self.tail = self.head - } - self.length++ -} - -function Node (value, prev, next, list) { - if (!(this instanceof Node)) { - return new Node(value, prev, next, list) - } - - this.list = list - this.value = value - - if (prev) { - prev.next = this - this.prev = prev - } else { - this.prev = null - } - - if (next) { - next.prev = this - this.next = next - } else { - this.next = null - } -} - -try { - // add if support for Symbol.iterator is present - require('./iterator.js')(Yallist) -} catch (er) {} diff --git a/node_modules/@mapbox/node-pre-gyp/package.json b/node_modules/@mapbox/node-pre-gyp/package.json index 34b0d3ce..5e1d6fd5 100644 --- a/node_modules/@mapbox/node-pre-gyp/package.json +++ b/node_modules/@mapbox/node-pre-gyp/package.json @@ -1,7 +1,7 @@ { "name": "@mapbox/node-pre-gyp", "description": "Node.js native addon binary install tool", - "version": "1.0.10", + "version": "1.0.11", "keywords": [ "native", "addon", diff --git a/node_modules/bcrypt/.github/workflows/ci.yaml b/node_modules/bcrypt/.github/workflows/ci.yaml index afc6a86a..dc3f12f4 100644 --- a/node_modules/bcrypt/.github/workflows/ci.yaml +++ b/node_modules/bcrypt/.github/workflows/ci.yaml @@ -10,34 +10,50 @@ on: jobs: build: - runs-on: ubuntu-22.04 strategy: matrix: - node-version: [14.x, 16.x, 18.x] + os: [ubuntu-20.04, macos-11.0, windows-2019] + nodeVersion: [14, 16, 18, 20] + runs-on: ${{ matrix.os }} steps: - - uses: actions/checkout@v2 - - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v1 + - uses: actions/checkout@v3 + - name: Use Node.js ${{ matrix.nodeVersion }} + uses: actions/setup-node@v3 with: - node-version: ${{ matrix.node-version }} - - name: Install dependencies - run: | - sudo apt-get install -y python3 make g++ + node-version: ${{ matrix.nodeVersion }} - name: Test run: npm test + - name: Package + if: startsWith(github.ref, 'refs/tags/') || startsWith(github.ref, 'refs/heads/master') + run: npx node-pre-gyp package + - name: Upload + uses: actions/upload-artifact@v3 + if: matrix.nodeVersion == '14' && (startsWith(github.ref, 'refs/tags/') || startsWith(github.ref, 'refs/heads/master')) + with: + name: bcrypt-lib-${{ matrix.os }}-${{ matrix.nodeVersion }} + path: build/stage/**/bcrypt_lib*.tar.gz build-alpine: - runs-on: ubuntu-22.04 + runs-on: ubuntu-latest strategy: matrix: - node-version: [14, 16, 18] + nodeVersion: [14, 16, 18, 20] container: - image: node:${{ matrix.node-version }}-alpine + image: node:${{ matrix.nodeVersion }}-alpine steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Install dependencies run: | apk add make g++ python3 - name: Test run: | npm test --unsafe-perm + - name: Package + if: startsWith(github.ref, 'refs/tags/') || startsWith(github.ref, 'refs/heads/master') + run: npx node-pre-gyp package --unsafe-perm + - name: Upload + if: matrix.nodeVersion == '14' && (startsWith(github.ref, 'refs/tags/') || startsWith(github.ref, 'refs/heads/master')) + uses: actions/upload-artifact@v3 + with: + name: bcrypt-lib-alpine-${{ matrix.nodeVersion }} + path: build/stage/**/bcrypt_lib*.tar.gz diff --git a/node_modules/bcrypt/CHANGELOG.md b/node_modules/bcrypt/CHANGELOG.md index 409a2cb0..f2fcb471 100644 --- a/node_modules/bcrypt/CHANGELOG.md +++ b/node_modules/bcrypt/CHANGELOG.md @@ -1,3 +1,6 @@ +# 5.1.0 (2022-10-06) + * Update `node-pre-gyp` to 1.0.11 + # 5.1.0 (2022-10-06) * Update `node-pre-gyp` to 1.0.10 * Replace `nodeunit` with `jest` as the testing library diff --git a/node_modules/bcrypt/bcrypt-5.1.0.tgz b/node_modules/bcrypt/bcrypt-5.1.0.tgz deleted file mode 100644 index 399a242a7a458e81131e1f88c7dfb4628b6a1bdf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 32939 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 mDgp{iVRzrSLFA0R!G(CA$? { + const start = Date.now(); + + // genSalt + const salt = await bcrypt.genSalt(10) + console.log('salt: ' + salt); + console.log('salt cb end: ' + (Date.now() - start) + 'ms'); + + // hash + const crypted = await bcrypt.hash('test', salt) console.log('crypted: ' + crypted); console.log('crypted cb end: ' + (Date.now() - start) + 'ms'); console.log('rounds used from hash:', bcrypt.getRounds(crypted)); - bcrypt.compare('test', crypted, function(err, res) { - console.log('compared true: ' + res); - console.log('compared true cb end: ' + (Date.now() - start) + 'ms'); - }); - bcrypt.compare('bacon', crypted, function(err, res) { - console.log('compared false: ' + res); - console.log('compared false cb end: ' + (Date.now() - start) + 'ms'); - }); - }); -}) -console.log('end: ' + (Date.now() - start) + 'ms'); + + // compare + const res = await bcrypt.compare('test', crypted) + console.log('compared true: ' + res); + console.log('compared true cb end: ' + (Date.now() - start) + 'ms'); + + // compare + const res = await bcrypt.compare('bacon', crypted) + console.log('compared false: ' + res); + console.log('compared false cb end: ' + (Date.now() - start) + 'ms'); + + console.log('end: ' + (Date.now() - start) + 'ms'); +})(); diff --git a/node_modules/bcrypt/lib/binding/napi-v3/bcrypt_lib.node b/node_modules/bcrypt/lib/binding/napi-v3/bcrypt_lib.node index 11f5cc23764f4a59ab25639243f796e47c528450..ba87d282512b984efb464d9a7403b11747317040 100755 GIT binary patch literal 190464 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

Bo%tW({voZD**0xr`r=# zgT?^z73>6`GjH3SOd@d!o!fGevco((d>h(^Qcl*4b?u3|fkN@GilqtWTRmyw&CHj< zVv1_og#?7J7s6gJ#3_CZ1&Kid@k@VYS1cGr@d8ND8EM6hoD*vp4-`g948?LksDjM~ zPKQ5|KW=aP+-C3Tb6fe>&c9XsTg|_F%{vu6<>tiVR5Ne2-hctM))oMWAY|~mGxnAA z)Pe{Ov-M4T#yiyJ!$#VA8w-3&CqQEx_u^ay?M& zvn8H1zoYWPc#7VpBC$LJKHs7N0Uz_5Jb;X4FcE#JK$A=Y&?J4q!q!^D`&oKfG55a) zrAJQ{P`W+^N^7N(zKryqVoX><9=w%>%GhX8wr> z`rb!J>AU$$UQ?22fuxpA0xJNM*tHT9#r*a((b!hT0?{!yO-Lre^vZ$OgRN?38rfs^ z?L@zW_msVxc>`J3|mQ4egS8+Q}EVq-0o%^w-0zsc^8 z&QR;3R^Do;Nnzt$y3n5_OquA>SyKKsk*0WZ~eve_V=?u;GDC_+zFr{*N z%41@@4|Y)0p77zUB`$xMIGUl+<~@4_DBO}+Q3F;v zWqboWh~=P+J% z%ZIeWXW&1&U#`c%LFK30GJ71nDrOX-Q?2g>YWvN82&JUELUbmr2^mVwC)!=F^B^gA z9Z!dAZiCYp&O@N-kU5jO(2zT)M6>rBwRWY7@(fA~FSjG2JH?zZC{1s=)}C#iEGdqS zYRGJ&qCB>@5vsR{FA($TX5r|UR*st(C0ju<2 zic@&Bw3(p@)FzCL_L=jP zNmObRZ=1pSPe@ZUuvc1|i8jo24>G!`s1Pvtj- zhs;qt%PKE}UvukCL|k%QnIajXA>S-ZCdGf;BC+7yhA717`NNDykKC&$lSEPYLFDrgO*{hGq|K#Xw4Q8faH8!zft1|gX}#`B65F@Hce4N-h~kq^7ECD=kFnXZhmlZRK} z>~4FnZ417=J+ho`F%`WndPx>u5mArCxLbUpziEr^nC{GguX)f3F@Av@Yjbs@2&@q* zWaz7CIbdWLC5C&`Z;lP=vg-u&&95Vx6`+rA0q9EvzUMPXUIp!n;$_|qjV0>~ zp(?uvaRhpe6A&V1-pzhmuj##QoEK~+Ie~Grh++gD8OSu8ghbK6`$h_hEh%!eG!kT_ zZVMB#|I+;e7b43ZZ2d(45U$6S?dFpV%Xcm|+STW3ciqj4`J*0Y!r19Id=-JFxds04 zrtE;@b+dIK8PX8F;KY2~&TqS1ZzAqlcC!#mv&=bU@*A@u(EI&O*`>Op->g#QfOe6_ zG&N+CdA00eM~}JdZ6PE=BRt9N(hAkBd@AAaJZ?{R)!>G_>YK7A0BxhEgP9xTJm<{+6VbWESkV3~q zUqcagB#E=pU%=8}=hKs$^>EkmHD6l(2!`P5)RD;-VM=P&F%*9bn`(%dUzW=H?g|*s zrnHZON{%|DW8wk3$3*fQ$qK*bz&67ZnR2{`zz~FR3Z4wm6BG2XBQ%AW0a%2KDN97M zlyKw?P2duR&!K_*k&#qs9AE3f&`E-5*wtIjUBXy&*VL@YRU19gCF~6Pm~5!6V5w6pa%dw_U{3{M ziG5ycX*2MNaXgf!^%39lseHhhM;y!r@-u*;jO9`=feohkD*%-k@-$Vke} ze5D+K6~x)2y570u&BO)V6yw2df-|lXDOrOtCcxLk7+gpURZ?q--mN!c1ie&Lh-opJ?h9-EU zb-CnX1|Q|PHP5V5lW+o)qe>@>pBgB4DpzOG-|x8S@13oxZ9Tj>+h6le{HqGXZRBfc z@K@$Dj}4M6{wlSgpH$CHQX^jqF$DMDxk?Q+k>7CVqw0xO5lks)a+ZM3+#$PxMbG#N zp=c|i&*}z?Tpk#MQ^ug;L{q?vt z=|z4_4;z9ysH-4d_=G_fb*PH0{uolvAEX|@2w_OhkF9!sBJ~_*e;ifMcA11!=gw92 z4Dbj-*+&bPQxY;VTD(YVg_Mz6=SX$GQQK_~t47bbbnbTQN)S!#fJU7Pol~*eZA0;f zizpvdTq70JLeAMdaIVlqnKS_bWHYBpSFyxabwizWC5y+Us$Z6=o@GIeo@&F|pXtAY z_A`4-_OwMb%AR)19XUp)IqDOjWv5xgkN5&$FT>e0%ClBx&iwFWQo|~Oj@0?@)F=0W zQD0(cN!jBA?H|?3-9z(=f8Egh!h9i-g@)lskxtK+65u#DEw!j;tLLe1Uo^DB^mGjB z|CLwBTpI_Vrrv)Lsj!u0(D)4E$rPVIMvy_jrrlWp6*$;`uijX7dm~KMyb)-c_Qnw#`OY^oJT@htZ}a%*ZP#(mdpv($#JO>` zkx$vl+46l@M9R6d`94g_rRyD3r4%FUAQ)mH9}srFM%tJlXSXRF$?Aq)rthy+u{@C!B%2hQg|?D z3M5gM)^XQu2ymrSX*>T1efB3c2{NcFEU%tg(zDpeF(;0qF zhE#RhofoB6YhXR8GoOE#y7+Uon?GNfyZO_VdHkE<;?GrX{(N~Z=^f2f#P7Esuzr6S zvwnZpC%>Prj5J%n_dH;>wA2%6?o3+hiL|+ywA9lrf&6Bv zERZKZyggvO$q#Qa>rMUKZ13BAWTkC$|B{XKRx<;iov*i;ueW5r-jexx>))BLw^H-< zR%*W9O3l|>|MU5J^qBLt;;qllm!!F@8Oh9-q#Zq9k~U<%R=hQMzT|CSzT|E2eBs`! zrcAKI0K5q(a?&pbvKM@!AiD#c#D2+={c>~Gelj!zG1?t>@z;WE4ahDU4B3)l@i&!! zui9zaEteMYaJ7p+UlA5NkAE|Y_;VG6gQ&=AQaoi41J0JxbPI^yYP`F&eX{Lc=Z?g!)DRJPA!O# z5RdTJ_G?9a%O0tXbRyqvDBqZN4ZlS@%bqxX$ok;Y_(*vLM;B`%Xd`U34N z|6KV%?5My2SV^V>yS=vG`4WEif$qtwaI<_po@Rr^{VoKR4#-c8|wy z!IrqT5{s0Hqx9-^PLORVPj5M5<6&{0Uh@ZeSdt9|jof3qS#crgNj!36!7;iKmF#9; zHEEF_%QH7O=#f835dsDDknR>9d8lEHA~n#_V6^ERVo#ItM+_JjdW408A&NJkJ{o1p zUD(|=!qM8ypPfO6&&87P5>M29B-}rC@uV(Kg&h%3w`aWMfZ7$MokUkh_~Q~!?4OiM zucu0E7Ok~aFsy-g)gHf;Jd}s>JRKGO zB-Lhl)Lm}0p698FYi$ywGvS!<&3Wn=3y0nKjM~`<_ZmHR+eY=zJb2aaIjRV^EV#9knU&{(_ zaSlJM=ERZszCVeyz~OE^7%cWwRRoL7-(QgF_knRh!NG24=mb>$&<-^MJB~o43itdw z=`t*h&DQLT>Pd3pio{=g@CyEB1#^8h`xnnhox;*ne=aXaAg3Bg7P%~+y*$a`nvWL2xfa|lO$e39vgmD$N)kLFWg%I8D5 zroC&Av9Dm<_qjXXHvALAhjX;MJLwUDtpP9*z=z{FwA?`w55cR|+XwP?7)zwbdBB?D z8SuMJw=XL(Iy=qmHRxdLN_1mEf9f?j0{7Qj^YlZngtxdOQ_GaUSM(*ybk~V7kuCn$ zR6Rmz>*2Z*=b(y$xw`hug8sxK+T;BFoirz92C}(Z*_d@DlJ9A9bZC$9w>2CernSmZ zrh0s(ddSjRr|}TKfIl*C;&U$yW#tyZBA^i2bZSDOvdgSJXO2HznCh;+i@IfvQBWc8_E9*3K*Vuz&!po4s!>&$sH&<6Mm&vJadFirOB+-DYh(#%{@*(Pvvv03aP_~k&UJ@BXPvKOdDS}q0(k#_>->LtKVLiM ze`%esIrKT}JQm@IT4%2B_+MCOqh%I=Bl`MqXQP)mS{%T+Yi+<#LW!)5=0?8jyG#`L zNZARC+X!AD$gy70wq<3GXoX7A2YEWSpkc3QehvAW+uht*;pvP!+MWKS?v{ka4o^Ad zk}*%DQAZo@w&aiw0QO&ocnh!+X$$$gj91j&DgZHPJ-yNJL%||>H zYqvq)c@Dka`L?5DL#!_=T2Pd=#e4QHPxA&2>v1Q3;Vbt@M|}|w9rZ{@15v;9&Tq5`33pT{C4|2*xRWr=V&6t5jTsef zyJd=Y2djwG>*?6t{JQ4pd^?*C(cg{@%^y`SrZ;<<57=X`=QMA~&Dx2zguA^+r#JGH zc+zY2#!GK7sBj}H7`$F6Dn2t||9ZW|7yg**MU1Eac)f&U_|Mj>fw{OmwO+bfFcA#- z552Dc^Hrmj&t0|qk6yK*Yj#veKYz`np95>=|NpyYS-Pn z8=j7Apk+gQ7TMlUN!esd-73_R9J3Y|++^_-${=$Wf}lzWhFnV)YJT@@(coFSC;a3HIUHG} z0>x4CYfiZum$0%}2XJMpQ&0AAlk0we^fI`X+2cI~*Hh%UXr$1r@?)C$?_(K~3sZuJ zWR+eK92Q<>B^WZ*Oy~;A)Zxg7hA;Ovt^W$W6Mt{iafHhYfT>kmn+AdtJ3pdh4|<_;n!Ef zhGk#TURPS{)WTn(sL>-8BBr+}YH_Ytr0EZ>hv0R*1!u^gvGV6QMPPFeBR$+|?v+UNnGn`?mrt+FnSr2w$(fxQDFjI7KF1 zS7>b~%4nvRIpZU&hwONc^J!Hk-=0T6#RK`?SMHbPqi97}3dnDOd z=9CwA)h%V%uwy862evid4pyO~N9MYwYdIc_JF!B9v2bdSXU{mp)(n?&wQd*!C$ju{ zwFfgXch%QQf;q`LS7IDco;Z~!Jt^QFw(=n*1~9Fcq*{IUd1l$Cvh46Z!tVS}YG%_7 ztvL-)3?mIwZ4aT!NQMVoa;D6K9@~Vz<$T^(&IXU z*M63fvDh57DTLQCuO_e2mAD5P3s>=Vc&ckJ37v4zP9UkTv3gyeQb8P5@g`nsr-eM~ z%XI4t@a4&{O+(sZ`?2o^*rpHhUx1t*E%0#bL|dq<)~~gSNl$G+YrS87FSq>V5t4|X{Urc=hbgfTg#?PunH=wV#7v1iX zX1H`_!=hYDiw0L|Vyje~Im@I%Ils=#MA1>Vqcx&R-mnKWr6RQKXR$zzo~NWT_v1_5 zkInKt=Bd4Y(%ahLZ0ijyM80Tmj$nJU)U8qv-axXDYakL zT7{*pZPMDl%P*p(BvTX@$T!auYy)C@!Mq<-p9s}{^|qU9zZSfv_8Y;*+FOF-YZnAd zY8M3yYeT`Q?hCs^vnqEdo;NRGNfQ2UPel=RFh-e%#Cn1Y3p1bNY26&m)z-&zVTVD~ zV68<&65txM04tmr750}E(T94x6%#pT86Du5%msi}g72D_RpHdMP>?8vWAh@uzRKP0 zzSotMKq@Ymr(yCmtjpIoAyMLK-KHMP31Zl}%T$f?#U;L|U=>eC%zbv(npZt-Wa$bl+7`Ja+kNbufogR<@he_3W4j7xZ9T(zeYsUEMw95@&o0I z^n;xRp*id{Om=1&Q(XZI5h#0yYIjixgt@fD7R*j|D$x`MAPI;&JJ$;|*l}dcV5crS zSU};BfW3@*B;2Ia=h%i%%<|vL2G^s@uoF|!RNyWDGn=Pqb7= zHhV$EPc$zJ*n&5UVB)rU0i(%{xY6p{%r|}7;{~NSzxIW1=(9CMuP@E=tff8N2?dhAU37>&YB2;~-AP~J< zxLd5L5~Ts-ZW|T(<-ViuNK{n?a)|@LY*`9mrT-;4UU`o7dDbxL>GiNf__1J!46U zzW#I?mVfG?afX}94t3R4FOnd!G}>G{QleEuUn~%@A<>y5m+3-th_|RQM40XYy z$xx;9nTxR@`Y3LuY=;K*7evSPP5rF5-Y-h8mBwWgy)r2*x8RXl!6Tyuk60@+e#pw4 zih3wC95XV_4(UJ8fRW9&a;D{Y?9~aMC!Ci| zT&$N1`48Nq1MJqd$#l5O{K8+vkan0Z2ONJFaNrHIPH1~gf(Y}6xPW_jGLdDkO!X{d zh>AJ|R?G6HPsgJY1N`XkO81L|zvZ1G&LqgT;m@YXwl=|Bgxy%c558LxQHLX>*V}%* zm}wr6-=$dQd)sel=3hI=GMK{^H;E!|^%;x%?6%M-tte;3b9MA~5H$le|u0B4A?IR|61a&_c+|*zklE@K$3~a71 zZIC`pm-7RwD5M8ciQ5zYTUIDvzUZR1$f0%Jx`@&nx#3|wLX0(na7Z62==P&}q-{Sd zD{e(b+fo^E#J7exTWiT3qm>&lPQQUc-|%M??`?f#B_O_XE?zy1^2d#Y{hD{i{xhfxwAqA zQm`@nfPnF*-l`j#gCl|6<(9SnmvFo#h#AT4!6IXJtCc!hrIw0$dQ`yz#Kh*?1XeZ) ztSFmWanrKmPp0k4Ev8_wU3o>o7>hdDr#%)|D&@lsxRZ@C^XXekr953|@Xu8#;~fgK zmR2cGh1}v;0dvFo{!xI$QYo+Dk&|s=sh=fA+Hw%FANjg{3H%7h`c_J@oDsu7g8!{?j`$l&8ISZkk6??oJnCliIMxcw0?#N+UE8~#qk2ALP`{M!`S?`7hA5v=aHD@d=kxT>(g8~c zO*e)gPJEjL9Q-T|v|DMQ%Ln?s0BAw;o6$gz6I_7?+VwxsK-Z@<(DnakG|*tSOdtdi zW@N6FJBI$*r8ga}eAze9;+kaf6>oA}gL&Om%j6=B$TDYFU6Ea+!^@yx_gVttrzWx=m4J9Z zAeAgWi$ZdoRjJth8Lx`W+@$RIiKK%x7`brO)kPuhUw``zs_D@qbDScDP8Pq;yR>vQ z2YWUK2t!Zqfqu`tk_%Kg7K^N7aldseey|~ZEcS6o;CE;o;FeX`+#Iv;4(r-xJk+ea zlFc3Wr7m*jE}NZXH=ia!j+_N@I?y5ef36z{H{^{#NZ~VzAI1JAL__OV>g3020 zNSB>*zTiB$lqn!$HZr7db(TOOB+eDPTqsd06;f4VU0o+djW(zBJjE z(Y6Mxk;&t0#?>##J<}Ad++y@6i_4`7@j6Ntm+%OH7hwrh5dJtB%tZ`R(k3UFb=NfK z!tb$-l&B3dTfjqEI%30hbJX3(6hyRg0 zxXdZ^U%*#@*B48jY(s(f%D0XIypvU8sRVs%mMOq}UG;Hjj1x<;AIDuo%#`Qjwg5E5cs?0zgjy&Mnvl-X&x3 zAj>%)g7>Z$Fhrj~{n|i77@H-&EhqZilrNaf zh~-6QUdo`@8^}nlv(h54ln8Yh6awR|61;M(@7JjBP-5b+2Mnr0S?T)9QWuw>)u%Y1 z+;yxq{vXzLP3uq0w#7VA-EKYtT1ggv@Tv^CMNz#fLPrT7=!RC3nW3r^%~wWdsv4KBDltRqc~iW$*rqP? zXR>&JL>c^yu>IO&x!m=n!gOhmIrQX49t&*72Kvk;YN0;p!YUiC7{IJ6h57|XMb*VE zbb6%FjsQ31^9=?!nSBNCrviqqJ*T{?y^D|l;J&)g0tY368RVs%_6dQO|1B7OwQh`g z2nn#UHT>GedgYj(?*`2GY~|}~e6`|8z`@0*GgRT3ir^3#+G&P7Brs7pKlMQgs|p9Tk^eSAS;Co@DX&r~?E?;O&ia zd3<7@_T$EiDU&JH*TPyK2xO2zBHBd%RocYec_F&s37gz(_xm9NNOgPJwnI>>@EFLU4tvUw8`9g?|N@MR46 zb3(Wx5Nsgo{v@%DcY7!Y&0%7LZrp@n=OSl#X*SxCO|*giLxmo_M>b6Y6F|R{gd(Om z^nOcK)Mkqr%Zh^EYN^7MITpOBrRr|^y|$%_{IOs|OVvH{dr?c(x8?UsEmhxdp&j866dd{9$Vr|>)Yg~Y<-9PoW8zQeok87B0tBize9cs)`#UM zXZ`K`5NwAvsoYaB{j~dxbwZS5;*c!<7>!C~SyAF787dhT?QQhm(b>f%)9Uk|`HXtb z8P8%XrTKm(vQY~Uj}7WJ^3Aey6$tK7cNncUhMPB$FbG_fECYnFuX&Pdr|h1#U(*8x z(|6`1cL++h8%{PO(YA8l;?g?ZDBds0H9Lc2jUENl8}vOr^ssE-Qr{QtKS<%vWO220 zF#?F+T>4lC<1P`nn{Ul7tXQvXAJ> zSxWQZvAUuzev}-^JRix=>gT+i1|`Z<(;^ugxx}^)>;Q$%eT~LGc+AigArtO@iJk#W zlh!p{jeAVBGgPTJ>9siFwp2Izz+|Oshl7^pReMT8qr>ZD1xG9{3a=AEp-qtiPw~*@ zD`R{<9EyD=zb=0F^NZxt*RS+b5#RF>A2$&-JRgWkmYKZ}D?7~@bZK>Xh0BJC0*GfW zV`!Yc5!wQZNw!$Vr_4N)1SEGOlf^&YC#%+DuxWqDBbjUXCTQp;#vSU9XD+iGitz)6Mcwt-jW zXyxWPdwe?0(r=)}6K%|jyLmNo?vgCe9ZQ6ix%ymO*XJrH$6j^K-(i3FOq;(O*_iZc zH+H3wllam{VMcx*_+(boOgShsfXW=@5~1^#5N$P;oqa@*x>(4M}4WVqmfuCV#2 zqrUS|tcy>fme9kPWV@7Mc3$W~sU)wfE@?|p%?|gu2Rm{_6aPHDsC5OiYx5*PWOqky z;ypJh;izcB+1W)@9?GNzwCB5@CM}ziI4<~|tXs5rXbMYyD#}+j!=BXUI>ew(p zLHEibIplm*$D?>-iy%)?)!bz6H3+JpwO+=orot$kVBSyR=$sQGCFWm01iU_upT}48 z50j}fI%e`#J2v3iq!8_d$DC8h~C_7sx60)1^>{f)h z&@Yh{x@bqYn|?*Zt{?!CtSZriMek+44^XGPWlPLabmj@siC1o+L#4dMZ)9etMYAEX z_o(V6phT*6^AJeS6Fy=OonZLftaxP1ub~_wIX~iW<(9ydO!qv7Ze& z8h*CQ?BNh0S-zT2@@yPItZI;5RB;>h>IYEmAz07qe|p z72Ib@b%H^=Wi!hvTbHj4kSXxG)sqe*K~=F(r<>C}%(LebDJLgCCQ)0=bE!s-Y2^7^ z>fI_>hCBGciJsJ%iHr;wJ2(&TaSk(dz2-dmWLKx$uKI>4crUqQbF-UrnV zp%*zBp%)J)H0i_BNY3==N~kWd9#}#emiu=H&!}~FD0zF~v@I-Qj`=G=0z$D5{&u$Y z%^32nN;G)t1mSG&?*Vci;`?e|-j|oB)r(PhP+n$8Nu%&}o~gVl?&1Bp_~YyxIlqMd zKL-6W|Ev`Kaw78uMKj#|4Jk*#gp?J783X|m>q6lLC4^xz-jhp75lTCOf;a~fW3LGq zIj1~AFSu;jU)k@k?B!Nmp=9>#fHK#k^$foMQ|-=QlbbIDhvj2{Tj-1g;h}|6UN{Hp z1;6^>Km6kKQ)v-E8QT0}jseB_`Bk#Y0S@CV z{8%Eix66oKcjOloX6c3xCi>o0kia zMGJo+&pOZPvWh;M3aq6PQaU_i%yBXXw#9U${_^{=Xv_G$(l4FgYH9)Nw+8!hRn}6s zRc?vj8Ub?C^%N%1_%J{FwN7rfMA^u|dr9J;i3q6GYz-EeUlP$tWK4|obXCw)``#io zTDbdfoCwi+;irU_d+Rh(QL6n{OzlLKcH*g-$&h#4wNBuI>Aua(5xe%aX#-!Q#bK+~ z<H6b&bG z<&)b-o3AjkC!`%t%&{yG_z|eS28iAgDDSN6$aZ?#?S5t4`=*YL6$}T9zmJj+O3AU5 zOl*2CzT*swu%<2RzXAV7JTrx@yzx+{bT&8!Gl2`U^Fy;a8E`HOUJCM`rduCFZ}^{R zPW|U!pFCpy7tPK;BdOVJllu9yBnG>r*HFRZaGFm1Je`ZR1{}(T!Wq};Z`&B$!7kBH zW>Mt^<>#K0k(Q98J#L>zKaQJMlZCBYxHC(vl_+ly{gqF+&6js>lz4!Jzx}H)h`YQT z;5GTd@??w{ui^d)3lBs+?}qzFE*Z8~EaEn{bb5jQwK8|%!y`P}C9#bj!`qoHZCdk< zXd^sEtz{^WI3!p89yTo-UcA)U%51NuG=Z7EEIFcu=krm3gK$Ns%=ViaYC~AqvtpeddyeBRdo1w(uESM^>qK>Z4UP>sRg_&>P++Y zCW_7VQx%jV7};u$0Jaz&6&M?whvS-h%$N_$~WL_+Xu0Na3pxj=J)=wW%GwYJlXelw#D$=X12ne zE~F@-H@ReXWTK$C+Ga&}7Q&9?f5ac8GLVtBs!bkV)0E;&FNfaVcXYqF$Tt69bSyL{ z0OhDUrCmuhgTDQ#evQUg+dfYVatrp}m|8+4EYhjBRHvMD3JH(Zq4yIfpn@0)_0RZ8 zR}?5&-)Hb}0UM2+@BT*Sb2rndrj(UMtsJulVLh{F$fajQg>L;RTbsCQ)%jZMcX^bJ zf;1xZ_jo&R#92@)z$isRCtFs|3XE74H1r$L+iQstJZ(d=0PrgQ{VV0fP@e!yS8 zQ{VNGzh;lt=A$BZEo%P_{&GOHua6rbxR2BwK$12_R$^0UC^UE}{450@LvK(yRy6ZG z)p@}@60;a=hzRq$;)(QHbPX94oun^Xs|+HepK3I!RA8dLd3 zR**66PmL*2{Jux6VJNePbi7DL^EWk`5i%OBRopPsBYHP}7H_gBR{w)Vs_&nfP1p?( zPI@2a%)u8_#Jkmm^0MU9Z8^W?{3U+ne0C#Ruk_YRmx<<-TV7{t(aWZy=8#$=QG+=um6@9;sa7`7r5ef3L=N zY}qNWoKI^fNCDgwoJ#QEH%4?=p&kR#W%h}7&r?apfIVKHXD#w7DC~E9tJ(|a&bEkj3 z>WNK5dHpPRevMa+Z;yE@UFUuOE zJjQb%qU}UcGylqx(FrIDWYW`;9V4TY*JDj6X1h2cCH~>B*%3Sr*R{|vck|{86OQPO zc6a+(3C9r+!VPPJ=*1Wnb#%M&>N7HV?vB0YRV&$wj`yiLk)slQRi_0s-w{vj%^Xkj zrbb`;nGMnD7&;CUXgNb5N6wpV;L}@&5gbx4N1n8MZ8_C77@Y{?G<}1ooyY|3)q2Ze zA^w(6)YtAfblDrf_|Ya;gD}>I;(F&tXrwk! z{qjnE?eM)nUoa_u@6V-_V;2QsUWODzs1(z0+Hl{Xg89qK^|fDBkuT=Wvzo)`>{z7^ zQp%mR!_)5cwa>B(iDa4lRuDixW%ipf`9-H;`BlOD+=Oq{B7Ccsxlns!ge$wDnJJKf zc)v@9hDG<1XGwJ6m39&bum={&jLx*1KW&i1{!s4nc7^$1No$NMDc)ViKioMGHoe~bDe3u?Rg14FXMWkN3V~2HNeRaLsd^ugYw#0c}HrZ;r zBpP(L3O?#JHe=Vty;GuVrBWC~TKYbDcypOp7V$|$%BWE0iwb3d3i1h7m1`}IHTF#G z3pmmyuC0&xI^tZzhy+2KzBwGr)4$Kzx&*_WRccNYNewgE$AJCerd|LVZRr4(`aM@* zSV9aY^k&i9OYF6yVj46*S=vlb=_*F8!Ltb)anS_r-VM5AFYVuk^cEpuGB&xnHp`ON z=+P;5bKIYB!?|dJZoC@G?aG~?bLB+aySJUwQOEtVkE*^YY~yLZP0WJjrik|lTkI!z zJX+KA9(T46mrF;abt0GD_hE$1TD*Q0sob(s_HSb=t2@#9L%oDv1 zK>@OS1Z@P{_{5d28Ec;_iA|sFfk?kK*K?@1tIj?FBhc%YpS78T+@DVd0d18bE0e)-(}sg&@Y?FKfuaRjq2mc4fO}PR22Oo!LgKYQ zig`sW{u3zOp|T*3hs&9G;cbpuV^IbT0`30PR4E;69>#wH*DRrcw(+6>x7c&L%?%hC zcv1U#S>{0?t$-186*h>#oPf5#F_M=GucJ!=B-5wh+#f9%4RG(Z!1^oR6j(bX=%JW* zt8@ax0nRP}fjY6RkZC>&e1Tjs2TJSDKO^Hon>&|6`}|G*>;~gK?CpXliytid#N$vc zgsXw97(qTTM* zUXBLo*+sVkDk4!7>Chk(3?-^p^Ew1xmJ#c8kqe>v5TG$dHfVfg+^crkP@owAnY$4L z$lVNpOe_U5JsB*>tuPj@1Y}|m+6q?+yl^w7gvWE~;ZNCir&LKG<96x1=6ykdh`>eZ zEky0$88c)B-~F_QYDQ}OkV^Ev^Rkdo6Hl6**+aMa$L;cwkbsH`6Cs<(SCxyq$4wd z2FGm<@Oh7!7&$ zbh4b=Qcj79)LMz7V`SFu3N>644+oB1wMo;|5kEPU7#ER1@dAW;9}9CUXHhx;*v zs`n|Zc5oxc14zx-Kqp!xheb2#lZ0~8+P2E40m77!4QoX#ppV181jWn*eI0N7=Y(k8 zeQUlBDU{$L2fZeg13JHo}6riSy)iu|`NF4;1*Ys-Njd`QlP<(p= zL>e@non~ZjG{5_fb(jfr%O1rMNL|qchtT|ni+*H>U$=*!%{ut<$uEz)Pca7JxJPT< z&QQYfY^~K$5BA_p@sl_%96w2GeZ=|}T!eN%I4QjnY#dn!d6feL;k+Bl2U={myB!iq zwv)ugbTt^HjB2E;Ix()v9C`C)*88SkS3~f87t@gOOUA`Vi@`9Gb@lV;9 z=fS@05>@_u<*0|tkkCV0W?HppMTUj@v$eY(qQ0s*6+wqFXFM9#3-s#mS5bTDnzc#3 z%;N^G#pjFOca%=pvBH3{Sz`HaH{V`}T=8sjMC!+PVV0aZu@^8cZsi6orLb#zH+ZYB zU7|?^>$`_hvkf(*bP9-=uNGOlxKw7V!n01k3t>=+N1a?YdKqdS=4WIznL~F=CG;De z-0EbplN}cB$LTo4%p9YKIz4=Ptkkz;JOqroP~D8`xPTAPl&;E}HQMO1Mte64hf zSkWs(8cx6i7M{{tiE%5q#JZi$TXimq5Lv`MvI*QDOT5OV z1)i3V)asmx6nD&jBb|_bFs(w&vzXg2XH;8+-qbteA|wh_Kcd#-c)g8_H$;}FJvI#g zrT7ojBM^`^&s#lFU-4zHF~!NffA-tT2@bdX3ldeV4f>*MeV*h5ksHs-uCs21|H+x^ zAURI4zubGK*TffU-m1lR2|__Q0=F|URV28eq3*izve1bdYP43!s+anxRjTwvXQ297 z&V1IZYJ;1Vh&7QHh@4lA(D<`jsg$vRrO&=PyW$D_?#_$YT!2RD7KrE{P3v>rFjMw;Rb>OD1z`p$OQ}8$BX#zo0?A zddx3*4t>eWHt8N-WFdZ<&e<+GmsvTNOHO5G77{gJ^t`Fa9tlb@o*#d7S_SZB1pvPV zJ{r|nfc&r+D^#5?2-6#gOvH|0GnTD-v>--U_njEl^psh$e(r%8);$cuUbM_8i)Sg5 zJoWnzd*~0E*D07=>FAO=AT#+#Ds_-pF~vdPl<6 zS&=M$_fI5>)nEAIk`VTch4=B@|#y+|x&C5CjKd0ncWEB@_zdh-X3BO>Df zf`g|5v1!fUD3loA1uBqL2Zx!pSY1m`KcL*;ak^7(4UKxF0kbe17O*12`opCtH?bF6 zn?vOhpDThzne|<)%lgRIzcyQa+KGV~jpZRUC$%p!gN%iV9%)GGbMjUw9pNpqTC9Ps zbY(dloibUyMQ4`Hi?oZ8n7s0c-7&mw16(t8gdcc7wwCz?Ad}8Xkxs;hEh=%V`E^-4s`;^8c5ChQ43C|*QO8d54=@phGoh(R$ojTjiDNd;@Te9I) zKn{r@QB7u~7bnn-1RU&Mv&-zx4)ZHwK5f^p6uM z$XO;B#K2N0W7Td>QxcK%ysV-&8NkWr(`RJn1@zaS3@%N4-6*`7@2dO1;xkj$G^ppR zq5F-(DU!o7XOf<;Bp+S5maZhuhln=6p$dlRxy$PLY}L?K>G@W(!0Pz~vS)0*&ENJZ zf>8(oPSJsRKl5Q}aNp{|^Pa0}`|P~`kzA_de=j}uyzd?+m93I&1M}WVW_tgV*VFU< zuvMDge?^+zZQf4;Q*O=sG{|(a-$Hho_q!n-k1^#(jl(EBQL1A22dtU*sw&kGteL-6 zX8yq4sR2w-T?k%3Xy#8)ecvfL2Kt^uK05O{>npPUz2*nw)X3@kFUd*Y-yk8=_iw|l zll_lm*T43Pz@zSX)dCbtQkgz_EZdc6;W-S}Y^RDy&K1-Lh=j6nD=#)LmrVoU=24xn ze2MtOqURPfDOJ`e{DR~M$_mUz%7+V!c~4uM4BlUv0}3hiVI$wXJzGwd=$MNzTY$EB z>n?tTIs_S1N)r6vXuZ0U7*awjV#8IzC`1#r(V2MB(9G{rUKYeH;}W_+1r=4K*qu4A z{T!oOb{Nw502n&mJ+=j788U%gXTG`@DPB4~j2s z({?>N>EWMA!<}L&*4d9(@RTjOQ47xTzFLOe1Qr|I-Id=Qc(tlIZqQbj_tmNvV>_J7 z3BoexL!htw017Wruns9BnEPPpF@8ZXbz#2G3HE4)|BfKG5r&TjPMg7k+&Vh-zemq;?YDGU(9M;uz) zIVzVzm&YO|Eqtjgcg%Mn1u9<#*dK3H8?34;H4+~qC7d~+Oi=;6{D{y=uNd~5?`7w%J7MC~FRP6R;BC2;rR4hT9=IXfwr z$R6`C*}#bY_&^=9>jvsA;hn75|GqBxH>^q7mDO(qeTR=%uc zSW5sf-%f~9{8MjDti(!or_tTn@AN1#Onaef5cWQb2TT@EqGz&sc46}KWh9M9oBW7> z)*@vG$s}X1^F2%+k16j>%MUz8Tv2_>p{>+gwXjTXESgeej-z&O`yxbPi;DPH!atV^ z%;&8-Cp0rqy|5(Y8bJjQl6%ZvWLf4M z8Z~T*6(YgVYYr^-c&iqv{$m^3l$6~=zV)I_-Vw$aUEu*~{BtVdJ_n*iH++gj0I`_X~aG#lb7vRNVc24N> z&rJT3RDO$){RMBI8SF78e^+Yqz3t4sQYpyD<$=f$-D)8!cN^O*ao6=o_pCJ-oh&}{ zmud|z?_~{M=8s{Ex2nplWpEE#hClOJh9cUYf@5{;7^_f|UIo>u6fjg6+hkGLMzSL2 z^TnCfxcTVSXcRfbEFm@Krd7Mh{ZjaN@GW^(OgxktTt_Bm=?FbfH1p}PCpufaGNx~0 zY#ZZynR(PofyjmMdg8s`N34=XLw^voGdg^tP{Rtid>( zxa{EeAyrtk&2aOUp;d%c%`5u+;paG+LM9i@1`OhE%xnylAA%e4cOF4%-=#y*j13sj z9?xM2=c}r9iVML8NCv0aL)3JIUY9Z{Lj%_FNhLJwmEoNWiav})OpWG0k?S?r;!AfB z3lLuX<PV2yYtdaG?Z!+{2`(f2jO_g04M)k&)3*ErHdWB++t836t~`iEJ`g3NOKx^o zO*|`fNFCQ)ET=o(#?)4?F&E>xoN})NSmz6{ihO!dWQ&IAQhUJhsi$ofRM$W6+jTbaj8FAVDgKV zp7~osxuY@);Z6LuJUn~MxJyMkjovc`X@cEXZ;Zh0V>+|M^IEE1p?2JJ6_VQacWuXqWt z*4%$#=u{jou$kT&EN(Ew9Z)2EJIoJgF#dCD_cWVd5?oFk+a(1mkT118Y+vZ`bad(E zdj*9NSZ#y+>IZw}r%@<}1@bftD>3<<8yNSt7v0l*Q7%CBn%{`Y%%OZ(CldK;y&!a= zw<^>wLMDP$q@x8HTM|`f4TzBWKIyaHEs1!d__JSp;>e{a)g3Cbh56DUX)jRPC>RHW zK>EbN&!qb`A4=aXVr~5T12Q+r+~7CQ9y}FsLxy=wZmu)%>pIA4oOS!@r&0_E4|6%q*cxA4PGef zq>~v+qN4VTp`5B2SwWM5v;BmtKL8um}yyzfyfYD2wX7MF5*_6MY@p#M5GQQzi6=JP7?^>DpKr9$e;M z3+aE;P9_@?a1F={67Yo`kRR7lH6&nwkW-L=yA~I?t8OX_Mx~L&ooPBkRZg9%?#kUr z|I4Iep(9pF#X{8ue>H@n8%#qWE6v#WFkHpTfpg}HxTWQt2V`oEoST-XaSlQyj7IyJ zFwfc?o`HqtWbq<8P4|ya7RT>X-9LfuV=eU{(;}zMeDcvR5fZWl;;C_7@@$0zCODod3Ti8!5CAUi( z>EV(vy@K}&-rc-&jhNoZdn502d7rC0o+U{x8&8Ded0u^%9npaoMEVq5aJnE#s%hEK=dU-?MsLAw9lMdK~!Q=_DRCk0r)P2gQcP zJViRVgd43>9ei?~06-m+$p0fPwN4g-ozThY)M(CH0mW*&2;%e1YbdM6!2y>lc6+

4OeU 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 W7ShZ8^lrz$Y#i(>1781++Wucx6{ofU literal 88832 zcmd3P34Bz=((h!0px{I$intIoUcm*E00JtPgk)f%0V5E=1w(*9kS!(?77+;~fehnl zM7iRg>lMX4F06_s?2Aj>ak~T*IftkqdIeF)`&U(;Gd*DjTj8^= z4o3o$5w->XQrk;;YWt3ix2_4T7<6<}SBo!F@eMy;_=cY^eAYFN2=KA4u>v}xaizb_ z!gkCxQPEjfqNPvvZqFF{{`5fxkGWo}>a(sE-;Lm-_WjjQoFW{g>I-L=T4ikOs+z-X zYYQ1s`0GC~$MHamiFdX8HuCxraeICq_tWj(C2yzRLsg{X??(KQUC6Yjl%CNo^^}kA zZQCkxWNc+*yH2GoYNI+$9+eVtTI|10PpECxcD*Ai)e+Gt`tsuFh#{qE7sW-S#g?5q zCobz$cMC@Z$)e9-xj2U4nuEWg3Z~0&{N0SdTktmmfAqOcE{ zZ#@3!GXZ~-@HYj2ci^uGe;)kNrv!gf@i(0Sd}hdn|Gg9c-lgDK>UuY>rTCkxVCzzb zFO>@L;<`Y6_u=Zt-@W*&Qn>qZ{RjRY!rx;2J%YbS@psl8+dusMr7wH$9KNvYlzv5@ zKfAN9uloD9-n;+r%XU`ZK490AcfM4y;)(rt-I{NF@W7v~uNmxnGN&qcmH+3{TEDXM*G*l|UHkFRS8l64r)R=HAIR%Cc=qFoBQ85|@6;t< z_I~oqyq?!YzSCo{`9R}&kqdt+8~e=FO@I2c&M$hY;>)e;{N7hzy7R3k>M#6o?i&wB zT+lP&wywP%UjE#dy`P`+uQU6)KK-HWKOA2OPkURCIikiD|*D7Isc7^N5ud1c;B^uVj zA{4&OX`$ukg|UAY^b95EyfAk7EKI%sK`;#^=eIEJ+8(CgyN2nno?-Nv2m6Gw=eRI( zHic>LAjrQEf6YHHhG}n~Fzp=-`=8!i2;f)4=(9MCKYSR*J`2O>^HZ31b;KkRs$Yto zq3w2c7&-03=-)Gp{2#*5Ulzt6R)w+Kk}z@>!2Y57y$RznRD1o?^jROqf4&Z*=khRd<7(I;RK4xdkD=^8 z4ebqO|1ZMC^Lc1jsPQ;2jGm{3@xvow?0iNTIWL77*9XJ&%MW4X{1C>@^TX)#M;JLf z!r1LG*tw<)o=syb2~Dolfuv7_O@{(sXV`f!dD@lkevFRg1B1YTcaNtzg7_MD*R1KpZ!^am;;zT zM^tb;XP{j*nS$7-@Q*5doWiSSI7VQ+bab?FRH=Hcv38lNw_&{qu;^=Ai+xhR5PU!Q zAAKGO)4v~}jPx1lVls#7PRISq&ZSB|wTC{}us&@a4bALE_B#VB8~0UAX8&`8vVZMn zL7k=gh1L&TZ*Rf>q57ps*?GKbFF^iu!?>eC+eOAUljyMu+FZrF|V zsa5(UC^?0y->cUN;&X+M3uFI7umkB+t?b`k(SM-qw!c;o);OwAb}PL>@VTm8U&F8B z9PJzrq4{(?+#^$vjy#lR`RQ_6U07+AEE44qv&ZZNuPaO z?>UZwX7#>p*`Zm#3|Drj-=O$WAARmr_OEvf+)XZyJ2AhLeH`_I@IVjxT%z=89w+~X zdZ}L;RKE-ta>w#8@vy(u@BM{voU&&Y+C_0=ni@x7=TDllTZ8Jac!eLT+FQR?5Gq_c z#zA$`zfd{C1||PXrDt_B|9M;4KjB7^Qwloze5>r-ynp|r{3J=$YmK`&Rd4Ah!fz@& zJ92Z!O`0+}x7d?cbNAAtZJ^D_ZGHvYm;)2}#$)m>? z7UUOYCwI4S=~E_q@~3;UZy%ftjdbEM`6ndqX-VOxpk1E)V?{%1N|H@j>?z96o0Kwb zO3|3?>kB;DFu=_z$#!x6^uoN!W0Jy%B935jLVq0c!6~`K(qq)bvAGlSXB?}ZlF0Szxbo!gR73vgQDo$z8HJt@gax-llK>&4otSX+sL{uhh+Yc_CEDW%wP=%} z;gm7?xy5-CJ=vqP3r2ei9L19hi^fm(j3ouTjbgoW$K_8ZlFQ;H_!7xl=< z2j7$#uBoBRd-c!v49YJqndos19Gu(LHF>HlG+}bj8z$RwUDNYNmw57B*~v+hQ6nrj zH8(dqOclw!G|u!XlL{y1H)l;wW-;VnCB-af%tT#W3fHX0P(}(jX2?+0+@M02gC*sW z1<*;{b_xj7r{@;t7Zp#TA?%rvJ2ffL${_xXWZhE1MM-**Ze%pjvPi&)95Y5COia!l zorm6~3I`XbC%e#BgRUQ(mpPg(J-GNPM3C|0CcA*7I0B+>2rq@nNx2AB;Ig_W22Si;s36Y7olT*MrF+XoYZb4qr7)|G1LuM4_yNZgY6g4wpcSb68 zxbl>w+`+l|lL}#~qWnUH(kVrGgUXcusOE?pA&5>0xQpKL!QK*7 zLbb#DMo%iVS)~Qt`{jA^CXyE*W{S6tB}{HU^^8rN+%-LK;>1yTqbCd=J*6L_~Kl9+#nWB9y5OOIMr%Q)fhYQ7NBxV zJY#zX;l(e+K0+B7WsIdNVW`~E81zM|a%+SJNt(h<7Sx!0rc6_8V~g^GS#*YQ zTBun;AB^2@n0&+amV1!3Yy;*_&6`+~FHMIbCg+CnJ+Td%kvq0z@@NWu!o%eG%1>=i z3yLT`Fgei3Mhu7BiSwxON>-jSRwNbV6K=t*4THvn-Tz1exI@PTct=f{ z0*9c4Vc_+g7)aeIR}CQ(rxjn9H#KkY=%Vq39+%ZCmW@;=+}w>)XE7+J2HLo>8{1<{ zz9(<|L`*wYz{)^4%gpXatsP3{m6iv}GchJyE<`_9k6}f5h48=Nfs~yhS%n?QXb>Th zw;PM>kH=N+&6D#cL6I?eoGeV9Hc4nk%Pyq5>gohLq+ZGwqrp z4Us%$QuFCL$g`6%t|-g2b2{`myGc+wXFE!8Z0*@k4W#2nV4cbi@K#SsyquWl89zBW z$lSrxHYZ)2T(Pb0D9JC$&kZ86B2lo0_6&j0bTeWb5;6p{>3O5ZPfbqlf$y~RV>`1k znQE{Mmg5OhQ7^f>OhERe6rvVnVY$WQk5^G>DM||~)*PdKN^)-Q)JdTQXAai#J8Jmg zV-Tv1b~b5+?!uCy{M@PIi##P5OS!p)h$8uUV`w>;D_!Q8IDS;IXUyo!F6&Y}rOQ9JfW!kQ6NsY5M@K-gt6)?AMM>FK#$ z!P!46vu}ECN|%%_-5u$}ho|+;%uVjnRnWtSgT&f|!4`sSA7Jx?KT)_}gZ{H1^@T4w zrF^F?nPqd>Q%8A6&nNB{V z92eR25sr@(J&GM7FVdEms`fF##GeGU@#=1dx9+3LZia8TR`^CX!&`9nc^#R+l0Q;y zzzuJPuewR(6gI;rDEjHm@NpA_zNQ&I^;W^JY=+Oy6?}a&e084Sw>QH#j1qjDx-ZMp zzxHOqw`-0cA^4TPXSN%nJx}VAVlxp}ZfwbgU=Uzmw<100KWil33rQt_1M*gYR@Z>s{{G}TH z4vl`LhF4plT)J7qPtxeKm3>H09dBs#*4{a>9n$csOGKL5hb1|)1;hVt@6eI26mN9A zTdP;cCuwr>G&!}J939_Nqo;eZtWTprzBUX#L5;`ea$+@l zk0!q$41RMMd?!u5E+(fcYQ@&??k~I8S3yEt_ z4Nn=M^-0z6NQ~@{Tf?g(G%m~5@T9Bt8Lr{&xfz8cHN5Uu1sWa+o&71)@ORl*+~=#| zaf^ZdDb?`S86y=|YIy4mpYT;0-bo1cS*+o$IhKm5HN1Y0@lp+cx+MhH8VzsVD?!C8 zHT;5Q1KxRZ=JC- zTgQOko~Ox))$nw$h4qQk@aJ1dT-#~*3p9L!h99QkJ85`5ZX{{=1dYC@h8K;cFjd3r z^SfKaKcLCU*6*J}7A4Zm5#S7`Wp4WF#xw`=$m z4d0;QyJ~nt!*|p0`!#%b4Sz_(U!~z47Y6*lhlY>U@I5troQ9vS;oE8WUK&0@!(Xl8 zJ8Af9G<=eV@2%l`YWTlv_*4zAmWW*H*6@Qh`fLr~N5c=-@TnSpq=vs$!xw1yz8bzz z!>4Qb=^8#m!GIq{6r0JX!wUU{C*8TU&9~L@P!)QUG_t)+ZS`b znc#3&)Ouo!*HP#$TOYelBf{6F?h8TEbn%1u*V!Qz-v}-sBD0|hpNkg|OsS7q&+uG= zDdjP18NQQXN_ET{hKmTMRK~1k_;!LRg)yrb9z`&vE@mmiHxo=Li&@C)i}2&PoSY+(2lf+>|S>luzDm{JI{mf^z&;4=xXVfX;Slp2`T4DTg4p5Q8mcM(h} zf?3M&mjqJ^U=}j`5y3R|njS} zOjEiU$M91G(^PIc7=DCcnyStHN2vV^2~Hrmf#C%NQ!q8_8JT%~FPMCYYv3vykCI1a~5MB*WJc+?n8PhWipsQ>2;7 z@YMv<)MzF#oI)^7iDm-Bml8}ePwwntIG^hSw5IQ;wO+@M?l-sxgxoevRO32~J@6d4g%mG2*Ob5e{ z5KL2sx&IIDe}Yp9ZeVx;!D$57Gd!1Ini|YnhVLYprUbKw;Ua=*Dln@VzMWtf!Bq^8 zBDf#Hr3~LpFiiz!A;W_Rb`w03;p+&_BsiPlz64XqH&YqDnqUg`W)j0G1XCzC6Bxdf zU<%=89K#n9OrhI!Fx;MC3fboV!`%M_Q>Zo@7(RvI8wsvwIFjH&1lKZr_*+l;JN4rWD#NWcVY3hZ8)K;jIMUL~u64YYD!Y;8ccJ z6MPH7NesV6Fiq)Z0^l6CzxPsL+}_?-rd`Be+It5093_{y%X&YHVu}b%i~@ASh>bDXAdL8B z9dQMe23ryc9iG2Ix&BJI_SDMuKtonj{Rndy1UNgCI`A>C$M*nxRgUj85Do5nAMM!s z=F@RS*T^*Q<}~jX=kjmT>WsLwI1~mg zy!n<4F9H(BJA3>Sk#9a#bJF9VniFW>$=Rjr{9vn|Y@Y=8=*iX{>`fFJDcX0GL*}8)x*U8o$95qk2?%;@hvULZ~7AISG@Jw}bbqB@=#y?G%CprG3 zn~$-R82=9Nh8_Q@zio8n-6YXo^ZArmGk|bZu z0#Lfkn5hh3z5V}ONwK4Go5Yi})wDLIoWi-HeTF|hVr;KpT+Z~hY5vrRu^GKKx|}OE zr#btr^}A8B5#P4DlE0#Y0nUEgGMp>cfqsB9eO*82^43oL6W#Kb5ovV|v94BiD6LJa z+ZhW!=ZZSe6H#UDvHCntFebW0nS={=Y> z6ao*VD@V(k09LEoE$3-UC_QpR&ArjNAXy z)Z}y3Kt!y!><|{(K3A=`>`#2j>h(v-=b8TUM5-doo4?rYbya2gW-WfR6oQ}<^3#Bv z3rS8+O=j7q*fj63L%tk1e}1)CqrjU}mHd(0J8SV+Z%*~tsx0rW z4DZn_?>^(ezNRL(Z@}W@@^gYr@=bCr>^i9`%Rd9AbXB|kuG(OexV_t`Whkh@wNkYU za$%o?#v_o+wGfmnhB7L+vYaZnucXoqizK^hjgG&vAwwAPHMD!N+h56gd0nM$uYWqy zUYN3!P3i0aJ6iQ!+N?e@s1YBczE^+Y`qI4p524F&5o0fdu}j6+6;uoCU0U)W>|GGn z-Z^RBPs!tc9qji0K|52%Za5e1M!CH^vb^6DqjSZlX(L9Mm;Z!xy(-|pV=F%LxN^$& zMmSfXS9X*4PW&uZ+}G{>g@my^-TuMRZtuV0aO7yle-5Dey&6jls)Y3#p;i+AoxBZD zE2KQ}r?jDIIcY-%dq0LgJu5zPmT!OqQ-5dqXVqqUkD%#rHgx{dH0ScO@Ha35E``or znpw6nwr*!!-L7`6wi5mixg5r@mv2YBIW;I4`ln9SBxOgL%9~T0N!RD3kUdmy9pu3jHI=hJ>0 z?AKH4*Q)=2+MDv@|NHiC^EboG#PyNe%`w6no3o^Z*QD;*hH^v40H_Q7QN?a)y zxGFCI+0clzx^LULQievjDu+e@(JvBf&5v9u{UX!qcE!0`eeA027YY2pC|ZNMQU*rx zWKcOU%DMdRXyCS_rQq6Xo2%8j4DX1Vw931qK^;@Kr(Iggz!-F33~Fh?bVFOfXIg!b zR!Q*GmZ&E!Wopa1UFhbiEmNJ#e`|G+T(H&Wa3Ak1IMF_14dQ?}k@sWpMRBs-NWK(d zxeyuxFp|BfrFc=aSEkW5ttNct6bOytCIf=lp}%Xl&+4)_jxW-5i*ocyvb| zqIf(ea=$&MzAe)d-uD`jMz-?296WXBg=cH|E-mTb8Nb}ZvKlgr?RtM|V?WHA4 zEcOT5)$NO``zbb~@)rCJZk17a{VA2#pPEsb-a55%W}DQ?;?pVzJ6$QaCNhaDWk@1u z2DfshWF?+L#A*0)DmYvz8HuflEiL7)MDWdQla}I1JdFgTfyoIe2v^REHZ+7WIb``T zLHTB3EO=Vvc&;gdtot-nD6!uBf`baGV^6cP+KQGAF{j7V}8mUbtUQBvZ5$ifD@>hQ3g7 z3slxJEs53ZAAv6sK=hBqmq_{&g)dR`B^qC%=}Qd0#L$-(_(I(MiM=J9Znze`BqEpa zAjOW9c^G~f7^>_aImsx+G?V6iF9R!1N|W6F+0kV?J7Dhm5@aKrn{J_HZkF3TU^;a}kPe&(+G zDYESQKG3pTN?N5Sv88#Bo$p}ir$=Bn>sN@&@NP^iYjCF4{uJHnGht|((%0Xu0@RMm zY>*9(boctuId4ATEPpzM3^#HK1ct3?Wjp)S?rqWPfZJafUAC)FR8;PKGa^w{ACz6&GPUyWZhvt^*{-O%UD57dKRf4-gBO+UN^+Og zlKI=7QJLMek?deity;cW_WiZA6IfP@c-6W`<#mz4gjG4IrAMPOy&t-<<+hTo>D@i` zjI@<>0D+3_P9T0iqCy*_~ka zJ0p>tV4_YdZAx^OzY&8ai@*PqS^nE2uZ@`2GOcu0bfTx@YT9@oo8~>sJ!d`Dra717 ztC{{;k;%WUrt>Kydk@TZr~@iFg!EzBx=j`BP#G;3ymcQhq3>mD=wIhlqyZaZDE?jn z2XgzPQ?UcvXX-+?zak0c5DG+@aCF_y7DP@83~;;+A87*V zsaRaCc#=H6+i6q~QNG3L9f&g6b(FLGF7!FR<)t|vtaU{+psS56|B_N_9@Yx)!(wjV zGHPvx_oY}|TwcTN{bIE^!X8)hkH+fV`k?hKA}Y!J(#keO7>(cBA}lWBbKo+rd5LUY z@_v^8rBr-Lt{v;GNWhm&zpGsqO&t|1$1c6e ze1a;x>3_Pfd7Pw_Y=1KqCGgkPQMjs=Q2j3SIF>7oz6#R7ySB1oG_DAFm5W9(0uzLn z%PP5E#7$pC21+UyxSbJP15@x&;2N@+ zVZ36PVlhk(Ffc{ML@q%M+4xeqXcCuKRunTDH54&|YhVfzZ zbc;le(OD4(lWP&Qjfp!kzLxVa%JjFr!0kW(5fEayS0qEe@-?@&t_(?oe_))u&Wx;U zK)CONL3L{7DKrNl1lO9;NW&sqZAOg5f;+0RZv^KRwb6~eW!ys|;`Jtp*ZYL}gR(so z4z{Y2=LT1E9w0b03 z?Og6BcS4*-t8r+$(=m{yMtcua12FGw#hfDohoS*(ufc4CsmAU75Yq}9d6#8mB$LsYw<5eBpx)Hl zeO&Qj#f~Pp{n-dc_0tx){W1T36dB;oYvB?t5n!T`D)eh%-a)5YRz8V%9pOqwutB(X zRt!LqIbJVMTS-TYnPq>vv7fSjfWIKZybEVeZ?+(>B8OTDKXaH%a5Rj*ycV`>nT`&K zth}y;`3lknqz4sEo|{VhBzmHMSvR(-ban(50yji@{*Ig@^4dgCm-1TArOxHUqJWJ` zt}Q*BSn@fJr)EU(oREw~;BKP_x1~ju3^!ip;5T@ zm#vQ@E%~Gmf|HDC|88n(+#>6G-^_N#ID+eO^tS=3K)+#ep0u*fP5Yg7krlPG?|1u4 z_8DiwK8^E0^G}=RQk%wkUpI^mrfY;O^KXEB*@yhsHF@2Ky!DN%bf8|}e;|9UTnht) zw$~M88_Qm+xs5UZ+yGoCdo`fyQ1-el*k0X2+v^J3Ufvx>{5KGFjNSSG+gKN{+m!@w zhE4oXN$i$k+hn$v?eP_8%$a1Jvfg8DGTn5YEz{Ky>AB5Jw>-#n@K1k?JG8ws(6*}nrc`oC%a*~*ehdyGJwp3`lI{NpBK6xLF4Q0K_VCs)$(Cj$<(F8iHKNi@eA^YPK zB31p7Ym@5Z!tRgfi1fejk3dJPFGbcdl5bBf?U{(1fXaR-Rf&M3bb3U}?4O*=vm>+o zBO{PSd0Ln4%_}_|G3^T=BGXFmN{mh{!A8qniS~NC0g9C!>M(5uAIV{jy{qi7^X}(} zCdT;qGx9vOvR;I6KOF1MLUKUg;E~9a+`egs@dOPpUoqf4#wa*_MXmF}^a5KiJO5IN zQ$mpbx8fA30ju9R_fwzb&{>4h8!EZ|Gu=4kFy=rY_ToS?-Ed#i`vAPsS+UpwVkkpe zxc%1`uo`ER8fEJf*cg(xu|1v$We;z_9?psxXi$(%-bJ%v6X*O~l<0PG-aA0i#uzI; zB`w7^&iRvo=X+`4U_+oJ8iRzZmo`PwJyjURJB%m5X!a(^i<`x$X(c;1tn6LOYwjlFR%l4Xg(Qde=dt!CeKFl<`lq2T*Gkk^ zYpe$|(cKR^6-k}teQ2EqO1FOzorM@Xl(20~R6#iCmgM$UbRwDlWg`g#RX$UMkF$V9 zT0NL9Nk;d@A6cCMOLaf%%>*=QkMTW-#BbR?o7g_!c9@?dj*FlR zSrBc;vY^*R&>JG?JzPl8<3!|LN9WP6eMGiBXsl+`4r3t?=6YYA}qC8-NAwr!a)RPtU-$C6tPxM^K6n4j6Bn*kd&|5LI;l}Ktc0UCIa{{`v zk&gL+;e5gH5ju;|Cgr1z-@;4CAjQB_Q@^4r-)ekU-JjXWtG>XR_pio>Xo#cnI)lb_ zaD2E4jzUE-6dzE8#c%;eFb#VeZdWVL$;5e_i11pyh`EmkJFhLA<-MClg!euaqAg5x zoQSYq5kC4?BErGaAMDgHxM(r@>qM;Z&gBPGl{@xy3jCX(%Etf%BU@-I-*=~`Y zr(`EXkWkMLqCQ8c+Y5D9MIB{R-^As1JlG4{!UB!U*aFeS1^531L?ZmsAmMKb^%|l6 z3>RwVGbAz)4|YhK_EVc0?Rs}It8K6%kyI>_?opC%wd;Ki=+|jt2|zHAFm^N$3#qV6<==+o;O_c|7=44Ve)6LZ&KG`NDWB zU#NSR9Hv>maQS;OGES5)JP76!<_oVVVJFNNo>7E@nHd@b{M13RK$m_^Ef^X!NqtIC>fNCAT2OBE)m(CM0T2z zeL4gQ^|&DF-(fB^>F}%Eq%#%ux1bT~UM$Uy4_k$Nn~;A;7sQ7*Z1PiBxRozFCe)7$ z^>SRuUh_y~AU?b!ZK|g>ZL_tkV^-T>gGAC`ku*_By4J3DA<6?LNEGUeh5GM``ZQ2m z@nIBG*zw^Pm>X93wT7+GMlpQDLODJZ;cJNaa0{VB#D{d@G+v-8j~gEjxV^B}Zn{?_ z*7$)fgS}#$P2&L;+&G5BtE8jxE5zZO@z@sR@$&&B*EW6$6B;wQV26HfgLt!wYZ(Ih(OhsC%U2Z+(vrty^oMhpyl z8;ctPD`=5H=LkEn?%=hIzoL*USPMipz8RlGMn!E2ZVAM_fd2TEI8{yFl0{b9k?E}k zm7Azehd>HplZn|st17v66>0AFEhDMCR{X{N0xA^gs17&R_~`CJteO0{pV3gO$wha5`#Vk&6BoLUh1vX8$60blJN{yu42C1(d{tb=%tqVe(!i9^No8a;CI{bUCehsLEw zp@827CWtKA$}yyL zg^l+9#UOwIvERLe!XCER?m>l{sIa|V*ec`7{e9}mVb@8@vPa~`4J$*c|QQHn_Q4MlSY;G4u81A>wcwb3v@<-If_SAmdlaBjbvV3>$ z$GtAC3B69CUCFhaLsCL)JONG$yAG~oR*lhHYAqiCgcpR^5#DjY?Yy+sC_bIkTlw$fAq)?jzNddl^8Stw{bO-zRP?7_^-zH7I@VO89 z?`ZNC9`bHBKRZg8fIkNNAD$+X)fjnUWR`DQtaDy&43vQvx_wEw*~nS`1u_(P8de$y z>DXj~a*-_{E1Ojn?W~~Nklkf76C$1S?&j$_y%TL4yM2XpyOZY}aM8Z;Yp^XjOfeWs zXH_{$t`!^HOnry@zo()add7!i0vJDQ>1Sy6DL;}VlHsTwXe_S_agRO40UUNwh8M9)giPc%#~i38Ki(&!U)GrP^d1F( z{wv9PC3p~z41W#}4sL+k*LS~KbYmoV zLiQgz&ArL)LgQu{)4rhoyN#`_`p@U5E(+0qM$&Ro_7K|be4AIPN)T=j#iKu}<4rgP z9K*HJ*oPj1Am1tOvbE9vIZa289zFPB$ITa);^Q&Bb(~oo#4|z9m6k$eMxEP#U8LKY z@u8y@%U4pvUG`;ER_DFOZsjnKuwfRFhuL|^el4U{!OKB{WtQ0$GU&T{0O_kPuF zbmuR5gE{$6sK%q3Rjx{OK|O37?|C(Em#76;Jupqr#Lk4pXVwZ(d^KR_un(yp~P zXacoQt4I#rKcIrZGIk`oi{OSgsAPxntliQdA%Q1Nw##fX+PCN; zQK+5^t%i)E!i{#}>j1U3WKii+yL1t=(s?mWP?u1l&n}$Kg|s6}g{M&AWV`SdfPo42 z$7NJY{7;W^3tOUvG*y2N8d33zAW`pt+PugX6-S~1=KiP1dP-!yNf+3{2O^aOCa|zQ zMkNfWP;D6109B15U>kpvYL~MpyCeHky)VG?q;xUBfKe}{!h2EJxLCV$!@Pko^BT*| z*)&e=dzAU5ZCZZFFKyFd3dcH}+6+!=1}8Lw;{Z#RAm_`MQBz=t2Lg6z$NGP3u7-;I z(l+xe*i_CF_@!-H{d)d@XS)U?f9Odu3i$)>a7Pw9uLkqGo-&lut|dXYtZi->|Ic%CV6>pSmwab;M5 zvi5%eev;x}iR@YZS%$y!{0uN?*7RF12gXj=gK*bNt~%ofpK7FqVrvMh?2DmynUjA>^+?`wbP`dL{Oj~Sc6@V22Ut| z(~e6Hv>}jEFGN2fv_9~U1eye2qzl5pU7(?Te0DXnBO0Z0zkt(I+u`&HxESZZBqogK zL0-W{;z`ica&PlOsG#gB0~P&1DavY|^Lear55eB`XdBt@J7vEQxZ^Ff8O0nKh!eP< z(RtsiBv`wrF;4Djbk1Ll0{uR|O29$)@kK*^*&*D=HyI_t_wn7TXk(0hXq|l@-@FXq zVFm6(6~AN%WO+@#&9DZxgSE(c$z|?96>xI@q9h{x~n%6-iB1s=u zR$>*hfJ_qUt57vHST&_^O*@PQb~W`7oJk`GSxKJ>&{ihwn?L}^871{iQ1zvwKGE)B zu!(kSnr zG>{pA|HuP2|CPb~JBT2dzn8{eYiCy9QeWE(`x1hD@lzoegX2D2Nb6j*McTM5h`PT} zyM;PWQ72Q&xl_d>@L(FOzwLQMj#+4j2%5;O%d)AD#Jq=Dz4$*Ca@B1~Cc5)G(3!u% zO@ys`Q2m>PWwWsC#D%nd6*NNK65j#?|6!qiM5te<3o0n13KrQFd;+3CCyo`Cal%rn zD#*4gc!sI1OtGg>_Y&$ss)7rtf^K#N#X&4F!qP%mIw+QXz?uTJ# zu3$dhd~d$MJ@?lAY`#zFg4Qh|Nh`o+zJ`Bb9dwM!f2d?Q4FcIZIhQ0__NV}H<6LtV zdPl`C^A3C$b%ehW_2C^o<^v#AYHnxL9wXJZ&pcL2SF^3C882#fQEDCqmR~Dso(gdk zhs_Aor{!Db0eGyg{{&*8<1oGzw95Pl<+^^?qnz}s2HsqTe;Vub{h-C*)Zxt}>1&un zwfDsN-7rp!0{cUcAg%@HcblJ+h_^@2@6H67mEXOBG5bHw@96yJujO|)vFV%Vchmoi z{I0_@(y%*DnBR@#yr+47cLVsX{O+1i`CSq^KRCZ@{j5}(&l7IUk$W-L{Y&CNM@}L6 z9YF~2#4P*2s0Q;A3*-FmY{Vc;Jwg{Mzgw;o1o8^b?-r;=|AR9dney%YE*|Zak@>(< zsy%*vo&y8Wx*6jqcml#|2WXA3+LM$=po#_dujFg>s_l!9ldn-$LX+>)iuP2d<=obM z0d5^GUwdPT*mbGoYfJoO*AwJx`=4gJrlLyOS$l`te7t<^Hf}#BblBjr^JdQ1QbdFD zMmt1iqYZ(uy^DJ>{@Z)lc7M_ZVd`DboJ77h>0i>!4ad#b20?{T`PyC%N+I*LZptgR zU>L&JR2pY?Wez)E+ev~$HuTr9~KpN?D&e94rMix|lsL}key{7+GvtlZ5`>827I-ta#8NXR^L2vcw#`5Y0I z_1?0;&Y3cUbEZOWH1_Z$-)aS)fmf5anmH%}uRp+helV|$Kb!YG)>n9Az$>v~8ugPM z6k72xia!N15fm=Mg@VE_zzTIHzFBGL%8@Xiyn&r2qp_;w@oWBP^fM z1uV}Hi^JCIAcz93@e0cVVfhy>)S6iJb8s-yg> z5_t1*{G(@6FE@j~B%;>jW0GvXOu9n5vtSElhDTZ69wQ1UX}3`cl-UBTie$Q~(go9q z75+wYe7Y6hsAelHo5xmopDw8936k_O{Gjn^E1%tqlu&OU?Zj$ui2Sb|ML0Sibk6G> zi?6<6ooJ`e?MvbFK__NVJdK7;?j3lEm9gzfiHlEyl#cnF<*O)DQ#*UJFb^G@`JLdv zE{T}@1F@Ail(zCH{oG#M3X9Ec-cvNjLyVQ>(fOomFWyO( zn^Wn;{j8i%?KDEUqy8M-@( z^0NaX`+|2H-##h2SFrB#BoDj-r5vm(wo?P&Rz!ScOgr_ynAgiF{@}RSemjP+qY~_}(%fdt_~22|F^PV&K--2ReM>b>WcVb+V`$y?mMoKm%I`tDrHLOzo+2bD>7 z@&@D2C;XiCJi>#vQ|KI=lfszyc?J#}agr#l~}29=aj%H3pSVTd3(p_X8a zG|LC?-Xh+8AW#zI-CMy=`=aCjw4$eho(N3ScM{}_pE-y6qx*xn&~!Kk?UOv4P0b4m zvi7yA7gxb@XmHgfGl84N&F)9E`3UfMz-X|# zyTG4KEPg%$HlBD$%;*va<|4V7j?SMcJei~ZAZ742Ve4GDB@lu6Pq_|nXj6M8s*ah? z`dMf*|1jxEXNqKL^m`KzCnQRLKn1lynGGAM`JcSiPJB8M0t>h*^u24_q z@?tzL&Clw#6!KUh@5tnPjGuueHSi`N3Ylb?dr22R-mKD{8tccad~RI~H3r#goF6Rs zWt775uiVYPycrj=)M5~c9zSupt;cL3FBS5K75R9QiHBq4t)so~2O0s3?!I~%p;g; zBMZd^h!w6@!gV2Y9W)LAE7Wc(x7+?D zYaRd9UEKCxaiO-a2aP!mfk#;4S)_eH{fzKDD?GJyfpx2hC*9`RNkn!v#lqqd7Qd=y z1X!eo*HIp5xJ#(}33aZbzS5?y2$FraP`4B6WJMi8>bzk)%Ag>Y?-p^7@1Du6K8g#q z`hC!tbHD=sB=|Pw*=|k-${f$VO)CeZAJO$dOZDVD6LA%PHXK{B?jX#s=rpf3qG*_{-~&f3qcn)+6u!_4P>2eWLmm$6t?R z)6{*O^~e_xW35M)QQPItiodWPxvxqTc!-mOn9}JOg(q5%Y(s6xYm?B;lCeF44p5uV z&DJBSVjY^kgEF>us@g(SYpq8TEya&nj~EWDN0v|}LFyc^q zNe*JNQ zPt13m^+yrne$e{kY#_p~KYmah(ro=vg4mDQBgFb+CR9-Ck9ycfCa|-}cD5y#LMANv z9D8*4wYZQa7cz||(q4abVv#$HQd{0el3>dlF7j>?c|}TIUt1mpFnx)%eL-OTaTj>4 zv}vPpnn-erq)sg9pm7LTnfYn`aVNM#tUtnqZ+~w?>@hghhcj|GWdupmd zBhowDrg1!GgPp;44M2TM2Gw z>oGZ)yon6&i+2e5If~pQqQLs&bf6KSLaaaDhi7T)j~m%=vi^7-Mbh*?P=~et$Z6fUoDJ;huHjUu~_%~WoC|II>ui%@%19T}k3)*p+Q$j%`DCOnr2Pbytt-8kY2 ztUvOCs`-VD6aVWJZg?A2%{QQthIhp`s|o9k4MM$9sCVE(4S&U^jtP?ekWeoc>Q@!@ z9MEX%kB^ARZuJ;p$rqNp70WKRolAuRjKXJ!t(A0fd&-FRUam{(;GC;1}tFKDi4-$E-hEvL?;e9|yqyzp(yz z0b-i3KZdbtw)YrlGc+|Pv8Itq(~pSp#OsgiLDp>j(UZiZt<}`lE(oC~Tz|Bnx{g_Y zsQ2t`N5VKO{6D)M&oG3espRtdBikyHZeW{a(;BGmyC%HY^Y@^(EchSmj|^5aQ>5ygPgzq+*Aa3@E}+z-BC?<-UK}|c4s{zl?XB#9JEH+WBdjK^QO5xAC-W* zr>z zT2_e8e6mCxlr_2pPer9F>XYfD2hj^5ItU#Di*p|tnX0i?2klY%MK$je=e+MBO)QP4 zihR@C!2;Ap)Sc9acy`M;b&lvhg8g4TfZb zL3mDy?f|s*7r2k*hu-QGT_LCXv#QJ}+Ats=kn(@3a-SvV2`;DA6Y6O)=BV;7xVPwN zs>yr~B)q=RoxU zE9JSg0TqZj`ngyN*USB<7P0W*ea4%LHCI?^w5c<(`%yX8pbzvRnbsO~XSg%5UuKI6 z^2P@HOzb=o;%hU4FFB=hCPvNWGcmFk>CF!{`(y4KL&S0j;g>V9uOSvcyO02mEN}71 zO1w?hx`UqAjz5f}HRX>SJms{^I7jv06^vBT_j_Zma@4cgyjYa_A;&o~dJh zz&dC(e1q0U^a^WxeYD9sSD{E~UQTNpTYWvw9^D#T!n}AX)kJ)G(fdLSx zkB+5=cRw4Ap?I(dG-@kw;@w1`d~R7EG8`QYlmJa*=RL$qq@X{7AALp7#}%Sh*#gJA z{hjxfaSHmA(G7Mqr`lQZZq&=EGmhET8Pi0I>7vE`bis6y2Q6ftS;6IM`LMxo3wfrH zkHUodkmK?>`{~l^twW*y9jlEy1fGyyH+2uht;a~Gj^7_n%n z)IE^dZA0(i&W~^4VbT3}T*%N{h^VYLfvV5%hf8aHegF%5dL}Xzwl{YJ5aBdJHAGZr{=R)Z# zy#E$DqOXpO=Ds?Mn~3+{f`(Qw+ib3G8rMc+qi}5!t_EDFhigD13bbHq>xsj~pf=C5 zMbYiuG6Ko>XHsF4Z6xy7fayj7p=z4R+x|fRs@v_q~WppS4RpL98vP zZ~+QIY_wtz;xmMM2_FNz8vS=Om)JvEb~!LwEo<%qLz-R7X~CsWq7=rh9>vC8MHjf6 z7etLus2a}W8XC;vCb4)GLIj9VYP@gNq~7OBI1o53l~;0v3< zXEcK&0qf@pGtmah=jq7}ervi?d^GTM9~PO|eDA0ght0M4iXec2!g1NShWYXaA_qTzgO}}joNiys5pG{H*>PaCA1B3mi4VWS_PZOuorw4Pz0VZwn*DySdiy$-88M4S zl50#0{5DNX`fZxovBn$deEZe>@-jfylkN}G_;bSXdz$gXXt#_opO^+a*vgW<`F=C& zhjbEPl&0(i`_=8%>j(3U60*AwcYomx@!m~MgW}wHK|EfMKz(w~43w#N#E+nAecFrE zvrwb)Ik1h-Nd#_iTklv;rlPlq0UcV-9lNgaCtW@1539Y%eq+whg}vxbCH}>q1e)UT zD*AE2mh>bsYe*N`CYN9DY3J~qrCG5ZUa6?Y5oJ`y2UDTf4#e^+Ab?}J=PWyp&&DfB z@GB-Wp=IOKnuj%h7f?}t&q(zL={M`PQ2K2GR`fgnr1ZPe($5b8Vf6coX#TQ(-;4;Q z-zB79D%o$=^yc=vz_uTXZ!1A@+4|;ooDX#4=dj~$h(AWpXW5QjNzccE>}dI)X20Gc z^_vf@==TkJBe;Kq^n2SAQolVwvwp7d`aM8xIH7(Ox59p*#_M{rOtasTf@i)5`v2nh zq{zS$ui&Ri#wDb`_Ipxi6HLD+RRZzH*js*2Y8}zcJCVJY-4dofzk)qPdyas<a?>+S)n11i+aa1GiIwvq5<@cT%LBqfIq&ICRgvxx9hf#`9bmb z$jzGlC?-KpE0J>=+KcTe3cHsSK_P$lYLWRmF2;AzO8g%${c-#HKo_GFWVQk?2=QA) zyn=~K9r%#q7JU_b&Za-N3oCprF2;PFUe_0_92jTEIXv;`UTh74OQsjAU-}p;@yuN# znN-DJdY>%)wDF`W{tr60r{kS8u_| zMic0c)z`X8Pv zLFP|W&{c~2XAt;Y<$m|kvfpE-#jOPBaDUvew5zjXFur4p2@3HYeaXys8oZpeeU}Sk z-WiTWR&MLg@?slMjpvQ&?bM`$EytL{AfoLoXhb)?dd|)A&x}(mdJ>Aac^ThBW%SH- zI8UW_*WtXZ`T7=i$wsqC`G-XbngPj6p1&Ln{@zaNNQ!5wU#uVJ!2UG*m$TwhC`~U9 z+sCiHmAy`Wp&lzk@8|Q!R6rP;Y0oBCEldlb1otVrs*KlFM;#>n)Ngxue^>3;V1zP^^tp&B2P}2l; zs-Vs$Sz`p%PEgT=qVccY@1nmr8R;C}&OF^1NZQKY5BneQpREFtoMy%rTF0o?4SK?%$m%O)){_zsjy&F z;fFfcPY?DvbcX6L+_g;ReM5Es9_s$U%achimN%uE3-!H}yasPM4!F=HaiK!h@a616 zB==|Af4-Z^@s+T+>5qLf$lz()gb~N{ohs6{XMPdBIi>kfOU|13zY~r_CnzB=o zz0!|};s=4bbY?s2-txZORnCe=;1M52!cbUl)ldSM>8F=Mc=0~SZ*CV~!LPQ$@zsyI z@C|wLGf(i=CgYIUx}u(mc*?~#eNvXsRqOT**qr4bfT4;gaxklNoxAS$D5L*)k@^P@ zh={!F8Y|&n#fj)SfA0rzF?K** z5%VeY6}MAj#)_D6BBoS{$+l~KM#$k-*l^uo^bqo%LVhEY?=w2u zexV{i04# z0>4i0_D!Y5xwHISWFzu=DSu9_;Zh#h6FaHurBnFf2Y*hDF;kV)gT8E5O$_p!dQTR= zzJ|WSqW`=IuN1}v?%3$6M(-deJZM~uZl#!dRX|=2Xa~T}N@|V%C@q~;?QmAO*imU* zU{oRxWz`;H6*~HA{lS$eL~&aUPx^+xj(33kByav^{~6!ms1Y{?uXnlQuqhAz*TRS*m)y$ z2$EasVbv`a<5B2J{?42sL=r#L_@;ytu5eaI9$Yv<-+rKRGu#i6@ z9SX`mW6BYv!J+}-$XAZ9dv-uRkS^$~>YW*9}4je~G0ejQ*y6BiX;heEvlc~L-` z`h9UkA55L~v`Uq!6S+Gr&3Vu+04s%t>)GjetI%0~KMfbU7lS6AmC7w;YNH!8aH`

g&}$ODLLK~NPnp=nXXAv4oLZ-ND^wijdC?2 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 diff --git a/node_modules/bcrypt/package.json b/node_modules/bcrypt/package.json index ba10d68b..621fc1be 100644 --- a/node_modules/bcrypt/package.json +++ b/node_modules/bcrypt/package.json @@ -11,7 +11,7 @@ "crypto" ], "main": "./bcrypt", - "version": "5.1.0", + "version": "5.1.1", "author": "Nick Campbell (https://github.com/ncb000gt)", "engines": { "node": ">= 10.0.0" @@ -29,11 +29,11 @@ "install": "node-pre-gyp install --fallback-to-build" }, "dependencies": { - "@mapbox/node-pre-gyp": "^1.0.10", + "@mapbox/node-pre-gyp": "^1.0.11", "node-addon-api": "^5.0.0" }, "devDependencies": { - "jest": "^29.1.2" + "jest": "^29.6.2" }, "contributors": [ "Antonio Salazar Cardozo (https://github.com/Shadowfiend)", diff --git a/node_modules/bcrypt/test_alpine.sh b/node_modules/bcrypt/test_alpine.sh deleted file mode 100755 index f23af5c8..00000000 --- a/node_modules/bcrypt/test_alpine.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/bin/sh - -set -xe - -echo "Running on $(node -v)" - -apk add make g++ python -npm test --unsafe-perm - -./node_modules/.bin/node-pre-gyp configure -./node_modules/.bin/node-pre-gyp build -./node_modules/.bin/node-pre-gyp package diff --git a/node_modules/detect-libc/README.md b/node_modules/detect-libc/README.md index cd5972fd..23212fdd 100644 --- a/node_modules/detect-libc/README.md +++ b/node_modules/detect-libc/README.md @@ -8,6 +8,9 @@ Currently supports detection of GNU glibc and MUSL libc. Provides asychronous and synchronous functions for the family (e.g. `glibc`, `musl`) and version (e.g. `1.23`, `1.2.3`). +The version numbers of libc implementations +are not guaranteed to be semver-compliant. + For previous v1.x releases, please see the [v1](https://github.com/lovell/detect-libc/tree/v1) branch. @@ -147,7 +150,7 @@ if (isNonGlibcLinuxSync()) { ... } ## Licensing -Copyright 2017, 2022 Lovell Fuller +Copyright 2017 Lovell Fuller and others. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/node_modules/detect-libc/index.d.ts b/node_modules/detect-libc/index.d.ts index aabe8081..4c0fb2b0 100644 --- a/node_modules/detect-libc/index.d.ts +++ b/node_modules/detect-libc/index.d.ts @@ -1,3 +1,6 @@ +// Copyright 2017 Lovell Fuller and others. +// SPDX-License-Identifier: Apache-2.0 + export const GLIBC: 'glibc'; export const MUSL: 'musl'; diff --git a/node_modules/detect-libc/lib/detect-libc.js b/node_modules/detect-libc/lib/detect-libc.js index 5b66e612..fe499870 100644 --- a/node_modules/detect-libc/lib/detect-libc.js +++ b/node_modules/detect-libc/lib/detect-libc.js @@ -1,7 +1,14 @@ +// Copyright 2017 Lovell Fuller and others. +// SPDX-License-Identifier: Apache-2.0 + 'use strict'; const childProcess = require('child_process'); const { isLinux, getReport } = require('./process'); +const { LDD_PATH, readFile, readFileSync } = require('./filesystem'); + +let cachedFamilyFilesystem; +let cachedVersionFilesystem; const command = 'getconf GNU_LIBC_VERSION 2>&1 || true; ldd --version 2>&1 || true'; let commandOut = ''; @@ -36,6 +43,12 @@ const safeCommandSync = () => { */ const GLIBC = 'glibc'; +/** + * A Regexp constant to get the GLIBC Version. + * @type {string} + */ +const RE_GLIBC_VERSION = /LIBC[a-z0-9 \-).]*?(\d+\.\d+)/i; + /** * A String constant containing the value `musl`. * @type {string} @@ -69,6 +82,40 @@ const familyFromCommand = (out) => { return null; }; +const getFamilyFromLddContent = (content) => { + if (content.includes('musl')) { + return MUSL; + } + if (content.includes('GNU C Library')) { + return GLIBC; + } + return null; +}; + +const familyFromFilesystem = async () => { + if (cachedFamilyFilesystem !== undefined) { + return cachedFamilyFilesystem; + } + cachedFamilyFilesystem = null; + try { + const lddContent = await readFile(LDD_PATH); + cachedFamilyFilesystem = getFamilyFromLddContent(lddContent); + } catch (e) {} + return cachedFamilyFilesystem; +}; + +const familyFromFilesystemSync = () => { + if (cachedFamilyFilesystem !== undefined) { + return cachedFamilyFilesystem; + } + cachedFamilyFilesystem = null; + try { + const lddContent = readFileSync(LDD_PATH); + cachedFamilyFilesystem = getFamilyFromLddContent(lddContent); + } catch (e) {} + return cachedFamilyFilesystem; +}; + /** * Resolves with the libc family when it can be determined, `null` otherwise. * @returns {Promise} @@ -76,7 +123,10 @@ const familyFromCommand = (out) => { const family = async () => { let family = null; if (isLinux()) { - family = familyFromReport(); + family = await familyFromFilesystem(); + if (!family) { + family = familyFromReport(); + } if (!family) { const out = await safeCommand(); family = familyFromCommand(out); @@ -92,7 +142,10 @@ const family = async () => { const familySync = () => { let family = null; if (isLinux()) { - family = familyFromReport(); + family = familyFromFilesystemSync(); + if (!family) { + family = familyFromReport(); + } if (!family) { const out = safeCommandSync(); family = familyFromCommand(out); @@ -113,6 +166,36 @@ const isNonGlibcLinux = async () => isLinux() && await family() !== GLIBC; */ const isNonGlibcLinuxSync = () => isLinux() && familySync() !== GLIBC; +const versionFromFilesystem = async () => { + if (cachedVersionFilesystem !== undefined) { + return cachedVersionFilesystem; + } + cachedVersionFilesystem = null; + try { + const lddContent = await readFile(LDD_PATH); + const versionMatch = lddContent.match(RE_GLIBC_VERSION); + if (versionMatch) { + cachedVersionFilesystem = versionMatch[1]; + } + } catch (e) {} + return cachedVersionFilesystem; +}; + +const versionFromFilesystemSync = () => { + if (cachedVersionFilesystem !== undefined) { + return cachedVersionFilesystem; + } + cachedVersionFilesystem = null; + try { + const lddContent = readFileSync(LDD_PATH); + const versionMatch = lddContent.match(RE_GLIBC_VERSION); + if (versionMatch) { + cachedVersionFilesystem = versionMatch[1]; + } + } catch (e) {} + return cachedVersionFilesystem; +}; + const versionFromReport = () => { const report = getReport(); if (report.header && report.header.glibcVersionRuntime) { @@ -141,7 +224,10 @@ const versionFromCommand = (out) => { const version = async () => { let version = null; if (isLinux()) { - version = versionFromReport(); + version = await versionFromFilesystem(); + if (!version) { + version = versionFromReport(); + } if (!version) { const out = await safeCommand(); version = versionFromCommand(out); @@ -157,7 +243,10 @@ const version = async () => { const versionSync = () => { let version = null; if (isLinux()) { - version = versionFromReport(); + version = versionFromFilesystemSync(); + if (!version) { + version = versionFromReport(); + } if (!version) { const out = safeCommandSync(); version = versionFromCommand(out); diff --git a/node_modules/detect-libc/lib/process.js b/node_modules/detect-libc/lib/process.js index 8d5840f1..ee78ad26 100644 --- a/node_modules/detect-libc/lib/process.js +++ b/node_modules/detect-libc/lib/process.js @@ -1,3 +1,6 @@ +// Copyright 2017 Lovell Fuller and others. +// SPDX-License-Identifier: Apache-2.0 + 'use strict'; const isLinux = () => process.platform === 'linux'; @@ -6,9 +9,14 @@ let report = null; const getReport = () => { if (!report) { /* istanbul ignore next */ - report = isLinux() && process.report - ? process.report.getReport() - : {}; + if (isLinux() && process.report) { + const orig = process.report.excludeNetwork; + process.report.excludeNetwork = true; + report = process.report.getReport(); + process.report.excludeNetwork = orig; + } else { + report = {}; + } } return report; }; diff --git a/node_modules/detect-libc/package.json b/node_modules/detect-libc/package.json index aeb7cc1d..d5adec31 100644 --- a/node_modules/detect-libc/package.json +++ b/node_modules/detect-libc/package.json @@ -1,6 +1,6 @@ { "name": "detect-libc", - "version": "2.0.1", + "version": "2.0.3", "description": "Node.js module to detect the C standard library (libc) implementation family and version", "main": "lib/detect-libc.js", "files": [ @@ -8,7 +8,9 @@ "index.d.ts" ], "scripts": { - "test": "semistandard && nyc --reporter=lcov --check-coverage --branches=100 ava test/unit.js" + "test": "semistandard && nyc --reporter=text --check-coverage --branches=100 ava test/unit.js", + "bench": "node benchmark/detect-libc", + "bench:calls": "node benchmark/call-familySync.js && sleep 1 && node benchmark/call-isNonGlibcLinuxSync.js && sleep 1 && node benchmark/call-versionSync.js" }, "repository": { "type": "git", @@ -21,11 +23,13 @@ ], "author": "Lovell Fuller ", "contributors": [ - "Niklas Salmoukas " + "Niklas Salmoukas ", + "Vinícius Lourenço " ], "license": "Apache-2.0", "devDependencies": { "ava": "^2.4.0", + "benchmark": "^2.1.4", "nyc": "^15.1.0", "proxyquire": "^2.1.3", "semistandard": "^14.2.3" diff --git a/node_modules/minipass/LICENSE b/node_modules/minipass/LICENSE index bf1dece2..97f8e32e 100644 --- a/node_modules/minipass/LICENSE +++ b/node_modules/minipass/LICENSE @@ -1,6 +1,6 @@ The ISC License -Copyright (c) 2017-2022 npm, Inc., Isaac Z. Schlueter, and Contributors +Copyright (c) 2017-2023 npm, Inc., Isaac Z. Schlueter, and Contributors Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above diff --git a/node_modules/minipass/README.md b/node_modules/minipass/README.md index 2cde46c3..61088093 100644 --- a/node_modules/minipass/README.md +++ b/node_modules/minipass/README.md @@ -4,35 +4,37 @@ A _very_ minimal implementation of a [PassThrough stream](https://nodejs.org/api/stream.html#stream_class_stream_passthrough) [It's very -fast](https://docs.google.com/spreadsheets/d/1oObKSrVwLX_7Ut4Z6g3fZW-AX1j1-k6w-cDsrkaSbHM/edit#gid=0) +fast](https://docs.google.com/spreadsheets/d/1K_HR5oh3r80b8WVMWCPPjfuWXUgfkmhlX7FGI6JJ8tY/edit?usp=sharing) for objects, strings, and buffers. -Supports `pipe()`ing (including multi-`pipe()` and backpressure transmission), -buffering data until either a `data` event handler or `pipe()` is added (so -you don't lose the first chunk), and most other cases where PassThrough is -a good idea. +Supports `pipe()`ing (including multi-`pipe()` and backpressure +transmission), buffering data until either a `data` event handler +or `pipe()` is added (so you don't lose the first chunk), and +most other cases where PassThrough is a good idea. -There is a `read()` method, but it's much more efficient to consume data -from this stream via `'data'` events or by calling `pipe()` into some other -stream. Calling `read()` requires the buffer to be flattened in some -cases, which requires copying memory. +There is a `read()` method, but it's much more efficient to +consume data from this stream via `'data'` events or by calling +`pipe()` into some other stream. Calling `read()` requires the +buffer to be flattened in some cases, which requires copying +memory. -If you set `objectMode: true` in the options, then whatever is written will -be emitted. Otherwise, it'll do a minimal amount of Buffer copying to -ensure proper Streams semantics when `read(n)` is called. +If you set `objectMode: true` in the options, then whatever is +written will be emitted. Otherwise, it'll do a minimal amount of +Buffer copying to ensure proper Streams semantics when `read(n)` +is called. -`objectMode` can also be set by doing `stream.objectMode = true`, or by -writing any non-string/non-buffer data. `objectMode` cannot be set to -false once it is set. +`objectMode` can also be set by doing `stream.objectMode = true`, +or by writing any non-string/non-buffer data. `objectMode` cannot +be set to false once it is set. -This is not a `through` or `through2` stream. It doesn't transform the -data, it just passes it right through. If you want to transform the data, -extend the class, and override the `write()` method. Once you're done -transforming the data however you want, call `super.write()` with the -transform output. +This is not a `through` or `through2` stream. It doesn't +transform the data, it just passes it right through. If you want +to transform the data, extend the class, and override the +`write()` method. Once you're done transforming the data however +you want, call `super.write()` with the transform output. -For some examples of streams that extend Minipass in various ways, check -out: +For some examples of streams that extend Minipass in various +ways, check out: - [minizlib](http://npm.im/minizlib) - [fs-minipass](http://npm.im/fs-minipass) @@ -54,11 +56,11 @@ out: ## Differences from Node.js Streams -There are several things that make Minipass streams different from (and in -some ways superior to) Node.js core streams. +There are several things that make Minipass streams different +from (and in some ways superior to) Node.js core streams. -Please read these caveats if you are familiar with node-core streams and -intend to use Minipass streams in your programs. +Please read these caveats if you are familiar with node-core +streams and intend to use Minipass streams in your programs. You can avoid most of these differences entirely (for a very small performance penalty) by setting `{async: true}` in the @@ -66,28 +68,35 @@ constructor options. ### Timing -Minipass streams are designed to support synchronous use-cases. Thus, data -is emitted as soon as it is available, always. It is buffered until read, -but no longer. Another way to look at it is that Minipass streams are -exactly as synchronous as the logic that writes into them. +Minipass streams are designed to support synchronous use-cases. +Thus, data is emitted as soon as it is available, always. It is +buffered until read, but no longer. Another way to look at it is +that Minipass streams are exactly as synchronous as the logic +that writes into them. -This can be surprising if your code relies on `PassThrough.write()` always -providing data on the next tick rather than the current one, or being able -to call `resume()` and not have the entire buffer disappear immediately. +This can be surprising if your code relies on +`PassThrough.write()` always providing data on the next tick +rather than the current one, or being able to call `resume()` and +not have the entire buffer disappear immediately. -However, without this synchronicity guarantee, there would be no way for -Minipass to achieve the speeds it does, or support the synchronous use -cases that it does. Simply put, waiting takes time. +However, without this synchronicity guarantee, there would be no +way for Minipass to achieve the speeds it does, or support the +synchronous use cases that it does. Simply put, waiting takes +time. -This non-deferring approach makes Minipass streams much easier to reason -about, especially in the context of Promises and other flow-control -mechanisms. +This non-deferring approach makes Minipass streams much easier to +reason about, especially in the context of Promises and other +flow-control mechanisms. Example: ```js -const Minipass = require('minipass') -const stream = new Minipass({ async: true }) +// hybrid module, either works +import { Minipass } from 'minipass' +// or: +const { Minipass } = require('minipass') + +const stream = new Minipass() stream.on('data', () => console.log('data event')) console.log('before write') stream.write('hello') @@ -106,7 +115,11 @@ async mode either by setting `async: true` in the constructor options, or by setting `stream.async = true` later on. ```js -const Minipass = require('minipass') +// hybrid module, either works +import { Minipass } from 'minipass' +// or: +const { Minipass } = require('minipass') + const asyncStream = new Minipass({ async: true }) asyncStream.on('data', () => console.log('data event')) console.log('before write') @@ -119,10 +132,10 @@ console.log('after write') ``` Switching _out_ of async mode is unsafe, as it could cause data -corruption, and so is not enabled. Example: +corruption, and so is not enabled. Example: ```js -const Minipass = require('minipass') +import { Minipass } from 'minipass' const stream = new Minipass({ encoding: 'utf8' }) stream.on('data', chunk => console.log(chunk)) stream.async = true @@ -143,7 +156,7 @@ To avoid this problem, once set into async mode, any attempt to make the stream sync again will be ignored. ```js -const Minipass = require('minipass') +const { Minipass } = require('minipass') const stream = new Minipass({ encoding: 'utf8' }) stream.on('data', chunk => console.log(chunk)) stream.async = true @@ -161,33 +174,35 @@ console.log('after writes') ### No High/Low Water Marks -Node.js core streams will optimistically fill up a buffer, returning `true` -on all writes until the limit is hit, even if the data has nowhere to go. -Then, they will not attempt to draw more data in until the buffer size dips -below a minimum value. +Node.js core streams will optimistically fill up a buffer, +returning `true` on all writes until the limit is hit, even if +the data has nowhere to go. Then, they will not attempt to draw +more data in until the buffer size dips below a minimum value. -Minipass streams are much simpler. The `write()` method will return `true` -if the data has somewhere to go (which is to say, given the timing -guarantees, that the data is already there by the time `write()` returns). +Minipass streams are much simpler. The `write()` method will +return `true` if the data has somewhere to go (which is to say, +given the timing guarantees, that the data is already there by +the time `write()` returns). -If the data has nowhere to go, then `write()` returns false, and the data -sits in a buffer, to be drained out immediately as soon as anyone consumes -it. +If the data has nowhere to go, then `write()` returns false, and +the data sits in a buffer, to be drained out immediately as soon +as anyone consumes it. Since nothing is ever buffered unnecessarily, there is much less copying data, and less bookkeeping about buffer capacity levels. ### Hazards of Buffering (or: Why Minipass Is So Fast) -Since data written to a Minipass stream is immediately written all the way -through the pipeline, and `write()` always returns true/false based on -whether the data was fully flushed, backpressure is communicated -immediately to the upstream caller. This minimizes buffering. +Since data written to a Minipass stream is immediately written +all the way through the pipeline, and `write()` always returns +true/false based on whether the data was fully flushed, +backpressure is communicated immediately to the upstream caller. +This minimizes buffering. Consider this case: ```js -const {PassThrough} = require('stream') +const { PassThrough } = require('stream') const p1 = new PassThrough({ highWaterMark: 1024 }) const p2 = new PassThrough({ highWaterMark: 1024 }) const p3 = new PassThrough({ highWaterMark: 1024 }) @@ -210,14 +225,15 @@ p4.on('data', () => console.log('made it through')) p1.write(Buffer.alloc(2048)) // returns false ``` -Along the way, the data was buffered and deferred at each stage, and -multiple event deferrals happened, for an unblocked pipeline where it was -perfectly safe to write all the way through! +Along the way, the data was buffered and deferred at each stage, +and multiple event deferrals happened, for an unblocked pipeline +where it was perfectly safe to write all the way through! -Furthermore, setting a `highWaterMark` of `1024` might lead someone reading -the code to think an advisory maximum of 1KiB is being set for the -pipeline. However, the actual advisory buffering level is the _sum_ of -`highWaterMark` values, since each one has its own bucket. +Furthermore, setting a `highWaterMark` of `1024` might lead +someone reading the code to think an advisory maximum of 1KiB is +being set for the pipeline. However, the actual advisory +buffering level is the _sum_ of `highWaterMark` values, since +each one has its own bucket. Consider the Minipass case: @@ -242,47 +258,49 @@ m4.on('data', () => console.log('made it through')) m1.write(Buffer.alloc(2048)) // returns true ``` -It is extremely unlikely that you _don't_ want to buffer any data written, -or _ever_ buffer data that can be flushed all the way through. Neither -node-core streams nor Minipass ever fail to buffer written data, but -node-core streams do a lot of unnecessary buffering and pausing. +It is extremely unlikely that you _don't_ want to buffer any data +written, or _ever_ buffer data that can be flushed all the way +through. Neither node-core streams nor Minipass ever fail to +buffer written data, but node-core streams do a lot of +unnecessary buffering and pausing. -As always, the faster implementation is the one that does less stuff and -waits less time to do it. +As always, the faster implementation is the one that does less +stuff and waits less time to do it. ### Immediately emit `end` for empty streams (when not paused) -If a stream is not paused, and `end()` is called before writing any data -into it, then it will emit `end` immediately. +If a stream is not paused, and `end()` is called before writing +any data into it, then it will emit `end` immediately. -If you have logic that occurs on the `end` event which you don't want to -potentially happen immediately (for example, closing file descriptors, -moving on to the next entry in an archive parse stream, etc.) then be sure -to call `stream.pause()` on creation, and then `stream.resume()` once you -are ready to respond to the `end` event. +If you have logic that occurs on the `end` event which you don't +want to potentially happen immediately (for example, closing file +descriptors, moving on to the next entry in an archive parse +stream, etc.) then be sure to call `stream.pause()` on creation, +and then `stream.resume()` once you are ready to respond to the +`end` event. However, this is _usually_ not a problem because: ### Emit `end` When Asked -One hazard of immediately emitting `'end'` is that you may not yet have had -a chance to add a listener. In order to avoid this hazard, Minipass -streams safely re-emit the `'end'` event if a new listener is added after -`'end'` has been emitted. +One hazard of immediately emitting `'end'` is that you may not +yet have had a chance to add a listener. In order to avoid this +hazard, Minipass streams safely re-emit the `'end'` event if a +new listener is added after `'end'` has been emitted. -Ie, if you do `stream.on('end', someFunction)`, and the stream has already -emitted `end`, then it will call the handler right away. (You can think of -this somewhat like attaching a new `.then(fn)` to a previously-resolved -Promise.) +Ie, if you do `stream.on('end', someFunction)`, and the stream +has already emitted `end`, then it will call the handler right +away. (You can think of this somewhat like attaching a new +`.then(fn)` to a previously-resolved Promise.) -To prevent calling handlers multiple times who would not expect multiple -ends to occur, all listeners are removed from the `'end'` event whenever it -is emitted. +To prevent calling handlers multiple times who would not expect +multiple ends to occur, all listeners are removed from the +`'end'` event whenever it is emitted. ### Emit `error` When Asked The most recent error object passed to the `'error'` event is -stored on the stream. If a new `'error'` event handler is added, +stored on the stream. If a new `'error'` event handler is added, and an error was previously emitted, then the event handler will be called immediately (or on `process.nextTick` in the case of async streams). @@ -302,10 +320,11 @@ t.pipe(dest2) t.write('foo') // goes to both destinations ``` -Since Minipass streams _immediately_ process any pending data through the -pipeline when a new pipe destination is added, this can have surprising -effects, especially when a stream comes in from some other function and may -or may not have data in its buffer. +Since Minipass streams _immediately_ process any pending data +through the pipeline when a new pipe destination is added, this +can have surprising effects, especially when a stream comes in +from some other function and may or may not have data in its +buffer. ```js // WARNING! WILL LOSE DATA! @@ -315,8 +334,8 @@ src.pipe(dest1) // 'foo' chunk flows to dest1 immediately, and is gone src.pipe(dest2) // gets nothing! ``` -One solution is to create a dedicated tee-stream junction that pipes to -both locations, and then pipe to _that_ instead. +One solution is to create a dedicated tee-stream junction that +pipes to both locations, and then pipe to _that_ instead. ```js // Safe example: tee to both places @@ -328,9 +347,9 @@ tee.pipe(dest2) src.pipe(tee) // tee gets 'foo', pipes to both locations ``` -The same caveat applies to `on('data')` event listeners. The first one -added will _immediately_ receive all of the data, leaving nothing for the -second: +The same caveat applies to `on('data')` event listeners. The +first one added will _immediately_ receive all of the data, +leaving nothing for the second: ```js // WARNING! WILL LOSE DATA! @@ -354,18 +373,18 @@ src.pipe(tee) All of the hazards in this section are avoided by setting `{ async: true }` in the Minipass constructor, or by setting -`stream.async = true` afterwards. Note that this does add some +`stream.async = true` afterwards. Note that this does add some overhead, so should only be done in cases where you are willing to lose a bit of performance in order to avoid having to refactor program logic. ## USAGE -It's a stream! Use it like a stream and it'll most likely do what you -want. +It's a stream! Use it like a stream and it'll most likely do what +you want. ```js -const Minipass = require('minipass') +import { Minipass } from 'minipass' const mp = new Minipass(options) // optional: { encoding, objectMode } mp.write('foo') mp.pipe(someOtherStream) @@ -374,145 +393,165 @@ mp.end('bar') ### OPTIONS -* `encoding` How would you like the data coming _out_ of the stream to be - encoded? Accepts any values that can be passed to `Buffer.toString()`. -* `objectMode` Emit data exactly as it comes in. This will be flipped on - by default if you write() something other than a string or Buffer at any - point. Setting `objectMode: true` will prevent setting any encoding - value. -* `async` Defaults to `false`. Set to `true` to defer data - emission until next tick. This reduces performance slightly, +- `encoding` How would you like the data coming _out_ of the + stream to be encoded? Accepts any values that can be passed to + `Buffer.toString()`. +- `objectMode` Emit data exactly as it comes in. This will be + flipped on by default if you write() something other than a + string or Buffer at any point. Setting `objectMode: true` will + prevent setting any encoding value. +- `async` Defaults to `false`. Set to `true` to defer data + emission until next tick. This reduces performance slightly, but makes Minipass streams use timing behavior closer to Node - core streams. See [Timing](#timing) for more details. + core streams. See [Timing](#timing) for more details. +- `signal` An `AbortSignal` that will cause the stream to unhook + itself from everything and become as inert as possible. Note + that providing a `signal` parameter will make `'error'` events + no longer throw if they are unhandled, but they will still be + emitted to handlers if any are attached. ### API -Implements the user-facing portions of Node.js's `Readable` and `Writable` -streams. +Implements the user-facing portions of Node.js's `Readable` and +`Writable` streams. ### Methods -* `write(chunk, [encoding], [callback])` - Put data in. (Note that, in the - base Minipass class, the same data will come out.) Returns `false` if - the stream will buffer the next write, or true if it's still in "flowing" - mode. -* `end([chunk, [encoding]], [callback])` - Signal that you have no more - data to write. This will queue an `end` event to be fired when all the - data has been consumed. -* `setEncoding(encoding)` - Set the encoding for data coming of the stream. - This can only be done once. -* `pause()` - No more data for a while, please. This also prevents `end` - from being emitted for empty streams until the stream is resumed. -* `resume()` - Resume the stream. If there's data in the buffer, it is all - discarded. Any buffered events are immediately emitted. -* `pipe(dest)` - Send all output to the stream provided. When +- `write(chunk, [encoding], [callback])` - Put data in. (Note + that, in the base Minipass class, the same data will come out.) + Returns `false` if the stream will buffer the next write, or + true if it's still in "flowing" mode. +- `end([chunk, [encoding]], [callback])` - Signal that you have + no more data to write. This will queue an `end` event to be + fired when all the data has been consumed. +- `setEncoding(encoding)` - Set the encoding for data coming of + the stream. This can only be done once. +- `pause()` - No more data for a while, please. This also + prevents `end` from being emitted for empty streams until the + stream is resumed. +- `resume()` - Resume the stream. If there's data in the buffer, + it is all discarded. Any buffered events are immediately + emitted. +- `pipe(dest)` - Send all output to the stream provided. When data is emitted, it is immediately written to any and all pipe - destinations. (Or written on next tick in `async` mode.) -* `unpipe(dest)` - Stop piping to the destination stream. This - is immediate, meaning that any asynchronously queued data will + destinations. (Or written on next tick in `async` mode.) +- `unpipe(dest)` - Stop piping to the destination stream. This is + immediate, meaning that any asynchronously queued data will _not_ make it to the destination when running in `async` mode. - * `options.end` - Boolean, end the destination stream when - the source stream ends. Default `true`. - * `options.proxyErrors` - Boolean, proxy `error` events from - the source stream to the destination stream. Note that - errors are _not_ proxied after the pipeline terminates, - either due to the source emitting `'end'` or manually - unpiping with `src.unpipe(dest)`. Default `false`. -* `on(ev, fn)`, `emit(ev, fn)` - Minipass streams are EventEmitters. Some - events are given special treatment, however. (See below under "events".) -* `promise()` - Returns a Promise that resolves when the stream emits - `end`, or rejects if the stream emits `error`. -* `collect()` - Return a Promise that resolves on `end` with an array - containing each chunk of data that was emitted, or rejects if the stream - emits `error`. Note that this consumes the stream data. -* `concat()` - Same as `collect()`, but concatenates the data into a single - Buffer object. Will reject the returned promise if the stream is in - objectMode, or if it goes into objectMode by the end of the data. -* `read(n)` - Consume `n` bytes of data out of the buffer. If `n` is not - provided, then consume all of it. If `n` bytes are not available, then - it returns null. **Note** consuming streams in this way is less - efficient, and can lead to unnecessary Buffer copying. -* `destroy([er])` - Destroy the stream. If an error is provided, then an - `'error'` event is emitted. If the stream has a `close()` method, and - has not emitted a `'close'` event yet, then `stream.close()` will be - called. Any Promises returned by `.promise()`, `.collect()` or - `.concat()` will be rejected. After being destroyed, writing to the - stream will emit an error. No more data will be emitted if the stream is - destroyed, even if it was previously buffered. + - `options.end` - Boolean, end the destination stream when the + source stream ends. Default `true`. + - `options.proxyErrors` - Boolean, proxy `error` events from + the source stream to the destination stream. Note that errors + are _not_ proxied after the pipeline terminates, either due + to the source emitting `'end'` or manually unpiping with + `src.unpipe(dest)`. Default `false`. +- `on(ev, fn)`, `emit(ev, fn)` - Minipass streams are + EventEmitters. Some events are given special treatment, + however. (See below under "events".) +- `promise()` - Returns a Promise that resolves when the stream + emits `end`, or rejects if the stream emits `error`. +- `collect()` - Return a Promise that resolves on `end` with an + array containing each chunk of data that was emitted, or + rejects if the stream emits `error`. Note that this consumes + the stream data. +- `concat()` - Same as `collect()`, but concatenates the data + into a single Buffer object. Will reject the returned promise + if the stream is in objectMode, or if it goes into objectMode + by the end of the data. +- `read(n)` - Consume `n` bytes of data out of the buffer. If `n` + is not provided, then consume all of it. If `n` bytes are not + available, then it returns null. **Note** consuming streams in + this way is less efficient, and can lead to unnecessary Buffer + copying. +- `destroy([er])` - Destroy the stream. If an error is provided, + then an `'error'` event is emitted. If the stream has a + `close()` method, and has not emitted a `'close'` event yet, + then `stream.close()` will be called. Any Promises returned by + `.promise()`, `.collect()` or `.concat()` will be rejected. + After being destroyed, writing to the stream will emit an + error. No more data will be emitted if the stream is destroyed, + even if it was previously buffered. ### Properties -* `bufferLength` Read-only. Total number of bytes buffered, or in the case - of objectMode, the total number of objects. -* `encoding` The encoding that has been set. (Setting this is equivalent - to calling `setEncoding(enc)` and has the same prohibition against - setting multiple times.) -* `flowing` Read-only. Boolean indicating whether a chunk written to the - stream will be immediately emitted. -* `emittedEnd` Read-only. Boolean indicating whether the end-ish events - (ie, `end`, `prefinish`, `finish`) have been emitted. Note that - listening on any end-ish event will immediateyl re-emit it if it has - already been emitted. -* `writable` Whether the stream is writable. Default `true`. Set to - `false` when `end()` -* `readable` Whether the stream is readable. Default `true`. -* `buffer` A [yallist](http://npm.im/yallist) linked list of chunks written - to the stream that have not yet been emitted. (It's probably a bad idea - to mess with this.) -* `pipes` A [yallist](http://npm.im/yallist) linked list of streams that - this stream is piping into. (It's probably a bad idea to mess with - this.) -* `destroyed` A getter that indicates whether the stream was destroyed. -* `paused` True if the stream has been explicitly paused, otherwise false. -* `objectMode` Indicates whether the stream is in `objectMode`. Once set - to `true`, it cannot be set to `false`. +- `bufferLength` Read-only. Total number of bytes buffered, or in + the case of objectMode, the total number of objects. +- `encoding` The encoding that has been set. (Setting this is + equivalent to calling `setEncoding(enc)` and has the same + prohibition against setting multiple times.) +- `flowing` Read-only. Boolean indicating whether a chunk written + to the stream will be immediately emitted. +- `emittedEnd` Read-only. Boolean indicating whether the end-ish + events (ie, `end`, `prefinish`, `finish`) have been emitted. + Note that listening on any end-ish event will immediateyl + re-emit it if it has already been emitted. +- `writable` Whether the stream is writable. Default `true`. Set + to `false` when `end()` +- `readable` Whether the stream is readable. Default `true`. +- `pipes` An array of Pipe objects referencing streams that this + stream is piping into. +- `destroyed` A getter that indicates whether the stream was + destroyed. +- `paused` True if the stream has been explicitly paused, + otherwise false. +- `objectMode` Indicates whether the stream is in `objectMode`. + Once set to `true`, it cannot be set to `false`. +- `aborted` Readonly property set when the `AbortSignal` + dispatches an `abort` event. ### Events -* `data` Emitted when there's data to read. Argument is the data to read. - This is never emitted while not flowing. If a listener is attached, that - will resume the stream. -* `end` Emitted when there's no more data to read. This will be emitted - immediately for empty streams when `end()` is called. If a listener is - attached, and `end` was already emitted, then it will be emitted again. - All listeners are removed when `end` is emitted. -* `prefinish` An end-ish event that follows the same logic as `end` and is - emitted in the same conditions where `end` is emitted. Emitted after - `'end'`. -* `finish` An end-ish event that follows the same logic as `end` and is - emitted in the same conditions where `end` is emitted. Emitted after - `'prefinish'`. -* `close` An indication that an underlying resource has been released. - Minipass does not emit this event, but will defer it until after `end` - has been emitted, since it throws off some stream libraries otherwise. -* `drain` Emitted when the internal buffer empties, and it is again - suitable to `write()` into the stream. -* `readable` Emitted when data is buffered and ready to be read by a - consumer. -* `resume` Emitted when stream changes state from buffering to flowing - mode. (Ie, when `resume` is called, `pipe` is called, or a `data` event - listener is added.) +- `data` Emitted when there's data to read. Argument is the data + to read. This is never emitted while not flowing. If a listener + is attached, that will resume the stream. +- `end` Emitted when there's no more data to read. This will be + emitted immediately for empty streams when `end()` is called. + If a listener is attached, and `end` was already emitted, then + it will be emitted again. All listeners are removed when `end` + is emitted. +- `prefinish` An end-ish event that follows the same logic as + `end` and is emitted in the same conditions where `end` is + emitted. Emitted after `'end'`. +- `finish` An end-ish event that follows the same logic as `end` + and is emitted in the same conditions where `end` is emitted. + Emitted after `'prefinish'`. +- `close` An indication that an underlying resource has been + released. Minipass does not emit this event, but will defer it + until after `end` has been emitted, since it throws off some + stream libraries otherwise. +- `drain` Emitted when the internal buffer empties, and it is + again suitable to `write()` into the stream. +- `readable` Emitted when data is buffered and ready to be read + by a consumer. +- `resume` Emitted when stream changes state from buffering to + flowing mode. (Ie, when `resume` is called, `pipe` is called, + or a `data` event listener is added.) ### Static Methods -* `Minipass.isStream(stream)` Returns `true` if the argument is a stream, - and false otherwise. To be considered a stream, the object must be - either an instance of Minipass, or an EventEmitter that has either a - `pipe()` method, or both `write()` and `end()` methods. (Pretty much any - stream in node-land will return `true` for this.) +- `Minipass.isStream(stream)` Returns `true` if the argument is a + stream, and false otherwise. To be considered a stream, the + object must be either an instance of Minipass, or an + EventEmitter that has either a `pipe()` method, or both + `write()` and `end()` methods. (Pretty much any stream in + node-land will return `true` for this.) ## EXAMPLES -Here are some examples of things you can do with Minipass streams. +Here are some examples of things you can do with Minipass +streams. ### simple "are you done yet" promise ```js -mp.promise().then(() => { - // stream is finished -}, er => { - // stream emitted an error -}) +mp.promise().then( + () => { + // stream is finished + }, + er => { + // stream emitted an error + } +) ``` ### collecting @@ -531,9 +570,9 @@ mp.collect().then(all => { ### collecting into a single blob -This is a bit slower because it concatenates the data into one chunk for -you, but if you're going to do it yourself anyway, it's convenient this -way: +This is a bit slower because it concatenates the data into one +chunk for you, but if you're going to do it yourself anyway, it's +convenient this way: ```js mp.concat().then(onebigchunk => { @@ -544,17 +583,18 @@ mp.concat().then(onebigchunk => { ### iteration -You can iterate over streams synchronously or asynchronously in platforms -that support it. +You can iterate over streams synchronously or asynchronously in +platforms that support it. -Synchronous iteration will end when the currently available data is -consumed, even if the `end` event has not been reached. In string and -buffer mode, the data is concatenated, so unless multiple writes are -occurring in the same tick as the `read()`, sync iteration loops will -generally only have a single iteration. +Synchronous iteration will end when the currently available data +is consumed, even if the `end` event has not been reached. In +string and buffer mode, the data is concatenated, so unless +multiple writes are occurring in the same tick as the `read()`, +sync iteration loops will generally only have a single iteration. -To consume chunks in this way exactly as they have been written, with no -flattening, create the stream with the `{ objectMode: true }` option. +To consume chunks in this way exactly as they have been written, +with no flattening, create the stream with the `{ objectMode: +true }` option. ```js const mp = new Minipass({ objectMode: true }) @@ -587,8 +627,7 @@ const mp = new Minipass({ encoding: 'utf8' }) // some source of some data let i = 5 const inter = setInterval(() => { - if (i-- > 0) - mp.write(Buffer.from('foo\n', 'utf8')) + if (i-- > 0) mp.write(Buffer.from('foo\n', 'utf8')) else { mp.end() clearInterval(inter) @@ -596,7 +635,7 @@ const inter = setInterval(() => { }, 100) // consume the data with asynchronous iteration -async function consume () { +async function consume() { for await (let chunk of mp) { console.log(chunk) } @@ -611,11 +650,11 @@ consume().then(res => console.log(res)) ```js class Logger extends Minipass { - write (chunk, encoding, callback) { + write(chunk, encoding, callback) { console.log('WRITE', chunk, encoding) return super.write(chunk, encoding, callback) } - end (chunk, encoding, callback) { + end(chunk, encoding, callback) { console.log('END', chunk, encoding) return super.end(chunk, encoding, callback) } @@ -629,21 +668,23 @@ someSource.pipe(new Logger()).pipe(someDest) ```js // js classes are fun someSource - .pipe(new (class extends Minipass { - emit (ev, ...data) { - // let's also log events, because debugging some weird thing - console.log('EMIT', ev) - return super.emit(ev, ...data) - } - write (chunk, encoding, callback) { - console.log('WRITE', chunk, encoding) - return super.write(chunk, encoding, callback) - } - end (chunk, encoding, callback) { - console.log('END', chunk, encoding) - return super.end(chunk, encoding, callback) - } - })) + .pipe( + new (class extends Minipass { + emit(ev, ...data) { + // let's also log events, because debugging some weird thing + console.log('EMIT', ev) + return super.emit(ev, ...data) + } + write(chunk, encoding, callback) { + console.log('WRITE', chunk, encoding) + return super.write(chunk, encoding, callback) + } + end(chunk, encoding, callback) { + console.log('END', chunk, encoding) + return super.end(chunk, encoding, callback) + } + })() + ) .pipe(someDest) ``` @@ -651,7 +692,7 @@ someSource ```js class SlowEnd extends Minipass { - emit (ev, ...args) { + emit(ev, ...args) { if (ev === 'end') { console.log('going to end, hold on a sec') setTimeout(() => { @@ -669,7 +710,7 @@ class SlowEnd extends Minipass { ```js class NDJSONEncode extends Minipass { - write (obj, cb) { + write(obj, cb) { try { // JSON.stringify can throw, emit an error on that return super.write(JSON.stringify(obj) + '\n', 'utf8', cb) @@ -677,7 +718,7 @@ class NDJSONEncode extends Minipass { this.emit('error', er) } } - end (obj, cb) { + end(obj, cb) { if (typeof obj === 'function') { cb = obj obj = undefined @@ -704,7 +745,7 @@ class NDJSONDecode extends Minipass { typeof encoding === 'string' && encoding !== 'utf8') { chunk = Buffer.from(chunk, encoding).toString() - } else if (Buffer.isBuffer(chunk)) + } else if (Buffer.isBuffer(chunk)) { chunk = chunk.toString() } if (typeof encoding === 'function') { diff --git a/node_modules/minipass/index.d.ts b/node_modules/minipass/index.d.ts index f68ce8a2..86851f96 100644 --- a/node_modules/minipass/index.d.ts +++ b/node_modules/minipass/index.d.ts @@ -6,56 +6,62 @@ import { EventEmitter } from 'events' import { Stream } from 'stream' -declare namespace Minipass { - type Encoding = BufferEncoding | 'buffer' | null +export namespace Minipass { + export type Encoding = BufferEncoding | 'buffer' | null - interface Writable extends EventEmitter { + export interface Writable extends EventEmitter { end(): any write(chunk: any, ...args: any[]): any } - interface Readable extends EventEmitter { + export interface Readable extends EventEmitter { pause(): any resume(): any pipe(): any } - type DualIterable = Iterable & AsyncIterable + export type DualIterable = Iterable & AsyncIterable - type ContiguousData = Buffer | ArrayBufferLike | ArrayBufferView | string + export type ContiguousData = + | Buffer + | ArrayBufferLike + | ArrayBufferView + | string - type BufferOrString = Buffer | string + export type BufferOrString = Buffer | string - interface StringOptions { + export interface SharedOptions { + async?: boolean + signal?: AbortSignal + } + + export interface StringOptions extends SharedOptions { encoding: BufferEncoding objectMode?: boolean - async?: boolean } - interface BufferOptions { + export interface BufferOptions extends SharedOptions { encoding?: null | 'buffer' objectMode?: boolean - async?: boolean } - interface ObjectModeOptions { + export interface ObjectModeOptions extends SharedOptions { objectMode: true - async?: boolean } - interface PipeOptions { + export interface PipeOptions { end?: boolean proxyErrors?: boolean } - type Options = T extends string + export type Options = T extends string ? StringOptions : T extends Buffer ? BufferOptions : ObjectModeOptions } -declare class Minipass< +export class Minipass< RType extends any = Buffer, WType extends any = RType extends Minipass.BufferOrString ? Minipass.ContiguousData @@ -70,6 +76,7 @@ declare class Minipass< readonly flowing: boolean readonly writable: boolean readonly readable: boolean + readonly aborted: boolean readonly paused: boolean readonly emittedEnd: boolean readonly destroyed: boolean @@ -140,8 +147,6 @@ declare class Minipass< listener: () => any ): this - [Symbol.iterator](): Iterator - [Symbol.asyncIterator](): AsyncIterator + [Symbol.iterator](): Generator + [Symbol.asyncIterator](): AsyncGenerator } - -export = Minipass diff --git a/node_modules/minipass/index.js b/node_modules/minipass/index.js index d5003ed9..ed07c17a 100644 --- a/node_modules/minipass/index.js +++ b/node_modules/minipass/index.js @@ -1,11 +1,15 @@ 'use strict' -const proc = typeof process === 'object' && process ? process : { - stdout: null, - stderr: null, -} +const proc = + typeof process === 'object' && process + ? process + : { + stdout: null, + stderr: null, + } const EE = require('events') const Stream = require('stream') -const SD = require('string_decoder').StringDecoder +const stringdecoder = require('string_decoder') +const SD = stringdecoder.StringDecoder const EOF = Symbol('EOF') const MAYBE_EMIT_END = Symbol('maybeEmitEnd') @@ -27,85 +31,85 @@ const BUFFERLENGTH = Symbol('bufferLength') const BUFFERPUSH = Symbol('bufferPush') const BUFFERSHIFT = Symbol('bufferShift') const OBJECTMODE = Symbol('objectMode') +// internal event when stream is destroyed const DESTROYED = Symbol('destroyed') +// internal event when stream has an error +const ERROR = Symbol('error') const EMITDATA = Symbol('emitData') const EMITEND = Symbol('emitEnd') const EMITEND2 = Symbol('emitEnd2') const ASYNC = Symbol('async') +const ABORT = Symbol('abort') +const ABORTED = Symbol('aborted') +const SIGNAL = Symbol('signal') const defer = fn => Promise.resolve().then(fn) // TODO remove when Node v8 support drops -const doIter = global._MP_NO_ITERATOR_SYMBOLS_ !== '1' -const ASYNCITERATOR = doIter && Symbol.asyncIterator - || Symbol('asyncIterator not implemented') -const ITERATOR = doIter && Symbol.iterator - || Symbol('iterator not implemented') +const doIter = global._MP_NO_ITERATOR_SYMBOLS_ !== '1' +const ASYNCITERATOR = + (doIter && Symbol.asyncIterator) || Symbol('asyncIterator not implemented') +const ITERATOR = + (doIter && Symbol.iterator) || Symbol('iterator not implemented') // events that mean 'the stream is over' // these are treated specially, and re-emitted // if they are listened for after emitting. -const isEndish = ev => - ev === 'end' || - ev === 'finish' || - ev === 'prefinish' +const isEndish = ev => ev === 'end' || ev === 'finish' || ev === 'prefinish' -const isArrayBuffer = b => b instanceof ArrayBuffer || - typeof b === 'object' && - b.constructor && - b.constructor.name === 'ArrayBuffer' && - b.byteLength >= 0 +const isArrayBuffer = b => + b instanceof ArrayBuffer || + (typeof b === 'object' && + b.constructor && + b.constructor.name === 'ArrayBuffer' && + b.byteLength >= 0) const isArrayBufferView = b => !Buffer.isBuffer(b) && ArrayBuffer.isView(b) class Pipe { - constructor (src, dest, opts) { + constructor(src, dest, opts) { this.src = src this.dest = dest this.opts = opts this.ondrain = () => src[RESUME]() dest.on('drain', this.ondrain) } - unpipe () { + unpipe() { this.dest.removeListener('drain', this.ondrain) } // istanbul ignore next - only here for the prototype - proxyErrors () {} - end () { + proxyErrors() {} + end() { this.unpipe() - if (this.opts.end) - this.dest.end() + if (this.opts.end) this.dest.end() } } class PipeProxyErrors extends Pipe { - unpipe () { + unpipe() { this.src.removeListener('error', this.proxyErrors) super.unpipe() } - constructor (src, dest, opts) { + constructor(src, dest, opts) { super(src, dest, opts) this.proxyErrors = er => dest.emit('error', er) src.on('error', this.proxyErrors) } } -module.exports = class Minipass extends Stream { - constructor (options) { +class Minipass extends Stream { + constructor(options) { super() this[FLOWING] = false // whether we're explicitly paused this[PAUSED] = false this[PIPES] = [] this[BUFFER] = [] - this[OBJECTMODE] = options && options.objectMode || false - if (this[OBJECTMODE]) - this[ENCODING] = null - else - this[ENCODING] = options && options.encoding || null - if (this[ENCODING] === 'buffer') - this[ENCODING] = null - this[ASYNC] = options && !!options.async || false + this[OBJECTMODE] = (options && options.objectMode) || false + if (this[OBJECTMODE]) this[ENCODING] = null + else this[ENCODING] = (options && options.encoding) || null + if (this[ENCODING] === 'buffer') this[ENCODING] = null + this[ASYNC] = (options && !!options.async) || false this[DECODER] = this[ENCODING] ? new SD(this[ENCODING]) : null this[EOF] = false this[EMITTED_END] = false @@ -122,17 +126,31 @@ module.exports = class Minipass extends Stream { if (options && options.debugExposePipes === true) { Object.defineProperty(this, 'pipes', { get: () => this[PIPES] }) } + this[SIGNAL] = options && options.signal + this[ABORTED] = false + if (this[SIGNAL]) { + this[SIGNAL].addEventListener('abort', () => this[ABORT]()) + if (this[SIGNAL].aborted) { + this[ABORT]() + } + } } - get bufferLength () { return this[BUFFERLENGTH] } + get bufferLength() { + return this[BUFFERLENGTH] + } - get encoding () { return this[ENCODING] } - set encoding (enc) { - if (this[OBJECTMODE]) - throw new Error('cannot set encoding in objectMode') + get encoding() { + return this[ENCODING] + } + set encoding(enc) { + if (this[OBJECTMODE]) throw new Error('cannot set encoding in objectMode') - if (this[ENCODING] && enc !== this[ENCODING] && - (this[DECODER] && this[DECODER].lastNeed || this[BUFFERLENGTH])) + if ( + this[ENCODING] && + enc !== this[ENCODING] && + ((this[DECODER] && this[DECODER].lastNeed) || this[BUFFERLENGTH]) + ) throw new Error('cannot change encoding') if (this[ENCODING] !== enc) { @@ -144,33 +162,54 @@ module.exports = class Minipass extends Stream { this[ENCODING] = enc } - setEncoding (enc) { + setEncoding(enc) { this.encoding = enc } - get objectMode () { return this[OBJECTMODE] } - set objectMode (om) { this[OBJECTMODE] = this[OBJECTMODE] || !!om } + get objectMode() { + return this[OBJECTMODE] + } + set objectMode(om) { + this[OBJECTMODE] = this[OBJECTMODE] || !!om + } + + get ['async']() { + return this[ASYNC] + } + set ['async'](a) { + this[ASYNC] = this[ASYNC] || !!a + } + + // drop everything and get out of the flow completely + [ABORT]() { + this[ABORTED] = true + this.emit('abort', this[SIGNAL].reason) + this.destroy(this[SIGNAL].reason) + } - get ['async'] () { return this[ASYNC] } - set ['async'] (a) { this[ASYNC] = this[ASYNC] || !!a } + get aborted() { + return this[ABORTED] + } + set aborted(_) {} - write (chunk, encoding, cb) { - if (this[EOF]) - throw new Error('write after end') + write(chunk, encoding, cb) { + if (this[ABORTED]) return false + if (this[EOF]) throw new Error('write after end') if (this[DESTROYED]) { - this.emit('error', Object.assign( - new Error('Cannot call write after a stream was destroyed'), - { code: 'ERR_STREAM_DESTROYED' } - )) + this.emit( + 'error', + Object.assign( + new Error('Cannot call write after a stream was destroyed'), + { code: 'ERR_STREAM_DESTROYED' } + ) + ) return true } - if (typeof encoding === 'function') - cb = encoding, encoding = 'utf8' + if (typeof encoding === 'function') (cb = encoding), (encoding = 'utf8') - if (!encoding) - encoding = 'utf8' + if (!encoding) encoding = 'utf8' const fn = this[ASYNC] ? defer : f => f() @@ -181,8 +220,7 @@ module.exports = class Minipass extends Stream { if (!this[OBJECTMODE] && !Buffer.isBuffer(chunk)) { if (isArrayBufferView(chunk)) chunk = Buffer.from(chunk.buffer, chunk.byteOffset, chunk.byteLength) - else if (isArrayBuffer(chunk)) - chunk = Buffer.from(chunk) + else if (isArrayBuffer(chunk)) chunk = Buffer.from(chunk) else if (typeof chunk !== 'string') // use the setter so we throw if we have encoding set this.objectMode = true @@ -192,19 +230,14 @@ module.exports = class Minipass extends Stream { // this yields better performance, fewer checks later. if (this[OBJECTMODE]) { /* istanbul ignore if - maybe impossible? */ - if (this.flowing && this[BUFFERLENGTH] !== 0) - this[FLUSH](true) + if (this.flowing && this[BUFFERLENGTH] !== 0) this[FLUSH](true) - if (this.flowing) - this.emit('data', chunk) - else - this[BUFFERPUSH](chunk) + if (this.flowing) this.emit('data', chunk) + else this[BUFFERPUSH](chunk) - if (this[BUFFERLENGTH] !== 0) - this.emit('readable') + if (this[BUFFERLENGTH] !== 0) this.emit('readable') - if (cb) - fn(cb) + if (cb) fn(cb) return this.flowing } @@ -212,18 +245,18 @@ module.exports = class Minipass extends Stream { // at this point the chunk is a buffer or string // don't buffer it up or send it to the decoder if (!chunk.length) { - if (this[BUFFERLENGTH] !== 0) - this.emit('readable') - if (cb) - fn(cb) + if (this[BUFFERLENGTH] !== 0) this.emit('readable') + if (cb) fn(cb) return this.flowing } // fast-path writing strings of same encoding to a stream with // an empty buffer, skipping the buffer/decoder dance - if (typeof chunk === 'string' && - // unless it is a string already ready for us to use - !(encoding === this[ENCODING] && !this[DECODER].lastNeed)) { + if ( + typeof chunk === 'string' && + // unless it is a string already ready for us to use + !(encoding === this[ENCODING] && !this[DECODER].lastNeed) + ) { chunk = Buffer.from(chunk, encoding) } @@ -231,40 +264,31 @@ module.exports = class Minipass extends Stream { chunk = this[DECODER].write(chunk) // Note: flushing CAN potentially switch us into not-flowing mode - if (this.flowing && this[BUFFERLENGTH] !== 0) - this[FLUSH](true) + if (this.flowing && this[BUFFERLENGTH] !== 0) this[FLUSH](true) - if (this.flowing) - this.emit('data', chunk) - else - this[BUFFERPUSH](chunk) + if (this.flowing) this.emit('data', chunk) + else this[BUFFERPUSH](chunk) - if (this[BUFFERLENGTH] !== 0) - this.emit('readable') + if (this[BUFFERLENGTH] !== 0) this.emit('readable') - if (cb) - fn(cb) + if (cb) fn(cb) return this.flowing } - read (n) { - if (this[DESTROYED]) - return null + read(n) { + if (this[DESTROYED]) return null if (this[BUFFERLENGTH] === 0 || n === 0 || n > this[BUFFERLENGTH]) { this[MAYBE_EMIT_END]() return null } - if (this[OBJECTMODE]) - n = null + if (this[OBJECTMODE]) n = null if (this[BUFFER].length > 1 && !this[OBJECTMODE]) { - if (this.encoding) - this[BUFFER] = [this[BUFFER].join('')] - else - this[BUFFER] = [Buffer.concat(this[BUFFER], this[BUFFERLENGTH])] + if (this.encoding) this[BUFFER] = [this[BUFFER].join('')] + else this[BUFFER] = [Buffer.concat(this[BUFFER], this[BUFFERLENGTH])] } const ret = this[READ](n || null, this[BUFFER][0]) @@ -272,9 +296,8 @@ module.exports = class Minipass extends Stream { return ret } - [READ] (n, chunk) { - if (n === chunk.length || n === null) - this[BUFFERSHIFT]() + [READ](n, chunk) { + if (n === chunk.length || n === null) this[BUFFERSHIFT]() else { this[BUFFER][0] = chunk.slice(n) chunk = chunk.slice(0, n) @@ -283,21 +306,16 @@ module.exports = class Minipass extends Stream { this.emit('data', chunk) - if (!this[BUFFER].length && !this[EOF]) - this.emit('drain') + if (!this[BUFFER].length && !this[EOF]) this.emit('drain') return chunk } - end (chunk, encoding, cb) { - if (typeof chunk === 'function') - cb = chunk, chunk = null - if (typeof encoding === 'function') - cb = encoding, encoding = 'utf8' - if (chunk) - this.write(chunk, encoding) - if (cb) - this.once('end', cb) + end(chunk, encoding, cb) { + if (typeof chunk === 'function') (cb = chunk), (chunk = null) + if (typeof encoding === 'function') (cb = encoding), (encoding = 'utf8') + if (chunk) this.write(chunk, encoding) + if (cb) this.once('end', cb) this[EOF] = true this.writable = false @@ -305,106 +323,92 @@ module.exports = class Minipass extends Stream { // even if we're not reading. // we'll re-emit if a new 'end' listener is added anyway. // This makes MP more suitable to write-only use cases. - if (this.flowing || !this[PAUSED]) - this[MAYBE_EMIT_END]() + if (this.flowing || !this[PAUSED]) this[MAYBE_EMIT_END]() return this } // don't let the internal resume be overwritten - [RESUME] () { - if (this[DESTROYED]) - return + [RESUME]() { + if (this[DESTROYED]) return this[PAUSED] = false this[FLOWING] = true this.emit('resume') - if (this[BUFFER].length) - this[FLUSH]() - else if (this[EOF]) - this[MAYBE_EMIT_END]() - else - this.emit('drain') + if (this[BUFFER].length) this[FLUSH]() + else if (this[EOF]) this[MAYBE_EMIT_END]() + else this.emit('drain') } - resume () { + resume() { return this[RESUME]() } - pause () { + pause() { this[FLOWING] = false this[PAUSED] = true } - get destroyed () { + get destroyed() { return this[DESTROYED] } - get flowing () { + get flowing() { return this[FLOWING] } - get paused () { + get paused() { return this[PAUSED] } - [BUFFERPUSH] (chunk) { - if (this[OBJECTMODE]) - this[BUFFERLENGTH] += 1 - else - this[BUFFERLENGTH] += chunk.length + [BUFFERPUSH](chunk) { + if (this[OBJECTMODE]) this[BUFFERLENGTH] += 1 + else this[BUFFERLENGTH] += chunk.length this[BUFFER].push(chunk) } - [BUFFERSHIFT] () { - if (this[BUFFER].length) { - if (this[OBJECTMODE]) - this[BUFFERLENGTH] -= 1 - else - this[BUFFERLENGTH] -= this[BUFFER][0].length - } + [BUFFERSHIFT]() { + if (this[OBJECTMODE]) this[BUFFERLENGTH] -= 1 + else this[BUFFERLENGTH] -= this[BUFFER][0].length return this[BUFFER].shift() } - [FLUSH] (noDrain) { - do {} while (this[FLUSHCHUNK](this[BUFFERSHIFT]())) + [FLUSH](noDrain) { + do {} while (this[FLUSHCHUNK](this[BUFFERSHIFT]()) && this[BUFFER].length) - if (!noDrain && !this[BUFFER].length && !this[EOF]) - this.emit('drain') + if (!noDrain && !this[BUFFER].length && !this[EOF]) this.emit('drain') } - [FLUSHCHUNK] (chunk) { - return chunk ? (this.emit('data', chunk), this.flowing) : false + [FLUSHCHUNK](chunk) { + this.emit('data', chunk) + return this.flowing } - pipe (dest, opts) { - if (this[DESTROYED]) - return + pipe(dest, opts) { + if (this[DESTROYED]) return const ended = this[EMITTED_END] opts = opts || {} - if (dest === proc.stdout || dest === proc.stderr) - opts.end = false - else - opts.end = opts.end !== false + if (dest === proc.stdout || dest === proc.stderr) opts.end = false + else opts.end = opts.end !== false opts.proxyErrors = !!opts.proxyErrors // piping an ended stream ends immediately if (ended) { - if (opts.end) - dest.end() + if (opts.end) dest.end() } else { - this[PIPES].push(!opts.proxyErrors ? new Pipe(this, dest, opts) - : new PipeProxyErrors(this, dest, opts)) - if (this[ASYNC]) - defer(() => this[RESUME]()) - else - this[RESUME]() + this[PIPES].push( + !opts.proxyErrors + ? new Pipe(this, dest, opts) + : new PipeProxyErrors(this, dest, opts) + ) + if (this[ASYNC]) defer(() => this[RESUME]()) + else this[RESUME]() } return dest } - unpipe (dest) { + unpipe(dest) { const p = this[PIPES].find(p => p.dest === dest) if (p) { this[PIPES].splice(this[PIPES].indexOf(p), 1) @@ -412,69 +416,72 @@ module.exports = class Minipass extends Stream { } } - addListener (ev, fn) { + addListener(ev, fn) { return this.on(ev, fn) } - on (ev, fn) { + on(ev, fn) { const ret = super.on(ev, fn) - if (ev === 'data' && !this[PIPES].length && !this.flowing) - this[RESUME]() + if (ev === 'data' && !this[PIPES].length && !this.flowing) this[RESUME]() else if (ev === 'readable' && this[BUFFERLENGTH] !== 0) super.emit('readable') else if (isEndish(ev) && this[EMITTED_END]) { super.emit(ev) this.removeAllListeners(ev) } else if (ev === 'error' && this[EMITTED_ERROR]) { - if (this[ASYNC]) - defer(() => fn.call(this, this[EMITTED_ERROR])) - else - fn.call(this, this[EMITTED_ERROR]) + if (this[ASYNC]) defer(() => fn.call(this, this[EMITTED_ERROR])) + else fn.call(this, this[EMITTED_ERROR]) } return ret } - get emittedEnd () { + get emittedEnd() { return this[EMITTED_END] } - [MAYBE_EMIT_END] () { - if (!this[EMITTING_END] && - !this[EMITTED_END] && - !this[DESTROYED] && - this[BUFFER].length === 0 && - this[EOF]) { + [MAYBE_EMIT_END]() { + if ( + !this[EMITTING_END] && + !this[EMITTED_END] && + !this[DESTROYED] && + this[BUFFER].length === 0 && + this[EOF] + ) { this[EMITTING_END] = true this.emit('end') this.emit('prefinish') this.emit('finish') - if (this[CLOSED]) - this.emit('close') + if (this[CLOSED]) this.emit('close') this[EMITTING_END] = false } } - emit (ev, data, ...extra) { + emit(ev, data, ...extra) { // error and close are only events allowed after calling destroy() if (ev !== 'error' && ev !== 'close' && ev !== DESTROYED && this[DESTROYED]) return else if (ev === 'data') { - return !data ? false - : this[ASYNC] ? defer(() => this[EMITDATA](data)) + return !this[OBJECTMODE] && !data + ? false + : this[ASYNC] + ? defer(() => this[EMITDATA](data)) : this[EMITDATA](data) } else if (ev === 'end') { return this[EMITEND]() } else if (ev === 'close') { this[CLOSED] = true // don't emit close before 'end' and 'finish' - if (!this[EMITTED_END] && !this[DESTROYED]) - return + if (!this[EMITTED_END] && !this[DESTROYED]) return const ret = super.emit('close') this.removeAllListeners('close') return ret } else if (ev === 'error') { this[EMITTED_ERROR] = data - const ret = super.emit('error', data) + super.emit(ERROR, data) + const ret = + !this[SIGNAL] || this.listeners('error').length + ? super.emit('error', data) + : false this[MAYBE_EMIT_END]() return ret } else if (ev === 'resume') { @@ -493,29 +500,25 @@ module.exports = class Minipass extends Stream { return ret } - [EMITDATA] (data) { + [EMITDATA](data) { for (const p of this[PIPES]) { - if (p.dest.write(data) === false) - this.pause() + if (p.dest.write(data) === false) this.pause() } const ret = super.emit('data', data) this[MAYBE_EMIT_END]() return ret } - [EMITEND] () { - if (this[EMITTED_END]) - return + [EMITEND]() { + if (this[EMITTED_END]) return this[EMITTED_END] = true this.readable = false - if (this[ASYNC]) - defer(() => this[EMITEND2]()) - else - this[EMITEND2]() + if (this[ASYNC]) defer(() => this[EMITEND2]()) + else this[EMITEND2]() } - [EMITEND2] () { + [EMITEND2]() { if (this[DECODER]) { const data = this[DECODER].end() if (data) { @@ -535,33 +538,34 @@ module.exports = class Minipass extends Stream { } // const all = await stream.collect() - collect () { + collect() { const buf = [] - if (!this[OBJECTMODE]) - buf.dataLength = 0 + if (!this[OBJECTMODE]) buf.dataLength = 0 // set the promise first, in case an error is raised // by triggering the flow here. const p = this.promise() this.on('data', c => { buf.push(c) - if (!this[OBJECTMODE]) - buf.dataLength += c.length + if (!this[OBJECTMODE]) buf.dataLength += c.length }) return p.then(() => buf) } // const data = await stream.concat() - concat () { + concat() { return this[OBJECTMODE] ? Promise.reject(new Error('cannot concat in objectMode')) : this.collect().then(buf => this[OBJECTMODE] ? Promise.reject(new Error('cannot concat in objectMode')) - : this[ENCODING] ? buf.join('') : Buffer.concat(buf, buf.dataLength)) + : this[ENCODING] + ? buf.join('') + : Buffer.concat(buf, buf.dataLength) + ) } // stream.promise().then(() => done, er => emitted error) - promise () { + promise() { return new Promise((resolve, reject) => { this.on(DESTROYED, () => reject(new Error('stream destroyed'))) this.on('error', er => reject(er)) @@ -570,31 +574,41 @@ module.exports = class Minipass extends Stream { } // for await (let chunk of stream) - [ASYNCITERATOR] () { + [ASYNCITERATOR]() { + let stopped = false + const stop = () => { + this.pause() + stopped = true + return Promise.resolve({ done: true }) + } const next = () => { + if (stopped) return stop() const res = this.read() - if (res !== null) - return Promise.resolve({ done: false, value: res }) + if (res !== null) return Promise.resolve({ done: false, value: res }) - if (this[EOF]) - return Promise.resolve({ done: true }) + if (this[EOF]) return stop() let resolve = null let reject = null const onerr = er => { this.removeListener('data', ondata) this.removeListener('end', onend) + this.removeListener(DESTROYED, ondestroy) + stop() reject(er) } const ondata = value => { this.removeListener('error', onerr) this.removeListener('end', onend) + this.removeListener(DESTROYED, ondestroy) this.pause() resolve({ value: value, done: !!this[EOF] }) } const onend = () => { this.removeListener('error', onerr) this.removeListener('data', ondata) + this.removeListener(DESTROYED, ondestroy) + stop() resolve({ done: true }) } const ondestroy = () => onerr(new Error('stream destroyed')) @@ -608,25 +622,51 @@ module.exports = class Minipass extends Stream { }) } - return { next } + return { + next, + throw: stop, + return: stop, + [ASYNCITERATOR]() { + return this + }, + } } // for (let chunk of stream) - [ITERATOR] () { + [ITERATOR]() { + let stopped = false + const stop = () => { + this.pause() + this.removeListener(ERROR, stop) + this.removeListener(DESTROYED, stop) + this.removeListener('end', stop) + stopped = true + return { done: true } + } + const next = () => { + if (stopped) return stop() const value = this.read() - const done = value === null - return { value, done } + return value === null ? stop() : { value } + } + this.once('end', stop) + this.once(ERROR, stop) + this.once(DESTROYED, stop) + + return { + next, + throw: stop, + return: stop, + [ITERATOR]() { + return this + }, } - return { next } } - destroy (er) { + destroy(er) { if (this[DESTROYED]) { - if (er) - this.emit('error', er) - else - this.emit(DESTROYED) + if (er) this.emit('error', er) + else this.emit(DESTROYED) return this } @@ -636,22 +676,27 @@ module.exports = class Minipass extends Stream { this[BUFFER].length = 0 this[BUFFERLENGTH] = 0 - if (typeof this.close === 'function' && !this[CLOSED]) - this.close() + if (typeof this.close === 'function' && !this[CLOSED]) this.close() - if (er) - this.emit('error', er) - else // if no error to emit, still reject pending promises - this.emit(DESTROYED) + if (er) this.emit('error', er) + // if no error to emit, still reject pending promises + else this.emit(DESTROYED) return this } - static isStream (s) { - return !!s && (s instanceof Minipass || s instanceof Stream || - s instanceof EE && ( - typeof s.pipe === 'function' || // readable - (typeof s.write === 'function' && typeof s.end === 'function') // writable - )) + static isStream(s) { + return ( + !!s && + (s instanceof Minipass || + s instanceof Stream || + (s instanceof EE && + // readable + (typeof s.pipe === 'function' || + // writable + (typeof s.write === 'function' && typeof s.end === 'function')))) + ) } } + +exports.Minipass = Minipass diff --git a/node_modules/minipass/node_modules/yallist/LICENSE b/node_modules/minipass/node_modules/yallist/LICENSE deleted file mode 100644 index 19129e31..00000000 --- a/node_modules/minipass/node_modules/yallist/LICENSE +++ /dev/null @@ -1,15 +0,0 @@ -The ISC License - -Copyright (c) Isaac Z. Schlueter and Contributors - -Permission to use, copy, modify, and/or distribute this software for any -purpose with or without fee is hereby granted, provided that the above -copyright notice and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR -IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/node_modules/minipass/node_modules/yallist/README.md b/node_modules/minipass/node_modules/yallist/README.md deleted file mode 100644 index f5861018..00000000 --- a/node_modules/minipass/node_modules/yallist/README.md +++ /dev/null @@ -1,204 +0,0 @@ -# yallist - -Yet Another Linked List - -There are many doubly-linked list implementations like it, but this -one is mine. - -For when an array would be too big, and a Map can't be iterated in -reverse order. - - -[![Build Status](https://travis-ci.org/isaacs/yallist.svg?branch=master)](https://travis-ci.org/isaacs/yallist) [![Coverage Status](https://coveralls.io/repos/isaacs/yallist/badge.svg?service=github)](https://coveralls.io/github/isaacs/yallist) - -## basic usage - -```javascript -var yallist = require('yallist') -var myList = yallist.create([1, 2, 3]) -myList.push('foo') -myList.unshift('bar') -// of course pop() and shift() are there, too -console.log(myList.toArray()) // ['bar', 1, 2, 3, 'foo'] -myList.forEach(function (k) { - // walk the list head to tail -}) -myList.forEachReverse(function (k, index, list) { - // walk the list tail to head -}) -var myDoubledList = myList.map(function (k) { - return k + k -}) -// now myDoubledList contains ['barbar', 2, 4, 6, 'foofoo'] -// mapReverse is also a thing -var myDoubledListReverse = myList.mapReverse(function (k) { - return k + k -}) // ['foofoo', 6, 4, 2, 'barbar'] - -var reduced = myList.reduce(function (set, entry) { - set += entry - return set -}, 'start') -console.log(reduced) // 'startfoo123bar' -``` - -## api - -The whole API is considered "public". - -Functions with the same name as an Array method work more or less the -same way. - -There's reverse versions of most things because that's the point. - -### Yallist - -Default export, the class that holds and manages a list. - -Call it with either a forEach-able (like an array) or a set of -arguments, to initialize the list. - -The Array-ish methods all act like you'd expect. No magic length, -though, so if you change that it won't automatically prune or add -empty spots. - -### Yallist.create(..) - -Alias for Yallist function. Some people like factories. - -#### yallist.head - -The first node in the list - -#### yallist.tail - -The last node in the list - -#### yallist.length - -The number of nodes in the list. (Change this at your peril. It is -not magic like Array length.) - -#### yallist.toArray() - -Convert the list to an array. - -#### yallist.forEach(fn, [thisp]) - -Call a function on each item in the list. - -#### yallist.forEachReverse(fn, [thisp]) - -Call a function on each item in the list, in reverse order. - -#### yallist.get(n) - -Get the data at position `n` in the list. If you use this a lot, -probably better off just using an Array. - -#### yallist.getReverse(n) - -Get the data at position `n`, counting from the tail. - -#### yallist.map(fn, thisp) - -Create a new Yallist with the result of calling the function on each -item. - -#### yallist.mapReverse(fn, thisp) - -Same as `map`, but in reverse. - -#### yallist.pop() - -Get the data from the list tail, and remove the tail from the list. - -#### yallist.push(item, ...) - -Insert one or more items to the tail of the list. - -#### yallist.reduce(fn, initialValue) - -Like Array.reduce. - -#### yallist.reduceReverse - -Like Array.reduce, but in reverse. - -#### yallist.reverse - -Reverse the list in place. - -#### yallist.shift() - -Get the data from the list head, and remove the head from the list. - -#### yallist.slice([from], [to]) - -Just like Array.slice, but returns a new Yallist. - -#### yallist.sliceReverse([from], [to]) - -Just like yallist.slice, but the result is returned in reverse. - -#### yallist.toArray() - -Create an array representation of the list. - -#### yallist.toArrayReverse() - -Create a reversed array representation of the list. - -#### yallist.unshift(item, ...) - -Insert one or more items to the head of the list. - -#### yallist.unshiftNode(node) - -Move a Node object to the front of the list. (That is, pull it out of -wherever it lives, and make it the new head.) - -If the node belongs to a different list, then that list will remove it -first. - -#### yallist.pushNode(node) - -Move a Node object to the end of the list. (That is, pull it out of -wherever it lives, and make it the new tail.) - -If the node belongs to a list already, then that list will remove it -first. - -#### yallist.removeNode(node) - -Remove a node from the list, preserving referential integrity of head -and tail and other nodes. - -Will throw an error if you try to have a list remove a node that -doesn't belong to it. - -### Yallist.Node - -The class that holds the data and is actually the list. - -Call with `var n = new Node(value, previousNode, nextNode)` - -Note that if you do direct operations on Nodes themselves, it's very -easy to get into weird states where the list is broken. Be careful :) - -#### node.next - -The next node in the list. - -#### node.prev - -The previous node in the list. - -#### node.value - -The data the node contains. - -#### node.list - -The list to which this node belongs. (Null if it does not belong to -any list.) diff --git a/node_modules/minipass/node_modules/yallist/iterator.js b/node_modules/minipass/node_modules/yallist/iterator.js deleted file mode 100644 index d41c97a1..00000000 --- a/node_modules/minipass/node_modules/yallist/iterator.js +++ /dev/null @@ -1,8 +0,0 @@ -'use strict' -module.exports = function (Yallist) { - Yallist.prototype[Symbol.iterator] = function* () { - for (let walker = this.head; walker; walker = walker.next) { - yield walker.value - } - } -} diff --git a/node_modules/minipass/node_modules/yallist/package.json b/node_modules/minipass/node_modules/yallist/package.json deleted file mode 100644 index 8a083867..00000000 --- a/node_modules/minipass/node_modules/yallist/package.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "name": "yallist", - "version": "4.0.0", - "description": "Yet Another Linked List", - "main": "yallist.js", - "directories": { - "test": "test" - }, - "files": [ - "yallist.js", - "iterator.js" - ], - "dependencies": {}, - "devDependencies": { - "tap": "^12.1.0" - }, - "scripts": { - "test": "tap test/*.js --100", - "preversion": "npm test", - "postversion": "npm publish", - "postpublish": "git push origin --all; git push origin --tags" - }, - "repository": { - "type": "git", - "url": "git+https://github.com/isaacs/yallist.git" - }, - "author": "Isaac Z. Schlueter (http://blog.izs.me/)", - "license": "ISC" -} diff --git a/node_modules/minipass/node_modules/yallist/yallist.js b/node_modules/minipass/node_modules/yallist/yallist.js deleted file mode 100644 index 4e83ab1c..00000000 --- a/node_modules/minipass/node_modules/yallist/yallist.js +++ /dev/null @@ -1,426 +0,0 @@ -'use strict' -module.exports = Yallist - -Yallist.Node = Node -Yallist.create = Yallist - -function Yallist (list) { - var self = this - if (!(self instanceof Yallist)) { - self = new Yallist() - } - - self.tail = null - self.head = null - self.length = 0 - - if (list && typeof list.forEach === 'function') { - list.forEach(function (item) { - self.push(item) - }) - } else if (arguments.length > 0) { - for (var i = 0, l = arguments.length; i < l; i++) { - self.push(arguments[i]) - } - } - - return self -} - -Yallist.prototype.removeNode = function (node) { - if (node.list !== this) { - throw new Error('removing node which does not belong to this list') - } - - var next = node.next - var prev = node.prev - - if (next) { - next.prev = prev - } - - if (prev) { - prev.next = next - } - - if (node === this.head) { - this.head = next - } - if (node === this.tail) { - this.tail = prev - } - - node.list.length-- - node.next = null - node.prev = null - node.list = null - - return next -} - -Yallist.prototype.unshiftNode = function (node) { - if (node === this.head) { - return - } - - if (node.list) { - node.list.removeNode(node) - } - - var head = this.head - node.list = this - node.next = head - if (head) { - head.prev = node - } - - this.head = node - if (!this.tail) { - this.tail = node - } - this.length++ -} - -Yallist.prototype.pushNode = function (node) { - if (node === this.tail) { - return - } - - if (node.list) { - node.list.removeNode(node) - } - - var tail = this.tail - node.list = this - node.prev = tail - if (tail) { - tail.next = node - } - - this.tail = node - if (!this.head) { - this.head = node - } - this.length++ -} - -Yallist.prototype.push = function () { - for (var i = 0, l = arguments.length; i < l; i++) { - push(this, arguments[i]) - } - return this.length -} - -Yallist.prototype.unshift = function () { - for (var i = 0, l = arguments.length; i < l; i++) { - unshift(this, arguments[i]) - } - return this.length -} - -Yallist.prototype.pop = function () { - if (!this.tail) { - return undefined - } - - var res = this.tail.value - this.tail = this.tail.prev - if (this.tail) { - this.tail.next = null - } else { - this.head = null - } - this.length-- - return res -} - -Yallist.prototype.shift = function () { - if (!this.head) { - return undefined - } - - var res = this.head.value - this.head = this.head.next - if (this.head) { - this.head.prev = null - } else { - this.tail = null - } - this.length-- - return res -} - -Yallist.prototype.forEach = function (fn, thisp) { - thisp = thisp || this - for (var walker = this.head, i = 0; walker !== null; i++) { - fn.call(thisp, walker.value, i, this) - walker = walker.next - } -} - -Yallist.prototype.forEachReverse = function (fn, thisp) { - thisp = thisp || this - for (var walker = this.tail, i = this.length - 1; walker !== null; i--) { - fn.call(thisp, walker.value, i, this) - walker = walker.prev - } -} - -Yallist.prototype.get = function (n) { - for (var i = 0, walker = this.head; walker !== null && i < n; i++) { - // abort out of the list early if we hit a cycle - walker = walker.next - } - if (i === n && walker !== null) { - return walker.value - } -} - -Yallist.prototype.getReverse = function (n) { - for (var i = 0, walker = this.tail; walker !== null && i < n; i++) { - // abort out of the list early if we hit a cycle - walker = walker.prev - } - if (i === n && walker !== null) { - return walker.value - } -} - -Yallist.prototype.map = function (fn, thisp) { - thisp = thisp || this - var res = new Yallist() - for (var walker = this.head; walker !== null;) { - res.push(fn.call(thisp, walker.value, this)) - walker = walker.next - } - return res -} - -Yallist.prototype.mapReverse = function (fn, thisp) { - thisp = thisp || this - var res = new Yallist() - for (var walker = this.tail; walker !== null;) { - res.push(fn.call(thisp, walker.value, this)) - walker = walker.prev - } - return res -} - -Yallist.prototype.reduce = function (fn, initial) { - var acc - var walker = this.head - if (arguments.length > 1) { - acc = initial - } else if (this.head) { - walker = this.head.next - acc = this.head.value - } else { - throw new TypeError('Reduce of empty list with no initial value') - } - - for (var i = 0; walker !== null; i++) { - acc = fn(acc, walker.value, i) - walker = walker.next - } - - return acc -} - -Yallist.prototype.reduceReverse = function (fn, initial) { - var acc - var walker = this.tail - if (arguments.length > 1) { - acc = initial - } else if (this.tail) { - walker = this.tail.prev - acc = this.tail.value - } else { - throw new TypeError('Reduce of empty list with no initial value') - } - - for (var i = this.length - 1; walker !== null; i--) { - acc = fn(acc, walker.value, i) - walker = walker.prev - } - - return acc -} - -Yallist.prototype.toArray = function () { - var arr = new Array(this.length) - for (var i = 0, walker = this.head; walker !== null; i++) { - arr[i] = walker.value - walker = walker.next - } - return arr -} - -Yallist.prototype.toArrayReverse = function () { - var arr = new Array(this.length) - for (var i = 0, walker = this.tail; walker !== null; i++) { - arr[i] = walker.value - walker = walker.prev - } - return arr -} - -Yallist.prototype.slice = function (from, to) { - to = to || this.length - if (to < 0) { - to += this.length - } - from = from || 0 - if (from < 0) { - from += this.length - } - var ret = new Yallist() - if (to < from || to < 0) { - return ret - } - if (from < 0) { - from = 0 - } - if (to > this.length) { - to = this.length - } - for (var i = 0, walker = this.head; walker !== null && i < from; i++) { - walker = walker.next - } - for (; walker !== null && i < to; i++, walker = walker.next) { - ret.push(walker.value) - } - return ret -} - -Yallist.prototype.sliceReverse = function (from, to) { - to = to || this.length - if (to < 0) { - to += this.length - } - from = from || 0 - if (from < 0) { - from += this.length - } - var ret = new Yallist() - if (to < from || to < 0) { - return ret - } - if (from < 0) { - from = 0 - } - if (to > this.length) { - to = this.length - } - for (var i = this.length, walker = this.tail; walker !== null && i > to; i--) { - walker = walker.prev - } - for (; walker !== null && i > from; i--, walker = walker.prev) { - ret.push(walker.value) - } - return ret -} - -Yallist.prototype.splice = function (start, deleteCount, ...nodes) { - if (start > this.length) { - start = this.length - 1 - } - if (start < 0) { - start = this.length + start; - } - - for (var i = 0, walker = this.head; walker !== null && i < start; i++) { - walker = walker.next - } - - var ret = [] - for (var i = 0; walker && i < deleteCount; i++) { - ret.push(walker.value) - walker = this.removeNode(walker) - } - if (walker === null) { - walker = this.tail - } - - if (walker !== this.head && walker !== this.tail) { - walker = walker.prev - } - - for (var i = 0; i < nodes.length; i++) { - walker = insert(this, walker, nodes[i]) - } - return ret; -} - -Yallist.prototype.reverse = function () { - var head = this.head - var tail = this.tail - for (var walker = head; walker !== null; walker = walker.prev) { - var p = walker.prev - walker.prev = walker.next - walker.next = p - } - this.head = tail - this.tail = head - return this -} - -function insert (self, node, value) { - var inserted = node === self.head ? - new Node(value, null, node, self) : - new Node(value, node, node.next, self) - - if (inserted.next === null) { - self.tail = inserted - } - if (inserted.prev === null) { - self.head = inserted - } - - self.length++ - - return inserted -} - -function push (self, item) { - self.tail = new Node(item, self.tail, null, self) - if (!self.head) { - self.head = self.tail - } - self.length++ -} - -function unshift (self, item) { - self.head = new Node(item, null, self.head, self) - if (!self.tail) { - self.tail = self.head - } - self.length++ -} - -function Node (value, prev, next, list) { - if (!(this instanceof Node)) { - return new Node(value, prev, next, list) - } - - this.list = list - this.value = value - - if (prev) { - prev.next = this - this.prev = prev - } else { - this.prev = null - } - - if (next) { - next.prev = this - this.next = next - } else { - this.next = null - } -} - -try { - // add if support for Symbol.iterator is present - require('./iterator.js')(Yallist) -} catch (er) {} diff --git a/node_modules/minipass/package.json b/node_modules/minipass/package.json index ca30e694..0e20e988 100644 --- a/node_modules/minipass/package.json +++ b/node_modules/minipass/package.json @@ -1,26 +1,45 @@ { "name": "minipass", - "version": "4.0.0", + "version": "5.0.0", "description": "minimal implementation of a PassThrough stream", - "main": "index.js", - "types": "index.d.ts", - "dependencies": { - "yallist": "^4.0.0" + "main": "./index.js", + "module": "./index.mjs", + "types": "./index.d.ts", + "exports": { + ".": { + "import": { + "types": "./index.d.ts", + "default": "./index.mjs" + }, + "require": { + "types": "./index.d.ts", + "default": "./index.js" + } + }, + "./package.json": "./package.json" }, "devDependencies": { "@types/node": "^17.0.41", "end-of-stream": "^1.4.0", + "node-abort-controller": "^3.1.1", "prettier": "^2.6.2", "tap": "^16.2.0", "through2": "^2.0.3", "ts-node": "^10.8.1", + "typedoc": "^0.23.24", "typescript": "^4.7.3" }, "scripts": { + "pretest": "npm run prepare", + "presnap": "npm run prepare", + "prepare": "node ./scripts/transpile-to-esm.js", + "snap": "tap", "test": "tap", "preversion": "npm test", "postversion": "npm publish", - "postpublish": "git push origin --follow-tags" + "postpublish": "git push origin --follow-tags", + "typedoc": "typedoc ./index.d.ts", + "format": "prettier --write . --loglevel warn" }, "repository": { "type": "git", @@ -34,7 +53,8 @@ "license": "ISC", "files": [ "index.d.ts", - "index.js" + "index.js", + "index.mjs" ], "tap": { "check-coverage": true diff --git a/node_modules/node-addon-api/README.md b/node_modules/node-addon-api/README.md index 7a0a69bf..6a79c917 100644 --- a/node_modules/node-addon-api/README.md +++ b/node_modules/node-addon-api/README.md @@ -16,15 +16,15 @@ provided by Node.js when using C++. It provides a C++ object model and exception handling semantics with low overhead. There are three options for implementing addons: Node-API, nan, or direct -use of internal V8, libuv and Node.js libraries. Unless there is a need for -direct access to functionality which is not exposed by Node-API as outlined +use of internal V8, libuv, and Node.js libraries. Unless there is a need for +direct access to functionality that is not exposed by Node-API as outlined in [C/C++ addons](https://nodejs.org/dist/latest/docs/api/addons.html) in Node.js core, use Node-API. Refer to [C/C++ addons with Node-API](https://nodejs.org/dist/latest/docs/api/n-api.html) for more information on Node-API. Node-API is an ABI stable C interface provided by Node.js for building native -addons. It is independent from the underlying JavaScript runtime (e.g. V8 or ChakraCore) +addons. It is independent of the underlying JavaScript runtime (e.g. V8 or ChakraCore) and is maintained as part of Node.js itself. It is intended to insulate native addons from changes in the underlying JavaScript engine and allow modules compiled for one version to run on later versions of Node.js without @@ -46,7 +46,7 @@ provides an [ABI stability guide][] containing a detailed explanation of ABI stability in general, and the Node-API ABI stability guarantee in particular. As new APIs are added to Node-API, node-addon-api must be updated to provide -wrappers for those new APIs. For this reason node-addon-api provides +wrappers for those new APIs. For this reason, node-addon-api provides methods that allow callers to obtain the underlying Node-API handles so direct calls to Node-API and the use of the objects/methods provided by node-addon-api can be used together. For example, in order to be able @@ -56,7 +56,7 @@ APIs exposed by node-addon-api are generally used to create and manipulate JavaScript values. Concepts and operations generally map to ideas specified in the **ECMA262 Language Specification**. -The [Node-API Resource](https://nodejs.github.io/node-addon-examples/) offers an +The [Node-API Resource](https://nodejs.github.io/node-addon-examples/) offers an excellent orientation and tips for developers just getting started with Node-API and node-addon-api. @@ -70,7 +70,7 @@ and node-addon-api. - **[Contributors](#contributors)** - **[License](#license)** -## **Current version: 5.0.0** +## **Current version: 5.1.0** (See [CHANGELOG.md](CHANGELOG.md) for complete Changelog) @@ -187,6 +187,28 @@ npm test --NAPI_VERSION=X where X is the version of Node-API you want to target. +To run a specific unit test, filter conditions are available + +**Example:** + compile and run only tests on objectwrap.cc and objectwrap.js + ``` + npm run unit --filter=objectwrap + ``` + +Multiple unit tests cane be selected with wildcards + +**Example:** +compile and run all test files ending with "reference" -> function_reference.cc, object_reference.cc, reference.cc + ``` + npm run unit --filter=*reference + ``` + +Multiple filter conditions can be joined to broaden the test selection + +**Example:** + compile and run all tests under folders threadsafe_function and typed_threadsafe_function and also the objectwrap.cc file + npm run unit --filter='*function objectwrap' + ### **Debug** To run the **node-addon-api** tests with `--debug` option: @@ -195,7 +217,7 @@ To run the **node-addon-api** tests with `--debug` option: npm run-script dev ``` -If you want faster build, you might use the following option: +If you want a faster build, you might use the following option: ``` npm run-script dev:incremental @@ -223,7 +245,7 @@ See [benchmark/README.md](benchmark/README.md) for more details about running an As node-addon-api's core mission is to expose the plain C Node-API as C++ wrappers, tools that facilitate n-api/node-addon-api providing more -convenient patterns on developing a Node.js add-ons with n-api/node-addon-api +convenient patterns for developing a Node.js add-on with n-api/node-addon-api can be published to NPM as standalone packages. It is also recommended to tag such packages with `node-addon-api` to provide more visibility to the community. @@ -269,19 +291,21 @@ See [CONTRIBUTING.md](CONTRIBUTING.md) for more details on our philosophy around | ------------------- | ----------------------------------------------------- | | Anna Henningsen | [addaleax](https://github.com/addaleax) | | Chengzhong Wu | [legendecas](https://github.com/legendecas) | -| Gabriel Schulhof | [gabrielschulhof](https://github.com/gabrielschulhof) | -| Jim Schlight | [jschlight](https://github.com/jschlight) | +| Jack Xia | [JckXia](https://github.com/JckXia) | +| Kevin Eady | [KevinEady](https://github.com/KevinEady) | | Michael Dawson | [mhdawson](https://github.com/mhdawson) | -| Kevin Eady | [KevinEady](https://github.com/KevinEady) | Nicola Del Gobbo | [NickNaso](https://github.com/NickNaso) | +| Vladimir Morozov | [vmoroz](https://github.com/vmoroz) | ### Emeritus | Name | GitHub Link | | ------------------- | ----------------------------------------------------- | | Arunesh Chandra | [aruneshchandra](https://github.com/aruneshchandra) | | Benjamin Byholm | [kkoopa](https://github.com/kkoopa) | -| Jason Ginchereau | [jasongin](https://github.com/jasongin) | +| Gabriel Schulhof | [gabrielschulhof](https://github.com/gabrielschulhof) | | Hitesh Kanwathirtha | [digitalinfinity](https://github.com/digitalinfinity) | +| Jason Ginchereau | [jasongin](https://github.com/jasongin) | +| Jim Schlight | [jschlight](https://github.com/jschlight) | | Sampson Gao | [sampsongao](https://github.com/sampsongao) | | Taylor Woll | [boingoing](https://github.com/boingoing) | diff --git a/node_modules/node-addon-api/index.js b/node_modules/node-addon-api/index.js index 2fa51c58..52f53e3c 100644 --- a/node_modules/node-addon-api/index.js +++ b/node_modules/node-addon-api/index.js @@ -1,11 +1,11 @@ const path = require('path'); -const include_dir = path.relative('.', __dirname); +const includeDir = path.relative('.', __dirname); module.exports = { include: `"${__dirname}"`, // deprecated, can be removed as part of 4.0.0 - include_dir, - gyp: path.join(include_dir, 'node_api.gyp:nothing'), + include_dir: includeDir, + gyp: path.join(includeDir, 'node_api.gyp:nothing'), isNodeApiBuiltin: true, needsFlag: false }; diff --git a/node_modules/node-addon-api/napi-inl.deprecated.h b/node_modules/node-addon-api/napi-inl.deprecated.h index 51e954ce..3ddbb2ef 100644 --- a/node_modules/node-addon-api/napi-inl.deprecated.h +++ b/node_modules/node-addon-api/napi-inl.deprecated.h @@ -6,187 +6,181 @@ //////////////////////////////////////////////////////////////////////////////// template -inline PropertyDescriptor -PropertyDescriptor::Accessor(const char* utf8name, - Getter getter, - napi_property_attributes attributes, - void* /*data*/) { +inline PropertyDescriptor PropertyDescriptor::Accessor( + const char* utf8name, + Getter getter, + napi_property_attributes attributes, + void* /*data*/) { using CbData = details::CallbackData; // TODO: Delete when the function is destroyed - auto callbackData = new CbData({ getter, nullptr }); - - return PropertyDescriptor({ - utf8name, - nullptr, - nullptr, - CbData::Wrapper, - nullptr, - nullptr, - attributes, - callbackData - }); + auto callbackData = new CbData({getter, nullptr}); + + return PropertyDescriptor({utf8name, + nullptr, + nullptr, + CbData::Wrapper, + nullptr, + nullptr, + attributes, + callbackData}); } template -inline PropertyDescriptor PropertyDescriptor::Accessor(const std::string& utf8name, - Getter getter, - napi_property_attributes attributes, - void* data) { +inline PropertyDescriptor PropertyDescriptor::Accessor( + const std::string& utf8name, + Getter getter, + napi_property_attributes attributes, + void* data) { return Accessor(utf8name.c_str(), getter, attributes, data); } template -inline PropertyDescriptor PropertyDescriptor::Accessor(napi_value name, - Getter getter, - napi_property_attributes attributes, - void* /*data*/) { +inline PropertyDescriptor PropertyDescriptor::Accessor( + napi_value name, + Getter getter, + napi_property_attributes attributes, + void* /*data*/) { using CbData = details::CallbackData; // TODO: Delete when the function is destroyed - auto callbackData = new CbData({ getter, nullptr }); - - return PropertyDescriptor({ - nullptr, - name, - nullptr, - CbData::Wrapper, - nullptr, - nullptr, - attributes, - callbackData - }); + auto callbackData = new CbData({getter, nullptr}); + + return PropertyDescriptor({nullptr, + name, + nullptr, + CbData::Wrapper, + nullptr, + nullptr, + attributes, + callbackData}); } template -inline PropertyDescriptor PropertyDescriptor::Accessor(Name name, - Getter getter, - napi_property_attributes attributes, - void* data) { +inline PropertyDescriptor PropertyDescriptor::Accessor( + Name name, Getter getter, napi_property_attributes attributes, void* data) { napi_value nameValue = name; return PropertyDescriptor::Accessor(nameValue, getter, attributes, data); } template -inline PropertyDescriptor PropertyDescriptor::Accessor(const char* utf8name, - Getter getter, - Setter setter, - napi_property_attributes attributes, - void* /*data*/) { +inline PropertyDescriptor PropertyDescriptor::Accessor( + const char* utf8name, + Getter getter, + Setter setter, + napi_property_attributes attributes, + void* /*data*/) { using CbData = details::AccessorCallbackData; // TODO: Delete when the function is destroyed - auto callbackData = new CbData({ getter, setter, nullptr }); - - return PropertyDescriptor({ - utf8name, - nullptr, - nullptr, - CbData::GetterWrapper, - CbData::SetterWrapper, - nullptr, - attributes, - callbackData - }); + auto callbackData = new CbData({getter, setter, nullptr}); + + return PropertyDescriptor({utf8name, + nullptr, + nullptr, + CbData::GetterWrapper, + CbData::SetterWrapper, + nullptr, + attributes, + callbackData}); } template -inline PropertyDescriptor PropertyDescriptor::Accessor(const std::string& utf8name, - Getter getter, - Setter setter, - napi_property_attributes attributes, - void* data) { +inline PropertyDescriptor PropertyDescriptor::Accessor( + const std::string& utf8name, + Getter getter, + Setter setter, + napi_property_attributes attributes, + void* data) { return Accessor(utf8name.c_str(), getter, setter, attributes, data); } template -inline PropertyDescriptor PropertyDescriptor::Accessor(napi_value name, - Getter getter, - Setter setter, - napi_property_attributes attributes, - void* /*data*/) { +inline PropertyDescriptor PropertyDescriptor::Accessor( + napi_value name, + Getter getter, + Setter setter, + napi_property_attributes attributes, + void* /*data*/) { using CbData = details::AccessorCallbackData; // TODO: Delete when the function is destroyed - auto callbackData = new CbData({ getter, setter, nullptr }); - - return PropertyDescriptor({ - nullptr, - name, - nullptr, - CbData::GetterWrapper, - CbData::SetterWrapper, - nullptr, - attributes, - callbackData - }); + auto callbackData = new CbData({getter, setter, nullptr}); + + return PropertyDescriptor({nullptr, + name, + nullptr, + CbData::GetterWrapper, + CbData::SetterWrapper, + nullptr, + attributes, + callbackData}); } template -inline PropertyDescriptor PropertyDescriptor::Accessor(Name name, - Getter getter, - Setter setter, - napi_property_attributes attributes, - void* data) { +inline PropertyDescriptor PropertyDescriptor::Accessor( + Name name, + Getter getter, + Setter setter, + napi_property_attributes attributes, + void* data) { napi_value nameValue = name; - return PropertyDescriptor::Accessor(nameValue, getter, setter, attributes, data); + return PropertyDescriptor::Accessor( + nameValue, getter, setter, attributes, data); } template -inline PropertyDescriptor PropertyDescriptor::Function(const char* utf8name, - Callable cb, - napi_property_attributes attributes, - void* /*data*/) { +inline PropertyDescriptor PropertyDescriptor::Function( + const char* utf8name, + Callable cb, + napi_property_attributes attributes, + void* /*data*/) { using ReturnType = decltype(cb(CallbackInfo(nullptr, nullptr))); using CbData = details::CallbackData; // TODO: Delete when the function is destroyed - auto callbackData = new CbData({ cb, nullptr }); - - return PropertyDescriptor({ - utf8name, - nullptr, - CbData::Wrapper, - nullptr, - nullptr, - nullptr, - attributes, - callbackData - }); + auto callbackData = new CbData({cb, nullptr}); + + return PropertyDescriptor({utf8name, + nullptr, + CbData::Wrapper, + nullptr, + nullptr, + nullptr, + attributes, + callbackData}); } template -inline PropertyDescriptor PropertyDescriptor::Function(const std::string& utf8name, - Callable cb, - napi_property_attributes attributes, - void* data) { +inline PropertyDescriptor PropertyDescriptor::Function( + const std::string& utf8name, + Callable cb, + napi_property_attributes attributes, + void* data) { return Function(utf8name.c_str(), cb, attributes, data); } template -inline PropertyDescriptor PropertyDescriptor::Function(napi_value name, - Callable cb, - napi_property_attributes attributes, - void* /*data*/) { +inline PropertyDescriptor PropertyDescriptor::Function( + napi_value name, + Callable cb, + napi_property_attributes attributes, + void* /*data*/) { using ReturnType = decltype(cb(CallbackInfo(nullptr, nullptr))); using CbData = details::CallbackData; // TODO: Delete when the function is destroyed - auto callbackData = new CbData({ cb, nullptr }); - - return PropertyDescriptor({ - nullptr, - name, - CbData::Wrapper, - nullptr, - nullptr, - nullptr, - attributes, - callbackData - }); + auto callbackData = new CbData({cb, nullptr}); + + return PropertyDescriptor({nullptr, + name, + CbData::Wrapper, + nullptr, + nullptr, + nullptr, + attributes, + callbackData}); } template -inline PropertyDescriptor PropertyDescriptor::Function(Name name, - Callable cb, - napi_property_attributes attributes, - void* data) { +inline PropertyDescriptor PropertyDescriptor::Function( + Name name, Callable cb, napi_property_attributes attributes, void* data) { napi_value nameValue = name; return PropertyDescriptor::Function(nameValue, cb, attributes, data); } -#endif // !SRC_NAPI_INL_DEPRECATED_H_ +#endif // !SRC_NAPI_INL_DEPRECATED_H_ diff --git a/node_modules/node-addon-api/napi-inl.h b/node_modules/node-addon-api/napi-inl.h index 14e75aa1..3ddc1baa 100644 --- a/node_modules/node-addon-api/napi-inl.h +++ b/node_modules/node-addon-api/napi-inl.h @@ -30,11 +30,11 @@ namespace details { // TODO: Replace this code with `napi_add_finalizer()` whenever it becomes // available on all supported versions of Node.js. template -static inline napi_status AttachData(napi_env env, - napi_value obj, - FreeType* data, - napi_finalize finalizer = nullptr, - void* hint = nullptr) { +inline napi_status AttachData(napi_env env, + napi_value obj, + FreeType* data, + napi_finalize finalizer = nullptr, + void* hint = nullptr) { napi_status status; if (finalizer == nullptr) { finalizer = [](napi_env /*env*/, void* data, void* /*hint*/) { @@ -45,22 +45,16 @@ static inline napi_status AttachData(napi_env env, napi_value symbol, external; status = napi_create_symbol(env, nullptr, &symbol); if (status == napi_ok) { - status = napi_create_external(env, - data, - finalizer, - hint, - &external); + status = napi_create_external(env, data, finalizer, hint, &external); if (status == napi_ok) { - napi_property_descriptor desc = { - nullptr, - symbol, - nullptr, - nullptr, - nullptr, - external, - napi_default, - nullptr - }; + napi_property_descriptor desc = {nullptr, + symbol, + nullptr, + nullptr, + nullptr, + external, + napi_default, + nullptr}; status = napi_define_properties(env, obj, 1, &desc); } } @@ -81,16 +75,16 @@ inline napi_value WrapCallback(Callable callback) { e.ThrowAsJavaScriptException(); return nullptr; } -#else // NAPI_CPP_EXCEPTIONS +#else // NAPI_CPP_EXCEPTIONS // When C++ exceptions are disabled, errors are immediately thrown as JS // exceptions, so there is no need to catch and rethrow them here. return callback(); -#endif // NAPI_CPP_EXCEPTIONS +#endif // NAPI_CPP_EXCEPTIONS } // For use in JS to C++ void callback wrappers to catch any Napi::Error -// exceptions and rethrow them as JavaScript exceptions before returning from the -// callback. +// exceptions and rethrow them as JavaScript exceptions before returning from +// the callback. template inline void WrapVoidCallback(Callable callback) { #ifdef NAPI_CPP_EXCEPTIONS @@ -99,21 +93,20 @@ inline void WrapVoidCallback(Callable callback) { } catch (const Error& e) { e.ThrowAsJavaScriptException(); } -#else // NAPI_CPP_EXCEPTIONS +#else // NAPI_CPP_EXCEPTIONS // When C++ exceptions are disabled, errors are immediately thrown as JS // exceptions, so there is no need to catch and rethrow them here. callback(); -#endif // NAPI_CPP_EXCEPTIONS +#endif // NAPI_CPP_EXCEPTIONS } template struct CallbackData { - static inline - napi_value Wrapper(napi_env env, napi_callback_info info) { + static inline napi_value Wrapper(napi_env env, napi_callback_info info) { return details::WrapCallback([&] { CallbackInfo callbackInfo(env, info); CallbackData* callbackData = - static_cast(callbackInfo.Data()); + static_cast(callbackInfo.Data()); callbackInfo.SetData(callbackData->data); return callbackData->callback(callbackInfo); }); @@ -125,12 +118,11 @@ struct CallbackData { template struct CallbackData { - static inline - napi_value Wrapper(napi_env env, napi_callback_info info) { + static inline napi_value Wrapper(napi_env env, napi_callback_info info) { return details::WrapCallback([&] { CallbackInfo callbackInfo(env, info); CallbackData* callbackData = - static_cast(callbackInfo.Data()); + static_cast(callbackInfo.Data()); callbackInfo.SetData(callbackData->data); callbackData->callback(callbackInfo); return nullptr; @@ -142,8 +134,8 @@ struct CallbackData { }; template -static napi_value -TemplatedVoidCallback(napi_env env, napi_callback_info info) NAPI_NOEXCEPT { +napi_value TemplatedVoidCallback(napi_env env, + napi_callback_info info) NAPI_NOEXCEPT { return details::WrapCallback([&] { CallbackInfo cbInfo(env, info); Callback(cbInfo); @@ -152,8 +144,8 @@ TemplatedVoidCallback(napi_env env, napi_callback_info info) NAPI_NOEXCEPT { } template -static napi_value -TemplatedCallback(napi_env env, napi_callback_info info) NAPI_NOEXCEPT { +napi_value TemplatedCallback(napi_env env, + napi_callback_info info) NAPI_NOEXCEPT { return details::WrapCallback([&] { CallbackInfo cbInfo(env, info); return Callback(cbInfo); @@ -162,8 +154,8 @@ TemplatedCallback(napi_env env, napi_callback_info info) NAPI_NOEXCEPT { template -static napi_value -TemplatedInstanceCallback(napi_env env, napi_callback_info info) NAPI_NOEXCEPT { +napi_value TemplatedInstanceCallback(napi_env env, + napi_callback_info info) NAPI_NOEXCEPT { return details::WrapCallback([&] { CallbackInfo cbInfo(env, info); T* instance = T::Unwrap(cbInfo.This().As()); @@ -172,9 +164,8 @@ TemplatedInstanceCallback(napi_env env, napi_callback_info info) NAPI_NOEXCEPT { } template -static napi_value -TemplatedInstanceVoidCallback(napi_env env, - napi_callback_info info) NAPI_NOEXCEPT { +napi_value TemplatedInstanceVoidCallback(napi_env env, napi_callback_info info) + NAPI_NOEXCEPT { return details::WrapCallback([&] { CallbackInfo cbInfo(env, info); T* instance = T::Unwrap(cbInfo.This().As()); @@ -200,7 +191,8 @@ struct FinalizeData { void* finalizeHint) NAPI_NOEXCEPT { WrapVoidCallback([&] { FinalizeData* finalizeData = static_cast(finalizeHint); - finalizeData->callback(Env(env), static_cast(data), finalizeData->hint); + finalizeData->callback( + Env(env), static_cast(data), finalizeData->hint); delete finalizeData; }); } @@ -210,14 +202,14 @@ struct FinalizeData { }; #if (NAPI_VERSION > 3 && !defined(__wasm32__)) -template , - typename FinalizerDataType=void> +template , + typename FinalizerDataType = void> struct ThreadSafeFinalize { - static inline - void Wrapper(napi_env env, void* rawFinalizeData, void* /* rawContext */) { - if (rawFinalizeData == nullptr) - return; + static inline void Wrapper(napi_env env, + void* rawFinalizeData, + void* /* rawContext */) { + if (rawFinalizeData == nullptr) return; ThreadSafeFinalize* finalizeData = static_cast(rawFinalizeData); @@ -225,12 +217,10 @@ struct ThreadSafeFinalize { delete finalizeData; } - static inline - void FinalizeWrapperWithData(napi_env env, - void* rawFinalizeData, - void* /* rawContext */) { - if (rawFinalizeData == nullptr) - return; + static inline void FinalizeWrapperWithData(napi_env env, + void* rawFinalizeData, + void* /* rawContext */) { + if (rawFinalizeData == nullptr) return; ThreadSafeFinalize* finalizeData = static_cast(rawFinalizeData); @@ -238,12 +228,10 @@ struct ThreadSafeFinalize { delete finalizeData; } - static inline - void FinalizeWrapperWithContext(napi_env env, - void* rawFinalizeData, - void* rawContext) { - if (rawFinalizeData == nullptr) - return; + static inline void FinalizeWrapperWithContext(napi_env env, + void* rawFinalizeData, + void* rawContext) { + if (rawFinalizeData == nullptr) return; ThreadSafeFinalize* finalizeData = static_cast(rawFinalizeData); @@ -251,17 +239,14 @@ struct ThreadSafeFinalize { delete finalizeData; } - static inline - void FinalizeFinalizeWrapperWithDataAndContext(napi_env env, - void* rawFinalizeData, - void* rawContext) { - if (rawFinalizeData == nullptr) - return; + static inline void FinalizeFinalizeWrapperWithDataAndContext( + napi_env env, void* rawFinalizeData, void* rawContext) { + if (rawFinalizeData == nullptr) return; ThreadSafeFinalize* finalizeData = static_cast(rawFinalizeData); - finalizeData->callback(Env(env), finalizeData->data, - static_cast(rawContext)); + finalizeData->callback( + Env(env), finalizeData->data, static_cast(rawContext)); delete finalizeData; } @@ -270,8 +255,8 @@ struct ThreadSafeFinalize { }; template -typename std::enable_if::type static inline CallJsWrapper( - napi_env env, napi_value jsCallback, void* context, void* data) { +inline typename std::enable_if(nullptr)>::type +CallJsWrapper(napi_env env, napi_value jsCallback, void* context, void* data) { call(env, Function(env, jsCallback), static_cast(context), @@ -279,8 +264,11 @@ typename std::enable_if::type static inline CallJsWrapper( } template -typename std::enable_if::type static inline CallJsWrapper( - napi_env env, napi_value jsCallback, void* /*context*/, void* /*data*/) { +inline typename std::enable_if(nullptr)>::type +CallJsWrapper(napi_env env, + napi_value jsCallback, + void* /*context*/, + void* /*data*/) { if (jsCallback != nullptr) { Function(env, jsCallback).Call(0, nullptr); } @@ -311,23 +299,23 @@ napi_value DefaultCallbackWrapper(napi_env env, Napi::Function cb) { template struct AccessorCallbackData { - static inline - napi_value GetterWrapper(napi_env env, napi_callback_info info) { + static inline napi_value GetterWrapper(napi_env env, + napi_callback_info info) { return details::WrapCallback([&] { CallbackInfo callbackInfo(env, info); AccessorCallbackData* callbackData = - static_cast(callbackInfo.Data()); + static_cast(callbackInfo.Data()); callbackInfo.SetData(callbackData->data); return callbackData->getterCallback(callbackInfo); }); } - static inline - napi_value SetterWrapper(napi_env env, napi_callback_info info) { + static inline napi_value SetterWrapper(napi_env env, + napi_callback_info info) { return details::WrapCallback([&] { CallbackInfo callbackInfo(env, info); AccessorCallbackData* callbackData = - static_cast(callbackInfo.Data()); + static_cast(callbackInfo.Data()); callbackInfo.SetData(callbackData->data); callbackData->setterCallback(callbackInfo); return nullptr; @@ -342,8 +330,8 @@ struct AccessorCallbackData { } // namespace details #ifndef NODE_ADDON_API_DISABLE_DEPRECATED -# include "napi-inl.deprecated.h" -#endif // !NODE_ADDON_API_DISABLE_DEPRECATED +#include "napi-inl.deprecated.h" +#endif // !NODE_ADDON_API_DISABLE_DEPRECATED //////////////////////////////////////////////////////////////////////////////// // Module registration @@ -358,16 +346,15 @@ struct AccessorCallbackData { // Register an add-on based on a subclass of `Addon` with a custom Node.js // module name. -#define NODE_API_NAMED_ADDON(modname, classname) \ - static napi_value __napi_ ## classname(napi_env env, \ - napi_value exports) { \ - return Napi::RegisterModule(env, exports, &classname::Init); \ - } \ - NAPI_MODULE(modname, __napi_ ## classname) +#define NODE_API_NAMED_ADDON(modname, classname) \ + static napi_value __napi_##classname(napi_env env, napi_value exports) { \ + return Napi::RegisterModule(env, exports, &classname::Init); \ + } \ + NAPI_MODULE(modname, __napi_##classname) // Register an add-on based on a subclass of `Addon` with the Node.js module // name given by node-gyp from the `target_name` in binding.gyp. -#define NODE_API_ADDON(classname) \ +#define NODE_API_ADDON(classname) \ NODE_API_NAMED_ADDON(NODE_GYP_MODULE_NAME, classname) // Adapt the NAPI_MODULE registration function: @@ -377,8 +364,8 @@ inline napi_value RegisterModule(napi_env env, napi_value exports, ModuleRegisterCallback registerCallback) { return details::WrapCallback([&] { - return napi_value(registerCallback(Napi::Env(env), - Napi::Object(env, exports))); + return napi_value( + registerCallback(Napi::Env(env), Napi::Object(env, exports))); }); } @@ -452,8 +439,7 @@ inline Maybe Just(const T& t) { // Env class //////////////////////////////////////////////////////////////////////////////// -inline Env::Env(napi_env env) : _env(env) { -} +inline Env::Env(napi_env env) : _env(env) {} inline Env::operator napi_env() const { return _env; @@ -483,7 +469,8 @@ inline Value Env::Null() const { inline bool Env::IsExceptionPending() const { bool result; napi_status status = napi_is_exception_pending(_env, &result); - if (status != napi_ok) result = false; // Checking for a pending exception shouldn't throw. + if (status != napi_ok) + result = false; // Checking for a pending exception shouldn't throw. return result; } @@ -536,10 +523,11 @@ void Env::CleanupHook::WrapperWithArg(void* data) NAPI_NOEXCEPT { #if NAPI_VERSION > 5 template fini> inline void Env::SetInstanceData(T* data) const { - napi_status status = - napi_set_instance_data(_env, data, [](napi_env env, void* data, void*) { - fini(env, static_cast(data)); - }, nullptr); + napi_status status = napi_set_instance_data( + _env, + data, + [](napi_env env, void* data, void*) { fini(env, static_cast(data)); }, + nullptr); NAPI_THROW_IF_FAILED_VOID(_env, status); } @@ -547,11 +535,13 @@ template fini> inline void Env::SetInstanceData(DataType* data, HintType* hint) const { - napi_status status = - napi_set_instance_data(_env, data, + napi_status status = napi_set_instance_data( + _env, + data, [](napi_env env, void* data, void* hint) { fini(env, static_cast(data), static_cast(hint)); - }, hint); + }, + hint); NAPI_THROW_IF_FAILED_VOID(_env, status); } @@ -565,7 +555,8 @@ inline T* Env::GetInstanceData() const { return static_cast(data); } -template void Env::DefaultFini(Env, T* data) { +template +void Env::DefaultFini(Env, T* data) { delete data; } @@ -579,22 +570,21 @@ void Env::DefaultFiniWithHint(Env, DataType* data, HintType*) { // Value class //////////////////////////////////////////////////////////////////////////////// -inline Value::Value() : _env(nullptr), _value(nullptr) { -} +inline Value::Value() : _env(nullptr), _value(nullptr) {} -inline Value::Value(napi_env env, napi_value value) : _env(env), _value(value) { -} +inline Value::Value(napi_env env, napi_value value) + : _env(env), _value(value) {} inline Value::operator napi_value() const { return _value; } -inline bool Value::operator ==(const Value& other) const { +inline bool Value::operator==(const Value& other) const { return StrictEquals(other); } -inline bool Value::operator !=(const Value& other) const { - return !this->operator ==(other); +inline bool Value::operator!=(const Value& other) const { + return !this->operator==(other); } inline bool Value::StrictEquals(const Value& other) const { @@ -788,11 +778,10 @@ inline Boolean Boolean::New(napi_env env, bool val) { return Boolean(env, value); } -inline Boolean::Boolean() : Napi::Value() { -} +inline Boolean::Boolean() : Napi::Value() {} -inline Boolean::Boolean(napi_env env, napi_value value) : Napi::Value(env, value) { -} +inline Boolean::Boolean(napi_env env, napi_value value) + : Napi::Value(env, value) {} inline Boolean::operator bool() const { return Value(); @@ -816,11 +805,9 @@ inline Number Number::New(napi_env env, double val) { return Number(env, value); } -inline Number::Number() : Value() { -} +inline Number::Number() : Value() {} -inline Number::Number(napi_env env, napi_value value) : Value(env, value) { -} +inline Number::Number(napi_env env, napi_value value) : Value(env, value) {} inline Number::operator int32_t() const { return Int32Value(); @@ -893,46 +880,50 @@ inline BigInt BigInt::New(napi_env env, uint64_t val) { return BigInt(env, value); } -inline BigInt BigInt::New(napi_env env, int sign_bit, size_t word_count, const uint64_t* words) { +inline BigInt BigInt::New(napi_env env, + int sign_bit, + size_t word_count, + const uint64_t* words) { napi_value value; - napi_status status = napi_create_bigint_words(env, sign_bit, word_count, words, &value); + napi_status status = + napi_create_bigint_words(env, sign_bit, word_count, words, &value); NAPI_THROW_IF_FAILED(env, status, BigInt()); return BigInt(env, value); } -inline BigInt::BigInt() : Value() { -} +inline BigInt::BigInt() : Value() {} -inline BigInt::BigInt(napi_env env, napi_value value) : Value(env, value) { -} +inline BigInt::BigInt(napi_env env, napi_value value) : Value(env, value) {} inline int64_t BigInt::Int64Value(bool* lossless) const { int64_t result; - napi_status status = napi_get_value_bigint_int64( - _env, _value, &result, lossless); + napi_status status = + napi_get_value_bigint_int64(_env, _value, &result, lossless); NAPI_THROW_IF_FAILED(_env, status, 0); return result; } inline uint64_t BigInt::Uint64Value(bool* lossless) const { uint64_t result; - napi_status status = napi_get_value_bigint_uint64( - _env, _value, &result, lossless); + napi_status status = + napi_get_value_bigint_uint64(_env, _value, &result, lossless); NAPI_THROW_IF_FAILED(_env, status, 0); return result; } inline size_t BigInt::WordCount() const { size_t word_count; - napi_status status = napi_get_value_bigint_words( - _env, _value, nullptr, &word_count, nullptr); + napi_status status = + napi_get_value_bigint_words(_env, _value, nullptr, &word_count, nullptr); NAPI_THROW_IF_FAILED(_env, status, 0); return word_count; } -inline void BigInt::ToWords(int* sign_bit, size_t* word_count, uint64_t* words) { - napi_status status = napi_get_value_bigint_words( - _env, _value, sign_bit, word_count, words); +inline void BigInt::ToWords(int* sign_bit, + size_t* word_count, + uint64_t* words) { + napi_status status = + napi_get_value_bigint_words(_env, _value, sign_bit, word_count, words); NAPI_THROW_IF_FAILED_VOID(_env, status); } #endif // NAPI_VERSION > 5 @@ -949,11 +940,9 @@ inline Date Date::New(napi_env env, double val) { return Date(env, value); } -inline Date::Date() : Value() { -} +inline Date::Date() : Value() {} -inline Date::Date(napi_env env, napi_value value) : Value(env, value) { -} +inline Date::Date(napi_env env, napi_value value) : Value(env, value) {} inline Date::operator double() const { return ValueOf(); @@ -961,8 +950,7 @@ inline Date::operator double() const { inline double Date::ValueOf() const { double result; - napi_status status = napi_get_date_value( - _env, _value, &result); + napi_status status = napi_get_date_value(_env, _value, &result); NAPI_THROW_IF_FAILED(_env, status, 0); return result; } @@ -972,11 +960,9 @@ inline double Date::ValueOf() const { // Name class //////////////////////////////////////////////////////////////////////////////// -inline Name::Name() : Value() { -} +inline Name::Name() : Value() {} -inline Name::Name(napi_env env, napi_value value) : Value(env, value) { -} +inline Name::Name(napi_env env, napi_value value) : Value(env, value) {} //////////////////////////////////////////////////////////////////////////////// // String class @@ -998,7 +984,8 @@ inline String String::New(napi_env env, const char* val) { NAPI_THROW_IF_FAILED(env, napi_invalid_arg, String()); } napi_value value; - napi_status status = napi_create_string_utf8(env, val, std::strlen(val), &value); + napi_status status = + napi_create_string_utf8(env, val, std::strlen(val), &value); NAPI_THROW_IF_FAILED(env, status, String()); return String(env, value); } @@ -1011,7 +998,8 @@ inline String String::New(napi_env env, const char16_t* val) { // Throw an error that looks like it came from core. NAPI_THROW_IF_FAILED(env, napi_invalid_arg, String()); } - napi_status status = napi_create_string_utf16(env, val, std::u16string(val).size(), &value); + napi_status status = + napi_create_string_utf16(env, val, std::u16string(val).size(), &value); NAPI_THROW_IF_FAILED(env, status, String()); return String(env, value); } @@ -1030,11 +1018,9 @@ inline String String::New(napi_env env, const char16_t* val, size_t length) { return String(env, value); } -inline String::String() : Name() { -} +inline String::String() : Name() {} -inline String::String(napi_env env, napi_value value) : Name(env, value) { -} +inline String::String(napi_env env, napi_value value) : Name(env, value) {} inline String::operator std::string() const { return Utf8Value(); @@ -1046,26 +1032,30 @@ inline String::operator std::u16string() const { inline std::string String::Utf8Value() const { size_t length; - napi_status status = napi_get_value_string_utf8(_env, _value, nullptr, 0, &length); + napi_status status = + napi_get_value_string_utf8(_env, _value, nullptr, 0, &length); NAPI_THROW_IF_FAILED(_env, status, ""); std::string value; value.reserve(length + 1); value.resize(length); - status = napi_get_value_string_utf8(_env, _value, &value[0], value.capacity(), nullptr); + status = napi_get_value_string_utf8( + _env, _value, &value[0], value.capacity(), nullptr); NAPI_THROW_IF_FAILED(_env, status, ""); return value; } inline std::u16string String::Utf16Value() const { size_t length; - napi_status status = napi_get_value_string_utf16(_env, _value, nullptr, 0, &length); + napi_status status = + napi_get_value_string_utf16(_env, _value, nullptr, 0, &length); NAPI_THROW_IF_FAILED(_env, status, NAPI_WIDE_TEXT("")); std::u16string value; value.reserve(length + 1); value.resize(length); - status = napi_get_value_string_utf16(_env, _value, &value[0], value.capacity(), nullptr); + status = napi_get_value_string_utf16( + _env, _value, &value[0], value.capacity(), nullptr); NAPI_THROW_IF_FAILED(_env, status, NAPI_WIDE_TEXT("")); return value; } @@ -1075,8 +1065,9 @@ inline std::u16string String::Utf16Value() const { //////////////////////////////////////////////////////////////////////////////// inline Symbol Symbol::New(napi_env env, const char* description) { - napi_value descriptionValue = description != nullptr ? - String::New(env, description) : static_cast(nullptr); + napi_value descriptionValue = description != nullptr + ? String::New(env, description) + : static_cast(nullptr); return Symbol::New(env, descriptionValue); } @@ -1108,7 +1099,12 @@ inline MaybeOrValue Symbol::WellKnown(napi_env env, } return Nothing(); #else - return Napi::Env(env).Global().Get("Symbol").As().Get(name).As(); + return Napi::Env(env) + .Global() + .Get("Symbol") + .As() + .Get(name) + .As(); #endif } @@ -1149,11 +1145,9 @@ inline MaybeOrValue Symbol::For(napi_env env, napi_value description) { #endif } -inline Symbol::Symbol() : Name() { -} +inline Symbol::Symbol() : Name() {} -inline Symbol::Symbol(napi_env env, napi_value value) : Name(env, value) { -} +inline Symbol::Symbol(napi_env env, napi_value value) : Name(env, value) {} //////////////////////////////////////////////////////////////////////////////// // Automagic value creation @@ -1167,7 +1161,7 @@ struct vf_number { } }; -template<> +template <> struct vf_number { static Boolean From(napi_env env, bool value) { return Boolean::New(env, value); @@ -1199,36 +1193,33 @@ struct vf_utf16_string { template struct vf_fallback { - static Value From(napi_env env, const T& value) { - return Value(env, value); - } + static Value From(napi_env env, const T& value) { return Value(env, value); } }; -template struct disjunction : std::false_type {}; -template struct disjunction : B {}; +template +struct disjunction : std::false_type {}; +template +struct disjunction : B {}; template struct disjunction : std::conditional>::type {}; template struct can_make_string - : disjunction::type, - typename std::is_convertible::type, + : disjunction::type, + typename std::is_convertible::type, typename std::is_convertible::type, typename std::is_convertible::type> {}; -} +} // namespace details template Value Value::From(napi_env env, const T& value) { using Helper = typename std::conditional< - std::is_integral::value || std::is_floating_point::value, - details::vf_number, - typename std::conditional< - details::can_make_string::value, - String, - details::vf_fallback - >::type - >::type; + std::is_integral::value || std::is_floating_point::value, + details::vf_number, + typename std::conditional::value, + String, + details::vf_fallback>::type>::type; return Helper::From(env, value); } @@ -1236,22 +1227,18 @@ template String String::From(napi_env env, const T& value) { struct Dummy {}; using Helper = typename std::conditional< - std::is_convertible::value, - details::vf_utf8_charp, - typename std::conditional< - std::is_convertible::value, - details::vf_utf16_charp, + std::is_convertible::value, + details::vf_utf8_charp, typename std::conditional< - std::is_convertible::value, - details::vf_utf8_string, - typename std::conditional< - std::is_convertible::value, - details::vf_utf16_string, - Dummy - >::type - >::type - >::type - >::type; + std::is_convertible::value, + details::vf_utf16_charp, + typename std::conditional< + std::is_convertible::value, + details::vf_utf8_string, + typename std::conditional< + std::is_convertible::value, + details::vf_utf16_string, + Dummy>::type>::type>::type>::type; return Helper::From(env, value); } @@ -1269,8 +1256,10 @@ inline Object::PropertyLValue::operator Value() const { #endif } -template template -inline Object::PropertyLValue& Object::PropertyLValue::operator =(ValueType value) { +template +template +inline Object::PropertyLValue& Object::PropertyLValue::operator=( + ValueType value) { #ifdef NODE_ADDON_API_ENABLE_MAYBE MaybeOrValue result = #endif @@ -1283,7 +1272,7 @@ inline Object::PropertyLValue& Object::PropertyLValue::operator =(Valu template inline Object::PropertyLValue::PropertyLValue(Object object, Key key) - : _env(object.Env()), _object(object), _key(key) {} + : _env(object.Env()), _object(object), _key(key) {} inline Object Object::New(napi_env env) { napi_value value; @@ -1292,11 +1281,9 @@ inline Object Object::New(napi_env env) { return Object(env, value); } -inline Object::Object() : Value() { -} +inline Object::Object() : Value() {} -inline Object::Object(napi_env env, napi_value value) : Value(env, value) { -} +inline Object::Object(napi_env env, napi_value value) : Value(env, value) {} inline Object::PropertyLValue Object::operator[]( const char* utf8name) { @@ -1365,7 +1352,8 @@ inline MaybeOrValue Object::HasOwnProperty(Value key) const { inline MaybeOrValue Object::HasOwnProperty(const char* utf8name) const { napi_value key; - napi_status status = napi_create_string_utf8(_env, utf8name, std::strlen(utf8name), &key); + napi_status status = + napi_create_string_utf8(_env, utf8name, std::strlen(utf8name), &key); NAPI_MAYBE_THROW_IF_FAILED(_env, status, bool); return HasOwnProperty(key); } @@ -1480,22 +1468,31 @@ inline MaybeOrValue Object::GetPropertyNames() const { inline MaybeOrValue Object::DefineProperty( const PropertyDescriptor& property) const { - napi_status status = napi_define_properties(_env, _value, 1, - reinterpret_cast(&property)); + napi_status status = napi_define_properties( + _env, + _value, + 1, + reinterpret_cast(&property)); NAPI_RETURN_OR_THROW_IF_FAILED(_env, status, status == napi_ok, bool); } inline MaybeOrValue Object::DefineProperties( const std::initializer_list& properties) const { - napi_status status = napi_define_properties(_env, _value, properties.size(), - reinterpret_cast(properties.begin())); + napi_status status = napi_define_properties( + _env, + _value, + properties.size(), + reinterpret_cast(properties.begin())); NAPI_RETURN_OR_THROW_IF_FAILED(_env, status, status == napi_ok, bool); } inline MaybeOrValue Object::DefineProperties( const std::vector& properties) const { - napi_status status = napi_define_properties(_env, _value, properties.size(), - reinterpret_cast(properties.data())); + napi_status status = napi_define_properties( + _env, + _value, + properties.size(), + reinterpret_cast(properties.data())); NAPI_RETURN_OR_THROW_IF_FAILED(_env, status, status == napi_ok, bool); } @@ -1530,12 +1527,12 @@ inline void Object::AddFinalizer(Finalizer finalizeCallback, details::FinalizeData* finalizeData = new details::FinalizeData( {std::move(finalizeCallback), finalizeHint}); - napi_status status = - details::AttachData(_env, - *this, - data, - details::FinalizeData::WrapperWithHint, - finalizeData); + napi_status status = details::AttachData( + _env, + *this, + data, + details::FinalizeData::WrapperWithHint, + finalizeData); if (status != napi_ok) { delete finalizeData; NAPI_THROW_IF_FAILED_VOID(_env, status); @@ -1638,7 +1635,8 @@ inline MaybeOrValue Object::Seal() const { template inline External External::New(napi_env env, T* data) { napi_value value; - napi_status status = napi_create_external(env, data, nullptr, nullptr, &value); + napi_status status = + napi_create_external(env, data, nullptr, nullptr, &value); NAPI_THROW_IF_FAILED(env, status, External()); return External(env, value); } @@ -1652,12 +1650,12 @@ inline External External::New(napi_env env, details::FinalizeData* finalizeData = new details::FinalizeData( {std::move(finalizeCallback), nullptr}); - napi_status status = napi_create_external( - env, - data, - details::FinalizeData::Wrapper, - finalizeData, - &value); + napi_status status = + napi_create_external(env, + data, + details::FinalizeData::Wrapper, + finalizeData, + &value); if (status != napi_ok) { delete finalizeData; NAPI_THROW_IF_FAILED(env, status, External()); @@ -1676,11 +1674,11 @@ inline External External::New(napi_env env, new details::FinalizeData( {std::move(finalizeCallback), finalizeHint}); napi_status status = napi_create_external( - env, - data, - details::FinalizeData::WrapperWithHint, - finalizeData, - &value); + env, + data, + details::FinalizeData::WrapperWithHint, + finalizeData, + &value); if (status != napi_ok) { delete finalizeData; NAPI_THROW_IF_FAILED(env, status, External()); @@ -1689,12 +1687,11 @@ inline External External::New(napi_env env, } template -inline External::External() : Value() { -} +inline External::External() : Value() {} template -inline External::External(napi_env env, napi_value value) : Value(env, value) { -} +inline External::External(napi_env env, napi_value value) + : Value(env, value) {} template inline T* External::Data() const { @@ -1722,11 +1719,9 @@ inline Array Array::New(napi_env env, size_t length) { return Array(env, value); } -inline Array::Array() : Object() { -} +inline Array::Array() : Object() {} -inline Array::Array(napi_env env, napi_value value) : Object(env, value) { -} +inline Array::Array(napi_env env, napi_value value) : Object(env, value) {} inline uint32_t Array::Length() const { uint32_t result; @@ -1753,7 +1748,7 @@ inline ArrayBuffer ArrayBuffer::New(napi_env env, size_t byteLength) { napi_value value; napi_status status = napi_create_external_arraybuffer( - env, externalData, byteLength, nullptr, nullptr, &value); + env, externalData, byteLength, nullptr, nullptr, &value); NAPI_THROW_IF_FAILED(env, status, ArrayBuffer()); return ArrayBuffer(env, value); @@ -1769,12 +1764,12 @@ inline ArrayBuffer ArrayBuffer::New(napi_env env, new details::FinalizeData( {std::move(finalizeCallback), nullptr}); napi_status status = napi_create_external_arraybuffer( - env, - externalData, - byteLength, - details::FinalizeData::Wrapper, - finalizeData, - &value); + env, + externalData, + byteLength, + details::FinalizeData::Wrapper, + finalizeData, + &value); if (status != napi_ok) { delete finalizeData; NAPI_THROW_IF_FAILED(env, status, ArrayBuffer()); @@ -1794,12 +1789,12 @@ inline ArrayBuffer ArrayBuffer::New(napi_env env, new details::FinalizeData( {std::move(finalizeCallback), finalizeHint}); napi_status status = napi_create_external_arraybuffer( - env, - externalData, - byteLength, - details::FinalizeData::WrapperWithHint, - finalizeData, - &value); + env, + externalData, + byteLength, + details::FinalizeData::WrapperWithHint, + finalizeData, + &value); if (status != napi_ok) { delete finalizeData; NAPI_THROW_IF_FAILED(env, status, ArrayBuffer()); @@ -1808,12 +1803,10 @@ inline ArrayBuffer ArrayBuffer::New(napi_env env, return ArrayBuffer(env, value); } -inline ArrayBuffer::ArrayBuffer() : Object() { -} +inline ArrayBuffer::ArrayBuffer() : Object() {} inline ArrayBuffer::ArrayBuffer(napi_env env, napi_value value) - : Object(env, value) { -} + : Object(env, value) {} inline void* ArrayBuffer::Data() { void* data; @@ -1824,7 +1817,8 @@ inline void* ArrayBuffer::Data() { inline size_t ArrayBuffer::ByteLength() { size_t length; - napi_status status = napi_get_arraybuffer_info(_env, _value, nullptr, &length); + napi_status status = + napi_get_arraybuffer_info(_env, _value, nullptr, &length); NAPI_THROW_IF_FAILED(_env, status, 0); return length; } @@ -1846,8 +1840,7 @@ inline void ArrayBuffer::Detach() { //////////////////////////////////////////////////////////////////////////////// // DataView class //////////////////////////////////////////////////////////////////////////////// -inline DataView DataView::New(napi_env env, - Napi::ArrayBuffer arrayBuffer) { +inline DataView DataView::New(napi_env env, Napi::ArrayBuffer arrayBuffer) { return New(env, arrayBuffer, 0, arrayBuffer.ByteLength()); } @@ -1855,12 +1848,12 @@ inline DataView DataView::New(napi_env env, Napi::ArrayBuffer arrayBuffer, size_t byteOffset) { if (byteOffset > arrayBuffer.ByteLength()) { - NAPI_THROW(RangeError::New(env, - "Start offset is outside the bounds of the buffer"), - DataView()); + NAPI_THROW(RangeError::New( + env, "Start offset is outside the bounds of the buffer"), + DataView()); } - return New(env, arrayBuffer, byteOffset, - arrayBuffer.ByteLength() - byteOffset); + return New( + env, arrayBuffer, byteOffset, arrayBuffer.ByteLength() - byteOffset); } inline DataView DataView::New(napi_env env, @@ -1868,52 +1861,47 @@ inline DataView DataView::New(napi_env env, size_t byteOffset, size_t byteLength) { if (byteOffset + byteLength > arrayBuffer.ByteLength()) { - NAPI_THROW(RangeError::New(env, "Invalid DataView length"), - DataView()); + NAPI_THROW(RangeError::New(env, "Invalid DataView length"), DataView()); } napi_value value; - napi_status status = napi_create_dataview( - env, byteLength, arrayBuffer, byteOffset, &value); + napi_status status = + napi_create_dataview(env, byteLength, arrayBuffer, byteOffset, &value); NAPI_THROW_IF_FAILED(env, status, DataView()); return DataView(env, value); } -inline DataView::DataView() : Object() { -} +inline DataView::DataView() : Object() {} inline DataView::DataView(napi_env env, napi_value value) : Object(env, value) { - napi_status status = napi_get_dataview_info( - _env, - _value /* dataView */, - &_length /* byteLength */, - &_data /* data */, - nullptr /* arrayBuffer */, - nullptr /* byteOffset */); + napi_status status = napi_get_dataview_info(_env, + _value /* dataView */, + &_length /* byteLength */, + &_data /* data */, + nullptr /* arrayBuffer */, + nullptr /* byteOffset */); NAPI_THROW_IF_FAILED_VOID(_env, status); } inline Napi::ArrayBuffer DataView::ArrayBuffer() const { napi_value arrayBuffer; - napi_status status = napi_get_dataview_info( - _env, - _value /* dataView */, - nullptr /* byteLength */, - nullptr /* data */, - &arrayBuffer /* arrayBuffer */, - nullptr /* byteOffset */); + napi_status status = napi_get_dataview_info(_env, + _value /* dataView */, + nullptr /* byteLength */, + nullptr /* data */, + &arrayBuffer /* arrayBuffer */, + nullptr /* byteOffset */); NAPI_THROW_IF_FAILED(_env, status, Napi::ArrayBuffer()); return Napi::ArrayBuffer(_env, arrayBuffer); } inline size_t DataView::ByteOffset() const { size_t byteOffset; - napi_status status = napi_get_dataview_info( - _env, - _value /* dataView */, - nullptr /* byteLength */, - nullptr /* data */, - nullptr /* arrayBuffer */, - &byteOffset /* byteOffset */); + napi_status status = napi_get_dataview_info(_env, + _value /* dataView */, + nullptr /* byteLength */, + nullptr /* data */, + nullptr /* arrayBuffer */, + &byteOffset /* byteOffset */); NAPI_THROW_IF_FAILED(_env, status, 0); return byteOffset; } @@ -1994,8 +1982,9 @@ template inline T DataView::ReadData(size_t byteOffset) const { if (byteOffset + sizeof(T) > _length || byteOffset + sizeof(T) < byteOffset) { // overflow - NAPI_THROW(RangeError::New(_env, - "Offset is outside the bounds of the DataView"), 0); + NAPI_THROW( + RangeError::New(_env, "Offset is outside the bounds of the DataView"), + 0); } return *reinterpret_cast(static_cast(_data) + byteOffset); @@ -2005,8 +1994,8 @@ template inline void DataView::WriteData(size_t byteOffset, T value) const { if (byteOffset + sizeof(T) > _length || byteOffset + sizeof(T) < byteOffset) { // overflow - NAPI_THROW_VOID(RangeError::New(_env, - "Offset is outside the bounds of the DataView")); + NAPI_THROW_VOID( + RangeError::New(_env, "Offset is outside the bounds of the DataView")); } *reinterpret_cast(static_cast(_data) + byteOffset) = value; @@ -2017,33 +2006,37 @@ inline void DataView::WriteData(size_t byteOffset, T value) const { //////////////////////////////////////////////////////////////////////////////// inline TypedArray::TypedArray() - : Object(), _type(TypedArray::unknown_array_type), _length(0) { -} + : Object(), _type(napi_typedarray_type::napi_int8_array), _length(0) {} inline TypedArray::TypedArray(napi_env env, napi_value value) - : Object(env, value), _type(TypedArray::unknown_array_type), _length(0) { + : Object(env, value), + _type(napi_typedarray_type::napi_int8_array), + _length(0) { + if (value != nullptr) { + napi_status status = + napi_get_typedarray_info(_env, + _value, + &const_cast(this)->_type, + &const_cast(this)->_length, + nullptr, + nullptr, + nullptr); + NAPI_THROW_IF_FAILED_VOID(_env, status); + } } inline TypedArray::TypedArray(napi_env env, napi_value value, napi_typedarray_type type, size_t length) - : Object(env, value), _type(type), _length(length) { -} + : Object(env, value), _type(type), _length(length) {} inline napi_typedarray_type TypedArray::TypedArrayType() const { - if (_type == TypedArray::unknown_array_type) { - napi_status status = napi_get_typedarray_info(_env, _value, - &const_cast(this)->_type, &const_cast(this)->_length, - nullptr, nullptr, nullptr); - NAPI_THROW_IF_FAILED(_env, status, napi_int8_array); - } - return _type; } inline uint8_t TypedArray::ElementSize() const { - switch (TypedArrayType()) { + switch (_type) { case napi_int8_array: case napi_uint8_array: case napi_uint8_clamped_array: @@ -2067,20 +2060,13 @@ inline uint8_t TypedArray::ElementSize() const { } inline size_t TypedArray::ElementLength() const { - if (_type == TypedArray::unknown_array_type) { - napi_status status = napi_get_typedarray_info(_env, _value, - &const_cast(this)->_type, &const_cast(this)->_length, - nullptr, nullptr, nullptr); - NAPI_THROW_IF_FAILED(_env, status, 0); - } - return _length; } inline size_t TypedArray::ByteOffset() const { size_t byteOffset; napi_status status = napi_get_typedarray_info( - _env, _value, nullptr, nullptr, nullptr, nullptr, &byteOffset); + _env, _value, nullptr, nullptr, nullptr, nullptr, &byteOffset); NAPI_THROW_IF_FAILED(_env, status, 0); return byteOffset; } @@ -2092,7 +2078,7 @@ inline size_t TypedArray::ByteLength() const { inline Napi::ArrayBuffer TypedArray::ArrayBuffer() const { napi_value arrayBuffer; napi_status status = napi_get_typedarray_info( - _env, _value, nullptr, nullptr, nullptr, &arrayBuffer, nullptr); + _env, _value, nullptr, nullptr, nullptr, &arrayBuffer, nullptr); NAPI_THROW_IF_FAILED(_env, status, Napi::ArrayBuffer()); return Napi::ArrayBuffer(_env, arrayBuffer); } @@ -2105,7 +2091,8 @@ template inline TypedArrayOf TypedArrayOf::New(napi_env env, size_t elementLength, napi_typedarray_type type) { - Napi::ArrayBuffer arrayBuffer = Napi::ArrayBuffer::New(env, elementLength * sizeof (T)); + Napi::ArrayBuffer arrayBuffer = + Napi::ArrayBuffer::New(env, elementLength * sizeof(T)); return New(env, elementLength, arrayBuffer, 0, type); } @@ -2117,21 +2104,24 @@ inline TypedArrayOf TypedArrayOf::New(napi_env env, napi_typedarray_type type) { napi_value value; napi_status status = napi_create_typedarray( - env, type, elementLength, arrayBuffer, bufferOffset, &value); + env, type, elementLength, arrayBuffer, bufferOffset, &value); NAPI_THROW_IF_FAILED(env, status, TypedArrayOf()); return TypedArrayOf( - env, value, type, elementLength, - reinterpret_cast(reinterpret_cast(arrayBuffer.Data()) + bufferOffset)); + env, + value, + type, + elementLength, + reinterpret_cast(reinterpret_cast(arrayBuffer.Data()) + + bufferOffset)); } template -inline TypedArrayOf::TypedArrayOf() : TypedArray(), _data(nullptr) { -} +inline TypedArrayOf::TypedArrayOf() : TypedArray(), _data(nullptr) {} template inline TypedArrayOf::TypedArrayOf(napi_env env, napi_value value) - : TypedArray(env, value), _data(nullptr) { + : TypedArray(env, value), _data(nullptr) { napi_status status = napi_ok; if (value != nullptr) { void* data = nullptr; @@ -2151,21 +2141,24 @@ inline TypedArrayOf::TypedArrayOf(napi_env env, napi_typedarray_type type, size_t length, T* data) - : TypedArray(env, value, type, length), _data(data) { + : TypedArray(env, value, type, length), _data(data) { if (!(type == TypedArrayTypeForPrimitiveType() || - (type == napi_uint8_clamped_array && std::is_same::value))) { - NAPI_THROW_VOID(TypeError::New(env, "Array type must match the template parameter. " - "(Uint8 arrays may optionally have the \"clamped\" array type.)")); + (type == napi_uint8_clamped_array && + std::is_same::value))) { + NAPI_THROW_VOID(TypeError::New( + env, + "Array type must match the template parameter. " + "(Uint8 arrays may optionally have the \"clamped\" array type.)")); } } template -inline T& TypedArrayOf::operator [](size_t index) { +inline T& TypedArrayOf::operator[](size_t index) { return _data[index]; } template -inline const T& TypedArrayOf::operator [](size_t index) const { +inline const T& TypedArrayOf::operator[](size_t index) const { return _data[index]; } @@ -2184,12 +2177,11 @@ inline const T* TypedArrayOf::Data() const { //////////////////////////////////////////////////////////////////////////////// template -static inline napi_status -CreateFunction(napi_env env, - const char* utf8name, - napi_callback cb, - CbData* data, - napi_value* result) { +inline napi_status CreateFunction(napi_env env, + const char* utf8name, + napi_callback cb, + CbData* data, + napi_value* result) { napi_status status = napi_create_function(env, utf8name, NAPI_AUTO_LENGTH, cb, data, result); if (status == napi_ok) { @@ -2249,11 +2241,8 @@ inline Function Function::New(napi_env env, auto callbackData = new CbData{std::move(cb), data}; napi_value value; - napi_status status = CreateFunction(env, - utf8name, - CbData::Wrapper, - callbackData, - &value); + napi_status status = + CreateFunction(env, utf8name, CbData::Wrapper, callbackData, &value); if (status != napi_ok) { delete callbackData; NAPI_THROW_IF_FAILED(env, status, Function()); @@ -2270,11 +2259,10 @@ inline Function Function::New(napi_env env, return New(env, cb, utf8name.c_str(), data); } -inline Function::Function() : Object() { -} +inline Function::Function() : Object() {} -inline Function::Function(napi_env env, napi_value value) : Object(env, value) { -} +inline Function::Function(napi_env env, napi_value value) + : Object(env, value) {} inline MaybeOrValue Function::operator()( const std::initializer_list& args) const { @@ -2336,8 +2324,8 @@ inline MaybeOrValue Function::Call(napi_value recv, size_t argc, const napi_value* args) const { napi_value result; - napi_status status = napi_call_function( - _env, recv, _value, argc, args, &result); + napi_status status = + napi_call_function(_env, recv, _value, argc, args, &result); NAPI_RETURN_OR_THROW_IF_FAILED( _env, status, Napi::Value(_env, result), Napi::Value); } @@ -2362,8 +2350,8 @@ inline MaybeOrValue Function::MakeCallback( const napi_value* args, napi_async_context context) const { napi_value result; - napi_status status = napi_make_callback( - _env, context, recv, _value, argc, args, &result); + napi_status status = + napi_make_callback(_env, context, recv, _value, argc, args, &result); NAPI_RETURN_OR_THROW_IF_FAILED( _env, status, Napi::Value(_env, result), Napi::Value); } @@ -2381,8 +2369,7 @@ inline MaybeOrValue Function::New( inline MaybeOrValue Function::New(size_t argc, const napi_value* args) const { napi_value result; - napi_status status = napi_new_instance( - _env, _value, argc, args, &result); + napi_status status = napi_new_instance(_env, _value, argc, args, &result); NAPI_RETURN_OR_THROW_IF_FAILED( _env, status, Napi::Object(_env, result), Napi::Object); } @@ -2418,8 +2405,7 @@ inline void Promise::Deferred::Reject(napi_value value) const { NAPI_THROW_IF_FAILED_VOID(_env, status); } -inline Promise::Promise(napi_env env, napi_value value) : Object(env, value) { -} +inline Promise::Promise(napi_env env, napi_value value) : Object(env, value) {} //////////////////////////////////////////////////////////////////////////////// // Buffer class @@ -2429,7 +2415,8 @@ template inline Buffer Buffer::New(napi_env env, size_t length) { napi_value value; void* data; - napi_status status = napi_create_buffer(env, length * sizeof (T), &data, &value); + napi_status status = + napi_create_buffer(env, length * sizeof(T), &data, &value); NAPI_THROW_IF_FAILED(env, status, Buffer()); return Buffer(env, value, length, static_cast(data)); } @@ -2438,7 +2425,7 @@ template inline Buffer Buffer::New(napi_env env, T* data, size_t length) { napi_value value; napi_status status = napi_create_external_buffer( - env, length * sizeof (T), data, nullptr, nullptr, &value); + env, length * sizeof(T), data, nullptr, nullptr, &value); NAPI_THROW_IF_FAILED(env, status, Buffer()); return Buffer(env, value, length, data); } @@ -2453,13 +2440,13 @@ inline Buffer Buffer::New(napi_env env, details::FinalizeData* finalizeData = new details::FinalizeData( {std::move(finalizeCallback), nullptr}); - napi_status status = napi_create_external_buffer( - env, - length * sizeof (T), - data, - details::FinalizeData::Wrapper, - finalizeData, - &value); + napi_status status = + napi_create_external_buffer(env, + length * sizeof(T), + data, + details::FinalizeData::Wrapper, + finalizeData, + &value); if (status != napi_ok) { delete finalizeData; NAPI_THROW_IF_FAILED(env, status, Buffer()); @@ -2479,12 +2466,12 @@ inline Buffer Buffer::New(napi_env env, new details::FinalizeData( {std::move(finalizeCallback), finalizeHint}); napi_status status = napi_create_external_buffer( - env, - length * sizeof (T), - data, - details::FinalizeData::WrapperWithHint, - finalizeData, - &value); + env, + length * sizeof(T), + data, + details::FinalizeData::WrapperWithHint, + finalizeData, + &value); if (status != napi_ok) { delete finalizeData; NAPI_THROW_IF_FAILED(env, status, Buffer()); @@ -2495,25 +2482,22 @@ inline Buffer Buffer::New(napi_env env, template inline Buffer Buffer::Copy(napi_env env, const T* data, size_t length) { napi_value value; - napi_status status = napi_create_buffer_copy( - env, length * sizeof (T), data, nullptr, &value); + napi_status status = + napi_create_buffer_copy(env, length * sizeof(T), data, nullptr, &value); NAPI_THROW_IF_FAILED(env, status, Buffer()); return Buffer(env, value); } template -inline Buffer::Buffer() : Uint8Array(), _length(0), _data(nullptr) { -} +inline Buffer::Buffer() : Uint8Array(), _length(0), _data(nullptr) {} template inline Buffer::Buffer(napi_env env, napi_value value) - : Uint8Array(env, value), _length(0), _data(nullptr) { -} + : Uint8Array(env, value), _length(0), _data(nullptr) {} template inline Buffer::Buffer(napi_env env, napi_value value, size_t length, T* data) - : Uint8Array(env, value), _length(length), _data(data) { -} + : Uint8Array(env, value), _length(length), _data(data) {} template inline size_t Buffer::Length() const { @@ -2535,9 +2519,10 @@ inline void Buffer::EnsureInfo() const { if (_data == nullptr) { size_t byteLength; void* voidData; - napi_status status = napi_get_buffer_info(_env, _value, &voidData, &byteLength); + napi_status status = + napi_get_buffer_info(_env, _value, &voidData, &byteLength); NAPI_THROW_IF_FAILED_VOID(_env, status); - _length = byteLength / sizeof (T); + _length = byteLength / sizeof(T); _data = static_cast(voidData); } } @@ -2574,19 +2559,16 @@ inline Error Error::New(napi_env env) { // A pending exception takes precedence over any internal error status. if (is_exception_pending) { status = napi_get_and_clear_last_exception(env, &error); - NAPI_FATAL_IF_FAILED(status, "Error::New", "napi_get_and_clear_last_exception"); - } - else { + NAPI_FATAL_IF_FAILED( + status, "Error::New", "napi_get_and_clear_last_exception"); + } else { const char* error_message = last_error_info_copy.error_message != nullptr ? last_error_info_copy.error_message : "Error in native callback"; napi_value message; status = napi_create_string_utf8( - env, - error_message, - std::strlen(error_message), - &message); + env, error_message, std::strlen(error_message), &message); NAPI_FATAL_IF_FAILED(status, "Error::New", "napi_create_string_utf8"); switch (last_error_info_copy.error_code) { @@ -2607,21 +2589,24 @@ inline Error Error::New(napi_env env) { } inline Error Error::New(napi_env env, const char* message) { - return Error::New(env, message, std::strlen(message), napi_create_error); + return Error::New( + env, message, std::strlen(message), napi_create_error); } inline Error Error::New(napi_env env, const std::string& message) { - return Error::New(env, message.c_str(), message.size(), napi_create_error); + return Error::New( + env, message.c_str(), message.size(), napi_create_error); } -inline NAPI_NO_RETURN void Error::Fatal(const char* location, const char* message) { +inline NAPI_NO_RETURN void Error::Fatal(const char* location, + const char* message) { napi_fatal_error(location, NAPI_AUTO_LENGTH, message, NAPI_AUTO_LENGTH); } -inline Error::Error() : ObjectReference() { -} +inline Error::Error() : ObjectReference() {} -inline Error::Error(napi_env env, napi_value value) : ObjectReference(env, nullptr) { +inline Error::Error(napi_env env, napi_value value) + : ObjectReference(env, nullptr) { if (value != nullptr) { // Attempting to create a reference on the error object. // If it's not a Object/Function/Symbol, this call will return an error @@ -2699,18 +2684,16 @@ inline Object Error::Value() const { return Object(_env, refValue); } -inline Error::Error(Error&& other) : ObjectReference(std::move(other)) { -} +inline Error::Error(Error&& other) : ObjectReference(std::move(other)) {} -inline Error& Error::operator =(Error&& other) { +inline Error& Error::operator=(Error&& other) { static_cast*>(this)->operator=(std::move(other)); return *this; } -inline Error::Error(const Error& other) : ObjectReference(other) { -} +inline Error::Error(const Error& other) : ObjectReference(other) {} -inline Error& Error::operator =(const Error& other) { +inline Error& Error::operator=(const Error& other) { Reset(); _env = other.Env(); @@ -2730,12 +2713,11 @@ inline const std::string& Error::Message() const NAPI_NOEXCEPT { #ifdef NAPI_CPP_EXCEPTIONS try { _message = Get("message").As(); - } - catch (...) { + } catch (...) { // Catch all errors here, to include e.g. a std::bad_alloc from // the std::string::operator=, because this method may not throw. } -#else // NAPI_CPP_EXCEPTIONS +#else // NAPI_CPP_EXCEPTIONS #if defined(NODE_ADDON_API_ENABLE_MAYBE) Napi::Value message_val; if (Get("message").UnwrapTo(&message_val)) { @@ -2744,7 +2726,7 @@ inline const std::string& Error::Message() const NAPI_NOEXCEPT { #else _message = Get("message").As(); #endif -#endif // NAPI_CPP_EXCEPTIONS +#endif // NAPI_CPP_EXCEPTIONS } return _message; } @@ -2790,9 +2772,10 @@ inline void Error::ThrowAsJavaScriptException() const { if (status != napi_ok) { throw Error::New(_env); } -#else // NAPI_CPP_EXCEPTIONS - NAPI_FATAL_IF_FAILED(status, "Error::ThrowAsJavaScriptException", "napi_throw"); -#endif // NAPI_CPP_EXCEPTIONS +#else // NAPI_CPP_EXCEPTIONS + NAPI_FATAL_IF_FAILED( + status, "Error::ThrowAsJavaScriptException", "napi_throw"); +#endif // NAPI_CPP_EXCEPTIONS } } @@ -2802,7 +2785,7 @@ inline const char* Error::what() const NAPI_NOEXCEPT { return Message().c_str(); } -#endif // NAPI_CPP_EXCEPTIONS +#endif // NAPI_CPP_EXCEPTIONS inline const char* Error::ERROR_WRAP_VALUE() NAPI_NOEXCEPT { return "4bda9e7e-4913-4dbc-95de-891cbf66598e-errorVal"; @@ -2825,39 +2808,42 @@ inline TError Error::New(napi_env env, } inline TypeError TypeError::New(napi_env env, const char* message) { - return Error::New(env, message, std::strlen(message), napi_create_type_error); + return Error::New( + env, message, std::strlen(message), napi_create_type_error); } inline TypeError TypeError::New(napi_env env, const std::string& message) { - return Error::New(env, message.c_str(), message.size(), napi_create_type_error); + return Error::New( + env, message.c_str(), message.size(), napi_create_type_error); } -inline TypeError::TypeError() : Error() { -} +inline TypeError::TypeError() : Error() {} -inline TypeError::TypeError(napi_env env, napi_value value) : Error(env, value) { -} +inline TypeError::TypeError(napi_env env, napi_value value) + : Error(env, value) {} inline RangeError RangeError::New(napi_env env, const char* message) { - return Error::New(env, message, std::strlen(message), napi_create_range_error); + return Error::New( + env, message, std::strlen(message), napi_create_range_error); } inline RangeError RangeError::New(napi_env env, const std::string& message) { - return Error::New(env, message.c_str(), message.size(), napi_create_range_error); + return Error::New( + env, message.c_str(), message.size(), napi_create_range_error); } -inline RangeError::RangeError() : Error() { -} +inline RangeError::RangeError() : Error() {} -inline RangeError::RangeError(napi_env env, napi_value value) : Error(env, value) { -} +inline RangeError::RangeError(napi_env env, napi_value value) + : Error(env, value) {} //////////////////////////////////////////////////////////////////////////////// // Reference class //////////////////////////////////////////////////////////////////////////////// template -inline Reference Reference::New(const T& value, uint32_t initialRefcount) { +inline Reference Reference::New(const T& value, + uint32_t initialRefcount) { napi_env env = value.Env(); napi_value val = value; @@ -2872,15 +2858,13 @@ inline Reference Reference::New(const T& value, uint32_t initialRefcount) return Reference(env, ref); } - template -inline Reference::Reference() : _env(nullptr), _ref(nullptr), _suppressDestruct(false) { -} +inline Reference::Reference() + : _env(nullptr), _ref(nullptr), _suppressDestruct(false) {} template inline Reference::Reference(napi_env env, napi_ref ref) - : _env(env), _ref(ref), _suppressDestruct(false) { -} + : _env(env), _ref(ref), _suppressDestruct(false) {} template inline Reference::~Reference() { @@ -2895,14 +2879,16 @@ inline Reference::~Reference() { template inline Reference::Reference(Reference&& other) - : _env(other._env), _ref(other._ref), _suppressDestruct(other._suppressDestruct) { + : _env(other._env), + _ref(other._ref), + _suppressDestruct(other._suppressDestruct) { other._env = nullptr; other._ref = nullptr; other._suppressDestruct = false; } template -inline Reference& Reference::operator =(Reference&& other) { +inline Reference& Reference::operator=(Reference&& other) { Reset(); _env = other._env; _ref = other._ref; @@ -2915,15 +2901,17 @@ inline Reference& Reference::operator =(Reference&& other) { template inline Reference::Reference(const Reference& other) - : _env(other._env), _ref(nullptr), _suppressDestruct(false) { + : _env(other._env), _ref(nullptr), _suppressDestruct(false) { HandleScope scope(_env); napi_value value = other.Value(); if (value != nullptr) { - // Copying is a limited scenario (currently only used for Error object) and always creates a - // strong reference to the given value even if the incoming reference is weak. + // Copying is a limited scenario (currently only used for Error object) and + // always creates a strong reference to the given value even if the incoming + // reference is weak. napi_status status = napi_create_reference(_env, value, 1, &_ref); - NAPI_FATAL_IF_FAILED(status, "Reference::Reference", "napi_create_reference"); + NAPI_FATAL_IF_FAILED( + status, "Reference::Reference", "napi_create_reference"); } } @@ -2933,14 +2921,14 @@ inline Reference::operator napi_ref() const { } template -inline bool Reference::operator ==(const Reference &other) const { +inline bool Reference::operator==(const Reference& other) const { HandleScope scope(_env); return this->Value().StrictEquals(other.Value()); } template -inline bool Reference::operator !=(const Reference &other) const { - return !this->operator ==(other); +inline bool Reference::operator!=(const Reference& other) const { + return !this->operator==(other); } template @@ -3037,33 +3025,29 @@ inline FunctionReference Persistent(Function value) { // ObjectReference class //////////////////////////////////////////////////////////////////////////////// -inline ObjectReference::ObjectReference(): Reference() { -} +inline ObjectReference::ObjectReference() : Reference() {} -inline ObjectReference::ObjectReference(napi_env env, napi_ref ref): Reference(env, ref) { -} +inline ObjectReference::ObjectReference(napi_env env, napi_ref ref) + : Reference(env, ref) {} inline ObjectReference::ObjectReference(Reference&& other) - : Reference(std::move(other)) { -} + : Reference(std::move(other)) {} -inline ObjectReference& ObjectReference::operator =(Reference&& other) { +inline ObjectReference& ObjectReference::operator=(Reference&& other) { static_cast*>(this)->operator=(std::move(other)); return *this; } inline ObjectReference::ObjectReference(ObjectReference&& other) - : Reference(std::move(other)) { -} + : Reference(std::move(other)) {} -inline ObjectReference& ObjectReference::operator =(ObjectReference&& other) { +inline ObjectReference& ObjectReference::operator=(ObjectReference&& other) { static_cast*>(this)->operator=(std::move(other)); return *this; } inline ObjectReference::ObjectReference(const ObjectReference& other) - : Reference(other) { -} + : Reference(other) {} inline MaybeOrValue ObjectReference::Get( const char* utf8name) const { @@ -3215,27 +3199,25 @@ inline MaybeOrValue ObjectReference::Set(uint32_t index, // FunctionReference class //////////////////////////////////////////////////////////////////////////////// -inline FunctionReference::FunctionReference(): Reference() { -} +inline FunctionReference::FunctionReference() : Reference() {} inline FunctionReference::FunctionReference(napi_env env, napi_ref ref) - : Reference(env, ref) { -} + : Reference(env, ref) {} inline FunctionReference::FunctionReference(Reference&& other) - : Reference(std::move(other)) { -} + : Reference(std::move(other)) {} -inline FunctionReference& FunctionReference::operator =(Reference&& other) { +inline FunctionReference& FunctionReference::operator=( + Reference&& other) { static_cast*>(this)->operator=(std::move(other)); return *this; } inline FunctionReference::FunctionReference(FunctionReference&& other) - : Reference(std::move(other)) { -} + : Reference(std::move(other)) {} -inline FunctionReference& FunctionReference::operator =(FunctionReference&& other) { +inline FunctionReference& FunctionReference::operator=( + FunctionReference&& other) { static_cast*>(this)->operator=(std::move(other)); return *this; } @@ -3441,10 +3423,15 @@ inline MaybeOrValue FunctionReference::New( //////////////////////////////////////////////////////////////////////////////// inline CallbackInfo::CallbackInfo(napi_env env, napi_callback_info info) - : _env(env), _info(info), _this(nullptr), _dynamicArgs(nullptr), _data(nullptr) { + : _env(env), + _info(info), + _this(nullptr), + _dynamicArgs(nullptr), + _data(nullptr) { _argc = _staticArgCount; _argv = _staticArgs; - napi_status status = napi_get_cb_info(env, info, &_argc, _argv, &_this, &_data); + napi_status status = + napi_get_cb_info(env, info, &_argc, _argv, &_this, &_data); NAPI_THROW_IF_FAILED_VOID(_env, status); if (_argc > _staticArgCount) { @@ -3464,6 +3451,10 @@ inline CallbackInfo::~CallbackInfo() { } } +inline CallbackInfo::operator napi_callback_info() const { + return _info; +} + inline Value CallbackInfo::NewTarget() const { napi_value newTarget; napi_status status = napi_get_new_target(_env, _info, &newTarget); @@ -3483,7 +3474,7 @@ inline size_t CallbackInfo::Length() const { return _argc; } -inline const Value CallbackInfo::operator [](size_t index) const { +inline const Value CallbackInfo::operator[](size_t index) const { return index < _argc ? Value(_env, _argv[index]) : Env().Undefined(); } @@ -3507,10 +3498,8 @@ inline void CallbackInfo::SetData(void* data) { //////////////////////////////////////////////////////////////////////////////// template -PropertyDescriptor -PropertyDescriptor::Accessor(const char* utf8name, - napi_property_attributes attributes, - void* data) { +PropertyDescriptor PropertyDescriptor::Accessor( + const char* utf8name, napi_property_attributes attributes, void* data) { napi_property_descriptor desc = napi_property_descriptor(); desc.utf8name = utf8name; @@ -3522,18 +3511,16 @@ PropertyDescriptor::Accessor(const char* utf8name, } template -PropertyDescriptor -PropertyDescriptor::Accessor(const std::string& utf8name, - napi_property_attributes attributes, - void* data) { +PropertyDescriptor PropertyDescriptor::Accessor( + const std::string& utf8name, + napi_property_attributes attributes, + void* data) { return Accessor(utf8name.c_str(), attributes, data); } template -PropertyDescriptor -PropertyDescriptor::Accessor(Name name, - napi_property_attributes attributes, - void* data) { +PropertyDescriptor PropertyDescriptor::Accessor( + Name name, napi_property_attributes attributes, void* data) { napi_property_descriptor desc = napi_property_descriptor(); desc.name = name; @@ -3544,14 +3531,10 @@ PropertyDescriptor::Accessor(Name name, return desc; } -template < -typename PropertyDescriptor::GetterCallback Getter, -typename PropertyDescriptor::SetterCallback Setter> -PropertyDescriptor -PropertyDescriptor::Accessor(const char* utf8name, - napi_property_attributes attributes, - void* data) { - +template +PropertyDescriptor PropertyDescriptor::Accessor( + const char* utf8name, napi_property_attributes attributes, void* data) { napi_property_descriptor desc = napi_property_descriptor(); desc.utf8name = utf8name; @@ -3563,23 +3546,19 @@ PropertyDescriptor::Accessor(const char* utf8name, return desc; } -template < -typename PropertyDescriptor::GetterCallback Getter, -typename PropertyDescriptor::SetterCallback Setter> -PropertyDescriptor -PropertyDescriptor::Accessor(const std::string& utf8name, - napi_property_attributes attributes, - void* data) { +template +PropertyDescriptor PropertyDescriptor::Accessor( + const std::string& utf8name, + napi_property_attributes attributes, + void* data) { return Accessor(utf8name.c_str(), attributes, data); } -template < -typename PropertyDescriptor::GetterCallback Getter, -typename PropertyDescriptor::SetterCallback Setter> -PropertyDescriptor -PropertyDescriptor::Accessor(Name name, - napi_property_attributes attributes, - void* data) { +template +PropertyDescriptor PropertyDescriptor::Accessor( + Name name, napi_property_attributes attributes, void* data) { napi_property_descriptor desc = napi_property_descriptor(); desc.name = name; @@ -3592,15 +3571,15 @@ PropertyDescriptor::Accessor(Name name, } template -inline PropertyDescriptor -PropertyDescriptor::Accessor(Napi::Env env, - Napi::Object object, - const char* utf8name, - Getter getter, - napi_property_attributes attributes, - void* data) { +inline PropertyDescriptor PropertyDescriptor::Accessor( + Napi::Env env, + Napi::Object object, + const char* utf8name, + Getter getter, + napi_property_attributes attributes, + void* data) { using CbData = details::CallbackData; - auto callbackData = new CbData({ getter, data }); + auto callbackData = new CbData({getter, data}); napi_status status = AttachData(env, object, callbackData); if (status != napi_ok) { @@ -3608,37 +3587,37 @@ PropertyDescriptor::Accessor(Napi::Env env, NAPI_THROW_IF_FAILED(env, status, napi_property_descriptor()); } - return PropertyDescriptor({ - utf8name, - nullptr, - nullptr, - CbData::Wrapper, - nullptr, - nullptr, - attributes, - callbackData - }); + return PropertyDescriptor({utf8name, + nullptr, + nullptr, + CbData::Wrapper, + nullptr, + nullptr, + attributes, + callbackData}); } template -inline PropertyDescriptor PropertyDescriptor::Accessor(Napi::Env env, - Napi::Object object, - const std::string& utf8name, - Getter getter, - napi_property_attributes attributes, - void* data) { +inline PropertyDescriptor PropertyDescriptor::Accessor( + Napi::Env env, + Napi::Object object, + const std::string& utf8name, + Getter getter, + napi_property_attributes attributes, + void* data) { return Accessor(env, object, utf8name.c_str(), getter, attributes, data); } template -inline PropertyDescriptor PropertyDescriptor::Accessor(Napi::Env env, - Napi::Object object, - Name name, - Getter getter, - napi_property_attributes attributes, - void* data) { +inline PropertyDescriptor PropertyDescriptor::Accessor( + Napi::Env env, + Napi::Object object, + Name name, + Getter getter, + napi_property_attributes attributes, + void* data) { using CbData = details::CallbackData; - auto callbackData = new CbData({ getter, data }); + auto callbackData = new CbData({getter, data}); napi_status status = AttachData(env, object, callbackData); if (status != napi_ok) { @@ -3646,28 +3625,27 @@ inline PropertyDescriptor PropertyDescriptor::Accessor(Napi::Env env, NAPI_THROW_IF_FAILED(env, status, napi_property_descriptor()); } - return PropertyDescriptor({ - nullptr, - name, - nullptr, - CbData::Wrapper, - nullptr, - nullptr, - attributes, - callbackData - }); + return PropertyDescriptor({nullptr, + name, + nullptr, + CbData::Wrapper, + nullptr, + nullptr, + attributes, + callbackData}); } template -inline PropertyDescriptor PropertyDescriptor::Accessor(Napi::Env env, - Napi::Object object, - const char* utf8name, - Getter getter, - Setter setter, - napi_property_attributes attributes, - void* data) { +inline PropertyDescriptor PropertyDescriptor::Accessor( + Napi::Env env, + Napi::Object object, + const char* utf8name, + Getter getter, + Setter setter, + napi_property_attributes attributes, + void* data) { using CbData = details::AccessorCallbackData; - auto callbackData = new CbData({ getter, setter, data }); + auto callbackData = new CbData({getter, setter, data}); napi_status status = AttachData(env, object, callbackData); if (status != napi_ok) { @@ -3675,39 +3653,40 @@ inline PropertyDescriptor PropertyDescriptor::Accessor(Napi::Env env, NAPI_THROW_IF_FAILED(env, status, napi_property_descriptor()); } - return PropertyDescriptor({ - utf8name, - nullptr, - nullptr, - CbData::GetterWrapper, - CbData::SetterWrapper, - nullptr, - attributes, - callbackData - }); + return PropertyDescriptor({utf8name, + nullptr, + nullptr, + CbData::GetterWrapper, + CbData::SetterWrapper, + nullptr, + attributes, + callbackData}); } template -inline PropertyDescriptor PropertyDescriptor::Accessor(Napi::Env env, - Napi::Object object, - const std::string& utf8name, - Getter getter, - Setter setter, - napi_property_attributes attributes, - void* data) { - return Accessor(env, object, utf8name.c_str(), getter, setter, attributes, data); +inline PropertyDescriptor PropertyDescriptor::Accessor( + Napi::Env env, + Napi::Object object, + const std::string& utf8name, + Getter getter, + Setter setter, + napi_property_attributes attributes, + void* data) { + return Accessor( + env, object, utf8name.c_str(), getter, setter, attributes, data); } template -inline PropertyDescriptor PropertyDescriptor::Accessor(Napi::Env env, - Napi::Object object, - Name name, - Getter getter, - Setter setter, - napi_property_attributes attributes, - void* data) { +inline PropertyDescriptor PropertyDescriptor::Accessor( + Napi::Env env, + Napi::Object object, + Name name, + Getter getter, + Setter setter, + napi_property_attributes attributes, + void* data) { using CbData = details::AccessorCallbackData; - auto callbackData = new CbData({ getter, setter, data }); + auto callbackData = new CbData({getter, setter, data}); napi_status status = AttachData(env, object, callbackData); if (status != napi_ok) { @@ -3715,99 +3694,99 @@ inline PropertyDescriptor PropertyDescriptor::Accessor(Napi::Env env, NAPI_THROW_IF_FAILED(env, status, napi_property_descriptor()); } - return PropertyDescriptor({ - nullptr, - name, - nullptr, - CbData::GetterWrapper, - CbData::SetterWrapper, - nullptr, - attributes, - callbackData - }); + return PropertyDescriptor({nullptr, + name, + nullptr, + CbData::GetterWrapper, + CbData::SetterWrapper, + nullptr, + attributes, + callbackData}); } template -inline PropertyDescriptor PropertyDescriptor::Function(Napi::Env env, - Napi::Object /*object*/, - const char* utf8name, - Callable cb, - napi_property_attributes attributes, - void* data) { - return PropertyDescriptor({ - utf8name, - nullptr, - nullptr, - nullptr, - nullptr, - Napi::Function::New(env, cb, utf8name, data), - attributes, - nullptr - }); +inline PropertyDescriptor PropertyDescriptor::Function( + Napi::Env env, + Napi::Object /*object*/, + const char* utf8name, + Callable cb, + napi_property_attributes attributes, + void* data) { + return PropertyDescriptor({utf8name, + nullptr, + nullptr, + nullptr, + nullptr, + Napi::Function::New(env, cb, utf8name, data), + attributes, + nullptr}); } template -inline PropertyDescriptor PropertyDescriptor::Function(Napi::Env env, - Napi::Object object, - const std::string& utf8name, - Callable cb, - napi_property_attributes attributes, - void* data) { +inline PropertyDescriptor PropertyDescriptor::Function( + Napi::Env env, + Napi::Object object, + const std::string& utf8name, + Callable cb, + napi_property_attributes attributes, + void* data) { return Function(env, object, utf8name.c_str(), cb, attributes, data); } template -inline PropertyDescriptor PropertyDescriptor::Function(Napi::Env env, - Napi::Object /*object*/, - Name name, - Callable cb, - napi_property_attributes attributes, - void* data) { - return PropertyDescriptor({ - nullptr, - name, - nullptr, - nullptr, - nullptr, - Napi::Function::New(env, cb, nullptr, data), - attributes, - nullptr - }); -} - -inline PropertyDescriptor PropertyDescriptor::Value(const char* utf8name, - napi_value value, - napi_property_attributes attributes) { - return PropertyDescriptor({ - utf8name, nullptr, nullptr, nullptr, nullptr, value, attributes, nullptr - }); +inline PropertyDescriptor PropertyDescriptor::Function( + Napi::Env env, + Napi::Object /*object*/, + Name name, + Callable cb, + napi_property_attributes attributes, + void* data) { + return PropertyDescriptor({nullptr, + name, + nullptr, + nullptr, + nullptr, + Napi::Function::New(env, cb, nullptr, data), + attributes, + nullptr}); } -inline PropertyDescriptor PropertyDescriptor::Value(const std::string& utf8name, - napi_value value, - napi_property_attributes attributes) { +inline PropertyDescriptor PropertyDescriptor::Value( + const char* utf8name, + napi_value value, + napi_property_attributes attributes) { + return PropertyDescriptor({utf8name, + nullptr, + nullptr, + nullptr, + nullptr, + value, + attributes, + nullptr}); +} + +inline PropertyDescriptor PropertyDescriptor::Value( + const std::string& utf8name, + napi_value value, + napi_property_attributes attributes) { return Value(utf8name.c_str(), value, attributes); } -inline PropertyDescriptor PropertyDescriptor::Value(napi_value name, - napi_value value, - napi_property_attributes attributes) { - return PropertyDescriptor({ - nullptr, name, nullptr, nullptr, nullptr, value, attributes, nullptr - }); +inline PropertyDescriptor PropertyDescriptor::Value( + napi_value name, napi_value value, napi_property_attributes attributes) { + return PropertyDescriptor( + {nullptr, name, nullptr, nullptr, nullptr, value, attributes, nullptr}); } -inline PropertyDescriptor PropertyDescriptor::Value(Name name, - Napi::Value value, - napi_property_attributes attributes) { +inline PropertyDescriptor PropertyDescriptor::Value( + Name name, Napi::Value value, napi_property_attributes attributes) { napi_value nameValue = name; napi_value valueValue = value; return PropertyDescriptor::Value(nameValue, valueValue, attributes); } inline PropertyDescriptor::PropertyDescriptor(napi_property_descriptor desc) - : _desc(desc) { -} + : _desc(desc) {} inline PropertyDescriptor::operator napi_property_descriptor&() { return _desc; @@ -3822,26 +3801,22 @@ inline PropertyDescriptor::operator const napi_property_descriptor&() const { //////////////////////////////////////////////////////////////////////////////// template -inline void InstanceWrap::AttachPropData(napi_env env, - napi_value value, - const napi_property_descriptor* prop) { +inline void InstanceWrap::AttachPropData( + napi_env env, napi_value value, const napi_property_descriptor* prop) { napi_status status; if (!(prop->attributes & napi_static)) { if (prop->method == T::InstanceVoidMethodCallbackWrapper) { - status = Napi::details::AttachData(env, - value, - static_cast(prop->data)); + status = Napi::details::AttachData( + env, value, static_cast(prop->data)); NAPI_THROW_IF_FAILED_VOID(env, status); } else if (prop->method == T::InstanceMethodCallbackWrapper) { - status = Napi::details::AttachData(env, - value, - static_cast(prop->data)); + status = Napi::details::AttachData( + env, value, static_cast(prop->data)); NAPI_THROW_IF_FAILED_VOID(env, status); } else if (prop->getter == T::InstanceGetterCallbackWrapper || - prop->setter == T::InstanceSetterCallbackWrapper) { - status = Napi::details::AttachData(env, - value, - static_cast(prop->data)); + prop->setter == T::InstanceSetterCallbackWrapper) { + status = Napi::details::AttachData( + env, value, static_cast(prop->data)); NAPI_THROW_IF_FAILED_VOID(env, status); } } @@ -3854,7 +3829,7 @@ inline ClassPropertyDescriptor InstanceWrap::InstanceMethod( napi_property_attributes attributes, void* data) { InstanceVoidMethodCallbackData* callbackData = - new InstanceVoidMethodCallbackData({ method, data}); + new InstanceVoidMethodCallbackData({method, data}); napi_property_descriptor desc = napi_property_descriptor(); desc.utf8name = utf8name; @@ -3870,7 +3845,8 @@ inline ClassPropertyDescriptor InstanceWrap::InstanceMethod( InstanceMethodCallback method, napi_property_attributes attributes, void* data) { - InstanceMethodCallbackData* callbackData = new InstanceMethodCallbackData({ method, data }); + InstanceMethodCallbackData* callbackData = + new InstanceMethodCallbackData({method, data}); napi_property_descriptor desc = napi_property_descriptor(); desc.utf8name = utf8name; @@ -3887,7 +3863,7 @@ inline ClassPropertyDescriptor InstanceWrap::InstanceMethod( napi_property_attributes attributes, void* data) { InstanceVoidMethodCallbackData* callbackData = - new InstanceVoidMethodCallbackData({ method, data}); + new InstanceVoidMethodCallbackData({method, data}); napi_property_descriptor desc = napi_property_descriptor(); desc.name = name; @@ -3903,7 +3879,8 @@ inline ClassPropertyDescriptor InstanceWrap::InstanceMethod( InstanceMethodCallback method, napi_property_attributes attributes, void* data) { - InstanceMethodCallbackData* callbackData = new InstanceMethodCallbackData({ method, data }); + InstanceMethodCallbackData* callbackData = + new InstanceMethodCallbackData({method, data}); napi_property_descriptor desc = napi_property_descriptor(); desc.name = name; @@ -3916,9 +3893,7 @@ inline ClassPropertyDescriptor InstanceWrap::InstanceMethod( template template ::InstanceVoidMethodCallback method> inline ClassPropertyDescriptor InstanceWrap::InstanceMethod( - const char* utf8name, - napi_property_attributes attributes, - void* data) { + const char* utf8name, napi_property_attributes attributes, void* data) { napi_property_descriptor desc = napi_property_descriptor(); desc.utf8name = utf8name; desc.method = details::TemplatedInstanceVoidCallback; @@ -3930,9 +3905,7 @@ inline ClassPropertyDescriptor InstanceWrap::InstanceMethod( template template ::InstanceMethodCallback method> inline ClassPropertyDescriptor InstanceWrap::InstanceMethod( - const char* utf8name, - napi_property_attributes attributes, - void* data) { + const char* utf8name, napi_property_attributes attributes, void* data) { napi_property_descriptor desc = napi_property_descriptor(); desc.utf8name = utf8name; desc.method = details::TemplatedInstanceCallback; @@ -3944,9 +3917,7 @@ inline ClassPropertyDescriptor InstanceWrap::InstanceMethod( template template ::InstanceVoidMethodCallback method> inline ClassPropertyDescriptor InstanceWrap::InstanceMethod( - Symbol name, - napi_property_attributes attributes, - void* data) { + Symbol name, napi_property_attributes attributes, void* data) { napi_property_descriptor desc = napi_property_descriptor(); desc.name = name; desc.method = details::TemplatedInstanceVoidCallback; @@ -3958,9 +3929,7 @@ inline ClassPropertyDescriptor InstanceWrap::InstanceMethod( template template ::InstanceMethodCallback method> inline ClassPropertyDescriptor InstanceWrap::InstanceMethod( - Symbol name, - napi_property_attributes attributes, - void* data) { + Symbol name, napi_property_attributes attributes, void* data) { napi_property_descriptor desc = napi_property_descriptor(); desc.name = name; desc.method = details::TemplatedInstanceCallback; @@ -3977,7 +3946,7 @@ inline ClassPropertyDescriptor InstanceWrap::InstanceAccessor( napi_property_attributes attributes, void* data) { InstanceAccessorCallbackData* callbackData = - new InstanceAccessorCallbackData({ getter, setter, data }); + new InstanceAccessorCallbackData({getter, setter, data}); napi_property_descriptor desc = napi_property_descriptor(); desc.utf8name = utf8name; @@ -3996,7 +3965,7 @@ inline ClassPropertyDescriptor InstanceWrap::InstanceAccessor( napi_property_attributes attributes, void* data) { InstanceAccessorCallbackData* callbackData = - new InstanceAccessorCallbackData({ getter, setter, data }); + new InstanceAccessorCallbackData({getter, setter, data}); napi_property_descriptor desc = napi_property_descriptor(); desc.name = name; @@ -4011,9 +3980,7 @@ template template ::InstanceGetterCallback getter, typename InstanceWrap::InstanceSetterCallback setter> inline ClassPropertyDescriptor InstanceWrap::InstanceAccessor( - const char* utf8name, - napi_property_attributes attributes, - void* data) { + const char* utf8name, napi_property_attributes attributes, void* data) { napi_property_descriptor desc = napi_property_descriptor(); desc.utf8name = utf8name; desc.getter = details::TemplatedInstanceCallback; @@ -4027,9 +3994,7 @@ template template ::InstanceGetterCallback getter, typename InstanceWrap::InstanceSetterCallback setter> inline ClassPropertyDescriptor InstanceWrap::InstanceAccessor( - Symbol name, - napi_property_attributes attributes, - void* data) { + Symbol name, napi_property_attributes attributes, void* data) { napi_property_descriptor desc = napi_property_descriptor(); desc.name = name; desc.getter = details::TemplatedInstanceCallback; @@ -4053,9 +4018,7 @@ inline ClassPropertyDescriptor InstanceWrap::InstanceValue( template inline ClassPropertyDescriptor InstanceWrap::InstanceValue( - Symbol name, - Napi::Value value, - napi_property_attributes attributes) { + Symbol name, Napi::Value value, napi_property_attributes attributes) { napi_property_descriptor desc = napi_property_descriptor(); desc.name = name; desc.value = value; @@ -4065,12 +4028,11 @@ inline ClassPropertyDescriptor InstanceWrap::InstanceValue( template inline napi_value InstanceWrap::InstanceVoidMethodCallbackWrapper( - napi_env env, - napi_callback_info info) { + napi_env env, napi_callback_info info) { return details::WrapCallback([&] { CallbackInfo callbackInfo(env, info); InstanceVoidMethodCallbackData* callbackData = - reinterpret_cast(callbackInfo.Data()); + reinterpret_cast(callbackInfo.Data()); callbackInfo.SetData(callbackData->data); T* instance = T::Unwrap(callbackInfo.This().As()); auto cb = callbackData->callback; @@ -4081,12 +4043,11 @@ inline napi_value InstanceWrap::InstanceVoidMethodCallbackWrapper( template inline napi_value InstanceWrap::InstanceMethodCallbackWrapper( - napi_env env, - napi_callback_info info) { + napi_env env, napi_callback_info info) { return details::WrapCallback([&] { CallbackInfo callbackInfo(env, info); InstanceMethodCallbackData* callbackData = - reinterpret_cast(callbackInfo.Data()); + reinterpret_cast(callbackInfo.Data()); callbackInfo.SetData(callbackData->data); T* instance = T::Unwrap(callbackInfo.This().As()); auto cb = callbackData->callback; @@ -4096,12 +4057,11 @@ inline napi_value InstanceWrap::InstanceMethodCallbackWrapper( template inline napi_value InstanceWrap::InstanceGetterCallbackWrapper( - napi_env env, - napi_callback_info info) { + napi_env env, napi_callback_info info) { return details::WrapCallback([&] { CallbackInfo callbackInfo(env, info); InstanceAccessorCallbackData* callbackData = - reinterpret_cast(callbackInfo.Data()); + reinterpret_cast(callbackInfo.Data()); callbackInfo.SetData(callbackData->data); T* instance = T::Unwrap(callbackInfo.This().As()); auto cb = callbackData->getterCallback; @@ -4111,12 +4071,11 @@ inline napi_value InstanceWrap::InstanceGetterCallbackWrapper( template inline napi_value InstanceWrap::InstanceSetterCallbackWrapper( - napi_env env, - napi_callback_info info) { + napi_env env, napi_callback_info info) { return details::WrapCallback([&] { CallbackInfo callbackInfo(env, info); InstanceAccessorCallbackData* callbackData = - reinterpret_cast(callbackInfo.Data()); + reinterpret_cast(callbackInfo.Data()); callbackInfo.SetData(callbackData->data); T* instance = T::Unwrap(callbackInfo.This().As()); auto cb = callbackData->setterCallback; @@ -4169,7 +4128,7 @@ inline ObjectWrap::~ObjectWrap() { } } -template +template inline T* ObjectWrap::Unwrap(Object wrapper) { void* unwrapped; napi_status status = napi_unwrap(wrapper.Env(), wrapper, &unwrapped); @@ -4178,12 +4137,12 @@ inline T* ObjectWrap::Unwrap(Object wrapper) { } template -inline Function -ObjectWrap::DefineClass(Napi::Env env, - const char* utf8name, - const size_t props_count, - const napi_property_descriptor* descriptors, - void* data) { +inline Function ObjectWrap::DefineClass( + Napi::Env env, + const char* utf8name, + const size_t props_count, + const napi_property_descriptor* descriptors, + void* data) { napi_status status; std::vector props(props_count); @@ -4199,16 +4158,18 @@ ObjectWrap::DefineClass(Napi::Env env, props[index] = descriptors[index]; napi_property_descriptor* prop = &props[index]; if (prop->method == T::StaticMethodCallbackWrapper) { - status = CreateFunction(env, - utf8name, - prop->method, - static_cast(prop->data), - &(prop->value)); + status = + CreateFunction(env, + utf8name, + prop->method, + static_cast(prop->data), + &(prop->value)); NAPI_THROW_IF_FAILED(env, status, Function()); prop->method = nullptr; prop->data = nullptr; } else if (prop->method == T::StaticVoidMethodCallbackWrapper) { - status = CreateFunction(env, + status = + CreateFunction(env, utf8name, prop->method, static_cast(prop->data), @@ -4238,9 +4199,8 @@ ObjectWrap::DefineClass(Napi::Env env, if (prop->getter == T::StaticGetterCallbackWrapper || prop->setter == T::StaticSetterCallbackWrapper) { - status = Napi::details::AttachData(env, - value, - static_cast(prop->data)); + status = Napi::details::AttachData( + env, value, static_cast(prop->data)); NAPI_THROW_IF_FAILED(env, status, Function()); } else { // InstanceWrap::AttachPropData is responsible for attaching the data @@ -4258,11 +4218,12 @@ inline Function ObjectWrap::DefineClass( const char* utf8name, const std::initializer_list>& properties, void* data) { - return DefineClass(env, - utf8name, - properties.size(), - reinterpret_cast(properties.begin()), - data); + return DefineClass( + env, + utf8name, + properties.size(), + reinterpret_cast(properties.begin()), + data); } template @@ -4271,11 +4232,12 @@ inline Function ObjectWrap::DefineClass( const char* utf8name, const std::vector>& properties, void* data) { - return DefineClass(env, - utf8name, - properties.size(), - reinterpret_cast(properties.data()), - data); + return DefineClass( + env, + utf8name, + properties.size(), + reinterpret_cast(properties.data()), + data); } template @@ -4284,13 +4246,15 @@ inline ClassPropertyDescriptor ObjectWrap::StaticMethod( StaticVoidMethodCallback method, napi_property_attributes attributes, void* data) { - StaticVoidMethodCallbackData* callbackData = new StaticVoidMethodCallbackData({ method, data }); + StaticVoidMethodCallbackData* callbackData = + new StaticVoidMethodCallbackData({method, data}); napi_property_descriptor desc = napi_property_descriptor(); desc.utf8name = utf8name; desc.method = T::StaticVoidMethodCallbackWrapper; desc.data = callbackData; - desc.attributes = static_cast(attributes | napi_static); + desc.attributes = + static_cast(attributes | napi_static); return desc; } @@ -4300,13 +4264,15 @@ inline ClassPropertyDescriptor ObjectWrap::StaticMethod( StaticMethodCallback method, napi_property_attributes attributes, void* data) { - StaticMethodCallbackData* callbackData = new StaticMethodCallbackData({ method, data }); + StaticMethodCallbackData* callbackData = + new StaticMethodCallbackData({method, data}); napi_property_descriptor desc = napi_property_descriptor(); desc.utf8name = utf8name; desc.method = T::StaticMethodCallbackWrapper; desc.data = callbackData; - desc.attributes = static_cast(attributes | napi_static); + desc.attributes = + static_cast(attributes | napi_static); return desc; } @@ -4316,13 +4282,15 @@ inline ClassPropertyDescriptor ObjectWrap::StaticMethod( StaticVoidMethodCallback method, napi_property_attributes attributes, void* data) { - StaticVoidMethodCallbackData* callbackData = new StaticVoidMethodCallbackData({ method, data }); + StaticVoidMethodCallbackData* callbackData = + new StaticVoidMethodCallbackData({method, data}); napi_property_descriptor desc = napi_property_descriptor(); desc.name = name; desc.method = T::StaticVoidMethodCallbackWrapper; desc.data = callbackData; - desc.attributes = static_cast(attributes | napi_static); + desc.attributes = + static_cast(attributes | napi_static); return desc; } @@ -4332,69 +4300,67 @@ inline ClassPropertyDescriptor ObjectWrap::StaticMethod( StaticMethodCallback method, napi_property_attributes attributes, void* data) { - StaticMethodCallbackData* callbackData = new StaticMethodCallbackData({ method, data }); + StaticMethodCallbackData* callbackData = + new StaticMethodCallbackData({method, data}); napi_property_descriptor desc = napi_property_descriptor(); desc.name = name; desc.method = T::StaticMethodCallbackWrapper; desc.data = callbackData; - desc.attributes = static_cast(attributes | napi_static); + desc.attributes = + static_cast(attributes | napi_static); return desc; } template template ::StaticVoidMethodCallback method> inline ClassPropertyDescriptor ObjectWrap::StaticMethod( - const char* utf8name, - napi_property_attributes attributes, - void* data) { + const char* utf8name, napi_property_attributes attributes, void* data) { napi_property_descriptor desc = napi_property_descriptor(); desc.utf8name = utf8name; desc.method = details::TemplatedVoidCallback; desc.data = data; - desc.attributes = static_cast(attributes | napi_static); + desc.attributes = + static_cast(attributes | napi_static); return desc; } template template ::StaticVoidMethodCallback method> inline ClassPropertyDescriptor ObjectWrap::StaticMethod( - Symbol name, - napi_property_attributes attributes, - void* data) { + Symbol name, napi_property_attributes attributes, void* data) { napi_property_descriptor desc = napi_property_descriptor(); desc.name = name; desc.method = details::TemplatedVoidCallback; desc.data = data; - desc.attributes = static_cast(attributes | napi_static); + desc.attributes = + static_cast(attributes | napi_static); return desc; } template template ::StaticMethodCallback method> inline ClassPropertyDescriptor ObjectWrap::StaticMethod( - const char* utf8name, - napi_property_attributes attributes, - void* data) { + const char* utf8name, napi_property_attributes attributes, void* data) { napi_property_descriptor desc = napi_property_descriptor(); desc.utf8name = utf8name; desc.method = details::TemplatedCallback; desc.data = data; - desc.attributes = static_cast(attributes | napi_static); + desc.attributes = + static_cast(attributes | napi_static); return desc; } template template ::StaticMethodCallback method> inline ClassPropertyDescriptor ObjectWrap::StaticMethod( - Symbol name, - napi_property_attributes attributes, - void* data) { + Symbol name, napi_property_attributes attributes, void* data) { napi_property_descriptor desc = napi_property_descriptor(); desc.name = name; desc.method = details::TemplatedCallback; desc.data = data; - desc.attributes = static_cast(attributes | napi_static); + desc.attributes = + static_cast(attributes | napi_static); return desc; } @@ -4406,14 +4372,15 @@ inline ClassPropertyDescriptor ObjectWrap::StaticAccessor( napi_property_attributes attributes, void* data) { StaticAccessorCallbackData* callbackData = - new StaticAccessorCallbackData({ getter, setter, data }); + new StaticAccessorCallbackData({getter, setter, data}); napi_property_descriptor desc = napi_property_descriptor(); desc.utf8name = utf8name; desc.getter = getter != nullptr ? T::StaticGetterCallbackWrapper : nullptr; desc.setter = setter != nullptr ? T::StaticSetterCallbackWrapper : nullptr; desc.data = callbackData; - desc.attributes = static_cast(attributes | napi_static); + desc.attributes = + static_cast(attributes | napi_static); return desc; } @@ -4425,14 +4392,15 @@ inline ClassPropertyDescriptor ObjectWrap::StaticAccessor( napi_property_attributes attributes, void* data) { StaticAccessorCallbackData* callbackData = - new StaticAccessorCallbackData({ getter, setter, data }); + new StaticAccessorCallbackData({getter, setter, data}); napi_property_descriptor desc = napi_property_descriptor(); desc.name = name; desc.getter = getter != nullptr ? T::StaticGetterCallbackWrapper : nullptr; desc.setter = setter != nullptr ? T::StaticSetterCallbackWrapper : nullptr; desc.data = callbackData; - desc.attributes = static_cast(attributes | napi_static); + desc.attributes = + static_cast(attributes | napi_static); return desc; } @@ -4440,15 +4408,14 @@ template template ::StaticGetterCallback getter, typename ObjectWrap::StaticSetterCallback setter> inline ClassPropertyDescriptor ObjectWrap::StaticAccessor( - const char* utf8name, - napi_property_attributes attributes, - void* data) { + const char* utf8name, napi_property_attributes attributes, void* data) { napi_property_descriptor desc = napi_property_descriptor(); desc.utf8name = utf8name; desc.getter = details::TemplatedCallback; desc.setter = This::WrapStaticSetter(This::StaticSetterTag()); desc.data = data; - desc.attributes = static_cast(attributes | napi_static); + desc.attributes = + static_cast(attributes | napi_static); return desc; } @@ -4456,35 +4423,38 @@ template template ::StaticGetterCallback getter, typename ObjectWrap::StaticSetterCallback setter> inline ClassPropertyDescriptor ObjectWrap::StaticAccessor( - Symbol name, - napi_property_attributes attributes, - void* data) { + Symbol name, napi_property_attributes attributes, void* data) { napi_property_descriptor desc = napi_property_descriptor(); desc.name = name; desc.getter = details::TemplatedCallback; desc.setter = This::WrapStaticSetter(This::StaticSetterTag()); desc.data = data; - desc.attributes = static_cast(attributes | napi_static); + desc.attributes = + static_cast(attributes | napi_static); return desc; } template -inline ClassPropertyDescriptor ObjectWrap::StaticValue(const char* utf8name, - Napi::Value value, napi_property_attributes attributes) { +inline ClassPropertyDescriptor ObjectWrap::StaticValue( + const char* utf8name, + Napi::Value value, + napi_property_attributes attributes) { napi_property_descriptor desc = napi_property_descriptor(); desc.utf8name = utf8name; desc.value = value; - desc.attributes = static_cast(attributes | napi_static); + desc.attributes = + static_cast(attributes | napi_static); return desc; } template -inline ClassPropertyDescriptor ObjectWrap::StaticValue(Symbol name, - Napi::Value value, napi_property_attributes attributes) { +inline ClassPropertyDescriptor ObjectWrap::StaticValue( + Symbol name, Napi::Value value, napi_property_attributes attributes) { napi_property_descriptor desc = napi_property_descriptor(); desc.name = name; desc.value = value; - desc.attributes = static_cast(attributes | napi_static); + desc.attributes = + static_cast(attributes | napi_static); return desc; } @@ -4502,8 +4472,7 @@ inline void ObjectWrap::Finalize(Napi::Env /*env*/) {} template inline napi_value ObjectWrap::ConstructorCallbackWrapper( - napi_env env, - napi_callback_info info) { + napi_env env, napi_callback_info info) { napi_value new_target; napi_status status = napi_get_new_target(env, info, &new_target); if (status != napi_ok) return nullptr; @@ -4528,7 +4497,7 @@ inline napi_value ObjectWrap::ConstructorCallbackWrapper( } else { instance->_construction_failed = false; } -# endif // NAPI_CPP_EXCEPTIONS +#endif // NAPI_CPP_EXCEPTIONS return callbackInfo.This(); }); @@ -4537,12 +4506,11 @@ inline napi_value ObjectWrap::ConstructorCallbackWrapper( template inline napi_value ObjectWrap::StaticVoidMethodCallbackWrapper( - napi_env env, - napi_callback_info info) { + napi_env env, napi_callback_info info) { return details::WrapCallback([&] { CallbackInfo callbackInfo(env, info); StaticVoidMethodCallbackData* callbackData = - reinterpret_cast(callbackInfo.Data()); + reinterpret_cast(callbackInfo.Data()); callbackInfo.SetData(callbackData->data); callbackData->callback(callbackInfo); return nullptr; @@ -4551,12 +4519,11 @@ inline napi_value ObjectWrap::StaticVoidMethodCallbackWrapper( template inline napi_value ObjectWrap::StaticMethodCallbackWrapper( - napi_env env, - napi_callback_info info) { + napi_env env, napi_callback_info info) { return details::WrapCallback([&] { CallbackInfo callbackInfo(env, info); StaticMethodCallbackData* callbackData = - reinterpret_cast(callbackInfo.Data()); + reinterpret_cast(callbackInfo.Data()); callbackInfo.SetData(callbackData->data); return callbackData->callback(callbackInfo); }); @@ -4564,12 +4531,11 @@ inline napi_value ObjectWrap::StaticMethodCallbackWrapper( template inline napi_value ObjectWrap::StaticGetterCallbackWrapper( - napi_env env, - napi_callback_info info) { + napi_env env, napi_callback_info info) { return details::WrapCallback([&] { CallbackInfo callbackInfo(env, info); StaticAccessorCallbackData* callbackData = - reinterpret_cast(callbackInfo.Data()); + reinterpret_cast(callbackInfo.Data()); callbackInfo.SetData(callbackData->data); return callbackData->getterCallback(callbackInfo); }); @@ -4577,12 +4543,11 @@ inline napi_value ObjectWrap::StaticGetterCallbackWrapper( template inline napi_value ObjectWrap::StaticSetterCallbackWrapper( - napi_env env, - napi_callback_info info) { + napi_env env, napi_callback_info info) { return details::WrapCallback([&] { CallbackInfo callbackInfo(env, info); StaticAccessorCallbackData* callbackData = - reinterpret_cast(callbackInfo.Data()); + reinterpret_cast(callbackInfo.Data()); callbackInfo.SetData(callbackData->data); callbackData->setterCallback(callbackInfo, callbackInfo[0]); return nullptr; @@ -4590,7 +4555,9 @@ inline napi_value ObjectWrap::StaticSetterCallbackWrapper( } template -inline void ObjectWrap::FinalizeCallback(napi_env env, void* data, void* /*hint*/) { +inline void ObjectWrap::FinalizeCallback(napi_env env, + void* data, + void* /*hint*/) { HandleScope scope(env); T* instance = static_cast(data); instance->Finalize(Napi::Env(env)); @@ -4613,8 +4580,7 @@ inline napi_value ObjectWrap::WrappedMethod( //////////////////////////////////////////////////////////////////////////////// inline HandleScope::HandleScope(napi_env env, napi_handle_scope scope) - : _env(env), _scope(scope) { -} + : _env(env), _scope(scope) {} inline HandleScope::HandleScope(Napi::Env env) : _env(env) { napi_status status = napi_open_handle_scope(_env, &_scope); @@ -4623,9 +4589,8 @@ inline HandleScope::HandleScope(Napi::Env env) : _env(env) { inline HandleScope::~HandleScope() { napi_status status = napi_close_handle_scope(_env, _scope); - NAPI_FATAL_IF_FAILED(status, - "HandleScope::~HandleScope", - "napi_close_handle_scope"); + NAPI_FATAL_IF_FAILED( + status, "HandleScope::~HandleScope", "napi_close_handle_scope"); } inline HandleScope::operator napi_handle_scope() const { @@ -4641,8 +4606,8 @@ inline Napi::Env HandleScope::Env() const { //////////////////////////////////////////////////////////////////////////////// inline EscapableHandleScope::EscapableHandleScope( - napi_env env, napi_escapable_handle_scope scope) : _env(env), _scope(scope) { -} + napi_env env, napi_escapable_handle_scope scope) + : _env(env), _scope(scope) {} inline EscapableHandleScope::EscapableHandleScope(Napi::Env env) : _env(env) { napi_status status = napi_open_escapable_handle_scope(_env, &_scope); @@ -4671,28 +4636,25 @@ inline Value EscapableHandleScope::Escape(napi_value escapee) { return Value(_env, result); } - #if (NAPI_VERSION > 2) //////////////////////////////////////////////////////////////////////////////// // CallbackScope class //////////////////////////////////////////////////////////////////////////////// -inline CallbackScope::CallbackScope( - napi_env env, napi_callback_scope scope) : _env(env), _scope(scope) { -} +inline CallbackScope::CallbackScope(napi_env env, napi_callback_scope scope) + : _env(env), _scope(scope) {} inline CallbackScope::CallbackScope(napi_env env, napi_async_context context) : _env(env) { - napi_status status = napi_open_callback_scope( - _env, Object::New(env), context, &_scope); + napi_status status = + napi_open_callback_scope(_env, Object::New(env), context, &_scope); NAPI_THROW_IF_FAILED_VOID(_env, status); } inline CallbackScope::~CallbackScope() { napi_status status = napi_close_callback_scope(_env, _scope); - NAPI_FATAL_IF_FAILED(status, - "CallbackScope::~CallbackScope", - "napi_close_callback_scope"); + NAPI_FATAL_IF_FAILED( + status, "CallbackScope::~CallbackScope", "napi_close_callback_scope"); } inline CallbackScope::operator napi_callback_scope() const { @@ -4709,8 +4671,7 @@ inline Napi::Env CallbackScope::Env() const { //////////////////////////////////////////////////////////////////////////////// inline AsyncContext::AsyncContext(napi_env env, const char* resource_name) - : AsyncContext(env, resource_name, Object::New(env)) { -} + : AsyncContext(env, resource_name, Object::New(env)) {} inline AsyncContext::AsyncContext(napi_env env, const char* resource_name, @@ -4739,7 +4700,7 @@ inline AsyncContext::AsyncContext(AsyncContext&& other) { other._context = nullptr; } -inline AsyncContext& AsyncContext::operator =(AsyncContext&& other) { +inline AsyncContext& AsyncContext::operator=(AsyncContext&& other) { _env = other._env; other._env = nullptr; _context = other._context; @@ -4760,78 +4721,72 @@ inline Napi::Env AsyncContext::Env() const { //////////////////////////////////////////////////////////////////////////////// inline AsyncWorker::AsyncWorker(const Function& callback) - : AsyncWorker(callback, "generic") { -} + : AsyncWorker(callback, "generic") {} inline AsyncWorker::AsyncWorker(const Function& callback, const char* resource_name) - : AsyncWorker(callback, resource_name, Object::New(callback.Env())) { -} + : AsyncWorker(callback, resource_name, Object::New(callback.Env())) {} inline AsyncWorker::AsyncWorker(const Function& callback, const char* resource_name, const Object& resource) - : AsyncWorker(Object::New(callback.Env()), - callback, - resource_name, - resource) { -} + : AsyncWorker( + Object::New(callback.Env()), callback, resource_name, resource) {} inline AsyncWorker::AsyncWorker(const Object& receiver, const Function& callback) - : AsyncWorker(receiver, callback, "generic") { -} + : AsyncWorker(receiver, callback, "generic") {} inline AsyncWorker::AsyncWorker(const Object& receiver, const Function& callback, const char* resource_name) - : AsyncWorker(receiver, - callback, - resource_name, - Object::New(callback.Env())) { -} + : AsyncWorker( + receiver, callback, resource_name, Object::New(callback.Env())) {} inline AsyncWorker::AsyncWorker(const Object& receiver, const Function& callback, const char* resource_name, const Object& resource) - : _env(callback.Env()), - _receiver(Napi::Persistent(receiver)), - _callback(Napi::Persistent(callback)), - _suppress_destruct(false) { + : _env(callback.Env()), + _receiver(Napi::Persistent(receiver)), + _callback(Napi::Persistent(callback)), + _suppress_destruct(false) { napi_value resource_id; napi_status status = napi_create_string_latin1( _env, resource_name, NAPI_AUTO_LENGTH, &resource_id); NAPI_THROW_IF_FAILED_VOID(_env, status); - status = napi_create_async_work(_env, resource, resource_id, OnAsyncWorkExecute, - OnAsyncWorkComplete, this, &_work); + status = napi_create_async_work(_env, + resource, + resource_id, + OnAsyncWorkExecute, + OnAsyncWorkComplete, + this, + &_work); NAPI_THROW_IF_FAILED_VOID(_env, status); } -inline AsyncWorker::AsyncWorker(Napi::Env env) - : AsyncWorker(env, "generic") { -} +inline AsyncWorker::AsyncWorker(Napi::Env env) : AsyncWorker(env, "generic") {} -inline AsyncWorker::AsyncWorker(Napi::Env env, - const char* resource_name) - : AsyncWorker(env, resource_name, Object::New(env)) { -} +inline AsyncWorker::AsyncWorker(Napi::Env env, const char* resource_name) + : AsyncWorker(env, resource_name, Object::New(env)) {} inline AsyncWorker::AsyncWorker(Napi::Env env, const char* resource_name, const Object& resource) - : _env(env), - _receiver(), - _callback(), - _suppress_destruct(false) { + : _env(env), _receiver(), _callback(), _suppress_destruct(false) { napi_value resource_id; napi_status status = napi_create_string_latin1( _env, resource_name, NAPI_AUTO_LENGTH, &resource_id); NAPI_THROW_IF_FAILED_VOID(_env, status); - status = napi_create_async_work(_env, resource, resource_id, OnAsyncWorkExecute, - OnAsyncWorkComplete, this, &_work); + status = napi_create_async_work(_env, + resource, + resource_id, + OnAsyncWorkExecute, + OnAsyncWorkComplete, + this, + &_work); NAPI_THROW_IF_FAILED_VOID(_env, status); } @@ -4857,7 +4812,7 @@ inline AsyncWorker::AsyncWorker(AsyncWorker&& other) { _suppress_destruct = other._suppress_destruct; } -inline AsyncWorker& AsyncWorker::operator =(AsyncWorker&& other) { +inline AsyncWorker& AsyncWorker::operator=(AsyncWorker&& other) { _env = other._env; other._env = nullptr; _work = other._work; @@ -4907,7 +4862,8 @@ inline void AsyncWorker::OnOK() { inline void AsyncWorker::OnError(const Error& e) { if (!_callback.IsEmpty()) { - _callback.Call(_receiver.Value(), std::initializer_list{ e.Value() }); + _callback.Call(_receiver.Value(), + std::initializer_list{e.Value()}); } } @@ -4937,9 +4893,9 @@ inline void AsyncWorker::OnExecute(Napi::Env /*DO_NOT_USE*/) { } catch (const std::exception& e) { SetError(e.what()); } -#else // NAPI_CPP_EXCEPTIONS +#else // NAPI_CPP_EXCEPTIONS Execute(); -#endif // NAPI_CPP_EXCEPTIONS +#endif // NAPI_CPP_EXCEPTIONS } inline void AsyncWorker::OnAsyncWorkComplete(napi_env env, @@ -4954,8 +4910,7 @@ inline void AsyncWorker::OnWorkComplete(Napi::Env /*env*/, napi_status status) { details::WrapCallback([&] { if (_error.size() == 0) { OnOK(); - } - else { + } else { OnError(Error::New(_env, _error)); } return nullptr; @@ -5458,68 +5413,93 @@ TypedThreadSafeFunction::FunctionOrEmpty( // static template inline ThreadSafeFunction ThreadSafeFunction::New(napi_env env, - const Function& callback, - ResourceString resourceName, - size_t maxQueueSize, - size_t initialThreadCount) { - return New(env, callback, Object(), resourceName, maxQueueSize, - initialThreadCount); + const Function& callback, + ResourceString resourceName, + size_t maxQueueSize, + size_t initialThreadCount) { + return New( + env, callback, Object(), resourceName, maxQueueSize, initialThreadCount); } // static template inline ThreadSafeFunction ThreadSafeFunction::New(napi_env env, - const Function& callback, - ResourceString resourceName, - size_t maxQueueSize, - size_t initialThreadCount, - ContextType* context) { - return New(env, callback, Object(), resourceName, maxQueueSize, - initialThreadCount, context); + const Function& callback, + ResourceString resourceName, + size_t maxQueueSize, + size_t initialThreadCount, + ContextType* context) { + return New(env, + callback, + Object(), + resourceName, + maxQueueSize, + initialThreadCount, + context); } // static template inline ThreadSafeFunction ThreadSafeFunction::New(napi_env env, - const Function& callback, - ResourceString resourceName, - size_t maxQueueSize, - size_t initialThreadCount, - Finalizer finalizeCallback) { - return New(env, callback, Object(), resourceName, maxQueueSize, - initialThreadCount, finalizeCallback); + const Function& callback, + ResourceString resourceName, + size_t maxQueueSize, + size_t initialThreadCount, + Finalizer finalizeCallback) { + return New(env, + callback, + Object(), + resourceName, + maxQueueSize, + initialThreadCount, + finalizeCallback); } // static -template inline ThreadSafeFunction ThreadSafeFunction::New(napi_env env, - const Function& callback, - ResourceString resourceName, - size_t maxQueueSize, - size_t initialThreadCount, - Finalizer finalizeCallback, - FinalizerDataType* data) { - return New(env, callback, Object(), resourceName, maxQueueSize, - initialThreadCount, finalizeCallback, data); + const Function& callback, + ResourceString resourceName, + size_t maxQueueSize, + size_t initialThreadCount, + Finalizer finalizeCallback, + FinalizerDataType* data) { + return New(env, + callback, + Object(), + resourceName, + maxQueueSize, + initialThreadCount, + finalizeCallback, + data); } // static template inline ThreadSafeFunction ThreadSafeFunction::New(napi_env env, - const Function& callback, - ResourceString resourceName, - size_t maxQueueSize, - size_t initialThreadCount, - ContextType* context, - Finalizer finalizeCallback) { - return New(env, callback, Object(), resourceName, maxQueueSize, - initialThreadCount, context, finalizeCallback); + const Function& callback, + ResourceString resourceName, + size_t maxQueueSize, + size_t initialThreadCount, + ContextType* context, + Finalizer finalizeCallback) { + return New(env, + callback, + Object(), + resourceName, + maxQueueSize, + initialThreadCount, + context, + finalizeCallback); } // static -template +template inline ThreadSafeFunction ThreadSafeFunction::New(napi_env env, const Function& callback, ResourceString resourceName, @@ -5528,89 +5508,128 @@ inline ThreadSafeFunction ThreadSafeFunction::New(napi_env env, ContextType* context, Finalizer finalizeCallback, FinalizerDataType* data) { - return New(env, callback, Object(), resourceName, maxQueueSize, - initialThreadCount, context, finalizeCallback, data); + return New(env, + callback, + Object(), + resourceName, + maxQueueSize, + initialThreadCount, + context, + finalizeCallback, + data); } // static template inline ThreadSafeFunction ThreadSafeFunction::New(napi_env env, - const Function& callback, - const Object& resource, - ResourceString resourceName, - size_t maxQueueSize, - size_t initialThreadCount) { - return New(env, callback, resource, resourceName, maxQueueSize, - initialThreadCount, static_cast(nullptr) /* context */); + const Function& callback, + const Object& resource, + ResourceString resourceName, + size_t maxQueueSize, + size_t initialThreadCount) { + return New(env, + callback, + resource, + resourceName, + maxQueueSize, + initialThreadCount, + static_cast(nullptr) /* context */); } // static template inline ThreadSafeFunction ThreadSafeFunction::New(napi_env env, - const Function& callback, - const Object& resource, - ResourceString resourceName, - size_t maxQueueSize, - size_t initialThreadCount, - ContextType* context) { - return New(env, callback, resource, resourceName, maxQueueSize, - initialThreadCount, context, + const Function& callback, + const Object& resource, + ResourceString resourceName, + size_t maxQueueSize, + size_t initialThreadCount, + ContextType* context) { + return New(env, + callback, + resource, + resourceName, + maxQueueSize, + initialThreadCount, + context, [](Env, ContextType*) {} /* empty finalizer */); } // static template inline ThreadSafeFunction ThreadSafeFunction::New(napi_env env, - const Function& callback, - const Object& resource, - ResourceString resourceName, - size_t maxQueueSize, - size_t initialThreadCount, - Finalizer finalizeCallback) { - return New(env, callback, resource, resourceName, maxQueueSize, - initialThreadCount, static_cast(nullptr) /* context */, - finalizeCallback, static_cast(nullptr) /* data */, + const Function& callback, + const Object& resource, + ResourceString resourceName, + size_t maxQueueSize, + size_t initialThreadCount, + Finalizer finalizeCallback) { + return New(env, + callback, + resource, + resourceName, + maxQueueSize, + initialThreadCount, + static_cast(nullptr) /* context */, + finalizeCallback, + static_cast(nullptr) /* data */, details::ThreadSafeFinalize::Wrapper); } // static -template inline ThreadSafeFunction ThreadSafeFunction::New(napi_env env, - const Function& callback, - const Object& resource, - ResourceString resourceName, - size_t maxQueueSize, - size_t initialThreadCount, - Finalizer finalizeCallback, - FinalizerDataType* data) { - return New(env, callback, resource, resourceName, maxQueueSize, - initialThreadCount, static_cast(nullptr) /* context */, - finalizeCallback, data, - details::ThreadSafeFinalize< - void, Finalizer, FinalizerDataType>::FinalizeWrapperWithData); + const Function& callback, + const Object& resource, + ResourceString resourceName, + size_t maxQueueSize, + size_t initialThreadCount, + Finalizer finalizeCallback, + FinalizerDataType* data) { + return New(env, + callback, + resource, + resourceName, + maxQueueSize, + initialThreadCount, + static_cast(nullptr) /* context */, + finalizeCallback, + data, + details::ThreadSafeFinalize:: + FinalizeWrapperWithData); } // static template inline ThreadSafeFunction ThreadSafeFunction::New(napi_env env, - const Function& callback, - const Object& resource, - ResourceString resourceName, - size_t maxQueueSize, - size_t initialThreadCount, - ContextType* context, - Finalizer finalizeCallback) { - return New(env, callback, resource, resourceName, maxQueueSize, - initialThreadCount, context, finalizeCallback, - static_cast(nullptr) /* data */, - details::ThreadSafeFinalize< - ContextType, Finalizer>::FinalizeWrapperWithContext); + const Function& callback, + const Object& resource, + ResourceString resourceName, + size_t maxQueueSize, + size_t initialThreadCount, + ContextType* context, + Finalizer finalizeCallback) { + return New( + env, + callback, + resource, + resourceName, + maxQueueSize, + initialThreadCount, + context, + finalizeCallback, + static_cast(nullptr) /* data */, + details::ThreadSafeFinalize::FinalizeWrapperWithContext); } // static -template +template inline ThreadSafeFunction ThreadSafeFunction::New(napi_env env, const Function& callback, const Object& resource, @@ -5620,20 +5639,24 @@ inline ThreadSafeFunction ThreadSafeFunction::New(napi_env env, ContextType* context, Finalizer finalizeCallback, FinalizerDataType* data) { - return New(env, callback, resource, resourceName, maxQueueSize, - initialThreadCount, context, finalizeCallback, data, - details::ThreadSafeFinalize::FinalizeFinalizeWrapperWithDataAndContext); + return New( + env, + callback, + resource, + resourceName, + maxQueueSize, + initialThreadCount, + context, + finalizeCallback, + data, + details::ThreadSafeFinalize:: + FinalizeFinalizeWrapperWithDataAndContext); } -inline ThreadSafeFunction::ThreadSafeFunction() - : _tsfn() { -} +inline ThreadSafeFunction::ThreadSafeFunction() : _tsfn() {} -inline ThreadSafeFunction::ThreadSafeFunction( - napi_threadsafe_function tsfn) - : _tsfn(tsfn) { -} +inline ThreadSafeFunction::ThreadSafeFunction(napi_threadsafe_function tsfn) + : _tsfn(tsfn) {} inline ThreadSafeFunction::operator napi_threadsafe_function() const { return _tsfn; @@ -5644,20 +5667,18 @@ inline napi_status ThreadSafeFunction::BlockingCall() const { } template <> -inline napi_status ThreadSafeFunction::BlockingCall( - void* data) const { +inline napi_status ThreadSafeFunction::BlockingCall(void* data) const { return napi_call_threadsafe_function(_tsfn, data, napi_tsfn_blocking); } template -inline napi_status ThreadSafeFunction::BlockingCall( - Callback callback) const { +inline napi_status ThreadSafeFunction::BlockingCall(Callback callback) const { return CallInternal(new CallbackWrapper(callback), napi_tsfn_blocking); } template -inline napi_status ThreadSafeFunction::BlockingCall( - DataType* data, Callback callback) const { +inline napi_status ThreadSafeFunction::BlockingCall(DataType* data, + Callback callback) const { auto wrapper = [data, callback](Env env, Function jsCallback) { callback(env, jsCallback, data); }; @@ -5669,8 +5690,7 @@ inline napi_status ThreadSafeFunction::NonBlockingCall() const { } template <> -inline napi_status ThreadSafeFunction::NonBlockingCall( - void* data) const { +inline napi_status ThreadSafeFunction::NonBlockingCall(void* data) const { return napi_call_threadsafe_function(_tsfn, data, napi_tsfn_nonblocking); } @@ -5715,17 +5735,21 @@ inline napi_status ThreadSafeFunction::Abort() const { return napi_release_threadsafe_function(_tsfn, napi_tsfn_abort); } -inline ThreadSafeFunction::ConvertibleContext -ThreadSafeFunction::GetContext() const { +inline ThreadSafeFunction::ConvertibleContext ThreadSafeFunction::GetContext() + const { void* context; napi_status status = napi_get_threadsafe_function_context(_tsfn, &context); - NAPI_FATAL_IF_FAILED(status, "ThreadSafeFunction::GetContext", "napi_get_threadsafe_function_context"); - return ConvertibleContext({ context }); + NAPI_FATAL_IF_FAILED(status, + "ThreadSafeFunction::GetContext", + "napi_get_threadsafe_function_context"); + return ConvertibleContext({context}); } // static -template +template inline ThreadSafeFunction ThreadSafeFunction::New(napi_env env, const Function& callback, const Object& resource, @@ -5736,16 +5760,26 @@ inline ThreadSafeFunction ThreadSafeFunction::New(napi_env env, Finalizer finalizeCallback, FinalizerDataType* data, napi_finalize wrapper) { - static_assert(details::can_make_string::value - || std::is_convertible::value, - "Resource name should be convertible to the string type"); + static_assert(details::can_make_string::value || + std::is_convertible::value, + "Resource name should be convertible to the string type"); ThreadSafeFunction tsfn; - auto* finalizeData = new details::ThreadSafeFinalize({ data, finalizeCallback }); - napi_status status = napi_create_threadsafe_function(env, callback, resource, - Value::From(env, resourceName), maxQueueSize, initialThreadCount, - finalizeData, wrapper, context, CallJS, &tsfn._tsfn); + auto* finalizeData = new details:: + ThreadSafeFinalize( + {data, finalizeCallback}); + napi_status status = + napi_create_threadsafe_function(env, + callback, + resource, + Value::From(env, resourceName), + maxQueueSize, + initialThreadCount, + finalizeData, + wrapper, + context, + CallJS, + &tsfn._tsfn); if (status != napi_ok) { delete finalizeData; NAPI_THROW_IF_FAILED(env, status, ThreadSafeFunction()); @@ -5757,8 +5791,8 @@ inline ThreadSafeFunction ThreadSafeFunction::New(napi_env env, inline napi_status ThreadSafeFunction::CallInternal( CallbackWrapper* callbackWrapper, napi_threadsafe_function_call_mode mode) const { - napi_status status = napi_call_threadsafe_function( - _tsfn, callbackWrapper, mode); + napi_status status = + napi_call_threadsafe_function(_tsfn, callbackWrapper, mode); if (status != napi_ok && callbackWrapper != nullptr) { delete callbackWrapper; } @@ -5788,13 +5822,15 @@ inline void ThreadSafeFunction::CallJS(napi_env env, // Async Progress Worker Base class //////////////////////////////////////////////////////////////////////////////// template -inline AsyncProgressWorkerBase::AsyncProgressWorkerBase(const Object& receiver, - const Function& callback, - const char* resource_name, - const Object& resource, - size_t queue_size) - : AsyncWorker(receiver, callback, resource_name, resource) { - // Fill all possible arguments to work around ambiguous ThreadSafeFunction::New signatures. +inline AsyncProgressWorkerBase::AsyncProgressWorkerBase( + const Object& receiver, + const Function& callback, + const char* resource_name, + const Object& resource, + size_t queue_size) + : AsyncWorker(receiver, callback, resource_name, resource) { + // Fill all possible arguments to work around ambiguous + // ThreadSafeFunction::New signatures. _tsfn = ThreadSafeFunction::New(callback.Env(), callback, resource, @@ -5808,15 +5844,18 @@ inline AsyncProgressWorkerBase::AsyncProgressWorkerBase(const Object& #if NAPI_VERSION > 4 template -inline AsyncProgressWorkerBase::AsyncProgressWorkerBase(Napi::Env env, - const char* resource_name, - const Object& resource, - size_t queue_size) - : AsyncWorker(env, resource_name, resource) { +inline AsyncProgressWorkerBase::AsyncProgressWorkerBase( + Napi::Env env, + const char* resource_name, + const Object& resource, + size_t queue_size) + : AsyncWorker(env, resource_name, resource) { // TODO: Once the changes to make the callback optional for threadsafe - // functions are available on all versions we can remove the dummy Function here. + // functions are available on all versions we can remove the dummy Function + // here. Function callback; - // Fill all possible arguments to work around ambiguous ThreadSafeFunction::New signatures. + // Fill all possible arguments to work around ambiguous + // ThreadSafeFunction::New signatures. _tsfn = ThreadSafeFunction::New(env, callback, resource, @@ -5829,38 +5868,45 @@ inline AsyncProgressWorkerBase::AsyncProgressWorkerBase(Napi::Env env, } #endif -template +template inline AsyncProgressWorkerBase::~AsyncProgressWorkerBase() { // Abort pending tsfn call. // Don't send progress events after we've already completed. - // It's ok to call ThreadSafeFunction::Abort and ThreadSafeFunction::Release duplicated. + // It's ok to call ThreadSafeFunction::Abort and ThreadSafeFunction::Release + // duplicated. _tsfn.Abort(); } template -inline void AsyncProgressWorkerBase::OnAsyncWorkProgress(Napi::Env /* env */, - Napi::Function /* jsCallback */, - void* data) { +inline void AsyncProgressWorkerBase::OnAsyncWorkProgress( + Napi::Env /* env */, Napi::Function /* jsCallback */, void* data) { ThreadSafeData* tsd = static_cast(data); tsd->asyncprogressworker()->OnWorkProgress(tsd->data()); delete tsd; } template -inline napi_status AsyncProgressWorkerBase::NonBlockingCall(DataType* data) { +inline napi_status AsyncProgressWorkerBase::NonBlockingCall( + DataType* data) { auto tsd = new AsyncProgressWorkerBase::ThreadSafeData(this, data); - return _tsfn.NonBlockingCall(tsd, OnAsyncWorkProgress); + auto ret = _tsfn.NonBlockingCall(tsd, OnAsyncWorkProgress); + if (ret != napi_ok) { + delete tsd; + } + return ret; } template -inline void AsyncProgressWorkerBase::OnWorkComplete(Napi::Env /* env */, napi_status status) { +inline void AsyncProgressWorkerBase::OnWorkComplete( + Napi::Env /* env */, napi_status status) { _work_completed = true; _complete_status = status; _tsfn.Release(); } template -inline void AsyncProgressWorkerBase::OnThreadSafeFunctionFinalize(Napi::Env env, void* /* data */, AsyncProgressWorkerBase* context) { +inline void AsyncProgressWorkerBase::OnThreadSafeFunctionFinalize( + Napi::Env env, void* /* data */, AsyncProgressWorkerBase* context) { if (context->_work_completed) { context->AsyncWorker::OnWorkComplete(env, context->_complete_status); } @@ -5869,76 +5915,65 @@ inline void AsyncProgressWorkerBase::OnThreadSafeFunctionFinalize(Napi //////////////////////////////////////////////////////////////////////////////// // Async Progress Worker class //////////////////////////////////////////////////////////////////////////////// -template +template inline AsyncProgressWorker::AsyncProgressWorker(const Function& callback) - : AsyncProgressWorker(callback, "generic") { -} + : AsyncProgressWorker(callback, "generic") {} -template +template inline AsyncProgressWorker::AsyncProgressWorker(const Function& callback, - const char* resource_name) - : AsyncProgressWorker(callback, resource_name, Object::New(callback.Env())) { -} + const char* resource_name) + : AsyncProgressWorker( + callback, resource_name, Object::New(callback.Env())) {} -template +template inline AsyncProgressWorker::AsyncProgressWorker(const Function& callback, - const char* resource_name, - const Object& resource) - : AsyncProgressWorker(Object::New(callback.Env()), - callback, - resource_name, - resource) { -} + const char* resource_name, + const Object& resource) + : AsyncProgressWorker( + Object::New(callback.Env()), callback, resource_name, resource) {} -template +template inline AsyncProgressWorker::AsyncProgressWorker(const Object& receiver, const Function& callback) - : AsyncProgressWorker(receiver, callback, "generic") { -} + : AsyncProgressWorker(receiver, callback, "generic") {} -template +template inline AsyncProgressWorker::AsyncProgressWorker(const Object& receiver, const Function& callback, const char* resource_name) - : AsyncProgressWorker(receiver, - callback, - resource_name, - Object::New(callback.Env())) { -} + : AsyncProgressWorker( + receiver, callback, resource_name, Object::New(callback.Env())) {} -template +template inline AsyncProgressWorker::AsyncProgressWorker(const Object& receiver, const Function& callback, const char* resource_name, const Object& resource) - : AsyncProgressWorkerBase(receiver, callback, resource_name, resource), - _asyncdata(nullptr), - _asyncsize(0) { -} + : AsyncProgressWorkerBase(receiver, callback, resource_name, resource), + _asyncdata(nullptr), + _asyncsize(0), + _signaled(false) {} #if NAPI_VERSION > 4 -template +template inline AsyncProgressWorker::AsyncProgressWorker(Napi::Env env) - : AsyncProgressWorker(env, "generic") { -} + : AsyncProgressWorker(env, "generic") {} -template +template inline AsyncProgressWorker::AsyncProgressWorker(Napi::Env env, const char* resource_name) - : AsyncProgressWorker(env, resource_name, Object::New(env)) { -} + : AsyncProgressWorker(env, resource_name, Object::New(env)) {} -template +template inline AsyncProgressWorker::AsyncProgressWorker(Napi::Env env, const char* resource_name, const Object& resource) - : AsyncProgressWorkerBase(env, resource_name, resource), - _asyncdata(nullptr), - _asyncsize(0) { -} + : AsyncProgressWorkerBase(env, resource_name, resource), + _asyncdata(nullptr), + _asyncsize(0) {} #endif -template +template inline AsyncProgressWorker::~AsyncProgressWorker() { { std::lock_guard lock(this->_mutex); @@ -5947,22 +5982,25 @@ inline AsyncProgressWorker::~AsyncProgressWorker() { } } -template +template inline void AsyncProgressWorker::Execute() { ExecutionProgress progress(this); Execute(progress); } -template +template inline void AsyncProgressWorker::OnWorkProgress(void*) { T* data; size_t size; + bool signaled; { std::lock_guard lock(this->_mutex); data = this->_asyncdata; size = this->_asyncsize; + signaled = this->_signaled; this->_asyncdata = nullptr; this->_asyncsize = 0; + this->_signaled = false; } /** @@ -5972,7 +6010,7 @@ inline void AsyncProgressWorker::OnWorkProgress(void*) { * the deferring the signal of uv_async_t is been sent again, i.e. potential * not coalesced two calls of the TSFN callback. */ - if (data == nullptr) { + if (data == nullptr && !signaled) { return; } @@ -5980,119 +6018,119 @@ inline void AsyncProgressWorker::OnWorkProgress(void*) { delete[] data; } -template +template inline void AsyncProgressWorker::SendProgress_(const T* data, size_t count) { - T* new_data = new T[count]; - std::copy(data, data + count, new_data); - - T* old_data; - { - std::lock_guard lock(this->_mutex); - old_data = _asyncdata; - _asyncdata = new_data; - _asyncsize = count; - } - this->NonBlockingCall(nullptr); + T* new_data = new T[count]; + std::copy(data, data + count, new_data); + + T* old_data; + { + std::lock_guard lock(this->_mutex); + old_data = _asyncdata; + _asyncdata = new_data; + _asyncsize = count; + _signaled = false; + } + this->NonBlockingCall(nullptr); - delete[] old_data; + delete[] old_data; } -template -inline void AsyncProgressWorker::Signal() const { +template +inline void AsyncProgressWorker::Signal() { + { + std::lock_guard lock(this->_mutex); + _signaled = true; + } this->NonBlockingCall(static_cast(nullptr)); } -template +template inline void AsyncProgressWorker::ExecutionProgress::Signal() const { - _worker->Signal(); + this->_worker->Signal(); } -template -inline void AsyncProgressWorker::ExecutionProgress::Send(const T* data, size_t count) const { +template +inline void AsyncProgressWorker::ExecutionProgress::Send( + const T* data, size_t count) const { _worker->SendProgress_(data, count); } //////////////////////////////////////////////////////////////////////////////// // Async Progress Queue Worker class //////////////////////////////////////////////////////////////////////////////// -template -inline AsyncProgressQueueWorker::AsyncProgressQueueWorker(const Function& callback) - : AsyncProgressQueueWorker(callback, "generic") { -} +template +inline AsyncProgressQueueWorker::AsyncProgressQueueWorker( + const Function& callback) + : AsyncProgressQueueWorker(callback, "generic") {} -template -inline AsyncProgressQueueWorker::AsyncProgressQueueWorker(const Function& callback, - const char* resource_name) - : AsyncProgressQueueWorker(callback, resource_name, Object::New(callback.Env())) { -} +template +inline AsyncProgressQueueWorker::AsyncProgressQueueWorker( + const Function& callback, const char* resource_name) + : AsyncProgressQueueWorker( + callback, resource_name, Object::New(callback.Env())) {} -template -inline AsyncProgressQueueWorker::AsyncProgressQueueWorker(const Function& callback, - const char* resource_name, - const Object& resource) - : AsyncProgressQueueWorker(Object::New(callback.Env()), - callback, - resource_name, - resource) { -} +template +inline AsyncProgressQueueWorker::AsyncProgressQueueWorker( + const Function& callback, const char* resource_name, const Object& resource) + : AsyncProgressQueueWorker( + Object::New(callback.Env()), callback, resource_name, resource) {} -template -inline AsyncProgressQueueWorker::AsyncProgressQueueWorker(const Object& receiver, - const Function& callback) - : AsyncProgressQueueWorker(receiver, callback, "generic") { -} +template +inline AsyncProgressQueueWorker::AsyncProgressQueueWorker( + const Object& receiver, const Function& callback) + : AsyncProgressQueueWorker(receiver, callback, "generic") {} -template -inline AsyncProgressQueueWorker::AsyncProgressQueueWorker(const Object& receiver, - const Function& callback, - const char* resource_name) - : AsyncProgressQueueWorker(receiver, - callback, - resource_name, - Object::New(callback.Env())) { -} +template +inline AsyncProgressQueueWorker::AsyncProgressQueueWorker( + const Object& receiver, const Function& callback, const char* resource_name) + : AsyncProgressQueueWorker( + receiver, callback, resource_name, Object::New(callback.Env())) {} -template -inline AsyncProgressQueueWorker::AsyncProgressQueueWorker(const Object& receiver, - const Function& callback, - const char* resource_name, - const Object& resource) - : AsyncProgressWorkerBase>(receiver, callback, resource_name, resource, /** unlimited queue size */0) { -} +template +inline AsyncProgressQueueWorker::AsyncProgressQueueWorker( + const Object& receiver, + const Function& callback, + const char* resource_name, + const Object& resource) + : AsyncProgressWorkerBase>( + receiver, + callback, + resource_name, + resource, + /** unlimited queue size */ 0) {} #if NAPI_VERSION > 4 -template +template inline AsyncProgressQueueWorker::AsyncProgressQueueWorker(Napi::Env env) - : AsyncProgressQueueWorker(env, "generic") { -} + : AsyncProgressQueueWorker(env, "generic") {} -template -inline AsyncProgressQueueWorker::AsyncProgressQueueWorker(Napi::Env env, - const char* resource_name) - : AsyncProgressQueueWorker(env, resource_name, Object::New(env)) { -} +template +inline AsyncProgressQueueWorker::AsyncProgressQueueWorker( + Napi::Env env, const char* resource_name) + : AsyncProgressQueueWorker(env, resource_name, Object::New(env)) {} -template -inline AsyncProgressQueueWorker::AsyncProgressQueueWorker(Napi::Env env, - const char* resource_name, - const Object& resource) - : AsyncProgressWorkerBase>(env, resource_name, resource, /** unlimited queue size */0) { -} +template +inline AsyncProgressQueueWorker::AsyncProgressQueueWorker( + Napi::Env env, const char* resource_name, const Object& resource) + : AsyncProgressWorkerBase>( + env, resource_name, resource, /** unlimited queue size */ 0) {} #endif -template +template inline void AsyncProgressQueueWorker::Execute() { ExecutionProgress progress(this); Execute(progress); } -template -inline void AsyncProgressQueueWorker::OnWorkProgress(std::pair* datapair) { +template +inline void AsyncProgressQueueWorker::OnWorkProgress( + std::pair* datapair) { if (datapair == nullptr) { return; } - T *data = datapair->first; + T* data = datapair->first; size_t size = datapair->second; this->OnProgress(data, size); @@ -6100,33 +6138,36 @@ inline void AsyncProgressQueueWorker::OnWorkProgress(std::pair* d delete[] data; } -template -inline void AsyncProgressQueueWorker::SendProgress_(const T* data, size_t count) { - T* new_data = new T[count]; - std::copy(data, data + count, new_data); +template +inline void AsyncProgressQueueWorker::SendProgress_(const T* data, + size_t count) { + T* new_data = new T[count]; + std::copy(data, data + count, new_data); - auto pair = new std::pair(new_data, count); - this->NonBlockingCall(pair); + auto pair = new std::pair(new_data, count); + this->NonBlockingCall(pair); } -template +template inline void AsyncProgressQueueWorker::Signal() const { - this->NonBlockingCall(nullptr); + this->SendProgress_(static_cast(nullptr), 0); } -template -inline void AsyncProgressQueueWorker::OnWorkComplete(Napi::Env env, napi_status status) { +template +inline void AsyncProgressQueueWorker::OnWorkComplete(Napi::Env env, + napi_status status) { // Draining queued items in TSFN. AsyncProgressWorkerBase>::OnWorkComplete(env, status); } -template +template inline void AsyncProgressQueueWorker::ExecutionProgress::Signal() const { - _worker->Signal(); + _worker->SendProgress_(static_cast(nullptr), 0); } -template -inline void AsyncProgressQueueWorker::ExecutionProgress::Send(const T* data, size_t count) const { +template +inline void AsyncProgressQueueWorker::ExecutionProgress::Send( + const T* data, size_t count) const { _worker->SendProgress_(data, count); } #endif // NAPI_VERSION > 3 && !defined(__wasm32__) @@ -6135,9 +6176,11 @@ inline void AsyncProgressQueueWorker::ExecutionProgress::Send(const T* data, // Memory Management class //////////////////////////////////////////////////////////////////////////////// -inline int64_t MemoryManagement::AdjustExternalMemory(Env env, int64_t change_in_bytes) { +inline int64_t MemoryManagement::AdjustExternalMemory(Env env, + int64_t change_in_bytes) { int64_t result; - napi_status status = napi_adjust_external_memory(env, change_in_bytes, &result); + napi_status status = + napi_adjust_external_memory(env, change_in_bytes, &result); NAPI_THROW_IF_FAILED(env, status, 0); return result; } @@ -6178,24 +6221,20 @@ inline T* Addon::Unwrap(Object wrapper) { } template -inline void -Addon::DefineAddon(Object exports, - const std::initializer_list& props) { +inline void Addon::DefineAddon( + Object exports, const std::initializer_list& props) { DefineProperties(exports, props); entry_point_ = exports; } template -inline Napi::Object -Addon::DefineProperties(Object object, - const std::initializer_list& props) { +inline Napi::Object Addon::DefineProperties( + Object object, const std::initializer_list& props) { const napi_property_descriptor* properties = - reinterpret_cast(props.begin()); + reinterpret_cast(props.begin()); size_t size = props.size(); - napi_status status = napi_define_properties(object.Env(), - object, - size, - properties); + napi_status status = + napi_define_properties(object.Env(), object, size, properties); NAPI_THROW_IF_FAILED(object.Env(), status, object); for (size_t idx = 0; idx < size; idx++) T::AttachPropData(object.Env(), object, &properties[idx]); @@ -6214,6 +6253,11 @@ Env::CleanupHook Env::AddCleanupHook(Hook hook) { return CleanupHook(*this, hook); } +template +Env::CleanupHook::CleanupHook() { + data = nullptr; +} + template Env::CleanupHook::CleanupHook(Napi::Env env, Hook hook) : wrapper(Env::CleanupHook::Wrapper) { @@ -6254,6 +6298,6 @@ bool Env::CleanupHook::IsEmpty() const { } // namespace NAPI_CPP_CUSTOM_NAMESPACE #endif -} // namespace Napi +} // namespace Napi -#endif // SRC_NAPI_INL_H_ +#endif // SRC_NAPI_INL_H_ diff --git a/node_modules/node-addon-api/napi.h b/node_modules/node-addon-api/napi.h index c88ca3d4..831b3b6d 100644 --- a/node_modules/node-addon-api/napi.h +++ b/node_modules/node-addon-api/napi.h @@ -9,29 +9,32 @@ #include #include -// VS2015 RTM has bugs with constexpr, so require min of VS2015 Update 3 (known good version) +// VS2015 RTM has bugs with constexpr, so require min of VS2015 Update 3 (known +// good version) #if !defined(_MSC_VER) || _MSC_FULL_VER >= 190024210 #define NAPI_HAS_CONSTEXPR 1 #endif -// VS2013 does not support char16_t literal strings, so we'll work around it using wchar_t strings -// and casting them. This is safe as long as the character sizes are the same. +// VS2013 does not support char16_t literal strings, so we'll work around it +// using wchar_t strings and casting them. This is safe as long as the character +// sizes are the same. #if defined(_MSC_VER) && _MSC_VER <= 1800 -static_assert(sizeof(char16_t) == sizeof(wchar_t), "Size mismatch between char16_t and wchar_t"); -#define NAPI_WIDE_TEXT(x) reinterpret_cast(L ## x) +static_assert(sizeof(char16_t) == sizeof(wchar_t), + "Size mismatch between char16_t and wchar_t"); +#define NAPI_WIDE_TEXT(x) reinterpret_cast(L##x) #else -#define NAPI_WIDE_TEXT(x) u ## x +#define NAPI_WIDE_TEXT(x) u##x #endif // If C++ exceptions are not explicitly enabled or disabled, enable them // if exceptions were enabled in the compiler settings. #if !defined(NAPI_CPP_EXCEPTIONS) && !defined(NAPI_DISABLE_CPP_EXCEPTIONS) - #if defined(_CPPUNWIND) || defined (__EXCEPTIONS) - #define NAPI_CPP_EXCEPTIONS - #else - #error Exception support not detected. \ +#if defined(_CPPUNWIND) || defined(__EXCEPTIONS) +#define NAPI_CPP_EXCEPTIONS +#else +#error Exception support not detected. \ Define either NAPI_CPP_EXCEPTIONS or NAPI_DISABLE_CPP_EXCEPTIONS. - #endif +#endif #endif // If C++ NAPI_CPP_EXCEPTIONS are enabled, NODE_ADDON_API_ENABLE_MAYBE should @@ -42,9 +45,9 @@ static_assert(sizeof(char16_t) == sizeof(wchar_t), "Size mismatch between char16 #endif #ifdef _NOEXCEPT - #define NAPI_NOEXCEPT _NOEXCEPT +#define NAPI_NOEXCEPT _NOEXCEPT #else - #define NAPI_NOEXCEPT noexcept +#define NAPI_NOEXCEPT noexcept #endif #ifdef NAPI_CPP_EXCEPTIONS @@ -55,16 +58,16 @@ static_assert(sizeof(char16_t) == sizeof(wchar_t), "Size mismatch between char16 // We need _VOID versions of the macros to avoid warnings resulting from // leaving the NAPI_THROW_* `...` argument empty. -#define NAPI_THROW(e, ...) throw e -#define NAPI_THROW_VOID(e) throw e +#define NAPI_THROW(e, ...) throw e +#define NAPI_THROW_VOID(e) throw e -#define NAPI_THROW_IF_FAILED(env, status, ...) \ +#define NAPI_THROW_IF_FAILED(env, status, ...) \ if ((status) != napi_ok) throw Napi::Error::New(env); -#define NAPI_THROW_IF_FAILED_VOID(env, status) \ +#define NAPI_THROW_IF_FAILED_VOID(env, status) \ if ((status) != napi_ok) throw Napi::Error::New(env); -#else // NAPI_CPP_EXCEPTIONS +#else // NAPI_CPP_EXCEPTIONS // When C++ exceptions are disabled, Errors are thrown as JavaScript exceptions, // which are pending until the callback returns to JS. The variadic parameter @@ -72,16 +75,16 @@ static_assert(sizeof(char16_t) == sizeof(wchar_t), "Size mismatch between char16 // We need _VOID versions of the macros to avoid warnings resulting from // leaving the NAPI_THROW_* `...` argument empty. -#define NAPI_THROW(e, ...) \ - do { \ - (e).ThrowAsJavaScriptException(); \ - return __VA_ARGS__; \ +#define NAPI_THROW(e, ...) \ + do { \ + (e).ThrowAsJavaScriptException(); \ + return __VA_ARGS__; \ } while (0) -#define NAPI_THROW_VOID(e) \ - do { \ - (e).ThrowAsJavaScriptException(); \ - return; \ +#define NAPI_THROW_VOID(e) \ + do { \ + (e).ThrowAsJavaScriptException(); \ + return; \ } while (0) #define NAPI_THROW_IF_FAILED(env, status, ...) \ @@ -96,7 +99,7 @@ static_assert(sizeof(char16_t) == sizeof(wchar_t), "Size mismatch between char16 return; \ } -#endif // NAPI_CPP_EXCEPTIONS +#endif // NAPI_CPP_EXCEPTIONS #ifdef NODE_ADDON_API_ENABLE_MAYBE #define NAPI_MAYBE_THROW_IF_FAILED(env, status, type) \ @@ -114,12 +117,12 @@ static_assert(sizeof(char16_t) == sizeof(wchar_t), "Size mismatch between char16 return result; #endif -# define NAPI_DISALLOW_ASSIGN(CLASS) void operator=(const CLASS&) = delete; -# define NAPI_DISALLOW_COPY(CLASS) CLASS(const CLASS&) = delete; +#define NAPI_DISALLOW_ASSIGN(CLASS) void operator=(const CLASS&) = delete; +#define NAPI_DISALLOW_COPY(CLASS) CLASS(const CLASS&) = delete; -#define NAPI_DISALLOW_ASSIGN_COPY(CLASS) \ - NAPI_DISALLOW_ASSIGN(CLASS) \ - NAPI_DISALLOW_COPY(CLASS) +#define NAPI_DISALLOW_ASSIGN_COPY(CLASS) \ + NAPI_DISALLOW_ASSIGN(CLASS) \ + NAPI_DISALLOW_COPY(CLASS) #define NAPI_CHECK(condition, location, message) \ do { \ @@ -152,2852 +155,2960 @@ using namespace NAPI_CPP_CUSTOM_NAMESPACE; namespace NAPI_CPP_CUSTOM_NAMESPACE { #endif - // Forward declarations - class Env; - class Value; - class Boolean; - class Number; +// Forward declarations +class Env; +class Value; +class Boolean; +class Number; #if NAPI_VERSION > 5 - class BigInt; +class BigInt; #endif // NAPI_VERSION > 5 #if (NAPI_VERSION > 4) - class Date; +class Date; #endif - class String; - class Object; - class Array; - class ArrayBuffer; - class Function; - class Error; - class PropertyDescriptor; - class CallbackInfo; - class TypedArray; - template class TypedArrayOf; - - using Int8Array = - TypedArrayOf; ///< Typed-array of signed 8-bit integers - using Uint8Array = - TypedArrayOf; ///< Typed-array of unsigned 8-bit integers - using Int16Array = - TypedArrayOf; ///< Typed-array of signed 16-bit integers - using Uint16Array = - TypedArrayOf; ///< Typed-array of unsigned 16-bit integers - using Int32Array = - TypedArrayOf; ///< Typed-array of signed 32-bit integers - using Uint32Array = - TypedArrayOf; ///< Typed-array of unsigned 32-bit integers - using Float32Array = - TypedArrayOf; ///< Typed-array of 32-bit floating-point values - using Float64Array = - TypedArrayOf; ///< Typed-array of 64-bit floating-point values +class String; +class Object; +class Array; +class ArrayBuffer; +class Function; +class Error; +class PropertyDescriptor; +class CallbackInfo; +class TypedArray; +template +class TypedArrayOf; + +using Int8Array = + TypedArrayOf; ///< Typed-array of signed 8-bit integers +using Uint8Array = + TypedArrayOf; ///< Typed-array of unsigned 8-bit integers +using Int16Array = + TypedArrayOf; ///< Typed-array of signed 16-bit integers +using Uint16Array = + TypedArrayOf; ///< Typed-array of unsigned 16-bit integers +using Int32Array = + TypedArrayOf; ///< Typed-array of signed 32-bit integers +using Uint32Array = + TypedArrayOf; ///< Typed-array of unsigned 32-bit integers +using Float32Array = + TypedArrayOf; ///< Typed-array of 32-bit floating-point values +using Float64Array = + TypedArrayOf; ///< Typed-array of 64-bit floating-point values #if NAPI_VERSION > 5 - using BigInt64Array = - TypedArrayOf; ///< Typed array of signed 64-bit integers - using BigUint64Array = - TypedArrayOf; ///< Typed array of unsigned 64-bit integers -#endif // NAPI_VERSION > 5 - - /// Defines the signature of a Node-API C++ module's registration callback - /// (init) function. - using ModuleRegisterCallback = Object (*)(Env env, Object exports); - - class MemoryManagement; - - /// A simple Maybe type, representing an object which may or may not have a - /// value. - /// - /// If an API method returns a Maybe<>, the API method can potentially fail - /// either because an exception is thrown, or because an exception is pending, - /// e.g. because a previous API call threw an exception that hasn't been - /// caught yet. In that case, a "Nothing" value is returned. - template - class Maybe { - public: - bool IsNothing() const; - bool IsJust() const; - - /// Short-hand for Unwrap(), which doesn't return a value. Could be used - /// where the actual value of the Maybe is not needed like Object::Set. - /// If this Maybe is nothing (empty), node-addon-api will crash the - /// process. - void Check() const; - - /// Return the value of type T contained in the Maybe. If this Maybe is - /// nothing (empty), node-addon-api will crash the process. - T Unwrap() const; - - /// Return the value of type T contained in the Maybe, or using a default - /// value if this Maybe is nothing (empty). - T UnwrapOr(const T& default_value) const; - - /// Converts this Maybe to a value of type T in the out. If this Maybe is - /// nothing (empty), `false` is returned and `out` is left untouched. - bool UnwrapTo(T* out) const; - - bool operator==(const Maybe& other) const; - bool operator!=(const Maybe& other) const; - - private: - Maybe(); - explicit Maybe(const T& t); - - bool _has_value; - T _value; +using BigInt64Array = + TypedArrayOf; ///< Typed array of signed 64-bit integers +using BigUint64Array = + TypedArrayOf; ///< Typed array of unsigned 64-bit integers +#endif // NAPI_VERSION > 5 - template - friend Maybe Nothing(); - template - friend Maybe Just(const U& u); - }; +/// Defines the signature of a Node-API C++ module's registration callback +/// (init) function. +using ModuleRegisterCallback = Object (*)(Env env, Object exports); - template - inline Maybe Nothing(); +class MemoryManagement; - template - inline Maybe Just(const T& t); +/// A simple Maybe type, representing an object which may or may not have a +/// value. +/// +/// If an API method returns a Maybe<>, the API method can potentially fail +/// either because an exception is thrown, or because an exception is pending, +/// e.g. because a previous API call threw an exception that hasn't been +/// caught yet. In that case, a "Nothing" value is returned. +template +class Maybe { + public: + bool IsNothing() const; + bool IsJust() const; + + /// Short-hand for Unwrap(), which doesn't return a value. Could be used + /// where the actual value of the Maybe is not needed like Object::Set. + /// If this Maybe is nothing (empty), node-addon-api will crash the + /// process. + void Check() const; + + /// Return the value of type T contained in the Maybe. If this Maybe is + /// nothing (empty), node-addon-api will crash the process. + T Unwrap() const; + + /// Return the value of type T contained in the Maybe, or using a default + /// value if this Maybe is nothing (empty). + T UnwrapOr(const T& default_value) const; + + /// Converts this Maybe to a value of type T in the out. If this Maybe is + /// nothing (empty), `false` is returned and `out` is left untouched. + bool UnwrapTo(T* out) const; + + bool operator==(const Maybe& other) const; + bool operator!=(const Maybe& other) const; + + private: + Maybe(); + explicit Maybe(const T& t); + + bool _has_value; + T _value; + + template + friend Maybe Nothing(); + template + friend Maybe Just(const U& u); +}; + +template +inline Maybe Nothing(); + +template +inline Maybe Just(const T& t); #if defined(NODE_ADDON_API_ENABLE_MAYBE) - template - using MaybeOrValue = Maybe; +template +using MaybeOrValue = Maybe; #else - template - using MaybeOrValue = T; +template +using MaybeOrValue = T; #endif - /// Environment for Node-API values and operations. - /// - /// All Node-API values and operations must be associated with an environment. - /// An environment instance is always provided to callback functions; that - /// environment must then be used for any creation of Node-API values or other - /// Node-API operations within the callback. (Many methods infer the - /// environment from the `this` instance that the method is called on.) - /// - /// In the future, multiple environments per process may be supported, - /// although current implementations only support one environment per process. - /// - /// In the V8 JavaScript engine, a Node-API environment approximately - /// corresponds to an Isolate. - class Env { - private: -#if NAPI_VERSION > 2 - template - class CleanupHook; -#endif // NAPI_VERSION > 2 +/// Environment for Node-API values and operations. +/// +/// All Node-API values and operations must be associated with an environment. +/// An environment instance is always provided to callback functions; that +/// environment must then be used for any creation of Node-API values or other +/// Node-API operations within the callback. (Many methods infer the +/// environment from the `this` instance that the method is called on.) +/// +/// In the future, multiple environments per process may be supported, +/// although current implementations only support one environment per process. +/// +/// In the V8 JavaScript engine, a Node-API environment approximately +/// corresponds to an Isolate. +class Env { + private: + napi_env _env; #if NAPI_VERSION > 5 - template static void DefaultFini(Env, T* data); - template - static void DefaultFiniWithHint(Env, DataType* data, HintType* hint); + template + static void DefaultFini(Env, T* data); + template + static void DefaultFiniWithHint(Env, DataType* data, HintType* hint); #endif // NAPI_VERSION > 5 - public: - Env(napi_env env); + public: + Env(napi_env env); - operator napi_env() const; + operator napi_env() const; - Object Global() const; - Value Undefined() const; - Value Null() const; + Object Global() const; + Value Undefined() const; + Value Null() const; - bool IsExceptionPending() const; - Error GetAndClearPendingException() const; + bool IsExceptionPending() const; + Error GetAndClearPendingException() const; - MaybeOrValue RunScript(const char* utf8script) const; - MaybeOrValue RunScript(const std::string& utf8script) const; - MaybeOrValue RunScript(String script) const; + MaybeOrValue RunScript(const char* utf8script) const; + MaybeOrValue RunScript(const std::string& utf8script) const; + MaybeOrValue RunScript(String script) const; #if NAPI_VERSION > 2 - template - CleanupHook AddCleanupHook(Hook hook); + template + class CleanupHook; - template - CleanupHook AddCleanupHook(Hook hook, Arg* arg); + template + CleanupHook AddCleanupHook(Hook hook); + + template + CleanupHook AddCleanupHook(Hook hook, Arg* arg); #endif // NAPI_VERSION > 2 #if NAPI_VERSION > 5 - template - T* GetInstanceData() const; - - template using Finalizer = void (*)(Env, T*); - template fini = Env::DefaultFini> - void SetInstanceData(T* data) const; - - template - using FinalizerWithHint = void (*)(Env, DataType*, HintType*); - template fini = - Env::DefaultFiniWithHint> - void SetInstanceData(DataType* data, HintType* hint) const; -#endif // NAPI_VERSION > 5 + template + T* GetInstanceData() const; - private: - napi_env _env; + template + using Finalizer = void (*)(Env, T*); + template fini = Env::DefaultFini> + void SetInstanceData(T* data) const; + + template + using FinalizerWithHint = void (*)(Env, DataType*, HintType*); + template fini = + Env::DefaultFiniWithHint> + void SetInstanceData(DataType* data, HintType* hint) const; +#endif // NAPI_VERSION > 5 #if NAPI_VERSION > 2 - template - class CleanupHook { - public: - CleanupHook(Env env, Hook hook, Arg* arg); - CleanupHook(Env env, Hook hook); - bool Remove(Env env); - bool IsEmpty() const; - - private: - static inline void Wrapper(void* data) NAPI_NOEXCEPT; - static inline void WrapperWithArg(void* data) NAPI_NOEXCEPT; - - void (*wrapper)(void* arg); - struct CleanupData { - Hook hook; - Arg* arg; - } * data; - }; + template + class CleanupHook { + public: + CleanupHook(); + CleanupHook(Env env, Hook hook, Arg* arg); + CleanupHook(Env env, Hook hook); + bool Remove(Env env); + bool IsEmpty() const; + + private: + static inline void Wrapper(void* data) NAPI_NOEXCEPT; + static inline void WrapperWithArg(void* data) NAPI_NOEXCEPT; + + void (*wrapper)(void* arg); + struct CleanupData { + Hook hook; + Arg* arg; + } * data; }; #endif // NAPI_VERSION > 2 +}; - /// A JavaScript value of unknown type. - /// - /// For type-specific operations, convert to one of the Value subclasses using a `To*` or `As()` - /// method. The `To*` methods do type coercion; the `As()` method does not. +/// A JavaScript value of unknown type. +/// +/// For type-specific operations, convert to one of the Value subclasses using a +/// `To*` or `As()` method. The `To*` methods do type coercion; the `As()` +/// method does not. +/// +/// Napi::Value value = ... +/// if (!value.IsString()) throw Napi::TypeError::New(env, "Invalid +/// arg..."); Napi::String str = value.As(); // Cast to a +/// string value +/// +/// Napi::Value anotherValue = ... +/// bool isTruthy = anotherValue.ToBoolean(); // Coerce to a boolean value +class Value { + public: + Value(); ///< Creates a new _empty_ Value instance. + Value(napi_env env, + napi_value value); ///< Wraps a Node-API value primitive. + + /// Creates a JS value from a C++ primitive. /// - /// Napi::Value value = ... - /// if (!value.IsString()) throw Napi::TypeError::New(env, "Invalid arg..."); - /// Napi::String str = value.As(); // Cast to a string value + /// `value` may be any of: + /// - bool + /// - Any integer type + /// - Any floating point type + /// - const char* (encoded using UTF-8, null-terminated) + /// - const char16_t* (encoded using UTF-16-LE, null-terminated) + /// - std::string (encoded using UTF-8) + /// - std::u16string + /// - napi::Value + /// - napi_value + template + static Value From(napi_env env, const T& value); + + /// Converts to a Node-API value primitive. /// - /// Napi::Value anotherValue = ... - /// bool isTruthy = anotherValue.ToBoolean(); // Coerce to a boolean value - class Value { - public: - Value(); ///< Creates a new _empty_ Value instance. - Value(napi_env env, - napi_value value); ///< Wraps a Node-API value primitive. + /// If the instance is _empty_, this returns `nullptr`. + operator napi_value() const; - /// Creates a JS value from a C++ primitive. - /// - /// `value` may be any of: - /// - bool - /// - Any integer type - /// - Any floating point type - /// - const char* (encoded using UTF-8, null-terminated) - /// - const char16_t* (encoded using UTF-16-LE, null-terminated) - /// - std::string (encoded using UTF-8) - /// - std::u16string - /// - napi::Value - /// - napi_value - template - static Value From(napi_env env, const T& value); - - /// Converts to a Node-API value primitive. - /// - /// If the instance is _empty_, this returns `nullptr`. - operator napi_value() const; - - /// Tests if this value strictly equals another value. - bool operator ==(const Value& other) const; - - /// Tests if this value does not strictly equal another value. - bool operator !=(const Value& other) const; - - /// Tests if this value strictly equals another value. - bool StrictEquals(const Value& other) const; - - /// Gets the environment the value is associated with. - Napi::Env Env() const; + /// Tests if this value strictly equals another value. + bool operator==(const Value& other) const; - /// Checks if the value is empty (uninitialized). - /// - /// An empty value is invalid, and most attempts to perform an operation on an empty value - /// will result in an exception. Note an empty value is distinct from JavaScript `null` or - /// `undefined`, which are valid values. - /// - /// When C++ exceptions are disabled at compile time, a method with a `Value` return type may - /// return an empty value to indicate a pending exception. So when not using C++ exceptions, - /// callers should check whether the value is empty before attempting to use it. - bool IsEmpty() const; + /// Tests if this value does not strictly equal another value. + bool operator!=(const Value& other) const; + + /// Tests if this value strictly equals another value. + bool StrictEquals(const Value& other) const; - napi_valuetype Type() const; ///< Gets the type of the value. + /// Gets the environment the value is associated with. + Napi::Env Env() const; - bool IsUndefined() const; ///< Tests if a value is an undefined JavaScript value. - bool IsNull() const; ///< Tests if a value is a null JavaScript value. - bool IsBoolean() const; ///< Tests if a value is a JavaScript boolean. - bool IsNumber() const; ///< Tests if a value is a JavaScript number. + /// Checks if the value is empty (uninitialized). + /// + /// An empty value is invalid, and most attempts to perform an operation on an + /// empty value will result in an exception. Note an empty value is distinct + /// from JavaScript `null` or `undefined`, which are valid values. + /// + /// When C++ exceptions are disabled at compile time, a method with a `Value` + /// return type may return an empty value to indicate a pending exception. So + /// when not using C++ exceptions, callers should check whether the value is + /// empty before attempting to use it. + bool IsEmpty() const; + + napi_valuetype Type() const; ///< Gets the type of the value. + + bool IsUndefined() + const; ///< Tests if a value is an undefined JavaScript value. + bool IsNull() const; ///< Tests if a value is a null JavaScript value. + bool IsBoolean() const; ///< Tests if a value is a JavaScript boolean. + bool IsNumber() const; ///< Tests if a value is a JavaScript number. #if NAPI_VERSION > 5 - bool IsBigInt() const; ///< Tests if a value is a JavaScript bigint. -#endif // NAPI_VERSION > 5 + bool IsBigInt() const; ///< Tests if a value is a JavaScript bigint. +#endif // NAPI_VERSION > 5 #if (NAPI_VERSION > 4) - bool IsDate() const; ///< Tests if a value is a JavaScript date. + bool IsDate() const; ///< Tests if a value is a JavaScript date. #endif - bool IsString() const; ///< Tests if a value is a JavaScript string. - bool IsSymbol() const; ///< Tests if a value is a JavaScript symbol. - bool IsArray() const; ///< Tests if a value is a JavaScript array. - bool IsArrayBuffer() const; ///< Tests if a value is a JavaScript array buffer. - bool IsTypedArray() const; ///< Tests if a value is a JavaScript typed array. - bool IsObject() const; ///< Tests if a value is a JavaScript object. - bool IsFunction() const; ///< Tests if a value is a JavaScript function. - bool IsPromise() const; ///< Tests if a value is a JavaScript promise. - bool IsDataView() const; ///< Tests if a value is a JavaScript data view. - bool IsBuffer() const; ///< Tests if a value is a Node buffer. - bool IsExternal() const; ///< Tests if a value is a pointer to external data. - - /// Casts to another type of `Napi::Value`, when the actual type is known or assumed. - /// - /// This conversion does NOT coerce the type. Calling any methods inappropriate for the actual - /// value type will throw `Napi::Error`. - template T As() const; - - MaybeOrValue ToBoolean() - const; ///< Coerces a value to a JavaScript boolean. - MaybeOrValue ToNumber() - const; ///< Coerces a value to a JavaScript number. - MaybeOrValue ToString() - const; ///< Coerces a value to a JavaScript string. - MaybeOrValue ToObject() - const; ///< Coerces a value to a JavaScript object. - - protected: - /// !cond INTERNAL - napi_env _env; - napi_value _value; - /// !endcond - }; - - /// A JavaScript boolean value. - class Boolean : public Value { - public: - static Boolean New(napi_env env, ///< Node-API environment - bool value ///< Boolean value - ); - - Boolean(); ///< Creates a new _empty_ Boolean instance. - Boolean(napi_env env, - napi_value value); ///< Wraps a Node-API value primitive. + bool IsString() const; ///< Tests if a value is a JavaScript string. + bool IsSymbol() const; ///< Tests if a value is a JavaScript symbol. + bool IsArray() const; ///< Tests if a value is a JavaScript array. + bool IsArrayBuffer() + const; ///< Tests if a value is a JavaScript array buffer. + bool IsTypedArray() const; ///< Tests if a value is a JavaScript typed array. + bool IsObject() const; ///< Tests if a value is a JavaScript object. + bool IsFunction() const; ///< Tests if a value is a JavaScript function. + bool IsPromise() const; ///< Tests if a value is a JavaScript promise. + bool IsDataView() const; ///< Tests if a value is a JavaScript data view. + bool IsBuffer() const; ///< Tests if a value is a Node buffer. + bool IsExternal() const; ///< Tests if a value is a pointer to external data. + + /// Casts to another type of `Napi::Value`, when the actual type is known or + /// assumed. + /// + /// This conversion does NOT coerce the type. Calling any methods + /// inappropriate for the actual value type will throw `Napi::Error`. + template + T As() const; + + MaybeOrValue ToBoolean() + const; ///< Coerces a value to a JavaScript boolean. + MaybeOrValue ToNumber() + const; ///< Coerces a value to a JavaScript number. + MaybeOrValue ToString() + const; ///< Coerces a value to a JavaScript string. + MaybeOrValue ToObject() + const; ///< Coerces a value to a JavaScript object. + + protected: + /// !cond INTERNAL + napi_env _env; + napi_value _value; + /// !endcond +}; + +/// A JavaScript boolean value. +class Boolean : public Value { + public: + static Boolean New(napi_env env, ///< Node-API environment + bool value ///< Boolean value + ); + + Boolean(); ///< Creates a new _empty_ Boolean instance. + Boolean(napi_env env, + napi_value value); ///< Wraps a Node-API value primitive. - operator bool() const; ///< Converts a Boolean value to a boolean primitive. - bool Value() const; ///< Converts a Boolean value to a boolean primitive. - }; + operator bool() const; ///< Converts a Boolean value to a boolean primitive. + bool Value() const; ///< Converts a Boolean value to a boolean primitive. +}; - /// A JavaScript number value. - class Number : public Value { - public: - static Number New(napi_env env, ///< Node-API environment - double value ///< Number value - ); +/// A JavaScript number value. +class Number : public Value { + public: + static Number New(napi_env env, ///< Node-API environment + double value ///< Number value + ); - Number(); ///< Creates a new _empty_ Number instance. - Number(napi_env env, - napi_value value); ///< Wraps a Node-API value primitive. + Number(); ///< Creates a new _empty_ Number instance. + Number(napi_env env, + napi_value value); ///< Wraps a Node-API value primitive. - operator int32_t() - const; ///< Converts a Number value to a 32-bit signed integer value. - operator uint32_t() - const; ///< Converts a Number value to a 32-bit unsigned integer value. - operator int64_t() - const; ///< Converts a Number value to a 64-bit signed integer value. - operator float() - const; ///< Converts a Number value to a 32-bit floating-point value. - operator double() - const; ///< Converts a Number value to a 64-bit floating-point value. - - int32_t Int32Value() - const; ///< Converts a Number value to a 32-bit signed integer value. - uint32_t Uint32Value() - const; ///< Converts a Number value to a 32-bit unsigned integer value. - int64_t Int64Value() - const; ///< Converts a Number value to a 64-bit signed integer value. - float FloatValue() - const; ///< Converts a Number value to a 32-bit floating-point value. - double DoubleValue() - const; ///< Converts a Number value to a 64-bit floating-point value. - }; + operator int32_t() + const; ///< Converts a Number value to a 32-bit signed integer value. + operator uint32_t() + const; ///< Converts a Number value to a 32-bit unsigned integer value. + operator int64_t() + const; ///< Converts a Number value to a 64-bit signed integer value. + operator float() + const; ///< Converts a Number value to a 32-bit floating-point value. + operator double() + const; ///< Converts a Number value to a 64-bit floating-point value. + + int32_t Int32Value() + const; ///< Converts a Number value to a 32-bit signed integer value. + uint32_t Uint32Value() + const; ///< Converts a Number value to a 32-bit unsigned integer value. + int64_t Int64Value() + const; ///< Converts a Number value to a 64-bit signed integer value. + float FloatValue() + const; ///< Converts a Number value to a 32-bit floating-point value. + double DoubleValue() + const; ///< Converts a Number value to a 64-bit floating-point value. +}; #if NAPI_VERSION > 5 - /// A JavaScript bigint value. - class BigInt : public Value { - public: - static BigInt New(napi_env env, ///< Node-API environment - int64_t value ///< Number value - ); - static BigInt New(napi_env env, ///< Node-API environment - uint64_t value ///< Number value - ); - - /// Creates a new BigInt object using a specified sign bit and a - /// specified list of digits/words. - /// The resulting number is calculated as: - /// (-1)^sign_bit * (words[0] * (2^64)^0 + words[1] * (2^64)^1 + ...) - static BigInt New(napi_env env, ///< Node-API environment - int sign_bit, ///< Sign bit. 1 if negative. - size_t word_count, ///< Number of words in array - const uint64_t* words ///< Array of words - ); - - BigInt(); ///< Creates a new _empty_ BigInt instance. - BigInt(napi_env env, - napi_value value); ///< Wraps a Node-API value primitive. +/// A JavaScript bigint value. +class BigInt : public Value { + public: + static BigInt New(napi_env env, ///< Node-API environment + int64_t value ///< Number value + ); + static BigInt New(napi_env env, ///< Node-API environment + uint64_t value ///< Number value + ); + + /// Creates a new BigInt object using a specified sign bit and a + /// specified list of digits/words. + /// The resulting number is calculated as: + /// (-1)^sign_bit * (words[0] * (2^64)^0 + words[1] * (2^64)^1 + ...) + static BigInt New(napi_env env, ///< Node-API environment + int sign_bit, ///< Sign bit. 1 if negative. + size_t word_count, ///< Number of words in array + const uint64_t* words ///< Array of words + ); + + BigInt(); ///< Creates a new _empty_ BigInt instance. + BigInt(napi_env env, + napi_value value); ///< Wraps a Node-API value primitive. - int64_t Int64Value(bool* lossless) - const; ///< Converts a BigInt value to a 64-bit signed integer value. - uint64_t Uint64Value(bool* lossless) - const; ///< Converts a BigInt value to a 64-bit unsigned integer value. - - size_t WordCount() const; ///< The number of 64-bit words needed to store - ///< the result of ToWords(). - - /// Writes the contents of this BigInt to a specified memory location. - /// `sign_bit` must be provided and will be set to 1 if this BigInt is - /// negative. - /// `*word_count` has to be initialized to the length of the `words` array. - /// Upon return, it will be set to the actual number of words that would - /// be needed to store this BigInt (i.e. the return value of `WordCount()`). - void ToWords(int* sign_bit, size_t* word_count, uint64_t* words); - }; + int64_t Int64Value(bool* lossless) + const; ///< Converts a BigInt value to a 64-bit signed integer value. + uint64_t Uint64Value(bool* lossless) + const; ///< Converts a BigInt value to a 64-bit unsigned integer value. + + size_t WordCount() const; ///< The number of 64-bit words needed to store + ///< the result of ToWords(). + + /// Writes the contents of this BigInt to a specified memory location. + /// `sign_bit` must be provided and will be set to 1 if this BigInt is + /// negative. + /// `*word_count` has to be initialized to the length of the `words` array. + /// Upon return, it will be set to the actual number of words that would + /// be needed to store this BigInt (i.e. the return value of `WordCount()`). + void ToWords(int* sign_bit, size_t* word_count, uint64_t* words); +}; #endif // NAPI_VERSION > 5 #if (NAPI_VERSION > 4) - /// A JavaScript date value. - class Date : public Value { - public: - /// Creates a new Date value from a double primitive. - static Date New(napi_env env, ///< Node-API environment - double value ///< Number value - ); - - Date(); ///< Creates a new _empty_ Date instance. - Date(napi_env env, napi_value value); ///< Wraps a Node-API value primitive. - operator double() const; ///< Converts a Date value to double primitive - - double ValueOf() const; ///< Converts a Date value to a double primitive. - }; - #endif +/// A JavaScript date value. +class Date : public Value { + public: + /// Creates a new Date value from a double primitive. + static Date New(napi_env env, ///< Node-API environment + double value ///< Number value + ); + + Date(); ///< Creates a new _empty_ Date instance. + Date(napi_env env, napi_value value); ///< Wraps a Node-API value primitive. + operator double() const; ///< Converts a Date value to double primitive + + double ValueOf() const; ///< Converts a Date value to a double primitive. +}; +#endif - /// A JavaScript string or symbol value (that can be used as a property name). - class Name : public Value { - public: - Name(); ///< Creates a new _empty_ Name instance. - Name(napi_env env, +/// A JavaScript string or symbol value (that can be used as a property name). +class Name : public Value { + public: + Name(); ///< Creates a new _empty_ Name instance. + Name(napi_env env, + napi_value value); ///< Wraps a Node-API value primitive. +}; + +/// A JavaScript string value. +class String : public Name { + public: + /// Creates a new String value from a UTF-8 encoded C++ string. + static String New(napi_env env, ///< Node-API environment + const std::string& value ///< UTF-8 encoded C++ string + ); + + /// Creates a new String value from a UTF-16 encoded C++ string. + static String New(napi_env env, ///< Node-API environment + const std::u16string& value ///< UTF-16 encoded C++ string + ); + + /// Creates a new String value from a UTF-8 encoded C string. + static String New( + napi_env env, ///< Node-API environment + const char* value ///< UTF-8 encoded null-terminated C string + ); + + /// Creates a new String value from a UTF-16 encoded C string. + static String New( + napi_env env, ///< Node-API environment + const char16_t* value ///< UTF-16 encoded null-terminated C string + ); + + /// Creates a new String value from a UTF-8 encoded C string with specified + /// length. + static String New(napi_env env, ///< Node-API environment + const char* value, ///< UTF-8 encoded C string (not + ///< necessarily null-terminated) + size_t length ///< length of the string in bytes + ); + + /// Creates a new String value from a UTF-16 encoded C string with specified + /// length. + static String New( + napi_env env, ///< Node-API environment + const char16_t* value, ///< UTF-16 encoded C string (not necessarily + ///< null-terminated) + size_t length ///< Length of the string in 2-byte code units + ); + + /// Creates a new String based on the original object's type. + /// + /// `value` may be any of: + /// - const char* (encoded using UTF-8, null-terminated) + /// - const char16_t* (encoded using UTF-16-LE, null-terminated) + /// - std::string (encoded using UTF-8) + /// - std::u16string + template + static String From(napi_env env, const T& value); + + String(); ///< Creates a new _empty_ String instance. + String(napi_env env, napi_value value); ///< Wraps a Node-API value primitive. - }; - /// A JavaScript string value. - class String : public Name { - public: - /// Creates a new String value from a UTF-8 encoded C++ string. - static String New(napi_env env, ///< Node-API environment - const std::string& value ///< UTF-8 encoded C++ string - ); - - /// Creates a new String value from a UTF-16 encoded C++ string. - static String New(napi_env env, ///< Node-API environment - const std::u16string& value ///< UTF-16 encoded C++ string - ); - - /// Creates a new String value from a UTF-8 encoded C string. - static String New( - napi_env env, ///< Node-API environment - const char* value ///< UTF-8 encoded null-terminated C string - ); - - /// Creates a new String value from a UTF-16 encoded C string. - static String New( - napi_env env, ///< Node-API environment - const char16_t* value ///< UTF-16 encoded null-terminated C string - ); - - /// Creates a new String value from a UTF-8 encoded C string with specified - /// length. - static String New(napi_env env, ///< Node-API environment - const char* value, ///< UTF-8 encoded C string (not - ///< necessarily null-terminated) - size_t length ///< length of the string in bytes - ); - - /// Creates a new String value from a UTF-16 encoded C string with specified - /// length. - static String New( - napi_env env, ///< Node-API environment - const char16_t* value, ///< UTF-16 encoded C string (not necessarily - ///< null-terminated) - size_t length ///< Length of the string in 2-byte code units - ); - - /// Creates a new String based on the original object's type. - /// - /// `value` may be any of: - /// - const char* (encoded using UTF-8, null-terminated) - /// - const char16_t* (encoded using UTF-16-LE, null-terminated) - /// - std::string (encoded using UTF-8) - /// - std::u16string - template - static String From(napi_env env, const T& value); - - String(); ///< Creates a new _empty_ String instance. - String(napi_env env, - napi_value value); ///< Wraps a Node-API value primitive. + operator std::string() + const; ///< Converts a String value to a UTF-8 encoded C++ string. + operator std::u16string() + const; ///< Converts a String value to a UTF-16 encoded C++ string. + std::string Utf8Value() + const; ///< Converts a String value to a UTF-8 encoded C++ string. + std::u16string Utf16Value() + const; ///< Converts a String value to a UTF-16 encoded C++ string. +}; + +/// A JavaScript symbol value. +class Symbol : public Name { + public: + /// Creates a new Symbol value with an optional description. + static Symbol New( + napi_env env, ///< Node-API environment + const char* description = + nullptr ///< Optional UTF-8 encoded null-terminated C string + /// describing the symbol + ); + + /// Creates a new Symbol value with a description. + static Symbol New( + napi_env env, ///< Node-API environment + const std::string& + description ///< UTF-8 encoded C++ string describing the symbol + ); + + /// Creates a new Symbol value with a description. + static Symbol New(napi_env env, ///< Node-API environment + String description ///< String value describing the symbol + ); + + /// Creates a new Symbol value with a description. + static Symbol New( + napi_env env, ///< Node-API environment + napi_value description ///< String value describing the symbol + ); + + /// Get a public Symbol (e.g. Symbol.iterator). + static MaybeOrValue WellKnown(napi_env, const std::string& name); + + // Create a symbol in the global registry, UTF-8 Encoded cpp string + static MaybeOrValue For(napi_env env, const std::string& description); + + // Create a symbol in the global registry, C style string (null terminated) + static MaybeOrValue For(napi_env env, const char* description); + + // Create a symbol in the global registry, String value describing the symbol + static MaybeOrValue For(napi_env env, String description); + + // Create a symbol in the global registry, napi_value describing the symbol + static MaybeOrValue For(napi_env env, napi_value description); + + Symbol(); ///< Creates a new _empty_ Symbol instance. + Symbol(napi_env env, + napi_value value); ///< Wraps a Node-API value primitive. +}; - operator std::string() - const; ///< Converts a String value to a UTF-8 encoded C++ string. - operator std::u16string() - const; ///< Converts a String value to a UTF-16 encoded C++ string. - std::string Utf8Value() - const; ///< Converts a String value to a UTF-8 encoded C++ string. - std::u16string Utf16Value() - const; ///< Converts a String value to a UTF-16 encoded C++ string. - }; +/// A JavaScript object value. +class Object : public Value { + public: + /// Enables property and element assignments using indexing syntax. + /// + /// This is a convenient helper to get and set object properties. As + /// getting and setting object properties may throw with JavaScript + /// exceptions, it is notable that these operations may fail. + /// When NODE_ADDON_API_ENABLE_MAYBE is defined, the process will abort + /// on JavaScript exceptions. + /// + /// Example: + /// + /// Napi::Value propertyValue = object1['A']; + /// object2['A'] = propertyValue; + /// Napi::Value elementValue = array[0]; + /// array[1] = elementValue; + template + class PropertyLValue { + public: + /// Converts an L-value to a value. + operator Value() const; - /// A JavaScript symbol value. - class Symbol : public Name { - public: - /// Creates a new Symbol value with an optional description. - static Symbol New( - napi_env env, ///< Node-API environment - const char* description = - nullptr ///< Optional UTF-8 encoded null-terminated C string - /// describing the symbol - ); - - /// Creates a new Symbol value with a description. - static Symbol New( - napi_env env, ///< Node-API environment - const std::string& - description ///< UTF-8 encoded C++ string describing the symbol - ); - - /// Creates a new Symbol value with a description. - static Symbol New(napi_env env, ///< Node-API environment - String description ///< String value describing the symbol - ); - - /// Creates a new Symbol value with a description. - static Symbol New( - napi_env env, ///< Node-API environment - napi_value description ///< String value describing the symbol - ); - - /// Get a public Symbol (e.g. Symbol.iterator). - static MaybeOrValue WellKnown(napi_env, const std::string& name); - - // Create a symbol in the global registry, UTF-8 Encoded cpp string - static MaybeOrValue For(napi_env env, - const std::string& description); - - // Create a symbol in the global registry, C style string (null terminated) - static MaybeOrValue For(napi_env env, const char* description); - - // Create a symbol in the global registry, String value describing the symbol - static MaybeOrValue For(napi_env env, String description); - - // Create a symbol in the global registry, napi_value describing the symbol - static MaybeOrValue For(napi_env env, napi_value description); - - Symbol(); ///< Creates a new _empty_ Symbol instance. - Symbol(napi_env env, - napi_value value); ///< Wraps a Node-API value primitive. - }; + /// Assigns a value to the property. The type of value can be + /// anything supported by `Object::Set`. + template + PropertyLValue& operator=(ValueType value); - /// A JavaScript object value. - class Object : public Value { - public: - /// Enables property and element assignments using indexing syntax. - /// - /// This is a convenient helper to get and set object properties. As - /// getting and setting object properties may throw with JavaScript - /// exceptions, it is notable that these operations may fail. - /// When NODE_ADDON_API_ENABLE_MAYBE is defined, the process will abort - /// on JavaScript exceptions. - /// - /// Example: - /// - /// Napi::Value propertyValue = object1['A']; - /// object2['A'] = propertyValue; - /// Napi::Value elementValue = array[0]; - /// array[1] = elementValue; - template - class PropertyLValue { - public: - /// Converts an L-value to a value. - operator Value() const; - - /// Assigns a value to the property. The type of value can be - /// anything supported by `Object::Set`. - template - PropertyLValue& operator =(ValueType value); - - private: - PropertyLValue() = delete; - PropertyLValue(Object object, Key key); - napi_env _env; - napi_value _object; - Key _key; - - friend class Napi::Object; - }; - - /// Creates a new Object value. - static Object New(napi_env env ///< Node-API environment - ); - - Object(); ///< Creates a new _empty_ Object instance. - Object(napi_env env, - napi_value value); ///< Wraps a Node-API value primitive. + private: + PropertyLValue() = delete; + PropertyLValue(Object object, Key key); + napi_env _env; + napi_value _object; + Key _key; - /// Gets or sets a named property. - PropertyLValue operator[]( - const char* utf8name ///< UTF-8 encoded null-terminated property name - ); - - /// Gets or sets a named property. - PropertyLValue operator[]( - const std::string& utf8name ///< UTF-8 encoded property name - ); - - /// Gets or sets an indexed property or array element. - PropertyLValue operator[]( - uint32_t index /// Property / element index - ); - - /// Gets or sets an indexed property or array element. - PropertyLValue operator[](Value index /// Property / element index - ) const; - - /// Gets a named property. - MaybeOrValue operator[]( - const char* utf8name ///< UTF-8 encoded null-terminated property name - ) const; - - /// Gets a named property. - MaybeOrValue operator[]( - const std::string& utf8name ///< UTF-8 encoded property name - ) const; - - /// Gets an indexed property or array element. - MaybeOrValue operator[](uint32_t index ///< Property / element index - ) const; - - /// Checks whether a property is present. - MaybeOrValue Has(napi_value key ///< Property key primitive - ) const; - - /// Checks whether a property is present. - MaybeOrValue Has(Value key ///< Property key - ) const; - - /// Checks whether a named property is present. - MaybeOrValue Has( - const char* utf8name ///< UTF-8 encoded null-terminated property name - ) const; - - /// Checks whether a named property is present. - MaybeOrValue Has( - const std::string& utf8name ///< UTF-8 encoded property name - ) const; - - /// Checks whether a own property is present. - MaybeOrValue HasOwnProperty( - napi_value key ///< Property key primitive - ) const; - - /// Checks whether a own property is present. - MaybeOrValue HasOwnProperty(Value key ///< Property key - ) const; - - /// Checks whether a own property is present. - MaybeOrValue HasOwnProperty( - const char* utf8name ///< UTF-8 encoded null-terminated property name - ) const; - - /// Checks whether a own property is present. - MaybeOrValue HasOwnProperty( - const std::string& utf8name ///< UTF-8 encoded property name - ) const; - - /// Gets a property. - MaybeOrValue Get(napi_value key ///< Property key primitive - ) const; - - /// Gets a property. - MaybeOrValue Get(Value key ///< Property key - ) const; - - /// Gets a named property. - MaybeOrValue Get( - const char* utf8name ///< UTF-8 encoded null-terminated property name - ) const; - - /// Gets a named property. - MaybeOrValue Get( - const std::string& utf8name ///< UTF-8 encoded property name - ) const; - - /// Sets a property. - template - MaybeOrValue Set(napi_value key, ///< Property key primitive - const ValueType& value ///< Property value primitive - ) const; + friend class Napi::Object; + }; - /// Sets a property. - template - MaybeOrValue Set(Value key, ///< Property key - const ValueType& value ///< Property value - ) const; + /// Creates a new Object value. + static Object New(napi_env env ///< Node-API environment + ); - /// Sets a named property. - template - MaybeOrValue Set( - const char* utf8name, ///< UTF-8 encoded null-terminated property name - const ValueType& value) const; + Object(); ///< Creates a new _empty_ Object instance. + Object(napi_env env, + napi_value value); ///< Wraps a Node-API value primitive. - /// Sets a named property. - template - MaybeOrValue Set( - const std::string& utf8name, ///< UTF-8 encoded property name - const ValueType& value ///< Property value primitive - ) const; - - /// Delete property. - MaybeOrValue Delete(napi_value key ///< Property key primitive - ) const; - - /// Delete property. - MaybeOrValue Delete(Value key ///< Property key - ) const; - - /// Delete property. - MaybeOrValue Delete( - const char* utf8name ///< UTF-8 encoded null-terminated property name - ) const; - - /// Delete property. - MaybeOrValue Delete( - const std::string& utf8name ///< UTF-8 encoded property name - ) const; - - /// Checks whether an indexed property is present. - MaybeOrValue Has(uint32_t index ///< Property / element index - ) const; - - /// Gets an indexed property or array element. - MaybeOrValue Get(uint32_t index ///< Property / element index - ) const; - - /// Sets an indexed property or array element. - template - MaybeOrValue Set(uint32_t index, ///< Property / element index - const ValueType& value ///< Property value primitive - ) const; - - /// Deletes an indexed property or array element. - MaybeOrValue Delete(uint32_t index ///< Property / element index - ) const; - - /// This operation can fail in case of Proxy.[[OwnPropertyKeys]] and - /// Proxy.[[GetOwnProperty]] calling into JavaScript. See: - /// - - /// https://tc39.es/ecma262/#sec-proxy-object-internal-methods-and-internal-slots-ownpropertykeys - /// - - /// https://tc39.es/ecma262/#sec-proxy-object-internal-methods-and-internal-slots-getownproperty-p - MaybeOrValue GetPropertyNames() const; ///< Get all property names - - /// Defines a property on the object. - /// - /// This operation can fail in case of Proxy.[[DefineOwnProperty]] calling - /// into JavaScript. See - /// https://tc39.es/ecma262/#sec-proxy-object-internal-methods-and-internal-slots-defineownproperty-p-desc - MaybeOrValue DefineProperty( - const PropertyDescriptor& - property ///< Descriptor for the property to be defined - ) const; - - /// Defines properties on the object. - /// - /// This operation can fail in case of Proxy.[[DefineOwnProperty]] calling - /// into JavaScript. See - /// https://tc39.es/ecma262/#sec-proxy-object-internal-methods-and-internal-slots-defineownproperty-p-desc - MaybeOrValue DefineProperties( - const std::initializer_list& properties - ///< List of descriptors for the properties to be defined - ) const; - - /// Defines properties on the object. - /// - /// This operation can fail in case of Proxy.[[DefineOwnProperty]] calling - /// into JavaScript. See - /// https://tc39.es/ecma262/#sec-proxy-object-internal-methods-and-internal-slots-defineownproperty-p-desc - MaybeOrValue DefineProperties( - const std::vector& properties - ///< Vector of descriptors for the properties to be defined - ) const; - - /// Checks if an object is an instance created by a constructor function. - /// - /// This is equivalent to the JavaScript `instanceof` operator. - /// - /// This operation can fail in case of Proxy.[[GetPrototypeOf]] calling into - /// JavaScript. - /// See - /// https://tc39.es/ecma262/#sec-proxy-object-internal-methods-and-internal-slots-getprototypeof - MaybeOrValue InstanceOf( - const Function& constructor ///< Constructor function - ) const; - - template - inline void AddFinalizer(Finalizer finalizeCallback, T* data) const; - - template - inline void AddFinalizer(Finalizer finalizeCallback, - T* data, - Hint* finalizeHint) const; + /// Gets or sets a named property. + PropertyLValue operator[]( + const char* utf8name ///< UTF-8 encoded null-terminated property name + ); + + /// Gets or sets a named property. + PropertyLValue operator[]( + const std::string& utf8name ///< UTF-8 encoded property name + ); + + /// Gets or sets an indexed property or array element. + PropertyLValue operator[]( + uint32_t index /// Property / element index + ); + + /// Gets or sets an indexed property or array element. + PropertyLValue operator[](Value index /// Property / element index + ) const; + + /// Gets a named property. + MaybeOrValue operator[]( + const char* utf8name ///< UTF-8 encoded null-terminated property name + ) const; + + /// Gets a named property. + MaybeOrValue operator[]( + const std::string& utf8name ///< UTF-8 encoded property name + ) const; + + /// Gets an indexed property or array element. + MaybeOrValue operator[](uint32_t index ///< Property / element index + ) const; + + /// Checks whether a property is present. + MaybeOrValue Has(napi_value key ///< Property key primitive + ) const; + + /// Checks whether a property is present. + MaybeOrValue Has(Value key ///< Property key + ) const; + + /// Checks whether a named property is present. + MaybeOrValue Has( + const char* utf8name ///< UTF-8 encoded null-terminated property name + ) const; + + /// Checks whether a named property is present. + MaybeOrValue Has( + const std::string& utf8name ///< UTF-8 encoded property name + ) const; + + /// Checks whether a own property is present. + MaybeOrValue HasOwnProperty(napi_value key ///< Property key primitive + ) const; + + /// Checks whether a own property is present. + MaybeOrValue HasOwnProperty(Value key ///< Property key + ) const; + + /// Checks whether a own property is present. + MaybeOrValue HasOwnProperty( + const char* utf8name ///< UTF-8 encoded null-terminated property name + ) const; + + /// Checks whether a own property is present. + MaybeOrValue HasOwnProperty( + const std::string& utf8name ///< UTF-8 encoded property name + ) const; + + /// Gets a property. + MaybeOrValue Get(napi_value key ///< Property key primitive + ) const; + + /// Gets a property. + MaybeOrValue Get(Value key ///< Property key + ) const; + + /// Gets a named property. + MaybeOrValue Get( + const char* utf8name ///< UTF-8 encoded null-terminated property name + ) const; + + /// Gets a named property. + MaybeOrValue Get( + const std::string& utf8name ///< UTF-8 encoded property name + ) const; + + /// Sets a property. + template + MaybeOrValue Set(napi_value key, ///< Property key primitive + const ValueType& value ///< Property value primitive + ) const; + + /// Sets a property. + template + MaybeOrValue Set(Value key, ///< Property key + const ValueType& value ///< Property value + ) const; + + /// Sets a named property. + template + MaybeOrValue Set( + const char* utf8name, ///< UTF-8 encoded null-terminated property name + const ValueType& value) const; + + /// Sets a named property. + template + MaybeOrValue Set( + const std::string& utf8name, ///< UTF-8 encoded property name + const ValueType& value ///< Property value primitive + ) const; + + /// Delete property. + MaybeOrValue Delete(napi_value key ///< Property key primitive + ) const; + + /// Delete property. + MaybeOrValue Delete(Value key ///< Property key + ) const; + + /// Delete property. + MaybeOrValue Delete( + const char* utf8name ///< UTF-8 encoded null-terminated property name + ) const; + + /// Delete property. + MaybeOrValue Delete( + const std::string& utf8name ///< UTF-8 encoded property name + ) const; + + /// Checks whether an indexed property is present. + MaybeOrValue Has(uint32_t index ///< Property / element index + ) const; + + /// Gets an indexed property or array element. + MaybeOrValue Get(uint32_t index ///< Property / element index + ) const; + + /// Sets an indexed property or array element. + template + MaybeOrValue Set(uint32_t index, ///< Property / element index + const ValueType& value ///< Property value primitive + ) const; + + /// Deletes an indexed property or array element. + MaybeOrValue Delete(uint32_t index ///< Property / element index + ) const; + + /// This operation can fail in case of Proxy.[[OwnPropertyKeys]] and + /// Proxy.[[GetOwnProperty]] calling into JavaScript. See: + /// - + /// https://tc39.es/ecma262/#sec-proxy-object-internal-methods-and-internal-slots-ownpropertykeys + /// - + /// https://tc39.es/ecma262/#sec-proxy-object-internal-methods-and-internal-slots-getownproperty-p + MaybeOrValue GetPropertyNames() const; ///< Get all property names + + /// Defines a property on the object. + /// + /// This operation can fail in case of Proxy.[[DefineOwnProperty]] calling + /// into JavaScript. See + /// https://tc39.es/ecma262/#sec-proxy-object-internal-methods-and-internal-slots-defineownproperty-p-desc + MaybeOrValue DefineProperty( + const PropertyDescriptor& + property ///< Descriptor for the property to be defined + ) const; + + /// Defines properties on the object. + /// + /// This operation can fail in case of Proxy.[[DefineOwnProperty]] calling + /// into JavaScript. See + /// https://tc39.es/ecma262/#sec-proxy-object-internal-methods-and-internal-slots-defineownproperty-p-desc + MaybeOrValue DefineProperties( + const std::initializer_list& properties + ///< List of descriptors for the properties to be defined + ) const; + + /// Defines properties on the object. + /// + /// This operation can fail in case of Proxy.[[DefineOwnProperty]] calling + /// into JavaScript. See + /// https://tc39.es/ecma262/#sec-proxy-object-internal-methods-and-internal-slots-defineownproperty-p-desc + MaybeOrValue DefineProperties( + const std::vector& properties + ///< Vector of descriptors for the properties to be defined + ) const; + + /// Checks if an object is an instance created by a constructor function. + /// + /// This is equivalent to the JavaScript `instanceof` operator. + /// + /// This operation can fail in case of Proxy.[[GetPrototypeOf]] calling into + /// JavaScript. + /// See + /// https://tc39.es/ecma262/#sec-proxy-object-internal-methods-and-internal-slots-getprototypeof + MaybeOrValue InstanceOf( + const Function& constructor ///< Constructor function + ) const; + + template + inline void AddFinalizer(Finalizer finalizeCallback, T* data) const; + + template + inline void AddFinalizer(Finalizer finalizeCallback, + T* data, + Hint* finalizeHint) const; #ifdef NAPI_CPP_EXCEPTIONS - class const_iterator; + class const_iterator; - inline const_iterator begin() const; + inline const_iterator begin() const; - inline const_iterator end() const; + inline const_iterator end() const; - class iterator; + class iterator; - inline iterator begin(); + inline iterator begin(); - inline iterator end(); + inline iterator end(); #endif // NAPI_CPP_EXCEPTIONS #if NAPI_VERSION >= 8 - /// This operation can fail in case of Proxy.[[GetPrototypeOf]] calling into - /// JavaScript. - /// See - /// https://tc39.es/ecma262/#sec-proxy-object-internal-methods-and-internal-slots-getprototypeof - MaybeOrValue Freeze() const; - /// This operation can fail in case of Proxy.[[GetPrototypeOf]] calling into - /// JavaScript. - /// See - /// https://tc39.es/ecma262/#sec-proxy-object-internal-methods-and-internal-slots-getprototypeof - MaybeOrValue Seal() const; + /// This operation can fail in case of Proxy.[[GetPrototypeOf]] calling into + /// JavaScript. + /// See + /// https://tc39.es/ecma262/#sec-proxy-object-internal-methods-and-internal-slots-getprototypeof + MaybeOrValue Freeze() const; + /// This operation can fail in case of Proxy.[[GetPrototypeOf]] calling into + /// JavaScript. + /// See + /// https://tc39.es/ecma262/#sec-proxy-object-internal-methods-and-internal-slots-getprototypeof + MaybeOrValue Seal() const; #endif // NAPI_VERSION >= 8 - }; +}; - template - class External : public Value { - public: - static External New(napi_env env, T* data); - - // Finalizer must implement `void operator()(Env env, T* data)`. - template - static External New(napi_env env, - T* data, - Finalizer finalizeCallback); - // Finalizer must implement `void operator()(Env env, T* data, Hint* hint)`. - template - static External New(napi_env env, - T* data, - Finalizer finalizeCallback, - Hint* finalizeHint); - - External(); - External(napi_env env, napi_value value); - - T* Data() const; - }; +template +class External : public Value { + public: + static External New(napi_env env, T* data); - class Array : public Object { - public: - static Array New(napi_env env); - static Array New(napi_env env, size_t length); + // Finalizer must implement `void operator()(Env env, T* data)`. + template + static External New(napi_env env, T* data, Finalizer finalizeCallback); + // Finalizer must implement `void operator()(Env env, T* data, Hint* hint)`. + template + static External New(napi_env env, + T* data, + Finalizer finalizeCallback, + Hint* finalizeHint); - Array(); - Array(napi_env env, napi_value value); + External(); + External(napi_env env, napi_value value); - uint32_t Length() const; - }; + T* Data() const; +}; + +class Array : public Object { + public: + static Array New(napi_env env); + static Array New(napi_env env, size_t length); + + Array(); + Array(napi_env env, napi_value value); + + uint32_t Length() const; +}; #ifdef NAPI_CPP_EXCEPTIONS - class Object::const_iterator { - private: - enum class Type { BEGIN, END }; +class Object::const_iterator { + private: + enum class Type { BEGIN, END }; - inline const_iterator(const Object* object, const Type type); + inline const_iterator(const Object* object, const Type type); - public: - inline const_iterator& operator++(); + public: + inline const_iterator& operator++(); - inline bool operator==(const const_iterator& other) const; + inline bool operator==(const const_iterator& other) const; - inline bool operator!=(const const_iterator& other) const; + inline bool operator!=(const const_iterator& other) const; - inline const std::pair> operator*() - const; + inline const std::pair> operator*() + const; - private: - const Napi::Object* _object; - Array _keys; - uint32_t _index; + private: + const Napi::Object* _object; + Array _keys; + uint32_t _index; - friend class Object; - }; + friend class Object; +}; - class Object::iterator { - private: - enum class Type { BEGIN, END }; +class Object::iterator { + private: + enum class Type { BEGIN, END }; - inline iterator(Object* object, const Type type); + inline iterator(Object* object, const Type type); - public: - inline iterator& operator++(); + public: + inline iterator& operator++(); - inline bool operator==(const iterator& other) const; + inline bool operator==(const iterator& other) const; - inline bool operator!=(const iterator& other) const; + inline bool operator!=(const iterator& other) const; - inline std::pair> operator*(); + inline std::pair> operator*(); - private: - Napi::Object* _object; - Array _keys; - uint32_t _index; + private: + Napi::Object* _object; + Array _keys; + uint32_t _index; - friend class Object; - }; + friend class Object; +}; #endif // NAPI_CPP_EXCEPTIONS - /// A JavaScript array buffer value. - class ArrayBuffer : public Object { - public: - /// Creates a new ArrayBuffer instance over a new automatically-allocated buffer. - static ArrayBuffer New( - napi_env env, ///< Node-API environment - size_t byteLength ///< Length of the buffer to be allocated, in bytes - ); - - /// Creates a new ArrayBuffer instance, using an external buffer with - /// specified byte length. - static ArrayBuffer New( - napi_env env, ///< Node-API environment - void* externalData, ///< Pointer to the external buffer to be used by - ///< the array - size_t byteLength ///< Length of the external buffer to be used by the - ///< array, in bytes - ); - - /// Creates a new ArrayBuffer instance, using an external buffer with - /// specified byte length. - template - static ArrayBuffer New( - napi_env env, ///< Node-API environment - void* externalData, ///< Pointer to the external buffer to be used by - ///< the array - size_t byteLength, ///< Length of the external buffer to be used by the - ///< array, - /// in bytes - Finalizer finalizeCallback ///< Function to be called when the array +/// A JavaScript array buffer value. +class ArrayBuffer : public Object { + public: + /// Creates a new ArrayBuffer instance over a new automatically-allocated + /// buffer. + static ArrayBuffer New( + napi_env env, ///< Node-API environment + size_t byteLength ///< Length of the buffer to be allocated, in bytes + ); + + /// Creates a new ArrayBuffer instance, using an external buffer with + /// specified byte length. + static ArrayBuffer New( + napi_env env, ///< Node-API environment + void* externalData, ///< Pointer to the external buffer to be used by + ///< the array + size_t byteLength ///< Length of the external buffer to be used by the + ///< array, in bytes + ); + + /// Creates a new ArrayBuffer instance, using an external buffer with + /// specified byte length. + template + static ArrayBuffer New( + napi_env env, ///< Node-API environment + void* externalData, ///< Pointer to the external buffer to be used by + ///< the array + size_t byteLength, ///< Length of the external buffer to be used by the + ///< array, + /// in bytes + Finalizer finalizeCallback ///< Function to be called when the array + ///< buffer is destroyed; + /// must implement `void operator()(Env env, + /// void* externalData)` + ); + + /// Creates a new ArrayBuffer instance, using an external buffer with + /// specified byte length. + template + static ArrayBuffer New( + napi_env env, ///< Node-API environment + void* externalData, ///< Pointer to the external buffer to be used by + ///< the array + size_t byteLength, ///< Length of the external buffer to be used by the + ///< array, + /// in bytes + Finalizer finalizeCallback, ///< Function to be called when the array ///< buffer is destroyed; - /// must implement `void operator()(Env env, - /// void* externalData)` - ); - - /// Creates a new ArrayBuffer instance, using an external buffer with - /// specified byte length. - template - static ArrayBuffer New( - napi_env env, ///< Node-API environment - void* externalData, ///< Pointer to the external buffer to be used by - ///< the array - size_t byteLength, ///< Length of the external buffer to be used by the - ///< array, - /// in bytes - Finalizer finalizeCallback, ///< Function to be called when the array - ///< buffer is destroyed; - /// must implement `void operator()(Env - /// env, void* externalData, Hint* hint)` - Hint* finalizeHint ///< Hint (second parameter) to be passed to the - ///< finalize callback - ); - - ArrayBuffer(); ///< Creates a new _empty_ ArrayBuffer instance. - ArrayBuffer(napi_env env, - napi_value value); ///< Wraps a Node-API value primitive. + /// must implement `void operator()(Env + /// env, void* externalData, Hint* hint)` + Hint* finalizeHint ///< Hint (second parameter) to be passed to the + ///< finalize callback + ); + + ArrayBuffer(); ///< Creates a new _empty_ ArrayBuffer instance. + ArrayBuffer(napi_env env, + napi_value value); ///< Wraps a Node-API value primitive. - void* Data(); ///< Gets a pointer to the data buffer. - size_t ByteLength(); ///< Gets the length of the array buffer in bytes. + void* Data(); ///< Gets a pointer to the data buffer. + size_t ByteLength(); ///< Gets the length of the array buffer in bytes. #if NAPI_VERSION >= 7 - bool IsDetached() const; - void Detach(); + bool IsDetached() const; + void Detach(); #endif // NAPI_VERSION >= 7 - }; - - /// A JavaScript typed-array value with unknown array type. - /// - /// For type-specific operations, cast to a `TypedArrayOf` instance using the `As()` - /// method: - /// - /// Napi::TypedArray array = ... - /// if (t.TypedArrayType() == napi_int32_array) { - /// Napi::Int32Array int32Array = t.As(); - /// } - class TypedArray : public Object { - public: - TypedArray(); ///< Creates a new _empty_ TypedArray instance. - TypedArray(napi_env env, - napi_value value); ///< Wraps a Node-API value primitive. +}; - napi_typedarray_type TypedArrayType() const; ///< Gets the type of this typed-array. - Napi::ArrayBuffer ArrayBuffer() const; ///< Gets the backing array buffer. +/// A JavaScript typed-array value with unknown array type. +/// +/// For type-specific operations, cast to a `TypedArrayOf` instance using the +/// `As()` method: +/// +/// Napi::TypedArray array = ... +/// if (t.TypedArrayType() == napi_int32_array) { +/// Napi::Int32Array int32Array = t.As(); +/// } +class TypedArray : public Object { + public: + TypedArray(); ///< Creates a new _empty_ TypedArray instance. + TypedArray(napi_env env, + napi_value value); ///< Wraps a Node-API value primitive. - uint8_t ElementSize() const; ///< Gets the size in bytes of one element in the array. - size_t ElementLength() const; ///< Gets the number of elements in the array. - size_t ByteOffset() const; ///< Gets the offset into the buffer where the array starts. - size_t ByteLength() const; ///< Gets the length of the array in bytes. + napi_typedarray_type TypedArrayType() + const; ///< Gets the type of this typed-array. + Napi::ArrayBuffer ArrayBuffer() const; ///< Gets the backing array buffer. - protected: - /// !cond INTERNAL - napi_typedarray_type _type; - size_t _length; + uint8_t ElementSize() + const; ///< Gets the size in bytes of one element in the array. + size_t ElementLength() const; ///< Gets the number of elements in the array. + size_t ByteOffset() + const; ///< Gets the offset into the buffer where the array starts. + size_t ByteLength() const; ///< Gets the length of the array in bytes. - TypedArray(napi_env env, napi_value value, napi_typedarray_type type, size_t length); + protected: + /// !cond INTERNAL + napi_typedarray_type _type; + size_t _length; - static const napi_typedarray_type unknown_array_type = static_cast(-1); + TypedArray(napi_env env, + napi_value value, + napi_typedarray_type type, + size_t length); - template - static + template + static #if defined(NAPI_HAS_CONSTEXPR) - constexpr + constexpr #endif - napi_typedarray_type TypedArrayTypeForPrimitiveType() { - return std::is_same::value ? napi_int8_array - : std::is_same::value ? napi_uint8_array - : std::is_same::value ? napi_int16_array - : std::is_same::value ? napi_uint16_array - : std::is_same::value ? napi_int32_array - : std::is_same::value ? napi_uint32_array - : std::is_same::value ? napi_float32_array - : std::is_same::value ? napi_float64_array + napi_typedarray_type + TypedArrayTypeForPrimitiveType() { + return std::is_same::value ? napi_int8_array + : std::is_same::value ? napi_uint8_array + : std::is_same::value ? napi_int16_array + : std::is_same::value ? napi_uint16_array + : std::is_same::value ? napi_int32_array + : std::is_same::value ? napi_uint32_array + : std::is_same::value ? napi_float32_array + : std::is_same::value ? napi_float64_array #if NAPI_VERSION > 5 - : std::is_same::value ? napi_bigint64_array - : std::is_same::value ? napi_biguint64_array + : std::is_same::value ? napi_bigint64_array + : std::is_same::value ? napi_biguint64_array #endif // NAPI_VERSION > 5 - : unknown_array_type; - } - /// !endcond - }; + : napi_int8_array; + } + /// !endcond +}; - /// A JavaScript typed-array value with known array type. +/// A JavaScript typed-array value with known array type. +/// +/// Note while it is possible to create and access Uint8 "clamped" arrays using +/// this class, the _clamping_ behavior is only applied in JavaScript. +template +class TypedArrayOf : public TypedArray { + public: + /// Creates a new TypedArray instance over a new automatically-allocated array + /// buffer. /// - /// Note while it is possible to create and access Uint8 "clamped" arrays using this class, - /// the _clamping_ behavior is only applied in JavaScript. - template - class TypedArrayOf : public TypedArray { - public: - /// Creates a new TypedArray instance over a new automatically-allocated array buffer. - /// - /// The array type parameter can normally be omitted (because it is inferred from the template - /// parameter T), except when creating a "clamped" array: - /// - /// Uint8Array::New(env, length, napi_uint8_clamped_array) - static TypedArrayOf New( - napi_env env, ///< Node-API environment - size_t elementLength, ///< Length of the created array, as a number of - ///< elements + /// The array type parameter can normally be omitted (because it is inferred + /// from the template parameter T), except when creating a "clamped" array: + /// + /// Uint8Array::New(env, length, napi_uint8_clamped_array) + static TypedArrayOf New( + napi_env env, ///< Node-API environment + size_t elementLength, ///< Length of the created array, as a number of + ///< elements #if defined(NAPI_HAS_CONSTEXPR) - napi_typedarray_type type = - TypedArray::TypedArrayTypeForPrimitiveType() + napi_typedarray_type type = + TypedArray::TypedArrayTypeForPrimitiveType() #else - napi_typedarray_type type + napi_typedarray_type type #endif - ///< Type of array, if different from the default array type for the - ///< template parameter T. - ); - - /// Creates a new TypedArray instance over a provided array buffer. - /// - /// The array type parameter can normally be omitted (because it is inferred from the template - /// parameter T), except when creating a "clamped" array: - /// - /// Uint8Array::New(env, length, buffer, 0, napi_uint8_clamped_array) - static TypedArrayOf New( - napi_env env, ///< Node-API environment - size_t elementLength, ///< Length of the created array, as a number of - ///< elements - Napi::ArrayBuffer arrayBuffer, ///< Backing array buffer instance to use - size_t bufferOffset, ///< Offset into the array buffer where the - ///< typed-array starts + ///< Type of array, if different from the default array type for the + ///< template parameter T. + ); + + /// Creates a new TypedArray instance over a provided array buffer. + /// + /// The array type parameter can normally be omitted (because it is inferred + /// from the template parameter T), except when creating a "clamped" array: + /// + /// Uint8Array::New(env, length, buffer, 0, napi_uint8_clamped_array) + static TypedArrayOf New( + napi_env env, ///< Node-API environment + size_t elementLength, ///< Length of the created array, as a number of + ///< elements + Napi::ArrayBuffer arrayBuffer, ///< Backing array buffer instance to use + size_t bufferOffset, ///< Offset into the array buffer where the + ///< typed-array starts #if defined(NAPI_HAS_CONSTEXPR) - napi_typedarray_type type = - TypedArray::TypedArrayTypeForPrimitiveType() + napi_typedarray_type type = + TypedArray::TypedArrayTypeForPrimitiveType() #else - napi_typedarray_type type + napi_typedarray_type type #endif - ///< Type of array, if different from the default array type for the - ///< template parameter T. - ); - - TypedArrayOf(); ///< Creates a new _empty_ TypedArrayOf instance. - TypedArrayOf(napi_env env, - napi_value value); ///< Wraps a Node-API value primitive. - - T& operator [](size_t index); ///< Gets or sets an element in the array. - const T& operator [](size_t index) const; ///< Gets an element in the array. - - /// Gets a pointer to the array's backing buffer. - /// - /// This is not necessarily the same as the `ArrayBuffer::Data()` pointer, because the - /// typed-array may have a non-zero `ByteOffset()` into the `ArrayBuffer`. - T* Data(); - - /// Gets a pointer to the array's backing buffer. - /// - /// This is not necessarily the same as the `ArrayBuffer::Data()` pointer, because the - /// typed-array may have a non-zero `ByteOffset()` into the `ArrayBuffer`. - const T* Data() const; - - private: - T* _data; - - TypedArrayOf(napi_env env, - napi_value value, - napi_typedarray_type type, - size_t length, - T* data); - }; - - /// The DataView provides a low-level interface for reading/writing multiple - /// number types in an ArrayBuffer irrespective of the platform's endianness. - class DataView : public Object { - public: - static DataView New(napi_env env, - Napi::ArrayBuffer arrayBuffer); - static DataView New(napi_env env, - Napi::ArrayBuffer arrayBuffer, - size_t byteOffset); - static DataView New(napi_env env, - Napi::ArrayBuffer arrayBuffer, - size_t byteOffset, - size_t byteLength); - - DataView(); ///< Creates a new _empty_ DataView instance. - DataView(napi_env env, - napi_value value); ///< Wraps a Node-API value primitive. + ///< Type of array, if different from the default array type for the + ///< template parameter T. + ); - Napi::ArrayBuffer ArrayBuffer() const; ///< Gets the backing array buffer. - size_t ByteOffset() const; ///< Gets the offset into the buffer where the array starts. - size_t ByteLength() const; ///< Gets the length of the array in bytes. - - void* Data() const; - - float GetFloat32(size_t byteOffset) const; - double GetFloat64(size_t byteOffset) const; - int8_t GetInt8(size_t byteOffset) const; - int16_t GetInt16(size_t byteOffset) const; - int32_t GetInt32(size_t byteOffset) const; - uint8_t GetUint8(size_t byteOffset) const; - uint16_t GetUint16(size_t byteOffset) const; - uint32_t GetUint32(size_t byteOffset) const; - - void SetFloat32(size_t byteOffset, float value) const; - void SetFloat64(size_t byteOffset, double value) const; - void SetInt8(size_t byteOffset, int8_t value) const; - void SetInt16(size_t byteOffset, int16_t value) const; - void SetInt32(size_t byteOffset, int32_t value) const; - void SetUint8(size_t byteOffset, uint8_t value) const; - void SetUint16(size_t byteOffset, uint16_t value) const; - void SetUint32(size_t byteOffset, uint32_t value) const; - - private: - template - T ReadData(size_t byteOffset) const; - - template - void WriteData(size_t byteOffset, T value) const; - - void* _data; - size_t _length; - }; - - class Function : public Object { - public: - using VoidCallback = void (*)(const CallbackInfo& info); - using Callback = Value (*)(const CallbackInfo& info); - - template - static Function New(napi_env env, - const char* utf8name = nullptr, - void* data = nullptr); - - template - static Function New(napi_env env, - const char* utf8name = nullptr, - void* data = nullptr); - - template - static Function New(napi_env env, - const std::string& utf8name, - void* data = nullptr); - - template - static Function New(napi_env env, - const std::string& utf8name, - void* data = nullptr); - - /// Callable must implement operator() accepting a const CallbackInfo& - /// and return either void or Value. - template - static Function New(napi_env env, - Callable cb, - const char* utf8name = nullptr, - void* data = nullptr); - /// Callable must implement operator() accepting a const CallbackInfo& - /// and return either void or Value. - template - static Function New(napi_env env, - Callable cb, - const std::string& utf8name, - void* data = nullptr); - - Function(); - Function(napi_env env, napi_value value); - - MaybeOrValue operator()( - const std::initializer_list& args) const; - - MaybeOrValue Call( - const std::initializer_list& args) const; - MaybeOrValue Call(const std::vector& args) const; - MaybeOrValue Call(const std::vector& args) const; - MaybeOrValue Call(size_t argc, const napi_value* args) const; - MaybeOrValue Call( - napi_value recv, const std::initializer_list& args) const; - MaybeOrValue Call(napi_value recv, - const std::vector& args) const; - MaybeOrValue Call(napi_value recv, - const std::vector& args) const; - MaybeOrValue Call(napi_value recv, - size_t argc, - const napi_value* args) const; - - MaybeOrValue MakeCallback( - napi_value recv, - const std::initializer_list& args, - napi_async_context context = nullptr) const; - MaybeOrValue MakeCallback(napi_value recv, - const std::vector& args, - napi_async_context context = nullptr) const; - MaybeOrValue MakeCallback(napi_value recv, - size_t argc, - const napi_value* args, - napi_async_context context = nullptr) const; - - MaybeOrValue New( - const std::initializer_list& args) const; - MaybeOrValue New(const std::vector& args) const; - MaybeOrValue New(size_t argc, const napi_value* args) const; - }; - - class Promise : public Object { - public: - class Deferred { - public: - static Deferred New(napi_env env); - Deferred(napi_env env); - - Napi::Promise Promise() const; - Napi::Env Env() const; + TypedArrayOf(); ///< Creates a new _empty_ TypedArrayOf instance. + TypedArrayOf(napi_env env, + napi_value value); ///< Wraps a Node-API value primitive. - void Resolve(napi_value value) const; - void Reject(napi_value value) const; + T& operator[](size_t index); ///< Gets or sets an element in the array. + const T& operator[](size_t index) const; ///< Gets an element in the array. - private: - napi_env _env; - napi_deferred _deferred; - napi_value _promise; - }; + /// Gets a pointer to the array's backing buffer. + /// + /// This is not necessarily the same as the `ArrayBuffer::Data()` pointer, + /// because the typed-array may have a non-zero `ByteOffset()` into the + /// `ArrayBuffer`. + T* Data(); - Promise(napi_env env, napi_value value); - }; + /// Gets a pointer to the array's backing buffer. + /// + /// This is not necessarily the same as the `ArrayBuffer::Data()` pointer, + /// because the typed-array may have a non-zero `ByteOffset()` into the + /// `ArrayBuffer`. + const T* Data() const; + + private: + T* _data; + + TypedArrayOf(napi_env env, + napi_value value, + napi_typedarray_type type, + size_t length, + T* data); +}; + +/// The DataView provides a low-level interface for reading/writing multiple +/// number types in an ArrayBuffer irrespective of the platform's endianness. +class DataView : public Object { + public: + static DataView New(napi_env env, Napi::ArrayBuffer arrayBuffer); + static DataView New(napi_env env, + Napi::ArrayBuffer arrayBuffer, + size_t byteOffset); + static DataView New(napi_env env, + Napi::ArrayBuffer arrayBuffer, + size_t byteOffset, + size_t byteLength); + + DataView(); ///< Creates a new _empty_ DataView instance. + DataView(napi_env env, + napi_value value); ///< Wraps a Node-API value primitive. + Napi::ArrayBuffer ArrayBuffer() const; ///< Gets the backing array buffer. + size_t ByteOffset() + const; ///< Gets the offset into the buffer where the array starts. + size_t ByteLength() const; ///< Gets the length of the array in bytes. + + void* Data() const; + + float GetFloat32(size_t byteOffset) const; + double GetFloat64(size_t byteOffset) const; + int8_t GetInt8(size_t byteOffset) const; + int16_t GetInt16(size_t byteOffset) const; + int32_t GetInt32(size_t byteOffset) const; + uint8_t GetUint8(size_t byteOffset) const; + uint16_t GetUint16(size_t byteOffset) const; + uint32_t GetUint32(size_t byteOffset) const; + + void SetFloat32(size_t byteOffset, float value) const; + void SetFloat64(size_t byteOffset, double value) const; + void SetInt8(size_t byteOffset, int8_t value) const; + void SetInt16(size_t byteOffset, int16_t value) const; + void SetInt32(size_t byteOffset, int32_t value) const; + void SetUint8(size_t byteOffset, uint8_t value) const; + void SetUint16(size_t byteOffset, uint16_t value) const; + void SetUint32(size_t byteOffset, uint32_t value) const; + + private: template - class Buffer : public Uint8Array { - public: - static Buffer New(napi_env env, size_t length); - static Buffer New(napi_env env, T* data, size_t length); - - // Finalizer must implement `void operator()(Env env, T* data)`. - template - static Buffer New(napi_env env, T* data, - size_t length, - Finalizer finalizeCallback); - // Finalizer must implement `void operator()(Env env, T* data, Hint* hint)`. - template - static Buffer New(napi_env env, T* data, - size_t length, - Finalizer finalizeCallback, - Hint* finalizeHint); - - static Buffer Copy(napi_env env, const T* data, size_t length); - - Buffer(); - Buffer(napi_env env, napi_value value); - size_t Length() const; - T* Data() const; - - private: - mutable size_t _length; - mutable T* _data; - - Buffer(napi_env env, napi_value value, size_t length, T* data); - void EnsureInfo() const; - }; + T ReadData(size_t byteOffset) const; - /// Holds a counted reference to a value; initially a weak reference unless otherwise specified, - /// may be changed to/from a strong reference by adjusting the refcount. - /// - /// The referenced value is not immediately destroyed when the reference count is zero; it is - /// merely then eligible for garbage-collection if there are no other references to the value. template - class Reference { - public: - static Reference New(const T& value, uint32_t initialRefcount = 0); - - Reference(); - Reference(napi_env env, napi_ref ref); - ~Reference(); + void WriteData(size_t byteOffset, T value) const; + + void* _data; + size_t _length; +}; + +class Function : public Object { + public: + using VoidCallback = void (*)(const CallbackInfo& info); + using Callback = Value (*)(const CallbackInfo& info); + + template + static Function New(napi_env env, + const char* utf8name = nullptr, + void* data = nullptr); + + template + static Function New(napi_env env, + const char* utf8name = nullptr, + void* data = nullptr); + + template + static Function New(napi_env env, + const std::string& utf8name, + void* data = nullptr); + + template + static Function New(napi_env env, + const std::string& utf8name, + void* data = nullptr); + + /// Callable must implement operator() accepting a const CallbackInfo& + /// and return either void or Value. + template + static Function New(napi_env env, + Callable cb, + const char* utf8name = nullptr, + void* data = nullptr); + /// Callable must implement operator() accepting a const CallbackInfo& + /// and return either void or Value. + template + static Function New(napi_env env, + Callable cb, + const std::string& utf8name, + void* data = nullptr); + + Function(); + Function(napi_env env, napi_value value); + + MaybeOrValue operator()( + const std::initializer_list& args) const; + + MaybeOrValue Call(const std::initializer_list& args) const; + MaybeOrValue Call(const std::vector& args) const; + MaybeOrValue Call(const std::vector& args) const; + MaybeOrValue Call(size_t argc, const napi_value* args) const; + MaybeOrValue Call(napi_value recv, + const std::initializer_list& args) const; + MaybeOrValue Call(napi_value recv, + const std::vector& args) const; + MaybeOrValue Call(napi_value recv, + const std::vector& args) const; + MaybeOrValue Call(napi_value recv, + size_t argc, + const napi_value* args) const; + + MaybeOrValue MakeCallback( + napi_value recv, + const std::initializer_list& args, + napi_async_context context = nullptr) const; + MaybeOrValue MakeCallback(napi_value recv, + const std::vector& args, + napi_async_context context = nullptr) const; + MaybeOrValue MakeCallback(napi_value recv, + size_t argc, + const napi_value* args, + napi_async_context context = nullptr) const; - // A reference can be moved but cannot be copied. - Reference(Reference&& other); - Reference& operator =(Reference&& other); - NAPI_DISALLOW_ASSIGN(Reference) + MaybeOrValue New(const std::initializer_list& args) const; + MaybeOrValue New(const std::vector& args) const; + MaybeOrValue New(size_t argc, const napi_value* args) const; +}; - operator napi_ref() const; - bool operator ==(const Reference &other) const; - bool operator !=(const Reference &other) const; +class Promise : public Object { + public: + class Deferred { + public: + static Deferred New(napi_env env); + Deferred(napi_env env); + Napi::Promise Promise() const; Napi::Env Env() const; - bool IsEmpty() const; - - // Note when getting the value of a Reference it is usually correct to do so - // within a HandleScope so that the value handle gets cleaned up efficiently. - T Value() const; - - uint32_t Ref() const; - uint32_t Unref() const; - void Reset(); - void Reset(const T& value, uint32_t refcount = 0); - - // Call this on a reference that is declared as static data, to prevent its - // destructor from running at program shutdown time, which would attempt to - // reset the reference when the environment is no longer valid. Avoid using - // this if at all possible. If you do need to use static data, MAKE SURE to - // warn your users that your addon is NOT threadsafe. - void SuppressDestruct(); - protected: - Reference(const Reference&); + void Resolve(napi_value value) const; + void Reject(napi_value value) const; - /// !cond INTERNAL + private: napi_env _env; - napi_ref _ref; - /// !endcond - - private: - bool _suppressDestruct; - }; - - class ObjectReference: public Reference { - public: - ObjectReference(); - ObjectReference(napi_env env, napi_ref ref); - - // A reference can be moved but cannot be copied. - ObjectReference(Reference&& other); - ObjectReference& operator =(Reference&& other); - ObjectReference(ObjectReference&& other); - ObjectReference& operator =(ObjectReference&& other); - NAPI_DISALLOW_ASSIGN(ObjectReference) - - MaybeOrValue Get(const char* utf8name) const; - MaybeOrValue Get(const std::string& utf8name) const; - MaybeOrValue Set(const char* utf8name, napi_value value) const; - MaybeOrValue Set(const char* utf8name, Napi::Value value) const; - MaybeOrValue Set(const char* utf8name, const char* utf8value) const; - MaybeOrValue Set(const char* utf8name, bool boolValue) const; - MaybeOrValue Set(const char* utf8name, double numberValue) const; - MaybeOrValue Set(const std::string& utf8name, napi_value value) const; - MaybeOrValue Set(const std::string& utf8name, - Napi::Value value) const; - MaybeOrValue Set(const std::string& utf8name, - std::string& utf8value) const; - MaybeOrValue Set(const std::string& utf8name, bool boolValue) const; - MaybeOrValue Set(const std::string& utf8name, - double numberValue) const; - - MaybeOrValue Get(uint32_t index) const; - MaybeOrValue Set(uint32_t index, const napi_value value) const; - MaybeOrValue Set(uint32_t index, const Napi::Value value) const; - MaybeOrValue Set(uint32_t index, const char* utf8value) const; - MaybeOrValue Set(uint32_t index, const std::string& utf8value) const; - MaybeOrValue Set(uint32_t index, bool boolValue) const; - MaybeOrValue Set(uint32_t index, double numberValue) const; - - protected: - ObjectReference(const ObjectReference&); + napi_deferred _deferred; + napi_value _promise; }; - class FunctionReference: public Reference { - public: - FunctionReference(); - FunctionReference(napi_env env, napi_ref ref); - - // A reference can be moved but cannot be copied. - FunctionReference(Reference&& other); - FunctionReference& operator =(Reference&& other); - FunctionReference(FunctionReference&& other); - FunctionReference& operator =(FunctionReference&& other); - NAPI_DISALLOW_ASSIGN_COPY(FunctionReference) - - MaybeOrValue operator()( - const std::initializer_list& args) const; - - MaybeOrValue Call( - const std::initializer_list& args) const; - MaybeOrValue Call(const std::vector& args) const; - MaybeOrValue Call( - napi_value recv, const std::initializer_list& args) const; - MaybeOrValue Call(napi_value recv, - const std::vector& args) const; - MaybeOrValue Call(napi_value recv, - size_t argc, - const napi_value* args) const; - - MaybeOrValue MakeCallback( - napi_value recv, - const std::initializer_list& args, - napi_async_context context = nullptr) const; - MaybeOrValue MakeCallback( - napi_value recv, - const std::vector& args, - napi_async_context context = nullptr) const; - MaybeOrValue MakeCallback( - napi_value recv, - size_t argc, - const napi_value* args, - napi_async_context context = nullptr) const; - - MaybeOrValue New( - const std::initializer_list& args) const; - MaybeOrValue New(const std::vector& args) const; - }; - - // Shortcuts to creating a new reference with inferred type and refcount = 0. - template Reference Weak(T value); - ObjectReference Weak(Object value); - FunctionReference Weak(Function value); - - // Shortcuts to creating a new reference with inferred type and refcount = 1. - template Reference Persistent(T value); - ObjectReference Persistent(Object value); - FunctionReference Persistent(Function value); - - /// A persistent reference to a JavaScript error object. Use of this class - /// depends somewhat on whether C++ exceptions are enabled at compile time. - /// - /// ### Handling Errors With C++ Exceptions - /// - /// If C++ exceptions are enabled, then the `Error` class extends - /// `std::exception` and enables integrated error-handling for C++ exceptions - /// and JavaScript exceptions. - /// - /// If a Node-API call fails without executing any JavaScript code (for - /// example due to an invalid argument), then the Node-API wrapper - /// automatically converts and throws the error as a C++ exception of type - /// `Napi::Error`. Or if a JavaScript function called by C++ code via Node-API - /// throws a JavaScript exception, then the Node-API wrapper automatically - /// converts and throws it as a C++ exception of type `Napi::Error`. - /// - /// If a C++ exception of type `Napi::Error` escapes from a Node-API C++ - /// callback, then the Node-API wrapper automatically converts and throws it - /// as a JavaScript exception. Therefore, catching a C++ exception of type - /// `Napi::Error` prevents a JavaScript exception from being thrown. - /// - /// #### Example 1A - Throwing a C++ exception: - /// - /// Napi::Env env = ... - /// throw Napi::Error::New(env, "Example exception"); - /// - /// Following C++ statements will not be executed. The exception will bubble - /// up as a C++ exception of type `Napi::Error`, until it is either caught - /// while still in C++, or else automatically propataged as a JavaScript - /// exception when the callback returns to JavaScript. - /// - /// #### Example 2A - Propagating a Node-API C++ exception: - /// - /// Napi::Function jsFunctionThatThrows = someObj.As(); - /// Napi::Value result = jsFunctionThatThrows({ arg1, arg2 }); - /// - /// Following C++ statements will not be executed. The exception will bubble - /// up as a C++ exception of type `Napi::Error`, until it is either caught - /// while still in C++, or else automatically propagated as a JavaScript - /// exception when the callback returns to JavaScript. - /// - /// #### Example 3A - Handling a Node-API C++ exception: - /// - /// Napi::Function jsFunctionThatThrows = someObj.As(); - /// Napi::Value result; - /// try { - /// result = jsFunctionThatThrows({ arg1, arg2 }); - /// } catch (const Napi::Error& e) { - /// cerr << "Caught JavaScript exception: " + e.what(); - /// } - /// - /// Since the exception was caught here, it will not be propagated as a - /// JavaScript exception. - /// - /// ### Handling Errors Without C++ Exceptions - /// - /// If C++ exceptions are disabled (by defining `NAPI_DISABLE_CPP_EXCEPTIONS`) - /// then this class does not extend `std::exception`, and APIs in the `Napi` - /// namespace do not throw C++ exceptions when they fail. Instead, they raise - /// _pending_ JavaScript exceptions and return _empty_ `Value`s. Calling code - /// should check `Value::IsEmpty()` before attempting to use a returned value, - /// and may use methods on the `Env` class to check for, get, and clear a - /// pending JavaScript exception. If the pending exception is not cleared, it - /// will be thrown when the native callback returns to JavaScript. - /// - /// #### Example 1B - Throwing a JS exception - /// - /// Napi::Env env = ... - /// Napi::Error::New(env, "Example - /// exception").ThrowAsJavaScriptException(); return; - /// - /// After throwing a JS exception, the code should generally return - /// immediately from the native callback, after performing any necessary - /// cleanup. - /// - /// #### Example 2B - Propagating a Node-API JS exception: - /// - /// Napi::Function jsFunctionThatThrows = someObj.As(); - /// Napi::Value result = jsFunctionThatThrows({ arg1, arg2 }); - /// if (result.IsEmpty()) return; - /// - /// An empty value result from a Node-API call indicates an error occurred, - /// and a JavaScript exception is pending. To let the exception propagate, the - /// code should generally return immediately from the native callback, after - /// performing any necessary cleanup. - /// - /// #### Example 3B - Handling a Node-API JS exception: - /// - /// Napi::Function jsFunctionThatThrows = someObj.As(); - /// Napi::Value result = jsFunctionThatThrows({ arg1, arg2 }); - /// if (result.IsEmpty()) { - /// Napi::Error e = env.GetAndClearPendingException(); - /// cerr << "Caught JavaScript exception: " + e.Message(); - /// } - /// - /// Since the exception was cleared here, it will not be propagated as a - /// JavaScript exception after the native callback returns. - class Error : public ObjectReference + Promise(napi_env env, napi_value value); +}; + +template +class Buffer : public Uint8Array { + public: + static Buffer New(napi_env env, size_t length); + static Buffer New(napi_env env, T* data, size_t length); + + // Finalizer must implement `void operator()(Env env, T* data)`. + template + static Buffer New(napi_env env, + T* data, + size_t length, + Finalizer finalizeCallback); + // Finalizer must implement `void operator()(Env env, T* data, Hint* hint)`. + template + static Buffer New(napi_env env, + T* data, + size_t length, + Finalizer finalizeCallback, + Hint* finalizeHint); + + static Buffer Copy(napi_env env, const T* data, size_t length); + + Buffer(); + Buffer(napi_env env, napi_value value); + size_t Length() const; + T* Data() const; + + private: + mutable size_t _length; + mutable T* _data; + + Buffer(napi_env env, napi_value value, size_t length, T* data); + void EnsureInfo() const; +}; + +/// Holds a counted reference to a value; initially a weak reference unless +/// otherwise specified, may be changed to/from a strong reference by adjusting +/// the refcount. +/// +/// The referenced value is not immediately destroyed when the reference count +/// is zero; it is merely then eligible for garbage-collection if there are no +/// other references to the value. +template +class Reference { + public: + static Reference New(const T& value, uint32_t initialRefcount = 0); + + Reference(); + Reference(napi_env env, napi_ref ref); + ~Reference(); + + // A reference can be moved but cannot be copied. + Reference(Reference&& other); + Reference& operator=(Reference&& other); + NAPI_DISALLOW_ASSIGN(Reference) + + operator napi_ref() const; + bool operator==(const Reference& other) const; + bool operator!=(const Reference& other) const; + + Napi::Env Env() const; + bool IsEmpty() const; + + // Note when getting the value of a Reference it is usually correct to do so + // within a HandleScope so that the value handle gets cleaned up efficiently. + T Value() const; + + uint32_t Ref() const; + uint32_t Unref() const; + void Reset(); + void Reset(const T& value, uint32_t refcount = 0); + + // Call this on a reference that is declared as static data, to prevent its + // destructor from running at program shutdown time, which would attempt to + // reset the reference when the environment is no longer valid. Avoid using + // this if at all possible. If you do need to use static data, MAKE SURE to + // warn your users that your addon is NOT threadsafe. + void SuppressDestruct(); + + protected: + Reference(const Reference&); + + /// !cond INTERNAL + napi_env _env; + napi_ref _ref; + /// !endcond + + private: + bool _suppressDestruct; +}; + +class ObjectReference : public Reference { + public: + ObjectReference(); + ObjectReference(napi_env env, napi_ref ref); + + // A reference can be moved but cannot be copied. + ObjectReference(Reference&& other); + ObjectReference& operator=(Reference&& other); + ObjectReference(ObjectReference&& other); + ObjectReference& operator=(ObjectReference&& other); + NAPI_DISALLOW_ASSIGN(ObjectReference) + + MaybeOrValue Get(const char* utf8name) const; + MaybeOrValue Get(const std::string& utf8name) const; + MaybeOrValue Set(const char* utf8name, napi_value value) const; + MaybeOrValue Set(const char* utf8name, Napi::Value value) const; + MaybeOrValue Set(const char* utf8name, const char* utf8value) const; + MaybeOrValue Set(const char* utf8name, bool boolValue) const; + MaybeOrValue Set(const char* utf8name, double numberValue) const; + MaybeOrValue Set(const std::string& utf8name, napi_value value) const; + MaybeOrValue Set(const std::string& utf8name, Napi::Value value) const; + MaybeOrValue Set(const std::string& utf8name, + std::string& utf8value) const; + MaybeOrValue Set(const std::string& utf8name, bool boolValue) const; + MaybeOrValue Set(const std::string& utf8name, double numberValue) const; + + MaybeOrValue Get(uint32_t index) const; + MaybeOrValue Set(uint32_t index, const napi_value value) const; + MaybeOrValue Set(uint32_t index, const Napi::Value value) const; + MaybeOrValue Set(uint32_t index, const char* utf8value) const; + MaybeOrValue Set(uint32_t index, const std::string& utf8value) const; + MaybeOrValue Set(uint32_t index, bool boolValue) const; + MaybeOrValue Set(uint32_t index, double numberValue) const; + + protected: + ObjectReference(const ObjectReference&); +}; + +class FunctionReference : public Reference { + public: + FunctionReference(); + FunctionReference(napi_env env, napi_ref ref); + + // A reference can be moved but cannot be copied. + FunctionReference(Reference&& other); + FunctionReference& operator=(Reference&& other); + FunctionReference(FunctionReference&& other); + FunctionReference& operator=(FunctionReference&& other); + NAPI_DISALLOW_ASSIGN_COPY(FunctionReference) + + MaybeOrValue operator()( + const std::initializer_list& args) const; + + MaybeOrValue Call( + const std::initializer_list& args) const; + MaybeOrValue Call(const std::vector& args) const; + MaybeOrValue Call( + napi_value recv, const std::initializer_list& args) const; + MaybeOrValue Call(napi_value recv, + const std::vector& args) const; + MaybeOrValue Call(napi_value recv, + size_t argc, + const napi_value* args) const; + + MaybeOrValue MakeCallback( + napi_value recv, + const std::initializer_list& args, + napi_async_context context = nullptr) const; + MaybeOrValue MakeCallback( + napi_value recv, + const std::vector& args, + napi_async_context context = nullptr) const; + MaybeOrValue MakeCallback( + napi_value recv, + size_t argc, + const napi_value* args, + napi_async_context context = nullptr) const; + + MaybeOrValue New(const std::initializer_list& args) const; + MaybeOrValue New(const std::vector& args) const; +}; + +// Shortcuts to creating a new reference with inferred type and refcount = 0. +template +Reference Weak(T value); +ObjectReference Weak(Object value); +FunctionReference Weak(Function value); + +// Shortcuts to creating a new reference with inferred type and refcount = 1. +template +Reference Persistent(T value); +ObjectReference Persistent(Object value); +FunctionReference Persistent(Function value); + +/// A persistent reference to a JavaScript error object. Use of this class +/// depends somewhat on whether C++ exceptions are enabled at compile time. +/// +/// ### Handling Errors With C++ Exceptions +/// +/// If C++ exceptions are enabled, then the `Error` class extends +/// `std::exception` and enables integrated error-handling for C++ exceptions +/// and JavaScript exceptions. +/// +/// If a Node-API call fails without executing any JavaScript code (for +/// example due to an invalid argument), then the Node-API wrapper +/// automatically converts and throws the error as a C++ exception of type +/// `Napi::Error`. Or if a JavaScript function called by C++ code via Node-API +/// throws a JavaScript exception, then the Node-API wrapper automatically +/// converts and throws it as a C++ exception of type `Napi::Error`. +/// +/// If a C++ exception of type `Napi::Error` escapes from a Node-API C++ +/// callback, then the Node-API wrapper automatically converts and throws it +/// as a JavaScript exception. Therefore, catching a C++ exception of type +/// `Napi::Error` prevents a JavaScript exception from being thrown. +/// +/// #### Example 1A - Throwing a C++ exception: +/// +/// Napi::Env env = ... +/// throw Napi::Error::New(env, "Example exception"); +/// +/// Following C++ statements will not be executed. The exception will bubble +/// up as a C++ exception of type `Napi::Error`, until it is either caught +/// while still in C++, or else automatically propataged as a JavaScript +/// exception when the callback returns to JavaScript. +/// +/// #### Example 2A - Propagating a Node-API C++ exception: +/// +/// Napi::Function jsFunctionThatThrows = someObj.As(); +/// Napi::Value result = jsFunctionThatThrows({ arg1, arg2 }); +/// +/// Following C++ statements will not be executed. The exception will bubble +/// up as a C++ exception of type `Napi::Error`, until it is either caught +/// while still in C++, or else automatically propagated as a JavaScript +/// exception when the callback returns to JavaScript. +/// +/// #### Example 3A - Handling a Node-API C++ exception: +/// +/// Napi::Function jsFunctionThatThrows = someObj.As(); +/// Napi::Value result; +/// try { +/// result = jsFunctionThatThrows({ arg1, arg2 }); +/// } catch (const Napi::Error& e) { +/// cerr << "Caught JavaScript exception: " + e.what(); +/// } +/// +/// Since the exception was caught here, it will not be propagated as a +/// JavaScript exception. +/// +/// ### Handling Errors Without C++ Exceptions +/// +/// If C++ exceptions are disabled (by defining `NAPI_DISABLE_CPP_EXCEPTIONS`) +/// then this class does not extend `std::exception`, and APIs in the `Napi` +/// namespace do not throw C++ exceptions when they fail. Instead, they raise +/// _pending_ JavaScript exceptions and return _empty_ `Value`s. Calling code +/// should check `Value::IsEmpty()` before attempting to use a returned value, +/// and may use methods on the `Env` class to check for, get, and clear a +/// pending JavaScript exception. If the pending exception is not cleared, it +/// will be thrown when the native callback returns to JavaScript. +/// +/// #### Example 1B - Throwing a JS exception +/// +/// Napi::Env env = ... +/// Napi::Error::New(env, "Example +/// exception").ThrowAsJavaScriptException(); return; +/// +/// After throwing a JS exception, the code should generally return +/// immediately from the native callback, after performing any necessary +/// cleanup. +/// +/// #### Example 2B - Propagating a Node-API JS exception: +/// +/// Napi::Function jsFunctionThatThrows = someObj.As(); +/// Napi::Value result = jsFunctionThatThrows({ arg1, arg2 }); +/// if (result.IsEmpty()) return; +/// +/// An empty value result from a Node-API call indicates an error occurred, +/// and a JavaScript exception is pending. To let the exception propagate, the +/// code should generally return immediately from the native callback, after +/// performing any necessary cleanup. +/// +/// #### Example 3B - Handling a Node-API JS exception: +/// +/// Napi::Function jsFunctionThatThrows = someObj.As(); +/// Napi::Value result = jsFunctionThatThrows({ arg1, arg2 }); +/// if (result.IsEmpty()) { +/// Napi::Error e = env.GetAndClearPendingException(); +/// cerr << "Caught JavaScript exception: " + e.Message(); +/// } +/// +/// Since the exception was cleared here, it will not be propagated as a +/// JavaScript exception after the native callback returns. +class Error : public ObjectReference #ifdef NAPI_CPP_EXCEPTIONS - , public std::exception -#endif // NAPI_CPP_EXCEPTIONS - { - public: - static Error New(napi_env env); - static Error New(napi_env env, const char* message); - static Error New(napi_env env, const std::string& message); + , + public std::exception +#endif // NAPI_CPP_EXCEPTIONS +{ + public: + static Error New(napi_env env); + static Error New(napi_env env, const char* message); + static Error New(napi_env env, const std::string& message); - static NAPI_NO_RETURN void Fatal(const char* location, const char* message); + static NAPI_NO_RETURN void Fatal(const char* location, const char* message); - Error(); - Error(napi_env env, napi_value value); + Error(); + Error(napi_env env, napi_value value); - // An error can be moved or copied. - Error(Error&& other); - Error& operator =(Error&& other); - Error(const Error&); - Error& operator =(const Error&); + // An error can be moved or copied. + Error(Error&& other); + Error& operator=(Error&& other); + Error(const Error&); + Error& operator=(const Error&); - const std::string& Message() const NAPI_NOEXCEPT; - void ThrowAsJavaScriptException() const; + const std::string& Message() const NAPI_NOEXCEPT; + void ThrowAsJavaScriptException() const; - Object Value() const; + Object Value() const; #ifdef NAPI_CPP_EXCEPTIONS - const char* what() const NAPI_NOEXCEPT override; -#endif // NAPI_CPP_EXCEPTIONS - - protected: - /// !cond INTERNAL - using create_error_fn = napi_status (*)(napi_env envb, - napi_value code, - napi_value msg, - napi_value* result); - - template - static TError New(napi_env env, - const char* message, - size_t length, - create_error_fn create_error); - /// !endcond - - private: - static inline const char* ERROR_WRAP_VALUE() NAPI_NOEXCEPT; - mutable std::string _message; - }; - - class TypeError : public Error { - public: - static TypeError New(napi_env env, const char* message); - static TypeError New(napi_env env, const std::string& message); - - TypeError(); - TypeError(napi_env env, napi_value value); - }; - - class RangeError : public Error { - public: - static RangeError New(napi_env env, const char* message); - static RangeError New(napi_env env, const std::string& message); - - RangeError(); - RangeError(napi_env env, napi_value value); - }; - - class CallbackInfo { - public: - CallbackInfo(napi_env env, napi_callback_info info); - ~CallbackInfo(); - - // Disallow copying to prevent multiple free of _dynamicArgs - NAPI_DISALLOW_ASSIGN_COPY(CallbackInfo) - - Napi::Env Env() const; - Value NewTarget() const; - bool IsConstructCall() const; - size_t Length() const; - const Value operator [](size_t index) const; - Value This() const; - void* Data() const; - void SetData(void* data); - - private: - const size_t _staticArgCount = 6; - napi_env _env; - napi_callback_info _info; - napi_value _this; - size_t _argc; - napi_value* _argv; - napi_value _staticArgs[6]; - napi_value* _dynamicArgs; - void* _data; - }; + const char* what() const NAPI_NOEXCEPT override; +#endif // NAPI_CPP_EXCEPTIONS - class PropertyDescriptor { - public: - using GetterCallback = Napi::Value (*)(const Napi::CallbackInfo& info); - using SetterCallback = void (*)(const Napi::CallbackInfo& info); + protected: + /// !cond INTERNAL + using create_error_fn = napi_status (*)(napi_env envb, + napi_value code, + napi_value msg, + napi_value* result); + + template + static TError New(napi_env env, + const char* message, + size_t length, + create_error_fn create_error); + /// !endcond + + private: + static inline const char* ERROR_WRAP_VALUE() NAPI_NOEXCEPT; + mutable std::string _message; +}; + +class TypeError : public Error { + public: + static TypeError New(napi_env env, const char* message); + static TypeError New(napi_env env, const std::string& message); + + TypeError(); + TypeError(napi_env env, napi_value value); +}; + +class RangeError : public Error { + public: + static RangeError New(napi_env env, const char* message); + static RangeError New(napi_env env, const std::string& message); + + RangeError(); + RangeError(napi_env env, napi_value value); +}; + +class CallbackInfo { + public: + CallbackInfo(napi_env env, napi_callback_info info); + ~CallbackInfo(); + + // Disallow copying to prevent multiple free of _dynamicArgs + NAPI_DISALLOW_ASSIGN_COPY(CallbackInfo) + + Napi::Env Env() const; + Value NewTarget() const; + bool IsConstructCall() const; + size_t Length() const; + const Value operator[](size_t index) const; + Value This() const; + void* Data() const; + void SetData(void* data); + operator napi_callback_info() const; + + private: + const size_t _staticArgCount = 6; + napi_env _env; + napi_callback_info _info; + napi_value _this; + size_t _argc; + napi_value* _argv; + napi_value _staticArgs[6]; + napi_value* _dynamicArgs; + void* _data; +}; + +class PropertyDescriptor { + public: + using GetterCallback = Napi::Value (*)(const Napi::CallbackInfo& info); + using SetterCallback = void (*)(const Napi::CallbackInfo& info); #ifndef NODE_ADDON_API_DISABLE_DEPRECATED - template - static PropertyDescriptor Accessor(const char* utf8name, - Getter getter, - napi_property_attributes attributes = napi_default, - void* data = nullptr); - template - static PropertyDescriptor Accessor(const std::string& utf8name, - Getter getter, - napi_property_attributes attributes = napi_default, - void* data = nullptr); - template - static PropertyDescriptor Accessor(napi_value name, - Getter getter, - napi_property_attributes attributes = napi_default, - void* data = nullptr); - template - static PropertyDescriptor Accessor(Name name, - Getter getter, - napi_property_attributes attributes = napi_default, - void* data = nullptr); - template - static PropertyDescriptor Accessor(const char* utf8name, - Getter getter, - Setter setter, - napi_property_attributes attributes = napi_default, - void* data = nullptr); - template - static PropertyDescriptor Accessor(const std::string& utf8name, - Getter getter, - Setter setter, - napi_property_attributes attributes = napi_default, - void* data = nullptr); - template - static PropertyDescriptor Accessor(napi_value name, - Getter getter, - Setter setter, - napi_property_attributes attributes = napi_default, - void* data = nullptr); - template - static PropertyDescriptor Accessor(Name name, - Getter getter, - Setter setter, - napi_property_attributes attributes = napi_default, - void* data = nullptr); - template - static PropertyDescriptor Function(const char* utf8name, - Callable cb, - napi_property_attributes attributes = napi_default, - void* data = nullptr); - template - static PropertyDescriptor Function(const std::string& utf8name, - Callable cb, - napi_property_attributes attributes = napi_default, - void* data = nullptr); - template - static PropertyDescriptor Function(napi_value name, - Callable cb, - napi_property_attributes attributes = napi_default, - void* data = nullptr); - template - static PropertyDescriptor Function(Name name, - Callable cb, - napi_property_attributes attributes = napi_default, - void* data = nullptr); -#endif // !NODE_ADDON_API_DISABLE_DEPRECATED - - template - static PropertyDescriptor Accessor(const char* utf8name, - napi_property_attributes attributes = napi_default, - void* data = nullptr); - - template - static PropertyDescriptor Accessor(const std::string& utf8name, - napi_property_attributes attributes = napi_default, - void* data = nullptr); - - template - static PropertyDescriptor Accessor(Name name, - napi_property_attributes attributes = napi_default, - void* data = nullptr); - - template - static PropertyDescriptor Accessor(const char* utf8name, - napi_property_attributes attributes = napi_default, - void* data = nullptr); - - template - static PropertyDescriptor Accessor(const std::string& utf8name, - napi_property_attributes attributes = napi_default, - void* data = nullptr); - - template - static PropertyDescriptor Accessor(Name name, - napi_property_attributes attributes = napi_default, - void* data = nullptr); - - template - static PropertyDescriptor Accessor(Napi::Env env, - Napi::Object object, - const char* utf8name, - Getter getter, - napi_property_attributes attributes = napi_default, - void* data = nullptr); - template - static PropertyDescriptor Accessor(Napi::Env env, - Napi::Object object, - const std::string& utf8name, - Getter getter, - napi_property_attributes attributes = napi_default, - void* data = nullptr); - template - static PropertyDescriptor Accessor(Napi::Env env, - Napi::Object object, - Name name, - Getter getter, - napi_property_attributes attributes = napi_default, - void* data = nullptr); - template - static PropertyDescriptor Accessor(Napi::Env env, - Napi::Object object, - const char* utf8name, - Getter getter, - Setter setter, - napi_property_attributes attributes = napi_default, - void* data = nullptr); - template - static PropertyDescriptor Accessor(Napi::Env env, - Napi::Object object, - const std::string& utf8name, - Getter getter, - Setter setter, - napi_property_attributes attributes = napi_default, - void* data = nullptr); - template - static PropertyDescriptor Accessor(Napi::Env env, - Napi::Object object, - Name name, - Getter getter, - Setter setter, - napi_property_attributes attributes = napi_default, - void* data = nullptr); - template - static PropertyDescriptor Function(Napi::Env env, - Napi::Object object, - const char* utf8name, - Callable cb, - napi_property_attributes attributes = napi_default, - void* data = nullptr); - template - static PropertyDescriptor Function(Napi::Env env, - Napi::Object object, - const std::string& utf8name, - Callable cb, - napi_property_attributes attributes = napi_default, - void* data = nullptr); - template - static PropertyDescriptor Function(Napi::Env env, - Napi::Object object, - Name name, - Callable cb, - napi_property_attributes attributes = napi_default, - void* data = nullptr); - static PropertyDescriptor Value(const char* utf8name, - napi_value value, - napi_property_attributes attributes = napi_default); - static PropertyDescriptor Value(const std::string& utf8name, - napi_value value, - napi_property_attributes attributes = napi_default); - static PropertyDescriptor Value(napi_value name, - napi_value value, - napi_property_attributes attributes = napi_default); - static PropertyDescriptor Value(Name name, - Napi::Value value, - napi_property_attributes attributes = napi_default); - - PropertyDescriptor(napi_property_descriptor desc); - - operator napi_property_descriptor&(); - operator const napi_property_descriptor&() const; - - private: - napi_property_descriptor _desc; - }; - - /// Property descriptor for use with `ObjectWrap::DefineClass()`. - /// - /// This is different from the standalone `PropertyDescriptor` because it is specific to each - /// `ObjectWrap` subclass. This prevents using descriptors from a different class when - /// defining a new class (preventing the callbacks from having incorrect `this` pointers). - template - class ClassPropertyDescriptor { - public: - ClassPropertyDescriptor(napi_property_descriptor desc) : _desc(desc) {} - - operator napi_property_descriptor&() { return _desc; } - operator const napi_property_descriptor&() const { return _desc; } - - private: - napi_property_descriptor _desc; - }; - - template - struct MethodCallbackData { - TCallback callback; - void* data; - }; - - template - struct AccessorCallbackData { - TGetterCallback getterCallback; - TSetterCallback setterCallback; - void* data; - }; - - template - class InstanceWrap { - public: - using InstanceVoidMethodCallback = void (T::*)(const CallbackInfo& info); - using InstanceMethodCallback = Napi::Value (T::*)(const CallbackInfo& info); - using InstanceGetterCallback = Napi::Value (T::*)(const CallbackInfo& info); - using InstanceSetterCallback = void (T::*)(const CallbackInfo& info, - const Napi::Value& value); - - using PropertyDescriptor = ClassPropertyDescriptor; - - static PropertyDescriptor InstanceMethod(const char* utf8name, - InstanceVoidMethodCallback method, - napi_property_attributes attributes = napi_default, - void* data = nullptr); - static PropertyDescriptor InstanceMethod(const char* utf8name, - InstanceMethodCallback method, - napi_property_attributes attributes = napi_default, - void* data = nullptr); - static PropertyDescriptor InstanceMethod(Symbol name, - InstanceVoidMethodCallback method, - napi_property_attributes attributes = napi_default, - void* data = nullptr); - static PropertyDescriptor InstanceMethod(Symbol name, - InstanceMethodCallback method, - napi_property_attributes attributes = napi_default, - void* data = nullptr); - template - static PropertyDescriptor InstanceMethod(const char* utf8name, - napi_property_attributes attributes = napi_default, - void* data = nullptr); - template - static PropertyDescriptor InstanceMethod(const char* utf8name, - napi_property_attributes attributes = napi_default, - void* data = nullptr); - template - static PropertyDescriptor InstanceMethod(Symbol name, - napi_property_attributes attributes = napi_default, - void* data = nullptr); - template - static PropertyDescriptor InstanceMethod(Symbol name, - napi_property_attributes attributes = napi_default, - void* data = nullptr); - static PropertyDescriptor InstanceAccessor(const char* utf8name, - InstanceGetterCallback getter, - InstanceSetterCallback setter, - napi_property_attributes attributes = napi_default, - void* data = nullptr); - static PropertyDescriptor InstanceAccessor(Symbol name, - InstanceGetterCallback getter, - InstanceSetterCallback setter, - napi_property_attributes attributes = napi_default, - void* data = nullptr); - template - static PropertyDescriptor InstanceAccessor(const char* utf8name, - napi_property_attributes attributes = napi_default, - void* data = nullptr); - template - static PropertyDescriptor InstanceAccessor(Symbol name, - napi_property_attributes attributes = napi_default, - void* data = nullptr); - static PropertyDescriptor InstanceValue(const char* utf8name, - Napi::Value value, - napi_property_attributes attributes = napi_default); - static PropertyDescriptor InstanceValue(Symbol name, - Napi::Value value, - napi_property_attributes attributes = napi_default); - - protected: - static void AttachPropData(napi_env env, napi_value value, const napi_property_descriptor* prop); - - private: - using This = InstanceWrap; - - using InstanceVoidMethodCallbackData = - MethodCallbackData; - using InstanceMethodCallbackData = - MethodCallbackData; - using InstanceAccessorCallbackData = - AccessorCallbackData; - - static napi_value InstanceVoidMethodCallbackWrapper(napi_env env, napi_callback_info info); - static napi_value InstanceMethodCallbackWrapper(napi_env env, napi_callback_info info); - static napi_value InstanceGetterCallbackWrapper(napi_env env, napi_callback_info info); - static napi_value InstanceSetterCallbackWrapper(napi_env env, napi_callback_info info); - - template - static napi_value WrappedMethod(napi_env env, - napi_callback_info info) NAPI_NOEXCEPT; - - template struct SetterTag {}; - - template - static napi_callback WrapSetter(SetterTag) NAPI_NOEXCEPT { - return &This::WrappedMethod; - } - static napi_callback WrapSetter(SetterTag) NAPI_NOEXCEPT { - return nullptr; - } - }; + template + static PropertyDescriptor Accessor( + const char* utf8name, + Getter getter, + napi_property_attributes attributes = napi_default, + void* data = nullptr); + template + static PropertyDescriptor Accessor( + const std::string& utf8name, + Getter getter, + napi_property_attributes attributes = napi_default, + void* data = nullptr); + template + static PropertyDescriptor Accessor( + napi_value name, + Getter getter, + napi_property_attributes attributes = napi_default, + void* data = nullptr); + template + static PropertyDescriptor Accessor( + Name name, + Getter getter, + napi_property_attributes attributes = napi_default, + void* data = nullptr); + template + static PropertyDescriptor Accessor( + const char* utf8name, + Getter getter, + Setter setter, + napi_property_attributes attributes = napi_default, + void* data = nullptr); + template + static PropertyDescriptor Accessor( + const std::string& utf8name, + Getter getter, + Setter setter, + napi_property_attributes attributes = napi_default, + void* data = nullptr); + template + static PropertyDescriptor Accessor( + napi_value name, + Getter getter, + Setter setter, + napi_property_attributes attributes = napi_default, + void* data = nullptr); + template + static PropertyDescriptor Accessor( + Name name, + Getter getter, + Setter setter, + napi_property_attributes attributes = napi_default, + void* data = nullptr); + template + static PropertyDescriptor Function( + const char* utf8name, + Callable cb, + napi_property_attributes attributes = napi_default, + void* data = nullptr); + template + static PropertyDescriptor Function( + const std::string& utf8name, + Callable cb, + napi_property_attributes attributes = napi_default, + void* data = nullptr); + template + static PropertyDescriptor Function( + napi_value name, + Callable cb, + napi_property_attributes attributes = napi_default, + void* data = nullptr); + template + static PropertyDescriptor Function( + Name name, + Callable cb, + napi_property_attributes attributes = napi_default, + void* data = nullptr); +#endif // !NODE_ADDON_API_DISABLE_DEPRECATED + + template + static PropertyDescriptor Accessor( + const char* utf8name, + napi_property_attributes attributes = napi_default, + void* data = nullptr); + + template + static PropertyDescriptor Accessor( + const std::string& utf8name, + napi_property_attributes attributes = napi_default, + void* data = nullptr); + + template + static PropertyDescriptor Accessor( + Name name, + napi_property_attributes attributes = napi_default, + void* data = nullptr); + + template + static PropertyDescriptor Accessor( + const char* utf8name, + napi_property_attributes attributes = napi_default, + void* data = nullptr); + + template + static PropertyDescriptor Accessor( + const std::string& utf8name, + napi_property_attributes attributes = napi_default, + void* data = nullptr); + + template + static PropertyDescriptor Accessor( + Name name, + napi_property_attributes attributes = napi_default, + void* data = nullptr); + + template + static PropertyDescriptor Accessor( + Napi::Env env, + Napi::Object object, + const char* utf8name, + Getter getter, + napi_property_attributes attributes = napi_default, + void* data = nullptr); + template + static PropertyDescriptor Accessor( + Napi::Env env, + Napi::Object object, + const std::string& utf8name, + Getter getter, + napi_property_attributes attributes = napi_default, + void* data = nullptr); + template + static PropertyDescriptor Accessor( + Napi::Env env, + Napi::Object object, + Name name, + Getter getter, + napi_property_attributes attributes = napi_default, + void* data = nullptr); + template + static PropertyDescriptor Accessor( + Napi::Env env, + Napi::Object object, + const char* utf8name, + Getter getter, + Setter setter, + napi_property_attributes attributes = napi_default, + void* data = nullptr); + template + static PropertyDescriptor Accessor( + Napi::Env env, + Napi::Object object, + const std::string& utf8name, + Getter getter, + Setter setter, + napi_property_attributes attributes = napi_default, + void* data = nullptr); + template + static PropertyDescriptor Accessor( + Napi::Env env, + Napi::Object object, + Name name, + Getter getter, + Setter setter, + napi_property_attributes attributes = napi_default, + void* data = nullptr); + template + static PropertyDescriptor Function( + Napi::Env env, + Napi::Object object, + const char* utf8name, + Callable cb, + napi_property_attributes attributes = napi_default, + void* data = nullptr); + template + static PropertyDescriptor Function( + Napi::Env env, + Napi::Object object, + const std::string& utf8name, + Callable cb, + napi_property_attributes attributes = napi_default, + void* data = nullptr); + template + static PropertyDescriptor Function( + Napi::Env env, + Napi::Object object, + Name name, + Callable cb, + napi_property_attributes attributes = napi_default, + void* data = nullptr); + static PropertyDescriptor Value( + const char* utf8name, + napi_value value, + napi_property_attributes attributes = napi_default); + static PropertyDescriptor Value( + const std::string& utf8name, + napi_value value, + napi_property_attributes attributes = napi_default); + static PropertyDescriptor Value( + napi_value name, + napi_value value, + napi_property_attributes attributes = napi_default); + static PropertyDescriptor Value( + Name name, + Napi::Value value, + napi_property_attributes attributes = napi_default); + + PropertyDescriptor(napi_property_descriptor desc); + + operator napi_property_descriptor&(); + operator const napi_property_descriptor&() const; + + private: + napi_property_descriptor _desc; +}; + +/// Property descriptor for use with `ObjectWrap::DefineClass()`. +/// +/// This is different from the standalone `PropertyDescriptor` because it is +/// specific to each `ObjectWrap` subclass. This prevents using descriptors +/// from a different class when defining a new class (preventing the callbacks +/// from having incorrect `this` pointers). +template +class ClassPropertyDescriptor { + public: + ClassPropertyDescriptor(napi_property_descriptor desc) : _desc(desc) {} + + operator napi_property_descriptor&() { return _desc; } + operator const napi_property_descriptor&() const { return _desc; } + + private: + napi_property_descriptor _desc; +}; + +template +struct MethodCallbackData { + TCallback callback; + void* data; +}; + +template +struct AccessorCallbackData { + TGetterCallback getterCallback; + TSetterCallback setterCallback; + void* data; +}; + +template +class InstanceWrap { + public: + using InstanceVoidMethodCallback = void (T::*)(const CallbackInfo& info); + using InstanceMethodCallback = Napi::Value (T::*)(const CallbackInfo& info); + using InstanceGetterCallback = Napi::Value (T::*)(const CallbackInfo& info); + using InstanceSetterCallback = void (T::*)(const CallbackInfo& info, + const Napi::Value& value); + + using PropertyDescriptor = ClassPropertyDescriptor; + + static PropertyDescriptor InstanceMethod( + const char* utf8name, + InstanceVoidMethodCallback method, + napi_property_attributes attributes = napi_default, + void* data = nullptr); + static PropertyDescriptor InstanceMethod( + const char* utf8name, + InstanceMethodCallback method, + napi_property_attributes attributes = napi_default, + void* data = nullptr); + static PropertyDescriptor InstanceMethod( + Symbol name, + InstanceVoidMethodCallback method, + napi_property_attributes attributes = napi_default, + void* data = nullptr); + static PropertyDescriptor InstanceMethod( + Symbol name, + InstanceMethodCallback method, + napi_property_attributes attributes = napi_default, + void* data = nullptr); + template + static PropertyDescriptor InstanceMethod( + const char* utf8name, + napi_property_attributes attributes = napi_default, + void* data = nullptr); + template + static PropertyDescriptor InstanceMethod( + const char* utf8name, + napi_property_attributes attributes = napi_default, + void* data = nullptr); + template + static PropertyDescriptor InstanceMethod( + Symbol name, + napi_property_attributes attributes = napi_default, + void* data = nullptr); + template + static PropertyDescriptor InstanceMethod( + Symbol name, + napi_property_attributes attributes = napi_default, + void* data = nullptr); + static PropertyDescriptor InstanceAccessor( + const char* utf8name, + InstanceGetterCallback getter, + InstanceSetterCallback setter, + napi_property_attributes attributes = napi_default, + void* data = nullptr); + static PropertyDescriptor InstanceAccessor( + Symbol name, + InstanceGetterCallback getter, + InstanceSetterCallback setter, + napi_property_attributes attributes = napi_default, + void* data = nullptr); + template + static PropertyDescriptor InstanceAccessor( + const char* utf8name, + napi_property_attributes attributes = napi_default, + void* data = nullptr); + template + static PropertyDescriptor InstanceAccessor( + Symbol name, + napi_property_attributes attributes = napi_default, + void* data = nullptr); + static PropertyDescriptor InstanceValue( + const char* utf8name, + Napi::Value value, + napi_property_attributes attributes = napi_default); + static PropertyDescriptor InstanceValue( + Symbol name, + Napi::Value value, + napi_property_attributes attributes = napi_default); + + protected: + static void AttachPropData(napi_env env, + napi_value value, + const napi_property_descriptor* prop); + + private: + using This = InstanceWrap; + + using InstanceVoidMethodCallbackData = + MethodCallbackData; + using InstanceMethodCallbackData = + MethodCallbackData; + using InstanceAccessorCallbackData = + AccessorCallbackData; + + static napi_value InstanceVoidMethodCallbackWrapper(napi_env env, + napi_callback_info info); + static napi_value InstanceMethodCallbackWrapper(napi_env env, + napi_callback_info info); + static napi_value InstanceGetterCallbackWrapper(napi_env env, + napi_callback_info info); + static napi_value InstanceSetterCallbackWrapper(napi_env env, + napi_callback_info info); + + template + static napi_value WrappedMethod(napi_env env, + napi_callback_info info) NAPI_NOEXCEPT; + + template + struct SetterTag {}; + + template + static napi_callback WrapSetter(SetterTag) NAPI_NOEXCEPT { + return &This::WrappedMethod; + } + static napi_callback WrapSetter(SetterTag) NAPI_NOEXCEPT { + return nullptr; + } +}; - /// Base class to be extended by C++ classes exposed to JavaScript; each C++ class instance gets - /// "wrapped" by a JavaScript object that is managed by this class. - /// - /// At initialization time, the `DefineClass()` method must be used to - /// hook up the accessor and method callbacks. It takes a list of - /// property descriptors, which can be constructed via the various - /// static methods on the base class. - /// - /// #### Example: - /// - /// class Example: public Napi::ObjectWrap { - /// public: - /// static void Initialize(Napi::Env& env, Napi::Object& target) { - /// Napi::Function constructor = DefineClass(env, "Example", { - /// InstanceAccessor<&Example::GetSomething, &Example::SetSomething>("value"), - /// InstanceMethod<&Example::DoSomething>("doSomething"), - /// }); - /// target.Set("Example", constructor); - /// } - /// - /// Example(const Napi::CallbackInfo& info); // Constructor - /// Napi::Value GetSomething(const Napi::CallbackInfo& info); - /// void SetSomething(const Napi::CallbackInfo& info, const Napi::Value& value); - /// Napi::Value DoSomething(const Napi::CallbackInfo& info); - /// } - template - class ObjectWrap : public InstanceWrap, public Reference { - public: - ObjectWrap(const CallbackInfo& callbackInfo); - virtual ~ObjectWrap(); - - static T* Unwrap(Object wrapper); - - // Methods exposed to JavaScript must conform to one of these callback signatures. - using StaticVoidMethodCallback = void (*)(const CallbackInfo& info); - using StaticMethodCallback = Napi::Value (*)(const CallbackInfo& info); - using StaticGetterCallback = Napi::Value (*)(const CallbackInfo& info); - using StaticSetterCallback = void (*)(const CallbackInfo& info, - const Napi::Value& value); - - using PropertyDescriptor = ClassPropertyDescriptor; - - static Function DefineClass(Napi::Env env, - const char* utf8name, - const std::initializer_list& properties, - void* data = nullptr); - static Function DefineClass(Napi::Env env, - const char* utf8name, - const std::vector& properties, - void* data = nullptr); - static PropertyDescriptor StaticMethod(const char* utf8name, - StaticVoidMethodCallback method, - napi_property_attributes attributes = napi_default, - void* data = nullptr); - static PropertyDescriptor StaticMethod(const char* utf8name, - StaticMethodCallback method, - napi_property_attributes attributes = napi_default, - void* data = nullptr); - static PropertyDescriptor StaticMethod(Symbol name, - StaticVoidMethodCallback method, - napi_property_attributes attributes = napi_default, - void* data = nullptr); - static PropertyDescriptor StaticMethod(Symbol name, - StaticMethodCallback method, - napi_property_attributes attributes = napi_default, - void* data = nullptr); - template - static PropertyDescriptor StaticMethod(const char* utf8name, - napi_property_attributes attributes = napi_default, - void* data = nullptr); - template - static PropertyDescriptor StaticMethod(Symbol name, - napi_property_attributes attributes = napi_default, - void* data = nullptr); - template - static PropertyDescriptor StaticMethod(const char* utf8name, - napi_property_attributes attributes = napi_default, - void* data = nullptr); - template - static PropertyDescriptor StaticMethod(Symbol name, - napi_property_attributes attributes = napi_default, - void* data = nullptr); - static PropertyDescriptor StaticAccessor(const char* utf8name, - StaticGetterCallback getter, - StaticSetterCallback setter, - napi_property_attributes attributes = napi_default, - void* data = nullptr); - static PropertyDescriptor StaticAccessor(Symbol name, - StaticGetterCallback getter, - StaticSetterCallback setter, - napi_property_attributes attributes = napi_default, - void* data = nullptr); - template - static PropertyDescriptor StaticAccessor(const char* utf8name, - napi_property_attributes attributes = napi_default, - void* data = nullptr); - template - static PropertyDescriptor StaticAccessor(Symbol name, - napi_property_attributes attributes = napi_default, - void* data = nullptr); - static PropertyDescriptor StaticValue(const char* utf8name, - Napi::Value value, - napi_property_attributes attributes = napi_default); - static PropertyDescriptor StaticValue(Symbol name, - Napi::Value value, - napi_property_attributes attributes = napi_default); - static Napi::Value OnCalledAsFunction( - const Napi::CallbackInfo& callbackInfo); - virtual void Finalize(Napi::Env env); - - private: - using This = ObjectWrap; - - static napi_value ConstructorCallbackWrapper(napi_env env, napi_callback_info info); - static napi_value StaticVoidMethodCallbackWrapper(napi_env env, napi_callback_info info); - static napi_value StaticMethodCallbackWrapper(napi_env env, napi_callback_info info); - static napi_value StaticGetterCallbackWrapper(napi_env env, napi_callback_info info); - static napi_value StaticSetterCallbackWrapper(napi_env env, napi_callback_info info); - static void FinalizeCallback(napi_env env, void* data, void* hint); - static Function DefineClass(Napi::Env env, - const char* utf8name, - const size_t props_count, - const napi_property_descriptor* props, - void* data = nullptr); - - using StaticVoidMethodCallbackData = - MethodCallbackData; - using StaticMethodCallbackData = - MethodCallbackData; - - using StaticAccessorCallbackData = - AccessorCallbackData; - - template - static napi_value WrappedMethod(napi_env env, - napi_callback_info info) NAPI_NOEXCEPT; - - template struct StaticSetterTag {}; - - template - static napi_callback WrapStaticSetter(StaticSetterTag) - NAPI_NOEXCEPT { - return &This::WrappedMethod; - } - static napi_callback WrapStaticSetter(StaticSetterTag) - NAPI_NOEXCEPT { - return nullptr; - } +/// Base class to be extended by C++ classes exposed to JavaScript; each C++ +/// class instance gets "wrapped" by a JavaScript object that is managed by this +/// class. +/// +/// At initialization time, the `DefineClass()` method must be used to +/// hook up the accessor and method callbacks. It takes a list of +/// property descriptors, which can be constructed via the various +/// static methods on the base class. +/// +/// #### Example: +/// +/// class Example: public Napi::ObjectWrap { +/// public: +/// static void Initialize(Napi::Env& env, Napi::Object& target) { +/// Napi::Function constructor = DefineClass(env, "Example", { +/// InstanceAccessor<&Example::GetSomething, +/// &Example::SetSomething>("value"), +/// InstanceMethod<&Example::DoSomething>("doSomething"), +/// }); +/// target.Set("Example", constructor); +/// } +/// +/// Example(const Napi::CallbackInfo& info); // Constructor +/// Napi::Value GetSomething(const Napi::CallbackInfo& info); +/// void SetSomething(const Napi::CallbackInfo& info, const Napi::Value& +/// value); Napi::Value DoSomething(const Napi::CallbackInfo& info); +/// } +template +class ObjectWrap : public InstanceWrap, public Reference { + public: + ObjectWrap(const CallbackInfo& callbackInfo); + virtual ~ObjectWrap(); + + static T* Unwrap(Object wrapper); + + // Methods exposed to JavaScript must conform to one of these callback + // signatures. + using StaticVoidMethodCallback = void (*)(const CallbackInfo& info); + using StaticMethodCallback = Napi::Value (*)(const CallbackInfo& info); + using StaticGetterCallback = Napi::Value (*)(const CallbackInfo& info); + using StaticSetterCallback = void (*)(const CallbackInfo& info, + const Napi::Value& value); + + using PropertyDescriptor = ClassPropertyDescriptor; + + static Function DefineClass( + Napi::Env env, + const char* utf8name, + const std::initializer_list& properties, + void* data = nullptr); + static Function DefineClass(Napi::Env env, + const char* utf8name, + const std::vector& properties, + void* data = nullptr); + static PropertyDescriptor StaticMethod( + const char* utf8name, + StaticVoidMethodCallback method, + napi_property_attributes attributes = napi_default, + void* data = nullptr); + static PropertyDescriptor StaticMethod( + const char* utf8name, + StaticMethodCallback method, + napi_property_attributes attributes = napi_default, + void* data = nullptr); + static PropertyDescriptor StaticMethod( + Symbol name, + StaticVoidMethodCallback method, + napi_property_attributes attributes = napi_default, + void* data = nullptr); + static PropertyDescriptor StaticMethod( + Symbol name, + StaticMethodCallback method, + napi_property_attributes attributes = napi_default, + void* data = nullptr); + template + static PropertyDescriptor StaticMethod( + const char* utf8name, + napi_property_attributes attributes = napi_default, + void* data = nullptr); + template + static PropertyDescriptor StaticMethod( + Symbol name, + napi_property_attributes attributes = napi_default, + void* data = nullptr); + template + static PropertyDescriptor StaticMethod( + const char* utf8name, + napi_property_attributes attributes = napi_default, + void* data = nullptr); + template + static PropertyDescriptor StaticMethod( + Symbol name, + napi_property_attributes attributes = napi_default, + void* data = nullptr); + static PropertyDescriptor StaticAccessor( + const char* utf8name, + StaticGetterCallback getter, + StaticSetterCallback setter, + napi_property_attributes attributes = napi_default, + void* data = nullptr); + static PropertyDescriptor StaticAccessor( + Symbol name, + StaticGetterCallback getter, + StaticSetterCallback setter, + napi_property_attributes attributes = napi_default, + void* data = nullptr); + template + static PropertyDescriptor StaticAccessor( + const char* utf8name, + napi_property_attributes attributes = napi_default, + void* data = nullptr); + template + static PropertyDescriptor StaticAccessor( + Symbol name, + napi_property_attributes attributes = napi_default, + void* data = nullptr); + static PropertyDescriptor StaticValue( + const char* utf8name, + Napi::Value value, + napi_property_attributes attributes = napi_default); + static PropertyDescriptor StaticValue( + Symbol name, + Napi::Value value, + napi_property_attributes attributes = napi_default); + static Napi::Value OnCalledAsFunction(const Napi::CallbackInfo& callbackInfo); + virtual void Finalize(Napi::Env env); + + private: + using This = ObjectWrap; + + static napi_value ConstructorCallbackWrapper(napi_env env, + napi_callback_info info); + static napi_value StaticVoidMethodCallbackWrapper(napi_env env, + napi_callback_info info); + static napi_value StaticMethodCallbackWrapper(napi_env env, + napi_callback_info info); + static napi_value StaticGetterCallbackWrapper(napi_env env, + napi_callback_info info); + static napi_value StaticSetterCallbackWrapper(napi_env env, + napi_callback_info info); + static void FinalizeCallback(napi_env env, void* data, void* hint); + static Function DefineClass(Napi::Env env, + const char* utf8name, + const size_t props_count, + const napi_property_descriptor* props, + void* data = nullptr); + + using StaticVoidMethodCallbackData = + MethodCallbackData; + using StaticMethodCallbackData = MethodCallbackData; + + using StaticAccessorCallbackData = + AccessorCallbackData; + + template + static napi_value WrappedMethod(napi_env env, + napi_callback_info info) NAPI_NOEXCEPT; + + template + struct StaticSetterTag {}; + + template + static napi_callback WrapStaticSetter(StaticSetterTag) NAPI_NOEXCEPT { + return &This::WrappedMethod; + } + static napi_callback WrapStaticSetter(StaticSetterTag) + NAPI_NOEXCEPT { + return nullptr; + } - bool _construction_failed = true; - }; + bool _construction_failed = true; +}; - class HandleScope { - public: - HandleScope(napi_env env, napi_handle_scope scope); - explicit HandleScope(Napi::Env env); - ~HandleScope(); +class HandleScope { + public: + HandleScope(napi_env env, napi_handle_scope scope); + explicit HandleScope(Napi::Env env); + ~HandleScope(); - // Disallow copying to prevent double close of napi_handle_scope - NAPI_DISALLOW_ASSIGN_COPY(HandleScope) + // Disallow copying to prevent double close of napi_handle_scope + NAPI_DISALLOW_ASSIGN_COPY(HandleScope) - operator napi_handle_scope() const; + operator napi_handle_scope() const; - Napi::Env Env() const; + Napi::Env Env() const; - private: - napi_env _env; - napi_handle_scope _scope; - }; + private: + napi_env _env; + napi_handle_scope _scope; +}; - class EscapableHandleScope { - public: - EscapableHandleScope(napi_env env, napi_escapable_handle_scope scope); - explicit EscapableHandleScope(Napi::Env env); - ~EscapableHandleScope(); +class EscapableHandleScope { + public: + EscapableHandleScope(napi_env env, napi_escapable_handle_scope scope); + explicit EscapableHandleScope(Napi::Env env); + ~EscapableHandleScope(); - // Disallow copying to prevent double close of napi_escapable_handle_scope - NAPI_DISALLOW_ASSIGN_COPY(EscapableHandleScope) + // Disallow copying to prevent double close of napi_escapable_handle_scope + NAPI_DISALLOW_ASSIGN_COPY(EscapableHandleScope) - operator napi_escapable_handle_scope() const; + operator napi_escapable_handle_scope() const; - Napi::Env Env() const; - Value Escape(napi_value escapee); + Napi::Env Env() const; + Value Escape(napi_value escapee); - private: - napi_env _env; - napi_escapable_handle_scope _scope; - }; + private: + napi_env _env; + napi_escapable_handle_scope _scope; +}; #if (NAPI_VERSION > 2) - class CallbackScope { - public: - CallbackScope(napi_env env, napi_callback_scope scope); - CallbackScope(napi_env env, napi_async_context context); - virtual ~CallbackScope(); +class CallbackScope { + public: + CallbackScope(napi_env env, napi_callback_scope scope); + CallbackScope(napi_env env, napi_async_context context); + virtual ~CallbackScope(); - // Disallow copying to prevent double close of napi_callback_scope - NAPI_DISALLOW_ASSIGN_COPY(CallbackScope) + // Disallow copying to prevent double close of napi_callback_scope + NAPI_DISALLOW_ASSIGN_COPY(CallbackScope) - operator napi_callback_scope() const; + operator napi_callback_scope() const; - Napi::Env Env() const; + Napi::Env Env() const; - private: - napi_env _env; - napi_callback_scope _scope; - }; + private: + napi_env _env; + napi_callback_scope _scope; +}; #endif - class AsyncContext { - public: - explicit AsyncContext(napi_env env, const char* resource_name); - explicit AsyncContext(napi_env env, const char* resource_name, const Object& resource); - virtual ~AsyncContext(); - - AsyncContext(AsyncContext&& other); - AsyncContext& operator =(AsyncContext&& other); - NAPI_DISALLOW_ASSIGN_COPY(AsyncContext) - - operator napi_async_context() const; - - Napi::Env Env() const; - - private: - napi_env _env; - napi_async_context _context; - }; - - class AsyncWorker { - public: - virtual ~AsyncWorker(); - - // An async worker can be moved but cannot be copied. - AsyncWorker(AsyncWorker&& other); - AsyncWorker& operator =(AsyncWorker&& other); - NAPI_DISALLOW_ASSIGN_COPY(AsyncWorker) - - operator napi_async_work() const; - - Napi::Env Env() const; - - void Queue(); - void Cancel(); - void SuppressDestruct(); - - ObjectReference& Receiver(); - FunctionReference& Callback(); - - virtual void OnExecute(Napi::Env env); - virtual void OnWorkComplete(Napi::Env env, - napi_status status); - - protected: - explicit AsyncWorker(const Function& callback); - explicit AsyncWorker(const Function& callback, - const char* resource_name); - explicit AsyncWorker(const Function& callback, - const char* resource_name, - const Object& resource); - explicit AsyncWorker(const Object& receiver, - const Function& callback); - explicit AsyncWorker(const Object& receiver, - const Function& callback, - const char* resource_name); - explicit AsyncWorker(const Object& receiver, - const Function& callback, - const char* resource_name, - const Object& resource); - - explicit AsyncWorker(Napi::Env env); - explicit AsyncWorker(Napi::Env env, - const char* resource_name); - explicit AsyncWorker(Napi::Env env, - const char* resource_name, - const Object& resource); - - virtual void Execute() = 0; - virtual void OnOK(); - virtual void OnError(const Error& e); - virtual void Destroy(); - virtual std::vector GetResult(Napi::Env env); - - void SetError(const std::string& error); - - private: - static inline void OnAsyncWorkExecute(napi_env env, void* asyncworker); - static inline void OnAsyncWorkComplete(napi_env env, - napi_status status, - void* asyncworker); - - napi_env _env; - napi_async_work _work; - ObjectReference _receiver; - FunctionReference _callback; - std::string _error; - bool _suppress_destruct; - }; - - #if (NAPI_VERSION > 3 && !defined(__wasm32__)) - class ThreadSafeFunction { - public: - // This API may only be called from the main thread. - template - static ThreadSafeFunction New(napi_env env, - const Function& callback, - ResourceString resourceName, - size_t maxQueueSize, - size_t initialThreadCount); - - // This API may only be called from the main thread. - template - static ThreadSafeFunction New(napi_env env, - const Function& callback, - ResourceString resourceName, - size_t maxQueueSize, - size_t initialThreadCount, - ContextType* context); - - // This API may only be called from the main thread. - template - static ThreadSafeFunction New(napi_env env, - const Function& callback, - ResourceString resourceName, - size_t maxQueueSize, - size_t initialThreadCount, - Finalizer finalizeCallback); - - // This API may only be called from the main thread. - template - static ThreadSafeFunction New(napi_env env, - const Function& callback, - ResourceString resourceName, - size_t maxQueueSize, - size_t initialThreadCount, - Finalizer finalizeCallback, - FinalizerDataType* data); - - // This API may only be called from the main thread. - template - static ThreadSafeFunction New(napi_env env, - const Function& callback, - ResourceString resourceName, - size_t maxQueueSize, - size_t initialThreadCount, - ContextType* context, - Finalizer finalizeCallback); - - // This API may only be called from the main thread. - template - static ThreadSafeFunction New(napi_env env, - const Function& callback, - ResourceString resourceName, - size_t maxQueueSize, - size_t initialThreadCount, - ContextType* context, - Finalizer finalizeCallback, - FinalizerDataType* data); - - // This API may only be called from the main thread. - template - static ThreadSafeFunction New(napi_env env, - const Function& callback, - const Object& resource, - ResourceString resourceName, - size_t maxQueueSize, - size_t initialThreadCount); - - // This API may only be called from the main thread. - template - static ThreadSafeFunction New(napi_env env, - const Function& callback, - const Object& resource, - ResourceString resourceName, - size_t maxQueueSize, - size_t initialThreadCount, - ContextType* context); - - // This API may only be called from the main thread. - template - static ThreadSafeFunction New(napi_env env, - const Function& callback, - const Object& resource, - ResourceString resourceName, - size_t maxQueueSize, - size_t initialThreadCount, - Finalizer finalizeCallback); - - // This API may only be called from the main thread. - template - static ThreadSafeFunction New(napi_env env, - const Function& callback, - const Object& resource, - ResourceString resourceName, - size_t maxQueueSize, - size_t initialThreadCount, - Finalizer finalizeCallback, - FinalizerDataType* data); - - // This API may only be called from the main thread. - template - static ThreadSafeFunction New(napi_env env, - const Function& callback, - const Object& resource, - ResourceString resourceName, - size_t maxQueueSize, - size_t initialThreadCount, - ContextType* context, - Finalizer finalizeCallback); - - // This API may only be called from the main thread. - template - static ThreadSafeFunction New(napi_env env, - const Function& callback, - const Object& resource, - ResourceString resourceName, - size_t maxQueueSize, - size_t initialThreadCount, - ContextType* context, - Finalizer finalizeCallback, - FinalizerDataType* data); - - ThreadSafeFunction(); - ThreadSafeFunction(napi_threadsafe_function tsFunctionValue); - - operator napi_threadsafe_function() const; - - // This API may be called from any thread. - napi_status BlockingCall() const; - - // This API may be called from any thread. - template - napi_status BlockingCall(Callback callback) const; - - // This API may be called from any thread. - template - napi_status BlockingCall(DataType* data, Callback callback) const; - - // This API may be called from any thread. - napi_status NonBlockingCall() const; - - // This API may be called from any thread. - template - napi_status NonBlockingCall(Callback callback) const; - - // This API may be called from any thread. - template - napi_status NonBlockingCall(DataType* data, Callback callback) const; - - // This API may only be called from the main thread. - void Ref(napi_env env) const; - - // This API may only be called from the main thread. - void Unref(napi_env env) const; - - // This API may be called from any thread. - napi_status Acquire() const; - - // This API may be called from any thread. - napi_status Release() const; - - // This API may be called from any thread. - napi_status Abort() const; - - struct ConvertibleContext - { - template - operator T*() { return static_cast(context); } - void* context; - }; - - // This API may be called from any thread. - ConvertibleContext GetContext() const; - - private: - using CallbackWrapper = std::function; - - template - static ThreadSafeFunction New(napi_env env, - const Function& callback, - const Object& resource, - ResourceString resourceName, - size_t maxQueueSize, - size_t initialThreadCount, - ContextType* context, - Finalizer finalizeCallback, - FinalizerDataType* data, - napi_finalize wrapper); - - napi_status CallInternal(CallbackWrapper* callbackWrapper, - napi_threadsafe_function_call_mode mode) const; - - static void CallJS(napi_env env, - napi_value jsCallback, - void* context, - void* data); - - napi_threadsafe_function _tsfn; +class AsyncContext { + public: + explicit AsyncContext(napi_env env, const char* resource_name); + explicit AsyncContext(napi_env env, + const char* resource_name, + const Object& resource); + virtual ~AsyncContext(); + + AsyncContext(AsyncContext&& other); + AsyncContext& operator=(AsyncContext&& other); + NAPI_DISALLOW_ASSIGN_COPY(AsyncContext) + + operator napi_async_context() const; + + Napi::Env Env() const; + + private: + napi_env _env; + napi_async_context _context; +}; + +class AsyncWorker { + public: + virtual ~AsyncWorker(); + + // An async worker can be moved but cannot be copied. + AsyncWorker(AsyncWorker&& other); + AsyncWorker& operator=(AsyncWorker&& other); + NAPI_DISALLOW_ASSIGN_COPY(AsyncWorker) + + operator napi_async_work() const; + + Napi::Env Env() const; + + void Queue(); + void Cancel(); + void SuppressDestruct(); + + ObjectReference& Receiver(); + FunctionReference& Callback(); + + virtual void OnExecute(Napi::Env env); + virtual void OnWorkComplete(Napi::Env env, napi_status status); + + protected: + explicit AsyncWorker(const Function& callback); + explicit AsyncWorker(const Function& callback, const char* resource_name); + explicit AsyncWorker(const Function& callback, + const char* resource_name, + const Object& resource); + explicit AsyncWorker(const Object& receiver, const Function& callback); + explicit AsyncWorker(const Object& receiver, + const Function& callback, + const char* resource_name); + explicit AsyncWorker(const Object& receiver, + const Function& callback, + const char* resource_name, + const Object& resource); + + explicit AsyncWorker(Napi::Env env); + explicit AsyncWorker(Napi::Env env, const char* resource_name); + explicit AsyncWorker(Napi::Env env, + const char* resource_name, + const Object& resource); + + virtual void Execute() = 0; + virtual void OnOK(); + virtual void OnError(const Error& e); + virtual void Destroy(); + virtual std::vector GetResult(Napi::Env env); + + void SetError(const std::string& error); + + private: + static inline void OnAsyncWorkExecute(napi_env env, void* asyncworker); + static inline void OnAsyncWorkComplete(napi_env env, + napi_status status, + void* asyncworker); + + napi_env _env; + napi_async_work _work; + ObjectReference _receiver; + FunctionReference _callback; + std::string _error; + bool _suppress_destruct; +}; + +#if (NAPI_VERSION > 3 && !defined(__wasm32__)) +class ThreadSafeFunction { + public: + // This API may only be called from the main thread. + template + static ThreadSafeFunction New(napi_env env, + const Function& callback, + ResourceString resourceName, + size_t maxQueueSize, + size_t initialThreadCount); + + // This API may only be called from the main thread. + template + static ThreadSafeFunction New(napi_env env, + const Function& callback, + ResourceString resourceName, + size_t maxQueueSize, + size_t initialThreadCount, + ContextType* context); + + // This API may only be called from the main thread. + template + static ThreadSafeFunction New(napi_env env, + const Function& callback, + ResourceString resourceName, + size_t maxQueueSize, + size_t initialThreadCount, + Finalizer finalizeCallback); + + // This API may only be called from the main thread. + template + static ThreadSafeFunction New(napi_env env, + const Function& callback, + ResourceString resourceName, + size_t maxQueueSize, + size_t initialThreadCount, + Finalizer finalizeCallback, + FinalizerDataType* data); + + // This API may only be called from the main thread. + template + static ThreadSafeFunction New(napi_env env, + const Function& callback, + ResourceString resourceName, + size_t maxQueueSize, + size_t initialThreadCount, + ContextType* context, + Finalizer finalizeCallback); + + // This API may only be called from the main thread. + template + static ThreadSafeFunction New(napi_env env, + const Function& callback, + ResourceString resourceName, + size_t maxQueueSize, + size_t initialThreadCount, + ContextType* context, + Finalizer finalizeCallback, + FinalizerDataType* data); + + // This API may only be called from the main thread. + template + static ThreadSafeFunction New(napi_env env, + const Function& callback, + const Object& resource, + ResourceString resourceName, + size_t maxQueueSize, + size_t initialThreadCount); + + // This API may only be called from the main thread. + template + static ThreadSafeFunction New(napi_env env, + const Function& callback, + const Object& resource, + ResourceString resourceName, + size_t maxQueueSize, + size_t initialThreadCount, + ContextType* context); + + // This API may only be called from the main thread. + template + static ThreadSafeFunction New(napi_env env, + const Function& callback, + const Object& resource, + ResourceString resourceName, + size_t maxQueueSize, + size_t initialThreadCount, + Finalizer finalizeCallback); + + // This API may only be called from the main thread. + template + static ThreadSafeFunction New(napi_env env, + const Function& callback, + const Object& resource, + ResourceString resourceName, + size_t maxQueueSize, + size_t initialThreadCount, + Finalizer finalizeCallback, + FinalizerDataType* data); + + // This API may only be called from the main thread. + template + static ThreadSafeFunction New(napi_env env, + const Function& callback, + const Object& resource, + ResourceString resourceName, + size_t maxQueueSize, + size_t initialThreadCount, + ContextType* context, + Finalizer finalizeCallback); + + // This API may only be called from the main thread. + template + static ThreadSafeFunction New(napi_env env, + const Function& callback, + const Object& resource, + ResourceString resourceName, + size_t maxQueueSize, + size_t initialThreadCount, + ContextType* context, + Finalizer finalizeCallback, + FinalizerDataType* data); + + ThreadSafeFunction(); + ThreadSafeFunction(napi_threadsafe_function tsFunctionValue); + + operator napi_threadsafe_function() const; + + // This API may be called from any thread. + napi_status BlockingCall() const; + + // This API may be called from any thread. + template + napi_status BlockingCall(Callback callback) const; + + // This API may be called from any thread. + template + napi_status BlockingCall(DataType* data, Callback callback) const; + + // This API may be called from any thread. + napi_status NonBlockingCall() const; + + // This API may be called from any thread. + template + napi_status NonBlockingCall(Callback callback) const; + + // This API may be called from any thread. + template + napi_status NonBlockingCall(DataType* data, Callback callback) const; + + // This API may only be called from the main thread. + void Ref(napi_env env) const; + + // This API may only be called from the main thread. + void Unref(napi_env env) const; + + // This API may be called from any thread. + napi_status Acquire() const; + + // This API may be called from any thread. + napi_status Release() const; + + // This API may be called from any thread. + napi_status Abort() const; + + struct ConvertibleContext { + template + operator T*() { + return static_cast(context); + } + void* context; }; - // A TypedThreadSafeFunction by default has no context (nullptr) and can - // accept any type (void) to its CallJs. - template - class TypedThreadSafeFunction { - public: - // This API may only be called from the main thread. - // Helper function that returns nullptr if running Node-API 5+, otherwise a - // non-empty, no-op Function. This provides the ability to specify at - // compile-time a callback parameter to `New` that safely does no action - // when targeting _any_ Node-API version. + // This API may be called from any thread. + ConvertibleContext GetContext() const; + + private: + using CallbackWrapper = std::function; + + template + static ThreadSafeFunction New(napi_env env, + const Function& callback, + const Object& resource, + ResourceString resourceName, + size_t maxQueueSize, + size_t initialThreadCount, + ContextType* context, + Finalizer finalizeCallback, + FinalizerDataType* data, + napi_finalize wrapper); + + napi_status CallInternal(CallbackWrapper* callbackWrapper, + napi_threadsafe_function_call_mode mode) const; + + static void CallJS(napi_env env, + napi_value jsCallback, + void* context, + void* data); + + napi_threadsafe_function _tsfn; +}; + +// A TypedThreadSafeFunction by default has no context (nullptr) and can +// accept any type (void) to its CallJs. +template +class TypedThreadSafeFunction { + public: + // This API may only be called from the main thread. + // Helper function that returns nullptr if running Node-API 5+, otherwise a + // non-empty, no-op Function. This provides the ability to specify at + // compile-time a callback parameter to `New` that safely does no action + // when targeting _any_ Node-API version. #if NAPI_VERSION > 4 - static std::nullptr_t EmptyFunctionFactory(Napi::Env env); + static std::nullptr_t EmptyFunctionFactory(Napi::Env env); #else - static Napi::Function EmptyFunctionFactory(Napi::Env env); + static Napi::Function EmptyFunctionFactory(Napi::Env env); #endif - static Napi::Function FunctionOrEmpty(Napi::Env env, - Napi::Function& callback); + static Napi::Function FunctionOrEmpty(Napi::Env env, + Napi::Function& callback); #if NAPI_VERSION > 4 - // This API may only be called from the main thread. - // Creates a new threadsafe function with: - // Callback [missing] Resource [missing] Finalizer [missing] - template - static TypedThreadSafeFunction New( - napi_env env, - ResourceString resourceName, - size_t maxQueueSize, - size_t initialThreadCount, - ContextType* context = nullptr); - - // This API may only be called from the main thread. - // Creates a new threadsafe function with: - // Callback [missing] Resource [passed] Finalizer [missing] - template - static TypedThreadSafeFunction New( - napi_env env, - const Object& resource, - ResourceString resourceName, - size_t maxQueueSize, - size_t initialThreadCount, - ContextType* context = nullptr); - - // This API may only be called from the main thread. - // Creates a new threadsafe function with: - // Callback [missing] Resource [missing] Finalizer [passed] - template - static TypedThreadSafeFunction New( - napi_env env, - ResourceString resourceName, - size_t maxQueueSize, - size_t initialThreadCount, - ContextType* context, - Finalizer finalizeCallback, - FinalizerDataType* data = nullptr); - - // This API may only be called from the main thread. - // Creates a new threadsafe function with: - // Callback [missing] Resource [passed] Finalizer [passed] - template - static TypedThreadSafeFunction New( - napi_env env, - const Object& resource, - ResourceString resourceName, - size_t maxQueueSize, - size_t initialThreadCount, - ContextType* context, - Finalizer finalizeCallback, - FinalizerDataType* data = nullptr); + // This API may only be called from the main thread. + // Creates a new threadsafe function with: + // Callback [missing] Resource [missing] Finalizer [missing] + template + static TypedThreadSafeFunction New( + napi_env env, + ResourceString resourceName, + size_t maxQueueSize, + size_t initialThreadCount, + ContextType* context = nullptr); + + // This API may only be called from the main thread. + // Creates a new threadsafe function with: + // Callback [missing] Resource [passed] Finalizer [missing] + template + static TypedThreadSafeFunction New( + napi_env env, + const Object& resource, + ResourceString resourceName, + size_t maxQueueSize, + size_t initialThreadCount, + ContextType* context = nullptr); + + // This API may only be called from the main thread. + // Creates a new threadsafe function with: + // Callback [missing] Resource [missing] Finalizer [passed] + template + static TypedThreadSafeFunction New( + napi_env env, + ResourceString resourceName, + size_t maxQueueSize, + size_t initialThreadCount, + ContextType* context, + Finalizer finalizeCallback, + FinalizerDataType* data = nullptr); + + // This API may only be called from the main thread. + // Creates a new threadsafe function with: + // Callback [missing] Resource [passed] Finalizer [passed] + template + static TypedThreadSafeFunction New( + napi_env env, + const Object& resource, + ResourceString resourceName, + size_t maxQueueSize, + size_t initialThreadCount, + ContextType* context, + Finalizer finalizeCallback, + FinalizerDataType* data = nullptr); #endif - // This API may only be called from the main thread. - // Creates a new threadsafe function with: - // Callback [passed] Resource [missing] Finalizer [missing] - template - static TypedThreadSafeFunction New( - napi_env env, - const Function& callback, - ResourceString resourceName, - size_t maxQueueSize, - size_t initialThreadCount, - ContextType* context = nullptr); - - // This API may only be called from the main thread. - // Creates a new threadsafe function with: - // Callback [passed] Resource [passed] Finalizer [missing] - template - static TypedThreadSafeFunction New( - napi_env env, - const Function& callback, - const Object& resource, - ResourceString resourceName, - size_t maxQueueSize, - size_t initialThreadCount, - ContextType* context = nullptr); - - // This API may only be called from the main thread. - // Creates a new threadsafe function with: - // Callback [passed] Resource [missing] Finalizer [passed] - template - static TypedThreadSafeFunction New( - napi_env env, - const Function& callback, - ResourceString resourceName, - size_t maxQueueSize, - size_t initialThreadCount, - ContextType* context, - Finalizer finalizeCallback, - FinalizerDataType* data = nullptr); - - // This API may only be called from the main thread. - // Creates a new threadsafe function with: - // Callback [passed] Resource [passed] Finalizer [passed] - template - static TypedThreadSafeFunction New( - napi_env env, - CallbackType callback, - const Object& resource, - ResourceString resourceName, - size_t maxQueueSize, - size_t initialThreadCount, - ContextType* context, - Finalizer finalizeCallback, - FinalizerDataType* data = nullptr); - - TypedThreadSafeFunction(); - TypedThreadSafeFunction(napi_threadsafe_function tsFunctionValue); - - operator napi_threadsafe_function() const; - - // This API may be called from any thread. - napi_status BlockingCall(DataType* data = nullptr) const; - - // This API may be called from any thread. - napi_status NonBlockingCall(DataType* data = nullptr) const; - - // This API may only be called from the main thread. - void Ref(napi_env env) const; - - // This API may only be called from the main thread. - void Unref(napi_env env) const; - - // This API may be called from any thread. - napi_status Acquire() const; - - // This API may be called from any thread. - napi_status Release() const; - - // This API may be called from any thread. - napi_status Abort() const; - - // This API may be called from any thread. - ContextType* GetContext() const; + // This API may only be called from the main thread. + // Creates a new threadsafe function with: + // Callback [passed] Resource [missing] Finalizer [missing] + template + static TypedThreadSafeFunction New( + napi_env env, + const Function& callback, + ResourceString resourceName, + size_t maxQueueSize, + size_t initialThreadCount, + ContextType* context = nullptr); + + // This API may only be called from the main thread. + // Creates a new threadsafe function with: + // Callback [passed] Resource [passed] Finalizer [missing] + template + static TypedThreadSafeFunction New( + napi_env env, + const Function& callback, + const Object& resource, + ResourceString resourceName, + size_t maxQueueSize, + size_t initialThreadCount, + ContextType* context = nullptr); + + // This API may only be called from the main thread. + // Creates a new threadsafe function with: + // Callback [passed] Resource [missing] Finalizer [passed] + template + static TypedThreadSafeFunction New( + napi_env env, + const Function& callback, + ResourceString resourceName, + size_t maxQueueSize, + size_t initialThreadCount, + ContextType* context, + Finalizer finalizeCallback, + FinalizerDataType* data = nullptr); + + // This API may only be called from the main thread. + // Creates a new threadsafe function with: + // Callback [passed] Resource [passed] Finalizer [passed] + template + static TypedThreadSafeFunction New( + napi_env env, + CallbackType callback, + const Object& resource, + ResourceString resourceName, + size_t maxQueueSize, + size_t initialThreadCount, + ContextType* context, + Finalizer finalizeCallback, + FinalizerDataType* data = nullptr); + + TypedThreadSafeFunction(); + TypedThreadSafeFunction(napi_threadsafe_function tsFunctionValue); + + operator napi_threadsafe_function() const; + + // This API may be called from any thread. + napi_status BlockingCall(DataType* data = nullptr) const; + + // This API may be called from any thread. + napi_status NonBlockingCall(DataType* data = nullptr) const; + + // This API may only be called from the main thread. + void Ref(napi_env env) const; + + // This API may only be called from the main thread. + void Unref(napi_env env) const; + + // This API may be called from any thread. + napi_status Acquire() const; + + // This API may be called from any thread. + napi_status Release() const; + + // This API may be called from any thread. + napi_status Abort() const; + + // This API may be called from any thread. + ContextType* GetContext() const; + + private: + template + static TypedThreadSafeFunction New( + napi_env env, + const Function& callback, + const Object& resource, + ResourceString resourceName, + size_t maxQueueSize, + size_t initialThreadCount, + ContextType* context, + Finalizer finalizeCallback, + FinalizerDataType* data, + napi_finalize wrapper); + + static void CallJsInternal(napi_env env, + napi_value jsCallback, + void* context, + void* data); + + protected: + napi_threadsafe_function _tsfn; +}; +template +class AsyncProgressWorkerBase : public AsyncWorker { + public: + virtual void OnWorkProgress(DataType* data) = 0; + class ThreadSafeData { + public: + ThreadSafeData(AsyncProgressWorkerBase* asyncprogressworker, DataType* data) + : _asyncprogressworker(asyncprogressworker), _data(data) {} + + AsyncProgressWorkerBase* asyncprogressworker() { + return _asyncprogressworker; + }; + DataType* data() { return _data; }; private: - template - static TypedThreadSafeFunction New( - napi_env env, - const Function& callback, - const Object& resource, - ResourceString resourceName, - size_t maxQueueSize, - size_t initialThreadCount, - ContextType* context, - Finalizer finalizeCallback, - FinalizerDataType* data, - napi_finalize wrapper); - - static void CallJsInternal(napi_env env, - napi_value jsCallback, - void* context, - void* data); - - protected: - napi_threadsafe_function _tsfn; + AsyncProgressWorkerBase* _asyncprogressworker; + DataType* _data; }; - template - class AsyncProgressWorkerBase : public AsyncWorker { - public: - virtual void OnWorkProgress(DataType* data) = 0; - class ThreadSafeData { - public: - ThreadSafeData(AsyncProgressWorkerBase* asyncprogressworker, DataType* data) - : _asyncprogressworker(asyncprogressworker), _data(data) {} - - AsyncProgressWorkerBase* asyncprogressworker() { return _asyncprogressworker; }; - DataType* data() { return _data; }; - - private: - AsyncProgressWorkerBase* _asyncprogressworker; - DataType* _data; - }; - void OnWorkComplete(Napi::Env env, napi_status status) override; - protected: - explicit AsyncProgressWorkerBase(const Object& receiver, - const Function& callback, - const char* resource_name, - const Object& resource, - size_t queue_size = 1); - virtual ~AsyncProgressWorkerBase(); - -// Optional callback of Napi::ThreadSafeFunction only available after NAPI_VERSION 4. -// Refs: https://github.com/nodejs/node/pull/27791 + void OnWorkComplete(Napi::Env env, napi_status status) override; + + protected: + explicit AsyncProgressWorkerBase(const Object& receiver, + const Function& callback, + const char* resource_name, + const Object& resource, + size_t queue_size = 1); + virtual ~AsyncProgressWorkerBase(); + +// Optional callback of Napi::ThreadSafeFunction only available after +// NAPI_VERSION 4. Refs: https://github.com/nodejs/node/pull/27791 #if NAPI_VERSION > 4 - explicit AsyncProgressWorkerBase(Napi::Env env, - const char* resource_name, - const Object& resource, - size_t queue_size = 1); + explicit AsyncProgressWorkerBase(Napi::Env env, + const char* resource_name, + const Object& resource, + size_t queue_size = 1); #endif - static inline void OnAsyncWorkProgress(Napi::Env env, - Napi::Function jsCallback, - void* data); + static inline void OnAsyncWorkProgress(Napi::Env env, + Napi::Function jsCallback, + void* data); - napi_status NonBlockingCall(DataType* data); + napi_status NonBlockingCall(DataType* data); - private: - ThreadSafeFunction _tsfn; - bool _work_completed = false; - napi_status _complete_status; - static inline void OnThreadSafeFunctionFinalize(Napi::Env env, void* data, AsyncProgressWorkerBase* context); - }; + private: + ThreadSafeFunction _tsfn; + bool _work_completed = false; + napi_status _complete_status; + static inline void OnThreadSafeFunctionFinalize( + Napi::Env env, void* data, AsyncProgressWorkerBase* context); +}; - template - class AsyncProgressWorker : public AsyncProgressWorkerBase { - public: - virtual ~AsyncProgressWorker(); - - class ExecutionProgress { - friend class AsyncProgressWorker; - public: - void Signal() const; - void Send(const T* data, size_t count) const; - private: - explicit ExecutionProgress(AsyncProgressWorker* worker) : _worker(worker) {} - AsyncProgressWorker* const _worker; - }; - - void OnWorkProgress(void*) override; - - protected: - explicit AsyncProgressWorker(const Function& callback); - explicit AsyncProgressWorker(const Function& callback, - const char* resource_name); - explicit AsyncProgressWorker(const Function& callback, - const char* resource_name, - const Object& resource); - explicit AsyncProgressWorker(const Object& receiver, - const Function& callback); - explicit AsyncProgressWorker(const Object& receiver, - const Function& callback, - const char* resource_name); - explicit AsyncProgressWorker(const Object& receiver, - const Function& callback, - const char* resource_name, - const Object& resource); - -// Optional callback of Napi::ThreadSafeFunction only available after NAPI_VERSION 4. -// Refs: https://github.com/nodejs/node/pull/27791 -#if NAPI_VERSION > 4 - explicit AsyncProgressWorker(Napi::Env env); - explicit AsyncProgressWorker(Napi::Env env, - const char* resource_name); - explicit AsyncProgressWorker(Napi::Env env, - const char* resource_name, - const Object& resource); -#endif - virtual void Execute(const ExecutionProgress& progress) = 0; - virtual void OnProgress(const T* data, size_t count) = 0; +template +class AsyncProgressWorker : public AsyncProgressWorkerBase { + public: + virtual ~AsyncProgressWorker(); - private: - void Execute() override; - void Signal() const; - void SendProgress_(const T* data, size_t count); + class ExecutionProgress { + friend class AsyncProgressWorker; - std::mutex _mutex; - T* _asyncdata; - size_t _asyncsize; + public: + void Signal() const; + void Send(const T* data, size_t count) const; + + private: + explicit ExecutionProgress(AsyncProgressWorker* worker) : _worker(worker) {} + AsyncProgressWorker* const _worker; }; - template - class AsyncProgressQueueWorker : public AsyncProgressWorkerBase> { - public: - virtual ~AsyncProgressQueueWorker() {}; - - class ExecutionProgress { - friend class AsyncProgressQueueWorker; - public: - void Signal() const; - void Send(const T* data, size_t count) const; - private: - explicit ExecutionProgress(AsyncProgressQueueWorker* worker) : _worker(worker) {} - AsyncProgressQueueWorker* const _worker; - }; - - void OnWorkComplete(Napi::Env env, napi_status status) override; - void OnWorkProgress(std::pair*) override; - - protected: - explicit AsyncProgressQueueWorker(const Function& callback); - explicit AsyncProgressQueueWorker(const Function& callback, - const char* resource_name); - explicit AsyncProgressQueueWorker(const Function& callback, - const char* resource_name, - const Object& resource); - explicit AsyncProgressQueueWorker(const Object& receiver, - const Function& callback); - explicit AsyncProgressQueueWorker(const Object& receiver, - const Function& callback, - const char* resource_name); - explicit AsyncProgressQueueWorker(const Object& receiver, - const Function& callback, - const char* resource_name, - const Object& resource); - -// Optional callback of Napi::ThreadSafeFunction only available after NAPI_VERSION 4. -// Refs: https://github.com/nodejs/node/pull/27791 + void OnWorkProgress(void*) override; + + protected: + explicit AsyncProgressWorker(const Function& callback); + explicit AsyncProgressWorker(const Function& callback, + const char* resource_name); + explicit AsyncProgressWorker(const Function& callback, + const char* resource_name, + const Object& resource); + explicit AsyncProgressWorker(const Object& receiver, + const Function& callback); + explicit AsyncProgressWorker(const Object& receiver, + const Function& callback, + const char* resource_name); + explicit AsyncProgressWorker(const Object& receiver, + const Function& callback, + const char* resource_name, + const Object& resource); + +// Optional callback of Napi::ThreadSafeFunction only available after +// NAPI_VERSION 4. Refs: https://github.com/nodejs/node/pull/27791 #if NAPI_VERSION > 4 - explicit AsyncProgressQueueWorker(Napi::Env env); - explicit AsyncProgressQueueWorker(Napi::Env env, - const char* resource_name); - explicit AsyncProgressQueueWorker(Napi::Env env, - const char* resource_name, - const Object& resource); + explicit AsyncProgressWorker(Napi::Env env); + explicit AsyncProgressWorker(Napi::Env env, const char* resource_name); + explicit AsyncProgressWorker(Napi::Env env, + const char* resource_name, + const Object& resource); #endif - virtual void Execute(const ExecutionProgress& progress) = 0; - virtual void OnProgress(const T* data, size_t count) = 0; + virtual void Execute(const ExecutionProgress& progress) = 0; + virtual void OnProgress(const T* data, size_t count) = 0; - private: - void Execute() override; - void Signal() const; - void SendProgress_(const T* data, size_t count); - }; - #endif // NAPI_VERSION > 3 && !defined(__wasm32__) + private: + void Execute() override; + void Signal(); + void SendProgress_(const T* data, size_t count); - // Memory management. - class MemoryManagement { - public: - static int64_t AdjustExternalMemory(Env env, int64_t change_in_bytes); - }; + std::mutex _mutex; + T* _asyncdata; + size_t _asyncsize; + bool _signaled; +}; - // Version management - class VersionManagement { - public: - static uint32_t GetNapiVersion(Env env); - static const napi_node_version* GetNodeVersion(Env env); - }; +template +class AsyncProgressQueueWorker + : public AsyncProgressWorkerBase> { + public: + virtual ~AsyncProgressQueueWorker(){}; -#if NAPI_VERSION > 5 - template - class Addon : public InstanceWrap { - public: - static inline Object Init(Env env, Object exports); - static T* Unwrap(Object wrapper); + class ExecutionProgress { + friend class AsyncProgressQueueWorker; - protected: - using AddonProp = ClassPropertyDescriptor; - void DefineAddon(Object exports, - const std::initializer_list& props); - Napi::Object DefineProperties(Object object, - const std::initializer_list& props); + public: + void Signal() const; + void Send(const T* data, size_t count) const; private: - Object entry_point_; + explicit ExecutionProgress(AsyncProgressQueueWorker* worker) + : _worker(worker) {} + AsyncProgressQueueWorker* const _worker; }; + + void OnWorkComplete(Napi::Env env, napi_status status) override; + void OnWorkProgress(std::pair*) override; + + protected: + explicit AsyncProgressQueueWorker(const Function& callback); + explicit AsyncProgressQueueWorker(const Function& callback, + const char* resource_name); + explicit AsyncProgressQueueWorker(const Function& callback, + const char* resource_name, + const Object& resource); + explicit AsyncProgressQueueWorker(const Object& receiver, + const Function& callback); + explicit AsyncProgressQueueWorker(const Object& receiver, + const Function& callback, + const char* resource_name); + explicit AsyncProgressQueueWorker(const Object& receiver, + const Function& callback, + const char* resource_name, + const Object& resource); + +// Optional callback of Napi::ThreadSafeFunction only available after +// NAPI_VERSION 4. Refs: https://github.com/nodejs/node/pull/27791 +#if NAPI_VERSION > 4 + explicit AsyncProgressQueueWorker(Napi::Env env); + explicit AsyncProgressQueueWorker(Napi::Env env, const char* resource_name); + explicit AsyncProgressQueueWorker(Napi::Env env, + const char* resource_name, + const Object& resource); +#endif + virtual void Execute(const ExecutionProgress& progress) = 0; + virtual void OnProgress(const T* data, size_t count) = 0; + + private: + void Execute() override; + void Signal() const; + void SendProgress_(const T* data, size_t count); +}; +#endif // NAPI_VERSION > 3 && !defined(__wasm32__) + +// Memory management. +class MemoryManagement { + public: + static int64_t AdjustExternalMemory(Env env, int64_t change_in_bytes); +}; + +// Version management +class VersionManagement { + public: + static uint32_t GetNapiVersion(Env env); + static const napi_node_version* GetNodeVersion(Env env); +}; + +#if NAPI_VERSION > 5 +template +class Addon : public InstanceWrap { + public: + static inline Object Init(Env env, Object exports); + static T* Unwrap(Object wrapper); + + protected: + using AddonProp = ClassPropertyDescriptor; + void DefineAddon(Object exports, + const std::initializer_list& props); + Napi::Object DefineProperties(Object object, + const std::initializer_list& props); + + private: + Object entry_point_; +}; #endif // NAPI_VERSION > 5 #ifdef NAPI_CPP_CUSTOM_NAMESPACE - } // namespace NAPI_CPP_CUSTOM_NAMESPACE +} // namespace NAPI_CPP_CUSTOM_NAMESPACE #endif -} // namespace Napi +} // namespace Napi // Inline implementations of all the above class methods are included here. #include "napi-inl.h" -#endif // SRC_NAPI_H_ +#endif // SRC_NAPI_H_ diff --git a/node_modules/node-addon-api/package.json b/node_modules/node-addon-api/package.json index cd491862..3ec3776e 100644 --- a/node_modules/node-addon-api/package.json +++ b/node_modules/node-addon-api/package.json @@ -15,6 +15,10 @@ "name": "Alexander Floh", "url": "https://github.com/alexanderfloh" }, + { + "name": "Ammar Faizi", + "url": "https://github.com/ammarfaizi2" + }, { "name": "András Timár, Dr", "url": "https://github.com/timarandras" @@ -71,6 +75,10 @@ "name": "Daniel Bevenius", "url": "https://github.com/danbev" }, + { + "name": "Dante Calderón", + "url": "https://github.com/dantehemerson" + }, { "name": "Darshan Sen", "url": "https://github.com/RaisinTen" @@ -103,6 +111,10 @@ "name": "extremeheat", "url": "https://github.com/extremeheat" }, + { + "name": "Feng Yu", + "url": "https://github.com/F3n67u" + }, { "name": "Ferdinand Holzer", "url": "https://github.com/fholzer" @@ -147,6 +159,10 @@ "name": "Jason Ginchereau", "url": "https://github.com/jasongin" }, + { + "name": "Jenny", + "url": "https://github.com/egg-bread" + }, { "name": "Jeroen Janssen", "url": "https://github.com/japj" @@ -167,6 +183,10 @@ "name": "joshgarde", "url": "https://github.com/joshgarde" }, + { + "name": "Julian Mesa", + "url": "https://github.com/julianmesa-gitkraken" + }, { "name": "Kasumi Hanazuki", "url": "https://github.com/hanazuki" @@ -199,6 +219,10 @@ "name": "Kyle Farnung", "url": "https://github.com/kfarnung" }, + { + "name": "Kyle Kovacs", + "url": "https://github.com/nullromo" + }, { "name": "legendecas", "url": "https://github.com/legendecas" @@ -267,6 +291,10 @@ "name": "pacop", "url": "https://github.com/pacop" }, + { + "name": "Peter Šándor", + "url": "https://github.com/petersandor" + }, { "name": "Philipp Renoth", "url": "https://github.com/DaAitch" @@ -275,6 +303,10 @@ "name": "rgerd", "url": "https://github.com/rgerd" }, + { + "name": "Richard Lau", + "url": "https://github.com/richardlau" + }, { "name": "Rolf Timmermans", "url": "https://github.com/rolftimmermans" @@ -287,6 +319,10 @@ "name": "Ryuichi Okumura", "url": "https://github.com/okuryu" }, + { + "name": "Saint Gabriel", + "url": "https://github.com/chineduG" + }, { "name": "Sampson Gao", "url": "https://github.com/sampsongao" @@ -351,6 +387,10 @@ { "name": "Ziqiu Zhao", "url": "https://github.com/ZzqiZQute" + }, + { + "name": "Feng Yu", + "url": "https://github.com/F3n67u" } ], "description": "Node.js API (Node-API)", @@ -401,6 +441,7 @@ "benchmark": "node benchmark", "pretest": "node-gyp rebuild -C test", "test": "node test", + "test:debug": "node-gyp rebuild -C test --debug && NODE_API_BUILD_CONFIG=Debug node ./test/index.js", "predev": "node-gyp rebuild -C test --debug", "dev": "node test", "predev:incremental": "node-gyp configure build -C test --debug", @@ -410,6 +451,6 @@ "lint:fix": "node tools/clang-format --fix && node tools/eslint-format --fix" }, "pre-commit": "lint", - "version": "5.0.0", + "version": "5.1.0", "support": true } diff --git a/node_modules/node-addon-api/tools/check-napi.js b/node_modules/node-addon-api/tools/check-napi.js index 48fdfc07..9199af33 100644 --- a/node_modules/node-addon-api/tools/check-napi.js +++ b/node_modules/node-addon-api/tools/check-napi.js @@ -4,16 +4,15 @@ const fs = require('fs'); const path = require('path'); -const child_process = require('child_process'); // Read the output of the command, break it into lines, and use the reducer to // decide whether the file is an N-API module or not. -function checkFile(file, command, argv, reducer) { - const child = child_process.spawn(command, argv, { +function checkFile (file, command, argv, reducer) { + const child = require('child_process').spawn(command, argv, { stdio: ['inherit', 'pipe', 'inherit'] }); let leftover = ''; - let isNapi = undefined; + let isNapi; child.stdout.on('data', (chunk) => { if (isNapi === undefined) { chunk = (leftover + chunk.toString()).split(/[\r\n]+/); @@ -27,11 +26,11 @@ function checkFile(file, command, argv, reducer) { child.on('close', (code, signal) => { if ((code === null && signal !== null) || (code !== 0)) { console.log( - command + ' exited with code: ' + code + ' and signal: ' + signal); + command + ' exited with code: ' + code + ' and signal: ' + signal); } else { // Green if it's a N-API module, red otherwise. console.log( - '\x1b[' + (isNapi ? '42' : '41') + 'm' + + '\x1b[' + (isNapi ? '42' : '41') + 'm' + (isNapi ? ' N-API' : 'Not N-API') + '\x1b[0m: ' + file); } @@ -39,7 +38,7 @@ function checkFile(file, command, argv, reducer) { } // Use nm -a to list symbols. -function checkFileUNIX(file) { +function checkFileUNIX (file) { checkFile(file, 'nm', ['-a', file], (soFar, line) => { if (soFar === undefined) { line = line.match(/([0-9a-f]*)? ([a-zA-Z]) (.*$)/); @@ -54,7 +53,7 @@ function checkFileUNIX(file) { } // Use dumpbin /imports to list symbols. -function checkFileWin32(file) { +function checkFileWin32 (file) { checkFile(file, 'dumpbin', ['/imports', file], (soFar, line) => { if (soFar === undefined) { line = line.match(/([0-9a-f]*)? +([a-zA-Z0-9]) (.*$)/); @@ -68,16 +67,16 @@ function checkFileWin32(file) { // Descend into a directory structure and pass each file ending in '.node' to // one of the above checks, depending on the OS. -function recurse(top) { +function recurse (top) { fs.readdir(top, (error, items) => { if (error) { - throw ("error reading directory " + top + ": " + error); + throw new Error('error reading directory ' + top + ': ' + error); } items.forEach((item) => { item = path.join(top, item); fs.stat(item, ((item) => (error, stats) => { if (error) { - throw ("error about " + item + ": " + error); + throw new Error('error about ' + item + ': ' + error); } if (stats.isDirectory()) { recurse(item); @@ -86,9 +85,9 @@ function recurse(top) { // artefacts of node-addon-api having identified a version of // Node.js that ships with a correct implementation of N-API. path.basename(item) !== 'nothing.node') { - process.platform === 'win32' ? - checkFileWin32(item) : - checkFileUNIX(item); + process.platform === 'win32' + ? checkFileWin32(item) + : checkFileUNIX(item); } })(item)); }); diff --git a/node_modules/node-addon-api/tools/conversion.js b/node_modules/node-addon-api/tools/conversion.js index 5aef2c3f..f89245ac 100755 --- a/node_modules/node-addon-api/tools/conversion.js +++ b/node_modules/node-addon-api/tools/conversion.js @@ -1,6 +1,6 @@ #! /usr/bin/env node -'use strict' +'use strict'; const fs = require('fs'); const path = require('path'); @@ -15,255 +15,247 @@ if (!dir) { const NodeApiVersion = require('../package.json').version; const disable = args[1]; -if (disable != "--disable" && dir != "--disable") { - var ConfigFileOperations = { +let ConfigFileOperations; +if (disable !== '--disable' && dir !== '--disable') { + ConfigFileOperations = { 'package.json': [ - [ /([ ]*)"dependencies": {/g, '$1"dependencies": {\n$1 "node-addon-api": "' + NodeApiVersion + '",'], - [ /[ ]*"nan": *"[^"]+"(,|)[\n\r]/g, '' ] + [/([ ]*)"dependencies": {/g, '$1"dependencies": {\n$1 "node-addon-api": "' + NodeApiVersion + '",'], + [/[ ]*"nan": *"[^"]+"(,|)[\n\r]/g, ''] ], 'binding.gyp': [ - [ /([ ]*)'include_dirs': \[/g, '$1\'include_dirs\': [\n$1 \'\s+(\w+)\s*=\s*Nan::New\([\w\d:]+\);(?:\w+->Reset\(\1\))?\s+\1->SetClassName\(Nan::String::New\("(\w+)"\)\);/g, 'Napi::Function $1 = DefineClass(env, "$2", {' ], - [ /Local\s+(\w+)\s*=\s*Nan::New\([\w\d:]+\);\s+(\w+)\.Reset\((\1)\);\s+\1->SetClassName\((Nan::String::New|Nan::New<(v8::)*String>)\("(.+?)"\)\);/g, 'Napi::Function $1 = DefineClass(env, "$6", {'], - [ /Local\s+(\w+)\s*=\s*Nan::New\([\w\d:]+\);(?:\w+->Reset\(\1\))?\s+\1->SetClassName\(Nan::String::New\("(\w+)"\)\);/g, 'Napi::Function $1 = DefineClass(env, "$2", {' ], - [ /Nan::New\(([\w\d:]+)\)->GetFunction\(\)/g, 'Napi::Function::New(env, $1)' ], - [ /Nan::New\(([\w\d:]+)\)->GetFunction()/g, 'Napi::Function::New(env, $1);' ], - [ /Nan::New\(([\w\d:]+)\)/g, 'Napi::Function::New(env, $1)' ], - [ /Nan::New\(([\w\d:]+)\)/g, 'Napi::Function::New(env, $1)' ], + [/v8::Local\s+(\w+)\s*=\s*Nan::New\([\w\d:]+\);(?:\w+->Reset\(\1\))?\s+\1->SetClassName\(Nan::String::New\("(\w+)"\)\);/g, 'Napi::Function $1 = DefineClass(env, "$2", {'], + [/Local\s+(\w+)\s*=\s*Nan::New\([\w\d:]+\);\s+(\w+)\.Reset\((\1)\);\s+\1->SetClassName\((Nan::String::New|Nan::New<(v8::)*String>)\("(.+?)"\)\);/g, 'Napi::Function $1 = DefineClass(env, "$6", {'], + [/Local\s+(\w+)\s*=\s*Nan::New\([\w\d:]+\);(?:\w+->Reset\(\1\))?\s+\1->SetClassName\(Nan::String::New\("(\w+)"\)\);/g, 'Napi::Function $1 = DefineClass(env, "$2", {'], + [/Nan::New\(([\w\d:]+)\)->GetFunction\(\)/g, 'Napi::Function::New(env, $1)'], + [/Nan::New\(([\w\d:]+)\)->GetFunction()/g, 'Napi::Function::New(env, $1);'], + [/Nan::New\(([\w\d:]+)\)/g, 'Napi::Function::New(env, $1)'], + [/Nan::New\(([\w\d:]+)\)/g, 'Napi::Function::New(env, $1)'], // FunctionTemplate to FunctionReference - [ /Nan::Persistent<(v8::)*FunctionTemplate>/g, 'Napi::FunctionReference' ], - [ /Nan::Persistent<(v8::)*Function>/g, 'Napi::FunctionReference' ], - [ /v8::Local/g, 'Napi::FunctionReference' ], - [ /Local/g, 'Napi::FunctionReference' ], - [ /v8::FunctionTemplate/g, 'Napi::FunctionReference' ], - [ /FunctionTemplate/g, 'Napi::FunctionReference' ], - - - [ /([ ]*)Nan::SetPrototypeMethod\(\w+, "(\w+)", (\w+)\);/g, '$1InstanceMethod("$2", &$3),' ], - [ /([ ]*)(?:\w+\.Reset\(\w+\);\s+)?\(target\)\.Set\("(\w+)",\s*Nan::GetFunction\((\w+)\)\);/gm, + [/Nan::Persistent<(v8::)*FunctionTemplate>/g, 'Napi::FunctionReference'], + [/Nan::Persistent<(v8::)*Function>/g, 'Napi::FunctionReference'], + [/v8::Local/g, 'Napi::FunctionReference'], + [/Local/g, 'Napi::FunctionReference'], + [/v8::FunctionTemplate/g, 'Napi::FunctionReference'], + [/FunctionTemplate/g, 'Napi::FunctionReference'], + + [/([ ]*)Nan::SetPrototypeMethod\(\w+, "(\w+)", (\w+)\);/g, '$1InstanceMethod("$2", &$3),'], + [/([ ]*)(?:\w+\.Reset\(\w+\);\s+)?\(target\)\.Set\("(\w+)",\s*Nan::GetFunction\((\w+)\)\);/gm, '});\n\n' + '$1constructor = Napi::Persistent($3);\n' + '$1constructor.SuppressDestruct();\n' + - '$1target.Set("$2", $3);' ], - + '$1target.Set("$2", $3);'], // TODO: Other attribute combinations - [ /static_cast\(ReadOnly\s*\|\s*DontDelete\)/gm, - 'static_cast(napi_enumerable | napi_configurable)' ], + [/static_cast\(ReadOnly\s*\|\s*DontDelete\)/gm, + 'static_cast(napi_enumerable | napi_configurable)'], - [ /([\w\d:<>]+?)::Cast\((.+?)\)/g, '$2.As<$1>()' ], + [/([\w\d:<>]+?)::Cast\((.+?)\)/g, '$2.As<$1>()'], - [ /\*Nan::Utf8String\(([^)]+)\)/g, '$1->As().Utf8Value().c_str()' ], - [ /Nan::Utf8String +(\w+)\(([^)]+)\)/g, 'std::string $1 = $2.As()' ], - [ /Nan::Utf8String/g, 'std::string' ], + [/\*Nan::Utf8String\(([^)]+)\)/g, '$1->As().Utf8Value().c_str()'], + [/Nan::Utf8String +(\w+)\(([^)]+)\)/g, 'std::string $1 = $2.As()'], + [/Nan::Utf8String/g, 'std::string'], - [ /v8::String::Utf8Value (.+?)\((.+?)\)/g, 'Napi::String $1(env, $2)' ], - [ /String::Utf8Value (.+?)\((.+?)\)/g, 'Napi::String $1(env, $2)' ], - [ /\.length\(\)/g, '.Length()' ], + [/v8::String::Utf8Value (.+?)\((.+?)\)/g, 'Napi::String $1(env, $2)'], + [/String::Utf8Value (.+?)\((.+?)\)/g, 'Napi::String $1(env, $2)'], + [/\.length\(\)/g, '.Length()'], - [ /Nan::MakeCallback\(([^,]+),[\s\\]+([^,]+),/gm, '$2.MakeCallback($1,' ], + [/Nan::MakeCallback\(([^,]+),[\s\\]+([^,]+),/gm, '$2.MakeCallback($1,'], - [ /class\s+(\w+)\s*:\s*public\s+Nan::ObjectWrap/g, 'class $1 : public Napi::ObjectWrap<$1>' ], - [ /(\w+)\(([^\)]*)\)\s*:\s*Nan::ObjectWrap\(\)\s*(,)?/gm, '$1($2) : Napi::ObjectWrap<$1>()$3' ], + [/class\s+(\w+)\s*:\s*public\s+Nan::ObjectWrap/g, 'class $1 : public Napi::ObjectWrap<$1>'], + [/(\w+)\(([^)]*)\)\s*:\s*Nan::ObjectWrap\(\)\s*(,)?/gm, '$1($2) : Napi::ObjectWrap<$1>()$3'], // HandleOKCallback to OnOK - [ /HandleOKCallback/g, 'OnOK' ], + [/HandleOKCallback/g, 'OnOK'], // HandleErrorCallback to OnError - [ /HandleErrorCallback/g, 'OnError' ], + [/HandleErrorCallback/g, 'OnError'], // ex. .As() to .As() - [ /\.As\(\)/g, '.As()' ], - [ /\.As<(Value|Boolean|String|Number|Object|Array|Symbol|External|Function)>\(\)/g, '.As()' ], + [/\.As\(\)/g, '.As()'], + [/\.As<(Value|Boolean|String|Number|Object|Array|Symbol|External|Function)>\(\)/g, '.As()'], // ex. Nan::New(info[0]) to Napi::Number::New(info[0]) - [ /Nan::New<(v8::)*Integer>\((.+?)\)/g, 'Napi::Number::New(env, $2)' ], - [ /Nan::New\(([0-9\.]+)\)/g, 'Napi::Number::New(env, $1)' ], - [ /Nan::New<(v8::)*String>\("(.+?)"\)/g, 'Napi::String::New(env, "$2")' ], - [ /Nan::New\("(.+?)"\)/g, 'Napi::String::New(env, "$1")' ], - [ /Nan::New<(v8::)*(.+?)>\(\)/g, 'Napi::$2::New(env)' ], - [ /Nan::New<(.+?)>\(\)/g, 'Napi::$1::New(env)' ], - [ /Nan::New<(v8::)*(.+?)>\(/g, 'Napi::$2::New(env, ' ], - [ /Nan::New<(.+?)>\(/g, 'Napi::$1::New(env, ' ], - [ /Nan::NewBuffer\(/g, 'Napi::Buffer::New(env, ' ], + [/Nan::New<(v8::)*Integer>\((.+?)\)/g, 'Napi::Number::New(env, $2)'], + [/Nan::New\(([0-9.]+)\)/g, 'Napi::Number::New(env, $1)'], + [/Nan::New<(v8::)*String>\("(.+?)"\)/g, 'Napi::String::New(env, "$2")'], + [/Nan::New\("(.+?)"\)/g, 'Napi::String::New(env, "$1")'], + [/Nan::New<(v8::)*(.+?)>\(\)/g, 'Napi::$2::New(env)'], + [/Nan::New<(.+?)>\(\)/g, 'Napi::$1::New(env)'], + [/Nan::New<(v8::)*(.+?)>\(/g, 'Napi::$2::New(env, '], + [/Nan::New<(.+?)>\(/g, 'Napi::$1::New(env, '], + [/Nan::NewBuffer\(/g, 'Napi::Buffer::New(env, '], // TODO: Properly handle this - [ /Nan::New\(/g, 'Napi::New(env, ' ], + [/Nan::New\(/g, 'Napi::New(env, '], - [ /\.IsInt32\(\)/g, '.IsNumber()' ], - [ /->IsInt32\(\)/g, '.IsNumber()' ], + [/\.IsInt32\(\)/g, '.IsNumber()'], + [/->IsInt32\(\)/g, '.IsNumber()'], - - [ /(.+?)->BooleanValue\(\)/g, '$1.As().Value()' ], - [ /(.+?)->Int32Value\(\)/g, '$1.As().Int32Value()' ], - [ /(.+?)->Uint32Value\(\)/g, '$1.As().Uint32Value()' ], - [ /(.+?)->IntegerValue\(\)/g, '$1.As().Int64Value()' ], - [ /(.+?)->NumberValue\(\)/g, '$1.As().DoubleValue()' ], + [/(.+?)->BooleanValue\(\)/g, '$1.As().Value()'], + [/(.+?)->Int32Value\(\)/g, '$1.As().Int32Value()'], + [/(.+?)->Uint32Value\(\)/g, '$1.As().Uint32Value()'], + [/(.+?)->IntegerValue\(\)/g, '$1.As().Int64Value()'], + [/(.+?)->NumberValue\(\)/g, '$1.As().DoubleValue()'], // ex. Nan::To(info[0]) to info[0].Value() - [ /Nan::To\((.+?)\)/g, '$2.To()' ], - [ /Nan::To<(Boolean|String|Number|Object|Array|Symbol|Function)>\((.+?)\)/g, '$2.To()' ], + [/Nan::To\((.+?)\)/g, '$2.To()'], + [/Nan::To<(Boolean|String|Number|Object|Array|Symbol|Function)>\((.+?)\)/g, '$2.To()'], // ex. Nan::To(info[0]) to info[0].As().Value() - [ /Nan::To\((.+?)\)/g, '$1.As().Value()' ], + [/Nan::To\((.+?)\)/g, '$1.As().Value()'], // ex. Nan::To(info[0]) to info[0].As().Int32Value() - [ /Nan::To\((.+?)\)/g, '$1.As().Int32Value()' ], + [/Nan::To\((.+?)\)/g, '$1.As().Int32Value()'], // ex. Nan::To(info[0]) to info[0].As().Int32Value() - [ /Nan::To\((.+?)\)/g, '$1.As().Int32Value()' ], + [/Nan::To\((.+?)\)/g, '$1.As().Int32Value()'], // ex. Nan::To(info[0]) to info[0].As().Uint32Value() - [ /Nan::To\((.+?)\)/g, '$1.As().Uint32Value()' ], + [/Nan::To\((.+?)\)/g, '$1.As().Uint32Value()'], // ex. Nan::To(info[0]) to info[0].As().Int64Value() - [ /Nan::To\((.+?)\)/g, '$1.As().Int64Value()' ], + [/Nan::To\((.+?)\)/g, '$1.As().Int64Value()'], // ex. Nan::To(info[0]) to info[0].As().FloatValue() - [ /Nan::To\((.+?)\)/g, '$1.As().FloatValue()' ], + [/Nan::To\((.+?)\)/g, '$1.As().FloatValue()'], // ex. Nan::To(info[0]) to info[0].As().DoubleValue() - [ /Nan::To\((.+?)\)/g, '$1.As().DoubleValue()' ], - - [ /Nan::New\((\w+)\)->HasInstance\((\w+)\)/g, '$2.InstanceOf($1.Value())' ], + [/Nan::To\((.+?)\)/g, '$1.As().DoubleValue()'], - [ /Nan::Has\(([^,]+),\s*/gm, '($1).Has(' ], - [ /\.Has\([\s|\\]*Nan::New<(v8::)*String>\(([^)]+)\)\)/gm, '.Has($1)' ], - [ /\.Has\([\s|\\]*Nan::New\(([^)]+)\)\)/gm, '.Has($1)' ], + [/Nan::New\((\w+)\)->HasInstance\((\w+)\)/g, '$2.InstanceOf($1.Value())'], - [ /Nan::Get\(([^,]+),\s*/gm, '($1).Get(' ], - [ /\.Get\([\s|\\]*Nan::New<(v8::)*String>\(([^)]+)\)\)/gm, '.Get($1)' ], - [ /\.Get\([\s|\\]*Nan::New\(([^)]+)\)\)/gm, '.Get($1)' ], + [/Nan::Has\(([^,]+),\s*/gm, '($1).Has('], + [/\.Has\([\s|\\]*Nan::New<(v8::)*String>\(([^)]+)\)\)/gm, '.Has($1)'], + [/\.Has\([\s|\\]*Nan::New\(([^)]+)\)\)/gm, '.Has($1)'], - [ /Nan::Set\(([^,]+),\s*/gm, '($1).Set(' ], - [ /\.Set\([\s|\\]*Nan::New<(v8::)*String>\(([^)]+)\)\s*,/gm, '.Set($1,' ], - [ /\.Set\([\s|\\]*Nan::New\(([^)]+)\)\s*,/gm, '.Set($1,' ], + [/Nan::Get\(([^,]+),\s*/gm, '($1).Get('], + [/\.Get\([\s|\\]*Nan::New<(v8::)*String>\(([^)]+)\)\)/gm, '.Get($1)'], + [/\.Get\([\s|\\]*Nan::New\(([^)]+)\)\)/gm, '.Get($1)'], + [/Nan::Set\(([^,]+),\s*/gm, '($1).Set('], + [/\.Set\([\s|\\]*Nan::New<(v8::)*String>\(([^)]+)\)\s*,/gm, '.Set($1,'], + [/\.Set\([\s|\\]*Nan::New\(([^)]+)\)\s*,/gm, '.Set($1,'], // ex. node::Buffer::HasInstance(info[0]) to info[0].IsBuffer() - [ /node::Buffer::HasInstance\((.+?)\)/g, '$1.IsBuffer()' ], + [/node::Buffer::HasInstance\((.+?)\)/g, '$1.IsBuffer()'], // ex. node::Buffer::Length(info[0]) to info[0].Length() - [ /node::Buffer::Length\((.+?)\)/g, '$1.As>().Length()' ], + [/node::Buffer::Length\((.+?)\)/g, '$1.As>().Length()'], // ex. node::Buffer::Data(info[0]) to info[0].Data() - [ /node::Buffer::Data\((.+?)\)/g, '$1.As>().Data()' ], - [ /Nan::CopyBuffer\(/g, 'Napi::Buffer::Copy(env, ' ], + [/node::Buffer::Data\((.+?)\)/g, '$1.As>().Data()'], + [/Nan::CopyBuffer\(/g, 'Napi::Buffer::Copy(env, '], // Nan::AsyncQueueWorker(worker) - [ /Nan::AsyncQueueWorker\((.+)\);/g, '$1.Queue();' ], - [ /Nan::(Undefined|Null|True|False)\(\)/g, 'env.$1()' ], + [/Nan::AsyncQueueWorker\((.+)\);/g, '$1.Queue();'], + [/Nan::(Undefined|Null|True|False)\(\)/g, 'env.$1()'], // Nan::ThrowError(error) to Napi::Error::New(env, error).ThrowAsJavaScriptException() - [ /([ ]*)return Nan::Throw(\w*?)Error\((.+?)\);/g, '$1Napi::$2Error::New(env, $3).ThrowAsJavaScriptException();\n$1return env.Null();' ], - [ /Nan::Throw(\w*?)Error\((.+?)\);\n(\s*)return;/g, 'Napi::$1Error::New(env, $2).ThrowAsJavaScriptException();\n$3return env.Null();' ], - [ /Nan::Throw(\w*?)Error\((.+?)\);/g, 'Napi::$1Error::New(env, $2).ThrowAsJavaScriptException();\n' ], + [/([ ]*)return Nan::Throw(\w*?)Error\((.+?)\);/g, '$1Napi::$2Error::New(env, $3).ThrowAsJavaScriptException();\n$1return env.Null();'], + [/Nan::Throw(\w*?)Error\((.+?)\);\n(\s*)return;/g, 'Napi::$1Error::New(env, $2).ThrowAsJavaScriptException();\n$3return env.Null();'], + [/Nan::Throw(\w*?)Error\((.+?)\);/g, 'Napi::$1Error::New(env, $2).ThrowAsJavaScriptException();\n'], // Nan::RangeError(error) to Napi::RangeError::New(env, error) - [ /Nan::(\w*?)Error\((.+)\)/g, 'Napi::$1Error::New(env, $2)' ], + [/Nan::(\w*?)Error\((.+)\)/g, 'Napi::$1Error::New(env, $2)'], - [ /Nan::Set\((.+?),\n* *(.+?),\n* *(.+?),\n* *(.+?)\)/g, '$1.Set($2, $3, $4)' ], + [/Nan::Set\((.+?),\n* *(.+?),\n* *(.+?),\n* *(.+?)\)/g, '$1.Set($2, $3, $4)'], - [ /Nan::(Escapable)?HandleScope\s+(\w+)\s*;/g, 'Napi::$1HandleScope $2(env);' ], - [ /Nan::(Escapable)?HandleScope/g, 'Napi::$1HandleScope' ], - [ /Nan::ForceSet\(([^,]+), ?/g, '$1->DefineProperty(' ], - [ /\.ForceSet\(Napi::String::New\(env, "(\w+)"\),\s*?/g, '.DefineProperty("$1", ' ], + [/Nan::(Escapable)?HandleScope\s+(\w+)\s*;/g, 'Napi::$1HandleScope $2(env);'], + [/Nan::(Escapable)?HandleScope/g, 'Napi::$1HandleScope'], + [/Nan::ForceSet\(([^,]+), ?/g, '$1->DefineProperty('], + [/\.ForceSet\(Napi::String::New\(env, "(\w+)"\),\s*?/g, '.DefineProperty("$1", '], // [ /Nan::GetPropertyNames\(([^,]+)\)/, '$1->GetPropertyNames()' ], - [ /Nan::Equals\(([^,]+),/g, '$1.StrictEquals(' ], - - - [ /(.+)->Set\(/g, '$1.Set\(' ], - - - [ /Nan::Callback/g, 'Napi::FunctionReference' ], - + [/Nan::Equals\(([^,]+),/g, '$1.StrictEquals('], - [ /Nan::Persistent/g, 'Napi::ObjectReference' ], - [ /Nan::ADDON_REGISTER_FUNCTION_ARGS_TYPE target/g, 'Napi::Env& env, Napi::Object& target' ], + [/(.+)->Set\(/g, '$1.Set('], - [ /(\w+)\*\s+(\w+)\s*=\s*Nan::ObjectWrap::Unwrap<\w+>\(info\.This\(\)\);/g, '$1* $2 = this;' ], - [ /Nan::ObjectWrap::Unwrap<(\w+)>\((.*)\);/g, '$2.Unwrap<$1>();' ], + [/Nan::Callback/g, 'Napi::FunctionReference'], - [ /Nan::NAN_METHOD_RETURN_TYPE/g, 'void' ], - [ /NAN_INLINE/g, 'inline' ], + [/Nan::Persistent/g, 'Napi::ObjectReference'], + [/Nan::ADDON_REGISTER_FUNCTION_ARGS_TYPE target/g, 'Napi::Env& env, Napi::Object& target'], - [ /Nan::NAN_METHOD_ARGS_TYPE/g, 'const Napi::CallbackInfo&' ], - [ /NAN_METHOD\(([\w\d:]+?)\)/g, 'Napi::Value $1(const Napi::CallbackInfo& info)'], - [ /static\s*NAN_GETTER\(([\w\d:]+?)\)/g, 'Napi::Value $1(const Napi::CallbackInfo& info)' ], - [ /NAN_GETTER\(([\w\d:]+?)\)/g, 'Napi::Value $1(const Napi::CallbackInfo& info)' ], - [ /static\s*NAN_SETTER\(([\w\d:]+?)\)/g, 'void $1(const Napi::CallbackInfo& info, const Napi::Value& value)' ], - [ /NAN_SETTER\(([\w\d:]+?)\)/g, 'void $1(const Napi::CallbackInfo& info, const Napi::Value& value)' ], - [ /void Init\((v8::)*Local<(v8::)*Object> exports\)/g, 'Napi::Object Init(Napi::Env env, Napi::Object exports)' ], - [ /NAN_MODULE_INIT\(([\w\d:]+?)\);/g, 'Napi::Object $1(Napi::Env env, Napi::Object exports);' ], - [ /NAN_MODULE_INIT\(([\w\d:]+?)\)/g, 'Napi::Object $1(Napi::Env env, Napi::Object exports)' ], + [/(\w+)\*\s+(\w+)\s*=\s*Nan::ObjectWrap::Unwrap<\w+>\(info\.This\(\)\);/g, '$1* $2 = this;'], + [/Nan::ObjectWrap::Unwrap<(\w+)>\((.*)\);/g, '$2.Unwrap<$1>();'], + [/Nan::NAN_METHOD_RETURN_TYPE/g, 'void'], + [/NAN_INLINE/g, 'inline'], - [ /::(Init(?:ialize)?)\(target\)/g, '::$1(env, target, module)' ], - [ /constructor_template/g, 'constructor' ], + [/Nan::NAN_METHOD_ARGS_TYPE/g, 'const Napi::CallbackInfo&'], + [/NAN_METHOD\(([\w\d:]+?)\)/g, 'Napi::Value $1(const Napi::CallbackInfo& info)'], + [/static\s*NAN_GETTER\(([\w\d:]+?)\)/g, 'Napi::Value $1(const Napi::CallbackInfo& info)'], + [/NAN_GETTER\(([\w\d:]+?)\)/g, 'Napi::Value $1(const Napi::CallbackInfo& info)'], + [/static\s*NAN_SETTER\(([\w\d:]+?)\)/g, 'void $1(const Napi::CallbackInfo& info, const Napi::Value& value)'], + [/NAN_SETTER\(([\w\d:]+?)\)/g, 'void $1(const Napi::CallbackInfo& info, const Napi::Value& value)'], + [/void Init\((v8::)*Local<(v8::)*Object> exports\)/g, 'Napi::Object Init(Napi::Env env, Napi::Object exports)'], + [/NAN_MODULE_INIT\(([\w\d:]+?)\);/g, 'Napi::Object $1(Napi::Env env, Napi::Object exports);'], + [/NAN_MODULE_INIT\(([\w\d:]+?)\)/g, 'Napi::Object $1(Napi::Env env, Napi::Object exports)'], - [ /Nan::FunctionCallbackInfo<(v8::)?Value>[ ]*& [ ]*info\)[ ]*{\n*([ ]*)/gm, 'Napi::CallbackInfo& info) {\n$2Napi::Env env = info.Env();\n$2' ], - [ /Nan::FunctionCallbackInfo<(v8::)*Value>\s*&\s*info\);/g, 'Napi::CallbackInfo& info);' ], - [ /Nan::FunctionCallbackInfo<(v8::)*Value>\s*&/g, 'Napi::CallbackInfo&' ], + [/::(Init(?:ialize)?)\(target\)/g, '::$1(env, target, module)'], + [/constructor_template/g, 'constructor'], - [ /Buffer::HasInstance\(([^)]+)\)/g, '$1.IsBuffer()' ], + [/Nan::FunctionCallbackInfo<(v8::)?Value>[ ]*& [ ]*info\)[ ]*{\n*([ ]*)/gm, 'Napi::CallbackInfo& info) {\n$2Napi::Env env = info.Env();\n$2'], + [/Nan::FunctionCallbackInfo<(v8::)*Value>\s*&\s*info\);/g, 'Napi::CallbackInfo& info);'], + [/Nan::FunctionCallbackInfo<(v8::)*Value>\s*&/g, 'Napi::CallbackInfo&'], - [ /info\[(\d+)\]->/g, 'info[$1].' ], - [ /info\[([\w\d]+)\]->/g, 'info[$1].' ], - [ /info\.This\(\)->/g, 'info.This().' ], - [ /->Is(Object|String|Int32|Number)\(\)/g, '.Is$1()' ], - [ /info.GetReturnValue\(\).SetUndefined\(\)/g, 'return env.Undefined()' ], - [ /info\.GetReturnValue\(\)\.Set\(((\n|.)+?)\);/g, 'return $1;' ], + [/Buffer::HasInstance\(([^)]+)\)/g, '$1.IsBuffer()'], + [/info\[(\d+)\]->/g, 'info[$1].'], + [/info\[([\w\d]+)\]->/g, 'info[$1].'], + [/info\.This\(\)->/g, 'info.This().'], + [/->Is(Object|String|Int32|Number)\(\)/g, '.Is$1()'], + [/info.GetReturnValue\(\).SetUndefined\(\)/g, 'return env.Undefined()'], + [/info\.GetReturnValue\(\)\.Set\(((\n|.)+?)\);/g, 'return $1;'], // ex. Local to Napi::Value - [ /v8::Local/g, 'Napi::$1' ], - [ /Local<(Value|Boolean|String|Number|Object|Array|Symbol|External|Function)>/g, 'Napi::$1' ], + [/v8::Local/g, 'Napi::$1'], + [/Local<(Value|Boolean|String|Number|Object|Array|Symbol|External|Function)>/g, 'Napi::$1'], // Declare an env in helper functions that take a Napi::Value - [ /(\w+)\(Napi::Value (\w+)(,\s*[^\()]+)?\)\s*{\n*([ ]*)/gm, '$1(Napi::Value $2$3) {\n$4Napi::Env env = $2.Env();\n$4' ], + [/(\w+)\(Napi::Value (\w+)(,\s*[^()]+)?\)\s*{\n*([ ]*)/gm, '$1(Napi::Value $2$3) {\n$4Napi::Env env = $2.Env();\n$4'], // delete #include and/or - [ /#include +(<|")(?:node|nan).h("|>)/g, "#include $1napi.h$2\n#include $1uv.h$2" ], + [/#include +(<|")(?:node|nan).h("|>)/g, '#include $1napi.h$2\n#include $1uv.h$2'], // NODE_MODULE to NODE_API_MODULE - [ /NODE_MODULE/g, 'NODE_API_MODULE' ], - [ /Nan::/g, 'Napi::' ], - [ /nan.h/g, 'napi.h' ], + [/NODE_MODULE/g, 'NODE_API_MODULE'], + [/Nan::/g, 'Napi::'], + [/nan.h/g, 'napi.h'], // delete .FromJust() - [ /\.FromJust\(\)/g, '' ], + [/\.FromJust\(\)/g, ''], // delete .ToLocalCheck() - [ /\.ToLocalChecked\(\)/g, '' ], - [ /^.*->SetInternalFieldCount\(.*$/gm, '' ], + [/\.ToLocalChecked\(\)/g, ''], + [/^.*->SetInternalFieldCount\(.*$/gm, ''], // replace using node; and/or using v8; to using Napi; - [ /using (node|v8);/g, 'using Napi;' ], - [ /using namespace (node|Nan|v8);/g, 'using namespace Napi;' ], + [/using (node|v8);/g, 'using Napi;'], + [/using namespace (node|Nan|v8);/g, 'using namespace Napi;'], // delete using v8::Local; - [ /using v8::Local;\n/g, '' ], + [/using v8::Local;\n/g, ''], // replace using v8::XXX; with using Napi::XXX - [ /using v8::([A-Za-z]+);/g, 'using Napi::$1;' ], + [/using v8::([A-Za-z]+);/g, 'using Napi::$1;'] ]; -var paths = listFiles(dir); -paths.forEach(function(dirEntry) { - var filename = dirEntry.split('\\').pop().split('/').pop(); +const paths = listFiles(dir); +paths.forEach(function (dirEntry) { + const filename = dirEntry.split('\\').pop().split('/').pop(); // Check whether the file is a source file or a config file // then execute function accordingly - var sourcePattern = /.+\.h|.+\.cc|.+\.cpp/; + const sourcePattern = /.+\.h|.+\.cc|.+\.cpp/; if (sourcePattern.test(filename)) { convertFile(dirEntry, SourceFileOperations); } else if (ConfigFileOperations[filename] != null) { @@ -271,12 +263,12 @@ paths.forEach(function(dirEntry) { } }); -function listFiles(dir, filelist) { - var files = fs.readdirSync(dir); +function listFiles (dir, filelist) { + const files = fs.readdirSync(dir); filelist = filelist || []; - files.forEach(function(file) { + files.forEach(function (file) { if (file === 'node_modules') { - return + return; } if (fs.statSync(path.join(dir, file)).isDirectory()) { @@ -288,21 +280,21 @@ function listFiles(dir, filelist) { return filelist; } -function convert(content, operations) { - for (let i = 0; i < operations.length; i ++) { - let operation = operations[i]; +function convert (content, operations) { + for (let i = 0; i < operations.length; i++) { + const operation = operations[i]; content = content.replace(operation[0], operation[1]); } return content; } -function convertFile(fileName, operations) { - fs.readFile(fileName, "utf-8", function (err, file) { +function convertFile (fileName, operations) { + fs.readFile(fileName, 'utf-8', function (err, file) { if (err) throw err; file = convert(file, operations); - fs.writeFile(fileName, file, function(err){ + fs.writeFile(fileName, file, function (err) { if (err) throw err; }); }); diff --git a/node_modules/node-addon-api/tools/eslint-format.js b/node_modules/node-addon-api/tools/eslint-format.js index 5938835d..1dda4449 100644 --- a/node_modules/node-addon-api/tools/eslint-format.js +++ b/node_modules/node-addon-api/tools/eslint-format.js @@ -4,6 +4,8 @@ const spawn = require('child_process').spawnSync; const filesToCheck = '*.js'; const FORMAT_START = process.env.FORMAT_START || 'main'; +const IS_WIN = process.platform === 'win32'; +const ESLINT_PATH = IS_WIN ? 'node_modules\\.bin\\eslint.cmd' : 'node_modules/.bin/eslint'; function main (args) { let fix = false; @@ -44,10 +46,16 @@ function main (args) { if (fix) { options.push('--fix'); } - const result = spawn('node_modules/.bin/eslint', [...options], { + + const result = spawn(ESLINT_PATH, [...options], { encoding: 'utf-8' }); + if (result.error && result.error.errno === 'ENOENT') { + console.error('Eslint not found! Eslint is supposed to be found at ', ESLINT_PATH); + return 2; + } + if (result.status === 1) { console.error('Eslint error:', result.stdout); const fixCmd = 'npm run lint:fix'; diff --git a/node_modules/tar/README.md b/node_modules/tar/README.md index 7cb09da6..f620568e 100644 --- a/node_modules/tar/README.md +++ b/node_modules/tar/README.md @@ -115,6 +115,8 @@ Handlers receive 3 arguments: encountered an error which prevented it from being unpacked. This occurs when: - an unrecoverable fs error happens during unpacking, + - an entry is trying to extract into an excessively deep + location (by default, limited to 1024 subfolders), - an entry has `..` in the path and `preservePaths` is not set, or - an entry is extracting through a symbolic link, when `preservePaths` is not set. @@ -427,6 +429,10 @@ The following options are supported: `process.umask()` to determine the default umask value, since tar will extract with whatever mode is provided, and let the process `umask` apply normally. +- `maxDepth` The maximum depth of subfolders to extract into. This + defaults to 1024. Anything deeper than the limit will raise a + warning and skip the entry. Set to `Infinity` to remove the + limitation. The following options are mostly internal, but can be modified in some advanced use cases, such as re-using caches between runs. @@ -749,6 +755,10 @@ Most unpack errors will cause a `warn` event to be emitted. If the `process.umask()` to determine the default umask value, since tar will extract with whatever mode is provided, and let the process `umask` apply normally. +- `maxDepth` The maximum depth of subfolders to extract into. This + defaults to 1024. Anything deeper than the limit will raise a + warning and skip the entry. Set to `Infinity` to remove the + limitation. ### class tar.Unpack.Sync diff --git a/node_modules/tar/lib/normalize-unicode.js b/node_modules/tar/lib/normalize-unicode.js index 43dc406e..79e285ab 100644 --- a/node_modules/tar/lib/normalize-unicode.js +++ b/node_modules/tar/lib/normalize-unicode.js @@ -6,7 +6,7 @@ const normalizeCache = Object.create(null) const { hasOwnProperty } = Object.prototype module.exports = s => { if (!hasOwnProperty.call(normalizeCache, s)) { - normalizeCache[s] = s.normalize('NFKD') + normalizeCache[s] = s.normalize('NFD') } return normalizeCache[s] } diff --git a/node_modules/tar/lib/pack.js b/node_modules/tar/lib/pack.js index a3f4ff22..d533a068 100644 --- a/node_modules/tar/lib/pack.js +++ b/node_modules/tar/lib/pack.js @@ -22,7 +22,7 @@ class PackJob { } } -const MiniPass = require('minipass') +const { Minipass } = require('minipass') const zlib = require('minizlib') const ReadEntry = require('./read-entry.js') const WriteEntry = require('./write-entry.js') @@ -56,7 +56,7 @@ const path = require('path') const warner = require('./warn-mixin.js') const normPath = require('./normalize-windows-path.js') -const Pack = warner(class Pack extends MiniPass { +const Pack = warner(class Pack extends Minipass { constructor (opt) { super(opt) opt = opt || Object.create(null) @@ -79,14 +79,26 @@ const Pack = warner(class Pack extends MiniPass { this.portable = !!opt.portable this.zip = null - if (opt.gzip) { - if (typeof opt.gzip !== 'object') { - opt.gzip = {} + + if (opt.gzip || opt.brotli) { + if (opt.gzip && opt.brotli) { + throw new TypeError('gzip and brotli are mutually exclusive') } - if (this.portable) { - opt.gzip.portable = true + if (opt.gzip) { + if (typeof opt.gzip !== 'object') { + opt.gzip = {} + } + if (this.portable) { + opt.gzip.portable = true + } + this.zip = new zlib.Gzip(opt.gzip) + } + if (opt.brotli) { + if (typeof opt.brotli !== 'object') { + opt.brotli = {} + } + this.zip = new zlib.BrotliCompress(opt.brotli) } - this.zip = new zlib.Gzip(opt.gzip) this.zip.on('data', chunk => super.write(chunk)) this.zip.on('end', _ => super.end()) this.zip.on('drain', _ => this[ONDRAIN]()) diff --git a/node_modules/tar/lib/parse.js b/node_modules/tar/lib/parse.js index 4b85915c..94e53042 100644 --- a/node_modules/tar/lib/parse.js +++ b/node_modules/tar/lib/parse.js @@ -97,6 +97,16 @@ module.exports = warner(class Parser extends EE { this.strict = !!opt.strict this.maxMetaEntrySize = opt.maxMetaEntrySize || maxMetaEntrySize this.filter = typeof opt.filter === 'function' ? opt.filter : noop + // Unlike gzip, brotli doesn't have any magic bytes to identify it + // Users need to explicitly tell us they're extracting a brotli file + // Or we infer from the file extension + const isTBR = (opt.file && ( + opt.file.endsWith('.tar.br') || opt.file.endsWith('.tbr'))) + // if it's a tbr file it MIGHT be brotli, but we don't know until + // we look at it and verify it's not a valid tar file. + this.brotli = !opt.gzip && opt.brotli !== undefined ? opt.brotli + : isTBR ? undefined + : false // have to set this so that streams are ok piping into it this.writable = true @@ -347,7 +357,9 @@ module.exports = warner(class Parser extends EE { } // first write, might be gzipped - if (this[UNZIP] === null && chunk) { + const needSniff = this[UNZIP] === null || + this.brotli === undefined && this[UNZIP] === false + if (needSniff && chunk) { if (this[BUFFER]) { chunk = Buffer.concat([this[BUFFER], chunk]) this[BUFFER] = null @@ -356,15 +368,45 @@ module.exports = warner(class Parser extends EE { this[BUFFER] = chunk return true } + + // look for gzip header for (let i = 0; this[UNZIP] === null && i < gzipHeader.length; i++) { if (chunk[i] !== gzipHeader[i]) { this[UNZIP] = false } } - if (this[UNZIP] === null) { + + const maybeBrotli = this.brotli === undefined + if (this[UNZIP] === false && maybeBrotli) { + // read the first header to see if it's a valid tar file. If so, + // we can safely assume that it's not actually brotli, despite the + // .tbr or .tar.br file extension. + // if we ended before getting a full chunk, yes, def brotli + if (chunk.length < 512) { + if (this[ENDED]) { + this.brotli = true + } else { + this[BUFFER] = chunk + return true + } + } else { + // if it's tar, it's pretty reliably not brotli, chances of + // that happening are astronomical. + try { + new Header(chunk.slice(0, 512)) + this.brotli = false + } catch (_) { + this.brotli = true + } + } + } + + if (this[UNZIP] === null || (this[UNZIP] === false && this.brotli)) { const ended = this[ENDED] this[ENDED] = false - this[UNZIP] = new zlib.Unzip() + this[UNZIP] = this[UNZIP] === null + ? new zlib.Unzip() + : new zlib.BrotliDecompress() this[UNZIP].on('data', chunk => this[CONSUMECHUNK](chunk)) this[UNZIP].on('error', er => this.abort(er)) this[UNZIP].on('end', _ => { @@ -502,6 +544,7 @@ module.exports = warner(class Parser extends EE { this[UNZIP].end(chunk) } else { this[ENDED] = true + if (this.brotli === undefined) chunk = chunk || Buffer.alloc(0) this.write(chunk) } } diff --git a/node_modules/tar/lib/path-reservations.js b/node_modules/tar/lib/path-reservations.js index ef380cab..8d349d58 100644 --- a/node_modules/tar/lib/path-reservations.js +++ b/node_modules/tar/lib/path-reservations.js @@ -123,7 +123,7 @@ module.exports = () => { // effectively removing all parallelization on windows. paths = isWindows ? ['win32 parallelization disabled'] : paths.map(p => { // don't need normPath, because we skip this entirely for windows - return normalize(stripSlashes(join(p))).toLowerCase() + return stripSlashes(join(normalize(p))).toLowerCase() }) const dirs = new Set( diff --git a/node_modules/tar/lib/read-entry.js b/node_modules/tar/lib/read-entry.js index 7f44bebf..6186266e 100644 --- a/node_modules/tar/lib/read-entry.js +++ b/node_modules/tar/lib/read-entry.js @@ -1,9 +1,9 @@ 'use strict' -const MiniPass = require('minipass') +const { Minipass } = require('minipass') const normPath = require('./normalize-windows-path.js') const SLURP = Symbol('slurp') -module.exports = class ReadEntry extends MiniPass { +module.exports = class ReadEntry extends Minipass { constructor (header, ex, gex) { super() // read entries always start life paused. this is to avoid the diff --git a/node_modules/tar/lib/replace.js b/node_modules/tar/lib/replace.js index c6e619be..8db6800b 100644 --- a/node_modules/tar/lib/replace.js +++ b/node_modules/tar/lib/replace.js @@ -23,7 +23,7 @@ module.exports = (opt_, files, cb) => { throw new TypeError('file is required') } - if (opt.gzip) { + if (opt.gzip || opt.brotli || opt.file.endsWith('.br') || opt.file.endsWith('.tbr')) { throw new TypeError('cannot append to compressed archives') } diff --git a/node_modules/tar/lib/unpack.js b/node_modules/tar/lib/unpack.js index e341ad0c..03172e2c 100644 --- a/node_modules/tar/lib/unpack.js +++ b/node_modules/tar/lib/unpack.js @@ -48,6 +48,7 @@ const crypto = require('crypto') const getFlag = require('./get-write-flag.js') const platform = process.env.TESTING_TAR_FAKE_PLATFORM || process.platform const isWindows = platform === 'win32' +const DEFAULT_MAX_DEPTH = 1024 // Unlinks on Windows are not atomic. // @@ -105,7 +106,7 @@ const uint32 = (a, b, c) => // Note that on windows, we always drop the entire cache whenever a // symbolic link is encountered, because 8.3 filenames are impossible // to reason about, and collisions are hazards rather than just failures. -const cacheKeyNormalize = path => normalize(stripSlash(normPath(path))) +const cacheKeyNormalize = path => stripSlash(normPath(normalize(path))) .toLowerCase() const pruneCache = (cache, abs) => { @@ -181,6 +182,12 @@ class Unpack extends Parser { this.processGid = (this.preserveOwner || this.setOwner) && process.getgid ? process.getgid() : null + // prevent excessively deep nesting of subfolders + // set to `Infinity` to remove this restriction + this.maxDepth = typeof opt.maxDepth === 'number' + ? opt.maxDepth + : DEFAULT_MAX_DEPTH + // mostly just for testing, but useful in some cases. // Forcibly trigger a chown on every entry, no matter what this.forceChown = opt.forceChown === true @@ -238,13 +245,13 @@ class Unpack extends Parser { } [CHECKPATH] (entry) { + const p = normPath(entry.path) + const parts = p.split('/') + if (this.strip) { - const parts = normPath(entry.path).split('/') if (parts.length < this.strip) { return false } - entry.path = parts.slice(this.strip).join('/') - if (entry.type === 'Link') { const linkparts = normPath(entry.linkpath).split('/') if (linkparts.length >= this.strip) { @@ -253,11 +260,21 @@ class Unpack extends Parser { return false } } + parts.splice(0, this.strip) + entry.path = parts.join('/') + } + + if (isFinite(this.maxDepth) && parts.length > this.maxDepth) { + this.warn('TAR_ENTRY_ERROR', 'path excessively deep', { + entry, + path: p, + depth: parts.length, + maxDepth: this.maxDepth, + }) + return false } if (!this.preservePaths) { - const p = normPath(entry.path) - const parts = p.split('/') if (parts.includes('..') || isWindows && /^[a-z]:\.\.$/i.test(parts[0])) { this.warn('TAR_ENTRY_ERROR', `path contains '..'`, { entry, diff --git a/node_modules/tar/lib/update.js b/node_modules/tar/lib/update.js index ded977dc..4d328543 100644 --- a/node_modules/tar/lib/update.js +++ b/node_modules/tar/lib/update.js @@ -13,7 +13,7 @@ module.exports = (opt_, files, cb) => { throw new TypeError('file is required') } - if (opt.gzip) { + if (opt.gzip || opt.brotli || opt.file.endsWith('.br') || opt.file.endsWith('.tbr')) { throw new TypeError('cannot append to compressed archives') } diff --git a/node_modules/tar/lib/write-entry.js b/node_modules/tar/lib/write-entry.js index 3b5540f7..7d2f3eb1 100644 --- a/node_modules/tar/lib/write-entry.js +++ b/node_modules/tar/lib/write-entry.js @@ -1,5 +1,5 @@ 'use strict' -const MiniPass = require('minipass') +const { Minipass } = require('minipass') const Pax = require('./pax.js') const Header = require('./header.js') const fs = require('fs') @@ -41,7 +41,7 @@ const stripAbsolutePath = require('./strip-absolute-path.js') const modeFix = require('./mode-fix.js') -const WriteEntry = warner(class WriteEntry extends MiniPass { +const WriteEntry = warner(class WriteEntry extends Minipass { constructor (p, opt) { opt = opt || {} super(opt) @@ -417,7 +417,7 @@ class WriteEntrySync extends WriteEntry { } } -const WriteEntryTar = warner(class WriteEntryTar extends MiniPass { +const WriteEntryTar = warner(class WriteEntryTar extends Minipass { constructor (readEntry, opt) { opt = opt || {} super(opt) diff --git a/node_modules/tar/package.json b/node_modules/tar/package.json index e6d6b933..f84a41cc 100644 --- a/node_modules/tar/package.json +++ b/node_modules/tar/package.json @@ -2,32 +2,27 @@ "author": "GitHub Inc.", "name": "tar", "description": "tar for node", - "version": "6.1.13", + "version": "6.2.1", "repository": { "type": "git", - "url": "https://github.com/npm/node-tar.git" + "url": "https://github.com/isaacs/node-tar.git" }, "scripts": { "genparse": "node scripts/generate-parse-fixtures.js", - "template-oss-apply": "template-oss-apply --force", - "lint": "eslint \"**/*.js\"", - "postlint": "template-oss-check", - "lintfix": "npm run lint -- --fix", "snap": "tap", - "test": "tap", - "posttest": "npm run lint" + "test": "tap" }, "dependencies": { "chownr": "^2.0.0", "fs-minipass": "^2.0.0", - "minipass": "^4.0.0", + "minipass": "^5.0.0", "minizlib": "^2.1.1", "mkdirp": "^1.0.3", "yallist": "^4.0.0" }, "devDependencies": { "@npmcli/eslint-config": "^4.0.0", - "@npmcli/template-oss": "4.10.0", + "@npmcli/template-oss": "4.11.0", "chmodr": "^1.2.0", "end-of-stream": "^1.4.3", "events-to-array": "^2.0.3", @@ -55,7 +50,7 @@ }, "templateOSS": { "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", - "version": "4.10.0", + "version": "4.11.0", "content": "scripts/template-oss", "engines": ">=10", "distPaths": [ diff --git a/package-lock.json b/package-lock.json index b84c7034..ceb0132b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -17,7 +17,7 @@ "@google-cloud/storage": "^6.10.1", "adminjs": "^6.7.2", "axios": "^1.7.2", - "bcrypt": "^5.0.0", + "bcrypt": "^5.1.1", "body-parser": "^1.19.0", "boom": "^7.3.0", "chalk": "^4.1.0", @@ -2697,9 +2697,10 @@ } }, "node_modules/@mapbox/node-pre-gyp": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.10.tgz", - "integrity": "sha512-4ySo4CjzStuprMwk35H5pPbkymjv1SF3jGLj6rAHp/xT/RF7TL7bd9CTm1xDY49K2qF7jmR/g7k+SkLETP6opA==", + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.11.tgz", + "integrity": "sha512-Yhlar6v9WQgUp/He7BdgzOz8lqMQ8sU+jkCq7Wx8Myc5YFJLbEe7lgui/V7G1qB1DJykHSGwreceSaD60Y0PUQ==", + "license": "BSD-3-Clause", "dependencies": { "detect-libc": "^2.0.0", "https-proxy-agent": "^5.0.0", @@ -2715,21 +2716,11 @@ "node-pre-gyp": "bin/node-pre-gyp" } }, - "node_modules/@mapbox/node-pre-gyp/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/@mapbox/node-pre-gyp/node_modules/make-dir": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "license": "MIT", "dependencies": { "semver": "^6.0.0" }, @@ -2741,20 +2732,19 @@ } }, "node_modules/@mapbox/node-pre-gyp/node_modules/make-dir/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "license": "ISC", "bin": { "semver": "bin/semver.js" } }, "node_modules/@mapbox/node-pre-gyp/node_modules/semver": { - "version": "7.3.8", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", - "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", - "dependencies": { - "lru-cache": "^6.0.0" - }, + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "license": "ISC", "bin": { "semver": "bin/semver.js" }, @@ -2762,11 +2752,6 @@ "node": ">=10" } }, - "node_modules/@mapbox/node-pre-gyp/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - }, "node_modules/@popperjs/core": { "version": "2.11.6", "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.6.tgz", @@ -4004,7 +3989,8 @@ "node_modules/aproba": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", - "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==" + "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==", + "license": "ISC" }, "node_modules/archiver": { "version": "5.3.1", @@ -4084,6 +4070,8 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz", "integrity": "sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==", + "deprecated": "This package is no longer supported.", + "license": "ISC", "dependencies": { "delegates": "^1.0.0", "readable-stream": "^3.6.0" @@ -4318,12 +4306,13 @@ ] }, "node_modules/bcrypt": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/bcrypt/-/bcrypt-5.1.0.tgz", - "integrity": "sha512-RHBS7HI5N5tEnGTmtR/pppX0mmDSBpQ4aCBsj7CEQfYXDcO74A8sIBYcJMuCsis2E81zDxeENYhv66oZwLiA+Q==", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/bcrypt/-/bcrypt-5.1.1.tgz", + "integrity": "sha512-AGBHOG5hPYZ5Xl9KXzU5iKq9516yEmvCKDg3ecP5kX2aB6UqTeXZxk2ELnDgDm6BQSMlLt9rDB4LoSMx0rYwww==", "hasInstallScript": true, + "license": "MIT", "dependencies": { - "@mapbox/node-pre-gyp": "^1.0.10", + "@mapbox/node-pre-gyp": "^1.0.11", "node-addon-api": "^5.0.0" }, "engines": { @@ -4723,6 +4712,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "license": "ISC", "engines": { "node": ">=10" } @@ -4861,6 +4851,7 @@ "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", + "license": "ISC", "bin": { "color-support": "bin.js" } @@ -4936,7 +4927,8 @@ "node_modules/console-control-strings": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", - "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==" + "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==", + "license": "ISC" }, "node_modules/content-disposition": { "version": "0.5.4", @@ -5270,7 +5262,8 @@ "node_modules/delegates": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", - "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==" + "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==", + "license": "MIT" }, "node_modules/denque": { "version": "1.5.1", @@ -5303,9 +5296,10 @@ } }, "node_modules/detect-libc": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.1.tgz", - "integrity": "sha512-463v3ZeIrcWtdgIg6vI6XUncguvr2TnGl4SzDXinkt9mSLpBJKXT3mW6xT3VQdDN11+WVs29pgvivTc4Lp8v+w==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz", + "integrity": "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==", + "license": "Apache-2.0", "engines": { "node": ">=8" } @@ -6798,6 +6792,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "license": "ISC", "dependencies": { "minipass": "^3.0.0" }, @@ -6809,6 +6804,7 @@ "version": "3.3.6", "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "license": "ISC", "dependencies": { "yallist": "^4.0.0" }, @@ -6819,7 +6815,8 @@ "node_modules/fs-minipass/node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "license": "ISC" }, "node_modules/fs.realpath": { "version": "1.0.0", @@ -6923,6 +6920,8 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/gauge/-/gauge-3.0.2.tgz", "integrity": "sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==", + "deprecated": "This package is no longer supported.", + "license": "ISC", "dependencies": { "aproba": "^1.0.3 || ^2.0.0", "color-support": "^1.1.2", @@ -7519,7 +7518,8 @@ "node_modules/has-unicode": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", - "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==" + "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==", + "license": "ISC" }, "node_modules/hashlru": { "version": "2.3.0", @@ -8694,25 +8694,19 @@ } }, "node_modules/minipass": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-4.0.0.tgz", - "integrity": "sha512-g2Uuh2jEKoht+zvO6vJqXmYpflPqzRBT+Th2h01DKh5z7wbY/AZ2gCQ78cP70YoHPyFdY30YBV5WxgLOEwOykw==", - "dependencies": { - "yallist": "^4.0.0" - }, + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", + "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", + "license": "ISC", "engines": { "node": ">=8" } }, - "node_modules/minipass/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - }, "node_modules/minizlib": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "license": "MIT", "dependencies": { "minipass": "^3.0.0", "yallist": "^4.0.0" @@ -8725,6 +8719,7 @@ "version": "3.3.6", "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "license": "ISC", "dependencies": { "yallist": "^4.0.0" }, @@ -8735,7 +8730,8 @@ "node_modules/minizlib/node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "license": "ISC" }, "node_modules/mkdirp": { "version": "1.0.4", @@ -9137,9 +9133,10 @@ } }, "node_modules/node-addon-api": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-5.0.0.tgz", - "integrity": "sha512-CvkDw2OEnme7ybCykJpVcKH+uAOLV2qLqiyla128dN9TkEWfrYmxG6C2boDe5KcNQqZF3orkqzGgOMvZ/JNekA==" + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-5.1.0.tgz", + "integrity": "sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA==", + "license": "MIT" }, "node_modules/node-cron": { "version": "3.0.2", @@ -9272,6 +9269,7 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==", + "license": "ISC", "dependencies": { "abbrev": "1" }, @@ -9294,6 +9292,8 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-5.0.1.tgz", "integrity": "sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==", + "deprecated": "This package is no longer supported.", + "license": "ISC", "dependencies": { "are-we-there-yet": "^2.0.0", "console-control-strings": "^1.1.0", @@ -10989,7 +10989,8 @@ "node_modules/set-blocking": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==" + "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", + "license": "ISC" }, "node_modules/set-cookie-parser": { "version": "2.5.1", @@ -11471,13 +11472,14 @@ } }, "node_modules/tar": { - "version": "6.1.13", - "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.13.tgz", - "integrity": "sha512-jdIBIN6LTIe2jqzay/2vtYLlBHa3JF42ot3h1dW8Q0PaAG4v8rm0cvpVePtau5C6OKXGGcgO9q2AMNSWxiLqKw==", + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz", + "integrity": "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==", + "license": "ISC", "dependencies": { "chownr": "^2.0.0", "fs-minipass": "^2.0.0", - "minipass": "^4.0.0", + "minipass": "^5.0.0", "minizlib": "^2.1.1", "mkdirp": "^1.0.3", "yallist": "^4.0.0" @@ -11514,7 +11516,8 @@ "node_modules/tar/node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "license": "ISC" }, "node_modules/teeny-request": { "version": "8.0.3", @@ -12449,6 +12452,7 @@ "version": "1.1.5", "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz", "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==", + "license": "ISC", "dependencies": { "string-width": "^1.0.2 || 2 || 3 || 4" } @@ -14636,9 +14640,9 @@ "integrity": "sha512-Xs/4RZltsAL7pkvaNStUQt7netTkyxrS0K+RILcVr3TRMS/ToOg4I6uNfhB9SlGsnWBym4U+EaXq0f0cEMNkHA==" }, "@mapbox/node-pre-gyp": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.10.tgz", - "integrity": "sha512-4ySo4CjzStuprMwk35H5pPbkymjv1SF3jGLj6rAHp/xT/RF7TL7bd9CTm1xDY49K2qF7jmR/g7k+SkLETP6opA==", + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.11.tgz", + "integrity": "sha512-Yhlar6v9WQgUp/He7BdgzOz8lqMQ8sU+jkCq7Wx8Myc5YFJLbEe7lgui/V7G1qB1DJykHSGwreceSaD60Y0PUQ==", "requires": { "detect-libc": "^2.0.0", "https-proxy-agent": "^5.0.0", @@ -14651,14 +14655,6 @@ "tar": "^6.1.11" }, "dependencies": { - "lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "requires": { - "yallist": "^4.0.0" - } - }, "make-dir": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", @@ -14668,24 +14664,16 @@ }, "dependencies": { "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==" } } }, "semver": { - "version": "7.3.8", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", - "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", - "requires": { - "lru-cache": "^6.0.0" - } - }, - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==" } } }, @@ -15873,11 +15861,11 @@ "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" }, "bcrypt": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/bcrypt/-/bcrypt-5.1.0.tgz", - "integrity": "sha512-RHBS7HI5N5tEnGTmtR/pppX0mmDSBpQ4aCBsj7CEQfYXDcO74A8sIBYcJMuCsis2E81zDxeENYhv66oZwLiA+Q==", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/bcrypt/-/bcrypt-5.1.1.tgz", + "integrity": "sha512-AGBHOG5hPYZ5Xl9KXzU5iKq9516yEmvCKDg3ecP5kX2aB6UqTeXZxk2ELnDgDm6BQSMlLt9rDB4LoSMx0rYwww==", "requires": { - "@mapbox/node-pre-gyp": "^1.0.10", + "@mapbox/node-pre-gyp": "^1.0.11", "node-addon-api": "^5.0.0" } }, @@ -16582,9 +16570,9 @@ "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==" }, "detect-libc": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.1.tgz", - "integrity": "sha512-463v3ZeIrcWtdgIg6vI6XUncguvr2TnGl4SzDXinkt9mSLpBJKXT3mW6xT3VQdDN11+WVs29pgvivTc4Lp8v+w==" + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz", + "integrity": "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==" }, "dezalgo": { "version": "1.0.4", @@ -19349,19 +19337,9 @@ "integrity": "sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==" }, "minipass": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-4.0.0.tgz", - "integrity": "sha512-g2Uuh2jEKoht+zvO6vJqXmYpflPqzRBT+Th2h01DKh5z7wbY/AZ2gCQ78cP70YoHPyFdY30YBV5WxgLOEwOykw==", - "requires": { - "yallist": "^4.0.0" - }, - "dependencies": { - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - } - } + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", + "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==" }, "minizlib": { "version": "2.1.2", @@ -19686,9 +19664,9 @@ "integrity": "sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==" }, "node-addon-api": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-5.0.0.tgz", - "integrity": "sha512-CvkDw2OEnme7ybCykJpVcKH+uAOLV2qLqiyla128dN9TkEWfrYmxG6C2boDe5KcNQqZF3orkqzGgOMvZ/JNekA==" + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-5.1.0.tgz", + "integrity": "sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA==" }, "node-cron": { "version": "3.0.2", @@ -21454,13 +21432,13 @@ "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==" }, "tar": { - "version": "6.1.13", - "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.13.tgz", - "integrity": "sha512-jdIBIN6LTIe2jqzay/2vtYLlBHa3JF42ot3h1dW8Q0PaAG4v8rm0cvpVePtau5C6OKXGGcgO9q2AMNSWxiLqKw==", + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz", + "integrity": "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==", "requires": { "chownr": "^2.0.0", "fs-minipass": "^2.0.0", - "minipass": "^4.0.0", + "minipass": "^5.0.0", "minizlib": "^2.1.1", "mkdirp": "^1.0.3", "yallist": "^4.0.0" diff --git a/package.json b/package.json index 32596bbc..56e6b6c6 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,7 @@ "@google-cloud/storage": "^6.10.1", "adminjs": "^6.7.2", "axios": "^1.7.2", - "bcrypt": "^5.0.0", + "bcrypt": "^5.1.1", "body-parser": "^1.19.0", "boom": "^7.3.0", "chalk": "^4.1.0",