├── .github ├── CODEOWNERS ├── composite-actions │ └── setup-node │ │ └── action.yml └── workflows │ ├── ci.yml │ └── dependency_review.yml ├── .gitignore ├── .node-version ├── CHANGELOG.md ├── LICENSE ├── README.md ├── biome.json ├── package.json ├── pnpm-lock.yaml ├── src ├── __tests__ │ └── urql-exhaustive-additional-typenames-exchange.test.ts └── index.ts └── tsconfig.json /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | * @MH4GF 2 | -------------------------------------------------------------------------------- /.github/composite-actions/setup-node/action.yml: -------------------------------------------------------------------------------- 1 | name: Setup Node 2 | 3 | runs: 4 | using: "composite" 5 | steps: 6 | - uses: pnpm/action-setup@a3252b78c470c02df07e9d59298aecedc3ccdd6d # v3.0.0 7 | with: 8 | version: 8 9 | - uses: actions/setup-node@v4 10 | with: 11 | node-version-file: ".node-version" 12 | cache: pnpm 13 | cache-dependency-path: "pnpm-lock.yaml" 14 | - run: npm run setup 15 | shell: bash 16 | - run: pnpm i 17 | shell: bash 18 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: ci 2 | 3 | on: 4 | pull_request: 5 | push: 6 | branches: 7 | - main 8 | 9 | jobs: 10 | lint: 11 | runs-on: ubuntu-latest 12 | steps: 13 | - uses: actions/checkout@v4 14 | - name: Setup Biome 15 | uses: biomejs/setup-biome@c016c38f26f2c4a6eb3662679143614a254263fd # v2.3.0 16 | with: 17 | version: latest 18 | - name: Run Biome 19 | run: biome ci . 20 | test: 21 | runs-on: ubuntu-latest 22 | steps: 23 | - uses: actions/checkout@v4 24 | - uses: ./.github/composite-actions/setup-node 25 | - run: pnpm test 26 | -------------------------------------------------------------------------------- /.github/workflows/dependency_review.yml: -------------------------------------------------------------------------------- 1 | name: Dependency Review 2 | 3 | on: [pull_request] 4 | 5 | permissions: 6 | contents: read 7 | pull-requests: write 8 | 9 | jobs: 10 | dependency_review: 11 | uses: route06/actions/.github/workflows/dependency_review.yml@v2 12 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dist 3 | -------------------------------------------------------------------------------- /.node-version: -------------------------------------------------------------------------------- 1 | 20.11.1 2 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | ## v0.1.1 4 | 5 | - Adjustment for publish package 6 | 7 | ## v0.1.0 8 | 9 | **Initial Release** 10 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2018 GitHub, Inc. and contributors 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in 14 | all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | THE SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # urql-exhaustive-additional-typenames-exchange 2 | 3 | [![npm version](https://badge.fury.io/js/urql-exhaustive-additional-typenames-exchange.svg)](https://badge.fury.io/js/urql-exhaustive-additional-typenames-exchange) 4 | [![ci](https://github.com/route06inc/urql-exhaustive-additional-typenames-exchange/actions/workflows/ci.yml/badge.svg)](https://github.com/route06inc/urql-exhaustive-additional-typenames-exchange/actions/workflows/ci.yml) 5 | 6 | `urql-exhaustive-additional-typenames-exchange` add all list fields in an operation to additionalTypenames. 7 | This is useful if your project is more about avoiding the risk of bugs from cache operations than cache efficiency. 8 | 9 | ## Motivation 10 | 11 | When working with the document cache, you need to consider which types to add to additionalTypenames. As mentioned in [Document Cache Gotchas](https://commerce.nearform.com/open-source/urql/docs/basics/document-caching/#document-cache-gotchas), in situations where the response data for a list field is empty, that type should be added. However, attempting to do this rigorously can make it difficult to enumerate the type correctly, as it is often only apparent at runtime. Therefore, the basic policy for this custom exchange is to "add all list fields in the operation to additionalTypenames". This approach may reduce cache efficiency, but we do not see this as a problem if the priority is to minimize the risk of bugs. 12 | 13 | related: https://github.com/urql-graphql/urql/discussions/3440 14 | 15 | ## Installation 16 | 17 | ```sh 18 | pnpm add urql-exhaustive-additional-typenames-exchange 19 | ``` 20 | 21 | ## Usage 22 | 23 | ```ts 24 | import { Client, cacheExchange, fetchExchange } from "urql"; 25 | import { exhaustiveAdditionalTypenamesExchange } from "urql-exhaustive-additional-typenames-exchange"; 26 | import schema from "./generated/minified.json"; 27 | 28 | const client = new Client({ 29 | url: "http://localhost:3000/graphql", 30 | exchanges: [ 31 | cacheExchange, 32 | exhaustiveAdditionalTypenamesExchange({ schema }), 33 | fetchExchange, 34 | ], 35 | }); 36 | ``` 37 | 38 | ### Providing schema 39 | 40 | You may have noticed that `schema` is passed. This exchange requires a schema definition to identify the types included in the operation at runtime. 41 | It is similar to that used in [Schema Awareness](https://commerce.nearform.com/open-source/urql/docs/graphcache/schema-awareness/) in GraphCache. 42 | 43 | Here is how to get a minified schema using [GraphQL Code Generator](https://the-guild.dev/graphql/codegen) and the [@urql/introspection](https://www.npmjs.com/package/@urql/introspection) package provided by urql. 44 | 45 | ```sh 46 | pnpm add -D @graphql-codegen/cli @graphql-codegen/introspection @urql/introspection 47 | ``` 48 | 49 | ```js 50 | //lib/minifyIntrospection.mjs 51 | 52 | #!/usr/bin/env node 53 | import { minifyIntrospectionQuery } from '@urql/introspection' 54 | import * as fs from 'fs' 55 | 56 | const main = () => { 57 | const json = fs.readFileSync('./generated/introspection.json', 'utf8') 58 | const minified = minifyIntrospectionQuery(JSON.parse(json)) 59 | 60 | fs.writeFileSync('./generated/minified.json', JSON.stringify(minified)) 61 | } 62 | 63 | main() 64 | ``` 65 | 66 | ```ts 67 | // codegen.ts 68 | import type { CodegenConfig } from "@graphql-codegen/cli"; 69 | 70 | const config: CodegenConfig = { 71 | schema: `http://localhost:3000/graphql`, 72 | generates: { 73 | ["/generated/introspection.json"]: { 74 | plugins: ["introspection"], 75 | config: { 76 | minify: true, 77 | }, 78 | hooks: { 79 | afterOneFileWrite: ["node lib/minifyIntrospection.mjs"], 80 | }, 81 | }, 82 | }, 83 | }; 84 | 85 | export default config; 86 | ``` 87 | 88 | ### Options 89 | 90 | | Input | Description | 91 | | ------ | ---------------------------------------------------------------- | 92 | | schema | A serialized GraphQL schema that is used by detect list fields. | 93 | | debug | If true, the detected list fields will be logged to the console. | 94 | 95 | ## Contributing 96 | 97 | If you'd like to contribute, please fork the repository and use a feature branch. Pull requests are warmly welcome. 98 | 99 | ## License 100 | 101 | MIT 102 | 103 | ## Related articles 104 | 105 | - [urqlのDocument Cachingを安全に運用する - ROUTE06 Tech Blog](https://tech.route06.co.jp/entry/2024/03/13/134852) 106 | -------------------------------------------------------------------------------- /biome.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "./node_modules/@biomejs/biome/configuration_schema.json", 3 | "organizeImports": { 4 | "enabled": true 5 | }, 6 | "linter": { 7 | "enabled": true, 8 | "rules": { 9 | "recommended": true 10 | } 11 | }, 12 | "formatter": { 13 | "enabled": true, 14 | "indentStyle": "space", 15 | "lineWidth": 80 16 | }, 17 | "javascript": { 18 | "formatter": { 19 | "semicolons": "asNeeded", 20 | "quoteStyle": "single", 21 | "trailingComma": "es5" 22 | } 23 | }, 24 | "vcs": { 25 | "enabled": true, 26 | "clientKind": "git", 27 | "useIgnoreFile": true 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "urql-exhaustive-additional-typenames-exchange", 3 | "description": "urql exchange that add all list fields in an operation to additionalTypenames", 4 | "version": "0.1.2", 5 | "license": "MIT", 6 | "sideEffects": false, 7 | "exports": { 8 | "require": "./dist/index.js", 9 | "import": "./dist/index.mjs", 10 | "types": "./dist/index.d.ts" 11 | }, 12 | "main": "./dist/index.js", 13 | "repository": { 14 | "type": "git", 15 | "url": "git+https://github.com/route06inc/urql-exhaustive-additional-typenames-exchange.git" 16 | }, 17 | "keywords": ["urql", "exchange", "graphql", "exchanges"], 18 | "files": ["LICENSE", "CHANGELOG.md", "README.md", "dist/"], 19 | "bugs": { 20 | "url": "https://github.com/route06inc/urql-exhaustive-additional-typenames-exchange/issues" 21 | }, 22 | "homepage": "https://github.com/route06inc/urql-exhaustive-additional-typenames-exchange", 23 | "publishConfig": { 24 | "access": "public" 25 | }, 26 | "scripts": { 27 | "setup": "corepack enable pnpm", 28 | "build": "tsup src/index.ts --format esm,cjs --dts", 29 | "test": "vitest", 30 | "lint": "biome check .", 31 | "format": "pnpm format:biome:format && pnpm format:biome:check", 32 | "format:biome:format": "biome format --write .", 33 | "format:biome:check": "biome check --apply ." 34 | }, 35 | "dependencies": { 36 | "@urql/core": ">=4.0.0", 37 | "@urql/exchange-context": ">=0.2.1" 38 | }, 39 | "devDependencies": { 40 | "@biomejs/biome": "1.6.1", 41 | "@types/node": "20.11.7", 42 | "tsup": "8.0.2", 43 | "typescript": "5.4.2", 44 | "vitest": "1.3.1" 45 | }, 46 | "peerDependencies": { 47 | "graphql": "^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0" 48 | }, 49 | "packageManager": "pnpm@8.15.4" 50 | } 51 | -------------------------------------------------------------------------------- /pnpm-lock.yaml: -------------------------------------------------------------------------------- 1 | lockfileVersion: '6.0' 2 | 3 | settings: 4 | autoInstallPeers: true 5 | excludeLinksFromLockfile: false 6 | 7 | dependencies: 8 | '@urql/core': 9 | specifier: '>=4.0.0' 10 | version: 4.2.2(graphql@16.8.1) 11 | '@urql/exchange-context': 12 | specifier: '>=0.2.1' 13 | version: 0.2.1(graphql@16.8.1) 14 | graphql: 15 | specifier: ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 16 | version: 16.8.1 17 | 18 | devDependencies: 19 | '@biomejs/biome': 20 | specifier: 1.6.1 21 | version: 1.6.1 22 | '@types/node': 23 | specifier: 20.11.7 24 | version: 20.11.7 25 | tsup: 26 | specifier: 8.0.2 27 | version: 8.0.2(typescript@5.4.2) 28 | typescript: 29 | specifier: 5.4.2 30 | version: 5.4.2 31 | vitest: 32 | specifier: 1.3.1 33 | version: 1.3.1(@types/node@20.11.7) 34 | 35 | packages: 36 | 37 | /@0no-co/graphql.web@1.0.4(graphql@16.8.1): 38 | resolution: {integrity: sha512-W3ezhHGfO0MS1PtGloaTpg0PbaT8aZSmmaerL7idtU5F7oCI+uu25k+MsMS31BVFlp4aMkHSrNRxiD72IlK8TA==} 39 | peerDependencies: 40 | graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 41 | peerDependenciesMeta: 42 | graphql: 43 | optional: true 44 | dependencies: 45 | graphql: 16.8.1 46 | dev: false 47 | 48 | /@biomejs/biome@1.6.1: 49 | resolution: {integrity: sha512-SILQvA2S0XeaOuu1bivv6fQmMo7zMfr2xqDEN+Sz78pGbAKZnGmg0emsXjQWoBY/RVm9kPCgX+aGEpZZTYaM7w==} 50 | engines: {node: '>=14.*'} 51 | hasBin: true 52 | requiresBuild: true 53 | optionalDependencies: 54 | '@biomejs/cli-darwin-arm64': 1.6.1 55 | '@biomejs/cli-darwin-x64': 1.6.1 56 | '@biomejs/cli-linux-arm64': 1.6.1 57 | '@biomejs/cli-linux-arm64-musl': 1.6.1 58 | '@biomejs/cli-linux-x64': 1.6.1 59 | '@biomejs/cli-linux-x64-musl': 1.6.1 60 | '@biomejs/cli-win32-arm64': 1.6.1 61 | '@biomejs/cli-win32-x64': 1.6.1 62 | dev: true 63 | 64 | /@biomejs/cli-darwin-arm64@1.6.1: 65 | resolution: {integrity: sha512-KlvY00iB9T/vFi4m/GXxEyYkYnYy6aw06uapzUIIdiMMj7I/pmZu7CsZlzWdekVD0j+SsQbxdZMsb0wPhnRSsg==} 66 | engines: {node: '>=14.*'} 67 | cpu: [arm64] 68 | os: [darwin] 69 | requiresBuild: true 70 | dev: true 71 | optional: true 72 | 73 | /@biomejs/cli-darwin-x64@1.6.1: 74 | resolution: {integrity: sha512-jP4E8TXaQX5e3nvRJSzB+qicZrdIDCrjR0sSb1DaDTx4JPZH5WXq/BlTqAyWi3IijM+IYMjWqAAK4kOHsSCzxw==} 75 | engines: {node: '>=14.*'} 76 | cpu: [x64] 77 | os: [darwin] 78 | requiresBuild: true 79 | dev: true 80 | optional: true 81 | 82 | /@biomejs/cli-linux-arm64-musl@1.6.1: 83 | resolution: {integrity: sha512-YdkDgFecdHJg7PJxAMaZIixVWGB6St4yH08BHagO0fEhNNiY8cAKEVo2mcXlsnEiTMpeSEAY9VxLUrVT3IVxpw==} 84 | engines: {node: '>=14.*'} 85 | cpu: [arm64] 86 | os: [linux] 87 | requiresBuild: true 88 | dev: true 89 | optional: true 90 | 91 | /@biomejs/cli-linux-arm64@1.6.1: 92 | resolution: {integrity: sha512-nxD1UyX3bWSl/RSKlib/JsOmt+652/9yieogdSC/UTLgVCZYOF7u8L/LK7kAa0Y4nA8zSPavAQTgko7mHC2ObA==} 93 | engines: {node: '>=14.*'} 94 | cpu: [arm64] 95 | os: [linux] 96 | requiresBuild: true 97 | dev: true 98 | optional: true 99 | 100 | /@biomejs/cli-linux-x64-musl@1.6.1: 101 | resolution: {integrity: sha512-aSISIDmxq04NNy7tm4x9rBk2vH0ub2VDIE4outEmdC2LBtEJoINiphlZagx/FvjbsqUfygent9QUSn0oREnAXg==} 102 | engines: {node: '>=14.*'} 103 | cpu: [x64] 104 | os: [linux] 105 | requiresBuild: true 106 | dev: true 107 | optional: true 108 | 109 | /@biomejs/cli-linux-x64@1.6.1: 110 | resolution: {integrity: sha512-BYAzenlMF3QdngjNFw9QVBXKGNzeecqwF3pwDgUGEvU7OJpn1/lyVkJVxYPtVGRNdjQ9e6l/s8NjKuBpW/ZR4Q==} 111 | engines: {node: '>=14.*'} 112 | cpu: [x64] 113 | os: [linux] 114 | requiresBuild: true 115 | dev: true 116 | optional: true 117 | 118 | /@biomejs/cli-win32-arm64@1.6.1: 119 | resolution: {integrity: sha512-/eCHQKZ1kEawUpkSuXq4urtxMsD1P1678OPG3zNKt3ru16AqqspLdO3jzBe3k74xCPYnQ36e9Yqc97Mo0qgPtg==} 120 | engines: {node: '>=14.*'} 121 | cpu: [arm64] 122 | os: [win32] 123 | requiresBuild: true 124 | dev: true 125 | optional: true 126 | 127 | /@biomejs/cli-win32-x64@1.6.1: 128 | resolution: {integrity: sha512-5TUZbzBwnDLFxLVGEPsorNi6eC2Gt+z4Oei9Qvq0M/4c4/mjZ96ABgwao/tMxf4ZBr/qyy2YdvF+gX9Rc+xC0A==} 129 | engines: {node: '>=14.*'} 130 | cpu: [x64] 131 | os: [win32] 132 | requiresBuild: true 133 | dev: true 134 | optional: true 135 | 136 | /@esbuild/aix-ppc64@0.19.12: 137 | resolution: {integrity: sha512-bmoCYyWdEL3wDQIVbcyzRyeKLgk2WtWLTWz1ZIAZF/EGbNOwSA6ew3PftJ1PqMiOOGu0OyFMzG53L0zqIpPeNA==} 138 | engines: {node: '>=12'} 139 | cpu: [ppc64] 140 | os: [aix] 141 | requiresBuild: true 142 | dev: true 143 | optional: true 144 | 145 | /@esbuild/android-arm64@0.19.12: 146 | resolution: {integrity: sha512-P0UVNGIienjZv3f5zq0DP3Nt2IE/3plFzuaS96vihvD0Hd6H/q4WXUGpCxD/E8YrSXfNyRPbpTq+T8ZQioSuPA==} 147 | engines: {node: '>=12'} 148 | cpu: [arm64] 149 | os: [android] 150 | requiresBuild: true 151 | dev: true 152 | optional: true 153 | 154 | /@esbuild/android-arm@0.19.12: 155 | resolution: {integrity: sha512-qg/Lj1mu3CdQlDEEiWrlC4eaPZ1KztwGJ9B6J+/6G+/4ewxJg7gqj8eVYWvao1bXrqGiW2rsBZFSX3q2lcW05w==} 156 | engines: {node: '>=12'} 157 | cpu: [arm] 158 | os: [android] 159 | requiresBuild: true 160 | dev: true 161 | optional: true 162 | 163 | /@esbuild/android-x64@0.19.12: 164 | resolution: {integrity: sha512-3k7ZoUW6Q6YqhdhIaq/WZ7HwBpnFBlW905Fa4s4qWJyiNOgT1dOqDiVAQFwBH7gBRZr17gLrlFCRzF6jFh7Kew==} 165 | engines: {node: '>=12'} 166 | cpu: [x64] 167 | os: [android] 168 | requiresBuild: true 169 | dev: true 170 | optional: true 171 | 172 | /@esbuild/darwin-arm64@0.19.12: 173 | resolution: {integrity: sha512-B6IeSgZgtEzGC42jsI+YYu9Z3HKRxp8ZT3cqhvliEHovq8HSX2YX8lNocDn79gCKJXOSaEot9MVYky7AKjCs8g==} 174 | engines: {node: '>=12'} 175 | cpu: [arm64] 176 | os: [darwin] 177 | requiresBuild: true 178 | dev: true 179 | optional: true 180 | 181 | /@esbuild/darwin-x64@0.19.12: 182 | resolution: {integrity: sha512-hKoVkKzFiToTgn+41qGhsUJXFlIjxI/jSYeZf3ugemDYZldIXIxhvwN6erJGlX4t5h417iFuheZ7l+YVn05N3A==} 183 | engines: {node: '>=12'} 184 | cpu: [x64] 185 | os: [darwin] 186 | requiresBuild: true 187 | dev: true 188 | optional: true 189 | 190 | /@esbuild/freebsd-arm64@0.19.12: 191 | resolution: {integrity: sha512-4aRvFIXmwAcDBw9AueDQ2YnGmz5L6obe5kmPT8Vd+/+x/JMVKCgdcRwH6APrbpNXsPz+K653Qg8HB/oXvXVukA==} 192 | engines: {node: '>=12'} 193 | cpu: [arm64] 194 | os: [freebsd] 195 | requiresBuild: true 196 | dev: true 197 | optional: true 198 | 199 | /@esbuild/freebsd-x64@0.19.12: 200 | resolution: {integrity: sha512-EYoXZ4d8xtBoVN7CEwWY2IN4ho76xjYXqSXMNccFSx2lgqOG/1TBPW0yPx1bJZk94qu3tX0fycJeeQsKovA8gg==} 201 | engines: {node: '>=12'} 202 | cpu: [x64] 203 | os: [freebsd] 204 | requiresBuild: true 205 | dev: true 206 | optional: true 207 | 208 | /@esbuild/linux-arm64@0.19.12: 209 | resolution: {integrity: sha512-EoTjyYyLuVPfdPLsGVVVC8a0p1BFFvtpQDB/YLEhaXyf/5bczaGeN15QkR+O4S5LeJ92Tqotve7i1jn35qwvdA==} 210 | engines: {node: '>=12'} 211 | cpu: [arm64] 212 | os: [linux] 213 | requiresBuild: true 214 | dev: true 215 | optional: true 216 | 217 | /@esbuild/linux-arm@0.19.12: 218 | resolution: {integrity: sha512-J5jPms//KhSNv+LO1S1TX1UWp1ucM6N6XuL6ITdKWElCu8wXP72l9MM0zDTzzeikVyqFE6U8YAV9/tFyj0ti+w==} 219 | engines: {node: '>=12'} 220 | cpu: [arm] 221 | os: [linux] 222 | requiresBuild: true 223 | dev: true 224 | optional: true 225 | 226 | /@esbuild/linux-ia32@0.19.12: 227 | resolution: {integrity: sha512-Thsa42rrP1+UIGaWz47uydHSBOgTUnwBwNq59khgIwktK6x60Hivfbux9iNR0eHCHzOLjLMLfUMLCypBkZXMHA==} 228 | engines: {node: '>=12'} 229 | cpu: [ia32] 230 | os: [linux] 231 | requiresBuild: true 232 | dev: true 233 | optional: true 234 | 235 | /@esbuild/linux-loong64@0.19.12: 236 | resolution: {integrity: sha512-LiXdXA0s3IqRRjm6rV6XaWATScKAXjI4R4LoDlvO7+yQqFdlr1Bax62sRwkVvRIrwXxvtYEHHI4dm50jAXkuAA==} 237 | engines: {node: '>=12'} 238 | cpu: [loong64] 239 | os: [linux] 240 | requiresBuild: true 241 | dev: true 242 | optional: true 243 | 244 | /@esbuild/linux-mips64el@0.19.12: 245 | resolution: {integrity: sha512-fEnAuj5VGTanfJ07ff0gOA6IPsvrVHLVb6Lyd1g2/ed67oU1eFzL0r9WL7ZzscD+/N6i3dWumGE1Un4f7Amf+w==} 246 | engines: {node: '>=12'} 247 | cpu: [mips64el] 248 | os: [linux] 249 | requiresBuild: true 250 | dev: true 251 | optional: true 252 | 253 | /@esbuild/linux-ppc64@0.19.12: 254 | resolution: {integrity: sha512-nYJA2/QPimDQOh1rKWedNOe3Gfc8PabU7HT3iXWtNUbRzXS9+vgB0Fjaqr//XNbd82mCxHzik2qotuI89cfixg==} 255 | engines: {node: '>=12'} 256 | cpu: [ppc64] 257 | os: [linux] 258 | requiresBuild: true 259 | dev: true 260 | optional: true 261 | 262 | /@esbuild/linux-riscv64@0.19.12: 263 | resolution: {integrity: sha512-2MueBrlPQCw5dVJJpQdUYgeqIzDQgw3QtiAHUC4RBz9FXPrskyyU3VI1hw7C0BSKB9OduwSJ79FTCqtGMWqJHg==} 264 | engines: {node: '>=12'} 265 | cpu: [riscv64] 266 | os: [linux] 267 | requiresBuild: true 268 | dev: true 269 | optional: true 270 | 271 | /@esbuild/linux-s390x@0.19.12: 272 | resolution: {integrity: sha512-+Pil1Nv3Umes4m3AZKqA2anfhJiVmNCYkPchwFJNEJN5QxmTs1uzyy4TvmDrCRNT2ApwSari7ZIgrPeUx4UZDg==} 273 | engines: {node: '>=12'} 274 | cpu: [s390x] 275 | os: [linux] 276 | requiresBuild: true 277 | dev: true 278 | optional: true 279 | 280 | /@esbuild/linux-x64@0.19.12: 281 | resolution: {integrity: sha512-B71g1QpxfwBvNrfyJdVDexenDIt1CiDN1TIXLbhOw0KhJzE78KIFGX6OJ9MrtC0oOqMWf+0xop4qEU8JrJTwCg==} 282 | engines: {node: '>=12'} 283 | cpu: [x64] 284 | os: [linux] 285 | requiresBuild: true 286 | dev: true 287 | optional: true 288 | 289 | /@esbuild/netbsd-x64@0.19.12: 290 | resolution: {integrity: sha512-3ltjQ7n1owJgFbuC61Oj++XhtzmymoCihNFgT84UAmJnxJfm4sYCiSLTXZtE00VWYpPMYc+ZQmB6xbSdVh0JWA==} 291 | engines: {node: '>=12'} 292 | cpu: [x64] 293 | os: [netbsd] 294 | requiresBuild: true 295 | dev: true 296 | optional: true 297 | 298 | /@esbuild/openbsd-x64@0.19.12: 299 | resolution: {integrity: sha512-RbrfTB9SWsr0kWmb9srfF+L933uMDdu9BIzdA7os2t0TXhCRjrQyCeOt6wVxr79CKD4c+p+YhCj31HBkYcXebw==} 300 | engines: {node: '>=12'} 301 | cpu: [x64] 302 | os: [openbsd] 303 | requiresBuild: true 304 | dev: true 305 | optional: true 306 | 307 | /@esbuild/sunos-x64@0.19.12: 308 | resolution: {integrity: sha512-HKjJwRrW8uWtCQnQOz9qcU3mUZhTUQvi56Q8DPTLLB+DawoiQdjsYq+j+D3s9I8VFtDr+F9CjgXKKC4ss89IeA==} 309 | engines: {node: '>=12'} 310 | cpu: [x64] 311 | os: [sunos] 312 | requiresBuild: true 313 | dev: true 314 | optional: true 315 | 316 | /@esbuild/win32-arm64@0.19.12: 317 | resolution: {integrity: sha512-URgtR1dJnmGvX864pn1B2YUYNzjmXkuJOIqG2HdU62MVS4EHpU2946OZoTMnRUHklGtJdJZ33QfzdjGACXhn1A==} 318 | engines: {node: '>=12'} 319 | cpu: [arm64] 320 | os: [win32] 321 | requiresBuild: true 322 | dev: true 323 | optional: true 324 | 325 | /@esbuild/win32-ia32@0.19.12: 326 | resolution: {integrity: sha512-+ZOE6pUkMOJfmxmBZElNOx72NKpIa/HFOMGzu8fqzQJ5kgf6aTGrcJaFsNiVMH4JKpMipyK+7k0n2UXN7a8YKQ==} 327 | engines: {node: '>=12'} 328 | cpu: [ia32] 329 | os: [win32] 330 | requiresBuild: true 331 | dev: true 332 | optional: true 333 | 334 | /@esbuild/win32-x64@0.19.12: 335 | resolution: {integrity: sha512-T1QyPSDCyMXaO3pzBkF96E8xMkiRYbUEZADd29SyPGabqxMViNoii+NcK7eWJAEoU6RZyEm5lVSIjTmcdoB9HA==} 336 | engines: {node: '>=12'} 337 | cpu: [x64] 338 | os: [win32] 339 | requiresBuild: true 340 | dev: true 341 | optional: true 342 | 343 | /@isaacs/cliui@8.0.2: 344 | resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} 345 | engines: {node: '>=12'} 346 | dependencies: 347 | string-width: 5.1.2 348 | string-width-cjs: /string-width@4.2.3 349 | strip-ansi: 7.1.0 350 | strip-ansi-cjs: /strip-ansi@6.0.1 351 | wrap-ansi: 8.1.0 352 | wrap-ansi-cjs: /wrap-ansi@7.0.0 353 | dev: true 354 | 355 | /@jest/schemas@29.6.3: 356 | resolution: {integrity: sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==} 357 | engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} 358 | dependencies: 359 | '@sinclair/typebox': 0.27.8 360 | dev: true 361 | 362 | /@jridgewell/gen-mapping@0.3.5: 363 | resolution: {integrity: sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==} 364 | engines: {node: '>=6.0.0'} 365 | dependencies: 366 | '@jridgewell/set-array': 1.2.1 367 | '@jridgewell/sourcemap-codec': 1.4.15 368 | '@jridgewell/trace-mapping': 0.3.25 369 | dev: true 370 | 371 | /@jridgewell/resolve-uri@3.1.2: 372 | resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} 373 | engines: {node: '>=6.0.0'} 374 | dev: true 375 | 376 | /@jridgewell/set-array@1.2.1: 377 | resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==} 378 | engines: {node: '>=6.0.0'} 379 | dev: true 380 | 381 | /@jridgewell/sourcemap-codec@1.4.15: 382 | resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==} 383 | dev: true 384 | 385 | /@jridgewell/trace-mapping@0.3.25: 386 | resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} 387 | dependencies: 388 | '@jridgewell/resolve-uri': 3.1.2 389 | '@jridgewell/sourcemap-codec': 1.4.15 390 | dev: true 391 | 392 | /@nodelib/fs.scandir@2.1.5: 393 | resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} 394 | engines: {node: '>= 8'} 395 | dependencies: 396 | '@nodelib/fs.stat': 2.0.5 397 | run-parallel: 1.2.0 398 | dev: true 399 | 400 | /@nodelib/fs.stat@2.0.5: 401 | resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} 402 | engines: {node: '>= 8'} 403 | dev: true 404 | 405 | /@nodelib/fs.walk@1.2.8: 406 | resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} 407 | engines: {node: '>= 8'} 408 | dependencies: 409 | '@nodelib/fs.scandir': 2.1.5 410 | fastq: 1.17.1 411 | dev: true 412 | 413 | /@pkgjs/parseargs@0.11.0: 414 | resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} 415 | engines: {node: '>=14'} 416 | requiresBuild: true 417 | dev: true 418 | optional: true 419 | 420 | /@rollup/rollup-android-arm-eabi@4.12.1: 421 | resolution: {integrity: sha512-iU2Sya8hNn1LhsYyf0N+L4Gf9Qc+9eBTJJJsaOGUp+7x4n2M9dxTt8UvhJl3oeftSjblSlpCfvjA/IfP3g5VjQ==} 422 | cpu: [arm] 423 | os: [android] 424 | requiresBuild: true 425 | dev: true 426 | optional: true 427 | 428 | /@rollup/rollup-android-arm64@4.12.1: 429 | resolution: {integrity: sha512-wlzcWiH2Ir7rdMELxFE5vuM7D6TsOcJ2Yw0c3vaBR3VOsJFVTx9xvwnAvhgU5Ii8Gd6+I11qNHwndDscIm0HXg==} 430 | cpu: [arm64] 431 | os: [android] 432 | requiresBuild: true 433 | dev: true 434 | optional: true 435 | 436 | /@rollup/rollup-darwin-arm64@4.12.1: 437 | resolution: {integrity: sha512-YRXa1+aZIFN5BaImK+84B3uNK8C6+ynKLPgvn29X9s0LTVCByp54TB7tdSMHDR7GTV39bz1lOmlLDuedgTwwHg==} 438 | cpu: [arm64] 439 | os: [darwin] 440 | requiresBuild: true 441 | dev: true 442 | optional: true 443 | 444 | /@rollup/rollup-darwin-x64@4.12.1: 445 | resolution: {integrity: sha512-opjWJ4MevxeA8FhlngQWPBOvVWYNPFkq6/25rGgG+KOy0r8clYwL1CFd+PGwRqqMFVQ4/Qd3sQu5t7ucP7C/Uw==} 446 | cpu: [x64] 447 | os: [darwin] 448 | requiresBuild: true 449 | dev: true 450 | optional: true 451 | 452 | /@rollup/rollup-linux-arm-gnueabihf@4.12.1: 453 | resolution: {integrity: sha512-uBkwaI+gBUlIe+EfbNnY5xNyXuhZbDSx2nzzW8tRMjUmpScd6lCQYKY2V9BATHtv5Ef2OBq6SChEP8h+/cxifQ==} 454 | cpu: [arm] 455 | os: [linux] 456 | requiresBuild: true 457 | dev: true 458 | optional: true 459 | 460 | /@rollup/rollup-linux-arm64-gnu@4.12.1: 461 | resolution: {integrity: sha512-0bK9aG1kIg0Su7OcFTlexkVeNZ5IzEsnz1ept87a0TUgZ6HplSgkJAnFpEVRW7GRcikT4GlPV0pbtVedOaXHQQ==} 462 | cpu: [arm64] 463 | os: [linux] 464 | requiresBuild: true 465 | dev: true 466 | optional: true 467 | 468 | /@rollup/rollup-linux-arm64-musl@4.12.1: 469 | resolution: {integrity: sha512-qB6AFRXuP8bdkBI4D7UPUbE7OQf7u5OL+R94JE42Z2Qjmyj74FtDdLGeriRyBDhm4rQSvqAGCGC01b8Fu2LthQ==} 470 | cpu: [arm64] 471 | os: [linux] 472 | requiresBuild: true 473 | dev: true 474 | optional: true 475 | 476 | /@rollup/rollup-linux-riscv64-gnu@4.12.1: 477 | resolution: {integrity: sha512-sHig3LaGlpNgDj5o8uPEoGs98RII8HpNIqFtAI8/pYABO8i0nb1QzT0JDoXF/pxzqO+FkxvwkHZo9k0NJYDedg==} 478 | cpu: [riscv64] 479 | os: [linux] 480 | requiresBuild: true 481 | dev: true 482 | optional: true 483 | 484 | /@rollup/rollup-linux-x64-gnu@4.12.1: 485 | resolution: {integrity: sha512-nD3YcUv6jBJbBNFvSbp0IV66+ba/1teuBcu+fBBPZ33sidxitc6ErhON3JNavaH8HlswhWMC3s5rgZpM4MtPqQ==} 486 | cpu: [x64] 487 | os: [linux] 488 | requiresBuild: true 489 | dev: true 490 | optional: true 491 | 492 | /@rollup/rollup-linux-x64-musl@4.12.1: 493 | resolution: {integrity: sha512-7/XVZqgBby2qp/cO0TQ8uJK+9xnSdJ9ct6gSDdEr4MfABrjTyrW6Bau7HQ73a2a5tPB7hno49A0y1jhWGDN9OQ==} 494 | cpu: [x64] 495 | os: [linux] 496 | requiresBuild: true 497 | dev: true 498 | optional: true 499 | 500 | /@rollup/rollup-win32-arm64-msvc@4.12.1: 501 | resolution: {integrity: sha512-CYc64bnICG42UPL7TrhIwsJW4QcKkIt9gGlj21gq3VV0LL6XNb1yAdHVp1pIi9gkts9gGcT3OfUYHjGP7ETAiw==} 502 | cpu: [arm64] 503 | os: [win32] 504 | requiresBuild: true 505 | dev: true 506 | optional: true 507 | 508 | /@rollup/rollup-win32-ia32-msvc@4.12.1: 509 | resolution: {integrity: sha512-LN+vnlZ9g0qlHGlS920GR4zFCqAwbv2lULrR29yGaWP9u7wF5L7GqWu9Ah6/kFZPXPUkpdZwd//TNR+9XC9hvA==} 510 | cpu: [ia32] 511 | os: [win32] 512 | requiresBuild: true 513 | dev: true 514 | optional: true 515 | 516 | /@rollup/rollup-win32-x64-msvc@4.12.1: 517 | resolution: {integrity: sha512-n+vkrSyphvmU0qkQ6QBNXCGr2mKjhP08mPRM/Xp5Ck2FV4NrHU+y6axzDeixUrCBHVUS51TZhjqrKBBsHLKb2Q==} 518 | cpu: [x64] 519 | os: [win32] 520 | requiresBuild: true 521 | dev: true 522 | optional: true 523 | 524 | /@sinclair/typebox@0.27.8: 525 | resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==} 526 | dev: true 527 | 528 | /@types/estree@1.0.5: 529 | resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==} 530 | dev: true 531 | 532 | /@types/node@20.11.7: 533 | resolution: {integrity: sha512-GPmeN1C3XAyV5uybAf4cMLWT9fDWcmQhZVtMFu7OR32WjrqGG+Wnk2V1d0bmtUyE/Zy1QJ9BxyiTih9z8Oks8A==} 534 | dependencies: 535 | undici-types: 5.26.5 536 | dev: true 537 | 538 | /@urql/core@4.2.2(graphql@16.8.1): 539 | resolution: {integrity: sha512-TP1kheq9bnrEdnVbJqh0g0ZY/wfdpPeAzjiiDK+Tm+Pbi0O1Xdu6+fUJ/wJo5QpHZzkIyya4/AecG63e6scFqQ==} 540 | dependencies: 541 | '@0no-co/graphql.web': 1.0.4(graphql@16.8.1) 542 | wonka: 6.3.4 543 | transitivePeerDependencies: 544 | - graphql 545 | dev: false 546 | 547 | /@urql/exchange-context@0.2.1(graphql@16.8.1): 548 | resolution: {integrity: sha512-DH65X7grIGDG5WEDQ3AIxSzW3eF+zpTRzHYUFpbcbjoQO+FzFM5X2oJofCbq5TqgrT9hMu8U2Y8qsGscmLkQhg==} 549 | dependencies: 550 | '@urql/core': 4.2.2(graphql@16.8.1) 551 | wonka: 6.3.4 552 | transitivePeerDependencies: 553 | - graphql 554 | dev: false 555 | 556 | /@vitest/expect@1.3.1: 557 | resolution: {integrity: sha512-xofQFwIzfdmLLlHa6ag0dPV8YsnKOCP1KdAeVVh34vSjN2dcUiXYCD9htu/9eM7t8Xln4v03U9HLxLpPlsXdZw==} 558 | dependencies: 559 | '@vitest/spy': 1.3.1 560 | '@vitest/utils': 1.3.1 561 | chai: 4.4.1 562 | dev: true 563 | 564 | /@vitest/runner@1.3.1: 565 | resolution: {integrity: sha512-5FzF9c3jG/z5bgCnjr8j9LNq/9OxV2uEBAITOXfoe3rdZJTdO7jzThth7FXv/6b+kdY65tpRQB7WaKhNZwX+Kg==} 566 | dependencies: 567 | '@vitest/utils': 1.3.1 568 | p-limit: 5.0.0 569 | pathe: 1.1.2 570 | dev: true 571 | 572 | /@vitest/snapshot@1.3.1: 573 | resolution: {integrity: sha512-EF++BZbt6RZmOlE3SuTPu/NfwBF6q4ABS37HHXzs2LUVPBLx2QoY/K0fKpRChSo8eLiuxcbCVfqKgx/dplCDuQ==} 574 | dependencies: 575 | magic-string: 0.30.8 576 | pathe: 1.1.2 577 | pretty-format: 29.7.0 578 | dev: true 579 | 580 | /@vitest/spy@1.3.1: 581 | resolution: {integrity: sha512-xAcW+S099ylC9VLU7eZfdT9myV67Nor9w9zhf0mGCYJSO+zM2839tOeROTdikOi/8Qeusffvxb/MyBSOja1Uig==} 582 | dependencies: 583 | tinyspy: 2.2.1 584 | dev: true 585 | 586 | /@vitest/utils@1.3.1: 587 | resolution: {integrity: sha512-d3Waie/299qqRyHTm2DjADeTaNdNSVsnwHPWrs20JMpjh6eiVq7ggggweO8rc4arhf6rRkWuHKwvxGvejUXZZQ==} 588 | dependencies: 589 | diff-sequences: 29.6.3 590 | estree-walker: 3.0.3 591 | loupe: 2.3.7 592 | pretty-format: 29.7.0 593 | dev: true 594 | 595 | /acorn-walk@8.3.2: 596 | resolution: {integrity: sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==} 597 | engines: {node: '>=0.4.0'} 598 | dev: true 599 | 600 | /acorn@8.11.3: 601 | resolution: {integrity: sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==} 602 | engines: {node: '>=0.4.0'} 603 | hasBin: true 604 | dev: true 605 | 606 | /ansi-regex@5.0.1: 607 | resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} 608 | engines: {node: '>=8'} 609 | dev: true 610 | 611 | /ansi-regex@6.0.1: 612 | resolution: {integrity: sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==} 613 | engines: {node: '>=12'} 614 | dev: true 615 | 616 | /ansi-styles@4.3.0: 617 | resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} 618 | engines: {node: '>=8'} 619 | dependencies: 620 | color-convert: 2.0.1 621 | dev: true 622 | 623 | /ansi-styles@5.2.0: 624 | resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==} 625 | engines: {node: '>=10'} 626 | dev: true 627 | 628 | /ansi-styles@6.2.1: 629 | resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} 630 | engines: {node: '>=12'} 631 | dev: true 632 | 633 | /any-promise@1.3.0: 634 | resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==} 635 | dev: true 636 | 637 | /anymatch@3.1.3: 638 | resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} 639 | engines: {node: '>= 8'} 640 | dependencies: 641 | normalize-path: 3.0.0 642 | picomatch: 2.3.1 643 | dev: true 644 | 645 | /array-union@2.1.0: 646 | resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} 647 | engines: {node: '>=8'} 648 | dev: true 649 | 650 | /assertion-error@1.1.0: 651 | resolution: {integrity: sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==} 652 | dev: true 653 | 654 | /balanced-match@1.0.2: 655 | resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} 656 | dev: true 657 | 658 | /binary-extensions@2.2.0: 659 | resolution: {integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==} 660 | engines: {node: '>=8'} 661 | dev: true 662 | 663 | /brace-expansion@2.0.1: 664 | resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} 665 | dependencies: 666 | balanced-match: 1.0.2 667 | dev: true 668 | 669 | /braces@3.0.2: 670 | resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==} 671 | engines: {node: '>=8'} 672 | dependencies: 673 | fill-range: 7.0.1 674 | dev: true 675 | 676 | /bundle-require@4.0.2(esbuild@0.19.12): 677 | resolution: {integrity: sha512-jwzPOChofl67PSTW2SGubV9HBQAhhR2i6nskiOThauo9dzwDUgOWQScFVaJkjEfYX+UXiD+LEx8EblQMc2wIag==} 678 | engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} 679 | peerDependencies: 680 | esbuild: '>=0.17' 681 | dependencies: 682 | esbuild: 0.19.12 683 | load-tsconfig: 0.2.5 684 | dev: true 685 | 686 | /cac@6.7.14: 687 | resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} 688 | engines: {node: '>=8'} 689 | dev: true 690 | 691 | /chai@4.4.1: 692 | resolution: {integrity: sha512-13sOfMv2+DWduEU+/xbun3LScLoqN17nBeTLUsmDfKdoiC1fr0n9PU4guu4AhRcOVFk/sW8LyZWHuhWtQZiF+g==} 693 | engines: {node: '>=4'} 694 | dependencies: 695 | assertion-error: 1.1.0 696 | check-error: 1.0.3 697 | deep-eql: 4.1.3 698 | get-func-name: 2.0.2 699 | loupe: 2.3.7 700 | pathval: 1.1.1 701 | type-detect: 4.0.8 702 | dev: true 703 | 704 | /check-error@1.0.3: 705 | resolution: {integrity: sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==} 706 | dependencies: 707 | get-func-name: 2.0.2 708 | dev: true 709 | 710 | /chokidar@3.6.0: 711 | resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} 712 | engines: {node: '>= 8.10.0'} 713 | dependencies: 714 | anymatch: 3.1.3 715 | braces: 3.0.2 716 | glob-parent: 5.1.2 717 | is-binary-path: 2.1.0 718 | is-glob: 4.0.3 719 | normalize-path: 3.0.0 720 | readdirp: 3.6.0 721 | optionalDependencies: 722 | fsevents: 2.3.3 723 | dev: true 724 | 725 | /color-convert@2.0.1: 726 | resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} 727 | engines: {node: '>=7.0.0'} 728 | dependencies: 729 | color-name: 1.1.4 730 | dev: true 731 | 732 | /color-name@1.1.4: 733 | resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} 734 | dev: true 735 | 736 | /commander@4.1.1: 737 | resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==} 738 | engines: {node: '>= 6'} 739 | dev: true 740 | 741 | /cross-spawn@7.0.3: 742 | resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} 743 | engines: {node: '>= 8'} 744 | dependencies: 745 | path-key: 3.1.1 746 | shebang-command: 2.0.0 747 | which: 2.0.2 748 | dev: true 749 | 750 | /debug@4.3.4: 751 | resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} 752 | engines: {node: '>=6.0'} 753 | peerDependencies: 754 | supports-color: '*' 755 | peerDependenciesMeta: 756 | supports-color: 757 | optional: true 758 | dependencies: 759 | ms: 2.1.2 760 | dev: true 761 | 762 | /deep-eql@4.1.3: 763 | resolution: {integrity: sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==} 764 | engines: {node: '>=6'} 765 | dependencies: 766 | type-detect: 4.0.8 767 | dev: true 768 | 769 | /diff-sequences@29.6.3: 770 | resolution: {integrity: sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==} 771 | engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} 772 | dev: true 773 | 774 | /dir-glob@3.0.1: 775 | resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} 776 | engines: {node: '>=8'} 777 | dependencies: 778 | path-type: 4.0.0 779 | dev: true 780 | 781 | /eastasianwidth@0.2.0: 782 | resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} 783 | dev: true 784 | 785 | /emoji-regex@8.0.0: 786 | resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} 787 | dev: true 788 | 789 | /emoji-regex@9.2.2: 790 | resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} 791 | dev: true 792 | 793 | /esbuild@0.19.12: 794 | resolution: {integrity: sha512-aARqgq8roFBj054KvQr5f1sFu0D65G+miZRCuJyJ0G13Zwx7vRar5Zhn2tkQNzIXcBrNVsv/8stehpj+GAjgbg==} 795 | engines: {node: '>=12'} 796 | hasBin: true 797 | requiresBuild: true 798 | optionalDependencies: 799 | '@esbuild/aix-ppc64': 0.19.12 800 | '@esbuild/android-arm': 0.19.12 801 | '@esbuild/android-arm64': 0.19.12 802 | '@esbuild/android-x64': 0.19.12 803 | '@esbuild/darwin-arm64': 0.19.12 804 | '@esbuild/darwin-x64': 0.19.12 805 | '@esbuild/freebsd-arm64': 0.19.12 806 | '@esbuild/freebsd-x64': 0.19.12 807 | '@esbuild/linux-arm': 0.19.12 808 | '@esbuild/linux-arm64': 0.19.12 809 | '@esbuild/linux-ia32': 0.19.12 810 | '@esbuild/linux-loong64': 0.19.12 811 | '@esbuild/linux-mips64el': 0.19.12 812 | '@esbuild/linux-ppc64': 0.19.12 813 | '@esbuild/linux-riscv64': 0.19.12 814 | '@esbuild/linux-s390x': 0.19.12 815 | '@esbuild/linux-x64': 0.19.12 816 | '@esbuild/netbsd-x64': 0.19.12 817 | '@esbuild/openbsd-x64': 0.19.12 818 | '@esbuild/sunos-x64': 0.19.12 819 | '@esbuild/win32-arm64': 0.19.12 820 | '@esbuild/win32-ia32': 0.19.12 821 | '@esbuild/win32-x64': 0.19.12 822 | dev: true 823 | 824 | /estree-walker@3.0.3: 825 | resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} 826 | dependencies: 827 | '@types/estree': 1.0.5 828 | dev: true 829 | 830 | /execa@5.1.1: 831 | resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==} 832 | engines: {node: '>=10'} 833 | dependencies: 834 | cross-spawn: 7.0.3 835 | get-stream: 6.0.1 836 | human-signals: 2.1.0 837 | is-stream: 2.0.1 838 | merge-stream: 2.0.0 839 | npm-run-path: 4.0.1 840 | onetime: 5.1.2 841 | signal-exit: 3.0.7 842 | strip-final-newline: 2.0.0 843 | dev: true 844 | 845 | /execa@8.0.1: 846 | resolution: {integrity: sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==} 847 | engines: {node: '>=16.17'} 848 | dependencies: 849 | cross-spawn: 7.0.3 850 | get-stream: 8.0.1 851 | human-signals: 5.0.0 852 | is-stream: 3.0.0 853 | merge-stream: 2.0.0 854 | npm-run-path: 5.3.0 855 | onetime: 6.0.0 856 | signal-exit: 4.1.0 857 | strip-final-newline: 3.0.0 858 | dev: true 859 | 860 | /fast-glob@3.3.2: 861 | resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==} 862 | engines: {node: '>=8.6.0'} 863 | dependencies: 864 | '@nodelib/fs.stat': 2.0.5 865 | '@nodelib/fs.walk': 1.2.8 866 | glob-parent: 5.1.2 867 | merge2: 1.4.1 868 | micromatch: 4.0.5 869 | dev: true 870 | 871 | /fastq@1.17.1: 872 | resolution: {integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==} 873 | dependencies: 874 | reusify: 1.0.4 875 | dev: true 876 | 877 | /fill-range@7.0.1: 878 | resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==} 879 | engines: {node: '>=8'} 880 | dependencies: 881 | to-regex-range: 5.0.1 882 | dev: true 883 | 884 | /foreground-child@3.1.1: 885 | resolution: {integrity: sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==} 886 | engines: {node: '>=14'} 887 | dependencies: 888 | cross-spawn: 7.0.3 889 | signal-exit: 4.1.0 890 | dev: true 891 | 892 | /fsevents@2.3.3: 893 | resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} 894 | engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} 895 | os: [darwin] 896 | requiresBuild: true 897 | dev: true 898 | optional: true 899 | 900 | /get-func-name@2.0.2: 901 | resolution: {integrity: sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==} 902 | dev: true 903 | 904 | /get-stream@6.0.1: 905 | resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} 906 | engines: {node: '>=10'} 907 | dev: true 908 | 909 | /get-stream@8.0.1: 910 | resolution: {integrity: sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==} 911 | engines: {node: '>=16'} 912 | dev: true 913 | 914 | /glob-parent@5.1.2: 915 | resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} 916 | engines: {node: '>= 6'} 917 | dependencies: 918 | is-glob: 4.0.3 919 | dev: true 920 | 921 | /glob@10.3.10: 922 | resolution: {integrity: sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==} 923 | engines: {node: '>=16 || 14 >=14.17'} 924 | hasBin: true 925 | dependencies: 926 | foreground-child: 3.1.1 927 | jackspeak: 2.3.6 928 | minimatch: 9.0.3 929 | minipass: 7.0.4 930 | path-scurry: 1.10.1 931 | dev: true 932 | 933 | /globby@11.1.0: 934 | resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} 935 | engines: {node: '>=10'} 936 | dependencies: 937 | array-union: 2.1.0 938 | dir-glob: 3.0.1 939 | fast-glob: 3.3.2 940 | ignore: 5.3.1 941 | merge2: 1.4.1 942 | slash: 3.0.0 943 | dev: true 944 | 945 | /graphql@16.8.1: 946 | resolution: {integrity: sha512-59LZHPdGZVh695Ud9lRzPBVTtlX9ZCV150Er2W43ro37wVof0ctenSaskPPjN7lVTIN8mSZt8PHUNKZuNQUuxw==} 947 | engines: {node: ^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0} 948 | dev: false 949 | 950 | /human-signals@2.1.0: 951 | resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==} 952 | engines: {node: '>=10.17.0'} 953 | dev: true 954 | 955 | /human-signals@5.0.0: 956 | resolution: {integrity: sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==} 957 | engines: {node: '>=16.17.0'} 958 | dev: true 959 | 960 | /ignore@5.3.1: 961 | resolution: {integrity: sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==} 962 | engines: {node: '>= 4'} 963 | dev: true 964 | 965 | /is-binary-path@2.1.0: 966 | resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} 967 | engines: {node: '>=8'} 968 | dependencies: 969 | binary-extensions: 2.2.0 970 | dev: true 971 | 972 | /is-extglob@2.1.1: 973 | resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} 974 | engines: {node: '>=0.10.0'} 975 | dev: true 976 | 977 | /is-fullwidth-code-point@3.0.0: 978 | resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} 979 | engines: {node: '>=8'} 980 | dev: true 981 | 982 | /is-glob@4.0.3: 983 | resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} 984 | engines: {node: '>=0.10.0'} 985 | dependencies: 986 | is-extglob: 2.1.1 987 | dev: true 988 | 989 | /is-number@7.0.0: 990 | resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} 991 | engines: {node: '>=0.12.0'} 992 | dev: true 993 | 994 | /is-stream@2.0.1: 995 | resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} 996 | engines: {node: '>=8'} 997 | dev: true 998 | 999 | /is-stream@3.0.0: 1000 | resolution: {integrity: sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==} 1001 | engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} 1002 | dev: true 1003 | 1004 | /isexe@2.0.0: 1005 | resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} 1006 | dev: true 1007 | 1008 | /jackspeak@2.3.6: 1009 | resolution: {integrity: sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==} 1010 | engines: {node: '>=14'} 1011 | dependencies: 1012 | '@isaacs/cliui': 8.0.2 1013 | optionalDependencies: 1014 | '@pkgjs/parseargs': 0.11.0 1015 | dev: true 1016 | 1017 | /joycon@3.1.1: 1018 | resolution: {integrity: sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==} 1019 | engines: {node: '>=10'} 1020 | dev: true 1021 | 1022 | /js-tokens@8.0.3: 1023 | resolution: {integrity: sha512-UfJMcSJc+SEXEl9lH/VLHSZbThQyLpw1vLO1Lb+j4RWDvG3N2f7yj3PVQA3cmkTBNldJ9eFnM+xEXxHIXrYiJw==} 1024 | dev: true 1025 | 1026 | /jsonc-parser@3.2.1: 1027 | resolution: {integrity: sha512-AilxAyFOAcK5wA1+LeaySVBrHsGQvUFCDWXKpZjzaL0PqW+xfBOttn8GNtWKFWqneyMZj41MWF9Kl6iPWLwgOA==} 1028 | dev: true 1029 | 1030 | /lilconfig@3.1.1: 1031 | resolution: {integrity: sha512-O18pf7nyvHTckunPWCV1XUNXU1piu01y2b7ATJ0ppkUkk8ocqVWBrYjJBCwHDjD/ZWcfyrA0P4gKhzWGi5EINQ==} 1032 | engines: {node: '>=14'} 1033 | dev: true 1034 | 1035 | /lines-and-columns@1.2.4: 1036 | resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} 1037 | dev: true 1038 | 1039 | /load-tsconfig@0.2.5: 1040 | resolution: {integrity: sha512-IXO6OCs9yg8tMKzfPZ1YmheJbZCiEsnBdcB03l0OcfK9prKnJb96siuHCr5Fl37/yo9DnKU+TLpxzTUspw9shg==} 1041 | engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} 1042 | dev: true 1043 | 1044 | /local-pkg@0.5.0: 1045 | resolution: {integrity: sha512-ok6z3qlYyCDS4ZEU27HaU6x/xZa9Whf8jD4ptH5UZTQYZVYeb9bnZ3ojVhiJNLiXK1Hfc0GNbLXcmZ5plLDDBg==} 1046 | engines: {node: '>=14'} 1047 | dependencies: 1048 | mlly: 1.6.1 1049 | pkg-types: 1.0.3 1050 | dev: true 1051 | 1052 | /lodash.sortby@4.7.0: 1053 | resolution: {integrity: sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==} 1054 | dev: true 1055 | 1056 | /loupe@2.3.7: 1057 | resolution: {integrity: sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==} 1058 | dependencies: 1059 | get-func-name: 2.0.2 1060 | dev: true 1061 | 1062 | /lru-cache@10.2.0: 1063 | resolution: {integrity: sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q==} 1064 | engines: {node: 14 || >=16.14} 1065 | dev: true 1066 | 1067 | /magic-string@0.30.8: 1068 | resolution: {integrity: sha512-ISQTe55T2ao7XtlAStud6qwYPZjE4GK1S/BeVPus4jrq6JuOnQ00YKQC581RWhR122W7msZV263KzVeLoqidyQ==} 1069 | engines: {node: '>=12'} 1070 | dependencies: 1071 | '@jridgewell/sourcemap-codec': 1.4.15 1072 | dev: true 1073 | 1074 | /merge-stream@2.0.0: 1075 | resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} 1076 | dev: true 1077 | 1078 | /merge2@1.4.1: 1079 | resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} 1080 | engines: {node: '>= 8'} 1081 | dev: true 1082 | 1083 | /micromatch@4.0.5: 1084 | resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==} 1085 | engines: {node: '>=8.6'} 1086 | dependencies: 1087 | braces: 3.0.2 1088 | picomatch: 2.3.1 1089 | dev: true 1090 | 1091 | /mimic-fn@2.1.0: 1092 | resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} 1093 | engines: {node: '>=6'} 1094 | dev: true 1095 | 1096 | /mimic-fn@4.0.0: 1097 | resolution: {integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==} 1098 | engines: {node: '>=12'} 1099 | dev: true 1100 | 1101 | /minimatch@9.0.3: 1102 | resolution: {integrity: sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==} 1103 | engines: {node: '>=16 || 14 >=14.17'} 1104 | dependencies: 1105 | brace-expansion: 2.0.1 1106 | dev: true 1107 | 1108 | /minipass@7.0.4: 1109 | resolution: {integrity: sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==} 1110 | engines: {node: '>=16 || 14 >=14.17'} 1111 | dev: true 1112 | 1113 | /mlly@1.6.1: 1114 | resolution: {integrity: sha512-vLgaHvaeunuOXHSmEbZ9izxPx3USsk8KCQ8iC+aTlp5sKRSoZvwhHh5L9VbKSaVC6sJDqbyohIS76E2VmHIPAA==} 1115 | dependencies: 1116 | acorn: 8.11.3 1117 | pathe: 1.1.2 1118 | pkg-types: 1.0.3 1119 | ufo: 1.4.0 1120 | dev: true 1121 | 1122 | /ms@2.1.2: 1123 | resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} 1124 | dev: true 1125 | 1126 | /mz@2.7.0: 1127 | resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} 1128 | dependencies: 1129 | any-promise: 1.3.0 1130 | object-assign: 4.1.1 1131 | thenify-all: 1.6.0 1132 | dev: true 1133 | 1134 | /nanoid@3.3.7: 1135 | resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==} 1136 | engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} 1137 | hasBin: true 1138 | dev: true 1139 | 1140 | /normalize-path@3.0.0: 1141 | resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} 1142 | engines: {node: '>=0.10.0'} 1143 | dev: true 1144 | 1145 | /npm-run-path@4.0.1: 1146 | resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} 1147 | engines: {node: '>=8'} 1148 | dependencies: 1149 | path-key: 3.1.1 1150 | dev: true 1151 | 1152 | /npm-run-path@5.3.0: 1153 | resolution: {integrity: sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==} 1154 | engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} 1155 | dependencies: 1156 | path-key: 4.0.0 1157 | dev: true 1158 | 1159 | /object-assign@4.1.1: 1160 | resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} 1161 | engines: {node: '>=0.10.0'} 1162 | dev: true 1163 | 1164 | /onetime@5.1.2: 1165 | resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} 1166 | engines: {node: '>=6'} 1167 | dependencies: 1168 | mimic-fn: 2.1.0 1169 | dev: true 1170 | 1171 | /onetime@6.0.0: 1172 | resolution: {integrity: sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==} 1173 | engines: {node: '>=12'} 1174 | dependencies: 1175 | mimic-fn: 4.0.0 1176 | dev: true 1177 | 1178 | /p-limit@5.0.0: 1179 | resolution: {integrity: sha512-/Eaoq+QyLSiXQ4lyYV23f14mZRQcXnxfHrN0vCai+ak9G0pp9iEQukIIZq5NccEvwRB8PUnZT0KsOoDCINS1qQ==} 1180 | engines: {node: '>=18'} 1181 | dependencies: 1182 | yocto-queue: 1.0.0 1183 | dev: true 1184 | 1185 | /path-key@3.1.1: 1186 | resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} 1187 | engines: {node: '>=8'} 1188 | dev: true 1189 | 1190 | /path-key@4.0.0: 1191 | resolution: {integrity: sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==} 1192 | engines: {node: '>=12'} 1193 | dev: true 1194 | 1195 | /path-scurry@1.10.1: 1196 | resolution: {integrity: sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==} 1197 | engines: {node: '>=16 || 14 >=14.17'} 1198 | dependencies: 1199 | lru-cache: 10.2.0 1200 | minipass: 7.0.4 1201 | dev: true 1202 | 1203 | /path-type@4.0.0: 1204 | resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} 1205 | engines: {node: '>=8'} 1206 | dev: true 1207 | 1208 | /pathe@1.1.2: 1209 | resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==} 1210 | dev: true 1211 | 1212 | /pathval@1.1.1: 1213 | resolution: {integrity: sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==} 1214 | dev: true 1215 | 1216 | /picocolors@1.0.0: 1217 | resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} 1218 | dev: true 1219 | 1220 | /picomatch@2.3.1: 1221 | resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} 1222 | engines: {node: '>=8.6'} 1223 | dev: true 1224 | 1225 | /pirates@4.0.6: 1226 | resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==} 1227 | engines: {node: '>= 6'} 1228 | dev: true 1229 | 1230 | /pkg-types@1.0.3: 1231 | resolution: {integrity: sha512-nN7pYi0AQqJnoLPC9eHFQ8AcyaixBUOwvqc5TDnIKCMEE6I0y8P7OKA7fPexsXGCGxQDl/cmrLAp26LhcwxZ4A==} 1232 | dependencies: 1233 | jsonc-parser: 3.2.1 1234 | mlly: 1.6.1 1235 | pathe: 1.1.2 1236 | dev: true 1237 | 1238 | /postcss-load-config@4.0.2: 1239 | resolution: {integrity: sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==} 1240 | engines: {node: '>= 14'} 1241 | peerDependencies: 1242 | postcss: '>=8.0.9' 1243 | ts-node: '>=9.0.0' 1244 | peerDependenciesMeta: 1245 | postcss: 1246 | optional: true 1247 | ts-node: 1248 | optional: true 1249 | dependencies: 1250 | lilconfig: 3.1.1 1251 | yaml: 2.4.1 1252 | dev: true 1253 | 1254 | /postcss@8.4.35: 1255 | resolution: {integrity: sha512-u5U8qYpBCpN13BsiEB0CbR1Hhh4Gc0zLFuedrHJKMctHCHAGrMdG0PRM/KErzAL3CU6/eckEtmHNB3x6e3c0vA==} 1256 | engines: {node: ^10 || ^12 || >=14} 1257 | dependencies: 1258 | nanoid: 3.3.7 1259 | picocolors: 1.0.0 1260 | source-map-js: 1.0.2 1261 | dev: true 1262 | 1263 | /pretty-format@29.7.0: 1264 | resolution: {integrity: sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==} 1265 | engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} 1266 | dependencies: 1267 | '@jest/schemas': 29.6.3 1268 | ansi-styles: 5.2.0 1269 | react-is: 18.2.0 1270 | dev: true 1271 | 1272 | /punycode@2.3.1: 1273 | resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} 1274 | engines: {node: '>=6'} 1275 | dev: true 1276 | 1277 | /queue-microtask@1.2.3: 1278 | resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} 1279 | dev: true 1280 | 1281 | /react-is@18.2.0: 1282 | resolution: {integrity: sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==} 1283 | dev: true 1284 | 1285 | /readdirp@3.6.0: 1286 | resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} 1287 | engines: {node: '>=8.10.0'} 1288 | dependencies: 1289 | picomatch: 2.3.1 1290 | dev: true 1291 | 1292 | /resolve-from@5.0.0: 1293 | resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} 1294 | engines: {node: '>=8'} 1295 | dev: true 1296 | 1297 | /reusify@1.0.4: 1298 | resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} 1299 | engines: {iojs: '>=1.0.0', node: '>=0.10.0'} 1300 | dev: true 1301 | 1302 | /rollup@4.12.1: 1303 | resolution: {integrity: sha512-ggqQKvx/PsB0FaWXhIvVkSWh7a/PCLQAsMjBc+nA2M8Rv2/HG0X6zvixAB7KyZBRtifBUhy5k8voQX/mRnABPg==} 1304 | engines: {node: '>=18.0.0', npm: '>=8.0.0'} 1305 | hasBin: true 1306 | dependencies: 1307 | '@types/estree': 1.0.5 1308 | optionalDependencies: 1309 | '@rollup/rollup-android-arm-eabi': 4.12.1 1310 | '@rollup/rollup-android-arm64': 4.12.1 1311 | '@rollup/rollup-darwin-arm64': 4.12.1 1312 | '@rollup/rollup-darwin-x64': 4.12.1 1313 | '@rollup/rollup-linux-arm-gnueabihf': 4.12.1 1314 | '@rollup/rollup-linux-arm64-gnu': 4.12.1 1315 | '@rollup/rollup-linux-arm64-musl': 4.12.1 1316 | '@rollup/rollup-linux-riscv64-gnu': 4.12.1 1317 | '@rollup/rollup-linux-x64-gnu': 4.12.1 1318 | '@rollup/rollup-linux-x64-musl': 4.12.1 1319 | '@rollup/rollup-win32-arm64-msvc': 4.12.1 1320 | '@rollup/rollup-win32-ia32-msvc': 4.12.1 1321 | '@rollup/rollup-win32-x64-msvc': 4.12.1 1322 | fsevents: 2.3.3 1323 | dev: true 1324 | 1325 | /run-parallel@1.2.0: 1326 | resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} 1327 | dependencies: 1328 | queue-microtask: 1.2.3 1329 | dev: true 1330 | 1331 | /shebang-command@2.0.0: 1332 | resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} 1333 | engines: {node: '>=8'} 1334 | dependencies: 1335 | shebang-regex: 3.0.0 1336 | dev: true 1337 | 1338 | /shebang-regex@3.0.0: 1339 | resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} 1340 | engines: {node: '>=8'} 1341 | dev: true 1342 | 1343 | /siginfo@2.0.0: 1344 | resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} 1345 | dev: true 1346 | 1347 | /signal-exit@3.0.7: 1348 | resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} 1349 | dev: true 1350 | 1351 | /signal-exit@4.1.0: 1352 | resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} 1353 | engines: {node: '>=14'} 1354 | dev: true 1355 | 1356 | /slash@3.0.0: 1357 | resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} 1358 | engines: {node: '>=8'} 1359 | dev: true 1360 | 1361 | /source-map-js@1.0.2: 1362 | resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==} 1363 | engines: {node: '>=0.10.0'} 1364 | dev: true 1365 | 1366 | /source-map@0.8.0-beta.0: 1367 | resolution: {integrity: sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==} 1368 | engines: {node: '>= 8'} 1369 | dependencies: 1370 | whatwg-url: 7.1.0 1371 | dev: true 1372 | 1373 | /stackback@0.0.2: 1374 | resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} 1375 | dev: true 1376 | 1377 | /std-env@3.7.0: 1378 | resolution: {integrity: sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg==} 1379 | dev: true 1380 | 1381 | /string-width@4.2.3: 1382 | resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} 1383 | engines: {node: '>=8'} 1384 | dependencies: 1385 | emoji-regex: 8.0.0 1386 | is-fullwidth-code-point: 3.0.0 1387 | strip-ansi: 6.0.1 1388 | dev: true 1389 | 1390 | /string-width@5.1.2: 1391 | resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} 1392 | engines: {node: '>=12'} 1393 | dependencies: 1394 | eastasianwidth: 0.2.0 1395 | emoji-regex: 9.2.2 1396 | strip-ansi: 7.1.0 1397 | dev: true 1398 | 1399 | /strip-ansi@6.0.1: 1400 | resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} 1401 | engines: {node: '>=8'} 1402 | dependencies: 1403 | ansi-regex: 5.0.1 1404 | dev: true 1405 | 1406 | /strip-ansi@7.1.0: 1407 | resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} 1408 | engines: {node: '>=12'} 1409 | dependencies: 1410 | ansi-regex: 6.0.1 1411 | dev: true 1412 | 1413 | /strip-final-newline@2.0.0: 1414 | resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==} 1415 | engines: {node: '>=6'} 1416 | dev: true 1417 | 1418 | /strip-final-newline@3.0.0: 1419 | resolution: {integrity: sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==} 1420 | engines: {node: '>=12'} 1421 | dev: true 1422 | 1423 | /strip-literal@2.0.0: 1424 | resolution: {integrity: sha512-f9vHgsCWBq2ugHAkGMiiYY+AYG0D/cbloKKg0nhaaaSNsujdGIpVXCNsrJpCKr5M0f4aI31mr13UjY6GAuXCKA==} 1425 | dependencies: 1426 | js-tokens: 8.0.3 1427 | dev: true 1428 | 1429 | /sucrase@3.35.0: 1430 | resolution: {integrity: sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==} 1431 | engines: {node: '>=16 || 14 >=14.17'} 1432 | hasBin: true 1433 | dependencies: 1434 | '@jridgewell/gen-mapping': 0.3.5 1435 | commander: 4.1.1 1436 | glob: 10.3.10 1437 | lines-and-columns: 1.2.4 1438 | mz: 2.7.0 1439 | pirates: 4.0.6 1440 | ts-interface-checker: 0.1.13 1441 | dev: true 1442 | 1443 | /thenify-all@1.6.0: 1444 | resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==} 1445 | engines: {node: '>=0.8'} 1446 | dependencies: 1447 | thenify: 3.3.1 1448 | dev: true 1449 | 1450 | /thenify@3.3.1: 1451 | resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==} 1452 | dependencies: 1453 | any-promise: 1.3.0 1454 | dev: true 1455 | 1456 | /tinybench@2.6.0: 1457 | resolution: {integrity: sha512-N8hW3PG/3aOoZAN5V/NSAEDz0ZixDSSt5b/a05iqtpgfLWMSVuCo7w0k2vVvEjdrIoeGqZzweX2WlyioNIHchA==} 1458 | dev: true 1459 | 1460 | /tinypool@0.8.2: 1461 | resolution: {integrity: sha512-SUszKYe5wgsxnNOVlBYO6IC+8VGWdVGZWAqUxp3UErNBtptZvWbwyUOyzNL59zigz2rCA92QiL3wvG+JDSdJdQ==} 1462 | engines: {node: '>=14.0.0'} 1463 | dev: true 1464 | 1465 | /tinyspy@2.2.1: 1466 | resolution: {integrity: sha512-KYad6Vy5VDWV4GH3fjpseMQ/XU2BhIYP7Vzd0LG44qRWm/Yt2WCOTicFdvmgo6gWaqooMQCawTtILVQJupKu7A==} 1467 | engines: {node: '>=14.0.0'} 1468 | dev: true 1469 | 1470 | /to-regex-range@5.0.1: 1471 | resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} 1472 | engines: {node: '>=8.0'} 1473 | dependencies: 1474 | is-number: 7.0.0 1475 | dev: true 1476 | 1477 | /tr46@1.0.1: 1478 | resolution: {integrity: sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA==} 1479 | dependencies: 1480 | punycode: 2.3.1 1481 | dev: true 1482 | 1483 | /tree-kill@1.2.2: 1484 | resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==} 1485 | hasBin: true 1486 | dev: true 1487 | 1488 | /ts-interface-checker@0.1.13: 1489 | resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} 1490 | dev: true 1491 | 1492 | /tsup@8.0.2(typescript@5.4.2): 1493 | resolution: {integrity: sha512-NY8xtQXdH7hDUAZwcQdY/Vzlw9johQsaqf7iwZ6g1DOUlFYQ5/AtVAjTvihhEyeRlGo4dLRVHtrRaL35M1daqQ==} 1494 | engines: {node: '>=18'} 1495 | hasBin: true 1496 | peerDependencies: 1497 | '@microsoft/api-extractor': ^7.36.0 1498 | '@swc/core': ^1 1499 | postcss: ^8.4.12 1500 | typescript: '>=4.5.0' 1501 | peerDependenciesMeta: 1502 | '@microsoft/api-extractor': 1503 | optional: true 1504 | '@swc/core': 1505 | optional: true 1506 | postcss: 1507 | optional: true 1508 | typescript: 1509 | optional: true 1510 | dependencies: 1511 | bundle-require: 4.0.2(esbuild@0.19.12) 1512 | cac: 6.7.14 1513 | chokidar: 3.6.0 1514 | debug: 4.3.4 1515 | esbuild: 0.19.12 1516 | execa: 5.1.1 1517 | globby: 11.1.0 1518 | joycon: 3.1.1 1519 | postcss-load-config: 4.0.2 1520 | resolve-from: 5.0.0 1521 | rollup: 4.12.1 1522 | source-map: 0.8.0-beta.0 1523 | sucrase: 3.35.0 1524 | tree-kill: 1.2.2 1525 | typescript: 5.4.2 1526 | transitivePeerDependencies: 1527 | - supports-color 1528 | - ts-node 1529 | dev: true 1530 | 1531 | /type-detect@4.0.8: 1532 | resolution: {integrity: sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==} 1533 | engines: {node: '>=4'} 1534 | dev: true 1535 | 1536 | /typescript@5.4.2: 1537 | resolution: {integrity: sha512-+2/g0Fds1ERlP6JsakQQDXjZdZMM+rqpamFZJEKh4kwTIn3iDkgKtby0CeNd5ATNZ4Ry1ax15TMx0W2V+miizQ==} 1538 | engines: {node: '>=14.17'} 1539 | hasBin: true 1540 | dev: true 1541 | 1542 | /ufo@1.4.0: 1543 | resolution: {integrity: sha512-Hhy+BhRBleFjpJ2vchUNN40qgkh0366FWJGqVLYBHev0vpHTrXSA0ryT+74UiW6KWsldNurQMKGqCm1M2zBciQ==} 1544 | dev: true 1545 | 1546 | /undici-types@5.26.5: 1547 | resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} 1548 | dev: true 1549 | 1550 | /vite-node@1.3.1(@types/node@20.11.7): 1551 | resolution: {integrity: sha512-azbRrqRxlWTJEVbzInZCTchx0X69M/XPTCz4H+TLvlTcR/xH/3hkRqhOakT41fMJCMzXTu4UvegkZiEoJAWvng==} 1552 | engines: {node: ^18.0.0 || >=20.0.0} 1553 | hasBin: true 1554 | dependencies: 1555 | cac: 6.7.14 1556 | debug: 4.3.4 1557 | pathe: 1.1.2 1558 | picocolors: 1.0.0 1559 | vite: 5.1.5(@types/node@20.11.7) 1560 | transitivePeerDependencies: 1561 | - '@types/node' 1562 | - less 1563 | - lightningcss 1564 | - sass 1565 | - stylus 1566 | - sugarss 1567 | - supports-color 1568 | - terser 1569 | dev: true 1570 | 1571 | /vite@5.1.5(@types/node@20.11.7): 1572 | resolution: {integrity: sha512-BdN1xh0Of/oQafhU+FvopafUp6WaYenLU/NFoL5WyJL++GxkNfieKzBhM24H3HVsPQrlAqB7iJYTHabzaRed5Q==} 1573 | engines: {node: ^18.0.0 || >=20.0.0} 1574 | hasBin: true 1575 | peerDependencies: 1576 | '@types/node': ^18.0.0 || >=20.0.0 1577 | less: '*' 1578 | lightningcss: ^1.21.0 1579 | sass: '*' 1580 | stylus: '*' 1581 | sugarss: '*' 1582 | terser: ^5.4.0 1583 | peerDependenciesMeta: 1584 | '@types/node': 1585 | optional: true 1586 | less: 1587 | optional: true 1588 | lightningcss: 1589 | optional: true 1590 | sass: 1591 | optional: true 1592 | stylus: 1593 | optional: true 1594 | sugarss: 1595 | optional: true 1596 | terser: 1597 | optional: true 1598 | dependencies: 1599 | '@types/node': 20.11.7 1600 | esbuild: 0.19.12 1601 | postcss: 8.4.35 1602 | rollup: 4.12.1 1603 | optionalDependencies: 1604 | fsevents: 2.3.3 1605 | dev: true 1606 | 1607 | /vitest@1.3.1(@types/node@20.11.7): 1608 | resolution: {integrity: sha512-/1QJqXs8YbCrfv/GPQ05wAZf2eakUPLPa18vkJAKE7RXOKfVHqMZZ1WlTjiwl6Gcn65M5vpNUB6EFLnEdRdEXQ==} 1609 | engines: {node: ^18.0.0 || >=20.0.0} 1610 | hasBin: true 1611 | peerDependencies: 1612 | '@edge-runtime/vm': '*' 1613 | '@types/node': ^18.0.0 || >=20.0.0 1614 | '@vitest/browser': 1.3.1 1615 | '@vitest/ui': 1.3.1 1616 | happy-dom: '*' 1617 | jsdom: '*' 1618 | peerDependenciesMeta: 1619 | '@edge-runtime/vm': 1620 | optional: true 1621 | '@types/node': 1622 | optional: true 1623 | '@vitest/browser': 1624 | optional: true 1625 | '@vitest/ui': 1626 | optional: true 1627 | happy-dom: 1628 | optional: true 1629 | jsdom: 1630 | optional: true 1631 | dependencies: 1632 | '@types/node': 20.11.7 1633 | '@vitest/expect': 1.3.1 1634 | '@vitest/runner': 1.3.1 1635 | '@vitest/snapshot': 1.3.1 1636 | '@vitest/spy': 1.3.1 1637 | '@vitest/utils': 1.3.1 1638 | acorn-walk: 8.3.2 1639 | chai: 4.4.1 1640 | debug: 4.3.4 1641 | execa: 8.0.1 1642 | local-pkg: 0.5.0 1643 | magic-string: 0.30.8 1644 | pathe: 1.1.2 1645 | picocolors: 1.0.0 1646 | std-env: 3.7.0 1647 | strip-literal: 2.0.0 1648 | tinybench: 2.6.0 1649 | tinypool: 0.8.2 1650 | vite: 5.1.5(@types/node@20.11.7) 1651 | vite-node: 1.3.1(@types/node@20.11.7) 1652 | why-is-node-running: 2.2.2 1653 | transitivePeerDependencies: 1654 | - less 1655 | - lightningcss 1656 | - sass 1657 | - stylus 1658 | - sugarss 1659 | - supports-color 1660 | - terser 1661 | dev: true 1662 | 1663 | /webidl-conversions@4.0.2: 1664 | resolution: {integrity: sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==} 1665 | dev: true 1666 | 1667 | /whatwg-url@7.1.0: 1668 | resolution: {integrity: sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==} 1669 | dependencies: 1670 | lodash.sortby: 4.7.0 1671 | tr46: 1.0.1 1672 | webidl-conversions: 4.0.2 1673 | dev: true 1674 | 1675 | /which@2.0.2: 1676 | resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} 1677 | engines: {node: '>= 8'} 1678 | hasBin: true 1679 | dependencies: 1680 | isexe: 2.0.0 1681 | dev: true 1682 | 1683 | /why-is-node-running@2.2.2: 1684 | resolution: {integrity: sha512-6tSwToZxTOcotxHeA+qGCq1mVzKR3CwcJGmVcY+QE8SHy6TnpFnh8PAvPNHYr7EcuVeG0QSMxtYCuO1ta/G/oA==} 1685 | engines: {node: '>=8'} 1686 | hasBin: true 1687 | dependencies: 1688 | siginfo: 2.0.0 1689 | stackback: 0.0.2 1690 | dev: true 1691 | 1692 | /wonka@6.3.4: 1693 | resolution: {integrity: sha512-CjpbqNtBGNAeyNS/9W6q3kSkKE52+FjIj7AkFlLr11s/VWGUu6a2CdYSdGxocIhIVjaW/zchesBQUKPVU69Cqg==} 1694 | dev: false 1695 | 1696 | /wrap-ansi@7.0.0: 1697 | resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} 1698 | engines: {node: '>=10'} 1699 | dependencies: 1700 | ansi-styles: 4.3.0 1701 | string-width: 4.2.3 1702 | strip-ansi: 6.0.1 1703 | dev: true 1704 | 1705 | /wrap-ansi@8.1.0: 1706 | resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} 1707 | engines: {node: '>=12'} 1708 | dependencies: 1709 | ansi-styles: 6.2.1 1710 | string-width: 5.1.2 1711 | strip-ansi: 7.1.0 1712 | dev: true 1713 | 1714 | /yaml@2.4.1: 1715 | resolution: {integrity: sha512-pIXzoImaqmfOrL7teGUBt/T7ZDnyeGBWyXQBvOVhLkWLN37GXv8NMLK406UY6dS51JfcQHsmcW5cJ441bHg6Lg==} 1716 | engines: {node: '>= 14'} 1717 | hasBin: true 1718 | dev: true 1719 | 1720 | /yocto-queue@1.0.0: 1721 | resolution: {integrity: sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==} 1722 | engines: {node: '>=12.20'} 1723 | dev: true 1724 | -------------------------------------------------------------------------------- /src/__tests__/urql-exhaustive-additional-typenames-exchange.test.ts: -------------------------------------------------------------------------------- 1 | import type { TypedDocumentNode } from '@urql/core' 2 | import { cacheExchange, createClient, fetchExchange, gql } from '@urql/core' 3 | import type { IntrospectionQuery } from 'graphql' 4 | import { buildSchema, getIntrospectionQuery, graphqlSync } from 'graphql' 5 | import { describe, expect, it } from 'vitest' 6 | 7 | import { exhaustiveAdditionalTypenamesExchange } from '..' 8 | 9 | const sdlString = /* GraphQL */ ` 10 | interface Node { 11 | id: ID! 12 | } 13 | 14 | type Post implements Node { 15 | id: ID! 16 | title: String! 17 | body: String! 18 | comments: [Comment!]! 19 | } 20 | 21 | type User implements Node { 22 | id: ID! 23 | name: String! 24 | posts: [Post!]! 25 | } 26 | 27 | type UserEdge { 28 | cursor: String! 29 | node: User 30 | } 31 | 32 | type UserConnection { 33 | edges: [UserEdge!]! 34 | nodes: [User!]! 35 | pageInfo: PageInfo! 36 | totalCount: Int! 37 | } 38 | 39 | type PageInfo { 40 | endCursor: String 41 | hasNextPage: Boolean! 42 | hasPreviousPage: Boolean! 43 | startCursor: String 44 | } 45 | 46 | interface Comment { 47 | body: String! 48 | likedBy: [User!]! 49 | } 50 | 51 | type PostComment implements Comment & Node { 52 | id: ID! 53 | title: String! 54 | body: String! 55 | likedBy: [User!]! 56 | } 57 | 58 | type Query { 59 | nodes: [Node!]! 60 | node(id: ID!): Node 61 | users: [User!]! 62 | nullableUsers: [User] 63 | userConnection( 64 | after: String 65 | before: String 66 | first: Int 67 | last: Int 68 | ): UserConnection! 69 | } 70 | ` 71 | 72 | // NOTE: graphqlSync()は返却型をGenericsで指定することができないため、asでキャストしている 73 | const introspection = graphqlSync({ 74 | schema: buildSchema(sdlString), 75 | source: getIntrospectionQuery(), 76 | }).data as unknown as IntrospectionQuery 77 | 78 | if (introspection == null) { 79 | throw new Error('introspection is undefined') 80 | } 81 | 82 | const client = createClient({ 83 | url: 'http://localhost:8000/graphql', 84 | exchanges: [ 85 | cacheExchange, 86 | exhaustiveAdditionalTypenamesExchange({ schema: introspection }), 87 | fetchExchange, 88 | ], 89 | suspense: true, 90 | }) 91 | 92 | const run = async (query: TypedDocumentNode) => { 93 | const { operation } = await client.query(query, {}).toPromise() 94 | return operation.context.additionalTypenames 95 | } 96 | 97 | describe('exhaustiveAdditionalTypenamesExchange', () => { 98 | it('enumerates the typenames contained in the list of SelectionSet', async () => { 99 | const queryGql = gql` 100 | query sampleQuery { 101 | users { 102 | id 103 | name 104 | } 105 | } 106 | ` 107 | const additionalTypenames = await run(queryGql) 108 | expect(additionalTypenames).toStrictEqual(['User']) 109 | }) 110 | 111 | it('enumerates the typenames in the nested list', async () => { 112 | const queryGql = gql` 113 | query sampleQuery { 114 | users { 115 | id 116 | posts { 117 | id 118 | title 119 | } 120 | } 121 | } 122 | ` 123 | const additionalTypenames = await run(queryGql) 124 | expect(additionalTypenames).toStrictEqual(['User', 'Post']) 125 | }) 126 | 127 | it('enumerates the typenames in nullable lists', async () => { 128 | const queryGql = gql` 129 | query sampleQuery { 130 | nullableUsers { 131 | id 132 | name 133 | } 134 | } 135 | ` 136 | const additionalTypenames = await run(queryGql) 137 | expect(additionalTypenames).toStrictEqual(['User']) 138 | }) 139 | 140 | it('enumerates the typenames contained in the list defined as Fragment', async () => { 141 | const queryGql = gql` 142 | fragment UserFragment on User { 143 | id 144 | name 145 | posts { 146 | title 147 | } 148 | } 149 | query sampleQuery { 150 | nullableUsers { 151 | ...UserFragment 152 | } 153 | } 154 | ` 155 | const additionalTypenames = await run(queryGql) 156 | expect(additionalTypenames).toStrictEqual(['User', 'Post']) 157 | }) 158 | 159 | it('enumerates the typenames with duplicates removed', async () => { 160 | const queryGql = gql` 161 | query sampleQuery { 162 | nullableUsers { 163 | name 164 | posts { 165 | title 166 | } 167 | } 168 | users { 169 | name 170 | } 171 | } 172 | ` 173 | const additionalTypenames = await run(queryGql) 174 | expect(additionalTypenames).toStrictEqual(['User', 'Post']) 175 | }) 176 | 177 | it('enumerates the typenames included in Connection type', async () => { 178 | const queryGql = gql` 179 | query sampleQuery { 180 | userConnection(first: 10) { 181 | edges { 182 | node { 183 | name 184 | } 185 | } 186 | nodes { 187 | name 188 | } 189 | } 190 | } 191 | ` 192 | const additionalTypenames = await run(queryGql) 193 | expect(additionalTypenames).toStrictEqual(['UserEdge', 'User']) 194 | }) 195 | 196 | it('enumerates the typenames contained in the inline fragment contained in the list defined as interface', async () => { 197 | const queryGql = gql` 198 | query sampleQuery { 199 | nodes { 200 | ... on User { 201 | name 202 | } 203 | ... on Post { 204 | body 205 | } 206 | } 207 | } 208 | ` 209 | const additionalTypenames = await run(queryGql) 210 | expect(additionalTypenames).toStrictEqual(['User', 'Post']) 211 | }) 212 | 213 | it('enumerates the typenames contained in the FragmentSpread contained in the interface', async () => { 214 | const queryGql = gql` 215 | fragment UserFragment on User { 216 | posts { 217 | body 218 | } 219 | } 220 | 221 | query sampleQuery { 222 | node(id: "1") { 223 | ... on User { 224 | ...UserFragment 225 | } 226 | } 227 | } 228 | ` 229 | const additionalTypenames = await run(queryGql) 230 | expect(additionalTypenames).toStrictEqual(['Post']) 231 | }) 232 | 233 | it('enumerates the typenames contained in the List contained in the interface, contained in the Inline fragment', async () => { 234 | const queryGql = gql` 235 | fragment PostFragment on Post { 236 | comments { 237 | likedBy { 238 | name 239 | } 240 | } 241 | } 242 | 243 | query sampleQuery { 244 | node(id: "1") { 245 | ... on Post { 246 | ...PostFragment 247 | } 248 | } 249 | } 250 | ` 251 | const additionalTypenames = await run(queryGql) 252 | expect(additionalTypenames).toStrictEqual(['User']) 253 | }) 254 | 255 | it('enumerates the typenames contained in the List contained in the Inline fragment with interface', async () => { 256 | const queryGql = gql` 257 | fragment CommentFragment on Comment { 258 | likedBy { 259 | name 260 | } 261 | } 262 | 263 | query sampleQuery { 264 | node(id: "1") { 265 | ... on Comment { 266 | ...CommentFragment 267 | } 268 | } 269 | } 270 | ` 271 | const additionalTypenames = await run(queryGql) 272 | expect(additionalTypenames).toStrictEqual(['User']) 273 | }) 274 | 275 | it('enumerates the typenames contained in the List contained in the FragmentSpread and InlineFragment', async () => { 276 | const queryGql = gql` 277 | fragment NodeFragment on Node { 278 | ... on User { 279 | name 280 | } 281 | 282 | ... on Post { 283 | body 284 | } 285 | } 286 | 287 | query sampleQuery { 288 | nodes { 289 | ...NodeFragment 290 | } 291 | } 292 | ` 293 | const additionalTypenames = await run(queryGql) 294 | expect(additionalTypenames).toStrictEqual(['User', 'Post']) 295 | }) 296 | 297 | it('enumerates the typenames with duplicates removed, including user-supplied additionalTypenames', async () => { 298 | const queryGql = gql` 299 | query sampleQuery { 300 | users { 301 | id 302 | name 303 | } 304 | } 305 | ` 306 | const { operation } = await client 307 | .query(queryGql, {}, { additionalTypenames: ['User', 'Post'] }) 308 | .toPromise() 309 | expect(operation.context.additionalTypenames).toStrictEqual([ 310 | 'User', 311 | 'Post', 312 | ]) 313 | }) 314 | }) 315 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | import type { Operation } from '@urql/core' 2 | import { contextExchange } from '@urql/exchange-context' 3 | import { 4 | GraphQLInterfaceType, 5 | GraphQLList, 6 | GraphQLNonNull, 7 | GraphQLObjectType, 8 | Kind, 9 | buildClientSchema, 10 | } from 'graphql' 11 | import type { 12 | FieldNode, 13 | FragmentDefinitionNode, 14 | FragmentSpreadNode, 15 | GraphQLField, 16 | GraphQLNamedType, 17 | GraphQLOutputType, 18 | GraphQLSchema, 19 | InlineFragmentNode, 20 | IntrospectionQuery, 21 | SelectionNode, 22 | } from 'graphql' 23 | 24 | /** 25 | * getFields() を呼び出せる型 26 | */ 27 | type TypeWithFields = GraphQLObjectType | GraphQLInterfaceType 28 | 29 | const isTypeWithFields = ( 30 | type: GraphQLNamedType | undefined 31 | ): type is TypeWithFields => { 32 | return ( 33 | type instanceof GraphQLObjectType || type instanceof GraphQLInterfaceType 34 | ) 35 | } 36 | 37 | /** 38 | * リスト型の判定 NonNullでラップされていることがある 39 | */ 40 | const isListType = ( 41 | type: GraphQLOutputType 42 | ): type is GraphQLList => { 43 | if (type instanceof GraphQLNonNull) { 44 | return isListType(type.ofType) 45 | } 46 | 47 | return type instanceof GraphQLList 48 | } 49 | 50 | /** 51 | * 52 | * GraphQLOutputType から GraphQLNamedType を取り出す 53 | * GraphQLOutputTypeには GraphQLList と GraphQLNonNull があるので、それを取り除きたい 54 | */ 55 | const getNamedType = (type: GraphQLOutputType): GraphQLNamedType => { 56 | if (type instanceof GraphQLNonNull || type instanceof GraphQLList) { 57 | return getNamedType(type.ofType) 58 | } 59 | return type 60 | } 61 | 62 | class AdditionalTypenamesDetector { 63 | private readonly schema: GraphQLSchema 64 | private readonly operation: Operation 65 | private readonly additionalTypenames: Set 66 | 67 | constructor(schema: GraphQLSchema, operation: Operation) { 68 | this.schema = schema 69 | this.operation = operation 70 | this.additionalTypenames = new Set(operation.context.additionalTypenames) 71 | } 72 | 73 | public getAdditionalTypenames(): string[] { 74 | const queryType = this.schema.getQueryType() 75 | if (!queryType) return [] 76 | 77 | for (const definition of this.operation.query.definitions) { 78 | if (definition.kind !== Kind.OPERATION_DEFINITION) continue 79 | 80 | for (const selection of definition.selectionSet.selections) { 81 | this.exploreSelections(selection, queryType, false) 82 | } 83 | } 84 | 85 | return Array.from(this.additionalTypenames) 86 | } 87 | 88 | private addListFieldToAdditionalTypenames( 89 | field: GraphQLField 90 | ) { 91 | if (!isListType(field.type)) return 92 | 93 | const fieldType = getNamedType(field.type.ofType) 94 | this.additionalTypenames.add(fieldType.name) 95 | } 96 | 97 | /** 98 | * 下記のような単純なフィールド定義を辿る 99 | * ```graphql 100 | * query { users { name } 101 | * ``` 102 | */ 103 | private exploreField(fieldNode: FieldNode, parentType: GraphQLNamedType) { 104 | if (!isTypeWithFields(parentType)) return 105 | 106 | const fieldName = fieldNode.name.value 107 | const field = parentType.getFields()[fieldName] 108 | if (!field) return 109 | 110 | const fieldType = getNamedType(field.type) 111 | if (!(fieldType instanceof GraphQLInterfaceType)) { 112 | this.addListFieldToAdditionalTypenames(field) 113 | } 114 | 115 | const fieldIsList = isListType(field.type) 116 | 117 | for (const s of fieldNode.selectionSet?.selections || []) { 118 | this.exploreSelections(s, fieldType, fieldIsList) 119 | } 120 | } 121 | 122 | /** 123 | * 下記のようなスプレッド構文のFragmentを辿る 124 | * ```graphql 125 | * fragment UserFragment on User { name } 126 | * query getUsers { users { ...UserFragment } } 127 | * ``` 128 | */ 129 | private exploreFragmentSpread( 130 | fragmentSpreadNode: FragmentSpreadNode, 131 | isList: boolean 132 | ) { 133 | const foundFragment = this.resolveFragment(fragmentSpreadNode.name.value) 134 | if (!foundFragment) return 135 | 136 | const fragmentOnType = this.schema.getType( 137 | foundFragment.typeCondition.name.value 138 | ) 139 | if (!isTypeWithFields(fragmentOnType)) return 140 | 141 | for (const s of foundFragment.selectionSet?.selections || []) { 142 | this.exploreSelections(s, fragmentOnType, isList) 143 | } 144 | } 145 | 146 | /** 147 | * 下記のようなインラインのFragmentを辿る 148 | * ```graphql 149 | * query { node(id: "1") { ... on User { name } } } 150 | * ``` 151 | */ 152 | private exploreInlineFragment( 153 | inlineFragmentNode: InlineFragmentNode, 154 | isList: boolean 155 | ) { 156 | if (inlineFragmentNode.typeCondition?.name.value === undefined) return 157 | 158 | const fieldType = this.schema.getType( 159 | inlineFragmentNode.typeCondition.name.value 160 | ) 161 | if (!isTypeWithFields(fieldType)) return 162 | 163 | if (isList) { 164 | this.additionalTypenames.add(fieldType.name) 165 | } 166 | 167 | for (const s of inlineFragmentNode.selectionSet?.selections || []) { 168 | this.exploreSelections(s, fieldType, false) 169 | } 170 | } 171 | 172 | private exploreSelections( 173 | selectionNode: SelectionNode, 174 | parentType: GraphQLNamedType, 175 | isList: boolean 176 | ) { 177 | switch (selectionNode.kind) { 178 | case 'Field': 179 | this.exploreField(selectionNode, parentType) 180 | break 181 | case 'FragmentSpread': 182 | this.exploreFragmentSpread(selectionNode, isList) 183 | break 184 | case 'InlineFragment': 185 | this.exploreInlineFragment(selectionNode, isList) 186 | break 187 | } 188 | } 189 | 190 | private resolveFragment( 191 | fragmentName: string 192 | ): FragmentDefinitionNode | undefined { 193 | const fragments = this.operation.query.definitions.filter( 194 | (definition) => definition.kind === Kind.FRAGMENT_DEFINITION 195 | ) as FragmentDefinitionNode[] 196 | const fragmentMap = new Map( 197 | fragments.map((definition) => [definition.name.value, definition]) 198 | ) 199 | return fragmentMap.get(fragmentName) 200 | } 201 | } 202 | 203 | // urqlのgraphcacheで定義している型を参考 204 | // @see: https://github.com/urql-graphql/urql/blob/8ff4e3e449b7eece8a64566f54b04dfdb534eccb/exchanges/graphcache/src/ast/schema.ts?plain=1#L42 205 | interface PartialIntrospectionSchema { 206 | queryType: { name: string; kind?: unknown } 207 | mutationType?: { name: string; kind?: unknown } | null 208 | subscriptionType?: { name: string; kind?: unknown } | null 209 | types?: readonly unknown[] 210 | } 211 | 212 | type IntrospectionData = 213 | | IntrospectionQuery 214 | | { __schema: PartialIntrospectionSchema } 215 | 216 | type ExhaustiveAdditionalTypenamesExchangeOptions = { 217 | /** 218 | * A serialized GraphQL schema that is used by detect list fields. 219 | */ 220 | schema: IntrospectionData 221 | /** 222 | * If true, the detected list fields will be logged to the console. 223 | */ 224 | debug?: boolean 225 | } 226 | 227 | export const exhaustiveAdditionalTypenamesExchange = ({ 228 | schema: _schema, 229 | debug, 230 | }: ExhaustiveAdditionalTypenamesExchangeOptions) => { 231 | // PartialIntrospectionSchemaなので型は合わない 232 | // ちゃんとやるならurqlのgraphcacheのようにbuildClientSchemaを自前で実装する必要がある 233 | // @see: https://github.com/urql-graphql/urql/blob/8ff4e3e449b7eece8a64566f54b04dfdb534eccb/exchanges/graphcache/src/ast/schema.ts?plain=1#L46 234 | // @ts-expect-error 235 | const schema = buildClientSchema(_schema) 236 | 237 | return contextExchange({ 238 | getContext: (operation) => { 239 | const detector = new AdditionalTypenamesDetector(schema, operation) 240 | const additionalTypenames = detector.getAdditionalTypenames() 241 | 242 | if (debug) { 243 | console.info('[DEBUG] exhaustiveAdditionalTypenamesExchange:', { 244 | operation, 245 | additionalTypenames, 246 | }) 247 | } 248 | 249 | return { 250 | ...operation.context, 251 | additionalTypenames, 252 | } 253 | }, 254 | }) 255 | } 256 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json.schemastore.org/tsconfig", 3 | "compilerOptions": { 4 | "strict": true, 5 | "allowUnusedLabels": false, 6 | "allowUnreachableCode": false, 7 | "exactOptionalPropertyTypes": true, 8 | "noFallthroughCasesInSwitch": true, 9 | "noImplicitOverride": true, 10 | "noImplicitReturns": true, 11 | "noPropertyAccessFromIndexSignature": true, 12 | "noUncheckedIndexedAccess": true, 13 | "noUnusedLocals": true, 14 | "noUnusedParameters": true, 15 | "isolatedModules": true, 16 | "checkJs": true, 17 | "esModuleInterop": true, 18 | "skipLibCheck": true, 19 | "forceConsistentCasingInFileNames": true, 20 | "baseUrl": ".", 21 | "module": "es2015", 22 | "moduleResolution": "node" 23 | }, 24 | "include": ["src/*.ts"] 25 | } 26 | --------------------------------------------------------------------------------