index.js 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. 'use strict';
  2. var escapeStringRegexp = require('escape-string-regexp');
  3. var ansiStyles = require('ansi-styles');
  4. var stripAnsi = require('strip-ansi');
  5. var hasAnsi = require('has-ansi');
  6. var supportsColor = require('supports-color');
  7. var defineProps = Object.defineProperties;
  8. var chalk = module.exports;
  9. function build(_styles) {
  10. var builder = function builder() {
  11. return applyStyle.apply(builder, arguments);
  12. };
  13. builder._styles = _styles;
  14. // __proto__ is used because we must return a function, but there is
  15. // no way to create a function with a different prototype.
  16. builder.__proto__ = proto;
  17. return builder;
  18. }
  19. var styles = (function () {
  20. var ret = {};
  21. ansiStyles.grey = ansiStyles.gray;
  22. Object.keys(ansiStyles).forEach(function (key) {
  23. ansiStyles[key].closeRe = new RegExp(escapeStringRegexp(ansiStyles[key].close), 'g');
  24. ret[key] = {
  25. get: function () {
  26. return build(this._styles.concat(key));
  27. }
  28. };
  29. });
  30. return ret;
  31. })();
  32. var proto = defineProps(function chalk() {}, styles);
  33. function applyStyle() {
  34. // support varags, but simply cast to string in case there's only one arg
  35. var args = arguments;
  36. var argsLen = args.length;
  37. var str = argsLen !== 0 && String(arguments[0]);
  38. if (argsLen > 1) {
  39. // don't slice `arguments`, it prevents v8 optimizations
  40. for (var a = 1; a < argsLen; a++) {
  41. str += ' ' + args[a];
  42. }
  43. }
  44. if (!chalk.enabled || !str) {
  45. return str;
  46. }
  47. /*jshint validthis: true*/
  48. var nestedStyles = this._styles;
  49. for (var i = 0; i < nestedStyles.length; i++) {
  50. var code = ansiStyles[nestedStyles[i]];
  51. // Replace any instances already present with a re-opening code
  52. // otherwise only the part of the string until said closing code
  53. // will be colored, and the rest will simply be 'plain'.
  54. str = code.open + str.replace(code.closeRe, code.open) + code.close;
  55. }
  56. return str;
  57. }
  58. function init() {
  59. var ret = {};
  60. Object.keys(styles).forEach(function (name) {
  61. ret[name] = {
  62. get: function () {
  63. return build([name]);
  64. }
  65. };
  66. });
  67. return ret;
  68. }
  69. defineProps(chalk, init());
  70. chalk.styles = ansiStyles;
  71. chalk.hasColor = hasAnsi;
  72. chalk.stripColor = stripAnsi;
  73. chalk.supportsColor = supportsColor;
  74. // detect mode if not set manually
  75. if (chalk.enabled === undefined) {
  76. chalk.enabled = chalk.supportsColor;
  77. }