Izmjenjena struktura, dodan backand

This commit is contained in:
GotPPay
2017-10-16 11:19:46 +02:00
parent 1ec88afacb
commit 048e32c4aa
37153 changed files with 2975854 additions and 1 deletions

140
web/node_modules/react-dev-utils/FileSizeReporter.js generated vendored Normal file
View File

@@ -0,0 +1,140 @@
/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
'use strict';
var fs = require('fs');
var path = require('path');
var chalk = require('chalk');
var filesize = require('filesize');
var recursive = require('recursive-readdir');
var stripAnsi = require('strip-ansi');
var gzipSize = require('gzip-size').sync;
// Prints a detailed summary of build files.
function printFileSizesAfterBuild(
webpackStats,
previousSizeMap,
buildFolder,
maxBundleGzipSize,
maxChunkGzipSize
) {
var root = previousSizeMap.root;
var sizes = previousSizeMap.sizes;
var assets = webpackStats
.toJson()
.assets.filter(asset => /\.(js|css)$/.test(asset.name))
.map(asset => {
var fileContents = fs.readFileSync(path.join(root, asset.name));
var size = gzipSize(fileContents);
var previousSize = sizes[removeFileNameHash(root, asset.name)];
var difference = getDifferenceLabel(size, previousSize);
return {
folder: path.join(path.basename(buildFolder), path.dirname(asset.name)),
name: path.basename(asset.name),
size: size,
sizeLabel: filesize(size) + (difference ? ' (' + difference + ')' : ''),
};
});
assets.sort((a, b) => b.size - a.size);
var longestSizeLabelLength = Math.max.apply(
null,
assets.map(a => stripAnsi(a.sizeLabel).length)
);
var suggestBundleSplitting = false;
assets.forEach(asset => {
var sizeLabel = asset.sizeLabel;
var sizeLength = stripAnsi(sizeLabel).length;
if (sizeLength < longestSizeLabelLength) {
var rightPadding = ' '.repeat(longestSizeLabelLength - sizeLength);
sizeLabel += rightPadding;
}
var isMainBundle = asset.name.indexOf('main.') === 0;
var maxRecommendedSize = isMainBundle
? maxBundleGzipSize
: maxChunkGzipSize;
var isLarge = maxRecommendedSize && asset.size > maxRecommendedSize;
if (isLarge && path.extname(asset.name) === '.js') {
suggestBundleSplitting = true;
}
console.log(
' ' +
(isLarge ? chalk.yellow(sizeLabel) : sizeLabel) +
' ' +
chalk.dim(asset.folder + path.sep) +
chalk.cyan(asset.name)
);
});
if (suggestBundleSplitting) {
console.log();
console.log(
chalk.yellow('The bundle size is significantly larger than recommended.')
);
console.log(
chalk.yellow(
'Consider reducing it with code splitting: https://goo.gl/9VhYWB'
)
);
console.log(
chalk.yellow(
'You can also analyze the project dependencies: https://goo.gl/LeUzfb'
)
);
}
}
function removeFileNameHash(buildFolder, fileName) {
return fileName
.replace(buildFolder, '')
.replace(/\/?(.*)(\.\w+)(\.js|\.css)/, (match, p1, p2, p3) => p1 + p3);
}
// Input: 1024, 2048
// Output: "(+1 KB)"
function getDifferenceLabel(currentSize, previousSize) {
var FIFTY_KILOBYTES = 1024 * 50;
var difference = currentSize - previousSize;
var fileSize = !Number.isNaN(difference) ? filesize(difference) : 0;
if (difference >= FIFTY_KILOBYTES) {
return chalk.red('+' + fileSize);
} else if (difference < FIFTY_KILOBYTES && difference > 0) {
return chalk.yellow('+' + fileSize);
} else if (difference < 0) {
return chalk.green(fileSize);
} else {
return '';
}
}
function measureFileSizesBeforeBuild(buildFolder) {
return new Promise(resolve => {
recursive(buildFolder, (err, fileNames) => {
var sizes;
if (!err && fileNames) {
sizes = fileNames
.filter(fileName => /\.(js|css)$/.test(fileName))
.reduce((memo, fileName) => {
var contents = fs.readFileSync(fileName);
var key = removeFileNameHash(buildFolder, fileName);
memo[key] = gzipSize(contents);
return memo;
}, {});
}
resolve({
root: buildFolder,
sizes: sizes || {},
});
});
});
}
module.exports = {
measureFileSizesBeforeBuild: measureFileSizesBeforeBuild,
printFileSizesAfterBuild: printFileSizesAfterBuild,
};

View File

@@ -0,0 +1,46 @@
/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
// This Webpack plugin lets us interpolate custom variables into `index.html`.
// Usage: `new InterpolateHtmlPlugin({ 'MY_VARIABLE': 42 })`
// Then, you can use %MY_VARIABLE% in your `index.html`.
// It works in tandem with HtmlWebpackPlugin.
// Learn more about creating plugins like this:
// https://github.com/ampedandwired/html-webpack-plugin#events
'use strict';
const escapeStringRegexp = require('escape-string-regexp');
class InterpolateHtmlPlugin {
constructor(replacements) {
this.replacements = replacements;
}
apply(compiler) {
compiler.plugin('compilation', compilation => {
compilation.plugin(
'html-webpack-plugin-before-html-processing',
(data, callback) => {
// Run HTML through a series of user-specified string replacements.
Object.keys(this.replacements).forEach(key => {
const value = this.replacements[key];
data.html = data.html.replace(
new RegExp('%' + escapeStringRegexp(key) + '%', 'g'),
value
);
});
callback(null, data);
}
);
});
}
}
module.exports = InterpolateHtmlPlugin;

83
web/node_modules/react-dev-utils/ModuleScopePlugin.js generated vendored Normal file
View File

@@ -0,0 +1,83 @@
/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
'use strict';
const chalk = require('chalk');
const path = require('path');
class ModuleScopePlugin {
constructor(appSrc, allowedFiles = []) {
this.appSrc = appSrc;
this.allowedFiles = new Set(allowedFiles);
}
apply(resolver) {
const { appSrc } = this;
resolver.plugin('file', (request, callback) => {
// Unknown issuer, probably webpack internals
if (!request.context.issuer) {
return callback();
}
if (
// If this resolves to a node_module, we don't care what happens next
request.descriptionFileRoot.indexOf('/node_modules/') !== -1 ||
request.descriptionFileRoot.indexOf('\\node_modules\\') !== -1 ||
// Make sure this request was manual
!request.__innerRequest_request
) {
return callback();
}
// Resolve the issuer from our appSrc and make sure it's one of our files
// Maybe an indexOf === 0 would be better?
const relative = path.relative(appSrc, request.context.issuer);
// If it's not in src/ or a subdirectory, not our request!
if (relative.startsWith('../') || relative.startsWith('..\\')) {
return callback();
}
const requestFullPath = path.resolve(
path.dirname(request.context.issuer),
request.__innerRequest_request
);
if (this.allowedFiles.has(requestFullPath)) {
return callback();
}
// Find path from src to the requested file
// Error if in a parent directory of src/
const requestRelative = path.relative(appSrc, requestFullPath);
if (
requestRelative.startsWith('../') ||
requestRelative.startsWith('..\\')
) {
callback(
new Error(
`You attempted to import ${chalk.cyan(
request.__innerRequest_request
)} which falls outside of the project ${chalk.cyan(
'src/'
)} directory. ` +
`Relative imports outside of ${chalk.cyan(
'src/'
)} are not supported. ` +
`You can either move it inside ${chalk.cyan(
'src/'
)}, or add a symlink to it from project's ${chalk.cyan(
'node_modules/'
)}.`
),
request
);
} else {
callback();
}
});
}
}
module.exports = ModuleScopePlugin;

328
web/node_modules/react-dev-utils/README.md generated vendored Normal file
View File

