UNPKG

10.6 kBJavaScriptView Raw
1'use strict';
2
3Object.defineProperty(exports, "__esModule", {
4 value: true
5});
6exports.LatticeLogs = exports.Deferred = exports.joinLines = undefined;
7
8var _asyncToGenerator2 = require('babel-runtime/helpers/asyncToGenerator');
9
10var _asyncToGenerator3 = _interopRequireDefault(_asyncToGenerator2);
11
12var _promise = require('babel-runtime/core-js/promise');
13
14var _promise2 = _interopRequireDefault(_promise);
15
16var _neTagFns = require('ne-tag-fns');
17
18Object.defineProperty(exports, 'joinLines', {
19 enumerable: true,
20 get: function () {
21 return _neTagFns.dedent;
22 }
23});
24exports.promisify = promisify;
25exports.getLatticePrefs = getLatticePrefs;
26
27var _fs = require('fs');
28
29var _fs2 = _interopRequireDefault(_fs);
30
31var _util = require('util');
32
33var _util2 = _interopRequireDefault(_util);
34
35var _neTypes = require('ne-types');
36
37var _readPkgUp = require('read-pkg-up');
38
39var _lodash = require('lodash');
40
41function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
42
43const { Stats } = _fs2.default;
44
45/**
46 * Deferred is modeled after jQuery's deferred object. It inverts a promise
47 * such that its resolve and reject methods can be invoked without wrapping
48 * all of the related code within a Promise's function.
49 *
50 * @memberof utils
51 * @class Deferred
52 */
53let Deferred = exports.Deferred = class Deferred {
54
55 /**
56 * Creates an object with four properties of note; promise, resolve, reject
57 * and a flag complete that will be set once either resolve or reject have
58 * been called. A Deferred is considered to be pending while complete is set
59 * to false.
60 *
61 * Once constructed, resolve and reject can be called later, at which point,
62 * the promise is completed. The promise property is the promise resolved
63 * or rejected by the associated properties and can be used with other
64 * async/await or Promise based code.
65 *
66 * @instance
67 * @memberof Deferred
68 * @method ⎆⠀constructor
69 *
70 * @param {any} resolveWith a deferred resolved as Promise.resolve() might do
71 * @param {any} rejectWith a deferred rejected as Promise.reject() might do
72 */
73
74
75 /**
76 * This is the promise wrapped by and inverted in this deferred instance
77 *
78 * @type {Promise}
79 * @memberof Deferred
80 * @instance
81 */
82
83 /**
84 * This property holds a `resolve` function from within the promise this
85 * deferred inverts.
86 *
87 * @type {Function}
88 * @memberof Deferred
89 * @instance
90 */
91 constructor(resolveWith, rejectWith) {
92 this.promise = new _promise2.default((resolve, reject) => {
93 this.complete = false;
94
95 this.resolve = (...args) => {
96 this.complete = true;
97 return resolve(...args);
98 };
99
100 this.reject = (...args) => {
101 this.complete = true;
102 return reject(...args);
103 };
104
105 if (resolveWith && !rejectWith) {
106 this.resolve(resolveWith);
107 }
108 if (rejectWith && !resolveWith) {
109 this.reject(rejectWith);
110 }
111 });
112 }
113
114 /**
115 * Shorthand getter that denotes true if the deferred is not yet complete.
116 *
117 * @instance
118 * @memberof Deferred
119 * @method ⬇︎⠀pending
120 *
121 * @return {boolean} true if the promise is not yet complete; false otherwise
122 */
123
124
125 /**
126 * An at a glance boolean property that denotes whether or not this
127 * deferred has been resolved or rejected yet.
128 *
129 * @type {boolean}
130 * @memberof Deferred
131 * @instance
132 */
133
134
135 /**
136 * This property holds a `reject` function from within the promise this
137 * deferred inverts
138 *
139 * @type {Function}
140 * @memberof Deferred
141 * @instance
142 */
143 get pending() {
144 return !this.complete;
145 }
146
147 /**
148 * Promises are great but if the code never resolves or rejects a deferred,
149 * then things will become eternal; in a bad way. This makes that less likely
150 * of an event.
151 *
152 * If the number of milliseconds elapses before a resolve or reject occur,
153 * then the deferred is rejected.
154 *
155 * @static
156 * @memberof Deferred
157 * @method ⌾⠀TimedDeferred
158 *
159 * @param {Number} timeOut a number of milliseconds to wait before rejecting
160 * the deferred.
161 * @param {Promise} proxyPromise a promise to proxy then/catch through to the
162 * deferreds resolve/reject.
163 * @return {Deferred} an instance of deferred that will timeout after
164 * `timeOut` milliseconds have elapsed. If `proxyPromise` is a `Promise`
165 * then the deferred's reject and resolve will be tied to the Promise's
166 * catch() and then() methods, respectively.
167 */
168 static TimedDeferred(timeOut, proxyPromise) {
169 const deferred = new Deferred();
170
171 if (proxyPromise && (0, _neTypes.typeOf)(proxyPromise) === _promise2.default.name) {
172 proxyPromise.then((...args) => deferred.resolve(...args));
173 proxyPromise.catch(reason => deferred.reject(reason));
174 }
175
176 setTimeout(() => deferred.reject(new Error('Deferred timed out'), timeOut));
177
178 return deferred;
179 }
180};
181
182/**
183 * A simply promisify style function that returns an async function wrapped
184 * around a supplied function designed for the standard callback methodology.
185 * If the callback is the last parameter, and that callback is in the form of
186 * (error, ...results) then this wrapper will do the trick for you.
187 *
188 * @method utils~⌾⠀promisify
189 * @since 2.7.0
190 *
191 * @param {Function} method a function to wrap in an asynchronous function
192 * @param {mixed} context an optional `this` object for use with the supplied
193 * function.
194 * @return {Function} an asynchronous function, i.e. one that returns a promise
195 * containing the contents the callback results, that wraps the supplied
196 * function.
197 */
198
199function promisify(method, context) {
200 return (() => {
201 var _ref = (0, _asyncToGenerator3.default)(function* (...args) {
202 return new _promise2.default(function (resolve, reject) {
203 args.push(function (error, ...callbackArgs) {
204 if (error) {
205 reject(error);
206 } else {
207 resolve(...callbackArgs);
208 }
209 });
210
211 method.apply(context, args);
212 });
213 });
214
215 return function () {
216 return _ref.apply(this, arguments);
217 };
218 })();
219}
220
221/**
222 * It may be necessary to read GraphQL Lattice preferences from the nearest
223 * `package.json` object to the excuting code. `getLatticePrefs()` does this
224 * and merges any subsequently found options in said file on top of the
225 * default values specified here in this file.
226 *
227 * @method utils~⌾⠀getLatticePrefs
228 * @since 2.13.0
229 *
230 * @return {Object} an object containing at least the defaults plus any other
231 * values specified in `package.json`
232 */
233function getLatticePrefs(readPkgUpOpts) {
234 let { pkg } = (0, _readPkgUp.sync)(readPkgUpOpts);
235 let options = {
236 ModuleParser: {
237 extensions: ['.js', '.jsx', '.ts', '.tsx'],
238 failOnError: false
239 }
240 };
241
242 if (pkg.lattice) {
243 (0, _lodash.merge)(options, pkg.lattice || {});
244 }
245
246 return options;
247}
248
249/**
250 * A small near pass-thru facility for logging within Lattice such that error
251 * objects supplied get mapped to their message unless `LATTICE_ERRORS=STACK`
252 * is set in `process.env`.
253 *
254 * Note the order of log levels for Lattice may be somewhat non-standard. Info
255 * has been taken out of flow and placed above error to solve issues with jest
256 * logging.
257 *
258 * @memberof utils
259 * @type Object
260 * @static
261 */
262const LatticeLogs = exports.LatticeLogs = {
263 get LOG() {
264 return 'log';
265 },
266
267 get WARN() {
268 return 'warn';
269 },
270
271 get ERROR() {
272 return 'error';
273 },
274
275 get INFO() {
276 return 'info';
277 },
278
279 get TRACE() {
280 return 'trace';
281 },
282
283 /**
284 * Ordering of log levels for LatticeLogs. `INFO` is a non error log level
285 * that is non-crucial and appears if LATTICE_LOGLEVEL is set to `INFO` or
286 * `TRACE`
287 */
288 get LEVELS() {
289 const ll = LatticeLogs;
290
291 return [ll.LOG, ll.WARN, ll.ERROR, ll.INFO, ll.TRACE];
292 },
293
294 equalOrBelow(testedLevel, lessThan = 'error') {
295 const ll = LatticeLogs;
296
297 return ll.LEVELS.indexOf(testedLevel) <= ll.LEVELS.indexOf(lessThan);
298 },
299
300 atLeast(testedLevel, atLeastLevel) {
301 const ll = LatticeLogs;
302
303 return ll.LEVELS.indexOf(testedLevel) >= ll.LEVELS.indexOf(atLeastLevel);
304 },
305
306 /**
307 * All arguments of any logging function in `LatticeLogs` get passed through
308 * this function first to modify or alter the type of value being logged.
309 *
310 * @param {mixed} arg the argument being passed to the `map()` function
311 * @param {number} index the index in the array of arguments
312 * @param {Array<mixed>} array the array containing this element
313 */
314 argMapper(arg, index, array) {
315 let isError = (0, _neTypes.typeOf)(arg) === Error.name;
316 let showStack = /\bSTACK\b/i.test(process.env.LATTICE_ERRORS || '');
317
318 // $FlowFixMe
319 return !isError ? arg : showStack ? arg : arg.message;
320 },
321
322 /** A function that, when it returns true, will cause logging to be skipped */
323 failFast(logLevel, lessThan) {
324 const ll = LatticeLogs;
325
326 if (logLevel) {
327 let compareTo = lessThan || process.env.LATTICE_LOGLEVEL || ll.ERROR;
328 if (!ll.equalOrBelow(logLevel, compareTo)) return true;
329 }
330
331 return (/\b(NONE|OFF|NO|0)\b/i.test(process.env.LATTICE_ERRORS || '')
332 );
333 },
334
335 /** Pass-thru to console.log; arguments parsed via `argMapper` */
336 log(...args) {
337 if (LatticeLogs.failFast(LatticeLogs.LOG)) return;
338 console.log(...args.map(LatticeLogs.argMapper));
339 },
340
341 /** Pass-thru to console.warn; arguments parsed via `argMapper` */
342 warn(...args) {
343 if (LatticeLogs.failFast(LatticeLogs.WARN)) return;
344 console.warn(...args.map(LatticeLogs.argMapper));
345 },
346
347 /** Pass-thru to console.error; arguments parsed via `argMapper` */
348 error(...args) {
349 if (LatticeLogs.failFast(LatticeLogs.ERROR)) return;
350 console.error(...args.map(LatticeLogs.argMapper));
351 },
352
353 /** Pass-thru to console.info; arguments parsed via `argMapper` */
354 info(...args) {
355 if (LatticeLogs.failFast(LatticeLogs.INFO)) return;
356 console.info(...args.map(LatticeLogs.argMapper));
357 },
358
359 /** Pass-thru to console.trace; arguments parsed via `argMapper` */
360 trace(...args) {
361 if (LatticeLogs.failFast(LatticeLogs.TRACE)) return;
362 console.trace(...args.map(LatticeLogs.argMapper));
363 },
364
365 outWrite(chunk, encoding, callback) {
366 if (LatticeLogs.failFast(LatticeLogs.LOG)) return;
367 // $FlowFixMe
368 process.stdout.write(chunk, encoding, callback);
369 },
370
371 errWrite(chunk, encoding, callback) {
372 if (LatticeLogs.failFast(LatticeLogs.ERROR)) return;
373 // $FlowFixMe
374 process.stderr.write(chunk, encoding, callback);
375 }
376};
377//# sourceMappingURL=utils.js.map
\No newline at end of file