From 1c1cf80fdd43e60827727f5a3f9f17e4fb88943f Mon Sep 17 00:00:00 2001 From: Kepler Vital Date: Fri, 25 Oct 2024 10:22:03 +0200 Subject: [PATCH] feat(didc-js): Javascript multi purpose library with candid utils (#577) * feat(didc-js): Javascript multi purpose library with candid utils * use latest pnpm * remove idl2json * update build * allow decoding with the service method arg type * PR comments * include dist folder in publish --- Cargo.lock | 254 +- Cargo.toml | 1 + tools/README.md | 1 + tools/didc-js/.gitignore | 3 + tools/didc-js/.node-version | 1 + tools/didc-js/.npmrc | 4 + tools/didc-js/LICENSE | 208 ++ tools/didc-js/README.md | 68 + tools/didc-js/package.json | 29 + tools/didc-js/pnpm-lock.yaml | 2967 +++++++++++++++++ tools/didc-js/pnpm-workspace.yaml | 3 + tools/didc-js/wasm-package/Cargo.toml | 33 + tools/didc-js/wasm-package/LICENSE | 208 ++ tools/didc-js/wasm-package/README.md | 68 + tools/didc-js/wasm-package/build.sh | 124 + tools/didc-js/wasm-package/package.json | 39 + tools/didc-js/wasm-package/src/core.rs | 120 + tools/didc-js/wasm-package/src/errors.rs | 33 + tools/didc-js/wasm-package/src/lib.rs | 34 + tools/didc-js/wasm-package/src/types.rs | 293 ++ tools/didc-js/wasm-package/src/utils.rs | 111 + tools/didc-js/wasm-package/src/validation.rs | 82 + tools/didc-js/wasm-tests/jest.config.ts | 8 + tools/didc-js/wasm-tests/package.json | 19 + tools/didc-js/wasm-tests/src/decode.test.ts | 40 + tools/didc-js/wasm-tests/src/encode.test.ts | 65 + .../src/get_service_methods.test.ts | 14 + tools/didc-js/wasm-tests/src/test.utils.ts | 27 + tools/didc-js/wasm-tests/src/wasm.test.ts | 16 + tools/didc-js/wasm-tests/tsconfig.json | 12 + 30 files changed, 4873 insertions(+), 12 deletions(-) create mode 100644 tools/didc-js/.gitignore create mode 100644 tools/didc-js/.node-version create mode 100644 tools/didc-js/.npmrc create mode 100644 tools/didc-js/LICENSE create mode 100644 tools/didc-js/README.md create mode 100644 tools/didc-js/package.json create mode 100644 tools/didc-js/pnpm-lock.yaml create mode 100644 tools/didc-js/pnpm-workspace.yaml create mode 100644 tools/didc-js/wasm-package/Cargo.toml create mode 100644 tools/didc-js/wasm-package/LICENSE create mode 100644 tools/didc-js/wasm-package/README.md create mode 100755 tools/didc-js/wasm-package/build.sh create mode 100644 tools/didc-js/wasm-package/package.json create mode 100644 tools/didc-js/wasm-package/src/core.rs create mode 100644 tools/didc-js/wasm-package/src/errors.rs create mode 100644 tools/didc-js/wasm-package/src/lib.rs create mode 100644 tools/didc-js/wasm-package/src/types.rs create mode 100644 tools/didc-js/wasm-package/src/utils.rs create mode 100644 tools/didc-js/wasm-package/src/validation.rs create mode 100644 tools/didc-js/wasm-tests/jest.config.ts create mode 100644 tools/didc-js/wasm-tests/package.json create mode 100644 tools/didc-js/wasm-tests/src/decode.test.ts create mode 100644 tools/didc-js/wasm-tests/src/encode.test.ts create mode 100644 tools/didc-js/wasm-tests/src/get_service_methods.test.ts create mode 100644 tools/didc-js/wasm-tests/src/test.utils.ts create mode 100644 tools/didc-js/wasm-tests/src/wasm.test.ts create mode 100644 tools/didc-js/wasm-tests/tsconfig.json diff --git a/Cargo.lock b/Cargo.lock index 7e5c9381..06d98ae3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -172,6 +172,12 @@ dependencies = [ "serde", ] +[[package]] +name = "bumpalo" +version = "3.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" + [[package]] name = "byteorder" version = "1.5.0" @@ -186,10 +192,10 @@ dependencies = [ "bincode", "binread", "byteorder", - "candid_derive", - "candid_parser", + "candid_derive 0.6.6", + "candid_parser 0.2.0-beta.4", "hex", - "ic_principal", + "ic_principal 0.1.1", "leb128", "num-bigint", "num-traits", @@ -204,9 +210,44 @@ dependencies = [ "thiserror", ] +[[package]] +name = "candid" +version = "0.10.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c30ee7f886f296b6422c0ff017e89dd4f831521dfdcc76f3f71aae1ce817222" +dependencies = [ + "anyhow", + "binread", + "byteorder", + "candid_derive 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", + "hex", + "ic_principal 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "leb128", + "num-bigint", + "num-traits", + "paste", + "pretty", + "serde", + "serde_bytes", + "stacker", + "thiserror", +] + +[[package]] +name = "candid_derive" +version = "0.6.6" +dependencies = [ + "lazy_static", + "proc-macro2 1.0.86", + "quote 1.0.36", + "syn 2.0.72", +] + [[package]] name = "candid_derive" version = "0.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3de398570c386726e7a59d9887b68763c481477f9a043fb998a2e09d428df1a9" dependencies = [ "lazy_static", "proc-macro2 1.0.86", @@ -214,13 +255,32 @@ dependencies = [ "syn 2.0.72", ] +[[package]] +name = "candid_parser" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48a3da76f989cd350b7342c64c6c6008341bb6186f6832ef04e56dc50ba0fd76" +dependencies = [ + "anyhow", + "candid 0.10.10 (registry+https://github.com/rust-lang/crates.io-index)", + "codespan-reporting", + "convert_case", + "hex", + "lalrpop", + "lalrpop-util", + "logos 0.13.0", + "num-bigint", + "pretty", + "thiserror", +] + [[package]] name = "candid_parser" version = "0.2.0-beta.4" dependencies = [ "anyhow", "arbitrary", - "candid", + "candid 0.10.10", "codespan-reporting", "console", "convert_case", @@ -232,7 +292,7 @@ dependencies = [ "hex", "lalrpop", "lalrpop-util", - "logos", + "logos 0.14.0", "num-bigint", "num-traits", "pretty", @@ -330,6 +390,16 @@ dependencies = [ "windows-sys", ] +[[package]] +name = "console_error_panic_hook" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a06aeb73f470f66dcdbf7223caeebb85984942f22f1adb2a088cf9668146bbbc" +dependencies = [ + "cfg-if", + "wasm-bindgen", +] + [[package]] name = "convert_case" version = "0.6.0" @@ -412,7 +482,7 @@ name = "didc" version = "0.4.0" dependencies = [ "anyhow", - "candid_parser", + "candid_parser 0.2.0-beta.4", "clap", "console", "hex", @@ -420,6 +490,27 @@ dependencies = [ "rand", ] +[[package]] +name = "didc-js" +version = "0.0.0" +dependencies = [ + "anyhow", + "candid 0.10.10 (registry+https://github.com/rust-lang/crates.io-index)", + "candid_parser 0.1.4", + "console_error_panic_hook", + "getrandom", + "hex", + "js-sys", + "log", + "pretty-hex", + "rand", + "serde", + "serde-wasm-bindgen", + "thiserror", + "wasm-bindgen", + "wasm-bindgen-console-logger", +] + [[package]] name = "digest" version = "0.10.7" @@ -533,8 +624,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" dependencies = [ "cfg-if", + "js-sys", "libc", "wasi", + "wasm-bindgen", ] [[package]] @@ -609,6 +702,20 @@ dependencies = [ "thiserror", ] +[[package]] +name = "ic_principal" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1762deb6f7c8d8c2bdee4b6c5a47b60195b74e9b5280faa5ba29692f8e17429c" +dependencies = [ + "arbitrary", + "crc32fast", + "data-encoding", + "serde", + "sha2", + "thiserror", +] + [[package]] name = "impls" version = "1.0.3" @@ -646,6 +753,15 @@ version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" +[[package]] +name = "js-sys" +version = "0.3.72" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a88f1bda2bd75b0452a14784937d796722fdebfe50df998aeb3f0b7603019a9" +dependencies = [ + "wasm-bindgen", +] + [[package]] name = "lalrpop" version = "0.20.2" @@ -660,7 +776,7 @@ dependencies = [ "petgraph", "pico-args", "regex", - "regex-syntax", + "regex-syntax 0.8.4", "string_cache", "term", "tiny-keccak", @@ -727,13 +843,36 @@ version = "0.4.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" +[[package]] +name = "logos" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c000ca4d908ff18ac99b93a062cb8958d331c3220719c52e77cb19cc6ac5d2c1" +dependencies = [ + "logos-derive 0.13.0", +] + [[package]] name = "logos" version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "161971eb88a0da7ae0c333e1063467c5b5727e7fb6b710b8db4814eade3a42e8" dependencies = [ - "logos-derive", + "logos-derive 0.14.0", +] + +[[package]] +name = "logos-codegen" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc487311295e0002e452025d6b580b77bb17286de87b57138f3b5db711cded68" +dependencies = [ + "beef", + "fnv", + "proc-macro2 1.0.86", + "quote 1.0.36", + "regex-syntax 0.6.29", + "syn 2.0.72", ] [[package]] @@ -747,17 +886,26 @@ dependencies = [ "lazy_static", "proc-macro2 1.0.86", "quote 1.0.36", - "regex-syntax", + "regex-syntax 0.8.4", "syn 2.0.72", ] +[[package]] +name = "logos-derive" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbfc0d229f1f42d790440136d941afd806bc9e949e2bcb8faa813b0f00d1267e" +dependencies = [ + "logos-codegen 0.13.0", +] + [[package]] name = "logos-derive" version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1c2a69b3eb68d5bd595107c9ee58d7e07fe2bb5e360cc85b0f084dedac80de0a" dependencies = [ - "logos-codegen", + "logos-codegen 0.14.0", ] [[package]] @@ -1051,7 +1199,7 @@ dependencies = [ "aho-corasick", "memchr", "regex-automata", - "regex-syntax", + "regex-syntax 0.8.4", ] [[package]] @@ -1062,9 +1210,15 @@ checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" dependencies = [ "aho-corasick", "memchr", - "regex-syntax", + "regex-syntax 0.8.4", ] +[[package]] +name = "regex-syntax" +version = "0.6.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" + [[package]] name = "regex-syntax" version = "0.8.4" @@ -1120,6 +1274,17 @@ dependencies = [ "serde_derive", ] +[[package]] +name = "serde-wasm-bindgen" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3b143e2833c57ab9ad3ea280d21fd34e285a42837aeb0ee301f4f41890fa00e" +dependencies = [ + "js-sys", + "serde", + "wasm-bindgen", +] + [[package]] name = "serde_bytes" version = "0.11.15" @@ -1477,6 +1642,71 @@ version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +[[package]] +name = "wasm-bindgen" +version = "0.2.95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "128d1e363af62632b8eb57219c8fd7877144af57558fb2ef0368d0087bddeb2e" +dependencies = [ + "cfg-if", + "once_cell", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb6dd4d3ca0ddffd1dd1c9c04f94b868c37ff5fac97c30b97cff2d74fce3a358" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2 1.0.86", + "quote 1.0.36", + "syn 2.0.72", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-console-logger" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7530a275e7faf7b5b83aabdf78244fb8d9a68a2ec4b26935a05ecc0c9b0185ed" +dependencies = [ + "log", + "wasm-bindgen", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e79384be7f8f5a9dd5d7167216f022090cf1f9ec128e6e6a482a2cb5c5422c56" +dependencies = [ + "quote 1.0.36", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26c6ab57572f7a24a4985830b120de1594465e5d500f24afe89e16b4e833ef68" +dependencies = [ + "proc-macro2 1.0.86", + "quote 1.0.36", + "syn 2.0.72", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65fc09f10666a9f147042251e0dda9c18f166ff7de300607007e96bdebc1068d" + [[package]] name = "winapi" version = "0.3.9" diff --git a/Cargo.toml b/Cargo.toml index 341dbdde..32e4f8f3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,6 +5,7 @@ members = [ "rust/candid_derive", "rust/ic_principal", "tools/didc", + "tools/didc-js/wasm-package", ] resolver = "2" diff --git a/tools/README.md b/tools/README.md index 49d181d5..42a3a1a5 100644 --- a/tools/README.md +++ b/tools/README.md @@ -2,3 +2,4 @@ - Didc -- multiple-purpose candid tool, including the "DFINITY Interface Description Compiler" - Candiff -- relates candid values that change over time +- [@dfinity/didc](https://www.npmjs.com/package/@dfinity/didc) -- JavaScript library counter part of the didc tool, meant to be used in JavaScript projects. diff --git a/tools/didc-js/.gitignore b/tools/didc-js/.gitignore new file mode 100644 index 00000000..885086d5 --- /dev/null +++ b/tools/didc-js/.gitignore @@ -0,0 +1,3 @@ +node_modules +dist +pkg diff --git a/tools/didc-js/.node-version b/tools/didc-js/.node-version new file mode 100644 index 00000000..10fef252 --- /dev/null +++ b/tools/didc-js/.node-version @@ -0,0 +1 @@ +20.18 diff --git a/tools/didc-js/.npmrc b/tools/didc-js/.npmrc new file mode 100644 index 00000000..95cb7efc --- /dev/null +++ b/tools/didc-js/.npmrc @@ -0,0 +1,4 @@ +engine-strict=true +enable-pre-post-scripts=true +package-manager-strict=true +manage-package-manager-versions=true diff --git a/tools/didc-js/LICENSE b/tools/didc-js/LICENSE new file mode 100644 index 00000000..ecc50baa --- /dev/null +++ b/tools/didc-js/LICENSE @@ -0,0 +1,208 @@ + 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 + +LLVM EXCEPTIONS TO THE APACHE 2.0 LICENSE + +As an exception, if, as a result of your compiling your source code, portions +of this Software are embedded into an Object form of such source code, you may +redistribute such embedded portions in such Object form without complying with +the conditions of Sections 4(a), 4(b) and 4(d) of the License. + +In addition, if you combine or link compiled forms of this Software with +software that is licensed under the GPLv2 ("Combined Software") and if a court +of competent jurisdiction determines that the patent provision (Section 3), the +indemnity provision (Section 9) or other Section of the License conflicts with +the conditions of the GPLv2, you may retroactively and prospectively choose to +deem waived or otherwise exclude such Section(s) of the License, but only in +their entirety and only with respect to the Combined Software. + +END OF LLVM EXCEPTIONS + +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 2024 DFINITY Stiftung + +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. + +END OF APPENDIX diff --git a/tools/didc-js/README.md b/tools/didc-js/README.md new file mode 100644 index 00000000..b7cd542c --- /dev/null +++ b/tools/didc-js/README.md @@ -0,0 +1,68 @@ +# @dfinity/didc + +A multi-purpose Candid tool for JavaScript projects, including encoding and decoding Candid values. + +## Usage + +```javascript +import { getServiceMethods, encode, decode } from "@dfinity/didc"; + +// The IDL in text format to be used, most canisters expose their IDL through +// the `candid:service` public metadata. +// +// You can fetch the IDL with an agent call or dfx with `dfx canister metadata candid:service` +export const IDL = ` + type StoreNumberInput = record { + number : nat64; + }; + + service : { + store_number : (input : StoreNumberInput) -> (); + get_number : () -> (nat64) query; + }; +`; + +// Gets the service methods from the IDL and returns an array of the methods. +// +// Example returned value: ['store_number', 'get_number'] +const methods = getServiceMethods(IDL); + +// Encodes a candid text representation of a value to a hex representation. +// +// Example returned value: '4449444c016c01c98dea8b0a7801005a00000000000000' +const encoded encode({ + idl: IDL, + input: "(record { number=90; })", + serviceMethod: "store_number", + targetFormat: "hex", +}); + +// Decodes a hex representation of a candid value to a text representation. +// +// Example returned value: '(90 : nat64)' +const decoded = decode({ + idl: IDL, + input: "4449444c0001785a00000000000000", + serviceMethod: "get_number", + inputFormat: "hex", + targetFormat: "candid", +}); +``` + +### Web Usage + +For web usage, you need to initialize the async wasm module before using the functions. + +```javascript +import init, { encode } from "@dfinity/didc"; + +await init(); + +// then you can use the functions because the wasm will be initialized +const encoded = encode({ + idl: IDL, + input: "(record { number=90; })", + serviceMethod: "store_number", + targetFormat: "hex", +}); +``` diff --git a/tools/didc-js/package.json b/tools/didc-js/package.json new file mode 100644 index 00000000..351e731c --- /dev/null +++ b/tools/didc-js/package.json @@ -0,0 +1,29 @@ +{ + "name": "didc-js", + "description": "Workspace for the didc-js project.", + "private": true, + "packageManager": "pnpm@9.12.2", + "engines": { + "node": "^20", + "pnpm": "^9", + "npm": "please use pnpm", + "yarn": "please use pnpm" + }, + "scripts": { + "preinstall": "npx only-allow pnpm", + "build": "pnpm run -r build", + "dev": "pnpm run -r dev", + "test": "pnpm run -r test" + }, + "devDependencies": { + "@types/jest": "29.5.14", + "@types/node": "22.7.9", + "jest": "29.7.0", + "terser": "5.36.0", + "ts-jest": "29.2.5", + "ts-node": "10.9.2", + "tslib": "2.8.0", + "typescript": "5.6.3", + "wasm-pack": "0.13.0" + } +} diff --git a/tools/didc-js/pnpm-lock.yaml b/tools/didc-js/pnpm-lock.yaml new file mode 100644 index 00000000..9d262f4e --- /dev/null +++ b/tools/didc-js/pnpm-lock.yaml @@ -0,0 +1,2967 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + devDependencies: + '@types/jest': + specifier: 29.5.14 + version: 29.5.14 + '@types/node': + specifier: 22.7.9 + version: 22.7.9 + jest: + specifier: 29.7.0 + version: 29.7.0(@types/node@22.7.9)(ts-node@10.9.2(@types/node@22.7.9)(typescript@5.6.3)) + terser: + specifier: 5.36.0 + version: 5.36.0 + ts-jest: + specifier: 29.2.5 + version: 29.2.5(@babel/core@7.25.8)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.25.8))(jest@29.7.0(@types/node@22.7.9)(ts-node@10.9.2(@types/node@22.7.9)(typescript@5.6.3)))(typescript@5.6.3) + ts-node: + specifier: 10.9.2 + version: 10.9.2(@types/node@22.7.9)(typescript@5.6.3) + tslib: + specifier: 2.8.0 + version: 2.8.0 + typescript: + specifier: 5.6.3 + version: 5.6.3 + wasm-pack: + specifier: 0.13.0 + version: 0.13.0 + + wasm-package: + devDependencies: + wasm-pack: + specifier: 0.13.0 + version: 0.13.0 + + wasm-tests: + devDependencies: + '@dfinity/didc': + specifier: workspace:* + version: link:../wasm-package + '@types/jest': + specifier: 29.5.14 + version: 29.5.14 + '@types/node': + specifier: 22.7.9 + version: 22.7.9 + jest: + specifier: 29.7.0 + version: 29.7.0(@types/node@22.7.9)(ts-node@10.9.2(@types/node@22.7.9)(typescript@5.6.3)) + ts-jest: + specifier: 29.2.5 + version: 29.2.5(@babel/core@7.25.8)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.25.8))(jest@29.7.0(@types/node@22.7.9)(ts-node@10.9.2(@types/node@22.7.9)(typescript@5.6.3)))(typescript@5.6.3) + ts-node: + specifier: 10.9.2 + version: 10.9.2(@types/node@22.7.9)(typescript@5.6.3) + tslib: + specifier: 2.8.0 + version: 2.8.0 + typescript: + specifier: 5.6.3 + version: 5.6.3 + +packages: + + '@ampproject/remapping@2.3.0': + resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} + engines: {node: '>=6.0.0'} + + '@babel/code-frame@7.25.7': + resolution: {integrity: sha512-0xZJFNE5XMpENsgfHYTw8FbX4kv53mFLn2i3XPoq69LyhYSCBJtitaHx9QnsVTrsogI4Z3+HtEfZ2/GFPOtf5g==} + engines: {node: '>=6.9.0'} + + '@babel/compat-data@7.25.8': + resolution: {integrity: sha512-ZsysZyXY4Tlx+Q53XdnOFmqwfB9QDTHYxaZYajWRoBLuLEAwI2UIbtxOjWh/cFaa9IKUlcB+DDuoskLuKu56JA==} + engines: {node: '>=6.9.0'} + + '@babel/core@7.25.8': + resolution: {integrity: sha512-Oixnb+DzmRT30qu9d3tJSQkxuygWm32DFykT4bRoORPa9hZ/L4KhVB/XiRm6KG+roIEM7DBQlmg27kw2HZkdZg==} + engines: {node: '>=6.9.0'} + + '@babel/generator@7.25.7': + resolution: {integrity: sha512-5Dqpl5fyV9pIAD62yK9P7fcA768uVPUyrQmqpqstHWgMma4feF1x/oFysBCVZLY5wJ2GkMUCdsNDnGZrPoR6rA==} + engines: {node: '>=6.9.0'} + + '@babel/helper-compilation-targets@7.25.7': + resolution: {integrity: sha512-DniTEax0sv6isaw6qSQSfV4gVRNtw2rte8HHM45t9ZR0xILaufBRNkpMifCRiAPyvL4ACD6v0gfCwCmtOQaV4A==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-imports@7.25.7': + resolution: {integrity: sha512-o0xCgpNmRohmnoWKQ0Ij8IdddjyBFE4T2kagL/x6M3+4zUgc+4qTOUBoNe4XxDskt1HPKO007ZPiMgLDq2s7Kw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-transforms@7.25.7': + resolution: {integrity: sha512-k/6f8dKG3yDz/qCwSM+RKovjMix563SLxQFo0UhRNo239SP6n9u5/eLtKD6EAjwta2JHJ49CsD8pms2HdNiMMQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-plugin-utils@7.25.7': + resolution: {integrity: sha512-eaPZai0PiqCi09pPs3pAFfl/zYgGaE6IdXtYvmf0qlcDTd3WCtO7JWCcRd64e0EQrcYgiHibEZnOGsSY4QSgaw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-simple-access@7.25.7': + resolution: {integrity: sha512-FPGAkJmyoChQeM+ruBGIDyrT2tKfZJO8NcxdC+CWNJi7N8/rZpSxK7yvBJ5O/nF1gfu5KzN7VKG3YVSLFfRSxQ==} + engines: {node: '>=6.9.0'} + + '@babel/helper-string-parser@7.25.7': + resolution: {integrity: sha512-CbkjYdsJNHFk8uqpEkpCvRs3YRp9tY6FmFY7wLMSYuGYkrdUi7r2lc4/wqsvlHoMznX3WJ9IP8giGPq68T/Y6g==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-identifier@7.25.7': + resolution: {integrity: sha512-AM6TzwYqGChO45oiuPqwL2t20/HdMC1rTPAesnBCgPCSF1x3oN9MVUwQV2iyz4xqWrctwK5RNC8LV22kaQCNYg==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-option@7.25.7': + resolution: {integrity: sha512-ytbPLsm+GjArDYXJ8Ydr1c/KJuutjF2besPNbIZnZ6MKUxi/uTA22t2ymmA4WFjZFpjiAMO0xuuJPqK2nvDVfQ==} + engines: {node: '>=6.9.0'} + + '@babel/helpers@7.25.7': + resolution: {integrity: sha512-Sv6pASx7Esm38KQpF/U/OXLwPPrdGHNKoeblRxgZRLXnAtnkEe4ptJPDtAZM7fBLadbc1Q07kQpSiGQ0Jg6tRA==} + engines: {node: '>=6.9.0'} + + '@babel/highlight@7.25.7': + resolution: {integrity: sha512-iYyACpW3iW8Fw+ZybQK+drQre+ns/tKpXbNESfrhNnPLIklLbXr7MYJ6gPEd0iETGLOK+SxMjVvKb/ffmk+FEw==} + engines: {node: '>=6.9.0'} + + '@babel/parser@7.25.8': + resolution: {integrity: sha512-HcttkxzdPucv3nNFmfOOMfFf64KgdJVqm1KaCm25dPGMLElo9nsLvXeJECQg8UzPuBGLyTSA0ZzqCtDSzKTEoQ==} + engines: {node: '>=6.0.0'} + hasBin: true + + '@babel/plugin-syntax-async-generators@7.8.4': + resolution: {integrity: sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-bigint@7.8.3': + resolution: {integrity: sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-class-properties@7.12.13': + resolution: {integrity: sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-class-static-block@7.14.5': + resolution: {integrity: sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-import-attributes@7.25.7': + resolution: {integrity: sha512-AqVo+dguCgmpi/3mYBdu9lkngOBlQ2w2vnNpa6gfiCxQZLzV4ZbhsXitJ2Yblkoe1VQwtHSaNmIaGll/26YWRw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-import-meta@7.10.4': + resolution: {integrity: sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-json-strings@7.8.3': + resolution: {integrity: sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-jsx@7.25.7': + resolution: {integrity: sha512-ruZOnKO+ajVL/MVx+PwNBPOkrnXTXoWMtte1MBpegfCArhqOe3Bj52avVj1huLLxNKYKXYaSxZ2F+woK1ekXfw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-logical-assignment-operators@7.10.4': + resolution: {integrity: sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-nullish-coalescing-operator@7.8.3': + resolution: {integrity: sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-numeric-separator@7.10.4': + resolution: {integrity: sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-object-rest-spread@7.8.3': + resolution: {integrity: sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-optional-catch-binding@7.8.3': + resolution: {integrity: sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-optional-chaining@7.8.3': + resolution: {integrity: sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-private-property-in-object@7.14.5': + resolution: {integrity: sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-top-level-await@7.14.5': + resolution: {integrity: sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-typescript@7.25.7': + resolution: {integrity: sha512-rR+5FDjpCHqqZN2bzZm18bVYGaejGq5ZkpVCJLXor/+zlSrSoc4KWcHI0URVWjl/68Dyr1uwZUz/1njycEAv9g==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/template@7.25.7': + resolution: {integrity: sha512-wRwtAgI3bAS+JGU2upWNL9lSlDcRCqD05BZ1n3X2ONLH1WilFP6O1otQjeMK/1g0pvYcXC7b/qVUB1keofjtZA==} + engines: {node: '>=6.9.0'} + + '@babel/traverse@7.25.7': + resolution: {integrity: sha512-jatJPT1Zjqvh/1FyJs6qAHL+Dzb7sTb+xr7Q+gM1b+1oBsMsQQ4FkVKb6dFlJvLlVssqkRzV05Jzervt9yhnzg==} + engines: {node: '>=6.9.0'} + + '@babel/types@7.25.8': + resolution: {integrity: sha512-JWtuCu8VQsMladxVz/P4HzHUGCAwpuqacmowgXFs5XjxIgKuNjnLokQzuVjlTvIzODaDmpjT3oxcC48vyk9EWg==} + engines: {node: '>=6.9.0'} + + '@bcoe/v8-coverage@0.2.3': + resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==} + + '@cspotcode/source-map-support@0.8.1': + resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} + engines: {node: '>=12'} + + '@istanbuljs/load-nyc-config@1.1.0': + resolution: {integrity: sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==} + engines: {node: '>=8'} + + '@istanbuljs/schema@0.1.3': + resolution: {integrity: sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==} + engines: {node: '>=8'} + + '@jest/console@29.7.0': + resolution: {integrity: sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/core@29.7.0': + resolution: {integrity: sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + + '@jest/environment@29.7.0': + resolution: {integrity: sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/expect-utils@29.7.0': + resolution: {integrity: sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/expect@29.7.0': + resolution: {integrity: sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/fake-timers@29.7.0': + resolution: {integrity: sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/globals@29.7.0': + resolution: {integrity: sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/reporters@29.7.0': + resolution: {integrity: sha512-DApq0KJbJOEzAFYjHADNNxAE3KbhxQB1y5Kplb5Waqw6zVbuWatSnMjE5gs8FUgEPmNsnZA3NCWl9NG0ia04Pg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + + '@jest/schemas@29.6.3': + resolution: {integrity: sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/source-map@29.6.3': + resolution: {integrity: sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/test-result@29.7.0': + resolution: {integrity: sha512-Fdx+tv6x1zlkJPcWXmMDAG2HBnaR9XPSd5aDWQVsfrZmLVT3lU1cwyxLgRmXR9yrq4NBoEm9BMsfgFzTQAbJYA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/test-sequencer@29.7.0': + resolution: {integrity: sha512-GQwJ5WZVrKnOJuiYiAF52UNUJXgTZx1NHjFSEB0qEMmSZKAkdMoIzw/Cj6x6NF4AvV23AUqDpFzQkN/eYCYTxw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/transform@29.7.0': + resolution: {integrity: sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/types@29.6.3': + resolution: {integrity: sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==} + 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/source-map@0.3.6': + resolution: {integrity: sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==} + + '@jridgewell/sourcemap-codec@1.5.0': + resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} + + '@jridgewell/trace-mapping@0.3.25': + resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} + + '@jridgewell/trace-mapping@0.3.9': + resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} + + '@sinclair/typebox@0.27.8': + resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==} + + '@sinonjs/commons@3.0.1': + resolution: {integrity: sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==} + + '@sinonjs/fake-timers@10.3.0': + resolution: {integrity: sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==} + + '@tsconfig/node10@1.0.11': + resolution: {integrity: sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==} + + '@tsconfig/node12@1.0.11': + resolution: {integrity: sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==} + + '@tsconfig/node14@1.0.3': + resolution: {integrity: sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==} + + '@tsconfig/node16@1.0.4': + resolution: {integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==} + + '@types/babel__core@7.20.5': + resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==} + + '@types/babel__generator@7.6.8': + resolution: {integrity: sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==} + + '@types/babel__template@7.4.4': + resolution: {integrity: sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==} + + '@types/babel__traverse@7.20.6': + resolution: {integrity: sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==} + + '@types/graceful-fs@4.1.9': + resolution: {integrity: sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==} + + '@types/istanbul-lib-coverage@2.0.6': + resolution: {integrity: sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==} + + '@types/istanbul-lib-report@3.0.3': + resolution: {integrity: sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==} + + '@types/istanbul-reports@3.0.4': + resolution: {integrity: sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==} + + '@types/jest@29.5.14': + resolution: {integrity: sha512-ZN+4sdnLUbo8EVvVc2ao0GFW6oVrQRPn4K2lglySj7APvSrgzxHiNNK99us4WDMi57xxA2yggblIAMNhXOotLQ==} + + '@types/node@22.7.9': + resolution: {integrity: sha512-jrTfRC7FM6nChvU7X2KqcrgquofrWLFDeYC1hKfwNWomVvrn7JIksqf344WN2X/y8xrgqBd2dJATZV4GbatBfg==} + + '@types/stack-utils@2.0.3': + resolution: {integrity: sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==} + + '@types/yargs-parser@21.0.3': + resolution: {integrity: sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==} + + '@types/yargs@17.0.33': + resolution: {integrity: sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA==} + + acorn-walk@8.3.4: + resolution: {integrity: sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==} + engines: {node: '>=0.4.0'} + + acorn@8.13.0: + resolution: {integrity: sha512-8zSiw54Oxrdym50NlZ9sUusyO1Z1ZchgRLWRaK6c86XJFClyCgFKetdowBg5bKxyp/u+CDBJG4Mpp0m3HLZl9w==} + engines: {node: '>=0.4.0'} + hasBin: true + + ansi-escapes@4.3.2: + resolution: {integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==} + engines: {node: '>=8'} + + ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + + 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'} + + anymatch@3.1.3: + resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} + engines: {node: '>= 8'} + + arg@4.1.3: + resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==} + + argparse@1.0.10: + resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} + + async@3.2.6: + resolution: {integrity: sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==} + + axios@0.26.1: + resolution: {integrity: sha512-fPwcX4EvnSHuInCMItEhAGnaSEXRBjtzh9fOtsE6E1G6p7vl7edEeZe11QHf18+6+9gR5PbKV/sGKNaD8YaMeA==} + + babel-jest@29.7.0: + resolution: {integrity: sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + '@babel/core': ^7.8.0 + + babel-plugin-istanbul@6.1.1: + resolution: {integrity: sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==} + engines: {node: '>=8'} + + babel-plugin-jest-hoist@29.6.3: + resolution: {integrity: sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + babel-preset-current-node-syntax@1.1.0: + resolution: {integrity: sha512-ldYss8SbBlWva1bs28q78Ju5Zq1F+8BrqBZZ0VFhLBvhh6lCpC2o3gDJi/5DRLs9FgYZCnmPYIVFU4lRXCkyUw==} + peerDependencies: + '@babel/core': ^7.0.0 + + babel-preset-jest@29.6.3: + resolution: {integrity: sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + '@babel/core': ^7.0.0 + + balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + + binary-install@1.1.0: + resolution: {integrity: sha512-rkwNGW+3aQVSZoD0/o3mfPN6Yxh3Id0R/xzTVBVVpGNlVz8EGwusksxRlbk/A5iKTZt9zkMn3qIqmAt3vpfbzg==} + engines: {node: '>=10'} + + brace-expansion@1.1.11: + resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} + + brace-expansion@2.0.1: + resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} + + braces@3.0.3: + resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} + engines: {node: '>=8'} + + browserslist@4.24.0: + resolution: {integrity: sha512-Rmb62sR1Zpjql25eSanFGEhAxcFwfA1K0GuQcLoaJBAcENegrQut3hYdhXFF1obQfiDyqIW/cLM5HSJ/9k884A==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + + bs-logger@0.2.6: + resolution: {integrity: sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==} + engines: {node: '>= 6'} + + bser@2.1.1: + resolution: {integrity: sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==} + + buffer-from@1.1.2: + resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} + + callsites@3.1.0: + resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} + engines: {node: '>=6'} + + camelcase@5.3.1: + resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==} + engines: {node: '>=6'} + + camelcase@6.3.0: + resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} + engines: {node: '>=10'} + + caniuse-lite@1.0.30001669: + resolution: {integrity: sha512-DlWzFDJqstqtIVx1zeSpIMLjunf5SmwOw0N2Ck/QSQdS8PLS4+9HrLaYei4w8BIAL7IB/UEDu889d8vhCTPA0w==} + + chalk@2.4.2: + resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} + engines: {node: '>=4'} + + chalk@4.1.2: + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} + engines: {node: '>=10'} + + char-regex@1.0.2: + resolution: {integrity: sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==} + engines: {node: '>=10'} + + chownr@2.0.0: + resolution: {integrity: sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==} + engines: {node: '>=10'} + + ci-info@3.9.0: + resolution: {integrity: sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==} + engines: {node: '>=8'} + + cjs-module-lexer@1.4.1: + resolution: {integrity: sha512-cuSVIHi9/9E/+821Qjdvngor+xpnlwnuwIyZOaLmHBVdXL+gP+I6QQB9VkO7RI77YIcTV+S1W9AreJ5eN63JBA==} + + cliui@8.0.1: + resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} + engines: {node: '>=12'} + + co@4.6.0: + resolution: {integrity: sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==} + engines: {iojs: '>= 1.0.0', node: '>= 0.12.0'} + + collect-v8-coverage@1.0.2: + resolution: {integrity: sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==} + + 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==} + + commander@2.20.3: + resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} + + concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + + convert-source-map@2.0.0: + resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + + create-jest@29.7.0: + resolution: {integrity: sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + hasBin: true + + create-require@1.1.1: + resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==} + + cross-spawn@7.0.3: + resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} + engines: {node: '>= 8'} + + debug@4.3.7: + resolution: {integrity: sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + dedent@1.5.3: + resolution: {integrity: sha512-NHQtfOOW68WD8lgypbLA5oT+Bt0xXJhiYvoR6SmmNXZfpzOGXwdKWmcwG8N7PwVVWV3eF/68nmD9BaJSsTBhyQ==} + peerDependencies: + babel-plugin-macros: ^3.1.0 + peerDependenciesMeta: + babel-plugin-macros: + optional: true + + deepmerge@4.3.1: + resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} + engines: {node: '>=0.10.0'} + + detect-newline@3.1.0: + resolution: {integrity: sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==} + engines: {node: '>=8'} + + diff-sequences@29.6.3: + resolution: {integrity: sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + diff@4.0.2: + resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==} + engines: {node: '>=0.3.1'} + + ejs@3.1.10: + resolution: {integrity: sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==} + engines: {node: '>=0.10.0'} + hasBin: true + + electron-to-chromium@1.5.39: + resolution: {integrity: sha512-4xkpSR6CjuiaNyvwiWDI85N9AxsvbPawB8xc7yzLPonYTuP19BVgYweKyUMFtHEZgIcHWMt1ks5Cqx2m+6/Grg==} + + emittery@0.13.1: + resolution: {integrity: sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==} + engines: {node: '>=12'} + + emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + + error-ex@1.3.2: + resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} + + escalade@3.2.0: + resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} + engines: {node: '>=6'} + + escape-string-regexp@1.0.5: + resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} + engines: {node: '>=0.8.0'} + + escape-string-regexp@2.0.0: + resolution: {integrity: sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==} + engines: {node: '>=8'} + + esprima@4.0.1: + resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} + engines: {node: '>=4'} + hasBin: true + + execa@5.1.1: + resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==} + engines: {node: '>=10'} + + exit@0.1.2: + resolution: {integrity: sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==} + engines: {node: '>= 0.8.0'} + + expect@29.7.0: + resolution: {integrity: sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + fast-json-stable-stringify@2.1.0: + resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} + + fb-watchman@2.0.2: + resolution: {integrity: sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==} + + filelist@1.0.4: + resolution: {integrity: sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==} + + fill-range@7.1.1: + resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} + engines: {node: '>=8'} + + find-up@4.1.0: + resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} + engines: {node: '>=8'} + + follow-redirects@1.15.9: + resolution: {integrity: sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==} + engines: {node: '>=4.0'} + peerDependencies: + debug: '*' + peerDependenciesMeta: + debug: + optional: true + + fs-minipass@2.1.0: + resolution: {integrity: sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==} + engines: {node: '>= 8'} + + 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==} + + gensync@1.0.0-beta.2: + resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} + engines: {node: '>=6.9.0'} + + get-caller-file@2.0.5: + resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} + engines: {node: 6.* || 8.* || >= 10.*} + + get-package-type@0.1.0: + resolution: {integrity: sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==} + engines: {node: '>=8.0.0'} + + get-stream@6.0.1: + resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} + engines: {node: '>=10'} + + glob@7.2.3: + resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} + deprecated: Glob versions prior to v9 are no longer supported + + globals@11.12.0: + resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} + engines: {node: '>=4'} + + 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==} + + human-signals@2.1.0: + resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==} + engines: {node: '>=10.17.0'} + + import-local@3.2.0: + resolution: {integrity: sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==} + engines: {node: '>=8'} + hasBin: true + + imurmurhash@0.1.4: + resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} + engines: {node: '>=0.8.19'} + + 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==} + + is-arrayish@0.2.1: + resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} + + is-core-module@2.15.1: + resolution: {integrity: sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==} + engines: {node: '>= 0.4'} + + is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + + is-generator-fn@2.1.0: + resolution: {integrity: sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==} + engines: {node: '>=6'} + + is-number@7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + + is-stream@2.0.1: + resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} + engines: {node: '>=8'} + + isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + + istanbul-lib-coverage@3.2.2: + resolution: {integrity: sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==} + engines: {node: '>=8'} + + istanbul-lib-instrument@5.2.1: + resolution: {integrity: sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==} + engines: {node: '>=8'} + + istanbul-lib-instrument@6.0.3: + resolution: {integrity: sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==} + engines: {node: '>=10'} + + istanbul-lib-report@3.0.1: + resolution: {integrity: sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==} + engines: {node: '>=10'} + + istanbul-lib-source-maps@4.0.1: + resolution: {integrity: sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==} + engines: {node: '>=10'} + + istanbul-reports@3.1.7: + resolution: {integrity: sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==} + engines: {node: '>=8'} + + jake@10.9.2: + resolution: {integrity: sha512-2P4SQ0HrLQ+fw6llpLnOaGAvN2Zu6778SJMrCUwns4fOoG9ayrTiZk3VV8sCPkVZF8ab0zksVpS8FDY5pRCNBA==} + engines: {node: '>=10'} + hasBin: true + + jest-changed-files@29.7.0: + resolution: {integrity: sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-circus@29.7.0: + resolution: {integrity: sha512-3E1nCMgipcTkCocFwM90XXQab9bS+GMsjdpmPrlelaxwD93Ad8iVEjX/vvHPdLPnFf+L40u+5+iutRdA1N9myw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-cli@29.7.0: + resolution: {integrity: sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + hasBin: true + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + + jest-config@29.7.0: + resolution: {integrity: sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + '@types/node': '*' + ts-node: '>=9.0.0' + peerDependenciesMeta: + '@types/node': + optional: true + ts-node: + optional: true + + jest-diff@29.7.0: + resolution: {integrity: sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-docblock@29.7.0: + resolution: {integrity: sha512-q617Auw3A612guyaFgsbFeYpNP5t2aoUNLwBUbc/0kD1R4t9ixDbyFTHd1nok4epoVFpr7PmeWHrhvuV3XaJ4g==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-each@29.7.0: + resolution: {integrity: sha512-gns+Er14+ZrEoC5fhOfYCY1LOHHr0TI+rQUHZS8Ttw2l7gl+80eHc/gFf2Ktkw0+SIACDTeWvpFcv3B04VembQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-environment-node@29.7.0: + resolution: {integrity: sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-get-type@29.6.3: + resolution: {integrity: sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-haste-map@29.7.0: + resolution: {integrity: sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-leak-detector@29.7.0: + resolution: {integrity: sha512-kYA8IJcSYtST2BY9I+SMC32nDpBT3J2NvWJx8+JCuCdl/CR1I4EKUJROiP8XtCcxqgTTBGJNdbB1A8XRKbTetw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-matcher-utils@29.7.0: + resolution: {integrity: sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-message-util@29.7.0: + resolution: {integrity: sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-mock@29.7.0: + resolution: {integrity: sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-pnp-resolver@1.2.3: + resolution: {integrity: sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==} + engines: {node: '>=6'} + peerDependencies: + jest-resolve: '*' + peerDependenciesMeta: + jest-resolve: + optional: true + + jest-regex-util@29.6.3: + resolution: {integrity: sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-resolve-dependencies@29.7.0: + resolution: {integrity: sha512-un0zD/6qxJ+S0et7WxeI3H5XSe9lTBBR7bOHCHXkKR6luG5mwDDlIzVQ0V5cZCuoTgEdcdwzTghYkTWfubi+nA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-resolve@29.7.0: + resolution: {integrity: sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-runner@29.7.0: + resolution: {integrity: sha512-fsc4N6cPCAahybGBfTRcq5wFR6fpLznMg47sY5aDpsoejOcVYFb07AHuSnR0liMcPTgBsA3ZJL6kFOjPdoNipQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-runtime@29.7.0: + resolution: {integrity: sha512-gUnLjgwdGqW7B4LvOIkbKs9WGbn+QLqRQQ9juC6HndeDiezIwhDP+mhMwHWCEcfQ5RUXa6OPnFF8BJh5xegwwQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-snapshot@29.7.0: + resolution: {integrity: sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-util@29.7.0: + resolution: {integrity: sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-validate@29.7.0: + resolution: {integrity: sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-watcher@29.7.0: + resolution: {integrity: sha512-49Fg7WXkU3Vl2h6LbLtMQ/HyB6rXSIX7SqvBLQmssRBGN9I0PNvPmAmCWSOY6SOvrjhI/F7/bGAv9RtnsPA03g==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-worker@29.7.0: + resolution: {integrity: sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest@29.7.0: + resolution: {integrity: sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + hasBin: true + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + + js-tokens@4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + + js-yaml@3.14.1: + resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==} + hasBin: true + + jsesc@3.0.2: + resolution: {integrity: sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==} + engines: {node: '>=6'} + hasBin: true + + json-parse-even-better-errors@2.3.1: + resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} + + json5@2.2.3: + resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} + engines: {node: '>=6'} + hasBin: true + + kleur@3.0.3: + resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==} + engines: {node: '>=6'} + + leven@3.1.0: + resolution: {integrity: sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==} + engines: {node: '>=6'} + + lines-and-columns@1.2.4: + resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} + + locate-path@5.0.0: + resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} + engines: {node: '>=8'} + + lodash.memoize@4.1.2: + resolution: {integrity: sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==} + + lru-cache@5.1.1: + resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} + + make-dir@4.0.0: + resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==} + engines: {node: '>=10'} + + make-error@1.3.6: + resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} + + makeerror@1.0.12: + resolution: {integrity: sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==} + + merge-stream@2.0.0: + resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} + + micromatch@4.0.8: + resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} + engines: {node: '>=8.6'} + + mimic-fn@2.1.0: + resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} + engines: {node: '>=6'} + + minimatch@3.1.2: + resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + + minimatch@5.1.6: + resolution: {integrity: sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==} + engines: {node: '>=10'} + + minipass@3.3.6: + resolution: {integrity: sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==} + engines: {node: '>=8'} + + minipass@5.0.0: + resolution: {integrity: sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==} + engines: {node: '>=8'} + + minizlib@2.1.2: + resolution: {integrity: sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==} + engines: {node: '>= 8'} + + mkdirp@1.0.4: + resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==} + engines: {node: '>=10'} + hasBin: true + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + natural-compare@1.4.0: + resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + + node-int64@0.4.0: + resolution: {integrity: sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==} + + node-releases@2.0.18: + resolution: {integrity: sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==} + + normalize-path@3.0.0: + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} + engines: {node: '>=0.10.0'} + + npm-run-path@4.0.1: + resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} + engines: {node: '>=8'} + + once@1.4.0: + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + + onetime@5.1.2: + resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} + engines: {node: '>=6'} + + p-limit@2.3.0: + resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} + engines: {node: '>=6'} + + p-limit@3.1.0: + resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} + engines: {node: '>=10'} + + p-locate@4.1.0: + resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} + engines: {node: '>=8'} + + p-try@2.2.0: + resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} + engines: {node: '>=6'} + + parse-json@5.2.0: + resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} + engines: {node: '>=8'} + + path-exists@4.0.0: + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} + engines: {node: '>=8'} + + 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-parse@1.0.7: + resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + + picocolors@1.1.0: + resolution: {integrity: sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==} + + picomatch@2.3.1: + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + engines: {node: '>=8.6'} + + pirates@4.0.6: + resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==} + engines: {node: '>= 6'} + + pkg-dir@4.2.0: + resolution: {integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==} + engines: {node: '>=8'} + + pretty-format@29.7.0: + resolution: {integrity: sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + prompts@2.4.2: + resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==} + engines: {node: '>= 6'} + + pure-rand@6.1.0: + resolution: {integrity: sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==} + + react-is@18.3.1: + resolution: {integrity: sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==} + + require-directory@2.1.1: + resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} + engines: {node: '>=0.10.0'} + + resolve-cwd@3.0.0: + resolution: {integrity: sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==} + engines: {node: '>=8'} + + resolve-from@5.0.0: + resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} + engines: {node: '>=8'} + + resolve.exports@2.0.2: + resolution: {integrity: sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg==} + engines: {node: '>=10'} + + resolve@1.22.8: + resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==} + hasBin: true + + rimraf@3.0.2: + resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} + deprecated: Rimraf versions prior to v4 are no longer supported + hasBin: true + + semver@6.3.1: + resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} + hasBin: true + + semver@7.6.3: + resolution: {integrity: sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==} + 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'} + + signal-exit@3.0.7: + resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} + + sisteransi@1.0.5: + resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} + + slash@3.0.0: + resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} + engines: {node: '>=8'} + + source-map-support@0.5.13: + resolution: {integrity: sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==} + + source-map-support@0.5.21: + resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} + + source-map@0.6.1: + resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} + engines: {node: '>=0.10.0'} + + sprintf-js@1.0.3: + resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} + + stack-utils@2.0.6: + resolution: {integrity: sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==} + engines: {node: '>=10'} + + string-length@4.0.2: + resolution: {integrity: sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==} + engines: {node: '>=10'} + + string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + + strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + + strip-bom@4.0.0: + resolution: {integrity: sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==} + engines: {node: '>=8'} + + strip-final-newline@2.0.0: + resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==} + engines: {node: '>=6'} + + strip-json-comments@3.1.1: + resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} + engines: {node: '>=8'} + + 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-color@8.1.1: + resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==} + engines: {node: '>=10'} + + supports-preserve-symlinks-flag@1.0.0: + resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} + engines: {node: '>= 0.4'} + + tar@6.2.1: + resolution: {integrity: sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==} + engines: {node: '>=10'} + + terser@5.36.0: + resolution: {integrity: sha512-IYV9eNMuFAV4THUspIRXkLakHnV6XO7FEdtKjf/mDyrnqUg9LnlOn6/RwRvM9SZjR4GUq8Nk8zj67FzVARr74w==} + engines: {node: '>=10'} + hasBin: true + + test-exclude@6.0.0: + resolution: {integrity: sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==} + engines: {node: '>=8'} + + tmpl@1.0.5: + resolution: {integrity: sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==} + + to-fast-properties@2.0.0: + resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} + engines: {node: '>=4'} + + to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + + ts-jest@29.2.5: + resolution: {integrity: sha512-KD8zB2aAZrcKIdGk4OwpJggeLcH1FgrICqDSROWqlnJXGCXK4Mn6FcdK2B6670Xr73lHMG1kHw8R87A0ecZ+vA==} + engines: {node: ^14.15.0 || ^16.10.0 || ^18.0.0 || >=20.0.0} + hasBin: true + peerDependencies: + '@babel/core': '>=7.0.0-beta.0 <8' + '@jest/transform': ^29.0.0 + '@jest/types': ^29.0.0 + babel-jest: ^29.0.0 + esbuild: '*' + jest: ^29.0.0 + typescript: '>=4.3 <6' + peerDependenciesMeta: + '@babel/core': + optional: true + '@jest/transform': + optional: true + '@jest/types': + optional: true + babel-jest: + optional: true + esbuild: + optional: true + + ts-node@10.9.2: + resolution: {integrity: sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==} + hasBin: true + peerDependencies: + '@swc/core': '>=1.2.50' + '@swc/wasm': '>=1.2.50' + '@types/node': '*' + typescript: '>=2.7' + peerDependenciesMeta: + '@swc/core': + optional: true + '@swc/wasm': + optional: true + + tslib@2.8.0: + resolution: {integrity: sha512-jWVzBLplnCmoaTr13V9dYbiQ99wvZRd0vNWaDRg+aVYRcjDF3nDksxFDE/+fkXnKhpnUUkmx5pK/v8mCtLVqZA==} + + type-detect@4.0.8: + resolution: {integrity: sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==} + engines: {node: '>=4'} + + type-fest@0.21.3: + resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==} + engines: {node: '>=10'} + + typescript@5.6.3: + resolution: {integrity: sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==} + engines: {node: '>=14.17'} + hasBin: true + + undici-types@6.19.8: + resolution: {integrity: sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==} + + update-browserslist-db@1.1.1: + resolution: {integrity: sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + + v8-compile-cache-lib@3.0.1: + resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==} + + v8-to-istanbul@9.3.0: + resolution: {integrity: sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==} + engines: {node: '>=10.12.0'} + + walker@1.0.8: + resolution: {integrity: sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==} + + wasm-pack@0.13.0: + resolution: {integrity: sha512-AmboGZEnZoIcVCzSlkLEmNFEqJN+IwgshJ5S7pi30uNUTce4LvWkifQzsQRxnWj47G8gkqZxlyGlyQplsnIS7w==} + hasBin: true + + which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + + wrap-ansi@7.0.0: + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} + + wrappy@1.0.2: + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + + write-file-atomic@4.0.2: + resolution: {integrity: sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + + y18n@5.0.8: + resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} + engines: {node: '>=10'} + + yallist@3.1.1: + resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} + + yallist@4.0.0: + resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} + + yargs-parser@21.1.1: + resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} + engines: {node: '>=12'} + + yargs@17.7.2: + resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} + engines: {node: '>=12'} + + yn@3.1.1: + resolution: {integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==} + engines: {node: '>=6'} + + yocto-queue@0.1.0: + resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} + engines: {node: '>=10'} + +snapshots: + + '@ampproject/remapping@2.3.0': + dependencies: + '@jridgewell/gen-mapping': 0.3.5 + '@jridgewell/trace-mapping': 0.3.25 + + '@babel/code-frame@7.25.7': + dependencies: + '@babel/highlight': 7.25.7 + picocolors: 1.1.0 + + '@babel/compat-data@7.25.8': {} + + '@babel/core@7.25.8': + dependencies: + '@ampproject/remapping': 2.3.0 + '@babel/code-frame': 7.25.7 + '@babel/generator': 7.25.7 + '@babel/helper-compilation-targets': 7.25.7 + '@babel/helper-module-transforms': 7.25.7(@babel/core@7.25.8) + '@babel/helpers': 7.25.7 + '@babel/parser': 7.25.8 + '@babel/template': 7.25.7 + '@babel/traverse': 7.25.7 + '@babel/types': 7.25.8 + convert-source-map: 2.0.0 + debug: 4.3.7 + gensync: 1.0.0-beta.2 + json5: 2.2.3 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/generator@7.25.7': + dependencies: + '@babel/types': 7.25.8 + '@jridgewell/gen-mapping': 0.3.5 + '@jridgewell/trace-mapping': 0.3.25 + jsesc: 3.0.2 + + '@babel/helper-compilation-targets@7.25.7': + dependencies: + '@babel/compat-data': 7.25.8 + '@babel/helper-validator-option': 7.25.7 + browserslist: 4.24.0 + lru-cache: 5.1.1 + semver: 6.3.1 + + '@babel/helper-module-imports@7.25.7': + dependencies: + '@babel/traverse': 7.25.7 + '@babel/types': 7.25.8 + transitivePeerDependencies: + - supports-color + + '@babel/helper-module-transforms@7.25.7(@babel/core@7.25.8)': + dependencies: + '@babel/core': 7.25.8 + '@babel/helper-module-imports': 7.25.7 + '@babel/helper-simple-access': 7.25.7 + '@babel/helper-validator-identifier': 7.25.7 + '@babel/traverse': 7.25.7 + transitivePeerDependencies: + - supports-color + + '@babel/helper-plugin-utils@7.25.7': {} + + '@babel/helper-simple-access@7.25.7': + dependencies: + '@babel/traverse': 7.25.7 + '@babel/types': 7.25.8 + transitivePeerDependencies: + - supports-color + + '@babel/helper-string-parser@7.25.7': {} + + '@babel/helper-validator-identifier@7.25.7': {} + + '@babel/helper-validator-option@7.25.7': {} + + '@babel/helpers@7.25.7': + dependencies: + '@babel/template': 7.25.7 + '@babel/types': 7.25.8 + + '@babel/highlight@7.25.7': + dependencies: + '@babel/helper-validator-identifier': 7.25.7 + chalk: 2.4.2 + js-tokens: 4.0.0 + picocolors: 1.1.0 + + '@babel/parser@7.25.8': + dependencies: + '@babel/types': 7.25.8 + + '@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.25.8)': + dependencies: + '@babel/core': 7.25.8 + '@babel/helper-plugin-utils': 7.25.7 + + '@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.25.8)': + dependencies: + '@babel/core': 7.25.8 + '@babel/helper-plugin-utils': 7.25.7 + + '@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.25.8)': + dependencies: + '@babel/core': 7.25.8 + '@babel/helper-plugin-utils': 7.25.7 + + '@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@7.25.8)': + dependencies: + '@babel/core': 7.25.8 + '@babel/helper-plugin-utils': 7.25.7 + + '@babel/plugin-syntax-import-attributes@7.25.7(@babel/core@7.25.8)': + dependencies: + '@babel/core': 7.25.8 + '@babel/helper-plugin-utils': 7.25.7 + + '@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.25.8)': + dependencies: + '@babel/core': 7.25.8 + '@babel/helper-plugin-utils': 7.25.7 + + '@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.25.8)': + dependencies: + '@babel/core': 7.25.8 + '@babel/helper-plugin-utils': 7.25.7 + + '@babel/plugin-syntax-jsx@7.25.7(@babel/core@7.25.8)': + dependencies: + '@babel/core': 7.25.8 + '@babel/helper-plugin-utils': 7.25.7 + + '@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.25.8)': + dependencies: + '@babel/core': 7.25.8 + '@babel/helper-plugin-utils': 7.25.7 + + '@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.25.8)': + dependencies: + '@babel/core': 7.25.8 + '@babel/helper-plugin-utils': 7.25.7 + + '@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.25.8)': + dependencies: + '@babel/core': 7.25.8 + '@babel/helper-plugin-utils': 7.25.7 + + '@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.25.8)': + dependencies: + '@babel/core': 7.25.8 + '@babel/helper-plugin-utils': 7.25.7 + + '@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.25.8)': + dependencies: + '@babel/core': 7.25.8 + '@babel/helper-plugin-utils': 7.25.7 + + '@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.25.8)': + dependencies: + '@babel/core': 7.25.8 + '@babel/helper-plugin-utils': 7.25.7 + + '@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.25.8)': + dependencies: + '@babel/core': 7.25.8 + '@babel/helper-plugin-utils': 7.25.7 + + '@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.25.8)': + dependencies: + '@babel/core': 7.25.8 + '@babel/helper-plugin-utils': 7.25.7 + + '@babel/plugin-syntax-typescript@7.25.7(@babel/core@7.25.8)': + dependencies: + '@babel/core': 7.25.8 + '@babel/helper-plugin-utils': 7.25.7 + + '@babel/template@7.25.7': + dependencies: + '@babel/code-frame': 7.25.7 + '@babel/parser': 7.25.8 + '@babel/types': 7.25.8 + + '@babel/traverse@7.25.7': + dependencies: + '@babel/code-frame': 7.25.7 + '@babel/generator': 7.25.7 + '@babel/parser': 7.25.8 + '@babel/template': 7.25.7 + '@babel/types': 7.25.8 + debug: 4.3.7 + globals: 11.12.0 + transitivePeerDependencies: + - supports-color + + '@babel/types@7.25.8': + dependencies: + '@babel/helper-string-parser': 7.25.7 + '@babel/helper-validator-identifier': 7.25.7 + to-fast-properties: 2.0.0 + + '@bcoe/v8-coverage@0.2.3': {} + + '@cspotcode/source-map-support@0.8.1': + dependencies: + '@jridgewell/trace-mapping': 0.3.9 + + '@istanbuljs/load-nyc-config@1.1.0': + dependencies: + camelcase: 5.3.1 + find-up: 4.1.0 + get-package-type: 0.1.0 + js-yaml: 3.14.1 + resolve-from: 5.0.0 + + '@istanbuljs/schema@0.1.3': {} + + '@jest/console@29.7.0': + dependencies: + '@jest/types': 29.6.3 + '@types/node': 22.7.9 + chalk: 4.1.2 + jest-message-util: 29.7.0 + jest-util: 29.7.0 + slash: 3.0.0 + + '@jest/core@29.7.0(ts-node@10.9.2(@types/node@22.7.9)(typescript@5.6.3))': + dependencies: + '@jest/console': 29.7.0 + '@jest/reporters': 29.7.0 + '@jest/test-result': 29.7.0 + '@jest/transform': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 22.7.9 + ansi-escapes: 4.3.2 + chalk: 4.1.2 + ci-info: 3.9.0 + exit: 0.1.2 + graceful-fs: 4.2.11 + jest-changed-files: 29.7.0 + jest-config: 29.7.0(@types/node@22.7.9)(ts-node@10.9.2(@types/node@22.7.9)(typescript@5.6.3)) + jest-haste-map: 29.7.0 + jest-message-util: 29.7.0 + jest-regex-util: 29.6.3 + jest-resolve: 29.7.0 + jest-resolve-dependencies: 29.7.0 + jest-runner: 29.7.0 + jest-runtime: 29.7.0 + jest-snapshot: 29.7.0 + jest-util: 29.7.0 + jest-validate: 29.7.0 + jest-watcher: 29.7.0 + micromatch: 4.0.8 + pretty-format: 29.7.0 + slash: 3.0.0 + strip-ansi: 6.0.1 + transitivePeerDependencies: + - babel-plugin-macros + - supports-color + - ts-node + + '@jest/environment@29.7.0': + dependencies: + '@jest/fake-timers': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 22.7.9 + jest-mock: 29.7.0 + + '@jest/expect-utils@29.7.0': + dependencies: + jest-get-type: 29.6.3 + + '@jest/expect@29.7.0': + dependencies: + expect: 29.7.0 + jest-snapshot: 29.7.0 + transitivePeerDependencies: + - supports-color + + '@jest/fake-timers@29.7.0': + dependencies: + '@jest/types': 29.6.3 + '@sinonjs/fake-timers': 10.3.0 + '@types/node': 22.7.9 + jest-message-util: 29.7.0 + jest-mock: 29.7.0 + jest-util: 29.7.0 + + '@jest/globals@29.7.0': + dependencies: + '@jest/environment': 29.7.0 + '@jest/expect': 29.7.0 + '@jest/types': 29.6.3 + jest-mock: 29.7.0 + transitivePeerDependencies: + - supports-color + + '@jest/reporters@29.7.0': + dependencies: + '@bcoe/v8-coverage': 0.2.3 + '@jest/console': 29.7.0 + '@jest/test-result': 29.7.0 + '@jest/transform': 29.7.0 + '@jest/types': 29.6.3 + '@jridgewell/trace-mapping': 0.3.25 + '@types/node': 22.7.9 + chalk: 4.1.2 + collect-v8-coverage: 1.0.2 + exit: 0.1.2 + glob: 7.2.3 + graceful-fs: 4.2.11 + istanbul-lib-coverage: 3.2.2 + istanbul-lib-instrument: 6.0.3 + istanbul-lib-report: 3.0.1 + istanbul-lib-source-maps: 4.0.1 + istanbul-reports: 3.1.7 + jest-message-util: 29.7.0 + jest-util: 29.7.0 + jest-worker: 29.7.0 + slash: 3.0.0 + string-length: 4.0.2 + strip-ansi: 6.0.1 + v8-to-istanbul: 9.3.0 + transitivePeerDependencies: + - supports-color + + '@jest/schemas@29.6.3': + dependencies: + '@sinclair/typebox': 0.27.8 + + '@jest/source-map@29.6.3': + dependencies: + '@jridgewell/trace-mapping': 0.3.25 + callsites: 3.1.0 + graceful-fs: 4.2.11 + + '@jest/test-result@29.7.0': + dependencies: + '@jest/console': 29.7.0 + '@jest/types': 29.6.3 + '@types/istanbul-lib-coverage': 2.0.6 + collect-v8-coverage: 1.0.2 + + '@jest/test-sequencer@29.7.0': + dependencies: + '@jest/test-result': 29.7.0 + graceful-fs: 4.2.11 + jest-haste-map: 29.7.0 + slash: 3.0.0 + + '@jest/transform@29.7.0': + dependencies: + '@babel/core': 7.25.8 + '@jest/types': 29.6.3 + '@jridgewell/trace-mapping': 0.3.25 + babel-plugin-istanbul: 6.1.1 + chalk: 4.1.2 + convert-source-map: 2.0.0 + fast-json-stable-stringify: 2.1.0 + graceful-fs: 4.2.11 + jest-haste-map: 29.7.0 + jest-regex-util: 29.6.3 + jest-util: 29.7.0 + micromatch: 4.0.8 + pirates: 4.0.6 + slash: 3.0.0 + write-file-atomic: 4.0.2 + transitivePeerDependencies: + - supports-color + + '@jest/types@29.6.3': + dependencies: + '@jest/schemas': 29.6.3 + '@types/istanbul-lib-coverage': 2.0.6 + '@types/istanbul-reports': 3.0.4 + '@types/node': 22.7.9 + '@types/yargs': 17.0.33 + chalk: 4.1.2 + + '@jridgewell/gen-mapping@0.3.5': + dependencies: + '@jridgewell/set-array': 1.2.1 + '@jridgewell/sourcemap-codec': 1.5.0 + '@jridgewell/trace-mapping': 0.3.25 + + '@jridgewell/resolve-uri@3.1.2': {} + + '@jridgewell/set-array@1.2.1': {} + + '@jridgewell/source-map@0.3.6': + dependencies: + '@jridgewell/gen-mapping': 0.3.5 + '@jridgewell/trace-mapping': 0.3.25 + + '@jridgewell/sourcemap-codec@1.5.0': {} + + '@jridgewell/trace-mapping@0.3.25': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.0 + + '@jridgewell/trace-mapping@0.3.9': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.0 + + '@sinclair/typebox@0.27.8': {} + + '@sinonjs/commons@3.0.1': + dependencies: + type-detect: 4.0.8 + + '@sinonjs/fake-timers@10.3.0': + dependencies: + '@sinonjs/commons': 3.0.1 + + '@tsconfig/node10@1.0.11': {} + + '@tsconfig/node12@1.0.11': {} + + '@tsconfig/node14@1.0.3': {} + + '@tsconfig/node16@1.0.4': {} + + '@types/babel__core@7.20.5': + dependencies: + '@babel/parser': 7.25.8 + '@babel/types': 7.25.8 + '@types/babel__generator': 7.6.8 + '@types/babel__template': 7.4.4 + '@types/babel__traverse': 7.20.6 + + '@types/babel__generator@7.6.8': + dependencies: + '@babel/types': 7.25.8 + + '@types/babel__template@7.4.4': + dependencies: + '@babel/parser': 7.25.8 + '@babel/types': 7.25.8 + + '@types/babel__traverse@7.20.6': + dependencies: + '@babel/types': 7.25.8 + + '@types/graceful-fs@4.1.9': + dependencies: + '@types/node': 22.7.9 + + '@types/istanbul-lib-coverage@2.0.6': {} + + '@types/istanbul-lib-report@3.0.3': + dependencies: + '@types/istanbul-lib-coverage': 2.0.6 + + '@types/istanbul-reports@3.0.4': + dependencies: + '@types/istanbul-lib-report': 3.0.3 + + '@types/jest@29.5.14': + dependencies: + expect: 29.7.0 + pretty-format: 29.7.0 + + '@types/node@22.7.9': + dependencies: + undici-types: 6.19.8 + + '@types/stack-utils@2.0.3': {} + + '@types/yargs-parser@21.0.3': {} + + '@types/yargs@17.0.33': + dependencies: + '@types/yargs-parser': 21.0.3 + + acorn-walk@8.3.4: + dependencies: + acorn: 8.13.0 + + acorn@8.13.0: {} + + ansi-escapes@4.3.2: + dependencies: + type-fest: 0.21.3 + + ansi-regex@5.0.1: {} + + ansi-styles@3.2.1: + dependencies: + color-convert: 1.9.3 + + ansi-styles@4.3.0: + dependencies: + color-convert: 2.0.1 + + ansi-styles@5.2.0: {} + + anymatch@3.1.3: + dependencies: + normalize-path: 3.0.0 + picomatch: 2.3.1 + + arg@4.1.3: {} + + argparse@1.0.10: + dependencies: + sprintf-js: 1.0.3 + + async@3.2.6: {} + + axios@0.26.1: + dependencies: + follow-redirects: 1.15.9 + transitivePeerDependencies: + - debug + + babel-jest@29.7.0(@babel/core@7.25.8): + dependencies: + '@babel/core': 7.25.8 + '@jest/transform': 29.7.0 + '@types/babel__core': 7.20.5 + babel-plugin-istanbul: 6.1.1 + babel-preset-jest: 29.6.3(@babel/core@7.25.8) + chalk: 4.1.2 + graceful-fs: 4.2.11 + slash: 3.0.0 + transitivePeerDependencies: + - supports-color + + babel-plugin-istanbul@6.1.1: + dependencies: + '@babel/helper-plugin-utils': 7.25.7 + '@istanbuljs/load-nyc-config': 1.1.0 + '@istanbuljs/schema': 0.1.3 + istanbul-lib-instrument: 5.2.1 + test-exclude: 6.0.0 + transitivePeerDependencies: + - supports-color + + babel-plugin-jest-hoist@29.6.3: + dependencies: + '@babel/template': 7.25.7 + '@babel/types': 7.25.8 + '@types/babel__core': 7.20.5 + '@types/babel__traverse': 7.20.6 + + babel-preset-current-node-syntax@1.1.0(@babel/core@7.25.8): + dependencies: + '@babel/core': 7.25.8 + '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.25.8) + '@babel/plugin-syntax-bigint': 7.8.3(@babel/core@7.25.8) + '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.25.8) + '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.25.8) + '@babel/plugin-syntax-import-attributes': 7.25.7(@babel/core@7.25.8) + '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.25.8) + '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.25.8) + '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.25.8) + '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.25.8) + '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.25.8) + '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.25.8) + '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.25.8) + '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.25.8) + '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.25.8) + '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.25.8) + + babel-preset-jest@29.6.3(@babel/core@7.25.8): + dependencies: + '@babel/core': 7.25.8 + babel-plugin-jest-hoist: 29.6.3 + babel-preset-current-node-syntax: 1.1.0(@babel/core@7.25.8) + + balanced-match@1.0.2: {} + + binary-install@1.1.0: + dependencies: + axios: 0.26.1 + rimraf: 3.0.2 + tar: 6.2.1 + transitivePeerDependencies: + - debug + + 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 + + braces@3.0.3: + dependencies: + fill-range: 7.1.1 + + browserslist@4.24.0: + dependencies: + caniuse-lite: 1.0.30001669 + electron-to-chromium: 1.5.39 + node-releases: 2.0.18 + update-browserslist-db: 1.1.1(browserslist@4.24.0) + + bs-logger@0.2.6: + dependencies: + fast-json-stable-stringify: 2.1.0 + + bser@2.1.1: + dependencies: + node-int64: 0.4.0 + + buffer-from@1.1.2: {} + + callsites@3.1.0: {} + + camelcase@5.3.1: {} + + camelcase@6.3.0: {} + + caniuse-lite@1.0.30001669: {} + + chalk@2.4.2: + dependencies: + ansi-styles: 3.2.1 + escape-string-regexp: 1.0.5 + supports-color: 5.5.0 + + chalk@4.1.2: + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + + char-regex@1.0.2: {} + + chownr@2.0.0: {} + + ci-info@3.9.0: {} + + cjs-module-lexer@1.4.1: {} + + cliui@8.0.1: + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 7.0.0 + + co@4.6.0: {} + + collect-v8-coverage@1.0.2: {} + + color-convert@1.9.3: + dependencies: + color-name: 1.1.3 + + color-convert@2.0.1: + dependencies: + color-name: 1.1.4 + + color-name@1.1.3: {} + + color-name@1.1.4: {} + + commander@2.20.3: {} + + concat-map@0.0.1: {} + + convert-source-map@2.0.0: {} + + create-jest@29.7.0(@types/node@22.7.9)(ts-node@10.9.2(@types/node@22.7.9)(typescript@5.6.3)): + dependencies: + '@jest/types': 29.6.3 + chalk: 4.1.2 + exit: 0.1.2 + graceful-fs: 4.2.11 + jest-config: 29.7.0(@types/node@22.7.9)(ts-node@10.9.2(@types/node@22.7.9)(typescript@5.6.3)) + jest-util: 29.7.0 + prompts: 2.4.2 + transitivePeerDependencies: + - '@types/node' + - babel-plugin-macros + - supports-color + - ts-node + + create-require@1.1.1: {} + + cross-spawn@7.0.3: + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + + debug@4.3.7: + dependencies: + ms: 2.1.3 + + dedent@1.5.3: {} + + deepmerge@4.3.1: {} + + detect-newline@3.1.0: {} + + diff-sequences@29.6.3: {} + + diff@4.0.2: {} + + ejs@3.1.10: + dependencies: + jake: 10.9.2 + + electron-to-chromium@1.5.39: {} + + emittery@0.13.1: {} + + emoji-regex@8.0.0: {} + + error-ex@1.3.2: + dependencies: + is-arrayish: 0.2.1 + + escalade@3.2.0: {} + + escape-string-regexp@1.0.5: {} + + escape-string-regexp@2.0.0: {} + + esprima@4.0.1: {} + + execa@5.1.1: + dependencies: + cross-spawn: 7.0.3 + get-stream: 6.0.1 + human-signals: 2.1.0 + is-stream: 2.0.1 + merge-stream: 2.0.0 + npm-run-path: 4.0.1 + onetime: 5.1.2 + signal-exit: 3.0.7 + strip-final-newline: 2.0.0 + + exit@0.1.2: {} + + expect@29.7.0: + dependencies: + '@jest/expect-utils': 29.7.0 + jest-get-type: 29.6.3 + jest-matcher-utils: 29.7.0 + jest-message-util: 29.7.0 + jest-util: 29.7.0 + + fast-json-stable-stringify@2.1.0: {} + + fb-watchman@2.0.2: + dependencies: + bser: 2.1.1 + + filelist@1.0.4: + dependencies: + minimatch: 5.1.6 + + fill-range@7.1.1: + dependencies: + to-regex-range: 5.0.1 + + find-up@4.1.0: + dependencies: + locate-path: 5.0.0 + path-exists: 4.0.0 + + follow-redirects@1.15.9: {} + + fs-minipass@2.1.0: + dependencies: + minipass: 3.3.6 + + fs.realpath@1.0.0: {} + + fsevents@2.3.3: + optional: true + + function-bind@1.1.2: {} + + gensync@1.0.0-beta.2: {} + + get-caller-file@2.0.5: {} + + get-package-type@0.1.0: {} + + get-stream@6.0.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 + + globals@11.12.0: {} + + graceful-fs@4.2.11: {} + + has-flag@3.0.0: {} + + has-flag@4.0.0: {} + + hasown@2.0.2: + dependencies: + function-bind: 1.1.2 + + html-escaper@2.0.2: {} + + human-signals@2.1.0: {} + + import-local@3.2.0: + dependencies: + pkg-dir: 4.2.0 + resolve-cwd: 3.0.0 + + imurmurhash@0.1.4: {} + + inflight@1.0.6: + dependencies: + once: 1.4.0 + wrappy: 1.0.2 + + inherits@2.0.4: {} + + is-arrayish@0.2.1: {} + + is-core-module@2.15.1: + dependencies: + hasown: 2.0.2 + + is-fullwidth-code-point@3.0.0: {} + + is-generator-fn@2.1.0: {} + + is-number@7.0.0: {} + + is-stream@2.0.1: {} + + isexe@2.0.0: {} + + istanbul-lib-coverage@3.2.2: {} + + istanbul-lib-instrument@5.2.1: + dependencies: + '@babel/core': 7.25.8 + '@babel/parser': 7.25.8 + '@istanbuljs/schema': 0.1.3 + istanbul-lib-coverage: 3.2.2 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + istanbul-lib-instrument@6.0.3: + dependencies: + '@babel/core': 7.25.8 + '@babel/parser': 7.25.8 + '@istanbuljs/schema': 0.1.3 + istanbul-lib-coverage: 3.2.2 + semver: 7.6.3 + transitivePeerDependencies: + - supports-color + + 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@4.0.1: + dependencies: + debug: 4.3.7 + istanbul-lib-coverage: 3.2.2 + source-map: 0.6.1 + transitivePeerDependencies: + - supports-color + + istanbul-reports@3.1.7: + dependencies: + html-escaper: 2.0.2 + istanbul-lib-report: 3.0.1 + + jake@10.9.2: + dependencies: + async: 3.2.6 + chalk: 4.1.2 + filelist: 1.0.4 + minimatch: 3.1.2 + + jest-changed-files@29.7.0: + dependencies: + execa: 5.1.1 + jest-util: 29.7.0 + p-limit: 3.1.0 + + jest-circus@29.7.0: + dependencies: + '@jest/environment': 29.7.0 + '@jest/expect': 29.7.0 + '@jest/test-result': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 22.7.9 + chalk: 4.1.2 + co: 4.6.0 + dedent: 1.5.3 + is-generator-fn: 2.1.0 + jest-each: 29.7.0 + jest-matcher-utils: 29.7.0 + jest-message-util: 29.7.0 + jest-runtime: 29.7.0 + jest-snapshot: 29.7.0 + jest-util: 29.7.0 + p-limit: 3.1.0 + pretty-format: 29.7.0 + pure-rand: 6.1.0 + slash: 3.0.0 + stack-utils: 2.0.6 + transitivePeerDependencies: + - babel-plugin-macros + - supports-color + + jest-cli@29.7.0(@types/node@22.7.9)(ts-node@10.9.2(@types/node@22.7.9)(typescript@5.6.3)): + dependencies: + '@jest/core': 29.7.0(ts-node@10.9.2(@types/node@22.7.9)(typescript@5.6.3)) + '@jest/test-result': 29.7.0 + '@jest/types': 29.6.3 + chalk: 4.1.2 + create-jest: 29.7.0(@types/node@22.7.9)(ts-node@10.9.2(@types/node@22.7.9)(typescript@5.6.3)) + exit: 0.1.2 + import-local: 3.2.0 + jest-config: 29.7.0(@types/node@22.7.9)(ts-node@10.9.2(@types/node@22.7.9)(typescript@5.6.3)) + jest-util: 29.7.0 + jest-validate: 29.7.0 + yargs: 17.7.2 + transitivePeerDependencies: + - '@types/node' + - babel-plugin-macros + - supports-color + - ts-node + + jest-config@29.7.0(@types/node@22.7.9)(ts-node@10.9.2(@types/node@22.7.9)(typescript@5.6.3)): + dependencies: + '@babel/core': 7.25.8 + '@jest/test-sequencer': 29.7.0 + '@jest/types': 29.6.3 + babel-jest: 29.7.0(@babel/core@7.25.8) + chalk: 4.1.2 + ci-info: 3.9.0 + deepmerge: 4.3.1 + glob: 7.2.3 + graceful-fs: 4.2.11 + jest-circus: 29.7.0 + jest-environment-node: 29.7.0 + jest-get-type: 29.6.3 + jest-regex-util: 29.6.3 + jest-resolve: 29.7.0 + jest-runner: 29.7.0 + jest-util: 29.7.0 + jest-validate: 29.7.0 + micromatch: 4.0.8 + parse-json: 5.2.0 + pretty-format: 29.7.0 + slash: 3.0.0 + strip-json-comments: 3.1.1 + optionalDependencies: + '@types/node': 22.7.9 + ts-node: 10.9.2(@types/node@22.7.9)(typescript@5.6.3) + transitivePeerDependencies: + - babel-plugin-macros + - supports-color + + jest-diff@29.7.0: + dependencies: + chalk: 4.1.2 + diff-sequences: 29.6.3 + jest-get-type: 29.6.3 + pretty-format: 29.7.0 + + jest-docblock@29.7.0: + dependencies: + detect-newline: 3.1.0 + + jest-each@29.7.0: + dependencies: + '@jest/types': 29.6.3 + chalk: 4.1.2 + jest-get-type: 29.6.3 + jest-util: 29.7.0 + pretty-format: 29.7.0 + + jest-environment-node@29.7.0: + dependencies: + '@jest/environment': 29.7.0 + '@jest/fake-timers': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 22.7.9 + jest-mock: 29.7.0 + jest-util: 29.7.0 + + jest-get-type@29.6.3: {} + + jest-haste-map@29.7.0: + dependencies: + '@jest/types': 29.6.3 + '@types/graceful-fs': 4.1.9 + '@types/node': 22.7.9 + anymatch: 3.1.3 + fb-watchman: 2.0.2 + graceful-fs: 4.2.11 + jest-regex-util: 29.6.3 + jest-util: 29.7.0 + jest-worker: 29.7.0 + micromatch: 4.0.8 + walker: 1.0.8 + optionalDependencies: + fsevents: 2.3.3 + + jest-leak-detector@29.7.0: + dependencies: + jest-get-type: 29.6.3 + pretty-format: 29.7.0 + + jest-matcher-utils@29.7.0: + dependencies: + chalk: 4.1.2 + jest-diff: 29.7.0 + jest-get-type: 29.6.3 + pretty-format: 29.7.0 + + jest-message-util@29.7.0: + dependencies: + '@babel/code-frame': 7.25.7 + '@jest/types': 29.6.3 + '@types/stack-utils': 2.0.3 + chalk: 4.1.2 + graceful-fs: 4.2.11 + micromatch: 4.0.8 + pretty-format: 29.7.0 + slash: 3.0.0 + stack-utils: 2.0.6 + + jest-mock@29.7.0: + dependencies: + '@jest/types': 29.6.3 + '@types/node': 22.7.9 + jest-util: 29.7.0 + + jest-pnp-resolver@1.2.3(jest-resolve@29.7.0): + optionalDependencies: + jest-resolve: 29.7.0 + + jest-regex-util@29.6.3: {} + + jest-resolve-dependencies@29.7.0: + dependencies: + jest-regex-util: 29.6.3 + jest-snapshot: 29.7.0 + transitivePeerDependencies: + - supports-color + + jest-resolve@29.7.0: + dependencies: + chalk: 4.1.2 + graceful-fs: 4.2.11 + jest-haste-map: 29.7.0 + jest-pnp-resolver: 1.2.3(jest-resolve@29.7.0) + jest-util: 29.7.0 + jest-validate: 29.7.0 + resolve: 1.22.8 + resolve.exports: 2.0.2 + slash: 3.0.0 + + jest-runner@29.7.0: + dependencies: + '@jest/console': 29.7.0 + '@jest/environment': 29.7.0 + '@jest/test-result': 29.7.0 + '@jest/transform': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 22.7.9 + chalk: 4.1.2 + emittery: 0.13.1 + graceful-fs: 4.2.11 + jest-docblock: 29.7.0 + jest-environment-node: 29.7.0 + jest-haste-map: 29.7.0 + jest-leak-detector: 29.7.0 + jest-message-util: 29.7.0 + jest-resolve: 29.7.0 + jest-runtime: 29.7.0 + jest-util: 29.7.0 + jest-watcher: 29.7.0 + jest-worker: 29.7.0 + p-limit: 3.1.0 + source-map-support: 0.5.13 + transitivePeerDependencies: + - supports-color + + jest-runtime@29.7.0: + dependencies: + '@jest/environment': 29.7.0 + '@jest/fake-timers': 29.7.0 + '@jest/globals': 29.7.0 + '@jest/source-map': 29.6.3 + '@jest/test-result': 29.7.0 + '@jest/transform': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 22.7.9 + chalk: 4.1.2 + cjs-module-lexer: 1.4.1 + collect-v8-coverage: 1.0.2 + glob: 7.2.3 + graceful-fs: 4.2.11 + jest-haste-map: 29.7.0 + jest-message-util: 29.7.0 + jest-mock: 29.7.0 + jest-regex-util: 29.6.3 + jest-resolve: 29.7.0 + jest-snapshot: 29.7.0 + jest-util: 29.7.0 + slash: 3.0.0 + strip-bom: 4.0.0 + transitivePeerDependencies: + - supports-color + + jest-snapshot@29.7.0: + dependencies: + '@babel/core': 7.25.8 + '@babel/generator': 7.25.7 + '@babel/plugin-syntax-jsx': 7.25.7(@babel/core@7.25.8) + '@babel/plugin-syntax-typescript': 7.25.7(@babel/core@7.25.8) + '@babel/types': 7.25.8 + '@jest/expect-utils': 29.7.0 + '@jest/transform': 29.7.0 + '@jest/types': 29.6.3 + babel-preset-current-node-syntax: 1.1.0(@babel/core@7.25.8) + chalk: 4.1.2 + expect: 29.7.0 + graceful-fs: 4.2.11 + jest-diff: 29.7.0 + jest-get-type: 29.6.3 + jest-matcher-utils: 29.7.0 + jest-message-util: 29.7.0 + jest-util: 29.7.0 + natural-compare: 1.4.0 + pretty-format: 29.7.0 + semver: 7.6.3 + transitivePeerDependencies: + - supports-color + + jest-util@29.7.0: + dependencies: + '@jest/types': 29.6.3 + '@types/node': 22.7.9 + chalk: 4.1.2 + ci-info: 3.9.0 + graceful-fs: 4.2.11 + picomatch: 2.3.1 + + jest-validate@29.7.0: + dependencies: + '@jest/types': 29.6.3 + camelcase: 6.3.0 + chalk: 4.1.2 + jest-get-type: 29.6.3 + leven: 3.1.0 + pretty-format: 29.7.0 + + jest-watcher@29.7.0: + dependencies: + '@jest/test-result': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 22.7.9 + ansi-escapes: 4.3.2 + chalk: 4.1.2 + emittery: 0.13.1 + jest-util: 29.7.0 + string-length: 4.0.2 + + jest-worker@29.7.0: + dependencies: + '@types/node': 22.7.9 + jest-util: 29.7.0 + merge-stream: 2.0.0 + supports-color: 8.1.1 + + jest@29.7.0(@types/node@22.7.9)(ts-node@10.9.2(@types/node@22.7.9)(typescript@5.6.3)): + dependencies: + '@jest/core': 29.7.0(ts-node@10.9.2(@types/node@22.7.9)(typescript@5.6.3)) + '@jest/types': 29.6.3 + import-local: 3.2.0 + jest-cli: 29.7.0(@types/node@22.7.9)(ts-node@10.9.2(@types/node@22.7.9)(typescript@5.6.3)) + transitivePeerDependencies: + - '@types/node' + - babel-plugin-macros + - supports-color + - ts-node + + js-tokens@4.0.0: {} + + js-yaml@3.14.1: + dependencies: + argparse: 1.0.10 + esprima: 4.0.1 + + jsesc@3.0.2: {} + + json-parse-even-better-errors@2.3.1: {} + + json5@2.2.3: {} + + kleur@3.0.3: {} + + leven@3.1.0: {} + + lines-and-columns@1.2.4: {} + + locate-path@5.0.0: + dependencies: + p-locate: 4.1.0 + + lodash.memoize@4.1.2: {} + + lru-cache@5.1.1: + dependencies: + yallist: 3.1.1 + + make-dir@4.0.0: + dependencies: + semver: 7.6.3 + + make-error@1.3.6: {} + + makeerror@1.0.12: + dependencies: + tmpl: 1.0.5 + + merge-stream@2.0.0: {} + + micromatch@4.0.8: + dependencies: + braces: 3.0.3 + picomatch: 2.3.1 + + mimic-fn@2.1.0: {} + + minimatch@3.1.2: + dependencies: + brace-expansion: 1.1.11 + + minimatch@5.1.6: + dependencies: + brace-expansion: 2.0.1 + + minipass@3.3.6: + dependencies: + yallist: 4.0.0 + + minipass@5.0.0: {} + + minizlib@2.1.2: + dependencies: + minipass: 3.3.6 + yallist: 4.0.0 + + mkdirp@1.0.4: {} + + ms@2.1.3: {} + + natural-compare@1.4.0: {} + + node-int64@0.4.0: {} + + node-releases@2.0.18: {} + + normalize-path@3.0.0: {} + + npm-run-path@4.0.1: + dependencies: + path-key: 3.1.1 + + once@1.4.0: + dependencies: + wrappy: 1.0.2 + + onetime@5.1.2: + dependencies: + mimic-fn: 2.1.0 + + p-limit@2.3.0: + dependencies: + p-try: 2.2.0 + + p-limit@3.1.0: + dependencies: + yocto-queue: 0.1.0 + + p-locate@4.1.0: + dependencies: + p-limit: 2.3.0 + + p-try@2.2.0: {} + + parse-json@5.2.0: + dependencies: + '@babel/code-frame': 7.25.7 + error-ex: 1.3.2 + json-parse-even-better-errors: 2.3.1 + lines-and-columns: 1.2.4 + + path-exists@4.0.0: {} + + path-is-absolute@1.0.1: {} + + path-key@3.1.1: {} + + path-parse@1.0.7: {} + + picocolors@1.1.0: {} + + picomatch@2.3.1: {} + + pirates@4.0.6: {} + + pkg-dir@4.2.0: + dependencies: + find-up: 4.1.0 + + pretty-format@29.7.0: + dependencies: + '@jest/schemas': 29.6.3 + ansi-styles: 5.2.0 + react-is: 18.3.1 + + prompts@2.4.2: + dependencies: + kleur: 3.0.3 + sisteransi: 1.0.5 + + pure-rand@6.1.0: {} + + react-is@18.3.1: {} + + require-directory@2.1.1: {} + + resolve-cwd@3.0.0: + dependencies: + resolve-from: 5.0.0 + + resolve-from@5.0.0: {} + + resolve.exports@2.0.2: {} + + resolve@1.22.8: + dependencies: + is-core-module: 2.15.1 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + + rimraf@3.0.2: + dependencies: + glob: 7.2.3 + + semver@6.3.1: {} + + semver@7.6.3: {} + + shebang-command@2.0.0: + dependencies: + shebang-regex: 3.0.0 + + shebang-regex@3.0.0: {} + + signal-exit@3.0.7: {} + + sisteransi@1.0.5: {} + + slash@3.0.0: {} + + source-map-support@0.5.13: + dependencies: + buffer-from: 1.1.2 + source-map: 0.6.1 + + source-map-support@0.5.21: + dependencies: + buffer-from: 1.1.2 + source-map: 0.6.1 + + source-map@0.6.1: {} + + sprintf-js@1.0.3: {} + + stack-utils@2.0.6: + dependencies: + escape-string-regexp: 2.0.0 + + string-length@4.0.2: + dependencies: + char-regex: 1.0.2 + strip-ansi: 6.0.1 + + string-width@4.2.3: + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + + strip-ansi@6.0.1: + dependencies: + ansi-regex: 5.0.1 + + strip-bom@4.0.0: {} + + strip-final-newline@2.0.0: {} + + strip-json-comments@3.1.1: {} + + supports-color@5.5.0: + dependencies: + has-flag: 3.0.0 + + supports-color@7.2.0: + dependencies: + has-flag: 4.0.0 + + supports-color@8.1.1: + dependencies: + has-flag: 4.0.0 + + supports-preserve-symlinks-flag@1.0.0: {} + + 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 + + terser@5.36.0: + dependencies: + '@jridgewell/source-map': 0.3.6 + acorn: 8.13.0 + commander: 2.20.3 + source-map-support: 0.5.21 + + test-exclude@6.0.0: + dependencies: + '@istanbuljs/schema': 0.1.3 + glob: 7.2.3 + minimatch: 3.1.2 + + tmpl@1.0.5: {} + + to-fast-properties@2.0.0: {} + + to-regex-range@5.0.1: + dependencies: + is-number: 7.0.0 + + ts-jest@29.2.5(@babel/core@7.25.8)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.25.8))(jest@29.7.0(@types/node@22.7.9)(ts-node@10.9.2(@types/node@22.7.9)(typescript@5.6.3)))(typescript@5.6.3): + dependencies: + bs-logger: 0.2.6 + ejs: 3.1.10 + fast-json-stable-stringify: 2.1.0 + jest: 29.7.0(@types/node@22.7.9)(ts-node@10.9.2(@types/node@22.7.9)(typescript@5.6.3)) + jest-util: 29.7.0 + json5: 2.2.3 + lodash.memoize: 4.1.2 + make-error: 1.3.6 + semver: 7.6.3 + typescript: 5.6.3 + yargs-parser: 21.1.1 + optionalDependencies: + '@babel/core': 7.25.8 + '@jest/transform': 29.7.0 + '@jest/types': 29.6.3 + babel-jest: 29.7.0(@babel/core@7.25.8) + + ts-node@10.9.2(@types/node@22.7.9)(typescript@5.6.3): + dependencies: + '@cspotcode/source-map-support': 0.8.1 + '@tsconfig/node10': 1.0.11 + '@tsconfig/node12': 1.0.11 + '@tsconfig/node14': 1.0.3 + '@tsconfig/node16': 1.0.4 + '@types/node': 22.7.9 + acorn: 8.13.0 + acorn-walk: 8.3.4 + arg: 4.1.3 + create-require: 1.1.1 + diff: 4.0.2 + make-error: 1.3.6 + typescript: 5.6.3 + v8-compile-cache-lib: 3.0.1 + yn: 3.1.1 + + tslib@2.8.0: {} + + type-detect@4.0.8: {} + + type-fest@0.21.3: {} + + typescript@5.6.3: {} + + undici-types@6.19.8: {} + + update-browserslist-db@1.1.1(browserslist@4.24.0): + dependencies: + browserslist: 4.24.0 + escalade: 3.2.0 + picocolors: 1.1.0 + + v8-compile-cache-lib@3.0.1: {} + + v8-to-istanbul@9.3.0: + dependencies: + '@jridgewell/trace-mapping': 0.3.25 + '@types/istanbul-lib-coverage': 2.0.6 + convert-source-map: 2.0.0 + + walker@1.0.8: + dependencies: + makeerror: 1.0.12 + + wasm-pack@0.13.0: + dependencies: + binary-install: 1.1.0 + transitivePeerDependencies: + - debug + + which@2.0.2: + dependencies: + isexe: 2.0.0 + + wrap-ansi@7.0.0: + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + + wrappy@1.0.2: {} + + write-file-atomic@4.0.2: + dependencies: + imurmurhash: 0.1.4 + signal-exit: 3.0.7 + + y18n@5.0.8: {} + + yallist@3.1.1: {} + + yallist@4.0.0: {} + + yargs-parser@21.1.1: {} + + yargs@17.7.2: + dependencies: + cliui: 8.0.1 + escalade: 3.2.0 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + string-width: 4.2.3 + y18n: 5.0.8 + yargs-parser: 21.1.1 + + yn@3.1.1: {} + + yocto-queue@0.1.0: {} diff --git a/tools/didc-js/pnpm-workspace.yaml b/tools/didc-js/pnpm-workspace.yaml new file mode 100644 index 00000000..f7257bfc --- /dev/null +++ b/tools/didc-js/pnpm-workspace.yaml @@ -0,0 +1,3 @@ +packages: + - "wasm-package" + - "wasm-tests" diff --git a/tools/didc-js/wasm-package/Cargo.toml b/tools/didc-js/wasm-package/Cargo.toml new file mode 100644 index 00000000..51670581 --- /dev/null +++ b/tools/didc-js/wasm-package/Cargo.toml @@ -0,0 +1,33 @@ +[package] +name = "didc-js" +description = "Utility tools for candid in JavaScript." +version = "0.0.0" +authors = ["DFINITY Team"] +edition = "2021" +publish = false +repository = "https://github.com/dfinity/candid" +license = "Apache-2.0" + +[lib] +path = "./src/lib.rs" +crate-type = ["cdylib"] + +[package.metadata.wasm-pack.profile.release] +wasm-opt = ["-Oz", "--enable-mutable-globals"] + +[dependencies] +candid = "0.10" +candid_parser = "0.1" +pretty-hex = "0.4.1" +hex.workspace = true +anyhow.workspace = true +rand.workspace = true +serde.workspace = true +thiserror.workspace = true +wasm-bindgen = "0.2" +console_error_panic_hook = "0.1" +wasm-bindgen-console-logger = "0.1" +log = "0.4" +getrandom = { version = "0.2", features = ["js"] } +serde-wasm-bindgen = "0.5" +js-sys = "0.3" diff --git a/tools/didc-js/wasm-package/LICENSE b/tools/didc-js/wasm-package/LICENSE new file mode 100644 index 00000000..ecc50baa --- /dev/null +++ b/tools/didc-js/wasm-package/LICENSE @@ -0,0 +1,208 @@ + 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 + +LLVM EXCEPTIONS TO THE APACHE 2.0 LICENSE + +As an exception, if, as a result of your compiling your source code, portions +of this Software are embedded into an Object form of such source code, you may +redistribute such embedded portions in such Object form without complying with +the conditions of Sections 4(a), 4(b) and 4(d) of the License. + +In addition, if you combine or link compiled forms of this Software with +software that is licensed under the GPLv2 ("Combined Software") and if a court +of competent jurisdiction determines that the patent provision (Section 3), the +indemnity provision (Section 9) or other Section of the License conflicts with +the conditions of the GPLv2, you may retroactively and prospectively choose to +deem waived or otherwise exclude such Section(s) of the License, but only in +their entirety and only with respect to the Combined Software. + +END OF LLVM EXCEPTIONS + +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 2024 DFINITY Stiftung + +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. + +END OF APPENDIX diff --git a/tools/didc-js/wasm-package/README.md b/tools/didc-js/wasm-package/README.md new file mode 100644 index 00000000..b7cd542c --- /dev/null +++ b/tools/didc-js/wasm-package/README.md @@ -0,0 +1,68 @@ +# @dfinity/didc + +A multi-purpose Candid tool for JavaScript projects, including encoding and decoding Candid values. + +## Usage + +```javascript +import { getServiceMethods, encode, decode } from "@dfinity/didc"; + +// The IDL in text format to be used, most canisters expose their IDL through +// the `candid:service` public metadata. +// +// You can fetch the IDL with an agent call or dfx with `dfx canister metadata candid:service` +export const IDL = ` + type StoreNumberInput = record { + number : nat64; + }; + + service : { + store_number : (input : StoreNumberInput) -> (); + get_number : () -> (nat64) query; + }; +`; + +// Gets the service methods from the IDL and returns an array of the methods. +// +// Example returned value: ['store_number', 'get_number'] +const methods = getServiceMethods(IDL); + +// Encodes a candid text representation of a value to a hex representation. +// +// Example returned value: '4449444c016c01c98dea8b0a7801005a00000000000000' +const encoded encode({ + idl: IDL, + input: "(record { number=90; })", + serviceMethod: "store_number", + targetFormat: "hex", +}); + +// Decodes a hex representation of a candid value to a text representation. +// +// Example returned value: '(90 : nat64)' +const decoded = decode({ + idl: IDL, + input: "4449444c0001785a00000000000000", + serviceMethod: "get_number", + inputFormat: "hex", + targetFormat: "candid", +}); +``` + +### Web Usage + +For web usage, you need to initialize the async wasm module before using the functions. + +```javascript +import init, { encode } from "@dfinity/didc"; + +await init(); + +// then you can use the functions because the wasm will be initialized +const encoded = encode({ + idl: IDL, + input: "(record { number=90; })", + serviceMethod: "store_number", + targetFormat: "hex", +}); +``` diff --git a/tools/didc-js/wasm-package/build.sh b/tools/didc-js/wasm-package/build.sh new file mode 100755 index 00000000..53f5a509 --- /dev/null +++ b/tools/didc-js/wasm-package/build.sh @@ -0,0 +1,124 @@ +############################################# +# USAGE # +############################################# + +function title() { + echo "Build script for the rust and js code" +} + +function usage() { + cat < The target to build for, default is "web" + --mode The build mode, default is "production" + --dir The build directory, default is "./dist" +EOF +} + +function help() { + cat < Result, LibraryError> { + let idl = parse_idl(&idl)?; + let mut methods = Vec::new(); + + if let Some(actor) = &idl.actor { + let service = idl + .env + .as_service(actor) + .map_err(|e| LibraryError::IdlParsingFailed { + reason: format!("Could not convert to service {}", e), + })?; + + for (method_name, _) in service.iter() { + methods.push(method_name.clone()); + } + } + + methods.sort(); + + Ok(methods) +} + +/// Encode the provided input in candid text format to the specified format. +pub fn encode(args: EncodeArgs) -> Result { + // Validate the provided arguments + args.validate()?; + + let idl = parse_idl(&args.idl)?; + let idl_args = parse_idl_args(&args.input)?; + + let args_bytes = match (args.service_method, &idl.actor) { + (Some(method), Some(actor)) => { + let method = idl.env.get_method(actor, &method).map_err(|_| { + LibraryError::IdlMethodNotFound { + method: method.clone(), + } + })?; + + idl_args + .to_bytes_with_types(&idl.env, &method.args) + .map_err(|e| LibraryError::IdlArgsToBytesFailed { + reason: format!("Could not encode args to bytes {}", e), + })? + } + (Some(method), None) => Err(LibraryError::IdlMethodNotFound { method })?, + (None, _) => idl_args + .to_bytes() + .map_err(|e| LibraryError::IdlArgsToBytesFailed { + reason: format!("Could not encode args to bytes {}", e), + })?, + }; + + let encoded_args = match args.target_format { + EncodeFormat::Hex => hex::encode(&args_bytes), + EncodeFormat::Blob => { + let mut res = String::new(); + for ch in args_bytes.iter() { + res.push_str(&candid_parser::pretty::candid::value::pp_char(*ch)); + } + + res + } + }; + + Ok(encoded_args) +} + +/// Decode the provided hex or blob value to the specified format. +pub fn decode(args: DecodeArgs) -> Result { + // Validate the provided arguments + args.validate()?; + + let idl = parse_idl(&args.idl)?; + let args_bytes = match args.input_format { + EncodeFormat::Hex => decode_hex(&args.input)?, + EncodeFormat::Blob => decode_candid_blob(&args.input)?, + }; + + let idl_args = match (args.service_method, &idl.actor) { + (Some(method), Some(actor)) => { + let method = idl.env.get_method(actor, &method).map_err(|_| { + LibraryError::IdlMethodNotFound { + method: method.clone(), + } + })?; + + let method_types = match args.use_service_method_return_type { + None | Some(true) => &method.rets, + Some(false) => &method.args, + }; + + IDLArgs::from_bytes_with_types(&args_bytes, &idl.env, method_types).map_err(|e| { + LibraryError::IdlArgsFromBytesFailed { + reason: format!("Could not decode args from bytes {}", e), + } + })? + } + (Some(method), None) => Err(LibraryError::IdlMethodNotFound { method })?, + (None, _) => { + IDLArgs::from_bytes(&args_bytes).map_err(|e| LibraryError::IdlArgsFromBytesFailed { + reason: format!("Could not decode args from bytes {}", e), + })? + } + }; + + let decoded_idl_args = match args.target_format { + DecodeFormat::Candid => idl_args.to_string(), + }; + + Ok(decoded_idl_args) +} diff --git a/tools/didc-js/wasm-package/src/errors.rs b/tools/didc-js/wasm-package/src/errors.rs new file mode 100644 index 00000000..20dd6c7d --- /dev/null +++ b/tools/didc-js/wasm-package/src/errors.rs @@ -0,0 +1,33 @@ +use thiserror::Error; + +/// Container for all errors that can occur in this crate. +#[derive(Error, Debug, Eq, PartialEq, Clone)] +pub enum LibraryError { + /// Failed to parse the provided candid idl. + #[error(r#"Failed to parse the provided candid idl `{reason}`."#)] + IdlParsingFailed { reason: String }, + /// Service method not found. + #[error(r#"Service method not found `{method}`."#)] + IdlMethodNotFound { method: String }, + /// Failed to parse arguments. + #[error(r#"Failed to parse arguments `{reason}`."#)] + IdlArgsParsingFailed { reason: String }, + /// Failed to convert idl args to bytes. + #[error(r#"Failed to convert idl args to bytes due to `{reason}`."#)] + IdlArgsToBytesFailed { reason: String }, + /// Failed to convert bytes to idl args. + #[error(r#"Failed to convert bytes to idl args due to `{reason}`."#)] + IdlArgsFromBytesFailed { reason: String }, + /// Validation failed due to specific reason. + #[error(r#"Validation failed due to `{reason}`."#)] + ValidationError { reason: String }, + /// Hex decoding failed. + #[error(r#"Hex decoding failed due to `{reason}`."#)] + HexDecodingFailed { reason: String }, + /// Candid blob decoding failed. + #[error(r#"Candid blob decoding failed due to `{reason}`."#)] + CandidBlobDecodingFailed { reason: String }, + /// Mapping error. + #[error(r#"Mapping error `{reason}`."#)] + MappingError { reason: String }, +} diff --git a/tools/didc-js/wasm-package/src/lib.rs b/tools/didc-js/wasm-package/src/lib.rs new file mode 100644 index 00000000..fb1a41cc --- /dev/null +++ b/tools/didc-js/wasm-package/src/lib.rs @@ -0,0 +1,34 @@ +#![deny(clippy::all)] +use types::{JsDecodeArgs, JsEncodeArgs}; +use wasm_bindgen::prelude::*; + +mod core; +mod errors; +mod types; +mod utils; +mod validation; + +#[wasm_bindgen(start)] +fn start() { + console_error_panic_hook::set_once(); + match log::set_logger(&wasm_bindgen_console_logger::DEFAULT_LOGGER) { + Ok(_) => log::info!("Console logger initialized"), + Err(e) => log::error!("Failed to set console logger: {}", e), + } + log::set_max_level(log::LevelFilter::Trace); +} + +#[wasm_bindgen(js_name = getServiceMethods)] +pub fn get_service_methods(idl: String) -> Result, JsError> { + core::get_service_methods(idl).map_err(Into::into) +} + +#[wasm_bindgen] +pub fn encode(args: JsEncodeArgs) -> Result { + core::encode(args.try_into()?).map_err(Into::into) +} + +#[wasm_bindgen] +pub fn decode(args: JsDecodeArgs) -> Result { + core::decode(args.try_into()?).map_err(Into::into) +} diff --git a/tools/didc-js/wasm-package/src/types.rs b/tools/didc-js/wasm-package/src/types.rs new file mode 100644 index 00000000..acc50573 --- /dev/null +++ b/tools/didc-js/wasm-package/src/types.rs @@ -0,0 +1,293 @@ +use std::str::FromStr; + +use serde::{Deserialize, Serialize}; +use wasm_bindgen::JsCast; +use wasm_bindgen::{prelude::wasm_bindgen, JsValue}; + +use crate::errors::LibraryError; + +#[wasm_bindgen(typescript_custom_section)] +const TS_TYPES: &'static str = r#" +export interface EncodeArgs { + /** + * The Candid IDL to convert into the candid ast and encode the value against. + */ + idl: string; + /** + * A method to pick from the service. If not provided, the entire idl is used. + */ + serviceMethod?: string; + /** + * The format to encode the value in. Default is 'hex'. + */ + targetFormat?: 'hex' | 'blob'; + /** + * The candid text value to encode to the specified format. + */ + input: string; +} + +export interface DecodeArgs { + /** + * The Candid IDL to convert into the candid ast and decode the value against. + */ + idl: string; + /** + * The format to decode the value in. Default is 'candid'. + */ + targetFormat?: 'candid'; + /** + * A method to pick from the service. If not provided, the entire idl is used. + */ + serviceMethod?: string; + /** + * Wether to use the service method return type to decode the value. Default is true if serviceMethod is provided. + */ + useServiceMethodReturnType?: boolean; + /** + * The format of the input value. Default is 'hex'. + */ + inputFormat?: 'hex' | 'blob'; + /** + * The hex or blob value to decode to the specified format. + */ + input: string; +} +"#; + +#[wasm_bindgen] +extern "C" { + #[wasm_bindgen(typescript_type = "EncodeArgs")] + pub type JsEncodeArgs; + + #[wasm_bindgen(typescript_type = "DecodeArgs")] + pub type JsDecodeArgs; +} + +#[derive(Debug, Serialize, Deserialize)] +pub struct EncodeArgs { + pub idl: String, + pub target_format: EncodeFormat, + pub input: String, + pub service_method: Option, +} + +#[derive(Debug, Serialize, Deserialize, Eq, PartialEq)] +pub enum EncodeFormat { + Hex, + Blob, +} + +impl FromStr for EncodeFormat { + type Err = LibraryError; + + fn from_str(variant: &str) -> Result { + match variant { + "hex" => Ok(EncodeFormat::Hex), + "blob" => Ok(EncodeFormat::Blob), + _ => Err(LibraryError::ValidationError { + reason: format!("Invalid target format: {}", variant), + }), + } + } +} + +#[derive(Debug, Serialize, Deserialize)] +pub struct DecodeArgs { + pub idl: String, + pub target_format: DecodeFormat, + pub input_format: EncodeFormat, + pub input: String, + pub service_method: Option, + pub use_service_method_return_type: Option, +} + +#[derive(Debug, Serialize, Deserialize, Eq, PartialEq)] +pub enum DecodeFormat { + Candid, +} + +impl FromStr for DecodeFormat { + type Err = LibraryError; + + fn from_str(variant: &str) -> Result { + match variant { + "candid" => Ok(DecodeFormat::Candid), + _ => Err(LibraryError::ValidationError { + reason: format!("Invalid target format: {}", variant), + }), + } + } +} + +impl TryFrom for EncodeArgs { + type Error = LibraryError; + + fn try_from(args: JsEncodeArgs) -> Result { + let js_value = JsValue::from(args); + + let obj = + js_value + .dyn_into::() + .map_err(|_| LibraryError::MappingError { + reason: "Could not convert encode arguments".to_string(), + })?; + + let idl = js_sys::Reflect::get(&obj, &JsValue::from_str("idl")) + .map_err(|_| LibraryError::MappingError { + reason: "Could not get 'idl' from JsValue".to_string(), + })? + .as_string() + .ok_or(LibraryError::MappingError { + reason: "Field 'idl' should be a string".to_string(), + })?; + + let input = js_sys::Reflect::get(&obj, &JsValue::from_str("input")) + .map_err(|_| LibraryError::MappingError { + reason: "Could not get 'input' from JsValue".to_string(), + })? + .as_string() + .ok_or(LibraryError::MappingError { + reason: "Field 'input' should be a string".to_string(), + })?; + + let service_method = js_sys::Reflect::get(&obj, &JsValue::from_str("serviceMethod")) + .map_err(|_| LibraryError::MappingError { + reason: "Could not get 'serviceMethod' from JsValue".to_string(), + })? + .as_string(); + + let target_form = js_sys::Reflect::get(&obj, &JsValue::from_str("targetFormat")) + .map_err(|_| LibraryError::MappingError { + reason: "Could not get 'targetFormat' from JsValue".to_string(), + })? + .as_string(); + + let target_format = match target_form { + Some(target_form) => target_form.parse::()?, + None => EncodeFormat::Hex, + }; + + Ok(EncodeArgs { + idl, + target_format, + input, + service_method, + }) + } +} + +impl TryFrom for DecodeArgs { + type Error = LibraryError; + + fn try_from(args: JsDecodeArgs) -> Result { + let js_value = JsValue::from(args); + + let obj = + js_value + .dyn_into::() + .map_err(|_| LibraryError::MappingError { + reason: "Could not convert decode arguments".to_string(), + })?; + + let idl = js_sys::Reflect::get(&obj, &JsValue::from_str("idl")) + .map_err(|_| LibraryError::MappingError { + reason: "Could not get 'idl' from JsValue".to_string(), + })? + .as_string() + .ok_or(LibraryError::MappingError { + reason: "Field 'idl' should be a string".to_string(), + })?; + + let input = js_sys::Reflect::get(&obj, &JsValue::from_str("input")) + .map_err(|_| LibraryError::MappingError { + reason: "Could not get 'input' from JsValue".to_string(), + })? + .as_string() + .ok_or(LibraryError::MappingError { + reason: "Field 'input' should be a string".to_string(), + })?; + + let service_method = js_sys::Reflect::get(&obj, &JsValue::from_str("serviceMethod")) + .map_err(|_| LibraryError::MappingError { + reason: "Could not get 'serviceMethod' from JsValue".to_string(), + })? + .as_string(); + + let use_service_method_return_type = + js_sys::Reflect::get(&obj, &JsValue::from_str("useServiceMethodReturnType")) + .map_err(|_| LibraryError::MappingError { + reason: "Could not get 'useServiceMethodReturnType' from JsValue".to_string(), + })? + .as_bool(); + + let target_form = js_sys::Reflect::get(&obj, &JsValue::from_str("targetFormat")) + .map_err(|_| LibraryError::MappingError { + reason: "Could not get 'targetFormat' from JsValue".to_string(), + })? + .as_string(); + + let target_format = match target_form { + Some(target_form) => target_form.parse::()?, + None => DecodeFormat::Candid, + }; + + let input_form = js_sys::Reflect::get(&obj, &JsValue::from_str("inputFormat")) + .map_err(|_| LibraryError::MappingError { + reason: "Could not get 'inputFormat' from JsValue".to_string(), + })? + .as_string(); + + let input_format = match input_form { + Some(input_form) => input_form.parse::()?, + None => EncodeFormat::Hex, + }; + + Ok(DecodeArgs { + idl, + target_format, + input_format, + input, + service_method, + use_service_method_return_type, + }) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn can_map_encode_format_enum() { + let hex = "hex".parse::(); + let blob = "blob".parse::(); + + assert!(hex.is_ok()); + assert!(blob.is_ok()); + assert_eq!(hex.unwrap(), EncodeFormat::Hex); + assert_eq!(blob.unwrap(), EncodeFormat::Blob); + } + + #[test] + fn can_map_decode_format_enum() { + let candid = "candid".parse::(); + + assert!(candid.is_ok()); + assert_eq!(candid.unwrap(), DecodeFormat::Candid); + } + + #[test] + fn fails_map_unknown_encode_format_enum() { + let unknown = "unknown".parse::(); + + assert!(unknown.is_err()); + } + + #[test] + fn fails_map_unknown_decode_format_enum() { + let unknown = "unknown".parse::(); + + assert!(unknown.is_err()); + } +} diff --git a/tools/didc-js/wasm-package/src/utils.rs b/tools/didc-js/wasm-package/src/utils.rs new file mode 100644 index 00000000..3da835cd --- /dev/null +++ b/tools/didc-js/wasm-package/src/utils.rs @@ -0,0 +1,111 @@ +use crate::errors::LibraryError; +use candid::{types::Type, IDLArgs, TypeEnv}; +use candid_parser::{check_prog, parse_idl_value, IDLProg}; + +/// Parse the provided candid idl and return the parsed AST. +pub fn parse_idl_prog(idl: &str) -> Result { + match idl.parse::() { + Ok(ast) => Ok(ast), + Err(e) => Err(LibraryError::IdlParsingFailed { + reason: e.to_string(), + }), + } +} + +/// Parse the provided candid arguments and return the parsed AST. +pub fn parse_idl_args(args: &str) -> Result { + match candid_parser::parse_idl_args(args) { + Ok(ast) => Ok(ast), + Err(e) => Err(LibraryError::IdlArgsParsingFailed { + reason: e.to_string(), + }), + } +} + +#[derive(Debug)] +pub struct ParsedIDL { + pub env: TypeEnv, + pub actor: Option, +} + +impl ParsedIDL { + pub fn new(env: TypeEnv, actor: Option) -> Self { + Self { env, actor } + } +} + +/// Parse the provided candid idl and return the parsed AST along with the actor type. +pub fn parse_idl(idl: &str) -> Result { + let mut env = TypeEnv::new(); + let ast = parse_idl_prog(idl)?; + + let actor = check_prog(&mut env, &ast).map_err(|e| LibraryError::ValidationError { + reason: e.to_string(), + })?; + + Ok(ParsedIDL::new(env, actor)) +} + +/// Decode the provided hex input from text to bytes. +pub fn decode_hex(hex_input: &str) -> Result, LibraryError> { + hex::decode( + hex_input + .chars() + .filter(|c| !c.is_whitespace()) + .collect::(), + ) + .map_err(|e| LibraryError::HexDecodingFailed { + reason: e.to_string(), + }) +} + +/// Decode the provided candid blob text to bytes. +pub fn decode_candid_blob(blob_input: &str) -> Result, LibraryError> { + let blob_input = match blob_input.starts_with("DIDL") { + true => format!("blob \"{}\"", blob_input), + false => blob_input.to_string(), + }; + + match parse_idl_value(&blob_input) { + Ok(candid_parser::IDLValue::Blob(blob)) => Ok(blob), + Ok(_) => Err(LibraryError::CandidBlobDecodingFailed { + reason: "Expected a blob value".to_string(), + }), + Err(e) => Err(LibraryError::CandidBlobDecodingFailed { + reason: format!("Could not decode candid blob: {}", e), + }), + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn can_decode_hex_text_value() { + // Value generated from: didc encode --format hex '(90 : nat64)' + let hex_input = "4449444c0001785a00000000000000"; + + let result = decode_hex(hex_input); + + assert!(result.is_ok()); + assert_eq!( + result.unwrap(), + vec![68, 73, 68, 76, 0, 1, 120, 90, 0, 0, 0, 0, 0, 0, 0] + ); + } + + #[test] + fn can_decode_candid_blob_text_value() { + // Value generated from: didc encode --format blob '(90 : nat64)' + let blob_input = "DIDL\\00\\01xZ\\00\\00\\00\\00\\00\\00\\00"; + + let result = decode_candid_blob(blob_input); + + assert!(result.is_ok()); + assert_eq!( + result.unwrap(), + vec![68, 73, 68, 76, 0, 1, 120, 90, 0, 0, 0, 0, 0, 0, 0] + ); + } +} diff --git a/tools/didc-js/wasm-package/src/validation.rs b/tools/didc-js/wasm-package/src/validation.rs new file mode 100644 index 00000000..0847e717 --- /dev/null +++ b/tools/didc-js/wasm-package/src/validation.rs @@ -0,0 +1,82 @@ +use crate::{ + errors::LibraryError, + types::{DecodeArgs, EncodeArgs}, +}; + +/// A trait for validating structs or enums. +/// +/// Can be implemented for any struct or enum that needs to be validated. +pub trait Validate { + fn validate(&self) -> Result<(), Err>; +} + +/// Ensures that the specified field is not empty. +pub fn validate_required_text_field( + field_name: &str, + field_value: &str, +) -> Result<(), LibraryError> { + if field_value.is_empty() || field_value.trim().is_empty() { + return Err(LibraryError::ValidationError { + reason: format!("{} is required", field_name), + }); + } + + Ok(()) +} + +impl Validate for EncodeArgs { + fn validate(&self) -> Result<(), LibraryError> { + validate_required_text_field("idl", &self.idl)?; + validate_required_text_field("input", &self.input)?; + + Ok(()) + } +} + +impl Validate for DecodeArgs { + fn validate(&self) -> Result<(), LibraryError> { + validate_required_text_field("idl", &self.idl)?; + validate_required_text_field("input", &self.input)?; + + Ok(()) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::types::{DecodeFormat, EncodeFormat}; + + #[test] + fn test_validate_required_text_field() { + assert!(validate_required_text_field("test", "test").is_ok()); + assert!(validate_required_text_field("test", "").is_err()); + assert!(validate_required_text_field("test", " ").is_err()); + } + + #[test] + fn test_validate_encode_args() { + let args = EncodeArgs { + idl: "test".to_string(), + target_format: EncodeFormat::Hex, + input: "test".to_string(), + service_method: None, + }; + + assert!(args.validate().is_ok()); + } + + #[test] + fn test_validate_decode_args() { + let args = DecodeArgs { + idl: "test".to_string(), + target_format: DecodeFormat::Candid, + input_format: EncodeFormat::Hex, + input: "test".to_string(), + service_method: None, + use_service_method_return_type: None, + }; + + assert!(args.validate().is_ok()); + } +} diff --git a/tools/didc-js/wasm-tests/jest.config.ts b/tools/didc-js/wasm-tests/jest.config.ts new file mode 100644 index 00000000..51eef2e0 --- /dev/null +++ b/tools/didc-js/wasm-tests/jest.config.ts @@ -0,0 +1,8 @@ +import { createJsWithBabelEsmPreset, JestConfigWithTsJest } from "ts-jest"; + +const jestConfig: JestConfigWithTsJest = { + ...createJsWithBabelEsmPreset(), + testEnvironment: "node", +}; + +export default jestConfig; diff --git a/tools/didc-js/wasm-tests/package.json b/tools/didc-js/wasm-tests/package.json new file mode 100644 index 00000000..ba34dbab --- /dev/null +++ b/tools/didc-js/wasm-tests/package.json @@ -0,0 +1,19 @@ +{ + "name": "wasm-tests", + "description": "Tests the wasm package in the target environments.", + "version": "0.0.0", + "private": true, + "scripts": { + "test": "jest" + }, + "devDependencies": { + "@dfinity/didc": "workspace:*", + "@types/jest": "29.5.14", + "@types/node": "22.7.9", + "jest": "29.7.0", + "ts-jest": "29.2.5", + "ts-node": "10.9.2", + "tslib": "2.8.0", + "typescript": "5.6.3" + } +} diff --git a/tools/didc-js/wasm-tests/src/decode.test.ts b/tools/didc-js/wasm-tests/src/decode.test.ts new file mode 100644 index 00000000..2072315b --- /dev/null +++ b/tools/didc-js/wasm-tests/src/decode.test.ts @@ -0,0 +1,40 @@ +import { decode } from "@dfinity/didc"; +import { IDL } from "./test.utils"; + +describe("decode", () => { + it("decoding returns the method return type decoded value from hex", () => { + expect( + decode({ + idl: IDL, + input: "4449444c0001785a00000000000000", + serviceMethod: "get_number", + inputFormat: "hex", + targetFormat: "candid", + }) + ).toBe("(90 : nat64)"); + }); + + it("decoding returns the method arg type decoded value from hex", () => { + expect( + decode({ + idl: IDL, + input: "4449444c016c01c98dea8b0a7801006400000000000000", + serviceMethod: "store_number", + inputFormat: "hex", + targetFormat: "candid", + useServiceMethodReturnType: false, + }) + ).toBe("(record { number = 100 : nat64 })"); + }); + + it("decoding without the service method can still return the decoded value", () => { + expect( + decode({ + idl: IDL, + input: "4449444c016c01c98dea8b0a7801006400000000000000", + inputFormat: "hex", + targetFormat: "candid", + }) + ).toBe("(record { 2_709_161_673 = 100 : nat64 })"); + }); +}); diff --git a/tools/didc-js/wasm-tests/src/encode.test.ts b/tools/didc-js/wasm-tests/src/encode.test.ts new file mode 100644 index 00000000..18e40174 --- /dev/null +++ b/tools/didc-js/wasm-tests/src/encode.test.ts @@ -0,0 +1,65 @@ +import { encode } from "@dfinity/didc"; +import { IDL } from "./test.utils"; + +describe("encode", () => { + it("encoding returns the correct hex encoded value from candid into hex", () => { + expect( + encode({ + idl: IDL, + input: "(record { number=90; })", + serviceMethod: "store_number", + targetFormat: "hex", + }) + ).toBe("4449444c016c01c98dea8b0a7801005a00000000000000"); + }); + + it("encoding returns the correct hex encoded value from candid into blob", () => { + expect( + encode({ + idl: IDL, + input: "(record { number=90; })", + serviceMethod: "store_number", + targetFormat: "blob", + }) + ).toBe( + "DIDL\\01l\\01\\c9\\8d\\ea\\8b\\0ax\\01\\00Z\\00\\00\\00\\00\\00\\00\\00" + ); + }); + + it("encoding with an invalid service method throws", () => { + const performEncoding = () => + encode({ + idl: IDL, + input: "(record { number=90; })", + serviceMethod: "unknown_method", + }); + + expect(performEncoding).toThrow(Error); + expect(performEncoding).toThrow( + "Service method not found `unknown_method`." + ); + }); + + it("encoding with an invalid input throws", () => { + const performEncoding = () => + encode({ + idl: IDL, + input: "record { number=90; }", + serviceMethod: "store_number", + }); + + expect(performEncoding).toThrow(Error); + expect(performEncoding).toThrow("Failed to parse arguments"); + }); + + it("encoding with an invalid IDL throws", () => { + const performEncoding = () => + encode({ + idl: "type StoreNumberInput = number : nat64;", + input: "(record { number=90; })", + }); + + expect(performEncoding).toThrow(Error); + expect(performEncoding).toThrow("Failed to parse the provided candid idl"); + }); +}); diff --git a/tools/didc-js/wasm-tests/src/get_service_methods.test.ts b/tools/didc-js/wasm-tests/src/get_service_methods.test.ts new file mode 100644 index 00000000..c7b97aa8 --- /dev/null +++ b/tools/didc-js/wasm-tests/src/get_service_methods.test.ts @@ -0,0 +1,14 @@ +import { getServiceMethods } from "@dfinity/didc"; +import { IDL, IDL_SERVICE_METHODS } from "./test.utils"; + +describe("getServiceMethods", () => { + it("returns the available service methods from an IDL", () => { + expect(getServiceMethods(IDL)).toEqual( + expect.arrayContaining(IDL_SERVICE_METHODS) + ); + }); + + it("returns an empty array for a non service IDL", () => { + expect(getServiceMethods("type TestInput = nat64;")).toEqual([]); + }); +}); diff --git a/tools/didc-js/wasm-tests/src/test.utils.ts b/tools/didc-js/wasm-tests/src/test.utils.ts new file mode 100644 index 00000000..10f27eba --- /dev/null +++ b/tools/didc-js/wasm-tests/src/test.utils.ts @@ -0,0 +1,27 @@ +export const IDL = ` + type StoreNumberInput = record { + number : nat64; + }; + + type CustomType = record { + custom_field : nat64; + options: CustomVariant; + }; + + type CustomVariant = variant { + A : nat64; + B : text; + }; + + service : { + store_number : (input : StoreNumberInput) -> (); + get_number : () -> (nat64) query; + set_complex_type : (input : CustomType) -> (); + }; +`; + +export const IDL_SERVICE_METHODS = [ + "store_number", + "get_number", + "set_complex_type", +]; diff --git a/tools/didc-js/wasm-tests/src/wasm.test.ts b/tools/didc-js/wasm-tests/src/wasm.test.ts new file mode 100644 index 00000000..f0208ac1 --- /dev/null +++ b/tools/didc-js/wasm-tests/src/wasm.test.ts @@ -0,0 +1,16 @@ +import wasmModule, { encode, decode } from "@dfinity/didc"; + +describe("WebAssembly nodejs", () => { + it("the wasm module can be imported", () => { + expect(wasmModule).not.toBeUndefined(); + }); + + it("the wasm module is not a promise", () => { + expect(wasmModule).not.toBeInstanceOf(Promise); + }); + + it("the encode and decode functions are defined", () => { + expect(encode).not.toBeUndefined(); + expect(decode).not.toBeUndefined(); + }); +}); diff --git a/tools/didc-js/wasm-tests/tsconfig.json b/tools/didc-js/wasm-tests/tsconfig.json new file mode 100644 index 00000000..70084d2f --- /dev/null +++ b/tools/didc-js/wasm-tests/tsconfig.json @@ -0,0 +1,12 @@ +{ + "compilerOptions": { + "module": "NodeNext", + "allowSyntheticDefaultImports": true, + "moduleResolution": "NodeNext", + "target": "es2022", + "strict": true, + "esModuleInterop": true, + }, + "include": ["src/**/*"], + "exclude": ["node_modules"] +}