helpers.js 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. 'use strict';
  2. /*
  3. this seems to be not only shorter, but faster than
  4. string.replace(/\\/g, '\\\\').
  5. replace(/\u0008/g, '\\b').
  6. replace(/\t/g, '\\t').
  7. replace(/\n/g, '\\n').
  8. replace(/\f/g, '\\f').
  9. replace(/\r/g, '\\r').
  10. replace(/'/g, '\\\'').
  11. replace(/"/g, '\\"');
  12. or string.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&")
  13. see http://jsperf.com/string-escape-regexp-vs-json-stringify
  14. */
  15. function srcEscape(str) {
  16. return JSON.stringify({
  17. [str]: 1,
  18. }).slice(1, -3);
  19. }
  20. exports.srcEscape = srcEscape;
  21. let highlightFn;
  22. let cardinalRecommended = false;
  23. try {
  24. // the purpose of this is to prevent projects using Webpack from displaying a warning during runtime if cardinal is not a dependency
  25. const REQUIRE_TERMINATOR = '';
  26. highlightFn = require(`cardinal${REQUIRE_TERMINATOR}`).highlight;
  27. } catch (err) {
  28. highlightFn = (text) => {
  29. if (!cardinalRecommended) {
  30. // eslint-disable-next-line no-console
  31. console.log('For nicer debug output consider install cardinal@^2.0.0');
  32. cardinalRecommended = true;
  33. }
  34. return text;
  35. };
  36. }
  37. /**
  38. * Prints debug message with code frame, will try to use `cardinal` if available.
  39. */
  40. function printDebugWithCode(msg, code) {
  41. // eslint-disable-next-line no-console
  42. console.log(`\n\n${msg}:\n`);
  43. // eslint-disable-next-line no-console
  44. console.log(`${highlightFn(code)}\n`);
  45. }
  46. exports.printDebugWithCode = printDebugWithCode;
  47. /**
  48. * checks whether the `type` is in the `list`
  49. */
  50. function typeMatch(type, list, Types) {
  51. if (Array.isArray(list)) {
  52. return list.some((t) => type === Types[t]);
  53. }
  54. return !!list;
  55. }
  56. exports.typeMatch = typeMatch;
  57. const privateObjectProps = new Set([
  58. '__defineGetter__',
  59. '__defineSetter__',
  60. '__lookupGetter__',
  61. '__lookupSetter__',
  62. '__proto__',
  63. ]);
  64. exports.privateObjectProps = privateObjectProps;
  65. const fieldEscape = (field) => {
  66. if (privateObjectProps.has(field)) {
  67. throw new Error(
  68. `The field name (${field}) can't be the same as an object's private property.`,
  69. );
  70. }
  71. return srcEscape(field);
  72. };
  73. exports.fieldEscape = fieldEscape;