config.js 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. var rc = require('rc'),
  2. util = require('util');
  3. var conversions = {
  4. checkIfNull: function(value) {
  5. return value && value !== 'null' ? value : null;
  6. },
  7. keyToCamelKey: function(value) {
  8. return value.replace(/-(.)/g, function(_, lower) {
  9. return lower.toUpperCase();
  10. });
  11. },
  12. rcToInnerConfig: function(rcConfig) {
  13. var options = {};
  14. Object.keys(rcConfig).forEach(function(key) {
  15. var camelKey = conversions.keyToCamelKey(key),
  16. fixedVal = rcConfig[key],
  17. predefined;
  18. predefined = !!definitions[key];
  19. if (predefined) {
  20. try {
  21. fixedVal = definitions[key].convert(fixedVal);
  22. }
  23. catch (e) {
  24. console.warn('Cannot convert config option %s: %s.', key, e.message || e);
  25. }
  26. }
  27. options[camelKey] = fixedVal;
  28. });
  29. return options;
  30. },
  31. stringToArray: function(value) {
  32. var hidden;
  33. if (typeof value === 'string') {
  34. try {
  35. value = JSON.parse(value);
  36. } catch (e) {
  37. throw new Error('The value is not a valid JSON. ' + (e.message || e));
  38. }
  39. }
  40. if (util.isArray(value)) {
  41. hidden = value.map(function(s) { return new RegExp(s, 'i'); });
  42. } else {
  43. var msg = 'The value ' + JSON.stringify(value) + ' is not an array.';
  44. throw new Error(msg);
  45. }
  46. return hidden;
  47. },
  48. stringToBoolean: function(value) {
  49. return !!value;
  50. },
  51. stringToInt: function(value) {
  52. return parseInt(value, 10);
  53. }
  54. };
  55. var definitions = {
  56. 'help': {
  57. desc: 'Show this help',
  58. convert: conversions.stringToBoolean,
  59. defaultValue: false
  60. },
  61. 'version': {
  62. desc: 'Print Node Inspector\'s version',
  63. convert: conversions.stringToBoolean,
  64. defaultValue: false
  65. },
  66. 'web-port': {
  67. desc: 'Port to host the inspector',
  68. convert: conversions.stringToInt,
  69. defaultValue: 8080
  70. },
  71. 'web-host': {
  72. desc: 'Host to listen on',
  73. convert: conversions.checkIfNull,
  74. defaultValue: ''
  75. },
  76. 'debug-port': {
  77. desc: 'Port to connect to the debugging app',
  78. convert: conversions.stringToInt,
  79. defaultValue: 5858
  80. },
  81. 'save-live-edit': {
  82. desc: 'Save live edit changes to disk (update the edited files)',
  83. convert: conversions.stringToBoolean,
  84. defaultValue: false
  85. },
  86. 'preload': {
  87. desc: 'Preload *.js files. You can disable this option to speed up the startup.\n' +
  88. ' (command-line parameter: \u001b[92m--no-preload\u001b[0m)',
  89. convert: conversions.stringToBoolean,
  90. defaultValue: true
  91. },
  92. 'hidden': {
  93. desc: 'Array of files to hide from the UI (breakpoints in these files' +
  94. ' will be ignored)',
  95. convert: conversions.stringToArray,
  96. defaultValue: []
  97. },
  98. 'stack-trace-limit': {
  99. desc: 'Number of stack frames to show on a breakpoint',
  100. convert: conversions.stringToInt,
  101. defaultValue: 50
  102. }
  103. };
  104. var defaults = collectDefaultsFromDefinitions();
  105. var rcConfig = rc('node-inspector', defaults);
  106. var config = conversions.rcToInnerConfig(rcConfig);
  107. if (config.noPreload !== undefined) {
  108. // Deprecated in v0.7.3
  109. console.warn('The config option `no-preload` is deprecated, use `preload` instead');
  110. config.preload = config.preload || !config.noPreload;
  111. }
  112. module.exports = config;
  113. module.exports._collectDefaults = function() {
  114. var dashedKeyDefaults = collectDefaultsFromDefinitions();
  115. return conversions.rcToInnerConfig(dashedKeyDefaults);
  116. };
  117. module.exports._describeOptions = function() {
  118. return Object.keys(definitions)
  119. .map(function constructMessagePart(key) {
  120. var definition = definitions[key];
  121. var defaultValue = definition.defaultValue;
  122. var defaultString = JSON.stringify(definition.defaultValue);
  123. var typeString = Object.prototype.toString.call(defaultValue);
  124. var matchedType = /^\[object (.*)\]$/.exec(typeString)[1];
  125. var optionKey = '\u001b[92m--' + key;
  126. var optionTypeAndDefault =
  127. matchedType !== 'Undefined' && matchedType !== 'Boolean' ?
  128. '=\u001b[90m{' + matchedType + '}' +
  129. ' \u001b[96m(default: ' + defaultString + ')' :
  130. '';
  131. var optionDescription = '\u001b[0m' + definition.desc;
  132. return ' ' + optionKey + optionTypeAndDefault +
  133. '\n ' + optionDescription;
  134. })
  135. .join('\n\n');
  136. };
  137. function collectDefaultsFromDefinitions() {
  138. var options = {};
  139. Object.keys(definitions).forEach(function(key) {
  140. options[key] = definitions[key].defaultValue;
  141. });
  142. return options;
  143. }