JsonRenderer.js 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. var chalk = require('chalk');
  2. var Q = require('q');
  3. var promptly = require('promptly');
  4. var createError = require('../util/createError');
  5. function JsonRenderer() {
  6. this._nrLogs = 0;
  7. }
  8. JsonRenderer.prototype.end = function (data) {
  9. if (this._nrLogs) {
  10. process.stderr.write(']\n');
  11. }
  12. if (data) {
  13. process.stdout.write(this._stringify(data) + '\n');
  14. }
  15. };
  16. JsonRenderer.prototype.error = function (err) {
  17. var message = err.message;
  18. var stack;
  19. err.id = err.code || 'error';
  20. err.level = 'error';
  21. err.data = err.data || {};
  22. // Need to set message again because it is
  23. // not enumerable in some cases
  24. delete err.message;
  25. err.message = message;
  26. // Stack
  27. /*jshint camelcase:false*/
  28. stack = err.fstream_stack || err.stack || 'N/A';
  29. err.stacktrace = (Array.isArray(stack) ? stack.join('\n') : stack);
  30. /*jshint camelcase:true*/
  31. this.log(err);
  32. this.end();
  33. };
  34. JsonRenderer.prototype.log = function (log) {
  35. if (!this._nrLogs) {
  36. process.stderr.write('[');
  37. } else {
  38. process.stderr.write(', ');
  39. }
  40. process.stderr.write(this._stringify(log));
  41. this._nrLogs++;
  42. };
  43. JsonRenderer.prototype.prompt = function (prompts) {
  44. var promise = Q.resolve();
  45. var answers = {};
  46. var that = this;
  47. prompts.forEach(function (prompt) {
  48. var opts;
  49. var funcName;
  50. // Strip colors
  51. prompt.message = chalk.stripColor(prompt.message);
  52. // Prompt
  53. opts = {
  54. silent: true, // To not mess with JSON output
  55. trim: false, // To allow " " to not assume the default value
  56. default: prompt.default == null ? '' : prompt.default, // If default is null, make it '' so that it does not retry
  57. validator: !prompt.validate ? null : function (value) {
  58. var ret = prompt.validate(value);
  59. if (typeof ret === 'string') {
  60. throw ret;
  61. }
  62. return value;
  63. },
  64. };
  65. // For now only "input", "confirm" and "password" are supported
  66. switch (prompt.type) {
  67. case 'input':
  68. funcName = 'prompt';
  69. break;
  70. case 'confirm':
  71. case 'password':
  72. funcName = prompt.type;
  73. break;
  74. case 'checkbox':
  75. funcName = 'prompt';
  76. break;
  77. default:
  78. promise = promise.then(function () {
  79. throw createError('Unknown prompt type', 'ENOTSUP');
  80. });
  81. return;
  82. }
  83. promise = promise.then(function () {
  84. // Log
  85. prompt.level = 'prompt';
  86. that.log(prompt);
  87. return Q.nfcall(promptly[funcName], '', opts)
  88. .then(function (answer) {
  89. answers[prompt.name] = answer;
  90. });
  91. });
  92. if (prompt.type === 'checkbox') {
  93. promise = promise.then(function () {
  94. answers[prompt.name] = answers[prompt.name].split(',');
  95. });
  96. }
  97. });
  98. return promise.then(function () {
  99. return answers;
  100. });
  101. };
  102. // -------------------------
  103. JsonRenderer.prototype._stringify = function (log) {
  104. // To json
  105. var str = JSON.stringify(log, null, ' ');
  106. // Remove colors in case some log has colors..
  107. str = chalk.stripColor(str);
  108. return str;
  109. };
  110. module.exports = JsonRenderer;