UNPKG

14.2 kBJavaScriptView Raw
1import { fetchFactory } from 'fetchache';
2import { fetch, Request, Response, Headers } from 'cross-fetch';
3import isUrl from 'is-url';
4export { default as isUrl } from 'is-url';
5import { load } from 'js-yaml';
6import { isAbsolute, resolve, join, dirname } from 'path';
7import { promises, readFileSync } from 'fs';
8import { Interpolator } from '@ardatan/string-interpolation';
9import { format } from 'date-fns';
10import objectHash from 'object-hash';
11import { isInputType, GraphQLInt, GraphQLFloat, GraphQLBoolean, GraphQLString, GraphQLID, parse, print } from 'graphql';
12import { getResolversFromSchema } from '@graphql-tools/utils';
13import flatstr from 'flatstr';
14import lru from 'tiny-lru';
15import { compileQuery, isCompiledQuery } from 'graphql-jit';
16
17const { readFile, stat } = promises || {};
18function getCachedFetch(cache) {
19 return fetchFactory({
20 fetch,
21 Request,
22 Response,
23 cache,
24 });
25}
26async function readFileOrUrlWithCache(filePathOrUrl, cache, config) {
27 if (isUrl(filePathOrUrl)) {
28 return readUrlWithCache(filePathOrUrl, cache, config);
29 }
30 else {
31 return readFileWithCache(filePathOrUrl, cache, config);
32 }
33}
34async function readFileWithCache(filePath, cache, config) {
35 const { allowUnknownExtensions, cwd, fallbackFormat } = config || {};
36 const actualPath = isAbsolute(filePath) ? filePath : resolve(cwd || process.cwd(), filePath);
37 const cachedObj = await cache.get(actualPath);
38 const stats = await stat(actualPath);
39 if (cachedObj) {
40 if (stats.mtimeMs <= cachedObj.mtimeMs) {
41 return cachedObj.result;
42 }
43 }
44 let result = await readFile(actualPath, 'utf-8');
45 if (/json$/.test(filePath)) {
46 result = JSON.parse(result);
47 }
48 else if (/yaml$/.test(filePath) || /yml$/.test(filePath)) {
49 result = load(result);
50 }
51 else if (fallbackFormat) {
52 switch (fallbackFormat) {
53 case 'json':
54 result = JSON.parse(result);
55 break;
56 case 'yaml':
57 result = load(result);
58 break;
59 }
60 }
61 else if (!allowUnknownExtensions) {
62 throw new Error(`Failed to parse JSON/YAML. Ensure file '${filePath}' has ` +
63 `the correct extension (i.e. '.json', '.yaml', or '.yml).`);
64 }
65 cache.set(filePath, { result, mtimeMs: stats.mtimeMs });
66 return result;
67}
68async function readUrlWithCache(path, cache, config) {
69 var _a;
70 const { allowUnknownExtensions, fallbackFormat } = config || {};
71 const fetch = (config === null || config === void 0 ? void 0 : config.fetch) || getCachedFetch(cache);
72 const response = await fetch(path, config);
73 const contentType = ((_a = response.headers) === null || _a === void 0 ? void 0 : _a.get('content-type')) || '';
74 const responseText = await response.text();
75 if (/json$/.test(path) || contentType.startsWith('application/json') || fallbackFormat === 'json') {
76 return JSON.parse(responseText);
77 }
78 else if (/yaml$/.test(path) ||
79 /yml$/.test(path) ||
80 contentType.includes('yaml') ||
81 contentType.includes('yml') ||
82 fallbackFormat === 'yaml') {
83 return load(responseText);
84 }
85 else if (!allowUnknownExtensions) {
86 throw new Error(`Failed to parse JSON/YAML. Ensure URL '${path}' has ` +
87 `the correct extension (i.e. '.json', '.yaml', or '.yml) or mime type in the response headers.`);
88 }
89 return responseText;
90}
91
92const stringInterpolator = new Interpolator({
93 delimiter: ['{', '}'],
94});
95stringInterpolator.addAlias('typeName', 'info.parentType.name');
96stringInterpolator.addAlias('type', 'info.parentType.name');
97stringInterpolator.addAlias('parentType', 'info.parentType.name');
98stringInterpolator.addAlias('fieldName', 'info.fieldName');
99stringInterpolator.registerModifier('date', (formatStr) => format(new Date(), formatStr));
100stringInterpolator.registerModifier('hash', (value) => objectHash(value, { ignoreUnknown: true }));
101
102async function loadFromModuleExportExpression(expression, options) {
103 if (typeof expression !== 'string') {
104 return expression;
105 }
106 const { defaultExportName, cwd } = options || {};
107 const [modulePath, exportName = defaultExportName] = expression.split('#');
108 const mod = await tryImport(modulePath, cwd);
109 if (exportName === 'default' || !exportName) {
110 return mod.default || mod;
111 }
112 else {
113 return mod[exportName] || (mod.default && mod.default[exportName]);
114 }
115}
116async function tryImport(modulePath, cwd) {
117 try {
118 return await import(modulePath);
119 }
120 catch (e1) {
121 if (!isAbsolute(modulePath)) {
122 try {
123 const absoluteModulePath = isAbsolute(modulePath) ? modulePath : join(cwd || process.cwd(), modulePath);
124 return await import(absoluteModulePath);
125 }
126 catch (e2) {
127 if (e2.message.includes('Cannot find module')) {
128 throw e1;
129 }
130 else {
131 throw e2;
132 }
133 }
134 }
135 throw e1;
136 }
137}
138function loadFromModuleExportExpressionSync(expression, options) {
139 if (typeof expression !== 'string') {
140 return expression;
141 }
142 const { defaultExportName, cwd } = options || {};
143 const [modulePath, exportName = defaultExportName] = expression.split('#');
144 const mod = tryImportSync(modulePath, cwd);
145 if (exportName === 'default' || !exportName) {
146 return mod.default || mod;
147 }
148 else {
149 return mod[exportName] || (mod.default && mod.default[exportName]);
150 }
151}
152function tryImportSync(modulePath, cwd) {
153 try {
154 return require(modulePath);
155 }
156 catch (e1) {
157 if (!isAbsolute(modulePath)) {
158 try {
159 const absoluteModulePath = isAbsolute(modulePath) ? modulePath : join(cwd || process.cwd(), modulePath);
160 return require(absoluteModulePath);
161 }
162 catch (e2) {
163 if (e2.message.includes('Cannot find module')) {
164 throw e1;
165 }
166 else {
167 throw e2;
168 }
169 }
170 }
171 throw e1;
172 }
173}
174
175var ArgType;
176(function (ArgType) {
177 ArgType["ID"] = "ID";
178 ArgType["String"] = "String";
179 ArgType["Boolean"] = "Boolean";
180 ArgType["Float"] = "Float";
181 ArgType["Int"] = "Int";
182})(ArgType || (ArgType = {}));
183function getInputTypeFromTypeName(typeName) {
184 if (isInputType(typeName)) {
185 return typeName;
186 }
187 else {
188 switch (typeName) {
189 case ArgType.ID:
190 return GraphQLID;
191 case ArgType.String:
192 return GraphQLString;
193 case ArgType.Boolean:
194 return GraphQLBoolean;
195 case ArgType.Float:
196 return GraphQLFloat;
197 case ArgType.Int:
198 return GraphQLInt;
199 }
200 }
201}
202function parseInterpolationStrings(interpolationStrings, argTypeMap) {
203 const interpolationKeys = interpolationStrings.reduce((keys, str) => [...keys, ...(str ? stringInterpolator.parseRules(str).map((match) => match.key) : [])], []);
204 const args = {};
205 const contextVariables = [];
206 for (const interpolationKey of interpolationKeys) {
207 const interpolationKeyParts = interpolationKey.split('.');
208 const varName = interpolationKeyParts[interpolationKeyParts.length - 1];
209 if (interpolationKeyParts[0] === 'args') {
210 const argType = argTypeMap && varName in argTypeMap ? getInputTypeFromTypeName(argTypeMap[varName]) : GraphQLID;
211 args[varName] = {
212 type: argType,
213 };
214 }
215 else if (interpolationKeyParts[0] === 'context') {
216 contextVariables.push(varName);
217 }
218 }
219 return {
220 args,
221 contextVariables,
222 };
223}
224function getInterpolatedStringFactory(nonInterpolatedString) {
225 return resolverData => stringInterpolator.parse(nonInterpolatedString, resolverData);
226}
227function getInterpolatedHeadersFactory(nonInterpolatedHeaders = {}) {
228 return resolverData => {
229 const headers = new Headers();
230 for (const headerName in nonInterpolatedHeaders) {
231 const headerValue = nonInterpolatedHeaders[headerName];
232 if (headerValue) {
233 headers.set(headerName, stringInterpolator.parse(headerValue, resolverData));
234 }
235 }
236 return headers;
237 };
238}
239function getHeadersObject(headers) {
240 const headersObj = {};
241 headers.forEach((value, key) => {
242 headersObj[key] = value;
243 });
244 return headersObj;
245}
246
247function withCancel(asyncIteratorLike, onCancel) {
248 const asyncIterator = asyncIteratorLike[Symbol.asyncIterator]();
249 if (!asyncIterator.return) {
250 asyncIterator.return = () => Promise.resolve({ value: undefined, done: true });
251 }
252 const savedReturn = asyncIterator.return.bind(asyncIterator);
253 asyncIterator.return = () => {
254 onCancel();
255 return savedReturn();
256 };
257 return asyncIterator;
258}
259
260function extractResolvers(schema) {
261 const allResolvers = getResolversFromSchema(schema);
262 const filteredResolvers = {};
263 for (const prop in allResolvers) {
264 if (!prop.startsWith('_')) {
265 filteredResolvers[prop] = allResolvers[prop];
266 }
267 }
268 return filteredResolvers;
269}
270
271function ensureDocumentNode(document) {
272 return typeof document === 'string' ? parse(document) : document;
273}
274
275function groupTransforms(transforms) {
276 const wrapTransforms = [];
277 const noWrapTransforms = [];
278 transforms === null || transforms === void 0 ? void 0 : transforms.forEach(transform => {
279 if (transform.noWrap) {
280 noWrapTransforms.push(transform);
281 }
282 else {
283 wrapTransforms.push(transform);
284 }
285 });
286 return { wrapTransforms, noWrapTransforms };
287}
288
289function applySchemaTransforms(originalWrappingSchema, subschemaConfig, transformedSchema, transforms) {
290 return transforms.reduce((schema, transform) => 'transformSchema' in transform ? transform.transformSchema(schema, subschemaConfig, transformedSchema) : schema, originalWrappingSchema);
291}
292function applyRequestTransforms(originalRequest, delegationContext, transformationContext, transforms) {
293 transformationContext.contextMap = transformationContext.contextMap || new WeakMap();
294 const contextMap = transformationContext.contextMap;
295 transforms === null || transforms === void 0 ? void 0 : transforms.forEach(transform => {
296 if (!contextMap.has(transform)) {
297 contextMap.set(transform, {
298 nextIndex: 0,
299 paths: {},
300 });
301 }
302 });
303 return transforms.reduceRight((request, transform) => 'transformRequest' in transform
304 ? transform.transformRequest(request, delegationContext, contextMap.get(transform))
305 : request, originalRequest);
306}
307function applyResultTransforms(originalResult, delegationContext, transformationContext, transforms) {
308 const contextMap = transformationContext.contextMap;
309 return transforms.reduceRight((result, transform) => 'transformResult' in transform
310 ? transform.transformResult(result, delegationContext, contextMap.get(transform))
311 : result, originalResult);
312}
313
314function flatString(str) {
315 return flatstr(str);
316}
317function jsonFlatStringify(data, replacer, space) {
318 return flatString(JSON.stringify(data, replacer, space));
319}
320
321const { stat: stat$1, writeFile: fsWriteFile, readFile: readFile$1, mkdir: fsMkdir } = promises || {};
322async function pathExists(path) {
323 if (!path) {
324 return false;
325 }
326 try {
327 await stat$1(path);
328 return true;
329 }
330 catch (e) {
331 if (e.toString().includes('ENOENT')) {
332 return false;
333 }
334 else {
335 throw e;
336 }
337 }
338}
339function readJSONSync(path) {
340 const fileContent = readFileSync(path, 'utf-8');
341 return JSON.parse(fileContent);
342}
343async function readJSON(path) {
344 const fileContent = await readFile$1(path, 'utf-8');
345 return JSON.parse(fileContent);
346}
347function writeJSON(path, data, replacer, space) {
348 const stringified = jsonFlatStringify(data, replacer, space);
349 return writeFile(path, stringified, 'utf-8');
350}
351const writeFile = async (path, ...args) => {
352 if (typeof path === 'string') {
353 const containingDir = dirname(path);
354 if (!(await pathExists(containingDir))) {
355 await mkdir(containingDir);
356 }
357 }
358 return fsWriteFile(path, ...args);
359};
360async function mkdir(path, options = { recursive: true }) {
361 const ifExists = await pathExists(path);
362 if (!ifExists) {
363 await fsMkdir(path, options);
364 }
365}
366
367const globalLruCache = lru();
368
369const jitExecutorFactory = (schema, prefix) => ({ document, variables, context }, operationName, rootValue) => {
370 const documentStr = print(document);
371 const cacheKey = [prefix, documentStr, operationName].join('_');
372 if (!globalLruCache.has(cacheKey)) {
373 const compiledQuery = compileQuery(schema, document, operationName, {
374 disableLeafSerialization: true,
375 customJSONSerializer: true,
376 });
377 globalLruCache.set(cacheKey, compiledQuery);
378 }
379 const cachedQuery = globalLruCache.get(cacheKey);
380 if (isCompiledQuery(cachedQuery)) {
381 return cachedQuery.query(rootValue, context, variables);
382 }
383 return cachedQuery;
384};
385
386export { ArgType, applyRequestTransforms, applyResultTransforms, applySchemaTransforms, ensureDocumentNode, extractResolvers, flatString, getCachedFetch, getHeadersObject, getInputTypeFromTypeName, getInterpolatedHeadersFactory, getInterpolatedStringFactory, globalLruCache, groupTransforms, jitExecutorFactory, jsonFlatStringify, loadFromModuleExportExpression, loadFromModuleExportExpressionSync, mkdir, parseInterpolationStrings, pathExists, readFileOrUrlWithCache, readFileWithCache, readJSON, readJSONSync, readUrlWithCache, stringInterpolator, withCancel, writeFile, writeJSON };
387//# sourceMappingURL=index.esm.js.map