@graphql-tools/url-loader 7.9.12 → 7.9.15

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.
Files changed (4) hide show
  1. package/index.d.ts +2 -4
  2. package/index.js +23 -48
  3. package/index.mjs +24 -49
  4. package/package.json +5 -9
package/index.d.ts CHANGED
@@ -3,7 +3,6 @@
3
3
  import { IntrospectionOptions } from 'graphql';
4
4
  import { AsyncExecutor, Executor, SyncExecutor, Source, Loader, BaseLoaderOptions } from '@graphql-tools/utils';
5
5
  import { ClientOptions } from 'graphql-ws';
6
- import { ClientOptions as GraphQLSSEClientOptions } from 'graphql-sse';
7
6
  import WebSocket from 'isomorphic-ws';
8
7
  import { AsyncFetchFn } from './defaultAsyncFetch';
9
8
  import { SyncFetchFn } from './defaultSyncFetch';
@@ -77,9 +76,9 @@ export interface LoadFromUrlOptions extends BaseLoaderOptions, Partial<Introspec
77
76
  */
78
77
  subscriptionsProtocol?: SubscriptionProtocol;
79
78
  /**
80
- * Additional options to pass to the graphql-sse client.
79
+ * @deprecated This is no longer used. Will be removed in the next release
81
80
  */
82
- graphqlSseOptions?: Omit<GraphQLSSEClientOptions, 'url' | 'headers' | 'fetchFn' | 'abortControllerImpl'>;
81
+ graphqlSseOptions?: any;
83
82
  /**
84
83
  * Retry attempts
85
84
  */
