UNPKG

git-cz

Version:

Semantic emojified git commit, git-cz.

1,944 lines (1,590 loc) โ€ข 1.3 MB
(function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){ const chalk = require('chalk'); const InputPrompt = require('inquirer/lib/prompts/input'); class LimitedInputPrompt extends InputPrompt { constructor (...args) { super(...args); if (!this.opt.maxLength) { this.throwParamError('maxLength'); } this.originalMessage = this.opt.message; this.spacer = new Array(this.opt.maxLength).fill('-').join(''); if (this.opt.leadingLabel) { if (typeof this.opt.leadingLabel === 'function') { this.leadingLabel = ' ' + this.opt.leadingLabel(this.answers); } else { this.leadingLabel = ' ' + this.opt.leadingLabel; } } else { this.leadingLabel = ''; } this.leadingLength = this.leadingLabel.length; } remainingChar () { return this.opt.maxLength - this.leadingLength - this.rl.line.length; } onKeypress () { if (this.rl.line.length > this.opt.maxLength - this.leadingLength) { this.rl.line = this.rl.line.slice(0, this.opt.maxLength - this.leadingLength); this.rl.cursor--; } this.render(); } getCharsLeftText () { const chars = this.remainingChar(); if (chars > 15) { return chalk.green(`${chars} chars left`); } else if (chars > 5) { return chalk.yellow(`${chars} chars left`); } else { return chalk.red(`${chars} chars left`); } } render (error) { let bottomContent = ''; let message = this.getQuestion(); let appendContent = ''; const isFinal = this.status === 'answered'; if (isFinal) { appendContent = this.answer; } else { appendContent = this.rl.line; } message = `${message} [${this.spacer}] ${this.getCharsLeftText()} ${this.leadingLabel} ${appendContent}`; if (error) { bottomContent = chalk.red('>> ') + error; } this.screen.render(message, bottomContent); } } module.exports = LimitedInputPrompt; },{"chalk":24,"inquirer/lib/prompts/input":97}],2:[function(require,module,exports){ const {spawn, execSync} = require('child_process'); const fs = require('fs'); const {join} = require('path'); const shellescape = require('any-shell-escape'); const signale = require('signale'); const parseArgs = require('./parseArgs'); const createState = require('./createState'); const runInteractiveQuestions = require('./runInteractiveQuestions'); const runNonInteractiveMode = require('./runNonInteractiveMode'); const formatCommitMessage = require('./formatCommitMessage'); const getGitRootDir = require('./util/getGitRootDir'); // eslint-disable-next-line no-process-env const executeCommand = (command, env = process.env) => { const proc = spawn(command, [], { env, shell: true, stdio: [0, 1, 2] }); proc.on('close', (code) => { // eslint-disable-next-line no-process-exit process.exit(code); }); }; // eslint-disable-next-line complexity const main = async () => { try { const {cliAnswers, cliOptions, passThroughParams} = parseArgs(); if (cliOptions.dryRun) { // eslint-disable-next-line no-console console.log('Running in dry mode.'); } else if ( !passThroughParams['allow-empty'] && !passThroughParams.a && !passThroughParams.amend ) { try { /** * @author https://github.com/rodrigograca31 * @see https://github.com/streamich/git-cz/issues/177 * * Exits with 1 if there are differences and 0 if no differences. */ execSync('git diff HEAD --staged --quiet --exit-code'); // Executes the following line only if the one above didn't crash (exit code: 0) signale.error('No files staged!'); // eslint-disable-next-line no-process-exit process.exit(0); } catch (error) { // eslint-disable no-empty } } let state = null; if (cliOptions.disableEmoji) { state = createState({disableEmoji: cliOptions.disableEmoji}); } else { state = createState(); } if (cliOptions.nonInteractive) { await runNonInteractiveMode(state, cliAnswers); } else { await runInteractiveQuestions(state, cliAnswers); } const message = formatCommitMessage(state); const appendedArgs = []; // eslint-disable-next-line guard-for-in for (const key in passThroughParams) { const value = passThroughParams[key]; if (key.length === 1) { appendedArgs.push('-' + key); } else { appendedArgs.push('--' + key); } if (value !== true) { appendedArgs.push(value); } } const commitMsgFile = join(getGitRootDir(), '.git', 'COMMIT_EDITMSG'); const command = shellescape([ 'git', 'commit', '--file', commitMsgFile, ...appendedArgs ]); if (cliOptions.dryRun) { // eslint-disable-next-line no-console console.log('Will execute command:'); // The full path is replaced with a relative path to make the test pass on every machine // eslint-disable-next-line no-console console.log(command.replace(commitMsgFile, '.git/COMMIT_EDITMSG')); // eslint-disable-next-line no-console console.log('Message:'); // eslint-disable-next-line no-console console.log(message); } else { fs.writeFileSync(commitMsgFile, message); /** * @author https://github.com/oxyii * @see https://github.com/streamich/git-cz/issues/79 */ if (cliOptions.hook) { // eslint-disable-next-line no-process-exit process.exit(0); } executeCommand(command); } } catch (error) { signale.fatal(error); } }; main(); },{"./createState":4,"./formatCommitMessage":6,"./parseArgs":8,"./runInteractiveQuestions":16,"./runNonInteractiveMode":17,"./util/getGitRootDir":18,"any-shell-escape":23,"child_process":undefined,"fs":undefined,"path":undefined,"signale":539}],3:[function(require,module,exports){ /* eslint-disable import/no-dynamic-require, global-require */ const qBody = require('./questions/body'); const qBreaking = require('./questions/breaking'); const qIssues = require('./questions/issues'); const qLerna = require('./questions/lerna'); const qScope = require('./questions/scope'); const qSubject = require('./questions/subject'); const qType = require('./questions/type'); const creators = { body: qBody, breaking: qBreaking, issues: qIssues, lerna: qLerna, scope: qScope, subject: qSubject, type: qType }; const createQuestions = (state, cliAnswers) => { const questions = state.config.questions .filter((name) => cliAnswers[name] === undefined) .map((name) => { const question = creators[name].createQuestion(state); return question; }); return questions.filter(Boolean); }; module.exports = createQuestions; },{"./questions/body":9,"./questions/breaking":10,"./questions/issues":11,"./questions/lerna":12,"./questions/scope":13,"./questions/subject":14,"./questions/type":15}],4:[function(require,module,exports){ const getGitRootDir = require('./util/getGitRootDir'); const getConfig = require('./getConfig'); const createState = (config = {}) => { let root; try { root = getGitRootDir(); } catch (error) { throw new Error('Could not find Git root folder.'); } const state = { answers: { body: '', breaking: '', issues: '', lerna: '', scope: '', subject: '', type: '' }, config: { ...getConfig(root), ...config }, root }; return state; }; module.exports = createState; },{"./getConfig":7,"./util/getGitRootDir":18}],5:[function(require,module,exports){ const types = { chore: { description: 'Build process or auxiliary tool changes', emoji: '๐Ÿค–', value: 'chore' }, ci: { description: 'CI related changes', emoji: '๐ŸŽก', value: 'ci' }, docs: { description: 'Documentation only changes', emoji: 'โœ๏ธ', value: 'docs' }, feat: { description: 'A new feature', emoji: '๐ŸŽธ', value: 'feat' }, fix: { description: 'A bug fix', emoji: '๐Ÿ›', value: 'fix' }, perf: { description: 'A code change that improves performance', emoji: 'โšก๏ธ', value: 'perf' }, refactor: { description: 'A code change that neither fixes a bug or adds a feature', emoji: '๐Ÿ’ก', value: 'refactor' }, release: { description: 'Create a release commit', emoji: '๐Ÿน', value: 'release' }, style: { description: 'Markup, white-space, formatting, missing semi-colons...', emoji: '๐Ÿ’„', value: 'style' }, test: { description: 'Adding missing tests', emoji: '๐Ÿ’', value: 'test' } }; // https://github.com/angular/angular/blob/master/CONTRIBUTING.md#type const list = [ 'test', 'feat', 'fix', 'chore', 'docs', 'refactor', 'style', 'ci', 'perf' ]; // https://github.com/angular/angular/blob/master/CONTRIBUTING.md#scope const scopes = [ ]; const questions = [ 'type', 'scope', 'subject', 'body', 'breaking', 'issues', 'lerna' ]; module.exports = { breakingChangePrefix: '๐Ÿงจ ', closedIssueMessage: 'Closes: ', closedIssuePrefix: 'โœ… ', list, maxMessageLength: 64, minMessageLength: 3, questions, scopes, types }; },{}],6:[function(require,module,exports){ /* eslint-disable complexity */ const wrap = require('word-wrap'); const MAX_LINE_WIDTH = 72; const makeAffectsLine = function (answers) { const selectedPackages = answers.packages; if (selectedPackages && selectedPackages.length) { return `\naffects: ${selectedPackages.join(', ')}`; } return ''; }; const formatCommitMessage = (state) => { const {config, answers} = state; const wrapOptions = { indent: '', trim: true, width: MAX_LINE_WIDTH }; let head = ''; let scope = ''; if (answers.scope && answers.scope !== 'none') { scope = `(${answers.scope})`; } if (config.disableEmoji) { head = answers.type + scope + ': ' + answers.subject; } else { const emoji = config.types[answers.type].emoji; const emojiPrefix = emoji ? emoji + ' ' : ''; head = answers.type + scope + ': ' + emojiPrefix + answers.subject; } const affectsLine = makeAffectsLine(answers); // Wrap these lines at MAX_LINE_WIDTH character const body = wrap((answers.body || '') + affectsLine, wrapOptions); const breaking = wrap(answers.breaking, wrapOptions); const issues = wrap(answers.issues, wrapOptions); let msg = head; if (body) { msg += '\n\n' + body; } if (breaking) { const breakingEmoji = config.disableEmoji ? '' : config.breakingChangePrefix; msg += '\n\nBREAKING CHANGE: ' + breakingEmoji + breaking; } if (issues) { const closedIssueEmoji = config.disableEmoji ? '' : config.closedIssuePrefix; msg += '\n\n' + closedIssueEmoji + config.closedIssueMessage + issues; } return msg; }; module.exports = formatCommitMessage; },{"word-wrap":557}],7:[function(require,module,exports){ /* eslint-disable global-require, import/no-dynamic-require */ const path = require('path'); const fs = require('fs'); const signale = require('signale'); const defaults = require('./defaults'); const configFiles = [ '.git-cz.json', 'changelog.config.js', 'changelog.config.json' ]; const findOverrides = (root) => { const dir = root || process.cwd(); for (const file of configFiles) { const filename = path.resolve(dir, file); if (fs.existsSync(filename) && fs.statSync(filename).isFile()) { return require(filename); } } const parent = path.resolve(dir, '..'); if (parent !== dir) { return findOverrides(parent); } const pkgFilename = path.join(dir, 'package.json'); if (fs.existsSync(pkgFilename)) { try { const changelog = require(pkgFilename).config.commitizen.changelog; if (changelog) { return changelog; } // eslint-disable-next-line no-empty } catch (error) {} } return {}; }; const getConfig = (root) => { const overrides = findOverrides(root); if (typeof overrides !== 'object') { signale.fatal(new TypeError('Expected changelog config to be an object.')); // eslint-disable-next-line no-process-exit process.exit(1); } return { ...defaults, ...overrides }; }; module.exports = getConfig; },{"./defaults":5,"fs":undefined,"path":undefined,"signale":539}],8:[function(require,module,exports){ /* eslint-disable no-process-exit */ /* eslint-disable no-console */ /* eslint-disable id-length */ const minimist = require('minimist'); const pkg = require('../package.json'); const helpScreen = ` ${pkg.description} Usage: git-cz [options] options: -h, --help show usage information -v, --version print version info and exit --disable-emoji don't add emoji to commit title --non-interactive run git-cz in non-interactive mode non-interactive mode options: --type type of the commit, defaults to "chore" --subject message of the commit, defaults to "automated commit" --scope semantic commit scope --body extended description of the commit --breaking description of breaking changes, if any --issues GitHub issues this commit closed, e.g "#123" --lerna Lerna mono-repo packages this commit affects `; const parseArgs = () => { const { // eslint-disable-next-line no-unused-vars _: inputs, 'dry-run': dryRun, hook, 'disable-emoji': disableEmoji, 'non-interactive': nonInteractive, body, breaking, issues, lerna, scope, subject, type, help, h, version, v, ...passThroughParams } = minimist(process.argv.slice(2), { alias: { h: 'help', v: 'version' }, boolean: ['version', 'help', 'disable-emoji', 'non-interactive', 'hook', 'dry-run'], string: ['type', 'subject', 'scope', 'body', 'breaking', 'issues', 'learna'] }); if (help || h) { console.log(helpScreen); process.exit(); } if (version || v) { console.log(pkg.version); process.exit(); } const cliOptions = { disableEmoji, dryRun, help, hook, nonInteractive, version }; const cliAnswers = { body, breaking, issues, lerna, scope, subject, type }; return { cliAnswers, cliOptions, passThroughParams }; }; module.exports = parseArgs; },{"../package.json":558,"minimist":324}],9:[function(require,module,exports){ exports.createQuestion = () => { const question = { message: 'Provide a longer description of the change:\n ', name: 'body', type: 'input' }; return question; }; },{}],10:[function(require,module,exports){ const chalk = require('chalk'); exports.createQuestion = () => { const question = { message: `List any breaking changes\n ${chalk.red('BREAKING CHANGE')}:`, name: 'breaking', type: 'input' }; return question; }; },{"chalk":24}],11:[function(require,module,exports){ exports.createQuestion = () => ({ message: 'Issues this commit closes, e.g #123:', name: 'issues', type: 'input' }); },{}],12:[function(require,module,exports){ const {getAllPackages, getChangedPackages, isLerna} = require('../util/lerna'); exports.createQuestion = (state) => { if (!isLerna(state)) { return null; } const changedPackages = getChangedPackages(state); const allPackages = getAllPackages(state); const question = { choices: allPackages, default: changedPackages, message: `The packages that this commit has affected (${changedPackages.length} detected)\n`, name: 'packages', type: 'checkbox' }; return question; }; },{"../util/lerna":19}],13:[function(require,module,exports){ const fuzzy = require('fuzzy'); /** * Searches for the scopes containing the given substring. * * @param {string} substring Substring to search with. * @param {string[]} scopes Scopes list. */ const findScope = function (substring, scopes) { return Promise.resolve(fuzzy.filter(substring || '', scopes).map(({original: scope}) => scope)); }; exports.createQuestion = (state) => { const {scopes} = state.config; if (!scopes) { return null; } if (!Array.isArray(scopes)) { throw new TypeError('scopes must be an array of strings.'); } if (scopes.length < 1) { return null; } const question = { message: 'Select the scope this component affects:', name: 'scope', source: (_answers, input) => findScope(input, scopes), type: 'autocomplete' }; return question; }; },{"fuzzy":50}],14:[function(require,module,exports){ exports.createQuestion = (state) => { const {config} = state; const minTitleLengthErrorMessage = `The subject must have at least ${config.minMessageLength} characters`; const question = { filter: (input) => { let subject; subject = input.trim(); while (subject.endsWith('.')) { subject = subject.substr(0, subject.length - 1).trim(); } return subject; }, leadingLabel: (answers) => { let scope = ''; if (answers.scope && answers.scope !== 'none') { scope = `(${answers.scope})`; } return `${state.answers.type || answers.type}${scope}:`; }, // Minus 3 chars are for emoji + space. maxLength: config.maxMessageLength - 3, message: 'Write a short, imperative mood description of the change:', name: 'subject', type: 'limitedInput', validate: (input) => input.length >= config.minMessageLength || minTitleLengthErrorMessage }; return question; }; },{}],15:[function(require,module,exports){ const fuzzy = require('fuzzy'); const typeToListItem = ({types, disableEmoji}, type) => { const {description, emoji, value} = types[type]; const prefix = emoji && !disableEmoji ? emoji + ' ' : ''; return { name: prefix + (value + ':').padEnd(12, ' ') + description, value }; }; /** * Searches for the type that includes the given substring. * * @param {string} substring Substring to search with. * @param {string[]} config The whole config. */ const findType = function (substring, config) { const types = config.list; return Promise.resolve(fuzzy.filter(substring || '', types).map(({original: type}) => typeToListItem(config, type))); }; exports.createQuestion = (state) => { const {config} = state; const question = { message: 'Select the type of change that you\'re committing:', name: 'type', source: (_answers, input) => findType(input, config), type: 'autocomplete' }; return question; }; },{"fuzzy":50}],16:[function(require,module,exports){ const inquirer = require('inquirer'); const AutocompletePrompt = require('inquirer-list-search-prompt'); const LimitedInputPrompt = require('./LimitedInputPrompt'); const createQuestions = require('./createQuestions'); inquirer.registerPrompt('limitedInput', LimitedInputPrompt); inquirer.registerPrompt('autocomplete', AutocompletePrompt); // if (IS_LERNA_PROJECT) { // const allPackages = getAllPackages().map((pkg) => pkg.name); // const changedPackages = getChangedPackages(); // // promptQuestions = promptQuestions.concat(createPackagesQuestion(allPackages, changedPackages)); // } const runInteractiveQuestions = async (state, cliAnswers) => { Object.keys(cliAnswers).forEach((key) => { state.answers[key] = cliAnswers[key]; }); const questions = createQuestions(state, cliAnswers); const answers = await inquirer.prompt(questions); Object.keys(state.answers).forEach((key) => { if (answers[key]) { state.answers[key] = answers[key]; } }); return answers; }; module.exports = runInteractiveQuestions; },{"./LimitedInputPrompt":1,"./createQuestions":3,"inquirer":88,"inquirer-list-search-prompt":77}],17:[function(require,module,exports){ const runNonInteractiveMode = (state, {type = 'chore', subject = 'automated commit', ...restAnswers}) => { const answers = { subject, type, ...restAnswers }; Object.keys(state.answers).forEach((key) => { if (answers[key]) { state.answers[key] = answers[key]; delete answers[key]; } }); }; module.exports = runNonInteractiveMode; },{}],18:[function(require,module,exports){ const {execSync} = require('child_process'); const getGitRootDir = () => { const devNull = process.platform === 'win32' ? ' nul' : '/dev/null'; const dir = execSync('git rev-parse --show-toplevel 2>' + devNull) .toString() .trim(); return dir; }; module.exports = getGitRootDir; },{"child_process":undefined}],19:[function(require,module,exports){ const {execSync} = require('child_process'); const path = require('path'); const fs = require('fs'); const isLerna = (state) => fs.existsSync(path.join(state.root, 'lerna.json')); const isDir = (root) => (name) => { const filepath = path.join(root, name); try { const stats = fs.statSync(filepath); return stats.isDirectory(); } catch (error) { return false; } }; const removeLastDirectoryPartOf = (url) => { return url.substring(0, url.lastIndexOf('/')); } const getPackageDirectory = (state) => { const pkgFilename = path.join(state.root, 'package.json'); if (fs.existsSync(pkgFilename)) { try { const packagesDirectory = require(pkgFilename).workspaces.packages; if (packagesDirectory) { // Remove the /* on the tail return removeLastDirectoryPartOf("" + packagesDirectory); } // eslint-disable-next-line no-empty } catch (error) { } } return "packages"; } const getAllPackages = (state) => { try { const dir = path.join(state.root, getPackageDirectory(state)); return fs.readdirSync(dir).filter(isDir(dir)); } catch (error) { return []; } }; const getChangedFiles = () => { const devNull = process.platform === 'win32' ? ' nul' : '/dev/null' return execSync('git diff --cached --name-only 2>' + devNull) .toString() .trim() .split('\n'); } const getChangedPackages = (state) => { const unique = {}; const changedFiles = getChangedFiles(); const regex = new RegExp("^"+ getPackageDirectory(state) +"\/([^/]+)\/", "is"); for (const filename of changedFiles) { const matches = filename.match(regex); if (matches) { unique[matches[1]] = 1; } } return Object.keys(unique); }; module.exports = { getAllPackages, getChangedPackages, isLerna }; },{"child_process":undefined,"fs":undefined,"path":undefined}],20:[function(require,module,exports){ 'use strict'; const ansiEscapes = module.exports; // TODO: remove this in the next major version module.exports.default = ansiEscapes; const ESC = '\u001B['; const OSC = '\u001B]'; const BEL = '\u0007'; const SEP = ';'; const isTerminalApp = process.env.TERM_PROGRAM === 'Apple_Terminal'; ansiEscapes.cursorTo = (x, y) => { if (typeof x !== 'number') { throw new TypeError('The `x` argument is required'); } if (typeof y !== 'number') { return ESC + (x + 1) + 'G'; } return ESC + (y + 1) + ';' + (x + 1) + 'H'; }; ansiEscapes.cursorMove = (x, y) => { if (typeof x !== 'number') { throw new TypeError('The `x` argument is required'); } 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; }; ansiEscapes.cursorUp = (count = 1) => ESC + count + 'A'; ansiEscapes.cursorDown = (count = 1) => ESC + count + 'B'; ansiEscapes.cursorForward = (count = 1) => ESC + count + 'C'; ansiEscapes.cursorBackward = (count = 1) => ESC + count + 'D'; ansiEscapes.cursorLeft = ESC + 'G'; ansiEscapes.cursorSavePosition = isTerminalApp ? '\u001B7' : ESC + 's'; ansiEscapes.cursorRestorePosition = isTerminalApp ? '\u001B8' : ESC + 'u'; ansiEscapes.cursorGetPosition = ESC + '6n'; ansiEscapes.cursorNextLine = ESC + 'E'; ansiEscapes.cursorPrevLine = ESC + 'F'; ansiEscapes.cursorHide = ESC + '?25l'; ansiEscapes.cursorShow = ESC + '?25h'; ansiEscapes.eraseLines = count => { let clear = ''; for (let i = 0; i < count; i++) { clear += ansiEscapes.eraseLine + (i < count - 1 ? ansiEscapes.cursorUp() : ''); } if (count) { clear += ansiEscapes.cursorLeft; } return clear; }; ansiEscapes.eraseEndLine = ESC + 'K'; ansiEscapes.eraseStartLine = ESC + '1K'; ansiEscapes.eraseLine = ESC + '2K'; ansiEscapes.eraseDown = ESC + 'J'; ansiEscapes.eraseUp = ESC + '1J'; ansiEscapes.eraseScreen = ESC + '2J'; ansiEscapes.scrollUp = ESC + 'S'; ansiEscapes.scrollDown = ESC + 'T'; ansiEscapes.clearScreen = '\u001Bc'; ansiEscapes.clearTerminal = process.platform === 'win32' ? `${ansiEscapes.eraseScreen}${ESC}0f` : // 1. Erases the screen (Only done in case `2` is not supported) // 2. Erases the whole screen including scrollback buffer // 3. Moves cursor to the top-left position // More info: https://www.real-world-systems.com/docs/ANSIcode.html `${ansiEscapes.eraseScreen}${ESC}3J${ESC}H`; ansiEscapes.beep = BEL; ansiEscapes.link = (text, url) => { return [ OSC, '8', SEP, SEP, url, BEL, text, OSC, '8', SEP, SEP, BEL ].join(''); }; ansiEscapes.image = (buffer, options = {}) => { let ret = `${OSC}1337;File=inline=1`; if (options.width) { ret += `;width=${options.width}`; } if (options.height) { ret += `;height=${options.height}`; } if (options.preserveAspectRatio === false) { ret += ';preserveAspectRatio=0'; } return ret + ':' + buffer.toString('base64') + BEL; }; ansiEscapes.iTerm = { setCwd: (cwd = process.cwd()) => `${OSC}50;CurrentDir=${cwd}${BEL}`, annotation: (message, options = {}) => { let ret = `${OSC}1337;`; const hasX = typeof options.x !== 'undefined'; const hasY = typeof options.y !== 'undefined'; if ((hasX || hasY) && !(hasX && hasY && typeof options.length !== 'undefined')) { throw new Error('`x`, `y` and `length` must be defined when `x` or `y` is defined'); } message = message.replace(/\|/g, ''); ret += options.isHidden ? 'AddHiddenAnnotation=' : 'AddAnnotation='; if (options.length > 0) { ret += (hasX ? [message, options.length, options.x, options.y] : [options.length, message]).join('|'); } else { ret += message; } return ret + BEL; } }; },{}],21:[function(require,module,exports){ 'use strict'; module.exports = ({onlyFirst = false} = {}) => { const pattern = [ '[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:[a-zA-Z\\d]*(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?\\u0007)', '(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-ntqry=><~]))' ].join('|'); return new RegExp(pattern, onlyFirst ? undefined : 'g'); }; },{}],22:[function(require,module,exports){ 'use strict'; const wrapAnsi16 = (fn, offset) => (...args) => { const code = fn(...args); return `\u001B[${code + offset}m`; }; const wrapAnsi256 = (fn, offset) => (...args) => { const code = fn(...args); return `\u001B[${38 + offset};5;${code}m`; }; const wrapAnsi16m = (fn, offset) => (...args) => { const rgb = fn(...args); return `\u001B[${38 + offset};2;${rgb[0]};${rgb[1]};${rgb[2]}m`; }; const ansi2ansi = n => n; const rgb2rgb = (r, g, b) => [r, g, b]; const setLazyProperty = (object, property, get) => { Object.defineProperty(object, property, { get: () => { const value = get(); Object.defineProperty(object, property, { value, enumerable: true, configurable: true }); return value; }, enumerable: true, configurable: true }); }; /** @type {typeof import('color-convert')} */ let colorConvert; const makeDynamicStyles = (wrap, targetSpace, identity, isBackground) => { if (colorConvert === undefined) { colorConvert = require('color-convert'); } const offset = isBackground ? 10 : 0; const styles = {}; for (const [sourceSpace, suite] of Object.entries(colorConvert)) { const name = sourceSpace === 'ansi16' ? 'ansi' : sourceSpace; if (sourceSpace === targetSpace) { styles[name] = wrap(identity, offset); } else if (typeof suite === 'object') { styles[name] = wrap(suite[targetSpace], offset); } } return styles; }; function assembleStyles() { const codes = new Map(); const styles = { modifier: { reset: [0, 0], // 21 isn't widely supported and 22 does the same thing bold: [1, 22], dim: [2, 22], italic: [3, 23], underline: [4, 24], inverse: [7, 27], hidden: [8, 28], strikethrough: [9, 29] }, color: { black: [30, 39], red: [31, 39], green: [32, 39], yellow: [33, 39], blue: [34, 39], magenta: [35, 39], cyan: [36, 39], white: [37, 39], // Bright color blackBright: [90, 39], redBright: [91, 39], greenBright: [92, 39], yellowBright: [93, 39], blueBright: [94, 39], magentaBright: [95, 39], cyanBright: [96, 39], whiteBright: [97, 39] }, bgColor: { bgBlack: [40, 49], bgRed: [41, 49], bgGreen: [42, 49], bgYellow: [43, 49], bgBlue: [44, 49], bgMagenta: [45, 49], bgCyan: [46, 49], bgWhite: [47, 49], // Bright color bgBlackBright: [100, 49], bgRedBright: [101, 49], bgGreenBright: [102, 49], bgYellowBright: [103, 49], bgBlueBright: [104, 49], bgMagentaBright: [105, 49], bgCyanBright: [106, 49], bgWhiteBright: [107, 49] } }; // Alias bright black as gray (and grey) styles.color.gray = styles.color.blackBright; styles.bgColor.bgGray = styles.bgColor.bgBlackBright; styles.color.grey = styles.color.blackBright; styles.bgColor.bgGrey = styles.bgColor.bgBlackBright; for (const [groupName, group] of Object.entries(styles)) { for (const [styleName, style] of Object.entries(group)) { styles[styleName] = { open: `\u001B[${style[0]}m`, close: `\u001B[${style[1]}m` }; group[styleName] = styles[styleName]; codes.set(style[0], style[1]); } Object.defineProperty(styles, groupName, { value: group, enumerable: false }); } Object.defineProperty(styles, 'codes', { value: codes, enumerable: false }); styles.color.close = '\u001B[39m'; styles.bgColor.close = '\u001B[49m'; setLazyProperty(styles.color, 'ansi', () => makeDynamicStyles(wrapAnsi16, 'ansi16', ansi2ansi, false)); setLazyProperty(styles.color, 'ansi256', () => makeDynamicStyles(wrapAnsi256, 'ansi256', ansi2ansi, false)); setLazyProperty(styles.color, 'ansi16m', () => makeDynamicStyles(wrapAnsi16m, 'rgb', rgb2rgb, false)); setLazyProperty(styles.bgColor, 'ansi', () => makeDynamicStyles(wrapAnsi16, 'ansi16', ansi2ansi, true)); setLazyProperty(styles.bgColor, 'ansi256', () => makeDynamicStyles(wrapAnsi256, 'ansi256', ansi2ansi, true)); setLazyProperty(styles.bgColor, 'ansi16m', () => makeDynamicStyles(wrapAnsi16m, 'rgb', rgb2rgb, true)); return styles; } // Make the export immutable Object.defineProperty(module, 'exports', { enumerable: true, get: assembleStyles }); },{"color-convert":37}],23:[function(require,module,exports){ var util = require('util'), winCmd = /^win/.test(process.platform), escapePath; function escapePathSh(path) { if (!/^[A-Za-z0-9_\/-]+$/.test(path)) return ("'" + path.replace(/'/g, "'\"'\"'") + "'").replace(/''/g, ''); else return path; } function escapePathWin(path) { if (!/^[A-Za-z0-9_\/-]+$/.test(path)) return '"' + path.replace(/"/g, '""') + '"'; else return path; } if (winCmd) { escapePath = escapePathWin; } else { escapePath = escapePathSh; } module.exports = function(stringOrArray) { var ret = []; if (typeof(stringOrArray) == 'string') { return escapePath(stringOrArray); } else { stringOrArray.forEach(function(member) { ret.push(escapePath(member)); }); return ret.join(' '); } }; if (winCmd) { // Cannot escape messages on windows module.exports.msg = function(x) { if (typeof(x) == 'string') { return x; } else { return x.join(' '); } }; } else { module.exports.msg = module.exports; } },{"util":undefined}],24:[function(require,module,exports){ 'use strict'; const ansiStyles = require('ansi-styles'); const {stdout: stdoutColor, stderr: stderrColor} = require('supports-color'); const { stringReplaceAll, stringEncaseCRLFWithFirstIndex } = require('./util'); const {isArray} = Array; // `supportsColor.level` โ†’ `ansiStyles.color[name]` mapping const levelMapping = [ 'ansi', 'ansi', 'ansi256', 'ansi16m' ]; const styles = Object.create(null); const applyOptions = (object, options = {}) => { if (options.level && !(Number.isInteger(options.level) && options.level >= 0 && options.level <= 3)) { throw new Error('The `level` option should be an integer from 0 to 3'); } // Detect level if not set manually const colorLevel = stdoutColor ? stdoutColor.level : 0; object.level = options.level === undefined ? colorLevel : options.level; }; class ChalkClass { constructor(options) { // eslint-disable-next-line no-constructor-return return chalkFactory(options); } } const chalkFactory = options => { const chalk = {}; applyOptions(chalk, options); chalk.template = (...arguments_) => chalkTag(chalk.template, ...arguments_); Object.setPrototypeOf(chalk, Chalk.prototype); Object.setPrototypeOf(chalk.template, chalk); chalk.template.constructor = () => { throw new Error('`chalk.constructor()` is deprecated. Use `new chalk.Instance()` instead.'); }; chalk.template.Instance = ChalkClass; return chalk.template; }; function Chalk(options) { return chalkFactory(options); } for (const [styleName, style] of Object.entries(ansiStyles)) { styles[styleName] = { get() { const builder = createBuilder(this, createStyler(style.open, style.close, this._styler), this._isEmpty); Object.defineProperty(this, styleName, {value: builder}); return builder; } }; } styles.visible = { get() { const builder = createBuilder(this, this._styler, true); Object.defineProperty(this, 'visible', {value: builder}); return builder; } }; const usedModels = ['rgb', 'hex', 'keyword', 'hsl', 'hsv', 'hwb', 'ansi', 'ansi256']; for (const model of usedModels) { styles[model] = { get() { const {level} = this; return function (...arguments_) { const styler = createStyler(ansiStyles.color[levelMapping[level]][model](...arguments_), ansiStyles.color.close, this._styler); return createBuilder(this, styler, this._isEmpty); }; } }; } for (const model of usedModels) { const bgModel = 'bg' + model[0].toUpperCase() + model.slice(1); styles[bgModel] = { get() { const {level} = this; return function (...arguments_) { const styler = createStyler(ansiStyles.bgColor[levelMapping[level]][model](...arguments_), ansiStyles.bgColor.close, this._styler); return createBuilder(this, styler, this._isEmpty); }; } }; } const proto = Object.defineProperties(() => {}, { ...styles, level: { enumerable: true, get() { return this._generator.level; }, set(level) { this._generator.level = level; } } }); const createStyler = (open, close, parent) => { let openAll; let closeAll; if (parent === undefined) { openAll = open; closeAll = close; } else { openAll = parent.openAll + open; closeAll = close + parent.closeAll; } return { open, close, openAll, closeAll, parent }; }; const createBuilder = (self, _styler, _isEmpty) => { const builder = (...arguments_) => { if (isArray(arguments_[0]) && isArray(arguments_[0].raw)) { // Called as a template literal, for example: chalk.red`2 + 3 = {bold ${2+3}}` return applyStyle(builder, chalkTag(builder, ...arguments_)); } // Single argument is hot path, implicit coercion is faster than anything // eslint-disable-next-line no-implicit-coercion return applyStyle(builder, (arguments_.length === 1) ? ('' + arguments_[0]) : arguments_.join(' ')); }; // We alter the prototype because we must return a function, but there is // no way to create a function with a different prototype Object.setPrototypeOf(builder, proto); builder._generator = self; builder._styler = _styler; builder._isEmpty = _isEmpty; return builder; }; const applyStyle = (self, string) => { if (self.level <= 0 || !string) { return self._isEmpty ? '' : string; } let styler = self._styler; if (styler === undefined) { return string; } const {openAll, closeAll} = styler; if (string.indexOf('\u001B') !== -1) { while (styler !== undefined) { // 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'. string = stringReplaceAll(string, styler.close, styler.open); styler = styler.parent; } } // We can move both next actions out of loop, because remaining actions in loop won't have // any/visible effect on parts we add here. 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 const lfIndex = string.indexOf('\n'); if (lfIndex !== -1) { string = stringEncaseCRLFWithFirstIndex(string, closeAll, openAll, lfIndex); } return openAll + string + closeAll; }; let template; const chalkTag = (chalk, ...strings) => { const [firstString] = strings; if (!isArray(firstString) || !isArray(firstString.raw)) { // If chalk() was called by itself or with a string, // return the string itself as a string. return strings.join(' '); } const arguments_ = strings.slice(1); const parts = [firstString.raw[0]]; for (let i = 1; i < firstString.length; i++) { parts.push( String(arguments_[i - 1]).replace(/[{}\\]/g, '\\$&'), String(firstString.raw[i]) ); } if (template === undefined) { template = require('./templates'); } return template(chalk, parts.join('')); }; Object.defineProperties(Chalk.prototype, styles); const chalk = Chalk(); // eslint-disable-line new-cap chalk.supportsColor = stdoutColor; chalk.stderr = Chalk({level: stderrColor ? stderrColor.level : 0}); // eslint-disable-line new-cap chalk.stderr.supportsColor = stderrColor; module.exports = chalk; },{"./templates":25,"./util":26,"ansi-styles":22,"supports-color":554}],25:[function(require,module,exports){ 'use strict'; const TEMPLATE_REGEX = /(?:\\(u(?:[a-f\d]{4}|\{[a-f\d]{1,6}\})|x[a-f\d]{2}|.))|(?:\{(~)?(\w+(?:\([^)]*\))?(?:\.\w+(?:\([^)]*\))?)*)(?:[ \t]|(?=\r?\n)))|(\})|((?:.|[\r\n\f])+?)/gi; const STYLE_REGEX = /(?:^|\.)(\w+)(?:\(([^)]*)\))?/g; const STRING_REGEX = /^(['"])((?:\\.|(?!\1)[^\\])*)\1$/; const ESCAPE_REGEX = /\\(u(?:[a-f\d]{4}|{[a-f\d]{1,6}})|x[a-f\d]{2}|.)|([^\\])/gi; const ESCAPES = new Map([ ['n', '\n'], ['r', '\r'], ['t', '\t'], ['b', '\b'], ['f', '\f'], ['v', '\v'], ['0', '\0'], ['\\', '\\'], ['e', '\u001B'], ['a', '\u0007'] ]); function unescape(c) { const u = c[0] === 'u'; const bracket = c[1] === '{'; if ((u && !bracket && c.length === 5) || (c[0] === 'x' && c.length === 3)) { return String.fromCharCode(parseInt(c.slice(1), 16)); } if (u && bracket) { return String.fromCodePoint(parseInt(c.slice(2, -1), 16)); } return ESCAPES.get(c) || c; } function parseArguments(name, arguments_) { const results = []; const chunks = arguments_.trim().split(/\s*,\s*/g); let matches; for (const chunk of chunks) { const number = Number(chunk); if (!Number.isNaN(number)) { results.push(number); } else if ((matches = chunk.match(STRING_REGEX))) { results.push(matches[2].replace(ESCAPE_REGEX, (m, escape, character) => escape ? unescape(escape) : character)); } 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, styles] of Object.entries(enabled)) { if (!Array.isArray(styles)) { continue; } if (!(styleName in current)) { throw new Error(`Unknown Chalk style: ${styleName}`); } current = styles.length > 0 ? current[styleName](...styles) : current[styleName]; } return current; } module.exports = (chalk, temporary) => { const styles = []; const chunks = []; let chunk = []; // eslint-disable-next-line max-params temporary.replace(TEMPLATE_REGEX, (m, escapeCharacter, inverse, style, close, character) => { if (escapeCharacter) { chunk.push(unescape(escapeCharacter)); } else if (style) { const string = chunk.join(''); chunk = []; chunks.push(styles.length === 0 ? string : buildStyle(chalk, styles)(string)); 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(character); } }); chunks.push(chunk.join('')); if (styles.length > 0) { const errMessage = `Chalk template literal is missing ${styles.length} closing bracket${styles.length === 1 ? '' : 's'} (\`}\`)`; throw new Error(errMessage); } return chunks.join(''); }; },{}],26:[function(require,module,exports){ 'use strict'; const stringReplaceAll = (string, substring, replacer) => { let index = string.indexOf(substring); if (index === -1) { return string; } const substringLength = substring.length; let endIndex = 0; let returnValue = ''; do { returnValue += string.substr(endIndex, index - endIndex) + substring + replacer; endIndex = index + substringLength; index = string.indexOf(substring, endIndex); } while (index !== -1); returnValue += string.substr(endIndex); return returnValue; }; const stringEncaseCRLFWithFirstIndex = (string, prefix, postfix, index) => { let endIndex = 0; let returnValue = ''; do { const gotCR = string[index - 1] === '\r'; returnValue += string.substr(endIndex, (gotCR ? index - 1 : index) - endIndex) + prefix + (gotCR ? '\r\n' : '\n') + postfix; endIndex = index + 1; index = string.indexOf('\n', endIndex); } while (index !== -1); returnValue += string.substr(endIndex); return returnValue; }; module.exports = { stringReplaceAll, stringEncaseCRLFWithFirstIndex }; },{}],27:[function(require,module,exports){ var util = require('util'), Match = require ('../match'); /** * This is a superclass for the individual detectors for * each of the detectable members of the ISO 2022 family * of encodings. */ function ISO_2022() {} ISO_2022.prototype.match = function(det) { /** * Matching function shared among the 2022 detectors JP, CN and KR * Counts up the number of legal an unrecognized escape sequences in * the sample of text, and computes a score based on the total number & * the proportion that fit the encoding. * * * @param text the byte buffer containing text to analyse * @param textLen the size of the text in the byte. * @param escapeSequences the byte escape sequences to test for. * @return match quality, in the range of 0-100. */ var i, j; var escN; var hits = 0; var misses = 0; var shifts = 0; var quality; // TODO: refactor me var text = det.fInputBytes; var textLen = det.fInputLen; scanInput: for (i = 0; i < textLen; i++) { if (text[i] == 0x1b) { checkEscapes: for (escN = 0; escN < this.escapeSequences.length; escN++) { var seq = this.escapeSequences[escN]; if ((textLen - i) < seq.length) continue checkEscapes; for (j = 1; j < seq.length; j++) if (seq[j] != text[i + j]) continue checkEscapes; hits++; i += seq.length - 1; continue scanInput; } misses++; } // Shift in/out if (text[i] == 0x0e || text[i] == 0x0f) shifts++; } if (hits == 0) return null; // // Initial quality is based on relative proportion of recongized vs. // unrecognized escape sequences. // All good: quality = 100; // half or less good: quality = 0; // linear inbetween. quality = (100 * hits - 100 * misses) / (hits + misses); // Back off quality if there were too few escape sequences seen. // Include shifts in this computation, so that KR does not get penalized // for having only a single Escape sequence, but many shifts. if (hits + shifts < 5) quality -= (5 - (hits + shifts)) * 10; return quality <= 0 ? null : new Match(det, this, quality); }; module.exports.ISO_2022_JP = function() { this.name = function() { return 'ISO-2022-JP'; }; this.escapeSequences = [ [ 0x1b, 0x24, 0x28, 0x43 ], // KS X 1001:1992 [ 0x1b, 0x24, 0x28, 0x44 ], // JIS X 212-1990 [ 0x1b, 0x24, 0x40 ], // JIS C 6226-1978 [ 0x1b, 0x24, 0x41 ], // GB 2312-80 [ 0x1b, 0x24, 0x42 ], // JIS X 208-1983 [ 0x1b, 0x26, 0x40 ], // JIS X 208 1990, 1997 [ 0x1b, 0x28, 0x42 ], // ASCII [ 0x1b, 0x28, 0x48 ], // JIS-Roman [ 0x1b, 0x28, 0x49 ], // Half-width katakana [ 0x1b, 0x28, 0x4a ], // JIS-Roman [ 0x1b, 0x2e, 0x41 ], // ISO 8859-1 [ 0x1b, 0x2e, 0x46 ] // ISO 8859-7 ]; }; util.inherits(module.exports.ISO_2022_JP, ISO_2022); module.exports.ISO_2022_KR = function() { this.name = function() { return 'ISO-2022-KR'; }; this.escapeSequences = [ [ 0x1b, 0x24, 0x29, 0x43 ] ]; }; util.inherits(module.exports.ISO_2022_KR, ISO_2022); module.exports.ISO_2022_CN = function() { this.name = function() { return 'ISO-2022-CN'; }; this.escapeSequences = [ [ 0x1b, 0x24, 0x29, 0x41 ], // GB 2312-80 [ 0x1b, 0x24, 0x29, 0x47 ], // CNS 11643-1992 Plane 1 [ 0x1b, 0x24, 0x2A, 0x48 ], // CNS 11643-1992 Plane 2 [ 0x1b, 0x24, 0x29, 0x45 ], // ISO-IR-165 [ 0x1b, 0x24, 0x2B, 0x49 ], // CNS 11643-1992 Plane 3 [ 0x1b, 0x24, 0x2B, 0x4A ], // CNS 11643-1992 Plane 4 [ 0x1b, 0x24, 0x2B, 0x4B ], // CNS 11643-1992 Plane 5 [ 0x1b, 0x24, 0x2B, 0x4C ], // CNS 11643-1992 Plane 6 [ 0x1b, 0x24, 0x2B, 0x4D ], // CNS 11643-1992 Plane 7 [ 0x1b, 0x4e ], // SS2 [ 0x1b, 0x4f ] // SS3 ]; }; util.inherits(module.exports.ISO_2022_CN, ISO_2022); },{"../match":33,"util":undefined}],28:[function(require,module,exports){ var util = require('util'), Match = require ('../match'); /** * Binary search implementation (recursive) */ function binarySearch(arr, searchValue) { function find(arr, searchValue, left, right) { if (right < left) return -1; /* int mid = mid = (left + right) / 2; There is a bug in the above line; Joshua Bloch suggests the following replacement: */ var mid = Math.floor((left + right) >>> 1); if (searchValue > arr[mid]) return find(arr, searchValue, mid + 1, right); if (searchValue < arr[mid]) return find(arr, searchValue, left, mid - 1); return mid; }; return find(arr, searchValue, 0, arr.length - 1); }; // 'Character' iterated character class. // Recognizers for specific mbcs encodings make their 'characters' available // by providing a nextChar() function that fills in an instance of iteratedChar // with the next char from the input. // The returned characters are not converted to Unicode, but remain as the raw // bytes (concatenated into an int) from the codepage data. // // For Asian charsets, use the raw input rather than the input that has been // stripped of markup. Detection only considers multi-byte chars, effectively // stripping markup anyway, and double byte chars do occur in markup too. // function IteratedChar() { this.charValue = 0; // 1-4 bytes from the raw input data this.index = 0; this.nextIndex = 0; this.error = false; this.done = false; this.reset = function() { this.charValue = 0; this.index = -1; this.nextIndex = 0; this.error = false; this.done = false; }; this.nextByte = function(det) { if (this.nextIndex >= det.fRawLength) { this.done = true; return -1; } var byteValue = det.fRawInput[this.nextIndex++] & 0x00ff; return byteValue; }; }; /** * Asian double or multi-byte - charsets. * Match is determined mostly by the input data adhering to the * encoding scheme for the charset, and, optionally, * frequency-of-occurence of characters. */ function mbcs() {}; /** * Test the match of this charset with the input text data * which is obtained via the CharsetDetector object. * * @param det The CharsetDetector, which contains the input text * to be checked for being in this charset. * @return Two values packed into one int (Damn java, anyhow) * bits 0-7: the match confidence, ranging from 0-100 * bits 8-15: The match reason, an enum-like value. */ mbcs.prototype.match = funct