react-zutils 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of react-zutils might be problematic. Click here for more details.

@@ -0,0 +1,156 @@
1
+ /**
2
+ * Copyright (c) 2015-present, Facebook, Inc.
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
+ 'use strict';
9
+
10
+ var fs = require('fs');
11
+ var path = require('path');
12
+ var chalk = require('chalk');
13
+ var filesize = require('filesize');
14
+ var recursive = require('recursive-readdir');
15
+ var stripAnsi = require('strip-ansi');
16
+ var gzipSize = require('gzip-size').sync;
17
+
18
+ function canReadAsset(asset) {
19
+ return (
20
+ /\.(js|css)$/.test(asset) &&
21
+ !/service-worker\.js/.test(asset) &&
22
+ !/precache-manifest\.[0-9a-f]+\.js/.test(asset)
23
+ );
24
+ }
25
+
26
+ // Prints a detailed summary of build files.
27
+ function printFileSizesAfterBuild(
28
+ webpackStats,
29
+ previousSizeMap,
30
+ buildFolder,
31
+ maxBundleGzipSize,
32
+ maxChunkGzipSize
33
+ ) {
34
+ var root = previousSizeMap.root;
35
+ var sizes = previousSizeMap.sizes;
36
+ var assets = (webpackStats.stats || [webpackStats])
37
+ .map(stats =>
38
+ stats
39
+ .toJson({ all: false, assets: true })
40
+ .assets.filter(asset => canReadAsset(asset.name))
41
+ .map(asset => {
42
+ var fileContents = fs.readFileSync(path.join(root, asset.name));
43
+ var size = gzipSize(fileContents);
44
+ var previousSize = sizes[removeFileNameHash(root, asset.name)];
45
+ var difference = getDifferenceLabel(size, previousSize);
46
+ return {
47
+ folder: path.join(
48
+ path.basename(buildFolder),
49
+ path.dirname(asset.name)
50
+ ),
51
+ name: path.basename(asset.name),
52
+ size: size,
53
+ sizeLabel:
54
+ filesize(size) + (difference ? ' (' + difference + ')' : ''),
55
+ };
56
+ })
57
+ )
58
+ .reduce((single, all) => all.concat(single), []);
59
+ assets.sort((a, b) => b.size - a.size);
60
+ var longestSizeLabelLength = Math.max.apply(
61
+ null,
62
+ assets.map(a => stripAnsi(a.sizeLabel).length)
63
+ );
64
+ var suggestBundleSplitting = false;
65
+ assets.forEach(asset => {
66
+ var sizeLabel = asset.sizeLabel;
67
+ var sizeLength = stripAnsi(sizeLabel).length;
68
+ if (sizeLength < longestSizeLabelLength) {
69
+ var rightPadding = ' '.repeat(longestSizeLabelLength - sizeLength);
70
+ sizeLabel += rightPadding;
71
+ }
72
+ var isMainBundle = asset.name.indexOf('main.') === 0;
73
+ var maxRecommendedSize = isMainBundle
74
+ ? maxBundleGzipSize
75
+ : maxChunkGzipSize;
76
+ var isLarge = maxRecommendedSize && asset.size > maxRecommendedSize;
77
+ if (isLarge && path.extname(asset.name) === '.js') {
78
+ suggestBundleSplitting = true;
79
+ }
80
+ console.log(
81
+ ' ' +
82
+ (isLarge ? chalk.yellow(sizeLabel) : sizeLabel) +
83
+ ' ' +
84
+ chalk.dim(asset.folder + path.sep) +
85
+ chalk.cyan(asset.name)
86
+ );
87
+ });
88
+ if (suggestBundleSplitting) {
89
+ console.log();
90
+ console.log(
91
+ chalk.yellow('The bundle size is significantly larger than recommended.')
92
+ );
93
+ console.log(
94
+ chalk.yellow(
95
+ 'Consider reducing it with code splitting: https://goo.gl/9VhYWB'
96
+ )
97
+ );
98
+ console.log(
99
+ chalk.yellow(
100
+ 'You can also analyze the project dependencies: https://goo.gl/LeUzfb'
101
+ )
102
+ );
103
+ }
104
+ }
105
+
106
+ function removeFileNameHash(buildFolder, fileName) {
107
+ return fileName
108
+ .replace(buildFolder, '')
109
+ .replace(/\\/g, '/')
110
+ .replace(
111
+ /\/?(.*)(\.[0-9a-f]+)(\.chunk)?(\.js|\.css)/,
112
+ (match, p1, p2, p3, p4) => p1 + p4
113
+ );
114
+ }
115
+
116
+ // Input: 1024, 2048
117
+ // Output: "(+1 KB)"
118
+ function getDifferenceLabel(currentSize, previousSize) {
119
+ var FIFTY_KILOBYTES = 1024 * 50;
120
+ var difference = currentSize - previousSize;
121
+ var fileSize = !Number.isNaN(difference) ? filesize(difference) : 0;
122
+ if (difference >= FIFTY_KILOBYTES) {
123
+ return chalk.red('+' + fileSize);
124
+ } else if (difference < FIFTY_KILOBYTES && difference > 0) {
125
+ return chalk.yellow('+' + fileSize);
126
+ } else if (difference < 0) {
127
+ return chalk.green(fileSize);
128
+ } else {
129
+ return '';
130
+ }
131
+ }
132
+
133
+ function measureFileSizesBeforeBuild(buildFolder) {
134
+ return new Promise(resolve => {
135
+ recursive(buildFolder, (err, fileNames) => {
136
+ var sizes;
137
+ if (!err && fileNames) {
138
+ sizes = fileNames.filter(canReadAsset).reduce((memo, fileName) => {
139
+ var contents = fs.readFileSync(fileName);
140
+ var key = removeFileNameHash(buildFolder, fileName);
141
+ memo[key] = gzipSize(contents);
142
+ return memo;
143
+ }, {});
144
+ }
145
+ resolve({
146
+ root: buildFolder,
147
+ sizes: sizes || {},
148
+ });
149
+ });
150
+ });
151
+ }
152
+
153
+ module.exports = {
154
+ measureFileSizesBeforeBuild: measureFileSizesBeforeBuild,
155
+ printFileSizesAfterBuild: printFileSizesAfterBuild,
156
+ };
package/README.md ADDED
@@ -0,0 +1,8 @@
1
+ # My Node Library
2
+
3
+ A simple Node.js library.
4
+
5
+ ## Installation
6
+
7
+ ```sh
8
+ npm install react-zutils
@@ -0,0 +1,500 @@
1
+ /**
2
+ * Copyright (c) 2015-present, Facebook, Inc.
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
+ 'use strict';
8
+
9
+ const address = require('address');
10
+ const fs = require('fs');
11
+ const path = require('path');
12
+ const url = require('url');
13
+ const chalk = require('chalk');
14
+ const detect = require('detect-port-alt');
15
+ const isRoot = require('is-root');
16
+ const prompts = require('prompts');
17
+ const clearConsole = require('./clearConsole');
18
+ const formatWebpackMessages = require('./formatWebpackMessages');
19
+ const getProcessForPort = require('./getProcessForPort');
20
+ const typescriptFormatter = require('./typescriptFormatter');
21
+ const forkTsCheckerWebpackPlugin = require('./ForkTsCheckerWebpackPlugin');
22
+
23
+ const isInteractive = process.stdout.isTTY;
24
+
25
+ function prepareUrls(protocol, host, port, pathname = '/') {
26
+ const formatUrl = hostname =>
27
+ url.format({
28
+ protocol,
29
+ hostname,
30
+ port,
31
+ pathname,
32
+ });
33
+ const prettyPrintUrl = hostname =>
34
+ url.format({
35
+ protocol,
36
+ hostname,
37
+ port: chalk.bold(port),
38
+ pathname,
39
+ });
40
+
41
+ const isUnspecifiedHost = host === '0.0.0.0' || host === '::';
42
+ let prettyHost, lanUrlForConfig, lanUrlForTerminal;
43
+ if (isUnspecifiedHost) {
44
+ prettyHost = 'localhost';
45
+ try {
46
+ // This can only return an IPv4 address
47
+ lanUrlForConfig = address.ip();
48
+ if (lanUrlForConfig) {
49
+ // Check if the address is a private ip
50
+ // https://en.wikipedia.org/wiki/Private_network#Private_IPv4_address_spaces
51
+ if (
52
+ /^10[.]|^172[.](1[6-9]|2[0-9]|3[0-1])[.]|^192[.]168[.]/.test(
53
+ lanUrlForConfig
54
+ )
55
+ ) {
56
+ // Address is private, format it for later use
57
+ lanUrlForTerminal = prettyPrintUrl(lanUrlForConfig);
58
+ } else {
59
+ // Address is not private, so we will discard it
60
+ lanUrlForConfig = undefined;
61
+ }
62
+ }
63
+ } catch (_e) {
64
+ // ignored
65
+ }
66
+ } else {
67
+ prettyHost = host;
68
+ }
69
+ const localUrlForTerminal = prettyPrintUrl(prettyHost);
70
+ const localUrlForBrowser = formatUrl(prettyHost);
71
+ return {
72
+ lanUrlForConfig,
73
+ lanUrlForTerminal,
74
+ localUrlForTerminal,
75
+ localUrlForBrowser,
76
+ };
77
+ }
78
+
79
+ function printInstructions(appName, urls, useYarn) {
80
+ console.log();
81
+ console.log(`You can now view ${chalk.bold(appName)} in the browser.`);
82
+ console.log();
83
+
84
+ if (urls.lanUrlForTerminal) {
85
+ console.log(
86
+ ` ${chalk.bold('Local:')} ${urls.localUrlForTerminal}`
87
+ );
88
+ console.log(
89
+ ` ${chalk.bold('On Your Network:')} ${urls.lanUrlForTerminal}`
90
+ );
91
+ } else {
92
+ console.log(` ${urls.localUrlForTerminal}`);
93
+ }
94
+
95
+ console.log();
96
+ console.log('Note that the development build is not optimized.');
97
+ console.log(
98
+ `To create a production build, use ` +
99
+ `${chalk.cyan(`${useYarn ? 'yarn' : 'npm run'} build`)}.`
100
+ );
101
+ console.log();
102
+ }
103
+
104
+ function createCompiler({
105
+ appName,
106
+ config,
107
+ devSocket,
108
+ urls,
109
+ useYarn,
110
+ useTypeScript,
111
+ tscCompileOnError,
112
+ webpack,
113
+ }) {
114
+ // "Compiler" is a low-level interface to webpack.
115
+ // It lets us listen to some events and provide our own custom messages.
116
+ let compiler;
117
+ try {
118
+ compiler = webpack(config);
119
+ } catch (err) {
120
+ console.log(chalk.red('Failed to compile.'));
121
+ console.log();
122
+ console.log(err.message || err);
123
+ console.log();
124
+ process.exit(1);
125
+ }
126
+
127
+ // "invalid" event fires when you have changed a file, and webpack is
128
+ // recompiling a bundle. WebpackDevServer takes care to pause serving the
129
+ // bundle, so if you refresh, it'll wait instead of serving the old one.
130
+ // "invalid" is short for "bundle invalidated", it doesn't imply any errors.
131
+ compiler.hooks.invalid.tap('invalid', () => {
132
+ if (isInteractive) {
133
+ clearConsole();
134
+ }
135
+ console.log('Compiling...');
136
+ });
137
+
138
+ let isFirstCompile = true;
139
+ let tsMessagesPromise;
140
+ let tsMessagesResolver;
141
+
142
+ if (useTypeScript) {
143
+ compiler.hooks.beforeCompile.tap('beforeCompile', () => {
144
+ tsMessagesPromise = new Promise(resolve => {
145
+ tsMessagesResolver = msgs => resolve(msgs);
146
+ });
147
+ });
148
+
149
+ forkTsCheckerWebpackPlugin
150
+ .getCompilerHooks(compiler)
151
+ .receive.tap('afterTypeScriptCheck', (diagnostics, lints) => {
152
+ const allMsgs = [...diagnostics, ...lints];
153
+ const format = message =>
154
+ `${message.file}\n${typescriptFormatter(message, true)}`;
155
+
156
+ tsMessagesResolver({
157
+ errors: allMsgs.filter(msg => msg.severity === 'error').map(format),
158
+ warnings: allMsgs
159
+ .filter(msg => msg.severity === 'warning')
160
+ .map(format),
161
+ });
162
+ });
163
+ }
164
+
165
+ // "done" event fires when webpack has finished recompiling the bundle.
166
+ // Whether or not you have warnings or errors, you will get this event.
167
+ compiler.hooks.done.tap('done', async stats => {
168
+ if (isInteractive) {
169
+ clearConsole();
170
+ }
171
+
172
+ // We have switched off the default webpack output in WebpackDevServer
173
+ // options so we are going to "massage" the warnings and errors and present
174
+ // them in a readable focused way.
175
+ // We only construct the warnings and errors for speed:
176
+ // https://github.com/facebook/create-react-app/issues/4492#issuecomment-421959548
177
+ const statsData = stats.toJson({
178
+ all: false,
179
+ warnings: true,
180
+ errors: true,
181
+ });
182
+
183
+ if (useTypeScript && statsData.errors.length === 0) {
184
+ const delayedMsg = setTimeout(() => {
185
+ console.log(
186
+ chalk.yellow(
187
+ 'Files successfully emitted, waiting for typecheck results...'
188
+ )
189
+ );
190
+ }, 100);
191
+
192
+ const messages = await tsMessagesPromise;
193
+ clearTimeout(delayedMsg);
194
+ if (tscCompileOnError) {
195
+ statsData.warnings.push(...messages.errors);
196
+ } else {
197
+ statsData.errors.push(...messages.errors);
198
+ }
199
+ statsData.warnings.push(...messages.warnings);
200
+
201
+ // Push errors and warnings into compilation result
202
+ // to show them after page refresh triggered by user.
203
+ if (tscCompileOnError) {
204
+ stats.compilation.warnings.push(...messages.errors);
205
+ } else {
206
+ stats.compilation.errors.push(...messages.errors);
207
+ }
208
+ stats.compilation.warnings.push(...messages.warnings);
209
+
210
+ if (messages.errors.length > 0) {
211
+ if (tscCompileOnError) {
212
+ devSocket.warnings(messages.errors);
213
+ } else {
214
+ devSocket.errors(messages.errors);
215
+ }
216
+ } else if (messages.warnings.length > 0) {
217
+ devSocket.warnings(messages.warnings);
218
+ }
219
+
220
+ if (isInteractive) {
221
+ clearConsole();
222
+ }
223
+ }
224
+
225
+ const messages = formatWebpackMessages(statsData);
226
+ const isSuccessful = !messages.errors.length && !messages.warnings.length;
227
+ if (isSuccessful) {
228
+ console.log(chalk.green('Compiled successfully!'));
229
+ }
230
+ if (isSuccessful && (isInteractive || isFirstCompile)) {
231
+ printInstructions(appName, urls, useYarn);
232
+ }
233
+ isFirstCompile = false;
234
+
235
+ // If errors exist, only show errors.
236
+ if (messages.errors.length) {
237
+ // Only keep the first error. Others are often indicative
238
+ // of the same problem, but confuse the reader with noise.
239
+ if (messages.errors.length > 1) {
240
+ messages.errors.length = 1;
241
+ }
242
+ console.log(chalk.red('Failed to compile.\n'));
243
+ console.log(messages.errors.join('\n\n'));
244
+ return;
245
+ }
246
+
247
+ // Show warnings if no errors were found.
248
+ if (messages.warnings.length) {
249
+ console.log(chalk.yellow('Compiled with warnings.\n'));
250
+ console.log(messages.warnings.join('\n\n'));
251
+
252
+ // Teach some ESLint tricks.
253
+ console.log(
254
+ '\nSearch for the ' +
255
+ chalk.underline(chalk.yellow('keywords')) +
256
+ ' to learn more about each warning.'
257
+ );
258
+ console.log(
259
+ 'To ignore, add ' +
260
+ chalk.cyan('// eslint-disable-next-line') +
261
+ ' to the line before.\n'
262
+ );
263
+ }
264
+ });
265
+
266
+ // You can safely remove this after ejecting.
267
+ // We only use this block for testing of Create React App itself:
268
+ const isSmokeTest = process.argv.some(
269
+ arg => arg.indexOf('--smoke-test') > -1
270
+ );
271
+ if (isSmokeTest) {
272
+ compiler.hooks.failed.tap('smokeTest', async () => {
273
+ await tsMessagesPromise;
274
+ process.exit(1);
275
+ });
276
+ compiler.hooks.done.tap('smokeTest', async stats => {
277
+ await tsMessagesPromise;
278
+ if (stats.hasErrors() || stats.hasWarnings()) {
279
+ process.exit(1);
280
+ } else {
281
+ process.exit(0);
282
+ }
283
+ });
284
+ }
285
+
286
+ return compiler;
287
+ }
288
+
289
+ function resolveLoopback(proxy) {
290
+ const o = url.parse(proxy);
291
+ o.host = undefined;
292
+ if (o.hostname !== 'localhost') {
293
+ return proxy;
294
+ }
295
+ // Unfortunately, many languages (unlike node) do not yet support IPv6.
296
+ // This means even though localhost resolves to ::1, the application
297
+ // must fall back to IPv4 (on 127.0.0.1).
298
+ // We can re-enable this in a few years.
299
+ /*try {
300
+ o.hostname = address.ipv6() ? '::1' : '127.0.0.1';
301
+ } catch (_ignored) {
302
+ o.hostname = '127.0.0.1';
303
+ }*/
304
+
305
+ try {
306
+ // Check if we're on a network; if we are, chances are we can resolve
307
+ // localhost. Otherwise, we can just be safe and assume localhost is
308
+ // IPv4 for maximum compatibility.
309
+ if (!address.ip()) {
310
+ o.hostname = '127.0.0.1';
311
+ }
312
+ } catch (_ignored) {
313
+ o.hostname = '127.0.0.1';
314
+ }
315
+ return url.format(o);
316
+ }
317
+
318
+ // We need to provide a custom onError function for httpProxyMiddleware.
319
+ // It allows us to log custom error messages on the console.
320
+ function onProxyError(proxy) {
321
+ return (err, req, res) => {
322
+ const host = req.headers && req.headers.host;
323
+ console.log(
324
+ chalk.red('Proxy error:') +
325
+ ' Could not proxy request ' +
326
+ chalk.cyan(req.url) +
327
+ ' from ' +
328
+ chalk.cyan(host) +
329
+ ' to ' +
330
+ chalk.cyan(proxy) +
331
+ '.'
332
+ );
333
+ console.log(
334
+ 'See https://nodejs.org/api/errors.html#errors_common_system_errors for more information (' +
335
+ chalk.cyan(err.code) +
336
+ ').'
337
+ );
338
+ console.log();
339
+
340
+ // And immediately send the proper error response to the client.
341
+ // Otherwise, the request will eventually timeout with ERR_EMPTY_RESPONSE on the client side.
342
+ if (res.writeHead && !res.headersSent) {
343
+ res.writeHead(500);
344
+ }
345
+ res.end(
346
+ 'Proxy error: Could not proxy request ' +
347
+ req.url +
348
+ ' from ' +
349
+ host +
350
+ ' to ' +
351
+ proxy +
352
+ ' (' +
353
+ err.code +
354
+ ').'
355
+ );
356
+ };
357
+ }
358
+
359
+ function prepareProxy(proxy, appPublicFolder, servedPathname) {
360
+ // `proxy` lets you specify alternate servers for specific requests.
361
+ if (!proxy) {
362
+ return undefined;
363
+ }
364
+ if (typeof proxy !== 'string') {
365
+ console.log(
366
+ chalk.red('When specified, "proxy" in package.json must be a string.')
367
+ );
368
+ console.log(
369
+ chalk.red('Instead, the type of "proxy" was "' + typeof proxy + '".')
370
+ );
371
+ console.log(
372
+ chalk.red('Either remove "proxy" from package.json, or make it a string.')
373
+ );
374
+ process.exit(1);
375
+ }
376
+
377
+ // If proxy is specified, let it handle any request except for
378
+ // files in the public folder and requests to the WebpackDevServer socket endpoint.
379
+ // https://github.com/facebook/create-react-app/issues/6720
380
+ const sockPath = process.env.WDS_SOCKET_PATH || '/sockjs-node';
381
+ const isDefaultSockHost = !process.env.WDS_SOCKET_HOST;
382
+ function mayProxy(pathname) {
383
+ const maybePublicPath = path.resolve(
384
+ appPublicFolder,
385
+ pathname.replace(new RegExp('^' + servedPathname), '')
386
+ );
387
+ const isPublicFileRequest = fs.existsSync(maybePublicPath);
388
+ // used by webpackHotDevClient
389
+ const isWdsEndpointRequest =
390
+ isDefaultSockHost && pathname.startsWith(sockPath);
391
+ return !(isPublicFileRequest || isWdsEndpointRequest);
392
+ }
393
+
394
+ if (!/^http(s)?:\/\//.test(proxy)) {
395
+ console.log(
396
+ chalk.red(
397
+ 'When "proxy" is specified in package.json it must start with either http:// or https://'
398
+ )
399
+ );
400
+ process.exit(1);
401
+ }
402
+
403
+ let target;
404
+ if (process.platform === 'win32') {
405
+ target = resolveLoopback(proxy);
406
+ } else {
407
+ target = proxy;
408
+ }
409
+ return [
410
+ {
411
+ target,
412
+ logLevel: 'silent',
413
+ // For single page apps, we generally want to fallback to /index.html.
414
+ // However we also want to respect `proxy` for API calls.
415
+ // So if `proxy` is specified as a string, we need to decide which fallback to use.
416
+ // We use a heuristic: We want to proxy all the requests that are not meant
417
+ // for static assets and as all the requests for static assets will be using
418
+ // `GET` method, we can proxy all non-`GET` requests.
419
+ // For `GET` requests, if request `accept`s text/html, we pick /index.html.
420
+ // Modern browsers include text/html into `accept` header when navigating.
421
+ // However API calls like `fetch()` won’t generally accept text/html.
422
+ // If this heuristic doesn’t work well for you, use `src/setupProxy.js`.
423
+ context: function (pathname, req) {
424
+ return (
425
+ req.method !== 'GET' ||
426
+ (mayProxy(pathname) &&
427
+ req.headers.accept &&
428
+ req.headers.accept.indexOf('text/html') === -1)
429
+ );
430
+ },
431
+ onProxyReq: proxyReq => {
432
+ // Browsers may send Origin headers even with same-origin
433
+ // requests. To prevent CORS issues, we have to change
434
+ // the Origin to match the target URL.
435
+ if (proxyReq.getHeader('origin')) {
436
+ proxyReq.setHeader('origin', target);
437
+ }
438
+ },
439
+ onError: onProxyError(target),
440
+ secure: false,
441
+ changeOrigin: true,
442
+ ws: true,
443
+ xfwd: true,
444
+ },
445
+ ];
446
+ }
447
+
448
+ function choosePort(host, defaultPort) {
449
+ return detect(defaultPort, host).then(
450
+ port =>
451
+ new Promise(resolve => {
452
+ if (port === defaultPort) {
453
+ return resolve(port);
454
+ }
455
+ const message =
456
+ process.platform !== 'win32' && defaultPort < 1024 && !isRoot()
457
+ ? `Admin permissions are required to run a server on a port below 1024.`
458
+ : `Something is already running on port ${defaultPort}.`;
459
+ if (isInteractive) {
460
+ clearConsole();
461
+ const existingProcess = getProcessForPort(defaultPort);
462
+ const question = {
463
+ type: 'confirm',
464
+ name: 'shouldChangePort',
465
+ message:
466
+ chalk.yellow(
467
+ message +
468
+ `${existingProcess ? ` Probably:\n ${existingProcess}` : ''}`
469
+ ) + '\n\nWould you like to run the app on another port instead?',
470
+ initial: true,
471
+ };
472
+ prompts(question).then(answer => {
473
+ if (answer.shouldChangePort) {
474
+ resolve(port);
475
+ } else {
476
+ resolve(null);
477
+ }
478
+ });
479
+ } else {
480
+ console.log(chalk.red(message));
481
+ resolve(null);
482
+ }
483
+ }),
484
+ err => {
485
+ throw new Error(
486
+ chalk.red(`Could not find an open port at ${chalk.bold(host)}.`) +
487
+ '\n' +
488
+ ('Network error message: ' + err.message || err) +
489
+ '\n'
490
+ );
491
+ }
492
+ );
493
+ }
494
+
495
+ module.exports = {
496
+ choosePort,
497
+ createCompiler,
498
+ prepareProxy,
499
+ prepareUrls,
500
+ };
package/chalk.js ADDED
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Copyright (c) 2015-present, Facebook, Inc.
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
+ 'use strict';
9
+
10
+ var chalk = require('chalk');
11
+
12
+ module.exports = chalk;
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Copyright (c) 2015-present, Facebook, Inc.
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
+ 'use strict';
9
+
10
+ var fs = require('fs');
11
+ var path = require('path');
12
+ var chalk = require('chalk');
13
+
14
+ function checkRequiredFiles(files) {
15
+ var currentFilePath;
16
+ try {
17
+ files.forEach(filePath => {
18
+ currentFilePath = filePath;
19
+ fs.accessSync(filePath, fs.F_OK);
20
+ });
21
+ return true;
22
+ } catch (err) {
23
+ var dirName = path.dirname(currentFilePath);
24
+ var fileName = path.basename(currentFilePath);
25
+ console.log(chalk.red('Could not find a required file.'));
26
+ console.log(chalk.red(' Name: ') + chalk.cyan(fileName));
27
+ console.log(chalk.red(' Searched in: ') + chalk.cyan(dirName));
28
+ return false;
29
+ }
30
+ }
31
+
32
+ module.exports = checkRequiredFiles;