UNPKG

7.53 kBJavaScriptView Raw
1/**
2 * Copyright (c) Facebook, Inc. and its affiliates.
3 *
4 * This source code is licensed under the MIT license found in the
5 * LICENSE file in the root directory of this source tree.
6 *
7 *
8 * @format
9 */
10'use strict';
11
12var _asyncToGenerator = require("@babel/runtime/helpers/asyncToGenerator");
13
14var SUBSCRIPTION_NAME = 'graphql-codegen';
15var QUERY_RETRIES = 3;
16
17function queryFiles(_x, _x2, _x3) {
18 return _queryFiles.apply(this, arguments);
19}
20
21function _queryFiles() {
22 _queryFiles = _asyncToGenerator(function* (baseDir, expression, filter) {
23 return yield require("./GraphQLCompilerProfiler").waitFor('Watchman:query',
24 /*#__PURE__*/
25 _asyncToGenerator(function* () {
26 var client = new (require("./GraphQLWatchmanClient"))(QUERY_RETRIES);
27
28 var _ref = yield Promise.all([client.watchProject(baseDir), getFields(client)]),
29 watchResp = _ref[0],
30 fields = _ref[1];
31
32 var resp = yield client.command('query', watchResp.root, {
33 expression: expression,
34 fields: fields,
35 relative_root: watchResp.relativePath
36 });
37 client.end();
38 return updateFiles(new Set(), baseDir, filter, resp.files);
39 }));
40 });
41 return _queryFiles.apply(this, arguments);
42}
43
44function queryDirectories(_x4, _x5) {
45 return _queryDirectories.apply(this, arguments);
46}
47
48function _queryDirectories() {
49 _queryDirectories = _asyncToGenerator(function* (baseDir, expression) {
50 return yield require("./GraphQLCompilerProfiler").waitFor('Watchman:query',
51 /*#__PURE__*/
52 _asyncToGenerator(function* () {
53 var client = new (require("./GraphQLWatchmanClient"))();
54 var watchResp = yield client.watchProject(baseDir);
55 var resp = yield client.command('query', watchResp.root, {
56 expression: expression,
57 fields: ['name'],
58 relative_root: watchResp.relativePath
59 });
60 client.end();
61 return resp.files;
62 }));
63 });
64 return _queryDirectories.apply(this, arguments);
65}
66
67function getFields(_x6) {
68 return _getFields.apply(this, arguments);
69} // For use when not using Watchman.
70
71
72function _getFields() {
73 _getFields = _asyncToGenerator(function* (client) {
74 var fields = ['name', 'exists'];
75
76 if (yield client.hasCapability('field-content.sha1hex')) {
77 fields.push('content.sha1hex');
78 }
79
80 return fields;
81 });
82 return _getFields.apply(this, arguments);
83}
84
85function queryFilepaths(_x7, _x8, _x9) {
86 return _queryFilepaths.apply(this, arguments);
87}
88/**
89 * Provides a simplified API to the watchman API.
90 * Given some base directory and a list of subdirectories it calls the callback
91 * with watchman change events on file changes.
92 */
93
94
95function _queryFilepaths() {
96 _queryFilepaths = _asyncToGenerator(function* (baseDir, filepaths, filter) {
97 // Construct WatchmanChange objects as an intermediate step before
98 // calling updateFiles to produce file content.
99 var files = filepaths.map(function (filepath) {
100 return {
101 name: filepath,
102 exists: true,
103 'content.sha1hex': null
104 };
105 });
106 return updateFiles(new Set(), baseDir, filter, files);
107 });
108 return _queryFilepaths.apply(this, arguments);
109}
110
111function watch(_x10, _x11, _x12) {
112 return _watch.apply(this, arguments);
113}
114
115function _watch() {
116 _watch = _asyncToGenerator(function* (baseDir, expression, callback) {
117 return yield require("./GraphQLCompilerProfiler").waitFor('Watchman:subscribe',
118 /*#__PURE__*/
119 _asyncToGenerator(function* () {
120 var client = new (require("./GraphQLWatchmanClient"))();
121 var watchResp = yield client.watchProject(baseDir);
122 yield makeSubscription(client, watchResp.root, watchResp.relativePath, expression, callback);
123 }));
124 });
125 return _watch.apply(this, arguments);
126}
127
128function makeSubscription(_x13, _x14, _x15, _x16, _x17) {
129 return _makeSubscription.apply(this, arguments);
130}
131/**
132 * Further simplifies `watch` and calls the callback on every change with a
133 * full list of files that match the conditions.
134 */
135
136
137function _makeSubscription() {
138 _makeSubscription = _asyncToGenerator(function* (client, root, relativePath, expression, callback) {
139 client.on('subscription', function (resp) {
140 if (resp.subscription === SUBSCRIPTION_NAME) {
141 callback(resp);
142 }
143 });
144 var fields = yield getFields(client);
145 yield client.command('subscribe', root, SUBSCRIPTION_NAME, {
146 expression: expression,
147 fields: fields,
148 relative_root: relativePath
149 });
150 });
151 return _makeSubscription.apply(this, arguments);
152}
153
154function watchFiles(_x18, _x19, _x20, _x21) {
155 return _watchFiles.apply(this, arguments);
156}
157/**
158 * Similar to watchFiles, but takes an async function. The `compile` function
159 * is awaited and not called in parallel. If multiple changes are triggered
160 * before a compile finishes, the latest version is called after the compile
161 * finished.
162 *
163 * TODO: Consider changing from a Promise to abortable, so we can abort mid
164 * compilation.
165 */
166
167
168function _watchFiles() {
169 _watchFiles = _asyncToGenerator(function* (baseDir, expression, filter, callback) {
170 var files = new Set();
171 yield watch(baseDir, expression, function (changes) {
172 if (!changes.files) {
173 // Watchmen fires a change without files when a watchman state changes,
174 // for example during an hg update.
175 return;
176 }
177
178 files = updateFiles(files, baseDir, filter, changes.files);
179 callback(files);
180 });
181 });
182 return _watchFiles.apply(this, arguments);
183}
184
185function watchCompile(_x22, _x23, _x24, _x25) {
186 return _watchCompile.apply(this, arguments);
187}
188
189function _watchCompile() {
190 _watchCompile = _asyncToGenerator(function* (baseDir, expression, filter, compile) {
191 var compiling = false;
192 var needsCompiling = false;
193 var latestFiles = null;
194 watchFiles(baseDir, expression, filter,
195 /*#__PURE__*/
196 function () {
197 var _ref5 = _asyncToGenerator(function* (files) {
198 needsCompiling = true;
199 latestFiles = files;
200
201 if (compiling) {
202 return;
203 }
204
205 compiling = true;
206
207 while (needsCompiling) {
208 needsCompiling = false;
209 yield compile(latestFiles);
210 }
211
212 compiling = false;
213 });
214
215 return function (_x26) {
216 return _ref5.apply(this, arguments);
217 };
218 }());
219 });
220 return _watchCompile.apply(this, arguments);
221}
222
223function updateFiles(files, baseDir, filter, fileChanges) {
224 var fileMap = new Map();
225 files.forEach(function (file) {
226 file.exists && fileMap.set(file.relPath, file);
227 });
228 fileChanges.forEach(function (_ref2) {
229 var name = _ref2.name,
230 exists = _ref2.exists,
231 hash = _ref2['content.sha1hex'];
232 var shouldRemove = !exists;
233
234 if (!shouldRemove) {
235 var _file = {
236 exists: true,
237 relPath: name,
238 hash: hash || hashFile(require("path").join(baseDir, name))
239 };
240
241 if (filter(_file)) {
242 fileMap.set(name, _file);
243 } else {
244 shouldRemove = true;
245 }
246 }
247
248 shouldRemove && fileMap.set(name, {
249 exists: false,
250 relPath: name
251 });
252 });
253 return new Set(fileMap.values());
254}
255
256function hashFile(filename) {
257 var content = require("fs").readFileSync(filename);
258
259 return require("crypto").createHash('sha1').update(content).digest('hex');
260}
261
262module.exports = {
263 queryDirectories: queryDirectories,
264 queryFiles: queryFiles,
265 queryFilepaths: queryFilepaths,
266 watch: watch,
267 watchFiles: watchFiles,
268 watchCompile: watchCompile
269};
\No newline at end of file