smol-toml 1.0.1 → 1.1.0
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/README.md +87 -9
- package/dist/date.js +2 -0
- package/dist/extract.d.ts +29 -0
- package/dist/extract.js +92 -0
- package/dist/index.d.ts +3 -2
- package/dist/index.js +3 -121
- package/dist/parse.d.ts +1 -1
- package/dist/parse.js +111 -55
- package/dist/primitive.js +2 -2
- package/dist/stringify.d.ts +28 -0
- package/dist/stringify.js +148 -0
- package/dist/struct.js +1 -1
- package/package.json +4 -3
package/README.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
[](https://github.com/squirrelchat/smol-toml/blob/mistress/LICENSE)
|
|
4
4
|
[](https://npm.im/smol-toml)
|
|
5
5
|
|
|
6
|
-
A small, fast, and correct TOML parser. smol-toml is fully(ish) spec-compliant with TOML v1.0.0.
|
|
6
|
+
A small, fast, and correct TOML parser and serializer. smol-toml is fully(ish) spec-compliant with TOML v1.0.0.
|
|
7
7
|
|
|
8
8
|
Why yet another TOML parser? Well, the ecosystem of TOML parsers in JavaScript is quite underwhelming, most likely due
|
|
9
9
|
to a lack of interest. With most parsers being outdated, unmaintained, non-compliant, or a combination of these, a new
|
|
@@ -23,12 +23,13 @@ smol-toml also passes all of the tests in https://github.com/iarna/toml-spec-tes
|
|
|
23
23
|
|
|
24
24
|
<details>
|
|
25
25
|
<summary>List of failed `toml-test` cases</summary>
|
|
26
|
+
|
|
26
27
|
These tests were done by modifying `primitive.ts` and make the implementation return bigints for integers. This allows
|
|
27
28
|
verifying the parser correctly intents a number to be an integer or a float.
|
|
28
29
|
|
|
29
30
|
*Ideally, this becomes an option of the library, but for now...*
|
|
30
31
|
|
|
31
|
-
The following tests are failing:
|
|
32
|
+
The following parse tests are failing:
|
|
32
33
|
- invalid/encoding/bad-utf8-in-comment
|
|
33
34
|
- invalid/encoding/bad-utf8-in-multiline-literal
|
|
34
35
|
- invalid/encoding/bad-utf8-in-multiline
|
|
@@ -44,11 +45,65 @@ The following tests are failing:
|
|
|
44
45
|
|
|
45
46
|
## Usage
|
|
46
47
|
```js
|
|
47
|
-
import { parse } from 'smol-toml'
|
|
48
|
+
import { parse, stringify } from 'smol-toml'
|
|
48
49
|
|
|
49
50
|
const doc = '...'
|
|
50
51
|
const parsed = parse(doc)
|
|
51
52
|
console.log(parsed)
|
|
53
|
+
|
|
54
|
+
const toml = stringify(parsed)
|
|
55
|
+
console.log(toml)
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
A few notes on the `stringify` function:
|
|
59
|
+
- `undefined` and `null` values on objects are ignored (does not produce a key/value).
|
|
60
|
+
- `undefined` and `null` values in arrays are **rejected**.
|
|
61
|
+
- Functions, classes and symbols are **rejected**.
|
|
62
|
+
- floats will be serialized as integers if they don't have a decimal part.
|
|
63
|
+
- `stringify(parse('a = 1.0')) === 'a = 1'`
|
|
64
|
+
- JS `Date` will be serialized as Offset Date Time
|
|
65
|
+
- Use the [`TomlDate` object](#dates) for representing other types.
|
|
66
|
+
|
|
67
|
+
### Dates
|
|
68
|
+
`smol-toml` uses an extended `Date` object to represent all types of TOML Dates. In the future, `smol-toml` will use
|
|
69
|
+
objects from the Temporal proposal, but for now we're stuck with the legacy Date object.
|
|
70
|
+
|
|
71
|
+
```js
|
|
72
|
+
import { TomlDate } from 'smol-toml'
|
|
73
|
+
|
|
74
|
+
// Offset Date Time
|
|
75
|
+
const date = new TomlDate('1979-05-27T07:32:00.000-08:00')
|
|
76
|
+
console.log(date.isDateTime(), date.isDate(), date.isTime(), date.isLocal()) // ~> true, false, false, false
|
|
77
|
+
console.log(date.toISOString()) // ~> 1979-05-27T07:32:00.000-08:00
|
|
78
|
+
|
|
79
|
+
// Local Date Time
|
|
80
|
+
const date = new TomlDate('1979-05-27T07:32:00.000')
|
|
81
|
+
console.log(date.isDateTime(), date.isDate(), date.isTime(), date.isLocal()) // ~> true, false, false, true
|
|
82
|
+
console.log(date.toISOString()) // ~> 1979-05-27T07:32:00.000
|
|
83
|
+
|
|
84
|
+
// Local Date
|
|
85
|
+
const date = new TomlDate('1979-05-27')
|
|
86
|
+
console.log(date.isDateTime(), date.isDate(), date.isTime(), date.isLocal()) // ~> false, true, false, true
|
|
87
|
+
console.log(date.toISOString()) // ~> 1979-05-27
|
|
88
|
+
|
|
89
|
+
// Local Time
|
|
90
|
+
const date = new TomlDate('07:32:00')
|
|
91
|
+
console.log(date.isDateTime(), date.isDate(), date.isTime(), date.isLocal()) // ~> false, false, true, true
|
|
92
|
+
console.log(date.toISOString()) // ~> 07:32:00.000
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
You can also wrap a native `Date` object and specify using different methods depending on the type of date you wish
|
|
96
|
+
to represent:
|
|
97
|
+
|
|
98
|
+
```js
|
|
99
|
+
import { TomlDate } from 'smol-toml'
|
|
100
|
+
|
|
101
|
+
const jsDate = new Date()
|
|
102
|
+
|
|
103
|
+
const offsetDateTime = TomlDate.wrapAsOffsetDateTime(jsDate)
|
|
104
|
+
const localDateTime = TomlDate.wrapAsLocalDateTime(jsDate)
|
|
105
|
+
const localDate = TomlDate.wrapAsLocalDate(jsDate)
|
|
106
|
+
const localTime = TomlDate.wrapAsLocalTime(jsDate)
|
|
52
107
|
```
|
|
53
108
|
|
|
54
109
|
## Performance
|
|
@@ -61,15 +116,20 @@ idea is to have a file relatively close to a real-world application.
|
|
|
61
116
|
|
|
62
117
|
The large TOML generator can be found [here](https://gist.github.com/cyyynthia/e77c744cb6494dabe37d0182506526b9)
|
|
63
118
|
|
|
64
|
-
|
|
|
65
|
-
|
|
66
|
-
| Spec example | **71,356.51 op/s** | 33,629.31 op/s | 16,433.86 op/s
|
|
67
|
-
| ~5MB test file | **3.8091 op/s** | *DNF* | 2.4369 op/s
|
|
119
|
+
| **Parse** | smol-toml | @iarna/toml@3.0.0 | @ltd/j-toml | fast-toml |
|
|
120
|
+
|----------------|---------------------|-------------------|-----------------|-----------------|
|
|
121
|
+
| Spec example | **71,356.51 op/s** | 33,629.31 op/s | 16,433.86 op/s | 29,421.60 op/s |
|
|
122
|
+
| ~5MB test file | **3.8091 op/s** | *DNF* | 2.4369 op/s | 2.6078 op/s |
|
|
123
|
+
|
|
124
|
+
| **Stringify** | smol-toml | @iarna/toml@3.0.0 | @ltd/j-toml |
|
|
125
|
+
|----------------|----------------------|-------------------|----------------|
|
|
126
|
+
| Spec example | **195,191.99 op/s** | 46,583.07 op/s | 5,670.12 op/s |
|
|
127
|
+
| ~5MB test file | **14.6709 op/s** | 3.5941 op/s | 0.7856 op/s |
|
|
68
128
|
|
|
69
129
|
<details>
|
|
70
130
|
<summary>Detailed benchmark data</summary>
|
|
71
131
|
|
|
72
|
-
Tests ran using Vitest v0.31.0 on commit
|
|
132
|
+
Tests ran using Vitest v0.31.0 on commit f58cb6152e667e9cea09f31c93d90652e3b82bf5
|
|
73
133
|
|
|
74
134
|
CPU: Intel Core i7 7700K (4.2GHz)
|
|
75
135
|
|
|
@@ -87,6 +147,16 @@ CPU: Intel Core i7 7700K (4.2GHz)
|
|
|
87
147
|
· smol-toml 3.8091 239.60 287.30 262.53 274.17 287.30 287.30 287.30 ±3.66% 10 fastest
|
|
88
148
|
· @ltd/j-toml 2.4369 376.73 493.49 410.35 442.58 493.49 493.49 493.49 ±7.08% 10 slowest
|
|
89
149
|
· fast-toml 2.6078 373.88 412.79 383.47 388.62 412.79 412.79 412.79 ±2.72% 10
|
|
150
|
+
✓ bench/stringifySpecExample.bench.ts (3) 1886ms
|
|
151
|
+
name hz min max mean p75 p99 p995 p999 rme samples
|
|
152
|
+
· smol-toml 195,191.99 0.0047 0.2704 0.0051 0.0050 0.0099 0.0110 0.0152 ±0.41% 97596 fastest
|
|
153
|
+
· @iarna/toml 46,583.07 0.0197 0.2808 0.0215 0.0208 0.0448 0.0470 0.1704 ±0.47% 23292
|
|
154
|
+
· @ltd/j-toml 5,670.12 0.1613 0.5768 0.1764 0.1726 0.3036 0.3129 0.4324 ±0.56% 2836 slowest
|
|
155
|
+
✓ bench/stringifyLargeMixed.bench.ts (3) 24057ms
|
|
156
|
+
name hz min max mean p75 p99 p995 p999 rme samples
|
|
157
|
+
· smol-toml 14.6709 65.1071 79.2199 68.1623 67.1088 79.2199 79.2199 79.2199 ±5.25% 10 fastest
|
|
158
|
+
· @iarna/toml 3.5941 266.48 295.24 278.24 290.10 295.24 295.24 295.24 ±2.83% 10
|
|
159
|
+
· @ltd/j-toml 0.7856 1,254.33 1,322.05 1,272.87 1,286.82 1,322.05 1,322.05 1,322.05 ±1.37% 10 slowest
|
|
90
160
|
|
|
91
161
|
|
|
92
162
|
BENCH Summary
|
|
@@ -99,6 +169,14 @@ CPU: Intel Core i7 7700K (4.2GHz)
|
|
|
99
169
|
2.12x faster than @iarna/toml
|
|
100
170
|
2.43x faster than fast-toml
|
|
101
171
|
4.34x faster than @ltd/j-toml
|
|
172
|
+
|
|
173
|
+
smol-toml - bench/stringifyLargeMixed.bench.ts >
|
|
174
|
+
4.00x faster than @iarna/toml
|
|
175
|
+
18.33x faster than @ltd/j-toml
|
|
176
|
+
|
|
177
|
+
smol-toml - bench/stringifySpecExample.bench.ts >
|
|
178
|
+
4.19x faster than @iarna/toml
|
|
179
|
+
34.42x faster than @ltd/j-toml
|
|
102
180
|
```
|
|
103
181
|
|
|
104
182
|
---
|
|
@@ -111,7 +189,7 @@ I initially reported this to the library author, but the author decided to
|
|
|
111
189
|
- b) [delete the issue](https://github.com/huan231/toml-nodejs/issues/12) when pointed out links to the NodeJS
|
|
112
190
|
documentation about the flag removal and standard resolution algorithm.
|
|
113
191
|
|
|
114
|
-
For the reference anyways, `toml-nodejs` (with proper imports) is ~8x slower on both benchmark with:
|
|
192
|
+
For the reference anyways, `toml-nodejs` (with proper imports) is ~8x slower on both parse benchmark with:
|
|
115
193
|
- spec example: 7,543.47 op/s
|
|
116
194
|
- 5mb mixed: 0.7006 op/s
|
|
117
195
|
</details>
|
package/dist/date.js
CHANGED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright (c) Squirrel Chat et al., All rights reserved.
|
|
3
|
+
* SPDX-License-Identifier: BSD-3-Clause
|
|
4
|
+
*
|
|
5
|
+
* Redistribution and use in source and binary forms, with or without
|
|
6
|
+
* modification, are permitted provided that the following conditions are met:
|
|
7
|
+
*
|
|
8
|
+
* 1. Redistributions of source code must retain the above copyright notice, this
|
|
9
|
+
* list of conditions and the following disclaimer.
|
|
10
|
+
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
|
11
|
+
* this list of conditions and the following disclaimer in the
|
|
12
|
+
* documentation and/or other materials provided with the distribution.
|
|
13
|
+
* 3. Neither the name of the copyright holder nor the names of its contributors
|
|
14
|
+
* may be used to endorse or promote products derived from this software without
|
|
15
|
+
* specific prior written permission.
|
|
16
|
+
*
|
|
17
|
+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
18
|
+
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
19
|
+
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
20
|
+
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
21
|
+
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
22
|
+
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
23
|
+
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
24
|
+
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
25
|
+
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
26
|
+
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
27
|
+
*/
|
|
28
|
+
import { type TomlPrimitive } from './util.js';
|
|
29
|
+
export declare function extractValue(str: string, ptr: number, end?: string): [TomlPrimitive, number];
|
package/dist/extract.js
ADDED
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright (c) Squirrel Chat et al., All rights reserved.
|
|
3
|
+
* SPDX-License-Identifier: BSD-3-Clause
|
|
4
|
+
*
|
|
5
|
+
* Redistribution and use in source and binary forms, with or without
|
|
6
|
+
* modification, are permitted provided that the following conditions are met:
|
|
7
|
+
*
|
|
8
|
+
* 1. Redistributions of source code must retain the above copyright notice, this
|
|
9
|
+
* list of conditions and the following disclaimer.
|
|
10
|
+
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
|
11
|
+
* this list of conditions and the following disclaimer in the
|
|
12
|
+
* documentation and/or other materials provided with the distribution.
|
|
13
|
+
* 3. Neither the name of the copyright holder nor the names of its contributors
|
|
14
|
+
* may be used to endorse or promote products derived from this software without
|
|
15
|
+
* specific prior written permission.
|
|
16
|
+
*
|
|
17
|
+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
18
|
+
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
19
|
+
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
20
|
+
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
21
|
+
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
22
|
+
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
23
|
+
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
24
|
+
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
25
|
+
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
26
|
+
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
27
|
+
*/
|
|
28
|
+
import { parseString, parseValue } from './primitive.js';
|
|
29
|
+
import { parseArray, parseInlineTable } from './struct.js';
|
|
30
|
+
import { indexOfNewline, skipVoid, skipUntil, skipComment, getStringEnd } from './util.js';
|
|
31
|
+
import TomlError from './error.js';
|
|
32
|
+
function sliceAndTrimEndOf(str, startPtr, endPtr, allowNewLines) {
|
|
33
|
+
let value = str.slice(startPtr, endPtr);
|
|
34
|
+
let commentIdx = value.indexOf('#');
|
|
35
|
+
if (commentIdx > -1) {
|
|
36
|
+
// The call to skipComment allows to "validate" the comment
|
|
37
|
+
// (absence of control characters)
|
|
38
|
+
skipComment(str, commentIdx);
|
|
39
|
+
value = value.slice(0, commentIdx);
|
|
40
|
+
}
|
|
41
|
+
let trimmed = value.trimEnd();
|
|
42
|
+
if (!allowNewLines) {
|
|
43
|
+
let newlineIdx = value.indexOf('\n', trimmed.length);
|
|
44
|
+
if (newlineIdx > -1) {
|
|
45
|
+
throw new TomlError('newlines are not allowed in inline tables', {
|
|
46
|
+
toml: str,
|
|
47
|
+
ptr: startPtr + newlineIdx
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return [trimmed, commentIdx];
|
|
52
|
+
}
|
|
53
|
+
export function extractValue(str, ptr, end) {
|
|
54
|
+
let c = str[ptr];
|
|
55
|
+
if (c === '[' || c === '{') {
|
|
56
|
+
let [value, endPtr] = c === '['
|
|
57
|
+
? parseArray(str, ptr)
|
|
58
|
+
: parseInlineTable(str, ptr);
|
|
59
|
+
let newPtr = skipUntil(str, endPtr, ',', end);
|
|
60
|
+
if (end === '}') {
|
|
61
|
+
let nextNewLine = indexOfNewline(str, endPtr, newPtr);
|
|
62
|
+
if (nextNewLine > -1) {
|
|
63
|
+
throw new TomlError('newlines are not allowed in inline tables', {
|
|
64
|
+
toml: str,
|
|
65
|
+
ptr: nextNewLine
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
return [value, newPtr];
|
|
70
|
+
}
|
|
71
|
+
let endPtr;
|
|
72
|
+
if (c === '"' || c === "'") {
|
|
73
|
+
endPtr = getStringEnd(str, ptr);
|
|
74
|
+
return [parseString(str, ptr, endPtr), endPtr + +(!!end && str[endPtr] === ',')];
|
|
75
|
+
}
|
|
76
|
+
endPtr = skipUntil(str, ptr, ',', end);
|
|
77
|
+
let slice = sliceAndTrimEndOf(str, ptr, endPtr - (+(str[endPtr - 1] === ',')), end === ']');
|
|
78
|
+
if (!slice[0]) {
|
|
79
|
+
throw new TomlError('incomplete key-value declaration: no value specified', {
|
|
80
|
+
toml: str,
|
|
81
|
+
ptr: ptr
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
if (end && slice[1] > -1) {
|
|
85
|
+
endPtr = skipVoid(str, ptr + slice[1]);
|
|
86
|
+
endPtr += +(str[endPtr] === ',');
|
|
87
|
+
}
|
|
88
|
+
return [
|
|
89
|
+
parseValue(slice[0], str, ptr),
|
|
90
|
+
endPtr,
|
|
91
|
+
];
|
|
92
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -25,6 +25,7 @@
|
|
|
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
|
-
|
|
28
|
+
export { default as TomlError } from './error.js';
|
|
29
29
|
export { default as TomlDate } from './date.js';
|
|
30
|
-
export
|
|
30
|
+
export { parse } from './parse.js';
|
|
31
|
+
export { stringify } from './stringify.js';
|
package/dist/index.js
CHANGED
|
@@ -25,125 +25,7 @@
|
|
|
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
|
-
|
|
29
|
-
import { extractValue } from './parse.js';
|
|
30
|
-
import { skipVoid } from './util.js';
|
|
31
|
-
import TomlError from './error.js';
|
|
28
|
+
export { default as TomlError } from './error.js';
|
|
32
29
|
export { default as TomlDate } from './date.js';
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
let m = meta;
|
|
36
|
-
let k;
|
|
37
|
-
let hasOwn = false;
|
|
38
|
-
let state;
|
|
39
|
-
for (let i = 0; i < key.length; i++) {
|
|
40
|
-
if (i) {
|
|
41
|
-
t = hasOwn ? t[k] : (t[k] = {});
|
|
42
|
-
m = (state = m[k]).c;
|
|
43
|
-
if (type === 0 /* Type.DOTTED */ && state.t === 1 /* Type.EXPLICIT */) {
|
|
44
|
-
return null;
|
|
45
|
-
}
|
|
46
|
-
if (state.t === 2 /* Type.ARRAY */) {
|
|
47
|
-
let l = t.length - 1;
|
|
48
|
-
t = t[l];
|
|
49
|
-
m = m[l].c;
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
k = key[i];
|
|
53
|
-
if ((hasOwn = Object.hasOwn(t, k)) && m[k]?.t === 0 /* Type.DOTTED */ && m[k]?.d) {
|
|
54
|
-
return null;
|
|
55
|
-
}
|
|
56
|
-
if (!hasOwn) {
|
|
57
|
-
if (k === '__proto__') {
|
|
58
|
-
Object.defineProperty(t, k, { enumerable: true, configurable: true, writable: true });
|
|
59
|
-
Object.defineProperty(m, k, { enumerable: true, configurable: true, writable: true });
|
|
60
|
-
}
|
|
61
|
-
m[k] = {
|
|
62
|
-
t: i < key.length - 1 && type === 2 /* Type.ARRAY */
|
|
63
|
-
? 0 /* Type.DOTTED */
|
|
64
|
-
: type,
|
|
65
|
-
d: false,
|
|
66
|
-
i: 0,
|
|
67
|
-
c: {},
|
|
68
|
-
};
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
state = m[k];
|
|
72
|
-
if (state.t !== type) {
|
|
73
|
-
// Bad key type!
|
|
74
|
-
return null;
|
|
75
|
-
}
|
|
76
|
-
if (type === 2 /* Type.ARRAY */) {
|
|
77
|
-
if (!state.d) {
|
|
78
|
-
state.d = true;
|
|
79
|
-
t[k] = [];
|
|
80
|
-
}
|
|
81
|
-
t[k].push(t = {});
|
|
82
|
-
state.c[state.i++] = (state = { t: 1 /* Type.EXPLICIT */, d: false, i: 0, c: {} });
|
|
83
|
-
}
|
|
84
|
-
if (state.d) {
|
|
85
|
-
// Redefining a table!
|
|
86
|
-
return null;
|
|
87
|
-
}
|
|
88
|
-
state.d = true;
|
|
89
|
-
if (type === 1 /* Type.EXPLICIT */) {
|
|
90
|
-
t = hasOwn ? t[k] : (t[k] = {});
|
|
91
|
-
}
|
|
92
|
-
else if (type === 0 /* Type.DOTTED */ && hasOwn) {
|
|
93
|
-
return null;
|
|
94
|
-
}
|
|
95
|
-
return [k, t, state.c];
|
|
96
|
-
}
|
|
97
|
-
export function parse(toml) {
|
|
98
|
-
let res = {};
|
|
99
|
-
let meta = {};
|
|
100
|
-
let tbl = res;
|
|
101
|
-
let m = meta;
|
|
102
|
-
for (let ptr = skipVoid(toml, 0); ptr < toml.length;) {
|
|
103
|
-
if (toml[ptr] === '[') {
|
|
104
|
-
let isTableArray = toml[++ptr] === '[';
|
|
105
|
-
let k = parseKey(toml, ptr += +isTableArray, ']');
|
|
106
|
-
if (isTableArray) {
|
|
107
|
-
if (toml[k[1] - 1] !== ']') {
|
|
108
|
-
throw new TomlError('expected end of table declaration', {
|
|
109
|
-
toml: toml,
|
|
110
|
-
ptr: k[1] - 1,
|
|
111
|
-
});
|
|
112
|
-
}
|
|
113
|
-
k[1]++;
|
|
114
|
-
}
|
|
115
|
-
let p = peekTable(k[0], res, meta, isTableArray ? 2 /* Type.ARRAY */ : 1 /* Type.EXPLICIT */);
|
|
116
|
-
if (!p) {
|
|
117
|
-
throw new TomlError('trying to redefine an already defined table or value', {
|
|
118
|
-
toml: toml,
|
|
119
|
-
ptr: ptr,
|
|
120
|
-
});
|
|
121
|
-
}
|
|
122
|
-
m = p[2];
|
|
123
|
-
tbl = p[1];
|
|
124
|
-
ptr = k[1];
|
|
125
|
-
}
|
|
126
|
-
else {
|
|
127
|
-
let k = parseKey(toml, ptr);
|
|
128
|
-
let p = peekTable(k[0], tbl, m, 0 /* Type.DOTTED */);
|
|
129
|
-
if (!p) {
|
|
130
|
-
throw new TomlError('trying to redefine an already defined table or value', {
|
|
131
|
-
toml: toml,
|
|
132
|
-
ptr: ptr,
|
|
133
|
-
});
|
|
134
|
-
}
|
|
135
|
-
let v = extractValue(toml, k[1]);
|
|
136
|
-
p[1][p[0]] = v[0];
|
|
137
|
-
ptr = v[1];
|
|
138
|
-
}
|
|
139
|
-
ptr = skipVoid(toml, ptr, true);
|
|
140
|
-
if (toml[ptr] && toml[ptr] !== '\n' && toml[ptr] !== '\r') {
|
|
141
|
-
throw new TomlError('each key-value declaration must be followed by an end-of-line', {
|
|
142
|
-
toml: toml,
|
|
143
|
-
ptr: ptr
|
|
144
|
-
});
|
|
145
|
-
}
|
|
146
|
-
ptr = skipVoid(toml, ptr);
|
|
147
|
-
}
|
|
148
|
-
return res;
|
|
149
|
-
}
|
|
30
|
+
export { parse } from './parse.js';
|
|
31
|
+
export { stringify } from './stringify.js';
|
package/dist/parse.d.ts
CHANGED
|
@@ -26,4 +26,4 @@
|
|
|
26
26
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
27
27
|
*/
|
|
28
28
|
import { type TomlPrimitive } from './util.js';
|
|
29
|
-
export declare function
|
|
29
|
+
export declare function parse(toml: string): Record<string, TomlPrimitive>;
|
package/dist/parse.js
CHANGED
|
@@ -25,68 +25,124 @@
|
|
|
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 {
|
|
29
|
-
import {
|
|
30
|
-
import {
|
|
28
|
+
import { parseKey } from './struct.js';
|
|
29
|
+
import { extractValue } from './extract.js';
|
|
30
|
+
import { skipVoid } from './util.js';
|
|
31
31
|
import TomlError from './error.js';
|
|
32
|
-
function
|
|
33
|
-
let
|
|
34
|
-
let
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
32
|
+
function peekTable(key, table, meta, type) {
|
|
33
|
+
let t = table;
|
|
34
|
+
let m = meta;
|
|
35
|
+
let k;
|
|
36
|
+
let hasOwn = false;
|
|
37
|
+
let state;
|
|
38
|
+
for (let i = 0; i < key.length; i++) {
|
|
39
|
+
if (i) {
|
|
40
|
+
t = hasOwn ? t[k] : (t[k] = {});
|
|
41
|
+
m = (state = m[k]).c;
|
|
42
|
+
if (type === 0 /* Type.DOTTED */ && state.t === 1 /* Type.EXPLICIT */) {
|
|
43
|
+
return null;
|
|
44
|
+
}
|
|
45
|
+
if (state.t === 2 /* Type.ARRAY */) {
|
|
46
|
+
let l = t.length - 1;
|
|
47
|
+
t = t[l];
|
|
48
|
+
m = m[l].c;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
k = key[i];
|
|
52
|
+
if ((hasOwn = Object.hasOwn(t, k)) && m[k]?.t === 0 /* Type.DOTTED */ && m[k]?.d) {
|
|
53
|
+
return null;
|
|
54
|
+
}
|
|
55
|
+
if (!hasOwn) {
|
|
56
|
+
if (k === '__proto__') {
|
|
57
|
+
Object.defineProperty(t, k, { enumerable: true, configurable: true, writable: true });
|
|
58
|
+
Object.defineProperty(m, k, { enumerable: true, configurable: true, writable: true });
|
|
59
|
+
}
|
|
60
|
+
m[k] = {
|
|
61
|
+
t: i < key.length - 1 && type === 2 /* Type.ARRAY */
|
|
62
|
+
? 0 /* Type.DOTTED */
|
|
63
|
+
: type,
|
|
64
|
+
d: false,
|
|
65
|
+
i: 0,
|
|
66
|
+
c: {},
|
|
67
|
+
};
|
|
68
|
+
}
|
|
40
69
|
}
|
|
41
|
-
|
|
42
|
-
if (
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
70
|
+
state = m[k];
|
|
71
|
+
if (state.t !== type) {
|
|
72
|
+
// Bad key type!
|
|
73
|
+
return null;
|
|
74
|
+
}
|
|
75
|
+
if (type === 2 /* Type.ARRAY */) {
|
|
76
|
+
if (!state.d) {
|
|
77
|
+
state.d = true;
|
|
78
|
+
t[k] = [];
|
|
49
79
|
}
|
|
80
|
+
t[k].push(t = {});
|
|
81
|
+
state.c[state.i++] = (state = { t: 1 /* Type.EXPLICIT */, d: false, i: 0, c: {} });
|
|
82
|
+
}
|
|
83
|
+
if (state.d) {
|
|
84
|
+
// Redefining a table!
|
|
85
|
+
return null;
|
|
86
|
+
}
|
|
87
|
+
state.d = true;
|
|
88
|
+
if (type === 1 /* Type.EXPLICIT */) {
|
|
89
|
+
t = hasOwn ? t[k] : (t[k] = {});
|
|
50
90
|
}
|
|
51
|
-
|
|
91
|
+
else if (type === 0 /* Type.DOTTED */ && hasOwn) {
|
|
92
|
+
return null;
|
|
93
|
+
}
|
|
94
|
+
return [k, t, state.c];
|
|
52
95
|
}
|
|
53
|
-
export function
|
|
54
|
-
let
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
let
|
|
62
|
-
if (
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
96
|
+
export function parse(toml) {
|
|
97
|
+
let res = {};
|
|
98
|
+
let meta = {};
|
|
99
|
+
let tbl = res;
|
|
100
|
+
let m = meta;
|
|
101
|
+
for (let ptr = skipVoid(toml, 0); ptr < toml.length;) {
|
|
102
|
+
if (toml[ptr] === '[') {
|
|
103
|
+
let isTableArray = toml[++ptr] === '[';
|
|
104
|
+
let k = parseKey(toml, ptr += +isTableArray, ']');
|
|
105
|
+
if (isTableArray) {
|
|
106
|
+
if (toml[k[1] - 1] !== ']') {
|
|
107
|
+
throw new TomlError('expected end of table declaration', {
|
|
108
|
+
toml: toml,
|
|
109
|
+
ptr: k[1] - 1,
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
k[1]++;
|
|
113
|
+
}
|
|
114
|
+
let p = peekTable(k[0], res, meta, isTableArray ? 2 /* Type.ARRAY */ : 1 /* Type.EXPLICIT */);
|
|
115
|
+
if (!p) {
|
|
116
|
+
throw new TomlError('trying to redefine an already defined table or value', {
|
|
117
|
+
toml: toml,
|
|
118
|
+
ptr: ptr,
|
|
66
119
|
});
|
|
67
120
|
}
|
|
121
|
+
m = p[2];
|
|
122
|
+
tbl = p[1];
|
|
123
|
+
ptr = k[1];
|
|
68
124
|
}
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
125
|
+
else {
|
|
126
|
+
let k = parseKey(toml, ptr);
|
|
127
|
+
let p = peekTable(k[0], tbl, m, 0 /* Type.DOTTED */);
|
|
128
|
+
if (!p) {
|
|
129
|
+
throw new TomlError('trying to redefine an already defined table or value', {
|
|
130
|
+
toml: toml,
|
|
131
|
+
ptr: ptr,
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
let v = extractValue(toml, k[1]);
|
|
135
|
+
p[1][p[0]] = v[0];
|
|
136
|
+
ptr = v[1];
|
|
137
|
+
}
|
|
138
|
+
ptr = skipVoid(toml, ptr, true);
|
|
139
|
+
if (toml[ptr] && toml[ptr] !== '\n' && toml[ptr] !== '\r') {
|
|
140
|
+
throw new TomlError('each key-value declaration must be followed by an end-of-line', {
|
|
141
|
+
toml: toml,
|
|
142
|
+
ptr: ptr
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
ptr = skipVoid(toml, ptr);
|
|
87
146
|
}
|
|
88
|
-
return
|
|
89
|
-
parseValue(slice[0], str, ptr),
|
|
90
|
-
endPtr,
|
|
91
|
-
];
|
|
147
|
+
return res;
|
|
92
148
|
}
|
package/dist/primitive.js
CHANGED
|
@@ -135,10 +135,10 @@ export function parseValue(value, toml, ptr) {
|
|
|
135
135
|
return Infinity;
|
|
136
136
|
if (value === 'nan' || value === '+nan' || value === '-nan')
|
|
137
137
|
return NaN;
|
|
138
|
-
// Numbers
|
|
139
|
-
let isInt;
|
|
140
138
|
if (value === '-0')
|
|
141
139
|
return 0; // Avoid FP representation of -0
|
|
140
|
+
// Numbers
|
|
141
|
+
let isInt;
|
|
142
142
|
if ((isInt = INT_REGEX.test(value)) || FLOAT_REGEX.test(value)) {
|
|
143
143
|
if (LEADING_ZERO.test(value)) {
|
|
144
144
|
throw new TomlError('leading zeroes are not allowed', {
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright (c) Squirrel Chat et al., All rights reserved.
|
|
3
|
+
* SPDX-License-Identifier: BSD-3-Clause
|
|
4
|
+
*
|
|
5
|
+
* Redistribution and use in source and binary forms, with or without
|
|
6
|
+
* modification, are permitted provided that the following conditions are met:
|
|
7
|
+
*
|
|
8
|
+
* 1. Redistributions of source code must retain the above copyright notice, this
|
|
9
|
+
* list of conditions and the following disclaimer.
|
|
10
|
+
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
|
11
|
+
* this list of conditions and the following disclaimer in the
|
|
12
|
+
* documentation and/or other materials provided with the distribution.
|
|
13
|
+
* 3. Neither the name of the copyright holder nor the names of its contributors
|
|
14
|
+
* may be used to endorse or promote products derived from this software without
|
|
15
|
+
* specific prior written permission.
|
|
16
|
+
*
|
|
17
|
+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
18
|
+
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
19
|
+
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
20
|
+
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
21
|
+
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
22
|
+
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
23
|
+
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
24
|
+
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
25
|
+
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
26
|
+
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
27
|
+
*/
|
|
28
|
+
export declare function stringify(obj: any): string;
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright (c) Squirrel Chat et al., All rights reserved.
|
|
3
|
+
* SPDX-License-Identifier: BSD-3-Clause
|
|
4
|
+
*
|
|
5
|
+
* Redistribution and use in source and binary forms, with or without
|
|
6
|
+
* modification, are permitted provided that the following conditions are met:
|
|
7
|
+
*
|
|
8
|
+
* 1. Redistributions of source code must retain the above copyright notice, this
|
|
9
|
+
* list of conditions and the following disclaimer.
|
|
10
|
+
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
|
11
|
+
* this list of conditions and the following disclaimer in the
|
|
12
|
+
* documentation and/or other materials provided with the distribution.
|
|
13
|
+
* 3. Neither the name of the copyright holder nor the names of its contributors
|
|
14
|
+
* may be used to endorse or promote products derived from this software without
|
|
15
|
+
* specific prior written permission.
|
|
16
|
+
*
|
|
17
|
+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
18
|
+
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
19
|
+
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
20
|
+
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
21
|
+
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
22
|
+
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
23
|
+
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
24
|
+
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
25
|
+
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
26
|
+
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
27
|
+
*/
|
|
28
|
+
const BARE_KEY = /^[a-z0-9-_]+$/i;
|
|
29
|
+
function extendedTypeOf(obj) {
|
|
30
|
+
let type = typeof obj;
|
|
31
|
+
if (type === 'object') {
|
|
32
|
+
if (Array.isArray(obj))
|
|
33
|
+
return 'array';
|
|
34
|
+
if (obj instanceof Date)
|
|
35
|
+
return 'date';
|
|
36
|
+
}
|
|
37
|
+
return type;
|
|
38
|
+
}
|
|
39
|
+
function isArrayOfTables(obj) {
|
|
40
|
+
for (let i = 0; i < obj.length; i++) {
|
|
41
|
+
if (extendedTypeOf(obj[i]) !== 'object')
|
|
42
|
+
return false;
|
|
43
|
+
}
|
|
44
|
+
return true;
|
|
45
|
+
}
|
|
46
|
+
function formatString(s) {
|
|
47
|
+
return JSON.stringify(s).replace(/\x7f/g, '\\u007f');
|
|
48
|
+
}
|
|
49
|
+
function stringifyValue(val, type = extendedTypeOf(val)) {
|
|
50
|
+
if (type === 'number') {
|
|
51
|
+
if (isNaN(val))
|
|
52
|
+
return 'nan';
|
|
53
|
+
if (val === Infinity)
|
|
54
|
+
return 'inf';
|
|
55
|
+
if (val === -Infinity)
|
|
56
|
+
return '-inf';
|
|
57
|
+
return val.toString();
|
|
58
|
+
}
|
|
59
|
+
if (type === 'bigint' || type === 'boolean') {
|
|
60
|
+
return val.toString();
|
|
61
|
+
}
|
|
62
|
+
if (type === 'string') {
|
|
63
|
+
return formatString(val);
|
|
64
|
+
}
|
|
65
|
+
if (type === 'date') {
|
|
66
|
+
if (isNaN(val.getTime())) {
|
|
67
|
+
throw new TypeError('cannot serialize invalid date');
|
|
68
|
+
}
|
|
69
|
+
return val.toISOString();
|
|
70
|
+
}
|
|
71
|
+
if (type === 'object') {
|
|
72
|
+
return stringifyInlineTable(val);
|
|
73
|
+
}
|
|
74
|
+
if (type === 'array') {
|
|
75
|
+
return stringifyArray(val);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
function stringifyInlineTable(obj) {
|
|
79
|
+
let res = '{ ';
|
|
80
|
+
let keys = Object.keys(obj);
|
|
81
|
+
for (let i = 0; i < keys.length; i++) {
|
|
82
|
+
let k = keys[i];
|
|
83
|
+
if (i)
|
|
84
|
+
res += ', ';
|
|
85
|
+
res += BARE_KEY.test(k) ? k : formatString(k);
|
|
86
|
+
res += ' = ';
|
|
87
|
+
res += stringifyValue(obj[k]);
|
|
88
|
+
}
|
|
89
|
+
return res + ' }';
|
|
90
|
+
}
|
|
91
|
+
function stringifyArray(array) {
|
|
92
|
+
let res = '[ ';
|
|
93
|
+
for (let i = 0; i < array.length; i++) {
|
|
94
|
+
if (i)
|
|
95
|
+
res += ', ';
|
|
96
|
+
if (array[i] === null || array[i] === void 0) {
|
|
97
|
+
throw new TypeError('arrays cannot contain null or undefined values');
|
|
98
|
+
}
|
|
99
|
+
res += stringifyValue(array[i]);
|
|
100
|
+
}
|
|
101
|
+
return res + ' ]';
|
|
102
|
+
}
|
|
103
|
+
function stringifyArrayTable(array, key) {
|
|
104
|
+
let res = '';
|
|
105
|
+
for (let i = 0; i < array.length; i++) {
|
|
106
|
+
res += `[[${key}]]\n`;
|
|
107
|
+
res += stringifyTable(array[i], key);
|
|
108
|
+
res += '\n\n';
|
|
109
|
+
}
|
|
110
|
+
return res;
|
|
111
|
+
}
|
|
112
|
+
function stringifyTable(obj, prefix = '') {
|
|
113
|
+
let preamble = '';
|
|
114
|
+
let tables = '';
|
|
115
|
+
let keys = Object.keys(obj);
|
|
116
|
+
for (let i = 0; i < keys.length; i++) {
|
|
117
|
+
let k = keys[i];
|
|
118
|
+
if (obj[k] !== null && obj[k] !== void 0) {
|
|
119
|
+
let type = extendedTypeOf(obj[k]);
|
|
120
|
+
if (type === 'symbol' || type === 'function') {
|
|
121
|
+
throw new TypeError(`cannot serialize values of type '${type}'`);
|
|
122
|
+
}
|
|
123
|
+
let key = BARE_KEY.test(k) ? k : formatString(k);
|
|
124
|
+
if (type === 'array' && isArrayOfTables(obj[k])) {
|
|
125
|
+
tables += stringifyArrayTable(obj[k], prefix ? `${prefix}.${key}` : key);
|
|
126
|
+
}
|
|
127
|
+
else if (type === 'object') {
|
|
128
|
+
let tblKey = prefix ? `${prefix}.${key}` : key;
|
|
129
|
+
tables += `[${tblKey}]\n`;
|
|
130
|
+
tables += stringifyTable(obj[k], tblKey);
|
|
131
|
+
tables += '\n\n';
|
|
132
|
+
}
|
|
133
|
+
else {
|
|
134
|
+
preamble += key;
|
|
135
|
+
preamble += ' = ';
|
|
136
|
+
preamble += stringifyValue(obj[k], type);
|
|
137
|
+
preamble += '\n';
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
return `${preamble}\n${tables}`.trim();
|
|
142
|
+
}
|
|
143
|
+
export function stringify(obj) {
|
|
144
|
+
if (extendedTypeOf(obj) !== 'object') {
|
|
145
|
+
throw new TypeError('stringify can only be called with an object');
|
|
146
|
+
}
|
|
147
|
+
return stringifyTable(obj);
|
|
148
|
+
}
|
package/dist/struct.js
CHANGED
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
27
27
|
*/
|
|
28
28
|
import { parseString } from './primitive.js';
|
|
29
|
-
import { extractValue } from './
|
|
29
|
+
import { extractValue } from './extract.js';
|
|
30
30
|
import { skipComment, indexOfNewline, getStringEnd, skipVoid } from './util.js';
|
|
31
31
|
import TomlError from './error.js';
|
|
32
32
|
let KEY_PART_RE = /^[a-zA-Z0-9-_]+[ \t]*$/;
|
package/package.json
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "smol-toml",
|
|
3
|
-
"version": "1.0
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"keywords": [
|
|
5
5
|
"toml",
|
|
6
|
-
"parser"
|
|
6
|
+
"parser",
|
|
7
|
+
"serializer"
|
|
7
8
|
],
|
|
8
|
-
"description": "A small, fast, and correct TOML parser",
|
|
9
|
+
"description": "A small, fast, and correct TOML parser/serializer",
|
|
9
10
|
"repository": "git@github.com:squirrelchat/smol-toml.git",
|
|
10
11
|
"author": "Cynthia <cyyynthia@borkenware.com>",
|
|
11
12
|
"license": "BSD-3-Clause",
|