1 | "use strict";
|
2 | Object.defineProperty(exports, "__esModule", { value: true });
|
3 | exports.CodeFileLoader = void 0;
|
4 | const tslib_1 = require("tslib");
|
5 | const graphql_1 = require("graphql");
|
6 | const utils_1 = require("@graphql-tools/utils");
|
7 | const graphql_tag_pluck_1 = require("@graphql-tools/graphql-tag-pluck");
|
8 | const globby_1 = tslib_1.__importDefault(require("globby"));
|
9 | const unixify_1 = tslib_1.__importDefault(require("unixify"));
|
10 | const load_from_module_js_1 = require("./load-from-module.js");
|
11 | const path_1 = require("path");
|
12 | const process_1 = require("process");
|
13 | const fs_1 = require("fs");
|
14 | const module_1 = require("module");
|
15 | const { readFile, access } = fs_1.promises;
|
16 | const FILE_EXTENSIONS = ['.ts', '.tsx', '.js', '.jsx', '.vue', '.svelte'];
|
17 | function createGlobbyOptions(options) {
|
18 | return { absolute: true, ...options, ignore: [] };
|
19 | }
|
20 | const buildIgnoreGlob = (path) => `!${path}`;
|
21 |
|
22 |
|
23 |
|
24 |
|
25 |
|
26 |
|
27 |
|
28 |
|
29 |
|
30 |
|
31 |
|
32 |
|
33 |
|
34 |
|
35 | class 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 | }
|
235 | exports.CodeFileLoader = CodeFileLoader;
|
236 | function 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 | }
|
254 | function ensureAbsolutePath(pointer, options) {
|
255 | return (0, path_1.isAbsolute)(pointer) ? pointer : (0, path_1.resolve)(options.cwd || (0, process_1.cwd)(), pointer);
|
256 | }
|