From f847650b1e1e20599312cc5029503f4a4907fbb2 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 2 Jul 2021 00:46:41 +0000 Subject: [PATCH 01/66] chore(deps): update dependency @vue/compiler-sfc to v3.1.3 (#3125) Co-authored-by: Renovate Bot --- packages/graphql-tag-pluck/package.json | 2 +- yarn.lock | 58 ++++++++++++------------- 2 files changed, 30 insertions(+), 30 deletions(-) diff --git a/packages/graphql-tag-pluck/package.json b/packages/graphql-tag-pluck/package.json index 0897e916c2d..8d29886811d 100644 --- a/packages/graphql-tag-pluck/package.json +++ b/packages/graphql-tag-pluck/package.json @@ -37,7 +37,7 @@ }, "devDependencies": { "@types/babel__traverse": "7.14.0", - "@vue/compiler-sfc": "3.1.2" + "@vue/compiler-sfc": "3.1.3" }, "buildOptions": { "external": [ diff --git a/yarn.lock b/yarn.lock index 59b215a2a07..7a960db8a80 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2950,37 +2950,37 @@ resolved "https://registry.yarnpkg.com/@vercel/ncc/-/ncc-0.28.3.tgz#9461bdbf334d616759b0e7e5415e2f480b9aa30f" integrity sha512-g3gk4D9itbhUQa5MtN7TOdeoQnNLkPDCox5SBaQ/H3Or5lo59TOaZWrLb+x47StiAJ+8DXZS/9MJ67cIBWSsRw== -"@vue/compiler-core@3.1.2": - version "3.1.2" - resolved "https://registry.yarnpkg.com/@vue/compiler-core/-/compiler-core-3.1.2.tgz#31ab1d88e1706a5c7a545faeeb64c31bd0101db0" - integrity sha512-nHmq7vLjq/XM2IMbZUcKWoH5sPXa2uR/nIKZtjbK5F3TcbnYE/zKsrSUR9WZJ03unlwotNBX1OyxVt9HbWD7/Q== +"@vue/compiler-core@3.1.3": + version "3.1.3" + resolved "https://registry.yarnpkg.com/@vue/compiler-core/-/compiler-core-3.1.3.tgz#cd9587aa1fda533b1bdf752689e281efccfb7062" + integrity sha512-I58MDtVa8AYEIa3waLO6/89JdmgpkDAEcL3Vrmlsbnt07KZ5sIGLqaXjzGrOT57j9s8ty0WTYlLQq2rWUVYGCg== dependencies: "@babel/parser" "^7.12.0" "@babel/types" "^7.12.0" - "@vue/shared" "3.1.2" + "@vue/shared" "3.1.3" estree-walker "^2.0.1" source-map "^0.6.1" -"@vue/compiler-dom@3.1.2": - version "3.1.2" - resolved "https://registry.yarnpkg.com/@vue/compiler-dom/-/compiler-dom-3.1.2.tgz#75a7731bcc5d9718183a3c56c18e992f7c13e7b1" - integrity sha512-k2+SWcWH0jL6WQAX7Or2ONqu5MbtTgTO0dJrvebQYzgqaKMXNI90RNeWeCxS4BnNFMDONpHBeFgbwbnDWIkmRg== +"@vue/compiler-dom@3.1.3": + version "3.1.3" + resolved "https://registry.yarnpkg.com/@vue/compiler-dom/-/compiler-dom-3.1.3.tgz#ade4ff7db4b0a197c543dd67b5bd467d737ac344" + integrity sha512-BunLXKP+UvY1XJ0L6M7KD/De0XP+kOlIxFg3OfXtVQZcLLgnLcTgSK3t/ylvIpYJOadGaHhb+BfCK/hdqOVAyw== dependencies: - "@vue/compiler-core" "3.1.2" - "@vue/shared" "3.1.2" + "@vue/compiler-core" "3.1.3" + "@vue/shared" "3.1.3" -"@vue/compiler-sfc@3.1.2": - version "3.1.2" - resolved "https://registry.yarnpkg.com/@vue/compiler-sfc/-/compiler-sfc-3.1.2.tgz#23ff1e366d887b964899568bffcb11e3d0511fc4" - integrity sha512-SeG/2+DvwejQ7oAiSx8BrDh5qOdqCYHGClPiTvVIHTfSIHiS2JjMbCANdDCjHkTOh/O7WZzo2JhdKm98bRBxTw== +"@vue/compiler-sfc@3.1.3": + version "3.1.3" + resolved "https://registry.yarnpkg.com/@vue/compiler-sfc/-/compiler-sfc-3.1.3.tgz#f8aba30e5254a2b7be9516159630c8f75b412216" + integrity sha512-WpQ0oHMT5Aeb92UBnYCOxfHwdOGFZJ+BUyFiu2rG6TTDuw+aPNHCsFxvi55eG+2P7uiqRFK03lc0mGh3v8OVmw== dependencies: "@babel/parser" "^7.13.9" "@babel/types" "^7.13.0" "@types/estree" "^0.0.48" - "@vue/compiler-core" "3.1.2" - "@vue/compiler-dom" "3.1.2" - "@vue/compiler-ssr" "3.1.2" - "@vue/shared" "3.1.2" + "@vue/compiler-core" "3.1.3" + "@vue/compiler-dom" "3.1.3" + "@vue/compiler-ssr" "3.1.3" + "@vue/shared" "3.1.3" consolidate "^0.16.0" estree-walker "^2.0.1" hash-sum "^2.0.0" @@ -2992,18 +2992,18 @@ postcss-selector-parser "^6.0.4" source-map "^0.6.1" -"@vue/compiler-ssr@3.1.2": - version "3.1.2" - resolved "https://registry.yarnpkg.com/@vue/compiler-ssr/-/compiler-ssr-3.1.2.tgz#e33ad0876d9b96f0950e22b0e174b94c1b049d2d" - integrity sha512-BwXo9LFk5OSWdMyZQ4bX1ELHX0Z/9F+ld/OaVnpUPzAZCHslBYLvyKUVDwv2C/lpLjRffpC2DOUEdl1+RP1aGg== +"@vue/compiler-ssr@3.1.3": + version "3.1.3" + resolved "https://registry.yarnpkg.com/@vue/compiler-ssr/-/compiler-ssr-3.1.3.tgz#e74394b031f6956710f1881e21fa9fe1fa5a030e" + integrity sha512-dAktYBae3h9QWJoSKsrfrcZEjh4hwphDMWwj+ZwIkHBhEpyjdFLJks8MpxRjGMZzqz5vNyteVXkbOAaoiWPwwA== dependencies: - "@vue/compiler-dom" "3.1.2" - "@vue/shared" "3.1.2" + "@vue/compiler-dom" "3.1.3" + "@vue/shared" "3.1.3" -"@vue/shared@3.1.2": - version "3.1.2" - resolved "https://registry.yarnpkg.com/@vue/shared/-/shared-3.1.2.tgz#1069c0bc7d6f4bd15ccf3a5f3be29450aca368f9" - integrity sha512-EmH/poaDWBPJaPILXNI/1fvUbArJQmmTyVCwvvyDYDFnkPoTclAbHRAtyIvqfez7jybTDn077HTNILpxlsoWhg== +"@vue/shared@3.1.3": + version "3.1.3" + resolved "https://registry.yarnpkg.com/@vue/shared/-/shared-3.1.3.tgz#3f6f5e7226d8d2d965ef39780ae3f89dc906b5fc" + integrity sha512-uGBX4bZVFvgranxzpH3q1gGmICUjEUnNrMIBFeZRw8hBfCPhT+VnuY8+mG2l/yEyY73J9e6d36CtbFUqDXa12w== "@webassemblyjs/ast@1.11.0": version "1.11.0" From 3846041c14d0fe37d43b77156e2a0b85da8651ba Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 2 Jul 2021 13:28:14 +0000 Subject: [PATCH 02/66] chore(deps): update dependency @vue/compiler-sfc to v3.1.4 (#3126) Co-authored-by: Renovate Bot --- packages/graphql-tag-pluck/package.json | 2 +- yarn.lock | 58 ++++++++++++------------- 2 files changed, 30 insertions(+), 30 deletions(-) diff --git a/packages/graphql-tag-pluck/package.json b/packages/graphql-tag-pluck/package.json index 8d29886811d..4b7f706e36c 100644 --- a/packages/graphql-tag-pluck/package.json +++ b/packages/graphql-tag-pluck/package.json @@ -37,7 +37,7 @@ }, "devDependencies": { "@types/babel__traverse": "7.14.0", - "@vue/compiler-sfc": "3.1.3" + "@vue/compiler-sfc": "3.1.4" }, "buildOptions": { "external": [ diff --git a/yarn.lock b/yarn.lock index 7a960db8a80..9fea859d5c7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2950,37 +2950,37 @@ resolved "https://registry.yarnpkg.com/@vercel/ncc/-/ncc-0.28.3.tgz#9461bdbf334d616759b0e7e5415e2f480b9aa30f" integrity sha512-g3gk4D9itbhUQa5MtN7TOdeoQnNLkPDCox5SBaQ/H3Or5lo59TOaZWrLb+x47StiAJ+8DXZS/9MJ67cIBWSsRw== -"@vue/compiler-core@3.1.3": - version "3.1.3" - resolved "https://registry.yarnpkg.com/@vue/compiler-core/-/compiler-core-3.1.3.tgz#cd9587aa1fda533b1bdf752689e281efccfb7062" - integrity sha512-I58MDtVa8AYEIa3waLO6/89JdmgpkDAEcL3Vrmlsbnt07KZ5sIGLqaXjzGrOT57j9s8ty0WTYlLQq2rWUVYGCg== +"@vue/compiler-core@3.1.4": + version "3.1.4" + resolved "https://registry.yarnpkg.com/@vue/compiler-core/-/compiler-core-3.1.4.tgz#a3a74cf52e8f01af386d364ac8a099cbeb260424" + integrity sha512-TnUz+1z0y74O/A4YKAbzsdUfamyHV73MihrEfvettWpm9bQKVoZd1nEmR1cGN9LsXWlwAvVQBetBlWdOjmQO5Q== dependencies: "@babel/parser" "^7.12.0" "@babel/types" "^7.12.0" - "@vue/shared" "3.1.3" + "@vue/shared" "3.1.4" estree-walker "^2.0.1" source-map "^0.6.1" -"@vue/compiler-dom@3.1.3": - version "3.1.3" - resolved "https://registry.yarnpkg.com/@vue/compiler-dom/-/compiler-dom-3.1.3.tgz#ade4ff7db4b0a197c543dd67b5bd467d737ac344" - integrity sha512-BunLXKP+UvY1XJ0L6M7KD/De0XP+kOlIxFg3OfXtVQZcLLgnLcTgSK3t/ylvIpYJOadGaHhb+BfCK/hdqOVAyw== +"@vue/compiler-dom@3.1.4": + version "3.1.4" + resolved "https://registry.yarnpkg.com/@vue/compiler-dom/-/compiler-dom-3.1.4.tgz#bf3795e1449f32c965d38c4ea6d808ca05fdfc97" + integrity sha512-3tG2ScHkghhUBuFwl9KgyZhrS8CPFZsO7hUDekJgIp5b1OMkROr4AvxHu6rRMl4WkyvYkvidFNBS2VfOnwa6Kw== dependencies: - "@vue/compiler-core" "3.1.3" - "@vue/shared" "3.1.3" + "@vue/compiler-core" "3.1.4" + "@vue/shared" "3.1.4" -"@vue/compiler-sfc@3.1.3": - version "3.1.3" - resolved "https://registry.yarnpkg.com/@vue/compiler-sfc/-/compiler-sfc-3.1.3.tgz#f8aba30e5254a2b7be9516159630c8f75b412216" - integrity sha512-WpQ0oHMT5Aeb92UBnYCOxfHwdOGFZJ+BUyFiu2rG6TTDuw+aPNHCsFxvi55eG+2P7uiqRFK03lc0mGh3v8OVmw== +"@vue/compiler-sfc@3.1.4": + version "3.1.4" + resolved "https://registry.yarnpkg.com/@vue/compiler-sfc/-/compiler-sfc-3.1.4.tgz#93e87db950e0711339c18baa7bb7d28d3522d7bc" + integrity sha512-4KDQg60Khy3SgnF+V/TB2NZqzmM4TyGRmzsxqG1SebGdMSecCweFDSlI/F1vDYk6dKiCHgmpoT9A1sLxswkJ0A== dependencies: "@babel/parser" "^7.13.9" "@babel/types" "^7.13.0" "@types/estree" "^0.0.48" - "@vue/compiler-core" "3.1.3" - "@vue/compiler-dom" "3.1.3" - "@vue/compiler-ssr" "3.1.3" - "@vue/shared" "3.1.3" + "@vue/compiler-core" "3.1.4" + "@vue/compiler-dom" "3.1.4" + "@vue/compiler-ssr" "3.1.4" + "@vue/shared" "3.1.4" consolidate "^0.16.0" estree-walker "^2.0.1" hash-sum "^2.0.0" @@ -2992,18 +2992,18 @@ postcss-selector-parser "^6.0.4" source-map "^0.6.1" -"@vue/compiler-ssr@3.1.3": - version "3.1.3" - resolved "https://registry.yarnpkg.com/@vue/compiler-ssr/-/compiler-ssr-3.1.3.tgz#e74394b031f6956710f1881e21fa9fe1fa5a030e" - integrity sha512-dAktYBae3h9QWJoSKsrfrcZEjh4hwphDMWwj+ZwIkHBhEpyjdFLJks8MpxRjGMZzqz5vNyteVXkbOAaoiWPwwA== +"@vue/compiler-ssr@3.1.4": + version "3.1.4" + resolved "https://registry.yarnpkg.com/@vue/compiler-ssr/-/compiler-ssr-3.1.4.tgz#7f6eaac5b1851fc15c82c083e8179eb1216b303c" + integrity sha512-Box8fCuCFPp0FuimIswjDkjwiSDCBkHvt/xVALyFkYCiIMWv2eR53fIjmlsnEHhcBuZ+VgRC+UanCTcKvSA1gA== dependencies: - "@vue/compiler-dom" "3.1.3" - "@vue/shared" "3.1.3" + "@vue/compiler-dom" "3.1.4" + "@vue/shared" "3.1.4" -"@vue/shared@3.1.3": - version "3.1.3" - resolved "https://registry.yarnpkg.com/@vue/shared/-/shared-3.1.3.tgz#3f6f5e7226d8d2d965ef39780ae3f89dc906b5fc" - integrity sha512-uGBX4bZVFvgranxzpH3q1gGmICUjEUnNrMIBFeZRw8hBfCPhT+VnuY8+mG2l/yEyY73J9e6d36CtbFUqDXa12w== +"@vue/shared@3.1.4": + version "3.1.4" + resolved "https://registry.yarnpkg.com/@vue/shared/-/shared-3.1.4.tgz#c14c461ec42ea2c1556e86f60b0354341d91adc3" + integrity sha512-6O45kZAmkLvzGLToBxEz4lR2W6kXohCtebV2UxjH9GXjd8X9AhEn68FN9eNanFtWNzvgw1hqd6HkPRVQalqf7Q== "@webassemblyjs/ast@1.11.0": version "1.11.0" From 26778f681e7355d59960d6e6cb8972d966a7032f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 2 Jul 2021 23:09:02 +0300 Subject: [PATCH 03/66] fix(deps): update dependency @types/websocket to v1.0.3 (#3129) Co-authored-by: Renovate Bot --- packages/loaders/url/package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/loaders/url/package.json b/packages/loaders/url/package.json index 20b3bbd6fb2..0135793bdff 100644 --- a/packages/loaders/url/package.json +++ b/packages/loaders/url/package.json @@ -47,7 +47,7 @@ "@graphql-tools/wrap": "^7.0.4", "@microsoft/fetch-event-source": "2.0.1", "@n1ru4l/graphql-live-query": "0.7.1", - "@types/websocket": "1.0.2", + "@types/websocket": "1.0.3", "abort-controller": "3.0.0", "cross-fetch": "3.1.4", "extract-files": "11.0.0", diff --git a/yarn.lock b/yarn.lock index 9fea859d5c7..8d42f689465 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2838,10 +2838,10 @@ tapable "^2.2.0" webpack "^5" -"@types/websocket@1.0.2": - version "1.0.2" - resolved "https://registry.yarnpkg.com/@types/websocket/-/websocket-1.0.2.tgz#d2855c6a312b7da73ed16ba6781815bf30c6187a" - integrity sha512-B5m9aq7cbbD/5/jThEr33nUY8WEfVi6A2YKCTOvw5Ldy7mtsOkqRvGjnzy6g7iMMDsgu7xREuCzqATLDLQVKcQ== +"@types/websocket@1.0.3": + version "1.0.3" + resolved "https://registry.yarnpkg.com/@types/websocket/-/websocket-1.0.3.tgz#49e09f939afd0ccdee4f7108d4712ec9feb0f153" + integrity sha512-ZdoTSwmDsKR7l1I8fpfQtmTI/hUwlOvE3q0iyJsp4tXU0MkdrYowimDzwxjhQvxU4qjhHLd3a6ig0OXRbLgIdw== dependencies: "@types/node" "*" From 6afe3bebadd6e083be6c196291533547d09e0ccc Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 2 Jul 2021 23:09:13 +0300 Subject: [PATCH 04/66] chore(deps): update dependency @types/ws to v7.4.6 (#3128) Co-authored-by: Renovate Bot --- packages/loaders/url/package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/loaders/url/package.json b/packages/loaders/url/package.json index 0135793bdff..368401887dc 100644 --- a/packages/loaders/url/package.json +++ b/packages/loaders/url/package.json @@ -36,7 +36,7 @@ }, "devDependencies": { "@types/extract-files": "8.1.0", - "@types/ws": "7.4.5", + "@types/ws": "7.4.6", "graphql-upload": "12.0.0", "mock-http": "1.1.0", "mock-socket": "9.0.3" diff --git a/yarn.lock b/yarn.lock index 8d42f689465..853a8cc248b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2845,10 +2845,10 @@ dependencies: "@types/node" "*" -"@types/ws@7.4.5": - version "7.4.5" - resolved "https://registry.yarnpkg.com/@types/ws/-/ws-7.4.5.tgz#8ff0f7efcd8fea19f51f9dd66cb8b498d172a752" - integrity sha512-8mbDgtc8xpxDDem5Gwj76stBDJX35KQ3YBoayxlqUQcL5BZUthiqP/VQ4PQnLHqM4PmlbyO74t98eJpURO+gPA== +"@types/ws@7.4.6": + version "7.4.6" + resolved "https://registry.yarnpkg.com/@types/ws/-/ws-7.4.6.tgz#c4320845e43d45a7129bb32905e28781c71c1fff" + integrity sha512-ijZ1vzRawI7QoWnTNL8KpHixd2b2XVb9I9HAqI3triPsh1EC0xH0Eg6w2O3TKbDCgiNNlJqfrof6j4T2I+l9vw== dependencies: "@types/node" "*" From e05525204e46e67a6ba4f85271eece3695105fc7 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 3 Jul 2021 01:33:40 +0000 Subject: [PATCH 05/66] chore(deps): update dependency eslint to v7.30.0 (#3130) Co-authored-by: Renovate Bot --- package.json | 2 +- yarn.lock | 23 +++++++++++++++++++---- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 65f34b79d77..a6963d107c5 100644 --- a/package.json +++ b/package.json @@ -55,7 +55,7 @@ "@typescript-eslint/parser": "4.28.1", "babel-jest": "27.0.6", "concurrently": "6.2.0", - "eslint": "7.29.0", + "eslint": "7.30.0", "eslint-config-prettier": "8.3.0", "eslint-config-standard": "16.0.3", "eslint-plugin-import": "2.23.4", diff --git a/yarn.lock b/yarn.lock index 853a8cc248b..0bcbd991a68 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1918,6 +1918,20 @@ dependencies: "@hapi/hoek" "^9.0.0" +"@humanwhocodes/config-array@^0.5.0": + version "0.5.0" + resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.5.0.tgz#1407967d4c6eecd7388f83acf1eaf4d0c6e58ef9" + integrity sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg== + dependencies: + "@humanwhocodes/object-schema" "^1.2.0" + debug "^4.1.1" + minimatch "^3.0.4" + +"@humanwhocodes/object-schema@^1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.0.tgz#87de7af9c231826fdd68ac7258f77c429e0e5fcf" + integrity sha512-wdppn25U8z/2yiaT6YGquE6X8sSv7hNMWSXYSSU1jGv/yd6XqjXgTDJ8KP4NgjTXfJ3GbRjeeb8RTV7a/VpM+w== + "@istanbuljs/load-nyc-config@^1.0.0": version "1.1.0" resolved "https://registry.yarnpkg.com/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz#fd3db1d59ecf7cf121e80650bb86712f9b55eced" @@ -5767,13 +5781,14 @@ eslint-visitor-keys@^2.0.0: resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-2.0.0.tgz#21fdc8fbcd9c795cc0321f0563702095751511a8" integrity sha512-QudtT6av5WXels9WjIM7qz1XD1cWGvX4gGXvp/zBn9nXG02D0utdU3Em2m/QjTnrsk6bBjmCygl3rmj118msQQ== -eslint@7.29.0: - version "7.29.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.29.0.tgz#ee2a7648f2e729485e4d0bd6383ec1deabc8b3c0" - integrity sha512-82G/JToB9qIy/ArBzIWG9xvvwL3R86AlCjtGw+A29OMZDqhTybz/MByORSukGxeI+YPCR4coYyITKk8BFH9nDA== +eslint@7.30.0: + version "7.30.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.30.0.tgz#6d34ab51aaa56112fd97166226c9a97f505474f8" + integrity sha512-VLqz80i3as3NdloY44BQSJpFw534L9Oh+6zJOUaViV4JPd+DaHwutqP7tcpkW3YiXbK6s05RZl7yl7cQn+lijg== dependencies: "@babel/code-frame" "7.12.11" "@eslint/eslintrc" "^0.4.2" + "@humanwhocodes/config-array" "^0.5.0" ajv "^6.10.0" chalk "^4.0.0" cross-spawn "^7.0.2" From 40db362ce396966e47cc4a22a53b0a1a6785f20d Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 4 Jul 2021 07:49:35 +0000 Subject: [PATCH 06/66] fix(deps): update dependency ws to v7.5.2 (#3131) Co-authored-by: Renovate Bot --- packages/loaders/url/package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/loaders/url/package.json b/packages/loaders/url/package.json index 368401887dc..6c20a1ad9af 100644 --- a/packages/loaders/url/package.json +++ b/packages/loaders/url/package.json @@ -61,7 +61,7 @@ "sync-fetch": "0.3.0", "tslib": "~2.3.0", "valid-url": "1.0.9", - "ws": "7.5.1", + "ws": "7.5.2", "value-or-promise": "1.0.10" }, "publishConfig": { diff --git a/yarn.lock b/yarn.lock index 0bcbd991a68..58177b44fa0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -13677,10 +13677,10 @@ write-pkg@^4.0.0: type-fest "^0.4.1" write-json-file "^3.2.0" -ws@7.5.1, "ws@^5.2.0 || ^6.0.0 || ^7.0.0", ws@^7.3.1, ws@^7.4.5: - version "7.5.1" - resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.1.tgz#44fc000d87edb1d9c53e51fbc69a0ac1f6871d66" - integrity sha512-2c6faOUH/nhoQN6abwMloF7Iyl0ZS2E9HGtsiLrWn0zOOMWlhtDmdf/uihDt6jnuCxgtwGBNy6Onsoy2s2O2Ow== +ws@7.5.2, "ws@^5.2.0 || ^6.0.0 || ^7.0.0", ws@^7.3.1, ws@^7.4.5: + version "7.5.2" + resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.2.tgz#09cc8fea3bec1bc5ed44ef51b42f945be36900f6" + integrity sha512-lkF7AWRicoB9mAgjeKbGqVUekLnSNO4VjKVnuPHpQeOxZOErX6BPXwJk70nFslRCEEA8EVW7ZjKwXaP9N+1sKQ== ws@^6.2.1: version "6.2.1" From fd81e80091e2a4aec017994b2120258b43bc488f Mon Sep 17 00:00:00 2001 From: Arda TANRIKULU Date: Sun, 4 Jul 2021 15:07:56 +0300 Subject: [PATCH 07/66] fix(url-loader): fix node support for EventSource --- .changeset/unlucky-kangaroos-tan.md | 5 +++++ packages/loaders/url/package.json | 2 +- packages/loaders/url/src/index.ts | 2 +- yarn.lock | 10 +++++----- 4 files changed, 12 insertions(+), 7 deletions(-) create mode 100644 .changeset/unlucky-kangaroos-tan.md diff --git a/.changeset/unlucky-kangaroos-tan.md b/.changeset/unlucky-kangaroos-tan.md new file mode 100644 index 00000000000..1ea9d5164c5 --- /dev/null +++ b/.changeset/unlucky-kangaroos-tan.md @@ -0,0 +1,5 @@ +--- +'@graphql-tools/url-loader': patch +--- + +fix(url-loader): fix node support for EventSource diff --git a/packages/loaders/url/package.json b/packages/loaders/url/package.json index 6c20a1ad9af..a238ad6db93 100644 --- a/packages/loaders/url/package.json +++ b/packages/loaders/url/package.json @@ -45,7 +45,7 @@ "@graphql-tools/delegate": "^7.0.1", "@graphql-tools/utils": "^7.9.0", "@graphql-tools/wrap": "^7.0.4", - "@microsoft/fetch-event-source": "2.0.1", + "@ardatan/fetch-event-source": "2.0.2", "@n1ru4l/graphql-live-query": "0.7.1", "@types/websocket": "1.0.3", "abort-controller": "3.0.0", diff --git a/packages/loaders/url/src/index.ts b/packages/loaders/url/src/index.ts index ef3cc4dd3ab..f5cd4c9f5cf 100644 --- a/packages/loaders/url/src/index.ts +++ b/packages/loaders/url/src/index.ts @@ -26,7 +26,7 @@ import syncFetch from 'sync-fetch'; import isPromise from 'is-promise'; import { extractFiles, isExtractableFile } from 'extract-files'; import FormData from 'form-data'; -import { fetchEventSource, FetchEventSourceInit } from '@microsoft/fetch-event-source'; +import { fetchEventSource, FetchEventSourceInit } from '@ardatan/fetch-event-source'; import { ConnectionParamsOptions, SubscriptionClient as LegacySubscriptionClient } from 'subscriptions-transport-ws'; import AbortController from 'abort-controller'; import { meros } from 'meros'; diff --git a/yarn.lock b/yarn.lock index 58177b44fa0..af084c55171 100644 --- a/yarn.lock +++ b/yarn.lock @@ -144,6 +144,11 @@ tslib "^1.10.0" zen-observable "^0.8.14" +"@ardatan/fetch-event-source@2.0.2": + version "2.0.2" + resolved "https://registry.yarnpkg.com/@ardatan/fetch-event-source/-/fetch-event-source-2.0.2.tgz#734aa3eaa0da456453d24d8dc7c14d5e366a8d21" + integrity sha512-mcpz/wJ7s50PJIVz4OQ1Yim3w/AAchtYtIg0QMWiMR2cZZoI9t23hRyqeumtD5EmyJu0fxtjmQ5WY8GI86V4rQ== + "@babel/code-frame@7.10.4": version "7.10.4" resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.10.4.tgz#168da1a36e90da68ae8d49c0f1b48c7c6249213a" @@ -2184,11 +2189,6 @@ resolved "https://registry.yarnpkg.com/@mdx-js/util/-/util-1.6.22.tgz#219dfd89ae5b97a8801f015323ffa4b62f45718b" integrity sha512-H1rQc1ZOHANWBvPcW+JpGwr+juXSxM8Q8YCkm3GhZd8REu1fHR3z99CErO1p9pkcfcxZnMdIZdIsXkOHY0NilA== -"@microsoft/fetch-event-source@2.0.1": - version "2.0.1" - resolved "https://registry.yarnpkg.com/@microsoft/fetch-event-source/-/fetch-event-source-2.0.1.tgz#9ceecc94b49fbaa15666e38ae8587f64acce007d" - integrity sha512-W6CLUJ2eBMw3Rec70qrsEW0jOm/3twwJv21mrmj2yORiaVmVYGS4sSS5yUwvQc1ZlDLYGPnClVWmUUMagKNsfA== - "@n1ru4l/graphql-live-query@0.7.1": version "0.7.1" resolved "https://registry.yarnpkg.com/@n1ru4l/graphql-live-query/-/graphql-live-query-0.7.1.tgz#c020d017c3ed6bcfdde49a7106ba035e4d0774f5" From 1a81264557f14d36c148079ed0e41868329be69e Mon Sep 17 00:00:00 2001 From: ntziolis Date: Sun, 4 Jul 2021 19:01:53 +0200 Subject: [PATCH 08/66] feat(resolvers-composition): add support for glob patterns (#3132) * feat(resolvers-composition): add support for glob patterns * fix(resolvers-composition): add typings for micromatch * feat(resolvers-composition): add unit tests for glob patterns * chore(resolver-compositions): cleanup * feat(docs): added samples for resolver composition path matcher format * chore: added changeset * fix(docs): typo * fix(changeset): change patch to minor * Fix tests and cleanup Co-authored-by: Arda TANRIKULU --- .changeset/silver-comics-check.md | 5 + packages/node-require/src/index.ts | 7 +- .../node-require/test/node-require.spec.ts | 10 +- packages/resolvers-composition/package.json | 8 +- .../src/resolvers-composition.ts | 106 +++++++----------- .../tests/resolvers-composition.spec.ts | 57 ++++++++++ website/docs/resolvers-composition.md | 11 ++ yarn.lock | 2 +- 8 files changed, 129 insertions(+), 77 deletions(-) create mode 100644 .changeset/silver-comics-check.md diff --git a/.changeset/silver-comics-check.md b/.changeset/silver-comics-check.md new file mode 100644 index 00000000000..06bc791cdd6 --- /dev/null +++ b/.changeset/silver-comics-check.md @@ -0,0 +1,5 @@ +--- +'@graphql-tools/resolvers-composition': minor +--- + +Added glob pattern support for composeResolver method diff --git a/packages/node-require/src/index.ts b/packages/node-require/src/index.ts index d238c3b50d5..43b801ac65e 100644 --- a/packages/node-require/src/index.ts +++ b/packages/node-require/src/index.ts @@ -11,8 +11,7 @@ import { isSome } from '@graphql-tools/utils'; const VALID_EXTENSIONS = ['graphql', 'graphqls', 'gql', 'gqls']; -function handleModule(m: NodeModule, filename: string) { - console.log(m, filename); +export function handleModule(m: NodeModule, filename: string) { const sources = loadTypedefsSync(filename, { loaders: [new GraphQLFileLoader()], }); @@ -22,9 +21,9 @@ function handleModule(m: NodeModule, filename: string) { m.exports = mergedDoc; } -export function registerGraphQLExtensions(require: NodeRequire) { +export function registerGraphQLExtensions(nodeRequire: NodeRequire) { for (const ext of VALID_EXTENSIONS) { - require.extensions[`.${ext}`] = handleModule; + nodeRequire.extensions[`.${ext}`] = handleModule; } } diff --git a/packages/node-require/test/node-require.spec.ts b/packages/node-require/test/node-require.spec.ts index febaac67b37..d2dac6d6f2e 100644 --- a/packages/node-require/test/node-require.spec.ts +++ b/packages/node-require/test/node-require.spec.ts @@ -1,12 +1,14 @@ -import '../src'; +import { handleModule } from '../src'; import { print } from 'graphql'; import { readFileSync } from 'fs'; +import { join } from 'path'; describe('GraphQL Node Import', () => { - it.skip('should import correct definitions', () => { - console.log(require.main); + it('should import correct definitions', () => { const filePath = './fixtures/test.graphql'; - const typeDefs = require(filePath); + const m: any = {}; + handleModule(m, join(__dirname, filePath)); + const typeDefs = m.exports; expect(print(typeDefs).replace(/\s\s+/g, ' ')).toBe( readFileSync(require.resolve(filePath), 'utf8').replace(/\s\s+/g, ' ') ); diff --git a/packages/resolvers-composition/package.json b/packages/resolvers-composition/package.json index dcb0a1f4580..a1b3ef2fe45 100644 --- a/packages/resolvers-composition/package.json +++ b/packages/resolvers-composition/package.json @@ -11,8 +11,8 @@ "license": "MIT", "sideEffects": false, "main": "dist/index.js", - "module": "dist/index.mjs", - "exports": { + "module": "dist/index.mjs", + "exports": { ".": { "require": "./dist/index.js", "import": "./dist/index.mjs" @@ -30,11 +30,13 @@ "graphql": "^14.0.0 || ^15.0.0" }, "devDependencies": { - "@types/lodash": "4.14.170" + "@types/lodash": "4.14.170", + "@types/micromatch": "^4.0.1" }, "dependencies": { "@graphql-tools/utils": "^7.9.1", "lodash": "4.17.21", + "micromatch": "^4.0.4", "tslib": "~2.3.0" }, "publishConfig": { diff --git a/packages/resolvers-composition/src/resolvers-composition.ts b/packages/resolvers-composition/src/resolvers-composition.ts index f07bad3174d..a61e42ea26b 100644 --- a/packages/resolvers-composition/src/resolvers-composition.ts +++ b/packages/resolvers-composition/src/resolvers-composition.ts @@ -2,6 +2,7 @@ import { chainFunctions } from './chain-functions'; import _ from 'lodash'; import { GraphQLFieldResolver, GraphQLScalarTypeConfig } from 'graphql'; import { asArray } from '@graphql-tools/utils'; +import { matcher } from 'micromatch'; export type ResolversComposition< Resolver extends GraphQLFieldResolver = GraphQLFieldResolver @@ -27,88 +28,63 @@ function isScalarTypeConfiguration(config: any): config is GraphQLScalarTypeConf function resolveRelevantMappings = Record>( resolvers: Resolvers, - path: string, - allMappings: ResolversComposerMapping + path: string ): string[] { - const split = path.split('.'); + if (!resolvers) { + return []; + } - if (split.length === 2) { - const typeName = split[0]; + const [typeNameOrGlob, fieldNameOrGlob] = path.split('.'); + const isTypeMatch = matcher(typeNameOrGlob); - if (isScalarTypeConfiguration(resolvers[typeName])) { - return []; - } + let fixedFieldGlob = fieldNameOrGlob; + // convert single value OR `{singleField}` to `singleField` as matching will fail otherwise + if (fixedFieldGlob.includes('{') && !fixedFieldGlob.includes(',')) { + fixedFieldGlob = fieldNameOrGlob.replace('{', '').replace('}', ''); + } + fixedFieldGlob = fixedFieldGlob.replace(', ', ',').trim(); - const fieldName = split[1]; + const isFieldMatch = matcher(fixedFieldGlob); - if (typeName === '*') { - if (!resolvers) { - return []; - } - const mappings: string[] = []; - for (const typeName in resolvers) { - const relevantMappings = resolveRelevantMappings(resolvers, `${typeName}.${fieldName}`, allMappings); - for (const relevantMapping of relevantMappings) { - mappings.push(relevantMapping); - } - } - return mappings; + const mappings: string[] = []; + for (const typeName in resolvers) { + if (!isTypeMatch(typeName)) { + continue; } - if (fieldName === '*') { - const fieldMap = resolvers[typeName]; - if (!fieldMap) { - return []; - } - const mappings: string[] = []; - for (const field in fieldMap) { - const relevantMappings = resolveRelevantMappings(resolvers, `${typeName}.${field}`, allMappings); - for (const relevantMapping of relevantMappings) { - if (!allMappings[relevantMapping]) { - mappings.push(relevantMapping); - } - } - } - return mappings; - } else { - const paths = []; - - if (resolvers[typeName] && resolvers[typeName][fieldName]) { - if (resolvers[typeName][fieldName].subscribe) { - paths.push(path + '.subscribe'); - } - - if (resolvers[typeName][fieldName].resolve) { - paths.push(path + '.resolve'); - } - - if (typeof resolvers[typeName][fieldName] === 'function') { - paths.push(path); - } - } - - return paths; + if (isScalarTypeConfiguration(resolvers[typeName])) { + continue; } - } else if (split.length === 1) { - const typeName = split[0]; const fieldMap = resolvers[typeName]; if (!fieldMap) { return []; } - const mappings: string[] = []; + for (const field in fieldMap) { + if (!isFieldMatch(field)) { + continue; + } - for (const fieldName in fieldMap) { - const relevantMappings = resolveRelevantMappings(resolvers, `${typeName}.${fieldName}`, allMappings); - for (const relevantMapping of relevantMappings) { - mappings.push(relevantMapping); + const resolvedPath = `${typeName}.${field}`; + + if (resolvers[typeName] && resolvers[typeName][field]) { + if (resolvers[typeName][field].subscribe) { + mappings.push(resolvedPath + '.subscribe'); + } + + if (resolvers[typeName][field].resolve) { + mappings.push(resolvedPath + '.resolve'); + } + + if (typeof resolvers[typeName][field] === 'function') { + mappings.push(resolvedPath); + } } } - return mappings; } - return []; + return mappings; } /** @@ -129,7 +105,7 @@ export function composeResolvers>( const resolverPathMapping = mapping[resolverPath]; if (resolverPathMapping instanceof Array || typeof resolverPathMapping === 'function') { const composeFns = resolverPathMapping as ResolversComposition | ResolversComposition[]; - const relevantFields = resolveRelevantMappings(resolvers, resolverPath, mapping); + const relevantFields = resolveRelevantMappings(resolvers, resolverPath); for (const path of relevantFields) { mappingResult[path] = asArray(composeFns); @@ -137,7 +113,7 @@ export function composeResolvers>( } else if (resolverPathMapping) { for (const fieldName in resolverPathMapping) { const composeFns = resolverPathMapping[fieldName]; - const relevantFields = resolveRelevantMappings(resolvers, resolverPath + '.' + fieldName, mapping); + const relevantFields = resolveRelevantMappings(resolvers, resolverPath + '.' + fieldName); for (const path of relevantFields) { mappingResult[path] = asArray(composeFns); diff --git a/packages/resolvers-composition/tests/resolvers-composition.spec.ts b/packages/resolvers-composition/tests/resolvers-composition.spec.ts index 8449371c3ab..908b88dc3d5 100644 --- a/packages/resolvers-composition/tests/resolvers-composition.spec.ts +++ b/packages/resolvers-composition/tests/resolvers-composition.spec.ts @@ -290,6 +290,63 @@ describe('Resolvers composition', () => { }); + it('should support glob pattern for fields - Query.{foo, bar}', async () => { + const resolvers = { + Query: { + foo: async () => 0, + bar: async () => 1, + fooBar: async () => 2, + }, + Mutation: { + qux: async () => 3, + baz: async () => 4, + }, + }; + const resolversComposition = { + 'Query.{foo, bar}': [ + (next: any) => async (...args: any) => { + const result = await next(...args); + return result + 1; + } + ] + } + const composedResolvers = composeResolvers(resolvers, resolversComposition); + + expect(await composedResolvers.Query.foo()).toBe(1); + expect(await composedResolvers.Query.bar()).toBe(2); + expect(await composedResolvers.Query.fooBar()).toBe(2); + expect(await composedResolvers.Mutation.qux()).toBe(3); + expect(await composedResolvers.Mutation.baz()).toBe(4); + }); + + it('should support glob pattern for fields - Query.!{foo, bar}', async () => { + const resolvers = { + Query: { + foo: async () => 0, + bar: async () => 1, + fooBar: async () => 2, + }, + Mutation: { + qux: async () => 3, + baz: async () => 4, + }, + }; + const resolversComposition = { + 'Query.!{foo, bar}': [ + (next: any) => async (...args: any) => { + const result = await next(...args); + return result + 1; + } + ] + } + const composedResolvers = composeResolvers(resolvers, resolversComposition); + + expect(await composedResolvers.Query.foo()).toBe(0); + expect(await composedResolvers.Query.bar()).toBe(1); + expect(await composedResolvers.Query.fooBar()).toBe(3); + expect(await composedResolvers.Mutation.qux()).toBe(3); + expect(await composedResolvers.Mutation.baz()).toBe(4); + }); it('should handle nullish properties correctly', async () => { const getFoo = () => 'FOO'; const resolvers = { diff --git a/website/docs/resolvers-composition.md b/website/docs/resolvers-composition.md index 68513317ddc..0f814926a39 100644 --- a/website/docs/resolvers-composition.md +++ b/website/docs/resolvers-composition.md @@ -78,3 +78,14 @@ const composedResolvers = composeResolvers(resolvers, resolversComposition); ``` `composeResolvers` is a method in `@graphql-tools/resolvers-composition` package that accepts `IResolvers` object and mappings for composition functions that would be run before resolver itself. + +### Supported path matcher format +The paths for resolvers support `*` wildcard for types and glob patters for fields, eg: +- `*.*` - all types and all fields +- `Query.*` - all queries +- `Query.single` - only a single query +- `Query.{first, second}` - queries for first/second +- `Query.!first` - all queries but first +- `Query.!{first, second}` - all queries but first/second + + diff --git a/yarn.lock b/yarn.lock index af084c55171..0ec8797f688 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2715,7 +2715,7 @@ dependencies: "@types/unist" "*" -"@types/micromatch@latest": +"@types/micromatch@^4.0.1", "@types/micromatch@latest": version "4.0.1" resolved "https://registry.yarnpkg.com/@types/micromatch/-/micromatch-4.0.1.tgz#9381449dd659fc3823fd2a4190ceacc985083bc7" integrity sha1-k4FEndZZ/Dgj/SpBkM6syYUIO8c= From 09db9906684bce93ac086925e2d2d0b59773fbde Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 4 Jul 2021 14:47:49 -0400 Subject: [PATCH 09/66] chore(deps): pin dependency @types/micromatch to 4.0.1 (#3133) Co-authored-by: Renovate Bot --- packages/resolvers-composition/package.json | 2 +- yarn.lock | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/resolvers-composition/package.json b/packages/resolvers-composition/package.json index a1b3ef2fe45..ba6fc246eec 100644 --- a/packages/resolvers-composition/package.json +++ b/packages/resolvers-composition/package.json @@ -31,7 +31,7 @@ }, "devDependencies": { "@types/lodash": "4.14.170", - "@types/micromatch": "^4.0.1" + "@types/micromatch": "4.0.1" }, "dependencies": { "@graphql-tools/utils": "^7.9.1", diff --git a/yarn.lock b/yarn.lock index 0ec8797f688..1bc6f001821 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2715,7 +2715,7 @@ dependencies: "@types/unist" "*" -"@types/micromatch@^4.0.1", "@types/micromatch@latest": +"@types/micromatch@4.0.1", "@types/micromatch@latest": version "4.0.1" resolved "https://registry.yarnpkg.com/@types/micromatch/-/micromatch-4.0.1.tgz#9381449dd659fc3823fd2a4190ceacc985083bc7" integrity sha1-k4FEndZZ/Dgj/SpBkM6syYUIO8c= From 9f93cd7b3e03d908c41052465a08b0cf6c5d5385 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 4 Jul 2021 19:18:39 +0000 Subject: [PATCH 10/66] chore(deps): update dependency nock to v13.1.1 (#3134) Co-authored-by: Renovate Bot --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index a6963d107c5..d7c5bb04142 100644 --- a/package.json +++ b/package.json @@ -68,7 +68,7 @@ "husky": "7.0.0", "jest": "27.0.6", "lint-staged": "11.0.0", - "nock": "13.1.0", + "nock": "13.1.1", "patch-package": "6.4.7", "prettier": "2.3.2", "ts-jest": "27.0.3", diff --git a/yarn.lock b/yarn.lock index 1bc6f001821..c53780c8d99 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9422,10 +9422,10 @@ no-case@^3.0.4: lower-case "^2.0.2" tslib "^2.0.3" -nock@13.1.0: - version "13.1.0" - resolved "https://registry.yarnpkg.com/nock/-/nock-13.1.0.tgz#41c8ce8b35ab7d618c4cbf40de1d5bce319979ba" - integrity sha512-3N3DUY8XYrxxzWazQ+nSBpiaJ3q6gcpNh4gXovC/QBxrsvNp4tq+wsLHF6mJ3nrn3lPLn7KCJqKxy/9aD+0fdw== +nock@13.1.1: + version "13.1.1" + resolved "https://registry.yarnpkg.com/nock/-/nock-13.1.1.tgz#3c830129d4560957f59b6f480a41ddbaf9cf57af" + integrity sha512-YKTR9MjfK3kS9/l4nuTxyYm30cgOExRHzkLNhL8nhEUyU4f8Za/dRxOqjhVT1vGs0svWo3dDnJTUX1qxYeWy5w== dependencies: debug "^4.1.0" json-stringify-safe "^5.0.1" From 21dd87df11387a9dd54e8d03503553554f5def24 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 5 Jul 2021 18:42:33 +0000 Subject: [PATCH 11/66] chore(deps): update typescript-eslint monorepo to v4.28.2 (#3135) Co-authored-by: Renovate Bot --- package.json | 4 +-- yarn.lock | 82 ++++++++++++++++++++++++++-------------------------- 2 files changed, 43 insertions(+), 43 deletions(-) diff --git a/package.json b/package.json index d7c5bb04142..abd1b79d965 100644 --- a/package.json +++ b/package.json @@ -51,8 +51,8 @@ "@changesets/cli": "2.16.0", "@types/jest": "26.0.23", "@types/node": "14.17.4", - "@typescript-eslint/eslint-plugin": "4.28.1", - "@typescript-eslint/parser": "4.28.1", + "@typescript-eslint/eslint-plugin": "4.28.2", + "@typescript-eslint/parser": "4.28.2", "babel-jest": "27.0.6", "concurrently": "6.2.0", "eslint": "7.30.0", diff --git a/yarn.lock b/yarn.lock index c53780c8d99..4beb248a301 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2890,73 +2890,73 @@ resolved "https://registry.yarnpkg.com/@types/zen-observable/-/zen-observable-0.8.2.tgz#808c9fa7e4517274ed555fa158f2de4b4f468e71" integrity sha512-HrCIVMLjE1MOozVoD86622S7aunluLb2PJdPfb3nYiEtohm8mIB/vyv0Fd37AdeMFrTUQXEunw78YloMA3Qilg== -"@typescript-eslint/eslint-plugin@4.28.1": - version "4.28.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.28.1.tgz#c045e440196ae45464e08e20c38aff5c3a825947" - integrity sha512-9yfcNpDaNGQ6/LQOX/KhUFTR1sCKH+PBr234k6hI9XJ0VP5UqGxap0AnNwBnWFk1MNyWBylJH9ZkzBXC+5akZQ== +"@typescript-eslint/eslint-plugin@4.28.2": + version "4.28.2" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.28.2.tgz#7a8320f00141666813d0ae43b49ee8244f7cf92a" + integrity sha512-PGqpLLzHSxq956rzNGasO3GsAPf2lY9lDUBXhS++SKonglUmJypaUtcKzRtUte8CV7nruwnDxtLUKpVxs0wQBw== dependencies: - "@typescript-eslint/experimental-utils" "4.28.1" - "@typescript-eslint/scope-manager" "4.28.1" + "@typescript-eslint/experimental-utils" "4.28.2" + "@typescript-eslint/scope-manager" "4.28.2" debug "^4.3.1" functional-red-black-tree "^1.0.1" regexpp "^3.1.0" semver "^7.3.5" tsutils "^3.21.0" -"@typescript-eslint/experimental-utils@4.28.1": - version "4.28.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-4.28.1.tgz#3869489dcca3c18523c46018b8996e15948dbadc" - integrity sha512-n8/ggadrZ+uyrfrSEchx3jgODdmcx7MzVM2sI3cTpI/YlfSm0+9HEUaWw3aQn2urL2KYlWYMDgn45iLfjDYB+Q== +"@typescript-eslint/experimental-utils@4.28.2": + version "4.28.2" + resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-4.28.2.tgz#4ebdec06a10888e9326e1d51d81ad52a361bd0b0" + integrity sha512-MwHPsL6qo98RC55IoWWP8/opTykjTp4JzfPu1VfO2Z0MshNP0UZ1GEV5rYSSnZSUI8VD7iHvtIPVGW5Nfh7klQ== dependencies: "@types/json-schema" "^7.0.7" - "@typescript-eslint/scope-manager" "4.28.1" - "@typescript-eslint/types" "4.28.1" - "@typescript-eslint/typescript-estree" "4.28.1" + "@typescript-eslint/scope-manager" "4.28.2" + "@typescript-eslint/types" "4.28.2" + "@typescript-eslint/typescript-estree" "4.28.2" eslint-scope "^5.1.1" eslint-utils "^3.0.0" -"@typescript-eslint/parser@4.28.1": - version "4.28.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-4.28.1.tgz#5181b81658414f47291452c15bf6cd44a32f85bd" - integrity sha512-UjrMsgnhQIIK82hXGaD+MCN8IfORS1CbMdu7VlZbYa8LCZtbZjJA26De4IPQB7XYZbL8gJ99KWNj0l6WD0guJg== +"@typescript-eslint/parser@4.28.2": + version "4.28.2" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-4.28.2.tgz#6aff11bf4b91eb67ca7517962eede951e9e2a15d" + integrity sha512-Q0gSCN51eikAgFGY+gnd5p9bhhCUAl0ERMiDKrTzpSoMYRubdB8MJrTTR/BBii8z+iFwz8oihxd0RAdP4l8w8w== dependencies: - "@typescript-eslint/scope-manager" "4.28.1" - "@typescript-eslint/types" "4.28.1" - "@typescript-eslint/typescript-estree" "4.28.1" + "@typescript-eslint/scope-manager" "4.28.2" + "@typescript-eslint/types" "4.28.2" + "@typescript-eslint/typescript-estree" "4.28.2" debug "^4.3.1" -"@typescript-eslint/scope-manager@4.28.1": - version "4.28.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-4.28.1.tgz#fd3c20627cdc12933f6d98b386940d8d0ce8a991" - integrity sha512-o95bvGKfss6705x7jFGDyS7trAORTy57lwJ+VsYwil/lOUxKQ9tA7Suuq+ciMhJc/1qPwB3XE2DKh9wubW8YYA== +"@typescript-eslint/scope-manager@4.28.2": + version "4.28.2" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-4.28.2.tgz#451dce90303a3ce283750111495d34c9c204e510" + integrity sha512-MqbypNjIkJFEFuOwPWNDjq0nqXAKZvDNNs9yNseoGBB1wYfz1G0WHC2AVOy4XD7di3KCcW3+nhZyN6zruqmp2A== dependencies: - "@typescript-eslint/types" "4.28.1" - "@typescript-eslint/visitor-keys" "4.28.1" + "@typescript-eslint/types" "4.28.2" + "@typescript-eslint/visitor-keys" "4.28.2" -"@typescript-eslint/types@4.28.1": - version "4.28.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.28.1.tgz#d0f2ecbef3684634db357b9bbfc97b94b828f83f" - integrity sha512-4z+knEihcyX7blAGi7O3Fm3O6YRCP+r56NJFMNGsmtdw+NCdpG5SgNz427LS9nQkRVTswZLhz484hakQwB8RRg== +"@typescript-eslint/types@4.28.2": + version "4.28.2" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.28.2.tgz#e6b9e234e0e9a66c4d25bab881661e91478223b5" + integrity sha512-Gr15fuQVd93uD9zzxbApz3wf7ua3yk4ZujABZlZhaxxKY8ojo448u7XTm/+ETpy0V0dlMtj6t4VdDvdc0JmUhA== -"@typescript-eslint/typescript-estree@4.28.1": - version "4.28.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.28.1.tgz#af882ae41740d1f268e38b4d0fad21e7e8d86a81" - integrity sha512-GhKxmC4sHXxHGJv8e8egAZeTZ6HI4mLU6S7FUzvFOtsk7ZIDN1ksA9r9DyOgNqowA9yAtZXV0Uiap61bIO81FQ== +"@typescript-eslint/typescript-estree@4.28.2": + version "4.28.2" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.28.2.tgz#680129b2a285289a15e7c6108c84739adf3a798c" + integrity sha512-86lLstLvK6QjNZjMoYUBMMsULFw0hPHJlk1fzhAVoNjDBuPVxiwvGuPQq3fsBMCxuDJwmX87tM/AXoadhHRljg== dependencies: - "@typescript-eslint/types" "4.28.1" - "@typescript-eslint/visitor-keys" "4.28.1" + "@typescript-eslint/types" "4.28.2" + "@typescript-eslint/visitor-keys" "4.28.2" debug "^4.3.1" globby "^11.0.3" is-glob "^4.0.1" semver "^7.3.5" tsutils "^3.21.0" -"@typescript-eslint/visitor-keys@4.28.1": - version "4.28.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.28.1.tgz#162a515ee255f18a6068edc26df793cdc1ec9157" - integrity sha512-K4HMrdFqr9PFquPu178SaSb92CaWe2yErXyPumc8cYWxFmhgJsNY9eSePmO05j0JhBvf2Cdhptd6E6Yv9HVHcg== +"@typescript-eslint/visitor-keys@4.28.2": + version "4.28.2" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.28.2.tgz#bf56a400857bb68b59b311e6d0a5fbef5c3b5130" + integrity sha512-aT2B4PLyyRDUVUafXzpZFoc0C9t0za4BJAKP5sgWIhG+jHECQZUEjuQSCIwZdiJJ4w4cgu5r3Kh20SOdtEBl0w== dependencies: - "@typescript-eslint/types" "4.28.1" + "@typescript-eslint/types" "4.28.2" eslint-visitor-keys "^2.0.0" "@vercel/ncc@0.28.3": From 8f519da03b9c4377003b78596444f5adede7b3c9 Mon Sep 17 00:00:00 2001 From: Yaacov Rydzinski Date: Tue, 6 Jul 2021 07:01:19 +0300 Subject: [PATCH 12/66] don't throw on errors that should not be relocated (#3136) --- packages/batch-delegate/src/getLoader.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/batch-delegate/src/getLoader.ts b/packages/batch-delegate/src/getLoader.ts index 80182a41361..5b62f0d0ff0 100644 --- a/packages/batch-delegate/src/getLoader.ts +++ b/packages/batch-delegate/src/getLoader.ts @@ -28,11 +28,11 @@ function createBatchFn(options: BatchDelegateOptions) { const [pathFieldName, pathNumber] = originalError.path; if (pathFieldName !== fieldName) { - throw new Error(`Error path value at index 0 should be '${fieldName}', received '${pathFieldName}'.`); + return originalError; } const pathNumberType = typeof pathNumber; if (pathNumberType !== 'number') { - throw new Error(`Error path value at index 1 should be of type number, received '${pathNumberType}'.`); + return originalError; } return relocatedError(originalError, originalError.path.slice(0, 0).concat(originalError.path.slice(2))); From c9827546dfe493c6c8d449b6569dd496cd4b1e56 Mon Sep 17 00:00:00 2001 From: Yaacov Rydzinski Date: Tue, 6 Jul 2021 07:21:00 +0300 Subject: [PATCH 13/66] refactor: internal StitchingInfo properties (#3137) to never be undefined --- packages/delegate/src/delegationBindings.ts | 4 +--- packages/delegate/src/types.ts | 4 ++-- packages/stitch/src/stitchingInfo.ts | 14 ++++---------- 3 files changed, 7 insertions(+), 15 deletions(-) diff --git a/packages/delegate/src/delegationBindings.ts b/packages/delegate/src/delegationBindings.ts index 23bffcc73ee..1eb05edc5a9 100644 --- a/packages/delegate/src/delegationBindings.ts +++ b/packages/delegate/src/delegationBindings.ts @@ -1,4 +1,4 @@ -import { assertSome, Maybe } from '@graphql-tools/utils'; +import { Maybe } from '@graphql-tools/utils'; import { Transform, StitchingInfo, DelegationContext } from './types'; import AddSelectionSets from './transforms/AddSelectionSets'; @@ -18,8 +18,6 @@ export function defaultDelegationBinding( const stitchingInfo: Maybe = info?.schema.extensions?.['stitchingInfo']; if (stitchingInfo != null) { - assertSome(stitchingInfo.selectionSetsByType); - assertSome(stitchingInfo.dynamicSelectionSetsByField); delegationTransforms = delegationTransforms.concat([ new ExpandAbstractTypes(), new AddSelectionSets( diff --git a/packages/delegate/src/types.ts b/packages/delegate/src/types.ts index cc2a614414d..1e12ddd9592 100644 --- a/packages/delegate/src/types.ts +++ b/packages/delegate/src/types.ts @@ -188,9 +188,9 @@ export type MergedTypeResolver> = ( export interface StitchingInfo> { subschemaMap: Map, Subschema>; - selectionSetsByType: Record | undefined; + selectionSetsByType: Record; selectionSetsByField: Record>; - dynamicSelectionSetsByField: Record SelectionSetNode>>> | undefined; + dynamicSelectionSetsByField: Record SelectionSetNode>>>; mergedTypes: Record>; } diff --git a/packages/stitch/src/stitchingInfo.ts b/packages/stitch/src/stitchingInfo.ts index 8f048d2b5dd..da5ace90a1c 100644 --- a/packages/stitch/src/stitchingInfo.ts +++ b/packages/stitch/src/stitchingInfo.ts @@ -76,9 +76,9 @@ export function createStitchingInfo>( return { subschemaMap, - selectionSetsByType: undefined, + selectionSetsByType: Object.create(null), selectionSetsByField, - dynamicSelectionSetsByField: undefined, + dynamicSelectionSetsByField: Object.create(null), mergedTypes, }; } @@ -227,7 +227,8 @@ export function completeStitchingInfo>( resolvers: IResolvers, schema: GraphQLSchema ): StitchingInfo { - const selectionSetsByType = Object.create(null); + const { selectionSetsByType, selectionSetsByField, dynamicSelectionSetsByField } = stitchingInfo; + const rootTypes = [schema.getQueryType(), schema.getMutationType()]; for (const rootType of rootTypes) { if (rootType) { @@ -235,9 +236,6 @@ export function completeStitchingInfo>( } } - const selectionSetsByField = stitchingInfo.selectionSetsByField; - const dynamicSelectionSetsByField = Object.create(null); - for (const typeName in resolvers) { const type = resolvers[typeName]; if (isScalarType(type)) { @@ -288,10 +286,6 @@ export function completeStitchingInfo>( } } - stitchingInfo.selectionSetsByType = selectionSetsByType; - stitchingInfo.selectionSetsByField = selectionSetsByField; - stitchingInfo.dynamicSelectionSetsByField = dynamicSelectionSetsByField; - return stitchingInfo; } From 11daa9273267d2760d8512f1606112ba854c4437 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 6 Jul 2021 07:28:04 -0400 Subject: [PATCH 14/66] chore(deps): update dependency husky to v7.0.1 (#3139) Co-authored-by: Renovate Bot --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index abd1b79d965..6dedb306417 100644 --- a/package.json +++ b/package.json @@ -65,7 +65,7 @@ "graphql": "15.5.1", "graphql-helix": "1.6.1", "graphql-subscriptions": "1.2.1", - "husky": "7.0.0", + "husky": "7.0.1", "jest": "27.0.6", "lint-staged": "11.0.0", "nock": "13.1.1", diff --git a/yarn.lock b/yarn.lock index 4beb248a301..7bd5cbe91b6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7216,10 +7216,10 @@ human-signals@^2.1.0: resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== -husky@7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/husky/-/husky-7.0.0.tgz#3dbd5d28e76234689ee29bb41e048f28e3e46616" - integrity sha512-xK7lO0EtSzfFPiw+oQncQVy/XqV7UVVjxBByc+Iv5iK3yhW9boDoWgvZy3OGo48QKg/hUtZkzz0hi2HXa0kn7w== +husky@7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/husky/-/husky-7.0.1.tgz#579f4180b5da4520263e8713cc832942b48e1f1c" + integrity sha512-gceRaITVZ+cJH9sNHqx5tFwbzlLCVxtVZcusME8JYQ8Edy5mpGDOqD8QBCdMhpyo9a+JXddnujQ4rpY2Ff9SJA== iconv-lite@0.4.24, iconv-lite@^0.4.24: version "0.4.24" From b5961175987c9aa30c5696e68c0711b63b80d26c Mon Sep 17 00:00:00 2001 From: Yaacov Rydzinski Date: Tue, 6 Jul 2021 18:18:00 +0300 Subject: [PATCH 15/66] add getDefinedRootType helper (#3138) --- packages/delegate/src/delegateToSchema.ts | 12 ++-------- packages/delegate/src/getDefinedRootType.ts | 23 +++++++++++++++++++ .../src/transforms/AddArgumentsAsVariables.ts | 17 +++++--------- .../delegate/src/transforms/FilterToSchema.ts | 14 +++-------- .../src/transforms/VisitSelectionSets.ts | 11 +++------ 5 files changed, 37 insertions(+), 40 deletions(-) create mode 100644 packages/delegate/src/getDefinedRootType.ts diff --git a/packages/delegate/src/delegateToSchema.ts b/packages/delegate/src/delegateToSchema.ts index 2c1d4896f80..49ede02f108 100644 --- a/packages/delegate/src/delegateToSchema.ts +++ b/packages/delegate/src/delegateToSchema.ts @@ -9,7 +9,6 @@ import { OperationDefinitionNode, DocumentNode, GraphQLOutputType, - GraphQLObjectType, } from 'graphql'; import { ValueOrPromise } from 'value-or-promise'; @@ -38,6 +37,7 @@ import { isSubschemaConfig } from './subschemaConfig'; import { Subschema } from './Subschema'; import { createRequestFromInfo, getDelegatingOperation } from './createRequest'; import { Transformer } from './Transformer'; +import { getDefinedRootType } from './getDefinedRootType'; export function delegateToSchema, TArgs = any>( options: IDelegateToSchemaOptions @@ -75,15 +75,7 @@ function getDelegationReturnType( operation: OperationTypeNode, fieldName: string ): GraphQLOutputType { - let rootType: Maybe>; - if (operation === 'query') { - rootType = targetSchema.getQueryType(); - } else if (operation === 'mutation') { - rootType = targetSchema.getMutationType(); - } else { - rootType = targetSchema.getSubscriptionType(); - } - assertSome(rootType); + const rootType = getDefinedRootType(targetSchema, operation); return rootType.getFields()[fieldName].type; } diff --git a/packages/delegate/src/getDefinedRootType.ts b/packages/delegate/src/getDefinedRootType.ts new file mode 100644 index 00000000000..f45248855ec --- /dev/null +++ b/packages/delegate/src/getDefinedRootType.ts @@ -0,0 +1,23 @@ +import { GraphQLObjectType, GraphQLSchema, OperationTypeNode } from 'graphql'; + +import { Maybe } from '../../utils/src/types'; + +export function getDefinedRootType(schema: GraphQLSchema, operation: OperationTypeNode): GraphQLObjectType { + let rootType: Maybe; + if (operation === 'query') { + rootType = schema.getQueryType(); + } else if (operation === 'mutation') { + rootType = schema.getMutationType(); + } else if (operation === 'subscription') { + rootType = schema.getSubscriptionType(); + } else { + // Future proof against new operation types + throw new Error(`Unknown operation "${operation}", cannot get root type.`); + } + + if (rootType == null) { + throw new Error(`Root type for operation "${operation}" not defined by the given schema.`); + } + + return rootType; +} diff --git a/packages/delegate/src/transforms/AddArgumentsAsVariables.ts b/packages/delegate/src/transforms/AddArgumentsAsVariables.ts index 05d96eeddef..9fabdb6f444 100644 --- a/packages/delegate/src/transforms/AddArgumentsAsVariables.ts +++ b/packages/delegate/src/transforms/AddArgumentsAsVariables.ts @@ -3,7 +3,6 @@ import { DocumentNode, FragmentDefinitionNode, GraphQLField, - GraphQLObjectType, GraphQLSchema, Kind, OperationDefinitionNode, @@ -11,9 +10,10 @@ import { VariableDefinitionNode, } from 'graphql'; -import { Maybe, Request, serializeInputValue, updateArgument, assertSome } from '@graphql-tools/utils'; +import { Request, serializeInputValue, updateArgument } from '@graphql-tools/utils'; import { Transform, DelegationContext } from '../types'; +import { getDefinedRootType } from '../getDefinedRootType'; export default class AddArgumentsAsVariables implements Transform { private readonly args: Record; @@ -70,16 +70,11 @@ function addVariablesToRootField( {} ); - let type: Maybe; - if (operation.operation === 'subscription') { - type = targetSchema.getSubscriptionType(); - } else if (operation.operation === 'mutation') { - type = targetSchema.getMutationType(); - } else { - type = targetSchema.getQueryType(); - } + const type = getDefinedRootType(targetSchema, operation.operation); - assertSome(type); + if (type == null) { + throw new Error(`Schema missing root type for operation "${operation}".`); + } const newSelectionSet: Array = []; diff --git a/packages/delegate/src/transforms/FilterToSchema.ts b/packages/delegate/src/transforms/FilterToSchema.ts index 3c703ed9141..8a82564e284 100644 --- a/packages/delegate/src/transforms/FilterToSchema.ts +++ b/packages/delegate/src/transforms/FilterToSchema.ts @@ -19,12 +19,12 @@ import { getNamedType, isObjectType, isInterfaceType, - GraphQLObjectType, } from 'graphql'; -import { Request, implementsAbstractType, TypeMap, assertSome, Maybe } from '@graphql-tools/utils'; +import { Request, implementsAbstractType, TypeMap, assertSome } from '@graphql-tools/utils'; import { Transform, DelegationContext } from '../types'; +import { getDefinedRootType } from '../getDefinedRootType'; export default class FilterToSchema implements Transform { public transformRequest( @@ -72,15 +72,7 @@ function filterToSchema( let fragmentSet = Object.create(null); for (const operation of operations) { - let type: Maybe>; - if (operation.operation === 'subscription') { - type = targetSchema.getSubscriptionType(); - } else if (operation.operation === 'mutation') { - type = targetSchema.getMutationType(); - } else { - type = targetSchema.getQueryType(); - } - assertSome(type); + const type = getDefinedRootType(targetSchema, operation.operation); const { selectionSet, diff --git a/packages/delegate/src/transforms/VisitSelectionSets.ts b/packages/delegate/src/transforms/VisitSelectionSets.ts index d0021378bc3..583538de1a7 100644 --- a/packages/delegate/src/transforms/VisitSelectionSets.ts +++ b/packages/delegate/src/transforms/VisitSelectionSets.ts @@ -13,9 +13,10 @@ import { DefinitionNode, } from 'graphql'; -import { Request, collectFields, GraphQLExecutionContext, assertSome, Maybe } from '@graphql-tools/utils'; +import { Request, collectFields, GraphQLExecutionContext, Maybe } from '@graphql-tools/utils'; import { Transform, DelegationContext } from '../types'; +import { getDefinedRootType } from '../getDefinedRootType'; type VisitSelectionSetsVisitor = (node: SelectionSetNode, typeInfo: TypeInfo) => Maybe; @@ -70,13 +71,7 @@ function visitSelectionSets( const typeInfo = new TypeInfo(schema, undefined, initialType); const newDefinitions: Array = operations.map(operation => { - const type = - operation.operation === 'query' - ? schema.getQueryType() - : operation.operation === 'mutation' - ? schema.getMutationType() - : schema.getSubscriptionType(); - assertSome(type); + const type = getDefinedRootType(schema, operation.operation); const fields = collectFields( partialExecutionContext, From 79a45386f6dc743228c07668551d6390cee8f7ce Mon Sep 17 00:00:00 2001 From: Yaacov Rydzinski Date: Tue, 6 Jul 2021 18:29:13 +0300 Subject: [PATCH 16/66] add comment (#3140) --- packages/stitch/src/stitchingInfo.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/stitch/src/stitchingInfo.ts b/packages/stitch/src/stitchingInfo.ts index da5ace90a1c..062e25be43e 100644 --- a/packages/stitch/src/stitchingInfo.ts +++ b/packages/stitch/src/stitchingInfo.ts @@ -229,6 +229,8 @@ export function completeStitchingInfo>( ): StitchingInfo { const { selectionSetsByType, selectionSetsByField, dynamicSelectionSetsByField } = stitchingInfo; + // must add __typename to query and mutation root types to handle type merging with nested root types + // cannot add __typename to subscription root types, but they cannot be nested const rootTypes = [schema.getQueryType(), schema.getMutationType()]; for (const rootType of rootTypes) { if (rootType) { From f6115d3f5b95a2607856b3074fc77098d763e057 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 6 Jul 2021 17:34:32 +0000 Subject: [PATCH 17/66] chore(deps): update dependency @apollo/client to v3.3.21 (#3142) Co-authored-by: Renovate Bot --- packages/links/package.json | 2 +- yarn.lock | 18 +++++++++--------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/packages/links/package.json b/packages/links/package.json index f0a89101225..4b209f92e3b 100644 --- a/packages/links/package.json +++ b/packages/links/package.json @@ -38,7 +38,7 @@ ] }, "devDependencies": { - "@apollo/client": "3.3.20", + "@apollo/client": "3.3.21", "@types/apollo-upload-client": "14.1.0", "@types/graphql-upload": "8.0.5", "express-graphql": "0.12.0", diff --git a/yarn.lock b/yarn.lock index 7bd5cbe91b6..bc27d6fd85e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -125,10 +125,10 @@ "@algolia/logger-common" "4.9.1" "@algolia/requester-common" "4.9.1" -"@apollo/client@3.3.20", "@apollo/client@^3.1.3", "@apollo/client@~3.2.5 || ~3.3.0": - version "3.3.20" - resolved "https://registry.yarnpkg.com/@apollo/client/-/client-3.3.20.tgz#8f0935fa991857e9cf2e73c9bd378ad7ec97caf8" - integrity sha512-hS7UmBwJweudw/J3M0RAcusMHNiRuGqkRH6g91PM2ev8cXScIMdXr/++9jo7wD1nAITMCMF4HQQ3LFaw/Or0Bw== +"@apollo/client@3.3.21", "@apollo/client@^3.1.3", "@apollo/client@~3.2.5 || ~3.3.0": + version "3.3.21" + resolved "https://registry.yarnpkg.com/@apollo/client/-/client-3.3.21.tgz#2862baa4e1ced8c5e89ebe6fc52877fc64a726aa" + integrity sha512-RAmZReFuKCKx0Rs5C0nVJwKomAHUHn+gGP/YvbEsXQWu0sXoncEUZa71UqlfCPVXa/0MkYOIbCXSQdOcuRrHgw== dependencies: "@graphql-typed-document-node/core" "^3.0.0" "@types/zen-observable" "^0.8.0" @@ -140,7 +140,7 @@ optimism "^0.16.0" prop-types "^15.7.2" symbol-observable "^4.0.0" - ts-invariant "^0.7.0" + ts-invariant "^0.8.0" tslib "^1.10.0" zen-observable "^0.8.14" @@ -12675,10 +12675,10 @@ ts-essentials@^2.0.3: resolved "https://registry.yarnpkg.com/ts-essentials/-/ts-essentials-2.0.12.tgz#c9303f3d74f75fa7528c3d49b80e089ab09d8745" integrity sha512-3IVX4nI6B5cc31/GFFE+i8ey/N2eA0CZDbo6n0yrz0zDX8ZJ8djmU1p+XRz7G3is0F3bB3pu2pAroFdAWQKU3w== -ts-invariant@^0.7.0: - version "0.7.3" - resolved "https://registry.yarnpkg.com/ts-invariant/-/ts-invariant-0.7.3.tgz#13aae22a4a165393aaf5cecdee45ef4128d358b8" - integrity sha512-UWDDeovyUTIMWj+45g5nhnl+8oo+GhxL5leTaHn5c8FkQWfh8v66gccLd2/YzVmV5hoQUjCEjhrXnQqVDJdvKA== +ts-invariant@^0.8.0: + version "0.8.2" + resolved "https://registry.yarnpkg.com/ts-invariant/-/ts-invariant-0.8.2.tgz#62af654ebfb8b1eeb55bc9adc2f40c6b93b0ff7e" + integrity sha512-VI1ZSMW8soizP5dU8DsMbj/TncHf7bIUqavuE7FTeYeQat454HHurJ8wbfCnVWcDOMkyiBUWOW2ytew3xUxlRw== dependencies: tslib "^2.1.0" From f1d7b3c290633d6943ac4454097b2910bf88b4dc Mon Sep 17 00:00:00 2001 From: Laurin Quast Date: Tue, 6 Jul 2021 19:36:20 +0200 Subject: [PATCH 18/66] fix: ensure operations with GraphQL magic comment are only parsed once. (#3143) --- .changeset/ninety-spies-care.md | 5 +++++ packages/graphql-tag-pluck/src/visitor.ts | 17 ++++++++++---- .../tests/graphql-tag-pluck.test.ts | 22 +++++++++++++++++++ 3 files changed, 40 insertions(+), 4 deletions(-) create mode 100644 .changeset/ninety-spies-care.md diff --git a/.changeset/ninety-spies-care.md b/.changeset/ninety-spies-care.md new file mode 100644 index 00000000000..39d5f421437 --- /dev/null +++ b/.changeset/ninety-spies-care.md @@ -0,0 +1,5 @@ +--- +'@graphql-tools/graphql-tag-pluck': patch +--- + +ensure operations with GraphQL magic comment are only parsed once. diff --git a/packages/graphql-tag-pluck/src/visitor.ts b/packages/graphql-tag-pluck/src/visitor.ts index d3e722c0611..72b51183443 100644 --- a/packages/graphql-tag-pluck/src/visitor.ts +++ b/packages/graphql-tag-pluck/src/visitor.ts @@ -167,6 +167,7 @@ export default (code: string, out: any, options: GraphQLTagPluckOptions = {}) => // Will result with ['gql', 'graphql'] const definedIdentifierNames: string[] = []; + const alreadyProcessedOperationsCache = new Set(); // Will accumulate all template literals const gqlTemplateLiterals: PluckedContent[] = []; @@ -194,6 +195,15 @@ export default (code: string, out: any, options: GraphQLTagPluckOptions = {}) => ); }; + const addTemplateLiteralToResult = (content: PluckedContent) => { + const cacheKey = `end/${content.end}/start/${content.start}/${content.content}`; + if (alreadyProcessedOperationsCache.has(cacheKey)) { + return; + } + alreadyProcessedOperationsCache.add(cacheKey); + gqlTemplateLiterals.push(content); + }; + // Push all template literals leaded by graphql magic comment // e.g. /* GraphQL */ `query myQuery {}` -> query myQuery {} const pluckMagicTemplateLiteral = (node: any, takeExpression = false) => { @@ -215,9 +225,8 @@ export default (code: string, out: any, options: GraphQLTagPluckOptions = {}) => const nodeToUse = takeExpression ? node.expression : node; const gqlTemplateLiteral = pluckStringFromFile(nodeToUse); - if (gqlTemplateLiteral) { - gqlTemplateLiterals.push({ + addTemplateLiteralToResult({ content: gqlTemplateLiteral, loc: node.loc, end: node.end, @@ -262,7 +271,7 @@ export default (code: string, out: any, options: GraphQLTagPluckOptions = {}) => // If the entire template was made out of interpolations it should be an empty // string by now and thus should be ignored if (gqlTemplateLiteral) { - gqlTemplateLiterals.push({ + addTemplateLiteralToResult({ content: gqlTemplateLiteral, loc, end, @@ -344,7 +353,7 @@ export default (code: string, out: any, options: GraphQLTagPluckOptions = {}) => const gqlTemplateLiteral = pluckStringFromFile(path.node.quasi); if (gqlTemplateLiteral) { - gqlTemplateLiterals.push({ + addTemplateLiteralToResult({ content: gqlTemplateLiteral, end: path.node.quasi.end, start: path.node.quasi.start, diff --git a/packages/graphql-tag-pluck/tests/graphql-tag-pluck.test.ts b/packages/graphql-tag-pluck/tests/graphql-tag-pluck.test.ts index cd092de10f5..af30e6f7078 100644 --- a/packages/graphql-tag-pluck/tests/graphql-tag-pluck.test.ts +++ b/packages/graphql-tag-pluck/tests/graphql-tag-pluck.test.ts @@ -1207,6 +1207,28 @@ describe('graphql-tag-pluck', () => { `)); }); + it('should pluck graphql-tag template literals from code string with /* GraphQL */ comment', async () => { + const sources = await pluck('test.js', freeText(` + import gql from 'graphql-tag' + + const doc = gql(/* GraphQL */ \` + query foo { + foo { + foo + } + } + \`) + `)); + + expect(sources.map(source => source.body).join('\n\n')).toEqual(freeText(` + query foo { + foo { + foo + } + } + `)); + }) + it('should pluck graphql-tag template literals from a .js file', async () => { const sources = await pluck('tmp-XXXXXX.js', freeText(` import gql from 'graphql-tag' From 70cd65ebb1043af798653bce5fc53697278c4888 Mon Sep 17 00:00:00 2001 From: Arda TANRIKULU Date: Tue, 6 Jul 2021 21:54:03 +0300 Subject: [PATCH 19/66] feat(stitching-directives): move federation-to-stitching-sdl (#3144) --- .changeset/quiet-carrots-arrive.md | 5 + .../src/federationToStitchingSDL.ts | 146 ++++++++++++++++++ packages/stitching-directives/src/index.ts | 1 + .../tests/federationToStitchingSDL.test.ts | 141 +++++++++++++++++ website/docs/federation-to-stitching-sdl.md | 121 +++++++++++++++ website/sidebars.js | 1 + 6 files changed, 415 insertions(+) create mode 100644 .changeset/quiet-carrots-arrive.md create mode 100644 packages/stitching-directives/src/federationToStitchingSDL.ts create mode 100644 packages/stitching-directives/tests/federationToStitchingSDL.test.ts create mode 100644 website/docs/federation-to-stitching-sdl.md diff --git a/.changeset/quiet-carrots-arrive.md b/.changeset/quiet-carrots-arrive.md new file mode 100644 index 00000000000..387c8a80107 --- /dev/null +++ b/.changeset/quiet-carrots-arrive.md @@ -0,0 +1,5 @@ +--- +'@graphql-tools/stitching-directives': minor +--- + +feat(stitching-directives): move federation-to-stitching-sdl diff --git a/packages/stitching-directives/src/federationToStitchingSDL.ts b/packages/stitching-directives/src/federationToStitchingSDL.ts new file mode 100644 index 00000000000..ca0f34df2cb --- /dev/null +++ b/packages/stitching-directives/src/federationToStitchingSDL.ts @@ -0,0 +1,146 @@ +// Taken from https://github.com/gmac/federation-to-stitching-sdl/blob/main/index.js + +import { + print, + DefinitionNode, + DirectiveNode, + InterfaceTypeDefinitionNode, + InterfaceTypeExtensionNode, + Kind, + ObjectTypeDefinitionNode, + ObjectTypeExtensionNode, + parse, + SchemaDefinitionNode, +} from 'graphql'; +import { stitchingDirectives } from './stitchingDirectives'; + +const extensionKind = /Extension$/; + +type EntityKind = + | ObjectTypeDefinitionNode + | ObjectTypeExtensionNode + | InterfaceTypeDefinitionNode + | InterfaceTypeExtensionNode; + +const entityKinds: typeof Kind[keyof typeof Kind][] = [ + Kind.OBJECT_TYPE_DEFINITION, + Kind.OBJECT_TYPE_EXTENSION, + Kind.INTERFACE_TYPE_DEFINITION, + Kind.INTERFACE_TYPE_EXTENSION, +]; + +function isEntityKind(def: DefinitionNode): def is EntityKind { + return entityKinds.includes(def.kind); +} + +function getQueryTypeDef(definitions: readonly DefinitionNode[]): ObjectTypeDefinitionNode | undefined { + const schemaDef = definitions.find(def => def.kind === Kind.SCHEMA_DEFINITION) as SchemaDefinitionNode; + const typeName = schemaDef + ? schemaDef.operationTypes.find(({ operation }) => operation === 'query')?.type.name.value + : 'Query'; + return definitions.find( + def => def.kind === Kind.OBJECT_TYPE_DEFINITION && def.name.value === typeName + ) as ObjectTypeDefinitionNode; +} + +// Federation services are actually fairly complex, +// as the `buildFederatedSchema` helper does a fair amount +// of hidden work to setup the Federation schema specification: +// https://www.apollographql.com/docs/federation/federation-spec/#federation-schema-specification +export function federationToStitchingSDL(federationSDL: string, stitchingConfig = stitchingDirectives()) { + const doc = parse(federationSDL); + const entityTypes: string[] = []; + const baseTypeNames = doc.definitions.reduce((memo, typeDef) => { + if (!extensionKind.test(typeDef.kind) && 'name' in typeDef && typeDef.name) { + memo[typeDef.name.value] = true; + } + return memo; + }, {}); + + doc.definitions.forEach(typeDef => { + // Un-extend all types (remove "extends" keywords)... + // extended types are invalid GraphQL without a local base type to extend from. + // Stitching merges flat types in lieu of hierarchical extensions. + if (extensionKind.test(typeDef.kind) && 'name' in typeDef && typeDef.name && !baseTypeNames[typeDef.name.value]) { + (typeDef.kind as string) = typeDef.kind.replace(extensionKind, 'Definition'); + } + + if (!isEntityKind(typeDef)) return; + + // Find object definitions with "@key" directives; + // these are federated entities that get turned into merged types. + const keyDirs: DirectiveNode[] = []; + const otherDirs: DirectiveNode[] = []; + + typeDef.directives?.forEach(dir => { + if (dir.name.value === 'key') { + keyDirs.push(dir); + } else { + otherDirs.push(dir); + } + }); + + if (!keyDirs.length) return; + + // Setup stitching MergedTypeConfig for all federated entities: + const selectionSet = `{ ${keyDirs.map((dir: any) => dir.arguments[0].value.value).join(' ')} }`; + const keyFields = (parse(selectionSet).definitions[0] as any).selectionSet.selections.map( + (sel: any) => sel.name.value + ); + const keyDir = keyDirs[0]; + (keyDir.name.value as string) = stitchingConfig.keyDirective.name; + + (keyDir.arguments as any)[0].name.value = 'selectionSet'; + (keyDir.arguments as any)[0].value.value = selectionSet; + (typeDef.directives as any[]) = [keyDir, ...otherDirs]; + + // Remove non-key "@external" fields from the type... + // the stitching query planner expects services to only publish their own fields. + // This makes "@provides" moot because the query planner can automate the logic. + (typeDef.fields as any) = typeDef.fields?.filter(fieldDef => { + return ( + keyFields.includes(fieldDef.name.value) || !fieldDef.directives?.find(dir => dir.name.value === 'external') + ); + }); + + // Discard remaining "@external" directives and any "@provides" directives + typeDef.fields?.forEach((fieldDef: any) => { + fieldDef.directives = fieldDef.directives.filter((dir: any) => !/^(external|provides)$/.test(dir.name.value)); + fieldDef.directives.forEach((dir: any) => { + if (dir.name.value === 'requires') { + dir.name.value = stitchingConfig.computedDirective.name; + dir.arguments[0].name.value = 'selectionSet'; + dir.arguments[0].value.value = `{ ${dir.arguments[0].value.value} }`; + } + }); + }); + + if (typeDef.kind === Kind.OBJECT_TYPE_DEFINITION || typeDef.kind === Kind.OBJECT_TYPE_EXTENSION) { + entityTypes.push(typeDef.name.value); + } + }); + + // Federation service SDLs are incomplete because they omit the federation spec itself... + // (https://www.apollographql.com/docs/federation/federation-spec/#federation-schema-specification) + // To make federation SDLs into valid and parsable GraphQL schemas, + // we must fill in the missing details from the specification. + if (entityTypes.length) { + const queryDef = getQueryTypeDef(doc.definitions); + const entitiesSchema = parse(` + scalar _Any + union _Entity = ${entityTypes.filter((v, i, a) => a.indexOf(v) === i).join(' | ')} + type Query { _entities(representations: [_Any!]!): [_Entity]! @${stitchingConfig.mergeDirective.name} } + `).definitions as unknown as DefinitionNode & { fields: any[] }; + + (doc.definitions as any).push(entitiesSchema[0]); + (doc.definitions as any).push(entitiesSchema[1]); + + if (queryDef) { + (queryDef.fields as any).push(entitiesSchema[2].fields[0]); + } else { + (doc.definitions as any).push(entitiesSchema[2]); + } + } + + return [stitchingConfig.stitchingDirectivesTypeDefs, print(doc)].join('\n'); +} diff --git a/packages/stitching-directives/src/index.ts b/packages/stitching-directives/src/index.ts index 864d8bfdc8e..3cbe75f12b8 100644 --- a/packages/stitching-directives/src/index.ts +++ b/packages/stitching-directives/src/index.ts @@ -1,2 +1,3 @@ export * from './stitchingDirectives'; export * from './types'; +export * from './federationToStitchingSDL'; diff --git a/packages/stitching-directives/tests/federationToStitchingSDL.test.ts b/packages/stitching-directives/tests/federationToStitchingSDL.test.ts new file mode 100644 index 00000000000..ff5f38d136c --- /dev/null +++ b/packages/stitching-directives/tests/federationToStitchingSDL.test.ts @@ -0,0 +1,141 @@ +import { federationToStitchingSDL } from "../src/federationToStitchingSDL"; +import { stitchingDirectives } from "../src/stitchingDirectives"; + +const defaultStitchingDirectives = stitchingDirectives(); + +function normalizeString(str: string) { + return str.replace('\n', ' ').replace(/\s+/g, ' ').trim(); +} + +describe('federation sdl', () => { + test('translates to stitching annotations', async () => { + const federationSdl = ` + extend type Product implements IProduct @key(fields: "id") { + id: ID! @external + weight: Int @external + shippingCost: Int @requires(fields: "weight") + parent: Product @provides(fields: "weight") + } + extend interface IProduct @key(fields: "id") { + id: ID! @external + weight: Int @external + shippingCost: Int @requires(fields: "weight") + parent: Product @provides(fields: "weight") + } + `; + + const stitchingSdl = ` + ${defaultStitchingDirectives.stitchingDirectivesTypeDefs} + type Product implements IProduct @key(selectionSet: "{ id }") { + id: ID! + shippingCost: Int @computed(selectionSet: "{ weight }") + parent: Product + } + interface IProduct @key(selectionSet: "{ id }") { + id: ID! + shippingCost: Int @computed(selectionSet: "{ weight }") + parent: Product + } + scalar _Any + union _Entity = Product + type Query { + _entities(representations: [_Any!]!): [_Entity]! @merge + } + `; + + const result = federationToStitchingSDL(federationSdl); + expect(normalizeString(result)).toEqual(normalizeString(stitchingSdl)); + }); + + test('adds _entities to existing Query', async () => { + const federationSdl = ` + extend type Product @key(fields: "id") { + id: ID! + } + type Query { + product(id: ID!): Product + } + `; + + const stitchingSdl = ` + ${defaultStitchingDirectives.stitchingDirectivesTypeDefs} + type Product @key(selectionSet: "{ id }") { + id: ID! + } + type Query { + product(id: ID!): Product + _entities(representations: [_Any!]!): [_Entity]! @merge + } + scalar _Any + union _Entity = Product + `; + + const result = federationToStitchingSDL(federationSdl); + expect(normalizeString(result)).toEqual(normalizeString(stitchingSdl)); + }); + + test('adds _entities to schema-defined query type', async () => { + const federationSdl = ` + extend type Product @key(fields: "id") { + id: ID! + } + type RootQuery { + product(id: ID!): Product + } + schema { + query: RootQuery + } + `; + + const stitchingSdl = ` + ${defaultStitchingDirectives.stitchingDirectivesTypeDefs} + type Product @key(selectionSet: "{ id }") { + id: ID! + } + type RootQuery { + product(id: ID!): Product + _entities(representations: [_Any!]!): [_Entity]! @merge + } + schema { + query: RootQuery + } + scalar _Any + union _Entity = Product + `; + + const result = federationToStitchingSDL(federationSdl); + expect(normalizeString(result)).toEqual(normalizeString(stitchingSdl)); + }); + + test('only un-extends types without a base', async () => { + const federationSdl = ` + extend type Product { + id: ID! + name: String + } + type Thing { + id: ID + } + extend type Thing { + name: String + } + `; + + const stitchingSdl = ` + ${defaultStitchingDirectives.stitchingDirectivesTypeDefs} + type Product { + id: ID! + name: String + } + type Thing { + id: ID + } + extend type Thing { + name: String + } + `; + + const result = federationToStitchingSDL(federationSdl); + expect(normalizeString(result)).toEqual(normalizeString(stitchingSdl)); + }); +}); diff --git a/website/docs/federation-to-stitching-sdl.md b/website/docs/federation-to-stitching-sdl.md new file mode 100644 index 00000000000..a81658811c4 --- /dev/null +++ b/website/docs/federation-to-stitching-sdl.md @@ -0,0 +1,121 @@ +--- +id: federation-to-stitching-sdl +title: Federation SDL to Stitching SDL +sidebar_label: Federation to Stitching +--- + +`federationToStitchingSDL` utility converts an [Apollo Federation SDL](https://www.apollographql.com/docs/federation/federation-spec/) string into a [Schema Stitching SDL](https://www.graphql-tools.com/docs/stitch-directives-sdl/) string. + +> ⚠️ NOTE: integration with Apollo Federation and its evolving roadmap is NOT a core concern of GraphQL Tools Schema Stitching. While the two systems have plenty of similarities and you can pull many strings to make them talk to each other, there is no formal contract that guarentees their interoperability. This package interfaces known commonalities between the two systems. Buyer beware that you're assuming your own testing and maintenance overhead if you choose to couple these systems in a production environment. + +Schema Stitching supports freeform service bindings that may integrate with any GraphQL query, including the `_entities` query setup by [Federation services](https://github.com/apollographql/federation). That means Federation SDLs may be converted to a Stitching SDL and added to a stitched gateway... + +**Federation SDL:** + +```graphql +type Widget @key(fields: "id") { + id: ID! @external + name: String + price: Int @external + shippingCost: Int @requires(fields: "price") + parent: Widget @provides(fields: "price") +} +``` + +**converted Stitching SDL:** + +```graphql +type Widget @key(selectionSet: "{ id }") { + id: ID! + name: String + shippingCost: Int @computed(selectionSet: "{ price }") + parent: Widget +} + +scalar _Any +union _Entity = Widget + +type Query { + _entities(representations: [_Any!]!): [_Entity]! @merge +} +``` + +The translated SDL is configured for the Schema Stitching query planner, see complete [translation logic](#translation-logic). + +## Usage + +Install the package: + +```shell +npm install federation-to-stitching-sdl +``` + +Fetch the SDL from a Federation service: + +```graphql +query { + _service { + sdl + } +} +``` + +Convert the Federation SDL to a Stitching SDL: + +```js +const { federationToStitchingSDL, stitchingDirectives } = require('@graphql-tools/stitching-directives'); + +// config is only needed when customizing stitching directive names... +const config = stitchingDirectives(); +const stitchingSDL = federationToStitchingSDL(federationSDL, config); +``` + +## Example + +A working example can be found in the [Schema Stitching Handbook](https://github.com/gmac/schema-stitching-handbook/tree/master/federation-services). A compact summary of the major parts looks like this: + +```js +const { stitchSchemas } = require('@graphql-tools/stitch'); +const { federationToStitchingSDL, stitchingDirectives } = require('@graphql-tools/stitching-directives'); +const { buildSchema, print } = require('graphql'); +const { fetch } = require('cross-fetch'); +const stitchingConfig = stitchingDirectives(); + +const executor = async ({ document, variables }) => { + const query = typeof document === 'string' ? document : print(document); + const result = await fetch('http://localhost:4001/graphql', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ query, variables }), + }); + return result.json(); +}; + +const federationSDL = await executor({ document: '{ _service { sdl } }' }); +const stitchingSDL = federationToStitchingSDL(federationSDL, stitchingConfig); + +const gatewaySchema = stitchSchemas({ + subschemaConfigTransforms: [stitchingConfig.stitchingDirectivesTransformer], + subschemas: [ + { + schema: buildSchema(stitchingSDL), + executor, + }, + ], +}); +``` + +## Translation logic + +Federation and Stitching use fundamentally similar patterns to combine underlying subservices (in fact, both tools have shared origins in [Apollo Stitching](https://www.apollographql.com/docs/federation/migrating-from-stitching/)). However, Federation SDLs are nuanced because they are incomplete (they omit their own [spec](https://www.apollographql.com/docs/federation/federation-spec/)), they may contain baseless type extensions (which are invalid GraphQL), and they may contain fields that the service has no data for (the "external" fields). These nuances are normalized for Schema Stitching as follows: + +1. Prepend a directives type definition string. +1. Turn all baseless type extensions into base types. +1. Rewrite `@key(fields: "id")` as `@key(selectionSet: "{ id }")`. +1. Rewrite `@requires(fields: "price")` as `@computed(selectionSet: "{ price }")`. +1. Remove fields with an `@external` directive _unless they are part of the `@key`_. Stitching expects schemas to only publish fields that they actually have data for. Remove any remaining `@external` directives. +1. Remove all `@provides` directives. They are no longer necessary once the indirection of `@external` fields is eliminated. Stitching's query planner can automate the optimial selection of as many fields as possible from as few services as possible. +1. Collect the names of all types marked with `@key` (Entities). If there are one or more names: + - Add an `_Any` scalar. + - Add an `_Entity` union populated with all unique names. + - Add an `_entities(representations: [_Any!]!): [_Entity]! @merge` query. diff --git a/website/sidebars.js b/website/sidebars.js index b614f8cd3dc..b3b0333c39a 100644 --- a/website/sidebars.js +++ b/website/sidebars.js @@ -19,6 +19,7 @@ module.exports = { "stitch-combining-schemas", "stitch-type-merging", "stitch-directives-sdl", + "federation-to-stitching", "stitch-schema-extensions", "stitch-api" ] From 651c314a56948c614259bf90aad3e8bcfa468b2b Mon Sep 17 00:00:00 2001 From: Yaacov Rydzinski Date: Tue, 6 Jul 2021 22:42:24 +0300 Subject: [PATCH 20/66] add all the helpers everywhere (#3145) --- packages/delegate/src/delegateToSchema.ts | 2 +- packages/delegate/src/getDefinedRootType.ts | 23 ------ .../src/transforms/AddArgumentsAsVariables.ts | 7 +- .../delegate/src/transforms/FilterToSchema.ts | 3 +- .../src/transforms/VisitSelectionSets.ts | 3 +- .../src/transforms/WrapConcreteTypes.ts | 8 +- packages/mock/src/addMocksToSchema.ts | 13 +--- packages/stitch/src/stitchSchemas.ts | 16 ++-- packages/stitch/src/typeCandidates.ts | 72 +++++++++--------- packages/utils/src/addTypes.ts | 38 ++-------- .../utils/src/build-operation-for-field.ts | 9 +-- .../utils/src/getObjectTypeFromTypeMap.ts | 15 ++++ packages/utils/src/index.ts | 1 + packages/utils/src/mapSchema.ts | 35 +++------ packages/utils/src/prune.ts | 4 +- packages/utils/src/rootTypes.ts | 73 +++++++++++++++++++ .../wrap/src/generateProxyingResolvers.ts | 58 +++++++-------- .../src/transforms/TransformRootFields.ts | 10 +-- 18 files changed, 188 insertions(+), 202 deletions(-) delete mode 100644 packages/delegate/src/getDefinedRootType.ts create mode 100644 packages/utils/src/getObjectTypeFromTypeMap.ts create mode 100644 packages/utils/src/rootTypes.ts diff --git a/packages/delegate/src/delegateToSchema.ts b/packages/delegate/src/delegateToSchema.ts index 49ede02f108..9431b4b1279 100644 --- a/packages/delegate/src/delegateToSchema.ts +++ b/packages/delegate/src/delegateToSchema.ts @@ -23,6 +23,7 @@ import { assertSome, AggregateError, isAsyncIterable, + getDefinedRootType, } from '@graphql-tools/utils'; import { @@ -37,7 +38,6 @@ import { isSubschemaConfig } from './subschemaConfig'; import { Subschema } from './Subschema'; import { createRequestFromInfo, getDelegatingOperation } from './createRequest'; import { Transformer } from './Transformer'; -import { getDefinedRootType } from './getDefinedRootType'; export function delegateToSchema, TArgs = any>( options: IDelegateToSchemaOptions diff --git a/packages/delegate/src/getDefinedRootType.ts b/packages/delegate/src/getDefinedRootType.ts deleted file mode 100644 index f45248855ec..00000000000 --- a/packages/delegate/src/getDefinedRootType.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { GraphQLObjectType, GraphQLSchema, OperationTypeNode } from 'graphql'; - -import { Maybe } from '../../utils/src/types'; - -export function getDefinedRootType(schema: GraphQLSchema, operation: OperationTypeNode): GraphQLObjectType { - let rootType: Maybe; - if (operation === 'query') { - rootType = schema.getQueryType(); - } else if (operation === 'mutation') { - rootType = schema.getMutationType(); - } else if (operation === 'subscription') { - rootType = schema.getSubscriptionType(); - } else { - // Future proof against new operation types - throw new Error(`Unknown operation "${operation}", cannot get root type.`); - } - - if (rootType == null) { - throw new Error(`Root type for operation "${operation}" not defined by the given schema.`); - } - - return rootType; -} diff --git a/packages/delegate/src/transforms/AddArgumentsAsVariables.ts b/packages/delegate/src/transforms/AddArgumentsAsVariables.ts index 9fabdb6f444..398a3131f5e 100644 --- a/packages/delegate/src/transforms/AddArgumentsAsVariables.ts +++ b/packages/delegate/src/transforms/AddArgumentsAsVariables.ts @@ -10,10 +10,9 @@ import { VariableDefinitionNode, } from 'graphql'; -import { Request, serializeInputValue, updateArgument } from '@graphql-tools/utils'; +import { getDefinedRootType, Request, serializeInputValue, updateArgument } from '@graphql-tools/utils'; import { Transform, DelegationContext } from '../types'; -import { getDefinedRootType } from '../getDefinedRootType'; export default class AddArgumentsAsVariables implements Transform { private readonly args: Record; @@ -72,10 +71,6 @@ function addVariablesToRootField( const type = getDefinedRootType(targetSchema, operation.operation); - if (type == null) { - throw new Error(`Schema missing root type for operation "${operation}".`); - } - const newSelectionSet: Array = []; for (const selection of operation.selectionSet.selections) { diff --git a/packages/delegate/src/transforms/FilterToSchema.ts b/packages/delegate/src/transforms/FilterToSchema.ts index 8a82564e284..22076b3ca82 100644 --- a/packages/delegate/src/transforms/FilterToSchema.ts +++ b/packages/delegate/src/transforms/FilterToSchema.ts @@ -21,10 +21,9 @@ import { isInterfaceType, } from 'graphql'; -import { Request, implementsAbstractType, TypeMap, assertSome } from '@graphql-tools/utils'; +import { Request, implementsAbstractType, TypeMap, assertSome, getDefinedRootType } from '@graphql-tools/utils'; import { Transform, DelegationContext } from '../types'; -import { getDefinedRootType } from '../getDefinedRootType'; export default class FilterToSchema implements Transform { public transformRequest( diff --git a/packages/delegate/src/transforms/VisitSelectionSets.ts b/packages/delegate/src/transforms/VisitSelectionSets.ts index 583538de1a7..0c7acb9efaf 100644 --- a/packages/delegate/src/transforms/VisitSelectionSets.ts +++ b/packages/delegate/src/transforms/VisitSelectionSets.ts @@ -13,10 +13,9 @@ import { DefinitionNode, } from 'graphql'; -import { Request, collectFields, GraphQLExecutionContext, Maybe } from '@graphql-tools/utils'; +import { Request, collectFields, GraphQLExecutionContext, Maybe, getDefinedRootType } from '@graphql-tools/utils'; import { Transform, DelegationContext } from '../types'; -import { getDefinedRootType } from '../getDefinedRootType'; type VisitSelectionSetsVisitor = (node: SelectionSetNode, typeInfo: TypeInfo) => Maybe; diff --git a/packages/delegate/src/transforms/WrapConcreteTypes.ts b/packages/delegate/src/transforms/WrapConcreteTypes.ts index 7c7bb5b0352..4b12e78a900 100644 --- a/packages/delegate/src/transforms/WrapConcreteTypes.ts +++ b/packages/delegate/src/transforms/WrapConcreteTypes.ts @@ -13,7 +13,7 @@ import { FragmentDefinitionNode, } from 'graphql'; -import { Request } from '@graphql-tools/utils'; +import { getRootTypeNames, Request } from '@graphql-tools/utils'; import { Transform, DelegationContext } from '../types'; @@ -48,9 +48,7 @@ function wrapConcreteTypes( return document; } - const queryTypeName = targetSchema.getQueryType()?.name; - const mutationTypeName = targetSchema.getMutationType()?.name; - const subscriptionTypeName = targetSchema.getSubscriptionType()?.name; + const rootTypeNames = getRootTypeNames(targetSchema); const typeInfo = new TypeInfo(targetSchema); const newDocument = visit( @@ -58,7 +56,7 @@ function wrapConcreteTypes( visitWithTypeInfo(typeInfo, { [Kind.FRAGMENT_DEFINITION]: (node: FragmentDefinitionNode) => { const typeName = node.typeCondition.name.value; - if (typeName !== queryTypeName && typeName !== mutationTypeName && typeName !== subscriptionTypeName) { + if (!rootTypeNames.has(typeName)) { return false; } }, diff --git a/packages/mock/src/addMocksToSchema.ts b/packages/mock/src/addMocksToSchema.ts index 52fbdeee102..b1b24219690 100644 --- a/packages/mock/src/addMocksToSchema.ts +++ b/packages/mock/src/addMocksToSchema.ts @@ -9,7 +9,7 @@ import { GraphQLInterfaceType, isSchema, } from 'graphql'; -import { mapSchema, MapperKind, IResolvers } from '@graphql-tools/utils'; +import { mapSchema, MapperKind, IResolvers, getRootTypeNames } from '@graphql-tools/utils'; import { addResolversToSchema } from '@graphql-tools/schema'; import { isRef, IMockStore, IMocks, TypePolicy } from './types'; import { copyOwnProps, isObject } from './utils'; @@ -243,14 +243,7 @@ export function addMocksToSchema({ } const isRootType = (type: GraphQLObjectType, schema: GraphQLSchema) => { - const queryType = schema.getQueryType(); - const isOnQueryType = queryType != null && queryType.name === type.name; + const rootTypeNames = getRootTypeNames(schema); - const mutationType = schema.getMutationType(); - const isOnMutationType = mutationType != null && mutationType.name === type.name; - - const subscriptionType = schema.getSubscriptionType(); - const isOnSubscriptionType = subscriptionType != null && subscriptionType.name === type.name; - - return isOnQueryType || isOnMutationType || isOnSubscriptionType; + return rootTypeNames.has(type.name); }; diff --git a/packages/stitch/src/stitchSchemas.ts b/packages/stitch/src/stitchSchemas.ts index 5bc564dc6ac..3678c7fe53e 100644 --- a/packages/stitch/src/stitchSchemas.ts +++ b/packages/stitch/src/stitchSchemas.ts @@ -86,13 +86,8 @@ export function stitchSchemas>({ return acc; }, Object.create(null)); const schemaDefs = Object.create(null); - const operationTypeNames = { - query: 'Query', - mutation: 'Mutation', - subscription: 'Subscription', - }; - const typeCandidates = buildTypeCandidates({ + const [typeCandidates, rootTypeNameMap] = buildTypeCandidates({ subschemas: transformedSubschemas, originalSubschemaMap, types, @@ -101,7 +96,6 @@ export function stitchSchemas>({ extensions, directiveMap, schemaDefs, - operationTypeNames, mergeDirectives, }); @@ -115,16 +109,16 @@ export function stitchSchemas>({ typeCandidates, directives, stitchingInfo, - operationTypeNames, + rootTypeNames: Object.values(rootTypeNameMap), onTypeConflict, mergeTypes, typeMergingOptions, }); let schema = new GraphQLSchema({ - query: newTypeMap[operationTypeNames.query] as GraphQLObjectType, - mutation: newTypeMap[operationTypeNames.mutation] as GraphQLObjectType, - subscription: newTypeMap[operationTypeNames.subscription] as GraphQLObjectType, + query: newTypeMap[rootTypeNameMap.query] as GraphQLObjectType, + mutation: newTypeMap[rootTypeNameMap.mutation] as GraphQLObjectType, + subscription: newTypeMap[rootTypeNameMap.subscription] as GraphQLObjectType, types: Object.keys(newTypeMap).map(key => newTypeMap[key]), directives: newDirectives, astNode: schemaDefs.schemaDef, diff --git a/packages/stitch/src/typeCandidates.ts b/packages/stitch/src/typeCandidates.ts index 7d356cdc535..7bb1d75c470 100644 --- a/packages/stitch/src/typeCandidates.ts +++ b/packages/stitch/src/typeCandidates.ts @@ -9,11 +9,13 @@ import { isSpecifiedScalarType, GraphQLSchema, isDirective, + GraphQLObjectType, + OperationTypeNode, } from 'graphql'; import { wrapSchema } from '@graphql-tools/wrap'; import { Subschema, SubschemaConfig, StitchingInfo } from '@graphql-tools/delegate'; -import { GraphQLParseOptions, TypeSource, rewireTypes, TypeMap } from '@graphql-tools/utils'; +import { GraphQLParseOptions, TypeSource, rewireTypes, TypeMap, getRootTypeMap } from '@graphql-tools/utils'; import typeFromAST from './typeFromAST'; import { MergeTypeCandidate, MergeTypeFilter, OnTypeConflict, TypeMergingOptions } from './types'; @@ -34,7 +36,6 @@ export function buildTypeCandidates>({ extensions, directiveMap, schemaDefs, - operationTypeNames, mergeDirectives, }: { subschemas: Array>; @@ -51,9 +52,8 @@ export function buildTypeCandidates>({ schemaDef: SchemaDefinitionNode; schemaExtensions: Array; }; - operationTypeNames: Record; mergeDirectives?: boolean | undefined; -}): Record>> { +}): [Record>>, Record] { const typeCandidates: Record>> = Object.create(null); let schemaDef: SchemaDefinitionNode | undefined; @@ -71,25 +71,20 @@ export function buildTypeCandidates>({ schemaDefs.schemaDef = schemaDef ?? schemaDefs.schemaDef; schemaDefs.schemaExtensions = schemaExtensions; - setOperationTypeNames(schemaDefs, operationTypeNames); + const rootTypeNameMap = getRootTypeNameMap(schemaDefs); for (const subschema of subschemas) { const schema = wrapSchema(subschema); - const operationTypes = { - query: schema.getQueryType(), - mutation: schema.getMutationType(), - subscription: schema.getSubscriptionType(), - }; + const rootTypeMap = getRootTypeMap(schema); + const rootTypes = Array.from(rootTypeMap.values()); - for (const operationType in operationTypes) { - if (operationTypes[operationType] != null) { - addTypeCandidate(typeCandidates, operationTypeNames[operationType], { - type: operationTypes[operationType], - subschema: originalSubschemaMap.get(subschema), - transformedSubschema: subschema, - }); - } + for (const [operation, rootType] of rootTypeMap.entries()) { + addTypeCandidate(typeCandidates, rootTypeNameMap[operation], { + type: rootType, + subschema: originalSubschemaMap.get(subschema), + transformedSubschema: subschema, + }); } if (mergeDirectives === true) { @@ -104,9 +99,7 @@ export function buildTypeCandidates>({ if ( isNamedType(type) && getNamedType(type).name.slice(0, 2) !== '__' && - type !== operationTypes.query && - type !== operationTypes.mutation && - type !== operationTypes.subscription + !rootTypes.includes(type as GraphQLObjectType) ) { addTypeCandidate(typeCandidates, type.name, { type, @@ -148,19 +141,22 @@ export function buildTypeCandidates>({ addTypeCandidate(typeCandidates, type.name, { type }); } - return typeCandidates; + return [typeCandidates, rootTypeNameMap]; } -function setOperationTypeNames( - { - schemaDef, - schemaExtensions, - }: { - schemaDef: SchemaDefinitionNode; - schemaExtensions: Array; - }, - operationTypeNames: Record -): void { +function getRootTypeNameMap({ + schemaDef, + schemaExtensions, +}: { + schemaDef: SchemaDefinitionNode; + schemaExtensions: Array; +}): Record { + const rootTypeNameMap: Record = { + query: 'Query', + mutation: 'Mutation', + subscription: 'Subscription', + }; + const allNodes: Array = schemaExtensions.slice(); if (schemaDef != null) { allNodes.unshift(schemaDef); @@ -169,10 +165,12 @@ function setOperationTypeNames( for (const node of allNodes) { if (node.operationTypes != null) { for (const operationType of node.operationTypes) { - operationTypeNames[operationType.operation] = operationType.type.name.value; + rootTypeNameMap[operationType.operation] = operationType.type.name.value; } } } + + return rootTypeNameMap; } function addTypeCandidate>( @@ -190,7 +188,7 @@ export function buildTypes>({ typeCandidates, directives, stitchingInfo, - operationTypeNames, + rootTypeNames, onTypeConflict, mergeTypes, typeMergingOptions, @@ -198,7 +196,7 @@ export function buildTypes>({ typeCandidates: Record>>; directives: Array; stitchingInfo: StitchingInfo; - operationTypeNames: Record; + rootTypeNames: Array; onTypeConflict?: OnTypeConflict; mergeTypes: boolean | Array | MergeTypeFilter; typeMergingOptions?: TypeMergingOptions; @@ -207,9 +205,7 @@ export function buildTypes>({ for (const typeName in typeCandidates) { if ( - typeName === operationTypeNames['query'] || - typeName === operationTypeNames['mutation'] || - typeName === operationTypeNames['subscription'] || + rootTypeNames.includes(typeName) || (mergeTypes === true && !typeCandidates[typeName].some(candidate => isSpecifiedScalarType(candidate.type))) || (typeof mergeTypes === 'function' && mergeTypes(typeCandidates[typeName], typeName)) || (Array.isArray(mergeTypes) && mergeTypes.includes(typeName)) || diff --git a/packages/utils/src/addTypes.ts b/packages/utils/src/addTypes.ts index ae4859c3c2d..174b9172592 100644 --- a/packages/utils/src/addTypes.ts +++ b/packages/utils/src/addTypes.ts @@ -26,29 +26,15 @@ // enhanceSchema can fill this gap by adding an additional round of rewiring. // -import { - GraphQLObjectType, - GraphQLSchema, - GraphQLNamedType, - GraphQLDirective, - isNamedType, - isDirective, - isObjectType, -} from 'graphql'; +import { GraphQLSchema, GraphQLNamedType, GraphQLDirective, isNamedType, isDirective } from 'graphql'; + +import { getObjectTypeFromTypeMap } from './getObjectTypeFromTypeMap'; import { rewireTypes } from './rewire'; export function addTypes( schema: GraphQLSchema, newTypesOrDirectives: Array ): GraphQLSchema { - const queryType = schema.getQueryType(); - const mutationType = schema.getMutationType(); - const subscriptionType = schema.getSubscriptionType(); - - const queryTypeName = queryType != null ? queryType.name : undefined; - const mutationTypeName = mutationType != null ? mutationType.name : undefined; - const subscriptionTypeName = subscriptionType != null ? subscriptionType.name : undefined; - const config = schema.toConfig(); const originalTypeMap: Record = {}; @@ -73,22 +59,10 @@ export function addTypes( return new GraphQLSchema({ ...config, - query: getObjectTypeFromTypeMap(typeMap, queryTypeName), - mutation: getObjectTypeFromTypeMap(typeMap, mutationTypeName), - subscription: getObjectTypeFromTypeMap(typeMap, subscriptionTypeName), + query: getObjectTypeFromTypeMap(typeMap, schema.getQueryType()), + mutation: getObjectTypeFromTypeMap(typeMap, schema.getMutationType()), + subscription: getObjectTypeFromTypeMap(typeMap, schema.getSubscriptionType()), types: Object.values(typeMap), directives, }); } - -export function getObjectTypeFromTypeMap( - typeMap: Record, - typeName?: string -): GraphQLObjectType | undefined { - if (typeName) { - const maybeObjectType = typeMap[typeName]; - if (isObjectType(maybeObjectType)) { - return maybeObjectType; - } - } -} diff --git a/packages/utils/src/build-operation-for-field.ts b/packages/utils/src/build-operation-for-field.ts index 87652876f51..c9f45f1d975 100644 --- a/packages/utils/src/build-operation-for-field.ts +++ b/packages/utils/src/build-operation-for-field.ts @@ -28,6 +28,8 @@ import { Kind, } from 'graphql'; +import { getDefinedRootType } from './rootTypes'; + let operationVariables: VariableDefinitionNode[] = []; let fieldTypeMap = new Map(); @@ -119,12 +121,7 @@ function buildOperationAndCollectVariables({ argNames?: string[]; selectedFields: SelectedFields; }): OperationDefinitionNode { - const typeMap: Record = { - query: schema.getQueryType()!, - mutation: schema.getMutationType()!, - subscription: schema.getSubscriptionType()!, - }; - const type = typeMap[kind]; + const type = getDefinedRootType(schema, kind); const field = type.getFields()[fieldName]; const operationName = `${fieldName}_${kind}`; diff --git a/packages/utils/src/getObjectTypeFromTypeMap.ts b/packages/utils/src/getObjectTypeFromTypeMap.ts new file mode 100644 index 00000000000..a4f67aa0162 --- /dev/null +++ b/packages/utils/src/getObjectTypeFromTypeMap.ts @@ -0,0 +1,15 @@ +import { GraphQLNamedType, GraphQLObjectType, isObjectType } from 'graphql'; + +import { Maybe } from './types'; + +export function getObjectTypeFromTypeMap( + typeMap: Record, + type: Maybe +): GraphQLObjectType | undefined { + if (type) { + const maybeObjectType = typeMap[type.name]; + if (isObjectType(maybeObjectType)) { + return maybeObjectType; + } + } +} diff --git a/packages/utils/src/index.ts b/packages/utils/src/index.ts index 5fc559f2755..bc3f4a892c7 100644 --- a/packages/utils/src/index.ts +++ b/packages/utils/src/index.ts @@ -46,3 +46,4 @@ export * from './astFromValueUntyped'; export * from './executor'; export * from './withCancel'; export * from './AggregateError'; +export * from './rootTypes'; diff --git a/packages/utils/src/mapSchema.ts b/packages/utils/src/mapSchema.ts index d80b8e1284b..245728272e8 100644 --- a/packages/utils/src/mapSchema.ts +++ b/packages/utils/src/mapSchema.ts @@ -29,7 +29,8 @@ import { Kind, EnumValueDefinitionNode, } from 'graphql'; -import { getObjectTypeFromTypeMap } from './addTypes'; + +import { getObjectTypeFromTypeMap } from './getObjectTypeFromTypeMap'; import { SchemaMapper, @@ -76,21 +77,13 @@ export function mapSchema(schema: GraphQLSchema, schemaMapper: SchemaMapper = {} const originalDirectives = schema.getDirectives(); const newDirectives = mapDirectives(originalDirectives, schema, schemaMapper); - const queryType = schema.getQueryType(); - const mutationType = schema.getMutationType(); - const subscriptionType = schema.getSubscriptionType(); - - const newQueryTypeName = queryType?.name && newTypeMap?.[queryType?.name]?.name; - const newMutationTypeName = mutationType?.name && newTypeMap?.[mutationType?.name]?.name; - const newSubscriptionTypeName = subscriptionType?.name && newTypeMap?.[subscriptionType?.name]?.name; - const { typeMap, directives } = rewireTypes(newTypeMap, newDirectives); return new GraphQLSchema({ ...schema.toConfig(), - query: getObjectTypeFromTypeMap(typeMap, newQueryTypeName), - mutation: getObjectTypeFromTypeMap(typeMap, newMutationTypeName), - subscription: getObjectTypeFromTypeMap(typeMap, newSubscriptionTypeName), + query: getObjectTypeFromTypeMap(typeMap, getObjectTypeFromTypeMap(newTypeMap, schema.getQueryType())), + mutation: getObjectTypeFromTypeMap(typeMap, getObjectTypeFromTypeMap(newTypeMap, schema.getMutationType())), + subscription: getObjectTypeFromTypeMap(typeMap, getObjectTypeFromTypeMap(newTypeMap, schema.getSubscriptionType())), types: Object.values(typeMap), directives, }); @@ -407,14 +400,11 @@ function getTypeSpecifiers(schema: GraphQLSchema, typeName: string): Array = Object.create(null); - const rootTypes = [schema.getQueryType(), schema.getMutationType(), schema.getSubscriptionType()].filter(isSome); + const rootTypes = getRootTypes(schema); for (const rootType of rootTypes) { visitOutputType(visitedTypes, pruningContext, rootType); diff --git a/packages/utils/src/rootTypes.ts b/packages/utils/src/rootTypes.ts new file mode 100644 index 00000000000..c7ab9676cd7 --- /dev/null +++ b/packages/utils/src/rootTypes.ts @@ -0,0 +1,73 @@ +import { GraphQLObjectType, GraphQLSchema, OperationTypeNode } from 'graphql'; +import { Maybe } from './types'; + +export function getDefinedRootType(schema: GraphQLSchema, operation: OperationTypeNode): GraphQLObjectType { + let rootType: Maybe; + if (operation === 'query') { + rootType = schema.getQueryType(); + } else if (operation === 'mutation') { + rootType = schema.getMutationType(); + } else if (operation === 'subscription') { + rootType = schema.getSubscriptionType(); + } else { + // Future proof against new operation types + throw new Error(`Unknown operation "${operation}", cannot get root type.`); + } + + if (rootType == null) { + throw new Error(`Root type for operation "${operation}" not defined by the given schema.`); + } + + return rootType; +} + +export function getRootTypeNames(schema: GraphQLSchema): Set { + const rootTypeNames: Set = new Set(); + const queryType = schema.getQueryType(); + const mutationType = schema.getMutationType(); + const subscriptionType = schema.getSubscriptionType(); + + for (const rootType of [queryType, mutationType, subscriptionType]) { + if (rootType) { + rootTypeNames.add(rootType.name); + } + } + + return rootTypeNames; +} + +export function getRootTypes(schema: GraphQLSchema): Set { + const rootTypes: Set = new Set(); + const queryType = schema.getQueryType(); + const mutationType = schema.getMutationType(); + const subscriptionType = schema.getSubscriptionType(); + + for (const rootType of [queryType, mutationType, subscriptionType]) { + if (rootType) { + rootTypes.add(rootType); + } + } + + return rootTypes; +} + +export function getRootTypeMap(schema: GraphQLSchema): Map { + const rootTypeMap: Map = new Map(); + + const queryType = schema.getQueryType(); + if (queryType) { + rootTypeMap.set('query', queryType); + } + + const mutationType = schema.getMutationType(); + if (mutationType) { + rootTypeMap.set('mutation', mutationType); + } + + const subscriptionType = schema.getSubscriptionType(); + if (subscriptionType) { + rootTypeMap.set('subscription', subscriptionType); + } + + return rootTypeMap; +} diff --git a/packages/wrap/src/generateProxyingResolvers.ts b/packages/wrap/src/generateProxyingResolvers.ts index e394509003d..aafe5f38625 100644 --- a/packages/wrap/src/generateProxyingResolvers.ts +++ b/packages/wrap/src/generateProxyingResolvers.ts @@ -1,6 +1,6 @@ -import { GraphQLFieldResolver, GraphQLObjectType, GraphQLResolveInfo, OperationTypeNode } from 'graphql'; +import { GraphQLFieldResolver, GraphQLResolveInfo } from 'graphql'; -import { Maybe, getResponseKeyFromInfo } from '@graphql-tools/utils'; +import { getResponseKeyFromInfo, getRootTypeMap } from '@graphql-tools/utils'; import { delegateToSchema, getSubschema, @@ -20,42 +20,34 @@ export function generateProxyingResolvers( const transformedSchema = applySchemaTransforms(targetSchema, subschemaConfig); - const operationTypes: Record> = { - query: targetSchema.getQueryType(), - mutation: targetSchema.getMutationType(), - subscription: targetSchema.getSubscriptionType(), - }; + const rootTypeMap = getRootTypeMap(targetSchema); const resolvers = {}; - for (const operationAsString in operationTypes) { - const operation = operationAsString as OperationTypeNode; - const rootType = operationTypes[operation]; - if (rootType != null) { - const typeName = rootType.name; - const fields = rootType.getFields(); + for (const [operation, rootType] of rootTypeMap.entries()) { + const typeName = rootType.name; + const fields = rootType.getFields(); - resolvers[typeName] = {}; - for (const fieldName in fields) { - const proxyingResolver = createProxyingResolver({ - subschemaConfig, - transformedSchema, - operation, - fieldName, - }); + resolvers[typeName] = {}; + for (const fieldName in fields) { + const proxyingResolver = createProxyingResolver({ + subschemaConfig, + transformedSchema, + operation, + fieldName, + }); - const finalResolver = createPossiblyNestedProxyingResolver(subschemaConfig, proxyingResolver); + const finalResolver = createPossiblyNestedProxyingResolver(subschemaConfig, proxyingResolver); - if (operation === 'subscription') { - resolvers[typeName][fieldName] = { - subscribe: finalResolver, - resolve: (payload: any, _: never, __: never, { fieldName: targetFieldName }: GraphQLResolveInfo) => - payload[targetFieldName], - }; - } else { - resolvers[typeName][fieldName] = { - resolve: finalResolver, - }; - } + if (operation === 'subscription') { + resolvers[typeName][fieldName] = { + subscribe: finalResolver, + resolve: (payload: any, _: never, __: never, { fieldName: targetFieldName }: GraphQLResolveInfo) => + payload[targetFieldName], + }; + } else { + resolvers[typeName][fieldName] = { + resolve: finalResolver, + }; } } } diff --git a/packages/wrap/src/transforms/TransformRootFields.ts b/packages/wrap/src/transforms/TransformRootFields.ts index bd0193108ea..403bde123cd 100644 --- a/packages/wrap/src/transforms/TransformRootFields.ts +++ b/packages/wrap/src/transforms/TransformRootFields.ts @@ -28,24 +28,20 @@ export default class TransformRootFields implements Transform { subschemaConfig: SubschemaConfig, transformedSchema?: GraphQLSchema ): GraphQLSchema { - const queryTypeName = originalWrappingSchema.getQueryType()?.name; - const mutationTypeName = originalWrappingSchema.getMutationType()?.name; - const subscriptionTypeName = originalWrappingSchema.getSubscriptionType()?.name; - const rootToObjectFieldTransformer = ( typeName: string, fieldName: string, fieldConfig: GraphQLFieldConfig ) => { - if (typeName === queryTypeName) { + if (typeName === originalWrappingSchema.getQueryType()?.name) { return this.rootFieldTransformer('Query', fieldName, fieldConfig); } - if (typeName === mutationTypeName) { + if (typeName === originalWrappingSchema.getMutationType()?.name) { return this.rootFieldTransformer('Mutation', fieldName, fieldConfig); } - if (typeName === subscriptionTypeName) { + if (typeName === originalWrappingSchema.getSubscriptionType()?.name) { return this.rootFieldTransformer('Subscription', fieldName, fieldConfig); } From a3fa243ec9907103278d42a1e1495472bd798517 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 6 Jul 2021 20:22:25 +0000 Subject: [PATCH 21/66] chore(deps): update dependency @types/babel__traverse to v7.14.1 (#3146) Co-authored-by: Renovate Bot --- packages/graphql-tag-pluck/package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/graphql-tag-pluck/package.json b/packages/graphql-tag-pluck/package.json index 4b7f706e36c..c44a6903f5e 100644 --- a/packages/graphql-tag-pluck/package.json +++ b/packages/graphql-tag-pluck/package.json @@ -36,7 +36,7 @@ "tslib": "~2.3.0" }, "devDependencies": { - "@types/babel__traverse": "7.14.0", + "@types/babel__traverse": "7.14.1", "@vue/compiler-sfc": "3.1.4" }, "buildOptions": { diff --git a/yarn.lock b/yarn.lock index bc27d6fd85e..bd41306d408 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2457,10 +2457,10 @@ "@babel/parser" "^7.1.0" "@babel/types" "^7.0.0" -"@types/babel__traverse@*", "@types/babel__traverse@7.14.0", "@types/babel__traverse@^7.0.4", "@types/babel__traverse@^7.0.6": - version "7.14.0" - resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.14.0.tgz#a34277cf8acbd3185ea74129e1f100491eb1da7f" - integrity sha512-IilJZ1hJBUZwMOVDNTdflOOLzJB/ZtljYVa7k3gEZN/jqIJIPkWHC6dvbX+DD2CwZDHB9wAKzZPzzqMIkW37/w== +"@types/babel__traverse@*", "@types/babel__traverse@7.14.1", "@types/babel__traverse@^7.0.4", "@types/babel__traverse@^7.0.6": + version "7.14.1" + resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.14.1.tgz#46c2f9501a7a8f0596ddfd365e08c15285a47cce" + integrity sha512-DomsDK/nX3XXHs6jlQ8/YYE6jZAuhmoGAFfcYi1h1jbBNGS7Efdx74FKLTO3HCCyLqQyLlNbql87xqa7C3M/FQ== dependencies: "@babel/types" "^7.3.0" From b9e40d6db9130ab68b36389801d9fe3201701685 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 6 Jul 2021 23:18:00 +0000 Subject: [PATCH 22/66] chore(deps): update dependency @types/extract-files to v8.1.1 (#3148) Co-authored-by: Renovate Bot --- packages/loaders/url/package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/loaders/url/package.json b/packages/loaders/url/package.json index a238ad6db93..c43092cd922 100644 --- a/packages/loaders/url/package.json +++ b/packages/loaders/url/package.json @@ -35,7 +35,7 @@ "graphql": "^14.0.0 || ^15.0.0" }, "devDependencies": { - "@types/extract-files": "8.1.0", + "@types/extract-files": "8.1.1", "@types/ws": "7.4.6", "graphql-upload": "12.0.0", "mock-http": "1.1.0", diff --git a/yarn.lock b/yarn.lock index bd41306d408..e5b2ccb9c0b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2554,10 +2554,10 @@ "@types/qs" "*" "@types/serve-static" "*" -"@types/extract-files@*", "@types/extract-files@8.1.0": - version "8.1.0" - resolved "https://registry.yarnpkg.com/@types/extract-files/-/extract-files-8.1.0.tgz#4728440e1d92a6d1d11ac47f5a10e3f9ce47f044" - integrity sha512-ulxvlFU71yLVV3JxdBgryASAIp+aZQuQOpkhU1SznJlcWz0qsJCWHqdJqP6Lprs3blqGS5FH5GbBkU0977+Wew== +"@types/extract-files@*", "@types/extract-files@8.1.1": + version "8.1.1" + resolved "https://registry.yarnpkg.com/@types/extract-files/-/extract-files-8.1.1.tgz#11b67e795ad2c8b483431e8d4f190db2fd22944b" + integrity sha512-dMJJqBqyhsfJKuK7p7HyyNmki7qj1AlwhUKWx6KrU7i1K2T2SPsUsSUTWFmr/sEM1q8rfR8j5IyUmYrDbrhfjQ== "@types/fs-capacitor@*": version "2.0.0" From ba10181fcd810c763998ecff25a45af16a181342 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 6 Jul 2021 20:28:44 -0400 Subject: [PATCH 23/66] chore(deps): update dependency @types/jest to v26.0.24 (#3152) Co-authored-by: Renovate Bot --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 6dedb306417..139ff330347 100644 --- a/package.json +++ b/package.json @@ -49,7 +49,7 @@ "@babel/preset-env": "7.14.7", "@babel/preset-typescript": "7.14.5", "@changesets/cli": "2.16.0", - "@types/jest": "26.0.23", + "@types/jest": "26.0.24", "@types/node": "14.17.4", "@typescript-eslint/eslint-plugin": "4.28.2", "@typescript-eslint/parser": "4.28.2", diff --git a/yarn.lock b/yarn.lock index e5b2ccb9c0b..ba6cf6eca40 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2642,10 +2642,10 @@ dependencies: "@types/istanbul-lib-report" "*" -"@types/jest@26.0.23": - version "26.0.23" - resolved "https://registry.yarnpkg.com/@types/jest/-/jest-26.0.23.tgz#a1b7eab3c503b80451d019efb588ec63522ee4e7" - integrity sha512-ZHLmWMJ9jJ9PTiT58juykZpL7KjwJywFN3Rr2pTSkyQfydf/rk22yS7W8p5DaVUMQ2BQC7oYiU3FjbTM/mYrOA== +"@types/jest@26.0.24": + version "26.0.24" + resolved "https://registry.yarnpkg.com/@types/jest/-/jest-26.0.24.tgz#943d11976b16739185913a1936e0de0c4a7d595a" + integrity sha512-E/X5Vib8BWqZNRlDxj9vYXhsDwPYbPINqKF9BsnSoon4RQ0D9moEuLD8txgyypFLH7J4+Lho9Nr/c8H0Fi+17w== dependencies: jest-diff "^26.0.0" pretty-format "^26.0.0" From 50bdb97713409ff1825a32355e12b2d60f75a504 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 6 Jul 2021 20:28:50 -0400 Subject: [PATCH 24/66] chore(deps): update dependency @types/is-glob to v4.0.2 (#3151) Co-authored-by: Renovate Bot --- packages/load/package.json | 2 +- packages/loaders/code-file/package.json | 2 +- packages/loaders/graphql-file/package.json | 2 +- yarn.lock | 8 ++++---- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/packages/load/package.json b/packages/load/package.json index e1dc1f4bd99..65438569349 100644 --- a/packages/load/package.json +++ b/packages/load/package.json @@ -30,7 +30,7 @@ "graphql": "^14.0.0 || ^15.0.0" }, "devDependencies": { - "@types/is-glob": "4.0.1", + "@types/is-glob": "4.0.2", "@types/valid-url": "1.0.3", "graphql-tag": "2.12.5", "graphql-type-json": "0.3.2" diff --git a/packages/loaders/code-file/package.json b/packages/loaders/code-file/package.json index 8cb1f297bd4..160ece71648 100644 --- a/packages/loaders/code-file/package.json +++ b/packages/loaders/code-file/package.json @@ -27,7 +27,7 @@ "definition": "dist/index.d.ts" }, "devDependencies": { - "@types/is-glob": "4.0.1" + "@types/is-glob": "4.0.2" }, "peerDependencies": { "graphql": "^14.0.0 || ^15.0.0" diff --git a/packages/loaders/graphql-file/package.json b/packages/loaders/graphql-file/package.json index aea17e2cb30..cb7b2513ef5 100644 --- a/packages/loaders/graphql-file/package.json +++ b/packages/loaders/graphql-file/package.json @@ -33,7 +33,7 @@ "input": "./src/index.ts" }, "devDependencies": { - "@types/is-glob": "4.0.1" + "@types/is-glob": "4.0.2" }, "dependencies": { "@graphql-tools/import": "^6.2.6", diff --git a/yarn.lock b/yarn.lock index ba6cf6eca40..4bf434a48c7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2618,10 +2618,10 @@ resolved "https://registry.yarnpkg.com/@types/http-errors/-/http-errors-1.8.0.tgz#682477dbbbd07cd032731cb3b0e7eaee3d026b69" integrity sha512-2aoSC4UUbHDj2uCsCxcG/vRMXey/m17bC7UwitVm5hn22nI8O8Y9iDpA76Orc+DWkQ4zZrOKEshCqR/jSuXAHA== -"@types/is-glob@4.0.1": - version "4.0.1" - resolved "https://registry.yarnpkg.com/@types/is-glob/-/is-glob-4.0.1.tgz#a93eec1714172c8eb3225a1cc5eb88c2477b7d00" - integrity sha512-k3RS5HyBPu4h+5hTmIEfPB2rl5P3LnGdQEZrV2b9OWTJVtsUQ2VBcedqYKGqxvZqle5UALUXdSfVA8nf3HfyWQ== +"@types/is-glob@4.0.2": + version "4.0.2" + resolved "https://registry.yarnpkg.com/@types/is-glob/-/is-glob-4.0.2.tgz#c243dd0d09eac2992130142419ff2308ffd988bf" + integrity sha512-4j5G9Y5jljDSICQ1R2f/Rcyoj6DZmYGneny+p/cDkjep0rkqNg0W73Ty0bVjMUTZgLXHf8oiMjg1XC3CDwCz+g== "@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0", "@types/istanbul-lib-coverage@^2.0.1": version "2.0.3" From 5033a5a877dc23c2b774d7fb91098928a20534e7 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 6 Jul 2021 20:28:57 -0400 Subject: [PATCH 25/66] chore(deps): update dependency @types/graphql-upload to v8.0.6 (#3149) Co-authored-by: Renovate Bot --- packages/links/package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/links/package.json b/packages/links/package.json index 4b209f92e3b..fe19fba0cb0 100644 --- a/packages/links/package.json +++ b/packages/links/package.json @@ -40,7 +40,7 @@ "devDependencies": { "@apollo/client": "3.3.21", "@types/apollo-upload-client": "14.1.0", - "@types/graphql-upload": "8.0.5", + "@types/graphql-upload": "8.0.6", "express-graphql": "0.12.0", "graphql-upload": "12.0.0" }, diff --git a/yarn.lock b/yarn.lock index 4bf434a48c7..8d52f53c37b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2586,10 +2586,10 @@ dependencies: "@types/node" "*" -"@types/graphql-upload@8.0.5": - version "8.0.5" - resolved "https://registry.yarnpkg.com/@types/graphql-upload/-/graphql-upload-8.0.5.tgz#d6adce53f82630e59dca8900c2285877ae61b9eb" - integrity sha512-h01wGd+0wzEGZhTi5609xTRheTtHaDOIG21NEb6UP2O9FcyU6FeMiTq2rLzjtN3JL2b0HKhwYhIzEe8XLTPerw== +"@types/graphql-upload@8.0.6": + version "8.0.6" + resolved "https://registry.yarnpkg.com/@types/graphql-upload/-/graphql-upload-8.0.6.tgz#6212b69fabb171389ca3c29e0a54b8c0d7b12301" + integrity sha512-PNFVwWMy1btDKN51ncAZbD2sTFdqGq416Tk/pUC/U5op97Vg0uw9/4psOPkDn+oEZMJjH0xMMFyJAH2lnoOxSA== dependencies: "@types/express" "*" "@types/fs-capacitor" "*" From a4357c9f18bec0b49a78231cbc792b02e77ea952 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 7 Jul 2021 01:18:38 +0000 Subject: [PATCH 26/66] chore(deps): update dependency @types/lodash to v4.14.171 (#3153) Co-authored-by: Renovate Bot --- packages/resolvers-composition/package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/resolvers-composition/package.json b/packages/resolvers-composition/package.json index ba6fc246eec..3091008687d 100644 --- a/packages/resolvers-composition/package.json +++ b/packages/resolvers-composition/package.json @@ -30,7 +30,7 @@ "graphql": "^14.0.0 || ^15.0.0" }, "devDependencies": { - "@types/lodash": "4.14.170", + "@types/lodash": "4.14.171", "@types/micromatch": "4.0.1" }, "dependencies": { diff --git a/yarn.lock b/yarn.lock index 8d52f53c37b..7b4f2fd06ad 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2703,10 +2703,10 @@ "@types/koa-compose" "*" "@types/node" "*" -"@types/lodash@4.14.170": - version "4.14.170" - resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.170.tgz#0d67711d4bf7f4ca5147e9091b847479b87925d6" - integrity sha512-bpcvu/MKHHeYX+qeEN8GE7DIravODWdACVA1ctevD8CN24RhPZIKMn9ntfAsrvLfSX3cR5RrBKAbYm9bGs0A+Q== +"@types/lodash@4.14.171": + version "4.14.171" + resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.171.tgz#f01b3a5fe3499e34b622c362a46a609fdb23573b" + integrity sha512-7eQ2xYLLI/LsicL2nejW9Wyko3lcpN6O/z0ZLHrEQsg280zIdCv1t/0m6UtBjUHokCGBQ3gYTbHzDkZ1xOBwwg== "@types/mdast@^3.0.0": version "3.0.3" From f05dffa2d3d2519cb3f9200fd0e0b1993dc18b1c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 7 Jul 2021 02:46:17 +0000 Subject: [PATCH 27/66] chore(deps): update dependency @types/micromatch to v4.0.2 (#3154) Co-authored-by: Renovate Bot --- packages/resolvers-composition/package.json | 2 +- yarn.lock | 9 ++++++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/packages/resolvers-composition/package.json b/packages/resolvers-composition/package.json index 3091008687d..fd419cf1b09 100644 --- a/packages/resolvers-composition/package.json +++ b/packages/resolvers-composition/package.json @@ -31,7 +31,7 @@ }, "devDependencies": { "@types/lodash": "4.14.171", - "@types/micromatch": "4.0.1" + "@types/micromatch": "4.0.2" }, "dependencies": { "@graphql-tools/utils": "^7.9.1", diff --git a/yarn.lock b/yarn.lock index 7b4f2fd06ad..6a55f4945f0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2715,7 +2715,14 @@ dependencies: "@types/unist" "*" -"@types/micromatch@4.0.1", "@types/micromatch@latest": +"@types/micromatch@4.0.2": + version "4.0.2" + resolved "https://registry.yarnpkg.com/@types/micromatch/-/micromatch-4.0.2.tgz#ce29c8b166a73bf980a5727b1e4a4d099965151d" + integrity sha512-oqXqVb0ci19GtH0vOA/U2TmHTcRY9kuZl4mqUxe0QmJAlIW13kzhuK5pi1i9+ngav8FjpSb9FVS/GE00GLX1VA== + dependencies: + "@types/braces" "*" + +"@types/micromatch@latest": version "4.0.1" resolved "https://registry.yarnpkg.com/@types/micromatch/-/micromatch-4.0.1.tgz#9381449dd659fc3823fd2a4190ceacc985083bc7" integrity sha1-k4FEndZZ/Dgj/SpBkM6syYUIO8c= From c6c382bcf5b58cdace1ea1d81b44e83fefdf1da1 Mon Sep 17 00:00:00 2001 From: Arda TANRIKULU Date: Wed, 7 Jul 2021 19:35:03 +0300 Subject: [PATCH 28/66] fix(resolvers-composition): fix ESM support for micromatch import --- packages/resolvers-composition/src/resolvers-composition.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/resolvers-composition/src/resolvers-composition.ts b/packages/resolvers-composition/src/resolvers-composition.ts index a61e42ea26b..ff88bbec07b 100644 --- a/packages/resolvers-composition/src/resolvers-composition.ts +++ b/packages/resolvers-composition/src/resolvers-composition.ts @@ -2,7 +2,7 @@ import { chainFunctions } from './chain-functions'; import _ from 'lodash'; import { GraphQLFieldResolver, GraphQLScalarTypeConfig } from 'graphql'; import { asArray } from '@graphql-tools/utils'; -import { matcher } from 'micromatch'; +import micromatch from 'micromatch'; export type ResolversComposition< Resolver extends GraphQLFieldResolver = GraphQLFieldResolver @@ -35,7 +35,7 @@ function resolveRelevantMappings = Record< } const [typeNameOrGlob, fieldNameOrGlob] = path.split('.'); - const isTypeMatch = matcher(typeNameOrGlob); + const isTypeMatch = micromatch.matcher(typeNameOrGlob); let fixedFieldGlob = fieldNameOrGlob; // convert single value OR `{singleField}` to `singleField` as matching will fail otherwise @@ -44,7 +44,7 @@ function resolveRelevantMappings = Record< } fixedFieldGlob = fixedFieldGlob.replace(', ', ',').trim(); - const isFieldMatch = matcher(fixedFieldGlob); + const isFieldMatch = micromatch.matcher(fixedFieldGlob); const mappings: string[] = []; for (const typeName in resolvers) { From af9a78deb33a728cd2d398b79f991954eca958e0 Mon Sep 17 00:00:00 2001 From: Arda TANRIKULU Date: Wed, 7 Jul 2021 21:18:55 +0300 Subject: [PATCH 29/66] handle glob in loaders and return Source[] instead of Source (#3157) * Handle glob in loaders and return Source[] instead of Source * Fix TS * include rawSDL in Source of plucked files (#3161) Co-authored-by: Laurin Quast --- .changeset/blue-ducks-stare.md | 20 ++ .changeset/khaki-balloons-check.md | 5 + packages/load/package.json | 6 +- packages/load/src/load-typedefs.ts | 19 +- .../load/src/load-typedefs/collect-sources.ts | 280 +----------------- packages/load/src/load-typedefs/load-file.ts | 4 +- packages/load/src/load-typedefs/parse.ts | 8 +- packages/load/src/utils/pointers.ts | 10 +- .../documents/documents-from-glob.spec.ts | 4 +- packages/loaders/apollo-engine/src/index.ts | 16 +- packages/loaders/code-file/src/index.ts | 112 ++++--- .../tests/load-from-code-file.spec.ts | 73 +++-- .../tests/schema-from-export.spec.ts | 25 +- .../tests/test-files/multiple-from-file.ts | 25 ++ packages/loaders/git/package.json | 1 + packages/loaders/git/src/index.ts | 85 +++--- .../tests/__snapshots__/loader.spec.ts.snap | 8 + packages/loaders/git/tests/loader.spec.ts | 10 +- packages/loaders/github/src/index.ts | 22 +- .../github/tests/schema-from-github.spec.ts | 6 +- packages/loaders/graphql-file/src/index.ts | 70 +++-- .../loaders/graphql-file/tests/loader.spec.ts | 9 +- packages/loaders/json-file/src/index.ts | 25 +- .../loaders/json-file/tests/loader.spec.ts | 8 +- packages/loaders/module/src/index.ts | 17 +- packages/loaders/module/tests/loader.spec.ts | 10 +- packages/loaders/url/package.json | 5 +- packages/loaders/url/src/index.ts | 27 +- packages/loaders/url/tests/url-loader.spec.ts | 26 +- packages/utils/src/loaders.ts | 40 +-- yarn.lock | 14 +- 31 files changed, 414 insertions(+), 576 deletions(-) create mode 100644 .changeset/blue-ducks-stare.md create mode 100644 .changeset/khaki-balloons-check.md create mode 100644 packages/loaders/code-file/tests/test-files/multiple-from-file.ts diff --git a/.changeset/blue-ducks-stare.md b/.changeset/blue-ducks-stare.md new file mode 100644 index 00000000000..376bf91ace4 --- /dev/null +++ b/.changeset/blue-ducks-stare.md @@ -0,0 +1,20 @@ +--- +'@graphql-tools/load': major +'@graphql-tools/apollo-engine-loader': major +'@graphql-tools/code-file-loader': major +'@graphql-tools/git-loader': major +'@graphql-tools/github-loader': major +'@graphql-tools/graphql-file-loader': major +'@graphql-tools/json-file-loader': major +'@graphql-tools/module-loader': major +'@graphql-tools/url-loader': major +'@graphql-tools/utils': major +--- + +BREAKING CHANGE + +- Now each loader handles glob patterns internally and returns an array of `Source` object instead of single `Source` + +- GraphQL Tag Pluck now respects code locations and returns graphql-js `Source` objects for each found code block + +- Thanks to the one above, `CodeFileLoader` now returns different `Source` objects for each found SDL code block. diff --git a/.changeset/khaki-balloons-check.md b/.changeset/khaki-balloons-check.md new file mode 100644 index 00000000000..94f22de2def --- /dev/null +++ b/.changeset/khaki-balloons-check.md @@ -0,0 +1,5 @@ +--- +'@graphql-tools/code-file-loader': minor +--- + +include rawSDL in Source of plucked files diff --git a/packages/load/package.json b/packages/load/package.json index 65438569349..86c747f81dd 100644 --- a/packages/load/package.json +++ b/packages/load/package.json @@ -30,8 +30,6 @@ "graphql": "^14.0.0 || ^15.0.0" }, "devDependencies": { - "@types/is-glob": "4.0.2", - "@types/valid-url": "1.0.3", "graphql-tag": "2.12.5", "graphql-type-json": "0.3.2" }, @@ -39,10 +37,8 @@ "@graphql-tools/utils": "^7.5.0", "@graphql-tools/merge": "^6.2.12", "import-from": "4.0.0", - "is-glob": "4.0.1", "p-limit": "3.1.0", - "tslib": "~2.3.0", - "valid-url": "1.0.9" + "tslib": "~2.3.0" }, "publishConfig": { "access": "public", diff --git a/packages/load/src/load-typedefs.ts b/packages/load/src/load-typedefs.ts index defb838b0af..2defd60cd59 100644 --- a/packages/load/src/load-typedefs.ts +++ b/packages/load/src/load-typedefs.ts @@ -1,4 +1,4 @@ -import { Source, SingleFileOptions, Loader, compareStrings } from '@graphql-tools/utils'; +import { Source, BaseLoaderOptions, Loader, compareStrings, asArray } from '@graphql-tools/utils'; import { normalizePointers } from './utils/pointers'; import { applyDefaultOptions } from './load-typedefs/options'; import { collectSources, collectSourcesSync } from './load-typedefs/collect-sources'; @@ -7,12 +7,11 @@ import { useLimit } from './utils/helpers'; const CONCURRENCY_LIMIT = 100; -export type LoadTypedefsOptions = SingleFileOptions & +export type LoadTypedefsOptions = BaseLoaderOptions & ExtraConfig & { cache?: { [key: string]: Source }; loaders: Loader[]; filterKinds?: string[]; - ignore?: string | string[]; sort?: boolean; }; @@ -29,8 +28,10 @@ export async function loadTypedefs>( pointerOrPointers: UnnormalizedTypeDefPointer | UnnormalizedTypeDefPointer[], options: LoadTypedefsOptions> ): Promise { - const pointerOptionMap = normalizePointers(pointerOrPointers); - const globOptions: any = {}; + const { ignore, pointerOptionMap } = normalizePointers(pointerOrPointers); + + options.ignore = asArray(options.ignore || []); + options.ignore.push(...ignore); applyDefaultOptions(options); @@ -50,7 +51,6 @@ export async function loadTypedefs>( parseSource({ partialSource, options, - globOptions, pointerOptionMap, addValidSource(source) { validSources.push(source); @@ -74,8 +74,10 @@ export function loadTypedefsSync>( pointerOrPointers: UnnormalizedTypeDefPointer | UnnormalizedTypeDefPointer[], options: LoadTypedefsOptions> ): Source[] { - const pointerOptionMap = normalizePointers(pointerOrPointers); - const globOptions: any = {}; + const { ignore, pointerOptionMap } = normalizePointers(pointerOrPointers); + + options.ignore = asArray(options.ignore || []); + options.ignore.push(...ignore); applyDefaultOptions(options); @@ -90,7 +92,6 @@ export function loadTypedefsSync>( parseSource({ partialSource, options, - globOptions, pointerOptionMap, addValidSource(source) { validSources.push(source); diff --git a/packages/load/src/load-typedefs/collect-sources.ts b/packages/load/src/load-typedefs/collect-sources.ts index 1bdd8e02d6e..1a330a4319d 100644 --- a/packages/load/src/load-typedefs/collect-sources.ts +++ b/packages/load/src/load-typedefs/collect-sources.ts @@ -1,15 +1,5 @@ -import { - Source, - isDocumentString, - parseGraphQLSDL, - asArray, - getDocumentNodeFromSchema, - Loader, - ResolverGlobs, - isSome, -} from '@graphql-tools/utils'; +import { Source, isDocumentString, parseGraphQLSDL, getDocumentNodeFromSchema } from '@graphql-tools/utils'; import { isSchema, Kind } from 'graphql'; -import isGlob from 'is-glob'; import { LoadTypedefsOptions } from '../load-typedefs'; import { loadFile, loadFileSync } from './load-file'; import { stringToHash, useStack, StackNext, StackFn } from '../utils/helpers'; @@ -17,7 +7,6 @@ import { useCustomLoader, useCustomLoaderSync } from '../utils/custom-loader'; import { useQueue, useSyncQueue } from '../utils/queue'; type AddSource = (data: { pointer: string; source: Source; noCache?: boolean }) => void; -type AddGlob = (data: { pointer: string; pointerOptions: any }) => void; type AddToQueue = (fn: () => Promise | T) => void; const CONCURRENCY_LIMIT = 50; @@ -32,16 +21,12 @@ export async function collectSources({ options: LoadTypedefsOptions>; }): Promise { const sources: Source[] = []; - const globs: string[] = []; - const globOptions: any = {}; const queue = useQueue({ concurrency: CONCURRENCY_LIMIT }); - const { addSource, addGlob, collect } = createHelpers({ + const { addSource, collect } = createHelpers({ sources, - globs, options, - globOptions, - stack: [collectDocumentString, collectGlob, collectCustomLoader, collectFallback], + stack: [collectDocumentString, collectCustomLoader, collectFallback], }); for (const pointer in pointerOptionMap) { @@ -53,21 +38,6 @@ export async function collectSources({ pointerOptionMap, options, addSource, - addGlob, - queue: queue.add as AddToQueue, - }); - } - - if (globs.length) { - // TODO: use the queue? - const paths = await collectPathsFromGlobs(globs, options); - - collectSourcesFromGlobals({ - filepaths: paths, - options, - globOptions, - pointerOptionMap, - addSource, queue: queue.add as AddToQueue, }); } @@ -87,16 +57,12 @@ export function collectSourcesSync({ options: LoadTypedefsOptions>; }): Source[] { const sources: Source[] = []; - const globs: string[] = []; - const globOptions: any = {}; const queue = useSyncQueue(); - const { addSource, addGlob, collect } = createHelpers({ + const { addSource, collect } = createHelpers({ sources, - globs, options, - globOptions, - stack: [collectDocumentString, collectGlob, collectCustomLoaderSync, collectFallbackSync], + stack: [collectDocumentString, collectCustomLoaderSync, collectFallbackSync], }); for (const pointer in pointerOptionMap) { @@ -108,20 +74,6 @@ export function collectSourcesSync({ pointerOptionMap, options, addSource, - addGlob, - queue: queue.add, - }); - } - - if (globs.length) { - const paths = collectPathsFromGlobsSync(globs, options); - - collectSourcesFromGlobalsSync({ - filepaths: paths, - options, - globOptions, - pointerOptionMap, - addSource, queue: queue.add, }); } @@ -133,15 +85,11 @@ export function collectSourcesSync({ function createHelpers({ sources, - globs, options, - globOptions, stack, }: { sources: Source[]; - globs: string[]; options: LoadTypedefsOptions>; - globOptions: any; stack: StackFn>[]; }) { const addSource: AddSource = ({ @@ -162,209 +110,18 @@ function createHelpers({ const collect = useStack(...stack); - const addGlob: AddGlob = ({ pointerOptions, pointer }) => { - globs.push(pointer); - Object.assign(globOptions, pointerOptions); - }; - return { addSource, collect, - addGlob, }; } -async function addGlobsToLoaders({ - options, - loadersForGlobs, - globs, - type, -}: { - options: LoadTypedefsOptions; - loadersForGlobs: Map; - globs: string[]; - type: 'globs' | 'ignores'; -}) { - for (const glob of globs) { - let loader; - for await (const candidateLoader of options.loaders) { - if (candidateLoader.resolveGlobs && (await candidateLoader.canLoad(glob, options))) { - loader = candidateLoader; - break; - } - } - if (!loader) { - throw new Error(`unable to find loader for glob "${glob}"`); - } - let resolverGlobs = loadersForGlobs.get(loader); - if (!isSome(resolverGlobs)) { - resolverGlobs = { globs: [], ignores: [] }; - loadersForGlobs.set(loader, resolverGlobs); - } - resolverGlobs[type].push(glob); - } -} - -function addGlobsToLoadersSync({ - options, - loadersForGlobs, - globs, - type, -}: { - options: LoadTypedefsOptions; - loadersForGlobs: Map; - globs: string[]; - type: 'globs' | 'ignores'; -}) { - for (const glob of globs) { - let loader; - for (const candidateLoader of options.loaders) { - if ( - isSome(candidateLoader.resolveGlobsSync) && - isSome(candidateLoader.canLoadSync) && - candidateLoader.canLoadSync(glob, options) - ) { - loader = candidateLoader; - break; - } - } - if (!loader) { - throw new Error(`unable to find loader for glob "${glob}"`); - } - let resolverGlobs = loadersForGlobs.get(loader); - if (!isSome(resolverGlobs)) { - resolverGlobs = { globs: [], ignores: [] }; - loadersForGlobs.set(loader, resolverGlobs); - } - resolverGlobs[type].push(glob); - } -} - -async function collectPathsFromGlobs(globs: string[], options: LoadTypedefsOptions): Promise { - const paths: string[] = []; - - const loadersForGlobs: Map = new Map(); - - await addGlobsToLoaders({ options, loadersForGlobs, globs, type: 'globs' }); - await addGlobsToLoaders({ - options, - loadersForGlobs, - globs: isSome(options.ignore) ? asArray(options.ignore) : [], - type: 'ignores', - }); - - for await (const [loader, globsAndIgnores] of loadersForGlobs.entries()) { - if (isSome(loader.resolveGlobs)) { - const resolvedPaths = await loader.resolveGlobs(globsAndIgnores, options); - if (resolvedPaths) { - paths.push(...resolvedPaths); - } - } - } - - return paths; -} - -function collectPathsFromGlobsSync(globs: string[], options: LoadTypedefsOptions): string[] { - const paths: string[] = []; - - const loadersForGlobs: Map = new Map(); - - addGlobsToLoadersSync({ options, loadersForGlobs, globs, type: 'globs' }); - addGlobsToLoadersSync({ - options, - loadersForGlobs, - globs: isSome(options.ignore) ? asArray(options.ignore) : [], - type: 'ignores', - }); - - for (const [loader, globsAndIgnores] of loadersForGlobs.entries()) { - if (isSome(loader.resolveGlobsSync)) { - const resolvedPaths = loader.resolveGlobsSync(globsAndIgnores, options); - if (resolvedPaths) { - paths.push(...resolvedPaths); - } - } - } - - return paths; -} - -function collectSourcesFromGlobals({ - filepaths, - options, - globOptions, - pointerOptionMap, - addSource, - queue, -}: { - filepaths: string[]; - options: LoadTypedefsOptions>; - globOptions: any; - pointerOptionMap: P; - addSource: AddSource; - queue: AddToQueue; -}) { - const collectFromGlobs = useStack(collectCustomLoader, collectFallback); - - for (let i = 0; i < filepaths.length; i++) { - const pointer = filepaths[i]; - - collectFromGlobs({ - pointer, - pointerOptions: globOptions, - pointerOptionMap, - options, - addSource, - addGlob: () => { - throw new Error(`I don't accept any new globs!`); - }, - queue, - }); - } -} - -function collectSourcesFromGlobalsSync({ - filepaths, - options, - globOptions, - pointerOptionMap, - addSource, - queue, -}: { - filepaths: string[]; - options: LoadTypedefsOptions>; - globOptions: any; - pointerOptionMap: P; - addSource: AddSource; - queue: AddToQueue; -}) { - const collectFromGlobs = useStack(collectCustomLoaderSync, collectFallbackSync); - - for (let i = 0; i < filepaths.length; i++) { - const pointer = filepaths[i]; - - collectFromGlobs({ - pointer, - pointerOptions: globOptions, - pointerOptionMap, - options, - addSource, - addGlob: () => { - throw new Error(`I don't accept any new globs!`); - }, - queue, - }); - } -} - type CollectOptions = { pointer: string; pointerOptions: any; options: LoadTypedefsOptions>; pointerOptionMap: Record; addSource: AddSource; - addGlob: AddGlob; queue: AddToQueue; }; @@ -427,17 +184,6 @@ function collectDocumentString( next(); } -function collectGlob({ pointer, pointerOptions, addGlob }: CollectOptions, next: StackNext) { - if (isGlob(pointer)) { - return addGlob({ - pointer, - pointerOptions, - }); - } - - next(); -} - function collectCustomLoader( { pointer, pointerOptions, queue, addSource, options, pointerOptionMap }: CollectOptions, next: StackNext @@ -482,26 +228,30 @@ function collectCustomLoaderSync( function collectFallback({ queue, pointer, options, pointerOptions, addSource }: CollectOptions) { return queue(async () => { - const source = await loadFile(pointer, { + const sources = await loadFile(pointer, { ...options, ...pointerOptions, }); - if (source) { - addSource({ source, pointer }); + if (sources) { + for (const source of sources) { + addSource({ source, pointer }); + } } }); } function collectFallbackSync({ queue, pointer, options, pointerOptions, addSource }: CollectOptions) { return queue(() => { - const source = loadFileSync(pointer, { + const sources = loadFileSync(pointer, { ...options, ...pointerOptions, }); - if (source) { - addSource({ source, pointer }); + if (sources) { + for (const source of sources) { + addSource({ source, pointer }); + } } }); } diff --git a/packages/load/src/load-typedefs/load-file.ts b/packages/load/src/load-typedefs/load-file.ts index 7f6acf067e8..ee7944a7426 100644 --- a/packages/load/src/load-typedefs/load-file.ts +++ b/packages/load/src/load-typedefs/load-file.ts @@ -2,7 +2,7 @@ import { Source, Maybe } from '@graphql-tools/utils'; import { env } from 'process'; import { LoadTypedefsOptions } from '../load-typedefs'; -export async function loadFile(pointer: string, options: LoadTypedefsOptions): Promise> { +export async function loadFile(pointer: string, options: LoadTypedefsOptions): Promise> { const cached = useCache({ pointer, options }); if (cached) { @@ -28,7 +28,7 @@ export async function loadFile(pointer: string, options: LoadTypedefsOptions): P return undefined; } -export function loadFileSync(pointer: string, options: LoadTypedefsOptions): Maybe { +export function loadFileSync(pointer: string, options: LoadTypedefsOptions): Maybe { const cached = useCache({ pointer, options }); if (cached) { diff --git a/packages/load/src/load-typedefs/parse.ts b/packages/load/src/load-typedefs/parse.ts index 87ae377be06..ca85e03d9c3 100644 --- a/packages/load/src/load-typedefs/parse.ts +++ b/packages/load/src/load-typedefs/parse.ts @@ -11,17 +11,15 @@ type AddValidSource = (source: Source) => void; type ParseOptions = { partialSource: Source; options: any; - globOptions: any; pointerOptionMap: any; addValidSource: AddValidSource; }; -export function parseSource({ partialSource, options, globOptions, pointerOptionMap, addValidSource }: ParseOptions) { +export function parseSource({ partialSource, options, pointerOptionMap, addValidSource }: ParseOptions) { if (partialSource) { const input = prepareInput({ source: partialSource, options, - globOptions, pointerOptionMap, }); @@ -41,12 +39,10 @@ export function parseSource({ partialSource, options, globOptions, pointerOption function prepareInput({ source, options, - globOptions, pointerOptionMap, }: { source: Source; options: any; - globOptions: any; pointerOptionMap: any; }): Input { let specificOptions = { @@ -56,7 +52,7 @@ function prepareInput({ if (source.location) { specificOptions = { ...specificOptions, - ...(source.location in pointerOptionMap ? globOptions : pointerOptionMap[source.location]), + ...pointerOptionMap[source.location], }; } diff --git a/packages/load/src/utils/pointers.ts b/packages/load/src/utils/pointers.ts index 87534c20b33..1261576e905 100644 --- a/packages/load/src/utils/pointers.ts +++ b/packages/load/src/utils/pointers.ts @@ -4,10 +4,15 @@ import { UnnormalizedTypeDefPointer } from './../load-typedefs'; export function normalizePointers( unnormalizedPointerOrPointers: UnnormalizedTypeDefPointer | UnnormalizedTypeDefPointer[] ) { - return asArray(unnormalizedPointerOrPointers).reduce<{ [key: string]: any }>( + const ignore: string[] = []; + const pointerOptionMap = asArray(unnormalizedPointerOrPointers).reduce<{ [key: string]: any }>( (normalizedPointers, unnormalizedPointer) => { if (typeof unnormalizedPointer === 'string') { - normalizedPointers[unnormalizedPointer] = {}; + if (unnormalizedPointer.startsWith('!')) { + ignore.push(unnormalizedPointer.replace('!', '')); + } else { + normalizedPointers[unnormalizedPointer] = {}; + } } else if (typeof unnormalizedPointer === 'object') { Object.assign(normalizedPointers, unnormalizedPointer); } else { @@ -18,4 +23,5 @@ export function normalizePointers( }, {} ); + return { ignore, pointerOptionMap }; } diff --git a/packages/load/tests/loaders/documents/documents-from-glob.spec.ts b/packages/load/tests/loaders/documents/documents-from-glob.spec.ts index f7fe2ce3532..d8ebedf3283 100644 --- a/packages/load/tests/loaders/documents/documents-from-glob.spec.ts +++ b/packages/load/tests/loaders/documents/documents-from-glob.spec.ts @@ -34,10 +34,8 @@ describe('documentsFromGlob', () => { const result = await load(glob, { loaders: [new CodeFileLoader()] }); - const { document } = result[0]; - const operations = document && separateOperations(document); - expect(operations && Object.keys(operations)).toHaveLength(2); + expect(result).toHaveLength(2); }); test(`Should load GraphQL documents that match custom settings`, async () => { diff --git a/packages/loaders/apollo-engine/src/index.ts b/packages/loaders/apollo-engine/src/index.ts index 2c1c4b47ba5..854eb7a06d7 100644 --- a/packages/loaders/apollo-engine/src/index.ts +++ b/packages/loaders/apollo-engine/src/index.ts @@ -1,11 +1,11 @@ -import { SchemaLoader, Source, SingleFileOptions, parseGraphQLSDL, AggregateError } from '@graphql-tools/utils'; +import { Source, parseGraphQLSDL, AggregateError, BaseLoaderOptions, Loader } from '@graphql-tools/utils'; import { fetch } from 'cross-fetch'; import syncFetch from 'sync-fetch'; /** * Additional options for loading from Apollo Engine */ -export interface ApolloEngineOptions extends SingleFileOptions { +export interface ApolloEngineOptions extends BaseLoaderOptions { engine: { endpoint?: string; apiKey: string; @@ -20,7 +20,7 @@ const DEFAULT_APOLLO_ENDPOINT = 'https://engine-graphql.apollographql.com/api/gr /** * This loader loads a schema from Apollo Engine */ -export class ApolloEngineLoader implements SchemaLoader { +export class ApolloEngineLoader implements Loader { loaderId() { return 'apollo-engine'; } @@ -58,7 +58,7 @@ export class ApolloEngineLoader implements SchemaLoader { return typeof ptr === 'string' && ptr === 'apollo-engine'; } - async load(pointer: 'apollo-engine', options: ApolloEngineOptions): Promise { + async load(pointer: 'apollo-engine', options: ApolloEngineOptions): Promise { const fetchArgs = this.getFetchArgs(options); const response = await fetch(...fetchArgs); @@ -68,10 +68,11 @@ export class ApolloEngineLoader implements SchemaLoader { throw new AggregateError(errors, 'Introspection from Apollo Engine failed'); } - return parseGraphQLSDL(pointer, data.service.schema.document, options); + const source = parseGraphQLSDL(pointer, data.service.schema.document, options); + return [source]; } - loadSync(pointer: 'apollo-engine', options: ApolloEngineOptions): Source { + loadSync(pointer: 'apollo-engine', options: ApolloEngineOptions): Source[] { const fetchArgs = this.getFetchArgs(options); const response = syncFetch(...fetchArgs); @@ -81,7 +82,8 @@ export class ApolloEngineLoader implements SchemaLoader { throw new AggregateError(errors, 'Introspection from Apollo Engine failed'); } - return parseGraphQLSDL(pointer, data.service.schema.document, options); + const source = parseGraphQLSDL(pointer, data.service.schema.document, options); + return [source]; } } diff --git a/packages/loaders/code-file/src/index.ts b/packages/loaders/code-file/src/index.ts index 1299c2c61f7..68274a89587 100644 --- a/packages/loaders/code-file/src/index.ts +++ b/packages/loaders/code-file/src/index.ts @@ -1,17 +1,14 @@ import type { GlobbyOptions } from 'globby'; -import { isSchema, GraphQLSchema, DocumentNode, concatAST, parse } from 'graphql'; +import { isSchema, GraphQLSchema, DocumentNode, parse } from 'graphql'; import { - SchemaPointerSingle, - DocumentPointerSingle, - SingleFileOptions, Source, - UniversalLoader, asArray, isValidPath, parseGraphQLSDL, isDocumentNode, - ResolverGlobs, + BaseLoaderOptions, + Loader, } from '@graphql-tools/utils'; import { GraphQLTagPluckOptions, @@ -37,7 +34,7 @@ export type CodeFileLoaderOptions = { pluckConfig?: GraphQLTagPluckOptions; noPluck?: boolean; noRequire?: boolean; -} & SingleFileOptions; +} & BaseLoaderOptions; const FILE_EXTENSIONS = ['.ts', '.tsx', '.js', '.jsx', '.vue']; @@ -59,15 +56,12 @@ function createGlobbyOptions(options: CodeFileLoaderOptions): GlobbyOptions { * * Supported extensions include: `.ts`, `.tsx`, `.js`, `.jsx`, `.vue` */ -export class CodeFileLoader implements UniversalLoader { +export class CodeFileLoader implements Loader { loaderId(): string { return 'code-file'; } - async canLoad( - pointer: SchemaPointerSingle | DocumentPointerSingle, - options: CodeFileLoaderOptions - ): Promise { + async canLoad(pointer: string, options: CodeFileLoaderOptions): Promise { if (isGlob(pointer)) { // FIXME: parse to find and check the file extensions? return true; @@ -88,7 +82,7 @@ export class CodeFileLoader implements UniversalLoader { return false; } - canLoadSync(pointer: SchemaPointerSingle | DocumentPointerSingle, options: CodeFileLoaderOptions): boolean { + canLoadSync(pointer: string, options: CodeFileLoaderOptions): boolean { if (isGlob(pointer)) { // FIXME: parse to find and check the file extensions? return true; @@ -104,25 +98,52 @@ export class CodeFileLoader implements UniversalLoader { return false; } - async resolveGlobs({ globs, ignores }: ResolverGlobs, options: CodeFileLoaderOptions) { - return globby( - globs.concat(ignores.map(v => `!(${v})`)).map(v => unixify(v)), - createGlobbyOptions(options) - ); + async resolveGlobs(glob: string, options: CodeFileLoaderOptions) { + const ignores = asArray(options.ignore || []); + return globby([glob, ...ignores.map(v => `!(${v})`).map(v => unixify(v))], createGlobbyOptions(options)); } - resolveGlobsSync({ globs, ignores }: ResolverGlobs, options: CodeFileLoaderOptions) { - return globby.sync( - globs.concat(ignores.map(v => `!(${v})`)).map(v => unixify(v)), - createGlobbyOptions(options) - ); + resolveGlobsSync(glob: string, options: CodeFileLoaderOptions) { + const ignores = asArray(options.ignore || []); + return globby.sync([glob, ...ignores.map(v => `!(${v})`).map(v => unixify(v))], createGlobbyOptions(options)); } - async load( - pointer: SchemaPointerSingle | DocumentPointerSingle, - options: CodeFileLoaderOptions - ): Promise { - const normalizedFilePath = ensureAbsolutePath(pointer, options); + async load(pointer: string, options: CodeFileLoaderOptions): Promise { + if (isGlob(pointer)) { + const resolvedPaths = await this.resolveGlobs(pointer, options); + const finalResult: Source[] = []; + await Promise.all( + resolvedPaths.map(async path => { + if (await this.canLoad(path, options)) { + const result = await this.handleSinglePath(path, options); + result?.forEach(result => finalResult.push(result)); + } + }) + ); + return finalResult; + } + + return this.handleSinglePath(pointer, options); + } + + loadSync(pointer: string, options: CodeFileLoaderOptions): Source[] | null { + if (isGlob(pointer)) { + const resolvedPaths = this.resolveGlobsSync(pointer, options); + const finalResult: Source[] = []; + for (const path of resolvedPaths) { + if (this.canLoadSync(path, options)) { + const result = this.handleSinglePathSync(path, options); + result?.forEach(result => finalResult.push(result)); + } + } + return finalResult; + } + + return this.handleSinglePathSync(pointer, options); + } + + async handleSinglePath(location: string, options: CodeFileLoaderOptions): Promise { + const normalizedFilePath = ensureAbsolutePath(location, options); const errors: Error[] = []; @@ -132,10 +153,11 @@ export class CodeFileLoader implements UniversalLoader { const sources = await gqlPluckFromCodeString(normalizedFilePath, content, options.pluckConfig); if (sources.length) { - return { - document: concatAST(sources.map(source => parse(source, options))), - location: pointer, - }; + return sources.map(source => ({ + document: parse(source, options), + location, + rawSDL: source.body, + })); } } catch (e) { if (env['DEBUG']) { @@ -152,10 +174,10 @@ export class CodeFileLoader implements UniversalLoader { } const loaded = await tryToLoadFromExport(normalizedFilePath); - const source = resolveSource(pointer, loaded, options); + const source = resolveSource(location, loaded, options); if (source) { - return source; + return [source]; } } catch (e) { errors.push(e); @@ -169,8 +191,8 @@ export class CodeFileLoader implements UniversalLoader { return null; } - loadSync(pointer: SchemaPointerSingle | DocumentPointerSingle, options: CodeFileLoaderOptions): Source | null { - const normalizedFilePath = ensureAbsolutePath(pointer, options); + handleSinglePathSync(location: string, options: CodeFileLoaderOptions): Source[] | null { + const normalizedFilePath = ensureAbsolutePath(location, options); const errors: Error[] = []; @@ -180,10 +202,11 @@ export class CodeFileLoader implements UniversalLoader { const sources = gqlPluckFromCodeStringSync(normalizedFilePath, content, options.pluckConfig); if (sources.length) { - return { - document: concatAST(sources.map(source => parse(source, options))), - location: pointer, - }; + return sources.map(source => ({ + document: parse(source, options), + location, + rawSDL: source.body, + })); } } catch (e) { if (env['DEBUG']) { @@ -203,10 +226,10 @@ export class CodeFileLoader implements UniversalLoader { } const loaded = tryToLoadFromExportSync(normalizedFilePath); - const source = resolveSource(pointer, loaded, options); + const source = resolveSource(location, loaded, options); if (source) { - return source; + return [source]; } } catch (e) { errors.push(e); @@ -243,9 +266,6 @@ function resolveSource( return null; } -function ensureAbsolutePath( - pointer: SchemaPointerSingle | DocumentPointerSingle, - options: CodeFileLoaderOptions -): string { +function ensureAbsolutePath(pointer: string, options: CodeFileLoaderOptions): string { return isAbsolute(pointer) ? pointer : resolve(options.cwd || cwd(), pointer); } diff --git a/packages/loaders/code-file/tests/load-from-code-file.spec.ts b/packages/loaders/code-file/tests/load-from-code-file.spec.ts index 06e273905a3..88e36b88ea0 100644 --- a/packages/loaders/code-file/tests/load-from-code-file.spec.ts +++ b/packages/loaders/code-file/tests/load-from-code-file.spec.ts @@ -8,10 +8,11 @@ describe('loadFromCodeFile', () => { it('Should throw an error when a document is loaded using AST and the document is not valid', async () => { try { - const loaded = await loader.load('./test-files/invalid-anon-doc.js', { + const result = await loader.load('./test-files/invalid-anon-doc.js', { noRequire: true, - cwd: __dirname + cwd: __dirname, }); + const loaded = result?.[0]; const doc = loaded?.document ? loaded?.document : parse(loaded?.rawSDL!); expect(doc).toBeFalsy(); @@ -21,39 +22,43 @@ describe('loadFromCodeFile', () => { }); it('should load a valid file', async () => { - const loaded = await loader.load('./test-files/valid-doc.js', { + const result = await loader.load('./test-files/valid-doc.js', { noRequire: true, - cwd: __dirname + cwd: __dirname, }); + const loaded = result?.[0]; const doc = loaded?.document ? loaded?.document : parse(loaded?.rawSDL!); expect(doc?.kind).toEqual('Document'); }); it('should consider options.cwd', async () => { - const loaded = await loader.load('valid-doc.js', { + const result = await loader.load('valid-doc.js', { cwd: path.resolve(__dirname, 'test-files'), noRequire: true, }); + const loaded = result?.[0]; const doc = loaded?.document ? loaded?.document : parse(loaded?.rawSDL!); expect(doc?.kind).toEqual('Document'); }); it('should load a TypeScript file using decorator', async () => { - const loaded = await loader.load('./test-files/with-decorator-doc.ts', { + const result = await loader.load('./test-files/with-decorator-doc.ts', { noRequire: true, - cwd: __dirname + cwd: __dirname, }); + const loaded = result?.[0]; const doc = loaded?.document ? loaded?.document : parse(loaded?.rawSDL!); expect(doc?.kind).toEqual('Document'); }); it('should support string interpolation', async () => { - const loaded = await loader.load('./test-files/string-interpolation.js', { - cwd: __dirname + const result = await loader.load('./test-files/string-interpolation.js', { + cwd: __dirname, }); + const loaded = result?.[0]; const doc = loaded?.document ? loaded?.document : parse(loaded?.rawSDL!); expect(doc?.kind).toEqual('Document'); @@ -65,43 +70,77 @@ describe('loadFromCodeFileSync', () => { it('Should throw an error when a document is loaded using AST and the document is not valid', () => { expect(() => { - const loaded = loader.loadSync('./test-files/invalid-anon-doc.js', { + const result = loader.loadSync('./test-files/invalid-anon-doc.js', { noRequire: true, - cwd: __dirname + cwd: __dirname, }); + const loaded = result?.[0]; const doc = loaded?.document ? loaded?.document : parse(loaded?.rawSDL!); expect(doc?.kind).toEqual('Document'); - }).toThrowError('Syntax Error: Unexpected Name "InvalidGetUser"') + }).toThrowError('Syntax Error: Unexpected Name "InvalidGetUser"'); }); it('should load a valid file', () => { - const loaded = loader.loadSync('./test-files/valid-doc.js', { + const result = loader.loadSync('./test-files/valid-doc.js', { noRequire: true, - cwd: __dirname + cwd: __dirname, }); + const loaded = result?.[0]; const doc = loaded?.document; expect(doc?.kind).toEqual('Document'); }); it('should consider options.cwd', () => { - const loaded = loader.loadSync('valid-doc.js', { + const result = loader.loadSync('valid-doc.js', { cwd: path.resolve(__dirname, 'test-files'), noRequire: true, }); + const loaded = result?.[0]; const doc = loaded?.document; expect(doc?.kind).toEqual('Document'); }); it('should support string interpolation', () => { - const loaded = loader.loadSync('./test-files/string-interpolation.js', { - cwd: __dirname + const result = loader.loadSync('./test-files/string-interpolation.js', { + cwd: __dirname, }); + const loaded = result?.[0]; const doc = loaded?.document; expect(doc?.kind).toEqual('Document'); }); + + it('should support loading many in same file', () => { + const loaded = loader.loadSync('./test-files/multiple-from-file.ts', { + cwd: __dirname, + }); + expect(loaded?.length).toEqual(3); + expect(loaded?.[0].rawSDL).toBeDefined(); + expect(loaded?.[0].rawSDL).toMatchInlineSnapshot(` + "query Foo { + Tweets { + id + } + }" + `); + expect(loaded?.[1].rawSDL).toBeDefined(); + expect(loaded?.[1].rawSDL).toMatchInlineSnapshot(` +"fragment Lel on Tweet { + id + body +}" +`); + expect(loaded?.[2].rawSDL).toBeDefined(); + expect(loaded?.[2].rawSDL).toMatchInlineSnapshot(` +"query Bar { + Tweets { + ...Lel + } +}" +`); + }); }); diff --git a/packages/loaders/code-file/tests/schema-from-export.spec.ts b/packages/loaders/code-file/tests/schema-from-export.spec.ts index 6cc205700c7..ceb708b0ac4 100644 --- a/packages/loaders/code-file/tests/schema-from-export.spec.ts +++ b/packages/loaders/code-file/tests/schema-from-export.spec.ts @@ -7,35 +7,35 @@ describe('Schema From Export', () => { const result = await loader.load('./test-files/loaders/module-exports.js', { cwd: __dirname }); - expect(result).toBeDefined(); + expect(result?.[0]).toBeDefined(); }); it('should load the schema (with extend) correctly from module.exports', async () => { const result = await loader.load('./test-files/loaders/with-extend.js', { cwd: __dirname }); - expect(result).toBeDefined(); + expect(result?.[0]).toBeDefined(); }); it('should load the schema correctly from variable export', async () => { const result = await loader.load('./test-files/loaders/schema-export.js', { cwd: __dirname }); - expect(result).toBeDefined(); + expect(result?.[0]).toBeDefined(); }); it('should load the schema correctly from default export', async () => { const result = await loader.load('./test-files/loaders/default-export.js', { cwd: __dirname }); - expect(result).toBeDefined(); + expect(result?.[0]).toBeDefined(); }); it('should load the schema correctly from promise export', async () => { const result = await loader.load('./test-files/loaders/promise-export.js', { cwd: __dirname }); - expect(result).toBeDefined(); + expect(result?.[0]).toBeDefined(); }); }); @@ -46,34 +46,27 @@ describe('Schema From Export (sync)', () => { const result = loader.loadSync('./test-files/loaders/module-exports.js', { cwd: __dirname }); - expect(result).toBeDefined(); + expect(result?.[0]).toBeDefined(); }); it('should load the schema (with extend) correctly from module.exports', () => { const result = loader.loadSync('./test-files/loaders/with-extend.js', { cwd: __dirname }); - expect(result).toBeDefined(); + expect(result?.[0]).toBeDefined(); }); it('should load the schema correctly from variable export', () => { const result = loader.loadSync('./test-files/loaders/schema-export.js', { cwd: __dirname }); - expect(result).toBeDefined(); + expect(result?.[0]).toBeDefined(); }); it('should load the schema correctly from default export', () => { const result = loader.loadSync('./test-files/loaders/default-export.js', { cwd: __dirname }); - expect(result).toBeDefined(); - }); - - it('should load the schema correctly from promise export', () => { - const result = loader.loadSync('./test-files/loaders/promise-export.js', { - cwd: __dirname - }); - expect(result).toBeDefined(); + expect(result?.[0]).toBeDefined(); }); }); diff --git a/packages/loaders/code-file/tests/test-files/multiple-from-file.ts b/packages/loaders/code-file/tests/test-files/multiple-from-file.ts new file mode 100644 index 00000000000..aea200b0ee9 --- /dev/null +++ b/packages/loaders/code-file/tests/test-files/multiple-from-file.ts @@ -0,0 +1,25 @@ +//@ts-ignore +import { gql } from "@app/gql"; + +const FooQuery = gql(/* GraphQL */ ` + query Foo { + Tweets { + id + } + } +`); + +const LelFragment = gql(/* GraphQL */ ` + fragment Lel on Tweet { + id + body + } +`); + +const BarQuery = gql(/* GraphQL */ ` + query Bar { + Tweets { + ...Lel + } + } +`); diff --git a/packages/loaders/git/package.json b/packages/loaders/git/package.json index 146ee3b7402..c6104a55d7e 100644 --- a/packages/loaders/git/package.json +++ b/packages/loaders/git/package.json @@ -32,6 +32,7 @@ "dependencies": { "@graphql-tools/graphql-tag-pluck": "^6.2.6", "@graphql-tools/utils": "^7.0.0", + "is-glob": "4.0.1", "micromatch": "^4.0.4", "tslib": "~2.3.0", "unixify": "^1.0.0" diff --git a/packages/loaders/git/src/index.ts b/packages/loaders/git/src/index.ts index f5b3af9ee35..acc6f9ddba4 100644 --- a/packages/loaders/git/src/index.ts +++ b/packages/loaders/git/src/index.ts @@ -1,4 +1,3 @@ -import { UniversalLoader, SingleFileOptions, ResolverGlobs } from '@graphql-tools/utils'; import { GraphQLTagPluckOptions, gqlPluckFromCodeString, @@ -9,7 +8,9 @@ import unixify from 'unixify'; import { loadFromGit, loadFromGitSync, readTreeAtRef, readTreeAtRefSync } from './load-git'; import { parse as handleStuff } from './parse'; -import { concatAST, parse } from 'graphql'; +import { parse } from 'graphql'; +import { asArray, BaseLoaderOptions, Loader, Source } from '@graphql-tools/utils'; +import isGlob from 'is-glob'; // git:branch:path/to/file function extractData(pointer: string): { @@ -31,7 +32,7 @@ function extractData(pointer: string): { /** * Additional options for loading from git */ -export type GitLoaderOptions = SingleFileOptions & { +export type GitLoaderOptions = BaseLoaderOptions & { /** * Additional options to pass to `graphql-tag-pluck` */ @@ -47,7 +48,7 @@ export type GitLoaderOptions = SingleFileOptions & { * }) * ``` */ -export class GitLoader implements UniversalLoader { +export class GitLoader implements Loader { loaderId() { return 'git-loader'; } @@ -60,16 +61,14 @@ export class GitLoader implements UniversalLoader { return typeof pointer === 'string' && pointer.toLowerCase().startsWith('git:'); } - async resolveGlobs({ globs, ignores }: ResolverGlobs) { + async resolveGlobs(glob: string, ignores: string[]) { const refsForPaths = new Map(); - for (const glob of globs) { - const { ref, path } = extractData(glob); - if (!refsForPaths.has(ref)) { - refsForPaths.set(ref, []); - } - refsForPaths.get(ref).push(unixify(path)); + const { ref, path } = extractData(glob); + if (!refsForPaths.has(ref)) { + refsForPaths.set(ref, []); } + refsForPaths.get(ref).push(unixify(path)); for (const ignore of ignores) { const { ref, path } = extractData(ignore); @@ -80,22 +79,22 @@ export class GitLoader implements UniversalLoader { } const resolved: string[] = []; - for await (const [ref, paths] of refsForPaths.entries()) { - resolved.push(...micromatch(await readTreeAtRef(ref), paths).map(filePath => `git:${ref}:${filePath}`)); - } + await Promise.all( + [...refsForPaths.entries()].map(async ([ref, paths]) => { + resolved.push(...micromatch(await readTreeAtRef(ref), paths).map(filePath => `git:${ref}:${filePath}`)); + }) + ); return resolved; } - resolveGlobsSync({ globs, ignores }: ResolverGlobs) { + resolveGlobsSync(glob: string, ignores: string[]) { const refsForPaths = new Map(); - for (const glob of globs) { - const { ref, path } = extractData(glob); - if (!refsForPaths.has(ref)) { - refsForPaths.set(ref, []); - } - refsForPaths.get(ref).push(unixify(path)); + const { ref, path } = extractData(glob); + if (!refsForPaths.has(ref)) { + refsForPaths.set(ref, []); } + refsForPaths.get(ref).push(unixify(path)); for (const ignore of ignores) { const { ref, path } = extractData(ignore); @@ -112,41 +111,57 @@ export class GitLoader implements UniversalLoader { return resolved; } - async load(pointer: string, options: GitLoaderOptions) { + async load(pointer: string, options: GitLoaderOptions): Promise { const { ref, path } = extractData(pointer); + if (isGlob(path)) { + const resolvedPaths = await this.resolveGlobs(pointer, asArray(options.ignore || [])); + const finalResult: Source[] = []; + + await Promise.all( + resolvedPaths.map(async path => { + const results = await this.load(path, options); + results?.forEach(result => finalResult.push(result)); + }) + ); + } const content = await loadFromGit({ ref, path }); const parsed = handleStuff({ path, options, pointer, content }); if (parsed) { - return parsed; + return [parsed]; } const sources = await gqlPluckFromCodeString(pointer, content, options.pluckConfig); - const documents = sources.map(source => parse(source, options)); - - return { + return sources.map(source => ({ location: pointer, - document: concatAST(documents), - }; + document: parse(source, options), + })); } - loadSync(pointer: string, options: GitLoaderOptions) { + loadSync(pointer: string, options: GitLoaderOptions): Source[] { const { ref, path } = extractData(pointer); + if (isGlob(path)) { + const resolvedPaths = this.resolveGlobsSync(pointer, asArray(options.ignore || [])); + const finalResult: Source[] = []; + + resolvedPaths.forEach(path => { + const results = this.loadSync(path, options); + results?.forEach(result => finalResult.push(result)); + }); + } const content = loadFromGitSync({ ref, path }); const parsed = handleStuff({ path, options, pointer, content }); if (parsed) { - return parsed; + return [parsed]; } const sources = gqlPluckFromCodeStringSync(pointer, content, options.pluckConfig); - const documents = sources.map(source => parse(source, options)); - - return { + return sources.map(source => ({ location: pointer, - document: concatAST(documents), - }; + document: parse(source, options), + })); } } diff --git a/packages/loaders/git/tests/__snapshots__/loader.spec.ts.snap b/packages/loaders/git/tests/__snapshots__/loader.spec.ts.snap index f196ba19681..1b03a705348 100644 --- a/packages/loaders/git/tests/__snapshots__/loader.spec.ts.snap +++ b/packages/loaders/git/tests/__snapshots__/loader.spec.ts.snap @@ -58,6 +58,10 @@ Object { }, ], "kind": "Document", + "loc": Object { + "end": 30, + "start": 0, + }, } `; @@ -119,5 +123,9 @@ Object { }, ], "kind": "Document", + "loc": Object { + "end": 30, + "start": 0, + }, } `; diff --git a/packages/loaders/git/tests/loader.spec.ts b/packages/loaders/git/tests/loader.spec.ts index ba4969380ef..54b704f50fd 100644 --- a/packages/loaders/git/tests/loader.spec.ts +++ b/packages/loaders/git/tests/loader.spec.ts @@ -1,7 +1,5 @@ import { execSync } from 'child_process'; -import { Source } from '@graphql-tools/utils'; - import { GitLoader } from '../src'; import { runTests } from '../../../testing/utils'; @@ -43,22 +41,22 @@ describe('GitLoader', () => { sync: loader.loadSync.bind(loader), })(load => { it('should load document from a .graphql file', async () => { - const result: Source = await load(getPointer('type-defs.graphql'), {}); + const [result]= await load(getPointer('type-defs.graphql'), {}); expect(result.document).toBeDefined(); }); it('should load introspection data from a .json file', async () => { - const result: Source = await load(getPointer('introspection.json'), {}); + const [result]= await load(getPointer('introspection.json'), {}); expect(result.schema).toBeDefined(); }); it('should load type definitions from a .json file', async () => { - const result: Source = await load(getPointer('type-defs.json'), {}); + const [result]= await load(getPointer('type-defs.json'), {}); expect(result.document).toBeDefined(); }); it('should load type definitions from a pluckable file', async () => { - const result: Source = await load(getPointer('pluckable.ts'), {}); + const [result]= await load(getPointer('pluckable.ts'), {}); expect(result.document).toMatchSnapshot(); }); diff --git a/packages/loaders/github/src/index.ts b/packages/loaders/github/src/index.ts index 983f972b8b9..cf28b8cdc25 100644 --- a/packages/loaders/github/src/index.ts +++ b/packages/loaders/github/src/index.ts @@ -1,7 +1,7 @@ -import { UniversalLoader, parseGraphQLSDL, parseGraphQLJSON, SingleFileOptions } from '@graphql-tools/utils'; +import { Loader, parseGraphQLSDL, parseGraphQLJSON, BaseLoaderOptions, Source } from '@graphql-tools/utils'; import { fetch } from 'cross-fetch'; import { GraphQLTagPluckOptions, gqlPluckFromCodeString } from '@graphql-tools/graphql-tag-pluck'; -import { concatAST, parse } from 'graphql'; +import { parse } from 'graphql'; // github:owner/name#ref:path/to/file function extractData(pointer: string): { @@ -25,7 +25,7 @@ function extractData(pointer: string): { /** * Additional options for loading from GitHub */ -export interface GithubLoaderOptions extends SingleFileOptions { +export interface GithubLoaderOptions extends BaseLoaderOptions { /** * A GitHub access token */ @@ -46,7 +46,7 @@ export interface GithubLoaderOptions extends SingleFileOptions { * }) * ``` */ -export class GithubLoader implements UniversalLoader { +export class GithubLoader implements Loader { loaderId() { return 'github-loader'; } @@ -59,7 +59,7 @@ export class GithubLoader implements UniversalLoader { return false; } - async load(pointer: string, options: GithubLoaderOptions) { + async load(pointer: string, options: GithubLoaderOptions): Promise { const { owner, name, ref, path } = extractData(pointer); const request = await fetch('https://api.github.com/graphql', { method: 'POST', @@ -104,19 +104,19 @@ export class GithubLoader implements UniversalLoader { const content = response.data.repository.object.text; if (/\.(gql|graphql)s?$/i.test(path)) { - return parseGraphQLSDL(pointer, content, options); + return [parseGraphQLSDL(pointer, content, options)]; } if (/\.json$/i.test(path)) { - return parseGraphQLJSON(pointer, content, options); + return [parseGraphQLJSON(pointer, content, options)]; } if (path.endsWith('.tsx') || path.endsWith('.ts') || path.endsWith('.js') || path.endsWith('.jsx')) { const sources = await gqlPluckFromCodeString(pointer, content, options.pluckConfig); - return { - location: path, - document: concatAST(sources.map(source => parse(source, options))), - }; + return sources.map(source => ({ + location: pointer, + document: parse(source, options), + })); } throw new Error(`Invalid file extension: ${path}`); diff --git a/packages/loaders/github/tests/schema-from-github.spec.ts b/packages/loaders/github/tests/schema-from-github.spec.ts index 5c9e150ebb1..b7020962b11 100644 --- a/packages/loaders/github/tests/schema-from-github.spec.ts +++ b/packages/loaders/github/tests/schema-from-github.spec.ts @@ -57,7 +57,7 @@ test('load schema from GitHub', async () => { const loader = new GithubLoader(); - const schema = await loader.load(pointer, { + const [source] = await loader.load(pointer, { token, }); @@ -94,7 +94,7 @@ test('load schema from GitHub', async () => { // name expect(params.operationName).toEqual('GetGraphQLSchemaForGraphQLtools'); - assertNonMaybe(schema.document) + assertNonMaybe(source.document) // schema - expect(print(schema.document)).toEqual(printSchema(buildSchema(typeDefs))); + expect(print(source.document)).toEqual(printSchema(buildSchema(typeDefs))); }); diff --git a/packages/loaders/graphql-file/src/index.ts b/packages/loaders/graphql-file/src/index.ts index 6a036156527..79dd1bdc391 100644 --- a/packages/loaders/graphql-file/src/index.ts +++ b/packages/loaders/graphql-file/src/index.ts @@ -1,15 +1,6 @@ import type { GlobbyOptions } from 'globby'; -import { - Source, - UniversalLoader, - DocumentPointerSingle, - SchemaPointerSingle, - isValidPath, - parseGraphQLSDL, - SingleFileOptions, - ResolverGlobs, -} from '@graphql-tools/utils'; +import { Source, Loader, isValidPath, parseGraphQLSDL, BaseLoaderOptions, asArray } from '@graphql-tools/utils'; import { isAbsolute, resolve } from 'path'; import { readFileSync, promises as fsPromises, existsSync } from 'fs'; import { cwd as processCwd } from 'process'; @@ -25,7 +16,7 @@ const FILE_EXTENSIONS = ['.gql', '.gqls', '.graphql', '.graphqls']; /** * Additional options for loading from a GraphQL file */ -export interface GraphQLFileLoaderOptions extends SingleFileOptions { +export interface GraphQLFileLoaderOptions extends BaseLoaderOptions { /** * Set to `true` to disable handling `#import` syntax */ @@ -64,15 +55,12 @@ function createGlobbyOptions(options: GraphQLFileLoaderOptions): GlobbyOptions { * }); * ``` */ -export class GraphQLFileLoader implements UniversalLoader { +export class GraphQLFileLoader implements Loader { loaderId(): string { return 'graphql-file'; } - async canLoad( - pointer: SchemaPointerSingle | DocumentPointerSingle, - options: GraphQLFileLoaderOptions - ): Promise { + async canLoad(pointer: string, options: GraphQLFileLoaderOptions): Promise { if (isGlob(pointer)) { // FIXME: parse to find and check the file extensions? return true; @@ -93,7 +81,7 @@ export class GraphQLFileLoader implements UniversalLoader `!(${v})`)).map(v => unixify(v)), - createGlobbyOptions(options) - ); + async resolveGlobs(glob: string, options: GraphQLFileLoaderOptions) { + const ignores = asArray(options.ignore || []); + return globby([glob, ...ignores.map(v => `!(${v})`).map(v => unixify(v))], createGlobbyOptions(options)); } - resolveGlobsSync({ globs, ignores }: ResolverGlobs, options: GraphQLFileLoaderOptions) { - return globby.sync( - globs.concat(ignores.map(v => `!(${v})`)).map(v => unixify(v)), - createGlobbyOptions(options) - ); + resolveGlobsSync(glob: string, options: GraphQLFileLoaderOptions) { + const ignores = asArray(options.ignore || []); + return globby.sync([glob, ...ignores.map(v => `!(${v})`).map(v => unixify(v))], createGlobbyOptions(options)); } - async load(pointer: SchemaPointerSingle | DocumentPointerSingle, options: GraphQLFileLoaderOptions): Promise { + async load(pointer: string, options: GraphQLFileLoaderOptions): Promise { + if (isGlob(pointer)) { + const resolvedPaths = await this.resolveGlobs(pointer, options); + const finalResult: Source[] = []; + await Promise.all( + resolvedPaths.map(async path => { + if (await this.canLoad(path, options)) { + const result = await this.load(path, options); + result?.forEach(result => finalResult.push(result)); + } + }) + ); + return finalResult; + } const normalizedFilePath = isAbsolute(pointer) ? pointer : resolve(options.cwd || processCwd(), pointer); const rawSDL: string = await readFile(normalizedFilePath, { encoding: 'utf8' }); - return this.handleFileContent(rawSDL, normalizedFilePath, options); + return [this.handleFileContent(rawSDL, normalizedFilePath, options)]; } - loadSync(pointer: SchemaPointerSingle | DocumentPointerSingle, options: GraphQLFileLoaderOptions): Source { + loadSync(pointer: string, options: GraphQLFileLoaderOptions): Source[] { + if (isGlob(pointer)) { + const resolvedPaths = this.resolveGlobsSync(pointer, options); + const finalResult: Source[] = []; + for (const path of resolvedPaths) { + if (this.canLoadSync(path, options)) { + const result = this.loadSync(path, options); + result?.forEach(result => finalResult.push(result)); + } + } + return finalResult; + } const normalizedFilePath = isAbsolute(pointer) ? pointer : resolve(options.cwd || processCwd(), pointer); const rawSDL = readFileSync(normalizedFilePath, { encoding: 'utf8' }); - return this.handleFileContent(rawSDL, normalizedFilePath, options); + return [this.handleFileContent(rawSDL, normalizedFilePath, options)]; } handleFileContent(rawSDL: string, pointer: string, options: GraphQLFileLoaderOptions) { diff --git a/packages/loaders/graphql-file/tests/loader.spec.ts b/packages/loaders/graphql-file/tests/loader.spec.ts index ccfcc914d9d..05069ddc290 100644 --- a/packages/loaders/graphql-file/tests/loader.spec.ts +++ b/packages/loaders/graphql-file/tests/loader.spec.ts @@ -1,7 +1,6 @@ import { join } from 'path'; import { print } from 'graphql' -import { Source } from '@graphql-tools/utils'; import { GraphQLFileLoader } from '../src'; import { runTests } from '../../../testing/utils'; @@ -52,17 +51,17 @@ describe('GraphQLFileLoader', () => { sync: loader.loadSync.bind(loader), })(load => { it('should load type definitions from a .graphql file', async () => { - const result: Source = await load(getPointer('type-defs.graphql'), {}); + const [result] = await load(getPointer('type-defs.graphql'), {}); expect(result.document).toBeDefined(); }); it('should load file from absolute path', async () => { - const result: Source = await load(join(process.cwd(), getPointer('type-defs.graphql')), {}); + const [result] = await load(join(process.cwd(), getPointer('type-defs.graphql')), {}); expect(result.document).toBeDefined(); }); it('should load type definitions document with #import expression', async () => { - const result: Source = await load(getPointer('type-defs-with-import.graphql'), {}); + const [result] = await load(getPointer('type-defs-with-import.graphql'), {}); expect(print(result.document!)).toBeSimilarGqlDoc(/* GraphQL */` type Query { a: A @@ -75,7 +74,7 @@ describe('GraphQLFileLoader', () => { }); it('should load executable document with #import expression', async () => { - const result: Source = await load(getPointer('executable.graphql'), {}); + const [result] = await load(getPointer('executable.graphql'), {}); expect(print(result.document!)).toBeSimilarGqlDoc(/* GraphQL */` query MyQuery { a { diff --git a/packages/loaders/json-file/src/index.ts b/packages/loaders/json-file/src/index.ts index a9feb325935..69d0a14c2c8 100644 --- a/packages/loaders/json-file/src/index.ts +++ b/packages/loaders/json-file/src/index.ts @@ -1,11 +1,4 @@ -import { - Source, - parseGraphQLJSON, - SchemaPointerSingle, - DocumentLoader, - isValidPath, - SingleFileOptions, -} from '@graphql-tools/utils'; +import { Source, parseGraphQLJSON, Loader, isValidPath, BaseLoaderOptions } from '@graphql-tools/utils'; import { isAbsolute, resolve } from 'path'; import { readFileSync, promises as fsPromises, existsSync } from 'fs'; import { cwd } from 'process'; @@ -17,7 +10,7 @@ const FILE_EXTENSIONS = ['.json']; /** * Additional options for loading from a JSON file */ -export interface JsonFileLoaderOptions extends SingleFileOptions {} +export interface JsonFileLoaderOptions extends BaseLoaderOptions {} /** * This loader loads documents and type definitions from JSON files. @@ -42,12 +35,12 @@ export interface JsonFileLoaderOptions extends SingleFileOptions {} * }); * ``` */ -export class JsonFileLoader implements DocumentLoader { +export class JsonFileLoader implements Loader { loaderId(): string { return 'json-file'; } - async canLoad(pointer: SchemaPointerSingle, options: JsonFileLoaderOptions): Promise { + async canLoad(pointer: string, options: JsonFileLoaderOptions): Promise { if (isValidPath(pointer)) { if (FILE_EXTENSIONS.find(extension => pointer.endsWith(extension))) { const normalizedFilePath = isAbsolute(pointer) ? pointer : resolve(options.cwd || cwd(), pointer); @@ -63,7 +56,7 @@ export class JsonFileLoader implements DocumentLoader { return false; } - canLoadSync(pointer: SchemaPointerSingle, options: JsonFileLoaderOptions): boolean { + canLoadSync(pointer: string, options: JsonFileLoaderOptions): boolean { if (isValidPath(pointer)) { if (FILE_EXTENSIONS.find(extension => pointer.endsWith(extension))) { const normalizedFilePath = isAbsolute(pointer) ? pointer : resolve(options.cwd || cwd(), pointer); @@ -75,23 +68,23 @@ export class JsonFileLoader implements DocumentLoader { return false; } - async load(pointer: SchemaPointerSingle, options: JsonFileLoaderOptions): Promise { + async load(pointer: string, options: JsonFileLoaderOptions): Promise { const normalizedFilePath = isAbsolute(pointer) ? pointer : resolve(options.cwd || cwd(), pointer); try { const jsonContent: string = await readFile(normalizedFilePath, { encoding: 'utf8' }); - return parseGraphQLJSON(pointer, jsonContent, options); + return [parseGraphQLJSON(pointer, jsonContent, options)]; } catch (e) { throw new Error(`Unable to read JSON file: ${normalizedFilePath}: ${e.message || /* istanbul ignore next */ e}`); } } - loadSync(pointer: SchemaPointerSingle, options: JsonFileLoaderOptions): Source { + loadSync(pointer: string, options: JsonFileLoaderOptions): Source[] { const normalizedFilepath = isAbsolute(pointer) ? pointer : resolve(options.cwd || cwd(), pointer); try { const jsonContent = readFileSync(normalizedFilepath, 'utf8'); - return parseGraphQLJSON(pointer, jsonContent, options); + return [parseGraphQLJSON(pointer, jsonContent, options)]; } catch (e) { throw new Error(`Unable to read JSON file: ${normalizedFilepath}: ${e.message || /* istanbul ignore next */ e}`); } diff --git a/packages/loaders/json-file/tests/loader.spec.ts b/packages/loaders/json-file/tests/loader.spec.ts index 4f14e46daf4..7492bae5602 100644 --- a/packages/loaders/json-file/tests/loader.spec.ts +++ b/packages/loaders/json-file/tests/loader.spec.ts @@ -1,7 +1,5 @@ import { join } from 'path'; -import { Source } from '@graphql-tools/utils'; - import { JsonFileLoader } from '../src'; import { runTests } from '../../../testing/utils'; @@ -50,17 +48,17 @@ describe('JsonFileLoader', () => { sync: loader.loadSync.bind(loader), })(load => { it('should load introspection data from a .json file', async () => { - const result: Source = await load(getPointer('introspection.json'), {}); + const [result] = await load(getPointer('introspection.json'), {}); expect(result.schema).toBeDefined(); }); it('should load type definitions from a .json file', async () => { - const result: Source = await load(getPointer('type-defs.json'), {}); + const [result] = await load(getPointer('type-defs.json'), {}); expect(result.document).toBeDefined(); }); it('should load file from absolute path', async () => { - const result: Source = await load(join(process.cwd(), getPointer('type-defs.json')), {}); + const [result] = await load(join(process.cwd(), getPointer('type-defs.json')), {}); expect(result.document).toBeDefined(); }); diff --git a/packages/loaders/module/src/index.ts b/packages/loaders/module/src/index.ts index 3ed2e72a53b..db7840a5770 100644 --- a/packages/loaders/module/src/index.ts +++ b/packages/loaders/module/src/index.ts @@ -1,8 +1,5 @@ import { DocumentNode, GraphQLSchema, isSchema } from 'graphql'; -import { - UniversalLoader, - Source, -} from '@graphql-tools/utils'; +import { Loader, Source } from '@graphql-tools/utils'; import { existsSync, promises as fsPromises } from 'fs'; const { access } = fsPromises; @@ -12,9 +9,7 @@ const createLoadError = (error: any) => new Error('Unable to load schema from module: ' + `${error.message || /* istanbul ignore next */ error}`); // module:node/module#export -function extractData( - pointer: string -): { +function extractData(pointer: string): { modulePath: string; exportName?: string; } { @@ -39,7 +34,7 @@ function extractData( * }) * ``` */ -export class ModuleLoader implements UniversalLoader { +export class ModuleLoader implements Loader { loaderId() { return 'module-loader'; } @@ -68,7 +63,7 @@ export class ModuleLoader implements UniversalLoader { try { const moduleAbsolutePath = require.resolve(modulePath); return existsSync(moduleAbsolutePath); - } catch(e) { + } catch (e) { return false; } } @@ -80,7 +75,7 @@ export class ModuleLoader implements UniversalLoader { const result = this.parse(pointer, await this.importModule(pointer)); if (result) { - return result; + return [result]; } throw InvalidError; @@ -94,7 +89,7 @@ export class ModuleLoader implements UniversalLoader { const result = this.parse(pointer, this.importModuleSync(pointer)); if (result) { - return result; + return [result]; } throw InvalidError; diff --git a/packages/loaders/module/tests/loader.spec.ts b/packages/loaders/module/tests/loader.spec.ts index b5b821dfd90..220af74d42f 100644 --- a/packages/loaders/module/tests/loader.spec.ts +++ b/packages/loaders/module/tests/loader.spec.ts @@ -1,7 +1,5 @@ import { join } from 'path'; -import { Source } from '@graphql-tools/utils'; - import { ModuleLoader } from '../src'; import { runTests } from '../../../testing/utils'; @@ -43,22 +41,22 @@ describe('ModuleLoader', () => { sync: loader.loadSync.bind(loader), })(load => { it('should load GraphQLSchema object from a file', async () => { - const result: Source = await load(getPointer('schema')); + const [result] = await load(getPointer('schema')); expect(result.schema).toBeDefined(); }); it('should load DocumentNode object from a file', async () => { - const result: Source = await load(getPointer('type-defs')); + const [result] = await load(getPointer('type-defs')); expect(result.document).toBeDefined(); }); it('should load string from a file', async () => { - const result: Source = await load(getPointer('type-defs-string')); + const [result] = await load(getPointer('type-defs-string')); expect(result.rawSDL).toBeDefined(); }); it('should load using a named export', async () => { - const result: Source = await load(getPointer('type-defs-named-export', 'typeDefs')); + const [result] = await load(getPointer('type-defs-named-export', 'typeDefs')); expect(result.document).toBeDefined(); }); diff --git a/packages/loaders/url/package.json b/packages/loaders/url/package.json index c43092cd922..f7d526b6767 100644 --- a/packages/loaders/url/package.json +++ b/packages/loaders/url/package.json @@ -11,8 +11,8 @@ "license": "MIT", "sideEffects": false, "main": "dist/index.js", - "module": "dist/index.mjs", - "exports": { + "module": "dist/index.mjs", + "exports": { ".": { "require": "./dist/index.js", "import": "./dist/index.mjs" @@ -35,6 +35,7 @@ "graphql": "^14.0.0 || ^15.0.0" }, "devDependencies": { + "@types/valid-url": "1.0.3", "@types/extract-files": "8.1.1", "@types/ws": "7.4.6", "graphql-upload": "12.0.0", diff --git a/packages/loaders/url/src/index.ts b/packages/loaders/url/src/index.ts index f5cd4c9f5cf..f2411f107d7 100644 --- a/packages/loaders/url/src/index.ts +++ b/packages/loaders/url/src/index.ts @@ -6,10 +6,9 @@ import { AsyncExecutor, Executor, SyncExecutor, - SchemaPointerSingle, Source, - DocumentLoader, - SingleFileOptions, + Loader, + BaseLoaderOptions, observableToAsyncIterable, isAsyncIterable, ExecutionParams, @@ -86,7 +85,7 @@ export enum SubscriptionProtocol { /** * Additional options for loading from a URL */ -export interface LoadFromUrlOptions extends SingleFileOptions, Partial { +export interface LoadFromUrlOptions extends BaseLoaderOptions, Partial { /** * Additional headers to include when querying the original schema */ @@ -147,16 +146,16 @@ export interface LoadFromUrlOptions extends SingleFileOptions, Partial { +export class UrlLoader implements Loader { loaderId(): string { return 'url'; } - async canLoad(pointer: SchemaPointerSingle, options: LoadFromUrlOptions): Promise { + async canLoad(pointer: string, options: LoadFromUrlOptions): Promise { return this.canLoadSync(pointer, options); } - canLoadSync(pointer: SchemaPointerSingle, _options: LoadFromUrlOptions): boolean { + canLoadSync(pointer: string, _options: LoadFromUrlOptions): boolean { return !!isWebUri(pointer); } @@ -619,9 +618,9 @@ export class UrlLoader implements DocumentLoader { return executor; } - handleSDL(pointer: SchemaPointerSingle, fetch: SyncFetchFn, options: LoadFromUrlOptions): Source; - handleSDL(pointer: SchemaPointerSingle, fetch: AsyncFetchFn, options: LoadFromUrlOptions): Promise; - handleSDL(pointer: SchemaPointerSingle, fetch: FetchFn, options: LoadFromUrlOptions): Source | Promise { + handleSDL(pointer: string, fetch: SyncFetchFn, options: LoadFromUrlOptions): Source; + handleSDL(pointer: string, fetch: AsyncFetchFn, options: LoadFromUrlOptions): Promise; + handleSDL(pointer: string, fetch: FetchFn, options: LoadFromUrlOptions): Source | Promise { const defaultMethod = this.getDefaultMethodFromOptions(options?.method, 'GET'); return new ValueOrPromise(() => fetch(pointer, { @@ -634,7 +633,7 @@ export class UrlLoader implements DocumentLoader { .resolve(); } - async load(pointer: SchemaPointerSingle, options: LoadFromUrlOptions): Promise { + async load(pointer: string, options: LoadFromUrlOptions): Promise { let source: Source = { location: pointer, }; @@ -669,10 +668,10 @@ export class UrlLoader implements DocumentLoader { executor, }); - return source; + return [source]; } - loadSync(pointer: SchemaPointerSingle, options: LoadFromUrlOptions): Source { + loadSync(pointer: string, options: LoadFromUrlOptions): Source[] { let source: Source = { location: pointer, }; @@ -707,7 +706,7 @@ export class UrlLoader implements DocumentLoader { executor, }); - return source; + return [source]; } } diff --git a/packages/loaders/url/tests/url-loader.spec.ts b/packages/loaders/url/tests/url-loader.spec.ts index eb99a2e963e..659865c4e0e 100644 --- a/packages/loaders/url/tests/url-loader.spec.ts +++ b/packages/loaders/url/tests/url-loader.spec.ts @@ -133,7 +133,7 @@ input TestInput { it('Should return a valid schema when request is valid', async () => { scope = mockGraphQLServer({ schema: testSchema, host: testHost, path: testPathChecker }); - const source = await loader.load(testUrl, {}); + const [source] = await loader.load(testUrl, {}); assertNonMaybe(source.schema) expect(printSchemaWithDirectives(source.schema)).toBeSimilarGqlDoc(testTypeDefs); }); @@ -150,7 +150,7 @@ input TestInput { }, }); - const source = await loader.load(testUrl, {}); + const [source] = await loader.load(testUrl, {}); expect(source).toBeDefined(); assertNonMaybe(source.schema) @@ -171,7 +171,7 @@ input TestInput { }, }); - const source = await loader.load(testUrl, { headers: { Auth: '1' } }); + const [source] = await loader.load(testUrl, { headers: { Auth: '1' } }); expect(source).toBeDefined(); assertNonMaybe(source.schema) @@ -184,7 +184,7 @@ input TestInput { it('Should utilize extra introspection options', async () => { scope = mockGraphQLServer({ schema: testSchema, host: testHost, path: testPathChecker }); - const source = await loader.load(testUrl, { descriptions: false }); + const [source] = await loader.load(testUrl, { descriptions: false }); expect(source).toBeDefined(); assertNonMaybe(source.schema) @@ -197,7 +197,7 @@ input TestInput { it('should handle useGETForQueries correctly', async () => { scope = mockGraphQLServer({ schema: testSchema, host: testHost, path: testPathChecker, method: 'GET' }); - const source = await loader.load(testUrl, { + const [source] = await loader.load(testUrl, { descriptions: false, useGETForQueries: true, }); @@ -234,7 +234,7 @@ input TestInput { }; const url = address.host + address.path; scope = mockGraphQLServer({ schema: testSchema, host: address.host, path: address.path }); - const result = await loader.load(url, {}); + const [result] = await loader.load(url, {}); assertNonMaybe(result.schema) expect(printSchemaWithDirectives(result.schema)).toBeSimilarGqlDoc(testTypeDefs); @@ -251,7 +251,7 @@ input TestInput { host: address.host.replace('ws', 'http'), path: address.path, }); - const result = await loader.load(url, {}); + const [result] = await loader.load(url, {}); assertNonMaybe(result.schema) expect(printSchemaWithDirectives(result.schema)).toBeSimilarGqlDoc(testTypeDefs); @@ -268,7 +268,7 @@ input TestInput { host: address.host.replace('wss', 'https'), path: address.path, }); - const result = await loader.load(url, {}); + const [result] = await loader.load(url, {}); assertNonMaybe(result.schema) expect(printSchemaWithDirectives(result.schema)).toBeSimilarGqlDoc(testTypeDefs); @@ -277,7 +277,7 @@ input TestInput { const testHost = 'http://localhost:3000'; const testPath = '/schema.graphql'; scope = nock(testHost).get(testPath).reply(200, testTypeDefs); - const result = await loader.load(testHost + testPath, {}); + const [result] = await loader.load(testHost + testPath, {}); assertNonMaybe(result.document) expect(print(result.document)).toBeSimilarGqlDoc(testTypeDefs); @@ -286,7 +286,7 @@ input TestInput { const testHost = 'http://localhost:3000'; const testPath = '/sdl'; scope = nock(testHost).get(testPath).reply(200, testTypeDefs); - const result = await loader.load(testHost + testPath, { + const [result] = await loader.load(testHost + testPath, { handleAsSDL: true, }); @@ -296,7 +296,7 @@ input TestInput { it('should handle subscriptions - new protocol', (done) => { Promise.resolve().then(async () => { const testUrl = 'http://localhost:8081/graphql'; - const { schema } = await loader.load(testUrl, { + const [{ schema }] = await loader.load(testUrl, { customFetch: async () => ({ headers: { 'content-type': 'application/json' @@ -366,7 +366,7 @@ input TestInput { it('should handle subscriptions - legacy protocol', (done) => { Promise.resolve().then(async () => { const testUrl = 'http://localhost:8081/graphql'; - const { schema } = await loader.load(testUrl, { + const [{ schema }] = await loader.load(testUrl, { customFetch: async () => ({ headers: { 'content-type': 'application/json' @@ -433,7 +433,7 @@ input TestInput { it('should handle multipart requests', async () => { scope = mockGraphQLServer({ schema: testSchema, host: testHost, path: testPathChecker, method: 'POST' }); - const { schema } = await loader.load(testUrl, { + const [{ schema }] = await loader.load(testUrl, { multipart: true, }); diff --git a/packages/utils/src/loaders.ts b/packages/utils/src/loaders.ts index 56efc329de4..73b1d6fac24 100644 --- a/packages/utils/src/loaders.ts +++ b/packages/utils/src/loaders.ts @@ -8,45 +8,19 @@ export interface Source { location?: string; } -export type SingleFileOptions = GraphQLParseOptions & +export type BaseLoaderOptions = GraphQLParseOptions & BuildSchemaOptions & { cwd?: string; + ignore?: string | string[]; }; export type WithList = T | T[]; export type ElementOf = TList extends Array ? TElement : never; -export type SchemaPointer = WithList; -export type SchemaPointerSingle = ElementOf; -export type DocumentGlobPathPointer = string; -export type DocumentPointer = WithList; -export type DocumentPointerSingle = ElementOf; -export interface Loader { +export interface Loader { loaderId(): string; - canLoad(pointer: TPointer, options?: TOptions): Promise; - canLoadSync?(pointer: TPointer, options?: TOptions): boolean; - resolveGlobs?(globs: ResolverGlobs, options?: TOptions): Promise; - resolveGlobsSync?(globs: ResolverGlobs, options?: TOptions): TPointer[]; - load(pointer: TPointer, options?: TOptions): Promise; - loadSync?(pointer: TPointer, options?: TOptions): Source | null | never; + canLoad(pointer: string, options?: TOptions): Promise; + canLoadSync?(pointer: string, options?: TOptions): boolean; + load(pointer: string, options?: TOptions): Promise; + loadSync?(pointer: string, options?: TOptions): Source[] | null | never; } - -export type SchemaLoader = Loader< - SchemaPointerSingle, - TOptions ->; - -export type DocumentLoader = Loader< - DocumentPointerSingle, - TOptions ->; - -export type UniversalLoader = Loader< - SchemaPointerSingle | DocumentPointerSingle, - TOptions ->; - -export type ResolverGlobs = { - globs: string[]; - ignores: string[]; -}; diff --git a/yarn.lock b/yarn.lock index 6a55f4945f0..ad8e0795d0e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7599,13 +7599,6 @@ is-generator-fn@^2.0.0: resolved "https://registry.yarnpkg.com/is-generator-fn/-/is-generator-fn-2.1.0.tgz#7d140adc389aaf3011a8f2a2a4cfa6faadffb118" integrity sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ== -is-glob@4.0.1, is-glob@^4.0.0, is-glob@^4.0.1, is-glob@~4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc" - integrity sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg== - dependencies: - is-extglob "^2.1.1" - is-glob@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-2.0.1.tgz#d096f926a3ded5600f3fdfd91198cb0888c2d863" @@ -7620,6 +7613,13 @@ is-glob@^3.1.0: dependencies: is-extglob "^2.1.0" +is-glob@^4.0.0, is-glob@^4.0.1, is-glob@~4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc" + integrity sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg== + dependencies: + is-extglob "^2.1.1" + is-hexadecimal@^1.0.0: version "1.0.4" resolved "https://registry.yarnpkg.com/is-hexadecimal/-/is-hexadecimal-1.0.4.tgz#cc35c97588da4bd49a8eedd6bc4082d44dcb23a7" From ce9c398daf77443cca46e4dd63d90e4293054bf1 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 7 Jul 2021 15:03:14 -0400 Subject: [PATCH 30/66] chore(deps): update dependency @types/node to v14.17.5 (#3160) Co-authored-by: Renovate Bot --- package.json | 2 +- yarn.lock | 22 +++++++++++----------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/package.json b/package.json index 139ff330347..30aeab737d0 100644 --- a/package.json +++ b/package.json @@ -50,7 +50,7 @@ "@babel/preset-typescript": "7.14.5", "@changesets/cli": "2.16.0", "@types/jest": "26.0.24", - "@types/node": "14.17.4", + "@types/node": "14.17.5", "@typescript-eslint/eslint-plugin": "4.28.2", "@typescript-eslint/parser": "4.28.2", "babel-jest": "27.0.6", diff --git a/yarn.lock b/yarn.lock index ad8e0795d0e..e6ec9c9e849 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2749,10 +2749,10 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-15.6.0.tgz#f0ddca5a61e52627c9dcb771a6039d44694597bc" integrity sha512-gCYSfQpy+LYhOFTKAeE8BkyGqaxmlFxe+n4DKM6DR0wzw/HISUE/hAmkC/KT8Sw5PCJblqg062b3z9gucv3k0A== -"@types/node@14.17.4": - version "14.17.4" - resolved "https://registry.yarnpkg.com/@types/node/-/node-14.17.4.tgz#218712242446fc868d0e007af29a4408c7765bc0" - integrity sha512-8kQ3+wKGRNN0ghtEn7EGps/B8CzuBz1nXZEIGGLP2GnwbqYn4dbTs7k+VKLTq1HvZLRCIDtN3Snx1Ege8B7L5A== +"@types/node@14.17.5": + version "14.17.5" + resolved "https://registry.yarnpkg.com/@types/node/-/node-14.17.5.tgz#b59daf6a7ffa461b5648456ca59050ba8e40ed54" + integrity sha512-bjqH2cX/O33jXT/UmReo2pM7DIJREPMnarixbQ57DOOzzFaI6D2+IcwaJQaJpv0M1E9TIhPCYVxrkcityLjlqA== "@types/node@^12.7.1": version "12.20.6" @@ -7599,6 +7599,13 @@ is-generator-fn@^2.0.0: resolved "https://registry.yarnpkg.com/is-generator-fn/-/is-generator-fn-2.1.0.tgz#7d140adc389aaf3011a8f2a2a4cfa6faadffb118" integrity sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ== +is-glob@4.0.1, is-glob@^4.0.0, is-glob@^4.0.1, is-glob@~4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc" + integrity sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg== + dependencies: + is-extglob "^2.1.1" + is-glob@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-2.0.1.tgz#d096f926a3ded5600f3fdfd91198cb0888c2d863" @@ -7613,13 +7620,6 @@ is-glob@^3.1.0: dependencies: is-extglob "^2.1.0" -is-glob@^4.0.0, is-glob@^4.0.1, is-glob@~4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc" - integrity sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg== - dependencies: - is-extglob "^2.1.1" - is-hexadecimal@^1.0.0: version "1.0.4" resolved "https://registry.yarnpkg.com/is-hexadecimal/-/is-hexadecimal-1.0.4.tgz#cc35c97588da4bd49a8eedd6bc4082d44dcb23a7" From bbb5746ff13a81bf1c91ea4f60f16791acdde008 Mon Sep 17 00:00:00 2001 From: Laurin Quast Date: Wed, 7 Jul 2021 23:35:06 +0200 Subject: [PATCH 31/66] ensure indent is covered via test (#3162) * ensure indent is covered * allow providing config via constructor * fix: ensure next loader will be used if first one does not yield a result --- .changeset/metal-apes-sell.md | 5 ++ packages/load/src/load-typedefs/load-file.ts | 11 +++- .../documents/documents-from-glob.spec.ts | 7 +++ packages/loaders/code-file/src/index.ts | 29 +++++++-- .../tests/load-from-code-file.spec.ts | 61 ++++++++++++++----- 5 files changed, 92 insertions(+), 21 deletions(-) create mode 100644 .changeset/metal-apes-sell.md diff --git a/.changeset/metal-apes-sell.md b/.changeset/metal-apes-sell.md new file mode 100644 index 00000000000..ea3002604fc --- /dev/null +++ b/.changeset/metal-apes-sell.md @@ -0,0 +1,5 @@ +--- +'@graphql-tools/code-file-loader': minor +--- + +allow supplying config via constructor diff --git a/packages/load/src/load-typedefs/load-file.ts b/packages/load/src/load-typedefs/load-file.ts index ee7944a7426..237adce9ac0 100644 --- a/packages/load/src/load-typedefs/load-file.ts +++ b/packages/load/src/load-typedefs/load-file.ts @@ -1,4 +1,4 @@ -import { Source, Maybe } from '@graphql-tools/utils'; +import { Source, Maybe, isSome } from '@graphql-tools/utils'; import { env } from 'process'; import { LoadTypedefsOptions } from '../load-typedefs'; @@ -15,6 +15,9 @@ export async function loadFile(pointer: string, options: LoadTypedefsOptions): P if (canLoad) { const loadedValue = await loader.load(pointer, options); + if (!isSome(loadedValue) || loadedValue.length === 0) { + continue; + } return loadedValue; } } catch (error) { @@ -41,7 +44,11 @@ export function loadFileSync(pointer: string, options: LoadTypedefsOptions): May if (canLoad) { // We check for the existence so it is okay to force non null - return loader.loadSync!(pointer, options); + const loadedValue = loader.loadSync!(pointer, options); + if (!isSome(loadedValue) || loadedValue.length === 0) { + continue; + } + return loadedValue; } } catch (error) { if (env['DEBUG']) { diff --git a/packages/load/tests/loaders/documents/documents-from-glob.spec.ts b/packages/load/tests/loaders/documents/documents-from-glob.spec.ts index d8ebedf3283..27ddbe34fab 100644 --- a/packages/load/tests/loaders/documents/documents-from-glob.spec.ts +++ b/packages/load/tests/loaders/documents/documents-from-glob.spec.ts @@ -133,5 +133,12 @@ describe('documentsFromGlob', () => { }); expect(result.length).toBe(1); }); + test(`should try next loader if first one fails`, async () => { + const glob = join(__dirname, './test-with-brackets/', '**/*.ts'); + const result = await load(glob, { + loaders: [new GraphQLFileLoader(), new CodeFileLoader()], + }); + expect(result.length).toBe(1); + }) }) }); diff --git a/packages/loaders/code-file/src/index.ts b/packages/loaders/code-file/src/index.ts index 68274a89587..1ae63b12828 100644 --- a/packages/loaders/code-file/src/index.ts +++ b/packages/loaders/code-file/src/index.ts @@ -26,15 +26,19 @@ import { createRequire } from 'module'; const { readFile, access } = fsPromises; +export type CodeFileLoaderConfig = { + pluckConfig?: GraphQLTagPluckOptions; + noPluck?: boolean; + noRequire?: boolean; +}; + /** * Additional options for loading from a code file */ export type CodeFileLoaderOptions = { require?: string | string[]; - pluckConfig?: GraphQLTagPluckOptions; - noPluck?: boolean; - noRequire?: boolean; -} & BaseLoaderOptions; +} & CodeFileLoaderConfig & + BaseLoaderOptions; const FILE_EXTENSIONS = ['.ts', '.tsx', '.js', '.jsx', '.vue']; @@ -57,11 +61,21 @@ function createGlobbyOptions(options: CodeFileLoaderOptions): GlobbyOptions { * Supported extensions include: `.ts`, `.tsx`, `.js`, `.jsx`, `.vue` */ export class CodeFileLoader implements Loader { + private config: CodeFileLoaderConfig; + constructor(config?: CodeFileLoaderConfig) { + this.config = config ?? {}; + } + + private getMergedOptions(options: CodeFileLoaderOptions): CodeFileLoaderOptions { + return { ...this.config, ...options }; + } + loaderId(): string { return 'code-file'; } async canLoad(pointer: string, options: CodeFileLoaderOptions): Promise { + options = this.getMergedOptions(options); if (isGlob(pointer)) { // FIXME: parse to find and check the file extensions? return true; @@ -83,6 +97,7 @@ export class CodeFileLoader implements Loader { } canLoadSync(pointer: string, options: CodeFileLoaderOptions): boolean { + options = this.getMergedOptions(options); if (isGlob(pointer)) { // FIXME: parse to find and check the file extensions? return true; @@ -99,16 +114,19 @@ export class CodeFileLoader implements Loader { } async resolveGlobs(glob: string, options: CodeFileLoaderOptions) { + options = this.getMergedOptions(options); const ignores = asArray(options.ignore || []); return globby([glob, ...ignores.map(v => `!(${v})`).map(v => unixify(v))], createGlobbyOptions(options)); } resolveGlobsSync(glob: string, options: CodeFileLoaderOptions) { + options = this.getMergedOptions(options); const ignores = asArray(options.ignore || []); return globby.sync([glob, ...ignores.map(v => `!(${v})`).map(v => unixify(v))], createGlobbyOptions(options)); } async load(pointer: string, options: CodeFileLoaderOptions): Promise { + options = this.getMergedOptions(options); if (isGlob(pointer)) { const resolvedPaths = await this.resolveGlobs(pointer, options); const finalResult: Source[] = []; @@ -127,6 +145,7 @@ export class CodeFileLoader implements Loader { } loadSync(pointer: string, options: CodeFileLoaderOptions): Source[] | null { + options = this.getMergedOptions(options); if (isGlob(pointer)) { const resolvedPaths = this.resolveGlobsSync(pointer, options); const finalResult: Source[] = []; @@ -143,6 +162,7 @@ export class CodeFileLoader implements Loader { } async handleSinglePath(location: string, options: CodeFileLoaderOptions): Promise { + options = this.getMergedOptions(options); const normalizedFilePath = ensureAbsolutePath(location, options); const errors: Error[] = []; @@ -192,6 +212,7 @@ export class CodeFileLoader implements Loader { } handleSinglePathSync(location: string, options: CodeFileLoaderOptions): Source[] | null { + options = this.getMergedOptions(options); const normalizedFilePath = ensureAbsolutePath(location, options); const errors: Error[] = []; diff --git a/packages/loaders/code-file/tests/load-from-code-file.spec.ts b/packages/loaders/code-file/tests/load-from-code-file.spec.ts index 88e36b88ea0..109a27f16ac 100644 --- a/packages/loaders/code-file/tests/load-from-code-file.spec.ts +++ b/packages/loaders/code-file/tests/load-from-code-file.spec.ts @@ -117,30 +117,61 @@ describe('loadFromCodeFileSync', () => { it('should support loading many in same file', () => { const loaded = loader.loadSync('./test-files/multiple-from-file.ts', { cwd: __dirname, + pluckConfig: { + skipIndent: true, + }, }); expect(loaded?.length).toEqual(3); expect(loaded?.[0].rawSDL).toBeDefined(); expect(loaded?.[0].rawSDL).toMatchInlineSnapshot(` - "query Foo { - Tweets { - id + " + query Foo { + Tweets { + id + } } - }" + " `); expect(loaded?.[1].rawSDL).toBeDefined(); expect(loaded?.[1].rawSDL).toMatchInlineSnapshot(` -"fragment Lel on Tweet { - id - body -}" -`); + " + fragment Lel on Tweet { + id + body + } + " + `); expect(loaded?.[2].rawSDL).toBeDefined(); expect(loaded?.[2].rawSDL).toMatchInlineSnapshot(` -"query Bar { - Tweets { - ...Lel - } -}" -`); + " + query Bar { + Tweets { + ...Lel + } + } + " + `); }); + + it('can inherit config options from constructor', () => { + const loader = new CodeFileLoader({ + pluckConfig: { + skipIndent: true + } + }) + const loaded = loader.loadSync('./test-files/multiple-from-file.ts', { + cwd: __dirname, + }); + expect(loaded?.length).toEqual(3); + expect(loaded?.[0].rawSDL).toBeDefined(); + expect(loaded?.[0].rawSDL).toMatchInlineSnapshot(` + " + query Foo { + Tweets { + id + } + } + " + `); + }) }); From 76a81220eabd4c8afff91c67f4a5543cb0dc1d74 Mon Sep 17 00:00:00 2001 From: Arda TANRIKULU Date: Thu, 8 Jul 2021 11:45:45 -0400 Subject: [PATCH 32/66] Update bug_report.md --- .github/ISSUE_TEMPLATE/config.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index 11c9593b727..31ec19dc557 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -3,3 +3,6 @@ contact_links: - name: Have a question? url: https://github.com/ardatan/graphql-tools/discussions/new about: Not sure about something? need help from the community? have a question to our team? please ask and answer questions here. + - name: Any issue with `npm audit` + url: https://overreacted.io/npm-audit-broken-by-design/ + about: Please do not create issues about `npm audit` and you can contact with us directly for more questions. From 9c8f85bfd6c8fad13dcbf0015e83e53f13b3be2c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 8 Jul 2021 12:24:45 -0400 Subject: [PATCH 33/66] chore(deps): update dependency @types/babel__traverse to v7.14.2 (#3167) Co-authored-by: Renovate Bot --- packages/graphql-tag-pluck/package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/graphql-tag-pluck/package.json b/packages/graphql-tag-pluck/package.json index c44a6903f5e..d9ca6f4c5a8 100644 --- a/packages/graphql-tag-pluck/package.json +++ b/packages/graphql-tag-pluck/package.json @@ -36,7 +36,7 @@ "tslib": "~2.3.0" }, "devDependencies": { - "@types/babel__traverse": "7.14.1", + "@types/babel__traverse": "7.14.2", "@vue/compiler-sfc": "3.1.4" }, "buildOptions": { diff --git a/yarn.lock b/yarn.lock index e6ec9c9e849..f4d5c6c8ec5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2457,10 +2457,10 @@ "@babel/parser" "^7.1.0" "@babel/types" "^7.0.0" -"@types/babel__traverse@*", "@types/babel__traverse@7.14.1", "@types/babel__traverse@^7.0.4", "@types/babel__traverse@^7.0.6": - version "7.14.1" - resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.14.1.tgz#46c2f9501a7a8f0596ddfd365e08c15285a47cce" - integrity sha512-DomsDK/nX3XXHs6jlQ8/YYE6jZAuhmoGAFfcYi1h1jbBNGS7Efdx74FKLTO3HCCyLqQyLlNbql87xqa7C3M/FQ== +"@types/babel__traverse@*", "@types/babel__traverse@7.14.2", "@types/babel__traverse@^7.0.4", "@types/babel__traverse@^7.0.6": + version "7.14.2" + resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.14.2.tgz#ffcd470bbb3f8bf30481678fb5502278ca833a43" + integrity sha512-K2waXdXBi2302XUdcHcR1jCeU0LL4TD9HRs/gk0N2Xvrht+G/BfJa4QObBQZfhMdxiCpV3COl5Nfq4uKTeTnJA== dependencies: "@babel/types" "^7.3.0" From a590eeaaa69994addb74905800df0ac5e15b9738 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 8 Jul 2021 12:24:52 -0400 Subject: [PATCH 34/66] fix(deps): update dependency the-guild-components to v1.4.3 (#3168) Co-authored-by: Renovate Bot --- website/package.json | 2 +- yarn.lock | 18 +++++++++--------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/website/package.json b/website/package.json index a2fb03b07a0..9f943d0109c 100644 --- a/website/package.json +++ b/website/package.json @@ -15,7 +15,7 @@ "react": "17.0.2", "react-dom": "17.0.2", "styled-components": "5.3.0", - "the-guild-components": "1.4.2" + "the-guild-components": "1.4.3" }, "browserslist": { "production": [ diff --git a/yarn.lock b/yarn.lock index f4d5c6c8ec5..998abfd6bdf 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2386,10 +2386,10 @@ dependencies: defer-to-connect "^1.0.1" -"@theguild/components@1.4.2": - version "1.4.2" - resolved "https://registry.yarnpkg.com/@theguild/components/-/components-1.4.2.tgz#3eb507ba5eb9404a24c21b7441bb5c540646ddd1" - integrity sha512-ERz8MclhrvuSOl7cLMYPQWQT/vNkDyRiow6VpMVKCC2SiXf2Js2RtG8KKMNZY9QwRjX8PhDkJW9KXikV6ugdGA== +"@theguild/components@1.4.3": + version "1.4.3" + resolved "https://registry.yarnpkg.com/@theguild/components/-/components-1.4.3.tgz#ade9c67981fc97c139c058e034f62a6db6072df0" + integrity sha512-35sj751HgiM+HWh5MCKWhEj0D4ZYe4G90JTKMMIaPyv3PbdIMnyMhdywuDcAhTCPScH1ubd39/NgkouqznS4Ig== dependencies: "@emotion/react" "^11.4.0" "@emotion/styled" "^11.3.0" @@ -12530,12 +12530,12 @@ text-table@0.2.0, text-table@^0.2.0: resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= -the-guild-components@1.4.2: - version "1.4.2" - resolved "https://registry.yarnpkg.com/the-guild-components/-/the-guild-components-1.4.2.tgz#a0aa8f3c0d8774f6b4cf9d689c120866e84ff81a" - integrity sha512-bkM6qwe7Ee/W0q0SVccmPjsM81mo7OZUpXIbWOlr5XK9KcUGWhR8QPXuctxAku0srhsrgmorNYuwUnEiwhc6Ag== +the-guild-components@1.4.3: + version "1.4.3" + resolved "https://registry.yarnpkg.com/the-guild-components/-/the-guild-components-1.4.3.tgz#fe648275dcc84f204114e9229af6b60acd586b6a" + integrity sha512-bKyb9NQxV+BZgnkqGB3tMYwq6zRGAdo5H6THpvTKgT8jDQk7UF4gGAGT0N/WvCz7VWf68f/yKpcHgSMVPVM+Vg== dependencies: - "@theguild/components" "1.4.2" + "@theguild/components" "1.4.3" throat@^6.0.1: version "6.0.1" From 78fb79136719447de1c6d8936d3b3358146ae3e5 Mon Sep 17 00:00:00 2001 From: Yaacov Rydzinski Date: Thu, 8 Jul 2021 22:43:53 +0300 Subject: [PATCH 35/66] replace assertSome calls with more granular errors (#3169) --- packages/batch-execute/src/prefix.ts | 5 +++-- packages/batch-execute/src/splitResult.ts | 16 ++++++---------- packages/delegate/src/delegateToSchema.ts | 5 +++-- .../delegate/src/transforms/FilterToSchema.ts | 12 +++++++++--- .../src/stitchingDirectivesTransformer.ts | 5 +++-- packages/wrap/src/transforms/HoistField.ts | 14 +++++--------- packages/wrap/src/transforms/MapFields.ts | 11 ++++++++--- packages/wrap/src/transforms/MapLeafValues.ts | 19 ++++++++++++++----- .../transforms/TransformCompositeFields.ts | 11 ++++++++--- .../transforms/TransformInputObjectFields.ts | 11 ++++++++--- .../transforms/TransformInterfaceFields.ts | 11 ++++++++--- .../src/transforms/TransformObjectFields.ts | 11 ++++++++--- .../src/transforms/TransformRootFields.ts | 11 ++++++++--- packages/wrap/src/transforms/WrapFields.ts | 7 +++++-- 14 files changed, 96 insertions(+), 53 deletions(-) diff --git a/packages/batch-execute/src/prefix.ts b/packages/batch-execute/src/prefix.ts index 97460d521c8..7ec09a23c12 100644 --- a/packages/batch-execute/src/prefix.ts +++ b/packages/batch-execute/src/prefix.ts @@ -4,10 +4,11 @@ export function createPrefix(index: string): string { return `graphqlTools${index}_`; } -export function parseKey(prefixedKey: string): null | { index: number; originalKey: string } { +export function parseKey(prefixedKey: string): { index: number; originalKey: string } { const match = /^graphqlTools([\d]+)_(.*)$/.exec(prefixedKey); if (match && match.length === 3 && !isNaN(Number(match[1])) && match[2]) { return { index: Number(match[1]), originalKey: match[2] }; } - return null; + + throw new Error(`Key ${prefixedKey} is not correctly prefixed`); } diff --git a/packages/batch-execute/src/splitResult.ts b/packages/batch-execute/src/splitResult.ts index 1626a77186e..a05ad381591 100644 --- a/packages/batch-execute/src/splitResult.ts +++ b/packages/batch-execute/src/splitResult.ts @@ -2,7 +2,7 @@ import { ExecutionResult, GraphQLError } from 'graphql'; -import { assertSome, relocatedError } from '@graphql-tools/utils'; +import { relocatedError } from '@graphql-tools/utils'; import { parseKey } from './prefix'; @@ -17,9 +17,7 @@ export function splitResult({ data, errors }: ExecutionResult, numResults: numbe if (data) { for (const prefixedKey in data) { - const parsedKey = parseKey(prefixedKey); - assertSome(parsedKey, "'parsedKey' should not be null."); - const { index, originalKey } = parsedKey; + const { index, originalKey } = parseKey(prefixedKey); const result = splitResults[index]; if (result == null) { continue; @@ -36,12 +34,10 @@ export function splitResult({ data, errors }: ExecutionResult, numResults: numbe for (const error of errors) { if (error.path) { const parsedKey = parseKey(error.path[0] as string); - if (parsedKey) { - const { index, originalKey } = parsedKey; - const newError = relocatedError(error, [originalKey, ...error.path.slice(1)]); - const errors = (splitResults[index].errors = (splitResults[index].errors || []) as GraphQLError[]); - errors.push(newError); - } + const { index, originalKey } = parsedKey; + const newError = relocatedError(error, [originalKey, ...error.path.slice(1)]); + const errors = (splitResults[index].errors = (splitResults[index].errors || []) as GraphQLError[]); + errors.push(newError); } } } diff --git a/packages/delegate/src/delegateToSchema.ts b/packages/delegate/src/delegateToSchema.ts index 9431b4b1279..ada9b9cf133 100644 --- a/packages/delegate/src/delegateToSchema.ts +++ b/packages/delegate/src/delegateToSchema.ts @@ -20,7 +20,6 @@ import { Executor, ExecutionParams, Maybe, - assertSome, AggregateError, isAsyncIterable, getDefinedRootType, @@ -140,7 +139,9 @@ function getDelegationContext({ if (operation == null) { operationDefinition = getOperationAST(request.document, request.operationName); - assertSome(operationDefinition, 'Could not identify the main operation of the document.'); + if (operationDefinition == null) { + throw new Error('Cannot infer main operation from the provided document.'); + } targetOperation = operationDefinition.operation; } else { targetOperation = operation; diff --git a/packages/delegate/src/transforms/FilterToSchema.ts b/packages/delegate/src/transforms/FilterToSchema.ts index 22076b3ca82..8dd738e37e7 100644 --- a/packages/delegate/src/transforms/FilterToSchema.ts +++ b/packages/delegate/src/transforms/FilterToSchema.ts @@ -21,7 +21,7 @@ import { isInterfaceType, } from 'graphql'; -import { Request, implementsAbstractType, TypeMap, assertSome, getDefinedRootType } from '@graphql-tools/utils'; +import { Request, implementsAbstractType, TypeMap, getDefinedRootType } from '@graphql-tools/utils'; import { Transform, DelegationContext } from '../types'; @@ -141,7 +141,11 @@ function collectFragmentVariables( const name = nextFragmentName; const typeName = fragment.typeCondition.name.value; const type = targetSchema.getType(typeName); - assertSome(type); + if (type == null) { + throw new Error( + `Fragment reference type "${typeName}", but the type is not contained within the target schema.` + ); + } const { selectionSet, usedFragments: fragmentUsedFragments, @@ -209,7 +213,9 @@ function filterSelectionSet( }, leave(node: FieldNode): null | undefined | FieldNode { const type = typeInfo.getType(); - assertSome(type); + if (type == null) { + throw new Error(`No type was found for field node ${node}.`); + } const resolvedType = getNamedType(type); if (isObjectType(resolvedType) || isInterfaceType(resolvedType)) { const selections = node.selectionSet != null ? node.selectionSet.selections : null; diff --git a/packages/stitching-directives/src/stitchingDirectivesTransformer.ts b/packages/stitching-directives/src/stitchingDirectivesTransformer.ts index 27691311b2b..87094987316 100644 --- a/packages/stitching-directives/src/stitchingDirectivesTransformer.ts +++ b/packages/stitching-directives/src/stitchingDirectivesTransformer.ts @@ -17,7 +17,6 @@ import { import { cloneSubschemaConfig, SubschemaConfig, MergedTypeConfig, MergedFieldConfig } from '@graphql-tools/delegate'; import { - assertSome, getDirectives, getImplementingTypes, MapperKind, @@ -483,7 +482,9 @@ function buildKeyExpr(key: Array): string { } const aliasParts = aliasPath.split('.'); const lastAliasPart = aliasParts.pop(); - assertSome(lastAliasPart); + if (lastAliasPart == null) { + throw new Error(`Key "${key}" is invalid, no path provided.`); + } let object: Record = { [lastAliasPart]: `$key.${keyPath}` }; for (const aliasPart of aliasParts.reverse()) { diff --git a/packages/wrap/src/transforms/HoistField.ts b/packages/wrap/src/transforms/HoistField.ts index 4c686613016..299c9fcd45d 100644 --- a/packages/wrap/src/transforms/HoistField.ts +++ b/packages/wrap/src/transforms/HoistField.ts @@ -9,14 +9,7 @@ import { GraphQLFieldResolver, } from 'graphql'; -import { - appendObjectFields, - removeObjectFields, - Request, - ExecutionResult, - relocatedError, - assertSome, -} from '@graphql-tools/utils'; +import { appendObjectFields, removeObjectFields, Request, ExecutionResult, relocatedError } from '@graphql-tools/utils'; import { Transform, defaultMergedResolver, DelegationContext, SubschemaConfig } from '@graphql-tools/delegate'; @@ -52,7 +45,10 @@ export default class HoistField implements Transform { const pathToField = path.slice(); const oldFieldName = pathToField.pop(); - assertSome(oldFieldName); + + if (oldFieldName == null) { + throw new Error(`Cannot hoist field to ${newFieldName} on type ${typeName}, no path provided.`); + } this.oldFieldName = oldFieldName; this.pathToField = pathToField; diff --git a/packages/wrap/src/transforms/MapFields.ts b/packages/wrap/src/transforms/MapFields.ts index d63af39f41e..0580fa0f604 100644 --- a/packages/wrap/src/transforms/MapFields.ts +++ b/packages/wrap/src/transforms/MapFields.ts @@ -1,6 +1,6 @@ import { GraphQLSchema } from 'graphql'; -import { Request, FieldNodeMappers, ExecutionResult, assertSome } from '@graphql-tools/utils'; +import { Request, FieldNodeMappers, ExecutionResult } from '@graphql-tools/utils'; import { Transform, DelegationContext, SubschemaConfig } from '@graphql-tools/delegate'; @@ -25,8 +25,13 @@ export default class MapFields implements Transform { } private _getTransformer() { - assertSome(this.transformer); - return this.transformer; + const transformer = this.transformer; + if (transformer === undefined) { + throw new Error( + `The MapFields transform's "transformRequest" and "transformResult" methods cannot be used without first calling "transformSchema".` + ); + } + return transformer; } public transformSchema( diff --git a/packages/wrap/src/transforms/MapLeafValues.ts b/packages/wrap/src/transforms/MapLeafValues.ts index cbd4c0141ea..82da267e027 100644 --- a/packages/wrap/src/transforms/MapLeafValues.ts +++ b/packages/wrap/src/transforms/MapLeafValues.ts @@ -20,7 +20,6 @@ import { ResultVisitorMap, updateArgument, transformInputValue, - assertSome, } from '@graphql-tools/utils'; import { Transform, DelegationContext, SubschemaConfig } from '@graphql-tools/delegate'; @@ -45,13 +44,23 @@ export default class MapLeafValues implements Transform> im } private _getTypeInfo() { - assertSome(this.typeInfo); - return this.typeInfo; + const typeInfo = this.typeInfo; + if (typeInfo === undefined) { + throw new Error( + `The TransformCompositeFields transform's "transformRequest" and "transformResult" methods cannot be used without first calling "transformSchema".` + ); + } + return typeInfo; } public transformSchema( diff --git a/packages/wrap/src/transforms/TransformInputObjectFields.ts b/packages/wrap/src/transforms/TransformInputObjectFields.ts index 8f15bc67dd2..0c0bf526c8b 100644 --- a/packages/wrap/src/transforms/TransformInputObjectFields.ts +++ b/packages/wrap/src/transforms/TransformInputObjectFields.ts @@ -14,7 +14,7 @@ import { isInputType, } from 'graphql'; -import { Maybe, Request, MapperKind, mapSchema, transformInputValue, assertSome } from '@graphql-tools/utils'; +import { Maybe, Request, MapperKind, mapSchema, transformInputValue } from '@graphql-tools/utils'; import { Transform, DelegationContext, SubschemaConfig } from '@graphql-tools/delegate'; @@ -39,8 +39,13 @@ export default class TransformInputObjectFields implements Transform { } private _getTransformedSchema() { - assertSome(this.transformedSchema); - return this.transformedSchema; + const transformedSchema = this.transformedSchema; + if (transformedSchema === undefined) { + throw new Error( + `The TransformInputObjectFields transform's "transformRequest" and "transformResult" methods cannot be used without first calling "transformSchema".` + ); + } + return transformedSchema; } public transformSchema( diff --git a/packages/wrap/src/transforms/TransformInterfaceFields.ts b/packages/wrap/src/transforms/TransformInterfaceFields.ts index 9af6ef85754..e3a3f1da00d 100644 --- a/packages/wrap/src/transforms/TransformInterfaceFields.ts +++ b/packages/wrap/src/transforms/TransformInterfaceFields.ts @@ -1,6 +1,6 @@ import { GraphQLSchema, isInterfaceType, GraphQLFieldConfig } from 'graphql'; -import { Request, ExecutionResult, assertSome } from '@graphql-tools/utils'; +import { Request, ExecutionResult } from '@graphql-tools/utils'; import { Transform, DelegationContext, SubschemaConfig } from '@graphql-tools/delegate'; @@ -19,8 +19,13 @@ export default class TransformInterfaceFields implements Transform { } private _getTransformer() { - assertSome(this.transformer); - return this.transformer; + const transformer = this.transformer; + if (transformer === undefined) { + throw new Error( + `The TransformInterfaceFields transform's "transformRequest" and "transformResult" methods cannot be used without first calling "transformSchema".` + ); + } + return transformer; } public transformSchema( diff --git a/packages/wrap/src/transforms/TransformObjectFields.ts b/packages/wrap/src/transforms/TransformObjectFields.ts index ac88e6e7103..0869c96832c 100644 --- a/packages/wrap/src/transforms/TransformObjectFields.ts +++ b/packages/wrap/src/transforms/TransformObjectFields.ts @@ -1,6 +1,6 @@ import { GraphQLSchema, isObjectType, GraphQLFieldConfig } from 'graphql'; -import { Request, ExecutionResult, assertSome } from '@graphql-tools/utils'; +import { Request, ExecutionResult } from '@graphql-tools/utils'; import { Transform, DelegationContext, SubschemaConfig } from '@graphql-tools/delegate'; @@ -19,8 +19,13 @@ export default class TransformObjectFields implements Transform { } private _getTransformer() { - assertSome(this.transformer); - return this.transformer; + const transformer = this.transformer; + if (transformer === undefined) { + throw new Error( + `The TransformObjectFields transform's "transformRequest" and "transformResult" methods cannot be used without first calling "transformSchema".` + ); + } + return transformer; } public transformSchema( diff --git a/packages/wrap/src/transforms/TransformRootFields.ts b/packages/wrap/src/transforms/TransformRootFields.ts index 403bde123cd..8521c2a2ea7 100644 --- a/packages/wrap/src/transforms/TransformRootFields.ts +++ b/packages/wrap/src/transforms/TransformRootFields.ts @@ -1,6 +1,6 @@ import { GraphQLSchema, GraphQLFieldConfig } from 'graphql'; -import { Request, ExecutionResult, assertSome } from '@graphql-tools/utils'; +import { Request, ExecutionResult } from '@graphql-tools/utils'; import { Transform, DelegationContext, SubschemaConfig } from '@graphql-tools/delegate'; @@ -19,8 +19,13 @@ export default class TransformRootFields implements Transform { } private _getTransformer() { - assertSome(this.transformer); - return this.transformer; + const transformer = this.transformer; + if (transformer === undefined) { + throw new Error( + `The TransformRootFields transform's "transformRequest" and "transformResult" methods cannot be used without first calling "transformSchema".` + ); + } + return transformer; } public transformSchema( diff --git a/packages/wrap/src/transforms/WrapFields.ts b/packages/wrap/src/transforms/WrapFields.ts index 2ae45201e1c..e6e4702d423 100644 --- a/packages/wrap/src/transforms/WrapFields.ts +++ b/packages/wrap/src/transforms/WrapFields.ts @@ -18,7 +18,6 @@ import { modifyObjectFields, ExecutionResult, relocatedError, - assertSome, } from '@graphql-tools/utils'; import { Transform, defaultMergedResolver, DelegationContext, SubschemaConfig } from '@graphql-tools/delegate'; @@ -54,7 +53,11 @@ export default class WrapFields implements Transform( { [outerTypeName]: { From 93f795f20ab52345e70180e6db9985f14deaf697 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 8 Jul 2021 20:48:58 -0400 Subject: [PATCH 36/66] chore(deps): update dependency @types/relay-compiler to v8.0.1 (#3170) Co-authored-by: Renovate Bot --- packages/relay-operation-optimizer/package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/relay-operation-optimizer/package.json b/packages/relay-operation-optimizer/package.json index 98c10b4adac..6f8e37164f1 100644 --- a/packages/relay-operation-optimizer/package.json +++ b/packages/relay-operation-optimizer/package.json @@ -46,7 +46,7 @@ "tslib": "~2.3.0" }, "devDependencies": { - "@types/relay-compiler": "8.0.0" + "@types/relay-compiler": "8.0.1" }, "buildOptions": { "external": [ diff --git a/yarn.lock b/yarn.lock index 998abfd6bdf..1842642c5e4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2794,10 +2794,10 @@ resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.3.tgz#7ee330ba7caafb98090bece86a5ee44115904c2c" integrity sha512-ewFXqrQHlFsgc09MK5jP5iR7vumV/BYayNC6PgJO2LPe8vrnNFyjQjSppfEngITi0qvfKtzFvgKymGheFM9UOA== -"@types/relay-compiler@8.0.0": - version "8.0.0" - resolved "https://registry.yarnpkg.com/@types/relay-compiler/-/relay-compiler-8.0.0.tgz#98961b923555145067d3895f8774f3024f14e6fa" - integrity sha512-rSR62gfhm2ZZp888RK93/jODOCA1j2MpWr5ibZEyYprmVG1G9KE5TfNUERCcc9z58F4d8tMIX00ZpBOU1sWcDA== +"@types/relay-compiler@8.0.1": + version "8.0.1" + resolved "https://registry.yarnpkg.com/@types/relay-compiler/-/relay-compiler-8.0.1.tgz#eb85b503cfa571e60a1ae3eb5a4513fa9fcdb5f6" + integrity sha512-C2CkGeyInDAedzLrI0KcQvSKTqtMvG49tw79AqnkGJ3qyaGHbCFQYnysndPr4iyLvphNt6DJCxAqr4egFbGNzw== dependencies: "@types/relay-runtime" "*" graphql "^14.5.3" From b51730f28e97d1a53110e7acd4c55f067c912da3 Mon Sep 17 00:00:00 2001 From: Alin Simoc Date: Fri, 9 Jul 2021 18:30:08 +0300 Subject: [PATCH 37/66] root components update (#3173) --- website/docusaurus.config.js | 49 +----------------------------------- website/package.json | 3 +-- website/src/theme/Root.js | 26 +++++++++++-------- 3 files changed, 17 insertions(+), 61 deletions(-) diff --git a/website/docusaurus.config.js b/website/docusaurus.config.js index 7b9f24322f0..44e33c4839f 100644 --- a/website/docusaurus.config.js +++ b/website/docusaurus.config.js @@ -38,55 +38,8 @@ module.exports = { }, ], }, - footer: { - style: 'dark', - links: [ - /* { - title: 'Docs', - items: [ - { - label: 'Style Guide', - to: 'docs/doc1' - }, - { - label: 'Second Doc', - to: 'docs/doc2' - } - ] - }, */ - { - title: 'Community', - items: [ - { - label: 'Discord', - href: 'http://bit.ly/guild-chat', - }, - { - label: 'Stack Overflow', - href: 'https://stackoverflow.com/questions/tagged/graphql-tools', - }, - ], - }, - { - title: 'Social', - items: [ - { - label: 'GitHub', - href: 'https://github.com/Urigo/graphql-tools/', - }, - { - label: 'Twitter', - href: 'https://twitter.com/TheGuildDev', - }, - ], - }, - ], - copyright: `Copyright © ${new Date().getFullYear()} The Guild, Inc. Built with Docusaurus.`, - }, }, - scripts: [ - 'https://the-guild.dev/static/crisp.js' - ], + scripts: ['https://the-guild.dev/static/crisp.js'], presets: [ [ '@docusaurus/preset-classic', diff --git a/website/package.json b/website/package.json index 9f943d0109c..ee8b44d3446 100644 --- a/website/package.json +++ b/website/package.json @@ -14,8 +14,7 @@ "classnames": "2.3.1", "react": "17.0.2", "react-dom": "17.0.2", - "styled-components": "5.3.0", - "the-guild-components": "1.4.3" + "@theguild/components": "1.4.3" }, "browserslist": { "production": [ diff --git a/website/src/theme/Root.js b/website/src/theme/Root.js index e5d8a904bb0..d5a0eb4adb3 100644 --- a/website/src/theme/Root.js +++ b/website/src/theme/Root.js @@ -1,20 +1,24 @@ import React from 'react'; -import BrowserOnly from '@docusaurus/BrowserOnly'; -import { ThemeProvider, Header } from 'the-guild-components'; +import { ThemeProvider, GlobalStyles, Header, FooterExtended } from '@theguild/components'; // Default implementation, that you can customize function Root({ children }) { return ( - <> - - {() => ( - -
- - )} - + + +
{children} - + + ); } From 4bc21c8c18841893c88685ef059933c5cfe1de4e Mon Sep 17 00:00:00 2001 From: Arda TANRIKULU Date: Fri, 9 Jul 2021 11:55:51 -0400 Subject: [PATCH 38/66] Create codeql-analysis.yml --- .github/workflows/codeql-analysis.yml | 69 +++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 .github/workflows/codeql-analysis.yml diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml new file mode 100644 index 00000000000..7ed83923d7b --- /dev/null +++ b/.github/workflows/codeql-analysis.yml @@ -0,0 +1,69 @@ +# For most projects, this workflow file will not need changing; you simply need +# to commit it to your repository. +# +# You may wish to alter this file to override the set of languages analyzed, +# or to provide custom queries or build logic. +# +# ******** NOTE ******** +# We have attempted to detect the languages in your repository. Please check +# the `language` matrix defined below to confirm you have the correct set of +# supported CodeQL languages. +# +name: "CodeQL" + +on: + push: + branches: [ master ] + pull_request: + # The branches below must be a subset of the branches above + branches: [ master ] + +jobs: + analyze: + name: Analyze + runs-on: ubuntu-latest + permissions: + actions: read + contents: read + security-events: write + + strategy: + fail-fast: false + matrix: + language: [ 'javascript' ] + # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ] + # Learn more: + # https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed + + steps: + - name: Checkout repository + uses: actions/checkout@v2 + + # Initializes the CodeQL tools for scanning. + - name: Initialize CodeQL + uses: github/codeql-action/init@v1 + with: + languages: ${{ matrix.language }} + # If you wish to specify custom queries, you can do so here or in a config file. + # By default, queries listed here will override any specified in a config file. + # Prefix the list here with "+" to use these queries and those in the config file. + # queries: ./path/to/local/query, your-org/your-repo/queries@main + + # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). + # If this step fails, then you should remove it and run the build manually (see below) + - name: Autobuild + uses: github/codeql-action/autobuild@v1 + + # ℹ️ Command-line programs to run using the OS shell. + # 📚 https://git.io/JvXDl + + # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines + # and modify them (or add more) to build your code if your project + # uses a compiled language + + #- run: | + # make bootstrap + # make release + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v1 From 56e0a4ed3d08e86b103cf3c6ad4a523883ddd02d Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 10 Jul 2021 10:46:33 +0300 Subject: [PATCH 39/66] fix(deps): update dependency ws to v7.5.3 (#3176) Co-authored-by: Renovate Bot --- packages/loaders/url/package.json | 2 +- yarn.lock | 99 ++++--------------------------- 2 files changed, 11 insertions(+), 90 deletions(-) diff --git a/packages/loaders/url/package.json b/packages/loaders/url/package.json index f7d526b6767..89c10a9f721 100644 --- a/packages/loaders/url/package.json +++ b/packages/loaders/url/package.json @@ -62,7 +62,7 @@ "sync-fetch": "0.3.0", "tslib": "~2.3.0", "valid-url": "1.0.9", - "ws": "7.5.2", + "ws": "7.5.3", "value-or-promise": "1.0.10" }, "publishConfig": { diff --git a/yarn.lock b/yarn.lock index 1842642c5e4..e3b29655c81 100644 --- a/yarn.lock +++ b/yarn.lock @@ -227,7 +227,7 @@ jsesc "^2.5.1" source-map "^0.5.0" -"@babel/helper-annotate-as-pure@^7.0.0", "@babel/helper-annotate-as-pure@^7.10.4", "@babel/helper-annotate-as-pure@^7.12.13", "@babel/helper-annotate-as-pure@^7.14.5": +"@babel/helper-annotate-as-pure@^7.10.4", "@babel/helper-annotate-as-pure@^7.12.13", "@babel/helper-annotate-as-pure@^7.14.5": version "7.14.5" resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.14.5.tgz#7bf478ec3b71726d56a8ca5775b046fc29879e61" integrity sha512-EivH9EgBIb+G8ij1B2jAwSH36WnGvkQSEC6CkX/6v6ZFlw5fVOHvsgGF4uiEHO2GzMvunZb6tDLQEQSdrdocrA== @@ -337,7 +337,7 @@ dependencies: "@babel/types" "^7.14.5" -"@babel/helper-module-imports@^7.0.0", "@babel/helper-module-imports@^7.12.13", "@babel/helper-module-imports@^7.14.5": +"@babel/helper-module-imports@^7.12.13", "@babel/helper-module-imports@^7.14.5": version "7.14.5" resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.14.5.tgz#6d1a44df6a38c957aa7c312da076429f11b422f3" integrity sha512-SwrNHu5QWS84XlHwGYPDtCxcA0hrSlL2yhWYLgeOc0w7ccOl2qv4s/nARI0aYZW+bSwAL5CukeXA47B/1NKcnQ== @@ -1195,7 +1195,7 @@ "@babel/parser" "^7.14.5" "@babel/types" "^7.14.5" -"@babel/traverse@7.14.7", "@babel/traverse@^7.0.0", "@babel/traverse@^7.1.0", "@babel/traverse@^7.12.13", "@babel/traverse@^7.12.9", "@babel/traverse@^7.13.0", "@babel/traverse@^7.14.5", "@babel/traverse@^7.4.5", "@babel/traverse@^7.7.2": +"@babel/traverse@7.14.7", "@babel/traverse@^7.0.0", "@babel/traverse@^7.1.0", "@babel/traverse@^7.12.13", "@babel/traverse@^7.12.9", "@babel/traverse@^7.13.0", "@babel/traverse@^7.14.5", "@babel/traverse@^7.7.2": version "7.14.7" resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.14.7.tgz#64007c9774cfdc3abd23b0780bc18a3ce3631753" integrity sha512-9vDr5NzHu27wgwejuKL7kIOm4bwEtaPQ4Z6cpCmjSuaRqpH/7xc4qcGEscwMqlkwgcXl6MvqoAjZkQ24uSdIZQ== @@ -1789,13 +1789,6 @@ resolved "https://registry.yarnpkg.com/@emotion/hash/-/hash-0.8.0.tgz#bbbff68978fefdbe68ccb533bc8cbe1d1afb5413" integrity sha512-kBJtf7PH6aWwZ6fka3zQ0p6SBYzx4fl1LoZXE2RrnYST9Xljm7WfKJrU4g/Xr3Beg72MLrp1AWNUmuYJTL7Cow== -"@emotion/is-prop-valid@^0.8.8": - version "0.8.8" - resolved "https://registry.yarnpkg.com/@emotion/is-prop-valid/-/is-prop-valid-0.8.8.tgz#db28b1c4368a259b60a97311d6a952d4fd01ac1a" - integrity sha512-u5WtneEAr5IDG2Wv65yhunPSMLIpuKsbuOktRojfrEiEvRyC85LgPMZI63cr7NUqT8ZIGdSVg8ZKGxIug4lXcA== - dependencies: - "@emotion/memoize" "0.7.4" - "@emotion/is-prop-valid@^1.1.0": version "1.1.0" resolved "https://registry.yarnpkg.com/@emotion/is-prop-valid/-/is-prop-valid-1.1.0.tgz#29ef6be1e946fb4739f9707def860f316f668cde" @@ -1803,11 +1796,6 @@ dependencies: "@emotion/memoize" "^0.7.4" -"@emotion/memoize@0.7.4": - version "0.7.4" - resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.7.4.tgz#19bf0f5af19149111c40d98bb0cf82119f5d9eeb" - integrity sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw== - "@emotion/memoize@^0.7.4", "@emotion/memoize@^0.7.5": version "0.7.5" resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.7.5.tgz#2c40f81449a4e554e9fc6396910ed4843ec2be50" @@ -1853,12 +1841,7 @@ "@emotion/serialize" "^1.0.2" "@emotion/utils" "^1.0.0" -"@emotion/stylis@^0.8.4": - version "0.8.5" - resolved "https://registry.yarnpkg.com/@emotion/stylis/-/stylis-0.8.5.tgz#deacb389bd6ee77d1e7fcaccce9e16c5c7e78e04" - integrity sha512-h6KtPihKFn3T9fuIrwvXXUOwlx3rfUvfZIcP5a6rh8Y7zjE3O06hT5Ss4S/YI1AYhuZ1kjaE/5EaOOI2NqSylQ== - -"@emotion/unitless@^0.7.4", "@emotion/unitless@^0.7.5": +"@emotion/unitless@^0.7.5": version "0.7.5" resolved "https://registry.yarnpkg.com/@emotion/unitless/-/unitless-0.7.5.tgz#77211291c1900a700b8a78cfafda3160d76949ed" integrity sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg== @@ -3711,21 +3694,6 @@ babel-plugin-polyfill-regenerator@^0.2.2: dependencies: "@babel/helper-define-polyfill-provider" "^0.2.2" -"babel-plugin-styled-components@>= 1.12.0": - version "1.12.0" - resolved "https://registry.yarnpkg.com/babel-plugin-styled-components/-/babel-plugin-styled-components-1.12.0.tgz#1dec1676512177de6b827211e9eda5a30db4f9b9" - integrity sha512-FEiD7l5ZABdJPpLssKXjBUJMYqzbcNzBowfXDCdJhOpbhWiewapUaY+LZGT8R4Jg2TwOjGjG4RKeyrO5p9sBkA== - dependencies: - "@babel/helper-annotate-as-pure" "^7.0.0" - "@babel/helper-module-imports" "^7.0.0" - babel-plugin-syntax-jsx "^6.18.0" - lodash "^4.17.11" - -babel-plugin-syntax-jsx@^6.18.0: - version "6.18.0" - resolved "https://registry.yarnpkg.com/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz#0af32a9a6e13ca7a3fd5069e62d7b0f58d0d8946" - integrity sha1-CvMqmm4Tyno/1QaeYtew9Y0NiUY= - babel-plugin-syntax-trailing-function-commas@^7.0.0-beta.0: version "7.0.0-beta.0" resolved "https://registry.yarnpkg.com/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-7.0.0-beta.0.tgz#aa213c1435e2bffeb6fca842287ef534ad05d5cf" @@ -4159,11 +4127,6 @@ camelcase@^6.2.0: resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.2.0.tgz#924af881c9d525ac9d87f40d964e5cea982a1809" integrity sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg== -camelize@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/camelize/-/camelize-1.0.0.tgz#164a5483e630fa4321e5af07020e531831b2609b" - integrity sha1-FkpUg+Yw+kMh5a8HAg5TGDGyYJs= - caniuse-api@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/caniuse-api/-/caniuse-api-3.0.0.tgz#5e4d90e2274961d46291997df599e3ed008ee4c0" @@ -4806,11 +4769,6 @@ crypto-random-string@^2.0.0: resolved "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-2.0.0.tgz#ef2a7a966ec11083388369baa02ebead229b30d5" integrity sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA== -css-color-keywords@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/css-color-keywords/-/css-color-keywords-1.0.0.tgz#fea2616dc676b2962686b3af8dbdbe180b244e05" - integrity sha1-/qJhbcZ2spYmhrOvjb2+GAskTgU= - css-color-names@^0.0.4: version "0.0.4" resolved "https://registry.yarnpkg.com/css-color-names/-/css-color-names-0.0.4.tgz#808adc2e79cf84738069b646cb20ec27beb629e0" @@ -4895,15 +4853,6 @@ css-select@~1.2.0: domutils "1.5.1" nth-check "~1.0.1" -css-to-react-native@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/css-to-react-native/-/css-to-react-native-3.0.0.tgz#62dbe678072a824a689bcfee011fc96e02a7d756" - integrity sha512-Ro1yETZA813eoyUp2GDBhG2j+YggidUmzO1/v9eYBKR2EHVEniE2MI/NqpTQ954BMpTPZFsGNPm46qFB9dpaPQ== - dependencies: - camelize "^1.0.0" - css-color-keywords "^1.0.0" - postcss-value-parser "^4.0.2" - css-tree@1.0.0-alpha.37: version "1.0.0-alpha.37" resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-1.0.0-alpha.37.tgz#98bebd62c4c1d9f960ec340cf9f7522e30709a22" @@ -7024,7 +6973,7 @@ history@^4.9.0: tiny-warning "^1.0.0" value-equal "^1.0.1" -hoist-non-react-statics@^3.0.0, hoist-non-react-statics@^3.1.0, hoist-non-react-statics@^3.3.1, hoist-non-react-statics@^3.3.2: +hoist-non-react-statics@^3.1.0, hoist-non-react-statics@^3.3.1, hoist-non-react-statics@^3.3.2: version "3.3.2" resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz#ece0acaf71d62c2969c2ec59feff42a4b1a85b45" integrity sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw== @@ -11736,11 +11685,6 @@ shallow-clone@^3.0.0: dependencies: kind-of "^6.0.2" -shallowequal@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/shallowequal/-/shallowequal-1.1.0.tgz#188d521de95b9087404fd4dcb68b13df0ae4e7f8" - integrity sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ== - shebang-command@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" @@ -12270,22 +12214,6 @@ style-to-object@0.3.0, style-to-object@^0.3.0: dependencies: inline-style-parser "0.1.1" -styled-components@5.3.0: - version "5.3.0" - resolved "https://registry.yarnpkg.com/styled-components/-/styled-components-5.3.0.tgz#e47c3d3e9ddfff539f118a3dd0fd4f8f4fb25727" - integrity sha512-bPJKwZCHjJPf/hwTJl6TbkSZg/3evha+XPEizrZUGb535jLImwDUdjTNxXqjjaASt2M4qO4AVfoHJNe3XB/tpQ== - dependencies: - "@babel/helper-module-imports" "^7.0.0" - "@babel/traverse" "^7.4.5" - "@emotion/is-prop-valid" "^0.8.8" - "@emotion/stylis" "^0.8.4" - "@emotion/unitless" "^0.7.4" - babel-plugin-styled-components ">= 1.12.0" - css-to-react-native "^3.0.0" - hoist-non-react-statics "^3.0.0" - shallowequal "^1.1.0" - supports-color "^5.5.0" - stylehacks@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/stylehacks/-/stylehacks-5.0.1.tgz#323ec554198520986806388c7fdaebc38d2c06fb" @@ -12310,7 +12238,7 @@ subscriptions-transport-ws@^0.10.0: symbol-observable "^1.0.4" ws "^5.2.0 || ^6.0.0 || ^7.0.0" -supports-color@^5.3.0, supports-color@^5.4.0, supports-color@^5.5.0: +supports-color@^5.3.0, supports-color@^5.4.0: version "5.5.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== @@ -12530,13 +12458,6 @@ text-table@0.2.0, text-table@^0.2.0: resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= -the-guild-components@1.4.3: - version "1.4.3" - resolved "https://registry.yarnpkg.com/the-guild-components/-/the-guild-components-1.4.3.tgz#fe648275dcc84f204114e9229af6b60acd586b6a" - integrity sha512-bKyb9NQxV+BZgnkqGB3tMYwq6zRGAdo5H6THpvTKgT8jDQk7UF4gGAGT0N/WvCz7VWf68f/yKpcHgSMVPVM+Vg== - dependencies: - "@theguild/components" "1.4.3" - throat@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/throat/-/throat-6.0.1.tgz#d514fedad95740c12c2d7fc70ea863eb51ade375" @@ -13684,10 +13605,10 @@ write-pkg@^4.0.0: type-fest "^0.4.1" write-json-file "^3.2.0" -ws@7.5.2, "ws@^5.2.0 || ^6.0.0 || ^7.0.0", ws@^7.3.1, ws@^7.4.5: - version "7.5.2" - resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.2.tgz#09cc8fea3bec1bc5ed44ef51b42f945be36900f6" - integrity sha512-lkF7AWRicoB9mAgjeKbGqVUekLnSNO4VjKVnuPHpQeOxZOErX6BPXwJk70nFslRCEEA8EVW7ZjKwXaP9N+1sKQ== +ws@7.5.3, "ws@^5.2.0 || ^6.0.0 || ^7.0.0", ws@^7.3.1, ws@^7.4.5: + version "7.5.3" + resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.3.tgz#160835b63c7d97bfab418fc1b8a9fced2ac01a74" + integrity sha512-kQ/dHIzuLrS6Je9+uv81ueZomEwH0qVYstcAQ4/Z93K8zeko9gtAbttJWzoC5ukqXY1PpoouV3+VSOqEAFt5wg== ws@^6.2.1: version "6.2.1" From e569fe8b3bb06d7a50106aafaa8e99b5a1794ced Mon Sep 17 00:00:00 2001 From: Yaacov Rydzinski Date: Sun, 11 Jul 2021 00:06:51 +0300 Subject: [PATCH 40/66] Small refactors (#3177) * remove last prod assertSome * style --- packages/delegate/src/createRequest.ts | 15 +++++++-------- .../loaders/prisma/src/prisma-yml/Environment.ts | 8 +++++--- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/packages/delegate/src/createRequest.ts b/packages/delegate/src/createRequest.ts index f5bde01de0c..b27546f55ca 100644 --- a/packages/delegate/src/createRequest.ts +++ b/packages/delegate/src/createRequest.ts @@ -52,10 +52,6 @@ export function createRequestFromInfo({ }); } -const raiseError = (message: string) => { - throw new Error(message); -}; - export function createRequest({ sourceSchema, sourceParentType, @@ -127,15 +123,18 @@ export function createRequest({ ); } + const rootFieldName = targetFieldName ?? fieldNodes?.[0]?.name.value; + + if (rootFieldName === undefined) { + throw new Error(`Either "targetFieldName" or a non empty "fieldNodes" array must be provided.`); + } + const rootfieldNode: FieldNode = { kind: Kind.FIELD, arguments: Object.values(argumentNodeMap), name: { kind: Kind.NAME, - value: - targetFieldName ?? - fieldNodes?.[0]?.name.value ?? - raiseError("Either 'targetFieldName' or a non empty 'fieldNodes' array must be provided."), + value: rootFieldName, }, selectionSet: newSelectionSet, }; diff --git a/packages/loaders/prisma/src/prisma-yml/Environment.ts b/packages/loaders/prisma/src/prisma-yml/Environment.ts index e6bfb76c01e..beddbb71a8c 100644 --- a/packages/loaders/prisma/src/prisma-yml/Environment.ts +++ b/packages/loaders/prisma/src/prisma-yml/Environment.ts @@ -14,7 +14,6 @@ import { getProxyAgent } from './utils/getProxyAgent'; // eslint-disable-next-line // @ts-ignore import * as jwt from 'jsonwebtoken'; -import { assertSome } from '@graphql-tools/utils'; const debug = require('debug')('Environment'); export class Environment { @@ -39,8 +38,11 @@ export class Environment { } private _getClusters() { - assertSome(this.clusters); - return this.clusters; + const clusters = this.clusters; + if (clusters === undefined) { + throw new Error(`Cannot get clusters. Did you forget to call "Environment.load()"?`); + } + return clusters; } async load() { From 1489677e01863ce52f9a1f64c522b7c95deccab1 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 10 Jul 2021 22:31:23 +0000 Subject: [PATCH 41/66] chore(deps): update dependency typedoc to v0.21.3 (#3178) Co-authored-by: Renovate Bot --- package.json | 2 +- yarn.lock | 9 ++++----- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index 30aeab737d0..64720d503b3 100644 --- a/package.json +++ b/package.json @@ -72,7 +72,7 @@ "patch-package": "6.4.7", "prettier": "2.3.2", "ts-jest": "27.0.3", - "typedoc": "0.21.2", + "typedoc": "0.21.3", "typedoc-plugin-markdown": "3.10.2", "typescript": "4.3.5" }, diff --git a/yarn.lock b/yarn.lock index e3b29655c81..132ca30f2b4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -12778,14 +12778,13 @@ typedoc-plugin-markdown@3.10.2: dependencies: handlebars "^4.7.7" -typedoc@0.21.2: - version "0.21.2" - resolved "https://registry.yarnpkg.com/typedoc/-/typedoc-0.21.2.tgz#cf5094314d3d63e95a8ef052ceff06a6cafd509d" - integrity sha512-SR1ByJB3USg+jxoxwzMRP07g/0f/cQUE5t7gOh1iTUyjTPyJohu9YSKRlK+MSXXqlhIq+m0jkEHEG5HoY7/Adg== +typedoc@0.21.3: + version "0.21.3" + resolved "https://registry.yarnpkg.com/typedoc/-/typedoc-0.21.3.tgz#9d35e6789c70d3b5b908f69a830294652ef7128e" + integrity sha512-SE0MytBcr3LpZmo22KxOI5vOvy+4cHl7U3TwYfc7OpUWaZLsDgP1yVqswoIdAUl6qwqskZie6Lyw/nzW5y840w== dependencies: glob "^7.1.7" handlebars "^4.7.7" - lodash "^4.17.21" lunr "^2.3.9" marked "^2.1.1" minimatch "^3.0.0" From 84bf7916ac156cac2764144989768b7cb8b4abca Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 12 Jul 2021 03:35:00 +0000 Subject: [PATCH 42/66] chore(deps): update dependency typedoc to v0.21.4 (#3179) Co-authored-by: Renovate Bot --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 64720d503b3..203d27c87b4 100644 --- a/package.json +++ b/package.json @@ -72,7 +72,7 @@ "patch-package": "6.4.7", "prettier": "2.3.2", "ts-jest": "27.0.3", - "typedoc": "0.21.3", + "typedoc": "0.21.4", "typedoc-plugin-markdown": "3.10.2", "typescript": "4.3.5" }, diff --git a/yarn.lock b/yarn.lock index 132ca30f2b4..12dd1d51598 100644 --- a/yarn.lock +++ b/yarn.lock @@ -12778,10 +12778,10 @@ typedoc-plugin-markdown@3.10.2: dependencies: handlebars "^4.7.7" -typedoc@0.21.3: - version "0.21.3" - resolved "https://registry.yarnpkg.com/typedoc/-/typedoc-0.21.3.tgz#9d35e6789c70d3b5b908f69a830294652ef7128e" - integrity sha512-SE0MytBcr3LpZmo22KxOI5vOvy+4cHl7U3TwYfc7OpUWaZLsDgP1yVqswoIdAUl6qwqskZie6Lyw/nzW5y840w== +typedoc@0.21.4: + version "0.21.4" + resolved "https://registry.yarnpkg.com/typedoc/-/typedoc-0.21.4.tgz#fced3cffdc30180db60a5dbfec9dbbb273cb5b31" + integrity sha512-slZQhvD9U0d9KacktYAyuNMMOXJRFNHy+Gd8xY2Qrqq3eTTTv3frv3N4au/cFnab9t3T5WA0Orb6QUjMc+1bDA== dependencies: glob "^7.1.7" handlebars "^4.7.7" From ae55af7edb948244b0da8f6dba516260eaadfb1d Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 12 Jul 2021 07:44:54 +0000 Subject: [PATCH 43/66] fix(deps): update dependency @theguild/components to v1.4.4 (#3181) Co-authored-by: Renovate Bot --- website/package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/website/package.json b/website/package.json index ee8b44d3446..f853d937e9d 100644 --- a/website/package.json +++ b/website/package.json @@ -14,7 +14,7 @@ "classnames": "2.3.1", "react": "17.0.2", "react-dom": "17.0.2", - "@theguild/components": "1.4.3" + "@theguild/components": "1.4.4" }, "browserslist": { "production": [ diff --git a/yarn.lock b/yarn.lock index 12dd1d51598..0db8bd8164c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2369,10 +2369,10 @@ dependencies: defer-to-connect "^1.0.1" -"@theguild/components@1.4.3": - version "1.4.3" - resolved "https://registry.yarnpkg.com/@theguild/components/-/components-1.4.3.tgz#ade9c67981fc97c139c058e034f62a6db6072df0" - integrity sha512-35sj751HgiM+HWh5MCKWhEj0D4ZYe4G90JTKMMIaPyv3PbdIMnyMhdywuDcAhTCPScH1ubd39/NgkouqznS4Ig== +"@theguild/components@1.4.4": + version "1.4.4" + resolved "https://registry.yarnpkg.com/@theguild/components/-/components-1.4.4.tgz#d5f69529bc6e03aaaecbd05015238312a9c65bd4" + integrity sha512-S8E/Q4n0MgTS9yakXv02Uji5+zgXFXMw41E+ppkeDPyysBJBxNoHbyu3LcePReyPM5UsnBooXdveG8XVyFk+bg== dependencies: "@emotion/react" "^11.4.0" "@emotion/styled" "^11.3.0" From d718efa153a4fb791aea49437de9b4ee66a8016d Mon Sep 17 00:00:00 2001 From: Arda TANRIKULU Date: Mon, 12 Jul 2021 15:25:14 +0300 Subject: [PATCH 44/66] fix(url-loader): handle operationName correctly --- packages/loaders/url/src/index.ts | 48 ++++++++++++++++++------------- 1 file changed, 28 insertions(+), 20 deletions(-) diff --git a/packages/loaders/url/src/index.ts b/packages/loaders/url/src/index.ts index f2411f107d7..e86c1fb44d2 100644 --- a/packages/loaders/url/src/index.ts +++ b/packages/loaders/url/src/index.ts @@ -21,7 +21,7 @@ import { fetch as crossFetch } from 'cross-fetch'; import { introspectSchema, wrapSchema } from '@graphql-tools/wrap'; import { ClientOptions, createClient } from 'graphql-ws'; import WebSocket from 'isomorphic-ws'; -import syncFetch from 'sync-fetch'; +import syncFetchImported from 'sync-fetch'; import isPromise from 'is-promise'; import { extractFiles, isExtractableFile } from 'extract-files'; import FormData from 'form-data'; @@ -33,6 +33,15 @@ import _ from 'lodash'; import { ValueOrPromise } from 'value-or-promise'; import { isLiveQueryOperationDefinitionNode } from '@n1ru4l/graphql-live-query'; +const syncFetch: SyncFetchFn = (input: RequestInfo, init?: RequestInit): SyncResponse => { + if (typeof input === 'string') { + delete init?.signal; + } else { + delete (input as any).signal; + } + return syncFetchImported(input, init); +}; + export type AsyncFetchFn = typeof import('cross-fetch').fetch; export type SyncFetchFn = (input: RequestInfo, init?: RequestInit) => SyncResponse; export type SyncResponse = Omit & { @@ -41,10 +50,8 @@ export type SyncResponse = Omit & { }; export type FetchFn = AsyncFetchFn | SyncFetchFn; -// TODO: Should the types here be changed to T extends Record ? -export type AsyncImportFn = (moduleName: string) => PromiseLike; -// TODO: Should the types here be changed to T extends Record ? -export type SyncImportFn = (moduleName: string) => T; +export type AsyncImportFn = (moduleName: string) => PromiseLike; +export type SyncImportFn = (moduleName: string) => any; const asyncImport: AsyncImportFn = (moduleName: string) => import(moduleName); const syncImport: SyncImportFn = (moduleName: string) => require(moduleName); @@ -472,10 +479,10 @@ export class UrlLoader implements Loader { fetch: AsyncFetchFn, options?: Omit ): AsyncExecutor { - return async ({ document, variables, extensions }) => { + return async ({ document, variables, extensions, operationName }) => { const controller = new AbortController(); const query = print(document); - const finalUrl = this.prepareGETUrl({ baseUrl: endpoint, query, variables }); + const finalUrl = this.prepareGETUrl({ baseUrl: endpoint, query, variables, operationName, extensions }); return observableToAsyncIterable({ subscribe: observer => { const headers = Object.assign({}, options?.headers || {}, extensions?.headers || {}); @@ -530,17 +537,21 @@ export class UrlLoader implements Loader { if (customFetch) { if (typeof customFetch === 'string') { const [moduleName, fetchFnName] = customFetch.split('#'); - const moduleResult = importFn(moduleName); - if (isPromise(moduleResult)) { - return moduleResult.then(module => (fetchFnName ? (module as Record)[fetchFnName] : module)); - } else { - return fetchFnName ? (module as Record)[fetchFnName] : moduleResult; - } + return new ValueOrPromise(() => importFn(moduleName)) + .then(module => (fetchFnName ? (module as Record)[fetchFnName] : module)) + .resolve(); } else { return customFetch as any; } } - return importFn === asyncImport ? (typeof fetch === 'undefined' ? crossFetch : fetch) : syncFetch; + if (importFn === asyncImport) { + if (typeof fetch === 'undefined') { + return crossFetch as any; + } + return fetch as any; + } else { + return syncFetch; + } } private getDefaultMethodFromOptions(method: LoadFromUrlOptions['method'], defaultMethod: 'GET' | 'POST') { @@ -560,12 +571,9 @@ export class UrlLoader implements Loader { ): typeof WebSocket | PromiseLike { if (typeof options?.webSocketImpl === 'string') { const [moduleName, webSocketImplName] = options.webSocketImpl.split('#'); - const importedModule = importFn(moduleName); - if (isPromise(importedModule)) { - return importedModule.then(webSocketImplName ? importedModule[webSocketImplName] : importedModule); - } else { - return webSocketImplName ? (importedModule as Record)[webSocketImplName] : importedModule; - } + return new ValueOrPromise(() => importFn(moduleName)) + .then(importedModule => (webSocketImplName ? importedModule[webSocketImplName] : importedModule)) + .resolve(); } else { const websocketImpl = options?.webSocketImpl || WebSocket; return websocketImpl; From fed00e3c6571013451fb0ecdc2e62a6393378f73 Mon Sep 17 00:00:00 2001 From: Arda TANRIKULU Date: Mon, 12 Jul 2021 15:52:20 +0300 Subject: [PATCH 45/66] Disable TSC incremental --- package.json | 4 ++-- tsconfig.build.es5.json | 1 - tsconfig.build.json | 1 - 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index 203d27c87b4..1bc86c68b8a 100644 --- a/package.json +++ b/package.json @@ -7,8 +7,8 @@ "postinstall": "patch-package && husky install", "predeploy:website": "yarn build:api-docs", "deploy:website": "cd website && yarn deploy", - "ts:check": "tsc --noEmit --incremental", - "ts:transpile": "concurrently \"tsc --project tsconfig.build.json --incremental\" \"tsc --project tsconfig.build.es5.json --incremental\"", + "ts:check": "tsc --noEmit", + "ts:transpile": "concurrently \"tsc --project tsconfig.build.json\" \"tsc --project tsconfig.build.es5.json\"", "clean-dist": "rimraf \"packages/**/dist\" && rimraf \"packages/**/dist-es5\" && rimraf \".bob\"", "build": "yarn ts:transpile && bob build", "build:api-docs": "node scripts/build-api-docs.js", diff --git a/tsconfig.build.es5.json b/tsconfig.build.es5.json index 879594f93ff..b7dd9bc6b5f 100644 --- a/tsconfig.build.es5.json +++ b/tsconfig.build.es5.json @@ -3,7 +3,6 @@ "compilerOptions": { "outDir": "dist-es5", "target": "es5", - "tsBuildInfoFile": "./node_modules/tsconfig.build.es5.tsbuildinfo", "sourceMap": false, "inlineSourceMap": false } diff --git a/tsconfig.build.json b/tsconfig.build.json index a4e8b33e761..e342b4620c6 100644 --- a/tsconfig.build.json +++ b/tsconfig.build.json @@ -1,7 +1,6 @@ { "extends": "./tsconfig.json", "compilerOptions": { - "tsBuildInfoFile": "./node_modules/tsconfig.build.tsbuildinfo", "sourceMap": false, "inlineSourceMap": false }, From dae6dc7bc07e58f73a46c37e83ae53ddf1c07cc2 Mon Sep 17 00:00:00 2001 From: Yaacov Rydzinski Date: Mon, 12 Jul 2021 18:36:41 +0300 Subject: [PATCH 46/66] consolidate Request and ExecutionParams types (#3180) * consolidate Request and ExecutionParams - also affixes rootValue to Request - when delegating with delegateToSchema, rootValue can be set multiple ways: * when using a custom executor, the custom executor can utilize a rootValue in whichever custom way it specifies. * when using the default executor (execute/subscribe from graphql-js): -- rootValue can be passed to delegateToSchema via a named option -- rootValue can be included within a subschemaConfig -- otherwise, rootValue is inferred from the originating schema - when using wrapSchema/stitchSchemas, a subschemaConfig can specify the createProxyingResolver function which can pass whatever rootValue it wants to delegateToSchema as above. * add changeset * test --- .changeset/fresh-queens-watch.md | 24 ++++++++ .../tests/withTransforms.test.ts | 2 +- .../src/createBatchingExecutor.ts | 43 +++++++------- .../batch-execute/src/getBatchingExecutor.ts | 6 +- ...rgeExecutionParams.ts => mergeRequests.ts} | 34 +++++------ packages/delegate/src/createRequest.ts | 4 ++ packages/delegate/src/delegateToSchema.ts | 57 ++++++++----------- packages/delegate/src/index.ts | 2 +- .../src/transforms/AddArgumentsAsVariables.ts | 2 +- .../delegate/src/transforms/FilterToSchema.ts | 18 +++--- packages/delegate/src/types.ts | 17 +++--- .../delegate/tests/batchExecution.test.ts | 10 ++-- packages/links/src/linkToExecutor.ts | 6 +- packages/loaders/url/src/index.ts | 6 +- packages/stitch/tests/fixtures/schemas.ts | 4 +- packages/utils/src/Interfaces.ts | 24 +++++--- packages/utils/src/executor.ts | 24 ++------ packages/wrap/src/transforms/MapLeafValues.ts | 2 +- .../transforms/TransformInputObjectFields.ts | 2 +- packages/wrap/tests/fixtures/schemas.ts | 4 +- packages/wrap/tests/requests.test.ts | 1 + website/docs/remote-schemas.md | 5 +- website/docs/stitch-combining-schemas.md | 4 +- website/docs/stitch-type-merging.md | 2 +- 24 files changed, 156 insertions(+), 147 deletions(-) create mode 100644 .changeset/fresh-queens-watch.md rename packages/batch-execute/src/{mergeExecutionParams.ts => mergeRequests.ts} (88%) diff --git a/.changeset/fresh-queens-watch.md b/.changeset/fresh-queens-watch.md new file mode 100644 index 00000000000..baa9a52de83 --- /dev/null +++ b/.changeset/fresh-queens-watch.md @@ -0,0 +1,24 @@ +--- +'@graphql-tools/batch-delegate': major +'@graphql-tools/batch-execute': major +'@graphql-tools/delegate': major +'@graphql-tools/links': major +'@graphql-tools/url-loader': major +'@graphql-tools/stitch': major +'@graphql-tools/utils': major +'@graphql-tools/wrap': major +--- + +refactor: ExecutionParams type replaced by Request type + +rootValue property is now a part of the Request type. + +When delegating with delegateToSchema, rootValue can be set multiple ways: + +- when using a custom executor, the custom executor can utilize a rootValue in whichever custom way it specifies. +- when using the default executor (execute/subscribe from graphql-js): + -- rootValue can be passed to delegateToSchema via a named option + -- rootValue can be included within a subschemaConfig + -- otherwise, rootValue is inferred from the originating schema + +When using wrapSchema/stitchSchemas, a subschemaConfig can specify the createProxyingResolver function which can pass whatever rootValue it wants to delegateToSchema as above. diff --git a/packages/batch-delegate/tests/withTransforms.test.ts b/packages/batch-delegate/tests/withTransforms.test.ts index 66f64086a8e..844e9c2946d 100644 --- a/packages/batch-delegate/tests/withTransforms.test.ts +++ b/packages/batch-delegate/tests/withTransforms.test.ts @@ -73,7 +73,7 @@ describe('works with complex transforms', () => { ] }), resultTransformer: (results, delegationContext) => { - const userIds = delegationContext.args['userIds']; + const userIds = delegationContext.args?.['userIds']; const booksByUserIds = results.reduce( (acc: any, { userId, books }: { userId: string, books: any[] }) => { acc[userId] = books diff --git a/packages/batch-execute/src/createBatchingExecutor.ts b/packages/batch-execute/src/createBatchingExecutor.ts index 5f1bd306872..98c5e859cd6 100644 --- a/packages/batch-execute/src/createBatchingExecutor.ts +++ b/packages/batch-execute/src/createBatchingExecutor.ts @@ -4,9 +4,9 @@ import DataLoader from 'dataloader'; import { ValueOrPromise } from 'value-or-promise'; -import { ExecutionParams, Executor, ExecutionResult } from '@graphql-tools/utils'; +import { Request, Executor, ExecutionResult } from '@graphql-tools/utils'; -import { mergeExecutionParams } from './mergeExecutionParams'; +import { mergeRequests } from './mergeRequests'; import { splitResult } from './splitResult'; export function createBatchingExecutor( @@ -14,49 +14,47 @@ export function createBatchingExecutor( dataLoaderOptions?: DataLoader.Options, extensionsReducer: ( mergedExtensions: Record, - executionParams: ExecutionParams + request: Request ) => Record = defaultExtensionsReducer ): Executor { const loader = new DataLoader(createLoadFn(executor, extensionsReducer), dataLoaderOptions); - return (executionParams: ExecutionParams) => - executionParams.info?.operation.operation === 'subscription' - ? executor(executionParams) - : loader.load(executionParams); + return (request: Request) => + request.info?.operation.operation === 'subscription' ? executor(request) : loader.load(request); } function createLoadFn( executor: Executor, - extensionsReducer: (mergedExtensions: Record, executionParams: ExecutionParams) => Record + extensionsReducer: (mergedExtensions: Record, request: Request) => Record ) { - return async (execs: ReadonlyArray): Promise> => { - const execBatches: Array> = []; + return async (requests: ReadonlyArray): Promise> => { + const execBatches: Array> = []; let index = 0; - const exec = execs[index]; - let currentBatch: Array = [exec]; + const request = requests[index]; + let currentBatch: Array = [request]; execBatches.push(currentBatch); - const operationType = getOperationAST(exec.document, undefined)?.operation; + const operationType = getOperationAST(request.document, undefined)?.operation; if (operationType == null) { throw new Error('Could not identify operation type of document.'); } - while (++index < execs.length) { - const currentOperationType = getOperationAST(execs[index].document, undefined)?.operation; + while (++index < requests.length) { + const currentOperationType = getOperationAST(requests[index].document, undefined)?.operation; if (operationType == null) { throw new Error('Could not identify operation type of document.'); } if (operationType === currentOperationType) { - currentBatch.push(execs[index]); + currentBatch.push(requests[index]); } else { - currentBatch = [execs[index]]; + currentBatch = [requests[index]]; execBatches.push(currentBatch); } } const executionResults: Array> = execBatches.map(execBatch => { - const mergedExecutionParams = mergeExecutionParams(execBatch, extensionsReducer); - return new ValueOrPromise(() => executor(mergedExecutionParams) as ExecutionResult); + const mergedRequests = mergeRequests(execBatch, extensionsReducer); + return new ValueOrPromise(() => executor(mergedRequests) as ExecutionResult); }); return ValueOrPromise.all(executionResults) @@ -70,11 +68,8 @@ function createLoadFn( }; } -function defaultExtensionsReducer( - mergedExtensions: Record, - executionParams: ExecutionParams -): Record { - const newExtensions = executionParams.extensions; +function defaultExtensionsReducer(mergedExtensions: Record, request: Request): Record { + const newExtensions = request.extensions; if (newExtensions != null) { Object.assign(mergedExtensions, newExtensions); } diff --git a/packages/batch-execute/src/getBatchingExecutor.ts b/packages/batch-execute/src/getBatchingExecutor.ts index 6d5e5de32cc..e315ee3b1a2 100644 --- a/packages/batch-execute/src/getBatchingExecutor.ts +++ b/packages/batch-execute/src/getBatchingExecutor.ts @@ -1,6 +1,6 @@ import DataLoader from 'dataloader'; -import { ExecutionParams, Executor } from '@graphql-tools/utils'; +import { Request, Executor } from '@graphql-tools/utils'; import { createBatchingExecutor } from './createBatchingExecutor'; import { memoize2of4 } from './memoize'; @@ -8,9 +8,7 @@ export const getBatchingExecutor = memoize2of4(function ( _context: Record, executor: Executor, dataLoaderOptions?: DataLoader.Options | undefined, - extensionsReducer?: - | undefined - | ((mergedExtensions: Record, executionParams: ExecutionParams) => Record) + extensionsReducer?: undefined | ((mergedExtensions: Record, request: Request) => Record) ): Executor { return createBatchingExecutor(executor, dataLoaderOptions, extensionsReducer); }); diff --git a/packages/batch-execute/src/mergeExecutionParams.ts b/packages/batch-execute/src/mergeRequests.ts similarity index 88% rename from packages/batch-execute/src/mergeExecutionParams.ts rename to packages/batch-execute/src/mergeRequests.ts index 80e2fce52fc..6c14b168998 100644 --- a/packages/batch-execute/src/mergeExecutionParams.ts +++ b/packages/batch-execute/src/mergeRequests.ts @@ -18,7 +18,7 @@ import { OperationTypeNode, } from 'graphql'; -import { ExecutionParams, Maybe } from '@graphql-tools/utils'; +import { Request, Maybe } from '@graphql-tools/utils'; import { createPrefix } from './prefix'; @@ -56,10 +56,10 @@ import { createPrefix } from './prefix'; * } * } */ -export function mergeExecutionParams( - execs: Array, - extensionsReducer: (mergedExtensions: Record, executionParams: ExecutionParams) => Record -): ExecutionParams { +export function mergeRequests( + requests: Array, + extensionsReducer: (mergedExtensions: Record, request: Request) => Record +): Request { const mergedVariables: Record = Object.create(null); const mergedVariableDefinitions: Array = []; const mergedSelections: Array = []; @@ -68,11 +68,11 @@ export function mergeExecutionParams( let operation: Maybe; - for (const index in execs) { - const executionParams = execs[index]; - const prefixedExecutionParams = prefixExecutionParams(createPrefix(index), executionParams); + for (const index in requests) { + const request = requests[index]; + const prefixedRequests = prefixRequest(createPrefix(index), request); - for (const def of prefixedExecutionParams.document.definitions) { + for (const def of prefixedRequests.document.definitions) { if (isOperationDefinition(def)) { operation = def.operation; mergedSelections.push(...def.selectionSet.selections); @@ -84,8 +84,8 @@ export function mergeExecutionParams( mergedFragmentDefinitions.push(def); } } - Object.assign(mergedVariables, prefixedExecutionParams.variables); - mergedExtensions = extensionsReducer(mergedExtensions, executionParams); + Object.assign(mergedVariables, prefixedRequests.variables); + mergedExtensions = extensionsReducer(mergedExtensions, request); } if (operation == null) { @@ -109,18 +109,18 @@ export function mergeExecutionParams( }, variables: mergedVariables, extensions: mergedExtensions, - context: execs[0].context, - info: execs[0].info, + context: requests[0].context, + info: requests[0].info, }; } -function prefixExecutionParams(prefix: string, executionParams: ExecutionParams): ExecutionParams { - let document = aliasTopLevelFields(prefix, executionParams.document); - const executionVariables = executionParams.variables ?? {}; +function prefixRequest(prefix: string, request: Request): Request { + let document = aliasTopLevelFields(prefix, request.document); + const executionVariables = request.variables ?? {}; const variableNames = Object.keys(executionVariables); if (variableNames.length === 0) { - return { ...executionParams, document }; + return { ...request, document }; } document = visit(document, { diff --git a/packages/delegate/src/createRequest.ts b/packages/delegate/src/createRequest.ts index b27546f55ca..4a298a073e7 100644 --- a/packages/delegate/src/createRequest.ts +++ b/packages/delegate/src/createRequest.ts @@ -31,6 +31,7 @@ export function getDelegatingOperation(parentType: GraphQLObjectType, schema: Gr export function createRequestFromInfo({ info, + rootValue, operationName, operation = getDelegatingOperation(info.parentType, info.schema), fieldName = info.fieldName, @@ -44,6 +45,7 @@ export function createRequestFromInfo({ fragments: info.fragments, variableDefinitions: info.operation.variableDefinitions, variableValues: info.variableValues, + targetRootValue: rootValue, targetOperationName: operationName, targetOperation: operation, targetFieldName: fieldName, @@ -59,6 +61,7 @@ export function createRequest({ fragments, variableDefinitions, variableValues, + targetRootValue, targetOperationName, targetOperation, targetFieldName, @@ -171,6 +174,7 @@ export function createRequest({ return { document, variables: newVariables, + rootValue: targetRootValue, operationName: targetOperationName, }; } diff --git a/packages/delegate/src/delegateToSchema.ts b/packages/delegate/src/delegateToSchema.ts index ada9b9cf133..60ce50c1c03 100644 --- a/packages/delegate/src/delegateToSchema.ts +++ b/packages/delegate/src/delegateToSchema.ts @@ -18,7 +18,7 @@ import { getBatchingExecutor } from '@graphql-tools/batch-execute'; import { mapAsyncIterator, Executor, - ExecutionParams, + Request, Maybe, AggregateError, isAsyncIterable, @@ -43,10 +43,11 @@ export function delegateToSchema, TArgs = any>( ): any { const { info, + schema, + rootValue, operationName, operation = getDelegatingOperation(info.parentType, info.schema), fieldName = info.fieldName, - returnType = info.returnType, selectionSet, fieldNodes, } = options; @@ -57,15 +58,13 @@ export function delegateToSchema, TArgs = any>( fieldName, selectionSet, fieldNodes, + rootValue: rootValue ?? (schema as SubschemaConfig).rootValue, operationName, }); return delegateRequest({ ...options, request, - operation, - fieldName, - returnType, }); } @@ -75,7 +74,6 @@ function getDelegationReturnType( fieldName: string ): GraphQLOutputType { const rootType = getDefinedRootType(targetSchema, operation); - return rootType.getFields()[fieldName].type; } @@ -115,27 +113,22 @@ export function delegateRequest, TArgs = any>( .resolve(); } -const emptyObject = {}; - function getDelegationContext({ request, schema, operation, fieldName, returnType, - args = {}, + args, context, info, - rootValue = emptyObject, transforms = [], transformedSchema, skipTypeMerging = false, - operationName, }: IDelegateRequestOptions): DelegationContext { let operationDefinition: Maybe; let targetOperation: Maybe; let targetFieldName: string; - let targetOperationName: string | undefined; if (operation == null) { operationDefinition = getOperationAST(request.document, request.operationName); @@ -154,16 +147,6 @@ function getDelegationContext({ targetFieldName = fieldName; } - if (operationName == null) { - if (request.operationName) { - targetOperationName = request.operationName; - } else if (operationDefinition?.name?.value) { - targetOperationName = operationDefinition.name.value; - } - } else { - targetOperationName = operationName; - } - const stitchingInfo: Maybe> = info?.schema.extensions?.['stitchingInfo']; const subschemaOrSubschemaConfig: GraphQLSchema | SubschemaConfig = @@ -176,12 +159,10 @@ function getDelegationContext({ subschemaConfig: subschemaOrSubschemaConfig, targetSchema, operation: targetOperation, - operationName: targetOperationName, fieldName: targetFieldName, args, context, info, - rootValue: rootValue ?? emptyObject, returnType: returnType ?? info?.returnType ?? getDelegationReturnType(targetSchema, targetOperation, targetFieldName), transforms: @@ -204,7 +185,6 @@ function getDelegationContext({ args, context, info, - rootValue: rootValue, returnType: returnType ?? info?.returnType ?? @@ -245,17 +225,26 @@ function getExecutor(delegationContext: DelegationContext): return executor; } -const createDefaultExecutor = (schema: GraphQLSchema, operation: OperationTypeNode) => - (({ document, context, variables, rootValue }: ExecutionParams) => { - const executionParams = { +function createDefaultExecutor(schema: GraphQLSchema, operation: OperationTypeNode): Executor { + if (operation === 'subscription') { + return (({ document, context, variables, rootValue, operationName }: Request) => + subscribe({ + schema, + document, + contextValue: context, + variableValues: variables, + rootValue, + operationName, + })) as Executor; + } + + return (({ document, context, variables, rootValue, operationName }: Request) => + execute({ schema, document, contextValue: context, variableValues: variables, rootValue, - }; - if (operation === 'subscription') { - return subscribe(executionParams); - } - return execute(executionParams); - }) as Executor; + operationName, + })) as Executor; +} diff --git a/packages/delegate/src/index.ts b/packages/delegate/src/index.ts index 030fed028b0..68f0066911f 100644 --- a/packages/delegate/src/index.ts +++ b/packages/delegate/src/index.ts @@ -9,4 +9,4 @@ export * from './resolveExternalValue'; export * from './subschemaConfig'; export * from './transforms'; export * from './types'; -export { Executor, AsyncExecutor, SyncExecutor, ExecutionParams } from '@graphql-tools/utils'; +export { Executor, AsyncExecutor, SyncExecutor, Request } from '@graphql-tools/utils'; diff --git a/packages/delegate/src/transforms/AddArgumentsAsVariables.ts b/packages/delegate/src/transforms/AddArgumentsAsVariables.ts index 398a3131f5e..dfc77be8397 100644 --- a/packages/delegate/src/transforms/AddArgumentsAsVariables.ts +++ b/packages/delegate/src/transforms/AddArgumentsAsVariables.ts @@ -51,7 +51,7 @@ function addVariablesToRootField( variables: Record; } { const document = originalRequest.document; - const variableValues = originalRequest.variables; + const variableValues = originalRequest.variables ?? {}; const operations: Array = document.definitions.filter( def => def.kind === Kind.OPERATION_DEFINITION diff --git a/packages/delegate/src/transforms/FilterToSchema.ts b/packages/delegate/src/transforms/FilterToSchema.ts index 8dd738e37e7..bb1f6767c5b 100644 --- a/packages/delegate/src/transforms/FilterToSchema.ts +++ b/packages/delegate/src/transforms/FilterToSchema.ts @@ -41,7 +41,7 @@ export default class FilterToSchema implements Transform { function filterToSchema( targetSchema: GraphQLSchema, document: DocumentNode, - variables: Record + variables?: Record ): { document: DocumentNode; variables: Record } { const operations: Array = document.definitions.filter( def => def.kind === Kind.OPERATION_DEFINITION @@ -105,13 +105,15 @@ function filterToSchema( }); } - const newVariables = usedVariables.reduce((acc, variableName) => { - const variableValue = variables[variableName]; - if (variableValue !== undefined) { - acc[variableName] = variableValue; - } - return acc; - }, {}); + const newVariables = variables + ? usedVariables.reduce((acc, variableName) => { + const variableValue = variables[variableName]; + if (variableValue !== undefined) { + acc[variableName] = variableValue; + } + return acc; + }, {}) + : {}; return { document: { diff --git a/packages/delegate/src/types.ts b/packages/delegate/src/types.ts index 1e12ddd9592..17c101a03c6 100644 --- a/packages/delegate/src/types.ts +++ b/packages/delegate/src/types.ts @@ -14,7 +14,7 @@ import { import DataLoader from 'dataloader'; -import { ExecutionParams, ExecutionResult, Executor, Request, TypeMap } from '@graphql-tools/utils'; +import { Request, ExecutionResult, Executor, TypeMap } from '@graphql-tools/utils'; import { Subschema } from './Subschema'; import { OBJECT_SUBSCHEMA_SYMBOL, FIELD_SUBSCHEMA_MAP_SYMBOL, UNPATHED_ERRORS_SYMBOL } from './symbols'; @@ -47,12 +47,12 @@ export interface DelegationContext> { targetSchema: GraphQLSchema; operation: OperationTypeNode; fieldName: string; - args: Record; + args?: Record; context?: TContext; info: GraphQLResolveInfo; - rootValue?: Record; returnType: GraphQLOutputType; onLocatedError?: (originalError: GraphQLError) => GraphQLError; + rootValue?: any; transforms: Array>; transformedSchema: GraphQLSchema; skipTypeMerging: boolean; @@ -75,7 +75,7 @@ export interface IDelegateToSchemaOptions, TArgs fieldNodes?: ReadonlyArray; context?: TContext; info: GraphQLResolveInfo; - rootValue?: Record; + rootValue?: any; transforms?: Array>; transformedSchema?: GraphQLSchema; validateRequest?: boolean; @@ -90,9 +90,10 @@ export interface IDelegateRequestOptions, TArgs = export interface ICreateRequestFromInfo { info: GraphQLResolveInfo; + rootValue?: any; operationName?: string; - operation: OperationTypeNode; - fieldName: string; + operation?: OperationTypeNode; + fieldName?: string; selectionSet?: SelectionSetNode; fieldNodes?: ReadonlyArray; } @@ -105,6 +106,7 @@ export interface ICreateRequest { variableDefinitions?: ReadonlyArray; variableValues?: Record; targetOperation: OperationTypeNode; + targetRootValue?: any; targetOperationName?: string; targetFieldName: string; selectionSet?: SelectionSetNode; @@ -135,13 +137,14 @@ export type CreateProxyingResolverFn> = ( ) => GraphQLFieldResolver; export interface BatchingOptions { - extensionsReducer?: (mergedExtensions: Record, executionParams: ExecutionParams) => Record; + extensionsReducer?: (mergedExtensions: Record, request: Request) => Record; dataLoaderOptions?: DataLoader.Options; } export interface SubschemaConfig> { schema: GraphQLSchema; createProxyingResolver?: CreateProxyingResolverFn; + rootValue?: any; transforms?: Array>; merge?: Record>; executor?: Executor; diff --git a/packages/delegate/tests/batchExecution.test.ts b/packages/delegate/tests/batchExecution.test.ts index 59119b8ff88..93c82b8a0a0 100644 --- a/packages/delegate/tests/batchExecution.test.ts +++ b/packages/delegate/tests/batchExecution.test.ts @@ -1,7 +1,7 @@ import { graphql, execute, ExecutionResult } from 'graphql'; import { makeExecutableSchema } from '@graphql-tools/schema'; -import { delegateToSchema, SubschemaConfig, ExecutionParams, SyncExecutor, Executor } from '../src'; +import { delegateToSchema, SubschemaConfig, Request, SyncExecutor, Executor } from '../src'; import { stitchSchemas } from '@graphql-tools/stitch'; import { FilterObjectFields } from '@graphql-tools/wrap'; @@ -27,9 +27,9 @@ describe('batch execution', () => { const innerSubschemaConfig: SubschemaConfig = { schema: innerSchema, batch: true, - executor: ((params: ExecutionParams): ExecutionResult => { + executor: ((request: Request): ExecutionResult => { executions++; - return execute(innerSchema, params.document, undefined, params.context, params.variables) as ExecutionResult; + return execute(innerSchema, request.document, undefined, request.context, request.variables) as ExecutionResult; }) as SyncExecutor } @@ -104,9 +104,9 @@ describe('batch execution', () => { let executions = 0; - const executor = ((params: ExecutionParams): ExecutionResult => { + const executor = ((request: Request): ExecutionResult => { executions++; - return execute(innerSchemaA, params.document, undefined, params.context, params.variables) as ExecutionResult; + return execute(innerSchemaA, request.document, undefined, request.context, request.variables) as ExecutionResult; }) as Executor; const innerSubschemaConfigA: Array = [{ diff --git a/packages/links/src/linkToExecutor.ts b/packages/links/src/linkToExecutor.ts index 1f8e579da6b..685cd37612c 100644 --- a/packages/links/src/linkToExecutor.ts +++ b/packages/links/src/linkToExecutor.ts @@ -2,12 +2,12 @@ import { toPromise } from '@apollo/client/core'; import { ApolloLink, execute } from '@apollo/client/link/core'; import { Observable } from '@apollo/client/utilities'; -import { Executor, ExecutionParams, ExecutionResult, observableToAsyncIterable } from '@graphql-tools/utils'; +import { Executor, Request, ExecutionResult, observableToAsyncIterable } from '@graphql-tools/utils'; export const linkToExecutor = (link: ApolloLink): Executor => - async (params: ExecutionParams) => { - const { document, variables, extensions, context, info, operationName } = params; + async (request: Request) => { + const { document, variables, extensions, context, info, operationName } = request; const observable = execute(link, { query: document, variables, diff --git a/packages/loaders/url/src/index.ts b/packages/loaders/url/src/index.ts index e86c1fb44d2..413cc403743 100644 --- a/packages/loaders/url/src/index.ts +++ b/packages/loaders/url/src/index.ts @@ -11,7 +11,7 @@ import { BaseLoaderOptions, observableToAsyncIterable, isAsyncIterable, - ExecutionParams, + Request, mapAsyncIterator, withCancel, parseGraphQLSDL, @@ -295,7 +295,7 @@ export class UrlLoader implements Loader { variables, operationName, extensions, - }: ExecutionParams) => { + }: Request) => { const controller = new AbortController(); let method = defaultMethod; if (options?.useGETForQueries) { @@ -463,7 +463,7 @@ export class UrlLoader implements Loader { webSocketImpl ); - return async ({ document, variables, operationName }: ExecutionParams) => { + return async ({ document, variables, operationName }: Request) => { return observableToAsyncIterable( subscriptionClient.request({ query: document, diff --git a/packages/stitch/tests/fixtures/schemas.ts b/packages/stitch/tests/fixtures/schemas.ts index bab2fb0b1b5..9364d9747da 100644 --- a/packages/stitch/tests/fixtures/schemas.ts +++ b/packages/stitch/tests/fixtures/schemas.ts @@ -25,7 +25,7 @@ import { } from '@graphql-tools/utils'; import { makeExecutableSchema } from '@graphql-tools/schema'; -import { ExecutionParams, SubschemaConfig } from '@graphql-tools/delegate'; +import { Request, SubschemaConfig } from '@graphql-tools/delegate'; export class CustomError extends GraphQLError { constructor(message: string, extensions: Record) { @@ -682,7 +682,7 @@ export const subscriptionSchema: GraphQLSchema = makeExecutableSchema({ }); function makeExecutorFromSchema(schema: GraphQLSchema) { - return async ({ document, variables, context, info }: ExecutionParams) => { + return async ({ document, variables, context, info }: Request) => { if (info?.operation.operation === 'subscription') { const result = subscribe( schema, diff --git a/packages/utils/src/Interfaces.ts b/packages/utils/src/Interfaces.ts index 23190a3c41a..22cc148dc34 100644 --- a/packages/utils/src/Interfaces.ts +++ b/packages/utils/src/Interfaces.ts @@ -58,6 +58,23 @@ export interface ExecutionResult> extends GraphQLExe extensions?: Record; } +export interface Request< + TArgs extends Record = Record, + TContext = any, + TRootValue = any, + TExtensions = Record +> { + document: DocumentNode; + variables?: TArgs; + extensions?: TExtensions; + operationName?: string; + // If the request will be executed locally, it may contain a rootValue + rootValue?: TRootValue; + // If the request originates within execution of a parent request, it may contain the parent context and info + context?: TContext; + info?: GraphQLResolveInfo; +} + // graphql-js non-exported typings export type TypeMap = Record; @@ -309,13 +326,6 @@ export type IDefaultValueIteratorFn = (type: GraphQLInputType, value: any) => vo export type NextResolverFn = () => Promise; -export interface Request { - document: DocumentNode; - variables: Record; - operationName?: string; - extensions?: Record; -} - export type VisitableSchemaType = | GraphQLSchema | GraphQLObjectType diff --git a/packages/utils/src/executor.ts b/packages/utils/src/executor.ts index ac89baeb322..45fd4e18747 100644 --- a/packages/utils/src/executor.ts +++ b/packages/utils/src/executor.ts @@ -1,24 +1,8 @@ -import { DocumentNode, GraphQLResolveInfo } from 'graphql'; -import { ExecutionResult } from './Interfaces'; +import { ExecutionResult, Request } from './Interfaces'; type MaybePromise = Promise | T; type MaybeAsyncIterableIterator = AsyncIterableIterator | T; -export interface ExecutionParams< - TArgs extends Record = Record, - TContext = any, - TRootValue = any, - TExtensions = Record -> { - document: DocumentNode; - variables?: TArgs; - extensions?: TExtensions; - context?: TContext; - info?: GraphQLResolveInfo; - rootValue?: TRootValue; - operationName?: string; -} - export type AsyncExecutor, TBaseExtensions = Record> = < TReturn = any, TArgs = Record, @@ -26,7 +10,7 @@ export type AsyncExecutor, TBaseExtensions = TRoot = any, TExtensions extends TBaseExtensions = TBaseExtensions >( - params: ExecutionParams + request: Request ) => Promise>>; export type SyncExecutor, TBaseExtensions = Record> = < @@ -36,7 +20,7 @@ export type SyncExecutor, TBaseExtensions = R TRoot = any, TExtensions extends TBaseExtensions = TBaseExtensions >( - params: ExecutionParams + request: Request ) => ExecutionResult; export type Executor, TBaseExtensions = Record> = < @@ -46,5 +30,5 @@ export type Executor, TBaseExtensions = Recor TRoot = any, TExtensions extends TBaseExtensions = TBaseExtensions >( - params: ExecutionParams + request: Request ) => MaybePromise>>; diff --git a/packages/wrap/src/transforms/MapLeafValues.ts b/packages/wrap/src/transforms/MapLeafValues.ts index 82da267e027..a8d7d6bc23d 100644 --- a/packages/wrap/src/transforms/MapLeafValues.ts +++ b/packages/wrap/src/transforms/MapLeafValues.ts @@ -88,7 +88,7 @@ export default class MapLeafValues implements Transform = document.definitions.filter( def => def.kind === Kind.OPERATION_DEFINITION diff --git a/packages/wrap/src/transforms/TransformInputObjectFields.ts b/packages/wrap/src/transforms/TransformInputObjectFields.ts index 0c0bf526c8b..09713065799 100644 --- a/packages/wrap/src/transforms/TransformInputObjectFields.ts +++ b/packages/wrap/src/transforms/TransformInputObjectFields.ts @@ -78,7 +78,7 @@ export default class TransformInputObjectFields implements Transform { delegationContext: DelegationContext, _transformationContext: Record ): Request { - const variableValues = originalRequest.variables; + const variableValues = originalRequest.variables ?? {}; const fragments = Object.create(null); const operations: Array = []; diff --git a/packages/wrap/tests/fixtures/schemas.ts b/packages/wrap/tests/fixtures/schemas.ts index 22edcc4f7f4..172ea0debf9 100644 --- a/packages/wrap/tests/fixtures/schemas.ts +++ b/packages/wrap/tests/fixtures/schemas.ts @@ -22,7 +22,7 @@ import { isAsyncIterable, } from '@graphql-tools/utils'; import { makeExecutableSchema } from '@graphql-tools/schema'; -import { SubschemaConfig, ExecutionParams } from '@graphql-tools/delegate'; +import { SubschemaConfig, Request } from '@graphql-tools/delegate'; export class CustomError extends GraphQLError { constructor(message: string, extensions: Record) { @@ -678,7 +678,7 @@ export const subscriptionSchema: GraphQLSchema = makeExecutableSchema({ }); function makeExecutorFromSchema(schema: GraphQLSchema) { - return async ({ document, variables, context, info }: ExecutionParams) => { + return async ({ document, variables, context, info }: Request) => { if (info?.operation.operation === 'subscription') { const result = await subscribe( schema, diff --git a/packages/wrap/tests/requests.test.ts b/packages/wrap/tests/requests.test.ts index a4f308c2116..3a87fbb520f 100644 --- a/packages/wrap/tests/requests.test.ts +++ b/packages/wrap/tests/requests.test.ts @@ -48,6 +48,7 @@ describe('requests', () => { } } `), + rootValue: undefined, variables: {}, operationName: 'test' }); diff --git a/website/docs/remote-schemas.md b/website/docs/remote-schemas.md index a9fbbad9687..4b5967e8942 100644 --- a/website/docs/remote-schemas.md +++ b/website/docs/remote-schemas.md @@ -27,9 +27,9 @@ You can use an executor with an HTTP Client implementation (like cross-fetch). A We've chosen to split this functionality up to give you the flexibility to choose when to do the introspection step. For example, you might already have the remote schema information, allowing you to skip the `introspectSchema` step entirely. Here's a complete example: ```js -type Executor = (operation: ExecutionParams) => Promise; +type Executor = (request: Request) => Promise; -type ExecutionParams = { +type Request = { document: DocumentNode, variables?: Object, context?: Object, @@ -213,7 +213,6 @@ import { delegateToSchema } from '@graphql-tools/delegate'; export function defaultCreateProxyingResolver({ subschemaConfig, operation, - transforms, transformedSchema, }: ICreateProxyingResolverOptions): GraphQLFieldResolver { return (_parent, _args, context, info) => diff --git a/website/docs/stitch-combining-schemas.md b/website/docs/stitch-combining-schemas.md index 648fb96bfc9..f34cb5168ac 100644 --- a/website/docs/stitch-combining-schemas.md +++ b/website/docs/stitch-combining-schemas.md @@ -86,16 +86,16 @@ In the example above, the extra "subschema" wrapper objects may look verbose at ```js export interface SubschemaConfig { schema: GraphQLSchema; - rootValue?: Record; executor?: Executor; createProxyingResolver?: CreateProxyingResolverFn; + rootValue?: Record; transforms?: Array; merge?: Record; batch?: boolean; batchingOptions?: { extensionsReducer?: ( mergedExtensions: Record, - executionParams: ExecutionParams + request: Request ) => Record, dataLoaderOptions?: DataLoader.Options, }; diff --git a/website/docs/stitch-type-merging.md b/website/docs/stitch-type-merging.md index 9602a10f478..f6a08c97428 100644 --- a/website/docs/stitch-type-merging.md +++ b/website/docs/stitch-type-merging.md @@ -253,7 +253,7 @@ Query batching will collect all queries made during an execution cycle and combi ```ts batchingOptions?: { dataLoaderOptions?: DataLoader.Options; - extensionsReducer?: (mergedExtensions: Record, executionParams: ExecutionParams) => Record; + extensionsReducer?: (mergedExtensions: Record, request: Request) => Record; } ``` From c5342de7250589ca24dccbb7d54ec8a50dbc900e Mon Sep 17 00:00:00 2001 From: Laurin Quast Date: Mon, 12 Jul 2021 18:49:02 +0200 Subject: [PATCH 47/66] fix: Loader.canLoad should only handle file paths and glob negation (#3172) * add failing test * fix: glob negation * uri loader should use canLoad within load --- .changeset/pretty-laws-rest.md | 8 +++ packages/load/src/load-typedefs/load-file.ts | 26 +++---- .../documents/documents-from-glob.spec.ts | 2 +- .../schema/schema-from-typedefs.spec.ts | 12 ++++ .../test-files/schema-dir/invalid.graphql | 1 + packages/loaders/code-file/src/index.ts | 12 +--- packages/loaders/git/src/index.ts | 4 +- packages/loaders/graphql-file/src/index.ts | 70 +++++++------------ packages/loaders/url/src/index.ts | 18 ++++- 9 files changed, 79 insertions(+), 74 deletions(-) create mode 100644 .changeset/pretty-laws-rest.md create mode 100644 packages/load/tests/loaders/schema/test-files/schema-dir/invalid.graphql diff --git a/.changeset/pretty-laws-rest.md b/.changeset/pretty-laws-rest.md new file mode 100644 index 00000000000..ff12beb4131 --- /dev/null +++ b/.changeset/pretty-laws-rest.md @@ -0,0 +1,8 @@ +--- +'@graphql-tools/code-file-loader': major +'@graphql-tools/git-loader': major +'@graphql-tools/graphql-file-loader': major +'@graphql-tools/load': patch +--- + +Loader.canLoad and Loader.canLoadSync can only handle file paths not glob patterns diff --git a/packages/load/src/load-typedefs/load-file.ts b/packages/load/src/load-typedefs/load-file.ts index 237adce9ac0..1b09b1703c0 100644 --- a/packages/load/src/load-typedefs/load-file.ts +++ b/packages/load/src/load-typedefs/load-file.ts @@ -11,15 +11,11 @@ export async function loadFile(pointer: string, options: LoadTypedefsOptions): P for await (const loader of options.loaders) { try { - const canLoad = await loader.canLoad(pointer, options); - - if (canLoad) { - const loadedValue = await loader.load(pointer, options); - if (!isSome(loadedValue) || loadedValue.length === 0) { - continue; - } - return loadedValue; + const loadedValue = await loader.load(pointer, options); + if (!isSome(loadedValue) || loadedValue.length === 0) { + continue; } + return loadedValue; } catch (error) { if (env['DEBUG']) { console.error(`Failed to find any GraphQL type definitions in: ${pointer} - ${error.message}`); @@ -40,16 +36,12 @@ export function loadFileSync(pointer: string, options: LoadTypedefsOptions): May for (const loader of options.loaders) { try { - const canLoad = loader.canLoadSync && loader.loadSync && loader.canLoadSync(pointer, options); - - if (canLoad) { - // We check for the existence so it is okay to force non null - const loadedValue = loader.loadSync!(pointer, options); - if (!isSome(loadedValue) || loadedValue.length === 0) { - continue; - } - return loadedValue; + // We check for the existence so it is okay to force non null + const loadedValue = loader.loadSync!(pointer, options); + if (!isSome(loadedValue) || loadedValue.length === 0) { + continue; } + return loadedValue; } catch (error) { if (env['DEBUG']) { console.error(`Failed to find any GraphQL type definitions in: ${pointer} - ${error.message}`); diff --git a/packages/load/tests/loaders/documents/documents-from-glob.spec.ts b/packages/load/tests/loaders/documents/documents-from-glob.spec.ts index 27ddbe34fab..db585b777d7 100644 --- a/packages/load/tests/loaders/documents/documents-from-glob.spec.ts +++ b/packages/load/tests/loaders/documents/documents-from-glob.spec.ts @@ -119,7 +119,7 @@ describe('documentsFromGlob', () => { test(`Should ignore files that is added to ignore glob (using negative glob)`, async () => { const glob = join(__dirname, './test-files/', '*.graphql'); - const ignoreGlob = `!(${join(__dirname, './test-files/', '*.query.graphql')})`; + const ignoreGlob = `!${join(__dirname, './test-files/', '*.query.graphql')}`; const result = await load([glob, ignoreGlob], { loaders: [new GraphQLFileLoader()] }); diff --git a/packages/load/tests/loaders/schema/schema-from-typedefs.spec.ts b/packages/load/tests/loaders/schema/schema-from-typedefs.spec.ts index 0199d4178a3..04f989a8084 100644 --- a/packages/load/tests/loaders/schema/schema-from-typedefs.spec.ts +++ b/packages/load/tests/loaders/schema/schema-from-typedefs.spec.ts @@ -161,5 +161,17 @@ describe('schema from typedefs', () => { assertNonMaybe(schemaWithoutSources.extensions) expect(schemaWithoutSources.extensions['sources']).not.toBeDefined(); }); + + it('should be able to exclude documents via negative glob', async () => { + const result = await load([ + './tests/loaders/schema/test-files/schema-dir/user.graphql', + './tests/loaders/schema/test-files/schema-dir/invalid.graphql', + '!./tests/loaders/schema/test-files/schema-dir/i*.graphql', + ], { + loaders: [new GraphQLFileLoader()], + includeSources: true, + }); + expect(result.getTypeMap()["User"]).toBeDefined() + }) }) }); diff --git a/packages/load/tests/loaders/schema/test-files/schema-dir/invalid.graphql b/packages/load/tests/loaders/schema/test-files/schema-dir/invalid.graphql new file mode 100644 index 00000000000..cbcdcddaa7e --- /dev/null +++ b/packages/load/tests/loaders/schema/test-files/schema-dir/invalid.graphql @@ -0,0 +1 @@ +type Query { diff --git a/packages/loaders/code-file/src/index.ts b/packages/loaders/code-file/src/index.ts index 1ae63b12828..c4bdd063126 100644 --- a/packages/loaders/code-file/src/index.ts +++ b/packages/loaders/code-file/src/index.ts @@ -76,10 +76,6 @@ export class CodeFileLoader implements Loader { async canLoad(pointer: string, options: CodeFileLoaderOptions): Promise { options = this.getMergedOptions(options); - if (isGlob(pointer)) { - // FIXME: parse to find and check the file extensions? - return true; - } if (isValidPath(pointer)) { if (FILE_EXTENSIONS.find(extension => pointer.endsWith(extension))) { @@ -98,10 +94,6 @@ export class CodeFileLoader implements Loader { canLoadSync(pointer: string, options: CodeFileLoaderOptions): boolean { options = this.getMergedOptions(options); - if (isGlob(pointer)) { - // FIXME: parse to find and check the file extensions? - return true; - } if (isValidPath(pointer)) { if (FILE_EXTENSIONS.find(extension => pointer.endsWith(extension))) { @@ -116,13 +108,13 @@ export class CodeFileLoader implements Loader { async resolveGlobs(glob: string, options: CodeFileLoaderOptions) { options = this.getMergedOptions(options); const ignores = asArray(options.ignore || []); - return globby([glob, ...ignores.map(v => `!(${v})`).map(v => unixify(v))], createGlobbyOptions(options)); + return globby([glob, ...ignores.map(v => `!${v}`).map(v => unixify(v))], createGlobbyOptions(options)); } resolveGlobsSync(glob: string, options: CodeFileLoaderOptions) { options = this.getMergedOptions(options); const ignores = asArray(options.ignore || []); - return globby.sync([glob, ...ignores.map(v => `!(${v})`).map(v => unixify(v))], createGlobbyOptions(options)); + return globby.sync([glob, ...ignores.map(v => `!${v}`).map(v => unixify(v))], createGlobbyOptions(options)); } async load(pointer: string, options: CodeFileLoaderOptions): Promise { diff --git a/packages/loaders/git/src/index.ts b/packages/loaders/git/src/index.ts index acc6f9ddba4..b105341160b 100644 --- a/packages/loaders/git/src/index.ts +++ b/packages/loaders/git/src/index.ts @@ -75,7 +75,7 @@ export class GitLoader implements Loader { if (!refsForPaths.has(ref)) { refsForPaths.set(ref, []); } - refsForPaths.get(ref).push(`!(${unixify(path)})`); + refsForPaths.get(ref).push(`!${unixify(path)}`); } const resolved: string[] = []; @@ -101,7 +101,7 @@ export class GitLoader implements Loader { if (!refsForPaths.has(ref)) { refsForPaths.set(ref, []); } - refsForPaths.get(ref).push(`!(${unixify(path)})`); + refsForPaths.get(ref).push(`!${unixify(path)}`); } const resolved: string[] = []; diff --git a/packages/loaders/graphql-file/src/index.ts b/packages/loaders/graphql-file/src/index.ts index 79dd1bdc391..e851a1b1c0c 100644 --- a/packages/loaders/graphql-file/src/index.ts +++ b/packages/loaders/graphql-file/src/index.ts @@ -6,7 +6,6 @@ import { readFileSync, promises as fsPromises, existsSync } from 'fs'; import { cwd as processCwd } from 'process'; import { processImport } from '@graphql-tools/import'; import globby from 'globby'; -import isGlob from 'is-glob'; import unixify from 'unixify'; const { readFile, access } = fsPromises; @@ -61,11 +60,6 @@ export class GraphQLFileLoader implements Loader { } async canLoad(pointer: string, options: GraphQLFileLoaderOptions): Promise { - if (isGlob(pointer)) { - // FIXME: parse to find and check the file extensions? - return true; - } - if (isValidPath(pointer)) { if (FILE_EXTENSIONS.find(extension => pointer.endsWith(extension))) { const normalizedFilePath = isAbsolute(pointer) ? pointer : resolve(options.cwd || processCwd(), pointer); @@ -82,66 +76,56 @@ export class GraphQLFileLoader implements Loader { } canLoadSync(pointer: string, options: GraphQLFileLoaderOptions): boolean { - if (isGlob(pointer)) { - // FIXME: parse to find and check the file extensions? - return true; - } - if (isValidPath(pointer)) { if (FILE_EXTENSIONS.find(extension => pointer.endsWith(extension))) { const normalizedFilePath = isAbsolute(pointer) ? pointer : resolve(options.cwd || processCwd(), pointer); return existsSync(normalizedFilePath); } } - return false; } async resolveGlobs(glob: string, options: GraphQLFileLoaderOptions) { const ignores = asArray(options.ignore || []); - return globby([glob, ...ignores.map(v => `!(${v})`).map(v => unixify(v))], createGlobbyOptions(options)); + const target = [glob, ...ignores.map(v => `!${v}`).map(v => unixify(v))]; + const result = await globby(target, createGlobbyOptions(options)); + return result; } resolveGlobsSync(glob: string, options: GraphQLFileLoaderOptions) { const ignores = asArray(options.ignore || []); - return globby.sync([glob, ...ignores.map(v => `!(${v})`).map(v => unixify(v))], createGlobbyOptions(options)); + const target = [glob, ...ignores.map(v => `!${v}`).map(v => unixify(v))]; + const result = globby.sync(target, createGlobbyOptions(options)); + return result; } async load(pointer: string, options: GraphQLFileLoaderOptions): Promise { - if (isGlob(pointer)) { - const resolvedPaths = await this.resolveGlobs(pointer, options); - const finalResult: Source[] = []; - await Promise.all( - resolvedPaths.map(async path => { - if (await this.canLoad(path, options)) { - const result = await this.load(path, options); - result?.forEach(result => finalResult.push(result)); - } - }) - ); - return finalResult; - } - const normalizedFilePath = isAbsolute(pointer) ? pointer : resolve(options.cwd || processCwd(), pointer); - const rawSDL: string = await readFile(normalizedFilePath, { encoding: 'utf8' }); - - return [this.handleFileContent(rawSDL, normalizedFilePath, options)]; + const resolvedPaths = await this.resolveGlobs(pointer, options); + const finalResult: Source[] = []; + + await Promise.all( + resolvedPaths.map(async path => { + if (await this.canLoad(path, options)) { + const normalizedFilePath = isAbsolute(path) ? path : resolve(options.cwd || processCwd(), path); + const rawSDL: string = await readFile(normalizedFilePath, { encoding: 'utf8' }); + finalResult.push(this.handleFileContent(rawSDL, normalizedFilePath, options)); + } + }) + ); + return finalResult; } loadSync(pointer: string, options: GraphQLFileLoaderOptions): Source[] { - if (isGlob(pointer)) { - const resolvedPaths = this.resolveGlobsSync(pointer, options); - const finalResult: Source[] = []; - for (const path of resolvedPaths) { - if (this.canLoadSync(path, options)) { - const result = this.loadSync(path, options); - result?.forEach(result => finalResult.push(result)); - } + const resolvedPaths = this.resolveGlobsSync(pointer, options); + const finalResult: Source[] = []; + for (const path of resolvedPaths) { + if (this.canLoadSync(path, options)) { + const normalizedFilePath = isAbsolute(path) ? path : resolve(options.cwd || processCwd(), path); + const rawSDL = readFileSync(normalizedFilePath, { encoding: 'utf8' }); + finalResult.push(this.handleFileContent(rawSDL, normalizedFilePath, options)); } - return finalResult; } - const normalizedFilePath = isAbsolute(pointer) ? pointer : resolve(options.cwd || processCwd(), pointer); - const rawSDL = readFileSync(normalizedFilePath, { encoding: 'utf8' }); - return [this.handleFileContent(rawSDL, normalizedFilePath, options)]; + return finalResult; } handleFileContent(rawSDL: string, pointer: string, options: GraphQLFileLoaderOptions) { diff --git a/packages/loaders/url/src/index.ts b/packages/loaders/url/src/index.ts index 413cc403743..2af5fe7f9cc 100644 --- a/packages/loaders/url/src/index.ts +++ b/packages/loaders/url/src/index.ts @@ -141,6 +141,15 @@ export interface LoadFromUrlOptions extends BaseLoaderOptions, Partial { + if (isWebUri(uri)) { + return true; + } + // we just replace the url part, the remaining validation is the same + const wsUri = uri.replace('wss://', 'http://').replace('ws://', 'http://'); + return !!isWebUri(wsUri); +}; + /** * This loader loads a schema from a URL. The loaded schema is a fully-executable, * remote schema since it's created using [@graphql-tools/wrap](/docs/remote-schemas). @@ -163,7 +172,7 @@ export class UrlLoader implements Loader { } canLoadSync(pointer: string, _options: LoadFromUrlOptions): boolean { - return !!isWebUri(pointer); + return isCompatibleUri(pointer); } createFormDataFromVariables({ @@ -642,6 +651,9 @@ export class UrlLoader implements Loader { } async load(pointer: string, options: LoadFromUrlOptions): Promise { + if (!(await this.canLoad(pointer, options))) { + return []; + } let source: Source = { location: pointer, }; @@ -680,6 +692,10 @@ export class UrlLoader implements Loader { } loadSync(pointer: string, options: LoadFromUrlOptions): Source[] { + if (!this.canLoad(pointer, options)) { + return []; + } + let source: Source = { location: pointer, }; From 74581cf399472428a4d0f15c0892d6377db29d47 Mon Sep 17 00:00:00 2001 From: Yaacov Rydzinski Date: Mon, 12 Jul 2021 20:58:05 +0300 Subject: [PATCH 48/66] feat: support Gatsby-style directives in extensions (#3185) * feat: support Gatsby-style directives in extensions BREAKING CHANGE: getDirectives now always return an array of DirectiveAnnotation objects New function getDirective returns an array of args records for each use of the directive. Note: this is true even when the directive is non-repeatable. This is because one use of this function is to throw an error if more than one directive annotation is used for a non repeatable directive! * add changeset --- .changeset/quick-hotels-beam.md | 16 ++ .../computedDirectiveTransformer.ts | 6 +- .../stitch/tests/mergeDefinitions.test.ts | 38 +-- .../tests/typeMergingWithExtensions.test.ts | 17 +- .../src/stitchingDirectivesTransformer.ts | 148 +++++++---- .../src/stitchingDirectivesValidator.ts | 40 +-- packages/utils/src/get-directives.ts | 117 ++++++++- packages/utils/tests/get-directives.spec.ts | 62 +++-- packages/utils/tests/schemaTransforms.test.ts | 125 ++++----- .../RemoveObjectFieldsWithDirective.ts | 11 +- website/docs/schema-directives.md | 245 +++++++++--------- 11 files changed, 482 insertions(+), 343 deletions(-) create mode 100644 .changeset/quick-hotels-beam.md diff --git a/.changeset/quick-hotels-beam.md b/.changeset/quick-hotels-beam.md new file mode 100644 index 00000000000..f37aa1f8814 --- /dev/null +++ b/.changeset/quick-hotels-beam.md @@ -0,0 +1,16 @@ +--- +'@graphql-tools/stitch': major +'@graphql-tools/stitching-directives': major +'@graphql-tools/utils': major +'@graphql-tools/wrap': major +--- + +fix(getDirectives): preserve order around repeatable directives + +BREAKING CHANGE: getDirectives now always return an array of individual DirectiveAnnotation objects consisting of `name` and `args` properties. + +New useful function `getDirective` returns an array of objects representing any args for each use of a single directive (returning the empty object `{}` when a directive is used without arguments). + +Note: The `getDirective` function returns an array even when the specified directive is non-repeatable. This is because one use of this function is to throw an error if more than one directive annotation is used for a non repeatable directive! + +When specifying directives in extensions, one can use either the old or new format. diff --git a/packages/stitch/src/subschemaConfigTransforms/computedDirectiveTransformer.ts b/packages/stitch/src/subschemaConfigTransforms/computedDirectiveTransformer.ts index cb84a17ddf9..d39e097cc5a 100644 --- a/packages/stitch/src/subschemaConfigTransforms/computedDirectiveTransformer.ts +++ b/packages/stitch/src/subschemaConfigTransforms/computedDirectiveTransformer.ts @@ -1,4 +1,4 @@ -import { getDirectives, MapperKind, mapSchema } from '@graphql-tools/utils'; +import { getDirective, MapperKind, mapSchema } from '@graphql-tools/utils'; import { cloneSubschemaConfig, SubschemaConfig } from '@graphql-tools/delegate'; import { SubschemaConfigTransform } from '../types'; @@ -15,13 +15,13 @@ export function computedDirectiveTransformer(computedDirectiveName: string): Sub return undefined; } - const computed = getDirectives(schema, fieldConfig)[computedDirectiveName]; + const computed = getDirective(schema, fieldConfig, computedDirectiveName)?.[0]; if (computed == null) { return undefined; } - const selectionSet = computed.fields != null ? `{ ${computed.fields} }` : computed.selectionSet; + const selectionSet = computed['fields'] != null ? `{ ${computed['fields']} }` : computed['selectionSet']; if (selectionSet == null) { return undefined; diff --git a/packages/stitch/tests/mergeDefinitions.test.ts b/packages/stitch/tests/mergeDefinitions.test.ts index 17af8555698..655d91916b5 100644 --- a/packages/stitch/tests/mergeDefinitions.test.ts +++ b/packages/stitch/tests/mergeDefinitions.test.ts @@ -1,6 +1,6 @@ import { makeExecutableSchema } from '@graphql-tools/schema'; import { stitchSchemas } from '@graphql-tools/stitch'; -import { getDirectives } from '@graphql-tools/utils'; +import { getDirective } from '@graphql-tools/utils'; import { stitchingDirectives } from '@graphql-tools/stitching-directives'; import { GraphQLObjectType, @@ -282,22 +282,22 @@ describe('merge canonical types', () => { const scalarType = gatewaySchema.getType('ProductScalar'); assertGraphQLScalerType(scalarType) - expect(getDirectives(firstSchema, queryType.toConfig())['mydir'].value).toEqual('first'); - expect(getDirectives(firstSchema, objectType.toConfig())['mydir'].value).toEqual('first'); - expect(getDirectives(firstSchema, interfaceType.toConfig())['mydir'].value).toEqual('first'); - expect(getDirectives(firstSchema, inputType.toConfig())['mydir'].value).toEqual('first'); - expect(getDirectives(firstSchema, enumType.toConfig())['mydir'].value).toEqual('first'); - expect(getDirectives(firstSchema, unionType.toConfig())['mydir'].value).toEqual('first'); - expect(getDirectives(firstSchema, scalarType.toConfig())['mydir'].value).toEqual('first'); - - expect(getDirectives(firstSchema, queryType.getFields()['field1'])['mydir'].value).toEqual('first'); - expect(getDirectives(firstSchema, queryType.getFields()['field2'])['mydir'].value).toEqual('second'); - expect(getDirectives(firstSchema, objectType.getFields()['id'])['mydir'].value).toEqual('first'); - expect(getDirectives(firstSchema, objectType.getFields()['url'])['mydir'].value).toEqual('second'); - expect(getDirectives(firstSchema, interfaceType.getFields()['id'])['mydir'].value).toEqual('first'); - expect(getDirectives(firstSchema, interfaceType.getFields()['url'])['mydir'].value).toEqual('second'); - expect(getDirectives(firstSchema, inputType.getFields()['id'])['mydir'].value).toEqual('first'); - expect(getDirectives(firstSchema, inputType.getFields()['url'])['mydir'].value).toEqual('second'); + expect(getDirective(firstSchema, queryType.toConfig(), 'mydir')?.[0]['value']).toEqual('first'); + expect(getDirective(firstSchema, objectType.toConfig(), 'mydir')?.[0]['value']).toEqual('first'); + expect(getDirective(firstSchema, interfaceType.toConfig(), 'mydir')?.[0]['value']).toEqual('first'); + expect(getDirective(firstSchema, inputType.toConfig(), 'mydir')?.[0]['value']).toEqual('first'); + expect(getDirective(firstSchema, enumType.toConfig(), 'mydir')?.[0]['value']).toEqual('first'); + expect(getDirective(firstSchema, unionType.toConfig(), 'mydir')?.[0]['value']).toEqual('first'); + expect(getDirective(firstSchema, scalarType.toConfig(), 'mydir')?.[0]['value']).toEqual('first'); + + expect(getDirective(firstSchema, queryType.getFields()['field1'], 'mydir')?.[0]['value']).toEqual('first'); + expect(getDirective(firstSchema, queryType.getFields()['field2'], 'mydir')?.[0]['value']).toEqual('second'); + expect(getDirective(firstSchema, objectType.getFields()['id'], 'mydir')?.[0]['value']).toEqual('first'); + expect(getDirective(firstSchema, objectType.getFields()['url'], 'mydir')?.[0]['value']).toEqual('second'); + expect(getDirective(firstSchema, interfaceType.getFields()['id'], 'mydir')?.[0]['value']).toEqual('first'); + expect(getDirective(firstSchema, interfaceType.getFields()['url'], 'mydir')?.[0]['value']).toEqual('second'); + expect(getDirective(firstSchema, inputType.getFields()['id'], 'mydir')?.[0]['value']).toEqual('first'); + expect(getDirective(firstSchema, inputType.getFields()['url'], 'mydir')?.[0]['value']).toEqual('second'); expect(enumType.toConfig().astNode?.values?.map(v => v.description?.value)).toEqual(['first', 'first', 'second']); expect(enumType.toConfig().values['YES'].astNode?.description?.value).toEqual('first'); @@ -309,8 +309,8 @@ describe('merge canonical types', () => { const objectType = gatewaySchema.getType('Product') as GraphQLObjectType; expect(objectType.getFields()['id'].deprecationReason).toEqual('first'); expect(objectType.getFields()['url'].deprecationReason).toEqual('second'); - expect(getDirectives(firstSchema, objectType.getFields()['id'])['deprecated'].reason).toEqual('first'); - expect(getDirectives(firstSchema, objectType.getFields()['url'])['deprecated'].reason).toEqual('second'); + expect(getDirective(firstSchema, objectType.getFields()['id'], 'deprecated')?.[0]['reason']).toEqual('first'); + expect(getDirective(firstSchema, objectType.getFields()['url'], 'deprecated')?.[0]['reason']).toEqual('second'); }); it('promotes canonical root field definitions', async () => { diff --git a/packages/stitch/tests/typeMergingWithExtensions.test.ts b/packages/stitch/tests/typeMergingWithExtensions.test.ts index a84c33d130d..d11153cf6e6 100644 --- a/packages/stitch/tests/typeMergingWithExtensions.test.ts +++ b/packages/stitch/tests/typeMergingWithExtensions.test.ts @@ -52,9 +52,9 @@ describe('merging using type merging', () => { }, resolve: (_root, { keys }) => keys.map((key: Record) => users.find(u => u.id === key['id'])), extensions: { - directives: { - merge: {}, - }, + directives: [{ + name: 'merge', + }], }, } }), @@ -68,12 +68,13 @@ describe('merging using type merging', () => { username: { type: GraphQLString } }), extensions: { - directives: { - key: { + directives: [{ + name: 'key', + args: { selectionSet: '{ id }', - } - } - } + }, + }], + }, }); const accountsSchema = stitchingDirectivesValidator(new GraphQLSchema({ diff --git a/packages/stitching-directives/src/stitchingDirectivesTransformer.ts b/packages/stitching-directives/src/stitchingDirectivesTransformer.ts index 87094987316..c0cef3553ae 100644 --- a/packages/stitching-directives/src/stitchingDirectivesTransformer.ts +++ b/packages/stitching-directives/src/stitchingDirectivesTransformer.ts @@ -17,7 +17,7 @@ import { import { cloneSubschemaConfig, SubschemaConfig, MergedTypeConfig, MergedFieldConfig } from '@graphql-tools/delegate'; import { - getDirectives, + getDirective, getImplementingTypes, MapperKind, mapSchema, @@ -73,45 +73,48 @@ export function stitchingDirectivesTransformer( mapSchema(schema, { [MapperKind.OBJECT_TYPE]: type => { - const directives = getDirectives(schema, type, pathToDirectivesInExtensions); - - if (keyDirectiveName != null && directives[keyDirectiveName] != null) { - const keyDirective = directives[keyDirectiveName]; - const selectionSet = parseSelectionSet(keyDirective.selectionSet, { noLocation: true }); + const keyDirective = getDirective(schema, type, keyDirectiveName, pathToDirectivesInExtensions)?.[0]; + if (keyDirective != null) { + const selectionSet = parseSelectionSet(keyDirective['selectionSet'], { noLocation: true }); selectionSetsByType[type.name] = selectionSet; } - if (canonicalDirectiveName != null && directives[canonicalDirectiveName]) { + const canonicalDirective = getDirective( + schema, + type, + canonicalDirectiveName, + pathToDirectivesInExtensions + )?.[0]; + if (canonicalDirective != null) { setCanonicalDefinition(type.name); } - return undefined; }, [MapperKind.OBJECT_FIELD]: (fieldConfig, fieldName, typeName) => { - const directives = getDirectives(schema, fieldConfig, pathToDirectivesInExtensions); - - if (computedDirectiveName != null && directives[computedDirectiveName] != null) { - const computedDirective = directives[computedDirectiveName]; - const selectionSet = parseSelectionSet(computedDirective.selectionSet, { noLocation: true }); + const computedDirective = getDirective( + schema, + fieldConfig, + computedDirectiveName, + pathToDirectivesInExtensions + )?.[0]; + if (computedDirective != null) { + const selectionSet = parseSelectionSet(computedDirective['selectionSet'], { noLocation: true }); if (!computedFieldSelectionSets[typeName]) { computedFieldSelectionSets[typeName] = Object.create(null); } computedFieldSelectionSets[typeName][fieldName] = selectionSet; } - if ( - mergeDirectiveName != null && - directives[mergeDirectiveName] != null && - directives[mergeDirectiveName].keyField - ) { - const mergeDirectiveKeyField = directives[mergeDirectiveName].keyField; + const mergeDirective = getDirective(schema, fieldConfig, mergeDirectiveName, pathToDirectivesInExtensions)?.[0]; + if (mergeDirective?.['keyField'] != null) { + const mergeDirectiveKeyField = mergeDirective['keyField']; const selectionSet = parseSelectionSet(`{ ${mergeDirectiveKeyField}}`, { noLocation: true }); - const typeNames: Array = directives[mergeDirectiveName].types; + const typeNames: Array = mergeDirective['types']; const returnType = getNamedType(fieldConfig.type); - forEachConcreteType(schema, returnType, directives[mergeDirectiveName]?.types, typeName => { + forEachConcreteType(schema, returnType, typeNames, typeName => { if (typeNames == null || typeNames.includes(typeName)) { const existingSelectionSet = selectionSetsByType[typeName]; selectionSetsByType[typeName] = existingSelectionSet @@ -121,70 +124,111 @@ export function stitchingDirectivesTransformer( }); } - if (canonicalDirectiveName != null && directives[canonicalDirectiveName] != null) { + const canonicalDirective = getDirective( + schema, + fieldConfig, + canonicalDirectiveName, + pathToDirectivesInExtensions + )?.[0]; + if (canonicalDirective != null) { setCanonicalDefinition(typeName, fieldName); } return undefined; }, [MapperKind.INTERFACE_TYPE]: type => { - const directives = getDirectives(schema, type, pathToDirectivesInExtensions); - - if (canonicalDirectiveName != null && directives[canonicalDirectiveName] != null) { + const canonicalDirective = getDirective( + schema, + type, + canonicalDirectiveName, + pathToDirectivesInExtensions + )?.[0]; + + if (canonicalDirective) { setCanonicalDefinition(type.name); } return undefined; }, [MapperKind.INTERFACE_FIELD]: (fieldConfig, fieldName, typeName) => { - const directives = getDirectives(schema, fieldConfig, pathToDirectivesInExtensions); - - if (canonicalDirectiveName != null && directives[canonicalDirectiveName]) { + const canonicalDirective = getDirective( + schema, + fieldConfig, + canonicalDirectiveName, + pathToDirectivesInExtensions + )?.[0]; + + if (canonicalDirective) { setCanonicalDefinition(typeName, fieldName); } return undefined; }, [MapperKind.INPUT_OBJECT_TYPE]: type => { - const directives = getDirectives(schema, type, pathToDirectivesInExtensions); - - if (canonicalDirectiveName != null && directives[canonicalDirectiveName] != null) { + const canonicalDirective = getDirective( + schema, + type, + canonicalDirectiveName, + pathToDirectivesInExtensions + )?.[0]; + + if (canonicalDirective) { setCanonicalDefinition(type.name); } return undefined; }, [MapperKind.INPUT_OBJECT_FIELD]: (inputFieldConfig, fieldName, typeName) => { - const directives = getDirectives(schema, inputFieldConfig, pathToDirectivesInExtensions); - - if (canonicalDirectiveName != null && directives[canonicalDirectiveName] != null) { + const canonicalDirective = getDirective( + schema, + inputFieldConfig, + canonicalDirectiveName, + pathToDirectivesInExtensions + )?.[0]; + + if (canonicalDirective != null) { setCanonicalDefinition(typeName, fieldName); } return undefined; }, [MapperKind.UNION_TYPE]: type => { - const directives = getDirectives(schema, type, pathToDirectivesInExtensions); - - if (canonicalDirectiveName != null && directives[canonicalDirectiveName] != null) { + const canonicalDirective = getDirective( + schema, + type, + canonicalDirectiveName, + pathToDirectivesInExtensions + )?.[0]; + + if (canonicalDirective != null) { setCanonicalDefinition(type.name); } return undefined; }, [MapperKind.ENUM_TYPE]: type => { - const directives = getDirectives(schema, type, pathToDirectivesInExtensions); - - if (canonicalDirectiveName != null && directives[canonicalDirectiveName] != null) { + const canonicalDirective = getDirective( + schema, + type, + canonicalDirectiveName, + pathToDirectivesInExtensions + )?.[0]; + + if (canonicalDirective != null) { setCanonicalDefinition(type.name); } return undefined; }, [MapperKind.SCALAR_TYPE]: type => { - const directives = getDirectives(schema, type, pathToDirectivesInExtensions); - - if (canonicalDirectiveName != null && directives[canonicalDirectiveName] != null) { + const canonicalDirective = getDirective( + schema, + type, + canonicalDirectiveName, + pathToDirectivesInExtensions + )?.[0]; + + if (canonicalDirective != null) { setCanonicalDefinition(type.name); } @@ -248,23 +292,21 @@ export function stitchingDirectivesTransformer( mapSchema(schema, { [MapperKind.OBJECT_FIELD]: (fieldConfig, fieldName) => { - const directives = getDirectives(schema, fieldConfig, pathToDirectivesInExtensions); - - if (mergeDirectiveName != null && directives[mergeDirectiveName] != null) { - const directiveArgumentMap = directives[mergeDirectiveName]; + const mergeDirective = getDirective(schema, fieldConfig, mergeDirectiveName, pathToDirectivesInExtensions)?.[0]; + if (mergeDirective != null) { const returnType = getNullableType(fieldConfig.type); const returnsList = isListType(returnType); const namedType = getNamedType(returnType); - let mergeArgsExpr: string = directiveArgumentMap.argsExpr; + let mergeArgsExpr: string = mergeDirective['argsExpr']; if (mergeArgsExpr == null) { - const key: Array = directiveArgumentMap.key; - const keyField: string = directiveArgumentMap.keyField; + const key: Array = mergeDirective['key']; + const keyField: string = mergeDirective['keyField']; const keyExpr = key != null ? buildKeyExpr(key) : keyField != null ? `$key.${keyField}` : '$key'; - const keyArg: string = directiveArgumentMap.keyArg; + const keyArg: string = mergeDirective['keyArg']; const argNames = keyArg == null ? [Object.keys(fieldConfig.args ?? {})[0]] : keyArg.split('.'); const lastArgName = argNames.pop(); @@ -275,7 +317,7 @@ export function stitchingDirectivesTransformer( } } - const typeNames: Array = directiveArgumentMap.types; + const typeNames: Array = mergeDirective['types']; forEachConcreteTypeName(namedType, schema, typeNames, typeName => { const parsedMergeArgsExpr = parseMergeArgsExpr( @@ -285,7 +327,7 @@ export function stitchingDirectivesTransformer( : mergeSelectionSets(...allSelectionSetsByType[typeName]) ); - const additionalArgs = directiveArgumentMap.additionalArgs; + const additionalArgs = mergeDirective['additionalArgs']; if (additionalArgs != null) { parsedMergeArgsExpr.args = mergeDeep( parsedMergeArgsExpr.args, diff --git a/packages/stitching-directives/src/stitchingDirectivesValidator.ts b/packages/stitching-directives/src/stitchingDirectivesValidator.ts index 92ab3ddd9b5..daa3ea482cf 100644 --- a/packages/stitching-directives/src/stitchingDirectivesValidator.ts +++ b/packages/stitching-directives/src/stitchingDirectivesValidator.ts @@ -11,7 +11,7 @@ import { } from 'graphql'; import { - getDirectives, + getDirective, getImplementingTypes, isSome, MapperKind, @@ -39,26 +39,28 @@ export function stitchingDirectivesValidator( mapSchema(schema, { [MapperKind.OBJECT_TYPE]: type => { - const directives = getDirectives(schema, type, pathToDirectivesInExtensions); + const keyDirective = getDirective(schema, type, keyDirectiveName, pathToDirectivesInExtensions)?.[0]; - if (keyDirectiveName != null && directives[keyDirectiveName]) { - const directiveArgumentMap = directives[keyDirectiveName]; - parseSelectionSet(directiveArgumentMap.selectionSet); + if (keyDirective != null) { + parseSelectionSet(keyDirective['selectionSet']); } return undefined; }, [MapperKind.OBJECT_FIELD]: (fieldConfig, _fieldName, typeName) => { - const directives = getDirectives(schema, fieldConfig, pathToDirectivesInExtensions); - - if (computedDirectiveName != null && directives[computedDirectiveName]) { - const directiveArgumentMap = directives[computedDirectiveName]; - parseSelectionSet(directiveArgumentMap.selectionSet); + const computedDirective = getDirective( + schema, + fieldConfig, + computedDirectiveName, + pathToDirectivesInExtensions + )?.[0]; + + if (computedDirective != null) { + parseSelectionSet(computedDirective['selectionSet']); } - if (mergeDirectiveName != null && directives[mergeDirectiveName]) { - const directiveArgumentMap = directives[mergeDirectiveName]; - + const mergeDirective = getDirective(schema, fieldConfig, mergeDirectiveName, pathToDirectivesInExtensions)?.[0]; + if (mergeDirective != null) { if (typeName !== queryTypeName) { throw new Error('@merge directive may be used only for root fields of the root Query type.'); } @@ -73,14 +75,14 @@ export function stitchingDirectivesValidator( throw new Error('@merge directive must be used on a field that returns an object or a list of objects.'); } - const mergeArgsExpr = directiveArgumentMap.argsExpr; + const mergeArgsExpr = mergeDirective['argsExpr']; if (mergeArgsExpr != null) { parseMergeArgsExpr(mergeArgsExpr); } const args = Object.keys(fieldConfig.args ?? {}); - const keyArg = directiveArgumentMap.keyArg; + const keyArg = mergeDirective['keyArg']; if (keyArg == null) { if (!mergeArgsExpr && args.length !== 1) { throw new Error( @@ -94,7 +96,7 @@ export function stitchingDirectivesValidator( // TODO: ideally we should check that the arg exists for the resolver } - const keyField = directiveArgumentMap.keyArg; + const keyField = mergeDirective['keyField']; if (keyField != null && !keyField.match(dottedNameRegEx)) { throw new Error( '`keyField` argument for @merge directive must be a set of valid GraphQL SDL names separated by periods.' @@ -102,7 +104,7 @@ export function stitchingDirectivesValidator( // TODO: ideally we should check that it is part of the key } - const key: Array = directiveArgumentMap.key; + const key: Array = mergeDirective['key']; if (key != null) { if (keyField != null) { throw new Error('Cannot use @merge directive with both `keyField` and `key` arguments.'); @@ -132,7 +134,7 @@ export function stitchingDirectivesValidator( } } - const additionalArgs = directiveArgumentMap.additionalArgs; + const additionalArgs = mergeDirective['additionalArgs']; if (additionalArgs != null) { parseValue(`{ ${additionalArgs} }`, { noLocation: true }); } @@ -147,7 +149,7 @@ export function stitchingDirectivesValidator( ); } - const typeNames: Array = directiveArgumentMap.types; + const typeNames: Array = mergeDirective['types']; if (typeNames != null) { if (!isAbstractType(returnType)) { throw new Error('Types argument can only be used with a field that returns an abstract type.'); diff --git a/packages/utils/src/get-directives.ts b/packages/utils/src/get-directives.ts index d0afe8fb287..c3a4bdf6d4b 100644 --- a/packages/utils/src/get-directives.ts +++ b/packages/utils/src/get-directives.ts @@ -23,11 +23,13 @@ import { GraphQLEnumValueConfig, EnumValueDefinitionNode, } from 'graphql'; -import { Maybe } from '@graphql-tools/utils'; import { getArgumentValues } from './getArgumentValues'; -export type DirectiveUseMap = { [key: string]: any }; +export interface DirectiveAnnotation { + name: string; + args?: Record; +} type SchemaOrTypeNode = | SchemaDefinitionNode @@ -58,23 +60,70 @@ type DirectableGraphQLObject = export function getDirectivesInExtensions( node: DirectableGraphQLObject, pathToDirectivesInExtensions = ['directives'] -): Maybe { - const directivesInExtensions = pathToDirectivesInExtensions.reduce( +): Array { + return pathToDirectivesInExtensions.reduce( (acc, pathSegment) => (acc == null ? acc : acc[pathSegment]), node?.extensions + ) as Array; +} + +function _getDirectiveInExtensions( + directivesInExtensions: Array, + directiveName: string +): Array> | undefined { + const directiveInExtensions = directivesInExtensions.filter( + directiveAnnotation => directiveAnnotation.name === directiveName ); + if (!directiveInExtensions.length) { + return undefined; + } + + return directiveInExtensions.map(directive => directive.args ?? {}); +} + +export function getDirectiveInExtensions( + node: DirectableGraphQLObject, + directiveName: string, + pathToDirectivesInExtensions = ['directives'] +): Array> | undefined { + const directivesInExtensions = pathToDirectivesInExtensions.reduce( + (acc, pathSegment) => (acc == null ? acc : acc[pathSegment]), + node?.extensions + ) as Record | Array>> | Array | undefined; - return directivesInExtensions; + if (directivesInExtensions === undefined) { + return undefined; + } + + if (Array.isArray(directivesInExtensions)) { + return _getDirectiveInExtensions(directivesInExtensions, directiveName); + } + + // Support condensed format by converting to longer format + // The condensed format does not preserve ordering of directives when repeatable directives are used. + // See https://github.com/ardatan/graphql-tools/issues/2534 + const reformattedDirectivesInExtensions: Array = []; + for (const [name, argsOrArrayOfArgs] of Object.entries(directivesInExtensions)) { + if (Array.isArray(argsOrArrayOfArgs)) { + for (const args of argsOrArrayOfArgs) { + reformattedDirectivesInExtensions.push({ name, args }); + } + } else { + reformattedDirectivesInExtensions.push({ name, args: argsOrArrayOfArgs }); + } + } + + return _getDirectiveInExtensions(reformattedDirectivesInExtensions, directiveName); } export function getDirectives( schema: GraphQLSchema, node: DirectableGraphQLObject, pathToDirectivesInExtensions = ['directives'] -): DirectiveUseMap { +): Array { const directivesInExtensions = getDirectivesInExtensions(node, pathToDirectivesInExtensions); - if (directivesInExtensions != null) { + if (directivesInExtensions != null && directivesInExtensions.length > 0) { return directivesInExtensions; } @@ -94,23 +143,63 @@ export function getDirectives( astNodes = [...astNodes, ...node.extensionASTNodes]; } - const result: DirectiveUseMap = {}; + const result: Array = []; for (const astNode of astNodes) { if (astNode.directives) { for (const directiveNode of astNode.directives) { const schemaDirective = schemaDirectiveMap[directiveNode.name.value]; if (schemaDirective) { - if (schemaDirective.isRepeatable) { - result[schemaDirective.name] = result[schemaDirective.name] ?? []; - result[schemaDirective.name].push(getArgumentValues(schemaDirective, directiveNode)); - } else { - result[schemaDirective.name] = getArgumentValues(schemaDirective, directiveNode); - } + result.push({ name: directiveNode.name.value, args: getArgumentValues(schemaDirective, directiveNode) }); + } + } + } + } + + return result; +} + +export function getDirective( + schema: GraphQLSchema, + node: DirectableGraphQLObject, + directiveName: string, + pathToDirectivesInExtensions = ['directives'] +): Array> | undefined { + const directiveInExtensions = getDirectiveInExtensions(node, directiveName, pathToDirectivesInExtensions); + + if (directiveInExtensions != null) { + return directiveInExtensions; + } + + const schemaDirective = schema && schema.getDirective ? schema.getDirective(directiveName) : undefined; + + if (schemaDirective == null) { + return undefined; + } + + let astNodes: Array = []; + if (node.astNode) { + astNodes.push(node.astNode); + } + if ('extensionASTNodes' in node && node.extensionASTNodes) { + astNodes = [...astNodes, ...node.extensionASTNodes]; + } + + const result: Array> = []; + + for (const astNode of astNodes) { + if (astNode.directives) { + for (const directiveNode of astNode.directives) { + if (directiveNode.name.value === directiveName) { + result.push(getArgumentValues(schemaDirective, directiveNode)); } } } } + if (!result.length) { + return undefined; + } + return result; } diff --git a/packages/utils/tests/get-directives.spec.ts b/packages/utils/tests/get-directives.spec.ts index 19da8413343..4058d9b4eed 100644 --- a/packages/utils/tests/get-directives.spec.ts +++ b/packages/utils/tests/get-directives.spec.ts @@ -4,19 +4,19 @@ import { assertGraphQLObjectType } from '../../testing/assertion'; import { GraphQLSchema } from 'graphql'; describe('getDirectives', () => { - it('should return the correct directives map when no directives specified', () => { + it('should return the correct directives when no directives specified', () => { const typeDefs = ` type Query { test: String } `; const schema = makeExecutableSchema({ typeDefs, resolvers: {} }) as GraphQLSchema; - const directivesMap = getDirectives(schema, schema.getQueryType()!); + const directives = getDirectives(schema, schema.getQueryType()!); - expect(directivesMap).toEqual({}); + expect(directives).toEqual([]); }); - it('should return the correct directives map when built-in directive specified over FIELD_DEFINITION', () => { + it('should return the correct directives built-in directive specified over FIELD_DEFINITION', () => { const typeDefs = ` type Query { test: String @deprecated @@ -24,15 +24,16 @@ describe('getDirectives', () => { `; const schema = makeExecutableSchema({ typeDefs, resolvers: {} }) as GraphQLSchema; - const directivesMap = getDirectives(schema, schema.getQueryType()!.getFields()['test']); - expect(directivesMap).toEqual({ - deprecated: { + const directives = getDirectives(schema, schema.getQueryType()!.getFields()['test']); + expect(directives).toEqual([{ + name: 'deprecated', + args: { reason: 'No longer supported', }, - }); + }]); }); - it('should return the correct directives map when using custom directive without arguments', () => { + it('should return the correct directives when using custom directive without arguments', () => { const typeDefs = ` type Query { test: String @mydir @@ -42,13 +43,14 @@ describe('getDirectives', () => { `; const schema = makeExecutableSchema({ typeDefs, resolvers: {} }) as GraphQLSchema; - const directivesMap = getDirectives(schema, schema.getQueryType()!.getFields()['test']); - expect(directivesMap).toEqual({ - mydir: {}, - }); + const directives = getDirectives(schema, schema.getQueryType()!.getFields()['test']); + expect(directives).toEqual([{ + name: 'mydir', + args: {}, + }]); }); - it('should return the correct directives map when using custom directive with optional argument', () => { + it('should return the correct directives when using custom directive with optional argument', () => { const typeDefs = ` type Query { test: String @mydir(f1: "test") @@ -58,15 +60,16 @@ describe('getDirectives', () => { `; const schema = makeExecutableSchema({ typeDefs, resolvers: {} }) as GraphQLSchema; - const directivesMap = getDirectives(schema, schema.getQueryType()!.getFields()['test']); - expect(directivesMap).toEqual({ - mydir: { + const directives = getDirectives(schema, schema.getQueryType()!.getFields()['test']); + expect(directives).toEqual([{ + name: 'mydir', + args: { f1: 'test', }, - }); + }]); }); - it('should return the correct directives map when using custom directive with optional argument an no value', () => { + it('should return the correct directives when using custom directive with optional argument an no value', () => { const typeDefs = ` type Query { test: String @mydir @@ -76,10 +79,11 @@ describe('getDirectives', () => { `; const schema = makeExecutableSchema({ typeDefs, resolvers: {} }) as GraphQLSchema; - const directivesMap = getDirectives(schema, schema.getQueryType()!.getFields()['test']); - expect(directivesMap).toEqual({ - mydir: {}, - }); + const directives = getDirectives(schema, schema.getQueryType()!.getFields()['test']); + expect(directives).toEqual([{ + name: 'mydir', + args: {}, + }]); }); it('provides the extension definition', () => { @@ -96,7 +100,7 @@ describe('getDirectives', () => { }); const QueryType = schema.getQueryType() assertGraphQLObjectType(QueryType) - expect(getDirectives(schema,QueryType)).toEqual({ mydir: { arg: 'ext1' } }); + expect(getDirectives(schema,QueryType)).toEqual([{ name: 'mydir', args: { arg: 'ext1' } }]); }); it('builds proper repeatable directives listing', () => { @@ -110,8 +114,12 @@ describe('getDirectives', () => { }); const QueryType = schema.getQueryType() assertGraphQLObjectType(QueryType) - expect(getDirectives(schema, QueryType)).toEqual({ - mydir: [{ arg: "first" }, { arg: "second" }] - }); + expect(getDirectives(schema, QueryType)).toEqual([{ + name: 'mydir', + args: { arg: 'first' }, + }, { + name: 'mydir', + args: { arg: 'second' }, + }]); }); }); diff --git a/packages/utils/tests/schemaTransforms.test.ts b/packages/utils/tests/schemaTransforms.test.ts index 451314b4a82..12643ddafeb 100644 --- a/packages/utils/tests/schemaTransforms.test.ts +++ b/packages/utils/tests/schemaTransforms.test.ts @@ -31,6 +31,7 @@ import { MapperKind, getDirectives, ExecutionResult, + getDirective, } from '@graphql-tools/utils'; import { addMocksToSchema } from '@graphql-tools/mock'; @@ -122,8 +123,8 @@ describe('@directives', () => { return schema => mapSchema(schema, { [MapperKind.OBJECT_TYPE]: type => { const directives = getDirectives(schema, type); - for (const directiveName in directives) { - if (directiveNames.includes(directiveName)) { + for (const directive of directives) { + if (directiveNames.includes(directive.name)) { expect(type.name).toBe(schema.getQueryType()?.name); visited.add(type); } @@ -149,8 +150,8 @@ describe('@directives', () => { function recordSchemaDirectiveUses(directiveNames: Array): (schema: GraphQLSchema) => GraphQLSchema { return schema => { const directives = getDirectives(schema, schema); - for (const directiveName in directives) { - if (directiveNames.includes(directiveName)) { + for (const directive of directives) { + if (directiveNames.includes(directive.name)) { visited.push(schema); } } @@ -179,8 +180,8 @@ describe('@directives', () => { upperDirectiveTypeDefs: `directive @${directiveName} on FIELD_DEFINITION`, upperDirectiveTransformer: (schema: GraphQLSchema) => mapSchema(schema, { [MapperKind.OBJECT_FIELD]: (fieldConfig) => { - const directives = getDirectives(schema, fieldConfig); - if (directives[directiveName]) { + const upperDirective = getDirective(schema, fieldConfig, directiveName)?.[0]; + if (upperDirective) { const { resolve = defaultFieldResolver } = fieldConfig; fieldConfig.resolve = async function (source, args, context, info) { const result = await resolve(source, args, context, info); @@ -234,18 +235,16 @@ describe('@directives', () => { deprecatedDirectiveTypeDefs: `directive @${directiveName}(reason: String) on FIELD_DEFINITION | ENUM_VALUE`, deprecatedDirectiveTransformer: (schema: GraphQLSchema) => mapSchema(schema, { [MapperKind.OBJECT_FIELD]: (fieldConfig) => { - const directives = getDirectives(schema, fieldConfig); - const directiveArgumentMap = directives[directiveName]; - if (directiveArgumentMap) { - fieldConfig.deprecationReason = directiveArgumentMap.reason; + const deprecatedDirective = getDirective(schema, fieldConfig, directiveName)?.[0]; + if (deprecatedDirective) { + fieldConfig.deprecationReason = deprecatedDirective['reason']; return fieldConfig; } }, [MapperKind.ENUM_VALUE]: (enumValueConfig) => { - const directives = getDirectives(schema, enumValueConfig); - const directiveArgumentMap = directives[directiveName]; - if (directiveArgumentMap) { - enumValueConfig.deprecationReason = directiveArgumentMap.reason; + const deprecatedDirective = getDirective(schema, enumValueConfig, directiveName)?.[0]; + if (deprecatedDirective) { + enumValueConfig.deprecationReason = deprecatedDirective['reason']; return enumValueConfig; } } @@ -278,16 +277,14 @@ describe('@directives', () => { dateDirectiveTypeDefs: `directive @${directiveName}(format: String) on FIELD_DEFINITION`, dateDirectiveTransformer: (schema: GraphQLSchema) => mapSchema(schema, { [MapperKind.OBJECT_FIELD]: (fieldConfig) => { - const directives = getDirectives(schema, fieldConfig); - const directiveArgumentMap = directives[directiveName]; - if (directiveArgumentMap) { + const dateDirective = getDirective(schema, fieldConfig, directiveName)?.[0]; + if (dateDirective) { const { resolve = defaultFieldResolver } = fieldConfig; - const { format } = directiveArgumentMap; - fieldConfig.resolve = async function (source, args, context, info) { + const { format } = dateDirective; + fieldConfig.resolve = async (source, args, context, info) => { const date = await resolve(source, args, context, info); return formatDate(date, format, true); - - } + }; return fieldConfig; } } @@ -338,11 +335,10 @@ describe('@directives', () => { `, formattableDateDirectiveTransformer: (schema: GraphQLSchema) => mapSchema(schema, { [MapperKind.OBJECT_FIELD]: (fieldConfig) => { - const directives = getDirectives(schema, fieldConfig); - const directiveArgumentMap = directives[directiveName]; - if (directiveArgumentMap) { + const dateDirective = getDirective(schema, fieldConfig, directiveName)?.[0]; + if (dateDirective) { const { resolve = defaultFieldResolver } = fieldConfig; - const { defaultFormat } = directiveArgumentMap; + const { defaultFormat } = dateDirective; if (!fieldConfig.args) { throw new Error("Unexpected Error. args should be defined.") @@ -353,12 +349,12 @@ describe('@directives', () => { }; fieldConfig.type = GraphQLString; - fieldConfig.resolve = async function ( + fieldConfig.resolve = async ( source, { format, ...args }, context, info, - ) { + ) => { const newFormat = format || defaultFormat; const date = await resolve(source, args, context, info); return formatDate(date, newFormat, true); @@ -430,15 +426,16 @@ describe('@directives', () => { }`, authDirectiveTransformer: (schema: GraphQLSchema) => mapSchema(schema, { [MapperKind.TYPE]: (type) => { - const typeDirectives = getDirectives(schema, type); - typeDirectiveArgumentMaps[type.name] = typeDirectives[directiveName]; + const authDirective = getDirective(schema, type, directiveName)?.[0]; + if (authDirective) { + typeDirectiveArgumentMaps[type.name] = authDirective; + } return undefined; }, [MapperKind.OBJECT_FIELD]: (fieldConfig, _fieldName, typeName) => { - const fieldDirectives = getDirectives(schema, fieldConfig); - const directiveArgumentMap = fieldDirectives[directiveName] ?? typeDirectiveArgumentMaps[typeName]; - if (directiveArgumentMap) { - const { requires } = directiveArgumentMap; + const authDirective = getDirective(schema, fieldConfig, directiveName)?.[0] ?? typeDirectiveArgumentMaps[typeName]; + if (authDirective) { + const { requires } = authDirective; if (requires) { const { resolve = defaultFieldResolver } = fieldConfig; fieldConfig.resolve = function (source, args, context, info) { @@ -626,10 +623,9 @@ describe('@directives', () => { lengthDirectiveTypeDefs: `directive @${directiveName}(max: Int) on FIELD_DEFINITION | INPUT_FIELD_DEFINITION`, lengthDirectiveTransformer: (schema: GraphQLSchema) => mapSchema(schema, { [MapperKind.FIELD]: (fieldConfig) => { - const directives = getDirectives(schema, fieldConfig); - const directiveArgumentMap = directives[directiveName]; - if (directiveArgumentMap) { - wrapType(fieldConfig, directiveArgumentMap); + const lengthDirective = getDirective(schema, fieldConfig, directiveName)?.[0]; + if (lengthDirective) { + wrapType(fieldConfig, lengthDirective); return fieldConfig; } } @@ -717,10 +713,9 @@ describe('@directives', () => { uniqueIDDirectiveTypeDefs: `directive @${directiveName}(name: String, from: [String]) on OBJECT`, uniqueIDDirectiveTransformer: (schema: GraphQLSchema) => mapSchema(schema, { [MapperKind.OBJECT_TYPE]: (type) => { - const directives = getDirectives(schema, type); - const directiveArgumentMap = directives[directiveName]; - if (directiveArgumentMap) { - const { name, from } = directiveArgumentMap; + const uniqueIDDirective = getDirective(schema, type, directiveName)?.[0]; + if (uniqueIDDirective) { + const { name, from } = uniqueIDDirective; const config = type.toConfig(); config.fields[name] = { type: GraphQLID, @@ -827,9 +822,8 @@ describe('@directives', () => { function renameObjectTypeToHumanDirective(directiveName: string): (schema: GraphQLSchema) => GraphQLSchema { return schema => mapSchema(schema, { [MapperKind.OBJECT_TYPE]: (type) => { - const directives = getDirectives(schema, type); - const directiveArgumentMap = directives[directiveName]; - if (directiveArgumentMap) { + const directive = getDirective(schema, type, directiveName)?.[0]; + if (directive) { const config = type.toConfig(); config.name = 'Human'; return new GraphQLObjectType(config); @@ -875,9 +869,8 @@ describe('@directives', () => { function removeEnumValueDirective(directiveName: string): (schema: GraphQLSchema) => GraphQLSchema { return schema => mapSchema(schema, { [MapperKind.ENUM_VALUE]: (enumValueConfig) => { - const directives = getDirectives(schema, enumValueConfig); - const directiveArgumentMap = directives[directiveName]; - if (directiveArgumentMap && directiveArgumentMap.if) { + const directive = getDirective(schema, enumValueConfig, directiveName)?.[0]; + if (directive?.['if']) { return null; } } @@ -912,10 +905,9 @@ describe('@directives', () => { function modifyExternalEnumValueDirective(directiveName: string): (schema: GraphQLSchema) => GraphQLSchema { return schema => mapSchema(schema, { [MapperKind.ENUM_VALUE]: (enumValueConfig) => { - const directives = getDirectives(schema, enumValueConfig); - const directiveArgumentMap = directives[directiveName]; - if (directiveArgumentMap) { - return [directiveArgumentMap.new, enumValueConfig]; + const directive = getDirective(schema, enumValueConfig, directiveName)?.[0]; + if (directive) { + return [directive['new'], enumValueConfig]; } } }); @@ -950,10 +942,9 @@ describe('@directives', () => { function modifyInternalEnumValueDirective(directiveName: string): (schema: GraphQLSchema) => GraphQLSchema { return schema => mapSchema(schema, { [MapperKind.ENUM_VALUE]: (enumValueConfig) => { - const directives = getDirectives(schema, enumValueConfig); - const directiveArgumentMap = directives[directiveName]; - if (directiveArgumentMap) { - enumValueConfig.value = directiveArgumentMap.new; + const directive = getDirective(schema, enumValueConfig, directiveName)?.[0]; + if (directive) { + enumValueConfig.value = directive['new']; return enumValueConfig; } } @@ -989,11 +980,10 @@ describe('@directives', () => { function renameObjectTypeDirective(directiveName: string): (schema: GraphQLSchema) => GraphQLSchema { return schema => mapSchema(schema, { [MapperKind.OBJECT_TYPE]: (type) => { - const directives = getDirectives(schema, type); - const directiveArgumentMap = directives[directiveName]; - if (directiveArgumentMap) { + const directive = getDirective(schema, type, directiveName)?.[0]; + if (directive) { const config = type.toConfig(); - config.name = directiveArgumentMap.to; + config.name = directive['to']; return new GraphQLObjectType(config); } } @@ -1042,9 +1032,8 @@ describe('@directives', () => { function addObjectTypeToSetDirective(directiveName: string): (schema: GraphQLSchema) => GraphQLSchema { return schema => mapSchema(schema, { [MapperKind.OBJECT_TYPE]: type => { - const directives = getDirectives(schema, type); - const directiveArgumentMap = directives[directiveName]; - if (directiveArgumentMap) { + const directive = getDirective(schema, type, directiveName)?.[0]; + if (directive) { expect(type.name).toBe(schema.getQueryType()?.name); visited.add(type); } @@ -1072,8 +1061,8 @@ describe('@directives', () => { function upperDirective(directiveName: string): (schema: GraphQLSchema) => GraphQLSchema { return schema => mapSchema(schema, { [MapperKind.OBJECT_FIELD]: (fieldConfig) => { - const directives = getDirectives(schema, fieldConfig); - if (directives[directiveName]) { + const upperDirective = getDirective(schema, fieldConfig, directiveName)?.[0]; + if (upperDirective) { const { resolve = defaultFieldResolver } = fieldConfig; fieldConfig.resolve = async function (source, args, context, info) { const result = await resolve(source, args, context, info); @@ -1091,8 +1080,8 @@ describe('@directives', () => { function reverseDirective(directiveName: string): (schema: GraphQLSchema) => GraphQLSchema { return schema => mapSchema(schema, { [MapperKind.OBJECT_FIELD]: (fieldConfig) => { - const directives = getDirectives(schema, fieldConfig); - if (directives[directiveName]) { + const reverseDirective = getDirective(schema, fieldConfig, directiveName)?.[0]; + if (reverseDirective) { const { resolve = defaultFieldResolver } = fieldConfig; fieldConfig.resolve = async function (source, args, context, info) { const result = await resolve(source, args, context, info); @@ -1145,10 +1134,10 @@ describe('@directives', () => { const listWrapperTypes = new Map(); return mapSchema(schema, { [MapperKind.COMPOSITE_FIELD]: (fieldConfig, fieldName) => { - const hasDirectiveAnnotation = !!getDirectives(schema, fieldConfig)['addListWrapper']; + const directive = getDirective(schema, fieldConfig, 'addListWrapper')?.[0]; // Leave the field untouched if it does not have the directive annotation - if (!hasDirectiveAnnotation) { + if (!directive) { return undefined; } diff --git a/packages/wrap/src/transforms/RemoveObjectFieldsWithDirective.ts b/packages/wrap/src/transforms/RemoveObjectFieldsWithDirective.ts index 2633df6e282..4b6dc019741 100644 --- a/packages/wrap/src/transforms/RemoveObjectFieldsWithDirective.ts +++ b/packages/wrap/src/transforms/RemoveObjectFieldsWithDirective.ts @@ -21,13 +21,10 @@ export default class RemoveObjectFieldsWithDirective implements Transform { transformedSchema?: GraphQLSchema ): GraphQLSchema { const transformer = new FilterObjectFields((_typeName, _fieldName, fieldConfig) => { - const valueMap = getDirectives(originalWrappingSchema, fieldConfig); - return !Object.keys(valueMap).some( - directiveName => - valueMatchesCriteria(directiveName, this.directiveName) && - ((Array.isArray(valueMap[directiveName]) && - valueMap[directiveName].some((value: any) => valueMatchesCriteria(value, this.args))) || - valueMatchesCriteria(valueMap[directiveName], this.args)) + const directives = getDirectives(originalWrappingSchema, fieldConfig); + return !directives.some( + directive => + valueMatchesCriteria(directive.name, this.directiveName) && valueMatchesCriteria(directive.args, this.args) ); }); diff --git a/website/docs/schema-directives.md b/website/docs/schema-directives.md index 124bbfaaf07..5b1709bc54c 100644 --- a/website/docs/schema-directives.md +++ b/website/docs/schema-directives.md @@ -61,28 +61,25 @@ Here is one possible implementation of the `@deprecated` directive we saw above: import { mapSchema, getDirectives } from '@graphql-tools/utils'; import { GraphQLSchema } from 'graphql'; -export function deprecatedDirective(directiveName: string) { +function deprecatedDirective(directiveName: string) { return { deprecatedDirectiveTypeDefs: `directive @${directiveName}(reason: String) on FIELD_DEFINITION | ENUM_VALUE`, - deprecatedDirectiveTransformer: (schema: GraphQLSchema) => - mapSchema(schema, { - [MapperKind.OBJECT_FIELD]: fieldConfig => { - const directives = getDirectives(schema, fieldConfig); - const directiveArgumentMap = directives[directiveName]; - if (directiveArgumentMap) { - fieldConfig.deprecationReason = directiveArgumentMap.reason; - return fieldConfig; - } - }, - [MapperKind.ENUM_VALUE]: enumValueConfig => { - const directives = getDirectives(schema, enumValueConfig); - const directiveArgumentMap = directives[directiveName]; - if (directiveArgumentMap) { - enumValueConfig.deprecationReason = directiveArgumentMap.reason; - return enumValueConfig; - } - }, - }), + deprecatedDirectiveTransformer: (schema: GraphQLSchema) => mapSchema(schema, { + [MapperKind.OBJECT_FIELD]: (fieldConfig) => { + const deprecatedDirective = getDirective(schema, fieldConfig, directiveName)?.[0]; + if (deprecatedDirective) { + fieldConfig.deprecationReason = deprecatedDirective['reason']; + return fieldConfig; + } + }, + [MapperKind.ENUM_VALUE]: (enumValueConfig) => { + const deprecatedDirective = getDirective(schema, enumValueConfig, directiveName)?.[0]; + if (deprecatedDirective) { + enumValueConfig.deprecationReason = deprecatedDirective['reason']; + return enumValueConfig; + } + } + }), }; } ``` @@ -131,26 +128,23 @@ To appreciate the range of possibilities enabled by `mapSchema`, let's examine a Suppose you want to ensure a string-valued field is converted to uppercase. Though this use case is simple, it's a good example of a directive implementation that works by wrapping a field's `resolve` function: ```js -function upperDirective(directiveName: string) { - return { - upperDirectiveTypeDefs: `directive @${directiveName} on FIELD_DEFINITION`, - upperDirectiveTransformer: (schema: GraphQLSchema) => mapSchema(schema, { - [MapperKind.OBJECT_FIELD]: (fieldConfig) => { - const directives = getDirectives(schema, fieldConfig); - if (directives[directiveName]) { - const { resolve = defaultFieldResolver } = fieldConfig; - fieldConfig.resolve = async function (source, args, context, info) { - const result = await resolve(source, args, context, info); - if (typeof result === 'string') { - return result.toUpperCase(); - } - return result; +function upperDirective(directiveName: string): (schema: GraphQLSchema) => GraphQLSchema { + return schema => mapSchema(schema, { + [MapperKind.OBJECT_FIELD]: (fieldConfig) => { + const upperDirective = getDirective(schema, fieldConfig, directiveName)?.[0]; + if (upperDirective) { + const { resolve = defaultFieldResolver } = fieldConfig; + fieldConfig.resolve = async function (source, args, context, info) { + const result = await resolve(source, args, context, info); + if (typeof result === 'string') { + return result.toUpperCase(); } - return fieldConfig; + return result; } + return fieldConfig; } - }) - }; + } + }); } const { upperDirectiveTypeDefs, upperDirectiveTransformer } = upperDirective('upper'); @@ -190,10 +184,9 @@ function restDirective(directiveName: string) { restDirectiveTypeDefs: `directive @${directiveName}(url: String) on FIELD_DEFINITION`; restDirectiveTransformer: (schema: GraphQLSchema) => mapSchema(schema, { [MapperKind.OBJECT_FIELD]: (fieldConfig) => { - const directives = getDirectives(schema, fieldConfig); - const directiveArgumentMap = directives[directiveName]; - if (directiveArgumentMap) { - const { url } = directiveArgumentMap; + const restDirective = getDirective(schema, fieldConfig, directiveName)?.[0]; + if (restDirective) { + const { url } = restDirective; fieldConfig.resolve = () => fetch(url); return fieldConfig; } @@ -224,22 +217,20 @@ Suppose your resolver returns a `Date` object but you want to return a formatted function dateDirective(directiveName: string) { return { dateDirectiveTypeDefs: `directive @${directiveName}(format: String) on FIELD_DEFINITION`, - dateDirectiveTransformer: (schema: GraphQLSchema) => - mapSchema(schema, { - [MapperKind.OBJECT_FIELD]: fieldConfig => { - const directives = getDirectives(schema, fieldConfig); - const directiveArgumentMap = directives[directiveName]; - if (directiveArgumentMap) { - const { resolve = defaultFieldResolver } = fieldConfig; - const { format } = directiveArgumentMap; - fieldConfig.resolve = async function (source, args, context, info) { - const date = await resolve(source, args, context, info); - return formatDate(date, format, true); - }; - return fieldConfig; - } - }, - }), + dateDirectiveTransformer: (schema: GraphQLSchema) => mapSchema(schema, { + [MapperKind.OBJECT_FIELD]: (fieldConfig) => { + const dateDirective = getDirective(schema, fieldConfig, directiveName)?.[0]; + if (dateDirective) { + const { resolve = defaultFieldResolver } = fieldConfig; + const { format } = dateDirective; + fieldConfig.resolve = async (source, args, context, info) => { + const date = await resolve(source, args, context, info); + return formatDate(date, format, true); + }; + return fieldConfig; + } + } + }), }; } @@ -278,29 +269,36 @@ function formattableDateDirective(directiveName: string) { defaultFormat: String = "mmmm d, yyyy" ) on FIELD_DEFINITION `, - formattableDateDirectiveTransformer: (schema: GraphQLSchema) => - mapSchema(schema, { - [MapperKind.OBJECT_FIELD]: fieldConfig => { - const directives = getDirectives(schema, fieldConfig); - const directiveArgumentMap = directives[directiveName]; - if (directiveArgumentMap) { - const { resolve = defaultFieldResolver } = fieldConfig; - const { defaultFormat } = directiveArgumentMap; - - fieldConfig.args['format'] = { - type: GraphQLString, - }; - - fieldConfig.type = GraphQLString; - fieldConfig.resolve = async function (source, { format, ...args }, context, info) { - const newFormat = format || defaultFormat; - const date = await resolve(source, args, context, info); - return formatDate(date, newFormat, true); - }; - return fieldConfig; + formattableDateDirectiveTransformer: (schema: GraphQLSchema) => mapSchema(schema, { + [MapperKind.OBJECT_FIELD]: (fieldConfig) => { + const dateDirective = getDirective(schema, fieldConfig, directiveName)?.[0]; + if (dateDirective) { + const { resolve = defaultFieldResolver } = fieldConfig; + const { defaultFormat } = dateDirective; + + if (!fieldConfig.args) { + throw new Error("Unexpected Error. args should be defined.") } - }, - }), + + fieldConfig.args['format'] = { + type: GraphQLString, + }; + + fieldConfig.type = GraphQLString; + fieldConfig.resolve = async ( + source, + { format, ...args }, + context, + info, + ) => { + const newFormat = format || defaultFormat; + const date = await resolve(source, args, context, info); + return formatDate(date, newFormat, true); + }; + return fieldConfig; + } + } + }), }; } @@ -395,15 +393,16 @@ function authDirective(directiveName: string, getUserFn: (token: string) => { ha }`, authDirectiveTransformer: (schema: GraphQLSchema) => mapSchema(schema, { [MapperKind.TYPE]: (type) => { - const typeDirectives = getDirectives(schema, type); - typeDirectiveArgumentMaps[type.name] = typeDirectives[directiveName]; + const authDirective = getDirective(schema, type, directiveName)?.[0]; + if (authDirective) { + typeDirectiveArgumentMaps[type.name] = authDirective; + } return undefined; }, [MapperKind.OBJECT_FIELD]: (fieldConfig, _fieldName, typeName) => { - const fieldDirectives = getDirectives(schema, fieldConfig); - const directiveArgumentMap = fieldDirectives[directiveName] ?? typeDirectiveArgumentMaps[typeName]; - if (directiveArgumentMap) { - const { requires } = directiveArgumentMap; + const authDirective = getDirective(schema, fieldConfig, directiveName)?.[0] ?? typeDirectiveArgumentMaps[typeName]; + if (authDirective) { + const { requires } = authDirective; if (requires) { const { resolve = defaultFieldResolver } = fieldConfig; fieldConfig.resolve = function (source, args, context, info) { @@ -419,7 +418,7 @@ function authDirective(directiveName: string, getUserFn: (token: string) => { ha } }) }; -}; +} function getUser(token: string) { const roles = ['UNKNOWN', 'USER', 'REVIEWER', 'ADMIN']; @@ -494,7 +493,7 @@ function lengthDirective(directiveName: string) { return type.parseValue(value); }, - parseLiteral(ast: StringValueNode) { + parseLiteral(ast) { return type.parseLiteral(ast, {}); }, }); @@ -524,9 +523,9 @@ function lengthDirective(directiveName: string) { function wrapType | GraphQLInputFieldConfig>(fieldConfig: F, directiveArgumentMap: Record): void { if (isNonNullType(fieldConfig.type) && isScalarType(fieldConfig.type.ofType)) { - fieldConfig.type = getLimitedLengthType(fieldConfig.type.ofType, directiveArgumentMap.max); + fieldConfig.type = getLimitedLengthType(fieldConfig.type.ofType, directiveArgumentMap['max']); } else if (isScalarType(fieldConfig.type)) { - fieldConfig.type = getLimitedLengthType(fieldConfig.type, directiveArgumentMap.max); + fieldConfig.type = getLimitedLengthType(fieldConfig.type, directiveArgumentMap['max']); } else { throw new Error(`Not a scalar type: ${fieldConfig.type.toString()}`); } @@ -536,16 +535,15 @@ function lengthDirective(directiveName: string) { lengthDirectiveTypeDefs: `directive @${directiveName}(max: Int) on FIELD_DEFINITION | INPUT_FIELD_DEFINITION`, lengthDirectiveTransformer: (schema: GraphQLSchema) => mapSchema(schema, { [MapperKind.FIELD]: (fieldConfig) => { - const directives = getDirectives(schema, fieldConfig); - const directiveArgumentMap = directives[directiveName]; - if (directiveArgumentMap) { - wrapType(fieldConfig, directiveArgumentMap); + const lengthDirective = getDirective(schema, fieldConfig, directiveName)?.[0]; + if (lengthDirective) { + wrapType(fieldConfig, lengthDirective); return fieldConfig; } } }), }; -}; +} const { lengthDirectiveTypeDefs, lengthDirectiveTransformer } = lengthDirective('length'); @@ -600,31 +598,29 @@ import { createHash } from 'crypto'; function uniqueIDDirective(directiveName: string) { return { uniqueIDDirectiveTypeDefs: `directive @${directiveName}(name: String, from: [String]) on OBJECT`, - uniqueIDDirectiveTransformer: (schema: GraphQLSchema) => - mapSchema(schema, { - [MapperKind.OBJECT_TYPE]: type => { - const directives = getDirectives(schema, type); - const directiveArgumentMap = directives[directiveName]; - if (directiveArgumentMap) { - const { name, from } = directiveArgumentMap; - const config = type.toConfig(); - config.fields[name] = { - type: GraphQLID, - description: 'Unique ID', - args: {}, - resolve(object: any) { - const hash = createHash('sha1'); - hash.update(type.name); - for (const fieldName of from) { - hash.update(String(object[fieldName])); - } - return hash.digest('hex'); - }, - }; - return new GraphQLObjectType(config); - } - }, - }), + uniqueIDDirectiveTransformer: (schema: GraphQLSchema) => mapSchema(schema, { + [MapperKind.OBJECT_TYPE]: (type) => { + const uniqueIDDirective = getDirective(schema, type, directiveName)?.[0]; + if (uniqueIDDirective) { + const { name, from } = uniqueIDDirective; + const config = type.toConfig(); + config.fields[name] = { + type: GraphQLID, + description: 'Unique ID', + args: {}, + resolve(object: any) { + const hash = createHash('sha1'); + hash.update(type.name); + for (const fieldName of from ){ + hash.update(String(object[fieldName])); + } + return hash.digest('hex'); + }, + }; + return new GraphQLObjectType(config); + } + } + }), }; } @@ -686,9 +682,9 @@ In theory, access to the query directives is available within the `info` resolve ## What about `directiveResolvers`? -The `makeExecutableSchema` function also takes a `directiveResolvers` option that can be used for implementing certain kinds of `@directive`s on fields that have resolver functions. +The `makeExecutableSchema` function used to take a `directiveResolvers` option that could be used for implementing certain kinds of `@directive`s on fields that have resolver functions. -The new abstraction is more general, since it can visit any kind of schema syntax, and do much more than just wrap resolver functions. However, the old `directiveResolvers` API has been left in place for backwards compatibility, though it is now implemented in terms of `mapSchema`: +The new abstraction is more general, since it can visit any kind of schema syntax, and do much more than just wrap resolver functions. The old `directiveResolvers` API can be implemented with the above new API as follows: ```typescript export function attachDirectiveResolvers( @@ -702,11 +698,12 @@ export function attachDirectiveResolvers( const newFieldConfig = { ...fieldConfig }; const directives = getDirectives(schema, fieldConfig); - for (const directiveName in directives) { + for (const directive of directives) { + const directiveName = directive.name; if (directiveResolvers[directiveName]) { const resolver = directiveResolvers[directiveName]; const originalResolver = newFieldConfig.resolve != null ? newFieldConfig.resolve : defaultFieldResolver; - const directiveArgs = directives[directiveName]; + const directiveArgs = directive.args; newFieldConfig.resolve = (source, originalArgs, context, info) => { return resolver( () => @@ -732,8 +729,6 @@ export function attachDirectiveResolvers( } ``` -Existing code that uses `directiveResolvers` could consider migrating to direct usage of `mapSchema`, though we have no immediate plans to deprecate `directiveResolvers`. - ## What about code-first schemas? You can use schema transformation functions with code-first schemas as well. By default, if a `directives` key exists within the `extensions` field for a given GraphQL entity, the `getDirectives` function will retrieve the directive data from the GraphQL entity's `extensions.directives` data rather than from the SDL. This, of course, allows schemas created without SDL to use any schema transformation functions created for directive use, as long as they define the necessary data within the GraphQL entity extensions. From ecfe6a6e12e895a473b07f15776470105d0d0057 Mon Sep 17 00:00:00 2001 From: Arda TANRIKULU Date: Mon, 12 Jul 2021 21:05:47 +0300 Subject: [PATCH 49/66] fix(load): load from all loaders at once even if one returns some result (#3184) * Try to load afrom all loaders * TypeScript :) * add test Co-authored-by: Laurin Quast --- packages/load/src/load-typedefs/load-file.ts | 46 +++++++++---------- .../documents/documents-from-glob.spec.ts | 9 ++++ 2 files changed, 32 insertions(+), 23 deletions(-) diff --git a/packages/load/src/load-typedefs/load-file.ts b/packages/load/src/load-typedefs/load-file.ts index 1b09b1703c0..54096f8c102 100644 --- a/packages/load/src/load-typedefs/load-file.ts +++ b/packages/load/src/load-typedefs/load-file.ts @@ -1,47 +1,47 @@ -import { Source, Maybe, isSome } from '@graphql-tools/utils'; +import { Source } from '@graphql-tools/utils'; import { env } from 'process'; import { LoadTypedefsOptions } from '../load-typedefs'; -export async function loadFile(pointer: string, options: LoadTypedefsOptions): Promise> { +export async function loadFile(pointer: string, options: LoadTypedefsOptions): Promise { const cached = useCache({ pointer, options }); if (cached) { return cached; } - for await (const loader of options.loaders) { - try { - const loadedValue = await loader.load(pointer, options); - if (!isSome(loadedValue) || loadedValue.length === 0) { - continue; - } - return loadedValue; - } catch (error) { - if (env['DEBUG']) { - console.error(`Failed to find any GraphQL type definitions in: ${pointer} - ${error.message}`); + const results: Source[] = []; + + await Promise.all( + options.loaders.map(async loader => { + try { + const loaderResults = await loader.load(pointer, options); + loaderResults?.forEach(result => results.push(result)); + } catch (error) { + if (env['DEBUG']) { + console.error(`Failed to find any GraphQL type definitions in: ${pointer} - ${error.message}`); + } + throw error; } - throw error; - } - } + }) + ); - return undefined; + return results; } -export function loadFileSync(pointer: string, options: LoadTypedefsOptions): Maybe { +export function loadFileSync(pointer: string, options: LoadTypedefsOptions): Source[] { const cached = useCache({ pointer, options }); if (cached) { return cached; } + const results: Source[] = []; + for (const loader of options.loaders) { try { // We check for the existence so it is okay to force non null - const loadedValue = loader.loadSync!(pointer, options); - if (!isSome(loadedValue) || loadedValue.length === 0) { - continue; - } - return loadedValue; + const loaderResults = loader.loadSync!(pointer, options); + loaderResults?.forEach(result => results.push(result)); } catch (error) { if (env['DEBUG']) { console.error(`Failed to find any GraphQL type definitions in: ${pointer} - ${error.message}`); @@ -50,7 +50,7 @@ export function loadFileSync(pointer: string, options: LoadTypedefsOptions): May } } - return undefined; + return results; } function useCache({ pointer, options }: { pointer: string; options: T }) { diff --git a/packages/load/tests/loaders/documents/documents-from-glob.spec.ts b/packages/load/tests/loaders/documents/documents-from-glob.spec.ts index db585b777d7..f48d465f3cd 100644 --- a/packages/load/tests/loaders/documents/documents-from-glob.spec.ts +++ b/packages/load/tests/loaders/documents/documents-from-glob.spec.ts @@ -140,5 +140,14 @@ describe('documentsFromGlob', () => { }); expect(result.length).toBe(1); }) + test(`should try loading using all loaders`, async () => { + const glob = join(__dirname, './test-files/', '(tags.js|2.graphql)'); + const result = await load(glob, { + loaders: [new GraphQLFileLoader(), new CodeFileLoader()], + }); + // 1 from 2.graphql + // 2 from tags.js + expect(result.length).toEqual(3); + }) }) }); From e9fa6133541727572f74ab886f9d61dae64d5bca Mon Sep 17 00:00:00 2001 From: Laurin Quast Date: Mon, 12 Jul 2021 20:43:52 +0200 Subject: [PATCH 50/66] fix: git loader should simply ignore non git paths instead of panicking (#3188) --- packages/loaders/git/src/index.ts | 107 ++++++++++++++++------ packages/loaders/git/tests/loader.spec.ts | 10 +- 2 files changed, 83 insertions(+), 34 deletions(-) diff --git a/packages/loaders/git/src/index.ts b/packages/loaders/git/src/index.ts index b105341160b..e94607d630c 100644 --- a/packages/loaders/git/src/index.ts +++ b/packages/loaders/git/src/index.ts @@ -13,14 +13,14 @@ import { asArray, BaseLoaderOptions, Loader, Source } from '@graphql-tools/utils import isGlob from 'is-glob'; // git:branch:path/to/file -function extractData(pointer: string): { +function extractData(pointer: string): null | { ref: string; path: string; } { const parts = pointer.replace(/^git\:/i, '').split(':'); if (!parts || parts.length !== 2) { - throw new Error('Schema pointer should match "git:branchName:path/to/file"'); + return null; } return { @@ -61,17 +61,24 @@ export class GitLoader implements Loader { return typeof pointer === 'string' && pointer.toLowerCase().startsWith('git:'); } - async resolveGlobs(glob: string, ignores: string[]) { + async resolveGlobs(glob: string, ignores: string[]): Promise> { + const data = extractData(glob); + if (data === null) { + return []; + } const refsForPaths = new Map(); - - const { ref, path } = extractData(glob); + const { ref, path } = data; if (!refsForPaths.has(ref)) { refsForPaths.set(ref, []); } refsForPaths.get(ref).push(unixify(path)); for (const ignore of ignores) { - const { ref, path } = extractData(ignore); + const data = extractData(ignore); + if (data === null) { + continue; + } + const { ref, path } = data; if (!refsForPaths.has(ref)) { refsForPaths.set(ref, []); } @@ -88,16 +95,24 @@ export class GitLoader implements Loader { } resolveGlobsSync(glob: string, ignores: string[]) { + const data = extractData(glob); + if (data === null) { + return []; + } + const { ref, path } = data; const refsForPaths = new Map(); - const { ref, path } = extractData(glob); if (!refsForPaths.has(ref)) { refsForPaths.set(ref, []); } refsForPaths.get(ref).push(unixify(path)); for (const ignore of ignores) { - const { ref, path } = extractData(ignore); + const data = extractData(ignore); + if (data === null) { + continue; + } + const { ref, path } = data; if (!refsForPaths.has(ref)) { refsForPaths.set(ref, []); } @@ -111,19 +126,12 @@ export class GitLoader implements Loader { return resolved; } - async load(pointer: string, options: GitLoaderOptions): Promise { - const { ref, path } = extractData(pointer); - if (isGlob(path)) { - const resolvedPaths = await this.resolveGlobs(pointer, asArray(options.ignore || [])); - const finalResult: Source[] = []; - - await Promise.all( - resolvedPaths.map(async path => { - const results = await this.load(path, options); - results?.forEach(result => finalResult.push(result)); - }) - ); + private async _load(pointer: string, options: GitLoaderOptions): Promise { + const result = extractData(pointer); + if (result === null) { + return []; } + const { ref, path } = result; const content = await loadFromGit({ ref, path }); const parsed = handleStuff({ path, options, pointer, content }); @@ -139,17 +147,37 @@ export class GitLoader implements Loader { })); } - loadSync(pointer: string, options: GitLoaderOptions): Source[] { - const { ref, path } = extractData(pointer); + async load(pointer: string, options: GitLoaderOptions): Promise { + const result = extractData(pointer); + if (result === null) { + return []; + } + const { path } = result; + const finalResult: Source[] = []; + if (isGlob(path)) { - const resolvedPaths = this.resolveGlobsSync(pointer, asArray(options.ignore || [])); - const finalResult: Source[] = []; + const resolvedPaths = await this.resolveGlobs(pointer, asArray(options.ignore || [])); - resolvedPaths.forEach(path => { - const results = this.loadSync(path, options); - results?.forEach(result => finalResult.push(result)); - }); + await Promise.all( + resolvedPaths.map(async path => { + const results = await this.load(path, options); + finalResult.push(...results); + }) + ); + } else if (await this.canLoad(pointer)) { + finalResult.push(...(await this._load(pointer, options))); } + + return finalResult; + } + + private _loadSync(pointer: string, options: GitLoaderOptions): Source[] { + const result = extractData(pointer); + if (result === null) { + return []; + } + const { ref, path } = result; + const content = loadFromGitSync({ ref, path }); const parsed = handleStuff({ path, options, pointer, content }); @@ -164,4 +192,27 @@ export class GitLoader implements Loader { document: parse(source, options), })); } + + loadSync(pointer: string, options: GitLoaderOptions): Source[] { + const result = extractData(pointer); + if (result === null) { + return []; + } + const { path } = result; + const finalResult: Source[] = []; + + if (isGlob(path)) { + const resolvedPaths = this.resolveGlobsSync(pointer, asArray(options.ignore || [])); + const finalResult: Source[] = []; + for (const path of resolvedPaths) { + if (this.canLoadSync(path)) { + finalResult.push(...this.loadSync(path, options)); + } + } + } else if (this.canLoadSync(pointer)) { + finalResult.push(...this._loadSync(pointer, options)); + } + + return finalResult; + } } diff --git a/packages/loaders/git/tests/loader.spec.ts b/packages/loaders/git/tests/loader.spec.ts index 54b704f50fd..8c3e7d85a9e 100644 --- a/packages/loaders/git/tests/loader.spec.ts +++ b/packages/loaders/git/tests/loader.spec.ts @@ -60,17 +60,15 @@ describe('GitLoader', () => { expect(result.document).toMatchSnapshot(); }); - it('should throw when pointer is malformed', async () => { - await expect(load(getPointer('foo:graphql'), {})).rejects.toThrowError( - 'Schema pointer should match "git:branchName:path/to/file"' - ); - }); - it('should throw when the file does not exist', async () => { await expect(load(getPointer('wrong-filename.graphql'), {})).rejects.toThrowError( 'Unable to load file from git' ); }); + it('should simply ignore a non git path', async () => { + const result = await load('./pluckable.ts', {}); + expect(result).toEqual([]) + }) }); }); }); From 4dfa5c20394fe5b665f657919339ce9287fa0ef1 Mon Sep 17 00:00:00 2001 From: Laurin Quast Date: Mon, 12 Jul 2021 21:10:03 +0200 Subject: [PATCH 51/66] fix github, json, apollo and prisma loader (#3189) * sfix: skip pointers that cannot be loaded * fix: json file loader * fix prisma and apollo loaders --- packages/loaders/apollo-engine/src/index.ts | 10 ++++++++-- packages/loaders/github/src/index.ts | 3 +++ .../loaders/github/tests/schema-from-github.spec.ts | 9 +++++++++ packages/loaders/json-file/src/index.ts | 13 +++++++++---- packages/loaders/json-file/tests/loader.spec.ts | 4 ++++ packages/loaders/prisma/src/index.ts | 3 +++ 6 files changed, 36 insertions(+), 6 deletions(-) diff --git a/packages/loaders/apollo-engine/src/index.ts b/packages/loaders/apollo-engine/src/index.ts index 854eb7a06d7..21b3340b3ed 100644 --- a/packages/loaders/apollo-engine/src/index.ts +++ b/packages/loaders/apollo-engine/src/index.ts @@ -58,7 +58,10 @@ export class ApolloEngineLoader implements Loader { return typeof ptr === 'string' && ptr === 'apollo-engine'; } - async load(pointer: 'apollo-engine', options: ApolloEngineOptions): Promise { + async load(pointer: string, options: ApolloEngineOptions): Promise { + if (!(await this.canLoad(pointer))) { + return []; + } const fetchArgs = this.getFetchArgs(options); const response = await fetch(...fetchArgs); @@ -72,7 +75,10 @@ export class ApolloEngineLoader implements Loader { return [source]; } - loadSync(pointer: 'apollo-engine', options: ApolloEngineOptions): Source[] { + loadSync(pointer: string, options: ApolloEngineOptions): Source[] { + if (!this.canLoadSync(pointer)) { + return []; + } const fetchArgs = this.getFetchArgs(options); const response = syncFetch(...fetchArgs); diff --git a/packages/loaders/github/src/index.ts b/packages/loaders/github/src/index.ts index cf28b8cdc25..f72ad9210a3 100644 --- a/packages/loaders/github/src/index.ts +++ b/packages/loaders/github/src/index.ts @@ -60,6 +60,9 @@ export class GithubLoader implements Loader { } async load(pointer: string, options: GithubLoaderOptions): Promise { + if (!(await this.canLoad(pointer))) { + return []; + } const { owner, name, ref, path } = extractData(pointer); const request = await fetch('https://api.github.com/graphql', { method: 'POST', diff --git a/packages/loaders/github/tests/schema-from-github.spec.ts b/packages/loaders/github/tests/schema-from-github.spec.ts index b7020962b11..30c455170b0 100644 --- a/packages/loaders/github/tests/schema-from-github.spec.ts +++ b/packages/loaders/github/tests/schema-from-github.spec.ts @@ -98,3 +98,12 @@ test('load schema from GitHub', async () => { // schema expect(print(source.document)).toEqual(printSchema(buildSchema(typeDefs))); }); + +test('simply skips schema for path that cannot be loaded', async () => { + const loader = new GithubLoader(); + + const result = await loader.load("./test/123", { + token, + }); + expect(result).toEqual([]) +}) diff --git a/packages/loaders/json-file/src/index.ts b/packages/loaders/json-file/src/index.ts index 69d0a14c2c8..f451ec83c83 100644 --- a/packages/loaders/json-file/src/index.ts +++ b/packages/loaders/json-file/src/index.ts @@ -60,7 +60,6 @@ export class JsonFileLoader implements Loader { if (isValidPath(pointer)) { if (FILE_EXTENSIONS.find(extension => pointer.endsWith(extension))) { const normalizedFilePath = isAbsolute(pointer) ? pointer : resolve(options.cwd || cwd(), pointer); - return existsSync(normalizedFilePath); } } @@ -70,6 +69,9 @@ export class JsonFileLoader implements Loader { async load(pointer: string, options: JsonFileLoaderOptions): Promise { const normalizedFilePath = isAbsolute(pointer) ? pointer : resolve(options.cwd || cwd(), pointer); + if (!(await this.canLoad(normalizedFilePath, options))) { + return []; + } try { const jsonContent: string = await readFile(normalizedFilePath, { encoding: 'utf8' }); @@ -80,13 +82,16 @@ export class JsonFileLoader implements Loader { } loadSync(pointer: string, options: JsonFileLoaderOptions): Source[] { - const normalizedFilepath = isAbsolute(pointer) ? pointer : resolve(options.cwd || cwd(), pointer); + const normalizedFilePath = isAbsolute(pointer) ? pointer : resolve(options.cwd || cwd(), pointer); + if (!this.canLoadSync(normalizedFilePath, options)) { + return []; + } try { - const jsonContent = readFileSync(normalizedFilepath, 'utf8'); + const jsonContent = readFileSync(normalizedFilePath, 'utf8'); return [parseGraphQLJSON(pointer, jsonContent, options)]; } catch (e) { - throw new Error(`Unable to read JSON file: ${normalizedFilepath}: ${e.message || /* istanbul ignore next */ e}`); + throw new Error(`Unable to read JSON file: ${normalizedFilePath}: ${e.message || /* istanbul ignore next */ e}`); } } } diff --git a/packages/loaders/json-file/tests/loader.spec.ts b/packages/loaders/json-file/tests/loader.spec.ts index 7492bae5602..50f3887fd41 100644 --- a/packages/loaders/json-file/tests/loader.spec.ts +++ b/packages/loaders/json-file/tests/loader.spec.ts @@ -65,6 +65,10 @@ describe('JsonFileLoader', () => { it('should throw when the file content is malformed', async () => { await expect(load(getPointer('malformed.json'), {})).rejects.toThrowError('Unable to read JSON file'); }); + it('should skip file it cannot load', async () => { + const result = await load(getPointer('id_do_not_exist.json'), {}); + expect(result).toEqual([]) + }) }); }); }); diff --git a/packages/loaders/prisma/src/index.ts b/packages/loaders/prisma/src/index.ts index 8d28705614b..14e6ab025c1 100644 --- a/packages/loaders/prisma/src/index.ts +++ b/packages/loaders/prisma/src/index.ts @@ -42,6 +42,9 @@ export class PrismaLoader extends UrlLoader { } async load(prismaConfigFilePath: string, options: PrismaLoaderOptions) { + if (!(await this.canLoad(prismaConfigFilePath, options))) { + return []; + } const { graceful, envVars } = options; const home = homedir(); const env = new Environment(home); From 0eaab362b061ba707483bdf26a80e4ed42aab9a6 Mon Sep 17 00:00:00 2001 From: Laurin Quast Date: Mon, 12 Jul 2021 22:05:54 +0200 Subject: [PATCH 52/66] fix(code-loader): do not load illegal files (#3190) --- packages/loaders/code-file/src/index.ts | 26 ++++++++++++------- .../tests/load-from-code-file.spec.ts | 25 ++++++++++++++++++ .../code-file/tests/test-files/other.graphql | 3 +++ 3 files changed, 44 insertions(+), 10 deletions(-) create mode 100644 packages/loaders/code-file/tests/test-files/other.graphql diff --git a/packages/loaders/code-file/src/index.ts b/packages/loaders/code-file/src/index.ts index c4bdd063126..e943c9c57ed 100644 --- a/packages/loaders/code-file/src/index.ts +++ b/packages/loaders/code-file/src/index.ts @@ -117,23 +117,22 @@ export class CodeFileLoader implements Loader { return globby.sync([glob, ...ignores.map(v => `!${v}`).map(v => unixify(v))], createGlobbyOptions(options)); } - async load(pointer: string, options: CodeFileLoaderOptions): Promise { + async load(pointer: string, options: CodeFileLoaderOptions): Promise { options = this.getMergedOptions(options); + const finalResult: Source[] = []; + if (isGlob(pointer)) { const resolvedPaths = await this.resolveGlobs(pointer, options); - const finalResult: Source[] = []; await Promise.all( resolvedPaths.map(async path => { - if (await this.canLoad(path, options)) { - const result = await this.handleSinglePath(path, options); - result?.forEach(result => finalResult.push(result)); - } + finalResult.push(...(await this.handleSinglePath(path, options))); }) ); - return finalResult; + } else { + finalResult.push(...(await this.handleSinglePath(pointer, options))); } - return this.handleSinglePath(pointer, options); + return finalResult; } loadSync(pointer: string, options: CodeFileLoaderOptions): Source[] | null { @@ -153,7 +152,11 @@ export class CodeFileLoader implements Loader { return this.handleSinglePathSync(pointer, options); } - async handleSinglePath(location: string, options: CodeFileLoaderOptions): Promise { + async handleSinglePath(location: string, options: CodeFileLoaderOptions): Promise { + if (!(await this.canLoad(location, options))) { + return []; + } + options = this.getMergedOptions(options); const normalizedFilePath = ensureAbsolutePath(location, options); @@ -200,10 +203,13 @@ export class CodeFileLoader implements Loader { throw errors[0]; } - return null; + return []; } handleSinglePathSync(location: string, options: CodeFileLoaderOptions): Source[] | null { + if (!this.canLoadSync(location, options)) { + return []; + } options = this.getMergedOptions(options); const normalizedFilePath = ensureAbsolutePath(location, options); diff --git a/packages/loaders/code-file/tests/load-from-code-file.spec.ts b/packages/loaders/code-file/tests/load-from-code-file.spec.ts index 109a27f16ac..67eada1e3fd 100644 --- a/packages/loaders/code-file/tests/load-from-code-file.spec.ts +++ b/packages/loaders/code-file/tests/load-from-code-file.spec.ts @@ -63,6 +63,19 @@ describe('loadFromCodeFile', () => { expect(doc?.kind).toEqual('Document'); }); + + + it('does not try to load single file it cannot load', async () => { + const loader = new CodeFileLoader({ + pluckConfig: { + skipIndent: true + } + }) + const loaded = await loader.load('./test-files/other.graphql', { + cwd: __dirname, + }); + expect(loaded).toEqual([]) + }) }); describe('loadFromCodeFileSync', () => { @@ -174,4 +187,16 @@ describe('loadFromCodeFileSync', () => { " `); }) + + it('does not try to load single file it cannot load', async () => { + const loader = new CodeFileLoader({ + pluckConfig: { + skipIndent: true + } + }) + const loaded = loader.loadSync('./test-files/other.graphql', { + cwd: __dirname, + }); + expect(loaded).toEqual([]) + }) }); diff --git a/packages/loaders/code-file/tests/test-files/other.graphql b/packages/loaders/code-file/tests/test-files/other.graphql new file mode 100644 index 00000000000..25125dac93b --- /dev/null +++ b/packages/loaders/code-file/tests/test-files/other.graphql @@ -0,0 +1,3 @@ +query { + foo +} From 6813e81f8ebe10b7f3be7320995315d58c763677 Mon Sep 17 00:00:00 2001 From: Laurin Quast Date: Mon, 12 Jul 2021 22:39:22 +0200 Subject: [PATCH 53/66] fix: handle ignore for nested pointers (#3191) * fix: handle ignore for nested pointers * add test --- packages/load/src/utils/pointers.ts | 37 ++++++++++--------- .../schema/schema-from-typedefs.spec.ts | 13 +++++++ 2 files changed, 33 insertions(+), 17 deletions(-) diff --git a/packages/load/src/utils/pointers.ts b/packages/load/src/utils/pointers.ts index 1261576e905..cc70d6718d4 100644 --- a/packages/load/src/utils/pointers.ts +++ b/packages/load/src/utils/pointers.ts @@ -5,23 +5,26 @@ export function normalizePointers( unnormalizedPointerOrPointers: UnnormalizedTypeDefPointer | UnnormalizedTypeDefPointer[] ) { const ignore: string[] = []; - const pointerOptionMap = asArray(unnormalizedPointerOrPointers).reduce<{ [key: string]: any }>( - (normalizedPointers, unnormalizedPointer) => { - if (typeof unnormalizedPointer === 'string') { - if (unnormalizedPointer.startsWith('!')) { - ignore.push(unnormalizedPointer.replace('!', '')); - } else { - normalizedPointers[unnormalizedPointer] = {}; - } - } else if (typeof unnormalizedPointer === 'object') { - Object.assign(normalizedPointers, unnormalizedPointer); - } else { - throw new Error(`Invalid pointer ${unnormalizedPointer}`); - } + const pointerOptionMap: Record> = {}; + + const handlePointer = (rawPointer: string, options = {}) => { + if (rawPointer.startsWith('!')) { + ignore.push(rawPointer.replace('!', '')); + } else { + pointerOptionMap[rawPointer] = options; + } + }; - return normalizedPointers; - }, - {} - ); + for (const rawPointer of asArray(unnormalizedPointerOrPointers)) { + if (typeof rawPointer === 'string') { + handlePointer(rawPointer); + } else if (typeof rawPointer === 'object') { + for (const [path, options] of Object.entries(rawPointer)) { + handlePointer(path, options); + } + } else { + throw new Error(`Invalid pointer '${rawPointer}'.`); + } + } return { ignore, pointerOptionMap }; } diff --git a/packages/load/tests/loaders/schema/schema-from-typedefs.spec.ts b/packages/load/tests/loaders/schema/schema-from-typedefs.spec.ts index 04f989a8084..f7895150e0b 100644 --- a/packages/load/tests/loaders/schema/schema-from-typedefs.spec.ts +++ b/packages/load/tests/loaders/schema/schema-from-typedefs.spec.ts @@ -173,5 +173,18 @@ describe('schema from typedefs', () => { }); expect(result.getTypeMap()["User"]).toBeDefined() }) + + it('should be able to exclude documents via nested negative glob', async () => { + await load([ + './tests/loaders/schema/test-files/schema-dir/user.graphql', + './tests/loaders/schema/test-files/schema-dir/invalid.graphql', + { + '!./tests/loaders/schema/test-files/schema-dir/i*.graphql' : {} + } + ], { + loaders: [new GraphQLFileLoader()], + includeSources: true, + }); + }) }) }); From cdf711c0eefc8048c1b6912b2fc3d619dc92abf9 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 12 Jul 2021 21:51:03 +0000 Subject: [PATCH 54/66] chore(deps): update typescript-eslint monorepo to v4.28.3 (#3186) Co-authored-by: Renovate Bot --- package.json | 4 +-- yarn.lock | 82 ++++++++++++++++++++++++++-------------------------- 2 files changed, 43 insertions(+), 43 deletions(-) diff --git a/package.json b/package.json index 1bc86c68b8a..b55f48c67fe 100644 --- a/package.json +++ b/package.json @@ -51,8 +51,8 @@ "@changesets/cli": "2.16.0", "@types/jest": "26.0.24", "@types/node": "14.17.5", - "@typescript-eslint/eslint-plugin": "4.28.2", - "@typescript-eslint/parser": "4.28.2", + "@typescript-eslint/eslint-plugin": "4.28.3", + "@typescript-eslint/parser": "4.28.3", "babel-jest": "27.0.6", "concurrently": "6.2.0", "eslint": "7.30.0", diff --git a/yarn.lock b/yarn.lock index 0db8bd8164c..23308efd3e8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2880,73 +2880,73 @@ resolved "https://registry.yarnpkg.com/@types/zen-observable/-/zen-observable-0.8.2.tgz#808c9fa7e4517274ed555fa158f2de4b4f468e71" integrity sha512-HrCIVMLjE1MOozVoD86622S7aunluLb2PJdPfb3nYiEtohm8mIB/vyv0Fd37AdeMFrTUQXEunw78YloMA3Qilg== -"@typescript-eslint/eslint-plugin@4.28.2": - version "4.28.2" - resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.28.2.tgz#7a8320f00141666813d0ae43b49ee8244f7cf92a" - integrity sha512-PGqpLLzHSxq956rzNGasO3GsAPf2lY9lDUBXhS++SKonglUmJypaUtcKzRtUte8CV7nruwnDxtLUKpVxs0wQBw== +"@typescript-eslint/eslint-plugin@4.28.3": + version "4.28.3" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.28.3.tgz#36cdcd9ca6f9e5cb49b9f61b970b1976708d084b" + integrity sha512-jW8sEFu1ZeaV8xzwsfi6Vgtty2jf7/lJmQmDkDruBjYAbx5DA8JtbcMnP0rNPUG+oH5GoQBTSp+9613BzuIpYg== dependencies: - "@typescript-eslint/experimental-utils" "4.28.2" - "@typescript-eslint/scope-manager" "4.28.2" + "@typescript-eslint/experimental-utils" "4.28.3" + "@typescript-eslint/scope-manager" "4.28.3" debug "^4.3.1" functional-red-black-tree "^1.0.1" regexpp "^3.1.0" semver "^7.3.5" tsutils "^3.21.0" -"@typescript-eslint/experimental-utils@4.28.2": - version "4.28.2" - resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-4.28.2.tgz#4ebdec06a10888e9326e1d51d81ad52a361bd0b0" - integrity sha512-MwHPsL6qo98RC55IoWWP8/opTykjTp4JzfPu1VfO2Z0MshNP0UZ1GEV5rYSSnZSUI8VD7iHvtIPVGW5Nfh7klQ== +"@typescript-eslint/experimental-utils@4.28.3": + version "4.28.3" + resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-4.28.3.tgz#976f8c1191b37105fd06658ed57ddfee4be361ca" + integrity sha512-zZYl9TnrxwEPi3FbyeX0ZnE8Hp7j3OCR+ELoUfbwGHGxWnHg9+OqSmkw2MoCVpZksPCZYpQzC559Ee9pJNHTQw== dependencies: "@types/json-schema" "^7.0.7" - "@typescript-eslint/scope-manager" "4.28.2" - "@typescript-eslint/types" "4.28.2" - "@typescript-eslint/typescript-estree" "4.28.2" + "@typescript-eslint/scope-manager" "4.28.3" + "@typescript-eslint/types" "4.28.3" + "@typescript-eslint/typescript-estree" "4.28.3" eslint-scope "^5.1.1" eslint-utils "^3.0.0" -"@typescript-eslint/parser@4.28.2": - version "4.28.2" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-4.28.2.tgz#6aff11bf4b91eb67ca7517962eede951e9e2a15d" - integrity sha512-Q0gSCN51eikAgFGY+gnd5p9bhhCUAl0ERMiDKrTzpSoMYRubdB8MJrTTR/BBii8z+iFwz8oihxd0RAdP4l8w8w== +"@typescript-eslint/parser@4.28.3": + version "4.28.3" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-4.28.3.tgz#95f1d475c08268edffdcb2779993c488b6434b44" + integrity sha512-ZyWEn34bJexn/JNYvLQab0Mo5e+qqQNhknxmc8azgNd4XqspVYR5oHq9O11fLwdZMRcj4by15ghSlIEq+H5ltQ== dependencies: - "@typescript-eslint/scope-manager" "4.28.2" - "@typescript-eslint/types" "4.28.2" - "@typescript-eslint/typescript-estree" "4.28.2" + "@typescript-eslint/scope-manager" "4.28.3" + "@typescript-eslint/types" "4.28.3" + "@typescript-eslint/typescript-estree" "4.28.3" debug "^4.3.1" -"@typescript-eslint/scope-manager@4.28.2": - version "4.28.2" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-4.28.2.tgz#451dce90303a3ce283750111495d34c9c204e510" - integrity sha512-MqbypNjIkJFEFuOwPWNDjq0nqXAKZvDNNs9yNseoGBB1wYfz1G0WHC2AVOy4XD7di3KCcW3+nhZyN6zruqmp2A== +"@typescript-eslint/scope-manager@4.28.3": + version "4.28.3" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-4.28.3.tgz#c32ad4491b3726db1ba34030b59ea922c214e371" + integrity sha512-/8lMisZ5NGIzGtJB+QizQ5eX4Xd8uxedFfMBXOKuJGP0oaBBVEMbJVddQKDXyyB0bPlmt8i6bHV89KbwOelJiQ== dependencies: - "@typescript-eslint/types" "4.28.2" - "@typescript-eslint/visitor-keys" "4.28.2" + "@typescript-eslint/types" "4.28.3" + "@typescript-eslint/visitor-keys" "4.28.3" -"@typescript-eslint/types@4.28.2": - version "4.28.2" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.28.2.tgz#e6b9e234e0e9a66c4d25bab881661e91478223b5" - integrity sha512-Gr15fuQVd93uD9zzxbApz3wf7ua3yk4ZujABZlZhaxxKY8ojo448u7XTm/+ETpy0V0dlMtj6t4VdDvdc0JmUhA== +"@typescript-eslint/types@4.28.3": + version "4.28.3" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.28.3.tgz#8fffd436a3bada422c2c1da56060a0566a9506c7" + integrity sha512-kQFaEsQBQVtA9VGVyciyTbIg7S3WoKHNuOp/UF5RG40900KtGqfoiETWD/v0lzRXc+euVE9NXmfer9dLkUJrkA== -"@typescript-eslint/typescript-estree@4.28.2": - version "4.28.2" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.28.2.tgz#680129b2a285289a15e7c6108c84739adf3a798c" - integrity sha512-86lLstLvK6QjNZjMoYUBMMsULFw0hPHJlk1fzhAVoNjDBuPVxiwvGuPQq3fsBMCxuDJwmX87tM/AXoadhHRljg== +"@typescript-eslint/typescript-estree@4.28.3": + version "4.28.3" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.28.3.tgz#253d7088100b2a38aefe3c8dd7bd1f8232ec46fb" + integrity sha512-YAb1JED41kJsqCQt1NcnX5ZdTA93vKFCMP4lQYG6CFxd0VzDJcKttRlMrlG+1qiWAw8+zowmHU1H0OzjWJzR2w== dependencies: - "@typescript-eslint/types" "4.28.2" - "@typescript-eslint/visitor-keys" "4.28.2" + "@typescript-eslint/types" "4.28.3" + "@typescript-eslint/visitor-keys" "4.28.3" debug "^4.3.1" globby "^11.0.3" is-glob "^4.0.1" semver "^7.3.5" tsutils "^3.21.0" -"@typescript-eslint/visitor-keys@4.28.2": - version "4.28.2" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.28.2.tgz#bf56a400857bb68b59b311e6d0a5fbef5c3b5130" - integrity sha512-aT2B4PLyyRDUVUafXzpZFoc0C9t0za4BJAKP5sgWIhG+jHECQZUEjuQSCIwZdiJJ4w4cgu5r3Kh20SOdtEBl0w== +"@typescript-eslint/visitor-keys@4.28.3": + version "4.28.3" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.28.3.tgz#26ac91e84b23529968361045829da80a4e5251c4" + integrity sha512-ri1OzcLnk1HH4gORmr1dllxDzzrN6goUIz/P4MHFV0YZJDCADPR3RvYNp0PW2SetKTThar6wlbFTL00hV2Q+fg== dependencies: - "@typescript-eslint/types" "4.28.2" + "@typescript-eslint/types" "4.28.3" eslint-visitor-keys "^2.0.0" "@vercel/ncc@0.28.3": From a0ff8f3efe108045fbab2d1c405261216822eccb Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 12 Jul 2021 22:58:58 +0000 Subject: [PATCH 55/66] fix(deps): update dependency @theguild/components to v1.4.5 (#3187) Co-authored-by: Renovate Bot --- website/package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/website/package.json b/website/package.json index f853d937e9d..ed5bba5516d 100644 --- a/website/package.json +++ b/website/package.json @@ -14,7 +14,7 @@ "classnames": "2.3.1", "react": "17.0.2", "react-dom": "17.0.2", - "@theguild/components": "1.4.4" + "@theguild/components": "1.4.5" }, "browserslist": { "production": [ diff --git a/yarn.lock b/yarn.lock index 23308efd3e8..0661f17da60 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2369,10 +2369,10 @@ dependencies: defer-to-connect "^1.0.1" -"@theguild/components@1.4.4": - version "1.4.4" - resolved "https://registry.yarnpkg.com/@theguild/components/-/components-1.4.4.tgz#d5f69529bc6e03aaaecbd05015238312a9c65bd4" - integrity sha512-S8E/Q4n0MgTS9yakXv02Uji5+zgXFXMw41E+ppkeDPyysBJBxNoHbyu3LcePReyPM5UsnBooXdveG8XVyFk+bg== +"@theguild/components@1.4.5": + version "1.4.5" + resolved "https://registry.yarnpkg.com/@theguild/components/-/components-1.4.5.tgz#914ced6b7192f98eab39d9ef4ddfb81366fd4f06" + integrity sha512-OONwnqCDU7517rD9n0pASm2gqnIgHbOUIqn65MrcluJwYgkru3LTrcpCusCeoCxOYcaM4CHfMmZmNX2n9DaI1Q== dependencies: "@emotion/react" "^11.4.0" "@emotion/styled" "^11.3.0" From c42e811d8562f860d25d6698d84f236c595deae1 Mon Sep 17 00:00:00 2001 From: Arda TANRIKULU Date: Tue, 13 Jul 2021 02:37:44 +0300 Subject: [PATCH 56/66] Remove info from ExecutionParams and add operationType (#3166) * Remove info from ExecutionParams and add operationType * Fix tests * Allow getBatchingExecutor to cache executor by memoizing default executor * Memoize for a single so allow to memoize correctly. * Rename Request to ExecutionRequest * Remove unnecessary diff * Remove unnecessary operationName from DelegationContext * Add `context` in `createRequest` and `createRequestInfo` instead of `delegateToSchema` * Get context from request * Do not export extra types from delegate * Add info back * Fix typings --- .changeset/lazy-turtles-dress.md | 25 ++++++ .../src/createBatchingExecutor.ts | 31 ++++--- .../batch-execute/src/getBatchingExecutor.ts | 8 +- packages/batch-execute/src/mergeRequests.ts | 22 ++--- packages/delegate/src/Transformer.ts | 6 +- packages/delegate/src/createRequest.ts | 14 +++- packages/delegate/src/delegateToSchema.ts | 82 ++++++++----------- packages/delegate/src/index.ts | 1 - .../src/transforms/AddArgumentsAsVariables.ts | 8 +- .../src/transforms/AddSelectionSets.ts | 6 +- .../src/transforms/AddTypenameToAbstract.ts | 6 +- .../src/transforms/ExpandAbstractTypes.ts | 6 +- .../delegate/src/transforms/FilterToSchema.ts | 6 +- .../src/transforms/VisitSelectionSets.ts | 14 +++- .../src/transforms/WrapConcreteTypes.ts | 6 +- packages/delegate/src/types.ts | 14 ++-- .../delegate/tests/batchExecution.test.ts | 7 +- packages/links/src/linkToExecutor.ts | 8 +- packages/loaders/url/src/index.ts | 12 +-- packages/stitch/tests/errors.test.ts | 3 +- packages/stitch/tests/fixtures/schemas.ts | 7 +- packages/utils/src/Interfaces.ts | 4 +- packages/utils/src/executor.ts | 8 +- packages/utils/src/visitResult.ts | 4 +- packages/utils/tests/visitResult.test.ts | 7 +- packages/wrap/src/introspect.ts | 1 + packages/wrap/src/transforms/ExtractField.ts | 6 +- .../src/transforms/FilterInputObjectFields.ts | 6 +- packages/wrap/src/transforms/HoistField.ts | 12 ++- packages/wrap/src/transforms/MapFields.ts | 6 +- packages/wrap/src/transforms/MapLeafValues.ts | 8 +- .../src/transforms/RenameInputObjectFields.ts | 6 +- .../src/transforms/RenameInterfaceFields.ts | 6 +- .../wrap/src/transforms/RenameObjectFields.ts | 6 +- .../wrap/src/transforms/RenameRootFields.ts | 6 +- .../wrap/src/transforms/RenameRootTypes.ts | 6 +- packages/wrap/src/transforms/RenameTypes.ts | 6 +- .../transforms/TransformCompositeFields.ts | 6 +- .../src/transforms/TransformEnumValues.ts | 6 +- .../transforms/TransformInputObjectFields.ts | 8 +- .../transforms/TransformInterfaceFields.ts | 6 +- .../src/transforms/TransformObjectFields.ts | 6 +- .../wrap/src/transforms/TransformQuery.ts | 6 +- .../src/transforms/TransformRootFields.ts | 6 +- packages/wrap/src/transforms/WrapFields.ts | 6 +- packages/wrap/src/transforms/WrapQuery.ts | 6 +- packages/wrap/src/transforms/WrapType.ts | 6 +- packages/wrap/src/types.ts | 6 +- packages/wrap/tests/fixtures/schemas.ts | 17 ++-- packages/wrap/tests/requests.test.ts | 5 +- .../tests/transformFilterToSchema.test.ts | 5 +- 51 files changed, 266 insertions(+), 219 deletions(-) create mode 100644 .changeset/lazy-turtles-dress.md diff --git a/.changeset/lazy-turtles-dress.md b/.changeset/lazy-turtles-dress.md new file mode 100644 index 00000000000..c98b1dfce1f --- /dev/null +++ b/.changeset/lazy-turtles-dress.md @@ -0,0 +1,25 @@ +--- +'@graphql-tools/batch-execute': major +'@graphql-tools/delegate': major +'@graphql-tools/links': major +'@graphql-tools/utils': major +'@graphql-tools/wrap': major +--- + +BREAKING CHANGES; + +- Rename `Request` to `ExecutionRequest` +- Drop unnecessary `GraphQLResolveInfo` in `ExecutionRequest` +- Add required `operationType: OperationTypeNode` field in `ExecutionRequest` +- Add `context` in `createRequest` and `createRequestInfo` instead of `delegateToSchema` + +> It doesn't rely on info.operation.operationType to allow the user to call an operation from different root type. +And it doesn't call getOperationAST again and again to get operation type from the document/operation because we have it in Request and ExecutionParams +https://github.com/ardatan/graphql-tools/pull/3166/files#diff-d4824895ea613dcc1f710c3ac82e952fe0ca12391b671f70d9f2d90d5656fdceR38 + +Improvements; +- Memoize `defaultExecutor` for a single `GraphQLSchema` so allow `getBatchingExecutor` to memoize `batchingExecutor` correctly. +- And there is no different `defaultExecutor` is created for `subscription` and other operation types. Only one executor is used. + +> Batch executor is memoized by `executor` reference but `createDefaultExecutor` didn't memoize the default executor so this memoization wasn't working correctly on `batch-execute` side. +https://github.com/ardatan/graphql-tools/blob/remove-info-executor/packages/batch-execute/src/getBatchingExecutor.ts#L9 diff --git a/packages/batch-execute/src/createBatchingExecutor.ts b/packages/batch-execute/src/createBatchingExecutor.ts index 98c5e859cd6..2645230bc8e 100644 --- a/packages/batch-execute/src/createBatchingExecutor.ts +++ b/packages/batch-execute/src/createBatchingExecutor.ts @@ -1,10 +1,8 @@ -import { getOperationAST } from 'graphql'; - import DataLoader from 'dataloader'; import { ValueOrPromise } from 'value-or-promise'; -import { Request, Executor, ExecutionResult } from '@graphql-tools/utils'; +import { ExecutionRequest, Executor, ExecutionResult } from '@graphql-tools/utils'; import { mergeRequests } from './mergeRequests'; import { splitResult } from './splitResult'; @@ -14,32 +12,30 @@ export function createBatchingExecutor( dataLoaderOptions?: DataLoader.Options, extensionsReducer: ( mergedExtensions: Record, - request: Request + request: ExecutionRequest ) => Record = defaultExtensionsReducer ): Executor { const loader = new DataLoader(createLoadFn(executor, extensionsReducer), dataLoaderOptions); - return (request: Request) => - request.info?.operation.operation === 'subscription' ? executor(request) : loader.load(request); + return (request: ExecutionRequest) => { + return request.operationType === 'subscription' ? executor(request) : loader.load(request); + }; } function createLoadFn( executor: Executor, - extensionsReducer: (mergedExtensions: Record, request: Request) => Record + extensionsReducer: (mergedExtensions: Record, request: ExecutionRequest) => Record ) { - return async (requests: ReadonlyArray): Promise> => { - const execBatches: Array> = []; + return async (requests: ReadonlyArray): Promise> => { + const execBatches: Array> = []; let index = 0; const request = requests[index]; - let currentBatch: Array = [request]; + let currentBatch: Array = [request]; execBatches.push(currentBatch); - const operationType = getOperationAST(request.document, undefined)?.operation; - if (operationType == null) { - throw new Error('Could not identify operation type of document.'); - } + const operationType = request.operationType; while (++index < requests.length) { - const currentOperationType = getOperationAST(requests[index].document, undefined)?.operation; + const currentOperationType = requests[index].operationType; if (operationType == null) { throw new Error('Could not identify operation type of document.'); } @@ -68,7 +64,10 @@ function createLoadFn( }; } -function defaultExtensionsReducer(mergedExtensions: Record, request: Request): Record { +function defaultExtensionsReducer( + mergedExtensions: Record, + request: ExecutionRequest +): Record { const newExtensions = request.extensions; if (newExtensions != null) { Object.assign(mergedExtensions, newExtensions); diff --git a/packages/batch-execute/src/getBatchingExecutor.ts b/packages/batch-execute/src/getBatchingExecutor.ts index e315ee3b1a2..4bfda8d6ec7 100644 --- a/packages/batch-execute/src/getBatchingExecutor.ts +++ b/packages/batch-execute/src/getBatchingExecutor.ts @@ -1,14 +1,16 @@ import DataLoader from 'dataloader'; -import { Request, Executor } from '@graphql-tools/utils'; +import { ExecutionRequest, Executor } from '@graphql-tools/utils'; import { createBatchingExecutor } from './createBatchingExecutor'; import { memoize2of4 } from './memoize'; -export const getBatchingExecutor = memoize2of4(function ( +export const getBatchingExecutor = memoize2of4(function getBatchingExecutor( _context: Record, executor: Executor, dataLoaderOptions?: DataLoader.Options | undefined, - extensionsReducer?: undefined | ((mergedExtensions: Record, request: Request) => Record) + extensionsReducer?: + | undefined + | ((mergedExtensions: Record, request: ExecutionRequest) => Record) ): Executor { return createBatchingExecutor(executor, dataLoaderOptions, extensionsReducer); }); diff --git a/packages/batch-execute/src/mergeRequests.ts b/packages/batch-execute/src/mergeRequests.ts index 6c14b168998..d40f35f3442 100644 --- a/packages/batch-execute/src/mergeRequests.ts +++ b/packages/batch-execute/src/mergeRequests.ts @@ -15,10 +15,9 @@ import { ASTKindToNode, InlineFragmentNode, FieldNode, - OperationTypeNode, } from 'graphql'; -import { Request, Maybe } from '@graphql-tools/utils'; +import { ExecutionRequest } from '@graphql-tools/utils'; import { createPrefix } from './prefix'; @@ -57,24 +56,21 @@ import { createPrefix } from './prefix'; * } */ export function mergeRequests( - requests: Array, - extensionsReducer: (mergedExtensions: Record, request: Request) => Record -): Request { + requests: Array, + extensionsReducer: (mergedExtensions: Record, request: ExecutionRequest) => Record +): ExecutionRequest { const mergedVariables: Record = Object.create(null); const mergedVariableDefinitions: Array = []; const mergedSelections: Array = []; const mergedFragmentDefinitions: Array = []; let mergedExtensions: Record = Object.create(null); - let operation: Maybe; - for (const index in requests) { const request = requests[index]; const prefixedRequests = prefixRequest(createPrefix(index), request); for (const def of prefixedRequests.document.definitions) { if (isOperationDefinition(def)) { - operation = def.operation; mergedSelections.push(...def.selectionSet.selections); if (def.variableDefinitions) { mergedVariableDefinitions.push(...def.variableDefinitions); @@ -88,13 +84,9 @@ export function mergeRequests( mergedExtensions = extensionsReducer(mergedExtensions, request); } - if (operation == null) { - throw new Error('Could not identify operation type. Did the document only include fragment definitions?'); - } - const mergedOperationDefinition: OperationDefinitionNode = { kind: Kind.OPERATION_DEFINITION, - operation, + operation: requests[0].operationType, variableDefinitions: mergedVariableDefinitions, selectionSet: { kind: Kind.SELECTION_SET, @@ -111,10 +103,11 @@ export function mergeRequests( extensions: mergedExtensions, context: requests[0].context, info: requests[0].info, + operationType: requests[0].operationType, }; } -function prefixRequest(prefix: string, request: Request): Request { +function prefixRequest(prefix: string, request: ExecutionRequest): ExecutionRequest { let document = aliasTopLevelFields(prefix, request.document); const executionVariables = request.variables ?? {}; const variableNames = Object.keys(executionVariables); @@ -137,6 +130,7 @@ function prefixRequest(prefix: string, request: Request): Request { return { document, variables: prefixedVariables, + operationType: request.operationType, }; } diff --git a/packages/delegate/src/Transformer.ts b/packages/delegate/src/Transformer.ts index 376cb24015c..6e2e807f1fd 100644 --- a/packages/delegate/src/Transformer.ts +++ b/packages/delegate/src/Transformer.ts @@ -1,4 +1,4 @@ -import { Request, ExecutionResult } from '@graphql-tools/utils'; +import { ExecutionRequest, ExecutionResult } from '@graphql-tools/utils'; import { DelegationContext, DelegationBinding, Transform } from './types'; @@ -25,9 +25,9 @@ export class Transformer> { this.transformations.push({ transform, context }); } - public transformRequest(originalRequest: Request) { + public transformRequest(originalRequest: ExecutionRequest) { return this.transformations.reduce( - (request: Request, transformation: Transformation) => + (request: ExecutionRequest, transformation: Transformation) => transformation.transform.transformRequest != null ? transformation.transform.transformRequest(request, this.delegationContext, transformation.context) : request, diff --git a/packages/delegate/src/createRequest.ts b/packages/delegate/src/createRequest.ts index 4a298a073e7..e73b0758c4a 100644 --- a/packages/delegate/src/createRequest.ts +++ b/packages/delegate/src/createRequest.ts @@ -16,7 +16,7 @@ import { DocumentNode, } from 'graphql'; -import { Request, serializeInputValue, updateArgument } from '@graphql-tools/utils'; +import { ExecutionRequest, serializeInputValue, updateArgument } from '@graphql-tools/utils'; import { ICreateRequestFromInfo, ICreateRequest } from './types'; export function getDelegatingOperation(parentType: GraphQLObjectType, schema: GraphQLSchema): OperationTypeNode { @@ -37,7 +37,8 @@ export function createRequestFromInfo({ fieldName = info.fieldName, selectionSet, fieldNodes = info.fieldNodes, -}: ICreateRequestFromInfo): Request { + context, +}: ICreateRequestFromInfo): ExecutionRequest { return createRequest({ sourceSchema: info.schema, sourceParentType: info.parentType, @@ -51,6 +52,8 @@ export function createRequestFromInfo({ targetFieldName: fieldName, selectionSet, fieldNodes, + context, + info, }); } @@ -67,7 +70,9 @@ export function createRequest({ targetFieldName, selectionSet, fieldNodes, -}: ICreateRequest): Request { + context, + info, +}: ICreateRequest): ExecutionRequest { let newSelectionSet: SelectionSetNode | undefined; let argumentNodeMap: Record; @@ -176,6 +181,9 @@ export function createRequest({ variables: newVariables, rootValue: targetRootValue, operationName: targetOperationName, + operationType: targetOperation, + context, + info, }; } diff --git a/packages/delegate/src/delegateToSchema.ts b/packages/delegate/src/delegateToSchema.ts index 60ce50c1c03..53938ae1ebf 100644 --- a/packages/delegate/src/delegateToSchema.ts +++ b/packages/delegate/src/delegateToSchema.ts @@ -9,6 +9,7 @@ import { OperationDefinitionNode, DocumentNode, GraphQLOutputType, + ExecutionArgs, } from 'graphql'; import { ValueOrPromise } from 'value-or-promise'; @@ -18,7 +19,7 @@ import { getBatchingExecutor } from '@graphql-tools/batch-execute'; import { mapAsyncIterator, Executor, - Request, + ExecutionRequest, Maybe, AggregateError, isAsyncIterable, @@ -50,6 +51,7 @@ export function delegateToSchema, TArgs = any>( fieldName = info.fieldName, selectionSet, fieldNodes, + context, } = options; const request = createRequestFromInfo({ @@ -60,6 +62,7 @@ export function delegateToSchema, TArgs = any>( fieldNodes, rootValue: rootValue ?? (schema as SubschemaConfig).rootValue, operationName, + context, }); return delegateRequest({ @@ -90,17 +93,9 @@ export function delegateRequest, TArgs = any>( validateRequest(delegationContext, processedRequest.document); } - const { context, info } = delegationContext; - const executor = getExecutor(delegationContext); - return new ValueOrPromise(() => - executor({ - ...processedRequest, - context, - info, - }) - ) + return new ValueOrPromise(() => executor(processedRequest)) .then(originalResult => { if (isAsyncIterable(originalResult)) { // "subscribe" to the subscription result and map the result through the transforms @@ -116,32 +111,23 @@ export function delegateRequest, TArgs = any>( function getDelegationContext({ request, schema, - operation, fieldName, returnType, args, - context, info, transforms = [], transformedSchema, skipTypeMerging = false, }: IDelegateRequestOptions): DelegationContext { + const { operationType: operation, context, operationName, document } = request; let operationDefinition: Maybe; - let targetOperation: Maybe; let targetFieldName: string; - if (operation == null) { - operationDefinition = getOperationAST(request.document, request.operationName); + if (fieldName == null) { + operationDefinition = getOperationAST(document, operationName); if (operationDefinition == null) { throw new Error('Cannot infer main operation from the provided document.'); } - targetOperation = operationDefinition.operation; - } else { - targetOperation = operation; - } - - if (fieldName == null) { - operationDefinition = operationDefinition ?? getOperationAST(request.document, request.operationName); targetFieldName = (operationDefinition?.selectionSet.selections[0] as unknown as FieldDefinitionNode).name.value; } else { targetFieldName = fieldName; @@ -158,13 +144,12 @@ function getDelegationContext({ subschema: schema, subschemaConfig: subschemaOrSubschemaConfig, targetSchema, - operation: targetOperation, + operation, fieldName: targetFieldName, args, context, info, - returnType: - returnType ?? info?.returnType ?? getDelegationReturnType(targetSchema, targetOperation, targetFieldName), + returnType: returnType ?? info?.returnType ?? getDelegationReturnType(targetSchema, operation, targetFieldName), transforms: subschemaOrSubschemaConfig.transforms != null ? subschemaOrSubschemaConfig.transforms.concat(transforms) @@ -180,15 +165,13 @@ function getDelegationContext({ subschema: schema, subschemaConfig: undefined, targetSchema: subschemaOrSubschemaConfig, - operation: targetOperation, + operation, fieldName: targetFieldName, args, context, info, returnType: - returnType ?? - info?.returnType ?? - getDelegationReturnType(subschemaOrSubschemaConfig, targetOperation, targetFieldName), + returnType ?? info?.returnType ?? getDelegationReturnType(subschemaOrSubschemaConfig, operation, targetFieldName), transforms, transformedSchema: transformedSchema ?? subschemaOrSubschemaConfig, skipTypeMerging, @@ -208,9 +191,9 @@ function validateRequest(delegationContext: DelegationContext, document: Do } function getExecutor(delegationContext: DelegationContext): Executor { - const { subschemaConfig, targetSchema, context, operation } = delegationContext; + const { subschemaConfig, targetSchema, context } = delegationContext; - let executor: Executor = subschemaConfig?.executor || createDefaultExecutor(targetSchema, operation); + let executor: Executor = subschemaConfig?.executor || createDefaultExecutor(targetSchema); if (subschemaConfig?.batch) { const batchingOptions = subschemaConfig?.batchingOptions; @@ -225,26 +208,33 @@ function getExecutor(delegationContext: DelegationContext): return executor; } -function createDefaultExecutor(schema: GraphQLSchema, operation: OperationTypeNode): Executor { - if (operation === 'subscription') { - return (({ document, context, variables, rootValue, operationName }: Request) => - subscribe({ +const defaultExecutorCache = new WeakMap(); + +function createDefaultExecutor(schema: GraphQLSchema): Executor { + let defaultExecutor = defaultExecutorCache.get(schema); + if (!defaultExecutor) { + defaultExecutor = function defaultExecutor({ + document, + context, + variables, + rootValue, + operationName, + operationType, + }: ExecutionRequest) { + const executionArgs: ExecutionArgs = { schema, document, contextValue: context, variableValues: variables, rootValue, operationName, - })) as Executor; + }; + if (operationType === 'subscription') { + return subscribe(executionArgs); + } + return execute(executionArgs); + } as Executor; + defaultExecutorCache.set(schema, defaultExecutor); } - - return (({ document, context, variables, rootValue, operationName }: Request) => - execute({ - schema, - document, - contextValue: context, - variableValues: variables, - rootValue, - operationName, - })) as Executor; + return defaultExecutor; } diff --git a/packages/delegate/src/index.ts b/packages/delegate/src/index.ts index 68f0066911f..cf3f755b8e8 100644 --- a/packages/delegate/src/index.ts +++ b/packages/delegate/src/index.ts @@ -9,4 +9,3 @@ export * from './resolveExternalValue'; export * from './subschemaConfig'; export * from './transforms'; export * from './types'; -export { Executor, AsyncExecutor, SyncExecutor, Request } from '@graphql-tools/utils'; diff --git a/packages/delegate/src/transforms/AddArgumentsAsVariables.ts b/packages/delegate/src/transforms/AddArgumentsAsVariables.ts index dfc77be8397..6326c515e59 100644 --- a/packages/delegate/src/transforms/AddArgumentsAsVariables.ts +++ b/packages/delegate/src/transforms/AddArgumentsAsVariables.ts @@ -10,7 +10,7 @@ import { VariableDefinitionNode, } from 'graphql'; -import { getDefinedRootType, Request, serializeInputValue, updateArgument } from '@graphql-tools/utils'; +import { getDefinedRootType, ExecutionRequest, serializeInputValue, updateArgument } from '@graphql-tools/utils'; import { Transform, DelegationContext } from '../types'; @@ -28,10 +28,10 @@ export default class AddArgumentsAsVariables implements Transform { } public transformRequest( - originalRequest: Request, + originalRequest: ExecutionRequest, delegationContext: DelegationContext, _transformationContext: Record - ): Request { + ): ExecutionRequest { const { document, variables } = addVariablesToRootField(delegationContext.targetSchema, originalRequest, this.args); return { @@ -44,7 +44,7 @@ export default class AddArgumentsAsVariables implements Transform { function addVariablesToRootField( targetSchema: GraphQLSchema, - originalRequest: Request, + originalRequest: ExecutionRequest, args: Record ): { document: DocumentNode; diff --git a/packages/delegate/src/transforms/AddSelectionSets.ts b/packages/delegate/src/transforms/AddSelectionSets.ts index 3ffad61e54a..4a5951c59bc 100644 --- a/packages/delegate/src/transforms/AddSelectionSets.ts +++ b/packages/delegate/src/transforms/AddSelectionSets.ts @@ -1,6 +1,6 @@ import { SelectionSetNode, TypeInfo, Kind, FieldNode, SelectionNode, print } from 'graphql'; -import { Maybe, Request } from '@graphql-tools/utils'; +import { Maybe, ExecutionRequest } from '@graphql-tools/utils'; import { Transform, DelegationContext } from '../types'; import { memoize2 } from '../memoize'; @@ -21,10 +21,10 @@ export default class AddSelectionSets implements Transform { } public transformRequest( - originalRequest: Request, + originalRequest: ExecutionRequest, delegationContext: DelegationContext, transformationContext: Record - ): Request { + ): ExecutionRequest { return this.transformer.transformRequest(originalRequest, delegationContext, transformationContext); } } diff --git a/packages/delegate/src/transforms/AddTypenameToAbstract.ts b/packages/delegate/src/transforms/AddTypenameToAbstract.ts index 0eb25a2416c..f254e17d36a 100644 --- a/packages/delegate/src/transforms/AddTypenameToAbstract.ts +++ b/packages/delegate/src/transforms/AddTypenameToAbstract.ts @@ -10,16 +10,16 @@ import { isAbstractType, } from 'graphql'; -import { Maybe, Request } from '@graphql-tools/utils'; +import { Maybe, ExecutionRequest } from '@graphql-tools/utils'; import { Transform, DelegationContext } from '../types'; export default class AddTypenameToAbstract implements Transform { public transformRequest( - originalRequest: Request, + originalRequest: ExecutionRequest, delegationContext: DelegationContext, _transformationContext: Record - ): Request { + ): ExecutionRequest { const document = addTypenameToAbstract(delegationContext.targetSchema, originalRequest.document); return { ...originalRequest, diff --git a/packages/delegate/src/transforms/ExpandAbstractTypes.ts b/packages/delegate/src/transforms/ExpandAbstractTypes.ts index f320397c209..da26311280b 100644 --- a/packages/delegate/src/transforms/ExpandAbstractTypes.ts +++ b/packages/delegate/src/transforms/ExpandAbstractTypes.ts @@ -15,16 +15,16 @@ import { visitWithTypeInfo, } from 'graphql'; -import { implementsAbstractType, Request } from '@graphql-tools/utils'; +import { implementsAbstractType, ExecutionRequest } from '@graphql-tools/utils'; import { Transform, DelegationContext } from '../types'; export default class ExpandAbstractTypes implements Transform { public transformRequest( - originalRequest: Request, + originalRequest: ExecutionRequest, delegationContext: DelegationContext, _transformationContext: Record - ): Request { + ): ExecutionRequest { const targetSchema = delegationContext.targetSchema; const { possibleTypesMap, interfaceExtensionsMap } = extractPossibleTypes( delegationContext.info.schema, diff --git a/packages/delegate/src/transforms/FilterToSchema.ts b/packages/delegate/src/transforms/FilterToSchema.ts index bb1f6767c5b..5f256405cca 100644 --- a/packages/delegate/src/transforms/FilterToSchema.ts +++ b/packages/delegate/src/transforms/FilterToSchema.ts @@ -21,16 +21,16 @@ import { isInterfaceType, } from 'graphql'; -import { Request, implementsAbstractType, TypeMap, getDefinedRootType } from '@graphql-tools/utils'; +import { ExecutionRequest, implementsAbstractType, TypeMap, getDefinedRootType } from '@graphql-tools/utils'; import { Transform, DelegationContext } from '../types'; export default class FilterToSchema implements Transform { public transformRequest( - originalRequest: Request, + originalRequest: ExecutionRequest, delegationContext: DelegationContext, _transformationContext: Record - ): Request { + ): ExecutionRequest { return { ...originalRequest, ...filterToSchema(delegationContext.targetSchema, originalRequest.document, originalRequest.variables), diff --git a/packages/delegate/src/transforms/VisitSelectionSets.ts b/packages/delegate/src/transforms/VisitSelectionSets.ts index 0c7acb9efaf..1b131eddcec 100644 --- a/packages/delegate/src/transforms/VisitSelectionSets.ts +++ b/packages/delegate/src/transforms/VisitSelectionSets.ts @@ -13,7 +13,13 @@ import { DefinitionNode, } from 'graphql'; -import { Request, collectFields, GraphQLExecutionContext, Maybe, getDefinedRootType } from '@graphql-tools/utils'; +import { + ExecutionRequest, + collectFields, + GraphQLExecutionContext, + Maybe, + getDefinedRootType, +} from '@graphql-tools/utils'; import { Transform, DelegationContext } from '../types'; @@ -27,10 +33,10 @@ export default class VisitSelectionSets implements Transform { } public transformRequest( - originalRequest: Request, + originalRequest: ExecutionRequest, delegationContext: DelegationContext, _transformationContext: Record - ): Request { + ): ExecutionRequest { const document = visitSelectionSets( originalRequest, delegationContext.info.schema, @@ -45,7 +51,7 @@ export default class VisitSelectionSets implements Transform { } function visitSelectionSets( - request: Request, + request: ExecutionRequest, schema: GraphQLSchema, initialType: GraphQLOutputType, visitor: VisitSelectionSetsVisitor diff --git a/packages/delegate/src/transforms/WrapConcreteTypes.ts b/packages/delegate/src/transforms/WrapConcreteTypes.ts index 4b12e78a900..8a252904293 100644 --- a/packages/delegate/src/transforms/WrapConcreteTypes.ts +++ b/packages/delegate/src/transforms/WrapConcreteTypes.ts @@ -13,7 +13,7 @@ import { FragmentDefinitionNode, } from 'graphql'; -import { getRootTypeNames, Request } from '@graphql-tools/utils'; +import { getRootTypeNames, ExecutionRequest } from '@graphql-tools/utils'; import { Transform, DelegationContext } from '../types'; @@ -21,10 +21,10 @@ import { Transform, DelegationContext } from '../types'; export default class WrapConcreteTypes implements Transform { public transformRequest( - originalRequest: Request, + originalRequest: ExecutionRequest, delegationContext: DelegationContext, _transformationContext: Record - ): Request { + ): ExecutionRequest { const document = wrapConcreteTypes( delegationContext.returnType, delegationContext.targetSchema, diff --git a/packages/delegate/src/types.ts b/packages/delegate/src/types.ts index 17c101a03c6..5b0dcaee820 100644 --- a/packages/delegate/src/types.ts +++ b/packages/delegate/src/types.ts @@ -14,7 +14,7 @@ import { import DataLoader from 'dataloader'; -import { Request, ExecutionResult, Executor, TypeMap } from '@graphql-tools/utils'; +import { ExecutionRequest, ExecutionResult, Executor, TypeMap } from '@graphql-tools/utils'; import { Subschema } from './Subschema'; import { OBJECT_SUBSCHEMA_SYMBOL, FIELD_SUBSCHEMA_MAP_SYMBOL, UNPATHED_ERRORS_SYMBOL } from './symbols'; @@ -25,10 +25,10 @@ export type SchemaTransform> = ( transformedSchema?: GraphQLSchema ) => GraphQLSchema; export type RequestTransform> = ( - originalRequest: Request, + originalRequest: ExecutionRequest, delegationContext: DelegationContext, transformationContext: T -) => Request; +) => ExecutionRequest; export type ResultTransform> = ( originalResult: ExecutionResult, delegationContext: DelegationContext, @@ -56,7 +56,6 @@ export interface DelegationContext> { transforms: Array>; transformedSchema: GraphQLSchema; skipTypeMerging: boolean; - operationName?: string; } export type DelegationBinding> = ( @@ -85,7 +84,7 @@ export interface IDelegateToSchemaOptions, TArgs export interface IDelegateRequestOptions, TArgs = Record> extends IDelegateToSchemaOptions { - request: Request; + request: ExecutionRequest; } export interface ICreateRequestFromInfo { @@ -96,6 +95,7 @@ export interface ICreateRequestFromInfo { fieldName?: string; selectionSet?: SelectionSetNode; fieldNodes?: ReadonlyArray; + context?: any; } export interface ICreateRequest { @@ -111,6 +111,8 @@ export interface ICreateRequest { targetFieldName: string; selectionSet?: SelectionSetNode; fieldNodes?: ReadonlyArray; + context?: any; + info?: GraphQLResolveInfo; } export interface MergedTypeInfo> { @@ -137,7 +139,7 @@ export type CreateProxyingResolverFn> = ( ) => GraphQLFieldResolver; export interface BatchingOptions { - extensionsReducer?: (mergedExtensions: Record, request: Request) => Record; + extensionsReducer?: (mergedExtensions: Record, request: ExecutionRequest) => Record; dataLoaderOptions?: DataLoader.Options; } diff --git a/packages/delegate/tests/batchExecution.test.ts b/packages/delegate/tests/batchExecution.test.ts index 93c82b8a0a0..51972c15444 100644 --- a/packages/delegate/tests/batchExecution.test.ts +++ b/packages/delegate/tests/batchExecution.test.ts @@ -1,9 +1,10 @@ import { graphql, execute, ExecutionResult } from 'graphql'; import { makeExecutableSchema } from '@graphql-tools/schema'; -import { delegateToSchema, SubschemaConfig, Request, SyncExecutor, Executor } from '../src'; +import { delegateToSchema, SubschemaConfig } from '../src'; import { stitchSchemas } from '@graphql-tools/stitch'; import { FilterObjectFields } from '@graphql-tools/wrap'; +import { ExecutionRequest, Executor, SyncExecutor } from '@graphql-tools/utils'; describe('batch execution', () => { it('should batch', async () => { @@ -27,7 +28,7 @@ describe('batch execution', () => { const innerSubschemaConfig: SubschemaConfig = { schema: innerSchema, batch: true, - executor: ((request: Request): ExecutionResult => { + executor: ((request: ExecutionRequest): ExecutionResult => { executions++; return execute(innerSchema, request.document, undefined, request.context, request.variables) as ExecutionResult; }) as SyncExecutor @@ -104,7 +105,7 @@ describe('batch execution', () => { let executions = 0; - const executor = ((request: Request): ExecutionResult => { + const executor = ((request: ExecutionRequest): ExecutionResult => { executions++; return execute(innerSchemaA, request.document, undefined, request.context, request.variables) as ExecutionResult; }) as Executor; diff --git a/packages/links/src/linkToExecutor.ts b/packages/links/src/linkToExecutor.ts index 685cd37612c..854e05bcc5f 100644 --- a/packages/links/src/linkToExecutor.ts +++ b/packages/links/src/linkToExecutor.ts @@ -2,12 +2,12 @@ import { toPromise } from '@apollo/client/core'; import { ApolloLink, execute } from '@apollo/client/link/core'; import { Observable } from '@apollo/client/utilities'; -import { Executor, Request, ExecutionResult, observableToAsyncIterable } from '@graphql-tools/utils'; +import { Executor, ExecutionRequest, ExecutionResult, observableToAsyncIterable } from '@graphql-tools/utils'; export const linkToExecutor = (link: ApolloLink): Executor => - async (request: Request) => { - const { document, variables, extensions, context, info, operationName } = request; + async (params: ExecutionRequest) => { + const { document, variables, extensions, context, operationType, operationName, info } = params; const observable = execute(link, { query: document, variables, @@ -19,7 +19,7 @@ export const linkToExecutor = extensions, operationName, }) as Observable>; - if (info?.operation.operation === 'subscription') { + if (operationType === 'subscription') { return observableToAsyncIterable>(observable)[Symbol.asyncIterator](); } return toPromise(observable); diff --git a/packages/loaders/url/src/index.ts b/packages/loaders/url/src/index.ts index 2af5fe7f9cc..090d72c7141 100644 --- a/packages/loaders/url/src/index.ts +++ b/packages/loaders/url/src/index.ts @@ -11,7 +11,7 @@ import { BaseLoaderOptions, observableToAsyncIterable, isAsyncIterable, - Request, + ExecutionRequest, mapAsyncIterator, withCancel, parseGraphQLSDL, @@ -304,12 +304,12 @@ export class UrlLoader implements Loader { variables, operationName, extensions, - }: Request) => { + operationType, + }: ExecutionRequest) => { const controller = new AbortController(); let method = defaultMethod; if (options?.useGETForQueries) { - const operationAst = getOperationAST(document, operationName); - if (operationAst?.operation === 'query') { + if (operationType === 'query') { method = 'GET'; } else { method = defaultMethod; @@ -472,7 +472,7 @@ export class UrlLoader implements Loader { webSocketImpl ); - return async ({ document, variables, operationName }: Request) => { + return async ({ document, variables, operationName }: ExecutionRequest) => { return observableToAsyncIterable( subscriptionClient.request({ query: document, @@ -619,7 +619,7 @@ export class UrlLoader implements Loader { throw new Error(`No valid operations found: ${params.operationName || ''}`); } if ( - operationAst.operation === 'subscription' || + params.operationType === 'subscription' || isLiveQueryOperationDefinitionNode(operationAst, params.variables as Record) ) { return subscriptionExecutor(params); diff --git a/packages/stitch/tests/errors.test.ts b/packages/stitch/tests/errors.test.ts index b9571d460df..6154b4e16ce 100644 --- a/packages/stitch/tests/errors.test.ts +++ b/packages/stitch/tests/errors.test.ts @@ -1,9 +1,8 @@ import { graphql, GraphQLError, buildSchema } from 'graphql'; -import { Executor } from '@graphql-tools/delegate'; import { makeExecutableSchema } from '@graphql-tools/schema'; import { stitchSchemas } from '@graphql-tools/stitch'; -import { assertSome, ExecutionResult } from '@graphql-tools/utils'; +import { assertSome, ExecutionResult, Executor } from '@graphql-tools/utils'; describe('passes along errors for missing fields on list', () => { test('if non-null', async () => { diff --git a/packages/stitch/tests/fixtures/schemas.ts b/packages/stitch/tests/fixtures/schemas.ts index 9364d9747da..7b3e7555346 100644 --- a/packages/stitch/tests/fixtures/schemas.ts +++ b/packages/stitch/tests/fixtures/schemas.ts @@ -22,10 +22,11 @@ import { ExecutionResult, mapAsyncIterator, isAsyncIterable, + ExecutionRequest, } from '@graphql-tools/utils'; import { makeExecutableSchema } from '@graphql-tools/schema'; -import { Request, SubschemaConfig } from '@graphql-tools/delegate'; +import { SubschemaConfig } from '@graphql-tools/delegate'; export class CustomError extends GraphQLError { constructor(message: string, extensions: Record) { @@ -682,8 +683,8 @@ export const subscriptionSchema: GraphQLSchema = makeExecutableSchema({ }); function makeExecutorFromSchema(schema: GraphQLSchema) { - return async ({ document, variables, context, info }: Request) => { - if (info?.operation.operation === 'subscription') { + return async ({ document, variables, context, operationType }: ExecutionRequest) => { + if (operationType === 'subscription') { const result = subscribe( schema, document, diff --git a/packages/utils/src/Interfaces.ts b/packages/utils/src/Interfaces.ts index 22cc148dc34..5dde9a8d595 100644 --- a/packages/utils/src/Interfaces.ts +++ b/packages/utils/src/Interfaces.ts @@ -48,6 +48,7 @@ import { GraphQLType, Source, DefinitionNode, + OperationTypeNode, } from 'graphql'; // graphql-js < v15 backwards compatible ExecutionResult @@ -58,13 +59,14 @@ export interface ExecutionResult> extends GraphQLExe extensions?: Record; } -export interface Request< +export interface ExecutionRequest< TArgs extends Record = Record, TContext = any, TRootValue = any, TExtensions = Record > { document: DocumentNode; + operationType: OperationTypeNode; variables?: TArgs; extensions?: TExtensions; operationName?: string; diff --git a/packages/utils/src/executor.ts b/packages/utils/src/executor.ts index 45fd4e18747..b6463179c75 100644 --- a/packages/utils/src/executor.ts +++ b/packages/utils/src/executor.ts @@ -1,4 +1,4 @@ -import { ExecutionResult, Request } from './Interfaces'; +import { ExecutionResult, ExecutionRequest } from './Interfaces'; type MaybePromise = Promise | T; type MaybeAsyncIterableIterator = AsyncIterableIterator | T; @@ -10,7 +10,7 @@ export type AsyncExecutor, TBaseExtensions = TRoot = any, TExtensions extends TBaseExtensions = TBaseExtensions >( - request: Request + request: ExecutionRequest ) => Promise>>; export type SyncExecutor, TBaseExtensions = Record> = < @@ -20,7 +20,7 @@ export type SyncExecutor, TBaseExtensions = R TRoot = any, TExtensions extends TBaseExtensions = TBaseExtensions >( - request: Request + request: ExecutionRequest ) => ExecutionResult; export type Executor, TBaseExtensions = Record> = < @@ -30,5 +30,5 @@ export type Executor, TBaseExtensions = Recor TRoot = any, TExtensions extends TBaseExtensions = TBaseExtensions >( - request: Request + request: ExecutionRequest ) => MaybePromise>>; diff --git a/packages/utils/src/visitResult.ts b/packages/utils/src/visitResult.ts index f71725fd41f..dad14ecbc18 100644 --- a/packages/utils/src/visitResult.ts +++ b/packages/utils/src/visitResult.ts @@ -15,7 +15,7 @@ import { TypeNameMetaFieldDef, } from 'graphql'; -import { Request, GraphQLExecutionContext, ExecutionResult } from './Interfaces'; +import { ExecutionRequest, GraphQLExecutionContext, ExecutionResult } from './Interfaces'; import { collectFields } from './collectFields'; import { Maybe } from '@graphql-tools/utils'; @@ -77,7 +77,7 @@ export function visitErrors( } export function visitResult( result: ExecutionResult, - request: Request, + request: ExecutionRequest, schema: GraphQLSchema, resultVisitorMap?: ResultVisitorMap, errorVisitorMap?: ErrorVisitorMap diff --git a/packages/utils/tests/visitResult.test.ts b/packages/utils/tests/visitResult.test.ts index e67ca1a38fd..067e1c38852 100644 --- a/packages/utils/tests/visitResult.test.ts +++ b/packages/utils/tests/visitResult.test.ts @@ -22,6 +22,7 @@ describe('visiting results', () => { const request = { document: parse('{ test { field } }'), variables: {}, + operationType: 'query' as const }; it('should visit without throwing', async () => { @@ -45,7 +46,8 @@ describe('visiting results', () => { it('should visit with a request with introspection fields without throwing', async () => { const introspectionRequest = { document: parse('{ test { field __typename } }'), - variables: {} + variables: {}, + operationType: 'query' as const }; const result = { data: { @@ -226,6 +228,7 @@ describe('visiting nested results', () => { } }`), variables: {}, + operationType: 'query' as const, }; it('should work', async () => { @@ -293,6 +296,7 @@ describe('visiting nested results', () => { } }`), variables: {}, + operationType: 'query' as const, }; it('should work', async () => { @@ -352,6 +356,7 @@ describe('visiting errors', () => { const request = { document: parse('{ test { field } }'), variables: {}, + operationType: 'query' as const, }; it('should allow visiting without an errorVisitor', async () => { diff --git a/packages/wrap/src/introspect.ts b/packages/wrap/src/introspect.ts index 6a11a74e545..b0130db1501 100644 --- a/packages/wrap/src/introspect.ts +++ b/packages/wrap/src/introspect.ts @@ -56,6 +56,7 @@ export function introspectSchema( return new ValueOrPromise(() => executor({ document: parsedIntrospectionQuery, + operationType: 'query', context, }) ) diff --git a/packages/wrap/src/transforms/ExtractField.ts b/packages/wrap/src/transforms/ExtractField.ts index 787372bf7f7..8d5d881118f 100644 --- a/packages/wrap/src/transforms/ExtractField.ts +++ b/packages/wrap/src/transforms/ExtractField.ts @@ -1,6 +1,6 @@ import { visit, Kind, SelectionSetNode, BREAK, FieldNode } from 'graphql'; -import { Request } from '@graphql-tools/utils'; +import { ExecutionRequest } from '@graphql-tools/utils'; import { Transform, DelegationContext } from '@graphql-tools/delegate'; @@ -14,10 +14,10 @@ export default class ExtractField implements Transform { } public transformRequest( - originalRequest: Request, + originalRequest: ExecutionRequest, _delegationContext: DelegationContext, _transformationContext: Record - ): Request { + ): ExecutionRequest { let fromSelection: SelectionSetNode | undefined; const ourPathFrom = JSON.stringify(this.from); const ourPathTo = JSON.stringify(this.to); diff --git a/packages/wrap/src/transforms/FilterInputObjectFields.ts b/packages/wrap/src/transforms/FilterInputObjectFields.ts index e5b4158fc2c..01533e42674 100644 --- a/packages/wrap/src/transforms/FilterInputObjectFields.ts +++ b/packages/wrap/src/transforms/FilterInputObjectFields.ts @@ -1,6 +1,6 @@ import { GraphQLSchema, GraphQLInputFieldConfig } from 'graphql'; -import { Request, InputFieldFilter } from '@graphql-tools/utils'; +import { ExecutionRequest, InputFieldFilter } from '@graphql-tools/utils'; import { Transform, DelegationContext, SubschemaConfig } from '@graphql-tools/delegate'; @@ -29,10 +29,10 @@ export default class FilterInputObjectFields implements Transform { } public transformRequest( - originalRequest: Request, + originalRequest: ExecutionRequest, delegationContext: DelegationContext, transformationContext: Record - ): Request { + ): ExecutionRequest { return this.transformer.transformRequest(originalRequest, delegationContext, transformationContext); } } diff --git a/packages/wrap/src/transforms/HoistField.ts b/packages/wrap/src/transforms/HoistField.ts index 299c9fcd45d..c94590c753a 100644 --- a/packages/wrap/src/transforms/HoistField.ts +++ b/packages/wrap/src/transforms/HoistField.ts @@ -9,7 +9,13 @@ import { GraphQLFieldResolver, } from 'graphql'; -import { appendObjectFields, removeObjectFields, Request, ExecutionResult, relocatedError } from '@graphql-tools/utils'; +import { + appendObjectFields, + removeObjectFields, + ExecutionRequest, + ExecutionResult, + relocatedError, +} from '@graphql-tools/utils'; import { Transform, defaultMergedResolver, DelegationContext, SubschemaConfig } from '@graphql-tools/delegate'; @@ -153,10 +159,10 @@ export default class HoistField implements Transform { } public transformRequest( - originalRequest: Request, + originalRequest: ExecutionRequest, delegationContext: DelegationContext, transformationContext: Record - ): Request { + ): ExecutionRequest { return this.transformer.transformRequest(originalRequest, delegationContext, transformationContext); } diff --git a/packages/wrap/src/transforms/MapFields.ts b/packages/wrap/src/transforms/MapFields.ts index 0580fa0f604..1f530da717f 100644 --- a/packages/wrap/src/transforms/MapFields.ts +++ b/packages/wrap/src/transforms/MapFields.ts @@ -1,6 +1,6 @@ import { GraphQLSchema } from 'graphql'; -import { Request, FieldNodeMappers, ExecutionResult } from '@graphql-tools/utils'; +import { ExecutionRequest, FieldNodeMappers, ExecutionResult } from '@graphql-tools/utils'; import { Transform, DelegationContext, SubschemaConfig } from '@graphql-tools/delegate'; @@ -85,10 +85,10 @@ export default class MapFields implements Transform { } public transformRequest( - originalRequest: Request, + originalRequest: ExecutionRequest, delegationContext: DelegationContext, transformationContext: Record - ): Request { + ): ExecutionRequest { return this._getTransformer().transformRequest(originalRequest, delegationContext, transformationContext); } diff --git a/packages/wrap/src/transforms/MapLeafValues.ts b/packages/wrap/src/transforms/MapLeafValues.ts index a8d7d6bc23d..fb3ce7945e4 100644 --- a/packages/wrap/src/transforms/MapLeafValues.ts +++ b/packages/wrap/src/transforms/MapLeafValues.ts @@ -14,7 +14,7 @@ import { } from 'graphql'; import { - Request, + ExecutionRequest, ExecutionResult, visitResult, ResultVisitorMap, @@ -27,7 +27,7 @@ import { Transform, DelegationContext, SubschemaConfig } from '@graphql-tools/de import { LeafValueTransformer } from '../types'; export interface MapLeafValuesTransformationContext { - transformedRequest: Request; + transformedRequest: ExecutionRequest; } export default class MapLeafValues implements Transform { @@ -83,10 +83,10 @@ export default class MapLeafValues implements Transform - ): Request { + ): ExecutionRequest { return this.transformer.transformRequest(originalRequest, delegationContext, transformationContext); } } diff --git a/packages/wrap/src/transforms/RenameInterfaceFields.ts b/packages/wrap/src/transforms/RenameInterfaceFields.ts index 091b98c9c6b..3388cd699f5 100644 --- a/packages/wrap/src/transforms/RenameInterfaceFields.ts +++ b/packages/wrap/src/transforms/RenameInterfaceFields.ts @@ -1,6 +1,6 @@ import { GraphQLSchema, GraphQLFieldConfig } from 'graphql'; -import { Request } from '@graphql-tools/utils'; +import { ExecutionRequest } from '@graphql-tools/utils'; import { Transform, DelegationContext, SubschemaConfig } from '@graphql-tools/delegate'; @@ -27,10 +27,10 @@ export default class RenameInterfaceFields implements Transform { } public transformRequest( - originalRequest: Request, + originalRequest: ExecutionRequest, delegationContext: DelegationContext, transformationContext: Record - ): Request { + ): ExecutionRequest { return this.transformer.transformRequest(originalRequest, delegationContext, transformationContext); } } diff --git a/packages/wrap/src/transforms/RenameObjectFields.ts b/packages/wrap/src/transforms/RenameObjectFields.ts index c763a82844e..4583e55c4b1 100644 --- a/packages/wrap/src/transforms/RenameObjectFields.ts +++ b/packages/wrap/src/transforms/RenameObjectFields.ts @@ -1,6 +1,6 @@ import { GraphQLSchema, GraphQLFieldConfig } from 'graphql'; -import { Request } from '@graphql-tools/utils'; +import { ExecutionRequest } from '@graphql-tools/utils'; import { Transform, DelegationContext, SubschemaConfig } from '@graphql-tools/delegate'; @@ -27,10 +27,10 @@ export default class RenameObjectFields implements Transform { } public transformRequest( - originalRequest: Request, + originalRequest: ExecutionRequest, delegationContext: DelegationContext, transformationContext: Record - ): Request { + ): ExecutionRequest { return this.transformer.transformRequest(originalRequest, delegationContext, transformationContext); } } diff --git a/packages/wrap/src/transforms/RenameRootFields.ts b/packages/wrap/src/transforms/RenameRootFields.ts index 6db0d3c39b9..caa437f46a4 100644 --- a/packages/wrap/src/transforms/RenameRootFields.ts +++ b/packages/wrap/src/transforms/RenameRootFields.ts @@ -1,6 +1,6 @@ import { GraphQLSchema, GraphQLFieldConfig } from 'graphql'; -import { Request } from '@graphql-tools/utils'; +import { ExecutionRequest } from '@graphql-tools/utils'; import { Transform, DelegationContext, SubschemaConfig } from '@graphql-tools/delegate'; @@ -34,10 +34,10 @@ export default class RenameRootFields implements Transform { } public transformRequest( - originalRequest: Request, + originalRequest: ExecutionRequest, delegationContext: DelegationContext, transformationContext: Record - ): Request { + ): ExecutionRequest { return this.transformer.transformRequest(originalRequest, delegationContext, transformationContext); } } diff --git a/packages/wrap/src/transforms/RenameRootTypes.ts b/packages/wrap/src/transforms/RenameRootTypes.ts index 3d3f06d5aa0..63b4805da61 100644 --- a/packages/wrap/src/transforms/RenameRootTypes.ts +++ b/packages/wrap/src/transforms/RenameRootTypes.ts @@ -1,6 +1,6 @@ import { visit, GraphQLSchema, NamedTypeNode, Kind } from 'graphql'; -import { Request, ExecutionResult, MapperKind, mapSchema, renameType, visitData } from '@graphql-tools/utils'; +import { ExecutionRequest, ExecutionResult, MapperKind, mapSchema, renameType, visitData } from '@graphql-tools/utils'; import { Transform, DelegationContext, SubschemaConfig } from '@graphql-tools/delegate'; @@ -35,10 +35,10 @@ export default class RenameRootTypes implements Transform { } public transformRequest( - originalRequest: Request, + originalRequest: ExecutionRequest, _delegationContext: DelegationContext, _transformationContext: Record - ): Request { + ): ExecutionRequest { const document = visit(originalRequest.document, { [Kind.NAMED_TYPE]: (node: NamedTypeNode) => { const name = node.name.value; diff --git a/packages/wrap/src/transforms/RenameTypes.ts b/packages/wrap/src/transforms/RenameTypes.ts index 00a207b358e..664789e9ed3 100644 --- a/packages/wrap/src/transforms/RenameTypes.ts +++ b/packages/wrap/src/transforms/RenameTypes.ts @@ -9,7 +9,7 @@ import { } from 'graphql'; import { - Request, + ExecutionRequest, ExecutionResult, MapperKind, RenameTypesOptions, @@ -66,10 +66,10 @@ export default class RenameTypes implements Transform { } public transformRequest( - originalRequest: Request, + originalRequest: ExecutionRequest, _delegationContext: DelegationContext, _transformationContext: Record - ): Request { + ): ExecutionRequest { const document = visit(originalRequest.document, { [Kind.NAMED_TYPE]: (node: NamedTypeNode) => { const name = node.name.value; diff --git a/packages/wrap/src/transforms/TransformCompositeFields.ts b/packages/wrap/src/transforms/TransformCompositeFields.ts index 53d2c3945fd..99be7cf41e8 100644 --- a/packages/wrap/src/transforms/TransformCompositeFields.ts +++ b/packages/wrap/src/transforms/TransformCompositeFields.ts @@ -11,7 +11,7 @@ import { FragmentDefinitionNode, } from 'graphql'; -import { Request, MapperKind, mapSchema, visitData, ExecutionResult, Maybe } from '@graphql-tools/utils'; +import { ExecutionRequest, MapperKind, mapSchema, visitData, ExecutionResult, Maybe } from '@graphql-tools/utils'; import { Transform, DelegationContext, SubschemaConfig } from '@graphql-tools/delegate'; @@ -78,10 +78,10 @@ export default class TransformCompositeFields> im } public transformRequest( - originalRequest: Request, + originalRequest: ExecutionRequest, _delegationContext: DelegationContext, transformationContext: Record - ): Request { + ): ExecutionRequest { const document = originalRequest.document; const fragments = Object.create(null); for (const def of document.definitions) { diff --git a/packages/wrap/src/transforms/TransformEnumValues.ts b/packages/wrap/src/transforms/TransformEnumValues.ts index 29a6fba90ce..817aaf928bd 100644 --- a/packages/wrap/src/transforms/TransformEnumValues.ts +++ b/packages/wrap/src/transforms/TransformEnumValues.ts @@ -1,6 +1,6 @@ import { GraphQLSchema, GraphQLEnumValueConfig, ExecutionResult } from 'graphql'; -import { Request, MapperKind, mapSchema, Maybe } from '@graphql-tools/utils'; +import { ExecutionRequest, MapperKind, mapSchema, Maybe } from '@graphql-tools/utils'; import { Transform, DelegationContext, SubschemaConfig } from '@graphql-tools/delegate'; @@ -43,10 +43,10 @@ export default class TransformEnumValues implements Transform - ): Request { + ): ExecutionRequest { const variableValues = originalRequest.variables ?? {}; const fragments = Object.create(null); @@ -152,7 +152,7 @@ export default class TransformInputObjectFields implements Transform { mapping: Record>, inputFieldNodeTransformer: InputFieldNodeTransformer | undefined, inputObjectNodeTransformer: InputObjectNodeTransformer | undefined, - request: Request, + request: ExecutionRequest, delegationContext?: DelegationContext ): DocumentNode { const typeInfo = new TypeInfo(this._getTransformedSchema()); diff --git a/packages/wrap/src/transforms/TransformInterfaceFields.ts b/packages/wrap/src/transforms/TransformInterfaceFields.ts index e3a3f1da00d..444c98e0500 100644 --- a/packages/wrap/src/transforms/TransformInterfaceFields.ts +++ b/packages/wrap/src/transforms/TransformInterfaceFields.ts @@ -1,6 +1,6 @@ import { GraphQLSchema, isInterfaceType, GraphQLFieldConfig } from 'graphql'; -import { Request, ExecutionResult } from '@graphql-tools/utils'; +import { ExecutionRequest, ExecutionResult } from '@graphql-tools/utils'; import { Transform, DelegationContext, SubschemaConfig } from '@graphql-tools/delegate'; @@ -51,10 +51,10 @@ export default class TransformInterfaceFields implements Transform { } public transformRequest( - originalRequest: Request, + originalRequest: ExecutionRequest, delegationContext: DelegationContext, transformationContext: Record - ): Request { + ): ExecutionRequest { return this._getTransformer().transformRequest(originalRequest, delegationContext, transformationContext); } diff --git a/packages/wrap/src/transforms/TransformObjectFields.ts b/packages/wrap/src/transforms/TransformObjectFields.ts index 0869c96832c..82364c71291 100644 --- a/packages/wrap/src/transforms/TransformObjectFields.ts +++ b/packages/wrap/src/transforms/TransformObjectFields.ts @@ -1,6 +1,6 @@ import { GraphQLSchema, isObjectType, GraphQLFieldConfig } from 'graphql'; -import { Request, ExecutionResult } from '@graphql-tools/utils'; +import { ExecutionRequest, ExecutionResult } from '@graphql-tools/utils'; import { Transform, DelegationContext, SubschemaConfig } from '@graphql-tools/delegate'; @@ -51,10 +51,10 @@ export default class TransformObjectFields implements Transform { } public transformRequest( - originalRequest: Request, + originalRequest: ExecutionRequest, delegationContext: DelegationContext, transformationContext: Record - ): Request { + ): ExecutionRequest { return this._getTransformer().transformRequest(originalRequest, delegationContext, transformationContext); } diff --git a/packages/wrap/src/transforms/TransformQuery.ts b/packages/wrap/src/transforms/TransformQuery.ts index 6a1690a4b53..3143d523250 100644 --- a/packages/wrap/src/transforms/TransformQuery.ts +++ b/packages/wrap/src/transforms/TransformQuery.ts @@ -1,6 +1,6 @@ import { visit, Kind, SelectionSetNode, FragmentDefinitionNode, GraphQLError } from 'graphql'; -import { Request, ExecutionResult, relocatedError } from '@graphql-tools/utils'; +import { ExecutionRequest, ExecutionResult, relocatedError } from '@graphql-tools/utils'; import { Transform, DelegationContext } from '@graphql-tools/delegate'; @@ -47,10 +47,10 @@ export default class TransformQuery implements Transform { } public transformRequest( - originalRequest: Request, + originalRequest: ExecutionRequest, delegationContext: DelegationContext, transformationContext: Record - ): Request { + ): ExecutionRequest { const pathLength = this.path.length; let index = 0; const document = visit(originalRequest.document, { diff --git a/packages/wrap/src/transforms/TransformRootFields.ts b/packages/wrap/src/transforms/TransformRootFields.ts index 8521c2a2ea7..abd8b5be9bf 100644 --- a/packages/wrap/src/transforms/TransformRootFields.ts +++ b/packages/wrap/src/transforms/TransformRootFields.ts @@ -1,6 +1,6 @@ import { GraphQLSchema, GraphQLFieldConfig } from 'graphql'; -import { Request, ExecutionResult } from '@graphql-tools/utils'; +import { ExecutionRequest, ExecutionResult } from '@graphql-tools/utils'; import { Transform, DelegationContext, SubschemaConfig } from '@graphql-tools/delegate'; @@ -59,10 +59,10 @@ export default class TransformRootFields implements Transform { } public transformRequest( - originalRequest: Request, + originalRequest: ExecutionRequest, delegationContext: DelegationContext, transformationContext: Record - ): Request { + ): ExecutionRequest { return this._getTransformer().transformRequest(originalRequest, delegationContext, transformationContext); } diff --git a/packages/wrap/src/transforms/WrapFields.ts b/packages/wrap/src/transforms/WrapFields.ts index e6e4702d423..395fe81549a 100644 --- a/packages/wrap/src/transforms/WrapFields.ts +++ b/packages/wrap/src/transforms/WrapFields.ts @@ -12,7 +12,7 @@ import { } from 'graphql'; import { - Request, + ExecutionRequest, appendObjectFields, selectObjectFields, modifyObjectFields, @@ -159,10 +159,10 @@ export default class WrapFields implements Transform - ): Request { + ): ExecutionRequest { const fieldPath: Array = []; const ourPath = JSON.stringify(this.path); const document = visit(originalRequest.document, { diff --git a/packages/wrap/src/transforms/WrapType.ts b/packages/wrap/src/transforms/WrapType.ts index 8d32d768675..fa9d3725927 100644 --- a/packages/wrap/src/transforms/WrapType.ts +++ b/packages/wrap/src/transforms/WrapType.ts @@ -1,6 +1,6 @@ import { GraphQLSchema } from 'graphql'; -import { Request, ExecutionResult } from '@graphql-tools/utils'; +import { ExecutionRequest, ExecutionResult } from '@graphql-tools/utils'; import { Transform, DelegationContext, SubschemaConfig } from '@graphql-tools/delegate'; @@ -22,10 +22,10 @@ export default class WrapType implements Transform { } public transformRequest( - originalRequest: Request, + originalRequest: ExecutionRequest, delegationContext: DelegationContext, transformationContext: Record - ): Request { + ): ExecutionRequest { return this.transformer.transformRequest(originalRequest, delegationContext, transformationContext as any); } diff --git a/packages/wrap/src/types.ts b/packages/wrap/src/types.ts index 2ff018fd6c9..2e6a7ead9d4 100644 --- a/packages/wrap/src/types.ts +++ b/packages/wrap/src/types.ts @@ -10,7 +10,7 @@ import { GraphQLEnumValueConfig, } from 'graphql'; import { DelegationContext } from '@graphql-tools/delegate'; -import { Request, Maybe } from '@graphql-tools/utils'; +import { ExecutionRequest, Maybe } from '@graphql-tools/utils'; export type InputFieldTransformer = ( typeName: string, @@ -22,14 +22,14 @@ export type InputFieldNodeTransformer = ( typeName: string, fieldName: string, inputFieldNode: ObjectFieldNode, - request: Request, + request: ExecutionRequest, delegationContext?: DelegationContext ) => ObjectFieldNode | Array; export type InputObjectNodeTransformer = ( typeName: string, inputObjectNode: ObjectValueNode, - request: Request, + request: ExecutionRequest, delegationContext?: DelegationContext ) => ObjectValueNode | undefined; diff --git a/packages/wrap/tests/fixtures/schemas.ts b/packages/wrap/tests/fixtures/schemas.ts index 172ea0debf9..d413c9ec9f1 100644 --- a/packages/wrap/tests/fixtures/schemas.ts +++ b/packages/wrap/tests/fixtures/schemas.ts @@ -18,11 +18,12 @@ import { introspectSchema } from '../../src/introspect'; import { IResolvers, ExecutionResult, - mapAsyncIterator, isAsyncIterable, + AsyncExecutor, + ExecutionRequest, } from '@graphql-tools/utils'; import { makeExecutableSchema } from '@graphql-tools/schema'; -import { SubschemaConfig, Request } from '@graphql-tools/delegate'; +import { SubschemaConfig } from '@graphql-tools/delegate'; export class CustomError extends GraphQLError { constructor(message: string, extensions: Record) { @@ -677,9 +678,9 @@ export const subscriptionSchema: GraphQLSchema = makeExecutableSchema({ resolvers: subscriptionResolvers, }); -function makeExecutorFromSchema(schema: GraphQLSchema) { - return async ({ document, variables, context, info }: Request) => { - if (info?.operation.operation === 'subscription') { +function makeExecutorFromSchema(schema: GraphQLSchema): AsyncExecutor { + return async ({ document, variables, context, operationType }: ExecutionRequest) => { + if (operationType === 'subscription') { const result = await subscribe( schema, document, @@ -688,9 +689,9 @@ function makeExecutorFromSchema(schema: GraphQLSchema) { variables, ); if (isAsyncIterable>(result)) { - return mapAsyncIterator, TReturn>(result, (originalResult: ExecutionResult) => JSON.parse(JSON.stringify(originalResult))); + return result; } - return JSON.parse(JSON.stringify(result)); + return result; } return (new ValueOrPromise(() => graphql( schema, @@ -700,7 +701,7 @@ function makeExecutorFromSchema(schema: GraphQLSchema) { variables, )) .then(originalResult => JSON.parse(JSON.stringify(originalResult))) - .resolve()) as Promise> | ExecutionResult; + .resolve()); }; } diff --git a/packages/wrap/tests/requests.test.ts b/packages/wrap/tests/requests.test.ts index 3a87fbb520f..4c66ec613e6 100644 --- a/packages/wrap/tests/requests.test.ts +++ b/packages/wrap/tests/requests.test.ts @@ -50,7 +50,10 @@ describe('requests', () => { `), rootValue: undefined, variables: {}, - operationName: 'test' + operationName: 'test', + operationType: 'query', + context: undefined, + info: undefined, }); expect(expectedRequest).toMatchObject(request); diff --git a/packages/wrap/tests/transformFilterToSchema.test.ts b/packages/wrap/tests/transformFilterToSchema.test.ts index 4a752c0a76f..fb5d2385501 100644 --- a/packages/wrap/tests/transformFilterToSchema.test.ts +++ b/packages/wrap/tests/transformFilterToSchema.test.ts @@ -26,7 +26,8 @@ describe('FilterToSchema', () => { document: query, variables: { id: 'c1', - } + }, + operationType: 'query' as const }, { targetSchema: bookingSchema } as DelegationContext, {}); @@ -60,6 +61,7 @@ describe('FilterToSchema', () => { id: 'c1', limit: 10, }, + operationType: 'query' as const, }, { targetSchema: bookingSchema } as DelegationContext, {}); @@ -92,6 +94,7 @@ describe('FilterToSchema', () => { variables: { id: 'b1', }, + operationType: 'query' as const, }, { targetSchema: bookingSchema } as DelegationContext, {}); From ac634e58622f3b2d20b361b41cfb2bb3d362474f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 13 Jul 2021 01:32:10 +0000 Subject: [PATCH 57/66] chore(deps): update dependency typedoc-plugin-markdown to v3.10.3 (#3192) Co-authored-by: Renovate Bot --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index b55f48c67fe..669d6fd6574 100644 --- a/package.json +++ b/package.json @@ -73,7 +73,7 @@ "prettier": "2.3.2", "ts-jest": "27.0.3", "typedoc": "0.21.4", - "typedoc-plugin-markdown": "3.10.2", + "typedoc-plugin-markdown": "3.10.3", "typescript": "4.3.5" }, "lint-staged": { diff --git a/yarn.lock b/yarn.lock index 0661f17da60..64d03c50772 100644 --- a/yarn.lock +++ b/yarn.lock @@ -12771,10 +12771,10 @@ typedoc-default-themes@^0.12.10: resolved "https://registry.yarnpkg.com/typedoc-default-themes/-/typedoc-default-themes-0.12.10.tgz#614c4222fe642657f37693ea62cad4dafeddf843" integrity sha512-fIS001cAYHkyQPidWXmHuhs8usjP5XVJjWB8oZGqkTowZaz3v7g3KDZeeqE82FBrmkAnIBOY3jgy7lnPnqATbA== -typedoc-plugin-markdown@3.10.2: - version "3.10.2" - resolved "https://registry.yarnpkg.com/typedoc-plugin-markdown/-/typedoc-plugin-markdown-3.10.2.tgz#4b1400706d4c8c3924481808aba4efa684605174" - integrity sha512-eAV7fuCymdbUIk2P3jjehUWG0VE3YSr/qGGYAHUEBTrRZMuFxS/rYrooF0PPabBUdbprL4BKV8HaP7oed12T2Q== +typedoc-plugin-markdown@3.10.3: + version "3.10.3" + resolved "https://registry.yarnpkg.com/typedoc-plugin-markdown/-/typedoc-plugin-markdown-3.10.3.tgz#8d7f3e8d44363143cd4d032bab5db0460b0434f8" + integrity sha512-CmNfHjiCc3ttJo3IYa7te+xOLJIn+jRVloSkM4j3It2rhJTeYp6OhZocnIHYIJIIqXuttoXAbFAbfJ2v7X+nbA== dependencies: handlebars "^4.7.7" From ffe14c262ed30eb1db2c9478b36f381918f2c445 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 13 Jul 2021 07:13:15 -0400 Subject: [PATCH 58/66] chore(deps): update dependency lint-staged to v11.0.1 (#3193) Co-authored-by: Renovate Bot --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 669d6fd6574..04be99a7728 100644 --- a/package.json +++ b/package.json @@ -67,7 +67,7 @@ "graphql-subscriptions": "1.2.1", "husky": "7.0.1", "jest": "27.0.6", - "lint-staged": "11.0.0", + "lint-staged": "11.0.1", "nock": "13.1.1", "patch-package": "6.4.7", "prettier": "2.3.2", diff --git a/yarn.lock b/yarn.lock index 64d03c50772..7edaf23e091 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8568,10 +8568,10 @@ lines-and-columns@^1.1.6: resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.1.6.tgz#1c00c743b433cd0a4e80758f7b64a57440d9ff00" integrity sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA= -lint-staged@11.0.0: - version "11.0.0" - resolved "https://registry.yarnpkg.com/lint-staged/-/lint-staged-11.0.0.tgz#24d0a95aa316ba28e257f5c4613369a75a10c712" - integrity sha512-3rsRIoyaE8IphSUtO1RVTFl1e0SLBtxxUOPBtHxQgBHS5/i6nqvjcUfNioMa4BU9yGnPzbO+xkfLtXtxBpCzjw== +lint-staged@11.0.1: + version "11.0.1" + resolved "https://registry.yarnpkg.com/lint-staged/-/lint-staged-11.0.1.tgz#1b8ae8ed5a52ed87252db95fe008c2618c85f55a" + integrity sha512-RkTA1ulE6jAGFskxpGAwxfVRXjHp7D9gFg/+KMARUWMPiVFP0t28Em2u0gL8sA0w3/ck3TC57F2v2RNeQ5XPnw== dependencies: chalk "^4.1.1" cli-truncate "^2.1.0" From 7f25ae06ed287765aacf4757becd86b9a4435332 Mon Sep 17 00:00:00 2001 From: Arda TANRIKULU Date: Tue, 13 Jul 2021 14:14:35 +0300 Subject: [PATCH 59/66] Add benchmark tests (#3147) * Add benchmark tests * Try again * Submodules? * Hoba * Go for it * Fix tests * Report errors * K6 * Fix k6 steps * Fix and compare (#3159) * Move wait-on to the benchmark * Fix paths to k6 reports * two decimals * Bring some improvements * Some small improvements * Naming functions and better memoization * set NODE_ENV=production * More * Add monolith benchmark * Add matrix for benchmarks * Better names for benchmark workflows * More tests * Handle more than 2 benchmarks (#3183) * Add monolith the compare results Co-authored-by: Kamil Kisiela --- .github/workflows/benchmark.yml | 53 + benchmark/compare.js | 35 + benchmark/federation/.gitignore | 53 + benchmark/federation/call.js | 52 + benchmark/federation/federation.js | 26 + benchmark/federation/index.js | 67 + benchmark/federation/k6.js | 65 + benchmark/federation/monolith.js | 157 ++ benchmark/federation/package.json | 22 + .../federation/services/accounts/index.js | 59 + .../federation/services/inventory/index.js | 48 + .../federation/services/products/index.js | 64 + .../federation/services/reviews/index.js | 91 + benchmark/federation/stitching.js | 40 + benchmark/federation/yarn.lock | 2073 +++++++++++++++++ benchmark/utils.js | 23 + package.json | 3 +- packages/batch-delegate/src/getLoader.ts | 14 +- .../transforms/CheckResultAndHandleErrors.ts | 2 +- .../src/transforms/ExpandAbstractTypes.ts | 75 +- .../src/transforms/VisitSelectionSets.ts | 124 +- packages/loaders/git/package.json | 2 +- yarn.lock | 887 ++++++- 23 files changed, 3910 insertions(+), 125 deletions(-) create mode 100644 .github/workflows/benchmark.yml create mode 100644 benchmark/compare.js create mode 100644 benchmark/federation/.gitignore create mode 100644 benchmark/federation/call.js create mode 100644 benchmark/federation/federation.js create mode 100644 benchmark/federation/index.js create mode 100644 benchmark/federation/k6.js create mode 100644 benchmark/federation/monolith.js create mode 100644 benchmark/federation/package.json create mode 100644 benchmark/federation/services/accounts/index.js create mode 100644 benchmark/federation/services/inventory/index.js create mode 100644 benchmark/federation/services/products/index.js create mode 100644 benchmark/federation/services/reviews/index.js create mode 100644 benchmark/federation/stitching.js create mode 100644 benchmark/federation/yarn.lock create mode 100644 benchmark/utils.js diff --git a/.github/workflows/benchmark.yml b/.github/workflows/benchmark.yml new file mode 100644 index 00000000000..c20a5db8460 --- /dev/null +++ b/.github/workflows/benchmark.yml @@ -0,0 +1,53 @@ +name: Benchmark + +on: + pull_request: + branches: + - master + +jobs: + federation-benchmark: + name: Federation Benchmark with ${{matrix.products_size}} Products + runs-on: ubuntu-latest + strategy: + matrix: + products_size: [3, 10, 50, 100, 1000] + steps: + - name: Checkout Master + uses: actions/checkout@v2 + - name: Use Node + uses: actions/setup-node@master + with: + node-version: 16 + - name: Cache Yarn + uses: actions/cache@v2 + with: + path: '**/node_modules' + key: ${{ runner.os }}-16-16-yarn-${{ hashFiles('yarn.lock') }} + restore-keys: | + ${{ runner.os }}-16-16-yarn + - name: Install Dependencies using Yarn + run: yarn install --ignore-engines && git checkout yarn.lock + - name: Build + run: yarn build + - name: Setup K6 + run: | + sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys C5AD17C747E3415A3642D57D77C6C491D6AC1D69 + echo "deb https://dl.k6.io/deb stable main" | sudo tee /etc/apt/sources.list.d/k6.list + sudo apt-get update + sudo apt-get install k6 + - name: GraphQL API + working-directory: ./benchmark/federation + run: | + yarn start & + yarn wait-on tcp:3000 + env: + PRODUCTS_SIZE: ${{matrix.products_size}} + - name: Federation + run: k6 -e ENDPOINT=federation run --out json=federation.json benchmark/federation/k6.js + - name: Stitching + run: k6 -e ENDPOINT=stitching run --out json=stitching.json benchmark/federation/k6.js + - name: Monolith + run: k6 -e ENDPOINT=monolith run --out json=monolith.json benchmark/federation/k6.js + - name: Compare + run: node benchmark/compare monolith:monolith.json federation:federation.json stitching:stitching.json diff --git a/benchmark/compare.js b/benchmark/compare.js new file mode 100644 index 00000000000..2212b18c2bc --- /dev/null +++ b/benchmark/compare.js @@ -0,0 +1,35 @@ +const fs = require('fs'); +const path = require('path'); +let [, , ...rawPointers] = process.argv; + +function createReport(pointer) { + const [name, file] = pointer.split(':'); + + const lines = fs.readFileSync(path.join(process.cwd(), file), 'utf-8').split('\n'); + + let sum = 0; + let count = 0; + + for (let line of lines) { + if (line.trim().length) { + const metric = JSON.parse(line); + + if (metric.type === 'Point' && metric.metric === 'http_req_duration' && metric.data.tags.status === '200') { + count++; + sum += metric.data.value; + } + } + } + + return { + name, + file, + avg: sum / count, + }; +} + +const pointers = rawPointers.map(createReport); + +const stats = pointers.map(pointer => `${pointer.name}: ${pointer.avg.toFixed(2)} ms`).join('\n') + +console.log(stats); diff --git a/benchmark/federation/.gitignore b/benchmark/federation/.gitignore new file mode 100644 index 00000000000..d87615e3ba7 --- /dev/null +++ b/benchmark/federation/.gitignore @@ -0,0 +1,53 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +lerna-debug.log* + +# Diagnostic reports (https://nodejs.org/api/report.html) +report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage + +# nyc test coverage +.nyc_output + +# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# Bower dependency directory (https://bower.io/) +bower_components + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (https://nodejs.org/api/addons.html) +build/Release + +# Dependency directories +node_modules/ +jspm_packages/ + +# TypeScript v1 declaration files +typings/ + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# environment variables +.env diff --git a/benchmark/federation/call.js b/benchmark/federation/call.js new file mode 100644 index 00000000000..42ed37ff2be --- /dev/null +++ b/benchmark/federation/call.js @@ -0,0 +1,52 @@ +const fetch = require('cross-fetch'); + +fetch('http://localhost:3000/monolith', { + method: 'POST', + headers: { + 'content-type': 'application/json' + }, + body: JSON.stringify({ + query: /* GraphQL */ ` + fragment User on User { + id + username + name + } + + fragment Review on Review { + id + body + } + + fragment Product on Product { + inStock + name + price + shippingEstimate + upc + weight + } + + query TestQuery { + users { + ...User + reviews { + ...Review + product { + ...Product + } + } + } + topProducts { + ...Product + reviews { + ...Review + author { + ...User + } + } + } + } + `, + }), +}).then(res => res.json()).then(data => console.log(JSON.stringify(data, null, 2))); diff --git a/benchmark/federation/federation.js b/benchmark/federation/federation.js new file mode 100644 index 00000000000..7953fbc5cf2 --- /dev/null +++ b/benchmark/federation/federation.js @@ -0,0 +1,26 @@ +const { ApolloGateway, LocalGraphQLDataSource } = require('@apollo/gateway'); + +const serviceMap = { + accounts: require('./services/accounts'), + inventory: require('./services/inventory'), + products: require('./services/products'), + reviews: require('./services/reviews'), +}; + +module.exports = async function () { + const gateway = new ApolloGateway({ + localServiceList: Object.entries(serviceMap).map(([name, { typeDefs }]) => ({ + name, + typeDefs, + })), + buildService: ({ name }) => new LocalGraphQLDataSource(serviceMap[name].schema) + }); + + const { schema, executor } = await gateway.load(); + + return { + schema, + executor, + stop: () => gateway.stop(), + }; +}; diff --git a/benchmark/federation/index.js b/benchmark/federation/index.js new file mode 100644 index 00000000000..a0f03bccba7 --- /dev/null +++ b/benchmark/federation/index.js @@ -0,0 +1,67 @@ +const express = require('express'); +const runStitchingGateway = require('./stitching'); +const runApolloGateway = require('./federation'); +const makeMonolithSchema = require('./monolith'); +const { parse, execute } = require('graphql'); + +async function main() { + const [stitching, federation, monolith] = await Promise.all([ + runStitchingGateway(), + runApolloGateway(), + makeMonolithSchema(), + ]); + + const app = express(); + + app.use(express.json()); + + app.post('/federation', (req, res) => { + federation + .executor({ + document: parse(req.body.query), + request: { + query: req.body.query, + }, + cache: { + get: async () => undefined, + set: async () => {}, + delete: async () => true, + }, + schema: federation.schema, + context: {}, + }) + .then(result => res.json(result)) + .catch(error => res.status(500).send(error)); + }); + + app.post('/stitching', (req, res) => { + execute({ + schema: stitching, + document: parse(req.body.query), + contextValue: {}, + }) + .then(result => { + res.json(result); + }) + .catch(error => res.status(500).send(error)); + }); + + app.post('/monolith', (req, res) => { + try { + const result = execute({ + schema: monolith, + document: parse(req.body.query), + contextValue: {}, + }); + res.json(result); + } catch (error) { + res.status(500).send(error); + } + }); + + app.listen(3000, () => { + console.log('listening on 0.0.0.0:3000'); + }); +} + +main(); diff --git a/benchmark/federation/k6.js b/benchmark/federation/k6.js new file mode 100644 index 00000000000..511b82de79d --- /dev/null +++ b/benchmark/federation/k6.js @@ -0,0 +1,65 @@ +import { check } from 'k6'; +import { graphql, checkNoErrors } from '../utils.js'; + +export const options = { + vus: 1, + duration: '10s', + thresholds: { + no_errors: ['rate=1.0'], + expected_result: ['rate=1.0'], + }, +}; + +export default function () { + const res = graphql({ + endpoint: `http://0.0.0.0:3000/${__ENV.ENDPOINT}`, + query: /* GraphQL */ ` + fragment User on User { + id + username + name + } + + fragment Review on Review { + id + body + } + + fragment Product on Product { + inStock + name + price + shippingEstimate + upc + weight + } + + query TestQuery { + users { + ...User + reviews { + ...Review + product { + ...Product + } + } + } + topProducts { + ...Product + reviews { + ...Review + author { + ...User + } + } + } + } + `, + variables: {}, + }); + + check(res, { + no_errors: checkNoErrors, + expected_result: resp => 'reviews' in resp.json().data.users[0] && 'reviews' in resp.json().data.topProducts[0], + }); +} diff --git a/benchmark/federation/monolith.js b/benchmark/federation/monolith.js new file mode 100644 index 00000000000..4298d8c9000 --- /dev/null +++ b/benchmark/federation/monolith.js @@ -0,0 +1,157 @@ +const { gql } = require("graphql-tag"); +const { makeExecutableSchema } = require('@graphql-tools/schema'); + +const typeDefs = gql` + type Query { + me: User + users: [User] + topProducts(first: Int): [Product] + } + type User { + id: ID! + name: String + username: String + reviews: [Review] + } + type Product { + upc: String! + weight: Int + price: Int + name: String + inStock: Boolean + shippingEstimate: Int + reviews: [Review] + } + type Review { + id: ID! + body: String + author: User + product: Product + } +`; + +const resolvers = { + Query: { + me() { + return users[0]; + }, + users() { + return users; + }, + topProducts(_, args) { + return args.first ? products.slice(0, args.first) : products; + }, + }, + User: { + reviews(user) { + return reviews.filter((review) => review.authorID === user.id); + }, + username(user) { + const found = usernames.find((username) => username.id === user.id); + return found ? found.username : null; + }, + }, + Product: { + shippingEstimate(object) { + // free for expensive items + if (object.price > 1000) return 0; + // estimate is based on weight + return object.weight * 0.5; + }, + reviews(product) { + return reviews.filter((review) => review.product.upc === product.upc); + }, + inStock(product) { + return inventory.find((inv) => inv.upc === product.upc)?.inStock; + }, + }, + Review: { + author(review) { + return users.find((user) => user.id === review.authorID); + }, + }, +}; + + + +module.exports = () => makeExecutableSchema({ + typeDefs, + resolvers +}); + +const users = [ + { + id: "1", + name: "Ada Lovelace", + birthDate: "1815-12-10", + username: "@ada", + }, + { + id: "2", + name: "Alan Turing", + birthDate: "1912-06-23", + username: "@complete", + }, +]; + +const inventory = [ + { upc: "1", inStock: true }, + { upc: "2", inStock: false }, + { upc: "3", inStock: true }, +]; + +const listSize = parseInt(process.env.PRODUCTS_SIZE || '3'); + +const definedProducts = [ + { + upc: '1', + name: 'Table', + price: 899, + weight: 100, + }, + { + upc: '2', + name: 'Couch', + price: 1299, + weight: 1000, + }, + { + upc: '3', + name: 'Chair', + price: 54, + weight: 50, + }, +]; +const products = [...Array(listSize)].map((_, index) => definedProducts[index % 3]); + +const usernames = [ + { id: "1", username: "@ada" }, + { id: "2", username: "@complete" }, +]; + +const reviews = [ + { + id: "1", + authorID: "1", + product: { upc: "1" }, + body: "Love it!", + }, + { + id: "2", + authorID: "1", + product: { upc: "2" }, + body: "Too expensive.", + }, + { + id: "3", + authorID: "2", + product: { upc: "3" }, + body: "Could be better.", + }, + { + id: "4", + authorID: "2", + product: { upc: "1" }, + body: "Prefer something else.", + }, +]; diff --git a/benchmark/federation/package.json b/benchmark/federation/package.json new file mode 100644 index 00000000000..b0ce388767a --- /dev/null +++ b/benchmark/federation/package.json @@ -0,0 +1,22 @@ +{ + "name": "federation-benchmark", + "version": "0.0.0", + "private": true, + "scripts": { + "start": "cross-env NODE_ENV=production node index.js", + "loadtest:federation": "k6 -e ENDPOINT=federation run k6.js", + "loadtest:stitching": "k6 -e ENDPOINT=stitching run k6.js", + "loadtest:monolith": "k6 -e ENDPOINT=monolith run k6.js" + }, + "dependencies": { + "@apollo/gateway": "0.32.0", + "@apollo/federation": "0.25.2", + "@graphql-tools/stitch": "7.5.3", + "@graphql-tools/stitching-directives": "1.3.3", + "express": "4.17.1", + "graphql": "15.5.1", + "graphql-tag": "2.12.5", + "wait-on": "6.0.0", + "cross-env": "7.0.3" + } +} diff --git a/benchmark/federation/services/accounts/index.js b/benchmark/federation/services/accounts/index.js new file mode 100644 index 00000000000..f0124244b58 --- /dev/null +++ b/benchmark/federation/services/accounts/index.js @@ -0,0 +1,59 @@ +const { gql } = require("graphql-tag"); +const { buildFederatedSchema } = require("@apollo/federation"); + +const typeDefs = gql` + extend type Query { + me: User + users: [User] + } + + type User @key(fields: "id") { + id: ID! + name: String + username: String + } +`; + +const resolvers = { + Query: { + me() { + return users[0]; + }, + users() { + return users; + } + }, + User: { + __resolveReference(object) { + return users.find(user => user.id === object.id); + } + } +}; + +const schema = buildFederatedSchema([ + { + typeDefs, + resolvers, + }, +]); + +module.exports = { + typeDefs, + resolvers, + schema +} + +const users = [ + { + id: "1", + name: "Ada Lovelace", + birthDate: "1815-12-10", + username: "@ada" + }, + { + id: "2", + name: "Alan Turing", + birthDate: "1912-06-23", + username: "@complete" + } +]; diff --git a/benchmark/federation/services/inventory/index.js b/benchmark/federation/services/inventory/index.js new file mode 100644 index 00000000000..6887afdcf67 --- /dev/null +++ b/benchmark/federation/services/inventory/index.js @@ -0,0 +1,48 @@ +const { gql } = require('graphql-tag'); +const { buildFederatedSchema } = require('@apollo/federation'); + +const typeDefs = gql` + extend type Product @key(fields: "upc") { + upc: String! @external + weight: Int @external + price: Int @external + inStock: Boolean + shippingEstimate: Int @requires(fields: "price weight") + } +`; + +const resolvers = { + Product: { + __resolveReference(object) { + return { + ...object, + ...inventory.find(product => product.upc === object.upc), + }; + }, + shippingEstimate(object) { + // free for expensive items + if (object.price > 1000) return 0; + // estimate is based on weight + return object.weight * 0.5; + }, + }, +}; + +const schema = buildFederatedSchema([ + { + typeDefs, + resolvers, + }, +]); + +module.exports = { + typeDefs, + resolvers, + schema, +}; + +const inventory = [ + { upc: '1', inStock: true }, + { upc: '2', inStock: false }, + { upc: '3', inStock: true }, +]; diff --git a/benchmark/federation/services/products/index.js b/benchmark/federation/services/products/index.js new file mode 100644 index 00000000000..a00d08e7875 --- /dev/null +++ b/benchmark/federation/services/products/index.js @@ -0,0 +1,64 @@ +const { gql } = require('graphql-tag'); +const { buildFederatedSchema } = require('@apollo/federation'); + +const typeDefs = gql` + extend type Query { + topProducts(first: Int): [Product] + } + + type Product @key(fields: "upc") { + upc: String! + name: String + price: Int + weight: Int + } +`; + +const listSize = parseInt(process.env.PRODUCTS_SIZE || '3'); + +const definedProducts = [ + { + upc: '1', + name: 'Table', + price: 899, + weight: 100, + }, + { + upc: '2', + name: 'Couch', + price: 1299, + weight: 1000, + }, + { + upc: '3', + name: 'Chair', + price: 54, + weight: 50, + }, +]; +const products = [...Array(listSize)].map((_, index) => definedProducts[index % 3]); + +const resolvers = { + Product: { + __resolveReference(object) { + return products.find(product => product.upc === object.upc); + }, + }, + Query: { + topProducts(_, args) { + return args.first ? products.slice(0, args.first) : products; + }, + }, +}; +const schema = buildFederatedSchema([ + { + typeDefs, + resolvers, + }, +]); + +module.exports = { + typeDefs, + resolvers, + schema, +}; diff --git a/benchmark/federation/services/reviews/index.js b/benchmark/federation/services/reviews/index.js new file mode 100644 index 00000000000..253dd800f87 --- /dev/null +++ b/benchmark/federation/services/reviews/index.js @@ -0,0 +1,91 @@ +const { gql } = require('graphql-tag'); +const { buildFederatedSchema } = require('@apollo/federation'); + +const typeDefs = gql` + type Review @key(fields: "id") { + id: ID! + body: String + author: User @provides(fields: "username") + product: Product + } + + extend type User @key(fields: "id") { + id: ID! @external + username: String @external + reviews: [Review] + } + + extend type Product @key(fields: "upc") { + upc: String! @external + reviews: [Review] + } +`; + +const resolvers = { + Review: { + author(review) { + return { __typename: 'User', id: review.authorID }; + }, + }, + User: { + reviews(user) { + return reviews.filter(review => review.authorID === user.id); + }, + numberOfReviews(user) { + return reviews.filter(review => review.authorID === user.id).length; + }, + username(user) { + const found = usernames.find(username => username.id === user.id); + return found ? found.username : null; + }, + }, + Product: { + reviews(product) { + return reviews.filter(review => review.product.upc === product.upc); + }, + }, +}; + +const schema = buildFederatedSchema([ + { + typeDefs, + resolvers, + }, +]); + +module.exports = { + typeDefs, + resolvers, + schema, +}; + +const usernames = [ + { id: '1', username: '@ada' }, + { id: '2', username: '@complete' }, +]; +const reviews = [ + { + id: '1', + authorID: '1', + product: { upc: '1' }, + body: 'Love it!', + }, + { + id: '2', + authorID: '1', + product: { upc: '2' }, + body: 'Too expensive.', + }, + { + id: '3', + authorID: '2', + product: { upc: '3' }, + body: 'Could be better.', + }, + { + id: '4', + authorID: '2', + product: { upc: '1' }, + body: 'Prefer something else.', + }, +]; diff --git a/benchmark/federation/stitching.js b/benchmark/federation/stitching.js new file mode 100644 index 00000000000..4d8a5f55eb4 --- /dev/null +++ b/benchmark/federation/stitching.js @@ -0,0 +1,40 @@ +const { stitchSchemas } = require('@graphql-tools/stitch'); +const { federationToStitchingSDL, stitchingDirectives } = require('@graphql-tools/stitching-directives'); +const { stitchingDirectivesTransformer } = stitchingDirectives(); +const { buildSchema, execute, print } = require('graphql'); + +const services = [ + require('./services/accounts'), + require('./services/inventory'), + require('./services/products'), + require('./services/reviews'), +]; + +function createExecutor(schema) { + return function serviceExecutor({ document, variables, context }) { + return execute({ + schema, + document, + variableValues: variables, + contextValue: context, + }); + }; +} + +async function makeGatewaySchema() { + return stitchSchemas({ + subschemaConfigTransforms: [stitchingDirectivesTransformer], + subschemas: services.map(service => fetchFederationSubschema(service)), + }); +} + +function fetchFederationSubschema({ schema, typeDefs }) { + const sdl = federationToStitchingSDL(print(typeDefs)); + return { + schema: buildSchema(sdl), + executor: createExecutor(schema), + batch: true + }; +} + +module.exports = makeGatewaySchema; diff --git a/benchmark/federation/yarn.lock b/benchmark/federation/yarn.lock new file mode 100644 index 00000000000..112de248902 --- /dev/null +++ b/benchmark/federation/yarn.lock @@ -0,0 +1,2073 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@apollo/federation@0.25.2", "@apollo/federation@^0.25.2": + version "0.25.2" + resolved "https://registry.yarnpkg.com/@apollo/federation/-/federation-0.25.2.tgz#10b2e22ac20e64701fd6d31d9abbf7f411b03763" + integrity sha512-TrRCrGniHpnRwALm2J7q2c1X4Lcc95e7SeHkVjascaQx6nBZGFbBXadw8rOPxlw5syfxYf8h9winF+wwld+gsg== + dependencies: + apollo-graphql "^0.9.3" + lodash.xorby "^4.7.0" + +"@apollo/gateway@0.32.0": + version "0.32.0" + resolved "https://registry.yarnpkg.com/@apollo/gateway/-/gateway-0.32.0.tgz#639b7b826c76a2bffdf777902010485dfd981918" + integrity sha512-Pxq3VVxG1ALrFNN8SM3RVy6Kwm+5p1KG3ObVmQX720Wx5WpRKvCRC23J/c3oFRpsGqjPOglh3vmpAQVdJJTCZA== + dependencies: + "@apollo/federation" "^0.25.2" + "@apollo/query-planner" "^0.2.2" + "@opentelemetry/api" "^1.0.1" + "@types/node-fetch" "2.5.10" + apollo-graphql "^0.9.3" + apollo-reporting-protobuf "^0.8.0 || ^3.0.0 || ^3.0.0-preview.2" + apollo-server-caching "^0.7.0 || ^3.0.0 || ^3.0.0-preview.2" + apollo-server-core "^2.23.0 || ^3.0.0 || ^3.0.0-preview.2" + apollo-server-env "^3.0.0 || ^4.0.0 || ^3.2.0-preview.2 || ^4.0.0-rc.0" + apollo-server-errors "^2.5.0 || ^3.0.0 || ^3.0.0-preview.2" + apollo-server-types "^0.9.0 || ^3.0.0 || ^3.0.0-preview.2" + loglevel "^1.6.1" + make-fetch-happen "^8.0.0" + pretty-format "^26.0.0" + +"@apollo/protobufjs@1.2.2": + version "1.2.2" + resolved "https://registry.yarnpkg.com/@apollo/protobufjs/-/protobufjs-1.2.2.tgz#4bd92cd7701ccaef6d517cdb75af2755f049f87c" + integrity sha512-vF+zxhPiLtkwxONs6YanSt1EpwpGilThpneExUN5K3tCymuxNnVq2yojTvnpRjv2QfsEIt/n7ozPIIzBLwGIDQ== + dependencies: + "@protobufjs/aspromise" "^1.1.2" + "@protobufjs/base64" "^1.1.2" + "@protobufjs/codegen" "^2.0.4" + "@protobufjs/eventemitter" "^1.1.0" + "@protobufjs/fetch" "^1.1.0" + "@protobufjs/float" "^1.0.2" + "@protobufjs/inquire" "^1.1.0" + "@protobufjs/path" "^1.1.2" + "@protobufjs/pool" "^1.1.0" + "@protobufjs/utf8" "^1.1.0" + "@types/long" "^4.0.0" + "@types/node" "^10.1.0" + long "^4.0.0" + +"@apollo/query-planner@^0.2.2": + version "0.2.2" + resolved "https://registry.yarnpkg.com/@apollo/query-planner/-/query-planner-0.2.2.tgz#5397e5cd8a73dede34c485fb0c5fefa054f9153a" + integrity sha512-+RZSKY0xDYki9qwlzKXDNa+jrbj0Qstq44lcB21aViiDdEJWOTwf7Cqg3h/hN7QsUnL75XiDrwsjMLnwFdHSoQ== + dependencies: + chalk "^4.1.0" + deep-equal "^2.0.5" + pretty-format "^26.0.0" + +"@apollographql/apollo-tools@^0.5.0": + version "0.5.1" + resolved "https://registry.yarnpkg.com/@apollographql/apollo-tools/-/apollo-tools-0.5.1.tgz#f0baef739ff7e2fafcb8b98ad29f6ac817e53e32" + integrity sha512-ZII+/xUFfb9ezDU2gad114+zScxVFMVlZ91f8fGApMzlS1kkqoyLnC4AJaQ1Ya/X+b63I20B4Gd+eCL8QuB4sA== + +"@apollographql/graphql-playground-html@1.6.27": + version "1.6.27" + resolved "https://registry.yarnpkg.com/@apollographql/graphql-playground-html/-/graphql-playground-html-1.6.27.tgz#bc9ab60e9445aa2a8813b4e94f152fa72b756335" + integrity sha512-tea2LweZvn6y6xFV11K0KC8ETjmm52mQrW+ezgB2O/aTQf8JGyFmMcRPFgUaQZeHbWdm8iisDC6EjOKsXu0nfw== + dependencies: + xss "^1.0.8" + +"@apollographql/graphql-upload-8-fork@^8.1.3": + version "8.1.3" + resolved "https://registry.yarnpkg.com/@apollographql/graphql-upload-8-fork/-/graphql-upload-8-fork-8.1.3.tgz#a0d4e0d5cec8e126d78bd915c264d6b90f5784bc" + integrity sha512-ssOPUT7euLqDXcdVv3Qs4LoL4BPtfermW1IOouaqEmj36TpHYDmYDIbKoSQxikd9vtMumFnP87OybH7sC9fJ6g== + dependencies: + "@types/express" "*" + "@types/fs-capacitor" "*" + "@types/koa" "*" + busboy "^0.3.1" + fs-capacitor "^2.0.4" + http-errors "^1.7.3" + object-path "^0.11.4" + +"@ardatan/aggregate-error@0.0.6": + version "0.0.6" + resolved "https://registry.yarnpkg.com/@ardatan/aggregate-error/-/aggregate-error-0.0.6.tgz#fe6924771ea40fc98dc7a7045c2e872dc8527609" + integrity sha512-vyrkEHG1jrukmzTPtyWB4NLPauUw5bQeg4uhn8f+1SSynmrOcyvlb1GKQjjgoBzElLdfXCRYX8UnBlhklOHYRQ== + dependencies: + tslib "~2.0.1" + +"@graphql-tools/batch-delegate@^7.0.0": + version "7.0.2" + resolved "https://registry.yarnpkg.com/@graphql-tools/batch-delegate/-/batch-delegate-7.0.2.tgz#e18bfe3f545c60c03b0bc079fe4bfa8f208b1631" + integrity sha512-Dn1LKcbZfgttfxW1V7E3JYrLGCWOhtPC+HkxBRrvzxkesxqDbgaOH8X4rsx3Po8AQD49J0eLdg9KXa0yF20VCA== + dependencies: + "@graphql-tools/delegate" "^7.0.10" + dataloader "2.0.0" + tslib "~2.1.0" + +"@graphql-tools/batch-execute@^7.1.2": + version "7.1.2" + resolved "https://registry.yarnpkg.com/@graphql-tools/batch-execute/-/batch-execute-7.1.2.tgz#35ba09a1e0f80f34f1ce111d23c40f039d4403a0" + integrity sha512-IuR2SB2MnC2ztA/XeTMTfWcA0Wy7ZH5u+nDkDNLAdX+AaSyDnsQS35sCmHqG0VOGTl7rzoyBWLCKGwSJplgtwg== + dependencies: + "@graphql-tools/utils" "^7.7.0" + dataloader "2.0.0" + tslib "~2.2.0" + value-or-promise "1.0.6" + +"@graphql-tools/delegate@^7.0.10", "@graphql-tools/delegate@^7.1.4", "@graphql-tools/delegate@^7.1.5": + version "7.1.5" + resolved "https://registry.yarnpkg.com/@graphql-tools/delegate/-/delegate-7.1.5.tgz#0b027819b7047eff29bacbd5032e34a3d64bd093" + integrity sha512-bQu+hDd37e+FZ0CQGEEczmRSfQRnnXeUxI/0miDV+NV/zCbEdIJj5tYFNrKT03W6wgdqx8U06d8L23LxvGri/g== + dependencies: + "@ardatan/aggregate-error" "0.0.6" + "@graphql-tools/batch-execute" "^7.1.2" + "@graphql-tools/schema" "^7.1.5" + "@graphql-tools/utils" "^7.7.1" + dataloader "2.0.0" + tslib "~2.2.0" + value-or-promise "1.0.6" + +"@graphql-tools/merge@^6.2.11": + version "6.2.14" + resolved "https://registry.yarnpkg.com/@graphql-tools/merge/-/merge-6.2.14.tgz#694e2a2785ba47558e5665687feddd2935e9d94e" + integrity sha512-RWT4Td0ROJai2eR66NHejgf8UwnXJqZxXgDWDI+7hua5vNA2OW8Mf9K1Wav1ZkjWnuRp4ztNtkZGie5ISw55ow== + dependencies: + "@graphql-tools/schema" "^7.0.0" + "@graphql-tools/utils" "^7.7.0" + tslib "~2.2.0" + +"@graphql-tools/schema@^7.0.0", "@graphql-tools/schema@^7.1.4", "@graphql-tools/schema@^7.1.5": + version "7.1.5" + resolved "https://registry.yarnpkg.com/@graphql-tools/schema/-/schema-7.1.5.tgz#07b24e52b182e736a6b77c829fc48b84d89aa711" + integrity sha512-uyn3HSNSckf4mvQSq0Q07CPaVZMNFCYEVxroApOaw802m9DcZPgf9XVPy/gda5GWj9AhbijfRYVTZQgHnJ4CXA== + dependencies: + "@graphql-tools/utils" "^7.1.2" + tslib "~2.2.0" + value-or-promise "1.0.6" + +"@graphql-tools/stitch@7.5.3": + version "7.5.3" + resolved "https://registry.yarnpkg.com/@graphql-tools/stitch/-/stitch-7.5.3.tgz#1b339942ebb93ea4e9da248439b8cf06660688cc" + integrity sha512-0oBdNFkviWRs0OkQiGow6THjRtDbiSOljCxCtkwF+C+bB/yLEPCNatTMo3ZR51twWBRPFgMwHZbSVbhRlK51kw== + dependencies: + "@graphql-tools/batch-delegate" "^7.0.0" + "@graphql-tools/delegate" "^7.1.4" + "@graphql-tools/merge" "^6.2.11" + "@graphql-tools/schema" "^7.1.4" + "@graphql-tools/utils" "^7.7.0" + "@graphql-tools/wrap" "^7.0.6" + tslib "~2.2.0" + +"@graphql-tools/stitching-directives@1.3.3": + version "1.3.3" + resolved "https://registry.yarnpkg.com/@graphql-tools/stitching-directives/-/stitching-directives-1.3.3.tgz#f847f1e8bf80e67dd0b5e763f19a4c8e34ac97dd" + integrity sha512-G3Ia7zcoJPGQn05CKvsnBGI9xkA6+WIpJ9VfxP7LlAGnjS7be0F9tJRHF7HUSzKMXVVs4m4b1oO1IPf2cJ+mag== + dependencies: + "@graphql-tools/delegate" "^7.0.10" + "@graphql-tools/utils" "^7.2.4" + tslib "~2.2.0" + +"@graphql-tools/utils@^7.1.2", "@graphql-tools/utils@^7.2.4", "@graphql-tools/utils@^7.7.0", "@graphql-tools/utils@^7.7.1", "@graphql-tools/utils@^7.8.1": + version "7.10.0" + resolved "https://registry.yarnpkg.com/@graphql-tools/utils/-/utils-7.10.0.tgz#07a4cb5d1bec1ff1dc1d47a935919ee6abd38699" + integrity sha512-d334r6bo9mxdSqZW6zWboEnnOOFRrAPVQJ7LkU8/6grglrbcu6WhwCLzHb90E94JI3TD3ricC3YGbUqIi9Xg0w== + dependencies: + "@ardatan/aggregate-error" "0.0.6" + camel-case "4.1.2" + tslib "~2.2.0" + +"@graphql-tools/wrap@^7.0.6": + version "7.0.8" + resolved "https://registry.yarnpkg.com/@graphql-tools/wrap/-/wrap-7.0.8.tgz#ad41e487135ca3ea1ae0ea04bb3f596177fb4f50" + integrity sha512-1NDUymworsOlb53Qfh7fonDi2STvqCtbeE68ntKY9K/Ju/be2ZNxrFSbrBHwnxWcN9PjISNnLcAyJ1L5tCUyhg== + dependencies: + "@graphql-tools/delegate" "^7.1.5" + "@graphql-tools/schema" "^7.1.5" + "@graphql-tools/utils" "^7.8.1" + tslib "~2.2.0" + value-or-promise "1.0.6" + +"@jest/types@^26.6.2": + version "26.6.2" + resolved "https://registry.yarnpkg.com/@jest/types/-/types-26.6.2.tgz#bef5a532030e1d88a2f5a6d933f84e97226ed48e" + integrity sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ== + dependencies: + "@types/istanbul-lib-coverage" "^2.0.0" + "@types/istanbul-reports" "^3.0.0" + "@types/node" "*" + "@types/yargs" "^15.0.0" + chalk "^4.0.0" + +"@josephg/resolvable@^1.0.0": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@josephg/resolvable/-/resolvable-1.0.1.tgz#69bc4db754d79e1a2f17a650d3466e038d94a5eb" + integrity sha512-CtzORUwWTTOTqfVtHaKRJ0I1kNQd1bpn3sUh8I3nJDVY+5/M/Oe1DnEWzPQvqq/xPIIkzzzIP7mfCoAjFRvDhg== + +"@npmcli/move-file@^1.0.1": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@npmcli/move-file/-/move-file-1.1.2.tgz#1a82c3e372f7cae9253eb66d72543d6b8685c674" + integrity sha512-1SUf/Cg2GzGDyaf15aR9St9TWlb+XvbZXWpDx8YKs7MLzMH/BCeopv+y9vzrzgkfykCGuWOlSu3mZhj2+FQcrg== + dependencies: + mkdirp "^1.0.4" + rimraf "^3.0.2" + +"@opentelemetry/api@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@opentelemetry/api/-/api-1.0.1.tgz#03c72f548431da5820a0c8864d1401e348e7e79f" + integrity sha512-H5Djcc2txGAINgf3TNaq4yFofYSIK3722PM89S/3R8FuI/eqi1UscajlXk7EBkG9s2pxss/q6SHlpturaavXaw== + +"@protobufjs/aspromise@^1.1.1", "@protobufjs/aspromise@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@protobufjs/aspromise/-/aspromise-1.1.2.tgz#9b8b0cc663d669a7d8f6f5d0893a14d348f30fbf" + integrity sha1-m4sMxmPWaafY9vXQiToU00jzD78= + +"@protobufjs/base64@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@protobufjs/base64/-/base64-1.1.2.tgz#4c85730e59b9a1f1f349047dbf24296034bb2735" + integrity sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg== + +"@protobufjs/codegen@^2.0.4": + version "2.0.4" + resolved "https://registry.yarnpkg.com/@protobufjs/codegen/-/codegen-2.0.4.tgz#7ef37f0d010fb028ad1ad59722e506d9262815cb" + integrity sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg== + +"@protobufjs/eventemitter@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz#355cbc98bafad5978f9ed095f397621f1d066b70" + integrity sha1-NVy8mLr61ZePntCV85diHx0Ga3A= + +"@protobufjs/fetch@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/fetch/-/fetch-1.1.0.tgz#ba99fb598614af65700c1619ff06d454b0d84c45" + integrity sha1-upn7WYYUr2VwDBYZ/wbUVLDYTEU= + dependencies: + "@protobufjs/aspromise" "^1.1.1" + "@protobufjs/inquire" "^1.1.0" + +"@protobufjs/float@^1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@protobufjs/float/-/float-1.0.2.tgz#5e9e1abdcb73fc0a7cb8b291df78c8cbd97b87d1" + integrity sha1-Xp4avctz/Ap8uLKR33jIy9l7h9E= + +"@protobufjs/inquire@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/inquire/-/inquire-1.1.0.tgz#ff200e3e7cf2429e2dcafc1140828e8cc638f089" + integrity sha1-/yAOPnzyQp4tyvwRQIKOjMY48Ik= + +"@protobufjs/path@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@protobufjs/path/-/path-1.1.2.tgz#6cc2b20c5c9ad6ad0dccfd21ca7673d8d7fbf68d" + integrity sha1-bMKyDFya1q0NzP0hynZz2Nf79o0= + +"@protobufjs/pool@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/pool/-/pool-1.1.0.tgz#09fd15f2d6d3abfa9b65bc366506d6ad7846ff54" + integrity sha1-Cf0V8tbTq/qbZbw2ZQbWrXhG/1Q= + +"@protobufjs/utf8@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/utf8/-/utf8-1.1.0.tgz#a777360b5b39a1a2e5106f8e858f2fd2d060c570" + integrity sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA= + +"@tootallnate/once@1": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-1.1.2.tgz#ccb91445360179a04e7fe6aff78c00ffc1eeaf82" + integrity sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw== + +"@types/accepts@*": + version "1.3.5" + resolved "https://registry.yarnpkg.com/@types/accepts/-/accepts-1.3.5.tgz#c34bec115cfc746e04fe5a059df4ce7e7b391575" + integrity sha512-jOdnI/3qTpHABjM5cx1Hc0sKsPoYCp+DP/GJRGtDlPd7fiV9oXGGIcjW/ZOxLIvjGz8MA+uMZI9metHlgqbgwQ== + dependencies: + "@types/node" "*" + +"@types/body-parser@*": + version "1.19.1" + resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.19.1.tgz#0c0174c42a7d017b818303d4b5d969cb0b75929c" + integrity sha512-a6bTJ21vFOGIkwM0kzh9Yr89ziVxq4vYH2fQ6N8AeipEzai/cFK6aGMArIkUeIdRIgpwQa+2bXiLuUJCpSf2Cg== + dependencies: + "@types/connect" "*" + "@types/node" "*" + +"@types/connect@*": + version "3.4.35" + resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.35.tgz#5fcf6ae445e4021d1fc2219a4873cc73a3bb2ad1" + integrity sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ== + dependencies: + "@types/node" "*" + +"@types/content-disposition@*": + version "0.5.4" + resolved "https://registry.yarnpkg.com/@types/content-disposition/-/content-disposition-0.5.4.tgz#de48cf01c79c9f1560bcfd8ae43217ab028657f8" + integrity sha512-0mPF08jn9zYI0n0Q/Pnz7C4kThdSt+6LD4amsrYDDpgBfrVWa3TcCOxKX1zkGgYniGagRv8heN2cbh+CAn+uuQ== + +"@types/cookies@*": + version "0.7.7" + resolved "https://registry.yarnpkg.com/@types/cookies/-/cookies-0.7.7.tgz#7a92453d1d16389c05a5301eef566f34946cfd81" + integrity sha512-h7BcvPUogWbKCzBR2lY4oqaZbO3jXZksexYJVFvkrFeLgbZjQkU4x8pRq6eg2MHXQhY0McQdqmmsxRWlVAHooA== + dependencies: + "@types/connect" "*" + "@types/express" "*" + "@types/keygrip" "*" + "@types/node" "*" + +"@types/express-serve-static-core@^4.17.18": + version "4.17.23" + resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.23.tgz#721c371fc53fe7b3ea40d8977b209b90cb275f58" + integrity sha512-WYqTtTPTJn9kXMdnAH5HPPb7ctXvBpP4PfuOb8MV4OHPQWHhDZixGlhgR159lJPpKm23WOdoCkt2//cCEaOJkw== + dependencies: + "@types/node" "*" + "@types/qs" "*" + "@types/range-parser" "*" + +"@types/express@*": + version "4.17.13" + resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.13.tgz#a76e2995728999bab51a33fabce1d705a3709034" + integrity sha512-6bSZTPaTIACxn48l50SR+axgrqm6qXFIxrdAKaG6PaJk3+zuUr35hBlgT7vOmJcum+OEaIBLtHV/qloEAFITeA== + dependencies: + "@types/body-parser" "*" + "@types/express-serve-static-core" "^4.17.18" + "@types/qs" "*" + "@types/serve-static" "*" + +"@types/fs-capacitor@*": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@types/fs-capacitor/-/fs-capacitor-2.0.0.tgz#17113e25817f584f58100fb7a08eed288b81956e" + integrity sha512-FKVPOCFbhCvZxpVAMhdBdTfVfXUpsh15wFHgqOKxh9N9vzWZVuWCSijZ5T4U34XYNnuj2oduh6xcs1i+LPI+BQ== + dependencies: + "@types/node" "*" + +"@types/http-assert@*": + version "1.5.1" + resolved "https://registry.yarnpkg.com/@types/http-assert/-/http-assert-1.5.1.tgz#d775e93630c2469c2f980fc27e3143240335db3b" + integrity sha512-PGAK759pxyfXE78NbKxyfRcWYA/KwW17X290cNev/qAsn9eQIxkH4shoNBafH37wewhDG/0p1cHPbK6+SzZjWQ== + +"@types/http-errors@*": + version "1.8.1" + resolved "https://registry.yarnpkg.com/@types/http-errors/-/http-errors-1.8.1.tgz#e81ad28a60bee0328c6d2384e029aec626f1ae67" + integrity sha512-e+2rjEwK6KDaNOm5Aa9wNGgyS9oSZU/4pfSMMPYNOfjvFI0WVXm29+ITRFr6aKDvvKo7uU1jV68MW4ScsfDi7Q== + +"@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0": + version "2.0.3" + resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz#4ba8ddb720221f432e443bd5f9117fd22cfd4762" + integrity sha512-sz7iLqvVUg1gIedBOvlkxPlc8/uVzyS5OwGz1cKjXzkl3FpL3al0crU8YGU1WoHkxn0Wxbw5tyi6hvzJKNzFsw== + +"@types/istanbul-lib-report@*": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz#c14c24f18ea8190c118ee7562b7ff99a36552686" + integrity sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg== + dependencies: + "@types/istanbul-lib-coverage" "*" + +"@types/istanbul-reports@^3.0.0": + version "3.0.1" + resolved "https://registry.yarnpkg.com/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz#9153fe98bba2bd565a63add9436d6f0d7f8468ff" + integrity sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw== + dependencies: + "@types/istanbul-lib-report" "*" + +"@types/keygrip@*": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@types/keygrip/-/keygrip-1.0.2.tgz#513abfd256d7ad0bf1ee1873606317b33b1b2a72" + integrity sha512-GJhpTepz2udxGexqos8wgaBx4I/zWIDPh/KOGEwAqtuGDkOUJu5eFvwmdBX4AmB8Odsr+9pHCQqiAqDL/yKMKw== + +"@types/koa-compose@*": + version "3.2.5" + resolved "https://registry.yarnpkg.com/@types/koa-compose/-/koa-compose-3.2.5.tgz#85eb2e80ac50be95f37ccf8c407c09bbe3468e9d" + integrity sha512-B8nG/OoE1ORZqCkBVsup/AKcvjdgoHnfi4pZMn5UwAPCbhk/96xyv284eBYW8JlQbQ7zDmnpFr68I/40mFoIBQ== + dependencies: + "@types/koa" "*" + +"@types/koa@*": + version "2.13.4" + resolved "https://registry.yarnpkg.com/@types/koa/-/koa-2.13.4.tgz#10620b3f24a8027ef5cbae88b393d1b31205726b" + integrity sha512-dfHYMfU+z/vKtQB7NUrthdAEiSvnLebvBjwHtfFmpZmB7em2N3WVQdHgnFq+xvyVgxW5jKDmjWfLD3lw4g4uTw== + dependencies: + "@types/accepts" "*" + "@types/content-disposition" "*" + "@types/cookies" "*" + "@types/http-assert" "*" + "@types/http-errors" "*" + "@types/keygrip" "*" + "@types/koa-compose" "*" + "@types/node" "*" + +"@types/long@^4.0.0": + version "4.0.1" + resolved "https://registry.yarnpkg.com/@types/long/-/long-4.0.1.tgz#459c65fa1867dafe6a8f322c4c51695663cc55e9" + integrity sha512-5tXH6Bx/kNGd3MgffdmP4dy2Z+G4eaXw0SE81Tq3BNadtnMR5/ySMzX4SLEzHJzSmPNn4HIdpQsBvXMUykr58w== + +"@types/mime@^1": + version "1.3.2" + resolved "https://registry.yarnpkg.com/@types/mime/-/mime-1.3.2.tgz#93e25bf9ee75fe0fd80b594bc4feb0e862111b5a" + integrity sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw== + +"@types/node-fetch@2.5.10": + version "2.5.10" + resolved "https://registry.yarnpkg.com/@types/node-fetch/-/node-fetch-2.5.10.tgz#9b4d4a0425562f9fcea70b12cb3fcdd946ca8132" + integrity sha512-IpkX0AasN44hgEad0gEF/V6EgR5n69VEqPEgnmoM8GsIGro3PowbWs4tR6IhxUTyPLpOn+fiGG6nrQhcmoCuIQ== + dependencies: + "@types/node" "*" + form-data "^3.0.0" + +"@types/node@*": + version "16.0.0" + resolved "https://registry.yarnpkg.com/@types/node/-/node-16.0.0.tgz#067a6c49dc7a5c2412a505628e26902ae967bf6f" + integrity sha512-TmCW5HoZ2o2/z2EYi109jLqIaPIi9y/lc2LmDCWzuCi35bcaQ+OtUh6nwBiFK7SOu25FAU5+YKdqFZUwtqGSdg== + +"@types/node@^10.1.0": + version "10.17.60" + resolved "https://registry.yarnpkg.com/@types/node/-/node-10.17.60.tgz#35f3d6213daed95da7f0f73e75bcc6980e90597b" + integrity sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw== + +"@types/qs@*": + version "6.9.6" + resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.6.tgz#df9c3c8b31a247ec315e6996566be3171df4b3b1" + integrity sha512-0/HnwIfW4ki2D8L8c9GVcG5I72s9jP5GSLVF0VIXDW00kmIpA6O33G7a8n59Tmh7Nz0WUC3rSb7PTY/sdW2JzA== + +"@types/range-parser@*": + version "1.2.3" + resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.3.tgz#7ee330ba7caafb98090bece86a5ee44115904c2c" + integrity sha512-ewFXqrQHlFsgc09MK5jP5iR7vumV/BYayNC6PgJO2LPe8vrnNFyjQjSppfEngITi0qvfKtzFvgKymGheFM9UOA== + +"@types/serve-static@*": + version "1.13.10" + resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.13.10.tgz#f5e0ce8797d2d7cc5ebeda48a52c96c4fa47a8d9" + integrity sha512-nCkHGI4w7ZgAdNkrEu0bv+4xNV/XDqW+DydknebMOQwkpDGx8G+HTlj7R7ABI8i8nKxVw0wtKPi1D+lPOkh4YQ== + dependencies: + "@types/mime" "^1" + "@types/node" "*" + +"@types/ws@^7.0.0": + version "7.4.6" + resolved "https://registry.yarnpkg.com/@types/ws/-/ws-7.4.6.tgz#c4320845e43d45a7129bb32905e28781c71c1fff" + integrity sha512-ijZ1vzRawI7QoWnTNL8KpHixd2b2XVb9I9HAqI3triPsh1EC0xH0Eg6w2O3TKbDCgiNNlJqfrof6j4T2I+l9vw== + dependencies: + "@types/node" "*" + +"@types/yargs-parser@*": + version "20.2.1" + resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-20.2.1.tgz#3b9ce2489919d9e4fea439b76916abc34b2df129" + integrity sha512-7tFImggNeNBVMsn0vLrpn1H1uPrUBdnARPTpZoitY37ZrdJREzf7I16tMrlK3hen349gr1NYh8CmZQa7CTG6Aw== + +"@types/yargs@^15.0.0": + version "15.0.14" + resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-15.0.14.tgz#26d821ddb89e70492160b66d10a0eb6df8f6fb06" + integrity sha512-yEJzHoxf6SyQGhBhIYGXQDSCkJjB6HohDShto7m8vaKg9Yp0Yn8+71J9eakh2bnPg6BfsH9PRMhiRTZnd4eXGQ== + dependencies: + "@types/yargs-parser" "*" + +"@wry/equality@^0.1.2": + version "0.1.11" + resolved "https://registry.yarnpkg.com/@wry/equality/-/equality-0.1.11.tgz#35cb156e4a96695aa81a9ecc4d03787bc17f1790" + integrity sha512-mwEVBDUVODlsQQ5dfuLUS5/Tf7jqUKyhKYHmVi4fPB6bDMOfWvUPJmKgS1Z7Za/sOI3vzWt4+O7yCiL/70MogA== + dependencies: + tslib "^1.9.3" + +accepts@~1.3.7: + version "1.3.7" + resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.7.tgz#531bc726517a3b2b41f850021c6cc15eaab507cd" + integrity sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA== + dependencies: + mime-types "~2.1.24" + negotiator "0.6.2" + +agent-base@6, agent-base@^6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" + integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ== + dependencies: + debug "4" + +agentkeepalive@^4.1.3: + version "4.1.4" + resolved "https://registry.yarnpkg.com/agentkeepalive/-/agentkeepalive-4.1.4.tgz#d928028a4862cb11718e55227872e842a44c945b" + integrity sha512-+V/rGa3EuU74H6wR04plBb7Ks10FbtUQgRj/FQOG7uUIEuaINI+AiqJR1k6t3SVNs7o7ZjIdus6706qqzVq8jQ== + dependencies: + debug "^4.1.0" + depd "^1.1.2" + humanize-ms "^1.2.1" + +aggregate-error@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-3.1.0.tgz#92670ff50f5359bdb7a3e0d40d0ec30c5737687a" + integrity sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA== + dependencies: + clean-stack "^2.0.0" + indent-string "^4.0.0" + +ansi-regex@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.0.tgz#388539f55179bf39339c81af30a654d69f87cb75" + integrity sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg== + +ansi-styles@^4.0.0, ansi-styles@^4.1.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" + integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== + dependencies: + color-convert "^2.0.1" + +apollo-cache-control@^0.14.0: + version "0.14.0" + resolved "https://registry.yarnpkg.com/apollo-cache-control/-/apollo-cache-control-0.14.0.tgz#95f20c3e03e7994e0d1bd48c59aeaeb575ed0ce7" + integrity sha512-qN4BCq90egQrgNnTRMUHikLZZAprf3gbm8rC5Vwmc6ZdLolQ7bFsa769Hqi6Tq/lS31KLsXBLTOsRbfPHph12w== + dependencies: + apollo-server-env "^3.1.0" + apollo-server-plugin-base "^0.13.0" + +apollo-datasource@^0.9.0: + version "0.9.0" + resolved "https://registry.yarnpkg.com/apollo-datasource/-/apollo-datasource-0.9.0.tgz#b0b2913257a6103a5f4c03cb56d78a30e9d850db" + integrity sha512-y8H99NExU1Sk4TvcaUxTdzfq2SZo6uSj5dyh75XSQvbpH6gdAXIW9MaBcvlNC7n0cVPsidHmOcHOWxJ/pTXGjA== + dependencies: + apollo-server-caching "^0.7.0" + apollo-server-env "^3.1.0" + +apollo-graphql@^0.9.0, apollo-graphql@^0.9.3: + version "0.9.3" + resolved "https://registry.yarnpkg.com/apollo-graphql/-/apollo-graphql-0.9.3.tgz#1ca6f625322ae10a66f57a39642849a07a7a5dc9" + integrity sha512-rcAl2E841Iko4kSzj4Pt3PRBitmyq1MvoEmpl04TQSpGnoVgl1E/ZXuLBYxMTSnEAm7umn2IsoY+c6Ll9U/10A== + dependencies: + core-js-pure "^3.10.2" + lodash.sortby "^4.7.0" + sha.js "^2.4.11" + +apollo-link@^1.2.14: + version "1.2.14" + resolved "https://registry.yarnpkg.com/apollo-link/-/apollo-link-1.2.14.tgz#3feda4b47f9ebba7f4160bef8b977ba725b684d9" + integrity sha512-p67CMEFP7kOG1JZ0ZkYZwRDa369w5PIjtMjvrQd/HnIV8FRsHRqLqK+oAZQnFa1DDdZtOtHTi+aMIW6EatC2jg== + dependencies: + apollo-utilities "^1.3.0" + ts-invariant "^0.4.0" + tslib "^1.9.3" + zen-observable-ts "^0.8.21" + +apollo-reporting-protobuf@^0.8.0, "apollo-reporting-protobuf@^0.8.0 || ^3.0.0 || ^3.0.0-preview.2": + version "0.8.0" + resolved "https://registry.yarnpkg.com/apollo-reporting-protobuf/-/apollo-reporting-protobuf-0.8.0.tgz#ae9d967934d3d8ed816fc85a0d8068ef45c371b9" + integrity sha512-B3XmnkH6Y458iV6OsA7AhfwvTgeZnFq9nPVjbxmLKnvfkEl8hYADtz724uPa0WeBiD7DSFcnLtqg9yGmCkBohg== + dependencies: + "@apollo/protobufjs" "1.2.2" + +apollo-server-caching@^0.7.0, "apollo-server-caching@^0.7.0 || ^3.0.0 || ^3.0.0-preview.2": + version "0.7.0" + resolved "https://registry.yarnpkg.com/apollo-server-caching/-/apollo-server-caching-0.7.0.tgz#e6d1e68e3bb571cba63a61f60b434fb771c6ff39" + integrity sha512-MsVCuf/2FxuTFVhGLK13B+TZH9tBd2qkyoXKKILIiGcZ5CDUEBO14vIV63aNkMkS1xxvK2U4wBcuuNj/VH2Mkw== + dependencies: + lru-cache "^6.0.0" + +"apollo-server-core@^2.23.0 || ^3.0.0 || ^3.0.0-preview.2": + version "2.25.2" + resolved "https://registry.yarnpkg.com/apollo-server-core/-/apollo-server-core-2.25.2.tgz#ff65da5e512d9b5ca54c8e5e8c78ee28b5987247" + integrity sha512-lrohEjde2TmmDTO7FlOs8x5QQbAS0Sd3/t0TaK2TWaodfzi92QAvIsq321Mol6p6oEqmjm8POIDHW1EuJd7XMA== + dependencies: + "@apollographql/apollo-tools" "^0.5.0" + "@apollographql/graphql-playground-html" "1.6.27" + "@apollographql/graphql-upload-8-fork" "^8.1.3" + "@josephg/resolvable" "^1.0.0" + "@types/ws" "^7.0.0" + apollo-cache-control "^0.14.0" + apollo-datasource "^0.9.0" + apollo-graphql "^0.9.0" + apollo-reporting-protobuf "^0.8.0" + apollo-server-caching "^0.7.0" + apollo-server-env "^3.1.0" + apollo-server-errors "^2.5.0" + apollo-server-plugin-base "^0.13.0" + apollo-server-types "^0.9.0" + apollo-tracing "^0.15.0" + async-retry "^1.2.1" + fast-json-stable-stringify "^2.0.0" + graphql-extensions "^0.15.0" + graphql-tag "^2.11.0" + graphql-tools "^4.0.8" + loglevel "^1.6.7" + lru-cache "^6.0.0" + sha.js "^2.4.11" + subscriptions-transport-ws "^0.9.19" + uuid "^8.0.0" + +"apollo-server-env@^3.0.0 || ^4.0.0 || ^3.2.0-preview.2 || ^4.0.0-rc.0", apollo-server-env@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/apollo-server-env/-/apollo-server-env-3.1.0.tgz#0733c2ef50aea596cc90cf40a53f6ea2ad402cd0" + integrity sha512-iGdZgEOAuVop3vb0F2J3+kaBVi4caMoxefHosxmgzAbbSpvWehB8Y1QiSyyMeouYC38XNVk5wnZl+jdGSsWsIQ== + dependencies: + node-fetch "^2.6.1" + util.promisify "^1.0.0" + +apollo-server-errors@^2.5.0, "apollo-server-errors@^2.5.0 || ^3.0.0 || ^3.0.0-preview.2": + version "2.5.0" + resolved "https://registry.yarnpkg.com/apollo-server-errors/-/apollo-server-errors-2.5.0.tgz#5d1024117c7496a2979e3e34908b5685fe112b68" + integrity sha512-lO5oTjgiC3vlVg2RKr3RiXIIQ5pGXBFxYGGUkKDhTud3jMIhs+gel8L8zsEjKaKxkjHhCQAA/bcEfYiKkGQIvA== + +apollo-server-plugin-base@^0.13.0: + version "0.13.0" + resolved "https://registry.yarnpkg.com/apollo-server-plugin-base/-/apollo-server-plugin-base-0.13.0.tgz#3f85751a420d3c4625355b6cb3fbdd2acbe71f13" + integrity sha512-L3TMmq2YE6BU6I4Tmgygmd0W55L+6XfD9137k+cWEBFu50vRY4Re+d+fL5WuPkk5xSPKd/PIaqzidu5V/zz8Kg== + dependencies: + apollo-server-types "^0.9.0" + +apollo-server-types@^0.9.0, "apollo-server-types@^0.9.0 || ^3.0.0 || ^3.0.0-preview.2": + version "0.9.0" + resolved "https://registry.yarnpkg.com/apollo-server-types/-/apollo-server-types-0.9.0.tgz#ccf550b33b07c48c72f104fbe2876232b404848b" + integrity sha512-qk9tg4Imwpk732JJHBkhW0jzfG0nFsLqK2DY6UhvJf7jLnRePYsPxWfPiNkxni27pLE2tiNlCwoDFSeWqpZyBg== + dependencies: + apollo-reporting-protobuf "^0.8.0" + apollo-server-caching "^0.7.0" + apollo-server-env "^3.1.0" + +apollo-tracing@^0.15.0: + version "0.15.0" + resolved "https://registry.yarnpkg.com/apollo-tracing/-/apollo-tracing-0.15.0.tgz#237fbbbf669aee4370b7e9081b685eabaa8ce84a" + integrity sha512-UP0fztFvaZPHDhIB/J+qGuy6hWO4If069MGC98qVs0I8FICIGu4/8ykpX3X3K6RtaQ56EDAWKykCxFv4ScxMeA== + dependencies: + apollo-server-env "^3.1.0" + apollo-server-plugin-base "^0.13.0" + +apollo-utilities@^1.0.1, apollo-utilities@^1.3.0: + version "1.3.4" + resolved "https://registry.yarnpkg.com/apollo-utilities/-/apollo-utilities-1.3.4.tgz#6129e438e8be201b6c55b0f13ce49d2c7175c9cf" + integrity sha512-pk2hiWrCXMAy2fRPwEyhvka+mqwzeP60Jr1tRYi5xru+3ko94HI9o6lK0CT33/w4RDlxWchmdhDCrvdr+pHCig== + dependencies: + "@wry/equality" "^0.1.2" + fast-json-stable-stringify "^2.0.0" + ts-invariant "^0.4.0" + tslib "^1.10.0" + +array-flatten@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" + integrity sha1-ml9pkFGx5wczKPKgCJaLZOopVdI= + +async-retry@^1.2.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/async-retry/-/async-retry-1.3.1.tgz#139f31f8ddce50c0870b0ba558a6079684aaed55" + integrity sha512-aiieFW/7h3hY0Bq5d+ktDBejxuwR78vRu9hDUdR8rNhSaQ29VzPL4AoIRG7D/c7tdenwOcKvgPM6tIxB3cB6HA== + dependencies: + retry "0.12.0" + +asynckit@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" + integrity sha1-x57Zf380y48robyXkLzDZkdLS3k= + +available-typed-arrays@^1.0.2: + version "1.0.4" + resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.4.tgz#9e0ae84ecff20caae6a94a1c3bc39b955649b7a9" + integrity sha512-SA5mXJWrId1TaQjfxUYghbqQ/hYioKmLJvPJyDuYRtXXenFNMjj4hSSt1Cf1xsuXSXrtxrVC5Ot4eU6cOtBDdA== + +backo2@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/backo2/-/backo2-1.0.2.tgz#31ab1ac8b129363463e35b3ebb69f4dfcfba7947" + integrity sha1-MasayLEpNjRj41s+u2n038+6eUc= + +balanced-match@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" + integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== + +body-parser@1.19.0: + version "1.19.0" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.19.0.tgz#96b2709e57c9c4e09a6fd66a8fd979844f69f08a" + integrity sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw== + dependencies: + bytes "3.1.0" + content-type "~1.0.4" + debug "2.6.9" + depd "~1.1.2" + http-errors "1.7.2" + iconv-lite "0.4.24" + on-finished "~2.3.0" + qs "6.7.0" + raw-body "2.4.0" + type-is "~1.6.17" + +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +busboy@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/busboy/-/busboy-0.3.1.tgz#170899274c5bf38aae27d5c62b71268cd585fd1b" + integrity sha512-y7tTxhGKXcyBxRKAni+awqx8uqaJKrSFSNFSeRG5CsWNdmy2BIK+6VGWEW7TZnIO/533mtMEA4rOevQV815YJw== + dependencies: + dicer "0.3.0" + +bytes@3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.0.tgz#f6cf7933a360e0588fa9fde85651cdc7f805d1f6" + integrity sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg== + +cacache@^15.0.5: + version "15.2.0" + resolved "https://registry.yarnpkg.com/cacache/-/cacache-15.2.0.tgz#73af75f77c58e72d8c630a7a2858cb18ef523389" + integrity sha512-uKoJSHmnrqXgthDFx/IU6ED/5xd+NNGe+Bb+kLZy7Ku4P+BaiWEUflAKPZ7eAzsYGcsAGASJZsybXp+quEcHTw== + dependencies: + "@npmcli/move-file" "^1.0.1" + chownr "^2.0.0" + fs-minipass "^2.0.0" + glob "^7.1.4" + infer-owner "^1.0.4" + lru-cache "^6.0.0" + minipass "^3.1.1" + minipass-collect "^1.0.2" + minipass-flush "^1.0.5" + minipass-pipeline "^1.2.2" + mkdirp "^1.0.3" + p-map "^4.0.0" + promise-inflight "^1.0.1" + rimraf "^3.0.2" + ssri "^8.0.1" + tar "^6.0.2" + unique-filename "^1.1.1" + +call-bind@^1.0.0, call-bind@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" + integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA== + dependencies: + function-bind "^1.1.1" + get-intrinsic "^1.0.2" + +camel-case@4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/camel-case/-/camel-case-4.1.2.tgz#9728072a954f805228225a6deea6b38461e1bd5a" + integrity sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw== + dependencies: + pascal-case "^3.1.2" + tslib "^2.0.3" + +chalk@^4.0.0, chalk@^4.1.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.1.tgz#c80b3fab28bf6371e6863325eee67e618b77e6ad" + integrity sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + +chownr@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/chownr/-/chownr-2.0.0.tgz#15bfbe53d2eab4cf70f18a8cd68ebe5b3cb1dece" + integrity sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ== + +clean-stack@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-2.2.0.tgz#ee8472dbb129e727b31e8a10a427dee9dfe4008b" + integrity sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A== + +color-convert@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" + integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== + dependencies: + color-name "~1.1.4" + +color-name@~1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== + +combined-stream@^1.0.8: + version "1.0.8" + resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" + integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== + dependencies: + delayed-stream "~1.0.0" + +commander@^2.20.3: + version "2.20.3" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" + integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= + +content-disposition@0.5.3: + version "0.5.3" + resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.3.tgz#e130caf7e7279087c5616c2007d0485698984fbd" + integrity sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g== + dependencies: + safe-buffer "5.1.2" + +content-type@~1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" + integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA== + +cookie-signature@1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" + integrity sha1-4wOogrNCzD7oylE6eZmXNNqzriw= + +cookie@0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.0.tgz#beb437e7022b3b6d49019d088665303ebe9c14ba" + integrity sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg== + +core-js-pure@^3.10.2: + version "3.15.2" + resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.15.2.tgz#c8e0874822705f3385d3197af9348f7c9ae2e3ce" + integrity sha512-D42L7RYh1J2grW8ttxoY1+17Y4wXZeKe7uyplAI3FkNQyI5OgBIAjUfFiTPfL1rs0qLpxaabITNbjKl1Sp82tA== + +cssfilter@0.0.10: + version "0.0.10" + resolved "https://registry.yarnpkg.com/cssfilter/-/cssfilter-0.0.10.tgz#c6d2672632a2e5c83e013e6864a42ce8defd20ae" + integrity sha1-xtJnJjKi5cg+AT5oZKQs6N79IK4= + +dataloader@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/dataloader/-/dataloader-2.0.0.tgz#41eaf123db115987e21ca93c005cd7753c55fe6f" + integrity sha512-YzhyDAwA4TaQIhM5go+vCLmU0UikghC/t9DTQYZR2M/UvZ1MdOhPezSDZcjj9uqQJOMqjLcpWtyW2iNINdlatQ== + +debug@2.6.9: + version "2.6.9" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" + integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== + dependencies: + ms "2.0.0" + +debug@4, debug@^4.1.0: + version "4.3.2" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.2.tgz#f0a49c18ac8779e31d4a0c6029dfb76873c7428b" + integrity sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw== + dependencies: + ms "2.1.2" + +deep-equal@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-2.0.5.tgz#55cd2fe326d83f9cbf7261ef0e060b3f724c5cb9" + integrity sha512-nPiRgmbAtm1a3JsnLCf6/SLfXcjyN5v8L1TXzdCmHrXJ4hx+gW/w1YCcn7z8gJtSiDArZCgYtbao3QqLm/N1Sw== + dependencies: + call-bind "^1.0.0" + es-get-iterator "^1.1.1" + get-intrinsic "^1.0.1" + is-arguments "^1.0.4" + is-date-object "^1.0.2" + is-regex "^1.1.1" + isarray "^2.0.5" + object-is "^1.1.4" + object-keys "^1.1.1" + object.assign "^4.1.2" + regexp.prototype.flags "^1.3.0" + side-channel "^1.0.3" + which-boxed-primitive "^1.0.1" + which-collection "^1.0.1" + which-typed-array "^1.1.2" + +define-properties@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" + integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ== + dependencies: + object-keys "^1.0.12" + +delayed-stream@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" + integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk= + +depd@^1.1.2, depd@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" + integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak= + +deprecated-decorator@^0.1.6: + version "0.1.6" + resolved "https://registry.yarnpkg.com/deprecated-decorator/-/deprecated-decorator-0.1.6.tgz#00966317b7a12fe92f3cc831f7583af329b86c37" + integrity sha1-AJZjF7ehL+kvPMgx91g68ym4bDc= + +destroy@~1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" + integrity sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA= + +dicer@0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/dicer/-/dicer-0.3.0.tgz#eacd98b3bfbf92e8ab5c2fdb71aaac44bb06b872" + integrity sha512-MdceRRWqltEG2dZqO769g27N/3PXfcKl04VhYnBlo2YhH7zPi88VebsjTKclaOyiuMaGU72hTfw3VkUitGcVCA== + dependencies: + streamsearch "0.1.2" + +ee-first@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" + integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= + +encodeurl@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" + integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= + +encoding@^0.1.12: + version "0.1.13" + resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.13.tgz#56574afdd791f54a8e9b2785c0582a2d26210fa9" + integrity sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A== + dependencies: + iconv-lite "^0.6.2" + +err-code@^2.0.2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/err-code/-/err-code-2.0.3.tgz#23c2f3b756ffdfc608d30e27c9a941024807e7f9" + integrity sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA== + +es-abstract@^1.18.0-next.1, es-abstract@^1.18.0-next.2: + version "1.18.3" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.18.3.tgz#25c4c3380a27aa203c44b2b685bba94da31b63e0" + integrity sha512-nQIr12dxV7SSxE6r6f1l3DtAeEYdsGpps13dR0TwJg1S8gyp4ZPgy3FZcHBgbiQqnoqSTb+oC+kO4UQ0C/J8vw== + dependencies: + call-bind "^1.0.2" + es-to-primitive "^1.2.1" + function-bind "^1.1.1" + get-intrinsic "^1.1.1" + has "^1.0.3" + has-symbols "^1.0.2" + is-callable "^1.2.3" + is-negative-zero "^2.0.1" + is-regex "^1.1.3" + is-string "^1.0.6" + object-inspect "^1.10.3" + object-keys "^1.1.1" + object.assign "^4.1.2" + string.prototype.trimend "^1.0.4" + string.prototype.trimstart "^1.0.4" + unbox-primitive "^1.0.1" + +es-get-iterator@^1.1.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/es-get-iterator/-/es-get-iterator-1.1.2.tgz#9234c54aba713486d7ebde0220864af5e2b283f7" + integrity sha512-+DTO8GYwbMCwbywjimwZMHp8AuYXOS2JZFWoi2AlPOS3ebnII9w/NLpNZtA7A0YLaVDw+O7KFCeoIV7OPvM7hQ== + dependencies: + call-bind "^1.0.2" + get-intrinsic "^1.1.0" + has-symbols "^1.0.1" + is-arguments "^1.1.0" + is-map "^2.0.2" + is-set "^2.0.2" + is-string "^1.0.5" + isarray "^2.0.5" + +es-to-primitive@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a" + integrity sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA== + dependencies: + is-callable "^1.1.4" + is-date-object "^1.0.1" + is-symbol "^1.0.2" + +escape-html@~1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" + integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg= + +etag@~1.8.1: + version "1.8.1" + resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" + integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc= + +eventemitter3@^3.1.0: + version "3.1.2" + resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-3.1.2.tgz#2d3d48f9c346698fce83a85d7d664e98535df6e7" + integrity sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q== + +express@4.17.1: + version "4.17.1" + resolved "https://registry.yarnpkg.com/express/-/express-4.17.1.tgz#4491fc38605cf51f8629d39c2b5d026f98a4c134" + integrity sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g== + dependencies: + accepts "~1.3.7" + array-flatten "1.1.1" + body-parser "1.19.0" + content-disposition "0.5.3" + content-type "~1.0.4" + cookie "0.4.0" + cookie-signature "1.0.6" + debug "2.6.9" + depd "~1.1.2" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + finalhandler "~1.1.2" + fresh "0.5.2" + merge-descriptors "1.0.1" + methods "~1.1.2" + on-finished "~2.3.0" + parseurl "~1.3.3" + path-to-regexp "0.1.7" + proxy-addr "~2.0.5" + qs "6.7.0" + range-parser "~1.2.1" + safe-buffer "5.1.2" + send "0.17.1" + serve-static "1.14.1" + setprototypeof "1.1.1" + statuses "~1.5.0" + type-is "~1.6.18" + utils-merge "1.0.1" + vary "~1.1.2" + +fast-json-stable-stringify@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" + integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== + +finalhandler@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.2.tgz#b7e7d000ffd11938d0fdb053506f6ebabe9f587d" + integrity sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA== + dependencies: + debug "2.6.9" + encodeurl "~1.0.2" + escape-html "~1.0.3" + on-finished "~2.3.0" + parseurl "~1.3.3" + statuses "~1.5.0" + unpipe "~1.0.0" + +for-each@^0.3.3: + version "0.3.3" + resolved "https://registry.yarnpkg.com/for-each/-/for-each-0.3.3.tgz#69b447e88a0a5d32c3e7084f3f1710034b21376e" + integrity sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw== + dependencies: + is-callable "^1.1.3" + +foreach@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/foreach/-/foreach-2.0.5.tgz#0bee005018aeb260d0a3af3ae658dd0136ec1b99" + integrity sha1-C+4AUBiusmDQo6865ljdATbsG5k= + +form-data@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-3.0.1.tgz#ebd53791b78356a99af9a300d4282c4d5eb9755f" + integrity sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.8" + mime-types "^2.1.12" + +forwarded@0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811" + integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow== + +fresh@0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" + integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac= + +fs-capacitor@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/fs-capacitor/-/fs-capacitor-2.0.4.tgz#5a22e72d40ae5078b4fe64fe4d08c0d3fc88ad3c" + integrity sha512-8S4f4WsCryNw2mJJchi46YgB6CR5Ze+4L1h8ewl9tEpL4SJ3ZO+c/bS4BWhB8bK+O3TMqhuZarTitd0S0eh2pA== + +fs-minipass@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-2.1.0.tgz#7f5036fdbf12c63c169190cbe4199c852271f9fb" + integrity sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg== + dependencies: + minipass "^3.0.0" + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= + +function-bind@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" + integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== + +get-intrinsic@^1.0.1, get-intrinsic@^1.0.2, get-intrinsic@^1.1.0, get-intrinsic@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.1.tgz#15f59f376f855c446963948f0d24cd3637b4abc6" + integrity sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q== + dependencies: + function-bind "^1.1.1" + has "^1.0.3" + has-symbols "^1.0.1" + +glob@^7.1.3, glob@^7.1.4: + version "7.1.7" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.7.tgz#3b193e9233f01d42d0b3f78294bbeeb418f94a90" + integrity sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + +graphql-extensions@^0.15.0: + version "0.15.0" + resolved "https://registry.yarnpkg.com/graphql-extensions/-/graphql-extensions-0.15.0.tgz#3f291f9274876b0c289fa4061909a12678bd9817" + integrity sha512-bVddVO8YFJPwuACn+3pgmrEg6I8iBuYLuwvxiE+lcQQ7POotVZxm2rgGw0PvVYmWWf3DT7nTVDZ5ROh/ALp8mA== + dependencies: + "@apollographql/apollo-tools" "^0.5.0" + apollo-server-env "^3.1.0" + apollo-server-types "^0.9.0" + +graphql-tag@2.12.5, graphql-tag@^2.11.0: + version "2.12.5" + resolved "https://registry.yarnpkg.com/graphql-tag/-/graphql-tag-2.12.5.tgz#5cff974a67b417747d05c8d9f5f3cb4495d0db8f" + integrity sha512-5xNhP4063d16Pz3HBtKprutsPrmHZi5IdUGOWRxA2B6VF7BIRGOHZ5WQvDmJXZuPcBg7rYwaFxvQYjqkSdR3TQ== + dependencies: + tslib "^2.1.0" + +graphql-tools@^4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/graphql-tools/-/graphql-tools-4.0.8.tgz#e7fb9f0d43408fb0878ba66b522ce871bafe9d30" + integrity sha512-MW+ioleBrwhRjalKjYaLQbr+920pHBgy9vM/n47sswtns8+96sRn5M/G+J1eu7IMeKWiN/9p6tmwCHU7552VJg== + dependencies: + apollo-link "^1.2.14" + apollo-utilities "^1.0.1" + deprecated-decorator "^0.1.6" + iterall "^1.1.3" + uuid "^3.1.0" + +graphql@15.5.1: + version "15.5.1" + resolved "https://registry.yarnpkg.com/graphql/-/graphql-15.5.1.tgz#f2f84415d8985e7b84731e7f3536f8bb9d383aad" + integrity sha512-FeTRX67T3LoE3LWAxxOlW2K3Bz+rMYAC18rRguK4wgXaTZMiJwSUwDmPFo3UadAKbzirKIg5Qy+sNJXbpPRnQw== + +has-bigints@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.1.tgz#64fe6acb020673e3b78db035a5af69aa9d07b113" + integrity sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA== + +has-flag@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" + integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== + +has-symbols@^1.0.1, has-symbols@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.2.tgz#165d3070c00309752a1236a479331e3ac56f1423" + integrity sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw== + +has@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" + integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== + dependencies: + function-bind "^1.1.1" + +http-cache-semantics@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz#49e91c5cbf36c9b94bcfcd71c23d5249ec74e390" + integrity sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ== + +http-errors@1.7.2: + version "1.7.2" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.2.tgz#4f5029cf13239f31036e5b2e55292bcfbcc85c8f" + integrity sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg== + dependencies: + depd "~1.1.2" + inherits "2.0.3" + setprototypeof "1.1.1" + statuses ">= 1.5.0 < 2" + toidentifier "1.0.0" + +http-errors@^1.7.3: + version "1.8.0" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.8.0.tgz#75d1bbe497e1044f51e4ee9e704a62f28d336507" + integrity sha512-4I8r0C5JDhT5VkvI47QktDW75rNlGVsUf/8hzjCC/wkWI/jdTRmBb9aI7erSG82r1bjKY3F6k28WnsVxB1C73A== + dependencies: + depd "~1.1.2" + inherits "2.0.4" + setprototypeof "1.2.0" + statuses ">= 1.5.0 < 2" + toidentifier "1.0.0" + +http-errors@~1.7.2: + version "1.7.3" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.3.tgz#6c619e4f9c60308c38519498c14fbb10aacebb06" + integrity sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw== + dependencies: + depd "~1.1.2" + inherits "2.0.4" + setprototypeof "1.1.1" + statuses ">= 1.5.0 < 2" + toidentifier "1.0.0" + +http-proxy-agent@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz#8a8c8ef7f5932ccf953c296ca8291b95aa74aa3a" + integrity sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg== + dependencies: + "@tootallnate/once" "1" + agent-base "6" + debug "4" + +https-proxy-agent@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz#e2a90542abb68a762e0a0850f6c9edadfd8506b2" + integrity sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA== + dependencies: + agent-base "6" + debug "4" + +humanize-ms@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/humanize-ms/-/humanize-ms-1.2.1.tgz#c46e3159a293f6b896da29316d8b6fe8bb79bbed" + integrity sha1-xG4xWaKT9riW2ikxbYtv6Lt5u+0= + dependencies: + ms "^2.0.0" + +iconv-lite@0.4.24: + version "0.4.24" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" + integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== + dependencies: + safer-buffer ">= 2.1.2 < 3" + +iconv-lite@^0.6.2: + version "0.6.3" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.3.tgz#a52f80bf38da1952eb5c681790719871a1a72501" + integrity sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw== + dependencies: + safer-buffer ">= 2.1.2 < 3.0.0" + +imurmurhash@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" + integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= + +indent-string@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-4.0.0.tgz#624f8f4497d619b2d9768531d58f4122854d7251" + integrity sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg== + +infer-owner@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/infer-owner/-/infer-owner-1.0.4.tgz#c4cefcaa8e51051c2a40ba2ce8a3d27295af9467" + integrity sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A== + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2, inherits@2.0.4, inherits@^2.0.1: + version "2.0.4" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + +inherits@2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" + integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= + +ip@^1.1.5: + version "1.1.5" + resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.5.tgz#bdded70114290828c0a039e72ef25f5aaec4354a" + integrity sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo= + +ipaddr.js@1.9.1: + version "1.9.1" + resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" + integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== + +is-arguments@^1.0.4, is-arguments@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.1.0.tgz#62353031dfbee07ceb34656a6bde59efecae8dd9" + integrity sha512-1Ij4lOMPl/xB5kBDn7I+b2ttPMKa8szhEIrXDuXQD/oe3HJLTLhqhgGspwgyGd6MOywBUqVvYicF72lkgDnIHg== + dependencies: + call-bind "^1.0.0" + +is-bigint@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-bigint/-/is-bigint-1.0.2.tgz#ffb381442503235ad245ea89e45b3dbff040ee5a" + integrity sha512-0JV5+SOCQkIdzjBK9buARcV804Ddu7A0Qet6sHi3FimE9ne6m4BGQZfRn+NZiXbBk4F4XmHfDZIipLj9pX8dSA== + +is-boolean-object@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.1.1.tgz#3c0878f035cb821228d350d2e1e36719716a3de8" + integrity sha512-bXdQWkECBUIAcCkeH1unwJLIpZYaa5VvuygSyS/c2lf719mTKZDU5UdDRlpd01UjADgmW8RfqaP+mRaVPdr/Ng== + dependencies: + call-bind "^1.0.2" + +is-callable@^1.1.3, is-callable@^1.1.4, is-callable@^1.2.3: + version "1.2.3" + resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.3.tgz#8b1e0500b73a1d76c70487636f368e519de8db8e" + integrity sha512-J1DcMe8UYTBSrKezuIUTUwjXsho29693unXM2YhJUTR2txK/eG47bvNa/wipPFmZFgr/N6f1GA66dv0mEyTIyQ== + +is-date-object@^1.0.1, is-date-object@^1.0.2: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.4.tgz#550cfcc03afada05eea3dd30981c7b09551f73e5" + integrity sha512-/b4ZVsG7Z5XVtIxs/h9W8nvfLgSAyKYdtGWQLbqy6jA1icmgjf8WCoTKgeS4wy5tYaPePouzFMANbnj94c2Z+A== + +is-lambda@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-lambda/-/is-lambda-1.0.1.tgz#3d9877899e6a53efc0160504cde15f82e6f061d5" + integrity sha1-PZh3iZ5qU+/AFgUEzeFfgubwYdU= + +is-map@^2.0.1, is-map@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/is-map/-/is-map-2.0.2.tgz#00922db8c9bf73e81b7a335827bc2a43f2b91127" + integrity sha512-cOZFQQozTha1f4MxLFzlgKYPTyj26picdZTx82hbc/Xf4K/tZOOXSCkMvU4pKioRXGDLJRn0GM7Upe7kR721yg== + +is-negative-zero@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.1.tgz#3de746c18dda2319241a53675908d8f766f11c24" + integrity sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w== + +is-number-object@^1.0.4: + version "1.0.5" + resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.5.tgz#6edfaeed7950cff19afedce9fbfca9ee6dd289eb" + integrity sha512-RU0lI/n95pMoUKu9v1BZP5MBcZuNSVJkMkAG2dJqC4z2GlkGUNeH68SuHuBKBD/XFe+LHZ+f9BKkLET60Niedw== + +is-regex@^1.1.1, is-regex@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.3.tgz#d029f9aff6448b93ebbe3f33dac71511fdcbef9f" + integrity sha512-qSVXFz28HM7y+IWX6vLCsexdlvzT1PJNFSBuaQLQ5o0IEw8UDYW6/2+eCMVyIsbM8CNLX2a/QWmSpyxYEHY7CQ== + dependencies: + call-bind "^1.0.2" + has-symbols "^1.0.2" + +is-set@^2.0.1, is-set@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/is-set/-/is-set-2.0.2.tgz#90755fa4c2562dc1c5d4024760d6119b94ca18ec" + integrity sha512-+2cnTEZeY5z/iXGbLhPrOAaK/Mau5k5eXq9j14CpRTftq0pAJu2MwVRSZhyZWBzx3o6X795Lz6Bpb6R0GKf37g== + +is-string@^1.0.5, is-string@^1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.6.tgz#3fe5d5992fb0d93404f32584d4b0179a71b54a5f" + integrity sha512-2gdzbKUuqtQ3lYNrUTQYoClPhm7oQu4UdpSZMp1/DGgkHBT8E2Z1l0yMdb6D4zNAxwDiMv8MdulKROJGNl0Q0w== + +is-symbol@^1.0.2, is-symbol@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.4.tgz#a6dac93b635b063ca6872236de88910a57af139c" + integrity sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg== + dependencies: + has-symbols "^1.0.2" + +is-typed-array@^1.1.3: + version "1.1.5" + resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.5.tgz#f32e6e096455e329eb7b423862456aa213f0eb4e" + integrity sha512-S+GRDgJlR3PyEbsX/Fobd9cqpZBuvUS+8asRqYDMLCb2qMzt1oz5m5oxQCxOgUDxiWsOVNi4yaF+/uvdlHlYug== + dependencies: + available-typed-arrays "^1.0.2" + call-bind "^1.0.2" + es-abstract "^1.18.0-next.2" + foreach "^2.0.5" + has-symbols "^1.0.1" + +is-weakmap@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-weakmap/-/is-weakmap-2.0.1.tgz#5008b59bdc43b698201d18f62b37b2ca243e8cf2" + integrity sha512-NSBR4kH5oVj1Uwvv970ruUkCV7O1mzgVFO4/rev2cLRda9Tm9HrL70ZPut4rOHgY0FNrUu9BCbXA2sdQ+x0chA== + +is-weakset@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-weakset/-/is-weakset-2.0.1.tgz#e9a0af88dbd751589f5e50d80f4c98b780884f83" + integrity sha512-pi4vhbhVHGLxohUw7PhGsueT4vRGFoXhP7+RGN0jKIv9+8PWYCQTqtADngrxOm2g46hoH0+g8uZZBzMrvVGDmw== + +isarray@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.5.tgz#8af1e4c1221244cc62459faf38940d4e644a5723" + integrity sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw== + +iterall@^1.1.3, iterall@^1.2.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/iterall/-/iterall-1.3.0.tgz#afcb08492e2915cbd8a0884eb93a8c94d0d72fea" + integrity sha512-QZ9qOMdF+QLHxy1QIpUHUU1D5pS2CG2P69LF6L6CPjPYA/XMOmKV3PZpawHoAjHNyB0swdVTRxdYT4tbBbxqwg== + +lodash.sortby@^4.7.0: + version "4.7.0" + resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438" + integrity sha1-7dFMgk4sycHgsKG0K7UhBRakJDg= + +lodash.xorby@^4.7.0: + version "4.7.0" + resolved "https://registry.yarnpkg.com/lodash.xorby/-/lodash.xorby-4.7.0.tgz#9c19a6f9f063a6eb53dd03c1b6871799801463d7" + integrity sha1-nBmm+fBjputT3QPBtocXmYAUY9c= + +loglevel@^1.6.1, loglevel@^1.6.7: + version "1.7.1" + resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.7.1.tgz#005fde2f5e6e47068f935ff28573e125ef72f197" + integrity sha512-Hesni4s5UkWkwCGJMQGAh71PaLUmKFM60dHvq0zi/vDhhrzuk+4GgNbTXJ12YYQJn6ZKBDNIjYcuQGKudvqrIw== + +long@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/long/-/long-4.0.0.tgz#9a7b71cfb7d361a194ea555241c92f7468d5bf28" + integrity sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA== + +lower-case@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/lower-case/-/lower-case-2.0.2.tgz#6fa237c63dbdc4a82ca0fd882e4722dc5e634e28" + integrity sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg== + dependencies: + tslib "^2.0.3" + +lru-cache@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" + integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== + dependencies: + yallist "^4.0.0" + +make-fetch-happen@^8.0.0: + version "8.0.14" + resolved "https://registry.yarnpkg.com/make-fetch-happen/-/make-fetch-happen-8.0.14.tgz#aaba73ae0ab5586ad8eaa68bd83332669393e222" + integrity sha512-EsS89h6l4vbfJEtBZnENTOFk8mCRpY5ru36Xe5bcX1KYIli2mkSHqoFsp5O1wMDvTJJzxe/4THpCTtygjeeGWQ== + dependencies: + agentkeepalive "^4.1.3" + cacache "^15.0.5" + http-cache-semantics "^4.1.0" + http-proxy-agent "^4.0.1" + https-proxy-agent "^5.0.0" + is-lambda "^1.0.1" + lru-cache "^6.0.0" + minipass "^3.1.3" + minipass-collect "^1.0.2" + minipass-fetch "^1.3.2" + minipass-flush "^1.0.5" + minipass-pipeline "^1.2.4" + promise-retry "^2.0.1" + socks-proxy-agent "^5.0.0" + ssri "^8.0.0" + +media-typer@0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" + integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g= + +merge-descriptors@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" + integrity sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E= + +methods@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" + integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4= + +mime-db@1.48.0: + version "1.48.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.48.0.tgz#e35b31045dd7eada3aaad537ed88a33afbef2d1d" + integrity sha512-FM3QwxV+TnZYQ2aRqhlKBMHxk10lTbMt3bBkMAp54ddrNeVSfcQYOOKuGuy3Ddrm38I04If834fOUSq1yzslJQ== + +mime-types@^2.1.12, mime-types@~2.1.24: + version "2.1.31" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.31.tgz#a00d76b74317c61f9c2db2218b8e9f8e9c5c9e6b" + integrity sha512-XGZnNzm3QvgKxa8dpzyhFTHmpP3l5YNusmne07VUOXxou9CqUqYa/HBy124RqtVh/O2pECas/MOcsDgpilPOPg== + dependencies: + mime-db "1.48.0" + +mime@1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" + integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== + +minimatch@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" + integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== + dependencies: + brace-expansion "^1.1.7" + +minipass-collect@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/minipass-collect/-/minipass-collect-1.0.2.tgz#22b813bf745dc6edba2576b940022ad6edc8c617" + integrity sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA== + dependencies: + minipass "^3.0.0" + +minipass-fetch@^1.3.2: + version "1.3.3" + resolved "https://registry.yarnpkg.com/minipass-fetch/-/minipass-fetch-1.3.3.tgz#34c7cea038c817a8658461bf35174551dce17a0a" + integrity sha512-akCrLDWfbdAWkMLBxJEeWTdNsjML+dt5YgOI4gJ53vuO0vrmYQkUPxa6j6V65s9CcePIr2SSWqjT2EcrNseryQ== + dependencies: + minipass "^3.1.0" + minipass-sized "^1.0.3" + minizlib "^2.0.0" + optionalDependencies: + encoding "^0.1.12" + +minipass-flush@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/minipass-flush/-/minipass-flush-1.0.5.tgz#82e7135d7e89a50ffe64610a787953c4c4cbb373" + integrity sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw== + dependencies: + minipass "^3.0.0" + +minipass-pipeline@^1.2.2, minipass-pipeline@^1.2.4: + version "1.2.4" + resolved "https://registry.yarnpkg.com/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz#68472f79711c084657c067c5c6ad93cddea8214c" + integrity sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A== + dependencies: + minipass "^3.0.0" + +minipass-sized@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/minipass-sized/-/minipass-sized-1.0.3.tgz#70ee5a7c5052070afacfbc22977ea79def353b70" + integrity sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g== + dependencies: + minipass "^3.0.0" + +minipass@^3.0.0, minipass@^3.1.0, minipass@^3.1.1, minipass@^3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-3.1.3.tgz#7d42ff1f39635482e15f9cdb53184deebd5815fd" + integrity sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg== + dependencies: + yallist "^4.0.0" + +minizlib@^2.0.0, minizlib@^2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-2.1.2.tgz#e90d3466ba209b932451508a11ce3d3632145931" + integrity sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg== + dependencies: + minipass "^3.0.0" + yallist "^4.0.0" + +mkdirp@^1.0.3, mkdirp@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" + integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== + +ms@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= + +ms@2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" + integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg== + +ms@2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" + integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== + +ms@^2.0.0: + version "2.1.3" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" + integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== + +negotiator@0.6.2: + version "0.6.2" + resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.2.tgz#feacf7ccf525a77ae9634436a64883ffeca346fb" + integrity sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw== + +no-case@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/no-case/-/no-case-3.0.4.tgz#d361fd5c9800f558551a8369fc0dcd4662b6124d" + integrity sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg== + dependencies: + lower-case "^2.0.2" + tslib "^2.0.3" + +node-fetch@^2.6.1: + version "2.6.1" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052" + integrity sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw== + +object-inspect@^1.10.3, object-inspect@^1.9.0: + version "1.10.3" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.10.3.tgz#c2aa7d2d09f50c99375704f7a0adf24c5782d369" + integrity sha512-e5mCJlSH7poANfC8z8S9s9S2IN5/4Zb3aZ33f5s8YqoazCFzNLloLU8r5VCG+G7WoqLvAAZoVMcy3tp/3X0Plw== + +object-is@^1.1.4: + version "1.1.5" + resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.1.5.tgz#b9deeaa5fc7f1846a0faecdceec138e5778f53ac" + integrity sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + +object-keys@^1.0.12, object-keys@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" + integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== + +object-path@^0.11.4: + version "0.11.5" + resolved "https://registry.yarnpkg.com/object-path/-/object-path-0.11.5.tgz#d4e3cf19601a5140a55a16ad712019a9c50b577a" + integrity sha512-jgSbThcoR/s+XumvGMTMf81QVBmah+/Q7K7YduKeKVWL7N111unR2d6pZZarSk6kY/caeNxUDyxOvMWyzoU2eg== + +object.assign@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.2.tgz#0ed54a342eceb37b38ff76eb831a0e788cb63940" + integrity sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ== + dependencies: + call-bind "^1.0.0" + define-properties "^1.1.3" + has-symbols "^1.0.1" + object-keys "^1.1.1" + +object.getownpropertydescriptors@^2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.2.tgz#1bd63aeacf0d5d2d2f31b5e393b03a7c601a23f7" + integrity sha512-WtxeKSzfBjlzL+F9b7M7hewDzMwy+C8NRssHd1YrNlzHzIDrXcXiNOMrezdAEM4UXixgV+vvnyBeN7Rygl2ttQ== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + es-abstract "^1.18.0-next.2" + +on-finished@~2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" + integrity sha1-IPEzZIGwg811M3mSoWlxqi2QaUc= + dependencies: + ee-first "1.1.1" + +once@^1.3.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= + dependencies: + wrappy "1" + +p-map@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/p-map/-/p-map-4.0.0.tgz#bb2f95a5eda2ec168ec9274e06a747c3e2904d2b" + integrity sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ== + dependencies: + aggregate-error "^3.0.0" + +parseurl@~1.3.3: + version "1.3.3" + resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" + integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== + +pascal-case@^3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/pascal-case/-/pascal-case-3.1.2.tgz#b48e0ef2b98e205e7c1dae747d0b1508237660eb" + integrity sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g== + dependencies: + no-case "^3.0.4" + tslib "^2.0.3" + +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= + +path-to-regexp@0.1.7: + version "0.1.7" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" + integrity sha1-32BBeABfUi8V60SQ5yR6G/qmf4w= + +pretty-format@^26.0.0: + version "26.6.2" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-26.6.2.tgz#e35c2705f14cb7fe2fe94fa078345b444120fc93" + integrity sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg== + dependencies: + "@jest/types" "^26.6.2" + ansi-regex "^5.0.0" + ansi-styles "^4.0.0" + react-is "^17.0.1" + +promise-inflight@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3" + integrity sha1-mEcocL8igTL8vdhoEputEsPAKeM= + +promise-retry@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/promise-retry/-/promise-retry-2.0.1.tgz#ff747a13620ab57ba688f5fc67855410c370da22" + integrity sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g== + dependencies: + err-code "^2.0.2" + retry "^0.12.0" + +proxy-addr@~2.0.5: + version "2.0.7" + resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.7.tgz#f19fe69ceab311eeb94b42e70e8c2070f9ba1025" + integrity sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg== + dependencies: + forwarded "0.2.0" + ipaddr.js "1.9.1" + +qs@6.7.0: + version "6.7.0" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.7.0.tgz#41dc1a015e3d581f1621776be31afb2876a9b1bc" + integrity sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ== + +range-parser@~1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" + integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== + +raw-body@2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.4.0.tgz#a1ce6fb9c9bc356ca52e89256ab59059e13d0332" + integrity sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q== + dependencies: + bytes "3.1.0" + http-errors "1.7.2" + iconv-lite "0.4.24" + unpipe "1.0.0" + +react-is@^17.0.1: + version "17.0.2" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0" + integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w== + +regexp.prototype.flags@^1.3.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.3.1.tgz#7ef352ae8d159e758c0eadca6f8fcb4eef07be26" + integrity sha512-JiBdRBq91WlY7uRJ0ds7R+dU02i6LKi8r3BuQhNXn+kmeLN+EfHhfjqMRis1zJxnlu88hq/4dx0P2OP3APRTOA== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + +retry@0.12.0, retry@^0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/retry/-/retry-0.12.0.tgz#1b42a6266a21f07421d1b0b54b7dc167b01c013b" + integrity sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs= + +rimraf@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" + integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== + dependencies: + glob "^7.1.3" + +safe-buffer@5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" + integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== + +safe-buffer@^5.0.1: + version "5.2.1" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" + integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== + +"safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0": + version "2.1.2" + resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== + +send@0.17.1: + version "0.17.1" + resolved "https://registry.yarnpkg.com/send/-/send-0.17.1.tgz#c1d8b059f7900f7466dd4938bdc44e11ddb376c8" + integrity sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg== + dependencies: + debug "2.6.9" + depd "~1.1.2" + destroy "~1.0.4" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + fresh "0.5.2" + http-errors "~1.7.2" + mime "1.6.0" + ms "2.1.1" + on-finished "~2.3.0" + range-parser "~1.2.1" + statuses "~1.5.0" + +serve-static@1.14.1: + version "1.14.1" + resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.14.1.tgz#666e636dc4f010f7ef29970a88a674320898b2f9" + integrity sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg== + dependencies: + encodeurl "~1.0.2" + escape-html "~1.0.3" + parseurl "~1.3.3" + send "0.17.1" + +setprototypeof@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.1.tgz#7e95acb24aa92f5885e0abef5ba131330d4ae683" + integrity sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw== + +setprototypeof@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424" + integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== + +sha.js@^2.4.11: + version "2.4.11" + resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.11.tgz#37a5cf0b81ecbc6943de109ba2960d1b26584ae7" + integrity sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ== + dependencies: + inherits "^2.0.1" + safe-buffer "^5.0.1" + +side-channel@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf" + integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw== + dependencies: + call-bind "^1.0.0" + get-intrinsic "^1.0.2" + object-inspect "^1.9.0" + +smart-buffer@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/smart-buffer/-/smart-buffer-4.1.0.tgz#91605c25d91652f4661ea69ccf45f1b331ca21ba" + integrity sha512-iVICrxOzCynf/SNaBQCw34eM9jROU/s5rzIhpOvzhzuYHfJR/DhZfDkXiZSgKXfgv26HT3Yni3AV/DGw0cGnnw== + +socks-proxy-agent@^5.0.0: + version "5.0.1" + resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-5.0.1.tgz#032fb583048a29ebffec2e6a73fca0761f48177e" + integrity sha512-vZdmnjb9a2Tz6WEQVIurybSwElwPxMZaIc7PzqbJTrezcKNznv6giT7J7tZDZ1BojVaa1jvO/UiUdhDVB0ACoQ== + dependencies: + agent-base "^6.0.2" + debug "4" + socks "^2.3.3" + +socks@^2.3.3: + version "2.6.1" + resolved "https://registry.yarnpkg.com/socks/-/socks-2.6.1.tgz#989e6534a07cf337deb1b1c94aaa44296520d30e" + integrity sha512-kLQ9N5ucj8uIcxrDwjm0Jsqk06xdpBjGNQtpXy4Q8/QY2k+fY7nZH8CARy+hkbG+SGAovmzzuauCpBlb8FrnBA== + dependencies: + ip "^1.1.5" + smart-buffer "^4.1.0" + +ssri@^8.0.0, ssri@^8.0.1: + version "8.0.1" + resolved "https://registry.yarnpkg.com/ssri/-/ssri-8.0.1.tgz#638e4e439e2ffbd2cd289776d5ca457c4f51a2af" + integrity sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ== + dependencies: + minipass "^3.1.1" + +"statuses@>= 1.5.0 < 2", statuses@~1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" + integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow= + +streamsearch@0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/streamsearch/-/streamsearch-0.1.2.tgz#808b9d0e56fc273d809ba57338e929919a1a9f1a" + integrity sha1-gIudDlb8Jz2Am6VzOOkpkZoanxo= + +string.prototype.trimend@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz#e75ae90c2942c63504686c18b287b4a0b1a45f80" + integrity sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + +string.prototype.trimstart@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz#b36399af4ab2999b4c9c648bd7a3fb2bb26feeed" + integrity sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + +subscriptions-transport-ws@^0.9.19: + version "0.9.19" + resolved "https://registry.yarnpkg.com/subscriptions-transport-ws/-/subscriptions-transport-ws-0.9.19.tgz#10ca32f7e291d5ee8eb728b9c02e43c52606cdcf" + integrity sha512-dxdemxFFB0ppCLg10FTtRqH/31FNRL1y1BQv8209MK5I4CwALb7iihQg+7p65lFcIl8MHatINWBLOqpgU4Kyyw== + dependencies: + backo2 "^1.0.2" + eventemitter3 "^3.1.0" + iterall "^1.2.1" + symbol-observable "^1.0.4" + ws "^5.2.0 || ^6.0.0 || ^7.0.0" + +supports-color@^7.1.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" + integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== + dependencies: + has-flag "^4.0.0" + +symbol-observable@^1.0.4: + version "1.2.0" + resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.2.0.tgz#c22688aed4eab3cdc2dfeacbb561660560a00804" + integrity sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ== + +tar@^6.0.2: + version "6.1.0" + resolved "https://registry.yarnpkg.com/tar/-/tar-6.1.0.tgz#d1724e9bcc04b977b18d5c573b333a2207229a83" + integrity sha512-DUCttfhsnLCjwoDoFcI+B2iJgYa93vBnDUATYEeRx6sntCTdN01VnqsIuTlALXla/LWooNg0yEGeB+Y8WdFxGA== + dependencies: + chownr "^2.0.0" + fs-minipass "^2.0.0" + minipass "^3.0.0" + minizlib "^2.1.1" + mkdirp "^1.0.3" + yallist "^4.0.0" + +toidentifier@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.0.tgz#7e1be3470f1e77948bc43d94a3c8f4d7752ba553" + integrity sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw== + +ts-invariant@^0.4.0: + version "0.4.4" + resolved "https://registry.yarnpkg.com/ts-invariant/-/ts-invariant-0.4.4.tgz#97a523518688f93aafad01b0e80eb803eb2abd86" + integrity sha512-uEtWkFM/sdZvRNNDL3Ehu4WVpwaulhwQszV8mrtcdeE8nN00BV9mAmQ88RkrBhFgl9gMgvjJLAQcZbnPXI9mlA== + dependencies: + tslib "^1.9.3" + +tslib@^1.10.0, tslib@^1.9.3: + version "1.14.1" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" + integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== + +tslib@^2.0.3, tslib@^2.1.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.3.0.tgz#803b8cdab3e12ba581a4ca41c8839bbb0dacb09e" + integrity sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg== + +tslib@~2.0.1: + version "2.0.3" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.0.3.tgz#8e0741ac45fc0c226e58a17bfc3e64b9bc6ca61c" + integrity sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ== + +tslib@~2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.1.0.tgz#da60860f1c2ecaa5703ab7d39bc05b6bf988b97a" + integrity sha512-hcVC3wYEziELGGmEEXue7D75zbwIIVUMWAVbHItGPx0ziyXxrOMQx4rQEVEV45Ut/1IotuEvwqPopzIOkDMf0A== + +tslib@~2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.2.0.tgz#fb2c475977e35e241311ede2693cee1ec6698f5c" + integrity sha512-gS9GVHRU+RGn5KQM2rllAlR3dU6m7AcpJKdtH8gFvQiC4Otgk98XnmMU+nZenHt/+VhnBPWwgrJsyrdcw6i23w== + +type-is@~1.6.17, type-is@~1.6.18: + version "1.6.18" + resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" + integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g== + dependencies: + media-typer "0.3.0" + mime-types "~2.1.24" + +unbox-primitive@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.1.tgz#085e215625ec3162574dc8859abee78a59b14471" + integrity sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw== + dependencies: + function-bind "^1.1.1" + has-bigints "^1.0.1" + has-symbols "^1.0.2" + which-boxed-primitive "^1.0.2" + +unique-filename@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/unique-filename/-/unique-filename-1.1.1.tgz#1d69769369ada0583103a1e6ae87681b56573230" + integrity sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ== + dependencies: + unique-slug "^2.0.0" + +unique-slug@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/unique-slug/-/unique-slug-2.0.2.tgz#baabce91083fc64e945b0f3ad613e264f7cd4e6c" + integrity sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w== + dependencies: + imurmurhash "^0.1.4" + +unpipe@1.0.0, unpipe@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" + integrity sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw= + +util.promisify@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/util.promisify/-/util.promisify-1.1.1.tgz#77832f57ced2c9478174149cae9b96e9918cd54b" + integrity sha512-/s3UsZUrIfa6xDhr7zZhnE9SLQ5RIXyYfiVnMMyMDzOc8WhWN4Nbh36H842OyurKbCDAesZOJaVyvmSl6fhGQw== + dependencies: + call-bind "^1.0.0" + define-properties "^1.1.3" + for-each "^0.3.3" + has-symbols "^1.0.1" + object.getownpropertydescriptors "^2.1.1" + +utils-merge@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" + integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM= + +uuid@^3.1.0: + version "3.4.0" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" + integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== + +uuid@^8.0.0: + version "8.3.2" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" + integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== + +value-or-promise@1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/value-or-promise/-/value-or-promise-1.0.6.tgz#218aa4794aa2ee24dcf48a29aba4413ed584747f" + integrity sha512-9r0wQsWD8z/BxPOvnwbPf05ZvFngXyouE9EKB+5GbYix+BYnAwrIChCUyFIinfbf2FL/U71z+CPpbnmTdxrwBg== + +vary@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" + integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw= + +which-boxed-primitive@^1.0.1, which-boxed-primitive@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz#13757bc89b209b049fe5d86430e21cf40a89a8e6" + integrity sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg== + dependencies: + is-bigint "^1.0.1" + is-boolean-object "^1.1.0" + is-number-object "^1.0.4" + is-string "^1.0.5" + is-symbol "^1.0.3" + +which-collection@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/which-collection/-/which-collection-1.0.1.tgz#70eab71ebbbd2aefaf32f917082fc62cdcb70906" + integrity sha512-W8xeTUwaln8i3K/cY1nGXzdnVZlidBcagyNFtBdD5kxnb4TvGKR7FfSIS3mYpwWS1QUCutfKz8IY8RjftB0+1A== + dependencies: + is-map "^2.0.1" + is-set "^2.0.1" + is-weakmap "^2.0.1" + is-weakset "^2.0.1" + +which-typed-array@^1.1.2: + version "1.1.4" + resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.4.tgz#8fcb7d3ee5adf2d771066fba7cf37e32fe8711ff" + integrity sha512-49E0SpUe90cjpoc7BOJwyPHRqSAd12c10Qm2amdEZrJPCY2NDxaW01zHITrem+rnETY3dwrbH3UUrUwagfCYDA== + dependencies: + available-typed-arrays "^1.0.2" + call-bind "^1.0.0" + es-abstract "^1.18.0-next.1" + foreach "^2.0.5" + function-bind "^1.1.1" + has-symbols "^1.0.1" + is-typed-array "^1.1.3" + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= + +"ws@^5.2.0 || ^6.0.0 || ^7.0.0": + version "7.5.2" + resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.2.tgz#09cc8fea3bec1bc5ed44ef51b42f945be36900f6" + integrity sha512-lkF7AWRicoB9mAgjeKbGqVUekLnSNO4VjKVnuPHpQeOxZOErX6BPXwJk70nFslRCEEA8EVW7ZjKwXaP9N+1sKQ== + +xss@^1.0.8: + version "1.0.9" + resolved "https://registry.yarnpkg.com/xss/-/xss-1.0.9.tgz#3ffd565571ff60d2e40db7f3b80b4677bec770d2" + integrity sha512-2t7FahYnGJys6DpHLhajusId7R0Pm2yTmuL0GV9+mV0ZlaLSnb2toBmppATfg5sWIhZQGlsTLoecSzya+l4EAQ== + dependencies: + commander "^2.20.3" + cssfilter "0.0.10" + +yallist@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" + integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== + +zen-observable-ts@^0.8.21: + version "0.8.21" + resolved "https://registry.yarnpkg.com/zen-observable-ts/-/zen-observable-ts-0.8.21.tgz#85d0031fbbde1eba3cd07d3ba90da241215f421d" + integrity sha512-Yj3yXweRc8LdRMrCC8nIc4kkjWecPAUVh0TI0OUrWXx6aX790vLcDlWca6I4vsyCGH3LpWxq0dJRcMOFoVqmeg== + dependencies: + tslib "^1.9.3" + zen-observable "^0.8.0" + +zen-observable@^0.8.0: + version "0.8.15" + resolved "https://registry.yarnpkg.com/zen-observable/-/zen-observable-0.8.15.tgz#96415c512d8e3ffd920afd3889604e30b9eaac15" + integrity sha512-PQ2PC7R9rslx84ndNBZB/Dkv8V8fZEpk83RLgXtYd0fwUgEjseMn1Dgajh2x6S8QbZAFa9p2qVCEuYZNgve0dQ== diff --git a/benchmark/utils.js b/benchmark/utils.js new file mode 100644 index 00000000000..df74173972c --- /dev/null +++ b/benchmark/utils.js @@ -0,0 +1,23 @@ +import http from "k6/http"; + +const params = { + headers: { + "Content-Type": "application/json", + }, +}; + +export function checkNoErrors(resp) { + return !("errors" in resp.json()); +} + +export function graphql({ query, operationName, variables, endpoint }) { + return http.post( + endpoint, + JSON.stringify({ + query, + operationName, + variables, + }), + params + ); +} diff --git a/package.json b/package.json index 04be99a7728..1166df450d4 100644 --- a/package.json +++ b/package.json @@ -88,7 +88,8 @@ "packages": [ "./packages/*", "./packages/loaders/*", - "./website" + "./website", + "./benchmark/*" ], "nohoist": [ "@graphql-tools/website/@docusaurus/*" diff --git a/packages/batch-delegate/src/getLoader.ts b/packages/batch-delegate/src/getLoader.ts index 5b62f0d0ff0..016c4565f4a 100644 --- a/packages/batch-delegate/src/getLoader.ts +++ b/packages/batch-delegate/src/getLoader.ts @@ -51,6 +51,8 @@ function createBatchFn(options: BatchDelegateOptions) { }; } +const cacheKeyFn = (key: any) => (typeof key === 'object' ? JSON.stringify(key) : key); + export function getLoader(options: BatchDelegateOptions): DataLoader { const fieldName = options.fieldName ?? options.info.fieldName; @@ -58,13 +60,19 @@ export function getLoader(options: BatchDelegateOptions options.info.fieldNodes ); + // Prevents the keys to be passed with the same structure + const dataLoaderOptions: DataLoader.Options = { + cacheKeyFn, + ...options.dataLoaderOptions, + }; + if (cache2 === undefined) { cache2 = new WeakMap(); cache1.set(options.info.fieldNodes, cache2); const loaders = Object.create(null); cache2.set(options.schema, loaders); const batchFn = createBatchFn(options); - const loader = new DataLoader(keys => batchFn(keys), options.dataLoaderOptions); + const loader = new DataLoader(keys => batchFn(keys), dataLoaderOptions); loaders[fieldName] = loader; return loader; } @@ -75,7 +83,7 @@ export function getLoader(options: BatchDelegateOptions loaders = Object.create(null) as Record>; cache2.set(options.schema, loaders); const batchFn = createBatchFn(options); - const loader = new DataLoader(keys => batchFn(keys), options.dataLoaderOptions); + const loader = new DataLoader(keys => batchFn(keys), dataLoaderOptions); loaders[fieldName] = loader; return loader; } @@ -84,7 +92,7 @@ export function getLoader(options: BatchDelegateOptions if (loader === undefined) { const batchFn = createBatchFn(options); - loader = new DataLoader(keys => batchFn(keys), options.dataLoaderOptions); + loader = new DataLoader(keys => batchFn(keys), dataLoaderOptions); loaders[fieldName] = loader; } diff --git a/packages/delegate/src/transforms/CheckResultAndHandleErrors.ts b/packages/delegate/src/transforms/CheckResultAndHandleErrors.ts index bb1de4a5cdc..15f2b473dc8 100644 --- a/packages/delegate/src/transforms/CheckResultAndHandleErrors.ts +++ b/packages/delegate/src/transforms/CheckResultAndHandleErrors.ts @@ -20,7 +20,7 @@ export default class CheckResultAndHandleErrors implements Transform { ): ExecutionResult { return checkResultAndHandleErrors( originalResult, - delegationContext.context != null ? delegationContext.context : {}, + delegationContext.context!, delegationContext.info, delegationContext.fieldName, delegationContext.subschema, diff --git a/packages/delegate/src/transforms/ExpandAbstractTypes.ts b/packages/delegate/src/transforms/ExpandAbstractTypes.ts index da26311280b..8891219980c 100644 --- a/packages/delegate/src/transforms/ExpandAbstractTypes.ts +++ b/packages/delegate/src/transforms/ExpandAbstractTypes.ts @@ -48,23 +48,29 @@ export default class ExpandAbstractTypes implements Transform { function extractPossibleTypes(sourceSchema: GraphQLSchema, targetSchema: GraphQLSchema) { const typeMap = sourceSchema.getTypeMap(); + const targetTypeMap = targetSchema.getTypeMap(); const possibleTypesMap: Record> = Object.create(null); const interfaceExtensionsMap: Record> = Object.create(null); + for (const typeName in typeMap) { const type = typeMap[typeName]; + if (isAbstractType(type)) { - const targetType = targetSchema.getType(typeName); + const targetType = targetTypeMap[typeName]; if (isInterfaceType(type) && isInterfaceType(targetType)) { const targetTypeFields = targetType.getFields(); + const sourceTypeFields = type.getFields(); const extensionFields: Record = Object.create(null); let isExtensionFieldsEmpty = true; - for (const fieldName in type.getFields()) { + + for (const fieldName in sourceTypeFields) { if (!targetTypeFields[fieldName]) { extensionFields[fieldName] = true; isExtensionFieldsEmpty = false; } } + if (!isExtensionFieldsEmpty) { interfaceExtensionsMap[typeName] = extensionFields; } @@ -72,9 +78,13 @@ function extractPossibleTypes(sourceSchema: GraphQLSchema, targetSchema: GraphQL if (!isAbstractType(targetType) || typeName in interfaceExtensionsMap) { const implementations = sourceSchema.getPossibleTypes(type); - possibleTypesMap[typeName] = implementations - .filter(impl => targetSchema.getType(impl.name)) - .map(impl => impl.name); + possibleTypesMap[typeName] = []; + + for (const impl of implementations) { + if (targetTypeMap[impl.name]) { + possibleTypesMap[typeName].push(impl.name); + } + } } } } @@ -102,25 +112,36 @@ function expandAbstractTypes( interfaceExtensionsMap: Record>, document: DocumentNode ): DocumentNode { - const operations: Array = document.definitions.filter( - def => def.kind === Kind.OPERATION_DEFINITION - ) as Array; + const operations: OperationDefinitionNode[] = []; + const fragments: FragmentDefinitionNode[] = []; + const newFragments: FragmentDefinitionNode[] = []; + const existingFragmentNames = new Set(); - const fragments: Array = document.definitions.filter( - def => def.kind === Kind.FRAGMENT_DEFINITION - ) as Array; + for (let i = 0; i < document.definitions.length; i++) { + const def = document.definitions[i]; + + if (def.kind === Kind.FRAGMENT_DEFINITION) { + fragments.push(def); + newFragments.push(def); + existingFragmentNames.add(def.name.value); + } else if (def.kind === Kind.OPERATION_DEFINITION) { + operations.push(def); + } + } - const existingFragmentNames = fragments.map(fragment => fragment.name.value); let fragmentCounter = 0; - const generateFragmentName = (typeName: string) => { - let fragmentName; + function generateFragmentName(typeName: string) { + let fragmentName: string; + do { fragmentName = `_${typeName}_Fragment${fragmentCounter.toString()}`; fragmentCounter++; - } while (existingFragmentNames.indexOf(fragmentName) !== -1); + } while (existingFragmentNames.has(fragmentName)); + return fragmentName; - }; - const generateInlineFragment = (typeName: string, selectionSet: SelectionSetNode) => { + } + + function generateInlineFragment(typeName: string, selectionSet: SelectionSetNode) { return { kind: Kind.INLINE_FRAGMENT, typeCondition: { @@ -132,19 +153,20 @@ function expandAbstractTypes( }, selectionSet, }; - }; + } - const newFragments: Array = []; const fragmentReplacements: Record> = Object.create(null); for (const fragment of fragments) { - newFragments.push(fragment); const possibleTypes = possibleTypesMap[fragment.typeCondition.name.value]; + if (possibleTypes != null) { - fragmentReplacements[fragment.name.value] = []; + const fragmentName = fragment.name.value; + fragmentReplacements[fragmentName] = []; for (const possibleTypeName of possibleTypes) { const name = generateFragmentName(possibleTypeName); - existingFragmentNames.push(name); + existingFragmentNames.add(name); + const newFragment: FragmentDefinitionNode = { kind: Kind.FRAGMENT_DEFINITION, name: { @@ -160,9 +182,10 @@ function expandAbstractTypes( }, selectionSet: fragment.selectionSet, }; + newFragments.push(newFragment); - fragmentReplacements[fragment.name.value].push({ + fragmentReplacements[fragmentName].push({ fragmentName: name, typeName: possibleTypeName, }); @@ -175,6 +198,7 @@ function expandAbstractTypes( definitions: [...operations, ...newFragments], }; const typeInfo = new TypeInfo(targetSchema); + return visit( newDocument, visitWithTypeInfo(typeInfo, { @@ -182,14 +206,17 @@ function expandAbstractTypes( let newSelections = node.selections; const addedSelections = []; const maybeType = typeInfo.getParentType(); + if (maybeType != null) { const parentType: GraphQLNamedType = getNamedType(maybeType); const interfaceExtension = interfaceExtensionsMap[parentType.name]; const interfaceExtensionFields = [] as Array; + for (const selection of node.selections) { if (selection.kind === Kind.INLINE_FRAGMENT) { if (selection.typeCondition != null) { const possibleTypes = possibleTypesMap[selection.typeCondition.name.value]; + if (possibleTypes != null) { for (const possibleType of possibleTypes) { const maybePossibleType = targetSchema.getType(possibleType); @@ -204,10 +231,12 @@ function expandAbstractTypes( } } else if (selection.kind === Kind.FRAGMENT_SPREAD) { const fragmentName = selection.name.value; + if (fragmentName in fragmentReplacements) { for (const replacement of fragmentReplacements[fragmentName]) { const typeName = replacement.typeName; const maybeReplacementType = targetSchema.getType(typeName); + if (maybeReplacementType != null && implementsAbstractType(targetSchema, parentType, maybeType)) { addedSelections.push({ kind: Kind.FRAGMENT_SPREAD, diff --git a/packages/delegate/src/transforms/VisitSelectionSets.ts b/packages/delegate/src/transforms/VisitSelectionSets.ts index 1b131eddcec..bdf605db12d 100644 --- a/packages/delegate/src/transforms/VisitSelectionSets.ts +++ b/packages/delegate/src/transforms/VisitSelectionSets.ts @@ -58,83 +58,77 @@ function visitSelectionSets( ): DocumentNode { const { document, variables } = request; + const typeInfo = new TypeInfo(schema, undefined, initialType); const operations: Array = []; const fragments: Record = Object.create(null); + const newDefinitions: Array = []; + for (const def of document.definitions) { if (def.kind === Kind.OPERATION_DEFINITION) { + const operation = def; operations.push(def); - } else if (def.kind === Kind.FRAGMENT_DEFINITION) { - fragments[def.name.value] = def; - } - } - - const partialExecutionContext = { - schema, - variableValues: variables, - fragments, - } as GraphQLExecutionContext; - - const typeInfo = new TypeInfo(schema, undefined, initialType); - const newDefinitions: Array = operations.map(operation => { - const type = getDefinedRootType(schema, operation.operation); - - const fields = collectFields( - partialExecutionContext, - type, - operation.selectionSet, - Object.create(null), - Object.create(null) - ); - - const newSelections: Array = []; - for (const responseKey in fields) { - const fieldNodes = fields[responseKey]; - for (const fieldNode of fieldNodes) { - const selectionSet = fieldNode.selectionSet; - if (selectionSet == null) { - newSelections.push(fieldNode); - continue; + const type = getDefinedRootType(schema, operation.operation); + const fields = collectFields( + { + schema, + variableValues: variables, + fragments, + } as GraphQLExecutionContext, + type, + operation.selectionSet, + Object.create(null), + Object.create(null) + ); + + const newSelections: Array = []; + for (const responseKey in fields) { + const fieldNodes = fields[responseKey]; + for (const fieldNode of fieldNodes) { + const selectionSet = fieldNode.selectionSet; + + if (selectionSet == null) { + newSelections.push(fieldNode); + continue; + } + + const newSelectionSet = visit( + selectionSet, + visitWithTypeInfo(typeInfo, { + [Kind.SELECTION_SET]: node => visitor(node, typeInfo), + }) + ); + + if (newSelectionSet === selectionSet) { + newSelections.push(fieldNode); + continue; + } + + newSelections.push({ + ...fieldNode, + selectionSet: newSelectionSet, + }); } + } - const newSelectionSet = visit( - selectionSet, + newDefinitions.push({ + ...def, + selectionSet: { + kind: Kind.SELECTION_SET, + selections: newSelections, + }, + }); + } else if (def.kind === Kind.FRAGMENT_DEFINITION) { + fragments[def.name.value] = def; + newDefinitions.push( + visit( + def, visitWithTypeInfo(typeInfo, { [Kind.SELECTION_SET]: node => visitor(node, typeInfo), }) - ); - - if (newSelectionSet === selectionSet) { - newSelections.push(fieldNode); - continue; - } - - newSelections.push({ - ...fieldNode, - selectionSet: newSelectionSet, - }); - } + ) + ); } - - return { - ...operation, - selectionSet: { - kind: Kind.SELECTION_SET, - selections: newSelections, - }, - }; - }); - - for (const fragmentIndex in fragments) { - const fragment = fragments[fragmentIndex]; - newDefinitions.push( - visit( - fragment, - visitWithTypeInfo(typeInfo, { - [Kind.SELECTION_SET]: node => visitor(node, typeInfo), - }) - ) - ); } return { diff --git a/packages/loaders/git/package.json b/packages/loaders/git/package.json index c6104a55d7e..e6d102acbfb 100644 --- a/packages/loaders/git/package.json +++ b/packages/loaders/git/package.json @@ -38,7 +38,7 @@ "unixify": "^1.0.0" }, "devDependencies": { - "@types/micromatch": "latest" + "@types/micromatch": "4.0.1" }, "publishConfig": { "access": "public", diff --git a/yarn.lock b/yarn.lock index 7edaf23e091..f1beecbfa22 100644 --- a/yarn.lock +++ b/yarn.lock @@ -144,6 +144,87 @@ tslib "^1.10.0" zen-observable "^0.8.14" +"@apollo/federation@0.25.2", "@apollo/federation@^0.25.2": + version "0.25.2" + resolved "https://registry.yarnpkg.com/@apollo/federation/-/federation-0.25.2.tgz#10b2e22ac20e64701fd6d31d9abbf7f411b03763" + integrity sha512-TrRCrGniHpnRwALm2J7q2c1X4Lcc95e7SeHkVjascaQx6nBZGFbBXadw8rOPxlw5syfxYf8h9winF+wwld+gsg== + dependencies: + apollo-graphql "^0.9.3" + lodash.xorby "^4.7.0" + +"@apollo/gateway@0.32.0": + version "0.32.0" + resolved "https://registry.yarnpkg.com/@apollo/gateway/-/gateway-0.32.0.tgz#639b7b826c76a2bffdf777902010485dfd981918" + integrity sha512-Pxq3VVxG1ALrFNN8SM3RVy6Kwm+5p1KG3ObVmQX720Wx5WpRKvCRC23J/c3oFRpsGqjPOglh3vmpAQVdJJTCZA== + dependencies: + "@apollo/federation" "^0.25.2" + "@apollo/query-planner" "^0.2.2" + "@opentelemetry/api" "^1.0.1" + "@types/node-fetch" "2.5.10" + apollo-graphql "^0.9.3" + apollo-reporting-protobuf "^0.8.0 || ^3.0.0 || ^3.0.0-preview.2" + apollo-server-caching "^0.7.0 || ^3.0.0 || ^3.0.0-preview.2" + apollo-server-core "^2.23.0 || ^3.0.0 || ^3.0.0-preview.2" + apollo-server-env "^3.0.0 || ^4.0.0 || ^3.2.0-preview.2 || ^4.0.0-rc.0" + apollo-server-errors "^2.5.0 || ^3.0.0 || ^3.0.0-preview.2" + apollo-server-types "^0.9.0 || ^3.0.0 || ^3.0.0-preview.2" + loglevel "^1.6.1" + make-fetch-happen "^8.0.0" + pretty-format "^26.0.0" + +"@apollo/protobufjs@1.2.2": + version "1.2.2" + resolved "https://registry.yarnpkg.com/@apollo/protobufjs/-/protobufjs-1.2.2.tgz#4bd92cd7701ccaef6d517cdb75af2755f049f87c" + integrity sha512-vF+zxhPiLtkwxONs6YanSt1EpwpGilThpneExUN5K3tCymuxNnVq2yojTvnpRjv2QfsEIt/n7ozPIIzBLwGIDQ== + dependencies: + "@protobufjs/aspromise" "^1.1.2" + "@protobufjs/base64" "^1.1.2" + "@protobufjs/codegen" "^2.0.4" + "@protobufjs/eventemitter" "^1.1.0" + "@protobufjs/fetch" "^1.1.0" + "@protobufjs/float" "^1.0.2" + "@protobufjs/inquire" "^1.1.0" + "@protobufjs/path" "^1.1.2" + "@protobufjs/pool" "^1.1.0" + "@protobufjs/utf8" "^1.1.0" + "@types/long" "^4.0.0" + "@types/node" "^10.1.0" + long "^4.0.0" + +"@apollo/query-planner@^0.2.2": + version "0.2.2" + resolved "https://registry.yarnpkg.com/@apollo/query-planner/-/query-planner-0.2.2.tgz#5397e5cd8a73dede34c485fb0c5fefa054f9153a" + integrity sha512-+RZSKY0xDYki9qwlzKXDNa+jrbj0Qstq44lcB21aViiDdEJWOTwf7Cqg3h/hN7QsUnL75XiDrwsjMLnwFdHSoQ== + dependencies: + chalk "^4.1.0" + deep-equal "^2.0.5" + pretty-format "^26.0.0" + +"@apollographql/apollo-tools@^0.5.0": + version "0.5.1" + resolved "https://registry.yarnpkg.com/@apollographql/apollo-tools/-/apollo-tools-0.5.1.tgz#f0baef739ff7e2fafcb8b98ad29f6ac817e53e32" + integrity sha512-ZII+/xUFfb9ezDU2gad114+zScxVFMVlZ91f8fGApMzlS1kkqoyLnC4AJaQ1Ya/X+b63I20B4Gd+eCL8QuB4sA== + +"@apollographql/graphql-playground-html@1.6.27": + version "1.6.27" + resolved "https://registry.yarnpkg.com/@apollographql/graphql-playground-html/-/graphql-playground-html-1.6.27.tgz#bc9ab60e9445aa2a8813b4e94f152fa72b756335" + integrity sha512-tea2LweZvn6y6xFV11K0KC8ETjmm52mQrW+ezgB2O/aTQf8JGyFmMcRPFgUaQZeHbWdm8iisDC6EjOKsXu0nfw== + dependencies: + xss "^1.0.8" + +"@apollographql/graphql-upload-8-fork@^8.1.3": + version "8.1.3" + resolved "https://registry.yarnpkg.com/@apollographql/graphql-upload-8-fork/-/graphql-upload-8-fork-8.1.3.tgz#a0d4e0d5cec8e126d78bd915c264d6b90f5784bc" + integrity sha512-ssOPUT7euLqDXcdVv3Qs4LoL4BPtfermW1IOouaqEmj36TpHYDmYDIbKoSQxikd9vtMumFnP87OybH7sC9fJ6g== + dependencies: + "@types/express" "*" + "@types/fs-capacitor" "*" + "@types/koa" "*" + busboy "^0.3.1" + fs-capacitor "^2.0.4" + http-errors "^1.7.3" + object-path "^0.11.4" + "@ardatan/fetch-event-source@2.0.2": version "2.0.2" resolved "https://registry.yarnpkg.com/@ardatan/fetch-event-source/-/fetch-event-source-2.0.2.tgz#734aa3eaa0da456453d24d8dc7c14d5e366a8d21" @@ -2116,6 +2197,11 @@ "@types/yargs" "^16.0.0" chalk "^4.0.0" +"@josephg/resolvable@^1.0.0": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@josephg/resolvable/-/resolvable-1.0.1.tgz#69bc4db754d79e1a2f17a650d3466e038d94a5eb" + integrity sha512-CtzORUwWTTOTqfVtHaKRJ0I1kNQd1bpn3sUh8I3nJDVY+5/M/Oe1DnEWzPQvqq/xPIIkzzzIP7mfCoAjFRvDhg== + "@manypkg/find-root@^1.1.0": version "1.1.0" resolved "https://registry.yarnpkg.com/@manypkg/find-root/-/find-root-1.1.0.tgz#a62d8ed1cd7e7d4c11d9d52a8397460b5d4ad29f" @@ -2198,11 +2284,77 @@ "@nodelib/fs.scandir" "2.1.4" fastq "^1.6.0" +"@npmcli/move-file@^1.0.1": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@npmcli/move-file/-/move-file-1.1.2.tgz#1a82c3e372f7cae9253eb66d72543d6b8685c674" + integrity sha512-1SUf/Cg2GzGDyaf15aR9St9TWlb+XvbZXWpDx8YKs7MLzMH/BCeopv+y9vzrzgkfykCGuWOlSu3mZhj2+FQcrg== + dependencies: + mkdirp "^1.0.4" + rimraf "^3.0.2" + +"@opentelemetry/api@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@opentelemetry/api/-/api-1.0.1.tgz#03c72f548431da5820a0c8864d1401e348e7e79f" + integrity sha512-H5Djcc2txGAINgf3TNaq4yFofYSIK3722PM89S/3R8FuI/eqi1UscajlXk7EBkG9s2pxss/q6SHlpturaavXaw== + "@polka/url@^1.0.0-next.9": version "1.0.0-next.11" resolved "https://registry.yarnpkg.com/@polka/url/-/url-1.0.0-next.11.tgz#aeb16f50649a91af79dbe36574b66d0f9e4d9f71" integrity sha512-3NsZsJIA/22P3QUyrEDNA2D133H4j224twJrdipXN38dpnIOzAbUDtOwkcJ5pXmn75w7LSQDjA4tO9dm1XlqlA== +"@protobufjs/aspromise@^1.1.1", "@protobufjs/aspromise@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@protobufjs/aspromise/-/aspromise-1.1.2.tgz#9b8b0cc663d669a7d8f6f5d0893a14d348f30fbf" + integrity sha1-m4sMxmPWaafY9vXQiToU00jzD78= + +"@protobufjs/base64@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@protobufjs/base64/-/base64-1.1.2.tgz#4c85730e59b9a1f1f349047dbf24296034bb2735" + integrity sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg== + +"@protobufjs/codegen@^2.0.4": + version "2.0.4" + resolved "https://registry.yarnpkg.com/@protobufjs/codegen/-/codegen-2.0.4.tgz#7ef37f0d010fb028ad1ad59722e506d9262815cb" + integrity sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg== + +"@protobufjs/eventemitter@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz#355cbc98bafad5978f9ed095f397621f1d066b70" + integrity sha1-NVy8mLr61ZePntCV85diHx0Ga3A= + +"@protobufjs/fetch@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/fetch/-/fetch-1.1.0.tgz#ba99fb598614af65700c1619ff06d454b0d84c45" + integrity sha1-upn7WYYUr2VwDBYZ/wbUVLDYTEU= + dependencies: + "@protobufjs/aspromise" "^1.1.1" + "@protobufjs/inquire" "^1.1.0" + +"@protobufjs/float@^1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@protobufjs/float/-/float-1.0.2.tgz#5e9e1abdcb73fc0a7cb8b291df78c8cbd97b87d1" + integrity sha1-Xp4avctz/Ap8uLKR33jIy9l7h9E= + +"@protobufjs/inquire@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/inquire/-/inquire-1.1.0.tgz#ff200e3e7cf2429e2dcafc1140828e8cc638f089" + integrity sha1-/yAOPnzyQp4tyvwRQIKOjMY48Ik= + +"@protobufjs/path@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@protobufjs/path/-/path-1.1.2.tgz#6cc2b20c5c9ad6ad0dccfd21ca7673d8d7fbf68d" + integrity sha1-bMKyDFya1q0NzP0hynZz2Nf79o0= + +"@protobufjs/pool@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/pool/-/pool-1.1.0.tgz#09fd15f2d6d3abfa9b65bc366506d6ad7846ff54" + integrity sha1-Cf0V8tbTq/qbZbw2ZQbWrXhG/1Q= + +"@protobufjs/utf8@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/utf8/-/utf8-1.1.0.tgz#a777360b5b39a1a2e5106f8e858f2fd2d060c570" + integrity sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA= + "@rollup/plugin-node-resolve@7.1.1": version "7.1.1" resolved "https://registry.yarnpkg.com/@rollup/plugin-node-resolve/-/plugin-node-resolve-7.1.1.tgz#8c6e59c4b28baf9d223028d0e450e06a485bb2b7" @@ -2537,7 +2689,12 @@ "@types/qs" "*" "@types/serve-static" "*" -"@types/extract-files@*", "@types/extract-files@8.1.1": +"@types/extract-files@*": + version "8.1.0" + resolved "https://registry.yarnpkg.com/@types/extract-files/-/extract-files-8.1.0.tgz#4728440e1d92a6d1d11ac47f5a10e3f9ce47f044" + integrity sha512-ulxvlFU71yLVV3JxdBgryASAIp+aZQuQOpkhU1SznJlcWz0qsJCWHqdJqP6Lprs3blqGS5FH5GbBkU0977+Wew== + +"@types/extract-files@8.1.1": version "8.1.1" resolved "https://registry.yarnpkg.com/@types/extract-files/-/extract-files-8.1.1.tgz#11b67e795ad2c8b483431e8d4f190db2fd22944b" integrity sha512-dMJJqBqyhsfJKuK7p7HyyNmki7qj1AlwhUKWx6KrU7i1K2T2SPsUsSUTWFmr/sEM1q8rfR8j5IyUmYrDbrhfjQ== @@ -2691,6 +2848,11 @@ resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.171.tgz#f01b3a5fe3499e34b622c362a46a609fdb23573b" integrity sha512-7eQ2xYLLI/LsicL2nejW9Wyko3lcpN6O/z0ZLHrEQsg280zIdCv1t/0m6UtBjUHokCGBQ3gYTbHzDkZ1xOBwwg== +"@types/long@^4.0.0": + version "4.0.1" + resolved "https://registry.yarnpkg.com/@types/long/-/long-4.0.1.tgz#459c65fa1867dafe6a8f322c4c51695663cc55e9" + integrity sha512-5tXH6Bx/kNGd3MgffdmP4dy2Z+G4eaXw0SE81Tq3BNadtnMR5/ySMzX4SLEzHJzSmPNn4HIdpQsBvXMUykr58w== + "@types/mdast@^3.0.0": version "3.0.3" resolved "https://registry.yarnpkg.com/@types/mdast/-/mdast-3.0.3.tgz#2d7d671b1cd1ea3deb306ea75036c2a0407d2deb" @@ -2698,6 +2860,13 @@ dependencies: "@types/unist" "*" +"@types/micromatch@4.0.1": + version "4.0.1" + resolved "https://registry.yarnpkg.com/@types/micromatch/-/micromatch-4.0.1.tgz#9381449dd659fc3823fd2a4190ceacc985083bc7" + integrity sha1-k4FEndZZ/Dgj/SpBkM6syYUIO8c= + dependencies: + "@types/braces" "*" + "@types/micromatch@4.0.2": version "4.0.2" resolved "https://registry.yarnpkg.com/@types/micromatch/-/micromatch-4.0.2.tgz#ce29c8b166a73bf980a5727b1e4a4d099965151d" @@ -2705,13 +2874,6 @@ dependencies: "@types/braces" "*" -"@types/micromatch@latest": - version "4.0.1" - resolved "https://registry.yarnpkg.com/@types/micromatch/-/micromatch-4.0.1.tgz#9381449dd659fc3823fd2a4190ceacc985083bc7" - integrity sha1-k4FEndZZ/Dgj/SpBkM6syYUIO8c= - dependencies: - "@types/braces" "*" - "@types/mime@^1": version "1.3.2" resolved "https://registry.yarnpkg.com/@types/mime/-/mime-1.3.2.tgz#93e25bf9ee75fe0fd80b594bc4feb0e862111b5a" @@ -2727,6 +2889,14 @@ resolved "https://registry.yarnpkg.com/@types/minimist/-/minimist-1.2.1.tgz#283f669ff76d7b8260df8ab7a4262cc83d988256" integrity sha512-fZQQafSREFyuZcdWFAExYjBiCL7AUCdgsk80iO0q4yihYYdcIiH28CcuPTGFgLOCC8RlW49GSQxdHwZP+I7CNg== +"@types/node-fetch@2.5.10": + version "2.5.10" + resolved "https://registry.yarnpkg.com/@types/node-fetch/-/node-fetch-2.5.10.tgz#9b4d4a0425562f9fcea70b12cb3fcdd946ca8132" + integrity sha512-IpkX0AasN44hgEad0gEF/V6EgR5n69VEqPEgnmoM8GsIGro3PowbWs4tR6IhxUTyPLpOn+fiGG6nrQhcmoCuIQ== + dependencies: + "@types/node" "*" + form-data "^3.0.0" + "@types/node@*", "@types/node@^15.0.1": version "15.6.0" resolved "https://registry.yarnpkg.com/@types/node/-/node-15.6.0.tgz#f0ddca5a61e52627c9dcb771a6039d44694597bc" @@ -2737,6 +2907,11 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-14.17.5.tgz#b59daf6a7ffa461b5648456ca59050ba8e40ed54" integrity sha512-bjqH2cX/O33jXT/UmReo2pM7DIJREPMnarixbQ57DOOzzFaI6D2+IcwaJQaJpv0M1E9TIhPCYVxrkcityLjlqA== +"@types/node@^10.1.0": + version "10.17.60" + resolved "https://registry.yarnpkg.com/@types/node/-/node-10.17.60.tgz#35f3d6213daed95da7f0f73e75bcc6980e90597b" + integrity sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw== + "@types/node@^12.7.1": version "12.20.6" resolved "https://registry.yarnpkg.com/@types/node/-/node-12.20.6.tgz#7b73cce37352936e628c5ba40326193443cfba25" @@ -2849,7 +3024,7 @@ dependencies: "@types/node" "*" -"@types/ws@7.4.6": +"@types/ws@7.4.6", "@types/ws@^7.0.0": version "7.4.6" resolved "https://registry.yarnpkg.com/@types/ws/-/ws-7.4.6.tgz#c4320845e43d45a7129bb32905e28781c71c1fff" integrity sha512-ijZ1vzRawI7QoWnTNL8KpHixd2b2XVb9I9HAqI3triPsh1EC0xH0Eg6w2O3TKbDCgiNNlJqfrof6j4T2I+l9vw== @@ -3137,6 +3312,13 @@ dependencies: tslib "^2.1.0" +"@wry/equality@^0.1.2": + version "0.1.11" + resolved "https://registry.yarnpkg.com/@wry/equality/-/equality-0.1.11.tgz#35cb156e4a96695aa81a9ecc4d03787bc17f1790" + integrity sha512-mwEVBDUVODlsQQ5dfuLUS5/Tf7jqUKyhKYHmVi4fPB6bDMOfWvUPJmKgS1Z7Za/sOI3vzWt4+O7yCiL/70MogA== + dependencies: + tslib "^1.9.3" + "@wry/equality@^0.5.0": version "0.5.1" resolved "https://registry.yarnpkg.com/@wry/equality/-/equality-0.5.1.tgz#b22e4e1674d7bf1439f8ccdccfd6a785f6de68b0" @@ -3233,13 +3415,22 @@ address@1.1.2, address@^1.0.1: resolved "https://registry.yarnpkg.com/address/-/address-1.1.2.tgz#bf1116c9c758c51b7a933d296b72c221ed9428b6" integrity sha512-aT6camzM4xEA54YVJYSqxz1kv4IHnQZRtThJJHhUMRExaU5spC7jX5ugSwTaTgJliIgs4VhZOk7htClvQ/LmRA== -agent-base@6: +agent-base@6, agent-base@^6.0.2: version "6.0.2" resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ== dependencies: debug "4" +agentkeepalive@^4.1.3: + version "4.1.4" + resolved "https://registry.yarnpkg.com/agentkeepalive/-/agentkeepalive-4.1.4.tgz#d928028a4862cb11718e55227872e842a44c945b" + integrity sha512-+V/rGa3EuU74H6wR04plBb7Ks10FbtUQgRj/FQOG7uUIEuaINI+AiqJR1k6t3SVNs7o7ZjIdus6706qqzVq8jQ== + dependencies: + debug "^4.1.0" + depd "^1.1.2" + humanize-ms "^1.2.1" + aggregate-error@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-3.1.0.tgz#92670ff50f5359bdb7a3e0d40d0ec30c5737687a" @@ -3401,6 +3592,123 @@ anymatch@^3.0.3, anymatch@~3.1.1: normalize-path "^3.0.0" picomatch "^2.0.4" +apollo-cache-control@^0.14.0: + version "0.14.0" + resolved "https://registry.yarnpkg.com/apollo-cache-control/-/apollo-cache-control-0.14.0.tgz#95f20c3e03e7994e0d1bd48c59aeaeb575ed0ce7" + integrity sha512-qN4BCq90egQrgNnTRMUHikLZZAprf3gbm8rC5Vwmc6ZdLolQ7bFsa769Hqi6Tq/lS31KLsXBLTOsRbfPHph12w== + dependencies: + apollo-server-env "^3.1.0" + apollo-server-plugin-base "^0.13.0" + +apollo-datasource@^0.9.0: + version "0.9.0" + resolved "https://registry.yarnpkg.com/apollo-datasource/-/apollo-datasource-0.9.0.tgz#b0b2913257a6103a5f4c03cb56d78a30e9d850db" + integrity sha512-y8H99NExU1Sk4TvcaUxTdzfq2SZo6uSj5dyh75XSQvbpH6gdAXIW9MaBcvlNC7n0cVPsidHmOcHOWxJ/pTXGjA== + dependencies: + apollo-server-caching "^0.7.0" + apollo-server-env "^3.1.0" + +apollo-graphql@^0.9.0, apollo-graphql@^0.9.3: + version "0.9.3" + resolved "https://registry.yarnpkg.com/apollo-graphql/-/apollo-graphql-0.9.3.tgz#1ca6f625322ae10a66f57a39642849a07a7a5dc9" + integrity sha512-rcAl2E841Iko4kSzj4Pt3PRBitmyq1MvoEmpl04TQSpGnoVgl1E/ZXuLBYxMTSnEAm7umn2IsoY+c6Ll9U/10A== + dependencies: + core-js-pure "^3.10.2" + lodash.sortby "^4.7.0" + sha.js "^2.4.11" + +apollo-link@^1.2.14: + version "1.2.14" + resolved "https://registry.yarnpkg.com/apollo-link/-/apollo-link-1.2.14.tgz#3feda4b47f9ebba7f4160bef8b977ba725b684d9" + integrity sha512-p67CMEFP7kOG1JZ0ZkYZwRDa369w5PIjtMjvrQd/HnIV8FRsHRqLqK+oAZQnFa1DDdZtOtHTi+aMIW6EatC2jg== + dependencies: + apollo-utilities "^1.3.0" + ts-invariant "^0.4.0" + tslib "^1.9.3" + zen-observable-ts "^0.8.21" + +apollo-reporting-protobuf@^0.8.0, "apollo-reporting-protobuf@^0.8.0 || ^3.0.0 || ^3.0.0-preview.2": + version "0.8.0" + resolved "https://registry.yarnpkg.com/apollo-reporting-protobuf/-/apollo-reporting-protobuf-0.8.0.tgz#ae9d967934d3d8ed816fc85a0d8068ef45c371b9" + integrity sha512-B3XmnkH6Y458iV6OsA7AhfwvTgeZnFq9nPVjbxmLKnvfkEl8hYADtz724uPa0WeBiD7DSFcnLtqg9yGmCkBohg== + dependencies: + "@apollo/protobufjs" "1.2.2" + +apollo-server-caching@^0.7.0, "apollo-server-caching@^0.7.0 || ^3.0.0 || ^3.0.0-preview.2": + version "0.7.0" + resolved "https://registry.yarnpkg.com/apollo-server-caching/-/apollo-server-caching-0.7.0.tgz#e6d1e68e3bb571cba63a61f60b434fb771c6ff39" + integrity sha512-MsVCuf/2FxuTFVhGLK13B+TZH9tBd2qkyoXKKILIiGcZ5CDUEBO14vIV63aNkMkS1xxvK2U4wBcuuNj/VH2Mkw== + dependencies: + lru-cache "^6.0.0" + +"apollo-server-core@^2.23.0 || ^3.0.0 || ^3.0.0-preview.2": + version "2.25.2" + resolved "https://registry.yarnpkg.com/apollo-server-core/-/apollo-server-core-2.25.2.tgz#ff65da5e512d9b5ca54c8e5e8c78ee28b5987247" + integrity sha512-lrohEjde2TmmDTO7FlOs8x5QQbAS0Sd3/t0TaK2TWaodfzi92QAvIsq321Mol6p6oEqmjm8POIDHW1EuJd7XMA== + dependencies: + "@apollographql/apollo-tools" "^0.5.0" + "@apollographql/graphql-playground-html" "1.6.27" + "@apollographql/graphql-upload-8-fork" "^8.1.3" + "@josephg/resolvable" "^1.0.0" + "@types/ws" "^7.0.0" + apollo-cache-control "^0.14.0" + apollo-datasource "^0.9.0" + apollo-graphql "^0.9.0" + apollo-reporting-protobuf "^0.8.0" + apollo-server-caching "^0.7.0" + apollo-server-env "^3.1.0" + apollo-server-errors "^2.5.0" + apollo-server-plugin-base "^0.13.0" + apollo-server-types "^0.9.0" + apollo-tracing "^0.15.0" + async-retry "^1.2.1" + fast-json-stable-stringify "^2.0.0" + graphql-extensions "^0.15.0" + graphql-tag "^2.11.0" + graphql-tools "^4.0.8" + loglevel "^1.6.7" + lru-cache "^6.0.0" + sha.js "^2.4.11" + subscriptions-transport-ws "^0.9.19" + uuid "^8.0.0" + +"apollo-server-env@^3.0.0 || ^4.0.0 || ^3.2.0-preview.2 || ^4.0.0-rc.0", apollo-server-env@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/apollo-server-env/-/apollo-server-env-3.1.0.tgz#0733c2ef50aea596cc90cf40a53f6ea2ad402cd0" + integrity sha512-iGdZgEOAuVop3vb0F2J3+kaBVi4caMoxefHosxmgzAbbSpvWehB8Y1QiSyyMeouYC38XNVk5wnZl+jdGSsWsIQ== + dependencies: + node-fetch "^2.6.1" + util.promisify "^1.0.0" + +apollo-server-errors@^2.5.0, "apollo-server-errors@^2.5.0 || ^3.0.0 || ^3.0.0-preview.2": + version "2.5.0" + resolved "https://registry.yarnpkg.com/apollo-server-errors/-/apollo-server-errors-2.5.0.tgz#5d1024117c7496a2979e3e34908b5685fe112b68" + integrity sha512-lO5oTjgiC3vlVg2RKr3RiXIIQ5pGXBFxYGGUkKDhTud3jMIhs+gel8L8zsEjKaKxkjHhCQAA/bcEfYiKkGQIvA== + +apollo-server-plugin-base@^0.13.0: + version "0.13.0" + resolved "https://registry.yarnpkg.com/apollo-server-plugin-base/-/apollo-server-plugin-base-0.13.0.tgz#3f85751a420d3c4625355b6cb3fbdd2acbe71f13" + integrity sha512-L3TMmq2YE6BU6I4Tmgygmd0W55L+6XfD9137k+cWEBFu50vRY4Re+d+fL5WuPkk5xSPKd/PIaqzidu5V/zz8Kg== + dependencies: + apollo-server-types "^0.9.0" + +apollo-server-types@^0.9.0, "apollo-server-types@^0.9.0 || ^3.0.0 || ^3.0.0-preview.2": + version "0.9.0" + resolved "https://registry.yarnpkg.com/apollo-server-types/-/apollo-server-types-0.9.0.tgz#ccf550b33b07c48c72f104fbe2876232b404848b" + integrity sha512-qk9tg4Imwpk732JJHBkhW0jzfG0nFsLqK2DY6UhvJf7jLnRePYsPxWfPiNkxni27pLE2tiNlCwoDFSeWqpZyBg== + dependencies: + apollo-reporting-protobuf "^0.8.0" + apollo-server-caching "^0.7.0" + apollo-server-env "^3.1.0" + +apollo-tracing@^0.15.0: + version "0.15.0" + resolved "https://registry.yarnpkg.com/apollo-tracing/-/apollo-tracing-0.15.0.tgz#237fbbbf669aee4370b7e9081b685eabaa8ce84a" + integrity sha512-UP0fztFvaZPHDhIB/J+qGuy6hWO4If069MGC98qVs0I8FICIGu4/8ykpX3X3K6RtaQ56EDAWKykCxFv4ScxMeA== + dependencies: + apollo-server-env "^3.1.0" + apollo-server-plugin-base "^0.13.0" + apollo-upload-client@16.0.0: version "16.0.0" resolved "https://registry.yarnpkg.com/apollo-upload-client/-/apollo-upload-client-16.0.0.tgz#704c9bc21e12bd4687172876eb927cf756b2e524" @@ -3408,6 +3716,16 @@ apollo-upload-client@16.0.0: dependencies: extract-files "^11.0.0" +apollo-utilities@^1.0.1, apollo-utilities@^1.3.0: + version "1.3.4" + resolved "https://registry.yarnpkg.com/apollo-utilities/-/apollo-utilities-1.3.4.tgz#6129e438e8be201b6c55b0f13ce49d2c7175c9cf" + integrity sha512-pk2hiWrCXMAy2fRPwEyhvka+mqwzeP60Jr1tRYi5xru+3ko94HI9o6lK0CT33/w4RDlxWchmdhDCrvdr+pHCig== + dependencies: + "@wry/equality" "^0.1.2" + fast-json-stable-stringify "^2.0.0" + ts-invariant "^0.4.0" + tslib "^1.10.0" + arg@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/arg/-/arg-5.0.0.tgz#a20e2bb5710e82950a516b3f933fee5ed478be90" @@ -3522,6 +3840,13 @@ async-limiter@~1.0.0: resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.1.tgz#dd379e94f0db8310b08291f9d64c3209766617fd" integrity sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ== +async-retry@^1.2.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/async-retry/-/async-retry-1.3.1.tgz#139f31f8ddce50c0870b0ba558a6079684aaed55" + integrity sha512-aiieFW/7h3hY0Bq5d+ktDBejxuwR78vRu9hDUdR8rNhSaQ29VzPL4AoIRG7D/c7tdenwOcKvgPM6tIxB3cB6HA== + dependencies: + retry "0.12.0" + async@^2.6.2: version "2.6.3" resolved "https://registry.yarnpkg.com/async/-/async-2.6.3.tgz#d72625e2344a3656e3a3ad4fa749fa83299d82ff" @@ -3556,6 +3881,11 @@ autoprefixer@^10.0.2, autoprefixer@^10.2.5: normalize-range "^0.1.2" postcss-value-parser "^4.1.0" +available-typed-arrays@^1.0.2: + version "1.0.4" + resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.4.tgz#9e0ae84ecff20caae6a94a1c3bc39b955649b7a9" + integrity sha512-SA5mXJWrId1TaQjfxUYghbqQ/hYioKmLJvPJyDuYRtXXenFNMjj4hSSt1Cf1xsuXSXrtxrVC5Ot4eU6cOtBDdA== + axios@^0.21.1: version "0.21.1" resolved "https://registry.yarnpkg.com/axios/-/axios-0.21.1.tgz#22563481962f4d6bde9a76d516ef0e5d3c09b2b8" @@ -4049,6 +4379,29 @@ bytes@3.1.0, bytes@^3.0.0: resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.0.tgz#f6cf7933a360e0588fa9fde85651cdc7f805d1f6" integrity sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg== +cacache@^15.0.5: + version "15.2.0" + resolved "https://registry.yarnpkg.com/cacache/-/cacache-15.2.0.tgz#73af75f77c58e72d8c630a7a2858cb18ef523389" + integrity sha512-uKoJSHmnrqXgthDFx/IU6ED/5xd+NNGe+Bb+kLZy7Ku4P+BaiWEUflAKPZ7eAzsYGcsAGASJZsybXp+quEcHTw== + dependencies: + "@npmcli/move-file" "^1.0.1" + chownr "^2.0.0" + fs-minipass "^2.0.0" + glob "^7.1.4" + infer-owner "^1.0.4" + lru-cache "^6.0.0" + minipass "^3.1.1" + minipass-collect "^1.0.2" + minipass-flush "^1.0.5" + minipass-pipeline "^1.2.2" + mkdirp "^1.0.3" + p-map "^4.0.0" + promise-inflight "^1.0.1" + rimraf "^3.0.2" + ssri "^8.0.1" + tar "^6.0.2" + unique-filename "^1.1.1" + cache-base@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/cache-base/-/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2" @@ -4261,6 +4614,11 @@ chokidar@^3.5.1: optionalDependencies: fsevents "~2.3.1" +chownr@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/chownr/-/chownr-2.0.0.tgz#15bfbe53d2eab4cf70f18a8cd68ebe5b3cb1dece" + integrity sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ== + chrome-trace-event@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.2.tgz#234090ee97c7d4ad1a2c4beae27505deffc608a4" @@ -4508,7 +4866,7 @@ comma-separated-tokens@^1.0.0: resolved "https://registry.yarnpkg.com/comma-separated-tokens/-/comma-separated-tokens-1.0.8.tgz#632b80b6117867a158f1080ad498b2fbe7e3f5ea" integrity sha512-GHuDRO12Sypu2cV70d1dkA2EUmXHgntrzbpvOB+Qy+49ypNfGgFQIC2fhhXbnyrJRynDCAARsT7Ou0M6hirpfw== -commander@^2.20.0: +commander@^2.20.0, commander@^2.20.3: version "2.20.3" resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== @@ -4687,6 +5045,11 @@ core-js-pure@^3.0.0: resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.9.1.tgz#677b322267172bd490e4464696f790cbc355bec5" integrity sha512-laz3Zx0avrw9a4QEIdmIblnVuJz8W51leY9iLThatCsFawWxC3sE4guASC78JbCin+DkwMpCdp1AVAuzL/GN7A== +core-js-pure@^3.10.2: + version "3.15.2" + resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.15.2.tgz#c8e0874822705f3385d3197af9348f7c9ae2e3ce" + integrity sha512-D42L7RYh1J2grW8ttxoY1+17Y4wXZeKe7uyplAI3FkNQyI5OgBIAjUfFiTPfL1rs0qLpxaabITNbjKl1Sp82tA== + core-js@^3.14.0, core-js@^3.9.1: version "3.14.0" resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.14.0.tgz#62322b98c71cc2018b027971a69419e2425c2a6c" @@ -4719,6 +5082,13 @@ cosmiconfig@^7.0.0: path-type "^4.0.0" yaml "^1.10.0" +cross-env@7.0.3: + version "7.0.3" + resolved "https://registry.yarnpkg.com/cross-env/-/cross-env-7.0.3.tgz#865264b29677dc015ba8418918965dd232fc54cf" + integrity sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw== + dependencies: + cross-spawn "^7.0.1" + cross-fetch@3.1.4, cross-fetch@^3.0.4, cross-fetch@^3.0.6: version "3.1.4" resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-3.1.4.tgz#9723f3a3a247bf8b89039f3a380a9244e8fa2f39" @@ -4735,7 +5105,7 @@ cross-spawn@7.0.1: shebang-command "^2.0.0" which "^2.0.1" -cross-spawn@7.0.3, cross-spawn@^7.0.2, cross-spawn@^7.0.3: +cross-spawn@7.0.3, cross-spawn@^7.0.1, cross-spawn@^7.0.2, cross-spawn@^7.0.3: version "7.0.3" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== @@ -4894,6 +5264,11 @@ cssesc@^3.0.0: resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee" integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg== +cssfilter@0.0.10: + version "0.0.10" + resolved "https://registry.yarnpkg.com/cssfilter/-/cssfilter-0.0.10.tgz#c6d2672632a2e5c83e013e6864a42ce8defd20ae" + integrity sha1-xtJnJjKi5cg+AT5oZKQs6N79IK4= + cssnano-preset-advanced@^5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/cssnano-preset-advanced/-/cssnano-preset-advanced-5.1.1.tgz#97652704ef799f13fa22922c6a069c9434ef2123" @@ -5101,6 +5476,27 @@ deep-equal@^1.0.1: object-keys "^1.1.1" regexp.prototype.flags "^1.2.0" +deep-equal@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-2.0.5.tgz#55cd2fe326d83f9cbf7261ef0e060b3f724c5cb9" + integrity sha512-nPiRgmbAtm1a3JsnLCf6/SLfXcjyN5v8L1TXzdCmHrXJ4hx+gW/w1YCcn7z8gJtSiDArZCgYtbao3QqLm/N1Sw== + dependencies: + call-bind "^1.0.0" + es-get-iterator "^1.1.1" + get-intrinsic "^1.0.1" + is-arguments "^1.0.4" + is-date-object "^1.0.2" + is-regex "^1.1.1" + isarray "^2.0.5" + object-is "^1.1.4" + object-keys "^1.1.1" + object.assign "^4.1.2" + regexp.prototype.flags "^1.3.0" + side-channel "^1.0.3" + which-boxed-primitive "^1.0.1" + which-collection "^1.0.1" + which-typed-array "^1.1.2" + deep-extend@^0.6.0: version "0.6.0" resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" @@ -5207,11 +5603,16 @@ delegate@^3.1.2: resolved "https://registry.yarnpkg.com/delegate/-/delegate-3.2.0.tgz#b66b71c3158522e8ab5744f720d8ca0c2af59166" integrity sha512-IofjkYBZaZivn0V8nnsMJGBr4jVLxHDheKSW88PyxS5QC4Vo9ZbZVvhzlSxY87fVq3STR6r+4cGepyHkcWOQSw== -depd@~1.1.2: +depd@^1.1.2, depd@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak= +deprecated-decorator@^0.1.6: + version "0.1.6" + resolved "https://registry.yarnpkg.com/deprecated-decorator/-/deprecated-decorator-0.1.6.tgz#00966317b7a12fe92f3cc831f7583af329b86c37" + integrity sha1-AJZjF7ehL+kvPMgx91g68ym4bDc= + destroy@~1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" @@ -5504,6 +5905,13 @@ encodeurl@~1.0.2: resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= +encoding@^0.1.12: + version "0.1.13" + resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.13.tgz#56574afdd791f54a8e9b2785c0582a2d26210fa9" + integrity sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A== + dependencies: + iconv-lite "^0.6.2" + end-of-stream@^1.1.0: version "1.4.4" resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" @@ -5536,6 +5944,11 @@ entities@^2.0.0: resolved "https://registry.yarnpkg.com/entities/-/entities-2.2.0.tgz#098dc90ebb83d8dffa089d55256b351d34c4da55" integrity sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A== +err-code@^2.0.2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/err-code/-/err-code-2.0.3.tgz#23c2f3b756ffdfc608d30e27c9a941024807e7f9" + integrity sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA== + errno@^0.1.3: version "0.1.8" resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.8.tgz#8bb3e9c7d463be4976ff888f76b4809ebc2e811f" @@ -5572,6 +5985,20 @@ es-abstract@^1.17.2, es-abstract@^1.18.0-next.1, es-abstract@^1.18.0-next.2: string.prototype.trimstart "^1.0.4" unbox-primitive "^1.0.0" +es-get-iterator@^1.1.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/es-get-iterator/-/es-get-iterator-1.1.2.tgz#9234c54aba713486d7ebde0220864af5e2b283f7" + integrity sha512-+DTO8GYwbMCwbywjimwZMHp8AuYXOS2JZFWoi2AlPOS3ebnII9w/NLpNZtA7A0YLaVDw+O7KFCeoIV7OPvM7hQ== + dependencies: + call-bind "^1.0.2" + get-intrinsic "^1.1.0" + has-symbols "^1.0.1" + is-arguments "^1.1.0" + is-map "^2.0.2" + is-set "^2.0.2" + is-string "^1.0.5" + isarray "^2.0.5" + es-module-lexer@^0.4.0: version "0.4.1" resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-0.4.1.tgz#dda8c6a14d8f340a24e34331e0fab0cb50438e0e" @@ -5966,7 +6393,7 @@ express-graphql@0.12.0: http-errors "1.8.0" raw-body "^2.4.1" -express@^4.17.1: +express@4.17.1, express@^4.17.1: version "4.17.1" resolved "https://registry.yarnpkg.com/express/-/express-4.17.1.tgz#4491fc38605cf51f8629d39c2b5d026f98a4c134" integrity sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g== @@ -6308,11 +6735,23 @@ follow-redirects@^1.0.0, follow-redirects@^1.10.0: resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.13.3.tgz#e5598ad50174c1bc4e872301e82ac2cd97f90267" integrity sha512-DUgl6+HDzB0iEptNQEXLx/KhTmDb8tZUHSeLqpnjpknR70H0nC2t9N73BK6fN4hOvJ84pKlIQVQ4k5FFlBedKA== +for-each@^0.3.3: + version "0.3.3" + resolved "https://registry.yarnpkg.com/for-each/-/for-each-0.3.3.tgz#69b447e88a0a5d32c3e7084f3f1710034b21376e" + integrity sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw== + dependencies: + is-callable "^1.1.3" + for-in@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" integrity sha1-gQaNKVqBQuwKxybG4iAMMPttXoA= +foreach@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/foreach/-/foreach-2.0.5.tgz#0bee005018aeb260d0a3af3ae658dd0136ec1b99" + integrity sha1-C+4AUBiusmDQo6865ljdATbsG5k= + fork-ts-checker-webpack-plugin@4.1.6: version "4.1.6" resolved "https://registry.yarnpkg.com/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-4.1.6.tgz#5055c703febcf37fa06405d400c122b905167fc5" @@ -6366,6 +6805,11 @@ fresh@0.5.2: resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac= +fs-capacitor@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/fs-capacitor/-/fs-capacitor-2.0.4.tgz#5a22e72d40ae5078b4fe64fe4d08c0d3fc88ad3c" + integrity sha512-8S4f4WsCryNw2mJJchi46YgB6CR5Ze+4L1h8ewl9tEpL4SJ3ZO+c/bS4BWhB8bK+O3TMqhuZarTitd0S0eh2pA== + fs-capacitor@^6.2.0: version "6.2.0" resolved "https://registry.yarnpkg.com/fs-capacitor/-/fs-capacitor-6.2.0.tgz#fa79ac6576629163cb84561995602d8999afb7f5" @@ -6418,6 +6862,13 @@ fs-extra@^9.1.0: jsonfile "^6.0.1" universalify "^2.0.0" +fs-minipass@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-2.1.0.tgz#7f5036fdbf12c63c169190cbe4199c852271f9fb" + integrity sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg== + dependencies: + minipass "^3.0.0" + fs.realpath@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" @@ -6468,7 +6919,7 @@ get-caller-file@^2.0.1, get-caller-file@^2.0.5: resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== -get-intrinsic@^1.0.2, get-intrinsic@^1.1.1: +get-intrinsic@^1.0.1, get-intrinsic@^1.0.2, get-intrinsic@^1.1.0, get-intrinsic@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.1.tgz#15f59f376f855c446963948f0d24cd3637b4abc6" integrity sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q== @@ -6686,6 +7137,15 @@ grapheme-splitter@^1.0.4: resolved "https://registry.yarnpkg.com/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz#9cf3a665c6247479896834af35cf1dbb4400767e" integrity sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ== +graphql-extensions@^0.15.0: + version "0.15.0" + resolved "https://registry.yarnpkg.com/graphql-extensions/-/graphql-extensions-0.15.0.tgz#3f291f9274876b0c289fa4061909a12678bd9817" + integrity sha512-bVddVO8YFJPwuACn+3pgmrEg6I8iBuYLuwvxiE+lcQQ7POotVZxm2rgGw0PvVYmWWf3DT7nTVDZ5ROh/ALp8mA== + dependencies: + "@apollographql/apollo-tools" "^0.5.0" + apollo-server-env "^3.1.0" + apollo-server-types "^0.9.0" + graphql-helix@1.6.1: version "1.6.1" resolved "https://registry.yarnpkg.com/graphql-helix/-/graphql-helix-1.6.1.tgz#f504b8ceb8661c5884a6ae5edfcbd66891342710" @@ -6714,13 +7174,24 @@ graphql-subscriptions@1.2.1: dependencies: iterall "^1.3.0" -graphql-tag@2.12.5, graphql-tag@^2.12.0: +graphql-tag@2.12.5, graphql-tag@^2.11.0, graphql-tag@^2.12.0: version "2.12.5" resolved "https://registry.yarnpkg.com/graphql-tag/-/graphql-tag-2.12.5.tgz#5cff974a67b417747d05c8d9f5f3cb4495d0db8f" integrity sha512-5xNhP4063d16Pz3HBtKprutsPrmHZi5IdUGOWRxA2B6VF7BIRGOHZ5WQvDmJXZuPcBg7rYwaFxvQYjqkSdR3TQ== dependencies: tslib "^2.1.0" +graphql-tools@^4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/graphql-tools/-/graphql-tools-4.0.8.tgz#e7fb9f0d43408fb0878ba66b522ce871bafe9d30" + integrity sha512-MW+ioleBrwhRjalKjYaLQbr+920pHBgy9vM/n47sswtns8+96sRn5M/G+J1eu7IMeKWiN/9p6tmwCHU7552VJg== + dependencies: + apollo-link "^1.2.14" + apollo-utilities "^1.0.1" + deprecated-decorator "^0.1.6" + iterall "^1.1.3" + uuid "^3.1.0" + graphql-type-json@0.3.2: version "0.3.2" resolved "https://registry.yarnpkg.com/graphql-type-json/-/graphql-type-json-0.3.2.tgz#f53a851dbfe07bd1c8157d24150064baab41e115" @@ -7068,7 +7539,7 @@ htmlparser2@^3.10.1, htmlparser2@^3.9.1: inherits "^2.0.1" readable-stream "^3.1.1" -http-cache-semantics@^4.0.0: +http-cache-semantics@^4.0.0, http-cache-semantics@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz#49e91c5cbf36c9b94bcfcd71c23d5249ec74e390" integrity sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ== @@ -7100,7 +7571,7 @@ http-errors@1.7.3, http-errors@~1.7.2: statuses ">= 1.5.0 < 2" toidentifier "1.0.0" -http-errors@1.8.0, http-errors@^1.8.0: +http-errors@1.8.0, http-errors@^1.7.3, http-errors@^1.8.0: version "1.8.0" resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.8.0.tgz#75d1bbe497e1044f51e4ee9e704a62f28d336507" integrity sha512-4I8r0C5JDhT5VkvI47QktDW75rNlGVsUf/8hzjCC/wkWI/jdTRmBb9aI7erSG82r1bjKY3F6k28WnsVxB1C73A== @@ -7172,6 +7643,13 @@ human-signals@^2.1.0: resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== +humanize-ms@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/humanize-ms/-/humanize-ms-1.2.1.tgz#c46e3159a293f6b896da29316d8b6fe8bb79bbed" + integrity sha1-xG4xWaKT9riW2ikxbYtv6Lt5u+0= + dependencies: + ms "^2.0.0" + husky@7.0.1: version "7.0.1" resolved "https://registry.yarnpkg.com/husky/-/husky-7.0.1.tgz#579f4180b5da4520263e8713cc832942b48e1f1c" @@ -7184,6 +7662,13 @@ iconv-lite@0.4.24, iconv-lite@^0.4.24: dependencies: safer-buffer ">= 2.1.2 < 3" +iconv-lite@^0.6.2: + version "0.6.3" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.3.tgz#a52f80bf38da1952eb5c681790719871a1a72501" + integrity sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw== + dependencies: + safer-buffer ">= 2.1.2 < 3.0.0" + icss-replace-symbols@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/icss-replace-symbols/-/icss-replace-symbols-1.1.0.tgz#06ea6f83679a7749e386cfe1fe812ae5db223ded" @@ -7263,6 +7748,11 @@ indent-string@^4.0.0: resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-4.0.0.tgz#624f8f4497d619b2d9768531d58f4122854d7251" integrity sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg== +infer-owner@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/infer-owner/-/infer-owner-1.0.4.tgz#c4cefcaa8e51051c2a40ba2ce8a3d27295af9467" + integrity sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A== + infima@0.2.0-alpha.23: version "0.2.0-alpha.23" resolved "https://registry.yarnpkg.com/infima/-/infima-0.2.0-alpha.23.tgz#2c17b473784ae8244fd985f126f9c27a49b24523" @@ -7368,7 +7858,7 @@ is-alphanumerical@^1.0.0: is-alphabetical "^1.0.0" is-decimal "^1.0.0" -is-arguments@^1.0.4: +is-arguments@^1.0.4, is-arguments@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.1.0.tgz#62353031dfbee07ceb34656a6bde59efecae8dd9" integrity sha512-1Ij4lOMPl/xB5kBDn7I+b2ttPMKa8szhEIrXDuXQD/oe3HJLTLhqhgGspwgyGd6MOywBUqVvYicF72lkgDnIHg== @@ -7421,7 +7911,7 @@ is-buffer@^2.0.0: resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-2.0.5.tgz#ebc252e400d22ff8d77fa09888821a24a658c191" integrity sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ== -is-callable@^1.1.4, is-callable@^1.2.3: +is-callable@^1.1.3, is-callable@^1.1.4, is-callable@^1.2.3: version "1.2.3" resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.3.tgz#8b1e0500b73a1d76c70487636f368e519de8db8e" integrity sha512-J1DcMe8UYTBSrKezuIUTUwjXsho29693unXM2YhJUTR2txK/eG47bvNa/wipPFmZFgr/N6f1GA66dv0mEyTIyQ== @@ -7478,6 +7968,11 @@ is-date-object@^1.0.1: resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.2.tgz#bda736f2cd8fd06d32844e7743bfa7494c3bfd7e" integrity sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g== +is-date-object@^1.0.2: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.4.tgz#550cfcc03afada05eea3dd30981c7b09551f73e5" + integrity sha512-/b4ZVsG7Z5XVtIxs/h9W8nvfLgSAyKYdtGWQLbqy6jA1icmgjf8WCoTKgeS4wy5tYaPePouzFMANbnj94c2Z+A== + is-decimal@^1.0.0: version "1.0.4" resolved "https://registry.yarnpkg.com/is-decimal/-/is-decimal-1.0.4.tgz#65a3a5958a1c5b63a706e1b333d7cd9f630d3fa5" @@ -7582,6 +8077,16 @@ is-installed-globally@^0.4.0: global-dirs "^3.0.0" is-path-inside "^3.0.2" +is-lambda@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-lambda/-/is-lambda-1.0.1.tgz#3d9877899e6a53efc0160504cde15f82e6f061d5" + integrity sha1-PZh3iZ5qU+/AFgUEzeFfgubwYdU= + +is-map@^2.0.1, is-map@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/is-map/-/is-map-2.0.2.tgz#00922db8c9bf73e81b7a335827bc2a43f2b91127" + integrity sha512-cOZFQQozTha1f4MxLFzlgKYPTyj26picdZTx82hbc/Xf4K/tZOOXSCkMvU4pKioRXGDLJRn0GM7Upe7kR721yg== + is-module@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-module/-/is-module-1.0.0.tgz#3258fb69f78c14d5b815d664336b4cffb6441591" @@ -7683,6 +8188,14 @@ is-regex@^1.0.4, is-regex@^1.1.2: call-bind "^1.0.2" has-symbols "^1.0.1" +is-regex@^1.1.1: + version "1.1.3" + resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.3.tgz#d029f9aff6448b93ebbe3f33dac71511fdcbef9f" + integrity sha512-qSVXFz28HM7y+IWX6vLCsexdlvzT1PJNFSBuaQLQ5o0IEw8UDYW6/2+eCMVyIsbM8CNLX2a/QWmSpyxYEHY7CQ== + dependencies: + call-bind "^1.0.2" + has-symbols "^1.0.2" + is-regexp@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-regexp/-/is-regexp-1.0.0.tgz#fd2d883545c46bac5a633e7b9a09e87fa2cb5069" @@ -7698,6 +8211,11 @@ is-root@2.1.0, is-root@^2.1.0: resolved "https://registry.yarnpkg.com/is-root/-/is-root-2.1.0.tgz#809e18129cf1129644302a4f8544035d51984a9c" integrity sha512-AGOriNp96vNBd3HtU+RzFEc75FfR5ymiYv8E553I71SCeXBiMsVDUtdio1OEFvrPyLIQ9tVR5RxXIFe5PUFjMg== +is-set@^2.0.1, is-set@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/is-set/-/is-set-2.0.2.tgz#90755fa4c2562dc1c5d4024760d6119b94ca18ec" + integrity sha512-+2cnTEZeY5z/iXGbLhPrOAaK/Mau5k5eXq9j14CpRTftq0pAJu2MwVRSZhyZWBzx3o6X795Lz6Bpb6R0GKf37g== + is-stream@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" @@ -7727,6 +8245,17 @@ is-symbol@^1.0.2, is-symbol@^1.0.3: dependencies: has-symbols "^1.0.1" +is-typed-array@^1.1.3: + version "1.1.5" + resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.5.tgz#f32e6e096455e329eb7b423862456aa213f0eb4e" + integrity sha512-S+GRDgJlR3PyEbsX/Fobd9cqpZBuvUS+8asRqYDMLCb2qMzt1oz5m5oxQCxOgUDxiWsOVNi4yaF+/uvdlHlYug== + dependencies: + available-typed-arrays "^1.0.2" + call-bind "^1.0.2" + es-abstract "^1.18.0-next.2" + foreach "^2.0.5" + has-symbols "^1.0.1" + is-typedarray@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" @@ -7737,6 +8266,16 @@ is-unicode-supported@^0.1.0: resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7" integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw== +is-weakmap@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-weakmap/-/is-weakmap-2.0.1.tgz#5008b59bdc43b698201d18f62b37b2ca243e8cf2" + integrity sha512-NSBR4kH5oVj1Uwvv970ruUkCV7O1mzgVFO4/rev2cLRda9Tm9HrL70ZPut4rOHgY0FNrUu9BCbXA2sdQ+x0chA== + +is-weakset@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-weakset/-/is-weakset-2.0.1.tgz#e9a0af88dbd751589f5e50d80f4c98b780884f83" + integrity sha512-pi4vhbhVHGLxohUw7PhGsueT4vRGFoXhP7+RGN0jKIv9+8PWYCQTqtADngrxOm2g46hoH0+g8uZZBzMrvVGDmw== + is-whitespace-character@^1.0.0: version "1.0.4" resolved "https://registry.yarnpkg.com/is-whitespace-character/-/is-whitespace-character-1.0.4.tgz#0858edd94a95594c7c9dd0b5c174ec6e45ee4aa7" @@ -7779,6 +8318,11 @@ isarray@1.0.0, isarray@~1.0.0: resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= +isarray@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.5.tgz#8af1e4c1221244cc62459faf38940d4e644a5723" + integrity sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw== + isexe@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" @@ -7855,7 +8399,7 @@ istanbul-reports@^3.0.2: html-escaper "^2.0.0" istanbul-lib-report "^3.0.0" -iterall@^1.2.1, iterall@^1.3.0: +iterall@^1.1.3, iterall@^1.2.1, iterall@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/iterall/-/iterall-1.3.0.tgz#afcb08492e2915cbd8a0884eb93a8c94d0d72fea" integrity sha512-QZ9qOMdF+QLHxy1QIpUHUU1D5pS2CG2P69LF6L6CPjPYA/XMOmKV3PZpawHoAjHNyB0swdVTRxdYT4tbBbxqwg== @@ -8822,6 +9366,11 @@ lodash.some@^4.4.0: resolved "https://registry.yarnpkg.com/lodash.some/-/lodash.some-4.6.0.tgz#1bb9f314ef6b8baded13b549169b2a945eb68e4d" integrity sha1-G7nzFO9ri63tE7VJFpsqlF62jk0= +lodash.sortby@^4.7.0: + version "4.7.0" + resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438" + integrity sha1-7dFMgk4sycHgsKG0K7UhBRakJDg= + lodash.startcase@^4.4.0: version "4.4.0" resolved "https://registry.yarnpkg.com/lodash.startcase/-/lodash.startcase-4.4.0.tgz#9436e34ed26093ed7ffae1936144350915d9add8" @@ -8847,6 +9396,11 @@ lodash.uniq@4.5.0, lodash.uniq@^4.5.0: resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M= +lodash.xorby@^4.7.0: + version "4.7.0" + resolved "https://registry.yarnpkg.com/lodash.xorby/-/lodash.xorby-4.7.0.tgz#9c19a6f9f063a6eb53dd03c1b6871799801463d7" + integrity sha1-nBmm+fBjputT3QPBtocXmYAUY9c= + lodash@4.17.21, lodash@4.x, lodash@^4.17.11, lodash@^4.17.14, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.21, lodash@^4.7.0: version "4.17.21" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" @@ -8870,11 +9424,16 @@ log-update@^4.0.0: slice-ansi "^4.0.0" wrap-ansi "^6.2.0" -loglevel@^1.6.8: +loglevel@^1.6.1, loglevel@^1.6.7, loglevel@^1.6.8: version "1.7.1" resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.7.1.tgz#005fde2f5e6e47068f935ff28573e125ef72f197" integrity sha512-Hesni4s5UkWkwCGJMQGAh71PaLUmKFM60dHvq0zi/vDhhrzuk+4GgNbTXJ12YYQJn6ZKBDNIjYcuQGKudvqrIw== +long@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/long/-/long-4.0.0.tgz#9a7b71cfb7d361a194ea555241c92f7468d5bf28" + integrity sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA== + loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.2.0, loose-envify@^1.3.1, loose-envify@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" @@ -8953,6 +9512,27 @@ make-error@1.x: resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== +make-fetch-happen@^8.0.0: + version "8.0.14" + resolved "https://registry.yarnpkg.com/make-fetch-happen/-/make-fetch-happen-8.0.14.tgz#aaba73ae0ab5586ad8eaa68bd83332669393e222" + integrity sha512-EsS89h6l4vbfJEtBZnENTOFk8mCRpY5ru36Xe5bcX1KYIli2mkSHqoFsp5O1wMDvTJJzxe/4THpCTtygjeeGWQ== + dependencies: + agentkeepalive "^4.1.3" + cacache "^15.0.5" + http-cache-semantics "^4.1.0" + http-proxy-agent "^4.0.1" + https-proxy-agent "^5.0.0" + is-lambda "^1.0.1" + lru-cache "^6.0.0" + minipass "^3.1.3" + minipass-collect "^1.0.2" + minipass-fetch "^1.3.2" + minipass-flush "^1.0.5" + minipass-pipeline "^1.2.4" + promise-retry "^2.0.1" + socks-proxy-agent "^5.0.0" + ssri "^8.0.0" + makeerror@1.0.x: version "1.0.11" resolved "https://registry.yarnpkg.com/makeerror/-/makeerror-1.0.11.tgz#e01a5c9109f2af79660e4e8b9587790184f5a96c" @@ -9241,6 +9821,60 @@ minimist@^1.1.1, minimist@^1.2.0, minimist@^1.2.5: resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== +minipass-collect@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/minipass-collect/-/minipass-collect-1.0.2.tgz#22b813bf745dc6edba2576b940022ad6edc8c617" + integrity sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA== + dependencies: + minipass "^3.0.0" + +minipass-fetch@^1.3.2: + version "1.3.3" + resolved "https://registry.yarnpkg.com/minipass-fetch/-/minipass-fetch-1.3.3.tgz#34c7cea038c817a8658461bf35174551dce17a0a" + integrity sha512-akCrLDWfbdAWkMLBxJEeWTdNsjML+dt5YgOI4gJ53vuO0vrmYQkUPxa6j6V65s9CcePIr2SSWqjT2EcrNseryQ== + dependencies: + minipass "^3.1.0" + minipass-sized "^1.0.3" + minizlib "^2.0.0" + optionalDependencies: + encoding "^0.1.12" + +minipass-flush@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/minipass-flush/-/minipass-flush-1.0.5.tgz#82e7135d7e89a50ffe64610a787953c4c4cbb373" + integrity sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw== + dependencies: + minipass "^3.0.0" + +minipass-pipeline@^1.2.2, minipass-pipeline@^1.2.4: + version "1.2.4" + resolved "https://registry.yarnpkg.com/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz#68472f79711c084657c067c5c6ad93cddea8214c" + integrity sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A== + dependencies: + minipass "^3.0.0" + +minipass-sized@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/minipass-sized/-/minipass-sized-1.0.3.tgz#70ee5a7c5052070afacfbc22977ea79def353b70" + integrity sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g== + dependencies: + minipass "^3.0.0" + +minipass@^3.0.0, minipass@^3.1.0, minipass@^3.1.1, minipass@^3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-3.1.3.tgz#7d42ff1f39635482e15f9cdb53184deebd5815fd" + integrity sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg== + dependencies: + yallist "^4.0.0" + +minizlib@^2.0.0, minizlib@^2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-2.1.2.tgz#e90d3466ba209b932451508a11ce3d3632145931" + integrity sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg== + dependencies: + minipass "^3.0.0" + yallist "^4.0.0" + mixin-deep@^1.2.0: version "1.3.2" resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.2.tgz#1120b43dc359a785dce65b55b82e257ccf479566" @@ -9254,7 +9888,7 @@ mixme@^0.4.0: resolved "https://registry.yarnpkg.com/mixme/-/mixme-0.4.0.tgz#a1aee27f0d63cc905e1cc6ddc98abf94d414435e" integrity sha512-B4Sm1CDC5+ov5AYxSkyeT5HLtiDgNOLKwFlq34wr8E2O3zRdTvQiLzo599Jt9cir6VJrSenOlgvdooVYCQJIYw== -mkdirp@1.0.4, mkdirp@1.x, mkdirp@^1.0.4: +mkdirp@1.0.4, mkdirp@1.x, mkdirp@^1.0.3, mkdirp@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== @@ -9310,6 +9944,11 @@ ms@2.1.2, ms@^2.1.1: resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== +ms@^2.0.0: + version "2.1.3" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" + integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== + multicast-dns-service-types@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/multicast-dns-service-types/-/multicast-dns-service-types-1.1.0.tgz#899f11d9686e5e05cb91b35d5f0e63b773cfc901" @@ -9519,7 +10158,7 @@ object-inspect@^1.9.0: resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.9.0.tgz#c90521d74e1127b67266ded3394ad6116986533a" integrity sha512-i3Bp9iTqwhaLZBxGkRfo5ZbE07BQRT7MGu8+nNgwW9ItGp1TzCTw2DLEoWwjClxBjOFI/hWljTAmYGCEwmtnOw== -object-is@^1.0.1: +object-is@^1.0.1, object-is@^1.1.4: version "1.1.5" resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.1.5.tgz#b9deeaa5fc7f1846a0faecdceec138e5778f53ac" integrity sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw== @@ -9532,7 +10171,7 @@ object-keys@^1.0.12, object-keys@^1.1.1: resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== -object-path@^0.11.5: +object-path@^0.11.4, object-path@^0.11.5: version "0.11.5" resolved "https://registry.yarnpkg.com/object-path/-/object-path-0.11.5.tgz#d4e3cf19601a5140a55a16ad712019a9c50b577a" integrity sha512-jgSbThcoR/s+XumvGMTMf81QVBmah+/Q7K7YduKeKVWL7N111unR2d6pZZarSk6kY/caeNxUDyxOvMWyzoU2eg== @@ -9554,7 +10193,7 @@ object.assign@^4.1.0, object.assign@^4.1.2: has-symbols "^1.0.1" object-keys "^1.1.1" -object.getownpropertydescriptors@^2.1.0: +object.getownpropertydescriptors@^2.1.0, object.getownpropertydescriptors@^2.1.1: version "2.1.2" resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.2.tgz#1bd63aeacf0d5d2d2f31b5e393b03a7c601a23f7" integrity sha512-WtxeKSzfBjlzL+F9b7M7hewDzMwy+C8NRssHd1YrNlzHzIDrXcXiNOMrezdAEM4UXixgV+vvnyBeN7Rygl2ttQ== @@ -10523,6 +11162,19 @@ progress@^2.0.0, progress@^2.0.3: resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== +promise-inflight@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3" + integrity sha1-mEcocL8igTL8vdhoEputEsPAKeM= + +promise-retry@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/promise-retry/-/promise-retry-2.0.1.tgz#ff747a13620ab57ba688f5fc67855410c370da22" + integrity sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g== + dependencies: + err-code "^2.0.2" + retry "^0.12.0" + promise@^7.1.1: version "7.3.1" resolved "https://registry.yarnpkg.com/promise/-/promise-7.3.1.tgz#064b72602b18f90f29192b8b1bc418ffd1ebd3bf" @@ -11069,7 +11721,7 @@ regex-not@^1.0.0, regex-not@^1.0.2: extend-shallow "^3.0.2" safe-regex "^1.1.0" -regexp.prototype.flags@^1.2.0: +regexp.prototype.flags@^1.2.0, regexp.prototype.flags@^1.3.0: version "1.3.1" resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.3.1.tgz#7ef352ae8d159e758c0eadca6f8fcb4eef07be26" integrity sha512-JiBdRBq91WlY7uRJ0ds7R+dU02i6LKi8r3BuQhNXn+kmeLN+EfHhfjqMRis1zJxnlu88hq/4dx0P2OP3APRTOA== @@ -11362,7 +12014,7 @@ ret@~0.1.10: resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg== -retry@^0.12.0: +retry@0.12.0, retry@^0.12.0: version "0.12.0" resolved "https://registry.yarnpkg.com/retry/-/retry-0.12.0.tgz#1b42a6266a21f07421d1b0b54b7dc167b01c013b" integrity sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs= @@ -11452,6 +12104,13 @@ rxjs@^6.6.3, rxjs@^6.6.7: dependencies: tslib "^1.9.0" +rxjs@^7.1.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.2.0.tgz#5cd12409639e9514a71c9f5f9192b2c4ae94de31" + integrity sha512-aX8w9OpKrQmiPKfT1bqETtUr9JygIz6GZ+gql8v7CijClsP0laoFUdKzxFAoWuRdSlOdU2+crss+cMf+cqMTnw== + dependencies: + tslib "~2.1.0" + safe-buffer@5.1.2, safe-buffer@>=5.1.0, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@~5.1.0, safe-buffer@~5.1.1: version "5.1.2" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" @@ -11464,7 +12123,7 @@ safe-regex@^1.1.0: dependencies: ret "~0.1.10" -"safer-buffer@>= 2.1.2 < 3": +"safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0": version "2.1.2" resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== @@ -11678,6 +12337,14 @@ setprototypeof@1.2.0: resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424" integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== +sha.js@^2.4.11: + version "2.4.11" + resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.11.tgz#37a5cf0b81ecbc6943de109ba2960d1b26584ae7" + integrity sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ== + dependencies: + inherits "^2.0.1" + safe-buffer "^5.0.1" + shallow-clone@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/shallow-clone/-/shallow-clone-3.0.1.tgz#8f2981ad92531f55035b01fb230769a40e02efa3" @@ -11731,6 +12398,15 @@ shiki@^0.9.3: onigasm "^2.2.5" vscode-textmate "^5.2.0" +side-channel@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf" + integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw== + dependencies: + call-bind "^1.0.0" + get-intrinsic "^1.0.2" + object-inspect "^1.9.0" + signal-exit@^3.0.0, signal-exit@^3.0.2, signal-exit@^3.0.3: version "3.0.3" resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.3.tgz#a1410c2edd8f077b08b4e253c8eacfcaf057461c" @@ -11800,6 +12476,11 @@ slice-ansi@^4.0.0: astral-regex "^2.0.0" is-fullwidth-code-point "^3.0.0" +smart-buffer@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/smart-buffer/-/smart-buffer-4.1.0.tgz#91605c25d91652f4661ea69ccf45f1b331ca21ba" + integrity sha512-iVICrxOzCynf/SNaBQCw34eM9jROU/s5rzIhpOvzhzuYHfJR/DhZfDkXiZSgKXfgv26HT3Yni3AV/DGw0cGnnw== + smartwrap@^1.2.3: version "1.2.5" resolved "https://registry.yarnpkg.com/smartwrap/-/smartwrap-1.2.5.tgz#45ee3e09ac234e5f7f17c16e916f511834f3cd23" @@ -11862,6 +12543,23 @@ sockjs@^0.3.21: uuid "^3.4.0" websocket-driver "^0.7.4" +socks-proxy-agent@^5.0.0: + version "5.0.1" + resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-5.0.1.tgz#032fb583048a29ebffec2e6a73fca0761f48177e" + integrity sha512-vZdmnjb9a2Tz6WEQVIurybSwElwPxMZaIc7PzqbJTrezcKNznv6giT7J7tZDZ1BojVaa1jvO/UiUdhDVB0ACoQ== + dependencies: + agent-base "^6.0.2" + debug "4" + socks "^2.3.3" + +socks@^2.3.3: + version "2.6.1" + resolved "https://registry.yarnpkg.com/socks/-/socks-2.6.1.tgz#989e6534a07cf337deb1b1c94aaa44296520d30e" + integrity sha512-kLQ9N5ucj8uIcxrDwjm0Jsqk06xdpBjGNQtpXy4Q8/QY2k+fY7nZH8CARy+hkbG+SGAovmzzuauCpBlb8FrnBA== + dependencies: + ip "^1.1.5" + smart-buffer "^4.1.0" + sort-css-media-queries@1.5.4: version "1.5.4" resolved "https://registry.yarnpkg.com/sort-css-media-queries/-/sort-css-media-queries-1.5.4.tgz#24182b12002a13d01ba943ddf74f5098d7c244ce" @@ -12007,6 +12705,13 @@ sprintf-js@~1.0.2: resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= +ssri@^8.0.0, ssri@^8.0.1: + version "8.0.1" + resolved "https://registry.yarnpkg.com/ssri/-/ssri-8.0.1.tgz#638e4e439e2ffbd2cd289776d5ca457c4f51a2af" + integrity sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ== + dependencies: + minipass "^3.1.1" + stable@^0.1.8: version "0.1.8" resolved "https://registry.yarnpkg.com/stable/-/stable-0.1.8.tgz#836eb3c8382fe2936feaf544631017ce7d47a3cf" @@ -12238,6 +12943,17 @@ subscriptions-transport-ws@^0.10.0: symbol-observable "^1.0.4" ws "^5.2.0 || ^6.0.0 || ^7.0.0" +subscriptions-transport-ws@^0.9.19: + version "0.9.19" + resolved "https://registry.yarnpkg.com/subscriptions-transport-ws/-/subscriptions-transport-ws-0.9.19.tgz#10ca32f7e291d5ee8eb728b9c02e43c52606cdcf" + integrity sha512-dxdemxFFB0ppCLg10FTtRqH/31FNRL1y1BQv8209MK5I4CwALb7iihQg+7p65lFcIl8MHatINWBLOqpgU4Kyyw== + dependencies: + backo2 "^1.0.2" + eventemitter3 "^3.1.0" + iterall "^1.2.1" + symbol-observable "^1.0.4" + ws "^5.2.0 || ^6.0.0 || ^7.0.0" + supports-color@^5.3.0, supports-color@^5.4.0: version "5.5.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" @@ -12394,6 +13110,18 @@ tapable@^2.0.0, tapable@^2.1.1, tapable@^2.2.0: resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.0.tgz#5c373d281d9c672848213d0e037d1c4165ab426b" integrity sha512-FBk4IesMV1rBxX2tfiK8RAmogtWn53puLOQlvO8XuwlgxcYbP4mVPS9Ph4aeamSyyVjOl24aYWAuc8U5kCVwMw== +tar@^6.0.2: + version "6.1.0" + resolved "https://registry.yarnpkg.com/tar/-/tar-6.1.0.tgz#d1724e9bcc04b977b18d5c573b333a2207229a83" + integrity sha512-DUCttfhsnLCjwoDoFcI+B2iJgYa93vBnDUATYEeRx6sntCTdN01VnqsIuTlALXla/LWooNg0yEGeB+Y8WdFxGA== + dependencies: + chownr "^2.0.0" + fs-minipass "^2.0.0" + minipass "^3.0.0" + minizlib "^2.1.1" + mkdirp "^1.0.3" + yallist "^4.0.0" + term-size@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/term-size/-/term-size-1.2.0.tgz#458b83887f288fc56d6fffbfad262e26638efa69" @@ -12603,6 +13331,13 @@ ts-essentials@^2.0.3: resolved "https://registry.yarnpkg.com/ts-essentials/-/ts-essentials-2.0.12.tgz#c9303f3d74f75fa7528c3d49b80e089ab09d8745" integrity sha512-3IVX4nI6B5cc31/GFFE+i8ey/N2eA0CZDbo6n0yrz0zDX8ZJ8djmU1p+XRz7G3is0F3bB3pu2pAroFdAWQKU3w== +ts-invariant@^0.4.0: + version "0.4.4" + resolved "https://registry.yarnpkg.com/ts-invariant/-/ts-invariant-0.4.4.tgz#97a523518688f93aafad01b0e80eb803eb2abd86" + integrity sha512-uEtWkFM/sdZvRNNDL3Ehu4WVpwaulhwQszV8mrtcdeE8nN00BV9mAmQ88RkrBhFgl9gMgvjJLAQcZbnPXI9mlA== + dependencies: + tslib "^1.9.3" + ts-invariant@^0.8.0: version "0.8.2" resolved "https://registry.yarnpkg.com/ts-invariant/-/ts-invariant-0.8.2.tgz#62af654ebfb8b1eeb55bc9adc2f40c6b93b0ff7e" @@ -12653,11 +13388,21 @@ tslib@1.11.1, tslib@^1.10.0, tslib@^1.11.1, tslib@^1.8.1, tslib@^1.9.0: resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.11.1.tgz#eb15d128827fbee2841549e171f45ed338ac7e35" integrity sha512-aZW88SY8kQbU7gpV19lN24LtXh/yD4ZZg6qieAJDDg+YBsJcSmLGK9QpnUjAKVG/xefmvJGd1WUmfpT/g6AJGA== +tslib@^1.9.3: + version "1.14.1" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" + integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== + tslib@^2.0.3, tslib@^2.1.0, tslib@^2.2.0, tslib@~2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.3.0.tgz#803b8cdab3e12ba581a4ca41c8839bbb0dacb09e" integrity sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg== +tslib@~2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.1.0.tgz#da60860f1c2ecaa5703ab7d39bc05b6bf988b97a" + integrity sha512-hcVC3wYEziELGGmEEXue7D75zbwIIVUMWAVbHItGPx0ziyXxrOMQx4rQEVEV45Ut/1IotuEvwqPopzIOkDMf0A== + tslib@~2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.2.0.tgz#fb2c475977e35e241311ede2693cee1ec6698f5c" @@ -12891,6 +13636,20 @@ uniqs@^2.0.0: resolved "https://registry.yarnpkg.com/uniqs/-/uniqs-2.0.0.tgz#ffede4b36b25290696e6e165d4a59edb998e6b02" integrity sha1-/+3ks2slKQaW5uFl1KWe25mOawI= +unique-filename@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/unique-filename/-/unique-filename-1.1.1.tgz#1d69769369ada0583103a1e6ae87681b56573230" + integrity sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ== + dependencies: + unique-slug "^2.0.0" + +unique-slug@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/unique-slug/-/unique-slug-2.0.2.tgz#baabce91083fc64e945b0f3ad613e264f7cd4e6c" + integrity sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w== + dependencies: + imurmurhash "^0.1.4" + unique-string@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/unique-string/-/unique-string-2.0.0.tgz#39c6451f81afb2749de2b233e3f7c5e8843bd89d" @@ -13099,6 +13858,17 @@ util-deprecate@^1.0.1, util-deprecate@^1.0.2, util-deprecate@~1.0.1: resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= +util.promisify@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/util.promisify/-/util.promisify-1.1.1.tgz#77832f57ced2c9478174149cae9b96e9918cd54b" + integrity sha512-/s3UsZUrIfa6xDhr7zZhnE9SLQ5RIXyYfiVnMMyMDzOc8WhWN4Nbh36H842OyurKbCDAesZOJaVyvmSl6fhGQw== + dependencies: + call-bind "^1.0.0" + define-properties "^1.1.3" + for-each "^0.3.3" + has-symbols "^1.0.1" + object.getownpropertydescriptors "^2.1.1" + util.promisify@~1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/util.promisify/-/util.promisify-1.0.1.tgz#6baf7774b80eeb0f7520d8b81d07982a59abbaee" @@ -13124,11 +13894,16 @@ utils-merge@1.0.1: resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM= -uuid@^3.3.2, uuid@^3.4.0: +uuid@^3.1.0, uuid@^3.3.2, uuid@^3.4.0: version "3.4.0" resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== +uuid@^8.0.0: + version "8.3.2" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" + integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== + v8-compile-cache@^2.0.3: version "2.3.0" resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee" @@ -13223,6 +13998,17 @@ w3c-xmlserializer@^2.0.0: dependencies: xml-name-validator "^3.0.0" +wait-on@6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/wait-on/-/wait-on-6.0.0.tgz#7e9bf8e3d7fe2daecbb7a570ac8ca41e9311c7e7" + integrity sha512-tnUJr9p5r+bEYXPUdRseolmz5XqJTTj98JgOsfBn7Oz2dxfE2g3zw1jE+Mo8lopM3j3et/Mq1yW7kKX6qw7RVw== + dependencies: + axios "^0.21.1" + joi "^17.4.0" + lodash "^4.17.21" + minimist "^1.2.5" + rxjs "^7.1.0" + wait-on@^5.3.0: version "5.3.0" resolved "https://registry.yarnpkg.com/wait-on/-/wait-on-5.3.0.tgz#584e17d4b3fe7b46ac2b9f8e5e102c005c2776c7" @@ -13469,6 +14255,16 @@ which-boxed-primitive@^1.0.1: is-string "^1.0.5" is-symbol "^1.0.3" +which-collection@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/which-collection/-/which-collection-1.0.1.tgz#70eab71ebbbd2aefaf32f917082fc62cdcb70906" + integrity sha512-W8xeTUwaln8i3K/cY1nGXzdnVZlidBcagyNFtBdD5kxnb4TvGKR7FfSIS3mYpwWS1QUCutfKz8IY8RjftB0+1A== + dependencies: + is-map "^2.0.1" + is-set "^2.0.1" + is-weakmap "^2.0.1" + is-weakset "^2.0.1" + which-module@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" @@ -13482,6 +14278,19 @@ which-pm@2.0.0: load-yaml-file "^0.2.0" path-exists "^4.0.0" +which-typed-array@^1.1.2: + version "1.1.4" + resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.4.tgz#8fcb7d3ee5adf2d771066fba7cf37e32fe8711ff" + integrity sha512-49E0SpUe90cjpoc7BOJwyPHRqSAd12c10Qm2amdEZrJPCY2NDxaW01zHITrem+rnETY3dwrbH3UUrUwagfCYDA== + dependencies: + available-typed-arrays "^1.0.2" + call-bind "^1.0.0" + es-abstract "^1.18.0-next.1" + foreach "^2.0.5" + function-bind "^1.1.1" + has-symbols "^1.0.1" + is-typed-array "^1.1.3" + which@^1.2.9, which@^1.3.1: version "1.3.1" resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" @@ -13638,6 +14447,14 @@ xmlchars@^2.2.0: resolved "https://registry.yarnpkg.com/xmlchars/-/xmlchars-2.2.0.tgz#060fe1bcb7f9c76fe2a17db86a9bc3ab894210cb" integrity sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw== +xss@^1.0.8: + version "1.0.9" + resolved "https://registry.yarnpkg.com/xss/-/xss-1.0.9.tgz#3ffd565571ff60d2e40db7f3b80b4677bec770d2" + integrity sha512-2t7FahYnGJys6DpHLhajusId7R0Pm2yTmuL0GV9+mV0ZlaLSnb2toBmppATfg5sWIhZQGlsTLoecSzya+l4EAQ== + dependencies: + commander "^2.20.3" + cssfilter "0.0.10" + xtend@^4.0.0, xtend@^4.0.1, xtend@^4.0.2: version "4.0.2" resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" @@ -13750,7 +14567,15 @@ yocto-queue@^0.1.0: resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== -zen-observable@^0.8.14: +zen-observable-ts@^0.8.21: + version "0.8.21" + resolved "https://registry.yarnpkg.com/zen-observable-ts/-/zen-observable-ts-0.8.21.tgz#85d0031fbbde1eba3cd07d3ba90da241215f421d" + integrity sha512-Yj3yXweRc8LdRMrCC8nIc4kkjWecPAUVh0TI0OUrWXx6aX790vLcDlWca6I4vsyCGH3LpWxq0dJRcMOFoVqmeg== + dependencies: + tslib "^1.9.3" + zen-observable "^0.8.0" + +zen-observable@^0.8.0, zen-observable@^0.8.14: version "0.8.15" resolved "https://registry.yarnpkg.com/zen-observable/-/zen-observable-0.8.15.tgz#96415c512d8e3ffd920afd3889604e30b9eaac15" integrity sha512-PQ2PC7R9rslx84ndNBZB/Dkv8V8fZEpk83RLgXtYd0fwUgEjseMn1Dgajh2x6S8QbZAFa9p2qVCEuYZNgve0dQ== From d9d3cc515d695c6405257e9bf728cab088ae94cf Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 13 Jul 2021 07:19:18 -0400 Subject: [PATCH 60/66] fix(deps): update apollo graphql packages (#3194) Co-authored-by: Renovate Bot --- benchmark/federation/package.json | 4 +- benchmark/federation/yarn.lock | 205 +++++++++++++++++++++--------- 2 files changed, 149 insertions(+), 60 deletions(-) diff --git a/benchmark/federation/package.json b/benchmark/federation/package.json index b0ce388767a..11e4bcada91 100644 --- a/benchmark/federation/package.json +++ b/benchmark/federation/package.json @@ -9,8 +9,8 @@ "loadtest:monolith": "k6 -e ENDPOINT=monolith run k6.js" }, "dependencies": { - "@apollo/gateway": "0.32.0", - "@apollo/federation": "0.25.2", + "@apollo/gateway": "0.33.0", + "@apollo/federation": "0.26.0", "@graphql-tools/stitch": "7.5.3", "@graphql-tools/stitching-directives": "1.3.3", "express": "4.17.1", diff --git a/benchmark/federation/yarn.lock b/benchmark/federation/yarn.lock index 112de248902..7f636bdf6e2 100644 --- a/benchmark/federation/yarn.lock +++ b/benchmark/federation/yarn.lock @@ -2,21 +2,21 @@ # yarn lockfile v1 -"@apollo/federation@0.25.2", "@apollo/federation@^0.25.2": - version "0.25.2" - resolved "https://registry.yarnpkg.com/@apollo/federation/-/federation-0.25.2.tgz#10b2e22ac20e64701fd6d31d9abbf7f411b03763" - integrity sha512-TrRCrGniHpnRwALm2J7q2c1X4Lcc95e7SeHkVjascaQx6nBZGFbBXadw8rOPxlw5syfxYf8h9winF+wwld+gsg== +"@apollo/federation@0.26.0", "@apollo/federation@^0.26.0": + version "0.26.0" + resolved "https://registry.yarnpkg.com/@apollo/federation/-/federation-0.26.0.tgz#72c89f01995bd2e066d447fed4aa58678d759bf6" + integrity sha512-j3l6lhQod630LQzLm2hhDyQQJtQikT7vRtRgIa3PuKEq6ouuOd1OQERhBnecobJlUfRWJkfvjYJ/PhQZ2sm/7Q== dependencies: apollo-graphql "^0.9.3" lodash.xorby "^4.7.0" -"@apollo/gateway@0.32.0": - version "0.32.0" - resolved "https://registry.yarnpkg.com/@apollo/gateway/-/gateway-0.32.0.tgz#639b7b826c76a2bffdf777902010485dfd981918" - integrity sha512-Pxq3VVxG1ALrFNN8SM3RVy6Kwm+5p1KG3ObVmQX720Wx5WpRKvCRC23J/c3oFRpsGqjPOglh3vmpAQVdJJTCZA== +"@apollo/gateway@0.33.0": + version "0.33.0" + resolved "https://registry.yarnpkg.com/@apollo/gateway/-/gateway-0.33.0.tgz#6e282fb88eb86d9ab9ae35d6d5d3e174085a6907" + integrity sha512-NQTFysgRzPYR8g90K43/hgH+Rxe7F/E2G2Linfc81VVNk5NruRSUeQV0EnsROC7lLbCqiCJ+WSQcN0ZaR2Jo7A== dependencies: - "@apollo/federation" "^0.25.2" - "@apollo/query-planner" "^0.2.2" + "@apollo/federation" "^0.26.0" + "@apollo/query-planner" "^0.2.3" "@opentelemetry/api" "^1.0.1" "@types/node-fetch" "2.5.10" apollo-graphql "^0.9.3" @@ -49,10 +49,10 @@ "@types/node" "^10.1.0" long "^4.0.0" -"@apollo/query-planner@^0.2.2": - version "0.2.2" - resolved "https://registry.yarnpkg.com/@apollo/query-planner/-/query-planner-0.2.2.tgz#5397e5cd8a73dede34c485fb0c5fefa054f9153a" - integrity sha512-+RZSKY0xDYki9qwlzKXDNa+jrbj0Qstq44lcB21aViiDdEJWOTwf7Cqg3h/hN7QsUnL75XiDrwsjMLnwFdHSoQ== +"@apollo/query-planner@^0.2.3": + version "0.2.3" + resolved "https://registry.yarnpkg.com/@apollo/query-planner/-/query-planner-0.2.3.tgz#8018ae12c24541838541cc7b20d6a628556918e5" + integrity sha512-3jYHLhuUTolAouVTkR1NrGH7ZQzj91KfH1L1Ddd2i2hfCG6VDj9xuRe+nznYV1Sk3/Uy226d7BPKo110H/3Pow== dependencies: chalk "^4.1.0" deep-equal "^2.0.5" @@ -182,6 +182,18 @@ tslib "~2.2.0" value-or-promise "1.0.6" +"@hapi/hoek@^9.0.0": + version "9.2.0" + resolved "https://registry.yarnpkg.com/@hapi/hoek/-/hoek-9.2.0.tgz#f3933a44e365864f4dad5db94158106d511e8131" + integrity sha512-sqKVVVOe5ivCaXDWivIJYVSaEgdQK9ul7a4Kity5Iw7u9+wBAPbX1RMSnLLmp7O4Vzj0WOWwMAJsTL00xwaNug== + +"@hapi/topo@^5.0.0": + version "5.1.0" + resolved "https://registry.yarnpkg.com/@hapi/topo/-/topo-5.1.0.tgz#dc448e332c6c6e37a4dc02fd84ba8d44b9afb012" + integrity sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg== + dependencies: + "@hapi/hoek" "^9.0.0" + "@jest/types@^26.6.2": version "26.6.2" resolved "https://registry.yarnpkg.com/@jest/types/-/types-26.6.2.tgz#bef5a532030e1d88a2f5a6d933f84e97226ed48e" @@ -264,6 +276,23 @@ resolved "https://registry.yarnpkg.com/@protobufjs/utf8/-/utf8-1.1.0.tgz#a777360b5b39a1a2e5106f8e858f2fd2d060c570" integrity sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA= +"@sideway/address@^4.1.0": + version "4.1.2" + resolved "https://registry.yarnpkg.com/@sideway/address/-/address-4.1.2.tgz#811b84333a335739d3969cfc434736268170cad1" + integrity sha512-idTz8ibqWFrPU8kMirL0CoPH/A29XOzzAzpyN3zQ4kAWnzmNfFmRaoMNN6VI8ske5M73HZyhIaW4OuSFIdM4oA== + dependencies: + "@hapi/hoek" "^9.0.0" + +"@sideway/formula@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@sideway/formula/-/formula-3.0.0.tgz#fe158aee32e6bd5de85044be615bc08478a0a13c" + integrity sha512-vHe7wZ4NOXVfkoRb8T5otiENVlT7a3IAiw7H5M2+GO+9CDgcVUUsX1zalAztCmwyOr2RUTGJdgB+ZvSVqmdHmg== + +"@sideway/pinpoint@^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@sideway/pinpoint/-/pinpoint-2.0.0.tgz#cff8ffadc372ad29fd3f78277aeb29e632cc70df" + integrity sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ== + "@tootallnate/once@1": version "1.1.2" resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-1.1.2.tgz#ccb91445360179a04e7fe6aff78c00ffc1eeaf82" @@ -405,12 +434,7 @@ "@types/node" "*" form-data "^3.0.0" -"@types/node@*": - version "16.0.0" - resolved "https://registry.yarnpkg.com/@types/node/-/node-16.0.0.tgz#067a6c49dc7a5c2412a505628e26902ae967bf6f" - integrity sha512-TmCW5HoZ2o2/z2EYi109jLqIaPIi9y/lc2LmDCWzuCi35bcaQ+OtUh6nwBiFK7SOu25FAU5+YKdqFZUwtqGSdg== - -"@types/node@^10.1.0": +"@types/node@*", "@types/node@^10.1.0": version "10.17.60" resolved "https://registry.yarnpkg.com/@types/node/-/node-10.17.60.tgz#35f3d6213daed95da7f0f73e75bcc6980e90597b" integrity sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw== @@ -652,6 +676,13 @@ available-typed-arrays@^1.0.2: resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.4.tgz#9e0ae84ecff20caae6a94a1c3bc39b955649b7a9" integrity sha512-SA5mXJWrId1TaQjfxUYghbqQ/hYioKmLJvPJyDuYRtXXenFNMjj4hSSt1Cf1xsuXSXrtxrVC5Ot4eU6cOtBDdA== +axios@^0.21.1: + version "0.21.1" + resolved "https://registry.yarnpkg.com/axios/-/axios-0.21.1.tgz#22563481962f4d6bde9a76d516ef0e5d3c09b2b8" + integrity sha512-dKQiRHxGD9PPRIUNIWvZhPTPpl1rf/OxTYKsqKUDjBwYylTvV7SjSHJb9ratfyzM6wCdLCOYLzs73qpg5c4iGA== + dependencies: + follow-redirects "^1.10.0" + backo2@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/backo2/-/backo2-1.0.2.tgz#31ab1ac8b129363463e35b3ebb69f4dfcfba7947" @@ -811,6 +842,22 @@ core-js-pure@^3.10.2: resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.15.2.tgz#c8e0874822705f3385d3197af9348f7c9ae2e3ce" integrity sha512-D42L7RYh1J2grW8ttxoY1+17Y4wXZeKe7uyplAI3FkNQyI5OgBIAjUfFiTPfL1rs0qLpxaabITNbjKl1Sp82tA== +cross-env@7.0.3: + version "7.0.3" + resolved "https://registry.yarnpkg.com/cross-env/-/cross-env-7.0.3.tgz#865264b29677dc015ba8418918965dd232fc54cf" + integrity sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw== + dependencies: + cross-spawn "^7.0.1" + +cross-spawn@^7.0.1: + version "7.0.3" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" + integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== + dependencies: + path-key "^3.1.0" + shebang-command "^2.0.0" + which "^2.0.1" + cssfilter@0.0.10: version "0.0.10" resolved "https://registry.yarnpkg.com/cssfilter/-/cssfilter-0.0.10.tgz#c6d2672632a2e5c83e013e6864a42ce8defd20ae" @@ -1026,6 +1073,11 @@ finalhandler@~1.1.2: statuses "~1.5.0" unpipe "~1.0.0" +follow-redirects@^1.10.0: + version "1.14.1" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.1.tgz#d9114ded0a1cfdd334e164e6662ad02bfd91ff43" + integrity sha512-HWqDgT7ZEkqRzBvc2s64vSZ/hfOceEol3ac/7tKwzuvEyWx3/4UegXh5oBOIotkGsObyk3xznnSRVADBgWSQVg== + for-each@^0.3.3: version "0.3.3" resolved "https://registry.yarnpkg.com/for-each/-/for-each-0.3.3.tgz#69b447e88a0a5d32c3e7084f3f1710034b21376e" @@ -1170,18 +1222,7 @@ http-errors@1.7.2: statuses ">= 1.5.0 < 2" toidentifier "1.0.0" -http-errors@^1.7.3: - version "1.8.0" - resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.8.0.tgz#75d1bbe497e1044f51e4ee9e704a62f28d336507" - integrity sha512-4I8r0C5JDhT5VkvI47QktDW75rNlGVsUf/8hzjCC/wkWI/jdTRmBb9aI7erSG82r1bjKY3F6k28WnsVxB1C73A== - dependencies: - depd "~1.1.2" - inherits "2.0.4" - setprototypeof "1.2.0" - statuses ">= 1.5.0 < 2" - toidentifier "1.0.0" - -http-errors@~1.7.2: +http-errors@^1.7.3, http-errors@~1.7.2: version "1.7.3" resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.3.tgz#6c619e4f9c60308c38519498c14fbb10aacebb06" integrity sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw== @@ -1373,11 +1414,27 @@ isarray@^2.0.5: resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.5.tgz#8af1e4c1221244cc62459faf38940d4e644a5723" integrity sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw== +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= + iterall@^1.1.3, iterall@^1.2.1: version "1.3.0" resolved "https://registry.yarnpkg.com/iterall/-/iterall-1.3.0.tgz#afcb08492e2915cbd8a0884eb93a8c94d0d72fea" integrity sha512-QZ9qOMdF+QLHxy1QIpUHUU1D5pS2CG2P69LF6L6CPjPYA/XMOmKV3PZpawHoAjHNyB0swdVTRxdYT4tbBbxqwg== +joi@^17.4.0: + version "17.4.1" + resolved "https://registry.yarnpkg.com/joi/-/joi-17.4.1.tgz#15d2f23c8cbe4d1baded2dd190c58f8dbe11cca0" + integrity sha512-gDPOwQ5sr+BUxXuPDGrC1pSNcVR/yGGcTI0aCnjYxZEa3za60K/iCQ+OFIkEHWZGVCUcUlXlFKvMmrlmxrG6UQ== + dependencies: + "@hapi/hoek" "^9.0.0" + "@hapi/topo" "^5.0.0" + "@sideway/address" "^4.1.0" + "@sideway/formula" "^3.0.0" + "@sideway/pinpoint" "^2.0.0" + lodash.sortby@^4.7.0: version "4.7.0" resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438" @@ -1388,6 +1445,11 @@ lodash.xorby@^4.7.0: resolved "https://registry.yarnpkg.com/lodash.xorby/-/lodash.xorby-4.7.0.tgz#9c19a6f9f063a6eb53dd03c1b6871799801463d7" integrity sha1-nBmm+fBjputT3QPBtocXmYAUY9c= +lodash@^4.17.21: + version "4.17.21" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" + integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== + loglevel@^1.6.1, loglevel@^1.6.7: version "1.7.1" resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.7.1.tgz#005fde2f5e6e47068f935ff28573e125ef72f197" @@ -1472,6 +1534,11 @@ minimatch@^3.0.4: dependencies: brace-expansion "^1.1.7" +minimist@^1.2.5: + version "1.2.5" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" + integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== + minipass-collect@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/minipass-collect/-/minipass-collect-1.0.2.tgz#22b813bf745dc6edba2576b940022ad6edc8c617" @@ -1541,16 +1608,11 @@ ms@2.1.1: resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg== -ms@2.1.2: +ms@2.1.2, ms@^2.0.0: version "2.1.2" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== -ms@^2.0.0: - version "2.1.3" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" - integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== - negotiator@0.6.2: version "0.6.2" resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.2.tgz#feacf7ccf525a77ae9634436a64883ffeca346fb" @@ -1650,6 +1712,11 @@ path-is-absolute@^1.0.0: resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= +path-key@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" + integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== + path-to-regexp@0.1.7: version "0.1.7" resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" @@ -1731,16 +1798,18 @@ rimraf@^3.0.2: dependencies: glob "^7.1.3" -safe-buffer@5.1.2: +rxjs@^7.1.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.2.0.tgz#5cd12409639e9514a71c9f5f9192b2c4ae94de31" + integrity sha512-aX8w9OpKrQmiPKfT1bqETtUr9JygIz6GZ+gql8v7CijClsP0laoFUdKzxFAoWuRdSlOdU2+crss+cMf+cqMTnw== + dependencies: + tslib "~2.1.0" + +safe-buffer@5.1.2, safe-buffer@^5.0.1: version "5.1.2" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== -safe-buffer@^5.0.1: - version "5.2.1" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" - integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== - "safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0": version "2.1.2" resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" @@ -1780,11 +1849,6 @@ setprototypeof@1.1.1: resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.1.tgz#7e95acb24aa92f5885e0abef5ba131330d4ae683" integrity sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw== -setprototypeof@1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424" - integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== - sha.js@^2.4.11: version "2.4.11" resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.11.tgz#37a5cf0b81ecbc6943de109ba2960d1b26584ae7" @@ -1793,6 +1857,18 @@ sha.js@^2.4.11: inherits "^2.0.1" safe-buffer "^5.0.1" +shebang-command@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" + integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== + dependencies: + shebang-regex "^3.0.0" + +shebang-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" + integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== + side-channel@^1.0.3: version "1.0.4" resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf" @@ -1909,10 +1985,10 @@ tslib@^1.10.0, tslib@^1.9.3: resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== -tslib@^2.0.3, tslib@^2.1.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.3.0.tgz#803b8cdab3e12ba581a4ca41c8839bbb0dacb09e" - integrity sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg== +tslib@^2.0.3, tslib@^2.1.0, tslib@~2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.2.0.tgz#fb2c475977e35e241311ede2693cee1ec6698f5c" + integrity sha512-gS9GVHRU+RGn5KQM2rllAlR3dU6m7AcpJKdtH8gFvQiC4Otgk98XnmMU+nZenHt/+VhnBPWwgrJsyrdcw6i23w== tslib@~2.0.1: version "2.0.3" @@ -1924,11 +2000,6 @@ tslib@~2.1.0: resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.1.0.tgz#da60860f1c2ecaa5703ab7d39bc05b6bf988b97a" integrity sha512-hcVC3wYEziELGGmEEXue7D75zbwIIVUMWAVbHItGPx0ziyXxrOMQx4rQEVEV45Ut/1IotuEvwqPopzIOkDMf0A== -tslib@~2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.2.0.tgz#fb2c475977e35e241311ede2693cee1ec6698f5c" - integrity sha512-gS9GVHRU+RGn5KQM2rllAlR3dU6m7AcpJKdtH8gFvQiC4Otgk98XnmMU+nZenHt/+VhnBPWwgrJsyrdcw6i23w== - type-is@~1.6.17, type-is@~1.6.18: version "1.6.18" resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" @@ -2002,6 +2073,17 @@ vary@~1.1.2: resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw= +wait-on@6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/wait-on/-/wait-on-6.0.0.tgz#7e9bf8e3d7fe2daecbb7a570ac8ca41e9311c7e7" + integrity sha512-tnUJr9p5r+bEYXPUdRseolmz5XqJTTj98JgOsfBn7Oz2dxfE2g3zw1jE+Mo8lopM3j3et/Mq1yW7kKX6qw7RVw== + dependencies: + axios "^0.21.1" + joi "^17.4.0" + lodash "^4.17.21" + minimist "^1.2.5" + rxjs "^7.1.0" + which-boxed-primitive@^1.0.1, which-boxed-primitive@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz#13757bc89b209b049fe5d86430e21cf40a89a8e6" @@ -2036,6 +2118,13 @@ which-typed-array@^1.1.2: has-symbols "^1.0.1" is-typed-array "^1.1.3" +which@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" + integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== + dependencies: + isexe "^2.0.0" + wrappy@1: version "1.0.2" resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" From f14f5722c6f5c70269de58d4d6a0380edaa8a9af Mon Sep 17 00:00:00 2001 From: Laurin Quast Date: Tue, 13 Jul 2021 16:22:47 +0200 Subject: [PATCH 61/66] Update index.ts (#3197) --- packages/loaders/url/src/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/loaders/url/src/index.ts b/packages/loaders/url/src/index.ts index 090d72c7141..116915812c6 100644 --- a/packages/loaders/url/src/index.ts +++ b/packages/loaders/url/src/index.ts @@ -692,7 +692,7 @@ export class UrlLoader implements Loader { } loadSync(pointer: string, options: LoadFromUrlOptions): Source[] { - if (!this.canLoad(pointer, options)) { + if (!this.canLoadSync(pointer, options)) { return []; } From bcdbba37c53b6301e06f80d90cf14cd288a27cd0 Mon Sep 17 00:00:00 2001 From: Yaacov Rydzinski Date: Tue, 13 Jul 2021 22:16:14 +0300 Subject: [PATCH 62/66] refactor(stitchingInfo): shift more calculation to build time (#3199) -- run collectFields on selectionSet hints at build time -- use a fieldNode cache at build time so that at run time we can collect unique fieldNodes simply by using a Set --- packages/delegate/src/delegationBindings.ts | 4 +- .../delegate/src/getFieldsNotInSubschema.ts | 42 ++-- .../src/transforms/AddSelectionSets.ts | 43 ++-- packages/delegate/src/types.ts | 4 +- packages/stitch/src/stitchingInfo.ts | 217 +++++++++++------- 5 files changed, 179 insertions(+), 131 deletions(-) diff --git a/packages/delegate/src/delegationBindings.ts b/packages/delegate/src/delegationBindings.ts index 1eb05edc5a9..8d22b761682 100644 --- a/packages/delegate/src/delegationBindings.ts +++ b/packages/delegate/src/delegationBindings.ts @@ -21,8 +21,8 @@ export function defaultDelegationBinding( delegationTransforms = delegationTransforms.concat([ new ExpandAbstractTypes(), new AddSelectionSets( - stitchingInfo.selectionSetsByType, - stitchingInfo.selectionSetsByField, + stitchingInfo.fieldNodesByType, + stitchingInfo.fieldNodesByField, stitchingInfo.dynamicSelectionSetsByField ), new WrapConcreteTypes(), diff --git a/packages/delegate/src/getFieldsNotInSubschema.ts b/packages/delegate/src/getFieldsNotInSubschema.ts index 92b01eec8bc..33a1678f7f1 100644 --- a/packages/delegate/src/getFieldsNotInSubschema.ts +++ b/packages/delegate/src/getFieldsNotInSubschema.ts @@ -31,23 +31,34 @@ function collectSubFields(info: GraphQLResolveInfo, typeName: string): Record = info.schema.extensions?.['stitchingInfo']; - const selectionSetsByField = stitchingInfo?.selectionSetsByField; + const fieldNodesByField = stitchingInfo?.fieldNodesByField; - for (const responseName in subFieldNodes) { - const fieldName = subFieldNodes[responseName][0].name.value; - const fieldSelectionSet = selectionSetsByField?.[typeName]?.[fieldName]; - if (fieldSelectionSet != null) { - subFieldNodes = collectFields( - partialExecutionContext, - type, - fieldSelectionSet, - subFieldNodes, - visitedFragmentNames - ); + const subFieldNodesByFieldName = Object.create(null); + for (const responseKey in subFieldNodes) { + const fieldName = subFieldNodes[responseKey][0].name.value; + const additionalFieldNodes = fieldNodesByField?.[typeName]?.[fieldName]; + if (additionalFieldNodes) { + for (const additionalFieldNode of additionalFieldNodes) { + const additionalFieldName = additionalFieldNode.name.value; + if (subFieldNodesByFieldName[additionalFieldName] == null) { + subFieldNodesByFieldName[additionalFieldName] = [additionalFieldNode]; + } else { + subFieldNodesByFieldName[additionalFieldName].push(additionalFieldNode); + } + } + } + } + + for (const responseKey in subFieldNodes) { + const fieldName = subFieldNodes[responseKey][0].name.value; + if (subFieldNodesByFieldName[fieldName] == null) { + subFieldNodesByFieldName[fieldName] = subFieldNodes[responseKey]; + } else { + subFieldNodesByFieldName[fieldName].concat(subFieldNodes[responseKey]); } } - return subFieldNodes; + return subFieldNodesByFieldName; } export const getFieldsNotInSubschema = memoizeInfoAnd2Objects(function ( @@ -65,10 +76,9 @@ export const getFieldsNotInSubschema = memoizeInfoAnd2Objects(function ( const subFieldNodes = collectSubFields(info, typeName); let fieldsNotInSchema: Array = []; - for (const responseName in subFieldNodes) { - const fieldName = subFieldNodes[responseName][0].name.value; + for (const fieldName in subFieldNodes) { if (!(fieldName in fields)) { - fieldsNotInSchema = fieldsNotInSchema.concat(subFieldNodes[responseName]); + fieldsNotInSchema = fieldsNotInSchema.concat(subFieldNodes[fieldName]); } } diff --git a/packages/delegate/src/transforms/AddSelectionSets.ts b/packages/delegate/src/transforms/AddSelectionSets.ts index 4a5951c59bc..76c3a47d712 100644 --- a/packages/delegate/src/transforms/AddSelectionSets.ts +++ b/packages/delegate/src/transforms/AddSelectionSets.ts @@ -1,9 +1,8 @@ -import { SelectionSetNode, TypeInfo, Kind, FieldNode, SelectionNode, print } from 'graphql'; +import { SelectionSetNode, TypeInfo, Kind, FieldNode, SelectionNode } from 'graphql'; import { Maybe, ExecutionRequest } from '@graphql-tools/utils'; import { Transform, DelegationContext } from '../types'; -import { memoize2 } from '../memoize'; import VisitSelectionSets from './VisitSelectionSets'; @@ -11,12 +10,12 @@ export default class AddSelectionSets implements Transform { private readonly transformer: VisitSelectionSets; constructor( - selectionSetsByType: Record, - selectionSetsByField: Record>, + fieldNodesByType: Record>, + fieldNodesByField: Record>>, dynamicSelectionSetsByField: Record SelectionSetNode>>> ) { this.transformer = new VisitSelectionSets((node, typeInfo) => - visitSelectionSet(node, typeInfo, selectionSetsByType, selectionSetsByField, dynamicSelectionSetsByField) + visitSelectionSet(node, typeInfo, fieldNodesByType, fieldNodesByField, dynamicSelectionSetsByField) ); } @@ -32,30 +31,30 @@ export default class AddSelectionSets implements Transform { function visitSelectionSet( node: SelectionSetNode, typeInfo: TypeInfo, - selectionSetsByType: Record, - selectionSetsByField: Record>, + fieldNodesByType: Record>, + fieldNodesByField: Record>>, dynamicSelectionSetsByField: Record SelectionSetNode>>> ): Maybe { const parentType = typeInfo.getParentType(); - const newSelections: Map = new Map(); + const newSelections: Set = new Set(); if (parentType != null) { const parentTypeName = parentType.name; - addSelectionsToMap(newSelections, node); + addSelectionsToSet(newSelections, node.selections); - if (parentTypeName in selectionSetsByType) { - const selectionSet = selectionSetsByType[parentTypeName]; - addSelectionsToMap(newSelections, selectionSet); + const fieldNodes = fieldNodesByType[parentTypeName]; + if (fieldNodes) { + addSelectionsToSet(newSelections, fieldNodes); } - if (parentTypeName in selectionSetsByField) { + if (parentTypeName in fieldNodesByField) { for (const selection of node.selections) { if (selection.kind === Kind.FIELD) { - const name = selection.name.value; - const selectionSet = selectionSetsByField[parentTypeName][name]; - if (selectionSet != null) { - addSelectionsToMap(newSelections, selectionSet); + const fieldName = selection.name.value; + const fieldNodes = fieldNodesByField[parentTypeName][fieldName]; + if (fieldNodes != null) { + addSelectionsToSet(newSelections, fieldNodes); } } } @@ -70,7 +69,7 @@ function visitSelectionSet( for (const selectionSetFn of dynamicSelectionSets) { const selectionSet = selectionSetFn(selection); if (selectionSet != null) { - addSelectionsToMap(newSelections, selectionSet); + addSelectionsToSet(newSelections, selectionSet.selections); } } } @@ -85,8 +84,8 @@ function visitSelectionSet( } } -const addSelectionsToMap = memoize2(function (map: Map, selectionSet: SelectionSetNode): void { - for (const selection of selectionSet.selections) { - map.set(print(selection), selection); +function addSelectionsToSet(set: Set, selections: ReadonlyArray): void { + for (const selection of selections) { + set.add(selection); } -}); +} diff --git a/packages/delegate/src/types.ts b/packages/delegate/src/types.ts index 5b0dcaee820..05933cfda1f 100644 --- a/packages/delegate/src/types.ts +++ b/packages/delegate/src/types.ts @@ -193,8 +193,8 @@ export type MergedTypeResolver> = ( export interface StitchingInfo> { subschemaMap: Map, Subschema>; - selectionSetsByType: Record; - selectionSetsByField: Record>; + fieldNodesByType: Record>; + fieldNodesByField: Record>>; dynamicSelectionSetsByField: Record SelectionSetNode>>>; mergedTypes: Record>; } diff --git a/packages/stitch/src/stitchingInfo.ts b/packages/stitch/src/stitchingInfo.ts index 062e25be43e..8446cbb0a85 100644 --- a/packages/stitch/src/stitchingInfo.ts +++ b/packages/stitch/src/stitchingInfo.ts @@ -4,22 +4,31 @@ import { Kind, SelectionSetNode, isObjectType, - isScalarType, getNamedType, GraphQLInterfaceType, - SelectionNode, print, isInterfaceType, isLeafType, + FieldNode, + isInputObjectType, + isUnionType, } from 'graphql'; -import { parseSelectionSet, TypeMap, IResolvers, IFieldResolverOptions, isSome } from '@graphql-tools/utils'; +import { + parseSelectionSet, + TypeMap, + IResolvers, + IFieldResolverOptions, + isSome, + GraphQLExecutionContext, +} from '@graphql-tools/utils'; import { MergedTypeResolver, Subschema, SubschemaConfig, MergedTypeInfo, StitchingInfo } from '@graphql-tools/delegate'; import { MergeTypeCandidate, MergeTypeFilter } from './types'; import { createMergedTypeResolver } from './createMergedTypeResolver'; +import { collectFields } from 'graphql/execution/execute'; export function createStitchingInfo>( subschemaMap: Map, Subschema>, @@ -27,57 +36,10 @@ export function createStitchingInfo>( mergeTypes?: boolean | Array | MergeTypeFilter ): StitchingInfo { const mergedTypes = createMergedTypes(typeCandidates, mergeTypes); - const selectionSetsByField: Record> = Object.create(null); - - for (const typeName in mergedTypes) { - const mergedTypeInfo = mergedTypes[typeName]; - if (mergedTypeInfo.selectionSets == null && mergedTypeInfo.fieldSelectionSets == null) { - continue; - } - - selectionSetsByField[typeName] = Object.create(null); - - for (const [subschemaConfig, selectionSet] of mergedTypeInfo.selectionSets) { - const schema = subschemaConfig.transformedSchema; - const type = schema.getType(typeName) as GraphQLObjectType; - const fields = type.getFields(); - for (const fieldName in fields) { - const field = fields[fieldName]; - const fieldType = getNamedType(field.type); - if (selectionSet && isLeafType(fieldType) && selectionSetContainsTopLevelField(selectionSet, fieldName)) { - continue; - } - if (selectionSetsByField[typeName][fieldName] == null) { - selectionSetsByField[typeName][fieldName] = { - kind: Kind.SELECTION_SET, - selections: [parseSelectionSet('{ __typename }', { noLocation: true }).selections[0]], - }; - } - selectionSetsByField[typeName][fieldName].selections = selectionSetsByField[typeName][ - fieldName - ].selections.concat(selectionSet.selections); - } - } - - for (const [, selectionSetFieldMap] of mergedTypeInfo.fieldSelectionSets) { - for (const fieldName in selectionSetFieldMap) { - if (selectionSetsByField[typeName][fieldName] == null) { - selectionSetsByField[typeName][fieldName] = { - kind: Kind.SELECTION_SET, - selections: [parseSelectionSet('{ __typename }', { noLocation: true }).selections[0]], - }; - } - selectionSetsByField[typeName][fieldName].selections = selectionSetsByField[typeName][ - fieldName - ].selections.concat(selectionSetFieldMap[fieldName].selections); - } - } - } - return { subschemaMap, - selectionSetsByType: Object.create(null), - selectionSetsByField, + fieldNodesByType: Object.create(null), + fieldNodesByField: Object.create(null), dynamicSelectionSetsByField: Object.create(null), mergedTypes, }; @@ -227,70 +189,147 @@ export function completeStitchingInfo>( resolvers: IResolvers, schema: GraphQLSchema ): StitchingInfo { - const { selectionSetsByType, selectionSetsByField, dynamicSelectionSetsByField } = stitchingInfo; + const { fieldNodesByType, fieldNodesByField, dynamicSelectionSetsByField, mergedTypes } = stitchingInfo; // must add __typename to query and mutation root types to handle type merging with nested root types // cannot add __typename to subscription root types, but they cannot be nested const rootTypes = [schema.getQueryType(), schema.getMutationType()]; for (const rootType of rootTypes) { if (rootType) { - selectionSetsByType[rootType.name] = parseSelectionSet('{ __typename }', { noLocation: true }); + fieldNodesByType[rootType.name] = [ + parseSelectionSet('{ __typename }', { noLocation: true }).selections[0] as FieldNode, + ]; } } - for (const typeName in resolvers) { - const type = resolvers[typeName]; - if (isScalarType(type)) { + const selectionSetsByField: Record>> = Object.create(null); + for (const typeName in mergedTypes) { + const mergedTypeInfo = mergedTypes[typeName]; + if (mergedTypeInfo.selectionSets == null && mergedTypeInfo.fieldSelectionSets == null) { continue; } - for (const fieldName in type) { - const field = type[fieldName] as IFieldResolverOptions; - if (field.selectionSet) { - if (typeof field.selectionSet === 'function') { - if (!(typeName in dynamicSelectionSetsByField)) { - dynamicSelectionSetsByField[typeName] = Object.create(null); - } - if (!(fieldName in dynamicSelectionSetsByField[typeName])) { - dynamicSelectionSetsByField[typeName][fieldName] = []; - } + for (const [subschemaConfig, selectionSet] of mergedTypeInfo.selectionSets) { + const schema = subschemaConfig.transformedSchema; + const type = schema.getType(typeName) as GraphQLObjectType; + const fields = type.getFields(); + for (const fieldName in fields) { + const field = fields[fieldName]; + const fieldType = getNamedType(field.type); + if (selectionSet && isLeafType(fieldType) && selectionSetContainsTopLevelField(selectionSet, fieldName)) { + continue; + } + updateSelectionSetMap(selectionSetsByField, typeName, fieldName, selectionSet, true); + } + } - dynamicSelectionSetsByField[typeName][fieldName].push(field.selectionSet); - } else { - const selectionSet = parseSelectionSet(field.selectionSet, { noLocation: true }); - if (!(typeName in selectionSetsByField)) { - selectionSetsByField[typeName] = Object.create(null); - } + for (const [, selectionSetFieldMap] of mergedTypeInfo.fieldSelectionSets) { + for (const fieldName in selectionSetFieldMap) { + const selectionSet = selectionSetFieldMap[fieldName]; + updateSelectionSetMap(selectionSetsByField, typeName, fieldName, selectionSet, true); + } + } + } - if (!(fieldName in selectionSetsByField[typeName])) { - selectionSetsByField[typeName][fieldName] = { - kind: Kind.SELECTION_SET, - selections: [], - }; - } - selectionSetsByField[typeName][fieldName].selections = selectionSetsByField[typeName][ - fieldName - ].selections.concat(selectionSet.selections); + for (const typeName in resolvers) { + const type = schema.getType(typeName); + if (type === undefined || isLeafType(type) || isInputObjectType(type) || isUnionType(type)) { + continue; + } + const resolver = resolvers[typeName]; + for (const fieldName in resolver) { + const field = resolver[fieldName] as IFieldResolverOptions; + if (typeof field.selectionSet === 'function') { + if (!(typeName in dynamicSelectionSetsByField)) { + dynamicSelectionSetsByField[typeName] = Object.create(null); } + + if (!(fieldName in dynamicSelectionSetsByField[typeName])) { + dynamicSelectionSetsByField[typeName][fieldName] = []; + } + + dynamicSelectionSetsByField[typeName][fieldName].push(field.selectionSet); + } else if (field.selectionSet) { + const selectionSet = parseSelectionSet(field.selectionSet, { noLocation: true }); + updateSelectionSetMap(selectionSetsByField, typeName, fieldName, selectionSet); } } } + const partialExecutionContext = { + schema, + variableValues: Object.create(null), + fragments: Object.create(null), + }; + + const fieldNodeMap = Object.create(null); + for (const typeName in selectionSetsByField) { - const typeSelectionSets = selectionSetsByField[typeName]; - for (const fieldName in typeSelectionSets) { - const consolidatedSelections: Map = new Map(); - const selectionSet = typeSelectionSets[fieldName]; - for (const selection of selectionSet.selections) { - consolidatedSelections.set(print(selection), selection); + const type = schema.getType(typeName) as GraphQLObjectType; + for (const fieldName in selectionSetsByField[typeName]) { + for (const selectionSet of selectionSetsByField[typeName][fieldName]) { + const fieldNodes = collectFields( + partialExecutionContext as GraphQLExecutionContext, + type, + selectionSet, + Object.create(null), + Object.create(null) + ); + + for (const responseKey in fieldNodes) { + for (const fieldNode of fieldNodes[responseKey]) { + const key = print(fieldNode); + if (fieldNodeMap[key] == null) { + fieldNodeMap[key] = fieldNode; + updateArrayMap(fieldNodesByField, typeName, fieldName, fieldNode); + } else { + updateArrayMap(fieldNodesByField, typeName, fieldName, fieldNodeMap[key]); + } + } + } } - selectionSet.selections = Array.from(consolidatedSelections.values()); } } return stitchingInfo; } +function updateSelectionSetMap( + map: Record>>, + typeName: string, + fieldName: string, + selectionSet: SelectionSetNode, + includeTypename?: boolean +): void { + if (includeTypename) { + const typenameSelectionSet = parseSelectionSet('{ __typename }', { noLocation: true }); + updateArrayMap(map, typeName, fieldName, selectionSet, typenameSelectionSet); + return; + } + + updateArrayMap(map, typeName, fieldName, selectionSet); +} + +function updateArrayMap( + map: Record>>, + typeName: string, + fieldName: string, + value: T, + initialValue?: T +): void { + if (map[typeName] == null) { + const initialItems = initialValue === undefined ? [value] : [initialValue, value]; + map[typeName] = { + [fieldName]: initialItems, + }; + } else if (map[typeName][fieldName] == null) { + const initialItems = initialValue === undefined ? [value] : [initialValue, value]; + map[typeName][fieldName] = initialItems; + } else { + map[typeName][fieldName].push(value); + } +} + export function addStitchingInfo>( stitchedSchema: GraphQLSchema, stitchingInfo: StitchingInfo From 6877b9136d532b5dc70d7f431ac2e79c3c8b2b80 Mon Sep 17 00:00:00 2001 From: Arda TANRIKULU Date: Wed, 14 Jul 2021 01:34:41 +0300 Subject: [PATCH 63/66] mergeDeep improvements (#3201) * enhance(delegate): use Object.assign instead of mergeDeep in mergeExternalObjects * Avoid isScalarType in mergeDeep * No need for isScalarType --- .changeset/green-rocks-swim.md | 8 ++++ packages/delegate/src/externalObjects.ts | 11 +++--- packages/merge/src/extensions.ts | 7 +--- packages/merge/src/merge-resolvers.ts | 2 +- .../src/stitchingDirectivesTransformer.ts | 14 +++---- packages/utils/src/mergeDeep.ts | 37 +++++++++--------- packages/utils/tests/mergeDeep.test.ts | 39 ++++++++++--------- 7 files changed, 63 insertions(+), 55 deletions(-) create mode 100644 .changeset/green-rocks-swim.md diff --git a/.changeset/green-rocks-swim.md b/.changeset/green-rocks-swim.md new file mode 100644 index 00000000000..9c291002d67 --- /dev/null +++ b/.changeset/green-rocks-swim.md @@ -0,0 +1,8 @@ +--- +'@graphql-tools/utils': major +--- + +BREAKING CHANGES; + +`mergeDeep` now takes an array of sources instead of set of parameters as input and it takes an additional flag to enable prototype merging +Instead of `mergeDeep(...sources)` => `mergeDeep(sources)` diff --git a/packages/delegate/src/externalObjects.ts b/packages/delegate/src/externalObjects.ts index daee3d8035d..d3310d12bb1 100644 --- a/packages/delegate/src/externalObjects.ts +++ b/packages/delegate/src/externalObjects.ts @@ -1,6 +1,6 @@ import { GraphQLSchema, GraphQLError, GraphQLObjectType, SelectionSetNode, locatedError } from 'graphql'; -import { mergeDeep, relocatedError, GraphQLExecutionContext, collectFields } from '@graphql-tools/utils'; +import { relocatedError, GraphQLExecutionContext, collectFields } from '@graphql-tools/utils'; import { SubschemaConfig, ExternalObject } from './types'; import { OBJECT_SUBSCHEMA_SYMBOL, FIELD_SUBSCHEMA_MAP_SYMBOL, UNPATHED_ERRORS_SYMBOL } from './symbols'; @@ -73,16 +73,17 @@ export function mergeExternalObjects( } } - const combinedResult: ExternalObject = results.reduce(mergeDeep, target); + const combinedResult: ExternalObject = Object.assign({}, target, ...results); - const newFieldSubschemaMap = results.reduce((newFieldSubschemaMap, source) => { + const newFieldSubschemaMap = target[FIELD_SUBSCHEMA_MAP_SYMBOL] ?? Object.create(null); + + for (const source of results) { const objectSubschema = source[OBJECT_SUBSCHEMA_SYMBOL]; const fieldSubschemaMap = source[FIELD_SUBSCHEMA_MAP_SYMBOL]; for (const responseKey in source) { newFieldSubschemaMap[responseKey] = fieldSubschemaMap?.[responseKey] ?? objectSubschema; } - return newFieldSubschemaMap; - }, target[FIELD_SUBSCHEMA_MAP_SYMBOL] ?? Object.create(null)); + } combinedResult[FIELD_SUBSCHEMA_MAP_SYMBOL] = newFieldSubschemaMap; combinedResult[OBJECT_SUBSCHEMA_SYMBOL] = target[OBJECT_SUBSCHEMA_SYMBOL]; diff --git a/packages/merge/src/extensions.ts b/packages/merge/src/extensions.ts index 58118ab0225..64816790318 100644 --- a/packages/merge/src/extensions.ts +++ b/packages/merge/src/extensions.ts @@ -140,10 +140,7 @@ export function travelSchemaPossibleExtensions( } export function mergeExtensions(extensions: SchemaExtensions[]): SchemaExtensions { - return extensions.reduce( - (result, extensionObj) => [result, extensionObj].reduce(mergeDeep, {} as SchemaExtensions), - {} as SchemaExtensions - ); + return mergeDeep(extensions); } function applyExtensionObject( @@ -154,7 +151,7 @@ function applyExtensionObject( return; } - obj.extensions = [obj.extensions || {}, extensions || {}].reduce(mergeDeep, {}); + obj.extensions = mergeDeep([obj.extensions || {}, extensions || {}]); } export function applyExtensions(schema: GraphQLSchema, extensions: SchemaExtensions): GraphQLSchema { diff --git a/packages/merge/src/merge-resolvers.ts b/packages/merge/src/merge-resolvers.ts index 1f7b26b27fa..8e58a480d43 100644 --- a/packages/merge/src/merge-resolvers.ts +++ b/packages/merge/src/merge-resolvers.ts @@ -62,7 +62,7 @@ export function mergeResolvers( resolvers.push(resolversDefinition); } } - const result = resolvers.reduce(mergeDeep, {}); + const result = mergeDeep(resolvers, true); if (options?.exclusions) { for (const exclusion of options.exclusions) { diff --git a/packages/stitching-directives/src/stitchingDirectivesTransformer.ts b/packages/stitching-directives/src/stitchingDirectivesTransformer.ts index c0cef3553ae..178a2cf9424 100644 --- a/packages/stitching-directives/src/stitchingDirectivesTransformer.ts +++ b/packages/stitching-directives/src/stitchingDirectivesTransformer.ts @@ -329,10 +329,10 @@ export function stitchingDirectivesTransformer( const additionalArgs = mergeDirective['additionalArgs']; if (additionalArgs != null) { - parsedMergeArgsExpr.args = mergeDeep( + parsedMergeArgsExpr.args = mergeDeep([ parsedMergeArgsExpr.args, - valueFromASTUntyped(parseValue(`{ ${additionalArgs} }`, { noLocation: true })) - ); + valueFromASTUntyped(parseValue(`{ ${additionalArgs} }`, { noLocation: true })), + ]); } mergedTypesResolversInfo[typeName] = { @@ -473,13 +473,13 @@ function generateArgsFromKeysFn( ): (keys: ReadonlyArray) => Record { const { expansions, args } = mergedTypeResolverInfo; return (keys: ReadonlyArray): Record => { - const newArgs = mergeDeep({}, args); + const newArgs = mergeDeep([{}, args]); if (expansions) { for (const expansion of expansions) { const mappingInstructions = expansion.mappingInstructions; const expanded: Array = []; for (const key of keys) { - let newValue = mergeDeep({}, expansion.valuePath); + let newValue = mergeDeep([{}, expansion.valuePath]); for (const { destinationPath, sourcePath } of mappingInstructions) { if (destinationPath.length) { addProperty(newValue, destinationPath, getProperty(key, sourcePath)); @@ -500,7 +500,7 @@ function generateArgsFn(mergedTypeResolverInfo: MergedTypeResolverInfo): (origin const { mappingInstructions, args, usedProperties } = mergedTypeResolverInfo; return (originalResult: any): Record => { - const newArgs = mergeDeep({}, args); + const newArgs = mergeDeep([{}, args]); const filteredResult = getProperties(originalResult, usedProperties); if (mappingInstructions) { for (const mappingInstruction of mappingInstructions) { @@ -532,7 +532,7 @@ function buildKeyExpr(key: Array): string { for (const aliasPart of aliasParts.reverse()) { object = { [aliasPart]: object }; } - mergedObject = mergeDeep(mergedObject, object); + mergedObject = mergeDeep([mergedObject, object]); } return JSON.stringify(mergedObject).replace(/"/g, ''); diff --git a/packages/utils/src/mergeDeep.ts b/packages/utils/src/mergeDeep.ts index 79a7b3a241e..5d0d940f1d4 100644 --- a/packages/utils/src/mergeDeep.ts +++ b/packages/utils/src/mergeDeep.ts @@ -1,28 +1,29 @@ import { isSome } from './helpers'; -import { isScalarType } from 'graphql'; type BoxedTupleTypes = { [P in keyof T]: [T[P]] }[Exclude]; type UnionToIntersection = (U extends any ? (k: U) => void : never) extends (k: infer I) => void ? I : never; type UnboxIntersection = T extends { 0: infer U } ? U : never; // eslint-disable-next-line @typescript-eslint/ban-types -export function mergeDeep( - target: T, - ...sources: S -): T & UnboxIntersection>> & any { - if (isScalarType(target)) { - return target; - } +export function mergeDeep( + sources: S, + respectPrototype = false +): UnboxIntersection>> & any { + const target = sources[0] || {}; const output = {}; - Object.setPrototypeOf(output, Object.create(Object.getPrototypeOf(target))); - for (const source of [target, ...sources]) { + if (respectPrototype) { + Object.setPrototypeOf(output, Object.create(Object.getPrototypeOf(target))); + } + for (const source of sources) { if (isObject(target) && isObject(source)) { - const outputPrototype = Object.getPrototypeOf(output); - const sourcePrototype = Object.getPrototypeOf(source); - if (sourcePrototype) { - for (const key of Object.getOwnPropertyNames(sourcePrototype)) { - const descriptor = Object.getOwnPropertyDescriptor(sourcePrototype, key); - if (isSome(descriptor)) { - Object.defineProperty(outputPrototype, key, descriptor); + if (respectPrototype) { + const outputPrototype = Object.getPrototypeOf(output); + const sourcePrototype = Object.getPrototypeOf(source); + if (sourcePrototype) { + for (const key of Object.getOwnPropertyNames(sourcePrototype)) { + const descriptor = Object.getOwnPropertyDescriptor(sourcePrototype, key); + if (isSome(descriptor)) { + Object.defineProperty(outputPrototype, key, descriptor); + } } } } @@ -32,7 +33,7 @@ export function mergeDeep( if (!(key in output)) { Object.assign(output, { [key]: source[key] }); } else { - output[key] = mergeDeep(output[key], source[key]); + output[key] = mergeDeep([output[key], source[key]] as S, respectPrototype); } } else { Object.assign(output, { [key]: source[key] }); diff --git a/packages/utils/tests/mergeDeep.test.ts b/packages/utils/tests/mergeDeep.test.ts index c60c537c434..4093209c3d6 100644 --- a/packages/utils/tests/mergeDeep.test.ts +++ b/packages/utils/tests/mergeDeep.test.ts @@ -1,6 +1,24 @@ import { mergeDeep } from '@graphql-tools/utils' describe('mergeDeep', () => { + + test('merges deeply', () => { + const x = { a: { one: 1 } } + const y = { a: { two: 2 } } + expect(mergeDeep([x, y])).toEqual({ a: { one: 1, two: 2 } }) + }) + + test('strips property symbols', () => { + const x = {} + const symbol = Symbol('symbol') + x[symbol] = 'value' + const y = { a: 2 } + + const merged = mergeDeep([x, y]) + expect(merged).toStrictEqual({ a: 2 }) + expect(Object.getOwnPropertySymbols(merged)).toEqual([]) + }) + test('merges prototypes', () => { const ClassA = class { a() { @@ -13,17 +31,11 @@ describe('mergeDeep', () => { } } - const merged = mergeDeep(new ClassA(), new ClassB()) + const merged = mergeDeep([new ClassA(), new ClassB()], true) expect(merged.a()).toEqual('a') expect(merged.b()).toEqual('b') }) - test('merges deeply', () => { - const x = { a: { one: 1 } } - const y = { a: { two: 2 } } - expect(mergeDeep(x, y)).toEqual({ a: { one: 1, two: 2 } }) - }) - test('merges prototype deeply', () => { const ClassA = class { a() { @@ -36,20 +48,9 @@ describe('mergeDeep', () => { } } - const merged = mergeDeep({ one: new ClassA()}, { one: new ClassB()}) + const merged = mergeDeep([{ one: new ClassA() }, { one: new ClassB() }], true) expect(merged.one.a()).toEqual('a') expect(merged.one.b()).toEqual('b') expect(merged.a).toBeUndefined() }) - - test('strips property symbols', () => { - const x = {} - const symbol = Symbol('symbol') - x[symbol] = 'value' - const y = { a: 2 } - - const merged = mergeDeep(x, y) - expect(merged).toStrictEqual({ a: 2 }) - expect(Object.getOwnPropertySymbols(merged)).toEqual([]) - }) }) From 1270a800b941637fe7b9fc31b7956c0c05b81bd1 Mon Sep 17 00:00:00 2001 From: Arda TANRIKULU Date: Wed, 14 Jul 2021 01:37:16 +0300 Subject: [PATCH 64/66] Use collectFields and ExecutionContext from graphql-js (#3200) --- packages/delegate/src/delegateToSchema.ts | 4 +- packages/delegate/src/externalObjects.ts | 5 +- .../delegate/src/getFieldsNotInSubschema.ts | 5 +- .../delegate/src/transforms/FilterToSchema.ts | 3 +- .../src/transforms/VisitSelectionSets.ts | 11 +- packages/delegate/src/types.ts | 3 +- packages/stitch/src/stitchingInfo.ts | 16 +-- packages/stitch/src/typeCandidates.ts | 3 +- packages/utils/src/Interfaces.ts | 16 --- packages/utils/src/collectFields.ts | 127 ------------------ packages/utils/src/heal.ts | 3 +- packages/utils/src/index.ts | 1 - packages/utils/src/mapSchema.ts | 2 +- packages/utils/src/rewire.ts | 2 +- packages/utils/src/visitResult.ts | 16 +-- .../wrap/src/generateProxyingResolvers.ts | 16 ++- 16 files changed, 42 insertions(+), 191 deletions(-) delete mode 100644 packages/utils/src/collectFields.ts diff --git a/packages/delegate/src/delegateToSchema.ts b/packages/delegate/src/delegateToSchema.ts index 53938ae1ebf..0fd2aa79534 100644 --- a/packages/delegate/src/delegateToSchema.ts +++ b/packages/delegate/src/delegateToSchema.ts @@ -99,9 +99,7 @@ export function delegateRequest, TArgs = any>( .then(originalResult => { if (isAsyncIterable(originalResult)) { // "subscribe" to the subscription result and map the result through the transforms - return mapAsyncIterator(originalResult, originalResult => ({ - [delegationContext.fieldName]: transformer.transformResult(originalResult), - })); + return mapAsyncIterator(originalResult, result => transformer.transformResult(result)); } return transformer.transformResult(originalResult); }) diff --git a/packages/delegate/src/externalObjects.ts b/packages/delegate/src/externalObjects.ts index d3310d12bb1..58887eca119 100644 --- a/packages/delegate/src/externalObjects.ts +++ b/packages/delegate/src/externalObjects.ts @@ -1,9 +1,10 @@ import { GraphQLSchema, GraphQLError, GraphQLObjectType, SelectionSetNode, locatedError } from 'graphql'; -import { relocatedError, GraphQLExecutionContext, collectFields } from '@graphql-tools/utils'; +import { relocatedError } from '@graphql-tools/utils'; import { SubschemaConfig, ExternalObject } from './types'; import { OBJECT_SUBSCHEMA_SYMBOL, FIELD_SUBSCHEMA_MAP_SYMBOL, UNPATHED_ERRORS_SYMBOL } from './symbols'; +import { collectFields, ExecutionContext } from 'graphql/execution/execute.js'; export function isExternalObject(data: any): data is ExternalObject { return data[UNPATHED_ERRORS_SYMBOL] !== undefined; @@ -50,7 +51,7 @@ export function mergeExternalObjects( schema, variableValues: {}, fragments: {}, - } as GraphQLExecutionContext, + } as ExecutionContext, schema.getType(typeName) as GraphQLObjectType, selectionSet, Object.create(null), diff --git a/packages/delegate/src/getFieldsNotInSubschema.ts b/packages/delegate/src/getFieldsNotInSubschema.ts index 33a1678f7f1..24e74e1944f 100644 --- a/packages/delegate/src/getFieldsNotInSubschema.ts +++ b/packages/delegate/src/getFieldsNotInSubschema.ts @@ -1,10 +1,11 @@ import { GraphQLSchema, FieldNode, GraphQLObjectType, GraphQLResolveInfo } from 'graphql'; -import { collectFields, GraphQLExecutionContext, Maybe } from '@graphql-tools/utils'; +import { Maybe } from '@graphql-tools/utils'; import { isSubschemaConfig } from './subschemaConfig'; import { MergedTypeInfo, SubschemaConfig, StitchingInfo } from './types'; import { memoizeInfoAnd2Objects } from './memoize'; +import { collectFields, ExecutionContext } from 'graphql/execution/execute.js'; function collectSubFields(info: GraphQLResolveInfo, typeName: string): Record> { let subFieldNodes: Record> = Object.create(null); @@ -15,7 +16,7 @@ function collectSubFields(info: GraphQLResolveInfo, typeName: string): Record Maybe; @@ -74,7 +69,7 @@ function visitSelectionSets( schema, variableValues: variables, fragments, - } as GraphQLExecutionContext, + } as ExecutionContext, type, operation.selectionSet, Object.create(null), diff --git a/packages/delegate/src/types.ts b/packages/delegate/src/types.ts index 05933cfda1f..f4d43144f0e 100644 --- a/packages/delegate/src/types.ts +++ b/packages/delegate/src/types.ts @@ -14,10 +14,11 @@ import { import DataLoader from 'dataloader'; -import { ExecutionRequest, ExecutionResult, Executor, TypeMap } from '@graphql-tools/utils'; +import { ExecutionRequest, ExecutionResult, Executor } from '@graphql-tools/utils'; import { Subschema } from './Subschema'; import { OBJECT_SUBSCHEMA_SYMBOL, FIELD_SUBSCHEMA_MAP_SYMBOL, UNPATHED_ERRORS_SYMBOL } from './symbols'; +import { TypeMap } from 'graphql/type/schema'; export type SchemaTransform> = ( originalWrappingSchema: GraphQLSchema, diff --git a/packages/stitch/src/stitchingInfo.ts b/packages/stitch/src/stitchingInfo.ts index 8446cbb0a85..4370078c450 100644 --- a/packages/stitch/src/stitchingInfo.ts +++ b/packages/stitch/src/stitchingInfo.ts @@ -14,21 +14,15 @@ import { isUnionType, } from 'graphql'; -import { - parseSelectionSet, - TypeMap, - IResolvers, - IFieldResolverOptions, - isSome, - GraphQLExecutionContext, -} from '@graphql-tools/utils'; +import { parseSelectionSet, IResolvers, IFieldResolverOptions, isSome } from '@graphql-tools/utils'; import { MergedTypeResolver, Subschema, SubschemaConfig, MergedTypeInfo, StitchingInfo } from '@graphql-tools/delegate'; import { MergeTypeCandidate, MergeTypeFilter } from './types'; import { createMergedTypeResolver } from './createMergedTypeResolver'; -import { collectFields } from 'graphql/execution/execute'; +import { collectFields, ExecutionContext } from 'graphql/execution/execute.js'; +import { TypeMap } from 'graphql/type/schema'; export function createStitchingInfo>( subschemaMap: Map, Subschema>, @@ -260,7 +254,7 @@ export function completeStitchingInfo>( schema, variableValues: Object.create(null), fragments: Object.create(null), - }; + } as ExecutionContext; const fieldNodeMap = Object.create(null); @@ -269,7 +263,7 @@ export function completeStitchingInfo>( for (const fieldName in selectionSetsByField[typeName]) { for (const selectionSet of selectionSetsByField[typeName][fieldName]) { const fieldNodes = collectFields( - partialExecutionContext as GraphQLExecutionContext, + partialExecutionContext, type, selectionSet, Object.create(null), diff --git a/packages/stitch/src/typeCandidates.ts b/packages/stitch/src/typeCandidates.ts index 7bb1d75c470..e5d174939fe 100644 --- a/packages/stitch/src/typeCandidates.ts +++ b/packages/stitch/src/typeCandidates.ts @@ -15,13 +15,14 @@ import { import { wrapSchema } from '@graphql-tools/wrap'; import { Subschema, SubschemaConfig, StitchingInfo } from '@graphql-tools/delegate'; -import { GraphQLParseOptions, TypeSource, rewireTypes, TypeMap, getRootTypeMap } from '@graphql-tools/utils'; +import { GraphQLParseOptions, TypeSource, rewireTypes, getRootTypeMap } from '@graphql-tools/utils'; import typeFromAST from './typeFromAST'; import { MergeTypeCandidate, MergeTypeFilter, OnTypeConflict, TypeMergingOptions } from './types'; import { mergeCandidates } from './mergeCandidates'; import { extractDefinitions } from './definitions'; import { mergeTypeDefs } from '@graphql-tools/merge'; +import { TypeMap } from 'graphql/type/schema'; type CandidateSelector> = ( candidates: Array> diff --git a/packages/utils/src/Interfaces.ts b/packages/utils/src/Interfaces.ts index 5dde9a8d595..147a6716b86 100644 --- a/packages/utils/src/Interfaces.ts +++ b/packages/utils/src/Interfaces.ts @@ -3,7 +3,6 @@ import { GraphQLField, GraphQLInputType, GraphQLNamedType, - GraphQLFieldResolver, GraphQLResolveInfo, GraphQLScalarType, DocumentNode, @@ -19,8 +18,6 @@ import { GraphQLDirective, FragmentDefinitionNode, SelectionNode, - OperationDefinitionNode, - GraphQLError, ExecutionResult as GraphQLExecutionResult, GraphQLOutputType, FieldDefinitionNode, @@ -79,19 +76,6 @@ export interface ExecutionRequest< // graphql-js non-exported typings -export type TypeMap = Record; - -export interface GraphQLExecutionContext { - schema: GraphQLSchema; - fragments: Record; - rootValue: any; - contextValue: any; - operation: OperationDefinitionNode; - variableValues: Record; - fieldResolver: GraphQLFieldResolver; - errors: Array; -} - export interface GraphQLParseOptions { noLocation?: boolean; allowLegacySDLEmptyFields?: boolean; diff --git a/packages/utils/src/collectFields.ts b/packages/utils/src/collectFields.ts deleted file mode 100644 index 120121c3d32..00000000000 --- a/packages/utils/src/collectFields.ts +++ /dev/null @@ -1,127 +0,0 @@ -import { - GraphQLObjectType, - SelectionSetNode, - FieldNode, - Kind, - FragmentSpreadNode, - InlineFragmentNode, - getDirectiveValues, - GraphQLSkipDirective, - GraphQLIncludeDirective, - FragmentDefinitionNode, - typeFromAST, - isAbstractType, -} from 'graphql'; - -import { GraphQLExecutionContext } from './Interfaces'; - -/** - * Given a selectionSet, adds all of the fields in that selection to - * the passed in map of fields, and returns it at the end. - * - * CollectFields requires the "runtime type" of an object. For a field which - * returns an Interface or Union type, the "runtime type" will be the actual - * Object type returned by that field. - * - * @internal - */ -export function collectFields( - exeContext: GraphQLExecutionContext, - runtimeType: GraphQLObjectType, - selectionSet: SelectionSetNode, - fields: Record>, - visitedFragmentNames: Record -): Record> { - for (const selection of selectionSet.selections) { - switch (selection.kind) { - case Kind.FIELD: { - if (!shouldIncludeNode(exeContext, selection)) { - continue; - } - const name = getFieldEntryKey(selection); - if (!(name in fields)) { - fields[name] = []; - } - fields[name].push(selection); - break; - } - case Kind.INLINE_FRAGMENT: { - if ( - !shouldIncludeNode(exeContext, selection) || - !doesFragmentConditionMatch(exeContext, selection, runtimeType) - ) { - continue; - } - collectFields(exeContext, runtimeType, selection.selectionSet, fields, visitedFragmentNames); - break; - } - case Kind.FRAGMENT_SPREAD: { - const fragName = selection.name.value; - if (visitedFragmentNames[fragName] || !shouldIncludeNode(exeContext, selection)) { - continue; - } - visitedFragmentNames[fragName] = true; - const fragment = exeContext.fragments[fragName]; - if (!fragment || !doesFragmentConditionMatch(exeContext, fragment, runtimeType)) { - continue; - } - collectFields(exeContext, runtimeType, fragment.selectionSet, fields, visitedFragmentNames); - break; - } - } - } - return fields; -} - -/** - * Determines if a field should be included based on the @include and @skip - * directives, where @skip has higher precedence than @include. - */ -function shouldIncludeNode( - exeContext: GraphQLExecutionContext, - node: FragmentSpreadNode | FieldNode | InlineFragmentNode -): boolean { - const skip = getDirectiveValues(GraphQLSkipDirective, node, exeContext.variableValues); - - if (skip?.['if'] === true) { - return false; - } - - const include = getDirectiveValues(GraphQLIncludeDirective, node, exeContext.variableValues); - - if (include?.['if'] === false) { - return false; - } - - return true; -} - -/** - * Determines if a fragment is applicable to the given type. - */ -function doesFragmentConditionMatch( - exeContext: GraphQLExecutionContext, - fragment: FragmentDefinitionNode | InlineFragmentNode, - type: GraphQLObjectType -): boolean { - const typeConditionNode = fragment.typeCondition; - if (!typeConditionNode) { - return true; - } - const conditionalType = typeFromAST(exeContext.schema, typeConditionNode); - if (conditionalType === type) { - return true; - } - if (isAbstractType(conditionalType)) { - return exeContext.schema.isPossibleType(conditionalType, type); - } - return false; -} - -/** - * Implements the logic to compute the key of a given field's entry - */ -function getFieldEntryKey(node: FieldNode): string { - // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition - return node.alias ? node.alias.value : node.name.value; -} diff --git a/packages/utils/src/heal.ts b/packages/utils/src/heal.ts index f0dd92fc8b3..be498e61467 100644 --- a/packages/utils/src/heal.ts +++ b/packages/utils/src/heal.ts @@ -20,8 +20,7 @@ import { isListType, isNonNullType, } from 'graphql'; - -import { TypeMap } from './Interfaces'; +import { TypeMap } from 'graphql/type/schema'; // Update any references to named schema types that disagree with the named // types found in schema.getTypeMap(). diff --git a/packages/utils/src/index.ts b/packages/utils/src/index.ts index bc3f4a892c7..ca51324521c 100644 --- a/packages/utils/src/index.ts +++ b/packages/utils/src/index.ts @@ -30,7 +30,6 @@ export * from './selectionSets'; export * from './getResponseKeyFromInfo'; export * from './fields'; export * from './renameType'; -export * from './collectFields'; export * from './transformInputValue'; export * from './mapAsyncIterator'; export * from './updateArgument'; diff --git a/packages/utils/src/mapSchema.ts b/packages/utils/src/mapSchema.ts index 245728272e8..50d4277c1ae 100644 --- a/packages/utils/src/mapSchema.ts +++ b/packages/utils/src/mapSchema.ts @@ -29,13 +29,13 @@ import { Kind, EnumValueDefinitionNode, } from 'graphql'; +import { TypeMap } from 'graphql/type/schema'; import { getObjectTypeFromTypeMap } from './getObjectTypeFromTypeMap'; import { SchemaMapper, MapperKind, - TypeMap, NamedTypeMapper, DirectiveMapper, GenericFieldMapper, diff --git a/packages/utils/src/rewire.ts b/packages/utils/src/rewire.ts index 45e6639d688..21554159371 100644 --- a/packages/utils/src/rewire.ts +++ b/packages/utils/src/rewire.ts @@ -25,9 +25,9 @@ import { isSpecifiedScalarType, isSpecifiedDirective, } from 'graphql'; +import { TypeMap } from 'graphql/type/schema'; import { getBuiltInForStub, isNamedStub } from './stub'; -import { TypeMap } from './Interfaces'; export function rewireTypes( originalTypeMap: Record, diff --git a/packages/utils/src/visitResult.ts b/packages/utils/src/visitResult.ts index dad14ecbc18..be89d6ed0f6 100644 --- a/packages/utils/src/visitResult.ts +++ b/packages/utils/src/visitResult.ts @@ -15,8 +15,8 @@ import { TypeNameMetaFieldDef, } from 'graphql'; -import { ExecutionRequest, GraphQLExecutionContext, ExecutionResult } from './Interfaces'; -import { collectFields } from './collectFields'; +import { ExecutionRequest, ExecutionResult } from './Interfaces'; +import { collectFields, ExecutionContext } from 'graphql/execution/execute.js'; import { Maybe } from '@graphql-tools/utils'; export type ValueVisitor = (value: any) => any; @@ -91,7 +91,7 @@ export function visitResult( return acc; }, {}), variableValues: request.variables, - } as GraphQLExecutionContext; + } as ExecutionContext; const errorInfo: ErrorInfo = { segmentInfoMap: new Map>(), @@ -157,7 +157,7 @@ function visitErrorsByType( function visitRoot( root: any, operation: OperationDefinitionNode, - exeContext: GraphQLExecutionContext, + exeContext: ExecutionContext, resultVisitorMap: Maybe, errors: Maybe>, errorInfo: ErrorInfo @@ -178,7 +178,7 @@ function visitObjectValue( object: Record, type: GraphQLObjectType, fieldNodeMap: Record>, - exeContext: GraphQLExecutionContext, + exeContext: ExecutionContext, resultVisitorMap: Maybe, pathIndex: number, errors: Maybe>, @@ -279,7 +279,7 @@ function visitListValue( list: Array, returnType: GraphQLOutputType, fieldNodes: Array, - exeContext: GraphQLExecutionContext, + exeContext: ExecutionContext, resultVisitorMap: Maybe, pathIndex: number, errors: ReadonlyArray, @@ -294,7 +294,7 @@ function visitFieldValue( value: any, returnType: GraphQLOutputType, fieldNodes: Array, - exeContext: GraphQLExecutionContext, + exeContext: ExecutionContext, resultVisitorMap: Maybe, pathIndex: number, errors: ReadonlyArray | undefined = [], @@ -398,7 +398,7 @@ function addPathSegmentInfo( } function collectSubFields( - exeContext: GraphQLExecutionContext, + exeContext: ExecutionContext, type: GraphQLObjectType, fieldNodes: Array ): Record> { diff --git a/packages/wrap/src/generateProxyingResolvers.ts b/packages/wrap/src/generateProxyingResolvers.ts index aafe5f38625..cc121d8662b 100644 --- a/packages/wrap/src/generateProxyingResolvers.ts +++ b/packages/wrap/src/generateProxyingResolvers.ts @@ -1,4 +1,4 @@ -import { GraphQLFieldResolver, GraphQLResolveInfo } from 'graphql'; +import { GraphQLFieldResolver } from 'graphql'; import { getResponseKeyFromInfo, getRootTypeMap } from '@graphql-tools/utils'; import { @@ -41,8 +41,7 @@ export function generateProxyingResolvers( if (operation === 'subscription') { resolvers[typeName][fieldName] = { subscribe: finalResolver, - resolve: (payload: any, _: never, __: never, { fieldName: targetFieldName }: GraphQLResolveInfo) => - payload[targetFieldName], + resolve: identical, }; } else { resolvers[typeName][fieldName] = { @@ -55,11 +54,15 @@ export function generateProxyingResolvers( return resolvers; } +function identical(value: T): T { + return value; +} + function createPossiblyNestedProxyingResolver( subschemaConfig: SubschemaConfig, proxyingResolver: GraphQLFieldResolver ): GraphQLFieldResolver { - return (parent, args, context, info) => { + return function possiblyNestedProxyingResolver(parent, args, context, info) { if (parent != null) { const responseKey = getResponseKeyFromInfo(info); @@ -86,12 +89,13 @@ export function defaultCreateProxyingResolver({ operation, transformedSchema, }: ICreateProxyingResolverOptions): GraphQLFieldResolver { - return (_parent, _args, context, info) => - delegateToSchema({ + return function proxyingResolver(_parent, _args, context, info) { + return delegateToSchema({ schema: subschemaConfig, operation, context, info, transformedSchema, }); + }; } From 7d962a53f509d273ffc7365380801cda2586f4b8 Mon Sep 17 00:00:00 2001 From: Arda TANRIKULU Date: Wed, 14 Jul 2021 03:09:37 +0300 Subject: [PATCH 65/66] Update call.js --- benchmark/federation/call.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/benchmark/federation/call.js b/benchmark/federation/call.js index 42ed37ff2be..7e9fe6e32e9 100644 --- a/benchmark/federation/call.js +++ b/benchmark/federation/call.js @@ -1,6 +1,6 @@ const fetch = require('cross-fetch'); -fetch('http://localhost:3000/monolith', { +fetch('http://localhost:3000/stitching', { method: 'POST', headers: { 'content-type': 'application/json' From 9c26b847838a9b5357dfcfb9015e7c6558f0ef89 Mon Sep 17 00:00:00 2001 From: Arda TANRIKULU Date: Wed, 14 Jul 2021 03:13:36 +0300 Subject: [PATCH 66/66] enhance(loaders): remove optional methods from the Loader interface --- .changeset/cool-onions-wink.md | 5 ++++ packages/loaders/apollo-engine/src/index.ts | 4 --- packages/loaders/code-file/src/index.ts | 4 --- packages/loaders/git/src/index.ts | 4 --- packages/loaders/git/tests/loader.spec.ts | 6 ---- packages/loaders/github/src/index.ts | 4 --- packages/loaders/graphql-file/src/index.ts | 4 --- .../loaders/graphql-file/tests/loader.spec.ts | 6 ---- packages/loaders/json-file/src/index.ts | 4 --- .../loaders/json-file/tests/loader.spec.ts | 6 ---- packages/loaders/module/src/index.ts | 4 --- packages/loaders/module/tests/loader.spec.ts | 6 ---- packages/loaders/prisma/src/index.ts | 4 --- packages/loaders/url/src/index.ts | 4 --- packages/utils/src/loaders.ts | 3 -- yarn.lock | 28 +++++++++---------- 16 files changed, 19 insertions(+), 77 deletions(-) create mode 100644 .changeset/cool-onions-wink.md diff --git a/.changeset/cool-onions-wink.md b/.changeset/cool-onions-wink.md new file mode 100644 index 00000000000..61e905e26ad --- /dev/null +++ b/.changeset/cool-onions-wink.md @@ -0,0 +1,5 @@ +--- +'@graphql-tools/utils': minor +--- + +enhance(loaders): remove optional methods from the Loader interface diff --git a/packages/loaders/apollo-engine/src/index.ts b/packages/loaders/apollo-engine/src/index.ts index 21b3340b3ed..03a66398062 100644 --- a/packages/loaders/apollo-engine/src/index.ts +++ b/packages/loaders/apollo-engine/src/index.ts @@ -21,10 +21,6 @@ const DEFAULT_APOLLO_ENDPOINT = 'https://engine-graphql.apollographql.com/api/gr * This loader loads a schema from Apollo Engine */ export class ApolloEngineLoader implements Loader { - loaderId() { - return 'apollo-engine'; - } - private getFetchArgs(options: ApolloEngineOptions): [string, RequestInit] { return [ options.engine.endpoint || DEFAULT_APOLLO_ENDPOINT, diff --git a/packages/loaders/code-file/src/index.ts b/packages/loaders/code-file/src/index.ts index e943c9c57ed..42b702f9cc5 100644 --- a/packages/loaders/code-file/src/index.ts +++ b/packages/loaders/code-file/src/index.ts @@ -70,10 +70,6 @@ export class CodeFileLoader implements Loader { return { ...this.config, ...options }; } - loaderId(): string { - return 'code-file'; - } - async canLoad(pointer: string, options: CodeFileLoaderOptions): Promise { options = this.getMergedOptions(options); diff --git a/packages/loaders/git/src/index.ts b/packages/loaders/git/src/index.ts index e94607d630c..45323de54e9 100644 --- a/packages/loaders/git/src/index.ts +++ b/packages/loaders/git/src/index.ts @@ -49,10 +49,6 @@ export type GitLoaderOptions = BaseLoaderOptions & { * ``` */ export class GitLoader implements Loader { - loaderId() { - return 'git-loader'; - } - async canLoad(pointer: string) { return this.canLoadSync(pointer); } diff --git a/packages/loaders/git/tests/loader.spec.ts b/packages/loaders/git/tests/loader.spec.ts index 8c3e7d85a9e..e4521bc8a77 100644 --- a/packages/loaders/git/tests/loader.spec.ts +++ b/packages/loaders/git/tests/loader.spec.ts @@ -10,12 +10,6 @@ describe('GitLoader', () => { return `git:${lastCommit}:packages/loaders/git/tests/test-files/${fileName}`; }; - describe('loaderId', () => { - it('should return a loader id', () => { - expect(loader.loaderId()).toBeDefined(); - }); - }); - describe('canLoad', () => { runTests({ async: loader.canLoad.bind(loader), diff --git a/packages/loaders/github/src/index.ts b/packages/loaders/github/src/index.ts index f72ad9210a3..9e16a01bde6 100644 --- a/packages/loaders/github/src/index.ts +++ b/packages/loaders/github/src/index.ts @@ -47,10 +47,6 @@ export interface GithubLoaderOptions extends BaseLoaderOptions { * ``` */ export class GithubLoader implements Loader { - loaderId() { - return 'github-loader'; - } - async canLoad(pointer: string) { return typeof pointer === 'string' && pointer.toLowerCase().startsWith('github:'); } diff --git a/packages/loaders/graphql-file/src/index.ts b/packages/loaders/graphql-file/src/index.ts index e851a1b1c0c..00d092718f8 100644 --- a/packages/loaders/graphql-file/src/index.ts +++ b/packages/loaders/graphql-file/src/index.ts @@ -55,10 +55,6 @@ function createGlobbyOptions(options: GraphQLFileLoaderOptions): GlobbyOptions { * ``` */ export class GraphQLFileLoader implements Loader { - loaderId(): string { - return 'graphql-file'; - } - async canLoad(pointer: string, options: GraphQLFileLoaderOptions): Promise { if (isValidPath(pointer)) { if (FILE_EXTENSIONS.find(extension => pointer.endsWith(extension))) { diff --git a/packages/loaders/graphql-file/tests/loader.spec.ts b/packages/loaders/graphql-file/tests/loader.spec.ts index 05069ddc290..318809fb36d 100644 --- a/packages/loaders/graphql-file/tests/loader.spec.ts +++ b/packages/loaders/graphql-file/tests/loader.spec.ts @@ -12,12 +12,6 @@ describe('GraphQLFileLoader', () => { return join('packages/loaders/graphql-file/tests/test-files', fileName); }; - describe('loaderId', () => { - it('should return a loader id', () => { - expect(loader.loaderId()).toBeDefined(); - }); - }); - describe('canLoad', () => { runTests({ async: loader.canLoad.bind(loader), diff --git a/packages/loaders/json-file/src/index.ts b/packages/loaders/json-file/src/index.ts index f451ec83c83..aef595fe62b 100644 --- a/packages/loaders/json-file/src/index.ts +++ b/packages/loaders/json-file/src/index.ts @@ -36,10 +36,6 @@ export interface JsonFileLoaderOptions extends BaseLoaderOptions {} * ``` */ export class JsonFileLoader implements Loader { - loaderId(): string { - return 'json-file'; - } - async canLoad(pointer: string, options: JsonFileLoaderOptions): Promise { if (isValidPath(pointer)) { if (FILE_EXTENSIONS.find(extension => pointer.endsWith(extension))) { diff --git a/packages/loaders/json-file/tests/loader.spec.ts b/packages/loaders/json-file/tests/loader.spec.ts index 50f3887fd41..1495b115cb3 100644 --- a/packages/loaders/json-file/tests/loader.spec.ts +++ b/packages/loaders/json-file/tests/loader.spec.ts @@ -9,12 +9,6 @@ describe('JsonFileLoader', () => { return join('packages/loaders/json-file/tests/test-files', fileName); }; - describe('loaderId', () => { - it('should return a loader id', () => { - expect(loader.loaderId()).toBeDefined(); - }); - }); - describe('canLoad', () => { runTests({ async: loader.canLoad.bind(loader), diff --git a/packages/loaders/module/src/index.ts b/packages/loaders/module/src/index.ts index db7840a5770..73abae15d89 100644 --- a/packages/loaders/module/src/index.ts +++ b/packages/loaders/module/src/index.ts @@ -35,10 +35,6 @@ function extractData(pointer: string): { * ``` */ export class ModuleLoader implements Loader { - loaderId() { - return 'module-loader'; - } - private isExpressionValid(pointer: string) { return typeof pointer === 'string' && pointer.toLowerCase().startsWith('module:'); } diff --git a/packages/loaders/module/tests/loader.spec.ts b/packages/loaders/module/tests/loader.spec.ts index 220af74d42f..077b3db1a52 100644 --- a/packages/loaders/module/tests/loader.spec.ts +++ b/packages/loaders/module/tests/loader.spec.ts @@ -10,12 +10,6 @@ describe('ModuleLoader', () => { return `module:${absolutePath}${exportName ? `#${exportName}` : ''}`; }; - describe('loaderId', () => { - it('should return a loader id', () => { - expect(loader.loaderId()).toBeDefined(); - }); - }); - describe('canLoad', () => { runTests({ async: loader.canLoad.bind(loader), diff --git a/packages/loaders/prisma/src/index.ts b/packages/loaders/prisma/src/index.ts index 14e6ab025c1..7b6c68e4a95 100644 --- a/packages/loaders/prisma/src/index.ts +++ b/packages/loaders/prisma/src/index.ts @@ -20,10 +20,6 @@ export interface PrismaLoaderOptions extends LoadFromUrlOptions { * This loader loads a schema from a `prisma.yml` file */ export class PrismaLoader extends UrlLoader { - loaderId() { - return 'prisma'; - } - canLoadSync() { return false; } diff --git a/packages/loaders/url/src/index.ts b/packages/loaders/url/src/index.ts index 116915812c6..ef29e22c07f 100644 --- a/packages/loaders/url/src/index.ts +++ b/packages/loaders/url/src/index.ts @@ -163,10 +163,6 @@ const isCompatibleUri = (uri: string): boolean => { * ``` */ export class UrlLoader implements Loader { - loaderId(): string { - return 'url'; - } - async canLoad(pointer: string, options: LoadFromUrlOptions): Promise { return this.canLoadSync(pointer, options); } diff --git a/packages/utils/src/loaders.ts b/packages/utils/src/loaders.ts index 73b1d6fac24..9c6a88d15d4 100644 --- a/packages/utils/src/loaders.ts +++ b/packages/utils/src/loaders.ts @@ -18,9 +18,6 @@ export type WithList = T | T[]; export type ElementOf = TList extends Array ? TElement : never; export interface Loader { - loaderId(): string; - canLoad(pointer: string, options?: TOptions): Promise; - canLoadSync?(pointer: string, options?: TOptions): boolean; load(pointer: string, options?: TOptions): Promise; loadSync?(pointer: string, options?: TOptions): Source[] | null | never; } diff --git a/yarn.lock b/yarn.lock index f1beecbfa22..70e2bc5df86 100644 --- a/yarn.lock +++ b/yarn.lock @@ -144,21 +144,21 @@ tslib "^1.10.0" zen-observable "^0.8.14" -"@apollo/federation@0.25.2", "@apollo/federation@^0.25.2": - version "0.25.2" - resolved "https://registry.yarnpkg.com/@apollo/federation/-/federation-0.25.2.tgz#10b2e22ac20e64701fd6d31d9abbf7f411b03763" - integrity sha512-TrRCrGniHpnRwALm2J7q2c1X4Lcc95e7SeHkVjascaQx6nBZGFbBXadw8rOPxlw5syfxYf8h9winF+wwld+gsg== +"@apollo/federation@0.26.0", "@apollo/federation@^0.26.0": + version "0.26.0" + resolved "https://registry.yarnpkg.com/@apollo/federation/-/federation-0.26.0.tgz#72c89f01995bd2e066d447fed4aa58678d759bf6" + integrity sha512-j3l6lhQod630LQzLm2hhDyQQJtQikT7vRtRgIa3PuKEq6ouuOd1OQERhBnecobJlUfRWJkfvjYJ/PhQZ2sm/7Q== dependencies: apollo-graphql "^0.9.3" lodash.xorby "^4.7.0" -"@apollo/gateway@0.32.0": - version "0.32.0" - resolved "https://registry.yarnpkg.com/@apollo/gateway/-/gateway-0.32.0.tgz#639b7b826c76a2bffdf777902010485dfd981918" - integrity sha512-Pxq3VVxG1ALrFNN8SM3RVy6Kwm+5p1KG3ObVmQX720Wx5WpRKvCRC23J/c3oFRpsGqjPOglh3vmpAQVdJJTCZA== +"@apollo/gateway@0.33.0": + version "0.33.0" + resolved "https://registry.yarnpkg.com/@apollo/gateway/-/gateway-0.33.0.tgz#6e282fb88eb86d9ab9ae35d6d5d3e174085a6907" + integrity sha512-NQTFysgRzPYR8g90K43/hgH+Rxe7F/E2G2Linfc81VVNk5NruRSUeQV0EnsROC7lLbCqiCJ+WSQcN0ZaR2Jo7A== dependencies: - "@apollo/federation" "^0.25.2" - "@apollo/query-planner" "^0.2.2" + "@apollo/federation" "^0.26.0" + "@apollo/query-planner" "^0.2.3" "@opentelemetry/api" "^1.0.1" "@types/node-fetch" "2.5.10" apollo-graphql "^0.9.3" @@ -191,10 +191,10 @@ "@types/node" "^10.1.0" long "^4.0.0" -"@apollo/query-planner@^0.2.2": - version "0.2.2" - resolved "https://registry.yarnpkg.com/@apollo/query-planner/-/query-planner-0.2.2.tgz#5397e5cd8a73dede34c485fb0c5fefa054f9153a" - integrity sha512-+RZSKY0xDYki9qwlzKXDNa+jrbj0Qstq44lcB21aViiDdEJWOTwf7Cqg3h/hN7QsUnL75XiDrwsjMLnwFdHSoQ== +"@apollo/query-planner@^0.2.3": + version "0.2.3" + resolved "https://registry.yarnpkg.com/@apollo/query-planner/-/query-planner-0.2.3.tgz#8018ae12c24541838541cc7b20d6a628556918e5" + integrity sha512-3jYHLhuUTolAouVTkR1NrGH7ZQzj91KfH1L1Ddd2i2hfCG6VDj9xuRe+nznYV1Sk3/Uy226d7BPKo110H/3Pow== dependencies: chalk "^4.1.0" deep-equal "^2.0.5"