1 | import { isValidPath, asArray, AggregateError, parseGraphQLJSON } from '@graphql-tools/utils';
|
2 | import { isAbsolute, resolve } from 'path';
|
3 | import { existsSync, readFileSync, promises } from 'fs';
|
4 | import { cwd, env } from 'process';
|
5 | import globby from 'globby';
|
6 | import unixify from 'unixify';
|
7 |
|
8 | const { readFile, access } = promises;
|
9 | const FILE_EXTENSIONS = ['.json'];
|
10 | function createGlobbyOptions(options) {
|
11 | return { absolute: true, ...options, ignore: [] };
|
12 | }
|
13 | const buildIgnoreGlob = (path) => `!${path}`;
|
14 |
|
15 |
|
16 |
|
17 |
|
18 |
|
19 |
|
20 |
|
21 |
|
22 |
|
23 |
|
24 |
|
25 |
|
26 |
|
27 |
|
28 |
|
29 |
|
30 |
|
31 |
|
32 |
|
33 |
|
34 |
|
35 |
|
36 |
|
37 | class JsonFileLoader {
|
38 | async canLoad(pointer, options) {
|
39 | if (isValidPath(pointer)) {
|
40 | if (FILE_EXTENSIONS.find(extension => pointer.endsWith(extension))) {
|
41 | const normalizedFilePath = isAbsolute(pointer) ? pointer : resolve(options.cwd || cwd(), pointer);
|
42 | try {
|
43 | await access(normalizedFilePath);
|
44 | return true;
|
45 | }
|
46 | catch (_a) {
|
47 | return false;
|
48 | }
|
49 | }
|
50 | }
|
51 | return false;
|
52 | }
|
53 | canLoadSync(pointer, options) {
|
54 | if (isValidPath(pointer)) {
|
55 | if (FILE_EXTENSIONS.find(extension => pointer.endsWith(extension))) {
|
56 | const normalizedFilePath = isAbsolute(pointer) ? pointer : resolve(options.cwd || cwd(), pointer);
|
57 | return existsSync(normalizedFilePath);
|
58 | }
|
59 | }
|
60 | return false;
|
61 | }
|
62 | _buildGlobs(glob, options) {
|
63 | const ignores = asArray(options.ignore || []);
|
64 | const globs = [unixify(glob), ...ignores.map(v => buildIgnoreGlob(unixify(v)))];
|
65 | return globs;
|
66 | }
|
67 | async resolveGlobs(glob, options) {
|
68 | const globs = this._buildGlobs(glob, options);
|
69 | const result = await globby(globs, createGlobbyOptions(options));
|
70 | return result;
|
71 | }
|
72 | resolveGlobsSync(glob, options) {
|
73 | const globs = this._buildGlobs(glob, options);
|
74 | const result = globby.sync(globs, createGlobbyOptions(options));
|
75 | return result;
|
76 | }
|
77 | async load(pointer, options) {
|
78 | const resolvedPaths = await this.resolveGlobs(pointer, options);
|
79 | const finalResult = [];
|
80 | const errors = [];
|
81 | await Promise.all(resolvedPaths.map(async (path) => {
|
82 | if (await this.canLoad(path, options)) {
|
83 | try {
|
84 | const normalizedFilePath = isAbsolute(path) ? path : resolve(options.cwd || cwd(), path);
|
85 | const rawSDL = await readFile(normalizedFilePath, { encoding: 'utf8' });
|
86 | finalResult.push(this.handleFileContent(normalizedFilePath, rawSDL, options));
|
87 | }
|
88 | catch (e) {
|
89 | if (env['DEBUG']) {
|
90 | console.error(e);
|
91 | }
|
92 | errors.push(e);
|
93 | }
|
94 | }
|
95 | }));
|
96 | if (errors.length > 0 && (options.noSilentErrors || finalResult.length === 0)) {
|
97 | if (errors.length === 1) {
|
98 | throw errors[0];
|
99 | }
|
100 | throw new AggregateError(errors, `Reading from ${pointer} failed ; \n ` + errors.map((e) => e.message).join('\n'));
|
101 | }
|
102 | return finalResult;
|
103 | }
|
104 | loadSync(pointer, options) {
|
105 | const resolvedPaths = this.resolveGlobsSync(pointer, options);
|
106 | const finalResult = [];
|
107 | const errors = [];
|
108 | for (const path of resolvedPaths) {
|
109 | if (this.canLoadSync(path, options)) {
|
110 | try {
|
111 | const normalizedFilePath = isAbsolute(path) ? path : resolve(options.cwd || cwd(), path);
|
112 | const rawSDL = readFileSync(normalizedFilePath, { encoding: 'utf8' });
|
113 | finalResult.push(this.handleFileContent(normalizedFilePath, rawSDL, options));
|
114 | }
|
115 | catch (e) {
|
116 | if (env['DEBUG']) {
|
117 | console.error(e);
|
118 | }
|
119 | errors.push(e);
|
120 | }
|
121 | }
|
122 | }
|
123 | if (errors.length > 0 && (options.noSilentErrors || finalResult.length === 0)) {
|
124 | if (errors.length === 1) {
|
125 | throw errors[0];
|
126 | }
|
127 | throw new AggregateError(errors, `Reading from ${pointer} failed ; \n ` + errors.map((e) => e.message).join('\n'));
|
128 | }
|
129 | return finalResult;
|
130 | }
|
131 | handleFileContent(normalizedFilePath, rawSDL, options) {
|
132 | try {
|
133 | return parseGraphQLJSON(normalizedFilePath, rawSDL, options);
|
134 | }
|
135 | catch (e) {
|
136 | throw new Error(`Unable to read JSON file: ${normalizedFilePath}: ${e.message || /* istanbul ignore next */ e}`);
|
137 | }
|
138 | }
|
139 | }
|
140 |
|
141 | export { JsonFileLoader };
|