From b6f3a3f8bfa7c4b193c1c03e0954e0619b632074 Mon Sep 17 00:00:00 2001 From: Kyle Harding Date: Fri, 18 Oct 2024 11:17:43 -0400 Subject: [PATCH 01/15] Update License and project description Signed-off-by: Kyle Harding --- LICENSE | 210 +++++++++++++++++++++++++++++++++++++++++++--- README.md | 9 +- package-lock.json | 6 +- package.json | 8 +- src/index.ts | 10 +++ 5 files changed, 220 insertions(+), 23 deletions(-) diff --git a/LICENSE b/LICENSE index 5691304..3a4b1ea 100644 --- a/LICENSE +++ b/LICENSE @@ -1,15 +1,201 @@ -ISC License + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ -Copyright (c) 2024, Balena + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION -Permission to use, copy, modify, and/or distribute this software for any -purpose with or without fee is hereby granted, provided that the above -copyright notice and this permission notice appear in all copies. + 1. Definitions. -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [2024] Balena Ltd. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/README.md b/README.md index 81aa260..c957171 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Deployable -> A GitHub App built with [Probot](https://github.com/probot/probot) that Approve deployments with comment reactions +> A GitHub App built with [Probot](https://github.com/probot/probot) to Approve deployments via signed comments from maintainers ## Setup @@ -16,10 +16,10 @@ npm start ```sh # 1. Build container -docker build -t Deployable . +docker build -t deployable . # 2. Start container -docker run -e APP_ID= -e PRIVATE_KEY= Deployable +docker run -e APP_ID= -e PRIVATE_KEY= deployable ``` ## Contributing @@ -30,4 +30,5 @@ For more, check out the [Contributing Guide](CONTRIBUTING.md). ## License -[ISC](LICENSE) © 2024 Balena +This project is licensed under Apache 2.0 - see the [LICENSE](LICENSE) file for +details. diff --git a/package-lock.json b/package-lock.json index a3978db..07a48fe 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,13 +1,13 @@ { - "name": "Deployable", + "name": "deployable", "version": "1.0.0", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "Deployable", + "name": "deployable", "version": "1.0.0", - "license": "ISC", + "license": "Apache-2.0", "dependencies": { "probot": "^13.0.1" }, diff --git a/package.json b/package.json index b5c821c..b24de45 100644 --- a/package.json +++ b/package.json @@ -1,11 +1,11 @@ { - "name": "Deployable", + "name": "deployable", "version": "1.0.0", "private": true, - "description": "Approve deployments with comment reactions", + "description": "Approve deployments via signed comments from maintainers", "author": "Balena", - "license": "ISC", - "homepage": "https://github.com//", + "license": "Apache-2.0", + "homepage": "https://github.com/balena-io-experimental/deployable", "keywords": [ "probot", "github", diff --git a/src/index.ts b/src/index.ts index 0a68622..f82783d 100644 --- a/src/index.ts +++ b/src/index.ts @@ -7,6 +7,16 @@ export default (app: Probot) => { }); await context.octokit.issues.createComment(issueComment); }); + + app.on("deployment_protection_rule.requested", async (context) => { + console.log("Deployment protection rule requested"); + console.log(JSON.stringify(context.payload, null, 2)); + }); + + app.on("issue_comment.created", async (context) => { + console.log("Issue comment created"); + console.log(JSON.stringify(context.payload, null, 2)); + }); // For more information on building apps: // https://probot.github.io/docs/ From b49124ce58c19255a78ae123d000299830eee5dd Mon Sep 17 00:00:00 2001 From: Kyle Harding Date: Tue, 19 Nov 2024 15:50:52 -0500 Subject: [PATCH 02/15] Add basic GHA workflows for testing Signed-off-by: Kyle Harding --- .github/actions/test/action.yml | 10 +++++++ .github/workflows/flowzone.yml | 49 +++++++++++++++++++++++++++++++++ .github/workflows/test.yml | 16 +++++++++++ 3 files changed, 75 insertions(+) create mode 100644 .github/actions/test/action.yml create mode 100644 .github/workflows/flowzone.yml create mode 100644 .github/workflows/test.yml diff --git a/.github/actions/test/action.yml b/.github/actions/test/action.yml new file mode 100644 index 0000000..3c4a5e6 --- /dev/null +++ b/.github/actions/test/action.yml @@ -0,0 +1,10 @@ +# https://docs.github.com/en/actions/creating-actions/creating-a-composite-action +name: "Test custom" +description: "Custom test step to run during a pull request" +runs: + using: "composite" + steps: + - name: Print environment + shell: bash + run: | + echo "Running in environment: ${environment}" diff --git a/.github/workflows/flowzone.yml b/.github/workflows/flowzone.yml new file mode 100644 index 0000000..38c6114 --- /dev/null +++ b/.github/workflows/flowzone.yml @@ -0,0 +1,49 @@ +name: Flowzone + +on: + pull_request: + types: [opened, synchronize, closed] + branches: [main, master] + # allow external contributions to use secrets within trusted code + pull_request_target: + types: [opened, synchronize, closed] + branches: [main, master] + +# Base permissions required by Flowzone +# https://docs.github.com/en/actions/security-for-github-actions/security-guides/automatic-token-authentication#permissions-for-the-github_token +# https://docs.github.com/en/actions/writing-workflows/workflow-syntax-for-github-actions#permissions +permissions: + actions: none + attestations: none + checks: none + contents: read + deployments: none + id-token: none + issues: none + discussions: none + # packages: read + pages: none + pull-requests: none + repository-projects: none + security-events: none + statuses: none + + # Additional permissions needed by this repo, such as: + packages: write # Allow Flowzone to publish to ghcr.io + +jobs: + flowzone: + name: Flowzone + uses: product-os/flowzone/.github/workflows/flowzone.yml@master + # prevent duplicate workflows and only allow one `pull_request` or `pull_request_target` for + # internal or external contributions respectively + if: | + (github.event.pull_request.head.repo.full_name == github.repository && github.event_name == 'pull_request') || + (github.event.pull_request.head.repo.full_name != github.repository && github.event_name == 'pull_request_target') + secrets: inherit + with: + restrict_custom_actions: false + custom_test_matrix: > + { + "environment": ["test"] + } diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000..d002379 --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,16 @@ +name: Deploy + +on: + pull_request: + branches: [main, master] + +jobs: + test: + name: Deploy + runs-on: ubuntu-latest + environment: test + + steps: + - name: Print environment + run: | + echo "Running in environment: test" From a021b9f7dd81277fc4270590cb66e8eadd31917f Mon Sep 17 00:00:00 2001 From: Kyle Harding Date: Tue, 19 Nov 2024 15:51:21 -0500 Subject: [PATCH 03/15] Update GitHub App Manifest with permissions and events Signed-off-by: Kyle Harding --- app.yml | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/app.yml b/app.yml index d5a22f8..a32b6f4 100644 --- a/app.yml +++ b/app.yml @@ -20,10 +20,11 @@ default_events: # - delete # - deployment # - deployment_status + - deployment_protection_rule # - fork # - gollum - # - issue_comment - - issues + - issue_comment + # - issues # - label # - milestone # - member @@ -66,7 +67,7 @@ default_permissions: # Deployments and deployment statuses. # https://developer.github.com/v3/apps/permissions/#permission-on-deployments - # deployments: read + deployments: read # Issues and related comments, assignees, labels, and milestones. # https://developer.github.com/v3/apps/permissions/#permission-on-issues @@ -82,7 +83,7 @@ default_permissions: # Pull requests and related comments, assignees, labels, milestones, and merges. # https://developer.github.com/v3/apps/permissions/#permission-on-pull-requests - # pull_requests: read + pull_requests: write # Manage the post-receive hooks for a repository. # https://developer.github.com/v3/apps/permissions/#permission-on-repository-hooks @@ -102,7 +103,7 @@ default_permissions: # Organization members and teams. # https://developer.github.com/v3/apps/permissions/#permission-on-members - # members: read + members: read # View and manage users blocked by the organization. # https://developer.github.com/v3/apps/permissions/#permission-on-organization-user-blocking @@ -124,13 +125,13 @@ default_permissions: # https://developer.github.com/v3/apps/permissions/ # organization_administration: read # The name of the GitHub App. Defaults to the name specified in package.json -# name: My Probot App +name: Deployable # The homepage of your GitHub App. -# url: https://example.com/ +url: https://github.com/balena-io-experimental/deployable # A description of the GitHub App. -# description: A description of my awesome app +description: Approve deployments via signed comments from maintainers # Set to true when your GitHub App is available to the public or false when it is only accessible to the owner of the app. # Default: true From 4446a25ad09fcc4c7a948865448945ef10cef67a Mon Sep 17 00:00:00 2001 From: Kyle Harding Date: Tue, 19 Nov 2024 15:56:55 -0500 Subject: [PATCH 04/15] Initial commit of some app logic to print event payloads Change-type: patch Signed-off-by: Kyle Harding --- src/index.ts | 21 +++++++++++++++++++- tsconfig.json | 55 ++++++++++++++++++++++++++++++--------------------- 2 files changed, 52 insertions(+), 24 deletions(-) diff --git a/src/index.ts b/src/index.ts index f82783d..ee03dce 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,4 +1,7 @@ -import { Probot } from "probot"; +import type { Probot } from "probot"; +// import { DeploymentApprover } from "./deployment"; + +// const approver = new DeploymentApprover(); export default (app: Probot) => { app.on("issues.opened", async (context) => { @@ -16,6 +19,22 @@ export default (app: Probot) => { app.on("issue_comment.created", async (context) => { console.log("Issue comment created"); console.log(JSON.stringify(context.payload, null, 2)); + + // post a reaction to the comment with :eyes: + const reaction = context.repo({ + comment_id: context.payload.comment.id, + content: "eyes" as + | "eyes" + | "+1" + | "-1" + | "laugh" + | "confused" + | "heart" + | "hooray" + | "rocket", + }); + + await context.octokit.reactions.createForIssueComment(reaction); }); // For more information on building apps: // https://probot.github.io/docs/ diff --git a/tsconfig.json b/tsconfig.json index 37aaa7c..5dd1cb9 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,25 +1,34 @@ { - "compilerOptions": { - "incremental": true, - "target": "es2022", - "module": "Node16", - "declaration": true, - "sourceMap": true, - "outDir": "./lib", - - /* Strict Type-Checking Options */ - "strict": true, - - /* Additional Checks */ - "noUnusedLocals": true, - "noUnusedParameters": true, - "noImplicitReturns": true, - "noFallthroughCasesInSwitch": true, - - "moduleResolution": "Node16", - "esModuleInterop": true, - "forceConsistentCasingInFileNames": true - }, - "include": ["src/"], - "compileOnSave": false + "compilerOptions": { + "module": "NodeNext", + "target": "es2022", + "declaration": true, + "outDir": "lib/", + "rootDir": "src/", + "strict": true, + "strictPropertyInitialization": false, + "strictFunctionTypes": false, + "useUnknownInCatchVariables": false, + "noImplicitThis": false, + "noUnusedParameters": true, + "noUnusedLocals": true, + "preserveConstEnums": true, + "sourceMap": true, + "skipLibCheck": true, + "resolveJsonModule": true, + "esModuleInterop": true + }, + "include": [ + "src/**/*.ts" + ], + "exclude": [ + "node_modules", + "**/*.d.ts" + ], + "ts-node": { + "esm": true, + "experimentalResolver": true, + "experimentalTsImportSpecifiers": true, + "transpileOnly": true + } } From 9a69a9091be4bdb96c518fa1d63e01a029f6164b Mon Sep 17 00:00:00 2001 From: Kyle Harding Date: Tue, 19 Nov 2024 15:52:26 -0500 Subject: [PATCH 05/15] Add some example event fixtures for testing Signed-off-by: Kyle Harding --- .../deployment_protection_rule.requested.json | 641 ++++++++++++++++++ test/fixtures/issue_comment.created.json | 276 ++++++++ 2 files changed, 917 insertions(+) create mode 100644 test/fixtures/deployment_protection_rule.requested.json create mode 100644 test/fixtures/issue_comment.created.json diff --git a/test/fixtures/deployment_protection_rule.requested.json b/test/fixtures/deployment_protection_rule.requested.json new file mode 100644 index 0000000..c5a0916 --- /dev/null +++ b/test/fixtures/deployment_protection_rule.requested.json @@ -0,0 +1,641 @@ +{ + "action": "requested", + "environment": "test", + "event": "pull_request", + "deployment_callback_url": "https://api.github.com/repos/balena-io-experimental/deployable/actions/runs/11921637963/deployment_protection_rule", + "deployment": { + "url": "https://api.github.com/repos/balena-io-experimental/deployable/deployments/1972070328", + "id": 1972070328, + "node_id": "DE_kwDONCUcDs51i2e4", + "task": "deploy", + "original_environment": "test", + "environment": "test", + "description": null, + "created_at": "2024-11-19T20:57:47Z", + "updated_at": "2024-11-19T20:57:49Z", + "statuses_url": "https://api.github.com/repos/balena-io-experimental/deployable/deployments/1972070328/statuses", + "repository_url": "https://api.github.com/repos/balena-io-experimental/deployable", + "creator": { + "login": "klutchell", + "id": 20458272, + "node_id": "MDQ6VXNlcjIwNDU4Mjcy", + "avatar_url": "https://avatars.githubusercontent.com/u/20458272?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/klutchell", + "html_url": "https://github.com/klutchell", + "followers_url": "https://api.github.com/users/klutchell/followers", + "following_url": "https://api.github.com/users/klutchell/following{/other_user}", + "gists_url": "https://api.github.com/users/klutchell/gists{/gist_id}", + "starred_url": "https://api.github.com/users/klutchell/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/klutchell/subscriptions", + "organizations_url": "https://api.github.com/users/klutchell/orgs", + "repos_url": "https://api.github.com/users/klutchell/repos", + "events_url": "https://api.github.com/users/klutchell/events{/privacy}", + "received_events_url": "https://api.github.com/users/klutchell/received_events", + "type": "User", + "user_view_type": "public", + "site_admin": false + }, + "sha": "abec9b0889165cf1f9c2b51414f51be2110d9319", + "ref": "kyle/develop", + "payload": {}, + "transient_environment": false, + "production_environment": false, + "performed_via_github_app": { + "id": 15368, + "client_id": "Iv1.05c79e9ad1f6bdfa", + "slug": "github-actions", + "node_id": "MDM6QXBwMTUzNjg=", + "owner": { + "login": "github", + "id": 9919, + "node_id": "MDEyOk9yZ2FuaXphdGlvbjk5MTk=", + "avatar_url": "https://avatars.githubusercontent.com/u/9919?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github", + "html_url": "https://github.com/github", + "followers_url": "https://api.github.com/users/github/followers", + "following_url": "https://api.github.com/users/github/following{/other_user}", + "gists_url": "https://api.github.com/users/github/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github/subscriptions", + "organizations_url": "https://api.github.com/users/github/orgs", + "repos_url": "https://api.github.com/users/github/repos", + "events_url": "https://api.github.com/users/github/events{/privacy}", + "received_events_url": "https://api.github.com/users/github/received_events", + "type": "Organization", + "user_view_type": "public", + "site_admin": false + }, + "name": "GitHub Actions", + "description": "Automate your workflow from idea to production", + "external_url": "https://help.github.com/en/actions", + "html_url": "https://github.com/apps/github-actions", + "created_at": "2018-07-30T09:30:17Z", + "updated_at": "2024-04-10T20:33:16Z", + "permissions": { + "actions": "write", + "administration": "read", + "attestations": "write", + "checks": "write", + "contents": "write", + "deployments": "write", + "discussions": "write", + "issues": "write", + "merge_queues": "write", + "metadata": "read", + "packages": "write", + "pages": "write", + "pull_requests": "write", + "repository_hooks": "write", + "repository_projects": "write", + "security_events": "write", + "statuses": "write", + "vulnerability_alerts": "read" + }, + "events": [ + "branch_protection_rule", + "check_run", + "check_suite", + "create", + "delete", + "deployment", + "deployment_status", + "discussion", + "discussion_comment", + "fork", + "gollum", + "issues", + "issue_comment", + "label", + "merge_group", + "milestone", + "page_build", + "project", + "project_card", + "project_column", + "public", + "pull_request", + "pull_request_review", + "pull_request_review_comment", + "push", + "registry_package", + "release", + "repository", + "repository_dispatch", + "status", + "watch", + "workflow_dispatch", + "workflow_run" + ] + } + }, + "pull_requests": [ + { + "url": "https://api.github.com/repos/balena-io-experimental/deployable/pulls/2", + "id": 2188445505, + "node_id": "PR_kwDONCUcDs6CcQdB", + "html_url": "https://github.com/balena-io-experimental/deployable/pull/2", + "diff_url": "https://github.com/balena-io-experimental/deployable/pull/2.diff", + "patch_url": "https://github.com/balena-io-experimental/deployable/pull/2.patch", + "issue_url": "https://api.github.com/repos/balena-io-experimental/deployable/issues/2", + "number": 2, + "state": "open", + "locked": false, + "title": "Initial commit of some app logic to print event payloads", + "user": { + "login": "klutchell", + "id": 20458272, + "node_id": "MDQ6VXNlcjIwNDU4Mjcy", + "avatar_url": "https://avatars.githubusercontent.com/u/20458272?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/klutchell", + "html_url": "https://github.com/klutchell", + "followers_url": "https://api.github.com/users/klutchell/followers", + "following_url": "https://api.github.com/users/klutchell/following{/other_user}", + "gists_url": "https://api.github.com/users/klutchell/gists{/gist_id}", + "starred_url": "https://api.github.com/users/klutchell/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/klutchell/subscriptions", + "organizations_url": "https://api.github.com/users/klutchell/orgs", + "repos_url": "https://api.github.com/users/klutchell/repos", + "events_url": "https://api.github.com/users/klutchell/events{/privacy}", + "received_events_url": "https://api.github.com/users/klutchell/received_events", + "type": "User", + "user_view_type": "public", + "site_admin": false + }, + "body": null, + "created_at": "2024-11-19T20:57:39Z", + "updated_at": "2024-11-19T20:57:39Z", + "closed_at": null, + "merged_at": null, + "merge_commit_sha": "17637ccc71b44b510c817c7966170cb7a44ae6ed", + "assignee": null, + "assignees": [], + "requested_reviewers": [], + "requested_teams": [], + "labels": [], + "milestone": null, + "draft": true, + "commits_url": "https://api.github.com/repos/balena-io-experimental/deployable/pulls/2/commits", + "review_comments_url": "https://api.github.com/repos/balena-io-experimental/deployable/pulls/2/comments", + "review_comment_url": "https://api.github.com/repos/balena-io-experimental/deployable/pulls/comments{/number}", + "comments_url": "https://api.github.com/repos/balena-io-experimental/deployable/issues/2/comments", + "statuses_url": "https://api.github.com/repos/balena-io-experimental/deployable/statuses/abec9b0889165cf1f9c2b51414f51be2110d9319", + "head": { + "label": "balena-io-experimental:kyle/develop", + "ref": "kyle/develop", + "sha": "abec9b0889165cf1f9c2b51414f51be2110d9319", + "user": { + "login": "balena-io-experimental", + "id": 18610741, + "node_id": "MDEyOk9yZ2FuaXphdGlvbjE4NjEwNzQx", + "avatar_url": "https://avatars.githubusercontent.com/u/18610741?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/balena-io-experimental", + "html_url": "https://github.com/balena-io-experimental", + "followers_url": "https://api.github.com/users/balena-io-experimental/followers", + "following_url": "https://api.github.com/users/balena-io-experimental/following{/other_user}", + "gists_url": "https://api.github.com/users/balena-io-experimental/gists{/gist_id}", + "starred_url": "https://api.github.com/users/balena-io-experimental/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/balena-io-experimental/subscriptions", + "organizations_url": "https://api.github.com/users/balena-io-experimental/orgs", + "repos_url": "https://api.github.com/users/balena-io-experimental/repos", + "events_url": "https://api.github.com/users/balena-io-experimental/events{/privacy}", + "received_events_url": "https://api.github.com/users/balena-io-experimental/received_events", + "type": "Organization", + "user_view_type": "public", + "site_admin": false + }, + "repo": { + "id": 874847246, + "node_id": "R_kgDONCUcDg", + "name": "deployable", + "full_name": "balena-io-experimental/deployable", + "private": true, + "owner": { + "login": "balena-io-experimental", + "id": 18610741, + "node_id": "MDEyOk9yZ2FuaXphdGlvbjE4NjEwNzQx", + "avatar_url": "https://avatars.githubusercontent.com/u/18610741?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/balena-io-experimental", + "html_url": "https://github.com/balena-io-experimental", + "followers_url": "https://api.github.com/users/balena-io-experimental/followers", + "following_url": "https://api.github.com/users/balena-io-experimental/following{/other_user}", + "gists_url": "https://api.github.com/users/balena-io-experimental/gists{/gist_id}", + "starred_url": "https://api.github.com/users/balena-io-experimental/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/balena-io-experimental/subscriptions", + "organizations_url": "https://api.github.com/users/balena-io-experimental/orgs", + "repos_url": "https://api.github.com/users/balena-io-experimental/repos", + "events_url": "https://api.github.com/users/balena-io-experimental/events{/privacy}", + "received_events_url": "https://api.github.com/users/balena-io-experimental/received_events", + "type": "Organization", + "user_view_type": "public", + "site_admin": false + }, + "html_url": "https://github.com/balena-io-experimental/deployable", + "description": "Approve deployments with comment reactions", + "fork": false, + "url": "https://api.github.com/repos/balena-io-experimental/deployable", + "forks_url": "https://api.github.com/repos/balena-io-experimental/deployable/forks", + "keys_url": "https://api.github.com/repos/balena-io-experimental/deployable/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/balena-io-experimental/deployable/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/balena-io-experimental/deployable/teams", + "hooks_url": "https://api.github.com/repos/balena-io-experimental/deployable/hooks", + "issue_events_url": "https://api.github.com/repos/balena-io-experimental/deployable/issues/events{/number}", + "events_url": "https://api.github.com/repos/balena-io-experimental/deployable/events", + "assignees_url": "https://api.github.com/repos/balena-io-experimental/deployable/assignees{/user}", + "branches_url": "https://api.github.com/repos/balena-io-experimental/deployable/branches{/branch}", + "tags_url": "https://api.github.com/repos/balena-io-experimental/deployable/tags", + "blobs_url": "https://api.github.com/repos/balena-io-experimental/deployable/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/balena-io-experimental/deployable/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/balena-io-experimental/deployable/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/balena-io-experimental/deployable/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/balena-io-experimental/deployable/statuses/{sha}", + "languages_url": "https://api.github.com/repos/balena-io-experimental/deployable/languages", + "stargazers_url": "https://api.github.com/repos/balena-io-experimental/deployable/stargazers", + "contributors_url": "https://api.github.com/repos/balena-io-experimental/deployable/contributors", + "subscribers_url": "https://api.github.com/repos/balena-io-experimental/deployable/subscribers", + "subscription_url": "https://api.github.com/repos/balena-io-experimental/deployable/subscription", + "commits_url": "https://api.github.com/repos/balena-io-experimental/deployable/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/balena-io-experimental/deployable/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/balena-io-experimental/deployable/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/balena-io-experimental/deployable/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/balena-io-experimental/deployable/contents/{+path}", + "compare_url": "https://api.github.com/repos/balena-io-experimental/deployable/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/balena-io-experimental/deployable/merges", + "archive_url": "https://api.github.com/repos/balena-io-experimental/deployable/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/balena-io-experimental/deployable/downloads", + "issues_url": "https://api.github.com/repos/balena-io-experimental/deployable/issues{/number}", + "pulls_url": "https://api.github.com/repos/balena-io-experimental/deployable/pulls{/number}", + "milestones_url": "https://api.github.com/repos/balena-io-experimental/deployable/milestones{/number}", + "notifications_url": "https://api.github.com/repos/balena-io-experimental/deployable/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/balena-io-experimental/deployable/labels{/name}", + "releases_url": "https://api.github.com/repos/balena-io-experimental/deployable/releases{/id}", + "deployments_url": "https://api.github.com/repos/balena-io-experimental/deployable/deployments", + "created_at": "2024-10-18T15:11:02Z", + "updated_at": "2024-10-18T15:12:13Z", + "pushed_at": "2024-11-19T20:57:23Z", + "git_url": "git://github.com/balena-io-experimental/deployable.git", + "ssh_url": "git@github.com:balena-io-experimental/deployable.git", + "clone_url": "https://github.com/balena-io-experimental/deployable.git", + "svn_url": "https://github.com/balena-io-experimental/deployable", + "homepage": null, + "size": 47, + "stargazers_count": 0, + "watchers_count": 0, + "language": "TypeScript", + "has_issues": true, + "has_projects": true, + "has_downloads": true, + "has_wiki": true, + "has_pages": false, + "has_discussions": false, + "forks_count": 0, + "mirror_url": null, + "archived": false, + "disabled": false, + "open_issues_count": 2, + "license": { + "key": "isc", + "name": "ISC License", + "spdx_id": "ISC", + "url": "https://api.github.com/licenses/isc", + "node_id": "MDc6TGljZW5zZTEw" + }, + "allow_forking": false, + "is_template": false, + "web_commit_signoff_required": false, + "topics": [], + "visibility": "internal", + "forks": 0, + "open_issues": 2, + "watchers": 0, + "default_branch": "main" + } + }, + "base": { + "label": "balena-io-experimental:main", + "ref": "main", + "sha": "89354cd1344b8de289e5965328831992448eac7a", + "user": { + "login": "balena-io-experimental", + "id": 18610741, + "node_id": "MDEyOk9yZ2FuaXphdGlvbjE4NjEwNzQx", + "avatar_url": "https://avatars.githubusercontent.com/u/18610741?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/balena-io-experimental", + "html_url": "https://github.com/balena-io-experimental", + "followers_url": "https://api.github.com/users/balena-io-experimental/followers", + "following_url": "https://api.github.com/users/balena-io-experimental/following{/other_user}", + "gists_url": "https://api.github.com/users/balena-io-experimental/gists{/gist_id}", + "starred_url": "https://api.github.com/users/balena-io-experimental/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/balena-io-experimental/subscriptions", + "organizations_url": "https://api.github.com/users/balena-io-experimental/orgs", + "repos_url": "https://api.github.com/users/balena-io-experimental/repos", + "events_url": "https://api.github.com/users/balena-io-experimental/events{/privacy}", + "received_events_url": "https://api.github.com/users/balena-io-experimental/received_events", + "type": "Organization", + "user_view_type": "public", + "site_admin": false + }, + "repo": { + "id": 874847246, + "node_id": "R_kgDONCUcDg", + "name": "deployable", + "full_name": "balena-io-experimental/deployable", + "private": true, + "owner": { + "login": "balena-io-experimental", + "id": 18610741, + "node_id": "MDEyOk9yZ2FuaXphdGlvbjE4NjEwNzQx", + "avatar_url": "https://avatars.githubusercontent.com/u/18610741?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/balena-io-experimental", + "html_url": "https://github.com/balena-io-experimental", + "followers_url": "https://api.github.com/users/balena-io-experimental/followers", + "following_url": "https://api.github.com/users/balena-io-experimental/following{/other_user}", + "gists_url": "https://api.github.com/users/balena-io-experimental/gists{/gist_id}", + "starred_url": "https://api.github.com/users/balena-io-experimental/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/balena-io-experimental/subscriptions", + "organizations_url": "https://api.github.com/users/balena-io-experimental/orgs", + "repos_url": "https://api.github.com/users/balena-io-experimental/repos", + "events_url": "https://api.github.com/users/balena-io-experimental/events{/privacy}", + "received_events_url": "https://api.github.com/users/balena-io-experimental/received_events", + "type": "Organization", + "user_view_type": "public", + "site_admin": false + }, + "html_url": "https://github.com/balena-io-experimental/deployable", + "description": "Approve deployments with comment reactions", + "fork": false, + "url": "https://api.github.com/repos/balena-io-experimental/deployable", + "forks_url": "https://api.github.com/repos/balena-io-experimental/deployable/forks", + "keys_url": "https://api.github.com/repos/balena-io-experimental/deployable/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/balena-io-experimental/deployable/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/balena-io-experimental/deployable/teams", + "hooks_url": "https://api.github.com/repos/balena-io-experimental/deployable/hooks", + "issue_events_url": "https://api.github.com/repos/balena-io-experimental/deployable/issues/events{/number}", + "events_url": "https://api.github.com/repos/balena-io-experimental/deployable/events", + "assignees_url": "https://api.github.com/repos/balena-io-experimental/deployable/assignees{/user}", + "branches_url": "https://api.github.com/repos/balena-io-experimental/deployable/branches{/branch}", + "tags_url": "https://api.github.com/repos/balena-io-experimental/deployable/tags", + "blobs_url": "https://api.github.com/repos/balena-io-experimental/deployable/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/balena-io-experimental/deployable/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/balena-io-experimental/deployable/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/balena-io-experimental/deployable/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/balena-io-experimental/deployable/statuses/{sha}", + "languages_url": "https://api.github.com/repos/balena-io-experimental/deployable/languages", + "stargazers_url": "https://api.github.com/repos/balena-io-experimental/deployable/stargazers", + "contributors_url": "https://api.github.com/repos/balena-io-experimental/deployable/contributors", + "subscribers_url": "https://api.github.com/repos/balena-io-experimental/deployable/subscribers", + "subscription_url": "https://api.github.com/repos/balena-io-experimental/deployable/subscription", + "commits_url": "https://api.github.com/repos/balena-io-experimental/deployable/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/balena-io-experimental/deployable/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/balena-io-experimental/deployable/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/balena-io-experimental/deployable/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/balena-io-experimental/deployable/contents/{+path}", + "compare_url": "https://api.github.com/repos/balena-io-experimental/deployable/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/balena-io-experimental/deployable/merges", + "archive_url": "https://api.github.com/repos/balena-io-experimental/deployable/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/balena-io-experimental/deployable/downloads", + "issues_url": "https://api.github.com/repos/balena-io-experimental/deployable/issues{/number}", + "pulls_url": "https://api.github.com/repos/balena-io-experimental/deployable/pulls{/number}", + "milestones_url": "https://api.github.com/repos/balena-io-experimental/deployable/milestones{/number}", + "notifications_url": "https://api.github.com/repos/balena-io-experimental/deployable/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/balena-io-experimental/deployable/labels{/name}", + "releases_url": "https://api.github.com/repos/balena-io-experimental/deployable/releases{/id}", + "deployments_url": "https://api.github.com/repos/balena-io-experimental/deployable/deployments", + "created_at": "2024-10-18T15:11:02Z", + "updated_at": "2024-10-18T15:12:13Z", + "pushed_at": "2024-11-19T20:57:23Z", + "git_url": "git://github.com/balena-io-experimental/deployable.git", + "ssh_url": "git@github.com:balena-io-experimental/deployable.git", + "clone_url": "https://github.com/balena-io-experimental/deployable.git", + "svn_url": "https://github.com/balena-io-experimental/deployable", + "homepage": null, + "size": 47, + "stargazers_count": 0, + "watchers_count": 0, + "language": "TypeScript", + "has_issues": true, + "has_projects": true, + "has_downloads": true, + "has_wiki": true, + "has_pages": false, + "has_discussions": false, + "forks_count": 0, + "mirror_url": null, + "archived": false, + "disabled": false, + "open_issues_count": 2, + "license": { + "key": "isc", + "name": "ISC License", + "spdx_id": "ISC", + "url": "https://api.github.com/licenses/isc", + "node_id": "MDc6TGljZW5zZTEw" + }, + "allow_forking": false, + "is_template": false, + "web_commit_signoff_required": false, + "topics": [], + "visibility": "internal", + "forks": 0, + "open_issues": 2, + "watchers": 0, + "default_branch": "main" + } + }, + "_links": { + "self": { + "href": "https://api.github.com/repos/balena-io-experimental/deployable/pulls/2" + }, + "html": { + "href": "https://github.com/balena-io-experimental/deployable/pull/2" + }, + "issue": { + "href": "https://api.github.com/repos/balena-io-experimental/deployable/issues/2" + }, + "comments": { + "href": "https://api.github.com/repos/balena-io-experimental/deployable/issues/2/comments" + }, + "review_comments": { + "href": "https://api.github.com/repos/balena-io-experimental/deployable/pulls/2/comments" + }, + "review_comment": { + "href": "https://api.github.com/repos/balena-io-experimental/deployable/pulls/comments{/number}" + }, + "commits": { + "href": "https://api.github.com/repos/balena-io-experimental/deployable/pulls/2/commits" + }, + "statuses": { + "href": "https://api.github.com/repos/balena-io-experimental/deployable/statuses/abec9b0889165cf1f9c2b51414f51be2110d9319" + } + }, + "author_association": "COLLABORATOR", + "auto_merge": null, + "active_lock_reason": null + } + ], + "repository": { + "id": 874847246, + "node_id": "R_kgDONCUcDg", + "name": "deployable", + "full_name": "balena-io-experimental/deployable", + "private": true, + "owner": { + "login": "balena-io-experimental", + "id": 18610741, + "node_id": "MDEyOk9yZ2FuaXphdGlvbjE4NjEwNzQx", + "avatar_url": "https://avatars.githubusercontent.com/u/18610741?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/balena-io-experimental", + "html_url": "https://github.com/balena-io-experimental", + "followers_url": "https://api.github.com/users/balena-io-experimental/followers", + "following_url": "https://api.github.com/users/balena-io-experimental/following{/other_user}", + "gists_url": "https://api.github.com/users/balena-io-experimental/gists{/gist_id}", + "starred_url": "https://api.github.com/users/balena-io-experimental/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/balena-io-experimental/subscriptions", + "organizations_url": "https://api.github.com/users/balena-io-experimental/orgs", + "repos_url": "https://api.github.com/users/balena-io-experimental/repos", + "events_url": "https://api.github.com/users/balena-io-experimental/events{/privacy}", + "received_events_url": "https://api.github.com/users/balena-io-experimental/received_events", + "type": "Organization", + "user_view_type": "public", + "site_admin": false + }, + "html_url": "https://github.com/balena-io-experimental/deployable", + "description": "Approve deployments with comment reactions", + "fork": false, + "url": "https://api.github.com/repos/balena-io-experimental/deployable", + "forks_url": "https://api.github.com/repos/balena-io-experimental/deployable/forks", + "keys_url": "https://api.github.com/repos/balena-io-experimental/deployable/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/balena-io-experimental/deployable/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/balena-io-experimental/deployable/teams", + "hooks_url": "https://api.github.com/repos/balena-io-experimental/deployable/hooks", + "issue_events_url": "https://api.github.com/repos/balena-io-experimental/deployable/issues/events{/number}", + "events_url": "https://api.github.com/repos/balena-io-experimental/deployable/events", + "assignees_url": "https://api.github.com/repos/balena-io-experimental/deployable/assignees{/user}", + "branches_url": "https://api.github.com/repos/balena-io-experimental/deployable/branches{/branch}", + "tags_url": "https://api.github.com/repos/balena-io-experimental/deployable/tags", + "blobs_url": "https://api.github.com/repos/balena-io-experimental/deployable/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/balena-io-experimental/deployable/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/balena-io-experimental/deployable/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/balena-io-experimental/deployable/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/balena-io-experimental/deployable/statuses/{sha}", + "languages_url": "https://api.github.com/repos/balena-io-experimental/deployable/languages", + "stargazers_url": "https://api.github.com/repos/balena-io-experimental/deployable/stargazers", + "contributors_url": "https://api.github.com/repos/balena-io-experimental/deployable/contributors", + "subscribers_url": "https://api.github.com/repos/balena-io-experimental/deployable/subscribers", + "subscription_url": "https://api.github.com/repos/balena-io-experimental/deployable/subscription", + "commits_url": "https://api.github.com/repos/balena-io-experimental/deployable/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/balena-io-experimental/deployable/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/balena-io-experimental/deployable/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/balena-io-experimental/deployable/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/balena-io-experimental/deployable/contents/{+path}", + "compare_url": "https://api.github.com/repos/balena-io-experimental/deployable/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/balena-io-experimental/deployable/merges", + "archive_url": "https://api.github.com/repos/balena-io-experimental/deployable/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/balena-io-experimental/deployable/downloads", + "issues_url": "https://api.github.com/repos/balena-io-experimental/deployable/issues{/number}", + "pulls_url": "https://api.github.com/repos/balena-io-experimental/deployable/pulls{/number}", + "milestones_url": "https://api.github.com/repos/balena-io-experimental/deployable/milestones{/number}", + "notifications_url": "https://api.github.com/repos/balena-io-experimental/deployable/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/balena-io-experimental/deployable/labels{/name}", + "releases_url": "https://api.github.com/repos/balena-io-experimental/deployable/releases{/id}", + "deployments_url": "https://api.github.com/repos/balena-io-experimental/deployable/deployments", + "created_at": "2024-10-18T15:11:02Z", + "updated_at": "2024-10-18T15:12:13Z", + "pushed_at": "2024-11-19T20:57:23Z", + "git_url": "git://github.com/balena-io-experimental/deployable.git", + "ssh_url": "git@github.com:balena-io-experimental/deployable.git", + "clone_url": "https://github.com/balena-io-experimental/deployable.git", + "svn_url": "https://github.com/balena-io-experimental/deployable", + "homepage": null, + "size": 47, + "stargazers_count": 0, + "watchers_count": 0, + "language": "TypeScript", + "has_issues": true, + "has_projects": true, + "has_downloads": true, + "has_wiki": true, + "has_pages": false, + "has_discussions": false, + "forks_count": 0, + "mirror_url": null, + "archived": false, + "disabled": false, + "open_issues_count": 2, + "license": { + "key": "isc", + "name": "ISC License", + "spdx_id": "ISC", + "url": "https://api.github.com/licenses/isc", + "node_id": "MDc6TGljZW5zZTEw" + }, + "allow_forking": false, + "is_template": false, + "web_commit_signoff_required": false, + "topics": [], + "visibility": "internal", + "forks": 0, + "open_issues": 2, + "watchers": 0, + "default_branch": "main", + "custom_properties": {} + }, + "organization": { + "login": "balena-io-experimental", + "id": 18610741, + "node_id": "MDEyOk9yZ2FuaXphdGlvbjE4NjEwNzQx", + "url": "https://api.github.com/orgs/balena-io-experimental", + "repos_url": "https://api.github.com/orgs/balena-io-experimental/repos", + "events_url": "https://api.github.com/orgs/balena-io-experimental/events", + "hooks_url": "https://api.github.com/orgs/balena-io-experimental/hooks", + "issues_url": "https://api.github.com/orgs/balena-io-experimental/issues", + "members_url": "https://api.github.com/orgs/balena-io-experimental/members{/member}", + "public_members_url": "https://api.github.com/orgs/balena-io-experimental/public_members{/member}", + "avatar_url": "https://avatars.githubusercontent.com/u/18610741?v=4", + "description": "A collection of play around and experimental projects for balena IoT devices" + }, + "enterprise": { + "id": 16136, + "slug": "balena", + "name": " Balena Ltd", + "node_id": "E_kgDNPwg", + "avatar_url": "https://avatars.githubusercontent.com/b/16136?v=4", + "description": "Balena brings the benefits of Linux containers to the IoT. Develop iteratively, deploy safely, and manage at scale.", + "website_url": "https://www.balena.io", + "html_url": "https://github.com/enterprises/balena", + "created_at": "2022-10-05T14:08:07Z", + "updated_at": "2024-10-04T08:57:35Z" + }, + "sender": { + "login": "klutchell", + "id": 20458272, + "node_id": "MDQ6VXNlcjIwNDU4Mjcy", + "avatar_url": "https://avatars.githubusercontent.com/u/20458272?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/klutchell", + "html_url": "https://github.com/klutchell", + "followers_url": "https://api.github.com/users/klutchell/followers", + "following_url": "https://api.github.com/users/klutchell/following{/other_user}", + "gists_url": "https://api.github.com/users/klutchell/gists{/gist_id}", + "starred_url": "https://api.github.com/users/klutchell/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/klutchell/subscriptions", + "organizations_url": "https://api.github.com/users/klutchell/orgs", + "repos_url": "https://api.github.com/users/klutchell/repos", + "events_url": "https://api.github.com/users/klutchell/events{/privacy}", + "received_events_url": "https://api.github.com/users/klutchell/received_events", + "type": "User", + "user_view_type": "public", + "site_admin": false + }, + "installation": { + "id": 57364329, + "node_id": "MDIzOkludGVncmF0aW9uSW5zdGFsbGF0aW9uNTczNjQzMjk=" + } +} diff --git a/test/fixtures/issue_comment.created.json b/test/fixtures/issue_comment.created.json new file mode 100644 index 0000000..da7f5e5 --- /dev/null +++ b/test/fixtures/issue_comment.created.json @@ -0,0 +1,276 @@ +{ + "action": "created", + "issue": { + "url": "https://api.github.com/repos/balena-io-experimental/deployable/issues/2", + "repository_url": "https://api.github.com/repos/balena-io-experimental/deployable", + "labels_url": "https://api.github.com/repos/balena-io-experimental/deployable/issues/2/labels{/name}", + "comments_url": "https://api.github.com/repos/balena-io-experimental/deployable/issues/2/comments", + "events_url": "https://api.github.com/repos/balena-io-experimental/deployable/issues/2/events", + "html_url": "https://github.com/balena-io-experimental/deployable/pull/2", + "id": 2673531470, + "node_id": "PR_kwDONCUcDs6CcQdB", + "number": 2, + "title": "Initial commit of some app logic to print event payloads", + "user": { + "login": "klutchell", + "id": 20458272, + "node_id": "MDQ6VXNlcjIwNDU4Mjcy", + "avatar_url": "https://avatars.githubusercontent.com/u/20458272?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/klutchell", + "html_url": "https://github.com/klutchell", + "followers_url": "https://api.github.com/users/klutchell/followers", + "following_url": "https://api.github.com/users/klutchell/following{/other_user}", + "gists_url": "https://api.github.com/users/klutchell/gists{/gist_id}", + "starred_url": "https://api.github.com/users/klutchell/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/klutchell/subscriptions", + "organizations_url": "https://api.github.com/users/klutchell/orgs", + "repos_url": "https://api.github.com/users/klutchell/repos", + "events_url": "https://api.github.com/users/klutchell/events{/privacy}", + "received_events_url": "https://api.github.com/users/klutchell/received_events", + "type": "User", + "user_view_type": "public", + "site_admin": false + }, + "labels": [], + "state": "open", + "locked": false, + "assignee": null, + "assignees": [], + "milestone": null, + "comments": 1, + "created_at": "2024-11-19T20:57:39Z", + "updated_at": "2024-11-19T20:59:28Z", + "closed_at": null, + "author_association": "COLLABORATOR", + "active_lock_reason": null, + "draft": true, + "pull_request": { + "url": "https://api.github.com/repos/balena-io-experimental/deployable/pulls/2", + "html_url": "https://github.com/balena-io-experimental/deployable/pull/2", + "diff_url": "https://github.com/balena-io-experimental/deployable/pull/2.diff", + "patch_url": "https://github.com/balena-io-experimental/deployable/pull/2.patch", + "merged_at": null + }, + "body": null, + "reactions": { + "url": "https://api.github.com/repos/balena-io-experimental/deployable/issues/2/reactions", + "total_count": 0, + "+1": 0, + "-1": 0, + "laugh": 0, + "hooray": 0, + "confused": 0, + "heart": 0, + "rocket": 0, + "eyes": 0 + }, + "timeline_url": "https://api.github.com/repos/balena-io-experimental/deployable/issues/2/timeline", + "performed_via_github_app": null, + "state_reason": null + }, + "comment": { + "url": "https://api.github.com/repos/balena-io-experimental/deployable/issues/comments/2486741061", + "html_url": "https://github.com/balena-io-experimental/deployable/pull/2#issuecomment-2486741061", + "issue_url": "https://api.github.com/repos/balena-io-experimental/deployable/issues/2", + "id": 2486741061, + "node_id": "IC_kwDONCUcDs6UOKhF", + "user": { + "login": "klutchell", + "id": 20458272, + "node_id": "MDQ6VXNlcjIwNDU4Mjcy", + "avatar_url": "https://avatars.githubusercontent.com/u/20458272?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/klutchell", + "html_url": "https://github.com/klutchell", + "followers_url": "https://api.github.com/users/klutchell/followers", + "following_url": "https://api.github.com/users/klutchell/following{/other_user}", + "gists_url": "https://api.github.com/users/klutchell/gists{/gist_id}", + "starred_url": "https://api.github.com/users/klutchell/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/klutchell/subscriptions", + "organizations_url": "https://api.github.com/users/klutchell/orgs", + "repos_url": "https://api.github.com/users/klutchell/repos", + "events_url": "https://api.github.com/users/klutchell/events{/privacy}", + "received_events_url": "https://api.github.com/users/klutchell/received_events", + "type": "User", + "user_view_type": "public", + "site_admin": false + }, + "created_at": "2024-11-19T20:59:26Z", + "updated_at": "2024-11-19T20:59:26Z", + "author_association": "MEMBER", + "body": "/deploy please", + "reactions": { + "url": "https://api.github.com/repos/balena-io-experimental/deployable/issues/comments/2486741061/reactions", + "total_count": 0, + "+1": 0, + "-1": 0, + "laugh": 0, + "hooray": 0, + "confused": 0, + "heart": 0, + "rocket": 0, + "eyes": 0 + }, + "performed_via_github_app": null + }, + "repository": { + "id": 874847246, + "node_id": "R_kgDONCUcDg", + "name": "deployable", + "full_name": "balena-io-experimental/deployable", + "private": true, + "owner": { + "login": "balena-io-experimental", + "id": 18610741, + "node_id": "MDEyOk9yZ2FuaXphdGlvbjE4NjEwNzQx", + "avatar_url": "https://avatars.githubusercontent.com/u/18610741?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/balena-io-experimental", + "html_url": "https://github.com/balena-io-experimental", + "followers_url": "https://api.github.com/users/balena-io-experimental/followers", + "following_url": "https://api.github.com/users/balena-io-experimental/following{/other_user}", + "gists_url": "https://api.github.com/users/balena-io-experimental/gists{/gist_id}", + "starred_url": "https://api.github.com/users/balena-io-experimental/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/balena-io-experimental/subscriptions", + "organizations_url": "https://api.github.com/users/balena-io-experimental/orgs", + "repos_url": "https://api.github.com/users/balena-io-experimental/repos", + "events_url": "https://api.github.com/users/balena-io-experimental/events{/privacy}", + "received_events_url": "https://api.github.com/users/balena-io-experimental/received_events", + "type": "Organization", + "user_view_type": "public", + "site_admin": false + }, + "html_url": "https://github.com/balena-io-experimental/deployable", + "description": "Approve deployments with comment reactions", + "fork": false, + "url": "https://api.github.com/repos/balena-io-experimental/deployable", + "forks_url": "https://api.github.com/repos/balena-io-experimental/deployable/forks", + "keys_url": "https://api.github.com/repos/balena-io-experimental/deployable/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/balena-io-experimental/deployable/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/balena-io-experimental/deployable/teams", + "hooks_url": "https://api.github.com/repos/balena-io-experimental/deployable/hooks", + "issue_events_url": "https://api.github.com/repos/balena-io-experimental/deployable/issues/events{/number}", + "events_url": "https://api.github.com/repos/balena-io-experimental/deployable/events", + "assignees_url": "https://api.github.com/repos/balena-io-experimental/deployable/assignees{/user}", + "branches_url": "https://api.github.com/repos/balena-io-experimental/deployable/branches{/branch}", + "tags_url": "https://api.github.com/repos/balena-io-experimental/deployable/tags", + "blobs_url": "https://api.github.com/repos/balena-io-experimental/deployable/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/balena-io-experimental/deployable/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/balena-io-experimental/deployable/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/balena-io-experimental/deployable/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/balena-io-experimental/deployable/statuses/{sha}", + "languages_url": "https://api.github.com/repos/balena-io-experimental/deployable/languages", + "stargazers_url": "https://api.github.com/repos/balena-io-experimental/deployable/stargazers", + "contributors_url": "https://api.github.com/repos/balena-io-experimental/deployable/contributors", + "subscribers_url": "https://api.github.com/repos/balena-io-experimental/deployable/subscribers", + "subscription_url": "https://api.github.com/repos/balena-io-experimental/deployable/subscription", + "commits_url": "https://api.github.com/repos/balena-io-experimental/deployable/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/balena-io-experimental/deployable/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/balena-io-experimental/deployable/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/balena-io-experimental/deployable/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/balena-io-experimental/deployable/contents/{+path}", + "compare_url": "https://api.github.com/repos/balena-io-experimental/deployable/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/balena-io-experimental/deployable/merges", + "archive_url": "https://api.github.com/repos/balena-io-experimental/deployable/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/balena-io-experimental/deployable/downloads", + "issues_url": "https://api.github.com/repos/balena-io-experimental/deployable/issues{/number}", + "pulls_url": "https://api.github.com/repos/balena-io-experimental/deployable/pulls{/number}", + "milestones_url": "https://api.github.com/repos/balena-io-experimental/deployable/milestones{/number}", + "notifications_url": "https://api.github.com/repos/balena-io-experimental/deployable/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/balena-io-experimental/deployable/labels{/name}", + "releases_url": "https://api.github.com/repos/balena-io-experimental/deployable/releases{/id}", + "deployments_url": "https://api.github.com/repos/balena-io-experimental/deployable/deployments", + "created_at": "2024-10-18T15:11:02Z", + "updated_at": "2024-10-18T15:12:13Z", + "pushed_at": "2024-11-19T20:57:23Z", + "git_url": "git://github.com/balena-io-experimental/deployable.git", + "ssh_url": "git@github.com:balena-io-experimental/deployable.git", + "clone_url": "https://github.com/balena-io-experimental/deployable.git", + "svn_url": "https://github.com/balena-io-experimental/deployable", + "homepage": null, + "size": 47, + "stargazers_count": 0, + "watchers_count": 0, + "language": "TypeScript", + "has_issues": true, + "has_projects": true, + "has_downloads": true, + "has_wiki": true, + "has_pages": false, + "has_discussions": false, + "forks_count": 0, + "mirror_url": null, + "archived": false, + "disabled": false, + "open_issues_count": 2, + "license": { + "key": "isc", + "name": "ISC License", + "spdx_id": "ISC", + "url": "https://api.github.com/licenses/isc", + "node_id": "MDc6TGljZW5zZTEw" + }, + "allow_forking": false, + "is_template": false, + "web_commit_signoff_required": false, + "topics": [], + "visibility": "internal", + "forks": 0, + "open_issues": 2, + "watchers": 0, + "default_branch": "main", + "custom_properties": {} + }, + "organization": { + "login": "balena-io-experimental", + "id": 18610741, + "node_id": "MDEyOk9yZ2FuaXphdGlvbjE4NjEwNzQx", + "url": "https://api.github.com/orgs/balena-io-experimental", + "repos_url": "https://api.github.com/orgs/balena-io-experimental/repos", + "events_url": "https://api.github.com/orgs/balena-io-experimental/events", + "hooks_url": "https://api.github.com/orgs/balena-io-experimental/hooks", + "issues_url": "https://api.github.com/orgs/balena-io-experimental/issues", + "members_url": "https://api.github.com/orgs/balena-io-experimental/members{/member}", + "public_members_url": "https://api.github.com/orgs/balena-io-experimental/public_members{/member}", + "avatar_url": "https://avatars.githubusercontent.com/u/18610741?v=4", + "description": "A collection of play around and experimental projects for balena IoT devices" + }, + "enterprise": { + "id": 16136, + "slug": "balena", + "name": " Balena Ltd", + "node_id": "E_kgDNPwg", + "avatar_url": "https://avatars.githubusercontent.com/b/16136?v=4", + "description": "Balena brings the benefits of Linux containers to the IoT. Develop iteratively, deploy safely, and manage at scale.", + "website_url": "https://www.balena.io", + "html_url": "https://github.com/enterprises/balena", + "created_at": "2022-10-05T14:08:07Z", + "updated_at": "2024-10-04T08:57:35Z" + }, + "sender": { + "login": "klutchell", + "id": 20458272, + "node_id": "MDQ6VXNlcjIwNDU4Mjcy", + "avatar_url": "https://avatars.githubusercontent.com/u/20458272?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/klutchell", + "html_url": "https://github.com/klutchell", + "followers_url": "https://api.github.com/users/klutchell/followers", + "following_url": "https://api.github.com/users/klutchell/following{/other_user}", + "gists_url": "https://api.github.com/users/klutchell/gists{/gist_id}", + "starred_url": "https://api.github.com/users/klutchell/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/klutchell/subscriptions", + "organizations_url": "https://api.github.com/users/klutchell/orgs", + "repos_url": "https://api.github.com/users/klutchell/repos", + "events_url": "https://api.github.com/users/klutchell/events{/privacy}", + "received_events_url": "https://api.github.com/users/klutchell/received_events", + "type": "User", + "user_view_type": "public", + "site_admin": false + }, + "installation": { + "id": 57364329, + "node_id": "MDIzOkludGVncmF0aW9uSW5zdGFsbGF0aW9uNTczNjQzMjk=" + } +} From aba6452358a9b8a77d717a1d73fdb1236a1c2950 Mon Sep 17 00:00:00 2001 From: Kyle Harding Date: Thu, 21 Nov 2024 12:07:37 -0500 Subject: [PATCH 06/15] Rough in application logic Signed-off-by: Kyle Harding --- .husky/pre-commit | 1 + .lintstagedrc | 8 + README.md | 2 +- app.yml | 7 +- package-lock.json | 7056 ++++++++++++++++++++++++++---- package.json | 16 +- src/client.ts | 145 + src/index.ts | 215 +- test/fixtures/issues.opened.json | 18 - test/index.test.ts | 260 +- tsconfig.build.json | 34 + tsconfig.json | 38 +- 12 files changed, 6886 insertions(+), 914 deletions(-) create mode 100644 .husky/pre-commit create mode 100644 .lintstagedrc create mode 100644 src/client.ts delete mode 100644 test/fixtures/issues.opened.json create mode 100644 tsconfig.build.json diff --git a/.husky/pre-commit b/.husky/pre-commit new file mode 100644 index 0000000..718da8a --- /dev/null +++ b/.husky/pre-commit @@ -0,0 +1 @@ +npx --no lint-staged diff --git a/.lintstagedrc b/.lintstagedrc new file mode 100644 index 0000000..3b463ff --- /dev/null +++ b/.lintstagedrc @@ -0,0 +1,8 @@ +{ + "*.ts": [ + "balena-lint --fix" + ], + "*.js": [ + "balena-lint --fix" + ] +} diff --git a/README.md b/README.md index c957171..d4008e7 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Deployable -> A GitHub App built with [Probot](https://github.com/probot/probot) to Approve deployments via signed comments from maintainers +> A GitHub App built with [Probot](https://github.com/probot/probot) to Approve deployments via comments from maintainers ## Setup diff --git a/app.yml b/app.yml index a32b6f4..e931fae 100644 --- a/app.yml +++ b/app.yml @@ -57,6 +57,9 @@ default_permissions: # https://developer.github.com/v3/apps/permissions/#permission-on-administration # administration: read + # https://docs.github.com/en/rest/authentication/permissions-required-for-github-apps#repository-permissions-for-actions + actions: read + # Checks on code. # https://developer.github.com/v3/apps/permissions/#permission-on-checks # checks: read @@ -67,7 +70,7 @@ default_permissions: # Deployments and deployment statuses. # https://developer.github.com/v3/apps/permissions/#permission-on-deployments - deployments: read + deployments: write # Issues and related comments, assignees, labels, and milestones. # https://developer.github.com/v3/apps/permissions/#permission-on-issues @@ -131,7 +134,7 @@ name: Deployable url: https://github.com/balena-io-experimental/deployable # A description of the GitHub App. -description: Approve deployments via signed comments from maintainers +description: Approve deployments via comments from maintainers # Set to true when your GitHub App is available to the public or false when it is only accessible to the owner of the app. # Default: true diff --git a/package-lock.json b/package-lock.json index 07a48fe..a79ecc5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,19 +9,228 @@ "version": "1.0.0", "license": "Apache-2.0", "dependencies": { - "probot": "^13.0.1" + "probot": "^13.0.1", + "typescript": "^5.6.3" }, "devDependencies": { + "@balena/lint": "^9.1.2", "@types/node": "^20.0.0", + "husky": "^9.1.7", + "lint-staged": "^15.2.10", "nock": "^14.0.0-beta.5", "smee-client": "^2.0.0", - "typescript": "^5.3.3", "vitest": "^1.3.1" }, "engines": { "node": ">= 18" } }, + "node_modules/@babel/code-frame": { + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.2.tgz", + "integrity": "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.25.9", + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/code-frame/node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@babel/generator": { + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.2.tgz", + "integrity": "sha512-zevQbhbau95nkoxSq3f/DC/SC+EEOUZd3DYqfSkMhY2/wfSeaHV1Ew4vk8e+x8lja31IbyuUa2uQ3JONqKbysw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.26.2", + "@babel/types": "^7.26.0", + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz", + "integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz", + "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.2.tgz", + "integrity": "sha512-DWMCZH9WA4Maitz2q21SRKHo9QXZxkDsbNZoVD62gusNtNBBqDg9i7uOhASfTfIGNzW+O+r7+jAlM8dwphcJKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.26.0" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/template": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.9.tgz", + "integrity": "sha512-9DGttpmPvIxBb/2uwpVo3dqJ+O6RooAFOS+lB+xDqoE2PVCE8nfoHMdZLpfCQRLwvohzXISPZcgxt80xLfsuwg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.25.9", + "@babel/parser": "^7.25.9", + "@babel/types": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.9.tgz", + "integrity": "sha512-ZCuvfwOwlz/bawvAuvcj8rrithP2/N55Tzz342AkTvq4qaWbGfmCk/tKhNaV2cthijKrPAA8SRJV5WWe7IBMJw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.25.9", + "@babel/generator": "^7.25.9", + "@babel/parser": "^7.25.9", + "@babel/template": "^7.25.9", + "@babel/types": "^7.25.9", + "debug": "^4.3.1", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse/node_modules/debug": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/@babel/traverse/node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/traverse/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@babel/types": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.0.tgz", + "integrity": "sha512-Z/yiTPj+lDVnF7lWeKCIJzaIkI0vYO87dMpZ4bg4TDrFe4XXLFWL1TbXU27gBP3QccxV9mZICCrnjnYlJjXHOA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.25.9", + "@babel/helper-validator-identifier": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@balena/lint": { + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/@balena/lint/-/lint-9.1.2.tgz", + "integrity": "sha512-1PlFbNsj3gLoHUmY5VXf512J32Fks05iUdNLYmcbso5larcL5xRrkBLmoVTl8S+eIMcQh8fxJc73exVjslfDbQ==", + "dev": true, + "license": "Apache 2.0", + "dependencies": { + "@eslint/js": "^9.15.0", + "@typescript-eslint/eslint-plugin": "^8.15.0", + "@typescript-eslint/parser": "^8.15.0", + "depcheck": "^1.4.7", + "eslint": "^9.15.0", + "eslint-config-prettier": "^9.1.0", + "eslint-plugin-chai-friendly": "^1.0.1", + "eslint-plugin-jsdoc": "^50.5.0", + "eslint-plugin-no-only-tests": "^3.3.0", + "eslint-plugin-react": "^7.37.2", + "eslint-plugin-react-hooks": "^5.0.0", + "glob": "^11.0.0", + "globals": "^15.12.0", + "prettier": "^3.3.3", + "typescript": "^5.6.3", + "typescript-eslint": "^8.15.0", + "yargs": "^17.7.2" + }, + "bin": { + "balena-lint": "bin/balena-lint" + }, + "engines": { + "node": ">=20.17.0", + "npm": ">=9.8.1" + } + }, + "node_modules/@es-joy/jsdoccomment": { + "version": "0.49.0", + "resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.49.0.tgz", + "integrity": "sha512-xjZTSFgECpb9Ohuk5yMX5RhUEbfeQcuOp8IF60e+wyzWEF0M5xeSgqsfLtvPEX8BIyOX9saZqzuGPmZ8oWc+5Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "comment-parser": "1.4.1", + "esquery": "^1.6.0", + "jsdoc-type-pratt-parser": "~4.1.0" + }, + "engines": { + "node": ">=16" + } + }, "node_modules/@esbuild/aix-ppc64": { "version": "0.21.5", "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", @@ -413,233 +622,473 @@ "node": ">=12" } }, - "node_modules/@hapi/bourne": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@hapi/bourne/-/bourne-2.1.0.tgz", - "integrity": "sha512-i1BpaNDVLJdRBEKeJWkVO6tYX6DMFBuwMhSuWqLsY4ufeTKGVuV5rBsUhxPayXqnnWHgXUAmWK16H/ykO5Wj4Q==", - "license": "BSD-3-Clause" - }, - "node_modules/@ioredis/commands": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@ioredis/commands/-/commands-1.2.0.tgz", - "integrity": "sha512-Sx1pU8EM64o2BrqNpEO1CNLtKQwyhuXuqyfH7oGKCk+1a33d2r5saW8zNwm3j6BTExtjrv2BxTgzzkMwts6vGg==", - "license": "MIT" - }, - "node_modules/@jest/schemas": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", - "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "node_modules/@eslint-community/eslint-utils": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.1.tgz", + "integrity": "sha512-s3O3waFUrMV8P/XaF/+ZTp1X9XBZW1a4B97ZnjQF2KYWaFD2A8KyFBsrsfSjEmjn3RGWAIuvlneuZm3CUK3jbA==", "dev": true, "license": "MIT", "dependencies": { - "@sinclair/typebox": "^0.27.8" + "eslint-visitor-keys": "^3.4.3" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" } }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", - "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", + "node_modules/@eslint-community/regexpp": { + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", + "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", "dev": true, - "license": "MIT" + "license": "MIT", + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } }, - "node_modules/@mswjs/interceptors": { - "version": "0.36.5", - "resolved": "https://registry.npmjs.org/@mswjs/interceptors/-/interceptors-0.36.5.tgz", - "integrity": "sha512-aQ8WF5zQwOdcxLsxSEk9Jd01GgGb80xxqCaiDDlewhtwqpSm8MOvUHslwPydVirasdW09++NxDNNftm1vLY8yA==", + "node_modules/@eslint/config-array": { + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.19.0.tgz", + "integrity": "sha512-zdHg2FPIFNKPdcHWtiNT+jEFCHYVplAXRDlQDyqy0zGx/q2parwh7brGJSiTxRk/TSMkbM//zt/f5CHgyTyaSQ==", "dev": true, - "license": "MIT", + "license": "Apache-2.0", "dependencies": { - "@open-draft/deferred-promise": "^2.2.0", - "@open-draft/logger": "^0.3.0", - "@open-draft/until": "^2.0.0", - "is-node-process": "^1.2.0", - "outvariant": "^1.4.3", - "strict-event-emitter": "^0.5.1" + "@eslint/object-schema": "^2.1.4", + "debug": "^4.3.1", + "minimatch": "^3.1.2" }, "engines": { - "node": ">=18" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, - "node_modules/@octokit/auth-app": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/@octokit/auth-app/-/auth-app-6.1.2.tgz", - "integrity": "sha512-fWjIOpxnL8/YFY3kqquciFQ4o99aCqHw5kMFoGPYbz/h5HNZ11dJlV9zag5wS2nt0X1wJ5cs9BUo+CsAPfW4jQ==", + "node_modules/@eslint/config-array/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, "license": "MIT", "dependencies": { - "@octokit/auth-oauth-app": "^7.1.0", - "@octokit/auth-oauth-user": "^4.1.0", - "@octokit/request": "^8.3.1", - "@octokit/request-error": "^5.1.0", - "@octokit/types": "^13.1.0", - "deprecation": "^2.3.1", - "lru-cache": "^10.0.0", - "universal-github-app-jwt": "^1.1.2", - "universal-user-agent": "^6.0.0" - }, - "engines": { - "node": ">= 18" + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" } }, - "node_modules/@octokit/auth-app/node_modules/@octokit/openapi-types": { - "version": "22.2.0", - "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-22.2.0.tgz", - "integrity": "sha512-QBhVjcUa9W7Wwhm6DBFu6ZZ+1/t/oYxqc2tp81Pi41YNuJinbFRx8B133qVOrAaBbF7D/m0Et6f9/pZt9Rc+tg==", - "license": "MIT" - }, - "node_modules/@octokit/auth-app/node_modules/@octokit/types": { - "version": "13.6.1", - "resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.6.1.tgz", - "integrity": "sha512-PHZE9Z+kWXb23Ndik8MKPirBPziOc0D2/3KH1P+6jK5nGWe96kadZuE4jev2/Jq7FvIfTlT2Ltg8Fv2x1v0a5g==", + "node_modules/@eslint/config-array/node_modules/debug": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "dev": true, "license": "MIT", "dependencies": { - "@octokit/openapi-types": "^22.2.0" + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } } }, - "node_modules/@octokit/auth-oauth-app": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/@octokit/auth-oauth-app/-/auth-oauth-app-7.1.0.tgz", - "integrity": "sha512-w+SyJN/b0l/HEb4EOPRudo7uUOSW51jcK1jwLa+4r7PA8FPFpoxEnHBHMITqCsc/3Vo2qqFjgQfz/xUUvsSQnA==", - "license": "MIT", + "node_modules/@eslint/config-array/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", "dependencies": { - "@octokit/auth-oauth-device": "^6.1.0", - "@octokit/auth-oauth-user": "^4.1.0", - "@octokit/request": "^8.3.1", - "@octokit/types": "^13.0.0", - "@types/btoa-lite": "^1.0.0", - "btoa-lite": "^1.0.0", - "universal-user-agent": "^6.0.0" + "brace-expansion": "^1.1.7" }, "engines": { - "node": ">= 18" + "node": "*" } }, - "node_modules/@octokit/auth-oauth-app/node_modules/@octokit/openapi-types": { - "version": "22.2.0", - "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-22.2.0.tgz", - "integrity": "sha512-QBhVjcUa9W7Wwhm6DBFu6ZZ+1/t/oYxqc2tp81Pi41YNuJinbFRx8B133qVOrAaBbF7D/m0Et6f9/pZt9Rc+tg==", + "node_modules/@eslint/config-array/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, "license": "MIT" }, - "node_modules/@octokit/auth-oauth-app/node_modules/@octokit/types": { - "version": "13.6.1", - "resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.6.1.tgz", - "integrity": "sha512-PHZE9Z+kWXb23Ndik8MKPirBPziOc0D2/3KH1P+6jK5nGWe96kadZuE4jev2/Jq7FvIfTlT2Ltg8Fv2x1v0a5g==", - "license": "MIT", - "dependencies": { - "@octokit/openapi-types": "^22.2.0" + "node_modules/@eslint/core": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.9.0.tgz", + "integrity": "sha512-7ATR9F0e4W85D/0w7cU0SNj7qkAexMG+bAHEZOjo9akvGuhHE2m7umzWzfnpa0XAg5Kxc1BWmtPMV67jJ+9VUg==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, - "node_modules/@octokit/auth-oauth-device": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/@octokit/auth-oauth-device/-/auth-oauth-device-6.1.0.tgz", - "integrity": "sha512-FNQ7cb8kASufd6Ej4gnJ3f1QB5vJitkoV1O0/g6e6lUsQ7+VsSNRHRmFScN2tV4IgKA12frrr/cegUs0t+0/Lw==", + "node_modules/@eslint/eslintrc": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.2.0.tgz", + "integrity": "sha512-grOjVNN8P3hjJn/eIETF1wwd12DdnwFDoyceUJLYYdkpbwq3nLi+4fqrTAONx7XDALqlL220wC/RHSC/QTI/0w==", + "dev": true, "license": "MIT", "dependencies": { - "@octokit/oauth-methods": "^4.1.0", - "@octokit/request": "^8.3.1", - "@octokit/types": "^13.0.0", - "universal-user-agent": "^6.0.0" + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^10.0.1", + "globals": "^14.0.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" }, "engines": { - "node": ">= 18" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, - "node_modules/@octokit/auth-oauth-device/node_modules/@octokit/openapi-types": { - "version": "22.2.0", - "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-22.2.0.tgz", - "integrity": "sha512-QBhVjcUa9W7Wwhm6DBFu6ZZ+1/t/oYxqc2tp81Pi41YNuJinbFRx8B133qVOrAaBbF7D/m0Et6f9/pZt9Rc+tg==", - "license": "MIT" - }, - "node_modules/@octokit/auth-oauth-device/node_modules/@octokit/types": { - "version": "13.6.1", - "resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.6.1.tgz", - "integrity": "sha512-PHZE9Z+kWXb23Ndik8MKPirBPziOc0D2/3KH1P+6jK5nGWe96kadZuE4jev2/Jq7FvIfTlT2Ltg8Fv2x1v0a5g==", + "node_modules/@eslint/eslintrc/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, "license": "MIT", "dependencies": { - "@octokit/openapi-types": "^22.2.0" + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" } }, - "node_modules/@octokit/auth-oauth-user": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@octokit/auth-oauth-user/-/auth-oauth-user-4.1.0.tgz", - "integrity": "sha512-FrEp8mtFuS/BrJyjpur+4GARteUCrPeR/tZJzD8YourzoVhRics7u7we/aDcKv+yywRNwNi/P4fRi631rG/OyQ==", + "node_modules/@eslint/eslintrc/node_modules/debug": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "dev": true, "license": "MIT", "dependencies": { - "@octokit/auth-oauth-device": "^6.1.0", - "@octokit/oauth-methods": "^4.1.0", - "@octokit/request": "^8.3.1", - "@octokit/types": "^13.0.0", - "btoa-lite": "^1.0.0", - "universal-user-agent": "^6.0.0" + "ms": "^2.1.3" }, "engines": { - "node": ">= 18" + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } } }, - "node_modules/@octokit/auth-oauth-user/node_modules/@octokit/openapi-types": { - "version": "22.2.0", - "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-22.2.0.tgz", - "integrity": "sha512-QBhVjcUa9W7Wwhm6DBFu6ZZ+1/t/oYxqc2tp81Pi41YNuJinbFRx8B133qVOrAaBbF7D/m0Et6f9/pZt9Rc+tg==", + "node_modules/@eslint/eslintrc/node_modules/globals": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", + "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@eslint/eslintrc/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@eslint/eslintrc/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, "license": "MIT" }, - "node_modules/@octokit/auth-oauth-user/node_modules/@octokit/types": { - "version": "13.6.1", - "resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.6.1.tgz", - "integrity": "sha512-PHZE9Z+kWXb23Ndik8MKPirBPziOc0D2/3KH1P+6jK5nGWe96kadZuE4jev2/Jq7FvIfTlT2Ltg8Fv2x1v0a5g==", + "node_modules/@eslint/js": { + "version": "9.15.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.15.0.tgz", + "integrity": "sha512-tMTqrY+EzbXmKJR5ToI8lxu7jaN5EdmrBFJpQk5JmSlyLsx6o4t27r883K5xsLuCYCpfKBCGswMSWXsM+jB7lg==", + "dev": true, "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/object-schema": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.4.tgz", + "integrity": "sha512-BsWiH1yFGjXXS2yvrf5LyuoSIIbPrGUWob917o+BTKuZ7qJdxX8aJLRxs1fS9n6r7vESrq1OUqb68dANcFXuQQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/plugin-kit": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.3.tgz", + "integrity": "sha512-2b/g5hRmpbb1o4GnTZax9N9m0FXzz9OV42ZzI4rDDMDuHUqigAiQCEWChBWCY4ztAGVRjoWT19v0yMmc5/L5kA==", + "dev": true, + "license": "Apache-2.0", "dependencies": { - "@octokit/openapi-types": "^22.2.0" + "levn": "^0.4.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, - "node_modules/@octokit/auth-token": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-4.0.0.tgz", - "integrity": "sha512-tY/msAuJo6ARbK6SPIxZrPBms3xPbfwBrulZe0Wtr/DIY9lje2HeV1uoebShn6mx7SjCHif6EjMvoREj+gZ+SA==", + "node_modules/@hapi/bourne": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@hapi/bourne/-/bourne-2.1.0.tgz", + "integrity": "sha512-i1BpaNDVLJdRBEKeJWkVO6tYX6DMFBuwMhSuWqLsY4ufeTKGVuV5rBsUhxPayXqnnWHgXUAmWK16H/ykO5Wj4Q==", + "license": "BSD-3-Clause" + }, + "node_modules/@humanfs/core": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", + "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node": { + "version": "0.16.6", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.6.tgz", + "integrity": "sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanfs/core": "^0.19.1", + "@humanwhocodes/retry": "^0.3.0" + }, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node/node_modules/@humanwhocodes/retry": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.1.tgz", + "integrity": "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/retry": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.1.tgz", + "integrity": "sha512-c7hNEllBlenFTHBky65mhq8WD2kbN9Q6gk0bTk8lSBvc554jpXSkST1iePudpt7+A/AQvuHs9EMqjHDXMY1lrA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@ioredis/commands": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ioredis/commands/-/commands-1.2.0.tgz", + "integrity": "sha512-Sx1pU8EM64o2BrqNpEO1CNLtKQwyhuXuqyfH7oGKCk+1a33d2r5saW8zNwm3j6BTExtjrv2BxTgzzkMwts6vGg==", + "license": "MIT" + }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "dev": true, "license": "MIT", + "dependencies": { + "@sinclair/typebox": "^0.27.8" + }, "engines": { - "node": ">= 18" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@octokit/auth-unauthenticated": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/@octokit/auth-unauthenticated/-/auth-unauthenticated-5.0.1.tgz", - "integrity": "sha512-oxeWzmBFxWd+XolxKTc4zr+h3mt+yofn4r7OfoIkR/Cj/o70eEGmPsFbueyJE2iBAGpjgTnEOKM3pnuEGVmiqg==", + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", + "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", + "dev": true, "license": "MIT", "dependencies": { - "@octokit/request-error": "^5.0.0", - "@octokit/types": "^12.0.0" + "@jridgewell/set-array": "^1.2.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.24" }, "engines": { - "node": ">= 18" + "node": ">=6.0.0" } }, - "node_modules/@octokit/core": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@octokit/core/-/core-5.2.0.tgz", - "integrity": "sha512-1LFfa/qnMQvEOAdzlQymH0ulepxbxnCYAKJZfMci/5XJyIHWgEYnDmgnKakbTh7CH2tFQ5O60oYDvns4i9RAIg==", + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "dev": true, "license": "MIT", "dependencies": { - "@octokit/auth-token": "^4.0.0", - "@octokit/graphql": "^7.1.0", + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@mswjs/interceptors": { + "version": "0.36.5", + "resolved": "https://registry.npmjs.org/@mswjs/interceptors/-/interceptors-0.36.5.tgz", + "integrity": "sha512-aQ8WF5zQwOdcxLsxSEk9Jd01GgGb80xxqCaiDDlewhtwqpSm8MOvUHslwPydVirasdW09++NxDNNftm1vLY8yA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@open-draft/deferred-promise": "^2.2.0", + "@open-draft/logger": "^0.3.0", + "@open-draft/until": "^2.0.0", + "is-node-process": "^1.2.0", + "outvariant": "^1.4.3", + "strict-event-emitter": "^0.5.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@octokit/auth-app": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@octokit/auth-app/-/auth-app-6.1.2.tgz", + "integrity": "sha512-fWjIOpxnL8/YFY3kqquciFQ4o99aCqHw5kMFoGPYbz/h5HNZ11dJlV9zag5wS2nt0X1wJ5cs9BUo+CsAPfW4jQ==", + "license": "MIT", + "dependencies": { + "@octokit/auth-oauth-app": "^7.1.0", + "@octokit/auth-oauth-user": "^4.1.0", "@octokit/request": "^8.3.1", "@octokit/request-error": "^5.1.0", - "@octokit/types": "^13.0.0", - "before-after-hook": "^2.2.0", + "@octokit/types": "^13.1.0", + "deprecation": "^2.3.1", + "lru-cache": "^10.0.0", + "universal-github-app-jwt": "^1.1.2", "universal-user-agent": "^6.0.0" }, "engines": { "node": ">= 18" } }, - "node_modules/@octokit/core/node_modules/@octokit/openapi-types": { + "node_modules/@octokit/auth-app/node_modules/@octokit/openapi-types": { "version": "22.2.0", "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-22.2.0.tgz", "integrity": "sha512-QBhVjcUa9W7Wwhm6DBFu6ZZ+1/t/oYxqc2tp81Pi41YNuJinbFRx8B133qVOrAaBbF7D/m0Et6f9/pZt9Rc+tg==", "license": "MIT" }, - "node_modules/@octokit/core/node_modules/@octokit/types": { + "node_modules/@octokit/auth-app/node_modules/@octokit/types": { "version": "13.6.1", "resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.6.1.tgz", "integrity": "sha512-PHZE9Z+kWXb23Ndik8MKPirBPziOc0D2/3KH1P+6jK5nGWe96kadZuE4jev2/Jq7FvIfTlT2Ltg8Fv2x1v0a5g==", @@ -648,26 +1097,31 @@ "@octokit/openapi-types": "^22.2.0" } }, - "node_modules/@octokit/endpoint": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-9.0.5.tgz", - "integrity": "sha512-ekqR4/+PCLkEBF6qgj8WqJfvDq65RH85OAgrtnVp1mSxaXF03u2xW/hUdweGS5654IlC0wkNYC18Z50tSYTAFw==", + "node_modules/@octokit/auth-oauth-app": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@octokit/auth-oauth-app/-/auth-oauth-app-7.1.0.tgz", + "integrity": "sha512-w+SyJN/b0l/HEb4EOPRudo7uUOSW51jcK1jwLa+4r7PA8FPFpoxEnHBHMITqCsc/3Vo2qqFjgQfz/xUUvsSQnA==", "license": "MIT", "dependencies": { - "@octokit/types": "^13.1.0", + "@octokit/auth-oauth-device": "^6.1.0", + "@octokit/auth-oauth-user": "^4.1.0", + "@octokit/request": "^8.3.1", + "@octokit/types": "^13.0.0", + "@types/btoa-lite": "^1.0.0", + "btoa-lite": "^1.0.0", "universal-user-agent": "^6.0.0" }, "engines": { "node": ">= 18" } }, - "node_modules/@octokit/endpoint/node_modules/@octokit/openapi-types": { + "node_modules/@octokit/auth-oauth-app/node_modules/@octokit/openapi-types": { "version": "22.2.0", "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-22.2.0.tgz", "integrity": "sha512-QBhVjcUa9W7Wwhm6DBFu6ZZ+1/t/oYxqc2tp81Pi41YNuJinbFRx8B133qVOrAaBbF7D/m0Et6f9/pZt9Rc+tg==", "license": "MIT" }, - "node_modules/@octokit/endpoint/node_modules/@octokit/types": { + "node_modules/@octokit/auth-oauth-app/node_modules/@octokit/types": { "version": "13.6.1", "resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.6.1.tgz", "integrity": "sha512-PHZE9Z+kWXb23Ndik8MKPirBPziOc0D2/3KH1P+6jK5nGWe96kadZuE4jev2/Jq7FvIfTlT2Ltg8Fv2x1v0a5g==", @@ -676,13 +1130,14 @@ "@octokit/openapi-types": "^22.2.0" } }, - "node_modules/@octokit/graphql": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-7.1.0.tgz", - "integrity": "sha512-r+oZUH7aMFui1ypZnAvZmn0KSqAUgE1/tUXIWaqUCa1758ts/Jio84GZuzsvUkme98kv0WFY8//n0J1Z+vsIsQ==", + "node_modules/@octokit/auth-oauth-device": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/@octokit/auth-oauth-device/-/auth-oauth-device-6.1.0.tgz", + "integrity": "sha512-FNQ7cb8kASufd6Ej4gnJ3f1QB5vJitkoV1O0/g6e6lUsQ7+VsSNRHRmFScN2tV4IgKA12frrr/cegUs0t+0/Lw==", "license": "MIT", "dependencies": { - "@octokit/request": "^8.3.0", + "@octokit/oauth-methods": "^4.1.0", + "@octokit/request": "^8.3.1", "@octokit/types": "^13.0.0", "universal-user-agent": "^6.0.0" }, @@ -690,13 +1145,157 @@ "node": ">= 18" } }, - "node_modules/@octokit/graphql/node_modules/@octokit/openapi-types": { + "node_modules/@octokit/auth-oauth-device/node_modules/@octokit/openapi-types": { "version": "22.2.0", "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-22.2.0.tgz", "integrity": "sha512-QBhVjcUa9W7Wwhm6DBFu6ZZ+1/t/oYxqc2tp81Pi41YNuJinbFRx8B133qVOrAaBbF7D/m0Et6f9/pZt9Rc+tg==", "license": "MIT" }, - "node_modules/@octokit/graphql/node_modules/@octokit/types": { + "node_modules/@octokit/auth-oauth-device/node_modules/@octokit/types": { + "version": "13.6.1", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.6.1.tgz", + "integrity": "sha512-PHZE9Z+kWXb23Ndik8MKPirBPziOc0D2/3KH1P+6jK5nGWe96kadZuE4jev2/Jq7FvIfTlT2Ltg8Fv2x1v0a5g==", + "license": "MIT", + "dependencies": { + "@octokit/openapi-types": "^22.2.0" + } + }, + "node_modules/@octokit/auth-oauth-user": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@octokit/auth-oauth-user/-/auth-oauth-user-4.1.0.tgz", + "integrity": "sha512-FrEp8mtFuS/BrJyjpur+4GARteUCrPeR/tZJzD8YourzoVhRics7u7we/aDcKv+yywRNwNi/P4fRi631rG/OyQ==", + "license": "MIT", + "dependencies": { + "@octokit/auth-oauth-device": "^6.1.0", + "@octokit/oauth-methods": "^4.1.0", + "@octokit/request": "^8.3.1", + "@octokit/types": "^13.0.0", + "btoa-lite": "^1.0.0", + "universal-user-agent": "^6.0.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@octokit/auth-oauth-user/node_modules/@octokit/openapi-types": { + "version": "22.2.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-22.2.0.tgz", + "integrity": "sha512-QBhVjcUa9W7Wwhm6DBFu6ZZ+1/t/oYxqc2tp81Pi41YNuJinbFRx8B133qVOrAaBbF7D/m0Et6f9/pZt9Rc+tg==", + "license": "MIT" + }, + "node_modules/@octokit/auth-oauth-user/node_modules/@octokit/types": { + "version": "13.6.1", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.6.1.tgz", + "integrity": "sha512-PHZE9Z+kWXb23Ndik8MKPirBPziOc0D2/3KH1P+6jK5nGWe96kadZuE4jev2/Jq7FvIfTlT2Ltg8Fv2x1v0a5g==", + "license": "MIT", + "dependencies": { + "@octokit/openapi-types": "^22.2.0" + } + }, + "node_modules/@octokit/auth-token": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-4.0.0.tgz", + "integrity": "sha512-tY/msAuJo6ARbK6SPIxZrPBms3xPbfwBrulZe0Wtr/DIY9lje2HeV1uoebShn6mx7SjCHif6EjMvoREj+gZ+SA==", + "license": "MIT", + "engines": { + "node": ">= 18" + } + }, + "node_modules/@octokit/auth-unauthenticated": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@octokit/auth-unauthenticated/-/auth-unauthenticated-5.0.1.tgz", + "integrity": "sha512-oxeWzmBFxWd+XolxKTc4zr+h3mt+yofn4r7OfoIkR/Cj/o70eEGmPsFbueyJE2iBAGpjgTnEOKM3pnuEGVmiqg==", + "license": "MIT", + "dependencies": { + "@octokit/request-error": "^5.0.0", + "@octokit/types": "^12.0.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@octokit/core": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@octokit/core/-/core-5.2.0.tgz", + "integrity": "sha512-1LFfa/qnMQvEOAdzlQymH0ulepxbxnCYAKJZfMci/5XJyIHWgEYnDmgnKakbTh7CH2tFQ5O60oYDvns4i9RAIg==", + "license": "MIT", + "dependencies": { + "@octokit/auth-token": "^4.0.0", + "@octokit/graphql": "^7.1.0", + "@octokit/request": "^8.3.1", + "@octokit/request-error": "^5.1.0", + "@octokit/types": "^13.0.0", + "before-after-hook": "^2.2.0", + "universal-user-agent": "^6.0.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@octokit/core/node_modules/@octokit/openapi-types": { + "version": "22.2.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-22.2.0.tgz", + "integrity": "sha512-QBhVjcUa9W7Wwhm6DBFu6ZZ+1/t/oYxqc2tp81Pi41YNuJinbFRx8B133qVOrAaBbF7D/m0Et6f9/pZt9Rc+tg==", + "license": "MIT" + }, + "node_modules/@octokit/core/node_modules/@octokit/types": { + "version": "13.6.1", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.6.1.tgz", + "integrity": "sha512-PHZE9Z+kWXb23Ndik8MKPirBPziOc0D2/3KH1P+6jK5nGWe96kadZuE4jev2/Jq7FvIfTlT2Ltg8Fv2x1v0a5g==", + "license": "MIT", + "dependencies": { + "@octokit/openapi-types": "^22.2.0" + } + }, + "node_modules/@octokit/endpoint": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-9.0.5.tgz", + "integrity": "sha512-ekqR4/+PCLkEBF6qgj8WqJfvDq65RH85OAgrtnVp1mSxaXF03u2xW/hUdweGS5654IlC0wkNYC18Z50tSYTAFw==", + "license": "MIT", + "dependencies": { + "@octokit/types": "^13.1.0", + "universal-user-agent": "^6.0.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@octokit/endpoint/node_modules/@octokit/openapi-types": { + "version": "22.2.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-22.2.0.tgz", + "integrity": "sha512-QBhVjcUa9W7Wwhm6DBFu6ZZ+1/t/oYxqc2tp81Pi41YNuJinbFRx8B133qVOrAaBbF7D/m0Et6f9/pZt9Rc+tg==", + "license": "MIT" + }, + "node_modules/@octokit/endpoint/node_modules/@octokit/types": { + "version": "13.6.1", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.6.1.tgz", + "integrity": "sha512-PHZE9Z+kWXb23Ndik8MKPirBPziOc0D2/3KH1P+6jK5nGWe96kadZuE4jev2/Jq7FvIfTlT2Ltg8Fv2x1v0a5g==", + "license": "MIT", + "dependencies": { + "@octokit/openapi-types": "^22.2.0" + } + }, + "node_modules/@octokit/graphql": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-7.1.0.tgz", + "integrity": "sha512-r+oZUH7aMFui1ypZnAvZmn0KSqAUgE1/tUXIWaqUCa1758ts/Jio84GZuzsvUkme98kv0WFY8//n0J1Z+vsIsQ==", + "license": "MIT", + "dependencies": { + "@octokit/request": "^8.3.0", + "@octokit/types": "^13.0.0", + "universal-user-agent": "^6.0.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@octokit/graphql/node_modules/@octokit/openapi-types": { + "version": "22.2.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-22.2.0.tgz", + "integrity": "sha512-QBhVjcUa9W7Wwhm6DBFu6ZZ+1/t/oYxqc2tp81Pi41YNuJinbFRx8B133qVOrAaBbF7D/m0Et6f9/pZt9Rc+tg==", + "license": "MIT" + }, + "node_modules/@octokit/graphql/node_modules/@octokit/types": { "version": "13.6.1", "resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.6.1.tgz", "integrity": "sha512-PHZE9Z+kWXb23Ndik8MKPirBPziOc0D2/3KH1P+6jK5nGWe96kadZuE4jev2/Jq7FvIfTlT2Ltg8Fv2x1v0a5g==", @@ -950,6 +1549,19 @@ "dev": true, "license": "MIT" }, + "node_modules/@pkgr/core": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.1.1.tgz", + "integrity": "sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/unts" + } + }, "node_modules/@probot/get-private-key": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@probot/get-private-key/-/get-private-key-1.1.2.tgz", @@ -1359,6 +1971,13 @@ "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==", "license": "MIT" }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/jsonwebtoken": { "version": "9.0.7", "resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-9.0.7.tgz", @@ -1374,6 +1993,13 @@ "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==", "license": "MIT" }, + "node_modules/@types/minimatch": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz", + "integrity": "sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/node": { "version": "20.16.12", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.16.12.tgz", @@ -1383,6 +2009,13 @@ "undici-types": "~6.19.2" } }, + "node_modules/@types/parse-json": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz", + "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/qs": { "version": "6.9.16", "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.16.tgz", @@ -1416,96 +2049,457 @@ "@types/send": "*" } }, - "node_modules/@vitest/expect": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-1.6.0.tgz", - "integrity": "sha512-ixEvFVQjycy/oNgHjqsL6AZCDduC+tflRluaHIzKIsdbzkLn2U/iBnVeJwB6HsIjQBdfMR8Z0tRxKUsvFJEeWQ==", + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.15.0.tgz", + "integrity": "sha512-+zkm9AR1Ds9uLWN3fkoeXgFppaQ+uEVtfOV62dDmsy9QCNqlRHWNEck4yarvRNrvRcHQLGfqBNui3cimoz8XAg==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/spy": "1.6.0", - "@vitest/utils": "1.6.0", - "chai": "^4.3.10" + "@eslint-community/regexpp": "^4.10.0", + "@typescript-eslint/scope-manager": "8.15.0", + "@typescript-eslint/type-utils": "8.15.0", + "@typescript-eslint/utils": "8.15.0", + "@typescript-eslint/visitor-keys": "8.15.0", + "graphemer": "^1.4.0", + "ignore": "^5.3.1", + "natural-compare": "^1.4.0", + "ts-api-utils": "^1.3.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { - "url": "https://opencollective.com/vitest" + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^8.0.0 || ^8.0.0-alpha.0", + "eslint": "^8.57.0 || ^9.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, - "node_modules/@vitest/runner": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-1.6.0.tgz", - "integrity": "sha512-P4xgwPjwesuBiHisAVz/LSSZtDjOTPYZVmNAnpHHSR6ONrf8eCJOFRvUwdHn30F5M1fxhqtl7QZQUk2dprIXAg==", + "node_modules/@typescript-eslint/parser": { + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.15.0.tgz", + "integrity": "sha512-7n59qFpghG4uazrF9qtGKBZXn7Oz4sOMm8dwNWDQY96Xlm2oX67eipqcblDj+oY1lLCbf1oltMZFpUso66Kl1A==", "dev": true, - "license": "MIT", + "license": "BSD-2-Clause", "dependencies": { - "@vitest/utils": "1.6.0", - "p-limit": "^5.0.0", - "pathe": "^1.1.1" + "@typescript-eslint/scope-manager": "8.15.0", + "@typescript-eslint/types": "8.15.0", + "@typescript-eslint/typescript-estree": "8.15.0", + "@typescript-eslint/visitor-keys": "8.15.0", + "debug": "^4.3.4" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { - "url": "https://opencollective.com/vitest" + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, - "node_modules/@vitest/runner/node_modules/p-limit": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-5.0.0.tgz", - "integrity": "sha512-/Eaoq+QyLSiXQ4lyYV23f14mZRQcXnxfHrN0vCai+ak9G0pp9iEQukIIZq5NccEvwRB8PUnZT0KsOoDCINS1qQ==", + "node_modules/@typescript-eslint/parser/node_modules/debug": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", "dev": true, "license": "MIT", "dependencies": { - "yocto-queue": "^1.0.0" + "ms": "^2.1.3" }, "engines": { - "node": ">=18" + "node": ">=6.0" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } } }, - "node_modules/@vitest/snapshot": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-1.6.0.tgz", - "integrity": "sha512-+Hx43f8Chus+DCmygqqfetcAZrDJwvTj0ymqjQq4CvmpKFSTVteEOBzCusu1x2tt4OJcvBflyHUE0DZSLgEMtQ==", + "node_modules/@typescript-eslint/parser/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.15.0.tgz", + "integrity": "sha512-QRGy8ADi4J7ii95xz4UoiymmmMd/zuy9azCaamnZ3FM8T5fZcex8UfJcjkiEZjJSztKfEBe3dZ5T/5RHAmw2mA==", "dev": true, "license": "MIT", "dependencies": { - "magic-string": "^0.30.5", - "pathe": "^1.1.1", - "pretty-format": "^29.7.0" + "@typescript-eslint/types": "8.15.0", + "@typescript-eslint/visitor-keys": "8.15.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { - "url": "https://opencollective.com/vitest" + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@vitest/spy": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-1.6.0.tgz", - "integrity": "sha512-leUTap6B/cqi/bQkXUu6bQV5TZPx7pmMBKBQiI0rJA8c3pB56ZsaTbREnF7CJfmvAS4V2cXIBAh/3rVwrrCYgw==", + "node_modules/@typescript-eslint/type-utils": { + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.15.0.tgz", + "integrity": "sha512-UU6uwXDoI3JGSXmcdnP5d8Fffa2KayOhUUqr/AiBnG1Gl7+7ut/oyagVeSkh7bxQ0zSXV9ptRh/4N15nkCqnpw==", "dev": true, "license": "MIT", "dependencies": { - "tinyspy": "^2.2.0" + "@typescript-eslint/typescript-estree": "8.15.0", + "@typescript-eslint/utils": "8.15.0", + "debug": "^4.3.4", + "ts-api-utils": "^1.3.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { - "url": "https://opencollective.com/vitest" + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, - "node_modules/@vitest/utils": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-1.6.0.tgz", - "integrity": "sha512-21cPiuGMoMZwiOHa2i4LXkMkMkCGzA+MVFV70jRwHo95dL4x/ts5GZhML1QWuy7yfp3WzK3lRvZi3JnXTYqrBw==", + "node_modules/@typescript-eslint/type-utils/node_modules/debug": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", "dev": true, "license": "MIT", "dependencies": { - "diff-sequences": "^29.6.3", - "estree-walker": "^3.0.3", - "loupe": "^2.3.7", + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/type-utils/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@typescript-eslint/types": { + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.15.0.tgz", + "integrity": "sha512-n3Gt8Y/KyJNe0S3yDCD2RVKrHBC4gTUcLTebVBXacPy091E6tNspFLKRXlk3hwT4G55nfr1n2AdFqi/XMxzmPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.15.0.tgz", + "integrity": "sha512-1eMp2JgNec/niZsR7ioFBlsh/Fk0oJbhaqO0jRyQBMgkz7RrFfkqF9lYYmBoGBaSiLnu8TAPQTwoTUiSTUW9dg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "@typescript-eslint/types": "8.15.0", + "@typescript-eslint/visitor-keys": "8.15.0", + "debug": "^4.3.4", + "fast-glob": "^3.3.2", + "is-glob": "^4.0.3", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^1.3.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/debug": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@typescript-eslint/utils": { + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.15.0.tgz", + "integrity": "sha512-k82RI9yGhr0QM3Dnq+egEpz9qB6Un+WLYhmoNcvl8ltMEededhh7otBVVIDDsEEttauwdY/hQoSsOv13lxrFzQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.0", + "@typescript-eslint/scope-manager": "8.15.0", + "@typescript-eslint/types": "8.15.0", + "@typescript-eslint/typescript-estree": "8.15.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.15.0.tgz", + "integrity": "sha512-h8vYOulWec9LhpwfAdZf2bjr8xIp0KNKnpgqSz0qqYYKAW/QZKw3ktRndbiAtUz4acH4QLQavwZBYCc0wulA/Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.15.0", + "eslint-visitor-keys": "^4.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz", + "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@vitest/expect": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-1.6.0.tgz", + "integrity": "sha512-ixEvFVQjycy/oNgHjqsL6AZCDduC+tflRluaHIzKIsdbzkLn2U/iBnVeJwB6HsIjQBdfMR8Z0tRxKUsvFJEeWQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/spy": "1.6.0", + "@vitest/utils": "1.6.0", + "chai": "^4.3.10" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/runner": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-1.6.0.tgz", + "integrity": "sha512-P4xgwPjwesuBiHisAVz/LSSZtDjOTPYZVmNAnpHHSR6ONrf8eCJOFRvUwdHn30F5M1fxhqtl7QZQUk2dprIXAg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/utils": "1.6.0", + "p-limit": "^5.0.0", + "pathe": "^1.1.1" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/runner/node_modules/p-limit": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-5.0.0.tgz", + "integrity": "sha512-/Eaoq+QyLSiXQ4lyYV23f14mZRQcXnxfHrN0vCai+ak9G0pp9iEQukIIZq5NccEvwRB8PUnZT0KsOoDCINS1qQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^1.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@vitest/snapshot": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-1.6.0.tgz", + "integrity": "sha512-+Hx43f8Chus+DCmygqqfetcAZrDJwvTj0ymqjQq4CvmpKFSTVteEOBzCusu1x2tt4OJcvBflyHUE0DZSLgEMtQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "magic-string": "^0.30.5", + "pathe": "^1.1.1", + "pretty-format": "^29.7.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/spy": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-1.6.0.tgz", + "integrity": "sha512-leUTap6B/cqi/bQkXUu6bQV5TZPx7pmMBKBQiI0rJA8c3pB56ZsaTbREnF7CJfmvAS4V2cXIBAh/3rVwrrCYgw==", + "dev": true, + "license": "MIT", + "dependencies": { + "tinyspy": "^2.2.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/utils": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-1.6.0.tgz", + "integrity": "sha512-21cPiuGMoMZwiOHa2i4LXkMkMkCGzA+MVFV70jRwHo95dL4x/ts5GZhML1QWuy7yfp3WzK3lRvZi3JnXTYqrBw==", + "dev": true, + "license": "MIT", + "dependencies": { + "diff-sequences": "^29.6.3", + "estree-walker": "^3.0.3", + "loupe": "^2.3.7", "pretty-format": "^29.7.0" }, "funding": { "url": "https://opencollective.com/vitest" } }, + "node_modules/@vue/compiler-core": { + "version": "3.5.13", + "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.13.tgz", + "integrity": "sha512-oOdAkwqUfW1WqpwSYJce06wvt6HljgY3fGeM9NcVA1HaYOij3mZG9Rkysn0OHuyUAGMbEbARIpsG+LPVlBJ5/Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.25.3", + "@vue/shared": "3.5.13", + "entities": "^4.5.0", + "estree-walker": "^2.0.2", + "source-map-js": "^1.2.0" + } + }, + "node_modules/@vue/compiler-core/node_modules/estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@vue/compiler-dom": { + "version": "3.5.13", + "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.13.tgz", + "integrity": "sha512-ZOJ46sMOKUjO3e94wPdCzQ6P1Lx/vhp2RSvfaab88Ajexs0AHeV0uasYhi99WPaogmBlRHNRuly8xV75cNTMDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vue/compiler-core": "3.5.13", + "@vue/shared": "3.5.13" + } + }, + "node_modules/@vue/compiler-sfc": { + "version": "3.5.13", + "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.13.tgz", + "integrity": "sha512-6VdaljMpD82w6c2749Zhf5T9u5uLBWKnVue6XWxprDobftnletJ8+oel7sexFfM3qIxNmVE7LSFGTpv6obNyaQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.25.3", + "@vue/compiler-core": "3.5.13", + "@vue/compiler-dom": "3.5.13", + "@vue/compiler-ssr": "3.5.13", + "@vue/shared": "3.5.13", + "estree-walker": "^2.0.2", + "magic-string": "^0.30.11", + "postcss": "^8.4.48", + "source-map-js": "^1.2.0" + } + }, + "node_modules/@vue/compiler-sfc/node_modules/estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@vue/compiler-ssr": { + "version": "3.5.13", + "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.13.tgz", + "integrity": "sha512-wMH6vrYHxQl/IybKJagqbquvxpWCuVYpoUJfCqFZwa/JY1GdATAQ+TgVtgrwwMZ0D07QhA99rs/EAAWfvG6KpA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vue/compiler-dom": "3.5.13", + "@vue/shared": "3.5.13" + } + }, + "node_modules/@vue/shared": { + "version": "3.5.13", + "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.13.tgz", + "integrity": "sha512-/hnE/qP5ZoGpol0a5mDi45bOd7t3tjYJBjsgCsivow7D48cJeV5l05RD82lPqi7gRiphZM37rnhW1l6ZoCNNnQ==", + "dev": true, + "license": "MIT" + }, "node_modules/accepts": { "version": "1.3.8", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", @@ -1520,9 +2514,9 @@ } }, "node_modules/acorn": { - "version": "8.13.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.13.0.tgz", - "integrity": "sha512-8zSiw54Oxrdym50NlZ9sUusyO1Z1ZchgRLWRaK6c86XJFClyCgFKetdowBg5bKxyp/u+CDBJG4Mpp0m3HLZl9w==", + "version": "8.14.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", + "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", "dev": true, "license": "MIT", "bin": { @@ -1532,6 +2526,16 @@ "node": ">=0.4.0" } }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, "node_modules/acorn-walk": { "version": "8.3.4", "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz", @@ -1558,6 +2562,52 @@ "node": ">=8" } }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ansi-escapes": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-7.0.0.tgz", + "integrity": "sha512-GdYO7a61mR0fOlAsvC9/rIHf7L96sBc6dEWzeOu+KAea5bZyQRPIpojrVoI4AXGJS/ycu/fBTdLrUkA4ODrvjw==", + "dev": true, + "license": "MIT", + "dependencies": { + "environment": "^1.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-regex": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, "node_modules/ansi-styles": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", @@ -1570,6 +2620,16 @@ "node": ">=4" } }, + "node_modules/are-docs-informative": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/are-docs-informative/-/are-docs-informative-0.0.2.tgz", + "integrity": "sha512-ixiS0nLNNG5jNQzgZJNoUpBKdo9yTYZMGJ+QgT2jmjR7G7+QHRCc4v6LQ3NgE7EBJq+o0ams3waJwkrlBom8Ig==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14" + } + }, "node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", @@ -1591,12 +2651,179 @@ "node": ">= 6.0.0" } }, - "node_modules/array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", + "node_modules/array-buffer-byte-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz", + "integrity": "sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.5", + "is-array-buffer": "^3.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array-differ": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-3.0.0.tgz", + "integrity": "sha512-THtfYS6KtME/yIAhKjZ2ul7XI96lQGHRputJQHO80LAWQnuGP4iCIN8vdMRboGbIEYBwU33q8Tch1os2+X0kMg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", "license": "MIT" }, + "node_modules/array-includes": { + "version": "3.1.8", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.8.tgz", + "integrity": "sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.4", + "is-string": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/array.prototype.findlast": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/array.prototype.findlast/-/array.prototype.findlast-1.2.5.tgz", + "integrity": "sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flat": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz", + "integrity": "sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flatmap": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz", + "integrity": "sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.tosorted": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.4.tgz", + "integrity": "sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.3", + "es-errors": "^1.3.0", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/arraybuffer.prototype.slice": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.3.tgz", + "integrity": "sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-buffer-byte-length": "^1.0.1", + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "es-abstract": "^1.22.3", + "es-errors": "^1.2.1", + "get-intrinsic": "^1.2.3", + "is-array-buffer": "^3.0.4", + "is-shared-array-buffer": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/arrify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", + "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/assertion-error": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", @@ -1616,6 +2843,29 @@ "node": ">=8.0.0" } }, + "node_modules/available-typed-arrays": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, "node_modules/before-after-hook": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.3.tgz", @@ -1652,6 +2902,29 @@ "integrity": "sha512-VHiNCbI1lKdl44tGrhNfU3lup0Tj/ZBMJB5/2ZbNXRCPuRCO7ed2mgcK4r17y+KB2EfuYuRaVlwNbAeaWGSpbw==", "license": "MIT" }, + "node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/btoa-lite": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/btoa-lite/-/btoa-lite-1.0.0.tgz", @@ -1702,6 +2975,25 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/callsite": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/callsite/-/callsite-1.0.0.tgz", + "integrity": "sha512-0vdNRFXn5q+dtOqjfFtmtlI9N2eVZ7LMyEV2iKC5mEEFvSg/69Ml6b/WU2qF8W1nLRa0wiSrDT3Y5jOHZCwKPQ==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/camelcase": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.0.0.tgz", @@ -1766,545 +3058,2849 @@ "node": ">=6" } }, - "node_modules/cluster-key-slot": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/cluster-key-slot/-/cluster-key-slot-1.1.2.tgz", - "integrity": "sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA==", - "license": "Apache-2.0", + "node_modules/cli-cursor": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-5.0.0.tgz", + "integrity": "sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==", + "dev": true, + "license": "MIT", + "dependencies": { + "restore-cursor": "^5.0.0" + }, "engines": { - "node": ">=0.10.0" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "node_modules/cli-truncate": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-4.0.0.tgz", + "integrity": "sha512-nPdaFdQ0h/GEigbPClz11D0v/ZJEwxmeVZGeMo3Z5StPtUTkA9o1lD6QwoirYiSDzbcwn2XcjwmCp68W1IS4TA==", + "dev": true, "license": "MIT", "dependencies": { - "color-name": "1.1.3" + "slice-ansi": "^5.0.0", + "string-width": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "license": "MIT" - }, - "node_modules/colorette": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.4.0.tgz", - "integrity": "sha512-Y2oEozpomLn7Q3HFP7dpww7AtMJplbM9lGZP6RDfHqmbeRjiwRg4n6VM6j4KLmRke85uWEI7JqF17f3pqdRA0g==", + "node_modules/cli-truncate/node_modules/emoji-regex": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.4.0.tgz", + "integrity": "sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw==", + "dev": true, "license": "MIT" }, - "node_modules/commander": { - "version": "12.1.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz", - "integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==", + "node_modules/cli-truncate/node_modules/string-width": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", + "dev": true, "license": "MIT", + "dependencies": { + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + }, "engines": { "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/confbox": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.1.8.tgz", - "integrity": "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==", + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", "dev": true, - "license": "MIT" - }, - "node_modules/content-disposition": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", - "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", - "license": "MIT", + "license": "ISC", "dependencies": { - "safe-buffer": "5.2.1" + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" }, "engines": { - "node": ">= 0.6" + "node": ">=12" } }, - "node_modules/content-type": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", - "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "node_modules/cliui/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, "license": "MIT", "engines": { - "node": ">= 0.6" + "node": ">=8" } }, - "node_modules/cookie": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz", - "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==", + "node_modules/cliui/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, "engines": { - "node": ">= 0.6" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/cookie-signature": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", - "license": "MIT" - }, - "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "node_modules/cliui/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, "license": "MIT", "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" + "color-name": "~1.1.4" }, "engines": { - "node": ">= 8" + "node": ">=7.0.0" } }, - "node_modules/dateformat": { - "version": "4.6.3", - "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-4.6.3.tgz", - "integrity": "sha512-2P0p0pFGzHS5EMnhdxQi7aJN+iMheud0UhG4dlE1DLAlvL8JHjJJTX/CSm4JXwV0Ka5nGk3zC5mcb5bUQUxxMA==", - "license": "MIT", - "engines": { - "node": "*" - } + "node_modules/cliui/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" }, - "node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "node_modules/cliui/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/cliui/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, "license": "MIT", - "dependencies": { - "ms": "2.0.0" + "engines": { + "node": ">=8" } }, - "node_modules/deep-eql": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.4.tgz", - "integrity": "sha512-SUwdGfqdKOwxCPeVYjwSyRpJ7Z+fhpwIAtmCUdZIWZ/YP5R9WAsyuSgpLVDi9bjWoN2LXHNss/dk3urXtdQxGg==", + "node_modules/cliui/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, "license": "MIT", "dependencies": { - "type-detect": "^4.0.0" + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" }, "engines": { - "node": ">=6" + "node": ">=8" } }, - "node_modules/deepmerge": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", - "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "node_modules/cliui/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, - "node_modules/define-data-property": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", - "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "node_modules/cliui/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, "license": "MIT", "dependencies": { - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "gopd": "^1.0.1" + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" }, "engines": { - "node": ">= 0.4" + "node": ">=10" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "node_modules/denque": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/denque/-/denque-2.1.0.tgz", - "integrity": "sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==", + "node_modules/cluster-key-slot": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/cluster-key-slot/-/cluster-key-slot-1.1.2.tgz", + "integrity": "sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA==", "license": "Apache-2.0", "engines": { - "node": ">=0.10" + "node": ">=0.10.0" } }, - "node_modules/depd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", "license": "MIT", - "engines": { - "node": ">= 0.8" + "dependencies": { + "color-name": "1.1.3" } }, - "node_modules/deprecation": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz", - "integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==", - "license": "ISC" + "node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "license": "MIT" }, - "node_modules/destroy": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", - "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "node_modules/colorette": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.4.0.tgz", + "integrity": "sha512-Y2oEozpomLn7Q3HFP7dpww7AtMJplbM9lGZP6RDfHqmbeRjiwRg4n6VM6j4KLmRke85uWEI7JqF17f3pqdRA0g==", + "license": "MIT" + }, + "node_modules/commander": { + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz", + "integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==", "license": "MIT", "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" + "node": ">=18" } }, - "node_modules/diff-sequences": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", - "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==", + "node_modules/comment-parser": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.4.1.tgz", + "integrity": "sha512-buhp5kePrmda3vhc5B9t7pUQXAb2Tnd0qgpkIhPhkHXxJpiPJ11H0ZEU0oBpJ2QztSbzG/ZxMj/CHsYJqRHmyg==", "dev": true, "license": "MIT", "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">= 12.0.0" } }, - "node_modules/dotenv": { - "version": "16.4.5", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.5.tgz", - "integrity": "sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==", - "license": "BSD-2-Clause", - "engines": { - "node": ">=12" + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true, + "license": "MIT" + }, + "node_modules/confbox": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.1.8.tgz", + "integrity": "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==", + "dev": true, + "license": "MIT" + }, + "node_modules/content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "license": "MIT", + "dependencies": { + "safe-buffer": "5.2.1" }, - "funding": { - "url": "https://dotenvx.com" + "engines": { + "node": ">= 0.6" } }, - "node_modules/ecdsa-sig-formatter": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", - "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", - "license": "Apache-2.0", - "dependencies": { - "safe-buffer": "^5.0.1" + "node_modules/content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "license": "MIT", + "engines": { + "node": ">= 0.6" } }, - "node_modules/ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", + "node_modules/cookie": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz", + "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", "license": "MIT" }, - "node_modules/encodeurl": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", - "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "node_modules/cosmiconfig": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", + "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", + "dev": true, "license": "MIT", + "dependencies": { + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.2.1", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.10.0" + }, "engines": { - "node": ">= 0.8" + "node": ">=10" } }, - "node_modules/end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "node_modules/cosmiconfig/node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, "license": "MIT", "dependencies": { - "once": "^1.4.0" + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dev": true, "license": "MIT", "dependencies": { - "is-arrayish": "^0.2.1" + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" } }, - "node_modules/es-define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", - "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "node_modules/data-view-buffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.1.tgz", + "integrity": "sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==", + "dev": true, "license": "MIT", "dependencies": { - "get-intrinsic": "^1.2.4" + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" }, "engines": { "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/es-errors": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", - "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "node_modules/data-view-byte-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.1.tgz", + "integrity": "sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==", + "dev": true, "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, "engines": { "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/esbuild": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", - "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", + "node_modules/data-view-byte-offset": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.0.tgz", + "integrity": "sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==", "dev": true, - "hasInstallScript": true, "license": "MIT", - "bin": { - "esbuild": "bin/esbuild" + "dependencies": { + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" }, "engines": { - "node": ">=12" + "node": ">= 0.4" }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.21.5", - "@esbuild/android-arm": "0.21.5", - "@esbuild/android-arm64": "0.21.5", - "@esbuild/android-x64": "0.21.5", - "@esbuild/darwin-arm64": "0.21.5", - "@esbuild/darwin-x64": "0.21.5", - "@esbuild/freebsd-arm64": "0.21.5", - "@esbuild/freebsd-x64": "0.21.5", - "@esbuild/linux-arm": "0.21.5", - "@esbuild/linux-arm64": "0.21.5", - "@esbuild/linux-ia32": "0.21.5", - "@esbuild/linux-loong64": "0.21.5", - "@esbuild/linux-mips64el": "0.21.5", - "@esbuild/linux-ppc64": "0.21.5", - "@esbuild/linux-riscv64": "0.21.5", - "@esbuild/linux-s390x": "0.21.5", - "@esbuild/linux-x64": "0.21.5", - "@esbuild/netbsd-x64": "0.21.5", - "@esbuild/openbsd-x64": "0.21.5", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/dateformat": { + "version": "4.6.3", + "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-4.6.3.tgz", + "integrity": "sha512-2P0p0pFGzHS5EMnhdxQi7aJN+iMheud0UhG4dlE1DLAlvL8JHjJJTX/CSm4JXwV0Ka5nGk3zC5mcb5bUQUxxMA==", + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/deep-eql": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.4.tgz", + "integrity": "sha512-SUwdGfqdKOwxCPeVYjwSyRpJ7Z+fhpwIAtmCUdZIWZ/YP5R9WAsyuSgpLVDi9bjWoN2LXHNss/dk3urXtdQxGg==", + "dev": true, + "license": "MIT", + "dependencies": { + "type-detect": "^4.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/denque": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/denque/-/denque-2.1.0.tgz", + "integrity": "sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==", + "license": "Apache-2.0", + "engines": { + "node": ">=0.10" + } + }, + "node_modules/depcheck": { + "version": "1.4.7", + "resolved": "https://registry.npmjs.org/depcheck/-/depcheck-1.4.7.tgz", + "integrity": "sha512-1lklS/bV5chOxwNKA/2XUUk/hPORp8zihZsXflr8x0kLwmcZ9Y9BsS6Hs3ssvA+2wUVbG0U2Ciqvm1SokNjPkA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.23.0", + "@babel/traverse": "^7.23.2", + "@vue/compiler-sfc": "^3.3.4", + "callsite": "^1.0.0", + "camelcase": "^6.3.0", + "cosmiconfig": "^7.1.0", + "debug": "^4.3.4", + "deps-regex": "^0.2.0", + "findup-sync": "^5.0.0", + "ignore": "^5.2.4", + "is-core-module": "^2.12.0", + "js-yaml": "^3.14.1", + "json5": "^2.2.3", + "lodash": "^4.17.21", + "minimatch": "^7.4.6", + "multimatch": "^5.0.0", + "please-upgrade-node": "^3.2.0", + "readdirp": "^3.6.0", + "require-package-name": "^2.0.1", + "resolve": "^1.22.3", + "resolve-from": "^5.0.0", + "semver": "^7.5.4", + "yargs": "^16.2.0" + }, + "bin": { + "depcheck": "bin/depcheck.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/depcheck/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/depcheck/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/depcheck/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "license": "MIT", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/depcheck/node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/depcheck/node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/depcheck/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/depcheck/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/depcheck/node_modules/debug": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/depcheck/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/depcheck/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/depcheck/node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/depcheck/node_modules/minimatch": { + "version": "7.4.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-7.4.6.tgz", + "integrity": "sha512-sBz8G/YjVniEz6lKPNpKxXwazJe4c19fEfV2GDMX6AjFz+MX9uDWIZW8XreVhkFW3fkIdTv/gxWr/Kks5FFAVw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/depcheck/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/depcheck/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/depcheck/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/depcheck/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/depcheck/node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "license": "MIT", + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/depcheck/node_modules/yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/deprecation": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz", + "integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==", + "license": "ISC" + }, + "node_modules/deps-regex": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/deps-regex/-/deps-regex-0.2.0.tgz", + "integrity": "sha512-PwuBojGMQAYbWkMXOY9Pd/NWCDNHVH12pnS7WHqZkTSeMESe4hwnKKRp0yR87g37113x4JPbo/oIvXY+s/f56Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "license": "MIT", + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/detect-file": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz", + "integrity": "sha512-DtCOLG98P007x7wiiOmfI0fi3eIKyWiLTGJ2MDnVi/E04lWGbf+JzrRHMm0rgIIZJGtHpKpbVgLWHrv8xXpc3Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/diff-sequences": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", + "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/dotenv": { + "version": "16.4.5", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.5.tgz", + "integrity": "sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true, + "license": "MIT" + }, + "node_modules/ecdsa-sig-formatter": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", + "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", + "license": "Apache-2.0", + "dependencies": { + "safe-buffer": "^5.0.1" + } + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", + "license": "MIT" + }, + "node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true, + "license": "MIT" + }, + "node_modules/encodeurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "license": "MIT", + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/environment": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/environment/-/environment-1.1.0.tgz", + "integrity": "sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "license": "MIT", + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/es-abstract": { + "version": "1.23.5", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.5.tgz", + "integrity": "sha512-vlmniQ0WNPwXqA0BnmwV3Ng7HxiGlh6r5U6JcTMNx8OilcAGqVJBHJcPjqOMaczU9fRuRK5Px2BdVyPRnKMMVQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-buffer-byte-length": "^1.0.1", + "arraybuffer.prototype.slice": "^1.0.3", + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "data-view-buffer": "^1.0.1", + "data-view-byte-length": "^1.0.1", + "data-view-byte-offset": "^1.0.0", + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-set-tostringtag": "^2.0.3", + "es-to-primitive": "^1.2.1", + "function.prototype.name": "^1.1.6", + "get-intrinsic": "^1.2.4", + "get-symbol-description": "^1.0.2", + "globalthis": "^1.0.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.0.3", + "has-symbols": "^1.0.3", + "hasown": "^2.0.2", + "internal-slot": "^1.0.7", + "is-array-buffer": "^3.0.4", + "is-callable": "^1.2.7", + "is-data-view": "^1.0.1", + "is-negative-zero": "^2.0.3", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.3", + "is-string": "^1.0.7", + "is-typed-array": "^1.1.13", + "is-weakref": "^1.0.2", + "object-inspect": "^1.13.3", + "object-keys": "^1.1.1", + "object.assign": "^4.1.5", + "regexp.prototype.flags": "^1.5.3", + "safe-array-concat": "^1.1.2", + "safe-regex-test": "^1.0.3", + "string.prototype.trim": "^1.2.9", + "string.prototype.trimend": "^1.0.8", + "string.prototype.trimstart": "^1.0.8", + "typed-array-buffer": "^1.0.2", + "typed-array-byte-length": "^1.0.1", + "typed-array-byte-offset": "^1.0.2", + "typed-array-length": "^1.0.6", + "unbox-primitive": "^1.0.2", + "which-typed-array": "^1.1.15" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", + "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "license": "MIT", + "dependencies": { + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-iterator-helpers": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.2.0.tgz", + "integrity": "sha512-tpxqxncxnpw3c93u8n3VOzACmRFoVmWJqbWXvX/JfKbkhBw1oslgPrUfeSt2psuqyEJFD6N/9lg5i7bsKpoq+Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.3", + "es-errors": "^1.3.0", + "es-set-tostringtag": "^2.0.3", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "globalthis": "^1.0.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.0.3", + "has-symbols": "^1.0.3", + "internal-slot": "^1.0.7", + "iterator.prototype": "^1.1.3", + "safe-array-concat": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-module-lexer": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.5.4.tgz", + "integrity": "sha512-MVNK56NiMrOwitFB7cqDwq0CQutbw+0BvLshJSse0MUNU+y1FC3bUS/AQg7oUng+/wKrrki7JfmwtVHkVfPLlw==", + "dev": true, + "license": "MIT" + }, + "node_modules/es-object-atoms": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.0.0.tgz", + "integrity": "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz", + "integrity": "sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-intrinsic": "^1.2.4", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-shim-unscopables": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.2.tgz", + "integrity": "sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.0" + } + }, + "node_modules/es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/esbuild": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", + "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.21.5", + "@esbuild/android-arm": "0.21.5", + "@esbuild/android-arm64": "0.21.5", + "@esbuild/android-x64": "0.21.5", + "@esbuild/darwin-arm64": "0.21.5", + "@esbuild/darwin-x64": "0.21.5", + "@esbuild/freebsd-arm64": "0.21.5", + "@esbuild/freebsd-x64": "0.21.5", + "@esbuild/linux-arm": "0.21.5", + "@esbuild/linux-arm64": "0.21.5", + "@esbuild/linux-ia32": "0.21.5", + "@esbuild/linux-loong64": "0.21.5", + "@esbuild/linux-mips64el": "0.21.5", + "@esbuild/linux-ppc64": "0.21.5", + "@esbuild/linux-riscv64": "0.21.5", + "@esbuild/linux-s390x": "0.21.5", + "@esbuild/linux-x64": "0.21.5", + "@esbuild/netbsd-x64": "0.21.5", + "@esbuild/openbsd-x64": "0.21.5", "@esbuild/sunos-x64": "0.21.5", "@esbuild/win32-arm64": "0.21.5", "@esbuild/win32-ia32": "0.21.5", "@esbuild/win32-x64": "0.21.5" } }, - "node_modules/escape-html": { + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", + "license": "MIT" + }, + "node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/eslint": { + "version": "9.15.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.15.0.tgz", + "integrity": "sha512-7CrWySmIibCgT1Os28lUU6upBshZ+GxybLOrmRzi08kS8MBuO8QA7pXEgYgY5W8vK3e74xv0lpjo9DbaGU9Rkw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.12.1", + "@eslint/config-array": "^0.19.0", + "@eslint/core": "^0.9.0", + "@eslint/eslintrc": "^3.2.0", + "@eslint/js": "9.15.0", + "@eslint/plugin-kit": "^0.2.3", + "@humanfs/node": "^0.16.6", + "@humanwhocodes/module-importer": "^1.0.1", + "@humanwhocodes/retry": "^0.4.1", + "@types/estree": "^1.0.6", + "@types/json-schema": "^7.0.15", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.5", + "debug": "^4.3.2", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^8.2.0", + "eslint-visitor-keys": "^4.2.0", + "espree": "^10.3.0", + "esquery": "^1.5.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^8.0.0", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "jiti": "*" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + } + } + }, + "node_modules/eslint-config-prettier": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.1.0.tgz", + "integrity": "sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==", + "dev": true, + "license": "MIT", + "bin": { + "eslint-config-prettier": "bin/cli.js" + }, + "peerDependencies": { + "eslint": ">=7.0.0" + } + }, + "node_modules/eslint-plugin-chai-friendly": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-chai-friendly/-/eslint-plugin-chai-friendly-1.0.1.tgz", + "integrity": "sha512-dxD/uz1YKJ8U4yah1i+V/p/u+kHRy3YxTPe2nJGqb5lCR+ucan/KIexfZ5+q4X+tkllyMe86EBbAkdlwxNy3oQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + }, + "peerDependencies": { + "eslint": ">=3.0.0" + } + }, + "node_modules/eslint-plugin-jsdoc": { + "version": "50.5.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-50.5.0.tgz", + "integrity": "sha512-xTkshfZrUbiSHXBwZ/9d5ulZ2OcHXxSvm/NPo494H/hadLRJwOq5PMV0EUpMqsb9V+kQo+9BAgi6Z7aJtdBp2A==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@es-joy/jsdoccomment": "~0.49.0", + "are-docs-informative": "^0.0.2", + "comment-parser": "1.4.1", + "debug": "^4.3.6", + "escape-string-regexp": "^4.0.0", + "espree": "^10.1.0", + "esquery": "^1.6.0", + "parse-imports": "^2.1.1", + "semver": "^7.6.3", + "spdx-expression-parse": "^4.0.0", + "synckit": "^0.9.1" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0 || ^9.0.0" + } + }, + "node_modules/eslint-plugin-jsdoc/node_modules/debug": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/eslint-plugin-jsdoc/node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint-plugin-jsdoc/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/eslint-plugin-no-only-tests": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-no-only-tests/-/eslint-plugin-no-only-tests-3.3.0.tgz", + "integrity": "sha512-brcKcxGnISN2CcVhXJ/kEQlNa0MEfGRtwKtWA16SkqXHKitaKIMrfemJKLKX1YqDU5C/5JY3PvZXd5jEW04e0Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=5.0.0" + } + }, + "node_modules/eslint-plugin-react": { + "version": "7.37.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.37.2.tgz", + "integrity": "sha512-EsTAnj9fLVr/GZleBLFbj/sSuXeWmp1eXIN60ceYnZveqEaUCyW4X+Vh4WTdUhCkW4xutXYqTXCUSyqD4rB75w==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-includes": "^3.1.8", + "array.prototype.findlast": "^1.2.5", + "array.prototype.flatmap": "^1.3.2", + "array.prototype.tosorted": "^1.1.4", + "doctrine": "^2.1.0", + "es-iterator-helpers": "^1.1.0", + "estraverse": "^5.3.0", + "hasown": "^2.0.2", + "jsx-ast-utils": "^2.4.1 || ^3.0.0", + "minimatch": "^3.1.2", + "object.entries": "^1.1.8", + "object.fromentries": "^2.0.8", + "object.values": "^1.2.0", + "prop-types": "^15.8.1", + "resolve": "^2.0.0-next.5", + "semver": "^6.3.1", + "string.prototype.matchall": "^4.0.11", + "string.prototype.repeat": "^1.0.0" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7" + } + }, + "node_modules/eslint-plugin-react-hooks": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-5.0.0.tgz", + "integrity": "sha512-hIOwI+5hYGpJEc4uPRmz2ulCjAGD/N13Lukkh8cLV0i2IRk/bdZDYjgLVHj+U9Z704kLIdIO6iueGvxNur0sgw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0" + } + }, + "node_modules/eslint-plugin-react/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/eslint-plugin-react/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/eslint-plugin-react/node_modules/resolve": { + "version": "2.0.0-next.5", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.5.tgz", + "integrity": "sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/eslint-plugin-react/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/eslint-scope": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.2.0.tgz", + "integrity": "sha512-PHlWUfG6lvPc3yvP5A4PNyBL1W8fkDUccmI21JUu/+GKZBoH/W5u6usENXUrWFRsyoW5ACUjFGgAFQp5gUlb/A==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/eslint/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/eslint/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/eslint/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/eslint/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/eslint/node_modules/debug": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/eslint/node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/eslint-visitor-keys": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz", + "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint/node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/eslint/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/eslint/node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint/node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/espree": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.3.0.tgz", + "integrity": "sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.14.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^4.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/espree/node_modules/eslint-visitor-keys": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz", + "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, + "license": "BSD-2-Clause", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/esquery": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", + "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/eventemitter3": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", + "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==", + "dev": true, + "license": "MIT" + }, + "node_modules/eventsource": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-2.0.2.tgz", + "integrity": "sha512-IzUmBGPR3+oUG9dUeXynyNmf91/3zUSJg1lCktzKw47OXuhco54U3r9B7O4XX+Rb1Itm9OZ2b0RkTs10bICOxA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/execa": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", + "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", + "dev": true, + "license": "MIT", + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^8.0.1", + "human-signals": "^5.0.0", + "is-stream": "^3.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^5.1.0", + "onetime": "^6.0.0", + "signal-exit": "^4.1.0", + "strip-final-newline": "^3.0.0" + }, + "engines": { + "node": ">=16.17" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/expand-tilde": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", + "integrity": "sha512-A5EmesHW6rfnZ9ysHQjPdJRni0SRar0tjtG5MNtm9n5TUvsYU8oozprtRD4AqHxcZWWlVuAmQo2nWKfN9oyjTw==", + "dev": true, + "license": "MIT", + "dependencies": { + "homedir-polyfill": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/express": { + "version": "4.21.1", + "resolved": "https://registry.npmjs.org/express/-/express-4.21.1.tgz", + "integrity": "sha512-YSFlK1Ee0/GC8QaO91tHcDxJiE/X4FbpAyQWkxAvG6AXCuR65YzK8ua6D9hvi/TzUfZMpc+BwuM1IPw8fmQBiQ==", + "license": "MIT", + "dependencies": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.20.3", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.7.1", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.3.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "merge-descriptors": "1.0.3", + "methods": "~1.1.2", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.10", + "proxy-addr": "~2.0.7", + "qs": "6.13.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.19.0", + "serve-static": "1.16.2", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-glob": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-redact": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/fast-redact/-/fast-redact-3.5.0.tgz", + "integrity": "sha512-dwsoQlS7h9hMeYUq1W++23NDcBLV4KqONnITDV9DjfS3q1SgDGVrBdvvTLUotWtPSD7asWDV9/CmsZPy8Hf70A==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/fast-safe-stringify": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz", + "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==", + "license": "MIT" + }, + "node_modules/fastq": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", + "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", + "dev": true, + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/file-entry-cache": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", + "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "flat-cache": "^4.0.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/finalhandler": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz", + "integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==", + "license": "MIT", + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "statuses": "2.0.1", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "license": "MIT", + "dependencies": { + "locate-path": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/findup-sync": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-5.0.0.tgz", + "integrity": "sha512-MzwXju70AuyflbgeOhzvQWAvvQdo1XL0A9bVvlXsYcFEBM87WR4OakL4OfZq+QRmr+duJubio+UtNQCPsVESzQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "detect-file": "^1.0.0", + "is-glob": "^4.0.3", + "micromatch": "^4.0.4", + "resolve-dir": "^1.0.1" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/flat-cache": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", + "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.4" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/flatted": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.2.tgz", + "integrity": "sha512-AiwGJM8YcNOaobumgtng+6NHuOqC3A7MixFeDafM3X9cIUM+xUXoS5Vfgf+OihAYe20fxqNM9yPBXJzRtZ/4eA==", + "dev": true, + "license": "ISC" + }, + "node_modules/for-each": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", + "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-callable": "^1.1.3" + } + }, + "node_modules/foreground-child": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.0.tgz", + "integrity": "sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==", + "dev": true, + "license": "ISC", + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/function.prototype.name": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", + "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "functions-have-names": "^1.2.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-east-asian-width": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.3.0.tgz", + "integrity": "sha512-vpeMIQKxczTD/0s2CdEWHcb0eeJe6TFjxb+J5xgX7hScxqrGuyjmv4c1D4A/gelKfyox0gJJwIHF+fLjeaM8kQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/get-func-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", + "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/get-intrinsic": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-stream": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", + "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/get-symbol-description": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz", + "integrity": "sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.5", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/glob": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-11.0.0.tgz", + "integrity": "sha512-9UiX/Bl6J2yaBbxKoEBRm4Cipxgok8kQYcOPEhScPwebu2I0HoQOuYdIO6S3hLuWoZgpDpwQZMzTFxgpkyT76g==", + "dev": true, + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^4.0.1", + "minimatch": "^10.0.0", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^2.0.0" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/glob/node_modules/minimatch": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.0.1.tgz", + "integrity": "sha512-ethXTt3SGGR+95gudmqJ1eNhRO7eGEGIgYA9vnPatK4/etz2MEVDno5GMCibdMTuBMyElzIlgxMna3K94XDIDQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/global-modules": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", + "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==", + "dev": true, + "license": "MIT", + "dependencies": { + "global-prefix": "^1.0.1", + "is-windows": "^1.0.1", + "resolve-dir": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/global-prefix": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz", + "integrity": "sha512-5lsx1NUDHtSjfg0eHlmYvZKv8/nVqX4ckFbM+FrGcQ+04KWcWFo9P5MxPZYSzUvyzmdTbI7Eix8Q4IbELDqzKg==", + "dev": true, + "license": "MIT", + "dependencies": { + "expand-tilde": "^2.0.2", + "homedir-polyfill": "^1.0.1", + "ini": "^1.3.4", + "is-windows": "^1.0.1", + "which": "^1.2.14" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/global-prefix/node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/globals": { + "version": "15.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-15.12.0.tgz", + "integrity": "sha512-1+gLErljJFhbOVyaetcwJiJ4+eLe45S2E7P5UiZ9xGfeq3ATQf5DOv9G7MH3gGbKQLkzmNh2DxfZwLdw+j6oTQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globalthis": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", + "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-properties": "^1.2.1", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "license": "MIT", + "dependencies": { + "get-intrinsic": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "license": "ISC" + }, + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true, + "license": "MIT" + }, + "node_modules/has-bigints": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", + "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", + "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/homedir-polyfill": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", + "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==", + "dev": true, + "license": "MIT", + "dependencies": { + "parse-passwd": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "license": "MIT", + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/human-signals": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", + "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=16.17.0" + } + }, + "node_modules/husky": { + "version": "9.1.7", + "resolved": "https://registry.npmjs.org/husky/-/husky-9.1.7.tgz", + "integrity": "sha512-5gs5ytaNjBrh5Ow3zrvdUUY+0VxIuWVL4i9irt6friV+BqdCfmV11CQTWMiBYWHbXhco+J1kHfTOUkePhCDvMA==", + "dev": true, + "license": "MIT", + "bin": { + "husky": "bin.js" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/typicode" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/immediate": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz", + "integrity": "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==", "license": "MIT" }, - "node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/import-fresh/node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, "license": "MIT", "engines": { - "node": ">=0.8.0" + "node": ">=4" } }, - "node_modules/estree-walker": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", - "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", "dev": true, "license": "MIT", - "dependencies": { - "@types/estree": "^1.0.0" + "engines": { + "node": ">=0.8.19" } }, - "node_modules/etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", "license": "MIT", "engines": { - "node": ">= 0.6" + "node": ">=8" } }, - "node_modules/eventsource": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-2.0.2.tgz", - "integrity": "sha512-IzUmBGPR3+oUG9dUeXynyNmf91/3zUSJg1lCktzKw47OXuhco54U3r9B7O4XX+Rb1Itm9OZ2b0RkTs10bICOxA==", + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "license": "ISC" + }, + "node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true, + "license": "ISC" + }, + "node_modules/internal-slot": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz", + "integrity": "sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==", "dev": true, "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "hasown": "^2.0.0", + "side-channel": "^1.0.4" + }, "engines": { - "node": ">=12.0.0" + "node": ">= 0.4" } }, - "node_modules/execa": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", - "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", - "dev": true, + "node_modules/ioredis": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/ioredis/-/ioredis-5.4.1.tgz", + "integrity": "sha512-2YZsvl7jopIa1gaePkeMtd9rAcSjOOjPtpcLlOeusyO+XH2SK5ZcT+UCrElPP+WVIInh2TzeI4XW9ENaSLVVHA==", "license": "MIT", "dependencies": { - "cross-spawn": "^7.0.3", - "get-stream": "^8.0.1", - "human-signals": "^5.0.0", - "is-stream": "^3.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^5.1.0", - "onetime": "^6.0.0", - "signal-exit": "^4.1.0", - "strip-final-newline": "^3.0.0" + "@ioredis/commands": "^1.1.1", + "cluster-key-slot": "^1.1.0", + "debug": "^4.3.4", + "denque": "^2.1.0", + "lodash.defaults": "^4.2.0", + "lodash.isarguments": "^3.1.0", + "redis-errors": "^1.2.0", + "redis-parser": "^3.0.0", + "standard-as-callback": "^2.1.0" }, "engines": { - "node": ">=16.17" + "node": ">=12.22.0" }, "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" + "type": "opencollective", + "url": "https://opencollective.com/ioredis" } }, - "node_modules/express": { - "version": "4.21.1", - "resolved": "https://registry.npmjs.org/express/-/express-4.21.1.tgz", - "integrity": "sha512-YSFlK1Ee0/GC8QaO91tHcDxJiE/X4FbpAyQWkxAvG6AXCuR65YzK8ua6D9hvi/TzUfZMpc+BwuM1IPw8fmQBiQ==", + "node_modules/ioredis/node_modules/debug": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", "license": "MIT", "dependencies": { - "accepts": "~1.3.8", - "array-flatten": "1.1.1", - "body-parser": "1.20.3", - "content-disposition": "0.5.4", - "content-type": "~1.0.4", - "cookie": "0.7.1", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "2.0.0", - "encodeurl": "~2.0.0", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "1.3.1", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "merge-descriptors": "1.0.3", - "methods": "~1.1.2", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "path-to-regexp": "0.1.10", - "proxy-addr": "~2.0.7", - "qs": "6.13.0", - "range-parser": "~1.2.1", - "safe-buffer": "5.2.1", - "send": "0.19.0", - "serve-static": "1.16.2", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "type-is": "~1.6.18", - "utils-merge": "1.0.1", - "vary": "~1.1.2" + "ms": "^2.1.3" }, "engines": { - "node": ">= 0.10.0" + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } } }, - "node_modules/fast-redact": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/fast-redact/-/fast-redact-3.5.0.tgz", - "integrity": "sha512-dwsoQlS7h9hMeYUq1W++23NDcBLV4KqONnITDV9DjfS3q1SgDGVrBdvvTLUotWtPSD7asWDV9/CmsZPy8Hf70A==", + "node_modules/ioredis/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", "license": "MIT", "engines": { - "node": ">=6" + "node": ">= 0.10" } }, - "node_modules/fast-safe-stringify": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz", - "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==", + "node_modules/is-array-buffer": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz", + "integrity": "sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", "license": "MIT" }, - "node_modules/finalhandler": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz", - "integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==", + "node_modules/is-async-function": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.0.0.tgz", + "integrity": "sha512-Y1JXKrfykRJGdlDwdKlLpLyMIiWqWvuSd17TvZk68PLAOGOoF4Xyav1z0Xhoi+gCYjZVeC5SI+hYFOfvXmGRCA==", + "dev": true, "license": "MIT", "dependencies": { - "debug": "2.6.9", - "encodeurl": "~2.0.0", - "escape-html": "~1.0.3", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "statuses": "2.0.1", - "unpipe": "~1.0.0" + "has-tostringtag": "^1.0.0" }, "engines": { - "node": ">= 0.8" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "node_modules/is-bigint": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", + "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", + "dev": true, "license": "MIT", "dependencies": { - "locate-path": "^3.0.0" + "has-bigints": "^1.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-boolean-object": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", + "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" }, "engines": { - "node": ">=6" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/forwarded": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", - "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "node_modules/is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "dev": true, "license": "MIT", "engines": { - "node": ">= 0.6" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "node_modules/is-core-module": { + "version": "2.15.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.1.tgz", + "integrity": "sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==", + "dev": true, "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, "engines": { - "node": ">= 0.6" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "node_modules/is-data-view": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.1.tgz", + "integrity": "sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==", "dev": true, - "hasInstallScript": true, "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], + "dependencies": { + "is-typed-array": "^1.1.13" + }, "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/function-bind": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "node_modules/is-date-object": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", + "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", + "dev": true, "license": "MIT", + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "license": "ISC", + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "license": "MIT", "engines": { - "node": "6.* || 8.* || >= 10.*" + "node": ">=0.10.0" + } + }, + "node_modules/is-finalizationregistry": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.0.2.tgz", + "integrity": "sha512-0by5vtUJs8iFQb5TYUHHPudOR+qXYIMKtiUzvLIZITZUjknFmziyBJuLhVRc+Ds0dREFlskDNJKYIdIzu/9pfw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/get-func-name": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", - "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", + "node_modules/is-fullwidth-code-point": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz", + "integrity": "sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==", "dev": true, "license": "MIT", "engines": { - "node": "*" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/get-intrinsic": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", - "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "node_modules/is-generator-function": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", + "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", + "dev": true, "license": "MIT", "dependencies": { - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3", - "hasown": "^2.0.0" + "has-tostringtag": "^1.0.0" }, "engines": { "node": ">= 0.4" @@ -2313,63 +5909,88 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/get-stream": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", - "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-map": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz", + "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==", "dev": true, "license": "MIT", "engines": { - "node": ">=16" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/gopd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", - "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "node_modules/is-negative-zero": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", + "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", + "dev": true, "license": "MIT", - "dependencies": { - "get-intrinsic": "^1.1.3" + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/graceful-fs": { - "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", - "license": "ISC" + "node_modules/is-node-process": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/is-node-process/-/is-node-process-1.2.0.tgz", + "integrity": "sha512-Vg4o6/fqPxIjtxgUH5QLJhwZ7gW5diGCVlXpuUfELC62CuxM1iHcRe51f2W1FDy04Ai4KJkagKjx3XaqyfRKXw==", + "dev": true, + "license": "MIT" }, - "node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, "license": "MIT", "engines": { - "node": ">=4" + "node": ">=0.12.0" } }, - "node_modules/has-property-descriptors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", - "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "node_modules/is-number-object": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", + "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", + "dev": true, "license": "MIT", "dependencies": { - "es-define-property": "^1.0.0" + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/has-proto": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", - "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", + "node_modules/is-regex": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "dev": true, "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, "engines": { "node": ">= 0.4" }, @@ -2377,10 +5998,11 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "node_modules/is-set": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz", + "integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==", + "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -2389,166 +6011,183 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/hasown": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", - "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "node_modules/is-shared-array-buffer": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz", + "integrity": "sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==", + "dev": true, "license": "MIT", "dependencies": { - "function-bind": "^1.1.2" + "call-bind": "^1.0.7" }, "engines": { "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/http-errors": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", - "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "node_modules/is-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", + "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-string": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", + "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "dev": true, "license": "MIT", "dependencies": { - "depd": "2.0.0", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "toidentifier": "1.0.1" + "has-tostringtag": "^1.0.0" }, "engines": { - "node": ">= 0.8" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/human-signals": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", - "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", + "node_modules/is-symbol": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", + "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", "dev": true, - "license": "Apache-2.0", + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.2" + }, "engines": { - "node": ">=16.17.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "node_modules/is-typed-array": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz", + "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==", + "dev": true, "license": "MIT", "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" + "which-typed-array": "^1.1.14" }, "engines": { - "node": ">=0.10.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/immediate": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz", - "integrity": "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==", - "license": "MIT" - }, - "node_modules/indent-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", - "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "node_modules/is-weakmap": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz", + "integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==", + "dev": true, "license": "MIT", "engines": { - "node": ">=8" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "license": "ISC" - }, - "node_modules/ioredis": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/ioredis/-/ioredis-5.4.1.tgz", - "integrity": "sha512-2YZsvl7jopIa1gaePkeMtd9rAcSjOOjPtpcLlOeusyO+XH2SK5ZcT+UCrElPP+WVIInh2TzeI4XW9ENaSLVVHA==", + "node_modules/is-weakref": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", + "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", + "dev": true, "license": "MIT", "dependencies": { - "@ioredis/commands": "^1.1.1", - "cluster-key-slot": "^1.1.0", - "debug": "^4.3.4", - "denque": "^2.1.0", - "lodash.defaults": "^4.2.0", - "lodash.isarguments": "^3.1.0", - "redis-errors": "^1.2.0", - "redis-parser": "^3.0.0", - "standard-as-callback": "^2.1.0" - }, - "engines": { - "node": ">=12.22.0" + "call-bind": "^1.0.2" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/ioredis" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/ioredis/node_modules/debug": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", - "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "node_modules/is-weakset": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.3.tgz", + "integrity": "sha512-LvIm3/KWzS9oRFHugab7d+M/GcBXuXX5xZkzPmN+NxihdQlZUQ4dWuSV1xR/sq6upL1TJEDrfBgRepHFdBtSNQ==", + "dev": true, "license": "MIT", "dependencies": { - "ms": "^2.1.3" + "call-bind": "^1.0.7", + "get-intrinsic": "^1.2.4" }, "engines": { - "node": ">=6.0" + "node": ">= 0.4" }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/ioredis/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "license": "MIT" - }, - "node_modules/ipaddr.js": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", - "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "node_modules/is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "dev": true, "license": "MIT", "engines": { - "node": ">= 0.10" + "node": ">=0.10.0" } }, - "node_modules/is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true, "license": "MIT" }, - "node_modules/is-node-process": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/is-node-process/-/is-node-process-1.2.0.tgz", - "integrity": "sha512-Vg4o6/fqPxIjtxgUH5QLJhwZ7gW5diGCVlXpuUfELC62CuxM1iHcRe51f2W1FDy04Ai4KJkagKjx3XaqyfRKXw==", + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", "dev": true, - "license": "MIT" + "license": "ISC" + }, + "node_modules/iterator.prototype": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.3.tgz", + "integrity": "sha512-FW5iMbeQ6rBGm/oKgzq2aW4KvAGpxPzYES8N4g4xNXUKpL1mclMvOe+76AcLDTvD+Ze+sOpVhgdAQEKF4L9iGQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-properties": "^1.2.1", + "get-intrinsic": "^1.2.1", + "has-symbols": "^1.0.3", + "reflect.getprototypeof": "^1.0.4", + "set-function-name": "^2.0.1" + }, + "engines": { + "node": ">= 0.4" + } }, - "node_modules/is-stream": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", - "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", + "node_modules/jackspeak": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-4.0.2.tgz", + "integrity": "sha512-bZsjR/iRjl1Nk1UkjGpAzLNfQtzuijhn2g+pbZb98HQ1Gk8vM9hfbxeMBP+M2/UUdwj0RqGG3mlvk2MsAqwvEw==", "dev": true, - "license": "MIT", + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + "node": "20 || >=22" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true, - "license": "ISC" - }, "node_modules/jmespath": { "version": "0.15.0", "resolved": "https://registry.npmjs.org/jmespath/-/jmespath-0.15.0.tgz", @@ -2585,12 +6224,63 @@ "js-yaml": "bin/js-yaml.js" } }, + "node_modules/jsdoc-type-pratt-parser": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-4.1.0.tgz", + "integrity": "sha512-Hicd6JK5Njt2QB6XYFS7ok9e37O8AYk3jTcppG4YVQnYjOemymvTcmc7OWsmq/Qqj5TdRFO5/x/tIPmBeRtGHg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/jsesc": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz", + "integrity": "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==", + "dev": true, + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true, + "license": "MIT" + }, "node_modules/json-parse-better-errors": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", "license": "MIT" }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true, + "license": "MIT" + }, "node_modules/json-stringify-safe": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", @@ -2598,6 +6288,19 @@ "dev": true, "license": "ISC" }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/jsonwebtoken": { "version": "9.0.2", "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz", @@ -2626,6 +6329,22 @@ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "license": "MIT" }, + "node_modules/jsx-ast-utils": { + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz", + "integrity": "sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-includes": "^3.1.6", + "array.prototype.flat": "^1.3.1", + "object.assign": "^4.1.4", + "object.values": "^1.1.6" + }, + "engines": { + "node": ">=4.0" + } + }, "node_modules/jwa": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", @@ -2647,6 +6366,16 @@ "safe-buffer": "^5.0.1" } }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "json-buffer": "3.0.1" + } + }, "node_modules/leven": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/leven/-/leven-2.1.0.tgz", @@ -2656,6 +6385,20 @@ "node": ">=0.10.0" } }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, "node_modules/lie": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/lie/-/lie-3.1.1.tgz", @@ -2665,6 +6408,186 @@ "immediate": "~3.0.5" } }, + "node_modules/lilconfig": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.2.tgz", + "integrity": "sha512-eop+wDAvpItUys0FWkHIKeC9ybYrTGbU41U5K7+bttZZeohvnY7M9dZ5kB21GNWiFT2q1OoPTvncPCgSOVO5ow==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antonk52" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true, + "license": "MIT" + }, + "node_modules/lint-staged": { + "version": "15.2.10", + "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-15.2.10.tgz", + "integrity": "sha512-5dY5t743e1byO19P9I4b3x8HJwalIznL5E1FWYnU6OWw33KxNBSLAc6Cy7F2PsFEO8FKnLwjwm5hx7aMF0jzZg==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "~5.3.0", + "commander": "~12.1.0", + "debug": "~4.3.6", + "execa": "~8.0.1", + "lilconfig": "~3.1.2", + "listr2": "~8.2.4", + "micromatch": "~4.0.8", + "pidtree": "~0.6.0", + "string-argv": "~0.3.2", + "yaml": "~2.5.0" + }, + "bin": { + "lint-staged": "bin/lint-staged.js" + }, + "engines": { + "node": ">=18.12.0" + }, + "funding": { + "url": "https://opencollective.com/lint-staged" + } + }, + "node_modules/lint-staged/node_modules/chalk": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", + "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/lint-staged/node_modules/debug": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/lint-staged/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/lint-staged/node_modules/yaml": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.5.1.tgz", + "integrity": "sha512-bLQOjaX/ADgQ20isPJRvF0iRUHIxVhYvr53Of7wGcWlO2jvtUlH5m87DsmulFVxRpNLOnI4tB6p/oh8D7kpn9Q==", + "dev": true, + "license": "ISC", + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/listr2": { + "version": "8.2.5", + "resolved": "https://registry.npmjs.org/listr2/-/listr2-8.2.5.tgz", + "integrity": "sha512-iyAZCeyD+c1gPyE9qpFu8af0Y+MRtmKOncdGoA2S5EY8iFq99dmmvkNnHiWo+pj0s7yH7l3KPIgee77tKpXPWQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "cli-truncate": "^4.0.0", + "colorette": "^2.0.20", + "eventemitter3": "^5.0.1", + "log-update": "^6.1.0", + "rfdc": "^1.4.1", + "wrap-ansi": "^9.0.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/listr2/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/listr2/node_modules/colorette": { + "version": "2.0.20", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", + "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", + "dev": true, + "license": "MIT" + }, + "node_modules/listr2/node_modules/emoji-regex": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.4.0.tgz", + "integrity": "sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw==", + "dev": true, + "license": "MIT" + }, + "node_modules/listr2/node_modules/string-width": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/listr2/node_modules/wrap-ansi": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.0.tgz", + "integrity": "sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, "node_modules/load-json-file": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-5.3.0.tgz", @@ -2720,6 +6643,13 @@ "node": ">=6" } }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true, + "license": "MIT" + }, "node_modules/lodash.defaults": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", @@ -2756,22 +6686,158 @@ "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==", "license": "MIT" }, - "node_modules/lodash.isplainobject": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", - "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==", - "license": "MIT" + "node_modules/lodash.isplainobject": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==", + "license": "MIT" + }, + "node_modules/lodash.isstring": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", + "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==", + "license": "MIT" + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.once": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", + "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==", + "license": "MIT" + }, + "node_modules/log-update": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/log-update/-/log-update-6.1.0.tgz", + "integrity": "sha512-9ie8ItPR6tjY5uYJh8K/Zrv/RMZ5VOlOWvtZdEHYSTFKZfIBPQa9tOAEeAWhd+AnIneLJ22w5fjOYtoutpWq5w==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-escapes": "^7.0.0", + "cli-cursor": "^5.0.0", + "slice-ansi": "^7.1.0", + "strip-ansi": "^7.1.0", + "wrap-ansi": "^9.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/log-update/node_modules/emoji-regex": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.4.0.tgz", + "integrity": "sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw==", + "dev": true, + "license": "MIT" + }, + "node_modules/log-update/node_modules/is-fullwidth-code-point": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-5.0.0.tgz", + "integrity": "sha512-OVa3u9kkBbw7b8Xw5F9P+D/T9X+Z4+JruYVNapTjPYZYUznQ5YfWeFkOj606XYYW8yugTfC8Pj0hYqvi4ryAhA==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-east-asian-width": "^1.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/slice-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-7.1.0.tgz", + "integrity": "sha512-bSiSngZ/jWeX93BqeIAbImyTbEihizcwNjFoRUIY/T1wWQsfsm2Vw1agPKylXvQTU7iASGdHhyqRlqQzfz+Htg==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.2.1", + "is-fullwidth-code-point": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/log-update/node_modules/string-width": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/wrap-ansi": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.0.tgz", + "integrity": "sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } }, - "node_modules/lodash.isstring": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", - "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==", - "license": "MIT" + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } }, - "node_modules/lodash.once": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", - "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==", + "node_modules/loose-envify/node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true, "license": "MIT" }, "node_modules/loupe": { @@ -2825,6 +6891,16 @@ "dev": true, "license": "MIT" }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, "node_modules/methods": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", @@ -2834,6 +6910,20 @@ "node": ">= 0.6" } }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "dev": true, + "license": "MIT", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, "node_modules/mime": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", @@ -2880,6 +6970,45 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/mimic-function": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/mimic-function/-/mimic-function-5.0.1.tgz", + "integrity": "sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, "node_modules/mlly": { "version": "1.7.2", "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.7.2.tgz", @@ -2908,6 +7037,50 @@ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "license": "MIT" }, + "node_modules/multimatch": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/multimatch/-/multimatch-5.0.0.tgz", + "integrity": "sha512-ypMKuglUrZUD99Tk2bUQ+xNQj43lPEfAeX2o9cTteAmShXy2VHDJpuwu1o0xqoKCt9jLVAvwyFKdLTPXKAfJyA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/minimatch": "^3.0.3", + "array-differ": "^3.0.0", + "array-union": "^2.1.0", + "arrify": "^2.0.1", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/multimatch/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/multimatch/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, "node_modules/nanoid": { "version": "3.3.7", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", @@ -2927,6 +7100,13 @@ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true, + "license": "MIT" + }, "node_modules/negotiator": { "version": "0.6.3", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", @@ -2980,11 +7160,102 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/object-inspect": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz", - "integrity": "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==", + "version": "1.13.3", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.3.tgz", + "integrity": "sha512-kDCGIbxkDSXE3euJZZXzc6to7fCrKHNI/hSRQnRuQ+BWjFNzZwiFF8fj/6o2t2G9/jTj8PSIYTfCLelLZEeRpA==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.assign": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", + "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "has-symbols": "^1.0.3", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.entries": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.8.tgz", + "integrity": "sha512-cmopxi8VwRIAw/fkijJohSfpef5PdN0pMQJN6VC/ZKvn0LIknWD8KtgY6KlQdEc4tIjcQ3HxSMmnvtzIscdaYQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.fromentries": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.8.tgz", + "integrity": "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.values": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.0.tgz", + "integrity": "sha512-yBYjY9QX2hnRmZHAjG/f13MzmBzxzYgQhFrke06TTyKY5zSTEqkOeukBzIdVA3j3ulu8Qa3MbVFShV7T2RmGtQ==", + "dev": true, "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, "engines": { "node": ">= 0.4" }, @@ -3056,6 +7327,24 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/optionator": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, "node_modules/outvariant": { "version": "1.4.3", "resolved": "https://registry.npmjs.org/outvariant/-/outvariant-1.4.3.tgz", @@ -3099,6 +7388,40 @@ "node": ">=6" } }, + "node_modules/package-json-from-dist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", + "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", + "dev": true, + "license": "BlueOak-1.0.0" + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "license": "MIT", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-imports": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/parse-imports/-/parse-imports-2.2.1.tgz", + "integrity": "sha512-OL/zLggRp8mFhKL0rNORUTR4yBYujK/uU+xZL+/0Rgm2QE4nLO9v8PzEweSJEbMGKmDRjJE4R3IMJlL2di4JeQ==", + "dev": true, + "license": "Apache-2.0 AND MIT", + "dependencies": { + "es-module-lexer": "^1.5.3", + "slashes": "^3.0.12" + }, + "engines": { + "node": ">= 18" + } + }, "node_modules/parse-json": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", @@ -3112,6 +7435,16 @@ "node": ">=4" } }, + "node_modules/parse-passwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", + "integrity": "sha512-1Y1A//QUXEZK7YKz+rD9WydcE1+EuPr6ZBgKecAB8tmoW6UFv0NREVJe1p+jRxtThkcbbKkfwIbWJe/IeE6m2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/parseurl": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", @@ -3140,12 +7473,56 @@ "node": ">=8" } }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true, + "license": "MIT" + }, + "node_modules/path-scurry": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.0.tgz", + "integrity": "sha512-ypGJsmGtdXUOeM5u93TyeIEfEhM6s+ljAhrk5vAvSx8uyY/02OvrZnA0YNGUrPXfpJMgI1ODd3nwz8Npx4O4cg==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^11.0.0", + "minipass": "^7.1.2" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-scurry/node_modules/lru-cache": { + "version": "11.0.2", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.0.2.tgz", + "integrity": "sha512-123qHRfJBmo2jXDbo/a5YOQrJoHF/GNQTLzQ5+IdK5pWpceK17yRc6ozlWd25FxvGKQbIUs91fDFkXmDHTKcyA==", + "dev": true, + "license": "ISC", + "engines": { + "node": "20 || >=22" + } + }, "node_modules/path-to-regexp": { "version": "0.1.10", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.10.tgz", "integrity": "sha512-7lf7qcQidTku0Gu3YDPc8DJ1q7OOucfa/BSsIwjuh56VU7katFvuM8hULfkwB3Fns/rsVF7PwPKVw1sl5KQS9w==", "license": "MIT" }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/pathe": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz", @@ -3160,16 +7537,42 @@ "dev": true, "license": "MIT", "engines": { - "node": "*" + "node": "*" + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pidtree": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/pidtree/-/pidtree-0.6.0.tgz", + "integrity": "sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g==", + "dev": true, + "license": "MIT", + "bin": { + "pidtree": "bin/pidtree.js" + }, + "engines": { + "node": ">=0.10" } }, - "node_modules/picocolors": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", - "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", - "dev": true, - "license": "ISC" - }, "node_modules/pify": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", @@ -3285,10 +7688,30 @@ "pathe": "^1.1.2" } }, + "node_modules/please-upgrade-node": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/please-upgrade-node/-/please-upgrade-node-3.2.0.tgz", + "integrity": "sha512-gQR3WpIgNIKwBMVLkpMUeR3e1/E1y42bqDQZfql+kDeXd8COYfM8PQA4X6y7a8u9Ua9FHmsrrmirW2vHs45hWg==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver-compare": "^1.0.0" + } + }, + "node_modules/possible-typed-array-names": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", + "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, "node_modules/postcss": { - "version": "8.4.47", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.47.tgz", - "integrity": "sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==", + "version": "8.4.49", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.49.tgz", + "integrity": "sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==", "dev": true, "funding": [ { @@ -3307,13 +7730,39 @@ "license": "MIT", "dependencies": { "nanoid": "^3.3.7", - "picocolors": "^1.1.0", + "picocolors": "^1.1.1", "source-map-js": "^1.2.1" }, "engines": { "node": "^10 || ^12 || >=14" } }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/prettier": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.3.tgz", + "integrity": "sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==", + "dev": true, + "license": "MIT", + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, "node_modules/pretty-format": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", @@ -3388,6 +7837,25 @@ "integrity": "sha512-/MyYDxttz7DfGMMHiysAsFE4qF+pQYAA8ziO/3NcRVrQ5fSk+Mns4QZA/oRPFzvcqNoVJXQNWNAsdwBXLUkQKw==", "license": "MIT" }, + "node_modules/prop-types": { + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "dev": true, + "license": "MIT", + "dependencies": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" + } + }, + "node_modules/prop-types/node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "dev": true, + "license": "MIT" + }, "node_modules/propagate": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/propagate/-/propagate-2.0.1.tgz", @@ -3421,6 +7889,16 @@ "once": "^1.3.1" } }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/qs": { "version": "6.13.0", "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", @@ -3436,6 +7914,27 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, "node_modules/quick-format-unescaped": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/quick-format-unescaped/-/quick-format-unescaped-4.0.4.tgz", @@ -3487,6 +7986,19 @@ "node": ">= 6" } }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, "node_modules/real-require": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/real-require/-/real-require-0.2.0.tgz", @@ -3517,6 +8029,150 @@ "node": ">=4" } }, + "node_modules/reflect.getprototypeof": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.6.tgz", + "integrity": "sha512-fmfw4XgoDke3kdI6h4xcUz1dG8uaiv5q9gcEwLS4Pnth2kxT+GZ7YehS1JTMGBQmtV7Y4GFGbs2re2NqhdozUg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.1", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4", + "globalthis": "^1.0.3", + "which-builtin-type": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/regexp.prototype.flags": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.3.tgz", + "integrity": "sha512-vqlC04+RQoFalODCbCumG2xIOvapzVMHwsyIGM/SIE8fRhFFsXeH8/QQ+s0T0kDAhKc4k30s73/0ydkHQz6HlQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-errors": "^1.3.0", + "set-function-name": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-package-name": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/require-package-name/-/require-package-name-2.0.1.tgz", + "integrity": "sha512-uuoJ1hU/k6M0779t3VMVIYpb2VMJk05cehCaABFhXaibcbvfgR8wKiozLjVFSzJPmQMRqIcO0HMyTFqfV09V6Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/resolve": { + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-dir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz", + "integrity": "sha512-R7uiTjECzvOsWSfdM0QKFNBVFcK27aHOUwdvK53BcW8zqnGdYp0Fbj82cy54+2A4P2tFM22J5kRfe1R+lM/1yg==", + "dev": true, + "license": "MIT", + "dependencies": { + "expand-tilde": "^2.0.0", + "global-modules": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/restore-cursor": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-5.1.0.tgz", + "integrity": "sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==", + "dev": true, + "license": "MIT", + "dependencies": { + "onetime": "^7.0.0", + "signal-exit": "^4.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/restore-cursor/node_modules/onetime": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-7.0.0.tgz", + "integrity": "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-function": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true, + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, "node_modules/rfdc": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz", @@ -3559,6 +8215,49 @@ "fsevents": "~2.3.2" } }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/safe-array-concat": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.2.tgz", + "integrity": "sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "get-intrinsic": "^1.2.4", + "has-symbols": "^1.0.3", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">=0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -3579,6 +8278,24 @@ ], "license": "MIT" }, + "node_modules/safe-regex-test": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.3.tgz", + "integrity": "sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-regex": "^1.1.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/safe-stable-stringify": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.5.0.tgz", @@ -3606,6 +8323,13 @@ "node": ">=10" } }, + "node_modules/semver-compare": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz", + "integrity": "sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==", + "dev": true, + "license": "MIT" + }, "node_modules/send": { "version": "0.19.0", "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz", @@ -3677,6 +8401,22 @@ "node": ">= 0.4" } }, + "node_modules/set-function-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", + "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "functions-have-names": "^1.2.3", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/setprototypeof": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", @@ -3731,17 +8471,54 @@ "dev": true, "license": "ISC" }, - "node_modules/signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/slashes": { + "version": "3.0.12", + "resolved": "https://registry.npmjs.org/slashes/-/slashes-3.0.12.tgz", + "integrity": "sha512-Q9VME8WyGkc7pJf6QEkj3wE+2CnvZMI+XJhwdTPR8Z/kWQRXi7boAWLDibRPyHRTUTPx5FaU7MsyrjI3yLB4HA==", + "dev": true, + "license": "ISC" + }, + "node_modules/slice-ansi": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-5.0.0.tgz", + "integrity": "sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.0.0", + "is-fullwidth-code-point": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/slice-ansi/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", "dev": true, - "license": "ISC", + "license": "MIT", "engines": { - "node": ">=14" + "node": ">=12" }, "funding": { - "url": "https://github.com/sponsors/isaacs" + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/smee-client": { @@ -3778,6 +8555,31 @@ "node": ">=0.10.0" } }, + "node_modules/spdx-exceptions": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", + "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", + "dev": true, + "license": "CC-BY-3.0" + }, + "node_modules/spdx-expression-parse": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-4.0.0.tgz", + "integrity": "sha512-Clya5JIij/7C6bRR22+tnGXbc4VKlibKSVj2iHvVeX5iMW7s1SIQlqu699JkODJJIhh/pUu8L0/VLh8xflD+LQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-license-ids": { + "version": "3.0.20", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.20.tgz", + "integrity": "sha512-jg25NiDV/1fLtSgEgyvVyDunvaNHbuwF9lfNV17gSmPFAlYzdfNBlLtLzXTevwkPj7DhGbmN9VnmJIgLnhvaBw==", + "dev": true, + "license": "CC0-1.0" + }, "node_modules/split2": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", @@ -3787,6 +8589,13 @@ "node": ">= 10.x" } }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "dev": true, + "license": "BSD-3-Clause" + }, "node_modules/stackback": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", @@ -3832,6 +8641,220 @@ "safe-buffer": "~5.2.0" } }, + "node_modules/string-argv": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.2.tgz", + "integrity": "sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.6.19" + } + }, + "node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/string-width-cjs/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string.prototype.matchall": { + "version": "4.0.11", + "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.11.tgz", + "integrity": "sha512-NUdh0aDavY2og7IbBPenWqR9exH+E26Sv8e0/eTe1tltDGZL+GtBkDAnnyBtmekfK6/Dq3MkcGtzXFEd1LQrtg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-symbols": "^1.0.3", + "internal-slot": "^1.0.7", + "regexp.prototype.flags": "^1.5.2", + "set-function-name": "^2.0.2", + "side-channel": "^1.0.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.repeat": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/string.prototype.repeat/-/string.prototype.repeat-1.0.0.tgz", + "integrity": "sha512-0u/TldDbKD8bFCQ/4f5+mNRrXwZ8hg2w7ZR8wa16e8z9XpePWl3eGEcUD0OXpEH/VJH/2G3gjUtR3ZOiBe2S/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5" + } + }, + "node_modules/string.prototype.trim": { + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.9.tgz", + "integrity": "sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.0", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimend": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.8.tgz", + "integrity": "sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimstart": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", + "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/strip-bom": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", @@ -3891,6 +8914,36 @@ "node": ">=4" } }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/synckit": { + "version": "0.9.2", + "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.9.2.tgz", + "integrity": "sha512-vrozgXDQwYO72vHjUb/HnFbQx1exDjoKzqx23aXEg2a9VIg2TSFZ8FmeZpTjUCFMYw7mpX4BE2SFu8wI7asYsw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@pkgr/core": "^0.1.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/unts" + } + }, "node_modules/thread-stream": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/thread-stream/-/thread-stream-3.1.0.tgz", @@ -3927,6 +8980,19 @@ "node": ">=14.0.0" } }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, "node_modules/toidentifier": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", @@ -3936,6 +9002,39 @@ "node": ">=0.6" } }, + "node_modules/ts-api-utils": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.4.0.tgz", + "integrity": "sha512-032cPxaEKwM+GT3vA5JXNzIaizx388rhsSW79vGRNGXfRRAdEAn2mvk36PvK5HnOchyWZ7afLEXqYCvPCrzuzQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=16" + }, + "peerDependencies": { + "typescript": ">=4.2.0" + } + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "dev": true, + "license": "0BSD" + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, "node_modules/type-detect": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.1.0.tgz", @@ -3952,27 +9051,103 @@ "integrity": "sha512-cUGJnCdr4STbePCgqNFbpVNCepa+kAVohJs1sLhxzdH+gnEoOd8VhbYa7pD3zZYGiURWM2xzEII3fQcRizDkYQ==", "license": "(MIT OR CC0-1.0)", "engines": { - "node": ">=6" + "node": ">=6" + } + }, + "node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "license": "MIT", + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/typed-array-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz", + "integrity": "sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/typed-array-byte-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.1.tgz", + "integrity": "sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-byte-offset": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.2.tgz", + "integrity": "sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==", + "dev": true, + "license": "MIT", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/type-is": { - "version": "1.6.18", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", - "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "node_modules/typed-array-length": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.6.tgz", + "integrity": "sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==", + "dev": true, "license": "MIT", "dependencies": { - "media-typer": "0.3.0", - "mime-types": "~2.1.24" + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13", + "possible-typed-array-names": "^1.0.0" }, "engines": { - "node": ">= 0.6" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/typescript": { "version": "5.6.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.3.tgz", "integrity": "sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==", - "dev": true, "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", @@ -3982,6 +9157,33 @@ "node": ">=14.17" } }, + "node_modules/typescript-eslint": { + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.15.0.tgz", + "integrity": "sha512-wY4FRGl0ZI+ZU4Jo/yjdBu0lVTSML58pu6PgGtJmCufvzfV565pUF6iACQt092uFOd49iLOTX/sEVmHtbSrS+w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/eslint-plugin": "8.15.0", + "@typescript-eslint/parser": "8.15.0", + "@typescript-eslint/utils": "8.15.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, "node_modules/ufo": { "version": "1.5.4", "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.5.4.tgz", @@ -3989,6 +9191,22 @@ "dev": true, "license": "MIT" }, + "node_modules/unbox-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", + "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "has-bigints": "^1.0.2", + "has-symbols": "^1.0.3", + "which-boxed-primitive": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/undici-types": { "version": "6.19.8", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", @@ -4029,6 +9247,16 @@ "dotenv": "*" } }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", @@ -4278,6 +9506,89 @@ "node": ">= 8" } }, + "node_modules/which-boxed-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-builtin-type": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.1.4.tgz", + "integrity": "sha512-bppkmBSsHFmIMSl8BO9TbsyzsvGjVoppt8xUiGzwiu/bhDCGxnpOKCxgqj6GuyHE0mINMDecBFPlOm2hzY084w==", + "dev": true, + "license": "MIT", + "dependencies": { + "function.prototype.name": "^1.1.6", + "has-tostringtag": "^1.0.2", + "is-async-function": "^2.0.0", + "is-date-object": "^1.0.5", + "is-finalizationregistry": "^1.0.2", + "is-generator-function": "^1.0.10", + "is-regex": "^1.1.4", + "is-weakref": "^1.0.2", + "isarray": "^2.0.5", + "which-boxed-primitive": "^1.0.2", + "which-collection": "^1.0.2", + "which-typed-array": "^1.1.15" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-collection": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz", + "integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-map": "^2.0.3", + "is-set": "^2.0.3", + "is-weakmap": "^2.0.2", + "is-weakset": "^2.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-typed-array": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz", + "integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==", + "dev": true, + "license": "MIT", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/why-is-node-running": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz", @@ -4295,12 +9606,267 @@ "node": ">=8" } }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/wrap-ansi-cjs/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", "license": "ISC" }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">= 6" + } + }, + "node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "dev": true, + "license": "MIT", + "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.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/yargs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/yargs/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/yargs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/yargs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/yocto-queue": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.1.1.tgz", diff --git a/package.json b/package.json index b24de45..c781d48 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "deployable", "version": "1.0.0", "private": true, - "description": "Approve deployments via signed comments from maintainers", + "description": "Approve deployments via comments from maintainers", "author": "Balena", "license": "Apache-2.0", "homepage": "https://github.com/balena-io-experimental/deployable", @@ -14,17 +14,23 @@ "scripts": { "build": "tsc", "start": "probot run ./lib/index.js", - "test": "vitest" + "test": "vitest", + "lint": "balena-lint src/ test/ && tsc --noEmit --project .", + "lint-fix": "balena-lint --fix src/ test/", + "prepare": "node -e \"try { (await import('husky')).default() } catch (e) { if (e.code !== 'ERR_MODULE_NOT_FOUND') throw e }\" --input-type module" }, "dependencies": { - "probot": "^13.0.1" + "probot": "^13.0.1", + "typescript": "^5.6.3" }, "devDependencies": { + "@balena/lint": "^9.1.2", "@types/node": "^20.0.0", + "husky": "^9.1.7", + "lint-staged": "^15.2.10", "nock": "^14.0.0-beta.5", "smee-client": "^2.0.0", - "vitest": "^1.3.1", - "typescript": "^5.3.3" + "vitest": "^1.3.1" }, "engines": { "node": ">= 18" diff --git a/src/client.ts b/src/client.ts new file mode 100644 index 0000000..fa7f406 --- /dev/null +++ b/src/client.ts @@ -0,0 +1,145 @@ +export async function whoAmI(context: any): Promise { + const query = `query { viewer { databaseId login } }`; + const { viewer } = await context.octokit.graphql(query); + console.log(`Authenticated as: ${viewer.login}`); + return { login: viewer.login, id: viewer.databaseId }; +} + +// https://octokit.github.io/rest.js/v21/#repos-get-collaborator-permission-level +// https://docs.github.com/en/rest/collaborators/collaborators#list-repository-collaborators +export async function hasRepoWriteAccess( + context: any, + username: string, +): Promise { + const request = context.repo({ + username, + }); + + const { + data: { permission }, + } = await context.octokit.rest.repos.getCollaboratorPermissionLevel(request); + + context.log.info( + `Permission level for ${username}: ${JSON.stringify(permission, null, 2)}`, + ); + + return ['admin', 'write'].includes(permission); +} + +export async function addCommentReaction( + context: any, + commentId: number, + content: string, +): Promise { + const request = context.repo({ + comment_id: commentId, + content, + }); + + await context.octokit.reactions.createForIssueComment(request); +} + +// https://docs.github.com/en/rest/deployments/deployments#list-deployments +// export async function listDeployments( +// context: any, +// sha: string +// ): Promise { +// const request = context.repo({ +// sha, +// }); +// const { data: deployments } = +// await context.octokit.rest.repos.listDeployments(request); +// return deployments; +// } + +export async function listPullRequestContributors( + context: any, + prNumber: number, +): Promise { + const commits = await this.listPullRequestCommits(context, prNumber); + return commits.map((c: any) => c.author.id); +} + +export async function listPullRequestCommits( + context: any, + prNumber: number, +): Promise { + const request = context.repo({ + pull_number: prNumber, + }); + const { data: commits } = + await context.octokit.rest.pulls.listPullRequestCommits(request); + return commits; +} + +export async function getPullRequest( + context: any, + prNumber: number, +): Promise { + const request = context.repo({ + pull_number: prNumber, + }); + const { data: pullRequest } = await context.octokit.rest.pulls.get(request); + return pullRequest; +} + +// https://octokit.github.io/rest.js/v21/#actions-list-workflow-runs-for-repo +// https://docs.github.com/en/rest/actions/workflow-runs#list-workflow-runs-for-a-repository +// https://docs.github.com/en/search-github/getting-started-with-searching-on-github/understanding-the-search-syntax#query-for-dates +export async function listWorkflowRuns( + context: any, + headSha: string, + created: string, +): Promise { + // what is the status "requested" used for? + const request = context.repo({ + status: 'waiting', + created, + head_sha: headSha, + }); + + context.log.info( + `Searching for workflow runs with ${JSON.stringify(request, null, 2)}`, + ); + const { + data: { workflow_runs: runs }, + } = await context.octokit.rest.actions.listWorkflowRunsForRepo(request); + // console.log(JSON.stringify(runs, null, 2)) + return runs; +} + +// https://octokit.github.io/rest.js/v21/#actions-get-pending-deployments-for-run +// https://docs.github.com/en/rest/actions/workflow-runs?apiVersion=2022-11-28#get-pending-deployments-for-a-workflow-run +export async function listPendingDeployments( + context: any, + runId: number, +): Promise { + const request = context.repo({ + run_id: runId, + }); + const { data: deployments } = + await context.octokit.rest.actions.getPendingDeploymentsForRun(request); + // console.log(JSON.stringify(deployments, null, 2)) + return deployments; +} + +// https://octokit.github.io/rest.js/v21/#actions-review-custom-gates-for-run +// https://docs.github.com/en/rest/actions/workflow-runs#review-custom-deployment-protection-rules-for-a-workflow-run +export async function reviewWorkflowRun( + context: any, + runId: number, + environment: string, + state: string, + comment: string, +): Promise { + const request = context.repo({ + run_id: runId, + environment_name: environment, + state, + comment, + }); + + const { data: review } = + await context.octokit.rest.actions.reviewCustomGatesForRun(request); + return review; +} diff --git a/src/index.ts b/src/index.ts index ee03dce..1da0333 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,44 +1,177 @@ -import type { Probot } from "probot"; -// import { DeploymentApprover } from "./deployment"; - -// const approver = new DeploymentApprover(); +import type { Context, Probot } from 'probot'; +import type { + IssueCommentCreatedEvent, + DeploymentProtectionRuleRequestedEvent, +} from '@octokit/webhooks-types'; +import * as GitHubClient from './client.js'; export default (app: Probot) => { - app.on("issues.opened", async (context) => { - const issueComment = context.issue({ - body: "Thanks for opening this issue!", - }); - await context.octokit.issues.createComment(issueComment); - }); - - app.on("deployment_protection_rule.requested", async (context) => { - console.log("Deployment protection rule requested"); - console.log(JSON.stringify(context.payload, null, 2)); - }); - - app.on("issue_comment.created", async (context) => { - console.log("Issue comment created"); - console.log(JSON.stringify(context.payload, null, 2)); - - // post a reaction to the comment with :eyes: - const reaction = context.repo({ - comment_id: context.payload.comment.id, - content: "eyes" as - | "eyes" - | "+1" - | "-1" - | "laugh" - | "confused" - | "heart" - | "hooray" - | "rocket", - }); - - await context.octokit.reactions.createForIssueComment(reaction); - }); - // For more information on building apps: - // https://probot.github.io/docs/ - - // To get your app running against GitHub, see: - // https://probot.github.io/docs/development/ + app.on('deployment_protection_rule.requested', async (context: Context) => { + const { + event, + environment, + deployment, + deployment_callback_url: callbackUrl, + } = context.payload as DeploymentProtectionRuleRequestedEvent; + + if (!deployment || !event || !environment || !callbackUrl) { + context.log.error('Deployment protection rule not found'); + return; + } + + console.log('Deployment protection rule requested'); + // console.log(JSON.stringify(context.payload, null, 2)); + // console.log(JSON.stringify(deployment, null, 2)); + + if (!['pull_request', 'pull_request_target'].includes(event)) { + context.log.info('Ignoring non-pull request event'); + return; + } + + const appUser = await GitHubClient.whoAmI(context); + + if (!appUser) { + context.log.error('Failed to get app user'); + return; + } + + if (deployment.creator.login === appUser.login) { + context.log.info('Ignoring self deployment'); + return; + } + + if ( + !['balena-renovate[bot]', 'klutchell'].includes(deployment.creator.login) + ) { + context.log.info( + 'User %s is not on the auto-approve list', + deployment.creator.login, + ); + return; + } + + context.log.info('Approving deployment %s', deployment.id); + return context.octokit.request(`POST ${callbackUrl}`, { + environment_name: environment, + state: 'approved', + comment: `Auto-approved by ${appUser.login} on behalf of ${deployment.creator.login}`, + }); + }); + + app.on('issue_comment.created', async (context: Context) => { + const { issue, comment } = context.payload as IssueCommentCreatedEvent; + + console.log('Issue comment created'); + console.log(JSON.stringify(context.payload, null, 2)); + + if (issue.pull_request == null) { + context.log.info('Ignoring non-pull request comment'); + return; + } + + if (comment.user.type === 'Bot') { + context.log.info('Ignoring bot comment'); + return; + } + + if (!comment.body.startsWith('/deploy')) { + context.log.info('Ignoring non-deploy comment'); + return; + } + + if (comment.created_at !== comment.updated_at) { + context.log.info('Ignoring edited comment'); + return; + } + + // post a reaction to the comment with :eyes: + await GitHubClient.addCommentReaction(context, comment.id, 'eyes'); + + const appUser = await GitHubClient.whoAmI(context); + + if (!appUser) { + context.log.error('Failed to get app user'); + return; + } + + if (comment.user.login === appUser.login) { + context.log.info('Ignoring self comment'); + return; + } + + const hasRepoWriteAccess = await GitHubClient.hasRepoWriteAccess( + context, + comment.user.login, + ); + + if (!hasRepoWriteAccess) { + context.log.info('User does not have write access'); + return; + } + + const { + head: { sha }, + } = await GitHubClient.getPullRequest(context, issue.number); + + // Get the ISO date 2-min before the comment.created_at + const created = new Date(comment.created_at); + created.setMinutes(created.getMinutes() - 2); + + // filter workflow runs with the given hash and a creation date 2 minutes or more before the comment created date + // https://docs.github.com/en/search-github/getting-started-with-searching-on-github/understanding-the-search-syntax#query-for-dates + const runs = await GitHubClient.listWorkflowRuns( + context, + sha, + `<${created.toISOString()}`, + ); + + if (runs.length === 0) { + context.log.info('No workflow runs found for sha %s', sha); + return; + } + + for (const run of runs) { + const deployments = await GitHubClient.listPendingDeployments( + context, + run.id, + ); + + if (deployments.length === 0) { + context.log.info( + 'No pending deployments found for workflow run %s', + run.id, + ); + continue; + } + + for (const deployment of deployments) { + if (!deployment.current_user_can_approve) { + context.log.info( + 'User %s cannot approve deployment %s', + appUser.login, + deployment.id, + ); + continue; + } + + context.log.info( + 'Reviewing deployment with run %s and environment %s', + run.id, + deployment.environment.name, + ); + await GitHubClient.reviewWorkflowRun( + context, + run.id, + deployment.environment.name, + 'approved', + `Approved by ${comment.user.login} via ${appUser.login}`, + ); + } + } + }); + // For more information on building apps: + // https://probot.github.io/docs/ + + // To get your app running against GitHub, see: + // https://probot.github.io/docs/development/ }; diff --git a/test/fixtures/issues.opened.json b/test/fixtures/issues.opened.json deleted file mode 100644 index e570cd4..0000000 --- a/test/fixtures/issues.opened.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "action": "opened", - "issue": { - "number": 1, - "user": { - "login": "hiimbex" - } - }, - "repository": { - "name": "testing-things", - "owner": { - "login": "hiimbex" - } - }, - "installation": { - "id": 2 - } -} diff --git a/test/index.test.ts b/test/index.test.ts index 0eeaef1..0723c40 100644 --- a/test/index.test.ts +++ b/test/index.test.ts @@ -1,83 +1,197 @@ -// You can import your modules -// import index from '../src/index' +import nock from 'nock'; +import myProbotApp from '../src/index.js'; +import { Probot, ProbotOctokit } from 'probot'; +import fs from 'fs'; +import path from 'path'; +import { describe, beforeEach, afterEach, test, expect } from 'vitest'; -import nock from "nock"; -// Requiring our app implementation -import myProbotApp from "../src/index.js"; -import { Probot, ProbotOctokit } from "probot"; -// Requiring our fixtures -//import payload from "./fixtures/issues.opened.json" with { "type": "json"}; -import fs from "fs"; -import path from "path"; -import { fileURLToPath } from "url"; -import { describe, beforeEach, afterEach, test, expect } from "vitest"; - -const issueCreatedBody = { body: "Thanks for opening this issue!" }; +// Load test fixtures +const deploymentProtectionRule = JSON.parse( + fs.readFileSync( + path.join(__dirname, 'fixtures/deployment_protection_rule.requested.json'), + 'utf-8', + ), +); -const __dirname = path.dirname(fileURLToPath(import.meta.url)); +const issueComment = JSON.parse( + fs.readFileSync( + path.join(__dirname, 'fixtures/issue_comment.created.json'), + 'utf-8', + ), +); const privateKey = fs.readFileSync( - path.join(__dirname, "fixtures/mock-cert.pem"), - "utf-8", + path.join(__dirname, 'fixtures/mock-cert.pem'), + 'utf-8', ); -const payload = JSON.parse( - fs.readFileSync(path.join(__dirname, "fixtures/issues.opened.json"), "utf-8"), -); +describe('GitHub Deployment App', () => { + let probot: any; -describe("My Probot app", () => { - let probot: any; - - beforeEach(() => { - nock.disableNetConnect(); - probot = new Probot({ - appId: 123, - privateKey, - // disable request throttling and retries for testing - Octokit: ProbotOctokit.defaults({ - retry: { enabled: false }, - throttle: { enabled: false }, - }), - }); - // Load our app into probot - probot.load(myProbotApp); - }); - - test("creates a comment when an issue is opened", async () => { - const mock = nock("https://api.github.com") - // Test that we correctly return a test token - .post("/app/installations/2/access_tokens") - .reply(200, { - token: "test", - permissions: { - issues: "write", - }, - }) - - // Test that a comment is posted - .post("/repos/hiimbex/testing-things/issues/1/comments", (body: any) => { - expect(body).toMatchObject(issueCreatedBody); - return true; - }) - .reply(200); - - // Receive a webhook event - await probot.receive({ name: "issues", payload }); - - expect(mock.pendingMocks()).toStrictEqual([]); - }); - - afterEach(() => { - nock.cleanAll(); - nock.enableNetConnect(); - }); -}); + beforeEach(() => { + nock.disableNetConnect(); + probot = new Probot({ + appId: 123, + privateKey, + // Disable request throttling and retries for testing + Octokit: ProbotOctokit.defaults({ + retry: { enabled: false }, + throttle: { enabled: false }, + }), + }); + probot.load(myProbotApp); + }); + + afterEach(() => { + nock.cleanAll(); + nock.enableNetConnect(); + }); + + describe('deployment_protection_rule.requested', () => { + test('approves deployment for allowed user', async () => { + // Mock installation token and GraphQL API call for whoAmI + const mock = nock('https://api.github.com') + .post('/app/installations/57364329/access_tokens') + .reply(200, { token: 'test', permissions: { issues: 'write' } }) + .post('/graphql') + .reply(200, { + data: { + viewer: { + login: 'test-bot', + databaseId: 123, + }, + }, + }) + // Mock deployment approval callback + .post( + '/repos/balena-io-experimental/deployable/actions/runs/11921637963/deployment_protection_rule', + ) + .reply(200); + + await probot.receive({ + name: 'deployment_protection_rule', + payload: deploymentProtectionRule, + }); + + expect(mock.pendingMocks()).toStrictEqual([]); + }); + + test('ignores deployment from self', async () => { + const payload = { + ...deploymentProtectionRule, + deployment: { + ...deploymentProtectionRule.deployment, + creator: { + login: 'test-bot', + }, + }, + }; -// For more information about testing with Jest see: -// https://facebook.github.io/jest/ + // Mock installation token and GraphQL API call for whoAmI + const mock = nock('https://api.github.com') + .post('/app/installations/57364329/access_tokens') + .reply(200, { token: 'test', permissions: { issues: 'write' } }) + .post('/graphql') + .reply(200, { + data: { + viewer: { + login: 'test-bot', + databaseId: 123, + }, + }, + }); -// For more information about using TypeScript in your tests, Jest recommends: -// https://github.com/kulshekhar/ts-jest + await probot.receive({ + name: 'deployment_protection_rule', + payload, + }); -// For more information about testing with Nock see: -// https://github.com/nock/nock + expect(mock.pendingMocks()).toStrictEqual([]); + }); + }); + + describe('issue_comment.created', () => { + test('processes valid deploy comment', async () => { + // Mock all required API calls + const mock = nock('https://api.github.com') + // Mock installation token + .post('/app/installations/57364329/access_tokens') + .reply(200, { token: 'test', permissions: { issues: 'write' } }) + // Add eyes reaction + .post( + '/repos/balena-io-experimental/deployable/issues/comments/2486741061/reactions', + ) + .reply(200) + // Get app identity + .post('/graphql') + .reply(200, { + data: { + viewer: { + login: 'test-bot', + databaseId: 123, + }, + }, + }) + // Check user permissions + .get( + '/repos/balena-io-experimental/deployable/collaborators/klutchell/permission', + ) + .reply(200, { permission: 'admin' }) + // Get PR details + .get('/repos/balena-io-experimental/deployable/pulls/2') + .reply(200, { + head: { sha: 'abec9b0' }, + }) + // List workflow runs + .get('/repos/balena-io-experimental/deployable/actions/runs') + .query(true) + .reply(200, { workflow_runs: [] }); + + await probot.receive({ + name: 'issue_comment', + payload: issueComment, + }); + + expect(mock.pendingMocks()).toStrictEqual([]); + }); + + test('ignores non-deploy comments', async () => { + const payload = { + ...issueComment, + comment: { + ...issueComment.comment, + body: 'Just a regular comment', + }, + }; + + await probot.receive({ + name: 'issue_comment', + payload, + }); + + // No API calls should be made + expect(nock.pendingMocks()).toStrictEqual([]); + }); + + test('ignores bot comments', async () => { + const payload = { + ...issueComment, + comment: { + ...issueComment.comment, + user: { + ...issueComment.comment.user, + type: 'Bot', + }, + }, + }; + + await probot.receive({ + name: 'issue_comment', + payload, + }); + + // No API calls should be made + expect(nock.pendingMocks()).toStrictEqual([]); + }); + }); +}); diff --git a/tsconfig.build.json b/tsconfig.build.json new file mode 100644 index 0000000..1fd7419 --- /dev/null +++ b/tsconfig.build.json @@ -0,0 +1,34 @@ +{ + "compilerOptions": { + "module": "NodeNext", + "target": "es2022", + "declaration": true, + "outDir": "lib/", + "rootDir": "src/", + "strict": true, + "strictPropertyInitialization": false, + "strictFunctionTypes": false, + "useUnknownInCatchVariables": false, + "noImplicitThis": false, + "noUnusedParameters": true, + "noUnusedLocals": true, + "preserveConstEnums": true, + "sourceMap": true, + "skipLibCheck": true, + "resolveJsonModule": true, + "esModuleInterop": true + }, + "include": [ + "src/**/*.ts" + ], + "exclude": [ + "node_modules", + "**/*.d.ts" + ], + "ts-node": { + "esm": true, + "experimentalResolver": true, + "experimentalTsImportSpecifiers": true, + "transpileOnly": true + } +} \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json index 5dd1cb9..061f44b 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,34 +1,14 @@ { + "extends": "./tsconfig.build", "compilerOptions": { - "module": "NodeNext", - "target": "es2022", - "declaration": true, - "outDir": "lib/", - "rootDir": "src/", - "strict": true, - "strictPropertyInitialization": false, - "strictFunctionTypes": false, - "useUnknownInCatchVariables": false, - "noImplicitThis": false, - "noUnusedParameters": true, - "noUnusedLocals": true, - "preserveConstEnums": true, - "sourceMap": true, - "skipLibCheck": true, - "resolveJsonModule": true, - "esModuleInterop": true + "rootDir": "./", + "allowJs": true, + "checkJs": true }, "include": [ - "src/**/*.ts" - ], - "exclude": [ - "node_modules", - "**/*.d.ts" - ], - "ts-node": { - "esm": true, - "experimentalResolver": true, - "experimentalTsImportSpecifiers": true, - "transpileOnly": true - } + "src/**/*.ts", + "*.js", + "*.ts", + "test/**/*.ts" + ] } From edaf5bdca51db364e4324dbd031fa0eb4cc8d2c0 Mon Sep 17 00:00:00 2001 From: Kyle Harding Date: Thu, 21 Nov 2024 14:53:58 -0500 Subject: [PATCH 07/15] Publish docker images to ghcr.io via flowzone Signed-off-by: Kyle Harding --- .github/workflows/flowzone.yml | 2 ++ Dockerfile | 14 +++++++++----- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/.github/workflows/flowzone.yml b/.github/workflows/flowzone.yml index 38c6114..06d3e03 100644 --- a/.github/workflows/flowzone.yml +++ b/.github/workflows/flowzone.yml @@ -47,3 +47,5 @@ jobs: { "environment": ["test"] } + docker_images: + ghcr.io/balena-io-experimental/deployable diff --git a/Dockerfile b/Dockerfile index bb1a3aa..4b68e0f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,8 +1,12 @@ -FROM node:20-slim +FROM node:22-slim + WORKDIR /usr/src/app + COPY package.json package-lock.json ./ -RUN npm ci --production -RUN npm cache clean --force -ENV NODE_ENV="production" -COPY . . +RUN HUSKY=0 npm ci --unsafe-perm --production && npm cache clean --force + +COPY . /usr/src/app + +RUN npx tsc --noEmit --project ./tsconfig.build.json + CMD [ "npm", "start" ] From 4a681d8b8ed67a5eecff9ee70799da4f588207b2 Mon Sep 17 00:00:00 2001 From: Kyle Harding Date: Fri, 22 Nov 2024 09:26:37 -0500 Subject: [PATCH 08/15] Enable code coverage for tests Signed-off-by: Kyle Harding --- package-lock.json | 933 ++++++++++++++++++++++++++++------------------ package.json | 5 +- 2 files changed, 564 insertions(+), 374 deletions(-) diff --git a/package-lock.json b/package-lock.json index a79ecc5..c995994 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,16 +15,31 @@ "devDependencies": { "@balena/lint": "^9.1.2", "@types/node": "^20.0.0", + "@vitest/coverage-v8": "^2.1.5", "husky": "^9.1.7", "lint-staged": "^15.2.10", "nock": "^14.0.0-beta.5", "smee-client": "^2.0.0", - "vitest": "^1.3.1" + "vitest": "^2.1.5" }, "engines": { "node": ">= 18" } }, + "node_modules/@ampproject/remapping": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", + "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, "node_modules/@babel/code-frame": { "version": "7.26.2", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.2.tgz", @@ -216,6 +231,13 @@ "npm": ">=9.8.1" } }, + "node_modules/@bcoe/v8-coverage": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", + "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", + "dev": true, + "license": "MIT" + }, "node_modules/@es-joy/jsdoccomment": { "version": "0.49.0", "resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.49.0.tgz", @@ -940,17 +962,14 @@ "node": ">=12" } }, - "node_modules/@jest/schemas": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", - "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "node_modules/@istanbuljs/schema": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", "dev": true, "license": "MIT", - "dependencies": { - "@sinclair/typebox": "^0.27.8" - }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=8" } }, "node_modules/@jridgewell/gen-mapping": { @@ -1549,6 +1568,17 @@ "dev": true, "license": "MIT" }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=14" + } + }, "node_modules/@pkgr/core": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.1.1.tgz", @@ -1600,9 +1630,9 @@ } }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.24.0.tgz", - "integrity": "sha512-Q6HJd7Y6xdB48x8ZNVDOqsbh2uByBhgK8PiQgPhwkIw/HC/YX5Ghq2mQY5sRMZWHb3VsFkWooUVOZHKr7DmDIA==", + "version": "4.27.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.27.3.tgz", + "integrity": "sha512-EzxVSkIvCFxUd4Mgm4xR9YXrcp976qVaHnqom/Tgm+vU79k4vV4eYTjmRvGfeoW8m9LVcsAy/lGjcgVegKEhLQ==", "cpu": [ "arm" ], @@ -1614,9 +1644,9 @@ ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.24.0.tgz", - "integrity": "sha512-ijLnS1qFId8xhKjT81uBHuuJp2lU4x2yxa4ctFPtG+MqEE6+C5f/+X/bStmxapgmwLwiL3ih122xv8kVARNAZA==", + "version": "4.27.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.27.3.tgz", + "integrity": "sha512-LJc5pDf1wjlt9o/Giaw9Ofl+k/vLUaYsE2zeQGH85giX2F+wn/Cg8b3c5CDP3qmVmeO5NzwVUzQQxwZvC2eQKw==", "cpu": [ "arm64" ], @@ -1628,9 +1658,9 @@ ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.24.0.tgz", - "integrity": "sha512-bIv+X9xeSs1XCk6DVvkO+S/z8/2AMt/2lMqdQbMrmVpgFvXlmde9mLcbQpztXm1tajC3raFDqegsH18HQPMYtA==", + "version": "4.27.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.27.3.tgz", + "integrity": "sha512-OuRysZ1Mt7wpWJ+aYKblVbJWtVn3Cy52h8nLuNSzTqSesYw1EuN6wKp5NW/4eSre3mp12gqFRXOKTcN3AI3LqA==", "cpu": [ "arm64" ], @@ -1642,9 +1672,9 @@ ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.24.0.tgz", - "integrity": "sha512-X6/nOwoFN7RT2svEQWUsW/5C/fYMBe4fnLK9DQk4SX4mgVBiTA9h64kjUYPvGQ0F/9xwJ5U5UfTbl6BEjaQdBQ==", + "version": "4.27.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.27.3.tgz", + "integrity": "sha512-xW//zjJMlJs2sOrCmXdB4d0uiilZsOdlGQIC/jjmMWT47lkLLoB1nsNhPUcnoqyi5YR6I4h+FjBpILxbEy8JRg==", "cpu": [ "x64" ], @@ -1655,10 +1685,38 @@ "darwin" ] }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.27.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.27.3.tgz", + "integrity": "sha512-58E0tIcwZ+12nK1WiLzHOD8I0d0kdrY/+o7yFVPRHuVGY3twBwzwDdTIBGRxLmyjciMYl1B/U515GJy+yn46qw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.27.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.27.3.tgz", + "integrity": "sha512-78fohrpcVwTLxg1ZzBMlwEimoAJmY6B+5TsyAZ3Vok7YabRBUvjYTsRXPTjGEvv/mfgVBepbW28OlMEz4w8wGA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.24.0.tgz", - "integrity": "sha512-0KXvIJQMOImLCVCz9uvvdPgfyWo93aHHp8ui3FrtOP57svqrF/roSSR5pjqL2hcMp0ljeGlU4q9o/rQaAQ3AYA==", + "version": "4.27.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.27.3.tgz", + "integrity": "sha512-h2Ay79YFXyQi+QZKo3ISZDyKaVD7uUvukEHTOft7kh00WF9mxAaxZsNs3o/eukbeKuH35jBvQqrT61fzKfAB/Q==", "cpu": [ "arm" ], @@ -1670,9 +1728,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.24.0.tgz", - "integrity": "sha512-it2BW6kKFVh8xk/BnHfakEeoLPv8STIISekpoF+nBgWM4d55CZKc7T4Dx1pEbTnYm/xEKMgy1MNtYuoA8RFIWw==", + "version": "4.27.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.27.3.tgz", + "integrity": "sha512-Sv2GWmrJfRY57urktVLQ0VKZjNZGogVtASAgosDZ1aUB+ykPxSi3X1nWORL5Jk0sTIIwQiPH7iE3BMi9zGWfkg==", "cpu": [ "arm" ], @@ -1684,9 +1742,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.24.0.tgz", - "integrity": "sha512-i0xTLXjqap2eRfulFVlSnM5dEbTVque/3Pi4g2y7cxrs7+a9De42z4XxKLYJ7+OhE3IgxvfQM7vQc43bwTgPwA==", + "version": "4.27.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.27.3.tgz", + "integrity": "sha512-FPoJBLsPW2bDNWjSrwNuTPUt30VnfM8GPGRoLCYKZpPx0xiIEdFip3dH6CqgoT0RnoGXptaNziM0WlKgBc+OWQ==", "cpu": [ "arm64" ], @@ -1698,9 +1756,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.24.0.tgz", - "integrity": "sha512-9E6MKUJhDuDh604Qco5yP/3qn3y7SLXYuiC0Rpr89aMScS2UAmK1wHP2b7KAa1nSjWJc/f/Lc0Wl1L47qjiyQw==", + "version": "4.27.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.27.3.tgz", + "integrity": "sha512-TKxiOvBorYq4sUpA0JT+Fkh+l+G9DScnG5Dqx7wiiqVMiRSkzTclP35pE6eQQYjP4Gc8yEkJGea6rz4qyWhp3g==", "cpu": [ "arm64" ], @@ -1712,9 +1770,9 @@ ] }, "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.24.0.tgz", - "integrity": "sha512-2XFFPJ2XMEiF5Zi2EBf4h73oR1V/lycirxZxHZNc93SqDN/IWhYYSYj8I9381ikUFXZrz2v7r2tOVk2NBwxrWw==", + "version": "4.27.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.27.3.tgz", + "integrity": "sha512-v2M/mPvVUKVOKITa0oCFksnQQ/TqGrT+yD0184/cWHIu0LoIuYHwox0Pm3ccXEz8cEQDLk6FPKd1CCm+PlsISw==", "cpu": [ "ppc64" ], @@ -1726,9 +1784,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.24.0.tgz", - "integrity": "sha512-M3Dg4hlwuntUCdzU7KjYqbbd+BLq3JMAOhCKdBE3TcMGMZbKkDdJ5ivNdehOssMCIokNHFOsv7DO4rlEOfyKpg==", + "version": "4.27.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.27.3.tgz", + "integrity": "sha512-LdrI4Yocb1a/tFVkzmOE5WyYRgEBOyEhWYJe4gsDWDiwnjYKjNs7PS6SGlTDB7maOHF4kxevsuNBl2iOcj3b4A==", "cpu": [ "riscv64" ], @@ -1740,9 +1798,9 @@ ] }, "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.24.0.tgz", - "integrity": "sha512-mjBaoo4ocxJppTorZVKWFpy1bfFj9FeCMJqzlMQGjpNPY9JwQi7OuS1axzNIk0nMX6jSgy6ZURDZ2w0QW6D56g==", + "version": "4.27.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.27.3.tgz", + "integrity": "sha512-d4wVu6SXij/jyiwPvI6C4KxdGzuZOvJ6y9VfrcleHTwo68fl8vZC5ZYHsCVPUi4tndCfMlFniWgwonQ5CUpQcA==", "cpu": [ "s390x" ], @@ -1754,9 +1812,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.24.0.tgz", - "integrity": "sha512-ZXFk7M72R0YYFN5q13niV0B7G8/5dcQ9JDp8keJSfr3GoZeXEoMHP/HlvqROA3OMbMdfr19IjCeNAnPUG93b6A==", + "version": "4.27.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.27.3.tgz", + "integrity": "sha512-/6bn6pp1fsCGEY5n3yajmzZQAh+mW4QPItbiWxs69zskBzJuheb3tNynEjL+mKOsUSFK11X4LYF2BwwXnzWleA==", "cpu": [ "x64" ], @@ -1768,9 +1826,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.24.0.tgz", - "integrity": "sha512-w1i+L7kAXZNdYl+vFvzSZy8Y1arS7vMgIy8wusXJzRrPyof5LAb02KGr1PD2EkRcl73kHulIID0M501lN+vobQ==", + "version": "4.27.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.27.3.tgz", + "integrity": "sha512-nBXOfJds8OzUT1qUreT/en3eyOXd2EH5b0wr2bVB5999qHdGKkzGzIyKYaKj02lXk6wpN71ltLIaQpu58YFBoQ==", "cpu": [ "x64" ], @@ -1782,9 +1840,9 @@ ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.24.0.tgz", - "integrity": "sha512-VXBrnPWgBpVDCVY6XF3LEW0pOU51KbaHhccHw6AS6vBWIC60eqsH19DAeeObl+g8nKAz04QFdl/Cefta0xQtUQ==", + "version": "4.27.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.27.3.tgz", + "integrity": "sha512-ogfbEVQgIZOz5WPWXF2HVb6En+kWzScuxJo/WdQTqEgeyGkaa2ui5sQav9Zkr7bnNCLK48uxmmK0TySm22eiuw==", "cpu": [ "arm64" ], @@ -1796,9 +1854,9 @@ ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.24.0.tgz", - "integrity": "sha512-xrNcGDU0OxVcPTH/8n/ShH4UevZxKIO6HJFK0e15XItZP2UcaiLFd5kiX7hJnqCbSztUF8Qot+JWBC/QXRPYWQ==", + "version": "4.27.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.27.3.tgz", + "integrity": "sha512-ecE36ZBMLINqiTtSNQ1vzWc5pXLQHlf/oqGp/bSbi7iedcjcNb6QbCBNG73Euyy2C+l/fn8qKWEwxr+0SSfs3w==", "cpu": [ "ia32" ], @@ -1810,9 +1868,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.24.0.tgz", - "integrity": "sha512-fbMkAF7fufku0N2dE5TBXcNlg0pt0cJue4xBRE2Qc5Vqikxr4VCgKj/ht6SMdFcOacVA9rqF70APJ8RN/4vMJw==", + "version": "4.27.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.27.3.tgz", + "integrity": "sha512-vliZLrDmYKyaUoMzEbMTg2JkerfBjn03KmAw9CykO0Zzkzoyd7o3iZNam/TpyWNjNT+Cz2iO3P9Smv2wgrR+Eg==", "cpu": [ "x64" ], @@ -1902,13 +1960,6 @@ "node": ">=8" } }, - "node_modules/@sinclair/typebox": { - "version": "0.27.8", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", - "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", - "dev": true, - "license": "MIT" - }, "node_modules/@types/body-parser": { "version": "1.19.5", "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", @@ -2335,91 +2386,172 @@ "url": "https://opencollective.com/eslint" } }, + "node_modules/@vitest/coverage-v8": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-2.1.5.tgz", + "integrity": "sha512-/RoopB7XGW7UEkUndRXF87A9CwkoZAJW01pj8/3pgmDVsjMH2IKy6H1A38po9tmUlwhSyYs0az82rbKd9Yaynw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@ampproject/remapping": "^2.3.0", + "@bcoe/v8-coverage": "^0.2.3", + "debug": "^4.3.7", + "istanbul-lib-coverage": "^3.2.2", + "istanbul-lib-report": "^3.0.1", + "istanbul-lib-source-maps": "^5.0.6", + "istanbul-reports": "^3.1.7", + "magic-string": "^0.30.12", + "magicast": "^0.3.5", + "std-env": "^3.8.0", + "test-exclude": "^7.0.1", + "tinyrainbow": "^1.2.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "@vitest/browser": "2.1.5", + "vitest": "2.1.5" + }, + "peerDependenciesMeta": { + "@vitest/browser": { + "optional": true + } + } + }, + "node_modules/@vitest/coverage-v8/node_modules/debug": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/@vitest/coverage-v8/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, "node_modules/@vitest/expect": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-1.6.0.tgz", - "integrity": "sha512-ixEvFVQjycy/oNgHjqsL6AZCDduC+tflRluaHIzKIsdbzkLn2U/iBnVeJwB6HsIjQBdfMR8Z0tRxKUsvFJEeWQ==", + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-2.1.5.tgz", + "integrity": "sha512-nZSBTW1XIdpZvEJyoP/Sy8fUg0b8od7ZpGDkTUcfJ7wz/VoZAFzFfLyxVxGFhUjJzhYqSbIpfMtl/+k/dpWa3Q==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/spy": "1.6.0", - "@vitest/utils": "1.6.0", - "chai": "^4.3.10" + "@vitest/spy": "2.1.5", + "@vitest/utils": "2.1.5", + "chai": "^5.1.2", + "tinyrainbow": "^1.2.0" }, "funding": { "url": "https://opencollective.com/vitest" } }, - "node_modules/@vitest/runner": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-1.6.0.tgz", - "integrity": "sha512-P4xgwPjwesuBiHisAVz/LSSZtDjOTPYZVmNAnpHHSR6ONrf8eCJOFRvUwdHn30F5M1fxhqtl7QZQUk2dprIXAg==", + "node_modules/@vitest/mocker": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-2.1.5.tgz", + "integrity": "sha512-XYW6l3UuBmitWqSUXTNXcVBUCRytDogBsWuNXQijc00dtnU/9OqpXWp4OJroVrad/gLIomAq9aW8yWDBtMthhQ==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/utils": "1.6.0", - "p-limit": "^5.0.0", - "pathe": "^1.1.1" + "@vitest/spy": "2.1.5", + "estree-walker": "^3.0.3", + "magic-string": "^0.30.12" }, "funding": { "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "msw": "^2.4.9", + "vite": "^5.0.0" + }, + "peerDependenciesMeta": { + "msw": { + "optional": true + }, + "vite": { + "optional": true + } } }, - "node_modules/@vitest/runner/node_modules/p-limit": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-5.0.0.tgz", - "integrity": "sha512-/Eaoq+QyLSiXQ4lyYV23f14mZRQcXnxfHrN0vCai+ak9G0pp9iEQukIIZq5NccEvwRB8PUnZT0KsOoDCINS1qQ==", + "node_modules/@vitest/pretty-format": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-2.1.5.tgz", + "integrity": "sha512-4ZOwtk2bqG5Y6xRGHcveZVr+6txkH7M2e+nPFd6guSoN638v/1XQ0K06eOpi0ptVU/2tW/pIU4IoPotY/GZ9fw==", "dev": true, "license": "MIT", "dependencies": { - "yocto-queue": "^1.0.0" + "tinyrainbow": "^1.2.0" }, - "engines": { - "node": ">=18" + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/runner": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-2.1.5.tgz", + "integrity": "sha512-pKHKy3uaUdh7X6p1pxOkgkVAFW7r2I818vHDthYLvUyjRfkKOU6P45PztOch4DZarWQne+VOaIMwA/erSSpB9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/utils": "2.1.5", + "pathe": "^1.1.2" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://opencollective.com/vitest" } }, "node_modules/@vitest/snapshot": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-1.6.0.tgz", - "integrity": "sha512-+Hx43f8Chus+DCmygqqfetcAZrDJwvTj0ymqjQq4CvmpKFSTVteEOBzCusu1x2tt4OJcvBflyHUE0DZSLgEMtQ==", + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-2.1.5.tgz", + "integrity": "sha512-zmYw47mhfdfnYbuhkQvkkzYroXUumrwWDGlMjpdUr4jBd3HZiV2w7CQHj+z7AAS4VOtWxI4Zt4bWt4/sKcoIjg==", "dev": true, "license": "MIT", "dependencies": { - "magic-string": "^0.30.5", - "pathe": "^1.1.1", - "pretty-format": "^29.7.0" + "@vitest/pretty-format": "2.1.5", + "magic-string": "^0.30.12", + "pathe": "^1.1.2" }, "funding": { "url": "https://opencollective.com/vitest" } }, "node_modules/@vitest/spy": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-1.6.0.tgz", - "integrity": "sha512-leUTap6B/cqi/bQkXUu6bQV5TZPx7pmMBKBQiI0rJA8c3pB56ZsaTbREnF7CJfmvAS4V2cXIBAh/3rVwrrCYgw==", + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-2.1.5.tgz", + "integrity": "sha512-aWZF3P0r3w6DiYTVskOYuhBc7EMc3jvn1TkBg8ttylFFRqNN2XGD7V5a4aQdk6QiUzZQ4klNBSpCLJgWNdIiNw==", "dev": true, "license": "MIT", "dependencies": { - "tinyspy": "^2.2.0" + "tinyspy": "^3.0.2" }, "funding": { "url": "https://opencollective.com/vitest" } }, "node_modules/@vitest/utils": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-1.6.0.tgz", - "integrity": "sha512-21cPiuGMoMZwiOHa2i4LXkMkMkCGzA+MVFV70jRwHo95dL4x/ts5GZhML1QWuy7yfp3WzK3lRvZi3JnXTYqrBw==", + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-2.1.5.tgz", + "integrity": "sha512-yfj6Yrp0Vesw2cwJbP+cl04OC+IHFsuQsrsJBL9pyGeQXE56v1UAOQco+SR55Vf1nQzfV0QJg1Qum7AaWUwwYg==", "dev": true, "license": "MIT", "dependencies": { - "diff-sequences": "^29.6.3", - "estree-walker": "^3.0.3", - "loupe": "^2.3.7", - "pretty-format": "^29.7.0" + "@vitest/pretty-format": "2.1.5", + "loupe": "^3.1.2", + "tinyrainbow": "^1.2.0" }, "funding": { "url": "https://opencollective.com/vitest" @@ -2536,19 +2668,6 @@ "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, - "node_modules/acorn-walk": { - "version": "8.3.4", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz", - "integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==", - "dev": true, - "license": "MIT", - "dependencies": { - "acorn": "^8.11.0" - }, - "engines": { - "node": ">=0.4.0" - } - }, "node_modules/aggregate-error": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", @@ -2825,13 +2944,13 @@ } }, "node_modules/assertion-error": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", - "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", + "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", "dev": true, "license": "MIT", "engines": { - "node": "*" + "node": ">=12" } }, "node_modules/atomic-sleep": { @@ -3004,22 +3123,20 @@ } }, "node_modules/chai": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.5.0.tgz", - "integrity": "sha512-RITGBfijLkBddZvnn8jdqoTypxvqbOLYQkGGxXzeFjVHvudaPw0HNFD9x928/eUwYWd2dPCugVqspGALTZZQKw==", + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/chai/-/chai-5.1.2.tgz", + "integrity": "sha512-aGtmf24DW6MLHHG5gCx4zaI3uBq3KRtxeVs0DjFH6Z0rDNbsvTxFASFvdj79pxjxZ8/5u3PIiN3IwEIQkiiuPw==", "dev": true, "license": "MIT", "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.1.0" + "assertion-error": "^2.0.1", + "check-error": "^2.1.1", + "deep-eql": "^5.0.1", + "loupe": "^3.1.0", + "pathval": "^2.0.0" }, "engines": { - "node": ">=4" + "node": ">=12" } }, "node_modules/chalk": { @@ -3037,16 +3154,13 @@ } }, "node_modules/check-error": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz", - "integrity": "sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.1.tgz", + "integrity": "sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==", "dev": true, "license": "MIT", - "dependencies": { - "get-func-name": "^2.0.2" - }, "engines": { - "node": "*" + "node": ">= 16" } }, "node_modules/clean-stack": { @@ -3296,13 +3410,6 @@ "dev": true, "license": "MIT" }, - "node_modules/confbox": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.1.8.tgz", - "integrity": "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==", - "dev": true, - "license": "MIT" - }, "node_modules/content-disposition": { "version": "0.5.4", "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", @@ -3463,14 +3570,11 @@ } }, "node_modules/deep-eql": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.4.tgz", - "integrity": "sha512-SUwdGfqdKOwxCPeVYjwSyRpJ7Z+fhpwIAtmCUdZIWZ/YP5R9WAsyuSgpLVDi9bjWoN2LXHNss/dk3urXtdQxGg==", + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz", + "integrity": "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==", "dev": true, "license": "MIT", - "dependencies": { - "type-detect": "^4.0.0" - }, "engines": { "node": ">=6" } @@ -3843,16 +3947,6 @@ "node": ">=0.10.0" } }, - "node_modules/diff-sequences": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", - "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, "node_modules/doctrine": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", @@ -4887,6 +4981,16 @@ "node": ">=0.10.0" } }, + "node_modules/expect-type": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.1.0.tgz", + "integrity": "sha512-bFi65yM+xZgk+u/KRIpekdSYkTB5W1pEf0Lt8Q8Msh7b+eQ7LXVtIB1Bkm4fvclDEL1b2CZkMhv2mOeF8tMdkA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/express": { "version": "4.21.1", "resolved": "https://registry.npmjs.org/express/-/express-4.21.1.tgz", @@ -5218,16 +5322,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/get-func-name": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", - "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": "*" - } - }, "node_modules/get-intrinsic": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", @@ -5527,6 +5621,13 @@ "node": ">=0.10.0" } }, + "node_modules/html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true, + "license": "MIT" + }, "node_modules/http-errors": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", @@ -6155,6 +6256,108 @@ "dev": true, "license": "ISC" }, + "node_modules/istanbul-lib-coverage": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", + "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-report": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", + "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^4.0.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-report/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-report/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-source-maps": { + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-5.0.6.tgz", + "integrity": "sha512-yg2d+Em4KizZC5niWhQaIomgf5WlL4vOOjZ5xGCmF8SnPE/mDWWXgvRExdcpCgh9lLRRa1/fSYp2ymmbJ1pI+A==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.23", + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-source-maps/node_modules/debug": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/istanbul-lib-source-maps/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/istanbul-reports": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.7.tgz", + "integrity": "sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/iterator.prototype": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.3.tgz", @@ -6205,13 +6408,6 @@ "node": ">=10" } }, - "node_modules/js-tokens": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-9.0.0.tgz", - "integrity": "sha512-WriZw1luRMlmV3LGJaR6QOJjWwgLUTf89OwT2lUOyjX2dJGBwgmIkbcz+7WFZjrZM635JOIR517++e/67CP9dQ==", - "dev": true, - "license": "MIT" - }, "node_modules/js-yaml": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", @@ -6604,23 +6800,6 @@ "node": ">=6" } }, - "node_modules/local-pkg": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-0.5.0.tgz", - "integrity": "sha512-ok6z3qlYyCDS4ZEU27HaU6x/xZa9Whf8jD4ptH5UZTQYZVYeb9bnZ3ojVhiJNLiXK1Hfc0GNbLXcmZ5plLDDBg==", - "dev": true, - "license": "MIT", - "dependencies": { - "mlly": "^1.4.2", - "pkg-types": "^1.0.3" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/antfu" - } - }, "node_modules/localforage": { "version": "1.10.0", "resolved": "https://registry.npmjs.org/localforage/-/localforage-1.10.0.tgz", @@ -6841,14 +7020,11 @@ "license": "MIT" }, "node_modules/loupe": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.7.tgz", - "integrity": "sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.1.2.tgz", + "integrity": "sha512-23I4pFZHmAemUnz8WZXbYRSKYj801VDaNv9ETuMh7IrMc7VuVVSo+Z9iLE3ni30+U48iDWfi30d3twAXBYmnCg==", "dev": true, - "license": "MIT", - "dependencies": { - "get-func-name": "^2.0.1" - } + "license": "MIT" }, "node_modules/lru-cache": { "version": "10.4.3", @@ -6866,6 +7042,34 @@ "@jridgewell/sourcemap-codec": "^1.5.0" } }, + "node_modules/magicast": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/magicast/-/magicast-0.3.5.tgz", + "integrity": "sha512-L0WhttDl+2BOsybvEOLK7fW3UA0OQ0IQ2d6Zl2x/a6vVRs3bAY0ECOSHHeL5jD+SbOpOCUEi0y1DgHEn9Qn1AQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.25.4", + "@babel/types": "^7.25.4", + "source-map-js": "^1.2.0" + } + }, + "node_modules/make-dir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", + "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^7.5.3" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", @@ -7009,19 +7213,6 @@ "node": ">=16 || 14 >=14.17" } }, - "node_modules/mlly": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.7.2.tgz", - "integrity": "sha512-tN3dvVHYVz4DhSXinXIk7u9syPYaJvio118uomkovAtWBT+RdbP6Lfh/5Lvo519YMmwBafwlh20IPTXIStscpA==", - "dev": true, - "license": "MIT", - "dependencies": { - "acorn": "^8.12.1", - "pathe": "^1.1.2", - "pkg-types": "^1.2.0", - "ufo": "^1.5.4" - } - }, "node_modules/mri": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/mri/-/mri-1.1.4.tgz", @@ -7531,13 +7722,13 @@ "license": "MIT" }, "node_modules/pathval": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", - "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-2.0.0.tgz", + "integrity": "sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==", "dev": true, "license": "MIT", "engines": { - "node": "*" + "node": ">= 14.16" } }, "node_modules/picocolors": { @@ -7676,18 +7867,6 @@ "node": ">=6" } }, - "node_modules/pkg-types": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.2.1.tgz", - "integrity": "sha512-sQoqa8alT3nHjGuTjuKgOnvjo4cljkufdtLMnO2LBP/wRwuDlo1tkaEdMxCRhyGRPacv/ztlZgDPm2b7FAmEvw==", - "dev": true, - "license": "MIT", - "dependencies": { - "confbox": "^0.1.8", - "mlly": "^1.7.2", - "pathe": "^1.1.2" - } - }, "node_modules/please-upgrade-node": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/please-upgrade-node/-/please-upgrade-node-3.2.0.tgz", @@ -7763,34 +7942,6 @@ "url": "https://github.com/prettier/prettier?sponsor=1" } }, - "node_modules/pretty-format": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", - "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/schemas": "^29.6.3", - "ansi-styles": "^5.0.0", - "react-is": "^18.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/pretty-format/node_modules/ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, "node_modules/probot": { "version": "13.3.8", "resolved": "https://registry.npmjs.org/probot/-/probot-13.3.8.tgz", @@ -7965,13 +8116,6 @@ "node": ">= 0.8" } }, - "node_modules/react-is": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", - "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", - "dev": true, - "license": "MIT" - }, "node_modules/readable-stream": { "version": "3.6.2", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", @@ -8180,9 +8324,9 @@ "license": "MIT" }, "node_modules/rollup": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.24.0.tgz", - "integrity": "sha512-DOmrlGSXNk1DM0ljiQA+i+o0rSLhtii1je5wgk60j49d1jHT5YYttBv1iWOnYSTG+fZZESUOSNiAl89SIet+Cg==", + "version": "4.27.3", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.27.3.tgz", + "integrity": "sha512-SLsCOnlmGt9VoZ9Ek8yBK8tAdmPHeppkw+Xa7yDlCEhDTvwYei03JlWo1fdc7YTfLZ4tD8riJCUyAgTbszk1fQ==", "dev": true, "license": "MIT", "dependencies": { @@ -8196,22 +8340,24 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.24.0", - "@rollup/rollup-android-arm64": "4.24.0", - "@rollup/rollup-darwin-arm64": "4.24.0", - "@rollup/rollup-darwin-x64": "4.24.0", - "@rollup/rollup-linux-arm-gnueabihf": "4.24.0", - "@rollup/rollup-linux-arm-musleabihf": "4.24.0", - "@rollup/rollup-linux-arm64-gnu": "4.24.0", - "@rollup/rollup-linux-arm64-musl": "4.24.0", - "@rollup/rollup-linux-powerpc64le-gnu": "4.24.0", - "@rollup/rollup-linux-riscv64-gnu": "4.24.0", - "@rollup/rollup-linux-s390x-gnu": "4.24.0", - "@rollup/rollup-linux-x64-gnu": "4.24.0", - "@rollup/rollup-linux-x64-musl": "4.24.0", - "@rollup/rollup-win32-arm64-msvc": "4.24.0", - "@rollup/rollup-win32-ia32-msvc": "4.24.0", - "@rollup/rollup-win32-x64-msvc": "4.24.0", + "@rollup/rollup-android-arm-eabi": "4.27.3", + "@rollup/rollup-android-arm64": "4.27.3", + "@rollup/rollup-darwin-arm64": "4.27.3", + "@rollup/rollup-darwin-x64": "4.27.3", + "@rollup/rollup-freebsd-arm64": "4.27.3", + "@rollup/rollup-freebsd-x64": "4.27.3", + "@rollup/rollup-linux-arm-gnueabihf": "4.27.3", + "@rollup/rollup-linux-arm-musleabihf": "4.27.3", + "@rollup/rollup-linux-arm64-gnu": "4.27.3", + "@rollup/rollup-linux-arm64-musl": "4.27.3", + "@rollup/rollup-linux-powerpc64le-gnu": "4.27.3", + "@rollup/rollup-linux-riscv64-gnu": "4.27.3", + "@rollup/rollup-linux-s390x-gnu": "4.27.3", + "@rollup/rollup-linux-x64-gnu": "4.27.3", + "@rollup/rollup-linux-x64-musl": "4.27.3", + "@rollup/rollup-win32-arm64-msvc": "4.27.3", + "@rollup/rollup-win32-ia32-msvc": "4.27.3", + "@rollup/rollup-win32-x64-msvc": "4.27.3", "fsevents": "~2.3.2" } }, @@ -8619,9 +8765,9 @@ } }, "node_modules/std-env": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.7.0.tgz", - "integrity": "sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg==", + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.8.0.tgz", + "integrity": "sha512-Bc3YwwCB+OzldMxOXJIIvC6cPRWr/LxOp48CdQTOkPyk/t4JWWJbrilwBd7RJzKV8QW7tJkcgAmeuLLJugl5/w==", "dev": true, "license": "MIT" }, @@ -8889,19 +9035,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/strip-literal": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-2.1.0.tgz", - "integrity": "sha512-Op+UycaUt/8FbN/Z2TWPBLge3jWrP3xj10f3fnYxf052bKuS3EKs1ZQcVGjnEMdsNVAM+plXRdmjrZ/KgG3Skw==", - "dev": true, - "license": "MIT", - "dependencies": { - "js-tokens": "^9.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/antfu" - } - }, "node_modules/supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", @@ -8944,6 +9077,75 @@ "url": "https://opencollective.com/unts" } }, + "node_modules/test-exclude": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-7.0.1.tgz", + "integrity": "sha512-pFYqmTw68LXVjeWJMST4+borgQP2AyMNbg1BpZh9LbyhUeNkeaPF9gzfPGUAnSMV3qPYdWUwDIjjCLiSDOl7vg==", + "dev": true, + "license": "ISC", + "dependencies": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^10.4.1", + "minimatch": "^9.0.4" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/test-exclude/node_modules/glob": { + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "dev": true, + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/test-exclude/node_modules/jackspeak": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/test-exclude/node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/thread-stream": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/thread-stream/-/thread-stream-3.1.0.tgz", @@ -8960,10 +9162,27 @@ "dev": true, "license": "MIT" }, + "node_modules/tinyexec": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.1.tgz", + "integrity": "sha512-WiCJLEECkO18gwqIp6+hJg0//p23HXp4S+gGtAKu3mI2F2/sXC4FvHvXvB0zJVVaTPhx1/tOwdbRsa1sOBIKqQ==", + "dev": true, + "license": "MIT" + }, "node_modules/tinypool": { - "version": "0.8.4", - "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-0.8.4.tgz", - "integrity": "sha512-i11VH5gS6IFeLY3gMBQ00/MmLncVP7JLXOw1vlgkytLmJK7QnEr7NXf0LBdxfmNPAeyetukOk0bOYrJrFGjYJQ==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-1.0.2.tgz", + "integrity": "sha512-al6n+QEANGFOMf/dmUMsuS5/r9B06uwlyNjZZql/zv8J7ybHCgoihBNORZCY2mzUuAnomQa2JdhyHKzZxPCrFA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.0.0 || >=20.0.0" + } + }, + "node_modules/tinyrainbow": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-1.2.0.tgz", + "integrity": "sha512-weEDEq7Z5eTHPDh4xjX789+fHfF+P8boiFB+0vbWzpbnbsEr/GRaohi/uMKxg8RZMXnl1ItAi/IUHWMsjDV7kQ==", "dev": true, "license": "MIT", "engines": { @@ -8971,9 +9190,9 @@ } }, "node_modules/tinyspy": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-2.2.1.tgz", - "integrity": "sha512-KYad6Vy5VDWV4GH3fjpseMQ/XU2BhIYP7Vzd0LG44qRWm/Yt2WCOTicFdvmgo6gWaqooMQCawTtILVQJupKu7A==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-3.0.2.tgz", + "integrity": "sha512-n1cw8k1k0x4pgA2+9XrOkFydTerNcJ1zWCO5Nn9scWHTD+5tp8dghT2x1uduQePZTZgd3Tupf+x9BxJjeJi77Q==", "dev": true, "license": "MIT", "engines": { @@ -9035,16 +9254,6 @@ "node": ">= 0.8.0" } }, - "node_modules/type-detect": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.1.0.tgz", - "integrity": "sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, "node_modules/type-fest": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.3.1.tgz", @@ -9184,13 +9393,6 @@ } } }, - "node_modules/ufo": { - "version": "1.5.4", - "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.5.4.tgz", - "integrity": "sha512-UsUk3byDzKd04EyoZ7U4DOlxQaD14JUKQl6/P7wiX4FNvUfm3XL246n9W5AmqwW5RSFJ27NAuM0iLscAOYUiGQ==", - "dev": true, - "license": "MIT" - }, "node_modules/unbox-primitive": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", @@ -9292,9 +9494,9 @@ } }, "node_modules/vite": { - "version": "5.4.9", - "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.9.tgz", - "integrity": "sha512-20OVpJHh0PAM0oSOELa5GaZNWeDjcAvQjGXy2Uyr+Tp+/D2/Hdz6NLgpJLsarPTA2QJ6v8mX2P1ZfbsSKvdMkg==", + "version": "5.4.11", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.11.tgz", + "integrity": "sha512-c7jFQRklXua0mTzneGW9QVyxFjUgwcihC4bXEtujIo2ouWCe1Ajt/amn2PCxYnhYfd5k09JX3SB7OYWFKYqj8Q==", "dev": true, "license": "MIT", "dependencies": { @@ -9352,16 +9554,16 @@ } }, "node_modules/vite-node": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-1.6.0.tgz", - "integrity": "sha512-de6HJgzC+TFzOu0NTC4RAIsyf/DY/ibWDYQUcuEA84EMHhcefTUGkjFHKKEJhQN4A+6I0u++kr3l36ZF2d7XRw==", + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-2.1.5.tgz", + "integrity": "sha512-rd0QIgx74q4S1Rd56XIiL2cYEdyWn13cunYBIuqh9mpmQr7gGS0IxXoP8R6OaZtNQQLyXSWbd4rXKYUbhFpK5w==", "dev": true, "license": "MIT", "dependencies": { "cac": "^6.7.14", - "debug": "^4.3.4", - "pathe": "^1.1.1", - "picocolors": "^1.0.0", + "debug": "^4.3.7", + "es-module-lexer": "^1.5.4", + "pathe": "^1.1.2", "vite": "^5.0.0" }, "bin": { @@ -9400,32 +9602,32 @@ "license": "MIT" }, "node_modules/vitest": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/vitest/-/vitest-1.6.0.tgz", - "integrity": "sha512-H5r/dN06swuFnzNFhq/dnz37bPXnq8xB2xB5JOVk8K09rUtoeNN+LHWkoQ0A/i3hvbUKKcCei9KpbxqHMLhLLA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@vitest/expect": "1.6.0", - "@vitest/runner": "1.6.0", - "@vitest/snapshot": "1.6.0", - "@vitest/spy": "1.6.0", - "@vitest/utils": "1.6.0", - "acorn-walk": "^8.3.2", - "chai": "^4.3.10", - "debug": "^4.3.4", - "execa": "^8.0.1", - "local-pkg": "^0.5.0", - "magic-string": "^0.30.5", - "pathe": "^1.1.1", - "picocolors": "^1.0.0", - "std-env": "^3.5.0", - "strip-literal": "^2.0.0", - "tinybench": "^2.5.1", - "tinypool": "^0.8.3", + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-2.1.5.tgz", + "integrity": "sha512-P4ljsdpuzRTPI/kbND2sDZ4VmieerR2c9szEZpjc+98Z9ebvnXmM5+0tHEKqYZumXqlvnmfWsjeFOjXVriDG7A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/expect": "2.1.5", + "@vitest/mocker": "2.1.5", + "@vitest/pretty-format": "^2.1.5", + "@vitest/runner": "2.1.5", + "@vitest/snapshot": "2.1.5", + "@vitest/spy": "2.1.5", + "@vitest/utils": "2.1.5", + "chai": "^5.1.2", + "debug": "^4.3.7", + "expect-type": "^1.1.0", + "magic-string": "^0.30.12", + "pathe": "^1.1.2", + "std-env": "^3.8.0", + "tinybench": "^2.9.0", + "tinyexec": "^0.3.1", + "tinypool": "^1.0.1", + "tinyrainbow": "^1.2.0", "vite": "^5.0.0", - "vite-node": "1.6.0", - "why-is-node-running": "^2.2.2" + "vite-node": "2.1.5", + "why-is-node-running": "^2.3.0" }, "bin": { "vitest": "vitest.mjs" @@ -9439,8 +9641,8 @@ "peerDependencies": { "@edge-runtime/vm": "*", "@types/node": "^18.0.0 || >=20.0.0", - "@vitest/browser": "1.6.0", - "@vitest/ui": "1.6.0", + "@vitest/browser": "2.1.5", + "@vitest/ui": "2.1.5", "happy-dom": "*", "jsdom": "*" }, @@ -9866,19 +10068,6 @@ "engines": { "node": ">=8" } - }, - "node_modules/yocto-queue": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.1.1.tgz", - "integrity": "sha512-b4JR1PFR10y1mKjhHY9LaGo6tmrgjit7hxVIeAmyMw3jegXR4dhYqLaQF5zMXZxY7tLpMyJeLjr1C4rLmkVe8g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12.20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } } } } diff --git a/package.json b/package.json index c781d48..0d6780b 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,7 @@ "scripts": { "build": "tsc", "start": "probot run ./lib/index.js", - "test": "vitest", + "test": "vitest --coverage", "lint": "balena-lint src/ test/ && tsc --noEmit --project .", "lint-fix": "balena-lint --fix src/ test/", "prepare": "node -e \"try { (await import('husky')).default() } catch (e) { if (e.code !== 'ERR_MODULE_NOT_FOUND') throw e }\" --input-type module" @@ -26,11 +26,12 @@ "devDependencies": { "@balena/lint": "^9.1.2", "@types/node": "^20.0.0", + "@vitest/coverage-v8": "^2.1.5", "husky": "^9.1.7", "lint-staged": "^15.2.10", "nock": "^14.0.0-beta.5", "smee-client": "^2.0.0", - "vitest": "^1.3.1" + "vitest": "^2.1.5" }, "engines": { "node": ">= 18" From 44f485b95b253974fa0cd19b13c42c5fe598a6bd Mon Sep 17 00:00:00 2001 From: Kyle Harding Date: Fri, 22 Nov 2024 14:20:52 -0500 Subject: [PATCH 09/15] Extend tests Signed-off-by: Kyle Harding --- package.json | 4 +- src/index.ts | 45 ++++--- test/index.test.ts | 307 +++++++++++++++++++++++++++++++++++++-------- 3 files changed, 288 insertions(+), 68 deletions(-) diff --git a/package.json b/package.json index 0d6780b..f6fc5b0 100644 --- a/package.json +++ b/package.json @@ -13,8 +13,8 @@ ], "scripts": { "build": "tsc", - "start": "probot run ./lib/index.js", - "test": "vitest --coverage", + "start": "probot run ./lib/src/index.js", + "test": "npm run lint && vitest --coverage", "lint": "balena-lint src/ test/ && tsc --noEmit --project .", "lint-fix": "balena-lint --fix src/ test/", "prepare": "node -e \"try { (await import('husky')).default() } catch (e) { if (e.code !== 'ERR_MODULE_NOT_FOUND') throw e }\" --input-type module" diff --git a/src/index.ts b/src/index.ts index 1da0333..270fc72 100644 --- a/src/index.ts +++ b/src/index.ts @@ -19,7 +19,7 @@ export default (app: Probot) => { return; } - console.log('Deployment protection rule requested'); + console.log('Received event: deployment_protection_rule.requested'); // console.log(JSON.stringify(context.payload, null, 2)); // console.log(JSON.stringify(deployment, null, 2)); @@ -28,11 +28,11 @@ export default (app: Probot) => { return; } - const appUser = await GitHubClient.whoAmI(context); - - if (!appUser) { - context.log.error('Failed to get app user'); - return; + let appUser; + try { + appUser = await GitHubClient.whoAmI(context); + } catch (error) { + throw new Error('Failed to get app user: %s', error); } if (deployment.creator.login === appUser.login) { @@ -40,9 +40,7 @@ export default (app: Probot) => { return; } - if ( - !['balena-renovate[bot]', 'klutchell'].includes(deployment.creator.login) - ) { + if (!['balena-renovate[bot]'].includes(deployment.creator.login)) { context.log.info( 'User %s is not on the auto-approve list', deployment.creator.login, @@ -50,6 +48,19 @@ export default (app: Probot) => { return; } + // const hasRepoWriteAccess = await GitHubClient.hasRepoWriteAccess( + // context, + // deployment.creator.login + // ); + + // if (!hasRepoWriteAccess) { + // context.log.info( + // "User %s does not have write access", + // deployment.creator.login + // ); + // return; + // } + context.log.info('Approving deployment %s', deployment.id); return context.octokit.request(`POST ${callbackUrl}`, { environment_name: environment, @@ -61,8 +72,8 @@ export default (app: Probot) => { app.on('issue_comment.created', async (context: Context) => { const { issue, comment } = context.payload as IssueCommentCreatedEvent; - console.log('Issue comment created'); - console.log(JSON.stringify(context.payload, null, 2)); + console.log('Received event: issue_comment.created'); + // console.log(JSON.stringify(context.payload, null, 2)); if (issue.pull_request == null) { context.log.info('Ignoring non-pull request comment'); @@ -87,14 +98,14 @@ export default (app: Probot) => { // post a reaction to the comment with :eyes: await GitHubClient.addCommentReaction(context, comment.id, 'eyes'); - const appUser = await GitHubClient.whoAmI(context); - - if (!appUser) { - context.log.error('Failed to get app user'); - return; + let appUser; + try { + appUser = await GitHubClient.whoAmI(context); + } catch (error) { + throw new Error('Failed to get app user: %s', error); } - if (comment.user.login === appUser.login) { + if (appUser.login === comment.user.login) { context.log.info('Ignoring self comment'); return; } diff --git a/test/index.test.ts b/test/index.test.ts index 0723c40..dbe6f37 100644 --- a/test/index.test.ts +++ b/test/index.test.ts @@ -5,26 +5,59 @@ import fs from 'fs'; import path from 'path'; import { describe, beforeEach, afterEach, test, expect } from 'vitest'; -// Load test fixtures -const deploymentProtectionRule = JSON.parse( - fs.readFileSync( - path.join(__dirname, 'fixtures/deployment_protection_rule.requested.json'), - 'utf-8', - ), -); - -const issueComment = JSON.parse( - fs.readFileSync( - path.join(__dirname, 'fixtures/issue_comment.created.json'), - 'utf-8', - ), -); - const privateKey = fs.readFileSync( path.join(__dirname, 'fixtures/mock-cert.pem'), 'utf-8', ); +// Test fixtures +const testFixtures = { + deployment_protection_rule: { + action: 'requested', + environment: 'test', + event: 'pull_request', + deployment_callback_url: + 'https://api.github.com/repos/test-org/test-repo/actions/runs/1234/deployment_protection_rule', + deployment: { + creator: { + login: 'balena-renovate[bot]', + }, + }, + installation: { id: 12345678 }, + repository: { + owner: { + login: 'test-org', + }, + name: 'test-repo', + }, + }, + issue_comment: { + action: 'created', + issue: { + // eslint-disable-next-line id-denylist + number: 123, + pull_request: {}, + }, + comment: { + id: 456, + user: { + login: 'test-user', + type: 'User', + }, + body: '/deploy please', + created_at: '2024-01-01T00:00:00Z', + updated_at: '2024-01-01T00:00:00Z', + }, + installation: { id: 12345678 }, + repository: { + owner: { + login: 'test-org', + }, + name: 'test-repo', + }, + }, +}; + describe('GitHub Deployment App', () => { let probot: any; @@ -49,9 +82,8 @@ describe('GitHub Deployment App', () => { describe('deployment_protection_rule.requested', () => { test('approves deployment for allowed user', async () => { - // Mock installation token and GraphQL API call for whoAmI const mock = nock('https://api.github.com') - .post('/app/installations/57364329/access_tokens') + .post('/app/installations/12345678/access_tokens') .reply(200, { token: 'test', permissions: { issues: 'write' } }) .post('/graphql') .reply(200, { @@ -62,34 +94,109 @@ describe('GitHub Deployment App', () => { }, }, }) - // Mock deployment approval callback .post( - '/repos/balena-io-experimental/deployable/actions/runs/11921637963/deployment_protection_rule', + '/repos/test-org/test-repo/actions/runs/1234/deployment_protection_rule', ) .reply(200); await probot.receive({ name: 'deployment_protection_rule', - payload: deploymentProtectionRule, + payload: testFixtures.deployment_protection_rule, + }); + + expect(mock.pendingMocks()).toStrictEqual([]); + }); + + test('ignores events with missing properties', async () => { + const payload = { + ...testFixtures.deployment_protection_rule, + event: null, + }; + + const result = await probot.receive({ + name: 'deployment_protection_rule', + payload: payload, + }); + + expect(result).toBeUndefined(); + expect(nock.pendingMocks()).toStrictEqual([]); + }); + + test('ignores non-pull-request events', async () => { + const payload = { + ...testFixtures.deployment_protection_rule, + event: 'push', + }; + + const result = await probot.receive({ + name: 'deployment_protection_rule', + payload: payload, }); + expect(result).toBeUndefined(); + expect(nock.pendingMocks()).toStrictEqual([]); + }); + + test('throws error on failure to get app user', async () => { + const mock = nock('https://api.github.com') + .post('/app/installations/12345678/access_tokens') + .reply(200, { token: 'test', permissions: { issues: 'write' } }) + .post('/graphql') + .reply(404, { message: 'Not Found' }); + + await expect( + probot.receive({ + name: 'deployment_protection_rule', + payload: testFixtures.deployment_protection_rule, + }), + ).rejects.toThrow('Failed to get app user'); + expect(mock.pendingMocks()).toStrictEqual([]); }); test('ignores deployment from self', async () => { const payload = { - ...deploymentProtectionRule, + ...testFixtures.deployment_protection_rule, deployment: { - ...deploymentProtectionRule.deployment, creator: { login: 'test-bot', }, }, }; - // Mock installation token and GraphQL API call for whoAmI const mock = nock('https://api.github.com') - .post('/app/installations/57364329/access_tokens') + .post('/app/installations/12345678/access_tokens') + .reply(200, { token: 'test', permissions: { issues: 'write' } }) + .post('/graphql') + .reply(200, { + data: { + viewer: { + login: 'test-bot', + databaseId: 123, + }, + }, + }); + + await probot.receive({ + name: 'deployment_protection_rule', + payload, + }); + + expect(mock.pendingMocks()).toStrictEqual([]); + }); + + test('ignores deployment from unauthorized user', async () => { + const payload = { + ...testFixtures.deployment_protection_rule, + deployment: { + creator: { + login: 'unauthorized-user', + }, + }, + }; + + const mock = nock('https://api.github.com') + .post('/app/installations/12345678/access_tokens') .reply(200, { token: 'test', permissions: { issues: 'write' } }) .post('/graphql') .reply(200, { @@ -112,17 +219,11 @@ describe('GitHub Deployment App', () => { describe('issue_comment.created', () => { test('processes valid deploy comment', async () => { - // Mock all required API calls const mock = nock('https://api.github.com') - // Mock installation token - .post('/app/installations/57364329/access_tokens') + .post('/app/installations/12345678/access_tokens') .reply(200, { token: 'test', permissions: { issues: 'write' } }) - // Add eyes reaction - .post( - '/repos/balena-io-experimental/deployable/issues/comments/2486741061/reactions', - ) + .post('/repos/test-org/test-repo/issues/comments/456/reactions') .reply(200) - // Get app identity .post('/graphql') .reply(200, { data: { @@ -132,24 +233,19 @@ describe('GitHub Deployment App', () => { }, }, }) - // Check user permissions - .get( - '/repos/balena-io-experimental/deployable/collaborators/klutchell/permission', - ) + .get('/repos/test-org/test-repo/collaborators/test-user/permission') .reply(200, { permission: 'admin' }) - // Get PR details - .get('/repos/balena-io-experimental/deployable/pulls/2') + .get('/repos/test-org/test-repo/pulls/123') .reply(200, { - head: { sha: 'abec9b0' }, + head: { sha: 'test-sha' }, }) - // List workflow runs - .get('/repos/balena-io-experimental/deployable/actions/runs') + .get('/repos/test-org/test-repo/actions/runs') .query(true) .reply(200, { workflow_runs: [] }); await probot.receive({ name: 'issue_comment', - payload: issueComment, + payload: testFixtures.issue_comment, }); expect(mock.pendingMocks()).toStrictEqual([]); @@ -157,9 +253,9 @@ describe('GitHub Deployment App', () => { test('ignores non-deploy comments', async () => { const payload = { - ...issueComment, + ...testFixtures.issue_comment, comment: { - ...issueComment.comment, + ...testFixtures.issue_comment.comment, body: 'Just a regular comment', }, }; @@ -169,17 +265,16 @@ describe('GitHub Deployment App', () => { payload, }); - // No API calls should be made expect(nock.pendingMocks()).toStrictEqual([]); }); test('ignores bot comments', async () => { const payload = { - ...issueComment, + ...testFixtures.issue_comment, comment: { - ...issueComment.comment, + ...testFixtures.issue_comment.comment, user: { - ...issueComment.comment.user, + ...testFixtures.issue_comment.comment.user, type: 'Bot', }, }, @@ -190,8 +285,122 @@ describe('GitHub Deployment App', () => { payload, }); - // No API calls should be made expect(nock.pendingMocks()).toStrictEqual([]); }); + + test('ignores edited comments', async () => { + const payload = { + ...testFixtures.issue_comment, + comment: { + ...testFixtures.issue_comment.comment, + created_at: '2024-01-01T00:00:00Z', + updated_at: '2024-01-01T00:01:00Z', + }, + }; + + await probot.receive({ + name: 'issue_comment', + payload, + }); + + expect(nock.pendingMocks()).toStrictEqual([]); + }); + + test('ignores comments on non-pull-requests', async () => { + const payload = { + ...testFixtures.issue_comment, + issue: { + ...testFixtures.issue_comment.issue, + pull_request: null, + }, + }; + + await probot.receive({ + name: 'issue_comment', + payload, + }); + + expect(nock.pendingMocks()).toStrictEqual([]); + }); + + test('throws error on failure to get app user', async () => { + const mock = nock('https://api.github.com') + .post('/app/installations/12345678/access_tokens') + .reply(200, { token: 'test', permissions: { issues: 'write' } }) + .post('/repos/test-org/test-repo/issues/comments/456/reactions') + .reply(200) + .post('/graphql') + .reply(404, { message: 'Not Found' }); + + await expect( + probot.receive({ + name: 'issue_comment', + payload: testFixtures.issue_comment, + }), + ).rejects.toThrow('Failed to get app user'); + + expect(mock.pendingMocks()).toStrictEqual([]); + }); + + test('ignores comments from self', async () => { + const payload = { + ...testFixtures.issue_comment, + comment: { + ...testFixtures.issue_comment.comment, + user: { + ...testFixtures.issue_comment.comment.user, + login: 'test-bot', + }, + }, + }; + + const mock = nock('https://api.github.com') + .post('/app/installations/12345678/access_tokens') + .reply(200, { token: 'test', permissions: { issues: 'write' } }) + .post('/repos/test-org/test-repo/issues/comments/456/reactions') + .reply(200) + .post('/graphql') + .reply(200, { + data: { + viewer: { + login: 'test-bot', + databaseId: 123, + }, + }, + }); + + await probot.receive({ + name: 'issue_comment', + payload, + }); + + expect(mock.pendingMocks()).toStrictEqual([]); + }); + + test('ignores comments from users without write access', async () => { + const mock = nock('https://api.github.com') + .post('/app/installations/12345678/access_tokens') + .reply(200, { token: 'test', permissions: { issues: 'write' } }) + .post('/repos/test-org/test-repo/issues/comments/456/reactions') + .reply(200) + .post('/graphql') + .reply(200, { + data: { + viewer: { + login: 'test-bot', + databaseId: 123, + }, + }, + }) + .get('/repos/test-org/test-repo/collaborators/test-user/permission') + .reply(200, { permission: 'read' }); + + await probot.receive({ + name: 'issue_comment', + payload: testFixtures.issue_comment, + }); + + expect(mock.pendingMocks()).toStrictEqual([]); + }); }); }); From 5293c9502a505f69f8cad4cab787332501b73322 Mon Sep 17 00:00:00 2001 From: Kyle Harding Date: Sat, 23 Nov 2024 14:24:47 -0500 Subject: [PATCH 10/15] Process BYPASS_USERS env var by id Signed-off-by: Kyle Harding --- src/index.ts | 6 ++++-- test/index.test.ts | 8 ++++++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/index.ts b/src/index.ts index 270fc72..71fa287 100644 --- a/src/index.ts +++ b/src/index.ts @@ -35,12 +35,14 @@ export default (app: Probot) => { throw new Error('Failed to get app user: %s', error); } - if (deployment.creator.login === appUser.login) { + if (deployment.creator.id === appUser.id) { context.log.info('Ignoring self deployment'); return; } - if (!['balena-renovate[bot]'].includes(deployment.creator.login)) { + const bypassActors = process.env.BYPASS_ACTORS?.split(',') ?? []; + + if (!bypassActors.includes(deployment.creator.id.toString())) { context.log.info( 'User %s is not on the auto-approve list', deployment.creator.login, diff --git a/test/index.test.ts b/test/index.test.ts index dbe6f37..7765785 100644 --- a/test/index.test.ts +++ b/test/index.test.ts @@ -20,7 +20,8 @@ const testFixtures = { 'https://api.github.com/repos/test-org/test-repo/actions/runs/1234/deployment_protection_rule', deployment: { creator: { - login: 'balena-renovate[bot]', + login: 'bypass-actor', + id: 5, }, }, installation: { id: 12345678 }, @@ -63,8 +64,9 @@ describe('GitHub Deployment App', () => { beforeEach(() => { nock.disableNetConnect(); + process.env.BYPASS_ACTORS = '5'; probot = new Probot({ - appId: 123, + appId: 456, privateKey, // Disable request throttling and retries for testing Octokit: ProbotOctokit.defaults({ @@ -160,6 +162,7 @@ describe('GitHub Deployment App', () => { deployment: { creator: { login: 'test-bot', + id: 123, }, }, }; @@ -191,6 +194,7 @@ describe('GitHub Deployment App', () => { deployment: { creator: { login: 'unauthorized-user', + id: 789, }, }, }; From 83712d26e47ba4171cbe4ae53b7a18005eaa9ea4 Mon Sep 17 00:00:00 2001 From: Kyle Harding Date: Sun, 24 Nov 2024 09:45:32 -0500 Subject: [PATCH 11/15] Configure eslint and prettier to use balena-lint rules Signed-off-by: Kyle Harding --- .eslintrc.json | 3 +++ .lintstagedrc | 2 +- .prettierrc.js | 3 +++ 3 files changed, 7 insertions(+), 1 deletion(-) create mode 100644 .eslintrc.json create mode 100644 .prettierrc.js diff --git a/.eslintrc.json b/.eslintrc.json new file mode 100644 index 0000000..a94120d --- /dev/null +++ b/.eslintrc.json @@ -0,0 +1,3 @@ +{ + "extends": ["./node_modules/@balena/lint/config/.eslintrc.js"] +} diff --git a/.lintstagedrc b/.lintstagedrc index 3b463ff..ef089e6 100644 --- a/.lintstagedrc +++ b/.lintstagedrc @@ -2,7 +2,7 @@ "*.ts": [ "balena-lint --fix" ], - "*.js": [ + "*/**/*.js": [ "balena-lint --fix" ] } diff --git a/.prettierrc.js b/.prettierrc.js new file mode 100644 index 0000000..77076ca --- /dev/null +++ b/.prettierrc.js @@ -0,0 +1,3 @@ +const fs = require('fs'); + +module.exports = JSON.parse(fs.readFileSync('./node_modules/@balena/lint/config/.prettierrc', 'utf8')); From cf13a27d081e7ed7cd1f7f0b87defe515f4f4188 Mon Sep 17 00:00:00 2001 From: Kyle Harding Date: Sun, 24 Nov 2024 09:48:25 -0500 Subject: [PATCH 12/15] Filter deployments with unique environments Signed-off-by: Kyle Harding --- src/index.ts | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/src/index.ts b/src/index.ts index 71fa287..695d1a9 100644 --- a/src/index.ts +++ b/src/index.ts @@ -157,25 +157,21 @@ export default (app: Probot) => { continue; } - for (const deployment of deployments) { - if (!deployment.current_user_can_approve) { - context.log.info( - 'User %s cannot approve deployment %s', - appUser.login, - deployment.id, - ); - continue; - } + // map deployments to their environment names + const environments = deployments + .filter((deployment) => deployment.current_user_can_approve) + .map((deployment) => deployment.environment.name); + for (const environment of environments) { context.log.info( 'Reviewing deployment with run %s and environment %s', run.id, - deployment.environment.name, + environment, ); await GitHubClient.reviewWorkflowRun( context, run.id, - deployment.environment.name, + environment, 'approved', `Approved by ${comment.user.login} via ${appUser.login}`, ); From 281a1886acdfa65bb5bca75cd6620317c3e1f1aa Mon Sep 17 00:00:00 2001 From: Kyle Harding Date: Sun, 24 Nov 2024 19:13:43 -0500 Subject: [PATCH 13/15] Approve via pull request review comments Signed-off-by: Kyle Harding --- .prettierrc.cjs | 5 + .prettierrc.js | 3 - app.yml | 50 +- src/client.ts | 112 ++-- src/index.ts | 132 ++-- .../pull_request_review.submitted.json | 571 +++++++++++++++++ .../pull_request_review_comment.created.json | 600 ++++++++++++++++++ test/index.test.ts | 283 +++------ 8 files changed, 1396 insertions(+), 360 deletions(-) create mode 100644 .prettierrc.cjs delete mode 100644 .prettierrc.js create mode 100644 test/fixtures/pull_request_review.submitted.json create mode 100644 test/fixtures/pull_request_review_comment.created.json diff --git a/.prettierrc.cjs b/.prettierrc.cjs new file mode 100644 index 0000000..1644007 --- /dev/null +++ b/.prettierrc.cjs @@ -0,0 +1,5 @@ +const fs = require("fs"); +const path = require("path"); +module.exports = JSON.parse( + fs.readFileSync(path.join(__dirname, "node_modules", "@balena", "lint", "config", ".prettierrc"), "utf8"), +); diff --git a/.prettierrc.js b/.prettierrc.js deleted file mode 100644 index 77076ca..0000000 --- a/.prettierrc.js +++ /dev/null @@ -1,3 +0,0 @@ -const fs = require('fs'); - -module.exports = JSON.parse(fs.readFileSync('./node_modules/@balena/lint/config/.prettierrc', 'utf8')); diff --git a/app.yml b/app.yml index e931fae..e9cdc14 100644 --- a/app.yml +++ b/app.yml @@ -23,30 +23,30 @@ default_events: - deployment_protection_rule # - fork # - gollum - - issue_comment + # - issue_comment # - issues -# - label -# - milestone -# - member -# - membership -# - org_block -# - organization -# - page_build -# - project -# - project_card -# - project_column -# - public -# - pull_request -# - pull_request_review -# - pull_request_review_comment -# - push -# - release -# - repository -# - repository_import -# - status -# - team -# - team_add -# - watch + # - label + # - milestone + # - member + # - membership + # - org_block + # - organization + # - page_build + # - project + # - project_card + # - project_column + # - public + # - pull_request + - pull_request_review + # - pull_request_review_comment + # - push + # - release + # - repository + # - repository_import + # - status + # - team + # - team_add + # - watch # The set of permissions needed by the GitHub App. The format of the object uses # the permission name for the key (for example, issues) and the access type for @@ -74,7 +74,7 @@ default_permissions: # Issues and related comments, assignees, labels, and milestones. # https://developer.github.com/v3/apps/permissions/#permission-on-issues - issues: write + # issues: write # Search repositories, list collaborators, and access repository metadata. # https://developer.github.com/v3/apps/permissions/#metadata-permissions @@ -106,7 +106,7 @@ default_permissions: # Organization members and teams. # https://developer.github.com/v3/apps/permissions/#permission-on-members - members: read + # members: read # View and manage users blocked by the organization. # https://developer.github.com/v3/apps/permissions/#permission-on-organization-user-blocking diff --git a/src/client.ts b/src/client.ts index fa7f406..8da3340 100644 --- a/src/client.ts +++ b/src/client.ts @@ -1,43 +1,60 @@ -export async function whoAmI(context: any): Promise { - const query = `query { viewer { databaseId login } }`; - const { viewer } = await context.octokit.graphql(query); - console.log(`Authenticated as: ${viewer.login}`); - return { login: viewer.login, id: viewer.databaseId }; -} +// export async function whoAmI(context: any): Promise { +// const query = `query { viewer { databaseId login } }`; +// const { viewer } = await context.octokit.graphql(query); +// console.log(`Authenticated as: ${viewer.login} (${viewer.databaseId})`); +// return { login: viewer.login, id: viewer.databaseId }; +// } -// https://octokit.github.io/rest.js/v21/#repos-get-collaborator-permission-level -// https://docs.github.com/en/rest/collaborators/collaborators#list-repository-collaborators -export async function hasRepoWriteAccess( - context: any, - username: string, -): Promise { - const request = context.repo({ - username, - }); +// // https://octokit.github.io/rest.js/v21/#repos-get-collaborator-permission-level +// // https://docs.github.com/en/rest/collaborators/collaborators#list-repository-collaborators +// export async function hasRepoWriteAccess( +// context: any, +// username: string, +// ): Promise { +// const request = context.repo({ +// username, +// }); - const { - data: { permission }, - } = await context.octokit.rest.repos.getCollaboratorPermissionLevel(request); +// const { +// data: { permission }, +// } = await context.octokit.rest.repos.getCollaboratorPermissionLevel(request); - context.log.info( - `Permission level for ${username}: ${JSON.stringify(permission, null, 2)}`, - ); +// context.log.info( +// `Permission level for ${username}: ${JSON.stringify(permission, null, 2)}`, +// ); - return ['admin', 'write'].includes(permission); -} +// return ['admin', 'write'].includes(permission); +// } -export async function addCommentReaction( - context: any, - commentId: number, - content: string, -): Promise { - const request = context.repo({ - comment_id: commentId, - content, - }); +// // https://octokit.github.io/rest.js/v21/#reactions-create-for-issue-comment +// // https://docs.github.com/en/rest/reactions/reactions#create-reaction-for-an-issue-comment +// export async function addCommentReaction( +// context: any, +// commentId: number, +// content: string, +// ): Promise { +// const request = context.repo({ +// comment_id: commentId, +// content, +// }); - await context.octokit.reactions.createForIssueComment(request); -} +// await context.octokit.reactions.createForIssueComment(request); +// } + +// // https://octokit.github.io/rest.js/v21/#reactions-create-for-pull-request-review-comment +// // https://docs.github.com/en/rest/reactions/reactions#create-reaction-for-a-pull-request-review-comment +// export async function addPullRequestReviewCommentReaction( +// context: any, +// commentId: number, +// content: string, +// ): Promise { +// const request = context.repo({ +// comment_id: commentId, +// content, +// }); + +// await context.octokit.reactions.createForPullRequestReviewComment(request); +// } // https://docs.github.com/en/rest/deployments/deployments#list-deployments // export async function listDeployments( @@ -72,35 +89,28 @@ export async function listPullRequestCommits( return commits; } -export async function getPullRequest( - context: any, - prNumber: number, -): Promise { - const request = context.repo({ - pull_number: prNumber, - }); - const { data: pullRequest } = await context.octokit.rest.pulls.get(request); - return pullRequest; -} +// export async function getPullRequest( +// context: any, +// prNumber: number, +// ): Promise { +// const request = context.repo({ +// pull_number: prNumber, +// }); +// const { data: pullRequest } = await context.octokit.rest.pulls.get(request); +// return pullRequest; +// } // https://octokit.github.io/rest.js/v21/#actions-list-workflow-runs-for-repo // https://docs.github.com/en/rest/actions/workflow-runs#list-workflow-runs-for-a-repository -// https://docs.github.com/en/search-github/getting-started-with-searching-on-github/understanding-the-search-syntax#query-for-dates export async function listWorkflowRuns( context: any, headSha: string, - created: string, ): Promise { // what is the status "requested" used for? const request = context.repo({ status: 'waiting', - created, head_sha: headSha, }); - - context.log.info( - `Searching for workflow runs with ${JSON.stringify(request, null, 2)}`, - ); const { data: { workflow_runs: runs }, } = await context.octokit.rest.actions.listWorkflowRunsForRepo(request); diff --git a/src/index.ts b/src/index.ts index 695d1a9..deef589 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,7 +1,7 @@ import type { Context, Probot } from 'probot'; import type { - IssueCommentCreatedEvent, DeploymentProtectionRuleRequestedEvent, + PullRequestReviewSubmittedEvent, } from '@octokit/webhooks-types'; import * as GitHubClient from './client.js'; @@ -19,26 +19,17 @@ export default (app: Probot) => { return; } - console.log('Received event: deployment_protection_rule.requested'); - // console.log(JSON.stringify(context.payload, null, 2)); - // console.log(JSON.stringify(deployment, null, 2)); + app.log.info('Received event: deployment_protection_rule.requested'); + // app.log.info(JSON.stringify(context.payload, null, 2)); if (!['pull_request', 'pull_request_target'].includes(event)) { context.log.info('Ignoring non-pull request event'); return; } - let appUser; - try { - appUser = await GitHubClient.whoAmI(context); - } catch (error) { - throw new Error('Failed to get app user: %s', error); - } - - if (deployment.creator.id === appUser.id) { - context.log.info('Ignoring self deployment'); - return; - } + const client = await app.auth(); // Gets an authenticated Octokit client + const { data: appDetails } = await client.apps.getAuthenticated(); // Retrieves details about the authenticated app + // app.log.info(JSON.stringify(appDetails, null, 2)); // Logs details about the app const bypassActors = process.env.BYPASS_ACTORS?.split(',') ?? []; @@ -50,98 +41,42 @@ export default (app: Probot) => { return; } - // const hasRepoWriteAccess = await GitHubClient.hasRepoWriteAccess( - // context, - // deployment.creator.login - // ); - - // if (!hasRepoWriteAccess) { - // context.log.info( - // "User %s does not have write access", - // deployment.creator.login - // ); - // return; - // } - context.log.info('Approving deployment %s', deployment.id); return context.octokit.request(`POST ${callbackUrl}`, { environment_name: environment, state: 'approved', - comment: `Auto-approved by ${appUser.login} on behalf of ${deployment.creator.login}`, + comment: `Approved by ${appDetails.slug} on behalf of ${deployment.creator.login}`, }); }); - app.on('issue_comment.created', async (context: Context) => { - const { issue, comment } = context.payload as IssueCommentCreatedEvent; - - console.log('Received event: issue_comment.created'); - // console.log(JSON.stringify(context.payload, null, 2)); + app.on('pull_request_review.submitted', async (context: Context) => { + const { + review, + pull_request: { + head: { sha }, + }, + } = context.payload as PullRequestReviewSubmittedEvent; - if (issue.pull_request == null) { - context.log.info('Ignoring non-pull request comment'); - return; - } + app.log.info('Received event: pull_request_review.submitted'); + // app.log.info(JSON.stringify(context.payload, null, 2)); - if (comment.user.type === 'Bot') { - context.log.info('Ignoring bot comment'); + if (review.user.type === 'Bot') { + context.log.info('Ignoring bot review'); return; } - if (!comment.body.startsWith('/deploy')) { + if (!review.body?.startsWith('/deploy')) { context.log.info('Ignoring non-deploy comment'); return; } - if (comment.created_at !== comment.updated_at) { - context.log.info('Ignoring edited comment'); - return; - } - - // post a reaction to the comment with :eyes: - await GitHubClient.addCommentReaction(context, comment.id, 'eyes'); + const client = await app.auth(); // Gets an authenticated Octokit client + const { data: appDetails } = await client.apps.getAuthenticated(); // Retrieves details about the authenticated app + // app.log.info(JSON.stringify(appDetails, null, 2)); // Logs details about the app - let appUser; - try { - appUser = await GitHubClient.whoAmI(context); - } catch (error) { - throw new Error('Failed to get app user: %s', error); - } - - if (appUser.login === comment.user.login) { - context.log.info('Ignoring self comment'); - return; - } + // let approved = false; - const hasRepoWriteAccess = await GitHubClient.hasRepoWriteAccess( - context, - comment.user.login, - ); - - if (!hasRepoWriteAccess) { - context.log.info('User does not have write access'); - return; - } - - const { - head: { sha }, - } = await GitHubClient.getPullRequest(context, issue.number); - - // Get the ISO date 2-min before the comment.created_at - const created = new Date(comment.created_at); - created.setMinutes(created.getMinutes() - 2); - - // filter workflow runs with the given hash and a creation date 2 minutes or more before the comment created date - // https://docs.github.com/en/search-github/getting-started-with-searching-on-github/understanding-the-search-syntax#query-for-dates - const runs = await GitHubClient.listWorkflowRuns( - context, - sha, - `<${created.toISOString()}`, - ); - - if (runs.length === 0) { - context.log.info('No workflow runs found for sha %s', sha); - return; - } + const runs = await GitHubClient.listWorkflowRuns(context, sha); for (const run of runs) { const deployments = await GitHubClient.listPendingDeployments( @@ -173,10 +108,27 @@ export default (app: Probot) => { run.id, environment, 'approved', - `Approved by ${comment.user.login} via ${appUser.login}`, + `Approved by ${appDetails.slug} via review comment: ${review.html_url}`, ); + // approved = true; } } + + // if (approved) { + // // post a reaction to the comment with :rocket: + // await GitHubClient.addPullRequestReviewCommentReaction( + // context, + // review.id, + // 'rocket', + // ); + // } else { + // // post a reaction to the comment with :confused: + // await GitHubClient.addPullRequestReviewCommentReaction( + // context, + // review.id, + // 'confused', + // ); + // } }); // For more information on building apps: // https://probot.github.io/docs/ diff --git a/test/fixtures/pull_request_review.submitted.json b/test/fixtures/pull_request_review.submitted.json new file mode 100644 index 0000000..bdb619e --- /dev/null +++ b/test/fixtures/pull_request_review.submitted.json @@ -0,0 +1,571 @@ +{ + "action": "submitted", + "review": { + "id": 2458597072, + "node_id": "PRR_kwDONCUcDs6SizbQ", + "user": { + "login": "klutchell", + "id": 20458272, + "node_id": "MDQ6VXNlcjIwNDU4Mjcy", + "avatar_url": "https://avatars.githubusercontent.com/u/20458272?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/klutchell", + "html_url": "https://github.com/klutchell", + "followers_url": "https://api.github.com/users/klutchell/followers", + "following_url": "https://api.github.com/users/klutchell/following{/other_user}", + "gists_url": "https://api.github.com/users/klutchell/gists{/gist_id}", + "starred_url": "https://api.github.com/users/klutchell/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/klutchell/subscriptions", + "organizations_url": "https://api.github.com/users/klutchell/orgs", + "repos_url": "https://api.github.com/users/klutchell/repos", + "events_url": "https://api.github.com/users/klutchell/events{/privacy}", + "received_events_url": "https://api.github.com/users/klutchell/received_events", + "type": "User", + "user_view_type": "public", + "site_admin": false + }, + "body": "/deploy please", + "commit_id": "91707f292be6028f598270d2ed6fedeba18670be", + "submitted_at": "2024-11-25T14:27:54Z", + "state": "commented", + "html_url": "https://github.com/balena-io-experimental/deployable/pull/2#pullrequestreview-2458597072", + "pull_request_url": "https://api.github.com/repos/balena-io-experimental/deployable/pulls/2", + "author_association": "COLLABORATOR", + "_links": { + "html": { + "href": "https://github.com/balena-io-experimental/deployable/pull/2#pullrequestreview-2458597072" + }, + "pull_request": { + "href": "https://api.github.com/repos/balena-io-experimental/deployable/pulls/2" + } + } + }, + "pull_request": { + "url": "https://api.github.com/repos/balena-io-experimental/deployable/pulls/2", + "id": 2188445505, + "node_id": "PR_kwDONCUcDs6CcQdB", + "html_url": "https://github.com/balena-io-experimental/deployable/pull/2", + "diff_url": "https://github.com/balena-io-experimental/deployable/pull/2.diff", + "patch_url": "https://github.com/balena-io-experimental/deployable/pull/2.patch", + "issue_url": "https://api.github.com/repos/balena-io-experimental/deployable/issues/2", + "number": 2, + "state": "open", + "locked": false, + "title": "Initial commit of partial app logic", + "user": { + "login": "klutchell", + "id": 20458272, + "node_id": "MDQ6VXNlcjIwNDU4Mjcy", + "avatar_url": "https://avatars.githubusercontent.com/u/20458272?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/klutchell", + "html_url": "https://github.com/klutchell", + "followers_url": "https://api.github.com/users/klutchell/followers", + "following_url": "https://api.github.com/users/klutchell/following{/other_user}", + "gists_url": "https://api.github.com/users/klutchell/gists{/gist_id}", + "starred_url": "https://api.github.com/users/klutchell/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/klutchell/subscriptions", + "organizations_url": "https://api.github.com/users/klutchell/orgs", + "repos_url": "https://api.github.com/users/klutchell/repos", + "events_url": "https://api.github.com/users/klutchell/events{/privacy}", + "received_events_url": "https://api.github.com/users/klutchell/received_events", + "type": "User", + "user_view_type": "public", + "site_admin": false + }, + "body": null, + "created_at": "2024-11-19T20:57:39Z", + "updated_at": "2024-11-25T14:27:54Z", + "closed_at": null, + "merged_at": null, + "merge_commit_sha": "4fcecaf28fc9f124c541486b8c59cb33d695754a", + "assignee": null, + "assignees": [], + "requested_reviewers": [], + "requested_teams": [], + "labels": [], + "milestone": null, + "draft": false, + "commits_url": "https://api.github.com/repos/balena-io-experimental/deployable/pulls/2/commits", + "review_comments_url": "https://api.github.com/repos/balena-io-experimental/deployable/pulls/2/comments", + "review_comment_url": "https://api.github.com/repos/balena-io-experimental/deployable/pulls/comments{/number}", + "comments_url": "https://api.github.com/repos/balena-io-experimental/deployable/issues/2/comments", + "statuses_url": "https://api.github.com/repos/balena-io-experimental/deployable/statuses/91707f292be6028f598270d2ed6fedeba18670be", + "head": { + "label": "balena-io-experimental:kyle/develop", + "ref": "kyle/develop", + "sha": "91707f292be6028f598270d2ed6fedeba18670be", + "user": { + "login": "balena-io-experimental", + "id": 18610741, + "node_id": "MDEyOk9yZ2FuaXphdGlvbjE4NjEwNzQx", + "avatar_url": "https://avatars.githubusercontent.com/u/18610741?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/balena-io-experimental", + "html_url": "https://github.com/balena-io-experimental", + "followers_url": "https://api.github.com/users/balena-io-experimental/followers", + "following_url": "https://api.github.com/users/balena-io-experimental/following{/other_user}", + "gists_url": "https://api.github.com/users/balena-io-experimental/gists{/gist_id}", + "starred_url": "https://api.github.com/users/balena-io-experimental/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/balena-io-experimental/subscriptions", + "organizations_url": "https://api.github.com/users/balena-io-experimental/orgs", + "repos_url": "https://api.github.com/users/balena-io-experimental/repos", + "events_url": "https://api.github.com/users/balena-io-experimental/events{/privacy}", + "received_events_url": "https://api.github.com/users/balena-io-experimental/received_events", + "type": "Organization", + "user_view_type": "public", + "site_admin": false + }, + "repo": { + "id": 874847246, + "node_id": "R_kgDONCUcDg", + "name": "deployable", + "full_name": "balena-io-experimental/deployable", + "private": true, + "owner": { + "login": "balena-io-experimental", + "id": 18610741, + "node_id": "MDEyOk9yZ2FuaXphdGlvbjE4NjEwNzQx", + "avatar_url": "https://avatars.githubusercontent.com/u/18610741?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/balena-io-experimental", + "html_url": "https://github.com/balena-io-experimental", + "followers_url": "https://api.github.com/users/balena-io-experimental/followers", + "following_url": "https://api.github.com/users/balena-io-experimental/following{/other_user}", + "gists_url": "https://api.github.com/users/balena-io-experimental/gists{/gist_id}", + "starred_url": "https://api.github.com/users/balena-io-experimental/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/balena-io-experimental/subscriptions", + "organizations_url": "https://api.github.com/users/balena-io-experimental/orgs", + "repos_url": "https://api.github.com/users/balena-io-experimental/repos", + "events_url": "https://api.github.com/users/balena-io-experimental/events{/privacy}", + "received_events_url": "https://api.github.com/users/balena-io-experimental/received_events", + "type": "Organization", + "user_view_type": "public", + "site_admin": false + }, + "html_url": "https://github.com/balena-io-experimental/deployable", + "description": "Approve deployments with comment reactions", + "fork": false, + "url": "https://api.github.com/repos/balena-io-experimental/deployable", + "forks_url": "https://api.github.com/repos/balena-io-experimental/deployable/forks", + "keys_url": "https://api.github.com/repos/balena-io-experimental/deployable/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/balena-io-experimental/deployable/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/balena-io-experimental/deployable/teams", + "hooks_url": "https://api.github.com/repos/balena-io-experimental/deployable/hooks", + "issue_events_url": "https://api.github.com/repos/balena-io-experimental/deployable/issues/events{/number}", + "events_url": "https://api.github.com/repos/balena-io-experimental/deployable/events", + "assignees_url": "https://api.github.com/repos/balena-io-experimental/deployable/assignees{/user}", + "branches_url": "https://api.github.com/repos/balena-io-experimental/deployable/branches{/branch}", + "tags_url": "https://api.github.com/repos/balena-io-experimental/deployable/tags", + "blobs_url": "https://api.github.com/repos/balena-io-experimental/deployable/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/balena-io-experimental/deployable/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/balena-io-experimental/deployable/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/balena-io-experimental/deployable/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/balena-io-experimental/deployable/statuses/{sha}", + "languages_url": "https://api.github.com/repos/balena-io-experimental/deployable/languages", + "stargazers_url": "https://api.github.com/repos/balena-io-experimental/deployable/stargazers", + "contributors_url": "https://api.github.com/repos/balena-io-experimental/deployable/contributors", + "subscribers_url": "https://api.github.com/repos/balena-io-experimental/deployable/subscribers", + "subscription_url": "https://api.github.com/repos/balena-io-experimental/deployable/subscription", + "commits_url": "https://api.github.com/repos/balena-io-experimental/deployable/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/balena-io-experimental/deployable/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/balena-io-experimental/deployable/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/balena-io-experimental/deployable/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/balena-io-experimental/deployable/contents/{+path}", + "compare_url": "https://api.github.com/repos/balena-io-experimental/deployable/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/balena-io-experimental/deployable/merges", + "archive_url": "https://api.github.com/repos/balena-io-experimental/deployable/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/balena-io-experimental/deployable/downloads", + "issues_url": "https://api.github.com/repos/balena-io-experimental/deployable/issues{/number}", + "pulls_url": "https://api.github.com/repos/balena-io-experimental/deployable/pulls{/number}", + "milestones_url": "https://api.github.com/repos/balena-io-experimental/deployable/milestones{/number}", + "notifications_url": "https://api.github.com/repos/balena-io-experimental/deployable/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/balena-io-experimental/deployable/labels{/name}", + "releases_url": "https://api.github.com/repos/balena-io-experimental/deployable/releases{/id}", + "deployments_url": "https://api.github.com/repos/balena-io-experimental/deployable/deployments", + "created_at": "2024-10-18T15:11:02Z", + "updated_at": "2024-10-18T15:12:13Z", + "pushed_at": "2024-11-25T00:16:18Z", + "git_url": "git://github.com/balena-io-experimental/deployable.git", + "ssh_url": "git@github.com:balena-io-experimental/deployable.git", + "clone_url": "https://github.com/balena-io-experimental/deployable.git", + "svn_url": "https://github.com/balena-io-experimental/deployable", + "homepage": null, + "size": 171, + "stargazers_count": 0, + "watchers_count": 0, + "language": "TypeScript", + "has_issues": true, + "has_projects": true, + "has_downloads": true, + "has_wiki": true, + "has_pages": false, + "has_discussions": false, + "forks_count": 0, + "mirror_url": null, + "archived": false, + "disabled": false, + "open_issues_count": 2, + "license": { + "key": "isc", + "name": "ISC License", + "spdx_id": "ISC", + "url": "https://api.github.com/licenses/isc", + "node_id": "MDc6TGljZW5zZTEw" + }, + "allow_forking": false, + "is_template": false, + "web_commit_signoff_required": false, + "topics": [], + "visibility": "internal", + "forks": 0, + "open_issues": 2, + "watchers": 0, + "default_branch": "main", + "allow_squash_merge": false, + "allow_merge_commit": true, + "allow_rebase_merge": false, + "allow_auto_merge": true, + "delete_branch_on_merge": true, + "allow_update_branch": false, + "use_squash_pr_title_as_default": false, + "squash_merge_commit_message": "COMMIT_MESSAGES", + "squash_merge_commit_title": "COMMIT_OR_PR_TITLE", + "merge_commit_message": "PR_TITLE", + "merge_commit_title": "MERGE_MESSAGE" + } + }, + "base": { + "label": "balena-io-experimental:main", + "ref": "main", + "sha": "89354cd1344b8de289e5965328831992448eac7a", + "user": { + "login": "balena-io-experimental", + "id": 18610741, + "node_id": "MDEyOk9yZ2FuaXphdGlvbjE4NjEwNzQx", + "avatar_url": "https://avatars.githubusercontent.com/u/18610741?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/balena-io-experimental", + "html_url": "https://github.com/balena-io-experimental", + "followers_url": "https://api.github.com/users/balena-io-experimental/followers", + "following_url": "https://api.github.com/users/balena-io-experimental/following{/other_user}", + "gists_url": "https://api.github.com/users/balena-io-experimental/gists{/gist_id}", + "starred_url": "https://api.github.com/users/balena-io-experimental/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/balena-io-experimental/subscriptions", + "organizations_url": "https://api.github.com/users/balena-io-experimental/orgs", + "repos_url": "https://api.github.com/users/balena-io-experimental/repos", + "events_url": "https://api.github.com/users/balena-io-experimental/events{/privacy}", + "received_events_url": "https://api.github.com/users/balena-io-experimental/received_events", + "type": "Organization", + "user_view_type": "public", + "site_admin": false + }, + "repo": { + "id": 874847246, + "node_id": "R_kgDONCUcDg", + "name": "deployable", + "full_name": "balena-io-experimental/deployable", + "private": true, + "owner": { + "login": "balena-io-experimental", + "id": 18610741, + "node_id": "MDEyOk9yZ2FuaXphdGlvbjE4NjEwNzQx", + "avatar_url": "https://avatars.githubusercontent.com/u/18610741?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/balena-io-experimental", + "html_url": "https://github.com/balena-io-experimental", + "followers_url": "https://api.github.com/users/balena-io-experimental/followers", + "following_url": "https://api.github.com/users/balena-io-experimental/following{/other_user}", + "gists_url": "https://api.github.com/users/balena-io-experimental/gists{/gist_id}", + "starred_url": "https://api.github.com/users/balena-io-experimental/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/balena-io-experimental/subscriptions", + "organizations_url": "https://api.github.com/users/balena-io-experimental/orgs", + "repos_url": "https://api.github.com/users/balena-io-experimental/repos", + "events_url": "https://api.github.com/users/balena-io-experimental/events{/privacy}", + "received_events_url": "https://api.github.com/users/balena-io-experimental/received_events", + "type": "Organization", + "user_view_type": "public", + "site_admin": false + }, + "html_url": "https://github.com/balena-io-experimental/deployable", + "description": "Approve deployments with comment reactions", + "fork": false, + "url": "https://api.github.com/repos/balena-io-experimental/deployable", + "forks_url": "https://api.github.com/repos/balena-io-experimental/deployable/forks", + "keys_url": "https://api.github.com/repos/balena-io-experimental/deployable/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/balena-io-experimental/deployable/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/balena-io-experimental/deployable/teams", + "hooks_url": "https://api.github.com/repos/balena-io-experimental/deployable/hooks", + "issue_events_url": "https://api.github.com/repos/balena-io-experimental/deployable/issues/events{/number}", + "events_url": "https://api.github.com/repos/balena-io-experimental/deployable/events", + "assignees_url": "https://api.github.com/repos/balena-io-experimental/deployable/assignees{/user}", + "branches_url": "https://api.github.com/repos/balena-io-experimental/deployable/branches{/branch}", + "tags_url": "https://api.github.com/repos/balena-io-experimental/deployable/tags", + "blobs_url": "https://api.github.com/repos/balena-io-experimental/deployable/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/balena-io-experimental/deployable/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/balena-io-experimental/deployable/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/balena-io-experimental/deployable/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/balena-io-experimental/deployable/statuses/{sha}", + "languages_url": "https://api.github.com/repos/balena-io-experimental/deployable/languages", + "stargazers_url": "https://api.github.com/repos/balena-io-experimental/deployable/stargazers", + "contributors_url": "https://api.github.com/repos/balena-io-experimental/deployable/contributors", + "subscribers_url": "https://api.github.com/repos/balena-io-experimental/deployable/subscribers", + "subscription_url": "https://api.github.com/repos/balena-io-experimental/deployable/subscription", + "commits_url": "https://api.github.com/repos/balena-io-experimental/deployable/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/balena-io-experimental/deployable/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/balena-io-experimental/deployable/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/balena-io-experimental/deployable/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/balena-io-experimental/deployable/contents/{+path}", + "compare_url": "https://api.github.com/repos/balena-io-experimental/deployable/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/balena-io-experimental/deployable/merges", + "archive_url": "https://api.github.com/repos/balena-io-experimental/deployable/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/balena-io-experimental/deployable/downloads", + "issues_url": "https://api.github.com/repos/balena-io-experimental/deployable/issues{/number}", + "pulls_url": "https://api.github.com/repos/balena-io-experimental/deployable/pulls{/number}", + "milestones_url": "https://api.github.com/repos/balena-io-experimental/deployable/milestones{/number}", + "notifications_url": "https://api.github.com/repos/balena-io-experimental/deployable/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/balena-io-experimental/deployable/labels{/name}", + "releases_url": "https://api.github.com/repos/balena-io-experimental/deployable/releases{/id}", + "deployments_url": "https://api.github.com/repos/balena-io-experimental/deployable/deployments", + "created_at": "2024-10-18T15:11:02Z", + "updated_at": "2024-10-18T15:12:13Z", + "pushed_at": "2024-11-25T00:16:18Z", + "git_url": "git://github.com/balena-io-experimental/deployable.git", + "ssh_url": "git@github.com:balena-io-experimental/deployable.git", + "clone_url": "https://github.com/balena-io-experimental/deployable.git", + "svn_url": "https://github.com/balena-io-experimental/deployable", + "homepage": null, + "size": 171, + "stargazers_count": 0, + "watchers_count": 0, + "language": "TypeScript", + "has_issues": true, + "has_projects": true, + "has_downloads": true, + "has_wiki": true, + "has_pages": false, + "has_discussions": false, + "forks_count": 0, + "mirror_url": null, + "archived": false, + "disabled": false, + "open_issues_count": 2, + "license": { + "key": "isc", + "name": "ISC License", + "spdx_id": "ISC", + "url": "https://api.github.com/licenses/isc", + "node_id": "MDc6TGljZW5zZTEw" + }, + "allow_forking": false, + "is_template": false, + "web_commit_signoff_required": false, + "topics": [], + "visibility": "internal", + "forks": 0, + "open_issues": 2, + "watchers": 0, + "default_branch": "main", + "allow_squash_merge": false, + "allow_merge_commit": true, + "allow_rebase_merge": false, + "allow_auto_merge": true, + "delete_branch_on_merge": true, + "allow_update_branch": false, + "use_squash_pr_title_as_default": false, + "squash_merge_commit_message": "COMMIT_MESSAGES", + "squash_merge_commit_title": "COMMIT_OR_PR_TITLE", + "merge_commit_message": "PR_TITLE", + "merge_commit_title": "MERGE_MESSAGE" + } + }, + "_links": { + "self": { + "href": "https://api.github.com/repos/balena-io-experimental/deployable/pulls/2" + }, + "html": { + "href": "https://github.com/balena-io-experimental/deployable/pull/2" + }, + "issue": { + "href": "https://api.github.com/repos/balena-io-experimental/deployable/issues/2" + }, + "comments": { + "href": "https://api.github.com/repos/balena-io-experimental/deployable/issues/2/comments" + }, + "review_comments": { + "href": "https://api.github.com/repos/balena-io-experimental/deployable/pulls/2/comments" + }, + "review_comment": { + "href": "https://api.github.com/repos/balena-io-experimental/deployable/pulls/comments{/number}" + }, + "commits": { + "href": "https://api.github.com/repos/balena-io-experimental/deployable/pulls/2/commits" + }, + "statuses": { + "href": "https://api.github.com/repos/balena-io-experimental/deployable/statuses/91707f292be6028f598270d2ed6fedeba18670be" + } + }, + "author_association": "COLLABORATOR", + "auto_merge": null, + "active_lock_reason": null + }, + "repository": { + "id": 874847246, + "node_id": "R_kgDONCUcDg", + "name": "deployable", + "full_name": "balena-io-experimental/deployable", + "private": true, + "owner": { + "login": "balena-io-experimental", + "id": 18610741, + "node_id": "MDEyOk9yZ2FuaXphdGlvbjE4NjEwNzQx", + "avatar_url": "https://avatars.githubusercontent.com/u/18610741?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/balena-io-experimental", + "html_url": "https://github.com/balena-io-experimental", + "followers_url": "https://api.github.com/users/balena-io-experimental/followers", + "following_url": "https://api.github.com/users/balena-io-experimental/following{/other_user}", + "gists_url": "https://api.github.com/users/balena-io-experimental/gists{/gist_id}", + "starred_url": "https://api.github.com/users/balena-io-experimental/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/balena-io-experimental/subscriptions", + "organizations_url": "https://api.github.com/users/balena-io-experimental/orgs", + "repos_url": "https://api.github.com/users/balena-io-experimental/repos", + "events_url": "https://api.github.com/users/balena-io-experimental/events{/privacy}", + "received_events_url": "https://api.github.com/users/balena-io-experimental/received_events", + "type": "Organization", + "user_view_type": "public", + "site_admin": false + }, + "html_url": "https://github.com/balena-io-experimental/deployable", + "description": "Approve deployments with comment reactions", + "fork": false, + "url": "https://api.github.com/repos/balena-io-experimental/deployable", + "forks_url": "https://api.github.com/repos/balena-io-experimental/deployable/forks", + "keys_url": "https://api.github.com/repos/balena-io-experimental/deployable/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/balena-io-experimental/deployable/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/balena-io-experimental/deployable/teams", + "hooks_url": "https://api.github.com/repos/balena-io-experimental/deployable/hooks", + "issue_events_url": "https://api.github.com/repos/balena-io-experimental/deployable/issues/events{/number}", + "events_url": "https://api.github.com/repos/balena-io-experimental/deployable/events", + "assignees_url": "https://api.github.com/repos/balena-io-experimental/deployable/assignees{/user}", + "branches_url": "https://api.github.com/repos/balena-io-experimental/deployable/branches{/branch}", + "tags_url": "https://api.github.com/repos/balena-io-experimental/deployable/tags", + "blobs_url": "https://api.github.com/repos/balena-io-experimental/deployable/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/balena-io-experimental/deployable/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/balena-io-experimental/deployable/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/balena-io-experimental/deployable/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/balena-io-experimental/deployable/statuses/{sha}", + "languages_url": "https://api.github.com/repos/balena-io-experimental/deployable/languages", + "stargazers_url": "https://api.github.com/repos/balena-io-experimental/deployable/stargazers", + "contributors_url": "https://api.github.com/repos/balena-io-experimental/deployable/contributors", + "subscribers_url": "https://api.github.com/repos/balena-io-experimental/deployable/subscribers", + "subscription_url": "https://api.github.com/repos/balena-io-experimental/deployable/subscription", + "commits_url": "https://api.github.com/repos/balena-io-experimental/deployable/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/balena-io-experimental/deployable/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/balena-io-experimental/deployable/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/balena-io-experimental/deployable/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/balena-io-experimental/deployable/contents/{+path}", + "compare_url": "https://api.github.com/repos/balena-io-experimental/deployable/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/balena-io-experimental/deployable/merges", + "archive_url": "https://api.github.com/repos/balena-io-experimental/deployable/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/balena-io-experimental/deployable/downloads", + "issues_url": "https://api.github.com/repos/balena-io-experimental/deployable/issues{/number}", + "pulls_url": "https://api.github.com/repos/balena-io-experimental/deployable/pulls{/number}", + "milestones_url": "https://api.github.com/repos/balena-io-experimental/deployable/milestones{/number}", + "notifications_url": "https://api.github.com/repos/balena-io-experimental/deployable/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/balena-io-experimental/deployable/labels{/name}", + "releases_url": "https://api.github.com/repos/balena-io-experimental/deployable/releases{/id}", + "deployments_url": "https://api.github.com/repos/balena-io-experimental/deployable/deployments", + "created_at": "2024-10-18T15:11:02Z", + "updated_at": "2024-10-18T15:12:13Z", + "pushed_at": "2024-11-25T00:16:18Z", + "git_url": "git://github.com/balena-io-experimental/deployable.git", + "ssh_url": "git@github.com:balena-io-experimental/deployable.git", + "clone_url": "https://github.com/balena-io-experimental/deployable.git", + "svn_url": "https://github.com/balena-io-experimental/deployable", + "homepage": null, + "size": 171, + "stargazers_count": 0, + "watchers_count": 0, + "language": "TypeScript", + "has_issues": true, + "has_projects": true, + "has_downloads": true, + "has_wiki": true, + "has_pages": false, + "has_discussions": false, + "forks_count": 0, + "mirror_url": null, + "archived": false, + "disabled": false, + "open_issues_count": 2, + "license": { + "key": "isc", + "name": "ISC License", + "spdx_id": "ISC", + "url": "https://api.github.com/licenses/isc", + "node_id": "MDc6TGljZW5zZTEw" + }, + "allow_forking": false, + "is_template": false, + "web_commit_signoff_required": false, + "topics": [], + "visibility": "internal", + "forks": 0, + "open_issues": 2, + "watchers": 0, + "default_branch": "main", + "custom_properties": {} + }, + "organization": { + "login": "balena-io-experimental", + "id": 18610741, + "node_id": "MDEyOk9yZ2FuaXphdGlvbjE4NjEwNzQx", + "url": "https://api.github.com/orgs/balena-io-experimental", + "repos_url": "https://api.github.com/orgs/balena-io-experimental/repos", + "events_url": "https://api.github.com/orgs/balena-io-experimental/events", + "hooks_url": "https://api.github.com/orgs/balena-io-experimental/hooks", + "issues_url": "https://api.github.com/orgs/balena-io-experimental/issues", + "members_url": "https://api.github.com/orgs/balena-io-experimental/members{/member}", + "public_members_url": "https://api.github.com/orgs/balena-io-experimental/public_members{/member}", + "avatar_url": "https://avatars.githubusercontent.com/u/18610741?v=4", + "description": "A collection of play around and experimental projects for balena IoT devices" + }, + "enterprise": { + "id": 16136, + "slug": "balena", + "name": " Balena Ltd", + "node_id": "E_kgDNPwg", + "avatar_url": "https://avatars.githubusercontent.com/b/16136?v=4", + "description": "Balena brings the benefits of Linux containers to the IoT. Develop iteratively, deploy safely, and manage at scale.", + "website_url": "https://www.balena.io", + "html_url": "https://github.com/enterprises/balena", + "created_at": "2022-10-05T14:08:07Z", + "updated_at": "2024-10-04T08:57:35Z" + }, + "sender": { + "login": "klutchell", + "id": 20458272, + "node_id": "MDQ6VXNlcjIwNDU4Mjcy", + "avatar_url": "https://avatars.githubusercontent.com/u/20458272?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/klutchell", + "html_url": "https://github.com/klutchell", + "followers_url": "https://api.github.com/users/klutchell/followers", + "following_url": "https://api.github.com/users/klutchell/following{/other_user}", + "gists_url": "https://api.github.com/users/klutchell/gists{/gist_id}", + "starred_url": "https://api.github.com/users/klutchell/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/klutchell/subscriptions", + "organizations_url": "https://api.github.com/users/klutchell/orgs", + "repos_url": "https://api.github.com/users/klutchell/repos", + "events_url": "https://api.github.com/users/klutchell/events{/privacy}", + "received_events_url": "https://api.github.com/users/klutchell/received_events", + "type": "User", + "user_view_type": "public", + "site_admin": false + }, + "installation": { + "id": 57364329, + "node_id": "MDIzOkludGVncmF0aW9uSW5zdGFsbGF0aW9uNTczNjQzMjk=" + } +} diff --git a/test/fixtures/pull_request_review_comment.created.json b/test/fixtures/pull_request_review_comment.created.json new file mode 100644 index 0000000..28b324f --- /dev/null +++ b/test/fixtures/pull_request_review_comment.created.json @@ -0,0 +1,600 @@ +{ + "action": "created", + "comment": { + "url": "https://api.github.com/repos/balena-io-experimental/deployable/pulls/comments/1856689298", + "pull_request_review_id": 2458558740, + "id": 1856689298, + "node_id": "PRRC_kwDONCUcDs5uqtSS", + "diff_hunk": "@@ -0,0 +1,3 @@\n+const fs = require('fs');\n+\n+module.exports = JSON.parse(fs.readFileSync('./node_modules/@balena/lint/config/.prettierrc', 'utf8'));", + "path": ".prettierrc.js", + "commit_id": "91707f292be6028f598270d2ed6fedeba18670be", + "original_commit_id": "91707f292be6028f598270d2ed6fedeba18670be", + "user": { + "login": "klutchell", + "id": 20458272, + "node_id": "MDQ6VXNlcjIwNDU4Mjcy", + "avatar_url": "https://avatars.githubusercontent.com/u/20458272?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/klutchell", + "html_url": "https://github.com/klutchell", + "followers_url": "https://api.github.com/users/klutchell/followers", + "following_url": "https://api.github.com/users/klutchell/following{/other_user}", + "gists_url": "https://api.github.com/users/klutchell/gists{/gist_id}", + "starred_url": "https://api.github.com/users/klutchell/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/klutchell/subscriptions", + "organizations_url": "https://api.github.com/users/klutchell/orgs", + "repos_url": "https://api.github.com/users/klutchell/repos", + "events_url": "https://api.github.com/users/klutchell/events{/privacy}", + "received_events_url": "https://api.github.com/users/klutchell/received_events", + "type": "User", + "user_view_type": "public", + "site_admin": false + }, + "body": "This isn't working", + "created_at": "2024-11-25T14:14:43Z", + "updated_at": "2024-11-25T14:14:44Z", + "html_url": "https://github.com/balena-io-experimental/deployable/pull/2#discussion_r1856689298", + "pull_request_url": "https://api.github.com/repos/balena-io-experimental/deployable/pulls/2", + "author_association": "COLLABORATOR", + "_links": { + "self": { + "href": "https://api.github.com/repos/balena-io-experimental/deployable/pulls/comments/1856689298" + }, + "html": { + "href": "https://github.com/balena-io-experimental/deployable/pull/2#discussion_r1856689298" + }, + "pull_request": { + "href": "https://api.github.com/repos/balena-io-experimental/deployable/pulls/2" + } + }, + "reactions": { + "url": "https://api.github.com/repos/balena-io-experimental/deployable/pulls/comments/1856689298/reactions", + "total_count": 0, + "+1": 0, + "-1": 0, + "laugh": 0, + "hooray": 0, + "confused": 0, + "heart": 0, + "rocket": 0, + "eyes": 0 + }, + "start_line": null, + "original_start_line": null, + "start_side": null, + "line": 3, + "original_line": 3, + "side": "RIGHT", + "original_position": 3, + "position": 3, + "subject_type": "line" + }, + "pull_request": { + "url": "https://api.github.com/repos/balena-io-experimental/deployable/pulls/2", + "id": 2188445505, + "node_id": "PR_kwDONCUcDs6CcQdB", + "html_url": "https://github.com/balena-io-experimental/deployable/pull/2", + "diff_url": "https://github.com/balena-io-experimental/deployable/pull/2.diff", + "patch_url": "https://github.com/balena-io-experimental/deployable/pull/2.patch", + "issue_url": "https://api.github.com/repos/balena-io-experimental/deployable/issues/2", + "number": 2, + "state": "open", + "locked": false, + "title": "Initial commit of partial app logic", + "user": { + "login": "klutchell", + "id": 20458272, + "node_id": "MDQ6VXNlcjIwNDU4Mjcy", + "avatar_url": "https://avatars.githubusercontent.com/u/20458272?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/klutchell", + "html_url": "https://github.com/klutchell", + "followers_url": "https://api.github.com/users/klutchell/followers", + "following_url": "https://api.github.com/users/klutchell/following{/other_user}", + "gists_url": "https://api.github.com/users/klutchell/gists{/gist_id}", + "starred_url": "https://api.github.com/users/klutchell/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/klutchell/subscriptions", + "organizations_url": "https://api.github.com/users/klutchell/orgs", + "repos_url": "https://api.github.com/users/klutchell/repos", + "events_url": "https://api.github.com/users/klutchell/events{/privacy}", + "received_events_url": "https://api.github.com/users/klutchell/received_events", + "type": "User", + "user_view_type": "public", + "site_admin": false + }, + "body": null, + "created_at": "2024-11-19T20:57:39Z", + "updated_at": "2024-11-25T14:14:44Z", + "closed_at": null, + "merged_at": null, + "merge_commit_sha": "4fcecaf28fc9f124c541486b8c59cb33d695754a", + "assignee": null, + "assignees": [], + "requested_reviewers": [], + "requested_teams": [], + "labels": [], + "milestone": null, + "draft": false, + "commits_url": "https://api.github.com/repos/balena-io-experimental/deployable/pulls/2/commits", + "review_comments_url": "https://api.github.com/repos/balena-io-experimental/deployable/pulls/2/comments", + "review_comment_url": "https://api.github.com/repos/balena-io-experimental/deployable/pulls/comments{/number}", + "comments_url": "https://api.github.com/repos/balena-io-experimental/deployable/issues/2/comments", + "statuses_url": "https://api.github.com/repos/balena-io-experimental/deployable/statuses/91707f292be6028f598270d2ed6fedeba18670be", + "head": { + "label": "balena-io-experimental:kyle/develop", + "ref": "kyle/develop", + "sha": "91707f292be6028f598270d2ed6fedeba18670be", + "user": { + "login": "balena-io-experimental", + "id": 18610741, + "node_id": "MDEyOk9yZ2FuaXphdGlvbjE4NjEwNzQx", + "avatar_url": "https://avatars.githubusercontent.com/u/18610741?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/balena-io-experimental", + "html_url": "https://github.com/balena-io-experimental", + "followers_url": "https://api.github.com/users/balena-io-experimental/followers", + "following_url": "https://api.github.com/users/balena-io-experimental/following{/other_user}", + "gists_url": "https://api.github.com/users/balena-io-experimental/gists{/gist_id}", + "starred_url": "https://api.github.com/users/balena-io-experimental/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/balena-io-experimental/subscriptions", + "organizations_url": "https://api.github.com/users/balena-io-experimental/orgs", + "repos_url": "https://api.github.com/users/balena-io-experimental/repos", + "events_url": "https://api.github.com/users/balena-io-experimental/events{/privacy}", + "received_events_url": "https://api.github.com/users/balena-io-experimental/received_events", + "type": "Organization", + "user_view_type": "public", + "site_admin": false + }, + "repo": { + "id": 874847246, + "node_id": "R_kgDONCUcDg", + "name": "deployable", + "full_name": "balena-io-experimental/deployable", + "private": true, + "owner": { + "login": "balena-io-experimental", + "id": 18610741, + "node_id": "MDEyOk9yZ2FuaXphdGlvbjE4NjEwNzQx", + "avatar_url": "https://avatars.githubusercontent.com/u/18610741?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/balena-io-experimental", + "html_url": "https://github.com/balena-io-experimental", + "followers_url": "https://api.github.com/users/balena-io-experimental/followers", + "following_url": "https://api.github.com/users/balena-io-experimental/following{/other_user}", + "gists_url": "https://api.github.com/users/balena-io-experimental/gists{/gist_id}", + "starred_url": "https://api.github.com/users/balena-io-experimental/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/balena-io-experimental/subscriptions", + "organizations_url": "https://api.github.com/users/balena-io-experimental/orgs", + "repos_url": "https://api.github.com/users/balena-io-experimental/repos", + "events_url": "https://api.github.com/users/balena-io-experimental/events{/privacy}", + "received_events_url": "https://api.github.com/users/balena-io-experimental/received_events", + "type": "Organization", + "user_view_type": "public", + "site_admin": false + }, + "html_url": "https://github.com/balena-io-experimental/deployable", + "description": "Approve deployments with comment reactions", + "fork": false, + "url": "https://api.github.com/repos/balena-io-experimental/deployable", + "forks_url": "https://api.github.com/repos/balena-io-experimental/deployable/forks", + "keys_url": "https://api.github.com/repos/balena-io-experimental/deployable/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/balena-io-experimental/deployable/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/balena-io-experimental/deployable/teams", + "hooks_url": "https://api.github.com/repos/balena-io-experimental/deployable/hooks", + "issue_events_url": "https://api.github.com/repos/balena-io-experimental/deployable/issues/events{/number}", + "events_url": "https://api.github.com/repos/balena-io-experimental/deployable/events", + "assignees_url": "https://api.github.com/repos/balena-io-experimental/deployable/assignees{/user}", + "branches_url": "https://api.github.com/repos/balena-io-experimental/deployable/branches{/branch}", + "tags_url": "https://api.github.com/repos/balena-io-experimental/deployable/tags", + "blobs_url": "https://api.github.com/repos/balena-io-experimental/deployable/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/balena-io-experimental/deployable/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/balena-io-experimental/deployable/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/balena-io-experimental/deployable/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/balena-io-experimental/deployable/statuses/{sha}", + "languages_url": "https://api.github.com/repos/balena-io-experimental/deployable/languages", + "stargazers_url": "https://api.github.com/repos/balena-io-experimental/deployable/stargazers", + "contributors_url": "https://api.github.com/repos/balena-io-experimental/deployable/contributors", + "subscribers_url": "https://api.github.com/repos/balena-io-experimental/deployable/subscribers", + "subscription_url": "https://api.github.com/repos/balena-io-experimental/deployable/subscription", + "commits_url": "https://api.github.com/repos/balena-io-experimental/deployable/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/balena-io-experimental/deployable/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/balena-io-experimental/deployable/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/balena-io-experimental/deployable/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/balena-io-experimental/deployable/contents/{+path}", + "compare_url": "https://api.github.com/repos/balena-io-experimental/deployable/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/balena-io-experimental/deployable/merges", + "archive_url": "https://api.github.com/repos/balena-io-experimental/deployable/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/balena-io-experimental/deployable/downloads", + "issues_url": "https://api.github.com/repos/balena-io-experimental/deployable/issues{/number}", + "pulls_url": "https://api.github.com/repos/balena-io-experimental/deployable/pulls{/number}", + "milestones_url": "https://api.github.com/repos/balena-io-experimental/deployable/milestones{/number}", + "notifications_url": "https://api.github.com/repos/balena-io-experimental/deployable/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/balena-io-experimental/deployable/labels{/name}", + "releases_url": "https://api.github.com/repos/balena-io-experimental/deployable/releases{/id}", + "deployments_url": "https://api.github.com/repos/balena-io-experimental/deployable/deployments", + "created_at": "2024-10-18T15:11:02Z", + "updated_at": "2024-10-18T15:12:13Z", + "pushed_at": "2024-11-25T00:16:18Z", + "git_url": "git://github.com/balena-io-experimental/deployable.git", + "ssh_url": "git@github.com:balena-io-experimental/deployable.git", + "clone_url": "https://github.com/balena-io-experimental/deployable.git", + "svn_url": "https://github.com/balena-io-experimental/deployable", + "homepage": null, + "size": 171, + "stargazers_count": 0, + "watchers_count": 0, + "language": "TypeScript", + "has_issues": true, + "has_projects": true, + "has_downloads": true, + "has_wiki": true, + "has_pages": false, + "has_discussions": false, + "forks_count": 0, + "mirror_url": null, + "archived": false, + "disabled": false, + "open_issues_count": 2, + "license": { + "key": "isc", + "name": "ISC License", + "spdx_id": "ISC", + "url": "https://api.github.com/licenses/isc", + "node_id": "MDc6TGljZW5zZTEw" + }, + "allow_forking": false, + "is_template": false, + "web_commit_signoff_required": false, + "topics": [], + "visibility": "internal", + "forks": 0, + "open_issues": 2, + "watchers": 0, + "default_branch": "main", + "allow_squash_merge": false, + "allow_merge_commit": true, + "allow_rebase_merge": false, + "allow_auto_merge": true, + "delete_branch_on_merge": true, + "allow_update_branch": false, + "use_squash_pr_title_as_default": false, + "squash_merge_commit_message": "COMMIT_MESSAGES", + "squash_merge_commit_title": "COMMIT_OR_PR_TITLE", + "merge_commit_message": "PR_TITLE", + "merge_commit_title": "MERGE_MESSAGE" + } + }, + "base": { + "label": "balena-io-experimental:main", + "ref": "main", + "sha": "89354cd1344b8de289e5965328831992448eac7a", + "user": { + "login": "balena-io-experimental", + "id": 18610741, + "node_id": "MDEyOk9yZ2FuaXphdGlvbjE4NjEwNzQx", + "avatar_url": "https://avatars.githubusercontent.com/u/18610741?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/balena-io-experimental", + "html_url": "https://github.com/balena-io-experimental", + "followers_url": "https://api.github.com/users/balena-io-experimental/followers", + "following_url": "https://api.github.com/users/balena-io-experimental/following{/other_user}", + "gists_url": "https://api.github.com/users/balena-io-experimental/gists{/gist_id}", + "starred_url": "https://api.github.com/users/balena-io-experimental/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/balena-io-experimental/subscriptions", + "organizations_url": "https://api.github.com/users/balena-io-experimental/orgs", + "repos_url": "https://api.github.com/users/balena-io-experimental/repos", + "events_url": "https://api.github.com/users/balena-io-experimental/events{/privacy}", + "received_events_url": "https://api.github.com/users/balena-io-experimental/received_events", + "type": "Organization", + "user_view_type": "public", + "site_admin": false + }, + "repo": { + "id": 874847246, + "node_id": "R_kgDONCUcDg", + "name": "deployable", + "full_name": "balena-io-experimental/deployable", + "private": true, + "owner": { + "login": "balena-io-experimental", + "id": 18610741, + "node_id": "MDEyOk9yZ2FuaXphdGlvbjE4NjEwNzQx", + "avatar_url": "https://avatars.githubusercontent.com/u/18610741?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/balena-io-experimental", + "html_url": "https://github.com/balena-io-experimental", + "followers_url": "https://api.github.com/users/balena-io-experimental/followers", + "following_url": "https://api.github.com/users/balena-io-experimental/following{/other_user}", + "gists_url": "https://api.github.com/users/balena-io-experimental/gists{/gist_id}", + "starred_url": "https://api.github.com/users/balena-io-experimental/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/balena-io-experimental/subscriptions", + "organizations_url": "https://api.github.com/users/balena-io-experimental/orgs", + "repos_url": "https://api.github.com/users/balena-io-experimental/repos", + "events_url": "https://api.github.com/users/balena-io-experimental/events{/privacy}", + "received_events_url": "https://api.github.com/users/balena-io-experimental/received_events", + "type": "Organization", + "user_view_type": "public", + "site_admin": false + }, + "html_url": "https://github.com/balena-io-experimental/deployable", + "description": "Approve deployments with comment reactions", + "fork": false, + "url": "https://api.github.com/repos/balena-io-experimental/deployable", + "forks_url": "https://api.github.com/repos/balena-io-experimental/deployable/forks", + "keys_url": "https://api.github.com/repos/balena-io-experimental/deployable/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/balena-io-experimental/deployable/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/balena-io-experimental/deployable/teams", + "hooks_url": "https://api.github.com/repos/balena-io-experimental/deployable/hooks", + "issue_events_url": "https://api.github.com/repos/balena-io-experimental/deployable/issues/events{/number}", + "events_url": "https://api.github.com/repos/balena-io-experimental/deployable/events", + "assignees_url": "https://api.github.com/repos/balena-io-experimental/deployable/assignees{/user}", + "branches_url": "https://api.github.com/repos/balena-io-experimental/deployable/branches{/branch}", + "tags_url": "https://api.github.com/repos/balena-io-experimental/deployable/tags", + "blobs_url": "https://api.github.com/repos/balena-io-experimental/deployable/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/balena-io-experimental/deployable/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/balena-io-experimental/deployable/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/balena-io-experimental/deployable/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/balena-io-experimental/deployable/statuses/{sha}", + "languages_url": "https://api.github.com/repos/balena-io-experimental/deployable/languages", + "stargazers_url": "https://api.github.com/repos/balena-io-experimental/deployable/stargazers", + "contributors_url": "https://api.github.com/repos/balena-io-experimental/deployable/contributors", + "subscribers_url": "https://api.github.com/repos/balena-io-experimental/deployable/subscribers", + "subscription_url": "https://api.github.com/repos/balena-io-experimental/deployable/subscription", + "commits_url": "https://api.github.com/repos/balena-io-experimental/deployable/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/balena-io-experimental/deployable/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/balena-io-experimental/deployable/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/balena-io-experimental/deployable/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/balena-io-experimental/deployable/contents/{+path}", + "compare_url": "https://api.github.com/repos/balena-io-experimental/deployable/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/balena-io-experimental/deployable/merges", + "archive_url": "https://api.github.com/repos/balena-io-experimental/deployable/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/balena-io-experimental/deployable/downloads", + "issues_url": "https://api.github.com/repos/balena-io-experimental/deployable/issues{/number}", + "pulls_url": "https://api.github.com/repos/balena-io-experimental/deployable/pulls{/number}", + "milestones_url": "https://api.github.com/repos/balena-io-experimental/deployable/milestones{/number}", + "notifications_url": "https://api.github.com/repos/balena-io-experimental/deployable/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/balena-io-experimental/deployable/labels{/name}", + "releases_url": "https://api.github.com/repos/balena-io-experimental/deployable/releases{/id}", + "deployments_url": "https://api.github.com/repos/balena-io-experimental/deployable/deployments", + "created_at": "2024-10-18T15:11:02Z", + "updated_at": "2024-10-18T15:12:13Z", + "pushed_at": "2024-11-25T00:16:18Z", + "git_url": "git://github.com/balena-io-experimental/deployable.git", + "ssh_url": "git@github.com:balena-io-experimental/deployable.git", + "clone_url": "https://github.com/balena-io-experimental/deployable.git", + "svn_url": "https://github.com/balena-io-experimental/deployable", + "homepage": null, + "size": 171, + "stargazers_count": 0, + "watchers_count": 0, + "language": "TypeScript", + "has_issues": true, + "has_projects": true, + "has_downloads": true, + "has_wiki": true, + "has_pages": false, + "has_discussions": false, + "forks_count": 0, + "mirror_url": null, + "archived": false, + "disabled": false, + "open_issues_count": 2, + "license": { + "key": "isc", + "name": "ISC License", + "spdx_id": "ISC", + "url": "https://api.github.com/licenses/isc", + "node_id": "MDc6TGljZW5zZTEw" + }, + "allow_forking": false, + "is_template": false, + "web_commit_signoff_required": false, + "topics": [], + "visibility": "internal", + "forks": 0, + "open_issues": 2, + "watchers": 0, + "default_branch": "main", + "allow_squash_merge": false, + "allow_merge_commit": true, + "allow_rebase_merge": false, + "allow_auto_merge": true, + "delete_branch_on_merge": true, + "allow_update_branch": false, + "use_squash_pr_title_as_default": false, + "squash_merge_commit_message": "COMMIT_MESSAGES", + "squash_merge_commit_title": "COMMIT_OR_PR_TITLE", + "merge_commit_message": "PR_TITLE", + "merge_commit_title": "MERGE_MESSAGE" + } + }, + "_links": { + "self": { + "href": "https://api.github.com/repos/balena-io-experimental/deployable/pulls/2" + }, + "html": { + "href": "https://github.com/balena-io-experimental/deployable/pull/2" + }, + "issue": { + "href": "https://api.github.com/repos/balena-io-experimental/deployable/issues/2" + }, + "comments": { + "href": "https://api.github.com/repos/balena-io-experimental/deployable/issues/2/comments" + }, + "review_comments": { + "href": "https://api.github.com/repos/balena-io-experimental/deployable/pulls/2/comments" + }, + "review_comment": { + "href": "https://api.github.com/repos/balena-io-experimental/deployable/pulls/comments{/number}" + }, + "commits": { + "href": "https://api.github.com/repos/balena-io-experimental/deployable/pulls/2/commits" + }, + "statuses": { + "href": "https://api.github.com/repos/balena-io-experimental/deployable/statuses/91707f292be6028f598270d2ed6fedeba18670be" + } + }, + "author_association": "COLLABORATOR", + "auto_merge": null, + "active_lock_reason": null + }, + "repository": { + "id": 874847246, + "node_id": "R_kgDONCUcDg", + "name": "deployable", + "full_name": "balena-io-experimental/deployable", + "private": true, + "owner": { + "login": "balena-io-experimental", + "id": 18610741, + "node_id": "MDEyOk9yZ2FuaXphdGlvbjE4NjEwNzQx", + "avatar_url": "https://avatars.githubusercontent.com/u/18610741?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/balena-io-experimental", + "html_url": "https://github.com/balena-io-experimental", + "followers_url": "https://api.github.com/users/balena-io-experimental/followers", + "following_url": "https://api.github.com/users/balena-io-experimental/following{/other_user}", + "gists_url": "https://api.github.com/users/balena-io-experimental/gists{/gist_id}", + "starred_url": "https://api.github.com/users/balena-io-experimental/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/balena-io-experimental/subscriptions", + "organizations_url": "https://api.github.com/users/balena-io-experimental/orgs", + "repos_url": "https://api.github.com/users/balena-io-experimental/repos", + "events_url": "https://api.github.com/users/balena-io-experimental/events{/privacy}", + "received_events_url": "https://api.github.com/users/balena-io-experimental/received_events", + "type": "Organization", + "user_view_type": "public", + "site_admin": false + }, + "html_url": "https://github.com/balena-io-experimental/deployable", + "description": "Approve deployments with comment reactions", + "fork": false, + "url": "https://api.github.com/repos/balena-io-experimental/deployable", + "forks_url": "https://api.github.com/repos/balena-io-experimental/deployable/forks", + "keys_url": "https://api.github.com/repos/balena-io-experimental/deployable/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/balena-io-experimental/deployable/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/balena-io-experimental/deployable/teams", + "hooks_url": "https://api.github.com/repos/balena-io-experimental/deployable/hooks", + "issue_events_url": "https://api.github.com/repos/balena-io-experimental/deployable/issues/events{/number}", + "events_url": "https://api.github.com/repos/balena-io-experimental/deployable/events", + "assignees_url": "https://api.github.com/repos/balena-io-experimental/deployable/assignees{/user}", + "branches_url": "https://api.github.com/repos/balena-io-experimental/deployable/branches{/branch}", + "tags_url": "https://api.github.com/repos/balena-io-experimental/deployable/tags", + "blobs_url": "https://api.github.com/repos/balena-io-experimental/deployable/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/balena-io-experimental/deployable/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/balena-io-experimental/deployable/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/balena-io-experimental/deployable/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/balena-io-experimental/deployable/statuses/{sha}", + "languages_url": "https://api.github.com/repos/balena-io-experimental/deployable/languages", + "stargazers_url": "https://api.github.com/repos/balena-io-experimental/deployable/stargazers", + "contributors_url": "https://api.github.com/repos/balena-io-experimental/deployable/contributors", + "subscribers_url": "https://api.github.com/repos/balena-io-experimental/deployable/subscribers", + "subscription_url": "https://api.github.com/repos/balena-io-experimental/deployable/subscription", + "commits_url": "https://api.github.com/repos/balena-io-experimental/deployable/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/balena-io-experimental/deployable/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/balena-io-experimental/deployable/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/balena-io-experimental/deployable/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/balena-io-experimental/deployable/contents/{+path}", + "compare_url": "https://api.github.com/repos/balena-io-experimental/deployable/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/balena-io-experimental/deployable/merges", + "archive_url": "https://api.github.com/repos/balena-io-experimental/deployable/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/balena-io-experimental/deployable/downloads", + "issues_url": "https://api.github.com/repos/balena-io-experimental/deployable/issues{/number}", + "pulls_url": "https://api.github.com/repos/balena-io-experimental/deployable/pulls{/number}", + "milestones_url": "https://api.github.com/repos/balena-io-experimental/deployable/milestones{/number}", + "notifications_url": "https://api.github.com/repos/balena-io-experimental/deployable/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/balena-io-experimental/deployable/labels{/name}", + "releases_url": "https://api.github.com/repos/balena-io-experimental/deployable/releases{/id}", + "deployments_url": "https://api.github.com/repos/balena-io-experimental/deployable/deployments", + "created_at": "2024-10-18T15:11:02Z", + "updated_at": "2024-10-18T15:12:13Z", + "pushed_at": "2024-11-25T00:16:18Z", + "git_url": "git://github.com/balena-io-experimental/deployable.git", + "ssh_url": "git@github.com:balena-io-experimental/deployable.git", + "clone_url": "https://github.com/balena-io-experimental/deployable.git", + "svn_url": "https://github.com/balena-io-experimental/deployable", + "homepage": null, + "size": 171, + "stargazers_count": 0, + "watchers_count": 0, + "language": "TypeScript", + "has_issues": true, + "has_projects": true, + "has_downloads": true, + "has_wiki": true, + "has_pages": false, + "has_discussions": false, + "forks_count": 0, + "mirror_url": null, + "archived": false, + "disabled": false, + "open_issues_count": 2, + "license": { + "key": "isc", + "name": "ISC License", + "spdx_id": "ISC", + "url": "https://api.github.com/licenses/isc", + "node_id": "MDc6TGljZW5zZTEw" + }, + "allow_forking": false, + "is_template": false, + "web_commit_signoff_required": false, + "topics": [], + "visibility": "internal", + "forks": 0, + "open_issues": 2, + "watchers": 0, + "default_branch": "main", + "custom_properties": {} + }, + "organization": { + "login": "balena-io-experimental", + "id": 18610741, + "node_id": "MDEyOk9yZ2FuaXphdGlvbjE4NjEwNzQx", + "url": "https://api.github.com/orgs/balena-io-experimental", + "repos_url": "https://api.github.com/orgs/balena-io-experimental/repos", + "events_url": "https://api.github.com/orgs/balena-io-experimental/events", + "hooks_url": "https://api.github.com/orgs/balena-io-experimental/hooks", + "issues_url": "https://api.github.com/orgs/balena-io-experimental/issues", + "members_url": "https://api.github.com/orgs/balena-io-experimental/members{/member}", + "public_members_url": "https://api.github.com/orgs/balena-io-experimental/public_members{/member}", + "avatar_url": "https://avatars.githubusercontent.com/u/18610741?v=4", + "description": "A collection of play around and experimental projects for balena IoT devices" + }, + "enterprise": { + "id": 16136, + "slug": "balena", + "name": " Balena Ltd", + "node_id": "E_kgDNPwg", + "avatar_url": "https://avatars.githubusercontent.com/b/16136?v=4", + "description": "Balena brings the benefits of Linux containers to the IoT. Develop iteratively, deploy safely, and manage at scale.", + "website_url": "https://www.balena.io", + "html_url": "https://github.com/enterprises/balena", + "created_at": "2022-10-05T14:08:07Z", + "updated_at": "2024-10-04T08:57:35Z" + }, + "sender": { + "login": "klutchell", + "id": 20458272, + "node_id": "MDQ6VXNlcjIwNDU4Mjcy", + "avatar_url": "https://avatars.githubusercontent.com/u/20458272?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/klutchell", + "html_url": "https://github.com/klutchell", + "followers_url": "https://api.github.com/users/klutchell/followers", + "following_url": "https://api.github.com/users/klutchell/following{/other_user}", + "gists_url": "https://api.github.com/users/klutchell/gists{/gist_id}", + "starred_url": "https://api.github.com/users/klutchell/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/klutchell/subscriptions", + "organizations_url": "https://api.github.com/users/klutchell/orgs", + "repos_url": "https://api.github.com/users/klutchell/repos", + "events_url": "https://api.github.com/users/klutchell/events{/privacy}", + "received_events_url": "https://api.github.com/users/klutchell/received_events", + "type": "User", + "user_view_type": "public", + "site_admin": false + }, + "installation": { + "id": 57364329, + "node_id": "MDIzOkludGVncmF0aW9uSW5zdGFsbGF0aW9uNTczNjQzMjk=" + } +} diff --git a/test/index.test.ts b/test/index.test.ts index 7765785..3ab0fab 100644 --- a/test/index.test.ts +++ b/test/index.test.ts @@ -32,22 +32,20 @@ const testFixtures = { name: 'test-repo', }, }, - issue_comment: { - action: 'created', - issue: { - // eslint-disable-next-line id-denylist - number: 123, - pull_request: {}, + pull_request_review: { + action: 'submitted', + pull_request: { + head: { + sha: 'test-sha', + }, }, - comment: { + review: { id: 456, + body: '/deploy please', user: { login: 'test-user', - type: 'User', + id: 789, }, - body: '/deploy please', - created_at: '2024-01-01T00:00:00Z', - updated_at: '2024-01-01T00:00:00Z', }, installation: { id: 12345678 }, repository: { @@ -85,17 +83,10 @@ describe('GitHub Deployment App', () => { describe('deployment_protection_rule.requested', () => { test('approves deployment for allowed user', async () => { const mock = nock('https://api.github.com') + .get('/app') + .reply(200, { slug: 'test-bot' }) .post('/app/installations/12345678/access_tokens') .reply(200, { token: 'test', permissions: { issues: 'write' } }) - .post('/graphql') - .reply(200, { - data: { - viewer: { - login: 'test-bot', - databaseId: 123, - }, - }, - }) .post( '/repos/test-org/test-repo/actions/runs/1234/deployment_protection_rule', ) @@ -139,46 +130,20 @@ describe('GitHub Deployment App', () => { expect(nock.pendingMocks()).toStrictEqual([]); }); - test('throws error on failure to get app user', async () => { - const mock = nock('https://api.github.com') - .post('/app/installations/12345678/access_tokens') - .reply(200, { token: 'test', permissions: { issues: 'write' } }) - .post('/graphql') - .reply(404, { message: 'Not Found' }); - - await expect( - probot.receive({ - name: 'deployment_protection_rule', - payload: testFixtures.deployment_protection_rule, - }), - ).rejects.toThrow('Failed to get app user'); - - expect(mock.pendingMocks()).toStrictEqual([]); - }); - - test('ignores deployment from self', async () => { + test('ignores deployment from unauthorized user', async () => { const payload = { ...testFixtures.deployment_protection_rule, deployment: { creator: { - login: 'test-bot', - id: 123, + login: 'unauthorized-user', + id: 789, }, }, }; const mock = nock('https://api.github.com') - .post('/app/installations/12345678/access_tokens') - .reply(200, { token: 'test', permissions: { issues: 'write' } }) - .post('/graphql') - .reply(200, { - data: { - viewer: { - login: 'test-bot', - databaseId: 123, - }, - }, - }); + .get('/app') + .reply(200, { slug: 'test-bot' }); await probot.receive({ name: 'deployment_protection_rule', @@ -188,68 +153,59 @@ describe('GitHub Deployment App', () => { expect(mock.pendingMocks()).toStrictEqual([]); }); - test('ignores deployment from unauthorized user', async () => { - const payload = { - ...testFixtures.deployment_protection_rule, - deployment: { - creator: { - login: 'unauthorized-user', - id: 789, - }, - }, - }; + test('handles undefined BYPASS_ACTORS', async () => { + process.env.BYPASS_ACTORS = ''; const mock = nock('https://api.github.com') - .post('/app/installations/12345678/access_tokens') - .reply(200, { token: 'test', permissions: { issues: 'write' } }) - .post('/graphql') - .reply(200, { - data: { - viewer: { - login: 'test-bot', - databaseId: 123, - }, - }, - }); + .get('/app') + .reply(200, { slug: 'test-bot' }); await probot.receive({ name: 'deployment_protection_rule', - payload, + payload: testFixtures.deployment_protection_rule, + }); + + expect(mock.pendingMocks()).toStrictEqual([]); + }); + + test('handles defined bypass actors with multiple values', async () => { + process.env.BYPASS_ACTORS = '1,2,3'; + + const mock = nock('https://api.github.com') + .get('/app') + .reply(200, { slug: 'test-bot' }); + + await probot.receive({ + name: 'deployment_protection_rule', + payload: testFixtures.deployment_protection_rule, }); expect(mock.pendingMocks()).toStrictEqual([]); }); }); - describe('issue_comment.created', () => { + describe('pull_request_review.submitted', () => { test('processes valid deploy comment', async () => { const mock = nock('https://api.github.com') + .get('/app') + .reply(200, { slug: 'test-bot' }) .post('/app/installations/12345678/access_tokens') .reply(200, { token: 'test', permissions: { issues: 'write' } }) - .post('/repos/test-org/test-repo/issues/comments/456/reactions') - .reply(200) - .post('/graphql') - .reply(200, { - data: { - viewer: { - login: 'test-bot', - databaseId: 123, - }, - }, - }) - .get('/repos/test-org/test-repo/collaborators/test-user/permission') - .reply(200, { permission: 'admin' }) - .get('/repos/test-org/test-repo/pulls/123') - .reply(200, { - head: { sha: 'test-sha' }, - }) .get('/repos/test-org/test-repo/actions/runs') .query(true) - .reply(200, { workflow_runs: [] }); + .reply(200, { workflow_runs: [{ id: 1234 }] }) + .get('/repos/test-org/test-repo/actions/runs/1234/pending_deployments') + .reply(200, [ + { environment: { name: 'test' }, current_user_can_approve: true }, + ]) + .post( + '/repos/test-org/test-repo/actions/runs/1234/deployment_protection_rule', + ) + .reply(200); await probot.receive({ - name: 'issue_comment', - payload: testFixtures.issue_comment, + name: 'pull_request_review', + payload: testFixtures.pull_request_review, }); expect(mock.pendingMocks()).toStrictEqual([]); @@ -257,15 +213,15 @@ describe('GitHub Deployment App', () => { test('ignores non-deploy comments', async () => { const payload = { - ...testFixtures.issue_comment, - comment: { - ...testFixtures.issue_comment.comment, + ...testFixtures.pull_request_review, + review: { + ...testFixtures.pull_request_review.review, body: 'Just a regular comment', }, }; await probot.receive({ - name: 'issue_comment', + name: 'pull_request_review', payload, }); @@ -274,134 +230,79 @@ describe('GitHub Deployment App', () => { test('ignores bot comments', async () => { const payload = { - ...testFixtures.issue_comment, - comment: { - ...testFixtures.issue_comment.comment, + ...testFixtures.pull_request_review, + review: { + ...testFixtures.pull_request_review.review, user: { - ...testFixtures.issue_comment.comment.user, + ...testFixtures.pull_request_review.review.user, type: 'Bot', }, }, }; await probot.receive({ - name: 'issue_comment', + name: 'pull_request_review', payload, }); expect(nock.pendingMocks()).toStrictEqual([]); }); - test('ignores edited comments', async () => { - const payload = { - ...testFixtures.issue_comment, - comment: { - ...testFixtures.issue_comment.comment, - created_at: '2024-01-01T00:00:00Z', - updated_at: '2024-01-01T00:01:00Z', - }, - }; - - await probot.receive({ - name: 'issue_comment', - payload, - }); - - expect(nock.pendingMocks()).toStrictEqual([]); - }); - - test('ignores comments on non-pull-requests', async () => { - const payload = { - ...testFixtures.issue_comment, - issue: { - ...testFixtures.issue_comment.issue, - pull_request: null, - }, - }; - - await probot.receive({ - name: 'issue_comment', - payload, - }); - - expect(nock.pendingMocks()).toStrictEqual([]); - }); - - test('throws error on failure to get app user', async () => { + test('exits early if no matching workflow runs', async () => { const mock = nock('https://api.github.com') + .get('/app') + .reply(200, { slug: 'test-bot' }) .post('/app/installations/12345678/access_tokens') .reply(200, { token: 'test', permissions: { issues: 'write' } }) - .post('/repos/test-org/test-repo/issues/comments/456/reactions') - .reply(200) - .post('/graphql') - .reply(404, { message: 'Not Found' }); - - await expect( - probot.receive({ - name: 'issue_comment', - payload: testFixtures.issue_comment, - }), - ).rejects.toThrow('Failed to get app user'); + .get('/repos/test-org/test-repo/actions/runs') + .query(true) + .reply(200, { workflow_runs: [] }); + + await probot.receive({ + name: 'pull_request_review', + payload: testFixtures.pull_request_review, + }); expect(mock.pendingMocks()).toStrictEqual([]); }); - test('ignores comments from self', async () => { - const payload = { - ...testFixtures.issue_comment, - comment: { - ...testFixtures.issue_comment.comment, - user: { - ...testFixtures.issue_comment.comment.user, - login: 'test-bot', - }, - }, - }; - + test('exits early if no pending deployments', async () => { const mock = nock('https://api.github.com') + .get('/app') + .reply(200, { slug: 'test-bot' }) .post('/app/installations/12345678/access_tokens') .reply(200, { token: 'test', permissions: { issues: 'write' } }) - .post('/repos/test-org/test-repo/issues/comments/456/reactions') - .reply(200) - .post('/graphql') - .reply(200, { - data: { - viewer: { - login: 'test-bot', - databaseId: 123, - }, - }, - }); + .get('/repos/test-org/test-repo/actions/runs') + .query(true) + .reply(200, { workflow_runs: [{ id: 1234 }] }) + .get('/repos/test-org/test-repo/actions/runs/1234/pending_deployments') + .reply(200, []); await probot.receive({ - name: 'issue_comment', - payload, + name: 'pull_request_review', + payload: testFixtures.pull_request_review, }); expect(mock.pendingMocks()).toStrictEqual([]); }); - test('ignores comments from users without write access', async () => { + test('exits early if no deployments can be approved', async () => { const mock = nock('https://api.github.com') + .get('/app') + .reply(200, { slug: 'test-bot' }) .post('/app/installations/12345678/access_tokens') .reply(200, { token: 'test', permissions: { issues: 'write' } }) - .post('/repos/test-org/test-repo/issues/comments/456/reactions') - .reply(200) - .post('/graphql') - .reply(200, { - data: { - viewer: { - login: 'test-bot', - databaseId: 123, - }, - }, - }) - .get('/repos/test-org/test-repo/collaborators/test-user/permission') - .reply(200, { permission: 'read' }); + .get('/repos/test-org/test-repo/actions/runs') + .query(true) + .reply(200, { workflow_runs: [{ id: 1234 }] }) + .get('/repos/test-org/test-repo/actions/runs/1234/pending_deployments') + .reply(200, [ + { environment: { name: 'test' }, current_user_can_approve: false }, + ]); await probot.receive({ - name: 'issue_comment', - payload: testFixtures.issue_comment, + name: 'pull_request_review', + payload: testFixtures.pull_request_review, }); expect(mock.pendingMocks()).toStrictEqual([]); From 9d18166726809f4784965b6a9eaeb3ef6e4a665e Mon Sep 17 00:00:00 2001 From: Kyle Harding Date: Mon, 25 Nov 2024 12:04:33 -0500 Subject: [PATCH 14/15] Remove app login check Signed-off-by: Kyle Harding --- src/index.ts | 16 ++++++++-------- test/index.test.ts | 28 +++------------------------- 2 files changed, 11 insertions(+), 33 deletions(-) diff --git a/src/index.ts b/src/index.ts index deef589..c744d1f 100644 --- a/src/index.ts +++ b/src/index.ts @@ -27,9 +27,9 @@ export default (app: Probot) => { return; } - const client = await app.auth(); // Gets an authenticated Octokit client - const { data: appDetails } = await client.apps.getAuthenticated(); // Retrieves details about the authenticated app - // app.log.info(JSON.stringify(appDetails, null, 2)); // Logs details about the app + // const client = await app.auth(); // Gets an authenticated Octokit client + // const { data: appDetails } = await client.apps.getAuthenticated(); // Retrieves details about the authenticated app + // // app.log.info(JSON.stringify(appDetails, null, 2)); // Logs details about the app const bypassActors = process.env.BYPASS_ACTORS?.split(',') ?? []; @@ -45,7 +45,7 @@ export default (app: Probot) => { return context.octokit.request(`POST ${callbackUrl}`, { environment_name: environment, state: 'approved', - comment: `Approved by ${appDetails.slug} on behalf of ${deployment.creator.login}`, + comment: `Approved via bypass actors list for ${deployment.creator.login}`, }); }); @@ -70,9 +70,9 @@ export default (app: Probot) => { return; } - const client = await app.auth(); // Gets an authenticated Octokit client - const { data: appDetails } = await client.apps.getAuthenticated(); // Retrieves details about the authenticated app - // app.log.info(JSON.stringify(appDetails, null, 2)); // Logs details about the app + // const client = await app.auth(); // Gets an authenticated Octokit client + // const { data: appDetails } = await client.apps.getAuthenticated(); // Retrieves details about the authenticated app + // // app.log.info(JSON.stringify(appDetails, null, 2)); // Logs details about the app // let approved = false; @@ -108,7 +108,7 @@ export default (app: Probot) => { run.id, environment, 'approved', - `Approved by ${appDetails.slug} via review comment: ${review.html_url}`, + `Approved by ${review.user.login} via review [comment](${review.html_url})`, ); // approved = true; } diff --git a/test/index.test.ts b/test/index.test.ts index 3ab0fab..87292bb 100644 --- a/test/index.test.ts +++ b/test/index.test.ts @@ -83,8 +83,6 @@ describe('GitHub Deployment App', () => { describe('deployment_protection_rule.requested', () => { test('approves deployment for allowed user', async () => { const mock = nock('https://api.github.com') - .get('/app') - .reply(200, { slug: 'test-bot' }) .post('/app/installations/12345678/access_tokens') .reply(200, { token: 'test', permissions: { issues: 'write' } }) .post( @@ -141,54 +139,40 @@ describe('GitHub Deployment App', () => { }, }; - const mock = nock('https://api.github.com') - .get('/app') - .reply(200, { slug: 'test-bot' }); - await probot.receive({ name: 'deployment_protection_rule', payload, }); - expect(mock.pendingMocks()).toStrictEqual([]); + expect(nock.pendingMocks()).toStrictEqual([]); }); test('handles undefined BYPASS_ACTORS', async () => { process.env.BYPASS_ACTORS = ''; - const mock = nock('https://api.github.com') - .get('/app') - .reply(200, { slug: 'test-bot' }); - await probot.receive({ name: 'deployment_protection_rule', payload: testFixtures.deployment_protection_rule, }); - expect(mock.pendingMocks()).toStrictEqual([]); + expect(nock.pendingMocks()).toStrictEqual([]); }); test('handles defined bypass actors with multiple values', async () => { process.env.BYPASS_ACTORS = '1,2,3'; - const mock = nock('https://api.github.com') - .get('/app') - .reply(200, { slug: 'test-bot' }); - await probot.receive({ name: 'deployment_protection_rule', payload: testFixtures.deployment_protection_rule, }); - expect(mock.pendingMocks()).toStrictEqual([]); + expect(nock.pendingMocks()).toStrictEqual([]); }); }); describe('pull_request_review.submitted', () => { test('processes valid deploy comment', async () => { const mock = nock('https://api.github.com') - .get('/app') - .reply(200, { slug: 'test-bot' }) .post('/app/installations/12345678/access_tokens') .reply(200, { token: 'test', permissions: { issues: 'write' } }) .get('/repos/test-org/test-repo/actions/runs') @@ -250,8 +234,6 @@ describe('GitHub Deployment App', () => { test('exits early if no matching workflow runs', async () => { const mock = nock('https://api.github.com') - .get('/app') - .reply(200, { slug: 'test-bot' }) .post('/app/installations/12345678/access_tokens') .reply(200, { token: 'test', permissions: { issues: 'write' } }) .get('/repos/test-org/test-repo/actions/runs') @@ -268,8 +250,6 @@ describe('GitHub Deployment App', () => { test('exits early if no pending deployments', async () => { const mock = nock('https://api.github.com') - .get('/app') - .reply(200, { slug: 'test-bot' }) .post('/app/installations/12345678/access_tokens') .reply(200, { token: 'test', permissions: { issues: 'write' } }) .get('/repos/test-org/test-repo/actions/runs') @@ -288,8 +268,6 @@ describe('GitHub Deployment App', () => { test('exits early if no deployments can be approved', async () => { const mock = nock('https://api.github.com') - .get('/app') - .reply(200, { slug: 'test-bot' }) .post('/app/installations/12345678/access_tokens') .reply(200, { token: 'test', permissions: { issues: 'write' } }) .get('/repos/test-org/test-repo/actions/runs') From afd8cd63ecdd9d9ac3b9408312aae5e5bc1e4bae Mon Sep 17 00:00:00 2001 From: Kyle Harding Date: Mon, 25 Nov 2024 14:59:01 -0500 Subject: [PATCH 15/15] Handle existing review comments with matching sha Signed-off-by: Kyle Harding --- src/client.ts | 23 +++++----- src/index.ts | 50 +++++++++++++++------ test/index.test.ts | 106 +++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 153 insertions(+), 26 deletions(-) diff --git a/src/client.ts b/src/client.ts index 8da3340..f0e59f8 100644 --- a/src/client.ts +++ b/src/client.ts @@ -89,16 +89,19 @@ export async function listPullRequestCommits( return commits; } -// export async function getPullRequest( -// context: any, -// prNumber: number, -// ): Promise { -// const request = context.repo({ -// pull_number: prNumber, -// }); -// const { data: pullRequest } = await context.octokit.rest.pulls.get(request); -// return pullRequest; -// } +// https://octokit.github.io/rest.js/v21/#pulls-list-reviews +// https://docs.github.com/en/rest/pulls/reviews?apiVersion=2022-11-28#list-reviews-for-a-pull-request +export async function listPullRequestReviews( + context: any, + prNumber: number, +): Promise { + const request = context.repo({ + pull_number: prNumber, + }); + const { data: reviews } = + await context.octokit.rest.pulls.listReviews(request); + return reviews; +} // https://octokit.github.io/rest.js/v21/#actions-list-workflow-runs-for-repo // https://docs.github.com/en/rest/actions/workflow-runs#list-workflow-runs-for-a-repository diff --git a/src/index.ts b/src/index.ts index c744d1f..10b8ff1 100644 --- a/src/index.ts +++ b/src/index.ts @@ -12,9 +12,16 @@ export default (app: Probot) => { environment, deployment, deployment_callback_url: callbackUrl, + pull_requests: pullRequests, } = context.payload as DeploymentProtectionRuleRequestedEvent; - if (!deployment || !event || !environment || !callbackUrl) { + if ( + !deployment || + !event || + !environment || + !callbackUrl || + !pullRequests + ) { context.log.error('Deployment protection rule not found'); return; } @@ -32,21 +39,38 @@ export default (app: Probot) => { // // app.log.info(JSON.stringify(appDetails, null, 2)); // Logs details about the app const bypassActors = process.env.BYPASS_ACTORS?.split(',') ?? []; + if (bypassActors.includes(deployment.creator.id.toString())) { + // context.log.info('Approving deployment %s', deployment.id); + return context.octokit.request(`POST ${callbackUrl}`, { + environment_name: environment, + state: 'approved', + comment: `Approved via bypass actors list for ${deployment.creator.login}`, + }); + } - if (!bypassActors.includes(deployment.creator.id.toString())) { - context.log.info( - 'User %s is not on the auto-approve list', - deployment.creator.login, + for (const pull of pullRequests) { + // get all reviews for the pull request + const reviews = await GitHubClient.listPullRequestReviews( + context, + pull.number, ); - return; - } - context.log.info('Approving deployment %s', deployment.id); - return context.octokit.request(`POST ${callbackUrl}`, { - environment_name: environment, - state: 'approved', - comment: `Approved via bypass actors list for ${deployment.creator.login}`, - }); + // find the first review that is not a changes requested review and has the same sha as the deployment + const deployReview = reviews.find( + (review) => + review.state !== 'CHANGES_REQUESTED' && + review.commit_id === deployment.sha && + review.body.startsWith('/deploy'), + ); + + if (deployReview) { + return context.octokit.request(`POST ${callbackUrl}`, { + environment_name: environment, + state: 'approved', + comment: `Approved by ${deployReview.user.login} via review [comment](${deployReview.html_url})`, + }); + } + } }); app.on('pull_request_review.submitted', async (context: Context) => { diff --git a/test/index.test.ts b/test/index.test.ts index 87292bb..9d390d7 100644 --- a/test/index.test.ts +++ b/test/index.test.ts @@ -23,6 +23,7 @@ const testFixtures = { login: 'bypass-actor', id: 5, }, + sha: 'test-sha', }, installation: { id: 12345678 }, repository: { @@ -31,6 +32,8 @@ const testFixtures = { }, name: 'test-repo', }, + // eslint-disable-next-line id-denylist + pull_requests: [{ number: 123 }], }, pull_request_review: { action: 'submitted', @@ -129,6 +132,11 @@ describe('GitHub Deployment App', () => { }); test('ignores deployment from unauthorized user', async () => { + const mock = nock('https://api.github.com') + .post('/app/installations/12345678/access_tokens') + .reply(200, { token: 'test', permissions: { issues: 'write' } }) + .get('/repos/test-org/test-repo/pulls/123/reviews') + .reply(200, [{ commit_id: 'test-sha', body: '/deploy please' }]); const payload = { ...testFixtures.deployment_protection_rule, deployment: { @@ -144,29 +152,121 @@ describe('GitHub Deployment App', () => { payload, }); - expect(nock.pendingMocks()).toStrictEqual([]); + expect(mock.pendingMocks()).toStrictEqual([]); }); test('handles undefined BYPASS_ACTORS', async () => { process.env.BYPASS_ACTORS = ''; + const mock = nock('https://api.github.com') + .post('/app/installations/12345678/access_tokens') + .reply(200, { token: 'test', permissions: { issues: 'write' } }) + .get('/repos/test-org/test-repo/pulls/123/reviews') + .reply(200, []); + await probot.receive({ name: 'deployment_protection_rule', payload: testFixtures.deployment_protection_rule, }); - expect(nock.pendingMocks()).toStrictEqual([]); + expect(mock.pendingMocks()).toStrictEqual([]); }); test('handles defined bypass actors with multiple values', async () => { process.env.BYPASS_ACTORS = '1,2,3'; + const mock = nock('https://api.github.com') + .post('/app/installations/12345678/access_tokens') + .reply(200, { token: 'test', permissions: { issues: 'write' } }) + .get('/repos/test-org/test-repo/pulls/123/reviews') + .reply(200, []); + await probot.receive({ name: 'deployment_protection_rule', payload: testFixtures.deployment_protection_rule, }); - expect(nock.pendingMocks()).toStrictEqual([]); + expect(mock.pendingMocks()).toStrictEqual([]); + }); + + test('approves deployment for APPROVED pull request review', async () => { + const mock = nock('https://api.github.com') + .post('/app/installations/12345678/access_tokens') + .reply(200, { token: 'test', permissions: { issues: 'write' } }) + .get('/repos/test-org/test-repo/pulls/123/reviews') + .reply(200, [ + { + commit_id: 'test-sha', + body: '/deploy please', + state: 'APPROVED', + user: { login: 'test-user', id: 789 }, + }, + ]) + .post( + '/repos/test-org/test-repo/actions/runs/1234/deployment_protection_rule', + ) + .reply(200); + + process.env.BYPASS_ACTORS = ''; + + await probot.receive({ + name: 'deployment_protection_rule', + payload: testFixtures.deployment_protection_rule, + }); + + expect(mock.pendingMocks()).toStrictEqual([]); + }); + + test('approves deployment for COMMENTED pull request review', async () => { + const mock = nock('https://api.github.com') + .post('/app/installations/12345678/access_tokens') + .reply(200, { token: 'test', permissions: { issues: 'write' } }) + .get('/repos/test-org/test-repo/pulls/123/reviews') + .reply(200, [ + { + commit_id: 'test-sha', + body: '/deploy please', + state: 'commented', + user: { login: 'test-user', id: 789 }, + }, + ]) + .post( + '/repos/test-org/test-repo/actions/runs/1234/deployment_protection_rule', + ) + .reply(200); + + process.env.BYPASS_ACTORS = ''; + + await probot.receive({ + name: 'deployment_protection_rule', + payload: testFixtures.deployment_protection_rule, + }); + + expect(mock.pendingMocks()).toStrictEqual([]); + }); + + test('ignores deployment for CHANGES_REQUESTED pull request review', async () => { + const mock = nock('https://api.github.com') + .post('/app/installations/12345678/access_tokens') + .reply(200, { token: 'test', permissions: { issues: 'write' } }) + .get('/repos/test-org/test-repo/pulls/123/reviews') + .reply(200, [ + { + commit_id: 'test-sha', + body: '/deploy please', + state: 'CHANGES_REQUESTED', + user: { login: 'test-user', id: 789 }, + }, + ]); + + process.env.BYPASS_ACTORS = ''; + + await probot.receive({ + name: 'deployment_protection_rule', + payload: testFixtures.deployment_protection_rule, + }); + + expect(mock.pendingMocks()).toStrictEqual([]); }); });