@graphql-tools/batch-execute 9.0.6 → 9.0.7-alpha-63d80f9d08b5d8448f4bfb8b04aeff28b977dec8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,62 +1,51 @@
1
1
  {
2
2
  "name": "@graphql-tools/batch-execute",
3
- "version": "9.0.6",
3
+ "version": "9.0.7-alpha-63d80f9d08b5d8448f4bfb8b04aeff28b977dec8",
4
+ "type": "module",
4
5
  "description": "A set of utils for faster development of GraphQL tools",
5
- "sideEffects": false,
6
- "peerDependencies": {
7
- "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0"
8
- },
9
- "dependencies": {
10
- "@graphql-tools/utils": "^10.5.6",
11
- "dataloader": "^2.2.2",
12
- "tslib": "^2.4.0",
13
- "value-or-promise": "^1.0.12"
14
- },
15
6
  "repository": {
16
7
  "type": "git",
17
- "url": "ardatan/graphql-tools",
8
+ "url": "graphql-hive/gateway",
18
9
  "directory": "packages/batch-execute"
19
10
  },
20
11
  "license": "MIT",
21
12
  "engines": {
22
- "node": ">=16.0.0"
23
- },
24
- "main": "cjs/index.js",
25
- "module": "esm/index.js",
26
- "typings": "typings/index.d.ts",
27
- "typescript": {
28
- "definition": "typings/index.d.ts"
13
+ "node": ">=18.0.0"
29
14
  },
30
- "type": "module",
15
+ "main": "./dist/index.js",
31
16
  "exports": {
32
17
  ".": {
33
18
  "require": {
34
- "types": "./typings/index.d.cts",
35
- "default": "./cjs/index.js"
19
+ "types": "./dist/index.d.cts",
20
+ "default": "./dist/index.cjs"
36
21
  },
37
22
  "import": {
38
- "types": "./typings/index.d.ts",
39
- "default": "./esm/index.js"
40
- },
41
- "default": {
42
- "types": "./typings/index.d.ts",
43
- "default": "./esm/index.js"
44
- }
45
- },
46
- "./*": {
47
- "require": {
48
- "types": "./typings/*.d.cts",
49
- "default": "./cjs/*.js"
50
- },
51
- "import": {
52
- "types": "./typings/*.d.ts",
53
- "default": "./esm/*.js"
54
- },
55
- "default": {
56
- "types": "./typings/*.d.ts",
57
- "default": "./esm/*.js"
23
+ "types": "./dist/index.d.ts",
24
+ "default": "./dist/index.js"
58
25
  }
59
26
  },
60
27
  "./package.json": "./package.json"
61
- }
28
+ },
29
+ "types": "./dist/index.d.ts",
30
+ "files": [
31
+ "dist"
32
+ ],
33
+ "scripts": {
34
+ "build": "pkgroll --clean-dist",
35
+ "prepack": "yarn build"
36
+ },
37
+ "peerDependencies": {
38
+ "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0"
39
+ },
40
+ "dependencies": {
41
+ "@graphql-tools/utils": "^10.6.0",
42
+ "dataloader": "^2.2.2",
43
+ "tslib": "^2.4.0",
44
+ "value-or-promise": "^1.0.12"
45
+ },
46
+ "devDependencies": {
47
+ "graphql": "^16.9.0",
48
+ "pkgroll": "2.5.1"
49
+ },
50
+ "sideEffects": false
62
51
  }
