UNPKG

4.3 kBJavaScriptView Raw
1import { isValidPath, asArray, parseGraphQLSDL } from '@graphql-tools/utils';
2import { isAbsolute, resolve } from 'path';
3import { existsSync, readFileSync, promises } from 'fs';
4import { cwd } from 'process';
5import { processImport } from '@graphql-tools/import';
6import globby from 'globby';
7import unixify from 'unixify';
8
9const { readFile, access } = promises;
10const FILE_EXTENSIONS = ['.gql', '.gqls', '.graphql', '.graphqls'];
11function isGraphQLImportFile(rawSDL) {
12 const trimmedRawSDL = rawSDL.trim();
13 return trimmedRawSDL.startsWith('# import') || trimmedRawSDL.startsWith('#import');
14}
15function createGlobbyOptions(options) {
16 return { absolute: true, ...options, ignore: [] };
17}
18const buildIgnoreGlob = (path) => `!${path}`;
19/**
20 * This loader loads documents and type definitions from `.graphql` files.
21 *
22 * You can load a single source:
23 *
24 * ```js
25 * const schema = await loadSchema('schema.graphql', {
26 * loaders: [
27 * new GraphQLFileLoader()
28 * ]
29 * });
30 * ```
31 *
32 * Or provide a glob pattern to load multiple sources:
33 *
34 * ```js
35 * const schema = await loadSchema('graphql/*.graphql', {
36 * loaders: [
37 * new GraphQLFileLoader()
38 * ]
39 * });
40 * ```
41 */
42class GraphQLFileLoader {
43 async canLoad(pointer, options) {
44 if (isValidPath(pointer)) {
45 if (FILE_EXTENSIONS.find(extension => pointer.endsWith(extension))) {
46 const normalizedFilePath = isAbsolute(pointer) ? pointer : resolve(options.cwd || cwd(), pointer);
47 try {
48 await access(normalizedFilePath);
49 return true;
50 }
51 catch (_a) {
52 return false;
53 }
54 }
55 }
56 return false;
57 }
58 canLoadSync(pointer, options) {
59 if (isValidPath(pointer)) {
60 if (FILE_EXTENSIONS.find(extension => pointer.endsWith(extension))) {
61 const normalizedFilePath = isAbsolute(pointer) ? pointer : resolve(options.cwd || cwd(), pointer);
62 return existsSync(normalizedFilePath);
63 }
64 }
65 return false;
66 }
67 _buildGlobs(glob, options) {
68 const ignores = asArray(options.ignore || []);
69 const globs = [unixify(glob), ...ignores.map(v => buildIgnoreGlob(unixify(v)))];
70 return globs;
71 }
72 async resolveGlobs(glob, options) {
73 const globs = this._buildGlobs(glob, options);
74 const result = await globby(globs, createGlobbyOptions(options));
75 return result;
76 }
77 resolveGlobsSync(glob, options) {
78 const globs = this._buildGlobs(glob, options);
79 const result = globby.sync(globs, createGlobbyOptions(options));
80 return result;
81 }
82 async load(pointer, options) {
83 const resolvedPaths = await this.resolveGlobs(pointer, options);
84 const finalResult = [];
85 await Promise.all(resolvedPaths.map(async (path) => {
86 if (await this.canLoad(path, options)) {
87 const normalizedFilePath = isAbsolute(path) ? path : resolve(options.cwd || cwd(), path);
88 const rawSDL = await readFile(normalizedFilePath, { encoding: 'utf8' });
89 finalResult.push(this.handleFileContent(rawSDL, normalizedFilePath, options));
90 }
91 }));
92 return finalResult;
93 }
94 loadSync(pointer, options) {
95 const resolvedPaths = this.resolveGlobsSync(pointer, options);
96 const finalResult = [];
97 for (const path of resolvedPaths) {
98 if (this.canLoadSync(path, options)) {
99 const normalizedFilePath = isAbsolute(path) ? path : resolve(options.cwd || cwd(), path);
100 const rawSDL = readFileSync(normalizedFilePath, { encoding: 'utf8' });
101 finalResult.push(this.handleFileContent(rawSDL, normalizedFilePath, options));
102 }
103 }
104 return finalResult;
105 }
106 handleFileContent(rawSDL, pointer, options) {
107 if (!options.skipGraphQLImport && isGraphQLImportFile(rawSDL)) {
108 const document = processImport(pointer, options.cwd);
109 return {
110 location: pointer,
111 document,
112 };
113 }
114 return parseGraphQLSDL(pointer, rawSDL, options);
115 }
116}
117
118export { GraphQLFileLoader };