From ec055dface353595e7f540cd2b57f92f3c3dd4f9 Mon Sep 17 00:00:00 2001 From: Don <100505855+DonFungible@users.noreply.github.com> Date: Wed, 3 Jan 2024 20:04:52 -0500 Subject: [PATCH] init --- .changeset/config.json | 9 + .dockerignore | 4 + .gitignore | 40 + .gitmodules | 5 + .husky/pre-commit | 5 + .nvmrc | 1 + CODE_OF_CONDUCT.md | 76 + CONTRIBUTING.md | 66 + Dockerfile | 13 + LICENSE.md | 21 + Makefile | 22 + README.md | 152 + package.json | 24 + packages/core-sdk/.env.example | 11 + packages/core-sdk/.eslintrc.cjs | 9 + packages/core-sdk/.prettierignore | 1 + packages/core-sdk/README.md | 85 + packages/core-sdk/package.json | 91 + .../core-sdk/src/abi/ipOrgController.abi.ts | 19 + packages/core-sdk/src/abi/json/Errors.abi.ts | 881 +++ packages/core-sdk/src/abi/json/Errors.json | 881 +++ .../src/abi/json/IPOrgController.abi.ts | 73 + .../src/abi/json/LicenseRegistry.abi.ts | 73 + .../src/abi/json/RegistrationModule.abi.ts | 57 + .../src/abi/json/RelationshipModule.abi.ts | 100 + .../src/abi/json/StoryProtocol.abi.ts | 330 + .../core-sdk/src/abi/licenseRegistry.abi.ts | 12 + .../core-sdk/src/abi/licensingModule.abi.ts | 367 ++ .../src/abi/registrationModule.abi.ts | 18 + .../src/abi/relationshipModule.abi.ts | 14 + packages/core-sdk/src/abi/sdkEntities.json | 19 + .../core-sdk/src/abi/storyProtocol.abi.ts | 22 + packages/core-sdk/src/client.ts | 244 + packages/core-sdk/src/constants/common.ts | 3 + packages/core-sdk/src/constants/http.ts | 4 + packages/core-sdk/src/constants/license.ts | 12 + packages/core-sdk/src/enums/ActionType.ts | 10 + packages/core-sdk/src/enums/HookType.ts | 7 + packages/core-sdk/src/enums/Relatables.ts | 11 + packages/core-sdk/src/enums/ResourceType.ts | 14 + packages/core-sdk/src/index.ts | 102 + packages/core-sdk/src/resources/hook.ts | 16 + .../core-sdk/src/resources/hookReadOnly.ts | 57 + packages/core-sdk/src/resources/ipAsset.ts | 64 + .../core-sdk/src/resources/ipAssetReadOnly.ts | 57 + packages/core-sdk/src/resources/ipOrg.ts | 56 + .../core-sdk/src/resources/ipOrgReadOnly.ts | 55 + packages/core-sdk/src/resources/license.ts | 128 + .../core-sdk/src/resources/licenseReadOnly.ts | 102 + packages/core-sdk/src/resources/module.ts | 16 + .../core-sdk/src/resources/moduleReadOnly.ts | 56 + .../core-sdk/src/resources/relationship.ts | 68 + .../src/resources/relationshipReadOnly.ts | 72 + .../src/resources/relationshipType.ts | 67 + .../src/resources/relationshipTypeReadOnly.ts | 74 + .../core-sdk/src/resources/transaction.ts | 16 + .../src/resources/transactionReadOnly.ts | 52 + packages/core-sdk/src/types/client.ts | 40 + packages/core-sdk/src/types/common.ts | 6 + packages/core-sdk/src/types/config.ts | 20 + packages/core-sdk/src/types/options.ts | 12 + packages/core-sdk/src/types/resources/hook.ts | 54 + .../core-sdk/src/types/resources/ipAsset.ts | 89 + .../core-sdk/src/types/resources/ipOrg.ts | 77 + .../core-sdk/src/types/resources/license.ts | 198 + .../core-sdk/src/types/resources/module.ts | 53 + .../src/types/resources/relationship.ts | 79 + .../src/types/resources/relationshipType.ts | 95 + .../src/types/resources/transaction.ts | 56 + packages/core-sdk/src/utils/errors.ts | 6 + packages/core-sdk/src/utils/platform.ts | 44 + packages/core-sdk/src/utils/utils.ts | 179 + .../core-sdk/test/integration/config.test.ts | 7 + .../test/integration/hookReadOnly.test.ts | 100 + .../core-sdk/test/integration/ipAsset.test.ts | 137 + .../test/integration/ipAssetReadOnly.test.ts | 67 + .../core-sdk/test/integration/ipOrg.test.ts | 63 + .../test/integration/ipOrgReadOnly.test.ts | 103 + .../core-sdk/test/integration/license.test.ts | 443 ++ .../test/integration/licenseReadOnly.test.ts | 130 + .../test/integration/moduleReadOnly.test.ts | 96 + .../test/integration/platform.test.ts | 32 + .../test/integration/relationship.test.ts | 46 + .../integration/relationshipReadOnly.test.ts | 92 + .../test/integration/relationshipType.test.ts | 51 + .../relationshipTypeReadOnly.test.ts | 94 + .../integration/transactionReadOnly.test.ts | 86 + packages/core-sdk/test/unit/client.test.ts | 130 + .../core-sdk/test/unit/clientReadOnly.test.ts | 114 + .../test/unit/resources/hookReadOnly.test.ts | 191 + .../test/unit/resources/ipAsset.test.ts | 155 + .../unit/resources/ipAssetReadOnly.test.ts | 111 + .../test/unit/resources/ipOrg.test.ts | 146 + .../test/unit/resources/ipOrgReadOnly.test.ts | 100 + .../test/unit/resources/license.test.ts | 395 ++ .../unit/resources/licenseReadOnly.test.ts | 224 + .../unit/resources/moduleReadOnly.test.ts | 143 + .../test/unit/resources/relationship.test.ts | 166 + .../resources/relationshipReadOnly.test.ts | 125 + .../unit/resources/relationshipType.test.ts | 164 + .../relationshipTypeReadOnly.test.ts | 181 + .../resources/transactionReadOnly.test.ts | 98 + packages/core-sdk/test/unit/testUtils.ts | 75 + .../core-sdk/test/unit/utils/errors.test.ts | 20 + packages/core-sdk/test/unit/utils/mockData.ts | 70 + .../core-sdk/test/unit/utils/platform.test.ts | 121 + .../core-sdk/test/unit/utils/utils.test.ts | 172 + packages/core-sdk/tsconfig.json | 11 + packages/core-sdk/tsconfig.test.json | 9 + packages/core-sdk/tsdoc.json | 4 + packages/eslint-config-story/README.md | 3 + packages/eslint-config-story/index.js | 39 + packages/eslint-config-story/package.json | 22 + packages/prettier-config/index.json | 6 + packages/prettier-config/package.json | 12 + packages/tsconfig/base.json | 21 + packages/tsconfig/package.json | 6 + pnpm-lock.yaml | 5546 +++++++++++++++++ pnpm-workspace.yaml | 2 + turbo.json | 36 + 120 files changed, 16037 insertions(+) create mode 100644 .changeset/config.json create mode 100644 .dockerignore create mode 100644 .gitignore create mode 100644 .gitmodules create mode 100755 .husky/pre-commit create mode 100644 .nvmrc create mode 100644 CODE_OF_CONDUCT.md create mode 100644 CONTRIBUTING.md create mode 100644 Dockerfile create mode 100644 LICENSE.md create mode 100644 Makefile create mode 100644 README.md create mode 100644 package.json create mode 100644 packages/core-sdk/.env.example create mode 100644 packages/core-sdk/.eslintrc.cjs create mode 100644 packages/core-sdk/.prettierignore create mode 100644 packages/core-sdk/README.md create mode 100644 packages/core-sdk/package.json create mode 100644 packages/core-sdk/src/abi/ipOrgController.abi.ts create mode 100644 packages/core-sdk/src/abi/json/Errors.abi.ts create mode 100644 packages/core-sdk/src/abi/json/Errors.json create mode 100644 packages/core-sdk/src/abi/json/IPOrgController.abi.ts create mode 100644 packages/core-sdk/src/abi/json/LicenseRegistry.abi.ts create mode 100644 packages/core-sdk/src/abi/json/RegistrationModule.abi.ts create mode 100644 packages/core-sdk/src/abi/json/RelationshipModule.abi.ts create mode 100644 packages/core-sdk/src/abi/json/StoryProtocol.abi.ts create mode 100644 packages/core-sdk/src/abi/licenseRegistry.abi.ts create mode 100644 packages/core-sdk/src/abi/licensingModule.abi.ts create mode 100644 packages/core-sdk/src/abi/registrationModule.abi.ts create mode 100644 packages/core-sdk/src/abi/relationshipModule.abi.ts create mode 100644 packages/core-sdk/src/abi/sdkEntities.json create mode 100644 packages/core-sdk/src/abi/storyProtocol.abi.ts create mode 100644 packages/core-sdk/src/client.ts create mode 100644 packages/core-sdk/src/constants/common.ts create mode 100644 packages/core-sdk/src/constants/http.ts create mode 100644 packages/core-sdk/src/constants/license.ts create mode 100644 packages/core-sdk/src/enums/ActionType.ts create mode 100644 packages/core-sdk/src/enums/HookType.ts create mode 100644 packages/core-sdk/src/enums/Relatables.ts create mode 100644 packages/core-sdk/src/enums/ResourceType.ts create mode 100644 packages/core-sdk/src/index.ts create mode 100644 packages/core-sdk/src/resources/hook.ts create mode 100644 packages/core-sdk/src/resources/hookReadOnly.ts create mode 100644 packages/core-sdk/src/resources/ipAsset.ts create mode 100644 packages/core-sdk/src/resources/ipAssetReadOnly.ts create mode 100644 packages/core-sdk/src/resources/ipOrg.ts create mode 100644 packages/core-sdk/src/resources/ipOrgReadOnly.ts create mode 100644 packages/core-sdk/src/resources/license.ts create mode 100644 packages/core-sdk/src/resources/licenseReadOnly.ts create mode 100644 packages/core-sdk/src/resources/module.ts create mode 100644 packages/core-sdk/src/resources/moduleReadOnly.ts create mode 100644 packages/core-sdk/src/resources/relationship.ts create mode 100644 packages/core-sdk/src/resources/relationshipReadOnly.ts create mode 100644 packages/core-sdk/src/resources/relationshipType.ts create mode 100644 packages/core-sdk/src/resources/relationshipTypeReadOnly.ts create mode 100644 packages/core-sdk/src/resources/transaction.ts create mode 100644 packages/core-sdk/src/resources/transactionReadOnly.ts create mode 100644 packages/core-sdk/src/types/client.ts create mode 100644 packages/core-sdk/src/types/common.ts create mode 100644 packages/core-sdk/src/types/config.ts create mode 100644 packages/core-sdk/src/types/options.ts create mode 100644 packages/core-sdk/src/types/resources/hook.ts create mode 100644 packages/core-sdk/src/types/resources/ipAsset.ts create mode 100644 packages/core-sdk/src/types/resources/ipOrg.ts create mode 100644 packages/core-sdk/src/types/resources/license.ts create mode 100644 packages/core-sdk/src/types/resources/module.ts create mode 100644 packages/core-sdk/src/types/resources/relationship.ts create mode 100644 packages/core-sdk/src/types/resources/relationshipType.ts create mode 100644 packages/core-sdk/src/types/resources/transaction.ts create mode 100644 packages/core-sdk/src/utils/errors.ts create mode 100644 packages/core-sdk/src/utils/platform.ts create mode 100644 packages/core-sdk/src/utils/utils.ts create mode 100644 packages/core-sdk/test/integration/config.test.ts create mode 100644 packages/core-sdk/test/integration/hookReadOnly.test.ts create mode 100644 packages/core-sdk/test/integration/ipAsset.test.ts create mode 100644 packages/core-sdk/test/integration/ipAssetReadOnly.test.ts create mode 100644 packages/core-sdk/test/integration/ipOrg.test.ts create mode 100644 packages/core-sdk/test/integration/ipOrgReadOnly.test.ts create mode 100644 packages/core-sdk/test/integration/license.test.ts create mode 100644 packages/core-sdk/test/integration/licenseReadOnly.test.ts create mode 100644 packages/core-sdk/test/integration/moduleReadOnly.test.ts create mode 100644 packages/core-sdk/test/integration/platform.test.ts create mode 100644 packages/core-sdk/test/integration/relationship.test.ts create mode 100644 packages/core-sdk/test/integration/relationshipReadOnly.test.ts create mode 100644 packages/core-sdk/test/integration/relationshipType.test.ts create mode 100644 packages/core-sdk/test/integration/relationshipTypeReadOnly.test.ts create mode 100644 packages/core-sdk/test/integration/transactionReadOnly.test.ts create mode 100644 packages/core-sdk/test/unit/client.test.ts create mode 100644 packages/core-sdk/test/unit/clientReadOnly.test.ts create mode 100644 packages/core-sdk/test/unit/resources/hookReadOnly.test.ts create mode 100644 packages/core-sdk/test/unit/resources/ipAsset.test.ts create mode 100644 packages/core-sdk/test/unit/resources/ipAssetReadOnly.test.ts create mode 100644 packages/core-sdk/test/unit/resources/ipOrg.test.ts create mode 100644 packages/core-sdk/test/unit/resources/ipOrgReadOnly.test.ts create mode 100644 packages/core-sdk/test/unit/resources/license.test.ts create mode 100644 packages/core-sdk/test/unit/resources/licenseReadOnly.test.ts create mode 100644 packages/core-sdk/test/unit/resources/moduleReadOnly.test.ts create mode 100644 packages/core-sdk/test/unit/resources/relationship.test.ts create mode 100644 packages/core-sdk/test/unit/resources/relationshipReadOnly.test.ts create mode 100644 packages/core-sdk/test/unit/resources/relationshipType.test.ts create mode 100644 packages/core-sdk/test/unit/resources/relationshipTypeReadOnly.test.ts create mode 100644 packages/core-sdk/test/unit/resources/transactionReadOnly.test.ts create mode 100644 packages/core-sdk/test/unit/testUtils.ts create mode 100644 packages/core-sdk/test/unit/utils/errors.test.ts create mode 100644 packages/core-sdk/test/unit/utils/mockData.ts create mode 100644 packages/core-sdk/test/unit/utils/platform.test.ts create mode 100644 packages/core-sdk/test/unit/utils/utils.test.ts create mode 100644 packages/core-sdk/tsconfig.json create mode 100644 packages/core-sdk/tsconfig.test.json create mode 100644 packages/core-sdk/tsdoc.json create mode 100644 packages/eslint-config-story/README.md create mode 100644 packages/eslint-config-story/index.js create mode 100644 packages/eslint-config-story/package.json create mode 100644 packages/prettier-config/index.json create mode 100644 packages/prettier-config/package.json create mode 100644 packages/tsconfig/base.json create mode 100644 packages/tsconfig/package.json create mode 100644 pnpm-lock.yaml create mode 100644 pnpm-workspace.yaml create mode 100644 turbo.json diff --git a/.changeset/config.json b/.changeset/config.json new file mode 100644 index 00000000..ec59e9b5 --- /dev/null +++ b/.changeset/config.json @@ -0,0 +1,9 @@ +{ + "$schema": "https://unpkg.com/@changesets/config@2.3.0/schema.json", + "changelog": "@changesets/cli/changelog", + "commit": false, + "linked": [], + "access": "public", + "baseBranch": "main", + "updateInternalDependencies": "patch" + } \ No newline at end of file diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 00000000..2dd9a040 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,4 @@ +Dockerfile +.dockerignore +.git + diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..bd65852e --- /dev/null +++ b/.gitignore @@ -0,0 +1,40 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. +.idea + +# dependencies +node_modules +.pnp +.pnp.js + +# testing +coverage + +# next.js +.next/ +out/ +build + +# typescript +dist + +# misc +.DS_Store +*.pem + +# debug +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# local env files +.env +.env.local +.env.development.local +.env.test.local +.env.production.local + +# turbo +.turbo + +# vercel +.vercel diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 00000000..600ca6b9 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,5 @@ +[submodule "packages/core-sdk/protocol-contracts"] + path = packages/core-sdk/protocol-contracts + url = https://github.com/storyprotocol/protocol-contracts + branch = main + diff --git a/.husky/pre-commit b/.husky/pre-commit new file mode 100755 index 00000000..9be7aac4 --- /dev/null +++ b/.husky/pre-commit @@ -0,0 +1,5 @@ +#!/usr/bin/env sh +. "$(dirname -- "$0")/_/husky.sh" + +pnpm fix +git add . diff --git a/.nvmrc b/.nvmrc new file mode 100644 index 00000000..2a59cf43 --- /dev/null +++ b/.nvmrc @@ -0,0 +1 @@ +v20.0.0 diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 00000000..50172abe --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,76 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +In the interest of fostering an open and welcoming environment, we as +contributors and maintainers pledge to make participation in our project and +our community a harassment-free experience for everyone, regardless of age, body +size, disability, ethnicity, sex characteristics, gender identity and expression, +level of experience, education, socio-economic status, nationality, personal +appearance, race, religion, or sexual identity and orientation. + +## Our Standards + +Examples of behavior that contributes to creating a positive environment +include: + +* Using welcoming and inclusive language +* Being respectful of differing viewpoints and experiences +* Gracefully accepting constructive criticism +* Focusing on what is best for the community +* Showing empathy towards other community members + +Examples of unacceptable behavior by participants include: + +* The use of sexualized language or imagery and unwelcome sexual attention or + advances +* Trolling, insulting/derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or electronic + address, without explicit permission +* Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Our Responsibilities + +Project maintainers are responsible for clarifying the standards of acceptable +behavior and are expected to take appropriate and fair corrective action in +response to any instances of unacceptable behavior. + +Project maintainers have the right and responsibility to remove, edit, or +reject comments, commits, code, wiki edits, issues, and other contributions +that are not aligned to this Code of Conduct, or to ban temporarily or +permanently any contributor for other behaviors that they deem inappropriate, +threatening, offensive, or harmful. + +## Scope + +This Code of Conduct applies within all project spaces, and it also applies when +an individual is representing the project or its community in public spaces. +Examples of representing a project or community include using an official +project e-mail address, posting via an official social media account, or acting +as an appointed representative at an online or offline event. Representation of +a project may be further defined and clarified by project maintainers. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported by contacting the project team at contact@storyprotocol.xyz. All +complaints will be reviewed and investigated and will result in a response that +is deemed necessary and appropriate to the circumstances. The project team is +obligated to maintain confidentiality with regard to the reporter of an incident. +Further details of specific enforcement policies may be posted separately. + +Project maintainers who do not follow or enforce the Code of Conduct in good +faith may face temporary or permanent repercussions as determined by other +members of the project's leadership. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, +available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html + +[homepage]: https://www.contributor-covenant.org + +For answers to common questions about this code of conduct, see +https://www.contributor-covenant.org/faq \ No newline at end of file diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 00000000..90a70391 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,66 @@ +# Contributing + +## Code of Conduct + +Please make sure to read and observe our [Code of Conduct](/CODE_OF_CONDUCT.md). + +## Engineering Guideline + +[Typescript coding guidelines][3] + +[Good commit messages][2] + +## Bug Reports + +* Ensure your issue [has not already been reported][1]. It may already be fixed! +* Include the steps you carried out to produce the problem. +* Include the behavior you observed along with the behavior you expected, and + why you expected it. +* Include any relevant stack traces or debugging output. + +## Feature Requests + +We welcome feedback with or without pull requests. If you have an idea for how +to improve the project, great! All we ask is that you take the time to write a +clear and concise explanation of what need you are trying to solve. If you have +thoughts on _how_ it can be solved, include those too! + +The best way to see a feature added, however, is to submit a pull request. + +## Pull Requests + +* Before creating your pull request, it's usually worth asking if the code + you're planning on writing will actually be considered for merging. You can + do this by [opening an issue][1] and asking. It may also help give the + maintainers context for when the time comes to review your code. + +* Ensure your [commit messages are well-written][2]. This can double as your + pull request message, so it pays to take the time to write a clear message. + +* Add tests for your feature. You should be able to look at other tests for + examples. If you're unsure, don't hesitate to [open an issue][1] and ask! + +* Submit your pull request! + - Fork the repository on GitHub. + - Make your changes on your fork repository. + - Submit a PR. + +## Find something to work on + +We are always in need of help, be it fixing documentation, reporting bugs or writing some code. +Look at places where you feel best coding practices aren't followed, code refactoring is needed or tests are missing. + +If you have questions about the development process, +feel free to [file an issue](https://github.com/storyprotocol/project-nova/issues/new). + +## Code Review + +To make it easier for your PR to receive reviews, consider the reviewers will need you to: + +* follow [good coding guidelines][3]. +* write [good commit messages][2]. +* break large changes into a logical series of smaller patches which individually make easily understandable changes, and in aggregate solve a broader issue. + +[1]: https://github.com/storyprotocol/typescript-sdk/issues +[2]: https://chris.beams.io/posts/git-commit/#seven-rules +[3]: https://google.github.io/styleguide/tsguide.html \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 00000000..4ca55327 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,13 @@ +FROM node:18.15.0-slim + +# install pnpm +RUN npm i -g pnpm@8.8.0 + +# prepare packages +COPY . /repo +WORKDIR /repo +RUN pnpm install + +# set entrypoint +ENTRYPOINT ["pnpm"] + diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 00000000..04bc62c6 --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2023 Story Protocol Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/Makefile b/Makefile new file mode 100644 index 00000000..5705a362 --- /dev/null +++ b/Makefile @@ -0,0 +1,22 @@ +compile_contracts: + git submodule add -b main --force https://github.com/storyprotocol/protocol-contracts packages/core-sdk/protocol-contracts + git submodule update --remote --merge + cd packages/core-sdk/protocol-contracts && npm i + + solc --pretty-json --base-path packages/core-sdk/protocol-contracts --include-path packages/core-sdk/protocol-contracts/node_modules/ --abi packages/core-sdk/protocol-contracts/contracts/StoryProtocol.sol -o packages/core-sdk/src/abi/json/tmp/StoryProtocol + solc --pretty-json --base-path packages/core-sdk/protocol-contracts --include-path packages/core-sdk/protocol-contracts/node_modules/ --abi packages/core-sdk/protocol-contracts/contracts/ip-org/IPOrgController.sol -o packages/core-sdk/src/abi/json/tmp/IPOrgController + solc --pretty-json --base-path packages/core-sdk/protocol-contracts --include-path packages/core-sdk/protocol-contracts/node_modules/ --abi packages/core-sdk/protocol-contracts/contracts/modules/licensing/LicenseRegistry.sol -o packages/core-sdk/src/abi/json/tmp/LicenseRegistry + solc --pretty-json --base-path packages/core-sdk/protocol-contracts --include-path packages/core-sdk/protocol-contracts/node_modules/ --abi packages/core-sdk/protocol-contracts/contracts/modules/registration/RegistrationModule.sol -o packages/core-sdk/src/abi/json/tmp/RegistrationModule + solc --pretty-json --base-path packages/core-sdk/protocol-contracts --include-path packages/core-sdk/protocol-contracts/node_modules/ --abi packages/core-sdk/protocol-contracts/contracts/modules/relationships/RelationshipModule.sol -o packages/core-sdk/src/abi/json/tmp/RelationshipModule + solc --pretty-json --base-path packages/core-sdk/protocol-contracts --include-path packages/core-sdk/protocol-contracts/node_modules/ --abi packages/core-sdk/protocol-contracts/contracts/lib/Errors.sol -o packages/core-sdk/src/abi/json/tmp/Errors + cp packages/core-sdk/src/abi/json/tmp/Errors/Errors.abi packages/core-sdk/src/abi/json/Errors.json + + echo 'export default '"$$(jq '.' packages/core-sdk/src/abi/json/Errors.json)"' as const;' > packages/core-sdk/src/abi/json/Errors.abi.ts + echo 'export default '"$$(jq --argjson entities "$$(jq -c '.' packages/core-sdk/src/abi/sdkEntities.json)" 'map(select(.name as $$name | $$entities | if type == "array" then index($$name) else false end))' packages/core-sdk/src/abi/json/tmp/StoryProtocol/StoryProtocol.abi)"' as const;' > packages/core-sdk/src/abi/json/StoryProtocol.abi.ts + echo 'export default '"$$(jq --argjson entities "$$(jq -c '.' packages/core-sdk/src/abi/sdkEntities.json)" 'map(select(.name as $$name | $$entities | if type == "array" then index($$name) else false end))' packages/core-sdk/src/abi/json/tmp/IPOrgController/IPOrgController.abi)"' as const;' > packages/core-sdk/src/abi/json/IPOrgController.abi.ts + echo 'export default '"$$(jq --argjson entities "$$(jq -c '.' packages/core-sdk/src/abi/sdkEntities.json)" 'map(select(.name as $$name | $$entities | if type == "array" then index($$name) else false end))' packages/core-sdk/src/abi/json/tmp/LicenseRegistry/LicenseRegistry.abi)"' as const;' > packages/core-sdk/src/abi/json/LicenseRegistry.abi.ts + echo 'export default '"$$(jq --argjson entities "$$(jq -c '.' packages/core-sdk/src/abi/sdkEntities.json)" 'map(select(.name as $$name | $$entities | if type == "array" then index($$name) else false end))' packages/core-sdk/src/abi/json/tmp/RegistrationModule/RegistrationModule.abi)"' as const;' > packages/core-sdk/src/abi/json/RegistrationModule.abi.ts + echo 'export default '"$$(jq --argjson entities "$$(jq -c '.' packages/core-sdk/src/abi/sdkEntities.json)" 'map(select(.name as $$name | $$entities | if type == "array" then index($$name) else false end))' packages/core-sdk/src/abi/json/tmp/RelationshipModule/RelationshipModule.abi)"' as const;' > packages/core-sdk/src/abi/json/RelationshipModule.abi.ts + + rm -rf packages/core-sdk/src/abi/json/tmp + rm -rf packages/core-sdk/protocol-contracts diff --git a/README.md b/README.md new file mode 100644 index 00000000..4954ab4a --- /dev/null +++ b/README.md @@ -0,0 +1,152 @@ +# Story Protocol SDK + +Welcome to the documents for Story Protocol SDK. The SDK provides the APIs for developers to build applications with Story Protocol. By using the SDK, developers can create the resources like IP assets and perform actions to interact with the resource. + +## How to use Story Protocol SDK in Your Project + +### Install Story Protocol core SDK +Suppose you already have a node project or created a new node project. First, you need to install `@story-protocol/core-sdk` in your project. You can use one of the following command to install the package: + +Use `npm`: +``` +npm install --save @story-protocol/core-sdk viem +``` + +Use `pnpm`: +``` +pnpm install @story-protocol/core-sdk viem +``` + +Use `yarn`: +``` +yarn add @story-protocol/core-sdk viem +``` + +Besides the Story Protocol SDK package `@story-protocol/core-sdk`, we also require the package `viem` (https://www.npmjs.com/package/viem) to access the DeFi wallet accounts. + +### Setup the `.env` file for your project + +The second steps is to create a file named `.env` in the root directory of the project with the following environment variables: + +``` +NEXT_PUBLIC_API_BASE_URL= + +NEXT_PUBLIC_STORY_PROTOCOL_CONTRACT= +NEXT_PUBLIC_IP_ASSET_REGISTRY_CONTRACT= +NEXT_PUBLIC_IP_ORG_CONTROLLER_CONTRACT= +NEXT_PUBLIC_RELATIONSHIP_MODULE_CONTRACT= +NEXT_PUBLIC_REGISTRATION_MODULE_CONTRACT= +NEXT_PUBLIC_LICENSE_REGISTRY_CONTRACT= +NEXT_PUBLIC_MODULE_REGISTRY_CONTRACT= + +# RPC Endpoint for Sepolia Testnet +RPC_URL=https://rpc.ankr.com/eth_sepolia + +# Private key of the wallet to interact with Story Protocol SDK +PRIVATE_KEY="" +``` + +The above `.env` defines several variables with prefix `NEXT_PUBLIC_`that will be used by Story Protocol SDK. Because the alpha version of Story Protocol SDK works with the smart contracts deployed on Sepolia testnet, we need to provide the RPC URL for the end point. + +For the latest values of the smart contract addresses, please reach out the Story Protocol team or refer to [SDK Setup Guide Document](https://docs.storyprotocol.xyz/docs/setup) + +### Create Story Protocol Client + +Next, we need create a client to access Story Protocol by using private key or from the wallet app of browser. + +Here is the way to create a Story Protocol client with the private key: + +```typescript +import { privateKeyToAccount } from "viem/accounts"; + +const PRIVATE_KEY = process.env.PRIVATE_KEY || "0x"; +const account = privateKeyToAccount(PRIVATE_KEY as `0x${string}`); + +// Instantiate the Story Client for readonly operations, using default +export const realonlyClient = StoryClient.newReadOnlyClient({}); + +// Instantiate the Story Client, test environment required for alpha release. +// The private key is also required for written operations. +export const client = StoryClient.newClient({account}); +``` + +Here is the way to create a Story Protocol with wallet app: + +```typescript +import { createWalletClient, custom } from 'viem' +import { sepolia } from 'viem/chains' + +const walletClient = createWalletClient({ + chain: sepolia, + transport: custom(window.ethereum) +}) + +// Retrieve the first account for eth_requestAccounts method +const account = await walletClient.requestAddresses()[0] + +// Instantiate the Story Client for readonly operations, using default +export const realonlyClient = StoryClient.newReadOnlyClient({}); + +// Instantiate the Story Client, test environment required for alpha release. +// The private key is also required for written operations. +export const client = StoryClient.newClient({account}); +``` + +### Use `Client` or `ReadOnlyClient` to access Story Protocol + +Now you can use the `ReadOnlyClient` instance to perform read-only operations with Story Protocol resources, and `Client` instance to perform both read-only and write operations. `ReadOnlyClient` and `Client` are the aggregators for accessing the resources. You can refer to [SDK document](https://docs.storyprotocol.xyz/docs/overview-1) to learn how to use these clients interact with Story Protocol. + +You can also refer to the [Story Protocol Example Repostory](https://github.com/storyprotocol/my-story-protocol-example/) to learn with the SDK example. + +## How To Build and Test Story Protocol SDK + +This section provides the instructions on how to build Story Protocol SDK from source code. + +### Prerequisite + +* Install PNPM: Execute `npm install -g pnpm` +* Install TypeScript: Run `pnpm add typescript -D` +* Install Yalc: Use `npm install -g yalc` + +### Steps for Using Yalc for Local Testing of Core-SDK +For manual testing of the core-sdk, set up a separate web project. The guide below uses `yalc` to link the `core-sdk` locally, enabling its installation and import for testing. + +Under the `typescript-sdk/packages/core-sdk` directory: +* Navigate to the `core-sdk` directory. +* Execute `npm run build` to build your latest code. +* Run `yalc publish`. You should see a message like `@story-protocol/core-sdk@ published in store.` (Note: The version number may vary). + +To set up your testing environment (e.g., a new Next.js project), use `yalc add @story-protocol/core-sdk@` (ensure the version number is updated accordingly). +* Run `pnpm install`. This installs `@story-protocol/core-sdk@` with your local changes. + +### Steps to Refresh the Changes +Under the `typescript-sdk/packages/core-sdk` directory: +* Execute `npm run build` to build your latest code. +* Run `yalc push`. + +In your testing environment: +* Run `yalc update` to pull the latest changes. + +## Steps to pull and compile latest smart contract ABIs (Currently pulls from the protocol-contracts `dev` branch) +Must have `solc` installed (https://docs.soliditylang.org/en/v0.8.9/installing-solidity.html) +* run `make compile_contracts` + +## Release + +| Package | Description | +| :------------------------------ | :--------------------------------------------- | +| [core-sdk](./packages/core-sdk) | The core sdk for interacting with the protocol | + +## Contributing + +Pull requests are welcome. For major changes, please open an issue first +to discuss what you would like to change. Details see: [CONTRIBUTING](/CONTRIBUTING.md) + +Please make sure to update tests as appropriate. + +## License + +[MIT License](/LICENSE.md) + +## Contact Us + diff --git a/package.json b/package.json new file mode 100644 index 00000000..3eaf1593 --- /dev/null +++ b/package.json @@ -0,0 +1,24 @@ +{ + "name": "typescript-sdk", + "version": "0.0.0", + "private": true, + "repository": "https://github.com/storyprotocol/typescript-sdk", + "author": "storyprotocol engineering ", + "license": "MIT", + "scripts": { + "build": "turbo run build", + "lint": "turbo run lint", + "fix": "turbo run fix", + "test": "turbo run test --no-cache", + "prepare": "husky install" + }, + "devDependencies": { + "@changesets/cli": "^2.26.2", + "turbo": "^1.10.13", + "husky": "^8.0.0" + }, + "engines": { + "node": "^20.0.0" + }, + "packageManager": "pnpm@8.7.5" +} diff --git a/packages/core-sdk/.env.example b/packages/core-sdk/.env.example new file mode 100644 index 00000000..cf754918 --- /dev/null +++ b/packages/core-sdk/.env.example @@ -0,0 +1,11 @@ +# APP CONFIGs +API_BASE_URL = +FRANCHISE_REGISTRY_CONTRACT = +RELATIONSHIP_MODULE_CONTRACT = +COLLECT_MODULE_CONTRACT = +LICENSING_MODULE_CONTRACT = + +# TEST CONFIGs +RPC_PROVIDER_URL = +WALLET_PRIVATE_KEY = + diff --git a/packages/core-sdk/.eslintrc.cjs b/packages/core-sdk/.eslintrc.cjs new file mode 100644 index 00000000..07203546 --- /dev/null +++ b/packages/core-sdk/.eslintrc.cjs @@ -0,0 +1,9 @@ +module.exports = { + // We shouldn't ignore linting for tests. Add it back once we customize the linting rules for tests. + ignorePatterns: ["**/*.cjs", "**/test/**/*.ts"], + parserOptions: { + project: "./tsconfig.json", + tsconfigRootDir: __dirname, + }, + extends: ["@story-protocol/eslint-config"], +}; diff --git a/packages/core-sdk/.prettierignore b/packages/core-sdk/.prettierignore new file mode 100644 index 00000000..53c37a16 --- /dev/null +++ b/packages/core-sdk/.prettierignore @@ -0,0 +1 @@ +dist \ No newline at end of file diff --git a/packages/core-sdk/README.md b/packages/core-sdk/README.md new file mode 100644 index 00000000..425f2ac3 --- /dev/null +++ b/packages/core-sdk/README.md @@ -0,0 +1,85 @@ +core-sdk is the base level sdk to interact with story protocol. It provides functions to both read and write data to the protocol. + +## Installation + +Install the SDK and ethers.js + +npm + +```shell +npm i @story-protocol/core-sdk ethers@^5.7.2 +``` + +pnpm + +```shell +pnpm i @story-protocol/core-sdk ethers@^5.7.2 +``` + +yarn + +```shell +yarn add @story-protocol/core-sdk ethers@^5.7.2 +``` + +## Set up `.env` file + +(Ask the team to provide the values) + +``` +NEXT_PUBLIC_API_BASE_URL = +NEXT_PUBLIC_FRANCHISE_REGISTRY_CONTRACT = +NEXT_PUBLIC_RELATIONSHIP_MODULE_CONTRACT = +NEXT_PUBLIC_COLLECT_MODULE_CONTRACT = +NEXT_PUBLIC_LICENSING_MODULE_CONTRACT = +``` + +## Set up SDK client + +Using browser wallet + +```typescript +import { StoryClient } from "@story-protocol/core-sdk"; +import ethers from "ethers"; + +// Provider/Signer from browser wallet (i.e Metamask) +const provider = new ethers.providers.Web3Provider(window.ethereum); +await provider.send("eth_requestAccounts", []); +const signer = await provider.getSigner(); + +// Instantiate a read-only Story Client with an optional provider +const client = StoryClient.newReadOnlyClient({ provider }); + +// Instatiate a read/write Story Client with a signer +const client = StoryClient.newClient({ signer }); +``` + +Using private key + +```typescript +import { StoryClient } from "@story-protocol/core-sdk" +import ethers from "ethers" + +// Signer from private key +const provider = new ethers.providers.JsonRpcProvider() +const signer = new ethers.Wallet(, provider) + +// Instantiate the Story Client +const client = StoryClient.newClient({ signer }) + +``` + +## Use SDK client + +```typescript +// Create a new franchise +const response = await client.franchise.create({ + franchiseName: "Alice in Wonderland", + franchiseSymbol: "Wonderland", + franchiseDescription: + "Fantastical journey, curious girl, whimsical characters, dreamlike adventures.", +}); + +// List franchises +const { data: franchise } = await client.franchise.list(); +``` diff --git a/packages/core-sdk/package.json b/packages/core-sdk/package.json new file mode 100644 index 00000000..579fce29 --- /dev/null +++ b/packages/core-sdk/package.json @@ -0,0 +1,91 @@ +{ + "name": "@story-protocol/core-sdk", + "version": "0.1.0-alpha", + "description": "Story Protocol Core SDK", + "main": "dist/story-protocol-core-sdk.cjs.js", + "module": "dist/story-protocol-core-sdk.esm.js", + "exports": { + ".": { + "module": "./dist/story-protocol-core-sdk.esm.js", + "default": "./dist/story-protocol-core-sdk.cjs.js" + }, + "./package.json": "./package.json" + }, + "sideEffects": false, + "files": [ + "dist/**/*" + ], + "scripts": { + "build": "pnpm run fix && preconstruct build", + "test": "pnpm run test:unit && pnpm run test:integration", + "test:unit": "TS_NODE_PROJECT='./tsconfig.test.json' c8 --all --src ./src mocha -r ts-node/register './test/unit/**/*.test.ts'", + "test:integration": "TS_NODE_PROJECT='./tsconfig.test.json' mocha -r ts-node/register './test/integration/**/*.test.ts' --timeout 240000", + "fix": "pnpm run format:fix && pnpm run lint:fix", + "format": "prettier --check .", + "format:fix": "prettier --write .", + "lint:fix": "pnpm run lint --fix", + "lint": "eslint ./src", + "tsc": "tsc --noEmit" + }, + "license": "MIT", + "dependencies": { + "abitype": "^0.10.2", + "axios": "^1.5.1", + "dotenv": "^16.3.1", + "viem": "^1.18.4" + }, + "devDependencies": { + "@babel/core": "^7.23.0", + "@babel/preset-env": "^7.22.20", + "@babel/preset-typescript": "^7.23.0", + "@preconstruct/cli": "^2.8.1", + "@story-protocol/eslint-config": "workspace:*", + "@story-protocol/prettier-config": "workspace:*", + "@story-protocol/tsconfig": "workspace:*", + "@types/chai": "^4.3.6", + "@types/chai-as-promised": "^7.1.6", + "@types/mocha": "^10.0.2", + "@types/node": "^20.8.2", + "@types/sinon": "^10.0.18", + "c8": "^8.0.1", + "chai": "^4.3.10", + "chai-as-promised": "^7.1.1", + "eslint": "^8.50.0", + "mocha": "^10.2.0", + "prettier": "^2.8.8", + "sinon": "^16.0.0", + "ts-node": "^10.9.1", + "typechain": "^8.3.1", + "typescript": "^5.2.2" + }, + "prettier": "@story-protocol/prettier-config", + "babel": { + "presets": [ + "@babel/preset-env", + "@babel/preset-typescript" + ] + }, + "preconstruct": { + "entrypoints": [ + "index.ts" + ], + "exports": true + }, + "c8": { + "exclude": [ + "test/**/*", + "src/abi/**/*", + "src/index.ts", + "src/types/**/*" + ], + "check-coverage": true, + "lines": 100, + "functions": 100, + "branches": 100, + "statements": 100 + }, + "typedoc": { + "entryPoint": "./src/index.ts", + "tsconfig": "./tsconfig.json" + } +} diff --git a/packages/core-sdk/src/abi/ipOrgController.abi.ts b/packages/core-sdk/src/abi/ipOrgController.abi.ts new file mode 100644 index 00000000..7a79213b --- /dev/null +++ b/packages/core-sdk/src/abi/ipOrgController.abi.ts @@ -0,0 +1,19 @@ +import { getAddress } from "viem"; +import * as dotenv from "dotenv"; + +import IPOrgControllerABI from "./json/IPOrgController.abi"; + +if (typeof process !== "undefined") { + dotenv.config(); +} + +export const ipOrgControllerAbi = IPOrgControllerABI; + +export const ipOrgControllerConfig = { + abi: ipOrgControllerAbi, + address: getAddress( + process.env.IP_ORG_CONTROLLER_CONTRACT || + process.env.NEXT_PUBLIC_IP_ORG_CONTROLLER_CONTRACT || + "", + ), +}; diff --git a/packages/core-sdk/src/abi/json/Errors.abi.ts b/packages/core-sdk/src/abi/json/Errors.abi.ts new file mode 100644 index 00000000..6a4a8a10 --- /dev/null +++ b/packages/core-sdk/src/abi/json/Errors.abi.ts @@ -0,0 +1,881 @@ +export default [ + { + inputs: [ + { + internalType: "uint8", + name: "hookType", + type: "uint8", + }, + ], + name: "BaseModule_HooksParamsLengthMismatch", + type: "error", + }, + { + inputs: [], + name: "BaseModule_OnlyModuleRegistry", + type: "error", + }, + { + inputs: [], + name: "BaseModule_Unauthorized", + type: "error", + }, + { + inputs: [], + name: "BaseModule_ZeroIpaRegistry", + type: "error", + }, + { + inputs: [], + name: "BaseModule_ZeroLicenseRegistry", + type: "error", + }, + { + inputs: [], + name: "BaseRelationshipProcessor_OnlyRelationshipModule", + type: "error", + }, + { + inputs: [], + name: "CollectModule_CallerUnauthorized", + type: "error", + }, + { + inputs: [], + name: "CollectModule_CollectNotYetInitialized", + type: "error", + }, + { + inputs: [], + name: "CollectModule_CollectUnauthorized", + type: "error", + }, + { + inputs: [], + name: "CollectModule_IPAssetAlreadyInitialized", + type: "error", + }, + { + inputs: [], + name: "CollectModule_IPAssetNonExistent", + type: "error", + }, + { + inputs: [], + name: "CollectModule_IPOrgNonExistent", + type: "error", + }, + { + inputs: [], + name: "CollectNFT_AlreadyInitialized", + type: "error", + }, + { + inputs: [], + name: "CollectNFT_CallerUnauthorized", + type: "error", + }, + { + inputs: [], + name: "CollectNFT_CollectorInvalid", + type: "error", + }, + { + inputs: [], + name: "CollectNFT_IPAssetNonExistent", + type: "error", + }, + { + inputs: [], + name: "CollectPaymentModule_AmountInvalid", + type: "error", + }, + { + inputs: [], + name: "CollectPaymentModule_ERC20TransferFailed", + type: "error", + }, + { + inputs: [], + name: "CollectPaymentModule_ERC20TransferInvalidABIEncoding", + type: "error", + }, + { + inputs: [], + name: "CollectPaymentModule_ERC20TransferInvalidReturnValue", + type: "error", + }, + { + inputs: [], + name: "CollectPaymentModule_InvalidSettings", + type: "error", + }, + { + inputs: [], + name: "CollectPaymentModule_NativeTokenNotAllowed", + type: "error", + }, + { + inputs: [], + name: "CollectPaymentModule_NativeTransferFailed", + type: "error", + }, + { + inputs: [], + name: "CollectPaymentModule_PaymentInsufficient", + type: "error", + }, + { + inputs: [], + name: "CollectPaymentModule_PaymentParamsInvalid", + type: "error", + }, + { + inputs: [], + name: "CollectPaymentModule_TokenInvalid", + type: "error", + }, + { + inputs: [], + name: "ERC721_OwnerInvalid", + type: "error", + }, + { + inputs: [], + name: "ERC721_ReceiverInvalid", + type: "error", + }, + { + inputs: [], + name: "ERC721_SafeTransferUnsupported", + type: "error", + }, + { + inputs: [], + name: "ERC721_SenderUnauthorized", + type: "error", + }, + { + inputs: [], + name: "ERC721_TokenAlreadyMinted", + type: "error", + }, + { + inputs: [], + name: "ERC721_TokenNonExistent", + type: "error", + }, + { + inputs: [], + name: "EmptyArray", + type: "error", + }, + { + inputs: [], + name: "HookRegistry_CallerNotIPOrgOwner", + type: "error", + }, + { + inputs: [], + name: "HookRegistry_HooksConfigLengthMismatch", + type: "error", + }, + { + inputs: [ + { + internalType: "uint256", + name: "hooksIndex", + type: "uint256", + }, + ], + name: "HookRegistry_IndexOutOfBounds", + type: "error", + }, + { + inputs: [], + name: "HookRegistry_MaxHooksExceeded", + type: "error", + }, + { + inputs: [], + name: "HookRegistry_RegisteringDuplicatedHook", + type: "error", + }, + { + inputs: [ + { + internalType: "address", + name: "hookAddress", + type: "address", + }, + ], + name: "HookRegistry_RegisteringNonWhitelistedHook", + type: "error", + }, + { + inputs: [], + name: "HookRegistry_RegisteringZeroAddressHook", + type: "error", + }, + { + inputs: [], + name: "HookRegistry_ZeroModuleRegistry", + type: "error", + }, + { + inputs: [ + { + internalType: "bytes32", + name: "requestId", + type: "bytes32", + }, + { + internalType: "string", + name: "reason", + type: "string", + }, + ], + name: "Hook_AsyncHookError", + type: "error", + }, + { + inputs: [ + { + internalType: "bytes32", + name: "invalidRequestId", + type: "bytes32", + }, + ], + name: "Hook_InvalidAsyncRequestId", + type: "error", + }, + { + inputs: [ + { + internalType: "string", + name: "reason", + type: "string", + }, + ], + name: "Hook_InvalidHookConfig", + type: "error", + }, + { + inputs: [ + { + internalType: "address", + name: "current", + type: "address", + }, + { + internalType: "address", + name: "expected", + type: "address", + }, + ], + name: "Hook_OnlyCallbackCallerCanCallback", + type: "error", + }, + { + inputs: [], + name: "Hook_RequestedNotFound", + type: "error", + }, + { + inputs: [], + name: "Hook_UnsupportedAsyncOperation", + type: "error", + }, + { + inputs: [], + name: "Hook_UnsupportedSyncOperation", + type: "error", + }, + { + inputs: [], + name: "IPAccountImpl_CallerNotOwner", + type: "error", + }, + { + inputs: [], + name: "IPAccountRegistry_InitializationFailed", + type: "error", + }, + { + inputs: [], + name: "IPAccountRegistry_NonExistentIpAccountImpl", + type: "error", + }, + { + inputs: [], + name: "IPOrgController_IPOrgNonExistent", + type: "error", + }, + { + inputs: [], + name: "IPOrgController_InvalidIPOrgOwner", + type: "error", + }, + { + inputs: [], + name: "IPOrgController_InvalidNewIPOrgOwner", + type: "error", + }, + { + inputs: [], + name: "IPOrgController_InvalidOwner", + type: "error", + }, + { + inputs: [], + name: "IPOrgController_OwnerTransferUninitialized", + type: "error", + }, + { + inputs: [], + name: "IPOrg_IdDoesNotExist", + type: "error", + }, + { + inputs: [], + name: "IPOrg_IdOverBounds", + type: "error", + }, + { + inputs: [], + name: "IPOrg_LicensingNotConfigured", + type: "error", + }, + { + inputs: [], + name: "LengthMismatch", + type: "error", + }, + { + inputs: [], + name: "LibDuration_CallerNotRenewer", + type: "error", + }, + { + inputs: [], + name: "LibDuration_InvalidStartTime", + type: "error", + }, + { + inputs: [], + name: "LibDuration_NotRenewable", + type: "error", + }, + { + inputs: [], + name: "LibDuration_ZeroTTL", + type: "error", + }, + { + inputs: [], + name: "LicenseRegistry_CallerNotLicensingModule", + type: "error", + }, + { + inputs: [], + name: "LicenseRegistry_CallerNotLicensingModuleOrLicensee", + type: "error", + }, + { + inputs: [], + name: "LicenseRegistry_CallerNotLicensor", + type: "error", + }, + { + inputs: [], + name: "LicenseRegistry_CallerNotRevoker", + type: "error", + }, + { + inputs: [], + name: "LicenseRegistry_IPANotActive", + type: "error", + }, + { + inputs: [], + name: "LicenseRegistry_InvalidLicenseStatus", + type: "error", + }, + { + inputs: [], + name: "LicenseRegistry_LicenseAlreadyLinkedToIpa", + type: "error", + }, + { + inputs: [], + name: "LicenseRegistry_LicenseNotActive", + type: "error", + }, + { + inputs: [], + name: "LicenseRegistry_LicenseNotPendingApproval", + type: "error", + }, + { + inputs: [], + name: "LicenseRegistry_ParentLicenseNotActive", + type: "error", + }, + { + inputs: [], + name: "LicenseRegistry_UnknownLicenseId", + type: "error", + }, + { + inputs: [], + name: "LicensingFrameworkRepo_DuplicateParamType", + type: "error", + }, + { + inputs: [], + name: "LicensingFrameworkRepo_FrameworkAlreadyAdded", + type: "error", + }, + { + inputs: [], + name: "LicensingFrameworkRepo_TooManyParams", + type: "error", + }, + { + inputs: [], + name: "LicensingModule_CallerNotIpOrgOwner", + type: "error", + }, + { + inputs: [], + name: "LicensingModule_CallerNotLicenseOwner", + type: "error", + }, + { + inputs: [], + name: "LicensingModule_CallerNotLicensor", + type: "error", + }, + { + inputs: [], + name: "LicensingModule_CantFindParentLicenseOrRelatedIpa", + type: "error", + }, + { + inputs: [], + name: "LicensingModule_CommercialLicenseNotAllowed", + type: "error", + }, + { + inputs: [], + name: "LicensingModule_DerivativeNotAllowed", + type: "error", + }, + { + inputs: [], + name: "LicensingModule_DuplicateParam", + type: "error", + }, + { + inputs: [], + name: "LicensingModule_DuplicateTermId", + type: "error", + }, + { + inputs: [], + name: "LicensingModule_InvalidAction", + type: "error", + }, + { + inputs: [], + name: "LicensingModule_InvalidConfigType", + type: "error", + }, + { + inputs: [], + name: "LicensingModule_InvalidInputValue", + type: "error", + }, + { + inputs: [], + name: "LicensingModule_InvalidIpa", + type: "error", + }, + { + inputs: [], + name: "LicensingModule_InvalidLicenseeType", + type: "error", + }, + { + inputs: [], + name: "LicensingModule_InvalidLicensorConfig", + type: "error", + }, + { + inputs: [], + name: "LicensingModule_InvalidLicensorType", + type: "error", + }, + { + inputs: [], + name: "LicensingModule_InvalidParamValue", + type: "error", + }, + { + inputs: [], + name: "LicensingModule_InvalidParamsLength", + type: "error", + }, + { + inputs: [], + name: "LicensingModule_InvalidTermCommercialStatus", + type: "error", + }, + { + inputs: [], + name: "LicensingModule_IpOrgAlreadyConfigured", + type: "error", + }, + { + inputs: [], + name: "LicensingModule_IpOrgFrameworkAlreadySet", + type: "error", + }, + { + inputs: [], + name: "LicensingModule_IpOrgFrameworkNotSet", + type: "error", + }, + { + inputs: [], + name: "LicensingModule_IpOrgNotConfigured", + type: "error", + }, + { + inputs: [], + name: "LicensingModule_NonCommercialTermsRequired", + type: "error", + }, + { + inputs: [], + name: "LicensingModule_ParamSetByIpOrg", + type: "error", + }, + { + inputs: [], + name: "LicensingModule_ParentLicenseNotActive", + type: "error", + }, + { + inputs: [], + name: "LicensingModule_ReciprocalCannotSetParams", + type: "error", + }, + { + inputs: [], + name: "LicensingModule_ShareAlikeDisabled", + type: "error", + }, + { + inputs: [], + name: "LicensingModule_ipOrgTermNotFound", + type: "error", + }, + { + inputs: [], + name: "LicensorApprovalHook_ApprovalAlreadyRequested", + type: "error", + }, + { + inputs: [], + name: "LicensorApprovalHook_InvalidLicenseId", + type: "error", + }, + { + inputs: [], + name: "LicensorApprovalHook_InvalidLicensor", + type: "error", + }, + { + inputs: [], + name: "LicensorApprovalHook_InvalidResponseStatus", + type: "error", + }, + { + inputs: [], + name: "LicensorApprovalHook_NoApprovalRequested", + type: "error", + }, + { + inputs: [ + { + internalType: "bytes32", + name: "role", + type: "bytes32", + }, + { + internalType: "address", + name: "account", + type: "address", + }, + ], + name: "MissingRole", + type: "error", + }, + { + inputs: [], + name: "ModuleRegistry_CallerNotOrgOwner", + type: "error", + }, + { + inputs: [], + name: "ModuleRegistry_DependencyAlreadyRegistered", + type: "error", + }, + { + inputs: [], + name: "ModuleRegistry_DependencyNotYetRegistered", + type: "error", + }, + { + inputs: [ + { + internalType: "string", + name: "hookKey", + type: "string", + }, + ], + name: "ModuleRegistry_HookNotRegistered", + type: "error", + }, + { + inputs: [], + name: "ModuleRegistry_InvalidGateway", + type: "error", + }, + { + inputs: [], + name: "ModuleRegistry_ModuleAlreadyRegistered", + type: "error", + }, + { + inputs: [], + name: "ModuleRegistry_ModuleKeyMismatch", + type: "error", + }, + { + inputs: [], + name: "ModuleRegistry_ModuleNotYetRegistered", + type: "error", + }, + { + inputs: [], + name: "ModuleRegistry_Unauthorized", + type: "error", + }, + { + inputs: [], + name: "RegistrationModule_CallerNotAuthorized", + type: "error", + }, + { + inputs: [], + name: "RegistrationModule_IPAssetNonExistent", + type: "error", + }, + { + inputs: [], + name: "RegistrationModule_IPOrgNotConfigured", + type: "error", + }, + { + inputs: [], + name: "RegistrationModule_InvalidCaller", + type: "error", + }, + { + inputs: [], + name: "RegistrationModule_InvalidConfigOperation", + type: "error", + }, + { + inputs: [], + name: "RegistrationModule_InvalidExecutionOperation", + type: "error", + }, + { + inputs: [], + name: "RegistrationModule_InvalidIPAssetType", + type: "error", + }, + { + inputs: [], + name: "RegistrationModule_TooManyAssetTypes", + type: "error", + }, + { + inputs: [], + name: "RelationshipModule_CallerNotIpOrgOwner", + type: "error", + }, + { + inputs: [], + name: "RelationshipModule_CannotRelateToOtherIPOrg", + type: "error", + }, + { + inputs: [], + name: "RelationshipModule_IntentAlreadyRegistered", + type: "error", + }, + { + inputs: [], + name: "RelationshipModule_InvalidConfigOperation", + type: "error", + }, + { + inputs: [], + name: "RelationshipModule_InvalidDstAddress", + type: "error", + }, + { + inputs: [], + name: "RelationshipModule_InvalidDstId", + type: "error", + }, + { + inputs: [], + name: "RelationshipModule_InvalidEndTimestamp", + type: "error", + }, + { + inputs: [], + name: "RelationshipModule_InvalidRelatable", + type: "error", + }, + { + inputs: [], + name: "RelationshipModule_InvalidSrcAddress", + type: "error", + }, + { + inputs: [], + name: "RelationshipModule_InvalidSrcId", + type: "error", + }, + { + inputs: [], + name: "RelationshipModule_InvalidTTL", + type: "error", + }, + { + inputs: [], + name: "RelationshipModule_IpOrgRelatableCannotBeProtocolLevel", + type: "error", + }, + { + inputs: [], + name: "RelationshipModule_NonExistingRelationship", + type: "error", + }, + { + inputs: [ + { + internalType: "string", + name: "relType", + type: "string", + }, + ], + name: "RelationshipModule_RelTypeNotSet", + type: "error", + }, + { + inputs: [], + name: "RelationshipModule_UnsupportedIpOrgIndexType", + type: "error", + }, + { + inputs: [], + name: "RelationshipModule_UnsupportedRelationshipDst", + type: "error", + }, + { + inputs: [], + name: "RelationshipModule_UnsupportedRelationshipSrc", + type: "error", + }, + { + inputs: [ + { + internalType: "uint256", + name: "accountsLength", + type: "uint256", + }, + { + internalType: "uint256", + name: "allocationsLength", + type: "uint256", + }, + ], + name: "RoyaltyNFT_AccountsAndAllocationsMismatch", + type: "error", + }, + { + inputs: [ + { + internalType: "uint32", + name: "allocationsSum", + type: "uint32", + }, + ], + name: "RoyaltyNFT_InvalidAllocationsSum", + type: "error", + }, + { + inputs: [ + { + internalType: "address", + name: "tokenAddress", + type: "address", + }, + { + internalType: "address", + name: "ownerAddress", + type: "address", + }, + ], + name: "TokenGatedHook_NotTokenOwner", + type: "error", + }, + { + inputs: [], + name: "UintArrayMask_EmptyArray", + type: "error", + }, + { + inputs: [], + name: "Unauthorized", + type: "error", + }, + { + inputs: [ + { + internalType: "string", + name: "name", + type: "string", + }, + ], + name: "UnsupportedInterface", + type: "error", + }, + { + inputs: [], + name: "ZeroAddress", + type: "error", + }, + { + inputs: [], + name: "ZeroAmount", + type: "error", + }, +] as const; diff --git a/packages/core-sdk/src/abi/json/Errors.json b/packages/core-sdk/src/abi/json/Errors.json new file mode 100644 index 00000000..97c61340 --- /dev/null +++ b/packages/core-sdk/src/abi/json/Errors.json @@ -0,0 +1,881 @@ +[ + { + "inputs": [ + { + "internalType": "uint8", + "name": "hookType", + "type": "uint8" + } + ], + "name": "BaseModule_HooksParamsLengthMismatch", + "type": "error" + }, + { + "inputs": [], + "name": "BaseModule_OnlyModuleRegistry", + "type": "error" + }, + { + "inputs": [], + "name": "BaseModule_Unauthorized", + "type": "error" + }, + { + "inputs": [], + "name": "BaseModule_ZeroIpaRegistry", + "type": "error" + }, + { + "inputs": [], + "name": "BaseModule_ZeroLicenseRegistry", + "type": "error" + }, + { + "inputs": [], + "name": "BaseRelationshipProcessor_OnlyRelationshipModule", + "type": "error" + }, + { + "inputs": [], + "name": "CollectModule_CallerUnauthorized", + "type": "error" + }, + { + "inputs": [], + "name": "CollectModule_CollectNotYetInitialized", + "type": "error" + }, + { + "inputs": [], + "name": "CollectModule_CollectUnauthorized", + "type": "error" + }, + { + "inputs": [], + "name": "CollectModule_IPAssetAlreadyInitialized", + "type": "error" + }, + { + "inputs": [], + "name": "CollectModule_IPAssetNonExistent", + "type": "error" + }, + { + "inputs": [], + "name": "CollectModule_IPOrgNonExistent", + "type": "error" + }, + { + "inputs": [], + "name": "CollectNFT_AlreadyInitialized", + "type": "error" + }, + { + "inputs": [], + "name": "CollectNFT_CallerUnauthorized", + "type": "error" + }, + { + "inputs": [], + "name": "CollectNFT_CollectorInvalid", + "type": "error" + }, + { + "inputs": [], + "name": "CollectNFT_IPAssetNonExistent", + "type": "error" + }, + { + "inputs": [], + "name": "CollectPaymentModule_AmountInvalid", + "type": "error" + }, + { + "inputs": [], + "name": "CollectPaymentModule_ERC20TransferFailed", + "type": "error" + }, + { + "inputs": [], + "name": "CollectPaymentModule_ERC20TransferInvalidABIEncoding", + "type": "error" + }, + { + "inputs": [], + "name": "CollectPaymentModule_ERC20TransferInvalidReturnValue", + "type": "error" + }, + { + "inputs": [], + "name": "CollectPaymentModule_InvalidSettings", + "type": "error" + }, + { + "inputs": [], + "name": "CollectPaymentModule_NativeTokenNotAllowed", + "type": "error" + }, + { + "inputs": [], + "name": "CollectPaymentModule_NativeTransferFailed", + "type": "error" + }, + { + "inputs": [], + "name": "CollectPaymentModule_PaymentInsufficient", + "type": "error" + }, + { + "inputs": [], + "name": "CollectPaymentModule_PaymentParamsInvalid", + "type": "error" + }, + { + "inputs": [], + "name": "CollectPaymentModule_TokenInvalid", + "type": "error" + }, + { + "inputs": [], + "name": "ERC721_OwnerInvalid", + "type": "error" + }, + { + "inputs": [], + "name": "ERC721_ReceiverInvalid", + "type": "error" + }, + { + "inputs": [], + "name": "ERC721_SafeTransferUnsupported", + "type": "error" + }, + { + "inputs": [], + "name": "ERC721_SenderUnauthorized", + "type": "error" + }, + { + "inputs": [], + "name": "ERC721_TokenAlreadyMinted", + "type": "error" + }, + { + "inputs": [], + "name": "ERC721_TokenNonExistent", + "type": "error" + }, + { + "inputs": [], + "name": "EmptyArray", + "type": "error" + }, + { + "inputs": [], + "name": "HookRegistry_CallerNotIPOrgOwner", + "type": "error" + }, + { + "inputs": [], + "name": "HookRegistry_HooksConfigLengthMismatch", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "hooksIndex", + "type": "uint256" + } + ], + "name": "HookRegistry_IndexOutOfBounds", + "type": "error" + }, + { + "inputs": [], + "name": "HookRegistry_MaxHooksExceeded", + "type": "error" + }, + { + "inputs": [], + "name": "HookRegistry_RegisteringDuplicatedHook", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "hookAddress", + "type": "address" + } + ], + "name": "HookRegistry_RegisteringNonWhitelistedHook", + "type": "error" + }, + { + "inputs": [], + "name": "HookRegistry_RegisteringZeroAddressHook", + "type": "error" + }, + { + "inputs": [], + "name": "HookRegistry_ZeroModuleRegistry", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "requestId", + "type": "bytes32" + }, + { + "internalType": "string", + "name": "reason", + "type": "string" + } + ], + "name": "Hook_AsyncHookError", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "invalidRequestId", + "type": "bytes32" + } + ], + "name": "Hook_InvalidAsyncRequestId", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "reason", + "type": "string" + } + ], + "name": "Hook_InvalidHookConfig", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "current", + "type": "address" + }, + { + "internalType": "address", + "name": "expected", + "type": "address" + } + ], + "name": "Hook_OnlyCallbackCallerCanCallback", + "type": "error" + }, + { + "inputs": [], + "name": "Hook_RequestedNotFound", + "type": "error" + }, + { + "inputs": [], + "name": "Hook_UnsupportedAsyncOperation", + "type": "error" + }, + { + "inputs": [], + "name": "Hook_UnsupportedSyncOperation", + "type": "error" + }, + { + "inputs": [], + "name": "IPAccountImpl_CallerNotOwner", + "type": "error" + }, + { + "inputs": [], + "name": "IPAccountRegistry_InitializationFailed", + "type": "error" + }, + { + "inputs": [], + "name": "IPAccountRegistry_NonExistentIpAccountImpl", + "type": "error" + }, + { + "inputs": [], + "name": "IPOrgController_IPOrgNonExistent", + "type": "error" + }, + { + "inputs": [], + "name": "IPOrgController_InvalidIPOrgOwner", + "type": "error" + }, + { + "inputs": [], + "name": "IPOrgController_InvalidNewIPOrgOwner", + "type": "error" + }, + { + "inputs": [], + "name": "IPOrgController_InvalidOwner", + "type": "error" + }, + { + "inputs": [], + "name": "IPOrgController_OwnerTransferUninitialized", + "type": "error" + }, + { + "inputs": [], + "name": "IPOrg_IdDoesNotExist", + "type": "error" + }, + { + "inputs": [], + "name": "IPOrg_IdOverBounds", + "type": "error" + }, + { + "inputs": [], + "name": "IPOrg_LicensingNotConfigured", + "type": "error" + }, + { + "inputs": [], + "name": "LengthMismatch", + "type": "error" + }, + { + "inputs": [], + "name": "LibDuration_CallerNotRenewer", + "type": "error" + }, + { + "inputs": [], + "name": "LibDuration_InvalidStartTime", + "type": "error" + }, + { + "inputs": [], + "name": "LibDuration_NotRenewable", + "type": "error" + }, + { + "inputs": [], + "name": "LibDuration_ZeroTTL", + "type": "error" + }, + { + "inputs": [], + "name": "LicenseRegistry_CallerNotLicensingModule", + "type": "error" + }, + { + "inputs": [], + "name": "LicenseRegistry_CallerNotLicensingModuleOrLicensee", + "type": "error" + }, + { + "inputs": [], + "name": "LicenseRegistry_CallerNotLicensor", + "type": "error" + }, + { + "inputs": [], + "name": "LicenseRegistry_CallerNotRevoker", + "type": "error" + }, + { + "inputs": [], + "name": "LicenseRegistry_IPANotActive", + "type": "error" + }, + { + "inputs": [], + "name": "LicenseRegistry_InvalidLicenseStatus", + "type": "error" + }, + { + "inputs": [], + "name": "LicenseRegistry_LicenseAlreadyLinkedToIpa", + "type": "error" + }, + { + "inputs": [], + "name": "LicenseRegistry_LicenseNotActive", + "type": "error" + }, + { + "inputs": [], + "name": "LicenseRegistry_LicenseNotPendingApproval", + "type": "error" + }, + { + "inputs": [], + "name": "LicenseRegistry_ParentLicenseNotActive", + "type": "error" + }, + { + "inputs": [], + "name": "LicenseRegistry_UnknownLicenseId", + "type": "error" + }, + { + "inputs": [], + "name": "LicensingFrameworkRepo_DuplicateParamType", + "type": "error" + }, + { + "inputs": [], + "name": "LicensingFrameworkRepo_FrameworkAlreadyAdded", + "type": "error" + }, + { + "inputs": [], + "name": "LicensingFrameworkRepo_TooManyParams", + "type": "error" + }, + { + "inputs": [], + "name": "LicensingModule_CallerNotIpOrgOwner", + "type": "error" + }, + { + "inputs": [], + "name": "LicensingModule_CallerNotLicenseOwner", + "type": "error" + }, + { + "inputs": [], + "name": "LicensingModule_CallerNotLicensor", + "type": "error" + }, + { + "inputs": [], + "name": "LicensingModule_CantFindParentLicenseOrRelatedIpa", + "type": "error" + }, + { + "inputs": [], + "name": "LicensingModule_CommercialLicenseNotAllowed", + "type": "error" + }, + { + "inputs": [], + "name": "LicensingModule_DerivativeNotAllowed", + "type": "error" + }, + { + "inputs": [], + "name": "LicensingModule_DuplicateParam", + "type": "error" + }, + { + "inputs": [], + "name": "LicensingModule_DuplicateTermId", + "type": "error" + }, + { + "inputs": [], + "name": "LicensingModule_InvalidAction", + "type": "error" + }, + { + "inputs": [], + "name": "LicensingModule_InvalidConfigType", + "type": "error" + }, + { + "inputs": [], + "name": "LicensingModule_InvalidInputValue", + "type": "error" + }, + { + "inputs": [], + "name": "LicensingModule_InvalidIpa", + "type": "error" + }, + { + "inputs": [], + "name": "LicensingModule_InvalidLicenseeType", + "type": "error" + }, + { + "inputs": [], + "name": "LicensingModule_InvalidLicensorConfig", + "type": "error" + }, + { + "inputs": [], + "name": "LicensingModule_InvalidLicensorType", + "type": "error" + }, + { + "inputs": [], + "name": "LicensingModule_InvalidParamValue", + "type": "error" + }, + { + "inputs": [], + "name": "LicensingModule_InvalidParamsLength", + "type": "error" + }, + { + "inputs": [], + "name": "LicensingModule_InvalidTermCommercialStatus", + "type": "error" + }, + { + "inputs": [], + "name": "LicensingModule_IpOrgAlreadyConfigured", + "type": "error" + }, + { + "inputs": [], + "name": "LicensingModule_IpOrgFrameworkAlreadySet", + "type": "error" + }, + { + "inputs": [], + "name": "LicensingModule_IpOrgFrameworkNotSet", + "type": "error" + }, + { + "inputs": [], + "name": "LicensingModule_IpOrgNotConfigured", + "type": "error" + }, + { + "inputs": [], + "name": "LicensingModule_NonCommercialTermsRequired", + "type": "error" + }, + { + "inputs": [], + "name": "LicensingModule_ParamSetByIpOrg", + "type": "error" + }, + { + "inputs": [], + "name": "LicensingModule_ParentLicenseNotActive", + "type": "error" + }, + { + "inputs": [], + "name": "LicensingModule_ReciprocalCannotSetParams", + "type": "error" + }, + { + "inputs": [], + "name": "LicensingModule_ShareAlikeDisabled", + "type": "error" + }, + { + "inputs": [], + "name": "LicensingModule_ipOrgTermNotFound", + "type": "error" + }, + { + "inputs": [], + "name": "LicensorApprovalHook_ApprovalAlreadyRequested", + "type": "error" + }, + { + "inputs": [], + "name": "LicensorApprovalHook_InvalidLicenseId", + "type": "error" + }, + { + "inputs": [], + "name": "LicensorApprovalHook_InvalidLicensor", + "type": "error" + }, + { + "inputs": [], + "name": "LicensorApprovalHook_InvalidResponseStatus", + "type": "error" + }, + { + "inputs": [], + "name": "LicensorApprovalHook_NoApprovalRequested", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "MissingRole", + "type": "error" + }, + { + "inputs": [], + "name": "ModuleRegistry_CallerNotOrgOwner", + "type": "error" + }, + { + "inputs": [], + "name": "ModuleRegistry_DependencyAlreadyRegistered", + "type": "error" + }, + { + "inputs": [], + "name": "ModuleRegistry_DependencyNotYetRegistered", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "hookKey", + "type": "string" + } + ], + "name": "ModuleRegistry_HookNotRegistered", + "type": "error" + }, + { + "inputs": [], + "name": "ModuleRegistry_InvalidGateway", + "type": "error" + }, + { + "inputs": [], + "name": "ModuleRegistry_ModuleAlreadyRegistered", + "type": "error" + }, + { + "inputs": [], + "name": "ModuleRegistry_ModuleKeyMismatch", + "type": "error" + }, + { + "inputs": [], + "name": "ModuleRegistry_ModuleNotYetRegistered", + "type": "error" + }, + { + "inputs": [], + "name": "ModuleRegistry_Unauthorized", + "type": "error" + }, + { + "inputs": [], + "name": "RegistrationModule_CallerNotAuthorized", + "type": "error" + }, + { + "inputs": [], + "name": "RegistrationModule_IPAssetNonExistent", + "type": "error" + }, + { + "inputs": [], + "name": "RegistrationModule_IPOrgNotConfigured", + "type": "error" + }, + { + "inputs": [], + "name": "RegistrationModule_InvalidCaller", + "type": "error" + }, + { + "inputs": [], + "name": "RegistrationModule_InvalidConfigOperation", + "type": "error" + }, + { + "inputs": [], + "name": "RegistrationModule_InvalidExecutionOperation", + "type": "error" + }, + { + "inputs": [], + "name": "RegistrationModule_InvalidIPAssetType", + "type": "error" + }, + { + "inputs": [], + "name": "RegistrationModule_TooManyAssetTypes", + "type": "error" + }, + { + "inputs": [], + "name": "RelationshipModule_CallerNotIpOrgOwner", + "type": "error" + }, + { + "inputs": [], + "name": "RelationshipModule_CannotRelateToOtherIPOrg", + "type": "error" + }, + { + "inputs": [], + "name": "RelationshipModule_IntentAlreadyRegistered", + "type": "error" + }, + { + "inputs": [], + "name": "RelationshipModule_InvalidConfigOperation", + "type": "error" + }, + { + "inputs": [], + "name": "RelationshipModule_InvalidDstAddress", + "type": "error" + }, + { + "inputs": [], + "name": "RelationshipModule_InvalidDstId", + "type": "error" + }, + { + "inputs": [], + "name": "RelationshipModule_InvalidEndTimestamp", + "type": "error" + }, + { + "inputs": [], + "name": "RelationshipModule_InvalidRelatable", + "type": "error" + }, + { + "inputs": [], + "name": "RelationshipModule_InvalidSrcAddress", + "type": "error" + }, + { + "inputs": [], + "name": "RelationshipModule_InvalidSrcId", + "type": "error" + }, + { + "inputs": [], + "name": "RelationshipModule_InvalidTTL", + "type": "error" + }, + { + "inputs": [], + "name": "RelationshipModule_IpOrgRelatableCannotBeProtocolLevel", + "type": "error" + }, + { + "inputs": [], + "name": "RelationshipModule_NonExistingRelationship", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "relType", + "type": "string" + } + ], + "name": "RelationshipModule_RelTypeNotSet", + "type": "error" + }, + { + "inputs": [], + "name": "RelationshipModule_UnsupportedIpOrgIndexType", + "type": "error" + }, + { + "inputs": [], + "name": "RelationshipModule_UnsupportedRelationshipDst", + "type": "error" + }, + { + "inputs": [], + "name": "RelationshipModule_UnsupportedRelationshipSrc", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "accountsLength", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "allocationsLength", + "type": "uint256" + } + ], + "name": "RoyaltyNFT_AccountsAndAllocationsMismatch", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint32", + "name": "allocationsSum", + "type": "uint32" + } + ], + "name": "RoyaltyNFT_InvalidAllocationsSum", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "ownerAddress", + "type": "address" + } + ], + "name": "TokenGatedHook_NotTokenOwner", + "type": "error" + }, + { + "inputs": [], + "name": "UintArrayMask_EmptyArray", + "type": "error" + }, + { + "inputs": [], + "name": "Unauthorized", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "name", + "type": "string" + } + ], + "name": "UnsupportedInterface", + "type": "error" + }, + { + "inputs": [], + "name": "ZeroAddress", + "type": "error" + }, + { + "inputs": [], + "name": "ZeroAmount", + "type": "error" + } +] diff --git a/packages/core-sdk/src/abi/json/IPOrgController.abi.ts b/packages/core-sdk/src/abi/json/IPOrgController.abi.ts new file mode 100644 index 00000000..ce4f61b9 --- /dev/null +++ b/packages/core-sdk/src/abi/json/IPOrgController.abi.ts @@ -0,0 +1,73 @@ +export default [ + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: "address", + name: "owner", + type: "address", + }, + { + indexed: false, + internalType: "address", + name: "ipAssetOrg", + type: "address", + }, + { + indexed: false, + internalType: "string", + name: "name", + type: "string", + }, + { + indexed: false, + internalType: "string", + name: "symbol", + type: "string", + }, + { + indexed: false, + internalType: "string[]", + name: "ipAssetTypes", + type: "string[]", + }, + ], + name: "IPOrgRegistered", + type: "event", + }, + { + inputs: [ + { + internalType: "address", + name: "owner_", + type: "address", + }, + { + internalType: "string", + name: "name_", + type: "string", + }, + { + internalType: "string", + name: "symbol_", + type: "string", + }, + { + internalType: "string[]", + name: "ipAssetTypes_", + type: "string[]", + }, + ], + name: "registerIpOrg", + outputs: [ + { + internalType: "address", + name: "ipOrg_", + type: "address", + }, + ], + stateMutability: "nonpayable", + type: "function", + }, +] as const; diff --git a/packages/core-sdk/src/abi/json/LicenseRegistry.abi.ts b/packages/core-sdk/src/abi/json/LicenseRegistry.abi.ts new file mode 100644 index 00000000..c7985396 --- /dev/null +++ b/packages/core-sdk/src/abi/json/LicenseRegistry.abi.ts @@ -0,0 +1,73 @@ +export default [ + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "uint256", + name: "id", + type: "uint256", + }, + { + components: [ + { + internalType: "enum Licensing.LicenseStatus", + name: "status", + type: "uint8", + }, + { + internalType: "bool", + name: "derivativesAllowed", + type: "bool", + }, + { + internalType: "bool", + name: "isReciprocal", + type: "bool", + }, + { + internalType: "bool", + name: "derivativeNeedsApproval", + type: "bool", + }, + { + internalType: "address", + name: "revoker", + type: "address", + }, + { + internalType: "address", + name: "licensor", + type: "address", + }, + { + internalType: "address", + name: "ipOrg", + type: "address", + }, + { + internalType: "ShortString", + name: "frameworkId", + type: "bytes32", + }, + { + internalType: "uint256", + name: "ipaId", + type: "uint256", + }, + { + internalType: "uint256", + name: "parentLicenseId", + type: "uint256", + }, + ], + indexed: false, + internalType: "struct Licensing.LicenseData", + name: "licenseData", + type: "tuple", + }, + ], + name: "LicenseRegistered", + type: "event", + }, +] as const; diff --git a/packages/core-sdk/src/abi/json/RegistrationModule.abi.ts b/packages/core-sdk/src/abi/json/RegistrationModule.abi.ts new file mode 100644 index 00000000..a5fc7805 --- /dev/null +++ b/packages/core-sdk/src/abi/json/RegistrationModule.abi.ts @@ -0,0 +1,57 @@ +export default [ + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: "uint256", + name: "ipAssetId", + type: "uint256", + }, + { + indexed: true, + internalType: "address", + name: "ipOrg", + type: "address", + }, + { + indexed: false, + internalType: "uint256", + name: "ipOrgAssetId", + type: "uint256", + }, + { + indexed: true, + internalType: "address", + name: "owner", + type: "address", + }, + { + indexed: false, + internalType: "string", + name: "name", + type: "string", + }, + { + indexed: true, + internalType: "uint8", + name: "ipOrgAssetType", + type: "uint8", + }, + { + indexed: false, + internalType: "bytes32", + name: "hash", + type: "bytes32", + }, + { + indexed: false, + internalType: "string", + name: "mediaUrl", + type: "string", + }, + ], + name: "IPAssetRegistered", + type: "event", + }, +] as const; diff --git a/packages/core-sdk/src/abi/json/RelationshipModule.abi.ts b/packages/core-sdk/src/abi/json/RelationshipModule.abi.ts new file mode 100644 index 00000000..c7763ebb --- /dev/null +++ b/packages/core-sdk/src/abi/json/RelationshipModule.abi.ts @@ -0,0 +1,100 @@ +export default [ + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "uint256", + name: "relationshipId", + type: "uint256", + }, + { + indexed: false, + internalType: "string", + name: "relType", + type: "string", + }, + { + indexed: false, + internalType: "address", + name: "srcAddress", + type: "address", + }, + { + indexed: false, + internalType: "uint256", + name: "srcId", + type: "uint256", + }, + { + indexed: false, + internalType: "address", + name: "dstAddress", + type: "address", + }, + { + indexed: false, + internalType: "uint256", + name: "dstId", + type: "uint256", + }, + ], + name: "RelationshipCreated", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: "string", + name: "relType", + type: "string", + }, + { + indexed: true, + internalType: "address", + name: "ipOrg", + type: "address", + }, + { + indexed: false, + internalType: "address", + name: "src", + type: "address", + }, + { + indexed: false, + internalType: "enum LibRelationship.Relatables", + name: "srcRelatable", + type: "uint8", + }, + { + indexed: false, + internalType: "uint256", + name: "srcSubtypesMask", + type: "uint256", + }, + { + indexed: false, + internalType: "address", + name: "dst", + type: "address", + }, + { + indexed: false, + internalType: "enum LibRelationship.Relatables", + name: "dstRelatable", + type: "uint8", + }, + { + indexed: false, + internalType: "uint256", + name: "dstSubtypesMask", + type: "uint256", + }, + ], + name: "RelationshipTypeSet", + type: "event", + }, +] as const; diff --git a/packages/core-sdk/src/abi/json/StoryProtocol.abi.ts b/packages/core-sdk/src/abi/json/StoryProtocol.abi.ts new file mode 100644 index 00000000..4c2288af --- /dev/null +++ b/packages/core-sdk/src/abi/json/StoryProtocol.abi.ts @@ -0,0 +1,330 @@ +export default [ + { + inputs: [ + { + components: [ + { + internalType: "string", + name: "relType", + type: "string", + }, + { + internalType: "address", + name: "ipOrg", + type: "address", + }, + { + components: [ + { + internalType: "enum LibRelationship.Relatables", + name: "src", + type: "uint8", + }, + { + internalType: "enum LibRelationship.Relatables", + name: "dst", + type: "uint8", + }, + ], + internalType: "struct LibRelationship.RelatedElements", + name: "allowedElements", + type: "tuple", + }, + { + internalType: "uint8[]", + name: "allowedSrcs", + type: "uint8[]", + }, + { + internalType: "uint8[]", + name: "allowedDsts", + type: "uint8[]", + }, + ], + internalType: "struct LibRelationship.AddRelationshipTypeParams", + name: "params_", + type: "tuple", + }, + ], + name: "addRelationshipType", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "address", + name: "ipOrg_", + type: "address", + }, + { + components: [ + { + internalType: "string", + name: "frameworkId", + type: "string", + }, + { + components: [ + { + internalType: "ShortString", + name: "tag", + type: "bytes32", + }, + { + internalType: "bytes", + name: "value", + type: "bytes", + }, + ], + internalType: "struct Licensing.ParamValue[]", + name: "params", + type: "tuple[]", + }, + { + internalType: "enum Licensing.LicensorConfig", + name: "licensor", + type: "uint8", + }, + ], + internalType: "struct Licensing.LicensingConfig", + name: "config_", + type: "tuple", + }, + ], + name: "configureIpOrgLicensing", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "address", + name: "ipOrg_", + type: "address", + }, + { + components: [ + { + components: [ + { + internalType: "ShortString", + name: "tag", + type: "bytes32", + }, + { + internalType: "bytes", + name: "value", + type: "bytes", + }, + ], + internalType: "struct Licensing.ParamValue[]", + name: "params", + type: "tuple[]", + }, + { + internalType: "uint256", + name: "parentLicenseId", + type: "uint256", + }, + { + internalType: "uint256", + name: "ipaId", + type: "uint256", + }, + ], + internalType: "struct Licensing.LicenseCreation", + name: "params_", + type: "tuple", + }, + { + internalType: "bytes[]", + name: "preHooksData_", + type: "bytes[]", + }, + { + internalType: "bytes[]", + name: "postHooksData_", + type: "bytes[]", + }, + ], + name: "createLicense", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "address", + name: "ipOrg_", + type: "address", + }, + { + components: [ + { + internalType: "string", + name: "relType", + type: "string", + }, + { + internalType: "address", + name: "srcAddress", + type: "address", + }, + { + internalType: "uint256", + name: "srcId", + type: "uint256", + }, + { + internalType: "address", + name: "dstAddress", + type: "address", + }, + { + internalType: "uint256", + name: "dstId", + type: "uint256", + }, + ], + internalType: "struct LibRelationship.CreateRelationshipParams", + name: "params_", + type: "tuple", + }, + { + internalType: "bytes[]", + name: "preHooksData_", + type: "bytes[]", + }, + { + internalType: "bytes[]", + name: "postHooksData_", + type: "bytes[]", + }, + ], + name: "createRelationship", + outputs: [ + { + internalType: "uint256", + name: "relId", + type: "uint256", + }, + ], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "address", + name: "ipOrg_", + type: "address", + }, + { + components: [ + { + internalType: "address", + name: "owner", + type: "address", + }, + { + internalType: "uint8", + name: "ipOrgAssetType", + type: "uint8", + }, + { + internalType: "string", + name: "name", + type: "string", + }, + { + internalType: "bytes32", + name: "hash", + type: "bytes32", + }, + { + internalType: "string", + name: "mediaUrl", + type: "string", + }, + ], + internalType: "struct Registration.RegisterIPAssetParams", + name: "params_", + type: "tuple", + }, + { + internalType: "uint256", + name: "licenseId_", + type: "uint256", + }, + { + internalType: "bytes[]", + name: "preHooksData_", + type: "bytes[]", + }, + { + internalType: "bytes[]", + name: "postHooksData_", + type: "bytes[]", + }, + ], + name: "registerIPAsset", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "address", + name: "owner_", + type: "address", + }, + { + internalType: "string", + name: "name_", + type: "string", + }, + { + internalType: "string", + name: "symbol_", + type: "string", + }, + { + internalType: "string[]", + name: "ipAssetTypes_", + type: "string[]", + }, + ], + name: "registerIpOrg", + outputs: [ + { + internalType: "address", + name: "ipOrg_", + type: "address", + }, + ], + stateMutability: "nonpayable", + type: "function", + }, +] as const; diff --git a/packages/core-sdk/src/abi/licenseRegistry.abi.ts b/packages/core-sdk/src/abi/licenseRegistry.abi.ts new file mode 100644 index 00000000..75df9bf9 --- /dev/null +++ b/packages/core-sdk/src/abi/licenseRegistry.abi.ts @@ -0,0 +1,12 @@ +import { formatAbi } from "abitype"; +import { getAddress } from "viem"; + +import LicenseRegistryABI from "./json/LicenseRegistry.abi"; + +export const licenseRegistryRaw = LicenseRegistryABI; +export const licenseRegistryReadable = formatAbi(licenseRegistryRaw); + +export const licenseRegistryConfig = { + abi: licenseRegistryRaw, + address: getAddress(process.env.NEXT_PUBLIC_LICENSE_REGISTRY_CONTRACT!), +}; diff --git a/packages/core-sdk/src/abi/licensingModule.abi.ts b/packages/core-sdk/src/abi/licensingModule.abi.ts new file mode 100644 index 00000000..7e6034e1 --- /dev/null +++ b/packages/core-sdk/src/abi/licensingModule.abi.ts @@ -0,0 +1,367 @@ +export const licensingModuleRaw = [ + { + type: "constructor", + inputs: [ + { + name: "params_", + type: "tuple", + internalType: "struct BaseModule.ModuleConstruction", + components: [ + { + name: "ipaRegistry", + type: "address", + internalType: "contract IPAssetRegistry", + }, + { + name: "moduleRegistry", + type: "address", + internalType: "contract ModuleRegistry", + }, + { + name: "licenseRegistry", + type: "address", + internalType: "contract LicenseRegistry", + }, + { + name: "ipOrgController", + type: "address", + internalType: "contract IPOrgController", + }, + ], + }, + { name: "licFrameworkRepo_", type: "address", internalType: "address" }, + { name: "defaultRevoker_", type: "address", internalType: "address" }, + ], + stateMutability: "nonpayable", + }, + { + type: "function", + name: "DEFAULT_REVOKER", + inputs: [], + outputs: [{ name: "", type: "address", internalType: "address" }], + stateMutability: "view", + }, + { + type: "function", + name: "INDEX_NOT_FOUND", + inputs: [], + outputs: [{ name: "", type: "uint256", internalType: "uint256" }], + stateMutability: "view", + }, + { + type: "function", + name: "IPA_REGISTRY", + inputs: [], + outputs: [{ name: "", type: "address", internalType: "contract IPAssetRegistry" }], + stateMutability: "view", + }, + { + type: "function", + name: "IP_ORG_CONTROLLER", + inputs: [], + outputs: [{ name: "", type: "address", internalType: "contract IPOrgController" }], + stateMutability: "view", + }, + { + type: "function", + name: "LICENSE_REGISTRY", + inputs: [], + outputs: [{ name: "", type: "address", internalType: "contract LicenseRegistry" }], + stateMutability: "view", + }, + { + type: "function", + name: "LICENSING_FRAMEWORK_REPO", + inputs: [], + outputs: [{ name: "", type: "address", internalType: "contract LicensingFrameworkRepo" }], + stateMutability: "view", + }, + { + type: "function", + name: "MAX_HOOKS", + inputs: [], + outputs: [{ name: "", type: "uint256", internalType: "uint256" }], + stateMutability: "view", + }, + { + type: "function", + name: "MODULE_REGISTRY", + inputs: [], + outputs: [{ name: "", type: "address", internalType: "contract ModuleRegistry" }], + stateMutability: "view", + }, + { + type: "function", + name: "clearHooks", + inputs: [ + { name: "hookType_", type: "uint8", internalType: "enum HookRegistry.HookType" }, + { name: "ipOrg_", type: "address", internalType: "contract IIPOrg" }, + { name: "registryKey_", type: "bytes32", internalType: "bytes32" }, + ], + outputs: [], + stateMutability: "nonpayable", + }, + { + type: "function", + name: "configure", + inputs: [ + { name: "ipOrg_", type: "address", internalType: "contract IIPOrg" }, + { name: "caller_", type: "address", internalType: "address" }, + { name: "params_", type: "bytes", internalType: "bytes" }, + ], + outputs: [{ name: "", type: "bytes", internalType: "bytes" }], + stateMutability: "nonpayable", + }, + { + type: "function", + name: "execute", + inputs: [ + { name: "ipOrg_", type: "address", internalType: "contract IIPOrg" }, + { name: "caller_", type: "address", internalType: "address" }, + { name: "moduleParams_", type: "bytes", internalType: "bytes" }, + { name: "preHookParams_", type: "bytes[]", internalType: "bytes[]" }, + { name: "postHookParams_", type: "bytes[]", internalType: "bytes[]" }, + ], + outputs: [{ name: "result", type: "bytes", internalType: "bytes" }], + stateMutability: "nonpayable", + }, + { + type: "function", + name: "getIpOrgLicensorConfig", + inputs: [{ name: "ipOrg_", type: "address", internalType: "address" }], + outputs: [{ name: "", type: "uint8", internalType: "enum Licensing.LicensorConfig" }], + stateMutability: "view", + }, + { + type: "function", + name: "getIpOrgValueForParam", + inputs: [ + { name: "ipOrg_", type: "address", internalType: "address" }, + { name: "paramTag_", type: "string", internalType: "string" }, + ], + outputs: [{ name: "", type: "bytes", internalType: "bytes" }], + stateMutability: "view", + }, + { + type: "function", + name: "handleHookCallback", + inputs: [ + { name: "requestId_", type: "bytes32", internalType: "bytes32" }, + { name: "callbackData_", type: "bytes", internalType: "bytes" }, + ], + outputs: [], + stateMutability: "nonpayable", + }, + { + type: "function", + name: "hookAt", + inputs: [ + { name: "hookType_", type: "uint8", internalType: "enum HookRegistry.HookType" }, + { name: "registryKey_", type: "bytes32", internalType: "bytes32" }, + { name: "index_", type: "uint256", internalType: "uint256" }, + ], + outputs: [{ name: "", type: "address", internalType: "address" }], + stateMutability: "view", + }, + { + type: "function", + name: "hookConfigAt", + inputs: [ + { name: "hookType_", type: "uint8", internalType: "enum HookRegistry.HookType" }, + { name: "registryKey_", type: "bytes32", internalType: "bytes32" }, + { name: "index_", type: "uint256", internalType: "uint256" }, + ], + outputs: [{ name: "", type: "bytes", internalType: "bytes" }], + stateMutability: "view", + }, + { + type: "function", + name: "hookIndex", + inputs: [ + { name: "hookType_", type: "uint8", internalType: "enum HookRegistry.HookType" }, + { name: "registryKey_", type: "bytes32", internalType: "bytes32" }, + { name: "hook_", type: "address", internalType: "address" }, + ], + outputs: [{ name: "", type: "uint256", internalType: "uint256" }], + stateMutability: "view", + }, + { + type: "function", + name: "isRegistered", + inputs: [ + { name: "hookType_", type: "uint8", internalType: "enum HookRegistry.HookType" }, + { name: "registryKey_", type: "bytes32", internalType: "bytes32" }, + { name: "hook_", type: "address", internalType: "address" }, + ], + outputs: [{ name: "", type: "bool", internalType: "bool" }], + stateMutability: "view", + }, + { + type: "function", + name: "moduleKey", + inputs: [], + outputs: [{ name: "", type: "bytes32", internalType: "ModuleKey" }], + stateMutability: "pure", + }, + { + type: "function", + name: "registerHooks", + inputs: [ + { name: "hookType_", type: "uint8", internalType: "enum HookRegistry.HookType" }, + { name: "ipOrg_", type: "address", internalType: "contract IIPOrg" }, + { name: "registryKey_", type: "bytes32", internalType: "bytes32" }, + { name: "hooks_", type: "address[]", internalType: "address[]" }, + { name: "hooksConfig_", type: "bytes[]", internalType: "bytes[]" }, + ], + outputs: [], + stateMutability: "nonpayable", + }, + { + type: "function", + name: "supportsInterface", + inputs: [{ name: "interfaceId", type: "bytes4", internalType: "bytes4" }], + outputs: [{ name: "", type: "bool", internalType: "bool" }], + stateMutability: "view", + }, + { + type: "function", + name: "totalHooks", + inputs: [ + { name: "hookType_", type: "uint8", internalType: "enum HookRegistry.HookType" }, + { name: "registryKey_", type: "bytes32", internalType: "bytes32" }, + ], + outputs: [{ name: "", type: "uint256", internalType: "uint256" }], + stateMutability: "view", + }, + { + type: "function", + name: "totalHooksConfig", + inputs: [ + { name: "hookType_", type: "uint8", internalType: "enum HookRegistry.HookType" }, + { name: "registryKey_", type: "bytes32", internalType: "bytes32" }, + ], + outputs: [{ name: "", type: "uint256", internalType: "uint256" }], + stateMutability: "view", + }, + { + type: "event", + name: "HooksCleared", + inputs: [ + { + name: "hType", + type: "uint8", + indexed: true, + internalType: "enum HookRegistry.HookType", + }, + { name: "registryKey", type: "bytes32", indexed: true, internalType: "bytes32" }, + ], + anonymous: false, + }, + { + type: "event", + name: "HooksRegistered", + inputs: [ + { + name: "hType", + type: "uint8", + indexed: true, + internalType: "enum HookRegistry.HookType", + }, + { name: "registryKey", type: "bytes32", indexed: true, internalType: "bytes32" }, + { name: "hooks", type: "address[]", indexed: false, internalType: "address[]" }, + ], + anonymous: false, + }, + { + type: "event", + name: "IpOrgLicensingFrameworkSet", + inputs: [ + { name: "ipOrg", type: "address", indexed: true, internalType: "address" }, + { name: "frameworkId", type: "string", indexed: false, internalType: "string" }, + { name: "url", type: "string", indexed: false, internalType: "string" }, + { + name: "licensorConfig", + type: "uint8", + indexed: false, + internalType: "enum Licensing.LicensorConfig", + }, + { + name: "values", + type: "tuple[]", + indexed: false, + internalType: "struct Licensing.ParamValue[]", + components: [ + { name: "tag", type: "bytes32", internalType: "ShortString" }, + { name: "value", type: "bytes", internalType: "bytes" }, + ], + }, + ], + anonymous: false, + }, + { + type: "event", + name: "RequestCompleted", + inputs: [{ name: "sender", type: "address", indexed: true, internalType: "address" }], + anonymous: false, + }, + { + type: "event", + name: "RequestFailed", + inputs: [ + { name: "sender", type: "address", indexed: true, internalType: "address" }, + { name: "reason", type: "string", indexed: false, internalType: "string" }, + ], + anonymous: false, + }, + { + type: "event", + name: "RequestPending", + inputs: [{ name: "sender", type: "address", indexed: true, internalType: "address" }], + anonymous: false, + }, + { + type: "error", + name: "BaseModule_HooksParamsLengthMismatch", + inputs: [{ name: "hookType", type: "uint8", internalType: "uint8" }], + }, + { type: "error", name: "BaseModule_OnlyModuleRegistry", inputs: [] }, + { type: "error", name: "BaseModule_ZeroIpaRegistry", inputs: [] }, + { type: "error", name: "BaseModule_ZeroLicenseRegistry", inputs: [] }, + { type: "error", name: "HookRegistry_CallerNotIPOrgOwner", inputs: [] }, + { type: "error", name: "HookRegistry_HooksConfigLengthMismatch", inputs: [] }, + { + type: "error", + name: "HookRegistry_IndexOutOfBounds", + inputs: [{ name: "hooksIndex", type: "uint256", internalType: "uint256" }], + }, + { type: "error", name: "HookRegistry_MaxHooksExceeded", inputs: [] }, + { type: "error", name: "HookRegistry_RegisteringDuplicatedHook", inputs: [] }, + { + type: "error", + name: "HookRegistry_RegisteringNonWhitelistedHook", + inputs: [{ name: "hookAddress", type: "address", internalType: "address" }], + }, + { type: "error", name: "HookRegistry_RegisteringZeroAddressHook", inputs: [] }, + { type: "error", name: "HookRegistry_ZeroModuleRegistry", inputs: [] }, + { type: "error", name: "LicensingModule_CallerNotIpOrgOwner", inputs: [] }, + { type: "error", name: "LicensingModule_CallerNotLicensor", inputs: [] }, + { type: "error", name: "LicensingModule_DerivativeNotAllowed", inputs: [] }, + { type: "error", name: "LicensingModule_DuplicateParam", inputs: [] }, + { type: "error", name: "LicensingModule_InvalidAction", inputs: [] }, + { type: "error", name: "LicensingModule_InvalidConfigType", inputs: [] }, + { type: "error", name: "LicensingModule_InvalidInputValue", inputs: [] }, + { type: "error", name: "LicensingModule_InvalidLicensorConfig", inputs: [] }, + { type: "error", name: "LicensingModule_InvalidParamValue", inputs: [] }, + { type: "error", name: "LicensingModule_InvalidParamsLength", inputs: [] }, + { type: "error", name: "LicensingModule_IpOrgFrameworkAlreadySet", inputs: [] }, + { type: "error", name: "LicensingModule_IpOrgFrameworkNotSet", inputs: [] }, + { type: "error", name: "LicensingModule_ParamSetByIpOrg", inputs: [] }, + { type: "error", name: "LicensingModule_ParentLicenseNotActive", inputs: [] }, + { type: "error", name: "LicensingModule_ReciprocalCannotSetParams", inputs: [] }, + { + type: "error", + name: "StringTooLong", + inputs: [{ name: "str", type: "string", internalType: "string" }], + }, + { type: "error", name: "ZeroAddress", inputs: [] }, +] as const; diff --git a/packages/core-sdk/src/abi/registrationModule.abi.ts b/packages/core-sdk/src/abi/registrationModule.abi.ts new file mode 100644 index 00000000..d9324245 --- /dev/null +++ b/packages/core-sdk/src/abi/registrationModule.abi.ts @@ -0,0 +1,18 @@ +import { getAddress } from "viem"; +import * as dotenv from "dotenv"; + +import RegistrationModuleABI from "./json/RegistrationModule.abi"; + +if (typeof process !== "undefined") { + dotenv.config(); +} +export const registrationModuleAbi = RegistrationModuleABI; + +export const registrationModuleConfig = { + abi: registrationModuleAbi, + address: getAddress( + process.env.REGISTRATION_MODULE_CONTRACT || + process.env.NEXT_PUBLIC_REGISTRATION_MODULE_CONTRACT || + "", + ), +}; diff --git a/packages/core-sdk/src/abi/relationshipModule.abi.ts b/packages/core-sdk/src/abi/relationshipModule.abi.ts new file mode 100644 index 00000000..fabf5ac0 --- /dev/null +++ b/packages/core-sdk/src/abi/relationshipModule.abi.ts @@ -0,0 +1,14 @@ +import { getAddress } from "viem"; + +import RelationshipModuleABI from "./json/RelationshipModule.abi"; + +export const relationshipModuleAbi = RelationshipModuleABI; + +export const relationshipModuleConfig = { + abi: relationshipModuleAbi, + address: getAddress( + process.env.RELATIONSHIP_MODULE_CONTRACT || + process.env.NEXT_PUBLIC_RELATIONSHIP_MODULE_CONTRACT || + "", + ), +}; diff --git a/packages/core-sdk/src/abi/sdkEntities.json b/packages/core-sdk/src/abi/sdkEntities.json new file mode 100644 index 00000000..80e3cca4 --- /dev/null +++ b/packages/core-sdk/src/abi/sdkEntities.json @@ -0,0 +1,19 @@ +[ + "registerIPAsset", + "IPAssetRegistered", + "registerIpOrg", + "IPOrgRegistered", + "createLicense", + "createLicenseNft", + "createIpaBoundLicense", + "LicenseRegistered", + "createRelationship", + "RelationshipCreated", + "addRelationshipType", + "RelationshipTypeSet", + "configureIpOrgLicensing", + "comTermsConfig", + "nonComTermsConfig", + "TermsConfig", + "LicensorConfigEnum" +] diff --git a/packages/core-sdk/src/abi/storyProtocol.abi.ts b/packages/core-sdk/src/abi/storyProtocol.abi.ts new file mode 100644 index 00000000..0409c5f8 --- /dev/null +++ b/packages/core-sdk/src/abi/storyProtocol.abi.ts @@ -0,0 +1,22 @@ +import { getAddress, parseAbi } from "viem"; +import { formatAbi } from "abitype"; +import * as dotenv from "dotenv"; + +import StoryProtocolABI from "./json/StoryProtocol.abi"; +import errorsJson from "./json/Errors.json"; + +if (typeof process !== "undefined") { + dotenv.config(); +} + +export const storyProtocolAbi = StoryProtocolABI; +export const ErrorsAbi = errorsJson; + +const storyProtocolMerged = [...storyProtocolAbi, ...ErrorsAbi]; + +export const storyProtocolReadable = formatAbi(storyProtocolMerged); + +export const storyProtocolConfig = { + abi: parseAbi(storyProtocolReadable), + address: getAddress(process.env.NEXT_PUBLIC_STORY_PROTOCOL_CONTRACT!), +}; diff --git a/packages/core-sdk/src/client.ts b/packages/core-sdk/src/client.ts new file mode 100644 index 00000000..272fae48 --- /dev/null +++ b/packages/core-sdk/src/client.ts @@ -0,0 +1,244 @@ +import axios, { AxiosInstance } from "axios"; +import { createPublicClient, createWalletClient, http, PublicClient, WalletClient } from "viem"; +import { sepolia } from "viem/chains"; +import * as dotenv from "dotenv"; + +import { StoryConfig, StoryReadOnlyConfig } from "./types/config"; +import { IPOrgClient } from "./resources/ipOrg"; +import { IPOrgReadOnlyClient } from "./resources/ipOrgReadOnly"; +import { RelationshipReadOnlyClient } from "./resources/relationshipReadOnly"; +import { IPAssetClient } from "./resources/ipAsset"; +import { IPAssetReadOnlyClient } from "./resources/ipAssetReadOnly"; +import { LicenseReadOnlyClient } from "./resources/licenseReadOnly"; +import { TransactionClient } from "./resources/transaction"; +import { TransactionReadOnlyClient } from "./resources/transactionReadOnly"; +import { HTTP_TIMEOUT } from "./constants/http"; +import { Client, ReadOnlyClient } from "./types/client"; +import { ModuleClient } from "./resources/module"; +import { ModuleReadOnlyClient } from "./resources/moduleReadOnly"; +import { HookClient } from "./resources/hook"; +import { HookReadOnlyClient } from "./resources/hookReadOnly"; +import { PlatformClient } from "./utils/platform"; +import { LicenseClient } from "./resources/license"; +import { RelationshipClient } from "./resources/relationship"; +import { RelationshipTypeClient } from "./resources/relationshipType"; +import { RelationshipTypeReadOnlyClient } from "./resources/relationshipTypeReadOnly"; + +if (typeof process !== "undefined") { + dotenv.config(); +} +/** + * The StoryClient is the main entry point for the SDK. + */ +export class StoryClient { + private readonly config: StoryConfig | StoryReadOnlyConfig; + private readonly httpClient: AxiosInstance; + private readonly isReadOnly: boolean = false; + private readonly rpcClient: PublicClient; + private readonly wallet?: WalletClient; + + private _ipOrg: IPOrgClient | IPOrgReadOnlyClient | null = null; + private _license: LicenseReadOnlyClient | null = null; + private _transaction: TransactionClient | TransactionReadOnlyClient | null = null; + private _ipAsset: IPAssetClient | IPAssetReadOnlyClient | null = null; + private _relationship: RelationshipReadOnlyClient | null = null; + private _relationshipType: RelationshipTypeReadOnlyClient | null = null; + private _module: ModuleClient | ModuleReadOnlyClient | null = null; + private _hook: HookClient | HookReadOnlyClient | null = null; + private _platform: PlatformClient | null = null; + + /** + * @param config - the configuration for the SDK client + * @param isReadOnly + */ + private constructor(config: StoryConfig | StoryReadOnlyConfig, isReadOnly: boolean = false) { + this.config = config; + this.isReadOnly = isReadOnly; + + const clientConfig = { + chain: this.config.chain || sepolia, + transport: this.config.transport || http(process.env.RPC_PROVIDER_URL), + }; + + this.rpcClient = createPublicClient(clientConfig); + + if (!isReadOnly) { + const account = (this.config as StoryConfig).account; + if (!account) { + throw new Error("account is null"); + } + + this.wallet = createWalletClient({ + ...clientConfig, + account: account, + }); + } + + this.httpClient = axios.create({ + baseURL: process.env.API_BASE_URL || process.env.NEXT_PUBLIC_API_BASE_URL, + timeout: HTTP_TIMEOUT, + headers: { + version: "v0-alpha", + }, + }); + } + + /** + * Factory method for creating a read only SDK client. + * + * @param config - the configuration for a read only SDK client + */ + static newReadOnlyClient(config: StoryReadOnlyConfig): ReadOnlyClient { + return new StoryClient(config, true) as ReadOnlyClient; + } + + /** + * Factory method for creating a SDK client with a signer. + * + * @param config - the configuration for a new read/write SDK client + */ + static newClient(config: StoryConfig): Client { + return new StoryClient(config, false) as Client; + } + + /** + * Getter for the ipOrg client. The client is lazily created when + * this method is called. + * + * @returns the IPOrgClient or IPOrgReadOnlyClient instance + */ + public get ipOrg(): IPOrgClient | IPOrgReadOnlyClient { + if (this._ipOrg === null) { + this._ipOrg = this.isReadOnly + ? new IPOrgReadOnlyClient(this.httpClient, this.rpcClient) + : new IPOrgClient(this.httpClient, this.rpcClient, this.wallet!); + } + + return this._ipOrg; + } + + /** + * Getter for the relationship client. The client is lazily created when + * this method is called. + * + * @returns the RelationshipReadOnlyClient or RelationshipClient instance + */ + public get relationship(): RelationshipClient | RelationshipReadOnlyClient { + if (this._relationship === null) { + this._relationship = this.isReadOnly + ? new RelationshipReadOnlyClient(this.httpClient, this.rpcClient) + : new RelationshipClient(this.httpClient, this.rpcClient, this.wallet!); + } + + return this._relationship; + } + + /** + * Getter for the relationship type client. The client is lazily created when + * this method is called. + * + * @returns the RelationshipTypeReadOnlyClient or RelationshipTypeClient instance + */ + public get relationshipType(): RelationshipTypeClient | RelationshipTypeReadOnlyClient { + if (this._relationshipType === null) { + this._relationshipType = this.isReadOnly + ? new RelationshipTypeReadOnlyClient(this.httpClient, this.rpcClient) + : new RelationshipTypeClient(this.httpClient, this.rpcClient, this.wallet!); + } + + return this._relationshipType; + } + + /** + * Getter for the IP Asset client. The client is lazily created when + * this method is called. + * + * @returns the IPAssetReadOnlyClient or IpAssetClient instance + */ + public get ipAsset(): IPAssetClient | IPAssetReadOnlyClient { + if (this._ipAsset === null) { + this._ipAsset = this.isReadOnly + ? new IPAssetReadOnlyClient(this.httpClient, this.rpcClient) + : new IPAssetClient(this.httpClient, this.rpcClient, this.wallet!); + } + return this._ipAsset; + } + + /** + * Getter for the license client. The client is lazily created when + * this method is called. + * + * @returns the LicenseReadOnlyClient or LicenseClient instance + */ + public get license(): LicenseClient | LicenseReadOnlyClient { + if (this._license === null) { + this._license = this.isReadOnly + ? new LicenseReadOnlyClient(this.httpClient, this.rpcClient) + : new LicenseClient(this.httpClient, this.rpcClient, this.wallet!); + } + + return this._license; + } + + /** + * Getter for the transaction client. The client is lazily created when + * this method is called. + * + * @returns the TransactionReadOnlyClient or TransactionClient instance + */ + public get transaction(): TransactionClient | TransactionReadOnlyClient { + if (this._transaction === null) { + this._transaction = this.isReadOnly + ? new TransactionReadOnlyClient(this.httpClient, this.rpcClient) + : new TransactionClient(this.httpClient, this.rpcClient, this.wallet!); + } + + return this._transaction; + } + + /** + * Getter for the module client. The client is lazily created when + * this method is called. + * + * @returns the ModuleReadOnlyClient or ModuleClient instance + */ + public get module(): ModuleClient | ModuleReadOnlyClient { + if (this._module === null) { + this._module = this.isReadOnly + ? new ModuleReadOnlyClient(this.httpClient, this.rpcClient) + : new ModuleClient(this.httpClient, this.rpcClient, this.wallet!); + } + + return this._module; + } + + /** + * Getter for the hook client. The client is lazily created when + * this method is called. + * + * @returns the HookReadOnlyClient or HookClient instance + */ + public get hook(): HookClient | HookReadOnlyClient { + if (this._hook === null) { + this._hook = this.isReadOnly + ? new HookReadOnlyClient(this.httpClient, this.rpcClient) + : new HookClient(this.httpClient, this.rpcClient, this.wallet!); + } + + return this._hook; + } + + /** + * Getter for the platform client. The client is lazily created when + * this method is called. + * + * @returns the PlatformClient instance + */ + public get platform(): PlatformClient { + if (this._platform === null) { + this._platform = new PlatformClient(this.httpClient); + } + + return this._platform; + } +} diff --git a/packages/core-sdk/src/constants/common.ts b/packages/core-sdk/src/constants/common.ts new file mode 100644 index 00000000..84fa62c8 --- /dev/null +++ b/packages/core-sdk/src/constants/common.ts @@ -0,0 +1,3 @@ +export const AddressZero = "0x0000000000000000000000000000000000000000"; + +export const HashZero = "0x0000000000000000000000000000000000000000000000000000000000000000"; diff --git a/packages/core-sdk/src/constants/http.ts b/packages/core-sdk/src/constants/http.ts new file mode 100644 index 00000000..cb348fe6 --- /dev/null +++ b/packages/core-sdk/src/constants/http.ts @@ -0,0 +1,4 @@ +/** + * Default timeout value for http clients. + */ +export const HTTP_TIMEOUT = 5000; diff --git a/packages/core-sdk/src/constants/license.ts b/packages/core-sdk/src/constants/license.ts new file mode 100644 index 00000000..6e4e4b7b --- /dev/null +++ b/packages/core-sdk/src/constants/license.ts @@ -0,0 +1,12 @@ +export const PARAMS_TAG = { + CHANNELS_OF_DISTRIBUTION: "Channels-Of-Distribution", + ATTRIBUTION: "Attribution", + DERIVATIVES_ALLOWED: "Derivatives-Allowed", + DERIVATIVES_ALLOWED_OPTIONS: "Derivatives-Allowed-Options", +}; + +export const DERIVATIVES_ALLOWED_OPTIONS = [ + "Allowed-With-Approval", + "Allowed-Reciprocal-License", + "Allowed-With-Attribution", +]; diff --git a/packages/core-sdk/src/enums/ActionType.ts b/packages/core-sdk/src/enums/ActionType.ts new file mode 100644 index 00000000..e808a9e2 --- /dev/null +++ b/packages/core-sdk/src/enums/ActionType.ts @@ -0,0 +1,10 @@ +/** + * @public + */ +export enum ActionType { + Unspecified = "Unspecified", + Register = "Register", + Unregister = "Unregister", + Configure = "Configure", + Create = "Create", +} diff --git a/packages/core-sdk/src/enums/HookType.ts b/packages/core-sdk/src/enums/HookType.ts new file mode 100644 index 00000000..8d6989b3 --- /dev/null +++ b/packages/core-sdk/src/enums/HookType.ts @@ -0,0 +1,7 @@ +/** + * @public + */ +export enum HookType { + PreAction = 0, + PostAction = 1, +} diff --git a/packages/core-sdk/src/enums/Relatables.ts b/packages/core-sdk/src/enums/Relatables.ts new file mode 100644 index 00000000..d94ba9ee --- /dev/null +++ b/packages/core-sdk/src/enums/Relatables.ts @@ -0,0 +1,11 @@ +/** + * @public + */ +export enum Relatables { + Undefined = 0, + IPA = 1, + IPOrgEntry = 2, + License = 3, + Address = 4, + ExternalNFT = 5, +} diff --git a/packages/core-sdk/src/enums/ResourceType.ts b/packages/core-sdk/src/enums/ResourceType.ts new file mode 100644 index 00000000..57fc4a8d --- /dev/null +++ b/packages/core-sdk/src/enums/ResourceType.ts @@ -0,0 +1,14 @@ +/** + * @public + */ +export enum ResourceType { + Unspecified = "Unspecified", + IPOrg = "IPOrg", + IPAsset = "IPAsset", + License = "License", + Relationship = "Relationship", + RelationshipType = "RelationshipType", + Module = "Module", + Hook = "Hook", + Dispute = "Dispute", +} diff --git a/packages/core-sdk/src/index.ts b/packages/core-sdk/src/index.ts new file mode 100644 index 00000000..bedf17da --- /dev/null +++ b/packages/core-sdk/src/index.ts @@ -0,0 +1,102 @@ +export { StoryClient } from "./client"; +export { ResourceType } from "./enums/ResourceType"; +export { HookType } from "./enums/HookType"; +export { ActionType } from "./enums/ActionType"; +export { Relatables } from "./enums/Relatables"; +export { HookReadOnlyClient } from "./resources/hookReadOnly"; +export { IPAssetClient } from "./resources/ipAsset"; +export { IPAssetReadOnlyClient } from "./resources/ipAssetReadOnly"; +export { IPOrgClient } from "./resources/ipOrg"; +export { IPOrgReadOnlyClient } from "./resources/ipOrgReadOnly"; +export { LicenseClient } from "./resources/license"; +export { LicenseReadOnlyClient } from "./resources/licenseReadOnly"; +export { ModuleReadOnlyClient } from "./resources/moduleReadOnly"; +export { RelationshipClient } from "./resources/relationship"; +export { TransactionClient } from "./resources/transaction"; +export { PlatformClient } from "./utils/platform"; +export { AddressZero, HashZero } from "./constants/common"; + +export type { StoryConfig, StoryReadOnlyConfig } from "./types/config"; +export type { Client, ReadOnlyClient } from "./types/client"; +export type { Hex, TypedData } from "./types/common"; + +export type { + IPOrg, + GetIPOrgRequest, + GetIPOrgResponse, + CreateIPOrgRequest, + CreateIPOrgResponse, + ListIPOrgRequest, + ListIPOrgResponse, +} from "./types/resources/ipOrg"; + +export type { + IPAsset, + IPAssetType, + GetIpAssetRequest, + GetIpAssetResponse, + CreateIpAssetRequest, + CreateIpAssetResponse, + ListIpAssetRequest, + ListIpAssetResponse, +} from "./types/resources/ipAsset"; + +export type { + License, + GetLicenseRequest, + GetLicenseResponse, + CreateLicenseRequest, + CreateLicenseResponse, + ConfigureLicenseRequest, + ConfigureLicenseResponse, + ListLicenseRequest, + ListLicenseResponse, + LicensingConfig, + ParamValues, +} from "./types/resources/license"; + +export { LicensorConfigEnum } from "./types/resources/license"; + +export type { + Relationship, + RegisterRelationshipRequest, + RegisterRelationshipResponse, + ListRelationshipRequest, + ListRelationshipResponse, + GetRelationshipRequest, + GetRelationshipResponse, +} from "./types/resources/relationship"; + +export type { + RelationshipType, + GetRelationshipTypeRequest, + GetRelationshipTypeResponse, + ListRelationshipTypesRequest, + ListRelationshipTypesResponse, + RegisterRelationshipTypeRequest, + RegisterRelationshipTypeResponse, +} from "./types/resources/relationshipType"; + +export type { + Transaction, + GetTransactionRequest, + GetTransactionResponse, + ListTransactionRequest, + ListTransactionResponse, +} from "./types/resources/transaction"; + +export type { + Module, + GetModuleRequest, + GetModuleResponse, + ListModuleRequest, + ListModuleResponse, +} from "./types/resources/module"; + +export type { + Hook, + GetHookRequest, + GetHookResponse, + ListHookRequest, + ListHookResponse, +} from "./types/resources/hook"; diff --git a/packages/core-sdk/src/resources/hook.ts b/packages/core-sdk/src/resources/hook.ts new file mode 100644 index 00000000..75f10fda --- /dev/null +++ b/packages/core-sdk/src/resources/hook.ts @@ -0,0 +1,16 @@ +import { AxiosInstance } from "axios"; +import { PublicClient, WalletClient } from "viem"; + +import { HookReadOnlyClient } from "./hookReadOnly"; + +/** + * HookClient allows you to view and search hooks on Story Protocol. + */ +export class HookClient extends HookReadOnlyClient { + private readonly wallet: WalletClient; + + constructor(httpClient: AxiosInstance, rpcClient: PublicClient, wallet: WalletClient) { + super(httpClient, rpcClient); + this.wallet = wallet; + } +} diff --git a/packages/core-sdk/src/resources/hookReadOnly.ts b/packages/core-sdk/src/resources/hookReadOnly.ts new file mode 100644 index 00000000..8d9d36cc --- /dev/null +++ b/packages/core-sdk/src/resources/hookReadOnly.ts @@ -0,0 +1,57 @@ +import { AxiosInstance } from "axios"; +import { PublicClient } from "viem"; + +import { handleError } from "../utils/errors"; +import { + GetHookRequest, + GetHookResponse, + ListHookRequest, + ListHookResponse, +} from "../types/resources/hook"; + +/** + * HookReadOnlyClient allows you to get and search hooks on Story Protocol. + */ +export class HookReadOnlyClient { + protected readonly httpClient: AxiosInstance; + protected readonly rpcClient: PublicClient; + + constructor(httpClient: AxiosInstance, rpcClient: PublicClient) { + this.httpClient = httpClient; + this.rpcClient = rpcClient; + } + + /** + * Get hook data based on the specified hook id. + * + * @param request - the request object for getting the hook + * @returns the response object that contains the fetched hook object + */ + public async get(request: GetHookRequest): Promise { + try { + const response = await this.httpClient.get(`/protocol/hook/${request.hookId}`); + return response.data as GetHookResponse; + } catch (error: unknown) { + handleError(error, "Failed to get hook"); + } + } + + /** + * Get hook data based on the specified hook id. + * + * @param request - the request object for getting the hooks + * @returns the response object that contains the fetched hook object + */ + public async list(request?: ListHookRequest): Promise { + try { + const response = await this.httpClient.post(`/protocol/hook`, request || {}, { + params: { + moduleId: request?.moduleId, + }, + }); + return response.data as ListHookResponse; + } catch (error: unknown) { + handleError(error, `Failed to get hooks`); + } + } +} diff --git a/packages/core-sdk/src/resources/ipAsset.ts b/packages/core-sdk/src/resources/ipAsset.ts new file mode 100644 index 00000000..d0b6198f --- /dev/null +++ b/packages/core-sdk/src/resources/ipAsset.ts @@ -0,0 +1,64 @@ +import { AxiosInstance } from "axios"; +import { getAddress, PublicClient, WalletClient } from "viem"; + +import { CreateIpAssetRequest, CreateIpAssetResponse } from "../types/resources/ipAsset"; +import { handleError } from "../utils/errors"; +import { IPAssetReadOnlyClient } from "./ipAssetReadOnly"; +import { storyProtocolConfig } from "../abi/storyProtocol.abi"; +import { registrationModuleConfig } from "../abi/registrationModule.abi"; +import { parseToBigInt, waitTxAndFilterLog, typedDataArrayToBytesArray } from "../utils/utils"; +import { HashZero } from "../constants/common"; + +/** + * IpAssetClient allows you to create, view, and search IP Assets on Story Protocol. + */ +export class IPAssetClient extends IPAssetReadOnlyClient { + private readonly wallet: WalletClient; + + constructor(httpClient: AxiosInstance, rpcClient: PublicClient, wallet: WalletClient) { + super(httpClient, rpcClient); + this.wallet = wallet; + } + + /** + * Create an IP Asset on Story Protocol based on the specified input asset data. + * + * @param request - the request object that contains all data needed to create an IP Asset. + * @returns the response object that contains results from the asset creation. + */ + public async create(request: CreateIpAssetRequest): Promise { + try { + const { request: call } = await this.rpcClient.simulateContract({ + ...storyProtocolConfig, + functionName: "registerIPAsset", + args: [ + getAddress(request.ipOrgId), + { + owner: getAddress(request.owner || this.wallet.account!.address), + name: request.name, + ipOrgAssetType: parseToBigInt(request.typeIndex), + hash: request.contentHash || HashZero, + mediaUrl: request.mediaUrl || "", + }, + request.licenseId || 0, + request.preHookData ? typedDataArrayToBytesArray(request.preHookData) : [], + request.postHookData ? typedDataArrayToBytesArray(request.postHookData) : [], + ], + account: this.wallet.account, + }); + + const txHash = await this.wallet.writeContract(call); + if (request.txOptions?.waitForTransaction) { + const targetLog = await waitTxAndFilterLog(this.rpcClient, txHash, { + ...registrationModuleConfig, + eventName: "IPAssetRegistered", + }); + return { txHash: txHash, ipAssetId: targetLog?.args.ipAssetId.toString() }; + } else { + return { txHash: txHash }; + } + } catch (error) { + handleError(error, "Failed to create IP Asset"); + } + } +} diff --git a/packages/core-sdk/src/resources/ipAssetReadOnly.ts b/packages/core-sdk/src/resources/ipAssetReadOnly.ts new file mode 100644 index 00000000..79fccc45 --- /dev/null +++ b/packages/core-sdk/src/resources/ipAssetReadOnly.ts @@ -0,0 +1,57 @@ +import { AxiosInstance } from "axios"; +import { PublicClient } from "viem"; + +import { + GetIpAssetRequest, + GetIpAssetResponse, + ListIpAssetRequest, + ListIpAssetResponse, +} from "../types/resources/ipAsset"; +import { handleError } from "../utils/errors"; +import { isIntegerString } from "../utils/utils"; + +/** + * IPAssetReadOnlyClient allows you to view and search IP Assets on Story Protocol. + */ +export class IPAssetReadOnlyClient { + protected readonly httpClient: AxiosInstance; + protected readonly rpcClient: PublicClient; + + constructor(httpClient: AxiosInstance, rpcClient: PublicClient) { + this.httpClient = httpClient; + this.rpcClient = rpcClient; + } + + /** + * Get an IP Asset based on the specified IP asset ID. + * + * @param request - the request object for getting an IP Asset. + * @returns the response object the contains the fetched IP Asset. + */ + public async get(request: GetIpAssetRequest): Promise { + try { + if (!isIntegerString(request.ipAssetId)) { + throw new Error(`Invalid IP Asset id. Must be an integer. But get: ${request.ipAssetId}`); + } + + const response = await this.httpClient.get(`/protocol/ipasset/${request.ipAssetId}`); + return response.data as GetIpAssetResponse; + } catch (error: unknown) { + handleError(error, "Failed to get IP Asset"); + } + } + + /** + * List IP assets. + * + * @returns the response object that contains results from listing query. + */ + public async list(request?: ListIpAssetRequest): Promise { + try { + const response = await this.httpClient.post(`/protocol/ipasset`, request || {}); + return response.data as ListIpAssetResponse; + } catch (error) { + handleError(error, "Failed to list IP Asset."); + } + } +} diff --git a/packages/core-sdk/src/resources/ipOrg.ts b/packages/core-sdk/src/resources/ipOrg.ts new file mode 100644 index 00000000..5e63c20c --- /dev/null +++ b/packages/core-sdk/src/resources/ipOrg.ts @@ -0,0 +1,56 @@ +import { AxiosInstance } from "axios"; +import { getAddress, PublicClient, WalletClient } from "viem"; + +import { CreateIPOrgRequest, CreateIPOrgResponse } from "../types/resources/ipOrg"; +import { handleError } from "../utils/errors"; +import { IPOrgReadOnlyClient } from "./ipOrgReadOnly"; +import { storyProtocolConfig } from "../abi/storyProtocol.abi"; +import { ipOrgControllerConfig } from "../abi/ipOrgController.abi"; +import { waitTxAndFilterLog } from "../utils/utils"; + +/** + * IPOrgClient allows you to create, view, search IPOrgs on Story Protocol. + */ +export class IPOrgClient extends IPOrgReadOnlyClient { + private readonly wallet: WalletClient; + + constructor(httpClient: AxiosInstance, rpcClient: PublicClient, wallet: WalletClient) { + super(httpClient, rpcClient); + this.wallet = wallet; + } + + /** + * Create a IPOrg on Story Protocol based on the specified input IPOrg data. + * + * @param request - the request object that contains all data needed to create a IPOrg + * @returns the response object that contains results from the create IPOrg action + */ + public async create(request: CreateIPOrgRequest): Promise { + try { + const { request: call } = await this.rpcClient.simulateContract({ + ...storyProtocolConfig, + functionName: "registerIpOrg", + args: [ + getAddress(request.owner || this.wallet.account!.address), + request.name, + request.symbol, + request.ipAssetTypes, + ], + account: this.wallet.account, + }); + + const txHash = await this.wallet.writeContract(call); + if (request.txOptions?.waitForTransaction) { + const targetLog = await waitTxAndFilterLog(this.rpcClient, txHash, { + ...ipOrgControllerConfig, + eventName: "IPOrgRegistered", + }); + return { txHash: txHash, ipOrgId: targetLog?.args.ipAssetOrg }; + } else { + return { txHash: txHash }; + } + } catch (error: unknown) { + handleError(error, "Failed to create IPOrg"); + } + } +} diff --git a/packages/core-sdk/src/resources/ipOrgReadOnly.ts b/packages/core-sdk/src/resources/ipOrgReadOnly.ts new file mode 100644 index 00000000..5b80e8d9 --- /dev/null +++ b/packages/core-sdk/src/resources/ipOrgReadOnly.ts @@ -0,0 +1,55 @@ +import { AxiosInstance } from "axios"; +import { isAddress, PublicClient } from "viem"; + +import { + GetIPOrgRequest, + GetIPOrgResponse, + ListIPOrgRequest, + ListIPOrgResponse, +} from "../types/resources/ipOrg"; +import { handleError } from "../utils/errors"; + +/** + * IPOrgReadOnlyClient allows you to view and search IPOrgs on Story Protocol. + */ +export class IPOrgReadOnlyClient { + protected readonly httpClient: AxiosInstance; + protected readonly rpcClient: PublicClient; + + constructor(httpClient: AxiosInstance, rpcClient: PublicClient) { + this.httpClient = httpClient; + this.rpcClient = rpcClient; + } + + /** + * Get a IPOrg data based on the specified IPOrg id. + * + * @param request - the request object for getting the IPOrg + * @returns the response object that contains the fetched IPOrg object + */ + public async get(request: GetIPOrgRequest): Promise { + try { + if (!isAddress(request.ipOrgId)) { + throw new Error(`Invalid IPOrg id. Must be an address. But got: ${request.ipOrgId}`); + } + + const response = await this.httpClient.get(`/protocol/iporg/${request.ipOrgId}`); + return response.data as GetIPOrgResponse; + } catch (error: unknown) { + handleError(error, "Failed to get IPOrg"); + } + } + /** + * List IPOrgs. + * + * @returns the response object that contains a list of IPOrgs + */ + public async list(request?: ListIPOrgRequest): Promise { + try { + const response = await this.httpClient.post("/protocol/iporg", request || {}); + return response.data as ListIPOrgResponse; + } catch (error: unknown) { + handleError(error, "Failed to list IPOrgs."); + } + } +} diff --git a/packages/core-sdk/src/resources/license.ts b/packages/core-sdk/src/resources/license.ts new file mode 100644 index 00000000..f652c525 --- /dev/null +++ b/packages/core-sdk/src/resources/license.ts @@ -0,0 +1,128 @@ +import { Address, PublicClient, WalletClient, getAddress, Hex } from "viem"; +import { AxiosInstance } from "axios"; + +import storyProtocolJson from "../abi/json/StoryProtocol.abi"; +import { storyProtocolConfig } from "../abi/storyProtocol.abi"; +import { handleError } from "../utils/errors"; +import { typedDataToBytes, waitTxAndFilterLog } from "../utils/utils"; +import { LicenseReadOnlyClient } from "./licenseReadOnly"; +import { + ConfigureLicenseRequest, + ConfigureLicenseResponse, + CreateLicenseRequest, + CreateLicenseResponse, +} from "../types/resources/license"; +import { TypedData } from "../types/common"; + +/** + * Client for managing relationships. + */ +export class LicenseClient extends LicenseReadOnlyClient { + private readonly wallet: WalletClient; + + constructor(httpClient: AxiosInstance, rpcClient: PublicClient, wallet: WalletClient) { + super(httpClient, rpcClient); + this.wallet = wallet; + } + + public async create(request: CreateLicenseRequest): Promise { + const parsedParams = this.parseParamValues(request.params); + + const createLicenseParams = { + params: parsedParams, + parentLicenseId: request.parentLicenseId, + ipaId: request.ipaId, + }; + + const args = [request.ipOrgId, createLicenseParams, request.preHookData, request.postHookData]; + + try { + const { request: call } = await this.rpcClient.simulateContract({ + ...storyProtocolConfig, + functionName: "createLicense", + args, + account: this.wallet.account, + }); + const txHash = await this.wallet.writeContract(call); + if (request.txOptions?.waitForTransaction) { + const targetLog = await waitTxAndFilterLog(this.rpcClient, txHash, { + abi: [ + { + type: "event", + name: "LicenseRegistered", + inputs: [ + { name: "id", type: "uint256", indexed: true, internalType: "uint256" }, + { + name: "licenseData", + type: "tuple", + indexed: false, + internalType: "struct Licensing.LicenseData", + components: [ + { name: "status", type: "uint8", internalType: "enum Licensing.LicenseStatus" }, + { name: "derivativesAllowed", type: "bool", internalType: "bool" }, + { name: "isReciprocal", type: "bool", internalType: "bool" }, + { name: "derivativeNeedsApproval", type: "bool", internalType: "bool" }, + { name: "revoker", type: "address", internalType: "address" }, + { name: "licensor", type: "address", internalType: "address" }, + { name: "ipOrg", type: "address", internalType: "address" }, + { name: "frameworkId", type: "bytes32", internalType: "ShortString" }, + { name: "ipaId", type: "uint256", internalType: "uint256" }, + { name: "parentLicenseId", type: "uint256", internalType: "uint256" }, + ], + }, + ], + anonymous: false, + }, + ], + eventName: "LicenseRegistered", + confirmations: request.txOptions?.numBlockConfirmations, + }); + return { txHash: txHash, licenseId: targetLog?.args.id.toString() }; + } else { + return { txHash: txHash }; + } + } catch (error: unknown) { + handleError(error, `Failed to register license`); + } + } + + public async configure(request: ConfigureLicenseRequest): Promise { + const parsedParams = this.parseParamValues(request.params); + const config = { + frameworkId: request.frameworkId, + params: parsedParams, + licensor: request.licensor, + }; + + try { + const { request: call } = await this.rpcClient.simulateContract({ + // ...storyProtocolConfig, + abi: storyProtocolJson, + address: getAddress(process.env.NEXT_PUBLIC_STORY_PROTOCOL_CONTRACT!), + functionName: "configureIpOrgLicensing", + args: [request.ipOrg as Address, config], + account: this.wallet.account, + }); + const txHash = await this.wallet.writeContract(call); + + if (request.txOptions?.waitForTransaction) { + await this.rpcClient.waitForTransactionReceipt({ hash: txHash }); + return { txHash: txHash, success: true }; + } else { + return { txHash: txHash }; + } + } catch (error: unknown) { + handleError(error, "Failed to configure license"); + } + } + + private parseParamValues(params: { tag: Hex; value: TypedData }[]) { + return params.map((param: { tag: Hex; value: TypedData }) => { + return { + ...param, + tag: param.tag, + value: typedDataToBytes(param.value), + }; + }); + } +} diff --git a/packages/core-sdk/src/resources/licenseReadOnly.ts b/packages/core-sdk/src/resources/licenseReadOnly.ts new file mode 100644 index 00000000..7a36d067 --- /dev/null +++ b/packages/core-sdk/src/resources/licenseReadOnly.ts @@ -0,0 +1,102 @@ +import { AxiosInstance, AxiosResponse } from "axios"; +import { PublicClient } from "viem"; + +import { + GetLicenseRequest, + GetLicenseResponse, + LicenseParams, + ListLicenseParamsRequest, + ListLicenseParamsResponse, + ListLicenseRequest, + ListLicenseResponse, +} from "../types/resources/license"; +import { handleError } from "../utils/errors"; +import { isIntegerString, paramsTagValueDecoder } from "../utils/utils"; + +/** + * LicenseReadOnlyClient allows you to view and search relationships on Story Protocol. + */ +export class LicenseReadOnlyClient { + protected readonly httpClient: AxiosInstance; + protected readonly rpcClient: PublicClient; + + constructor(httpClient: AxiosInstance, rpcClient: PublicClient) { + this.httpClient = httpClient; + this.rpcClient = rpcClient; + } + + /** + * Get a license's data based on the specified license id. + * + * @param request - the request object for getting the license + * @returns the response object that contains the fetched license object + */ + public async get(request: GetLicenseRequest): Promise { + try { + if (!isIntegerString(request.licenseId)) { + throw new Error(`Invalid licenseId. Must be an integer. But got: ${request.licenseId}`); + } + + const response: AxiosResponse = await this.httpClient.get( + `/protocol/license/${request.licenseId}`, + ); + + return response.data as GetLicenseResponse; + } catch (error: unknown) { + handleError(error, `Failed to get license`); + } + } + + /** + * List licenses. + * + * @returns the response object that contains a list of licenses + */ + public async list(request?: ListLicenseRequest): Promise { + try { + const response = await this.httpClient.post("/protocol/license", request || {}, { + params: { + ipOrgId: request?.ipOrgId, + ipAssetId: request?.ipAssetId, + options: request?.options, + }, + }); + + return response.data as ListLicenseResponse; + } catch (error: unknown) { + handleError(error, `Failed to get licenses`); + } + } + + /** + * List licenses. + * + * @returns the response object that contains a list of licenses + */ + public async listParams(request: ListLicenseParamsRequest): Promise { + try { + const response: AxiosResponse<{ licenseParams: LicenseParams[] }> = + await this.httpClient.post("/protocol/license-params", request, { + params: { + ipOrgId: request.ipOrgId, + options: request?.options, + }, + }); + + const formattedRes = { + licenseParams: [ + { + ...response.data.licenseParams?.[0], + params: response.data.licenseParams?.[0].params.map(({ tag, value }) => + paramsTagValueDecoder(tag, value), + ), + }, + ], + }; + + return formattedRes; + } catch (error: unknown) { + handleError(error, `Failed to get license params`); + } + } +} diff --git a/packages/core-sdk/src/resources/module.ts b/packages/core-sdk/src/resources/module.ts new file mode 100644 index 00000000..8fe6b125 --- /dev/null +++ b/packages/core-sdk/src/resources/module.ts @@ -0,0 +1,16 @@ +import { AxiosInstance } from "axios"; +import { PublicClient, WalletClient } from "viem"; + +import { ModuleReadOnlyClient } from "./moduleReadOnly"; + +/** + * ModuleClient allows you to view and search modules on Story Protocol. + */ +export class ModuleClient extends ModuleReadOnlyClient { + private readonly wallet: WalletClient; + + constructor(httpClient: AxiosInstance, rpcClient: PublicClient, wallet: WalletClient) { + super(httpClient, rpcClient); + this.wallet = wallet; + } +} diff --git a/packages/core-sdk/src/resources/moduleReadOnly.ts b/packages/core-sdk/src/resources/moduleReadOnly.ts new file mode 100644 index 00000000..20efec41 --- /dev/null +++ b/packages/core-sdk/src/resources/moduleReadOnly.ts @@ -0,0 +1,56 @@ +import { AxiosInstance } from "axios"; +import { PublicClient } from "viem"; + +import { handleError } from "../utils/errors"; +import { + GetModuleRequest, + GetModuleResponse, + ListModuleRequest, + ListModuleResponse, +} from "../types/resources/module"; + +/** + * ModuleReadOnlyClient allows you to view and search modules on Story Protocol. + */ +export class ModuleReadOnlyClient { + protected readonly httpClient: AxiosInstance; + protected readonly rpcClient: PublicClient; + + constructor(httpClient: AxiosInstance, rpcClient: PublicClient) { + this.httpClient = httpClient; + this.rpcClient = rpcClient; + } + + /** + * Get module data based on the specified module id. + * + * @param request - the request object for getting the module + * @returns the response object that contains the fetched module object + */ + public async get(request: GetModuleRequest): Promise { + try { + const response = await this.httpClient.get(`/protocol/module/${request.moduleId}`); + return response.data as GetModuleResponse; + } catch (error: unknown) { + handleError(error, "Failed to get module"); + } + } + + /** + * List Modules. + * + * @returns the response object that contains a list of modules + */ + public async list(request?: ListModuleRequest): Promise { + try { + const response = await this.httpClient.post(`/protocol/module`, request || {}, { + params: { + ipOrgId: request?.ipOrgId, + }, + }); + return response.data as ListModuleResponse; + } catch (error: unknown) { + handleError(error, `Failed to list modules`); + } + } +} diff --git a/packages/core-sdk/src/resources/relationship.ts b/packages/core-sdk/src/resources/relationship.ts new file mode 100644 index 00000000..24bc7328 --- /dev/null +++ b/packages/core-sdk/src/resources/relationship.ts @@ -0,0 +1,68 @@ +import { getAddress, PublicClient, WalletClient } from "viem"; +import { AxiosInstance } from "axios"; + +import { + RegisterRelationshipRequest, + RegisterRelationshipResponse, +} from "../types/resources/relationship"; +import { handleError } from "../utils/errors"; +import { RelationshipReadOnlyClient } from "./relationshipReadOnly"; +import { storyProtocolConfig } from "../abi/storyProtocol.abi"; +import { relationshipModuleConfig } from "../abi/relationshipModule.abi"; +import { waitTxAndFilterLog, typedDataArrayToBytesArray } from "../utils/utils"; + +/** + * RelationshipClient allows you to create, view and search relationships on Story Protocol. + */ +export class RelationshipClient extends RelationshipReadOnlyClient { + private readonly wallet: WalletClient; + + constructor(httpClient: AxiosInstance, rpcClient: PublicClient, wallet: WalletClient) { + super(httpClient, rpcClient); + this.wallet = wallet; + } + + /** + * Register a relationship on Story Protocol based on the specified input relationship data. + * + * @param request - the request object that contains all data needed to register a relationship + * @returns the response object that contains results from the register relationship action + */ + public async register( + request: RegisterRelationshipRequest, + ): Promise { + try { + const { request: call } = await this.rpcClient.simulateContract({ + ...storyProtocolConfig, + functionName: "createRelationship", + args: [ + getAddress(request.ipOrgId), + { + relType: request.relType, + srcAddress: request.srcContract as `0x${string}`, + srcId: request.srcTokenId, + dstAddress: request.dstContract as `0x${string}`, + dstId: request.dstTokenId, + }, + request.preHookData ? typedDataArrayToBytesArray(request.preHookData) : [], + request.postHookData ? typedDataArrayToBytesArray(request.postHookData) : [], + ], + account: this.wallet.account, + }); + + const txHash = await this.wallet.writeContract(call); + if (request.txOptions?.waitForTransaction) { + const targetLog = await waitTxAndFilterLog(this.rpcClient, txHash, { + ...relationshipModuleConfig, + eventName: "RelationshipCreated", + }); + // https://sepolia.etherscan.io/tx/0x99d5736c65bd81cd4a361a731d4a035375a0926c95e4132e8fcb80ad5b602b5c#eventlog + return { txHash: txHash, relationshipId: targetLog?.args.relationshipId.toString() }; + } else { + return { txHash: txHash }; + } + } catch (error: unknown) { + handleError(error, "Failed to register relationship"); + } + } +} diff --git a/packages/core-sdk/src/resources/relationshipReadOnly.ts b/packages/core-sdk/src/resources/relationshipReadOnly.ts new file mode 100644 index 00000000..4ca07763 --- /dev/null +++ b/packages/core-sdk/src/resources/relationshipReadOnly.ts @@ -0,0 +1,72 @@ +import { AxiosInstance, AxiosResponse } from "axios"; +import { PublicClient } from "viem"; + +import { + GetRelationshipRequest, + GetRelationshipResponse, + ListRelationshipRequest, + ListRelationshipResponse, +} from "../types/resources/relationship"; +import { isIntegerString } from "../utils/utils"; +import { handleError } from "../utils/errors"; + +/** + * RelationshipReadOnlyClient allows you to view and search relationships on Story Protocol. + */ +export class RelationshipReadOnlyClient { + protected readonly httpClient: AxiosInstance; + protected readonly rpcClient: PublicClient; + + constructor(httpClient: AxiosInstance, rpcClient: PublicClient) { + this.httpClient = httpClient; + this.rpcClient = rpcClient; + } + + /** + * Get a relationship by its ID. + * + * @param request - the request object for getting the relationship + * @returns the response object that contains the fetched relationship object + */ + public async get(request: GetRelationshipRequest): Promise { + try { + if (!isIntegerString(request.relationshipId)) { + throw new Error( + `Invalid relationshipId. Must be an integer. But got: ${request.relationshipId}`, + ); + } + + const response: AxiosResponse = await this.httpClient.get( + `/protocol/relationship/${request.relationshipId}`, + ); + + return response.data as GetRelationshipResponse; + } catch (error: unknown) { + handleError(error, `Failed to get relationship`); + } + } + + /** + * List relationships. + * + * @returns the response object that contains a list of relationships. + */ + public async list(request: ListRelationshipRequest): Promise { + try { + const response: AxiosResponse = await this.httpClient.post( + `/protocol/relationship`, + request, + { + params: { + contract: request.contract, + tokenId: request.tokenId, + }, + }, + ); + + return response.data as ListRelationshipResponse; + } catch (error: unknown) { + handleError(error, `Failed to list relationships`); + } + } +} diff --git a/packages/core-sdk/src/resources/relationshipType.ts b/packages/core-sdk/src/resources/relationshipType.ts new file mode 100644 index 00000000..ff966a35 --- /dev/null +++ b/packages/core-sdk/src/resources/relationshipType.ts @@ -0,0 +1,67 @@ +import { getAddress, PublicClient, WalletClient } from "viem"; +import { AxiosInstance } from "axios"; + +import { + RegisterRelationshipTypeRequest, + RegisterRelationshipTypeResponse, +} from "../types/resources/relationshipType"; +import { handleError } from "../utils/errors"; +import { RelationshipTypeReadOnlyClient } from "./relationshipTypeReadOnly"; +import { storyProtocolConfig } from "../abi/storyProtocol.abi"; +import { relationshipModuleConfig } from "../abi/relationshipModule.abi"; +import { waitTxAndFilterLog } from "../utils/utils"; + +/** + * RelationshipTypeClient allows you to create, view and search relationship types on Story Protocol. + */ +export class RelationshipTypeClient extends RelationshipTypeReadOnlyClient { + private readonly wallet: WalletClient; + + constructor(httpClient: AxiosInstance, rpcClient: PublicClient, wallet: WalletClient) { + super(httpClient, rpcClient); + this.wallet = wallet; + } + /** + * Register a relationship type on Story Protocol based on the specified input data. + * + * @param request - the request object that contains all data needed to register a relationship type + * @returns the response object that contains results from the register relationship type action + */ + public async register( + request: RegisterRelationshipTypeRequest, + ): Promise { + try { + const { request: call } = await this.rpcClient.simulateContract({ + ...storyProtocolConfig, + functionName: "addRelationshipType", + args: [ + { + ipOrg: getAddress(request.ipOrgId), + relType: request.relType, + allowedElements: { + src: request.relatedElements.src, + dst: request.relatedElements.dst, + }, + allowedSrcs: request.allowedSrcIpAssetTypes, + allowedDsts: request.allowedDstIpAssetTypes, + }, + ], + account: this.wallet.account, + }); + + const txHash = await this.wallet.writeContract(call); + if (request.txOptions?.waitForTransaction) { + await waitTxAndFilterLog(this.rpcClient, txHash, { + ...relationshipModuleConfig, + eventName: "RelationshipTypeSet", + }); + // https://sepolia.etherscan.io/tx/0x6b5072235bf5af5e3dc440dcd67b295a6fe6d68e5263c5dc9576f84392e77616#eventlog + return { txHash: txHash, success: true }; + } else { + return { txHash: txHash }; + } + } catch (error: unknown) { + handleError(error, "Failed to register relationship type"); + } + } +} diff --git a/packages/core-sdk/src/resources/relationshipTypeReadOnly.ts b/packages/core-sdk/src/resources/relationshipTypeReadOnly.ts new file mode 100644 index 00000000..54846598 --- /dev/null +++ b/packages/core-sdk/src/resources/relationshipTypeReadOnly.ts @@ -0,0 +1,74 @@ +import { AxiosInstance, AxiosResponse } from "axios"; +import { isAddress, PublicClient } from "viem"; + +import { + GetRelationshipTypeRequest, + GetRelationshipTypeResponse, + ListRelationshipTypesRequest, + ListRelationshipTypesResponse, +} from "../types/resources/relationshipType"; +import { dictToQueryParams } from "../utils/utils"; +import { handleError } from "../utils/errors"; + +/** + * RelationshipTypeReadOnlyClient allows you to view and search relationship types on Story Protocol. + */ +export class RelationshipTypeReadOnlyClient { + protected readonly httpClient: AxiosInstance; + protected readonly rpcClient: PublicClient; + + constructor(httpClient: AxiosInstance, rpcClient: PublicClient) { + this.httpClient = httpClient; + this.rpcClient = rpcClient; + } + + /** + * Get a RelationshipType by ipOrgId or relType. + * + * @param request - the request object for getting the relationship type + * @returns the response object that contains the fetched relationship type object + */ + public async get(request: GetRelationshipTypeRequest): Promise { + if (!isAddress(request.ipOrgId)) { + return handleError( + new Error(`Invalid ipOrgId. Must be an address. But got: ${request.ipOrgId}`), + `Failed to get relationship type`, + ); + } + + try { + const params = dictToQueryParams(request); + const response: AxiosResponse = await this.httpClient.get( + `/protocol/relationship-type?${params}`, + ); + + return response.data as GetRelationshipTypeResponse; + } catch (error: unknown) { + handleError(error, `Failed to get relationship type`); + } + } + + /** + * List RelationshipTypes. + * + * @returns the response object that contains a list of relationship types + */ + public async list(request: ListRelationshipTypesRequest): Promise { + try { + const response: AxiosResponse = await this.httpClient.post( + `/protocol/relationship-type`, + request, + { + params: { + ipOrgId: request?.ipOrgId, + options: request?.options, + }, + }, + ); + + return response.data as ListRelationshipTypesResponse; + } catch (error: unknown) { + handleError(error, `Failed to list relationship types`); + } + } +} diff --git a/packages/core-sdk/src/resources/transaction.ts b/packages/core-sdk/src/resources/transaction.ts new file mode 100644 index 00000000..2757d7ac --- /dev/null +++ b/packages/core-sdk/src/resources/transaction.ts @@ -0,0 +1,16 @@ +import { AxiosInstance } from "axios"; +import { PublicClient, WalletClient } from "viem"; + +import { TransactionReadOnlyClient } from "./transactionReadOnly"; + +/** + * TransactionClient allows you to view and monitor transactions on Story Protocol. + */ +export class TransactionClient extends TransactionReadOnlyClient { + private readonly wallet: WalletClient; + + constructor(httpClient: AxiosInstance, rpcClient: PublicClient, wallet: WalletClient) { + super(httpClient, rpcClient); + this.wallet = wallet; + } +} diff --git a/packages/core-sdk/src/resources/transactionReadOnly.ts b/packages/core-sdk/src/resources/transactionReadOnly.ts new file mode 100644 index 00000000..5ee49743 --- /dev/null +++ b/packages/core-sdk/src/resources/transactionReadOnly.ts @@ -0,0 +1,52 @@ +import { AxiosInstance } from "axios"; +import { PublicClient } from "viem"; + +import { handleError } from "../utils/errors"; +import { + GetTransactionRequest, + GetTransactionResponse, + ListTransactionRequest, + ListTransactionResponse, +} from "../types/resources/transaction"; + +/** + * TransactionClient allows you to view and monitor transactions on Story Protocol. + */ +export class TransactionReadOnlyClient { + protected readonly httpClient: AxiosInstance; + protected readonly rpcClient: PublicClient; + + constructor(httpClient: AxiosInstance, rpcClient: PublicClient) { + this.httpClient = httpClient; + this.rpcClient = rpcClient; + } + + /** + * Get transaction data based on the specified transaction id. + * + * @param request - the request object for getting the transaction + * @returns the response object that contains the fetched transaction object + */ + public async get(request: GetTransactionRequest): Promise { + try { + const response = await this.httpClient.get(`/protocol/transaction/${request.transactionId}`); + return response.data as GetTransactionResponse; + } catch (error: unknown) { + handleError(error, "Failed to get transaction"); + } + } + + /** + * List Transactions. + * + * @returns the response object that contains a list of transactions + */ + public async list(request?: ListTransactionRequest): Promise { + try { + const response = await this.httpClient.post(`/protocol/transaction`, request || {}); + return response.data as ListTransactionResponse; + } catch (error: unknown) { + handleError(error, `Failed to list transactions`); + } + } +} diff --git a/packages/core-sdk/src/types/client.ts b/packages/core-sdk/src/types/client.ts new file mode 100644 index 00000000..1a740e13 --- /dev/null +++ b/packages/core-sdk/src/types/client.ts @@ -0,0 +1,40 @@ +import { LicenseReadOnlyClient } from "../resources/licenseReadOnly"; +import { TransactionClient } from "../resources/transaction"; +import { TransactionReadOnlyClient } from "../resources/transactionReadOnly"; +import { IPAssetClient } from "../resources/ipAsset"; +import { IPAssetReadOnlyClient } from "../resources/ipAssetReadOnly"; +import { RelationshipReadOnlyClient } from "../resources/relationshipReadOnly"; +import { IPOrgReadOnlyClient } from "../resources/ipOrgReadOnly"; +import { IPOrgClient } from "../resources/ipOrg"; +import { ModuleReadOnlyClient } from "../resources/moduleReadOnly"; +import { ModuleClient } from "../resources/module"; +import { HookReadOnlyClient } from "../resources/hookReadOnly"; +import { HookClient } from "../resources/hook"; +import { PlatformClient } from "../utils/platform"; +import { LicenseClient } from "../resources/license"; +import { RelationshipClient } from "../resources/relationship"; +import { RelationshipTypeClient } from "../resources/relationshipType"; +import { RelationshipTypeReadOnlyClient } from "../resources/relationshipTypeReadOnly"; + +export interface ReadOnlyClient { + hook: HookReadOnlyClient; + module: ModuleReadOnlyClient; + ipOrg: IPOrgReadOnlyClient; + license: LicenseReadOnlyClient; + transaction: TransactionReadOnlyClient; + ipAsset: IPAssetReadOnlyClient; + relationship: RelationshipReadOnlyClient; + relationshipType: RelationshipTypeReadOnlyClient; +} + +export interface Client { + hook: HookClient; + module: ModuleClient; + ipOrg: IPOrgClient; + license: LicenseClient; + transaction: TransactionClient; + ipAsset: IPAssetClient; + relationship: RelationshipClient; + relationshipType: RelationshipTypeClient; + platform: PlatformClient; +} diff --git a/packages/core-sdk/src/types/common.ts b/packages/core-sdk/src/types/common.ts new file mode 100644 index 00000000..e3b63fcb --- /dev/null +++ b/packages/core-sdk/src/types/common.ts @@ -0,0 +1,6 @@ +export type Hex = `0x${string}`; + +export type TypedData = { + interface: string; // i.e. "(address,uint256)" + data: unknown[]; +}; diff --git a/packages/core-sdk/src/types/config.ts b/packages/core-sdk/src/types/config.ts new file mode 100644 index 00000000..c196bffe --- /dev/null +++ b/packages/core-sdk/src/types/config.ts @@ -0,0 +1,20 @@ +import { Account, Chain, Transport } from "viem"; + +/** + * Configuration for the SDK Client. + * + * @public + */ +export interface StoryConfig extends StoryReadOnlyConfig { + readonly account: Account; +} + +/** + * Configuration for the read-only SDK Client. + * + * @public + */ +export interface StoryReadOnlyConfig { + readonly chain?: Chain; + readonly transport?: Transport; +} diff --git a/packages/core-sdk/src/types/options.ts b/packages/core-sdk/src/types/options.ts new file mode 100644 index 00000000..248bbdfc --- /dev/null +++ b/packages/core-sdk/src/types/options.ts @@ -0,0 +1,12 @@ +export type TxOptions = { + waitForTransaction?: boolean; + gasPrice?: bigint; + numBlockConfirmations?: number; +}; + +export type QueryOptions = { + pagination?: { + offset?: number; // starting from 0 + limit?: number; + }; +}; diff --git a/packages/core-sdk/src/types/resources/hook.ts b/packages/core-sdk/src/types/resources/hook.ts new file mode 100644 index 00000000..6208aeef --- /dev/null +++ b/packages/core-sdk/src/types/resources/hook.ts @@ -0,0 +1,54 @@ +import { QueryOptions } from "../options"; +import { HookType } from "../../enums/HookType"; + +/** + * Core data model for Hook. + * + * @public + */ +export type Hook = { + id: string; + moduleId: string; + interface?: string; + hookType: HookType; + registryKey: string; + registeredAt: string; // ISO 8601 + txHash: string; +}; + +/** + * Request type for hook.get method. + * + * @public + */ +export type GetHookRequest = { + hookId: string; +}; + +/** + * Response type for hook.get method. + * + * @public + */ +export type GetHookResponse = { + hook: Hook; +}; + +/** + * Request type for hook.list method. + * + * @public + */ +export type ListHookRequest = { + moduleId?: string; + options?: QueryOptions; +}; + +/** + * Response type for hook.list method. + * + * @public + */ +export type ListHookResponse = { + hooks: Hook[]; +}; diff --git a/packages/core-sdk/src/types/resources/ipAsset.ts b/packages/core-sdk/src/types/resources/ipAsset.ts new file mode 100644 index 00000000..49ceaec6 --- /dev/null +++ b/packages/core-sdk/src/types/resources/ipAsset.ts @@ -0,0 +1,89 @@ +import { QueryOptions, TxOptions } from "../options"; +import { TypedData } from "../common"; + +/** + * Core data model for IP Asset. + * + * @public + */ +export type IPAsset = { + id: string; + name: string; + type: IPAssetType; + ipOrgId: string; + owner: string; + mediaUrl: string; + contentHash?: string; + createdAt: string; // ISO 8601 + txHash: string; +}; + +export type IPAssetType = { + index: number; + value: string; +}; + +/** + * Request type for ipAsset.get method. + * + * @public + */ +export type GetIpAssetRequest = { + ipAssetId: string; +}; + +/** + * Response type for ipAsset.get method. + * + * @public + */ +export type GetIpAssetResponse = { + ipAsset: IPAsset; +}; + +/** + * Request type for ipAsset.create method. + * + * @public + */ +export type CreateIpAssetRequest = { + name: string; + typeIndex: number; + ipOrgId: string; + licenseId?: number; + owner?: string; + mediaUrl?: string; + contentHash?: `0x${string}`; + preHookData?: Array; + postHookData?: Array; + txOptions?: TxOptions; +}; + +/** + * Response type for ipAsset.create method. + * + * @public + */ +export type CreateIpAssetResponse = { + txHash: string; + ipAssetId?: string; +}; + +/** + * Request type for ipAsset.list method. + * + * @public + */ +export type ListIpAssetRequest = { + ipOrgId?: string; + options?: QueryOptions; +}; + +/** + * Response type for ipAsset.list method. + * + * @public + */ +export type ListIpAssetResponse = { + ipAssets: IPAsset[]; +}; diff --git a/packages/core-sdk/src/types/resources/ipOrg.ts b/packages/core-sdk/src/types/resources/ipOrg.ts new file mode 100644 index 00000000..d0f08420 --- /dev/null +++ b/packages/core-sdk/src/types/resources/ipOrg.ts @@ -0,0 +1,77 @@ +import { QueryOptions, TxOptions } from "../options"; + +/** + * Core data model for IP Org. + * + * @public + */ +export type IPOrg = { + id: string; + name: string; + symbol: string; + owner: string; + baseUri?: string; + contractUri?: string; + ipAssetTypes: Array; + createdAt: string; // ISO 8601 + txHash: string; +}; + +/** + * Request type for iporg.get method. + * + * @public + */ +export type GetIPOrgRequest = { + ipOrgId: string; +}; + +/** + * Response type for iporg.get method. + * + * @public + */ +export type GetIPOrgResponse = { + ipOrg: IPOrg; +}; + +/** + * Request type for iporg.create method. + * + * @public + */ +export type CreateIPOrgRequest = { + name: string; + symbol: string; + owner?: string; + ipAssetTypes: Array; + txOptions?: TxOptions; +}; + +/** + * Response type for iporg.create method. + * + * @public + */ +export type CreateIPOrgResponse = { + txHash: string; + ipOrgId?: string; +}; + +/** + * Request type for iporg.list method. + * + * @public + */ +export type ListIPOrgRequest = { + options?: QueryOptions; +}; + +/** + * Response type for iporg.list method. + * + * @public + */ +export type ListIPOrgResponse = { + ipOrgs: IPOrg[]; +}; diff --git a/packages/core-sdk/src/types/resources/license.ts b/packages/core-sdk/src/types/resources/license.ts new file mode 100644 index 00000000..a0314a4c --- /dev/null +++ b/packages/core-sdk/src/types/resources/license.ts @@ -0,0 +1,198 @@ +import { Hex } from "viem"; + +import { TypedData } from "../common"; +import { QueryOptions, TxOptions } from "../options"; + +/** + * Core data model for License. + * + * @public + */ +export type License = { + id: string; + isReciprocal: boolean; + derivativeNeedsApproval: boolean; + derivativesAllowed: boolean; + status: number; + licensor: string; + revoker: string; + ipOrgId: string; + ipAssetId: string; + parentLicenseId: string; + createdAt: string; + txHash: string; +}; + +/** + * Core data model for Param + * + * @public + */ +export type Param = { + tag: Hex; + value: Hex; +}; + +/** + * Core data model for Param + * + * @public + */ +export type FormattedParam = { + tag: string; + value: unknown; + type: string; +}; + +/** + * Core data model for License Params + * + * @public + */ +export type LicenseParams = { + ipOrgId: string; + frameworkId: string; + url: string; + licensorConfig: number; + params: Param[]; + createdAt: string; // ISO 8601 + txHash: string; +}; + +/** + * Core data model for License Params + * + * @public + */ +export type FormattedLicenseParams = { + ipOrgId: string; + frameworkId: string; + url: string; + licensorConfig: number; + params: FormattedParam[]; + createdAt: string; // ISO 8601 + txHash: string; +}; + +export type ParamValues = { + tag: Hex; + value: TypedData; +}; + +export enum LicensorConfigEnum { + Unset, + IpOrgOwnerAlways, + Source, +} + +export type LicensingConfig = { + frameworkId: string; + params: ParamValues[]; + licensor: LicensorConfigEnum; +}; + +/** + * Represents the response structure for configuring a license using the `license.create` method. + * + * @public + */ + +export type CreateLicenseRequest = { + ipOrgId: string; + parentLicenseId: string; + ipaId: string; + params: ParamValues[]; + preHookData: Array; + postHookData: Array; + txOptions?: TxOptions; +}; + +/** + * Represents the response structure for creating a new license using the `license.create` method. + * + * @public + */ +export type CreateLicenseResponse = { + txHash: string; // Transaction hash of the license creation transaction. + licenseId?: string; +}; + +/** + * Represents the response structure for configuring a license using the `license.configure` method. + * + * @public + */ +export type ConfigureLicenseRequest = { + ipOrg: string; + frameworkId: string; + params: ParamValues[]; + licensor: LicensorConfigEnum; + txOptions?: TxOptions; +}; + +/** + * Represents the response structure for creating a new license using the `license.configure` method. + * + * @public + */ +export type ConfigureLicenseResponse = { + txHash: string; + success?: boolean; +}; + +/** + * Request type for license.get method. + * + * @public + */ +export type GetLicenseRequest = { + licenseId: string; +}; + +/** + * Response type for license.get method. + * + * @public + */ +export type GetLicenseResponse = { + license: License; +}; + +/** + * Request type for license.list method. + * + * @public + */ +export type ListLicenseRequest = { + ipOrgId?: string; + ipAssetId?: string; + options?: QueryOptions; +}; + +/** + * Response type for license.list method. + * + * @public + */ +export type ListLicenseResponse = { + licenses: License[]; +}; + +/** + * Request type for license.listParams method. + * + * @public + */ +export type ListLicenseParamsRequest = { + ipOrgId: string; + options?: QueryOptions; +}; + +/** + * Response type for license.listParams method. + * + * @public + */ +export type ListLicenseParamsResponse = { + licenseParams: FormattedLicenseParams[]; +}; diff --git a/packages/core-sdk/src/types/resources/module.ts b/packages/core-sdk/src/types/resources/module.ts new file mode 100644 index 00000000..855d96b0 --- /dev/null +++ b/packages/core-sdk/src/types/resources/module.ts @@ -0,0 +1,53 @@ +import { Hook } from "./hook"; +import { QueryOptions } from "../options"; + +/** + * Core data model for Module. + * + * @public + */ +export type Module = { + id: string; + ipOrgId: string; + moduleKey: string; + interface?: string; + preHooks?: Hook[]; + postHooks?: Hook[]; +}; + +/** + * Request type for module.get method. + * + * @public + */ +export type GetModuleRequest = { + moduleId: string; +}; + +/** + * Response type for module.get method. + * + * @public + */ +export type GetModuleResponse = { + module: Module; +}; + +/** + * Request type for module.list method. + * + * @public + */ +export type ListModuleRequest = { + ipOrgId?: string; + options?: QueryOptions; +}; + +/** + * Response type for module.list method. + * + * @public + */ +export type ListModuleResponse = { + modules: Module[]; +}; diff --git a/packages/core-sdk/src/types/resources/relationship.ts b/packages/core-sdk/src/types/resources/relationship.ts new file mode 100644 index 00000000..2577c7e4 --- /dev/null +++ b/packages/core-sdk/src/types/resources/relationship.ts @@ -0,0 +1,79 @@ +import { QueryOptions, TxOptions } from "../options"; +import { TypedData } from "../common"; + +export type Relationship = { + id: string; + type: string; // i.e. "APPEARS_IN" + srcContract: string; + srcTokenId: string; + dstContract: string; + dstTokenId: string; + registeredAt: string; // ISO 8601 + txHash: string; +}; + +/** + * Request type for relationship.register method. + * + * @public + */ +export type RegisterRelationshipRequest = { + ipOrgId: string; + relType: string; + srcContract: string; + srcTokenId: string; + dstContract: string; + dstTokenId: string; + preHookData?: Array; + postHookData?: Array; + txOptions?: TxOptions; +}; + +/** + * Response type for relationship.register method. + * + * @public + */ +export type RegisterRelationshipResponse = { + txHash: string; + relationshipId?: string; +}; + +/** + * Request type for relationship.get method. + * + * @public + */ +export type GetRelationshipRequest = { + relationshipId: string; + options?: QueryOptions; +}; + +/** + * Response type for relationship.get method. + * + * @public + */ +export type GetRelationshipResponse = { + relationship: Relationship; +}; + +/** + * Request type for relationship.list method. + * + * @public + */ +export type ListRelationshipRequest = { + tokenId: string; + contract: string; + options?: QueryOptions; +}; + +/** + * Response type for relationship.list method. + * + * @public + */ +export type ListRelationshipResponse = { + relationships: Relationship[]; +}; diff --git a/packages/core-sdk/src/types/resources/relationshipType.ts b/packages/core-sdk/src/types/resources/relationshipType.ts new file mode 100644 index 00000000..ca8e4c3a --- /dev/null +++ b/packages/core-sdk/src/types/resources/relationshipType.ts @@ -0,0 +1,95 @@ +import { QueryOptions, TxOptions } from "../options"; +import { TypedData } from "../common"; +import { Relatables } from "../../enums/Relatables"; + +/** + * Core data model for Relationship Type. + * + * @public + */ +export type RelationshipType = { + type: string; + ipOrgId: string; + srcContract: string; + srcRelatable: number; + srcSubtypesMask: number; + dstContract: string; + dstRelatable: number; + dstSubtypesMask: number; + registeredAt: string; + txHash: string; +}; + +/** + * Request type for relationshipType.get method. + * + * @public + */ +export type GetRelationshipTypeRequest = { + ipOrgId: string; + relType: string; +}; + +/** + * Response type for relationshipType.get method. + * + * @public + */ +export type GetRelationshipTypeResponse = { + relationshipType: RelationshipType; +}; + +/** + * Request type for relationshipType.list method. + * + * @public + */ +export type ListRelationshipTypesRequest = { + ipOrgId?: string; + options?: QueryOptions; +}; + +/** + * Response type for relationshipType.list method. + * + * @public + */ +export type ListRelationshipTypesResponse = { + relationshipTypes: RelationshipType[]; +}; + +/** + * RelatedElements contains relatables from the source and the destination entity. + * + * @public + */ +export type RelatedElements = { + src: Relatables; + dst: Relatables; +}; + +/** + * Request type for relationshipType.register method. + * + * @public + */ +export type RegisterRelationshipTypeRequest = { + ipOrgId: string; + relType: string; + relatedElements: RelatedElements; + allowedSrcIpAssetTypes: number[]; // the number is the index of the ip asset type array defined in ip org + allowedDstIpAssetTypes: number[]; + preHooksConfig?: Array; + postHooksConfig?: Array; + txOptions?: TxOptions; +}; + +/** + * Response type for relationshipType.register method. + * + * @public + */ +export type RegisterRelationshipTypeResponse = { + txHash: string; + success?: boolean; +}; diff --git a/packages/core-sdk/src/types/resources/transaction.ts b/packages/core-sdk/src/types/resources/transaction.ts new file mode 100644 index 00000000..e252982a --- /dev/null +++ b/packages/core-sdk/src/types/resources/transaction.ts @@ -0,0 +1,56 @@ +import { ResourceType } from "../../enums/ResourceType"; +import { ActionType } from "../../enums/ActionType"; +import { QueryOptions } from "../options"; + +/** + * Core data model for transactions. + * + * @public + */ +export type Transaction = { + id: string; + txHash: string; + ipOrgId: string; + initiator: string; + resourceId: string; + resourceType: ResourceType; + actionType: ActionType; + createdAt: string; // ISO 8601 +}; + +/** + * Request type for transaction.get method. + * + * @public + */ +export type GetTransactionRequest = { + transactionId: string; +}; + +/** + * Response type for transaction.get method. + * + * @public + */ +export type GetTransactionResponse = { + transaction: Transaction; +}; + +/** + * Response type for transaction.list method. + * + * @public + */ +export type ListTransactionRequest = { + ipOrgId?: string; + options?: QueryOptions; +}; + +/** + * Response type for transaction.list method. + * + * @public + */ +export type ListTransactionResponse = { + transactions: Transaction[]; +}; diff --git a/packages/core-sdk/src/utils/errors.ts b/packages/core-sdk/src/utils/errors.ts new file mode 100644 index 00000000..df23d5cc --- /dev/null +++ b/packages/core-sdk/src/utils/errors.ts @@ -0,0 +1,6 @@ +export function handleError(error: unknown, msg: string): never { + if (error instanceof Error) { + throw new Error(`${msg}: ${error.message}`); + } + throw new Error(`${msg}: Unknown error type`); +} diff --git a/packages/core-sdk/src/utils/platform.ts b/packages/core-sdk/src/utils/platform.ts new file mode 100644 index 00000000..356e85c7 --- /dev/null +++ b/packages/core-sdk/src/utils/platform.ts @@ -0,0 +1,44 @@ +import { AxiosInstance } from "axios"; + +import { handleError } from "./errors"; + +export class PlatformClient { + protected readonly httpClient: AxiosInstance; + + constructor(httpClient: AxiosInstance) { + this.httpClient = httpClient; + } + + /** + * Upload a file to Arweave. + * + * @param file - the file binary data to upload + * @param mimeType - the mime type of the file + * @returns the response object that contains the uri of the uploaded file + */ + public async uploadFile(file: File | Buffer, mimeType: string): Promise<{ uri: string }> { + try { + // requst the s3 pre-signed url + const preSignUrlResp = await this.httpClient.post("/platform/file-upload/request"); + const data = preSignUrlResp.data as { url: string; key: string }; + + // upload the file to s3 + const uploadResp = await this.httpClient.put(data.url, file, { + timeout: 0, + headers: { + "Content-Type": mimeType, + }, + }); + if (uploadResp.status !== 200) { + throw new Error(`Failed to upload file to s3. Status: ${uploadResp.status}`); + } + + const confirmResp = await this.httpClient.post("/platform/file-upload/confirm", { + key: data.key, + }); + return confirmResp.data as { uri: string }; + } catch (error: unknown) { + return handleError(error, "Failed to upload file"); + } + } +} diff --git a/packages/core-sdk/src/utils/utils.ts b/packages/core-sdk/src/utils/utils.ts new file mode 100644 index 00000000..f7e57aa5 --- /dev/null +++ b/packages/core-sdk/src/utils/utils.ts @@ -0,0 +1,179 @@ +import { Hash } from "viem/types/misc"; +import { DecodeEventLogReturnType } from "viem/_types/utils/abi/decodeEventLog"; +import { Abi, decodeEventLog, PublicClient, encodeAbiParameters, parseAbiParameters } from "viem"; +import { InferEventName } from "viem/types/contract"; + +import { Hex, TypedData } from "../types/common"; +import { DERIVATIVES_ALLOWED_OPTIONS, PARAMS_TAG } from "../constants/license"; + +export function isIntegerString(s: string): boolean { + const num = Number(s); + return !isNaN(num) && parseInt(s, 10) === num; +} + +export function parseToBigInt(num: string | number): bigint { + return BigInt(num); +} + +export async function waitTxAndFilterLog< + const TAbi extends Abi | readonly unknown[], + TEventName extends string | undefined = undefined, + TTopics extends Hex[] = Hex[], + TData extends Hex | undefined = undefined, + TStrict extends boolean = true, +>( + client: PublicClient, + txHash: Hash, + params: { + abi: TAbi; + eventName: InferEventName; + confirmations?: number; + pollingInterval?: number; + timeout?: number; + }, +): Promise> { + const txReceipt = await client.waitForTransactionReceipt({ + hash: txHash, + confirmations: params.confirmations, + pollingInterval: params.pollingInterval, + timeout: params.timeout, + }); + + for (const log of txReceipt.logs) { + try { + return decodeEventLog({ + abi: params.abi, + eventName: params.eventName, + data: log.data as TData, + topics: log.topics as [signature: Hex, ...args: TTopics], + }); + } catch (e) { + continue; + } + } + + throw new Error(`not found event ${params.eventName} in target transaction`); +} + +export function dictToQueryParams(params: Record): string { + const queryParamList: string[] = []; + for (const key in params) { + const value = params[key]; + queryParamList.push(`${encodeURIComponent(key)}=${encodeURIComponent(value)}`); + } + + return queryParamList.join("&"); +} + +export function typedDataArrayToBytesArray(typedDataArray: Array): Array { + const result: Array = []; + typedDataArray.forEach(function (typedData: TypedData) { + result.push(typedDataToBytes(typedData)); + }); + return result; +} + +export function typedDataToBytes(typedData: TypedData): Hex { + return encodeAbiParameters(parseAbiParameters(typedData.interface), typedData.data); +} + +export function decodeShortstring(hexString: string): string { + if (hexString.startsWith("0x")) { + hexString = hexString.slice(2); + } + + // Replace the last two hexadecimal digits with zero + hexString = hexString.substring(0, hexString.length - 2) + "00"; + + let asciiString = ""; + for (let i = 0; i < hexString.length; i += 2) { + const hexByte = hexString.substring(i, i + 2); + if (hexByte === "00") { + break; // Stop if padding (00) is found + } + asciiString += String.fromCharCode(parseInt(hexByte, 16)); + } + return asciiString; +} + +export function splitIntoBytes32(hexString: string): Hex[] { + if (hexString.startsWith("0x")) { + hexString = hexString.slice(2); // Remove the '0x' prefix + } + + if (hexString.length % 64 !== 0) { + throw new Error("Hex string length must be a multiple of 64."); + } + + const bytes32Array: string[] = []; + for (let i = 0; i < hexString.length; i += 64) { + bytes32Array.push("0x" + hexString.substring(i, i + 64)); + } + + return bytes32Array as Hex[]; +} + +export function decodeChannelsOfDistribution(value: Hex): string[] { + return splitIntoBytes32(value).map((bytes32) => { + // Set the last byte to zero + return decodeShortstring(bytes32); + }); +} + +function hexToFixedLengthBitmask(hexString: string): number[] { + if (hexString.startsWith("0x")) { + hexString = hexString.slice(2); + } + + let binaryString = BigInt("0x" + hexString).toString(2); + + // Pad or truncate the binary string to the desired length + binaryString = binaryString.padStart(3, "0").slice(-3); + + return Array.from(binaryString).map((bit) => parseInt(bit)); +} + +function hexToBoolean(hexString: string): boolean { + if (hexString.toLowerCase() === "0x") { + return false; + } + + if (hexString.toLowerCase().startsWith("0x")) { + hexString = hexString.slice(2); + } + + return BigInt("0x" + hexString) !== BigInt(0); +} + +export function decodeDerivativesAllowedOptions(bitmask: number[], options: string[]): string[] { + return options.filter((_, index) => bitmask[index] === 1); +} + +export function paramsTagValueDecoder(paramTag: Hex, paramValue: unknown) { + const parsedTag = decodeShortstring(paramTag); + let value = paramValue; + let type = "unknown"; + switch (parsedTag) { + case PARAMS_TAG.CHANNELS_OF_DISTRIBUTION: + value = decodeChannelsOfDistribution(paramValue as Hex); + type = "string[]"; + break; + case PARAMS_TAG.ATTRIBUTION: + value = hexToBoolean(paramValue as Hex); + type = "boolean"; + break; + case PARAMS_TAG.DERIVATIVES_ALLOWED: + value = hexToBoolean(paramValue as Hex); + type = "boolean"; + break; + case PARAMS_TAG.DERIVATIVES_ALLOWED_OPTIONS: + value = decodeDerivativesAllowedOptions( + hexToFixedLengthBitmask(paramValue as Hex), + DERIVATIVES_ALLOWED_OPTIONS, + ); + type = "string[]"; + break; + } + + return { tag: parsedTag, value, type }; +} diff --git a/packages/core-sdk/test/integration/config.test.ts b/packages/core-sdk/test/integration/config.test.ts new file mode 100644 index 00000000..ca0c3049 --- /dev/null +++ b/packages/core-sdk/test/integration/config.test.ts @@ -0,0 +1,7 @@ +import chai from "chai"; +import chaiAsPromised from "chai-as-promised"; +import * as dotenv from "dotenv"; + +dotenv.config(); +chai.use(chaiAsPromised); +chai.config.truncateThreshold = 0; diff --git a/packages/core-sdk/test/integration/hookReadOnly.test.ts b/packages/core-sdk/test/integration/hookReadOnly.test.ts new file mode 100644 index 00000000..9dfdb02d --- /dev/null +++ b/packages/core-sdk/test/integration/hookReadOnly.test.ts @@ -0,0 +1,100 @@ +import { expect } from "chai"; +import { + StoryClient, + StoryReadOnlyConfig, + GetHookRequest, + ListHookRequest, + ReadOnlyClient, +} from "../../src"; + +describe("Hook client integration tests", () => { + let client: ReadOnlyClient; + + beforeEach(function () { + const config: StoryReadOnlyConfig = {}; + + client = StoryClient.newReadOnlyClient(config); + }); + + describe("List Hooks", async function () { + it("should return array of all hooks", async () => { + const req = { + options: { + pagination: { + limit: 10, + offset: 0, + }, + }, + } as ListHookRequest; + + const response = await client.hook.list(req); + + expect(response).to.have.property("hooks"); + expect(response.hooks).to.be.an("array"); + + const hook1 = response.hooks[0]; + expect(hook1).to.have.property("id"); + expect(hook1).to.have.property("moduleId"); + expect(hook1).to.have.property("registryKey"); + expect(hook1).to.have.property("txHash"); + expect(hook1.id).to.be.a("string"); + expect(hook1.moduleId).to.be.a("string"); + expect(hook1.registryKey).to.be.a("string"); + expect(hook1.txHash).to.be.a("string"); + }); + + it("should return array of limited amount of hooks", async () => { + const req = { + options: { + pagination: { + limit: 1, + offset: 0, + }, + }, + } as ListHookRequest; + + const response = await client.hook.list(req); + + expect(response).to.have.property("hooks"); + expect(response.hooks).to.be.an("array"); + expect(response.hooks.length).to.equal(1); + }); + + it("should return a list of hooks successfully without options", async () => { + const response = await client.hook.list(); + expect(response).is.not.null; + expect(response.hooks.length).to.gt(0); + }); + + it("should return a list of hooks if the options are invalid", async () => { + const options = { + options: {}, + } as ListHookRequest; + const response = await client.hook.list(options); + expect(response).is.not.null; + expect(response.hooks.length).to.gt(0); + }); + }); + + describe("Get Hook", async function () { + it("should return array of all hooks", async () => { + const req = { + hookId: process.env.TEST_HOOK_ID as string, + } as GetHookRequest; + + const response = await client.hook.get(req); + + expect(response).to.have.property("hook"); + + const hook = response.hook; + expect(hook).to.have.property("id"); + expect(hook).to.have.property("moduleId"); + expect(hook).to.have.property("registryKey"); + expect(hook).to.have.property("txHash"); + expect(hook.id).to.be.a("string"); + expect(hook.moduleId).to.be.a("string"); + expect(hook.registryKey).to.be.a("string"); + expect(hook.txHash).to.be.a("string"); + }); + }); +}); diff --git a/packages/core-sdk/test/integration/ipAsset.test.ts b/packages/core-sdk/test/integration/ipAsset.test.ts new file mode 100644 index 00000000..3748a644 --- /dev/null +++ b/packages/core-sdk/test/integration/ipAsset.test.ts @@ -0,0 +1,137 @@ +import { expect } from "chai"; +import { StoryClient, StoryConfig, Client } from "../../src"; +import { sepolia } from "viem/chains"; +import { Hex, http } from "viem"; +import { privateKeyToAccount } from "viem/accounts"; + +describe("IP Asset Functions", () => { + let client: Client; + let senderAddress: string; + + before(function () { + const config: StoryConfig = { + chain: sepolia, + transport: http(process.env.RPC_PROVIDER_URL), + account: privateKeyToAccount((process.env.WALLET_PRIVATE_KEY || "0x") as Hex), + }; + + senderAddress = config.account.address; + client = StoryClient.newClient(config); + }); + + describe("Create IP Asset", async function () { + it("should not throw error when creating an IP Asset", async () => { + const waitForTransaction: boolean = true; + const response = await expect( + client.ipAsset.create({ + name: "Test", + typeIndex: 0, + ipOrgId: process.env.TEST_IPORG_ID as string, + owner: senderAddress, + txOptions: { + waitForTransaction: waitForTransaction, + }, + }), + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string"); + expect(response.txHash).not.empty; + + if (waitForTransaction) { + expect(response.ipAssetId).to.be.a("string"); + expect(response.ipAssetId).not.empty; + } + }); + + it("should not throw error when creating an IP Asset with contentHash (SHA256)", async () => { + const waitForTransaction: boolean = true; + const response = await expect( + client.ipAsset.create({ + name: "Test", + typeIndex: 0, + ipOrgId: process.env.TEST_IPORG_ID as string, + owner: senderAddress, + contentHash: "0x0ffc6cd05f97735c7f621791f127c4b298159bce126a78acc2d4eaad729ca587", + txOptions: { + waitForTransaction: waitForTransaction, + }, + }), + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string"); + expect(response.txHash).not.empty; + + if (waitForTransaction) { + expect(response.ipAssetId).to.be.a("string"); + expect(response.ipAssetId).not.empty; + } + }); + + it("should not throw error when creating an IP Asset without owner field", async () => { + const waitForTransaction: boolean = true; + const response = await expect( + client.ipAsset.create({ + name: "Test", + typeIndex: 0, + ipOrgId: process.env.TEST_IPORG_ID as string, + mediaUrl: "", + txOptions: { + waitForTransaction: waitForTransaction, + }, + }), + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string"); + expect(response.txHash).not.empty; + + if (waitForTransaction) { + expect(response.ipAssetId).to.be.a("string"); + expect(response.ipAssetId).not.empty; + } + }); + + it.skip("should not throw error when creating an IP Asset with a hook", async () => { + const waitForTransaction: boolean = true; + const response = await expect( + client.ipAsset.create({ + name: "Test", + typeIndex: 0, + ipOrgId: process.env.TEST_IPORG_ID_WITH_HOOK as string, + owner: senderAddress, + preHookData: [ + { + interface: "address", + data: [process.env.TEST_WALLET_ADDRESS as string], + }, + ], + txOptions: { + waitForTransaction: waitForTransaction, + }, + }), + ).to.not.be.rejected; + + expect(response.txHash).to.be.a("string"); + expect(response.txHash).not.empty; + + if (waitForTransaction) { + expect(response.ipAssetId).to.be.a("string"); + expect(response.ipAssetId).not.empty; + } + }); + + it("should throw error when creating an IP Asset with a hook, without hook data", async () => { + const waitForTransaction: boolean = true; + const response = await expect( + client.ipAsset.create({ + name: "Test", + typeIndex: 0, + ipOrgId: "0x2554E198752d0F086c8b885CbCc5d663365673C2", + owner: senderAddress, + txOptions: { + waitForTransaction: waitForTransaction, + }, + }), + ).to.be.rejected; + }); + }); +}); diff --git a/packages/core-sdk/test/integration/ipAssetReadOnly.test.ts b/packages/core-sdk/test/integration/ipAssetReadOnly.test.ts new file mode 100644 index 00000000..e2ee1f22 --- /dev/null +++ b/packages/core-sdk/test/integration/ipAssetReadOnly.test.ts @@ -0,0 +1,67 @@ +import { expect } from "chai"; +import { StoryClient, StoryReadOnlyConfig, ListIpAssetRequest } from "../../src"; +import { ReadOnlyClient } from "../../src"; + +describe("IP Asset Read Only Functions", () => { + let client: ReadOnlyClient; + + before(function () { + const config: StoryReadOnlyConfig = {}; + + client = StoryClient.newReadOnlyClient(config); + }); + + describe("Get IP Asset", async function () { + it("should return asset when the asset id is valid", async () => { + const response = await client.ipAsset.get({ + ipAssetId: "1", + }); + expect(response.ipAsset).is.not.null; + }); + }); + + describe("List IP assets", async function () { + it("should return a list of IP assets successfully upon query", async () => { + const response = await client.ipAsset.list({ + ipOrgId: process.env.TEST_IPORG_ID as string, + options: { + pagination: { + limit: 10, + offset: 0, + }, + }, + }); + expect(response).is.not.null; + }); + + it("should return a list of IP assets with pagination", async () => { + const response = await client.ipAsset.list({ + ipOrgId: process.env.TEST_IPORG_ID as string, + options: { + pagination: { + limit: 1, + offset: 0, + }, + }, + }); + + expect(response).is.not.null; + expect(response.ipAssets.length).to.equal(1); + }); + + it("should return a list of ipAssets successfully without options", async () => { + const response = await client.ipAsset.list(); + expect(response).is.not.null; + expect(response.ipAssets.length).to.gt(0); + }); + + it("should return a list of ipAssets if the options are invalid", async () => { + const options = { + options: {}, + } as ListIpAssetRequest; + const response = await client.ipAsset.list(options); + expect(response).is.not.null; + expect(response.ipAssets.length).to.gt(0); + }); + }); +}); diff --git a/packages/core-sdk/test/integration/ipOrg.test.ts b/packages/core-sdk/test/integration/ipOrg.test.ts new file mode 100644 index 00000000..68e9ebec --- /dev/null +++ b/packages/core-sdk/test/integration/ipOrg.test.ts @@ -0,0 +1,63 @@ +import { expect } from "chai"; +import { StoryClient, StoryConfig, Client } from "../../src"; +import { sepolia } from "viem/chains"; +import { Hex, http } from "viem"; +import { privateKeyToAccount } from "viem/accounts"; + +describe("IPOrg Functions", () => { + let client: Client; + let senderAddress: string; + + before(function () { + const config: StoryConfig = { + chain: sepolia, + transport: http(process.env.RPC_PROVIDER_URL), + account: privateKeyToAccount((process.env.WALLET_PRIVATE_KEY || "0x") as Hex), + }; + senderAddress = config.account.address; + client = StoryClient.newClient(config); + }); + + describe("Create IPOrg", async function () { + it("should not throw error when creating a ipOrg", async () => { + const waitForTransaction: boolean = true; + const response = await expect( + client.ipOrg.create({ + name: "Alice In Wonderland", + symbol: "AIW", + owner: senderAddress, + ipAssetTypes: ["Story", "Character"], + txOptions: { + waitForTransaction: waitForTransaction, + }, + }), + ).to.not.be.rejected; + + expect(response.txHash).to.exist.and.be.a("string").and.not.be.empty; + + if (waitForTransaction) { + expect(response.ipOrgId).to.exist.and.be.a("string").and.not.be.empty; + } + }); + + it("should not throw error when creating a ipOrg without the owner field", async () => { + const waitForTransaction: boolean = true; + const response = await expect( + client.ipOrg.create({ + name: "Alice In Wonderland", + symbol: "AIW", + ipAssetTypes: ["Story", "Character"], + txOptions: { + waitForTransaction: waitForTransaction, + }, + }), + ).to.not.be.rejected; + + expect(response.txHash).to.exist.and.be.a("string").and.not.be.empty; + + if (waitForTransaction) { + expect(response.ipOrgId).to.exist.and.be.a("string").and.not.be.empty; + } + }); + }); +}); diff --git a/packages/core-sdk/test/integration/ipOrgReadOnly.test.ts b/packages/core-sdk/test/integration/ipOrgReadOnly.test.ts new file mode 100644 index 00000000..9cb41567 --- /dev/null +++ b/packages/core-sdk/test/integration/ipOrgReadOnly.test.ts @@ -0,0 +1,103 @@ +import { expect } from "chai"; +import { + StoryClient, + StoryReadOnlyConfig, + ReadOnlyClient, + ListIPOrgRequest, + IPOrg, +} from "../../src"; + +describe("IPOrg Read Only Functions", function () { + let client: ReadOnlyClient; + + before(function () { + const config: StoryReadOnlyConfig = {}; + client = StoryClient.newReadOnlyClient(config); + }); + + describe("Get IPOrg", async function () { + it("should return ipOrg when the ipOrg id is valid", async function () { + const response = await client.ipOrg.get({ + ipOrgId: process.env.TEST_IPORG_ID as string, + }); + + expect(response).to.have.property("ipOrg"); + expectIpOrgFields(response.ipOrg); + }); + }); + + describe("List IPOrgs", async function () { + it("should return a list of ipOrgs successfully upon query", async function () { + const options = { + options: { + pagination: { + limit: 10, + offset: 0, + }, + }, + } as ListIPOrgRequest; + const response = await client.ipOrg.list(options); + + expect(response).to.have.property("ipOrgs"); + expect(response.ipOrgs).to.be.an("array"); + expect(response.ipOrgs.length).to.gt(0); + expectIpOrgFields(response.ipOrgs[0]); + }); + + it("should return a list of ipOrgs successfully without options", async function () { + const response = await client.ipOrg.list(); + + expect(response).to.have.property("ipOrgs"); + expect(response.ipOrgs).to.be.an("array"); + expect(response.ipOrgs.length).to.gt(0); + expectIpOrgFields(response.ipOrgs[0]); + }); + + it("should return a list of ipOrgs with pagination", async function () { + const options = { + options: { + pagination: { + limit: 1, + offset: 0, + }, + }, + } as ListIPOrgRequest; + const response = await client.ipOrg.list(options); + + expect(response).to.have.property("ipOrgs"); + expect(response.ipOrgs).to.be.an("array"); + expect(response.ipOrgs.length).to.gt(0); + expectIpOrgFields(response.ipOrgs[0]); + }); + + it("should return a list of ipOrgs if the options are invalid", async function () { + const options = { + options: {}, + } as ListIPOrgRequest; + const response = await client.ipOrg.list(options); + + expect(response).to.have.property("ipOrgs"); + expect(response.ipOrgs).to.be.an("array"); + expect(response.ipOrgs.length).to.gt(0); + expectIpOrgFields(response.ipOrgs[0]); + }); + }); + + function expectIpOrgFields(ipOrg: IPOrg) { + expect(ipOrg).to.have.property("id"); + expect(ipOrg).to.have.property("name"); + expect(ipOrg).to.have.property("symbol"); + expect(ipOrg).to.have.property("owner"); + expect(ipOrg).to.have.property("ipAssetTypes"); + expect(ipOrg).to.have.property("createdAt"); + expect(ipOrg).to.have.property("txHash"); + + expect(ipOrg.id).to.be.a("string"); + expect(ipOrg.name).to.be.a("string"); + expect(ipOrg.symbol).to.be.a("string"); + expect(ipOrg.owner).to.be.a("string"); + expect(ipOrg.ipAssetTypes).to.be.an("array"); + expect(ipOrg.createdAt).to.be.a("string"); + expect(ipOrg.txHash).to.be.a("string"); + } +}); diff --git a/packages/core-sdk/test/integration/license.test.ts b/packages/core-sdk/test/integration/license.test.ts new file mode 100644 index 00000000..8e672fd1 --- /dev/null +++ b/packages/core-sdk/test/integration/license.test.ts @@ -0,0 +1,443 @@ +import { expect } from "chai"; +import { StoryClient, StoryConfig, Client } from "../../src"; +import { sepolia } from "viem/chains"; +import { http, parseGwei, PrivateKeyAccount, stringToHex } from "viem"; +import { privateKeyToAccount } from "viem/accounts"; + +import { + ConfigureLicenseRequest, + CreateLicenseRequest, + LicensorConfigEnum, +} from "../../src/types/resources/license"; + +describe("License Functions", () => { + let client: Client; + let senderAddress: string; + let wallet: PrivateKeyAccount; + + before(function () { + wallet = privateKeyToAccount(process.env.WALLET_PRIVATE_KEY as `0x${string}`); + + const config: StoryConfig = { + chain: sepolia, + transport: http(process.env.RPC_PROVIDER_URL), + account: wallet, + }; + + senderAddress = config.account.address; + client = StoryClient.newClient(config); + }); + + describe("Configuring license", async function () { + it("should be able to configure license with default values", async () => { + const waitForTransaction: boolean = true; + const createIpoResponse = await expect( + client.ipOrg.create({ + name: "Alice In Wonderland", + symbol: "AIW", + owner: senderAddress, + ipAssetTypes: ["Story", "Character"], + txOptions: { + waitForTransaction: waitForTransaction, + }, + }), + ).to.not.be.rejected; + expect(createIpoResponse.txHash).to.be.a("string"); + expect(createIpoResponse.txHash).not.empty; + expect(createIpoResponse.ipOrgId).to.be.a("string"); + expect(createIpoResponse.ipOrgId).not.empty; + + // Configure license + const configureLicenseRequest: ConfigureLicenseRequest = { + ipOrg: createIpoResponse.ipOrgId, + frameworkId: "SPUML-1.0", + params: [], + licensor: 1, + txOptions: { + waitForTransaction: true, + gasPrice: parseGwei("250"), + }, + }; + + const response = await client.license.configure(configureLicenseRequest); + + expect(response.txHash).to.be.a("string"); + expect(response.txHash).not.be.undefined; + + expect(response.success).to.be.true; + }); + it("should be able to configure with Attribution=true", async () => { + // 1. Create IPO first + // 2. Configure framework + // 3. Create license + + const createIpoResponse = await expect( + client.ipOrg.create({ + name: "Alice In Wonderland", + symbol: "AIW", + owner: senderAddress, + ipAssetTypes: ["Story", "Character"], + txOptions: { + waitForTransaction: true, + }, + }), + ).to.not.be.rejected; + expect(createIpoResponse.txHash).to.be.a("string"); + expect(createIpoResponse.txHash).not.empty; + expect(createIpoResponse.ipOrgId).to.be.a("string"); + expect(createIpoResponse.ipOrgId).not.empty; + + const attributionParam = { + tag: stringToHex("Attribution", { size: 32 }), + value: { + interface: "bool", + data: [true], + }, + }; + + const licenseParameters = [attributionParam]; + + // Configure license + const configureLicenseRequest: ConfigureLicenseRequest = { + ipOrg: createIpoResponse.ipOrgId, + frameworkId: "SPUML-1.0", + params: licenseParameters, + licensor: LicensorConfigEnum.Source, + txOptions: { + waitForTransaction: true, + gasPrice: parseGwei("250"), + }, + }; + + const configureResponse = await client.license.configure(configureLicenseRequest); + + expect(configureResponse.txHash).to.be.a("string"); + expect(configureResponse.txHash).not.be.undefined; + + expect(configureResponse.success).to.be.true; + }); + it("should be able to configure with Attribution=false", async () => { + // 1. Create IPO first + // 2. Configure framework + // 3. Create license + + const createIpoResponse = await expect( + client.ipOrg.create({ + name: "Alice In Wonderland", + symbol: "AIW", + owner: senderAddress, + ipAssetTypes: ["Story", "Character"], + txOptions: { + waitForTransaction: true, + }, + }), + ).to.not.be.rejected; + expect(createIpoResponse.txHash).to.be.a("string"); + expect(createIpoResponse.txHash).not.empty; + expect(createIpoResponse.ipOrgId).to.be.a("string"); + expect(createIpoResponse.ipOrgId).not.empty; + + const attributionParam = { + tag: stringToHex("Attribution", { size: 32 }), + value: { + interface: "bool", + data: [false], + }, + }; + + const licenseParameters = [attributionParam]; + + // Configure license + const configureLicenseRequest: ConfigureLicenseRequest = { + ipOrg: createIpoResponse.ipOrgId, + frameworkId: "SPUML-1.0", + params: licenseParameters, + licensor: LicensorConfigEnum.Source, + txOptions: { + waitForTransaction: true, + gasPrice: parseGwei("250"), + }, + }; + + const configureResponse = await client.license.configure(configureLicenseRequest); + + expect(configureResponse.txHash).to.be.a("string"); + expect(configureResponse.txHash).not.be.undefined; + + expect(configureResponse.success).to.be.true; + }); + it("should be able get txHash after configuring with Derivatives-Allowed=false", async () => { + // 1. Create IPO first + // 2. Configure framework + // 3. Create license + + const createIpoResponse = await expect( + client.ipOrg.create({ + name: "Alice In Wonderland", + symbol: "AIW", + owner: senderAddress, + ipAssetTypes: ["Story", "Character"], + txOptions: { + waitForTransaction: true, + }, + }), + ).to.not.be.rejected; + expect(createIpoResponse.txHash).to.be.a("string"); + expect(createIpoResponse.txHash).not.empty; + expect(createIpoResponse.ipOrgId).to.be.a("string"); + expect(createIpoResponse.ipOrgId).not.empty; + + const attributionParam = { + tag: stringToHex("Derivatives-Allowed", { size: 32 }), + value: { + interface: "bool", + data: [false], + }, + }; + + const licenseParameters = [attributionParam]; + + // Configure license + const configureLicenseRequest: ConfigureLicenseRequest = { + ipOrg: createIpoResponse.ipOrgId, + frameworkId: "SPUML-1.0", + params: licenseParameters, + licensor: LicensorConfigEnum.Source, + txOptions: { + waitForTransaction: false, + gasPrice: parseGwei("250"), + }, + }; + + const configureResponse = await client.license.configure(configureLicenseRequest); + + expect(configureResponse.txHash).to.be.a("string"); + expect(configureResponse.txHash).not.be.undefined; + }); + }); + + describe("License creation", async function () { + it("should be able to create an NFT with empty/default values", async () => { + // 1. Create IPO first + // 2. Configure framework + // 3. Create license + + const createIpoResponse = await expect( + client.ipOrg.create({ + name: "Alice In Wonderland", + symbol: "AIW", + owner: senderAddress, + ipAssetTypes: ["Story", "Character"], + txOptions: { + waitForTransaction: true, + }, + }), + ).to.not.be.rejected; + expect(createIpoResponse.txHash).to.be.a("string"); + expect(createIpoResponse.txHash).not.empty; + expect(createIpoResponse.ipOrgId).to.be.a("string"); + expect(createIpoResponse.ipOrgId).not.empty; + + // Configure license + const configureLicenseRequest: ConfigureLicenseRequest = { + ipOrg: createIpoResponse.ipOrgId, + frameworkId: "", + params: [], + licensor: 1, + txOptions: { + waitForTransaction: true, + gasPrice: parseGwei("250"), + // numBlockConfirmations: 1, + }, + }; + + const configureResponse = await client.license.configure(configureLicenseRequest); + + expect(configureResponse.txHash).to.be.a("string"); + expect(configureResponse.txHash).not.be.undefined; + + expect(configureResponse.success).to.be.true; + + const createLicenseRequest: CreateLicenseRequest = { + ipOrgId: createIpoResponse.ipOrgId, + params: [], + parentLicenseId: "0", + ipaId: "0", + preHookData: [], + postHookData: [], + txOptions: { + waitForTransaction: true, + gasPrice: parseGwei("250"), + // numBlockConfirmations: 1, + }, + }; + + const response = await expect(client.license.create(createLicenseRequest)).to.not.be.rejected; + + expect(response.txHash).to.be.a("string"); + expect(response.txHash).not.be.undefined; + + expect(response.licenseId).to.be.a("string"); + expect(response.licenseId).not.be.undefined; + }); + it("should be able to create an NFT with non-default license parameters", async () => { + // 1. Create IPO first + // 2. Configure framework + // 3. Create license + + const createIpoResponse = await expect( + client.ipOrg.create({ + name: "Alice In Wonderland", + symbol: "AIW", + owner: senderAddress, + ipAssetTypes: ["Story", "Character"], + txOptions: { + waitForTransaction: true, + }, + }), + ).to.not.be.rejected; + expect(createIpoResponse.txHash).to.be.a("string"); + expect(createIpoResponse.txHash).not.empty; + expect(createIpoResponse.ipOrgId).to.be.a("string"); + expect(createIpoResponse.ipOrgId).not.empty; + + // const attributionParam = { + // tag: "Attribution", + // value: { + // interface: "bool", + // data: [true], + // }, + // }; + const derivativesParam = { + tag: stringToHex("Derivatives-Allowed", { size: 32 }), + value: { + interface: "bool", + data: [false], + }, + }; + // const licenseParameters = [attributionParam]; + const licenseParameters = [derivativesParam]; + + // Configure license + const configureLicenseRequest: ConfigureLicenseRequest = { + ipOrg: createIpoResponse.ipOrgId, + frameworkId: "SPUML-1.0", + params: licenseParameters, + licensor: LicensorConfigEnum.Source, + txOptions: { + waitForTransaction: true, + gasPrice: parseGwei("250"), + numBlockConfirmations: 2, + }, + }; + + const configureResponse = await client.license.configure(configureLicenseRequest); + + expect(configureResponse.txHash).to.be.a("string"); + expect(configureResponse.txHash).not.be.undefined; + + expect(configureResponse.success).to.be.true; + + const createLicenseRequest: CreateLicenseRequest = { + ipOrgId: createIpoResponse.ipOrgId, + params: [], + parentLicenseId: "0", + ipaId: "0", + preHookData: [], + postHookData: [], + txOptions: { + waitForTransaction: true, + gasPrice: parseGwei("250"), + numBlockConfirmations: 2, + }, + }; + + const response = await expect(client.license.create(createLicenseRequest)).to.not.be.rejected; + + expect(response.txHash).to.be.a("string"); + expect(response.txHash).not.be.undefined; + + expect(response.licenseId).to.be.a("string"); + expect(response.licenseId).not.be.undefined; + }); + it.skip("should be able to create an NFT with 'Attribution'=true", async () => { + // 1. Create IPO first + // 2. Configure framework + // 3. Create license + + const createIpoResponse = await expect( + client.ipOrg.create({ + name: "Alice In Wonderland", + symbol: "AIW", + owner: senderAddress, + ipAssetTypes: ["Story", "Character"], + txOptions: { + waitForTransaction: true, + }, + }), + ).to.not.be.rejected; + expect(createIpoResponse.txHash).to.be.a("string"); + expect(createIpoResponse.txHash).not.empty; + expect(createIpoResponse.ipOrgId).to.be.a("string"); + expect(createIpoResponse.ipOrgId).not.empty; + + // const attributionParam = { + // tag: "Attribution", + // value: { + // interface: "bool", + // data: [true], + // }, + // }; + const derivativesParam = { + tag: stringToHex("Derivatives-Allowed", { size: 32 }), + value: { + interface: "bool", + data: [false], + }, + }; + // const licenseParameters = [attributionParam, derivativesParam]; + const licenseParameters = [derivativesParam]; + + // Configure license + const configureLicenseRequest: ConfigureLicenseRequest = { + ipOrg: createIpoResponse.ipOrgId, + frameworkId: "SPUML-1.0", + params: licenseParameters, + licensor: LicensorConfigEnum.Source, + txOptions: { + waitForTransaction: true, + gasPrice: parseGwei("250"), + }, + }; + + const configureResponse = await client.license.configure(configureLicenseRequest); + + expect(configureResponse.txHash).to.be.a("string"); + expect(configureResponse.txHash).not.be.undefined; + + expect(configureResponse.success).to.be.true; + + const createLicenseRequest: CreateLicenseRequest = { + ipOrgId: createIpoResponse.ipOrgId, + params: [], + parentLicenseId: "0", + ipaId: "0", + preHookData: [], + postHookData: [], + txOptions: { + waitForTransaction: true, + gasPrice: parseGwei("250"), + numBlockConfirmations: 2, + }, + }; + + const response = await expect(client.license.create(createLicenseRequest)).to.not.be.rejected; + + expect(response.txHash).to.be.a("string"); + expect(response.txHash).not.be.undefined; + + expect(response.licenseId).to.be.a("string"); + expect(response.licenseId).not.be.undefined; + }); + }); +}); diff --git a/packages/core-sdk/test/integration/licenseReadOnly.test.ts b/packages/core-sdk/test/integration/licenseReadOnly.test.ts new file mode 100644 index 00000000..f5a23524 --- /dev/null +++ b/packages/core-sdk/test/integration/licenseReadOnly.test.ts @@ -0,0 +1,130 @@ +import { expect } from "chai"; +import { StoryClient, StoryReadOnlyConfig, ListLicenseRequest, License } from "../../src/index"; +import { ReadOnlyClient } from "../../src/types/client"; +import { + Param, + LicenseParams, + ListLicenseParamsRequest, + ListLicenseParamsResponse, + FormattedLicenseParams, +} from "../../src/types/resources/license"; + +describe("License Read Only Functions", () => { + let client: ReadOnlyClient; + + before(async function () { + const config: StoryReadOnlyConfig = {}; + client = StoryClient.newReadOnlyClient(config); + }); + + describe("Get License", async function () { + it("should return a license when the license id is valid", async function () { + const response = await client.license.get({ + licenseId: process.env.TEST_LICENSE_ID as string, + }); + + expect(response).to.have.property("license"); + expectLicenseFields(response.license); + }); + + it("should handle errors when retrieving a license", async function () { + return expect( + client.license.get({ + licenseId: "invalid_id", // Provide an invalid license ID + }), + ).to.be.rejected; + }); + }); + + describe("List Licenses", async function () { + it("should list all licenses", async () => { + const mockListLicenseRequest: ListLicenseRequest = { + ipOrgId: process.env.TEST_IPORG_ID as string, + ipAssetId: process.env.TEST_IPASSET_ID2 as string, + }; + const response = await client.license.list(mockListLicenseRequest); + + expect(response).to.have.property("licenses"); + expect(response.licenses).to.be.an("array"); + expect(response.licenses.length).to.gt(0); + expectLicenseFields(response.licenses[0]); + }); + + it("should handle errors when listing licenses", async () => { + const mockListLicenseRequest: ListLicenseRequest = { + ipOrgId: "aaaaj", + ipAssetId: "aa", + }; + return expect(client.license.list(mockListLicenseRequest)).to.be.rejected; + }); + }); + + describe("List Licenses Params", async function () { + it("should list all license params", async () => { + const mockListLicenseParamsRequest: ListLicenseParamsRequest = { + ipOrgId: process.env.TEST_IPORG_ID as string, + }; + const response: ListLicenseParamsResponse = await client.license.listParams( + mockListLicenseParamsRequest, + ); + + expect(response).to.have.property("licenseParams"); + expectLicenseParamsFields(response.licenseParams[0]); + }); + + it("should handle errors when listing licenses", async () => { + const mockListLicenseParamsRequest: ListLicenseParamsRequest = { + ipOrgId: "aaaaj", + }; + return expect(client.license.list(mockListLicenseParamsRequest)).to.be.rejected; + }); + }); + + function expectLicenseFields(license: License) { + expect(license).to.have.property("id"); + expect(license).to.have.property("isReciprocal"); + expect(license).to.have.property("derivativeNeedsApproval"); + expect(license).to.have.property("derivativesAllowed"); + expect(license).to.have.property("status"); + expect(license).to.have.property("licensor"); + expect(license).to.have.property("revoker"); + expect(license).to.have.property("ipOrgId"); + expect(license).to.have.property("ipAssetId"); + expect(license).to.have.property("parentLicenseId"); + expect(license).to.have.property("createdAt"); + expect(license).to.have.property("txHash"); + + expect(license.id).to.be.a("string"); + expect(license.isReciprocal).to.be.a("boolean"); + expect(license.derivativeNeedsApproval).to.be.a("boolean"); + expect(license.derivativesAllowed).to.be.a("boolean"); + expect(license.status).to.be.a("number"); + expect(license.licensor).to.be.an("string"); + expect(license.revoker).to.be.an("string"); + expect(license.ipOrgId).to.be.an("string"); + expect(license.ipAssetId).to.be.an("string"); + expect(license.parentLicenseId).to.be.an("string"); + expect(license.createdAt).to.be.a("string"); + expect(license.txHash).to.be.a("string"); + } + + function expectLicenseParamsFields(licenseParams: FormattedLicenseParams) { + expect(licenseParams).to.have.property("ipOrgId"); + expect(licenseParams).to.have.property("frameworkId"); + expect(licenseParams).to.have.property("url"); + expect(licenseParams).to.have.property("licensorConfig"); + expect(licenseParams).to.have.property("params"); + expect(licenseParams).to.have.property("createdAt"); + expect(licenseParams).to.have.property("txHash"); + + expect(licenseParams.ipOrgId).to.be.a("string"); + expect(licenseParams.frameworkId).to.be.a("string"); + expect(licenseParams.url).to.be.a("string"); + expect(licenseParams.licensorConfig).to.be.a("number"); + expect(licenseParams.params).to.be.an("array"); + expect(licenseParams.params[0].tag).to.be.an("string"); + expect(licenseParams.params[0].value).to.be.an("array"); + expect(licenseParams.params[0].type).to.be.an("string"); + expect(licenseParams.createdAt).to.be.an("string"); + } +}); diff --git a/packages/core-sdk/test/integration/moduleReadOnly.test.ts b/packages/core-sdk/test/integration/moduleReadOnly.test.ts new file mode 100644 index 00000000..78106a8c --- /dev/null +++ b/packages/core-sdk/test/integration/moduleReadOnly.test.ts @@ -0,0 +1,96 @@ +import { expect } from "chai"; +import { + StoryClient, + StoryReadOnlyConfig, + GetModuleRequest, + ListModuleRequest, + ReadOnlyClient, +} from "../../src"; + +describe("Module client integration tests", () => { + let client: ReadOnlyClient; + + beforeEach(function () { + const config: StoryReadOnlyConfig = {}; + + client = StoryClient.newReadOnlyClient(config); + }); + + describe("List Modules", async function () { + it("should return array of all modules", async () => { + const req = { + options: { + pagination: { + limit: 10, + offset: 0, + }, + }, + } as ListModuleRequest; + + const response = await client.module.list(req); + + expect(response).to.have.property("modules"); + expect(response.modules).to.be.an("array"); + + const module1 = response.modules[0]; + expect(module1).to.have.property("id"); + expect(module1).to.have.property("ipOrgId"); + expect(module1).to.have.property("moduleKey"); + expect(module1.id).to.be.a("string"); + expect(module1.ipOrgId).to.be.a("string"); + expect(module1.moduleKey).to.be.a("string"); + }); + + it("should return array of limited amount of modules", async () => { + const req = { + options: { + pagination: { + limit: 1, + offset: 0, + }, + }, + } as ListModuleRequest; + + const response = await client.module.list(req); + + expect(response).to.have.property("modules"); + expect(response.modules).to.be.an("array"); + expect(response.modules.length).to.equal(1); + }); + + it("should return a list of modules successfully without options", async () => { + const response = await client.module.list(); + expect(response).is.not.null; + expect(response.modules.length).to.gt(0); + }); + + it("should return a list of modules if the options are invalid", async () => { + const options = { + options: {}, + } as ListModuleRequest; + const response = await client.module.list(options); + expect(response).is.not.null; + expect(response.modules.length).to.gt(0); + }); + }); + + describe("Get Module", async function () { + it("should return a module based on the module id", async () => { + const req = { + moduleId: process.env.TEST_MODULE_ID as string, + } as GetModuleRequest; + + const response = await client.module.get(req); + + expect(response).to.have.property("module"); + + const module = response.module; + expect(module).to.have.property("id"); + expect(module).to.have.property("ipOrgId"); + expect(module).to.have.property("moduleKey"); + expect(module.id).to.be.a("string"); + expect(module.ipOrgId).to.be.a("string"); + expect(module.moduleKey).to.be.a("string"); + }); + }); +}); diff --git a/packages/core-sdk/test/integration/platform.test.ts b/packages/core-sdk/test/integration/platform.test.ts new file mode 100644 index 00000000..0d235c8a --- /dev/null +++ b/packages/core-sdk/test/integration/platform.test.ts @@ -0,0 +1,32 @@ +import { expect } from "chai"; +import { StoryClient, StoryConfig, Client } from "../../src"; +import { createFileReaderMock } from "../unit/testUtils"; +import { goerli } from "viem/chains"; +import { Hex, http } from "viem"; +import { privateKeyToAccount } from "viem/accounts"; + +describe("Platform client integration tests", () => { + let client: Client; + before(() => { + global.FileReader = createFileReaderMock( + "data:base64,dGVzdCBzdHJpbmcgYmxvYg==", + new Event("onload") as unknown as ProgressEvent, + ) as any; + }); + + beforeEach(function () { + const config: StoryConfig = { + chain: goerli, + transport: http(process.env.RPC_PROVIDER_URL), + account: privateKeyToAccount((process.env.WALLET_PRIVATE_KEY || "0x") as Hex), + }; + + client = StoryClient.newClient(config); + }); + + it("should return arweave url when a buffer file is uploaded to arweave", async () => { + const response = await client.platform.uploadFile(Buffer.from("test"), "image/png"); + expect(response).to.have.property("uri"); + expect(response.uri).to.be.a("string"); + }); +}); diff --git a/packages/core-sdk/test/integration/relationship.test.ts b/packages/core-sdk/test/integration/relationship.test.ts new file mode 100644 index 00000000..aa251c43 --- /dev/null +++ b/packages/core-sdk/test/integration/relationship.test.ts @@ -0,0 +1,46 @@ +import { expect } from "chai"; +import { StoryClient, StoryConfig, Client, RegisterRelationshipRequest } from "../../src"; +import { privateKeyToAccount } from "viem/accounts"; +import { Hex, http } from "viem"; +import { sepolia } from "viem/chains"; + +describe("Relationship Functions", function () { + let client: Client; + + before(function () { + const config: StoryConfig = { + chain: sepolia, + transport: http(process.env.RPC_PROVIDER_URL), + account: privateKeyToAccount((process.env.WALLET_PRIVATE_KEY || "0x") as Hex), + }; + + client = StoryClient.newClient(config); + }); + + describe("Register", async function () { + it("should create a relationship and return txHash", async function () { + const waitForTransaction: boolean = true; + const mockRegisterRequest: RegisterRelationshipRequest = { + ipOrgId: process.env.TEST_IPORG_ID as string, + relType: process.env.TEST_RELATIONSHIP_TYPE as string, + srcContract: process.env.NEXT_PUBLIC_IP_ASSET_REGISTRY_CONTRACT as string, + srcTokenId: process.env.TEST_IPASSET_ID1 as string, + dstContract: process.env.NEXT_PUBLIC_IP_ASSET_REGISTRY_CONTRACT as string, + dstTokenId: process.env.TEST_IPASSET_ID2 as string, + preHookData: [], + postHookData: [], + txOptions: { + waitForTransaction: waitForTransaction, + }, + }; + + const response = await expect(client.relationship.register(mockRegisterRequest)).to.not.be + .rejected; + + expect(response.txHash).to.exist.and.be.a("string").and.not.be.empty; + if (waitForTransaction) { + expect(response.relationshipId).to.exist.and.be.a("string"); + } + }); + }); +}); diff --git a/packages/core-sdk/test/integration/relationshipReadOnly.test.ts b/packages/core-sdk/test/integration/relationshipReadOnly.test.ts new file mode 100644 index 00000000..af328062 --- /dev/null +++ b/packages/core-sdk/test/integration/relationshipReadOnly.test.ts @@ -0,0 +1,92 @@ +import { expect } from "chai"; +import { + StoryClient, + StoryReadOnlyConfig, + ReadOnlyClient, + ListRelationshipRequest, + Relationship, +} from "../../src"; + +describe("Relationship Read Only Functions", function () { + let client: ReadOnlyClient; + + before(async function () { + const config: StoryReadOnlyConfig = {}; + client = StoryClient.newReadOnlyClient(config); + }); + + describe("Get Relationship", async function () { + it("should retrieve a relationship by its ID", async function () { + const response = await expect( + client.relationship.get({ + relationshipId: process.env.TEST_RELATIONSHIP_ID as string, // Provide a valid ID + }), + ).to.not.be.rejected; + expect(response).to.have.property("relationship"); + expectRelationshipFields(response.relationship); + }); + + it("should throw errors when retrieving an invalid relationship", async function () { + return expect( + client.relationship.get({ + relationshipId: "invalid_id", // Provide an invalid ID + }), + ).to.be.rejected; + }); + }); + + describe("List Relationships", async function () { + it("should list all relationships", async function () { + const mockListRelationshipRequest: ListRelationshipRequest = { + tokenId: process.env.TEST_IPASSET_ID2 as string, + contract: process.env.NEXT_PUBLIC_IP_ASSET_REGISTRY_CONTRACT as string, + options: { + pagination: { + limit: 1, + offset: 0, + }, + }, + }; + const response = await client.relationship.list(mockListRelationshipRequest); + + expect(response).to.have.property("relationships"); + expect(response.relationships).to.be.an("array"); + expect(response.relationships.length).to.gt(0); + expectRelationshipFields(response.relationships[0]); + }); + + it("should handle errors when listing licenses with invalid id", async function () { + const mockInvalidListRelationshipRequest: ListRelationshipRequest = { + tokenId: "aaa", + contract: process.env.NEXT_PUBLIC_IP_ASSET_REGISTRY_CONTRACT as string, + options: { + pagination: { + limit: 1, + offset: 0, + }, + }, + }; + return expect(client.relationship.list(mockInvalidListRelationshipRequest)).to.be.rejected; + }); + }); + + function expectRelationshipFields(relationship: Relationship) { + expect(relationship).to.have.property("id"); + expect(relationship).to.have.property("type"); + expect(relationship).to.have.property("srcContract"); + expect(relationship).to.have.property("srcTokenId"); + expect(relationship).to.have.property("dstContract"); + expect(relationship).to.have.property("dstTokenId"); + expect(relationship).to.have.property("registeredAt"); + expect(relationship).to.have.property("txHash"); + + expect(relationship.id).to.be.a("string"); + expect(relationship.type).to.be.a("string"); + expect(relationship.srcContract).to.be.a("string"); + expect(relationship.srcTokenId).to.be.a("string"); + expect(relationship.dstContract).to.be.a("string"); + expect(relationship.dstTokenId).to.be.a("string"); + expect(relationship.registeredAt).to.be.a("string"); + expect(relationship.txHash).to.be.a("string"); + } +}); diff --git a/packages/core-sdk/test/integration/relationshipType.test.ts b/packages/core-sdk/test/integration/relationshipType.test.ts new file mode 100644 index 00000000..19a2437f --- /dev/null +++ b/packages/core-sdk/test/integration/relationshipType.test.ts @@ -0,0 +1,51 @@ +import { expect } from "chai"; +import { + StoryClient, + StoryConfig, + Client, + RegisterRelationshipTypeRequest, + Relatables, +} from "../../src"; +import { privateKeyToAccount } from "viem/accounts"; +import { Hex, http } from "viem"; +import { sepolia } from "viem/chains"; + +describe("Relationship Type Functions", function () { + let client: Client; + + before(function () { + const config: StoryConfig = { + chain: sepolia, + transport: http(process.env.RPC_PROVIDER_URL), + account: privateKeyToAccount((process.env.WALLET_PRIVATE_KEY || "0x") as Hex), + }; + + client = StoryClient.newClient(config); + }); + + describe("RegisterType", async function () { + it("should create a relationship type and return txHash", async function () { + const waitForTransaction: boolean = true; + const mockRegisterTypeRequest: RegisterRelationshipTypeRequest = { + ipOrgId: process.env.TEST_IPORG_ID as string, + relType: process.env.TEST_RELATIONSHIP_TYPE as string, + relatedElements: { + src: Relatables.IPA, + dst: Relatables.IPA, + }, + allowedSrcIpAssetTypes: [1], + allowedDstIpAssetTypes: [1], + txOptions: { + waitForTransaction: waitForTransaction, + }, + }; + const response = await expect(client.relationshipType.register(mockRegisterTypeRequest)).to + .not.be.rejected; + + expect(response.txHash).to.exist.and.be.a("string").and.not.be.empty; + if (waitForTransaction) { + expect(response.success).to.exist.and.be.true; + } + }); + }); +}); diff --git a/packages/core-sdk/test/integration/relationshipTypeReadOnly.test.ts b/packages/core-sdk/test/integration/relationshipTypeReadOnly.test.ts new file mode 100644 index 00000000..6e5324a4 --- /dev/null +++ b/packages/core-sdk/test/integration/relationshipTypeReadOnly.test.ts @@ -0,0 +1,94 @@ +import { expect } from "chai"; +import { + ReadOnlyClient, + StoryClient, + StoryReadOnlyConfig, + RelationshipType, + ListRelationshipTypesRequest, +} from "../../src"; + +describe("Relationship Type Read Only Functions", function () { + let client: ReadOnlyClient; + + before(async function () { + const config: StoryReadOnlyConfig = {}; + client = StoryClient.newReadOnlyClient(config); + }); + + describe("Get Relationship Type", () => { + it("should retrieve a relationship type by both ipOrgId and relType", async function () { + const response = await expect( + client.relationshipType.get({ + ipOrgId: process.env.TEST_IPORG_ID as string, + relType: process.env.TEST_RELATIONSHIP_TYPE as string, + }), + ).to.not.be.rejected; + + expect(response).to.have.property("relationshipType"); + expectRelationshipTypeFields(response.relationshipType); + }); + + it("should handle errors when retrieving a relationship type with invalid ipOrgId", async function () { + return expect( + client.relationshipType.get({ + ipOrgId: "0xde493e03d2de1cd7820b4f580beced57296b0009", + relType: process.env.TEST_RELATIONSHIP_TYPE as string, + }), + ).to.be.rejected; + }); + }); + + describe("List Relationship Types", async function () { + const mockListRelationshipTypeRequest: ListRelationshipTypesRequest = { + ipOrgId: process.env.TEST_IPORG_ID as string, + options: { + pagination: { + limit: 10, + offset: 0, + }, + }, + }; + + it("should list all relationship types", async function () { + const response = await expect(client.relationshipType.list(mockListRelationshipTypeRequest)) + .to.not.be.rejected; + + expect(response).to.have.property("relationshipTypes"); + expect(response.relationshipTypes).to.be.an("array"); + expect(response.relationshipTypes.length).to.be.gt(0); + expectRelationshipTypeFields(response.relationshipTypes[0]); + }); + + it("should handle errors when listing relationship types with invalid input", async function () { + return expect( + client.relationshipType.list({ + ipOrgId: "0xb422e54932c1dae83e78267a4dd2805aa64a806", + }), + ).to.be.rejected; + }); + }); + + function expectRelationshipTypeFields(relationshipType: RelationshipType) { + expect(relationshipType).to.have.property("type"); + expect(relationshipType).to.have.property("ipOrgId"); + expect(relationshipType).to.have.property("srcContract"); + expect(relationshipType).to.have.property("srcRelatable"); + expect(relationshipType).to.have.property("srcSubtypesMask"); + expect(relationshipType).to.have.property("dstContract"); + expect(relationshipType).to.have.property("dstRelatable"); + expect(relationshipType).to.have.property("dstSubtypesMask"); + expect(relationshipType).to.have.property("registeredAt"); + expect(relationshipType).to.have.property("txHash"); + + expect(relationshipType.type).to.be.a("string"); + expect(relationshipType.ipOrgId).to.be.a("string"); + expect(relationshipType.srcContract).to.be.a("string"); + expect(relationshipType.srcRelatable).to.be.a("number"); + expect(relationshipType.srcSubtypesMask).to.be.a("number"); + expect(relationshipType.dstContract).to.be.a("string"); + expect(relationshipType.dstRelatable).to.be.a("number"); + expect(relationshipType.dstSubtypesMask).to.be.a("number"); + expect(relationshipType.registeredAt).to.be.a("string"); + expect(relationshipType.txHash).to.be.a("string"); + } +}); diff --git a/packages/core-sdk/test/integration/transactionReadOnly.test.ts b/packages/core-sdk/test/integration/transactionReadOnly.test.ts new file mode 100644 index 00000000..d28dc8d7 --- /dev/null +++ b/packages/core-sdk/test/integration/transactionReadOnly.test.ts @@ -0,0 +1,86 @@ +import { expect } from "chai"; +import { + StoryClient, + StoryReadOnlyConfig, + ReadOnlyClient, + ListTransactionRequest, + ResourceType, + Transaction, +} from "../../src"; + +describe("Transaction client integration tests", function () { + let client: ReadOnlyClient; + + before(async function () { + const config: StoryReadOnlyConfig = {}; + client = StoryClient.newReadOnlyClient(config); + }); + + describe("List Transactions", async function () { + it("should return array of transactions", async function () { + const req = { + options: { + limit: 10, + offset: 0, + }, + } as ListTransactionRequest; + + const response = await client.transaction.list(req); + expect(response).to.have.property("transactions"); + expect(response.transactions).to.be.an("array"); + expect(response.transactions.length).to.gt(0); + expectTransactionFields(response.transactions[0]); + }); + + it("should return a list of transactions successfully without options", async function () { + const response = await client.transaction.list(); + + expect(response).to.have.property("transactions"); + expect(response.transactions).to.be.an("array"); + expect(response.transactions.length).to.gt(0); + expectTransactionFields(response.transactions[0]); + }); + + it("should return a list of transactions if the options are invalid", async function () { + const options = { + options: {}, + } as ListTransactionRequest; + const response = await client.transaction.list(options); + + expect(response).to.have.property("transactions"); + expect(response.transactions).to.be.an("array"); + expect(response.transactions.length).to.gt(0); + expectTransactionFields(response.transactions[0]); + }); + }); + + describe("Get Transaction", async function () { + it("should return transaction from request transaction id", async function () { + const response = await client.transaction.get({ + transactionId: process.env.TEST_TRANSACTION_ID as string, + }); + + expect(response).to.have.property("transaction"); + expectTransactionFields(response.transaction); + }); + }); + + function expectTransactionFields(transaction: Transaction) { + expect(transaction).to.have.property("id"); + expect(transaction).to.have.property("txHash"); + expect(transaction).to.have.property("createdAt"); + expect(transaction).to.have.property("initiator"); + expect(transaction).to.have.property("resourceType"); + expect(transaction).to.have.property("resourceId"); + if (transaction.resourceType !== ResourceType.Relationship.valueOf()) { + expect(transaction).to.have.property("ipOrgId"); + expect(transaction.ipOrgId).to.be.a("string"); + } + expect(transaction.id).to.be.a("string"); + expect(transaction.txHash).to.be.a("string"); + expect(transaction.createdAt).to.be.a("string"); + expect(transaction.initiator).to.be.a("string"); + expect(transaction.resourceType).to.be.a("string"); + expect(transaction.resourceId).to.be.a("string"); + } +}); diff --git a/packages/core-sdk/test/unit/client.test.ts b/packages/core-sdk/test/unit/client.test.ts new file mode 100644 index 00000000..2453a001 --- /dev/null +++ b/packages/core-sdk/test/unit/client.test.ts @@ -0,0 +1,130 @@ +import { expect } from "chai"; +import { StoryClient, Client, ReadOnlyClient } from "../../src"; +import { privateKeyToAccount, generatePrivateKey } from "viem/accounts"; +import { Account } from "viem"; + +describe("Test StoryClient", function () { + describe("Test constructor", function () { + it("should succeed when passing in valid params", function () { + try { + StoryClient.newClient({ + account: privateKeyToAccount(generatePrivateKey()), + }); + } catch (error) { + expect.fail(`Function should not have thrown any error, but it threw: ${error}`); + } + }); + + it("throw error when wallet account is null", function () { + try { + StoryClient.newClient({ + account: null as any as Account, + }); + expect.fail(`Function should not get here, it should throw an error `); + } catch (error) {} + }); + }); + + describe("Test getters", function () { + let client: Client; + let clientRO: ReadOnlyClient; + + beforeEach(function () { + client = StoryClient.newClient({ + account: privateKeyToAccount(generatePrivateKey()), + }); + clientRO = StoryClient.newReadOnlyClient({}); + }); + + describe("Test ipOrg getter", function () { + it("should return the same ipOrg when every time it's called", function () { + const ipOrg1 = client.ipOrg; + const ipOrg2 = client.ipOrg; + expect(ipOrg1).to.be.equal(ipOrg2); + }); + }); + + describe("Test IP Asset getter", function () { + it("should return the same ipOrg when every time it's called", function () { + const ipAsset1 = client.ipAsset; + const ipAsset2 = client.ipAsset; + expect(ipAsset1).to.be.equal(ipAsset2); + }); + }); + + describe("Test license getter", function () { + it("should return the same license when every time it's called", function () { + const license1 = client.license; + const license2 = client.license; + expect(license1).to.be.equal(license2); + }); + }); + + describe("Test transactions getter", function () { + it("should return the same transaction client when every time it's called", function () { + const transaction1 = client.transaction; + const transaction2 = client.transaction; + expect(transaction1).to.be.equal(transaction2); + }); + }); + + describe("Test relationship getter", function () { + it("should return the same relationship when every time it's called", function () { + const relationship1 = client.relationship; + const relationship2 = client.relationship; + expect(relationship1).to.be.equal(relationship2); + }); + }); + + describe("Test relationship type getter", function () { + it("should return the same relationship type when every time it's called", function () { + const relationshipType1 = client.relationshipType; + const relationshipType2 = client.relationshipType; + expect(relationshipType1).to.be.equal(relationshipType2); + }); + }); + + describe("Test platform getter", function () { + it("should return the same platform when every time it's called", function () { + const platform1 = client.platform; + const platform2 = client.platform; + expect(platform1).to.be.equal(platform2); + }); + }); + + describe("Test module getter", function () { + it("should return the same module when every time it's called", function () { + const module1 = client.module; + const module2 = client.module; + expect(module1).to.be.equal(module2); + + const moduleRO1 = clientRO.module; + const moduleRO2 = clientRO.module; + expect(moduleRO1).to.be.equal(moduleRO2); + }); + }); + + describe("Test hook getter", function () { + it("should return the same hook when every time it's called", function () { + const hook1 = client.hook; + const hook2 = client.hook; + expect(hook1).to.be.equal(hook2); + + const hookRO1 = clientRO.hook; + const hookRO2 = clientRO.hook; + expect(hookRO1).to.be.equal(hookRO2); + }); + }); + }); + + // describe("Test ipOrg getter w/o creating a client", function () { + // let client: Client; + // it("should throw error when a client hasn't been created", function () { + // try { + // client.ipOrg; + + // expect.fail(`You haven't created a client yet.`); + // } catch (error) {} + // }); + // }); +}); diff --git a/packages/core-sdk/test/unit/clientReadOnly.test.ts b/packages/core-sdk/test/unit/clientReadOnly.test.ts new file mode 100644 index 00000000..26f4f534 --- /dev/null +++ b/packages/core-sdk/test/unit/clientReadOnly.test.ts @@ -0,0 +1,114 @@ +import { expect } from "chai"; +import { StoryClient, ReadOnlyClient } from "../../src"; +import { fantom } from "viem/chains"; +import { http } from "viem"; + +describe("Test StoryReadOnlyClient", function () { + describe("Test constructor", function () { + it("should succeed when passing in valid params", function () { + try { + StoryClient.newReadOnlyClient({}); + } catch (error) { + expect.fail(`Function should not have thrown any error, but it threw: ${error}`); + } + }); + + it("should succeed when passing in valid params w/ provider", function () { + try { + StoryClient.newReadOnlyClient({ + chain: fantom, + transport: http(process.env.RPC_PROVIDER_URL), + }); + } catch (error) { + expect.fail(`Function should not have thrown any error, but it threw: ${error}`); + } + }); + }); + + describe("Test getters", function () { + let client: ReadOnlyClient; + + beforeEach(function () { + client = StoryClient.newReadOnlyClient({}); + }); + + describe("Test franchise getter", function () { + it("should return the same franchise when every time it's called", function () { + const franchise1 = client.ipOrg; + const franchise2 = client.ipOrg; + expect(franchise1).to.be.equal(franchise2); + }); + }); + + describe("Test IP Asset getter", function () { + it("should return the same franchise when every time it's called", function () { + const ipAsset1 = client.ipAsset; + const ipAsset2 = client.ipAsset; + expect(ipAsset1).to.be.equal(ipAsset2); + }); + }); + + describe("Test license getter", function () { + it("should return the same license when every time it's called", function () { + const license1 = client.license; + const license2 = client.license; + expect(license1).to.be.equal(license2); + }); + }); + + describe("Test transactions getter", function () { + it("should return the same transaction client when every time it's called", function () { + const transaction1 = client.transaction; + const transaction2 = client.transaction; + expect(transaction1).to.be.equal(transaction2); + }); + }); + + describe("Test relationship getter", function () { + it("should return the same relationship when every time it's called", function () { + const relationship1 = client.relationship; + const relationship2 = client.relationship; + expect(relationship1).to.be.equal(relationship2); + }); + }); + + describe("Test relationship type getter", function () { + it("should return the same relationship when every time it's called", function () { + const relationshipType1 = client.relationshipType; + const relationshipType2 = client.relationshipType; + expect(relationshipType1).to.be.equal(relationshipType2); + }); + }); + }); + + // describe("Test getters w/ provider", function () { + // let client: ReadOnlyClient; + + // beforeEach(function () { + // client = StoryClient.newReadOnlyClient({ + // environment: Environment.TEST, + // provider: new providers.JsonRpcProvider(), + // }); + // }); + + // describe("Test franchise getter w/ provider", function () { + // it("should return the same franchise when every time it's called", function () { + // const franchise1 = client.franchise; + // const franchise2 = client.franchise; + // expect(franchise1).to.be.equal(franchise2); + // }); + // }); + // }); + + // describe("Test franchise getter w/o creating a client", function () { + // let client: ReadOnlyClient; + + // it("should throw error when a client hasn't been created", function () { + // try { + // client.franchise; + + // expect.fail(`You haven't created a client yet.`); + // } catch (error) {} + // }); + // }); +}); diff --git a/packages/core-sdk/test/unit/resources/hookReadOnly.test.ts b/packages/core-sdk/test/unit/resources/hookReadOnly.test.ts new file mode 100644 index 00000000..20f99db7 --- /dev/null +++ b/packages/core-sdk/test/unit/resources/hookReadOnly.test.ts @@ -0,0 +1,191 @@ +import { expect } from "chai"; +import { HookReadOnlyClient, HookType } from "../../../src"; +import { AxiosInstance } from "axios"; +import { createMock } from "../testUtils"; +import * as sinon from "sinon"; +import chai from "chai"; +import chaiAsPromised from "chai-as-promised"; +import { PublicClient } from "viem"; + +chai.use(chaiAsPromised); + +describe("Test HookReadOnlyClient", function () { + let hookClient: HookReadOnlyClient; + let axiosMock: AxiosInstance; + let rpcMock: PublicClient; + + beforeEach(function () { + axiosMock = createMock(); + rpcMock = createMock(); + hookClient = new HookReadOnlyClient(axiosMock, rpcMock); + }); + + afterEach(function () { + sinon.restore(); + }); + + describe("Test hookClient.get", function () { + it("should return hook when the hook id is valid", async function () { + const expectedHook = { + id: "0xc0f6e387ac0b324ec18eacf22ee7271207dce3d5", + moduleId: "0x091e5f55135155bb8cb5868adb39e5c34eb32cfd", + registryKey: "0xac909466a23bec9adaf8b5f1cdfec2fb87df8a07765d813250eee97ecd862dcf", + registeredAt: "1700289864", + txHash: "0xfe06c299ab53f44a98e925d4d50904783284de80d105afc3ab73b2908322fe93", + hookType: HookType.PostAction, + }; + + axiosMock.get = sinon.stub().returns({ + data: { + hook: expectedHook, + }, + }); + + const response = await hookClient.get({ + hookId: "0xc0f6e387ac0b324ec18eacf22ee7271207dce3d5", + }); + + expect(response.hook).to.deep.equal(expectedHook); + }); + + it("should throw error", async function () { + axiosMock.get = sinon.stub().rejects(new Error("http 500")); + await expect( + hookClient.get({ + hookId: "0x1234514e0193144e1d7024428ee242c44e5cacdbd7458c629d17c6366f6c5cb6", + }), + ).to.be.rejectedWith("http 500"); + }); + + it("should throw error if asset id is invalid", async function () { + try { + await hookClient.get({ + hookId: "fake hook id", + }); + expect.fail(`Function should not get here, it should throw an error `); + } catch (error) { + // function is expected to throw. + } + }); + }); + + chai.use(chaiAsPromised); + + describe("Test HookReadOnlyClient", function () { + let hookClient: HookReadOnlyClient; + let axiosMock: AxiosInstance; + let rpcMock: PublicClient; + + beforeEach(function () { + axiosMock = createMock(); + rpcMock = createMock(); + hookClient = new HookReadOnlyClient(axiosMock, rpcMock); + }); + + afterEach(function () { + sinon.restore(); + }); + + describe("Test hookClient.get", function () { + it("should return hook when the hook id is valid", async function () { + const expectedHook = { + id: "0xc0f6e387ac0b324ec18eacf22ee7271207dce3d5", + moduleId: "0x091e5f55135155bb8cb5868adb39e5c34eb32cfd", + registryKey: "0xac909466a23bec9adaf8b5f1cdfec2fb87df8a07765d813250eee97ecd862dcf", + registeredAt: "1700289864", + txHash: "0xfe06c299ab53f44a98e925d4d50904783284de80d105afc3ab73b2908322fe93", + hookType: HookType.PostAction, + }; + axiosMock.get = sinon.stub().returns({ + data: { + hook: expectedHook, + }, + }); + const response = await hookClient.get({ + hookId: expectedHook.id, + }); + expect(response.hook).to.deep.equal(expectedHook); + }); + + it("should throw error", async function () { + axiosMock.get = sinon.stub().rejects(new Error("http 500")); + await expect( + hookClient.get({ + hookId: "0x1234514e0193144e1d7024428ee242c44e5cacdbd7458c629d17c6366f6c5cb6", + }), + ).to.be.rejectedWith("http 500"); + }); + + it("should throw error if asset id is invalid", async function () { + try { + await hookClient.get({ + hookId: "fake hook id", + }); + expect.fail(`Function should not get here, it should throw an error `); + } catch (error) { + // function is expected to throw. + } + }); + }); + + describe("Test hookClient.list", async function () { + const mockResponse = sinon.stub().returns({ + data: { + hooks: [ + { + id: "0xc0f6e387ac0b324ec18eacf22ee7271207dce3d5", + moduleId: "0x091e5f55135155bb8cb5868adb39e5c34eb32cfd", + registryKey: "0xac909466a23bec9adaf8b5f1cdfec2fb87df8a07765d813250eee97ecd862dcf", + registeredAt: "1700289864", + txHash: "0xfe06c299ab53f44a98e925d4d50904783284de80d105afc3ab73b2908322fe93", + hookType: HookType.PostAction, + }, + ], + }, + }); + + it("should return hooks without the request object", async function () { + axiosMock.post = mockResponse; + const response = await hookClient.list(); + const expectedHooks = [ + { + id: "0xc0f6e387ac0b324ec18eacf22ee7271207dce3d5", + moduleId: "0x091e5f55135155bb8cb5868adb39e5c34eb32cfd", + registryKey: "0xac909466a23bec9adaf8b5f1cdfec2fb87df8a07765d813250eee97ecd862dcf", + registeredAt: "1700289864", + txHash: "0xfe06c299ab53f44a98e925d4d50904783284de80d105afc3ab73b2908322fe93", + hookType: HookType.PostAction, + }, + ]; + expect(response.hooks).to.deep.equal(expectedHooks); + }); + + it("should throw error", async function () { + axiosMock.post = sinon.stub().rejects(new Error("HTTP 500")); + await expect( + hookClient.list({ + moduleId: "fake module id", + }), + ).to.be.rejectedWith("HTTP 500"); + }); + + it("should return hooks on a successful query", async function () { + axiosMock.post = mockResponse; + const expectedHooks = [ + { + id: "0xc0f6e387ac0b324ec18eacf22ee7271207dce3d5", + moduleId: "0x091e5f55135155bb8cb5868adb39e5c34eb32cfd", + registryKey: "0xac909466a23bec9adaf8b5f1cdfec2fb87df8a07765d813250eee97ecd862dcf", + registeredAt: "1700289864", + txHash: "0xfe06c299ab53f44a98e925d4d50904783284de80d105afc3ab73b2908322fe93", + hookType: HookType.PostAction, + }, + ]; + const response = await hookClient.list({ + moduleId: expectedHooks[0].moduleId, + }); + expect(response.hooks).to.deep.equal(expectedHooks); + }); + }); + }); +}); diff --git a/packages/core-sdk/test/unit/resources/ipAsset.test.ts b/packages/core-sdk/test/unit/resources/ipAsset.test.ts new file mode 100644 index 00000000..fb99380d --- /dev/null +++ b/packages/core-sdk/test/unit/resources/ipAsset.test.ts @@ -0,0 +1,155 @@ +import { expect } from "chai"; +import { AxiosInstance } from "axios"; +import { createMock } from "../testUtils"; +import * as sinon from "sinon"; +import { IPAssetClient, AddressZero } from "../../../src"; +import chai from "chai"; +import chaiAsPromised from "chai-as-promised"; +import { PublicClient, WalletClient, Account } from "viem"; + +chai.use(chaiAsPromised); + +describe("Test IpAssetClient", function () { + let ipAssetClient: IPAssetClient; + let axiosMock: AxiosInstance; + let rpcMock: PublicClient; + let walletMock: WalletClient; + + beforeEach(function () { + axiosMock = createMock(); + rpcMock = createMock(); + walletMock = createMock(); + const accountMock = createMock(); + accountMock.address = "0x73fcb515cee99e4991465ef586cfe2b072ebb512"; + walletMock.account = accountMock; + ipAssetClient = new IPAssetClient(axiosMock, rpcMock, walletMock); + }); + + afterEach(function () { + sinon.restore(); + }); + + describe("Test ipAssetClient.create", async function () { + it("should not throw error when creating a IP asset", async function () { + const txHash = "0x129f7dd802200f096221dd89d5b086e4bd3ad6eafb378a0c75e3b04fc375f997"; + rpcMock.readContract = sinon.stub().resolves(AddressZero); + rpcMock.simulateContract = sinon.stub().resolves({ request: null }); + walletMock.writeContract = sinon.stub().resolves(txHash); + + const res = await ipAssetClient.create({ + name: "The Empire Strikes Back", + typeIndex: 0, + ipOrgId: "0xB32BdE3fBfddAd30a8d824178F00F0adB43DF2e7", + owner: "0x4f9693ac46f2c7e2f48dd14d8fe1ab44192cd57d", + preHookData: [ + { + interface: "address", + data: ["0xf398C12A45Bc409b6C652E25bb0a3e702492A4ab"], + }, + ], + postHookData: [ + { + interface: "address", + data: ["0xf398C12A45Bc409b6C652E25bb0a3e702492A4ab"], + }, + ], + txOptions: { + waitForTransaction: false, + }, + }); + + expect(res.txHash).equal(txHash); + }); + + it("should not throw error when creating a IP asset without owner field", async function () { + const txHash = "0x129f7dd802200f096221dd89d5b086e4bd3ad6eafb378a0c75e3b04fc375f997"; + rpcMock.readContract = sinon.stub().resolves(AddressZero); + rpcMock.simulateContract = sinon.stub().resolves({ request: null }); + walletMock.writeContract = sinon.stub().resolves(txHash); + + const res = await ipAssetClient.create({ + name: "The Empire Strikes Back", + typeIndex: 0, + ipOrgId: "0xB32BdE3fBfddAd30a8d824178F00F0adB43DF2e7", + txOptions: { + waitForTransaction: false, + }, + }); + expect(res.txHash).equal(txHash); + }); + + it("should not throw error when creating a IP asset and wait for transaction confirmed", async function () { + const txHash = "0x129f7dd802200f096221dd89d5b086e4bd3ad6eafb378a0c75e3b04fc375f997"; + rpcMock.readContract = sinon.stub().resolves(AddressZero); + rpcMock.simulateContract = sinon.stub().resolves({ request: null }); + walletMock.writeContract = sinon.stub().resolves(txHash); + rpcMock.waitForTransactionReceipt = sinon.stub().resolves({ + logs: [ + { + address: "0x091e5f55135155bb8cb5868adb39e5c34eb32cfd", + topics: [ + "0xd051b12b5a18291aec9a26b17774a4be2d10dce167cbdc5944c7942c78f901c1", + "0x000000000000000000000000b422e54932c1dae83e78267a4dd2805aa64a8061", + "0x00000000000000000000000077cbcc0e29e10f1eea24e0d109aab26c5b2abd88", + "0x0000000000000000000000000000000000000000000000000000000000000000", + ], + data: "0x0000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000000454657374000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + blockNumber: 4738934n, + transactionHash: "0x3600464c4f0794de350e55a484d67cdb6ed4a89917274709b9bb48246935c891", + transactionIndex: 106, + blockHash: "0x8d431865dbcfa54988f48b18c0a07fea503ca38c387b6326f513aa6f238faddc", + logIndex: 52, + removed: false, + }, + ], + }); + + const response = await ipAssetClient.create({ + name: "The Empire Strikes Back", + typeIndex: 0, + ipOrgId: "0xB32BdE3fBfddAd30a8d824178F00F0adB43DF2e7", + owner: "0x4f9693ac46f2c7e2f48dd14d8fe1ab44192cd57d", + txOptions: { + waitForTransaction: true, + }, + }); + expect(response.txHash).equal(txHash); + expect(response.ipAssetId).equals("6"); + }); + + it("should throw error when request fails", async function () { + rpcMock.simulateContract = sinon.stub().resolves({ request: null }); + walletMock.writeContract = sinon.stub().rejects(new Error("http 500")); + await expect( + ipAssetClient.create({ + name: "The Empire Strikes Back", + typeIndex: 0, + ipOrgId: "0xB32BdE3fBfddAd30a8d824178F00F0adB43DF2e7", + owner: "0x4f9693ac46f2c7e2f48dd14d8fe1ab44192cd57d", + txOptions: { + waitForTransaction: false, + }, + }), + ).to.be.rejectedWith("http 500"); + }); + + it("should throw error when invalid IP asset ID is provided", async function () { + const txHash = "0x129f7dd802200f096221dd89d5b086e4bd3ad6eafb378a0c75e3b04fc375f997"; + rpcMock.readContract = sinon.stub().resolves(AddressZero); + rpcMock.simulateContract = sinon.stub().rejects(); + walletMock.writeContract = sinon.stub().resolves(txHash); + + await expect( + ipAssetClient.create({ + name: "The Empire Strikes Back", + typeIndex: 0, + ipOrgId: "0xB32BdE3fBfddAd30a8d824178F00F0adB43DF2e7", + owner: "0x4f9693ac46f2c7e2f48dd14d8fe1ab44192cd57d", + txOptions: { + waitForTransaction: false, + }, + }), + ).to.be.rejectedWith("Failed to create IP Asset: Error"); + }); + }); +}); diff --git a/packages/core-sdk/test/unit/resources/ipAssetReadOnly.test.ts b/packages/core-sdk/test/unit/resources/ipAssetReadOnly.test.ts new file mode 100644 index 00000000..3e48eec1 --- /dev/null +++ b/packages/core-sdk/test/unit/resources/ipAssetReadOnly.test.ts @@ -0,0 +1,111 @@ +import { expect } from "chai"; +import { AxiosInstance } from "axios"; +import { createMock } from "../testUtils"; +import * as sinon from "sinon"; +import { IPAssetReadOnlyClient } from "../../../src"; +import chai from "chai"; +import chaiAsPromised from "chai-as-promised"; +import { PublicClient } from "viem"; + +chai.use(chaiAsPromised); + +describe("Test IpAssetReadOnlyClient", function () { + let ipAssetClient: IPAssetReadOnlyClient; + let axiosMock: AxiosInstance; + let rpcMock: PublicClient; + + beforeEach(function () { + axiosMock = createMock(); + rpcMock = createMock(); + ipAssetClient = new IPAssetReadOnlyClient(axiosMock, rpcMock); + }); + + afterEach(function () { + sinon.restore(); + }); + + describe("Test ipAssetClient.get", function () { + it("should return asset when the franchise id is valid", async function () { + const expectedAsset = { + id: "1", + name: "The Empire Strikes Back", + ipOrgId: "0xB32BdE3fBfddAd30a8d824178F00F0adB43DF2e7", + owner: "0x4f9693ac46f2c7e2f48dd14d8fe1ab44192cd57d", + metadataUrl: "https://arweave.net/R7-xPDAMqOhUSw3CM_UwXI7zdpQkzCCCUq3smzxyAaU", + createdAt: "2023-11-14T00:29:13Z", + txHash: "0x00a1a14e0193144e1d7024428ee242c44e5cacdbd7458c629d17c6366f6c5cb6", + }; + axiosMock.get = sinon.stub().returns({ + data: { + ipAsset: expectedAsset, + }, + }); + + const response = await ipAssetClient.get({ + ipAssetId: "7", + }); + expect(response.ipAsset).to.deep.equal(expectedAsset); + }); + + it("should throw error", async function () { + axiosMock.get = sinon.stub().rejects(new Error("http 500")); + await expect( + ipAssetClient.get({ + ipAssetId: "7", + }), + ).to.be.rejectedWith("http 500"); + }); + + it("should throw error if asset id is invalid", async function () { + axiosMock.get = sinon.stub().rejects(new Error("http 500")); + await expect( + ipAssetClient.get({ + ipAssetId: "fake ip asset id", + }), + ).to.be.rejectedWith("fake ip asset id"); + }); + }); + + describe("Test ipAssetClient.list", async function () { + const ipAssetMock = { + id: "1", + name: "The Empire Strikes Back", + ipOrgId: "0xB32BdE3fBfddAd30a8d824178F00F0adB43DF2e7", + owner: "0x4f9693ac46f2c7e2f48dd14d8fe1ab44192cd57d", + metadataUrl: "https://arweave.net/R7-xPDAMqOhUSw3CM_UwXI7zdpQkzCCCUq3smzxyAaU", + createdAt: "2023-11-14T00:29:13Z", + txHash: "0x00a1a14e0193144e1d7024428ee242c44e5cacdbd7458c629d17c6366f6c5cb6", + }; + + const mockResponse = sinon.stub().returns({ + data: { + ipAssets: [ipAssetMock], + }, + }); + + it("should return ipAssets on a successful query", async function () { + axiosMock.post = mockResponse; + const response = await ipAssetClient.list({ + ipOrgId: "7", + }); + + expect(response.ipAssets[0]).to.deep.equal(ipAssetMock); + }); + + it("should return ipAssets without the request object", async function () { + axiosMock.post = mockResponse; + const response = await ipAssetClient.list(); + + expect(response.ipAssets[0]).to.deep.equal(ipAssetMock); + }); + + it("should throw error", async function () { + axiosMock.post = sinon.stub().rejects(new Error("HTTP 500")); + await expect( + ipAssetClient.list({ + ipOrgId: "abc", + }), + ).to.be.rejectedWith("HTTP 500"); + }); + }); +}); diff --git a/packages/core-sdk/test/unit/resources/ipOrg.test.ts b/packages/core-sdk/test/unit/resources/ipOrg.test.ts new file mode 100644 index 00000000..b4bd65b5 --- /dev/null +++ b/packages/core-sdk/test/unit/resources/ipOrg.test.ts @@ -0,0 +1,146 @@ +import chai, { expect } from "chai"; +import { AxiosInstance } from "axios"; +import { createMock } from "../testUtils"; +import * as sinon from "sinon"; +import chaiAsPromised from "chai-as-promised"; +import { PublicClient, WalletClient, Account } from "viem"; +import { IPOrgClient } from "../../../src"; + +chai.use(chaiAsPromised); +chai.config.truncateThreshold = 0; + +describe(`Test IPOrgClient`, function () { + let ipOrgClient: IPOrgClient; + let axiosMock: AxiosInstance; + let rpcMock: PublicClient; + let walletMock: WalletClient; + + beforeEach(function () { + axiosMock = createMock(); + rpcMock = createMock(); + walletMock = createMock(); + const accountMock = createMock(); + accountMock.address = "0x73fcb515cee99e4991465ef586cfe2b072ebb512"; + walletMock.account = accountMock; + ipOrgClient = new IPOrgClient(axiosMock, rpcMock, walletMock); + }); + + afterEach(function () { + sinon.restore(); + }); + + describe("Test ipOrgClient.create", async function () { + const txHash = "0x129f7dd802200f096221dd89d5b086e4bd3ad6eafb378a0c75e3b04fc375f997"; + it("should not throw error when creating a ip Org", async function () { + rpcMock.simulateContract = sinon.stub().resolves({ request: null }); + walletMock.writeContract = sinon.stub().resolves(txHash); + + const res = await ipOrgClient.create({ + name: "Star Wars", + symbol: "STAR", + owner: "0x4f9693ac46f2c7e2f48dd14d8fe1ab44192cd57d", + ipAssetTypes: ["Story", "Character"], + txOptions: { + waitForTransaction: false, + }, + }); + expect(res.txHash).to.be.equal(txHash); + }); + + it("should not throw error when creating a ip Org with ZeroAddress", async function () { + rpcMock.simulateContract = sinon.stub().resolves({ request: null }); + walletMock.writeContract = sinon.stub().resolves(txHash); + + const res = await ipOrgClient.create({ + name: "Star Wars", + symbol: "STAR", + ipAssetTypes: ["Story", "Character"], + txOptions: { + waitForTransaction: false, + }, + }); + expect(res.txHash).to.be.equal(txHash); + }); + + it("should not throw error when creating a ip Org and wait for transaction confirmed", async function () { + rpcMock.simulateContract = sinon.stub().resolves({ request: null }); + walletMock.writeContract = sinon.stub().resolves(txHash); + rpcMock.waitForTransactionReceipt = sinon.stub().resolves({ + logs: [ + { + address: "0x73fcb515cee99e4991465ef586cfe2b072ebb512", + topics: ["0x81e084d978860accc83df39f75b801d9019e40d18643b9b39f4cd2a70ca35adb"], + data: "0x000000000000000000000000f398c12a45bc409b6c652e25bb0a3e702492a4ab0000000000000000000000000dad65978b6c637598674ea03b1c6f3333d00f5b00000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000000095374617220576172730000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000453544152000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000001310000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000013200000000000000000000000000000000000000000000000000000000000000", + blockNumber: 4739106n, + transactionHash: "0x6bf8053b1e8ffdc8a767938b14a59eb1e08cf8821743be7f8377e5bad77f76a8", + transactionIndex: 105, + blockHash: "0x6677ab7dc2bab685131a05db009865faad06cbfb785c71813feaebed066e2f2d", + logIndex: 161, + removed: false, + }, + ], + }); + const resp = await ipOrgClient.create({ + name: "Star Wars", + symbol: "STAR", + owner: "0x4f9693ac46f2c7e2f48dd14d8fe1ab44192cd57d", + ipAssetTypes: ["Story", "Character"], + txOptions: { + waitForTransaction: true, + }, + }); + expect(resp.txHash).to.be.equal(txHash); + expect(resp.ipOrgId).to.be.equal("0x0Dad65978B6C637598674ea03B1C6f3333D00f5B"); + }); + + it("should throw error when registerIPOrg reverts", async function () { + rpcMock.simulateContract = sinon.stub().rejects(new Error("revert")); + await expect( + ipOrgClient.create({ + name: "Alice In Wonderland", + symbol: "AIW", + owner: "0x4f9693ac46f2c7e2f48dd14d8fe1ab44192cd57d", + ipAssetTypes: ["Story", "Character"], + txOptions: { + waitForTransaction: false, + }, + }), + ).to.be.rejectedWith("revert"); + }); + + it("should throw error when not found IPOrgRegistered event", async function () { + rpcMock.simulateContract = sinon.stub().resolves({ request: null }); + walletMock.writeContract = sinon + .stub() + .resolves("0x6bf8053b1e8ffdc8a767938b14a59eb1e08cf8821743be7f8377e5bad77f76a8"); + rpcMock.waitForTransactionReceipt = sinon.stub().resolves({ + logs: [ + { + address: "0x73fcb515cee99e4991465ef586cfe2b072ebb512", + topics: ["0x558b44f88e5959cec9c7836078a53ff4d6432142a9d5caa6f3a6eb7c83938981"], + data: "0x000000000000000000000000794421212db0f3eac69124e4bad728ab74e1575ea0000000000000000000000003d114640e01c09b570ff7fddb66f194f7f1da6ef000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000009537461722057617273000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000045354415200000000000000000000000000000000000000000000000000000000", + blockNumber: 4739106n, + transactionHash: "0x6bf8053b1e8ffdc8a767938b14a59eb1e08cf8821743be7f8377e5bad77f76a8", + transactionIndex: 105, + blockHash: "0x6677ab7dc2bab685131a05db009865faad06cbfb785c71813feaebed066e2f2d", + logIndex: 161, + removed: false, + }, + ], + }); + await expect( + ipOrgClient.create({ + name: "Star Wars", + symbol: "STAR", + owner: "0x4f9693ac46f2c7e2f48dd14d8fe1ab44192cd57d", + ipAssetTypes: ["Story", "Character"], + txOptions: { + waitForTransaction: true, + }, + }), + ).to.be.rejectedWith( + `Failed to create IPOrg: not found event IPOrgRegistered in target transaction`, + ); + }); + }); +}); diff --git a/packages/core-sdk/test/unit/resources/ipOrgReadOnly.test.ts b/packages/core-sdk/test/unit/resources/ipOrgReadOnly.test.ts new file mode 100644 index 00000000..9482a38a --- /dev/null +++ b/packages/core-sdk/test/unit/resources/ipOrgReadOnly.test.ts @@ -0,0 +1,100 @@ +import chai, { expect } from "chai"; +import { IPOrgReadOnlyClient } from "../../../src"; +import { AxiosInstance } from "axios"; +import { createMock } from "../testUtils"; +import * as sinon from "sinon"; +import chaiAsPromised from "chai-as-promised"; +import { PublicClient } from "viem"; + +chai.use(chaiAsPromised); + +describe(`Test IPOrgReadOnlyClient`, function () { + let ipOrgClient: IPOrgReadOnlyClient; + let axiosMock: AxiosInstance; + let rpcMock: PublicClient; + + beforeEach(function () { + axiosMock = createMock(); + rpcMock = createMock(); + ipOrgClient = new IPOrgReadOnlyClient(axiosMock, rpcMock); + }); + + afterEach(function () { + sinon.restore(); + }); + + describe("Test ipOrgClient.get", function () { + const ipOrgMock = { + id: "0x4f9693ac46f2c7e2f48dd14d8fe1ab44192cd57d", + name: "Star Wars", + symbol: "STAR", + owner: "0x4f9693ac46f2c7e2f48dd14d8fe1ab44192cd57d", + metadataUrl: "https://arweave.net/dnFJl1v8kgOx_6Z0gEsBce3D56cMP4-lxAcFqSsL0_w", + createdAt: "2023-11-14T00:29:13Z", + txHash: "0xc80c23b7992cc94a271d1a56280ccc16a8f78a6d63ee34efdc35d8ffc71eda58", + }; + + it("should return ipOrgClient when the ipOrgClient id is valid", async function () { + axiosMock.get = sinon.stub().returns({ + data: { + ipOrg: ipOrgMock, + }, + }); + + const response = await ipOrgClient.get({ + ipOrgId: "0x4f9693ac46f2c7e2f48dd14d8fe1ab44192cd57d", + }); + + expect(response.ipOrg).to.deep.equal(ipOrgMock); + }); + + it("should throw error", async function () { + axiosMock.get = sinon.stub().rejects(new Error("http 500")); + await expect( + ipOrgClient.get({ + ipOrgId: "0x4f9693ac46f2c7e2f48dd14d8fe1ab44192cd57d", + }), + ).to.be.rejectedWith("http 500"); + }); + + it("should throw error when the ipOrgClient id is invalid", async function () { + await expect( + ipOrgClient.get({ + ipOrgId: "abc", + }), + ).to.be.rejectedWith( + `Failed to get IPOrg: Invalid IPOrg id. Must be an address. But got: abc`, + ); + }); + }); + + describe("Test ipOrgClient.list", async function () { + it("should return ipOrgs on a successful query", async function () { + axiosMock.post = sinon.stub().returns({ + data: { + ipOrgs: [ + { + id: "7", + name: "Alice In Wonderland", + symbol: "AIW", + owner: "0x4f9693ac46f2c7e2f48dd14d8fe1ab44192cd57d", + metadataUrl: "https://arweave.net/dnFJl1v8kgOx_6Z0gEsBce3D56cMP4-lxAcFqSsL0_w", + createdAt: "2023-11-14T00:29:13Z", + txHash: "0xc80c23b7992cc94a271d1a56280ccc16a8f78a6d63ee34efdc35d8ffc71eda58", + }, + ], + }, + }); + + const response = await ipOrgClient.list(); + + expect(response.ipOrgs[0].id).to.equal("7"); + expect(response.ipOrgs[0].name).to.equal("Alice In Wonderland"); + }); + + it("should throw error", async function () { + axiosMock.post = sinon.stub().rejects(new Error("HTTP 500")); + await expect(ipOrgClient.list()).to.be.rejectedWith("HTTP 500"); + }); + }); +}); diff --git a/packages/core-sdk/test/unit/resources/license.test.ts b/packages/core-sdk/test/unit/resources/license.test.ts new file mode 100644 index 00000000..d462dbbe --- /dev/null +++ b/packages/core-sdk/test/unit/resources/license.test.ts @@ -0,0 +1,395 @@ +import chai, { expect } from "chai"; +import { AxiosInstance } from "axios"; +import { createMock } from "../testUtils"; +import * as sinon from "sinon"; +import chaiAsPromised from "chai-as-promised"; +import { PublicClient, WalletClient, Account, parseGwei, toBytes, stringToHex } from "viem"; +import { LicenseClient } from "../../../src"; +import { + ConfigureLicenseRequest, + CreateLicenseRequest, +} from "../../../src/types/resources/license"; +import { mockCreateAndConfigureLicenseLog } from "../utils/mockData"; + +chai.use(chaiAsPromised); +chai.config.truncateThreshold = 0; + +describe(`Test License`, function () { + let licenseClient: LicenseClient; + let axiosMock: AxiosInstance; + let rpcMock: PublicClient; + let walletMock: WalletClient; + + beforeEach(function () { + axiosMock = createMock(); + rpcMock = createMock(); + walletMock = createMock(); + const accountMock = createMock(); + accountMock.address = "0x73fcb515cee99e4991465ef586cfe2b072ebb512"; + walletMock.account = accountMock; + licenseClient = new LicenseClient(axiosMock, rpcMock, walletMock); + }); + + afterEach(function () { + sinon.restore(); + }); + + describe("Test LicenseClient.create", async function () { + it("should be able to create license", async function () { + const ipOrgIdMock = "0x8d312f57eb3b461ba5b34930768543611203c1aa"; + rpcMock.simulateContract = sinon.stub().resolves({ request: null }); + walletMock.writeContract = sinon + .stub() + .resolves("0x129f7dd802200f096221dd89d5b086e4bd3ad6eafb378a0c75e3b04fc375f997"); + rpcMock.waitForTransactionReceipt = sinon.stub().resolves({ + logs: mockCreateAndConfigureLicenseLog, + }); + + const createLicenseRequest: CreateLicenseRequest = { + ipOrgId: ipOrgIdMock, + params: [], + parentLicenseId: "0", + ipaId: "0", + preHookData: [], + postHookData: [], + txOptions: { + waitForTransaction: true, + }, + }; + + const createLicenseRes = await expect(licenseClient.create(createLicenseRequest)).not.to.be + .rejected; + console.log(createLicenseRes); + expect(createLicenseRes.licenseId).to.be.a("string"); + expect(createLicenseRes.licenseId).not.be.undefined; + }); + it("should be able to create license (don't wait for txn)", async function () { + const ipOrgIdMock = "0x8d312f57eb3b461ba5b34930768543611203c1aa"; + rpcMock.simulateContract = sinon.stub().resolves({ request: null }); + walletMock.writeContract = sinon + .stub() + .resolves("0x129f7dd802200f096221dd89d5b086e4bd3ad6eafb378a0c75e3b04fc375f997"); + rpcMock.waitForTransactionReceipt = sinon.stub().resolves({ + logs: mockCreateAndConfigureLicenseLog, + }); + + const createLicenseRequest: CreateLicenseRequest = { + ipOrgId: ipOrgIdMock, + params: [], + parentLicenseId: "0", + ipaId: "0", + preHookData: [], + postHookData: [], + txOptions: { + waitForTransaction: false, + }, + }; + + const createLicenseRes = await expect(licenseClient.create(createLicenseRequest)).not.to.be + .rejected; + console.log(createLicenseRes); + expect(createLicenseRes.txHash).to.be.a("string"); + expect(createLicenseRes.txHash).not.be.undefined; + }); + it("should be able to create license", async function () { + const ipOrgIdMock = "0x8d312f57eb3b461ba5b34930768543611203c1aa"; + rpcMock.simulateContract = sinon.stub().resolves({ request: null }); + walletMock.writeContract = sinon + .stub() + .resolves("0x129f7dd802200f096221dd89d5b086e4bd3ad6eafb378a0c75e3b04fc375f997"); + rpcMock.waitForTransactionReceipt = sinon.stub().resolves({ + logs: mockCreateAndConfigureLicenseLog, + }); + + const createLicenseRequest: CreateLicenseRequest = { + ipOrgId: ipOrgIdMock, + params: [], + parentLicenseId: "0", + ipaId: "0", + preHookData: [], + postHookData: [], + txOptions: { + waitForTransaction: true, + }, + }; + const createLicenseRes = await expect(licenseClient.create(createLicenseRequest)).not.to.be + .rejected; + console.log(createLicenseRes); + expect(createLicenseRes.txHash).to.be.a("string"); + expect(createLicenseRes.txHash).not.be.undefined; + }); + + it("should be able to get transaction hash after calling license.create", async function () { + const ipOrgIdMock = "0x973748DC37577905a072d3Bf5ea0e8E69547c872"; + rpcMock.simulateContract = sinon.stub().resolves({ request: null }); + walletMock.writeContract = sinon + .stub() + .resolves("0x129f7dd802200f096221dd89d5b086e4bd3ad6eafb378a0c75e3b04fc375f997"); + rpcMock.waitForTransactionReceipt = sinon.stub().resolves({ + logs: mockCreateAndConfigureLicenseLog, + }); + + const createLicenseRequest: CreateLicenseRequest = { + ipOrgId: ipOrgIdMock, + params: [], + parentLicenseId: "0", + ipaId: "0", + preHookData: [], + postHookData: [], + txOptions: { + waitForTransaction: true, + }, + }; + + const createLicenseRes = await expect(licenseClient.create(createLicenseRequest)).not.to.be + .rejected; + expect(createLicenseRes.txHash).to.be.a("string"); + expect(createLicenseRes.txHash).not.be.undefined; + }); + it("should be able to configure license", async function () { + const ipOrgIdMock = "0x973748DC37577905a072d3Bf5ea0e8E69547c872"; + rpcMock.simulateContract = sinon.stub().resolves({ request: null }); + walletMock.writeContract = sinon + .stub() + .resolves("0x129f7dd802200f096221dd89d5b086e4bd3ad6eafb378a0c75e3b04fc375f997"); + rpcMock.waitForTransactionReceipt = sinon.stub().resolves({ + logs: mockCreateAndConfigureLicenseLog, + }); + + // Configure license + const configureLicenseRequest: ConfigureLicenseRequest = { + ipOrg: ipOrgIdMock, + frameworkId: "SPUML-1.0", + params: [], + licensor: 1, + txOptions: { + waitForTransaction: true, + gasPrice: parseGwei("250"), + }, + }; + + const configureResponse = await licenseClient.configure(configureLicenseRequest); + + expect(configureResponse.success).to.be.true; + }); + it("should be able to configure license (don't wait for txn)", async function () { + const ipOrgIdMock = "0x973748DC37577905a072d3Bf5ea0e8E69547c872"; + rpcMock.simulateContract = sinon.stub().resolves({ request: null }); + walletMock.writeContract = sinon + .stub() + .resolves("0x129f7dd802200f096221dd89d5b086e4bd3ad6eafb378a0c75e3b04fc375f997"); + rpcMock.waitForTransactionReceipt = sinon.stub().resolves({ + logs: mockCreateAndConfigureLicenseLog, + }); + + // Configure license + const configureLicenseRequest: ConfigureLicenseRequest = { + ipOrg: ipOrgIdMock, + frameworkId: "SPUML-1.0", + params: [], + licensor: 1, + txOptions: { + waitForTransaction: true, + gasPrice: parseGwei("250"), + }, + }; + + const configureResponse = await licenseClient.configure(configureLicenseRequest); + + expect(configureResponse.txHash).to.be.a("string"); + expect(configureResponse.txHash).not.be.undefined; + }); + it("should be able to configure license with Derivatives-Allowed parameter ", async function () { + const ipOrgIdMock = "0x973748DC37577905a072d3Bf5ea0e8E69547c872"; + rpcMock.simulateContract = sinon.stub().resolves({ request: null }); + walletMock.writeContract = sinon + .stub() + .resolves("0x129f7dd802200f096221dd89d5b086e4bd3ad6eafb378a0c75e3b04fc375f997"); + rpcMock.waitForTransactionReceipt = sinon.stub().resolves({ + logs: mockCreateAndConfigureLicenseLog, + }); + + const attributionParam = { + tag: stringToHex("Derivatives-Allowed", { size: 32 }), + value: { + interface: "bool", + data: [false], + }, + }; + + const licenseParameters = [attributionParam]; + + // Configure license + const configureLicenseRequest: ConfigureLicenseRequest = { + ipOrg: ipOrgIdMock, + frameworkId: "SPUML-1.0", + params: licenseParameters, + licensor: 1, + txOptions: { + waitForTransaction: true, + gasPrice: parseGwei("250"), + }, + }; + + const configureResponse = await licenseClient.configure(configureLicenseRequest); + + expect(configureResponse.txHash).to.be.a("string"); + expect(configureResponse.txHash).not.be.undefined; + }); + it("should be able to configure license with Attribution parameter ", async function () { + const ipOrgIdMock = "0x973748DC37577905a072d3Bf5ea0e8E69547c872"; + rpcMock.simulateContract = sinon.stub().resolves({ request: null }); + walletMock.writeContract = sinon + .stub() + .resolves("0x129f7dd802200f096221dd89d5b086e4bd3ad6eafb378a0c75e3b04fc375f997"); + rpcMock.waitForTransactionReceipt = sinon.stub().resolves({ + logs: mockCreateAndConfigureLicenseLog, + }); + + const attributionParam = { + tag: stringToHex("Attribution", { size: 32 }), + value: { + interface: "bool", + data: [false], + }, + }; + + const licenseParameters = [attributionParam]; + + // Configure license + const configureLicenseRequest: ConfigureLicenseRequest = { + ipOrg: ipOrgIdMock, + frameworkId: "SPUML-1.0", + params: licenseParameters, + licensor: 1, + txOptions: { + waitForTransaction: true, + gasPrice: parseGwei("250"), + }, + }; + + const configureResponse = await licenseClient.configure(configureLicenseRequest); + + expect(configureResponse.txHash).to.be.a("string"); + expect(configureResponse.txHash).not.be.undefined; + }); + it("should be able to configure license", async function () { + const ipOrgIdMock = "0x973748DC37577905a072d3Bf5ea0e8E69547c872"; + rpcMock.simulateContract = sinon.stub().resolves({ request: null }); + walletMock.writeContract = sinon + .stub() + .resolves("0x129f7dd802200f096221dd89d5b086e4bd3ad6eafb378a0c75e3b04fc375f997"); + rpcMock.waitForTransactionReceipt = sinon.stub().resolves({ + logs: mockCreateAndConfigureLicenseLog, + }); + + // Configure license + const configureLicenseRequest: ConfigureLicenseRequest = { + ipOrg: ipOrgIdMock, + frameworkId: "SPUML-1.0", + params: [], + licensor: 1, + txOptions: { + waitForTransaction: true, + gasPrice: parseGwei("250"), + }, + }; + + const configureResponse = await licenseClient.configure(configureLicenseRequest); + + expect(configureResponse.success).to.be.true; + }); + it("should be able to get transaction hash after calling license.configure", async function () { + const ipOrgIdMock = "0x973748DC37577905a072d3Bf5ea0e8E69547c872"; + rpcMock.simulateContract = sinon.stub().resolves({ request: null }); + walletMock.writeContract = sinon + .stub() + .resolves("0x129f7dd802200f096221dd89d5b086e4bd3ad6eafb378a0c75e3b04fc375f997"); + rpcMock.waitForTransactionReceipt = sinon.stub().resolves({ + logs: mockCreateAndConfigureLicenseLog, + }); + + // Configure license + const configureLicenseRequest: ConfigureLicenseRequest = { + ipOrg: ipOrgIdMock, + frameworkId: "SPUML-1.0", + params: [], + licensor: 1, + txOptions: { + waitForTransaction: false, + gasPrice: parseGwei("250"), + }, + }; + + const configureResponse = await licenseClient.configure(configureLicenseRequest); + + expect(configureResponse.txHash).to.be.a("string"); + expect(configureResponse.txHash).not.be.undefined; + }); + + it("create should throw error", async () => { + const ipOrgIdMock = "0x973748DC37577905a072d3Bf5ea0e8E69547c872"; + rpcMock.simulateContract = sinon.stub().resolves({ request: null }); + walletMock.writeContract = sinon.stub().rejects(new Error("http 500")); + + const createLicenseRequest: CreateLicenseRequest = { + ipOrgId: ipOrgIdMock, + params: [], + parentLicenseId: "0", + ipaId: "0", + preHookData: [], + postHookData: [], + txOptions: { + waitForTransaction: true, + gasPrice: parseGwei("250"), + }, + }; + + await expect(licenseClient.create(createLicenseRequest)).to.be.rejectedWith("http 500"); + }); + it("configure should throw error", async () => { + const ipOrgIdMock = "0x973748DC37577905a072d3Bf5ea0e8E69547c872"; + rpcMock.simulateContract = sinon.stub().resolves({ request: null }); + walletMock.writeContract = sinon.stub().rejects(new Error("http 500")); + // Configure license + const configureLicenseRequest: ConfigureLicenseRequest = { + ipOrg: ipOrgIdMock, + frameworkId: "SPUML-1.0", + params: [], + licensor: 1, + txOptions: { + waitForTransaction: true, + gasPrice: parseGwei("250"), + }, + }; + + await expect(licenseClient.configure(configureLicenseRequest)).to.be.rejectedWith("http 500"); + }); + it("configure should throw error if incorrect params", async () => { + const ipOrgIdMock = "0x973748DC37577905a072d3Bf5ea0e8E69547c872"; + rpcMock.simulateContract = sinon.stub().resolves({ request: null }); + walletMock.writeContract = sinon.stub().rejects(new Error("http 500")); + // Configure license + const configureLicenseRequest: ConfigureLicenseRequest = { + ipOrg: ipOrgIdMock, + frameworkId: "SPUML-1.0", + params: [ + { + tag: stringToHex("foo", { size: 32 }), + value: { + interface: "bool", + data: [true], + }, + }, + ], + licensor: 1, + txOptions: { + waitForTransaction: true, + gasPrice: parseGwei("250"), + }, + }; + + await expect(licenseClient.configure(configureLicenseRequest)).to.be.rejectedWith("http 500"); + }); + }); +}); diff --git a/packages/core-sdk/test/unit/resources/licenseReadOnly.test.ts b/packages/core-sdk/test/unit/resources/licenseReadOnly.test.ts new file mode 100644 index 00000000..6b91da89 --- /dev/null +++ b/packages/core-sdk/test/unit/resources/licenseReadOnly.test.ts @@ -0,0 +1,224 @@ +import chai, { expect } from "chai"; +import chaiAsPromised from "chai-as-promised"; +import { AxiosInstance } from "axios"; +import { createMock } from "../testUtils"; +import * as sinon from "sinon"; +import { PublicClient } from "viem"; +import { ListLicenseRequest, LicenseReadOnlyClient } from "../../../src"; +import { ListLicenseParamsRequest } from "../../../src/types/resources/license"; + +chai.use(chaiAsPromised); + +describe("Test LicenseReadOnlyClient", function () { + let licenseClient: LicenseReadOnlyClient; + let axiosMock: AxiosInstance; + let rpcMock: PublicClient; + + beforeEach(function () { + axiosMock = createMock(); + rpcMock = createMock(); + licenseClient = new LicenseReadOnlyClient(axiosMock, rpcMock); + }); + + afterEach(function () { + sinon.restore(); + }); + + describe("Test license.get", function () { + const licenseMock = { + id: "24", + status: 3, + isReciprocal: true, + derivativeNeedsApproval: true, + derivativesAllowed: true, + licensor: "0xf398c12a45bc409b6c652e25bb0a3e702492a4ab", + revoker: "0xf398c12a45bc409b6c652e25bb0a3e702492a4ab", + ipOrgId: process.env.TEST_IPORG_ID as string, + ipAssetId: "1", + parentLicenseId: "0", + createdAt: "2023-11-23T02:55:36Z", + txHash: "0x000645882d175d1facd646f3ecca0bbf31a9b9697d3d3f3a564ce9c885d7eeb2", + }; + it("should return a license when the license ID is valid", async function () { + axiosMock.get = sinon.stub().returns({ + data: { + license: licenseMock, + }, + }); + + const response = await licenseClient.get({ + licenseId: "49", + }); + expect(response.license).to.deep.equal(licenseMock); + }); + + it("should throw an error", async function () { + axiosMock.get = sinon.stub().rejects(new Error("HTTP 500")); + + await expect( + licenseClient.get({ + licenseId: "123", + }), + ).to.be.rejectedWith("HTTP 500"); + }); + + it("should throw an error when the license ID is invalid", async function () { + await expect( + licenseClient.get({ + licenseId: "abc", + }), + ).to.be.rejectedWith(`Invalid licenseId. Must be an integer. But got: abc`); + }); + }); + + describe("Test license.list", function () { + const mockListLicenseRequest: ListLicenseRequest = { + ipOrgId: process.env.TEST_IPORG_ID as string, + ipAssetId: "5", + }; + const licenseMock1 = { + id: "24", + status: 3, + isReciprocal: true, + derivativeNeedsApproval: true, + derivativesAllowed: true, + licensor: "0xf398c12a45bc409b6c652e25bb0a3e702492a4ab", + revoker: "0xf398c12a45bc409b6c652e25bb0a3e702492a4ab", + ipOrgId: "0x1eBb43775fCC45CF05eaa96182C8762220e17941", + ipAssetId: "1", + parentLicenseId: "0", + createdAt: "2023-11-23T02:55:36Z", + txHash: "0x000645882d175d1facd646f3ecca0bbf31a9b9697d3d3f3a564ce9c885d7eeb2", + }; + const licenseMock2 = { + id: "13", + status: 3, + isReciprocal: true, + derivativeNeedsApproval: true, + derivativesAllowed: true, + licensor: "0xf398c12a45bc409b6c652e25bb0a3e702492a4ab", + revoker: "0xf398c12a45bc409b6c652e25bb0a3e702492a4ab", + ipOrgId: "0x1eBb43775fCC45CF05eaa96182C8762220e17941", + ipAssetId: "0", + parentLicenseId: "0", + createdAt: "2023-11-23T02:12:24Z", + txHash: "0x08c49125f2f91f8eda0b2a799424a41a825e6051541fd620727a96bdc4bc7a8a", + }; + const mockResponse = sinon.stub().returns({ + data: { + licenses: [licenseMock1, licenseMock2], + }, + }); + + it("should return a list of licenses", async function () { + axiosMock.post = mockResponse; + + const response = await licenseClient.list(mockListLicenseRequest); + expect(response.licenses).to.be.an("array"); + expect(response.licenses[0]).to.deep.equal(licenseMock1); + expect(response.licenses[1]).to.deep.equal(licenseMock2); + }); + + it("should return a list of licenses without the request object", async function () { + axiosMock.post = mockResponse; + + const response = await licenseClient.list(); + expect(response.licenses).to.be.an("array"); + expect(response.licenses[0]).to.deep.equal(licenseMock1); + }); + + it("should throw an error if wrong request object", async function () { + axiosMock.post = sinon.stub().rejects(new Error("HTTP 500")); + //@ts-ignore + await expect(licenseClient.list({ foo: "bar" })).to.be.rejectedWith("HTTP 500"); + }); + }); + + describe("Test license.listParams", function () { + const mockListLicenseParamsRequest: ListLicenseParamsRequest = { + ipOrgId: process.env.TEST_IPORG_ID as string, + }; + const licenseParamMock = [ + { + ipOrgId: "0x7eb6248eaba29cf7a6c5a9c63a8416cb67cd1898", + frameworkId: "SPUML-1.0", + url: "https://github.com/storyprotocol/protocol-contracts/blob/main/SPUML-v1.pdf", + licensorConfig: 1, + params: [ + { + tag: "0x4368616e6e656c732d4f662d446973747269627574696f6e0000000000000018", + value: + "0x0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000274657374310000000000000000000000000000000000000000000000000000057465737432000000000000000000000000000000000000000000000000000005", + }, + { + tag: "0x4174747269627574696f6e00000000000000000000000000000000000000000b", + value: "0x", + }, + { + tag: "0x44657269766174697665732d416c6c6f77656400000000000000000000000013", + value: "0x0000000000000000000000000000000000000000000000000000000000000001", + }, + { + tag: "0x44657269766174697665732d416c6c6f7765642d4f7074696f6e73000000001b", + value: "0x0000000000000000000000000000000000000000000000000000000000000003", + }, + ], + createdAt: "1702039260", + txHash: "0xb2ce442fe9b685f7817ee2fbebbaeee063fb441ea60ad1c233b827c772a6fc46", + }, + ]; + + const expectedOutput = [ + { + ipOrgId: "0x7eb6248eaba29cf7a6c5a9c63a8416cb67cd1898", + frameworkId: "SPUML-1.0", + url: "https://github.com/storyprotocol/protocol-contracts/blob/main/SPUML-v1.pdf", + licensorConfig: 1, + params: [ + { + tag: "Channels-Of-Distribution", + value: ["", "", "test1", "test2"], + type: "string[]", + }, + { + tag: "Attribution", + type: "boolean", + value: false, + }, + { + tag: "Derivatives-Allowed", + type: "boolean", + value: true, + }, + { + tag: "Derivatives-Allowed-Options", + type: "string[]", + value: ["Allowed-Reciprocal-License", "Allowed-With-Attribution"], + }, + ], + createdAt: "1702039260", + txHash: "0xb2ce442fe9b685f7817ee2fbebbaeee063fb441ea60ad1c233b827c772a6fc46", + }, + ]; + + const mockResponse = sinon.stub().returns({ + data: { + licenseParams: licenseParamMock, + }, + }); + + it("should return a list of license params", async function () { + axiosMock.post = mockResponse; + + const response = await licenseClient.listParams(mockListLicenseParamsRequest); + expect(response.licenseParams).to.be.an("array"); + expect(response.licenseParams).to.deep.equal(expectedOutput); + }); + + it("should throw an error if wrong request object", async function () { + axiosMock.post = sinon.stub().rejects(new Error("HTTP 500")); + //@ts-ignore + await expect(licenseClient.listParams({ foo: "bar" })).to.be.rejectedWith("HTTP 500"); + }); + }); +}); diff --git a/packages/core-sdk/test/unit/resources/moduleReadOnly.test.ts b/packages/core-sdk/test/unit/resources/moduleReadOnly.test.ts new file mode 100644 index 00000000..b6bd5f6f --- /dev/null +++ b/packages/core-sdk/test/unit/resources/moduleReadOnly.test.ts @@ -0,0 +1,143 @@ +import { expect } from "chai"; +import { ModuleReadOnlyClient } from "../../../src"; +import { AxiosInstance } from "axios"; +import { createMock } from "../testUtils"; +import * as sinon from "sinon"; +import chai from "chai"; +import chaiAsPromised from "chai-as-promised"; +import { PublicClient } from "viem"; +import { mock } from "node:test"; + +chai.use(chaiAsPromised); + +describe("Test ModuleReadOnlyClient", function () { + let moduleClient: ModuleReadOnlyClient; + let axiosMock: AxiosInstance; + let rpcMock: PublicClient; + + beforeEach(function () { + axiosMock = createMock(); + rpcMock = createMock(); + moduleClient = new ModuleReadOnlyClient(axiosMock, rpcMock); + }); + + afterEach(function () { + sinon.restore(); + }); + + describe("Test moduleClient.get", function () { + const moduleMock = { + id: "2", + ipOrgId: "7", + interface: "(uint,uint)", + preHooks: [ + { + id: "1", + moduleId: "0x1234514e0193144e1d7024428ee242c44e5cacdbd7458c629d17c6366f6c5cb6", + interface: "(uint,uint)", + registeredAt: "0001-01-01T00:00:00Z", + txHash: "0x00a1a14e0193144e1d7024428ee242c44e5cacdbd7458c629d17c6366f6c5cb6", + }, + ], + postHooks: [ + { + id: "1", + moduleId: "0x1234514e0193144e1d7024428ee242c44e5cacdbd7458c629d17c6366f6c5cb6", + interface: "(uint,uint)", + registeredAt: "0001-01-01T00:00:00Z", + txHash: "0x00a1a14e0193144e1d7024428ee242c44e5cacdbd7458c629d17c6366f6c5cb6", + }, + ], + }; + it("should return module when the module id is valid", async function () { + axiosMock.get = sinon.stub().returns({ + data: { + module: moduleMock, + }, + }); + + const response = await moduleClient.get({ + moduleId: "0x1234514e0193144e1d7024428ee242c44e5cacdbd7458c629d17c6366f6c5cb6", + }); + + expect(response.module).to.deep.equal(moduleMock); + }); + + it("should throw error", async function () { + axiosMock.get = sinon.stub().rejects(new Error("http 500")); + await expect( + moduleClient.get({ + moduleId: "0x1234514e0193144e1d7024428ee242c44e5cacdbd7458c629d17c6366f6c5cb6", + }), + ).to.be.rejectedWith("http 500"); + }); + + it("should throw error if asset id is invalid", async function () { + try { + await moduleClient.get({ + moduleId: "fake module id", + }); + expect.fail(`Function should not get here, it should throw an error `); + } catch (error) { + // function is expected to throw. + } + }); + }); + + describe("Test moduleClient.list", async function () { + const moduleMock = { + id: "1", + ipOrgId: "7", + interface: "(address,uint)", + preHooks: [ + { + id: "1", + moduleId: "0x1234514e0193144e1d7024428ee242c44e5cacdbd7458c629d17c6366f6c5cb6", + interface: "(uint,uint)", + registeredAt: "0001-01-01T00:00:00Z", + txHash: "0x00a1a14e0193144e1d7024428ee242c44e5cacdbd7458c629d17c6366f6c5cb6", + }, + ], + postHooks: [ + { + id: "1", + moduleId: "0x1234514e0193144e1d7024428ee242c44e5cacdbd7458c629d17c6366f6c5cb6", + interface: "(uint,uint)", + registeredAt: "0001-01-01T00:00:00Z", + txHash: "0x00a1a14e0193144e1d7024428ee242c44e5cacdbd7458c629d17c6366f6c5cb6", + }, + ], + }; + + const mockResponse = sinon.stub().returns({ + data: { + modules: moduleMock, + }, + }); + + it("should return modules on a successful query", async function () { + axiosMock.post = mockResponse; + const response = await moduleClient.list({ + ipOrgId: "7", + }); + + expect(response.modules).to.deep.equal(moduleMock); + }); + + it("should return modules without the request object", async function () { + axiosMock.post = mockResponse; + const response = await moduleClient.list(); + + expect(response.modules).to.deep.equal(moduleMock); + }); + + it("should throw error", async function () { + axiosMock.post = sinon.stub().rejects(new Error("HTTP 500")); + await expect( + moduleClient.list({ + ipOrgId: "abc", + }), + ).to.be.rejectedWith("HTTP 500"); + }); + }); +}); diff --git a/packages/core-sdk/test/unit/resources/relationship.test.ts b/packages/core-sdk/test/unit/resources/relationship.test.ts new file mode 100644 index 00000000..277a8a2e --- /dev/null +++ b/packages/core-sdk/test/unit/resources/relationship.test.ts @@ -0,0 +1,166 @@ +import chai, { expect } from "chai"; +import { RelationshipClient } from "../../../src"; +import { createMock } from "../testUtils"; +import * as sinon from "sinon"; + +import chaiAsPromised from "chai-as-promised"; +import { AxiosInstance } from "axios"; +import { PublicClient, WalletClient, stringToHex } from "viem"; + +chai.use(chaiAsPromised); + +describe("Test RelationshipClient", function () { + let relationshipClient: RelationshipClient; + let axiosMock: AxiosInstance; + let rpcMock: PublicClient; + let walletMock: WalletClient; + + beforeEach(function () { + axiosMock = createMock(); + rpcMock = createMock(); + walletMock = createMock(); + relationshipClient = new RelationshipClient(axiosMock, rpcMock, walletMock); + }); + + afterEach(function () { + sinon.restore(); + }); + + describe("Test RelationshipClient.register", async () => { + it("should not throw error when registering a relationship", async function () { + rpcMock.simulateContract = sinon.stub().resolves({ request: null }); + walletMock.writeContract = sinon + .stub() + .resolves("0x129f7dd802200f096221dd89d5b086e4bd3ad6eafb378a0c75e3b04fc375f997"); + + const resp = await relationshipClient.register({ + ipOrgId: process.env.TEST_IPORG_ID as string, + relType: "appears_in", + srcContract: "0x177175a4b26f6EA050676F8c9a14D395F896492C", + srcTokenId: "4", + dstContract: "0x177175a4b26f6EA050676F8c9a14D395F896492C", + dstTokenId: "5", + preHookData: [ + { + interface: "address", + data: ["0xf398C12A45Bc409b6C652E25bb0a3e702492A4ab"], + }, + ], + postHookData: [ + { + interface: "address", + data: ["0xf398C12A45Bc409b6C652E25bb0a3e702492A4ab"], + }, + ], + txOptions: { + waitForTransaction: false, + }, + }); + + expect(resp.txHash).to.be.equal( + "0x129f7dd802200f096221dd89d5b086e4bd3ad6eafb378a0c75e3b04fc375f997", + ); + }); + + it("should not throw error when registering a relationship and wait for transaction confirmed", async function () { + rpcMock.simulateContract = sinon.stub().resolves({ request: null }); + walletMock.writeContract = sinon + .stub() + .resolves("0x6bf8053b1e8ffdc8a767938b14a59eb1e08cf8821743be7f8377e5bad77f76a8"); + rpcMock.waitForTransactionReceipt = sinon.stub().resolves({ + logs: [ + { + address: "0x49477130a70a37e0d6e22b674ef9e923e6d0202c", + topics: [ + "0xc1ab5d0231434d664068cd9e5f80a04152484f1844e564dd9fee5c687caa0d7c", + "0x0000000000000000000000000000000000000000000000000000000000000001", + ], + data: "0x00000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000ad2377c8f9f0ca6382fef166b08aede8318fe49c0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000ad2377c8f9f0ca6382fef166b08aede8318fe49c0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000a617070656172735f696e00000000000000000000000000000000000000000000", + blockNumber: 4727501, + transactionHash: "0x99d5736c65bd81cd4a361a731d4a035375a0926c95e4132e8fcb80ad5b602b5c", + transactionIndex: 105, + blockHash: "0x6677ab7dc2bab685131a05db009865faad06cbfb785c71813feaebed066e2f2d", + logIndex: 161, + removed: false, + }, + ], + }); + + const resp = await relationshipClient.register({ + ipOrgId: process.env.TEST_IPORG_ID as string, + relType: "appears_in", + srcContract: "0x177175a4b26f6EA050676F8c9a14D395F896492C", + srcTokenId: "4", + dstContract: "0x177175a4b26f6EA050676F8c9a14D395F896492C", + dstTokenId: "5", + txOptions: { + waitForTransaction: true, + }, + }); + + expect(resp.txHash).to.be.equal( + "0x6bf8053b1e8ffdc8a767938b14a59eb1e08cf8821743be7f8377e5bad77f76a8", + ); + }); + + it("should throw error when registerRelationship reverts", async function () { + rpcMock.simulateContract = sinon.stub().rejects(new Error("revert")); + await expect( + relationshipClient.register({ + ipOrgId: process.env.TEST_IPORG_ID as string, + relType: "appears_in", + srcContract: "0x177175a4b26f6EA050676F8c9a14D395F896492C", + srcTokenId: "4", + dstContract: "0x177175a4b26f6EA050676F8c9a14D395F896492C", + dstTokenId: "5", + preHookData: [], + postHookData: [], + txOptions: { + waitForTransaction: false, + }, + }), + ).to.be.rejectedWith("revert"); + }); + + it("should throw error when not found RelationshipCreated event", async function () { + rpcMock.simulateContract = sinon.stub().resolves({ request: null }); + walletMock.writeContract = sinon.stub().rejects(new Error("revert")); + + rpcMock.waitForTransactionReceipt = sinon.stub().resolves({ + logs: [ + { + address: "0x49477130a70a37e0d6e22b674ef9e923e6d0202c", + topics: [ + "0xc1ab5d0231434d664068cd9e5f80a04152484f1844e564dd9fee5c687caa0d7c", + "0x0000000000000000000000000000000000000000000000000000000000000001", + "0xfc7f0454ed02c478c10dae3ce113c900c4f9d3b10762ac2d41405fa8fc48713b", + ], + data: "0x000000000000000000000000177175a4b26f6ea050676f8c9a14d395f896492c0000000000000000000000000000000000000000000000000000000000000004000000000000000000000000177175a4b26f6ea050676f8c9a14d395f896492c0000000000000000000000000000000000000000000000000000000000000005", + blockNumber: 4727501, + transactionHash: "0x99d5736c65bd81cd4a361a731d4a035375a0926c95e4132e8fcb80ad5b602b5c", + transactionIndex: 105, + blockHash: "0x6677ab7dc2bab685131a05db009865faad06cbfb785c71813feaebed066e2f2d", + logIndex: 161, + removed: false, + }, + ], + }); + + await expect( + relationshipClient.register({ + ipOrgId: process.env.TEST_IPORG_ID as string, + relType: "appears_in", + srcContract: "0x177175a4b26f6EA050676F8c9a14D395F896492C", + srcTokenId: "4", + dstContract: "0x177175a4b26f6EA050676F8c9a14D395F896492C", + dstTokenId: "5", + preHookData: [], + postHookData: [], + txOptions: { + waitForTransaction: false, + }, + }), + ).to.be.rejectedWith("Failed to register relationship: revert"); + }); + }); +}); diff --git a/packages/core-sdk/test/unit/resources/relationshipReadOnly.test.ts b/packages/core-sdk/test/unit/resources/relationshipReadOnly.test.ts new file mode 100644 index 00000000..a1c6b96a --- /dev/null +++ b/packages/core-sdk/test/unit/resources/relationshipReadOnly.test.ts @@ -0,0 +1,125 @@ +import chai, { expect } from "chai"; +import { RelationshipClient } from "../../../src"; +import { createMock } from "../testUtils"; +import * as sinon from "sinon"; + +import chaiAsPromised from "chai-as-promised"; +import { AxiosInstance } from "axios"; +import { PublicClient, WalletClient, stringToHex } from "viem"; +import { + GetRelationshipRequest, + GetRelationshipResponse, + ListRelationshipRequest, + ListRelationshipResponse, +} from "../../../src/types/resources/relationship"; + +chai.use(chaiAsPromised); + +describe("Test RelationshipReadOnlyClient", function () { + let relationshipClient: RelationshipClient; + let axiosMock: AxiosInstance; + let rpcMock: PublicClient; + let walletMock: WalletClient; + + beforeEach(function () { + axiosMock = createMock(); + rpcMock = createMock(); + walletMock = createMock(); + relationshipClient = new RelationshipClient(axiosMock, rpcMock, walletMock); + }); + + afterEach(function () { + sinon.restore(); + }); + + describe("test RelationshipClient.get", () => { + const mockGetRequest: GetRelationshipRequest = { + relationshipId: "1", + options: { + pagination: { + offset: 0, + limit: 10, + }, + }, + }; + + it("should retrieve a relationship by its ID", async () => { + const mockResponse: { data: GetRelationshipResponse } = { + data: { + relationship: { + id: "rel-1234", + type: "APPEARS_IN", + srcContract: "0xSourceContractAddress", + srcTokenId: "srcToken123", + dstContract: "0xDestContractAddress", + dstTokenId: "dstToken456", + registeredAt: "2023-01-01T00:00:00Z", // ISO 8601 format + txHash: "0xTransactionHash", + }, + }, + }; + + axiosMock.get = sinon.stub().resolves(mockResponse); + const response = await relationshipClient.get(mockGetRequest); + expect(response).to.deep.equal(mockResponse.data); + }); + + it("should handle errors when retrieving a relationship", async () => { + axiosMock.get = sinon.stub().rejects(new Error("HTTP 500")); + await expect(relationshipClient.get(mockGetRequest)).to.be.rejectedWith("HTTP 500"); + }); + + it("should throw error if asset id is invalid", async function () { + try { + await relationshipClient.get({ + relationshipId: "fake relationship id", + }); + expect.fail(`Function should not get here, it should throw an error `); + } catch (error) { + // function is expected to throw. + } + }); + }); + + describe("test RelationshipClient.list", () => { + const mockListRequest: ListRelationshipRequest = { + tokenId: "token123", + contract: "0x309c205347e3826472643f9b7ebd8a50d64ccd9e", + options: { + pagination: { + offset: 0, + limit: 10, + }, + }, + }; + + it("should list all relationships", async () => { + const mockResponse: { data: ListRelationshipResponse } = { + data: { + relationships: [ + { + id: "rel-1234", + type: "APPEARS_IN", + srcContract: "0xSourceContractAddress", + srcTokenId: "srcToken123", + dstContract: "0xDestContractAddress", + dstTokenId: "dstToken456", + registeredAt: "2023-01-01T00:00:00Z", + txHash: "0xTransactionHash", + }, + // ... Add more dummy relationships as needed + ], + }, + }; + + axiosMock.post = sinon.stub().resolves(mockResponse); + const response = await relationshipClient.list(mockListRequest); + expect(response).to.deep.equal(mockResponse.data); + }); + + it("should handle errors when listing relationships", async () => { + axiosMock.post = sinon.stub().rejects(new Error("HTTP 500")); + await expect(relationshipClient.list(mockListRequest)).to.be.rejectedWith("HTTP 500"); + }); + }); +}); diff --git a/packages/core-sdk/test/unit/resources/relationshipType.test.ts b/packages/core-sdk/test/unit/resources/relationshipType.test.ts new file mode 100644 index 00000000..128fa2af --- /dev/null +++ b/packages/core-sdk/test/unit/resources/relationshipType.test.ts @@ -0,0 +1,164 @@ +import chai, { expect } from "chai"; +import { RelationshipTypeClient } from "../../../src/resources/relationshipType"; +import { createMock } from "../testUtils"; +import * as sinon from "sinon"; + +import chaiAsPromised from "chai-as-promised"; +import { AxiosInstance } from "axios"; +import { PublicClient, WalletClient } from "viem"; +import exp from "constants"; + +chai.use(chaiAsPromised); + +describe("Test Relationship Type Client", function () { + let relationshipClient: RelationshipTypeClient; + let axiosMock: AxiosInstance; + let rpcMock: PublicClient; + let walletMock: WalletClient; + + beforeEach(function () { + axiosMock = createMock(); + rpcMock = createMock(); + walletMock = createMock(); + relationshipClient = new RelationshipTypeClient(axiosMock, rpcMock, walletMock); + }); + + afterEach(function () { + sinon.restore(); + }); + + describe("Test RelationshipClient.registerRelationshipType", () => { + it("should not throw error when registering a relationship type", async function () { + rpcMock.simulateContract = sinon.stub().resolves({ request: null }); + walletMock.writeContract = sinon + .stub() + .resolves("0x129f7dd802200f096221dd89d5b086e4bd3ad6eafb378a0c75e3b04fc375f997"); + + const resp = await relationshipClient.register({ + ipOrgId: "0xb422E54932c1dae83E78267A4DD2805aa64A8061", + relType: "appears_in", + relatedElements: { + src: 1, + dst: 1, + }, + allowedSrcIpAssetTypes: [1], + allowedDstIpAssetTypes: [1], + txOptions: { + waitForTransaction: false, + }, + }); + expect(resp.txHash).to.be.equal( + "0x129f7dd802200f096221dd89d5b086e4bd3ad6eafb378a0c75e3b04fc375f997", + ); + }); + + it("should not throw error when registering a relationship type and wait for transaction confirmed", async function () { + rpcMock.simulateContract = sinon.stub().resolves({ request: null }); + walletMock.writeContract = sinon + .stub() + .resolves("0x6bf8053b1e8ffdc8a767938b14a59eb1e08cf8821743be7f8377e5bad77f76a8"); + rpcMock.waitForTransactionReceipt = sinon.stub().resolves({ + logs: [ + { + address: "0x49477130a70a37e0d6e22b674ef9e923e6d0202c", + topics: [ + "0x5afe4586ed79afd39271a5d07aaa8d60de58e6e9a48ebf10c8f1ce828b592e75", + "0xfc7f0454ed02c478c10dae3ce113c900c4f9d3b10762ac2d41405fa8fc48713b", + ], + data: "0x00000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000ad2377c8f9f0ca6382fef166b08aede8318fe49c00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ad2377c8f9f0ca6382fef166b08aede8318fe49c00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a617070656172735f696e00000000000000000000000000000000000000000000", + blockNumber: 4727501, + transactionHash: "0x99d5736c65bd81cd4a361a731d4a035375a0926c95e4132e8fcb80ad5b602b5c", + transactionIndex: 105, + blockHash: "0x6677ab7dc2bab685131a05db009865faad06cbfb785c71813feaebed066e2f2d", + logIndex: 161, + removed: false, + }, + ], + }); + + const resp = await relationshipClient.register({ + ipOrgId: "0xb422E54932c1dae83E78267A4DD2805aa64A8061", + relType: "appears_in", + relatedElements: { + src: 1, + dst: 1, + }, + allowedSrcIpAssetTypes: [1], + allowedDstIpAssetTypes: [1], + txOptions: { + waitForTransaction: true, + }, + }); + expect(resp.txHash).to.be.equal( + "0x6bf8053b1e8ffdc8a767938b14a59eb1e08cf8821743be7f8377e5bad77f76a8", + ); + }); + + it("should throw error when registerRelationshipType reverts", async function () { + rpcMock.simulateContract = sinon.stub().rejects(new Error("revert")); + await expect( + relationshipClient.register({ + ipOrgId: "0xb422E54932c1dae83E78267A4DD2805aa64A8061", + relType: "appears_in", + relatedElements: { + src: 1, + dst: 1, + }, + allowedSrcIpAssetTypes: [1], + allowedDstIpAssetTypes: [1], + preHooksConfig: [], + postHooksConfig: [], + txOptions: { + waitForTransaction: false, + }, + }), + ).to.be.rejectedWith("revert"); + }); + + it("should throw error when not found RelationshipTypeSet event", async function () { + rpcMock.simulateContract = sinon.stub().resolves({ request: null }); + walletMock.writeContract = sinon + .stub() + .resolves("0x6bf8053b1e8ffdc8a767938b14a59eb1e08cf8821743be7f8377e5bad77f76a8"); + rpcMock.waitForTransactionReceipt = sinon.stub().resolves({ + logs: [ + { + address: "0x49477130a70a37e0d6e22b674ef9e923e6d0202c", + topics: [ + "0x5afe4586ed79afd39271a5d07aaa8d60de58e6e9a48ebf10c8f1ce828b592e75", + "0xfc7f0454ed02c478c10dae3ce113c900c4f9d3b10762ac2d41405fa8fc48713b", + "0xb422E54932c1dae83E78267A4DD2805aa64A8061", + ], + data: "0x000000000000000000000000177175a4b26f6ea050676f8c9a14d395f896492c00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000177175a4b26f6ea050676f8c9a14d395f896492c00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000", + blockNumber: 4727501, + transactionHash: "0x99d5736c65bd81cd4a361a731d4a035375a0926c95e4132e8fcb80ad5b602b5c", + transactionIndex: 105, + blockHash: "0x6677ab7dc2bab685131a05db009865faad06cbfb785c71813feaebed066e2f2d", + logIndex: 161, + removed: false, + }, + ], + }); + + await expect( + relationshipClient.register({ + ipOrgId: "0xb422E54932c1dae83E78267A4DD2805aa64A8061", + relType: "appears_in", + relatedElements: { + src: 1, + dst: 1, + }, + allowedSrcIpAssetTypes: [1], + allowedDstIpAssetTypes: [1], + preHooksConfig: [], + postHooksConfig: [], + txOptions: { + waitForTransaction: true, + }, + }), + ).to.be.rejectedWith( + "Failed to register relationship type: not found event RelationshipTypeSet in target transaction", + ); + }); + }); +}); diff --git a/packages/core-sdk/test/unit/resources/relationshipTypeReadOnly.test.ts b/packages/core-sdk/test/unit/resources/relationshipTypeReadOnly.test.ts new file mode 100644 index 00000000..786a71e9 --- /dev/null +++ b/packages/core-sdk/test/unit/resources/relationshipTypeReadOnly.test.ts @@ -0,0 +1,181 @@ +import chai, { expect } from "chai"; +import { RelationshipTypeReadOnlyClient } from "../../../src/resources/relationshipTypeReadOnly"; +import { createMock } from "../testUtils"; +import * as sinon from "sinon"; + +import chaiAsPromised from "chai-as-promised"; +import { AxiosInstance } from "axios"; +import { PublicClient, WalletClient, stringToHex } from "viem"; +import { + GetRelationshipTypeRequest, + GetRelationshipTypeResponse, + ListRelationshipTypesRequest, + ListRelationshipTypesResponse, +} from "../../../src/types/resources/relationshipType"; + +chai.use(chaiAsPromised); + +describe("Test RelationshipTypeReadOnlyClient", function () { + let relationshipTypeClient: RelationshipTypeReadOnlyClient; + let axiosMock: AxiosInstance; + let rpcMock: PublicClient; + let walletMock: WalletClient; + + beforeEach(function () { + axiosMock = createMock(); + rpcMock = createMock(); + walletMock = createMock(); + relationshipTypeClient = new RelationshipTypeReadOnlyClient(axiosMock, rpcMock); + }); + + afterEach(function () { + sinon.restore(); + }); + + describe("test RelationshipTypeClient.get", () => { + it("should retrieve a RelationshipType by its ip org id", async () => { + const mockGetRequest: GetRelationshipTypeRequest = { + ipOrgId: "0xb422e54932c1dae83e78267a4dd2805aa64a8061", + relType: "0xc12a5f0d1e5a95f4fc32ff629c53defa11273a372e29ae51ab24323e4af84fc3", + }; + const mockResponse: { data: GetRelationshipTypeResponse } = { + data: { + relationshipType: { + dstContract: "0x177175a4b26f6ea050676f8c9a14d395f896492c", + dstRelatable: 1, + dstSubtypesMask: 0, + ipOrgId: "0xb422e54932c1dae83e78267a4dd2805aa64a8061", + type: "0xc12a5f0d1e5a95f4fc32ff629c53defa11273a372e29ae51ab24323e4af84fc3", + srcContract: "0x177175a4b26f6ea050676f8c9a14d395f896492c", + srcRelatable: 1, + srcSubtypesMask: 0, + txHash: "0x02230010bf433393ad3999c95a2af63c73bf8e5c620c5e607de7648d7a8565a6", + registeredAt: "2021-09-14T00:00:00Z", + }, + }, + }; + + axiosMock.get = sinon.stub().resolves(mockResponse); + const response = await relationshipTypeClient.get(mockGetRequest); + expect(response).to.deep.equal(mockResponse.data); + }); + + it("should handle errors when retrieving a RelationshipType", async () => { + const mockGetRequest: GetRelationshipTypeRequest = { + ipOrgId: "0xb422e54932c1dae83e78267a4dd2805aa64a8061", + relType: "0xc12a5f0d1e5a95f4fc32ff629c53defa11273a372e29ae51ab24323e4af84ac3", // incorrect relType + }; + axiosMock.get = sinon.stub().rejects(new Error("HTTP 500")); + await expect(relationshipTypeClient.get(mockGetRequest)).to.be.rejectedWith("HTTP 500"); + }); + + it("should throw error if asset id is invalid", async function () { + const mockResponse: { data: GetRelationshipTypeResponse } = { + data: { + relationshipType: { + dstContract: "0x177175a4b26f6ea050676f8c9a14d395f896492c", + dstRelatable: 1, + dstSubtypesMask: 0, + ipOrgId: "0xb422e54932c1dae83e78267a4dd2805aa64a8061", + type: "0xc12a5f0d1e5a95f4fc32ff629c53defa11273a372e29ae51ab24323e4af84fc3", + srcContract: "0x177175a4b26f6ea050676f8c9a14d395f896492c", + srcRelatable: 1, + srcSubtypesMask: 0, + txHash: "0x02230010bf433393ad3999c95a2af63c73bf8e5c620c5e607de7648d7a8565a6", + registeredAt: "2021-09-14T00:00:00Z", + }, + }, + }; + + axiosMock.get = sinon.stub().resolves(mockResponse); + await expect( + relationshipTypeClient.get({ + ipOrgId: "0xb422e54932c1dae83e78267a4dd2805aa64a61", // invalid ipOrgId + relType: "0xc12a5f0d1e5a95f4fc32ff629c53defa11273a372e29ae51ab24323e4af84fc3", + }), + ).to.be.rejectedWith( + `Failed to get relationship type: Invalid ipOrgId. Must be an address. But got: 0xb422e54932c1dae83e78267a4dd2805aa64a61`, + ); + }); + }); + + describe("test RelationshipTypeReadOnlyClient.list", () => { + const mockListRequest: ListRelationshipTypesRequest = { + ipOrgId: "0xb422e54932c1dae83e78267a4dd2805aa64a8061", + options: { + pagination: { + offset: 0, + limit: 10, + }, + }, + }; + + it("should list all RelationshipTypes", async () => { + const mockResponse: { data: ListRelationshipTypesResponse } = { + data: { + relationshipTypes: [ + { + dstContract: "0x177175a4b26f6ea050676f8c9a14d395f896492c", + dstRelatable: 1, + dstSubtypesMask: 0, + ipOrgId: "0xb422e54932c1dae83e78267a4dd2805aa64a8061", + type: "0xc12a5f0d1e5a95f4fc32ff629c53defa11273a372e29ae51ab24323e4af84fc3", + srcContract: "0x177175a4b26f6ea050676f8c9a14d395f896492c", + srcRelatable: 1, + srcSubtypesMask: 0, + txHash: "0x02230010bf433393ad3999c95a2af63c73bf8e5c620c5e607de7648d7a8565a6", + registeredAt: "2021-09-14T00:00:00Z", + }, + // ... Add more dummy RelationshipTypes as needed + ], + }, + }; + + axiosMock.post = sinon.stub().resolves(mockResponse); + const response = await relationshipTypeClient.list(mockListRequest); + expect(response).to.deep.equal(mockResponse.data); + }); + + describe("test RelationshipTypeReadOnlyClient.list without specifying an iporgid", () => { + const mockListRequest: ListRelationshipTypesRequest = { + options: { + pagination: { + offset: 0, + limit: 10, + }, + }, + }; + + it("should list all RelationshipTypes", async () => { + const mockResponse: { data: ListRelationshipTypesResponse } = { + data: { + relationshipTypes: [ + { + dstContract: "0x177175a4b26f6ea050676f8c9a14d395f896492c", + dstRelatable: 1, + dstSubtypesMask: 0, + ipOrgId: "0xb422e54932c1dae83e78267a4dd2805aa64a8061", + type: "0xc12a5f0d1e5a95f4fc32ff629c53defa11273a372e29ae51ab24323e4af84fc3", + srcContract: "0x177175a4b26f6ea050676f8c9a14d395f896492c", + srcRelatable: 1, + srcSubtypesMask: 0, + txHash: "0x02230010bf433393ad3999c95a2af63c73bf8e5c620c5e607de7648d7a8565a6", + registeredAt: "2021-09-14T00:00:00Z", + }, + // ... Add more dummy RelationshipTypes as needed + ], + }, + }; + + axiosMock.post = sinon.stub().resolves(mockResponse); + const response = await relationshipTypeClient.list(mockListRequest); + expect(response).to.deep.equal(mockResponse.data); + }); + + it("should handle errors when listing RelationshipTypes", async () => { + axiosMock.post = sinon.stub().rejects(new Error("HTTP 500")); + await expect(relationshipTypeClient.list(mockListRequest)).to.be.rejectedWith("HTTP 500"); + }); + }); + }); +}); diff --git a/packages/core-sdk/test/unit/resources/transactionReadOnly.test.ts b/packages/core-sdk/test/unit/resources/transactionReadOnly.test.ts new file mode 100644 index 00000000..c7c3cb0d --- /dev/null +++ b/packages/core-sdk/test/unit/resources/transactionReadOnly.test.ts @@ -0,0 +1,98 @@ +import { AxiosInstance } from "axios"; +import * as sinon from "sinon"; +import { createMock } from "../testUtils"; +import chai from "chai"; +import { expect } from "chai"; +import chaiAsPromised from "chai-as-promised"; +import { PublicClient, WalletClient } from "viem"; +import { ResourceType, TransactionClient, ActionType } from "../../../src"; + +chai.use(chaiAsPromised); + +describe("Test TransactionClient", function () { + let transactionClient: TransactionClient; + let axiosMock: AxiosInstance; + let rpcMock: PublicClient; + let walletMock: WalletClient; + + beforeEach(function () { + axiosMock = createMock(); + rpcMock = createMock(); + walletMock = createMock(); + transactionClient = new TransactionClient(axiosMock, rpcMock, walletMock); + }); + + afterEach(function () { + sinon.restore(); + }); + + describe("Test transactionClient.get", function () { + const transactionMock = { + id: "1", + txHash: "0x00a1a14e0193144e1d7024428ee242c44e5cacdbd7458c629d17c6366f6c5cb6", + ipOrgId: "7", + resourceId: "1", + resourceType: ResourceType.IPAsset, + actionType: ActionType.Create, + initiator: "0x4f9693ac46f2c7e2f48dd14d8fe1ab44192cd57d", + createdAt: "0001-01-01T00:00:00Z", + }; + it("should get transaction ", async function () { + axiosMock.get = sinon.stub().resolves({ + data: { + transaction: transactionMock, + }, + }); + + const response = await transactionClient.get({ transactionId: "1" }); + expect(response.transaction).to.deep.equal(transactionMock); + }); + + it("should be able to throw an error", async function () { + axiosMock.get = sinon.stub().rejects(new Error("HTTP 500")); + await expect(transactionClient.get({ transactionId: "abc" })).to.be.rejectedWith("HTTP 500"); + }); + }); + + describe("Test transactionClient.list", function () { + const transactionMock1 = { + id: "1", + txHash: "0x00a1a14e0193144e1d7024428ee242c44e5cacdbd7458c629d17c6366f6c5cb6", + ipOrgId: "7", + resourceId: "1", + resourceType: ResourceType.IPAsset, + actionType: ActionType.Configure, + initiator: "0x4f9693ac46f2c7e2f48dd14d8fe1ab44192cd57d", + createdAt: "0001-01-01T00:00:00Z", + }; + const transactionMock2 = { + id: "2", + txHash: "0x00a1a14e0193144e1d7024428ee242c44e5cacdbd7458c629d17c6366f6c5cb6", + ipOrgId: "7", + resourceId: "2", + resourceType: "License", + actionType: ActionType.Register, + initiator: "0xd84316a1b6f40902c17b8177854cdaeb3c957daf", + createdAt: "0001-01-01T00:00:00Z", + }; + it("should return list of collections", async function () { + axiosMock.post = sinon.stub().resolves({ + data: { + transactions: [transactionMock1, transactionMock2], + }, + }); + + const response = await transactionClient.list(); + const transactions = response.transactions; + + // First transaction in array + expect(transactions[0]).to.be.deep.equal(transactionMock1); + expect(transactions[1]).to.be.deep.equal(transactionMock2); + }); + + it("should be able to throw an error", async function () { + axiosMock.post = sinon.stub().rejects(new Error("HTTP 500")); + await expect(transactionClient.list()).to.be.rejectedWith("HTTP 500"); + }); + }); +}); diff --git a/packages/core-sdk/test/unit/testUtils.ts b/packages/core-sdk/test/unit/testUtils.ts new file mode 100644 index 00000000..3f6f3b57 --- /dev/null +++ b/packages/core-sdk/test/unit/testUtils.ts @@ -0,0 +1,75 @@ +export function createMock(obj = {}): T { + const mockObj: any = obj; + return mockObj; +} + +export function createFileReaderMock( + base64: string, + onLoadEvent?: ProgressEvent, + onErrorEvent?: ProgressEvent, +) { + return class FileReaderMock { + // Adding required static properties + readonly EMPTY = 0; + readonly LOADING = 1; + readonly DONE = 2; + + onload: ((this: FileReader, ev: ProgressEvent) => any) | null = null; + onabort: ((this: FileReader, ev: ProgressEvent) => any) | null = null; + onerror: ((this: FileReader, ev: ProgressEvent) => any) | null = null; + onloadstart: ((this: FileReader, ev: ProgressEvent) => any) | null = null; + onloadend: ((this: FileReader, ev: ProgressEvent) => any) | null = null; + onprogress: ((this: FileReader, ev: ProgressEvent) => any) | null = null; + // Properties + readyState: 0 | 1 | 2 = 0; + result: string | ArrayBuffer | null = null; + error: DOMException | null = null; + + // Simulate the readAsDataURL method + readAsDataURL(blob: Blob) { + setTimeout(() => { + // Implementation of your mock logic + // For example, setting the result and triggering onload + this.result = base64; // Simulated result + if (onLoadEvent) { + this.onload?.(onLoadEvent); + } + if (onErrorEvent) { + this.onerror?.(onErrorEvent); + } + }, 100); // Simulate async behavior + } + + abort(): void { + /* Mock implementation */ + } + readAsArrayBuffer(blob: Blob): void { + /* Mock implementation */ + } + readAsBinaryString(blob: Blob): void { + /* Mock implementation */ + } + readAsText(blob: Blob, encoding?: string): void { + /* Mock implementation */ + } + + // Adding event listener methods + addEventListener( + type: string, + listener: EventListenerOrEventListenerObject, + options?: boolean | AddEventListenerOptions, + ): void { + /* Mock implementation */ + } + removeEventListener( + type: string, + listener: EventListenerOrEventListenerObject, + options?: boolean | EventListenerOptions, + ): void { + /* Mock implementation */ + } + dispatchEvent(event: Event): boolean { + /* Mock implementation */ return false; + } + }; +} diff --git a/packages/core-sdk/test/unit/utils/errors.test.ts b/packages/core-sdk/test/unit/utils/errors.test.ts new file mode 100644 index 00000000..a4f9a776 --- /dev/null +++ b/packages/core-sdk/test/unit/utils/errors.test.ts @@ -0,0 +1,20 @@ +import { expect } from "chai"; +import { handleError } from "../../../src/utils/errors"; + +describe("Test handleError", function () { + it("should throw unknown error message when passing in a non-Error error", function () { + try { + handleError({}, "abc"); + } catch (error) { + expect((error as Error).message).to.equal("abc: Unknown error type"); + } + }); + + it("should throw normal error message when passing in aError", function () { + try { + handleError(new Error("cde"), "abc"); + } catch (error) { + expect((error as Error).message).to.equal("abc: cde"); + } + }); +}); diff --git a/packages/core-sdk/test/unit/utils/mockData.ts b/packages/core-sdk/test/unit/utils/mockData.ts new file mode 100644 index 00000000..cf61630b --- /dev/null +++ b/packages/core-sdk/test/unit/utils/mockData.ts @@ -0,0 +1,70 @@ +export const mockCreateAndConfigureLicenseLog = [ + { + address: "0xe0ad549069628f7a06d60a07547df9073e3c6157", + topics: ["0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498"], + data: "0x0000000000000000000000000000000000000000000000000000000000000001", + blockNumber: 4846623n, + transactionHash: "0x54e086d1b286f29ea8a5278048a57ab0ac5ba4a83c74a5f1e399d076445bd6b3", + transactionIndex: 75, + blockHash: "0x1d370422cf3325516fd70547411be27650be60e99453f9012d7fade0d8321d2a", + logIndex: 130, + removed: false, + }, + { + address: "0x4bf7387c9666f5a30604b3dcba1dc6edfc50d4a2", + topics: [ + "0x48786003f3d30e41bfa4ee09afdeb9bfb04b7e06e2f74f3177da393a793bbc33", + "0x000000000000000000000000e0ad549069628f7a06d60a07547df9073e3c6157", + "0x0000000000000000000000006fb096d829304acec8922a10a8c2581e8e84695a", + ], + data: "0x000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000013524547495354524154494f4e5f4d4f44554c450000000000000000000000000000000000000000000000000000000000000000000000000000000000000001609aeb830ec91a14c97a5446cc7c86a42f73a78f37f9a77afa238b5d11520ddfbc000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000553746f727900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000094368617261637465720000000000000000000000000000000000000000000000", + blockNumber: 4846623n, + transactionHash: "0x54e086d1b286f29ea8a5278048a57ab0ac5ba4a83c74a5f1e399d076445bd6b3", + transactionIndex: 75, + blockHash: "0x1d370422cf3325516fd70547411be27650be60e99453f9012d7fade0d8321d2a", + logIndex: 131, + removed: false, + }, + { + address: "0x6fb096d829304acec8922a10a8c2581e8e84695a", + topics: ["0x81e084d978860accc83df39f75b801d9019e40d18643b9b39f4cd2a70ca35adb"], + data: "0x000000000000000000000000e17aa3e4bfe9812b64354e5275a211216f1dee2a000000000000000000000000e0ad549069628f7a06d60a07547df9073e3c615700000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000013416c69636520496e20576f6e6465726c616e640000000000000000000000000000000000000000000000000000000000000000000000000000000000000000034149570000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000553746f727900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000094368617261637465720000000000000000000000000000000000000000000000", + blockNumber: 4846623n, + transactionHash: "0x54e086d1b286f29ea8a5278048a57ab0ac5ba4a83c74a5f1e399d076445bd6b3", + transactionIndex: 75, + blockHash: "0x1d370422cf3325516fd70547411be27650be60e99453f9012d7fade0d8321d2a", + logIndex: 132, + removed: false, + }, + { + address: "0xd6ab11ce59ab4f3fac577a83d169a5666eac329c", + topics: [ + "0x0eaf6d681055f593c54be5a95da92bb2249915d24efbd7686fd32f6f89784204", + "0x000000000000000000000000000000000000000000000000000000000000000c", + ], + data: "0x0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f398c12a45bc409b6c652e25bb0a3e702492a4ab000000000000000000000000e17aa3e4bfe9812b64354e5275a211216f1dee2a000000000000000000000000e0ad549069628f7a06d60a07547df9073e3c6157000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + blockNumber: 4846625n, + transactionHash: "0x8e550b7201db47b6ffa14eaaa3d6218ba2ee65210539a9a271a017033ca23ada", + transactionIndex: 82, + blockHash: "0x66b9f3e551e7fa81f18b7ef3b4585c92993a35319803beb4534e82ac0aabde43", + logIndex: 104, + removed: false, + }, +]; + +export const mockCreateLicenseLog = [ + { + address: "0xcd28eb9d0d2afcf4354f2c93de5ce9bbf88257ae", + topics: [ + "0xfa538431a8d5829af24905451de4c43e40cc50ea0716dac651047b78e3d6f02b", + "0x0000000000000000000000000000000000000000000000000000000000000041", + ], + data: "0x000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f398c12a45bc409b6c652e25bb0a3e702492a4ab000000000000000000000000f398c12a45bc409b6c652e25bb0a3e702492a4ab0000000000000000000000008b2041ad29e1d0ef7bf838c7830b3eaa3081fa5f5350554d4c2d312e30000000000000000000000000000000000000000000000900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + blockNumber: 4845112n, + transactionHash: "0x3a42319eecb4811e6b303e82208033097969eadb566294becdc63f88ffbbd5cc", + transactionIndex: 83, + blockHash: "0x8cb49c87126f651eeb3e704c1ef5fbf3635c0eef1a95848bf7fb8aceda7709c2", + logIndex: 75, + removed: false, + }, +]; diff --git a/packages/core-sdk/test/unit/utils/platform.test.ts b/packages/core-sdk/test/unit/utils/platform.test.ts new file mode 100644 index 00000000..fd14a76f --- /dev/null +++ b/packages/core-sdk/test/unit/utils/platform.test.ts @@ -0,0 +1,121 @@ +import { AxiosInstance } from "axios"; +import * as sinon from "sinon"; +import { PlatformClient } from "../../../src"; +import chai from "chai"; +import { expect } from "chai"; +import chaiAsPromised from "chai-as-promised"; +import { createMock, createFileReaderMock } from "../testUtils"; +import { PublicClient, WalletClient } from "viem"; + +chai.use(chaiAsPromised); + +describe("Test PlatformClient", function () { + let platformClient: PlatformClient; + let axiosMock: AxiosInstance; + let rpcMock: PublicClient; + let walletMock: WalletClient; + + let mockFile = new File([""], "test.png", { type: "image/png" }); + let mockBuffer = Buffer.from("test"); + this.beforeEach(function () { + axiosMock = createMock(); + rpcMock = createMock(); + walletMock = createMock(); + platformClient = new PlatformClient(axiosMock); + }); + + afterEach(function () { + sinon.restore(); + }); + + describe("Test platform.uploadFile", function () { + before(() => { + const onLoadEvent = new Event("load") as unknown as ProgressEvent; + global.FileReader = createFileReaderMock( + "data:base64,dGVzdCBzdHJpbmcgYmxvYg==", + onLoadEvent, + ) as any; + }); + + it("should return url when the upload file transaction is successful on the client", async function () { + const mockPreSignUrlResp = { + data: { + url: "https://example.com/upload", + key: "file-key", + }, + }; + const mockArweaveUrl = "https://arweave.net/SVBYzNCI8-GdUCe1_N9eA2Nol0rYi_AH-CBw1vo2YUM"; + const mockUploadConfirmResp = { + data: { + uri: mockArweaveUrl, + }, + }; + axiosMock.post = sinon + .stub() + .withArgs("/platform/file-upload/request") + .resolves(mockPreSignUrlResp) + .withArgs("/platform/file-upload/confirm") + .resolves(mockUploadConfirmResp); + axiosMock.put = sinon.stub().resolves({ status: 200 }); + + const response = await platformClient.uploadFile(mockFile, "image/png"); + expect(response.uri).to.equal(mockArweaveUrl); + }); + + it("should return url when the upload file transaction is successful on the server", async function () { + const mockPreSignUrlResp = { + data: { + url: "https://example.com/upload", + key: "file-key", + }, + }; + const mockArweaveUrl = "https://arweave.net/SVBYzNCI8-GdUCe1_N9eA2Nol0rYi_AH-CBw1vo2YUM"; + const mockUploadConfirmResp = { + data: { + uri: mockArweaveUrl, + }, + }; + axiosMock.post = sinon + .stub() + .withArgs("/platform/file-upload/request") + .resolves(mockPreSignUrlResp) + .withArgs("/platform/file-upload/confirm") + .resolves(mockUploadConfirmResp); + axiosMock.put = sinon.stub().resolves({ status: 200 }); + + const response = await platformClient.uploadFile(mockBuffer, "image/png"); + expect(response.uri).to.equal(mockArweaveUrl); + }); + + it("should throw error when it failed to upload files to s3", async function () { + const mockPreSignUrlResp = { + data: { + url: "https://example.com/upload", + key: "file-key", + }, + }; + const mockArweaveUrl = "https://arweave.net/SVBYzNCI8-GdUCe1_N9eA2Nol0rYi_AH-CBw1vo2YUM"; + const mockUploadConfirmResp = { + data: { + uri: mockArweaveUrl, + }, + }; + axiosMock.post = sinon + .stub() + .withArgs("/platform/file-upload/request") + .resolves(mockPreSignUrlResp) + .withArgs("/platform/file-upload/confirm") + .resolves(mockUploadConfirmResp); + axiosMock.put = sinon.stub().resolves({ status: 400 }); + + await expect(platformClient.uploadFile(mockBuffer, "image/png")).to.be.rejectedWith( + "Failed to upload file: Failed to upload file to s3. Status: 400", + ); + }); + + it("should throw error", async function () { + axiosMock.post = sinon.stub().rejects(new Error("revert")); + await expect(platformClient.uploadFile(mockFile, "image/png")).to.be.rejectedWith("revert"); + }); + }); +}); diff --git a/packages/core-sdk/test/unit/utils/utils.test.ts b/packages/core-sdk/test/unit/utils/utils.test.ts new file mode 100644 index 00000000..1d066697 --- /dev/null +++ b/packages/core-sdk/test/unit/utils/utils.test.ts @@ -0,0 +1,172 @@ +import { expect } from "chai"; +import { + decodeChannelsOfDistribution, + decodeDerivativesAllowedOptions, + decodeShortstring, + isIntegerString, + paramsTagValueDecoder, + parseToBigInt, + splitIntoBytes32, +} from "../../../src/utils/utils"; + +describe("Test isIntegerString", function () { + it("should return true when passing in an integer string", function () { + expect(isIntegerString("7")).to.be.true; + }); + + it("should return false when passing in a non-integer string", function () { + expect(isIntegerString("a")).to.be.false; + }); + + it("should parse string to big int", function () { + expect(parseToBigInt("7")).to.be.equal(7n); + }); +}); + +describe("Test decodeShortstring", function () { + it("should decode a short string", function () { + const encodedString = "0x4368616e6e656c732d4f662d446973747269627574696f6e0000000000000018"; // "Hello World" in hex + const decodedString = decodeShortstring(encodedString); + expect(decodedString).to.equal("Channels-Of-Distribution"); + }); + + it("should return an empty string for an empty input", function () { + const encodedString = "0x"; + const decodedString = decodeShortstring(encodedString); + expect(decodedString).to.equal(""); + }); +}); + +describe("Test decodeChannelsOfDistribution", function () { + it("should decode a hex value to an array of strings", function () { + const hexValue = "0x6368616e6e656c31000000000000000000000000000000000000000000000000"; // "channel1" in hex + const decodedArray = decodeChannelsOfDistribution(hexValue); + expect(decodedArray).to.deep.equal(["channel1"]); + }); + + it("should decode multiple hex values to an array of strings", function () { + const hexValue = + "0x6368616e6e656c310000000000000000000000000000000000000000000000006368616e6e656c32000000000000000000000000000000000000000000000000"; // "channel1" and "channel2" in hex + const decodedArray = decodeChannelsOfDistribution(hexValue); + expect(decodedArray).to.deep.equal(["channel1", "channel2"]); + }); + + it("should return an empty array for an empty input", function () { + const hexValue = "0x"; + const decodedArray = decodeChannelsOfDistribution(hexValue); + expect(decodedArray).to.deep.equal([]); + }); +}); + +describe("decodeDerivativesAllowedOptions", () => { + const options = ["Option1", "Option2", "Option3"]; + + it("correctly decodes options based on a bitmask", () => { + const bitmask: number[] = [1, 0, 1]; + expect(decodeDerivativesAllowedOptions(bitmask, options)).to.deep.equal(["Option1", "Option3"]); + }); + + it("returns no options for a bitmask of all zeros", () => { + const bitmask: number[] = [0, 0, 0]; + expect(decodeDerivativesAllowedOptions(bitmask, options)).to.deep.equal([]); + }); + + it("returns all options for a bitmask of all ones", () => { + const bitmask: number[] = [1, 1, 1]; + expect(decodeDerivativesAllowedOptions(bitmask, options)).to.deep.equal(options); + }); + + it("returns no options for an empty bitmask", () => { + const bitmask: number[] = []; + expect(decodeDerivativesAllowedOptions(bitmask, options)).to.deep.equal([]); + }); + + it("returns an empty array for an empty options array", () => { + const bitmask: number[] = [1, 0, 1]; + expect(decodeDerivativesAllowedOptions(bitmask, [])).to.deep.equal([]); + }); + + it("handles bitmask longer than options array", () => { + const bitmask: number[] = [1, 0, 1, 1]; + expect(decodeDerivativesAllowedOptions(bitmask, options)).to.deep.equal(["Option1", "Option3"]); + }); + + it("handles options array longer than bitmask", () => { + const bitmask: number[] = [1, 0]; + expect(decodeDerivativesAllowedOptions(bitmask, options)).to.deep.equal(["Option1"]); + }); +}); + +describe("splitIntoBytes32", () => { + it("splits a valid hex string into bytes32 chunks", () => { + const hexString = "a".repeat(64); + const result = splitIntoBytes32(hexString); + expect(result).to.deep.equal(["0x" + "a".repeat(64)]); + }); + + it("handles hex strings with 0x prefix correctly", () => { + const hexString = "0x" + "b".repeat(64); + const result = splitIntoBytes32(hexString); + expect(result).to.deep.equal(["0x" + "b".repeat(64)]); + }); + + it("throws an error if hex string length is not a multiple of 64", () => { + const hexString = "c".repeat(63); + expect(() => splitIntoBytes32(hexString)).to.throw( + "Hex string length must be a multiple of 64.", + ); + }); + + it("handles empty hex string", () => { + const hexString = ""; + const result = splitIntoBytes32(hexString); + expect(result).to.deep.equal([]); + }); +}); + +describe("Test paramsTagValueDecoder", function () { + it("should decode tag and value for case 1", function () { + const tag = "0x4368616e6e656c732d4f662d446973747269627574696f6e0000000000000018"; + const value = + "0x0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000274657374310000000000000000000000000000000000000000000000000000057465737432000000000000000000000000000000000000000000000000000005"; + const result = paramsTagValueDecoder(tag, value); + expect(result).to.deep.equal({ + tag: "Channels-Of-Distribution", + type: "string[]", + value: ["", "", "test1", "test2"], + }); + }); + + it("should decode tag and value for case 2", function () { + const tag = "0x4174747269627574696f6e00000000000000000000000000000000000000000b"; + const value = "0x"; + const result = paramsTagValueDecoder(tag, value); + expect(result).to.deep.equal({ + tag: "Attribution", + value: false, + type: "boolean", + }); + }); + + it("should decode tag and value for case 3", function () { + const tag = "0x44657269766174697665732d416c6c6f77656400000000000000000000000013"; + const value = "0x0000000000000000000000000000000000000000000000000000000000000001"; + const result = paramsTagValueDecoder(tag, value); + expect(result).to.deep.equal({ + tag: "Derivatives-Allowed", + value: true, + type: "boolean", + }); + }); + + it("should decode tag and value for case 4", function () { + const tag = "0x44657269766174697665732d416c6c6f7765642d4f7074696f6e73000000001b"; + const value = "0x0000000000000000000000000000000000000000000000000000000000000003"; + const result = paramsTagValueDecoder(tag, value); + expect(result).to.deep.equal({ + tag: "Derivatives-Allowed-Options", + value: ["Allowed-Reciprocal-License", "Allowed-With-Attribution"], + type: "string[]", + }); + }); +}); diff --git a/packages/core-sdk/tsconfig.json b/packages/core-sdk/tsconfig.json new file mode 100644 index 00000000..b844b905 --- /dev/null +++ b/packages/core-sdk/tsconfig.json @@ -0,0 +1,11 @@ +{ + "extends": "@story-protocol/tsconfig/base.json", + "compilerOptions": { + "resolveJsonModule": true, + "module": "ESNext", + "outDir": "dist", + "types": ["mocha"], + "lib": ["dom"] + }, + "include": ["src/**/*", "test/**/*"] +} diff --git a/packages/core-sdk/tsconfig.test.json b/packages/core-sdk/tsconfig.test.json new file mode 100644 index 00000000..6c22c68c --- /dev/null +++ b/packages/core-sdk/tsconfig.test.json @@ -0,0 +1,9 @@ +{ + "extends": "@story-protocol/tsconfig/base.json", + "compilerOptions": { + "resolveJsonModule": true, + "module": "CommonJS", + "lib": ["dom"] + }, + "include": ["./test"] +} diff --git a/packages/core-sdk/tsdoc.json b/packages/core-sdk/tsdoc.json new file mode 100644 index 00000000..b89839ca --- /dev/null +++ b/packages/core-sdk/tsdoc.json @@ -0,0 +1,4 @@ +{ + "$schema": "https://developer.microsoft.com/json-schemas/tsdoc/v0/tsdoc.schema.json", + "extends": ["typedoc/tsdoc.json"] +} diff --git a/packages/eslint-config-story/README.md b/packages/eslint-config-story/README.md new file mode 100644 index 00000000..8b42d901 --- /dev/null +++ b/packages/eslint-config-story/README.md @@ -0,0 +1,3 @@ +# `@turbo/eslint-config` + +Collection of internal eslint configurations. diff --git a/packages/eslint-config-story/index.js b/packages/eslint-config-story/index.js new file mode 100644 index 00000000..4adf9007 --- /dev/null +++ b/packages/eslint-config-story/index.js @@ -0,0 +1,39 @@ +module.exports = { + parser: "@typescript-eslint/parser", + extends: [ + "eslint:recommended", + "turbo", + "prettier", + "plugin:import/typescript", + "plugin:@typescript-eslint/recommended", + "plugin:@typescript-eslint/recommended-requiring-type-checking", + ], + plugins: ["@typescript-eslint", "eslint-plugin-tsdoc", "import"], + rules: { + // eslint + "curly": "error", + "eqeqeq": "error", + "no-implicit-coercion": ["error", { boolean: false }], + "no-unused-expressions": "error", + "no-useless-computed-key": "error", + "no-console": "error", + + // Typescript + "no-shadow": "off", + "@typescript-eslint/no-shadow": "error", + "@typescript-eslint/no-unused-vars": "error", + '@typescript-eslint/no-unsafe-argument': 'off', // causing a lot of IDE false positives. + + // import rules + "import/newline-after-import": "error", + "import/no-cycle": "error", + "import/no-useless-path-segments": "error", + "import/order": [ + "error", + { + "groups": ["builtin", "external", "internal"], + "newlines-between": "always" + } + ] + } +} \ No newline at end of file diff --git a/packages/eslint-config-story/package.json b/packages/eslint-config-story/package.json new file mode 100644 index 00000000..40394922 --- /dev/null +++ b/packages/eslint-config-story/package.json @@ -0,0 +1,22 @@ +{ + "name": "@story-protocol/eslint-config", + "version": "0.1.0", + "private": true, + "dependencies": { + "@typescript-eslint/eslint-plugin": "^6.2.0", + "eslint-plugin-import": "^2.28.0", + "eslint-plugin-tsdoc": "^0.2.17", + "@typescript-eslint/parser": "^6.2.0", + "eslint-config-prettier": "^8.10.0", + "eslint-config-turbo": "^1.10.0" + }, + "devDependencies": { + "@story-protocol/prettier-config": "workspace:*", + "eslint": "^8.40.0", + "prettier": "^3.0.0" + }, + "peerDependencies": { + "eslint": "^8.40.0" + }, + "prettier": "@lens-protocol/prettier-config" +} diff --git a/packages/prettier-config/index.json b/packages/prettier-config/index.json new file mode 100644 index 00000000..2ad87fa0 --- /dev/null +++ b/packages/prettier-config/index.json @@ -0,0 +1,6 @@ +{ + "$schema": "http://json.schemastore.org/prettierrc", + "singleQuote": false, + "trailingComma": "all", + "printWidth": 100 +} \ No newline at end of file diff --git a/packages/prettier-config/package.json b/packages/prettier-config/package.json new file mode 100644 index 00000000..df026408 --- /dev/null +++ b/packages/prettier-config/package.json @@ -0,0 +1,12 @@ +{ + "name": "@story-protocol/prettier-config", + "version": "0.1.0", + "private": true, + "main": "./index.json", + "devDependencies": { + "prettier": "^3.0.0" + }, + "peerDependencies": { + "prettier": "^3.0.0" + } + } \ No newline at end of file diff --git a/packages/tsconfig/base.json b/packages/tsconfig/base.json new file mode 100644 index 00000000..82ec39e7 --- /dev/null +++ b/packages/tsconfig/base.json @@ -0,0 +1,21 @@ +{ + "$schema": "https://json.schemastore.org/tsconfig", + "compilerOptions": { + "target": "ESNext", + "allowSyntheticDefaultImports": true, + "declaration": true, + "declarationMap": true, + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "noFallthroughCasesInSwitch": true, + "inlineSources": false, + "isolatedModules": true, + "moduleResolution": "node", + "noUnusedLocals": false, + "noUnusedParameters": false, + "skipLibCheck": true, + "strict": true, + "lib": ["ESNext"] + }, + "exclude": ["node_modules"] +} diff --git a/packages/tsconfig/package.json b/packages/tsconfig/package.json new file mode 100644 index 00000000..0f488aec --- /dev/null +++ b/packages/tsconfig/package.json @@ -0,0 +1,6 @@ +{ + "name": "@story-protocol/tsconfig", + "version": "0.1.0", + "private": true, + "main": "./base.json" +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml new file mode 100644 index 00000000..01852a79 --- /dev/null +++ b/pnpm-lock.yaml @@ -0,0 +1,5546 @@ +lockfileVersion: '6.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + devDependencies: + '@changesets/cli': + specifier: ^2.26.2 + version: 2.26.2 + husky: + specifier: ^8.0.0 + version: 8.0.3 + turbo: + specifier: ^1.10.13 + version: 1.10.13 + + packages/core-sdk: + dependencies: + abitype: + specifier: ^0.10.2 + version: 0.10.2(typescript@5.2.2) + axios: + specifier: ^1.5.1 + version: 1.5.1 + dotenv: + specifier: ^16.3.1 + version: 16.3.1 + viem: + specifier: ^1.18.4 + version: 1.18.4(typescript@5.2.2) + devDependencies: + '@babel/core': + specifier: ^7.23.0 + version: 7.23.0 + '@babel/preset-env': + specifier: ^7.22.20 + version: 7.22.20(@babel/core@7.23.0) + '@babel/preset-typescript': + specifier: ^7.23.0 + version: 7.23.0(@babel/core@7.23.0) + '@preconstruct/cli': + specifier: ^2.8.1 + version: 2.8.1 + '@story-protocol/eslint-config': + specifier: workspace:* + version: link:../eslint-config-story + '@story-protocol/prettier-config': + specifier: workspace:* + version: link:../prettier-config + '@story-protocol/tsconfig': + specifier: workspace:* + version: link:../tsconfig + '@types/chai': + specifier: ^4.3.6 + version: 4.3.6 + '@types/chai-as-promised': + specifier: ^7.1.6 + version: 7.1.6 + '@types/mocha': + specifier: ^10.0.2 + version: 10.0.2 + '@types/node': + specifier: ^20.8.2 + version: 20.8.2 + '@types/sinon': + specifier: ^10.0.18 + version: 10.0.18 + c8: + specifier: ^8.0.1 + version: 8.0.1 + chai: + specifier: ^4.3.10 + version: 4.3.10 + chai-as-promised: + specifier: ^7.1.1 + version: 7.1.1(chai@4.3.10) + eslint: + specifier: ^8.50.0 + version: 8.50.0 + mocha: + specifier: ^10.2.0 + version: 10.2.0 + prettier: + specifier: ^2.8.8 + version: 2.8.8 + sinon: + specifier: ^16.0.0 + version: 16.0.0 + ts-node: + specifier: ^10.9.1 + version: 10.9.1(@types/node@20.8.2)(typescript@5.2.2) + typechain: + specifier: ^8.3.1 + version: 8.3.2(typescript@5.2.2) + typescript: + specifier: ^5.2.2 + version: 5.2.2 + + packages/eslint-config-story: + dependencies: + '@typescript-eslint/eslint-plugin': + specifier: ^6.2.0 + version: 6.5.0(@typescript-eslint/parser@6.5.0)(eslint@8.48.0)(typescript@5.2.2) + '@typescript-eslint/parser': + specifier: ^6.2.0 + version: 6.5.0(eslint@8.48.0)(typescript@5.2.2) + eslint-config-prettier: + specifier: ^8.10.0 + version: 8.10.0(eslint@8.48.0) + eslint-config-turbo: + specifier: ^1.10.0 + version: 1.10.14(eslint@8.48.0) + eslint-plugin-import: + specifier: ^2.28.0 + version: 2.28.1(@typescript-eslint/parser@6.5.0)(eslint@8.48.0) + eslint-plugin-tsdoc: + specifier: ^0.2.17 + version: 0.2.17 + devDependencies: + '@story-protocol/prettier-config': + specifier: workspace:* + version: link:../prettier-config + eslint: + specifier: ^8.40.0 + version: 8.48.0 + prettier: + specifier: ^3.0.0 + version: 3.0.3 + + packages/prettier-config: + devDependencies: + prettier: + specifier: ^3.0.0 + version: 3.0.3 + + packages/tsconfig: {} + +packages: + + /@aashutoshrathi/word-wrap@1.2.6: + resolution: {integrity: sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==} + engines: {node: '>=0.10.0'} + + /@adraffy/ens-normalize@1.9.4: + resolution: {integrity: sha512-UK0bHA7hh9cR39V+4gl2/NnBBjoXIxkuWAPCaY4X7fbH4L/azIi7ilWOCjMUYfpJgraLUAqkRi2BqrjME8Rynw==} + dev: false + + /@ampproject/remapping@2.2.1: + resolution: {integrity: sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==} + engines: {node: '>=6.0.0'} + dependencies: + '@jridgewell/gen-mapping': 0.3.3 + '@jridgewell/trace-mapping': 0.3.19 + dev: true + + /@babel/code-frame@7.22.13: + resolution: {integrity: sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/highlight': 7.22.20 + chalk: 2.4.2 + dev: true + + /@babel/compat-data@7.22.20: + resolution: {integrity: sha512-BQYjKbpXjoXwFW5jGqiizJQQT/aC7pFm9Ok1OWssonuguICi264lbgMzRp2ZMmRSlfkX6DsWDDcsrctK8Rwfiw==} + engines: {node: '>=6.9.0'} + dev: true + + /@babel/core@7.23.0: + resolution: {integrity: sha512-97z/ju/Jy1rZmDxybphrBuI+jtJjFVoz7Mr9yUQVVVi+DNZE333uFQeMOqcCIy1x3WYBIbWftUSLmbNXNT7qFQ==} + engines: {node: '>=6.9.0'} + dependencies: + '@ampproject/remapping': 2.2.1 + '@babel/code-frame': 7.22.13 + '@babel/generator': 7.23.0 + '@babel/helper-compilation-targets': 7.22.15 + '@babel/helper-module-transforms': 7.23.0(@babel/core@7.23.0) + '@babel/helpers': 7.23.1 + '@babel/parser': 7.23.0 + '@babel/template': 7.22.15 + '@babel/traverse': 7.23.0 + '@babel/types': 7.23.0 + convert-source-map: 2.0.0 + debug: 4.3.4(supports-color@8.1.1) + gensync: 1.0.0-beta.2 + json5: 2.2.3 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/generator@7.23.0: + resolution: {integrity: sha512-lN85QRR+5IbYrMWM6Y4pE/noaQtg4pNiqeNGX60eqOfo6gtEj6uw/JagelB8vVztSd7R6M5n1+PQkDbHbBRU4g==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.23.0 + '@jridgewell/gen-mapping': 0.3.3 + '@jridgewell/trace-mapping': 0.3.19 + jsesc: 2.5.2 + dev: true + + /@babel/helper-annotate-as-pure@7.22.5: + resolution: {integrity: sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.23.0 + dev: true + + /@babel/helper-builder-binary-assignment-operator-visitor@7.22.15: + resolution: {integrity: sha512-QkBXwGgaoC2GtGZRoma6kv7Szfv06khvhFav67ZExau2RaXzy8MpHSMO2PNoP2XtmQphJQRHFfg77Bq731Yizw==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.23.0 + dev: true + + /@babel/helper-compilation-targets@7.22.15: + resolution: {integrity: sha512-y6EEzULok0Qvz8yyLkCvVX+02ic+By2UdOhylwUOvOn9dvYc9mKICJuuU1n1XBI02YWsNsnrY1kc6DVbjcXbtw==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/compat-data': 7.22.20 + '@babel/helper-validator-option': 7.22.15 + browserslist: 4.22.1 + lru-cache: 5.1.1 + semver: 6.3.1 + dev: true + + /@babel/helper-create-class-features-plugin@7.22.15(@babel/core@7.23.0): + resolution: {integrity: sha512-jKkwA59IXcvSaiK2UN45kKwSC9o+KuoXsBDvHvU/7BecYIp8GQ2UwrVvFgJASUT+hBnwJx6MhvMCuMzwZZ7jlg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.23.0 + '@babel/helper-annotate-as-pure': 7.22.5 + '@babel/helper-environment-visitor': 7.22.20 + '@babel/helper-function-name': 7.23.0 + '@babel/helper-member-expression-to-functions': 7.23.0 + '@babel/helper-optimise-call-expression': 7.22.5 + '@babel/helper-replace-supers': 7.22.20(@babel/core@7.23.0) + '@babel/helper-skip-transparent-expression-wrappers': 7.22.5 + '@babel/helper-split-export-declaration': 7.22.6 + semver: 6.3.1 + dev: true + + /@babel/helper-create-regexp-features-plugin@7.22.15(@babel/core@7.23.0): + resolution: {integrity: sha512-29FkPLFjn4TPEa3RE7GpW+qbE8tlsu3jntNYNfcGsc49LphF1PQIiD+vMZ1z1xVOKt+93khA9tc2JBs3kBjA7w==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.23.0 + '@babel/helper-annotate-as-pure': 7.22.5 + regexpu-core: 5.3.2 + semver: 6.3.1 + dev: true + + /@babel/helper-define-polyfill-provider@0.4.2(@babel/core@7.23.0): + resolution: {integrity: sha512-k0qnnOqHn5dK9pZpfD5XXZ9SojAITdCKRn2Lp6rnDGzIbaP0rHyMPk/4wsSxVBVz4RfN0q6VpXWP2pDGIoQ7hw==} + peerDependencies: + '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 + dependencies: + '@babel/core': 7.23.0 + '@babel/helper-compilation-targets': 7.22.15 + '@babel/helper-plugin-utils': 7.22.5 + debug: 4.3.4(supports-color@8.1.1) + lodash.debounce: 4.0.8 + resolve: 1.22.6 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/helper-environment-visitor@7.22.20: + resolution: {integrity: sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==} + engines: {node: '>=6.9.0'} + dev: true + + /@babel/helper-function-name@7.23.0: + resolution: {integrity: sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/template': 7.22.15 + '@babel/types': 7.23.0 + dev: true + + /@babel/helper-hoist-variables@7.22.5: + resolution: {integrity: sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.23.0 + dev: true + + /@babel/helper-member-expression-to-functions@7.23.0: + resolution: {integrity: sha512-6gfrPwh7OuT6gZyJZvd6WbTfrqAo7vm4xCzAXOusKqq/vWdKXphTpj5klHKNmRUU6/QRGlBsyU9mAIPaWHlqJA==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.23.0 + dev: true + + /@babel/helper-module-imports@7.22.15: + resolution: {integrity: sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.23.0 + dev: true + + /@babel/helper-module-transforms@7.23.0(@babel/core@7.23.0): + resolution: {integrity: sha512-WhDWw1tdrlT0gMgUJSlX0IQvoO1eN279zrAUbVB+KpV2c3Tylz8+GnKOLllCS6Z/iZQEyVYxhZVUdPTqs2YYPw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.23.0 + '@babel/helper-environment-visitor': 7.22.20 + '@babel/helper-module-imports': 7.22.15 + '@babel/helper-simple-access': 7.22.5 + '@babel/helper-split-export-declaration': 7.22.6 + '@babel/helper-validator-identifier': 7.22.20 + dev: true + + /@babel/helper-optimise-call-expression@7.22.5: + resolution: {integrity: sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.23.0 + dev: true + + /@babel/helper-plugin-utils@7.22.5: + resolution: {integrity: sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==} + engines: {node: '>=6.9.0'} + dev: true + + /@babel/helper-remap-async-to-generator@7.22.20(@babel/core@7.23.0): + resolution: {integrity: sha512-pBGyV4uBqOns+0UvhsTO8qgl8hO89PmiDYv+/COyp1aeMcmfrfruz+/nCMFiYyFF/Knn0yfrC85ZzNFjembFTw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.23.0 + '@babel/helper-annotate-as-pure': 7.22.5 + '@babel/helper-environment-visitor': 7.22.20 + '@babel/helper-wrap-function': 7.22.20 + dev: true + + /@babel/helper-replace-supers@7.22.20(@babel/core@7.23.0): + resolution: {integrity: sha512-qsW0In3dbwQUbK8kejJ4R7IHVGwHJlV6lpG6UA7a9hSa2YEiAib+N1T2kr6PEeUT+Fl7najmSOS6SmAwCHK6Tw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.23.0 + '@babel/helper-environment-visitor': 7.22.20 + '@babel/helper-member-expression-to-functions': 7.23.0 + '@babel/helper-optimise-call-expression': 7.22.5 + dev: true + + /@babel/helper-simple-access@7.22.5: + resolution: {integrity: sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.23.0 + dev: true + + /@babel/helper-skip-transparent-expression-wrappers@7.22.5: + resolution: {integrity: sha512-tK14r66JZKiC43p8Ki33yLBVJKlQDFoA8GYN67lWCDCqoL6EMMSuM9b+Iff2jHaM/RRFYl7K+iiru7hbRqNx8Q==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.23.0 + dev: true + + /@babel/helper-split-export-declaration@7.22.6: + resolution: {integrity: sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.23.0 + dev: true + + /@babel/helper-string-parser@7.22.5: + resolution: {integrity: sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==} + engines: {node: '>=6.9.0'} + dev: true + + /@babel/helper-validator-identifier@7.22.20: + resolution: {integrity: sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==} + engines: {node: '>=6.9.0'} + dev: true + + /@babel/helper-validator-option@7.22.15: + resolution: {integrity: sha512-bMn7RmyFjY/mdECUbgn9eoSY4vqvacUnS9i9vGAGttgFWesO6B4CYWA7XlpbWgBt71iv/hfbPlynohStqnu5hA==} + engines: {node: '>=6.9.0'} + dev: true + + /@babel/helper-wrap-function@7.22.20: + resolution: {integrity: sha512-pms/UwkOpnQe/PDAEdV/d7dVCoBbB+R4FvYoHGZz+4VPcg7RtYy2KP7S2lbuWM6FCSgob5wshfGESbC/hzNXZw==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-function-name': 7.23.0 + '@babel/template': 7.22.15 + '@babel/types': 7.23.0 + dev: true + + /@babel/helpers@7.23.1: + resolution: {integrity: sha512-chNpneuK18yW5Oxsr+t553UZzzAs3aZnFm4bxhebsNTeshrC95yA7l5yl7GBAG+JG1rF0F7zzD2EixK9mWSDoA==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/template': 7.22.15 + '@babel/traverse': 7.23.0 + '@babel/types': 7.23.0 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/highlight@7.22.20: + resolution: {integrity: sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-validator-identifier': 7.22.20 + chalk: 2.4.2 + js-tokens: 4.0.0 + dev: true + + /@babel/parser@7.23.0: + resolution: {integrity: sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw==} + engines: {node: '>=6.0.0'} + hasBin: true + dependencies: + '@babel/types': 7.23.0 + dev: true + + /@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.22.15(@babel/core@7.23.0): + resolution: {integrity: sha512-FB9iYlz7rURmRJyXRKEnalYPPdn87H5no108cyuQQyMwlpJ2SJtpIUBI27kdTin956pz+LPypkPVPUTlxOmrsg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.23.0 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.22.15(@babel/core@7.23.0): + resolution: {integrity: sha512-Hyph9LseGvAeeXzikV88bczhsrLrIZqDPxO+sSmAunMPaGrBGhfMWzCPYTtiW9t+HzSE2wtV8e5cc5P6r1xMDQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.13.0 + dependencies: + '@babel/core': 7.23.0 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-skip-transparent-expression-wrappers': 7.22.5 + '@babel/plugin-transform-optional-chaining': 7.23.0(@babel/core@7.23.0) + dev: true + + /@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2(@babel/core@7.23.0): + resolution: {integrity: sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.0 + dev: true + + /@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.23.0): + resolution: {integrity: sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.0 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.23.0): + resolution: {integrity: sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.0 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@7.23.0): + resolution: {integrity: sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.0 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-syntax-dynamic-import@7.8.3(@babel/core@7.23.0): + resolution: {integrity: sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.0 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-syntax-export-namespace-from@7.8.3(@babel/core@7.23.0): + resolution: {integrity: sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.0 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-syntax-import-assertions@7.22.5(@babel/core@7.23.0): + resolution: {integrity: sha512-rdV97N7KqsRzeNGoWUOK6yUsWarLjE5Su/Snk9IYPU9CwkWHs4t+rTGOvffTR8XGkJMTAdLfO0xVnXm8wugIJg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.0 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-syntax-import-attributes@7.22.5(@babel/core@7.23.0): + resolution: {integrity: sha512-KwvoWDeNKPETmozyFE0P2rOLqh39EoQHNjqizrI5B8Vt0ZNS7M56s7dAiAqbYfiAYOuIzIh96z3iR2ktgu3tEg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.0 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.23.0): + resolution: {integrity: sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.0 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.23.0): + resolution: {integrity: sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.0 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-syntax-jsx@7.22.5(@babel/core@7.23.0): + resolution: {integrity: sha512-gvyP4hZrgrs/wWMaocvxZ44Hw0b3W8Pe+cMxc8V1ULQ07oh8VNbIRaoD1LRZVTvD+0nieDKjfgKg89sD7rrKrg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.0 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.23.0): + resolution: {integrity: sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.0 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.23.0): + resolution: {integrity: sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.0 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.23.0): + resolution: {integrity: sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.0 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.23.0): + resolution: {integrity: sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.0 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.23.0): + resolution: {integrity: sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.0 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.23.0): + resolution: {integrity: sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.0 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.23.0): + resolution: {integrity: sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.0 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.23.0): + resolution: {integrity: sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.0 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-syntax-typescript@7.22.5(@babel/core@7.23.0): + resolution: {integrity: sha512-1mS2o03i7t1c6VzH6fdQ3OA8tcEIxwG18zIPRp+UY1Ihv6W+XZzBCVxExF9upussPXJ0xE9XRHwMoNs1ep/nRQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.0 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-syntax-unicode-sets-regex@7.18.6(@babel/core@7.23.0): + resolution: {integrity: sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.23.0 + '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.23.0) + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-transform-arrow-functions@7.22.5(@babel/core@7.23.0): + resolution: {integrity: sha512-26lTNXoVRdAnsaDXPpvCNUq+OVWEVC6bx7Vvz9rC53F2bagUWW4u4ii2+h8Fejfh7RYqPxn+libeFBBck9muEw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.0 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-transform-async-generator-functions@7.22.15(@babel/core@7.23.0): + resolution: {integrity: sha512-jBm1Es25Y+tVoTi5rfd5t1KLmL8ogLKpXszboWOTTtGFGz2RKnQe2yn7HbZ+kb/B8N0FVSGQo874NSlOU1T4+w==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.0 + '@babel/helper-environment-visitor': 7.22.20 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-remap-async-to-generator': 7.22.20(@babel/core@7.23.0) + '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.23.0) + dev: true + + /@babel/plugin-transform-async-to-generator@7.22.5(@babel/core@7.23.0): + resolution: {integrity: sha512-b1A8D8ZzE/VhNDoV1MSJTnpKkCG5bJo+19R4o4oy03zM7ws8yEMK755j61Dc3EyvdysbqH5BOOTquJ7ZX9C6vQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.0 + '@babel/helper-module-imports': 7.22.15 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-remap-async-to-generator': 7.22.20(@babel/core@7.23.0) + dev: true + + /@babel/plugin-transform-block-scoped-functions@7.22.5(@babel/core@7.23.0): + resolution: {integrity: sha512-tdXZ2UdknEKQWKJP1KMNmuF5Lx3MymtMN/pvA+p/VEkhK8jVcQ1fzSy8KM9qRYhAf2/lV33hoMPKI/xaI9sADA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.0 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-transform-block-scoping@7.23.0(@babel/core@7.23.0): + resolution: {integrity: sha512-cOsrbmIOXmf+5YbL99/S49Y3j46k/T16b9ml8bm9lP6N9US5iQ2yBK7gpui1pg0V/WMcXdkfKbTb7HXq9u+v4g==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.0 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-transform-class-properties@7.22.5(@babel/core@7.23.0): + resolution: {integrity: sha512-nDkQ0NfkOhPTq8YCLiWNxp1+f9fCobEjCb0n8WdbNUBc4IB5V7P1QnX9IjpSoquKrXF5SKojHleVNs2vGeHCHQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.0 + '@babel/helper-create-class-features-plugin': 7.22.15(@babel/core@7.23.0) + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-transform-class-static-block@7.22.11(@babel/core@7.23.0): + resolution: {integrity: sha512-GMM8gGmqI7guS/llMFk1bJDkKfn3v3C4KHK9Yg1ey5qcHcOlKb0QvcMrgzvxo+T03/4szNh5lghY+fEC98Kq9g==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.12.0 + dependencies: + '@babel/core': 7.23.0 + '@babel/helper-create-class-features-plugin': 7.22.15(@babel/core@7.23.0) + '@babel/helper-plugin-utils': 7.22.5 + '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.23.0) + dev: true + + /@babel/plugin-transform-classes@7.22.15(@babel/core@7.23.0): + resolution: {integrity: sha512-VbbC3PGjBdE0wAWDdHM9G8Gm977pnYI0XpqMd6LrKISj8/DJXEsWqgRuTYaNE9Bv0JGhTZUzHDlMk18IpOuoqw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.0 + '@babel/helper-annotate-as-pure': 7.22.5 + '@babel/helper-compilation-targets': 7.22.15 + '@babel/helper-environment-visitor': 7.22.20 + '@babel/helper-function-name': 7.23.0 + '@babel/helper-optimise-call-expression': 7.22.5 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-replace-supers': 7.22.20(@babel/core@7.23.0) + '@babel/helper-split-export-declaration': 7.22.6 + globals: 11.12.0 + dev: true + + /@babel/plugin-transform-computed-properties@7.22.5(@babel/core@7.23.0): + resolution: {integrity: sha512-4GHWBgRf0krxPX+AaPtgBAlTgTeZmqDynokHOX7aqqAB4tHs3U2Y02zH6ETFdLZGcg9UQSD1WCmkVrE9ErHeOg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.0 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/template': 7.22.15 + dev: true + + /@babel/plugin-transform-destructuring@7.23.0(@babel/core@7.23.0): + resolution: {integrity: sha512-vaMdgNXFkYrB+8lbgniSYWHsgqK5gjaMNcc84bMIOMRLH0L9AqYq3hwMdvnyqj1OPqea8UtjPEuS/DCenah1wg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.0 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-transform-dotall-regex@7.22.5(@babel/core@7.23.0): + resolution: {integrity: sha512-5/Yk9QxCQCl+sOIB1WelKnVRxTJDSAIxtJLL2/pqL14ZVlbH0fUQUZa/T5/UnQtBNgghR7mfB8ERBKyKPCi7Vw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.0 + '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.23.0) + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-transform-duplicate-keys@7.22.5(@babel/core@7.23.0): + resolution: {integrity: sha512-dEnYD+9BBgld5VBXHnF/DbYGp3fqGMsyxKbtD1mDyIA7AkTSpKXFhCVuj/oQVOoALfBs77DudA0BE4d5mcpmqw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.0 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-transform-dynamic-import@7.22.11(@babel/core@7.23.0): + resolution: {integrity: sha512-g/21plo58sfteWjaO0ZNVb+uEOkJNjAaHhbejrnBmu011l/eNDScmkbjCC3l4FKb10ViaGU4aOkFznSu2zRHgA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.0 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.23.0) + dev: true + + /@babel/plugin-transform-exponentiation-operator@7.22.5(@babel/core@7.23.0): + resolution: {integrity: sha512-vIpJFNM/FjZ4rh1myqIya9jXwrwwgFRHPjT3DkUA9ZLHuzox8jiXkOLvwm1H+PQIP3CqfC++WPKeuDi0Sjdj1g==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.0 + '@babel/helper-builder-binary-assignment-operator-visitor': 7.22.15 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-transform-export-namespace-from@7.22.11(@babel/core@7.23.0): + resolution: {integrity: sha512-xa7aad7q7OiT8oNZ1mU7NrISjlSkVdMbNxn9IuLZyL9AJEhs1Apba3I+u5riX1dIkdptP5EKDG5XDPByWxtehw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.0 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/plugin-syntax-export-namespace-from': 7.8.3(@babel/core@7.23.0) + dev: true + + /@babel/plugin-transform-for-of@7.22.15(@babel/core@7.23.0): + resolution: {integrity: sha512-me6VGeHsx30+xh9fbDLLPi0J1HzmeIIyenoOQHuw2D4m2SAU3NrspX5XxJLBpqn5yrLzrlw2Iy3RA//Bx27iOA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.0 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-transform-function-name@7.22.5(@babel/core@7.23.0): + resolution: {integrity: sha512-UIzQNMS0p0HHiQm3oelztj+ECwFnj+ZRV4KnguvlsD2of1whUeM6o7wGNj6oLwcDoAXQ8gEqfgC24D+VdIcevg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.0 + '@babel/helper-compilation-targets': 7.22.15 + '@babel/helper-function-name': 7.23.0 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-transform-json-strings@7.22.11(@babel/core@7.23.0): + resolution: {integrity: sha512-CxT5tCqpA9/jXFlme9xIBCc5RPtdDq3JpkkhgHQqtDdiTnTI0jtZ0QzXhr5DILeYifDPp2wvY2ad+7+hLMW5Pw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.0 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.23.0) + dev: true + + /@babel/plugin-transform-literals@7.22.5(@babel/core@7.23.0): + resolution: {integrity: sha512-fTLj4D79M+mepcw3dgFBTIDYpbcB9Sm0bpm4ppXPaO+U+PKFFyV9MGRvS0gvGw62sd10kT5lRMKXAADb9pWy8g==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.0 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-transform-logical-assignment-operators@7.22.11(@babel/core@7.23.0): + resolution: {integrity: sha512-qQwRTP4+6xFCDV5k7gZBF3C31K34ut0tbEcTKxlX/0KXxm9GLcO14p570aWxFvVzx6QAfPgq7gaeIHXJC8LswQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.0 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.23.0) + dev: true + + /@babel/plugin-transform-member-expression-literals@7.22.5(@babel/core@7.23.0): + resolution: {integrity: sha512-RZEdkNtzzYCFl9SE9ATaUMTj2hqMb4StarOJLrZRbqqU4HSBE7UlBw9WBWQiDzrJZJdUWiMTVDI6Gv/8DPvfew==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.0 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-transform-modules-amd@7.23.0(@babel/core@7.23.0): + resolution: {integrity: sha512-xWT5gefv2HGSm4QHtgc1sYPbseOyf+FFDo2JbpE25GWl5BqTGO9IMwTYJRoIdjsF85GE+VegHxSCUt5EvoYTAw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.0 + '@babel/helper-module-transforms': 7.23.0(@babel/core@7.23.0) + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-transform-modules-commonjs@7.23.0(@babel/core@7.23.0): + resolution: {integrity: sha512-32Xzss14/UVc7k9g775yMIvkVK8xwKE0DPdP5JTapr3+Z9w4tzeOuLNY6BXDQR6BdnzIlXnCGAzsk/ICHBLVWQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.0 + '@babel/helper-module-transforms': 7.23.0(@babel/core@7.23.0) + '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-simple-access': 7.22.5 + dev: true + + /@babel/plugin-transform-modules-systemjs@7.23.0(@babel/core@7.23.0): + resolution: {integrity: sha512-qBej6ctXZD2f+DhlOC9yO47yEYgUh5CZNz/aBoH4j/3NOlRfJXJbY7xDQCqQVf9KbrqGzIWER1f23doHGrIHFg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.0 + '@babel/helper-hoist-variables': 7.22.5 + '@babel/helper-module-transforms': 7.23.0(@babel/core@7.23.0) + '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-validator-identifier': 7.22.20 + dev: true + + /@babel/plugin-transform-modules-umd@7.22.5(@babel/core@7.23.0): + resolution: {integrity: sha512-+S6kzefN/E1vkSsKx8kmQuqeQsvCKCd1fraCM7zXm4SFoggI099Tr4G8U81+5gtMdUeMQ4ipdQffbKLX0/7dBQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.0 + '@babel/helper-module-transforms': 7.23.0(@babel/core@7.23.0) + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-transform-named-capturing-groups-regex@7.22.5(@babel/core@7.23.0): + resolution: {integrity: sha512-YgLLKmS3aUBhHaxp5hi1WJTgOUb/NCuDHzGT9z9WTt3YG+CPRhJs6nprbStx6DnWM4dh6gt7SU3sZodbZ08adQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.23.0 + '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.23.0) + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-transform-new-target@7.22.5(@babel/core@7.23.0): + resolution: {integrity: sha512-AsF7K0Fx/cNKVyk3a+DW0JLo+Ua598/NxMRvxDnkpCIGFh43+h/v2xyhRUYf6oD8gE4QtL83C7zZVghMjHd+iw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.0 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-transform-nullish-coalescing-operator@7.22.11(@babel/core@7.23.0): + resolution: {integrity: sha512-YZWOw4HxXrotb5xsjMJUDlLgcDXSfO9eCmdl1bgW4+/lAGdkjaEvOnQ4p5WKKdUgSzO39dgPl0pTnfxm0OAXcg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.0 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.23.0) + dev: true + + /@babel/plugin-transform-numeric-separator@7.22.11(@babel/core@7.23.0): + resolution: {integrity: sha512-3dzU4QGPsILdJbASKhF/V2TVP+gJya1PsueQCxIPCEcerqF21oEcrob4mzjsp2Py/1nLfF5m+xYNMDpmA8vffg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.0 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.23.0) + dev: true + + /@babel/plugin-transform-object-rest-spread@7.22.15(@babel/core@7.23.0): + resolution: {integrity: sha512-fEB+I1+gAmfAyxZcX1+ZUwLeAuuf8VIg67CTznZE0MqVFumWkh8xWtn58I4dxdVf080wn7gzWoF8vndOViJe9Q==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/compat-data': 7.22.20 + '@babel/core': 7.23.0 + '@babel/helper-compilation-targets': 7.22.15 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.23.0) + '@babel/plugin-transform-parameters': 7.22.15(@babel/core@7.23.0) + dev: true + + /@babel/plugin-transform-object-super@7.22.5(@babel/core@7.23.0): + resolution: {integrity: sha512-klXqyaT9trSjIUrcsYIfETAzmOEZL3cBYqOYLJxBHfMFFggmXOv+NYSX/Jbs9mzMVESw/WycLFPRx8ba/b2Ipw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.0 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-replace-supers': 7.22.20(@babel/core@7.23.0) + dev: true + + /@babel/plugin-transform-optional-catch-binding@7.22.11(@babel/core@7.23.0): + resolution: {integrity: sha512-rli0WxesXUeCJnMYhzAglEjLWVDF6ahb45HuprcmQuLidBJFWjNnOzssk2kuc6e33FlLaiZhG/kUIzUMWdBKaQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.0 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.23.0) + dev: true + + /@babel/plugin-transform-optional-chaining@7.23.0(@babel/core@7.23.0): + resolution: {integrity: sha512-sBBGXbLJjxTzLBF5rFWaikMnOGOk/BmK6vVByIdEggZ7Vn6CvWXZyRkkLFK6WE0IF8jSliyOkUN6SScFgzCM0g==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.0 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-skip-transparent-expression-wrappers': 7.22.5 + '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.23.0) + dev: true + + /@babel/plugin-transform-parameters@7.22.15(@babel/core@7.23.0): + resolution: {integrity: sha512-hjk7qKIqhyzhhUvRT683TYQOFa/4cQKwQy7ALvTpODswN40MljzNDa0YldevS6tGbxwaEKVn502JmY0dP7qEtQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.0 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-transform-private-methods@7.22.5(@babel/core@7.23.0): + resolution: {integrity: sha512-PPjh4gyrQnGe97JTalgRGMuU4icsZFnWkzicB/fUtzlKUqvsWBKEpPPfr5a2JiyirZkHxnAqkQMO5Z5B2kK3fA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.0 + '@babel/helper-create-class-features-plugin': 7.22.15(@babel/core@7.23.0) + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-transform-private-property-in-object@7.22.11(@babel/core@7.23.0): + resolution: {integrity: sha512-sSCbqZDBKHetvjSwpyWzhuHkmW5RummxJBVbYLkGkaiTOWGxml7SXt0iWa03bzxFIx7wOj3g/ILRd0RcJKBeSQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.0 + '@babel/helper-annotate-as-pure': 7.22.5 + '@babel/helper-create-class-features-plugin': 7.22.15(@babel/core@7.23.0) + '@babel/helper-plugin-utils': 7.22.5 + '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.23.0) + dev: true + + /@babel/plugin-transform-property-literals@7.22.5(@babel/core@7.23.0): + resolution: {integrity: sha512-TiOArgddK3mK/x1Qwf5hay2pxI6wCZnvQqrFSqbtg1GLl2JcNMitVH/YnqjP+M31pLUeTfzY1HAXFDnUBV30rQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.0 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-transform-regenerator@7.22.10(@babel/core@7.23.0): + resolution: {integrity: sha512-F28b1mDt8KcT5bUyJc/U9nwzw6cV+UmTeRlXYIl2TNqMMJif0Jeey9/RQ3C4NOd2zp0/TRsDns9ttj2L523rsw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.0 + '@babel/helper-plugin-utils': 7.22.5 + regenerator-transform: 0.15.2 + dev: true + + /@babel/plugin-transform-reserved-words@7.22.5(@babel/core@7.23.0): + resolution: {integrity: sha512-DTtGKFRQUDm8svigJzZHzb/2xatPc6TzNvAIJ5GqOKDsGFYgAskjRulbR/vGsPKq3OPqtexnz327qYpP57RFyA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.0 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-transform-shorthand-properties@7.22.5(@babel/core@7.23.0): + resolution: {integrity: sha512-vM4fq9IXHscXVKzDv5itkO1X52SmdFBFcMIBZ2FRn2nqVYqw6dBexUgMvAjHW+KXpPPViD/Yo3GrDEBaRC0QYA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.0 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-transform-spread@7.22.5(@babel/core@7.23.0): + resolution: {integrity: sha512-5ZzDQIGyvN4w8+dMmpohL6MBo+l2G7tfC/O2Dg7/hjpgeWvUx8FzfeOKxGog9IimPa4YekaQ9PlDqTLOljkcxg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.0 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-skip-transparent-expression-wrappers': 7.22.5 + dev: true + + /@babel/plugin-transform-sticky-regex@7.22.5(@babel/core@7.23.0): + resolution: {integrity: sha512-zf7LuNpHG0iEeiyCNwX4j3gDg1jgt1k3ZdXBKbZSoA3BbGQGvMiSvfbZRR3Dr3aeJe3ooWFZxOOG3IRStYp2Bw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.0 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-transform-template-literals@7.22.5(@babel/core@7.23.0): + resolution: {integrity: sha512-5ciOehRNf+EyUeewo8NkbQiUs4d6ZxiHo6BcBcnFlgiJfu16q0bQUw9Jvo0b0gBKFG1SMhDSjeKXSYuJLeFSMA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.0 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-transform-typeof-symbol@7.22.5(@babel/core@7.23.0): + resolution: {integrity: sha512-bYkI5lMzL4kPii4HHEEChkD0rkc+nvnlR6+o/qdqR6zrm0Sv/nodmyLhlq2DO0YKLUNd2VePmPRjJXSBh9OIdA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.0 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-transform-typescript@7.22.15(@babel/core@7.23.0): + resolution: {integrity: sha512-1uirS0TnijxvQLnlv5wQBwOX3E1wCFX7ITv+9pBV2wKEk4K+M5tqDaoNXnTH8tjEIYHLO98MwiTWO04Ggz4XuA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.0 + '@babel/helper-annotate-as-pure': 7.22.5 + '@babel/helper-create-class-features-plugin': 7.22.15(@babel/core@7.23.0) + '@babel/helper-plugin-utils': 7.22.5 + '@babel/plugin-syntax-typescript': 7.22.5(@babel/core@7.23.0) + dev: true + + /@babel/plugin-transform-unicode-escapes@7.22.10(@babel/core@7.23.0): + resolution: {integrity: sha512-lRfaRKGZCBqDlRU3UIFovdp9c9mEvlylmpod0/OatICsSfuQ9YFthRo1tpTkGsklEefZdqlEFdY4A2dwTb6ohg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.0 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-transform-unicode-property-regex@7.22.5(@babel/core@7.23.0): + resolution: {integrity: sha512-HCCIb+CbJIAE6sXn5CjFQXMwkCClcOfPCzTlilJ8cUatfzwHlWQkbtV0zD338u9dZskwvuOYTuuaMaA8J5EI5A==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.0 + '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.23.0) + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-transform-unicode-regex@7.22.5(@babel/core@7.23.0): + resolution: {integrity: sha512-028laaOKptN5vHJf9/Arr/HiJekMd41hOEZYvNsrsXqJ7YPYuX2bQxh31fkZzGmq3YqHRJzYFFAVYvKfMPKqyg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.0 + '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.23.0) + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-transform-unicode-sets-regex@7.22.5(@babel/core@7.23.0): + resolution: {integrity: sha512-lhMfi4FC15j13eKrh3DnYHjpGj6UKQHtNKTbtc1igvAhRy4+kLhV07OpLcsN0VgDEw/MjAvJO4BdMJsHwMhzCg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.23.0 + '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.23.0) + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/preset-env@7.22.20(@babel/core@7.23.0): + resolution: {integrity: sha512-11MY04gGC4kSzlPHRfvVkNAZhUxOvm7DCJ37hPDnUENwe06npjIRAfInEMTGSb4LZK5ZgDFkv5hw0lGebHeTyg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/compat-data': 7.22.20 + '@babel/core': 7.23.0 + '@babel/helper-compilation-targets': 7.22.15 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-validator-option': 7.22.15 + '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression': 7.22.15(@babel/core@7.23.0) + '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining': 7.22.15(@babel/core@7.23.0) + '@babel/plugin-proposal-private-property-in-object': 7.21.0-placeholder-for-preset-env.2(@babel/core@7.23.0) + '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.23.0) + '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.23.0) + '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.23.0) + '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.23.0) + '@babel/plugin-syntax-export-namespace-from': 7.8.3(@babel/core@7.23.0) + '@babel/plugin-syntax-import-assertions': 7.22.5(@babel/core@7.23.0) + '@babel/plugin-syntax-import-attributes': 7.22.5(@babel/core@7.23.0) + '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.23.0) + '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.23.0) + '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.23.0) + '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.23.0) + '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.23.0) + '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.23.0) + '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.23.0) + '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.23.0) + '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.23.0) + '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.23.0) + '@babel/plugin-syntax-unicode-sets-regex': 7.18.6(@babel/core@7.23.0) + '@babel/plugin-transform-arrow-functions': 7.22.5(@babel/core@7.23.0) + '@babel/plugin-transform-async-generator-functions': 7.22.15(@babel/core@7.23.0) + '@babel/plugin-transform-async-to-generator': 7.22.5(@babel/core@7.23.0) + '@babel/plugin-transform-block-scoped-functions': 7.22.5(@babel/core@7.23.0) + '@babel/plugin-transform-block-scoping': 7.23.0(@babel/core@7.23.0) + '@babel/plugin-transform-class-properties': 7.22.5(@babel/core@7.23.0) + '@babel/plugin-transform-class-static-block': 7.22.11(@babel/core@7.23.0) + '@babel/plugin-transform-classes': 7.22.15(@babel/core@7.23.0) + '@babel/plugin-transform-computed-properties': 7.22.5(@babel/core@7.23.0) + '@babel/plugin-transform-destructuring': 7.23.0(@babel/core@7.23.0) + '@babel/plugin-transform-dotall-regex': 7.22.5(@babel/core@7.23.0) + '@babel/plugin-transform-duplicate-keys': 7.22.5(@babel/core@7.23.0) + '@babel/plugin-transform-dynamic-import': 7.22.11(@babel/core@7.23.0) + '@babel/plugin-transform-exponentiation-operator': 7.22.5(@babel/core@7.23.0) + '@babel/plugin-transform-export-namespace-from': 7.22.11(@babel/core@7.23.0) + '@babel/plugin-transform-for-of': 7.22.15(@babel/core@7.23.0) + '@babel/plugin-transform-function-name': 7.22.5(@babel/core@7.23.0) + '@babel/plugin-transform-json-strings': 7.22.11(@babel/core@7.23.0) + '@babel/plugin-transform-literals': 7.22.5(@babel/core@7.23.0) + '@babel/plugin-transform-logical-assignment-operators': 7.22.11(@babel/core@7.23.0) + '@babel/plugin-transform-member-expression-literals': 7.22.5(@babel/core@7.23.0) + '@babel/plugin-transform-modules-amd': 7.23.0(@babel/core@7.23.0) + '@babel/plugin-transform-modules-commonjs': 7.23.0(@babel/core@7.23.0) + '@babel/plugin-transform-modules-systemjs': 7.23.0(@babel/core@7.23.0) + '@babel/plugin-transform-modules-umd': 7.22.5(@babel/core@7.23.0) + '@babel/plugin-transform-named-capturing-groups-regex': 7.22.5(@babel/core@7.23.0) + '@babel/plugin-transform-new-target': 7.22.5(@babel/core@7.23.0) + '@babel/plugin-transform-nullish-coalescing-operator': 7.22.11(@babel/core@7.23.0) + '@babel/plugin-transform-numeric-separator': 7.22.11(@babel/core@7.23.0) + '@babel/plugin-transform-object-rest-spread': 7.22.15(@babel/core@7.23.0) + '@babel/plugin-transform-object-super': 7.22.5(@babel/core@7.23.0) + '@babel/plugin-transform-optional-catch-binding': 7.22.11(@babel/core@7.23.0) + '@babel/plugin-transform-optional-chaining': 7.23.0(@babel/core@7.23.0) + '@babel/plugin-transform-parameters': 7.22.15(@babel/core@7.23.0) + '@babel/plugin-transform-private-methods': 7.22.5(@babel/core@7.23.0) + '@babel/plugin-transform-private-property-in-object': 7.22.11(@babel/core@7.23.0) + '@babel/plugin-transform-property-literals': 7.22.5(@babel/core@7.23.0) + '@babel/plugin-transform-regenerator': 7.22.10(@babel/core@7.23.0) + '@babel/plugin-transform-reserved-words': 7.22.5(@babel/core@7.23.0) + '@babel/plugin-transform-shorthand-properties': 7.22.5(@babel/core@7.23.0) + '@babel/plugin-transform-spread': 7.22.5(@babel/core@7.23.0) + '@babel/plugin-transform-sticky-regex': 7.22.5(@babel/core@7.23.0) + '@babel/plugin-transform-template-literals': 7.22.5(@babel/core@7.23.0) + '@babel/plugin-transform-typeof-symbol': 7.22.5(@babel/core@7.23.0) + '@babel/plugin-transform-unicode-escapes': 7.22.10(@babel/core@7.23.0) + '@babel/plugin-transform-unicode-property-regex': 7.22.5(@babel/core@7.23.0) + '@babel/plugin-transform-unicode-regex': 7.22.5(@babel/core@7.23.0) + '@babel/plugin-transform-unicode-sets-regex': 7.22.5(@babel/core@7.23.0) + '@babel/preset-modules': 0.1.6-no-external-plugins(@babel/core@7.23.0) + '@babel/types': 7.23.0 + babel-plugin-polyfill-corejs2: 0.4.5(@babel/core@7.23.0) + babel-plugin-polyfill-corejs3: 0.8.4(@babel/core@7.23.0) + babel-plugin-polyfill-regenerator: 0.5.2(@babel/core@7.23.0) + core-js-compat: 3.33.0 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/preset-modules@0.1.6-no-external-plugins(@babel/core@7.23.0): + resolution: {integrity: sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==} + peerDependencies: + '@babel/core': ^7.0.0-0 || ^8.0.0-0 <8.0.0 + dependencies: + '@babel/core': 7.23.0 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/types': 7.23.0 + esutils: 2.0.3 + dev: true + + /@babel/preset-typescript@7.23.0(@babel/core@7.23.0): + resolution: {integrity: sha512-6P6VVa/NM/VlAYj5s2Aq/gdVg8FSENCg3wlZ6Qau9AcPaoF5LbN1nyGlR9DTRIw9PpxI94e+ReydsJHcjwAweg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.0 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-validator-option': 7.22.15 + '@babel/plugin-syntax-jsx': 7.22.5(@babel/core@7.23.0) + '@babel/plugin-transform-modules-commonjs': 7.23.0(@babel/core@7.23.0) + '@babel/plugin-transform-typescript': 7.22.15(@babel/core@7.23.0) + dev: true + + /@babel/regjsgen@0.8.0: + resolution: {integrity: sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==} + dev: true + + /@babel/runtime@7.23.1: + resolution: {integrity: sha512-hC2v6p8ZSI/W0HUzh3V8C5g+NwSKzKPtJwSpTjwl0o297GP9+ZLQSkdvHz46CM3LqyoXxq+5G9komY+eSqSO0g==} + engines: {node: '>=6.9.0'} + dependencies: + regenerator-runtime: 0.14.0 + dev: true + + /@babel/template@7.22.15: + resolution: {integrity: sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/code-frame': 7.22.13 + '@babel/parser': 7.23.0 + '@babel/types': 7.23.0 + dev: true + + /@babel/traverse@7.23.0: + resolution: {integrity: sha512-t/QaEvyIoIkwzpiZ7aoSKK8kObQYeF7T2v+dazAYCb8SXtp58zEVkWW7zAnju8FNKNdr4ScAOEDmMItbyOmEYw==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/code-frame': 7.22.13 + '@babel/generator': 7.23.0 + '@babel/helper-environment-visitor': 7.22.20 + '@babel/helper-function-name': 7.23.0 + '@babel/helper-hoist-variables': 7.22.5 + '@babel/helper-split-export-declaration': 7.22.6 + '@babel/parser': 7.23.0 + '@babel/types': 7.23.0 + debug: 4.3.4(supports-color@8.1.1) + globals: 11.12.0 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/types@7.23.0: + resolution: {integrity: sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-string-parser': 7.22.5 + '@babel/helper-validator-identifier': 7.22.20 + to-fast-properties: 2.0.0 + dev: true + + /@bcoe/v8-coverage@0.2.3: + resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==} + dev: true + + /@changesets/apply-release-plan@6.1.4: + resolution: {integrity: sha512-FMpKF1fRlJyCZVYHr3CbinpZZ+6MwvOtWUuO8uo+svcATEoc1zRDcj23pAurJ2TZ/uVz1wFHH6K3NlACy0PLew==} + dependencies: + '@babel/runtime': 7.23.1 + '@changesets/config': 2.3.1 + '@changesets/get-version-range-type': 0.3.2 + '@changesets/git': 2.0.0 + '@changesets/types': 5.2.1 + '@manypkg/get-packages': 1.1.3 + detect-indent: 6.1.0 + fs-extra: 7.0.1 + lodash.startcase: 4.4.0 + outdent: 0.5.0 + prettier: 2.8.8 + resolve-from: 5.0.0 + semver: 7.5.4 + dev: true + + /@changesets/assemble-release-plan@5.2.4: + resolution: {integrity: sha512-xJkWX+1/CUaOUWTguXEbCDTyWJFECEhmdtbkjhn5GVBGxdP/JwaHBIU9sW3FR6gD07UwZ7ovpiPclQZs+j+mvg==} + dependencies: + '@babel/runtime': 7.23.1 + '@changesets/errors': 0.1.4 + '@changesets/get-dependents-graph': 1.3.6 + '@changesets/types': 5.2.1 + '@manypkg/get-packages': 1.1.3 + semver: 7.5.4 + dev: true + + /@changesets/changelog-git@0.1.14: + resolution: {integrity: sha512-+vRfnKtXVWsDDxGctOfzJsPhaCdXRYoe+KyWYoq5X/GqoISREiat0l3L8B0a453B2B4dfHGcZaGyowHbp9BSaA==} + dependencies: + '@changesets/types': 5.2.1 + dev: true + + /@changesets/cli@2.26.2: + resolution: {integrity: sha512-dnWrJTmRR8bCHikJHl9b9HW3gXACCehz4OasrXpMp7sx97ECuBGGNjJhjPhdZNCvMy9mn4BWdplI323IbqsRig==} + hasBin: true + dependencies: + '@babel/runtime': 7.23.1 + '@changesets/apply-release-plan': 6.1.4 + '@changesets/assemble-release-plan': 5.2.4 + '@changesets/changelog-git': 0.1.14 + '@changesets/config': 2.3.1 + '@changesets/errors': 0.1.4 + '@changesets/get-dependents-graph': 1.3.6 + '@changesets/get-release-plan': 3.0.17 + '@changesets/git': 2.0.0 + '@changesets/logger': 0.0.5 + '@changesets/pre': 1.0.14 + '@changesets/read': 0.5.9 + '@changesets/types': 5.2.1 + '@changesets/write': 0.2.3 + '@manypkg/get-packages': 1.1.3 + '@types/is-ci': 3.0.2 + '@types/semver': 7.5.0 + ansi-colors: 4.1.3 + chalk: 2.4.2 + enquirer: 2.4.1 + external-editor: 3.1.0 + fs-extra: 7.0.1 + human-id: 1.0.2 + is-ci: 3.0.1 + meow: 6.1.1 + outdent: 0.5.0 + p-limit: 2.3.0 + preferred-pm: 3.1.2 + resolve-from: 5.0.0 + semver: 7.5.4 + spawndamnit: 2.0.0 + term-size: 2.2.1 + tty-table: 4.2.2 + dev: true + + /@changesets/config@2.3.1: + resolution: {integrity: sha512-PQXaJl82CfIXddUOppj4zWu+987GCw2M+eQcOepxN5s+kvnsZOwjEJO3DH9eVy+OP6Pg/KFEWdsECFEYTtbg6w==} + dependencies: + '@changesets/errors': 0.1.4 + '@changesets/get-dependents-graph': 1.3.6 + '@changesets/logger': 0.0.5 + '@changesets/types': 5.2.1 + '@manypkg/get-packages': 1.1.3 + fs-extra: 7.0.1 + micromatch: 4.0.5 + dev: true + + /@changesets/errors@0.1.4: + resolution: {integrity: sha512-HAcqPF7snsUJ/QzkWoKfRfXushHTu+K5KZLJWPb34s4eCZShIf8BFO3fwq6KU8+G7L5KdtN2BzQAXOSXEyiY9Q==} + dependencies: + extendable-error: 0.1.7 + dev: true + + /@changesets/get-dependents-graph@1.3.6: + resolution: {integrity: sha512-Q/sLgBANmkvUm09GgRsAvEtY3p1/5OCzgBE5vX3vgb5CvW0j7CEljocx5oPXeQSNph6FXulJlXV3Re/v3K3P3Q==} + dependencies: + '@changesets/types': 5.2.1 + '@manypkg/get-packages': 1.1.3 + chalk: 2.4.2 + fs-extra: 7.0.1 + semver: 7.5.4 + dev: true + + /@changesets/get-release-plan@3.0.17: + resolution: {integrity: sha512-6IwKTubNEgoOZwDontYc2x2cWXfr6IKxP3IhKeK+WjyD6y3M4Gl/jdQvBw+m/5zWILSOCAaGLu2ZF6Q+WiPniw==} + dependencies: + '@babel/runtime': 7.23.1 + '@changesets/assemble-release-plan': 5.2.4 + '@changesets/config': 2.3.1 + '@changesets/pre': 1.0.14 + '@changesets/read': 0.5.9 + '@changesets/types': 5.2.1 + '@manypkg/get-packages': 1.1.3 + dev: true + + /@changesets/get-version-range-type@0.3.2: + resolution: {integrity: sha512-SVqwYs5pULYjYT4op21F2pVbcrca4qA/bAA3FmFXKMN7Y+HcO8sbZUTx3TAy2VXulP2FACd1aC7f2nTuqSPbqg==} + dev: true + + /@changesets/git@2.0.0: + resolution: {integrity: sha512-enUVEWbiqUTxqSnmesyJGWfzd51PY4H7mH9yUw0hPVpZBJ6tQZFMU3F3mT/t9OJ/GjyiM4770i+sehAn6ymx6A==} + dependencies: + '@babel/runtime': 7.23.1 + '@changesets/errors': 0.1.4 + '@changesets/types': 5.2.1 + '@manypkg/get-packages': 1.1.3 + is-subdir: 1.2.0 + micromatch: 4.0.5 + spawndamnit: 2.0.0 + dev: true + + /@changesets/logger@0.0.5: + resolution: {integrity: sha512-gJyZHomu8nASHpaANzc6bkQMO9gU/ib20lqew1rVx753FOxffnCrJlGIeQVxNWCqM+o6OOleCo/ivL8UAO5iFw==} + dependencies: + chalk: 2.4.2 + dev: true + + /@changesets/parse@0.3.16: + resolution: {integrity: sha512-127JKNd167ayAuBjUggZBkmDS5fIKsthnr9jr6bdnuUljroiERW7FBTDNnNVyJ4l69PzR57pk6mXQdtJyBCJKg==} + dependencies: + '@changesets/types': 5.2.1 + js-yaml: 3.14.1 + dev: true + + /@changesets/pre@1.0.14: + resolution: {integrity: sha512-dTsHmxQWEQekHYHbg+M1mDVYFvegDh9j/kySNuDKdylwfMEevTeDouR7IfHNyVodxZXu17sXoJuf2D0vi55FHQ==} + dependencies: + '@babel/runtime': 7.23.1 + '@changesets/errors': 0.1.4 + '@changesets/types': 5.2.1 + '@manypkg/get-packages': 1.1.3 + fs-extra: 7.0.1 + dev: true + + /@changesets/read@0.5.9: + resolution: {integrity: sha512-T8BJ6JS6j1gfO1HFq50kU3qawYxa4NTbI/ASNVVCBTsKquy2HYwM9r7ZnzkiMe8IEObAJtUVGSrePCOxAK2haQ==} + dependencies: + '@babel/runtime': 7.23.1 + '@changesets/git': 2.0.0 + '@changesets/logger': 0.0.5 + '@changesets/parse': 0.3.16 + '@changesets/types': 5.2.1 + chalk: 2.4.2 + fs-extra: 7.0.1 + p-filter: 2.1.0 + dev: true + + /@changesets/types@4.1.0: + resolution: {integrity: sha512-LDQvVDv5Kb50ny2s25Fhm3d9QSZimsoUGBsUioj6MC3qbMUCuC8GPIvk/M6IvXx3lYhAs0lwWUQLb+VIEUCECw==} + dev: true + + /@changesets/types@5.2.1: + resolution: {integrity: sha512-myLfHbVOqaq9UtUKqR/nZA/OY7xFjQMdfgfqeZIBK4d0hA6pgxArvdv8M+6NUzzBsjWLOtvApv8YHr4qM+Kpfg==} + dev: true + + /@changesets/write@0.2.3: + resolution: {integrity: sha512-Dbamr7AIMvslKnNYsLFafaVORx4H0pvCA2MHqgtNCySMe1blImEyAEOzDmcgKAkgz4+uwoLz7demIrX+JBr/Xw==} + dependencies: + '@babel/runtime': 7.23.1 + '@changesets/types': 5.2.1 + fs-extra: 7.0.1 + human-id: 1.0.2 + prettier: 2.8.8 + dev: true + + /@cspotcode/source-map-support@0.8.1: + resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} + engines: {node: '>=12'} + dependencies: + '@jridgewell/trace-mapping': 0.3.9 + dev: true + + /@eslint-community/eslint-utils@4.4.0(eslint@8.48.0): + resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + dependencies: + eslint: 8.48.0 + eslint-visitor-keys: 3.4.3 + + /@eslint-community/eslint-utils@4.4.0(eslint@8.50.0): + resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + dependencies: + eslint: 8.50.0 + eslint-visitor-keys: 3.4.3 + dev: true + + /@eslint-community/regexpp@4.7.0: + resolution: {integrity: sha512-+HencqxU7CFJnQb7IKtuNBqS6Yx3Tz4kOL8BJXo+JyeiBm5MEX6pO8onXDkjrkCRlfYXS1Axro15ZjVFe9YgsA==} + engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} + + /@eslint-community/regexpp@4.9.1: + resolution: {integrity: sha512-Y27x+MBLjXa+0JWDhykM3+JE+il3kHKAEqabfEWq3SDhZjLYb6/BHL/JKFnH3fe207JaXkyDo685Oc2Glt6ifA==} + engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} + dev: true + + /@eslint/eslintrc@2.1.2: + resolution: {integrity: sha512-+wvgpDsrB1YqAMdEUCcnTlpfVBH7Vqn6A/NT3D8WVXFIaKMlErPIZT3oCIAVCOtarRpMtelZLqJeU3t7WY6X6g==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dependencies: + ajv: 6.12.6 + debug: 4.3.4(supports-color@8.1.1) + espree: 9.6.1 + globals: 13.20.0 + ignore: 5.2.4 + import-fresh: 3.3.0 + js-yaml: 4.1.0 + minimatch: 3.1.2 + strip-json-comments: 3.1.1 + transitivePeerDependencies: + - supports-color + + /@eslint/js@8.48.0: + resolution: {integrity: sha512-ZSjtmelB7IJfWD2Fvb7+Z+ChTIKWq6kjda95fLcQKNS5aheVHn4IkfgRQE3sIIzTcSLwLcLZUD9UBt+V7+h+Pw==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + /@eslint/js@8.50.0: + resolution: {integrity: sha512-NCC3zz2+nvYd+Ckfh87rA47zfu2QsQpvc6k1yzTk+b9KzRj0wkGa8LSoGOXN6Zv4lRf/EIoZ80biDh9HOI+RNQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dev: true + + /@humanwhocodes/config-array@0.11.10: + resolution: {integrity: sha512-KVVjQmNUepDVGXNuoRRdmmEjruj0KfiGSbS8LVc12LMsWDQzRXJ0qdhN8L8uUigKpfEHRhlaQFY0ib1tnUbNeQ==} + engines: {node: '>=10.10.0'} + dependencies: + '@humanwhocodes/object-schema': 1.2.1 + debug: 4.3.4(supports-color@8.1.1) + minimatch: 3.1.2 + transitivePeerDependencies: + - supports-color + + /@humanwhocodes/config-array@0.11.11: + resolution: {integrity: sha512-N2brEuAadi0CcdeMXUkhbZB84eskAc8MEX1By6qEchoVywSgXPIjou4rYsl0V3Hj0ZnuGycGCjdNgockbzeWNA==} + engines: {node: '>=10.10.0'} + dependencies: + '@humanwhocodes/object-schema': 1.2.1 + debug: 4.3.4(supports-color@8.1.1) + minimatch: 3.1.2 + transitivePeerDependencies: + - supports-color + dev: true + + /@humanwhocodes/module-importer@1.0.1: + resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} + engines: {node: '>=12.22'} + + /@humanwhocodes/object-schema@1.2.1: + resolution: {integrity: sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==} + + /@istanbuljs/schema@0.1.3: + resolution: {integrity: sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==} + engines: {node: '>=8'} + dev: true + + /@jridgewell/gen-mapping@0.3.3: + resolution: {integrity: sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==} + engines: {node: '>=6.0.0'} + dependencies: + '@jridgewell/set-array': 1.1.2 + '@jridgewell/sourcemap-codec': 1.4.15 + '@jridgewell/trace-mapping': 0.3.19 + dev: true + + /@jridgewell/resolve-uri@3.1.1: + resolution: {integrity: sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==} + engines: {node: '>=6.0.0'} + dev: true + + /@jridgewell/set-array@1.1.2: + resolution: {integrity: sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==} + engines: {node: '>=6.0.0'} + dev: true + + /@jridgewell/source-map@0.3.5: + resolution: {integrity: sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==} + dependencies: + '@jridgewell/gen-mapping': 0.3.3 + '@jridgewell/trace-mapping': 0.3.19 + dev: true + + /@jridgewell/sourcemap-codec@1.4.15: + resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==} + dev: true + + /@jridgewell/trace-mapping@0.3.19: + resolution: {integrity: sha512-kf37QtfW+Hwx/buWGMPcR60iF9ziHa6r/CZJIHbmcm4+0qrXiVdxegAH0F6yddEVQ7zdkjcGCgCzUu+BcbhQxw==} + dependencies: + '@jridgewell/resolve-uri': 3.1.1 + '@jridgewell/sourcemap-codec': 1.4.15 + dev: true + + /@jridgewell/trace-mapping@0.3.9: + resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} + dependencies: + '@jridgewell/resolve-uri': 3.1.1 + '@jridgewell/sourcemap-codec': 1.4.15 + dev: true + + /@manypkg/find-root@1.1.0: + resolution: {integrity: sha512-mki5uBvhHzO8kYYix/WRy2WX8S3B5wdVSc9D6KcU5lQNglP2yt58/VfLuAK49glRXChosY8ap2oJ1qgma3GUVA==} + dependencies: + '@babel/runtime': 7.23.1 + '@types/node': 12.20.55 + find-up: 4.1.0 + fs-extra: 8.1.0 + dev: true + + /@manypkg/get-packages@1.1.3: + resolution: {integrity: sha512-fo+QhuU3qE/2TQMQmbVMqaQ6EWbMhi4ABWP+O4AM1NqPBuy0OrApV5LO6BrrgnhtAHS2NH6RrVk9OL181tTi8A==} + dependencies: + '@babel/runtime': 7.23.1 + '@changesets/types': 4.1.0 + '@manypkg/find-root': 1.1.0 + fs-extra: 8.1.0 + globby: 11.1.0 + read-yaml-file: 1.1.0 + dev: true + + /@microsoft/tsdoc-config@0.16.2: + resolution: {integrity: sha512-OGiIzzoBLgWWR0UdRJX98oYO+XKGf7tiK4Zk6tQ/E4IJqGCe7dvkTvgDZV5cFJUzLGDOjeAXrnZoA6QkVySuxw==} + dependencies: + '@microsoft/tsdoc': 0.14.2 + ajv: 6.12.6 + jju: 1.4.0 + resolve: 1.19.0 + dev: false + + /@microsoft/tsdoc@0.14.2: + resolution: {integrity: sha512-9b8mPpKrfeGRuhFH5iO1iwCLeIIsV6+H1sRfxbkoGXIyQE2BTsPd9zqSqQJ+pv5sJ/hT5M1zvOFL02MnEezFug==} + dev: false + + /@noble/curves@1.2.0: + resolution: {integrity: sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw==} + dependencies: + '@noble/hashes': 1.3.2 + dev: false + + /@noble/hashes@1.3.2: + resolution: {integrity: sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ==} + engines: {node: '>= 16'} + dev: false + + /@nodelib/fs.scandir@2.1.5: + resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} + engines: {node: '>= 8'} + dependencies: + '@nodelib/fs.stat': 2.0.5 + run-parallel: 1.2.0 + + /@nodelib/fs.stat@2.0.5: + resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} + engines: {node: '>= 8'} + + /@nodelib/fs.walk@1.2.8: + resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} + engines: {node: '>= 8'} + dependencies: + '@nodelib/fs.scandir': 2.1.5 + fastq: 1.15.0 + + /@preconstruct/cli@2.8.1: + resolution: {integrity: sha512-PX5w+au06iY/QaT+9RLmRlIfavRCRoMTC/krwtNrgPEnubR9e6P+QlywrKmwiEvkzbR9AEzGnRZL8uNRDDMzrQ==} + hasBin: true + dependencies: + '@babel/code-frame': 7.22.13 + '@babel/core': 7.23.0 + '@babel/helper-module-imports': 7.22.15 + '@babel/runtime': 7.23.1 + '@preconstruct/hook': 0.4.0 + '@rollup/plugin-alias': 3.1.9(rollup@2.79.1) + '@rollup/plugin-commonjs': 15.1.0(rollup@2.79.1) + '@rollup/plugin-json': 4.1.0(rollup@2.79.1) + '@rollup/plugin-node-resolve': 11.2.1(rollup@2.79.1) + '@rollup/plugin-replace': 2.4.2(rollup@2.79.1) + builtin-modules: 3.3.0 + chalk: 4.1.2 + dataloader: 2.2.2 + detect-indent: 6.1.0 + enquirer: 2.4.1 + estree-walker: 2.0.2 + fast-deep-equal: 2.0.1 + fast-glob: 3.3.1 + fs-extra: 9.1.0 + is-ci: 2.0.0 + is-reference: 1.2.1 + jest-worker: 26.6.2 + magic-string: 0.30.4 + meow: 7.1.1 + ms: 2.1.3 + normalize-path: 3.0.0 + npm-packlist: 2.2.2 + p-limit: 3.1.0 + parse-glob: 3.0.4 + parse-json: 5.2.0 + quick-lru: 5.1.1 + resolve: 1.22.6 + resolve-from: 5.0.0 + rollup: 2.79.1 + semver: 7.5.4 + terser: 5.21.0 + v8-compile-cache: 2.4.0 + zod: 3.22.4 + transitivePeerDependencies: + - supports-color + dev: true + + /@preconstruct/hook@0.4.0: + resolution: {integrity: sha512-a7mrlPTM3tAFJyz43qb4pPVpUx8j8TzZBFsNFqcKcE/sEakNXRlQAuCT4RGZRf9dQiiUnBahzSIWawU4rENl+Q==} + dependencies: + '@babel/core': 7.23.0 + '@babel/plugin-transform-modules-commonjs': 7.23.0(@babel/core@7.23.0) + pirates: 4.0.6 + source-map-support: 0.5.21 + transitivePeerDependencies: + - supports-color + dev: true + + /@rollup/plugin-alias@3.1.9(rollup@2.79.1): + resolution: {integrity: sha512-QI5fsEvm9bDzt32k39wpOwZhVzRcL5ydcffUHMyLVaVaLeC70I8TJZ17F1z1eMoLu4E/UOcH9BWVkKpIKdrfiw==} + engines: {node: '>=8.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0 + dependencies: + rollup: 2.79.1 + slash: 3.0.0 + dev: true + + /@rollup/plugin-commonjs@15.1.0(rollup@2.79.1): + resolution: {integrity: sha512-xCQqz4z/o0h2syQ7d9LskIMvBSH4PX5PjYdpSSvgS+pQik3WahkQVNWg3D8XJeYjZoVWnIUQYDghuEMRGrmQYQ==} + engines: {node: '>= 8.0.0'} + peerDependencies: + rollup: ^2.22.0 + dependencies: + '@rollup/pluginutils': 3.1.0(rollup@2.79.1) + commondir: 1.0.1 + estree-walker: 2.0.2 + glob: 7.2.3 + is-reference: 1.2.1 + magic-string: 0.25.9 + resolve: 1.22.6 + rollup: 2.79.1 + dev: true + + /@rollup/plugin-json@4.1.0(rollup@2.79.1): + resolution: {integrity: sha512-yfLbTdNS6amI/2OpmbiBoW12vngr5NW2jCJVZSBEz+H5KfUJZ2M7sDjk0U6GOOdCWFVScShte29o9NezJ53TPw==} + peerDependencies: + rollup: ^1.20.0 || ^2.0.0 + dependencies: + '@rollup/pluginutils': 3.1.0(rollup@2.79.1) + rollup: 2.79.1 + dev: true + + /@rollup/plugin-node-resolve@11.2.1(rollup@2.79.1): + resolution: {integrity: sha512-yc2n43jcqVyGE2sqV5/YCmocy9ArjVAP/BeXyTtADTBBX6V0e5UMqwO8CdQ0kzjb6zu5P1qMzsScCMRvE9OlVg==} + engines: {node: '>= 10.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0 + dependencies: + '@rollup/pluginutils': 3.1.0(rollup@2.79.1) + '@types/resolve': 1.17.1 + builtin-modules: 3.3.0 + deepmerge: 4.3.1 + is-module: 1.0.0 + resolve: 1.22.6 + rollup: 2.79.1 + dev: true + + /@rollup/plugin-replace@2.4.2(rollup@2.79.1): + resolution: {integrity: sha512-IGcu+cydlUMZ5En85jxHH4qj2hta/11BHq95iHEyb2sbgiN0eCdzvUcHw5gt9pBL5lTi4JDYJ1acCoMGpTvEZg==} + peerDependencies: + rollup: ^1.20.0 || ^2.0.0 + dependencies: + '@rollup/pluginutils': 3.1.0(rollup@2.79.1) + magic-string: 0.25.9 + rollup: 2.79.1 + dev: true + + /@rollup/pluginutils@3.1.0(rollup@2.79.1): + resolution: {integrity: sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==} + engines: {node: '>= 8.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0 + dependencies: + '@types/estree': 0.0.39 + estree-walker: 1.0.1 + picomatch: 2.3.1 + rollup: 2.79.1 + dev: true + + /@scure/base@1.1.3: + resolution: {integrity: sha512-/+SgoRjLq7Xlf0CWuLHq2LUZeL/w65kfzAPG5NH9pcmBhs+nunQTn4gvdwgMTIXnt9b2C/1SeL2XiysZEyIC9Q==} + dev: false + + /@scure/bip32@1.3.2: + resolution: {integrity: sha512-N1ZhksgwD3OBlwTv3R6KFEcPojl/W4ElJOeCZdi+vuI5QmTFwLq3OFf2zd2ROpKvxFdgZ6hUpb0dx9bVNEwYCA==} + dependencies: + '@noble/curves': 1.2.0 + '@noble/hashes': 1.3.2 + '@scure/base': 1.1.3 + dev: false + + /@scure/bip39@1.2.1: + resolution: {integrity: sha512-Z3/Fsz1yr904dduJD0NpiyRHhRYHdcnyh73FZWiV+/qhWi83wNJ3NWolYqCEN+ZWsUz2TWwajJggcRE9r1zUYg==} + dependencies: + '@noble/hashes': 1.3.2 + '@scure/base': 1.1.3 + dev: false + + /@sinonjs/commons@2.0.0: + resolution: {integrity: sha512-uLa0j859mMrg2slwQYdO/AkrOfmH+X6LTVmNTS9CqexuE2IvVORIkSpJLqePAbEnKJ77aMmCwr1NUZ57120Xcg==} + dependencies: + type-detect: 4.0.8 + dev: true + + /@sinonjs/commons@3.0.0: + resolution: {integrity: sha512-jXBtWAF4vmdNmZgD5FoKsVLv3rPgDnLgPbU84LIJ3otV44vJlDRokVng5v8NFJdCf/da9legHcKaRuZs4L7faA==} + dependencies: + type-detect: 4.0.8 + dev: true + + /@sinonjs/fake-timers@10.3.0: + resolution: {integrity: sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==} + dependencies: + '@sinonjs/commons': 3.0.0 + dev: true + + /@sinonjs/samsam@8.0.0: + resolution: {integrity: sha512-Bp8KUVlLp8ibJZrnvq2foVhP0IVX2CIprMJPK0vqGqgrDa0OHVKeZyBykqskkrdxV6yKBPmGasO8LVjAKR3Gew==} + dependencies: + '@sinonjs/commons': 2.0.0 + lodash.get: 4.4.2 + type-detect: 4.0.8 + dev: true + + /@sinonjs/text-encoding@0.7.2: + resolution: {integrity: sha512-sXXKG+uL9IrKqViTtao2Ws6dy0znu9sOaP1di/jKGW1M6VssO8vlpXCQcpZ+jisQ1tTFAC5Jo/EOzFbggBagFQ==} + dev: true + + /@tsconfig/node10@1.0.9: + resolution: {integrity: sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==} + dev: true + + /@tsconfig/node12@1.0.11: + resolution: {integrity: sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==} + dev: true + + /@tsconfig/node14@1.0.3: + resolution: {integrity: sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==} + dev: true + + /@tsconfig/node16@1.0.4: + resolution: {integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==} + dev: true + + /@types/chai-as-promised@7.1.6: + resolution: {integrity: sha512-cQLhk8fFarRVZAXUQV1xEnZgMoPxqKojBvRkqPCKPQCzEhpbbSKl1Uu75kDng7k5Ln6LQLUmNBjLlFthCgm1NA==} + dependencies: + '@types/chai': 4.3.6 + dev: true + + /@types/chai@4.3.6: + resolution: {integrity: sha512-VOVRLM1mBxIRxydiViqPcKn6MIxZytrbMpd6RJLIWKxUNr3zux8no0Oc7kJx0WAPIitgZ0gkrDS+btlqQpubpw==} + dev: true + + /@types/estree@0.0.39: + resolution: {integrity: sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==} + dev: true + + /@types/estree@1.0.2: + resolution: {integrity: sha512-VeiPZ9MMwXjO32/Xu7+OwflfmeoRwkE/qzndw42gGtgJwZopBnzy2gD//NN1+go1mADzkDcqf/KnFRSjTJ8xJA==} + dev: true + + /@types/is-ci@3.0.2: + resolution: {integrity: sha512-9PyP1rgCro6xO3R7zOEoMgx5U9HpLhIg1FFb9p2mWX/x5QI8KMuCWWYtCT1dUQpicp84OsxEAw3iqwIKQY5Pog==} + dependencies: + ci-info: 3.9.0 + dev: true + + /@types/istanbul-lib-coverage@2.0.4: + resolution: {integrity: sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==} + dev: true + + /@types/json-schema@7.0.12: + resolution: {integrity: sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA==} + dev: false + + /@types/json5@0.0.29: + resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} + dev: false + + /@types/minimist@1.2.3: + resolution: {integrity: sha512-ZYFzrvyWUNhaPomn80dsMNgMeXxNWZBdkuG/hWlUvXvbdUH8ZERNBGXnU87McuGcWDsyzX2aChCv/SVN348k3A==} + dev: true + + /@types/mocha@10.0.2: + resolution: {integrity: sha512-NaHL0+0lLNhX6d9rs+NSt97WH/gIlRHmszXbQ/8/MV/eVcFNdeJ/GYhrFuUc8K7WuPhRhTSdMkCp8VMzhUq85w==} + dev: true + + /@types/node@12.20.55: + resolution: {integrity: sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==} + dev: true + + /@types/node@20.8.2: + resolution: {integrity: sha512-Vvycsc9FQdwhxE3y3DzeIxuEJbWGDsnrxvMADzTDF/lcdR9/K+AQIeAghTQsHtotg/q0j3WEOYS/jQgSdWue3w==} + dev: true + + /@types/normalize-package-data@2.4.2: + resolution: {integrity: sha512-lqa4UEhhv/2sjjIQgjX8B+RBjj47eo0mzGasklVJ78UKGQY1r0VpB9XHDaZZO9qzEFDdy4MrXLuEaSmPrPSe/A==} + dev: true + + /@types/prettier@2.7.3: + resolution: {integrity: sha512-+68kP9yzs4LMp7VNh8gdzMSPZFL44MLGqiHWvttYJe+6qnuVr4Ek9wSBQoveqY/r+LwjCcU29kNVkidwim+kYA==} + dev: true + + /@types/resolve@1.17.1: + resolution: {integrity: sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw==} + dependencies: + '@types/node': 20.8.2 + dev: true + + /@types/semver@7.5.0: + resolution: {integrity: sha512-G8hZ6XJiHnuhQKR7ZmysCeJWE08o8T0AXtk5darsCaTVsYZhhgUrq53jizaR2FvsoeCwJhlmwTjkXBY5Pn/ZHw==} + + /@types/sinon@10.0.18: + resolution: {integrity: sha512-OpQC9ug8BcnNxue2WF5aTruMaDRFn6NyfaE4DmAKOlQMn54b7CnCvDFV3wj5fk/HbSSTYmOYs2bTb5ShANjyQg==} + dependencies: + '@types/sinonjs__fake-timers': 8.1.3 + dev: true + + /@types/sinonjs__fake-timers@8.1.3: + resolution: {integrity: sha512-4g+2YyWe0Ve+LBh+WUm1697PD0Kdi6coG1eU0YjQbwx61AZ8XbEpL1zIT6WjuUKrCMCROpEaYQPDjBnDouBVAQ==} + dev: true + + /@typescript-eslint/eslint-plugin@6.5.0(@typescript-eslint/parser@6.5.0)(eslint@8.48.0)(typescript@5.2.2): + resolution: {integrity: sha512-2pktILyjvMaScU6iK3925uvGU87E+N9rh372uGZgiMYwafaw9SXq86U04XPq3UH6tzRvNgBsub6x2DacHc33lw==} + engines: {node: ^16.0.0 || >=18.0.0} + peerDependencies: + '@typescript-eslint/parser': ^6.0.0 || ^6.0.0-alpha + eslint: ^7.0.0 || ^8.0.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@eslint-community/regexpp': 4.7.0 + '@typescript-eslint/parser': 6.5.0(eslint@8.48.0)(typescript@5.2.2) + '@typescript-eslint/scope-manager': 6.5.0 + '@typescript-eslint/type-utils': 6.5.0(eslint@8.48.0)(typescript@5.2.2) + '@typescript-eslint/utils': 6.5.0(eslint@8.48.0)(typescript@5.2.2) + '@typescript-eslint/visitor-keys': 6.5.0 + debug: 4.3.4(supports-color@8.1.1) + eslint: 8.48.0 + graphemer: 1.4.0 + ignore: 5.2.4 + natural-compare: 1.4.0 + semver: 7.5.4 + ts-api-utils: 1.0.2(typescript@5.2.2) + typescript: 5.2.2 + transitivePeerDependencies: + - supports-color + dev: false + + /@typescript-eslint/parser@6.5.0(eslint@8.48.0)(typescript@5.2.2): + resolution: {integrity: sha512-LMAVtR5GN8nY0G0BadkG0XIe4AcNMeyEy3DyhKGAh9k4pLSMBO7rF29JvDBpZGCmp5Pgz5RLHP6eCpSYZJQDuQ==} + engines: {node: ^16.0.0 || >=18.0.0} + peerDependencies: + eslint: ^7.0.0 || ^8.0.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@typescript-eslint/scope-manager': 6.5.0 + '@typescript-eslint/types': 6.5.0 + '@typescript-eslint/typescript-estree': 6.5.0(typescript@5.2.2) + '@typescript-eslint/visitor-keys': 6.5.0 + debug: 4.3.4(supports-color@8.1.1) + eslint: 8.48.0 + typescript: 5.2.2 + transitivePeerDependencies: + - supports-color + dev: false + + /@typescript-eslint/scope-manager@6.5.0: + resolution: {integrity: sha512-A8hZ7OlxURricpycp5kdPTH3XnjG85UpJS6Fn4VzeoH4T388gQJ/PGP4ole5NfKt4WDVhmLaQ/dBLNDC4Xl/Kw==} + engines: {node: ^16.0.0 || >=18.0.0} + dependencies: + '@typescript-eslint/types': 6.5.0 + '@typescript-eslint/visitor-keys': 6.5.0 + dev: false + + /@typescript-eslint/type-utils@6.5.0(eslint@8.48.0)(typescript@5.2.2): + resolution: {integrity: sha512-f7OcZOkRivtujIBQ4yrJNIuwyCQO1OjocVqntl9dgSIZAdKqicj3xFDqDOzHDlGCZX990LqhLQXWRnQvsapq8A==} + engines: {node: ^16.0.0 || >=18.0.0} + peerDependencies: + eslint: ^7.0.0 || ^8.0.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@typescript-eslint/typescript-estree': 6.5.0(typescript@5.2.2) + '@typescript-eslint/utils': 6.5.0(eslint@8.48.0)(typescript@5.2.2) + debug: 4.3.4(supports-color@8.1.1) + eslint: 8.48.0 + ts-api-utils: 1.0.2(typescript@5.2.2) + typescript: 5.2.2 + transitivePeerDependencies: + - supports-color + dev: false + + /@typescript-eslint/types@6.5.0: + resolution: {integrity: sha512-eqLLOEF5/lU8jW3Bw+8auf4lZSbbljHR2saKnYqON12G/WsJrGeeDHWuQePoEf9ro22+JkbPfWQwKEC5WwLQ3w==} + engines: {node: ^16.0.0 || >=18.0.0} + dev: false + + /@typescript-eslint/typescript-estree@6.5.0(typescript@5.2.2): + resolution: {integrity: sha512-q0rGwSe9e5Kk/XzliB9h2LBc9tmXX25G0833r7kffbl5437FPWb2tbpIV9wAATebC/018pGa9fwPDuvGN+LxWQ==} + engines: {node: ^16.0.0 || >=18.0.0} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@typescript-eslint/types': 6.5.0 + '@typescript-eslint/visitor-keys': 6.5.0 + debug: 4.3.4(supports-color@8.1.1) + globby: 11.1.0 + is-glob: 4.0.3 + semver: 7.5.4 + ts-api-utils: 1.0.2(typescript@5.2.2) + typescript: 5.2.2 + transitivePeerDependencies: + - supports-color + dev: false + + /@typescript-eslint/utils@6.5.0(eslint@8.48.0)(typescript@5.2.2): + resolution: {integrity: sha512-9nqtjkNykFzeVtt9Pj6lyR9WEdd8npPhhIPM992FWVkZuS6tmxHfGVnlUcjpUP2hv8r4w35nT33mlxd+Be1ACQ==} + engines: {node: ^16.0.0 || >=18.0.0} + peerDependencies: + eslint: ^7.0.0 || ^8.0.0 + dependencies: + '@eslint-community/eslint-utils': 4.4.0(eslint@8.48.0) + '@types/json-schema': 7.0.12 + '@types/semver': 7.5.0 + '@typescript-eslint/scope-manager': 6.5.0 + '@typescript-eslint/types': 6.5.0 + '@typescript-eslint/typescript-estree': 6.5.0(typescript@5.2.2) + eslint: 8.48.0 + semver: 7.5.4 + transitivePeerDependencies: + - supports-color + - typescript + dev: false + + /@typescript-eslint/visitor-keys@6.5.0: + resolution: {integrity: sha512-yCB/2wkbv3hPsh02ZS8dFQnij9VVQXJMN/gbQsaaY+zxALkZnxa/wagvLEFsAWMPv7d7lxQmNsIzGU1w/T/WyA==} + engines: {node: ^16.0.0 || >=18.0.0} + dependencies: + '@typescript-eslint/types': 6.5.0 + eslint-visitor-keys: 3.4.3 + dev: false + + /abitype@0.10.2(typescript@5.2.2): + resolution: {integrity: sha512-1XndI+RKFWK4+TXCNv1683MRyX5NGmlHXCvqzjOqhSS3PQrxT2QYRZq1bMPPRNjn89B3eVaM2w7y3jVj/OIUzA==} + peerDependencies: + typescript: '>=5.0.4' + zod: ^3 >=3.22.0 + peerDependenciesMeta: + typescript: + optional: true + zod: + optional: true + dependencies: + typescript: 5.2.2 + dev: false + + /abitype@0.9.8(typescript@5.2.2): + resolution: {integrity: sha512-puLifILdm+8sjyss4S+fsUN09obiT1g2YW6CtcQF+QDzxR0euzgEB29MZujC6zMk2a6SVmtttq1fc6+YFA7WYQ==} + peerDependencies: + typescript: '>=5.0.4' + zod: ^3 >=3.19.1 + peerDependenciesMeta: + typescript: + optional: true + zod: + optional: true + dependencies: + typescript: 5.2.2 + dev: false + + /acorn-jsx@5.3.2(acorn@8.10.0): + resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + dependencies: + acorn: 8.10.0 + + /acorn-walk@8.2.0: + resolution: {integrity: sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==} + engines: {node: '>=0.4.0'} + dev: true + + /acorn@8.10.0: + resolution: {integrity: sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==} + engines: {node: '>=0.4.0'} + hasBin: true + + /ajv@6.12.6: + resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} + dependencies: + fast-deep-equal: 3.1.3 + fast-json-stable-stringify: 2.1.0 + json-schema-traverse: 0.4.1 + uri-js: 4.4.1 + + /ansi-colors@4.1.1: + resolution: {integrity: sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==} + engines: {node: '>=6'} + dev: true + + /ansi-colors@4.1.3: + resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==} + engines: {node: '>=6'} + dev: true + + /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'} + dependencies: + color-convert: 1.9.3 + dev: true + + /ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + dependencies: + color-convert: 2.0.1 + + /anymatch@3.1.3: + resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} + engines: {node: '>= 8'} + dependencies: + normalize-path: 3.0.0 + picomatch: 2.3.1 + dev: true + + /arg@4.1.3: + resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==} + dev: true + + /argparse@1.0.10: + resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} + dependencies: + sprintf-js: 1.0.3 + dev: true + + /argparse@2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + + /array-back@3.1.0: + resolution: {integrity: sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q==} + engines: {node: '>=6'} + dev: true + + /array-back@4.0.2: + resolution: {integrity: sha512-NbdMezxqf94cnNfWLL7V/im0Ub+Anbb0IoZhvzie8+4HJ4nMQuzHuy49FkGYCJK2yAloZ3meiB6AVMClbrI1vg==} + engines: {node: '>=8'} + dev: true + + /array-buffer-byte-length@1.0.0: + resolution: {integrity: sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A==} + dependencies: + call-bind: 1.0.2 + is-array-buffer: 3.0.2 + + /array-includes@3.1.7: + resolution: {integrity: sha512-dlcsNBIiWhPkHdOEEKnehA+RNUWDc4UqFtnIXU4uuYDPtA4LDkr7qip2p0VvFAEXNDr0yWZ9PJyIRiGjRLQzwQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + define-properties: 1.2.1 + es-abstract: 1.22.2 + get-intrinsic: 1.2.1 + is-string: 1.0.7 + dev: false + + /array-union@2.1.0: + resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} + engines: {node: '>=8'} + + /array.prototype.findlastindex@1.2.3: + resolution: {integrity: sha512-LzLoiOMAxvy+Gd3BAq3B7VeIgPdo+Q8hthvKtXybMvRV0jrXfJM/t8mw7nNlpEcVlVUnCnM2KSX4XU5HmpodOA==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + define-properties: 1.2.1 + es-abstract: 1.22.2 + es-shim-unscopables: 1.0.0 + get-intrinsic: 1.2.1 + dev: false + + /array.prototype.flat@1.3.2: + resolution: {integrity: sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + define-properties: 1.2.1 + es-abstract: 1.22.2 + es-shim-unscopables: 1.0.0 + + /array.prototype.flatmap@1.3.2: + resolution: {integrity: sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + define-properties: 1.2.1 + es-abstract: 1.22.2 + es-shim-unscopables: 1.0.0 + dev: false + + /arraybuffer.prototype.slice@1.0.2: + resolution: {integrity: sha512-yMBKppFur/fbHu9/6USUe03bZ4knMYiwFBcyiaXB8Go0qNehwX6inYPzK9U0NeQvGxKthcmHcaR8P5MStSRBAw==} + engines: {node: '>= 0.4'} + dependencies: + array-buffer-byte-length: 1.0.0 + call-bind: 1.0.2 + define-properties: 1.2.1 + es-abstract: 1.22.2 + get-intrinsic: 1.2.1 + is-array-buffer: 3.0.2 + is-shared-array-buffer: 1.0.2 + + /arrify@1.0.1: + resolution: {integrity: sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==} + engines: {node: '>=0.10.0'} + dev: true + + /assertion-error@1.1.0: + resolution: {integrity: sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==} + dev: true + + /asynckit@0.4.0: + resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + dev: false + + /at-least-node@1.0.0: + resolution: {integrity: sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==} + engines: {node: '>= 4.0.0'} + dev: true + + /available-typed-arrays@1.0.5: + resolution: {integrity: sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==} + engines: {node: '>= 0.4'} + + /axios@1.5.1: + resolution: {integrity: sha512-Q28iYCWzNHjAm+yEAot5QaAMxhMghWLFVf7rRdwhUI+c2jix2DUXjAHXVi+s1ibs3mjPO/cCgbA++3BjD0vP/A==} + dependencies: + follow-redirects: 1.15.3 + form-data: 4.0.0 + proxy-from-env: 1.1.0 + transitivePeerDependencies: + - debug + dev: false + + /babel-plugin-polyfill-corejs2@0.4.5(@babel/core@7.23.0): + resolution: {integrity: sha512-19hwUH5FKl49JEsvyTcoHakh6BE0wgXLLptIyKZ3PijHc/Ci521wygORCUCCred+E/twuqRyAkE02BAWPmsHOg==} + peerDependencies: + '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 + dependencies: + '@babel/compat-data': 7.22.20 + '@babel/core': 7.23.0 + '@babel/helper-define-polyfill-provider': 0.4.2(@babel/core@7.23.0) + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + dev: true + + /babel-plugin-polyfill-corejs3@0.8.4(@babel/core@7.23.0): + resolution: {integrity: sha512-9l//BZZsPR+5XjyJMPtZSK4jv0BsTO1zDac2GC6ygx9WLGlcsnRd1Co0B2zT5fF5Ic6BZy+9m3HNZ3QcOeDKfg==} + peerDependencies: + '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 + dependencies: + '@babel/core': 7.23.0 + '@babel/helper-define-polyfill-provider': 0.4.2(@babel/core@7.23.0) + core-js-compat: 3.33.0 + transitivePeerDependencies: + - supports-color + dev: true + + /babel-plugin-polyfill-regenerator@0.5.2(@babel/core@7.23.0): + resolution: {integrity: sha512-tAlOptU0Xj34V1Y2PNTL4Y0FOJMDB6bZmoW39FeCQIhigGLkqu3Fj6uiXpxIf6Ij274ENdYx64y6Au+ZKlb1IA==} + peerDependencies: + '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 + dependencies: + '@babel/core': 7.23.0 + '@babel/helper-define-polyfill-provider': 0.4.2(@babel/core@7.23.0) + transitivePeerDependencies: + - supports-color + dev: true + + /balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + + /better-path-resolve@1.0.0: + resolution: {integrity: sha512-pbnl5XzGBdrFU/wT4jqmJVPn2B6UHPBOhzMQkY/SPUPB6QtUXtmBHBIwCbXJol93mOpGMnQyP/+BB19q04xj7g==} + engines: {node: '>=4'} + dependencies: + is-windows: 1.0.2 + dev: true + + /binary-extensions@2.2.0: + resolution: {integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==} + engines: {node: '>=8'} + dev: true + + /brace-expansion@1.1.11: + resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + + /brace-expansion@2.0.1: + resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} + dependencies: + balanced-match: 1.0.2 + dev: true + + /braces@3.0.2: + resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==} + engines: {node: '>=8'} + dependencies: + fill-range: 7.0.1 + + /breakword@1.0.6: + resolution: {integrity: sha512-yjxDAYyK/pBvws9H4xKYpLDpYKEH6CzrBPAuXq3x18I+c/2MkVtT3qAr7Oloi6Dss9qNhPVueAAVU1CSeNDIXw==} + dependencies: + wcwidth: 1.0.1 + dev: true + + /browser-stdout@1.3.1: + resolution: {integrity: sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==} + dev: true + + /browserslist@4.22.1: + resolution: {integrity: sha512-FEVc202+2iuClEhZhrWy6ZiAcRLvNMyYcxZ8raemul1DYVOVdFsbqckWLdsixQZCpJlwe77Z3UTalE7jsjnKfQ==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + dependencies: + caniuse-lite: 1.0.30001543 + electron-to-chromium: 1.4.542 + node-releases: 2.0.13 + update-browserslist-db: 1.0.13(browserslist@4.22.1) + dev: true + + /buffer-from@1.1.2: + resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} + dev: true + + /builtin-modules@3.3.0: + resolution: {integrity: sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==} + engines: {node: '>=6'} + dev: true + + /c8@8.0.1: + resolution: {integrity: sha512-EINpopxZNH1mETuI0DzRA4MZpAUH+IFiRhnmFD3vFr3vdrgxqi3VfE3KL0AIL+zDq8rC9bZqwM/VDmmoe04y7w==} + engines: {node: '>=12'} + hasBin: true + dependencies: + '@bcoe/v8-coverage': 0.2.3 + '@istanbuljs/schema': 0.1.3 + find-up: 5.0.0 + foreground-child: 2.0.0 + istanbul-lib-coverage: 3.2.0 + istanbul-lib-report: 3.0.1 + istanbul-reports: 3.1.6 + rimraf: 3.0.2 + test-exclude: 6.0.0 + v8-to-istanbul: 9.1.2 + yargs: 17.7.2 + yargs-parser: 21.1.1 + dev: true + + /call-bind@1.0.2: + resolution: {integrity: sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==} + dependencies: + function-bind: 1.1.1 + get-intrinsic: 1.2.1 + + /callsites@3.1.0: + resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} + engines: {node: '>=6'} + + /camelcase-keys@6.2.2: + resolution: {integrity: sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==} + engines: {node: '>=8'} + dependencies: + camelcase: 5.3.1 + map-obj: 4.3.0 + quick-lru: 4.0.1 + dev: true + + /camelcase@5.3.1: + resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==} + engines: {node: '>=6'} + dev: true + + /camelcase@6.3.0: + resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} + engines: {node: '>=10'} + dev: true + + /caniuse-lite@1.0.30001543: + resolution: {integrity: sha512-qxdO8KPWPQ+Zk6bvNpPeQIOH47qZSYdFZd6dXQzb2KzhnSXju4Kd7H1PkSJx6NICSMgo/IhRZRhhfPTHYpJUCA==} + dev: true + + /chai-as-promised@7.1.1(chai@4.3.10): + resolution: {integrity: sha512-azL6xMoi+uxu6z4rhWQ1jbdUhOMhis2PvscD/xjLqNMkv3BPPp2JyyuTHOrf9BOosGpNQ11v6BKv/g57RXbiaA==} + peerDependencies: + chai: '>= 2.1.2 < 5' + dependencies: + chai: 4.3.10 + check-error: 1.0.3 + dev: true + + /chai@4.3.10: + resolution: {integrity: sha512-0UXG04VuVbruMUYbJ6JctvH0YnC/4q3/AkT18q4NaITo91CUm0liMS9VqzT9vZhVQ/1eqPanMWjBM+Juhfb/9g==} + engines: {node: '>=4'} + dependencies: + assertion-error: 1.1.0 + check-error: 1.0.3 + deep-eql: 4.1.3 + get-func-name: 2.0.2 + loupe: 2.3.6 + pathval: 1.1.1 + type-detect: 4.0.8 + dev: true + + /chalk@2.4.2: + resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} + engines: {node: '>=4'} + dependencies: + ansi-styles: 3.2.1 + escape-string-regexp: 1.0.5 + supports-color: 5.5.0 + dev: true + + /chalk@4.1.2: + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} + engines: {node: '>=10'} + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + + /chardet@0.7.0: + resolution: {integrity: sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==} + dev: true + + /check-error@1.0.3: + resolution: {integrity: sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==} + dependencies: + get-func-name: 2.0.2 + dev: true + + /chokidar@3.5.3: + resolution: {integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==} + engines: {node: '>= 8.10.0'} + dependencies: + anymatch: 3.1.3 + braces: 3.0.2 + glob-parent: 5.1.2 + is-binary-path: 2.1.0 + is-glob: 4.0.3 + normalize-path: 3.0.0 + readdirp: 3.6.0 + optionalDependencies: + fsevents: 2.3.3 + dev: true + + /ci-info@2.0.0: + resolution: {integrity: sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==} + dev: true + + /ci-info@3.9.0: + resolution: {integrity: sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==} + engines: {node: '>=8'} + dev: true + + /cliui@6.0.0: + resolution: {integrity: sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==} + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 6.2.0 + dev: true + + /cliui@7.0.4: + resolution: {integrity: sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==} + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 7.0.0 + dev: true + + /cliui@8.0.1: + resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} + engines: {node: '>=12'} + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 7.0.0 + dev: true + + /clone@1.0.4: + resolution: {integrity: sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==} + engines: {node: '>=0.8'} + dev: true + + /color-convert@1.9.3: + resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} + dependencies: + color-name: 1.1.3 + dev: true + + /color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + dependencies: + color-name: 1.1.4 + + /color-name@1.1.3: + resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==} + dev: true + + /color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + + /combined-stream@1.0.8: + resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} + engines: {node: '>= 0.8'} + dependencies: + delayed-stream: 1.0.0 + dev: false + + /command-line-args@5.2.1: + resolution: {integrity: sha512-H4UfQhZyakIjC74I9d34fGYDwk3XpSr17QhEd0Q3I9Xq1CETHo4Hcuo87WyWHpAF1aSLjLRf5lD9ZGX2qStUvg==} + engines: {node: '>=4.0.0'} + dependencies: + array-back: 3.1.0 + find-replace: 3.0.0 + lodash.camelcase: 4.3.0 + typical: 4.0.0 + dev: true + + /command-line-usage@6.1.3: + resolution: {integrity: sha512-sH5ZSPr+7UStsloltmDh7Ce5fb8XPlHyoPzTpyyMuYCtervL65+ubVZ6Q61cFtFl62UyJlc8/JwERRbAFPUqgw==} + engines: {node: '>=8.0.0'} + dependencies: + array-back: 4.0.2 + chalk: 2.4.2 + table-layout: 1.0.2 + typical: 5.2.0 + dev: true + + /commander@2.20.3: + resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} + dev: true + + /commondir@1.0.1: + resolution: {integrity: sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==} + dev: true + + /concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + + /convert-source-map@2.0.0: + resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + dev: true + + /core-js-compat@3.33.0: + resolution: {integrity: sha512-0w4LcLXsVEuNkIqwjjf9rjCoPhK8uqA4tMRh4Ge26vfLtUutshn+aRJU21I9LCJlh2QQHfisNToLjw1XEJLTWw==} + dependencies: + browserslist: 4.22.1 + dev: true + + /create-require@1.1.1: + resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==} + dev: true + + /cross-spawn@5.1.0: + resolution: {integrity: sha512-pTgQJ5KC0d2hcY8eyL1IzlBPYjTkyH72XRZPnLyKus2mBfNjQs3klqbJU2VILqZryAZUt9JOb3h/mWMy23/f5A==} + dependencies: + lru-cache: 4.1.5 + shebang-command: 1.2.0 + which: 1.3.1 + dev: true + + /cross-spawn@7.0.3: + resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} + engines: {node: '>= 8'} + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + + /csv-generate@3.4.3: + resolution: {integrity: sha512-w/T+rqR0vwvHqWs/1ZyMDWtHHSJaN06klRqJXBEpDJaM/+dZkso0OKh1VcuuYvK3XM53KysVNq8Ko/epCK8wOw==} + dev: true + + /csv-parse@4.16.3: + resolution: {integrity: sha512-cO1I/zmz4w2dcKHVvpCr7JVRu8/FymG5OEpmvsZYlccYolPBLoVGKUHgNoc4ZGkFeFlWGEDmMyBM+TTqRdW/wg==} + dev: true + + /csv-stringify@5.6.5: + resolution: {integrity: sha512-PjiQ659aQ+fUTQqSrd1XEDnOr52jh30RBurfzkscaE2tPaFsDH5wOAHJiw8XAHphRknCwMUE9KRayc4K/NbO8A==} + dev: true + + /csv@5.5.3: + resolution: {integrity: sha512-QTaY0XjjhTQOdguARF0lGKm5/mEq9PD9/VhZZegHDIBq2tQwgNpHc3dneD4mGo2iJs+fTKv5Bp0fZ+BRuY3Z0g==} + engines: {node: '>= 0.1.90'} + dependencies: + csv-generate: 3.4.3 + csv-parse: 4.16.3 + csv-stringify: 5.6.5 + stream-transform: 2.1.3 + dev: true + + /dataloader@2.2.2: + resolution: {integrity: sha512-8YnDaaf7N3k/q5HnTJVuzSyLETjoZjVmHc4AeKAzOvKHEFQKcn64OKBfzHYtE9zGjctNM7V9I0MfnUVLpi7M5g==} + dev: true + + /debug@3.2.7: + resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + dependencies: + ms: 2.1.2 + dev: false + + /debug@4.3.4(supports-color@8.1.1): + resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + dependencies: + ms: 2.1.2 + supports-color: 8.1.1 + + /decamelize-keys@1.1.1: + resolution: {integrity: sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg==} + engines: {node: '>=0.10.0'} + dependencies: + decamelize: 1.2.0 + map-obj: 1.0.1 + dev: true + + /decamelize@1.2.0: + resolution: {integrity: sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==} + engines: {node: '>=0.10.0'} + dev: true + + /decamelize@4.0.0: + resolution: {integrity: sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==} + engines: {node: '>=10'} + dev: true + + /deep-eql@4.1.3: + resolution: {integrity: sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==} + engines: {node: '>=6'} + dependencies: + type-detect: 4.0.8 + dev: true + + /deep-extend@0.6.0: + resolution: {integrity: sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==} + engines: {node: '>=4.0.0'} + dev: true + + /deep-is@0.1.4: + resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + + /deepmerge@4.3.1: + resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} + engines: {node: '>=0.10.0'} + dev: true + + /defaults@1.0.4: + resolution: {integrity: sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==} + dependencies: + clone: 1.0.4 + dev: true + + /define-data-property@1.1.0: + resolution: {integrity: sha512-UzGwzcjyv3OtAvolTj1GoyNYzfFR+iqbGjcnBEENZVCpM4/Ng1yhGNvS3lR/xDS74Tb2wGG9WzNSNIOS9UVb2g==} + engines: {node: '>= 0.4'} + dependencies: + get-intrinsic: 1.2.1 + gopd: 1.0.1 + has-property-descriptors: 1.0.0 + + /define-properties@1.2.1: + resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} + engines: {node: '>= 0.4'} + dependencies: + define-data-property: 1.1.0 + has-property-descriptors: 1.0.0 + object-keys: 1.1.1 + + /delayed-stream@1.0.0: + resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} + engines: {node: '>=0.4.0'} + dev: false + + /detect-indent@6.1.0: + resolution: {integrity: sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==} + engines: {node: '>=8'} + dev: true + + /diff@4.0.2: + resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==} + engines: {node: '>=0.3.1'} + dev: true + + /diff@5.0.0: + resolution: {integrity: sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==} + engines: {node: '>=0.3.1'} + dev: true + + /diff@5.1.0: + resolution: {integrity: sha512-D+mk+qE8VC/PAUrlAU34N+VfXev0ghe5ywmpqrawphmVZc1bEfn56uo9qpyGp1p4xpzOHkSW4ztBd6L7Xx4ACw==} + engines: {node: '>=0.3.1'} + dev: true + + /dir-glob@3.0.1: + resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} + engines: {node: '>=8'} + dependencies: + path-type: 4.0.0 + + /doctrine@2.1.0: + resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==} + engines: {node: '>=0.10.0'} + dependencies: + esutils: 2.0.3 + dev: false + + /doctrine@3.0.0: + resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==} + engines: {node: '>=6.0.0'} + dependencies: + esutils: 2.0.3 + + /dotenv@16.0.3: + resolution: {integrity: sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ==} + engines: {node: '>=12'} + dev: false + + /dotenv@16.3.1: + resolution: {integrity: sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ==} + engines: {node: '>=12'} + dev: false + + /electron-to-chromium@1.4.542: + resolution: {integrity: sha512-6+cpa00G09N3sfh2joln4VUXHquWrOFx3FLZqiVQvl45+zS9DskDBTPvob+BhvFRmTBkyDSk0vvLMMRo/qc6mQ==} + dev: true + + /emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + dev: true + + /enquirer@2.4.1: + resolution: {integrity: sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==} + engines: {node: '>=8.6'} + dependencies: + ansi-colors: 4.1.3 + strip-ansi: 6.0.1 + dev: true + + /error-ex@1.3.2: + resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} + dependencies: + is-arrayish: 0.2.1 + dev: true + + /es-abstract@1.22.2: + resolution: {integrity: sha512-YoxfFcDmhjOgWPWsV13+2RNjq1F6UQnfs+8TftwNqtzlmFzEXvlUwdrNrYeaizfjQzRMxkZ6ElWMOJIFKdVqwA==} + engines: {node: '>= 0.4'} + dependencies: + array-buffer-byte-length: 1.0.0 + arraybuffer.prototype.slice: 1.0.2 + available-typed-arrays: 1.0.5 + call-bind: 1.0.2 + es-set-tostringtag: 2.0.1 + es-to-primitive: 1.2.1 + function.prototype.name: 1.1.6 + get-intrinsic: 1.2.1 + get-symbol-description: 1.0.0 + globalthis: 1.0.3 + gopd: 1.0.1 + has: 1.0.3 + has-property-descriptors: 1.0.0 + has-proto: 1.0.1 + has-symbols: 1.0.3 + internal-slot: 1.0.5 + is-array-buffer: 3.0.2 + is-callable: 1.2.7 + is-negative-zero: 2.0.2 + is-regex: 1.1.4 + is-shared-array-buffer: 1.0.2 + is-string: 1.0.7 + is-typed-array: 1.1.12 + is-weakref: 1.0.2 + object-inspect: 1.12.3 + object-keys: 1.1.1 + object.assign: 4.1.4 + regexp.prototype.flags: 1.5.1 + safe-array-concat: 1.0.1 + safe-regex-test: 1.0.0 + string.prototype.trim: 1.2.8 + string.prototype.trimend: 1.0.7 + string.prototype.trimstart: 1.0.7 + typed-array-buffer: 1.0.0 + typed-array-byte-length: 1.0.0 + typed-array-byte-offset: 1.0.0 + typed-array-length: 1.0.4 + unbox-primitive: 1.0.2 + which-typed-array: 1.1.11 + + /es-set-tostringtag@2.0.1: + resolution: {integrity: sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg==} + engines: {node: '>= 0.4'} + dependencies: + get-intrinsic: 1.2.1 + has: 1.0.3 + has-tostringtag: 1.0.0 + + /es-shim-unscopables@1.0.0: + resolution: {integrity: sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w==} + dependencies: + has: 1.0.3 + + /es-to-primitive@1.2.1: + resolution: {integrity: sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==} + engines: {node: '>= 0.4'} + dependencies: + is-callable: 1.2.7 + is-date-object: 1.0.5 + is-symbol: 1.0.4 + + /escalade@3.1.1: + resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==} + engines: {node: '>=6'} + dev: true + + /escape-string-regexp@1.0.5: + resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} + engines: {node: '>=0.8.0'} + dev: true + + /escape-string-regexp@4.0.0: + resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} + engines: {node: '>=10'} + + /eslint-config-prettier@8.10.0(eslint@8.48.0): + resolution: {integrity: sha512-SM8AMJdeQqRYT9O9zguiruQZaN7+z+E4eAP9oiLNGKMtomwaB1E9dcgUD6ZAn/eQAb52USbvezbiljfZUhbJcg==} + hasBin: true + peerDependencies: + eslint: '>=7.0.0' + dependencies: + eslint: 8.48.0 + dev: false + + /eslint-config-turbo@1.10.14(eslint@8.48.0): + resolution: {integrity: sha512-ZeB+IcuFXy1OICkLuAplVa0euoYbhK+bMEQd0nH9+Lns18lgZRm33mVz/iSoH9VdUzl/1ZmFmoK+RpZc+8R80A==} + peerDependencies: + eslint: '>6.6.0' + dependencies: + eslint: 8.48.0 + eslint-plugin-turbo: 1.10.14(eslint@8.48.0) + dev: false + + /eslint-import-resolver-node@0.3.9: + resolution: {integrity: sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==} + dependencies: + debug: 3.2.7 + is-core-module: 2.13.0 + resolve: 1.22.6 + transitivePeerDependencies: + - supports-color + dev: false + + /eslint-module-utils@2.8.0(@typescript-eslint/parser@6.5.0)(eslint-import-resolver-node@0.3.9)(eslint@8.48.0): + resolution: {integrity: sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw==} + engines: {node: '>=4'} + peerDependencies: + '@typescript-eslint/parser': '*' + eslint: '*' + eslint-import-resolver-node: '*' + eslint-import-resolver-typescript: '*' + eslint-import-resolver-webpack: '*' + peerDependenciesMeta: + '@typescript-eslint/parser': + optional: true + eslint: + optional: true + eslint-import-resolver-node: + optional: true + eslint-import-resolver-typescript: + optional: true + eslint-import-resolver-webpack: + optional: true + dependencies: + '@typescript-eslint/parser': 6.5.0(eslint@8.48.0)(typescript@5.2.2) + debug: 3.2.7 + eslint: 8.48.0 + eslint-import-resolver-node: 0.3.9 + transitivePeerDependencies: + - supports-color + dev: false + + /eslint-plugin-import@2.28.1(@typescript-eslint/parser@6.5.0)(eslint@8.48.0): + resolution: {integrity: sha512-9I9hFlITvOV55alzoKBI+K9q74kv0iKMeY6av5+umsNwayt59fz692daGyjR+oStBQgx6nwR9rXldDev3Clw+A==} + engines: {node: '>=4'} + peerDependencies: + '@typescript-eslint/parser': '*' + eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 + peerDependenciesMeta: + '@typescript-eslint/parser': + optional: true + dependencies: + '@typescript-eslint/parser': 6.5.0(eslint@8.48.0)(typescript@5.2.2) + array-includes: 3.1.7 + array.prototype.findlastindex: 1.2.3 + array.prototype.flat: 1.3.2 + array.prototype.flatmap: 1.3.2 + debug: 3.2.7 + doctrine: 2.1.0 + eslint: 8.48.0 + eslint-import-resolver-node: 0.3.9 + eslint-module-utils: 2.8.0(@typescript-eslint/parser@6.5.0)(eslint-import-resolver-node@0.3.9)(eslint@8.48.0) + has: 1.0.3 + is-core-module: 2.13.0 + is-glob: 4.0.3 + minimatch: 3.1.2 + object.fromentries: 2.0.7 + object.groupby: 1.0.1 + object.values: 1.1.7 + semver: 6.3.1 + tsconfig-paths: 3.14.2 + transitivePeerDependencies: + - eslint-import-resolver-typescript + - eslint-import-resolver-webpack + - supports-color + dev: false + + /eslint-plugin-tsdoc@0.2.17: + resolution: {integrity: sha512-xRmVi7Zx44lOBuYqG8vzTXuL6IdGOeF9nHX17bjJ8+VE6fsxpdGem0/SBTmAwgYMKYB1WBkqRJVQ+n8GK041pA==} + dependencies: + '@microsoft/tsdoc': 0.14.2 + '@microsoft/tsdoc-config': 0.16.2 + dev: false + + /eslint-plugin-turbo@1.10.14(eslint@8.48.0): + resolution: {integrity: sha512-sBdBDnYr9AjT1g4lR3PBkZDonTrMnR4TvuGv5W0OiF7z9az1rI68yj2UHJZvjkwwcGu5mazWA1AfB0oaagpmfg==} + peerDependencies: + eslint: '>6.6.0' + dependencies: + dotenv: 16.0.3 + eslint: 8.48.0 + dev: false + + /eslint-scope@7.2.2: + resolution: {integrity: sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dependencies: + esrecurse: 4.3.0 + estraverse: 5.3.0 + + /eslint-visitor-keys@3.4.3: + resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + /eslint@8.48.0: + resolution: {integrity: sha512-sb6DLeIuRXxeM1YljSe1KEx9/YYeZFQWcV8Rq9HfigmdDEugjLEVEa1ozDjL6YDjBpQHPJxJzze+alxi4T3OLg==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + hasBin: true + dependencies: + '@eslint-community/eslint-utils': 4.4.0(eslint@8.48.0) + '@eslint-community/regexpp': 4.7.0 + '@eslint/eslintrc': 2.1.2 + '@eslint/js': 8.48.0 + '@humanwhocodes/config-array': 0.11.10 + '@humanwhocodes/module-importer': 1.0.1 + '@nodelib/fs.walk': 1.2.8 + ajv: 6.12.6 + chalk: 4.1.2 + cross-spawn: 7.0.3 + debug: 4.3.4(supports-color@8.1.1) + doctrine: 3.0.0 + escape-string-regexp: 4.0.0 + eslint-scope: 7.2.2 + eslint-visitor-keys: 3.4.3 + espree: 9.6.1 + esquery: 1.5.0 + esutils: 2.0.3 + fast-deep-equal: 3.1.3 + file-entry-cache: 6.0.1 + find-up: 5.0.0 + glob-parent: 6.0.2 + globals: 13.20.0 + graphemer: 1.4.0 + ignore: 5.2.4 + imurmurhash: 0.1.4 + is-glob: 4.0.3 + is-path-inside: 3.0.3 + js-yaml: 4.1.0 + json-stable-stringify-without-jsonify: 1.0.1 + levn: 0.4.1 + lodash.merge: 4.6.2 + minimatch: 3.1.2 + natural-compare: 1.4.0 + optionator: 0.9.3 + strip-ansi: 6.0.1 + text-table: 0.2.0 + transitivePeerDependencies: + - supports-color + + /eslint@8.50.0: + resolution: {integrity: sha512-FOnOGSuFuFLv/Sa+FDVRZl4GGVAAFFi8LecRsI5a1tMO5HIE8nCm4ivAlzt4dT3ol/PaaGC0rJEEXQmHJBGoOg==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + hasBin: true + dependencies: + '@eslint-community/eslint-utils': 4.4.0(eslint@8.50.0) + '@eslint-community/regexpp': 4.9.1 + '@eslint/eslintrc': 2.1.2 + '@eslint/js': 8.50.0 + '@humanwhocodes/config-array': 0.11.11 + '@humanwhocodes/module-importer': 1.0.1 + '@nodelib/fs.walk': 1.2.8 + ajv: 6.12.6 + chalk: 4.1.2 + cross-spawn: 7.0.3 + debug: 4.3.4(supports-color@8.1.1) + doctrine: 3.0.0 + escape-string-regexp: 4.0.0 + eslint-scope: 7.2.2 + eslint-visitor-keys: 3.4.3 + espree: 9.6.1 + esquery: 1.5.0 + esutils: 2.0.3 + fast-deep-equal: 3.1.3 + file-entry-cache: 6.0.1 + find-up: 5.0.0 + glob-parent: 6.0.2 + globals: 13.22.0 + graphemer: 1.4.0 + ignore: 5.2.4 + imurmurhash: 0.1.4 + is-glob: 4.0.3 + is-path-inside: 3.0.3 + js-yaml: 4.1.0 + json-stable-stringify-without-jsonify: 1.0.1 + levn: 0.4.1 + lodash.merge: 4.6.2 + minimatch: 3.1.2 + natural-compare: 1.4.0 + optionator: 0.9.3 + strip-ansi: 6.0.1 + text-table: 0.2.0 + transitivePeerDependencies: + - supports-color + dev: true + + /espree@9.6.1: + resolution: {integrity: sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dependencies: + acorn: 8.10.0 + acorn-jsx: 5.3.2(acorn@8.10.0) + eslint-visitor-keys: 3.4.3 + + /esprima@4.0.1: + resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} + engines: {node: '>=4'} + hasBin: true + dev: true + + /esquery@1.5.0: + resolution: {integrity: sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==} + engines: {node: '>=0.10'} + dependencies: + estraverse: 5.3.0 + + /esrecurse@4.3.0: + resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} + engines: {node: '>=4.0'} + dependencies: + estraverse: 5.3.0 + + /estraverse@5.3.0: + resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} + engines: {node: '>=4.0'} + + /estree-walker@1.0.1: + resolution: {integrity: sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==} + dev: true + + /estree-walker@2.0.2: + resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} + dev: true + + /esutils@2.0.3: + resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} + engines: {node: '>=0.10.0'} + + /extendable-error@0.1.7: + resolution: {integrity: sha512-UOiS2in6/Q0FK0R0q6UY9vYpQ21mr/Qn1KOnte7vsACuNJf514WvCCUHSRCPcgjPT2bAhNIJdlE6bVap1GKmeg==} + dev: true + + /external-editor@3.1.0: + resolution: {integrity: sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==} + engines: {node: '>=4'} + dependencies: + chardet: 0.7.0 + iconv-lite: 0.4.24 + tmp: 0.0.33 + dev: true + + /fast-deep-equal@2.0.1: + resolution: {integrity: sha512-bCK/2Z4zLidyB4ReuIsvALH6w31YfAQDmXMqMx6FyfHqvBxtjC0eRumeSu4Bs3XtXwpyIywtSTrVT99BxY1f9w==} + dev: true + + /fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + + /fast-glob@3.3.1: + resolution: {integrity: sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==} + engines: {node: '>=8.6.0'} + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.5 + + /fast-json-stable-stringify@2.1.0: + resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} + + /fast-levenshtein@2.0.6: + resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} + + /fastq@1.15.0: + resolution: {integrity: sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==} + dependencies: + reusify: 1.0.4 + + /file-entry-cache@6.0.1: + resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} + engines: {node: ^10.12.0 || >=12.0.0} + dependencies: + flat-cache: 3.0.4 + + /fill-range@7.0.1: + resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==} + engines: {node: '>=8'} + dependencies: + to-regex-range: 5.0.1 + + /find-replace@3.0.0: + resolution: {integrity: sha512-6Tb2myMioCAgv5kfvP5/PkZZ/ntTpVK39fHY7WkWBgvbeE+VHd/tZuZ4mrC+bxh4cfOZeYKVPaJIZtZXV7GNCQ==} + engines: {node: '>=4.0.0'} + dependencies: + array-back: 3.1.0 + dev: true + + /find-up@4.1.0: + resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} + engines: {node: '>=8'} + dependencies: + locate-path: 5.0.0 + path-exists: 4.0.0 + dev: true + + /find-up@5.0.0: + resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} + engines: {node: '>=10'} + dependencies: + locate-path: 6.0.0 + path-exists: 4.0.0 + + /find-yarn-workspace-root2@1.2.16: + resolution: {integrity: sha512-hr6hb1w8ePMpPVUK39S4RlwJzi+xPLuVuG8XlwXU3KD5Yn3qgBWVfy3AzNlDhWvE1EORCE65/Qm26rFQt3VLVA==} + dependencies: + micromatch: 4.0.5 + pkg-dir: 4.2.0 + dev: true + + /flat-cache@3.0.4: + resolution: {integrity: sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==} + engines: {node: ^10.12.0 || >=12.0.0} + dependencies: + flatted: 3.2.7 + rimraf: 3.0.2 + + /flat@5.0.2: + resolution: {integrity: sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==} + hasBin: true + dev: true + + /flatted@3.2.7: + resolution: {integrity: sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==} + + /follow-redirects@1.15.3: + resolution: {integrity: sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q==} + engines: {node: '>=4.0'} + peerDependencies: + debug: '*' + peerDependenciesMeta: + debug: + optional: true + dev: false + + /for-each@0.3.3: + resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==} + dependencies: + is-callable: 1.2.7 + + /foreground-child@2.0.0: + resolution: {integrity: sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA==} + engines: {node: '>=8.0.0'} + dependencies: + cross-spawn: 7.0.3 + signal-exit: 3.0.7 + dev: true + + /form-data@4.0.0: + resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==} + engines: {node: '>= 6'} + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + mime-types: 2.1.35 + dev: false + + /fs-extra@7.0.1: + resolution: {integrity: sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==} + engines: {node: '>=6 <7 || >=8'} + dependencies: + graceful-fs: 4.2.11 + jsonfile: 4.0.0 + universalify: 0.1.2 + dev: true + + /fs-extra@8.1.0: + resolution: {integrity: sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==} + engines: {node: '>=6 <7 || >=8'} + dependencies: + graceful-fs: 4.2.11 + jsonfile: 4.0.0 + universalify: 0.1.2 + dev: true + + /fs-extra@9.1.0: + resolution: {integrity: sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==} + engines: {node: '>=10'} + dependencies: + at-least-node: 1.0.0 + graceful-fs: 4.2.11 + jsonfile: 6.1.0 + universalify: 2.0.0 + dev: true + + /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] + requiresBuild: true + dev: true + optional: true + + /function-bind@1.1.1: + resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==} + + /function.prototype.name@1.1.6: + resolution: {integrity: sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + define-properties: 1.2.1 + es-abstract: 1.22.2 + functions-have-names: 1.2.3 + + /functions-have-names@1.2.3: + resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} + + /gensync@1.0.0-beta.2: + resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} + engines: {node: '>=6.9.0'} + dev: true + + /get-caller-file@2.0.5: + resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} + engines: {node: 6.* || 8.* || >= 10.*} + dev: true + + /get-func-name@2.0.2: + resolution: {integrity: sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==} + dev: true + + /get-intrinsic@1.2.1: + resolution: {integrity: sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==} + dependencies: + function-bind: 1.1.1 + has: 1.0.3 + has-proto: 1.0.1 + has-symbols: 1.0.3 + + /get-symbol-description@1.0.0: + resolution: {integrity: sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + get-intrinsic: 1.2.1 + + /glob-base@0.3.0: + resolution: {integrity: sha512-ab1S1g1EbO7YzauaJLkgLp7DZVAqj9M/dvKlTt8DkXA2tiOIcSMrlVI2J1RZyB5iJVccEscjGn+kpOG9788MHA==} + engines: {node: '>=0.10.0'} + dependencies: + glob-parent: 2.0.0 + is-glob: 2.0.1 + dev: true + + /glob-parent@2.0.0: + resolution: {integrity: sha512-JDYOvfxio/t42HKdxkAYaCiBN7oYiuxykOxKxdaUW5Qn0zaYN3gRQWolrwdnf0shM9/EP0ebuuTmyoXNr1cC5w==} + dependencies: + is-glob: 2.0.1 + dev: true + + /glob-parent@5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + dependencies: + is-glob: 4.0.3 + + /glob-parent@6.0.2: + resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} + engines: {node: '>=10.13.0'} + dependencies: + is-glob: 4.0.3 + + /glob@7.1.7: + resolution: {integrity: sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==} + 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 + dev: true + + /glob@7.2.0: + resolution: {integrity: sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==} + 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 + dev: true + + /glob@7.2.3: + resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} + 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: + resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} + engines: {node: '>=4'} + dev: true + + /globals@13.20.0: + resolution: {integrity: sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==} + engines: {node: '>=8'} + dependencies: + type-fest: 0.20.2 + + /globals@13.22.0: + resolution: {integrity: sha512-H1Ddc/PbZHTDVJSnj8kWptIRSD6AM3pK+mKytuIVF4uoBV7rshFlhhvA58ceJ5wp3Er58w6zj7bykMpYXt3ETw==} + engines: {node: '>=8'} + dependencies: + type-fest: 0.20.2 + dev: true + + /globalthis@1.0.3: + resolution: {integrity: sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==} + engines: {node: '>= 0.4'} + dependencies: + define-properties: 1.2.1 + + /globby@11.1.0: + resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} + engines: {node: '>=10'} + dependencies: + array-union: 2.1.0 + dir-glob: 3.0.1 + fast-glob: 3.3.1 + ignore: 5.2.4 + merge2: 1.4.1 + slash: 3.0.0 + + /gopd@1.0.1: + resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==} + dependencies: + get-intrinsic: 1.2.1 + + /graceful-fs@4.2.11: + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + dev: true + + /grapheme-splitter@1.0.4: + resolution: {integrity: sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==} + dev: true + + /graphemer@1.4.0: + resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} + + /hard-rejection@2.1.0: + resolution: {integrity: sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==} + engines: {node: '>=6'} + dev: true + + /has-bigints@1.0.2: + resolution: {integrity: sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==} + + /has-flag@3.0.0: + resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} + engines: {node: '>=4'} + dev: true + + /has-flag@4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + + /has-property-descriptors@1.0.0: + resolution: {integrity: sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==} + dependencies: + get-intrinsic: 1.2.1 + + /has-proto@1.0.1: + resolution: {integrity: sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==} + engines: {node: '>= 0.4'} + + /has-symbols@1.0.3: + resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==} + engines: {node: '>= 0.4'} + + /has-tostringtag@1.0.0: + resolution: {integrity: sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==} + engines: {node: '>= 0.4'} + dependencies: + has-symbols: 1.0.3 + + /has@1.0.3: + resolution: {integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==} + engines: {node: '>= 0.4.0'} + dependencies: + function-bind: 1.1.1 + + /he@1.2.0: + resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==} + hasBin: true + dev: true + + /hosted-git-info@2.8.9: + resolution: {integrity: sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==} + dev: true + + /html-escaper@2.0.2: + resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} + dev: true + + /human-id@1.0.2: + resolution: {integrity: sha512-UNopramDEhHJD+VR+ehk8rOslwSfByxPIZyJRfV739NDhN5LF1fa1MqnzKm2lGTQRjNrjK19Q5fhkgIfjlVUKw==} + dev: true + + /husky@8.0.3: + resolution: {integrity: sha512-+dQSyqPh4x1hlO1swXBiNb2HzTDN1I2IGLQx1GrBuiqFJfoMrnZWwVmatvSiO+Iz8fBUnf+lekwNo4c2LlXItg==} + engines: {node: '>=14'} + hasBin: true + dev: true + + /iconv-lite@0.4.24: + resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} + engines: {node: '>=0.10.0'} + dependencies: + safer-buffer: 2.1.2 + dev: true + + /ignore-walk@3.0.4: + resolution: {integrity: sha512-PY6Ii8o1jMRA1z4F2hRkH/xN59ox43DavKvD3oDpfurRlOJyAHpifIwpbdv1n4jt4ov0jSpw3kQ4GhJnpBL6WQ==} + dependencies: + minimatch: 3.1.2 + dev: true + + /ignore@5.2.4: + resolution: {integrity: sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==} + engines: {node: '>= 4'} + + /import-fresh@3.3.0: + resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==} + engines: {node: '>=6'} + dependencies: + parent-module: 1.0.1 + resolve-from: 4.0.0 + + /imurmurhash@0.1.4: + resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} + engines: {node: '>=0.8.19'} + + /indent-string@4.0.0: + resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==} + engines: {node: '>=8'} + dev: true + + /inflight@1.0.6: + resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} + dependencies: + once: 1.4.0 + wrappy: 1.0.2 + + /inherits@2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + + /internal-slot@1.0.5: + resolution: {integrity: sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ==} + engines: {node: '>= 0.4'} + dependencies: + get-intrinsic: 1.2.1 + has: 1.0.3 + side-channel: 1.0.4 + + /is-array-buffer@3.0.2: + resolution: {integrity: sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==} + dependencies: + call-bind: 1.0.2 + get-intrinsic: 1.2.1 + is-typed-array: 1.1.12 + + /is-arrayish@0.2.1: + resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} + dev: true + + /is-bigint@1.0.4: + resolution: {integrity: sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==} + dependencies: + has-bigints: 1.0.2 + + /is-binary-path@2.1.0: + resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} + engines: {node: '>=8'} + dependencies: + binary-extensions: 2.2.0 + dev: true + + /is-boolean-object@1.1.2: + resolution: {integrity: sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + has-tostringtag: 1.0.0 + + /is-callable@1.2.7: + resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} + engines: {node: '>= 0.4'} + + /is-ci@2.0.0: + resolution: {integrity: sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==} + hasBin: true + dependencies: + ci-info: 2.0.0 + dev: true + + /is-ci@3.0.1: + resolution: {integrity: sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ==} + hasBin: true + dependencies: + ci-info: 3.9.0 + dev: true + + /is-core-module@2.13.0: + resolution: {integrity: sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ==} + dependencies: + has: 1.0.3 + + /is-date-object@1.0.5: + resolution: {integrity: sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==} + engines: {node: '>= 0.4'} + dependencies: + has-tostringtag: 1.0.0 + + /is-dotfile@1.0.3: + resolution: {integrity: sha512-9YclgOGtN/f8zx0Pr4FQYMdibBiTaH3sn52vjYip4ZSf6C4/6RfTEZ+MR4GvKhCxdPh21Bg42/WL55f6KSnKpg==} + engines: {node: '>=0.10.0'} + dev: true + + /is-extglob@1.0.0: + resolution: {integrity: sha512-7Q+VbVafe6x2T+Tu6NcOf6sRklazEPmBoB3IWk3WdGZM2iGUwU/Oe3Wtq5lSEkDTTlpp8yx+5t4pzO/i9Ty1ww==} + engines: {node: '>=0.10.0'} + dev: true + + /is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + + /is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + dev: true + + /is-glob@2.0.1: + resolution: {integrity: sha512-a1dBeB19NXsf/E0+FHqkagizel/LQw2DjSQpvQrj3zT+jYPpaUCryPnrQajXKFLCMuf4I6FhRpaGtw4lPrG6Eg==} + engines: {node: '>=0.10.0'} + dependencies: + is-extglob: 1.0.0 + dev: true + + /is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + dependencies: + is-extglob: 2.1.1 + + /is-module@1.0.0: + resolution: {integrity: sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==} + dev: true + + /is-negative-zero@2.0.2: + resolution: {integrity: sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==} + engines: {node: '>= 0.4'} + + /is-number-object@1.0.7: + resolution: {integrity: sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==} + engines: {node: '>= 0.4'} + dependencies: + has-tostringtag: 1.0.0 + + /is-number@7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + + /is-path-inside@3.0.3: + resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==} + engines: {node: '>=8'} + + /is-plain-obj@1.1.0: + resolution: {integrity: sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==} + engines: {node: '>=0.10.0'} + dev: true + + /is-plain-obj@2.1.0: + resolution: {integrity: sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==} + engines: {node: '>=8'} + dev: true + + /is-reference@1.2.1: + resolution: {integrity: sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==} + dependencies: + '@types/estree': 1.0.2 + dev: true + + /is-regex@1.1.4: + resolution: {integrity: sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + has-tostringtag: 1.0.0 + + /is-shared-array-buffer@1.0.2: + resolution: {integrity: sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==} + dependencies: + call-bind: 1.0.2 + + /is-string@1.0.7: + resolution: {integrity: sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==} + engines: {node: '>= 0.4'} + dependencies: + has-tostringtag: 1.0.0 + + /is-subdir@1.2.0: + resolution: {integrity: sha512-2AT6j+gXe/1ueqbW6fLZJiIw3F8iXGJtt0yDrZaBhAZEG1raiTxKWU+IPqMCzQAXOUCKdA4UDMgacKH25XG2Cw==} + engines: {node: '>=4'} + dependencies: + better-path-resolve: 1.0.0 + dev: true + + /is-symbol@1.0.4: + resolution: {integrity: sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==} + engines: {node: '>= 0.4'} + dependencies: + has-symbols: 1.0.3 + + /is-typed-array@1.1.12: + resolution: {integrity: sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg==} + engines: {node: '>= 0.4'} + dependencies: + which-typed-array: 1.1.11 + + /is-unicode-supported@0.1.0: + resolution: {integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==} + engines: {node: '>=10'} + dev: true + + /is-weakref@1.0.2: + resolution: {integrity: sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==} + dependencies: + call-bind: 1.0.2 + + /is-windows@1.0.2: + resolution: {integrity: sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==} + engines: {node: '>=0.10.0'} + dev: true + + /isarray@0.0.1: + resolution: {integrity: sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==} + dev: true + + /isarray@2.0.5: + resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} + + /isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + + /isows@1.0.3(ws@8.13.0): + resolution: {integrity: sha512-2cKei4vlmg2cxEjm3wVSqn8pcoRF/LX/wpifuuNquFO4SQmPwarClT+SUCA2lt+l581tTeZIPIZuIDo2jWN1fg==} + peerDependencies: + ws: '*' + dependencies: + ws: 8.13.0 + dev: false + + /istanbul-lib-coverage@3.2.0: + resolution: {integrity: sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==} + engines: {node: '>=8'} + dev: true + + /istanbul-lib-report@3.0.1: + resolution: {integrity: sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==} + engines: {node: '>=10'} + dependencies: + istanbul-lib-coverage: 3.2.0 + make-dir: 4.0.0 + supports-color: 7.2.0 + dev: true + + /istanbul-reports@3.1.6: + resolution: {integrity: sha512-TLgnMkKg3iTDsQ9PbPTdpfAK2DzjF9mqUG7RMgcQl8oFjad8ob4laGxv5XV5U9MAfx8D6tSJiUyuAwzLicaxlg==} + engines: {node: '>=8'} + dependencies: + html-escaper: 2.0.2 + istanbul-lib-report: 3.0.1 + dev: true + + /jest-worker@26.6.2: + resolution: {integrity: sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==} + engines: {node: '>= 10.13.0'} + dependencies: + '@types/node': 20.8.2 + merge-stream: 2.0.0 + supports-color: 7.2.0 + dev: true + + /jju@1.4.0: + resolution: {integrity: sha512-8wb9Yw966OSxApiCt0K3yNJL8pnNeIv+OEq2YMidz4FKP6nonSRoOXc80iXY4JaN2FC11B9qsNmDsm+ZOfMROA==} + dev: false + + /js-sha3@0.8.0: + resolution: {integrity: sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==} + dev: true + + /js-tokens@4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + dev: true + + /js-yaml@3.14.1: + resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==} + hasBin: true + dependencies: + argparse: 1.0.10 + esprima: 4.0.1 + dev: true + + /js-yaml@4.1.0: + resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} + hasBin: true + dependencies: + argparse: 2.0.1 + + /jsesc@0.5.0: + resolution: {integrity: sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==} + hasBin: true + dev: true + + /jsesc@2.5.2: + resolution: {integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==} + engines: {node: '>=4'} + hasBin: true + dev: true + + /json-parse-even-better-errors@2.3.1: + resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} + dev: true + + /json-schema-traverse@0.4.1: + resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} + + /json-stable-stringify-without-jsonify@1.0.1: + resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} + + /json5@1.0.2: + resolution: {integrity: sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==} + hasBin: true + dependencies: + minimist: 1.2.8 + dev: false + + /json5@2.2.3: + resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} + engines: {node: '>=6'} + hasBin: true + dev: true + + /jsonfile@4.0.0: + resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==} + optionalDependencies: + graceful-fs: 4.2.11 + dev: true + + /jsonfile@6.1.0: + resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==} + dependencies: + universalify: 2.0.0 + optionalDependencies: + graceful-fs: 4.2.11 + dev: true + + /just-extend@4.2.1: + resolution: {integrity: sha512-g3UB796vUFIY90VIv/WX3L2c8CS2MdWUww3CNrYmqza1Fg0DURc2K/O4YrnklBdQarSJ/y8JnJYDGc+1iumQjg==} + dev: true + + /kind-of@6.0.3: + resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==} + engines: {node: '>=0.10.0'} + dev: true + + /kleur@4.1.5: + resolution: {integrity: sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==} + engines: {node: '>=6'} + dev: true + + /levn@0.4.1: + resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} + engines: {node: '>= 0.8.0'} + dependencies: + prelude-ls: 1.2.1 + type-check: 0.4.0 + + /lines-and-columns@1.2.4: + resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} + dev: true + + /load-yaml-file@0.2.0: + resolution: {integrity: sha512-OfCBkGEw4nN6JLtgRidPX6QxjBQGQf72q3si2uvqyFEMbycSFFHwAZeXx6cJgFM9wmLrf9zBwCP3Ivqa+LLZPw==} + engines: {node: '>=6'} + dependencies: + graceful-fs: 4.2.11 + js-yaml: 3.14.1 + pify: 4.0.1 + strip-bom: 3.0.0 + dev: true + + /locate-path@5.0.0: + resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} + engines: {node: '>=8'} + dependencies: + p-locate: 4.1.0 + dev: true + + /locate-path@6.0.0: + resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} + engines: {node: '>=10'} + dependencies: + p-locate: 5.0.0 + + /lodash.camelcase@4.3.0: + resolution: {integrity: sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==} + dev: true + + /lodash.debounce@4.0.8: + resolution: {integrity: sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==} + dev: true + + /lodash.get@4.4.2: + resolution: {integrity: sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==} + dev: true + + /lodash.merge@4.6.2: + resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} + + /lodash.startcase@4.4.0: + resolution: {integrity: sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==} + dev: true + + /lodash@4.17.21: + resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} + dev: true + + /log-symbols@4.1.0: + resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==} + engines: {node: '>=10'} + dependencies: + chalk: 4.1.2 + is-unicode-supported: 0.1.0 + dev: true + + /loupe@2.3.6: + resolution: {integrity: sha512-RaPMZKiMy8/JruncMU5Bt6na1eftNoo++R4Y+N2FrxkDVTrGvcyzFTsaGif4QTeKESheMGegbhw6iUAq+5A8zA==} + dependencies: + get-func-name: 2.0.2 + dev: true + + /lru-cache@4.1.5: + resolution: {integrity: sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==} + dependencies: + pseudomap: 1.0.2 + yallist: 2.1.2 + dev: true + + /lru-cache@5.1.1: + resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} + dependencies: + yallist: 3.1.1 + dev: true + + /lru-cache@6.0.0: + resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} + engines: {node: '>=10'} + dependencies: + yallist: 4.0.0 + + /magic-string@0.25.9: + resolution: {integrity: sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==} + dependencies: + sourcemap-codec: 1.4.8 + dev: true + + /magic-string@0.30.4: + resolution: {integrity: sha512-Q/TKtsC5BPm0kGqgBIF9oXAs/xEf2vRKiIB4wCRQTJOQIByZ1d+NnUOotvJOvNpi5RNIgVOMC3pOuaP1ZTDlVg==} + engines: {node: '>=12'} + dependencies: + '@jridgewell/sourcemap-codec': 1.4.15 + dev: true + + /make-dir@4.0.0: + resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==} + engines: {node: '>=10'} + dependencies: + semver: 7.5.4 + dev: true + + /make-error@1.3.6: + resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} + dev: true + + /map-obj@1.0.1: + resolution: {integrity: sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==} + engines: {node: '>=0.10.0'} + dev: true + + /map-obj@4.3.0: + resolution: {integrity: sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==} + engines: {node: '>=8'} + dev: true + + /meow@6.1.1: + resolution: {integrity: sha512-3YffViIt2QWgTy6Pale5QpopX/IvU3LPL03jOTqp6pGj3VjesdO/U8CuHMKpnQr4shCNCM5fd5XFFvIIl6JBHg==} + engines: {node: '>=8'} + dependencies: + '@types/minimist': 1.2.3 + camelcase-keys: 6.2.2 + decamelize-keys: 1.1.1 + hard-rejection: 2.1.0 + minimist-options: 4.1.0 + normalize-package-data: 2.5.0 + read-pkg-up: 7.0.1 + redent: 3.0.0 + trim-newlines: 3.0.1 + type-fest: 0.13.1 + yargs-parser: 18.1.3 + dev: true + + /meow@7.1.1: + resolution: {integrity: sha512-GWHvA5QOcS412WCo8vwKDlTelGLsCGBVevQB5Kva961rmNfun0PCbv5+xta2kUMFJyR8/oWnn7ddeKdosbAPbA==} + engines: {node: '>=10'} + dependencies: + '@types/minimist': 1.2.3 + camelcase-keys: 6.2.2 + decamelize-keys: 1.1.1 + hard-rejection: 2.1.0 + minimist-options: 4.1.0 + normalize-package-data: 2.5.0 + read-pkg-up: 7.0.1 + redent: 3.0.0 + trim-newlines: 3.0.1 + type-fest: 0.13.1 + yargs-parser: 18.1.3 + dev: true + + /merge-stream@2.0.0: + resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} + dev: true + + /merge2@1.4.1: + resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} + engines: {node: '>= 8'} + + /micromatch@4.0.5: + resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==} + engines: {node: '>=8.6'} + dependencies: + braces: 3.0.2 + picomatch: 2.3.1 + + /mime-db@1.52.0: + resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} + engines: {node: '>= 0.6'} + dev: false + + /mime-types@2.1.35: + resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} + engines: {node: '>= 0.6'} + dependencies: + mime-db: 1.52.0 + dev: false + + /min-indent@1.0.1: + resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==} + engines: {node: '>=4'} + dev: true + + /minimatch@3.1.2: + resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + dependencies: + brace-expansion: 1.1.11 + + /minimatch@5.0.1: + resolution: {integrity: sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==} + engines: {node: '>=10'} + dependencies: + brace-expansion: 2.0.1 + dev: true + + /minimist-options@4.1.0: + resolution: {integrity: sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==} + engines: {node: '>= 6'} + dependencies: + arrify: 1.0.1 + is-plain-obj: 1.1.0 + kind-of: 6.0.3 + dev: true + + /minimist@1.2.8: + resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + dev: false + + /mixme@0.5.9: + resolution: {integrity: sha512-VC5fg6ySUscaWUpI4gxCBTQMH2RdUpNrk+MsbpCYtIvf9SBJdiUey4qE7BXviJsJR4nDQxCZ+3yaYNW3guz/Pw==} + engines: {node: '>= 8.0.0'} + dev: true + + /mkdirp@1.0.4: + resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==} + engines: {node: '>=10'} + hasBin: true + dev: true + + /mocha@10.2.0: + resolution: {integrity: sha512-IDY7fl/BecMwFHzoqF2sg/SHHANeBoMMXFlS9r0OXKDssYE1M5O43wUY/9BVPeIvfH2zmEbBfseqN9gBQZzXkg==} + engines: {node: '>= 14.0.0'} + hasBin: true + dependencies: + ansi-colors: 4.1.1 + browser-stdout: 1.3.1 + chokidar: 3.5.3 + debug: 4.3.4(supports-color@8.1.1) + diff: 5.0.0 + escape-string-regexp: 4.0.0 + find-up: 5.0.0 + glob: 7.2.0 + he: 1.2.0 + js-yaml: 4.1.0 + log-symbols: 4.1.0 + minimatch: 5.0.1 + ms: 2.1.3 + nanoid: 3.3.3 + serialize-javascript: 6.0.0 + strip-json-comments: 3.1.1 + supports-color: 8.1.1 + workerpool: 6.2.1 + yargs: 16.2.0 + yargs-parser: 20.2.4 + yargs-unparser: 2.0.0 + dev: true + + /ms@2.1.2: + resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} + + /ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + dev: true + + /nanoid@3.3.3: + resolution: {integrity: sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + dev: true + + /natural-compare@1.4.0: + resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + + /nise@5.1.4: + resolution: {integrity: sha512-8+Ib8rRJ4L0o3kfmyVCL7gzrohyDe0cMFTBa2d364yIrEGMEoetznKJx899YxjybU6bL9SQkYPSBBs1gyYs8Xg==} + dependencies: + '@sinonjs/commons': 2.0.0 + '@sinonjs/fake-timers': 10.3.0 + '@sinonjs/text-encoding': 0.7.2 + just-extend: 4.2.1 + path-to-regexp: 1.8.0 + dev: true + + /node-releases@2.0.13: + resolution: {integrity: sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==} + dev: true + + /normalize-package-data@2.5.0: + resolution: {integrity: sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==} + dependencies: + hosted-git-info: 2.8.9 + resolve: 1.22.6 + semver: 5.7.2 + validate-npm-package-license: 3.0.4 + dev: true + + /normalize-path@3.0.0: + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} + engines: {node: '>=0.10.0'} + dev: true + + /npm-bundled@1.1.2: + resolution: {integrity: sha512-x5DHup0SuyQcmL3s7Rx/YQ8sbw/Hzg0rj48eN0dV7hf5cmQq5PXIeioroH3raV1QC1yh3uTYuMThvEQF3iKgGQ==} + dependencies: + npm-normalize-package-bin: 1.0.1 + dev: true + + /npm-normalize-package-bin@1.0.1: + resolution: {integrity: sha512-EPfafl6JL5/rU+ot6P3gRSCpPDW5VmIzX959Ob1+ySFUuuYHWHekXpwdUZcKP5C+DS4GEtdJluwBjnsNDl+fSA==} + dev: true + + /npm-packlist@2.2.2: + resolution: {integrity: sha512-Jt01acDvJRhJGthnUJVF/w6gumWOZxO7IkpY/lsX9//zqQgnF7OJaxgQXcerd4uQOLu7W5bkb4mChL9mdfm+Zg==} + engines: {node: '>=10'} + hasBin: true + dependencies: + glob: 7.2.3 + ignore-walk: 3.0.4 + npm-bundled: 1.1.2 + npm-normalize-package-bin: 1.0.1 + dev: true + + /object-inspect@1.12.3: + resolution: {integrity: sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==} + + /object-keys@1.1.1: + resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} + engines: {node: '>= 0.4'} + + /object.assign@4.1.4: + resolution: {integrity: sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + define-properties: 1.2.1 + has-symbols: 1.0.3 + object-keys: 1.1.1 + + /object.fromentries@2.0.7: + resolution: {integrity: sha512-UPbPHML6sL8PI/mOqPwsH4G6iyXcCGzLin8KvEPenOZN5lpCNBZZQ+V62vdjB1mQHrmqGQt5/OJzemUA+KJmEA==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + define-properties: 1.2.1 + es-abstract: 1.22.2 + dev: false + + /object.groupby@1.0.1: + resolution: {integrity: sha512-HqaQtqLnp/8Bn4GL16cj+CUYbnpe1bh0TtEaWvybszDG4tgxCJuRpV8VGuvNaI1fAnI4lUJzDG55MXcOH4JZcQ==} + dependencies: + call-bind: 1.0.2 + define-properties: 1.2.1 + es-abstract: 1.22.2 + get-intrinsic: 1.2.1 + dev: false + + /object.values@1.1.7: + resolution: {integrity: sha512-aU6xnDFYT3x17e/f0IiiwlGPTy2jzMySGfUB4fq6z7CV8l85CWHDk5ErhyhpfDHhrOMwGFhSQkhMGHaIotA6Ng==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + define-properties: 1.2.1 + es-abstract: 1.22.2 + dev: false + + /once@1.4.0: + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + dependencies: + wrappy: 1.0.2 + + /optionator@0.9.3: + resolution: {integrity: sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==} + engines: {node: '>= 0.8.0'} + dependencies: + '@aashutoshrathi/word-wrap': 1.2.6 + deep-is: 0.1.4 + fast-levenshtein: 2.0.6 + levn: 0.4.1 + prelude-ls: 1.2.1 + type-check: 0.4.0 + + /os-tmpdir@1.0.2: + resolution: {integrity: sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==} + engines: {node: '>=0.10.0'} + dev: true + + /outdent@0.5.0: + resolution: {integrity: sha512-/jHxFIzoMXdqPzTaCpFzAAWhpkSjZPF4Vsn6jAfNpmbH/ymsmd7Qc6VE9BGn0L6YMj6uwpQLxCECpus4ukKS9Q==} + dev: true + + /p-filter@2.1.0: + resolution: {integrity: sha512-ZBxxZ5sL2HghephhpGAQdoskxplTwr7ICaehZwLIlfL6acuVgZPm8yBNuRAFBGEqtD/hmUeq9eqLg2ys9Xr/yw==} + engines: {node: '>=8'} + dependencies: + p-map: 2.1.0 + dev: true + + /p-limit@2.3.0: + resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} + engines: {node: '>=6'} + dependencies: + p-try: 2.2.0 + dev: true + + /p-limit@3.1.0: + resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} + engines: {node: '>=10'} + dependencies: + yocto-queue: 0.1.0 + + /p-locate@4.1.0: + resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} + engines: {node: '>=8'} + dependencies: + p-limit: 2.3.0 + dev: true + + /p-locate@5.0.0: + resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} + engines: {node: '>=10'} + dependencies: + p-limit: 3.1.0 + + /p-map@2.1.0: + resolution: {integrity: sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==} + engines: {node: '>=6'} + dev: true + + /p-try@2.2.0: + resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} + engines: {node: '>=6'} + dev: true + + /parent-module@1.0.1: + resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} + engines: {node: '>=6'} + dependencies: + callsites: 3.1.0 + + /parse-glob@3.0.4: + resolution: {integrity: sha512-FC5TeK0AwXzq3tUBFtH74naWkPQCEWs4K+xMxWZBlKDWu0bVHXGZa+KKqxKidd7xwhdZ19ZNuF2uO1M/r196HA==} + engines: {node: '>=0.10.0'} + dependencies: + glob-base: 0.3.0 + is-dotfile: 1.0.3 + is-extglob: 1.0.0 + is-glob: 2.0.1 + dev: true + + /parse-json@5.2.0: + resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} + engines: {node: '>=8'} + dependencies: + '@babel/code-frame': 7.22.13 + error-ex: 1.3.2 + json-parse-even-better-errors: 2.3.1 + lines-and-columns: 1.2.4 + dev: true + + /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==} + + /path-to-regexp@1.8.0: + resolution: {integrity: sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==} + dependencies: + isarray: 0.0.1 + dev: true + + /path-type@4.0.0: + resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} + engines: {node: '>=8'} + + /pathval@1.1.1: + resolution: {integrity: sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==} + dev: true + + /picocolors@1.0.0: + resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} + dev: true + + /picomatch@2.3.1: + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + engines: {node: '>=8.6'} + + /pify@4.0.1: + resolution: {integrity: sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==} + engines: {node: '>=6'} + dev: true + + /pirates@4.0.6: + resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==} + engines: {node: '>= 6'} + dev: true + + /pkg-dir@4.2.0: + resolution: {integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==} + engines: {node: '>=8'} + dependencies: + find-up: 4.1.0 + dev: true + + /preferred-pm@3.1.2: + resolution: {integrity: sha512-nk7dKrcW8hfCZ4H6klWcdRknBOXWzNQByJ0oJyX97BOupsYD+FzLS4hflgEu/uPUEHZCuRfMxzCBsuWd7OzT8Q==} + engines: {node: '>=10'} + dependencies: + find-up: 5.0.0 + find-yarn-workspace-root2: 1.2.16 + path-exists: 4.0.0 + which-pm: 2.0.0 + dev: true + + /prelude-ls@1.2.1: + resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} + engines: {node: '>= 0.8.0'} + + /prettier@2.8.8: + resolution: {integrity: sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==} + engines: {node: '>=10.13.0'} + hasBin: true + dev: true + + /prettier@3.0.3: + resolution: {integrity: sha512-L/4pUDMxcNa8R/EthV08Zt42WBO4h1rarVtK0K+QJG0X187OLo7l699jWw0GKuwzkPQ//jMFA/8Xm6Fh3J/DAg==} + engines: {node: '>=14'} + dev: true + + /proxy-from-env@1.1.0: + resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} + dev: false + + /pseudomap@1.0.2: + resolution: {integrity: sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==} + dev: true + + /punycode@2.3.0: + resolution: {integrity: sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==} + engines: {node: '>=6'} + + /queue-microtask@1.2.3: + resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + + /quick-lru@4.0.1: + resolution: {integrity: sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==} + engines: {node: '>=8'} + dev: true + + /quick-lru@5.1.1: + resolution: {integrity: sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==} + engines: {node: '>=10'} + dev: true + + /randombytes@2.1.0: + resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==} + dependencies: + safe-buffer: 5.2.1 + dev: true + + /read-pkg-up@7.0.1: + resolution: {integrity: sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==} + engines: {node: '>=8'} + dependencies: + find-up: 4.1.0 + read-pkg: 5.2.0 + type-fest: 0.8.1 + dev: true + + /read-pkg@5.2.0: + resolution: {integrity: sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==} + engines: {node: '>=8'} + dependencies: + '@types/normalize-package-data': 2.4.2 + normalize-package-data: 2.5.0 + parse-json: 5.2.0 + type-fest: 0.6.0 + dev: true + + /read-yaml-file@1.1.0: + resolution: {integrity: sha512-VIMnQi/Z4HT2Fxuwg5KrY174U1VdUIASQVWXXyqtNRtxSr9IYkn1rsI6Tb6HsrHCmB7gVpNwX6JxPTHcH6IoTA==} + engines: {node: '>=6'} + dependencies: + graceful-fs: 4.2.11 + js-yaml: 3.14.1 + pify: 4.0.1 + strip-bom: 3.0.0 + dev: true + + /readdirp@3.6.0: + resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} + engines: {node: '>=8.10.0'} + dependencies: + picomatch: 2.3.1 + dev: true + + /redent@3.0.0: + resolution: {integrity: sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==} + engines: {node: '>=8'} + dependencies: + indent-string: 4.0.0 + strip-indent: 3.0.0 + dev: true + + /reduce-flatten@2.0.0: + resolution: {integrity: sha512-EJ4UNY/U1t2P/2k6oqotuX2Cc3T6nxJwsM0N0asT7dhrtH1ltUxDn4NalSYmPE2rCkVpcf/X6R0wDwcFpzhd4w==} + engines: {node: '>=6'} + dev: true + + /regenerate-unicode-properties@10.1.1: + resolution: {integrity: sha512-X007RyZLsCJVVrjgEFVpLUTZwyOZk3oiL75ZcuYjlIWd6rNJtOjkBwQc5AsRrpbKVkxN6sklw/k/9m2jJYOf8Q==} + engines: {node: '>=4'} + dependencies: + regenerate: 1.4.2 + dev: true + + /regenerate@1.4.2: + resolution: {integrity: sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==} + dev: true + + /regenerator-runtime@0.14.0: + resolution: {integrity: sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==} + dev: true + + /regenerator-transform@0.15.2: + resolution: {integrity: sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg==} + dependencies: + '@babel/runtime': 7.23.1 + dev: true + + /regexp.prototype.flags@1.5.1: + resolution: {integrity: sha512-sy6TXMN+hnP/wMy+ISxg3krXx7BAtWVO4UouuCN/ziM9UEne0euamVNafDfvC83bRNr95y0V5iijeDQFUNpvrg==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + define-properties: 1.2.1 + set-function-name: 2.0.1 + + /regexpu-core@5.3.2: + resolution: {integrity: sha512-RAM5FlZz+Lhmo7db9L298p2vHP5ZywrVXmVXpmAD9GuL5MPH6t9ROw1iA/wfHkQ76Qe7AaPF0nGuim96/IrQMQ==} + engines: {node: '>=4'} + dependencies: + '@babel/regjsgen': 0.8.0 + regenerate: 1.4.2 + regenerate-unicode-properties: 10.1.1 + regjsparser: 0.9.1 + unicode-match-property-ecmascript: 2.0.0 + unicode-match-property-value-ecmascript: 2.1.0 + dev: true + + /regjsparser@0.9.1: + resolution: {integrity: sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==} + hasBin: true + dependencies: + jsesc: 0.5.0 + dev: true + + /require-directory@2.1.1: + resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} + engines: {node: '>=0.10.0'} + dev: true + + /require-main-filename@2.0.0: + resolution: {integrity: sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==} + dev: true + + /resolve-from@4.0.0: + resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} + engines: {node: '>=4'} + + /resolve-from@5.0.0: + resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} + engines: {node: '>=8'} + dev: true + + /resolve@1.19.0: + resolution: {integrity: sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg==} + dependencies: + is-core-module: 2.13.0 + path-parse: 1.0.7 + dev: false + + /resolve@1.22.6: + resolution: {integrity: sha512-njhxM7mV12JfufShqGy3Rz8j11RPdLy4xi15UurGJeoHLfJpVXKdh3ueuOqbYUcDZnffr6X739JBo5LzyahEsw==} + hasBin: true + dependencies: + is-core-module: 2.13.0 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + + /reusify@1.0.4: + resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} + engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + + /rimraf@3.0.2: + resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} + hasBin: true + dependencies: + glob: 7.2.3 + + /rollup@2.79.1: + resolution: {integrity: sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw==} + engines: {node: '>=10.0.0'} + hasBin: true + optionalDependencies: + fsevents: 2.3.3 + dev: true + + /run-parallel@1.2.0: + resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + dependencies: + queue-microtask: 1.2.3 + + /safe-array-concat@1.0.1: + resolution: {integrity: sha512-6XbUAseYE2KtOuGueyeobCySj9L4+66Tn6KQMOPQJrAJEowYKW/YR/MGJZl7FdydUdaFu4LYyDZjxf4/Nmo23Q==} + engines: {node: '>=0.4'} + dependencies: + call-bind: 1.0.2 + get-intrinsic: 1.2.1 + has-symbols: 1.0.3 + isarray: 2.0.5 + + /safe-buffer@5.2.1: + resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + dev: true + + /safe-regex-test@1.0.0: + resolution: {integrity: sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==} + dependencies: + call-bind: 1.0.2 + get-intrinsic: 1.2.1 + is-regex: 1.1.4 + + /safer-buffer@2.1.2: + resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + dev: true + + /semver@5.7.2: + resolution: {integrity: sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==} + hasBin: true + dev: true + + /semver@6.3.1: + resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} + hasBin: true + + /semver@7.5.4: + resolution: {integrity: sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==} + engines: {node: '>=10'} + hasBin: true + dependencies: + lru-cache: 6.0.0 + + /serialize-javascript@6.0.0: + resolution: {integrity: sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==} + dependencies: + randombytes: 2.1.0 + dev: true + + /set-blocking@2.0.0: + resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==} + dev: true + + /set-function-name@2.0.1: + resolution: {integrity: sha512-tMNCiqYVkXIZgc2Hnoy2IvC/f8ezc5koaRFkCjrpWzGpCd3qbZXPzVy9MAZzK1ch/X0jvSkojys3oqJN0qCmdA==} + engines: {node: '>= 0.4'} + dependencies: + define-data-property: 1.1.0 + functions-have-names: 1.2.3 + has-property-descriptors: 1.0.0 + + /shebang-command@1.2.0: + resolution: {integrity: sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==} + engines: {node: '>=0.10.0'} + dependencies: + shebang-regex: 1.0.0 + dev: true + + /shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + dependencies: + shebang-regex: 3.0.0 + + /shebang-regex@1.0.0: + resolution: {integrity: sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==} + engines: {node: '>=0.10.0'} + dev: true + + /shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + + /side-channel@1.0.4: + resolution: {integrity: sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==} + dependencies: + call-bind: 1.0.2 + get-intrinsic: 1.2.1 + object-inspect: 1.12.3 + + /signal-exit@3.0.7: + resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} + dev: true + + /sinon@16.0.0: + resolution: {integrity: sha512-B8AaZZm9CT5pqe4l4uWJztfD/mOTa7dL8Qo0W4+s+t74xECOgSZDDQCBjNgIK3+n4kyxQrSTv2V5ul8K25qkiQ==} + dependencies: + '@sinonjs/commons': 3.0.0 + '@sinonjs/fake-timers': 10.3.0 + '@sinonjs/samsam': 8.0.0 + diff: 5.1.0 + nise: 5.1.4 + supports-color: 7.2.0 + dev: true + + /slash@3.0.0: + resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} + engines: {node: '>=8'} + + /smartwrap@2.0.2: + resolution: {integrity: sha512-vCsKNQxb7PnCNd2wY1WClWifAc2lwqsG8OaswpJkVJsvMGcnEntdTCDajZCkk93Ay1U3t/9puJmb525Rg5MZBA==} + engines: {node: '>=6'} + hasBin: true + dependencies: + array.prototype.flat: 1.3.2 + breakword: 1.0.6 + grapheme-splitter: 1.0.4 + strip-ansi: 6.0.1 + wcwidth: 1.0.1 + yargs: 15.4.1 + dev: true + + /source-map-support@0.5.21: + resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} + dependencies: + buffer-from: 1.1.2 + source-map: 0.6.1 + dev: true + + /source-map@0.6.1: + resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} + engines: {node: '>=0.10.0'} + dev: true + + /sourcemap-codec@1.4.8: + resolution: {integrity: sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==} + deprecated: Please use @jridgewell/sourcemap-codec instead + dev: true + + /spawndamnit@2.0.0: + resolution: {integrity: sha512-j4JKEcncSjFlqIwU5L/rp2N5SIPsdxaRsIv678+TZxZ0SRDJTm8JrxJMjE/XuiEZNEir3S8l0Fa3Ke339WI4qA==} + dependencies: + cross-spawn: 5.1.0 + signal-exit: 3.0.7 + dev: true + + /spdx-correct@3.2.0: + resolution: {integrity: sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==} + dependencies: + spdx-expression-parse: 3.0.1 + spdx-license-ids: 3.0.15 + dev: true + + /spdx-exceptions@2.3.0: + resolution: {integrity: sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==} + dev: true + + /spdx-expression-parse@3.0.1: + resolution: {integrity: sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==} + dependencies: + spdx-exceptions: 2.3.0 + spdx-license-ids: 3.0.15 + dev: true + + /spdx-license-ids@3.0.15: + resolution: {integrity: sha512-lpT8hSQp9jAKp9mhtBU4Xjon8LPGBvLIuBiSVhMEtmLecTh2mO0tlqrAMp47tBXzMr13NJMQ2lf7RpQGLJ3HsQ==} + dev: true + + /sprintf-js@1.0.3: + resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} + dev: true + + /stream-transform@2.1.3: + resolution: {integrity: sha512-9GHUiM5hMiCi6Y03jD2ARC1ettBXkQBoQAe7nJsPknnI0ow10aXjTnew8QtYQmLjzn974BnmWEAJgCY6ZP1DeQ==} + dependencies: + mixme: 0.5.9 + dev: true + + /string-format@2.0.0: + resolution: {integrity: sha512-bbEs3scLeYNXLecRRuk6uJxdXUSj6le/8rNPHChIJTn2V79aXVTR1EH2OH5zLKKoz0V02fOUKZZcw01pLUShZA==} + dev: true + + /string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + dev: true + + /string.prototype.trim@1.2.8: + resolution: {integrity: sha512-lfjY4HcixfQXOfaqCvcBuOIapyaroTXhbkfJN3gcB1OtyupngWK4sEET9Knd0cXd28kTUqu/kHoV4HKSJdnjiQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + define-properties: 1.2.1 + es-abstract: 1.22.2 + + /string.prototype.trimend@1.0.7: + resolution: {integrity: sha512-Ni79DqeB72ZFq1uH/L6zJ+DKZTkOtPIHovb3YZHQViE+HDouuU4mBrLOLDn5Dde3RF8qw5qVETEjhu9locMLvA==} + dependencies: + call-bind: 1.0.2 + define-properties: 1.2.1 + es-abstract: 1.22.2 + + /string.prototype.trimstart@1.0.7: + resolution: {integrity: sha512-NGhtDFu3jCEm7B4Fy0DpLewdJQOZcQ0rGbwQ/+stjnrp2i+rlKeCvos9hOIeCmqwratM47OBxY7uFZzjxHXmrg==} + dependencies: + call-bind: 1.0.2 + define-properties: 1.2.1 + es-abstract: 1.22.2 + + /strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + dependencies: + ansi-regex: 5.0.1 + + /strip-bom@3.0.0: + resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} + engines: {node: '>=4'} + + /strip-indent@3.0.0: + resolution: {integrity: sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==} + engines: {node: '>=8'} + dependencies: + min-indent: 1.0.1 + dev: true + + /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'} + dependencies: + has-flag: 3.0.0 + dev: true + + /supports-color@7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} + dependencies: + has-flag: 4.0.0 + + /supports-color@8.1.1: + resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==} + engines: {node: '>=10'} + dependencies: + has-flag: 4.0.0 + + /supports-preserve-symlinks-flag@1.0.0: + resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} + engines: {node: '>= 0.4'} + + /table-layout@1.0.2: + resolution: {integrity: sha512-qd/R7n5rQTRFi+Zf2sk5XVVd9UQl6ZkduPFC3S7WEGJAmetDTjY3qPN50eSKzwuzEyQKy5TN2TiZdkIjos2L6A==} + engines: {node: '>=8.0.0'} + dependencies: + array-back: 4.0.2 + deep-extend: 0.6.0 + typical: 5.2.0 + wordwrapjs: 4.0.1 + dev: true + + /term-size@2.2.1: + resolution: {integrity: sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==} + engines: {node: '>=8'} + dev: true + + /terser@5.21.0: + resolution: {integrity: sha512-WtnFKrxu9kaoXuiZFSGrcAvvBqAdmKx0SFNmVNYdJamMu9yyN3I/QF0FbH4QcqJQ+y1CJnzxGIKH0cSj+FGYRw==} + engines: {node: '>=10'} + hasBin: true + dependencies: + '@jridgewell/source-map': 0.3.5 + acorn: 8.10.0 + commander: 2.20.3 + source-map-support: 0.5.21 + dev: true + + /test-exclude@6.0.0: + resolution: {integrity: sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==} + engines: {node: '>=8'} + dependencies: + '@istanbuljs/schema': 0.1.3 + glob: 7.2.3 + minimatch: 3.1.2 + dev: true + + /text-table@0.2.0: + resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} + + /tmp@0.0.33: + resolution: {integrity: sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==} + engines: {node: '>=0.6.0'} + dependencies: + os-tmpdir: 1.0.2 + dev: true + + /to-fast-properties@2.0.0: + resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} + engines: {node: '>=4'} + dev: true + + /to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + dependencies: + is-number: 7.0.0 + + /trim-newlines@3.0.1: + resolution: {integrity: sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==} + engines: {node: '>=8'} + dev: true + + /ts-api-utils@1.0.2(typescript@5.2.2): + resolution: {integrity: sha512-Cbu4nIqnEdd+THNEsBdkolnOXhg0I8XteoHaEKgvsxpsbWda4IsUut2c187HxywQCvveojow0Dgw/amxtSKVkQ==} + engines: {node: '>=16.13.0'} + peerDependencies: + typescript: '>=4.2.0' + dependencies: + typescript: 5.2.2 + dev: false + + /ts-command-line-args@2.5.1: + resolution: {integrity: sha512-H69ZwTw3rFHb5WYpQya40YAX2/w7Ut75uUECbgBIsLmM+BNuYnxsltfyyLMxy6sEeKxgijLTnQtLd0nKd6+IYw==} + hasBin: true + dependencies: + chalk: 4.1.2 + command-line-args: 5.2.1 + command-line-usage: 6.1.3 + string-format: 2.0.0 + dev: true + + /ts-essentials@7.0.3(typescript@5.2.2): + resolution: {integrity: sha512-8+gr5+lqO3G84KdiTSMRLtuyJ+nTBVRKuCrK4lidMPdVeEp0uqC875uE5NMcaA7YYMN7XsNiFQuMvasF8HT/xQ==} + peerDependencies: + typescript: '>=3.7.0' + dependencies: + typescript: 5.2.2 + dev: true + + /ts-node@10.9.1(@types/node@20.8.2)(typescript@5.2.2): + resolution: {integrity: sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==} + 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 + dependencies: + '@cspotcode/source-map-support': 0.8.1 + '@tsconfig/node10': 1.0.9 + '@tsconfig/node12': 1.0.11 + '@tsconfig/node14': 1.0.3 + '@tsconfig/node16': 1.0.4 + '@types/node': 20.8.2 + acorn: 8.10.0 + acorn-walk: 8.2.0 + arg: 4.1.3 + create-require: 1.1.1 + diff: 4.0.2 + make-error: 1.3.6 + typescript: 5.2.2 + v8-compile-cache-lib: 3.0.1 + yn: 3.1.1 + dev: true + + /tsconfig-paths@3.14.2: + resolution: {integrity: sha512-o/9iXgCYc5L/JxCHPe3Hvh8Q/2xm5Z+p18PESBU6Ff33695QnCHBEjcytY2q19ua7Mbl/DavtBOLq+oG0RCL+g==} + dependencies: + '@types/json5': 0.0.29 + json5: 1.0.2 + minimist: 1.2.8 + strip-bom: 3.0.0 + dev: false + + /tty-table@4.2.2: + resolution: {integrity: sha512-2gvCArMZLxgvpZ2NvQKdnYWIFLe7I/z5JClMuhrDXunmKgSZcQKcZRjN9XjAFiToMz2pUo1dEIXyrm0AwgV5Tw==} + engines: {node: '>=8.0.0'} + hasBin: true + dependencies: + chalk: 4.1.2 + csv: 5.5.3 + kleur: 4.1.5 + smartwrap: 2.0.2 + strip-ansi: 6.0.1 + wcwidth: 1.0.1 + yargs: 17.7.2 + dev: true + + /turbo-darwin-64@1.10.13: + resolution: {integrity: sha512-vmngGfa2dlYvX7UFVncsNDMuT4X2KPyPJ2Jj+xvf5nvQnZR/3IeDEGleGVuMi/hRzdinoxwXqgk9flEmAYp0Xw==} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /turbo-darwin-arm64@1.10.13: + resolution: {integrity: sha512-eMoJC+k7gIS4i2qL6rKmrIQGP6Wr9nN4odzzgHFngLTMimok2cGLK3qbJs5O5F/XAtEeRAmuxeRnzQwTl/iuAw==} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /turbo-linux-64@1.10.13: + resolution: {integrity: sha512-0CyYmnKTs6kcx7+JRH3nPEqCnzWduM0hj8GP/aodhaIkLNSAGAa+RiYZz6C7IXN+xUVh5rrWTnU2f1SkIy7Gdg==} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /turbo-linux-arm64@1.10.13: + resolution: {integrity: sha512-0iBKviSGQQlh2OjZgBsGjkPXoxvRIxrrLLbLObwJo3sOjIH0loGmVIimGS5E323soMfi/o+sidjk2wU1kFfD7Q==} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /turbo-windows-64@1.10.13: + resolution: {integrity: sha512-S5XySRfW2AmnTeY1IT+Jdr6Goq7mxWganVFfrmqU+qqq3Om/nr0GkcUX+KTIo9mPrN0D3p5QViBRzulwB5iuUQ==} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /turbo-windows-arm64@1.10.13: + resolution: {integrity: sha512-nKol6+CyiExJIuoIc3exUQPIBjP9nIq5SkMJgJuxsot2hkgGrafAg/izVDRDrRduQcXj2s8LdtxJHvvnbI8hEQ==} + cpu: [arm64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /turbo@1.10.13: + resolution: {integrity: sha512-vOF5IPytgQPIsgGtT0n2uGZizR2N3kKuPIn4b5p5DdeLoI0BV7uNiydT7eSzdkPRpdXNnO8UwS658VaI4+YSzQ==} + hasBin: true + optionalDependencies: + turbo-darwin-64: 1.10.13 + turbo-darwin-arm64: 1.10.13 + turbo-linux-64: 1.10.13 + turbo-linux-arm64: 1.10.13 + turbo-windows-64: 1.10.13 + turbo-windows-arm64: 1.10.13 + dev: true + + /type-check@0.4.0: + resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} + engines: {node: '>= 0.8.0'} + dependencies: + prelude-ls: 1.2.1 + + /type-detect@4.0.8: + resolution: {integrity: sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==} + engines: {node: '>=4'} + dev: true + + /type-fest@0.13.1: + resolution: {integrity: sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==} + engines: {node: '>=10'} + dev: true + + /type-fest@0.20.2: + resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==} + engines: {node: '>=10'} + + /type-fest@0.6.0: + resolution: {integrity: sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==} + engines: {node: '>=8'} + dev: true + + /type-fest@0.8.1: + resolution: {integrity: sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==} + engines: {node: '>=8'} + dev: true + + /typechain@8.3.2(typescript@5.2.2): + resolution: {integrity: sha512-x/sQYr5w9K7yv3es7jo4KTX05CLxOf7TRWwoHlrjRh8H82G64g+k7VuWPJlgMo6qrjfCulOdfBjiaDtmhFYD/Q==} + hasBin: true + peerDependencies: + typescript: '>=4.3.0' + dependencies: + '@types/prettier': 2.7.3 + debug: 4.3.4(supports-color@8.1.1) + fs-extra: 7.0.1 + glob: 7.1.7 + js-sha3: 0.8.0 + lodash: 4.17.21 + mkdirp: 1.0.4 + prettier: 2.8.8 + ts-command-line-args: 2.5.1 + ts-essentials: 7.0.3(typescript@5.2.2) + typescript: 5.2.2 + transitivePeerDependencies: + - supports-color + dev: true + + /typed-array-buffer@1.0.0: + resolution: {integrity: sha512-Y8KTSIglk9OZEr8zywiIHG/kmQ7KWyjseXs1CbSo8vC42w7hg2HgYTxSWwP0+is7bWDc1H+Fo026CpHFwm8tkw==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + get-intrinsic: 1.2.1 + is-typed-array: 1.1.12 + + /typed-array-byte-length@1.0.0: + resolution: {integrity: sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + for-each: 0.3.3 + has-proto: 1.0.1 + is-typed-array: 1.1.12 + + /typed-array-byte-offset@1.0.0: + resolution: {integrity: sha512-RD97prjEt9EL8YgAgpOkf3O4IF9lhJFr9g0htQkm0rchFp/Vx7LW5Q8fSXXub7BXAODyUQohRMyOc3faCPd0hg==} + engines: {node: '>= 0.4'} + dependencies: + available-typed-arrays: 1.0.5 + call-bind: 1.0.2 + for-each: 0.3.3 + has-proto: 1.0.1 + is-typed-array: 1.1.12 + + /typed-array-length@1.0.4: + resolution: {integrity: sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==} + dependencies: + call-bind: 1.0.2 + for-each: 0.3.3 + is-typed-array: 1.1.12 + + /typescript@5.2.2: + resolution: {integrity: sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==} + engines: {node: '>=14.17'} + hasBin: true + + /typical@4.0.0: + resolution: {integrity: sha512-VAH4IvQ7BDFYglMd7BPRDfLgxZZX4O4TFcRDA6EN5X7erNJJq+McIEp8np9aVtxrCJ6qx4GTYVfOWNjcqwZgRw==} + engines: {node: '>=8'} + dev: true + + /typical@5.2.0: + resolution: {integrity: sha512-dvdQgNDNJo+8B2uBQoqdb11eUCE1JQXhvjC/CZtgvZseVd5TYMXnq0+vuUemXbd/Se29cTaUuPX3YIc2xgbvIg==} + engines: {node: '>=8'} + dev: true + + /unbox-primitive@1.0.2: + resolution: {integrity: sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==} + dependencies: + call-bind: 1.0.2 + has-bigints: 1.0.2 + has-symbols: 1.0.3 + which-boxed-primitive: 1.0.2 + + /unicode-canonical-property-names-ecmascript@2.0.0: + resolution: {integrity: sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==} + engines: {node: '>=4'} + dev: true + + /unicode-match-property-ecmascript@2.0.0: + resolution: {integrity: sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==} + engines: {node: '>=4'} + dependencies: + unicode-canonical-property-names-ecmascript: 2.0.0 + unicode-property-aliases-ecmascript: 2.1.0 + dev: true + + /unicode-match-property-value-ecmascript@2.1.0: + resolution: {integrity: sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA==} + engines: {node: '>=4'} + dev: true + + /unicode-property-aliases-ecmascript@2.1.0: + resolution: {integrity: sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==} + engines: {node: '>=4'} + dev: true + + /universalify@0.1.2: + resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==} + engines: {node: '>= 4.0.0'} + dev: true + + /universalify@2.0.0: + resolution: {integrity: sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==} + engines: {node: '>= 10.0.0'} + dev: true + + /update-browserslist-db@1.0.13(browserslist@4.22.1): + resolution: {integrity: sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + dependencies: + browserslist: 4.22.1 + escalade: 3.1.1 + picocolors: 1.0.0 + dev: true + + /uri-js@4.4.1: + resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + dependencies: + punycode: 2.3.0 + + /v8-compile-cache-lib@3.0.1: + resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==} + dev: true + + /v8-compile-cache@2.4.0: + resolution: {integrity: sha512-ocyWc3bAHBB/guyqJQVI5o4BZkPhznPYUG2ea80Gond/BgNWpap8TOmLSeeQG7bnh2KMISxskdADG59j7zruhw==} + dev: true + + /v8-to-istanbul@9.1.2: + resolution: {integrity: sha512-ZGBe7VAivuuoQXTeckpbYKTdtjXGcm3ZUHXC0PAk0CzFyuYvwi73a58iEKI3GkGD1c3EHc+EgfR1w5pgbfzJlQ==} + engines: {node: '>=10.12.0'} + dependencies: + '@jridgewell/trace-mapping': 0.3.19 + '@types/istanbul-lib-coverage': 2.0.4 + convert-source-map: 2.0.0 + dev: true + + /validate-npm-package-license@3.0.4: + resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==} + dependencies: + spdx-correct: 3.2.0 + spdx-expression-parse: 3.0.1 + dev: true + + /viem@1.18.4(typescript@5.2.2): + resolution: {integrity: sha512-im+y30k+IGT6VtfD/q1V0RX5PaiHPsFTHkKqvTjTqV+ZT8RgJXzOGPXr5E0uPIm2cbJAJp6A9nR9BCHY7BKR2Q==} + peerDependencies: + typescript: '>=5.0.4' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@adraffy/ens-normalize': 1.9.4 + '@noble/curves': 1.2.0 + '@noble/hashes': 1.3.2 + '@scure/bip32': 1.3.2 + '@scure/bip39': 1.2.1 + abitype: 0.9.8(typescript@5.2.2) + isows: 1.0.3(ws@8.13.0) + typescript: 5.2.2 + ws: 8.13.0 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + - zod + dev: false + + /wcwidth@1.0.1: + resolution: {integrity: sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==} + dependencies: + defaults: 1.0.4 + dev: true + + /which-boxed-primitive@1.0.2: + resolution: {integrity: sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==} + dependencies: + is-bigint: 1.0.4 + is-boolean-object: 1.1.2 + is-number-object: 1.0.7 + is-string: 1.0.7 + is-symbol: 1.0.4 + + /which-module@2.0.1: + resolution: {integrity: sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==} + dev: true + + /which-pm@2.0.0: + resolution: {integrity: sha512-Lhs9Pmyph0p5n5Z3mVnN0yWcbQYUAD7rbQUiMsQxOJ3T57k7RFe35SUwWMf7dsbDZks1uOmw4AecB/JMDj3v/w==} + engines: {node: '>=8.15'} + dependencies: + load-yaml-file: 0.2.0 + path-exists: 4.0.0 + dev: true + + /which-typed-array@1.1.11: + resolution: {integrity: sha512-qe9UWWpkeG5yzZ0tNYxDmd7vo58HDBc39mZ0xWWpolAGADdFOzkfamWLDxkOWcvHQKVmdTyQdLD4NOfjLWTKew==} + engines: {node: '>= 0.4'} + dependencies: + available-typed-arrays: 1.0.5 + call-bind: 1.0.2 + for-each: 0.3.3 + gopd: 1.0.1 + has-tostringtag: 1.0.0 + + /which@1.3.1: + resolution: {integrity: sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==} + hasBin: true + dependencies: + isexe: 2.0.0 + dev: true + + /which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + dependencies: + isexe: 2.0.0 + + /wordwrapjs@4.0.1: + resolution: {integrity: sha512-kKlNACbvHrkpIw6oPeYDSmdCTu2hdMHoyXLTcUKala++lx5Y+wjJ/e474Jqv5abnVmwxw08DiTuHmw69lJGksA==} + engines: {node: '>=8.0.0'} + dependencies: + reduce-flatten: 2.0.0 + typical: 5.2.0 + dev: true + + /workerpool@6.2.1: + resolution: {integrity: sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw==} + dev: true + + /wrap-ansi@6.2.0: + resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==} + engines: {node: '>=8'} + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + dev: true + + /wrap-ansi@7.0.0: + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + dev: true + + /wrappy@1.0.2: + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + + /ws@8.13.0: + resolution: {integrity: sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + dev: false + + /y18n@4.0.3: + resolution: {integrity: sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==} + dev: true + + /y18n@5.0.8: + resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} + engines: {node: '>=10'} + dev: true + + /yallist@2.1.2: + resolution: {integrity: sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==} + dev: true + + /yallist@3.1.1: + resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} + dev: true + + /yallist@4.0.0: + resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} + + /yargs-parser@18.1.3: + resolution: {integrity: sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==} + engines: {node: '>=6'} + dependencies: + camelcase: 5.3.1 + decamelize: 1.2.0 + dev: true + + /yargs-parser@20.2.4: + resolution: {integrity: sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==} + engines: {node: '>=10'} + dev: true + + /yargs-parser@21.1.1: + resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} + engines: {node: '>=12'} + dev: true + + /yargs-unparser@2.0.0: + resolution: {integrity: sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==} + engines: {node: '>=10'} + dependencies: + camelcase: 6.3.0 + decamelize: 4.0.0 + flat: 5.0.2 + is-plain-obj: 2.1.0 + dev: true + + /yargs@15.4.1: + resolution: {integrity: sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==} + engines: {node: '>=8'} + dependencies: + cliui: 6.0.0 + decamelize: 1.2.0 + find-up: 4.1.0 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + require-main-filename: 2.0.0 + set-blocking: 2.0.0 + string-width: 4.2.3 + which-module: 2.0.1 + y18n: 4.0.3 + yargs-parser: 18.1.3 + dev: true + + /yargs@16.2.0: + resolution: {integrity: sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==} + engines: {node: '>=10'} + dependencies: + cliui: 7.0.4 + escalade: 3.1.1 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + string-width: 4.2.3 + y18n: 5.0.8 + yargs-parser: 20.2.4 + dev: true + + /yargs@17.7.2: + resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} + engines: {node: '>=12'} + dependencies: + cliui: 8.0.1 + escalade: 3.1.1 + 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 + dev: true + + /yn@3.1.1: + resolution: {integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==} + engines: {node: '>=6'} + dev: true + + /yocto-queue@0.1.0: + resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} + engines: {node: '>=10'} + + /zod@3.22.4: + resolution: {integrity: sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg==} + dev: true diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml new file mode 100644 index 00000000..ccdc80cd --- /dev/null +++ b/pnpm-workspace.yaml @@ -0,0 +1,2 @@ +packages: + - "packages/*" \ No newline at end of file diff --git a/turbo.json b/turbo.json new file mode 100644 index 00000000..e77151fc --- /dev/null +++ b/turbo.json @@ -0,0 +1,36 @@ +{ + "$schema": "https://turbo.build/schema.json", + "globalEnv": [ + "API_BASE_URL", + "STORY_PROTOCOL_CONTRACT", + "IP_ORG_CONTROLLER_CONTRACT", + "IP_ASSET_REGISTRY_CONTRACT", + "RELATIONSHIP_MODULE_CONTRACT", + "REGISTRATION_MODULE_CONTRACT", + "LICENSE_REGISTRY_CONTRACT", + "NEXT_PUBLIC_API_BASE_URL", + "NEXT_PUBLIC_STORY_PROTOCOL_CONTRACT", + "NEXT_PUBLIC_IP_ORG_CONTROLLER_CONTRACT", + "NEXT_PUBLIC_IP_ASSET_REGISTRY_CONTRACT", + "NEXT_PUBLIC_RELATIONSHIP_MODULE_CONTRACT", + "NEXT_PUBLIC_REGISTRATION_MODULE_CONTRACT", + "NEXT_PUBLIC_LICENSE_REGISTRY_CONTRACT", + "RPC_PROVIDER_URL" + ], + "pipeline": { + "build": { + "dependsOn": ["^build"], + "outputs": ["dist/**"] + }, + "fix": { + "cache": false + }, + "lint": {}, + "lint:fix": {}, + "test": {}, + "dev": { + "cache": false, + "persistent": true + } + } +}