move JSON.parse source text access to stable ES

This commit is contained in:
Denis Pushkarev
2025-11-18 11:48:14 +02:00
parent 9a079d3ec2
commit 646f3abced
36 changed files with 575 additions and 509 deletions
+9
View File
@@ -1,5 +1,14 @@
# Changelog
### Unreleased
- [`JSON.parse` source text access proposal](https://github.com/tc39/proposal-json-parse-with-source) :
- Built-ins:
- `JSON.isRawJSON`
- `JSON.parse`
- `JSON.rawJSON`
- `JSON.stringify`
- Moved to stable ES, November 2025 TC39 meeting
- Added `es.` namespace modules, `/es/` and `/stable/` namespaces entries
- Reworked `JSON.stringify` internals
- [`Iterator` sequencing proposal](https://github.com/tc39/proposal-iterator-sequencing):
- Built-ins:
- `Iterator.concat`
+45 -44
View File
@@ -164,6 +164,7 @@ structuredClone(new Set([1, 2, 3])); // => new Set([1, 2, 3])
- [`Promise.withResolvers`](#promisewithresolvers)
- [`Symbol.asyncIterator` for asynchronous iteration](#symbolasynciterator-for-asynchronous-iteration)
- [`Symbol.prototype.description`](#symbolprototypedescription)
- [`JSON.parse` source text access](#jsonparse-source-text-access)
- [Well-formed `JSON.stringify`](#well-formed-jsonstringify)
- [Well-formed unicode strings](#well-formed-unicode-strings)
- [New `Set` methods](#new-set-methods)
@@ -171,7 +172,6 @@ structuredClone(new Set([1, 2, 3])); // => new Set([1, 2, 3])
- [Stage 3 proposals](#stage-3-proposals)
- [Joint iteration](#joint-iteration)
- [`Map` upsert](#map-upsert)
- [`JSON.parse` source text access](#jsonparse-source-text-access)
- [`Symbol.metadata` for decorators metadata proposal](#symbolmetadata-for-decorators-metadata-proposal)
- [Stage 2.7 proposals](#stage-27-proposals)
- [`Iterator` chunking](#iterator-chunking)
@@ -2139,23 +2139,47 @@ instance.c; // => 42
```
#### ECMAScript: JSON[⬆](#index)
Since `JSON` object is missed only in very old engines like IE7-, `core-js` does not provide a full `JSON` polyfill, however, fix already existing implementations by the current standard, for example, [well-formed `JSON.stringify`](https://github.com/tc39/proposal-well-formed-stringify). `JSON` is also fixed in other modules - for example, `Symbol` polyfill fixes `JSON.stringify` for correct work with symbols.
Since `JSON` object is missed only in very old engines like IE7-, `core-js` does not provide a full `JSON.{ parse, stringify }` polyfill, however, fix already existing implementations by the current standard.
Module [`es.json.to-string-tag`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.json.to-string-tag.js) and [`es.json.stringify`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.json.stringify.js).
Modules [`es.json.is-raw-json`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.json.is-raw-json.js), [`es.json.parse`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.json.parse.js), [`es.json.raw-json`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.json.raw-json.js), [`es.json.stringify`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.json.stringify.js) and [`es.json.to-string-tag`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.json.to-string-tag.js) .
```ts
namespace JSON {
isRawJSON(O: any): boolean;
parse(text: string, reviver?: (this: any, key: string, value: any, context: { source?: string }) => any): any;
rawJSON(text: any): RawJSON;
stringify(value: any, replacer?: Array<string | number> | (this: any, key: string, value: any) => any, space?: string | number): string | void;
@@toStringTag: 'JSON';
}
```
[*CommonJS entry points:*](#commonjs-api)
```
core-js(-pure)/es|stable|actual|full/json/is-raw-json
core-js(-pure)/es|stable|actual|full/json/parse
core-js(-pure)/es|stable|actual|full/json/raw-json
core-js(-pure)/es|stable|actual|full/json/stringify
core-js(-pure)/es|stable|actual|full/json/stringify
core-js(-pure)/es|stable|actual|full/json/to-string-tag
```
[*Examples*](https://is.gd/izZqKn):
[*Examples*](https://tinyurl.com/34ctm7cn):
```js
JSON.stringify({ '𠮷': ['\uDF06\uD834'] }); // => '{"𠮷":["\\udf06\\ud834"]}'
function digitsToBigInt(key, val, { source }) {
return /^\d+$/.test(source) ? BigInt(source) : val;
}
function bigIntToRawJSON(key, val) {
return typeof val === 'bigint' ? JSON.rawJSON(String(val)) : val;
}
const tooBigForNumber = BigInt(Number.MAX_SAFE_INTEGER) + 2n;
JSON.parse(String(tooBigForNumber), digitsToBigInt) === tooBigForNumber; // true
const wayTooBig = BigInt(`1${ '0'.repeat(1000) }`);
JSON.parse(String(wayTooBig), digitsToBigInt) === wayTooBig; // true
const embedded = JSON.stringify({ tooBigForNumber }, bigIntToRawJSON);
embedded === '{"tooBigForNumber":9007199254740993}'; // true
```
#### ECMAScript: globalThis[⬆](#index)
@@ -2649,6 +2673,23 @@ class Symbol {
```
core-js/proposals/symbol-description
```
##### [`JSON.parse` source text access](https://github.com/tc39/proposal-json-parse-with-source)[⬆](#index)
```ts
namespace JSON {
isRawJSON(O: any): boolean;
// patched for source support
parse(text: string, reviver?: (this: any, key: string, value: any, context: { source?: string }) => any): any;
rawJSON(text: any): RawJSON;
// patched for `JSON.rawJSON` support
stringify(value: any, replacer?: Array<string | number> | (this: any, key: string, value: any) => any, space?: string | number): string | void;
}
```
[*CommonJS entry points:*](#commonjs-api)
```
core-js/proposals/json-parse-with-source
```
##### [Well-formed `JSON.stringify`](https://github.com/tc39/proposal-well-formed-stringify)[⬆](#index)
```ts
namespace JSON {
@@ -2792,46 +2833,6 @@ map.getOrInsertComputed('c', key => key); // => 'c'
console.log(map); // => Map { 'a': 1, 'b': 3, 'c': 'c' }
```
##### [`JSON.parse` source text access](https://github.com/tc39/proposal-json-parse-with-source)[⬆](#index)
Modules [`esnext.json.is-raw-json`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.json.is-raw-json.js), [`esnext.json.parse`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.json.parse.js), [`esnext.json.raw-json`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.json.raw-json.js).
```ts
namespace JSON {
isRawJSON(O: any): boolean;
// patched for source support
parse(text: string, reviver?: (this: any, key: string, value: any, context: { source?: string }) => any): any;
rawJSON(text: any): RawJSON;
// patched for `JSON.rawJSON` support
stringify(value: any, replacer?: Array<string | number> | (this: any, key: string, value: any) => any, space?: string | number): string | void;
}
```
[*CommonJS entry points:*](#commonjs-api)
```
core-js/proposals/json-parse-with-source
core-js(-pure)/actual|full/json/is-raw-json
core-js(-pure)/actual|full/json/parse
core-js(-pure)/actual|full/json/raw-json
core-js(-pure)/actual|full/json/stringify
```
[*Examples*](https://tinyurl.com/22phm569):
```js
function digitsToBigInt(key, val, { source }) {
return /^\d+$/.test(source) ? BigInt(source) : val;
}
function bigIntToRawJSON(key, val) {
return typeof val === 'bigint' ? JSON.rawJSON(String(val)) : val;
}
const tooBigForNumber = BigInt(Number.MAX_SAFE_INTEGER) + 2n;
JSON.parse(String(tooBigForNumber), digitsToBigInt) === tooBigForNumber; // true
const wayTooBig = BigInt(`1${ '0'.repeat(1000) }`);
JSON.parse(String(wayTooBig), digitsToBigInt) === wayTooBig; // true
const embedded = JSON.stringify({ tooBigForNumber }, bigIntToRawJSON);
embedded === '{"tooBigForNumber":9007199254740993}'; // true
```
##### [`Symbol.metadata` for decorators metadata proposal](https://github.com/tc39/proposal-decorator-metadata)[⬆](#index)
Modules [`esnext.symbol.metadata`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.symbol.metadata.js) and [`esnext.function.metadata`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.function.metadata.js).
```ts
+24 -3
View File
@@ -1,12 +1,15 @@
# ECMAScript: JSON
Since `JSON` object is missed only in very old engines like IE7-, `core-js` does not provide a full `JSON` polyfill, however, fix already existing implementations by the current standard, for example, [well-formed `JSON.stringify`](https://github.com/tc39/proposal-well-formed-stringify). `JSON` is also fixed in other modules - for example, `Symbol` polyfill fixes `JSON.stringify` for correct work with symbols.
Since `JSON` object is missed only in very old engines like IE7-, `core-js` does not provide a full `JSON.{ parse, stringify }` polyfill, however, fix already existing implementations by the current standard.
## Modules
[`es.json.to-string-tag`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.json.to-string-tag.js) and [`es.json.stringify`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.json.stringify.js).
[`es.json.is-raw-json`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.json.is-raw-json.js), [`es.json.parse`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.json.parse.js), [`es.json.raw-json`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.json.raw-json.js), [`es.json.stringify`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.json.stringify.js) and [`es.json.to-string-tag`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.json.to-string-tag.js).
## Built-ins signatures
```ts
namespace JSON {
isRawJSON(O: any): boolean;
parse(text: string, reviver?: (this: any, key: string, value: any, context: { source?: string }) => any): any;
rawJSON(text: any): RawJSON;
stringify(value: any, replacer?: Array<string | number> | (this: any, key: string, value: any) => any, space?: string | number): string | void;
@@toStringTag: 'JSON';
}
@@ -14,11 +17,29 @@ namespace JSON {
## [Entry points]({docs-version}/docs/usage#h-entry-points)
```
core-js(-pure)/es|stable|actual|full/json/stringify
core-js(-pure)/es|stable|actual|full/json/is-raw-json
core-js(-pure)/es|stable|actual|full/json/parse
core-js(-pure)/es|stable|actual|full/json/raw-json
core-js(-pure)/es|stable|actual|full/json/to-string-tag
```
## Examples
```js
function digitsToBigInt(key, val, { source }) {
return /^\d+$/.test(source) ? BigInt(source) : val;
}
function bigIntToRawJSON(key, val) {
return typeof val === 'bigint' ? JSON.rawJSON(String(val)) : val;
}
const tooBigForNumber = BigInt(Number.MAX_SAFE_INTEGER) + 2n;
JSON.parse(String(tooBigForNumber), digitsToBigInt) === tooBigForNumber; // => true
const wayTooBig = BigInt(`1${ '0'.repeat(1000) }`);
JSON.parse(String(wayTooBig), digitsToBigInt) === wayTooBig; // => true
JSON.stringify({ tooBigForNumber }, bigIntToRawJSON); // => '{"tooBigForNumber":9007199254740993}'
JSON.stringify({ '𠮷': ['\uDF06\uD834'] }); // => '{"𠮷":["\\udf06\\ud834"]}'
```
@@ -3,7 +3,7 @@
[Proposal repo](https://github.com/tc39/proposal-json-parse-with-source)
## Modules
[`esnext.json.is-raw-json`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.json.is-raw-json.js), [`esnext.json.parse`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.json.parse.js), [`esnext.json.raw-json`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.json.raw-json.js).
[`es.json.is-raw-json`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.json.is-raw-json.js), [`es.json.parse`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.json.parse.js), [`es.json.raw-json`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.json.raw-json.js).
## Built-ins signatures
```ts
@@ -20,10 +20,10 @@ namespace JSON {
## [Entry points]({docs-version}/docs/usage#h-entry-points)
```ts
core-js/proposals/json-parse-with-source
core-js(-pure)/actual|full/json/is-raw-json
core-js(-pure)/actual|full/json/parse
core-js(-pure)/actual|full/json/raw-json
core-js(-pure)/actual|full/json/stringify
core-js(-pure)/es|stable|actual|full/json/is-raw-json
core-js(-pure)/es|stable|actual|full/json/parse
core-js(-pure)/es|stable|actual|full/json/raw-json
core-js(-pure)/es|stable|actual|full/json/stringify
```
## Examples
+4 -4
View File
@@ -221,6 +221,10 @@
"title": "Symbol.prototype.description",
"url": "{docs-version}/docs/features/proposals/symbol-prototype-description"
},
{
"title": "JSON.parse source text access",
"url": "{docs-version}/docs/features/proposals/json-parse-source-text-access"
},
{
"title": "Well-formed JSON.stringify",
"url": "{docs-version}/docs/features/proposals/well-formed-jsonstringify"
@@ -250,10 +254,6 @@
"title": "Map upsert",
"url": "{docs-version}/docs/features/proposals/map-upsert"
},
{
"title": "JSON.parse source text access",
"url": "{docs-version}/docs/features/proposals/json-parse-source-text-access"
},
{
"title": "Symbol.metadata for decorators metadata proposal",
"url": "{docs-version}/docs/features/proposals/symbol-metadata"
+37 -27
View File
@@ -806,13 +806,35 @@ export const data = {
firefox: '131',
safari: '18.4',
},
'es.json.is-raw-json': {
bun: '1.1.43',
chrome: '114',
// enabled in 132 and disabled in 133 because of regression, https://bugzilla.mozilla.org/show_bug.cgi?id=1925334
firefox: '135', // '132',
safari: '18.4',
},
'es.json.parse': {
bun: '1.1.43',
chrome: '114',
// enabled in 132 and disabled in 133 because of regression, https://bugzilla.mozilla.org/show_bug.cgi?id=1925334
firefox: '135', // '132',
safari: '18.4',
},
'es.json.raw-json': {
bun: '1.1.43',
chrome: '114',
// enabled in 132 and disabled in 133 because of regression, https://bugzilla.mozilla.org/show_bug.cgi?id=1925334
firefox: '135', // '132',
safari: '18.4',
},
'es.json.stringify': {
chrome: '72',
firefox: '64',
hermes: '0.13',
'react-native': '0.72',
rhino: '1.8.0',
safari: '12.1',
bun: '1.1.43',
chrome: '114', // '72',
firefox: '135', // '132', '64',
// hermes: '0.13',
// 'react-native': '0.72',
// rhino: '1.8.0',
safari: '18.4', // '12.1',
},
'es.json.to-string-tag': {
chrome: '50',
@@ -2551,27 +2573,12 @@ export const data = {
},
'esnext.iterator.zip-keyed': {
},
'esnext.json.is-raw-json': {
bun: '1.1.43',
chrome: '114',
// enabled in 132 and disabled in 133 because of regression, https://bugzilla.mozilla.org/show_bug.cgi?id=1925334
firefox: '135', // '132',
safari: '18.4',
},
'esnext.json.parse': {
bun: '1.1.43',
chrome: '114',
// enabled in 132 and disabled in 133 because of regression, https://bugzilla.mozilla.org/show_bug.cgi?id=1925334
firefox: '135', // '132',
safari: '18.4',
},
'esnext.json.raw-json': {
bun: '1.1.43',
chrome: '114',
// enabled in 132 and disabled in 133 because of regression, https://bugzilla.mozilla.org/show_bug.cgi?id=1925334
firefox: '135', // '132',
safari: '18.4',
},
// TODO: Remove from `core-js@4`
'esnext.json.is-raw-json': null,
// TODO: Remove from `core-js@4`
'esnext.json.parse': null,
// TODO: Remove from `core-js@4`
'esnext.json.raw-json': null,
'esnext.map.delete-all': {
},
// TODO: Remove from `core-js@4`
@@ -3183,6 +3190,9 @@ export const renamed = new Map([
['esnext.iterator.some', 'es.iterator.some'],
['esnext.iterator.take', 'es.iterator.take'],
['esnext.iterator.to-array', 'es.iterator.to-array'],
['esnext.json.is-raw-json', 'es.json.is-raw-json'],
['esnext.json.parse', 'es.json.parse'],
['esnext.json.raw-json', 'es.json.raw-json'],
['esnext.map.group-by', 'es.map.group-by'],
['esnext.math.f16round', 'es.math.f16round'],
['esnext.math.sum-precise', 'es.math.sum-precise'],
@@ -313,5 +313,8 @@ export default {
],
3.47: [
'es.iterator.concat',
'es.json.is-raw-json',
'es.json.parse',
'es.json.raw-json',
],
};
-3
View File
@@ -1,8 +1,5 @@
'use strict';
var parent = require('../../stable/json');
require('../../modules/es.object.create');
require('../../modules/es.object.freeze');
require('../../modules/es.object.keys');
require('../../modules/esnext.json.is-raw-json');
require('../../modules/esnext.json.parse');
require('../../modules/esnext.json.raw-json');
+2 -2
View File
@@ -1,5 +1,5 @@
'use strict';
var parent = require('../../stable/json/is-raw-json');
require('../../modules/esnext.json.is-raw-json');
var path = require('../../internals/path');
module.exports = path.JSON.isRawJSON;
module.exports = parent;
+2 -3
View File
@@ -1,6 +1,5 @@
'use strict';
require('../../modules/es.object.keys');
var parent = require('../../stable/json/parse');
require('../../modules/esnext.json.parse');
var path = require('../../internals/path');
module.exports = path.JSON.parse;
module.exports = parent;
+3 -4
View File
@@ -1,7 +1,6 @@
'use strict';
require('../../modules/es.object.create');
require('../../modules/es.object.freeze');
var parent = require('../../stable/json/raw-json');
require('../../modules/es.json.stringify');
require('../../modules/esnext.json.raw-json');
var path = require('../../internals/path');
module.exports = path.JSON.rawJSON;
module.exports = parent;
+6
View File
@@ -1,5 +1,11 @@
'use strict';
require('../../modules/es.object.create');
require('../../modules/es.object.freeze');
require('../../modules/es.object.keys');
require('../../modules/es.date.to-json');
require('../../modules/es.json.is-raw-json');
require('../../modules/es.json.parse');
require('../../modules/es.json.raw-json');
require('../../modules/es.json.stringify');
require('../../modules/es.json.to-string-tag');
var path = require('../../internals/path');
+5
View File
@@ -0,0 +1,5 @@
'use strict';
require('../../modules/es.json.is-raw-json');
var path = require('../../internals/path');
module.exports = path.JSON.isRawJSON;
+6
View File
@@ -0,0 +1,6 @@
'use strict';
require('../../modules/es.object.keys');
require('../../modules/es.json.parse');
var path = require('../../internals/path');
module.exports = path.JSON.parse;
+7
View File
@@ -0,0 +1,7 @@
'use strict';
require('../../modules/es.object.create');
require('../../modules/es.object.freeze');
require('../../modules/es.json.raw-json');
var path = require('../../internals/path');
module.exports = path.JSON.rawJSON;
@@ -1,30 +0,0 @@
'use strict';
var uncurryThis = require('../internals/function-uncurry-this');
var isArray = require('../internals/is-array');
var isCallable = require('../internals/is-callable');
var classof = require('../internals/classof-raw');
var toString = require('../internals/to-string');
var push = uncurryThis([].push);
module.exports = function (replacer) {
if (isCallable(replacer)) return replacer;
if (!isArray(replacer)) return;
var rawLength = replacer.length;
var keys = [];
for (var i = 0; i < rawLength; i++) {
var element = replacer[i];
if (typeof element == 'string') push(keys, element);
else if (typeof element == 'number' || classof(element) === 'Number' || classof(element) === 'String') push(keys, toString(element));
}
var keysLength = keys.length;
var root = true;
return function (key, value) {
if (root) {
root = false;
return value;
}
if (isArray(this)) return value;
for (var j = 0; j < keysLength; j++) if (keys[j] === key) return value;
};
};
@@ -0,0 +1,11 @@
'use strict';
var $ = require('../internals/export');
var NATIVE_RAW_JSON = require('../internals/native-raw-json');
var isRawJSON = require('../internals/is-raw-json');
// `JSON.isRawJSON` method
// https://tc39.es/proposal-json-parse-with-source/#sec-json.israwjson
// https://github.com/tc39/proposal-json-parse-with-source
$({ target: 'JSON', stat: true, forced: !NATIVE_RAW_JSON }, {
isRawJSON: isRawJSON
});
+251
View File
@@ -0,0 +1,251 @@
'use strict';
var $ = require('../internals/export');
var DESCRIPTORS = require('../internals/descriptors');
var globalThis = require('../internals/global-this');
var getBuiltIn = require('../internals/get-built-in');
var uncurryThis = require('../internals/function-uncurry-this');
var call = require('../internals/function-call');
var isCallable = require('../internals/is-callable');
var isObject = require('../internals/is-object');
var isArray = require('../internals/is-array');
var hasOwn = require('../internals/has-own-property');
var toString = require('../internals/to-string');
var lengthOfArrayLike = require('../internals/length-of-array-like');
var createProperty = require('../internals/create-property');
var fails = require('../internals/fails');
var parseJSONString = require('../internals/parse-json-string');
var NATIVE_SYMBOL = require('../internals/symbol-constructor-detection');
var JSON = globalThis.JSON;
var Number = globalThis.Number;
var SyntaxError = globalThis.SyntaxError;
var nativeParse = JSON && JSON.parse;
var enumerableOwnProperties = getBuiltIn('Object', 'keys');
// eslint-disable-next-line es/no-object-getownpropertydescriptor -- safe
var getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;
var at = uncurryThis(''.charAt);
var slice = uncurryThis(''.slice);
var exec = uncurryThis(/./.exec);
var push = uncurryThis([].push);
var IS_DIGIT = /^\d$/;
var IS_NON_ZERO_DIGIT = /^[1-9]$/;
var IS_NUMBER_START = /^[\d-]$/;
var IS_WHITESPACE = /^[\t\n\r ]$/;
var PRIMITIVE = 0;
var OBJECT = 1;
var $parse = function (source, reviver) {
source = toString(source);
var context = new Context(source, 0, '');
var root = context.parse();
var value = root.value;
var endIndex = context.skip(IS_WHITESPACE, root.end);
if (endIndex < source.length) {
throw new SyntaxError('Unexpected extra character: "' + at(source, endIndex) + '" after the parsed data at: ' + endIndex);
}
return isCallable(reviver) ? internalize({ '': value }, '', reviver, root) : value;
};
var internalize = function (holder, name, reviver, node) {
var val = holder[name];
var unmodified = node && val === node.value;
var context = unmodified && typeof node.source == 'string' ? { source: node.source } : {};
var elementRecordsLen, keys, len, i, P;
if (isObject(val)) {
var nodeIsArray = isArray(val);
var nodes = unmodified ? node.nodes : nodeIsArray ? [] : {};
if (nodeIsArray) {
elementRecordsLen = nodes.length;
len = lengthOfArrayLike(val);
for (i = 0; i < len; i++) {
internalizeProperty(val, i, internalize(val, '' + i, reviver, i < elementRecordsLen ? nodes[i] : undefined));
}
} else {
keys = enumerableOwnProperties(val);
len = lengthOfArrayLike(keys);
for (i = 0; i < len; i++) {
P = keys[i];
internalizeProperty(val, P, internalize(val, P, reviver, hasOwn(nodes, P) ? nodes[P] : undefined));
}
}
}
return call(reviver, holder, name, val, context);
};
var internalizeProperty = function (object, key, value) {
if (DESCRIPTORS) {
var descriptor = getOwnPropertyDescriptor(object, key);
if (descriptor && !descriptor.configurable) return;
}
if (value === undefined) delete object[key];
else createProperty(object, key, value);
};
var Node = function (value, end, source, nodes) {
this.value = value;
this.end = end;
this.source = source;
this.nodes = nodes;
};
var Context = function (source, index) {
this.source = source;
this.index = index;
};
// https://www.json.org/json-en.html
Context.prototype = {
fork: function (nextIndex) {
return new Context(this.source, nextIndex);
},
parse: function () {
var source = this.source;
var i = this.skip(IS_WHITESPACE, this.index);
var fork = this.fork(i);
var chr = at(source, i);
if (exec(IS_NUMBER_START, chr)) return fork.number();
switch (chr) {
case '{':
return fork.object();
case '[':
return fork.array();
case '"':
return fork.string();
case 't':
return fork.keyword(true);
case 'f':
return fork.keyword(false);
case 'n':
return fork.keyword(null);
} throw new SyntaxError('Unexpected character: "' + chr + '" at: ' + i);
},
node: function (type, value, start, end, nodes) {
return new Node(value, end, type ? null : slice(this.source, start, end), nodes);
},
object: function () {
var source = this.source;
var i = this.index + 1;
var expectKeypair = false;
var object = {};
var nodes = {};
while (i < source.length) {
i = this.until(['"', '}'], i);
if (at(source, i) === '}' && !expectKeypair) {
i++;
break;
}
// Parsing the key
var result = this.fork(i).string();
var key = result.value;
i = result.end;
i = this.until([':'], i) + 1;
// Parsing value
i = this.skip(IS_WHITESPACE, i);
result = this.fork(i).parse();
createProperty(nodes, key, result);
createProperty(object, key, result.value);
i = this.until([',', '}'], result.end);
var chr = at(source, i);
if (chr === ',') {
expectKeypair = true;
i++;
} else if (chr === '}') {
i++;
break;
}
}
return this.node(OBJECT, object, this.index, i, nodes);
},
array: function () {
var source = this.source;
var i = this.index + 1;
var expectElement = false;
var array = [];
var nodes = [];
while (i < source.length) {
i = this.skip(IS_WHITESPACE, i);
if (at(source, i) === ']' && !expectElement) {
i++;
break;
}
var result = this.fork(i).parse();
push(nodes, result);
push(array, result.value);
i = this.until([',', ']'], result.end);
if (at(source, i) === ',') {
expectElement = true;
i++;
} else if (at(source, i) === ']') {
i++;
break;
}
}
return this.node(OBJECT, array, this.index, i, nodes);
},
string: function () {
var index = this.index;
var parsed = parseJSONString(this.source, this.index + 1);
return this.node(PRIMITIVE, parsed.value, index, parsed.end);
},
number: function () {
var source = this.source;
var startIndex = this.index;
var i = startIndex;
if (at(source, i) === '-') i++;
if (at(source, i) === '0') i++;
else if (exec(IS_NON_ZERO_DIGIT, at(source, i))) i = this.skip(IS_DIGIT, i + 1);
else throw new SyntaxError('Failed to parse number at: ' + i);
if (at(source, i) === '.') i = this.skip(IS_DIGIT, i + 1);
if (at(source, i) === 'e' || at(source, i) === 'E') {
i++;
if (at(source, i) === '+' || at(source, i) === '-') i++;
var exponentStartIndex = i;
i = this.skip(IS_DIGIT, i);
if (exponentStartIndex === i) throw new SyntaxError("Failed to parse number's exponent value at: " + i);
}
return this.node(PRIMITIVE, Number(slice(source, startIndex, i)), startIndex, i);
},
keyword: function (value) {
var keyword = '' + value;
var index = this.index;
var endIndex = index + keyword.length;
if (slice(this.source, index, endIndex) !== keyword) throw new SyntaxError('Failed to parse value at: ' + index);
return this.node(PRIMITIVE, value, index, endIndex);
},
skip: function (regex, i) {
var source = this.source;
for (; i < source.length; i++) if (!exec(regex, at(source, i))) break;
return i;
},
until: function (array, i) {
i = this.skip(IS_WHITESPACE, i);
var chr = at(this.source, i);
for (var j = 0; j < array.length; j++) if (array[j] === chr) return i;
throw new SyntaxError('Unexpected character: "' + chr + '" at: ' + i);
}
};
var NO_SOURCE_SUPPORT = fails(function () {
var unsafeInt = '9007199254740993';
var source;
nativeParse(unsafeInt, function (key, value, context) {
source = context.source;
});
return source !== unsafeInt;
});
var PROPER_BASE_PARSE = NATIVE_SYMBOL && !fails(function () {
// Safari 9 bug
return 1 / nativeParse('-0 \t') !== -Infinity;
});
// `JSON.parse` method
// https://tc39.es/ecma262/#sec-json.parse
// https://github.com/tc39/proposal-json-parse-with-source
$({ target: 'JSON', stat: true, forced: NO_SOURCE_SUPPORT }, {
parse: function parse(text, reviver) {
return PROPER_BASE_PARSE && !isCallable(reviver) ? nativeParse(text) : $parse(text, reviver);
}
});
@@ -0,0 +1,39 @@
'use strict';
var $ = require('../internals/export');
var FREEZING = require('../internals/freezing');
var NATIVE_RAW_JSON = require('../internals/native-raw-json');
var getBuiltIn = require('../internals/get-built-in');
var uncurryThis = require('../internals/function-uncurry-this');
var toString = require('../internals/to-string');
var createProperty = require('../internals/create-property');
var setInternalState = require('../internals/internal-state').set;
var $SyntaxError = SyntaxError;
var parse = getBuiltIn('JSON', 'parse');
var create = getBuiltIn('Object', 'create');
var freeze = getBuiltIn('Object', 'freeze');
var at = uncurryThis(''.charAt);
var ERROR_MESSAGE = 'Unacceptable as raw JSON';
var isWhitespace = function (it) {
return it === ' ' || it === '\t' || it === '\n' || it === '\r';
};
// `JSON.rawJSON` method
// https://tc39.es/proposal-json-parse-with-source/#sec-json.rawjson
// https://github.com/tc39/proposal-json-parse-with-source
$({ target: 'JSON', stat: true, forced: !NATIVE_RAW_JSON }, {
rawJSON: function rawJSON(text) {
var jsonString = toString(text);
if (jsonString === '' || isWhitespace(at(jsonString, 0)) || isWhitespace(at(jsonString, jsonString.length - 1))) {
throw new $SyntaxError(ERROR_MESSAGE);
}
var parsed = parse(jsonString);
if (typeof parsed == 'object' && parsed !== null) throw new $SyntaxError(ERROR_MESSAGE);
var obj = create(null);
setInternalState(obj, { type: 'RawJSON' });
createProperty(obj, 'rawJSON', jsonString);
return FREEZING ? freeze(obj) : obj;
}
});
+78 -19
View File
@@ -5,11 +5,17 @@ var apply = require('../internals/function-apply');
var call = require('../internals/function-call');
var uncurryThis = require('../internals/function-uncurry-this');
var fails = require('../internals/fails');
var isArray = require('../internals/is-array');
var isCallable = require('../internals/is-callable');
var isRawJSON = require('../internals/is-raw-json');
var isSymbol = require('../internals/is-symbol');
var classof = require('../internals/classof-raw');
var toString = require('../internals/to-string');
var arraySlice = require('../internals/array-slice');
var getReplacerFunction = require('../internals/get-json-replacer-function');
var parseJSONString = require('../internals/parse-json-string');
var uid = require('../internals/uid');
var NATIVE_SYMBOL = require('../internals/symbol-constructor-detection');
var NATIVE_RAW_JSON = require('../internals/native-raw-json');
var $String = String;
var $stringify = getBuiltIn('JSON', 'stringify');
@@ -17,11 +23,16 @@ var exec = uncurryThis(/./.exec);
var charAt = uncurryThis(''.charAt);
var charCodeAt = uncurryThis(''.charCodeAt);
var replace = uncurryThis(''.replace);
var slice = uncurryThis(''.slice);
var push = uncurryThis([].push);
var numberToString = uncurryThis(1.1.toString);
var tester = /[\uD800-\uDFFF]/g;
var low = /^[\uD800-\uDBFF]$/;
var hi = /^[\uDC00-\uDFFF]$/;
var surrogates = /[\uD800-\uDFFF]/g;
var lowSurrogates = /^[\uD800-\uDBFF]$/;
var hiSurrogates = /^[\uDC00-\uDFFF]$/;
var MARK = uid();
var MARK_LENGTH = MARK.length;
var WRONG_SYMBOLS_CONVERSION = !NATIVE_SYMBOL || fails(function () {
var symbol = getBuiltIn('Symbol')('stringify detection');
@@ -39,7 +50,7 @@ var ILL_FORMED_UNICODE = fails(function () {
|| $stringify('\uDEAD') !== '"\\udead"';
});
var stringifyWithSymbolsFix = function (it, replacer) {
var stringifyWithProperSymbolsConversion = WRONG_SYMBOLS_CONVERSION ? function (it, replacer) {
var args = arraySlice(arguments);
var $replacer = getReplacerFunction(replacer);
if (!isCallable($replacer) && (it === undefined || isSymbol(it))) return; // IE8 returns string on undefined
@@ -49,25 +60,73 @@ var stringifyWithSymbolsFix = function (it, replacer) {
if (!isSymbol(value)) return value;
};
return apply($stringify, null, args);
};
} : $stringify;
var fixIllFormed = function (match, offset, string) {
var fixIllFormedJSON = function (match, offset, string) {
var prev = charAt(string, offset - 1);
var next = charAt(string, offset + 1);
if ((exec(low, match) && !exec(hi, next)) || (exec(hi, match) && !exec(low, prev))) {
if ((exec(lowSurrogates, match) && !exec(hiSurrogates, next)) || (exec(hiSurrogates, match) && !exec(lowSurrogates, prev))) {
return '\\u' + numberToString(charCodeAt(match, 0), 16);
} return match;
};
if ($stringify) {
// `JSON.stringify` method
// https://tc39.es/ecma262/#sec-json.stringify
$({ target: 'JSON', stat: true, arity: 3, forced: WRONG_SYMBOLS_CONVERSION || ILL_FORMED_UNICODE }, {
// eslint-disable-next-line no-unused-vars -- required for `.length`
stringify: function stringify(it, replacer, space) {
var args = arraySlice(arguments);
var result = apply(WRONG_SYMBOLS_CONVERSION ? stringifyWithSymbolsFix : $stringify, null, args);
return ILL_FORMED_UNICODE && typeof result == 'string' ? replace(result, tester, fixIllFormed) : result;
var getReplacerFunction = function (replacer) {
if (isCallable(replacer)) return replacer;
if (!isArray(replacer)) return;
var rawLength = replacer.length;
var keys = [];
for (var i = 0; i < rawLength; i++) {
var element = replacer[i];
if (typeof element == 'string') push(keys, element);
else if (typeof element == 'number' || classof(element) === 'Number' || classof(element) === 'String') push(keys, toString(element));
}
var keysLength = keys.length;
var root = true;
return function (key, value) {
if (root) {
root = false;
return value;
}
});
}
if (isArray(this)) return value;
for (var j = 0; j < keysLength; j++) if (keys[j] === key) return value;
};
};
// `JSON.stringify` method
// https://tc39.es/ecma262/#sec-json.stringify
// https://github.com/tc39/proposal-json-parse-with-source
if ($stringify) $({ target: 'JSON', stat: true, arity: 3, forced: WRONG_SYMBOLS_CONVERSION || ILL_FORMED_UNICODE || !NATIVE_RAW_JSON }, {
stringify: function stringify(text, replacer, space) {
var replacerFunction = getReplacerFunction(replacer);
var rawStrings = [];
var json = stringifyWithProperSymbolsConversion(text, function (key, value) {
// some old implementations (like WebKit) could pass numbers as keys
var v = isCallable(replacerFunction) ? call(replacerFunction, this, $String(key), value) : value;
return !NATIVE_RAW_JSON && isRawJSON(v) ? MARK + (push(rawStrings, v.rawJSON) - 1) : v;
}, space);
if (typeof json != 'string') return json;
if (ILL_FORMED_UNICODE) json = replace(json, surrogates, fixIllFormedJSON);
if (NATIVE_RAW_JSON) return json;
var result = '';
var length = json.length;
for (var i = 0; i < length; i++) {
var chr = charAt(json, i);
if (chr === '"') {
var end = parseJSONString(json, ++i).end - 1;
var string = slice(json, i, end);
result += slice(string, 0, MARK_LENGTH) === MARK
? rawStrings[slice(string, MARK_LENGTH)]
: '"' + string + '"';
i = end;
} else result += chr;
}
return result;
}
});
@@ -1,11 +1,3 @@
'use strict';
var $ = require('../internals/export');
var NATIVE_RAW_JSON = require('../internals/native-raw-json');
var isRawJSON = require('../internals/is-raw-json');
// `JSON.isRawJSON` method
// https://tc39.es/proposal-json-parse-with-source/#sec-json.israwjson
// https://github.com/tc39/proposal-json-parse-with-source
$({ target: 'JSON', stat: true, forced: !NATIVE_RAW_JSON }, {
isRawJSON: isRawJSON
});
// TODO: Remove from `core-js@4`
require('../modules/es.json.is-raw-json');
+2 -250
View File
@@ -1,251 +1,3 @@
'use strict';
var $ = require('../internals/export');
var DESCRIPTORS = require('../internals/descriptors');
var globalThis = require('../internals/global-this');
var getBuiltIn = require('../internals/get-built-in');
var uncurryThis = require('../internals/function-uncurry-this');
var call = require('../internals/function-call');
var isCallable = require('../internals/is-callable');
var isObject = require('../internals/is-object');
var isArray = require('../internals/is-array');
var hasOwn = require('../internals/has-own-property');
var toString = require('../internals/to-string');
var lengthOfArrayLike = require('../internals/length-of-array-like');
var createProperty = require('../internals/create-property');
var fails = require('../internals/fails');
var parseJSONString = require('../internals/parse-json-string');
var NATIVE_SYMBOL = require('../internals/symbol-constructor-detection');
var JSON = globalThis.JSON;
var Number = globalThis.Number;
var SyntaxError = globalThis.SyntaxError;
var nativeParse = JSON && JSON.parse;
var enumerableOwnProperties = getBuiltIn('Object', 'keys');
// eslint-disable-next-line es/no-object-getownpropertydescriptor -- safe
var getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;
var at = uncurryThis(''.charAt);
var slice = uncurryThis(''.slice);
var exec = uncurryThis(/./.exec);
var push = uncurryThis([].push);
var IS_DIGIT = /^\d$/;
var IS_NON_ZERO_DIGIT = /^[1-9]$/;
var IS_NUMBER_START = /^[\d-]$/;
var IS_WHITESPACE = /^[\t\n\r ]$/;
var PRIMITIVE = 0;
var OBJECT = 1;
var $parse = function (source, reviver) {
source = toString(source);
var context = new Context(source, 0, '');
var root = context.parse();
var value = root.value;
var endIndex = context.skip(IS_WHITESPACE, root.end);
if (endIndex < source.length) {
throw new SyntaxError('Unexpected extra character: "' + at(source, endIndex) + '" after the parsed data at: ' + endIndex);
}
return isCallable(reviver) ? internalize({ '': value }, '', reviver, root) : value;
};
var internalize = function (holder, name, reviver, node) {
var val = holder[name];
var unmodified = node && val === node.value;
var context = unmodified && typeof node.source == 'string' ? { source: node.source } : {};
var elementRecordsLen, keys, len, i, P;
if (isObject(val)) {
var nodeIsArray = isArray(val);
var nodes = unmodified ? node.nodes : nodeIsArray ? [] : {};
if (nodeIsArray) {
elementRecordsLen = nodes.length;
len = lengthOfArrayLike(val);
for (i = 0; i < len; i++) {
internalizeProperty(val, i, internalize(val, '' + i, reviver, i < elementRecordsLen ? nodes[i] : undefined));
}
} else {
keys = enumerableOwnProperties(val);
len = lengthOfArrayLike(keys);
for (i = 0; i < len; i++) {
P = keys[i];
internalizeProperty(val, P, internalize(val, P, reviver, hasOwn(nodes, P) ? nodes[P] : undefined));
}
}
}
return call(reviver, holder, name, val, context);
};
var internalizeProperty = function (object, key, value) {
if (DESCRIPTORS) {
var descriptor = getOwnPropertyDescriptor(object, key);
if (descriptor && !descriptor.configurable) return;
}
if (value === undefined) delete object[key];
else createProperty(object, key, value);
};
var Node = function (value, end, source, nodes) {
this.value = value;
this.end = end;
this.source = source;
this.nodes = nodes;
};
var Context = function (source, index) {
this.source = source;
this.index = index;
};
// https://www.json.org/json-en.html
Context.prototype = {
fork: function (nextIndex) {
return new Context(this.source, nextIndex);
},
parse: function () {
var source = this.source;
var i = this.skip(IS_WHITESPACE, this.index);
var fork = this.fork(i);
var chr = at(source, i);
if (exec(IS_NUMBER_START, chr)) return fork.number();
switch (chr) {
case '{':
return fork.object();
case '[':
return fork.array();
case '"':
return fork.string();
case 't':
return fork.keyword(true);
case 'f':
return fork.keyword(false);
case 'n':
return fork.keyword(null);
} throw new SyntaxError('Unexpected character: "' + chr + '" at: ' + i);
},
node: function (type, value, start, end, nodes) {
return new Node(value, end, type ? null : slice(this.source, start, end), nodes);
},
object: function () {
var source = this.source;
var i = this.index + 1;
var expectKeypair = false;
var object = {};
var nodes = {};
while (i < source.length) {
i = this.until(['"', '}'], i);
if (at(source, i) === '}' && !expectKeypair) {
i++;
break;
}
// Parsing the key
var result = this.fork(i).string();
var key = result.value;
i = result.end;
i = this.until([':'], i) + 1;
// Parsing value
i = this.skip(IS_WHITESPACE, i);
result = this.fork(i).parse();
createProperty(nodes, key, result);
createProperty(object, key, result.value);
i = this.until([',', '}'], result.end);
var chr = at(source, i);
if (chr === ',') {
expectKeypair = true;
i++;
} else if (chr === '}') {
i++;
break;
}
}
return this.node(OBJECT, object, this.index, i, nodes);
},
array: function () {
var source = this.source;
var i = this.index + 1;
var expectElement = false;
var array = [];
var nodes = [];
while (i < source.length) {
i = this.skip(IS_WHITESPACE, i);
if (at(source, i) === ']' && !expectElement) {
i++;
break;
}
var result = this.fork(i).parse();
push(nodes, result);
push(array, result.value);
i = this.until([',', ']'], result.end);
if (at(source, i) === ',') {
expectElement = true;
i++;
} else if (at(source, i) === ']') {
i++;
break;
}
}
return this.node(OBJECT, array, this.index, i, nodes);
},
string: function () {
var index = this.index;
var parsed = parseJSONString(this.source, this.index + 1);
return this.node(PRIMITIVE, parsed.value, index, parsed.end);
},
number: function () {
var source = this.source;
var startIndex = this.index;
var i = startIndex;
if (at(source, i) === '-') i++;
if (at(source, i) === '0') i++;
else if (exec(IS_NON_ZERO_DIGIT, at(source, i))) i = this.skip(IS_DIGIT, i + 1);
else throw new SyntaxError('Failed to parse number at: ' + i);
if (at(source, i) === '.') i = this.skip(IS_DIGIT, i + 1);
if (at(source, i) === 'e' || at(source, i) === 'E') {
i++;
if (at(source, i) === '+' || at(source, i) === '-') i++;
var exponentStartIndex = i;
i = this.skip(IS_DIGIT, i);
if (exponentStartIndex === i) throw new SyntaxError("Failed to parse number's exponent value at: " + i);
}
return this.node(PRIMITIVE, Number(slice(source, startIndex, i)), startIndex, i);
},
keyword: function (value) {
var keyword = '' + value;
var index = this.index;
var endIndex = index + keyword.length;
if (slice(this.source, index, endIndex) !== keyword) throw new SyntaxError('Failed to parse value at: ' + index);
return this.node(PRIMITIVE, value, index, endIndex);
},
skip: function (regex, i) {
var source = this.source;
for (; i < source.length; i++) if (!exec(regex, at(source, i))) break;
return i;
},
until: function (array, i) {
i = this.skip(IS_WHITESPACE, i);
var chr = at(this.source, i);
for (var j = 0; j < array.length; j++) if (array[j] === chr) return i;
throw new SyntaxError('Unexpected character: "' + chr + '" at: ' + i);
}
};
var NO_SOURCE_SUPPORT = fails(function () {
var unsafeInt = '9007199254740993';
var source;
nativeParse(unsafeInt, function (key, value, context) {
source = context.source;
});
return source !== unsafeInt;
});
var PROPER_BASE_PARSE = NATIVE_SYMBOL && !fails(function () {
// Safari 9 bug
return 1 / nativeParse('-0 \t') !== -Infinity;
});
// `JSON.parse` method
// https://tc39.es/ecma262/#sec-json.parse
// https://github.com/tc39/proposal-json-parse-with-source
$({ target: 'JSON', stat: true, forced: NO_SOURCE_SUPPORT }, {
parse: function parse(text, reviver) {
return PROPER_BASE_PARSE && !isCallable(reviver) ? nativeParse(text) : $parse(text, reviver);
}
});
// TODO: Remove from `core-js@4`
require('../modules/es.json.parse');
@@ -1,86 +1,3 @@
'use strict';
var $ = require('../internals/export');
var FREEZING = require('../internals/freezing');
var NATIVE_RAW_JSON = require('../internals/native-raw-json');
var getBuiltIn = require('../internals/get-built-in');
var call = require('../internals/function-call');
var uncurryThis = require('../internals/function-uncurry-this');
var isCallable = require('../internals/is-callable');
var isRawJSON = require('../internals/is-raw-json');
var toString = require('../internals/to-string');
var createProperty = require('../internals/create-property');
var parseJSONString = require('../internals/parse-json-string');
var getReplacerFunction = require('../internals/get-json-replacer-function');
var uid = require('../internals/uid');
var setInternalState = require('../internals/internal-state').set;
var $String = String;
var $SyntaxError = SyntaxError;
var parse = getBuiltIn('JSON', 'parse');
var $stringify = getBuiltIn('JSON', 'stringify');
var create = getBuiltIn('Object', 'create');
var freeze = getBuiltIn('Object', 'freeze');
var at = uncurryThis(''.charAt);
var slice = uncurryThis(''.slice);
var push = uncurryThis([].push);
var MARK = uid();
var MARK_LENGTH = MARK.length;
var ERROR_MESSAGE = 'Unacceptable as raw JSON';
var isWhitespace = function (it) {
return it === ' ' || it === '\t' || it === '\n' || it === '\r';
};
// `JSON.rawJSON` method
// https://tc39.es/proposal-json-parse-with-source/#sec-json.rawjson
// https://github.com/tc39/proposal-json-parse-with-source
$({ target: 'JSON', stat: true, forced: !NATIVE_RAW_JSON }, {
rawJSON: function rawJSON(text) {
var jsonString = toString(text);
if (jsonString === '' || isWhitespace(at(jsonString, 0)) || isWhitespace(at(jsonString, jsonString.length - 1))) {
throw new $SyntaxError(ERROR_MESSAGE);
}
var parsed = parse(jsonString);
if (typeof parsed == 'object' && parsed !== null) throw new $SyntaxError(ERROR_MESSAGE);
var obj = create(null);
setInternalState(obj, { type: 'RawJSON' });
createProperty(obj, 'rawJSON', jsonString);
return FREEZING ? freeze(obj) : obj;
}
});
// `JSON.stringify` method
// https://tc39.es/ecma262/#sec-json.stringify
// https://github.com/tc39/proposal-json-parse-with-source
if ($stringify) $({ target: 'JSON', stat: true, arity: 3, forced: !NATIVE_RAW_JSON }, {
stringify: function stringify(text, replacer, space) {
var replacerFunction = getReplacerFunction(replacer);
var rawStrings = [];
var json = $stringify(text, function (key, value) {
// some old implementations (like WebKit) could pass numbers as keys
var v = isCallable(replacerFunction) ? call(replacerFunction, this, $String(key), value) : value;
return isRawJSON(v) ? MARK + (push(rawStrings, v.rawJSON) - 1) : v;
}, space);
if (typeof json != 'string') return json;
var result = '';
var length = json.length;
for (var i = 0; i < length; i++) {
var chr = at(json, i);
if (chr === '"') {
var end = parseJSONString(json, ++i).end - 1;
var string = slice(json, i, end);
result += slice(string, 0, MARK_LENGTH) === MARK
? rawStrings[slice(string, MARK_LENGTH)]
: '"' + string + '"';
i = end;
} else result += chr;
}
return result;
}
});
// TODO: Remove from `core-js@4`
require('../modules/es.json.raw-json');
@@ -0,0 +1,4 @@
'use strict';
var parent = require('../../es/json/is-raw-json');
module.exports = parent;
+4
View File
@@ -0,0 +1,4 @@
'use strict';
var parent = require('../../es/json/parse');
module.exports = parent;
+4
View File
@@ -0,0 +1,4 @@
'use strict';
var parent = require('../../es/json/raw-json');
module.exports = parent;
-1
View File
@@ -3,7 +3,6 @@ var parent = require('./4');
require('../proposals/decorator-metadata-v2');
require('../proposals/joint-iteration');
require('../proposals/json-parse-with-source');
require('../proposals/map-upsert-v4');
// TODO: Obsolete versions, remove from `core-js@4`
require('../proposals/array-grouping-stage-3');
+1
View File
@@ -14,6 +14,7 @@ require('../proposals/global-this');
require('../proposals/is-error');
require('../proposals/iterator-helpers-stage-3-2');
require('../proposals/iterator-sequencing');
require('../proposals/json-parse-with-source');
require('../proposals/math-sum');
require('../proposals/promise-all-settled');
require('../proposals/promise-any');
+11 -11
View File
@@ -835,7 +835,17 @@ GLOBAL.tests = {
'es.iterator.to-array': function () {
return Iterator.prototype.toArray;
},
'es.json.stringify': [SYMBOLS_SUPPORT, function () {
'es.json.is-raw-json': NATIVE_RAW_JSON,
'es.json.parse': function () {
var unsafeInt = '9007199254740993';
var source;
JSON.parse(unsafeInt, function (key, value, context) {
source = context.source;
});
return source === unsafeInt;
},
'es.json.raw-json': NATIVE_RAW_JSON,
'es.json.stringify': [NATIVE_RAW_JSON, SYMBOLS_SUPPORT, function () {
var symbol = Symbol('stringify detection');
return JSON.stringify([symbol]) === '[null]'
&& JSON.stringify({ a: symbol }) === '{}'
@@ -1913,16 +1923,6 @@ GLOBAL.tests = {
'esnext.iterator.zip-keyed': function () {
return Iterator.zipKeyed;
},
'esnext.json.is-raw-json': NATIVE_RAW_JSON,
'esnext.json.parse': function () {
var unsafeInt = '9007199254740993';
var source;
JSON.parse(unsafeInt, function (key, value, context) {
source = context.source;
});
return source === unsafeInt;
},
'esnext.json.raw-json': NATIVE_RAW_JSON,
'esnext.map.delete-all': function () {
return Map.prototype.deleteAll;
},
+3 -3
View File
@@ -282,6 +282,9 @@ for (PATH of ['core-js-pure', 'core-js']) {
ok(load(NS, 'escape')('!q2ф') === '%21q2%u0444');
ok(load(NS, 'unescape')('%21q2%u0444') === '!q2ф');
ok(load(NS, 'json').stringify([1]) === '[1]');
ok(load(NS, 'json/is-raw-json')({}) === false);
ok(load(NS, 'json/parse')('[42]', (key, value, { source }) => typeof value == 'number' ? source + source : value)[0] === '4242');
ok(typeof load(NS, 'json/raw-json')(42) == 'object');
ok(load(NS, 'json/stringify')([1]) === '[1]');
ok(load(NS, 'json/to-string-tag') === 'JSON');
ok(typeof load(NS, 'date/now')(new Date()) === 'number');
@@ -714,9 +717,6 @@ for (PATH of ['core-js-pure', 'core-js']) {
ok(typeof load(NS, 'iterator/to-async') == 'function');
ok(typeof load(NS, 'iterator/zip') == 'function');
ok(typeof load(NS, 'iterator/zip-keyed') == 'function');
ok(load(NS, 'json/is-raw-json')({}) === false);
ok(load(NS, 'json/parse')('[42]', (key, value, { source }) => typeof value == 'number' ? source + source : value)[0] === '4242');
ok(typeof load(NS, 'json/raw-json')(42) == 'object');
ok(load(NS, 'map/get-or-insert')(new Map([[1, 2]]), 1, 3) === 2);
ok(load(NS, 'map/get-or-insert-computed')(new Map([[1, 2]]), 1, key => key) === 2);
ok(load(NS, 'symbol/metadata'));
@@ -1,5 +1,5 @@
import isRawJSON from 'core-js-pure/actual/json/is-raw-json';
import rawJSON from 'core-js-pure/actual/json/raw-json';
import isRawJSON from 'core-js-pure/es/json/is-raw-json';
import rawJSON from 'core-js-pure/es/json/raw-json';
import freeze from 'core-js-pure/es/object/freeze';
import Symbol from 'core-js-pure/es/symbol';
@@ -2,7 +2,7 @@
// Copyright (c) 2012 Ecma International. All rights reserved.
/* eslint-disable unicorn/escape-case -- testing */
import { DESCRIPTORS, REDEFINABLE_PROTO } from '../helpers/constants.js';
import parse from 'core-js-pure/actual/json/parse';
import parse from 'core-js-pure/es/json/parse';
import defineProperty from 'core-js-pure/es/object/define-property';
import hasOwn from 'core-js-pure/es/object/has-own';
import keys from 'core-js-pure/es/object/keys';
@@ -1,6 +1,6 @@
import { FREEZING } from '../helpers/constants.js';
import rawJSON from 'core-js-pure/actual/json/raw-json';
import stringify from 'core-js-pure/actual/json/stringify';
import rawJSON from 'core-js-pure/es/json/raw-json';
import stringify from 'core-js-pure/es/json/stringify';
import isFrozen from 'core-js-pure/es/object/is-frozen';
import hasOwn from 'core-js-pure/es/object/has-own';