@@ -123,7 +122,6 @@ export declare class UrlLoader implements Loader<LoadFromUrlOptions> {
123
122
  buildHTTPExecutor(endpoint: string, fetch: AsyncFetchFn, options?: LoadFromUrlOptions): AsyncExecutor<any, ExecutionExtensions>;
124
123
  buildWSExecutor(subscriptionsEndpoint: string, webSocketImpl: typeof WebSocket, connectionParams?: ClientOptions['connectionParams']): Executor;
125
124
  buildWSLegacyExecutor(subscriptionsEndpoint: string, WebSocketImpl: typeof WebSocket, options?: LoadFromUrlOptions): Executor;
126
- buildGraphQLSSEExecutor(endpoint: string, fetch: AsyncFetchFn, options?: Omit<LoadFromUrlOptions, 'subscriptionEndpoint'>): AsyncExecutor;
127
125
  getFetch(customFetch: LoadFromUrlOptions['customFetch'], importFn: AsyncImportFn): PromiseLike<AsyncFetchFn> | AsyncFetchFn;
128
126
  getFetch(customFetch: LoadFromUrlOptions['customFetch'], importFn: SyncImportFn): SyncFetchFn;
129
127
  private getDefaultMethodFromOptions;
package/index.js CHANGED
@@ -27,7 +27,6 @@ const graphql = require('graphql');
27
27
  const utils = require('@graphql-tools/utils');
28
28
  const wrap = require('@graphql-tools/wrap');
29
29
  const graphqlWs = require('graphql-ws');
30
- const graphqlSse = require('graphql-sse');
31
30
  const WebSocket = _interopDefault(require('isomorphic-ws'));
32
31
  const extractFiles = require('extract-files');
33
32
  const valueOrPromise = require('value-or-promise');
@@ -98,10 +97,17 @@ async function handleMultipartMixedResponse(response) {
98
97
  }
99
98
 
100
99
  /* eslint-disable no-labels */
100
+ let decodeUint8Array;
101
+ if (globalThis.Buffer) {
102
+ decodeUint8Array = uint8Array => globalThis.Buffer.from(uint8Array).toString('utf-8');
103
+ }
104
+ else {
105
+ const textDecoder = new TextDecoder();
106
+ decodeUint8Array = uint8Array => textDecoder.decode(uint8Array);
107
+ }
101
108
  async function* handleReadable(readable) {
102
- const decoder = new TextDecoder();
103
109
  outer: for await (const chunk of readable) {
104
- const chunkStr = typeof chunk === 'string' ? chunk : decoder.decode(chunk);
110
+ const chunkStr = typeof chunk === 'string' ? chunk : decodeUint8Array(chunk);
105
111
  for (const part of chunkStr.split('\n\n')) {
106
112
  if (part) {
107
113
  const eventStr = part.split('event: ')[1];
@@ -423,23 +429,18 @@ class UrlLoader {
423
429
  var _a, _b;
424
430
  const controller = new crossUndiciFetch.AbortController();
425
431
  let method = defaultMethod;
426
- if (options === null || options === void 0 ? void 0 : options.useGETForQueries) {
427
- const operationAst = utils.getOperationASTFromRequest(request);
428
- const operationType = operationAst.operation;
429
- if (operationType === 'query') {
430
- method = 'GET';
431
- }
432
+ const operationAst = utils.getOperationASTFromRequest(request);
433
+ const operationType = operationAst.operation;
434
+ if ((options === null || options === void 0 ? void 0 : options.useGETForQueries) && operationType === 'query') {
435
+ method = 'GET';
436
+ }
437
+ let accept = 'application/json, multipart/mixed';
438
+ if (operationType === 'subscription') {
439
+ method = 'GET';
440
+ accept = 'text/event-stream';
432
441
  }
433
442
  const endpoint = ((_a = request.extensions) === null || _a === void 0 ? void 0 : _a.endpoint) || HTTP_URL;
434
443
  const headers = Object.assign({}, options === null || options === void 0 ? void 0 : options.headers, ((_b = request.extensions) === null || _b === void 0 ? void 0 : _b.headers) || {});
435
- const acceptedProtocols = [`application/json`];
436
- if (method === 'GET' && (options === null || options === void 0 ? void 0 : options.subscriptionsProtocol) === exports.SubscriptionProtocol.SSE) {
437
- acceptedProtocols.push('text/event-stream');
438
- }
439
- else {
440
- acceptedProtocols.push('multipart/mixed');
441
- }
442
- const accept = acceptedProtocols.join(', ');
443
444
  const query = graphql.print(request.document);
444
445
  const requestBody = {
445
446
  query,
@@ -521,7 +522,9 @@ class UrlLoader {
521
522
  })
522
523
  .then(result => {
523
524
  if (typeof result === 'string') {
524
- return JSON.parse(result);
525
+ if (result) {
526
+ return JSON.parse(result);
527
+ }
525
528
  }
526
529
  else {
527
530
  return result;
@@ -668,31 +671,6 @@ class UrlLoader {
668
671
  });
669
672
  };
670
673
  }
671
- buildGraphQLSSEExecutor(endpoint, fetch, options = {}) {
672
- const { headers } = options;
673
- const client = graphqlSse.createClient({
674
- ...options.graphqlSseOptions,
675
- url: endpoint,
676
- fetchFn: fetch,
677
- abortControllerImpl: crossUndiciFetch.AbortController,
678
- headers,
679
- });
680
- return async ({ document, variables, operationName, extensions }) => {
681
- return utils.observableToAsyncIterable({
682
- subscribe: observer => {
683
- const unsubscribe = client.subscribe({
684
- query: document,
685
- variables: variables,
686
- operationName,
687
- extensions,
688
- }, observer);
689
- return {
690
- unsubscribe,
691
- };
692
- },
693
- });
694
- };
695
- }
696
674
  getFetch(customFetch, importFn) {
697
675
  if (customFetch) {
698
676
  if (typeof customFetch === 'string') {
@@ -732,10 +710,7 @@ class UrlLoader {
732
710
  }
733
711
  buildSubscriptionExecutor(subscriptionsEndpoint, fetch, importFn, options) {
734
712
  if ((options === null || options === void 0 ? void 0 : options.subscriptionsProtocol) === exports.SubscriptionProtocol.SSE) {
735
- return this.buildHTTPExecutor(subscriptionsEndpoint, fetch, {
736
- ...options,
737
- method: 'GET',
738
- });
713
+ return this.buildHTTPExecutor(subscriptionsEndpoint, fetch, options);
739
714
  }
740
715
  else if ((options === null || options === void 0 ? void 0 : options.subscriptionsProtocol) === exports.SubscriptionProtocol.GRAPHQL_SSE) {
741
716
  if (!(options === null || options === void 0 ? void 0 : options.subscriptionsEndpoint)) {
@@ -743,7 +718,7 @@ class UrlLoader {
743
718
  // graphql-sse is recommended to be used on `/graphql/stream`
744
719
  subscriptionsEndpoint += '/stream';
745
720
  }
746
- return this.buildGraphQLSSEExecutor(subscriptionsEndpoint, fetch, options);
721
+ return this.buildHTTPExecutor(subscriptionsEndpoint, fetch, options);
747
722
  }
748
723
  else {
749
724
  const webSocketImpl$ = new valueOrPromise.ValueOrPromise(() => this.getWebSocketImpl(importFn, options));
package/index.mjs CHANGED
@@ -2,12 +2,11 @@ import { print, buildASTSchema, buildSchema } from 'graphql';
2
2
  import { mapAsyncIterator, isAsyncIterable, inspect, withCancel, observableToAsyncIterable, parseGraphQLSDL, getOperationASTFromRequest } from '@graphql-tools/utils';
3
3
  import { introspectSchema, wrapSchema } from '@graphql-tools/wrap';
4
4
  import { createClient } from 'graphql-ws';
5
- import { createClient as createClient$1 } from 'graphql-sse';
6
5
  import WebSocket from 'isomorphic-ws';
7
6
  import { extractFiles, isExtractableFile } from 'extract-files';
8
7
  import { ValueOrPromise } from 'value-or-promise';
9
8
  import { isLiveQueryOperationDefinitionNode } from '@n1ru4l/graphql-live-query';
10
- import { fetch, FormData, AbortController, File } from 'cross-undici-fetch';
9
+ import { fetch, FormData, File, AbortController } from 'cross-undici-fetch';
11
10
  import syncFetchImported from 'sync-fetch';
12
11
  import { meros } from 'meros/node';
13
12
  import { meros as meros$1 } from 'meros/browser';
@@ -73,10 +72,17 @@ async function handleMultipartMixedResponse(response) {
73
72
  }
74
73
 
75
74
  /* eslint-disable no-labels */
75
+ let decodeUint8Array;
76
+ if (globalThis.Buffer) {
77
+ decodeUint8Array = uint8Array => globalThis.Buffer.from(uint8Array).toString('utf-8');
78
+ }
79
+ else {
80
+ const textDecoder = new TextDecoder();
81
+ decodeUint8Array = uint8Array => textDecoder.decode(uint8Array);
82
+ }
76
83
  async function* handleReadable(readable) {
77
- const decoder = new TextDecoder();
78
84
  outer: for await (const chunk of readable) {
79
- const chunkStr = typeof chunk === 'string' ? chunk : decoder.decode(chunk);
85
+ const chunkStr = typeof chunk === 'string' ? chunk : decodeUint8Array(chunk);
80
86
  for (const part of chunkStr.split('\n\n')) {
81
87
  if (part) {
82
88
  const eventStr = part.split('event: ')[1];
@@ -399,23 +405,18 @@ class UrlLoader {
399
405
  var _a, _b;
400
406
  const controller = new AbortController();
401
407
  let method = defaultMethod;
402
- if (options === null || options === void 0 ? void 0 : options.useGETForQueries) {
403
- const operationAst = getOperationASTFromRequest(request);
404
- const operationType = operationAst.operation;
405
- if (operationType === 'query') {
406
- method = 'GET';
407
- }
408
+ const operationAst = getOperationASTFromRequest(request);
409
+ const operationType = operationAst.operation;
410
+ if ((options === null || options === void 0 ? void 0 : options.useGETForQueries) && operationType === 'query') {
411
+ method = 'GET';
412
+ }
413
+ let accept = 'application/json, multipart/mixed';
414
+ if (operationType === 'subscription') {
415
+ method = 'GET';
416
+ accept = 'text/event-stream';
408
417
  }
409
418
  const endpoint = ((_a = request.extensions) === null || _a === void 0 ? void 0 : _a.endpoint) || HTTP_URL;
410
419
  const headers = Object.assign({}, options === null || options === void 0 ? void 0 : options.headers, ((_b = request.extensions) === null || _b === void 0 ? void 0 : _b.headers) || {});
411
- const acceptedProtocols = [`application/json`];
412
- if (method === 'GET' && (options === null || options === void 0 ? void 0 : options.subscriptionsProtocol) === SubscriptionProtocol.SSE) {
413
- acceptedProtocols.push('text/event-stream');
414
- }
415
- else {
416
- acceptedProtocols.push('multipart/mixed');
417
- }
418
- const accept = acceptedProtocols.join(', ');
419
420
  const query = print(request.document);
420
421
  const requestBody = {
421
422
  query,
@@ -497,7 +498,9 @@ class UrlLoader {
497
498
  })
498
499
  .then(result => {
499
500
  if (typeof result === 'string') {
500
- return JSON.parse(result);
501
+ if (result) {
502
+ return JSON.parse(result);
503
+ }
501
504
  }
502
505
  else {
503
506
  return result;
@@ -644,31 +647,6 @@ class UrlLoader {
644
647
  });
645
648
  };
646
649
  }
647
- buildGraphQLSSEExecutor(endpoint, fetch, options = {}) {
648
- const { headers } = options;
649
- const client = createClient$1({
650
- ...options.graphqlSseOptions,
651
- url: endpoint,
652
- fetchFn: fetch,
653
- abortControllerImpl: AbortController,
654
- headers,
655
- });
656
- return async ({ document, variables, operationName, extensions }) => {
657
- return observableToAsyncIterable({
658
- subscribe: observer => {
659
- const unsubscribe = client.subscribe({
660
- query: document,
661
- variables: variables,
662
- operationName,
663
- extensions,
664
- }, observer);
665
- return {
666
- unsubscribe,
667
- };
668
- },
669
- });
670
- };
671
- }
672
650
  getFetch(customFetch, importFn) {
673
651
  if (customFetch) {
674
652
  if (typeof customFetch === 'string') {
@@ -708,10 +686,7 @@ class UrlLoader {
708
686
  }
709
687
  buildSubscriptionExecutor(subscriptionsEndpoint, fetch, importFn, options) {
710
688
  if ((options === null || options === void 0 ? void 0 : options.subscriptionsProtocol) === SubscriptionProtocol.SSE) {
711
- return this.buildHTTPExecutor(subscriptionsEndpoint, fetch, {
712
- ...options,
713
- method: 'GET',
714
- });
689
+ return this.buildHTTPExecutor(subscriptionsEndpoint, fetch, options);
715
690
  }
716
691
  else if ((options === null || options === void 0 ? void 0 : options.subscriptionsProtocol) === SubscriptionProtocol.GRAPHQL_SSE) {
717
692
  if (!(options === null || options === void 0 ? void 0 : options.subscriptionsEndpoint)) {
@@ -719,7 +694,7 @@ class UrlLoader {
719
694
  // graphql-sse is recommended to be used on `/graphql/stream`
720
695
  subscriptionsEndpoint += '/stream';
721
696
  }
722
- return this.buildGraphQLSSEExecutor(subscriptionsEndpoint, fetch, options);
697
+ return this.buildHTTPExecutor(subscriptionsEndpoint, fetch, options);
723
698
  }
724
699
  else {
725
700
  const webSocketImpl$ = new ValueOrPromise(() => this.getWebSocketImpl(importFn, options));
package/package.json CHANGED
@@ -1,24 +1,20 @@
1
1
  {
2
2
  "name": "@graphql-tools/url-loader",
3
- "version": "7.9.12",
3
+ "version": "7.9.15",
4
4
  "description": "A set of utils for faster development of GraphQL tools",
5
5
  "sideEffects": false,
6
6
  "peerDependencies": {
7
7
  "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0"
8
8
  },
9
9
  "dependencies": {
10
- "@envelop/live-query": "3.3.1",
11
- "@graphql-tools/delegate": "8.7.5",
12
- "@graphql-tools/utils": "8.6.8",
13
- "@graphql-tools/wrap": "8.4.14",
14
- "@graphql-yoga/node": "2.3.0",
10
+ "@graphql-tools/delegate": "8.7.7",
11
+ "@graphql-tools/utils": "8.6.9",
12
+ "@graphql-tools/wrap": "8.4.16",
15
13
  "@n1ru4l/graphql-live-query": "^0.9.0",
16
- "@types/websocket": "^1.0.4",
17
14
  "@types/ws": "^8.0.0",
18
- "cross-undici-fetch": "^0.2.4",
15
+ "cross-undici-fetch": "^0.3.0",
19
16
  "dset": "^3.1.0",
20
17
  "extract-files": "^11.0.0",
21
- "graphql-sse": "^1.0.1",
22
18
  "graphql-ws": "^5.4.1",
23
19
  "isomorphic-ws": "^4.0.1",
24
20
  "meros": "^1.1.4",