@node-core/utils 7.3.1 → 7.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/ncu-ci.js +39 -0
- package/lib/ci/availability.js +24 -0
- package/lib/ci/ci_utils.js +13 -0
- package/lib/ci/failure_file_scanner.js +72 -21
- package/lib/ci/jenkins.js +23 -0
- package/lib/ci/resumable_build.js +86 -0
- package/lib/ci/resume_ci.js +64 -25
- package/lib/ci/run_ci.js +39 -9
- package/lib/ci/workload.js +72 -0
- package/lib/update-v8/deps.js +4 -1
- package/node_modules/branch-diff/.github/dependabot.yml +14 -2
- package/node_modules/branch-diff/.github/workflows/test-and-release.yml +4 -15
- package/node_modules/branch-diff/CHANGELOG.md +24 -0
- package/node_modules/branch-diff/package.json +35 -3
- package/node_modules/js-yaml/dist/browser/js-yaml.esm.min.mjs +2 -2
- package/node_modules/js-yaml/dist/browser/js-yaml.esm.min.mjs.map +1 -1
- package/node_modules/js-yaml/dist/browser/js-yaml.umd.min.js +1 -1
- package/node_modules/js-yaml/dist/browser/js-yaml.umd.min.js.map +1 -1
- package/node_modules/js-yaml/dist/js-yaml.cjs.js +2 -1
- package/node_modules/js-yaml/dist/js-yaml.cjs.js.map +1 -1
- package/node_modules/js-yaml/dist/js-yaml.mjs +2 -1
- package/node_modules/js-yaml/dist/js-yaml.mjs.map +1 -1
- package/node_modules/js-yaml/package.json +1 -1
- package/node_modules/smol-toml/README.md +460 -273
- package/node_modules/smol-toml/dist/date.js +50 -21
- package/node_modules/smol-toml/dist/error.d.ts +1 -2
- package/node_modules/smol-toml/dist/error.js +6 -2
- package/node_modules/smol-toml/dist/extract.js +240 -20
- package/node_modules/smol-toml/dist/index.cjs +409 -373
- package/node_modules/smol-toml/dist/index.d.ts +5 -4
- package/node_modules/smol-toml/dist/index.js +2 -1
- package/node_modules/smol-toml/dist/parse.d.ts +38 -1
- package/node_modules/smol-toml/dist/parse.js +52 -37
- package/node_modules/smol-toml/dist/primitive.js +23 -110
- package/node_modules/smol-toml/dist/stringify.d.ts +2 -1
- package/node_modules/smol-toml/dist/stringify.js +74 -36
- package/node_modules/smol-toml/dist/struct.js +76 -99
- package/node_modules/smol-toml/dist/util.d.ts +6 -1
- package/node_modules/smol-toml/dist/util.js +4 -36
- package/node_modules/smol-toml/package.json +8 -8
- package/package.json +1 -1
|
@@ -30,6 +30,11 @@ import { stringify } from './stringify.js';
|
|
|
30
30
|
import { TomlDate } from './date.js';
|
|
31
31
|
import { TomlError } from './error.js';
|
|
32
32
|
export type { TomlValue, TomlTable, TomlValueWithoutBigInt, TomlTableWithoutBigInt } from './util.js';
|
|
33
|
+
export { parse, stringify, TomlDate, TomlError };
|
|
34
|
+
export type {
|
|
35
|
+
/** @deprecated use {@link TomlValue} instead */
|
|
36
|
+
TomlValue as TomlPrimitive, } from './util.js';
|
|
37
|
+
/** @deprecated use `import * as ... from 'smol-toml'` instead */
|
|
33
38
|
declare const _default: {
|
|
34
39
|
parse: typeof parse;
|
|
35
40
|
stringify: typeof stringify;
|
|
@@ -37,7 +42,3 @@ declare const _default: {
|
|
|
37
42
|
TomlError: typeof TomlError;
|
|
38
43
|
};
|
|
39
44
|
export default _default;
|
|
40
|
-
export { parse, stringify, TomlDate, TomlError };
|
|
41
|
-
export type {
|
|
42
|
-
/** @deprecated use TomlValue instead */
|
|
43
|
-
TomlValue as TomlPrimitive, } from './util.js';
|
|
@@ -29,5 +29,6 @@ import { parse } from './parse.js';
|
|
|
29
29
|
import { stringify } from './stringify.js';
|
|
30
30
|
import { TomlDate } from './date.js';
|
|
31
31
|
import { TomlError } from './error.js';
|
|
32
|
-
export default { parse, stringify, TomlDate, TomlError };
|
|
33
32
|
export { parse, stringify, TomlDate, TomlError };
|
|
33
|
+
/** @deprecated use `import * as ... from 'smol-toml'` instead */
|
|
34
|
+
export default { parse, stringify, TomlDate, TomlError };
|
|
@@ -26,9 +26,46 @@
|
|
|
26
26
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
27
27
|
*/
|
|
28
28
|
import { type IntegersAsBigInt, type TomlTable, type TomlTableWithoutBigInt } from './util.js';
|
|
29
|
+
export type UnsafeKeyBehaviour =
|
|
30
|
+
/** Preserve the unsafe key in the final object. */
|
|
31
|
+
'keep'
|
|
32
|
+
/** Silently drop the unsafe key from the final object. */
|
|
33
|
+
| 'drop'
|
|
34
|
+
/** Reject documents with unsafe keys. */
|
|
35
|
+
| 'throw';
|
|
29
36
|
export interface ParseOptions {
|
|
30
|
-
|
|
37
|
+
/**
|
|
38
|
+
* Whether to parse integers as {@link BigInt} or not.
|
|
39
|
+
*
|
|
40
|
+
* Use the special value `"asNeeded"` to only use {@link BigInt} for
|
|
41
|
+
* integers that cannot be safely represented as JavaScript numbers.
|
|
42
|
+
*
|
|
43
|
+
* @defaultValue `false`
|
|
44
|
+
* @since 1.4.0
|
|
45
|
+
*/
|
|
31
46
|
integersAsBigInt?: IntegersAsBigInt;
|
|
47
|
+
/**
|
|
48
|
+
* Whether to use the legacy {@link TomlDate}, instead of the new
|
|
49
|
+
* {@link https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Temporal | Temporal API}.
|
|
50
|
+
*
|
|
51
|
+
* @defaultValue `true`
|
|
52
|
+
* @since 1.9.0
|
|
53
|
+
*/
|
|
54
|
+
useLegacyDate?: boolean;
|
|
55
|
+
/**
|
|
56
|
+
* Behaviour of the library when encountering a potentially unsafe property (`__proto__`, `constructor`).
|
|
57
|
+
*
|
|
58
|
+
* @defaultValue `'keep'`
|
|
59
|
+
* @since 1.9.0
|
|
60
|
+
*/
|
|
61
|
+
unsafeKeyBehaviour?: UnsafeKeyBehaviour;
|
|
62
|
+
/**
|
|
63
|
+
* Maximum permitted inline object/array depth.
|
|
64
|
+
*
|
|
65
|
+
* @defaultValue `1000`
|
|
66
|
+
* @since 1.9.0
|
|
67
|
+
*/
|
|
68
|
+
maxDepth?: number;
|
|
32
69
|
}
|
|
33
70
|
export declare function parse(toml: string, options?: ParseOptions & {
|
|
34
71
|
integersAsBigInt: Exclude<IntegersAsBigInt, undefined | false>;
|
|
@@ -29,7 +29,7 @@ import { parseKey } from './struct.js';
|
|
|
29
29
|
import { extractValue } from './extract.js';
|
|
30
30
|
import { skipVoid } from './util.js';
|
|
31
31
|
import { TomlError } from './error.js';
|
|
32
|
-
function peekTable(key, table, meta, type) {
|
|
32
|
+
function peekTable(ctx, key, table, meta, type) {
|
|
33
33
|
let t = table;
|
|
34
34
|
let m = meta;
|
|
35
35
|
let k;
|
|
@@ -37,7 +37,7 @@ function peekTable(key, table, meta, type) {
|
|
|
37
37
|
let state;
|
|
38
38
|
for (let i = 0; i < key.length; i++) {
|
|
39
39
|
if (i) {
|
|
40
|
-
t = hasOwn ? t[k] : (t[k] =
|
|
40
|
+
t = hasOwn ? t[k] : (t[k] = Object.create(null));
|
|
41
41
|
m = (state = m[k]).c;
|
|
42
42
|
if (type === 0 /* Type.DOTTED */ && (state.t === 1 /* Type.EXPLICIT */ || state.t === 2 /* Type.ARRAY */)) {
|
|
43
43
|
return null;
|
|
@@ -53,7 +53,10 @@ function peekTable(key, table, meta, type) {
|
|
|
53
53
|
return null;
|
|
54
54
|
}
|
|
55
55
|
if (!hasOwn) {
|
|
56
|
-
|
|
56
|
+
let unsafe = k === '__proto__';
|
|
57
|
+
if (ctx.uk && (unsafe || k === 'constructor'))
|
|
58
|
+
return false;
|
|
59
|
+
if (unsafe) {
|
|
57
60
|
Object.defineProperty(t, k, { enumerable: true, configurable: true, writable: true });
|
|
58
61
|
Object.defineProperty(m, k, { enumerable: true, configurable: true, writable: true });
|
|
59
62
|
}
|
|
@@ -62,7 +65,7 @@ function peekTable(key, table, meta, type) {
|
|
|
62
65
|
? 3 /* Type.ARRAY_DOTTED */ : type,
|
|
63
66
|
d: false,
|
|
64
67
|
i: 0,
|
|
65
|
-
c:
|
|
68
|
+
c: Object.create(null),
|
|
66
69
|
};
|
|
67
70
|
}
|
|
68
71
|
}
|
|
@@ -76,8 +79,8 @@ function peekTable(key, table, meta, type) {
|
|
|
76
79
|
state.d = true;
|
|
77
80
|
t[k] = [];
|
|
78
81
|
}
|
|
79
|
-
t[k].push(t =
|
|
80
|
-
state.c[state.i++] = (state = { t: 1 /* Type.EXPLICIT */, d: false, i: 0, c:
|
|
82
|
+
t[k].push(t = Object.create(null));
|
|
83
|
+
state.c[state.i++] = (state = { t: 1 /* Type.EXPLICIT */, d: false, i: 0, c: Object.create(null) });
|
|
81
84
|
}
|
|
82
85
|
if (state.d) {
|
|
83
86
|
// Redefining a table!
|
|
@@ -85,63 +88,75 @@ function peekTable(key, table, meta, type) {
|
|
|
85
88
|
}
|
|
86
89
|
state.d = true;
|
|
87
90
|
if (type === 1 /* Type.EXPLICIT */) {
|
|
88
|
-
t = hasOwn ? t[k] : (t[k] =
|
|
91
|
+
t = hasOwn ? t[k] : (t[k] = Object.create(null));
|
|
89
92
|
}
|
|
90
93
|
else if (type === 0 /* Type.DOTTED */ && hasOwn) {
|
|
91
94
|
return null;
|
|
92
95
|
}
|
|
93
96
|
return [k, t, state.c];
|
|
94
97
|
}
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
98
|
+
function validateTablePeek(ctx, peek, ptr) {
|
|
99
|
+
if (peek === null || ctx.uk === 2)
|
|
100
|
+
TomlError.x(peek === null
|
|
101
|
+
? 'trying to redefine an already defined table or value'
|
|
102
|
+
: 'document contains an unsafe property', ctx, ptr);
|
|
103
|
+
}
|
|
104
|
+
export function parse(toml, options = {}) {
|
|
105
|
+
let ctx = {
|
|
106
|
+
s: toml,
|
|
107
|
+
p: 0,
|
|
108
|
+
d: options.maxDepth ?? 1000,
|
|
109
|
+
bi: options.integersAsBigInt ?? false,
|
|
110
|
+
ld: options.useLegacyDate ?? true,
|
|
111
|
+
uk: options.unsafeKeyBehaviour === 'throw' ? 2 : options.unsafeKeyBehaviour === 'drop' ? 1 : 0,
|
|
112
|
+
};
|
|
113
|
+
let res = Object.create(null);
|
|
114
|
+
let meta = Object.create(null);
|
|
99
115
|
let tmp;
|
|
116
|
+
let skipping = false;
|
|
100
117
|
let tbl = res;
|
|
101
118
|
let m = meta;
|
|
119
|
+
// BOM is allowed, skip.
|
|
120
|
+
// JS is UTF-16, so we have to check for the UTF-16 BOM instead of the UTF-8 BOM sequence!
|
|
121
|
+
if (toml.charCodeAt(0) === 0xfeff)
|
|
122
|
+
ctx.p++;
|
|
102
123
|
skipVoid(ctx);
|
|
103
124
|
while (ctx.p < toml.length) {
|
|
104
125
|
if (toml.charCodeAt(ctx.p) === 0x5b /* [ */) {
|
|
105
126
|
let isTableArray = toml.charCodeAt(++ctx.p) === 0x5b; /* [ */
|
|
106
127
|
tmp = ctx.p += +isTableArray;
|
|
107
|
-
|
|
128
|
+
skipping = false;
|
|
129
|
+
let k = parseKey(ctx, 0x5d /* ] */);
|
|
108
130
|
if (isTableArray) {
|
|
109
|
-
if (toml.charCodeAt(ctx.p
|
|
110
|
-
|
|
111
|
-
toml: toml,
|
|
112
|
-
ptr: ctx.p - 1,
|
|
113
|
-
});
|
|
131
|
+
if (toml.charCodeAt(ctx.p) !== 0x5d /* ] */) {
|
|
132
|
+
TomlError.x('expected end of table array declaration', ctx);
|
|
114
133
|
}
|
|
115
134
|
ctx.p++;
|
|
116
135
|
}
|
|
117
|
-
let p = peekTable(k, res, meta, isTableArray ? 2 /* Type.ARRAY */ : 1 /* Type.EXPLICIT */);
|
|
136
|
+
let p = peekTable(ctx, k, res, meta, isTableArray ? 2 /* Type.ARRAY */ : 1 /* Type.EXPLICIT */);
|
|
118
137
|
if (!p) {
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
138
|
+
validateTablePeek(ctx, p, tmp);
|
|
139
|
+
skipping = true;
|
|
140
|
+
}
|
|
141
|
+
else {
|
|
142
|
+
m = p[2];
|
|
143
|
+
tbl = p[1];
|
|
123
144
|
}
|
|
124
|
-
m = p[2];
|
|
125
|
-
tbl = p[1];
|
|
126
145
|
}
|
|
127
146
|
else {
|
|
128
147
|
tmp = ctx.p;
|
|
129
148
|
let k = parseKey(ctx);
|
|
130
|
-
let p = peekTable(k, tbl, m, 0 /* Type.DOTTED */);
|
|
131
|
-
if (!p)
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
p[1][p[0]] = extractValue(ctx, void 0, integersAsBigInt);
|
|
149
|
+
let p = peekTable(ctx, k, tbl, m, 0 /* Type.DOTTED */);
|
|
150
|
+
if (!p && !skipping)
|
|
151
|
+
validateTablePeek(ctx, p, tmp);
|
|
152
|
+
skipVoid(ctx, true, true);
|
|
153
|
+
let v = extractValue(ctx, void 0);
|
|
154
|
+
if (p && !skipping)
|
|
155
|
+
p[1][p[0]] = v;
|
|
138
156
|
}
|
|
139
157
|
skipVoid(ctx, true);
|
|
140
|
-
if (ctx.p < toml.length && (tmp = toml.charCodeAt(ctx.p)) !== 0xa /* \n */ && tmp !== 0xd /* \r */) {
|
|
141
|
-
|
|
142
|
-
toml: toml,
|
|
143
|
-
ptr: ctx.p,
|
|
144
|
-
});
|
|
158
|
+
if (ctx.p < toml.length && (tmp = toml.charCodeAt(ctx.p)) !== 0xa /* \n */ && (tmp !== 0xd /* \r */ || toml.charCodeAt(ctx.p + 1) !== 0xa /* \n */)) {
|
|
159
|
+
TomlError.x('each key-value declaration must be followed by an end-of-line', ctx);
|
|
145
160
|
}
|
|
146
161
|
skipVoid(ctx);
|
|
147
162
|
}
|
|
@@ -25,16 +25,10 @@
|
|
|
25
25
|
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
26
26
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
27
27
|
*/
|
|
28
|
-
import { TomlDate } from './date.js';
|
|
29
28
|
import { TomlError } from './error.js';
|
|
30
|
-
import { skipComment, skipUntil } from './util.js';
|
|
31
|
-
// let CTRL_REGEX = /[\x00-\x08\x0f-\x1f\x7f]/
|
|
32
|
-
let INT_REGEX = /^((0x[0-9a-fA-F](_?[0-9a-fA-F])*)|(([+-]|0[ob])?\d(_?\d)*))$/;
|
|
33
|
-
let FLOAT_REGEX = /^[+-]?\d(_?\d)*(\.\d(_?\d)*)?([eE][+-]?\d(_?\d)*)?$/;
|
|
34
|
-
let LEADING_ZERO = /^[+-]?0[0-9_]/;
|
|
35
29
|
/** @internal */
|
|
36
30
|
export function parseString(ctx) {
|
|
37
|
-
let
|
|
31
|
+
let startPtr = ctx.p;
|
|
38
32
|
let c = ctx.s.charCodeAt(ctx.p++);
|
|
39
33
|
let first = c;
|
|
40
34
|
let isLiteral = c === 0x27; /* ' */
|
|
@@ -46,37 +40,8 @@ export function parseString(ctx) {
|
|
|
46
40
|
else if (c === 0xd /* \r */ && ctx.s.charCodeAt(ctx.p + 1) === 0xa /* \n */)
|
|
47
41
|
ctx.p += 2;
|
|
48
42
|
}
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
Kept for reference and/or future fafoing.
|
|
52
|
-
|
|
53
|
-
Without: spec 5.08 µs/iter 3.88 ipc (99.44% cache) 23.90 branch misses 28.61k cycles 111.01k instructions
|
|
54
|
-
5MB 115.73 ms/iter 2.51 ipc (98.36% cache) 3.12M branch misses 619.30M cycles 1.56G instructions
|
|
55
|
-
|
|
56
|
-
With: spec 5.09 µs/iter 3.90 ipc (99.46% cache) 24.42 branch misses 28.57k cycles 111.49k instructions
|
|
57
|
-
5MB 113.89 ms/iter 2.47 ipc (98.38% cache) 3.12M branch misses 611.94M cycles 1.51G instructions
|
|
58
|
-
|
|
59
|
-
if (c === "'") {
|
|
60
|
-
// Literal strings fast path - no transform needs to occur; just grab the str and that's it
|
|
61
|
-
let endPtr = str.indexOf(isMultiline ? "'''" : "'", ptr)
|
|
62
|
-
if (endPtr < 0) {
|
|
63
|
-
throw new TomlError("unfinished string literal", { toml: str, ptr })
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
if (isMultiline) {
|
|
67
|
-
// If the string ends with 4-5 quotes, then the first 1-2 are part of the string
|
|
68
|
-
if (str[endPtr + 3] === "'") endPtr++
|
|
69
|
-
if (str[endPtr + 3] === "'") endPtr++
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
let string = str.slice(ptr, endPtr)
|
|
73
|
-
if (CTRL_REGEX.test(string)) {
|
|
74
|
-
let match = string.match(CTRL_REGEX)!
|
|
75
|
-
throw new TomlError('control characters are not allowed in strings', { toml: str, ptr: ptr + (match.index ?? 0) })
|
|
76
|
-
}
|
|
77
|
-
return [string, endPtr + (isMultiline ? 3 : 1)]
|
|
78
|
-
}
|
|
79
|
-
*/
|
|
43
|
+
// For the record: it is not worth it to use a fast-path for literal strings using `indexOf`.
|
|
44
|
+
// Doing a char-by-char iteration ends up dispatching less instructions, for the same wall-clock runtime.
|
|
80
45
|
let parsed = '';
|
|
81
46
|
let sliceStart = ctx.p;
|
|
82
47
|
// states:
|
|
@@ -93,10 +58,7 @@ export function parseString(ctx) {
|
|
|
93
58
|
}
|
|
94
59
|
// Control characters are banned in TOML, so we throw an error if we encounter them
|
|
95
60
|
else if ((c < 0x20 && c !== 0x9 /* \t */) || c === 0x7f) {
|
|
96
|
-
|
|
97
|
-
toml: ctx.s,
|
|
98
|
-
ptr: ctx.p,
|
|
99
|
-
});
|
|
61
|
+
TomlError.x('control characters are not allowed in strings', ctx);
|
|
100
62
|
}
|
|
101
63
|
// The string might terminate while we're parsing through a newline escape.
|
|
102
64
|
// It must have encountered a newline; otherwise, it'll simply fail in another branch.
|
|
@@ -109,11 +71,15 @@ export function parseString(ctx) {
|
|
|
109
71
|
ctx.p++;
|
|
110
72
|
}
|
|
111
73
|
// If we're in a newline escape still, then there's nothing to add.
|
|
112
|
-
if (!state)
|
|
113
|
-
|
|
74
|
+
if (!state) {
|
|
75
|
+
// Avoid a useless concat operation if the string can be used as-is.
|
|
76
|
+
let s = ctx.s.slice(sliceStart, ctx.p);
|
|
77
|
+
parsed = parsed ? parsed + s : s;
|
|
78
|
+
}
|
|
114
79
|
ctx.p += isMultiline ? 3 : 1;
|
|
115
80
|
return parsed;
|
|
116
81
|
}
|
|
82
|
+
// Baseline state; keep moving forward unless an escape sequence starts
|
|
117
83
|
else if (!state) {
|
|
118
84
|
if (!isLiteral && c === 0x5c /* \ */) {
|
|
119
85
|
parsed += ctx.s.slice(sliceStart, (sliceStart = ctx.p));
|
|
@@ -122,29 +88,32 @@ export function parseString(ctx) {
|
|
|
122
88
|
}
|
|
123
89
|
else if (state === 1) {
|
|
124
90
|
if (c === 0x78 /* x */ || c === 0x75 /* u */ || c === 0x55 /* U */) { // Unicode escape
|
|
91
|
+
let errPtr = ctx.p++ - 1;
|
|
125
92
|
let value = 0;
|
|
126
93
|
let len = c === 0x78 /* x */ ? 2 : c === 0x75 /* u */ ? 4 : 8;
|
|
127
94
|
for (let j = 0; j < len; j++, ctx.p++) {
|
|
128
|
-
let hex = ctx.s.charCodeAt(ctx.p
|
|
95
|
+
let hex = ctx.s.charCodeAt(ctx.p);
|
|
129
96
|
let digit =
|
|
130
97
|
/* 0-9 */ hex >= 0x30 && hex <= 0x39 ? hex - 0x30 :
|
|
131
98
|
/* A-F */ hex >= 0x41 && hex <= 0x46 ? hex - 0x41 + 10 :
|
|
132
99
|
/* a-f */ hex >= 0x61 && hex <= 0x66 ? hex - 0x61 + 10 : -1;
|
|
133
100
|
if (digit < 0)
|
|
134
|
-
|
|
101
|
+
TomlError.x('invalid non-hex character in unicode escape', ctx);
|
|
135
102
|
value = (value << 4) | digit;
|
|
136
103
|
}
|
|
137
104
|
// Because JS does bitwise on signed 32bit integers, all 0xfzzzzzzz values are actually seen as negative
|
|
138
105
|
if (value < 0 || value > 0x10ffff || (value >= 0xd800 && value <= 0xdfff)) {
|
|
139
|
-
|
|
106
|
+
TomlError.x('invalid unicode escape', ctx, errPtr);
|
|
140
107
|
}
|
|
141
108
|
parsed += String.fromCodePoint(value);
|
|
142
|
-
sliceStart = ctx.p
|
|
109
|
+
sliceStart = ctx.p--;
|
|
143
110
|
state = 0;
|
|
144
111
|
}
|
|
145
|
-
|
|
112
|
+
// Newline escape sequence. We only need to care about spaces and tabs; newlines are dealt with earlier
|
|
113
|
+
else if (isMultiline && (c === 0x20 || c === 0x9 /* \t */)) {
|
|
146
114
|
state = 2;
|
|
147
115
|
}
|
|
116
|
+
// Basic escape sequence
|
|
148
117
|
else {
|
|
149
118
|
if (c === 0x62 /* b */)
|
|
150
119
|
parsed += '\b';
|
|
@@ -163,76 +132,20 @@ export function parseString(ctx) {
|
|
|
163
132
|
else if (c === 0x5c /* \ */)
|
|
164
133
|
parsed += '\\';
|
|
165
134
|
else
|
|
166
|
-
|
|
135
|
+
TomlError.x('unrecognised escape sequence', ctx);
|
|
167
136
|
sliceStart = ctx.p + 1;
|
|
168
137
|
state = 0;
|
|
169
138
|
}
|
|
170
139
|
}
|
|
140
|
+
// Newline escape continuation: keep moving forward until the first non-whitespace char
|
|
171
141
|
else if (c !== 0x20 && c !== 0x9 /* \t */) {
|
|
172
|
-
if (state === 2)
|
|
173
|
-
|
|
174
|
-
toml: ctx.s,
|
|
175
|
-
ptr: sliceStart,
|
|
176
|
-
});
|
|
177
|
-
}
|
|
142
|
+
if (state === 2)
|
|
143
|
+
TomlError.x('invalid escape: only line-ending whitespace may be escaped', ctx, sliceStart);
|
|
178
144
|
// State cannot be zero, or we'd have branched earlier already.
|
|
179
145
|
// If it's a backslash, immediately transition to the escape state so it can be processed.
|
|
180
146
|
state = !isLiteral && c === 0x5c /* \ */ ? 1 : 0;
|
|
181
147
|
sliceStart = ctx.p;
|
|
182
148
|
}
|
|
183
149
|
}
|
|
184
|
-
|
|
185
|
-
}
|
|
186
|
-
function sliceAndTrimEndOf(ctx, start, end) {
|
|
187
|
-
let value = ctx.s.slice(start, end);
|
|
188
|
-
let commentIdx = value.indexOf('#');
|
|
189
|
-
if (commentIdx > 0) {
|
|
190
|
-
// The call to skipComment allows to "validate" the comment
|
|
191
|
-
// (absence of control characters)
|
|
192
|
-
skipComment({ s: value, p: commentIdx, d: 0 });
|
|
193
|
-
value = value.slice(0, commentIdx);
|
|
194
|
-
}
|
|
195
|
-
return value.trimEnd();
|
|
196
|
-
}
|
|
197
|
-
/** @internal */
|
|
198
|
-
export function parseValue(ctx, integersAsBigInt, end) {
|
|
199
|
-
let ptr = ctx.p;
|
|
200
|
-
let err = { toml: ctx.s, ptr };
|
|
201
|
-
skipUntil(ctx, 0x2c /* , */, end);
|
|
202
|
-
let value = sliceAndTrimEndOf(ctx, ptr, ctx.p);
|
|
203
|
-
if (!value)
|
|
204
|
-
throw new TomlError('incomplete declaration: value expected', err);
|
|
205
|
-
if (value === '-inf')
|
|
206
|
-
return -Infinity;
|
|
207
|
-
if (value === 'inf' || value === '+inf')
|
|
208
|
-
return Infinity;
|
|
209
|
-
if (value === 'nan' || value === '+nan' || value === '-nan')
|
|
210
|
-
return NaN;
|
|
211
|
-
// Avoid FP representation of -0
|
|
212
|
-
if (value === '-0')
|
|
213
|
-
return integersAsBigInt ? 0n : 0;
|
|
214
|
-
// Numbers
|
|
215
|
-
let isInt = INT_REGEX.test(value);
|
|
216
|
-
if (isInt || FLOAT_REGEX.test(value)) {
|
|
217
|
-
if (LEADING_ZERO.test(value)) {
|
|
218
|
-
throw new TomlError('leading zeroes are not allowed', err);
|
|
219
|
-
}
|
|
220
|
-
value = value.replace(/_/g, '');
|
|
221
|
-
let numeric = +value;
|
|
222
|
-
if (isNaN(numeric)) {
|
|
223
|
-
throw new TomlError('invalid number', err);
|
|
224
|
-
}
|
|
225
|
-
if (isInt) {
|
|
226
|
-
if ((isInt = !Number.isSafeInteger(numeric)) && !integersAsBigInt) {
|
|
227
|
-
throw new TomlError('integer value cannot be represented losslessly', err);
|
|
228
|
-
}
|
|
229
|
-
if (isInt || integersAsBigInt === true)
|
|
230
|
-
numeric = BigInt(value);
|
|
231
|
-
}
|
|
232
|
-
return numeric;
|
|
233
|
-
}
|
|
234
|
-
const date = new TomlDate(value);
|
|
235
|
-
if (!date.isValid())
|
|
236
|
-
throw new TomlError('invalid value', err);
|
|
237
|
-
return date;
|
|
150
|
+
TomlError.x('unfinished string', ctx, startPtr);
|
|
238
151
|
}
|
|
@@ -25,7 +25,8 @@
|
|
|
25
25
|
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
26
26
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
27
27
|
*/
|
|
28
|
-
export declare function stringify(obj: any, { maxDepth, numbersAsFloat }?: {
|
|
28
|
+
export declare function stringify(obj: any, { maxDepth, numbersAsFloat, strictTemporal }?: {
|
|
29
29
|
maxDepth?: number;
|
|
30
30
|
numbersAsFloat?: boolean;
|
|
31
|
+
strictTemporal?: boolean;
|
|
31
32
|
}): string;
|
|
@@ -26,22 +26,29 @@
|
|
|
26
26
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
27
27
|
*/
|
|
28
28
|
let BARE_KEY = /^[a-z0-9-_]+$/i;
|
|
29
|
+
let HAS_WELLFORMED = !!(''.isWellFormed);
|
|
29
30
|
function extendedTypeOf(obj) {
|
|
30
31
|
let type = typeof obj;
|
|
31
32
|
if (type === 'object') {
|
|
32
33
|
if (Array.isArray(obj))
|
|
33
34
|
return 'array';
|
|
34
|
-
if (typeof obj
|
|
35
|
+
if (typeof obj.getUTCDate === 'function' && obj instanceof Date)
|
|
35
36
|
return 'date';
|
|
36
|
-
if (globalThis.Temporal
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
obj instanceof Temporal.
|
|
41
|
-
|
|
42
|
-
obj instanceof Temporal.PlainTime ||
|
|
43
|
-
|
|
44
|
-
|
|
37
|
+
if (globalThis.Temporal) {
|
|
38
|
+
if (obj.until) {
|
|
39
|
+
if (obj instanceof Temporal.ZonedDateTime)
|
|
40
|
+
return 'temporal/tz+uc';
|
|
41
|
+
if (obj instanceof Temporal.PlainDateTime || obj instanceof Temporal.PlainDate)
|
|
42
|
+
return 'temporal/uc';
|
|
43
|
+
if (obj instanceof Temporal.PlainTime || obj instanceof Temporal.Instant)
|
|
44
|
+
return 'temporal';
|
|
45
|
+
if (obj instanceof Temporal.PlainYearMonth)
|
|
46
|
+
return 'temporal/x';
|
|
47
|
+
}
|
|
48
|
+
else if ((obj.toPlainDate && obj instanceof Temporal.PlainMonthDay) ||
|
|
49
|
+
(obj.negated && obj instanceof Temporal.Duration)) {
|
|
50
|
+
return 'temporal/x';
|
|
51
|
+
}
|
|
45
52
|
}
|
|
46
53
|
}
|
|
47
54
|
return type;
|
|
@@ -53,16 +60,20 @@ function isArrayOfTables(obj) {
|
|
|
53
60
|
}
|
|
54
61
|
return obj.length != 0;
|
|
55
62
|
}
|
|
63
|
+
function formatWellFormedStringUnchecked(s) {
|
|
64
|
+
return JSON.stringify(s).replaceAll('\x7f', '\\u007f');
|
|
65
|
+
}
|
|
56
66
|
function formatString(s) {
|
|
57
|
-
return
|
|
67
|
+
return formatWellFormedStringUnchecked(HAS_WELLFORMED ? s.toWellFormed() : s);
|
|
58
68
|
}
|
|
59
|
-
function
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
69
|
+
function formatKey(s) {
|
|
70
|
+
if (BARE_KEY.test(s))
|
|
71
|
+
return s;
|
|
72
|
+
if (HAS_WELLFORMED && !s.isWellFormed())
|
|
73
|
+
throw new RangeError('key contains illegal lone surrogates');
|
|
74
|
+
return formatWellFormedStringUnchecked(s);
|
|
64
75
|
}
|
|
65
|
-
function stringifyValue(val, type, depth, numberAsFloat) {
|
|
76
|
+
function stringifyValue(val, type, depth, numberAsFloat, strictTemporal) {
|
|
66
77
|
if (depth === 0) {
|
|
67
78
|
throw new Error('Could not stringify the object: maximum object depth exceeded');
|
|
68
79
|
}
|
|
@@ -79,6 +90,7 @@ function stringifyValue(val, type, depth, numberAsFloat) {
|
|
|
79
90
|
return val.toFixed(1);
|
|
80
91
|
case 'bigint':
|
|
81
92
|
case 'boolean':
|
|
93
|
+
case 'temporal':
|
|
82
94
|
return val.toString();
|
|
83
95
|
case 'string':
|
|
84
96
|
return formatString(val);
|
|
@@ -87,14 +99,42 @@ function stringifyValue(val, type, depth, numberAsFloat) {
|
|
|
87
99
|
throw new TypeError('cannot serialize invalid date');
|
|
88
100
|
return val.toISOString();
|
|
89
101
|
case 'object':
|
|
90
|
-
return stringifyInlineTable(val, depth, numberAsFloat);
|
|
102
|
+
return stringifyInlineTable(val, depth, numberAsFloat, strictTemporal);
|
|
91
103
|
case 'array':
|
|
92
|
-
return stringifyArray(val, depth, numberAsFloat);
|
|
93
|
-
case
|
|
94
|
-
|
|
104
|
+
return stringifyArray(val, depth, numberAsFloat, strictTemporal);
|
|
105
|
+
// @ts-expect-error -- intentional fallthrough case
|
|
106
|
+
case 'temporal/tz+uc':
|
|
107
|
+
if (strictTemporal) {
|
|
108
|
+
let tz = val.timeZoneId;
|
|
109
|
+
let tzc = tz.charCodeAt(0);
|
|
110
|
+
if (
|
|
111
|
+
// Classic offset
|
|
112
|
+
tzc !== 0x2b /* + */ && tzc !== 0x2d /* - */ &&
|
|
113
|
+
(
|
|
114
|
+
// Fast pre-check pass; see below for the actually accepted values
|
|
115
|
+
(tzc !== 0x55 /* U */ && tzc !== 0x47 /* G */ && tzc !== 0x5a /* Z */ && tzc !== 0x45 /* E */) ||
|
|
116
|
+
(
|
|
117
|
+
// UTC and its aliases; Temporal implementations don't all canonicalise unfortunately
|
|
118
|
+
tz !== 'UTC' && tz !== 'UCT' && tz !== 'Universal' && tz !== 'Zulu' &&
|
|
119
|
+
// GMT is a TZ but it's for all intents and purposes equivalent to UTC. Safe to downgrade.
|
|
120
|
+
!tz.startsWith('GMT') && tz !== 'Greenwich' &&
|
|
121
|
+
// Etc/* are all safe to downgrade to offset (either UTC, GMT, or offset)
|
|
122
|
+
!tz.startsWith('Etc/')))) {
|
|
123
|
+
throw new TypeError('Temporal objects with an IANA timezone are not allowed in Temporal strict mode');
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
case 'temporal/uc':
|
|
127
|
+
if (strictTemporal && val.calendarId !== 'iso8601')
|
|
128
|
+
throw new TypeError('Temporal objects with a non-default calendar are not allowed in Temporal strict mode');
|
|
129
|
+
return val.toString({
|
|
130
|
+
calendarName: 'never',
|
|
131
|
+
timeZoneName: 'never',
|
|
132
|
+
});
|
|
133
|
+
case 'temporal/x':
|
|
134
|
+
throw new TypeError('Unsupported ' + val[Symbol.toStringTag]);
|
|
95
135
|
}
|
|
96
136
|
}
|
|
97
|
-
function stringifyInlineTable(obj, depth, numberAsFloat) {
|
|
137
|
+
function stringifyInlineTable(obj, depth, numberAsFloat, strictTemporal) {
|
|
98
138
|
let keys = Object.keys(obj);
|
|
99
139
|
if (keys.length === 0)
|
|
100
140
|
return '{}';
|
|
@@ -103,13 +143,11 @@ function stringifyInlineTable(obj, depth, numberAsFloat) {
|
|
|
103
143
|
let k = keys[i];
|
|
104
144
|
if (i)
|
|
105
145
|
res += ', ';
|
|
106
|
-
res +=
|
|
107
|
-
res += ' = ';
|
|
108
|
-
res += stringifyValue(obj[k], extendedTypeOf(obj[k]), depth - 1, numberAsFloat);
|
|
146
|
+
res += formatKey(k) + ' = ' + stringifyValue(obj[k], extendedTypeOf(obj[k]), depth - 1, numberAsFloat, strictTemporal);
|
|
109
147
|
}
|
|
110
148
|
return res + ' }';
|
|
111
149
|
}
|
|
112
|
-
function stringifyArray(array, depth, numberAsFloat) {
|
|
150
|
+
function stringifyArray(array, depth, numberAsFloat, strictTemporal) {
|
|
113
151
|
if (array.length === 0)
|
|
114
152
|
return '[]';
|
|
115
153
|
let res = '[ ';
|
|
@@ -119,22 +157,22 @@ function stringifyArray(array, depth, numberAsFloat) {
|
|
|
119
157
|
if (array[i] === null || array[i] === void 0) {
|
|
120
158
|
throw new TypeError('arrays cannot contain null or undefined values');
|
|
121
159
|
}
|
|
122
|
-
res += stringifyValue(array[i], extendedTypeOf(array[i]), depth - 1, numberAsFloat);
|
|
160
|
+
res += stringifyValue(array[i], extendedTypeOf(array[i]), depth - 1, numberAsFloat, strictTemporal);
|
|
123
161
|
}
|
|
124
162
|
return res + ' ]';
|
|
125
163
|
}
|
|
126
|
-
function stringifyArrayTable(array, key, depth, numberAsFloat) {
|
|
164
|
+
function stringifyArrayTable(array, key, depth, numberAsFloat, strictTemporal) {
|
|
127
165
|
if (depth === 0) {
|
|
128
166
|
throw new Error('Could not stringify the object: maximum object depth exceeded');
|
|
129
167
|
}
|
|
130
168
|
let res = '';
|
|
131
169
|
for (let i = 0; i < array.length; i++) {
|
|
132
170
|
res += `${res && '\n'}[[${key}]]\n`;
|
|
133
|
-
res += stringifyTable(0, array[i], key, depth, numberAsFloat);
|
|
171
|
+
res += stringifyTable(0, array[i], key, depth, numberAsFloat, strictTemporal);
|
|
134
172
|
}
|
|
135
173
|
return res;
|
|
136
174
|
}
|
|
137
|
-
function stringifyTable(tableKey, obj, prefix, depth, numberAsFloat) {
|
|
175
|
+
function stringifyTable(tableKey, obj, prefix, depth, numberAsFloat, strictTemporal) {
|
|
138
176
|
if (depth === 0) {
|
|
139
177
|
throw new Error('Could not stringify the object: maximum object depth exceeded');
|
|
140
178
|
}
|
|
@@ -148,18 +186,18 @@ function stringifyTable(tableKey, obj, prefix, depth, numberAsFloat) {
|
|
|
148
186
|
if (type === 'symbol' || type === 'function') {
|
|
149
187
|
throw new TypeError(`cannot serialize values of type '${type}'`);
|
|
150
188
|
}
|
|
151
|
-
let key =
|
|
189
|
+
let key = formatKey(k);
|
|
152
190
|
if (type === 'array' && isArrayOfTables(obj[k])) {
|
|
153
|
-
tables += (tables && '\n') + stringifyArrayTable(obj[k], prefix ? `${prefix}.${key}` : key, depth - 1, numberAsFloat);
|
|
191
|
+
tables += (tables && '\n') + stringifyArrayTable(obj[k], prefix ? `${prefix}.${key}` : key, depth - 1, numberAsFloat, strictTemporal);
|
|
154
192
|
}
|
|
155
193
|
else if (type === 'object') {
|
|
156
194
|
let tblKey = prefix ? `${prefix}.${key}` : key;
|
|
157
|
-
tables += (tables && '\n') + stringifyTable(tblKey, obj[k], tblKey, depth - 1, numberAsFloat);
|
|
195
|
+
tables += (tables && '\n') + stringifyTable(tblKey, obj[k], tblKey, depth - 1, numberAsFloat, strictTemporal);
|
|
158
196
|
}
|
|
159
197
|
else {
|
|
160
198
|
preamble += key;
|
|
161
199
|
preamble += ' = ';
|
|
162
|
-
preamble += stringifyValue(obj[k], type, depth, numberAsFloat);
|
|
200
|
+
preamble += stringifyValue(obj[k], type, depth, numberAsFloat, strictTemporal);
|
|
163
201
|
preamble += '\n';
|
|
164
202
|
}
|
|
165
203
|
}
|
|
@@ -170,11 +208,11 @@ function stringifyTable(tableKey, obj, prefix, depth, numberAsFloat) {
|
|
|
170
208
|
? `${preamble}\n${tables}`
|
|
171
209
|
: preamble || tables;
|
|
172
210
|
}
|
|
173
|
-
export function stringify(obj, { maxDepth = 1000, numbersAsFloat = false } = {}) {
|
|
211
|
+
export function stringify(obj, { maxDepth = 1000, numbersAsFloat = false, strictTemporal = false } = {}) {
|
|
174
212
|
if (extendedTypeOf(obj) !== 'object') {
|
|
175
213
|
throw new TypeError('stringify can only be called with an object');
|
|
176
214
|
}
|
|
177
|
-
let str = stringifyTable(0, obj, '', maxDepth, numbersAsFloat);
|
|
215
|
+
let str = stringifyTable(0, obj, '', maxDepth, numbersAsFloat, strictTemporal);
|
|
178
216
|
if (str[str.length - 1] !== '\n')
|
|
179
217
|
return str + '\n';
|
|
180
218
|
return str;
|