UNPKG

10.1 kBJavaScriptView Raw
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3exports.CodeFileLoader = void 0;
4const tslib_1 = require("tslib");
5const graphql_1 = require("graphql");
6const utils_1 = require("@graphql-tools/utils");
7const graphql_tag_pluck_1 = require("@graphql-tools/graphql-tag-pluck");
8const globby_1 = tslib_1.__importDefault(require("globby"));
9const unixify_1 = tslib_1.__importDefault(require("unixify"));
10const load_from_module_js_1 = require("./load-from-module.js");
11const path_1 = require("path");
12const process_1 = require("process");
13const fs_1 = require("fs");
14const module_1 = require("module");
15const { readFile, access } = fs_1.promises;
16const FILE_EXTENSIONS = ['.ts', '.tsx', '.js', '.jsx', '.vue', '.svelte'];
17function createGlobbyOptions(options) {
18 return { absolute: true, ...options, ignore: [] };
19}
20const buildIgnoreGlob = (path) => `!${path}`;
21/**
22 * This loader loads GraphQL documents and type definitions from code files
23 * using `graphql-tag-pluck`.
24 *
25 * ```js
26 * const documents = await loadDocuments('queries/*.js', {
27 * loaders: [
28 * new CodeFileLoader()
29 * ]
30 * });
31 * ```
32 *
33 * Supported extensions include: `.ts`, `.tsx`, `.js`, `.jsx`, `.vue`, `.svelte`
34 */
35class CodeFileLoader {
36 constructor(config) {
37 this.config = config !== null && config !== void 0 ? config : {};
38 }
39 getMergedOptions(options) {
40 return { ...this.config, ...options };
41 }
42 async canLoad(pointer, options) {
43 options = this.getMergedOptions(options);
44 if ((0, utils_1.isValidPath)(pointer)) {
45 if (FILE_EXTENSIONS.find(extension => pointer.endsWith(extension))) {
46 const normalizedFilePath = (0, path_1.isAbsolute)(pointer) ? pointer : (0, path_1.resolve)(options.cwd || (0, process_1.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 options = this.getMergedOptions(options);
60 if ((0, utils_1.isValidPath)(pointer)) {
61 if (FILE_EXTENSIONS.find(extension => pointer.endsWith(extension))) {
62 const normalizedFilePath = (0, path_1.isAbsolute)(pointer) ? pointer : (0, path_1.resolve)(options.cwd || (0, process_1.cwd)(), pointer);
63 return (0, fs_1.existsSync)(normalizedFilePath);
64 }
65 }
66 return false;
67 }
68 _buildGlobs(glob, options) {
69 const ignores = (0, utils_1.asArray)(options.ignore || []);
70 const globs = [(0, unixify_1.default)(glob), ...ignores.map(v => buildIgnoreGlob((0, unixify_1.default)(v)))];
71 return globs;
72 }
73 async resolveGlobs(glob, options) {
74 options = this.getMergedOptions(options);
75 const globs = this._buildGlobs(glob, options);
76 return (0, globby_1.default)(globs, createGlobbyOptions(options));
77 }
78 resolveGlobsSync(glob, options) {
79 options = this.getMergedOptions(options);
80 const globs = this._buildGlobs(glob, options);
81 return globby_1.default.sync(globs, createGlobbyOptions(options));
82 }
83 async load(pointer, options) {
84 options = this.getMergedOptions(options);
85 const resolvedPaths = await this.resolveGlobs(pointer, options);
86 const finalResult = [];
87 const errors = [];
88 await Promise.all(resolvedPaths.map(async (path) => {
89 try {
90 const result = await this.handleSinglePath(path, options);
91 result === null || result === void 0 ? void 0 : result.forEach(result => finalResult.push(result));
92 }
93 catch (e) {
94 if (process_1.env['DEBUG']) {
95 console.error(e);
96 }
97 errors.push(e);
98 }
99 }));
100 if (errors.length > 0 && (options.noSilentErrors || finalResult.length === 0)) {
101 if (errors.length === 1) {
102 throw errors[0];
103 }
104 throw new utils_1.AggregateError(errors, `Reading from ${pointer} failed ; \n ` + errors.map((e) => e.message).join('\n'));
105 }
106 return finalResult;
107 }
108 loadSync(pointer, options) {
109 options = this.getMergedOptions(options);
110 const resolvedPaths = this.resolveGlobsSync(pointer, options);
111 const finalResult = [];
112 const errors = [];
113 for (const path of resolvedPaths) {
114 if (this.canLoadSync(path, options)) {
115 try {
116 const result = this.handleSinglePathSync(path, options);
117 result === null || result === void 0 ? void 0 : result.forEach(result => finalResult.push(result));
118 }
119 catch (e) {
120 if (process_1.env['DEBUG']) {
121 console.error(e);
122 }
123 errors.push(e);
124 }
125 }
126 }
127 if (errors.length > 0 && (options.noSilentErrors || finalResult.length === 0)) {
128 if (errors.length === 1) {
129 throw errors[0];
130 }
131 throw new utils_1.AggregateError(errors, `Reading from ${pointer} failed ; \n ` + errors.map((e) => e.message).join('\n'));
132 }
133 return finalResult;
134 }
135 async handleSinglePath(location, options) {
136 if (!(await this.canLoad(location, options))) {
137 return [];
138 }
139 options = this.getMergedOptions(options);
140 const normalizedFilePath = ensureAbsolutePath(location, options);
141 const errors = [];
142 if (!options.noPluck) {
143 try {
144 const content = await readFile(normalizedFilePath, { encoding: 'utf-8' });
145 const sources = await (0, graphql_tag_pluck_1.gqlPluckFromCodeString)(normalizedFilePath, content, options.pluckConfig);
146 if (sources.length) {
147 return sources.map(source => ({
148 rawSDL: source.body,
149 document: (0, graphql_1.parse)(source),
150 location,
151 }));
152 }
153 }
154 catch (e) {
155 if (process_1.env['DEBUG']) {
156 console.error(`Failed to load schema from code file "${normalizedFilePath}": ${e.message}`);
157 }
158 errors.push(e);
159 }
160 }
161 if (!options.noRequire) {
162 try {
163 if (options && options.require) {
164 await Promise.all((0, utils_1.asArray)(options.require).map(m => Promise.resolve().then(() => tslib_1.__importStar(require(m)))));
165 }
166 const loaded = await (0, load_from_module_js_1.tryToLoadFromExport)(normalizedFilePath);
167 const sources = (0, utils_1.asArray)(loaded)
168 .map(value => resolveSource(location, value, options))
169 .filter(Boolean);
170 if (sources.length) {
171 return sources;
172 }
173 }
174 catch (e) {
175 errors.push(e);
176 }
177 }
178 if (errors.length > 0) {
179 throw errors[0];
180 }
181 return [];
182 }
183 handleSinglePathSync(location, options) {
184 if (!this.canLoadSync(location, options)) {
185 return [];
186 }
187 options = this.getMergedOptions(options);
188 const normalizedFilePath = ensureAbsolutePath(location, options);
189 const errors = [];
190 if (!options.noPluck) {
191 try {
192 const content = (0, fs_1.readFileSync)(normalizedFilePath, { encoding: 'utf-8' });
193 const sources = (0, graphql_tag_pluck_1.gqlPluckFromCodeStringSync)(normalizedFilePath, content, options.pluckConfig);
194 if (sources.length) {
195 return sources.map(source => ({
196 rawSDL: source.body,
197 document: (0, graphql_1.parse)(source),
198 location,
199 }));
200 }
201 }
202 catch (e) {
203 if (process_1.env['DEBUG']) {
204 console.error(`Failed to load schema from code file "${normalizedFilePath}": ${e.message}`);
205 }
206 errors.push(e);
207 }
208 }
209 if (!options.noRequire) {
210 try {
211 if (options && options.require) {
212 const cwdRequire = (0, module_1.createRequire)(options.cwd || (0, process_1.cwd)());
213 for (const m of (0, utils_1.asArray)(options.require)) {
214 cwdRequire(m);
215 }
216 }
217 const loaded = (0, load_from_module_js_1.tryToLoadFromExportSync)(normalizedFilePath);
218 const sources = (0, utils_1.asArray)(loaded)
219 .map(value => resolveSource(location, value, options))
220 .filter(Boolean);
221 if (sources.length) {
222 return sources;
223 }
224 }
225 catch (e) {
226 errors.push(e);
227 }
228 }
229 if (errors.length > 0) {
230 throw errors[0];
231 }
232 return null;
233 }
234}
235exports.CodeFileLoader = CodeFileLoader;
236function resolveSource(pointer, value, options) {
237 if (typeof value === 'string') {
238 return (0, utils_1.parseGraphQLSDL)(pointer, value, options);
239 }
240 else if ((0, graphql_1.isSchema)(value)) {
241 return {
242 location: pointer,
243 schema: value,
244 };
245 }
246 else if ((0, utils_1.isDocumentNode)(value)) {
247 return {
248 location: pointer,
249 document: value,
250 };
251 }
252 return null;
253}
254function ensureAbsolutePath(pointer, options) {
255 return (0, path_1.isAbsolute)(pointer) ? pointer : (0, path_1.resolve)(options.cwd || (0, process_1.cwd)(), pointer);
256}