@@ -0,0 +1,328 @@
# react-dev-utils
This package includes some utilities used by [Create React App](https://github.com/facebookincubator/create-react-app).<br>
Please refer to its documentation:
* [Getting Started](https://github.com/facebookincubator/create-react-app/blob/master/README.md#getting-started) How to create a new app.
* [User Guide](https://github.com/facebookincubator/create-react-app/blob/master/packages/react-scripts/template/README.md) How to develop apps bootstrapped with Create React App.
## Usage in Create React App Projects
These utilities come by default with [Create React App](https://github.com/facebookincubator/create-react-app), which includes it by default. **You dont need to install it separately in Create React App projects.**
## Usage Outside of Create React App
If you dont use Create React App, or if you [ejected](https://github.com/facebookincubator/create-react-app/blob/master/packages/react-scripts/template/README.md#npm-run-eject), you may keep using these utilities. Their development will be aligned with Create React App, so major versions of these utilities may come out relatively often. Feel free to fork or copy and paste them into your projects if youd like to have more control over them, or feel free to use the old versions. Not all of them are React-specific, but we might make some of them more React-specific in the future.
### Entry Points
There is no single entry point. You can only import individual top-level modules.
#### `new InterpolateHtmlPlugin(replacements: {[key:string]: string})`
This Webpack plugin lets us interpolate custom variables into `index.html`.<br>
It works in tandem with [HtmlWebpackPlugin](https://github.com/ampedandwired/html-webpack-plugin) 2.x via its [events](https://github.com/ampedandwired/html-webpack-plugin#events).
```js
var path = require('path');
var HtmlWebpackPlugin = require('html-dev-plugin');
var InterpolateHtmlPlugin = require('react-dev-utils/InterpolateHtmlPlugin');
// Webpack config
var publicUrl = '/my-custom-url';
module.exports = {
output: {
// ...
publicPath: publicUrl + '/'
},
// ...
plugins: [
// Makes the public URL available as %PUBLIC_URL% in index.html, e.g.:
// <link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
new InterpolateHtmlPlugin({
PUBLIC_URL: publicUrl
// You can pass any key-value pairs, this was just an example.
// WHATEVER: 42 will replace %WHATEVER% with 42 in index.html.
}),
// Generates an `index.html` file with the <script> injected.
new HtmlWebpackPlugin({
inject: true,
template: path.resolve('public/index.html'),
}),
// ...
],
// ...
}
```
#### `new ModuleScopePlugin(appSrc: string, allowedFiles?: string[])`
This Webpack plugin ensures that relative imports from app's source directory don't reach outside of it.
```js
var path = require('path');
var ModuleScopePlugin = require('react-dev-utils/ModuleScopePlugin');
module.exports = {
// ...
resolve: {
// ...
plugins: [
new ModuleScopePlugin(paths.appSrc, [paths.appPackageJson]),
// ...
],
// ...
},
// ...
}
```
#### `new WatchMissingNodeModulesPlugin(nodeModulesPath: string)`
This Webpack plugin ensures `npm install <library>` forces a project rebuild.<br>
Were not sure why this isn't Webpack's default behavior.<br>
See [#186](https://github.com/facebookincubator/create-react-app/issues/186) for details.
```js
var path = require('path');
var WatchMissingNodeModulesPlugin = require('react-dev-utils/WatchMissingNodeModulesPlugin');
// Webpack config
module.exports = {
// ...
plugins: [
// ...
// If you require a missing module and then `npm install` it, you still have
// to restart the development server for Webpack to discover it. This plugin
// makes the discovery automatic so you don't have to restart.
// See https://github.com/facebookincubator/create-react-app/issues/186
new WatchMissingNodeModulesPlugin(path.resolve('node_modules'))
],
// ...
}
```
#### `checkRequiredFiles(files: Array<string>): boolean`
Makes sure that all passed files exist.<br>
Filenames are expected to be absolute.<br>
If a file is not found, prints a warning message and returns `false`.
```js
var path = require('path');
var checkRequiredFiles = require('react-dev-utils/checkRequiredFiles');
if (!checkRequiredFiles([
path.resolve('public/index.html'),
path.resolve('src/index.js')
])) {
process.exit(1);
}
```
#### `clearConsole(): void`
Clears the console, hopefully in a cross-platform way.
```js
var clearConsole = require('react-dev-utils/clearConsole');
clearConsole();
console.log('Just cleared the screen!');
```
#### `eslintFormatter(results: Object): string`
This is our custom ESLint formatter that integrates well with Create React App console output.<br>
You can use the default one instead if you prefer so.
```js
const eslintFormatter = require('react-dev-utils/eslintFormatter');
// In your webpack config:
// ...
module: {
rules: [
{
test: /\.(js|jsx)$/,
include: paths.appSrc,
enforce: 'pre',
use: [
{
loader: 'eslint-loader',
options: {
// Pass the formatter:
formatter: eslintFormatter,
},
},
],
}
]
}
```
#### `FileSizeReporter`
##### `measureFileSizesBeforeBuild(buildFolder: string): Promise<OpaqueFileSizes>`
Captures JS and CSS asset sizes inside the passed `buildFolder`. Save the result value to compare it after the build.
##### `printFileSizesAfterBuild(webpackStats: WebpackStats, previousFileSizes: OpaqueFileSizes)`
Prints the JS and CSS asset sizes after the build, and includes a size comparison with `previousFileSizes` that were captured earlier using `measureFileSizesBeforeBuild()`.
```js
var {
measureFileSizesBeforeBuild,
printFileSizesAfterBuild,
} = require('react-dev-utils/FileSizeReporter');
measureFileSizesBeforeBuild(buildFolder).then(previousFileSizes => {
return cleanAndRebuild().then(webpackStats => {
printFileSizesAfterBuild(webpackStats, previousFileSizes);
});
});
```
#### `formatWebpackMessages({errors: Array<string>, warnings: Array<string>}): {errors: Array<string>, warnings: Array<string>}`
Extracts and prettifies warning and error messages from webpack [stats](https://github.com/webpack/docs/wiki/node.js-api#stats) object.
```js
var webpack = require('webpack');
var config = require('../config/webpack.config.dev');
var formatWebpackMessages = require('react-dev-utils/formatWebpackMessages');
var compiler = webpack(config);
compiler.plugin('invalid', function() {
console.log('Compiling...');
});
compiler.plugin('done', function(stats) {
var rawMessages = stats.toJson({}, true);
var messages = formatWebpackMessages(rawMessages);
if (!messages.errors.length && !messages.warnings.length) {
console.log('Compiled successfully!');
}
if (messages.errors.length) {
console.log('Failed to compile.');
messages.errors.forEach(e => console.log(e));
return;
}
if (messages.warnings.length) {
console.log('Compiled with warnings.');
messages.warnings.forEach(w => console.log(w));
}
});
```
#### `printBuildError(error: Object): void`
Prettify some known build errors.
Pass an Error object to log a prettified error message in the console.
```
const printBuildError = require('react-dev-utils/printBuildError')
try {
build()
} catch(e) {
printBuildError(e) // logs prettified message
}
```
#### `getProcessForPort(port: number): string`
Finds the currently running process on `port`.
Returns a string containing the name and directory, e.g.,
```
create-react-app
in /Users/developer/create-react-app
```
```js
var getProcessForPort = require('react-dev-utils/getProcessForPort');
getProcessForPort(3000);
```
#### `launchEditor(fileName: string, lineNumber: number): void`
On macOS, tries to find a known running editor process and opens the file in it. It can also be explicitly configured by `REACT_EDITOR`, `VISUAL`, or `EDITOR` environment variables. For example, you can put `REACT_EDITOR=atom` in your `.env.local` file, and Create React App will respect that.
#### `noopServiceWorkerMiddleware(): ExpressMiddleware`
Returns Express middleware that serves a `/service-worker.js` that resets any previously set service worker configuration. Useful for development.
#### `openBrowser(url: string): boolean`
Attempts to open the browser with a given URL.<br>
On Mac OS X, attempts to reuse an existing Chrome tab via AppleScript.<br>
Otherwise, falls back to [opn](https://github.com/sindresorhus/opn) behavior.
```js
var path = require('path');
var openBrowser = require('react-dev-utils/openBrowser');
if (openBrowser('http://localhost:3000')) {
console.log('The browser tab has been opened!');
}
```
#### `printHostingInstructions(appPackage: Object, publicUrl: string, publicPath: string, buildFolder: string, useYarn: boolean): void`
Prints hosting instructions after the project is built.
Pass your parsed `package.json` object as `appPackage`, your the URL where you plan to host the app as `publicUrl`, `output.publicPath` from your Webpack configuration as `publicPath`, the `buildFolder` name, and whether to `useYarn` in instructions.
```js
const appPackage = require(paths.appPackageJson);
const publicUrl = paths.publicUrl;
const publicPath = config.output.publicPath;
printHostingInstructions(appPackage, publicUrl, publicPath, 'build', true);
```
#### `WebpackDevServerUtils`
##### `choosePort(host: string, defaultPort: number): Promise<number | null>`
Returns a Promise resolving to either `defaultPort` or next available port if the user confirms it is okay to do. If the port is taken and the user has refused to use another port, or if the terminal is not interactive and cant present user with the choice, resolves to `null`.
##### `createCompiler(webpack: Function, config: Object, appName: string, urls: Object, useYarn: boolean): WebpackCompiler`
Creates a Webpack compiler instance for WebpackDevServer with built-in helpful messages. Takes the `require('webpack')` entry point as the first argument. To provide the `urls` argument, use `prepareUrls()` described below.
##### `prepareProxy(proxySetting: string, appPublicFolder: string): Object`
Creates a WebpackDevServer `proxy` configuration object from the `proxy` setting in `package.json`.
##### `prepareUrls(protocol: string, host: string, port: number): Object`
Returns an object with local and remote URLs for the development server. Pass this object to `createCompiler()` described above.
#### `webpackHotDevClient`
This is an alternative client for [WebpackDevServer](https://github.com/webpack/webpack-dev-server) that shows a syntax error overlay.
It currently supports only Webpack 3.x.
```js
// Webpack development config
module.exports = {
// ...
entry: [
// You can replace the line below with these two lines if you prefer the
// stock client:
// require.resolve('webpack-dev-server/client') + '?/',
// require.resolve('webpack/hot/dev-server'),
'react-dev-utils/webpackHotDevClient',
'src/index'
],
// ...
}
```

View File

@@ -0,0 +1,37 @@
/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
// This Webpack plugin ensures `npm install <library>` forces a project rebuild.
// Were not sure why this isn't Webpack's default behavior.
// See https://github.com/facebookincubator/create-react-app/issues/186.
'use strict';
class WatchMissingNodeModulesPlugin {
constructor(nodeModulesPath) {
this.nodeModulesPath = nodeModulesPath;
}
apply(compiler) {
compiler.plugin('emit', (compilation, callback) => {
var missingDeps = compilation.missingDependencies;
var nodeModulesPath = this.nodeModulesPath;
// If any missing files are expected to appear in node_modules...
if (missingDeps.some(file => file.indexOf(nodeModulesPath) !== -1)) {
// ...tell webpack to watch node_modules recursively until they appear.
compilation.contextDependencies.push(nodeModulesPath);
}
callback();
});
}
}
module.exports = WatchMissingNodeModulesPlugin;

View File

@@ -0,0 +1,437 @@
/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
'use strict';
const address = require('address');
const fs = require('fs');
const path = require('path');
const url = require('url');
const chalk = require('chalk');
const detect = require('detect-port-alt');
const isRoot = require('is-root');
const inquirer = require('inquirer');
const clearConsole = require('./clearConsole');
const formatWebpackMessages = require('./formatWebpackMessages');
const getProcessForPort = require('./getProcessForPort');
const isInteractive = process.stdout.isTTY;
let handleCompile;
// You can safely remove this after ejecting.
// We only use this block for testing of Create React App itself:
const isSmokeTest = process.argv.some(arg => arg.indexOf('--smoke-test') > -1);
if (isSmokeTest) {
handleCompile = (err, stats) => {
if (err || stats.hasErrors() || stats.hasWarnings()) {
process.exit(1);
} else {
process.exit(0);
}
};
}
function prepareUrls(protocol, host, port) {
const formatUrl = hostname =>
url.format({
protocol,
hostname,
port,
pathname: '/',
});
const prettyPrintUrl = hostname =>
url.format({
protocol,
hostname,
port: chalk.bold(port),
pathname: '/',
});
const isUnspecifiedHost = host === '0.0.0.0' || host === '::';
let prettyHost, lanUrlForConfig, lanUrlForTerminal;
if (isUnspecifiedHost) {
prettyHost = 'localhost';
try {
// This can only return an IPv4 address
lanUrlForConfig = address.ip();
if (lanUrlForConfig) {
// Check if the address is a private ip
// https://en.wikipedia.org/wiki/Private_network#Private_IPv4_address_spaces
if (
/^10[.]|^172[.](1[6-9]|2[0-9]|3[0-1])[.]|^192[.]168[.]/.test(
lanUrlForConfig
)
) {
// Address is private, format it for later use
lanUrlForTerminal = prettyPrintUrl(lanUrlForConfig);
} else {
// Address is not private, so we will discard it
lanUrlForConfig = undefined;
}
}
} catch (_e) {
// ignored
}
} else {
prettyHost = host;
}
const localUrlForTerminal = prettyPrintUrl(prettyHost);
const localUrlForBrowser = formatUrl(prettyHost);
return {
lanUrlForConfig,
lanUrlForTerminal,
localUrlForTerminal,
localUrlForBrowser,
};
}
function printInstructions(appName, urls, useYarn) {
console.log();
console.log(`You can now view ${chalk.bold(appName)} in the browser.`);
console.log();
if (urls.lanUrlForTerminal) {
console.log(
` ${chalk.bold('Local:')} ${urls.localUrlForTerminal}`
);
console.log(
` ${chalk.bold('On Your Network:')} ${urls.lanUrlForTerminal}`
);
} else {
console.log(` ${urls.localUrlForTerminal}`);
}
console.log();
console.log('Note that the development build is not optimized.');
console.log(
`To create a production build, use ` +
`${chalk.cyan(`${useYarn ? 'yarn' : 'npm run'} build`)}.`
);
console.log();
}
function createCompiler(webpack, config, appName, urls, useYarn) {
// "Compiler" is a low-level interface to Webpack.
// It lets us listen to some events and provide our own custom messages.
let compiler;
try {
compiler = webpack(config, handleCompile);
} catch (err) {
console.log(chalk.red('Failed to compile.'));
console.log();
console.log(err.message || err);
console.log();
process.exit(1);
}
// "invalid" event fires when you have changed a file, and Webpack is
// recompiling a bundle. WebpackDevServer takes care to pause serving the
// bundle, so if you refresh, it'll wait instead of serving the old one.
// "invalid" is short for "bundle invalidated", it doesn't imply any errors.
compiler.plugin('invalid', () => {
if (isInteractive) {
clearConsole();
}
console.log('Compiling...');
});
let isFirstCompile = true;
// "done" event fires when Webpack has finished recompiling the bundle.
// Whether or not you have warnings or errors, you will get this event.
compiler.plugin('done', stats => {
if (isInteractive) {
clearConsole();
}
// We have switched off the default Webpack output in WebpackDevServer
// options so we are going to "massage" the warnings and errors and present
// them in a readable focused way.
const messages = formatWebpackMessages(stats.toJson({}, true));
const isSuccessful = !messages.errors.length && !messages.warnings.length;
if (isSuccessful) {
console.log(chalk.green('Compiled successfully!'));
}
if (isSuccessful && (isInteractive || isFirstCompile)) {
printInstructions(appName, urls, useYarn);
}
isFirstCompile = false;
// If errors exist, only show errors.
if (messages.errors.length) {
// Only keep the first error. Others are often indicative
// of the same problem, but confuse the reader with noise.
if (messages.errors.length > 1) {
messages.errors.length = 1;
}
console.log(chalk.red('Failed to compile.\n'));
console.log(messages.errors.join('\n\n'));
return;
}
// Show warnings if no errors were found.
if (messages.warnings.length) {
console.log(chalk.yellow('Compiled with warnings.\n'));
console.log(messages.warnings.join('\n\n'));
// Teach some ESLint tricks.
console.log(
'\nSearch for the ' +
chalk.underline(chalk.yellow('keywords')) +
' to learn more about each warning.'
);
console.log(
'To ignore, add ' +
chalk.cyan('// eslint-disable-next-line') +
' to the line before.\n'
);
}
});
return compiler;
}
function resolveLoopback(proxy) {
const o = url.parse(proxy);
o.host = undefined;
if (o.hostname !== 'localhost') {
return proxy;
}
// Unfortunately, many languages (unlike node) do not yet support IPv6.
// This means even though localhost resolves to ::1, the application
// must fall back to IPv4 (on 127.0.0.1).
// We can re-enable this in a few years.
/*try {
o.hostname = address.ipv6() ? '::1' : '127.0.0.1';
} catch (_ignored) {
o.hostname = '127.0.0.1';
}*/
try {
// Check if we're on a network; if we are, chances are we can resolve
// localhost. Otherwise, we can just be safe and assume localhost is
// IPv4 for maximum compatibility.
if (!address.ip()) {
o.hostname = '127.0.0.1';
}
} catch (_ignored) {
o.hostname = '127.0.0.1';
}
return url.format(o);
}
// We need to provide a custom onError function for httpProxyMiddleware.
// It allows us to log custom error messages on the console.
function onProxyError(proxy) {
return (err, req, res) => {
const host = req.headers && req.headers.host;
console.log(
chalk.red('Proxy error:') +
' Could not proxy request ' +
chalk.cyan(req.url) +
' from ' +
chalk.cyan(host) +
' to ' +
chalk.cyan(proxy) +
'.'
);
console.log(
'See https://nodejs.org/api/errors.html#errors_common_system_errors for more information (' +
chalk.cyan(err.code) +
').'
);
console.log();
// And immediately send the proper error response to the client.
// Otherwise, the request will eventually timeout with ERR_EMPTY_RESPONSE on the client side.
if (res.writeHead && !res.headersSent) {
res.writeHead(500);
}
res.end(
'Proxy error: Could not proxy request ' +
req.url +
' from ' +
host +
' to ' +
proxy +
' (' +
err.code +
').'
);
};
}
function prepareProxy(proxy, appPublicFolder) {
// `proxy` lets you specify alternate servers for specific requests.
// It can either be a string or an object conforming to the Webpack dev server proxy configuration
// https://webpack.github.io/docs/webpack-dev-server.html
if (!proxy) {
return undefined;
}
if (typeof proxy !== 'object' && typeof proxy !== 'string') {
console.log(
chalk.red(
'When specified, "proxy" in package.json must be a string or an object.'
)
);
console.log(
chalk.red('Instead, the type of "proxy" was "' + typeof proxy + '".')
);
console.log(
chalk.red(
'Either remove "proxy" from package.json, or make it an object.'
)
);
process.exit(1);
}
// Otherwise, if proxy is specified, we will let it handle any request except for files in the public folder.
function mayProxy(pathname) {
const maybePublicPath = path.resolve(appPublicFolder, pathname.slice(1));
return !fs.existsSync(maybePublicPath);
}
// Support proxy as a string for those who are using the simple proxy option
if (typeof proxy === 'string') {
if (!/^http(s)?:\/\//.test(proxy)) {
console.log(
chalk.red(
'When "proxy" is specified in package.json it must start with either http:// or https://'
)
);
process.exit(1);
}
let target;
if (process.platform === 'win32') {
target = resolveLoopback(proxy);
} else {
target = proxy;
}
return [
{
target,
logLevel: 'silent',
// For single page apps, we generally want to fallback to /index.html.
// However we also want to respect `proxy` for API calls.
// So if `proxy` is specified as a string, we need to decide which fallback to use.
// We use a heuristic: if request `accept`s text/html, we pick /index.html.
// Modern browsers include text/html into `accept` header when navigating.
// However API calls like `fetch()` wont generally accept text/html.
// If this heuristic doesnt work well for you, use a custom `proxy` object.
context: function(pathname, req) {
return (
mayProxy(pathname) &&
req.headers.accept &&
req.headers.accept.indexOf('text/html') === -1
);
},
onProxyReq: proxyReq => {
// Browers may send Origin headers even with same-origin
// requests. To prevent CORS issues, we have to change
// the Origin to match the target URL.
if (proxyReq.getHeader('origin')) {
proxyReq.setHeader('origin', target);
}
},
onError: onProxyError(target),
secure: false,
changeOrigin: true,
ws: true,
xfwd: true,
},
];
}
// Otherwise, proxy is an object so create an array of proxies to pass to webpackDevServer
return Object.keys(proxy).map(function(context) {
if (!proxy[context].hasOwnProperty('target')) {
console.log(
chalk.red(
'When `proxy` in package.json is as an object, each `context` object must have a ' +
'`target` property specified as a url string'
)
);
process.exit(1);
}
let target;
if (process.platform === 'win32') {
target = resolveLoopback(proxy[context].target);
} else {
target = proxy[context].target;
}
return Object.assign({}, proxy[context], {
context: function(pathname) {
return mayProxy(pathname) && pathname.match(context);
},
onProxyReq: proxyReq => {
// Browers may send Origin headers even with same-origin
// requests. To prevent CORS issues, we have to change
// the Origin to match the target URL.
if (proxyReq.getHeader('origin')) {
proxyReq.setHeader('origin', target);
}
},
target,
onError: onProxyError(target),
});
});
}
function choosePort(host, defaultPort) {
return detect(defaultPort, host).then(
port =>
new Promise(resolve => {
if (port === defaultPort) {
return resolve(port);
}
const message =
process.platform !== 'win32' && defaultPort < 1024 && !isRoot()
? `Admin permissions are required to run a server on a port below 1024.`
: `Something is already running on port ${defaultPort}.`;
if (isInteractive) {
clearConsole();
const existingProcess = getProcessForPort(defaultPort);
const question = {
type: 'confirm',
name: 'shouldChangePort',
message:
chalk.yellow(
message +
`${existingProcess ? ` Probably:\n ${existingProcess}` : ''}`
) + '\n\nWould you like to run the app on another port instead?',
default: true,
};
inquirer.prompt(question).then(answer => {
if (answer.shouldChangePort) {
resolve(port);
} else {
resolve(null);
}
});
} else {
console.log(chalk.red(message));
resolve(null);
}
}),
err => {
throw new Error(
chalk.red(`Could not find an open port at ${chalk.bold(host)}.`) +
'\n' +
('Network error message: ' + err.message || err) +
'\n'
);
}
);
}
module.exports = {
choosePort,
createCompiler,
prepareProxy,
prepareUrls,
};

107
web/node_modules/react-dev-utils/ansiHTML.js generated vendored Normal file
View File

@@ -0,0 +1,107 @@
/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
'use strict';
var Anser = require('anser');
var Entities = require('html-entities').AllHtmlEntities;
var entities = new Entities();
// Color scheme inspired by https://chriskempson.github.io/base16/css/base16-github.css
// var base00 = 'ffffff'; // Default Background
var base01 = 'f5f5f5'; // Lighter Background (Used for status bars)
// var base02 = 'c8c8fa'; // Selection Background
var base03 = '6e6e6e'; // Comments, Invisibles, Line Highlighting
// var base04 = 'e8e8e8'; // Dark Foreground (Used for status bars)
var base05 = '333333'; // Default Foreground, Caret, Delimiters, Operators
// var base06 = 'ffffff'; // Light Foreground (Not often used)
// var base07 = 'ffffff'; // Light Background (Not often used)
var base08 = '881280'; // Variables, XML Tags, Markup Link Text, Markup Lists, Diff Deleted
// var base09 = '0086b3'; // Integers, Boolean, Constants, XML Attributes, Markup Link Url
// var base0A = '795da3'; // Classes, Markup Bold, Search Text Background
var base0B = '1155cc'; // Strings, Inherited Class, Markup Code, Diff Inserted
var base0C = '994500'; // Support, Regular Expressions, Escape Characters, Markup Quotes
// var base0D = '795da3'; // Functions, Methods, Attribute IDs, Headings
var base0E = 'c80000'; // Keywords, Storage, Selector, Markup Italic, Diff Changed
// var base0F = '333333'; // Deprecated, Opening/Closing Embedded Language Tags e.g. <?php ?>
// Map ANSI colors from what babel-code-frame uses to base16-github
// See: https://github.com/babel/babel/blob/e86f62b304d280d0bab52c38d61842b853848ba6/packages/babel-code-frame/src/index.js#L9-L22
var colors = {
reset: [base05, 'transparent'],
black: base05,
red: base08 /* marker, bg-invalid */,
green: base0B /* string */,
yellow: base08 /* capitalized, jsx_tag, punctuator */,
blue: base0C,
magenta: base0C /* regex */,
cyan: base0E /* keyword */,
gray: base03 /* comment, gutter */,
lightgrey: base01,
darkgrey: base03,
};
var anserMap = {
'ansi-bright-black': 'black',
'ansi-bright-yellow': 'yellow',
'ansi-yellow': 'yellow',
'ansi-bright-green': 'green',
'ansi-green': 'green',
'ansi-bright-cyan': 'cyan',
'ansi-cyan': 'cyan',
'ansi-bright-red': 'red',
'ansi-red': 'red',
'ansi-bright-magenta': 'magenta',
'ansi-magenta': 'magenta',
'ansi-white': 'darkgrey',
};
function ansiHTML(txt) {
var arr = new Anser().ansiToJson(entities.encode(txt), {
use_classes: true,
});
var result = '';
var open = false;
for (var index = 0; index < arr.length; ++index) {
var c = arr[index];
var content = c.content,
fg = c.fg;
var contentParts = content.split('\n');
for (var _index = 0; _index < contentParts.length; ++_index) {
if (!open) {
result += '<span data-ansi-line="true">';
open = true;
}
var part = contentParts[_index].replace('\r', '');
var color = colors[anserMap[fg]];
if (color != null) {
result += '<span style="color: #' + color + ';">' + part + '</span>';
} else {
if (fg != null) {
console.log('Missing color mapping: ', fg);
}
result += '<span>' + part + '</span>';
}
if (_index < contentParts.length - 1) {
result += '</span>';
open = false;
result += '<br/>';
}
}
}
if (open) {
result += '</span>';
open = false;
}
return result;
}
module.exports = ansiHTML;

34
web/node_modules/react-dev-utils/checkRequiredFiles.js generated vendored Normal file
View File

@@ -0,0 +1,34 @@
/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
'use strict';
var fs = require('fs');
var path = require('path');
var chalk = require('chalk');
function checkRequiredFiles(files) {
var currentFilePath;
try {
files.forEach(filePath => {
currentFilePath = filePath;
fs.accessSync(filePath, fs.F_OK);
});
return true;
} catch (err) {
var dirName = path.dirname(currentFilePath);
var fileName = path.basename(currentFilePath);
console.log(chalk.red('Could not find a required file.'));
console.log(chalk.red(' Name: ') + chalk.cyan(fileName));
console.log(chalk.red(' Searched in: ') + chalk.cyan(dirName));
return false;
}
}
module.exports = checkRequiredFiles;

18
web/node_modules/react-dev-utils/clearConsole.js generated vendored Normal file
View File

@@ -0,0 +1,18 @@
/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
'use strict';
function clearConsole() {
process.stdout.write(
process.platform === 'win32' ? '\x1Bc' : '\x1B[2J\x1B[3J\x1B[H'
);
}
module.exports = clearConsole;

14
web/node_modules/react-dev-utils/crossSpawn.js generated vendored Normal file
View File

@@ -0,0 +1,14 @@
/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
'use strict';
var crossSpawn = require('cross-spawn');
module.exports = crossSpawn;

94
web/node_modules/react-dev-utils/eslintFormatter.js generated vendored Normal file
View File

@@ -0,0 +1,94 @@
/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
'use strict';
const chalk = require('chalk');
const table = require('text-table');
function isError(message) {
if (message.fatal || message.severity === 2) {
return true;
}
return false;
}
function formatter(results) {
let output = '\n';
let hasErrors = false;
let reportContainsErrorRuleIDs = false;
results.forEach(result => {
let messages = result.messages;
if (messages.length === 0) {
return;
}
messages = messages.map(message => {
let messageType;
if (isError(message)) {
messageType = 'error';
hasErrors = true;
if (message.ruleId) {
reportContainsErrorRuleIDs = true;
}
} else {
messageType = 'warn';
}
let line = message.line || 0;
let position = chalk.bold('Line ' + line + ':');
return [
'',
position,
messageType,
message.message.replace(/\.$/, ''),
chalk.underline(message.ruleId || ''),
];
});
// if there are error messages, we want to show only errors
if (hasErrors) {
messages = messages.filter(m => m[2] === 'error');
}
// add color to rule keywords
messages.forEach(m => {
m[4] = m[2] === 'error' ? chalk.red(m[4]) : chalk.yellow(m[4]);
m.splice(2, 1);
});
let outputTable = table(messages, {
align: ['l', 'l', 'l'],
stringLength(str) {
return chalk.stripColor(str).length;
},
});
output += `${outputTable}\n\n`;
});
if (reportContainsErrorRuleIDs) {
// Unlike with warnings, we have to do it here.
// We have similar code in react-scripts for warnings,
// but warnings can appear in multiple files so we only
// print it once at the end. For errors, however, we print
// it here because we always show at most one error, and
// we can only be sure it's an ESLint error before exiting
// this function.
output +=
'Search for the ' +
chalk.underline(chalk.red('keywords')) +
' to learn more about each error.';
}
return output;
}
module.exports = formatter;

View File

@@ -0,0 +1,127 @@
/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
'use strict';
// WARNING: this code is untranspiled and is used in browser too.
// Please make sure any changes are in ES5 or contribute a Babel compile step.
// Some custom utilities to prettify Webpack output.
// This is quite hacky and hopefully won't be needed when Webpack fixes this.
// https://github.com/webpack/webpack/issues/2878
var chalk = require('chalk');
var friendlySyntaxErrorLabel = 'Syntax error:';
function isLikelyASyntaxError(message) {
return message.indexOf(friendlySyntaxErrorLabel) !== -1;
}
// Cleans up webpack error messages.
// eslint-disable-next-line no-unused-vars
function formatMessage(message, isError) {
var lines = message.split('\n');
if (lines.length > 2 && lines[1] === '') {
// Remove extra newline.
lines.splice(1, 1);
}
// Remove webpack-specific loader notation from filename.
// Before:
// ./~/css-loader!./~/postcss-loader!./src/App.css
// After:
// ./src/App.css
if (lines[0].lastIndexOf('!') !== -1) {
lines[0] = lines[0].substr(lines[0].lastIndexOf('!') + 1);
}
lines = lines.filter(function(line) {
// Webpack adds a list of entry points to warning messages:
// @ ./src/index.js
// @ multi react-scripts/~/react-dev-utils/webpackHotDevClient.js ...
// It is misleading (and unrelated to the warnings) so we clean it up.
// It is only useful for syntax errors but we have beautiful frames for them.
return line.indexOf(' @ ') !== 0;
});
// line #0 is filename
// line #1 is the main error message
if (!lines[0] || !lines[1]) {
return lines.join('\n');
}
// Cleans up verbose "module not found" messages for files and packages.
if (lines[1].indexOf('Module not found: ') === 0) {
lines = [
lines[0],
// Clean up message because "Module not found: " is descriptive enough.
lines[1]
.replace("Cannot resolve 'file' or 'directory' ", '')
.replace('Cannot resolve module ', '')
.replace('Error: ', '')
.replace('[CaseSensitivePathsPlugin] ', ''),
];
}
// Cleans up syntax error messages.
if (lines[1].indexOf('Module build failed: ') === 0) {
lines[1] = lines[1].replace(
'Module build failed: SyntaxError:',
friendlySyntaxErrorLabel
);
}
// Clean up export errors.
// TODO: we should really send a PR to Webpack for this.
var exportError = /\s*(.+?)\s*(")?export '(.+?)' was not found in '(.+?)'/;
if (lines[1].match(exportError)) {
lines[1] = lines[1].replace(
exportError,
"$1 '$4' does not contain an export named '$3'."
);
}
lines[0] = chalk.inverse(lines[0]);
// Reassemble the message.
message = lines.join('\n');
// Internal stacks are generally useless so we strip them... with the
// exception of stacks containing `webpack:` because they're normally
// from user code generated by WebPack. For more information see
// https://github.com/facebookincubator/create-react-app/pull/1050
message = message.replace(
/^\s*at\s((?!webpack:).)*:\d+:\d+[\s)]*(\n|$)/gm,
''
); // at ... ...:x:y
return message.trim();
}
function formatWebpackMessages(json) {
var formattedErrors = json.errors.map(function(message) {
return formatMessage(message, true);
});
var formattedWarnings = json.warnings.map(function(message) {
return formatMessage(message, false);
});
var result = {
errors: formattedErrors,
warnings: formattedWarnings,
};
if (result.errors.some(isLikelyASyntaxError)) {
// If there are any syntax errors, show just them.
// This prevents a confusing ESLint parsing error
// preceding a much more useful Babel syntax error.
result.errors = result.errors.filter(isLikelyASyntaxError);
}
return result;
}
module.exports = formatWebpackMessages;

77
web/node_modules/react-dev-utils/getProcessForPort.js generated vendored Normal file
View File

@@ -0,0 +1,77 @@
/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
'use strict';
var chalk = require('chalk');
var execSync = require('child_process').execSync;
var path = require('path');
var execOptions = {
encoding: 'utf8',
stdio: [
'pipe', // stdin (default)
'pipe', // stdout (default)
'ignore', //stderr
],
};
function isProcessAReactApp(processCommand) {
return /^node .*react-scripts\/scripts\/start\.js\s?$/.test(processCommand);
}
function getProcessIdOnPort(port) {
return execSync('lsof -i:' + port + ' -P -t -sTCP:LISTEN', execOptions)
.split('\n')[0]
.trim();
}
function getPackageNameInDirectory(directory) {
var packagePath = path.join(directory.trim(), 'package.json');
try {
return require(packagePath).name;
} catch (e) {
return null;
}
}
function getProcessCommand(processId, processDirectory) {
var command = execSync(
'ps -o command -p ' + processId + ' | sed -n 2p',
execOptions
);
if (isProcessAReactApp(command)) {
const packageName = getPackageNameInDirectory(processDirectory);
return packageName ? packageName + '\n' : command;
} else {
return command;
}
}
function getDirectoryOfProcessById(processId) {
return execSync(
'lsof -p ' + processId + ' | awk \'$4=="cwd" {print $9}\'',
execOptions
).trim();
}
function getProcessForPort(port) {
try {
var processId = getProcessIdOnPort(port);
var directory = getDirectoryOfProcessById(processId);
var command = getProcessCommand(processId, directory);
return chalk.cyan(command) + chalk.blue(' in ') + chalk.cyan(directory);
} catch (e) {
return null;
}
}
module.exports = getProcessForPort;

14
web/node_modules/react-dev-utils/inquirer.js generated vendored Normal file
View File

@@ -0,0 +1,14 @@
/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
'use strict';
var inquirer = require('inquirer');
module.exports = inquirer;

292
web/node_modules/react-dev-utils/launchEditor.js generated vendored Normal file
View File

@@ -0,0 +1,292 @@
/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
'use strict';
const fs = require('fs');
const path = require('path');
const child_process = require('child_process');
const os = require('os');
const chalk = require('chalk');
const shellQuote = require('shell-quote');
function isTerminalEditor(editor) {
switch (editor) {
case 'vim':
case 'emacs':
case 'nano':
return true;
}
return false;
}
// Map from full process name to binary that starts the process
// We can't just re-use full process name, because it will spawn a new instance
// of the app every time
const COMMON_EDITORS_OSX = {
'/Applications/Atom.app/Contents/MacOS/Atom': 'atom',
'/Applications/Atom Beta.app/Contents/MacOS/Atom Beta':
'/Applications/Atom Beta.app/Contents/MacOS/Atom Beta',
'/Applications/Brackets.app/Contents/MacOS/Brackets': 'brackets',
'/Applications/Sublime Text.app/Contents/MacOS/Sublime Text':
'/Applications/Sublime Text.app/Contents/SharedSupport/bin/subl',
'/Applications/Sublime Text 2.app/Contents/MacOS/Sublime Text 2':
'/Applications/Sublime Text 2.app/Contents/SharedSupport/bin/subl',
'/Applications/Visual Studio Code.app/Contents/MacOS/Electron': 'code',
'/Applications/AppCode.app/Contents/MacOS/appcode':
'/Applications/AppCode.app/Contents/MacOS/appcode',
'/Applications/CLion.app/Contents/MacOS/clion':
'/Applications/CLion.app/Contents/MacOS/clion',
'/Applications/IntelliJ IDEA.app/Contents/MacOS/idea':
'/Applications/IntelliJ IDEA.app/Contents/MacOS/idea',
'/Applications/PhpStorm.app/Contents/MacOS/phpstorm':
'/Applications/PhpStorm.app/Contents/MacOS/phpstorm',
'/Applications/PyCharm.app/Contents/MacOS/pycharm':
'/Applications/PyCharm.app/Contents/MacOS/pycharm',
'/Applications/PyCharm CE.app/Contents/MacOS/pycharm':
'/Applications/PyCharm CE.app/Contents/MacOS/pycharm',
'/Applications/RubyMine.app/Contents/MacOS/rubymine':
'/Applications/RubyMine.app/Contents/MacOS/rubymine',
'/Applications/WebStorm.app/Contents/MacOS/webstorm':
'/Applications/WebStorm.app/Contents/MacOS/webstorm',
};
const COMMON_EDITORS_WIN = [
'Brackets.exe',
'Code.exe',
'atom.exe',
'sublime_text.exe',
'notepad++.exe',
'clion.exe',
'clion64.exe',
'idea.exe',
'idea64.exe',
'phpstorm.exe',
'phpstorm64.exe',
'pycharm.exe',
'pycharm64.exe',
'rubymine.exe',
'rubymine64.exe',
'webstorm.exe',
'webstorm64.exe',
];
function addWorkspaceToArgumentsIfExists(args, workspace) {
if (workspace) {
args.unshift(workspace);
}
return args;
}
function getArgumentsForLineNumber(editor, fileName, lineNumber, workspace) {
const editorBasename = path.basename(editor).replace(/\.(exe|cmd|bat)$/i, '');
switch (editorBasename) {
case 'atom':
case 'Atom':
case 'Atom Beta':
case 'subl':
case 'sublime':
case 'sublime_text':
case 'wstorm':
case 'charm':
return [fileName + ':' + lineNumber];
case 'notepad++':
return ['-n' + lineNumber, fileName];
case 'vim':
case 'mvim':
case 'joe':
case 'emacs':
case 'emacsclient':
return ['+' + lineNumber, fileName];
case 'rmate':
case 'mate':
case 'mine':
return ['--line', lineNumber, fileName];
case 'code':
case 'Code':
return addWorkspaceToArgumentsIfExists(
['-g', fileName + ':' + lineNumber],
workspace
);
case 'appcode':
case 'clion':
case 'clion64':
case 'idea':
case 'idea64':
case 'phpstorm':
case 'phpstorm64':
case 'pycharm':
case 'pycharm64':
case 'rubymine':
case 'rubymine64':
case 'webstorm':
case 'webstorm64':
return addWorkspaceToArgumentsIfExists(
['--line', lineNumber, fileName],
workspace
);
}
// For all others, drop the lineNumber until we have
// a mapping above, since providing the lineNumber incorrectly
// can result in errors or confusing behavior.
return [fileName];
}
function guessEditor() {
// Explicit config always wins
if (process.env.REACT_EDITOR) {
return shellQuote.parse(process.env.REACT_EDITOR);
}
// Using `ps x` on OSX or `Get-Process` on Windows we can find out which editor is currently running.
// Potentially we could use similar technique for Linux
try {
if (process.platform === 'darwin') {
const output = child_process.execSync('ps x').toString();
const processNames = Object.keys(COMMON_EDITORS_OSX);
for (let i = 0; i < processNames.length; i++) {
const processName = processNames[i];
if (output.indexOf(processName) !== -1) {
return [COMMON_EDITORS_OSX[processName]];
}
}
} else if (process.platform === 'win32') {
const output = child_process
.execSync('powershell -Command "Get-Process | Select-Object Path"', {
stdio: ['pipe', 'pipe', 'ignore'],
})
.toString();
const runningProcesses = output.split('\r\n');
for (let i = 0; i < runningProcesses.length; i++) {
// `Get-Process` sometimes returns empty lines
if (!runningProcesses[i]) {
continue;
}
const fullProcessPath = runningProcesses[i].trim();
const shortProcessName = path.basename(fullProcessPath);
if (COMMON_EDITORS_WIN.indexOf(shortProcessName) !== -1) {
return [fullProcessPath];
}
}
}
} catch (error) {
// Ignore...
}
// Last resort, use old skool env vars
if (process.env.VISUAL) {
return [process.env.VISUAL];
} else if (process.env.EDITOR) {
return [process.env.EDITOR];
}
return [null];
}
function printInstructions(fileName, errorMessage) {
console.log();
console.log(
chalk.red('Could not open ' + path.basename(fileName) + ' in the editor.')
);
if (errorMessage) {
if (errorMessage[errorMessage.length - 1] !== '.') {
errorMessage += '.';
}
console.log(
chalk.red('The editor process exited with an error: ' + errorMessage)
);
}
console.log();
console.log(
'To set up the editor integration, add something like ' +
chalk.cyan('REACT_EDITOR=atom') +
' to the ' +
chalk.green('.env.local') +
' file in your project folder ' +
'and restart the development server. Learn more: ' +
chalk.green('https://goo.gl/MMTaZt')
);
console.log();
}
let _childProcess = null;
function launchEditor(fileName, lineNumber) {
if (!fs.existsSync(fileName)) {
return;
}
// Sanitize lineNumber to prevent malicious use on win32
// via: https://github.com/nodejs/node/blob/c3bb4b1aa5e907d489619fb43d233c3336bfc03d/lib/child_process.js#L333
if (lineNumber && isNaN(lineNumber)) {
return;
}
let [editor, ...args] = guessEditor();
if (!editor) {
printInstructions(fileName, null);
return;
}
if (
process.platform === 'linux' &&
fileName.startsWith('/mnt/') &&
/Microsoft/i.test(os.release())
) {
// Assume WSL / "Bash on Ubuntu on Windows" is being used, and
// that the file exists on the Windows file system.
// `os.release()` is "4.4.0-43-Microsoft" in the current release
// build of WSL, see: https://github.com/Microsoft/BashOnWindows/issues/423#issuecomment-221627364
// When a Windows editor is specified, interop functionality can
// handle the path translation, but only if a relative path is used.
fileName = path.relative('', fileName);
}
let workspace = null;
if (lineNumber) {
args = args.concat(
getArgumentsForLineNumber(editor, fileName, lineNumber, workspace)
);
} else {
args.push(fileName);
}
if (_childProcess && isTerminalEditor(editor)) {
// There's an existing editor process already and it's attached
// to the terminal, so go kill it. Otherwise two separate editor
// instances attach to the stdin/stdout which gets confusing.
_childProcess.kill('SIGKILL');
}
if (process.platform === 'win32') {
// On Windows, launch the editor in a shell because spawn can only
// launch .exe files.
_childProcess = child_process.spawn(
'cmd.exe',
['/C', editor].concat(args),
{ stdio: 'inherit' }
);
} else {
_childProcess = child_process.spawn(editor, args, { stdio: 'inherit' });
}
_childProcess.on('exit', function(errorCode) {
_childProcess = null;
if (errorCode) {
printInstructions(fileName, '(code ' + errorCode + ')');
}
});
_childProcess.on('error', function(error) {
printInstructions(fileName, error.message);
});
}
module.exports = launchEditor;

View File

@@ -0,0 +1,98 @@
'use strict';
const x = module.exports;
const ESC = '\u001B[';
const isTerminalApp = process.env.TERM_PROGRAM === 'Apple_Terminal';
x.cursorTo = function (x, y) {
if (arguments.length === 0) {
return ESC + 'H';
}
if (arguments.length === 1) {
return ESC + (x + 1) + 'G';
}
return ESC + (y + 1) + ';' + (x + 1) + 'H';
};
x.cursorMove = (x, y) => {
let ret = '';
if (x < 0) {
ret += ESC + (-x) + 'D';
} else if (x > 0) {
ret += ESC + x + 'C';
}
if (y < 0) {
ret += ESC + (-y) + 'A';
} else if (y > 0) {
ret += ESC + y + 'B';
}
return ret;
};
x.cursorUp = count => ESC + (typeof count === 'number' ? count : 1) + 'A';
x.cursorDown = count => ESC + (typeof count === 'number' ? count : 1) + 'B';
x.cursorForward = count => ESC + (typeof count === 'number' ? count : 1) + 'C';
x.cursorBackward = count => ESC + (typeof count === 'number' ? count : 1) + 'D';
x.cursorLeft = ESC + 'G';
x.cursorSavePosition = ESC + (isTerminalApp ? '7' : 's');
x.cursorRestorePosition = ESC + (isTerminalApp ? '8' : 'u');
x.cursorGetPosition = ESC + '6n';
x.cursorNextLine = ESC + 'E';
x.cursorPrevLine = ESC + 'F';
x.cursorHide = ESC + '?25l';
x.cursorShow = ESC + '?25h';
x.eraseLines = count => {
let clear = '';
for (let i = 0; i < count; i++) {
clear += x.eraseLine + (i < count - 1 ? x.cursorUp() : '');
}
if (count) {
clear += x.cursorLeft;
}
return clear;
};
x.eraseEndLine = ESC + 'K';
x.eraseStartLine = ESC + '1K';
x.eraseLine = ESC + '2K';
x.eraseDown = ESC + 'J';
x.eraseUp = ESC + '1J';
x.eraseScreen = ESC + '2J';
x.scrollUp = ESC + 'S';
x.scrollDown = ESC + 'T';
x.clearScreen = '\u001Bc';
x.beep = '\u0007';
x.image = (buf, opts) => {
opts = opts || {};
let ret = '\u001B]1337;File=inline=1';
if (opts.width) {
ret += `;width=${opts.width}`;
}
if (opts.height) {
ret += `;height=${opts.height}`;
}
if (opts.preserveAspectRatio === false) {
ret += ';preserveAspectRatio=0';
}
return ret + ':' + buf.toString('base64') + '\u0007';
};
x.iTerm = {};
x.iTerm.setCwd = cwd => '\u001B]50;CurrentDir=' + (cwd || process.cwd()) + '\u0007';

View File

@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.com)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

View File

@@ -0,0 +1,82 @@
{
"_from": "ansi-escapes@^2.0.0",
"_id": "ansi-escapes@2.0.0",
"_inBundle": false,
"_integrity": "sha1-W65SvkJIeN2Xg+iRDj/Cki6DyBs=",
"_location": "/react-dev-utils/ansi-escapes",
"_phantomChildren": {},
"_requested": {
"type": "range",
"registry": true,
"raw": "ansi-escapes@^2.0.0",
"name": "ansi-escapes",
"escapedName": "ansi-escapes",
"rawSpec": "^2.0.0",
"saveSpec": null,
"fetchSpec": "^2.0.0"
},
"_requiredBy": [
"/react-dev-utils/inquirer"
],
"_resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-2.0.0.tgz",
"_shasum": "5bae52be424878dd9783e8910e3fc2922e83c81b",
"_spec": "ansi-escapes@^2.0.0",
"_where": "/home/bilal/Saburly/slucajna-televizija/node_modules/react-dev-utils/node_modules/inquirer",
"author": {
"name": "Sindre Sorhus",
"email": "sindresorhus@gmail.com",
"url": "sindresorhus.com"
},
"bugs": {
"url": "https://github.com/sindresorhus/ansi-escapes/issues"
},
"bundleDependencies": false,
"deprecated": false,
"description": "ANSI escape codes for manipulating the terminal",
"devDependencies": {
"ava": "*",
"xo": "*"
},
"engines": {
"node": ">=4"
},
"files": [
"index.js"
],
"homepage": "https://github.com/sindresorhus/ansi-escapes#readme",
"keywords": [
"ansi",
"terminal",
"console",
"cli",
"string",
"tty",
"escape",
"escapes",
"formatting",
"shell",
"xterm",
"log",
"logging",
"command-line",
"text",
"vt100",
"sequence",
"control",
"code",
"codes",
"cursor",
"iterm",
"iterm2"
],
"license": "MIT",
"name": "ansi-escapes",
"repository": {
"type": "git",
"url": "git+https://github.com/sindresorhus/ansi-escapes.git"
},
"scripts": {
"test": "xo && ava"
},
"version": "2.0.0"
}

View File

@@ -0,0 +1,176 @@
# ansi-escapes [![Build Status](https://travis-ci.org/sindresorhus/ansi-escapes.svg?branch=master)](https://travis-ci.org/sindresorhus/ansi-escapes)
> [ANSI escape codes](http://www.termsys.demon.co.uk/vtansi.htm) for manipulating the terminal
## Install
```
$ npm install --save ansi-escapes
```
## Usage
```js
const ansiEscapes = require('ansi-escapes');
// Moves the cursor two rows up and to the left
process.stdout.write(ansiEscapes.cursorUp(2) + ansiEscapes.cursorLeft);
//=> '\u001B[2A\u001B[1000D'
```
## API
### cursorTo([x, [y]])
Set the absolute position of the cursor. `x0` `y0` is the top left of the screen.
Specify either both `x` & `y`, only `x`, or nothing.
### cursorMove(x, [y])
Set the position of the cursor relative to its current position.
### cursorUp(count)
Move cursor up a specific amount of rows. Default is `1`.
### cursorDown(count)
Move cursor down a specific amount of rows. Default is `1`.
### cursorForward(count)
Move cursor forward a specific amount of rows. Default is `1`.
### cursorBackward(count)
Move cursor backward a specific amount of rows. Default is `1`.
### cursorLeft
Move cursor to the left side.
### cursorSavePosition
Save cursor position.
### cursorRestorePosition
Restore saved cursor position.
### cursorGetPosition
Get cursor position.
### cursorNextLine
Move cursor to the next line.
### cursorPrevLine
Move cursor to the previous line.
### cursorHide
Hide cursor.
### cursorShow
Show cursor.
### eraseLines(count)
Erase from the current cursor position up the specified amount of rows.
### eraseEndLine
Erase from the current cursor position to the end of the current line.
### eraseStartLine
Erase from the current cursor position to the start of the current line.
### eraseLine
Erase the entire current line.
### eraseDown
Erase the screen from the current line down to the bottom of the screen.
### eraseUp
Erase the screen from the current line up to the top of the screen.
### eraseScreen
Erase the screen and move the cursor the top left position.
### scrollUp
Scroll display up one line.
### scrollDown
Scroll display down one line.
### clearScreen
Clear the terminal screen.
### beep
Output a beeping sound.
### image(input, [options])
Display an image.
*Currently only supported on iTerm >=2.9.*
See [term-img](https://github.com/sindresorhus/term-img) for a higher-level module.
#### input
Type: `Buffer`
Buffer of an image. Usually read in with `fs.readFile()`.
#### options
##### width
##### height
Type: `string` `number`
The width and height are given as a number followed by a unit, or the word "auto".
- `N`: N character cells.
- `Npx`: N pixels.
- `N%`: N percent of the session's width or height.
- `auto`: The image's inherent size will be used to determine an appropriate dimension.
##### preserveAspectRatio
Type: `boolean`<br>
Default: `true`
### iTerm.setCwd([path])
Type: `string`<br>
Default: `process.cwd()`
[Inform iTerm](https://www.iterm2.com/documentation-escape-codes.html) of the current directory to help semantic history and enable [Cmd-clicking relative paths](https://coderwall.com/p/b7e82q/quickly-open-files-in-iterm-with-cmd-click).
## Related
- [ansi-styles](https://github.com/chalk/ansi-styles) - ANSI escape codes for styling strings in the terminal
## License
MIT © [Sindre Sorhus](https://sindresorhus.com)

View File

@@ -0,0 +1,10 @@
'use strict';
module.exports = () => {
const pattern = [
'[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:[a-zA-Z\\d]*(?:;[a-zA-Z\\d]*)*)?\\u0007)',
'(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PRZcf-ntqry=><~]))'
].join('|');
return new RegExp(pattern, 'g');
};

View File

@@ -0,0 +1,9 @@
MIT License
Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.com)
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@@ -0,0 +1,86 @@
{
"_from": "ansi-regex@^3.0.0",
"_id": "ansi-regex@3.0.0",
"_inBundle": false,
"_integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
"_location": "/react-dev-utils/ansi-regex",
"_phantomChildren": {},
"_requested": {
"type": "range",
"registry": true,
"raw": "ansi-regex@^3.0.0",
"name": "ansi-regex",
"escapedName": "ansi-regex",
"rawSpec": "^3.0.0",
"saveSpec": null,
"fetchSpec": "^3.0.0"
},
"_requiredBy": [
"/react-dev-utils/inquirer/strip-ansi",
"/react-dev-utils/string-width/strip-ansi"
],
"_resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
"_shasum": "ed0317c322064f79466c02966bddb605ab37d998",
"_spec": "ansi-regex@^3.0.0",
"_where": "/home/bilal/Saburly/slucajna-televizija/node_modules/react-dev-utils/node_modules/string-width/node_modules/strip-ansi",
"author": {
"name": "Sindre Sorhus",
"email": "sindresorhus@gmail.com",
"url": "sindresorhus.com"
},
"bugs": {
"url": "https://github.com/chalk/ansi-regex/issues"
},
"bundleDependencies": false,
"deprecated": false,
"description": "Regular expression for matching ANSI escape codes",
"devDependencies": {
"ava": "*",
"xo": "*"
},
"engines": {
"node": ">=4"
},
"files": [
"index.js"
],
"homepage": "https://github.com/chalk/ansi-regex#readme",
"keywords": [
"ansi",
"styles",
"color",
"colour",
"colors",
"terminal",
"console",
"cli",
"string",
"tty",
"escape",
"formatting",
"rgb",
"256",
"shell",
"xterm",
"command-line",
"text",
"regex",
"regexp",
"re",
"match",
"test",
"find",
"pattern"
],
"license": "MIT",
"name": "ansi-regex",
"repository": {
"type": "git",
"url": "git+https://github.com/chalk/ansi-regex.git"
},
"scripts": {
"test": "xo && ava",
"view-supported": "node fixtures/view-codes.js"
},
"version": "3.0.0"
}

View File

@@ -0,0 +1,46 @@
# ansi-regex [![Build Status](https://travis-ci.org/chalk/ansi-regex.svg?branch=master)](https://travis-ci.org/chalk/ansi-regex)
> Regular expression for matching [ANSI escape codes](https://en.wikipedia.org/wiki/ANSI_escape_code)
## Install
```
$ npm install ansi-regex
```
## Usage
```js
const ansiRegex = require('ansi-regex');
ansiRegex().test('\u001B[4mcake\u001B[0m');
//=> true
ansiRegex().test('cake');
//=> false
'\u001B[4mcake\u001B[0m'.match(ansiRegex());
//=> ['\u001B[4m', '\u001B[0m']
```
## FAQ
### Why do you test for codes not in the ECMA 48 standard?
Some of the codes we run as a test are codes that we acquired finding various lists of non-standard or manufacturer specific codes. We test for both standard and non-standard codes, as most of them follow the same or similar format and can be safely matched in strings without the risk of removing actual string content. There are a few non-standard control codes that do not follow the traditional format (i.e. they end in numbers) thus forcing us to exclude them from the test because we cannot reliably match them.
On the historical side, those ECMA standards were established in the early 90's whereas the VT100, for example, was designed in the mid/late 70's. At that point in time, control codes were still pretty ungoverned and engineers used them for a multitude of things, namely to activate hardware ports that may have been proprietary. Somewhere else you see a similar 'anarchy' of codes is in the x86 architecture for processors; there are a ton of "interrupts" that can mean different things on certain brands of processors, most of which have been phased out.
## Maintainers
- [Sindre Sorhus](https://github.com/sindresorhus)
- [Josh Junon](https://github.com/qix-)
## License
MIT

View File

@@ -0,0 +1,3 @@
src
test
node_modules

View File

@@ -0,0 +1,43 @@
# babel-code-frame
> Generate errors that contain a code frame that point to source locations.
## Install
```sh
npm install --save-dev babel-code-frame
```
## Usage
```js
import codeFrame from 'babel-code-frame';
const rawLines = `class Foo {
constructor()
}`;
const lineNumber = 2;
const colNumber = 16;
const result = codeFrame(rawLines, lineNumber, colNumber, { /* options */ });
console.log(result);
```
```sh
1 | class Foo {
> 2 | constructor()
| ^
3 | }
```
If the column number is not known, you may pass `null` instead.
## Options
name | type | default | description
-----------------------|----------|-----------------|------------------------------------------------------
highlightCode | boolean | `false` | Syntax highlight the code as JavaScript for terminals
linesAbove | number | 2 | The number of lines to show above the error
linesBelow | number | 3 | The number of lines to show below the error
forceColor | boolean | `false` | Forcibly syntax highlight the code as JavaScript (for non-terminals); overrides highlightCode

View File

@@ -0,0 +1,141 @@
"use strict";
exports.__esModule = true;
exports.default = function (rawLines, lineNumber, colNumber) {
var opts = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
colNumber = Math.max(colNumber, 0);
var highlighted = opts.highlightCode && _chalk2.default.supportsColor || opts.forceColor;
var chalk = _chalk2.default;
if (opts.forceColor) {
chalk = new _chalk2.default.constructor({ enabled: true });
}
var maybeHighlight = function maybeHighlight(chalkFn, string) {
return highlighted ? chalkFn(string) : string;
};
var defs = getDefs(chalk);
if (highlighted) rawLines = highlight(defs, rawLines);
var linesAbove = opts.linesAbove || 2;
var linesBelow = opts.linesBelow || 3;
var lines = rawLines.split(NEWLINE);
var start = Math.max(lineNumber - (linesAbove + 1), 0);
var end = Math.min(lines.length, lineNumber + linesBelow);
if (!lineNumber && !colNumber) {
start = 0;
end = lines.length;
}
var numberMaxWidth = String(end).length;
var frame = lines.slice(start, end).map(function (line, index) {
var number = start + 1 + index;
var paddedNumber = (" " + number).slice(-numberMaxWidth);
var gutter = " " + paddedNumber + " | ";
if (number === lineNumber) {
var markerLine = "";
if (colNumber) {
var markerSpacing = line.slice(0, colNumber - 1).replace(/[^\t]/g, " ");
markerLine = ["\n ", maybeHighlight(defs.gutter, gutter.replace(/\d/g, " ")), markerSpacing, maybeHighlight(defs.marker, "^")].join("");
}
return [maybeHighlight(defs.marker, ">"), maybeHighlight(defs.gutter, gutter), line, markerLine].join("");
} else {
return " " + maybeHighlight(defs.gutter, gutter) + line;
}
}).join("\n");
if (highlighted) {
return chalk.reset(frame);
} else {
return frame;
}
};
var _jsTokens = require("js-tokens");
var _jsTokens2 = _interopRequireDefault(_jsTokens);
var _esutils = require("esutils");
var _esutils2 = _interopRequireDefault(_esutils);
var _chalk = require("chalk");
var _chalk2 = _interopRequireDefault(_chalk);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function getDefs(chalk) {
return {
keyword: chalk.cyan,
capitalized: chalk.yellow,
jsx_tag: chalk.yellow,
punctuator: chalk.yellow,
number: chalk.magenta,
string: chalk.green,
regex: chalk.magenta,
comment: chalk.grey,
invalid: chalk.white.bgRed.bold,
gutter: chalk.grey,
marker: chalk.red.bold
};
}
var NEWLINE = /\r\n|[\n\r\u2028\u2029]/;
var JSX_TAG = /^[a-z][\w-]*$/i;
var BRACKET = /^[()\[\]{}]$/;
function getTokenType(match) {
var _match$slice = match.slice(-2),
offset = _match$slice[0],
text = _match$slice[1];
var token = (0, _jsTokens.matchToToken)(match);
if (token.type === "name") {
if (_esutils2.default.keyword.isReservedWordES6(token.value)) {
return "keyword";
}
if (JSX_TAG.test(token.value) && (text[offset - 1] === "<" || text.substr(offset - 2, 2) == "</")) {
return "jsx_tag";
}
if (token.value[0] !== token.value[0].toLowerCase()) {
return "capitalized";
}
}
if (token.type === "punctuator" && BRACKET.test(token.value)) {
return "bracket";
}
return token.type;
}
function highlight(defs, text) {
return text.replace(_jsTokens2.default, function () {
for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}
var type = getTokenType(args);
var colorize = defs[type];
if (colorize) {
return args[0].split(NEWLINE).map(function (str) {
return colorize(str);
}).join("\n");
} else {
return args[0];
}
});
}
module.exports = exports["default"];

View File

@@ -0,0 +1,46 @@
{
"_from": "babel-code-frame@6.22.0",
"_id": "babel-code-frame@6.22.0",
"_inBundle": false,
"_integrity": "sha1-AnYgvuVnqIwyVhV05/0IAdMxGOQ=",
"_location": "/react-dev-utils/babel-code-frame",
"_phantomChildren": {},
"_requested": {
"type": "version",
"registry": true,
"raw": "babel-code-frame@6.22.0",
"name": "babel-code-frame",
"escapedName": "babel-code-frame",
"rawSpec": "6.22.0",
"saveSpec": null,
"fetchSpec": "6.22.0"
},
"_requiredBy": [
"/react-dev-utils"
],
"_resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.22.0.tgz",
"_shasum": "027620bee567a88c32561574e7fd0801d33118e4",
"_spec": "babel-code-frame@6.22.0",
"_where": "/home/bilal/Saburly/slucajna-televizija/node_modules/react-dev-utils",
"author": {
"name": "Sebastian McKenzie",
"email": "sebmck@gmail.com"
},
"bundleDependencies": false,
"dependencies": {
"chalk": "^1.1.0",
"esutils": "^2.0.2",
"js-tokens": "^3.0.0"
},
"deprecated": false,
"description": "Generate errors that contain a code frame that point to source locations.",
"homepage": "https://babeljs.io/",
"license": "MIT",
"main": "lib/index.js",
"name": "babel-code-frame",
"repository": {
"type": "git",
"url": "https://github.com/babel/babel/tree/master/packages/babel-code-frame"
},
"version": "6.22.0"
}

View File

@@ -0,0 +1,39 @@
'use strict';
const restoreCursor = require('restore-cursor');
let hidden = false;
exports.show = stream => {
const s = stream || process.stderr;
if (!s.isTTY) {
return;
}
hidden = false;
s.write('\u001b[?25h');
};
exports.hide = stream => {
const s = stream || process.stderr;
if (!s.isTTY) {
return;
}
restoreCursor();
hidden = true;
s.write('\u001b[?25l');
};
exports.toggle = (force, stream) => {
if (force !== undefined) {
hidden = force;
}
if (hidden) {
exports.show(stream);
} else {
exports.hide(stream);
}
};

View File

@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.com)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

View File

@@ -0,0 +1,78 @@
{
"_from": "cli-cursor@^2.1.0",
"_id": "cli-cursor@2.1.0",
"_inBundle": false,
"_integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=",
"_location": "/react-dev-utils/cli-cursor",
"_phantomChildren": {},
"_requested": {
"type": "range",
"registry": true,
"raw": "cli-cursor@^2.1.0",
"name": "cli-cursor",
"escapedName": "cli-cursor",
"rawSpec": "^2.1.0",
"saveSpec": null,
"fetchSpec": "^2.1.0"
},
"_requiredBy": [
"/react-dev-utils/inquirer"
],
"_resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz",
"_shasum": "b35dac376479facc3e94747d41d0d0f5238ffcb5",
"_spec": "cli-cursor@^2.1.0",
"_where": "/home/bilal/Saburly/slucajna-televizija/node_modules/react-dev-utils/node_modules/inquirer",
"author": {
"name": "Sindre Sorhus",
"email": "sindresorhus@gmail.com",
"url": "sindresorhus.com"
},
"bugs": {
"url": "https://github.com/sindresorhus/cli-cursor/issues"
},
"bundleDependencies": false,
"dependencies": {
"restore-cursor": "^2.0.0"
},
"deprecated": false,
"description": "Toggle the CLI cursor",
"devDependencies": {
"ava": "*",
"xo": "*"
},
"engines": {
"node": ">=4"
},
"files": [
"index.js"
],
"homepage": "https://github.com/sindresorhus/cli-cursor#readme",
"keywords": [
"cli",
"cursor",
"ansi",
"toggle",
"display",
"show",
"hide",
"term",
"terminal",
"console",
"tty",
"shell",
"command-line"
],
"license": "MIT",
"name": "cli-cursor",
"repository": {
"type": "git",
"url": "git+https://github.com/sindresorhus/cli-cursor.git"
},
"scripts": {
"test": "xo && ava"
},
"version": "2.1.0",
"xo": {
"esnext": true
}
}

View File

@@ -0,0 +1,45 @@
# cli-cursor [![Build Status](https://travis-ci.org/sindresorhus/cli-cursor.svg?branch=master)](https://travis-ci.org/sindresorhus/cli-cursor)
> Toggle the CLI cursor
The cursor is [gracefully restored](https://github.com/sindresorhus/restore-cursor) if the process exits.
## Install
```
$ npm install --save cli-cursor
```
## Usage
```js
const cliCursor = require('cli-cursor');
cliCursor.hide();
const unicornsAreAwesome = true;
cliCursor.toggle(unicornsAreAwesome);
```
## API
### .show([stream])
### .hide([stream])
### .toggle(force, [stream])
`force` is useful to show or hide the cursor based on a boolean.
#### stream
Type: `Stream`<br>
Default: `process.stderr`
## License
MIT © [Sindre Sorhus](https://sindresorhus.com)

View File

@@ -0,0 +1,147 @@
'use strict';
const escapeStringRegexp = require('escape-string-regexp');
const platform = process.platform;
const main = {
tick: '✔',
cross: '✖',
star: '★',
square: '▇',
squareSmall: '◻',
squareSmallFilled: '◼',
play: '▶',
circle: '◯',
circleFilled: '◉',
circleDotted: '◌',
circleDouble: '◎',
circleCircle: 'ⓞ',
circleCross: 'ⓧ',
circlePipe: 'Ⓘ',
circleQuestionMark: '?⃝',
bullet: '●',
dot: '',
line: '─',
ellipsis: '…',
pointer: '',
pointerSmall: '',
info: '',
warning: '⚠',
hamburger: '☰',
smiley: '㋡',
mustache: '෴',
heart: '♥',
arrowUp: '↑',
arrowDown: '↓',
arrowLeft: '←',
arrowRight: '→',
radioOn: '◉',
radioOff: '◯',
checkboxOn: '☒',
checkboxOff: '☐',
checkboxCircleOn: 'ⓧ',
checkboxCircleOff: 'Ⓘ',
questionMarkPrefix: '?⃝',
oneHalf: '½',
oneThird: '⅓',
oneQuarter: '¼',
oneFifth: '⅕',
oneSixth: '⅙',
oneSeventh: '⅐',
oneEighth: '⅛',
oneNinth: '⅑',
oneTenth: '⅒',
twoThirds: '⅔',
twoFifths: '⅖',
threeQuarters: '¾',
threeFifths: '⅗',
threeEighths: '⅜',
fourFifths: '⅘',
fiveSixths: '⅚',
fiveEighths: '⅝',
sevenEighths: '⅞'
};
const win = {
tick: '√',
cross: '×',
star: '*',
square: '█',
squareSmall: '[ ]',
squareSmallFilled: '[█]',
play: '►',
circle: '( )',
circleFilled: '(*)',
circleDotted: '( )',
circleDouble: '( )',
circleCircle: '(○)',
circleCross: '(×)',
circlePipe: '(│)',
circleQuestionMark: '(?)',
bullet: '*',
dot: '.',
line: '─',
ellipsis: '...',
pointer: '>',
pointerSmall: '»',
info: 'i',
warning: '‼',
hamburger: '≡',
smiley: '☺',
mustache: '┌─┐',
heart: main.heart,
arrowUp: main.arrowUp,
arrowDown: main.arrowDown,
arrowLeft: main.arrowLeft,
arrowRight: main.arrowRight,
radioOn: '(*)',
radioOff: '( )',
checkboxOn: '[×]',
checkboxOff: '[ ]',
checkboxCircleOn: '(×)',
checkboxCircleOff: '( )',
questionMarkPrefix: '',
oneHalf: '1/2',
oneThird: '1/3',
oneQuarter: '1/4',
oneFifth: '1/5',
oneSixth: '1/6',
oneSeventh: '1/7',
oneEighth: '1/8',
oneNinth: '1/9',
oneTenth: '1/10',
twoThirds: '2/3',
twoFifths: '2/5',
threeQuarters: '3/4',
threeFifths: '3/5',
threeEighths: '3/8',
fourFifths: '4/5',
fiveSixths: '5/6',
fiveEighths: '5/8',
sevenEighths: '7/8'
};
if (platform === 'linux') {
// the main one doesn't look that good on Ubuntu
main.questionMarkPrefix = '?';
}
const figures = platform === 'win32' ? win : main;
const fn = str => {
if (figures === main) {
return str;
}
Object.keys(main).forEach(key => {
if (main[key] === figures[key]) {
return;
}
str = str.replace(new RegExp(escapeStringRegexp(main[key]), 'g'), figures[key]);
});
return str;
};
module.exports = Object.assign(fn, figures);

View File

@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.com)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

View File

@@ -0,0 +1,79 @@
{
"_from": "figures@^2.0.0",
"_id": "figures@2.0.0",
"_inBundle": false,
"_integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=",
"_location": "/react-dev-utils/figures",
"_phantomChildren": {},
"_requested": {
"type": "range",
"registry": true,
"raw": "figures@^2.0.0",
"name": "figures",
"escapedName": "figures",
"rawSpec": "^2.0.0",
"saveSpec": null,
"fetchSpec": "^2.0.0"
},
"_requiredBy": [
"/react-dev-utils/inquirer"
],
"_resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz",
"_shasum": "3ab1a2d2a62c8bfb431a0c94cb797a2fce27c962",
"_spec": "figures@^2.0.0",
"_where": "/home/bilal/Saburly/slucajna-televizija/node_modules/react-dev-utils/node_modules/inquirer",
"author": {
"name": "Sindre Sorhus",
"email": "sindresorhus@gmail.com",
"url": "sindresorhus.com"
},
"bugs": {
"url": "https://github.com/sindresorhus/figures/issues"
},
"bundleDependencies": false,
"dependencies": {
"escape-string-regexp": "^1.0.5"
},
"deprecated": false,
"description": "Unicode symbols with Windows CMD fallbacks",
"devDependencies": {
"ava": "*",
"markdown-table": "^1.0.0",
"require-uncached": "^1.0.2",
"xo": "*"
},
"engines": {
"node": ">=4"
},
"files": [
"index.js"
],
"homepage": "https://github.com/sindresorhus/figures#readme",
"keywords": [
"unicode",
"cli",
"cmd",
"command-line",
"characters",
"char",
"symbol",
"symbols",
"figure",
"figures",
"fallback"
],
"license": "MIT",
"name": "figures",
"repository": {
"type": "git",
"url": "git+https://github.com/sindresorhus/figures.git"
},
"scripts": {
"make": "./makefile.js",
"test": "xo && ava"
},
"version": "2.0.0",
"xo": {
"esnext": true
}
}

View File

@@ -0,0 +1,120 @@
# figures [![Build Status: Linux](https://travis-ci.org/sindresorhus/figures.svg?branch=master)](https://travis-ci.org/sindresorhus/figures) [![Build status: Windows](https://ci.appveyor.com/api/projects/status/mb743hl70269be3r/branch/master?svg=true)](https://ci.appveyor.com/project/sindresorhus/figures/branch/master)
> Unicode symbols with Windows CMD fallbacks
[![](screenshot.png)](index.js)
[*and more...*](index.js)
Windows CMD only supports a [limited character set](http://en.wikipedia.org/wiki/Code_page_437).
## Install
```
$ npm install --save figures
```
## Usage
See the [source](index.js) for supported symbols.
```js
const figures = require('figures');
console.log(figures('✔︎ check'));
// On real OSes: ✔︎ check
// On Windows: √ check
console.log(figures.tick);
// On real OSes: ✔︎
// On Windows: √
```
## API
### figures(input)
Returns the input with replaced fallback unicode symbols on Windows.
All the below [figures](#figures) are attached to the main export as shown in the example above.
#### input
Type: `string`
String where the unicode symbols will be replaced with fallback symbols depending on the OS.
## Figures
| Name | Real OSes | Windows |
| ------------------ | :-------: | :-----: |
| tick | ✔ | √ |
| cross | ✖ | × |
| star | ★ | * |
| square | ▇ | █ |
| squareSmall | ◻ | [ ] |
| squareSmallFilled | ◼ | [█] |
| play | ▶ | ► |
| circle | ◯ | ( ) |
| circleFilled | ◉ | (*) |
| circleDotted | ◌ | ( ) |
| circleDouble | ◎ | ( ) |
| circleCircle | ⓞ | (○) |
| circleCross | ⓧ | (×) |
| circlePipe | Ⓘ | (│) |
| circleQuestionMark | ?⃝ | (?) |
| bullet | ● | * |
| dot | | . |
| line | ─ | ─ |
| ellipsis | … | ... |
| pointer | | > |
| pointerSmall | | » |
| info | | i |
| warning | ⚠ | ‼ |
| hamburger | ☰ | ≡ |
| smiley | ㋡ | ☺ |
| mustache | ෴ | ┌─┐ |
| heart | ♥ | ♥ |
| arrowUp | ↑ | ↑ |
| arrowDown | ↓ | ↓ |
| arrowLeft | ← | ← |
| arrowRight | → | → |
| radioOn | ◉ | (*) |
| radioOff | ◯ | ( ) |
| checkboxOn | ☒ | [×] |
| checkboxOff | ☐ | [ ] |
| checkboxCircleOn | ⓧ | (×) |
| checkboxCircleOff | Ⓘ | ( ) |
| questionMarkPrefix | ?⃝ | |
| oneHalf | ½ | 1/2 |
| oneThird | ⅓ | 1/3 |
| oneQuarter | ¼ | 1/4 |
| oneFifth | ⅕ | 1/5 |
| oneSixth | ⅙ | 1/6 |
| oneSeventh | ⅐ | 1/7 |
| oneEighth | ⅛ | 1/8 |
| oneNinth | ⅑ | 1/9 |
| oneTenth | ⅒ | 1/10 |
| twoThirds | ⅔ | 2/3 |
| twoFifths | ⅖ | 2/5 |
| threeQuarters | ¾ | 3/4 |
| threeFifths | ⅗ | 3/5 |
| threeEighths | ⅜ | 3/8 |
| fourFifths | ⅘ | 4/5 |
| fiveSixths | ⅚ | 5/6 |
| fiveEighths | ⅝ | 5/8 |
| sevenEighths | ⅞ | 7/8 |
## Related
- [log-symbols](https://github.com/sindresorhus/log-symbols) - Colored symbols for various log levels
## License
MIT © [Sindre Sorhus](https://sindresorhus.com)

View File

@@ -0,0 +1,374 @@
Inquirer.js
===========
[![npm](https://badge.fury.io/js/inquirer.svg)](http://badge.fury.io/js/inquirer) [![tests](https://travis-ci.org/SBoudrias/Inquirer.js.svg?branch=master)](http://travis-ci.org/SBoudrias/Inquirer.js) [![Coverage Status](https://coveralls.io/repos/yeoman/generator/badge.svg)](https://coveralls.io/r/SBoudrias/Inquirer.js) [![dependencies](https://david-dm.org/SBoudrias/Inquirer.js.svg?theme=shields.io)](https://david-dm.org/SBoudrias/Inquirer.js)
A collection of common interactive command line user interfaces.
## Table of Contents
1. [Documentation](#documentation)
1. [Installation](#installation)
2. [Examples](#examples)
3. [Methods](#methods)
4. [Objects](#objects)
1. [Questions](#questions)
2. [Answers](#answers)
3. [Separator](#separator)
4. [Prompt Types](#prompt)
2. [User Interfaces and Layouts](#layouts)
1. [Reactive Interface](#reactive)
3. [Support](#support)
4. [News](#news)
5. [Contributing](#contributing)
6. [License](#license)
7. [Plugins](#plugins)
## Goal and Philosophy
<img align="right" alt="Inquirer Logo" src="/assets/inquirer_readme.png" title="Inquirer.js"/>
**`Inquirer.js`** strives to be an easily embeddable and beautiful command line interface for [Node.js](https://nodejs.org/) (and perhaps the "CLI [Xanadu](https://en.wikipedia.org/wiki/Citizen_Kane)").
**`Inquirer.js`** should ease the process of
- providing *error feedback*
- *asking questions*
- *parsing* input
- *validating* answers
- managing *hierarchical prompts*
> **Note:** **`Inquirer.js`** provides the user interface and the inquiry session flow. If you're searching for a full blown command line program utility, then check out [commander](https://github.com/visionmedia/commander.js), [vorpal](https://github.com/dthree/vorpal) or [args](https://github.com/leo/args).
## [Documentation](#documentation)
<a name="documentation"></a>
### Installation
<a name="installation"></a>
``` shell
npm install inquirer
```
```javascript
var inquirer = require('inquirer');
inquirer.prompt([/* Pass your questions in here */]).then(function (answers) {
// Use user feedback for... whatever!!
});
```
<a name="examples"></a>
### Examples (Run it and see it)
Check out the `examples/` folder for code and interface examples.
``` shell
node examples/pizza.js
node examples/checkbox.js
# etc...
```
### Methods
<a name="methods"></a>
#### `inquirer.prompt(questions) -> promise`
Launch the prompt interface (inquiry session)
- **questions** (Array) containing [Question Object](#question) (using the [reactive interface](#reactive-interface), you can also pass a `Rx.Observable` instance)
- returns a **Promise**
#### `inquirer.registerPrompt(name, prompt)`
Register prompt plugins under `name`.
- **name** (string) name of the this new prompt. (used for question `type`)
- **prompt** (object) the prompt object itself (the plugin)
#### `inquirer.createPromptModule() -> prompt function`
Create a self contained inquirer module. If you don't want to affect other libraries that also rely on inquirer when you overwrite or add new prompt types.
```js
var prompt = inquirer.createPromptModule();
prompt(questions).then(/* ... */);
```
### Objects
<a name="objects"></a>
#### Question
<a name="questions"></a>
A question object is a `hash` containing question related values:
- **type**: (String) Type of the prompt. Defaults: `input` - Possible values: `input`, `confirm`,
`list`, `rawlist`, `expand`, `checkbox`, `password`, `editor`
- **name**: (String) The name to use when storing the answer in the answers hash. If the name contains periods, it will define a path in the answers hash.
- **message**: (String|Function) The question to print. If defined as a function, the first parameter will be the current inquirer session answers.
- **default**: (String|Number|Array|Function) Default value(s) to use if nothing is entered, or a function that returns the default value(s). If defined as a function, the first parameter will be the current inquirer session answers.
- **choices**: (Array|Function) Choices array or a function returning a choices array. If defined as a function, the first parameter will be the current inquirer session answers.
Array values can be simple `strings`, or `objects` containing a `name` (to display in list), a `value` (to save in the answers hash) and a `short` (to display after selection) properties. The choices array can also contain [a `Separator`](#separator).
- **validate**: (Function) Receive the user input and answers hash. Should return `true` if the value is valid, and an error message (`String`) otherwise. If `false` is returned, a default error message is provided.
- **filter**: (Function) Receive the user input and return the filtered value to be used inside the program. The value returned will be added to the _Answers_ hash.
- **when**: (Function, Boolean) Receive the current user answers hash and should return `true` or `false` depending on whether or not this question should be asked. The value can also be a simple boolean.
- **pageSize**: (Number) Change the number of lines that will be rendered when using `list`, `rawList`, `expand` or `checkbox`.
`default`, `choices`(if defined as functions), `validate`, `filter` and `when` functions can be called asynchronous. Either return a promise or use `this.async()` to get a callback you'll call with the final value.
``` javascript
{
/* Preferred way: with promise */
filter: function () {
return new Promise(/* etc... */);
},
/* Legacy way: with this.async */
validate: function (input) {
// Declare function as asynchronous, and save the done callback
var done = this.async();
// Do async stuff
setTimeout(function () {
if (typeof input !== 'number') {
// Pass the return value in the done callback
done('You need to provide a number');
return;
}
// Pass the return value in the done callback
done(null, true);
}, 3000);
}
}
```
### Answers
<a name="answers"></a>
A key/value hash containing the client answers in each prompt.
- **Key** The `name` property of the _question_ object
- **Value** (Depends on the prompt)
- `confirm`: (Boolean)
- `input` : User input (filtered if `filter` is defined) (String)
- `rawlist`, `list` : Selected choice value (or name if no value specified) (String)
### Separator
<a name="separator"></a>
A separator can be added to any `choices` array:
```
// In the question object
choices: [ "Choice A", new inquirer.Separator(), "choice B" ]
// Which'll be displayed this way
[?] What do you want to do?
> Order a pizza
Make a reservation
--------
Ask opening hours
Talk to the receptionist
```
The constructor takes a facultative `String` value that'll be use as the separator. If omitted, the separator will be `--------`.
Separator instances have a property `type` equal to `separator`. This should allow tools façading Inquirer interface from detecting separator types in lists.
<a name="prompt"></a>
### Prompt types
---------------------
> **Note:**: _allowed options written inside square brackets (`[]`) are optional. Others are required._
#### List - `{type: 'list'}`
Take `type`, `name`, `message`, `choices`[, `default`, `filter`] properties. (Note that
default must be the choice `index` in the array or a choice `value`)
![List prompt](assets/screenshots/list-prompt.png)
---
#### Raw List - `{type: 'rawlist'}`
Take `type`, `name`, `message`, `choices`[, `default`, `filter`] properties. (Note that
default must the choice `index` in the array)
![Raw list prompt](assets/screenshots/rawlist-prompt.png)
---
#### Expand - `{type: 'expand'}`
Take `type`, `name`, `message`, `choices`[, `default`] properties. (Note that
default must be the choice `index` in the array. If `default` key not provided, then `help` will be used as default choice)
Note that the `choices` object will take an extra parameter called `key` for the `expand` prompt. This parameter must be a single (lowercased) character. The `h` option is added by the prompt and shouldn't be defined by the user.
See `examples/expand.js` for a running example.
![Expand prompt closed](assets/screenshots/expand-prompt-1.png)
![Expand prompt expanded](assets/screenshots/expand-prompt-2.png)
---
#### Checkbox - `{type: 'checkbox'}`
Take `type`, `name`, `message`, `choices`[, `filter`, `validate`, `default`] properties. `default` is expected to be an Array of the checked choices value.
Choices marked as `{checked: true}` will be checked by default.
Choices whose property `disabled` is truthy will be unselectable. If `disabled` is a string, then the string will be outputted next to the disabled choice, otherwise it'll default to `"Disabled"`. The `disabled` property can also be a synchronous function receiving the current answers as argument and returning a boolean or a string.
![Checkbox prompt](assets/screenshots/checkbox-prompt.png)
---
#### Confirm - `{type: 'confirm'}`
Take `type`, `name`, `message`[, `default`] properties. `default` is expected to be a boolean if used.
![Confirm prompt](assets/screenshots/confirm-prompt.png)
---
#### Input - `{type: 'input'}`
Take `type`, `name`, `message`[, `default`, `filter`, `validate`] properties.
![Input prompt](assets/screenshots/input-prompt.png)
---
#### Password - `{type: 'password'}`
Take `type`, `name`, `message`[, `default`, `filter`, `validate`] properties.
![Password prompt](assets/screenshots/password-prompt.png)
---
#### Editor - `{type: 'editor'}`
Take `type`, `name`, `message`[, `default`, `filter`, `validate`] properties
Launches an instance of the users preferred editor on a temporary file. Once the user exits their editor, the contents of the temporary file are read in as the result. The editor to use is determined by reading the $VISUAL or $EDITOR environment variables. If neither of those are present, notepad (on Windows) or vim (Linux or Mac) is used.
<a name="layouts"></a>
## User Interfaces and layouts
Along with the prompts, Inquirer offers some basic text UI.
#### Bottom Bar - `inquirer.ui.BottomBar`
This UI present a fixed text at the bottom of a free text zone. This is useful to keep a message to the bottom of the screen while outputting command outputs on the higher section.
```javascript
var ui = new inquirer.ui.BottomBar();
// pipe a Stream to the log zone
outputStream.pipe(ui.log);
// Or simply write output
ui.log.write('something just happened.');
ui.log.write('Almost over, standby!');
// During processing, update the bottom bar content to display a loader
// or output a progress bar, etc
ui.updateBottomBar('new bottom bar content');
```
<a name="reactive"></a>
## Reactive interface
Internally, Inquirer uses the [JS reactive extension](https://github.com/Reactive-Extensions/RxJS) to handle events and async flows.
This mean you can take advantage of this feature to provide more advanced flows. For example, you can dynamically add questions to be asked:
```js
var prompts = new Rx.Subject();
inquirer.prompt(prompts);
// At some point in the future, push new questions
prompts.onNext({ /* question... */ });
prompts.onNext({ /* question... */ });
// When you're done
prompts.onCompleted();
```
And using the return value `process` property, you can access more fine grained callbacks:
```js
inquirer.prompt(prompts).ui.process.subscribe(
onEachAnswer,
onError,
onComplete
);
```
## Support (OS Terminals)
<a name="support"></a>
You should expect mostly good support for the CLI below. This does not mean we won't
look at issues found on other command line - feel free to report any!
- **Mac OS**:
- Terminal.app
- iTerm
- **Windows**:
- [ConEmu](https://conemu.github.io/)
- cmd.exe
- Powershell
- Cygwin
- **Linux (Ubuntu, openSUSE, Arch Linux, etc)**:
- gnome-terminal (Terminal GNOME)
- konsole
## News on the march (Release notes)
<a name="news"></a>
Please refer to the [Github releases section for the changelog](https://github.com/SBoudrias/Inquirer.js/releases)
## Contributing
<a name="contributing"></a>
**Unit test**
Unit test are written in [Mocha](https://mochajs.org/). Please add a unit test for every new feature or bug fix. `npm test` to run the test suite.
**Documentation**
Add documentation for every API change. Feel free to send typo fixes and better docs!
We're looking to offer good support for multiple prompts and environments. If you want to
help, we'd like to keep a list of testers for each terminal/OS so we can contact you and
get feedback before release. Let us know if you want to be added to the list (just tweet
to [@vaxilart](https://twitter.com/Vaxilart)) or just add your name to [the wiki](https://github.com/SBoudrias/Inquirer.js/wiki/Testers)
## License
<a name="license"></a>
Copyright (c) 2016 Simon Boudrias (twitter: [@vaxilart](https://twitter.com/Vaxilart))
Licensed under the MIT license.
## Plugins
<a name="plugins"></a>
### Prompts ###
[__autocomplete__](https://github.com/mokkabonna/inquirer-autocomplete-prompt)<br>
Presents a list of options as the user types, compatible with other packages such as fuzzy (for search)<br>
<br>
![autocomplete prompt](https://github.com/mokkabonna/inquirer-autocomplete-prompt/raw/master/inquirer.gif)
[__datetime__](https://github.com/DerekTBrown/inquirer-datepicker-prompt)<br>
Customizable date/time selector using both number pad and arrow keys<br>
<br>
![Datetime Prompt](https://github.com/DerekTBrown/inquirer-datepicker-prompt/raw/master/example/datetime-prompt.png)
[__inquirer-select-line__](https://github.com/adam-golab/inquirer-select-line)<br>
Prompt for selecting index in array where add new element
![inquirer-select-line gif](https://media.giphy.com/media/xUA7b1MxpngddUvdHW/giphy.gif)

View File

@@ -0,0 +1,84 @@
/**
* Inquirer.js
* A collection of common interactive command line user interfaces.
*/
var inquirer = module.exports;
/**
* Client interfaces
*/
inquirer.prompts = {};
inquirer.Separator = require('./objects/separator');
inquirer.ui = {
BottomBar: require('./ui/bottom-bar'),
Prompt: require('./ui/prompt')
};
/**
* Create a new self-contained prompt module.
*/
inquirer.createPromptModule = function (opt) {
var promptModule = function (questions) {
var ui = new inquirer.ui.Prompt(promptModule.prompts, opt);
var promise = ui.run(questions);
// Monkey patch the UI on the promise object so
// that it remains publicly accessible.
promise.ui = ui;
return promise;
};
promptModule.prompts = {};
/**
* Register a prompt type
* @param {String} name Prompt type name
* @param {Function} prompt Prompt constructor
* @return {inquirer}
*/
promptModule.registerPrompt = function (name, prompt) {
promptModule.prompts[name] = prompt;
return this;
};
/**
* Register the defaults provider prompts
*/
promptModule.restoreDefaultPrompts = function () {
this.registerPrompt('list', require('./prompts/list'));
this.registerPrompt('input', require('./prompts/input'));
this.registerPrompt('confirm', require('./prompts/confirm'));
this.registerPrompt('rawlist', require('./prompts/rawlist'));
this.registerPrompt('expand', require('./prompts/expand'));
this.registerPrompt('checkbox', require('./prompts/checkbox'));
this.registerPrompt('password', require('./prompts/password'));
this.registerPrompt('editor', require('./prompts/editor'));
};
promptModule.restoreDefaultPrompts();
return promptModule;
};
/**
* Public CLI helper interface
* @param {Array|Object|rx.Observable} questions - Questions settings array
* @param {Function} cb - Callback being passed the user answers
* @return {inquirer.ui.Prompt}
*/
inquirer.prompt = inquirer.createPromptModule();
// Expose helper functions on the top level for easiest usage by common users
inquirer.registerPrompt = function (name, prompt) {
inquirer.prompt.registerPrompt(name, prompt);
};
inquirer.restoreDefaultPrompts = function () {
inquirer.prompt.restoreDefaultPrompts();
};

View File

@@ -0,0 +1,35 @@
'use strict';
var _ = require('lodash');
/**
* Choice object
* Normalize input as choice object
* @constructor
* @param {String|Object} val Choice value. If an object is passed, it should contains
* at least one of `value` or `name` property
*/
var Choice = module.exports = function (val, answers) {
// Don't process Choice and Separator object
if (val instanceof Choice || val.type === 'separator') {
return val;
}
if (_.isString(val)) {
this.name = val;
this.value = val;
this.short = val;
} else {
_.extend(this, val, {
name: val.name || val.value,
value: 'value' in val ? val.value : val.name,
short: val.short || val.name || val.value
});
}
if (_.isFunction(val.disabled)) {
this.disabled = val.disabled(answers);
} else {
this.disabled = val.disabled;
}
};

View File

@@ -0,0 +1,112 @@
'use strict';
var assert = require('assert');
var _ = require('lodash');
var Separator = require('./separator');
var Choice = require('./choice');
/**
* Choices collection
* Collection of multiple `choice` object
* @constructor
* @param {Array} choices All `choice` to keep in the collection
*/
var Choices = module.exports = function (choices, answers) {
this.choices = choices.map(function (val) {
if (val.type === 'separator') {
if (!(val instanceof Separator)) {
val = new Separator(val.line);
}
return val;
}
return new Choice(val, answers);
});
this.realChoices = this.choices
.filter(Separator.exclude)
.filter(function (item) {
return !item.disabled;
});
Object.defineProperty(this, 'length', {
get: function () {
return this.choices.length;
},
set: function (val) {
this.choices.length = val;
}
});
Object.defineProperty(this, 'realLength', {
get: function () {
return this.realChoices.length;
},
set: function () {
throw new Error('Cannot set `realLength` of a Choices collection');
}
});
};
/**
* Get a valid choice from the collection
* @param {Number} selector The selected choice index
* @return {Choice|Undefined} Return the matched choice or undefined
*/
Choices.prototype.getChoice = function (selector) {
assert(_.isNumber(selector));
return this.realChoices[selector];
};
/**
* Get a raw element from the collection
* @param {Number} selector The selected index value
* @return {Choice|Undefined} Return the matched choice or undefined
*/
Choices.prototype.get = function (selector) {
assert(_.isNumber(selector));
return this.choices[selector];
};
/**
* Match the valid choices against a where clause
* @param {Object} whereClause Lodash `where` clause
* @return {Array} Matching choices or empty array
*/
Choices.prototype.where = function (whereClause) {
return _.filter(this.realChoices, whereClause);
};
/**
* Pluck a particular key from the choices
* @param {String} propertyName Property name to select
* @return {Array} Selected properties
*/
Choices.prototype.pluck = function (propertyName) {
return _.map(this.realChoices, propertyName);
};
// Expose usual Array methods
Choices.prototype.indexOf = function () {
return this.choices.indexOf.apply(this.choices, arguments);
};
Choices.prototype.forEach = function () {
return this.choices.forEach.apply(this.choices, arguments);
};
Choices.prototype.filter = function () {
return this.choices.filter.apply(this.choices, arguments);
};
Choices.prototype.find = function (func) {
return _.find(this.choices, func);
};
Choices.prototype.push = function () {
var objs = _.map(arguments, function (val) {
return new Choice(val);
});
this.choices.push.apply(this.choices, objs);
this.realChoices = this.choices.filter(Separator.exclude);
return this.choices;
};

View File

@@ -0,0 +1,34 @@
'use strict';
var chalk = require('chalk');
var figures = require('figures');
/**
* Separator object
* Used to space/separate choices group
* @constructor
* @param {String} line Separation line content (facultative)
*/
var Separator = module.exports = function (line) {
this.type = 'separator';
this.line = chalk.dim(line || new Array(15).join(figures.line));
};
/**
* Helper function returning false if object is a separator
* @param {Object} obj object to test against
* @return {Boolean} `false` if object is a separator
*/
Separator.exclude = function (obj) {
return obj.type !== 'separator';
};
/**
* Stringify separator
* @return {String} the separator display string
*/
Separator.prototype.toString = function () {
return this.line;
};

View File

@@ -0,0 +1,137 @@
/**
* Base prompt implementation
* Should be extended by prompt types.
*/
var _ = require('lodash');
var chalk = require('chalk');
var runAsync = require('run-async');
var Choices = require('../objects/choices');
var ScreenManager = require('../utils/screen-manager');
var Prompt = module.exports = function (question, rl, answers) {
// Setup instance defaults property
_.assign(this, {
answers: answers,
status: 'pending'
});
// Set defaults prompt options
this.opt = _.defaults(_.clone(question), {
validate: function () {
return true;
},
filter: function (val) {
return val;
},
when: function () {
return true;
}
});
// Check to make sure prompt requirements are there
if (!this.opt.message) {
this.throwParamError('message');
}
if (!this.opt.name) {
this.throwParamError('name');
}
// Normalize choices
if (Array.isArray(this.opt.choices)) {
this.opt.choices = new Choices(this.opt.choices, answers);
}
this.rl = rl;
this.screen = new ScreenManager(this.rl);
};
/**
* Start the Inquiry session and manage output value filtering
* @return {Promise}
*/
Prompt.prototype.run = function () {
return new Promise(function (resolve) {
this._run(function (value) {
resolve(value);
});
}.bind(this));
};
// default noop (this one should be overwritten in prompts)
Prompt.prototype._run = function (cb) {
cb();
};
/**
* Throw an error telling a required parameter is missing
* @param {String} name Name of the missing param
* @return {Throw Error}
*/
Prompt.prototype.throwParamError = function (name) {
throw new Error('You must provide a `' + name + '` parameter');
};
/**
* Called when the UI closes. Override to do any specific cleanup necessary
*/
Prompt.prototype.close = function () {
this.screen.releaseCursor();
};
/**
* Run the provided validation method each time a submit event occur.
* @param {Rx.Observable} submit - submit event flow
* @return {Object} Object containing two observables: `success` and `error`
*/
Prompt.prototype.handleSubmitEvents = function (submit) {
var self = this;
var validate = runAsync(this.opt.validate);
var filter = runAsync(this.opt.filter);
var validation = submit.flatMap(function (value) {
return filter(value, self.answers).then(function (filteredValue) {
return validate(filteredValue, self.answers).then(function (isValid) {
return {isValid: isValid, value: filteredValue};
}, function (err) {
return {isValid: err};
});
}, function (err) {
return {isValid: err};
});
}).share();
var success = validation
.filter(function (state) {
return state.isValid === true;
})
.take(1);
var error = validation
.filter(function (state) {
return state.isValid !== true;
})
.takeUntil(success);
return {
success: success,
error: error
};
};
/**
* Generate the prompt question string
* @return {String} prompt question string
*/
Prompt.prototype.getQuestion = function () {
var message = chalk.green('?') + ' ' + chalk.bold(this.opt.message) + chalk.reset(' ');
// Append the default if available, and if question isn't answered
if (this.opt.default != null && this.status !== 'answered') {
message += chalk.dim('(' + this.opt.default + ') ');
}
return message;
};

View File

@@ -0,0 +1,236 @@
/**
* `list` type prompt
*/
var _ = require('lodash');
var util = require('util');
var chalk = require('chalk');
var cliCursor = require('cli-cursor');
var figures = require('figures');
var Base = require('./base');
var observe = require('../utils/events');
var Paginator = require('../utils/paginator');
/**
* Module exports
*/
module.exports = Prompt;
/**
* Constructor
*/
function Prompt() {
Base.apply(this, arguments);
if (!this.opt.choices) {
this.throwParamError('choices');
}
if (_.isArray(this.opt.default)) {
this.opt.choices.forEach(function (choice) {
if (this.opt.default.indexOf(choice.value) >= 0) {
choice.checked = true;
}
}, this);
}
this.pointer = 0;
this.firstRender = true;
// Make sure no default is set (so it won't be printed)
this.opt.default = null;
this.paginator = new Paginator();
}
util.inherits(Prompt, Base);
/**
* Start the Inquiry session
* @param {Function} cb Callback when prompt is done
* @return {this}
*/
Prompt.prototype._run = function (cb) {
this.done = cb;
var events = observe(this.rl);
var validation = this.handleSubmitEvents(
events.line.map(this.getCurrentValue.bind(this))
);
validation.success.forEach(this.onEnd.bind(this));
validation.error.forEach(this.onError.bind(this));
events.normalizedUpKey.takeUntil(validation.success).forEach(this.onUpKey.bind(this));
events.normalizedDownKey.takeUntil(validation.success).forEach(this.onDownKey.bind(this));
events.numberKey.takeUntil(validation.success).forEach(this.onNumberKey.bind(this));
events.spaceKey.takeUntil(validation.success).forEach(this.onSpaceKey.bind(this));
events.aKey.takeUntil(validation.success).forEach(this.onAllKey.bind(this));
events.iKey.takeUntil(validation.success).forEach(this.onInverseKey.bind(this));
// Init the prompt
cliCursor.hide();
this.render();
this.firstRender = false;
return this;
};
/**
* Render the prompt to screen
* @return {Prompt} self
*/
Prompt.prototype.render = function (error) {
// Render question
var message = this.getQuestion();
var bottomContent = '';
if (this.firstRender) {
message += '(Press ' + chalk.cyan.bold('<space>') + ' to select, ' + chalk.cyan.bold('<a>') + ' to toggle all, ' + chalk.cyan.bold('<i>') + ' to inverse selection)';
}
// Render choices or answer depending on the state
if (this.status === 'answered') {
message += chalk.cyan(this.selection.join(', '));
} else {
var choicesStr = renderChoices(this.opt.choices, this.pointer);
var indexPosition = this.opt.choices.indexOf(this.opt.choices.getChoice(this.pointer));
message += '\n' + this.paginator.paginate(choicesStr, indexPosition, this.opt.pageSize);
}
if (error) {
bottomContent = chalk.red('>> ') + error;
}
this.screen.render(message, bottomContent);
};
/**
* When user press `enter` key
*/
Prompt.prototype.onEnd = function (state) {
this.status = 'answered';
// Rerender prompt (and clean subline error)
this.render();
this.screen.done();
cliCursor.show();
this.done(state.value);
};
Prompt.prototype.onError = function (state) {
this.render(state.isValid);
};
Prompt.prototype.getCurrentValue = function () {
var choices = this.opt.choices.filter(function (choice) {
return Boolean(choice.checked) && !choice.disabled;
});
this.selection = _.map(choices, 'short');
return _.map(choices, 'value');
};
Prompt.prototype.onUpKey = function () {
var len = this.opt.choices.realLength;
this.pointer = (this.pointer > 0) ? this.pointer - 1 : len - 1;
this.render();
};
Prompt.prototype.onDownKey = function () {
var len = this.opt.choices.realLength;
this.pointer = (this.pointer < len - 1) ? this.pointer + 1 : 0;
this.render();
};
Prompt.prototype.onNumberKey = function (input) {
if (input <= this.opt.choices.realLength) {
this.pointer = input - 1;
this.toggleChoice(this.pointer);
}
this.render();
};
Prompt.prototype.onSpaceKey = function () {
this.toggleChoice(this.pointer);
this.render();
};
Prompt.prototype.onAllKey = function () {
var shouldBeChecked = Boolean(this.opt.choices.find(function (choice) {
return choice.type !== 'separator' && !choice.checked;
}));
this.opt.choices.forEach(function (choice) {
if (choice.type !== 'separator') {
choice.checked = shouldBeChecked;
}
});
this.render();
};
Prompt.prototype.onInverseKey = function () {
this.opt.choices.forEach(function (choice) {
if (choice.type !== 'separator') {
choice.checked = !choice.checked;
}
});
this.render();
};
Prompt.prototype.toggleChoice = function (index) {
var item = this.opt.choices.getChoice(index);
if (item !== undefined) {
this.opt.choices.getChoice(index).checked = !item.checked;
}
};
/**
* Function for rendering checkbox choices
* @param {Number} pointer Position of the pointer
* @return {String} Rendered content
*/
function renderChoices(choices, pointer) {
var output = '';
var separatorOffset = 0;
choices.forEach(function (choice, i) {
if (choice.type === 'separator') {
separatorOffset++;
output += ' ' + choice + '\n';
return;
}
if (choice.disabled) {
separatorOffset++;
output += ' - ' + choice.name;
output += ' (' + (_.isString(choice.disabled) ? choice.disabled : 'Disabled') + ')';
} else {
var isSelected = (i - separatorOffset === pointer);
output += isSelected ? chalk.cyan(figures.pointer) : ' ';
output += getCheckbox(choice.checked) + ' ' + choice.name;
}
output += '\n';
});
return output.replace(/\n$/, '');
}
/**
* Get the checkbox
* @param {Boolean} checked - add a X or not to the checkbox
* @return {String} Composited checkbox string
*/
function getCheckbox(checked) {
return checked ? chalk.green(figures.radioOn) : figures.radioOff;
}

View File

@@ -0,0 +1,106 @@
/**
* `confirm` type prompt
*/
var _ = require('lodash');
var util = require('util');
var chalk = require('chalk');
var Base = require('./base');
var observe = require('../utils/events');
/**
* Module exports
*/
module.exports = Prompt;
/**
* Constructor
*/
function Prompt() {
Base.apply(this, arguments);
var rawDefault = true;
_.extend(this.opt, {
filter: function (input) {
var value = rawDefault;
if (input != null && input !== '') {
value = /^y(es)?/i.test(input);
}
return value;
}
});
if (_.isBoolean(this.opt.default)) {
rawDefault = this.opt.default;
}
this.opt.default = rawDefault ? 'Y/n' : 'y/N';
return this;
}
util.inherits(Prompt, Base);
/**
* Start the Inquiry session
* @param {Function} cb Callback when prompt is done
* @return {this}
*/
Prompt.prototype._run = function (cb) {
this.done = cb;
// Once user confirm (enter key)
var events = observe(this.rl);
events.keypress.takeUntil(events.line).forEach(this.onKeypress.bind(this));
events.line.take(1).forEach(this.onEnd.bind(this));
// Init
this.render();
return this;
};
/**
* Render the prompt to screen
* @return {Prompt} self
*/
Prompt.prototype.render = function (answer) {
var message = this.getQuestion();
if (typeof answer === 'boolean') {
message += chalk.cyan(answer ? 'Yes' : 'No');
} else {
message += this.rl.line;
}
this.screen.render(message);
return this;
};
/**
* When user press `enter` key
*/
Prompt.prototype.onEnd = function (input) {
this.status = 'answered';
var output = this.opt.filter(input);
this.render(output);
this.screen.done();
this.done(output);
};
/**
* When user press a key
*/
Prompt.prototype.onKeypress = function () {
this.render();
};

View File

@@ -0,0 +1,111 @@
/**
* `editor` type prompt
*/
var util = require('util');
var chalk = require('chalk');
var ExternalEditor = require('external-editor');
var Base = require('./base');
var observe = require('../utils/events');
var rx = require('rx-lite-aggregates');
/**
* Module exports
*/
module.exports = Prompt;
/**
* Constructor
*/
function Prompt() {
return Base.apply(this, arguments);
}
util.inherits(Prompt, Base);
/**
* Start the Inquiry session
* @param {Function} cb Callback when prompt is done
* @return {this}
*/
Prompt.prototype._run = function (cb) {
this.done = cb;
this.editorResult = new rx.Subject();
// Open Editor on "line" (Enter Key)
var events = observe(this.rl);
this.lineSubscription = events.line.forEach(this.startExternalEditor.bind(this));
// Trigger Validation when editor closes
var validation = this.handleSubmitEvents(this.editorResult);
validation.success.forEach(this.onEnd.bind(this));
validation.error.forEach(this.onError.bind(this));
// Prevents default from being printed on screen (can look weird with multiple lines)
this.currentText = this.opt.default;
this.opt.default = null;
// Init
this.render();
return this;
};
/**
* Render the prompt to screen
* @return {Prompt} self
*/
Prompt.prototype.render = function (error) {
var bottomContent = '';
var message = this.getQuestion();
if (this.status === 'answered') {
message += chalk.dim('Received');
} else {
message += chalk.dim('Press <enter> to launch your preferred editor.');
}
if (error) {
bottomContent = chalk.red('>> ') + error;
}
this.screen.render(message, bottomContent);
};
/**
* Launch $EDITOR on user press enter
*/
Prompt.prototype.startExternalEditor = function () {
// Pause Readline to prevent stdin and stdout from being modified while the editor is showing
this.rl.pause();
ExternalEditor.editAsync(this.currentText, this.endExternalEditor.bind(this));
};
Prompt.prototype.endExternalEditor = function (error, result) {
this.rl.resume();
if (error) {
this.editorResult.onError(error);
} else {
this.editorResult.onNext(result);
}
};
Prompt.prototype.onEnd = function (state) {
this.editorResult.dispose();
this.lineSubscription.dispose();
this.answer = state.value;
this.status = 'answered';
// Re-render prompt
this.render();
this.screen.done();
this.done(this.answer);
};
Prompt.prototype.onError = function (state) {
this.render(state.isValid);
};

View File

@@ -0,0 +1,260 @@
/**
* `rawlist` type prompt
*/
var _ = require('lodash');
var util = require('util');
var chalk = require('chalk');
var Base = require('./base');
var Separator = require('../objects/separator');
var observe = require('../utils/events');
var Paginator = require('../utils/paginator');
/**
* Module exports
*/
module.exports = Prompt;
/**
* Constructor
*/
function Prompt() {
Base.apply(this, arguments);
if (!this.opt.choices) {
this.throwParamError('choices');
}
this.validateChoices(this.opt.choices);
// Add the default `help` (/expand) option
this.opt.choices.push({
key: 'h',
name: 'Help, list all options',
value: 'help'
});
this.opt.validate = function (choice) {
if (choice == null) {
return 'Please enter a valid command';
}
return choice !== 'help';
};
// Setup the default string (capitalize the default key)
this.opt.default = this.generateChoicesString(this.opt.choices, this.opt.default);
this.paginator = new Paginator();
}
util.inherits(Prompt, Base);
/**
* Start the Inquiry session
* @param {Function} cb Callback when prompt is done
* @return {this}
*/
Prompt.prototype._run = function (cb) {
this.done = cb;
// Save user answer and update prompt to show selected option.
var events = observe(this.rl);
var validation = this.handleSubmitEvents(
events.line.map(this.getCurrentValue.bind(this))
);
validation.success.forEach(this.onSubmit.bind(this));
validation.error.forEach(this.onError.bind(this));
this.keypressObs = events.keypress.takeUntil(validation.success)
.forEach(this.onKeypress.bind(this));
// Init the prompt
this.render();
return this;
};
/**
* Render the prompt to screen
* @return {Prompt} self
*/
Prompt.prototype.render = function (error, hint) {
var message = this.getQuestion();
var bottomContent = '';
if (this.status === 'answered') {
message += chalk.cyan(this.answer);
} else if (this.status === 'expanded') {
var choicesStr = renderChoices(this.opt.choices, this.selectedKey);
message += this.paginator.paginate(choicesStr, this.selectedKey, this.opt.pageSize);
message += '\n Answer: ';
}
message += this.rl.line;
if (error) {
bottomContent = chalk.red('>> ') + error;
}
if (hint) {
bottomContent = chalk.cyan('>> ') + hint;
}
this.screen.render(message, bottomContent);
};
Prompt.prototype.getCurrentValue = function (input) {
if (!input) {
input = this.rawDefault;
}
var selected = this.opt.choices.where({key: input.toLowerCase().trim()})[0];
if (!selected) {
return null;
}
return selected.value;
};
/**
* Generate the prompt choices string
* @return {String} Choices string
*/
Prompt.prototype.getChoices = function () {
var output = '';
this.opt.choices.forEach(function (choice) {
output += '\n ';
if (choice.type === 'separator') {
output += ' ' + choice;
return;
}
var choiceStr = choice.key + ') ' + choice.name;
if (this.selectedKey === choice.key) {
choiceStr = chalk.cyan(choiceStr);
}
output += choiceStr;
}.bind(this));
return output;
};
Prompt.prototype.onError = function (state) {
if (state.value === 'help') {
this.selectedKey = '';
this.status = 'expanded';
this.render();
return;
}
this.render(state.isValid);
};
/**
* When user press `enter` key
*/
Prompt.prototype.onSubmit = function (state) {
this.status = 'answered';
var choice = this.opt.choices.where({value: state.value})[0];
this.answer = choice.short || choice.name;
// Re-render prompt
this.render();
this.screen.done();
this.done(state.value);
};
/**
* When user press a key
*/
Prompt.prototype.onKeypress = function () {
this.selectedKey = this.rl.line.toLowerCase();
var selected = this.opt.choices.where({key: this.selectedKey})[0];
if (this.status === 'expanded') {
this.render();
} else {
this.render(null, selected ? selected.name : null);
}
};
/**
* Validate the choices
* @param {Array} choices
*/
Prompt.prototype.validateChoices = function (choices) {
var formatError;
var errors = [];
var keymap = {};
choices.filter(Separator.exclude).forEach(function (choice) {
if (!choice.key || choice.key.length !== 1) {
formatError = true;
}
if (keymap[choice.key]) {
errors.push(choice.key);
}
keymap[choice.key] = true;
choice.key = String(choice.key).toLowerCase();
});
if (formatError) {
throw new Error('Format error: `key` param must be a single letter and is required.');
}
if (keymap.h) {
throw new Error('Reserved key error: `key` param cannot be `h` - this value is reserved.');
}
if (errors.length) {
throw new Error('Duplicate key error: `key` param must be unique. Duplicates: ' +
_.uniq(errors).join(', '));
}
};
/**
* Generate a string out of the choices keys
* @param {Array} choices
* @param {Number} defaultIndex - the choice index to capitalize
* @return {String} The rendered choices key string
*/
Prompt.prototype.generateChoicesString = function (choices, defaultIndex) {
var defIndex = choices.realLength - 1;
if (_.isNumber(defaultIndex) && this.opt.choices.getChoice(defaultIndex)) {
defIndex = defaultIndex;
}
var defStr = this.opt.choices.pluck('key');
this.rawDefault = defStr[defIndex];
defStr[defIndex] = String(defStr[defIndex]).toUpperCase();
return defStr.join('');
};
/**
* Function for rendering checkbox choices
* @param {String} pointer Selected key
* @return {String} Rendered content
*/
function renderChoices(choices, pointer) {
var output = '';
choices.forEach(function (choice) {
output += '\n ';
if (choice.type === 'separator') {
output += ' ' + choice;
return;
}
var choiceStr = choice.key + ') ' + choice.name;
if (pointer === choice.key) {
choiceStr = chalk.cyan(choiceStr);
}
output += choiceStr;
});
return output;
}

View File

@@ -0,0 +1,104 @@
/**
* `input` type prompt
*/
var util = require('util');
var chalk = require('chalk');
var Base = require('./base');
var observe = require('../utils/events');
/**
* Module exports
*/
module.exports = Prompt;
/**
* Constructor
*/
function Prompt() {
return Base.apply(this, arguments);
}
util.inherits(Prompt, Base);
/**
* Start the Inquiry session
* @param {Function} cb Callback when prompt is done
* @return {this}
*/
Prompt.prototype._run = function (cb) {
this.done = cb;
// Once user confirm (enter key)
var events = observe(this.rl);
var submit = events.line.map(this.filterInput.bind(this));
var validation = this.handleSubmitEvents(submit);
validation.success.forEach(this.onEnd.bind(this));
validation.error.forEach(this.onError.bind(this));
events.keypress.takeUntil(validation.success).forEach(this.onKeypress.bind(this));
// Init
this.render();
return this;
};
/**
* Render the prompt to screen
* @return {Prompt} self
*/
Prompt.prototype.render = function (error) {
var bottomContent = '';
var message = this.getQuestion();
if (this.status === 'answered') {
message += chalk.cyan(this.answer);
} else {
message += this.rl.line;
}
if (error) {
bottomContent = chalk.red('>> ') + error;
}
this.screen.render(message, bottomContent);
};
/**
* When user press `enter` key
*/
Prompt.prototype.filterInput = function (input) {
if (!input) {
return this.opt.default == null ? '' : this.opt.default;
}
return input;
};
Prompt.prototype.onEnd = function (state) {
this.answer = state.value;
this.status = 'answered';
// Re-render prompt
this.render();
this.screen.done();
this.done(state.value);
};
Prompt.prototype.onError = function (state) {
this.render(state.isValid);
};
/**
* When user press a key
*/
Prompt.prototype.onKeypress = function () {
this.render();
};

View File

@@ -0,0 +1,184 @@
/**
* `list` type prompt
*/
var _ = require('lodash');
var util = require('util');
var chalk = require('chalk');
var figures = require('figures');
var cliCursor = require('cli-cursor');
var runAsync = require('run-async');
var Base = require('./base');
var observe = require('../utils/events');
var Paginator = require('../utils/paginator');
/**
* Module exports
*/
module.exports = Prompt;
/**
* Constructor
*/
function Prompt() {
Base.apply(this, arguments);
if (!this.opt.choices) {
this.throwParamError('choices');
}
this.firstRender = true;
this.selected = 0;
var def = this.opt.default;
// If def is a Number, then use as index. Otherwise, check for value.
if (_.isNumber(def) && def >= 0 && def < this.opt.choices.realLength) {
this.selected = def;
} else if (!_.isNumber(def) && def != null) {
this.selected = this.opt.choices.pluck('value').indexOf(def);
}
// Make sure no default is set (so it won't be printed)
this.opt.default = null;
this.paginator = new Paginator();
}
util.inherits(Prompt, Base);
/**
* Start the Inquiry session
* @param {Function} cb Callback when prompt is done
* @return {this}
*/
Prompt.prototype._run = function (cb) {
this.done = cb;
var self = this;
var events = observe(this.rl);
events.normalizedUpKey.takeUntil(events.line).forEach(this.onUpKey.bind(this));
events.normalizedDownKey.takeUntil(events.line).forEach(this.onDownKey.bind(this));
events.numberKey.takeUntil(events.line).forEach(this.onNumberKey.bind(this));
events.line
.take(1)
.map(this.getCurrentValue.bind(this))
.flatMap(function (value) {
return runAsync(self.opt.filter)(value).catch(function (err) {
return err;
});
})
.forEach(this.onSubmit.bind(this));
// Init the prompt
cliCursor.hide();
this.render();
return this;
};
/**
* Render the prompt to screen
* @return {Prompt} self
*/
Prompt.prototype.render = function () {
// Render question
var message = this.getQuestion();
if (this.firstRender) {
message += chalk.dim('(Use arrow keys)');
}
// Render choices or answer depending on the state
if (this.status === 'answered') {
message += chalk.cyan(this.opt.choices.getChoice(this.selected).short);
} else {
var choicesStr = listRender(this.opt.choices, this.selected);
var indexPosition = this.opt.choices.indexOf(this.opt.choices.getChoice(this.selected));
message += '\n' + this.paginator.paginate(choicesStr, indexPosition, this.opt.pageSize);
}
this.firstRender = false;
this.screen.render(message);
};
/**
* When user press `enter` key
*/
Prompt.prototype.onSubmit = function (value) {
this.status = 'answered';
// Rerender prompt
this.render();
this.screen.done();
cliCursor.show();
this.done(value);
};
Prompt.prototype.getCurrentValue = function () {
return this.opt.choices.getChoice(this.selected).value;
};
/**
* When user press a key
*/
Prompt.prototype.onUpKey = function () {
var len = this.opt.choices.realLength;
this.selected = (this.selected > 0) ? this.selected - 1 : len - 1;
this.render();
};
Prompt.prototype.onDownKey = function () {
var len = this.opt.choices.realLength;
this.selected = (this.selected < len - 1) ? this.selected + 1 : 0;
this.render();
};
Prompt.prototype.onNumberKey = function (input) {
if (input <= this.opt.choices.realLength) {
this.selected = input - 1;
}
this.render();
};
/**
* Function for rendering list choices
* @param {Number} pointer Position of the pointer
* @return {String} Rendered content
*/
function listRender(choices, pointer) {
var output = '';
var separatorOffset = 0;
choices.forEach(function (choice, i) {
if (choice.type === 'separator') {
separatorOffset++;
output += ' ' + choice + '\n';
return;
}
if (choice.disabled) {
separatorOffset++;
output += ' - ' + choice.name;
output += ' (' + (_.isString(choice.disabled) ? choice.disabled : 'Disabled') + ')';
output += '\n';
return;
}
var isSelected = (i - separatorOffset === pointer);
var line = (isSelected ? figures.pointer + ' ' : ' ') + choice.name;
if (isSelected) {
line = chalk.cyan(line);
}
output += line + ' \n';
});
return output.replace(/\n$/, '');
}

View File

@@ -0,0 +1,115 @@
/**
* `password` type prompt
*/
var util = require('util');
var chalk = require('chalk');
var Base = require('./base');
var observe = require('../utils/events');
function mask(input, maskChar) {
input = String(input);
maskChar = typeof maskChar === 'string' ? maskChar : '*';
if (input.length === 0) {
return '';
}
return new Array(input.length + 1).join(maskChar);
}
/**
* Module exports
*/
module.exports = Prompt;
/**
* Constructor
*/
function Prompt() {
return Base.apply(this, arguments);
}
util.inherits(Prompt, Base);
/**
* Start the Inquiry session
* @param {Function} cb Callback when prompt is done
* @return {this}
*/
Prompt.prototype._run = function (cb) {
this.done = cb;
var events = observe(this.rl);
// Once user confirm (enter key)
var submit = events.line.map(this.filterInput.bind(this));
var validation = this.handleSubmitEvents(submit);
validation.success.forEach(this.onEnd.bind(this));
validation.error.forEach(this.onError.bind(this));
if (this.opt.mask) {
events.keypress.takeUntil(validation.success).forEach(this.onKeypress.bind(this));
}
// Init
this.render();
return this;
};
/**
* Render the prompt to screen
* @return {Prompt} self
*/
Prompt.prototype.render = function (error) {
var message = this.getQuestion();
var bottomContent = '';
if (this.status === 'answered') {
message += this.opt.mask ? chalk.cyan(mask(this.answer, this.opt.mask)) : chalk.italic.dim('[hidden]');
} else if (this.opt.mask) {
message += mask(this.rl.line || '', this.opt.mask);
} else {
message += chalk.italic.dim('[input is hidden] ');
}
if (error) {
bottomContent = '\n' + chalk.red('>> ') + error;
}
this.screen.render(message, bottomContent);
};
/**
* When user press `enter` key
*/
Prompt.prototype.filterInput = function (input) {
if (!input) {
return this.opt.default == null ? '' : this.opt.default;
}
return input;
};
Prompt.prototype.onEnd = function (state) {
this.status = 'answered';
this.answer = state.value;
// Re-render prompt
this.render();
this.screen.done();
this.done(state.value);
};
Prompt.prototype.onError = function (state) {
this.render(state.isValid);
};
Prompt.prototype.onKeypress = function () {
this.render();
};

View File

@@ -0,0 +1,179 @@
/**
* `rawlist` type prompt
*/
var _ = require('lodash');
var util = require('util');
var chalk = require('chalk');
var Base = require('./base');
var Separator = require('../objects/separator');
var observe = require('../utils/events');
var Paginator = require('../utils/paginator');
/**
* Module exports
*/
module.exports = Prompt;
/**
* Constructor
*/
function Prompt() {
Base.apply(this, arguments);
if (!this.opt.choices) {
this.throwParamError('choices');
}
this.opt.validChoices = this.opt.choices.filter(Separator.exclude);
this.selected = 0;
this.rawDefault = 0;
_.extend(this.opt, {
validate: function (val) {
return val != null;
}
});
var def = this.opt.default;
if (_.isNumber(def) && def >= 0 && def < this.opt.choices.realLength) {
this.selected = this.rawDefault = def;
}
// Make sure no default is set (so it won't be printed)
this.opt.default = null;
this.paginator = new Paginator();
}
util.inherits(Prompt, Base);
/**
* Start the Inquiry session
* @param {Function} cb Callback when prompt is done
* @return {this}
*/
Prompt.prototype._run = function (cb) {
this.done = cb;
// Once user confirm (enter key)
var events = observe(this.rl);
var submit = events.line.map(this.getCurrentValue.bind(this));
var validation = this.handleSubmitEvents(submit);
validation.success.forEach(this.onEnd.bind(this));
validation.error.forEach(this.onError.bind(this));
events.keypress.takeUntil(validation.success).forEach(this.onKeypress.bind(this));
// Init the prompt
this.render();
return this;
};
/**
* Render the prompt to screen
* @return {Prompt} self
*/
Prompt.prototype.render = function (error) {
// Render question
var message = this.getQuestion();
var bottomContent = '';
if (this.status === 'answered') {
message += chalk.cyan(this.answer);
} else {
var choicesStr = renderChoices(this.opt.choices, this.selected);
message += this.paginator.paginate(choicesStr, this.selected, this.opt.pageSize);
message += '\n Answer: ';
}
message += this.rl.line;
if (error) {
bottomContent = '\n' + chalk.red('>> ') + error;
}
this.screen.render(message, bottomContent);
};
/**
* When user press `enter` key
*/
Prompt.prototype.getCurrentValue = function (index) {
if (index == null || index === '') {
index = this.rawDefault;
} else {
index -= 1;
}
var choice = this.opt.choices.getChoice(index);
return choice ? choice.value : null;
};
Prompt.prototype.onEnd = function (state) {
this.status = 'answered';
this.answer = state.value;
// Re-render prompt
this.render();
this.screen.done();
this.done(state.value);
};
Prompt.prototype.onError = function () {
this.render('Please enter a valid index');
};
/**
* When user press a key
*/
Prompt.prototype.onKeypress = function () {
var index = this.rl.line.length ? Number(this.rl.line) - 1 : 0;
if (this.opt.choices.getChoice(index)) {
this.selected = index;
} else {
this.selected = undefined;
}
this.render();
};
/**
* Function for rendering list choices
* @param {Number} pointer Position of the pointer
* @return {String} Rendered content
*/
function renderChoices(choices, pointer) {
var output = '';
var separatorOffset = 0;
choices.forEach(function (choice, i) {
output += '\n ';
if (choice.type === 'separator') {
separatorOffset++;
output += ' ' + choice;
return;
}
var index = i - separatorOffset;
var display = (index + 1) + ') ' + choice.name;
if (index === pointer) {
display = chalk.cyan(display);
}
output += display;
});
return output;
}

View File

@@ -0,0 +1,75 @@
'use strict';
var _ = require('lodash');
var MuteStream = require('mute-stream');
var readline = require('readline');
/**
* Base interface class other can inherits from
*/
var UI = module.exports = function (opt) {
// Instantiate the Readline interface
// @Note: Don't reassign if already present (allow test to override the Stream)
if (!this.rl) {
this.rl = readline.createInterface(setupReadlineOptions(opt));
}
this.rl.resume();
this.onForceClose = this.onForceClose.bind(this);
// Make sure new prompt start on a newline when closing
process.on('exit', this.onForceClose);
// Terminate process on SIGINT (which will call process.on('exit') in return)
this.rl.on('SIGINT', this.onForceClose);
};
/**
* Handle the ^C exit
* @return {null}
*/
UI.prototype.onForceClose = function () {
this.close();
process.kill(process.pid, 'SIGINT');
console.log('');
};
/**
* Close the interface and cleanup listeners
*/
UI.prototype.close = function () {
// Remove events listeners
this.rl.removeListener('SIGINT', this.onForceClose);
process.removeListener('exit', this.onForceClose);
this.rl.output.unmute();
if (this.activePrompt && typeof this.activePrompt.close === 'function') {
this.activePrompt.close();
}
// Close the readline
this.rl.output.end();
this.rl.pause();
this.rl.close();
};
function setupReadlineOptions(opt) {
opt = opt || {};
// Default `input` to stdin
var input = opt.input || process.stdin;
// Add mute capabilities to the output
var ms = new MuteStream();
ms.pipe(opt.output || process.stdout);
var output = ms;
return _.extend({
terminal: true,
input: input,
output: output
}, _.omit(opt, ['input', 'output']));
}

View File

@@ -0,0 +1,105 @@
/**
* Sticky bottom bar user interface
*/
var util = require('util');
var through = require('through');
var Base = require('./baseUI');
var rlUtils = require('../utils/readline');
var _ = require('lodash');
/**
* Module exports
*/
module.exports = Prompt;
/**
* Constructor
*/
function Prompt(opt) {
opt || (opt = {});
Base.apply(this, arguments);
this.log = through(this.writeLog.bind(this));
this.bottomBar = opt.bottomBar || '';
this.render();
}
util.inherits(Prompt, Base);
/**
* Render the prompt to screen
* @return {Prompt} self
*/
Prompt.prototype.render = function () {
this.write(this.bottomBar);
return this;
};
Prompt.prototype.clean = function () {
rlUtils.clearLine(this.rl, this.bottomBar.split('\n').length);
return this;
};
/**
* Update the bottom bar content and rerender
* @param {String} bottomBar Bottom bar content
* @return {Prompt} self
*/
Prompt.prototype.updateBottomBar = function (bottomBar) {
this.bottomBar = bottomBar;
rlUtils.clearLine(this.rl, 1);
this.rl.output.unmute();
this.clean().render();
this.rl.output.mute();
return this;
};
/**
* Write out log data
* @param {String} data - The log data to be output
* @return {Prompt} self
*/
Prompt.prototype.writeLog = function (data) {
this.rl.output.unmute();
this.clean();
this.rl.output.write(this.enforceLF(data.toString()));
this.render();
this.rl.output.mute();
return this;
};
/**
* Make sure line end on a line feed
* @param {String} str Input string
* @return {String} The input string with a final line feed
*/
Prompt.prototype.enforceLF = function (str) {
return str.match(/[\r\n]$/) ? str : str + '\n';
};
/**
* Helper for writing message in Prompt
* @param {Prompt} prompt - The Prompt object that extends tty
* @param {String} message - The message to be output
*/
Prompt.prototype.write = function (message) {
var msgLines = message.split(/\n/);
this.height = msgLines.length;
// Write message to screen and setPrompt to control backspace
this.rl.setPrompt(_.last(msgLines));
if (this.rl.output.rows === 0 && this.rl.output.columns === 0) {
/* When it's a tty through serial port there's no terminal info and the render will malfunction,
so we need enforce the cursor to locate to the leftmost position for rendering. */
rlUtils.left(this.rl, message.length + this.rl.line.length);
}
this.rl.output.write(message);
};

View File

@@ -0,0 +1,115 @@
'use strict';
var _ = require('lodash');
var rx = require('rx-lite-aggregates');
var util = require('util');
var runAsync = require('run-async');
var utils = require('../utils/utils');
var Base = require('./baseUI');
/**
* Base interface class other can inherits from
*/
var PromptUI = module.exports = function (prompts, opt) {
Base.call(this, opt);
this.prompts = prompts;
};
util.inherits(PromptUI, Base);
PromptUI.prototype.run = function (questions) {
// Keep global reference to the answers
this.answers = {};
// Make sure questions is an array.
if (_.isPlainObject(questions)) {
questions = [questions];
}
// Create an observable, unless we received one as parameter.
// Note: As this is a public interface, we cannot do an instanceof check as we won't
// be using the exact same object in memory.
var obs = _.isArray(questions) ? rx.Observable.from(questions) : questions;
this.process = obs
.concatMap(this.processQuestion.bind(this))
// `publish` creates a hot Observable. It prevents duplicating prompts.
.publish();
this.process.connect();
return this.process
.reduce(function (answers, answer) {
_.set(this.answers, answer.name, answer.answer);
return this.answers;
}.bind(this), {})
.toPromise(Promise)
.then(this.onCompletion.bind(this));
};
/**
* Once all prompt are over
*/
PromptUI.prototype.onCompletion = function (answers) {
this.close();
return answers;
};
PromptUI.prototype.processQuestion = function (question) {
question = _.clone(question);
return rx.Observable.defer(function () {
var obs = rx.Observable.of(question);
return obs
.concatMap(this.setDefaultType.bind(this))
.concatMap(this.filterIfRunnable.bind(this))
.concatMap(utils.fetchAsyncQuestionProperty.bind(null, question, 'message', this.answers))
.concatMap(utils.fetchAsyncQuestionProperty.bind(null, question, 'default', this.answers))
.concatMap(utils.fetchAsyncQuestionProperty.bind(null, question, 'choices', this.answers))
.concatMap(this.fetchAnswer.bind(this));
}.bind(this));
};
PromptUI.prototype.fetchAnswer = function (question) {
var Prompt = this.prompts[question.type];
this.activePrompt = new Prompt(question, this.rl, this.answers);
return rx.Observable.defer(function () {
return rx.Observable.fromPromise(this.activePrompt.run().then(function (answer) {
return {name: question.name, answer: answer};
}));
}.bind(this));
};
PromptUI.prototype.setDefaultType = function (question) {
// Default type to input
if (!this.prompts[question.type]) {
question.type = 'input';
}
return rx.Observable.defer(function () {
return rx.Observable.return(question);
});
};
PromptUI.prototype.filterIfRunnable = function (question) {
if (question.when === false) {
return rx.Observable.empty();
}
if (!_.isFunction(question.when)) {
return rx.Observable.return(question);
}
var answers = this.answers;
return rx.Observable.defer(function () {
return rx.Observable.fromPromise(
runAsync(question.when)(answers).then(function (shouldRun) {
if (shouldRun) {
return question;
}
})
).filter(function (val) {
return val != null;
});
});
};

View File

@@ -0,0 +1,45 @@
'use strict';
var rx = require('rx-lite-aggregates');
function normalizeKeypressEvents(value, key) {
return {value: value, key: key || {}};
}
module.exports = function (rl) {
var keypress = rx.Observable.fromEvent(rl.input, 'keypress', normalizeKeypressEvents)
.filter(function (e) {
// Ignore `enter` key. On the readline, we only care about the `line` event.
return e.key.name !== 'enter' && e.key.name !== 'return';
});
return {
line: rx.Observable.fromEvent(rl, 'line'),
keypress: keypress,
normalizedUpKey: keypress.filter(function (e) {
return e.key.name === 'up' || e.key.name === 'k' || (e.key.name === 'p' && e.key.ctrl);
}).share(),
normalizedDownKey: keypress.filter(function (e) {
return e.key.name === 'down' || e.key.name === 'j' || (e.key.name === 'n' && e.key.ctrl);
}).share(),
numberKey: keypress.filter(function (e) {
return e.value && '123456789'.indexOf(e.value) >= 0;
}).map(function (e) {
return Number(e.value);
}).share(),
spaceKey: keypress.filter(function (e) {
return e.key && e.key.name === 'space';
}).share(),
aKey: keypress.filter(function (e) {
return e.key && e.key.name === 'a';
}).share(),
iKey: keypress.filter(function (e) {
return e.key && e.key.name === 'i';
}).share()
};
};

View File

@@ -0,0 +1,38 @@
'use strict';
var _ = require('lodash');
var chalk = require('chalk');
/**
* The paginator keeps track of a pointer index in a list and returns
* a subset of the choices if the list is too long.
*/
var Paginator = module.exports = function () {
this.pointer = 0;
this.lastIndex = 0;
};
Paginator.prototype.paginate = function (output, active, pageSize) {
pageSize = pageSize || 7;
var middleOfList = Math.floor(pageSize / 2);
var lines = output.split('\n');
// Make sure there's enough lines to paginate
if (lines.length <= pageSize) {
return output;
}
// Move the pointer only when the user go down and limit it to the middle of the list
if (this.pointer < middleOfList && this.lastIndex < active && active - this.lastIndex < pageSize) {
this.pointer = Math.min(middleOfList, this.pointer + active - this.lastIndex);
}
this.lastIndex = active;
// Duplicate the lines so it give an infinite list look
var infinite = _.flatten([lines, lines, lines]);
var topIndex = Math.max(0, active + lines.length - this.pointer);
var section = infinite.splice(topIndex, pageSize).join('\n');
return section + '\n' + chalk.dim('(Move up and down to reveal more choices)');
};

View File

@@ -0,0 +1,51 @@
'use strict';
var ansiEscapes = require('ansi-escapes');
/**
* Move cursor left by `x`
* @param {Readline} rl - Readline instance
* @param {Number} x - How far to go left (default to 1)
*/
exports.left = function (rl, x) {
rl.output.write(ansiEscapes.cursorBackward(x));
};
/**
* Move cursor right by `x`
* @param {Readline} rl - Readline instance
* @param {Number} x - How far to go left (default to 1)
*/
exports.right = function (rl, x) {
rl.output.write(ansiEscapes.cursorForward(x));
};
/**
* Move cursor up by `x`
* @param {Readline} rl - Readline instance
* @param {Number} x - How far to go up (default to 1)
*/
exports.up = function (rl, x) {
rl.output.write(ansiEscapes.cursorUp(x));
};
/**
* Move cursor down by `x`
* @param {Readline} rl - Readline instance
* @param {Number} x - How far to go down (default to 1)
*/
exports.down = function (rl, x) {
rl.output.write(ansiEscapes.cursorDown(x));
};
/**
* Clear current line
* @param {Readline} rl - Readline instance
* @param {Number} len - number of line to delete
*/
exports.clearLine = function (rl, len) {
rl.output.write(ansiEscapes.eraseLines(len));
};

View File

@@ -0,0 +1,135 @@
'use strict';
var _ = require('lodash');
var util = require('./readline');
var cliWidth = require('cli-width');
var stripAnsi = require('strip-ansi');
var stringWidth = require('string-width');
function height(content) {
return content.split('\n').length;
}
function lastLine(content) {
return _.last(content.split('\n'));
}
var ScreenManager = module.exports = function (rl) {
// These variables are keeping information to allow correct prompt re-rendering
this.height = 0;
this.extraLinesUnderPrompt = 0;
this.rl = rl;
};
ScreenManager.prototype.render = function (content, bottomContent) {
this.rl.output.unmute();
this.clean(this.extraLinesUnderPrompt);
/**
* Write message to screen and setPrompt to control backspace
*/
var promptLine = lastLine(content);
var rawPromptLine = stripAnsi(promptLine);
// Remove the rl.line from our prompt. We can't rely on the content of
// rl.line (mainly because of the password prompt), so just rely on it's
// length.
var prompt = promptLine;
if (this.rl.line.length) {
prompt = prompt.slice(0, -this.rl.line.length);
}
this.rl.setPrompt(prompt);
// setPrompt will change cursor position, now we can get correct value
var cursorPos = this.rl._getCursorPos();
var width = this.normalizedCliWidth();
content = forceLineReturn(content, width);
if (bottomContent) {
bottomContent = forceLineReturn(bottomContent, width);
}
// Manually insert an extra line if we're at the end of the line.
// This prevent the cursor from appearing at the beginning of the
// current line.
if (rawPromptLine.length % width === 0) {
content += '\n';
}
var fullContent = content + (bottomContent ? '\n' + bottomContent : '');
this.rl.output.write(fullContent);
/**
* Re-adjust the cursor at the correct position.
*/
// We need to consider parts of the prompt under the cursor as part of the bottom
// content in order to correctly cleanup and re-render.
var promptLineUpDiff = Math.floor(rawPromptLine.length / width) - cursorPos.rows;
var bottomContentHeight = promptLineUpDiff + (bottomContent ? height(bottomContent) : 0);
if (bottomContentHeight > 0) {
util.up(this.rl, bottomContentHeight);
}
// Reset cursor at the beginning of the line
util.left(this.rl, stringWidth(lastLine(fullContent)));
// Adjust cursor on the right
util.right(this.rl, cursorPos.cols);
/**
* Set up state for next re-rendering
*/
this.extraLinesUnderPrompt = bottomContentHeight;
this.height = height(fullContent);
this.rl.output.mute();
};
ScreenManager.prototype.clean = function (extraLines) {
if (extraLines > 0) {
util.down(this.rl, extraLines);
}
util.clearLine(this.rl, this.height);
};
ScreenManager.prototype.done = function () {
this.rl.setPrompt('');
this.rl.output.unmute();
this.rl.output.write('\n');
};
ScreenManager.prototype.releaseCursor = function () {
if (this.extraLinesUnderPrompt > 0) {
util.down(this.rl, this.extraLinesUnderPrompt);
}
};
ScreenManager.prototype.normalizedCliWidth = function () {
var width = cliWidth({
defaultWidth: 80,
output: this.rl.output
});
if (process.platform === 'win32') {
return width - 1;
}
return width;
};
function breakLines(lines, width) {
// Break lines who're longuer than the cli width so we can normalize the natural line
// returns behavior accross terminals.
var regex = new RegExp(
'(?:(?:\\033[[0-9;]*m)*.?){1,' + width + '}',
'g'
);
return lines.map(function (line) {
var chunk = line.match(regex);
// last match is always empty
chunk.pop();
return chunk || '';
});
}
function forceLineReturn(content, width) {
return _.flatten(breakLines(content.split('\n'), width)).join('\n');
}

View File

@@ -0,0 +1,26 @@
'use strict';
var _ = require('lodash');
var rx = require('rx-lite-aggregates');
var runAsync = require('run-async');
/**
* Resolve a question property value if it is passed as a function.
* This method will overwrite the property on the question object with the received value.
* @param {Object} question - Question object
* @param {String} prop - Property to fetch name
* @param {Object} answers - Answers object
* @return {rx.Obsersable} - Observable emitting once value is known
*/
exports.fetchAsyncQuestionProperty = function (question, prop, answers) {
if (!_.isFunction(question[prop])) {
return rx.Observable.return(question);
}
return rx.Observable.fromPromise(runAsync(question[prop])(answers)
.then(function (value) {
question[prop] = value;
return question;
})
);
};

View File

@@ -0,0 +1,220 @@
'use strict';
const escapeStringRegexp = require('escape-string-regexp');
const ansiStyles = require('ansi-styles');
const supportsColor = require('supports-color');
const template = require('./templates.js');
const isSimpleWindowsTerm = process.platform === 'win32' && !(process.env.TERM || '').toLowerCase().startsWith('xterm');
// `supportsColor.level` → `ansiStyles.color[name]` mapping
const levelMapping = ['ansi', 'ansi', 'ansi256', 'ansi16m'];
// `color-convert` models to exclude from the Chalk API due to conflicts and such
const skipModels = new Set(['gray']);
const styles = Object.create(null);
function applyOptions(obj, options) {
options = options || {};
// Detect level if not set manually
const scLevel = supportsColor ? supportsColor.level : 0;
obj.level = options.level === undefined ? scLevel : options.level;
obj.enabled = 'enabled' in options ? options.enabled : obj.level > 0;
}
function Chalk(options) {
// We check for this.template here since calling `chalk.constructor()`
// by itself will have a `this` of a previously constructed chalk object
if (!this || !(this instanceof Chalk) || this.template) {
const chalk = {};
applyOptions(chalk, options);
chalk.template = function () {
const args = [].slice.call(arguments);
return chalkTag.apply(null, [chalk.template].concat(args));
};
Object.setPrototypeOf(chalk, Chalk.prototype);
Object.setPrototypeOf(chalk.template, chalk);
chalk.template.constructor = Chalk;
return chalk.template;
}
applyOptions(this, options);
}
// Use bright blue on Windows as the normal blue color is illegible
if (isSimpleWindowsTerm) {
ansiStyles.blue.open = '\u001B[94m';
}
for (const key of Object.keys(ansiStyles)) {
ansiStyles[key].closeRe = new RegExp(escapeStringRegexp(ansiStyles[key].close), 'g');
styles[key] = {
get() {
const codes = ansiStyles[key];
return build.call(this, this._styles ? this._styles.concat(codes) : [codes], key);
}
};
}
ansiStyles.color.closeRe = new RegExp(escapeStringRegexp(ansiStyles.color.close), 'g');
for (const model of Object.keys(ansiStyles.color.ansi)) {
if (skipModels.has(model)) {
continue;
}
styles[model] = {
get() {
const level = this.level;
return function () {
const open = ansiStyles.color[levelMapping[level]][model].apply(null, arguments);
const codes = {
open,
close: ansiStyles.color.close,
closeRe: ansiStyles.color.closeRe
};
return build.call(this, this._styles ? this._styles.concat(codes) : [codes], model);
};
}
};
}
ansiStyles.bgColor.closeRe = new RegExp(escapeStringRegexp(ansiStyles.bgColor.close), 'g');
for (const model of Object.keys(ansiStyles.bgColor.ansi)) {
if (skipModels.has(model)) {
continue;
}
const bgModel = 'bg' + model[0].toUpperCase() + model.slice(1);
styles[bgModel] = {
get() {
const level = this.level;
return function () {
const open = ansiStyles.bgColor[levelMapping[level]][model].apply(null, arguments);
const codes = {
open,
close: ansiStyles.bgColor.close,
closeRe: ansiStyles.bgColor.closeRe
};
return build.call(this, this._styles ? this._styles.concat(codes) : [codes], model);
};
}
};
}
const proto = Object.defineProperties(() => {}, styles);
function build(_styles, key) {
const builder = function () {
return applyStyle.apply(builder, arguments);
};
builder._styles = _styles;
const self = this;
Object.defineProperty(builder, 'level', {
enumerable: true,
get() {
return self.level;
},
set(level) {
self.level = level;
}
});
Object.defineProperty(builder, 'enabled', {
enumerable: true,
get() {
return self.enabled;
},
set(enabled) {
self.enabled = enabled;
}
});
// See below for fix regarding invisible grey/dim combination on Windows
builder.hasGrey = this.hasGrey || key === 'gray' || key === 'grey';
// `__proto__` is used because we must return a function, but there is
// no way to create a function with a different prototype
builder.__proto__ = proto; // eslint-disable-line no-proto
return builder;
}
function applyStyle() {
// Support varags, but simply cast to string in case there's only one arg
const args = arguments;
const argsLen = args.length;
let str = String(arguments[0]);
if (argsLen === 0) {
return '';
}
if (argsLen > 1) {
// Don't slice `arguments`, it prevents V8 optimizations
for (let a = 1; a < argsLen; a++) {
str += ' ' + args[a];
}
}
if (!this.enabled || this.level <= 0 || !str) {
return str;
}
// Turns out that on Windows dimmed gray text becomes invisible in cmd.exe,
// see https://github.com/chalk/chalk/issues/58
// If we're on Windows and we're dealing with a gray color, temporarily make 'dim' a noop.
const originalDim = ansiStyles.dim.open;
if (isSimpleWindowsTerm && this.hasGrey) {
ansiStyles.dim.open = '';
}
for (const code of this._styles.slice().reverse()) {
// Replace any instances already present with a re-opening code
// otherwise only the part of the string until said closing code
// will be colored, and the rest will simply be 'plain'.
str = code.open + str.replace(code.closeRe, code.open) + code.close;
// Close the styling before a linebreak and reopen
// after next line to fix a bleed issue on macOS
// https://github.com/chalk/chalk/pull/92
str = str.replace(/\r?\n/g, `${code.close}$&${code.open}`);
}
// Reset the original `dim` if we changed it to work around the Windows dimmed gray issue
ansiStyles.dim.open = originalDim;
return str;
}
function chalkTag(chalk, strings) {
if (!Array.isArray(strings)) {
// If chalk() was called by itself or with a string,
// return the string itself as a string.
return [].slice.call(arguments, 1).join(' ');
}
const args = [].slice.call(arguments, 2);
const parts = [strings.raw[0]];
for (let i = 1; i < strings.length; i++) {
parts.push(String(args[i - 1]).replace(/[{}\\]/g, '\\$&'));
parts.push(String(strings.raw[i]));
}
return template(chalk, parts.join(''));
}
Object.defineProperties(Chalk.prototype, styles);
module.exports = Chalk(); // eslint-disable-line new-cap
module.exports.supportsColor = supportsColor;

View File

@@ -0,0 +1,9 @@
MIT License
Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.com)
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@@ -0,0 +1,95 @@
{
"_from": "chalk@^2.0.0",
"_id": "chalk@2.1.0",
"_inBundle": false,
"_integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==",
"_location": "/react-dev-utils/inquirer/chalk",
"_phantomChildren": {},
"_requested": {
"type": "range",
"registry": true,
"raw": "chalk@^2.0.0",
"name": "chalk",
"escapedName": "chalk",
"rawSpec": "^2.0.0",
"saveSpec": null,
"fetchSpec": "^2.0.0"
},
"_requiredBy": [
"/react-dev-utils/inquirer"
],
"_resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz",
"_shasum": "ac5becf14fa21b99c6c92ca7a7d7cfd5b17e743e",
"_spec": "chalk@^2.0.0",
"_where": "/home/bilal/Saburly/slucajna-televizija/node_modules/react-dev-utils/node_modules/inquirer",
"bugs": {
"url": "https://github.com/chalk/chalk/issues"
},
"bundleDependencies": false,
"dependencies": {
"ansi-styles": "^3.1.0",
"escape-string-regexp": "^1.0.5",
"supports-color": "^4.0.0"
},
"deprecated": false,
"description": "Terminal string styling done right",
"devDependencies": {
"ava": "*",
"coveralls": "^2.11.2",
"execa": "^0.7.0",
"import-fresh": "^2.0.0",
"matcha": "^0.7.0",
"nyc": "^11.0.2",
"resolve-from": "^3.0.0",
"xo": "*"
},
"engines": {
"node": ">=4"
},
"files": [
"index.js",
"templates.js"
],
"homepage": "https://github.com/chalk/chalk#readme",
"keywords": [
"color",
"colour",
"colors",
"terminal",
"console",
"cli",
"string",
"str",
"ansi",
"style",
"styles",
"tty",
"formatting",
"rgb",
"256",
"shell",
"xterm",
"log",
"logging",
"command-line",
"text"
],
"license": "MIT",
"name": "chalk",
"repository": {
"type": "git",
"url": "git+https://github.com/chalk/chalk.git"
},
"scripts": {
"bench": "matcha benchmark.js",
"coveralls": "nyc report --reporter=text-lcov | coveralls",
"test": "xo && nyc ava"
},
"version": "2.1.0",
"xo": {
"envs": [
"node",
"mocha"
]
}
}

View File

@@ -0,0 +1,306 @@
<h1 align="center">
<br>
<br>
<img width="320" src="https://cdn.rawgit.com/chalk/chalk/19935d6484811c5e468817f846b7b3d417d7bf4a/logo.svg" alt="chalk">
<br>
<br>
<br>
</h1>
> Terminal string styling done right
[![Build Status](https://travis-ci.org/chalk/chalk.svg?branch=master)](https://travis-ci.org/chalk/chalk) [![Coverage Status](https://coveralls.io/repos/github/chalk/chalk/badge.svg?branch=master)](https://coveralls.io/github/chalk/chalk?branch=master) [![](https://img.shields.io/badge/unicorn-approved-ff69b4.svg)](https://www.youtube.com/watch?v=9auOCbH5Ns4) [![XO code style](https://img.shields.io/badge/code_style-XO-5ed9c7.svg)](https://github.com/sindresorhus/xo)
### [See what's new in Chalk 2](https://github.com/chalk/chalk/releases/tag/v2.0.0)
![](https://github.com/chalk/ansi-styles/raw/master/screenshot.png)
## Highlights
- Expressive API
- Highly performant
- Ability to nest styles
- [256/Truecolor color support](#256-and-truecolor-color-support)
- Auto-detects color support
- Doesn't extend `String.prototype`
- Clean and focused
- Actively maintained
- [Used by ~17,000 packages](https://www.npmjs.com/browse/depended/chalk) as of June 20th, 2017
## Install
```console
$ npm install chalk
```
## Usage
```js
const chalk = require('chalk');
console.log(chalk.blue('Hello world!'));
```
Chalk comes with an easy to use composable API where you just chain and nest the styles you want.
```js
const chalk = require('chalk');
const log = console.log;
// Combine styled and normal strings
log(chalk.blue('Hello') + 'World' + chalk.red('!'));
// Compose multiple styles using the chainable API
log(chalk.blue.bgRed.bold('Hello world!'));
// Pass in multiple arguments
log(chalk.blue('Hello', 'World!', 'Foo', 'bar', 'biz', 'baz'));
// Nest styles
log(chalk.red('Hello', chalk.underline.bgBlue('world') + '!'));
// Nest styles of the same type even (color, underline, background)
log(chalk.green(
'I am a green line ' +
chalk.blue.underline.bold('with a blue substring') +
' that becomes green again!'
));
// ES2015 template literal
log(`
CPU: ${chalk.red('90%')}
RAM: ${chalk.green('40%')}
DISK: ${chalk.yellow('70%')}
`);
// ES2015 tagged template literal
log(chalk`
CPU: {red ${cpu.totalPercent}%}
RAM: {green ${ram.used / ram.total * 100}%}
DISK: {rgb(255,131,0) ${disk.used / disk.total * 100}%}
`);
// Use RGB colors in terminal emulators that support it.
log(chalk.keyword('orange')('Yay for orange colored text!'));
log(chalk.rgb(123, 45, 67).underline('Underlined reddish color'));
log(chalk.hex('#DEADED').bold('Bold gray!'));
```
Easily define your own themes:
```js
const chalk = require('chalk');
const error = chalk.bold.red;
const warning = chalk.keyword('orange');
console.log(error('Error!'));
console.log(warning('Warning!'));
```
Take advantage of console.log [string substitution](https://nodejs.org/docs/latest/api/console.html#console_console_log_data_args):
```js
const name = 'Sindre';
console.log(chalk.green('Hello %s'), name);
//=> 'Hello Sindre'
```
## API
### chalk.`<style>[.<style>...](string, [string...])`
Example: `chalk.red.bold.underline('Hello', 'world');`
Chain [styles](#styles) and call the last one as a method with a string argument. Order doesn't matter, and later styles take precedent in case of a conflict. This simply means that `chalk.red.yellow.green` is equivalent to `chalk.green`.
Multiple arguments will be separated by space.
### chalk.enabled
Color support is automatically detected, as is the level (see `chalk.level`). However, if you'd like to simply enable/disable Chalk, you can do so via the `.enabled` property.
Chalk is enabled by default unless expicitly disabled via the constructor or `chalk.level` is `0`.
If you need to change this in a reusable module, create a new instance:
```js
const ctx = new chalk.constructor({enabled: false});
```
### chalk.level
Color support is automatically detected, but you can override it by setting the `level` property. You should however only do this in your own code as it applies globally to all Chalk consumers.
If you need to change this in a reusable module, create a new instance:
```js
const ctx = new chalk.constructor({level: 0});
```
Levels are as follows:
0. All colors disabled
1. Basic color support (16 colors)
2. 256 color support
3. Truecolor support (16 million colors)
### chalk.supportsColor
Detect whether the terminal [supports color](https://github.com/chalk/supports-color). Used internally and handled for you, but exposed for convenience.
Can be overridden by the user with the flags `--color` and `--no-color`. For situations where using `--color` is not possible, add the environment variable `FORCE_COLOR=1` to forcefully enable color or `FORCE_COLOR=0` to forcefully disable. The use of `FORCE_COLOR` overrides all other color support checks.
Explicit 256/Truecolor mode can be enabled using the `--color=256` and `--color=16m` flags, respectively.
## Styles
### Modifiers
- `reset`
- `bold`
- `dim`
- `italic` *(Not widely supported)*
- `underline`
- `inverse`
- `hidden`
- `strikethrough` *(Not widely supported)*
### Colors
- `black`
- `red`
- `green`
- `yellow`
- `blue` *(On Windows the bright version is used since normal blue is illegible)*
- `magenta`
- `cyan`
- `white`
- `gray` ("bright black")
- `redBright`
- `greenBright`
- `yellowBright`
- `blueBright`
- `magentaBright`
- `cyanBright`
- `whiteBright`
### Background colors
- `bgBlack`
- `bgRed`
- `bgGreen`
- `bgYellow`
- `bgBlue`
- `bgMagenta`
- `bgCyan`
- `bgWhite`
- `bgBlackBright`
- `bgRedBright`
- `bgGreenBright`
- `bgYellowBright`
- `bgBlueBright`
- `bgMagentaBright`
- `bgCyanBright`
- `bgWhiteBright`
## Tagged template literal
Chalk can be used as a [tagged template literal](http://exploringjs.com/es6/ch_template-literals.html#_tagged-template-literals).
```js
const chalk = require('chalk');
const miles = 18;
const calculateFeet = miles => miles * 5280;
console.log(chalk`
There are {bold 5280 feet} in a mile.
In {bold ${miles} miles}, there are {green.bold ${calculateFeet(miles)} feet}.
`);
```
Blocks are delimited by an opening curly brace (`{`), a style, some content, and a closing curly brace (`}`).
Template styles are chained exactly like normal Chalk styles. The following two statements are equivalent:
```js
console.log(chalk.bold.rgb(10, 100, 200)('Hello!'));
console.log(chalk`{bold.rgb(10,100,200) Hello!}`);
```
Note that function styles (`rgb()`, `hsl()`, `keyword()`, etc.) may not contain spaces between parameters.
All interpolated values (`` chalk`${foo}` ``) are converted to strings via the `.toString()` method. All curly braces (`{` and `}`) in interpolated value strings are escaped.
## 256 and Truecolor color support
Chalk supports 256 colors and [Truecolor](https://gist.github.com/XVilka/8346728) (16 million colors) on supported terminal apps.
Colors are downsampled from 16 million RGB values to an ANSI color format that is supported by the terminal emulator (or by specifying `{level: n}` as a Chalk option). For example, Chalk configured to run at level 1 (basic color support) will downsample an RGB value of #FF0000 (red) to 31 (ANSI escape for red).
Examples:
- `chalk.hex('#DEADED').underline('Hello, world!')`
- `chalk.keyword('orange')('Some orange text')`
- `chalk.rgb(15, 100, 204).inverse('Hello!')`
Background versions of these models are prefixed with `bg` and the first level of the module capitalized (e.g. `keyword` for foreground colors and `bgKeyword` for background colors).
- `chalk.bgHex('#DEADED').underline('Hello, world!')`
- `chalk.bgKeyword('orange')('Some orange text')`
- `chalk.bgRgb(15, 100, 204).inverse('Hello!')`
The following color models can be used:
- [`rgb`](https://en.wikipedia.org/wiki/RGB_color_model) - Example: `chalk.rgb(255, 136, 0).bold('Orange!')`
- [`hex`](https://en.wikipedia.org/wiki/Web_colors#Hex_triplet) - Example: `chalk.hex('#FF8800').bold('Orange!')`
- [`keyword`](https://www.w3.org/wiki/CSS/Properties/color/keywords) (CSS keywords) - Example: `chalk.keyword('orange').bold('Orange!')`
- [`hsl`](https://en.wikipedia.org/wiki/HSL_and_HSV) - Example: `chalk.hsl(32, 100, 50).bold('Orange!')`
- [`hsv`](https://en.wikipedia.org/wiki/HSL_and_HSV) - Example: `chalk.hsl(32, 1, 1).bold('Orange!')`
- [`hwb`](https://en.wikipedia.org/wiki/HWB_color_model) - Example: `chalk.hsl(32, 0, 50).bold('Orange!')`
- `ansi16`
- `ansi256`
## Windows
If you're on Windows, do yourself a favor and use [`cmder`](http://cmder.net/) instead of `cmd.exe`.
## Origin story
[colors.js](https://github.com/Marak/colors.js) used to be the most popular string styling module, but it has serious deficiencies like extending `String.prototype` which causes all kinds of [problems](https://github.com/yeoman/yo/issues/68) and the package is unmaintained. Although there are other packages, they either do too much or not enough. Chalk is a clean and focused alternative.
## Related
- [chalk-cli](https://github.com/chalk/chalk-cli) - CLI for this module
- [ansi-styles](https://github.com/chalk/ansi-styles) - ANSI escape codes for styling strings in the terminal
- [supports-color](https://github.com/chalk/supports-color) - Detect whether a terminal supports color
- [strip-ansi](https://github.com/chalk/strip-ansi) - Strip ANSI escape codes
- [has-ansi](https://github.com/chalk/has-ansi) - Check if a string has ANSI escape codes
- [ansi-regex](https://github.com/chalk/ansi-regex) - Regular expression for matching ANSI escape codes
- [wrap-ansi](https://github.com/chalk/wrap-ansi) - Wordwrap a string with ANSI escape codes
- [slice-ansi](https://github.com/chalk/slice-ansi) - Slice a string with ANSI escape codes
- [color-convert](https://github.com/qix-/color-convert) - Converts colors between different models
- [chalk-animation](https://github.com/bokub/chalk-animation) - Animate strings in the terminal
- [gradient-string](https://github.com/bokub/gradient-string) - Apply color gradients to strings
## Maintainers
- [Sindre Sorhus](https://github.com/sindresorhus)
- [Josh Junon](https://github.com/qix-)
## License
MIT

View File

@@ -0,0 +1,128 @@
'use strict';
const TEMPLATE_REGEX = /(?:\\(u[a-f0-9]{4}|x[a-f0-9]{2}|.))|(?:\{(~)?(\w+(?:\([^)]*\))?(?:\.\w+(?:\([^)]*\))?)*)(?:[ \t]|(?=\r?\n)))|(\})|((?:.|[\r\n\f])+?)/gi;
const STYLE_REGEX = /(?:^|\.)(\w+)(?:\(([^)]*)\))?/g;
const STRING_REGEX = /^(['"])((?:\\.|(?!\1)[^\\])*)\1$/;
const ESCAPE_REGEX = /\\(u[0-9a-f]{4}|x[0-9a-f]{2}|.)|([^\\])/gi;
const ESCAPES = {
n: '\n',
r: '\r',
t: '\t',
b: '\b',
f: '\f',
v: '\v',
0: '\0',
'\\': '\\',
e: '\u001b',
a: '\u0007'
};
function unescape(c) {
if ((c[0] === 'u' && c.length === 5) || (c[0] === 'x' && c.length === 3)) {
return String.fromCharCode(parseInt(c.slice(1), 16));
}
return ESCAPES[c] || c;
}
function parseArguments(name, args) {
const results = [];
const chunks = args.trim().split(/\s*,\s*/g);
let matches;
for (const chunk of chunks) {
if (!isNaN(chunk)) {
results.push(Number(chunk));
} else if ((matches = chunk.match(STRING_REGEX))) {
results.push(matches[2].replace(ESCAPE_REGEX, (m, escape, chr) => escape ? unescape(escape) : chr));
} else {
throw new Error(`Invalid Chalk template style argument: ${chunk} (in style '${name}')`);
}
}
return results;
}
function parseStyle(style) {
STYLE_REGEX.lastIndex = 0;
const results = [];
let matches;
while ((matches = STYLE_REGEX.exec(style)) !== null) {
const name = matches[1];
if (matches[2]) {
const args = parseArguments(name, matches[2]);
results.push([name].concat(args));
} else {
results.push([name]);
}
}
return results;
}
function buildStyle(chalk, styles) {
const enabled = {};
for (const layer of styles) {
for (const style of layer.styles) {
enabled[style[0]] = layer.inverse ? null : style.slice(1);
}
}
let current = chalk;
for (const styleName of Object.keys(enabled)) {
if (Array.isArray(enabled[styleName])) {
if (!(styleName in current)) {
throw new Error(`Unknown Chalk style: ${styleName}`);
}
if (enabled[styleName].length > 0) {
current = current[styleName].apply(current, enabled[styleName]);
} else {
current = current[styleName];
}
}
}
return current;
}
module.exports = (chalk, tmp) => {
const styles = [];
const chunks = [];
let chunk = [];
// eslint-disable-next-line max-params
tmp.replace(TEMPLATE_REGEX, (m, escapeChar, inverse, style, close, chr) => {
if (escapeChar) {
chunk.push(unescape(escapeChar));
} else if (style) {
const str = chunk.join('');
chunk = [];
chunks.push(styles.length === 0 ? str : buildStyle(chalk, styles)(str));
styles.push({inverse, styles: parseStyle(style)});
} else if (close) {
if (styles.length === 0) {
throw new Error('Found extraneous } in Chalk template literal');
}
chunks.push(buildStyle(chalk, styles)(chunk.join('')));
chunk = [];
styles.pop();
} else {
chunk.push(chr);
}
});
chunks.push(chunk.join(''));
if (styles.length > 0) {
const errMsg = `Chalk template literal is missing ${styles.length} closing bracket${styles.length === 1 ? '' : 's'} (\`}\`)`;
throw new Error(errMsg);
}
return chunks.join('');
};

View File

@@ -0,0 +1,4 @@
'use strict';
const ansiRegex = require('ansi-regex');
module.exports = input => typeof input === 'string' ? input.replace(ansiRegex(), '') : input;

View File

@@ -0,0 +1,9 @@
MIT License
Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.com)
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@@ -0,0 +1,84 @@
{
"_from": "strip-ansi@^4.0.0",
"_id": "strip-ansi@4.0.0",
"_inBundle": false,
"_integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
"_location": "/react-dev-utils/inquirer/strip-ansi",
"_phantomChildren": {},
"_requested": {
"type": "range",
"registry": true,
"raw": "strip-ansi@^4.0.0",
"name": "strip-ansi",
"escapedName": "strip-ansi",
"rawSpec": "^4.0.0",
"saveSpec": null,
"fetchSpec": "^4.0.0"
},
"_requiredBy": [
"/react-dev-utils/inquirer"
],
"_resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
"_shasum": "a8479022eb1ac368a871389b635262c505ee368f",
"_spec": "strip-ansi@^4.0.0",
"_where": "/home/bilal/Saburly/slucajna-televizija/node_modules/react-dev-utils/node_modules/inquirer",
"author": {
"name": "Sindre Sorhus",
"email": "sindresorhus@gmail.com",
"url": "sindresorhus.com"
},
"bugs": {
"url": "https://github.com/chalk/strip-ansi/issues"
},
"bundleDependencies": false,
"dependencies": {
"ansi-regex": "^3.0.0"
},
"deprecated": false,
"description": "Strip ANSI escape codes",
"devDependencies": {
"ava": "*",
"xo": "*"
},
"engines": {
"node": ">=4"
},
"files": [
"index.js"
],
"homepage": "https://github.com/chalk/strip-ansi#readme",
"keywords": [
"strip",
"trim",
"remove",
"ansi",
"styles",
"color",
"colour",
"colors",
"terminal",
"console",
"string",
"tty",
"escape",
"formatting",
"rgb",
"256",
"shell",
"xterm",
"log",
"logging",
"command-line",
"text"
],
"license": "MIT",
"name": "strip-ansi",
"repository": {
"type": "git",
"url": "git+https://github.com/chalk/strip-ansi.git"
},
"scripts": {
"test": "xo && ava"
},
"version": "4.0.0"
}

View File

@@ -0,0 +1,39 @@
# strip-ansi [![Build Status](https://travis-ci.org/chalk/strip-ansi.svg?branch=master)](https://travis-ci.org/chalk/strip-ansi)
> Strip [ANSI escape codes](https://en.wikipedia.org/wiki/ANSI_escape_code)
## Install
```
$ npm install strip-ansi
```
## Usage
```js
const stripAnsi = require('strip-ansi');
stripAnsi('\u001B[4mUnicorn\u001B[0m');
//=> 'Unicorn'
```
## Related
- [strip-ansi-cli](https://github.com/chalk/strip-ansi-cli) - CLI for this module
- [has-ansi](https://github.com/chalk/has-ansi) - Check if a string has ANSI escape codes
- [ansi-regex](https://github.com/chalk/ansi-regex) - Regular expression for matching ANSI escape codes
- [chalk](https://github.com/chalk/chalk) - Terminal string styling done right
## Maintainers
- [Sindre Sorhus](https://github.com/sindresorhus)
- [Josh Junon](https://github.com/qix-)
## License
MIT

View File

@@ -0,0 +1,99 @@
{
"_from": "inquirer@3.2.1",
"_id": "inquirer@3.2.1",
"_inBundle": false,
"_integrity": "sha512-QgW3eiPN8gpj/K5vVpHADJJgrrF0ho/dZGylikGX7iqAdRgC9FVKYKWFLx6hZDBFcOLEoSqINYrVPeFAeG/PdA==",
"_location": "/react-dev-utils/inquirer",
"_phantomChildren": {
"ansi-regex": "3.0.0",
"ansi-styles": "3.2.0",
"escape-string-regexp": "1.0.5",
"supports-color": "4.4.0"
},
"_requested": {
"type": "version",
"registry": true,
"raw": "inquirer@3.2.1",
"name": "inquirer",
"escapedName": "inquirer",
"rawSpec": "3.2.1",
"saveSpec": null,
"fetchSpec": "3.2.1"
},
"_requiredBy": [
"/react-dev-utils"
],
"_resolved": "https://registry.npmjs.org/inquirer/-/inquirer-3.2.1.tgz",
"_shasum": "06ceb0f540f45ca548c17d6840959878265fa175",
"_spec": "inquirer@3.2.1",
"_where": "/home/bilal/Saburly/slucajna-televizija/node_modules/react-dev-utils",
"author": {
"name": "Simon Boudrias",
"email": "admin@simonboudrias.com"
},
"bugs": {
"url": "https://github.com/SBoudrias/Inquirer.js/issues"
},
"bundleDependencies": false,
"dependencies": {
"ansi-escapes": "^2.0.0",
"chalk": "^2.0.0",
"cli-cursor": "^2.1.0",
"cli-width": "^2.0.0",
"external-editor": "^2.0.4",
"figures": "^2.0.0",
"lodash": "^4.3.0",
"mute-stream": "0.0.7",
"run-async": "^2.2.0",
"rx-lite": "^4.0.8",
"rx-lite-aggregates": "^4.0.8",
"string-width": "^2.1.0",
"strip-ansi": "^4.0.0",
"through": "^2.3.6"
},
"deprecated": false,
"description": "A collection of common interactive command line user interfaces.",
"devDependencies": {
"chai": "^4.0.1",
"cmdify": "^0.0.4",
"eslint": "^4.2.0",
"eslint-config-xo-space": "^0.16.0",
"gulp": "^3.9.0",
"gulp-codacy": "^1.0.0",
"gulp-coveralls": "^0.1.0",
"gulp-eslint": "^4.0.0",
"gulp-exclude-gitignore": "^1.0.0",
"gulp-istanbul": "^1.1.2",
"gulp-line-ending-corrector": "^1.0.1",
"gulp-mocha": "^3.0.0",
"gulp-nsp": "^2.1.0",
"gulp-plumber": "^1.0.0",
"mocha": "^3.4.2",
"mockery": "^2.1.0",
"sinon": "^2.3.6"
},
"files": [
"lib"
],
"homepage": "https://github.com/SBoudrias/Inquirer.js#readme",
"keywords": [
"command",
"prompt",
"stdin",
"cli",
"tty",
"menu"
],
"license": "MIT",
"main": "lib/inquirer.js",
"name": "inquirer",
"repository": {
"type": "git",
"url": "git+https://github.com/SBoudrias/Inquirer.js.git"
},
"scripts": {
"prepublish": "gulp prepublish",
"test": "gulp"
},
"version": "3.2.1"
}

View File

@@ -0,0 +1,46 @@
'use strict';
/* eslint-disable yoda */
module.exports = x => {
if (Number.isNaN(x)) {
return false;
}
// code points are derived from:
// http://www.unix.org/Public/UNIDATA/EastAsianWidth.txt
if (
x >= 0x1100 && (
x <= 0x115f || // Hangul Jamo
x === 0x2329 || // LEFT-POINTING ANGLE BRACKET
x === 0x232a || // RIGHT-POINTING ANGLE BRACKET
// CJK Radicals Supplement .. Enclosed CJK Letters and Months
(0x2e80 <= x && x <= 0x3247 && x !== 0x303f) ||
// Enclosed CJK Letters and Months .. CJK Unified Ideographs Extension A
(0x3250 <= x && x <= 0x4dbf) ||
// CJK Unified Ideographs .. Yi Radicals
(0x4e00 <= x && x <= 0xa4c6) ||
// Hangul Jamo Extended-A
(0xa960 <= x && x <= 0xa97c) ||
// Hangul Syllables
(0xac00 <= x && x <= 0xd7a3) ||
// CJK Compatibility Ideographs
(0xf900 <= x && x <= 0xfaff) ||
// Vertical Forms
(0xfe10 <= x && x <= 0xfe19) ||
// CJK Compatibility Forms .. Small Form Variants
(0xfe30 <= x && x <= 0xfe6b) ||
// Halfwidth and Fullwidth Forms
(0xff01 <= x && x <= 0xff60) ||
(0xffe0 <= x && x <= 0xffe6) ||
// Kana Supplement
(0x1b000 <= x && x <= 0x1b001) ||
// Enclosed Ideographic Supplement
(0x1f200 <= x && x <= 0x1f251) ||
// CJK Unified Ideographs Extension B .. Tertiary Ideographic Plane
(0x20000 <= x && x <= 0x3fffd)
)
) {
return true;
}
return false;
};

View File

@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.com)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

View File

@@ -0,0 +1,77 @@
{
"_from": "is-fullwidth-code-point@^2.0.0",
"_id": "is-fullwidth-code-point@2.0.0",
"_inBundle": false,
"_integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
"_location": "/react-dev-utils/is-fullwidth-code-point",
"_phantomChildren": {},
"_requested": {
"type": "range",
"registry": true,
"raw": "is-fullwidth-code-point@^2.0.0",
"name": "is-fullwidth-code-point",
"escapedName": "is-fullwidth-code-point",
"rawSpec": "^2.0.0",
"saveSpec": null,
"fetchSpec": "^2.0.0"
},
"_requiredBy": [
"/react-dev-utils/string-width"
],
"_resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
"_shasum": "a3b30a5c4f199183167aaab93beefae3ddfb654f",
"_spec": "is-fullwidth-code-point@^2.0.0",
"_where": "/home/bilal/Saburly/slucajna-televizija/node_modules/react-dev-utils/node_modules/string-width",
"author": {
"name": "Sindre Sorhus",
"email": "sindresorhus@gmail.com",
"url": "sindresorhus.com"
},
"bugs": {
"url": "https://github.com/sindresorhus/is-fullwidth-code-point/issues"
},
"bundleDependencies": false,
"deprecated": false,
"description": "Check if the character represented by a given Unicode code point is fullwidth",
"devDependencies": {
"ava": "*",
"xo": "*"
},
"engines": {
"node": ">=4"
},
"files": [
"index.js"
],
"homepage": "https://github.com/sindresorhus/is-fullwidth-code-point#readme",
"keywords": [
"fullwidth",
"full-width",
"full",
"width",
"unicode",
"character",
"char",
"string",
"str",
"codepoint",
"code",
"point",
"is",
"detect",
"check"
],
"license": "MIT",
"name": "is-fullwidth-code-point",
"repository": {
"type": "git",
"url": "git+https://github.com/sindresorhus/is-fullwidth-code-point.git"
},
"scripts": {
"test": "xo && ava"
},
"version": "2.0.0",
"xo": {
"esnext": true
}
}

View File

@@ -0,0 +1,39 @@
# is-fullwidth-code-point [![Build Status](https://travis-ci.org/sindresorhus/is-fullwidth-code-point.svg?branch=master)](https://travis-ci.org/sindresorhus/is-fullwidth-code-point)
> Check if the character represented by a given [Unicode code point](https://en.wikipedia.org/wiki/Code_point) is [fullwidth](https://en.wikipedia.org/wiki/Halfwidth_and_fullwidth_forms)
## Install
```
$ npm install --save is-fullwidth-code-point
```
## Usage
```js
const isFullwidthCodePoint = require('is-fullwidth-code-point');
isFullwidthCodePoint('谢'.codePointAt());
//=> true
isFullwidthCodePoint('a'.codePointAt());
//=> false
```
## API
### isFullwidthCodePoint(input)
#### input
Type: `number`
[Code point](https://en.wikipedia.org/wiki/Code_point) of a character.
## License
MIT © [Sindre Sorhus](https://sindresorhus.com)

View File

@@ -0,0 +1 @@
{}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,9 @@
language: node_js
language: node_js
node_js:
- '0.8'
- '0.10'
- '0.12'
- 'iojs'
before_install:
- npm install -g npm@latest

View File

@@ -0,0 +1,15 @@
The ISC License
Copyright (c) Isaac Z. Schlueter and Contributors
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

View File

@@ -0,0 +1,68 @@
# mute-stream
Bytes go in, but they don't come out (when muted).
This is a basic pass-through stream, but when muted, the bytes are
silently dropped, rather than being passed through.
## Usage
```javascript
var MuteStream = require('mute-stream')
var ms = new MuteStream(options)
ms.pipe(process.stdout)
ms.write('foo') // writes 'foo' to stdout
ms.mute()
ms.write('bar') // does not write 'bar'
ms.unmute()
ms.write('baz') // writes 'baz' to stdout
// can also be used to mute incoming data
var ms = new MuteStream
input.pipe(ms)
ms.on('data', function (c) {
console.log('data: ' + c)
})
input.emit('data', 'foo') // logs 'foo'
ms.mute()
input.emit('data', 'bar') // does not log 'bar'
ms.unmute()
input.emit('data', 'baz') // logs 'baz'
```
## Options
All options are optional.
* `replace` Set to a string to replace each character with the
specified string when muted. (So you can show `****` instead of the
password, for example.)
* `prompt` If you are using a replacement char, and also using a
prompt with a readline stream (as for a `Password: *****` input),
then specify what the prompt is so that backspace will work
properly. Otherwise, pressing backspace will overwrite the prompt
with the replacement character, which is weird.
## ms.mute()
Set `muted` to `true`. Turns `.write()` into a no-op.
## ms.unmute()
Set `muted` to `false`
## ms.isTTY
True if the pipe destination is a TTY, or if the incoming pipe source is
a TTY.
## Other stream methods...
The other standard readable and writable stream methods are all
available. The MuteStream object acts as a facade to its pipe source
and destination.

View File

@@ -0,0 +1,93 @@
<!doctype html>
<html lang="en">
<head>
<title>Code coverage report for __root__/</title>
<meta charset="utf-8" />
<link rel="stylesheet" href="../prettify.css" />
<link rel="stylesheet" href="../base.css" />
<meta name="viewport" content="width=device-width, initial-scale=1">
<style type='text/css'>
.coverage-summary .sorter {
background-image: url(../sort-arrow-sprite.png);
}
</style>
</head>
<body>
<div class='wrapper'>
<div class='pad1'>
<h1>
<a href="../index.html">all files</a> __root__/
</h1>
<div class='clearfix'>
<div class='fl pad1y space-right2'>
<span class="strong">77.03% </span>
<span class="quiet">Statements</span>
<span class='fraction'>57/74</span>
</div>
<div class='fl pad1y space-right2'>
<span class="strong">57.14% </span>
<span class="quiet">Branches</span>
<span class='fraction'>28/49</span>
</div>
<div class='fl pad1y space-right2'>
<span class="strong">93.33% </span>
<span class="quiet">Functions</span>
<span class='fraction'>14/15</span>
</div>
<div class='fl pad1y space-right2'>
<span class="strong">79.1% </span>
<span class="quiet">Lines</span>
<span class='fraction'>53/67</span>
</div>
</div>
</div>
<div class='status-line medium'></div>
<div class="pad1">
<table class="coverage-summary">
<thead>
<tr>
<th data-col="file" data-fmt="html" data-html="true" class="file">File</th>
<th data-col="pic" data-type="number" data-fmt="html" data-html="true" class="pic"></th>
<th data-col="statements" data-type="number" data-fmt="pct" class="pct">Statements</th>
<th data-col="statements_raw" data-type="number" data-fmt="html" class="abs"></th>
<th data-col="branches" data-type="number" data-fmt="pct" class="pct">Branches</th>
<th data-col="branches_raw" data-type="number" data-fmt="html" class="abs"></th>
<th data-col="functions" data-type="number" data-fmt="pct" class="pct">Functions</th>
<th data-col="functions_raw" data-type="number" data-fmt="html" class="abs"></th>
<th data-col="lines" data-type="number" data-fmt="pct" class="pct">Lines</th>
<th data-col="lines_raw" data-type="number" data-fmt="html" class="abs"></th>
</tr>
</thead>
<tbody><tr>
<td class="file medium" data-value="mute.js"><a href="mute.js.html">mute.js</a></td>
<td data-value="77.03" class="pic medium"><div class="chart"><div class="cover-fill" style="width: 77%;"></div><div class="cover-empty" style="width:23%;"></div></div></td>
<td data-value="77.03" class="pct medium">77.03%</td>
<td data-value="74" class="abs medium">57/74</td>
<td data-value="57.14" class="pct medium">57.14%</td>
<td data-value="49" class="abs medium">28/49</td>
<td data-value="93.33" class="pct high">93.33%</td>
<td data-value="15" class="abs high">14/15</td>
<td data-value="79.1" class="pct medium">79.1%</td>
<td data-value="67" class="abs medium">53/67</td>
</tr>
</tbody>
</table>
</div><div class='push'></div><!-- for sticky footer -->
</div><!-- /wrapper -->
<div class='footer quiet pad2 space-top1 center small'>
Code coverage
generated by <a href="http://istanbul-js.org/" target="_blank">istanbul</a> at Fri Feb 12 2016 22:19:00 GMT-0800 (PST)
</div>
</div>
<script src="../prettify.js"></script>
<script>
window.onload = function () {
if (typeof prettyPrint === 'function') {
prettyPrint();
}
};
</script>
<script src="../sorter.js"></script>
</body>
</html>

View File

@@ -0,0 +1,500 @@
<!doctype html>
<html lang="en">
<head>
<title>Code coverage report for mute.js</title>
<meta charset="utf-8" />
<link rel="stylesheet" href="../prettify.css" />
<link rel="stylesheet" href="../base.css" />
<meta name="viewport" content="width=device-width, initial-scale=1">
<style type='text/css'>
.coverage-summary .sorter {
background-image: url(../sort-arrow-sprite.png);
}
</style>
</head>
<body>
<div class='wrapper'>
<div class='pad1'>
<h1>
<a href="../index.html">all files</a> / <a href="index.html">__root__/</a> mute.js
</h1>
<div class='clearfix'>
<div class='fl pad1y space-right2'>
<span class="strong">77.03% </span>
<span class="quiet">Statements</span>
<span class='fraction'>57/74</span>
</div>
<div class='fl pad1y space-right2'>
<span class="strong">57.14% </span>
<span class="quiet">Branches</span>
<span class='fraction'>28/49</span>
</div>
<div class='fl pad1y space-right2'>
<span class="strong">93.33% </span>
<span class="quiet">Functions</span>
<span class='fraction'>14/15</span>
</div>
<div class='fl pad1y space-right2'>
<span class="strong">79.1% </span>
<span class="quiet">Lines</span>
<span class='fraction'>53/67</span>
</div>
</div>
</div>
<div class='status-line medium'></div>
<pre><table class="coverage">
<tr><td class="line-count quiet">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146</td><td class="line-coverage quiet"><span class="cline-any cline-yes">1×</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">1×</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">1×</span>
<span class="cline-any cline-yes">7×</span>
<span class="cline-any cline-yes">7×</span>
<span class="cline-any cline-yes">7×</span>
<span class="cline-any cline-yes">7×</span>
<span class="cline-any cline-yes">7×</span>
<span class="cline-any cline-yes">7×</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">7×</span>
<span class="cline-any cline-yes">7×</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">1×</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">1×</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">1×</span>
<span class="cline-any cline-yes">10×</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">1×</span>
<span class="cline-any cline-yes">6×</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">1×</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">1×</span>
<span class="cline-any cline-yes">5×</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">1×</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">1×</span>
<span class="cline-any cline-yes">8×</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">1×</span>
<span class="cline-any cline-yes">2×</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">1×</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">5×</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">1×</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">5×</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">1×</span>
<span class="cline-any cline-yes">2×</span>
<span class="cline-any cline-yes">2×</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">1×</span>
<span class="cline-any cline-yes">2×</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">1×</span>
<span class="cline-any cline-yes">2×</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">1×</span>
<span class="cline-any cline-yes">25×</span>
<span class="cline-any cline-yes">13×</span>
<span class="cline-any cline-yes">8×</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">8×</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">8×</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">20×</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">1×</span>
<span class="cline-any cline-yes">2×</span>
<span class="cline-any cline-yes">2×</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">2×</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">2×</span>
<span class="cline-any cline-yes">2×</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">3×</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">1×</span>
<span class="cline-any cline-yes">1×</span>
<span class="cline-any cline-yes">1×</span>
<span class="cline-any cline-neutral">&nbsp;</span></td><td class="text"><pre class="prettyprint lang-js">var Stream = require('stream')
&nbsp;
module.exports = MuteStream
&nbsp;
// var out = new MuteStream(process.stdout)
// argument auto-pipes
function MuteStream (opts) {
Stream.apply(this)
opts = opts || {}
this.writable = this.readable = true
this.muted = false
this.on('pipe', this._onpipe)
this.replace = opts.replace
&nbsp;
// For readline-type situations
// This much at the start of a line being redrawn after a ctrl char
// is seen (such as backspace) won't be redrawn as the replacement
this._prompt = opts.prompt || null
this._hadControl = false
}
&nbsp;
MuteStream.prototype = Object.create(Stream.prototype)
&nbsp;
Object.defineProperty(MuteStream.prototype, 'constructor', {
value: MuteStream,
enumerable: false
})
&nbsp;
MuteStream.prototype.mute = function () {
this.muted = true
}
&nbsp;
MuteStream.prototype.unmute = function () {
this.muted = false
}
&nbsp;
Object.defineProperty(MuteStream.prototype, '_onpipe', {
value: onPipe,
enumerable: false,
writable: true,
configurable: true
})
&nbsp;
function onPipe (src) {
this._src = src
}
&nbsp;
Object.defineProperty(MuteStream.prototype, 'isTTY', {
get: getIsTTY,
set: setIsTTY,
enumerable: true,
configurable: true
})
&nbsp;
function getIsTTY () {
return( (this._dest) ? this._dest.isTTY
: (this._src) ? this._src.isTTY
: false
)
}
&nbsp;
// basically just get replace the getter/setter with a regular value
function setIsTTY (isTTY) {
Object.defineProperty(this, 'isTTY', {
value: isTTY,
enumerable: true,
writable: true,
configurable: true
})
}
&nbsp;
Object.defineProperty(MuteStream.prototype, 'rows', {
get: function () {
return( this._dest ? this._dest.rows
: this._src ? <span class="branch-0 cbranch-no" title="branch not covered" >this._src.rows</span>
: undefined )
}, enumerable: true, configurable: true })
&nbsp;
Object.defineProperty(MuteStream.prototype, 'columns', {
get: function () {
return( this._dest ? this._dest.columns
: this._src ? <span class="branch-0 cbranch-no" title="branch not covered" >this._src.columns</span>
: undefined )
}, enumerable: true, configurable: true })
&nbsp;
&nbsp;
MuteStream.prototype.pipe = function (dest, options) {
this._dest = dest
return Stream.prototype.pipe.call(this, dest, options)
}
&nbsp;
MuteStream.prototype.pause = function () {
<span class="missing-if-branch" title="else path not taken" >E</span>if (this._src) return this._src.pause()
}
&nbsp;
MuteStream.prototype.resume = function () {
<span class="missing-if-branch" title="else path not taken" >E</span>if (this._src) return this._src.resume()
}
&nbsp;
MuteStream.prototype.write = function (c) {
if (this.muted) {
if (!this.replace) return true
<span class="missing-if-branch" title="if path not taken" >I</span>if (c.match(/^\u001b/)) {
<span class="cstat-no" title="statement not covered" > if(c.indexOf(this._prompt) === 0) {</span>
<span class="cstat-no" title="statement not covered" > c = c.substr(this._prompt.length);</span>
<span class="cstat-no" title="statement not covered" > c = c.replace(/./g, this.replace);</span>
<span class="cstat-no" title="statement not covered" > c = this._prompt + c;</span>
}
<span class="cstat-no" title="statement not covered" > this._hadControl = true</span>
<span class="cstat-no" title="statement not covered" > return this.emit('data', c)</span>
} else {
<span class="missing-if-branch" title="if path not taken" >I</span>if (this._prompt &amp;&amp; <span class="branch-1 cbranch-no" title="branch not covered" >this._hadControl </span>&amp;&amp;
<span class="branch-2 cbranch-no" title="branch not covered" > c.indexOf(this._prompt) === 0)</span> {
<span class="cstat-no" title="statement not covered" > this._hadControl = false</span>
<span class="cstat-no" title="statement not covered" > this.emit('data', this._prompt)</span>
<span class="cstat-no" title="statement not covered" > c = c.substr(this._prompt.length)</span>
}
c = c.toString().replace(/./g, this.replace)
}
}
this.emit('data', c)
}
&nbsp;
MuteStream.prototype.end = function (c) {
<span class="missing-if-branch" title="else path not taken" >E</span>if (this.muted) {
<span class="missing-if-branch" title="if path not taken" >I</span>if (c &amp;&amp; this.replace) {
<span class="cstat-no" title="statement not covered" > c = c.toString().replace(/./g, this.replace)</span>
} else {
c = null
}
}
<span class="missing-if-branch" title="if path not taken" >I</span>if (c) <span class="cstat-no" title="statement not covered" >this.emit('data', c)</span>
this.emit('end')
}
&nbsp;
function proxy (fn) { return <span class="fstat-no" title="function not covered" >function () {</span>
<span class="cstat-no" title="statement not covered" > var d = this._dest</span>
<span class="cstat-no" title="statement not covered" > var s = this._src</span>
<span class="cstat-no" title="statement not covered" > if (d &amp;&amp; d[fn]) <span class="cstat-no" title="statement not covered" >d[fn].apply(d, arguments)</span></span>
<span class="cstat-no" title="statement not covered" > if (s &amp;&amp; s[fn]) <span class="cstat-no" title="statement not covered" >s[fn].apply(s, arguments)</span></span>
}}
&nbsp;
MuteStream.prototype.destroy = proxy('destroy')
MuteStream.prototype.destroySoon = proxy('destroySoon')
MuteStream.prototype.close = proxy('close')
&nbsp;</pre></td></tr>
</table></pre>
<div class='push'></div><!-- for sticky footer -->
</div><!-- /wrapper -->
<div class='footer quiet pad2 space-top1 center small'>
Code coverage
generated by <a href="http://istanbul-js.org/" target="_blank">istanbul</a> at Fri Feb 12 2016 22:19:00 GMT-0800 (PST)
</div>
</div>
<script src="../prettify.js"></script>
<script>
window.onload = function () {
if (typeof prettyPrint === 'function') {
prettyPrint();
}
};
</script>
<script src="../sorter.js"></script>
</body>
</html>

View File

@@ -0,0 +1,212 @@
body, html {
margin:0; padding: 0;
height: 100%;
}
body {
font-family: Helvetica Neue, Helvetica, Arial;
font-size: 14px;
color:#333;
}
.small { font-size: 12px;; }
*, *:after, *:before {
-webkit-box-sizing:border-box;
-moz-box-sizing:border-box;
box-sizing:border-box;
}
h1 { font-size: 20px; margin: 0;}
h2 { font-size: 14px; }
pre {
font: 12px/1.4 Consolas, "Liberation Mono", Menlo, Courier, monospace;
margin: 0;
padding: 0;
-moz-tab-size: 2;
-o-tab-size: 2;
tab-size: 2;
}
a { color:#0074D9; text-decoration:none; }
a:hover { text-decoration:underline; }
.strong { font-weight: bold; }
.space-top1 { padding: 10px 0 0 0; }
.pad2y { padding: 20px 0; }
.pad1y { padding: 10px 0; }
.pad2x { padding: 0 20px; }
.pad2 { padding: 20px; }
.pad1 { padding: 10px; }
.space-left2 { padding-left:55px; }
.space-right2 { padding-right:20px; }
.center { text-align:center; }
.clearfix { display:block; }
.clearfix:after {
content:'';
display:block;
height:0;
clear:both;
visibility:hidden;
}
.fl { float: left; }
@media only screen and (max-width:640px) {
.col3 { width:100%; max-width:100%; }
.hide-mobile { display:none!important; }
}
.quiet {
color: #7f7f7f;
color: rgba(0,0,0,0.5);
}
.quiet a { opacity: 0.7; }
.fraction {
font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace;
font-size: 10px;
color: #555;
background: #E8E8E8;
padding: 4px 5px;
border-radius: 3px;
vertical-align: middle;
}
div.path a:link, div.path a:visited { color: #333; }
table.coverage {
border-collapse: collapse;
margin: 10px 0 0 0;
padding: 0;
}
table.coverage td {
margin: 0;
padding: 0;
vertical-align: top;
}
table.coverage td.line-count {
text-align: right;
padding: 0 5px 0 20px;
}
table.coverage td.line-coverage {
text-align: right;
padding-right: 10px;
min-width:20px;
}
table.coverage td span.cline-any {
display: inline-block;
padding: 0 5px;
width: 100%;
}
.missing-if-branch {
display: inline-block;
margin-right: 5px;
border-radius: 3px;
position: relative;
padding: 0 4px;
background: #333;
color: yellow;
}
.skip-if-branch {
display: none;
margin-right: 10px;
position: relative;
padding: 0 4px;
background: #ccc;
color: white;
}
.missing-if-branch .typ, .skip-if-branch .typ {
color: inherit !important;
}
.coverage-summary {
border-collapse: collapse;
width: 100%;
}
.coverage-summary tr { border-bottom: 1px solid #bbb; }
.keyline-all { border: 1px solid #ddd; }
.coverage-summary td, .coverage-summary th { padding: 10px; }
.coverage-summary tbody { border: 1px solid #bbb; }
.coverage-summary td { border-right: 1px solid #bbb; }
.coverage-summary td:last-child { border-right: none; }
.coverage-summary th {
text-align: left;
font-weight: normal;
white-space: nowrap;
}
.coverage-summary th.file { border-right: none !important; }
.coverage-summary th.pct { }
.coverage-summary th.pic,
.coverage-summary th.abs,
.coverage-summary td.pct,
.coverage-summary td.abs { text-align: right; }
.coverage-summary td.file { white-space: nowrap; }
.coverage-summary td.pic { min-width: 120px !important; }
.coverage-summary tfoot td { }
.coverage-summary .sorter {
height: 10px;
width: 7px;
display: inline-block;
margin-left: 0.5em;
background: url(sort-arrow-sprite.png) no-repeat scroll 0 0 transparent;
}
.coverage-summary .sorted .sorter {
background-position: 0 -20px;
}
.coverage-summary .sorted-desc .sorter {
background-position: 0 -10px;
}
.status-line { height: 10px; }
/* dark red */
.red.solid, .status-line.low, .low .cover-fill { background:#C21F39 }
.low .chart { border:1px solid #C21F39 }
/* medium red */
.cstat-no, .fstat-no, .cbranch-no, .cbranch-no { background:#F6C6CE }
/* light red */
.low, .cline-no { background:#FCE1E5 }
/* light green */
.high, .cline-yes { background:rgb(230,245,208) }
/* medium green */
.cstat-yes { background:rgb(161,215,106) }
/* dark green */
.status-line.high, .high .cover-fill { background:rgb(77,146,33) }
.high .chart { border:1px solid rgb(77,146,33) }
.medium .chart { border:1px solid #666; }
.medium .cover-fill { background: #666; }
.cbranch-no { background: yellow !important; color: #111; }
.cstat-skip { background: #ddd; color: #111; }
.fstat-skip { background: #ddd; color: #111 !important; }
.cbranch-skip { background: #ddd !important; color: #111; }
span.cline-neutral { background: #eaeaea; }
.medium { background: #eaeaea; }
.cover-fill, .cover-empty {
display:inline-block;
height: 12px;
}
.chart {
line-height: 0;
}
.cover-empty {
background: white;
}
.cover-full {
border-right: none !important;
}
pre.prettyprint {
border: none !important;
padding: 0 !important;
margin: 0 !important;
}
.com { color: #999 !important; }
.ignore-none { color: #999; font-weight: normal; }
.wrapper {
min-height: 100%;
height: auto !important;
height: 100%;
margin: 0 auto -48px;
}
.footer, .push {
height: 48px;
}

View File

@@ -0,0 +1,93 @@
<!doctype html>
<html lang="en">
<head>
<title>Code coverage report for All files</title>
<meta charset="utf-8" />
<link rel="stylesheet" href="prettify.css" />
<link rel="stylesheet" href="base.css" />
<meta name="viewport" content="width=device-width, initial-scale=1">
<style type='text/css'>
.coverage-summary .sorter {
background-image: url(sort-arrow-sprite.png);
}
</style>
</head>
<body>
<div class='wrapper'>
<div class='pad1'>
<h1>
/
</h1>
<div class='clearfix'>
<div class='fl pad1y space-right2'>
<span class="strong">77.03% </span>
<span class="quiet">Statements</span>
<span class='fraction'>57/74</span>
</div>
<div class='fl pad1y space-right2'>
<span class="strong">57.14% </span>
<span class="quiet">Branches</span>
<span class='fraction'>28/49</span>
</div>
<div class='fl pad1y space-right2'>
<span class="strong">93.33% </span>
<span class="quiet">Functions</span>
<span class='fraction'>14/15</span>
</div>
<div class='fl pad1y space-right2'>
<span class="strong">79.1% </span>
<span class="quiet">Lines</span>
<span class='fraction'>53/67</span>
</div>
</div>
</div>
<div class='status-line medium'></div>
<div class="pad1">
<table class="coverage-summary">
<thead>
<tr>
<th data-col="file" data-fmt="html" data-html="true" class="file">File</th>
<th data-col="pic" data-type="number" data-fmt="html" data-html="true" class="pic"></th>
<th data-col="statements" data-type="number" data-fmt="pct" class="pct">Statements</th>
<th data-col="statements_raw" data-type="number" data-fmt="html" class="abs"></th>
<th data-col="branches" data-type="number" data-fmt="pct" class="pct">Branches</th>
<th data-col="branches_raw" data-type="number" data-fmt="html" class="abs"></th>
<th data-col="functions" data-type="number" data-fmt="pct" class="pct">Functions</th>
<th data-col="functions_raw" data-type="number" data-fmt="html" class="abs"></th>
<th data-col="lines" data-type="number" data-fmt="pct" class="pct">Lines</th>
<th data-col="lines_raw" data-type="number" data-fmt="html" class="abs"></th>
</tr>
</thead>
<tbody><tr>
<td class="file medium" data-value="__root__/"><a href="__root__/index.html">__root__/</a></td>
<td data-value="77.03" class="pic medium"><div class="chart"><div class="cover-fill" style="width: 77%;"></div><div class="cover-empty" style="width:23%;"></div></div></td>
<td data-value="77.03" class="pct medium">77.03%</td>
<td data-value="74" class="abs medium">57/74</td>
<td data-value="57.14" class="pct medium">57.14%</td>
<td data-value="49" class="abs medium">28/49</td>
<td data-value="93.33" class="pct high">93.33%</td>
<td data-value="15" class="abs high">14/15</td>
<td data-value="79.1" class="pct medium">79.1%</td>
<td data-value="67" class="abs medium">53/67</td>
</tr>
</tbody>
</table>
</div><div class='push'></div><!-- for sticky footer -->
</div><!-- /wrapper -->
<div class='footer quiet pad2 space-top1 center small'>
Code coverage
generated by <a href="http://istanbul-js.org/" target="_blank">istanbul</a> at Fri Feb 12 2016 22:19:00 GMT-0800 (PST)
</div>
</div>
<script src="prettify.js"></script>
<script>
window.onload = function () {
if (typeof prettyPrint === 'function') {
prettyPrint();
}
};
</script>
<script src="sorter.js"></script>
</body>
</html>

View File

@@ -0,0 +1 @@
.pln{color:#000}@media screen{.str{color:#080}.kwd{color:#008}.com{color:#800}.typ{color:#606}.lit{color:#066}.pun,.opn,.clo{color:#660}.tag{color:#008}.atn{color:#606}.atv{color:#080}.dec,.var{color:#606}.fun{color:red}}@media print,projection{.str{color:#060}.kwd{color:#006;font-weight:bold}.com{color:#600;font-style:italic}.typ{color:#404;font-weight:bold}.lit{color:#044}.pun,.opn,.clo{color:#440}.tag{color:#006;font-weight:bold}.atn{color:#404}.atv{color:#060}}pre.prettyprint{padding:2px;border:1px solid #888}ol.linenums{margin-top:0;margin-bottom:0}li.L0,li.L1,li.L2,li.L3,li.L5,li.L6,li.L7,li.L8{list-style-type:none}li.L1,li.L3,li.L5,li.L7,li.L9{background:#eee}

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 209 B

View File

@@ -0,0 +1,158 @@
var addSorting = (function () {
"use strict";
var cols,
currentSort = {
index: 0,
desc: false
};
// returns the summary table element
function getTable() { return document.querySelector('.coverage-summary'); }
// returns the thead element of the summary table
function getTableHeader() { return getTable().querySelector('thead tr'); }
// returns the tbody element of the summary table
function getTableBody() { return getTable().querySelector('tbody'); }
// returns the th element for nth column
function getNthColumn(n) { return getTableHeader().querySelectorAll('th')[n]; }
// loads all columns
function loadColumns() {
var colNodes = getTableHeader().querySelectorAll('th'),
colNode,
cols = [],
col,
i;
for (i = 0; i < colNodes.length; i += 1) {
colNode = colNodes[i];
col = {
key: colNode.getAttribute('data-col'),
sortable: !colNode.getAttribute('data-nosort'),
type: colNode.getAttribute('data-type') || 'string'
};
cols.push(col);
if (col.sortable) {
col.defaultDescSort = col.type === 'number';
colNode.innerHTML = colNode.innerHTML + '<span class="sorter"></span>';
}
}
return cols;
}
// attaches a data attribute to every tr element with an object
// of data values keyed by column name
function loadRowData(tableRow) {
var tableCols = tableRow.querySelectorAll('td'),
colNode,
col,
data = {},
i,
val;
for (i = 0; i < tableCols.length; i += 1) {
colNode = tableCols[i];
col = cols[i];
val = colNode.getAttribute('data-value');
if (col.type === 'number') {
val = Number(val);
}
data[col.key] = val;
}
return data;
}
// loads all row data
function loadData() {
var rows = getTableBody().querySelectorAll('tr'),
i;
for (i = 0; i < rows.length; i += 1) {
rows[i].data = loadRowData(rows[i]);
}
}
// sorts the table using the data for the ith column
function sortByIndex(index, desc) {
var key = cols[index].key,
sorter = function (a, b) {
a = a.data[key];
b = b.data[key];
return a < b ? -1 : a > b ? 1 : 0;
},
finalSorter = sorter,
tableBody = document.querySelector('.coverage-summary tbody'),
rowNodes = tableBody.querySelectorAll('tr'),
rows = [],
i;
if (desc) {
finalSorter = function (a, b) {
return -1 * sorter(a, b);
};
}
for (i = 0; i < rowNodes.length; i += 1) {
rows.push(rowNodes[i]);
tableBody.removeChild(rowNodes[i]);
}
rows.sort(finalSorter);
for (i = 0; i < rows.length; i += 1) {
tableBody.appendChild(rows[i]);
}
}
// removes sort indicators for current column being sorted
function removeSortIndicators() {
var col = getNthColumn(currentSort.index),
cls = col.className;
cls = cls.replace(/ sorted$/, '').replace(/ sorted-desc$/, '');
col.className = cls;
}
// adds sort indicators for current column being sorted
function addSortIndicators() {
getNthColumn(currentSort.index).className += currentSort.desc ? ' sorted-desc' : ' sorted';
}
// adds event listeners for all sorter widgets
function enableUI() {
var i,
el,
ithSorter = function ithSorter(i) {
var col = cols[i];
return function () {
var desc = col.defaultDescSort;
if (currentSort.index === i) {
desc = !currentSort.desc;
}
sortByIndex(i, desc);
removeSortIndicators();
currentSort.index = i;
currentSort.desc = desc;
addSortIndicators();
};
};
for (i =0 ; i < cols.length; i += 1) {
if (cols[i].sortable) {
// add the click event handler on the th so users
// dont have to click on those tiny arrows
el = getNthColumn(i).querySelector('.sorter').parentElement;
if (el.addEventListener) {
el.addEventListener('click', ithSorter(i));
} else {
el.attachEvent('onclick', ithSorter(i));
}
}
}
}
// adds sorting functionality to the UI
return function () {
if (!getTable()) {
return;
}
cols = loadColumns();
loadData(cols);
addSortIndicators();
enableUI();
};
})();
window.addEventListener('load', addSorting);

View File

@@ -0,0 +1,155 @@
TN:
SF:./mute.js
FN:7,MuteStream
FN:29,(anonymous_2)
FN:33,(anonymous_3)
FN:44,onPipe
FN:55,getIsTTY
FN:63,setIsTTY
FN:73,(anonymous_7)
FN:80,(anonymous_8)
FN:87,(anonymous_9)
FN:92,(anonymous_10)
FN:96,(anonymous_11)
FN:100,(anonymous_12)
FN:124,(anonymous_13)
FN:136,proxy
FN:136,(anonymous_15)
FNF:15
FNH:14
FNDA:7,MuteStream
FNDA:10,(anonymous_2)
FNDA:6,(anonymous_3)
FNDA:5,onPipe
FNDA:8,getIsTTY
FNDA:2,setIsTTY
FNDA:5,(anonymous_7)
FNDA:5,(anonymous_8)
FNDA:2,(anonymous_9)
FNDA:2,(anonymous_10)
FNDA:2,(anonymous_11)
FNDA:25,(anonymous_12)
FNDA:2,(anonymous_13)
FNDA:3,proxy
FNDA:0,(anonymous_15)
DA:1,1
DA:3,1
DA:7,1
DA:8,7
DA:9,7
DA:10,7
DA:11,7
DA:12,7
DA:13,7
DA:18,7
DA:19,7
DA:22,1
DA:24,1
DA:29,1
DA:30,10
DA:33,1
DA:34,6
DA:37,1
DA:44,1
DA:45,5
DA:48,1
DA:55,1
DA:56,8
DA:63,1
DA:64,2
DA:72,1
DA:74,5
DA:79,1
DA:81,5
DA:87,1
DA:88,2
DA:89,2
DA:92,1
DA:93,2
DA:96,1
DA:97,2
DA:100,1
DA:101,25
DA:102,13
DA:103,8
DA:104,0
DA:105,0
DA:106,0
DA:107,0
DA:109,0
DA:110,0
DA:112,8
DA:114,0
DA:115,0
DA:116,0
DA:118,8
DA:121,20
DA:124,1
DA:125,2
DA:126,2
DA:127,0
DA:129,2
DA:132,2
DA:133,2
DA:136,3
DA:137,0
DA:138,0
DA:139,0
DA:140,0
DA:143,1
DA:144,1
DA:145,1
LF:67
LH:53
BRDA:9,1,0,7
BRDA:9,1,1,5
BRDA:18,2,0,7
BRDA:18,2,1,7
BRDA:56,3,0,3
BRDA:56,3,1,5
BRDA:57,4,0,3
BRDA:57,4,1,2
BRDA:74,5,0,4
BRDA:74,5,1,1
BRDA:75,6,0,0
BRDA:75,6,1,1
BRDA:81,7,0,4
BRDA:81,7,1,1
BRDA:82,8,0,0
BRDA:82,8,1,1
BRDA:93,9,0,2
BRDA:93,9,1,0
BRDA:97,10,0,2
BRDA:97,10,1,0
BRDA:101,11,0,13
BRDA:101,11,1,12
BRDA:102,12,0,5
BRDA:102,12,1,8
BRDA:103,13,0,0
BRDA:103,13,1,8
BRDA:104,14,0,0
BRDA:104,14,1,0
BRDA:112,15,0,0
BRDA:112,15,1,8
BRDA:112,16,0,8
BRDA:112,16,1,0
BRDA:112,16,2,0
BRDA:125,17,0,2
BRDA:125,17,1,0
BRDA:126,18,0,0
BRDA:126,18,1,2
BRDA:126,19,0,2
BRDA:126,19,1,1
BRDA:132,20,0,0
BRDA:132,20,1,2
BRDA:139,21,0,0
BRDA:139,21,1,0
BRDA:139,22,0,0
BRDA:139,22,1,0
BRDA:140,23,0,0
BRDA:140,23,1,0
BRDA:140,24,0,0
BRDA:140,24,1,0
BRF:49
BRH:28
end_of_record

View File

@@ -0,0 +1,145 @@
var Stream = require('stream')
module.exports = MuteStream
// var out = new MuteStream(process.stdout)
// argument auto-pipes
function MuteStream (opts) {
Stream.apply(this)
opts = opts || {}
this.writable = this.readable = true
this.muted = false
this.on('pipe', this._onpipe)
this.replace = opts.replace
// For readline-type situations
// This much at the start of a line being redrawn after a ctrl char
// is seen (such as backspace) won't be redrawn as the replacement
this._prompt = opts.prompt || null
this._hadControl = false
}
MuteStream.prototype = Object.create(Stream.prototype)
Object.defineProperty(MuteStream.prototype, 'constructor', {
value: MuteStream,
enumerable: false
})
MuteStream.prototype.mute = function () {
this.muted = true
}
MuteStream.prototype.unmute = function () {
this.muted = false
}
Object.defineProperty(MuteStream.prototype, '_onpipe', {
value: onPipe,
enumerable: false,
writable: true,
configurable: true
})
function onPipe (src) {
this._src = src
}
Object.defineProperty(MuteStream.prototype, 'isTTY', {
get: getIsTTY,
set: setIsTTY,
enumerable: true,
configurable: true
})
function getIsTTY () {
return( (this._dest) ? this._dest.isTTY
: (this._src) ? this._src.isTTY
: false
)
}
// basically just get replace the getter/setter with a regular value
function setIsTTY (isTTY) {
Object.defineProperty(this, 'isTTY', {
value: isTTY,
enumerable: true,
writable: true,
configurable: true
})
}
Object.defineProperty(MuteStream.prototype, 'rows', {
get: function () {
return( this._dest ? this._dest.rows
: this._src ? this._src.rows
: undefined )
}, enumerable: true, configurable: true })
Object.defineProperty(MuteStream.prototype, 'columns', {
get: function () {
return( this._dest ? this._dest.columns
: this._src ? this._src.columns
: undefined )
}, enumerable: true, configurable: true })
MuteStream.prototype.pipe = function (dest, options) {
this._dest = dest
return Stream.prototype.pipe.call(this, dest, options)
}
MuteStream.prototype.pause = function () {
if (this._src) return this._src.pause()
}
MuteStream.prototype.resume = function () {
if (this._src) return this._src.resume()
}
MuteStream.prototype.write = function (c) {
if (this.muted) {
if (!this.replace) return true
if (c.match(/^\u001b/)) {
if(c.indexOf(this._prompt) === 0) {
c = c.substr(this._prompt.length);
c = c.replace(/./g, this.replace);
c = this._prompt + c;
}
this._hadControl = true
return this.emit('data', c)
} else {
if (this._prompt && this._hadControl &&
c.indexOf(this._prompt) === 0) {
this._hadControl = false
this.emit('data', this._prompt)
c = c.substr(this._prompt.length)
}
c = c.toString().replace(/./g, this.replace)
}
}
this.emit('data', c)
}
MuteStream.prototype.end = function (c) {
if (this.muted) {
if (c && this.replace) {
c = c.toString().replace(/./g, this.replace)
} else {
c = null
}
}
if (c) this.emit('data', c)
this.emit('end')
}
function proxy (fn) { return function () {
var d = this._dest
var s = this._src
if (d && d[fn]) d[fn].apply(d, arguments)
if (s && s[fn]) s[fn].apply(s, arguments)
}}
MuteStream.prototype.destroy = proxy('destroy')
MuteStream.prototype.destroySoon = proxy('destroySoon')
MuteStream.prototype.close = proxy('close')

View File

@@ -0,0 +1,59 @@
{
"_from": "mute-stream@0.0.7",
"_id": "mute-stream@0.0.7",
"_inBundle": false,
"_integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=",
"_location": "/react-dev-utils/mute-stream",
"_phantomChildren": {},
"_requested": {
"type": "version",
"registry": true,
"raw": "mute-stream@0.0.7",
"name": "mute-stream",
"escapedName": "mute-stream",
"rawSpec": "0.0.7",
"saveSpec": null,
"fetchSpec": "0.0.7"
},
"_requiredBy": [
"/react-dev-utils/inquirer"
],
"_resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz",
"_shasum": "3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab",
"_spec": "mute-stream@0.0.7",
"_where": "/home/bilal/Saburly/slucajna-televizija/node_modules/react-dev-utils/node_modules/inquirer",
"author": {
"name": "Isaac Z. Schlueter",
"email": "i@izs.me",
"url": "http://blog.izs.me/"
},
"bugs": {
"url": "https://github.com/isaacs/mute-stream/issues"
},
"bundleDependencies": false,
"deprecated": false,
"description": "Bytes go in, but they don't come out (when muted).",
"devDependencies": {
"tap": "^5.4.4"
},
"directories": {
"test": "test"
},
"homepage": "https://github.com/isaacs/mute-stream#readme",
"keywords": [
"mute",
"stream",
"pipe"
],
"license": "ISC",
"main": "mute.js",
"name": "mute-stream",
"repository": {
"type": "git",
"url": "git://github.com/isaacs/mute-stream.git"
},
"scripts": {
"test": "tap test/*.js --cov"
},
"version": "0.0.7"
}

View File

@@ -0,0 +1,207 @@
var Stream = require('stream')
var tap = require('tap')
var MS = require('../mute.js')
// some marker objects
var END = {}
var PAUSE = {}
var RESUME = {}
function PassThrough () {
Stream.call(this)
this.readable = this.writable = true
}
PassThrough.prototype = Object.create(Stream.prototype, {
constructor: {
value: PassThrough
},
write: {
value: function (c) {
this.emit('data', c)
return true
}
},
end: {
value: function (c) {
if (c) this.write(c)
this.emit('end')
}
},
pause: {
value: function () {
this.emit('pause')
}
},
resume: {
value: function () {
this.emit('resume')
}
}
})
tap.test('incoming', function (t) {
var ms = new MS
var str = new PassThrough
str.pipe(ms)
var expect = ['foo', 'boo', END]
ms.on('data', function (c) {
t.equal(c, expect.shift())
})
ms.on('end', function () {
t.equal(END, expect.shift())
t.end()
})
str.write('foo')
ms.mute()
str.write('bar')
ms.unmute()
str.write('boo')
ms.mute()
str.write('blaz')
str.end('grelb')
})
tap.test('outgoing', function (t) {
var ms = new MS
var str = new PassThrough
ms.pipe(str)
var expect = ['foo', 'boo', END]
str.on('data', function (c) {
t.equal(c, expect.shift())
})
str.on('end', function () {
t.equal(END, expect.shift())
t.end()
})
ms.write('foo')
ms.mute()
ms.write('bar')
ms.unmute()
ms.write('boo')
ms.mute()
ms.write('blaz')
ms.end('grelb')
})
tap.test('isTTY', function (t) {
var str = new PassThrough
str.isTTY = true
str.columns=80
str.rows=24
var ms = new MS
t.equal(ms.isTTY, false)
t.equal(ms.columns, undefined)
t.equal(ms.rows, undefined)
ms.pipe(str)
t.equal(ms.isTTY, true)
t.equal(ms.columns, 80)
t.equal(ms.rows, 24)
str.isTTY = false
t.equal(ms.isTTY, false)
t.equal(ms.columns, 80)
t.equal(ms.rows, 24)
str.isTTY = true
t.equal(ms.isTTY, true)
t.equal(ms.columns, 80)
t.equal(ms.rows, 24)
ms.isTTY = false
t.equal(ms.isTTY, false)
t.equal(ms.columns, 80)
t.equal(ms.rows, 24)
ms = new MS
t.equal(ms.isTTY, false)
str.pipe(ms)
t.equal(ms.isTTY, true)
str.isTTY = false
t.equal(ms.isTTY, false)
str.isTTY = true
t.equal(ms.isTTY, true)
ms.isTTY = false
t.equal(ms.isTTY, false)
t.end()
})
tap.test('pause/resume incoming', function (t) {
var str = new PassThrough
var ms = new MS
str.on('pause', function () {
t.equal(PAUSE, expect.shift())
})
str.on('resume', function () {
t.equal(RESUME, expect.shift())
})
var expect = [PAUSE, RESUME, PAUSE, RESUME]
str.pipe(ms)
ms.pause()
ms.resume()
ms.pause()
ms.resume()
t.equal(expect.length, 0, 'saw all events')
t.end()
})
tap.test('replace with *', function (t) {
var str = new PassThrough
var ms = new MS({replace: '*'})
str.pipe(ms)
var expect = ['foo', '*****', 'bar', '***', 'baz', 'boo', '**', '****']
ms.on('data', function (c) {
t.equal(c, expect.shift())
})
str.write('foo')
ms.mute()
str.write('12345')
ms.unmute()
str.write('bar')
ms.mute()
str.write('baz')
ms.unmute()
str.write('baz')
str.write('boo')
ms.mute()
str.write('xy')
str.write('xyzΩ')
t.equal(expect.length, 0)
t.end()
})
tap.test('replace with ~YARG~', function (t) {
var str = new PassThrough
var ms = new MS({replace: '~YARG~'})
str.pipe(ms)
var expect = ['foo', '~YARG~~YARG~~YARG~~YARG~~YARG~', 'bar',
'~YARG~~YARG~~YARG~', 'baz', 'boo', '~YARG~~YARG~',
'~YARG~~YARG~~YARG~~YARG~']
ms.on('data', function (c) {
t.equal(c, expect.shift())
})
// also throw some unicode in there, just for good measure.
str.write('foo')
ms.mute()
str.write('ΩΩ')
ms.unmute()
str.write('bar')
ms.mute()
str.write('Ω')
ms.unmute()
str.write('baz')
str.write('boo')
ms.mute()
str.write('Ω')
str.write('ΩΩ')
t.equal(expect.length, 0)
t.end()
})

View File

@@ -0,0 +1,39 @@
'use strict';
const mimicFn = require('mimic-fn');
module.exports = (fn, opts) => {
// TODO: Remove this in v3
if (opts === true) {
throw new TypeError('The second argument is now an options object');
}
if (typeof fn !== 'function') {
throw new TypeError('Expected a function');
}
opts = opts || {};
let ret;
let called = false;
const fnName = fn.displayName || fn.name || '<anonymous>';
const onetime = function () {
if (called) {
if (opts.throw === true) {
throw new Error(`Function \`${fnName}\` can only be called once`);
}
return ret;
}
called = true;
ret = fn.apply(this, arguments);
fn = null;
return ret;
};
mimicFn(onetime, fn);
return onetime;
};

View File

@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.com)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

View File

@@ -0,0 +1,72 @@
{
"_from": "onetime@^2.0.0",
"_id": "onetime@2.0.1",
"_inBundle": false,
"_integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=",
"_location": "/react-dev-utils/onetime",
"_phantomChildren": {},
"_requested": {
"type": "range",
"registry": true,
"raw": "onetime@^2.0.0",
"name": "onetime",
"escapedName": "onetime",
"rawSpec": "^2.0.0",
"saveSpec": null,
"fetchSpec": "^2.0.0"
},
"_requiredBy": [
"/react-dev-utils/restore-cursor"
],
"_resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz",
"_shasum": "067428230fd67443b2794b22bba528b6867962d4",
"_spec": "onetime@^2.0.0",
"_where": "/home/bilal/Saburly/slucajna-televizija/node_modules/react-dev-utils/node_modules/restore-cursor",
"author": {
"name": "Sindre Sorhus",
"email": "sindresorhus@gmail.com",
"url": "sindresorhus.com"
},
"bugs": {
"url": "https://github.com/sindresorhus/onetime/issues"
},
"bundleDependencies": false,
"dependencies": {
"mimic-fn": "^1.0.0"
},
"deprecated": false,
"description": "Ensure a function is only called once",
"devDependencies": {
"ava": "*",
"xo": "*"
},
"engines": {
"node": ">=4"
},
"files": [
"index.js"
],
"homepage": "https://github.com/sindresorhus/onetime#readme",
"keywords": [
"once",
"function",
"one",
"onetime",
"func",
"fn",
"single",
"call",
"called",
"prevent"
],
"license": "MIT",
"name": "onetime",
"repository": {
"type": "git",
"url": "git+https://github.com/sindresorhus/onetime.git"
},
"scripts": {
"test": "xo && ava"
},
"version": "2.0.1"
}

View File

@@ -0,0 +1,65 @@
# onetime [![Build Status](https://travis-ci.org/sindresorhus/onetime.svg?branch=master)](https://travis-ci.org/sindresorhus/onetime)
> Ensure a function is only called once
When called multiple times it will return the return value from the first call.
*Unlike the module [once](https://github.com/isaacs/once), this one isn't naughty extending `Function.prototype`.*
## Install
```
$ npm install --save onetime
```
## Usage
```js
let i = 0;
const foo = onetime(() => i++);
foo(); //=> 0
foo(); //=> 0
foo(); //=> 0
```
```js
const foo = onetime(() => {}, {throw: true});
foo();
foo();
//=> Error: Function `foo` can only be called once
```
## API
### onetime(fn, [options])
Returns a function that only calls `fn` once.
#### fn
Type: `Function`
Function that should only be called once.
#### options
Type: `Object`
##### throw
Type: `boolean`<br>
Default: `false`
Throw an error when called more than once.
## License
MIT © [Sindre Sorhus](https://sindresorhus.com)

View File

@@ -0,0 +1,9 @@
'use strict';
const onetime = require('onetime');
const signalExit = require('signal-exit');
module.exports = onetime(() => {
signalExit(() => {
process.stderr.write('\u001b[?25h');
}, {alwaysLast: true});
});

View File

@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.com)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

View File

@@ -0,0 +1,76 @@
{
"_from": "restore-cursor@^2.0.0",
"_id": "restore-cursor@2.0.0",
"_inBundle": false,
"_integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=",
"_location": "/react-dev-utils/restore-cursor",
"_phantomChildren": {},
"_requested": {
"type": "range",
"registry": true,
"raw": "restore-cursor@^2.0.0",
"name": "restore-cursor",
"escapedName": "restore-cursor",
"rawSpec": "^2.0.0",
"saveSpec": null,
"fetchSpec": "^2.0.0"
},
"_requiredBy": [
"/react-dev-utils/cli-cursor"
],
"_resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz",
"_shasum": "9f7ee287f82fd326d4fd162923d62129eee0dfaf",
"_spec": "restore-cursor@^2.0.0",
"_where": "/home/bilal/Saburly/slucajna-televizija/node_modules/react-dev-utils/node_modules/cli-cursor",
"author": {
"name": "Sindre Sorhus",
"email": "sindresorhus@gmail.com",
"url": "sindresorhus.com"
},
"bugs": {
"url": "https://github.com/sindresorhus/restore-cursor/issues"
},
"bundleDependencies": false,
"dependencies": {
"onetime": "^2.0.0",
"signal-exit": "^3.0.2"
},
"deprecated": false,
"description": "Gracefully restore the CLI cursor on exit",
"engines": {
"node": ">=4"
},
"files": [
"index.js"
],
"homepage": "https://github.com/sindresorhus/restore-cursor#readme",
"keywords": [
"exit",
"quit",
"process",
"graceful",
"shutdown",
"sigterm",
"sigint",
"terminate",
"kill",
"stop",
"cli",
"cursor",
"ansi",
"show",
"term",
"terminal",
"console",
"tty",
"shell",
"command-line"
],
"license": "MIT",
"name": "restore-cursor",
"repository": {
"type": "git",
"url": "git+https://github.com/sindresorhus/restore-cursor.git"
},
"version": "2.0.0"
}

View File

@@ -0,0 +1,25 @@
# restore-cursor
> Gracefully restore the CLI cursor on exit
Prevent the cursor you've hidden interactively from remaining hidden if the process crashes.
## Install
```
$ npm install --save restore-cursor
```
## Usage
```js
const restoreCursor = require('restore-cursor');
restoreCursor();
```
## License
MIT © [Sindre Sorhus](https://sindresorhus.com)

View File

@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2014 Simon Boudrias
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -0,0 +1,79 @@
Run Async
=========
[![npm](https://badge.fury.io/js/run-async.svg)](http://badge.fury.io/js/run-async) [![tests](https://travis-ci.org/SBoudrias/run-async.svg?branch=master)](http://travis-ci.org/SBoudrias/run-async) [![dependencies](https://david-dm.org/SBoudrias/run-async.svg?theme=shields.io)](https://david-dm.org/SBoudrias/run-async)
Utility method to run a function either synchronously or asynchronously using a series of common patterns. This is useful for library author accepting sync or async functions as parameter. `runAsync` will always run them as an async method, and normalize the multiple signature.
Installation
=========
```bash
npm install --save run-async
```
Usage
=========
Here's a simple example print the function results and three options a user can provide a function.
```js
var runAsync = require('run-async');
var printAfter = function (func) {
var cb = function (err, returnValue) {
console.log(returnValue);
};
runAsync(func, cb)(/* arguments for func */);
};
```
#### Using `this.async`
```js
printAfter(function () {
var done = this.async();
setTimeout(function () {
done(null, 'done running with callback');
}, 10);
});
```
#### Returning a promise
```js
printAfter(function () {
return new Promise(function (resolve, reject) {
resolve('done running with promises');
});
});
```
#### Synchronous function
```js
printAfter(function () {
return 'done running sync function';
});
```
### runAsync.cb
`runAsync.cb` supports all the function types that `runAsync` does and additionally a traditional **callback as the last argument** signature:
```js
var runAsync = require('run-async');
// IMPORTANT: The wrapped function must have a fixed number of parameters.
runAsync.cb(function(a, b, cb) {
cb(null, a + b);
}, function(err, result) {
console.log(result)
})(1, 2)
```
If your version of node support Promises natively (node >= 0.12), `runAsync` will return a promise. Example: `runAsync(func)(arg1, arg2).then(cb)`
Licence
========
Copyright (c) 2014 Simon Boudrias (twitter: @vaxilart)
Licensed under the MIT license.

View File

@@ -0,0 +1,61 @@
'use strict';
var isPromise = require('is-promise');
/**
* Return a function that will run a function asynchronously or synchronously
*
* example:
* runAsync(wrappedFunction, callback)(...args);
*
* @param {Function} func Function to run
* @param {Function} cb Callback function passed the `func` returned value
* @return {Function(arguments)} Arguments to pass to `func`. This function will in turn
* return a Promise (Node >= 0.12) or call the callbacks.
*/
var runAsync = module.exports = function (func, cb) {
cb = cb || function () {};
return function () {
var async = false;
var args = arguments;
var promise = new Promise(function (resolve, reject) {
var answer = func.apply({
async: function () {
async = true;
return function (err, value) {
if (err) {
reject(err);
} else {
resolve(value);
}
};
}
}, Array.prototype.slice.call(args));
if (!async) {
if (isPromise(answer)) {
answer.then(resolve, reject);
} else {
resolve(answer);
}
}
});
promise.then(cb.bind(null, null), cb);
return promise;
}
};
runAsync.cb = function (func, cb) {
return runAsync(function () {
var args = Array.prototype.slice.call(arguments);
if (args.length === func.length - 1) {
args.push(this.async());
}
return func.apply(this, args);
}, cb);
};

View File

@@ -0,0 +1,64 @@
{
"_from": "run-async@^2.2.0",
"_id": "run-async@2.3.0",
"_inBundle": false,
"_integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=",
"_location": "/react-dev-utils/run-async",
"_phantomChildren": {},
"_requested": {
"type": "range",
"registry": true,
"raw": "run-async@^2.2.0",
"name": "run-async",
"escapedName": "run-async",
"rawSpec": "^2.2.0",
"saveSpec": null,
"fetchSpec": "^2.2.0"
},
"_requiredBy": [
"/react-dev-utils/inquirer"
],
"_resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz",
"_shasum": "0371ab4ae0bdd720d4166d7dfda64ff7a445a6c0",
"_spec": "run-async@^2.2.0",
"_where": "/home/bilal/Saburly/slucajna-televizija/node_modules/react-dev-utils/node_modules/inquirer",
"author": {
"name": "Simon Boudrias",
"email": "admin@simonboudrias.com"
},
"bugs": {
"url": "https://github.com/SBoudrias/run-async/issues"
},
"bundleDependencies": false,
"dependencies": {
"is-promise": "^2.1.0"
},
"deprecated": false,
"description": "Utility method to run function either synchronously or asynchronously using the common `this.async()` style.",
"devDependencies": {
"mocha": "^3.1.2"
},
"engines": {
"node": ">=0.12.0"
},
"files": [
"index.js"
],
"homepage": "https://github.com/SBoudrias/run-async#readme",
"keywords": [
"flow",
"flow-control",
"async"
],
"license": "MIT",
"main": "index.js",
"name": "run-async",
"repository": {
"type": "git",
"url": "git+https://github.com/SBoudrias/run-async.git"
},
"scripts": {
"test": "mocha -R spec"
},
"version": "2.3.0"
}

Some files were not shown because too many files have changed in this diff Show More