├── .gitattributes
├── .github
├── renovate.json5
└── workflows
│ ├── release.yaml
│ └── ts.yaml
├── .gitignore
├── .prettierignore
├── .prettierrc.json
├── LICENSE
├── README.md
├── README_EXAMPLES.md
├── action.yaml
├── effective-build-cache-diagram.drawio.svg
├── eslint.config.js
├── package.json
├── pnpm-lock.yaml
├── src
├── bake.ts
├── docker.ts
├── github.ts
├── infer.ts
├── main.ts
└── run.ts
├── tests
├── docker.test.ts
├── fixture
│ ├── Dockerfile
│ └── docker-bake.hcl
├── github.ts
├── infer.test.ts
└── run.test.ts
├── tsconfig.json
└── vitest.config.ts
/.gitattributes:
--------------------------------------------------------------------------------
1 | dist/** -diff linguist-generated=true
--------------------------------------------------------------------------------
/.github/renovate.json5:
--------------------------------------------------------------------------------
1 | {
2 | "extends": [
3 | "github>int128/renovate-base",
4 | "github>int128/typescript-action-renovate-config",
5 | "helpers:pinGitHubActionDigests",
6 | ]
7 | }
8 |
--------------------------------------------------------------------------------
/.github/workflows/release.yaml:
--------------------------------------------------------------------------------
1 | name: release
2 |
3 | on:
4 | pull_request:
5 | paths:
6 | - .github/workflows/release.yaml
7 | push:
8 | branches:
9 | - main
10 | tags:
11 | - v*
12 |
13 | jobs:
14 | tag:
15 | runs-on: ubuntu-latest
16 | timeout-minutes: 10
17 | steps:
18 | - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
19 | - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
20 | with:
21 | node-version: 20
22 | - run: npm install -g pnpm@latest-10
23 | - run: pnpm i
24 | - run: pnpm build
25 | - uses: int128/release-typescript-action@4b93cf2f4b55fbce962db4c9acb89760c4a699d9 # v1.36.0
26 |
--------------------------------------------------------------------------------
/.github/workflows/ts.yaml:
--------------------------------------------------------------------------------
1 | name: ts
2 |
3 | on:
4 | pull_request:
5 | paths:
6 | - src/**
7 | - tests/**
8 | - '*.json'
9 | - '*.yaml'
10 | - .github/workflows/ts.yaml
11 | push:
12 | branches:
13 | - main
14 | paths:
15 | - src/**
16 | - tests/**
17 | - '*.json'
18 | - '*.yaml'
19 | - .github/workflows/ts.yaml
20 |
21 | jobs:
22 | test:
23 | runs-on: ubuntu-latest
24 | timeout-minutes: 10
25 | steps:
26 | - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
27 | - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
28 | with:
29 | node-version: 20
30 | - run: npm install -g pnpm@latest-10
31 | - run: pnpm i
32 | - run: pnpm test
33 | - run: pnpm build
34 |
35 | # E2E test
36 | - name: Run int128/docker-build-cache-config-action
37 | uses: ./
38 | id: cache
39 | with:
40 | image: ghcr.io/${{ github.repository }}/cache
41 | - uses: docker/metadata-action@902fa8ec7d6ecbf8d84d538b9b233a880e428804 # v5.7.0
42 | id: metadata
43 | with:
44 | images: ghcr.io/${{ github.repository }}
45 | - uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0
46 | with:
47 | registry: ghcr.io
48 | username: ${{ github.actor }}
49 | password: ${{ secrets.GITHUB_TOKEN }}
50 | - uses: docker/setup-buildx-action@b5ca514318bd6ebac0fb2aedd5d36ec1b5c232a2 # v3.10.0
51 | - uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0
52 | with:
53 | context: tests/fixture
54 | push: ${{ github.event_name == 'push' }}
55 | tags: ${{ steps.metadata.outputs.tags }}
56 | labels: ${{ steps.metadata.outputs.labels }}
57 | cache-from: ${{ steps.cache.outputs.cache-from }}
58 | cache-to: ${{ steps.cache.outputs.cache-to }}
59 | - uses: docker/bake-action@37816e747588cb137173af99ab33873600c46ea8 # v6.8.0
60 | with:
61 | push: ${{ github.event_name == 'push' }}
62 | workdir: tests/fixture
63 | source: .
64 | files: |
65 | ./docker-bake.hcl
66 | ${{ steps.metadata.outputs.bake-file }}
67 | ${{ steps.cache.outputs.bake-file }}
68 |
69 | generate:
70 | runs-on: ubuntu-latest
71 | timeout-minutes: 10
72 | steps:
73 | - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
74 | - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
75 | with:
76 | node-version: 20
77 | - run: npm install -g pnpm@latest-10
78 | - run: pnpm i
79 | - run: pnpm lint --fix
80 | - run: pnpm format
81 | - uses: int128/update-generated-files-action@f6dc44e35ce252932e9018f1c38d1e2a4ff80e14 # v2.60.0
82 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Dependency directory
2 | node_modules
3 |
4 | # Rest pulled from https://github.com/github/gitignore/blob/master/Node.gitignore
5 | # Logs
6 | logs
7 | *.log
8 | npm-debug.log*
9 | yarn-debug.log*
10 | yarn-error.log*
11 | lerna-debug.log*
12 |
13 | # Diagnostic reports (https://nodejs.org/api/report.html)
14 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
15 |
16 | # Runtime data
17 | pids
18 | *.pid
19 | *.seed
20 | *.pid.lock
21 |
22 | # Directory for instrumented libs generated by jscoverage/JSCover
23 | lib-cov
24 |
25 | # Coverage directory used by tools like istanbul
26 | coverage
27 | *.lcov
28 |
29 | # nyc test coverage
30 | .nyc_output
31 |
32 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
33 | .grunt
34 |
35 | # Bower dependency directory (https://bower.io/)
36 | bower_components
37 |
38 | # node-waf configuration
39 | .lock-wscript
40 |
41 | # Compiled binary addons (https://nodejs.org/api/addons.html)
42 | build/Release
43 |
44 | # Dependency directories
45 | jspm_packages/
46 |
47 | # TypeScript v1 declaration files
48 | typings/
49 |
50 | # TypeScript cache
51 | *.tsbuildinfo
52 |
53 | # Optional npm cache directory
54 | .npm
55 |
56 | # Optional eslint cache
57 | .eslintcache
58 |
59 | # Optional REPL history
60 | .node_repl_history
61 |
62 | # Output of 'npm pack'
63 | *.tgz
64 |
65 | # Yarn Integrity file
66 | .yarn-integrity
67 |
68 | # dotenv environment variables file
69 | .env
70 | .env.test
71 |
72 | # parcel-bundler cache (https://parceljs.org/)
73 | .cache
74 |
75 | # next.js build output
76 | .next
77 |
78 | # nuxt.js build output
79 | .nuxt
80 |
81 | # vuepress build output
82 | .vuepress/dist
83 |
84 | # Serverless directories
85 | .serverless/
86 |
87 | # FuseBox cache
88 | .fusebox/
89 |
90 | # DynamoDB Local files
91 | .dynamodb/
92 |
93 | # OS metadata
94 | .DS_Store
95 | Thumbs.db
96 |
97 | # Ignore built ts files
98 | lib/
99 |
100 | # Only release tag contains dist directory
101 | /dist
102 |
--------------------------------------------------------------------------------
/.prettierignore:
--------------------------------------------------------------------------------
1 | dist/
2 | lib/
3 | node_modules/
--------------------------------------------------------------------------------
/.prettierrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "printWidth": 120,
3 | "semi": false,
4 | "singleQuote": true
5 | }
6 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "[]"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright [yyyy] [name of copyright owner]
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # docker-build-cache-config-action [](https://github.com/int128/docker-build-cache-config-action/actions/workflows/ts.yaml)
2 |
3 | This action generates `cache-from` and `cache-to` inputs of [docker/build-push-action](https://github.com/docker/build-push-action) for the effective cache strategy in the pull request based development flow.
4 |
5 | ## Problem to solve
6 |
7 | [docker/build-push-action](https://github.com/docker/build-push-action) supports the cache management using Buildx (BuildKit).
8 | It can import and export a cache by the following parameters:
9 |
10 | ```yaml
11 | cache-from: type=registry,ref=REGISTRY/REPOSITORY:TAG
12 | cache-to: type=registry,ref=REGISTRY/REPOSITORY:TAG,mode=max
13 | ```
14 |
15 | If a same tag is used in the pull request based development flow, it will cause a cache miss.
16 | For example,
17 |
18 | 1. Initially, the cache points to main branch
19 | 1. When a pull request B is opened,
20 | - It imports the cache of main branch
21 | - The cache hits
22 | - It exports the cache of pull request B
23 | 1. When a pull request C is opened,
24 | - It imports the cache of pull request B
25 | - The cache misses
26 | - It exports the cache of pull request C
27 | 1. When the pull request B is merged into main,
28 | - It imports the cache of pull request C
29 | - The cache misses
30 | - It exports the cache of main branch
31 |
32 | Therefore, it needs to prevent the cache pollution caused by a pull request.
33 |
34 | ## How to solve
35 |
36 | Keep a cache tag tracking the corresponding branch.
37 |
38 | When the main branch is pushed, it imports a cache from the main tag.
39 | It finally exports a cache to the main tag for the future build.
40 |
41 | ```yaml
42 | cache-from: type=registry,ref=REGISTRY/REPOSITORY:main
43 | cache-to: type=registry,ref=REGISTRY/REPOSITORY:main,mode=max
44 | ```
45 |
46 | When a pull request is created or updated, it only imports a cache from the main tag.
47 | It does not export a cache to the main tag to prevent the cache pollution.
48 |
49 | ```yaml
50 | cache-from: type=registry,ref=REGISTRY/REPOSITORY:main
51 | cache-to:
52 | ```
53 |
54 | If the base branch of the pull request is not main, it imports both base tag and main tag.
55 |
56 | ```yaml
57 | cache-from: |
58 | type=registry,ref=REGISTRY/REPOSITORY:base
59 | type=registry,ref=REGISTRY/REPOSITORY:main
60 | cache-to:
61 | ```
62 |
63 | Here is the diagram of this cache strategy.
64 |
65 | 
66 |
67 | This action generates the cache parameters by this strategy.
68 |
69 | ```yaml
70 | - uses: int128/docker-build-cache-config-action@v1
71 | id: cache
72 | with:
73 | image: ghcr.io/${{ github.repository }}/cache
74 | - uses: docker/build-push-action@v2
75 | with:
76 | cache-from: ${{ steps.cache.outputs.cache-from }}
77 | cache-to: ${{ steps.cache.outputs.cache-to }}
78 | ```
79 |
80 | ## Examples
81 |
82 | ### Build with docker/build-push-action
83 |
84 | Here is an example to build a container image with [docker/build-push-action](https://github.com/docker/build-push-action).
85 |
86 | ```yaml
87 | - uses: docker/metadata-action@v3
88 | id: metadata
89 | with:
90 | images: ghcr.io/${{ github.repository }}
91 | - uses: int128/docker-build-cache-config-action@v1
92 | id: cache
93 | with:
94 | image: ghcr.io/${{ github.repository }}/cache
95 | - uses: docker/build-push-action@v2
96 | id: build
97 | with:
98 | push: true
99 | tags: ${{ steps.metadata.outputs.tags }}
100 | labels: ${{ steps.metadata.outputs.labels }}
101 | cache-from: ${{ steps.cache.outputs.cache-from }}
102 | cache-to: ${{ steps.cache.outputs.cache-to }}
103 | ```
104 |
105 | It will create the following image tags:
106 |
107 | ```
108 | ghcr.io/${{ github.repository }}:main
109 | ghcr.io/${{ github.repository }}:pr-1
110 | ghcr.io/${{ github.repository }}/cache:main
111 | ```
112 |
113 | See [README_EXAMPLES.md](README_EXAMPLES.md) for more examples.
114 |
115 | ### Build with docker/bake-action
116 |
117 | Here is an example to build a container image with [docker/bake-action](https://github.com/docker/bake-action).
118 |
119 | ```yaml
120 | - uses: docker/metadata-action@v3
121 | id: metadata
122 | with:
123 | images: ghcr.io/${{ github.repository }}
124 | - uses: int128/docker-build-cache-config-action@v1
125 | id: cache
126 | with:
127 | image: ghcr.io/${{ github.repository }}/cache
128 | - uses: docker/bake-action@v5
129 | id: build
130 | with:
131 | push: true
132 | files: |
133 | ./docker-bake.hcl
134 | ${{ steps.metadata.outputs.bake-file }}
135 | ${{ steps.cache.outputs.bake-file }}
136 | ```
137 |
138 | ```hcl
139 | # docker-bake.hcl
140 | target "docker-metadata-action" {}
141 |
142 | target "docker-build-cache-config-action" {}
143 |
144 | target "default" {
145 | inherits = ["docker-metadata-action", "docker-build-cache-config-action"]
146 | context = "."
147 | }
148 | ```
149 |
150 | ## Specification
151 |
152 | ### Inputs
153 |
154 | | Name | Default | Description |
155 | | -------------------- | ---------------------------------- | ---------------------------------------------------------------------------------------------- |
156 | | `image` | (required) | Image repository to import/export cache |
157 | | `cache-type` | `registry` | Type of cache backend (for source and destination). Can be registry, local, inline, gha and s3 |
158 | | `flavor` | - | Flavor (multiline string) |
159 | | `extra-cache-from` | - | Extra flag to `cache-from` |
160 | | `extra-cache-to` | - | Extra flag to `cache-to` |
161 | | `pull-request-cache` | - | Import and export a pull request cache |
162 | | `cache-key` | - | Custom cache key |
163 | | `cache-key-fallback` | - | Custom cache key to fallback |
164 | | `bake-target` | `docker-build-cache-config-action` | Bake target name |
165 |
166 | `flavor` is mostly compatible with [docker/metadata-action](https://github.com/docker/metadata-action#flavor-input)
167 | except this action supports only `prefix` and `suffix`.
168 |
169 | `extra-cache-to` is added to `cache-to` parameter only when it needs to export cache.
170 |
171 | Note that `cache-key` and `cache-key-fallback` are experimental.
172 | The specification may change in the future.
173 |
174 | ### Outputs
175 |
176 | | Name | Description |
177 | | ------------ | -------------------------------------- |
178 | | `cache-from` | Parameter for docker/build-push-action |
179 | | `cache-to` | Parameter for docker/build-push-action |
180 | | `bake-file` | Bake definition file |
181 |
182 | ### Events
183 |
184 | This action exports a cache on the following events:
185 |
186 | - `push` event to a branch
187 | - Export a cache to the tag corresponding to the pushed branch
188 | - `pull_request` event
189 | - Export a cache to the tag corresponding to the pull request number (only if `pull-request-cache` is set)
190 | - `issue_comment` event to a pull request
191 | - Export a cache to the tag corresponding to the pull request number (only if `pull-request-cache` is set)
192 | - Other events
193 | - Export nothing
194 |
195 | It imports a cache on the following events:
196 |
197 | - `push` event to a branch
198 | - Import a cache from the tag corresponding to the pushed branch
199 | - `pull_request` event
200 | - Import a cache from the tag corresponding to the pull request number
201 | - Import a cache from the tag corresponding to the base branch
202 | - Import a cache from the tag corresponding to the default branch
203 | - `issue_comment` event to a pull request
204 | - Import a cache from the tag corresponding to the pull request number
205 | - Import a cache from the tag corresponding to the base branch
206 | - Import a cache from the tag corresponding to the default branch
207 | - Other events
208 | - Import a cache from the tag corresponding to the default branch
209 |
--------------------------------------------------------------------------------
/README_EXAMPLES.md:
--------------------------------------------------------------------------------
1 | # Examples with docker-build-cache-config-action
2 |
3 | - [Basic](README.md#examples)
4 | - [Cache store](#cache-store)
5 | - [Store image and cache into the same repository](#store-image-and-cache-into-the-same-repository)
6 | - [For Amazon ECR](#for-amazon-ecr)
7 | - [Cache strategy](#cache-strategy)
8 | - [Import and export a pull request cache](#import-and-export-a-pull-request-cache)
9 | - [Build multi-architecture images](#build-multi-architecture-images)
10 | - [For monorepo](#for-monorepo)
11 | - [Build multiple image tags from a branch](#build-multiple-image-tags-from-a-branch)
12 | - [Cache backend type](#cache-backend-type)
13 | - [Use GitHub Actions cache backend](#use-github-actions-cache-backend)
14 |
15 | ## Cache store
16 |
17 | ### Store image and cache into the same repository
18 |
19 | You can set a tag suffix to store both image and cache into the same repository.
20 |
21 | ```yaml
22 | - uses: docker/metadata-action@v3
23 | id: metadata
24 | with:
25 | images: ghcr.io/${{ github.repository }}
26 | - uses: int128/docker-build-cache-config-action@v1
27 | id: cache
28 | with:
29 | image: ghcr.io/${{ github.repository }}
30 | flavor: suffix=-cache
31 | - uses: docker/build-push-action@v2
32 | id: build
33 | with:
34 | push: true
35 | tags: ${{ steps.metadata.outputs.tags }}
36 | labels: ${{ steps.metadata.outputs.labels }}
37 | cache-from: ${{ steps.cache.outputs.cache-from }}
38 | cache-to: ${{ steps.cache.outputs.cache-to }}
39 | ```
40 |
41 | It will create the following image tags:
42 |
43 | ```
44 | ghcr.io/${{ github.repository }}:main
45 | ghcr.io/${{ github.repository }}:main-cache
46 | ghcr.io/${{ github.repository }}:pr-1
47 | ```
48 |
49 | ### For Amazon ECR
50 |
51 | Amazon ECR now supports the cache manifest ([aws/containers-roadmap#876](https://github.com/aws/containers-roadmap/issues/876)).
52 | You can pass the extra attribute `image-manifest=true`.
53 | Here is an example to manage a cache in Amazon ECR.
54 |
55 | ```yaml
56 | jobs:
57 | build:
58 | runs-on: ubuntu-latest
59 | permissions:
60 | id-token: write
61 | contents: read
62 | outputs:
63 | image-uri: ${{ steps.ecr.outputs.registry }}/${{ github.repository }}@${{ steps.build.outputs.digest }}
64 | steps:
65 | - uses: aws-actions/configure-aws-credentials@v4
66 | with:
67 | role-to-assume: arn:aws:iam::ACCOUNT:role/ROLE
68 | - uses: aws-actions/amazon-ecr-login@v1
69 | id: ecr
70 | - uses: docker/metadata-action@v5
71 | id: metadata
72 | with:
73 | images: ${{ steps.ecr.outputs.registry }}/${{ github.repository }}
74 | - uses: int128/docker-build-cache-config-action@v1
75 | id: cache
76 | with:
77 | image: ${{ steps.ecr.outputs.registry }}/${{ github.repository }}
78 | suffix: -cache
79 | extra-cache-to: image-manifest=true
80 | - uses: docker/build-push-action@v5
81 | id: build
82 | with:
83 | push: true
84 | tags: ${{ steps.metadata.outputs.tags }}
85 | labels: ${{ steps.metadata.outputs.labels }}
86 | cache-from: ${{ steps.cache.outputs.cache-from }}
87 | cache-to: ${{ steps.cache.outputs.cache-to }}
88 | ```
89 |
90 | It will create the following image tags:
91 |
92 | ```
93 | ACCOUNT.dkr.ecr.REGION.amazonaws.com/${{ github.repository }}:main
94 | ACCOUNT.dkr.ecr.REGION.amazonaws.com/${{ github.repository }}:pr-1
95 | ACCOUNT.dkr.ecr.REGION.amazonaws.com/${{ github.repository }}:main-cache
96 | ```
97 |
98 | ## Cache strategy
99 |
100 | ### Import and export a pull request cache
101 |
102 | When a pull request is pushed, it can export a cache to a dedicated tag for the consecutive commits.
103 | It imports the cache from the dedicated tag when the pull request is pushed again.
104 |
105 | ```yaml
106 | cache-from: |
107 | type=registry,ref=REGISTRY/REPOSITORY:pr-1
108 | type=registry,ref=REGISTRY/REPOSITORY:main
109 | cache-to: type=registry,ref=REGISTRY/REPOSITORY:pr-1,mode=max
110 | ```
111 |
112 | Here is an example to enable the pull request cache feature.
113 |
114 | ```yaml
115 | - uses: docker/metadata-action@v3
116 | id: metadata
117 | with:
118 | images: ghcr.io/${{ github.repository }}
119 | - uses: int128/docker-build-cache-config-action@v1
120 | id: cache
121 | with:
122 | image: ghcr.io/${{ github.repository }}/cache
123 | pull-request-cache: true
124 | - uses: docker/build-push-action@v2
125 | id: build
126 | with:
127 | push: true
128 | tags: ${{ steps.metadata.outputs.tags }}
129 | labels: ${{ steps.metadata.outputs.labels }}
130 | cache-from: ${{ steps.cache.outputs.cache-from }}
131 | cache-to: ${{ steps.cache.outputs.cache-to }}
132 | ```
133 |
134 | It will create the following image tags:
135 |
136 | ```
137 | ghcr.io/${{ github.repository }}:main
138 | ghcr.io/${{ github.repository }}:pr-1
139 | ghcr.io/${{ github.repository }}/cache:main
140 | ghcr.io/${{ github.repository }}/cache:pr-1
141 | ```
142 |
143 | Note that it creates an image tag for every pull request.
144 | It is recommended to clean it when pull request is closed, or set a lifecycle policy into your container repository.
145 |
146 | ### Build multi-architecture images
147 |
148 | You can set a tag suffix to isolate caches for each architecture.
149 |
150 | ```yaml
151 | jobs:
152 | build:
153 | strategy:
154 | fail-fast: false
155 | matrix:
156 | platform:
157 | - linux/amd64
158 | - linux/arm64
159 | steps:
160 | - uses: docker/metadata-action@v3
161 | id: metadata
162 | with:
163 | images: ghcr.io/${{ github.repository }}
164 | flavor: suffix=-${{ matrix.platform }}
165 | - uses: int128/docker-build-cache-config-action@v1
166 | id: cache
167 | with:
168 | image: ghcr.io/${{ github.repository }}/cache
169 | flavor: suffix=-${{ matrix.platform }}
170 | - uses: docker/build-push-action@v2
171 | id: build
172 | with:
173 | push: true
174 | tags: ${{ steps.metadata.outputs.tags }}
175 | labels: ${{ steps.metadata.outputs.labels }}
176 | cache-from: ${{ steps.cache.outputs.cache-from }}
177 | cache-to: ${{ steps.cache.outputs.cache-to }}
178 | platforms: ${{ matrix.platform }}
179 | ```
180 |
181 | It will create the following image tags:
182 |
183 | ```
184 | ghcr.io/${{ github.repository }}:main-linux-amd64
185 | ghcr.io/${{ github.repository }}:main-linux-arm64
186 | ghcr.io/${{ github.repository }}:pr-1-linux-amd64
187 | ghcr.io/${{ github.repository }}:pr-1-linux-arm64
188 | ghcr.io/${{ github.repository }}/cache:main-linux-amd64
189 | ghcr.io/${{ github.repository }}/cache:main-linux-arm64
190 | ```
191 |
192 | ### For monorepo
193 |
194 | You can set a tag prefix to store caches of multiple images into a single repository.
195 |
196 | ```yaml
197 | - uses: docker/metadata-action@v3
198 | id: metadata
199 | with:
200 | images: ghcr.io/${{ github.repository }}/microservice-name
201 | - uses: int128/docker-build-cache-config-action@v1
202 | id: cache
203 | with:
204 | image: ghcr.io/${{ github.repository }}/cache
205 | flavor: prefix=microservice-name--
206 | - uses: docker/build-push-action@v2
207 | id: build
208 | with:
209 | push: true
210 | tags: ${{ steps.metadata.outputs.tags }}
211 | labels: ${{ steps.metadata.outputs.labels }}
212 | cache-from: ${{ steps.cache.outputs.cache-from }}
213 | cache-to: ${{ steps.cache.outputs.cache-to }}
214 | ```
215 |
216 | It will create the following image tags:
217 |
218 | ```
219 | ghcr.io/${{ github.repository }}/microservice-name:main
220 | ghcr.io/${{ github.repository }}/microservice-name:pr-1
221 | ghcr.io/${{ github.repository }}/cache:microservice-name--main
222 | ```
223 |
224 | ### Build multiple image tags from a branch
225 |
226 | For a complex project, it needs to build multiple image tags from a branch.
227 | For example, it builds the following images when the main branch is pushed:
228 |
229 | - Build an image tag `development` with the build-args of development environment
230 | - Build an image tag `staging` with the build-args of staging environment
231 |
232 | In this case, it needs to separate the cache for each environment as follows:
233 |
234 | - When the main branch is pushed,
235 | - A job builds an image for the development environment.
236 | It imports and exports a cache from/to `development` tag.
237 | - A job builds an image for the staging environment.
238 | It imports and exports a cache from/to `staging` tag.
239 | - When a pull request is created or updated,
240 | - A job builds an image for the pull request environment.
241 | It imports a cache from `development` tag.
242 |
243 | You can set a suffix to separate the caches for each environment.
244 |
245 | ```yaml
246 | jobs:
247 | build:
248 | strategy:
249 | fail-fast: false
250 | matrix:
251 | environment:
252 | - development
253 | - staging
254 | steps:
255 | - uses: docker/metadata-action@v3
256 | id: metadata
257 | with:
258 | images: ghcr.io/${{ github.repository }}
259 | flavor: suffix=-${{ matrix.environment }}
260 | - uses: int128/docker-build-cache-config-action@v1
261 | id: cache
262 | with:
263 | image: ghcr.io/${{ github.repository }}/cache
264 | cache-key: ${{ matrix.environment }}
265 | cache-key-fallback: development
266 | - uses: docker/build-push-action@v2
267 | id: build
268 | with:
269 | push: true
270 | tags: ${{ steps.metadata.outputs.tags }}
271 | labels: ${{ steps.metadata.outputs.labels }}
272 | cache-from: ${{ steps.cache.outputs.cache-from }}
273 | cache-to: ${{ steps.cache.outputs.cache-to }}
274 | ```
275 |
276 | It will create the following image tags:
277 |
278 | ```
279 | ghcr.io/${{ github.repository }}:development
280 | ghcr.io/${{ github.repository }}:staging
281 | ghcr.io/${{ github.repository }}/cache:development
282 | ghcr.io/${{ github.repository }}/cache:staging
283 | ```
284 |
285 | ## Cache backend type
286 |
287 | To ensure fast builds, BuildKit automatically caches the build result in its own internal cache. Additionally, BuildKit also supports exporting build cache to an external location, making it possible to import in future builds.
288 |
289 | Ref: https://docs.docker.com/build/cache/backends/
290 |
291 | You can set the `cache-type` to configure the backend to use.
292 |
293 | ```yaml
294 | - uses: int128/docker-build-cache-config-action@v1
295 | id: cache
296 | with:
297 | image: ghcr.io/${{ github.repository }}/cache
298 | cache-type: inline # cache backend storage
299 | ```
300 |
301 | Will generate the following outputs
302 |
303 | ```yaml
304 | cache-from: |
305 | type=inline,ref=REGISTRY/REPOSITORY:pr-1
306 | type=inline,ref=REGISTRY/REPOSITORY:main
307 | cache-to: type=inline,ref=REGISTRY/REPOSITORY:pr-1,mode=max
308 | ```
309 |
310 | ### Use GitHub Actions cache backend
311 |
312 | > The GitHub Actions cache utilizes the GitHub-provided Action's cache or other cache services supporting the GitHub Actions cache protocol. This is the recommended cache to use inside your GitHub Actions workflows, as long as your use case falls within the size and usage limits set by GitHub.
313 | > ⚠ This is an experimental feature. The interface and behavior are unstable and may change in future releases.
314 |
315 | Ref: https://docs.docker.com/build/cache/backends/gha/
316 |
317 | You can set the cache type to `gha` to use the GitHub Actions cache.
318 |
319 | ```yaml
320 | - uses: docker/metadata-action@v3
321 | id: metadata
322 | with:
323 | images: ghcr.io/${{ github.repository }}
324 | - uses: int128/docker-build-cache-config-action@v1
325 | id: cache
326 | with:
327 | image: ghcr.io/${{ github.repository }}/cache
328 | cache-type: gha
329 | - uses: docker/build-push-action@v2
330 | id: build
331 | with:
332 | push: true
333 | tags: ${{ steps.metadata.outputs.tags }}
334 | labels: ${{ steps.metadata.outputs.labels }}
335 | cache-from: ${{ steps.cache.outputs.cache-from }}
336 | cache-to: ${{ steps.cache.outputs.cache-to }}
337 | ```
338 |
--------------------------------------------------------------------------------
/action.yaml:
--------------------------------------------------------------------------------
1 | name: docker-build-cache-config
2 | description: Effective cache with docker/build-push-action for pull request based development flow
3 |
4 | inputs:
5 | image:
6 | description: Image repository to import/export cache
7 | required: true
8 | cache-type:
9 | description: Type of cache backend (for source and destination). Can be registry, local, inline, gha and s3.
10 | required: true
11 | default: 'registry'
12 | flavor:
13 | description: Flavor (multiline string)
14 | required: false
15 | extra-cache-from:
16 | description: Extra flag to cache-from
17 | required: false
18 | extra-cache-to:
19 | description: Extra flag to cache-to
20 | required: false
21 | pull-request-cache:
22 | description: Import and export a pull request cache
23 | required: false
24 | default: 'false'
25 | cache-key:
26 | description: Custom cache key (experimental)
27 | required: false
28 | cache-key-fallback:
29 | description: Custom cache key to fallback (experimental)
30 | required: false
31 | bake-target:
32 | description: Bake target name
33 | required: false
34 | default: docker-build-cache-config-action
35 | token:
36 | description: GitHub token
37 | required: false
38 | default: ${{ github.token }}
39 |
40 | outputs:
41 | cache-from:
42 | description: cache-from parameter for docker/build-push-action
43 | cache-to:
44 | description: cache-to parameter for docker/build-push-action
45 | bake-file:
46 | description: Bake definition file
47 |
48 | runs:
49 | using: 'node20'
50 | main: 'dist/index.js'
51 |
--------------------------------------------------------------------------------
/effective-build-cache-diagram.drawio.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/eslint.config.js:
--------------------------------------------------------------------------------
1 | // @ts-check
2 |
3 | import eslint from '@eslint/js'
4 | import vitest from '@vitest/eslint-plugin'
5 | import tseslint from 'typescript-eslint'
6 |
7 | export default tseslint.config(
8 | {
9 | ignores: ['.git/', 'node_modules/', 'dist/', '*.config.*'],
10 | },
11 | eslint.configs.recommended,
12 | ...tseslint.configs.recommendedTypeChecked,
13 | vitest.configs.recommended,
14 | {
15 | languageOptions: {
16 | parserOptions: {
17 | project: true,
18 | },
19 | },
20 | },
21 | )
22 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "private": true,
3 | "scripts": {
4 | "format": "prettier --write **/*.ts",
5 | "lint": "eslint .",
6 | "build": "ncc build --source-map --license licenses.txt src/main.ts",
7 | "test": "vitest"
8 | },
9 | "type": "module",
10 | "dependencies": {
11 | "@actions/core": "1.11.1",
12 | "@actions/github": "6.0.1"
13 | },
14 | "devDependencies": {
15 | "@eslint/js": "9.28.0",
16 | "@octokit/webhooks-types": "7.6.1",
17 | "@tsconfig/node20": "20.1.5",
18 | "@types/node": "20.19.0",
19 | "@vercel/ncc": "0.38.3",
20 | "@vitest/eslint-plugin": "1.2.1",
21 | "eslint": "9.28.0",
22 | "msw": "2.10.1",
23 | "pnpm": "10.11.1",
24 | "prettier": "3.5.3",
25 | "typescript": "5.8.3",
26 | "typescript-eslint": "8.33.1",
27 | "vitest": "3.2.2"
28 | },
29 | "packageManager": "pnpm@10.11.1"
30 | }
31 |
--------------------------------------------------------------------------------
/pnpm-lock.yaml:
--------------------------------------------------------------------------------
1 | lockfileVersion: '9.0'
2 |
3 | settings:
4 | autoInstallPeers: true
5 | excludeLinksFromLockfile: false
6 |
7 | importers:
8 |
9 | .:
10 | dependencies:
11 | '@actions/core':
12 | specifier: 1.11.1
13 | version: 1.11.1
14 | '@actions/github':
15 | specifier: 6.0.1
16 | version: 6.0.1
17 | devDependencies:
18 | '@eslint/js':
19 | specifier: 9.28.0
20 | version: 9.28.0
21 | '@octokit/webhooks-types':
22 | specifier: 7.6.1
23 | version: 7.6.1
24 | '@tsconfig/node20':
25 | specifier: 20.1.5
26 | version: 20.1.5
27 | '@types/node':
28 | specifier: 20.19.0
29 | version: 20.19.0
30 | '@vercel/ncc':
31 | specifier: 0.38.3
32 | version: 0.38.3
33 | '@vitest/eslint-plugin':
34 | specifier: 1.2.1
35 | version: 1.2.1(eslint@9.28.0)(typescript@5.8.3)(vitest@3.2.2(@types/node@20.19.0)(msw@2.10.1(@types/node@20.19.0)(typescript@5.8.3)))
36 | eslint:
37 | specifier: 9.28.0
38 | version: 9.28.0
39 | msw:
40 | specifier: 2.10.1
41 | version: 2.10.1(@types/node@20.19.0)(typescript@5.8.3)
42 | pnpm:
43 | specifier: 10.11.1
44 | version: 10.11.1
45 | prettier:
46 | specifier: 3.5.3
47 | version: 3.5.3
48 | typescript:
49 | specifier: 5.8.3
50 | version: 5.8.3
51 | typescript-eslint:
52 | specifier: 8.33.1
53 | version: 8.33.1(eslint@9.28.0)(typescript@5.8.3)
54 | vitest:
55 | specifier: 3.2.2
56 | version: 3.2.2(@types/node@20.19.0)(msw@2.10.1(@types/node@20.19.0)(typescript@5.8.3))
57 |
58 | packages:
59 |
60 | '@aashutoshrathi/word-wrap@1.2.6':
61 | resolution: {integrity: sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==}
62 | engines: {node: '>=0.10.0'}
63 |
64 | '@actions/core@1.11.1':
65 | resolution: {integrity: sha512-hXJCSrkwfA46Vd9Z3q4cpEpHB1rL5NG04+/rbqW9d3+CSvtB1tYe8UTpAlixa1vj0m/ULglfEK2UKxMGxCxv5A==}
66 |
67 | '@actions/exec@1.1.1':
68 | resolution: {integrity: sha512-+sCcHHbVdk93a0XT19ECtO/gIXoxvdsgQLzb2fE2/5sIZmWQuluYyjPQtrtTHdU1YzTZ7bAPN4sITq2xi1679w==}
69 |
70 | '@actions/github@6.0.1':
71 | resolution: {integrity: sha512-xbZVcaqD4XnQAe35qSQqskb3SqIAfRyLBrHMd/8TuL7hJSz2QtbDwnNM8zWx4zO5l2fnGtseNE3MbEvD7BxVMw==}
72 |
73 | '@actions/http-client@2.2.0':
74 | resolution: {integrity: sha512-q+epW0trjVUUHboliPb4UF9g2msf+w61b32tAkFEwL/IwP0DQWgbCMM0Hbe3e3WXSKz5VcUXbzJQgy8Hkra/Lg==}
75 |
76 | '@actions/io@1.1.3':
77 | resolution: {integrity: sha512-wi9JjgKLYS7U/z8PPbco+PvTb/nRWjeoFlJ1Qer83k/3C5PHQi28hiVdeE2kHXmIL99mQFawx8qt/JPjZilJ8Q==}
78 |
79 | '@bundled-es-modules/cookie@2.0.1':
80 | resolution: {integrity: sha512-8o+5fRPLNbjbdGRRmJj3h6Hh1AQJf2dk3qQ/5ZFb+PXkRNiSoMGGUKlsgLfrxneb72axVJyIYji64E2+nNfYyw==}
81 |
82 | '@bundled-es-modules/statuses@1.0.1':
83 | resolution: {integrity: sha512-yn7BklA5acgcBr+7w064fGV+SGIFySjCKpqjcWgBAIfrAkY+4GQTJJHQMeT3V/sgz23VTEVV8TtOmkvJAhFVfg==}
84 |
85 | '@bundled-es-modules/tough-cookie@0.1.6':
86 | resolution: {integrity: sha512-dvMHbL464C0zI+Yqxbz6kZ5TOEp7GLW+pry/RWndAR8MJQAXZ2rPmIs8tziTZjeIyhSNZgZbCePtfSbdWqStJw==}
87 |
88 | '@esbuild/aix-ppc64@0.25.5':
89 | resolution: {integrity: sha512-9o3TMmpmftaCMepOdA5k/yDw8SfInyzWWTjYTFCX3kPSDJMROQTb8jg+h9Cnwnmm1vOzvxN7gIfB5V2ewpjtGA==}
90 | engines: {node: '>=18'}
91 | cpu: [ppc64]
92 | os: [aix]
93 |
94 | '@esbuild/android-arm64@0.25.5':
95 | resolution: {integrity: sha512-VGzGhj4lJO+TVGV1v8ntCZWJktV7SGCs3Pn1GRWI1SBFtRALoomm8k5E9Pmwg3HOAal2VDc2F9+PM/rEY6oIDg==}
96 | engines: {node: '>=18'}
97 | cpu: [arm64]
98 | os: [android]
99 |
100 | '@esbuild/android-arm@0.25.5':
101 | resolution: {integrity: sha512-AdJKSPeEHgi7/ZhuIPtcQKr5RQdo6OO2IL87JkianiMYMPbCtot9fxPbrMiBADOWWm3T2si9stAiVsGbTQFkbA==}
102 | engines: {node: '>=18'}
103 | cpu: [arm]
104 | os: [android]
105 |
106 | '@esbuild/android-x64@0.25.5':
107 | resolution: {integrity: sha512-D2GyJT1kjvO//drbRT3Hib9XPwQeWd9vZoBJn+bu/lVsOZ13cqNdDeqIF/xQ5/VmWvMduP6AmXvylO/PIc2isw==}
108 | engines: {node: '>=18'}
109 | cpu: [x64]
110 | os: [android]
111 |
112 | '@esbuild/darwin-arm64@0.25.5':
113 | resolution: {integrity: sha512-GtaBgammVvdF7aPIgH2jxMDdivezgFu6iKpmT+48+F8Hhg5J/sfnDieg0aeG/jfSvkYQU2/pceFPDKlqZzwnfQ==}
114 | engines: {node: '>=18'}
115 | cpu: [arm64]
116 | os: [darwin]
117 |
118 | '@esbuild/darwin-x64@0.25.5':
119 | resolution: {integrity: sha512-1iT4FVL0dJ76/q1wd7XDsXrSW+oLoquptvh4CLR4kITDtqi2e/xwXwdCVH8hVHU43wgJdsq7Gxuzcs6Iq/7bxQ==}
120 | engines: {node: '>=18'}
121 | cpu: [x64]
122 | os: [darwin]
123 |
124 | '@esbuild/freebsd-arm64@0.25.5':
125 | resolution: {integrity: sha512-nk4tGP3JThz4La38Uy/gzyXtpkPW8zSAmoUhK9xKKXdBCzKODMc2adkB2+8om9BDYugz+uGV7sLmpTYzvmz6Sw==}
126 | engines: {node: '>=18'}
127 | cpu: [arm64]
128 | os: [freebsd]
129 |
130 | '@esbuild/freebsd-x64@0.25.5':
131 | resolution: {integrity: sha512-PrikaNjiXdR2laW6OIjlbeuCPrPaAl0IwPIaRv+SMV8CiM8i2LqVUHFC1+8eORgWyY7yhQY+2U2fA55mBzReaw==}
132 | engines: {node: '>=18'}
133 | cpu: [x64]
134 | os: [freebsd]
135 |
136 | '@esbuild/linux-arm64@0.25.5':
137 | resolution: {integrity: sha512-Z9kfb1v6ZlGbWj8EJk9T6czVEjjq2ntSYLY2cw6pAZl4oKtfgQuS4HOq41M/BcoLPzrUbNd+R4BXFyH//nHxVg==}
138 | engines: {node: '>=18'}
139 | cpu: [arm64]
140 | os: [linux]
141 |
142 | '@esbuild/linux-arm@0.25.5':
143 | resolution: {integrity: sha512-cPzojwW2okgh7ZlRpcBEtsX7WBuqbLrNXqLU89GxWbNt6uIg78ET82qifUy3W6OVww6ZWobWub5oqZOVtwolfw==}
144 | engines: {node: '>=18'}
145 | cpu: [arm]
146 | os: [linux]
147 |
148 | '@esbuild/linux-ia32@0.25.5':
149 | resolution: {integrity: sha512-sQ7l00M8bSv36GLV95BVAdhJ2QsIbCuCjh/uYrWiMQSUuV+LpXwIqhgJDcvMTj+VsQmqAHL2yYaasENvJ7CDKA==}
150 | engines: {node: '>=18'}
151 | cpu: [ia32]
152 | os: [linux]
153 |
154 | '@esbuild/linux-loong64@0.25.5':
155 | resolution: {integrity: sha512-0ur7ae16hDUC4OL5iEnDb0tZHDxYmuQyhKhsPBV8f99f6Z9KQM02g33f93rNH5A30agMS46u2HP6qTdEt6Q1kg==}
156 | engines: {node: '>=18'}
157 | cpu: [loong64]
158 | os: [linux]
159 |
160 | '@esbuild/linux-mips64el@0.25.5':
161 | resolution: {integrity: sha512-kB/66P1OsHO5zLz0i6X0RxlQ+3cu0mkxS3TKFvkb5lin6uwZ/ttOkP3Z8lfR9mJOBk14ZwZ9182SIIWFGNmqmg==}
162 | engines: {node: '>=18'}
163 | cpu: [mips64el]
164 | os: [linux]
165 |
166 | '@esbuild/linux-ppc64@0.25.5':
167 | resolution: {integrity: sha512-UZCmJ7r9X2fe2D6jBmkLBMQetXPXIsZjQJCjgwpVDz+YMcS6oFR27alkgGv3Oqkv07bxdvw7fyB71/olceJhkQ==}
168 | engines: {node: '>=18'}
169 | cpu: [ppc64]
170 | os: [linux]
171 |
172 | '@esbuild/linux-riscv64@0.25.5':
173 | resolution: {integrity: sha512-kTxwu4mLyeOlsVIFPfQo+fQJAV9mh24xL+y+Bm6ej067sYANjyEw1dNHmvoqxJUCMnkBdKpvOn0Ahql6+4VyeA==}
174 | engines: {node: '>=18'}
175 | cpu: [riscv64]
176 | os: [linux]
177 |
178 | '@esbuild/linux-s390x@0.25.5':
179 | resolution: {integrity: sha512-K2dSKTKfmdh78uJ3NcWFiqyRrimfdinS5ErLSn3vluHNeHVnBAFWC8a4X5N+7FgVE1EjXS1QDZbpqZBjfrqMTQ==}
180 | engines: {node: '>=18'}
181 | cpu: [s390x]
182 | os: [linux]
183 |
184 | '@esbuild/linux-x64@0.25.5':
185 | resolution: {integrity: sha512-uhj8N2obKTE6pSZ+aMUbqq+1nXxNjZIIjCjGLfsWvVpy7gKCOL6rsY1MhRh9zLtUtAI7vpgLMK6DxjO8Qm9lJw==}
186 | engines: {node: '>=18'}
187 | cpu: [x64]
188 | os: [linux]
189 |
190 | '@esbuild/netbsd-arm64@0.25.5':
191 | resolution: {integrity: sha512-pwHtMP9viAy1oHPvgxtOv+OkduK5ugofNTVDilIzBLpoWAM16r7b/mxBvfpuQDpRQFMfuVr5aLcn4yveGvBZvw==}
192 | engines: {node: '>=18'}
193 | cpu: [arm64]
194 | os: [netbsd]
195 |
196 | '@esbuild/netbsd-x64@0.25.5':
197 | resolution: {integrity: sha512-WOb5fKrvVTRMfWFNCroYWWklbnXH0Q5rZppjq0vQIdlsQKuw6mdSihwSo4RV/YdQ5UCKKvBy7/0ZZYLBZKIbwQ==}
198 | engines: {node: '>=18'}
199 | cpu: [x64]
200 | os: [netbsd]
201 |
202 | '@esbuild/openbsd-arm64@0.25.5':
203 | resolution: {integrity: sha512-7A208+uQKgTxHd0G0uqZO8UjK2R0DDb4fDmERtARjSHWxqMTye4Erz4zZafx7Di9Cv+lNHYuncAkiGFySoD+Mw==}
204 | engines: {node: '>=18'}
205 | cpu: [arm64]
206 | os: [openbsd]
207 |
208 | '@esbuild/openbsd-x64@0.25.5':
209 | resolution: {integrity: sha512-G4hE405ErTWraiZ8UiSoesH8DaCsMm0Cay4fsFWOOUcz8b8rC6uCvnagr+gnioEjWn0wC+o1/TAHt+It+MpIMg==}
210 | engines: {node: '>=18'}
211 | cpu: [x64]
212 | os: [openbsd]
213 |
214 | '@esbuild/sunos-x64@0.25.5':
215 | resolution: {integrity: sha512-l+azKShMy7FxzY0Rj4RCt5VD/q8mG/e+mDivgspo+yL8zW7qEwctQ6YqKX34DTEleFAvCIUviCFX1SDZRSyMQA==}
216 | engines: {node: '>=18'}
217 | cpu: [x64]
218 | os: [sunos]
219 |
220 | '@esbuild/win32-arm64@0.25.5':
221 | resolution: {integrity: sha512-O2S7SNZzdcFG7eFKgvwUEZ2VG9D/sn/eIiz8XRZ1Q/DO5a3s76Xv0mdBzVM5j5R639lXQmPmSo0iRpHqUUrsxw==}
222 | engines: {node: '>=18'}
223 | cpu: [arm64]
224 | os: [win32]
225 |
226 | '@esbuild/win32-ia32@0.25.5':
227 | resolution: {integrity: sha512-onOJ02pqs9h1iMJ1PQphR+VZv8qBMQ77Klcsqv9CNW2w6yLqoURLcgERAIurY6QE63bbLuqgP9ATqajFLK5AMQ==}
228 | engines: {node: '>=18'}
229 | cpu: [ia32]
230 | os: [win32]
231 |
232 | '@esbuild/win32-x64@0.25.5':
233 | resolution: {integrity: sha512-TXv6YnJ8ZMVdX+SXWVBo/0p8LTcrUYngpWjvm91TMjjBQii7Oz11Lw5lbDV5Y0TzuhSJHwiH4hEtC1I42mMS0g==}
234 | engines: {node: '>=18'}
235 | cpu: [x64]
236 | os: [win32]
237 |
238 | '@eslint-community/eslint-utils@4.7.0':
239 | resolution: {integrity: sha512-dyybb3AcajC7uha6CvhdVRJqaKyn7w2YKqKyAN37NKYgZT36w+iRb0Dymmc5qEJ549c/S31cMMSFd75bteCpCw==}
240 | engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
241 | peerDependencies:
242 | eslint: ^6.0.0 || ^7.0.0 || >=8.0.0
243 |
244 | '@eslint-community/regexpp@4.12.1':
245 | resolution: {integrity: sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==}
246 | engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0}
247 |
248 | '@eslint/config-array@0.20.0':
249 | resolution: {integrity: sha512-fxlS1kkIjx8+vy2SjuCB94q3htSNrufYTXubwiBFeaQHbH6Ipi43gFJq2zCMt6PHhImH3Xmr0NksKDvchWlpQQ==}
250 | engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
251 |
252 | '@eslint/config-helpers@0.2.1':
253 | resolution: {integrity: sha512-RI17tsD2frtDu/3dmI7QRrD4bedNKPM08ziRYaC5AhkGrzIAJelm9kJU1TznK+apx6V+cqRz8tfpEeG3oIyjxw==}
254 | engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
255 |
256 | '@eslint/core@0.14.0':
257 | resolution: {integrity: sha512-qIbV0/JZr7iSDjqAc60IqbLdsj9GDt16xQtWD+B78d/HAlvysGdZZ6rpJHGAc2T0FQx1X6thsSPdnoiGKdNtdg==}
258 | engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
259 |
260 | '@eslint/eslintrc@3.3.1':
261 | resolution: {integrity: sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==}
262 | engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
263 |
264 | '@eslint/js@9.28.0':
265 | resolution: {integrity: sha512-fnqSjGWd/CoIp4EXIxWVK/sHA6DOHN4+8Ix2cX5ycOY7LG0UY8nHCU5pIp2eaE1Mc7Qd8kHspYNzYXT2ojPLzg==}
266 | engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
267 |
268 | '@eslint/object-schema@2.1.6':
269 | resolution: {integrity: sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==}
270 | engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
271 |
272 | '@eslint/plugin-kit@0.3.1':
273 | resolution: {integrity: sha512-0J+zgWxHN+xXONWIyPWKFMgVuJoZuGiIFu8yxk7RJjxkzpGmyja5wRFqZIVtjDVOQpV+Rw0iOAjYPE2eQyjr0w==}
274 | engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
275 |
276 | '@fastify/busboy@2.1.1':
277 | resolution: {integrity: sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==}
278 | engines: {node: '>=14'}
279 |
280 | '@humanfs/core@0.19.1':
281 | resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==}
282 | engines: {node: '>=18.18.0'}
283 |
284 | '@humanfs/node@0.16.6':
285 | resolution: {integrity: sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==}
286 | engines: {node: '>=18.18.0'}
287 |
288 | '@humanwhocodes/module-importer@1.0.1':
289 | resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==}
290 | engines: {node: '>=12.22'}
291 |
292 | '@humanwhocodes/retry@0.3.1':
293 | resolution: {integrity: sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==}
294 | engines: {node: '>=18.18'}
295 |
296 | '@humanwhocodes/retry@0.4.2':
297 | resolution: {integrity: sha512-xeO57FpIu4p1Ri3Jq/EXq4ClRm86dVF2z/+kvFnyqVYRavTZmaFaUBbWCOuuTh0o/g7DSsk6kc2vrS4Vl5oPOQ==}
298 | engines: {node: '>=18.18'}
299 |
300 | '@inquirer/confirm@5.0.1':
301 | resolution: {integrity: sha512-6ycMm7k7NUApiMGfVc32yIPp28iPKxhGRMqoNDiUjq2RyTAkbs5Fx0TdzBqhabcKvniDdAAvHCmsRjnNfTsogw==}
302 | engines: {node: '>=18'}
303 | peerDependencies:
304 | '@types/node': '>=18'
305 |
306 | '@inquirer/core@10.0.1':
307 | resolution: {integrity: sha512-KKTgjViBQUi3AAssqjUFMnMO3CM3qwCHvePV9EW+zTKGKafFGFF01sc1yOIYjLJ7QU52G/FbzKc+c01WLzXmVQ==}
308 | engines: {node: '>=18'}
309 |
310 | '@inquirer/figures@1.0.7':
311 | resolution: {integrity: sha512-m+Trk77mp54Zma6xLkLuY+mvanPxlE4A7yNKs2HBiyZ4UkVs28Mv5c/pgWrHeInx+USHeX/WEPzjrWrcJiQgjw==}
312 | engines: {node: '>=18'}
313 |
314 | '@inquirer/type@3.0.0':
315 | resolution: {integrity: sha512-YYykfbw/lefC7yKj7nanzQXILM7r3suIvyFlCcMskc99axmsSewXWkAfXKwMbgxL76iAFVmRwmYdwNZNc8gjog==}
316 | engines: {node: '>=18'}
317 | peerDependencies:
318 | '@types/node': '>=18'
319 |
320 | '@jridgewell/sourcemap-codec@1.5.0':
321 | resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==}
322 |
323 | '@mswjs/interceptors@0.39.2':
324 | resolution: {integrity: sha512-RuzCup9Ct91Y7V79xwCb146RaBRHZ7NBbrIUySumd1rpKqHL5OonaqrGIbug5hNwP/fRyxFMA6ISgw4FTtYFYg==}
325 | engines: {node: '>=18'}
326 |
327 | '@nodelib/fs.scandir@2.1.5':
328 | resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==}
329 | engines: {node: '>= 8'}
330 |
331 | '@nodelib/fs.stat@2.0.5':
332 | resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==}
333 | engines: {node: '>= 8'}
334 |
335 | '@nodelib/fs.walk@1.2.8':
336 | resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==}
337 | engines: {node: '>= 8'}
338 |
339 | '@octokit/auth-token@4.0.0':
340 | resolution: {integrity: sha512-tY/msAuJo6ARbK6SPIxZrPBms3xPbfwBrulZe0Wtr/DIY9lje2HeV1uoebShn6mx7SjCHif6EjMvoREj+gZ+SA==}
341 | engines: {node: '>= 18'}
342 |
343 | '@octokit/core@5.1.0':
344 | resolution: {integrity: sha512-BDa2VAMLSh3otEiaMJ/3Y36GU4qf6GI+VivQ/P41NC6GHcdxpKlqV0ikSZ5gdQsmS3ojXeRx5vasgNTinF0Q4g==}
345 | engines: {node: '>= 18'}
346 |
347 | '@octokit/endpoint@9.0.6':
348 | resolution: {integrity: sha512-H1fNTMA57HbkFESSt3Y9+FBICv+0jFceJFPWDePYlR/iMGrwM5ph+Dd4XRQs+8X+PUFURLQgX9ChPfhJ/1uNQw==}
349 | engines: {node: '>= 18'}
350 |
351 | '@octokit/graphql@7.0.2':
352 | resolution: {integrity: sha512-OJ2iGMtj5Tg3s6RaXH22cJcxXRi7Y3EBqbHTBRq+PQAqfaS8f/236fUrWhfSn8P4jovyzqucxme7/vWSSZBX2Q==}
353 | engines: {node: '>= 18'}
354 |
355 | '@octokit/openapi-types@20.0.0':
356 | resolution: {integrity: sha512-EtqRBEjp1dL/15V7WiX5LJMIxxkdiGJnabzYx5Apx4FkQIFgAfKumXeYAqqJCj1s+BMX4cPFIFC4OLCR6stlnA==}
357 |
358 | '@octokit/openapi-types@24.2.0':
359 | resolution: {integrity: sha512-9sIH3nSUttelJSXUrmGzl7QUBFul0/mB8HRYl3fOlgHbIWG+WnYDXU3v/2zMtAvuzZ/ed00Ei6on975FhBfzrg==}
360 |
361 | '@octokit/plugin-paginate-rest@9.2.2':
362 | resolution: {integrity: sha512-u3KYkGF7GcZnSD/3UP0S7K5XUFT2FkOQdcfXZGZQPGv3lm4F2Xbf71lvjldr8c1H3nNbF+33cLEkWYbokGWqiQ==}
363 | engines: {node: '>= 18'}
364 | peerDependencies:
365 | '@octokit/core': '5'
366 |
367 | '@octokit/plugin-rest-endpoint-methods@10.4.1':
368 | resolution: {integrity: sha512-xV1b+ceKV9KytQe3zCVqjg+8GTGfDYwaT1ATU5isiUyVtlVAO3HNdzpS4sr4GBx4hxQ46s7ITtZrAsxG22+rVg==}
369 | engines: {node: '>= 18'}
370 | peerDependencies:
371 | '@octokit/core': '5'
372 |
373 | '@octokit/request-error@5.1.1':
374 | resolution: {integrity: sha512-v9iyEQJH6ZntoENr9/yXxjuezh4My67CBSu9r6Ve/05Iu5gNgnisNWOsoJHTP6k0Rr0+HQIpnH+kyammu90q/g==}
375 | engines: {node: '>= 18'}
376 |
377 | '@octokit/request@8.4.1':
378 | resolution: {integrity: sha512-qnB2+SY3hkCmBxZsR/MPCybNmbJe4KAlfWErXq+rBKkQJlbjdJeS85VI9r8UqeLYLvnAenU8Q1okM/0MBsAGXw==}
379 | engines: {node: '>= 18'}
380 |
381 | '@octokit/types@12.6.0':
382 | resolution: {integrity: sha512-1rhSOfRa6H9w4YwK0yrf5faDaDTb+yLyBUKOCV4xtCDB5VmIPqd/v9yr9o6SAzOAlRxMiRiCic6JVM1/kunVkw==}
383 |
384 | '@octokit/types@13.10.0':
385 | resolution: {integrity: sha512-ifLaO34EbbPj0Xgro4G5lP5asESjwHracYJvVaPIyXMuiuXLlhic3S47cBdTb+jfODkTE5YtGCLt3Ay3+J97sA==}
386 |
387 | '@octokit/webhooks-types@7.6.1':
388 | resolution: {integrity: sha512-S8u2cJzklBC0FgTwWVLaM8tMrDuDMVE4xiTK4EYXM9GntyvrdbSoxqDQa+Fh57CCNApyIpyeqPhhFEmHPfrXgw==}
389 |
390 | '@open-draft/deferred-promise@2.2.0':
391 | resolution: {integrity: sha512-CecwLWx3rhxVQF6V4bAgPS5t+So2sTbPgAzafKkVizyi7tlwpcFpdFqq+wqF2OwNBmqFuu6tOyouTuxgpMfzmA==}
392 |
393 | '@open-draft/logger@0.3.0':
394 | resolution: {integrity: sha512-X2g45fzhxH238HKO4xbSr7+wBS8Fvw6ixhTDuvLd5mqh6bJJCFAPwU9mPDxbcrRtfxv4u5IHCEH77BmxvXmmxQ==}
395 |
396 | '@open-draft/until@2.1.0':
397 | resolution: {integrity: sha512-U69T3ItWHvLwGg5eJ0n3I62nWuE6ilHlmz7zM0npLBRvPRd7e6NYmg54vvRtP5mZG7kZqZCFVdsTWo7BPtBujg==}
398 |
399 | '@rollup/rollup-android-arm-eabi@4.42.0':
400 | resolution: {integrity: sha512-gldmAyS9hpj+H6LpRNlcjQWbuKUtb94lodB9uCz71Jm+7BxK1VIOo7y62tZZwxhA7j1ylv/yQz080L5WkS+LoQ==}
401 | cpu: [arm]
402 | os: [android]
403 |
404 | '@rollup/rollup-android-arm64@4.42.0':
405 | resolution: {integrity: sha512-bpRipfTgmGFdCZDFLRvIkSNO1/3RGS74aWkJJTFJBH7h3MRV4UijkaEUeOMbi9wxtxYmtAbVcnMtHTPBhLEkaw==}
406 | cpu: [arm64]
407 | os: [android]
408 |
409 | '@rollup/rollup-darwin-arm64@4.42.0':
410 | resolution: {integrity: sha512-JxHtA081izPBVCHLKnl6GEA0w3920mlJPLh89NojpU2GsBSB6ypu4erFg/Wx1qbpUbepn0jY4dVWMGZM8gplgA==}
411 | cpu: [arm64]
412 | os: [darwin]
413 |
414 | '@rollup/rollup-darwin-x64@4.42.0':
415 | resolution: {integrity: sha512-rv5UZaWVIJTDMyQ3dCEK+m0SAn6G7H3PRc2AZmExvbDvtaDc+qXkei0knQWcI3+c9tEs7iL/4I4pTQoPbNL2SA==}
416 | cpu: [x64]
417 | os: [darwin]
418 |
419 | '@rollup/rollup-freebsd-arm64@4.42.0':
420 | resolution: {integrity: sha512-fJcN4uSGPWdpVmvLuMtALUFwCHgb2XiQjuECkHT3lWLZhSQ3MBQ9pq+WoWeJq2PrNxr9rPM1Qx+IjyGj8/c6zQ==}
421 | cpu: [arm64]
422 | os: [freebsd]
423 |
424 | '@rollup/rollup-freebsd-x64@4.42.0':
425 | resolution: {integrity: sha512-CziHfyzpp8hJpCVE/ZdTizw58gr+m7Y2Xq5VOuCSrZR++th2xWAz4Nqk52MoIIrV3JHtVBhbBsJcAxs6NammOQ==}
426 | cpu: [x64]
427 | os: [freebsd]
428 |
429 | '@rollup/rollup-linux-arm-gnueabihf@4.42.0':
430 | resolution: {integrity: sha512-UsQD5fyLWm2Fe5CDM7VPYAo+UC7+2Px4Y+N3AcPh/LdZu23YcuGPegQly++XEVaC8XUTFVPscl5y5Cl1twEI4A==}
431 | cpu: [arm]
432 | os: [linux]
433 |
434 | '@rollup/rollup-linux-arm-musleabihf@4.42.0':
435 | resolution: {integrity: sha512-/i8NIrlgc/+4n1lnoWl1zgH7Uo0XK5xK3EDqVTf38KvyYgCU/Rm04+o1VvvzJZnVS5/cWSd07owkzcVasgfIkQ==}
436 | cpu: [arm]
437 | os: [linux]
438 |
439 | '@rollup/rollup-linux-arm64-gnu@4.42.0':
440 | resolution: {integrity: sha512-eoujJFOvoIBjZEi9hJnXAbWg+Vo1Ov8n/0IKZZcPZ7JhBzxh2A+2NFyeMZIRkY9iwBvSjloKgcvnjTbGKHE44Q==}
441 | cpu: [arm64]
442 | os: [linux]
443 |
444 | '@rollup/rollup-linux-arm64-musl@4.42.0':
445 | resolution: {integrity: sha512-/3NrcOWFSR7RQUQIuZQChLND36aTU9IYE4j+TB40VU78S+RA0IiqHR30oSh6P1S9f9/wVOenHQnacs/Byb824g==}
446 | cpu: [arm64]
447 | os: [linux]
448 |
449 | '@rollup/rollup-linux-loongarch64-gnu@4.42.0':
450 | resolution: {integrity: sha512-O8AplvIeavK5ABmZlKBq9/STdZlnQo7Sle0LLhVA7QT+CiGpNVe197/t8Aph9bhJqbDVGCHpY2i7QyfEDDStDg==}
451 | cpu: [loong64]
452 | os: [linux]
453 |
454 | '@rollup/rollup-linux-powerpc64le-gnu@4.42.0':
455 | resolution: {integrity: sha512-6Qb66tbKVN7VyQrekhEzbHRxXXFFD8QKiFAwX5v9Xt6FiJ3BnCVBuyBxa2fkFGqxOCSGGYNejxd8ht+q5SnmtA==}
456 | cpu: [ppc64]
457 | os: [linux]
458 |
459 | '@rollup/rollup-linux-riscv64-gnu@4.42.0':
460 | resolution: {integrity: sha512-KQETDSEBamQFvg/d8jajtRwLNBlGc3aKpaGiP/LvEbnmVUKlFta1vqJqTrvPtsYsfbE/DLg5CC9zyXRX3fnBiA==}
461 | cpu: [riscv64]
462 | os: [linux]
463 |
464 | '@rollup/rollup-linux-riscv64-musl@4.42.0':
465 | resolution: {integrity: sha512-qMvnyjcU37sCo/tuC+JqeDKSuukGAd+pVlRl/oyDbkvPJ3awk6G6ua7tyum02O3lI+fio+eM5wsVd66X0jQtxw==}
466 | cpu: [riscv64]
467 | os: [linux]
468 |
469 | '@rollup/rollup-linux-s390x-gnu@4.42.0':
470 | resolution: {integrity: sha512-I2Y1ZUgTgU2RLddUHXTIgyrdOwljjkmcZ/VilvaEumtS3Fkuhbw4p4hgHc39Ypwvo2o7sBFNl2MquNvGCa55Iw==}
471 | cpu: [s390x]
472 | os: [linux]
473 |
474 | '@rollup/rollup-linux-x64-gnu@4.42.0':
475 | resolution: {integrity: sha512-Gfm6cV6mj3hCUY8TqWa63DB8Mx3NADoFwiJrMpoZ1uESbK8FQV3LXkhfry+8bOniq9pqY1OdsjFWNsSbfjPugw==}
476 | cpu: [x64]
477 | os: [linux]
478 |
479 | '@rollup/rollup-linux-x64-musl@4.42.0':
480 | resolution: {integrity: sha512-g86PF8YZ9GRqkdi0VoGlcDUb4rYtQKyTD1IVtxxN4Hpe7YqLBShA7oHMKU6oKTCi3uxwW4VkIGnOaH/El8de3w==}
481 | cpu: [x64]
482 | os: [linux]
483 |
484 | '@rollup/rollup-win32-arm64-msvc@4.42.0':
485 | resolution: {integrity: sha512-+axkdyDGSp6hjyzQ5m1pgcvQScfHnMCcsXkx8pTgy/6qBmWVhtRVlgxjWwDp67wEXXUr0x+vD6tp5W4x6V7u1A==}
486 | cpu: [arm64]
487 | os: [win32]
488 |
489 | '@rollup/rollup-win32-ia32-msvc@4.42.0':
490 | resolution: {integrity: sha512-F+5J9pelstXKwRSDq92J0TEBXn2nfUrQGg+HK1+Tk7VOL09e0gBqUHugZv7SW4MGrYj41oNCUe3IKCDGVlis2g==}
491 | cpu: [ia32]
492 | os: [win32]
493 |
494 | '@rollup/rollup-win32-x64-msvc@4.42.0':
495 | resolution: {integrity: sha512-LpHiJRwkaVz/LqjHjK8LCi8osq7elmpwujwbXKNW88bM8eeGxavJIKKjkjpMHAh/2xfnrt1ZSnhTv41WYUHYmA==}
496 | cpu: [x64]
497 | os: [win32]
498 |
499 | '@tsconfig/node20@20.1.5':
500 | resolution: {integrity: sha512-Vm8e3WxDTqMGPU4GATF9keQAIy1Drd7bPwlgzKJnZtoOsTm1tduUTbDjg0W5qERvGuxPI2h9RbMufH0YdfBylA==}
501 |
502 | '@types/chai@5.2.2':
503 | resolution: {integrity: sha512-8kB30R7Hwqf40JPiKhVzodJs2Qc1ZJ5zuT3uzw5Hq/dhNCl3G3l83jfpdI1e20BP348+fV7VIL/+FxaXkqBmWg==}
504 |
505 | '@types/cookie@0.6.0':
506 | resolution: {integrity: sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==}
507 |
508 | '@types/deep-eql@4.0.2':
509 | resolution: {integrity: sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==}
510 |
511 | '@types/estree@1.0.6':
512 | resolution: {integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==}
513 |
514 | '@types/estree@1.0.7':
515 | resolution: {integrity: sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==}
516 |
517 | '@types/json-schema@7.0.15':
518 | resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==}
519 |
520 | '@types/node@20.19.0':
521 | resolution: {integrity: sha512-hfrc+1tud1xcdVTABC2JiomZJEklMcXYNTVtZLAeqTVWD+qL5jkHKT+1lOtqDdGxt+mB53DTtiz673vfjU8D1Q==}
522 |
523 | '@types/statuses@2.0.5':
524 | resolution: {integrity: sha512-jmIUGWrAiwu3dZpxntxieC+1n/5c3mjrImkmOSQ2NC5uP6cYO4aAZDdSmRcI5C1oiTmqlZGHC+/NmJrKogbP5A==}
525 |
526 | '@types/tough-cookie@4.0.5':
527 | resolution: {integrity: sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==}
528 |
529 | '@typescript-eslint/eslint-plugin@8.33.1':
530 | resolution: {integrity: sha512-TDCXj+YxLgtvxvFlAvpoRv9MAncDLBV2oT9Bd7YBGC/b/sEURoOYuIwLI99rjWOfY3QtDzO+mk0n4AmdFExW8A==}
531 | engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
532 | peerDependencies:
533 | '@typescript-eslint/parser': ^8.33.1
534 | eslint: ^8.57.0 || ^9.0.0
535 | typescript: '>=4.8.4 <5.9.0'
536 |
537 | '@typescript-eslint/parser@8.33.1':
538 | resolution: {integrity: sha512-qwxv6dq682yVvgKKp2qWwLgRbscDAYktPptK4JPojCwwi3R9cwrvIxS4lvBpzmcqzR4bdn54Z0IG1uHFskW4dA==}
539 | engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
540 | peerDependencies:
541 | eslint: ^8.57.0 || ^9.0.0
542 | typescript: '>=4.8.4 <5.9.0'
543 |
544 | '@typescript-eslint/project-service@8.33.1':
545 | resolution: {integrity: sha512-DZR0efeNklDIHHGRpMpR5gJITQpu6tLr9lDJnKdONTC7vvzOlLAG/wcfxcdxEWrbiZApcoBCzXqU/Z458Za5Iw==}
546 | engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
547 | peerDependencies:
548 | typescript: '>=4.8.4 <5.9.0'
549 |
550 | '@typescript-eslint/scope-manager@8.33.1':
551 | resolution: {integrity: sha512-dM4UBtgmzHR9bS0Rv09JST0RcHYearoEoo3pG5B6GoTR9XcyeqX87FEhPo+5kTvVfKCvfHaHrcgeJQc6mrDKrA==}
552 | engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
553 |
554 | '@typescript-eslint/tsconfig-utils@8.33.1':
555 | resolution: {integrity: sha512-STAQsGYbHCF0/e+ShUQ4EatXQ7ceh3fBCXkNU7/MZVKulrlq1usH7t2FhxvCpuCi5O5oi1vmVaAjrGeL71OK1g==}
556 | engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
557 | peerDependencies:
558 | typescript: '>=4.8.4 <5.9.0'
559 |
560 | '@typescript-eslint/type-utils@8.33.1':
561 | resolution: {integrity: sha512-1cG37d9xOkhlykom55WVwG2QRNC7YXlxMaMzqw2uPeJixBFfKWZgaP/hjAObqMN/u3fr5BrTwTnc31/L9jQ2ww==}
562 | engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
563 | peerDependencies:
564 | eslint: ^8.57.0 || ^9.0.0
565 | typescript: '>=4.8.4 <5.9.0'
566 |
567 | '@typescript-eslint/types@8.33.1':
568 | resolution: {integrity: sha512-xid1WfizGhy/TKMTwhtVOgalHwPtV8T32MS9MaH50Cwvz6x6YqRIPdD2WvW0XaqOzTV9p5xdLY0h/ZusU5Lokg==}
569 | engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
570 |
571 | '@typescript-eslint/typescript-estree@8.33.1':
572 | resolution: {integrity: sha512-+s9LYcT8LWjdYWu7IWs7FvUxpQ/DGkdjZeE/GGulHvv8rvYwQvVaUZ6DE+j5x/prADUgSbbCWZ2nPI3usuVeOA==}
573 | engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
574 | peerDependencies:
575 | typescript: '>=4.8.4 <5.9.0'
576 |
577 | '@typescript-eslint/utils@8.33.1':
578 | resolution: {integrity: sha512-52HaBiEQUaRYqAXpfzWSR2U3gxk92Kw006+xZpElaPMg3C4PgM+A5LqwoQI1f9E5aZ/qlxAZxzm42WX+vn92SQ==}
579 | engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
580 | peerDependencies:
581 | eslint: ^8.57.0 || ^9.0.0
582 | typescript: '>=4.8.4 <5.9.0'
583 |
584 | '@typescript-eslint/visitor-keys@8.33.1':
585 | resolution: {integrity: sha512-3i8NrFcZeeDHJ+7ZUuDkGT+UHq+XoFGsymNK2jZCOHcfEzRQ0BdpRtdpSx/Iyf3MHLWIcLS0COuOPibKQboIiQ==}
586 | engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
587 |
588 | '@vercel/ncc@0.38.3':
589 | resolution: {integrity: sha512-rnK6hJBS6mwc+Bkab+PGPs9OiS0i/3kdTO+CkI8V0/VrW3vmz7O2Pxjw/owOlmo6PKEIxRSeZKv/kuL9itnpYA==}
590 | hasBin: true
591 |
592 | '@vitest/eslint-plugin@1.2.1':
593 | resolution: {integrity: sha512-JQr1jdVcrsoS7Sdzn83h9sq4DvREf9Q/onTZbJCqTVlv/76qb+TZrLv/9VhjnjSMHweQH5FdpMDeCR6aDe2fgw==}
594 | peerDependencies:
595 | eslint: '>= 8.57.0'
596 | typescript: '>= 5.0.0'
597 | vitest: '*'
598 | peerDependenciesMeta:
599 | typescript:
600 | optional: true
601 | vitest:
602 | optional: true
603 |
604 | '@vitest/expect@3.2.2':
605 | resolution: {integrity: sha512-ipHw0z669vEMjzz3xQE8nJX1s0rQIb7oEl4jjl35qWTwm/KIHERIg/p/zORrjAaZKXfsv7IybcNGHwhOOAPMwQ==}
606 |
607 | '@vitest/mocker@3.2.2':
608 | resolution: {integrity: sha512-jKojcaRyIYpDEf+s7/dD3LJt53c0dPfp5zCPXz9H/kcGrSlovU/t1yEaNzM9oFME3dcd4ULwRI/x0Po1Zf+LTw==}
609 | peerDependencies:
610 | msw: ^2.4.9
611 | vite: ^5.0.0 || ^6.0.0 || ^7.0.0-0
612 | peerDependenciesMeta:
613 | msw:
614 | optional: true
615 | vite:
616 | optional: true
617 |
618 | '@vitest/pretty-format@3.2.2':
619 | resolution: {integrity: sha512-FY4o4U1UDhO9KMd2Wee5vumwcaHw7Vg4V7yR4Oq6uK34nhEJOmdRYrk3ClburPRUA09lXD/oXWZ8y/Sdma0aUQ==}
620 |
621 | '@vitest/runner@3.2.2':
622 | resolution: {integrity: sha512-GYcHcaS3ejGRZYed2GAkvsjBeXIEerDKdX3orQrBJqLRiea4NSS9qvn9Nxmuy1IwIB+EjFOaxXnX79l8HFaBwg==}
623 |
624 | '@vitest/snapshot@3.2.2':
625 | resolution: {integrity: sha512-aMEI2XFlR1aNECbBs5C5IZopfi5Lb8QJZGGpzS8ZUHML5La5wCbrbhLOVSME68qwpT05ROEEOAZPRXFpxZV2wA==}
626 |
627 | '@vitest/spy@3.2.2':
628 | resolution: {integrity: sha512-6Utxlx3o7pcTxvp0u8kUiXtRFScMrUg28KjB3R2hon7w4YqOFAEA9QwzPVVS1QNL3smo4xRNOpNZClRVfpMcYg==}
629 |
630 | '@vitest/utils@3.2.2':
631 | resolution: {integrity: sha512-qJYMllrWpF/OYfWHP32T31QCaLa3BAzT/n/8mNGhPdVcjY+JYazQFO1nsJvXU12Kp1xMpNY4AGuljPTNjQve6A==}
632 |
633 | acorn-jsx@5.3.2:
634 | resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==}
635 | peerDependencies:
636 | acorn: ^6.0.0 || ^7.0.0 || ^8.0.0
637 |
638 | acorn@8.14.0:
639 | resolution: {integrity: sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==}
640 | engines: {node: '>=0.4.0'}
641 | hasBin: true
642 |
643 | ajv@6.12.6:
644 | resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==}
645 |
646 | ansi-escapes@4.3.2:
647 | resolution: {integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==}
648 | engines: {node: '>=8'}
649 |
650 | ansi-regex@5.0.1:
651 | resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==}
652 | engines: {node: '>=8'}
653 |
654 | ansi-styles@4.3.0:
655 | resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==}
656 | engines: {node: '>=8'}
657 |
658 | argparse@2.0.1:
659 | resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==}
660 |
661 | assertion-error@2.0.1:
662 | resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==}
663 | engines: {node: '>=12'}
664 |
665 | balanced-match@1.0.2:
666 | resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
667 |
668 | before-after-hook@2.2.3:
669 | resolution: {integrity: sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ==}
670 |
671 | brace-expansion@1.1.11:
672 | resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==}
673 |
674 | brace-expansion@2.0.1:
675 | resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==}
676 |
677 | braces@3.0.2:
678 | resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==}
679 | engines: {node: '>=8'}
680 |
681 | cac@6.7.14:
682 | resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==}
683 | engines: {node: '>=8'}
684 |
685 | callsites@3.1.0:
686 | resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==}
687 | engines: {node: '>=6'}
688 |
689 | chai@5.2.0:
690 | resolution: {integrity: sha512-mCuXncKXk5iCLhfhwTc0izo0gtEmpz5CtG2y8GiOINBlMVS6v8TMRc5TaLWKS6692m9+dVVfzgeVxR5UxWHTYw==}
691 | engines: {node: '>=12'}
692 |
693 | chalk@4.1.2:
694 | resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==}
695 | engines: {node: '>=10'}
696 |
697 | check-error@2.1.1:
698 | resolution: {integrity: sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==}
699 | engines: {node: '>= 16'}
700 |
701 | cli-width@4.1.0:
702 | resolution: {integrity: sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==}
703 | engines: {node: '>= 12'}
704 |
705 | cliui@8.0.1:
706 | resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==}
707 | engines: {node: '>=12'}
708 |
709 | color-convert@2.0.1:
710 | resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==}
711 | engines: {node: '>=7.0.0'}
712 |
713 | color-name@1.1.4:
714 | resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
715 |
716 | concat-map@0.0.1:
717 | resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==}
718 |
719 | cookie@0.7.2:
720 | resolution: {integrity: sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==}
721 | engines: {node: '>= 0.6'}
722 |
723 | cross-spawn@7.0.6:
724 | resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==}
725 | engines: {node: '>= 8'}
726 |
727 | debug@4.4.0:
728 | resolution: {integrity: sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==}
729 | engines: {node: '>=6.0'}
730 | peerDependencies:
731 | supports-color: '*'
732 | peerDependenciesMeta:
733 | supports-color:
734 | optional: true
735 |
736 | debug@4.4.1:
737 | resolution: {integrity: sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==}
738 | engines: {node: '>=6.0'}
739 | peerDependencies:
740 | supports-color: '*'
741 | peerDependenciesMeta:
742 | supports-color:
743 | optional: true
744 |
745 | deep-eql@5.0.2:
746 | resolution: {integrity: sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==}
747 | engines: {node: '>=6'}
748 |
749 | deep-is@0.1.4:
750 | resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==}
751 |
752 | deprecation@2.3.1:
753 | resolution: {integrity: sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==}
754 |
755 | emoji-regex@8.0.0:
756 | resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==}
757 |
758 | es-module-lexer@1.7.0:
759 | resolution: {integrity: sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==}
760 |
761 | esbuild@0.25.5:
762 | resolution: {integrity: sha512-P8OtKZRv/5J5hhz0cUAdu/cLuPIKXpQl1R9pZtvmHWQvrAUVd0UNIPT4IB4W3rNOqVO0rlqHmCIbSwxh/c9yUQ==}
763 | engines: {node: '>=18'}
764 | hasBin: true
765 |
766 | escalade@3.1.2:
767 | resolution: {integrity: sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==}
768 | engines: {node: '>=6'}
769 |
770 | escape-string-regexp@4.0.0:
771 | resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==}
772 | engines: {node: '>=10'}
773 |
774 | eslint-scope@8.3.0:
775 | resolution: {integrity: sha512-pUNxi75F8MJ/GdeKtVLSbYg4ZI34J6C0C7sbL4YOp2exGwen7ZsuBqKzUhXd0qMQ362yET3z+uPwKeg/0C2XCQ==}
776 | engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
777 |
778 | eslint-visitor-keys@3.4.3:
779 | resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==}
780 | engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
781 |
782 | eslint-visitor-keys@4.2.0:
783 | resolution: {integrity: sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==}
784 | engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
785 |
786 | eslint@9.28.0:
787 | resolution: {integrity: sha512-ocgh41VhRlf9+fVpe7QKzwLj9c92fDiqOj8Y3Sd4/ZmVA4Btx4PlUYPq4pp9JDyupkf1upbEXecxL2mwNV7jPQ==}
788 | engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
789 | hasBin: true
790 | peerDependencies:
791 | jiti: '*'
792 | peerDependenciesMeta:
793 | jiti:
794 | optional: true
795 |
796 | espree@10.3.0:
797 | resolution: {integrity: sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==}
798 | engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
799 |
800 | esquery@1.5.0:
801 | resolution: {integrity: sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==}
802 | engines: {node: '>=0.10'}
803 |
804 | esrecurse@4.3.0:
805 | resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==}
806 | engines: {node: '>=4.0'}
807 |
808 | estraverse@5.3.0:
809 | resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==}
810 | engines: {node: '>=4.0'}
811 |
812 | estree-walker@3.0.3:
813 | resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==}
814 |
815 | esutils@2.0.3:
816 | resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==}
817 | engines: {node: '>=0.10.0'}
818 |
819 | expect-type@1.2.1:
820 | resolution: {integrity: sha512-/kP8CAwxzLVEeFrMm4kMmy4CCDlpipyA7MYLVrdJIkV0fYF0UaigQHRsxHiuY/GEea+bh4KSv3TIlgr+2UL6bw==}
821 | engines: {node: '>=12.0.0'}
822 |
823 | fast-deep-equal@3.1.3:
824 | resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==}
825 |
826 | fast-glob@3.3.2:
827 | resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==}
828 | engines: {node: '>=8.6.0'}
829 |
830 | fast-json-stable-stringify@2.1.0:
831 | resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==}
832 |
833 | fast-levenshtein@2.0.6:
834 | resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==}
835 |
836 | fastq@1.17.1:
837 | resolution: {integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==}
838 |
839 | fdir@6.4.5:
840 | resolution: {integrity: sha512-4BG7puHpVsIYxZUbiUE3RqGloLaSSwzYie5jvasC4LWuBWzZawynvYouhjbQKw2JuIGYdm0DzIxl8iVidKlUEw==}
841 | peerDependencies:
842 | picomatch: ^3 || ^4
843 | peerDependenciesMeta:
844 | picomatch:
845 | optional: true
846 |
847 | file-entry-cache@8.0.0:
848 | resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==}
849 | engines: {node: '>=16.0.0'}
850 |
851 | fill-range@7.0.1:
852 | resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==}
853 | engines: {node: '>=8'}
854 |
855 | find-up@5.0.0:
856 | resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==}
857 | engines: {node: '>=10'}
858 |
859 | flat-cache@4.0.1:
860 | resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==}
861 | engines: {node: '>=16'}
862 |
863 | flatted@3.3.1:
864 | resolution: {integrity: sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==}
865 |
866 | fsevents@2.3.3:
867 | resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==}
868 | engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
869 | os: [darwin]
870 |
871 | get-caller-file@2.0.5:
872 | resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==}
873 | engines: {node: 6.* || 8.* || >= 10.*}
874 |
875 | glob-parent@5.1.2:
876 | resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==}
877 | engines: {node: '>= 6'}
878 |
879 | glob-parent@6.0.2:
880 | resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==}
881 | engines: {node: '>=10.13.0'}
882 |
883 | globals@14.0.0:
884 | resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==}
885 | engines: {node: '>=18'}
886 |
887 | graphemer@1.4.0:
888 | resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==}
889 |
890 | graphql@16.9.0:
891 | resolution: {integrity: sha512-GGTKBX4SD7Wdb8mqeDLni2oaRGYQWjWHGKPQ24ZMnUtKfcsVoiv4uX8+LJr1K6U5VW2Lu1BwJnj7uiori0YtRw==}
892 | engines: {node: ^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0}
893 |
894 | has-flag@4.0.0:
895 | resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==}
896 | engines: {node: '>=8'}
897 |
898 | headers-polyfill@4.0.3:
899 | resolution: {integrity: sha512-IScLbePpkvO846sIwOtOTDjutRMWdXdJmXdMvk6gCBHxFO8d+QKOQedyZSxFTTFYRSmlgSTDtXqqq4pcenBXLQ==}
900 |
901 | ignore@5.3.1:
902 | resolution: {integrity: sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==}
903 | engines: {node: '>= 4'}
904 |
905 | ignore@7.0.4:
906 | resolution: {integrity: sha512-gJzzk+PQNznz8ysRrC0aOkBNVRBDtE1n53IqyqEf3PXrYwomFs5q4pGMizBMJF+ykh03insJ27hB8gSrD2Hn8A==}
907 | engines: {node: '>= 4'}
908 |
909 | import-fresh@3.3.0:
910 | resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==}
911 | engines: {node: '>=6'}
912 |
913 | imurmurhash@0.1.4:
914 | resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==}
915 | engines: {node: '>=0.8.19'}
916 |
917 | is-extglob@2.1.1:
918 | resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==}
919 | engines: {node: '>=0.10.0'}
920 |
921 | is-fullwidth-code-point@3.0.0:
922 | resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==}
923 | engines: {node: '>=8'}
924 |
925 | is-glob@4.0.3:
926 | resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==}
927 | engines: {node: '>=0.10.0'}
928 |
929 | is-node-process@1.2.0:
930 | resolution: {integrity: sha512-Vg4o6/fqPxIjtxgUH5QLJhwZ7gW5diGCVlXpuUfELC62CuxM1iHcRe51f2W1FDy04Ai4KJkagKjx3XaqyfRKXw==}
931 |
932 | is-number@7.0.0:
933 | resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==}
934 | engines: {node: '>=0.12.0'}
935 |
936 | isexe@2.0.0:
937 | resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
938 |
939 | js-yaml@4.1.0:
940 | resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==}
941 | hasBin: true
942 |
943 | json-buffer@3.0.1:
944 | resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==}
945 |
946 | json-schema-traverse@0.4.1:
947 | resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==}
948 |
949 | json-stable-stringify-without-jsonify@1.0.1:
950 | resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==}
951 |
952 | keyv@4.5.4:
953 | resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==}
954 |
955 | levn@0.4.1:
956 | resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==}
957 | engines: {node: '>= 0.8.0'}
958 |
959 | locate-path@6.0.0:
960 | resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==}
961 | engines: {node: '>=10'}
962 |
963 | lodash.merge@4.6.2:
964 | resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==}
965 |
966 | loupe@3.1.3:
967 | resolution: {integrity: sha512-kkIp7XSkP78ZxJEsSxW3712C6teJVoeHHwgo9zJ380de7IYyJ2ISlxojcH2pC5OFLewESmnRi/+XCDIEEVyoug==}
968 |
969 | magic-string@0.30.17:
970 | resolution: {integrity: sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==}
971 |
972 | merge2@1.4.1:
973 | resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==}
974 | engines: {node: '>= 8'}
975 |
976 | micromatch@4.0.5:
977 | resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==}
978 | engines: {node: '>=8.6'}
979 |
980 | minimatch@3.1.2:
981 | resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==}
982 |
983 | minimatch@9.0.4:
984 | resolution: {integrity: sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==}
985 | engines: {node: '>=16 || 14 >=14.17'}
986 |
987 | ms@2.1.3:
988 | resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
989 |
990 | msw@2.10.1:
991 | resolution: {integrity: sha512-V/YhZE2QPd48vKFGLo2BZanbBqncJn2k9/+vGtq9IFtv2D78+DIXlKH63emxa8reE/LIQHz9p3ZcFOThhsTSOg==}
992 | engines: {node: '>=18'}
993 | hasBin: true
994 | peerDependencies:
995 | typescript: '>= 4.8.x'
996 | peerDependenciesMeta:
997 | typescript:
998 | optional: true
999 |
1000 | mute-stream@2.0.0:
1001 | resolution: {integrity: sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA==}
1002 | engines: {node: ^18.17.0 || >=20.5.0}
1003 |
1004 | nanoid@3.3.11:
1005 | resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==}
1006 | engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
1007 | hasBin: true
1008 |
1009 | natural-compare@1.4.0:
1010 | resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==}
1011 |
1012 | once@1.4.0:
1013 | resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==}
1014 |
1015 | optionator@0.9.3:
1016 | resolution: {integrity: sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==}
1017 | engines: {node: '>= 0.8.0'}
1018 |
1019 | outvariant@1.4.3:
1020 | resolution: {integrity: sha512-+Sl2UErvtsoajRDKCE5/dBz4DIvHXQQnAxtQTF04OJxY0+DyZXSo5P5Bb7XYWOh81syohlYL24hbDwxedPUJCA==}
1021 |
1022 | p-limit@3.1.0:
1023 | resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==}
1024 | engines: {node: '>=10'}
1025 |
1026 | p-locate@5.0.0:
1027 | resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==}
1028 | engines: {node: '>=10'}
1029 |
1030 | parent-module@1.0.1:
1031 | resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==}
1032 | engines: {node: '>=6'}
1033 |
1034 | path-exists@4.0.0:
1035 | resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==}
1036 | engines: {node: '>=8'}
1037 |
1038 | path-key@3.1.1:
1039 | resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==}
1040 | engines: {node: '>=8'}
1041 |
1042 | path-to-regexp@6.3.0:
1043 | resolution: {integrity: sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==}
1044 |
1045 | pathe@2.0.3:
1046 | resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==}
1047 |
1048 | pathval@2.0.0:
1049 | resolution: {integrity: sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==}
1050 | engines: {node: '>= 14.16'}
1051 |
1052 | picocolors@1.1.1:
1053 | resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==}
1054 |
1055 | picomatch@2.3.1:
1056 | resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==}
1057 | engines: {node: '>=8.6'}
1058 |
1059 | picomatch@4.0.2:
1060 | resolution: {integrity: sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==}
1061 | engines: {node: '>=12'}
1062 |
1063 | pnpm@10.11.1:
1064 | resolution: {integrity: sha512-5Rm592OYadyNXDxd/vc7PwkQlLCgBtcxc1PHKxJOgOGv1ClzLihwWta/oe6HnB/ORsEozOvTGSEB9D3WfGZ5Eg==}
1065 | engines: {node: '>=18.12'}
1066 | hasBin: true
1067 |
1068 | postcss@8.5.4:
1069 | resolution: {integrity: sha512-QSa9EBe+uwlGTFmHsPKokv3B/oEMQZxfqW0QqNCyhpa6mB1afzulwn8hihglqAb2pOw+BJgNlmXQ8la2VeHB7w==}
1070 | engines: {node: ^10 || ^12 || >=14}
1071 |
1072 | prelude-ls@1.2.1:
1073 | resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==}
1074 | engines: {node: '>= 0.8.0'}
1075 |
1076 | prettier@3.5.3:
1077 | resolution: {integrity: sha512-QQtaxnoDJeAkDvDKWCLiwIXkTgRhwYDEQCghU9Z6q03iyek/rxRh/2lC3HB7P8sWT2xC/y5JDctPLBIGzHKbhw==}
1078 | engines: {node: '>=14'}
1079 | hasBin: true
1080 |
1081 | psl@1.10.0:
1082 | resolution: {integrity: sha512-KSKHEbjAnpUuAUserOq0FxGXCUrzC3WniuSJhvdbs102rL55266ZcHBqLWOsG30spQMlPdpy7icATiAQehg/iA==}
1083 |
1084 | punycode@2.3.1:
1085 | resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==}
1086 | engines: {node: '>=6'}
1087 |
1088 | querystringify@2.2.0:
1089 | resolution: {integrity: sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==}
1090 |
1091 | queue-microtask@1.2.3:
1092 | resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==}
1093 |
1094 | require-directory@2.1.1:
1095 | resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==}
1096 | engines: {node: '>=0.10.0'}
1097 |
1098 | requires-port@1.0.0:
1099 | resolution: {integrity: sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==}
1100 |
1101 | resolve-from@4.0.0:
1102 | resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==}
1103 | engines: {node: '>=4'}
1104 |
1105 | reusify@1.0.4:
1106 | resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==}
1107 | engines: {iojs: '>=1.0.0', node: '>=0.10.0'}
1108 |
1109 | rollup@4.42.0:
1110 | resolution: {integrity: sha512-LW+Vse3BJPyGJGAJt1j8pWDKPd73QM8cRXYK1IxOBgL2AGLu7Xd2YOW0M2sLUBCkF5MshXXtMApyEAEzMVMsnw==}
1111 | engines: {node: '>=18.0.0', npm: '>=8.0.0'}
1112 | hasBin: true
1113 |
1114 | run-parallel@1.2.0:
1115 | resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==}
1116 |
1117 | semver@7.7.2:
1118 | resolution: {integrity: sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==}
1119 | engines: {node: '>=10'}
1120 | hasBin: true
1121 |
1122 | shebang-command@2.0.0:
1123 | resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==}
1124 | engines: {node: '>=8'}
1125 |
1126 | shebang-regex@3.0.0:
1127 | resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==}
1128 | engines: {node: '>=8'}
1129 |
1130 | siginfo@2.0.0:
1131 | resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==}
1132 |
1133 | signal-exit@4.1.0:
1134 | resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==}
1135 | engines: {node: '>=14'}
1136 |
1137 | source-map-js@1.2.1:
1138 | resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==}
1139 | engines: {node: '>=0.10.0'}
1140 |
1141 | stackback@0.0.2:
1142 | resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==}
1143 |
1144 | statuses@2.0.1:
1145 | resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==}
1146 | engines: {node: '>= 0.8'}
1147 |
1148 | std-env@3.9.0:
1149 | resolution: {integrity: sha512-UGvjygr6F6tpH7o2qyqR6QYpwraIjKSdtzyBdyytFOHmPZY917kwdwLG0RbOjWOnKmnm3PeHjaoLLMie7kPLQw==}
1150 |
1151 | strict-event-emitter@0.5.1:
1152 | resolution: {integrity: sha512-vMgjE/GGEPEFnhFub6pa4FmJBRBVOLpIII2hvCZ8Kzb7K0hlHo7mQv6xYrBvCL2LtAIBwFUK8wvuJgTVSQ5MFQ==}
1153 |
1154 | string-width@4.2.3:
1155 | resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==}
1156 | engines: {node: '>=8'}
1157 |
1158 | strip-ansi@6.0.1:
1159 | resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==}
1160 | engines: {node: '>=8'}
1161 |
1162 | strip-json-comments@3.1.1:
1163 | resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==}
1164 | engines: {node: '>=8'}
1165 |
1166 | supports-color@7.2.0:
1167 | resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==}
1168 | engines: {node: '>=8'}
1169 |
1170 | tinybench@2.9.0:
1171 | resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==}
1172 |
1173 | tinyexec@0.3.2:
1174 | resolution: {integrity: sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==}
1175 |
1176 | tinyglobby@0.2.14:
1177 | resolution: {integrity: sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ==}
1178 | engines: {node: '>=12.0.0'}
1179 |
1180 | tinypool@1.1.0:
1181 | resolution: {integrity: sha512-7CotroY9a8DKsKprEy/a14aCCm8jYVmR7aFy4fpkZM8sdpNJbKkixuNjgM50yCmip2ezc8z4N7k3oe2+rfRJCQ==}
1182 | engines: {node: ^18.0.0 || >=20.0.0}
1183 |
1184 | tinyrainbow@2.0.0:
1185 | resolution: {integrity: sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw==}
1186 | engines: {node: '>=14.0.0'}
1187 |
1188 | tinyspy@4.0.3:
1189 | resolution: {integrity: sha512-t2T/WLB2WRgZ9EpE4jgPJ9w+i66UZfDc8wHh0xrwiRNN+UwH98GIJkTeZqX9rg0i0ptwzqW+uYeIF0T4F8LR7A==}
1190 | engines: {node: '>=14.0.0'}
1191 |
1192 | to-regex-range@5.0.1:
1193 | resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==}
1194 | engines: {node: '>=8.0'}
1195 |
1196 | tough-cookie@4.1.4:
1197 | resolution: {integrity: sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==}
1198 | engines: {node: '>=6'}
1199 |
1200 | ts-api-utils@2.1.0:
1201 | resolution: {integrity: sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==}
1202 | engines: {node: '>=18.12'}
1203 | peerDependencies:
1204 | typescript: '>=4.8.4'
1205 |
1206 | tunnel@0.0.6:
1207 | resolution: {integrity: sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==}
1208 | engines: {node: '>=0.6.11 <=0.7.0 || >=0.7.3'}
1209 |
1210 | type-check@0.4.0:
1211 | resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==}
1212 | engines: {node: '>= 0.8.0'}
1213 |
1214 | type-fest@0.21.3:
1215 | resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==}
1216 | engines: {node: '>=10'}
1217 |
1218 | type-fest@4.41.0:
1219 | resolution: {integrity: sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==}
1220 | engines: {node: '>=16'}
1221 |
1222 | typescript-eslint@8.33.1:
1223 | resolution: {integrity: sha512-AgRnV4sKkWOiZ0Kjbnf5ytTJXMUZQ0qhSVdQtDNYLPLnjsATEYhaO94GlRQwi4t4gO8FfjM6NnikHeKjUm8D7A==}
1224 | engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
1225 | peerDependencies:
1226 | eslint: ^8.57.0 || ^9.0.0
1227 | typescript: '>=4.8.4 <5.9.0'
1228 |
1229 | typescript@5.8.3:
1230 | resolution: {integrity: sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==}
1231 | engines: {node: '>=14.17'}
1232 | hasBin: true
1233 |
1234 | undici-types@6.21.0:
1235 | resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==}
1236 |
1237 | undici@5.28.3:
1238 | resolution: {integrity: sha512-3ItfzbrhDlINjaP0duwnNsKpDQk3acHI3gVJ1z4fmwMK31k5G9OVIAMLSIaP6w4FaGkaAkN6zaQO9LUvZ1t7VA==}
1239 | engines: {node: '>=14.0'}
1240 |
1241 | undici@5.29.0:
1242 | resolution: {integrity: sha512-raqeBD6NQK4SkWhQzeYKd1KmIG6dllBOTt55Rmkt4HtI9mwdWtJljnrXjAFUBLTSN67HWrOIZ3EPF4kjUw80Bg==}
1243 | engines: {node: '>=14.0'}
1244 |
1245 | universal-user-agent@6.0.1:
1246 | resolution: {integrity: sha512-yCzhz6FN2wU1NiiQRogkTQszlQSlpWaw8SvVegAc+bDxbzHgh1vX8uIe8OYyMH6DwH+sdTJsgMl36+mSMdRJIQ==}
1247 |
1248 | universalify@0.2.0:
1249 | resolution: {integrity: sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==}
1250 | engines: {node: '>= 4.0.0'}
1251 |
1252 | uri-js@4.4.1:
1253 | resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==}
1254 |
1255 | url-parse@1.5.10:
1256 | resolution: {integrity: sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==}
1257 |
1258 | vite-node@3.2.2:
1259 | resolution: {integrity: sha512-Xj/jovjZvDXOq2FgLXu8NsY4uHUMWtzVmMC2LkCu9HWdr9Qu1Is5sanX3Z4jOFKdohfaWDnEJWp9pRP0vVpAcA==}
1260 | engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0}
1261 | hasBin: true
1262 |
1263 | vite@6.3.5:
1264 | resolution: {integrity: sha512-cZn6NDFE7wdTpINgs++ZJ4N49W2vRp8LCKrn3Ob1kYNtOo21vfDoaV5GzBfLU4MovSAB8uNRm4jgzVQZ+mBzPQ==}
1265 | engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0}
1266 | hasBin: true
1267 | peerDependencies:
1268 | '@types/node': ^18.0.0 || ^20.0.0 || >=22.0.0
1269 | jiti: '>=1.21.0'
1270 | less: '*'
1271 | lightningcss: ^1.21.0
1272 | sass: '*'
1273 | sass-embedded: '*'
1274 | stylus: '*'
1275 | sugarss: '*'
1276 | terser: ^5.16.0
1277 | tsx: ^4.8.1
1278 | yaml: ^2.4.2
1279 | peerDependenciesMeta:
1280 | '@types/node':
1281 | optional: true
1282 | jiti:
1283 | optional: true
1284 | less:
1285 | optional: true
1286 | lightningcss:
1287 | optional: true
1288 | sass:
1289 | optional: true
1290 | sass-embedded:
1291 | optional: true
1292 | stylus:
1293 | optional: true
1294 | sugarss:
1295 | optional: true
1296 | terser:
1297 | optional: true
1298 | tsx:
1299 | optional: true
1300 | yaml:
1301 | optional: true
1302 |
1303 | vitest@3.2.2:
1304 | resolution: {integrity: sha512-fyNn/Rp016Bt5qvY0OQvIUCwW2vnaEBLxP42PmKbNIoasSYjML+8xyeADOPvBe+Xfl/ubIw4og7Lt9jflRsCNw==}
1305 | engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0}
1306 | hasBin: true
1307 | peerDependencies:
1308 | '@edge-runtime/vm': '*'
1309 | '@types/debug': ^4.1.12
1310 | '@types/node': ^18.0.0 || ^20.0.0 || >=22.0.0
1311 | '@vitest/browser': 3.2.2
1312 | '@vitest/ui': 3.2.2
1313 | happy-dom: '*'
1314 | jsdom: '*'
1315 | peerDependenciesMeta:
1316 | '@edge-runtime/vm':
1317 | optional: true
1318 | '@types/debug':
1319 | optional: true
1320 | '@types/node':
1321 | optional: true
1322 | '@vitest/browser':
1323 | optional: true
1324 | '@vitest/ui':
1325 | optional: true
1326 | happy-dom:
1327 | optional: true
1328 | jsdom:
1329 | optional: true
1330 |
1331 | which@2.0.2:
1332 | resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==}
1333 | engines: {node: '>= 8'}
1334 | hasBin: true
1335 |
1336 | why-is-node-running@2.3.0:
1337 | resolution: {integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==}
1338 | engines: {node: '>=8'}
1339 | hasBin: true
1340 |
1341 | wrap-ansi@6.2.0:
1342 | resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==}
1343 | engines: {node: '>=8'}
1344 |
1345 | wrap-ansi@7.0.0:
1346 | resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==}
1347 | engines: {node: '>=10'}
1348 |
1349 | wrappy@1.0.2:
1350 | resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==}
1351 |
1352 | y18n@5.0.8:
1353 | resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==}
1354 | engines: {node: '>=10'}
1355 |
1356 | yargs-parser@21.1.1:
1357 | resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==}
1358 | engines: {node: '>=12'}
1359 |
1360 | yargs@17.7.2:
1361 | resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==}
1362 | engines: {node: '>=12'}
1363 |
1364 | yocto-queue@0.1.0:
1365 | resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==}
1366 | engines: {node: '>=10'}
1367 |
1368 | yoctocolors-cjs@2.1.2:
1369 | resolution: {integrity: sha512-cYVsTjKl8b+FrnidjibDWskAv7UKOfcwaVZdp/it9n1s9fU3IkgDbhdIRKCW4JDsAlECJY0ytoVPT3sK6kideA==}
1370 | engines: {node: '>=18'}
1371 |
1372 | snapshots:
1373 |
1374 | '@aashutoshrathi/word-wrap@1.2.6': {}
1375 |
1376 | '@actions/core@1.11.1':
1377 | dependencies:
1378 | '@actions/exec': 1.1.1
1379 | '@actions/http-client': 2.2.0
1380 |
1381 | '@actions/exec@1.1.1':
1382 | dependencies:
1383 | '@actions/io': 1.1.3
1384 |
1385 | '@actions/github@6.0.1':
1386 | dependencies:
1387 | '@actions/http-client': 2.2.0
1388 | '@octokit/core': 5.1.0
1389 | '@octokit/plugin-paginate-rest': 9.2.2(@octokit/core@5.1.0)
1390 | '@octokit/plugin-rest-endpoint-methods': 10.4.1(@octokit/core@5.1.0)
1391 | '@octokit/request': 8.4.1
1392 | '@octokit/request-error': 5.1.1
1393 | undici: 5.29.0
1394 |
1395 | '@actions/http-client@2.2.0':
1396 | dependencies:
1397 | tunnel: 0.0.6
1398 | undici: 5.28.3
1399 |
1400 | '@actions/io@1.1.3': {}
1401 |
1402 | '@bundled-es-modules/cookie@2.0.1':
1403 | dependencies:
1404 | cookie: 0.7.2
1405 |
1406 | '@bundled-es-modules/statuses@1.0.1':
1407 | dependencies:
1408 | statuses: 2.0.1
1409 |
1410 | '@bundled-es-modules/tough-cookie@0.1.6':
1411 | dependencies:
1412 | '@types/tough-cookie': 4.0.5
1413 | tough-cookie: 4.1.4
1414 |
1415 | '@esbuild/aix-ppc64@0.25.5':
1416 | optional: true
1417 |
1418 | '@esbuild/android-arm64@0.25.5':
1419 | optional: true
1420 |
1421 | '@esbuild/android-arm@0.25.5':
1422 | optional: true
1423 |
1424 | '@esbuild/android-x64@0.25.5':
1425 | optional: true
1426 |
1427 | '@esbuild/darwin-arm64@0.25.5':
1428 | optional: true
1429 |
1430 | '@esbuild/darwin-x64@0.25.5':
1431 | optional: true
1432 |
1433 | '@esbuild/freebsd-arm64@0.25.5':
1434 | optional: true
1435 |
1436 | '@esbuild/freebsd-x64@0.25.5':
1437 | optional: true
1438 |
1439 | '@esbuild/linux-arm64@0.25.5':
1440 | optional: true
1441 |
1442 | '@esbuild/linux-arm@0.25.5':
1443 | optional: true
1444 |
1445 | '@esbuild/linux-ia32@0.25.5':
1446 | optional: true
1447 |
1448 | '@esbuild/linux-loong64@0.25.5':
1449 | optional: true
1450 |
1451 | '@esbuild/linux-mips64el@0.25.5':
1452 | optional: true
1453 |
1454 | '@esbuild/linux-ppc64@0.25.5':
1455 | optional: true
1456 |
1457 | '@esbuild/linux-riscv64@0.25.5':
1458 | optional: true
1459 |
1460 | '@esbuild/linux-s390x@0.25.5':
1461 | optional: true
1462 |
1463 | '@esbuild/linux-x64@0.25.5':
1464 | optional: true
1465 |
1466 | '@esbuild/netbsd-arm64@0.25.5':
1467 | optional: true
1468 |
1469 | '@esbuild/netbsd-x64@0.25.5':
1470 | optional: true
1471 |
1472 | '@esbuild/openbsd-arm64@0.25.5':
1473 | optional: true
1474 |
1475 | '@esbuild/openbsd-x64@0.25.5':
1476 | optional: true
1477 |
1478 | '@esbuild/sunos-x64@0.25.5':
1479 | optional: true
1480 |
1481 | '@esbuild/win32-arm64@0.25.5':
1482 | optional: true
1483 |
1484 | '@esbuild/win32-ia32@0.25.5':
1485 | optional: true
1486 |
1487 | '@esbuild/win32-x64@0.25.5':
1488 | optional: true
1489 |
1490 | '@eslint-community/eslint-utils@4.7.0(eslint@9.28.0)':
1491 | dependencies:
1492 | eslint: 9.28.0
1493 | eslint-visitor-keys: 3.4.3
1494 |
1495 | '@eslint-community/regexpp@4.12.1': {}
1496 |
1497 | '@eslint/config-array@0.20.0':
1498 | dependencies:
1499 | '@eslint/object-schema': 2.1.6
1500 | debug: 4.4.0
1501 | minimatch: 3.1.2
1502 | transitivePeerDependencies:
1503 | - supports-color
1504 |
1505 | '@eslint/config-helpers@0.2.1': {}
1506 |
1507 | '@eslint/core@0.14.0':
1508 | dependencies:
1509 | '@types/json-schema': 7.0.15
1510 |
1511 | '@eslint/eslintrc@3.3.1':
1512 | dependencies:
1513 | ajv: 6.12.6
1514 | debug: 4.4.0
1515 | espree: 10.3.0
1516 | globals: 14.0.0
1517 | ignore: 5.3.1
1518 | import-fresh: 3.3.0
1519 | js-yaml: 4.1.0
1520 | minimatch: 3.1.2
1521 | strip-json-comments: 3.1.1
1522 | transitivePeerDependencies:
1523 | - supports-color
1524 |
1525 | '@eslint/js@9.28.0': {}
1526 |
1527 | '@eslint/object-schema@2.1.6': {}
1528 |
1529 | '@eslint/plugin-kit@0.3.1':
1530 | dependencies:
1531 | '@eslint/core': 0.14.0
1532 | levn: 0.4.1
1533 |
1534 | '@fastify/busboy@2.1.1': {}
1535 |
1536 | '@humanfs/core@0.19.1': {}
1537 |
1538 | '@humanfs/node@0.16.6':
1539 | dependencies:
1540 | '@humanfs/core': 0.19.1
1541 | '@humanwhocodes/retry': 0.3.1
1542 |
1543 | '@humanwhocodes/module-importer@1.0.1': {}
1544 |
1545 | '@humanwhocodes/retry@0.3.1': {}
1546 |
1547 | '@humanwhocodes/retry@0.4.2': {}
1548 |
1549 | '@inquirer/confirm@5.0.1(@types/node@20.19.0)':
1550 | dependencies:
1551 | '@inquirer/core': 10.0.1(@types/node@20.19.0)
1552 | '@inquirer/type': 3.0.0(@types/node@20.19.0)
1553 | '@types/node': 20.19.0
1554 |
1555 | '@inquirer/core@10.0.1(@types/node@20.19.0)':
1556 | dependencies:
1557 | '@inquirer/figures': 1.0.7
1558 | '@inquirer/type': 3.0.0(@types/node@20.19.0)
1559 | ansi-escapes: 4.3.2
1560 | cli-width: 4.1.0
1561 | mute-stream: 2.0.0
1562 | signal-exit: 4.1.0
1563 | strip-ansi: 6.0.1
1564 | wrap-ansi: 6.2.0
1565 | yoctocolors-cjs: 2.1.2
1566 | transitivePeerDependencies:
1567 | - '@types/node'
1568 |
1569 | '@inquirer/figures@1.0.7': {}
1570 |
1571 | '@inquirer/type@3.0.0(@types/node@20.19.0)':
1572 | dependencies:
1573 | '@types/node': 20.19.0
1574 |
1575 | '@jridgewell/sourcemap-codec@1.5.0': {}
1576 |
1577 | '@mswjs/interceptors@0.39.2':
1578 | dependencies:
1579 | '@open-draft/deferred-promise': 2.2.0
1580 | '@open-draft/logger': 0.3.0
1581 | '@open-draft/until': 2.1.0
1582 | is-node-process: 1.2.0
1583 | outvariant: 1.4.3
1584 | strict-event-emitter: 0.5.1
1585 |
1586 | '@nodelib/fs.scandir@2.1.5':
1587 | dependencies:
1588 | '@nodelib/fs.stat': 2.0.5
1589 | run-parallel: 1.2.0
1590 |
1591 | '@nodelib/fs.stat@2.0.5': {}
1592 |
1593 | '@nodelib/fs.walk@1.2.8':
1594 | dependencies:
1595 | '@nodelib/fs.scandir': 2.1.5
1596 | fastq: 1.17.1
1597 |
1598 | '@octokit/auth-token@4.0.0': {}
1599 |
1600 | '@octokit/core@5.1.0':
1601 | dependencies:
1602 | '@octokit/auth-token': 4.0.0
1603 | '@octokit/graphql': 7.0.2
1604 | '@octokit/request': 8.4.1
1605 | '@octokit/request-error': 5.1.1
1606 | '@octokit/types': 12.6.0
1607 | before-after-hook: 2.2.3
1608 | universal-user-agent: 6.0.1
1609 |
1610 | '@octokit/endpoint@9.0.6':
1611 | dependencies:
1612 | '@octokit/types': 13.10.0
1613 | universal-user-agent: 6.0.1
1614 |
1615 | '@octokit/graphql@7.0.2':
1616 | dependencies:
1617 | '@octokit/request': 8.4.1
1618 | '@octokit/types': 12.6.0
1619 | universal-user-agent: 6.0.1
1620 |
1621 | '@octokit/openapi-types@20.0.0': {}
1622 |
1623 | '@octokit/openapi-types@24.2.0': {}
1624 |
1625 | '@octokit/plugin-paginate-rest@9.2.2(@octokit/core@5.1.0)':
1626 | dependencies:
1627 | '@octokit/core': 5.1.0
1628 | '@octokit/types': 12.6.0
1629 |
1630 | '@octokit/plugin-rest-endpoint-methods@10.4.1(@octokit/core@5.1.0)':
1631 | dependencies:
1632 | '@octokit/core': 5.1.0
1633 | '@octokit/types': 12.6.0
1634 |
1635 | '@octokit/request-error@5.1.1':
1636 | dependencies:
1637 | '@octokit/types': 13.10.0
1638 | deprecation: 2.3.1
1639 | once: 1.4.0
1640 |
1641 | '@octokit/request@8.4.1':
1642 | dependencies:
1643 | '@octokit/endpoint': 9.0.6
1644 | '@octokit/request-error': 5.1.1
1645 | '@octokit/types': 13.10.0
1646 | universal-user-agent: 6.0.1
1647 |
1648 | '@octokit/types@12.6.0':
1649 | dependencies:
1650 | '@octokit/openapi-types': 20.0.0
1651 |
1652 | '@octokit/types@13.10.0':
1653 | dependencies:
1654 | '@octokit/openapi-types': 24.2.0
1655 |
1656 | '@octokit/webhooks-types@7.6.1': {}
1657 |
1658 | '@open-draft/deferred-promise@2.2.0': {}
1659 |
1660 | '@open-draft/logger@0.3.0':
1661 | dependencies:
1662 | is-node-process: 1.2.0
1663 | outvariant: 1.4.3
1664 |
1665 | '@open-draft/until@2.1.0': {}
1666 |
1667 | '@rollup/rollup-android-arm-eabi@4.42.0':
1668 | optional: true
1669 |
1670 | '@rollup/rollup-android-arm64@4.42.0':
1671 | optional: true
1672 |
1673 | '@rollup/rollup-darwin-arm64@4.42.0':
1674 | optional: true
1675 |
1676 | '@rollup/rollup-darwin-x64@4.42.0':
1677 | optional: true
1678 |
1679 | '@rollup/rollup-freebsd-arm64@4.42.0':
1680 | optional: true
1681 |
1682 | '@rollup/rollup-freebsd-x64@4.42.0':
1683 | optional: true
1684 |
1685 | '@rollup/rollup-linux-arm-gnueabihf@4.42.0':
1686 | optional: true
1687 |
1688 | '@rollup/rollup-linux-arm-musleabihf@4.42.0':
1689 | optional: true
1690 |
1691 | '@rollup/rollup-linux-arm64-gnu@4.42.0':
1692 | optional: true
1693 |
1694 | '@rollup/rollup-linux-arm64-musl@4.42.0':
1695 | optional: true
1696 |
1697 | '@rollup/rollup-linux-loongarch64-gnu@4.42.0':
1698 | optional: true
1699 |
1700 | '@rollup/rollup-linux-powerpc64le-gnu@4.42.0':
1701 | optional: true
1702 |
1703 | '@rollup/rollup-linux-riscv64-gnu@4.42.0':
1704 | optional: true
1705 |
1706 | '@rollup/rollup-linux-riscv64-musl@4.42.0':
1707 | optional: true
1708 |
1709 | '@rollup/rollup-linux-s390x-gnu@4.42.0':
1710 | optional: true
1711 |
1712 | '@rollup/rollup-linux-x64-gnu@4.42.0':
1713 | optional: true
1714 |
1715 | '@rollup/rollup-linux-x64-musl@4.42.0':
1716 | optional: true
1717 |
1718 | '@rollup/rollup-win32-arm64-msvc@4.42.0':
1719 | optional: true
1720 |
1721 | '@rollup/rollup-win32-ia32-msvc@4.42.0':
1722 | optional: true
1723 |
1724 | '@rollup/rollup-win32-x64-msvc@4.42.0':
1725 | optional: true
1726 |
1727 | '@tsconfig/node20@20.1.5': {}
1728 |
1729 | '@types/chai@5.2.2':
1730 | dependencies:
1731 | '@types/deep-eql': 4.0.2
1732 |
1733 | '@types/cookie@0.6.0': {}
1734 |
1735 | '@types/deep-eql@4.0.2': {}
1736 |
1737 | '@types/estree@1.0.6': {}
1738 |
1739 | '@types/estree@1.0.7': {}
1740 |
1741 | '@types/json-schema@7.0.15': {}
1742 |
1743 | '@types/node@20.19.0':
1744 | dependencies:
1745 | undici-types: 6.21.0
1746 |
1747 | '@types/statuses@2.0.5': {}
1748 |
1749 | '@types/tough-cookie@4.0.5': {}
1750 |
1751 | '@typescript-eslint/eslint-plugin@8.33.1(@typescript-eslint/parser@8.33.1(eslint@9.28.0)(typescript@5.8.3))(eslint@9.28.0)(typescript@5.8.3)':
1752 | dependencies:
1753 | '@eslint-community/regexpp': 4.12.1
1754 | '@typescript-eslint/parser': 8.33.1(eslint@9.28.0)(typescript@5.8.3)
1755 | '@typescript-eslint/scope-manager': 8.33.1
1756 | '@typescript-eslint/type-utils': 8.33.1(eslint@9.28.0)(typescript@5.8.3)
1757 | '@typescript-eslint/utils': 8.33.1(eslint@9.28.0)(typescript@5.8.3)
1758 | '@typescript-eslint/visitor-keys': 8.33.1
1759 | eslint: 9.28.0
1760 | graphemer: 1.4.0
1761 | ignore: 7.0.4
1762 | natural-compare: 1.4.0
1763 | ts-api-utils: 2.1.0(typescript@5.8.3)
1764 | typescript: 5.8.3
1765 | transitivePeerDependencies:
1766 | - supports-color
1767 |
1768 | '@typescript-eslint/parser@8.33.1(eslint@9.28.0)(typescript@5.8.3)':
1769 | dependencies:
1770 | '@typescript-eslint/scope-manager': 8.33.1
1771 | '@typescript-eslint/types': 8.33.1
1772 | '@typescript-eslint/typescript-estree': 8.33.1(typescript@5.8.3)
1773 | '@typescript-eslint/visitor-keys': 8.33.1
1774 | debug: 4.4.1
1775 | eslint: 9.28.0
1776 | typescript: 5.8.3
1777 | transitivePeerDependencies:
1778 | - supports-color
1779 |
1780 | '@typescript-eslint/project-service@8.33.1(typescript@5.8.3)':
1781 | dependencies:
1782 | '@typescript-eslint/tsconfig-utils': 8.33.1(typescript@5.8.3)
1783 | '@typescript-eslint/types': 8.33.1
1784 | debug: 4.4.1
1785 | typescript: 5.8.3
1786 | transitivePeerDependencies:
1787 | - supports-color
1788 |
1789 | '@typescript-eslint/scope-manager@8.33.1':
1790 | dependencies:
1791 | '@typescript-eslint/types': 8.33.1
1792 | '@typescript-eslint/visitor-keys': 8.33.1
1793 |
1794 | '@typescript-eslint/tsconfig-utils@8.33.1(typescript@5.8.3)':
1795 | dependencies:
1796 | typescript: 5.8.3
1797 |
1798 | '@typescript-eslint/type-utils@8.33.1(eslint@9.28.0)(typescript@5.8.3)':
1799 | dependencies:
1800 | '@typescript-eslint/typescript-estree': 8.33.1(typescript@5.8.3)
1801 | '@typescript-eslint/utils': 8.33.1(eslint@9.28.0)(typescript@5.8.3)
1802 | debug: 4.4.1
1803 | eslint: 9.28.0
1804 | ts-api-utils: 2.1.0(typescript@5.8.3)
1805 | typescript: 5.8.3
1806 | transitivePeerDependencies:
1807 | - supports-color
1808 |
1809 | '@typescript-eslint/types@8.33.1': {}
1810 |
1811 | '@typescript-eslint/typescript-estree@8.33.1(typescript@5.8.3)':
1812 | dependencies:
1813 | '@typescript-eslint/project-service': 8.33.1(typescript@5.8.3)
1814 | '@typescript-eslint/tsconfig-utils': 8.33.1(typescript@5.8.3)
1815 | '@typescript-eslint/types': 8.33.1
1816 | '@typescript-eslint/visitor-keys': 8.33.1
1817 | debug: 4.4.1
1818 | fast-glob: 3.3.2
1819 | is-glob: 4.0.3
1820 | minimatch: 9.0.4
1821 | semver: 7.7.2
1822 | ts-api-utils: 2.1.0(typescript@5.8.3)
1823 | typescript: 5.8.3
1824 | transitivePeerDependencies:
1825 | - supports-color
1826 |
1827 | '@typescript-eslint/utils@8.33.1(eslint@9.28.0)(typescript@5.8.3)':
1828 | dependencies:
1829 | '@eslint-community/eslint-utils': 4.7.0(eslint@9.28.0)
1830 | '@typescript-eslint/scope-manager': 8.33.1
1831 | '@typescript-eslint/types': 8.33.1
1832 | '@typescript-eslint/typescript-estree': 8.33.1(typescript@5.8.3)
1833 | eslint: 9.28.0
1834 | typescript: 5.8.3
1835 | transitivePeerDependencies:
1836 | - supports-color
1837 |
1838 | '@typescript-eslint/visitor-keys@8.33.1':
1839 | dependencies:
1840 | '@typescript-eslint/types': 8.33.1
1841 | eslint-visitor-keys: 4.2.0
1842 |
1843 | '@vercel/ncc@0.38.3': {}
1844 |
1845 | '@vitest/eslint-plugin@1.2.1(eslint@9.28.0)(typescript@5.8.3)(vitest@3.2.2(@types/node@20.19.0)(msw@2.10.1(@types/node@20.19.0)(typescript@5.8.3)))':
1846 | dependencies:
1847 | '@typescript-eslint/utils': 8.33.1(eslint@9.28.0)(typescript@5.8.3)
1848 | eslint: 9.28.0
1849 | optionalDependencies:
1850 | typescript: 5.8.3
1851 | vitest: 3.2.2(@types/node@20.19.0)(msw@2.10.1(@types/node@20.19.0)(typescript@5.8.3))
1852 | transitivePeerDependencies:
1853 | - supports-color
1854 |
1855 | '@vitest/expect@3.2.2':
1856 | dependencies:
1857 | '@types/chai': 5.2.2
1858 | '@vitest/spy': 3.2.2
1859 | '@vitest/utils': 3.2.2
1860 | chai: 5.2.0
1861 | tinyrainbow: 2.0.0
1862 |
1863 | '@vitest/mocker@3.2.2(msw@2.10.1(@types/node@20.19.0)(typescript@5.8.3))(vite@6.3.5(@types/node@20.19.0))':
1864 | dependencies:
1865 | '@vitest/spy': 3.2.2
1866 | estree-walker: 3.0.3
1867 | magic-string: 0.30.17
1868 | optionalDependencies:
1869 | msw: 2.10.1(@types/node@20.19.0)(typescript@5.8.3)
1870 | vite: 6.3.5(@types/node@20.19.0)
1871 |
1872 | '@vitest/pretty-format@3.2.2':
1873 | dependencies:
1874 | tinyrainbow: 2.0.0
1875 |
1876 | '@vitest/runner@3.2.2':
1877 | dependencies:
1878 | '@vitest/utils': 3.2.2
1879 | pathe: 2.0.3
1880 |
1881 | '@vitest/snapshot@3.2.2':
1882 | dependencies:
1883 | '@vitest/pretty-format': 3.2.2
1884 | magic-string: 0.30.17
1885 | pathe: 2.0.3
1886 |
1887 | '@vitest/spy@3.2.2':
1888 | dependencies:
1889 | tinyspy: 4.0.3
1890 |
1891 | '@vitest/utils@3.2.2':
1892 | dependencies:
1893 | '@vitest/pretty-format': 3.2.2
1894 | loupe: 3.1.3
1895 | tinyrainbow: 2.0.0
1896 |
1897 | acorn-jsx@5.3.2(acorn@8.14.0):
1898 | dependencies:
1899 | acorn: 8.14.0
1900 |
1901 | acorn@8.14.0: {}
1902 |
1903 | ajv@6.12.6:
1904 | dependencies:
1905 | fast-deep-equal: 3.1.3
1906 | fast-json-stable-stringify: 2.1.0
1907 | json-schema-traverse: 0.4.1
1908 | uri-js: 4.4.1
1909 |
1910 | ansi-escapes@4.3.2:
1911 | dependencies:
1912 | type-fest: 0.21.3
1913 |
1914 | ansi-regex@5.0.1: {}
1915 |
1916 | ansi-styles@4.3.0:
1917 | dependencies:
1918 | color-convert: 2.0.1
1919 |
1920 | argparse@2.0.1: {}
1921 |
1922 | assertion-error@2.0.1: {}
1923 |
1924 | balanced-match@1.0.2: {}
1925 |
1926 | before-after-hook@2.2.3: {}
1927 |
1928 | brace-expansion@1.1.11:
1929 | dependencies:
1930 | balanced-match: 1.0.2
1931 | concat-map: 0.0.1
1932 |
1933 | brace-expansion@2.0.1:
1934 | dependencies:
1935 | balanced-match: 1.0.2
1936 |
1937 | braces@3.0.2:
1938 | dependencies:
1939 | fill-range: 7.0.1
1940 |
1941 | cac@6.7.14: {}
1942 |
1943 | callsites@3.1.0: {}
1944 |
1945 | chai@5.2.0:
1946 | dependencies:
1947 | assertion-error: 2.0.1
1948 | check-error: 2.1.1
1949 | deep-eql: 5.0.2
1950 | loupe: 3.1.3
1951 | pathval: 2.0.0
1952 |
1953 | chalk@4.1.2:
1954 | dependencies:
1955 | ansi-styles: 4.3.0
1956 | supports-color: 7.2.0
1957 |
1958 | check-error@2.1.1: {}
1959 |
1960 | cli-width@4.1.0: {}
1961 |
1962 | cliui@8.0.1:
1963 | dependencies:
1964 | string-width: 4.2.3
1965 | strip-ansi: 6.0.1
1966 | wrap-ansi: 7.0.0
1967 |
1968 | color-convert@2.0.1:
1969 | dependencies:
1970 | color-name: 1.1.4
1971 |
1972 | color-name@1.1.4: {}
1973 |
1974 | concat-map@0.0.1: {}
1975 |
1976 | cookie@0.7.2: {}
1977 |
1978 | cross-spawn@7.0.6:
1979 | dependencies:
1980 | path-key: 3.1.1
1981 | shebang-command: 2.0.0
1982 | which: 2.0.2
1983 |
1984 | debug@4.4.0:
1985 | dependencies:
1986 | ms: 2.1.3
1987 |
1988 | debug@4.4.1:
1989 | dependencies:
1990 | ms: 2.1.3
1991 |
1992 | deep-eql@5.0.2: {}
1993 |
1994 | deep-is@0.1.4: {}
1995 |
1996 | deprecation@2.3.1: {}
1997 |
1998 | emoji-regex@8.0.0: {}
1999 |
2000 | es-module-lexer@1.7.0: {}
2001 |
2002 | esbuild@0.25.5:
2003 | optionalDependencies:
2004 | '@esbuild/aix-ppc64': 0.25.5
2005 | '@esbuild/android-arm': 0.25.5
2006 | '@esbuild/android-arm64': 0.25.5
2007 | '@esbuild/android-x64': 0.25.5
2008 | '@esbuild/darwin-arm64': 0.25.5
2009 | '@esbuild/darwin-x64': 0.25.5
2010 | '@esbuild/freebsd-arm64': 0.25.5
2011 | '@esbuild/freebsd-x64': 0.25.5
2012 | '@esbuild/linux-arm': 0.25.5
2013 | '@esbuild/linux-arm64': 0.25.5
2014 | '@esbuild/linux-ia32': 0.25.5
2015 | '@esbuild/linux-loong64': 0.25.5
2016 | '@esbuild/linux-mips64el': 0.25.5
2017 | '@esbuild/linux-ppc64': 0.25.5
2018 | '@esbuild/linux-riscv64': 0.25.5
2019 | '@esbuild/linux-s390x': 0.25.5
2020 | '@esbuild/linux-x64': 0.25.5
2021 | '@esbuild/netbsd-arm64': 0.25.5
2022 | '@esbuild/netbsd-x64': 0.25.5
2023 | '@esbuild/openbsd-arm64': 0.25.5
2024 | '@esbuild/openbsd-x64': 0.25.5
2025 | '@esbuild/sunos-x64': 0.25.5
2026 | '@esbuild/win32-arm64': 0.25.5
2027 | '@esbuild/win32-ia32': 0.25.5
2028 | '@esbuild/win32-x64': 0.25.5
2029 |
2030 | escalade@3.1.2: {}
2031 |
2032 | escape-string-regexp@4.0.0: {}
2033 |
2034 | eslint-scope@8.3.0:
2035 | dependencies:
2036 | esrecurse: 4.3.0
2037 | estraverse: 5.3.0
2038 |
2039 | eslint-visitor-keys@3.4.3: {}
2040 |
2041 | eslint-visitor-keys@4.2.0: {}
2042 |
2043 | eslint@9.28.0:
2044 | dependencies:
2045 | '@eslint-community/eslint-utils': 4.7.0(eslint@9.28.0)
2046 | '@eslint-community/regexpp': 4.12.1
2047 | '@eslint/config-array': 0.20.0
2048 | '@eslint/config-helpers': 0.2.1
2049 | '@eslint/core': 0.14.0
2050 | '@eslint/eslintrc': 3.3.1
2051 | '@eslint/js': 9.28.0
2052 | '@eslint/plugin-kit': 0.3.1
2053 | '@humanfs/node': 0.16.6
2054 | '@humanwhocodes/module-importer': 1.0.1
2055 | '@humanwhocodes/retry': 0.4.2
2056 | '@types/estree': 1.0.6
2057 | '@types/json-schema': 7.0.15
2058 | ajv: 6.12.6
2059 | chalk: 4.1.2
2060 | cross-spawn: 7.0.6
2061 | debug: 4.4.0
2062 | escape-string-regexp: 4.0.0
2063 | eslint-scope: 8.3.0
2064 | eslint-visitor-keys: 4.2.0
2065 | espree: 10.3.0
2066 | esquery: 1.5.0
2067 | esutils: 2.0.3
2068 | fast-deep-equal: 3.1.3
2069 | file-entry-cache: 8.0.0
2070 | find-up: 5.0.0
2071 | glob-parent: 6.0.2
2072 | ignore: 5.3.1
2073 | imurmurhash: 0.1.4
2074 | is-glob: 4.0.3
2075 | json-stable-stringify-without-jsonify: 1.0.1
2076 | lodash.merge: 4.6.2
2077 | minimatch: 3.1.2
2078 | natural-compare: 1.4.0
2079 | optionator: 0.9.3
2080 | transitivePeerDependencies:
2081 | - supports-color
2082 |
2083 | espree@10.3.0:
2084 | dependencies:
2085 | acorn: 8.14.0
2086 | acorn-jsx: 5.3.2(acorn@8.14.0)
2087 | eslint-visitor-keys: 4.2.0
2088 |
2089 | esquery@1.5.0:
2090 | dependencies:
2091 | estraverse: 5.3.0
2092 |
2093 | esrecurse@4.3.0:
2094 | dependencies:
2095 | estraverse: 5.3.0
2096 |
2097 | estraverse@5.3.0: {}
2098 |
2099 | estree-walker@3.0.3:
2100 | dependencies:
2101 | '@types/estree': 1.0.7
2102 |
2103 | esutils@2.0.3: {}
2104 |
2105 | expect-type@1.2.1: {}
2106 |
2107 | fast-deep-equal@3.1.3: {}
2108 |
2109 | fast-glob@3.3.2:
2110 | dependencies:
2111 | '@nodelib/fs.stat': 2.0.5
2112 | '@nodelib/fs.walk': 1.2.8
2113 | glob-parent: 5.1.2
2114 | merge2: 1.4.1
2115 | micromatch: 4.0.5
2116 |
2117 | fast-json-stable-stringify@2.1.0: {}
2118 |
2119 | fast-levenshtein@2.0.6: {}
2120 |
2121 | fastq@1.17.1:
2122 | dependencies:
2123 | reusify: 1.0.4
2124 |
2125 | fdir@6.4.5(picomatch@4.0.2):
2126 | optionalDependencies:
2127 | picomatch: 4.0.2
2128 |
2129 | file-entry-cache@8.0.0:
2130 | dependencies:
2131 | flat-cache: 4.0.1
2132 |
2133 | fill-range@7.0.1:
2134 | dependencies:
2135 | to-regex-range: 5.0.1
2136 |
2137 | find-up@5.0.0:
2138 | dependencies:
2139 | locate-path: 6.0.0
2140 | path-exists: 4.0.0
2141 |
2142 | flat-cache@4.0.1:
2143 | dependencies:
2144 | flatted: 3.3.1
2145 | keyv: 4.5.4
2146 |
2147 | flatted@3.3.1: {}
2148 |
2149 | fsevents@2.3.3:
2150 | optional: true
2151 |
2152 | get-caller-file@2.0.5: {}
2153 |
2154 | glob-parent@5.1.2:
2155 | dependencies:
2156 | is-glob: 4.0.3
2157 |
2158 | glob-parent@6.0.2:
2159 | dependencies:
2160 | is-glob: 4.0.3
2161 |
2162 | globals@14.0.0: {}
2163 |
2164 | graphemer@1.4.0: {}
2165 |
2166 | graphql@16.9.0: {}
2167 |
2168 | has-flag@4.0.0: {}
2169 |
2170 | headers-polyfill@4.0.3: {}
2171 |
2172 | ignore@5.3.1: {}
2173 |
2174 | ignore@7.0.4: {}
2175 |
2176 | import-fresh@3.3.0:
2177 | dependencies:
2178 | parent-module: 1.0.1
2179 | resolve-from: 4.0.0
2180 |
2181 | imurmurhash@0.1.4: {}
2182 |
2183 | is-extglob@2.1.1: {}
2184 |
2185 | is-fullwidth-code-point@3.0.0: {}
2186 |
2187 | is-glob@4.0.3:
2188 | dependencies:
2189 | is-extglob: 2.1.1
2190 |
2191 | is-node-process@1.2.0: {}
2192 |
2193 | is-number@7.0.0: {}
2194 |
2195 | isexe@2.0.0: {}
2196 |
2197 | js-yaml@4.1.0:
2198 | dependencies:
2199 | argparse: 2.0.1
2200 |
2201 | json-buffer@3.0.1: {}
2202 |
2203 | json-schema-traverse@0.4.1: {}
2204 |
2205 | json-stable-stringify-without-jsonify@1.0.1: {}
2206 |
2207 | keyv@4.5.4:
2208 | dependencies:
2209 | json-buffer: 3.0.1
2210 |
2211 | levn@0.4.1:
2212 | dependencies:
2213 | prelude-ls: 1.2.1
2214 | type-check: 0.4.0
2215 |
2216 | locate-path@6.0.0:
2217 | dependencies:
2218 | p-locate: 5.0.0
2219 |
2220 | lodash.merge@4.6.2: {}
2221 |
2222 | loupe@3.1.3: {}
2223 |
2224 | magic-string@0.30.17:
2225 | dependencies:
2226 | '@jridgewell/sourcemap-codec': 1.5.0
2227 |
2228 | merge2@1.4.1: {}
2229 |
2230 | micromatch@4.0.5:
2231 | dependencies:
2232 | braces: 3.0.2
2233 | picomatch: 2.3.1
2234 |
2235 | minimatch@3.1.2:
2236 | dependencies:
2237 | brace-expansion: 1.1.11
2238 |
2239 | minimatch@9.0.4:
2240 | dependencies:
2241 | brace-expansion: 2.0.1
2242 |
2243 | ms@2.1.3: {}
2244 |
2245 | msw@2.10.1(@types/node@20.19.0)(typescript@5.8.3):
2246 | dependencies:
2247 | '@bundled-es-modules/cookie': 2.0.1
2248 | '@bundled-es-modules/statuses': 1.0.1
2249 | '@bundled-es-modules/tough-cookie': 0.1.6
2250 | '@inquirer/confirm': 5.0.1(@types/node@20.19.0)
2251 | '@mswjs/interceptors': 0.39.2
2252 | '@open-draft/deferred-promise': 2.2.0
2253 | '@open-draft/until': 2.1.0
2254 | '@types/cookie': 0.6.0
2255 | '@types/statuses': 2.0.5
2256 | graphql: 16.9.0
2257 | headers-polyfill: 4.0.3
2258 | is-node-process: 1.2.0
2259 | outvariant: 1.4.3
2260 | path-to-regexp: 6.3.0
2261 | picocolors: 1.1.1
2262 | strict-event-emitter: 0.5.1
2263 | type-fest: 4.41.0
2264 | yargs: 17.7.2
2265 | optionalDependencies:
2266 | typescript: 5.8.3
2267 | transitivePeerDependencies:
2268 | - '@types/node'
2269 |
2270 | mute-stream@2.0.0: {}
2271 |
2272 | nanoid@3.3.11: {}
2273 |
2274 | natural-compare@1.4.0: {}
2275 |
2276 | once@1.4.0:
2277 | dependencies:
2278 | wrappy: 1.0.2
2279 |
2280 | optionator@0.9.3:
2281 | dependencies:
2282 | '@aashutoshrathi/word-wrap': 1.2.6
2283 | deep-is: 0.1.4
2284 | fast-levenshtein: 2.0.6
2285 | levn: 0.4.1
2286 | prelude-ls: 1.2.1
2287 | type-check: 0.4.0
2288 |
2289 | outvariant@1.4.3: {}
2290 |
2291 | p-limit@3.1.0:
2292 | dependencies:
2293 | yocto-queue: 0.1.0
2294 |
2295 | p-locate@5.0.0:
2296 | dependencies:
2297 | p-limit: 3.1.0
2298 |
2299 | parent-module@1.0.1:
2300 | dependencies:
2301 | callsites: 3.1.0
2302 |
2303 | path-exists@4.0.0: {}
2304 |
2305 | path-key@3.1.1: {}
2306 |
2307 | path-to-regexp@6.3.0: {}
2308 |
2309 | pathe@2.0.3: {}
2310 |
2311 | pathval@2.0.0: {}
2312 |
2313 | picocolors@1.1.1: {}
2314 |
2315 | picomatch@2.3.1: {}
2316 |
2317 | picomatch@4.0.2: {}
2318 |
2319 | pnpm@10.11.1: {}
2320 |
2321 | postcss@8.5.4:
2322 | dependencies:
2323 | nanoid: 3.3.11
2324 | picocolors: 1.1.1
2325 | source-map-js: 1.2.1
2326 |
2327 | prelude-ls@1.2.1: {}
2328 |
2329 | prettier@3.5.3: {}
2330 |
2331 | psl@1.10.0:
2332 | dependencies:
2333 | punycode: 2.3.1
2334 |
2335 | punycode@2.3.1: {}
2336 |
2337 | querystringify@2.2.0: {}
2338 |
2339 | queue-microtask@1.2.3: {}
2340 |
2341 | require-directory@2.1.1: {}
2342 |
2343 | requires-port@1.0.0: {}
2344 |
2345 | resolve-from@4.0.0: {}
2346 |
2347 | reusify@1.0.4: {}
2348 |
2349 | rollup@4.42.0:
2350 | dependencies:
2351 | '@types/estree': 1.0.7
2352 | optionalDependencies:
2353 | '@rollup/rollup-android-arm-eabi': 4.42.0
2354 | '@rollup/rollup-android-arm64': 4.42.0
2355 | '@rollup/rollup-darwin-arm64': 4.42.0
2356 | '@rollup/rollup-darwin-x64': 4.42.0
2357 | '@rollup/rollup-freebsd-arm64': 4.42.0
2358 | '@rollup/rollup-freebsd-x64': 4.42.0
2359 | '@rollup/rollup-linux-arm-gnueabihf': 4.42.0
2360 | '@rollup/rollup-linux-arm-musleabihf': 4.42.0
2361 | '@rollup/rollup-linux-arm64-gnu': 4.42.0
2362 | '@rollup/rollup-linux-arm64-musl': 4.42.0
2363 | '@rollup/rollup-linux-loongarch64-gnu': 4.42.0
2364 | '@rollup/rollup-linux-powerpc64le-gnu': 4.42.0
2365 | '@rollup/rollup-linux-riscv64-gnu': 4.42.0
2366 | '@rollup/rollup-linux-riscv64-musl': 4.42.0
2367 | '@rollup/rollup-linux-s390x-gnu': 4.42.0
2368 | '@rollup/rollup-linux-x64-gnu': 4.42.0
2369 | '@rollup/rollup-linux-x64-musl': 4.42.0
2370 | '@rollup/rollup-win32-arm64-msvc': 4.42.0
2371 | '@rollup/rollup-win32-ia32-msvc': 4.42.0
2372 | '@rollup/rollup-win32-x64-msvc': 4.42.0
2373 | fsevents: 2.3.3
2374 |
2375 | run-parallel@1.2.0:
2376 | dependencies:
2377 | queue-microtask: 1.2.3
2378 |
2379 | semver@7.7.2: {}
2380 |
2381 | shebang-command@2.0.0:
2382 | dependencies:
2383 | shebang-regex: 3.0.0
2384 |
2385 | shebang-regex@3.0.0: {}
2386 |
2387 | siginfo@2.0.0: {}
2388 |
2389 | signal-exit@4.1.0: {}
2390 |
2391 | source-map-js@1.2.1: {}
2392 |
2393 | stackback@0.0.2: {}
2394 |
2395 | statuses@2.0.1: {}
2396 |
2397 | std-env@3.9.0: {}
2398 |
2399 | strict-event-emitter@0.5.1: {}
2400 |
2401 | string-width@4.2.3:
2402 | dependencies:
2403 | emoji-regex: 8.0.0
2404 | is-fullwidth-code-point: 3.0.0
2405 | strip-ansi: 6.0.1
2406 |
2407 | strip-ansi@6.0.1:
2408 | dependencies:
2409 | ansi-regex: 5.0.1
2410 |
2411 | strip-json-comments@3.1.1: {}
2412 |
2413 | supports-color@7.2.0:
2414 | dependencies:
2415 | has-flag: 4.0.0
2416 |
2417 | tinybench@2.9.0: {}
2418 |
2419 | tinyexec@0.3.2: {}
2420 |
2421 | tinyglobby@0.2.14:
2422 | dependencies:
2423 | fdir: 6.4.5(picomatch@4.0.2)
2424 | picomatch: 4.0.2
2425 |
2426 | tinypool@1.1.0: {}
2427 |
2428 | tinyrainbow@2.0.0: {}
2429 |
2430 | tinyspy@4.0.3: {}
2431 |
2432 | to-regex-range@5.0.1:
2433 | dependencies:
2434 | is-number: 7.0.0
2435 |
2436 | tough-cookie@4.1.4:
2437 | dependencies:
2438 | psl: 1.10.0
2439 | punycode: 2.3.1
2440 | universalify: 0.2.0
2441 | url-parse: 1.5.10
2442 |
2443 | ts-api-utils@2.1.0(typescript@5.8.3):
2444 | dependencies:
2445 | typescript: 5.8.3
2446 |
2447 | tunnel@0.0.6: {}
2448 |
2449 | type-check@0.4.0:
2450 | dependencies:
2451 | prelude-ls: 1.2.1
2452 |
2453 | type-fest@0.21.3: {}
2454 |
2455 | type-fest@4.41.0: {}
2456 |
2457 | typescript-eslint@8.33.1(eslint@9.28.0)(typescript@5.8.3):
2458 | dependencies:
2459 | '@typescript-eslint/eslint-plugin': 8.33.1(@typescript-eslint/parser@8.33.1(eslint@9.28.0)(typescript@5.8.3))(eslint@9.28.0)(typescript@5.8.3)
2460 | '@typescript-eslint/parser': 8.33.1(eslint@9.28.0)(typescript@5.8.3)
2461 | '@typescript-eslint/utils': 8.33.1(eslint@9.28.0)(typescript@5.8.3)
2462 | eslint: 9.28.0
2463 | typescript: 5.8.3
2464 | transitivePeerDependencies:
2465 | - supports-color
2466 |
2467 | typescript@5.8.3: {}
2468 |
2469 | undici-types@6.21.0: {}
2470 |
2471 | undici@5.28.3:
2472 | dependencies:
2473 | '@fastify/busboy': 2.1.1
2474 |
2475 | undici@5.29.0:
2476 | dependencies:
2477 | '@fastify/busboy': 2.1.1
2478 |
2479 | universal-user-agent@6.0.1: {}
2480 |
2481 | universalify@0.2.0: {}
2482 |
2483 | uri-js@4.4.1:
2484 | dependencies:
2485 | punycode: 2.3.1
2486 |
2487 | url-parse@1.5.10:
2488 | dependencies:
2489 | querystringify: 2.2.0
2490 | requires-port: 1.0.0
2491 |
2492 | vite-node@3.2.2(@types/node@20.19.0):
2493 | dependencies:
2494 | cac: 6.7.14
2495 | debug: 4.4.1
2496 | es-module-lexer: 1.7.0
2497 | pathe: 2.0.3
2498 | vite: 6.3.5(@types/node@20.19.0)
2499 | transitivePeerDependencies:
2500 | - '@types/node'
2501 | - jiti
2502 | - less
2503 | - lightningcss
2504 | - sass
2505 | - sass-embedded
2506 | - stylus
2507 | - sugarss
2508 | - supports-color
2509 | - terser
2510 | - tsx
2511 | - yaml
2512 |
2513 | vite@6.3.5(@types/node@20.19.0):
2514 | dependencies:
2515 | esbuild: 0.25.5
2516 | fdir: 6.4.5(picomatch@4.0.2)
2517 | picomatch: 4.0.2
2518 | postcss: 8.5.4
2519 | rollup: 4.42.0
2520 | tinyglobby: 0.2.14
2521 | optionalDependencies:
2522 | '@types/node': 20.19.0
2523 | fsevents: 2.3.3
2524 |
2525 | vitest@3.2.2(@types/node@20.19.0)(msw@2.10.1(@types/node@20.19.0)(typescript@5.8.3)):
2526 | dependencies:
2527 | '@types/chai': 5.2.2
2528 | '@vitest/expect': 3.2.2
2529 | '@vitest/mocker': 3.2.2(msw@2.10.1(@types/node@20.19.0)(typescript@5.8.3))(vite@6.3.5(@types/node@20.19.0))
2530 | '@vitest/pretty-format': 3.2.2
2531 | '@vitest/runner': 3.2.2
2532 | '@vitest/snapshot': 3.2.2
2533 | '@vitest/spy': 3.2.2
2534 | '@vitest/utils': 3.2.2
2535 | chai: 5.2.0
2536 | debug: 4.4.1
2537 | expect-type: 1.2.1
2538 | magic-string: 0.30.17
2539 | pathe: 2.0.3
2540 | picomatch: 4.0.2
2541 | std-env: 3.9.0
2542 | tinybench: 2.9.0
2543 | tinyexec: 0.3.2
2544 | tinyglobby: 0.2.14
2545 | tinypool: 1.1.0
2546 | tinyrainbow: 2.0.0
2547 | vite: 6.3.5(@types/node@20.19.0)
2548 | vite-node: 3.2.2(@types/node@20.19.0)
2549 | why-is-node-running: 2.3.0
2550 | optionalDependencies:
2551 | '@types/node': 20.19.0
2552 | transitivePeerDependencies:
2553 | - jiti
2554 | - less
2555 | - lightningcss
2556 | - msw
2557 | - sass
2558 | - sass-embedded
2559 | - stylus
2560 | - sugarss
2561 | - supports-color
2562 | - terser
2563 | - tsx
2564 | - yaml
2565 |
2566 | which@2.0.2:
2567 | dependencies:
2568 | isexe: 2.0.0
2569 |
2570 | why-is-node-running@2.3.0:
2571 | dependencies:
2572 | siginfo: 2.0.0
2573 | stackback: 0.0.2
2574 |
2575 | wrap-ansi@6.2.0:
2576 | dependencies:
2577 | ansi-styles: 4.3.0
2578 | string-width: 4.2.3
2579 | strip-ansi: 6.0.1
2580 |
2581 | wrap-ansi@7.0.0:
2582 | dependencies:
2583 | ansi-styles: 4.3.0
2584 | string-width: 4.2.3
2585 | strip-ansi: 6.0.1
2586 |
2587 | wrappy@1.0.2: {}
2588 |
2589 | y18n@5.0.8: {}
2590 |
2591 | yargs-parser@21.1.1: {}
2592 |
2593 | yargs@17.7.2:
2594 | dependencies:
2595 | cliui: 8.0.1
2596 | escalade: 3.1.2
2597 | get-caller-file: 2.0.5
2598 | require-directory: 2.1.1
2599 | string-width: 4.2.3
2600 | y18n: 5.0.8
2601 | yargs-parser: 21.1.1
2602 |
2603 | yocto-queue@0.1.0: {}
2604 |
2605 | yoctocolors-cjs@2.1.2: {}
2606 |
--------------------------------------------------------------------------------
/src/bake.ts:
--------------------------------------------------------------------------------
1 | import { DockerFlags } from './docker.js'
2 |
3 | type Bake = {
4 | target: {
5 | [target: string]: {
6 | // https://docs.docker.com/build/bake/reference/#target
7 | 'cache-from': string[]
8 | 'cache-to': string[]
9 | }
10 | }
11 | }
12 |
13 | export const generateBake = (target: string, flags: DockerFlags): Bake => ({
14 | target: {
15 | [target]: {
16 | 'cache-from': flags.cacheFrom,
17 | 'cache-to': flags.cacheTo,
18 | },
19 | },
20 | })
21 |
--------------------------------------------------------------------------------
/src/docker.ts:
--------------------------------------------------------------------------------
1 | export type CacheType = 'registry' | 'local' | 'inline' | 'gha' | 's3'
2 |
3 | type Inputs = {
4 | cacheType: CacheType
5 | cacheFromImageTag: string[]
6 | cacheToImageTag: string[]
7 | extraCacheFrom: string
8 | extraCacheTo: string
9 | }
10 |
11 | export type DockerFlags = {
12 | cacheFrom: string[]
13 | cacheTo: string[]
14 | }
15 |
16 | export const generateDockerFlags = (inputs: Inputs): DockerFlags => {
17 | const cacheType = `type=${inputs.cacheType}`
18 |
19 | const cacheFrom = inputs.cacheFromImageTag.map((tag) => {
20 | const cacheFrom = [cacheType, `ref=${tag}`]
21 | if (inputs.extraCacheFrom) {
22 | cacheFrom.push(inputs.extraCacheFrom)
23 | }
24 | return cacheFrom.join(',')
25 | })
26 |
27 | const cacheTo = inputs.cacheToImageTag.map((tag) => {
28 | const cacheTo = []
29 | cacheTo.push(cacheType, `ref=${tag}`, 'mode=max')
30 | if (inputs.extraCacheTo) {
31 | cacheTo.push(inputs.extraCacheTo)
32 | }
33 | return cacheTo.join(',')
34 | })
35 |
36 | return {
37 | cacheFrom,
38 | cacheTo,
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/src/github.ts:
--------------------------------------------------------------------------------
1 | import * as github from '@actions/github'
2 | import * as os from 'os'
3 |
4 | export type Octokit = ReturnType
5 |
6 | // For testability, use a subset of github.context in this module.
7 | export type Context = Pick
8 |
9 | export const getRunnerTemp = (): string => process.env.RUNNER_TEMP || os.tmpdir()
10 |
--------------------------------------------------------------------------------
/src/infer.ts:
--------------------------------------------------------------------------------
1 | import { IssueCommentEvent, PullRequestEvent, PushEvent } from '@octokit/webhooks-types'
2 | import { Context, Octokit } from './github.js'
3 |
4 | type Inputs = {
5 | image: string
6 | flavor: string[]
7 | pullRequestCache: boolean
8 | cacheKey: string[]
9 | cacheKeyFallback: string[]
10 | }
11 |
12 | type Cache = {
13 | from: string[]
14 | to: string[]
15 | }
16 |
17 | export const inferImageTags = async (octokit: Octokit, context: Context, inputs: Inputs): Promise => {
18 | const flavor = parseFlavor(inputs.flavor)
19 | const keys = await inferCacheKeys(octokit, context, inputs)
20 | return {
21 | from: unique(keys.from.map((from) => `${inputs.image}:${escape(`${flavor.prefix}${from}${flavor.suffix}`)}`)),
22 | to: unique(keys.to.map((to) => `${inputs.image}:${escape(`${flavor.prefix}${to}${flavor.suffix}`)}`)),
23 | }
24 | }
25 |
26 | const escape = (s: string) => s.replaceAll(/[/]/g, '-')
27 |
28 | const unique = (a: T[]) => [...new Set(a)]
29 |
30 | const parseFlavor = (flavor: string[]) => {
31 | let prefix = ''
32 | let suffix = ''
33 | for (const kv of flavor.flatMap((s) => s.split(/,/))) {
34 | const [k, v] = kv.trim().split(/=/, 2)
35 | if (k === 'prefix') {
36 | prefix = v
37 | }
38 | if (k === 'suffix') {
39 | suffix = v
40 | }
41 | }
42 | return { prefix, suffix }
43 | }
44 |
45 | const inferCacheKeys = async (octokit: Octokit, context: Context, inputs: Inputs): Promise => {
46 | switch (context.eventName) {
47 | case 'issue_comment':
48 | return inferIssueCommentBranch(octokit, context, inputs)
49 |
50 | case 'pull_request':
51 | return inferPullRequestBranch(context, inputs)
52 |
53 | case 'push':
54 | return inferPushBranch(context, inputs)
55 | }
56 |
57 | if (inputs.cacheKeyFallback.length > 0) {
58 | return {
59 | from: inputs.cacheKeyFallback,
60 | to: [],
61 | }
62 | }
63 | return {
64 | from: [trimPrefix(context.ref, 'refs/heads/')],
65 | to: [],
66 | }
67 | }
68 |
69 | const inferIssueCommentBranch = async (octokit: Octokit, context: Context, inputs: Inputs): Promise => {
70 | const payload = context.payload as IssueCommentEvent
71 | if (!payload.issue.pull_request?.url) {
72 | if (inputs.cacheKeyFallback.length > 0) {
73 | return {
74 | from: inputs.cacheKeyFallback,
75 | to: [],
76 | }
77 | }
78 | return {
79 | from: [payload.repository.default_branch],
80 | to: [],
81 | }
82 | }
83 |
84 | const { data: pull } = await octokit.rest.pulls.get({
85 | owner: context.repo.owner,
86 | repo: context.repo.repo,
87 | pull_number: context.issue.number,
88 | })
89 | return inferPullRequestData(pull, inputs)
90 | }
91 |
92 | const inferPullRequestBranch = (context: Context, inputs: Inputs): Cache => {
93 | const payload = context.payload as PullRequestEvent
94 | return inferPullRequestData(payload.pull_request, inputs)
95 | }
96 |
97 | type PullRequest = {
98 | base: {
99 | ref: string
100 | repo: { default_branch: string }
101 | }
102 | number: number
103 | }
104 |
105 | const inferPullRequestData = (pull: PullRequest, inputs: Inputs): Cache => {
106 | if (!inputs.pullRequestCache) {
107 | if (inputs.cacheKeyFallback.length > 0) {
108 | return {
109 | from: inputs.cacheKeyFallback,
110 | to: [],
111 | }
112 | }
113 | return {
114 | from: [pull.base.ref, pull.base.repo.default_branch],
115 | to: [],
116 | }
117 | }
118 |
119 | if (inputs.cacheKey.length > 0) {
120 | // When cache-key is given, an image tag does not correspond to a branch name.
121 | // Do not fallback to the base branch.
122 | return {
123 | from: [...inputs.cacheKey, ...inputs.cacheKeyFallback],
124 | to: inputs.cacheKey,
125 | }
126 | }
127 |
128 | const pullRequestKey = `pr-${pull.number}`
129 | if (inputs.cacheKeyFallback.length > 0) {
130 | return {
131 | from: [pullRequestKey, pull.base.ref, ...inputs.cacheKeyFallback],
132 | to: [pullRequestKey],
133 | }
134 | }
135 | return {
136 | from: [pullRequestKey, pull.base.ref, pull.base.repo.default_branch],
137 | to: [pullRequestKey],
138 | }
139 | }
140 |
141 | const inferPushBranch = (context: Context, inputs: Inputs): Cache => {
142 | // branch push
143 | if (context.ref.startsWith('refs/heads/')) {
144 | if (inputs.cacheKey.length > 0) {
145 | return {
146 | from: inputs.cacheKey,
147 | to: inputs.cacheKey,
148 | }
149 | }
150 | const branchName = trimPrefix(context.ref, 'refs/heads/')
151 | return {
152 | from: [branchName],
153 | to: [branchName],
154 | }
155 | }
156 |
157 | // tag push
158 | if (inputs.cacheKeyFallback.length > 0) {
159 | return {
160 | from: inputs.cacheKeyFallback,
161 | to: [],
162 | }
163 | }
164 | const payload = context.payload as PushEvent
165 | return {
166 | from: [payload.repository.default_branch],
167 | to: [],
168 | }
169 | }
170 |
171 | const trimPrefix = (s: string, prefix: string) => (s.startsWith(prefix) ? s.substring(prefix.length) : s)
172 |
--------------------------------------------------------------------------------
/src/main.ts:
--------------------------------------------------------------------------------
1 | import * as core from '@actions/core'
2 | import * as github from '@actions/github'
3 | import { run } from './run.js'
4 | import { CacheType } from './docker.js'
5 |
6 | const main = async (): Promise => {
7 | if (core.getInput('tag-prefix')) {
8 | throw new Error('tag-prefix is obsoleted, use flavor instead')
9 | }
10 | if (core.getInput('tag-suffix')) {
11 | throw new Error('tag-suffix is obsoleted, use flavor instead')
12 | }
13 |
14 | const outputs = await run({
15 | image: core.getInput('image', { required: true }),
16 | cacheType: core.getInput('cache-type', { required: true }) as CacheType,
17 | flavor: core.getMultilineInput('flavor'),
18 | pullRequestCache: core.getBooleanInput('pull-request-cache'),
19 | cacheKey: core.getMultilineInput('cache-key'),
20 | cacheKeyFallback: core.getMultilineInput('cache-key-fallback'),
21 | extraCacheFrom: core.getInput('extra-cache-from'),
22 | extraCacheTo: core.getInput('extra-cache-to'),
23 | bakeTarget: core.getInput('bake-target', { required: true }),
24 | context: github.context,
25 | octokit: github.getOctokit(core.getInput('token', { required: true })),
26 | })
27 | core.info(`Setting outputs: ${JSON.stringify(outputs, undefined, 2)}`)
28 | core.setOutput('cache-from', outputs.cacheFrom)
29 | core.setOutput('cache-to', outputs.cacheTo)
30 | core.setOutput('bake-file', outputs.bakeFile)
31 | }
32 |
33 | main().catch((e: Error) => {
34 | core.setFailed(e)
35 | console.error(e)
36 | })
37 |
--------------------------------------------------------------------------------
/src/run.ts:
--------------------------------------------------------------------------------
1 | import * as core from '@actions/core'
2 | import * as fs from 'fs/promises'
3 | import * as path from 'path'
4 | import { Context, getRunnerTemp, Octokit } from './github.js'
5 | import { inferImageTags } from './infer.js'
6 | import { CacheType, generateDockerFlags } from './docker.js'
7 | import { generateBake } from './bake.js'
8 |
9 | type Inputs = {
10 | image: string
11 | cacheType: CacheType
12 | flavor: string[]
13 | pullRequestCache: boolean
14 | cacheKey: string[]
15 | cacheKeyFallback: string[]
16 | extraCacheFrom: string
17 | extraCacheTo: string
18 | bakeTarget: string
19 | context: Context
20 | octokit: Octokit
21 | }
22 |
23 | type Outputs = {
24 | cacheFrom: string
25 | cacheTo: string
26 | bakeFile: string
27 | }
28 |
29 | export const run = async (inputs: Inputs): Promise => {
30 | const tags = await inferImageTags(inputs.octokit, inputs.context, {
31 | image: inputs.image,
32 | flavor: inputs.flavor,
33 | pullRequestCache: inputs.pullRequestCache,
34 | cacheKey: inputs.cacheKey,
35 | cacheKeyFallback: inputs.cacheKeyFallback,
36 | })
37 | core.info(`Inferred cache-from: ${tags.from.join(', ')}`)
38 | core.info(`Inferred cache-to: ${tags.to.join(', ')}`)
39 | const dockerFlags = generateDockerFlags({
40 | cacheType: inputs.cacheType,
41 | cacheFromImageTag: tags.from,
42 | cacheToImageTag: tags.to,
43 | extraCacheFrom: inputs.extraCacheFrom,
44 | extraCacheTo: inputs.extraCacheTo,
45 | })
46 |
47 | const bake = generateBake(inputs.bakeTarget, dockerFlags)
48 | core.startGroup('Bake file definition')
49 | core.info(JSON.stringify(bake, undefined, 2))
50 | core.endGroup()
51 |
52 | const tempDir = await fs.mkdtemp(path.join(getRunnerTemp(), 'docker-build-cache-config-action-'))
53 | const bakeFile = `${tempDir}/docker-build-cache-config-action-bake.json`
54 | await fs.writeFile(bakeFile, JSON.stringify(bake))
55 | return {
56 | cacheFrom: dockerFlags.cacheFrom.join('\n'),
57 | cacheTo: dockerFlags.cacheTo.join('\n'),
58 | bakeFile,
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/tests/docker.test.ts:
--------------------------------------------------------------------------------
1 | import { expect, test } from 'vitest'
2 | import { generateDockerFlags } from '../src/docker.js'
3 |
4 | test('both from and to', () => {
5 | const outputs = generateDockerFlags({
6 | cacheType: 'registry',
7 | cacheFromImageTag: ['ghcr.io/int128/sandbox/cache:main'],
8 | cacheToImageTag: ['ghcr.io/int128/sandbox/cache:main'],
9 | extraCacheFrom: '',
10 | extraCacheTo: '',
11 | })
12 | expect(outputs).toStrictEqual({
13 | cacheFrom: ['type=registry,ref=ghcr.io/int128/sandbox/cache:main'],
14 | cacheTo: ['type=registry,ref=ghcr.io/int128/sandbox/cache:main,mode=max'],
15 | })
16 | })
17 |
18 | test('only from', () => {
19 | const outputs = generateDockerFlags({
20 | cacheType: 'registry',
21 | cacheFromImageTag: ['ghcr.io/int128/sandbox/cache:main'],
22 | cacheToImageTag: [],
23 | extraCacheFrom: '',
24 | extraCacheTo: '',
25 | })
26 | expect(outputs).toStrictEqual({
27 | cacheFrom: ['type=registry,ref=ghcr.io/int128/sandbox/cache:main'],
28 | cacheTo: [],
29 | })
30 | })
31 |
32 | test('both from and to with extra args', () => {
33 | const outputs = generateDockerFlags({
34 | cacheType: 'registry',
35 | cacheFromImageTag: ['ghcr.io/int128/sandbox/cache:main'],
36 | cacheToImageTag: ['ghcr.io/int128/sandbox/cache:main'],
37 | extraCacheFrom: 'foo=bar',
38 | extraCacheTo: 'image-manifest=true',
39 | })
40 | expect(outputs).toStrictEqual({
41 | cacheFrom: ['type=registry,ref=ghcr.io/int128/sandbox/cache:main,foo=bar'],
42 | cacheTo: ['type=registry,ref=ghcr.io/int128/sandbox/cache:main,mode=max,image-manifest=true'],
43 | })
44 | })
45 |
46 | test('only from with extra args', () => {
47 | const outputs = generateDockerFlags({
48 | cacheType: 'registry',
49 | cacheFromImageTag: ['ghcr.io/int128/sandbox/cache:main'],
50 | cacheToImageTag: [],
51 | extraCacheFrom: 'foo=bar',
52 | extraCacheTo: 'image-manifest=true',
53 | })
54 | expect(outputs).toStrictEqual({
55 | cacheFrom: ['type=registry,ref=ghcr.io/int128/sandbox/cache:main,foo=bar'],
56 | cacheTo: [],
57 | })
58 | })
59 |
60 | test('both multiple from and to', () => {
61 | const outputs = generateDockerFlags({
62 | cacheType: 'registry',
63 | cacheFromImageTag: ['ghcr.io/int128/sandbox/cache:pr-1', 'ghcr.io/int128/sandbox/cache:main'],
64 | cacheToImageTag: ['ghcr.io/int128/sandbox/cache:pr-1'],
65 | extraCacheFrom: '',
66 | extraCacheTo: '',
67 | })
68 | expect(outputs).toStrictEqual({
69 | cacheFrom: [
70 | 'type=registry,ref=ghcr.io/int128/sandbox/cache:pr-1',
71 | 'type=registry,ref=ghcr.io/int128/sandbox/cache:main',
72 | ],
73 | cacheTo: ['type=registry,ref=ghcr.io/int128/sandbox/cache:pr-1,mode=max'],
74 | })
75 | })
76 |
77 | test('cache type', () => {
78 | const outputs = generateDockerFlags({
79 | cacheType: 'gha',
80 | cacheFromImageTag: ['ghcr.io/int128/sandbox/cache:pr-1', 'ghcr.io/int128/sandbox/cache:main'],
81 | cacheToImageTag: ['ghcr.io/int128/sandbox/cache:pr-1'],
82 | extraCacheFrom: '',
83 | extraCacheTo: '',
84 | })
85 | expect(outputs).toStrictEqual({
86 | cacheFrom: ['type=gha,ref=ghcr.io/int128/sandbox/cache:pr-1', 'type=gha,ref=ghcr.io/int128/sandbox/cache:main'],
87 | cacheTo: ['type=gha,ref=ghcr.io/int128/sandbox/cache:pr-1,mode=max'],
88 | })
89 | })
90 |
--------------------------------------------------------------------------------
/tests/fixture/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM debian:12-slim
2 | RUN env
3 |
--------------------------------------------------------------------------------
/tests/fixture/docker-bake.hcl:
--------------------------------------------------------------------------------
1 | target "docker-metadata-action" {}
2 |
3 | target "docker-build-cache-config-action" {}
4 |
5 | target "default" {
6 | inherits = ["docker-metadata-action", "docker-build-cache-config-action"]
7 | context = "."
8 | }
9 |
--------------------------------------------------------------------------------
/tests/github.ts:
--------------------------------------------------------------------------------
1 | import * as github from '@actions/github'
2 | import { setupServer } from 'msw/node'
3 | import { http, HttpResponse } from 'msw'
4 |
5 | export const server = setupServer(
6 | http.get('https://api.github.com/repos/int128/sandbox/pulls/1', () =>
7 | HttpResponse.json({
8 | base: {
9 | ref: 'main',
10 | repo: { default_branch: 'main' },
11 | },
12 | number: 1,
13 | }),
14 | ),
15 | http.get('https://api.github.com/repos/int128/sandbox/pulls/123', () =>
16 | HttpResponse.json({
17 | base: {
18 | ref: 'main',
19 | repo: { default_branch: 'main' },
20 | },
21 | number: 123,
22 | }),
23 | ),
24 | )
25 |
26 | export const getOctokit = () => github.getOctokit('GITHUB_TOKEN', { request: { fetch } })
27 |
--------------------------------------------------------------------------------
/tests/infer.test.ts:
--------------------------------------------------------------------------------
1 | import { expect, beforeAll, afterAll, afterEach, test } from 'vitest'
2 | import { inferImageTags } from '../src/infer.js'
3 | import { getOctokit, server } from './github.js'
4 |
5 | beforeAll(() => server.listen())
6 | afterEach(() => server.resetHandlers())
7 | afterAll(() => server.close())
8 |
9 | test.each([
10 | {
11 | description: 'default',
12 | inputs: {
13 | image: 'ghcr.io/int128/sandbox/cache',
14 | flavor: [],
15 | pullRequestCache: false,
16 | cacheKey: [],
17 | cacheKeyFallback: [],
18 | },
19 | expected: {
20 | from: ['ghcr.io/int128/sandbox/cache:main'],
21 | to: [],
22 | },
23 | },
24 | {
25 | description: 'pull-request-cache',
26 | inputs: {
27 | image: 'ghcr.io/int128/sandbox/cache',
28 | flavor: [],
29 | pullRequestCache: true,
30 | cacheKey: [],
31 | cacheKeyFallback: [],
32 | },
33 | expected: {
34 | from: ['ghcr.io/int128/sandbox/cache:pr-123', 'ghcr.io/int128/sandbox/cache:main'],
35 | to: ['ghcr.io/int128/sandbox/cache:pr-123'],
36 | },
37 | },
38 | {
39 | description: 'cache-key-fallback',
40 | inputs: {
41 | image: 'ghcr.io/int128/sandbox/cache',
42 | flavor: [],
43 | pullRequestCache: false,
44 | cacheKey: [],
45 | cacheKeyFallback: ['development'],
46 | },
47 | expected: {
48 | from: ['ghcr.io/int128/sandbox/cache:development'],
49 | to: [],
50 | },
51 | },
52 | {
53 | description: 'pull-request-cache and cache-key-fallback',
54 | inputs: {
55 | image: 'ghcr.io/int128/sandbox/cache',
56 | flavor: [],
57 | pullRequestCache: true,
58 | cacheKey: [],
59 | cacheKeyFallback: ['development'],
60 | },
61 | expected: {
62 | from: [
63 | 'ghcr.io/int128/sandbox/cache:pr-123',
64 | 'ghcr.io/int128/sandbox/cache:main',
65 | 'ghcr.io/int128/sandbox/cache:development',
66 | ],
67 | to: ['ghcr.io/int128/sandbox/cache:pr-123'],
68 | },
69 | },
70 | {
71 | description: 'pull-request-cache, cache-key and cache-key-fallback',
72 | inputs: {
73 | image: 'ghcr.io/int128/sandbox/cache',
74 | flavor: [],
75 | pullRequestCache: true,
76 | cacheKey: ['pull-request-123'],
77 | cacheKeyFallback: ['development'],
78 | },
79 | expected: {
80 | from: ['ghcr.io/int128/sandbox/cache:pull-request-123', 'ghcr.io/int128/sandbox/cache:development'],
81 | to: ['ghcr.io/int128/sandbox/cache:pull-request-123'],
82 | },
83 | },
84 | ])('on pull_request with $description', async ({ inputs, expected }) => {
85 | const tags = await inferImageTags(
86 | getOctokit(),
87 | {
88 | eventName: 'pull_request',
89 | ref: 'refs/pulls/123/merge',
90 | payload: {
91 | pull_request: {
92 | number: 123,
93 | base: {
94 | ref: 'main',
95 | repo: { default_branch: 'main' },
96 | },
97 | },
98 | },
99 | repo: { owner: 'int128', repo: 'sandbox' },
100 | issue: { owner: 'int128', repo: 'sandbox', number: 123 },
101 | },
102 | inputs,
103 | )
104 | expect(tags).toStrictEqual(expected)
105 | })
106 |
107 | test.each([
108 | {
109 | description: 'default',
110 | inputs: {
111 | image: 'ghcr.io/int128/sandbox/cache',
112 | flavor: [],
113 | pullRequestCache: false,
114 | cacheKey: [],
115 | cacheKeyFallback: [],
116 | },
117 | expected: {
118 | from: ['ghcr.io/int128/sandbox/cache:yet-another-base', 'ghcr.io/int128/sandbox/cache:main'],
119 | to: [],
120 | },
121 | },
122 | {
123 | description: 'pull-request-cache',
124 | inputs: {
125 | image: 'ghcr.io/int128/sandbox/cache',
126 | flavor: [],
127 | pullRequestCache: true,
128 | cacheKey: [],
129 | cacheKeyFallback: [],
130 | },
131 | expected: {
132 | from: [
133 | 'ghcr.io/int128/sandbox/cache:pr-123',
134 | 'ghcr.io/int128/sandbox/cache:yet-another-base',
135 | 'ghcr.io/int128/sandbox/cache:main',
136 | ],
137 | to: ['ghcr.io/int128/sandbox/cache:pr-123'],
138 | },
139 | },
140 | ])('on pull_request to non-default branch with $description', async ({ inputs, expected }) => {
141 | const tags = await inferImageTags(
142 | getOctokit(),
143 | {
144 | eventName: 'pull_request',
145 | ref: 'refs/pulls/123/merge',
146 | payload: {
147 | pull_request: {
148 | number: 123,
149 | base: {
150 | ref: 'yet-another-base',
151 | repo: { default_branch: 'main' },
152 | },
153 | },
154 | },
155 | repo: { owner: 'int128', repo: 'sandbox' },
156 | issue: { owner: 'int128', repo: 'sandbox', number: 123 },
157 | },
158 | inputs,
159 | )
160 | expect(tags).toStrictEqual(expected)
161 | })
162 |
163 | test.each([
164 | {
165 | description: 'default',
166 | inputs: {
167 | image: 'ghcr.io/int128/sandbox/cache',
168 | flavor: [],
169 | pullRequestCache: false,
170 | cacheKey: [],
171 | cacheKeyFallback: [],
172 | },
173 | expected: {
174 | from: ['ghcr.io/int128/sandbox/cache:main'],
175 | to: [],
176 | },
177 | },
178 | {
179 | description: 'pull-request-cache',
180 | inputs: {
181 | image: 'ghcr.io/int128/sandbox/cache',
182 | flavor: [],
183 | pullRequestCache: true,
184 | cacheKey: [],
185 | cacheKeyFallback: [],
186 | },
187 | expected: {
188 | from: ['ghcr.io/int128/sandbox/cache:pr-123', 'ghcr.io/int128/sandbox/cache:main'],
189 | to: ['ghcr.io/int128/sandbox/cache:pr-123'],
190 | },
191 | },
192 | ])('on issue_comment of pull request with $description', async ({ inputs, expected }) => {
193 | const tags = await inferImageTags(
194 | getOctokit(),
195 | {
196 | eventName: 'issue_comment',
197 | ref: 'refs/pulls/123/merge',
198 | payload: {
199 | issue: {
200 | number: 123,
201 | pull_request: {
202 | url: 'https://api.github.com/int128/sandbox/pulls/123',
203 | },
204 | },
205 | },
206 | repo: { owner: 'int128', repo: 'sandbox' },
207 | issue: { owner: 'int128', repo: 'sandbox', number: 123 },
208 | },
209 | inputs,
210 | )
211 | expect(tags).toStrictEqual(expected)
212 | })
213 |
214 | test.each([
215 | {
216 | description: 'default',
217 | inputs: {
218 | image: 'ghcr.io/int128/sandbox/cache',
219 | flavor: [],
220 | pullRequestCache: false,
221 | cacheKey: [],
222 | cacheKeyFallback: [],
223 | },
224 | expected: {
225 | from: ['ghcr.io/int128/sandbox/cache:main'],
226 | to: ['ghcr.io/int128/sandbox/cache:main'],
227 | },
228 | },
229 | {
230 | description: 'cache-key',
231 | inputs: {
232 | image: 'ghcr.io/int128/sandbox/cache',
233 | flavor: [],
234 | pullRequestCache: false,
235 | cacheKey: ['development'],
236 | cacheKeyFallback: [],
237 | },
238 | expected: {
239 | from: ['ghcr.io/int128/sandbox/cache:development'],
240 | to: ['ghcr.io/int128/sandbox/cache:development'],
241 | },
242 | },
243 | {
244 | description: 'prefix',
245 | inputs: {
246 | image: 'ghcr.io/int128/sandbox/cache',
247 | flavor: ['prefix=frontend--'],
248 | pullRequestCache: false,
249 | cacheKey: [],
250 | cacheKeyFallback: [],
251 | },
252 | expected: {
253 | from: ['ghcr.io/int128/sandbox/cache:frontend--main'],
254 | to: ['ghcr.io/int128/sandbox/cache:frontend--main'],
255 | },
256 | },
257 | {
258 | description: 'suffix',
259 | inputs: {
260 | image: 'ghcr.io/int128/sandbox/cache',
261 | flavor: ['suffix=-arm64'],
262 | pullRequestCache: false,
263 | cacheKey: [],
264 | cacheKeyFallback: [],
265 | },
266 | expected: {
267 | from: ['ghcr.io/int128/sandbox/cache:main-arm64'],
268 | to: ['ghcr.io/int128/sandbox/cache:main-arm64'],
269 | },
270 | },
271 | {
272 | description: 'prefix and suffix',
273 | inputs: {
274 | image: 'ghcr.io/int128/sandbox/cache',
275 | flavor: ['prefix=frontend--,suffix=-arm64'],
276 | pullRequestCache: false,
277 | cacheKey: [],
278 | cacheKeyFallback: [],
279 | },
280 | expected: {
281 | from: ['ghcr.io/int128/sandbox/cache:frontend--main-arm64'],
282 | to: ['ghcr.io/int128/sandbox/cache:frontend--main-arm64'],
283 | },
284 | },
285 | ])('on push branch with $description', async ({ inputs, expected }) => {
286 | const tags = await inferImageTags(
287 | getOctokit(),
288 | {
289 | eventName: 'push',
290 | ref: 'refs/heads/main',
291 | payload: {},
292 | repo: { owner: 'int128', repo: 'sandbox' },
293 | issue: { owner: 'int128', repo: 'sandbox', number: 0 },
294 | },
295 | inputs,
296 | )
297 | expect(tags).toStrictEqual(expected)
298 | })
299 |
300 | test('on push tag', async () => {
301 | const tags = await inferImageTags(
302 | getOctokit(),
303 | {
304 | eventName: 'push',
305 | ref: 'refs/tags/v1.0.0',
306 | payload: {
307 | repository: {
308 | name: 'sandbox',
309 | owner: { login: 'int128' },
310 | default_branch: 'main',
311 | },
312 | },
313 | repo: { owner: 'int128', repo: 'sandbox' },
314 | issue: { owner: 'int128', repo: 'sandbox', number: 0 },
315 | },
316 | {
317 | image: 'ghcr.io/int128/sandbox/cache',
318 | flavor: [],
319 | pullRequestCache: false,
320 | cacheKey: [],
321 | cacheKeyFallback: [],
322 | },
323 | )
324 | expect(tags).toStrictEqual({
325 | from: ['ghcr.io/int128/sandbox/cache:main'],
326 | to: [],
327 | })
328 | })
329 |
330 | test('on schedule', async () => {
331 | const tags = await inferImageTags(
332 | getOctokit(),
333 | {
334 | eventName: 'schedule',
335 | ref: 'refs/heads/main',
336 | payload: {},
337 | repo: { owner: 'int128', repo: 'sandbox' },
338 | issue: { owner: 'int128', repo: 'sandbox', number: 0 },
339 | },
340 | {
341 | image: 'ghcr.io/int128/sandbox/cache',
342 | flavor: [],
343 | pullRequestCache: false,
344 | cacheKey: [],
345 | cacheKeyFallback: [],
346 | },
347 | )
348 | expect(tags).toStrictEqual({
349 | from: ['ghcr.io/int128/sandbox/cache:main'],
350 | to: [],
351 | })
352 | })
353 |
--------------------------------------------------------------------------------
/tests/run.test.ts:
--------------------------------------------------------------------------------
1 | import { describe, expect, beforeAll, afterAll, afterEach, test } from 'vitest'
2 | import { run } from '../src/run.js'
3 | import { getOctokit, server } from './github.js'
4 |
5 | beforeAll(() => server.listen())
6 | afterEach(() => server.resetHandlers())
7 | afterAll(() => server.close())
8 |
9 | describe('Basic usage', () => {
10 | test('push event of main branch', async () => {
11 | const outputs = await run({
12 | image: 'ghcr.io/int128/sandbox/cache',
13 | cacheType: 'registry',
14 | flavor: [],
15 | pullRequestCache: false,
16 | extraCacheFrom: '',
17 | extraCacheTo: '',
18 | cacheKey: [],
19 | cacheKeyFallback: [],
20 | context: {
21 | eventName: 'push',
22 | ref: 'refs/heads/main',
23 | payload: {},
24 | repo: { owner: 'int128', repo: 'sandbox' },
25 | issue: { owner: 'int128', repo: 'sandbox', number: 0 },
26 | },
27 | bakeTarget: 'docker-build-cache-config-action',
28 | octokit: getOctokit(),
29 | })
30 | expect(outputs.cacheFrom).toBe('type=registry,ref=ghcr.io/int128/sandbox/cache:main')
31 | expect(outputs.cacheTo).toBe('type=registry,ref=ghcr.io/int128/sandbox/cache:main,mode=max')
32 | })
33 |
34 | test('pull_request event', async () => {
35 | const outputs = await run({
36 | image: 'ghcr.io/int128/sandbox/cache',
37 | cacheType: 'registry',
38 | flavor: [],
39 | pullRequestCache: false,
40 | extraCacheFrom: '',
41 | extraCacheTo: '',
42 | cacheKey: [],
43 | cacheKeyFallback: [],
44 | context: {
45 | eventName: 'pull_request',
46 | ref: 'refs/pull/1/merge',
47 | payload: {
48 | pull_request: {
49 | base: {
50 | ref: 'main',
51 | repo: { default_branch: 'main' },
52 | },
53 | number: 1,
54 | },
55 | },
56 | repo: { owner: 'int128', repo: 'sandbox' },
57 | issue: { owner: 'int128', repo: 'sandbox', number: 1 },
58 | },
59 | bakeTarget: 'docker-build-cache-config-action',
60 | octokit: getOctokit(),
61 | })
62 | expect(outputs.cacheFrom).toBe('type=registry,ref=ghcr.io/int128/sandbox/cache:main')
63 | expect(outputs.cacheTo).toBe('')
64 | })
65 |
66 | test('issue_comment event', async () => {
67 | const outputs = await run({
68 | image: 'ghcr.io/int128/sandbox/cache',
69 | cacheType: 'registry',
70 | flavor: [],
71 | pullRequestCache: false,
72 | extraCacheFrom: '',
73 | extraCacheTo: '',
74 | cacheKey: [],
75 | cacheKeyFallback: [],
76 | context: {
77 | eventName: 'issue_comment',
78 | ref: 'refs/heads/main',
79 | payload: {
80 | issue: {
81 | number: 1,
82 | pull_request: {
83 | url: 'https://api.github.com/repos/int128/sandbox/pulls/1',
84 | },
85 | },
86 | },
87 | repo: { owner: 'int128', repo: 'sandbox' },
88 | issue: { owner: 'int128', repo: 'sandbox', number: 1 },
89 | },
90 | bakeTarget: 'docker-build-cache-config-action',
91 | octokit: getOctokit(),
92 | })
93 | expect(outputs.cacheFrom).toBe('type=registry,ref=ghcr.io/int128/sandbox/cache:main')
94 | expect(outputs.cacheTo).toBe('')
95 | })
96 |
97 | test('schedule event', async () => {
98 | const outputs = await run({
99 | image: 'ghcr.io/int128/sandbox/cache',
100 | cacheType: 'registry',
101 | flavor: [],
102 | pullRequestCache: false,
103 | extraCacheFrom: '',
104 | extraCacheTo: '',
105 | cacheKey: [],
106 | cacheKeyFallback: [],
107 | context: {
108 | eventName: 'schedule',
109 | ref: 'refs/heads/main',
110 | payload: {},
111 | repo: { owner: 'int128', repo: 'sandbox' },
112 | issue: { owner: 'int128', repo: 'sandbox', number: 0 },
113 | },
114 | bakeTarget: 'docker-build-cache-config-action',
115 | octokit: getOctokit(),
116 | })
117 | expect(outputs.cacheFrom).toBe('type=registry,ref=ghcr.io/int128/sandbox/cache:main')
118 | expect(outputs.cacheTo).toBe('')
119 | })
120 | })
121 |
122 | describe('Import and export a pull request cache', () => {
123 | test('pull_request event', async () => {
124 | const outputs = await run({
125 | image: 'ghcr.io/int128/sandbox/cache',
126 | cacheType: 'registry',
127 | flavor: [],
128 | pullRequestCache: true,
129 | extraCacheFrom: '',
130 | extraCacheTo: '',
131 | cacheKey: [],
132 | cacheKeyFallback: [],
133 | context: {
134 | eventName: 'pull_request',
135 | ref: 'refs/pull/1/merge',
136 | payload: {
137 | pull_request: {
138 | base: {
139 | ref: 'main',
140 | repo: { default_branch: 'main' },
141 | },
142 | number: 1,
143 | },
144 | },
145 | repo: { owner: 'int128', repo: 'sandbox' },
146 | issue: { owner: 'int128', repo: 'sandbox', number: 1 },
147 | },
148 | bakeTarget: 'docker-build-cache-config-action',
149 | octokit: getOctokit(),
150 | })
151 | expect(outputs.cacheFrom).toBe(`\
152 | type=registry,ref=ghcr.io/int128/sandbox/cache:pr-1
153 | type=registry,ref=ghcr.io/int128/sandbox/cache:main`)
154 | expect(outputs.cacheTo).toBe('type=registry,ref=ghcr.io/int128/sandbox/cache:pr-1,mode=max')
155 | })
156 | })
157 |
158 | describe('Build multi-architecture images', () => {
159 | test('push event of main branch', async () => {
160 | const outputs = await run({
161 | image: 'ghcr.io/int128/sandbox/cache',
162 | cacheType: 'registry',
163 | flavor: ['suffix=-arm64'],
164 | pullRequestCache: false,
165 | extraCacheFrom: '',
166 | extraCacheTo: '',
167 | cacheKey: [],
168 | cacheKeyFallback: [],
169 | context: {
170 | eventName: 'push',
171 | ref: 'refs/heads/main',
172 | payload: {},
173 | repo: { owner: 'int128', repo: 'sandbox' },
174 | issue: { owner: 'int128', repo: 'sandbox', number: 0 },
175 | },
176 | bakeTarget: 'docker-build-cache-config-action',
177 | octokit: getOctokit(),
178 | })
179 | expect(outputs.cacheFrom).toBe('type=registry,ref=ghcr.io/int128/sandbox/cache:main-arm64')
180 | expect(outputs.cacheTo).toBe('type=registry,ref=ghcr.io/int128/sandbox/cache:main-arm64,mode=max')
181 | })
182 | })
183 |
184 | describe('For Amazon ECR', () => {
185 | test('push event of main branch', async () => {
186 | const outputs = await run({
187 | image: '123456789012.dkr.ecr.us-west-2.amazonaws.com/int128/sandbox',
188 | cacheType: 'registry',
189 | flavor: ['suffix=-cache'],
190 | pullRequestCache: false,
191 | extraCacheFrom: '',
192 | extraCacheTo: 'image-manifest=true',
193 | cacheKey: [],
194 | cacheKeyFallback: [],
195 | context: {
196 | eventName: 'push',
197 | ref: 'refs/heads/main',
198 | payload: {},
199 | repo: { owner: 'int128', repo: 'sandbox' },
200 | issue: { owner: 'int128', repo: 'sandbox', number: 0 },
201 | },
202 | bakeTarget: 'docker-build-cache-config-action',
203 | octokit: getOctokit(),
204 | })
205 | expect(outputs.cacheFrom).toBe(
206 | 'type=registry,ref=123456789012.dkr.ecr.us-west-2.amazonaws.com/int128/sandbox:main-cache',
207 | )
208 | expect(outputs.cacheTo).toBe(
209 | 'type=registry,ref=123456789012.dkr.ecr.us-west-2.amazonaws.com/int128/sandbox:main-cache,mode=max,image-manifest=true',
210 | )
211 | })
212 | })
213 |
214 | describe('Build multiple image tags from a branch', () => {
215 | test('push event of main branch', async () => {
216 | const outputs = await run({
217 | image: 'ghcr.io/int128/sandbox/cache',
218 | cacheType: 'registry',
219 | flavor: [],
220 | pullRequestCache: false,
221 | extraCacheFrom: '',
222 | extraCacheTo: '',
223 | cacheKey: ['staging'],
224 | cacheKeyFallback: ['development'],
225 | context: {
226 | eventName: 'push',
227 | ref: 'refs/heads/main',
228 | payload: {},
229 | repo: { owner: 'int128', repo: 'sandbox' },
230 | issue: { owner: 'int128', repo: 'sandbox', number: 0 },
231 | },
232 | bakeTarget: 'docker-build-cache-config-action',
233 | octokit: getOctokit(),
234 | })
235 | expect(outputs.cacheFrom).toBe('type=registry,ref=ghcr.io/int128/sandbox/cache:staging')
236 | expect(outputs.cacheTo).toBe('type=registry,ref=ghcr.io/int128/sandbox/cache:staging,mode=max')
237 | })
238 |
239 | test('pull_request event', async () => {
240 | const outputs = await run({
241 | image: 'ghcr.io/int128/sandbox/cache',
242 | cacheType: 'registry',
243 | flavor: [],
244 | pullRequestCache: false,
245 | extraCacheFrom: '',
246 | extraCacheTo: '',
247 | cacheKey: ['pull-request-1'],
248 | cacheKeyFallback: ['development'],
249 | context: {
250 | eventName: 'pull_request',
251 | ref: 'refs/pull/1/merge',
252 | payload: {
253 | pull_request: {
254 | base: {
255 | ref: 'main',
256 | repo: { default_branch: 'main' },
257 | },
258 | number: 1,
259 | },
260 | },
261 | repo: { owner: 'int128', repo: 'sandbox' },
262 | issue: { owner: 'int128', repo: 'sandbox', number: 1 },
263 | },
264 | bakeTarget: 'docker-build-cache-config-action',
265 | octokit: getOctokit(),
266 | })
267 | expect(outputs.cacheFrom).toBe('type=registry,ref=ghcr.io/int128/sandbox/cache:development')
268 | expect(outputs.cacheTo).toBe('')
269 | })
270 |
271 | test('schedule event', async () => {
272 | const outputs = await run({
273 | image: 'ghcr.io/int128/sandbox/cache',
274 | cacheType: 'registry',
275 | flavor: [],
276 | pullRequestCache: false,
277 | extraCacheFrom: '',
278 | extraCacheTo: '',
279 | cacheKey: ['staging'],
280 | cacheKeyFallback: ['development'],
281 | context: {
282 | eventName: 'schedule',
283 | ref: 'refs/heads/main',
284 | payload: {},
285 | repo: { owner: 'int128', repo: 'sandbox' },
286 | issue: { owner: 'int128', repo: 'sandbox', number: 0 },
287 | },
288 | bakeTarget: 'docker-build-cache-config-action',
289 | octokit: getOctokit(),
290 | })
291 | expect(outputs.cacheFrom).toBe('type=registry,ref=ghcr.io/int128/sandbox/cache:development')
292 | expect(outputs.cacheTo).toBe('')
293 | })
294 | })
295 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://json.schemastore.org/tsconfig",
3 | "extends": "@tsconfig/node20/tsconfig.json"
4 | }
5 |
--------------------------------------------------------------------------------
/vitest.config.ts:
--------------------------------------------------------------------------------
1 | import { defineConfig } from 'vitest/config'
2 |
3 | export default defineConfig({
4 | test: {
5 | clearMocks: true,
6 | },
7 | })
8 |
--------------------------------------------------------------------------------