QuoteJSONString.js 1.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354
  1. 'use strict';
  2. var GetIntrinsic = require('get-intrinsic');
  3. var $TypeError = GetIntrinsic('%TypeError%');
  4. var callBound = require('call-bind/callBound');
  5. var forEach = require('../helpers/forEach');
  6. var isLeadingSurrogate = require('../helpers/isLeadingSurrogate');
  7. var isTrailingSurrogate = require('../helpers/isTrailingSurrogate');
  8. var $charCodeAt = callBound('String.prototype.charCodeAt');
  9. var StringToCodePoints = require('./StringToCodePoints');
  10. var Type = require('./Type');
  11. var UnicodeEscape = require('./UnicodeEscape');
  12. var UTF16EncodeCodePoint = require('./UTF16EncodeCodePoint');
  13. var has = require('has');
  14. // https://ecma-international.org/ecma-262/12.0/#sec-quotejsonstring
  15. var escapes = {
  16. '\u0008': '\\b',
  17. '\u0009': '\\t',
  18. '\u000A': '\\n',
  19. '\u000C': '\\f',
  20. '\u000D': '\\r',
  21. '\u0022': '\\"',
  22. '\u005c': '\\\\'
  23. };
  24. module.exports = function QuoteJSONString(value) {
  25. if (Type(value) !== 'String') {
  26. throw new $TypeError('Assertion failed: `value` must be a String');
  27. }
  28. var product = '"';
  29. if (value) {
  30. forEach(StringToCodePoints(value), function (C) {
  31. if (has(escapes, C)) {
  32. product += escapes[C];
  33. } else {
  34. var cCharCode = $charCodeAt(C, 0);
  35. if (cCharCode < 0x20 || isLeadingSurrogate(C) || isTrailingSurrogate(C)) {
  36. product += UnicodeEscape(C);
  37. } else {
  38. product += UTF16EncodeCodePoint(cCharCode);
  39. }
  40. }
  41. });
  42. }
  43. product += '"';
  44. return product;
  45. };