From ed9c1cec7a90adbde4cec43c74847fc5b20f5a6d Mon Sep 17 00:00:00 2001 From: Chris Barber Date: Tue, 2 Jul 2024 02:03:55 -0500 Subject: [PATCH 01/27] Refactor to ESM, TypeScript, update deps --- .gitattributes | 44 + .gitignore | 7 +- CHANGELOG.md | 4 + Jenkinsfile | 7 - LICENSE | 211 +- README.md | 6 +- biome.json | 40 + lefthook.yml | 6 + package.json | 118 +- patches/node-gyp-build@4.8.1.patch | 24 + pnpm-lock.yaml | 2879 ++++++++++++++++++++++++++++ rollup.config.ts | 28 + rollup.dts.config.ts | 19 + src/index.js | 77 - src/index.ts | 106 + src/watchnode.h | 2 +- src/winreglib.cpp | 2 +- test/test-winreglib.js | 725 ------- test/wingreglib.test.ts | 725 +++++++ tsconfig.build.json | 10 + tsconfig.check.json | 8 + tsconfig.json | 28 + vitest.config.ts | 14 + yarn.lock | 1476 -------------- 24 files changed, 4223 insertions(+), 2343 deletions(-) create mode 100644 .gitattributes delete mode 100644 Jenkinsfile create mode 100644 biome.json create mode 100644 lefthook.yml create mode 100644 patches/node-gyp-build@4.8.1.patch create mode 100644 pnpm-lock.yaml create mode 100644 rollup.config.ts create mode 100644 rollup.dts.config.ts delete mode 100644 src/index.js create mode 100644 src/index.ts delete mode 100644 test/test-winreglib.js create mode 100644 test/wingreglib.test.ts create mode 100644 tsconfig.build.json create mode 100644 tsconfig.check.json create mode 100644 tsconfig.json create mode 100644 vitest.config.ts delete mode 100644 yarn.lock diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..b30cb73 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,44 @@ +# .gitattributes snippet to force users to use same line endings for project. +# +# Handle line endings automatically for files detected as text +# and leave all files detected as binary untouched. +* text=auto + + +# These files are text and should be normalized (Convert crlf => lf) +*.php text +*.css text +*.js text eol=lf +*.json text +*.htm text +*.html text +*.xml text +*.txt text +*.ini text +*.inc text +*.pl text +*.rb text +*.py text +*.scm text +*.sql text +.htaccess text +*.sh text + +# These files are binary and should be left untouched +# (binary is a macro for -text -diff) +*.png binary +*.jpg binary +*.jpeg binary +*.gif binary +*.ico binary +*.mov binary +*.mp4 binary +*.mp3 binary +*.flv binary +*.fla binary +*.swf binary +*.gz binary +*.zip binary +*.7z binary +*.ttf binary +*.pyc binary diff --git a/.gitignore b/.gitignore index 78b3278..1ae4598 100644 --- a/.gitignore +++ b/.gitignore @@ -2,9 +2,14 @@ .DS_Store* .nyc_output .vscode +coverage +dist /build /prebuilds junit.xml node_modules npm-debug.log -yarn-error.log +.pnpm-debug.log +tmp +*.tsbuildinfo +*.tgz diff --git a/CHANGELOG.md b/CHANGELOG.md index f2e33c5..840280f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +# v3.0.0 + + * BREAKING CHANGE: Require Node.js 18.17 or newer + # v2.0.2 (Dec 1, 2020) * chore: Updated dependencies. diff --git a/Jenkinsfile b/Jenkinsfile deleted file mode 100644 index ab4cd3b..0000000 --- a/Jenkinsfile +++ /dev/null @@ -1,7 +0,0 @@ -#! groovy -library 'pipeline-library' - -runNPMPackage { - nodeVersions = [ '10.19.0', '12.18.0', '14.4.0' ] - platforms = [ 'windows' ] -} diff --git a/LICENSE b/LICENSE index 9c7f182..ad68aba 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,7 @@ -Copyright 2019-2020 by Axway, Inc. +====================================== +Titanium CLI +Copyright TiDev, Inc. 04/07/2022-Present +====================================== Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -6,8 +9,214 @@ Copyright 2019-2020 by Axway, Inc. http://www.apache.org/licenses/LICENSE-2.0 + (or the full text of the license is below) + Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + + + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright [yyyy] [name of copyright owner] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/README.md b/README.md index c03a40a..3141872 100644 --- a/README.md +++ b/README.md @@ -153,11 +153,9 @@ winreglib.on('log', msg => console.log(msg)); Alternatively, `winreglib` uses the amazing [`snooplogg`][2] debug logger where you simply set the `SNOOPLOGG` environment variable to `winreglib` (or `*`) and it will print the debug log to stdout. -## License +## Legal -This project is open source under the [Apache Public License v2][1] and is developed by -[Axway, Inc](http://www.axway.com/) and the community. Please read the [`LICENSE`][1] file included -in this distribution for more information. +Titanium is a registered trademark of TiDev Inc. All Titanium trademark and patent rights were transferred and assigned to TiDev Inc. on 4/7/2022. Please see the LEGAL information about using our trademarks, privacy policy, terms of usage and other legal information at https://tidev.io/legal. [1]: https://github.com/appcelerator/winreglib/blob/master/LICENSE [2]: https://www.npmjs.com/package/snooplogg diff --git a/biome.json b/biome.json new file mode 100644 index 0000000..fce092e --- /dev/null +++ b/biome.json @@ -0,0 +1,40 @@ +{ + "$schema": "https://biomejs.dev/schemas/1.7.3/schema.json", + "organizeImports": { + "enabled": true + }, + "files": { + "ignore": ["coverage/**", "dist/**"] + }, + "linter": { + "enabled": true, + "rules": { + "recommended": true, + "correctness": { + "noConstantCondition": "off", + "noConstructorReturn": "off" + }, + "performance": { + "noDelete": "off" + } + } + }, + "formatter": { + "enabled": true, + "indentStyle": "tab" + }, + "javascript": { + "formatter": { + "arrowParentheses": "asNeeded", + "quoteStyle": "single", + "semicolons": "always", + "trailingCommas": "none" + } + }, + "json": { + "formatter": { + "indentStyle": "space", + "indentWidth": 2 + } + } +} diff --git a/lefthook.yml b/lefthook.yml new file mode 100644 index 0000000..25796b0 --- /dev/null +++ b/lefthook.yml @@ -0,0 +1,6 @@ +pre-commit: + parallel: true + commands: + check: + glob: "*.{js,ts,jsx,tsx}" + run: pnpm check && git update-index --again diff --git a/package.json b/package.json index 171e361..47e6240 100644 --- a/package.json +++ b/package.json @@ -1,52 +1,70 @@ { - "name": "winreglib", - "version": "2.0.2", - "description": "Windows Registry Utility Library", - "main": "./src/index", - "gypfile": true, - "author": "Axway, Inc. ", - "maintainers": [ - "Chris Barber " - ], - "license": "Apache-2.0", - "keywords": [ - "appcelerator", - "windows", - "windows registry", - "winreg", - "microsoft" - ], - "scripts": { - "install": "node -e \"process.platform === 'win32' && require('node-gyp-build/bin.js')\"", - "prepublishOnly": "npm run prebuild && npm run prebuild-ia32", - "prebuild": "prebuildify --napi=true --strip", - "prebuild-ia32": "prebuildify --napi=true --strip --arch=ia32", - "build": "node-gyp -j 16 build", - "build-debug": "node-gyp -j 16 build --debug", - "clean": "node-gyp clean", - "rebuild": "node-gyp -j 16 rebuild", - "rebuild-debug": "node-gyp -j 16 rebuild --debug", - "test": "set JUNIT_REPORT_PATH=junit.xml&& mocha -r chai --reporter mocha-jenkins-reporter test/**/test-*.js" - }, - "dependencies": { - "napi-macros": "^2.0.0", - "node-gyp": "^7.1.2", - "node-gyp-build": "^4.2.3", - "snooplogg": "^3.0.1" - }, - "devDependencies": { - "chai": "^4.2.0", - "mocha": "^8.2.1", - "mocha-jenkins-reporter": "^0.4.5", - "prebuildify": "^4.1.1" - }, - "homepage": "https://github.com/appcelerator/winreglib", - "bugs": "https://github.com/appcelerator/winreglib/issues", - "repository": { - "type": "git", - "url": "git://github.com/appcelerator/winreglib.git" - }, - "engines": { - "node": ">=10.2.0" - } + "name": "winreglib", + "version": "4.0.0", + "description": "Windows Registry utility library", + "type": "module", + "exports": "./dist/index.js", + "types": "./dist/index.d.js", + "gypfile": true, + "author": "TiDev, Inc. ", + "license": "Apache-2.0", + "keywords": ["windows", "windows registry", "winreg", "microsoft"], + "scripts": { + "build": "pnpm build:bundle && pnpm build:types", + "build:prebuild": "pnpm prebuild-arm && pnpm prebuild-arm64 && pnpm prebuild-ia32 && pnpm prebuild-x64", + "build:bundle": "rimraf dist && rollup -c rollup.config.ts --configPlugin typescript", + "build:types": "pnpm build:types:temp && pnpm build:types:roll && pnpm build:types:check", + "build:types:temp": "tsc --declaration --emitDeclarationOnly --outDir temp --project tsconfig.build.json", + "build:types:roll": "rollup --config rollup.dts.config.ts --configPlugin typescript && rimraf temp", + "build:types:check": "tsc --project tsconfig.check.json", + "check": "biome check --write .", + "clean": "node-gyp clean", + "coverage": "vitest --coverage", + "install": "node -e \"process.exit(process.platform === 'win32' ? 0 : 1)\" && node-gyp-build", + "local:build": "node-gyp -j 20 build", + "local:build:debug": "node-gyp -j 20 build --debug", + "local:rebuild": "node-gyp -j 20 rebuild", + "local:rebuild:debug": "node-gyp -j 20 rebuild --debug", + "prepublishOnly": "pnpm build && pnpm build:prebuild", + "prebuild-arm": "prebuildify --napi --strip --platform='win32' --arch arm", + "prebuild-arm64": "prebuildify --napi --strip --platform='win32' --arch arm64", + "prebuild-ia32": "prebuildify --napi --strip --platform='win32' --arch ia32", + "prebuild-x64": "prebuildify --napi --strip --platform='win32' --arch x64", + "test": "vitest", + "type-check": "tsc --noEmit" + }, + "dependencies": { + "napi-macros": "2.2.2", + "node-gyp": "10.1.0", + "node-gyp-build": "4.8.1", + "snooplogg": "6.0.0-rc.1" + }, + "devDependencies": { + "@biomejs/biome": "1.8.3", + "@rollup/plugin-node-resolve": "15.2.3", + "@rollup/plugin-typescript": "11.1.6", + "@types/node": "20.14.9", + "@vitest/coverage-v8": "1.6.0", + "esbuild": "0.22.0", + "lefthook": "1.6.18", + "prebuildify": "6.0.1", + "rimraf": "5.0.7", + "rollup": "4.18.0", + "rollup-plugin-dts": "6.1.1", + "rollup-plugin-esbuild": "6.1.1", + "tslib": "2.6.3", + "typescript": "5.5.2", + "vitest": "1.6.0" + }, + "homepage": "https://github.com/tidev/winreglib", + "bugs": "https://github.com/tidev/winreglib/issues", + "repository": "https://github.com/tidev/winreglib", + "engines": { + "node": ">=18.17" + }, + "pnpm": { + "patchedDependencies": { + "node-gyp-build@4.8.1": "patches/node-gyp-build@4.8.1.patch" + } + } } diff --git a/patches/node-gyp-build@4.8.1.patch b/patches/node-gyp-build@4.8.1.patch new file mode 100644 index 0000000..f397b56 --- /dev/null +++ b/patches/node-gyp-build@4.8.1.patch @@ -0,0 +1,24 @@ +diff --git a/bin.js b/bin.js +index 7ca3ab5fd0babcfde234427387df4904b9e5f6f4..e2c6341228abc586bd5531b00e416269ce0a5947 100644 +--- a/bin.js ++++ b/bin.js +@@ -18,6 +18,7 @@ if (!buildFromSource()) { + function build () { + var win32 = os.platform() === 'win32' + var args = [win32 ? 'node-gyp.cmd' : 'node-gyp', 'rebuild'] ++ var shell = win32 + + try { + var pkg = require('node-gyp/package.json') +@@ -26,9 +27,10 @@ function build () { + path.join(require.resolve('node-gyp/package.json'), '..', typeof pkg.bin === 'string' ? pkg.bin : pkg.bin['node-gyp']), + 'rebuild' + ] ++ shell = false + } catch (_) {} + +- proc.spawn(args[0], args.slice(1), { stdio: 'inherit', shell: win32, windowsHide: true }).on('exit', function (code) { ++ proc.spawn(args[0], args.slice(1), { stdio: 'inherit', shell, windowsHide: true }).on('exit', function (code) { + if (code || !process.argv[3]) process.exit(code) + exec(process.argv[3]).on('exit', function (code) { + process.exit(code) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml new file mode 100644 index 0000000..c00d1bb --- /dev/null +++ b/pnpm-lock.yaml @@ -0,0 +1,2879 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +patchedDependencies: + node-gyp-build@4.8.1: + hash: caauzub3lunughu5goi7nkusjm + path: patches/node-gyp-build@4.8.1.patch + +importers: + + .: + dependencies: + napi-macros: + specifier: 2.2.2 + version: 2.2.2 + node-gyp: + specifier: 10.1.0 + version: 10.1.0 + node-gyp-build: + specifier: 4.8.1 + version: 4.8.1(patch_hash=caauzub3lunughu5goi7nkusjm) + snooplogg: + specifier: 6.0.0-rc.1 + version: 6.0.0-rc.1 + devDependencies: + '@biomejs/biome': + specifier: 1.8.3 + version: 1.8.3 + '@rollup/plugin-node-resolve': + specifier: 15.2.3 + version: 15.2.3(rollup@4.18.0) + '@rollup/plugin-typescript': + specifier: 11.1.6 + version: 11.1.6(rollup@4.18.0)(tslib@2.6.3)(typescript@5.5.2) + '@types/node': + specifier: 20.14.9 + version: 20.14.9 + '@vitest/coverage-v8': + specifier: 1.6.0 + version: 1.6.0(vitest@1.6.0(@types/node@20.14.9)) + esbuild: + specifier: 0.22.0 + version: 0.22.0 + lefthook: + specifier: 1.6.18 + version: 1.6.18 + prebuildify: + specifier: 6.0.1 + version: 6.0.1 + rimraf: + specifier: 5.0.7 + version: 5.0.7 + rollup: + specifier: 4.18.0 + version: 4.18.0 + rollup-plugin-dts: + specifier: 6.1.1 + version: 6.1.1(rollup@4.18.0)(typescript@5.5.2) + rollup-plugin-esbuild: + specifier: 6.1.1 + version: 6.1.1(esbuild@0.22.0)(rollup@4.18.0) + tslib: + specifier: 2.6.3 + version: 2.6.3 + typescript: + specifier: 5.5.2 + version: 5.5.2 + vitest: + specifier: 1.6.0 + version: 1.6.0(@types/node@20.14.9) + +packages: + + '@ampproject/remapping@2.3.0': + resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} + engines: {node: '>=6.0.0'} + + '@babel/code-frame@7.24.7': + resolution: {integrity: sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==} + engines: {node: '>=6.9.0'} + + '@babel/helper-string-parser@7.24.7': + resolution: {integrity: sha512-7MbVt6xrwFQbunH2DNQsAP5sTGxfqQtErvBIvIMi6EQnbgUOuVYanvREcmFrOPhoXBrTtjhhP+lW+o5UfK+tDg==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-identifier@7.24.7': + resolution: {integrity: sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==} + engines: {node: '>=6.9.0'} + + '@babel/highlight@7.24.7': + resolution: {integrity: sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==} + engines: {node: '>=6.9.0'} + + '@babel/parser@7.24.7': + resolution: {integrity: sha512-9uUYRm6OqQrCqQdG1iCBwBPZgN8ciDBro2nIOFaiRz1/BCxaI7CNvQbDHvsArAC7Tw9Hda/B3U+6ui9u4HWXPw==} + engines: {node: '>=6.0.0'} + hasBin: true + + '@babel/types@7.24.7': + resolution: {integrity: sha512-XEFXSlxiG5td2EJRe8vOmRbaXVgfcBlszKujvVmWIK/UpywWljQCfzAv3RQCGujWQ1RD4YYWEAqDXfuJiy8f5Q==} + engines: {node: '>=6.9.0'} + + '@bcoe/v8-coverage@0.2.3': + resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==} + + '@biomejs/biome@1.8.3': + resolution: {integrity: sha512-/uUV3MV+vyAczO+vKrPdOW0Iaet7UnJMU4bNMinggGJTAnBPjCoLEYcyYtYHNnUNYlv4xZMH6hVIQCAozq8d5w==} + engines: {node: '>=14.21.3'} + hasBin: true + + '@biomejs/cli-darwin-arm64@1.8.3': + resolution: {integrity: sha512-9DYOjclFpKrH/m1Oz75SSExR8VKvNSSsLnVIqdnKexj6NwmiMlKk94Wa1kZEdv6MCOHGHgyyoV57Cw8WzL5n3A==} + engines: {node: '>=14.21.3'} + cpu: [arm64] + os: [darwin] + + '@biomejs/cli-darwin-x64@1.8.3': + resolution: {integrity: sha512-UeW44L/AtbmOF7KXLCoM+9PSgPo0IDcyEUfIoOXYeANaNXXf9mLUwV1GeF2OWjyic5zj6CnAJ9uzk2LT3v/wAw==} + engines: {node: '>=14.21.3'} + cpu: [x64] + os: [darwin] + + '@biomejs/cli-linux-arm64-musl@1.8.3': + resolution: {integrity: sha512-9yjUfOFN7wrYsXt/T/gEWfvVxKlnh3yBpnScw98IF+oOeCYb5/b/+K7YNqKROV2i1DlMjg9g/EcN9wvj+NkMuQ==} + engines: {node: '>=14.21.3'} + cpu: [arm64] + os: [linux] + + '@biomejs/cli-linux-arm64@1.8.3': + resolution: {integrity: sha512-fed2ji8s+I/m8upWpTJGanqiJ0rnlHOK3DdxsyVLZQ8ClY6qLuPc9uehCREBifRJLl/iJyQpHIRufLDeotsPtw==} + engines: {node: '>=14.21.3'} + cpu: [arm64] + os: [linux] + + '@biomejs/cli-linux-x64-musl@1.8.3': + resolution: {integrity: sha512-UHrGJX7PrKMKzPGoEsooKC9jXJMa28TUSMjcIlbDnIO4EAavCoVmNQaIuUSH0Ls2mpGMwUIf+aZJv657zfWWjA==} + engines: {node: '>=14.21.3'} + cpu: [x64] + os: [linux] + + '@biomejs/cli-linux-x64@1.8.3': + resolution: {integrity: sha512-I8G2QmuE1teISyT8ie1HXsjFRz9L1m5n83U1O6m30Kw+kPMPSKjag6QGUn+sXT8V+XWIZxFFBoTDEDZW2KPDDw==} + engines: {node: '>=14.21.3'} + cpu: [x64] + os: [linux] + + '@biomejs/cli-win32-arm64@1.8.3': + resolution: {integrity: sha512-J+Hu9WvrBevfy06eU1Na0lpc7uR9tibm9maHynLIoAjLZpQU3IW+OKHUtyL8p6/3pT2Ju5t5emReeIS2SAxhkQ==} + engines: {node: '>=14.21.3'} + cpu: [arm64] + os: [win32] + + '@biomejs/cli-win32-x64@1.8.3': + resolution: {integrity: sha512-/PJ59vA1pnQeKahemaQf4Nyj7IKUvGQSc3Ze1uIGi+Wvr1xF7rGobSrAAG01T/gUDG21vkDsZYM03NAmPiVkqg==} + engines: {node: '>=14.21.3'} + cpu: [x64] + os: [win32] + + '@esbuild/aix-ppc64@0.21.5': + resolution: {integrity: sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [aix] + + '@esbuild/aix-ppc64@0.22.0': + resolution: {integrity: sha512-uvQR2crZ/zgzSHDvdygHyNI+ze9zwS8mqz0YtGXotSqvEE0UkYE9s+FZKQNTt1VtT719mfP3vHrUdCpxBNQZhQ==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + + '@esbuild/android-arm64@0.21.5': + resolution: {integrity: sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm64@0.22.0': + resolution: {integrity: sha512-UKhPb3o2gAB/bfXcl58ZXTn1q2oVu1rEu/bKrCtmm+Nj5MKUbrOwR5WAixE2v+lk0amWuwPvhnPpBRLIGiq7ig==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm@0.21.5': + resolution: {integrity: sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==} + engines: {node: '>=12'} + cpu: [arm] + os: [android] + + '@esbuild/android-arm@0.22.0': + resolution: {integrity: sha512-PBnyP+r8vJE4ifxsWys9l+Mc2UY/yYZOpX82eoyGISXXb3dRr0M21v+s4fgRKWMFPMSf/iyowqPW/u7ScSUkjQ==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + + '@esbuild/android-x64@0.21.5': + resolution: {integrity: sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==} + engines: {node: '>=12'} + cpu: [x64] + os: [android] + + '@esbuild/android-x64@0.22.0': + resolution: {integrity: sha512-IjTYtvIrjhR41Ijy2dDPgYjQHWG/x/A4KXYbs1fiU3efpRdoxMChK3oEZV6GPzVEzJqxFgcuBaiX1kwEvWUxSw==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + + '@esbuild/darwin-arm64@0.21.5': + resolution: {integrity: sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-arm64@0.22.0': + resolution: {integrity: sha512-mqt+Go4y9wRvEz81bhKd9RpHsQR1LwU8Xm6jZRUV/xpM7cIQFbFH6wBCLPTNsdELBvfoHeumud7X78jQQJv2TA==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-x64@0.21.5': + resolution: {integrity: sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + + '@esbuild/darwin-x64@0.22.0': + resolution: {integrity: sha512-vTaTQ9OgYc3VTaWtOE5pSuDT6H3d/qSRFRfSBbnxFfzAvYoB3pqKXA0LEbi/oT8GUOEAutspfRMqPj2ezdFaMw==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + + '@esbuild/freebsd-arm64@0.21.5': + resolution: {integrity: sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-arm64@0.22.0': + resolution: {integrity: sha512-0e1ZgoobJzaGnR4reD7I9rYZ7ttqdh1KPvJWnquUoDJhL0rYwdneeLailBzd2/4g/U5p4e5TIHEWa68NF2hFpQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.21.5': + resolution: {integrity: sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.22.0': + resolution: {integrity: sha512-BFgyYwlCwRWyPQJtkzqq2p6pJbiiWgp0P9PNf7a5FQ1itKY4czPuOMAlFVItirSmEpRPCeImuwePNScZS0pL5Q==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + + '@esbuild/linux-arm64@0.21.5': + resolution: {integrity: sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm64@0.22.0': + resolution: {integrity: sha512-V/K2rctCUgC0PCXpN7AqT4hoazXKgIYugFGu/myk2+pfe6jTW2guz/TBwq4cZ7ESqusR/IzkcQaBkcjquuBWsw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm@0.21.5': + resolution: {integrity: sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-arm@0.22.0': + resolution: {integrity: sha512-KEMWiA9aGuPUD4BH5yjlhElLgaRXe+Eri6gKBoDazoPBTo1BXc/e6IW5FcJO9DoL19FBeCxgONyh95hLDNepIg==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-ia32@0.21.5': + resolution: {integrity: sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-ia32@0.22.0': + resolution: {integrity: sha512-r2ZZqkOMOrpUhzNwxI7uLAHIDwkfeqmTnrv1cjpL/rjllPWszgqmprd/om9oviKXUBpMqHbXmppvjAYgISb26Q==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-loong64@0.21.5': + resolution: {integrity: sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==} + engines: {node: '>=12'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-loong64@0.22.0': + resolution: {integrity: sha512-qaowLrV/YOMAL2RfKQ4C/VaDzAuLDuylM2sd/LH+4OFirMl6CuDpRlCq4u49ZBaVV8pkI/Y+hTdiibvQRhojCA==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-mips64el@0.21.5': + resolution: {integrity: sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-mips64el@0.22.0': + resolution: {integrity: sha512-hgrezzjQTRxjkQ5k08J6rtZN5PNnkWx/Rz6Kmj9gnsdCAX1I4Dn4ZPqvFRkXo55Q3pnVQJBwbdtrTO7tMGtyVA==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-ppc64@0.21.5': + resolution: {integrity: sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-ppc64@0.22.0': + resolution: {integrity: sha512-ewxg6FLLUio883XgSjfULEmDl3VPv/TYNnRprVAS3QeGFLdCYdx1tIudBcd7n9jIdk82v1Ajov4jx87qW7h9+g==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-riscv64@0.21.5': + resolution: {integrity: sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-riscv64@0.22.0': + resolution: {integrity: sha512-Az5XbgSJC2lE8XK8pdcutsf9RgdafWdTpUK/+6uaDdfkviw/B4JCwAfh1qVeRWwOohwdsl4ywZrWBNWxwrPLFg==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-s390x@0.21.5': + resolution: {integrity: sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-s390x@0.22.0': + resolution: {integrity: sha512-8j4a2ChT9+V34NNNY9c/gMldutaJFmfMacTPq4KfNKwv2fitBCLYjee7c+Vxaha2nUhPK7cXcZpJtJ3+Y7ZdVQ==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-x64@0.21.5': + resolution: {integrity: sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + + '@esbuild/linux-x64@0.22.0': + resolution: {integrity: sha512-JUQyOnpbAkkRFOk/AhsEemz5TfWN4FJZxVObUlnlNCbe7QBl61ZNfM4cwBXayQA6laMJMUcqLHaYQHAB6YQ95Q==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + + '@esbuild/netbsd-x64@0.21.5': + resolution: {integrity: sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + + '@esbuild/netbsd-x64@0.22.0': + resolution: {integrity: sha512-11PoCoHXo4HFNbLsXuMB6bpMPWGDiw7xETji6COdJss4SQZLvcgNoeSqWtATRm10Jj1uEHiaIk4N0PiN6x4Fcg==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + + '@esbuild/openbsd-arm64@0.22.0': + resolution: {integrity: sha512-Ezlhu/YyITmXwKSB+Zu/QqD7cxrjrpiw85cc0Rbd3AWr2wsgp+dWbWOE8MqHaLW9NKMZvuL0DhbJbvzR7F6Zvg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + + '@esbuild/openbsd-x64@0.21.5': + resolution: {integrity: sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + + '@esbuild/openbsd-x64@0.22.0': + resolution: {integrity: sha512-ufjdW5tFJGUjlH9j/5cCE9lrwRffyZh+T4vYvoDKoYsC6IXbwaFeV/ENxeNXcxotF0P8CDzoICXVSbJaGBhkrw==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + + '@esbuild/sunos-x64@0.21.5': + resolution: {integrity: sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + + '@esbuild/sunos-x64@0.22.0': + resolution: {integrity: sha512-zY6ly/AoSmKnmNTowDJsK5ehra153/5ZhqxNLfq9NRsTTltetr+yHHcQ4RW7QDqw4JC8A1uC1YmeSfK9NRcK1w==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + + '@esbuild/win32-arm64@0.21.5': + resolution: {integrity: sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-arm64@0.22.0': + resolution: {integrity: sha512-Kml5F7tv/1Maam0pbbCrvkk9vj046dPej30kFzlhXnhuCtYYBP6FGy/cLbc5yUT1lkZznGLf2OvuvmLjscO5rw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-ia32@0.21.5': + resolution: {integrity: sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-ia32@0.22.0': + resolution: {integrity: sha512-IOgwn+mYTM3RrcydP4Og5IpXh+ftN8oF+HELTXSmbWBlujuci4Qa3DTeO+LEErceisI7KUSfEIiX+WOUlpELkw==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-x64@0.21.5': + resolution: {integrity: sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + + '@esbuild/win32-x64@0.22.0': + resolution: {integrity: sha512-4bDHJrk2WHBXJPhy1y80X7/5b5iZTZP3LGcKIlAP1J+KqZ4zQAPMLEzftGyjjfcKbA4JDlPt/+2R/F1ZTeRgrw==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + + '@isaacs/cliui@8.0.2': + resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} + engines: {node: '>=12'} + + '@istanbuljs/schema@0.1.3': + resolution: {integrity: sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==} + engines: {node: '>=8'} + + '@jest/schemas@29.6.3': + resolution: {integrity: sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jridgewell/gen-mapping@0.3.5': + resolution: {integrity: sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==} + engines: {node: '>=6.0.0'} + + '@jridgewell/resolve-uri@3.1.2': + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} + engines: {node: '>=6.0.0'} + + '@jridgewell/set-array@1.2.1': + resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==} + engines: {node: '>=6.0.0'} + + '@jridgewell/sourcemap-codec@1.4.15': + resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==} + + '@jridgewell/trace-mapping@0.3.25': + resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} + + '@npmcli/agent@2.2.2': + resolution: {integrity: sha512-OrcNPXdpSl9UX7qPVRWbmWMCSXrcDa2M9DvrbOTj7ao1S4PlqVFYv9/yLKMkrJKZ/V5A/kDBC690or307i26Og==} + engines: {node: ^16.14.0 || >=18.0.0} + + '@npmcli/fs@3.1.1': + resolution: {integrity: sha512-q9CRWjpHCMIh5sVyefoD1cA7PkvILqCZsnSOEUUivORLjxCO/Irmue2DprETiNgEqktDBZaM1Bi+jrarx1XdCg==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + '@pkgjs/parseargs@0.11.0': + resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} + engines: {node: '>=14'} + + '@rollup/plugin-node-resolve@15.2.3': + resolution: {integrity: sha512-j/lym8nf5E21LwBT4Df1VD6hRO2L2iwUeUmP7litikRsVp1H6NWx20NEp0Y7su+7XGc476GnXXc4kFeZNGmaSQ==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^2.78.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + + '@rollup/plugin-typescript@11.1.6': + resolution: {integrity: sha512-R92yOmIACgYdJ7dJ97p4K69I8gg6IEHt8M7dUBxN3W6nrO8uUxX5ixl0yU/N3aZTi8WhPuICvOHXQvF6FaykAA==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^2.14.0||^3.0.0||^4.0.0 + tslib: '*' + typescript: '>=3.7.0' + peerDependenciesMeta: + rollup: + optional: true + tslib: + optional: true + + '@rollup/pluginutils@5.1.0': + resolution: {integrity: sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + + '@rollup/rollup-android-arm-eabi@4.18.0': + resolution: {integrity: sha512-Tya6xypR10giZV1XzxmH5wr25VcZSncG0pZIjfePT0OVBvqNEurzValetGNarVrGiq66EBVAFn15iYX4w6FKgQ==} + cpu: [arm] + os: [android] + + '@rollup/rollup-android-arm64@4.18.0': + resolution: {integrity: sha512-avCea0RAP03lTsDhEyfy+hpfr85KfyTctMADqHVhLAF3MlIkq83CP8UfAHUssgXTYd+6er6PaAhx/QGv4L1EiA==} + cpu: [arm64] + os: [android] + + '@rollup/rollup-darwin-arm64@4.18.0': + resolution: {integrity: sha512-IWfdwU7KDSm07Ty0PuA/W2JYoZ4iTj3TUQjkVsO/6U+4I1jN5lcR71ZEvRh52sDOERdnNhhHU57UITXz5jC1/w==} + cpu: [arm64] + os: [darwin] + + '@rollup/rollup-darwin-x64@4.18.0': + resolution: {integrity: sha512-n2LMsUz7Ynu7DoQrSQkBf8iNrjOGyPLrdSg802vk6XT3FtsgX6JbE8IHRvposskFm9SNxzkLYGSq9QdpLYpRNA==} + cpu: [x64] + os: [darwin] + + '@rollup/rollup-linux-arm-gnueabihf@4.18.0': + resolution: {integrity: sha512-C/zbRYRXFjWvz9Z4haRxcTdnkPt1BtCkz+7RtBSuNmKzMzp3ZxdM28Mpccn6pt28/UWUCTXa+b0Mx1k3g6NOMA==} + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm-musleabihf@4.18.0': + resolution: {integrity: sha512-l3m9ewPgjQSXrUMHg93vt0hYCGnrMOcUpTz6FLtbwljo2HluS4zTXFy2571YQbisTnfTKPZ01u/ukJdQTLGh9A==} + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm64-gnu@4.18.0': + resolution: {integrity: sha512-rJ5D47d8WD7J+7STKdCUAgmQk49xuFrRi9pZkWoRD1UeSMakbcepWXPF8ycChBoAqs1pb2wzvbY6Q33WmN2ftw==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-arm64-musl@4.18.0': + resolution: {integrity: sha512-be6Yx37b24ZwxQ+wOQXXLZqpq4jTckJhtGlWGZs68TgdKXJgw54lUUoFYrg6Zs/kjzAQwEwYbp8JxZVzZLRepQ==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-powerpc64le-gnu@4.18.0': + resolution: {integrity: sha512-hNVMQK+qrA9Todu9+wqrXOHxFiD5YmdEi3paj6vP02Kx1hjd2LLYR2eaN7DsEshg09+9uzWi2W18MJDlG0cxJA==} + cpu: [ppc64] + os: [linux] + + '@rollup/rollup-linux-riscv64-gnu@4.18.0': + resolution: {integrity: sha512-ROCM7i+m1NfdrsmvwSzoxp9HFtmKGHEqu5NNDiZWQtXLA8S5HBCkVvKAxJ8U+CVctHwV2Gb5VUaK7UAkzhDjlg==} + cpu: [riscv64] + os: [linux] + + '@rollup/rollup-linux-s390x-gnu@4.18.0': + resolution: {integrity: sha512-0UyyRHyDN42QL+NbqevXIIUnKA47A+45WyasO+y2bGJ1mhQrfrtXUpTxCOrfxCR4esV3/RLYyucGVPiUsO8xjg==} + cpu: [s390x] + os: [linux] + + '@rollup/rollup-linux-x64-gnu@4.18.0': + resolution: {integrity: sha512-xuglR2rBVHA5UsI8h8UbX4VJ470PtGCf5Vpswh7p2ukaqBGFTnsfzxUBetoWBWymHMxbIG0Cmx7Y9qDZzr648w==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-linux-x64-musl@4.18.0': + resolution: {integrity: sha512-LKaqQL9osY/ir2geuLVvRRs+utWUNilzdE90TpyoX0eNqPzWjRm14oMEE+YLve4k/NAqCdPkGYDaDF5Sw+xBfg==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-win32-arm64-msvc@4.18.0': + resolution: {integrity: sha512-7J6TkZQFGo9qBKH0pk2cEVSRhJbL6MtfWxth7Y5YmZs57Pi+4x6c2dStAUvaQkHQLnEQv1jzBUW43GvZW8OFqA==} + cpu: [arm64] + os: [win32] + + '@rollup/rollup-win32-ia32-msvc@4.18.0': + resolution: {integrity: sha512-Txjh+IxBPbkUB9+SXZMpv+b/vnTEtFyfWZgJ6iyCmt2tdx0OF5WhFowLmnh8ENGNpfUlUZkdI//4IEmhwPieNg==} + cpu: [ia32] + os: [win32] + + '@rollup/rollup-win32-x64-msvc@4.18.0': + resolution: {integrity: sha512-UOo5FdvOL0+eIVTgS4tIdbW+TtnBLWg1YBCcU2KWM7nuNwRz9bksDX1bekJJCpu25N1DVWaCwnT39dVQxzqS8g==} + cpu: [x64] + os: [win32] + + '@sinclair/typebox@0.27.8': + resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==} + + '@types/estree@1.0.5': + resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==} + + '@types/node@20.14.9': + resolution: {integrity: sha512-06OCtnTXtWOZBJlRApleWndH4JsRVs1pDCc8dLSQp+7PpUpX3ePdHyeNSFTeSe7FtKyQkrlPvHwJOW3SLd8Oyg==} + + '@types/resolve@1.20.2': + resolution: {integrity: sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==} + + '@vitest/coverage-v8@1.6.0': + resolution: {integrity: sha512-KvapcbMY/8GYIG0rlwwOKCVNRc0OL20rrhFkg/CHNzncV03TE2XWvO5w9uZYoxNiMEBacAJt3unSOiZ7svePew==} + peerDependencies: + vitest: 1.6.0 + + '@vitest/expect@1.6.0': + resolution: {integrity: sha512-ixEvFVQjycy/oNgHjqsL6AZCDduC+tflRluaHIzKIsdbzkLn2U/iBnVeJwB6HsIjQBdfMR8Z0tRxKUsvFJEeWQ==} + + '@vitest/runner@1.6.0': + resolution: {integrity: sha512-P4xgwPjwesuBiHisAVz/LSSZtDjOTPYZVmNAnpHHSR6ONrf8eCJOFRvUwdHn30F5M1fxhqtl7QZQUk2dprIXAg==} + + '@vitest/snapshot@1.6.0': + resolution: {integrity: sha512-+Hx43f8Chus+DCmygqqfetcAZrDJwvTj0ymqjQq4CvmpKFSTVteEOBzCusu1x2tt4OJcvBflyHUE0DZSLgEMtQ==} + + '@vitest/spy@1.6.0': + resolution: {integrity: sha512-leUTap6B/cqi/bQkXUu6bQV5TZPx7pmMBKBQiI0rJA8c3pB56ZsaTbREnF7CJfmvAS4V2cXIBAh/3rVwrrCYgw==} + + '@vitest/utils@1.6.0': + resolution: {integrity: sha512-21cPiuGMoMZwiOHa2i4LXkMkMkCGzA+MVFV70jRwHo95dL4x/ts5GZhML1QWuy7yfp3WzK3lRvZi3JnXTYqrBw==} + + abbrev@2.0.0: + resolution: {integrity: sha512-6/mh1E2u2YgEsCHdY0Yx5oW+61gZU+1vXaoiHHrpKeuRNNgFvS+/jrwHiQhB5apAf5oB7UB7E19ol2R2LKH8hQ==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + acorn-walk@8.3.3: + resolution: {integrity: sha512-MxXdReSRhGO7VlFe1bRG/oI7/mdLV9B9JJT0N8vZOhF7gFRR5l3M8W9G8JxmKV+JC5mGqJ0QvqfSOLsCPa4nUw==} + engines: {node: '>=0.4.0'} + + acorn@8.12.0: + resolution: {integrity: sha512-RTvkC4w+KNXrM39/lWCUaG0IbRkWdCv7W/IOW9oU6SawyxulvkQy5HQPVTKxEjczcUvapcrw3cFx/60VN/NRNw==} + engines: {node: '>=0.4.0'} + hasBin: true + + agent-base@7.1.1: + resolution: {integrity: sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==} + engines: {node: '>= 14'} + + aggregate-error@3.1.0: + resolution: {integrity: sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==} + engines: {node: '>=8'} + + ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + + ansi-regex@6.0.1: + resolution: {integrity: sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==} + engines: {node: '>=12'} + + ansi-styles@3.2.1: + resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} + engines: {node: '>=4'} + + ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + + ansi-styles@5.2.0: + resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==} + engines: {node: '>=10'} + + ansi-styles@6.2.1: + resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} + engines: {node: '>=12'} + + assertion-error@1.1.0: + resolution: {integrity: sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==} + + balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + + base64-js@1.5.1: + resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} + + bl@4.1.0: + resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==} + + brace-expansion@1.1.11: + resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} + + brace-expansion@2.0.1: + resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} + + buffer@5.7.1: + resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==} + + builtin-modules@3.3.0: + resolution: {integrity: sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==} + engines: {node: '>=6'} + + cac@6.7.14: + resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} + engines: {node: '>=8'} + + cacache@18.0.3: + resolution: {integrity: sha512-qXCd4rh6I07cnDqh8V48/94Tc/WSfj+o3Gn6NZ0aZovS255bUx8O13uKxRFd2eWG0xgsco7+YItQNPaa5E85hg==} + engines: {node: ^16.14.0 || >=18.0.0} + + chai@4.4.1: + resolution: {integrity: sha512-13sOfMv2+DWduEU+/xbun3LScLoqN17nBeTLUsmDfKdoiC1fr0n9PU4guu4AhRcOVFk/sW8LyZWHuhWtQZiF+g==} + engines: {node: '>=4'} + + chalk@2.4.2: + resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} + engines: {node: '>=4'} + + check-error@1.0.3: + resolution: {integrity: sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==} + + chownr@1.1.4: + resolution: {integrity: sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==} + + chownr@2.0.0: + resolution: {integrity: sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==} + engines: {node: '>=10'} + + clean-stack@2.2.0: + resolution: {integrity: sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==} + engines: {node: '>=6'} + + color-convert@1.9.3: + resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} + + color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + + color-name@1.1.3: + resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==} + + color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + + concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + + confbox@0.1.7: + resolution: {integrity: sha512-uJcB/FKZtBMCJpK8MQji6bJHgu1tixKPxRLeGkNzBoOZzpnZUJm0jm2/sBDWcuBx1dYgxV4JU+g5hmNxCyAmdA==} + + cross-spawn@7.0.3: + resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} + engines: {node: '>= 8'} + + debug@4.3.5: + resolution: {integrity: sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + deep-eql@4.1.4: + resolution: {integrity: sha512-SUwdGfqdKOwxCPeVYjwSyRpJ7Z+fhpwIAtmCUdZIWZ/YP5R9WAsyuSgpLVDi9bjWoN2LXHNss/dk3urXtdQxGg==} + engines: {node: '>=6'} + + deepmerge@4.3.1: + resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} + engines: {node: '>=0.10.0'} + + diff-sequences@29.6.3: + resolution: {integrity: sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + eastasianwidth@0.2.0: + resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} + + emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + + emoji-regex@9.2.2: + resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} + + encoding@0.1.13: + resolution: {integrity: sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==} + + end-of-stream@1.4.4: + resolution: {integrity: sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==} + + env-paths@2.2.1: + resolution: {integrity: sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==} + engines: {node: '>=6'} + + err-code@2.0.3: + resolution: {integrity: sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==} + + es-module-lexer@1.5.4: + resolution: {integrity: sha512-MVNK56NiMrOwitFB7cqDwq0CQutbw+0BvLshJSse0MUNU+y1FC3bUS/AQg7oUng+/wKrrki7JfmwtVHkVfPLlw==} + + esbuild@0.21.5: + resolution: {integrity: sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==} + engines: {node: '>=12'} + hasBin: true + + esbuild@0.22.0: + resolution: {integrity: sha512-zNYA6bFZsVnsU481FnGAQjLDW0Pl/8BGG7EvAp15RzUvGC+ME7hf1q7LvIfStEQBz/iEHuBJCYcOwPmNCf1Tlw==} + engines: {node: '>=18'} + hasBin: true + + escape-string-regexp@1.0.5: + resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} + engines: {node: '>=0.8.0'} + + estree-walker@2.0.2: + resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} + + estree-walker@3.0.3: + resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} + + execa@8.0.1: + resolution: {integrity: sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==} + engines: {node: '>=16.17'} + + exponential-backoff@3.1.1: + resolution: {integrity: sha512-dX7e/LHVJ6W3DE1MHWi9S1EYzDESENfLrYohG2G++ovZrYOkm4Knwa0mc1cn84xJOR4KEU0WSchhLbd0UklbHw==} + + foreground-child@3.2.1: + resolution: {integrity: sha512-PXUUyLqrR2XCWICfv6ukppP96sdFwWbNEnfEMt7jNsISjMsvaLNinAHNDYyvkyU+SZG2BTSbT5NjG+vZslfGTA==} + engines: {node: '>=14'} + + fs-constants@1.0.0: + resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==} + + fs-minipass@2.1.0: + resolution: {integrity: sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==} + engines: {node: '>= 8'} + + fs-minipass@3.0.3: + resolution: {integrity: sha512-XUBA9XClHbnJWSfBzjkm6RvPsyg3sryZt06BEQoXcF7EK/xpGaQYJgQKDJSUH5SGZ76Y7pFx1QBnXz09rU5Fbw==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + fs.realpath@1.0.0: + resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} + + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + + function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + + get-func-name@2.0.2: + resolution: {integrity: sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==} + + get-stream@8.0.1: + resolution: {integrity: sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==} + engines: {node: '>=16'} + + get-tsconfig@4.7.5: + resolution: {integrity: sha512-ZCuZCnlqNzjb4QprAzXKdpp/gh6KTxSJuw3IBsPnV/7fV4NxC9ckB+vPTt8w7fJA0TaSD7c55BR47JD6MEDyDw==} + + glob@10.4.2: + resolution: {integrity: sha512-GwMlUF6PkPo3Gk21UxkCohOv0PLcIXVtKyLlpEI28R/cO/4eNOdmLk3CMW1wROV/WR/EsZOWAfBbBOqYvs88/w==} + engines: {node: '>=16 || 14 >=14.18'} + hasBin: true + + glob@7.2.3: + resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} + deprecated: Glob versions prior to v9 are no longer supported + + graceful-fs@4.2.11: + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + + has-flag@3.0.0: + resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} + engines: {node: '>=4'} + + has-flag@4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + + hasown@2.0.2: + resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} + engines: {node: '>= 0.4'} + + html-escaper@2.0.2: + resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} + + http-cache-semantics@4.1.1: + resolution: {integrity: sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==} + + http-proxy-agent@7.0.2: + resolution: {integrity: sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==} + engines: {node: '>= 14'} + + https-proxy-agent@7.0.4: + resolution: {integrity: sha512-wlwpilI7YdjSkWaQ/7omYBMTliDcmCN8OLihO6I9B86g06lMyAoqgoDpV0XqoaPOKj+0DIdAvnsWfyAAhmimcg==} + engines: {node: '>= 14'} + + human-signals@5.0.0: + resolution: {integrity: sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==} + engines: {node: '>=16.17.0'} + + iconv-lite@0.6.3: + resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} + engines: {node: '>=0.10.0'} + + ieee754@1.2.1: + resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} + + imurmurhash@0.1.4: + resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} + engines: {node: '>=0.8.19'} + + indent-string@4.0.0: + resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==} + engines: {node: '>=8'} + + inflight@1.0.6: + resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} + deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful. + + inherits@2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + + ip-address@9.0.5: + resolution: {integrity: sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==} + engines: {node: '>= 12'} + + is-builtin-module@3.2.1: + resolution: {integrity: sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==} + engines: {node: '>=6'} + + is-core-module@2.14.0: + resolution: {integrity: sha512-a5dFJih5ZLYlRtDc0dZWP7RiKr6xIKzmn/oAYCDvdLThadVgyJwlaoQPmRtMSpz+rk0OGAgIu+TcM9HUF0fk1A==} + engines: {node: '>= 0.4'} + + is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + + is-lambda@1.0.1: + resolution: {integrity: sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==} + + is-module@1.0.0: + resolution: {integrity: sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==} + + is-stream@3.0.0: + resolution: {integrity: sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + + isexe@3.1.1: + resolution: {integrity: sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==} + engines: {node: '>=16'} + + istanbul-lib-coverage@3.2.2: + resolution: {integrity: sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==} + engines: {node: '>=8'} + + istanbul-lib-report@3.0.1: + resolution: {integrity: sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==} + engines: {node: '>=10'} + + istanbul-lib-source-maps@5.0.4: + resolution: {integrity: sha512-wHOoEsNJTVltaJp8eVkm8w+GVkVNHT2YDYo53YdzQEL2gWm1hBX5cGFR9hQJtuGLebidVX7et3+dmDZrmclduw==} + engines: {node: '>=10'} + + istanbul-reports@3.1.7: + resolution: {integrity: sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==} + engines: {node: '>=8'} + + jackspeak@3.4.0: + resolution: {integrity: sha512-JVYhQnN59LVPFCEcVa2C3CrEKYacvjRfqIQl+h8oi91aLYQVWRYbxjPcv1bUiUy/kLmQaANrYfNMCO3kuEDHfw==} + engines: {node: '>=14'} + + js-tokens@4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + + js-tokens@9.0.0: + resolution: {integrity: sha512-WriZw1luRMlmV3LGJaR6QOJjWwgLUTf89OwT2lUOyjX2dJGBwgmIkbcz+7WFZjrZM635JOIR517++e/67CP9dQ==} + + jsbn@1.1.0: + resolution: {integrity: sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==} + + lefthook-darwin-arm64@1.6.18: + resolution: {integrity: sha512-AkpsTeO7aLZIIy6CKQ7Chx8RltE8a9uItbwQWoeaCkIdzpV8TFjq7/Pw4F5CkoJ2315sHtB8k+VFkgipQMBw1w==} + cpu: [arm64] + os: [darwin] + + lefthook-darwin-x64@1.6.18: + resolution: {integrity: sha512-qwKa+PaNIYjZ2PVrRRLq+HjNjQsjEItXN21byvSD89r7EYCULsIC8aW4H6aniOP2A6X1DIZ+djpg+3hNJ/94NA==} + cpu: [x64] + os: [darwin] + + lefthook-freebsd-arm64@1.6.18: + resolution: {integrity: sha512-UIOzQ+okwB7Ah9p8sNqomOiU6cPfmJnyW3HDPutRsdoHRD8udIap9d+ja4Kg4m/PkoYtkcLO78omANqAgA5wxQ==} + cpu: [arm64] + os: [freebsd] + + lefthook-freebsd-x64@1.6.18: + resolution: {integrity: sha512-UQANUgyNpaAh0+2/PjPFiJ7yd6aF15yyJxKZCXyna5cQF7VU8pSHu5tiDDquNpjToXOg+6TmiIAJKyfrrwTF3w==} + cpu: [x64] + os: [freebsd] + + lefthook-linux-arm64@1.6.18: + resolution: {integrity: sha512-4erletIa2HKUgY17/1ROvndAj6xn/9wkqO2GhBT3C0vFwIv6ycy5wpFzXOwKRZpFYv7UacN7iXhAZSK+vSOZZg==} + cpu: [arm64] + os: [linux] + + lefthook-linux-x64@1.6.18: + resolution: {integrity: sha512-l5SRqYMYygw9RjZncEg8uh29wShYN8kiYr53sp74DkntrlCttqWhLILBUlIr3fxH5s0ZyrmqUEjtMBryMk7b/g==} + cpu: [x64] + os: [linux] + + lefthook-windows-arm64@1.6.18: + resolution: {integrity: sha512-jeNBRoya3+mOEsKyT4wXf29Kng1nkJD7Uv/dqGBszoGMktGVNUFdIjWoxx6HSfhUssucs5pKRZpXSMgK/KCP+Q==} + cpu: [arm64] + os: [win32] + + lefthook-windows-x64@1.6.18: + resolution: {integrity: sha512-iEG8PbFOwMqlpAgCiqzANTxutERjwlwMx6WF6HDGEYwFJSCJsvi06TehDxaPIFbhmLLYYlbVrfSBlttWGoN0dg==} + cpu: [x64] + os: [win32] + + lefthook@1.6.18: + resolution: {integrity: sha512-Ftr/NkU1P1EsEyphsCqCX7lesGZA+QDXyUx4dS1RlSKB72xKtGW9VPjbGLK2kSQkONG5M+XYfbJkGA/r9NLTYQ==} + hasBin: true + + local-pkg@0.5.0: + resolution: {integrity: sha512-ok6z3qlYyCDS4ZEU27HaU6x/xZa9Whf8jD4ptH5UZTQYZVYeb9bnZ3ojVhiJNLiXK1Hfc0GNbLXcmZ5plLDDBg==} + engines: {node: '>=14'} + + loupe@2.3.7: + resolution: {integrity: sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==} + + lru-cache@10.2.2: + resolution: {integrity: sha512-9hp3Vp2/hFQUiIwKo8XCeFVnrg8Pk3TYNPIR7tJADKi5YfcF7vEaK7avFHTlSy3kOKYaJQaalfEo6YuXdceBOQ==} + engines: {node: 14 || >=16.14} + + magic-string@0.30.10: + resolution: {integrity: sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==} + + magicast@0.3.4: + resolution: {integrity: sha512-TyDF/Pn36bBji9rWKHlZe+PZb6Mx5V8IHCSxk7X4aljM4e/vyDvZZYwHewdVaqiA0nb3ghfHU/6AUpDxWoER2Q==} + + make-dir@4.0.0: + resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==} + engines: {node: '>=10'} + + make-fetch-happen@13.0.1: + resolution: {integrity: sha512-cKTUFc/rbKUd/9meOvgrpJ2WrNzymt6jfRDdwg5UCnVzv9dTpEj9JS5m3wtziXVCjluIXyL8pcaukYqezIzZQA==} + engines: {node: ^16.14.0 || >=18.0.0} + + merge-stream@2.0.0: + resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} + + mimic-fn@4.0.0: + resolution: {integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==} + engines: {node: '>=12'} + + minimatch@3.1.2: + resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + + minimatch@9.0.5: + resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} + engines: {node: '>=16 || 14 >=14.17'} + + minimist@1.2.8: + resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + + minipass-collect@2.0.1: + resolution: {integrity: sha512-D7V8PO9oaz7PWGLbCACuI1qEOsq7UKfLotx/C0Aet43fCUB/wfQ7DYeq2oR/svFJGYDHPr38SHATeaj/ZoKHKw==} + engines: {node: '>=16 || 14 >=14.17'} + + minipass-fetch@3.0.5: + resolution: {integrity: sha512-2N8elDQAtSnFV0Dk7gt15KHsS0Fyz6CbYZ360h0WTYV1Ty46li3rAXVOQj1THMNLdmrD9Vt5pBPtWtVkpwGBqg==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + minipass-flush@1.0.5: + resolution: {integrity: sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==} + engines: {node: '>= 8'} + + minipass-pipeline@1.2.4: + resolution: {integrity: sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==} + engines: {node: '>=8'} + + minipass-sized@1.0.3: + resolution: {integrity: sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==} + engines: {node: '>=8'} + + minipass@3.3.6: + resolution: {integrity: sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==} + engines: {node: '>=8'} + + minipass@5.0.0: + resolution: {integrity: sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==} + engines: {node: '>=8'} + + minipass@7.1.2: + resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} + engines: {node: '>=16 || 14 >=14.17'} + + minizlib@2.1.2: + resolution: {integrity: sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==} + engines: {node: '>= 8'} + + mkdirp-classic@0.5.3: + resolution: {integrity: sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==} + + mkdirp@1.0.4: + resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==} + engines: {node: '>=10'} + hasBin: true + + mlly@1.7.1: + resolution: {integrity: sha512-rrVRZRELyQzrIUAVMHxP97kv+G786pHmOKzuFII8zDYahFBS7qnHh2AlYSl1GAHhaMPCz6/oHjVMcfFYgFYHgA==} + + ms@2.1.2: + resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} + + nanoid@3.3.7: + resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + napi-macros@2.2.2: + resolution: {integrity: sha512-hmEVtAGYzVQpCKdbQea4skABsdXW4RUh5t5mJ2zzqowJS2OyXZTU1KhDVFhx+NlWZ4ap9mqR9TcDO3LTTttd+g==} + + negotiator@0.6.3: + resolution: {integrity: sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==} + engines: {node: '>= 0.6'} + + node-abi@3.65.0: + resolution: {integrity: sha512-ThjYBfoDNr08AWx6hGaRbfPwxKV9kVzAzOzlLKbk2CuqXE2xnCh+cbAGnwM3t8Lq4v9rUB7VfondlkBckcJrVA==} + engines: {node: '>=10'} + + node-gyp-build@4.8.1: + resolution: {integrity: sha512-OSs33Z9yWr148JZcbZd5WiAXhh/n9z8TxQcdMhIOlpN9AhWpLfvVFO73+m77bBABQMaY9XSvIa+qk0jlI7Gcaw==} + hasBin: true + + node-gyp@10.1.0: + resolution: {integrity: sha512-B4J5M1cABxPc5PwfjhbV5hoy2DP9p8lFXASnEN6hugXOa61416tnTZ29x9sSwAd0o99XNIcpvDDy1swAExsVKA==} + engines: {node: ^16.14.0 || >=18.0.0} + hasBin: true + + nopt@7.2.1: + resolution: {integrity: sha512-taM24ViiimT/XntxbPyJQzCG+p4EKOpgD3mxFwW38mGjVUrfERQOeY4EDHjdnptttfHuHQXFx+lTP08Q+mLa/w==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + hasBin: true + + npm-run-path@3.1.0: + resolution: {integrity: sha512-Dbl4A/VfiVGLgQv29URL9xshU8XDY1GeLy+fsaZ1AA8JDSfjvr5P5+pzRbWqRSBxk6/DW7MIh8lTM/PaGnP2kg==} + engines: {node: '>=8'} + + npm-run-path@5.3.0: + resolution: {integrity: sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + once@1.4.0: + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + + onetime@6.0.0: + resolution: {integrity: sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==} + engines: {node: '>=12'} + + p-limit@5.0.0: + resolution: {integrity: sha512-/Eaoq+QyLSiXQ4lyYV23f14mZRQcXnxfHrN0vCai+ak9G0pp9iEQukIIZq5NccEvwRB8PUnZT0KsOoDCINS1qQ==} + engines: {node: '>=18'} + + p-map@4.0.0: + resolution: {integrity: sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==} + engines: {node: '>=10'} + + package-json-from-dist@1.0.0: + resolution: {integrity: sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==} + + path-is-absolute@1.0.1: + resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} + engines: {node: '>=0.10.0'} + + path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + + path-key@4.0.0: + resolution: {integrity: sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==} + engines: {node: '>=12'} + + path-parse@1.0.7: + resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + + path-scurry@1.11.1: + resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} + engines: {node: '>=16 || 14 >=14.18'} + + pathe@1.1.2: + resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==} + + pathval@1.1.1: + resolution: {integrity: sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==} + + picocolors@1.0.1: + resolution: {integrity: sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==} + + picomatch@2.3.1: + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + engines: {node: '>=8.6'} + + pkg-types@1.1.1: + resolution: {integrity: sha512-ko14TjmDuQJ14zsotODv7dBlwxKhUKQEhuhmbqo1uCi9BB0Z2alo/wAXg6q1dTR5TyuqYyWhjtfe/Tsh+X28jQ==} + + postcss@8.4.38: + resolution: {integrity: sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==} + engines: {node: ^10 || ^12 || >=14} + + prebuildify@6.0.1: + resolution: {integrity: sha512-8Y2oOOateom/s8dNBsGIcnm6AxPmLH4/nanQzL5lQMU+sC0CMhzARZHizwr36pUPLdvBnOkCNQzxg4djuFSgIw==} + hasBin: true + + pretty-format@29.7.0: + resolution: {integrity: sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + proc-log@3.0.0: + resolution: {integrity: sha512-++Vn7NS4Xf9NacaU9Xq3URUuqZETPsf8L4j5/ckhaRYsfPeRyzGw+iDjFhV/Jr3uNmTvvddEJFWh5R1gRgUH8A==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + proc-log@4.2.0: + resolution: {integrity: sha512-g8+OnU/L2v+wyiVK+D5fA34J7EH8jZ8DDlvwhRCMxmMj7UCBvxiO1mGeN+36JXIKF4zevU4kRBd8lVgG9vLelA==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + promise-retry@2.0.1: + resolution: {integrity: sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==} + engines: {node: '>=10'} + + pump@3.0.0: + resolution: {integrity: sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==} + + react-is@18.3.1: + resolution: {integrity: sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==} + + readable-stream@3.6.2: + resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} + engines: {node: '>= 6'} + + resolve-pkg-maps@1.0.0: + resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} + + resolve@1.22.8: + resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==} + hasBin: true + + retry@0.12.0: + resolution: {integrity: sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==} + engines: {node: '>= 4'} + + rimraf@5.0.7: + resolution: {integrity: sha512-nV6YcJo5wbLW77m+8KjH8aB/7/rxQy9SZ0HY5shnwULfS+9nmTtVXAJET5NdZmCzA4fPI/Hm1wo/Po/4mopOdg==} + engines: {node: '>=14.18'} + hasBin: true + + rollup-plugin-dts@6.1.1: + resolution: {integrity: sha512-aSHRcJ6KG2IHIioYlvAOcEq6U99sVtqDDKVhnwt70rW6tsz3tv5OSjEiWcgzfsHdLyGXZ/3b/7b/+Za3Y6r1XA==} + engines: {node: '>=16'} + peerDependencies: + rollup: ^3.29.4 || ^4 + typescript: ^4.5 || ^5.0 + + rollup-plugin-esbuild@6.1.1: + resolution: {integrity: sha512-CehMY9FAqJD5OUaE/Mi1r5z0kNeYxItmRO2zG4Qnv2qWKF09J2lTy5GUzjJR354ZPrLkCj4fiBN41lo8PzBUhw==} + engines: {node: '>=14.18.0'} + peerDependencies: + esbuild: '>=0.18.0' + rollup: ^1.20.0 || ^2.0.0 || ^3.0.0 || ^4.0.0 + + rollup@4.18.0: + resolution: {integrity: sha512-QmJz14PX3rzbJCN1SG4Xe/bAAX2a6NpCP8ab2vfu2GiUr8AQcr2nCV/oEO3yneFarB67zk8ShlIyWb2LGTb3Sg==} + engines: {node: '>=18.0.0', npm: '>=8.0.0'} + hasBin: true + + safe-buffer@5.2.1: + resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + + safer-buffer@2.1.2: + resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + + semver@7.6.2: + resolution: {integrity: sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==} + engines: {node: '>=10'} + hasBin: true + + shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + + shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + + siginfo@2.0.0: + resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} + + signal-exit@4.1.0: + resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} + engines: {node: '>=14'} + + smart-buffer@4.2.0: + resolution: {integrity: sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==} + engines: {node: '>= 6.0.0', npm: '>= 3.0.0'} + + snooplogg@6.0.0-rc.1: + resolution: {integrity: sha512-bSMEYqOYV/9NWx1+EPjcNfGxJDgKoKc/t/bswimlWLuQFahOnvpPQNe2gFr64jyaHslxZTgzO0lqmwxTvBuWPA==} + engines: {node: '>=18.17'} + + socks-proxy-agent@8.0.3: + resolution: {integrity: sha512-VNegTZKhuGq5vSD6XNKlbqWhyt/40CgoEw8XxD6dhnm8Jq9IEa3nIa4HwnM8XOqU0CdB0BwWVXusqiFXfHB3+A==} + engines: {node: '>= 14'} + + socks@2.8.3: + resolution: {integrity: sha512-l5x7VUUWbjVFbafGLxPWkYsHIhEvmF85tbIeFZWc8ZPtoMyybuEhL7Jye/ooC4/d48FgOjSJXgsF/AJPYCW8Zw==} + engines: {node: '>= 10.0.0', npm: '>= 3.0.0'} + + source-map-js@1.2.0: + resolution: {integrity: sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==} + engines: {node: '>=0.10.0'} + + sprintf-js@1.1.3: + resolution: {integrity: sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==} + + ssri@10.0.6: + resolution: {integrity: sha512-MGrFH9Z4NP9Iyhqn16sDtBpRRNJ0Y2hNa6D65h736fVSaPCHr4DM4sWUNvVaSuC+0OBGhwsrydQwmgfg5LncqQ==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + stackback@0.0.2: + resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} + + std-env@3.7.0: + resolution: {integrity: sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg==} + + string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + + string-width@5.1.2: + resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} + engines: {node: '>=12'} + + string_decoder@1.3.0: + resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} + + strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + + strip-ansi@7.1.0: + resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} + engines: {node: '>=12'} + + strip-final-newline@3.0.0: + resolution: {integrity: sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==} + engines: {node: '>=12'} + + strip-literal@2.1.0: + resolution: {integrity: sha512-Op+UycaUt/8FbN/Z2TWPBLge3jWrP3xj10f3fnYxf052bKuS3EKs1ZQcVGjnEMdsNVAM+plXRdmjrZ/KgG3Skw==} + + supports-color@5.5.0: + resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} + engines: {node: '>=4'} + + supports-color@7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} + + supports-preserve-symlinks-flag@1.0.0: + resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} + engines: {node: '>= 0.4'} + + tar-fs@2.1.1: + resolution: {integrity: sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==} + + tar-stream@2.2.0: + resolution: {integrity: sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==} + engines: {node: '>=6'} + + tar@6.2.1: + resolution: {integrity: sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==} + engines: {node: '>=10'} + + test-exclude@6.0.0: + resolution: {integrity: sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==} + engines: {node: '>=8'} + + tinybench@2.8.0: + resolution: {integrity: sha512-1/eK7zUnIklz4JUUlL+658n58XO2hHLQfSk1Zf2LKieUjxidN16eKFEoDEfjHc3ohofSSqK3X5yO6VGb6iW8Lw==} + + tinypool@0.8.4: + resolution: {integrity: sha512-i11VH5gS6IFeLY3gMBQ00/MmLncVP7JLXOw1vlgkytLmJK7QnEr7NXf0LBdxfmNPAeyetukOk0bOYrJrFGjYJQ==} + engines: {node: '>=14.0.0'} + + tinyspy@2.2.1: + resolution: {integrity: sha512-KYad6Vy5VDWV4GH3fjpseMQ/XU2BhIYP7Vzd0LG44qRWm/Yt2WCOTicFdvmgo6gWaqooMQCawTtILVQJupKu7A==} + engines: {node: '>=14.0.0'} + + to-fast-properties@2.0.0: + resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} + engines: {node: '>=4'} + + tslib@2.6.3: + resolution: {integrity: sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==} + + type-detect@4.0.8: + resolution: {integrity: sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==} + engines: {node: '>=4'} + + typescript@5.5.2: + resolution: {integrity: sha512-NcRtPEOsPFFWjobJEtfihkLCZCXZt/os3zf8nTxjVH3RvTSxjrCamJpbExGvYOF+tFHc3pA65qpdwPbzjohhew==} + engines: {node: '>=14.17'} + hasBin: true + + ufo@1.5.3: + resolution: {integrity: sha512-Y7HYmWaFwPUmkoQCUIAYpKqkOf+SbVj/2fJJZ4RJMCfZp0rTGwRbzQD+HghfnhKOjL9E01okqz+ncJskGYfBNw==} + + undici-types@5.26.5: + resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} + + unique-filename@3.0.0: + resolution: {integrity: sha512-afXhuC55wkAmZ0P18QsVE6kp8JaxrEokN2HGIoIVv2ijHQd419H0+6EigAFcIzXeMIkcIkNBpB3L/DXB3cTS/g==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + unique-slug@4.0.0: + resolution: {integrity: sha512-WrcA6AyEfqDX5bWige/4NQfPZMtASNVxdmWR76WESYQVAACSgWcR6e9i0mofqqBxYFtL4oAxPIptY73/0YE1DQ==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + util-deprecate@1.0.2: + resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + + vite-node@1.6.0: + resolution: {integrity: sha512-de6HJgzC+TFzOu0NTC4RAIsyf/DY/ibWDYQUcuEA84EMHhcefTUGkjFHKKEJhQN4A+6I0u++kr3l36ZF2d7XRw==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + + vite@5.3.1: + resolution: {integrity: sha512-XBmSKRLXLxiaPYamLv3/hnP/KXDai1NDexN0FpkTaZXTfycHvkRHoenpgl/fvuK/kPbB6xAgoyiryAhQNxYmAQ==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + peerDependencies: + '@types/node': ^18.0.0 || >=20.0.0 + less: '*' + lightningcss: ^1.21.0 + sass: '*' + stylus: '*' + sugarss: '*' + terser: ^5.4.0 + peerDependenciesMeta: + '@types/node': + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + + vitest@1.6.0: + resolution: {integrity: sha512-H5r/dN06swuFnzNFhq/dnz37bPXnq8xB2xB5JOVk8K09rUtoeNN+LHWkoQ0A/i3hvbUKKcCei9KpbxqHMLhLLA==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + peerDependencies: + '@edge-runtime/vm': '*' + '@types/node': ^18.0.0 || >=20.0.0 + '@vitest/browser': 1.6.0 + '@vitest/ui': 1.6.0 + happy-dom: '*' + jsdom: '*' + peerDependenciesMeta: + '@edge-runtime/vm': + optional: true + '@types/node': + optional: true + '@vitest/browser': + optional: true + '@vitest/ui': + optional: true + happy-dom: + optional: true + jsdom: + optional: true + + which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + + which@4.0.0: + resolution: {integrity: sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==} + engines: {node: ^16.13.0 || >=18.0.0} + hasBin: true + + why-is-node-running@2.2.2: + resolution: {integrity: sha512-6tSwToZxTOcotxHeA+qGCq1mVzKR3CwcJGmVcY+QE8SHy6TnpFnh8PAvPNHYr7EcuVeG0QSMxtYCuO1ta/G/oA==} + engines: {node: '>=8'} + hasBin: true + + wrap-ansi@7.0.0: + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} + + wrap-ansi@8.1.0: + resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} + engines: {node: '>=12'} + + wrappy@1.0.2: + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + + yallist@4.0.0: + resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} + + yocto-queue@1.0.0: + resolution: {integrity: sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==} + engines: {node: '>=12.20'} + +snapshots: + + '@ampproject/remapping@2.3.0': + dependencies: + '@jridgewell/gen-mapping': 0.3.5 + '@jridgewell/trace-mapping': 0.3.25 + + '@babel/code-frame@7.24.7': + dependencies: + '@babel/highlight': 7.24.7 + picocolors: 1.0.1 + optional: true + + '@babel/helper-string-parser@7.24.7': {} + + '@babel/helper-validator-identifier@7.24.7': {} + + '@babel/highlight@7.24.7': + dependencies: + '@babel/helper-validator-identifier': 7.24.7 + chalk: 2.4.2 + js-tokens: 4.0.0 + picocolors: 1.0.1 + optional: true + + '@babel/parser@7.24.7': + dependencies: + '@babel/types': 7.24.7 + + '@babel/types@7.24.7': + dependencies: + '@babel/helper-string-parser': 7.24.7 + '@babel/helper-validator-identifier': 7.24.7 + to-fast-properties: 2.0.0 + + '@bcoe/v8-coverage@0.2.3': {} + + '@biomejs/biome@1.8.3': + optionalDependencies: + '@biomejs/cli-darwin-arm64': 1.8.3 + '@biomejs/cli-darwin-x64': 1.8.3 + '@biomejs/cli-linux-arm64': 1.8.3 + '@biomejs/cli-linux-arm64-musl': 1.8.3 + '@biomejs/cli-linux-x64': 1.8.3 + '@biomejs/cli-linux-x64-musl': 1.8.3 + '@biomejs/cli-win32-arm64': 1.8.3 + '@biomejs/cli-win32-x64': 1.8.3 + + '@biomejs/cli-darwin-arm64@1.8.3': + optional: true + + '@biomejs/cli-darwin-x64@1.8.3': + optional: true + + '@biomejs/cli-linux-arm64-musl@1.8.3': + optional: true + + '@biomejs/cli-linux-arm64@1.8.3': + optional: true + + '@biomejs/cli-linux-x64-musl@1.8.3': + optional: true + + '@biomejs/cli-linux-x64@1.8.3': + optional: true + + '@biomejs/cli-win32-arm64@1.8.3': + optional: true + + '@biomejs/cli-win32-x64@1.8.3': + optional: true + + '@esbuild/aix-ppc64@0.21.5': + optional: true + + '@esbuild/aix-ppc64@0.22.0': + optional: true + + '@esbuild/android-arm64@0.21.5': + optional: true + + '@esbuild/android-arm64@0.22.0': + optional: true + + '@esbuild/android-arm@0.21.5': + optional: true + + '@esbuild/android-arm@0.22.0': + optional: true + + '@esbuild/android-x64@0.21.5': + optional: true + + '@esbuild/android-x64@0.22.0': + optional: true + + '@esbuild/darwin-arm64@0.21.5': + optional: true + + '@esbuild/darwin-arm64@0.22.0': + optional: true + + '@esbuild/darwin-x64@0.21.5': + optional: true + + '@esbuild/darwin-x64@0.22.0': + optional: true + + '@esbuild/freebsd-arm64@0.21.5': + optional: true + + '@esbuild/freebsd-arm64@0.22.0': + optional: true + + '@esbuild/freebsd-x64@0.21.5': + optional: true + + '@esbuild/freebsd-x64@0.22.0': + optional: true + + '@esbuild/linux-arm64@0.21.5': + optional: true + + '@esbuild/linux-arm64@0.22.0': + optional: true + + '@esbuild/linux-arm@0.21.5': + optional: true + + '@esbuild/linux-arm@0.22.0': + optional: true + + '@esbuild/linux-ia32@0.21.5': + optional: true + + '@esbuild/linux-ia32@0.22.0': + optional: true + + '@esbuild/linux-loong64@0.21.5': + optional: true + + '@esbuild/linux-loong64@0.22.0': + optional: true + + '@esbuild/linux-mips64el@0.21.5': + optional: true + + '@esbuild/linux-mips64el@0.22.0': + optional: true + + '@esbuild/linux-ppc64@0.21.5': + optional: true + + '@esbuild/linux-ppc64@0.22.0': + optional: true + + '@esbuild/linux-riscv64@0.21.5': + optional: true + + '@esbuild/linux-riscv64@0.22.0': + optional: true + + '@esbuild/linux-s390x@0.21.5': + optional: true + + '@esbuild/linux-s390x@0.22.0': + optional: true + + '@esbuild/linux-x64@0.21.5': + optional: true + + '@esbuild/linux-x64@0.22.0': + optional: true + + '@esbuild/netbsd-x64@0.21.5': + optional: true + + '@esbuild/netbsd-x64@0.22.0': + optional: true + + '@esbuild/openbsd-arm64@0.22.0': + optional: true + + '@esbuild/openbsd-x64@0.21.5': + optional: true + + '@esbuild/openbsd-x64@0.22.0': + optional: true + + '@esbuild/sunos-x64@0.21.5': + optional: true + + '@esbuild/sunos-x64@0.22.0': + optional: true + + '@esbuild/win32-arm64@0.21.5': + optional: true + + '@esbuild/win32-arm64@0.22.0': + optional: true + + '@esbuild/win32-ia32@0.21.5': + optional: true + + '@esbuild/win32-ia32@0.22.0': + optional: true + + '@esbuild/win32-x64@0.21.5': + optional: true + + '@esbuild/win32-x64@0.22.0': + optional: true + + '@isaacs/cliui@8.0.2': + dependencies: + string-width: 5.1.2 + string-width-cjs: string-width@4.2.3 + strip-ansi: 7.1.0 + strip-ansi-cjs: strip-ansi@6.0.1 + wrap-ansi: 8.1.0 + wrap-ansi-cjs: wrap-ansi@7.0.0 + + '@istanbuljs/schema@0.1.3': {} + + '@jest/schemas@29.6.3': + dependencies: + '@sinclair/typebox': 0.27.8 + + '@jridgewell/gen-mapping@0.3.5': + dependencies: + '@jridgewell/set-array': 1.2.1 + '@jridgewell/sourcemap-codec': 1.4.15 + '@jridgewell/trace-mapping': 0.3.25 + + '@jridgewell/resolve-uri@3.1.2': {} + + '@jridgewell/set-array@1.2.1': {} + + '@jridgewell/sourcemap-codec@1.4.15': {} + + '@jridgewell/trace-mapping@0.3.25': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.4.15 + + '@npmcli/agent@2.2.2': + dependencies: + agent-base: 7.1.1 + http-proxy-agent: 7.0.2 + https-proxy-agent: 7.0.4 + lru-cache: 10.2.2 + socks-proxy-agent: 8.0.3 + transitivePeerDependencies: + - supports-color + + '@npmcli/fs@3.1.1': + dependencies: + semver: 7.6.2 + + '@pkgjs/parseargs@0.11.0': + optional: true + + '@rollup/plugin-node-resolve@15.2.3(rollup@4.18.0)': + dependencies: + '@rollup/pluginutils': 5.1.0(rollup@4.18.0) + '@types/resolve': 1.20.2 + deepmerge: 4.3.1 + is-builtin-module: 3.2.1 + is-module: 1.0.0 + resolve: 1.22.8 + optionalDependencies: + rollup: 4.18.0 + + '@rollup/plugin-typescript@11.1.6(rollup@4.18.0)(tslib@2.6.3)(typescript@5.5.2)': + dependencies: + '@rollup/pluginutils': 5.1.0(rollup@4.18.0) + resolve: 1.22.8 + typescript: 5.5.2 + optionalDependencies: + rollup: 4.18.0 + tslib: 2.6.3 + + '@rollup/pluginutils@5.1.0(rollup@4.18.0)': + dependencies: + '@types/estree': 1.0.5 + estree-walker: 2.0.2 + picomatch: 2.3.1 + optionalDependencies: + rollup: 4.18.0 + + '@rollup/rollup-android-arm-eabi@4.18.0': + optional: true + + '@rollup/rollup-android-arm64@4.18.0': + optional: true + + '@rollup/rollup-darwin-arm64@4.18.0': + optional: true + + '@rollup/rollup-darwin-x64@4.18.0': + optional: true + + '@rollup/rollup-linux-arm-gnueabihf@4.18.0': + optional: true + + '@rollup/rollup-linux-arm-musleabihf@4.18.0': + optional: true + + '@rollup/rollup-linux-arm64-gnu@4.18.0': + optional: true + + '@rollup/rollup-linux-arm64-musl@4.18.0': + optional: true + + '@rollup/rollup-linux-powerpc64le-gnu@4.18.0': + optional: true + + '@rollup/rollup-linux-riscv64-gnu@4.18.0': + optional: true + + '@rollup/rollup-linux-s390x-gnu@4.18.0': + optional: true + + '@rollup/rollup-linux-x64-gnu@4.18.0': + optional: true + + '@rollup/rollup-linux-x64-musl@4.18.0': + optional: true + + '@rollup/rollup-win32-arm64-msvc@4.18.0': + optional: true + + '@rollup/rollup-win32-ia32-msvc@4.18.0': + optional: true + + '@rollup/rollup-win32-x64-msvc@4.18.0': + optional: true + + '@sinclair/typebox@0.27.8': {} + + '@types/estree@1.0.5': {} + + '@types/node@20.14.9': + dependencies: + undici-types: 5.26.5 + + '@types/resolve@1.20.2': {} + + '@vitest/coverage-v8@1.6.0(vitest@1.6.0(@types/node@20.14.9))': + dependencies: + '@ampproject/remapping': 2.3.0 + '@bcoe/v8-coverage': 0.2.3 + debug: 4.3.5 + istanbul-lib-coverage: 3.2.2 + istanbul-lib-report: 3.0.1 + istanbul-lib-source-maps: 5.0.4 + istanbul-reports: 3.1.7 + magic-string: 0.30.10 + magicast: 0.3.4 + picocolors: 1.0.1 + std-env: 3.7.0 + strip-literal: 2.1.0 + test-exclude: 6.0.0 + vitest: 1.6.0(@types/node@20.14.9) + transitivePeerDependencies: + - supports-color + + '@vitest/expect@1.6.0': + dependencies: + '@vitest/spy': 1.6.0 + '@vitest/utils': 1.6.0 + chai: 4.4.1 + + '@vitest/runner@1.6.0': + dependencies: + '@vitest/utils': 1.6.0 + p-limit: 5.0.0 + pathe: 1.1.2 + + '@vitest/snapshot@1.6.0': + dependencies: + magic-string: 0.30.10 + pathe: 1.1.2 + pretty-format: 29.7.0 + + '@vitest/spy@1.6.0': + dependencies: + tinyspy: 2.2.1 + + '@vitest/utils@1.6.0': + dependencies: + diff-sequences: 29.6.3 + estree-walker: 3.0.3 + loupe: 2.3.7 + pretty-format: 29.7.0 + + abbrev@2.0.0: {} + + acorn-walk@8.3.3: + dependencies: + acorn: 8.12.0 + + acorn@8.12.0: {} + + agent-base@7.1.1: + dependencies: + debug: 4.3.5 + transitivePeerDependencies: + - supports-color + + aggregate-error@3.1.0: + dependencies: + clean-stack: 2.2.0 + indent-string: 4.0.0 + + ansi-regex@5.0.1: {} + + ansi-regex@6.0.1: {} + + ansi-styles@3.2.1: + dependencies: + color-convert: 1.9.3 + optional: true + + ansi-styles@4.3.0: + dependencies: + color-convert: 2.0.1 + + ansi-styles@5.2.0: {} + + ansi-styles@6.2.1: {} + + assertion-error@1.1.0: {} + + balanced-match@1.0.2: {} + + base64-js@1.5.1: {} + + bl@4.1.0: + dependencies: + buffer: 5.7.1 + inherits: 2.0.4 + readable-stream: 3.6.2 + + brace-expansion@1.1.11: + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + + brace-expansion@2.0.1: + dependencies: + balanced-match: 1.0.2 + + buffer@5.7.1: + dependencies: + base64-js: 1.5.1 + ieee754: 1.2.1 + + builtin-modules@3.3.0: {} + + cac@6.7.14: {} + + cacache@18.0.3: + dependencies: + '@npmcli/fs': 3.1.1 + fs-minipass: 3.0.3 + glob: 10.4.2 + lru-cache: 10.2.2 + minipass: 7.1.2 + minipass-collect: 2.0.1 + minipass-flush: 1.0.5 + minipass-pipeline: 1.2.4 + p-map: 4.0.0 + ssri: 10.0.6 + tar: 6.2.1 + unique-filename: 3.0.0 + + chai@4.4.1: + dependencies: + assertion-error: 1.1.0 + check-error: 1.0.3 + deep-eql: 4.1.4 + get-func-name: 2.0.2 + loupe: 2.3.7 + pathval: 1.1.1 + type-detect: 4.0.8 + + chalk@2.4.2: + dependencies: + ansi-styles: 3.2.1 + escape-string-regexp: 1.0.5 + supports-color: 5.5.0 + optional: true + + check-error@1.0.3: + dependencies: + get-func-name: 2.0.2 + + chownr@1.1.4: {} + + chownr@2.0.0: {} + + clean-stack@2.2.0: {} + + color-convert@1.9.3: + dependencies: + color-name: 1.1.3 + optional: true + + color-convert@2.0.1: + dependencies: + color-name: 1.1.4 + + color-name@1.1.3: + optional: true + + color-name@1.1.4: {} + + concat-map@0.0.1: {} + + confbox@0.1.7: {} + + cross-spawn@7.0.3: + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + + debug@4.3.5: + dependencies: + ms: 2.1.2 + + deep-eql@4.1.4: + dependencies: + type-detect: 4.0.8 + + deepmerge@4.3.1: {} + + diff-sequences@29.6.3: {} + + eastasianwidth@0.2.0: {} + + emoji-regex@8.0.0: {} + + emoji-regex@9.2.2: {} + + encoding@0.1.13: + dependencies: + iconv-lite: 0.6.3 + optional: true + + end-of-stream@1.4.4: + dependencies: + once: 1.4.0 + + env-paths@2.2.1: {} + + err-code@2.0.3: {} + + es-module-lexer@1.5.4: {} + + esbuild@0.21.5: + optionalDependencies: + '@esbuild/aix-ppc64': 0.21.5 + '@esbuild/android-arm': 0.21.5 + '@esbuild/android-arm64': 0.21.5 + '@esbuild/android-x64': 0.21.5 + '@esbuild/darwin-arm64': 0.21.5 + '@esbuild/darwin-x64': 0.21.5 + '@esbuild/freebsd-arm64': 0.21.5 + '@esbuild/freebsd-x64': 0.21.5 + '@esbuild/linux-arm': 0.21.5 + '@esbuild/linux-arm64': 0.21.5 + '@esbuild/linux-ia32': 0.21.5 + '@esbuild/linux-loong64': 0.21.5 + '@esbuild/linux-mips64el': 0.21.5 + '@esbuild/linux-ppc64': 0.21.5 + '@esbuild/linux-riscv64': 0.21.5 + '@esbuild/linux-s390x': 0.21.5 + '@esbuild/linux-x64': 0.21.5 + '@esbuild/netbsd-x64': 0.21.5 + '@esbuild/openbsd-x64': 0.21.5 + '@esbuild/sunos-x64': 0.21.5 + '@esbuild/win32-arm64': 0.21.5 + '@esbuild/win32-ia32': 0.21.5 + '@esbuild/win32-x64': 0.21.5 + + esbuild@0.22.0: + optionalDependencies: + '@esbuild/aix-ppc64': 0.22.0 + '@esbuild/android-arm': 0.22.0 + '@esbuild/android-arm64': 0.22.0 + '@esbuild/android-x64': 0.22.0 + '@esbuild/darwin-arm64': 0.22.0 + '@esbuild/darwin-x64': 0.22.0 + '@esbuild/freebsd-arm64': 0.22.0 + '@esbuild/freebsd-x64': 0.22.0 + '@esbuild/linux-arm': 0.22.0 + '@esbuild/linux-arm64': 0.22.0 + '@esbuild/linux-ia32': 0.22.0 + '@esbuild/linux-loong64': 0.22.0 + '@esbuild/linux-mips64el': 0.22.0 + '@esbuild/linux-ppc64': 0.22.0 + '@esbuild/linux-riscv64': 0.22.0 + '@esbuild/linux-s390x': 0.22.0 + '@esbuild/linux-x64': 0.22.0 + '@esbuild/netbsd-x64': 0.22.0 + '@esbuild/openbsd-arm64': 0.22.0 + '@esbuild/openbsd-x64': 0.22.0 + '@esbuild/sunos-x64': 0.22.0 + '@esbuild/win32-arm64': 0.22.0 + '@esbuild/win32-ia32': 0.22.0 + '@esbuild/win32-x64': 0.22.0 + + escape-string-regexp@1.0.5: + optional: true + + estree-walker@2.0.2: {} + + estree-walker@3.0.3: + dependencies: + '@types/estree': 1.0.5 + + execa@8.0.1: + dependencies: + cross-spawn: 7.0.3 + get-stream: 8.0.1 + human-signals: 5.0.0 + is-stream: 3.0.0 + merge-stream: 2.0.0 + npm-run-path: 5.3.0 + onetime: 6.0.0 + signal-exit: 4.1.0 + strip-final-newline: 3.0.0 + + exponential-backoff@3.1.1: {} + + foreground-child@3.2.1: + dependencies: + cross-spawn: 7.0.3 + signal-exit: 4.1.0 + + fs-constants@1.0.0: {} + + fs-minipass@2.1.0: + dependencies: + minipass: 3.3.6 + + fs-minipass@3.0.3: + dependencies: + minipass: 7.1.2 + + fs.realpath@1.0.0: {} + + fsevents@2.3.3: + optional: true + + function-bind@1.1.2: {} + + get-func-name@2.0.2: {} + + get-stream@8.0.1: {} + + get-tsconfig@4.7.5: + dependencies: + resolve-pkg-maps: 1.0.0 + + glob@10.4.2: + dependencies: + foreground-child: 3.2.1 + jackspeak: 3.4.0 + minimatch: 9.0.5 + minipass: 7.1.2 + package-json-from-dist: 1.0.0 + path-scurry: 1.11.1 + + glob@7.2.3: + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 3.1.2 + once: 1.4.0 + path-is-absolute: 1.0.1 + + graceful-fs@4.2.11: {} + + has-flag@3.0.0: + optional: true + + has-flag@4.0.0: {} + + hasown@2.0.2: + dependencies: + function-bind: 1.1.2 + + html-escaper@2.0.2: {} + + http-cache-semantics@4.1.1: {} + + http-proxy-agent@7.0.2: + dependencies: + agent-base: 7.1.1 + debug: 4.3.5 + transitivePeerDependencies: + - supports-color + + https-proxy-agent@7.0.4: + dependencies: + agent-base: 7.1.1 + debug: 4.3.5 + transitivePeerDependencies: + - supports-color + + human-signals@5.0.0: {} + + iconv-lite@0.6.3: + dependencies: + safer-buffer: 2.1.2 + optional: true + + ieee754@1.2.1: {} + + imurmurhash@0.1.4: {} + + indent-string@4.0.0: {} + + inflight@1.0.6: + dependencies: + once: 1.4.0 + wrappy: 1.0.2 + + inherits@2.0.4: {} + + ip-address@9.0.5: + dependencies: + jsbn: 1.1.0 + sprintf-js: 1.1.3 + + is-builtin-module@3.2.1: + dependencies: + builtin-modules: 3.3.0 + + is-core-module@2.14.0: + dependencies: + hasown: 2.0.2 + + is-fullwidth-code-point@3.0.0: {} + + is-lambda@1.0.1: {} + + is-module@1.0.0: {} + + is-stream@3.0.0: {} + + isexe@2.0.0: {} + + isexe@3.1.1: {} + + istanbul-lib-coverage@3.2.2: {} + + istanbul-lib-report@3.0.1: + dependencies: + istanbul-lib-coverage: 3.2.2 + make-dir: 4.0.0 + supports-color: 7.2.0 + + istanbul-lib-source-maps@5.0.4: + dependencies: + '@jridgewell/trace-mapping': 0.3.25 + debug: 4.3.5 + istanbul-lib-coverage: 3.2.2 + transitivePeerDependencies: + - supports-color + + istanbul-reports@3.1.7: + dependencies: + html-escaper: 2.0.2 + istanbul-lib-report: 3.0.1 + + jackspeak@3.4.0: + dependencies: + '@isaacs/cliui': 8.0.2 + optionalDependencies: + '@pkgjs/parseargs': 0.11.0 + + js-tokens@4.0.0: + optional: true + + js-tokens@9.0.0: {} + + jsbn@1.1.0: {} + + lefthook-darwin-arm64@1.6.18: + optional: true + + lefthook-darwin-x64@1.6.18: + optional: true + + lefthook-freebsd-arm64@1.6.18: + optional: true + + lefthook-freebsd-x64@1.6.18: + optional: true + + lefthook-linux-arm64@1.6.18: + optional: true + + lefthook-linux-x64@1.6.18: + optional: true + + lefthook-windows-arm64@1.6.18: + optional: true + + lefthook-windows-x64@1.6.18: + optional: true + + lefthook@1.6.18: + optionalDependencies: + lefthook-darwin-arm64: 1.6.18 + lefthook-darwin-x64: 1.6.18 + lefthook-freebsd-arm64: 1.6.18 + lefthook-freebsd-x64: 1.6.18 + lefthook-linux-arm64: 1.6.18 + lefthook-linux-x64: 1.6.18 + lefthook-windows-arm64: 1.6.18 + lefthook-windows-x64: 1.6.18 + + local-pkg@0.5.0: + dependencies: + mlly: 1.7.1 + pkg-types: 1.1.1 + + loupe@2.3.7: + dependencies: + get-func-name: 2.0.2 + + lru-cache@10.2.2: {} + + magic-string@0.30.10: + dependencies: + '@jridgewell/sourcemap-codec': 1.4.15 + + magicast@0.3.4: + dependencies: + '@babel/parser': 7.24.7 + '@babel/types': 7.24.7 + source-map-js: 1.2.0 + + make-dir@4.0.0: + dependencies: + semver: 7.6.2 + + make-fetch-happen@13.0.1: + dependencies: + '@npmcli/agent': 2.2.2 + cacache: 18.0.3 + http-cache-semantics: 4.1.1 + is-lambda: 1.0.1 + minipass: 7.1.2 + minipass-fetch: 3.0.5 + minipass-flush: 1.0.5 + minipass-pipeline: 1.2.4 + negotiator: 0.6.3 + proc-log: 4.2.0 + promise-retry: 2.0.1 + ssri: 10.0.6 + transitivePeerDependencies: + - supports-color + + merge-stream@2.0.0: {} + + mimic-fn@4.0.0: {} + + minimatch@3.1.2: + dependencies: + brace-expansion: 1.1.11 + + minimatch@9.0.5: + dependencies: + brace-expansion: 2.0.1 + + minimist@1.2.8: {} + + minipass-collect@2.0.1: + dependencies: + minipass: 7.1.2 + + minipass-fetch@3.0.5: + dependencies: + minipass: 7.1.2 + minipass-sized: 1.0.3 + minizlib: 2.1.2 + optionalDependencies: + encoding: 0.1.13 + + minipass-flush@1.0.5: + dependencies: + minipass: 3.3.6 + + minipass-pipeline@1.2.4: + dependencies: + minipass: 3.3.6 + + minipass-sized@1.0.3: + dependencies: + minipass: 3.3.6 + + minipass@3.3.6: + dependencies: + yallist: 4.0.0 + + minipass@5.0.0: {} + + minipass@7.1.2: {} + + minizlib@2.1.2: + dependencies: + minipass: 3.3.6 + yallist: 4.0.0 + + mkdirp-classic@0.5.3: {} + + mkdirp@1.0.4: {} + + mlly@1.7.1: + dependencies: + acorn: 8.12.0 + pathe: 1.1.2 + pkg-types: 1.1.1 + ufo: 1.5.3 + + ms@2.1.2: {} + + nanoid@3.3.7: {} + + napi-macros@2.2.2: {} + + negotiator@0.6.3: {} + + node-abi@3.65.0: + dependencies: + semver: 7.6.2 + + node-gyp-build@4.8.1(patch_hash=caauzub3lunughu5goi7nkusjm): {} + + node-gyp@10.1.0: + dependencies: + env-paths: 2.2.1 + exponential-backoff: 3.1.1 + glob: 10.4.2 + graceful-fs: 4.2.11 + make-fetch-happen: 13.0.1 + nopt: 7.2.1 + proc-log: 3.0.0 + semver: 7.6.2 + tar: 6.2.1 + which: 4.0.0 + transitivePeerDependencies: + - supports-color + + nopt@7.2.1: + dependencies: + abbrev: 2.0.0 + + npm-run-path@3.1.0: + dependencies: + path-key: 3.1.1 + + npm-run-path@5.3.0: + dependencies: + path-key: 4.0.0 + + once@1.4.0: + dependencies: + wrappy: 1.0.2 + + onetime@6.0.0: + dependencies: + mimic-fn: 4.0.0 + + p-limit@5.0.0: + dependencies: + yocto-queue: 1.0.0 + + p-map@4.0.0: + dependencies: + aggregate-error: 3.1.0 + + package-json-from-dist@1.0.0: {} + + path-is-absolute@1.0.1: {} + + path-key@3.1.1: {} + + path-key@4.0.0: {} + + path-parse@1.0.7: {} + + path-scurry@1.11.1: + dependencies: + lru-cache: 10.2.2 + minipass: 7.1.2 + + pathe@1.1.2: {} + + pathval@1.1.1: {} + + picocolors@1.0.1: {} + + picomatch@2.3.1: {} + + pkg-types@1.1.1: + dependencies: + confbox: 0.1.7 + mlly: 1.7.1 + pathe: 1.1.2 + + postcss@8.4.38: + dependencies: + nanoid: 3.3.7 + picocolors: 1.0.1 + source-map-js: 1.2.0 + + prebuildify@6.0.1: + dependencies: + minimist: 1.2.8 + mkdirp-classic: 0.5.3 + node-abi: 3.65.0 + npm-run-path: 3.1.0 + pump: 3.0.0 + tar-fs: 2.1.1 + + pretty-format@29.7.0: + dependencies: + '@jest/schemas': 29.6.3 + ansi-styles: 5.2.0 + react-is: 18.3.1 + + proc-log@3.0.0: {} + + proc-log@4.2.0: {} + + promise-retry@2.0.1: + dependencies: + err-code: 2.0.3 + retry: 0.12.0 + + pump@3.0.0: + dependencies: + end-of-stream: 1.4.4 + once: 1.4.0 + + react-is@18.3.1: {} + + readable-stream@3.6.2: + dependencies: + inherits: 2.0.4 + string_decoder: 1.3.0 + util-deprecate: 1.0.2 + + resolve-pkg-maps@1.0.0: {} + + resolve@1.22.8: + dependencies: + is-core-module: 2.14.0 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + + retry@0.12.0: {} + + rimraf@5.0.7: + dependencies: + glob: 10.4.2 + + rollup-plugin-dts@6.1.1(rollup@4.18.0)(typescript@5.5.2): + dependencies: + magic-string: 0.30.10 + rollup: 4.18.0 + typescript: 5.5.2 + optionalDependencies: + '@babel/code-frame': 7.24.7 + + rollup-plugin-esbuild@6.1.1(esbuild@0.22.0)(rollup@4.18.0): + dependencies: + '@rollup/pluginutils': 5.1.0(rollup@4.18.0) + debug: 4.3.5 + es-module-lexer: 1.5.4 + esbuild: 0.22.0 + get-tsconfig: 4.7.5 + rollup: 4.18.0 + transitivePeerDependencies: + - supports-color + + rollup@4.18.0: + dependencies: + '@types/estree': 1.0.5 + optionalDependencies: + '@rollup/rollup-android-arm-eabi': 4.18.0 + '@rollup/rollup-android-arm64': 4.18.0 + '@rollup/rollup-darwin-arm64': 4.18.0 + '@rollup/rollup-darwin-x64': 4.18.0 + '@rollup/rollup-linux-arm-gnueabihf': 4.18.0 + '@rollup/rollup-linux-arm-musleabihf': 4.18.0 + '@rollup/rollup-linux-arm64-gnu': 4.18.0 + '@rollup/rollup-linux-arm64-musl': 4.18.0 + '@rollup/rollup-linux-powerpc64le-gnu': 4.18.0 + '@rollup/rollup-linux-riscv64-gnu': 4.18.0 + '@rollup/rollup-linux-s390x-gnu': 4.18.0 + '@rollup/rollup-linux-x64-gnu': 4.18.0 + '@rollup/rollup-linux-x64-musl': 4.18.0 + '@rollup/rollup-win32-arm64-msvc': 4.18.0 + '@rollup/rollup-win32-ia32-msvc': 4.18.0 + '@rollup/rollup-win32-x64-msvc': 4.18.0 + fsevents: 2.3.3 + + safe-buffer@5.2.1: {} + + safer-buffer@2.1.2: + optional: true + + semver@7.6.2: {} + + shebang-command@2.0.0: + dependencies: + shebang-regex: 3.0.0 + + shebang-regex@3.0.0: {} + + siginfo@2.0.0: {} + + signal-exit@4.1.0: {} + + smart-buffer@4.2.0: {} + + snooplogg@6.0.0-rc.1: {} + + socks-proxy-agent@8.0.3: + dependencies: + agent-base: 7.1.1 + debug: 4.3.5 + socks: 2.8.3 + transitivePeerDependencies: + - supports-color + + socks@2.8.3: + dependencies: + ip-address: 9.0.5 + smart-buffer: 4.2.0 + + source-map-js@1.2.0: {} + + sprintf-js@1.1.3: {} + + ssri@10.0.6: + dependencies: + minipass: 7.1.2 + + stackback@0.0.2: {} + + std-env@3.7.0: {} + + string-width@4.2.3: + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + + string-width@5.1.2: + dependencies: + eastasianwidth: 0.2.0 + emoji-regex: 9.2.2 + strip-ansi: 7.1.0 + + string_decoder@1.3.0: + dependencies: + safe-buffer: 5.2.1 + + strip-ansi@6.0.1: + dependencies: + ansi-regex: 5.0.1 + + strip-ansi@7.1.0: + dependencies: + ansi-regex: 6.0.1 + + strip-final-newline@3.0.0: {} + + strip-literal@2.1.0: + dependencies: + js-tokens: 9.0.0 + + supports-color@5.5.0: + dependencies: + has-flag: 3.0.0 + optional: true + + supports-color@7.2.0: + dependencies: + has-flag: 4.0.0 + + supports-preserve-symlinks-flag@1.0.0: {} + + tar-fs@2.1.1: + dependencies: + chownr: 1.1.4 + mkdirp-classic: 0.5.3 + pump: 3.0.0 + tar-stream: 2.2.0 + + tar-stream@2.2.0: + dependencies: + bl: 4.1.0 + end-of-stream: 1.4.4 + fs-constants: 1.0.0 + inherits: 2.0.4 + readable-stream: 3.6.2 + + tar@6.2.1: + dependencies: + chownr: 2.0.0 + fs-minipass: 2.1.0 + minipass: 5.0.0 + minizlib: 2.1.2 + mkdirp: 1.0.4 + yallist: 4.0.0 + + test-exclude@6.0.0: + dependencies: + '@istanbuljs/schema': 0.1.3 + glob: 7.2.3 + minimatch: 3.1.2 + + tinybench@2.8.0: {} + + tinypool@0.8.4: {} + + tinyspy@2.2.1: {} + + to-fast-properties@2.0.0: {} + + tslib@2.6.3: {} + + type-detect@4.0.8: {} + + typescript@5.5.2: {} + + ufo@1.5.3: {} + + undici-types@5.26.5: {} + + unique-filename@3.0.0: + dependencies: + unique-slug: 4.0.0 + + unique-slug@4.0.0: + dependencies: + imurmurhash: 0.1.4 + + util-deprecate@1.0.2: {} + + vite-node@1.6.0(@types/node@20.14.9): + dependencies: + cac: 6.7.14 + debug: 4.3.5 + pathe: 1.1.2 + picocolors: 1.0.1 + vite: 5.3.1(@types/node@20.14.9) + transitivePeerDependencies: + - '@types/node' + - less + - lightningcss + - sass + - stylus + - sugarss + - supports-color + - terser + + vite@5.3.1(@types/node@20.14.9): + dependencies: + esbuild: 0.21.5 + postcss: 8.4.38 + rollup: 4.18.0 + optionalDependencies: + '@types/node': 20.14.9 + fsevents: 2.3.3 + + vitest@1.6.0(@types/node@20.14.9): + dependencies: + '@vitest/expect': 1.6.0 + '@vitest/runner': 1.6.0 + '@vitest/snapshot': 1.6.0 + '@vitest/spy': 1.6.0 + '@vitest/utils': 1.6.0 + acorn-walk: 8.3.3 + chai: 4.4.1 + debug: 4.3.5 + execa: 8.0.1 + local-pkg: 0.5.0 + magic-string: 0.30.10 + pathe: 1.1.2 + picocolors: 1.0.1 + std-env: 3.7.0 + strip-literal: 2.1.0 + tinybench: 2.8.0 + tinypool: 0.8.4 + vite: 5.3.1(@types/node@20.14.9) + vite-node: 1.6.0(@types/node@20.14.9) + why-is-node-running: 2.2.2 + optionalDependencies: + '@types/node': 20.14.9 + transitivePeerDependencies: + - less + - lightningcss + - sass + - stylus + - sugarss + - supports-color + - terser + + which@2.0.2: + dependencies: + isexe: 2.0.0 + + which@4.0.0: + dependencies: + isexe: 3.1.1 + + why-is-node-running@2.2.2: + dependencies: + siginfo: 2.0.0 + stackback: 0.0.2 + + wrap-ansi@7.0.0: + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + + wrap-ansi@8.1.0: + dependencies: + ansi-styles: 6.2.1 + string-width: 5.1.2 + strip-ansi: 7.1.0 + + wrappy@1.0.2: {} + + yallist@4.0.0: {} + + yocto-queue@1.0.0: {} diff --git a/rollup.config.ts b/rollup.config.ts new file mode 100644 index 0000000..77fce6b --- /dev/null +++ b/rollup.config.ts @@ -0,0 +1,28 @@ +import { nodeResolve } from '@rollup/plugin-node-resolve'; +import typescript from '@rollup/plugin-typescript'; +import { defineConfig } from 'rollup'; +import { minify as esbuildMinifyPlugin } from 'rollup-plugin-esbuild'; + +export default defineConfig([ + { + input: './src/index.ts', + output: { + dir: './dist', + externalLiveBindings: false, + format: 'es', + freeze: false, + preserveModules: false, + sourcemap: true + }, + plugins: [ + nodeResolve({ preferBuiltins: true }), + esbuildMinifyPlugin({ + minify: true, + minifySyntax: true + }), + typescript({ + tsconfig: './tsconfig.build.json' + }) + ] + } +]); diff --git a/rollup.dts.config.ts b/rollup.dts.config.ts new file mode 100644 index 0000000..99397a7 --- /dev/null +++ b/rollup.dts.config.ts @@ -0,0 +1,19 @@ +import { nodeResolve } from '@rollup/plugin-node-resolve'; +import { defineConfig } from 'rollup'; +import { dts } from 'rollup-plugin-dts'; + +export default defineConfig([ + { + input: './temp/index.d.ts', + output: { + file: './dist/index.d.ts', + format: 'es' + }, + plugins: [ + nodeResolve({ preferBuiltins: true }), + dts({ + respectExternal: true + }) + ] + } +]); diff --git a/src/index.js b/src/index.js deleted file mode 100644 index 073d190..0000000 --- a/src/index.js +++ /dev/null @@ -1,77 +0,0 @@ -const binding = require('node-gyp-build')(`${__dirname}/..`); -const { EventEmitter } = require('events'); -const logger = require('snooplogg').default('winreglib'); -const nss = {}; - -/** - * The `winreglib` API and debug log emitter. - * - * @type {EventEmitter} - * @emits {log} Emits a debug log message. - */ -const api = module.exports = new EventEmitter(); - -binding.init((ns, msg) => { - api.emit('log', msg); - if (ns) { - (nss[ns] || (nss[ns] = logger(ns))).log(msg); - } else { - logger.log(msg); - } -}); - -/** - * Gets the value for a specific key value. - * - * @param {String} key - The key. - * @param {String} value - The name of the value to get. - * @returns {*} The value reflects the data type from the registry. - */ -api.get = function get(key, value) { - if (!key || typeof key !== 'string') { - throw new TypeError('Expected key to be a non-empty string'); - } - - if (!value || typeof value !== 'string') { - throw new TypeError('Expected value name to be a non-empty string'); - } - - return binding.get(key, value); -}; - -/** - * Lists all subkeys and values for a specific key. - * - * @param {String} key - The key to list. - * @returns {Object} Contains the resolved `root`, `path`, `subkeys`, and `values`. - */ -api.list = function list(key) { - if (!key || typeof key !== 'string') { - throw new TypeError('Expected key to be a non-empty string'); - } - - return binding.list(key); -}; - -/** - * Watches a key for changes to subkeys and values. - * - * @param {String} key - The key to watch. - * @returns {EventEmitter} The handle to wire up listeners and stop watching. - * @emits {change} Emits an event object containing the `key` that changed. - */ -api.watch = function watch(key) { - if (!key || typeof key !== 'string') { - throw new TypeError('Expected key to be a non-empty string'); - } - - const handle = new EventEmitter(); - const emit = handle.emit.bind(handle); - - binding.watch(key, emit); - handle.stop = function stop() { - binding.unwatch(key, emit); - }; - - return handle; -}; diff --git a/src/index.ts b/src/index.ts new file mode 100644 index 0000000..26d58ac --- /dev/null +++ b/src/index.ts @@ -0,0 +1,106 @@ +import { EventEmitter } from 'node:events'; +import { fileURLToPath } from 'node:url'; +import * as nodeGypBuild from 'node-gyp-build'; +import snooplogg, { type Logger } from 'snooplogg'; + +const binding = nodeGypBuild(`${fileURLToPath(import.meta.dirname)}/..`); + +const logger = snooplogg('winreglib'); + +export class WinRegLibWatchHandle extends EventEmitter { + key: string; + + constructor(key: string) { + super(); + this.key = key; + this.emit = this.emit.bind(this); + binding.watch(key, this.emit); + } + + stop() { + binding.unwatch(this.key, this.emit); + } +} + +export type RegistryKey = { + root: string; + path: string; + subkeys: string[]; + values: Record; +}; + +/** + * The `winreglib` API and debug log emitter. + * + * @type {EventEmitter} + * @emits {log} Emits a debug log message. + */ +class WinRegLib extends EventEmitter { + nss: Record = {}; + + constructor() { + super(); + + binding.init((ns: string, msg: string) => { + this.emit('log', msg); + if (ns) { + if (!this.nss[ns]) { + this.nss[ns] = logger(ns); + } + this.nss[ns].log(msg); + } else { + logger.log(msg); + } + }); + } + + /** + * Gets the value for a specific key value. + * + * @param {String} key - The key. + * @param {String} value - The name of the value to get. + * @returns {*} The value reflects the data type from the registry. + */ + get(key: string, value: string): unknown { + if (!key || typeof key !== 'string') { + throw new TypeError('Expected key to be a non-empty string'); + } + + if (!value || typeof value !== 'string') { + throw new TypeError('Expected value name to be a non-empty string'); + } + + return binding.get(key, value); + } + + /** + * Lists all subkeys and values for a specific key. + * + * @param {String} key - The key to list. + * @returns {Object} Contains the resolved `root`, `path`, `subkeys`, and `values`. + */ + list(key: string): RegistryKey { + if (!key || typeof key !== 'string') { + throw new TypeError('Expected key to be a non-empty string'); + } + + return binding.list(key); + } + + /** + * Watches a key for changes to subkeys and values. + * + * @param {String} key - The key to watch. + * @returns {EventEmitter} The handle to wire up listeners and stop watching. + * @emits {change} Emits an event object containing the `key` that changed. + */ + watch(key: string): WinRegLibWatchHandle { + if (!key || typeof key !== 'string') { + throw new TypeError('Expected key to be a non-empty string'); + } + + return new WinRegLibWatchHandle(key); + } +} + +export default new WinRegLib(); diff --git a/src/watchnode.h b/src/watchnode.h index 397e37d..0e63619 100644 --- a/src/watchnode.h +++ b/src/watchnode.h @@ -20,7 +20,7 @@ const DWORD filter = REG_NOTIFY_CHANGE_NAME | #define PUSH_CALLBACK(list, evtType, key, listeners) \ if (listeners.size() > 0) { \ - char* type = evtType; \ + char type[] = evtType; \ (list).push(std::make_shared(type, key, listeners)); \ } diff --git a/src/winreglib.cpp b/src/winreglib.cpp index 7a28e9e..41704b1 100644 --- a/src/winreglib.cpp +++ b/src/winreglib.cpp @@ -353,7 +353,7 @@ napi_value watchHelper(napi_env env, napi_callback_info info, winreglib::WatchAc } key = root + key.substr(p); - char* ns = action == winreglib::Watch ? "watch" : "unwatch"; + const char* ns = action == winreglib::Watch ? "watch" : "unwatch"; LOG_DEBUG_1(ns, L"key=\"%ls\"", key.c_str()) winreglib::watchman->config(key, listener, action); diff --git a/test/test-winreglib.js b/test/test-winreglib.js deleted file mode 100644 index f6a5518..0000000 --- a/test/test-winreglib.js +++ /dev/null @@ -1,725 +0,0 @@ -const fs = require('fs'); -const winreglib = require('../src/index'); -const { expect } = require('chai'); -const { spawnSync } = require('child_process'); -const snooplogg = require('snooplogg').default; - -const { log } = snooplogg('test:winreglib'); - -const reg = (...args) => { - log('Executing: reg ' + args.join(' ')); - spawnSync('reg', args, { stdio: 'ignore' }); -}; - -describe('get()', () => { - it('should error if key is not specified', () => { - try { - winreglib.get(); - } catch (e) { - expect(e.message).to.equal('Expected key to be a non-empty string'); - return; - } - throw new Error('Expected error'); - }); - - it('should error if value name is not specified', () => { - try { - winreglib.get('HKLM\\software'); - } catch (e) { - expect(e.message).to.equal('Expected value name to be a non-empty string'); - return; - } - throw new Error('Expected error'); - }); - - it('should error if key does not contain a subkey', () => { - try { - winreglib.get('foo', 'bar'); - } catch (e) { - expect(e.message).to.equal('Expected key to contain both a root and subkey'); - return; - } - throw new Error('Expected error'); - }); - - it('should error if key is not valid', () => { - try { - winreglib.get('foo\\bar', 'baz'); - } catch (e) { - expect(e.message).to.equal('Invalid registry root key "foo"'); - return; - } - throw new Error('Expected error'); - }); - - it('should error if key is not found', () => { - try { - winreglib.get('HKLM\\foo', 'bar'); - } catch (e) { - expect(e.message).to.equal('Registry key or value not found'); - return; - } - throw new Error('Expected error'); - }); - - it('should error if value is not found', () => { - try { - winreglib.get('HKLM\\SOFTWARE', 'bar'); - } catch (e) { - expect(e.message).to.equal('Registry key or value not found'); - return; - } - throw new Error('Expected error'); - }); - - it('should get a string value', () => { - const value = winreglib.get('HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion', 'ProgramFilesDir'); - expect(value).to.be.a('string'); - expect(value).to.not.equal(''); - expect(fs.existsSync(value)).to.be.true; - }); - - it('should get an expanded string value', () => { - const value = winreglib.get('HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion', 'ProgramFilesPath'); - expect(value).to.be.a('string'); - expect(value).to.not.equal(''); - expect(fs.existsSync(value)).to.be.true; - }); - - it('should get multi-string value', () => { - const value = winreglib.get('HKLM\\HARDWARE\\DESCRIPTION\\System', 'SystemBiosVersion'); - expect(value).to.be.an('array'); - expect(value).to.have.lengthOf.above(0); - for (const v of value) { - expect(v).to.be.a('string'); - expect(v).to.not.equal(''); - } - }); - - it('should get an 32-bit integer value', () => { - const value = winreglib.get('HKLM\\HARDWARE\\DESCRIPTION\\System', 'Capabilities'); - expect(value).to.be.a('number'); - expect(value).to.be.at.least(0); - }); - - it('should get an 64-bit integer value', () => { - const value = winreglib.get('HKLM\\Software\\Microsoft\\Windows\\CurrentVersion\\Diagnostics\\DiagTrack', 'TriggerCount'); - expect(value).to.be.a('number'); - expect(value).to.be.at.least(0); - }); - - it('should get a binary value', () => { - const value = winreglib.get('HKLM\\HARDWARE\\DESCRIPTION\\System', 'Component Information'); - expect(value).to.be.an.instanceof(Buffer); - expect(value.length).to.be.above(0); - }); - - it('should get a full resource descriptor value', () => { - const value = winreglib.get('HKLM\\HARDWARE\\DESCRIPTION\\System', 'Configuration Data'); - expect(value).to.be.an.instanceof(Buffer); - expect(value.length).to.be.above(0); - }); - - it('should get a resource list value', () => { - const value = winreglib.get('HKLM\\HARDWARE\\RESOURCEMAP\\System Resources\\Loader Reserved', '.Raw'); - expect(value).to.be.an.instanceof(Buffer); - expect(value.length).to.be.above(0); - }); - - it('should get none value', function () { - this.timeout(15000); - this.slow(14000); - - try { - reg('delete', 'HKCU\\Software\\winreglib', '/f'); - reg('add', 'HKCU\\Software\\winreglib'); - reg('add', 'HKCU\\Software\\winreglib', '/v', 'foo', '/t', 'REG_NONE'); - - const value = winreglib.get('HKCU\\Software\\winreglib', 'foo'); - expect(value).to.be.null; - } finally { - reg('delete', 'HKCU\\Software\\winreglib', '/f'); - } - }); -}); - -describe('list()', () => { - it('should error if key is not specified', () => { - try { - winreglib.list(); - } catch (e) { - expect(e.message).to.equal('Expected key to be a non-empty string'); - return; - } - throw new Error('Expected error'); - }); - - it('should error if key does not contain a subkey', () => { - try { - winreglib.list('foo'); - } catch (e) { - expect(e.message).to.equal('Expected key to contain both a root and subkey'); - return; - } - throw new Error('Expected error'); - }); - - it('should error if key is not valid', () => { - try { - winreglib.list('foo\\bar'); - } catch (e) { - expect(e.message).to.equal('Invalid registry root key "foo"'); - return; - } - throw new Error('Expected error'); - }); - - it('should error if key is not found', () => { - try { - winreglib.list('HKLM\\foo'); - } catch (e) { - expect(e.message).to.equal('Registry key or value not found'); - return; - } - throw new Error('Expected error'); - }); - - it('should retrieve subkeys and values', () => { - const result = winreglib.list('HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion'); - - expect(result).to.be.an('object'); - expect(result).to.have.keys('resolvedRoot', 'key', 'subkeys', 'values'); - - expect(result.resolvedRoot).to.equal('HKEY_LOCAL_MACHINE'); - expect(result.key).to.equal('HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion'); - - expect(result.subkeys).to.be.an('array'); - for (const key of result.subkeys) { - expect(key).to.be.a('string'); - expect(key).to.not.equal(''); - } - - expect(result.values).to.be.an('array'); - for (const value of result.values) { - expect(value).to.be.a('string'); - expect(value).to.not.equal(''); - } - }); -}); - -describe('watch()', () => { - it('should error if key is not specified', () => { - try { - winreglib.watch(); - } catch (e) { - expect(e.message).to.equal('Expected key to be a non-empty string'); - return; - } - throw new Error('Expected error'); - }); - - it('should error if key does not contain a subkey', () => { - try { - winreglib.watch('HKLM'); - } catch (e) { - expect(e.message).to.equal('Expected key to contain both a root and subkey'); - return; - } - throw new Error('Expected error'); - }); - - it('should error if root key is not valid', () => { - try { - winreglib.watch('foo\\bar'); - } catch (e) { - expect(e.message).to.equal('Invalid registry root key "foo"'); - return; - } - throw new Error('Expected error'); - }); - - it('should watch existing key for new subkey', async function () { - this.timeout(15000); - this.slow(14000); - - reg('delete', 'HKCU\\Software\\winreglib', '/f'); - reg('add', 'HKCU\\Software\\winreglib'); - - const handle = winreglib.watch('HKCU\\SOFTWARE\\winreglib'); - - try { - let counter = 0; - - await new Promise((resolve, reject) => { - handle.on('change', evt => { - // console.log('CHANGE!', evt); - try { - expect(evt).to.be.an('object'); - switch (counter++) { - case 0: - expect(evt).to.deep.equal({ - type: 'change', - key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib' - }); - reg('delete', 'HKCU\\Software\\winreglib\\foo', '/f'); - break; - - case 1: - expect(evt).to.deep.equal({ - type: 'change', - key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib' - }); - resolve(); - break; - } - } catch (e) { - reject(e); - } - }); - - setTimeout(() => reg('add', 'HKCU\\Software\\winreglib\\foo'), 500); - }); - handle.stop(); - } finally { - // also test stop() being called twice - handle.stop(); - reg('delete', 'HKCU\\Software\\winreglib', '/f'); - } - }); - - it('should watch existing key for value change', async function () { - this.timeout(15000); - this.slow(14000); - - reg('delete', 'HKCU\\Software\\winreglib', '/f'); - reg('add', 'HKCU\\Software\\winreglib'); - - const handle = winreglib.watch('HKCU\\SOFTWARE\\winreglib'); - - try { - let counter = 0; - - await new Promise((resolve, reject) => { - handle.on('change', evt => { - try { - expect(evt).to.be.an('object'); - switch (counter++) { - case 0: - expect(evt).to.deep.equal({ - type: 'change', - key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib' - }); - reg('delete', 'HKCU\\Software\\winreglib', '/f', '/v', 'foo'); - break; - - case 1: - expect(evt).to.deep.equal({ - type: 'change', - key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib' - }); - resolve(); - break; - } - } catch (e) { - reject(e); - } - }); - - setTimeout(() => reg('add', 'HKCU\\Software\\winreglib', '/v', 'foo', '/t', 'REG_SZ', '/d', 'bar'), 500); - }); - } finally { - handle.stop(); - reg('delete', 'HKCU\\Software\\winreglib', '/f'); - } - }); - - it('should watch a key that does not exist', async function () { - this.timeout(15000); - this.slow(14000); - - reg('delete', 'HKCU\\Software\\winreglib', '/f'); - reg('add', 'HKCU\\Software\\winreglib'); - - const handle = winreglib.watch('HKCU\\SOFTWARE\\winreglib\\foo'); - - try { - let counter = 0; - - await new Promise((resolve, reject) => { - handle.on('change', evt => { - // console.log('CHANGE!!', counter, evt); - try { - expect(evt).to.be.an('object'); - switch (counter++) { - case 0: - expect(evt).to.deep.equal({ - type: 'add', - key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib\\foo' - }); - reg('add', 'HKCU\\Software\\winreglib\\foo', '/v', 'bar', '/t', 'REG_SZ', '/d', 'baz'); - break; - - case 1: - expect(evt).to.deep.equal({ - type: 'change', - key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib\\foo' - }); - - reg('delete', 'HKCU\\Software\\winreglib\\foo', '/f', '/v', 'bar'); - break; - - case 2: - expect(evt).to.deep.equal({ - type: 'change', - key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib\\foo' - }); - - setTimeout(() => reg('delete', 'HKCU\\Software\\winreglib\\foo', '/f'), 500); - break; - - case 3: - expect(evt).to.deep.equal({ - type: 'delete', - key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib\\foo' - }); - setTimeout(() => reg('add', 'HKCU\\Software\\winreglib\\foo'), 500); - break; - - case 4: - expect(evt).to.deep.equal({ - type: 'add', - key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib\\foo' - }); - resolve(); - break; - } - } catch (e) { - reject(e); - } - }); - - setTimeout(() => reg('add', 'HKCU\\Software\\winreglib\\foo'), 500); - }); - } finally { - handle.stop(); - reg('delete', 'HKCU\\Software\\winreglib', '/f'); - } - }); - - it('should watch a key whose parent does not exist', async function () { - this.timeout(15000); - this.slow(14000); - - reg('delete', 'HKCU\\Software\\winreglib', '/f'); - reg('add', 'HKCU\\Software\\winreglib'); - - const handle = winreglib.watch('HKCU\\SOFTWARE\\winreglib\\foo\\bar\\baz'); - - try { - let counter = 0; - - await new Promise((resolve, reject) => { - handle.on('change', evt => { - // console.log('CHANGE!!', counter, evt); - try { - expect(evt).to.be.an('object'); - switch (counter++) { - case 0: - expect(evt).to.deep.equal({ - type: 'add', - key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib\\foo\\bar\\baz' - }); - reg('add', 'HKCU\\Software\\winreglib\\foo\\bar\\baz', '/v', 'val1', '/t', 'REG_SZ', '/d', 'hello1'); - break; - - case 1: - expect(evt).to.deep.equal({ - type: 'change', - key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib\\foo\\bar\\baz' - }); - - // this next line should not trigger anything - reg('add', 'HKCU\\Software\\winreglib\\foo', '/v', 'val2', '/t', 'REG_SZ', '/d', 'hello2'); - - setTimeout(() => { - reg('add', 'HKCU\\Software\\winreglib\\foo\\bar\\baz', '/v', 'val3', '/t', 'REG_SZ', '/d', 'hello3'); - }, 1000); - break; - - case 2: - expect(evt).to.deep.equal({ - type: 'change', - key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib\\foo\\bar\\baz' - }); - - setTimeout(() => { - reg('delete', 'HKCU\\Software\\winreglib', '/f'); - }, 1000); - break; - - case 3: - expect(evt).to.deep.equal({ - type: 'delete', - key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib\\foo\\bar\\baz' - }); - resolve(); - break; - } - } catch (e) { - reject(e); - } - }); - - setTimeout(() => reg('add', 'HKCU\\Software\\winreglib\\foo'), 500); - setTimeout(() => reg('add', 'HKCU\\Software\\winreglib\\foo\\bar\\baz\\wiz'), 2000); - }); - } finally { - handle.stop(); - reg('delete', 'HKCU\\Software\\winreglib', '/f'); - } - }); - - it('should watch a key that gets deleted', async function () { - this.timeout(15000); - this.slow(14000); - - reg('delete', 'HKCU\\Software\\winreglib', '/f'); - reg('add', 'HKCU\\Software\\winreglib\\foo'); - - const handle = winreglib.watch('HKCU\\SOFTWARE\\winreglib\\foo'); - - try { - let counter = 0; - - await new Promise((resolve, reject) => { - handle.on('change', evt => { - // console.log('CHANGE!', evt); - try { - expect(evt).to.be.an('object'); - switch (counter++) { - case 0: - expect(evt).to.deep.equal({ - type: 'delete', - key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib\\foo' - }); - resolve(); - break; - } - } catch (e) { - reject(e); - } - }); - - setTimeout(() => reg('delete', 'HKCU\\Software\\winreglib\\foo', '/f'), 500); - }); - handle.stop(); - } finally { - // also test stop() being called twice - handle.stop(); - reg('delete', 'HKCU\\Software\\winreglib', '/f'); - } - }); - - it('should watch a key whose parent gets deleted', async function () { - this.timeout(15000); - this.slow(14000); - - reg('delete', 'HKCU\\Software\\winreglib', '/f'); - reg('add', 'HKCU\\Software\\winreglib\\foo\\bar\\baz'); - - const handle = winreglib.watch('HKCU\\SOFTWARE\\winreglib\\foo\\bar\\baz'); - - try { - let counter = 0; - - await new Promise((resolve, reject) => { - handle.on('change', evt => { - // console.log('CHANGE!', evt); - try { - expect(evt).to.be.an('object'); - switch (counter++) { - case 0: - expect(evt).to.deep.equal({ - type: 'delete', - key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib\\foo\\bar\\baz' - }); - resolve(); - break; - } - } catch (e) { - reject(e); - } - }); - - setTimeout(() => reg('delete', 'HKCU\\Software\\winreglib\\foo', '/f'), 500); - }); - handle.stop(); - } finally { - // also test stop() being called twice - handle.stop(); - reg('delete', 'HKCU\\Software\\winreglib', '/f'); - } - }); - - it('should survive the gauntlet', async function () { - this.timeout(15000); - this.slow(14000); - - reg('delete', 'HKCU\\Software\\winreglib', '/f'); - reg('add', 'HKCU\\Software\\winreglib'); - - const winreglibHandle = winreglib.watch('HKCU\\SOFTWARE\\winreglib'); - const fooHandle = winreglib.watch('HKCU\\SOFTWARE\\winreglib\\foo'); - const barHandle = winreglib.watch('HKCU\\SOFTWARE\\winreglib\\foo\\bar'); - const bazHandle = winreglib.watch('HKCU\\SOFTWARE\\winreglib\\foo\\bar\\baz'); - - try { - let counter = 0; - - await new Promise((resolve, reject) => { - const fn = evt => { - // console.log('CHANGE!', evt); - try { - expect(evt).to.be.an('object'); - switch (counter++) { - case 0: - expect(evt).to.deep.equal({ - type: 'change', - key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib' - }); - break; - - case 1: - expect(evt).to.deep.equal({ - type: 'add', - key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib\\foo' - }); - break; - - case 2: - expect(evt).to.deep.equal({ - type: 'add', - key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib\\foo\\bar' - }); - reg('delete', 'HKCU\\Software\\winreglib\\foo\\bar', '/f'); - break; - - case 3: - expect(evt).to.deep.equal({ - type: 'change', - key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib\\foo' - }); - break; - - case 4: - expect(evt).to.deep.equal({ - type: 'delete', - key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib\\foo\\bar' - }); - reg('add', 'HKCU\\Software\\winreglib', '/v', 'foo', '/t', 'REG_SZ', '/d', 'bar'); - break; - - case 5: - expect(evt).to.deep.equal({ - type: 'change', - key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib' - }); - reg('add', 'HKCU\\Software\\winreglib\\foo\\bar\\wiz'); - break; - - case 6: - expect(evt).to.deep.equal({ - type: 'change', - key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib\\foo' - }); - break; - - case 7: - expect(evt).to.deep.equal({ - type: 'add', - key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib\\foo\\bar' - }); - reg('add', 'HKCU\\Software\\winreglib\\foo\\bar\\baz'); - break; - - case 8: - expect(evt).to.deep.equal({ - type: 'change', - key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib\\foo\\bar' - }); - break; - - case 9: - expect(evt).to.deep.equal({ - type: 'add', - key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib\\foo\\bar\\baz' - }); - reg('add', 'HKCU\\Software\\winreglib\\foo\\bar\\baz', '/v', 'foo', '/t', 'REG_SZ', '/d', 'bar'); - break; - - case 10: - expect(evt).to.deep.equal({ - type: 'change', - key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib\\foo\\bar\\baz' - }); - reg('delete', 'HKCU\\Software\\winreglib', '/f', '/v', 'foo'); - break; - - case 11: - expect(evt).to.deep.equal({ - type: 'change', - key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib' - }); - reg('delete', 'HKCU\\Software\\winreglib\\foo', '/f'); - break; - - case 12: - expect(evt).to.deep.equal({ - type: 'delete', - key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib\\foo\\bar\\baz' - }); - break; - - case 13: - expect(evt).to.deep.equal({ - type: 'delete', - key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib\\foo\\bar' - }); - break; - - case 14: - expect(evt).to.deep.equal({ - type: 'delete', - key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib\\foo' - }); - break; - - case 15: - expect(evt).to.deep.equal({ - type: 'change', - key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib' - }); - resolve(); - break; - } - } catch (e) { - reject(e); - } - }; - - winreglibHandle.on('change', fn); - fooHandle.on('change', fn); - barHandle.on('change', fn); - bazHandle.on('change', fn); - - setTimeout(() => reg('add', 'HKCU\\Software\\winreglib\\foo\\bar'), 500); - }); - } finally { - winreglibHandle.stop(); - fooHandle.stop(); - barHandle.stop(); - bazHandle.stop(); - reg('delete', 'HKCU\\Software\\winreglib', '/f'); - } - }); -}); diff --git a/test/wingreglib.test.ts b/test/wingreglib.test.ts new file mode 100644 index 0000000..eef010a --- /dev/null +++ b/test/wingreglib.test.ts @@ -0,0 +1,725 @@ +import fs from 'node:fs'; +import { describe, expect, it } from 'vitest'; +import * as winreglib from '../src/index.js'; +const { spawnSync } = require('node:child_process'); +import snooplogg from 'snooplogg'; + +const { log } = snooplogg('test:winreglib'); + +const reg = (...args) => { + log(`Executing: reg ${args.join(' ')}`); + spawnSync('reg', args, { stdio: 'ignore' }); +}; + +describe('get()', () => { + it('should error if key is not specified', () => { + try { + winreglib.get(); + } catch (e) { + expect(e.message).to.equal('Expected key to be a non-empty string'); + return; + } + throw new Error('Expected error'); + }); + + // it('should error if value name is not specified', () => { + // try { + // winreglib.get('HKLM\\software'); + // } catch (e) { + // expect(e.message).to.equal('Expected value name to be a non-empty string'); + // return; + // } + // throw new Error('Expected error'); + // }); + + // it('should error if key does not contain a subkey', () => { + // try { + // winreglib.get('foo', 'bar'); + // } catch (e) { + // expect(e.message).to.equal('Expected key to contain both a root and subkey'); + // return; + // } + // throw new Error('Expected error'); + // }); + + // it('should error if key is not valid', () => { + // try { + // winreglib.get('foo\\bar', 'baz'); + // } catch (e) { + // expect(e.message).to.equal('Invalid registry root key "foo"'); + // return; + // } + // throw new Error('Expected error'); + // }); + + // it('should error if key is not found', () => { + // try { + // winreglib.get('HKLM\\foo', 'bar'); + // } catch (e) { + // expect(e.message).to.equal('Registry key or value not found'); + // return; + // } + // throw new Error('Expected error'); + // }); + + // it('should error if value is not found', () => { + // try { + // winreglib.get('HKLM\\SOFTWARE', 'bar'); + // } catch (e) { + // expect(e.message).to.equal('Registry key or value not found'); + // return; + // } + // throw new Error('Expected error'); + // }); + + // it('should get a string value', () => { + // const value = winreglib.get('HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion', 'ProgramFilesDir'); + // expect(value).to.be.a('string'); + // expect(value).to.not.equal(''); + // expect(fs.existsSync(value)).to.be.true; + // }); + + // it('should get an expanded string value', () => { + // const value = winreglib.get('HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion', 'ProgramFilesPath'); + // expect(value).to.be.a('string'); + // expect(value).to.not.equal(''); + // expect(fs.existsSync(value)).to.be.true; + // }); + + // it('should get multi-string value', () => { + // const value = winreglib.get('HKLM\\HARDWARE\\DESCRIPTION\\System', 'SystemBiosVersion'); + // expect(value).to.be.an('array'); + // expect(value).to.have.lengthOf.above(0); + // for (const v of value) { + // expect(v).to.be.a('string'); + // expect(v).to.not.equal(''); + // } + // }); + + // it('should get an 32-bit integer value', () => { + // const value = winreglib.get('HKLM\\HARDWARE\\DESCRIPTION\\System', 'Capabilities'); + // expect(value).to.be.a('number'); + // expect(value).to.be.at.least(0); + // }); + + // it('should get an 64-bit integer value', () => { + // const value = winreglib.get('HKLM\\Software\\Microsoft\\Windows\\CurrentVersion\\Diagnostics\\DiagTrack', 'TriggerCount'); + // expect(value).to.be.a('number'); + // expect(value).to.be.at.least(0); + // }); + + // it('should get a binary value', () => { + // const value = winreglib.get('HKLM\\HARDWARE\\DESCRIPTION\\System', 'Component Information'); + // expect(value).to.be.an.instanceof(Buffer); + // expect(value.length).to.be.above(0); + // }); + + // it('should get a full resource descriptor value', () => { + // const value = winreglib.get('HKLM\\HARDWARE\\DESCRIPTION\\System', 'Configuration Data'); + // expect(value).to.be.an.instanceof(Buffer); + // expect(value.length).to.be.above(0); + // }); + + // it('should get a resource list value', () => { + // const value = winreglib.get('HKLM\\HARDWARE\\RESOURCEMAP\\System Resources\\Loader Reserved', '.Raw'); + // expect(value).to.be.an.instanceof(Buffer); + // expect(value.length).to.be.above(0); + // }); + + // it('should get none value', function () { + // this.timeout(15000); + // this.slow(14000); + + // try { + // reg('delete', 'HKCU\\Software\\winreglib', '/f'); + // reg('add', 'HKCU\\Software\\winreglib'); + // reg('add', 'HKCU\\Software\\winreglib', '/v', 'foo', '/t', 'REG_NONE'); + + // const value = winreglib.get('HKCU\\Software\\winreglib', 'foo'); + // expect(value).to.be.null; + // } finally { + // reg('delete', 'HKCU\\Software\\winreglib', '/f'); + // } + // }); + // }); + + // describe('list()', () => { + // it('should error if key is not specified', () => { + // try { + // winreglib.list(); + // } catch (e) { + // expect(e.message).to.equal('Expected key to be a non-empty string'); + // return; + // } + // throw new Error('Expected error'); + // }); + + // it('should error if key does not contain a subkey', () => { + // try { + // winreglib.list('foo'); + // } catch (e) { + // expect(e.message).to.equal('Expected key to contain both a root and subkey'); + // return; + // } + // throw new Error('Expected error'); + // }); + + // it('should error if key is not valid', () => { + // try { + // winreglib.list('foo\\bar'); + // } catch (e) { + // expect(e.message).to.equal('Invalid registry root key "foo"'); + // return; + // } + // throw new Error('Expected error'); + // }); + + // it('should error if key is not found', () => { + // try { + // winreglib.list('HKLM\\foo'); + // } catch (e) { + // expect(e.message).to.equal('Registry key or value not found'); + // return; + // } + // throw new Error('Expected error'); + // }); + + // it('should retrieve subkeys and values', () => { + // const result = winreglib.list('HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion'); + + // expect(result).to.be.an('object'); + // expect(result).to.have.keys('resolvedRoot', 'key', 'subkeys', 'values'); + + // expect(result.resolvedRoot).to.equal('HKEY_LOCAL_MACHINE'); + // expect(result.key).to.equal('HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion'); + + // expect(result.subkeys).to.be.an('array'); + // for (const key of result.subkeys) { + // expect(key).to.be.a('string'); + // expect(key).to.not.equal(''); + // } + + // expect(result.values).to.be.an('array'); + // for (const value of result.values) { + // expect(value).to.be.a('string'); + // expect(value).to.not.equal(''); + // } + // }); + // }); + + // describe('watch()', () => { + // it('should error if key is not specified', () => { + // try { + // winreglib.watch(); + // } catch (e) { + // expect(e.message).to.equal('Expected key to be a non-empty string'); + // return; + // } + // throw new Error('Expected error'); + // }); + + // it('should error if key does not contain a subkey', () => { + // try { + // winreglib.watch('HKLM'); + // } catch (e) { + // expect(e.message).to.equal('Expected key to contain both a root and subkey'); + // return; + // } + // throw new Error('Expected error'); + // }); + + // it('should error if root key is not valid', () => { + // try { + // winreglib.watch('foo\\bar'); + // } catch (e) { + // expect(e.message).to.equal('Invalid registry root key "foo"'); + // return; + // } + // throw new Error('Expected error'); + // }); + + // it('should watch existing key for new subkey', async function () { + // this.timeout(15000); + // this.slow(14000); + + // reg('delete', 'HKCU\\Software\\winreglib', '/f'); + // reg('add', 'HKCU\\Software\\winreglib'); + + // const handle = winreglib.watch('HKCU\\SOFTWARE\\winreglib'); + + // try { + // let counter = 0; + + // await new Promise((resolve, reject) => { + // handle.on('change', evt => { + // // console.log('CHANGE!', evt); + // try { + // expect(evt).to.be.an('object'); + // switch (counter++) { + // case 0: + // expect(evt).to.deep.equal({ + // type: 'change', + // key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib' + // }); + // reg('delete', 'HKCU\\Software\\winreglib\\foo', '/f'); + // break; + + // case 1: + // expect(evt).to.deep.equal({ + // type: 'change', + // key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib' + // }); + // resolve(); + // break; + // } + // } catch (e) { + // reject(e); + // } + // }); + + // setTimeout(() => reg('add', 'HKCU\\Software\\winreglib\\foo'), 500); + // }); + // handle.stop(); + // } finally { + // // also test stop() being called twice + // handle.stop(); + // reg('delete', 'HKCU\\Software\\winreglib', '/f'); + // } + // }); + + // it('should watch existing key for value change', async function () { + // this.timeout(15000); + // this.slow(14000); + + // reg('delete', 'HKCU\\Software\\winreglib', '/f'); + // reg('add', 'HKCU\\Software\\winreglib'); + + // const handle = winreglib.watch('HKCU\\SOFTWARE\\winreglib'); + + // try { + // let counter = 0; + + // await new Promise((resolve, reject) => { + // handle.on('change', evt => { + // try { + // expect(evt).to.be.an('object'); + // switch (counter++) { + // case 0: + // expect(evt).to.deep.equal({ + // type: 'change', + // key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib' + // }); + // reg('delete', 'HKCU\\Software\\winreglib', '/f', '/v', 'foo'); + // break; + + // case 1: + // expect(evt).to.deep.equal({ + // type: 'change', + // key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib' + // }); + // resolve(); + // break; + // } + // } catch (e) { + // reject(e); + // } + // }); + + // setTimeout(() => reg('add', 'HKCU\\Software\\winreglib', '/v', 'foo', '/t', 'REG_SZ', '/d', 'bar'), 500); + // }); + // } finally { + // handle.stop(); + // reg('delete', 'HKCU\\Software\\winreglib', '/f'); + // } + // }); + + // it('should watch a key that does not exist', async function () { + // this.timeout(15000); + // this.slow(14000); + + // reg('delete', 'HKCU\\Software\\winreglib', '/f'); + // reg('add', 'HKCU\\Software\\winreglib'); + + // const handle = winreglib.watch('HKCU\\SOFTWARE\\winreglib\\foo'); + + // try { + // let counter = 0; + + // await new Promise((resolve, reject) => { + // handle.on('change', evt => { + // // console.log('CHANGE!!', counter, evt); + // try { + // expect(evt).to.be.an('object'); + // switch (counter++) { + // case 0: + // expect(evt).to.deep.equal({ + // type: 'add', + // key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib\\foo' + // }); + // reg('add', 'HKCU\\Software\\winreglib\\foo', '/v', 'bar', '/t', 'REG_SZ', '/d', 'baz'); + // break; + + // case 1: + // expect(evt).to.deep.equal({ + // type: 'change', + // key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib\\foo' + // }); + + // reg('delete', 'HKCU\\Software\\winreglib\\foo', '/f', '/v', 'bar'); + // break; + + // case 2: + // expect(evt).to.deep.equal({ + // type: 'change', + // key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib\\foo' + // }); + + // setTimeout(() => reg('delete', 'HKCU\\Software\\winreglib\\foo', '/f'), 500); + // break; + + // case 3: + // expect(evt).to.deep.equal({ + // type: 'delete', + // key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib\\foo' + // }); + // setTimeout(() => reg('add', 'HKCU\\Software\\winreglib\\foo'), 500); + // break; + + // case 4: + // expect(evt).to.deep.equal({ + // type: 'add', + // key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib\\foo' + // }); + // resolve(); + // break; + // } + // } catch (e) { + // reject(e); + // } + // }); + + // setTimeout(() => reg('add', 'HKCU\\Software\\winreglib\\foo'), 500); + // }); + // } finally { + // handle.stop(); + // reg('delete', 'HKCU\\Software\\winreglib', '/f'); + // } + // }); + + // it('should watch a key whose parent does not exist', async function () { + // this.timeout(15000); + // this.slow(14000); + + // reg('delete', 'HKCU\\Software\\winreglib', '/f'); + // reg('add', 'HKCU\\Software\\winreglib'); + + // const handle = winreglib.watch('HKCU\\SOFTWARE\\winreglib\\foo\\bar\\baz'); + + // try { + // let counter = 0; + + // await new Promise((resolve, reject) => { + // handle.on('change', evt => { + // // console.log('CHANGE!!', counter, evt); + // try { + // expect(evt).to.be.an('object'); + // switch (counter++) { + // case 0: + // expect(evt).to.deep.equal({ + // type: 'add', + // key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib\\foo\\bar\\baz' + // }); + // reg('add', 'HKCU\\Software\\winreglib\\foo\\bar\\baz', '/v', 'val1', '/t', 'REG_SZ', '/d', 'hello1'); + // break; + + // case 1: + // expect(evt).to.deep.equal({ + // type: 'change', + // key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib\\foo\\bar\\baz' + // }); + + // // this next line should not trigger anything + // reg('add', 'HKCU\\Software\\winreglib\\foo', '/v', 'val2', '/t', 'REG_SZ', '/d', 'hello2'); + + // setTimeout(() => { + // reg('add', 'HKCU\\Software\\winreglib\\foo\\bar\\baz', '/v', 'val3', '/t', 'REG_SZ', '/d', 'hello3'); + // }, 1000); + // break; + + // case 2: + // expect(evt).to.deep.equal({ + // type: 'change', + // key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib\\foo\\bar\\baz' + // }); + + // setTimeout(() => { + // reg('delete', 'HKCU\\Software\\winreglib', '/f'); + // }, 1000); + // break; + + // case 3: + // expect(evt).to.deep.equal({ + // type: 'delete', + // key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib\\foo\\bar\\baz' + // }); + // resolve(); + // break; + // } + // } catch (e) { + // reject(e); + // } + // }); + + // setTimeout(() => reg('add', 'HKCU\\Software\\winreglib\\foo'), 500); + // setTimeout(() => reg('add', 'HKCU\\Software\\winreglib\\foo\\bar\\baz\\wiz'), 2000); + // }); + // } finally { + // handle.stop(); + // reg('delete', 'HKCU\\Software\\winreglib', '/f'); + // } + // }); + + // it('should watch a key that gets deleted', async function () { + // this.timeout(15000); + // this.slow(14000); + + // reg('delete', 'HKCU\\Software\\winreglib', '/f'); + // reg('add', 'HKCU\\Software\\winreglib\\foo'); + + // const handle = winreglib.watch('HKCU\\SOFTWARE\\winreglib\\foo'); + + // try { + // let counter = 0; + + // await new Promise((resolve, reject) => { + // handle.on('change', evt => { + // // console.log('CHANGE!', evt); + // try { + // expect(evt).to.be.an('object'); + // switch (counter++) { + // case 0: + // expect(evt).to.deep.equal({ + // type: 'delete', + // key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib\\foo' + // }); + // resolve(); + // break; + // } + // } catch (e) { + // reject(e); + // } + // }); + + // setTimeout(() => reg('delete', 'HKCU\\Software\\winreglib\\foo', '/f'), 500); + // }); + // handle.stop(); + // } finally { + // // also test stop() being called twice + // handle.stop(); + // reg('delete', 'HKCU\\Software\\winreglib', '/f'); + // } + // }); + + // it('should watch a key whose parent gets deleted', async function () { + // this.timeout(15000); + // this.slow(14000); + + // reg('delete', 'HKCU\\Software\\winreglib', '/f'); + // reg('add', 'HKCU\\Software\\winreglib\\foo\\bar\\baz'); + + // const handle = winreglib.watch('HKCU\\SOFTWARE\\winreglib\\foo\\bar\\baz'); + + // try { + // let counter = 0; + + // await new Promise((resolve, reject) => { + // handle.on('change', evt => { + // // console.log('CHANGE!', evt); + // try { + // expect(evt).to.be.an('object'); + // switch (counter++) { + // case 0: + // expect(evt).to.deep.equal({ + // type: 'delete', + // key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib\\foo\\bar\\baz' + // }); + // resolve(); + // break; + // } + // } catch (e) { + // reject(e); + // } + // }); + + // setTimeout(() => reg('delete', 'HKCU\\Software\\winreglib\\foo', '/f'), 500); + // }); + // handle.stop(); + // } finally { + // // also test stop() being called twice + // handle.stop(); + // reg('delete', 'HKCU\\Software\\winreglib', '/f'); + // } + // }); + + // it('should survive the gauntlet', async function () { + // this.timeout(15000); + // this.slow(14000); + + // reg('delete', 'HKCU\\Software\\winreglib', '/f'); + // reg('add', 'HKCU\\Software\\winreglib'); + + // const winreglibHandle = winreglib.watch('HKCU\\SOFTWARE\\winreglib'); + // const fooHandle = winreglib.watch('HKCU\\SOFTWARE\\winreglib\\foo'); + // const barHandle = winreglib.watch('HKCU\\SOFTWARE\\winreglib\\foo\\bar'); + // const bazHandle = winreglib.watch('HKCU\\SOFTWARE\\winreglib\\foo\\bar\\baz'); + + // try { + // let counter = 0; + + // await new Promise((resolve, reject) => { + // const fn = evt => { + // // console.log('CHANGE!', evt); + // try { + // expect(evt).to.be.an('object'); + // switch (counter++) { + // case 0: + // expect(evt).to.deep.equal({ + // type: 'change', + // key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib' + // }); + // break; + + // case 1: + // expect(evt).to.deep.equal({ + // type: 'add', + // key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib\\foo' + // }); + // break; + + // case 2: + // expect(evt).to.deep.equal({ + // type: 'add', + // key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib\\foo\\bar' + // }); + // reg('delete', 'HKCU\\Software\\winreglib\\foo\\bar', '/f'); + // break; + + // case 3: + // expect(evt).to.deep.equal({ + // type: 'change', + // key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib\\foo' + // }); + // break; + + // case 4: + // expect(evt).to.deep.equal({ + // type: 'delete', + // key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib\\foo\\bar' + // }); + // reg('add', 'HKCU\\Software\\winreglib', '/v', 'foo', '/t', 'REG_SZ', '/d', 'bar'); + // break; + + // case 5: + // expect(evt).to.deep.equal({ + // type: 'change', + // key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib' + // }); + // reg('add', 'HKCU\\Software\\winreglib\\foo\\bar\\wiz'); + // break; + + // case 6: + // expect(evt).to.deep.equal({ + // type: 'change', + // key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib\\foo' + // }); + // break; + + // case 7: + // expect(evt).to.deep.equal({ + // type: 'add', + // key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib\\foo\\bar' + // }); + // reg('add', 'HKCU\\Software\\winreglib\\foo\\bar\\baz'); + // break; + + // case 8: + // expect(evt).to.deep.equal({ + // type: 'change', + // key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib\\foo\\bar' + // }); + // break; + + // case 9: + // expect(evt).to.deep.equal({ + // type: 'add', + // key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib\\foo\\bar\\baz' + // }); + // reg('add', 'HKCU\\Software\\winreglib\\foo\\bar\\baz', '/v', 'foo', '/t', 'REG_SZ', '/d', 'bar'); + // break; + + // case 10: + // expect(evt).to.deep.equal({ + // type: 'change', + // key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib\\foo\\bar\\baz' + // }); + // reg('delete', 'HKCU\\Software\\winreglib', '/f', '/v', 'foo'); + // break; + + // case 11: + // expect(evt).to.deep.equal({ + // type: 'change', + // key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib' + // }); + // reg('delete', 'HKCU\\Software\\winreglib\\foo', '/f'); + // break; + + // case 12: + // expect(evt).to.deep.equal({ + // type: 'delete', + // key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib\\foo\\bar\\baz' + // }); + // break; + + // case 13: + // expect(evt).to.deep.equal({ + // type: 'delete', + // key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib\\foo\\bar' + // }); + // break; + + // case 14: + // expect(evt).to.deep.equal({ + // type: 'delete', + // key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib\\foo' + // }); + // break; + + // case 15: + // expect(evt).to.deep.equal({ + // type: 'change', + // key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib' + // }); + // resolve(); + // break; + // } + // } catch (e) { + // reject(e); + // } + // }; + + // winreglibHandle.on('change', fn); + // fooHandle.on('change', fn); + // barHandle.on('change', fn); + // bazHandle.on('change', fn); + + // setTimeout(() => reg('add', 'HKCU\\Software\\winreglib\\foo\\bar'), 500); + // }); + // } finally { + // winreglibHandle.stop(); + // fooHandle.stop(); + // barHandle.stop(); + // bazHandle.stop(); + // reg('delete', 'HKCU\\Software\\winreglib', '/f'); + // } + // }); +}); diff --git a/tsconfig.build.json b/tsconfig.build.json new file mode 100644 index 0000000..58fbd1d --- /dev/null +++ b/tsconfig.build.json @@ -0,0 +1,10 @@ +{ + "compilerOptions": { + "module": "esnext", + "moduleResolution": "Bundler", + "rootDir": "./src", + "sourceMap": true + }, + "extends": "./tsconfig.json", + "include": ["./src"] +} diff --git a/tsconfig.check.json b/tsconfig.check.json new file mode 100644 index 0000000..c473fed --- /dev/null +++ b/tsconfig.check.json @@ -0,0 +1,8 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "noEmit": true + }, + "include": ["./dist"], + "exclude": [] +} diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..f17b8a3 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,28 @@ +{ + "compilerOptions": { + "allowJs": true, + "composite": false, + "declaration": false, + "declarationMap": false, + "esModuleInterop": false, + "forceConsistentCasingInFileNames": true, + "inlineSources": false, + "isolatedModules": true, + "lib": ["esnext"], + "module": "esnext", + "moduleResolution": "node", + "noImplicitAny": false, + "noUnusedLocals": false, + "noUnusedParameters": false, + "outDir": "./dist", + "preserveWatchOutput": true, + "removeComments": true, + "skipLibCheck": true, + "strict": true, + "sourceMap": false, + "target": "esnext", + "typeRoots": ["./node_modules/@types"], + "types": ["node"] + }, + "include": ["./rollup.config.ts", "./rollup.dts.config.ts", "./src"] +} diff --git a/vitest.config.ts b/vitest.config.ts new file mode 100644 index 0000000..0e7f05c --- /dev/null +++ b/vitest.config.ts @@ -0,0 +1,14 @@ +import { defineConfig } from 'vitest/config'; + +export default defineConfig({ + test: { + coverage: { + include: ['src/**/*.ts'], + reporter: ['html', 'lcov', 'text'] + }, + environment: 'node', + globals: false, + include: ['test/**/*.test.ts'], + watch: false + } +}); diff --git a/yarn.lock b/yarn.lock deleted file mode 100644 index 1561da6..0000000 --- a/yarn.lock +++ /dev/null @@ -1,1476 +0,0 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. -# yarn lockfile v1 - - -"@ungap/promise-all-settled@1.1.2": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz#aa58042711d6e3275dd37dc597e5d31e8c290a44" - integrity sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q== - -abbrev@1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" - integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== - -ajv@^6.12.3: - version "6.12.6" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" - integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== - dependencies: - fast-deep-equal "^3.1.1" - fast-json-stable-stringify "^2.0.0" - json-schema-traverse "^0.4.1" - uri-js "^4.2.2" - -ansi-colors@4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" - integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA== - -ansi-regex@^2.0.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" - integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8= - -ansi-regex@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" - integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg= - -ansi-regex@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997" - integrity sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg== - -ansi-styles@^3.2.0: - version "3.2.1" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" - integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== - dependencies: - color-convert "^1.9.0" - -ansi-styles@^4.1.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" - integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== - dependencies: - color-convert "^2.0.1" - -anymatch@~3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.1.tgz#c55ecf02185e2469259399310c173ce31233b142" - integrity sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg== - dependencies: - normalize-path "^3.0.0" - picomatch "^2.0.4" - -aproba@^1.0.3: - version "1.2.0" - resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" - integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw== - -are-we-there-yet@~1.1.2: - version "1.1.5" - resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz#4b35c2944f062a8bfcda66410760350fe9ddfc21" - integrity sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w== - dependencies: - delegates "^1.0.0" - readable-stream "^2.0.6" - -argparse@^1.0.7: - version "1.0.10" - resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" - integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== - dependencies: - sprintf-js "~1.0.2" - -asn1@~0.2.3: - version "0.2.4" - resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.4.tgz#8d2475dfab553bb33e77b54e59e880bb8ce23136" - integrity sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg== - dependencies: - safer-buffer "~2.1.0" - -assert-plus@1.0.0, assert-plus@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" - integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU= - -assertion-error@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-1.1.0.tgz#e60b6b0e8f301bd97e5375215bda406c85118c0b" - integrity sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw== - -asynckit@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" - integrity sha1-x57Zf380y48robyXkLzDZkdLS3k= - -aws-sign2@~0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" - integrity sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg= - -aws4@^1.8.0: - version "1.11.0" - resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.11.0.tgz#d61f46d83b2519250e2784daf5b09479a8b41c59" - integrity sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA== - -balanced-match@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" - integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= - -base64-js@^1.1.2, base64-js@^1.3.1: - version "1.5.1" - resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" - integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== - -bcrypt-pbkdf@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e" - integrity sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4= - dependencies: - tweetnacl "^0.14.3" - -binary-extensions@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.1.0.tgz#30fa40c9e7fe07dbc895678cd287024dea241dd9" - integrity sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ== - -bl@^4.0.3: - version "4.0.3" - resolved "https://registry.yarnpkg.com/bl/-/bl-4.0.3.tgz#12d6287adc29080e22a705e5764b2a9522cdc489" - integrity sha512-fs4G6/Hu4/EE+F75J8DuN/0IpQqNjAdC7aEQv7Qt8MHGUH7Ckv2MwTEEeN9QehD0pfIDkMI1bkHYkKy7xHyKIg== - dependencies: - buffer "^5.5.0" - inherits "^2.0.4" - readable-stream "^3.4.0" - -brace-expansion@^1.1.7: - version "1.1.11" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" - integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== - dependencies: - balanced-match "^1.0.0" - concat-map "0.0.1" - -braces@~3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" - integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== - dependencies: - fill-range "^7.0.1" - -brotli@^1.3.2: - version "1.3.2" - resolved "https://registry.yarnpkg.com/brotli/-/brotli-1.3.2.tgz#525a9cad4fcba96475d7d388f6aecb13eed52f46" - integrity sha1-UlqcrU/LqWR119OI9q7LE+7VL0Y= - dependencies: - base64-js "^1.1.2" - -browser-stdout@1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60" - integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw== - -bryt@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/bryt/-/bryt-1.0.2.tgz#041b58d0038aabb7517920e4d7ccad27f172cdd3" - integrity sha512-K/qt3xOAOU71q5Y2yJKOqleBwfeJ3J5tOn1pds9b/iQvQ/cq984oSzuv6iOXRxoTdZH3WGOazX1HXu0+sLU7VA== - dependencies: - brotli "^1.3.2" - -buffer-from@^1.0.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" - integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A== - -buffer@^5.5.0: - version "5.7.1" - resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0" - integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ== - dependencies: - base64-js "^1.3.1" - ieee754 "^1.1.13" - -camelcase@^5.0.0: - version "5.3.1" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" - integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== - -camelcase@^6.0.0: - version "6.2.0" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.2.0.tgz#924af881c9d525ac9d87f40d964e5cea982a1809" - integrity sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg== - -caseless@~0.12.0: - version "0.12.0" - resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" - integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= - -chai@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/chai/-/chai-4.2.0.tgz#760aa72cf20e3795e84b12877ce0e83737aa29e5" - integrity sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw== - dependencies: - assertion-error "^1.1.0" - check-error "^1.0.2" - deep-eql "^3.0.1" - get-func-name "^2.0.0" - pathval "^1.1.0" - type-detect "^4.0.5" - -chalk@^4.0.0, chalk@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.0.tgz#4e14870a618d9e2edd97dd8345fd9d9dc315646a" - integrity sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A== - dependencies: - ansi-styles "^4.1.0" - supports-color "^7.1.0" - -check-error@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/check-error/-/check-error-1.0.2.tgz#574d312edd88bb5dd8912e9286dd6c0aed4aac82" - integrity sha1-V00xLt2Iu13YkS6Sht1sCu1KrII= - -chokidar@3.4.3: - version "3.4.3" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.4.3.tgz#c1df38231448e45ca4ac588e6c79573ba6a57d5b" - integrity sha512-DtM3g7juCXQxFVSNPNByEC2+NImtBuxQQvWlHunpJIS5Ocr0lG306cC7FCi7cEA0fzmybPUIl4txBIobk1gGOQ== - dependencies: - anymatch "~3.1.1" - braces "~3.0.2" - glob-parent "~5.1.0" - is-binary-path "~2.1.0" - is-glob "~4.0.1" - normalize-path "~3.0.0" - readdirp "~3.5.0" - optionalDependencies: - fsevents "~2.1.2" - -chownr@^1.1.1: - version "1.1.4" - resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b" - integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg== - -chownr@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/chownr/-/chownr-2.0.0.tgz#15bfbe53d2eab4cf70f18a8cd68ebe5b3cb1dece" - integrity sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ== - -cliui@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-5.0.0.tgz#deefcfdb2e800784aa34f46fa08e06851c7bbbc5" - integrity sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA== - dependencies: - string-width "^3.1.0" - strip-ansi "^5.2.0" - wrap-ansi "^5.1.0" - -code-point-at@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" - integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c= - -color-convert@^1.9.0: - version "1.9.3" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" - integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== - dependencies: - color-name "1.1.3" - -color-convert@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" - integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== - dependencies: - color-name "~1.1.4" - -color-name@1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" - integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= - -color-name@~1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" - integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== - -combined-stream@^1.0.6, combined-stream@~1.0.6: - version "1.0.8" - resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" - integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== - dependencies: - delayed-stream "~1.0.0" - -concat-map@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" - integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= - -console-control-strings@^1.0.0, console-control-strings@~1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" - integrity sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4= - -core-util-is@1.0.2, core-util-is@~1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" - integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= - -dashdash@^1.12.0: - version "1.14.1" - resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" - integrity sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA= - dependencies: - assert-plus "^1.0.0" - -debug@4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.2.0.tgz#7f150f93920e94c58f5574c2fd01a3110effe7f1" - integrity sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg== - dependencies: - ms "2.1.2" - -decamelize@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" - integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= - -decamelize@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-4.0.0.tgz#aa472d7bf660eb15f3494efd531cab7f2a709837" - integrity sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ== - -deep-eql@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-3.0.1.tgz#dfc9404400ad1c8fe023e7da1df1c147c4b444df" - integrity sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw== - dependencies: - type-detect "^4.0.0" - -delayed-stream@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" - integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk= - -delegates@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" - integrity sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o= - -diff@4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.1.tgz#0c667cb467ebbb5cea7f14f135cc2dba7780a8ff" - integrity sha512-s2+XdvhPCOF01LRQBC8hf4vhbVmI2CGS5aZnxLJlT5FtdhPCDFq80q++zK2KlrVorVDdL5BOGZ/VfLrVtYNF+Q== - -diff@4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d" - integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== - -ecc-jsbn@~0.1.1: - version "0.1.2" - resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9" - integrity sha1-OoOpBOVDUyh4dMVkt1SThoSamMk= - dependencies: - jsbn "~0.1.0" - safer-buffer "^2.1.0" - -emoji-regex@^7.0.1: - version "7.0.3" - resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156" - integrity sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA== - -end-of-stream@^1.1.0, end-of-stream@^1.4.1: - version "1.4.4" - resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" - integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== - dependencies: - once "^1.4.0" - -env-paths@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/env-paths/-/env-paths-2.2.0.tgz#cdca557dc009152917d6166e2febe1f039685e43" - integrity sha512-6u0VYSCo/OW6IoD5WCLLy9JUGARbamfSavcNXry/eu8aHVFei6CD3Sw+VGX5alea1i9pgPHW0mbu6Xj0uBh7gA== - -escape-string-regexp@4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" - integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== - -esprima@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" - integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== - -execspawn@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/execspawn/-/execspawn-1.0.1.tgz#8286f9dde7cecde7905fbdc04e24f368f23f8da6" - integrity sha1-gob53efOzeeQX73ATiTzaPI/jaY= - dependencies: - util-extend "^1.0.1" - -extend@~3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" - integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== - -extsprintf@1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" - integrity sha1-lpGEQOMEGnpBT4xS48V06zw+HgU= - -extsprintf@^1.2.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f" - integrity sha1-4mifjzVvrWLMplo6kcXfX5VRaS8= - -fast-deep-equal@^3.1.1: - version "3.1.3" - resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" - integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== - -fast-json-stable-stringify@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" - integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== - -fill-range@^7.0.1: - version "7.0.1" - resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" - integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== - dependencies: - to-regex-range "^5.0.1" - -find-up@5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" - integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== - dependencies: - locate-path "^6.0.0" - path-exists "^4.0.0" - -find-up@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73" - integrity sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg== - dependencies: - locate-path "^3.0.0" - -flat@^5.0.2: - version "5.0.2" - resolved "https://registry.yarnpkg.com/flat/-/flat-5.0.2.tgz#8ca6fe332069ffa9d324c327198c598259ceb241" - integrity sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ== - -forever-agent@~0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" - integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE= - -form-data@~2.3.2: - version "2.3.3" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" - integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ== - dependencies: - asynckit "^0.4.0" - combined-stream "^1.0.6" - mime-types "^2.1.12" - -fs-constants@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad" - integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow== - -fs-minipass@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-2.1.0.tgz#7f5036fdbf12c63c169190cbe4199c852271f9fb" - integrity sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg== - dependencies: - minipass "^3.0.0" - -fs.realpath@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" - integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= - -fsevents@~2.1.2: - version "2.1.3" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.1.3.tgz#fb738703ae8d2f9fe900c33836ddebee8b97f23e" - integrity sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ== - -gauge@~2.7.3: - version "2.7.4" - resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" - integrity sha1-LANAXHU4w51+s3sxcCLjJfsBi/c= - dependencies: - aproba "^1.0.3" - console-control-strings "^1.0.0" - has-unicode "^2.0.0" - object-assign "^4.1.0" - signal-exit "^3.0.0" - string-width "^1.0.1" - strip-ansi "^3.0.1" - wide-align "^1.1.0" - -get-caller-file@^2.0.1: - version "2.0.5" - resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" - integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== - -get-func-name@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/get-func-name/-/get-func-name-2.0.0.tgz#ead774abee72e20409433a066366023dd6887a41" - integrity sha1-6td0q+5y4gQJQzoGY2YCPdaIekE= - -getpass@^0.1.1: - version "0.1.7" - resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" - integrity sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo= - dependencies: - assert-plus "^1.0.0" - -glob-parent@~5.1.0: - version "5.1.1" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.1.tgz#b6c1ef417c4e5663ea498f1c45afac6916bbc229" - integrity sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ== - dependencies: - is-glob "^4.0.1" - -glob@7.1.6, glob@^7.1.3, glob@^7.1.4: - version "7.1.6" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" - integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.0.4" - once "^1.3.0" - path-is-absolute "^1.0.0" - -graceful-fs@^4.2.3: - version "4.2.4" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.4.tgz#2256bde14d3632958c465ebc96dc467ca07a29fb" - integrity sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw== - -growl@1.10.5: - version "1.10.5" - resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.5.tgz#f2735dc2283674fa67478b10181059355c369e5e" - integrity sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA== - -har-schema@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" - integrity sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI= - -har-validator@~5.1.3: - version "5.1.5" - resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.5.tgz#1f0803b9f8cb20c0fa13822df1ecddb36bde1efd" - integrity sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w== - dependencies: - ajv "^6.12.3" - har-schema "^2.0.0" - -has-flag@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" - integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== - -has-unicode@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" - integrity sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk= - -he@1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" - integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== - -http-signature@~1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" - integrity sha1-muzZJRFHcvPZW2WmCruPfBj7rOE= - dependencies: - assert-plus "^1.0.0" - jsprim "^1.2.2" - sshpk "^1.7.0" - -ieee754@^1.1.13: - version "1.2.1" - resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" - integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== - -inflight@^1.0.4: - version "1.0.6" - resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" - integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= - dependencies: - once "^1.3.0" - wrappy "1" - -inherits@2, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.3: - version "2.0.4" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" - integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== - -is-binary-path@~2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" - integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== - dependencies: - binary-extensions "^2.0.0" - -is-extglob@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" - integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= - -is-fullwidth-code-point@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" - integrity sha1-754xOG8DGn8NZDr4L95QxFfvAMs= - dependencies: - number-is-nan "^1.0.0" - -is-fullwidth-code-point@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" - integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= - -is-glob@^4.0.1, is-glob@~4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc" - integrity sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg== - dependencies: - is-extglob "^2.1.1" - -is-number@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" - integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== - -is-plain-obj@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-2.1.0.tgz#45e42e37fccf1f40da8e5f76ee21515840c09287" - integrity sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA== - -is-typedarray@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" - integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= - -isarray@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" - integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= - -isexe@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" - integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= - -isstream@~0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" - integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo= - -js-yaml@3.14.0: - version "3.14.0" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.0.tgz#a7a34170f26a21bb162424d8adacb4113a69e482" - integrity sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A== - dependencies: - argparse "^1.0.7" - esprima "^4.0.0" - -jsbn@~0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" - integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM= - -json-schema-traverse@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" - integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== - -json-schema@0.2.3: - version "0.2.3" - resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" - integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM= - -json-stringify-safe@~5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" - integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= - -jsprim@^1.2.2: - version "1.4.1" - resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" - integrity sha1-MT5mvB5cwG5Di8G3SZwuXFastqI= - dependencies: - assert-plus "1.0.0" - extsprintf "1.3.0" - json-schema "0.2.3" - verror "1.10.0" - -locate-path@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e" - integrity sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A== - dependencies: - p-locate "^3.0.0" - path-exists "^3.0.0" - -locate-path@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" - integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== - dependencies: - p-locate "^5.0.0" - -log-symbols@4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-4.0.0.tgz#69b3cc46d20f448eccdb75ea1fa733d9e821c920" - integrity sha512-FN8JBzLx6CzeMrB0tg6pqlGU1wCrXW+ZXGH481kfsBqer0hToTIiHdjH4Mq8xJUbvATujKCvaREGWpGUionraA== - dependencies: - chalk "^4.0.0" - -mime-db@1.44.0: - version "1.44.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.44.0.tgz#fa11c5eb0aca1334b4233cb4d52f10c5a6272f92" - integrity sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg== - -mime-types@^2.1.12, mime-types@~2.1.19: - version "2.1.27" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.27.tgz#47949f98e279ea53119f5722e0f34e529bec009f" - integrity sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w== - dependencies: - mime-db "1.44.0" - -minimatch@3.0.4, minimatch@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" - integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== - dependencies: - brace-expansion "^1.1.7" - -minimist@^1.2.0, minimist@^1.2.5: - version "1.2.5" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" - integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== - -minipass@^3.0.0: - version "3.1.3" - resolved "https://registry.yarnpkg.com/minipass/-/minipass-3.1.3.tgz#7d42ff1f39635482e15f9cdb53184deebd5815fd" - integrity sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg== - dependencies: - yallist "^4.0.0" - -minizlib@^2.1.1: - version "2.1.2" - resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-2.1.2.tgz#e90d3466ba209b932451508a11ce3d3632145931" - integrity sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg== - dependencies: - minipass "^3.0.0" - yallist "^4.0.0" - -mkdirp-classic@^0.5.2: - version "0.5.3" - resolved "https://registry.yarnpkg.com/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz#fa10c9115cc6d8865be221ba47ee9bed78601113" - integrity sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A== - -mkdirp@^0.5.1, mkdirp@^0.5.4: - version "0.5.5" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" - integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ== - dependencies: - minimist "^1.2.5" - -mkdirp@^1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" - integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== - -mocha-jenkins-reporter@^0.4.5: - version "0.4.5" - resolved "https://registry.yarnpkg.com/mocha-jenkins-reporter/-/mocha-jenkins-reporter-0.4.5.tgz#d12865e0d991afbaa1d011b966195ebb8936850f" - integrity sha512-QoKXaxWz3gpzCBgfaqu2OZKVyibAwRTD/BF7ApMfNgafzzch9s8hMNVPTxRom9smmUAfaDfzARWKvrQMK7XACA== - dependencies: - diff "4.0.1" - mkdirp "^0.5.4" - xml "^1.0.1" - -mocha@^8.2.1: - version "8.2.1" - resolved "https://registry.yarnpkg.com/mocha/-/mocha-8.2.1.tgz#f2fa68817ed0e53343d989df65ccd358bc3a4b39" - integrity sha512-cuLBVfyFfFqbNR0uUKbDGXKGk+UDFe6aR4os78XIrMQpZl/nv7JYHcvP5MFIAb374b2zFXsdgEGwmzMtP0Xg8w== - dependencies: - "@ungap/promise-all-settled" "1.1.2" - ansi-colors "4.1.1" - browser-stdout "1.3.1" - chokidar "3.4.3" - debug "4.2.0" - diff "4.0.2" - escape-string-regexp "4.0.0" - find-up "5.0.0" - glob "7.1.6" - growl "1.10.5" - he "1.2.0" - js-yaml "3.14.0" - log-symbols "4.0.0" - minimatch "3.0.4" - ms "2.1.2" - nanoid "3.1.12" - serialize-javascript "5.0.1" - strip-json-comments "3.1.1" - supports-color "7.2.0" - which "2.0.2" - wide-align "1.1.3" - workerpool "6.0.2" - yargs "13.3.2" - yargs-parser "13.1.2" - yargs-unparser "2.0.0" - -ms@2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" - integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== - -nanobuffer@^1.1.7: - version "1.1.7" - resolved "https://registry.yarnpkg.com/nanobuffer/-/nanobuffer-1.1.7.tgz#d81b71411c1dc47af58c4c5f864cd2b0eb0bf404" - integrity sha512-LP1JYWQh4qFmpLaauE3mWuOjGJSxts+wnYeTlSb4zurdn8xIhJ906oyb7M7Ih6EiImaUskFdHfYx9gyijf1FLA== - dependencies: - source-map-support "^0.5.19" - -nanoid@3.1.12: - version "3.1.12" - resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.12.tgz#6f7736c62e8d39421601e4a0c77623a97ea69654" - integrity sha512-1qstj9z5+x491jfiC4Nelk+f8XBad7LN20PmyWINJEMRSf3wcAjAWysw1qaA8z6NSKe2sjq1hRSDpBH5paCb6A== - -napi-macros@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/napi-macros/-/napi-macros-2.0.0.tgz#2b6bae421e7b96eb687aa6c77a7858640670001b" - integrity sha512-A0xLykHtARfueITVDernsAWdtIMbOJgKgcluwENp3AlsKN/PloyO10HtmoqnFAQAcxPkgZN7wdfPfEd0zNGxbg== - -node-abi@^2.0.0: - version "2.19.3" - resolved "https://registry.yarnpkg.com/node-abi/-/node-abi-2.19.3.tgz#252f5dcab12dad1b5503b2d27eddd4733930282d" - integrity sha512-9xZrlyfvKhWme2EXFKQhZRp1yNWT/uI1luYPr3sFl+H4keYY4xR+1jO7mvTTijIsHf1M+QDe9uWuKeEpLInIlg== - dependencies: - semver "^5.4.1" - -node-gyp-build@^4.2.3: - version "4.2.3" - resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.2.3.tgz#ce6277f853835f718829efb47db20f3e4d9c4739" - integrity sha512-MN6ZpzmfNCRM+3t57PTJHgHyw/h4OWnZ6mR8P5j/uZtqQr46RRuDE/P+g3n0YR/AiYXeWixZZzaip77gdICfRg== - -node-gyp@^7.1.2: - version "7.1.2" - resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-7.1.2.tgz#21a810aebb187120251c3bcec979af1587b188ae" - integrity sha512-CbpcIo7C3eMu3dL1c3d0xw449fHIGALIJsRP4DDPHpyiW8vcriNY7ubh9TE4zEKfSxscY7PjeFnshE7h75ynjQ== - dependencies: - env-paths "^2.2.0" - glob "^7.1.4" - graceful-fs "^4.2.3" - nopt "^5.0.0" - npmlog "^4.1.2" - request "^2.88.2" - rimraf "^3.0.2" - semver "^7.3.2" - tar "^6.0.2" - which "^2.0.2" - -nopt@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/nopt/-/nopt-5.0.0.tgz#530942bb58a512fccafe53fe210f13a25355dc88" - integrity sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ== - dependencies: - abbrev "1" - -normalize-path@^3.0.0, normalize-path@~3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" - integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== - -npm-run-path@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-3.1.0.tgz#7f91be317f6a466efed3c9f2980ad8a4ee8b0fa5" - integrity sha512-Dbl4A/VfiVGLgQv29URL9xshU8XDY1GeLy+fsaZ1AA8JDSfjvr5P5+pzRbWqRSBxk6/DW7MIh8lTM/PaGnP2kg== - dependencies: - path-key "^3.0.0" - -npmlog@^4.1.2: - version "4.1.2" - resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" - integrity sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg== - dependencies: - are-we-there-yet "~1.1.2" - console-control-strings "~1.1.0" - gauge "~2.7.3" - set-blocking "~2.0.0" - -number-is-nan@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" - integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0= - -oauth-sign@~0.9.0: - version "0.9.0" - resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" - integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ== - -object-assign@^4.1.0: - version "4.1.1" - resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" - integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= - -once@^1.3.0, once@^1.3.1, once@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" - integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= - dependencies: - wrappy "1" - -p-limit@^2.0.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" - integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== - dependencies: - p-try "^2.0.0" - -p-limit@^3.0.2: - version "3.1.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" - integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== - dependencies: - yocto-queue "^0.1.0" - -p-locate@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4" - integrity sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ== - dependencies: - p-limit "^2.0.0" - -p-locate@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" - integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== - dependencies: - p-limit "^3.0.2" - -p-try@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" - integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== - -path-exists@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" - integrity sha1-zg6+ql94yxiSXqfYENe1mwEP1RU= - -path-exists@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" - integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== - -path-is-absolute@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" - integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= - -path-key@^3.0.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" - integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== - -pathval@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/pathval/-/pathval-1.1.0.tgz#b942e6d4bde653005ef6b71361def8727d0645e0" - integrity sha1-uULm1L3mUwBe9rcTYd74cn0GReA= - -performance-now@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" - integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= - -picomatch@^2.0.4, picomatch@^2.2.1: - version "2.2.2" - resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.2.tgz#21f333e9b6b8eaff02468f5146ea406d345f4dad" - integrity sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg== - -prebuildify@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/prebuildify/-/prebuildify-4.1.1.tgz#9468c0b1f97ecde84d6d4020ad1b322b7a42a88d" - integrity sha512-kGvcQY44OzfmgKLJPsMsOquQ0/05d5GyAXovxvHxyZSIXpjU/pLoAfMxSiES5QpcHFfWpJLSTwHFGHY3BcRNQA== - dependencies: - execspawn "^1.0.1" - minimist "^1.2.0" - mkdirp "^0.5.1" - node-abi "^2.0.0" - npm-run-path "^3.1.0" - pump "^3.0.0" - tar-fs "^2.1.0" - -process-nextick-args@~2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" - integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== - -psl@^1.1.28: - version "1.8.0" - resolved "https://registry.yarnpkg.com/psl/-/psl-1.8.0.tgz#9326f8bcfb013adcc005fdff056acce020e51c24" - integrity sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ== - -pump@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" - integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== - dependencies: - end-of-stream "^1.1.0" - once "^1.3.1" - -punycode@^2.1.0, punycode@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" - integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== - -qs@~6.5.2: - version "6.5.2" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" - integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA== - -randombytes@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" - integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== - dependencies: - safe-buffer "^5.1.0" - -readable-stream@^2.0.6: - version "2.3.7" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" - integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== - dependencies: - core-util-is "~1.0.0" - inherits "~2.0.3" - isarray "~1.0.0" - process-nextick-args "~2.0.0" - safe-buffer "~5.1.1" - string_decoder "~1.1.1" - util-deprecate "~1.0.1" - -readable-stream@^3.1.1, readable-stream@^3.4.0: - version "3.6.0" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" - integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== - dependencies: - inherits "^2.0.3" - string_decoder "^1.1.1" - util-deprecate "^1.0.1" - -readdirp@~3.5.0: - version "3.5.0" - resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.5.0.tgz#9ba74c019b15d365278d2e91bb8c48d7b4d42c9e" - integrity sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ== - dependencies: - picomatch "^2.2.1" - -request@^2.88.2: - version "2.88.2" - resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3" - integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw== - dependencies: - aws-sign2 "~0.7.0" - aws4 "^1.8.0" - caseless "~0.12.0" - combined-stream "~1.0.6" - extend "~3.0.2" - forever-agent "~0.6.1" - form-data "~2.3.2" - har-validator "~5.1.3" - http-signature "~1.2.0" - is-typedarray "~1.0.0" - isstream "~0.1.2" - json-stringify-safe "~5.0.1" - mime-types "~2.1.19" - oauth-sign "~0.9.0" - performance-now "^2.1.0" - qs "~6.5.2" - safe-buffer "^5.1.2" - tough-cookie "~2.5.0" - tunnel-agent "^0.6.0" - uuid "^3.3.2" - -require-directory@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" - integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= - -require-main-filename@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b" - integrity sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg== - -rimraf@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" - integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== - dependencies: - glob "^7.1.3" - -safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.2, safe-buffer@~5.2.0: - version "5.2.1" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" - integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== - -safe-buffer@~5.1.0, safe-buffer@~5.1.1: - version "5.1.2" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" - integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== - -safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: - version "2.1.2" - resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" - integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== - -semver@^5.4.1: - version "5.7.1" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" - integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== - -semver@^7.3.2: - version "7.3.2" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.2.tgz#604962b052b81ed0786aae84389ffba70ffd3938" - integrity sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ== - -serialize-javascript@5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-5.0.1.tgz#7886ec848049a462467a97d3d918ebb2aaf934f4" - integrity sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA== - dependencies: - randombytes "^2.1.0" - -set-blocking@^2.0.0, set-blocking@~2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" - integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= - -signal-exit@^3.0.0: - version "3.0.3" - resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.3.tgz#a1410c2edd8f077b08b4e253c8eacfcaf057461c" - integrity sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA== - -snooplogg@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/snooplogg/-/snooplogg-3.0.1.tgz#97ce91eae692c430638de782b79f15c7695a08d7" - integrity sha512-Djg8XAiDclbhfwjj4XLOJ17YN8xZjdJ+rtrokpHmx63U9hYnDh0TqGmwbsn0fNhKjODuNJqjNIU+42Cheoe+Xw== - dependencies: - bryt "^1.0.2" - chalk "^4.1.0" - nanobuffer "^1.1.7" - source-map-support "^0.5.19" - supports-color "^8.0.0" - -source-map-support@^0.5.19: - version "0.5.19" - resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.19.tgz#a98b62f86dcaf4f67399648c085291ab9e8fed61" - integrity sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw== - dependencies: - buffer-from "^1.0.0" - source-map "^0.6.0" - -source-map@^0.6.0: - version "0.6.1" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" - integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== - -sprintf-js@~1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" - integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= - -sshpk@^1.7.0: - version "1.16.1" - resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.16.1.tgz#fb661c0bef29b39db40769ee39fa70093d6f6877" - integrity sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg== - dependencies: - asn1 "~0.2.3" - assert-plus "^1.0.0" - bcrypt-pbkdf "^1.0.0" - dashdash "^1.12.0" - ecc-jsbn "~0.1.1" - getpass "^0.1.1" - jsbn "~0.1.0" - safer-buffer "^2.0.2" - tweetnacl "~0.14.0" - -string-width@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" - integrity sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M= - dependencies: - code-point-at "^1.0.0" - is-fullwidth-code-point "^1.0.0" - strip-ansi "^3.0.0" - -"string-width@^1.0.2 || 2": - version "2.1.1" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" - integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== - dependencies: - is-fullwidth-code-point "^2.0.0" - strip-ansi "^4.0.0" - -string-width@^3.0.0, string-width@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-3.1.0.tgz#22767be21b62af1081574306f69ac51b62203961" - integrity sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w== - dependencies: - emoji-regex "^7.0.1" - is-fullwidth-code-point "^2.0.0" - strip-ansi "^5.1.0" - -string_decoder@^1.1.1: - version "1.3.0" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" - integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== - dependencies: - safe-buffer "~5.2.0" - -string_decoder@~1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" - integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== - dependencies: - safe-buffer "~5.1.0" - -strip-ansi@^3.0.0, strip-ansi@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" - integrity sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8= - dependencies: - ansi-regex "^2.0.0" - -strip-ansi@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" - integrity sha1-qEeQIusaw2iocTibY1JixQXuNo8= - dependencies: - ansi-regex "^3.0.0" - -strip-ansi@^5.0.0, strip-ansi@^5.1.0, strip-ansi@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae" - integrity sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA== - dependencies: - ansi-regex "^4.1.0" - -strip-json-comments@3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" - integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== - -supports-color@7.2.0, supports-color@^7.1.0: - version "7.2.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" - integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== - dependencies: - has-flag "^4.0.0" - -supports-color@^8.0.0: - version "8.0.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.0.0.tgz#51fc88b5f0b8c47a64fcc54941f41a0ff9e695e3" - integrity sha512-of+3NN2wzrj+nTYWrTf4Oc13Lo5gDLVBzKREX8DW1e3IWw8znzOc03NaQwnma27qO3nKPDA8C0HN50SS0Pki7g== - dependencies: - has-flag "^4.0.0" - -tar-fs@^2.1.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-2.1.1.tgz#489a15ab85f1f0befabb370b7de4f9eb5cbe8784" - integrity sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng== - dependencies: - chownr "^1.1.1" - mkdirp-classic "^0.5.2" - pump "^3.0.0" - tar-stream "^2.1.4" - -tar-stream@^2.1.4: - version "2.1.4" - resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-2.1.4.tgz#c4fb1a11eb0da29b893a5b25476397ba2d053bfa" - integrity sha512-o3pS2zlG4gxr67GmFYBLlq+dM8gyRGUOvsrHclSkvtVtQbjV0s/+ZE8OpICbaj8clrX3tjeHngYGP7rweaBnuw== - dependencies: - bl "^4.0.3" - end-of-stream "^1.4.1" - fs-constants "^1.0.0" - inherits "^2.0.3" - readable-stream "^3.1.1" - -tar@^6.0.2: - version "6.0.5" - resolved "https://registry.yarnpkg.com/tar/-/tar-6.0.5.tgz#bde815086e10b39f1dcd298e89d596e1535e200f" - integrity sha512-0b4HOimQHj9nXNEAA7zWwMM91Zhhba3pspja6sQbgTpynOJf+bkjBnfybNYzbpLbnwXnbyB4LOREvlyXLkCHSg== - dependencies: - chownr "^2.0.0" - fs-minipass "^2.0.0" - minipass "^3.0.0" - minizlib "^2.1.1" - mkdirp "^1.0.3" - yallist "^4.0.0" - -to-regex-range@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" - integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== - dependencies: - is-number "^7.0.0" - -tough-cookie@~2.5.0: - version "2.5.0" - resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2" - integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g== - dependencies: - psl "^1.1.28" - punycode "^2.1.1" - -tunnel-agent@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" - integrity sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0= - dependencies: - safe-buffer "^5.0.1" - -tweetnacl@^0.14.3, tweetnacl@~0.14.0: - version "0.14.5" - resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" - integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q= - -type-detect@^4.0.0, type-detect@^4.0.5: - version "4.0.8" - resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" - integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g== - -uri-js@^4.2.2: - version "4.4.0" - resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.0.tgz#aa714261de793e8a82347a7bcc9ce74e86f28602" - integrity sha512-B0yRTzYdUCCn9n+F4+Gh4yIDtMQcaJsmYBDsTSG8g/OejKBodLQ2IHfN3bM7jUsRXndopT7OIXWdYqc1fjmV6g== - dependencies: - punycode "^2.1.0" - -util-deprecate@^1.0.1, util-deprecate@~1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" - integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= - -util-extend@^1.0.1: - version "1.0.3" - resolved "https://registry.yarnpkg.com/util-extend/-/util-extend-1.0.3.tgz#a7c216d267545169637b3b6edc6ca9119e2ff93f" - integrity sha1-p8IW0mdUUWljeztu3GypEZ4v+T8= - -uuid@^3.3.2: - version "3.4.0" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" - integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== - -verror@1.10.0: - version "1.10.0" - resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" - integrity sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA= - dependencies: - assert-plus "^1.0.0" - core-util-is "1.0.2" - extsprintf "^1.2.0" - -which-module@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" - integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho= - -which@2.0.2, which@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" - integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== - dependencies: - isexe "^2.0.0" - -wide-align@1.1.3, wide-align@^1.1.0: - version "1.1.3" - resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457" - integrity sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA== - dependencies: - string-width "^1.0.2 || 2" - -workerpool@6.0.2: - version "6.0.2" - resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.0.2.tgz#e241b43d8d033f1beb52c7851069456039d1d438" - integrity sha512-DSNyvOpFKrNusaaUwk+ej6cBj1bmhLcBfj80elGk+ZIo5JSkq+unB1dLKEOcNfJDZgjGICfhQ0Q5TbP0PvF4+Q== - -wrap-ansi@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-5.1.0.tgz#1fd1f67235d5b6d0fee781056001bfb694c03b09" - integrity sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q== - dependencies: - ansi-styles "^3.2.0" - string-width "^3.0.0" - strip-ansi "^5.0.0" - -wrappy@1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" - integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= - -xml@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/xml/-/xml-1.0.1.tgz#78ba72020029c5bc87b8a81a3cfcd74b4a2fc1e5" - integrity sha1-eLpyAgApxbyHuKgaPPzXS0ovweU= - -y18n@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.1.tgz#8db2b83c31c5d75099bb890b23f3094891e247d4" - integrity sha512-wNcy4NvjMYL8gogWWYAO7ZFWFfHcbdbE57tZO8e4cbpj8tfUcwrwqSl3ad8HxpYWCdXcJUCeKKZS62Av1affwQ== - -yallist@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" - integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== - -yargs-parser@13.1.2, yargs-parser@^13.1.2: - version "13.1.2" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-13.1.2.tgz#130f09702ebaeef2650d54ce6e3e5706f7a4fb38" - integrity sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg== - dependencies: - camelcase "^5.0.0" - decamelize "^1.2.0" - -yargs-unparser@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/yargs-unparser/-/yargs-unparser-2.0.0.tgz#f131f9226911ae5d9ad38c432fe809366c2325eb" - integrity sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA== - dependencies: - camelcase "^6.0.0" - decamelize "^4.0.0" - flat "^5.0.2" - is-plain-obj "^2.1.0" - -yargs@13.3.2: - version "13.3.2" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-13.3.2.tgz#ad7ffefec1aa59565ac915f82dccb38a9c31a2dd" - integrity sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw== - dependencies: - cliui "^5.0.0" - find-up "^3.0.0" - get-caller-file "^2.0.1" - require-directory "^2.1.1" - require-main-filename "^2.0.0" - set-blocking "^2.0.0" - string-width "^3.0.0" - which-module "^2.0.0" - y18n "^4.0.0" - yargs-parser "^13.1.2" - -yocto-queue@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" - integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== From 58a8d18f1c705ea42365b933b7be42671ef54ad0 Mon Sep 17 00:00:00 2001 From: Chris Barber Date: Thu, 4 Jul 2024 22:08:12 -0500 Subject: [PATCH 02/27] Work --- .github/workflows/publish.yml | 8 ++++---- .github/workflows/test.yml | 35 +++++++++++++++++++++++++++++++++++ package.json | 15 ++++++++------- 3 files changed, 47 insertions(+), 11 deletions(-) create mode 100644 .github/workflows/test.yml diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 48d8b27..1839d98 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -15,7 +15,7 @@ jobs: - name: Setup node uses: actions/setup-node@v4 with: - node-version: 18 + node-version: 20 registry-url: 'https://registry.npmjs.org/' - name: Install pnpm @@ -26,10 +26,10 @@ jobs: - name: Install dependencies run: pnpm install + - name: Lint + run: pnpm check + - name: Publish to npm env: - GH_TOKEN: ${{ github.token }} - GITHUB_TOKEN: ${{ github.token }} NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} - NPM_TOKEN: ${{ secrets.NPM_TOKEN }} run: npm publish --tag ${{ github.event.release.prerelease && 'next' || 'latest' }} diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000..21f3355 --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,35 @@ +name: Tests + +on: [push, pull_request] + +jobs: + test: + name: Test on node ${{ matrix.node }} + runs-on: windows-latest + strategy: + fail-fast: false + matrix: + node: [18, 20, 22] + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Use Node.js ${{ matrix.node }} + uses: actions/setup-node@v4 + with: + node-version: ${{ matrix.node }} + + - name: Install pnpm + uses: pnpm/action-setup@v2 + with: + version: latest + + - name: Install dependencies + run: pnpm install + + - name: Lint + run: pnpm check + + - name: Run tests + run: pnpm coverage diff --git a/package.json b/package.json index 487c386..507328a 100644 --- a/package.json +++ b/package.json @@ -11,13 +11,16 @@ "keywords": [ "windows", "windows registry", + "registry", "winreg", "microsoft" ], "scripts": { - "build": "pnpm build:bundle && pnpm build:types", + "build": "pnpm build:bundle && pnpm build:local", + "build:bundle": "rimraf dist && rollup -c rollup.config.ts --configPlugin typescript && pnpm build:types", + "build:local": "node-gyp -j 20 build", + "build:local-debug": "node-gyp -j 20 build --debug", "build:prebuild": "pnpm prebuild-arm && pnpm prebuild-arm64 && pnpm prebuild-ia32 && pnpm prebuild-x64", - "build:bundle": "rimraf dist && rollup -c rollup.config.ts --configPlugin typescript", "build:types": "pnpm build:types:temp && pnpm build:types:roll && pnpm build:types:check", "build:types:temp": "tsc --declaration --emitDeclarationOnly --outDir temp --project tsconfig.build.json", "build:types:roll": "rollup --config rollup.dts.config.ts --configPlugin typescript && rimraf temp", @@ -26,15 +29,13 @@ "clean": "node-gyp clean", "coverage": "vitest --coverage", "install": "node -e \"process.exit(process.platform === 'win32' ? 0 : 1)\" && node-gyp-build", - "local:build": "node-gyp -j 20 build", - "local:build:debug": "node-gyp -j 20 build --debug", - "local:rebuild": "node-gyp -j 20 rebuild", - "local:rebuild:debug": "node-gyp -j 20 rebuild --debug", - "prepublishOnly": "pnpm build && pnpm build:prebuild", + "prepublishOnly": "pnpm build:bundle && pnpm build:prebuild", "prebuild-arm": "prebuildify --napi --strip --platform='win32' --arch arm", "prebuild-arm64": "prebuildify --napi --strip --platform='win32' --arch arm64", "prebuild-ia32": "prebuildify --napi --strip --platform='win32' --arch ia32", "prebuild-x64": "prebuildify --napi --strip --platform='win32' --arch x64", + "rebuild:local": "node-gyp -j 20 rebuild", + "rebuild:local-debug": "node-gyp -j 20 rebuild --debug", "test": "vitest", "type-check": "tsc --noEmit" }, From 80a5bdf0c84df8d8673a842f75cec5a9e195ea39 Mon Sep 17 00:00:00 2001 From: Chris Barber Date: Thu, 4 Jul 2024 23:05:29 -0500 Subject: [PATCH 03/27] Fix bundling --- package.json | 1 - pnpm-lock.yaml | 53 ------------------------------------------------ rollup.config.ts | 2 -- src/index.ts | 10 +++++++-- 4 files changed, 8 insertions(+), 58 deletions(-) diff --git a/package.json b/package.json index 507328a..85d6d04 100644 --- a/package.json +++ b/package.json @@ -47,7 +47,6 @@ }, "devDependencies": { "@biomejs/biome": "1.8.3", - "@rollup/plugin-node-resolve": "15.2.3", "@rollup/plugin-typescript": "11.1.6", "@types/node": "20.14.9", "@vitest/coverage-v8": "1.6.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 787d97d..8c5ec37 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -29,9 +29,6 @@ importers: '@biomejs/biome': specifier: 1.8.3 version: 1.8.3 - '@rollup/plugin-node-resolve': - specifier: 15.2.3 - version: 15.2.3(rollup@4.18.0) '@rollup/plugin-typescript': specifier: 11.1.6 version: 11.1.6(rollup@4.18.0)(tslib@2.6.3)(typescript@5.5.3) @@ -483,15 +480,6 @@ packages: resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} engines: {node: '>=14'} - '@rollup/plugin-node-resolve@15.2.3': - resolution: {integrity: sha512-j/lym8nf5E21LwBT4Df1VD6hRO2L2iwUeUmP7litikRsVp1H6NWx20NEp0Y7su+7XGc476GnXXc4kFeZNGmaSQ==} - engines: {node: '>=14.0.0'} - peerDependencies: - rollup: ^2.78.0||^3.0.0||^4.0.0 - peerDependenciesMeta: - rollup: - optional: true - '@rollup/plugin-typescript@11.1.6': resolution: {integrity: sha512-R92yOmIACgYdJ7dJ97p4K69I8gg6IEHt8M7dUBxN3W6nrO8uUxX5ixl0yU/N3aZTi8WhPuICvOHXQvF6FaykAA==} engines: {node: '>=14.0.0'} @@ -603,9 +591,6 @@ packages: '@types/node@20.14.9': resolution: {integrity: sha512-06OCtnTXtWOZBJlRApleWndH4JsRVs1pDCc8dLSQp+7PpUpX3ePdHyeNSFTeSe7FtKyQkrlPvHwJOW3SLd8Oyg==} - '@types/resolve@1.20.2': - resolution: {integrity: sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==} - '@vitest/coverage-v8@1.6.0': resolution: {integrity: sha512-KvapcbMY/8GYIG0rlwwOKCVNRc0OL20rrhFkg/CHNzncV03TE2XWvO5w9uZYoxNiMEBacAJt3unSOiZ7svePew==} peerDependencies: @@ -692,10 +677,6 @@ packages: buffer@5.7.1: resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==} - builtin-modules@3.3.0: - resolution: {integrity: sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==} - engines: {node: '>=6'} - cac@6.7.14: resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} engines: {node: '>=8'} @@ -762,10 +743,6 @@ packages: resolution: {integrity: sha512-SUwdGfqdKOwxCPeVYjwSyRpJ7Z+fhpwIAtmCUdZIWZ/YP5R9WAsyuSgpLVDi9bjWoN2LXHNss/dk3urXtdQxGg==} engines: {node: '>=6'} - deepmerge@4.3.1: - resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} - engines: {node: '>=0.10.0'} - diff-sequences@29.6.3: resolution: {integrity: sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -926,10 +903,6 @@ packages: resolution: {integrity: sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==} engines: {node: '>= 12'} - is-builtin-module@3.2.1: - resolution: {integrity: sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==} - engines: {node: '>=6'} - is-core-module@2.14.0: resolution: {integrity: sha512-a5dFJih5ZLYlRtDc0dZWP7RiKr6xIKzmn/oAYCDvdLThadVgyJwlaoQPmRtMSpz+rk0OGAgIu+TcM9HUF0fk1A==} engines: {node: '>= 0.4'} @@ -941,9 +914,6 @@ packages: is-lambda@1.0.1: resolution: {integrity: sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==} - is-module@1.0.0: - resolution: {integrity: sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==} - is-stream@3.0.0: resolution: {integrity: sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} @@ -1789,17 +1759,6 @@ snapshots: '@pkgjs/parseargs@0.11.0': optional: true - '@rollup/plugin-node-resolve@15.2.3(rollup@4.18.0)': - dependencies: - '@rollup/pluginutils': 5.1.0(rollup@4.18.0) - '@types/resolve': 1.20.2 - deepmerge: 4.3.1 - is-builtin-module: 3.2.1 - is-module: 1.0.0 - resolve: 1.22.8 - optionalDependencies: - rollup: 4.18.0 - '@rollup/plugin-typescript@11.1.6(rollup@4.18.0)(tslib@2.6.3)(typescript@5.5.3)': dependencies: '@rollup/pluginutils': 5.1.0(rollup@4.18.0) @@ -1873,8 +1832,6 @@ snapshots: dependencies: undici-types: 5.26.5 - '@types/resolve@1.20.2': {} - '@vitest/coverage-v8@1.6.0(vitest@1.6.0(@types/node@20.14.9))': dependencies: '@ampproject/remapping': 2.3.0 @@ -1985,8 +1942,6 @@ snapshots: base64-js: 1.5.1 ieee754: 1.2.1 - builtin-modules@3.3.0: {} - cac@6.7.14: {} cacache@18.0.3: @@ -2063,8 +2018,6 @@ snapshots: dependencies: type-detect: 4.0.8 - deepmerge@4.3.1: {} - diff-sequences@29.6.3: {} eastasianwidth@0.2.0: {} @@ -2266,10 +2219,6 @@ snapshots: jsbn: 1.1.0 sprintf-js: 1.1.3 - is-builtin-module@3.2.1: - dependencies: - builtin-modules: 3.3.0 - is-core-module@2.14.0: dependencies: hasown: 2.0.2 @@ -2278,8 +2227,6 @@ snapshots: is-lambda@1.0.1: {} - is-module@1.0.0: {} - is-stream@3.0.0: {} isexe@2.0.0: {} diff --git a/rollup.config.ts b/rollup.config.ts index 77fce6b..6e1f035 100644 --- a/rollup.config.ts +++ b/rollup.config.ts @@ -1,4 +1,3 @@ -import { nodeResolve } from '@rollup/plugin-node-resolve'; import typescript from '@rollup/plugin-typescript'; import { defineConfig } from 'rollup'; import { minify as esbuildMinifyPlugin } from 'rollup-plugin-esbuild'; @@ -15,7 +14,6 @@ export default defineConfig([ sourcemap: true }, plugins: [ - nodeResolve({ preferBuiltins: true }), esbuildMinifyPlugin({ minify: true, minifySyntax: true diff --git a/src/index.ts b/src/index.ts index 26d58ac..7191929 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,12 +1,18 @@ import { EventEmitter } from 'node:events'; +import { dirname } from 'node:path'; import { fileURLToPath } from 'node:url'; -import * as nodeGypBuild from 'node-gyp-build'; import snooplogg, { type Logger } from 'snooplogg'; -const binding = nodeGypBuild(`${fileURLToPath(import.meta.dirname)}/..`); +const { default: nodeGypBuild } = await import( + 'node-gyp-build/node-gyp-build.js' +); +const binding = nodeGypBuild(dirname(fileURLToPath(import.meta.url))); const logger = snooplogg('winreglib'); +/** + * A handle for watching a registry key for changes. + */ export class WinRegLibWatchHandle extends EventEmitter { key: string; From ed89d2c46473914269340b10c25a596b0fe28286 Mon Sep 17 00:00:00 2001 From: Chris Barber Date: Fri, 5 Jul 2024 00:15:10 -0500 Subject: [PATCH 04/27] Work on getting tests to run --- .github/workflows/test.yml | 3 +++ package.json | 8 ++++---- rollup.dts.config.ts | 2 -- src/index.ts | 2 +- 4 files changed, 8 insertions(+), 7 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 21f3355..7941a8c 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -31,5 +31,8 @@ jobs: - name: Lint run: pnpm check + - name: Build + run: pnpm build + - name: Run tests run: pnpm coverage diff --git a/package.json b/package.json index 85d6d04..a19d1cc 100644 --- a/package.json +++ b/package.json @@ -30,10 +30,10 @@ "coverage": "vitest --coverage", "install": "node -e \"process.exit(process.platform === 'win32' ? 0 : 1)\" && node-gyp-build", "prepublishOnly": "pnpm build:bundle && pnpm build:prebuild", - "prebuild-arm": "prebuildify --napi --strip --platform='win32' --arch arm", - "prebuild-arm64": "prebuildify --napi --strip --platform='win32' --arch arm64", - "prebuild-ia32": "prebuildify --napi --strip --platform='win32' --arch ia32", - "prebuild-x64": "prebuildify --napi --strip --platform='win32' --arch x64", + "prebuild-arm": "prebuildify --napi --strip --platform=win32 --arch arm", + "prebuild-arm64": "prebuildify --napi --strip --platform=win32 --arch arm64", + "prebuild-ia32": "prebuildify --napi --strip --platform=win32 --arch ia32", + "prebuild-x64": "prebuildify --napi --strip --platform=win32 --arch x64", "rebuild:local": "node-gyp -j 20 rebuild", "rebuild:local-debug": "node-gyp -j 20 rebuild --debug", "test": "vitest", diff --git a/rollup.dts.config.ts b/rollup.dts.config.ts index 99397a7..cb43fa9 100644 --- a/rollup.dts.config.ts +++ b/rollup.dts.config.ts @@ -1,4 +1,3 @@ -import { nodeResolve } from '@rollup/plugin-node-resolve'; import { defineConfig } from 'rollup'; import { dts } from 'rollup-plugin-dts'; @@ -10,7 +9,6 @@ export default defineConfig([ format: 'es' }, plugins: [ - nodeResolve({ preferBuiltins: true }), dts({ respectExternal: true }) diff --git a/src/index.ts b/src/index.ts index 7191929..820a376 100644 --- a/src/index.ts +++ b/src/index.ts @@ -6,7 +6,7 @@ import snooplogg, { type Logger } from 'snooplogg'; const { default: nodeGypBuild } = await import( 'node-gyp-build/node-gyp-build.js' ); -const binding = nodeGypBuild(dirname(fileURLToPath(import.meta.url))); +const binding = nodeGypBuild(dirname(dirname(fileURLToPath(import.meta.url)))); const logger = snooplogg('winreglib'); From 9974072c38e592e783e127211b8e9e92b871bc60 Mon Sep 17 00:00:00 2001 From: Chris Barber Date: Fri, 5 Jul 2024 00:20:52 -0500 Subject: [PATCH 05/27] Fix import --- test/wingreglib.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/wingreglib.test.ts b/test/wingreglib.test.ts index eef010a..4abcd30 100644 --- a/test/wingreglib.test.ts +++ b/test/wingreglib.test.ts @@ -1,6 +1,6 @@ import fs from 'node:fs'; import { describe, expect, it } from 'vitest'; -import * as winreglib from '../src/index.js'; +import winreglib from '../src/index.js'; const { spawnSync } = require('node:child_process'); import snooplogg from 'snooplogg'; From 6ea7e6ffe6c433e320e82c69970fdf89dbd6ae74 Mon Sep 17 00:00:00 2001 From: Chris Barber Date: Tue, 9 Jul 2024 02:23:02 -0500 Subject: [PATCH 06/27] Seg fault workaround, cleaned up tests --- binding.gyp | 12 - package.json | 18 +- pnpm-lock.yaml | 633 +++++++++++++---------------- src/index.ts | 25 +- src/watchman.cpp | 16 +- src/watchman.h | 1 + src/winreglib.cpp | 39 +- src/winreglib.h | 15 +- test/wingreglib-get.test.ts | 147 +++++++ test/wingreglib-list.test.ts | 57 +++ test/wingreglib-watch.test.ts | 577 +++++++++++++++++++++++++++ test/wingreglib.test.ts | 725 ---------------------------------- vitest.config.ts | 5 + 13 files changed, 1134 insertions(+), 1136 deletions(-) create mode 100644 test/wingreglib-get.test.ts create mode 100644 test/wingreglib-list.test.ts create mode 100644 test/wingreglib-watch.test.ts delete mode 100644 test/wingreglib.test.ts diff --git a/binding.gyp b/binding.gyp index b32db48..c9e1bf5 100644 --- a/binding.gyp +++ b/binding.gyp @@ -1,9 +1,4 @@ { - 'variables': { - 'v8_enable_pointer_compression': 0, - 'v8_enable_31bit_smis_on_64bit_arch': 0, - 'openssl_fips': '' - }, 'conditions': [ ['OS=="win"', { 'targets': [ @@ -30,13 +25,6 @@ } } ] - }, { - 'targets': [ - { - 'target_name': 'node_winreglib', - 'type': 'none' - } - ] }] ] } diff --git a/package.json b/package.json index a19d1cc..d956159 100644 --- a/package.json +++ b/package.json @@ -27,16 +27,16 @@ "build:types:check": "tsc --project tsconfig.check.json", "check": "biome check --write .", "clean": "node-gyp clean", - "coverage": "vitest --coverage", + "coverage": "vitest --pool=forks --coverage", "install": "node -e \"process.exit(process.platform === 'win32' ? 0 : 1)\" && node-gyp-build", "prepublishOnly": "pnpm build:bundle && pnpm build:prebuild", "prebuild-arm": "prebuildify --napi --strip --platform=win32 --arch arm", "prebuild-arm64": "prebuildify --napi --strip --platform=win32 --arch arm64", "prebuild-ia32": "prebuildify --napi --strip --platform=win32 --arch ia32", - "prebuild-x64": "prebuildify --napi --strip --platform=win32 --arch x64", + "prebuild-x64": "prebuildify --napi --strip --platform=win32 --arch x64", "rebuild:local": "node-gyp -j 20 rebuild", "rebuild:local-debug": "node-gyp -j 20 rebuild --debug", - "test": "vitest", + "test": "vitest --pool=forks", "type-check": "tsc --noEmit" }, "dependencies": { @@ -48,18 +48,18 @@ "devDependencies": { "@biomejs/biome": "1.8.3", "@rollup/plugin-typescript": "11.1.6", - "@types/node": "20.14.9", - "@vitest/coverage-v8": "1.6.0", + "@types/node": "20.14.10", + "@vitest/coverage-v8": "2.0.1", "esbuild": "0.23.0", - "lefthook": "1.6.18", + "lefthook": "1.7.1", "prebuildify": "6.0.1", - "rimraf": "5.0.7", - "rollup": "4.18.0", + "rimraf": "6.0.0", + "rollup": "4.18.1", "rollup-plugin-dts": "6.1.1", "rollup-plugin-esbuild": "6.1.1", "tslib": "2.6.3", "typescript": "5.5.3", - "vitest": "1.6.0" + "vitest": "2.0.1" }, "homepage": "https://github.com/tidev/winreglib", "bugs": "https://github.com/tidev/winreglib/issues", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 8c5ec37..382618f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -31,34 +31,34 @@ importers: version: 1.8.3 '@rollup/plugin-typescript': specifier: 11.1.6 - version: 11.1.6(rollup@4.18.0)(tslib@2.6.3)(typescript@5.5.3) + version: 11.1.6(rollup@4.18.1)(tslib@2.6.3)(typescript@5.5.3) '@types/node': - specifier: 20.14.9 - version: 20.14.9 + specifier: 20.14.10 + version: 20.14.10 '@vitest/coverage-v8': - specifier: 1.6.0 - version: 1.6.0(vitest@1.6.0(@types/node@20.14.9)) + specifier: 2.0.1 + version: 2.0.1(vitest@2.0.1(@types/node@20.14.10)) esbuild: specifier: 0.23.0 version: 0.23.0 lefthook: - specifier: 1.6.18 - version: 1.6.18 + specifier: 1.7.1 + version: 1.7.1 prebuildify: specifier: 6.0.1 version: 6.0.1 rimraf: - specifier: 5.0.7 - version: 5.0.7 + specifier: 6.0.0 + version: 6.0.0 rollup: - specifier: 4.18.0 - version: 4.18.0 + specifier: 4.18.1 + version: 4.18.1 rollup-plugin-dts: specifier: 6.1.1 - version: 6.1.1(rollup@4.18.0)(typescript@5.5.3) + version: 6.1.1(rollup@4.18.1)(typescript@5.5.3) rollup-plugin-esbuild: specifier: 6.1.1 - version: 6.1.1(esbuild@0.23.0)(rollup@4.18.0) + version: 6.1.1(esbuild@0.23.0)(rollup@4.18.1) tslib: specifier: 2.6.3 version: 2.6.3 @@ -66,8 +66,8 @@ importers: specifier: 5.5.3 version: 5.5.3 vitest: - specifier: 1.6.0 - version: 1.6.0(@types/node@20.14.9) + specifier: 2.0.1 + version: 2.0.1(@types/node@20.14.10) packages: @@ -502,83 +502,83 @@ packages: rollup: optional: true - '@rollup/rollup-android-arm-eabi@4.18.0': - resolution: {integrity: sha512-Tya6xypR10giZV1XzxmH5wr25VcZSncG0pZIjfePT0OVBvqNEurzValetGNarVrGiq66EBVAFn15iYX4w6FKgQ==} + '@rollup/rollup-android-arm-eabi@4.18.1': + resolution: {integrity: sha512-lncuC4aHicncmbORnx+dUaAgzee9cm/PbIqgWz1PpXuwc+sa1Ct83tnqUDy/GFKleLiN7ZIeytM6KJ4cAn1SxA==} cpu: [arm] os: [android] - '@rollup/rollup-android-arm64@4.18.0': - resolution: {integrity: sha512-avCea0RAP03lTsDhEyfy+hpfr85KfyTctMADqHVhLAF3MlIkq83CP8UfAHUssgXTYd+6er6PaAhx/QGv4L1EiA==} + '@rollup/rollup-android-arm64@4.18.1': + resolution: {integrity: sha512-F/tkdw0WSs4ojqz5Ovrw5r9odqzFjb5LIgHdHZG65dFI1lWTWRVy32KDJLKRISHgJvqUeUhdIvy43fX41znyDg==} cpu: [arm64] os: [android] - '@rollup/rollup-darwin-arm64@4.18.0': - resolution: {integrity: sha512-IWfdwU7KDSm07Ty0PuA/W2JYoZ4iTj3TUQjkVsO/6U+4I1jN5lcR71ZEvRh52sDOERdnNhhHU57UITXz5jC1/w==} + '@rollup/rollup-darwin-arm64@4.18.1': + resolution: {integrity: sha512-vk+ma8iC1ebje/ahpxpnrfVQJibTMyHdWpOGZ3JpQ7Mgn/3QNHmPq7YwjZbIE7km73dH5M1e6MRRsnEBW7v5CQ==} cpu: [arm64] os: [darwin] - '@rollup/rollup-darwin-x64@4.18.0': - resolution: {integrity: sha512-n2LMsUz7Ynu7DoQrSQkBf8iNrjOGyPLrdSg802vk6XT3FtsgX6JbE8IHRvposskFm9SNxzkLYGSq9QdpLYpRNA==} + '@rollup/rollup-darwin-x64@4.18.1': + resolution: {integrity: sha512-IgpzXKauRe1Tafcej9STjSSuG0Ghu/xGYH+qG6JwsAUxXrnkvNHcq/NL6nz1+jzvWAnQkuAJ4uIwGB48K9OCGA==} cpu: [x64] os: [darwin] - '@rollup/rollup-linux-arm-gnueabihf@4.18.0': - resolution: {integrity: sha512-C/zbRYRXFjWvz9Z4haRxcTdnkPt1BtCkz+7RtBSuNmKzMzp3ZxdM28Mpccn6pt28/UWUCTXa+b0Mx1k3g6NOMA==} + '@rollup/rollup-linux-arm-gnueabihf@4.18.1': + resolution: {integrity: sha512-P9bSiAUnSSM7EmyRK+e5wgpqai86QOSv8BwvkGjLwYuOpaeomiZWifEos517CwbG+aZl1T4clSE1YqqH2JRs+g==} cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm-musleabihf@4.18.0': - resolution: {integrity: sha512-l3m9ewPgjQSXrUMHg93vt0hYCGnrMOcUpTz6FLtbwljo2HluS4zTXFy2571YQbisTnfTKPZ01u/ukJdQTLGh9A==} + '@rollup/rollup-linux-arm-musleabihf@4.18.1': + resolution: {integrity: sha512-5RnjpACoxtS+aWOI1dURKno11d7krfpGDEn19jI8BuWmSBbUC4ytIADfROM1FZrFhQPSoP+KEa3NlEScznBTyQ==} cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm64-gnu@4.18.0': - resolution: {integrity: sha512-rJ5D47d8WD7J+7STKdCUAgmQk49xuFrRi9pZkWoRD1UeSMakbcepWXPF8ycChBoAqs1pb2wzvbY6Q33WmN2ftw==} + '@rollup/rollup-linux-arm64-gnu@4.18.1': + resolution: {integrity: sha512-8mwmGD668m8WaGbthrEYZ9CBmPug2QPGWxhJxh/vCgBjro5o96gL04WLlg5BA233OCWLqERy4YUzX3bJGXaJgQ==} cpu: [arm64] os: [linux] - '@rollup/rollup-linux-arm64-musl@4.18.0': - resolution: {integrity: sha512-be6Yx37b24ZwxQ+wOQXXLZqpq4jTckJhtGlWGZs68TgdKXJgw54lUUoFYrg6Zs/kjzAQwEwYbp8JxZVzZLRepQ==} + '@rollup/rollup-linux-arm64-musl@4.18.1': + resolution: {integrity: sha512-dJX9u4r4bqInMGOAQoGYdwDP8lQiisWb9et+T84l2WXk41yEej8v2iGKodmdKimT8cTAYt0jFb+UEBxnPkbXEQ==} cpu: [arm64] os: [linux] - '@rollup/rollup-linux-powerpc64le-gnu@4.18.0': - resolution: {integrity: sha512-hNVMQK+qrA9Todu9+wqrXOHxFiD5YmdEi3paj6vP02Kx1hjd2LLYR2eaN7DsEshg09+9uzWi2W18MJDlG0cxJA==} + '@rollup/rollup-linux-powerpc64le-gnu@4.18.1': + resolution: {integrity: sha512-V72cXdTl4EI0x6FNmho4D502sy7ed+LuVW6Ym8aI6DRQ9hQZdp5sj0a2usYOlqvFBNKQnLQGwmYnujo2HvjCxQ==} cpu: [ppc64] os: [linux] - '@rollup/rollup-linux-riscv64-gnu@4.18.0': - resolution: {integrity: sha512-ROCM7i+m1NfdrsmvwSzoxp9HFtmKGHEqu5NNDiZWQtXLA8S5HBCkVvKAxJ8U+CVctHwV2Gb5VUaK7UAkzhDjlg==} + '@rollup/rollup-linux-riscv64-gnu@4.18.1': + resolution: {integrity: sha512-f+pJih7sxoKmbjghrM2RkWo2WHUW8UbfxIQiWo5yeCaCM0TveMEuAzKJte4QskBp1TIinpnRcxkquY+4WuY/tg==} cpu: [riscv64] os: [linux] - '@rollup/rollup-linux-s390x-gnu@4.18.0': - resolution: {integrity: sha512-0UyyRHyDN42QL+NbqevXIIUnKA47A+45WyasO+y2bGJ1mhQrfrtXUpTxCOrfxCR4esV3/RLYyucGVPiUsO8xjg==} + '@rollup/rollup-linux-s390x-gnu@4.18.1': + resolution: {integrity: sha512-qb1hMMT3Fr/Qz1OKovCuUM11MUNLUuHeBC2DPPAWUYYUAOFWaxInaTwTQmc7Fl5La7DShTEpmYwgdt2hG+4TEg==} cpu: [s390x] os: [linux] - '@rollup/rollup-linux-x64-gnu@4.18.0': - resolution: {integrity: sha512-xuglR2rBVHA5UsI8h8UbX4VJ470PtGCf5Vpswh7p2ukaqBGFTnsfzxUBetoWBWymHMxbIG0Cmx7Y9qDZzr648w==} + '@rollup/rollup-linux-x64-gnu@4.18.1': + resolution: {integrity: sha512-7O5u/p6oKUFYjRbZkL2FLbwsyoJAjyeXHCU3O4ndvzg2OFO2GinFPSJFGbiwFDaCFc+k7gs9CF243PwdPQFh5g==} cpu: [x64] os: [linux] - '@rollup/rollup-linux-x64-musl@4.18.0': - resolution: {integrity: sha512-LKaqQL9osY/ir2geuLVvRRs+utWUNilzdE90TpyoX0eNqPzWjRm14oMEE+YLve4k/NAqCdPkGYDaDF5Sw+xBfg==} + '@rollup/rollup-linux-x64-musl@4.18.1': + resolution: {integrity: sha512-pDLkYITdYrH/9Cv/Vlj8HppDuLMDUBmgsM0+N+xLtFd18aXgM9Nyqupb/Uw+HeidhfYg2lD6CXvz6CjoVOaKjQ==} cpu: [x64] os: [linux] - '@rollup/rollup-win32-arm64-msvc@4.18.0': - resolution: {integrity: sha512-7J6TkZQFGo9qBKH0pk2cEVSRhJbL6MtfWxth7Y5YmZs57Pi+4x6c2dStAUvaQkHQLnEQv1jzBUW43GvZW8OFqA==} + '@rollup/rollup-win32-arm64-msvc@4.18.1': + resolution: {integrity: sha512-W2ZNI323O/8pJdBGil1oCauuCzmVd9lDmWBBqxYZcOqWD6aWqJtVBQ1dFrF4dYpZPks6F+xCZHfzG5hYlSHZ6g==} cpu: [arm64] os: [win32] - '@rollup/rollup-win32-ia32-msvc@4.18.0': - resolution: {integrity: sha512-Txjh+IxBPbkUB9+SXZMpv+b/vnTEtFyfWZgJ6iyCmt2tdx0OF5WhFowLmnh8ENGNpfUlUZkdI//4IEmhwPieNg==} + '@rollup/rollup-win32-ia32-msvc@4.18.1': + resolution: {integrity: sha512-ELfEX1/+eGZYMaCIbK4jqLxO1gyTSOIlZr6pbC4SRYFaSIDVKOnZNMdoZ+ON0mrFDp4+H5MhwNC1H/AhE3zQLg==} cpu: [ia32] os: [win32] - '@rollup/rollup-win32-x64-msvc@4.18.0': - resolution: {integrity: sha512-UOo5FdvOL0+eIVTgS4tIdbW+TtnBLWg1YBCcU2KWM7nuNwRz9bksDX1bekJJCpu25N1DVWaCwnT39dVQxzqS8g==} + '@rollup/rollup-win32-x64-msvc@4.18.1': + resolution: {integrity: sha512-yjk2MAkQmoaPYCSu35RLJ62+dz358nE83VfTePJRp8CG7aMg25mEJYpXFiD+NcevhX8LxD5OP5tktPXnXN7GDw==} cpu: [x64] os: [win32] @@ -588,42 +588,33 @@ packages: '@types/estree@1.0.5': resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==} - '@types/node@20.14.9': - resolution: {integrity: sha512-06OCtnTXtWOZBJlRApleWndH4JsRVs1pDCc8dLSQp+7PpUpX3ePdHyeNSFTeSe7FtKyQkrlPvHwJOW3SLd8Oyg==} + '@types/node@20.14.10': + resolution: {integrity: sha512-MdiXf+nDuMvY0gJKxyfZ7/6UFsETO7mGKF54MVD/ekJS6HdFtpZFBgrh6Pseu64XTb2MLyFPlbW6hj8HYRQNOQ==} - '@vitest/coverage-v8@1.6.0': - resolution: {integrity: sha512-KvapcbMY/8GYIG0rlwwOKCVNRc0OL20rrhFkg/CHNzncV03TE2XWvO5w9uZYoxNiMEBacAJt3unSOiZ7svePew==} + '@vitest/coverage-v8@2.0.1': + resolution: {integrity: sha512-ACcSlJtWlravv0QyJSCO9rvm06msj6x0HooXouB0NXKG6PGxUN5VX4X8QEATfTMGsJlZLqWvq0dEY9W1V0rcSw==} peerDependencies: - vitest: 1.6.0 + vitest: 2.0.1 - '@vitest/expect@1.6.0': - resolution: {integrity: sha512-ixEvFVQjycy/oNgHjqsL6AZCDduC+tflRluaHIzKIsdbzkLn2U/iBnVeJwB6HsIjQBdfMR8Z0tRxKUsvFJEeWQ==} + '@vitest/expect@2.0.1': + resolution: {integrity: sha512-yw70WL3ZwzbI2O3MOXYP2Shf4vqVkS3q5FckLJ6lhT9VMMtDyWdofD53COZcoeuHwsBymdOZp99r5bOr5g+oeA==} - '@vitest/runner@1.6.0': - resolution: {integrity: sha512-P4xgwPjwesuBiHisAVz/LSSZtDjOTPYZVmNAnpHHSR6ONrf8eCJOFRvUwdHn30F5M1fxhqtl7QZQUk2dprIXAg==} + '@vitest/runner@2.0.1': + resolution: {integrity: sha512-XfcSXOGGxgR2dQ466ZYqf0ZtDLLDx9mZeQcKjQDLQ9y6Cmk2Wl7wxMuhiYK4Fo1VxCtLcFEGW2XpcfMuiD1Maw==} - '@vitest/snapshot@1.6.0': - resolution: {integrity: sha512-+Hx43f8Chus+DCmygqqfetcAZrDJwvTj0ymqjQq4CvmpKFSTVteEOBzCusu1x2tt4OJcvBflyHUE0DZSLgEMtQ==} + '@vitest/snapshot@2.0.1': + resolution: {integrity: sha512-rst79a4Q+J5vrvHRapdfK4BdqpMH0eF58jVY1vYeBo/1be+nkyenGI5SCSohmjf6MkCkI20/yo5oG+0R8qrAnA==} - '@vitest/spy@1.6.0': - resolution: {integrity: sha512-leUTap6B/cqi/bQkXUu6bQV5TZPx7pmMBKBQiI0rJA8c3pB56ZsaTbREnF7CJfmvAS4V2cXIBAh/3rVwrrCYgw==} + '@vitest/spy@2.0.1': + resolution: {integrity: sha512-NLkdxbSefAtJN56GtCNcB4GiHFb5i9q1uh4V229lrlTZt2fnwsTyjLuWIli1xwK2fQspJJmHXHyWx0Of3KTXWA==} - '@vitest/utils@1.6.0': - resolution: {integrity: sha512-21cPiuGMoMZwiOHa2i4LXkMkMkCGzA+MVFV70jRwHo95dL4x/ts5GZhML1QWuy7yfp3WzK3lRvZi3JnXTYqrBw==} + '@vitest/utils@2.0.1': + resolution: {integrity: sha512-STH+2fHZxlveh1mpU4tKzNgRk7RZJyr6kFGJYCI5vocdfqfPsQrgVC6k7dBWHfin5QNB4TLvRS0Ckly3Dt1uWw==} abbrev@2.0.0: resolution: {integrity: sha512-6/mh1E2u2YgEsCHdY0Yx5oW+61gZU+1vXaoiHHrpKeuRNNgFvS+/jrwHiQhB5apAf5oB7UB7E19ol2R2LKH8hQ==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - acorn-walk@8.3.3: - resolution: {integrity: sha512-MxXdReSRhGO7VlFe1bRG/oI7/mdLV9B9JJT0N8vZOhF7gFRR5l3M8W9G8JxmKV+JC5mGqJ0QvqfSOLsCPa4nUw==} - engines: {node: '>=0.4.0'} - - acorn@8.12.0: - resolution: {integrity: sha512-RTvkC4w+KNXrM39/lWCUaG0IbRkWdCv7W/IOW9oU6SawyxulvkQy5HQPVTKxEjczcUvapcrw3cFx/60VN/NRNw==} - engines: {node: '>=0.4.0'} - hasBin: true - agent-base@7.1.1: resolution: {integrity: sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==} engines: {node: '>= 14'} @@ -656,8 +647,9 @@ packages: resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} engines: {node: '>=12'} - assertion-error@1.1.0: - resolution: {integrity: sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==} + assertion-error@2.0.1: + resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} + engines: {node: '>=12'} balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} @@ -668,9 +660,6 @@ packages: bl@4.1.0: resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==} - brace-expansion@1.1.11: - resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} - brace-expansion@2.0.1: resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} @@ -685,16 +674,17 @@ packages: resolution: {integrity: sha512-qXCd4rh6I07cnDqh8V48/94Tc/WSfj+o3Gn6NZ0aZovS255bUx8O13uKxRFd2eWG0xgsco7+YItQNPaa5E85hg==} engines: {node: ^16.14.0 || >=18.0.0} - chai@4.4.1: - resolution: {integrity: sha512-13sOfMv2+DWduEU+/xbun3LScLoqN17nBeTLUsmDfKdoiC1fr0n9PU4guu4AhRcOVFk/sW8LyZWHuhWtQZiF+g==} - engines: {node: '>=4'} + chai@5.1.1: + resolution: {integrity: sha512-pT1ZgP8rPNqUgieVaEY+ryQr6Q4HXNg8Ei9UnLUrjN4IA7dvQC5JB+/kxVcPNDHyBcc/26CXPkbNzq3qwrOEKA==} + engines: {node: '>=12'} chalk@2.4.2: resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} engines: {node: '>=4'} - check-error@1.0.3: - resolution: {integrity: sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==} + check-error@2.1.1: + resolution: {integrity: sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==} + engines: {node: '>= 16'} chownr@1.1.4: resolution: {integrity: sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==} @@ -720,12 +710,6 @@ packages: color-name@1.1.4: resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} - concat-map@0.0.1: - resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} - - confbox@0.1.7: - resolution: {integrity: sha512-uJcB/FKZtBMCJpK8MQji6bJHgu1tixKPxRLeGkNzBoOZzpnZUJm0jm2/sBDWcuBx1dYgxV4JU+g5hmNxCyAmdA==} - cross-spawn@7.0.3: resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} engines: {node: '>= 8'} @@ -739,8 +723,8 @@ packages: supports-color: optional: true - deep-eql@4.1.4: - resolution: {integrity: sha512-SUwdGfqdKOwxCPeVYjwSyRpJ7Z+fhpwIAtmCUdZIWZ/YP5R9WAsyuSgpLVDi9bjWoN2LXHNss/dk3urXtdQxGg==} + deep-eql@5.0.2: + resolution: {integrity: sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==} engines: {node: '>=6'} diff-sequences@29.6.3: @@ -814,9 +798,6 @@ packages: resolution: {integrity: sha512-XUBA9XClHbnJWSfBzjkm6RvPsyg3sryZt06BEQoXcF7EK/xpGaQYJgQKDJSUH5SGZ76Y7pFx1QBnXz09rU5Fbw==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - fs.realpath@1.0.0: - resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} - fsevents@2.3.3: resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} @@ -840,9 +821,10 @@ packages: engines: {node: '>=16 || 14 >=14.18'} hasBin: true - glob@7.2.3: - resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} - deprecated: Glob versions prior to v9 are no longer supported + glob@11.0.0: + resolution: {integrity: sha512-9UiX/Bl6J2yaBbxKoEBRm4Cipxgok8kQYcOPEhScPwebu2I0HoQOuYdIO6S3hLuWoZgpDpwQZMzTFxgpkyT76g==} + engines: {node: 20 || >=22} + hasBin: true graceful-fs@4.2.11: resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} @@ -892,10 +874,6 @@ packages: resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==} engines: {node: '>=8'} - inflight@1.0.6: - resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} - deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful. - inherits@2.0.4: resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} @@ -933,8 +911,8 @@ packages: resolution: {integrity: sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==} engines: {node: '>=10'} - istanbul-lib-source-maps@5.0.4: - resolution: {integrity: sha512-wHOoEsNJTVltaJp8eVkm8w+GVkVNHT2YDYo53YdzQEL2gWm1hBX5cGFR9hQJtuGLebidVX7et3+dmDZrmclduw==} + istanbul-lib-source-maps@5.0.6: + resolution: {integrity: sha512-yg2d+Em4KizZC5niWhQaIomgf5WlL4vOOjZ5xGCmF8SnPE/mDWWXgvRExdcpCgh9lLRRa1/fSYp2ymmbJ1pI+A==} engines: {node: '>=10'} istanbul-reports@3.1.7: @@ -945,6 +923,10 @@ packages: resolution: {integrity: sha512-JVYhQnN59LVPFCEcVa2C3CrEKYacvjRfqIQl+h8oi91aLYQVWRYbxjPcv1bUiUy/kLmQaANrYfNMCO3kuEDHfw==} engines: {node: '>=14'} + jackspeak@4.0.1: + resolution: {integrity: sha512-cub8rahkh0Q/bw1+GxP7aeSe29hHHn2V4m29nnDlvCdlgU+3UGxkZp7Z53jLUdpX3jdTO0nJZUDl3xvbWc2Xog==} + engines: {node: 20 || >=22} + js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} @@ -954,61 +936,69 @@ packages: jsbn@1.1.0: resolution: {integrity: sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==} - lefthook-darwin-arm64@1.6.18: - resolution: {integrity: sha512-AkpsTeO7aLZIIy6CKQ7Chx8RltE8a9uItbwQWoeaCkIdzpV8TFjq7/Pw4F5CkoJ2315sHtB8k+VFkgipQMBw1w==} + lefthook-darwin-arm64@1.7.1: + resolution: {integrity: sha512-WNM92Ix2rKmDKXzjlkVGCdzSkzzj3Z9D7yKi22KeOZ1iCXG1EtXEWmXO5M2g28FNb4cZI0r2DACNH5hz8JsfgA==} cpu: [arm64] os: [darwin] + hasBin: true - lefthook-darwin-x64@1.6.18: - resolution: {integrity: sha512-qwKa+PaNIYjZ2PVrRRLq+HjNjQsjEItXN21byvSD89r7EYCULsIC8aW4H6aniOP2A6X1DIZ+djpg+3hNJ/94NA==} + lefthook-darwin-x64@1.7.1: + resolution: {integrity: sha512-SDPEciuP+eNzuKN8kx1x0dRzFElpO65on5q0raKgTbTvSOyVd3c7sMLGluz6OSM5qqEWEdEeA8QYKpdA56uXEw==} cpu: [x64] os: [darwin] + hasBin: true - lefthook-freebsd-arm64@1.6.18: - resolution: {integrity: sha512-UIOzQ+okwB7Ah9p8sNqomOiU6cPfmJnyW3HDPutRsdoHRD8udIap9d+ja4Kg4m/PkoYtkcLO78omANqAgA5wxQ==} + lefthook-freebsd-arm64@1.7.1: + resolution: {integrity: sha512-Ym2hhv6w7RWva3jfjtBOYck+GiaCx1JpnsOCf9tDYKFiV6ve/DoLrGQ+uI0UOqtiHN/bJzt5BrNXygfAubXaEg==} cpu: [arm64] os: [freebsd] + hasBin: true - lefthook-freebsd-x64@1.6.18: - resolution: {integrity: sha512-UQANUgyNpaAh0+2/PjPFiJ7yd6aF15yyJxKZCXyna5cQF7VU8pSHu5tiDDquNpjToXOg+6TmiIAJKyfrrwTF3w==} + lefthook-freebsd-x64@1.7.1: + resolution: {integrity: sha512-u9WYd+LDJr1A+VQV6lTe1a0yG0Ew9Wgeb9Ym9IKr9eLblrt6JNvW1x9u0e9OFteLwnqBCCT8omBY+NARcvqVvg==} cpu: [x64] os: [freebsd] + hasBin: true - lefthook-linux-arm64@1.6.18: - resolution: {integrity: sha512-4erletIa2HKUgY17/1ROvndAj6xn/9wkqO2GhBT3C0vFwIv6ycy5wpFzXOwKRZpFYv7UacN7iXhAZSK+vSOZZg==} + lefthook-linux-arm64@1.7.1: + resolution: {integrity: sha512-Sgc+vHNnAbiJ5b1yMJsFn/rQ6eVQ0KLzuL0x0KJqFZvmffFenVmqABrFHKNDzhj8//KUbHdgCgLzqQAkAbCNcg==} cpu: [arm64] os: [linux] + hasBin: true - lefthook-linux-x64@1.6.18: - resolution: {integrity: sha512-l5SRqYMYygw9RjZncEg8uh29wShYN8kiYr53sp74DkntrlCttqWhLILBUlIr3fxH5s0ZyrmqUEjtMBryMk7b/g==} + lefthook-linux-x64@1.7.1: + resolution: {integrity: sha512-UDIM6Cf0aHrfvIxeVz05M7g+omLdyTQpmB2BqkeANpd/5+1LqRMOBOdtW+y3X47NKYL++iFh2EtIhlIqVBj6Kw==} cpu: [x64] os: [linux] + hasBin: true - lefthook-windows-arm64@1.6.18: - resolution: {integrity: sha512-jeNBRoya3+mOEsKyT4wXf29Kng1nkJD7Uv/dqGBszoGMktGVNUFdIjWoxx6HSfhUssucs5pKRZpXSMgK/KCP+Q==} + lefthook-windows-arm64@1.7.1: + resolution: {integrity: sha512-cz3vhIdmORA25YF4ZnPjDQwi/KQd8cB89q7jHEQ9sv+bpSOTXiauMOM9jvXbnvGrmFaR1qbLRTYpKQs6oyGdsA==} cpu: [arm64] os: [win32] + hasBin: true - lefthook-windows-x64@1.6.18: - resolution: {integrity: sha512-iEG8PbFOwMqlpAgCiqzANTxutERjwlwMx6WF6HDGEYwFJSCJsvi06TehDxaPIFbhmLLYYlbVrfSBlttWGoN0dg==} + lefthook-windows-x64@1.7.1: + resolution: {integrity: sha512-Fa9HEkJczbD1zu6wBKP2rR738uRei5sb76d/DzgqW09ZBTwQl+6Oiyg3kicVU1N1X8bhZ/g1h49tcHrVtjU5ww==} cpu: [x64] os: [win32] - - lefthook@1.6.18: - resolution: {integrity: sha512-Ftr/NkU1P1EsEyphsCqCX7lesGZA+QDXyUx4dS1RlSKB72xKtGW9VPjbGLK2kSQkONG5M+XYfbJkGA/r9NLTYQ==} hasBin: true - local-pkg@0.5.0: - resolution: {integrity: sha512-ok6z3qlYyCDS4ZEU27HaU6x/xZa9Whf8jD4ptH5UZTQYZVYeb9bnZ3ojVhiJNLiXK1Hfc0GNbLXcmZ5plLDDBg==} - engines: {node: '>=14'} + lefthook@1.7.1: + resolution: {integrity: sha512-WNgjrPH4bYZyAYsiK7y7roQCQFIgqdCFxVCVe7ylAFD+QvW8tMceG19mR3GS2if1fGHC/cs+Z0r6PI52b/G1eA==} + hasBin: true - loupe@2.3.7: - resolution: {integrity: sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==} + loupe@3.1.1: + resolution: {integrity: sha512-edNu/8D5MKVfGVFRhFf8aAxiTM6Wumfz5XsaatSxlD3w4R1d/WEKUTydCdPGbl9K7QG/Ca3GnDV2sIKIpXRQcw==} lru-cache@10.3.0: resolution: {integrity: sha512-CQl19J/g+Hbjbv4Y3mFNNXFEL/5t/KCg8POCuUqd4rMKjGG+j1ybER83hxV58zL+dFI1PTkt3GNFSHRt+d8qEQ==} engines: {node: 14 || >=16.14} + lru-cache@11.0.0: + resolution: {integrity: sha512-Qv32eSV1RSCfhY3fpPE2GNZ8jgM9X7rdAfemLWqTUxwiyIC4jJ6Sy0fZ8H+oLWevO6i4/bizg7c8d8i6bxrzbA==} + engines: {node: 20 || >=22} + magic-string@0.30.10: resolution: {integrity: sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==} @@ -1030,8 +1020,9 @@ packages: resolution: {integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==} engines: {node: '>=12'} - minimatch@3.1.2: - resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + minimatch@10.0.1: + resolution: {integrity: sha512-ethXTt3SGGR+95gudmqJ1eNhRO7eGEGIgYA9vnPatK4/etz2MEVDno5GMCibdMTuBMyElzIlgxMna3K94XDIDQ==} + engines: {node: 20 || >=22} minimatch@9.0.5: resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} @@ -1084,9 +1075,6 @@ packages: engines: {node: '>=10'} hasBin: true - mlly@1.7.1: - resolution: {integrity: sha512-rrVRZRELyQzrIUAVMHxP97kv+G786pHmOKzuFII8zDYahFBS7qnHh2AlYSl1GAHhaMPCz6/oHjVMcfFYgFYHgA==} - ms@2.1.2: resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} @@ -1135,10 +1123,6 @@ packages: resolution: {integrity: sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==} engines: {node: '>=12'} - p-limit@5.0.0: - resolution: {integrity: sha512-/Eaoq+QyLSiXQ4lyYV23f14mZRQcXnxfHrN0vCai+ak9G0pp9iEQukIIZq5NccEvwRB8PUnZT0KsOoDCINS1qQ==} - engines: {node: '>=18'} - p-map@4.0.0: resolution: {integrity: sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==} engines: {node: '>=10'} @@ -1146,10 +1130,6 @@ packages: package-json-from-dist@1.0.0: resolution: {integrity: sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==} - path-is-absolute@1.0.1: - resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} - engines: {node: '>=0.10.0'} - path-key@3.1.1: resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} engines: {node: '>=8'} @@ -1165,11 +1145,16 @@ packages: resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} engines: {node: '>=16 || 14 >=14.18'} + path-scurry@2.0.0: + resolution: {integrity: sha512-ypGJsmGtdXUOeM5u93TyeIEfEhM6s+ljAhrk5vAvSx8uyY/02OvrZnA0YNGUrPXfpJMgI1ODd3nwz8Npx4O4cg==} + engines: {node: 20 || >=22} + pathe@1.1.2: resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==} - pathval@1.1.1: - resolution: {integrity: sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==} + pathval@2.0.0: + resolution: {integrity: sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==} + engines: {node: '>= 14.16'} picocolors@1.0.1: resolution: {integrity: sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==} @@ -1178,9 +1163,6 @@ packages: resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} engines: {node: '>=8.6'} - pkg-types@1.1.1: - resolution: {integrity: sha512-ko14TjmDuQJ14zsotODv7dBlwxKhUKQEhuhmbqo1uCi9BB0Z2alo/wAXg6q1dTR5TyuqYyWhjtfe/Tsh+X28jQ==} - postcss@8.4.38: resolution: {integrity: sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==} engines: {node: ^10 || ^12 || >=14} @@ -1226,9 +1208,9 @@ packages: resolution: {integrity: sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==} engines: {node: '>= 4'} - rimraf@5.0.7: - resolution: {integrity: sha512-nV6YcJo5wbLW77m+8KjH8aB/7/rxQy9SZ0HY5shnwULfS+9nmTtVXAJET5NdZmCzA4fPI/Hm1wo/Po/4mopOdg==} - engines: {node: '>=14.18'} + rimraf@6.0.0: + resolution: {integrity: sha512-u+yqhM92LW+89cxUQK0SRyvXYQmyuKHx0jkx4W7KfwLGLqJnQM5031Uv1trE4gB9XEXBM/s6MxKlfW95IidqaA==} + engines: {node: 20 || >=22} hasBin: true rollup-plugin-dts@6.1.1: @@ -1245,8 +1227,8 @@ packages: esbuild: '>=0.18.0' rollup: ^1.20.0 || ^2.0.0 || ^3.0.0 || ^4.0.0 - rollup@4.18.0: - resolution: {integrity: sha512-QmJz14PX3rzbJCN1SG4Xe/bAAX2a6NpCP8ab2vfu2GiUr8AQcr2nCV/oEO3yneFarB67zk8ShlIyWb2LGTb3Sg==} + rollup@4.18.1: + resolution: {integrity: sha512-Elx2UT8lzxxOXMpy5HWQGZqkrQOtrVDDa/bm9l10+U4rQnVzbL/LgZ4NOM1MPIDyHk69W4InuYDF5dzRh4Kw1A==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true @@ -1358,19 +1340,19 @@ packages: resolution: {integrity: sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==} engines: {node: '>=10'} - test-exclude@6.0.0: - resolution: {integrity: sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==} - engines: {node: '>=8'} + test-exclude@7.0.1: + resolution: {integrity: sha512-pFYqmTw68LXVjeWJMST4+borgQP2AyMNbg1BpZh9LbyhUeNkeaPF9gzfPGUAnSMV3qPYdWUwDIjjCLiSDOl7vg==} + engines: {node: '>=18'} tinybench@2.8.0: resolution: {integrity: sha512-1/eK7zUnIklz4JUUlL+658n58XO2hHLQfSk1Zf2LKieUjxidN16eKFEoDEfjHc3ohofSSqK3X5yO6VGb6iW8Lw==} - tinypool@0.8.4: - resolution: {integrity: sha512-i11VH5gS6IFeLY3gMBQ00/MmLncVP7JLXOw1vlgkytLmJK7QnEr7NXf0LBdxfmNPAeyetukOk0bOYrJrFGjYJQ==} - engines: {node: '>=14.0.0'} + tinypool@1.0.0: + resolution: {integrity: sha512-KIKExllK7jp3uvrNtvRBYBWBOAXSX8ZvoaD8T+7KB/QHIuoJW3Pmr60zucywjAlMb5TeXUkcs/MWeWLu0qvuAQ==} + engines: {node: ^18.0.0 || >=20.0.0} - tinyspy@2.2.1: - resolution: {integrity: sha512-KYad6Vy5VDWV4GH3fjpseMQ/XU2BhIYP7Vzd0LG44qRWm/Yt2WCOTicFdvmgo6gWaqooMQCawTtILVQJupKu7A==} + tinyspy@3.0.0: + resolution: {integrity: sha512-q5nmENpTHgiPVd1cJDDc9cVoYN5x4vCvwT3FMilvKPKneCBZAxn2YWQjDF0UMcE9k0Cay1gBiDfTMU0g+mPMQA==} engines: {node: '>=14.0.0'} to-fast-properties@2.0.0: @@ -1380,18 +1362,11 @@ packages: tslib@2.6.3: resolution: {integrity: sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==} - type-detect@4.0.8: - resolution: {integrity: sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==} - engines: {node: '>=4'} - typescript@5.5.3: resolution: {integrity: sha512-/hreyEujaB0w76zKo6717l3L0o/qEUtRgdvUBvlkhoWeOVMjMuHNHk0BRBzikzuGDqNmPQbg5ifMEqsHLiIUcQ==} engines: {node: '>=14.17'} hasBin: true - ufo@1.5.3: - resolution: {integrity: sha512-Y7HYmWaFwPUmkoQCUIAYpKqkOf+SbVj/2fJJZ4RJMCfZp0rTGwRbzQD+HghfnhKOjL9E01okqz+ncJskGYfBNw==} - undici-types@5.26.5: resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} @@ -1406,8 +1381,8 @@ packages: util-deprecate@1.0.2: resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} - vite-node@1.6.0: - resolution: {integrity: sha512-de6HJgzC+TFzOu0NTC4RAIsyf/DY/ibWDYQUcuEA84EMHhcefTUGkjFHKKEJhQN4A+6I0u++kr3l36ZF2d7XRw==} + vite-node@2.0.1: + resolution: {integrity: sha512-nVd6kyhPAql0s+xIVJzuF+RSRH8ZimNrm6U8ZvTA4MXv8CHI17TFaQwRaFiK75YX6XeFqZD4IoAaAfi9OR1XvQ==} engines: {node: ^18.0.0 || >=20.0.0} hasBin: true @@ -1439,15 +1414,15 @@ packages: terser: optional: true - vitest@1.6.0: - resolution: {integrity: sha512-H5r/dN06swuFnzNFhq/dnz37bPXnq8xB2xB5JOVk8K09rUtoeNN+LHWkoQ0A/i3hvbUKKcCei9KpbxqHMLhLLA==} + vitest@2.0.1: + resolution: {integrity: sha512-PBPvNXRJiywtI9NmbnEqHIhcXlk8mB0aKf6REQIaYGY4JtWF1Pg8Am+N0vAuxdg/wUSlxPSVJr8QdjwcVxc2Hg==} engines: {node: ^18.0.0 || >=20.0.0} hasBin: true peerDependencies: '@edge-runtime/vm': '*' '@types/node': ^18.0.0 || >=20.0.0 - '@vitest/browser': 1.6.0 - '@vitest/ui': 1.6.0 + '@vitest/browser': 2.0.1 + '@vitest/ui': 2.0.1 happy-dom: '*' jsdom: '*' peerDependenciesMeta: @@ -1493,10 +1468,6 @@ packages: yallist@4.0.0: resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} - yocto-queue@1.0.0: - resolution: {integrity: sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==} - engines: {node: '>=12.20'} - snapshots: '@ampproject/remapping@2.3.0': @@ -1759,135 +1730,128 @@ snapshots: '@pkgjs/parseargs@0.11.0': optional: true - '@rollup/plugin-typescript@11.1.6(rollup@4.18.0)(tslib@2.6.3)(typescript@5.5.3)': + '@rollup/plugin-typescript@11.1.6(rollup@4.18.1)(tslib@2.6.3)(typescript@5.5.3)': dependencies: - '@rollup/pluginutils': 5.1.0(rollup@4.18.0) + '@rollup/pluginutils': 5.1.0(rollup@4.18.1) resolve: 1.22.8 typescript: 5.5.3 optionalDependencies: - rollup: 4.18.0 + rollup: 4.18.1 tslib: 2.6.3 - '@rollup/pluginutils@5.1.0(rollup@4.18.0)': + '@rollup/pluginutils@5.1.0(rollup@4.18.1)': dependencies: '@types/estree': 1.0.5 estree-walker: 2.0.2 picomatch: 2.3.1 optionalDependencies: - rollup: 4.18.0 + rollup: 4.18.1 - '@rollup/rollup-android-arm-eabi@4.18.0': + '@rollup/rollup-android-arm-eabi@4.18.1': optional: true - '@rollup/rollup-android-arm64@4.18.0': + '@rollup/rollup-android-arm64@4.18.1': optional: true - '@rollup/rollup-darwin-arm64@4.18.0': + '@rollup/rollup-darwin-arm64@4.18.1': optional: true - '@rollup/rollup-darwin-x64@4.18.0': + '@rollup/rollup-darwin-x64@4.18.1': optional: true - '@rollup/rollup-linux-arm-gnueabihf@4.18.0': + '@rollup/rollup-linux-arm-gnueabihf@4.18.1': optional: true - '@rollup/rollup-linux-arm-musleabihf@4.18.0': + '@rollup/rollup-linux-arm-musleabihf@4.18.1': optional: true - '@rollup/rollup-linux-arm64-gnu@4.18.0': + '@rollup/rollup-linux-arm64-gnu@4.18.1': optional: true - '@rollup/rollup-linux-arm64-musl@4.18.0': + '@rollup/rollup-linux-arm64-musl@4.18.1': optional: true - '@rollup/rollup-linux-powerpc64le-gnu@4.18.0': + '@rollup/rollup-linux-powerpc64le-gnu@4.18.1': optional: true - '@rollup/rollup-linux-riscv64-gnu@4.18.0': + '@rollup/rollup-linux-riscv64-gnu@4.18.1': optional: true - '@rollup/rollup-linux-s390x-gnu@4.18.0': + '@rollup/rollup-linux-s390x-gnu@4.18.1': optional: true - '@rollup/rollup-linux-x64-gnu@4.18.0': + '@rollup/rollup-linux-x64-gnu@4.18.1': optional: true - '@rollup/rollup-linux-x64-musl@4.18.0': + '@rollup/rollup-linux-x64-musl@4.18.1': optional: true - '@rollup/rollup-win32-arm64-msvc@4.18.0': + '@rollup/rollup-win32-arm64-msvc@4.18.1': optional: true - '@rollup/rollup-win32-ia32-msvc@4.18.0': + '@rollup/rollup-win32-ia32-msvc@4.18.1': optional: true - '@rollup/rollup-win32-x64-msvc@4.18.0': + '@rollup/rollup-win32-x64-msvc@4.18.1': optional: true '@sinclair/typebox@0.27.8': {} '@types/estree@1.0.5': {} - '@types/node@20.14.9': + '@types/node@20.14.10': dependencies: undici-types: 5.26.5 - '@vitest/coverage-v8@1.6.0(vitest@1.6.0(@types/node@20.14.9))': + '@vitest/coverage-v8@2.0.1(vitest@2.0.1(@types/node@20.14.10))': dependencies: '@ampproject/remapping': 2.3.0 '@bcoe/v8-coverage': 0.2.3 debug: 4.3.5 istanbul-lib-coverage: 3.2.2 istanbul-lib-report: 3.0.1 - istanbul-lib-source-maps: 5.0.4 + istanbul-lib-source-maps: 5.0.6 istanbul-reports: 3.1.7 magic-string: 0.30.10 magicast: 0.3.4 picocolors: 1.0.1 std-env: 3.7.0 strip-literal: 2.1.0 - test-exclude: 6.0.0 - vitest: 1.6.0(@types/node@20.14.9) + test-exclude: 7.0.1 + vitest: 2.0.1(@types/node@20.14.10) transitivePeerDependencies: - supports-color - '@vitest/expect@1.6.0': + '@vitest/expect@2.0.1': dependencies: - '@vitest/spy': 1.6.0 - '@vitest/utils': 1.6.0 - chai: 4.4.1 + '@vitest/spy': 2.0.1 + '@vitest/utils': 2.0.1 + chai: 5.1.1 - '@vitest/runner@1.6.0': + '@vitest/runner@2.0.1': dependencies: - '@vitest/utils': 1.6.0 - p-limit: 5.0.0 + '@vitest/utils': 2.0.1 pathe: 1.1.2 - '@vitest/snapshot@1.6.0': + '@vitest/snapshot@2.0.1': dependencies: magic-string: 0.30.10 pathe: 1.1.2 pretty-format: 29.7.0 - '@vitest/spy@1.6.0': + '@vitest/spy@2.0.1': dependencies: - tinyspy: 2.2.1 + tinyspy: 3.0.0 - '@vitest/utils@1.6.0': + '@vitest/utils@2.0.1': dependencies: diff-sequences: 29.6.3 estree-walker: 3.0.3 - loupe: 2.3.7 + loupe: 3.1.1 pretty-format: 29.7.0 abbrev@2.0.0: {} - acorn-walk@8.3.3: - dependencies: - acorn: 8.12.0 - - acorn@8.12.0: {} - agent-base@7.1.1: dependencies: debug: 4.3.5 @@ -1916,7 +1880,7 @@ snapshots: ansi-styles@6.2.1: {} - assertion-error@1.1.0: {} + assertion-error@2.0.1: {} balanced-match@1.0.2: {} @@ -1928,11 +1892,6 @@ snapshots: inherits: 2.0.4 readable-stream: 3.6.2 - brace-expansion@1.1.11: - dependencies: - balanced-match: 1.0.2 - concat-map: 0.0.1 - brace-expansion@2.0.1: dependencies: balanced-match: 1.0.2 @@ -1959,15 +1918,13 @@ snapshots: tar: 6.2.1 unique-filename: 3.0.0 - chai@4.4.1: + chai@5.1.1: dependencies: - assertion-error: 1.1.0 - check-error: 1.0.3 - deep-eql: 4.1.4 - get-func-name: 2.0.2 - loupe: 2.3.7 - pathval: 1.1.1 - type-detect: 4.0.8 + assertion-error: 2.0.1 + check-error: 2.1.1 + deep-eql: 5.0.2 + loupe: 3.1.1 + pathval: 2.0.0 chalk@2.4.2: dependencies: @@ -1976,9 +1933,7 @@ snapshots: supports-color: 5.5.0 optional: true - check-error@1.0.3: - dependencies: - get-func-name: 2.0.2 + check-error@2.1.1: {} chownr@1.1.4: {} @@ -2000,10 +1955,6 @@ snapshots: color-name@1.1.4: {} - concat-map@0.0.1: {} - - confbox@0.1.7: {} - cross-spawn@7.0.3: dependencies: path-key: 3.1.1 @@ -2014,9 +1965,7 @@ snapshots: dependencies: ms: 2.1.2 - deep-eql@4.1.4: - dependencies: - type-detect: 4.0.8 + deep-eql@5.0.2: {} diff-sequences@29.6.3: {} @@ -2132,8 +2081,6 @@ snapshots: dependencies: minipass: 7.1.2 - fs.realpath@1.0.0: {} - fsevents@2.3.3: optional: true @@ -2156,14 +2103,14 @@ snapshots: package-json-from-dist: 1.0.0 path-scurry: 1.11.1 - glob@7.2.3: + glob@11.0.0: dependencies: - fs.realpath: 1.0.0 - inflight: 1.0.6 - inherits: 2.0.4 - minimatch: 3.1.2 - once: 1.4.0 - path-is-absolute: 1.0.1 + foreground-child: 3.2.1 + jackspeak: 4.0.1 + minimatch: 10.0.1 + minipass: 7.1.2 + package-json-from-dist: 1.0.0 + path-scurry: 2.0.0 graceful-fs@4.2.11: {} @@ -2207,11 +2154,6 @@ snapshots: indent-string@4.0.0: {} - inflight@1.0.6: - dependencies: - once: 1.4.0 - wrappy: 1.0.2 - inherits@2.0.4: {} ip-address@9.0.5: @@ -2241,7 +2183,7 @@ snapshots: make-dir: 4.0.0 supports-color: 7.2.0 - istanbul-lib-source-maps@5.0.4: + istanbul-lib-source-maps@5.0.6: dependencies: '@jridgewell/trace-mapping': 0.3.25 debug: 4.3.5 @@ -2260,6 +2202,12 @@ snapshots: optionalDependencies: '@pkgjs/parseargs': 0.11.0 + jackspeak@4.0.1: + dependencies: + '@isaacs/cliui': 8.0.2 + optionalDependencies: + '@pkgjs/parseargs': 0.11.0 + js-tokens@4.0.0: optional: true @@ -2267,52 +2215,49 @@ snapshots: jsbn@1.1.0: {} - lefthook-darwin-arm64@1.6.18: + lefthook-darwin-arm64@1.7.1: optional: true - lefthook-darwin-x64@1.6.18: + lefthook-darwin-x64@1.7.1: optional: true - lefthook-freebsd-arm64@1.6.18: + lefthook-freebsd-arm64@1.7.1: optional: true - lefthook-freebsd-x64@1.6.18: + lefthook-freebsd-x64@1.7.1: optional: true - lefthook-linux-arm64@1.6.18: + lefthook-linux-arm64@1.7.1: optional: true - lefthook-linux-x64@1.6.18: + lefthook-linux-x64@1.7.1: optional: true - lefthook-windows-arm64@1.6.18: + lefthook-windows-arm64@1.7.1: optional: true - lefthook-windows-x64@1.6.18: + lefthook-windows-x64@1.7.1: optional: true - lefthook@1.6.18: + lefthook@1.7.1: optionalDependencies: - lefthook-darwin-arm64: 1.6.18 - lefthook-darwin-x64: 1.6.18 - lefthook-freebsd-arm64: 1.6.18 - lefthook-freebsd-x64: 1.6.18 - lefthook-linux-arm64: 1.6.18 - lefthook-linux-x64: 1.6.18 - lefthook-windows-arm64: 1.6.18 - lefthook-windows-x64: 1.6.18 - - local-pkg@0.5.0: - dependencies: - mlly: 1.7.1 - pkg-types: 1.1.1 + lefthook-darwin-arm64: 1.7.1 + lefthook-darwin-x64: 1.7.1 + lefthook-freebsd-arm64: 1.7.1 + lefthook-freebsd-x64: 1.7.1 + lefthook-linux-arm64: 1.7.1 + lefthook-linux-x64: 1.7.1 + lefthook-windows-arm64: 1.7.1 + lefthook-windows-x64: 1.7.1 - loupe@2.3.7: + loupe@3.1.1: dependencies: get-func-name: 2.0.2 lru-cache@10.3.0: {} + lru-cache@11.0.0: {} + magic-string@0.30.10: dependencies: '@jridgewell/sourcemap-codec': 1.4.15 @@ -2348,9 +2293,9 @@ snapshots: mimic-fn@4.0.0: {} - minimatch@3.1.2: + minimatch@10.0.1: dependencies: - brace-expansion: 1.1.11 + brace-expansion: 2.0.1 minimatch@9.0.5: dependencies: @@ -2399,13 +2344,6 @@ snapshots: mkdirp@1.0.4: {} - mlly@1.7.1: - dependencies: - acorn: 8.12.0 - pathe: 1.1.2 - pkg-types: 1.1.1 - ufo: 1.5.3 - ms@2.1.2: {} nanoid@3.3.7: {} @@ -2455,18 +2393,12 @@ snapshots: dependencies: mimic-fn: 4.0.0 - p-limit@5.0.0: - dependencies: - yocto-queue: 1.0.0 - p-map@4.0.0: dependencies: aggregate-error: 3.1.0 package-json-from-dist@1.0.0: {} - path-is-absolute@1.0.1: {} - path-key@3.1.1: {} path-key@4.0.0: {} @@ -2478,20 +2410,19 @@ snapshots: lru-cache: 10.3.0 minipass: 7.1.2 + path-scurry@2.0.0: + dependencies: + lru-cache: 11.0.0 + minipass: 7.1.2 + pathe@1.1.2: {} - pathval@1.1.1: {} + pathval@2.0.0: {} picocolors@1.0.1: {} picomatch@2.3.1: {} - pkg-types@1.1.1: - dependencies: - confbox: 0.1.7 - mlly: 1.7.1 - pathe: 1.1.2 - postcss@8.4.38: dependencies: nanoid: 3.3.7 @@ -2545,49 +2476,49 @@ snapshots: retry@0.12.0: {} - rimraf@5.0.7: + rimraf@6.0.0: dependencies: - glob: 10.4.2 + glob: 11.0.0 - rollup-plugin-dts@6.1.1(rollup@4.18.0)(typescript@5.5.3): + rollup-plugin-dts@6.1.1(rollup@4.18.1)(typescript@5.5.3): dependencies: magic-string: 0.30.10 - rollup: 4.18.0 + rollup: 4.18.1 typescript: 5.5.3 optionalDependencies: '@babel/code-frame': 7.24.7 - rollup-plugin-esbuild@6.1.1(esbuild@0.23.0)(rollup@4.18.0): + rollup-plugin-esbuild@6.1.1(esbuild@0.23.0)(rollup@4.18.1): dependencies: - '@rollup/pluginutils': 5.1.0(rollup@4.18.0) + '@rollup/pluginutils': 5.1.0(rollup@4.18.1) debug: 4.3.5 es-module-lexer: 1.5.4 esbuild: 0.23.0 get-tsconfig: 4.7.5 - rollup: 4.18.0 + rollup: 4.18.1 transitivePeerDependencies: - supports-color - rollup@4.18.0: + rollup@4.18.1: dependencies: '@types/estree': 1.0.5 optionalDependencies: - '@rollup/rollup-android-arm-eabi': 4.18.0 - '@rollup/rollup-android-arm64': 4.18.0 - '@rollup/rollup-darwin-arm64': 4.18.0 - '@rollup/rollup-darwin-x64': 4.18.0 - '@rollup/rollup-linux-arm-gnueabihf': 4.18.0 - '@rollup/rollup-linux-arm-musleabihf': 4.18.0 - '@rollup/rollup-linux-arm64-gnu': 4.18.0 - '@rollup/rollup-linux-arm64-musl': 4.18.0 - '@rollup/rollup-linux-powerpc64le-gnu': 4.18.0 - '@rollup/rollup-linux-riscv64-gnu': 4.18.0 - '@rollup/rollup-linux-s390x-gnu': 4.18.0 - '@rollup/rollup-linux-x64-gnu': 4.18.0 - '@rollup/rollup-linux-x64-musl': 4.18.0 - '@rollup/rollup-win32-arm64-msvc': 4.18.0 - '@rollup/rollup-win32-ia32-msvc': 4.18.0 - '@rollup/rollup-win32-x64-msvc': 4.18.0 + '@rollup/rollup-android-arm-eabi': 4.18.1 + '@rollup/rollup-android-arm64': 4.18.1 + '@rollup/rollup-darwin-arm64': 4.18.1 + '@rollup/rollup-darwin-x64': 4.18.1 + '@rollup/rollup-linux-arm-gnueabihf': 4.18.1 + '@rollup/rollup-linux-arm-musleabihf': 4.18.1 + '@rollup/rollup-linux-arm64-gnu': 4.18.1 + '@rollup/rollup-linux-arm64-musl': 4.18.1 + '@rollup/rollup-linux-powerpc64le-gnu': 4.18.1 + '@rollup/rollup-linux-riscv64-gnu': 4.18.1 + '@rollup/rollup-linux-s390x-gnu': 4.18.1 + '@rollup/rollup-linux-x64-gnu': 4.18.1 + '@rollup/rollup-linux-x64-musl': 4.18.1 + '@rollup/rollup-win32-arm64-msvc': 4.18.1 + '@rollup/rollup-win32-ia32-msvc': 4.18.1 + '@rollup/rollup-win32-x64-msvc': 4.18.1 fsevents: 2.3.3 safe-buffer@5.2.1: {} @@ -2701,28 +2632,24 @@ snapshots: mkdirp: 1.0.4 yallist: 4.0.0 - test-exclude@6.0.0: + test-exclude@7.0.1: dependencies: '@istanbuljs/schema': 0.1.3 - glob: 7.2.3 - minimatch: 3.1.2 + glob: 10.4.2 + minimatch: 9.0.5 tinybench@2.8.0: {} - tinypool@0.8.4: {} + tinypool@1.0.0: {} - tinyspy@2.2.1: {} + tinyspy@3.0.0: {} to-fast-properties@2.0.0: {} tslib@2.6.3: {} - type-detect@4.0.8: {} - typescript@5.5.3: {} - ufo@1.5.3: {} - undici-types@5.26.5: {} unique-filename@3.0.0: @@ -2735,13 +2662,13 @@ snapshots: util-deprecate@1.0.2: {} - vite-node@1.6.0(@types/node@20.14.9): + vite-node@2.0.1(@types/node@20.14.10): dependencies: cac: 6.7.14 debug: 4.3.5 pathe: 1.1.2 picocolors: 1.0.1 - vite: 5.3.1(@types/node@20.14.9) + vite: 5.3.1(@types/node@20.14.10) transitivePeerDependencies: - '@types/node' - less @@ -2752,39 +2679,37 @@ snapshots: - supports-color - terser - vite@5.3.1(@types/node@20.14.9): + vite@5.3.1(@types/node@20.14.10): dependencies: esbuild: 0.21.5 postcss: 8.4.38 - rollup: 4.18.0 + rollup: 4.18.1 optionalDependencies: - '@types/node': 20.14.9 + '@types/node': 20.14.10 fsevents: 2.3.3 - vitest@1.6.0(@types/node@20.14.9): + vitest@2.0.1(@types/node@20.14.10): dependencies: - '@vitest/expect': 1.6.0 - '@vitest/runner': 1.6.0 - '@vitest/snapshot': 1.6.0 - '@vitest/spy': 1.6.0 - '@vitest/utils': 1.6.0 - acorn-walk: 8.3.3 - chai: 4.4.1 + '@ampproject/remapping': 2.3.0 + '@vitest/expect': 2.0.1 + '@vitest/runner': 2.0.1 + '@vitest/snapshot': 2.0.1 + '@vitest/spy': 2.0.1 + '@vitest/utils': 2.0.1 + chai: 5.1.1 debug: 4.3.5 execa: 8.0.1 - local-pkg: 0.5.0 magic-string: 0.30.10 pathe: 1.1.2 picocolors: 1.0.1 std-env: 3.7.0 - strip-literal: 2.1.0 tinybench: 2.8.0 - tinypool: 0.8.4 - vite: 5.3.1(@types/node@20.14.9) - vite-node: 1.6.0(@types/node@20.14.9) + tinypool: 1.0.0 + vite: 5.3.1(@types/node@20.14.10) + vite-node: 2.0.1(@types/node@20.14.10) why-is-node-running: 2.2.2 optionalDependencies: - '@types/node': 20.14.9 + '@types/node': 20.14.10 transitivePeerDependencies: - less - lightningcss @@ -2822,5 +2747,3 @@ snapshots: wrappy@1.0.2: {} yallist@4.0.0: {} - - yocto-queue@1.0.0: {} diff --git a/src/index.ts b/src/index.ts index 820a376..bd3da6d 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,12 +1,11 @@ import { EventEmitter } from 'node:events'; import { dirname } from 'node:path'; import { fileURLToPath } from 'node:url'; +import nodeGypBuild from 'node-gyp-build/node-gyp-build.js'; import snooplogg, { type Logger } from 'snooplogg'; -const { default: nodeGypBuild } = await import( - 'node-gyp-build/node-gyp-build.js' -); -const binding = nodeGypBuild(dirname(dirname(fileURLToPath(import.meta.url)))); +const cwd = dirname(dirname(fileURLToPath(import.meta.url))); +const binding = nodeGypBuild(cwd); const logger = snooplogg('winreglib'); @@ -15,24 +14,24 @@ const logger = snooplogg('winreglib'); */ export class WinRegLibWatchHandle extends EventEmitter { key: string; + stop: () => void; constructor(key: string) { super(); this.key = key; - this.emit = this.emit.bind(this); - binding.watch(key, this.emit); - } - stop() { - binding.unwatch(this.key, this.emit); + const emitter = this.emit.bind(this); + binding.watch(key, emitter); + + this.stop = () => binding.unwatch(this.key, emitter); } } export type RegistryKey = { - root: string; - path: string; + resolvedRoot: string; + key: string; subkeys: string[]; - values: Record; + values: unknown[]; }; /** @@ -85,7 +84,7 @@ class WinRegLib extends EventEmitter { * @param {String} key - The key to list. * @returns {Object} Contains the resolved `root`, `path`, `subkeys`, and `values`. */ - list(key: string): RegistryKey { + list(key: string): RegistryKey | undefined { if (!key || typeof key !== 'string') { throw new TypeError('Expected key to be a non-empty string'); } diff --git a/src/watchman.cpp b/src/watchman.cpp index 681b6bb..12c4aad 100644 --- a/src/watchman.cpp +++ b/src/watchman.cpp @@ -38,9 +38,14 @@ Watchman::Watchman(napi_env env) : env(env) { // block Node from exiting uv_loop_t* loop; ::napi_get_uv_event_loop(env, &loop); + notifyChange = new uv_async_t; - notifyChange->data = this; - ::uv_async_init(loop, notifyChange, [](uv_async_t* handle) { if (handle && handle->data) ((Watchman*)handle->data)->dispatch(); }); + notifyChange->data = (void*)this; + ::uv_async_init(loop, notifyChange, [](uv_async_t* handle) { + if (handle && handle->data) { + ((Watchman*)handle->data)->dispatch(); + } + }); ::uv_unref((uv_handle_t*)notifyChange); } @@ -52,7 +57,12 @@ Watchman::~Watchman() { ::napi_delete_async_work(env, asyncWork); ::CloseHandle(term); ::CloseHandle(refresh); - ::uv_close((uv_handle_t*)notifyChange, [](uv_handle_t* handle) { if (handle) delete (uv_async_t*)handle; }); + + notifyChange->data = NULL; + ::uv_close(reinterpret_cast(notifyChange), [](uv_handle_t* handle) { + uv_async_t* async = reinterpret_cast(handle); + delete async; + }); } /** diff --git a/src/watchman.h b/src/watchman.h index 08bcdc6..bb563cd 100644 --- a/src/watchman.h +++ b/src/watchman.h @@ -4,6 +4,7 @@ #include "winreglib.h" #include "watchnode.h" #include +#include #include #include #include diff --git a/src/winreglib.cpp b/src/winreglib.cpp index 41704b1..797d679 100644 --- a/src/winreglib.cpp +++ b/src/winreglib.cpp @@ -222,9 +222,12 @@ NAPI_METHOD(init) { // wire up the log notification handler uv_loop_t* loop; napi_get_uv_event_loop(env, &loop); - winreglib::logNotify.data = env; - uv_async_init(loop, &winreglib::logNotify, &dispatchLog); - uv_unref((uv_handle_t*)&winreglib::logNotify); + if (!winreglib::logNotify) { + winreglib::logNotify = new uv_async_t; + } + winreglib::logNotify->data = env; + uv_async_init(loop, (uv_async_t*)winreglib::logNotify, &dispatchLog); + uv_unref((uv_handle_t*)winreglib::logNotify); // create the reference for the emit log callback so it doesn't get GC'd NAPI_THROW_RETURN("init", "ERR_NAPI_CREATE_REFERENCE", napi_create_reference(env, logFn, 1, &winreglib::logRef), NULL) @@ -376,27 +379,31 @@ NAPI_METHOD(unwatch) { } /** - * Destroys the Watchman instance and closes open handles. + * Destroys the Watchman instance, log ref handle, and notify handle. */ -static void cleanup(void* arg) { - napi_env env = (napi_env)arg; - +static void cleanup(napi_async_cleanup_hook_handle handle, void* arg) { if (winreglib::watchman) { - LOG_DEBUG("cleanup", L"Deleting watchman") delete winreglib::watchman; - winreglib::watchman = NULL; } - uv_close((uv_handle_t*)&winreglib::logNotify, NULL); - if (winreglib::logRef) { - napi_delete_reference(env, winreglib::logRef); + napi_delete_reference((napi_env)arg, winreglib::logRef); winreglib::logRef = NULL; } + + if (winreglib::logNotify) { + uv_close((uv_handle_t*)winreglib::logNotify, [](uv_handle_t* handle) { + if (handle) { + delete handle; + } + }); + } + + napi_remove_async_cleanup_hook(handle); } /** - * Wire up the public API and cleanup handler and creates the Watchman instance. + * Wire up the public API, cleanup handler, and creates the Watchman instance. */ NAPI_INIT() { NAPI_EXPORT_FUNCTION(get); @@ -405,7 +412,11 @@ NAPI_INIT() { NAPI_EXPORT_FUNCTION(watch); NAPI_EXPORT_FUNCTION(unwatch); - NAPI_THROW("init", "ERR_NAPI_ADD_ENV_CLEANUP_HOOK", napi_add_env_cleanup_hook(env, cleanup, env)) + NAPI_THROW( + "init", + "ERR_NAPI_ADD_ASYNC_CLEANUP_HOOK", + napi_add_async_cleanup_hook(env, cleanup, NULL, NULL) + ) winreglib::watchman = new winreglib::Watchman(env); } diff --git a/src/winreglib.h b/src/winreglib.h index 1303756..02ce385 100644 --- a/src/winreglib.h +++ b/src/winreglib.h @@ -4,7 +4,8 @@ // enable the following line to bypass the message queue and print the raw debug log messages to stdout // #define ENABLE_RAW_DEBUGGING -#define NAPI_VERSION 3 +// v12.22.0+, v14.17.0+, v15.12.0+, 16.0.0 and all later versions +#define NAPI_VERSION 8 #include #include @@ -193,12 +194,12 @@ namespace winreglib { #define LOG_DEBUG_VARS \ std::mutex logLock; \ - uv_async_t logNotify; \ + uv_async_t* logNotify; \ std::queue> logQueue; #define LOG_DEBUG_EXTERN_VARS \ extern std::mutex logLock; \ - extern uv_async_t logNotify; \ + extern uv_async_t* logNotify; \ extern std::queue> logQueue; #ifdef ENABLE_RAW_DEBUGGING @@ -218,7 +219,9 @@ namespace winreglib { std::shared_ptr obj = std::make_shared(ns, u16buffer); \ std::lock_guard lock(winreglib::logLock); \ winreglib::logQueue.push(obj); \ - ::uv_async_send(&winreglib::logNotify); \ + if (winreglib::logNotify) { \ + ::uv_async_send(winreglib::logNotify); \ + } \ } #define WLOG_DEBUG(ns, wmsg) \ @@ -227,7 +230,9 @@ namespace winreglib { std::shared_ptr obj = std::make_shared(ns, u16buffer); \ std::lock_guard lock(winreglib::logLock); \ winreglib::logQueue.push(obj); \ - ::uv_async_send(&winreglib::logNotify); \ + if (winreglib::logNotify) { \ + ::uv_async_send(winreglib::logNotify); \ + } \ } #endif diff --git a/test/wingreglib-get.test.ts b/test/wingreglib-get.test.ts new file mode 100644 index 0000000..e20a2d0 --- /dev/null +++ b/test/wingreglib-get.test.ts @@ -0,0 +1,147 @@ +import fs from 'node:fs'; +import { describe, expect, it } from 'vitest'; +import winreglib from '../src/index.js'; +const { spawnSync } = require('node:child_process'); +import snooplogg from 'snooplogg'; + +const { log } = snooplogg('test:winreglib'); + +const reg = (...args) => { + log(`Executing: reg ${args.join(' ')}`); + spawnSync('reg', args, { stdio: 'ignore' }); +}; + +describe('get()', () => { + it('should error if key is not specified', () => { + expect(() => { + // biome-ignore lint/suspicious/noExplicitAny: need to test invalid input + winreglib.get(undefined as any, undefined as any); + }).toThrowError(new TypeError('Expected key to be a non-empty string')); + }); + + it('should error if value name is not specified', () => { + expect(() => { + // biome-ignore lint/suspicious/noExplicitAny: need to test invalid input + winreglib.get('HKLM\\software', undefined as any); + }).toThrowError( + new TypeError('Expected value name to be a non-empty string') + ); + }); + + it('should error if key does not contain a subkey', () => { + expect(() => { + winreglib.get('foo', 'bar'); + }).toThrowError( + new Error('Expected key to contain both a root and subkey') + ); + }); + + it('should error if key is not valid', () => { + expect(() => { + winreglib.get('foo\\bar', 'baz'); + }).toThrowError(new Error('Invalid registry root key "foo"')); + }); + + it('should error if key is not found', () => { + expect(() => { + winreglib.get('HKLM\\foo', 'bar'); + }).toThrowError(new Error('Registry key or value not found')); + }); + + it('should error if value is not found', () => { + expect(() => { + winreglib.get('HKLM\\SOFTWARE', 'bar'); + }).toThrowError(new Error('Registry key or value not found')); + }); + + it('should get a string value', () => { + const value = winreglib.get( + 'HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion', + 'ProgramFilesDir' + ) as string; + expect(value).toBeTypeOf('string'); + expect(value).not.toBe(''); + expect(fs.existsSync(value)).toBe(true); + }); + + it('should get an expanded string value', () => { + const value = winreglib.get( + 'HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion', + 'ProgramFilesPath' + ) as string; + expect(value).toBeTypeOf('string'); + expect(value).not.toBe(''); + expect(fs.existsSync(value)).toBe(true); + }); + + it('should get multi-string value', () => { + const value = winreglib.get( + 'HKLM\\HARDWARE\\DESCRIPTION\\System', + 'SystemBiosVersion' + ) as string[]; + expect(value).toBeInstanceOf(Array); + expect(value.length).toBeGreaterThan(0); + for (const v of value) { + expect(v).toBeTypeOf('string'); + expect(v).not.toBe(''); + } + }); + + it('should get an 32-bit integer value', () => { + const value = winreglib.get( + 'HKLM\\HARDWARE\\DESCRIPTION\\System', + 'Capabilities' + ) as number; + expect(value).toBeTypeOf('number'); + expect(value).toBeGreaterThanOrEqual(0); + }); + + it('should get an 64-bit integer value', () => { + const value = winreglib.get( + 'HKLM\\Software\\Microsoft\\Windows\\CurrentVersion\\Diagnostics\\DiagTrack', + 'TriggerCount' + ) as number; + expect(value).toBeTypeOf('number'); + expect(value).toBeGreaterThanOrEqual(0); + }); + + it('should get a binary value', () => { + const value = winreglib.get( + 'HKLM\\HARDWARE\\DESCRIPTION\\System', + 'Component Information' + ) as Buffer; + expect(value).toBeInstanceOf(Buffer); + expect(value.length).toBeGreaterThan(0); + }); + + it('should get a full resource descriptor value', () => { + const value = winreglib.get( + 'HKLM\\HARDWARE\\DESCRIPTION\\System', + 'Configuration Data' + ) as Buffer; + expect(value).toBeInstanceOf(Buffer); + expect(value.length).toBeGreaterThan(0); + }); + + it('should get a resource list value', () => { + const value = winreglib.get( + 'HKLM\\HARDWARE\\RESOURCEMAP\\System Resources\\Loader Reserved', + '.Raw' + ) as Buffer; + expect(value).toBeInstanceOf(Buffer); + expect(value.length).toBeGreaterThan(0); + }); + + it('should get none value', { timeout: 15000 }, () => { + try { + reg('delete', 'HKCU\\Software\\winreglib', '/f'); + reg('add', 'HKCU\\Software\\winreglib'); + reg('add', 'HKCU\\Software\\winreglib', '/v', 'foo', '/t', 'REG_NONE'); + + const value = winreglib.get('HKCU\\Software\\winreglib', 'foo'); + expect(value).toBeNull(); + } finally { + reg('delete', 'HKCU\\Software\\winreglib', '/f'); + } + }); +}); diff --git a/test/wingreglib-list.test.ts b/test/wingreglib-list.test.ts new file mode 100644 index 0000000..2978f26 --- /dev/null +++ b/test/wingreglib-list.test.ts @@ -0,0 +1,57 @@ +import assert from 'node:assert'; +import { describe, expect, it } from 'vitest'; +import winreglib from '../src/index.js'; + +describe('list()', () => { + it('should error if key is not specified', () => { + expect(() => { + // biome-ignore lint/suspicious/noExplicitAny: need to test invalid input + winreglib.list(undefined as any); + }).toThrowError(new Error('Expected key to be a non-empty string')); + }); + + it('should error if key does not contain a subkey', () => { + expect(() => { + winreglib.list('foo'); + }).toThrowError( + new Error('Expected key to contain both a root and subkey') + ); + }); + + it('should error if key is not valid', () => { + expect(() => { + winreglib.list('foo\\bar'); + }).toThrowError(new Error('Invalid registry root key "foo"')); + }); + + it('should error if key is not found', () => { + expect(() => { + winreglib.list('HKLM\\foo'); + }).toThrowError(new Error('Registry key or value not found')); + }); + + it('should retrieve subkeys and values', () => { + const result = winreglib.list( + 'HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion' + ); + expect(result).toBeTypeOf('object'); + assert(result); + expect(result).toHaveProperty('resolvedRoot', 'HKEY_LOCAL_MACHINE'); + expect(result).toHaveProperty( + 'key', + 'HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion' + ); + expect(result).toHaveProperty('subkeys'); + expect(result.subkeys).toBeInstanceOf(Array); + for (const key of result.subkeys) { + expect(key).toBeTypeOf('string'); + expect(key).not.toBe(''); + } + expect(result).toHaveProperty('values'); + expect(result.values).toBeInstanceOf(Array); + for (const value of result.values) { + expect(value).toBeTypeOf('string'); + expect(value).not.toBe(''); + } + }); +}); diff --git a/test/wingreglib-watch.test.ts b/test/wingreglib-watch.test.ts new file mode 100644 index 0000000..4ca03e0 --- /dev/null +++ b/test/wingreglib-watch.test.ts @@ -0,0 +1,577 @@ +import { describe, expect, it } from 'vitest'; +import winreglib from '../src/index.js'; +const { spawnSync } = require('node:child_process'); +import snooplogg from 'snooplogg'; + +const { log } = snooplogg('test:winreglib'); + +const reg = (...args) => { + log(`Executing: reg ${args.join(' ')}`); + spawnSync('reg', args, { stdio: 'ignore' }); +}; + +describe('watch()', () => { + it('should error if key is not specified', () => { + expect(() => { + // biome-ignore lint/suspicious/noExplicitAny: need to test invalid input + winreglib.watch(undefined as any); + }).toThrowError(new TypeError('Expected key to be a non-empty string')); + }); + + it('should error if key does not contain a subkey', () => { + expect(() => { + winreglib.watch('HKLM'); + }).toThrowError( + new TypeError('Expected key to contain both a root and subkey') + ); + }); + + it('should error if root key is not valid', () => { + expect(() => { + winreglib.watch('foo\\bar'); + }).toThrowError(new TypeError('Invalid registry root key "foo"')); + }); + + it( + 'should watch existing key for new subkey', + { timeout: 15000 }, + async () => { + reg('delete', 'HKCU\\Software\\winreglib', '/f'); + reg('add', 'HKCU\\Software\\winreglib'); + + const handle = winreglib.watch('HKCU\\SOFTWARE\\winreglib'); + + try { + let counter = 0; + await new Promise((resolve, reject) => { + handle.on('change', evt => { + // console.log('CHANGE!', evt); + try { + expect(evt).toBeInstanceOf(Object); + switch (counter++) { + case 0: + expect(evt).toMatchObject({ + type: 'change', + key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib' + }); + reg('delete', 'HKCU\\Software\\winreglib\\foo', '/f'); + break; + case 1: + expect(evt).toMatchObject({ + type: 'change', + key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib' + }); + resolve(); + break; + } + } catch (e) { + reject(e); + } + }); + setTimeout(() => reg('add', 'HKCU\\Software\\winreglib\\foo'), 500); + }); + handle.stop(); + } finally { + // also test stop() being called twice + handle.stop(); + reg('delete', 'HKCU\\Software\\winreglib', '/f'); + } + } + ); + + it.skip( + 'should watch existing key for value change', + { timeout: 15000 }, + async () => { + reg('delete', 'HKCU\\Software\\winreglib', '/f'); + reg('add', 'HKCU\\Software\\winreglib'); + + const handle = winreglib.watch('HKCU\\SOFTWARE\\winreglib'); + + try { + let counter = 0; + await new Promise((resolve, reject) => { + handle.on('change', evt => { + console.log('CHANGE!', evt); + try { + expect(evt).toBeTypeOf('object'); + switch (counter++) { + case 0: + expect(evt).toMatchObject({ + type: 'change', + key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib' + }); + reg('delete', 'HKCU\\Software\\winreglib', '/f', '/v', 'foo'); + break; + case 1: + expect(evt).toMatchObject({ + type: 'change', + key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib' + }); + resolve(); + break; + } + } catch (e) { + reject(e); + } + }); + setTimeout( + () => + reg( + 'add', + 'HKCU\\Software\\winreglib', + '/v', + 'foo', + '/t', + 'REG_SZ', + '/d', + 'bar' + ), + 500 + ); + }); + } finally { + handle.stop(); + reg('delete', 'HKCU\\Software\\winreglib', '/f'); + } + } + ); + + it.skip( + 'should watch a key that does not exist', + { timeout: 15000 }, + async () => { + reg('delete', 'HKCU\\Software\\winreglib', '/f'); + reg('add', 'HKCU\\Software\\winreglib'); + + const handle = winreglib.watch('HKCU\\SOFTWARE\\winreglib\\foo'); + + try { + let counter = 0; + await new Promise((resolve, reject) => { + handle.on('change', evt => { + // console.log('CHANGE!!', counter, evt); + try { + expect(evt).toBeTypeOf('object'); + switch (counter++) { + case 0: + expect(evt).toMatchObject({ + type: 'add', + key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib\\foo' + }); + reg( + 'add', + 'HKCU\\Software\\winreglib\\foo', + '/v', + 'bar', + '/t', + 'REG_SZ', + '/d', + 'baz' + ); + break; + case 1: + expect(evt).toMatchObject({ + type: 'change', + key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib\\foo' + }); + reg( + 'delete', + 'HKCU\\Software\\winreglib\\foo', + '/f', + '/v', + 'bar' + ); + break; + case 2: + expect(evt).toMatchObject({ + type: 'change', + key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib\\foo' + }); + setTimeout( + () => reg('delete', 'HKCU\\Software\\winreglib\\foo', '/f'), + 500 + ); + break; + case 3: + expect(evt).toMatchObject({ + type: 'delete', + key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib\\foo' + }); + setTimeout( + () => reg('add', 'HKCU\\Software\\winreglib\\foo'), + 500 + ); + break; + case 4: + expect(evt).toMatchObject({ + type: 'add', + key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib\\foo' + }); + resolve(); + break; + } + } catch (e) { + reject(e); + } + }); + setTimeout(() => reg('add', 'HKCU\\Software\\winreglib\\foo'), 500); + }); + } finally { + handle.stop(); + reg('delete', 'HKCU\\Software\\winreglib', '/f'); + } + } + ); + + it.skip( + 'should watch a key whose parent does not exist', + { timeout: 15000 }, + async () => { + reg('delete', 'HKCU\\Software\\winreglib', '/f'); + reg('add', 'HKCU\\Software\\winreglib'); + + const handle = winreglib.watch( + 'HKCU\\SOFTWARE\\winreglib\\foo\\bar\\baz' + ); + + try { + let counter = 0; + await new Promise((resolve, reject) => { + handle.on('change', evt => { + // console.log('CHANGE!!', counter, evt); + try { + expect(evt).toBeTypeOf('object'); + switch (counter++) { + case 0: + expect(evt).toMatchObject({ + type: 'add', + key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib\\foo\\bar\\baz' + }); + reg( + 'add', + 'HKCU\\Software\\winreglib\\foo\\bar\\baz', + '/v', + 'val1', + '/t', + 'REG_SZ', + '/d', + 'hello1' + ); + break; + case 1: + expect(evt).toMatchObject({ + type: 'change', + key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib\\foo\\bar\\baz' + }); + // this next line should not trigger anything + reg( + 'add', + 'HKCU\\Software\\winreglib\\foo', + '/v', + 'val2', + '/t', + 'REG_SZ', + '/d', + 'hello2' + ); + setTimeout(() => { + reg( + 'add', + 'HKCU\\Software\\winreglib\\foo\\bar\\baz', + '/v', + 'val3', + '/t', + 'REG_SZ', + '/d', + 'hello3' + ); + }, 1000); + break; + case 2: + expect(evt).toMatchObject({ + type: 'change', + key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib\\foo\\bar\\baz' + }); + setTimeout(() => { + reg('delete', 'HKCU\\Software\\winreglib', '/f'); + }, 1000); + break; + case 3: + expect(evt).toMatchObject({ + type: 'delete', + key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib\\foo\\bar\\baz' + }); + resolve(); + break; + } + } catch (e) { + reject(e); + } + }); + + setTimeout(() => reg('add', 'HKCU\\Software\\winreglib\\foo'), 500); + setTimeout( + () => reg('add', 'HKCU\\Software\\winreglib\\foo\\bar\\baz\\wiz'), + 2000 + ); + }); + } finally { + handle.stop(); + reg('delete', 'HKCU\\Software\\winreglib', '/f'); + } + } + ); + + it.skip( + 'should watch a key that gets deleted', + { timeout: 15000 }, + async () => { + reg('delete', 'HKCU\\Software\\winreglib', '/f'); + reg('add', 'HKCU\\Software\\winreglib\\foo'); + + const handle = winreglib.watch('HKCU\\SOFTWARE\\winreglib\\foo'); + + try { + let counter = 0; + await new Promise((resolve, reject) => { + handle.on('change', evt => { + // console.log('CHANGE!', evt); + try { + expect(evt).toBeTypeOf('object'); + switch (counter++) { + case 0: + expect(evt).toMatchObject({ + type: 'delete', + key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib\\foo' + }); + resolve(); + break; + } + } catch (e) { + reject(e); + } + }); + setTimeout( + () => reg('delete', 'HKCU\\Software\\winreglib\\foo', '/f'), + 500 + ); + }); + handle.stop(); + } finally { + // also test stop() being called twice + handle.stop(); + reg('delete', 'HKCU\\Software\\winreglib', '/f'); + } + } + ); + + it.skip( + 'should watch a key whose parent gets deleted', + { timeout: 15000 }, + async () => { + reg('delete', 'HKCU\\Software\\winreglib', '/f'); + reg('add', 'HKCU\\Software\\winreglib\\foo\\bar\\baz'); + + const handle = winreglib.watch( + 'HKCU\\SOFTWARE\\winreglib\\foo\\bar\\baz' + ); + + try { + let counter = 0; + await new Promise((resolve, reject) => { + handle.on('change', evt => { + // console.log('CHANGE!', evt); + try { + expect(evt).toBeTypeOf('object'); + switch (counter++) { + case 0: + expect(evt).toMatchObject({ + type: 'delete', + key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib\\foo\\bar\\baz' + }); + resolve(); + break; + } + } catch (e) { + reject(e); + } + }); + setTimeout( + () => reg('delete', 'HKCU\\Software\\winreglib\\foo', '/f'), + 500 + ); + }); + handle.stop(); + } finally { + // also test stop() being called twice + handle.stop(); + reg('delete', 'HKCU\\Software\\winreglib', '/f'); + } + } + ); + + it.skip('should survive the gauntlet', { timeout: 15000 }, async () => { + reg('delete', 'HKCU\\Software\\winreglib', '/f'); + reg('add', 'HKCU\\Software\\winreglib'); + + const winreglibHandle = winreglib.watch('HKCU\\SOFTWARE\\winreglib'); + const fooHandle = winreglib.watch('HKCU\\SOFTWARE\\winreglib\\foo'); + const barHandle = winreglib.watch('HKCU\\SOFTWARE\\winreglib\\foo\\bar'); + const bazHandle = winreglib.watch( + 'HKCU\\SOFTWARE\\winreglib\\foo\\bar\\baz' + ); + + try { + let counter = 0; + await new Promise((resolve, reject) => { + const fn = evt => { + // console.log('CHANGE!', evt); + try { + expect(evt).toBeTypeOf('object'); + switch (counter++) { + case 0: + expect(evt).toMatchObject({ + type: 'change', + key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib' + }); + break; + case 1: + expect(evt).toMatchObject({ + type: 'add', + key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib\\foo' + }); + break; + case 2: + expect(evt).toMatchObject({ + type: 'add', + key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib\\foo\\bar' + }); + reg('delete', 'HKCU\\Software\\winreglib\\foo\\bar', '/f'); + break; + case 3: + expect(evt).toMatchObject({ + type: 'change', + key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib\\foo' + }); + break; + case 4: + expect(evt).toMatchObject({ + type: 'delete', + key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib\\foo\\bar' + }); + reg( + 'add', + 'HKCU\\Software\\winreglib', + '/v', + 'foo', + '/t', + 'REG_SZ', + '/d', + 'bar' + ); + break; + case 5: + expect(evt).toMatchObject({ + type: 'change', + key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib' + }); + reg('add', 'HKCU\\Software\\winreglib\\foo\\bar\\wiz'); + break; + case 6: + expect(evt).toMatchObject({ + type: 'change', + key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib\\foo' + }); + break; + case 7: + expect(evt).toMatchObject({ + type: 'add', + key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib\\foo\\bar' + }); + reg('add', 'HKCU\\Software\\winreglib\\foo\\bar\\baz'); + break; + case 8: + expect(evt).toMatchObject({ + type: 'change', + key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib\\foo\\bar' + }); + break; + case 9: + expect(evt).toMatchObject({ + type: 'add', + key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib\\foo\\bar\\baz' + }); + reg( + 'add', + 'HKCU\\Software\\winreglib\\foo\\bar\\baz', + '/v', + 'foo', + '/t', + 'REG_SZ', + '/d', + 'bar' + ); + break; + case 10: + expect(evt).toMatchObject({ + type: 'change', + key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib\\foo\\bar\\baz' + }); + reg('delete', 'HKCU\\Software\\winreglib', '/f', '/v', 'foo'); + break; + case 11: + expect(evt).toMatchObject({ + type: 'change', + key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib' + }); + reg('delete', 'HKCU\\Software\\winreglib\\foo', '/f'); + break; + case 12: + expect(evt).toMatchObject({ + type: 'delete', + key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib\\foo\\bar\\baz' + }); + break; + case 13: + expect(evt).toMatchObject({ + type: 'delete', + key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib\\foo\\bar' + }); + break; + case 14: + expect(evt).toMatchObject({ + type: 'delete', + key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib\\foo' + }); + break; + case 15: + expect(evt).toMatchObject({ + type: 'change', + key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib' + }); + resolve(); + break; + } + } catch (e) { + reject(e); + } + }; + winreglibHandle.on('change', fn); + fooHandle.on('change', fn); + barHandle.on('change', fn); + bazHandle.on('change', fn); + setTimeout( + () => reg('add', 'HKCU\\Software\\winreglib\\foo\\bar'), + 500 + ); + }); + } finally { + winreglibHandle.stop(); + fooHandle.stop(); + barHandle.stop(); + bazHandle.stop(); + reg('delete', 'HKCU\\Software\\winreglib', '/f'); + } + }); +}); diff --git a/test/wingreglib.test.ts b/test/wingreglib.test.ts deleted file mode 100644 index 4abcd30..0000000 --- a/test/wingreglib.test.ts +++ /dev/null @@ -1,725 +0,0 @@ -import fs from 'node:fs'; -import { describe, expect, it } from 'vitest'; -import winreglib from '../src/index.js'; -const { spawnSync } = require('node:child_process'); -import snooplogg from 'snooplogg'; - -const { log } = snooplogg('test:winreglib'); - -const reg = (...args) => { - log(`Executing: reg ${args.join(' ')}`); - spawnSync('reg', args, { stdio: 'ignore' }); -}; - -describe('get()', () => { - it('should error if key is not specified', () => { - try { - winreglib.get(); - } catch (e) { - expect(e.message).to.equal('Expected key to be a non-empty string'); - return; - } - throw new Error('Expected error'); - }); - - // it('should error if value name is not specified', () => { - // try { - // winreglib.get('HKLM\\software'); - // } catch (e) { - // expect(e.message).to.equal('Expected value name to be a non-empty string'); - // return; - // } - // throw new Error('Expected error'); - // }); - - // it('should error if key does not contain a subkey', () => { - // try { - // winreglib.get('foo', 'bar'); - // } catch (e) { - // expect(e.message).to.equal('Expected key to contain both a root and subkey'); - // return; - // } - // throw new Error('Expected error'); - // }); - - // it('should error if key is not valid', () => { - // try { - // winreglib.get('foo\\bar', 'baz'); - // } catch (e) { - // expect(e.message).to.equal('Invalid registry root key "foo"'); - // return; - // } - // throw new Error('Expected error'); - // }); - - // it('should error if key is not found', () => { - // try { - // winreglib.get('HKLM\\foo', 'bar'); - // } catch (e) { - // expect(e.message).to.equal('Registry key or value not found'); - // return; - // } - // throw new Error('Expected error'); - // }); - - // it('should error if value is not found', () => { - // try { - // winreglib.get('HKLM\\SOFTWARE', 'bar'); - // } catch (e) { - // expect(e.message).to.equal('Registry key or value not found'); - // return; - // } - // throw new Error('Expected error'); - // }); - - // it('should get a string value', () => { - // const value = winreglib.get('HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion', 'ProgramFilesDir'); - // expect(value).to.be.a('string'); - // expect(value).to.not.equal(''); - // expect(fs.existsSync(value)).to.be.true; - // }); - - // it('should get an expanded string value', () => { - // const value = winreglib.get('HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion', 'ProgramFilesPath'); - // expect(value).to.be.a('string'); - // expect(value).to.not.equal(''); - // expect(fs.existsSync(value)).to.be.true; - // }); - - // it('should get multi-string value', () => { - // const value = winreglib.get('HKLM\\HARDWARE\\DESCRIPTION\\System', 'SystemBiosVersion'); - // expect(value).to.be.an('array'); - // expect(value).to.have.lengthOf.above(0); - // for (const v of value) { - // expect(v).to.be.a('string'); - // expect(v).to.not.equal(''); - // } - // }); - - // it('should get an 32-bit integer value', () => { - // const value = winreglib.get('HKLM\\HARDWARE\\DESCRIPTION\\System', 'Capabilities'); - // expect(value).to.be.a('number'); - // expect(value).to.be.at.least(0); - // }); - - // it('should get an 64-bit integer value', () => { - // const value = winreglib.get('HKLM\\Software\\Microsoft\\Windows\\CurrentVersion\\Diagnostics\\DiagTrack', 'TriggerCount'); - // expect(value).to.be.a('number'); - // expect(value).to.be.at.least(0); - // }); - - // it('should get a binary value', () => { - // const value = winreglib.get('HKLM\\HARDWARE\\DESCRIPTION\\System', 'Component Information'); - // expect(value).to.be.an.instanceof(Buffer); - // expect(value.length).to.be.above(0); - // }); - - // it('should get a full resource descriptor value', () => { - // const value = winreglib.get('HKLM\\HARDWARE\\DESCRIPTION\\System', 'Configuration Data'); - // expect(value).to.be.an.instanceof(Buffer); - // expect(value.length).to.be.above(0); - // }); - - // it('should get a resource list value', () => { - // const value = winreglib.get('HKLM\\HARDWARE\\RESOURCEMAP\\System Resources\\Loader Reserved', '.Raw'); - // expect(value).to.be.an.instanceof(Buffer); - // expect(value.length).to.be.above(0); - // }); - - // it('should get none value', function () { - // this.timeout(15000); - // this.slow(14000); - - // try { - // reg('delete', 'HKCU\\Software\\winreglib', '/f'); - // reg('add', 'HKCU\\Software\\winreglib'); - // reg('add', 'HKCU\\Software\\winreglib', '/v', 'foo', '/t', 'REG_NONE'); - - // const value = winreglib.get('HKCU\\Software\\winreglib', 'foo'); - // expect(value).to.be.null; - // } finally { - // reg('delete', 'HKCU\\Software\\winreglib', '/f'); - // } - // }); - // }); - - // describe('list()', () => { - // it('should error if key is not specified', () => { - // try { - // winreglib.list(); - // } catch (e) { - // expect(e.message).to.equal('Expected key to be a non-empty string'); - // return; - // } - // throw new Error('Expected error'); - // }); - - // it('should error if key does not contain a subkey', () => { - // try { - // winreglib.list('foo'); - // } catch (e) { - // expect(e.message).to.equal('Expected key to contain both a root and subkey'); - // return; - // } - // throw new Error('Expected error'); - // }); - - // it('should error if key is not valid', () => { - // try { - // winreglib.list('foo\\bar'); - // } catch (e) { - // expect(e.message).to.equal('Invalid registry root key "foo"'); - // return; - // } - // throw new Error('Expected error'); - // }); - - // it('should error if key is not found', () => { - // try { - // winreglib.list('HKLM\\foo'); - // } catch (e) { - // expect(e.message).to.equal('Registry key or value not found'); - // return; - // } - // throw new Error('Expected error'); - // }); - - // it('should retrieve subkeys and values', () => { - // const result = winreglib.list('HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion'); - - // expect(result).to.be.an('object'); - // expect(result).to.have.keys('resolvedRoot', 'key', 'subkeys', 'values'); - - // expect(result.resolvedRoot).to.equal('HKEY_LOCAL_MACHINE'); - // expect(result.key).to.equal('HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion'); - - // expect(result.subkeys).to.be.an('array'); - // for (const key of result.subkeys) { - // expect(key).to.be.a('string'); - // expect(key).to.not.equal(''); - // } - - // expect(result.values).to.be.an('array'); - // for (const value of result.values) { - // expect(value).to.be.a('string'); - // expect(value).to.not.equal(''); - // } - // }); - // }); - - // describe('watch()', () => { - // it('should error if key is not specified', () => { - // try { - // winreglib.watch(); - // } catch (e) { - // expect(e.message).to.equal('Expected key to be a non-empty string'); - // return; - // } - // throw new Error('Expected error'); - // }); - - // it('should error if key does not contain a subkey', () => { - // try { - // winreglib.watch('HKLM'); - // } catch (e) { - // expect(e.message).to.equal('Expected key to contain both a root and subkey'); - // return; - // } - // throw new Error('Expected error'); - // }); - - // it('should error if root key is not valid', () => { - // try { - // winreglib.watch('foo\\bar'); - // } catch (e) { - // expect(e.message).to.equal('Invalid registry root key "foo"'); - // return; - // } - // throw new Error('Expected error'); - // }); - - // it('should watch existing key for new subkey', async function () { - // this.timeout(15000); - // this.slow(14000); - - // reg('delete', 'HKCU\\Software\\winreglib', '/f'); - // reg('add', 'HKCU\\Software\\winreglib'); - - // const handle = winreglib.watch('HKCU\\SOFTWARE\\winreglib'); - - // try { - // let counter = 0; - - // await new Promise((resolve, reject) => { - // handle.on('change', evt => { - // // console.log('CHANGE!', evt); - // try { - // expect(evt).to.be.an('object'); - // switch (counter++) { - // case 0: - // expect(evt).to.deep.equal({ - // type: 'change', - // key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib' - // }); - // reg('delete', 'HKCU\\Software\\winreglib\\foo', '/f'); - // break; - - // case 1: - // expect(evt).to.deep.equal({ - // type: 'change', - // key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib' - // }); - // resolve(); - // break; - // } - // } catch (e) { - // reject(e); - // } - // }); - - // setTimeout(() => reg('add', 'HKCU\\Software\\winreglib\\foo'), 500); - // }); - // handle.stop(); - // } finally { - // // also test stop() being called twice - // handle.stop(); - // reg('delete', 'HKCU\\Software\\winreglib', '/f'); - // } - // }); - - // it('should watch existing key for value change', async function () { - // this.timeout(15000); - // this.slow(14000); - - // reg('delete', 'HKCU\\Software\\winreglib', '/f'); - // reg('add', 'HKCU\\Software\\winreglib'); - - // const handle = winreglib.watch('HKCU\\SOFTWARE\\winreglib'); - - // try { - // let counter = 0; - - // await new Promise((resolve, reject) => { - // handle.on('change', evt => { - // try { - // expect(evt).to.be.an('object'); - // switch (counter++) { - // case 0: - // expect(evt).to.deep.equal({ - // type: 'change', - // key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib' - // }); - // reg('delete', 'HKCU\\Software\\winreglib', '/f', '/v', 'foo'); - // break; - - // case 1: - // expect(evt).to.deep.equal({ - // type: 'change', - // key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib' - // }); - // resolve(); - // break; - // } - // } catch (e) { - // reject(e); - // } - // }); - - // setTimeout(() => reg('add', 'HKCU\\Software\\winreglib', '/v', 'foo', '/t', 'REG_SZ', '/d', 'bar'), 500); - // }); - // } finally { - // handle.stop(); - // reg('delete', 'HKCU\\Software\\winreglib', '/f'); - // } - // }); - - // it('should watch a key that does not exist', async function () { - // this.timeout(15000); - // this.slow(14000); - - // reg('delete', 'HKCU\\Software\\winreglib', '/f'); - // reg('add', 'HKCU\\Software\\winreglib'); - - // const handle = winreglib.watch('HKCU\\SOFTWARE\\winreglib\\foo'); - - // try { - // let counter = 0; - - // await new Promise((resolve, reject) => { - // handle.on('change', evt => { - // // console.log('CHANGE!!', counter, evt); - // try { - // expect(evt).to.be.an('object'); - // switch (counter++) { - // case 0: - // expect(evt).to.deep.equal({ - // type: 'add', - // key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib\\foo' - // }); - // reg('add', 'HKCU\\Software\\winreglib\\foo', '/v', 'bar', '/t', 'REG_SZ', '/d', 'baz'); - // break; - - // case 1: - // expect(evt).to.deep.equal({ - // type: 'change', - // key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib\\foo' - // }); - - // reg('delete', 'HKCU\\Software\\winreglib\\foo', '/f', '/v', 'bar'); - // break; - - // case 2: - // expect(evt).to.deep.equal({ - // type: 'change', - // key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib\\foo' - // }); - - // setTimeout(() => reg('delete', 'HKCU\\Software\\winreglib\\foo', '/f'), 500); - // break; - - // case 3: - // expect(evt).to.deep.equal({ - // type: 'delete', - // key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib\\foo' - // }); - // setTimeout(() => reg('add', 'HKCU\\Software\\winreglib\\foo'), 500); - // break; - - // case 4: - // expect(evt).to.deep.equal({ - // type: 'add', - // key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib\\foo' - // }); - // resolve(); - // break; - // } - // } catch (e) { - // reject(e); - // } - // }); - - // setTimeout(() => reg('add', 'HKCU\\Software\\winreglib\\foo'), 500); - // }); - // } finally { - // handle.stop(); - // reg('delete', 'HKCU\\Software\\winreglib', '/f'); - // } - // }); - - // it('should watch a key whose parent does not exist', async function () { - // this.timeout(15000); - // this.slow(14000); - - // reg('delete', 'HKCU\\Software\\winreglib', '/f'); - // reg('add', 'HKCU\\Software\\winreglib'); - - // const handle = winreglib.watch('HKCU\\SOFTWARE\\winreglib\\foo\\bar\\baz'); - - // try { - // let counter = 0; - - // await new Promise((resolve, reject) => { - // handle.on('change', evt => { - // // console.log('CHANGE!!', counter, evt); - // try { - // expect(evt).to.be.an('object'); - // switch (counter++) { - // case 0: - // expect(evt).to.deep.equal({ - // type: 'add', - // key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib\\foo\\bar\\baz' - // }); - // reg('add', 'HKCU\\Software\\winreglib\\foo\\bar\\baz', '/v', 'val1', '/t', 'REG_SZ', '/d', 'hello1'); - // break; - - // case 1: - // expect(evt).to.deep.equal({ - // type: 'change', - // key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib\\foo\\bar\\baz' - // }); - - // // this next line should not trigger anything - // reg('add', 'HKCU\\Software\\winreglib\\foo', '/v', 'val2', '/t', 'REG_SZ', '/d', 'hello2'); - - // setTimeout(() => { - // reg('add', 'HKCU\\Software\\winreglib\\foo\\bar\\baz', '/v', 'val3', '/t', 'REG_SZ', '/d', 'hello3'); - // }, 1000); - // break; - - // case 2: - // expect(evt).to.deep.equal({ - // type: 'change', - // key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib\\foo\\bar\\baz' - // }); - - // setTimeout(() => { - // reg('delete', 'HKCU\\Software\\winreglib', '/f'); - // }, 1000); - // break; - - // case 3: - // expect(evt).to.deep.equal({ - // type: 'delete', - // key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib\\foo\\bar\\baz' - // }); - // resolve(); - // break; - // } - // } catch (e) { - // reject(e); - // } - // }); - - // setTimeout(() => reg('add', 'HKCU\\Software\\winreglib\\foo'), 500); - // setTimeout(() => reg('add', 'HKCU\\Software\\winreglib\\foo\\bar\\baz\\wiz'), 2000); - // }); - // } finally { - // handle.stop(); - // reg('delete', 'HKCU\\Software\\winreglib', '/f'); - // } - // }); - - // it('should watch a key that gets deleted', async function () { - // this.timeout(15000); - // this.slow(14000); - - // reg('delete', 'HKCU\\Software\\winreglib', '/f'); - // reg('add', 'HKCU\\Software\\winreglib\\foo'); - - // const handle = winreglib.watch('HKCU\\SOFTWARE\\winreglib\\foo'); - - // try { - // let counter = 0; - - // await new Promise((resolve, reject) => { - // handle.on('change', evt => { - // // console.log('CHANGE!', evt); - // try { - // expect(evt).to.be.an('object'); - // switch (counter++) { - // case 0: - // expect(evt).to.deep.equal({ - // type: 'delete', - // key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib\\foo' - // }); - // resolve(); - // break; - // } - // } catch (e) { - // reject(e); - // } - // }); - - // setTimeout(() => reg('delete', 'HKCU\\Software\\winreglib\\foo', '/f'), 500); - // }); - // handle.stop(); - // } finally { - // // also test stop() being called twice - // handle.stop(); - // reg('delete', 'HKCU\\Software\\winreglib', '/f'); - // } - // }); - - // it('should watch a key whose parent gets deleted', async function () { - // this.timeout(15000); - // this.slow(14000); - - // reg('delete', 'HKCU\\Software\\winreglib', '/f'); - // reg('add', 'HKCU\\Software\\winreglib\\foo\\bar\\baz'); - - // const handle = winreglib.watch('HKCU\\SOFTWARE\\winreglib\\foo\\bar\\baz'); - - // try { - // let counter = 0; - - // await new Promise((resolve, reject) => { - // handle.on('change', evt => { - // // console.log('CHANGE!', evt); - // try { - // expect(evt).to.be.an('object'); - // switch (counter++) { - // case 0: - // expect(evt).to.deep.equal({ - // type: 'delete', - // key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib\\foo\\bar\\baz' - // }); - // resolve(); - // break; - // } - // } catch (e) { - // reject(e); - // } - // }); - - // setTimeout(() => reg('delete', 'HKCU\\Software\\winreglib\\foo', '/f'), 500); - // }); - // handle.stop(); - // } finally { - // // also test stop() being called twice - // handle.stop(); - // reg('delete', 'HKCU\\Software\\winreglib', '/f'); - // } - // }); - - // it('should survive the gauntlet', async function () { - // this.timeout(15000); - // this.slow(14000); - - // reg('delete', 'HKCU\\Software\\winreglib', '/f'); - // reg('add', 'HKCU\\Software\\winreglib'); - - // const winreglibHandle = winreglib.watch('HKCU\\SOFTWARE\\winreglib'); - // const fooHandle = winreglib.watch('HKCU\\SOFTWARE\\winreglib\\foo'); - // const barHandle = winreglib.watch('HKCU\\SOFTWARE\\winreglib\\foo\\bar'); - // const bazHandle = winreglib.watch('HKCU\\SOFTWARE\\winreglib\\foo\\bar\\baz'); - - // try { - // let counter = 0; - - // await new Promise((resolve, reject) => { - // const fn = evt => { - // // console.log('CHANGE!', evt); - // try { - // expect(evt).to.be.an('object'); - // switch (counter++) { - // case 0: - // expect(evt).to.deep.equal({ - // type: 'change', - // key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib' - // }); - // break; - - // case 1: - // expect(evt).to.deep.equal({ - // type: 'add', - // key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib\\foo' - // }); - // break; - - // case 2: - // expect(evt).to.deep.equal({ - // type: 'add', - // key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib\\foo\\bar' - // }); - // reg('delete', 'HKCU\\Software\\winreglib\\foo\\bar', '/f'); - // break; - - // case 3: - // expect(evt).to.deep.equal({ - // type: 'change', - // key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib\\foo' - // }); - // break; - - // case 4: - // expect(evt).to.deep.equal({ - // type: 'delete', - // key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib\\foo\\bar' - // }); - // reg('add', 'HKCU\\Software\\winreglib', '/v', 'foo', '/t', 'REG_SZ', '/d', 'bar'); - // break; - - // case 5: - // expect(evt).to.deep.equal({ - // type: 'change', - // key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib' - // }); - // reg('add', 'HKCU\\Software\\winreglib\\foo\\bar\\wiz'); - // break; - - // case 6: - // expect(evt).to.deep.equal({ - // type: 'change', - // key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib\\foo' - // }); - // break; - - // case 7: - // expect(evt).to.deep.equal({ - // type: 'add', - // key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib\\foo\\bar' - // }); - // reg('add', 'HKCU\\Software\\winreglib\\foo\\bar\\baz'); - // break; - - // case 8: - // expect(evt).to.deep.equal({ - // type: 'change', - // key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib\\foo\\bar' - // }); - // break; - - // case 9: - // expect(evt).to.deep.equal({ - // type: 'add', - // key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib\\foo\\bar\\baz' - // }); - // reg('add', 'HKCU\\Software\\winreglib\\foo\\bar\\baz', '/v', 'foo', '/t', 'REG_SZ', '/d', 'bar'); - // break; - - // case 10: - // expect(evt).to.deep.equal({ - // type: 'change', - // key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib\\foo\\bar\\baz' - // }); - // reg('delete', 'HKCU\\Software\\winreglib', '/f', '/v', 'foo'); - // break; - - // case 11: - // expect(evt).to.deep.equal({ - // type: 'change', - // key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib' - // }); - // reg('delete', 'HKCU\\Software\\winreglib\\foo', '/f'); - // break; - - // case 12: - // expect(evt).to.deep.equal({ - // type: 'delete', - // key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib\\foo\\bar\\baz' - // }); - // break; - - // case 13: - // expect(evt).to.deep.equal({ - // type: 'delete', - // key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib\\foo\\bar' - // }); - // break; - - // case 14: - // expect(evt).to.deep.equal({ - // type: 'delete', - // key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib\\foo' - // }); - // break; - - // case 15: - // expect(evt).to.deep.equal({ - // type: 'change', - // key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib' - // }); - // resolve(); - // break; - // } - // } catch (e) { - // reject(e); - // } - // }; - - // winreglibHandle.on('change', fn); - // fooHandle.on('change', fn); - // barHandle.on('change', fn); - // bazHandle.on('change', fn); - - // setTimeout(() => reg('add', 'HKCU\\Software\\winreglib\\foo\\bar'), 500); - // }); - // } finally { - // winreglibHandle.stop(); - // fooHandle.stop(); - // barHandle.stop(); - // bazHandle.stop(); - // reg('delete', 'HKCU\\Software\\winreglib', '/f'); - // } - // }); -}); diff --git a/vitest.config.ts b/vitest.config.ts index 0e7f05c..bfccd9a 100644 --- a/vitest.config.ts +++ b/vitest.config.ts @@ -9,6 +9,11 @@ export default defineConfig({ environment: 'node', globals: false, include: ['test/**/*.test.ts'], + poolOptions: { + forks: { + singleFork: true + } + }, watch: false } }); From 14f99a0e5f56720e8ad2500a59a581386427474e Mon Sep 17 00:00:00 2001 From: Chris Barber Date: Sun, 14 Jul 2024 17:50:50 -0500 Subject: [PATCH 07/27] Fix seg fault --- package.json | 12 +- pnpm-lock.yaml | 252 +++++++++++++++------------------- src/index.ts | 2 +- src/watchman.cpp | 88 +++++++++--- src/winreglib.cpp | 2 + test/wingreglib-get.test.ts | 2 +- test/wingreglib-list.test.ts | 2 +- test/wingreglib-watch.test.ts | 31 +++-- 8 files changed, 209 insertions(+), 182 deletions(-) diff --git a/package.json b/package.json index d956159..d8f55ec 100644 --- a/package.json +++ b/package.json @@ -36,12 +36,12 @@ "prebuild-x64": "prebuildify --napi --strip --platform=win32 --arch x64", "rebuild:local": "node-gyp -j 20 rebuild", "rebuild:local-debug": "node-gyp -j 20 rebuild --debug", - "test": "vitest --pool=forks", + "test": "vitest --allowOnly --pool=forks", "type-check": "tsc --noEmit" }, "dependencies": { "napi-macros": "2.2.2", - "node-gyp": "10.1.0", + "node-gyp": "10.2.0", "node-gyp-build": "4.8.1", "snooplogg": "6.0.0-rc.1" }, @@ -49,17 +49,17 @@ "@biomejs/biome": "1.8.3", "@rollup/plugin-typescript": "11.1.6", "@types/node": "20.14.10", - "@vitest/coverage-v8": "2.0.1", + "@vitest/coverage-v8": "2.0.2", "esbuild": "0.23.0", - "lefthook": "1.7.1", + "lefthook": "1.7.2", "prebuildify": "6.0.1", - "rimraf": "6.0.0", + "rimraf": "6.0.1", "rollup": "4.18.1", "rollup-plugin-dts": "6.1.1", "rollup-plugin-esbuild": "6.1.1", "tslib": "2.6.3", "typescript": "5.5.3", - "vitest": "2.0.1" + "vitest": "2.0.2" }, "homepage": "https://github.com/tidev/winreglib", "bugs": "https://github.com/tidev/winreglib/issues", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 382618f..b4e3f8a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -17,8 +17,8 @@ importers: specifier: 2.2.2 version: 2.2.2 node-gyp: - specifier: 10.1.0 - version: 10.1.0 + specifier: 10.2.0 + version: 10.2.0 node-gyp-build: specifier: 4.8.1 version: 4.8.1(patch_hash=4v3havyznpg2abqwiszfjnuita) @@ -36,20 +36,20 @@ importers: specifier: 20.14.10 version: 20.14.10 '@vitest/coverage-v8': - specifier: 2.0.1 - version: 2.0.1(vitest@2.0.1(@types/node@20.14.10)) + specifier: 2.0.2 + version: 2.0.2(vitest@2.0.2(@types/node@20.14.10)) esbuild: specifier: 0.23.0 version: 0.23.0 lefthook: - specifier: 1.7.1 - version: 1.7.1 + specifier: 1.7.2 + version: 1.7.2 prebuildify: specifier: 6.0.1 version: 6.0.1 rimraf: - specifier: 6.0.0 - version: 6.0.0 + specifier: 6.0.1 + version: 6.0.1 rollup: specifier: 4.18.1 version: 4.18.1 @@ -66,8 +66,8 @@ importers: specifier: 5.5.3 version: 5.5.3 vitest: - specifier: 2.0.1 - version: 2.0.1(@types/node@20.14.10) + specifier: 2.0.2 + version: 2.0.2(@types/node@20.14.10) packages: @@ -446,10 +446,6 @@ packages: resolution: {integrity: sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==} engines: {node: '>=8'} - '@jest/schemas@29.6.3': - resolution: {integrity: sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - '@jridgewell/gen-mapping@0.3.5': resolution: {integrity: sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==} engines: {node: '>=6.0.0'} @@ -582,34 +578,34 @@ packages: cpu: [x64] os: [win32] - '@sinclair/typebox@0.27.8': - resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==} - '@types/estree@1.0.5': resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==} '@types/node@20.14.10': resolution: {integrity: sha512-MdiXf+nDuMvY0gJKxyfZ7/6UFsETO7mGKF54MVD/ekJS6HdFtpZFBgrh6Pseu64XTb2MLyFPlbW6hj8HYRQNOQ==} - '@vitest/coverage-v8@2.0.1': - resolution: {integrity: sha512-ACcSlJtWlravv0QyJSCO9rvm06msj6x0HooXouB0NXKG6PGxUN5VX4X8QEATfTMGsJlZLqWvq0dEY9W1V0rcSw==} + '@vitest/coverage-v8@2.0.2': + resolution: {integrity: sha512-iA8eb4PMid3bMc++gfQSTvYE1QL//fC8pz+rKsTUDBFjdDiy/gH45hvpqyDu5K7FHhvgG0GNNCJzTMMSFKhoxg==} peerDependencies: - vitest: 2.0.1 + vitest: 2.0.2 - '@vitest/expect@2.0.1': - resolution: {integrity: sha512-yw70WL3ZwzbI2O3MOXYP2Shf4vqVkS3q5FckLJ6lhT9VMMtDyWdofD53COZcoeuHwsBymdOZp99r5bOr5g+oeA==} + '@vitest/expect@2.0.2': + resolution: {integrity: sha512-nKAvxBYqcDugYZ4nJvnm5OR8eDJdgWjk4XM9owQKUjzW70q0icGV2HVnQOyYsp906xJaBDUXw0+9EHw2T8e0mQ==} - '@vitest/runner@2.0.1': - resolution: {integrity: sha512-XfcSXOGGxgR2dQ466ZYqf0ZtDLLDx9mZeQcKjQDLQ9y6Cmk2Wl7wxMuhiYK4Fo1VxCtLcFEGW2XpcfMuiD1Maw==} + '@vitest/pretty-format@2.0.2': + resolution: {integrity: sha512-SBCyOXfGVvddRd9r2PwoVR0fonQjh9BMIcBMlSzbcNwFfGr6ZhOhvBzurjvi2F4ryut2HcqiFhNeDVGwru8tLg==} - '@vitest/snapshot@2.0.1': - resolution: {integrity: sha512-rst79a4Q+J5vrvHRapdfK4BdqpMH0eF58jVY1vYeBo/1be+nkyenGI5SCSohmjf6MkCkI20/yo5oG+0R8qrAnA==} + '@vitest/runner@2.0.2': + resolution: {integrity: sha512-OCh437Vi8Wdbif1e0OvQcbfM3sW4s2lpmOjAE7qfLrpzJX2M7J1IQlNvEcb/fu6kaIB9n9n35wS0G2Q3en5kHg==} - '@vitest/spy@2.0.1': - resolution: {integrity: sha512-NLkdxbSefAtJN56GtCNcB4GiHFb5i9q1uh4V229lrlTZt2fnwsTyjLuWIli1xwK2fQspJJmHXHyWx0Of3KTXWA==} + '@vitest/snapshot@2.0.2': + resolution: {integrity: sha512-Yc2ewhhZhx+0f9cSUdfzPRcsM6PhIb+S43wxE7OG0kTxqgqzo8tHkXFuFlndXeDMp09G3sY/X5OAo/RfYydf1g==} - '@vitest/utils@2.0.1': - resolution: {integrity: sha512-STH+2fHZxlveh1mpU4tKzNgRk7RZJyr6kFGJYCI5vocdfqfPsQrgVC6k7dBWHfin5QNB4TLvRS0Ckly3Dt1uWw==} + '@vitest/spy@2.0.2': + resolution: {integrity: sha512-MgwJ4AZtCgqyp2d7WcQVE8aNG5vQ9zu9qMPYQHjsld/QVsrvg78beNrXdO4HYkP0lDahCO3P4F27aagIag+SGQ==} + + '@vitest/utils@2.0.2': + resolution: {integrity: sha512-pxCY1v7kmOCWYWjzc0zfjGTA3Wmn8PKnlPvSrsA643P1NHl1fOyXj2Q9SaNlrlFE+ivCsxM80Ov3AR82RmHCWQ==} abbrev@2.0.0: resolution: {integrity: sha512-6/mh1E2u2YgEsCHdY0Yx5oW+61gZU+1vXaoiHHrpKeuRNNgFvS+/jrwHiQhB5apAf5oB7UB7E19ol2R2LKH8hQ==} @@ -639,10 +635,6 @@ packages: resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} engines: {node: '>=8'} - ansi-styles@5.2.0: - resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==} - engines: {node: '>=10'} - ansi-styles@6.2.1: resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} engines: {node: '>=12'} @@ -727,10 +719,6 @@ packages: resolution: {integrity: sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==} engines: {node: '>=6'} - diff-sequences@29.6.3: - resolution: {integrity: sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - eastasianwidth@0.2.0: resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} @@ -936,56 +924,56 @@ packages: jsbn@1.1.0: resolution: {integrity: sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==} - lefthook-darwin-arm64@1.7.1: - resolution: {integrity: sha512-WNM92Ix2rKmDKXzjlkVGCdzSkzzj3Z9D7yKi22KeOZ1iCXG1EtXEWmXO5M2g28FNb4cZI0r2DACNH5hz8JsfgA==} + lefthook-darwin-arm64@1.7.2: + resolution: {integrity: sha512-E3Ouk04/yeD8IBLGJkyzL0NMYIrjADQvaDbf4yNSq6HWGnUC0R2KpYxrZno2yahZnvQ0vYTDta7Egw6cqcYGlQ==} cpu: [arm64] os: [darwin] hasBin: true - lefthook-darwin-x64@1.7.1: - resolution: {integrity: sha512-SDPEciuP+eNzuKN8kx1x0dRzFElpO65on5q0raKgTbTvSOyVd3c7sMLGluz6OSM5qqEWEdEeA8QYKpdA56uXEw==} + lefthook-darwin-x64@1.7.2: + resolution: {integrity: sha512-Am6ZNmjItQSqKbK8/spFIj5GDWNHJ47PM0vpT1PnBHrgWanjz0iLw6adwpMu8u7+CkZlHjp08lbvjBPGHIu3dg==} cpu: [x64] os: [darwin] hasBin: true - lefthook-freebsd-arm64@1.7.1: - resolution: {integrity: sha512-Ym2hhv6w7RWva3jfjtBOYck+GiaCx1JpnsOCf9tDYKFiV6ve/DoLrGQ+uI0UOqtiHN/bJzt5BrNXygfAubXaEg==} + lefthook-freebsd-arm64@1.7.2: + resolution: {integrity: sha512-o1LBgHhwnUOLs9iVbi1GhvXMQlzYSKnyFcc061iADxHMJk1xWMD6RUyyohmLbfEU0gTWxkRfkdAFvbvwNqQiww==} cpu: [arm64] os: [freebsd] hasBin: true - lefthook-freebsd-x64@1.7.1: - resolution: {integrity: sha512-u9WYd+LDJr1A+VQV6lTe1a0yG0Ew9Wgeb9Ym9IKr9eLblrt6JNvW1x9u0e9OFteLwnqBCCT8omBY+NARcvqVvg==} + lefthook-freebsd-x64@1.7.2: + resolution: {integrity: sha512-vxB3FeeFYDfk4vAahaZdGJ7gbViGOkOyL5JRBDWlFjUfZJLGwVauf6GhtysdO1dgxs9K3ECdEtXgW+uOB872rQ==} cpu: [x64] os: [freebsd] hasBin: true - lefthook-linux-arm64@1.7.1: - resolution: {integrity: sha512-Sgc+vHNnAbiJ5b1yMJsFn/rQ6eVQ0KLzuL0x0KJqFZvmffFenVmqABrFHKNDzhj8//KUbHdgCgLzqQAkAbCNcg==} + lefthook-linux-arm64@1.7.2: + resolution: {integrity: sha512-4dbVj5Jjy12flAyOcVWvWQ6gJoQ6X7HJ3qfsrM8/GIfLQBlkw+YRcLuWHUI3H9qsQFpkpYZsLcmUXoVM77z5mw==} cpu: [arm64] os: [linux] hasBin: true - lefthook-linux-x64@1.7.1: - resolution: {integrity: sha512-UDIM6Cf0aHrfvIxeVz05M7g+omLdyTQpmB2BqkeANpd/5+1LqRMOBOdtW+y3X47NKYL++iFh2EtIhlIqVBj6Kw==} + lefthook-linux-x64@1.7.2: + resolution: {integrity: sha512-lT0IRp1pGtbua8IWVeIVCSAxKex9fOyAexHaEmBZytfqr/94lpjzWWEQdLFQAlpZthuyCkuaJp5kLgMj6/IySQ==} cpu: [x64] os: [linux] hasBin: true - lefthook-windows-arm64@1.7.1: - resolution: {integrity: sha512-cz3vhIdmORA25YF4ZnPjDQwi/KQd8cB89q7jHEQ9sv+bpSOTXiauMOM9jvXbnvGrmFaR1qbLRTYpKQs6oyGdsA==} + lefthook-windows-arm64@1.7.2: + resolution: {integrity: sha512-DxWLmcNI3NICd4rFqTPgXf+G/97ztl+ONvYuNE/ELAxVp338xAUFvzZCQvDZDzeTLrT1C4hZZ4zDvEhnOOECXg==} cpu: [arm64] os: [win32] hasBin: true - lefthook-windows-x64@1.7.1: - resolution: {integrity: sha512-Fa9HEkJczbD1zu6wBKP2rR738uRei5sb76d/DzgqW09ZBTwQl+6Oiyg3kicVU1N1X8bhZ/g1h49tcHrVtjU5ww==} + lefthook-windows-x64@1.7.2: + resolution: {integrity: sha512-fL4F8/XXoYUJJ6GSYCwFL+bRufzbkeMSGYZKUDr6ZKOI4KafIEcgFNwlnQF03gY6vkUrYKksXQofOVlOfv3vPA==} cpu: [x64] os: [win32] hasBin: true - lefthook@1.7.1: - resolution: {integrity: sha512-WNgjrPH4bYZyAYsiK7y7roQCQFIgqdCFxVCVe7ylAFD+QvW8tMceG19mR3GS2if1fGHC/cs+Z0r6PI52b/G1eA==} + lefthook@1.7.2: + resolution: {integrity: sha512-QCCq6KyVAVYBuxWf338TjMAjjGesyNRtfxJhjYV+kpUkd5ST2yr8ZUJrcEKe+0cUfziPOQ9Hz+1JZniXJx+JqA==} hasBin: true loupe@3.1.1: @@ -1098,8 +1086,8 @@ packages: resolution: {integrity: sha512-OSs33Z9yWr148JZcbZd5WiAXhh/n9z8TxQcdMhIOlpN9AhWpLfvVFO73+m77bBABQMaY9XSvIa+qk0jlI7Gcaw==} hasBin: true - node-gyp@10.1.0: - resolution: {integrity: sha512-B4J5M1cABxPc5PwfjhbV5hoy2DP9p8lFXASnEN6hugXOa61416tnTZ29x9sSwAd0o99XNIcpvDDy1swAExsVKA==} + node-gyp@10.2.0: + resolution: {integrity: sha512-sp3FonBAaFe4aYTcFdZUn2NYkbP7xroPGYvQmP4Nl5PxamznItBnNCgjrVTKrEfQynInMsJvZrdmqUnysCJ8rw==} engines: {node: ^16.14.0 || >=18.0.0} hasBin: true @@ -1171,14 +1159,6 @@ packages: resolution: {integrity: sha512-8Y2oOOateom/s8dNBsGIcnm6AxPmLH4/nanQzL5lQMU+sC0CMhzARZHizwr36pUPLdvBnOkCNQzxg4djuFSgIw==} hasBin: true - pretty-format@29.7.0: - resolution: {integrity: sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - proc-log@3.0.0: - resolution: {integrity: sha512-++Vn7NS4Xf9NacaU9Xq3URUuqZETPsf8L4j5/ckhaRYsfPeRyzGw+iDjFhV/Jr3uNmTvvddEJFWh5R1gRgUH8A==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - proc-log@4.2.0: resolution: {integrity: sha512-g8+OnU/L2v+wyiVK+D5fA34J7EH8jZ8DDlvwhRCMxmMj7UCBvxiO1mGeN+36JXIKF4zevU4kRBd8lVgG9vLelA==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} @@ -1190,9 +1170,6 @@ packages: pump@3.0.0: resolution: {integrity: sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==} - react-is@18.3.1: - resolution: {integrity: sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==} - readable-stream@3.6.2: resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} engines: {node: '>= 6'} @@ -1208,8 +1185,8 @@ packages: resolution: {integrity: sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==} engines: {node: '>= 4'} - rimraf@6.0.0: - resolution: {integrity: sha512-u+yqhM92LW+89cxUQK0SRyvXYQmyuKHx0jkx4W7KfwLGLqJnQM5031Uv1trE4gB9XEXBM/s6MxKlfW95IidqaA==} + rimraf@6.0.1: + resolution: {integrity: sha512-9dkvaxAsk/xNXSJzMgFqqMCuFgt2+KsOFek3TMLfo8NCPfWpBmqwyNn5Y+NX56QUYfCtsyhF3ayiboEoUmJk/A==} engines: {node: 20 || >=22} hasBin: true @@ -1351,6 +1328,10 @@ packages: resolution: {integrity: sha512-KIKExllK7jp3uvrNtvRBYBWBOAXSX8ZvoaD8T+7KB/QHIuoJW3Pmr60zucywjAlMb5TeXUkcs/MWeWLu0qvuAQ==} engines: {node: ^18.0.0 || >=20.0.0} + tinyrainbow@1.2.0: + resolution: {integrity: sha512-weEDEq7Z5eTHPDh4xjX789+fHfF+P8boiFB+0vbWzpbnbsEr/GRaohi/uMKxg8RZMXnl1ItAi/IUHWMsjDV7kQ==} + engines: {node: '>=14.0.0'} + tinyspy@3.0.0: resolution: {integrity: sha512-q5nmENpTHgiPVd1cJDDc9cVoYN5x4vCvwT3FMilvKPKneCBZAxn2YWQjDF0UMcE9k0Cay1gBiDfTMU0g+mPMQA==} engines: {node: '>=14.0.0'} @@ -1381,8 +1362,8 @@ packages: util-deprecate@1.0.2: resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} - vite-node@2.0.1: - resolution: {integrity: sha512-nVd6kyhPAql0s+xIVJzuF+RSRH8ZimNrm6U8ZvTA4MXv8CHI17TFaQwRaFiK75YX6XeFqZD4IoAaAfi9OR1XvQ==} + vite-node@2.0.2: + resolution: {integrity: sha512-w4vkSz1Wo+NIQg8pjlEn0jQbcM/0D+xVaYjhw3cvarTanLLBh54oNiRbsT8PNK5GfuST0IlVXjsNRoNlqvY/fw==} engines: {node: ^18.0.0 || >=20.0.0} hasBin: true @@ -1414,15 +1395,15 @@ packages: terser: optional: true - vitest@2.0.1: - resolution: {integrity: sha512-PBPvNXRJiywtI9NmbnEqHIhcXlk8mB0aKf6REQIaYGY4JtWF1Pg8Am+N0vAuxdg/wUSlxPSVJr8QdjwcVxc2Hg==} + vitest@2.0.2: + resolution: {integrity: sha512-WlpZ9neRIjNBIOQwBYfBSr0+of5ZCbxT2TVGKW4Lv0c8+srCFIiRdsP7U009t8mMn821HQ4XKgkx5dVWpyoyLw==} engines: {node: ^18.0.0 || >=20.0.0} hasBin: true peerDependencies: '@edge-runtime/vm': '*' '@types/node': ^18.0.0 || >=20.0.0 - '@vitest/browser': 2.0.1 - '@vitest/ui': 2.0.1 + '@vitest/browser': 2.0.2 + '@vitest/ui': 2.0.2 happy-dom: '*' jsdom: '*' peerDependenciesMeta: @@ -1692,10 +1673,6 @@ snapshots: '@istanbuljs/schema@0.1.3': {} - '@jest/schemas@29.6.3': - dependencies: - '@sinclair/typebox': 0.27.8 - '@jridgewell/gen-mapping@0.3.5': dependencies: '@jridgewell/set-array': 1.2.1 @@ -1795,15 +1772,13 @@ snapshots: '@rollup/rollup-win32-x64-msvc@4.18.1': optional: true - '@sinclair/typebox@0.27.8': {} - '@types/estree@1.0.5': {} '@types/node@20.14.10': dependencies: undici-types: 5.26.5 - '@vitest/coverage-v8@2.0.1(vitest@2.0.1(@types/node@20.14.10))': + '@vitest/coverage-v8@2.0.2(vitest@2.0.2(@types/node@20.14.10))': dependencies: '@ampproject/remapping': 2.3.0 '@bcoe/v8-coverage': 0.2.3 @@ -1814,41 +1789,46 @@ snapshots: istanbul-reports: 3.1.7 magic-string: 0.30.10 magicast: 0.3.4 - picocolors: 1.0.1 std-env: 3.7.0 strip-literal: 2.1.0 test-exclude: 7.0.1 - vitest: 2.0.1(@types/node@20.14.10) + tinyrainbow: 1.2.0 + vitest: 2.0.2(@types/node@20.14.10) transitivePeerDependencies: - supports-color - '@vitest/expect@2.0.1': + '@vitest/expect@2.0.2': dependencies: - '@vitest/spy': 2.0.1 - '@vitest/utils': 2.0.1 + '@vitest/spy': 2.0.2 + '@vitest/utils': 2.0.2 chai: 5.1.1 + tinyrainbow: 1.2.0 + + '@vitest/pretty-format@2.0.2': + dependencies: + tinyrainbow: 1.2.0 - '@vitest/runner@2.0.1': + '@vitest/runner@2.0.2': dependencies: - '@vitest/utils': 2.0.1 + '@vitest/utils': 2.0.2 pathe: 1.1.2 - '@vitest/snapshot@2.0.1': + '@vitest/snapshot@2.0.2': dependencies: + '@vitest/pretty-format': 2.0.2 magic-string: 0.30.10 pathe: 1.1.2 - pretty-format: 29.7.0 - '@vitest/spy@2.0.1': + '@vitest/spy@2.0.2': dependencies: tinyspy: 3.0.0 - '@vitest/utils@2.0.1': + '@vitest/utils@2.0.2': dependencies: - diff-sequences: 29.6.3 + '@vitest/pretty-format': 2.0.2 estree-walker: 3.0.3 loupe: 3.1.1 - pretty-format: 29.7.0 + tinyrainbow: 1.2.0 abbrev@2.0.0: {} @@ -1876,8 +1856,6 @@ snapshots: dependencies: color-convert: 2.0.1 - ansi-styles@5.2.0: {} - ansi-styles@6.2.1: {} assertion-error@2.0.1: {} @@ -1967,8 +1945,6 @@ snapshots: deep-eql@5.0.2: {} - diff-sequences@29.6.3: {} - eastasianwidth@0.2.0: {} emoji-regex@8.0.0: {} @@ -2215,40 +2191,40 @@ snapshots: jsbn@1.1.0: {} - lefthook-darwin-arm64@1.7.1: + lefthook-darwin-arm64@1.7.2: optional: true - lefthook-darwin-x64@1.7.1: + lefthook-darwin-x64@1.7.2: optional: true - lefthook-freebsd-arm64@1.7.1: + lefthook-freebsd-arm64@1.7.2: optional: true - lefthook-freebsd-x64@1.7.1: + lefthook-freebsd-x64@1.7.2: optional: true - lefthook-linux-arm64@1.7.1: + lefthook-linux-arm64@1.7.2: optional: true - lefthook-linux-x64@1.7.1: + lefthook-linux-x64@1.7.2: optional: true - lefthook-windows-arm64@1.7.1: + lefthook-windows-arm64@1.7.2: optional: true - lefthook-windows-x64@1.7.1: + lefthook-windows-x64@1.7.2: optional: true - lefthook@1.7.1: + lefthook@1.7.2: optionalDependencies: - lefthook-darwin-arm64: 1.7.1 - lefthook-darwin-x64: 1.7.1 - lefthook-freebsd-arm64: 1.7.1 - lefthook-freebsd-x64: 1.7.1 - lefthook-linux-arm64: 1.7.1 - lefthook-linux-x64: 1.7.1 - lefthook-windows-arm64: 1.7.1 - lefthook-windows-x64: 1.7.1 + lefthook-darwin-arm64: 1.7.2 + lefthook-darwin-x64: 1.7.2 + lefthook-freebsd-arm64: 1.7.2 + lefthook-freebsd-x64: 1.7.2 + lefthook-linux-arm64: 1.7.2 + lefthook-linux-x64: 1.7.2 + lefthook-windows-arm64: 1.7.2 + lefthook-windows-x64: 1.7.2 loupe@3.1.1: dependencies: @@ -2358,7 +2334,7 @@ snapshots: node-gyp-build@4.8.1(patch_hash=4v3havyznpg2abqwiszfjnuita): {} - node-gyp@10.1.0: + node-gyp@10.2.0: dependencies: env-paths: 2.2.1 exponential-backoff: 3.1.1 @@ -2366,7 +2342,7 @@ snapshots: graceful-fs: 4.2.11 make-fetch-happen: 13.0.1 nopt: 7.2.1 - proc-log: 3.0.0 + proc-log: 4.2.0 semver: 7.6.2 tar: 6.2.1 which: 4.0.0 @@ -2438,14 +2414,6 @@ snapshots: pump: 3.0.0 tar-fs: 2.1.1 - pretty-format@29.7.0: - dependencies: - '@jest/schemas': 29.6.3 - ansi-styles: 5.2.0 - react-is: 18.3.1 - - proc-log@3.0.0: {} - proc-log@4.2.0: {} promise-retry@2.0.1: @@ -2458,8 +2426,6 @@ snapshots: end-of-stream: 1.4.4 once: 1.4.0 - react-is@18.3.1: {} - readable-stream@3.6.2: dependencies: inherits: 2.0.4 @@ -2476,9 +2442,10 @@ snapshots: retry@0.12.0: {} - rimraf@6.0.0: + rimraf@6.0.1: dependencies: glob: 11.0.0 + package-json-from-dist: 1.0.0 rollup-plugin-dts@6.1.1(rollup@4.18.1)(typescript@5.5.3): dependencies: @@ -2642,6 +2609,8 @@ snapshots: tinypool@1.0.0: {} + tinyrainbow@1.2.0: {} + tinyspy@3.0.0: {} to-fast-properties@2.0.0: {} @@ -2662,12 +2631,12 @@ snapshots: util-deprecate@1.0.2: {} - vite-node@2.0.1(@types/node@20.14.10): + vite-node@2.0.2(@types/node@20.14.10): dependencies: cac: 6.7.14 debug: 4.3.5 pathe: 1.1.2 - picocolors: 1.0.1 + tinyrainbow: 1.2.0 vite: 5.3.1(@types/node@20.14.10) transitivePeerDependencies: - '@types/node' @@ -2688,25 +2657,26 @@ snapshots: '@types/node': 20.14.10 fsevents: 2.3.3 - vitest@2.0.1(@types/node@20.14.10): + vitest@2.0.2(@types/node@20.14.10): dependencies: '@ampproject/remapping': 2.3.0 - '@vitest/expect': 2.0.1 - '@vitest/runner': 2.0.1 - '@vitest/snapshot': 2.0.1 - '@vitest/spy': 2.0.1 - '@vitest/utils': 2.0.1 + '@vitest/expect': 2.0.2 + '@vitest/pretty-format': 2.0.2 + '@vitest/runner': 2.0.2 + '@vitest/snapshot': 2.0.2 + '@vitest/spy': 2.0.2 + '@vitest/utils': 2.0.2 chai: 5.1.1 debug: 4.3.5 execa: 8.0.1 magic-string: 0.30.10 pathe: 1.1.2 - picocolors: 1.0.1 std-env: 3.7.0 tinybench: 2.8.0 tinypool: 1.0.0 + tinyrainbow: 1.2.0 vite: 5.3.1(@types/node@20.14.10) - vite-node: 2.0.1(@types/node@20.14.10) + vite-node: 2.0.2(@types/node@20.14.10) why-is-node-running: 2.2.2 optionalDependencies: '@types/node': 20.14.10 diff --git a/src/index.ts b/src/index.ts index bd3da6d..a924d46 100644 --- a/src/index.ts +++ b/src/index.ts @@ -82,7 +82,7 @@ class WinRegLib extends EventEmitter { * Lists all subkeys and values for a specific key. * * @param {String} key - The key to list. - * @returns {Object} Contains the resolved `root`, `path`, `subkeys`, and `values`. + * @returns {RegistryKey} Contains the resolved `resolvedRoot`, `key`, `subkeys`, and `values`. */ list(key: string): RegistryKey | undefined { if (!key || typeof key !== 'string') { diff --git a/src/watchman.cpp b/src/watchman.cpp index 12c4aad..0f0fd30 100644 --- a/src/watchman.cpp +++ b/src/watchman.cpp @@ -6,11 +6,20 @@ using namespace winreglib; static void execute(napi_env env, void* data) { + LOG_DEBUG("execute", L"Calling run()"); ((Watchman*)data)->run(); + LOG_DEBUG("execute", L"run() returned!"); } static void complete(napi_env env, napi_status status, void* data) { - LOG_DEBUG("Watchman::complete", L"Worker thread exited") + if (status != napi_ok) { + const napi_extended_error_info* error; + ::napi_get_last_error_info(env, &error); + char msg[1024]; + ::snprintf(msg, 1024, "Watchman::complete: Worker thread failed (status=%d) %s", status, error->error_message); + } else { + LOG_DEBUG_1("Watchman::complete", L"Worker thread exited (status=%d)", status) + } } /** @@ -31,8 +40,22 @@ Watchman::Watchman(napi_env env) : env(env) { // initialize the background thread that waits for win32 events LOG_DEBUG_THREAD_ID("Watchman", L"Initializing async work") napi_value name; - NAPI_THROW("Watchman", "ERR_NAPI_CREATE_STRING", ::napi_create_string_utf8(env, "winreglib.runloop", NAPI_AUTO_LENGTH, &name)); - NAPI_THROW("Watchman", "ERR_NAPI_CREATE_ASYNC_WORK", ::napi_create_async_work(env, NULL, name, execute, complete, this, &asyncWork)); + NAPI_THROW("Watchman", "ERR_NAPI_CREATE_STRING", ::napi_create_string_utf8( + env, + "winreglib.runloop", + NAPI_AUTO_LENGTH, + &name + )) + NAPI_THROW("Watchman", "ERR_NAPI_CREATE_ASYNC_WORK", ::napi_create_async_work( + env, + NULL, + name, + execute, + complete, + this, + &asyncWork + )) + NAPI_THROW("Watchman", "ERR_NAPI_QUEUE_ASYNC_WORK", ::napi_queue_async_work(env, asyncWork)) // wire up our dispatch change handler into Node's event loop, then unref it so that we don't // block Node from exiting @@ -42,8 +65,13 @@ Watchman::Watchman(napi_env env) : env(env) { notifyChange = new uv_async_t; notifyChange->data = (void*)this; ::uv_async_init(loop, notifyChange, [](uv_async_t* handle) { + LOG_DEBUG("Watchman::Watchman", L"uv_async_t callback") if (handle && handle->data) { + LOG_DEBUG("Watchman::Watchman", L"Calling dispatch()") ((Watchman*)handle->data)->dispatch(); + LOG_DEBUG("Watchman::Watchman", L"dispatch() success!") + } else { + LOG_DEBUG("Watchman::Watchman", L"No data in handle! Watchman is no more!") } }); ::uv_unref((uv_handle_t*)notifyChange); @@ -53,16 +81,17 @@ Watchman::Watchman(napi_env env) : env(env) { * Stops the background thread and closes all handles. */ Watchman::~Watchman() { - ::SetEvent(term); - ::napi_delete_async_work(env, asyncWork); - ::CloseHandle(term); - ::CloseHandle(refresh); + LOG_DEBUG("Watchman::~Watchman", L"Stopping background thread") - notifyChange->data = NULL; ::uv_close(reinterpret_cast(notifyChange), [](uv_handle_t* handle) { uv_async_t* async = reinterpret_cast(handle); delete async; }); + + ::SetEvent(term); + ::napi_delete_async_work(env, asyncWork); + ::CloseHandle(term); + ::CloseHandle(refresh); } /** @@ -139,18 +168,25 @@ void Watchman::config(const std::wstring& key, napi_value listener, WatchAction } } - if (beforeCount == 0 && afterCount > 0) { - LOG_DEBUG_THREAD_ID("Watchman::config", L"Starting background thread") - NAPI_THROW("Watchman::config", "ERR_NAPI_QUEUE_ASYNC_WORK", ::napi_queue_async_work(env, asyncWork)) - } else if (beforeCount > 0 && afterCount == 0) { - LOG_DEBUG_THREAD_ID("Watchman::config", L"Signalling term event") - ::SetEvent(term); - } else if (beforeCount != afterCount) { - LOG_DEBUG_THREAD_ID("Watchman::config", L"Signalling refresh event") + // if (beforeCount == 0 && afterCount > 0) { + // LOG_DEBUG_THREAD_ID("Watchman::config", L"Starting background thread") + // NAPI_THROW("Watchman::config", "ERR_NAPI_QUEUE_ASYNC_WORK", ::napi_queue_async_work(env, asyncWork)) + // } else if (beforeCount > 0 && afterCount == 0) { + // LOG_DEBUG_THREAD_ID("Watchman::config", L"Signaling term event") + // ::SetEvent(term); + // } else if (beforeCount != afterCount) { + // LOG_DEBUG_THREAD_ID("Watchman::config", L"Signaling refresh event") + // ::SetEvent(refresh); + // } + + if ((beforeCount > 0 || afterCount > 0) && beforeCount != afterCount) { + LOG_DEBUG_THREAD_ID("Watchman::config", L"Signaling refresh event") ::SetEvent(refresh); } + LOG_DEBUG("Watchman::config", L"Printing tree") printTree(); + LOG_DEBUG("Watchman::config", L"Done printing tree") } /** @@ -162,23 +198,28 @@ void Watchman::dispatch() { while (1) { std::shared_ptr node; - DWORD count = 0; + DWORD remaining = 0; // check if there are any changed nodes left... // the first time we loop, we know there's at least one { + LOG_DEBUG("Watchman::dispatch", L"Obtaining lock for changed nodes...") std::lock_guard lock(changedNodesLock); if (changedNodes.empty()) { - break; + LOG_DEBUG("Watchman::dispatch", L"No changed nodes to dispatch, returning") + return; } - count = changedNodes.size(); + remaining = changedNodes.size(); + LOG_DEBUG_1("Watchman::dispatch", L"Found %ld changed nodes", remaining) node = changedNodes.front(); + LOG_DEBUG("Watchman::dispatch", L"Popping changed node...") changedNodes.pop_front(); + LOG_DEBUG("Watchman::dispatch", L"Popped changed node!") } - LOG_DEBUG_2("Watchman::dispatch", L"Dispatching change event for \"%ls\" (%d pending)", node->name.c_str(), --count) + LOG_DEBUG_2("Watchman::dispatch", L"Dispatching change event for \"%ls\" (%d remaining)", node->name.c_str(), --remaining) if (node->onChange()) { printTree(); } @@ -219,7 +260,9 @@ void Watchman::run() { while (1) { if (handles != NULL) { + LOG_DEBUG("Watchman::run", L"Deleting handles 1") delete[] handles; + LOG_DEBUG("Watchman::run", L"Deleted handles 1") } // WaitForMultipleObjects() wants an array of handles, so we must construct one @@ -240,6 +283,7 @@ void Watchman::run() { LOG_DEBUG_1("Watchman::run", L"Waiting on %ld objects...", count) DWORD result = ::WaitForMultipleObjects(count, handles, FALSE, INFINITE); + LOG_DEBUG("Watchman::run", L"Done waiting on objects") if (result == WAIT_OBJECT_0) { // terminate @@ -278,12 +322,16 @@ void Watchman::run() { } } + LOG_DEBUG("Watchman::run", L"Sending notification to main thread") ::uv_async_send(notifyChange); + LOG_DEBUG("Watchman::run", L"Done sending notification to main thread") } } } } } + LOG_DEBUG("Watchman::run", L"Deleting handles 2") delete[] handles; + LOG_DEBUG("Watchman::run", L"Deleted handles 2") } diff --git a/src/winreglib.cpp b/src/winreglib.cpp index 797d679..8d884a1 100644 --- a/src/winreglib.cpp +++ b/src/winreglib.cpp @@ -382,6 +382,8 @@ NAPI_METHOD(unwatch) { * Destroys the Watchman instance, log ref handle, and notify handle. */ static void cleanup(napi_async_cleanup_hook_handle handle, void* arg) { + LOG_DEBUG("cleanup", L"CLEANING UP!") + if (winreglib::watchman) { delete winreglib::watchman; } diff --git a/test/wingreglib-get.test.ts b/test/wingreglib-get.test.ts index e20a2d0..26cc735 100644 --- a/test/wingreglib-get.test.ts +++ b/test/wingreglib-get.test.ts @@ -11,7 +11,7 @@ const reg = (...args) => { spawnSync('reg', args, { stdio: 'ignore' }); }; -describe('get()', () => { +describe.skip('get()', () => { it('should error if key is not specified', () => { expect(() => { // biome-ignore lint/suspicious/noExplicitAny: need to test invalid input diff --git a/test/wingreglib-list.test.ts b/test/wingreglib-list.test.ts index 2978f26..d6f9393 100644 --- a/test/wingreglib-list.test.ts +++ b/test/wingreglib-list.test.ts @@ -2,7 +2,7 @@ import assert from 'node:assert'; import { describe, expect, it } from 'vitest'; import winreglib from '../src/index.js'; -describe('list()', () => { +describe.skip('list()', () => { it('should error if key is not specified', () => { expect(() => { // biome-ignore lint/suspicious/noExplicitAny: need to test invalid input diff --git a/test/wingreglib-watch.test.ts b/test/wingreglib-watch.test.ts index 4ca03e0..f7230df 100644 --- a/test/wingreglib-watch.test.ts +++ b/test/wingreglib-watch.test.ts @@ -32,7 +32,7 @@ describe('watch()', () => { }).toThrowError(new TypeError('Invalid registry root key "foo"')); }); - it( + it.only( 'should watch existing key for new subkey', { timeout: 15000 }, async () => { @@ -45,7 +45,7 @@ describe('watch()', () => { let counter = 0; await new Promise((resolve, reject) => { handle.on('change', evt => { - // console.log('CHANGE!', evt); + // log('CHANGE!', evt); try { expect(evt).toBeInstanceOf(Object); switch (counter++) { @@ -70,6 +70,7 @@ describe('watch()', () => { }); setTimeout(() => reg('add', 'HKCU\\Software\\winreglib\\foo'), 500); }); + handle.stop(); } finally { // also test stop() being called twice @@ -79,34 +80,40 @@ describe('watch()', () => { } ); - it.skip( + it.only( 'should watch existing key for value change', { timeout: 15000 }, async () => { - reg('delete', 'HKCU\\Software\\winreglib', '/f'); - reg('add', 'HKCU\\Software\\winreglib'); + reg('delete', 'HKCU\\Software\\winreglib2', '/f'); + reg('add', 'HKCU\\Software\\winreglib2'); - const handle = winreglib.watch('HKCU\\SOFTWARE\\winreglib'); + const handle = winreglib.watch('HKCU\\SOFTWARE\\winreglib2'); try { let counter = 0; await new Promise((resolve, reject) => { handle.on('change', evt => { - console.log('CHANGE!', evt); + // log('CHANGE!', evt); try { expect(evt).toBeTypeOf('object'); switch (counter++) { case 0: expect(evt).toMatchObject({ type: 'change', - key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib' + key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib2' }); - reg('delete', 'HKCU\\Software\\winreglib', '/f', '/v', 'foo'); + reg( + 'delete', + 'HKCU\\Software\\winreglib2', + '/f', + '/v', + 'foo' + ); break; case 1: expect(evt).toMatchObject({ type: 'change', - key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib' + key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib2' }); resolve(); break; @@ -119,7 +126,7 @@ describe('watch()', () => { () => reg( 'add', - 'HKCU\\Software\\winreglib', + 'HKCU\\Software\\winreglib2', '/v', 'foo', '/t', @@ -132,7 +139,7 @@ describe('watch()', () => { }); } finally { handle.stop(); - reg('delete', 'HKCU\\Software\\winreglib', '/f'); + reg('delete', 'HKCU\\Software\\winreglib2', '/f'); } } ); From 8fe94ea5346de71306fbe0f7d8631459a75d6d54 Mon Sep 17 00:00:00 2001 From: Chris Barber Date: Sun, 14 Jul 2024 18:32:10 -0500 Subject: [PATCH 08/27] Cleanup debug logging --- package.json | 4 ++-- src/watchman.cpp | 46 ++++++---------------------------------------- src/winreglib.cpp | 2 -- 3 files changed, 8 insertions(+), 44 deletions(-) diff --git a/package.json b/package.json index d8f55ec..d2c8eef 100644 --- a/package.json +++ b/package.json @@ -34,8 +34,8 @@ "prebuild-arm64": "prebuildify --napi --strip --platform=win32 --arch arm64", "prebuild-ia32": "prebuildify --napi --strip --platform=win32 --arch ia32", "prebuild-x64": "prebuildify --napi --strip --platform=win32 --arch x64", - "rebuild:local": "node-gyp -j 20 rebuild", - "rebuild:local-debug": "node-gyp -j 20 rebuild --debug", + "rebuild:local": "node-gyp rebuild", + "rebuild:local-debug": "node-gyp rebuild --debug", "test": "vitest --allowOnly --pool=forks", "type-check": "tsc --noEmit" }, diff --git a/src/watchman.cpp b/src/watchman.cpp index 0f0fd30..6b46441 100644 --- a/src/watchman.cpp +++ b/src/watchman.cpp @@ -6,17 +6,14 @@ using namespace winreglib; static void execute(napi_env env, void* data) { - LOG_DEBUG("execute", L"Calling run()"); ((Watchman*)data)->run(); - LOG_DEBUG("execute", L"run() returned!"); } static void complete(napi_env env, napi_status status, void* data) { if (status != napi_ok) { const napi_extended_error_info* error; ::napi_get_last_error_info(env, &error); - char msg[1024]; - ::snprintf(msg, 1024, "Watchman::complete: Worker thread failed (status=%d) %s", status, error->error_message); + LOG_DEBUG_2("Watchman::complete", L"Watchman::complete: Worker thread failed (status=%d) %s", status, error->error_message) } else { LOG_DEBUG_1("Watchman::complete", L"Worker thread exited (status=%d)", status) } @@ -65,13 +62,8 @@ Watchman::Watchman(napi_env env) : env(env) { notifyChange = new uv_async_t; notifyChange->data = (void*)this; ::uv_async_init(loop, notifyChange, [](uv_async_t* handle) { - LOG_DEBUG("Watchman::Watchman", L"uv_async_t callback") if (handle && handle->data) { - LOG_DEBUG("Watchman::Watchman", L"Calling dispatch()") ((Watchman*)handle->data)->dispatch(); - LOG_DEBUG("Watchman::Watchman", L"dispatch() success!") - } else { - LOG_DEBUG("Watchman::Watchman", L"No data in handle! Watchman is no more!") } }); ::uv_unref((uv_handle_t*)notifyChange); @@ -81,17 +73,15 @@ Watchman::Watchman(napi_env env) : env(env) { * Stops the background thread and closes all handles. */ Watchman::~Watchman() { - LOG_DEBUG("Watchman::~Watchman", L"Stopping background thread") + ::SetEvent(term); + ::napi_delete_async_work(env, asyncWork); + ::CloseHandle(term); + ::CloseHandle(refresh); ::uv_close(reinterpret_cast(notifyChange), [](uv_handle_t* handle) { uv_async_t* async = reinterpret_cast(handle); delete async; }); - - ::SetEvent(term); - ::napi_delete_async_work(env, asyncWork); - ::CloseHandle(term); - ::CloseHandle(refresh); } /** @@ -168,25 +158,12 @@ void Watchman::config(const std::wstring& key, napi_value listener, WatchAction } } - // if (beforeCount == 0 && afterCount > 0) { - // LOG_DEBUG_THREAD_ID("Watchman::config", L"Starting background thread") - // NAPI_THROW("Watchman::config", "ERR_NAPI_QUEUE_ASYNC_WORK", ::napi_queue_async_work(env, asyncWork)) - // } else if (beforeCount > 0 && afterCount == 0) { - // LOG_DEBUG_THREAD_ID("Watchman::config", L"Signaling term event") - // ::SetEvent(term); - // } else if (beforeCount != afterCount) { - // LOG_DEBUG_THREAD_ID("Watchman::config", L"Signaling refresh event") - // ::SetEvent(refresh); - // } - - if ((beforeCount > 0 || afterCount > 0) && beforeCount != afterCount) { + if (afterCount > 0 && beforeCount != afterCount) { LOG_DEBUG_THREAD_ID("Watchman::config", L"Signaling refresh event") ::SetEvent(refresh); } - LOG_DEBUG("Watchman::config", L"Printing tree") printTree(); - LOG_DEBUG("Watchman::config", L"Done printing tree") } /** @@ -203,20 +180,15 @@ void Watchman::dispatch() { // check if there are any changed nodes left... // the first time we loop, we know there's at least one { - LOG_DEBUG("Watchman::dispatch", L"Obtaining lock for changed nodes...") std::lock_guard lock(changedNodesLock); if (changedNodes.empty()) { - LOG_DEBUG("Watchman::dispatch", L"No changed nodes to dispatch, returning") return; } remaining = changedNodes.size(); - LOG_DEBUG_1("Watchman::dispatch", L"Found %ld changed nodes", remaining) node = changedNodes.front(); - LOG_DEBUG("Watchman::dispatch", L"Popping changed node...") changedNodes.pop_front(); - LOG_DEBUG("Watchman::dispatch", L"Popped changed node!") } LOG_DEBUG_2("Watchman::dispatch", L"Dispatching change event for \"%ls\" (%d remaining)", node->name.c_str(), --remaining) @@ -260,9 +232,7 @@ void Watchman::run() { while (1) { if (handles != NULL) { - LOG_DEBUG("Watchman::run", L"Deleting handles 1") delete[] handles; - LOG_DEBUG("Watchman::run", L"Deleted handles 1") } // WaitForMultipleObjects() wants an array of handles, so we must construct one @@ -322,16 +292,12 @@ void Watchman::run() { } } - LOG_DEBUG("Watchman::run", L"Sending notification to main thread") ::uv_async_send(notifyChange); - LOG_DEBUG("Watchman::run", L"Done sending notification to main thread") } } } } } - LOG_DEBUG("Watchman::run", L"Deleting handles 2") delete[] handles; - LOG_DEBUG("Watchman::run", L"Deleted handles 2") } diff --git a/src/winreglib.cpp b/src/winreglib.cpp index 8d884a1..797d679 100644 --- a/src/winreglib.cpp +++ b/src/winreglib.cpp @@ -382,8 +382,6 @@ NAPI_METHOD(unwatch) { * Destroys the Watchman instance, log ref handle, and notify handle. */ static void cleanup(napi_async_cleanup_hook_handle handle, void* arg) { - LOG_DEBUG("cleanup", L"CLEANING UP!") - if (winreglib::watchman) { delete winreglib::watchman; } From 7ea61f0681f41db07833b0c394ec94e028178638 Mon Sep 17 00:00:00 2001 From: Chris Barber Date: Mon, 15 Jul 2024 01:00:00 -0500 Subject: [PATCH 09/27] Enable tests --- src/watchman.cpp | 4 +- src/watchnode.cpp | 6 +- src/watchnode.h | 11 +- test/{wingreglib-get.test.ts => get.test.ts} | 2 +- .../{wingreglib-list.test.ts => list.test.ts} | 2 +- ...wingreglib-watch.test.ts => watch.test.ts} | 266 +++++++++--------- 6 files changed, 151 insertions(+), 140 deletions(-) rename test/{wingreglib-get.test.ts => get.test.ts} (99%) rename test/{wingreglib-list.test.ts => list.test.ts} (98%) rename test/{wingreglib-watch.test.ts => watch.test.ts} (74%) diff --git a/src/watchman.cpp b/src/watchman.cpp index 6b46441..87ba715 100644 --- a/src/watchman.cpp +++ b/src/watchman.cpp @@ -13,7 +13,7 @@ static void complete(napi_env env, napi_status status, void* data) { if (status != napi_ok) { const napi_extended_error_info* error; ::napi_get_last_error_info(env, &error); - LOG_DEBUG_2("Watchman::complete", L"Watchman::complete: Worker thread failed (status=%d) %s", status, error->error_message) + LOG_DEBUG_2("Watchman::complete", L"Watchman::complete: Worker thread failed (status=%d) %hs", status, error->error_message) } else { LOG_DEBUG_1("Watchman::complete", L"Worker thread exited (status=%d)", status) } @@ -62,6 +62,7 @@ Watchman::Watchman(napi_env env) : env(env) { notifyChange = new uv_async_t; notifyChange->data = (void*)this; ::uv_async_init(loop, notifyChange, [](uv_async_t* handle) { + // the background thread has signaled that a registry event has occurred if (handle && handle->data) { ((Watchman*)handle->data)->dispatch(); } @@ -253,7 +254,6 @@ void Watchman::run() { LOG_DEBUG_1("Watchman::run", L"Waiting on %ld objects...", count) DWORD result = ::WaitForMultipleObjects(count, handles, FALSE, INFINITE); - LOG_DEBUG("Watchman::run", L"Done waiting on objects") if (result == WAIT_OBJECT_0) { // terminate diff --git a/src/watchnode.cpp b/src/watchnode.cpp index 5266929..6cfa5a1 100644 --- a/src/watchnode.cpp +++ b/src/watchnode.cpp @@ -112,7 +112,7 @@ bool WatchNode::load(CallbackQueue* pending) { watch(pending); if (pending) { - PUSH_CALLBACK(*pending, "add", getKey(), listeners); + PUSH_CALLBACK(*pending, "add", getKey(), listeners) } for (auto const& it : subkeys) { @@ -146,7 +146,7 @@ bool WatchNode::onChange() { if (hkey) { if (watch(&pending)) { - PUSH_CALLBACK(pending, "change", getKey(), listeners); + PUSH_CALLBACK(pending, "change", getKey(), listeners) } for (auto const& it : subkeys) { @@ -251,7 +251,7 @@ void WatchNode::unload(CallbackQueue* pending) { hkey = NULL; if (pending) { - PUSH_CALLBACK(*pending, "delete", getKey(), listeners); + PUSH_CALLBACK(*pending, "delete", getKey(), listeners) } } } diff --git a/src/watchnode.h b/src/watchnode.h index 0e63619..36bb412 100644 --- a/src/watchnode.h +++ b/src/watchnode.h @@ -20,7 +20,7 @@ const DWORD filter = REG_NOTIFY_CHANGE_NAME | #define PUSH_CALLBACK(list, evtType, key, listeners) \ if (listeners.size() > 0) { \ - char type[] = evtType; \ + const char* type = evtType; \ (list).push(std::make_shared(type, key, listeners)); \ } @@ -28,10 +28,13 @@ const DWORD filter = REG_NOTIFY_CHANGE_NAME | * Holds everything needed to emit a change event for a given node. */ struct Callback { - Callback(char* type, std::u16string key, std::list listeners) : - type(type), key(key), listeners(listeners) {} + Callback(const char* type, std::u16string key, std::list listeners) : + key(key), listeners(listeners) + { + strncpy(this->type, type, 10); + } - char* type; + char type[10]; std::u16string key; std::list listeners; }; diff --git a/test/wingreglib-get.test.ts b/test/get.test.ts similarity index 99% rename from test/wingreglib-get.test.ts rename to test/get.test.ts index 26cc735..e20a2d0 100644 --- a/test/wingreglib-get.test.ts +++ b/test/get.test.ts @@ -11,7 +11,7 @@ const reg = (...args) => { spawnSync('reg', args, { stdio: 'ignore' }); }; -describe.skip('get()', () => { +describe('get()', () => { it('should error if key is not specified', () => { expect(() => { // biome-ignore lint/suspicious/noExplicitAny: need to test invalid input diff --git a/test/wingreglib-list.test.ts b/test/list.test.ts similarity index 98% rename from test/wingreglib-list.test.ts rename to test/list.test.ts index d6f9393..2978f26 100644 --- a/test/wingreglib-list.test.ts +++ b/test/list.test.ts @@ -2,7 +2,7 @@ import assert from 'node:assert'; import { describe, expect, it } from 'vitest'; import winreglib from '../src/index.js'; -describe.skip('list()', () => { +describe('list()', () => { it('should error if key is not specified', () => { expect(() => { // biome-ignore lint/suspicious/noExplicitAny: need to test invalid input diff --git a/test/wingreglib-watch.test.ts b/test/watch.test.ts similarity index 74% rename from test/wingreglib-watch.test.ts rename to test/watch.test.ts index f7230df..f6ea116 100644 --- a/test/wingreglib-watch.test.ts +++ b/test/watch.test.ts @@ -32,7 +32,7 @@ describe('watch()', () => { }).toThrowError(new TypeError('Invalid registry root key "foo"')); }); - it.only( + it( 'should watch existing key for new subkey', { timeout: 15000 }, async () => { @@ -80,7 +80,7 @@ describe('watch()', () => { } ); - it.only( + it( 'should watch existing key for value change', { timeout: 15000 }, async () => { @@ -144,94 +144,90 @@ describe('watch()', () => { } ); - it.skip( - 'should watch a key that does not exist', - { timeout: 15000 }, - async () => { - reg('delete', 'HKCU\\Software\\winreglib', '/f'); - reg('add', 'HKCU\\Software\\winreglib'); + it('should watch a key that does not exist', { timeout: 15000 }, async () => { + reg('delete', 'HKCU\\Software\\winreglib', '/f'); + reg('add', 'HKCU\\Software\\winreglib'); - const handle = winreglib.watch('HKCU\\SOFTWARE\\winreglib\\foo'); + const handle = winreglib.watch('HKCU\\SOFTWARE\\winreglib\\foo'); - try { - let counter = 0; - await new Promise((resolve, reject) => { - handle.on('change', evt => { - // console.log('CHANGE!!', counter, evt); - try { - expect(evt).toBeTypeOf('object'); - switch (counter++) { - case 0: - expect(evt).toMatchObject({ - type: 'add', - key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib\\foo' - }); - reg( - 'add', - 'HKCU\\Software\\winreglib\\foo', - '/v', - 'bar', - '/t', - 'REG_SZ', - '/d', - 'baz' - ); - break; - case 1: - expect(evt).toMatchObject({ - type: 'change', - key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib\\foo' - }); - reg( - 'delete', - 'HKCU\\Software\\winreglib\\foo', - '/f', - '/v', - 'bar' - ); - break; - case 2: - expect(evt).toMatchObject({ - type: 'change', - key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib\\foo' - }); - setTimeout( - () => reg('delete', 'HKCU\\Software\\winreglib\\foo', '/f'), - 500 - ); - break; - case 3: - expect(evt).toMatchObject({ - type: 'delete', - key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib\\foo' - }); - setTimeout( - () => reg('add', 'HKCU\\Software\\winreglib\\foo'), - 500 - ); - break; - case 4: - expect(evt).toMatchObject({ - type: 'add', - key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib\\foo' - }); - resolve(); - break; - } - } catch (e) { - reject(e); + try { + let counter = 0; + await new Promise((resolve, reject) => { + handle.on('change', evt => { + // console.log('CHANGE!!', counter, evt); + try { + expect(evt).toBeTypeOf('object'); + switch (counter++) { + case 0: + expect(evt).toMatchObject({ + type: 'add', + key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib\\foo' + }); + reg( + 'add', + 'HKCU\\Software\\winreglib\\foo', + '/v', + 'bar', + '/t', + 'REG_SZ', + '/d', + 'baz' + ); + break; + case 1: + expect(evt).toMatchObject({ + type: 'change', + key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib\\foo' + }); + reg( + 'delete', + 'HKCU\\Software\\winreglib\\foo', + '/f', + '/v', + 'bar' + ); + break; + case 2: + expect(evt).toMatchObject({ + type: 'change', + key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib\\foo' + }); + setTimeout( + () => reg('delete', 'HKCU\\Software\\winreglib\\foo', '/f'), + 500 + ); + break; + case 3: + expect(evt).toMatchObject({ + type: 'delete', + key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib\\foo' + }); + setTimeout( + () => reg('add', 'HKCU\\Software\\winreglib\\foo'), + 500 + ); + break; + case 4: + expect(evt).toMatchObject({ + type: 'add', + key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib\\foo' + }); + resolve(); + break; } - }); - setTimeout(() => reg('add', 'HKCU\\Software\\winreglib\\foo'), 500); + } catch (e) { + reject(e); + } }); - } finally { - handle.stop(); - reg('delete', 'HKCU\\Software\\winreglib', '/f'); - } + setTimeout(() => reg('add', 'HKCU\\Software\\winreglib\\foo'), 500); + }); + } finally { + handle.stop(); + reg('delete', 'HKCU\\Software\\winreglib', '/f'); } - ); + }); - it.skip( + it( 'should watch a key whose parent does not exist', { timeout: 15000 }, async () => { @@ -330,50 +326,46 @@ describe('watch()', () => { } ); - it.skip( - 'should watch a key that gets deleted', - { timeout: 15000 }, - async () => { - reg('delete', 'HKCU\\Software\\winreglib', '/f'); - reg('add', 'HKCU\\Software\\winreglib\\foo'); + it('should watch a key that gets deleted', { timeout: 15000 }, async () => { + reg('delete', 'HKCU\\Software\\winreglib', '/f'); + reg('add', 'HKCU\\Software\\winreglib\\foo'); - const handle = winreglib.watch('HKCU\\SOFTWARE\\winreglib\\foo'); + const handle = winreglib.watch('HKCU\\SOFTWARE\\winreglib\\foo'); - try { - let counter = 0; - await new Promise((resolve, reject) => { - handle.on('change', evt => { - // console.log('CHANGE!', evt); - try { - expect(evt).toBeTypeOf('object'); - switch (counter++) { - case 0: - expect(evt).toMatchObject({ - type: 'delete', - key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib\\foo' - }); - resolve(); - break; - } - } catch (e) { - reject(e); + try { + let counter = 0; + await new Promise((resolve, reject) => { + handle.on('change', evt => { + // console.log('CHANGE!', evt); + try { + expect(evt).toBeTypeOf('object'); + switch (counter++) { + case 0: + expect(evt).toMatchObject({ + type: 'delete', + key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib\\foo' + }); + resolve(); + break; } - }); - setTimeout( - () => reg('delete', 'HKCU\\Software\\winreglib\\foo', '/f'), - 500 - ); + } catch (e) { + reject(e); + } }); - handle.stop(); - } finally { - // also test stop() being called twice - handle.stop(); - reg('delete', 'HKCU\\Software\\winreglib', '/f'); - } + setTimeout( + () => reg('delete', 'HKCU\\Software\\winreglib\\foo', '/f'), + 500 + ); + }); + handle.stop(); + } finally { + // also test stop() being called twice + handle.stop(); + reg('delete', 'HKCU\\Software\\winreglib', '/f'); } - ); + }); - it.skip( + it( 'should watch a key whose parent gets deleted', { timeout: 15000 }, async () => { @@ -418,7 +410,7 @@ describe('watch()', () => { } ); - it.skip('should survive the gauntlet', { timeout: 15000 }, async () => { + it.only('should survive the gauntlet', { timeout: 15000 }, async () => { reg('delete', 'HKCU\\Software\\winreglib', '/f'); reg('add', 'HKCU\\Software\\winreglib'); @@ -432,24 +424,27 @@ describe('watch()', () => { try { let counter = 0; await new Promise((resolve, reject) => { - const fn = evt => { - // console.log('CHANGE!', evt); + const fn = (evt, handleName) => { + log('CHANGE!', counter, handleName, evt); try { expect(evt).toBeTypeOf('object'); switch (counter++) { case 0: + expect(handleName).toBe('winreglibHandle'); expect(evt).toMatchObject({ type: 'change', key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib' }); break; case 1: + expect(handleName).toBe('fooHandle'); expect(evt).toMatchObject({ type: 'add', key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib\\foo' }); break; case 2: + expect(handleName).toBe('barHandle'); expect(evt).toMatchObject({ type: 'add', key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib\\foo\\bar' @@ -457,12 +452,14 @@ describe('watch()', () => { reg('delete', 'HKCU\\Software\\winreglib\\foo\\bar', '/f'); break; case 3: + expect(handleName).toBe('fooHandle'); expect(evt).toMatchObject({ type: 'change', key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib\\foo' }); break; case 4: + expect(handleName).toBe('barHandle'); expect(evt).toMatchObject({ type: 'delete', key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib\\foo\\bar' @@ -479,6 +476,7 @@ describe('watch()', () => { ); break; case 5: + expect(handleName).toBe('winreglibHandle'); expect(evt).toMatchObject({ type: 'change', key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib' @@ -486,12 +484,14 @@ describe('watch()', () => { reg('add', 'HKCU\\Software\\winreglib\\foo\\bar\\wiz'); break; case 6: + expect(handleName).toBe('fooHandle'); expect(evt).toMatchObject({ type: 'change', key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib\\foo' }); break; case 7: + expect(handleName).toBe('barHandle'); expect(evt).toMatchObject({ type: 'add', key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib\\foo\\bar' @@ -499,12 +499,14 @@ describe('watch()', () => { reg('add', 'HKCU\\Software\\winreglib\\foo\\bar\\baz'); break; case 8: + expect(handleName).toBe('barHandle'); expect(evt).toMatchObject({ type: 'change', key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib\\foo\\bar' }); break; case 9: + expect(handleName).toBe('bazHandle'); expect(evt).toMatchObject({ type: 'add', key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib\\foo\\bar\\baz' @@ -521,6 +523,7 @@ describe('watch()', () => { ); break; case 10: + expect(handleName).toBe('bazHandle'); expect(evt).toMatchObject({ type: 'change', key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib\\foo\\bar\\baz' @@ -528,6 +531,7 @@ describe('watch()', () => { reg('delete', 'HKCU\\Software\\winreglib', '/f', '/v', 'foo'); break; case 11: + expect(handleName).toBe('winreglibHandle'); expect(evt).toMatchObject({ type: 'change', key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib' @@ -535,24 +539,28 @@ describe('watch()', () => { reg('delete', 'HKCU\\Software\\winreglib\\foo', '/f'); break; case 12: + expect(handleName).toBe('bazHandle'); expect(evt).toMatchObject({ type: 'delete', key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib\\foo\\bar\\baz' }); break; case 13: + expect(handleName).toBe('barHandle'); expect(evt).toMatchObject({ type: 'delete', key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib\\foo\\bar' }); break; case 14: + expect(handleName).toBe('fooHandle'); expect(evt).toMatchObject({ type: 'delete', key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib\\foo' }); break; case 15: + expect(handleName).toBe('winreglibHandle'); expect(evt).toMatchObject({ type: 'change', key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib' @@ -564,10 +572,10 @@ describe('watch()', () => { reject(e); } }; - winreglibHandle.on('change', fn); - fooHandle.on('change', fn); - barHandle.on('change', fn); - bazHandle.on('change', fn); + winreglibHandle.on('change', evt => fn(evt, 'winreglibHandle')); + fooHandle.on('change', evt => fn(evt, 'fooHandle')); + barHandle.on('change', evt => fn(evt, 'barHandle')); + bazHandle.on('change', evt => fn(evt, 'bazHandle')); setTimeout( () => reg('add', 'HKCU\\Software\\winreglib\\foo\\bar'), 500 From 8a9b8768749bec8b0999057fdddaecea82344678 Mon Sep 17 00:00:00 2001 From: Chris Barber Date: Tue, 16 Jul 2024 00:59:55 -0500 Subject: [PATCH 10/27] Finally fixed the bugs and tests pass --- CHANGELOG.md | 1 + package.json | 4 +- pnpm-lock.yaml | 94 +++++++++++++++++++++++----------------------- src/watchman.cpp | 12 +++--- src/watchnode.cpp | 24 +++++++++--- test/watch.test.ts | 38 +++++++++---------- 6 files changed, 93 insertions(+), 80 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d9c8c45..3cc114e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ * BREAKING CHANGE: Require Node.js 18.17 or newer * feat: Support for arm/arm64 + * fix: Fixed order of child key events when parent key is deleted # v2.0.4 (July 2, 2024) diff --git a/package.json b/package.json index d2c8eef..d0d0e73 100644 --- a/package.json +++ b/package.json @@ -49,7 +49,7 @@ "@biomejs/biome": "1.8.3", "@rollup/plugin-typescript": "11.1.6", "@types/node": "20.14.10", - "@vitest/coverage-v8": "2.0.2", + "@vitest/coverage-v8": "2.0.3", "esbuild": "0.23.0", "lefthook": "1.7.2", "prebuildify": "6.0.1", @@ -59,7 +59,7 @@ "rollup-plugin-esbuild": "6.1.1", "tslib": "2.6.3", "typescript": "5.5.3", - "vitest": "2.0.2" + "vitest": "2.0.3" }, "homepage": "https://github.com/tidev/winreglib", "bugs": "https://github.com/tidev/winreglib/issues", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b4e3f8a..2e066ca 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -36,8 +36,8 @@ importers: specifier: 20.14.10 version: 20.14.10 '@vitest/coverage-v8': - specifier: 2.0.2 - version: 2.0.2(vitest@2.0.2(@types/node@20.14.10)) + specifier: 2.0.3 + version: 2.0.3(vitest@2.0.3(@types/node@20.14.10)) esbuild: specifier: 0.23.0 version: 0.23.0 @@ -66,8 +66,8 @@ importers: specifier: 5.5.3 version: 5.5.3 vitest: - specifier: 2.0.2 - version: 2.0.2(@types/node@20.14.10) + specifier: 2.0.3 + version: 2.0.3(@types/node@20.14.10) packages: @@ -584,28 +584,28 @@ packages: '@types/node@20.14.10': resolution: {integrity: sha512-MdiXf+nDuMvY0gJKxyfZ7/6UFsETO7mGKF54MVD/ekJS6HdFtpZFBgrh6Pseu64XTb2MLyFPlbW6hj8HYRQNOQ==} - '@vitest/coverage-v8@2.0.2': - resolution: {integrity: sha512-iA8eb4PMid3bMc++gfQSTvYE1QL//fC8pz+rKsTUDBFjdDiy/gH45hvpqyDu5K7FHhvgG0GNNCJzTMMSFKhoxg==} + '@vitest/coverage-v8@2.0.3': + resolution: {integrity: sha512-53d+6jXFdYbasXBmsL6qaGIfcY5eBQq0sP57AjdasOcSiGNj4qxkkpDKIitUNfjxcfAfUfQ8BD0OR2fSey64+g==} peerDependencies: - vitest: 2.0.2 + vitest: 2.0.3 - '@vitest/expect@2.0.2': - resolution: {integrity: sha512-nKAvxBYqcDugYZ4nJvnm5OR8eDJdgWjk4XM9owQKUjzW70q0icGV2HVnQOyYsp906xJaBDUXw0+9EHw2T8e0mQ==} + '@vitest/expect@2.0.3': + resolution: {integrity: sha512-X6AepoOYePM0lDNUPsGXTxgXZAl3EXd0GYe/MZyVE4HzkUqyUVC6S3PrY5mClDJ6/7/7vALLMV3+xD/Ko60Hqg==} - '@vitest/pretty-format@2.0.2': - resolution: {integrity: sha512-SBCyOXfGVvddRd9r2PwoVR0fonQjh9BMIcBMlSzbcNwFfGr6ZhOhvBzurjvi2F4ryut2HcqiFhNeDVGwru8tLg==} + '@vitest/pretty-format@2.0.3': + resolution: {integrity: sha512-URM4GLsB2xD37nnTyvf6kfObFafxmycCL8un3OC9gaCs5cti2u+5rJdIflZ2fUJUen4NbvF6jCufwViAFLvz1g==} - '@vitest/runner@2.0.2': - resolution: {integrity: sha512-OCh437Vi8Wdbif1e0OvQcbfM3sW4s2lpmOjAE7qfLrpzJX2M7J1IQlNvEcb/fu6kaIB9n9n35wS0G2Q3en5kHg==} + '@vitest/runner@2.0.3': + resolution: {integrity: sha512-EmSP4mcjYhAcuBWwqgpjR3FYVeiA4ROzRunqKltWjBfLNs1tnMLtF+qtgd5ClTwkDP6/DGlKJTNa6WxNK0bNYQ==} - '@vitest/snapshot@2.0.2': - resolution: {integrity: sha512-Yc2ewhhZhx+0f9cSUdfzPRcsM6PhIb+S43wxE7OG0kTxqgqzo8tHkXFuFlndXeDMp09G3sY/X5OAo/RfYydf1g==} + '@vitest/snapshot@2.0.3': + resolution: {integrity: sha512-6OyA6v65Oe3tTzoSuRPcU6kh9m+mPL1vQ2jDlPdn9IQoUxl8rXhBnfICNOC+vwxWY684Vt5UPgtcA2aPFBb6wg==} - '@vitest/spy@2.0.2': - resolution: {integrity: sha512-MgwJ4AZtCgqyp2d7WcQVE8aNG5vQ9zu9qMPYQHjsld/QVsrvg78beNrXdO4HYkP0lDahCO3P4F27aagIag+SGQ==} + '@vitest/spy@2.0.3': + resolution: {integrity: sha512-sfqyAw/ypOXlaj4S+w8689qKM1OyPOqnonqOc9T91DsoHbfN5mU7FdifWWv3MtQFf0lEUstEwR9L/q/M390C+A==} - '@vitest/utils@2.0.2': - resolution: {integrity: sha512-pxCY1v7kmOCWYWjzc0zfjGTA3Wmn8PKnlPvSrsA643P1NHl1fOyXj2Q9SaNlrlFE+ivCsxM80Ov3AR82RmHCWQ==} + '@vitest/utils@2.0.3': + resolution: {integrity: sha512-c/UdELMuHitQbbc/EVctlBaxoYAwQPQdSNwv7z/vHyBKy2edYZaFgptE27BRueZB7eW8po+cllotMNTDpL3HWg==} abbrev@2.0.0: resolution: {integrity: sha512-6/mh1E2u2YgEsCHdY0Yx5oW+61gZU+1vXaoiHHrpKeuRNNgFvS+/jrwHiQhB5apAf5oB7UB7E19ol2R2LKH8hQ==} @@ -1362,8 +1362,8 @@ packages: util-deprecate@1.0.2: resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} - vite-node@2.0.2: - resolution: {integrity: sha512-w4vkSz1Wo+NIQg8pjlEn0jQbcM/0D+xVaYjhw3cvarTanLLBh54oNiRbsT8PNK5GfuST0IlVXjsNRoNlqvY/fw==} + vite-node@2.0.3: + resolution: {integrity: sha512-14jzwMx7XTcMB+9BhGQyoEAmSl0eOr3nrnn+Z12WNERtOvLN+d2scbRUvyni05rT3997Bg+rZb47NyP4IQPKXg==} engines: {node: ^18.0.0 || >=20.0.0} hasBin: true @@ -1395,15 +1395,15 @@ packages: terser: optional: true - vitest@2.0.2: - resolution: {integrity: sha512-WlpZ9neRIjNBIOQwBYfBSr0+of5ZCbxT2TVGKW4Lv0c8+srCFIiRdsP7U009t8mMn821HQ4XKgkx5dVWpyoyLw==} + vitest@2.0.3: + resolution: {integrity: sha512-o3HRvU93q6qZK4rI2JrhKyZMMuxg/JRt30E6qeQs6ueaiz5hr1cPj+Sk2kATgQzMMqsa2DiNI0TIK++1ULx8Jw==} engines: {node: ^18.0.0 || >=20.0.0} hasBin: true peerDependencies: '@edge-runtime/vm': '*' '@types/node': ^18.0.0 || >=20.0.0 - '@vitest/browser': 2.0.2 - '@vitest/ui': 2.0.2 + '@vitest/browser': 2.0.3 + '@vitest/ui': 2.0.3 happy-dom: '*' jsdom: '*' peerDependenciesMeta: @@ -1778,7 +1778,7 @@ snapshots: dependencies: undici-types: 5.26.5 - '@vitest/coverage-v8@2.0.2(vitest@2.0.2(@types/node@20.14.10))': + '@vitest/coverage-v8@2.0.3(vitest@2.0.3(@types/node@20.14.10))': dependencies: '@ampproject/remapping': 2.3.0 '@bcoe/v8-coverage': 0.2.3 @@ -1793,39 +1793,39 @@ snapshots: strip-literal: 2.1.0 test-exclude: 7.0.1 tinyrainbow: 1.2.0 - vitest: 2.0.2(@types/node@20.14.10) + vitest: 2.0.3(@types/node@20.14.10) transitivePeerDependencies: - supports-color - '@vitest/expect@2.0.2': + '@vitest/expect@2.0.3': dependencies: - '@vitest/spy': 2.0.2 - '@vitest/utils': 2.0.2 + '@vitest/spy': 2.0.3 + '@vitest/utils': 2.0.3 chai: 5.1.1 tinyrainbow: 1.2.0 - '@vitest/pretty-format@2.0.2': + '@vitest/pretty-format@2.0.3': dependencies: tinyrainbow: 1.2.0 - '@vitest/runner@2.0.2': + '@vitest/runner@2.0.3': dependencies: - '@vitest/utils': 2.0.2 + '@vitest/utils': 2.0.3 pathe: 1.1.2 - '@vitest/snapshot@2.0.2': + '@vitest/snapshot@2.0.3': dependencies: - '@vitest/pretty-format': 2.0.2 + '@vitest/pretty-format': 2.0.3 magic-string: 0.30.10 pathe: 1.1.2 - '@vitest/spy@2.0.2': + '@vitest/spy@2.0.3': dependencies: tinyspy: 3.0.0 - '@vitest/utils@2.0.2': + '@vitest/utils@2.0.3': dependencies: - '@vitest/pretty-format': 2.0.2 + '@vitest/pretty-format': 2.0.3 estree-walker: 3.0.3 loupe: 3.1.1 tinyrainbow: 1.2.0 @@ -2631,7 +2631,7 @@ snapshots: util-deprecate@1.0.2: {} - vite-node@2.0.2(@types/node@20.14.10): + vite-node@2.0.3(@types/node@20.14.10): dependencies: cac: 6.7.14 debug: 4.3.5 @@ -2657,15 +2657,15 @@ snapshots: '@types/node': 20.14.10 fsevents: 2.3.3 - vitest@2.0.2(@types/node@20.14.10): + vitest@2.0.3(@types/node@20.14.10): dependencies: '@ampproject/remapping': 2.3.0 - '@vitest/expect': 2.0.2 - '@vitest/pretty-format': 2.0.2 - '@vitest/runner': 2.0.2 - '@vitest/snapshot': 2.0.2 - '@vitest/spy': 2.0.2 - '@vitest/utils': 2.0.2 + '@vitest/expect': 2.0.3 + '@vitest/pretty-format': 2.0.3 + '@vitest/runner': 2.0.3 + '@vitest/snapshot': 2.0.3 + '@vitest/spy': 2.0.3 + '@vitest/utils': 2.0.3 chai: 5.1.1 debug: 4.3.5 execa: 8.0.1 @@ -2676,7 +2676,7 @@ snapshots: tinypool: 1.0.0 tinyrainbow: 1.2.0 vite: 5.3.1(@types/node@20.14.10) - vite-node: 2.0.2(@types/node@20.14.10) + vite-node: 2.0.3(@types/node@20.14.10) why-is-node-running: 2.2.2 optionalDependencies: '@types/node': 20.14.10 diff --git a/src/watchman.cpp b/src/watchman.cpp index 87ba715..b9fbfea 100644 --- a/src/watchman.cpp +++ b/src/watchman.cpp @@ -203,12 +203,12 @@ void Watchman::dispatch() { * Prints the watcher tree for debugging. */ void Watchman::printTree() { - std::wstringstream wss(L""); - std::wstring line; - root->print(wss); - while (std::getline(wss, line, L'\n')) { - WLOG_DEBUG("Watchman::printTree", line) - } + // std::wstringstream wss(L""); + // std::wstring line; + // root->print(wss); + // while (std::getline(wss, line, L'\n')) { + // WLOG_DEBUG("Watchman::printTree", line) + // } } /** diff --git a/src/watchnode.cpp b/src/watchnode.cpp index 6cfa5a1..14bd3fb 100644 --- a/src/watchnode.cpp +++ b/src/watchnode.cpp @@ -81,6 +81,8 @@ std::u16string WatchNode::getKey() { /** * Attempts to open this node's registry key and watch it. + * + * Returns true if something changed. */ bool WatchNode::load(CallbackQueue* pending) { bool result = false; @@ -99,8 +101,6 @@ bool WatchNode::load(CallbackQueue* pending) { LOG_DEBUG_1("WatchNode::load", L"\"%ls\" hkey is still valid", name.c_str()) } else { // no longer valid! - LOG_DEBUG_1("WatchNode::load", L"\"%ls\" hkey is no longer valid", name.c_str()) - unload(pending); result = true; } } else { @@ -116,9 +116,7 @@ bool WatchNode::load(CallbackQueue* pending) { } for (auto const& it : subkeys) { - if (it.second->load(pending)) { - result = true; - } + it.second->load(pending); } result = true; @@ -146,6 +144,17 @@ bool WatchNode::onChange() { if (hkey) { if (watch(&pending)) { + // hkey should be valid, check if subkeys are ok + LOG_DEBUG_1("WatchNode::onChange", L"Checking if subkeys under \"%ls\" are still valid", name.c_str()) + for (auto const& it : subkeys) { + HKEY tmp; + LSTATUS status = ::RegOpenKeyW(hkey, it.second->name.c_str(), &tmp); + if (status != ERROR_SUCCESS) { + LOG_DEBUG_1("WatchNode::onChange", L"\"%ls\" hkey is no longer valid", it.second->name.c_str()) + it.second->unload(&pending); + } + } + PUSH_CALLBACK(pending, "change", getKey(), listeners) } @@ -240,6 +249,7 @@ void WatchNode::removeListener(napi_value listener) { * Closes this node's registry key handle and its subkey's key handles. */ void WatchNode::unload(CallbackQueue* pending) { + LOG_DEBUG_1("WatchNode::unload", L"Checking subkeys under \"%ls\" hkey", name.c_str()) for (auto const& it : subkeys) { it.second->unload(pending); } @@ -257,7 +267,9 @@ void WatchNode::unload(CallbackQueue* pending) { } /** - * Wires up the change notification event. + * Wires up the Windows Registry change notification event asynchronously. + * + * Returns true if the key is valid and the watcher was successfully registered. */ bool WatchNode::watch(CallbackQueue* pending) { if (hkey) { diff --git a/test/watch.test.ts b/test/watch.test.ts index f6ea116..5d81972 100644 --- a/test/watch.test.ts +++ b/test/watch.test.ts @@ -68,7 +68,7 @@ describe('watch()', () => { reject(e); } }); - setTimeout(() => reg('add', 'HKCU\\Software\\winreglib\\foo'), 500); + setTimeout(() => reg('add', 'HKCU\\Software\\winreglib\\foo'), 250); }); handle.stop(); @@ -134,7 +134,7 @@ describe('watch()', () => { '/d', 'bar' ), - 500 + 250 ); }); } finally { @@ -194,7 +194,7 @@ describe('watch()', () => { }); setTimeout( () => reg('delete', 'HKCU\\Software\\winreglib\\foo', '/f'), - 500 + 250 ); break; case 3: @@ -204,7 +204,7 @@ describe('watch()', () => { }); setTimeout( () => reg('add', 'HKCU\\Software\\winreglib\\foo'), - 500 + 250 ); break; case 4: @@ -219,7 +219,7 @@ describe('watch()', () => { reject(e); } }); - setTimeout(() => reg('add', 'HKCU\\Software\\winreglib\\foo'), 500); + setTimeout(() => reg('add', 'HKCU\\Software\\winreglib\\foo'), 250); }); } finally { handle.stop(); @@ -289,7 +289,7 @@ describe('watch()', () => { '/d', 'hello3' ); - }, 1000); + }, 250); break; case 2: expect(evt).toMatchObject({ @@ -298,7 +298,7 @@ describe('watch()', () => { }); setTimeout(() => { reg('delete', 'HKCU\\Software\\winreglib', '/f'); - }, 1000); + }, 250); break; case 3: expect(evt).toMatchObject({ @@ -313,10 +313,10 @@ describe('watch()', () => { } }); - setTimeout(() => reg('add', 'HKCU\\Software\\winreglib\\foo'), 500); + setTimeout(() => reg('add', 'HKCU\\Software\\winreglib\\foo'), 250); setTimeout( () => reg('add', 'HKCU\\Software\\winreglib\\foo\\bar\\baz\\wiz'), - 2000 + 250 ); }); } finally { @@ -354,7 +354,7 @@ describe('watch()', () => { }); setTimeout( () => reg('delete', 'HKCU\\Software\\winreglib\\foo', '/f'), - 500 + 250 ); }); handle.stop(); @@ -398,7 +398,7 @@ describe('watch()', () => { }); setTimeout( () => reg('delete', 'HKCU\\Software\\winreglib\\foo', '/f'), - 500 + 250 ); }); handle.stop(); @@ -410,7 +410,7 @@ describe('watch()', () => { } ); - it.only('should survive the gauntlet', { timeout: 15000 }, async () => { + it('should survive the gauntlet', { timeout: 150000 }, async () => { reg('delete', 'HKCU\\Software\\winreglib', '/f'); reg('add', 'HKCU\\Software\\winreglib'); @@ -452,17 +452,17 @@ describe('watch()', () => { reg('delete', 'HKCU\\Software\\winreglib\\foo\\bar', '/f'); break; case 3: - expect(handleName).toBe('fooHandle'); + expect(handleName).toBe('barHandle'); expect(evt).toMatchObject({ - type: 'change', - key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib\\foo' + type: 'delete', + key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib\\foo\\bar' }); break; case 4: - expect(handleName).toBe('barHandle'); + expect(handleName).toBe('fooHandle'); expect(evt).toMatchObject({ - type: 'delete', - key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib\\foo\\bar' + type: 'change', + key: 'HKEY_CURRENT_USER\\SOFTWARE\\winreglib\\foo' }); reg( 'add', @@ -578,7 +578,7 @@ describe('watch()', () => { bazHandle.on('change', evt => fn(evt, 'bazHandle')); setTimeout( () => reg('add', 'HKCU\\Software\\winreglib\\foo\\bar'), - 500 + 250 ); }); } finally { From 03d53f996bfe1738764a27d254d730cfc500eaf6 Mon Sep 17 00:00:00 2001 From: Chris Barber Date: Tue, 16 Jul 2024 01:19:04 -0500 Subject: [PATCH 11/27] Cleanup --- CHANGELOG.md | 12 +++++++++--- src/watchman.cpp | 14 ++++++++------ src/watchman.h | 1 - src/watchnode.cpp | 1 - 4 files changed, 17 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3cc114e..2db4470 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,14 @@ # v3.0.0 - * BREAKING CHANGE: Require Node.js 18.17 or newer - * feat: Support for arm/arm64 - * fix: Fixed order of child key events when parent key is deleted + * BREAKING CHANGE: Require Node.js 18.17 or newer. + * feat: Support for arm/arm64. + * fix: Fixed order of child key events when parent key is deleted. + * fix: Fixed seg fault during cleanup that occurs when using winreglib in a + worker. + * fix: Fixed bug where the Windows Registry worker thread was being spawned + when adding the first listener. The idea was don't spawn the thread until + there was a listener, however thread shutdown is async and not worth the + hassle in a destructor, so now the background thread is always running. # v2.0.4 (July 2, 2024) diff --git a/src/watchman.cpp b/src/watchman.cpp index b9fbfea..04fd4aa 100644 --- a/src/watchman.cpp +++ b/src/watchman.cpp @@ -159,6 +159,8 @@ void Watchman::config(const std::wstring& key, napi_value listener, WatchAction } } + // if we have any active listeners and the number of listeners changed, + // then signal the refresh if (afterCount > 0 && beforeCount != afterCount) { LOG_DEBUG_THREAD_ID("Watchman::config", L"Signaling refresh event") ::SetEvent(refresh); @@ -203,12 +205,12 @@ void Watchman::dispatch() { * Prints the watcher tree for debugging. */ void Watchman::printTree() { - // std::wstringstream wss(L""); - // std::wstring line; - // root->print(wss); - // while (std::getline(wss, line, L'\n')) { - // WLOG_DEBUG("Watchman::printTree", line) - // } + std::wstringstream wss(L""); + std::wstring line; + root->print(wss); + while (std::getline(wss, line, L'\n')) { + WLOG_DEBUG("Watchman::printTree", line) + } } /** diff --git a/src/watchman.h b/src/watchman.h index bb563cd..08bcdc6 100644 --- a/src/watchman.h +++ b/src/watchman.h @@ -4,7 +4,6 @@ #include "winreglib.h" #include "watchnode.h" #include -#include #include #include #include diff --git a/src/watchnode.cpp b/src/watchnode.cpp index 14bd3fb..9ed7409 100644 --- a/src/watchnode.cpp +++ b/src/watchnode.cpp @@ -249,7 +249,6 @@ void WatchNode::removeListener(napi_value listener) { * Closes this node's registry key handle and its subkey's key handles. */ void WatchNode::unload(CallbackQueue* pending) { - LOG_DEBUG_1("WatchNode::unload", L"Checking subkeys under \"%ls\" hkey", name.c_str()) for (auto const& it : subkeys) { it.second->unload(pending); } From 79b2da29067b04a2be5c6fbf61d39be3a22844fb Mon Sep 17 00:00:00 2001 From: Chris Barber Date: Tue, 16 Jul 2024 01:39:17 -0500 Subject: [PATCH 12/27] Fix get 64-bit value test --- test/get.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/get.test.ts b/test/get.test.ts index e20a2d0..91caaac 100644 --- a/test/get.test.ts +++ b/test/get.test.ts @@ -98,8 +98,8 @@ describe('get()', () => { it('should get an 64-bit integer value', () => { const value = winreglib.get( - 'HKLM\\Software\\Microsoft\\Windows\\CurrentVersion\\Diagnostics\\DiagTrack', - 'TriggerCount' + 'HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Notifications', + 'TimestampWhenSeen' ) as number; expect(value).toBeTypeOf('number'); expect(value).toBeGreaterThanOrEqual(0); From 6b593b45454c815eb2b938f0d17ca8de4a2bbe45 Mon Sep 17 00:00:00 2001 From: Chris Barber Date: Tue, 16 Jul 2024 01:55:06 -0500 Subject: [PATCH 13/27] Debug logging --- test/get.test.ts | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/test/get.test.ts b/test/get.test.ts index 91caaac..d18830c 100644 --- a/test/get.test.ts +++ b/test/get.test.ts @@ -97,9 +97,17 @@ describe('get()', () => { }); it('should get an 64-bit integer value', () => { + spawnSync( + 'reg', + [ + 'query', + 'HKLMSoftwareMicrosoftWindowsCurrentVersionDiagnosticsDiagTrack' + ], + { stdio: 'inherit' } + ); const value = winreglib.get( - 'HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Notifications', - 'TimestampWhenSeen' + 'HKLM\\Software\\Microsoft\\Windows\\CurrentVersion\\Diagnostics\\DiagTrack', + 'TriggerCount' ) as number; expect(value).toBeTypeOf('number'); expect(value).toBeGreaterThanOrEqual(0); From 7d555b6c15a5ca21c7ce3164ea74a8c420bfccfb Mon Sep 17 00:00:00 2001 From: Chris Barber Date: Tue, 16 Jul 2024 02:12:35 -0500 Subject: [PATCH 14/27] Fixed key name --- test/get.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/get.test.ts b/test/get.test.ts index d18830c..f7f0c84 100644 --- a/test/get.test.ts +++ b/test/get.test.ts @@ -101,7 +101,7 @@ describe('get()', () => { 'reg', [ 'query', - 'HKLMSoftwareMicrosoftWindowsCurrentVersionDiagnosticsDiagTrack' + 'HKLM\\Software\\Microsoft\\Windows\\CurrentVersion\\Diagnostics\\DiagTrack' ], { stdio: 'inherit' } ); From 51639d9278a4935b4e8948b4107fbd781c701e6a Mon Sep 17 00:00:00 2001 From: Chris Barber Date: Tue, 16 Jul 2024 02:19:42 -0500 Subject: [PATCH 15/27] Trying another key --- test/get.test.ts | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/test/get.test.ts b/test/get.test.ts index f7f0c84..2a84b5a 100644 --- a/test/get.test.ts +++ b/test/get.test.ts @@ -101,16 +101,15 @@ describe('get()', () => { 'reg', [ 'query', - 'HKLM\\Software\\Microsoft\\Windows\\CurrentVersion\\Diagnostics\\DiagTrack' + 'HKLM\\Software\\Microsoft\\Windows\\CurrentVersion\\Diagnostics\\DiagTrack\\TraceManager' ], { stdio: 'inherit' } ); const value = winreglib.get( - 'HKLM\\Software\\Microsoft\\Windows\\CurrentVersion\\Diagnostics\\DiagTrack', - 'TriggerCount' + 'HKLM\\Software\\Microsoft\\Windows\\CurrentVersion\\Diagnostics\\DiagTrack\\TraceManager', + 'diagStartTime' ) as number; expect(value).toBeTypeOf('number'); - expect(value).toBeGreaterThanOrEqual(0); }); it('should get a binary value', () => { From 05a6d6f05e4c73b83f0fd0c5555b5de4ae593345 Mon Sep 17 00:00:00 2001 From: Chris Barber Date: Tue, 16 Jul 2024 02:32:02 -0500 Subject: [PATCH 16/27] Brute force --- test/get.test.ts | 33 ++++++++++++++++++++++++--------- 1 file changed, 24 insertions(+), 9 deletions(-) diff --git a/test/get.test.ts b/test/get.test.ts index 2a84b5a..2d3d1b6 100644 --- a/test/get.test.ts +++ b/test/get.test.ts @@ -2,6 +2,7 @@ import fs from 'node:fs'; import { describe, expect, it } from 'vitest'; import winreglib from '../src/index.js'; const { spawnSync } = require('node:child_process'); +import { spawn } from 'node:child_process'; import snooplogg from 'snooplogg'; const { log } = snooplogg('test:winreglib'); @@ -96,15 +97,29 @@ describe('get()', () => { expect(value).toBeGreaterThanOrEqual(0); }); - it('should get an 64-bit integer value', () => { - spawnSync( - 'reg', - [ - 'query', - 'HKLM\\Software\\Microsoft\\Windows\\CurrentVersion\\Diagnostics\\DiagTrack\\TraceManager' - ], - { stdio: 'inherit' } - ); + it('should get an 64-bit integer value', async () => { + await new Promise(resolve => { + const child = spawn( + 'reg', + ['query', 'HKLM\\Software\\Microsoft\\Windows\\CurrentVersion', '/s'], + { stdio: 'pipe' } + ); + let buffer = ''; + child.stdout.on('data', data => { + buffer += data.toString(); + }); + child.on('close', () => { + const chunks = buffer.split('\n\n'); + for (const chunk of chunks) { + if (chunk.includes('REG_QWORD')) { + console.log('-'.repeat(80)); + console.log(chunk); + console.log('-'.repeat(80)); + } + } + resolve(); + }); + }); const value = winreglib.get( 'HKLM\\Software\\Microsoft\\Windows\\CurrentVersion\\Diagnostics\\DiagTrack\\TraceManager', 'diagStartTime' From 5281c65c0a906b690f92e6a0261bde8dd378c51b Mon Sep 17 00:00:00 2001 From: Chris Barber Date: Tue, 16 Jul 2024 02:32:50 -0500 Subject: [PATCH 17/27] Only test node 20 --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 7941a8c..5f8461e 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -9,7 +9,7 @@ jobs: strategy: fail-fast: false matrix: - node: [18, 20, 22] + node: [20] steps: - name: Checkout repository From ffeedf16e977b0c6b05e8695425249ce2692a971 Mon Sep 17 00:00:00 2001 From: Chris Barber Date: Tue, 16 Jul 2024 02:40:41 -0500 Subject: [PATCH 18/27] timeouts --- test/get.test.ts | 2 +- test/watch.test.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/test/get.test.ts b/test/get.test.ts index 2d3d1b6..652bb40 100644 --- a/test/get.test.ts +++ b/test/get.test.ts @@ -97,7 +97,7 @@ describe('get()', () => { expect(value).toBeGreaterThanOrEqual(0); }); - it('should get an 64-bit integer value', async () => { + it('should get an 64-bit integer value', { timeout: 60000 }, async () => { await new Promise(resolve => { const child = spawn( 'reg', diff --git a/test/watch.test.ts b/test/watch.test.ts index 5d81972..956905b 100644 --- a/test/watch.test.ts +++ b/test/watch.test.ts @@ -410,7 +410,7 @@ describe('watch()', () => { } ); - it('should survive the gauntlet', { timeout: 150000 }, async () => { + it('should survive the gauntlet', { timeout: 15000 }, async () => { reg('delete', 'HKCU\\Software\\winreglib', '/f'); reg('add', 'HKCU\\Software\\winreglib'); From 372135eb864ef85d4ad2c0a41ec446abbf26f888 Mon Sep 17 00:00:00 2001 From: Chris Barber Date: Tue, 16 Jul 2024 02:50:03 -0500 Subject: [PATCH 19/27] timeouts again --- test/get.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/get.test.ts b/test/get.test.ts index 652bb40..37ff4f9 100644 --- a/test/get.test.ts +++ b/test/get.test.ts @@ -97,7 +97,7 @@ describe('get()', () => { expect(value).toBeGreaterThanOrEqual(0); }); - it('should get an 64-bit integer value', { timeout: 60000 }, async () => { + it('should get an 64-bit integer value', { timeout: 360000 }, async () => { await new Promise(resolve => { const child = spawn( 'reg', From 210ba7ec7640929c02d319621e290c9ca69f9ae4 Mon Sep 17 00:00:00 2001 From: Chris Barber Date: Tue, 16 Jul 2024 03:00:41 -0500 Subject: [PATCH 20/27] new tactic --- test/get.test.ts | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/test/get.test.ts b/test/get.test.ts index 37ff4f9..1634dca 100644 --- a/test/get.test.ts +++ b/test/get.test.ts @@ -99,24 +99,20 @@ describe('get()', () => { it('should get an 64-bit integer value', { timeout: 360000 }, async () => { await new Promise(resolve => { + console.log('-'.repeat(80)); const child = spawn( 'reg', ['query', 'HKLM\\Software\\Microsoft\\Windows\\CurrentVersion', '/s'], { stdio: 'pipe' } ); - let buffer = ''; child.stdout.on('data', data => { - buffer += data.toString(); + const s = data.toString(); + if (s.includes('REG_QWORD')) { + console.log(s); + } }); child.on('close', () => { - const chunks = buffer.split('\n\n'); - for (const chunk of chunks) { - if (chunk.includes('REG_QWORD')) { - console.log('-'.repeat(80)); - console.log(chunk); - console.log('-'.repeat(80)); - } - } + console.log('-'.repeat(80)); resolve(); }); }); From 5fc6bdffb59197e88e09ccefd38844845d60841e Mon Sep 17 00:00:00 2001 From: Chris Barber Date: Tue, 16 Jul 2024 03:11:59 -0500 Subject: [PATCH 21/27] Try again --- test/get.test.ts | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/test/get.test.ts b/test/get.test.ts index 1634dca..ecc8e3f 100644 --- a/test/get.test.ts +++ b/test/get.test.ts @@ -99,20 +99,25 @@ describe('get()', () => { it('should get an 64-bit integer value', { timeout: 360000 }, async () => { await new Promise(resolve => { - console.log('-'.repeat(80)); const child = spawn( 'reg', ['query', 'HKLM\\Software\\Microsoft\\Windows\\CurrentVersion', '/s'], { stdio: 'pipe' } ); + const buffer: string[] = []; child.stdout.on('data', data => { const s = data.toString(); + if (buffer.length > 10) { + buffer.unshift(); + } + buffer.push(s); if (s.includes('REG_QWORD')) { - console.log(s); + console.log('-'.repeat(80)); + console.log(buffer.join('\n')); + console.log('-'.repeat(80)); } }); child.on('close', () => { - console.log('-'.repeat(80)); resolve(); }); }); From 4ee15231d5147e45e0a68bc8c52b7c38a413c7af Mon Sep 17 00:00:00 2001 From: Chris Barber Date: Tue, 16 Jul 2024 03:40:18 -0500 Subject: [PATCH 22/27] Found a key --- test/get.test.ts | 31 ++++--------------------------- 1 file changed, 4 insertions(+), 27 deletions(-) diff --git a/test/get.test.ts b/test/get.test.ts index ecc8e3f..70f0164 100644 --- a/test/get.test.ts +++ b/test/get.test.ts @@ -2,7 +2,6 @@ import fs from 'node:fs'; import { describe, expect, it } from 'vitest'; import winreglib from '../src/index.js'; const { spawnSync } = require('node:child_process'); -import { spawn } from 'node:child_process'; import snooplogg from 'snooplogg'; const { log } = snooplogg('test:winreglib'); @@ -97,35 +96,13 @@ describe('get()', () => { expect(value).toBeGreaterThanOrEqual(0); }); - it('should get an 64-bit integer value', { timeout: 360000 }, async () => { - await new Promise(resolve => { - const child = spawn( - 'reg', - ['query', 'HKLM\\Software\\Microsoft\\Windows\\CurrentVersion', '/s'], - { stdio: 'pipe' } - ); - const buffer: string[] = []; - child.stdout.on('data', data => { - const s = data.toString(); - if (buffer.length > 10) { - buffer.unshift(); - } - buffer.push(s); - if (s.includes('REG_QWORD')) { - console.log('-'.repeat(80)); - console.log(buffer.join('\n')); - console.log('-'.repeat(80)); - } - }); - child.on('close', () => { - resolve(); - }); - }); + it('should get an 64-bit integer value', async () => { const value = winreglib.get( - 'HKLM\\Software\\Microsoft\\Windows\\CurrentVersion\\Diagnostics\\DiagTrack\\TraceManager', - 'diagStartTime' + 'HKLM\\Software\\Microsoft\\Windows\\CurrentVersion\\AppModel\\StateRepositoryStatus', + 'MaintenanceLastPerformed' ) as number; expect(value).toBeTypeOf('number'); + expect(value).toBeGreaterThan(0); }); it('should get a binary value', () => { From 49b9e23317fe0e90a1507d0623e7a0b9e77e5c40 Mon Sep 17 00:00:00 2001 From: Chris Barber Date: Tue, 16 Jul 2024 03:46:34 -0500 Subject: [PATCH 23/27] Re-enable node 18 and 22 --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 5f8461e..7941a8c 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -9,7 +9,7 @@ jobs: strategy: fail-fast: false matrix: - node: [20] + node: [18, 20, 22] steps: - name: Checkout repository From 04001053ea43cb3cda0c072ddcbbce4fe4316b93 Mon Sep 17 00:00:00 2001 From: Chris Barber Date: Tue, 16 Jul 2024 23:19:31 -0500 Subject: [PATCH 24/27] Update deps --- .github/workflows/test.yml | 4 ++++ CHANGELOG.md | 1 - package.json | 4 ++-- pnpm-lock.yaml | 44 +++++++++++++++++++------------------- 4 files changed, 28 insertions(+), 25 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 7941a8c..a7359e8 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -2,6 +2,10 @@ name: Tests on: [push, pull_request] +concurrency: + cancel-in-progress: ${{ github.event_name == 'pull_request' }} + group: ${{ github.workflow }}-${{ github.ref }} + jobs: test: name: Test on node ${{ matrix.node }} diff --git a/CHANGELOG.md b/CHANGELOG.md index 2db4470..8831c0c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,6 @@ # v3.0.0 * BREAKING CHANGE: Require Node.js 18.17 or newer. - * feat: Support for arm/arm64. * fix: Fixed order of child key events when parent key is deleted. * fix: Fixed seg fault during cleanup that occurs when using winreglib in a worker. diff --git a/package.json b/package.json index d0d0e73..9b81021 100644 --- a/package.json +++ b/package.json @@ -43,12 +43,12 @@ "napi-macros": "2.2.2", "node-gyp": "10.2.0", "node-gyp-build": "4.8.1", - "snooplogg": "6.0.0-rc.1" + "snooplogg": "6.0.0" }, "devDependencies": { "@biomejs/biome": "1.8.3", "@rollup/plugin-typescript": "11.1.6", - "@types/node": "20.14.10", + "@types/node": "20.14.11", "@vitest/coverage-v8": "2.0.3", "esbuild": "0.23.0", "lefthook": "1.7.2", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 2e066ca..938e087 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -23,8 +23,8 @@ importers: specifier: 4.8.1 version: 4.8.1(patch_hash=4v3havyznpg2abqwiszfjnuita) snooplogg: - specifier: 6.0.0-rc.1 - version: 6.0.0-rc.1 + specifier: 6.0.0 + version: 6.0.0 devDependencies: '@biomejs/biome': specifier: 1.8.3 @@ -33,11 +33,11 @@ importers: specifier: 11.1.6 version: 11.1.6(rollup@4.18.1)(tslib@2.6.3)(typescript@5.5.3) '@types/node': - specifier: 20.14.10 - version: 20.14.10 + specifier: 20.14.11 + version: 20.14.11 '@vitest/coverage-v8': specifier: 2.0.3 - version: 2.0.3(vitest@2.0.3(@types/node@20.14.10)) + version: 2.0.3(vitest@2.0.3(@types/node@20.14.11)) esbuild: specifier: 0.23.0 version: 0.23.0 @@ -67,7 +67,7 @@ importers: version: 5.5.3 vitest: specifier: 2.0.3 - version: 2.0.3(@types/node@20.14.10) + version: 2.0.3(@types/node@20.14.11) packages: @@ -581,8 +581,8 @@ packages: '@types/estree@1.0.5': resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==} - '@types/node@20.14.10': - resolution: {integrity: sha512-MdiXf+nDuMvY0gJKxyfZ7/6UFsETO7mGKF54MVD/ekJS6HdFtpZFBgrh6Pseu64XTb2MLyFPlbW6hj8HYRQNOQ==} + '@types/node@20.14.11': + resolution: {integrity: sha512-kprQpL8MMeszbz6ojB5/tU8PLN4kesnN8Gjzw349rDlNgsSzg90lAVj3llK99Dh7JON+t9AuscPPFW6mPbTnSA==} '@vitest/coverage-v8@2.0.3': resolution: {integrity: sha512-53d+6jXFdYbasXBmsL6qaGIfcY5eBQq0sP57AjdasOcSiGNj4qxkkpDKIitUNfjxcfAfUfQ8BD0OR2fSey64+g==} @@ -1239,8 +1239,8 @@ packages: resolution: {integrity: sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==} engines: {node: '>= 6.0.0', npm: '>= 3.0.0'} - snooplogg@6.0.0-rc.1: - resolution: {integrity: sha512-bSMEYqOYV/9NWx1+EPjcNfGxJDgKoKc/t/bswimlWLuQFahOnvpPQNe2gFr64jyaHslxZTgzO0lqmwxTvBuWPA==} + snooplogg@6.0.0: + resolution: {integrity: sha512-lzRh5OBbg6mRs94QhCY6UbUVX84rlupvXTfGEeRCEkZmDp3jMf6vGPSVoZ93n3YeUloWSKlWZA81IULVP22GnQ==} engines: {node: '>=18.17'} socks-proxy-agent@8.0.4: @@ -1774,11 +1774,11 @@ snapshots: '@types/estree@1.0.5': {} - '@types/node@20.14.10': + '@types/node@20.14.11': dependencies: undici-types: 5.26.5 - '@vitest/coverage-v8@2.0.3(vitest@2.0.3(@types/node@20.14.10))': + '@vitest/coverage-v8@2.0.3(vitest@2.0.3(@types/node@20.14.11))': dependencies: '@ampproject/remapping': 2.3.0 '@bcoe/v8-coverage': 0.2.3 @@ -1793,7 +1793,7 @@ snapshots: strip-literal: 2.1.0 test-exclude: 7.0.1 tinyrainbow: 1.2.0 - vitest: 2.0.3(@types/node@20.14.10) + vitest: 2.0.3(@types/node@20.14.11) transitivePeerDependencies: - supports-color @@ -2507,7 +2507,7 @@ snapshots: smart-buffer@4.2.0: {} - snooplogg@6.0.0-rc.1: {} + snooplogg@6.0.0: {} socks-proxy-agent@8.0.4: dependencies: @@ -2631,13 +2631,13 @@ snapshots: util-deprecate@1.0.2: {} - vite-node@2.0.3(@types/node@20.14.10): + vite-node@2.0.3(@types/node@20.14.11): dependencies: cac: 6.7.14 debug: 4.3.5 pathe: 1.1.2 tinyrainbow: 1.2.0 - vite: 5.3.1(@types/node@20.14.10) + vite: 5.3.1(@types/node@20.14.11) transitivePeerDependencies: - '@types/node' - less @@ -2648,16 +2648,16 @@ snapshots: - supports-color - terser - vite@5.3.1(@types/node@20.14.10): + vite@5.3.1(@types/node@20.14.11): dependencies: esbuild: 0.21.5 postcss: 8.4.38 rollup: 4.18.1 optionalDependencies: - '@types/node': 20.14.10 + '@types/node': 20.14.11 fsevents: 2.3.3 - vitest@2.0.3(@types/node@20.14.10): + vitest@2.0.3(@types/node@20.14.11): dependencies: '@ampproject/remapping': 2.3.0 '@vitest/expect': 2.0.3 @@ -2675,11 +2675,11 @@ snapshots: tinybench: 2.8.0 tinypool: 1.0.0 tinyrainbow: 1.2.0 - vite: 5.3.1(@types/node@20.14.10) - vite-node: 2.0.3(@types/node@20.14.10) + vite: 5.3.1(@types/node@20.14.11) + vite-node: 2.0.3(@types/node@20.14.11) why-is-node-running: 2.2.2 optionalDependencies: - '@types/node': 20.14.10 + '@types/node': 20.14.11 transitivePeerDependencies: - less - lightningcss From 6568597a4bdc307fab8ffa1951c3b973cb7a7e36 Mon Sep 17 00:00:00 2001 From: Chris Barber Date: Thu, 18 Jul 2024 02:16:17 -0500 Subject: [PATCH 25/27] Clean up readme, only prebuild x64 and ia32 --- README.md | 161 ++++++++++++++++++++++++++++++++----------- media/winreglib.webp | Bin 0 -> 25388 bytes package.json | 2 +- src/index.ts | 8 +-- 4 files changed, 127 insertions(+), 44 deletions(-) create mode 100644 media/winreglib.webp diff --git a/README.md b/README.md index 3141872..b2bf989 100644 --- a/README.md +++ b/README.md @@ -1,33 +1,37 @@ -# Windows Registry Utility Library +
+
+ winreglib +
+
-A library for querying and watching the Windows Registry. +`winreglib` is a native C++ addon for Node.js for querying and watching Windows +Registry keys. It provides a read-only, synchronous API for accessing the +Windows Registry. -## Prerequisites +## Features -`winreglib` requires N-API version 3 and the following Node.js versions: + - Get, list, and watch registry keys _without_ spawning `reg.exe` + - Written in TypeScript + - Packaged as an ESM module + - Supports x64 (64-bit) and ia32 (32-bit) CPU architectures -* v10.2.0 or newer +## Requirements -## Installation - - npm install winreglib - -## Introduction - -`winreglib` is a native Node.js addon for querying the Windows Registry. The API is synchronous. - -Currently `winreglib` only supports read operations. It can support write operations someday if -need and time exists. +`winreglib` requires Node.js >=18.17.0 (Node-API 8) and ships with pre-built +binaries for x64 and ia32 architectures. ARM-based architectures are not +officially supported, but should technically work as long as you have the +build tools installed. ## Example -```js +```javascript import winreglib from 'winreglib'; const key = 'HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion'; const results = winreglib.list(key); -console.log(`${results.root}\\${results.path}`); +console.log(`Resolved ${results.resolvedRoot}`); +console.log(`${results.key} has ${results.subkeys.length} subkeys`); console.log(' Subkeys:'); for (const subkey of results.subkeys) { @@ -40,6 +44,20 @@ for (const valueName of results.values) { } ``` +## Supported Root Keys + +| Name | Abbreviation | +| ---------------------------------- | ------------ | +| `HKEY_CLASSES_ROOT` | `HKCR` | +| `HKEY_CURRENT_CONFIG` | `HKCC` | +| `HKEY_CURRENT_USER` | `HKCU` | +| `HKEY_CURRENT_USER_LOCAL_SETTINGS` | | +| `HKEY_LOCAL_MACHINE` | `HKLM` | +| `HKEY_PERFORMANCE_DATA` | | +| `HKEY_PERFORMANCE_NLSTEXT` | | +| `HKEY_PERFORMANCE_TEXT` | | +| `HKEY_USERS` | `HKU` | + ## API ### `get(key, valueName)` @@ -51,12 +69,16 @@ Get a value for the given key and value name. | `key` | String | The key beginning with the root. | | `valueName` | String | The name of the value to get. | -Returns a `String`, `Number`, `Buffer`, `Array.`, or `null` depending on the value. +Returns a `String`, `Number`, `Buffer`, `Array.`, or `null` +depending on the value. If `key` or `valueName` is not found, an `Error` is thrown. ```js -const value = winreglib.get('HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion', 'ProgramFilesDir'); +const value = winreglib.get( + 'HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion', + 'ProgramFilesDir' +); console.log(value); ``` @@ -73,20 +95,31 @@ Retreives all subkeys and value names for a give key. | -------- | ------ | -------------------------------- | | `key` | String | The key beginning with the root. | -Returns an `Object` with the resolved `resolvedRoot` (String), `key` (String), `subkeys` -(Array[String]), and `values` (Array[String]). +Returns an `RegistryKey` object: + +``` +type RegistryKey = { + resolvedRoot: string; + key: string; + subkeys: string[]; + values: unknown[]; +}; +``` If `key` is not found, an `Error` is thrown. ```js -const result = winreglib.list('HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Setup'); +const result = winreglib.list( + 'HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Setup +); console.log(result); ``` ```js { resolvedRoot: 'HKEY_LOCAL_MACHINE', - key: 'HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Setup', + key: + 'HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Setup', subkeys: [ 'DPI', 'ImageServicingData', @@ -109,8 +142,8 @@ Watches a key for changes in subkeys or values. | -------- | ------ | -------------------------------- | | `key` | String | The key beginning with the root. | -Returns a handle (`EventEmitter`) that emits `"change"` events. Call `handle.stop()` to stop watching -the key. +Returns a handle (`WinRegLibWatchHandle` which extends `EventEmitter`) that +emits `"change"` events. Call `handle.stop()` to stop watching the key. ```js const handle = winreglib.watch('HKLM\\SOFTWARE'); @@ -120,7 +153,8 @@ handle.on('change', evt => { }); ``` -The `"change"` event object contains a change `"type"` and the affected `"key"`. +The `"change"` event object contains a change `"type"` and the affected +`"key"`. | Event Type | Description | | ---------- | ---------------------------------- | @@ -128,34 +162,83 @@ The `"change"` event object contains a change `"type"` and the affected `"key"`. | `change` | A subkey or value was added, changed, deleted, or permissions modified, but we don't know exactly what. | | `delete` | The `key` was deleted. | -`watch()` can track keys that do not exist and when they are created, a change event will be -emitted. You can watch the same key multiple times, however each returned handle is unique and you -must call `handle.stop()` for each. +`watch()` can track keys that do not exist and when they are created, a +change event will be emitted. You can watch the same key multiple times, +however each returned handle is unique and you must call `handle.stop()` for +each. -Due to limitations of the Win32 API, `watch()` is unable to determine what actually changed during -a `change` event type. You will need to call `list()` and cache the subkeys and values, then call -`list()` again when a change is emitted and compare the before and after. +Due to limitations of the Win32 API, `watch()` is unable to determine what +actually changed during a `change` event type. You will need to call `list()` +and cache the subkeys and values, then call `list()` again when a change is +emitted and compare the before and after. -Note that `watch()` does not support recursively watching for changes. +Note that `watch()` does not support recursively watching for changes. The +Win32 API does support recursive watching, so this could be added in the +future. ## Advanced ### Debug Logging -`winreglib` exposes an event emitter that emits debug log messages. This is intended to help debug -issues under the hood. The average user will never need to use this, however it would be handy when -filing a bug. +`winreglib` exposes an event emitter that emits debug log messages. This is +intended to help debug issues under the hood. The average user will never +need to use this, however it would be handy when filing a bug. ```js winreglib.on('log', msg => console.log(msg)); ``` -Alternatively, `winreglib` uses the amazing [`snooplogg`][2] debug logger where you simply set the -`SNOOPLOGG` environment variable to `winreglib` (or `*`) and it will print the debug log to stdout. +Alternatively, `winreglib` uses the amazing [`snooplogg`][2] debug logger +where you simply set the `SNOOPLOGG` environment variable to `winreglib` (or +`*`) and it will print the debug log to `stderr`. + +```bash +$ SNOOPLOGG=winreglib node myapp.js + 6.150s winreglib:Watchman Initializing async work (thread 16764576586047274673) + 6.150s winreglib:Watchman::run Initializing run loop (thread 12502165600786624632) + 6.151s winreglib:Watchman::run Populating active copy (count=0) + 6.151s winreglib:Watchman::run Waiting on 2 objects... + 6.152s winreglib:list key="HKLM" subkey="SOFTWARE\Microsoft\Windows\CurrentVersion" + 6.152s winreglib:list 170 keys (max 30), 11 values (max 24) +``` + +### Building `winreglib` + +`winreglib` has two components: the public interface written in TypeScript and +the native addon written in C++. + +To compile the C++ code, you will need the Microsoft Visual Studio (not VSCode) +or the Microsoft Build Tools. You may also need Python 3 installed. + +| Command | Description | +| -------------------- | ----------- | +| `pnpm build` | Compiles the TypeScript and the Node.js native C++ addon for the current architecture | +| `pnpm build:bundle` | Compiles only the TypeScript code | +| `pnpm build:local` | Compiles only the Node.js native C++ addon | +| `pnpm rebuild:local` | Cleans and re-compiles only the Node.js native C++ addon | + +When publishing, the native C++ addon is prebuilt for x64 and ia32 +architectures. Generally you shouldn't need be concerned with the prebuilt +binaries, however the following commands will compile the prebuilds: + +| Command | Description | +| --------------------- | ------------------------------ | +| `pnpm build:prebuild` | Prebuild for x64 and ia32 | +| `pnpm prebuild-arm` | Prebuild for arm (32-bit) | +| `pnpm prebuild-arm64` | Prebuild for arm64 | +| `pnpm prebuild-ia32` | Prebuild for ia32 (x86 32-bit) | +| `pnpm prebuild-x64` | Prebuild for x64 | + +### Architecture + +When `winreglib` is imported, it immediately spawns a background thread in the +event the app is going to watch a key. If a key is added/changed/deleted, the +background thread sends a message to the main thread which emits the change +event. ## Legal Titanium is a registered trademark of TiDev Inc. All Titanium trademark and patent rights were transferred and assigned to TiDev Inc. on 4/7/2022. Please see the LEGAL information about using our trademarks, privacy policy, terms of usage and other legal information at https://tidev.io/legal. -[1]: https://github.com/appcelerator/winreglib/blob/master/LICENSE +[1]: https://github.com/tidev/winreglib/blob/master/LICENSE [2]: https://www.npmjs.com/package/snooplogg diff --git a/media/winreglib.webp b/media/winreglib.webp new file mode 100644 index 0000000000000000000000000000000000000000..d12a26da5d8743730a2e9afb24e2a848e947fe45 GIT binary patch literal 25388 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Μkm7Ix5pA$EnayC^3*6W4Ovgmef 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 buu_j#j<8GAC-af!M~3!cjl;=TTp$1dPC2%Q literal 0 HcmV?d00001 diff --git a/package.json b/package.json index 9b81021..2180441 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,7 @@ "build:bundle": "rimraf dist && rollup -c rollup.config.ts --configPlugin typescript && pnpm build:types", "build:local": "node-gyp -j 20 build", "build:local-debug": "node-gyp -j 20 build --debug", - "build:prebuild": "pnpm prebuild-arm && pnpm prebuild-arm64 && pnpm prebuild-ia32 && pnpm prebuild-x64", + "build:prebuild": "pnpm pnpm prebuild-ia32 && pnpm prebuild-x64", "build:types": "pnpm build:types:temp && pnpm build:types:roll && pnpm build:types:check", "build:types:temp": "tsc --declaration --emitDeclarationOnly --outDir temp --project tsconfig.build.json", "build:types:roll": "rollup --config rollup.dts.config.ts --configPlugin typescript && rimraf temp", diff --git a/src/index.ts b/src/index.ts index a924d46..528b9e2 100644 --- a/src/index.ts +++ b/src/index.ts @@ -63,19 +63,19 @@ class WinRegLib extends EventEmitter { * Gets the value for a specific key value. * * @param {String} key - The key. - * @param {String} value - The name of the value to get. + * @param {String} valueName - The name of the value to get. * @returns {*} The value reflects the data type from the registry. */ - get(key: string, value: string): unknown { + get(key: string, valueName: string): unknown { if (!key || typeof key !== 'string') { throw new TypeError('Expected key to be a non-empty string'); } - if (!value || typeof value !== 'string') { + if (!valueName || typeof valueName !== 'string') { throw new TypeError('Expected value name to be a non-empty string'); } - return binding.get(key, value); + return binding.get(key, valueName); } /** From 96e56951af6ebe18603860bde4a91b011f493802 Mon Sep 17 00:00:00 2001 From: Chris Barber Date: Thu, 18 Jul 2024 09:54:12 -0500 Subject: [PATCH 26/27] Update deps --- package.json | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 2180441..6d4c48c 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,6 @@ "build:bundle": "rimraf dist && rollup -c rollup.config.ts --configPlugin typescript && pnpm build:types", "build:local": "node-gyp -j 20 build", "build:local-debug": "node-gyp -j 20 build --debug", - "build:prebuild": "pnpm pnpm prebuild-ia32 && pnpm prebuild-x64", "build:types": "pnpm build:types:temp && pnpm build:types:roll && pnpm build:types:check", "build:types:temp": "tsc --declaration --emitDeclarationOnly --outDir temp --project tsconfig.build.json", "build:types:roll": "rollup --config rollup.dts.config.ts --configPlugin typescript && rimraf temp", @@ -29,7 +28,8 @@ "clean": "node-gyp clean", "coverage": "vitest --pool=forks --coverage", "install": "node -e \"process.exit(process.platform === 'win32' ? 0 : 1)\" && node-gyp-build", - "prepublishOnly": "pnpm build:bundle && pnpm build:prebuild", + "prepublishOnly": "pnpm build:bundle && pnpm prebuild", + "prebuild": "pnpm pnpm prebuild-ia32 && pnpm prebuild-x64", "prebuild-arm": "prebuildify --napi --strip --platform=win32 --arch arm", "prebuild-arm64": "prebuildify --napi --strip --platform=win32 --arch arm64", "prebuild-ia32": "prebuildify --napi --strip --platform=win32 --arch ia32", @@ -51,7 +51,7 @@ "@types/node": "20.14.11", "@vitest/coverage-v8": "2.0.3", "esbuild": "0.23.0", - "lefthook": "1.7.2", + "lefthook": "1.7.3", "prebuildify": "6.0.1", "rimraf": "6.0.1", "rollup": "4.18.1", @@ -61,6 +61,13 @@ "typescript": "5.5.3", "vitest": "2.0.3" }, + "files": [ + "dist", + "patches", + "prebuilds", + "src/*.{cpp,h}", + "binding.gyp" + ], "homepage": "https://github.com/tidev/winreglib", "bugs": "https://github.com/tidev/winreglib/issues", "repository": "https://github.com/tidev/winreglib", From 52665db6126e87da035c449fce011cd062ddc52d Mon Sep 17 00:00:00 2001 From: Chris Barber Date: Thu, 18 Jul 2024 17:44:29 -0500 Subject: [PATCH 27/27] Tack on rc.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 6d4c48c..f0d16ea 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "winreglib", - "version": "3.0.0", + "version": "3.0.0-rc.0", "description": "Windows Registry utility library", "type": "module", "exports": "./dist/index.js",