You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. #!/usr/bin/env node
  2. (function() {
  3. var fs = require('fs');
  4. var he = require('../he.js');
  5. var strings = process.argv.splice(2);
  6. var stdin = process.stdin;
  7. var data;
  8. var timeout;
  9. var action;
  10. var options = {};
  11. var log = console.log;
  12. var main = function() {
  13. var option = strings[0];
  14. var count = 0;
  15. if (/^(?:-h|--help|undefined)$/.test(option)) {
  16. log(
  17. 'he v%s - https://mths.be/he',
  18. he.version
  19. );
  20. log([
  21. '\nUsage:\n',
  22. '\the [--escape] string',
  23. '\the [--encode] [--use-named-refs] [--everything] [--allow-unsafe] [--decimal] string',
  24. '\the [--decode] [--attribute] [--strict] string',
  25. '\the [-v | --version]',
  26. '\the [-h | --help]',
  27. '\nExamples:\n',
  28. '\the --escape \\<img\\ src\\=\\\'x\\\'\\ onerror\\=\\"prompt\\(1\\)\\"\\>',
  29. '\techo \'&copy; &#x1D306;\' | he --decode'
  30. ].join('\n'));
  31. return process.exit(option ? 0 : 1);
  32. }
  33. if (/^(?:-v|--version)$/.test(option)) {
  34. log('v%s', he.version);
  35. return process.exit(0);
  36. }
  37. strings.forEach(function(string) {
  38. // Process options
  39. if (string == '--escape') {
  40. action = 'escape';
  41. return;
  42. }
  43. if (string == '--encode') {
  44. action = 'encode';
  45. return;
  46. }
  47. if (string == '--use-named-refs') {
  48. action = 'encode';
  49. options.useNamedReferences = true;
  50. return;
  51. }
  52. if (string == '--everything') {
  53. action = 'encode';
  54. options.encodeEverything = true;
  55. return;
  56. }
  57. if (string == '--allow-unsafe') {
  58. action = 'encode';
  59. options.allowUnsafeSymbols = true;
  60. return;
  61. }
  62. if (string == '--decimal') {
  63. action = 'encode';
  64. options.decimal = true;
  65. return;
  66. }
  67. if (string == '--decode') {
  68. action = 'decode';
  69. return;
  70. }
  71. if (string == '--attribute') {
  72. action = 'decode';
  73. options.isAttributeValue = true;
  74. return;
  75. }
  76. if (string == '--strict') {
  77. action = 'decode';
  78. options.strict = true;
  79. return;
  80. }
  81. // Process string(s)
  82. var result;
  83. if (!action) {
  84. log('Error: he requires at least one option and a string argument.');
  85. log('Try `he --help` for more information.');
  86. return process.exit(1);
  87. }
  88. try {
  89. result = he[action](string, options);
  90. log(result);
  91. count++;
  92. } catch(error) {
  93. log(error.message + '\n');
  94. log('Error: failed to %s.', action);
  95. log('If you think this is a bug in he, please report it:');
  96. log('https://github.com/mathiasbynens/he/issues/new');
  97. log(
  98. '\nStack trace using he@%s:\n',
  99. he.version
  100. );
  101. log(error.stack);
  102. return process.exit(1);
  103. }
  104. });
  105. if (!count) {
  106. log('Error: he requires a string argument.');
  107. log('Try `he --help` for more information.');
  108. return process.exit(1);
  109. }
  110. // Return with exit status 0 outside of the `forEach` loop, in case
  111. // multiple strings were passed in.
  112. return process.exit(0);
  113. };
  114. if (stdin.isTTY) {
  115. // handle shell arguments
  116. main();
  117. } else {
  118. // Either the script is called from within a non-TTY context, or `stdin`
  119. // content is being piped in.
  120. if (!process.stdout.isTTY) {
  121. // The script was called from a non-TTY context. This is a rather uncommon
  122. // use case we don’t actively support. However, we don’t want the script
  123. // to wait forever in such cases, so…
  124. timeout = setTimeout(function() {
  125. // …if no piped data arrived after a whole minute, handle shell
  126. // arguments instead.
  127. main();
  128. }, 60000);
  129. }
  130. data = '';
  131. stdin.on('data', function(chunk) {
  132. clearTimeout(timeout);
  133. data += chunk;
  134. });
  135. stdin.on('end', function() {
  136. strings.push(data.trim());
  137. main();
  138. });
  139. stdin.resume();
  140. }
  141. }());