@@ -1,51 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.createBatchingExecutor = void 0;
4
- const tslib_1 = require("tslib");
5
- const dataloader_1 = tslib_1.__importDefault(require("dataloader"));
6
- const value_or_promise_1 = require("value-or-promise");
7
- const utils_1 = require("@graphql-tools/utils");
8
- const mergeRequests_js_1 = require("./mergeRequests.js");
9
- const splitResult_js_1 = require("./splitResult.js");
10
- function createBatchingExecutor(executor, dataLoaderOptions, extensionsReducer = defaultExtensionsReducer) {
11
- const loadFn = createLoadFn(executor, extensionsReducer);
12
- const queryLoader = new dataloader_1.default(loadFn, dataLoaderOptions);
13
- const mutationLoader = new dataloader_1.default(loadFn, dataLoaderOptions);
14
- return function batchingExecutor(request) {
15
- const operationType = request.operationType ?? (0, utils_1.getOperationASTFromRequest)(request)?.operation;
16
- switch (operationType) {
17
- case 'query':
18
- return queryLoader.load(request);
19
- case 'mutation':
20
- return mutationLoader.load(request);
21
- case 'subscription':
22
- return executor(request);
23
- default:
24
- throw new Error(`Invalid operation type "${operationType}"`);
25
- }
26
- };
27
- }
28
- exports.createBatchingExecutor = createBatchingExecutor;
29
- function createLoadFn(executor, extensionsReducer) {
30
- return function batchExecuteLoadFn(requests) {
31
- if (requests.length === 1) {
32
- return new value_or_promise_1.ValueOrPromise(() => executor(requests[0]))
33
- .then((result) => [result])
34
- .catch((err) => [err]);
35
- }
36
- const mergedRequests = (0, mergeRequests_js_1.mergeRequests)(requests, extensionsReducer);
37
- return new value_or_promise_1.ValueOrPromise(() => executor(mergedRequests)).then(resultBatches => {
38
- if ((0, utils_1.isAsyncIterable)(resultBatches)) {
39
- throw new Error('Executor must not return incremental results for batching');
40
- }
41
- return (0, splitResult_js_1.splitResult)(resultBatches, requests.length);
42
- });
43
- };
44
- }
45
- function defaultExtensionsReducer(mergedExtensions, request) {
46
- const newExtensions = request.extensions;
47
- if (newExtensions != null) {
48
- Object.assign(mergedExtensions, newExtensions);
49
- }
50
- return mergedExtensions;
51
- }
@@ -1,8 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getBatchingExecutor = void 0;
4
- const utils_1 = require("@graphql-tools/utils");
5
- const createBatchingExecutor_js_1 = require("./createBatchingExecutor.js");
6
- exports.getBatchingExecutor = (0, utils_1.memoize2of4)(function getBatchingExecutor(_context, executor, dataLoaderOptions, extensionsReducer) {
7
- return (0, createBatchingExecutor_js_1.createBatchingExecutor)(executor, dataLoaderOptions, extensionsReducer);
8
- });
package/cjs/index.js DELETED
@@ -1,5 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const tslib_1 = require("tslib");
4
- tslib_1.__exportStar(require("./createBatchingExecutor.js"), exports);
5
- tslib_1.__exportStar(require("./getBatchingExecutor.js"), exports);
@@ -1,264 +0,0 @@
1
- "use strict";
2
- // adapted from https://github.com/gatsbyjs/gatsby/blob/master/packages/gatsby-source-graphql/src/batching/merge-queries.js
3
- Object.defineProperty(exports, "__esModule", { value: true });
4
- exports.mergeRequests = void 0;
5
- const graphql_1 = require("graphql");
6
- const utils_1 = require("@graphql-tools/utils");
7
- const prefix_js_1 = require("./prefix.js");
8
- /**
9
- * Merge multiple queries into a single query in such a way that query results
10
- * can be split and transformed as if they were obtained by running original queries.
11
- *
12
- * Merging algorithm involves several transformations:
13
- * 1. Replace top-level fragment spreads with inline fragments (... on Query {})
14
- * 2. Add unique aliases to all top-level query fields (including those on inline fragments)
15
- * 3. Prefix all variable definitions and variable usages
16
- * 4. Prefix names (and spreads) of fragments
17
- *
18
- * i.e transform:
19
- * [
20
- * `query Foo($id: ID!) { foo, bar(id: $id), ...FooQuery }
21
- * fragment FooQuery on Query { baz }`,
22
- *
23
- * `query Bar($id: ID!) { foo: baz, bar(id: $id), ... on Query { baz } }`
24
- * ]
25
- * to:
26
- * query (
27
- * $graphqlTools1_id: ID!
28
- * $graphqlTools2_id: ID!
29
- * ) {
30
- * graphqlTools1_foo: foo,
31
- * graphqlTools1_bar: bar(id: $graphqlTools1_id)
32
- * ... on Query {
33
- * graphqlTools1__baz: baz
34
- * }
35
- * graphqlTools1__foo: baz
36
- * graphqlTools1__bar: bar(id: $graphqlTools1__id)
37
- * ... on Query {
38
- * graphqlTools1__baz: baz
39
- * }
40
- * }
41
- */
42
- function mergeRequests(requests, extensionsReducer) {
43
- const mergedVariables = Object.create(null);
44
- const mergedVariableDefinitions = [];
45
- const mergedSelections = [];
46
- const mergedFragmentDefinitions = [];
47
- let mergedExtensions = Object.create(null);
48
- for (let index = 0; index < requests.length; index++) {
49
- const request = requests[index];
50
- const prefixedRequests = prefixRequest((0, prefix_js_1.createPrefix)(index), request);
51
- for (const def of prefixedRequests.document.definitions) {
52
- if (isOperationDefinition(def)) {
53
- mergedSelections.push(...def.selectionSet.selections);
54
- if (def.variableDefinitions) {
55
- mergedVariableDefinitions.push(...def.variableDefinitions);
56
- }
57
- }
58
- if (isFragmentDefinition(def)) {
59
- mergedFragmentDefinitions.push(def);
60
- }
61
- }
62
- Object.assign(mergedVariables, prefixedRequests.variables);
63
- mergedExtensions = extensionsReducer(mergedExtensions, request);
64
- }
65
- const firstRequest = requests[0];
66
- const operationType = firstRequest.operationType ?? (0, utils_1.getOperationASTFromRequest)(firstRequest).operation;
67
- const mergedOperationDefinition = {
68
- kind: graphql_1.Kind.OPERATION_DEFINITION,
69
- operation: operationType,
70
- variableDefinitions: mergedVariableDefinitions,
71
- selectionSet: {
72
- kind: graphql_1.Kind.SELECTION_SET,
73
- selections: mergedSelections,
74
- },
75
- };
76
- const operationName = firstRequest.operationName ?? firstRequest.info?.operation?.name?.value;
77
- if (operationName) {
78
- mergedOperationDefinition.name = {
79
- kind: graphql_1.Kind.NAME,
80
- value: operationName,
81
- };
82
- }
83
- return {
84
- document: {
85
- kind: graphql_1.Kind.DOCUMENT,
86
- definitions: [mergedOperationDefinition, ...mergedFragmentDefinitions],
87
- },
88
- variables: mergedVariables,
89
- extensions: mergedExtensions,
90
- context: requests[0].context,
91
- info: requests[0].info,
92
- operationType,
93
- rootValue: requests[0].rootValue,
94
- };
95
- }
96
- exports.mergeRequests = mergeRequests;
97
- function prefixRequest(prefix, request) {
98
- const executionVariables = request.variables ?? {};
99
- function prefixNode(node) {
100
- return prefixNodeName(node, prefix);
101
- }
102
- let prefixedDocument = aliasTopLevelFields(prefix, request.document);
103
- const executionVariableNames = Object.keys(executionVariables);
104
- const hasFragmentDefinitions = request.document.definitions.some(def => isFragmentDefinition(def));
105
- const fragmentSpreadImpl = {};
106
- if (executionVariableNames.length > 0 || hasFragmentDefinitions) {
107
- prefixedDocument = (0, graphql_1.visit)(prefixedDocument, {
108
- [graphql_1.Kind.VARIABLE]: prefixNode,
109
- [graphql_1.Kind.FRAGMENT_DEFINITION]: prefixNode,
110
- [graphql_1.Kind.FRAGMENT_SPREAD]: node => {
111
- node = prefixNodeName(node, prefix);
112
- fragmentSpreadImpl[node.name.value] = true;
113
- return node;
114
- },
115
- });
116
- }
117
- const prefixedVariables = {};
118
- for (const variableName of executionVariableNames) {
119
- prefixedVariables[prefix + variableName] = executionVariables[variableName];
120
- }
121
- if (hasFragmentDefinitions) {
122
- prefixedDocument = {
123
- ...prefixedDocument,
124
- definitions: prefixedDocument.definitions.filter(def => {
125
- return !isFragmentDefinition(def) || fragmentSpreadImpl[def.name.value];
126
- }),
127
- };
128
- }
129
- return {
130
- document: prefixedDocument,
131
- variables: prefixedVariables,
132
- };
133
- }
134
- /**
135
- * Adds prefixed aliases to top-level fields of the query.
136
- *
137
- * @see aliasFieldsInSelection for implementation details
138
- */
139
- function aliasTopLevelFields(prefix, document) {
140
- const transformer = {
141
- [graphql_1.Kind.OPERATION_DEFINITION]: (def) => {
142
- const { selections } = def.selectionSet;
143
- return {
144
- ...def,
145
- selectionSet: {
146
- ...def.selectionSet,
147
- selections: aliasFieldsInSelection(prefix, selections, document),
148
- },
149
- };
150
- },
151
- };
152
- return (0, graphql_1.visit)(document, transformer, {
153
- [graphql_1.Kind.DOCUMENT]: [`definitions`],
154
- });
155
- }
156
- /**
157
- * Add aliases to fields of the selection, including top-level fields of inline fragments.
158
- * Fragment spreads are converted to inline fragments and their top-level fields are also aliased.
159
- *
160
- * Note that this method is shallow. It adds aliases only to the top-level fields and doesn't
161
- * descend to field sub-selections.
162
- *
163
- * For example, transforms:
164
- * {
165
- * foo
166
- * ... on Query { foo }
167
- * ...FragmentWithBarField
168
- * }
169
- * To:
170
- * {
171
- * graphqlTools1_foo: foo
172
- * ... on Query { graphqlTools1_foo: foo }
173
- * ... on Query { graphqlTools1_bar: bar }
174
- * }
175
- */
176
- function aliasFieldsInSelection(prefix, selections, document) {
177
- return selections.map(selection => {
178
- switch (selection.kind) {
179
- case graphql_1.Kind.INLINE_FRAGMENT:
180
- return aliasFieldsInInlineFragment(prefix, selection, document);
181
- case graphql_1.Kind.FRAGMENT_SPREAD: {
182
- const inlineFragment = inlineFragmentSpread(selection, document);
183
- return aliasFieldsInInlineFragment(prefix, inlineFragment, document);
184
- }
185
- case graphql_1.Kind.FIELD:
186
- default:
187
- return aliasField(selection, prefix);
188
- }
189
- });
190
- }
191
- /**
192
- * Add aliases to top-level fields of the inline fragment.
193
- * Returns new inline fragment node.
194
- *
195
- * For Example, transforms:
196
- * ... on Query { foo, ... on Query { bar: foo } }
197
- * To
198
- * ... on Query { graphqlTools1_foo: foo, ... on Query { graphqlTools1_bar: foo } }
199
- */
200
- function aliasFieldsInInlineFragment(prefix, fragment, document) {
201
- const { selections } = fragment.selectionSet;
202
- return {
203
- ...fragment,
204
- selectionSet: {
205
- ...fragment.selectionSet,
206
- selections: aliasFieldsInSelection(prefix, selections, document),
207
- },
208
- };
209
- }
210
- /**
211
- * Replaces fragment spread with inline fragment
212
- *
213
- * Example:
214
- * query { ...Spread }
215
- * fragment Spread on Query { bar }
216
- *
217
- * Transforms to:
218
- * query { ... on Query { bar } }
219
- */
220
- function inlineFragmentSpread(spread, document) {
221
- const fragment = document.definitions.find(def => isFragmentDefinition(def) && def.name.value === spread.name.value);
222
- if (!fragment) {
223
- throw new Error(`Fragment ${spread.name.value} does not exist`);
224
- }
225
- const { typeCondition, selectionSet } = fragment;
226
- return {
227
- kind: graphql_1.Kind.INLINE_FRAGMENT,
228
- typeCondition,
229
- selectionSet,
230
- directives: spread.directives,
231
- };
232
- }
233
- function prefixNodeName(namedNode, prefix) {
234
- return {
235
- ...namedNode,
236
- name: {
237
- ...namedNode.name,
238
- value: prefix + namedNode.name.value,
239
- },
240
- };
241
- }
242
- /**
243
- * Returns a new FieldNode with prefixed alias
244
- *
245
- * Example. Given prefix === "graphqlTools1_" transforms:
246
- * { foo } -> { graphqlTools1_foo: foo }
247
- * { foo: bar } -> { graphqlTools1_foo: bar }
248
- */
249
- function aliasField(field, aliasPrefix) {
250
- const aliasNode = field.alias ? field.alias : field.name;
251
- return {
252
- ...field,
253
- alias: {
254
- ...aliasNode,
255
- value: aliasPrefix + aliasNode.value,
256
- },
257
- };
258
- }
259
- function isOperationDefinition(def) {
260
- return def.kind === graphql_1.Kind.OPERATION_DEFINITION;
261
- }
262
- function isFragmentDefinition(def) {
263
- return def.kind === graphql_1.Kind.FRAGMENT_DEFINITION;
264
- }
package/cjs/package.json DELETED
@@ -1 +0,0 @@
1
- {"type":"commonjs"}
package/cjs/prefix.js DELETED
@@ -1,42 +0,0 @@
1
- "use strict";
2
- // adapted from https://github.com/gatsbyjs/gatsby/blob/master/packages/gatsby-source-graphql/src/batching/merge-queries.js
3
- Object.defineProperty(exports, "__esModule", { value: true });
4
- exports.parseKeyFromPath = exports.parseKey = exports.createPrefix = void 0;
5
- function createPrefix(index) {
6
- return `_${index}_`;
7
- }
8
- exports.createPrefix = createPrefix;
9
- function matchKey(prefixedKey) {
10
- const match = /^_(\d+)_(.*)$/.exec(prefixedKey);
11
- if (match && match.length === 3 && !isNaN(Number(match[1])) && match[2]) {
12
- return { index: Number(match[1]), originalKey: match[2] };
13
- }
14
- return null;
15
- }
16
- function parseKey(prefixedKey) {
17
- const match = matchKey(prefixedKey);
18
- if (!match) {
19
- throw new Error(`Key ${prefixedKey} is not correctly prefixed`);
20
- }
21
- return match;
22
- }
23
- exports.parseKey = parseKey;
24
- function parseKeyFromPath(path) {
25
- let keyOffset = 0;
26
- let match = null;
27
- // Keep looping over path until we've found a match or path has no more items left
28
- for (; !match && keyOffset < path.length; keyOffset++) {
29
- const pathKey = path[keyOffset];
30
- if (typeof pathKey === 'string') {
31
- match = matchKey(pathKey);
32
- }
33
- }
34
- if (!match) {
35
- throw new Error(`Path ${path.join('.')} does not contain correctly prefixed key`);
36
- }
37
- return {
38
- ...match,
39
- keyOffset,
40
- };
41
- }
42
- exports.parseKeyFromPath = parseKeyFromPath;
@@ -1,49 +0,0 @@
1
- "use strict";
2
- // adapted from https://github.com/gatsbyjs/gatsby/blob/master/packages/gatsby-source-graphql/src/batching/merge-queries.js
3
- Object.defineProperty(exports, "__esModule", { value: true });
4
- exports.splitResult = void 0;
5
- const utils_1 = require("@graphql-tools/utils");
6
- const prefix_js_1 = require("./prefix.js");
7
- /**
8
- * Split and transform result of the query produced by the `merge` function
9
- */
10
- function splitResult({ data, errors }, numResults) {
11
- const splitResults = [];
12
- for (let i = 0; i < numResults; i++) {
13
- splitResults.push({});
14
- }
15
- if (data) {
16
- for (const prefixedKey in data) {
17
- const { index, originalKey } = (0, prefix_js_1.parseKey)(prefixedKey);
18
- const result = splitResults[index];
19
- if (result == null) {
20
- continue;
21
- }
22
- if (result.data == null) {
23
- result.data = { [originalKey]: data[prefixedKey] };
24
- }
25
- else {
26
- result.data[originalKey] = data[prefixedKey];
27
- }
28
- }
29
- }
30
- if (errors) {
31
- for (const error of errors) {
32
- if (error.path) {
33
- const { index, originalKey, keyOffset } = (0, prefix_js_1.parseKeyFromPath)(error.path);
34
- const newError = (0, utils_1.relocatedError)(error, [originalKey, ...error.path.slice(keyOffset)]);
35
- const resultErrors = (splitResults[index].errors = (splitResults[index].errors ||
36
- []));
37
- resultErrors.push(newError);
38
- }
39
- else {
40
- splitResults.forEach(result => {
41
- const resultErrors = (result.errors = (result.errors || []));
42
- resultErrors.push(error);
43
- });
44
- }
45
- }
46
- }
47
- return splitResults;
48
- }
49
- exports.splitResult = splitResult;
@@ -1,46 +0,0 @@
1
- import DataLoader from 'dataloader';
2
- import { ValueOrPromise } from 'value-or-promise';
3
- import { getOperationASTFromRequest, isAsyncIterable, } from '@graphql-tools/utils';
4
- import { mergeRequests } from './mergeRequests.js';
5
- import { splitResult } from './splitResult.js';
6
- export function createBatchingExecutor(executor, dataLoaderOptions, extensionsReducer = defaultExtensionsReducer) {
7
- const loadFn = createLoadFn(executor, extensionsReducer);
8
- const queryLoader = new DataLoader(loadFn, dataLoaderOptions);
9
- const mutationLoader = new DataLoader(loadFn, dataLoaderOptions);
10
- return function batchingExecutor(request) {
11
- const operationType = request.operationType ?? getOperationASTFromRequest(request)?.operation;
12
- switch (operationType) {
13
- case 'query':
14
- return queryLoader.load(request);
15
- case 'mutation':
16
- return mutationLoader.load(request);
17
- case 'subscription':
18
- return executor(request);
19
- default:
20
- throw new Error(`Invalid operation type "${operationType}"`);
21
- }
22
- };
23
- }
24
- function createLoadFn(executor, extensionsReducer) {
25
- return function batchExecuteLoadFn(requests) {
26
- if (requests.length === 1) {
27
- return new ValueOrPromise(() => executor(requests[0]))
28
- .then((result) => [result])
29
- .catch((err) => [err]);
30
- }
31
- const mergedRequests = mergeRequests(requests, extensionsReducer);
32
- return new ValueOrPromise(() => executor(mergedRequests)).then(resultBatches => {
33
- if (isAsyncIterable(resultBatches)) {
34
- throw new Error('Executor must not return incremental results for batching');
35
- }
36
- return splitResult(resultBatches, requests.length);
37
- });
38
- };
39
- }
40
- function defaultExtensionsReducer(mergedExtensions, request) {
41
- const newExtensions = request.extensions;
42
- if (newExtensions != null) {
43
- Object.assign(mergedExtensions, newExtensions);
44
- }
45
- return mergedExtensions;
46
- }
@@ -1,5 +0,0 @@
1
- import { memoize2of4 } from '@graphql-tools/utils';
2
- import { createBatchingExecutor } from './createBatchingExecutor.js';
3
- export const getBatchingExecutor = memoize2of4(function getBatchingExecutor(_context, executor, dataLoaderOptions, extensionsReducer) {
4
- return createBatchingExecutor(executor, dataLoaderOptions, extensionsReducer);
5
- });
package/esm/index.js DELETED
@@ -1,2 +0,0 @@
1
- export * from './createBatchingExecutor.js';
2
- export * from './getBatchingExecutor.js';