UNPKG

12.7 kBJavaScriptView Raw
1'use strict';
2
3Object.defineProperty(exports, '__esModule', { value: true });
4
5function _interopNamespace(e) {
6 if (e && e.__esModule) { return e; } else {
7 var n = {};
8 if (e) {
9 Object.keys(e).forEach(function (k) {
10 var d = Object.getOwnPropertyDescriptor(e, k);
11 Object.defineProperty(n, k, d.get ? d : {
12 enumerable: true,
13 get: function () {
14 return e[k];
15 }
16 });
17 });
18 }
19 n['default'] = e;
20 return n;
21 }
22}
23
24const tslib = require('tslib');
25const graphql = require('graphql');
26const utils = require('@graphql-tools/utils/es5');
27const validUrl = require('valid-url');
28const crossFetch = require('cross-fetch');
29const wrap = require('@graphql-tools/wrap/es5');
30const subscriptionsTransportWs = require('subscriptions-transport-ws');
31const websocket = require('websocket');
32
33/**
34 * This loader loads a schema from a URL. The loaded schema is a fully-executable,
35 * remote schema since it's created using [@graphql-tools/wrap](/docs/remote-schemas).
36 *
37 * ```
38 * const schema = await loadSchema('http://localhost:3000/graphql', {
39 * loaders: [
40 * new UrlLoader(),
41 * ]
42 * });
43 * ```
44 */
45var UrlLoader = /** @class */ (function () {
46 function UrlLoader() {
47 }
48 UrlLoader.prototype.loaderId = function () {
49 return 'url';
50 };
51 UrlLoader.prototype.canLoad = function (pointer, options) {
52 return tslib.__awaiter(this, void 0, void 0, function () {
53 return tslib.__generator(this, function (_a) {
54 return [2 /*return*/, this.canLoadSync(pointer, options)];
55 });
56 });
57 };
58 UrlLoader.prototype.canLoadSync = function (pointer, _options) {
59 return !!validUrl.isWebUri(pointer);
60 };
61 UrlLoader.prototype.buildAsyncExecutor = function (_a) {
62 var _this = this;
63 var pointer = _a.pointer, fetch = _a.fetch, extraHeaders = _a.extraHeaders, defaultMethod = _a.defaultMethod, useGETForQueries = _a.useGETForQueries;
64 var HTTP_URL = switchProtocols(pointer, {
65 wss: 'https',
66 ws: 'http',
67 });
68 return function (_a) {
69 var document = _a.document, variables = _a.variables;
70 return tslib.__awaiter(_this, void 0, void 0, function () {
71 var method, _b, _c, definition, fetchResult, query, _d, urlObj, finalUrl;
72 var e_1, _e;
73 return tslib.__generator(this, function (_f) {
74 switch (_f.label) {
75 case 0:
76 method = defaultMethod;
77 if (useGETForQueries) {
78 method = 'GET';
79 try {
80 for (_b = tslib.__values(document.definitions), _c = _b.next(); !_c.done; _c = _b.next()) {
81 definition = _c.value;
82 if (definition.kind === graphql.Kind.OPERATION_DEFINITION) {
83 if (definition.operation !== 'query') {
84 method = defaultMethod;
85 }
86 }
87 }
88 }
89 catch (e_1_1) { e_1 = { error: e_1_1 }; }
90 finally {
91 try {
92 if (_c && !_c.done && (_e = _b.return)) _e.call(_b);
93 }
94 finally { if (e_1) throw e_1.error; }
95 }
96 }
97 query = graphql.print(document);
98 _d = method;
99 switch (_d) {
100 case 'GET': return [3 /*break*/, 1];
101 case 'POST': return [3 /*break*/, 3];
102 }
103 return [3 /*break*/, 5];
104 case 1:
105 urlObj = new URL(HTTP_URL);
106 urlObj.searchParams.set('query', query);
107 if (variables && Object.keys(variables).length > 0) {
108 urlObj.searchParams.set('variables', JSON.stringify(variables));
109 }
110 finalUrl = urlObj.toString();
111 return [4 /*yield*/, fetch(finalUrl, {
112 method: 'GET',
113 headers: extraHeaders,
114 })];
115 case 2:
116 fetchResult = _f.sent();
117 return [3 /*break*/, 5];
118 case 3: return [4 /*yield*/, fetch(HTTP_URL, {
119 method: 'POST',
120 body: JSON.stringify({
121 query: query,
122 variables: variables,
123 }),
124 headers: extraHeaders,
125 })];
126 case 4:
127 fetchResult = _f.sent();
128 return [3 /*break*/, 5];
129 case 5: return [2 /*return*/, fetchResult.json()];
130 }
131 });
132 });
133 };
134 };
135 UrlLoader.prototype.buildSubscriber = function (pointer, webSocketImpl) {
136 var _this = this;
137 var WS_URL = switchProtocols(pointer, {
138 https: 'wss',
139 http: 'ws',
140 });
141 var subscriptionClient = new subscriptionsTransportWs.SubscriptionClient(WS_URL, {}, webSocketImpl);
142 return function (_a) {
143 var document = _a.document, variables = _a.variables;
144 return tslib.__awaiter(_this, void 0, void 0, function () {
145 return tslib.__generator(this, function (_b) {
146 return [2 /*return*/, utils.observableToAsyncIterable(subscriptionClient.request({
147 query: document,
148 variables: variables,
149 }))];
150 });
151 });
152 };
153 };
154 UrlLoader.prototype.getExecutorAndSubscriber = function (pointer, options) {
155 return tslib.__awaiter(this, void 0, void 0, function () {
156 var headers, fetch, defaultMethod, webSocketImpl, _a, moduleName, fetchFnName_1, _b, moduleName, webSocketImplName_1, extraHeaders, executor, subscriber;
157 return tslib.__generator(this, function (_c) {
158 switch (_c.label) {
159 case 0:
160 headers = {};
161 fetch = crossFetch.fetch;
162 defaultMethod = 'POST';
163 webSocketImpl = websocket.w3cwebsocket;
164 if (!options) return [3 /*break*/, 7];
165 if (Array.isArray(options.headers)) {
166 headers = options.headers.reduce(function (prev, v) { return (tslib.__assign(tslib.__assign({}, prev), v)); }, {});
167 }
168 else if (typeof options.headers === 'object') {
169 headers = options.headers;
170 }
171 if (!options.customFetch) return [3 /*break*/, 3];
172 if (!(typeof options.customFetch === 'string')) return [3 /*break*/, 2];
173 _a = tslib.__read(options.customFetch.split('#'), 2), moduleName = _a[0], fetchFnName_1 = _a[1];
174 return [4 /*yield*/, new Promise(function (resolve) { resolve(_interopNamespace(require(moduleName))); }).then(function (module) { return (fetchFnName_1 ? module[fetchFnName_1] : module); })];
175 case 1:
176 fetch = _c.sent();
177 return [3 /*break*/, 3];
178 case 2:
179 fetch = options.customFetch;
180 _c.label = 3;
181 case 3:
182 if (!options.webSocketImpl) return [3 /*break*/, 6];
183 if (!(typeof options.webSocketImpl === 'string')) return [3 /*break*/, 5];
184 _b = tslib.__read(options.webSocketImpl.split('#'), 2), moduleName = _b[0], webSocketImplName_1 = _b[1];
185 return [4 /*yield*/, new Promise(function (resolve) { resolve(_interopNamespace(require(moduleName))); }).then(function (module) {
186 return webSocketImplName_1 ? module[webSocketImplName_1] : module;
187 })];
188 case 4:
189 webSocketImpl = _c.sent();
190 return [3 /*break*/, 6];
191 case 5:
192 webSocketImpl = options.webSocketImpl;
193 _c.label = 6;
194 case 6:
195 if (options.method) {
196 defaultMethod = options.method;
197 }
198 _c.label = 7;
199 case 7:
200 extraHeaders = tslib.__assign({ Accept: 'application/json', 'Content-Type': 'application/json' }, headers);
201 executor = this.buildAsyncExecutor({
202 pointer: pointer,
203 fetch: fetch,
204 extraHeaders: extraHeaders,
205 defaultMethod: defaultMethod,
206 useGETForQueries: options.useGETForQueries,
207 });
208 if (options.enableSubscriptions) {
209 subscriber = this.buildSubscriber(pointer, webSocketImpl);
210 }
211 return [2 /*return*/, {
212 executor: executor,
213 subscriber: subscriber,
214 }];
215 }
216 });
217 });
218 };
219 UrlLoader.prototype.getSubschemaConfig = function (pointer, options) {
220 return tslib.__awaiter(this, void 0, void 0, function () {
221 var _a, executor, subscriber;
222 var _b;
223 return tslib.__generator(this, function (_c) {
224 switch (_c.label) {
225 case 0: return [4 /*yield*/, this.getExecutorAndSubscriber(pointer, options)];
226 case 1:
227 _a = _c.sent(), executor = _a.executor, subscriber = _a.subscriber;
228 _b = {};
229 return [4 /*yield*/, wrap.introspectSchema(executor, undefined, options)];
230 case 2: return [2 /*return*/, (_b.schema = _c.sent(),
231 _b.executor = executor,
232 _b.subscriber = subscriber,
233 _b)];
234 }
235 });
236 });
237 };
238 UrlLoader.prototype.load = function (pointer, options) {
239 return tslib.__awaiter(this, void 0, void 0, function () {
240 var subschemaConfig, remoteExecutableSchema;
241 return tslib.__generator(this, function (_a) {
242 switch (_a.label) {
243 case 0: return [4 /*yield*/, this.getSubschemaConfig(pointer, options)];
244 case 1:
245 subschemaConfig = _a.sent();
246 remoteExecutableSchema = wrap.wrapSchema(subschemaConfig);
247 return [2 /*return*/, {
248 location: pointer,
249 schema: remoteExecutableSchema,
250 }];
251 }
252 });
253 });
254 };
255 UrlLoader.prototype.loadSync = function () {
256 throw new Error('Loader Url has no sync mode');
257 };
258 return UrlLoader;
259}());
260function switchProtocols(pointer, protocolMap) {
261 var protocols = Object.keys(protocolMap).map(function (source) { return [source, protocolMap[source]]; });
262 return protocols.reduce(function (prev, _a) {
263 var _b = tslib.__read(_a, 2), source = _b[0], target = _b[1];
264 return prev.replace(source + "://", target + "://").replace(source + ":\\", target + ":\\");
265 }, pointer);
266}
267
268exports.UrlLoader = UrlLoader;
269//# sourceMappingURL=index.cjs.js.map