helpers.js 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  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 {
  28. highlightFn = (text) => {
  29. if (!cardinalRecommended) {
  30. console.log('For nicer debug output consider install cardinal@^2.0.0');
  31. cardinalRecommended = true;
  32. }
  33. return text;
  34. };
  35. }
  36. /**
  37. * Prints debug message with code frame, will try to use `cardinal` if available.
  38. */
  39. function printDebugWithCode(msg, code) {
  40. console.log(`\n\n${msg}:\n`);
  41. console.log(`${highlightFn(code)}\n`);
  42. }
  43. exports.printDebugWithCode = printDebugWithCode;
  44. /**
  45. * checks whether the `type` is in the `list`
  46. */
  47. function typeMatch(type, list, Types) {
  48. if (Array.isArray(list)) {
  49. return list.some((t) => type === Types[t]);
  50. }
  51. return !!list;
  52. }
  53. exports.typeMatch = typeMatch;
  54. const privateObjectProps = new Set([
  55. '__defineGetter__',
  56. '__defineSetter__',
  57. '__lookupGetter__',
  58. '__lookupSetter__',
  59. '__proto__',
  60. ]);
  61. exports.privateObjectProps = privateObjectProps;
  62. const fieldEscape = (field, isEval = true) => {
  63. if (privateObjectProps.has(field)) {
  64. throw new Error(
  65. `The field name (${field}) can't be the same as an object's private property.`
  66. );
  67. }
  68. return isEval ? srcEscape(field) : field;
  69. };
  70. exports.fieldEscape = fieldEscape;