smol-toml 1.1.4 → 1.2.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/LICENSE CHANGED
File without changes
package/README.md CHANGED
@@ -2,6 +2,7 @@
2
2
  [![TOML 1.0.0](https://img.shields.io/badge/TOML-1.0.0-9c4221?style=flat-square)](https://toml.io/en/v1.0.0)
3
3
  [![License](https://img.shields.io/github/license/squirrelchat/smol-toml.svg?style=flat-square)](https://github.com/squirrelchat/smol-toml/blob/mistress/LICENSE)
4
4
  [![npm](https://img.shields.io/npm/v/smol-toml?style=flat-square)](https://npm.im/smol-toml)
5
+ [![Build](https://img.shields.io/github/actions/workflow/status/squirrelchat/smol-toml/build.yml?style=flat-square&logo=github)](https://github.com/squirrelchat/smol-toml/actions/workflows/build.yml)
5
6
 
6
7
  A small, fast, and correct TOML parser and serializer. smol-toml is fully(ish) spec-compliant with TOML v1.0.0.
7
8
 
@@ -11,32 +12,20 @@ parser didn't feel too out of place.
11
12
 
12
13
  *[insert xkcd 927]*
13
14
 
14
- smol-toml passes most of the tests from [BurntSushi's `toml-test` suite](https://github.com/BurntSushi/toml-test).
15
- However, due to the nature of JavaScript and the limits of the language, it doesn't pass certain tests, namely:
15
+ smol-toml passes most of the tests from the [`toml-test` suite](https://github.com/toml-lang/toml-test); use the
16
+ `run-toml-test.bash` script to run the tests. Due to the nature of JavaScript and the limits of the language,
17
+ it doesn't pass certain tests, namely:
16
18
  - Invalid UTF-8 strings are not rejected
17
19
  - Certain invalid UTF-8 codepoints are not rejected
20
+ - Certain invalid dates are not rejected
21
+ - For instance, `2023-02-30` would be accepted and parsed as `2023-03-02`. While additional checks could be performed
22
+ to reject these, they've not been added for performance reasons.
18
23
  - smol-toml doesn't preserve type information between integers and floats (in JS, everything is a float)
19
- - smol-toml doesn't support the whole 64-bit range for integers (but does throw an appropriate error)
20
- - As all numbers are floats in JS, the safe range is `2**53 - 1` <=> `-(2**53 - 1)`.
21
24
 
22
- smol-toml also passes all of the tests in https://github.com/iarna/toml-spec-tests.
23
-
24
- <details>
25
- <summary>List of failed `toml-test` cases</summary>
26
-
27
- These tests were done by modifying `primitive.ts` and make the implementation return bigints for integers. This allows
28
- verifying the parser correctly intents a number to be an integer or a float.
29
-
30
- *Ideally, this becomes an option of the library, but for now...*
31
-
32
- The following parse tests are failing:
33
- - invalid/encoding/bad-utf8-in-comment
34
- - invalid/encoding/bad-utf8-in-multiline-literal
35
- - invalid/encoding/bad-utf8-in-multiline
36
- - invalid/encoding/bad-utf8-in-string-literal
37
- - invalid/encoding/bad-utf8-in-string
38
- - invalid/string/bad-codepoint
39
- </details>
25
+ You can see a list of all tests smol-toml fails (and the reason why it fails these) in the list of skipped tests in
26
+ `run-toml-test.bash`. Note that some failures are *not* specification violations per-se. For instance, the TOML spec
27
+ does not require 64-bit integer range support or sub-millisecond time precision, but are included in the `toml-test`
28
+ suite. See https://github.com/toml-lang/toml-test/issues/154 and https://github.com/toml-lang/toml-test/issues/155
40
29
 
41
30
  ## Installation
42
31
  ```
@@ -55,6 +44,13 @@ const toml = stringify(parsed)
55
44
  console.log(toml)
56
45
  ```
57
46
 
47
+ Alternatively, if you prefer something similar to the JSON global, you can import the library as follows
48
+ ```js
49
+ import TOML from 'smol-toml'
50
+
51
+ TOML.stringify({ ... })
52
+ ```
53
+
58
54
  A few notes on the `stringify` function:
59
55
  - `undefined` and `null` values on objects are ignored (does not produce a key/value).
60
56
  - `undefined` and `null` values in arrays are **rejected**.
@@ -109,10 +105,11 @@ const localTime = TomlDate.wrapAsLocalTime(jsDate)
109
105
  ## Performance
110
106
  A note on these performance numbers: in some highly synthetic tests, other parsers such as `fast-toml` greatly
111
107
  outperform other parsers, mostly due to their lack of compliance with the spec. For example, to parse a string,
112
- `fast-toml` skips the entire string while `smol-toml` does validate the string, costing a fair chair of performance.
108
+ `fast-toml` skips the entire string while `smol-toml` does validate the string, costing a fair share of performance.
113
109
 
114
- The ~5MB test file used for benchmark here is filled with random data which attempts to be close-ish to reality. The
115
- idea is to have a file relatively close to a real-world application.
110
+ The ~5MB test file used for benchmark here is filled with random data which attempts to be close-ish to reality in
111
+ terms of structure. The idea is to have a file relatively close to a real-world application, with moderately sized
112
+ strings etc.
116
113
 
117
114
  The large TOML generator can be found [here](https://gist.github.com/cyyynthia/e77c744cb6494dabe37d0182506526b9)
118
115
 
@@ -189,7 +186,7 @@ I initially reported this to the library author, but the author decided to
189
186
  - b) [delete the issue](https://github.com/huan231/toml-nodejs/issues/12) when pointed out links to the NodeJS
190
187
  documentation about the flag removal and standard resolution algorithm.
191
188
 
192
- For the reference anyways, `toml-nodejs` (with proper imports) is ~8x slower on both parse benchmark with:
189
+ For the reference anyway, `toml-nodejs` (with proper imports) is ~8x slower on both parse benchmark with:
193
190
  - spec example: 7,543.47 op/s
194
191
  - 5mb mixed: 0.7006 op/s
195
192
  </details>
package/dist/date.d.ts CHANGED
@@ -25,7 +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
- export default class TomlDate extends Date {
28
+ export declare class TomlDate extends Date {
29
29
  #private;
30
30
  constructor(date: string | Date);
31
31
  isDateTime(): boolean;
package/dist/date.js CHANGED
@@ -1,3 +1,4 @@
1
+ "use strict";
1
2
  /*!
2
3
  * Copyright (c) Squirrel Chat et al., All rights reserved.
3
4
  * SPDX-License-Identifier: BSD-3-Clause
@@ -25,8 +26,10 @@
25
26
  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26
27
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28
  */
29
+ Object.defineProperty(exports, "__esModule", { value: true });
30
+ exports.TomlDate = void 0;
28
31
  let DATE_TIME_RE = /^(\d{4}-\d{2}-\d{2})?[T ]?(?:(\d{2}):\d{2}:\d{2}(?:\.\d+)?)?(Z|[-+]\d{2}:\d{2})?$/i;
29
- export default class TomlDate extends Date {
32
+ class TomlDate extends Date {
30
33
  #hasDate = false;
31
34
  #hasTime = false;
32
35
  #offset = null;
@@ -49,7 +52,7 @@ export default class TomlDate extends Date {
49
52
  else {
50
53
  offset = match[3] || null;
51
54
  date = date.toUpperCase();
52
- if (!offset)
55
+ if (!offset && hasTime)
53
56
  date += 'Z';
54
57
  }
55
58
  }
@@ -123,3 +126,4 @@ export default class TomlDate extends Date {
123
126
  return date;
124
127
  }
125
128
  }
129
+ exports.TomlDate = TomlDate;
package/dist/error.d.ts CHANGED
@@ -29,7 +29,7 @@ type TomlErrorOptions = ErrorOptions & {
29
29
  toml: string;
30
30
  ptr: number;
31
31
  };
32
- export default class TomlError extends Error {
32
+ export declare class TomlError extends Error {
33
33
  line: number;
34
34
  column: number;
35
35
  codeblock: string;
package/dist/error.js CHANGED
@@ -1,3 +1,4 @@
1
+ "use strict";
1
2
  /*!
2
3
  * Copyright (c) Squirrel Chat et al., All rights reserved.
3
4
  * SPDX-License-Identifier: BSD-3-Clause
@@ -25,6 +26,8 @@
25
26
  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26
27
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28
  */
29
+ Object.defineProperty(exports, "__esModule", { value: true });
30
+ exports.TomlError = void 0;
28
31
  function getLineColFromPtr(string, ptr) {
29
32
  let lines = string.slice(0, ptr).split(/\r\n|\n|\r/g);
30
33
  return [lines.length, lines.pop().length + 1];
@@ -48,7 +51,7 @@ function makeCodeBlock(string, line, column) {
48
51
  }
49
52
  return codeblock;
50
53
  }
51
- export default class TomlError extends Error {
54
+ class TomlError extends Error {
52
55
  line;
53
56
  column;
54
57
  codeblock;
@@ -61,3 +64,4 @@ export default class TomlError extends Error {
61
64
  this.codeblock = codeblock;
62
65
  }
63
66
  }
67
+ exports.TomlError = TomlError;
package/dist/extract.js CHANGED
@@ -1,3 +1,4 @@
1
+ "use strict";
1
2
  /*!
2
3
  * Copyright (c) Squirrel Chat et al., All rights reserved.
3
4
  * SPDX-License-Identifier: BSD-3-Clause
@@ -25,24 +26,26 @@
25
26
  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26
27
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28
  */
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';
29
+ Object.defineProperty(exports, "__esModule", { value: true });
30
+ exports.extractValue = void 0;
31
+ const primitive_js_1 = require("./primitive.js");
32
+ const struct_js_1 = require("./struct.js");
33
+ const util_js_1 = require("./util.js");
34
+ const error_js_1 = require("./error.js");
32
35
  function sliceAndTrimEndOf(str, startPtr, endPtr, allowNewLines) {
33
36
  let value = str.slice(startPtr, endPtr);
34
37
  let commentIdx = value.indexOf('#');
35
38
  if (commentIdx > -1) {
36
39
  // The call to skipComment allows to "validate" the comment
37
40
  // (absence of control characters)
38
- skipComment(str, commentIdx);
41
+ (0, util_js_1.skipComment)(str, commentIdx);
39
42
  value = value.slice(0, commentIdx);
40
43
  }
41
44
  let trimmed = value.trimEnd();
42
45
  if (!allowNewLines) {
43
46
  let newlineIdx = value.indexOf('\n', trimmed.length);
44
47
  if (newlineIdx > -1) {
45
- throw new TomlError('newlines are not allowed in inline tables', {
48
+ throw new error_js_1.TomlError('newlines are not allowed in inline tables', {
46
49
  toml: str,
47
50
  ptr: startPtr + newlineIdx
48
51
  });
@@ -50,17 +53,17 @@ function sliceAndTrimEndOf(str, startPtr, endPtr, allowNewLines) {
50
53
  }
51
54
  return [trimmed, commentIdx];
52
55
  }
53
- export function extractValue(str, ptr, end) {
56
+ function extractValue(str, ptr, end) {
54
57
  let c = str[ptr];
55
58
  if (c === '[' || c === '{') {
56
59
  let [value, endPtr] = c === '['
57
- ? parseArray(str, ptr)
58
- : parseInlineTable(str, ptr);
59
- let newPtr = skipUntil(str, endPtr, ',', end);
60
+ ? (0, struct_js_1.parseArray)(str, ptr)
61
+ : (0, struct_js_1.parseInlineTable)(str, ptr);
62
+ let newPtr = (0, util_js_1.skipUntil)(str, endPtr, ',', end);
60
63
  if (end === '}') {
61
- let nextNewLine = indexOfNewline(str, endPtr, newPtr);
64
+ let nextNewLine = (0, util_js_1.indexOfNewline)(str, endPtr, newPtr);
62
65
  if (nextNewLine > -1) {
63
- throw new TomlError('newlines are not allowed in inline tables', {
66
+ throw new error_js_1.TomlError('newlines are not allowed in inline tables', {
64
67
  toml: str,
65
68
  ptr: nextNewLine
66
69
  });
@@ -70,12 +73,12 @@ export function extractValue(str, ptr, end) {
70
73
  }
71
74
  let endPtr;
72
75
  if (c === '"' || c === "'") {
73
- endPtr = getStringEnd(str, ptr);
74
- let parsed = parseString(str, ptr, endPtr);
76
+ endPtr = (0, util_js_1.getStringEnd)(str, ptr);
77
+ let parsed = (0, primitive_js_1.parseString)(str, ptr, endPtr);
75
78
  if (end) {
76
- endPtr = skipVoid(str, endPtr, end !== ']');
79
+ endPtr = (0, util_js_1.skipVoid)(str, endPtr, end !== ']');
77
80
  if (str[endPtr] && str[endPtr] !== ',' && str[endPtr] !== end && str[endPtr] !== '\n' && str[endPtr] !== '\r') {
78
- throw new TomlError('unexpected character encountered', {
81
+ throw new error_js_1.TomlError('unexpected character encountered', {
79
82
  toml: str,
80
83
  ptr: endPtr,
81
84
  });
@@ -84,20 +87,21 @@ export function extractValue(str, ptr, end) {
84
87
  }
85
88
  return [parsed, endPtr];
86
89
  }
87
- endPtr = skipUntil(str, ptr, ',', end);
90
+ endPtr = (0, util_js_1.skipUntil)(str, ptr, ',', end);
88
91
  let slice = sliceAndTrimEndOf(str, ptr, endPtr - (+(str[endPtr - 1] === ',')), end === ']');
89
92
  if (!slice[0]) {
90
- throw new TomlError('incomplete key-value declaration: no value specified', {
93
+ throw new error_js_1.TomlError('incomplete key-value declaration: no value specified', {
91
94
  toml: str,
92
95
  ptr: ptr
93
96
  });
94
97
  }
95
98
  if (end && slice[1] > -1) {
96
- endPtr = skipVoid(str, ptr + slice[1]);
99
+ endPtr = (0, util_js_1.skipVoid)(str, ptr + slice[1]);
97
100
  endPtr += +(str[endPtr] === ',');
98
101
  }
99
102
  return [
100
- parseValue(slice[0], str, ptr),
103
+ (0, primitive_js_1.parseValue)(slice[0], str, ptr),
101
104
  endPtr,
102
105
  ];
103
106
  }
107
+ exports.extractValue = extractValue;
package/dist/index.d.ts CHANGED
@@ -25,8 +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 { default as TomlError } from './error.js';
29
- export { default as TomlDate } from './date.js';
28
+ export { TomlError } from './error.js';
29
+ export { TomlDate } from './date.js';
30
30
  export { parse } from './parse.js';
31
31
  export { stringify } from './stringify.js';
32
32
  export type { TomlPrimitive } from './util.js';
package/dist/index.js CHANGED
@@ -1,3 +1,4 @@
1
+ "use strict";
1
2
  /*!
2
3
  * Copyright (c) Squirrel Chat et al., All rights reserved.
3
4
  * SPDX-License-Identifier: BSD-3-Clause
@@ -25,7 +26,13 @@
25
26
  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26
27
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28
  */
28
- export { default as TomlError } from './error.js';
29
- export { default as TomlDate } from './date.js';
30
- export { parse } from './parse.js';
31
- export { stringify } from './stringify.js';
29
+ Object.defineProperty(exports, "__esModule", { value: true });
30
+ exports.stringify = exports.parse = exports.TomlDate = exports.TomlError = void 0;
31
+ var error_js_1 = require("./error.js");
32
+ Object.defineProperty(exports, "TomlError", { enumerable: true, get: function () { return error_js_1.TomlError; } });
33
+ var date_js_1 = require("./date.js");
34
+ Object.defineProperty(exports, "TomlDate", { enumerable: true, get: function () { return date_js_1.TomlDate; } });
35
+ var parse_js_1 = require("./parse.js");
36
+ Object.defineProperty(exports, "parse", { enumerable: true, get: function () { return parse_js_1.parse; } });
37
+ var stringify_js_1 = require("./stringify.js");
38
+ Object.defineProperty(exports, "stringify", { enumerable: true, get: function () { return stringify_js_1.stringify; } });
package/dist/parse.js CHANGED
@@ -1,3 +1,4 @@
1
+ "use strict";
1
2
  /*!
2
3
  * Copyright (c) Squirrel Chat et al., All rights reserved.
3
4
  * SPDX-License-Identifier: BSD-3-Clause
@@ -25,10 +26,12 @@
25
26
  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26
27
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28
  */
28
- import { parseKey } from './struct.js';
29
- import { extractValue } from './extract.js';
30
- import { skipVoid } from './util.js';
31
- import TomlError from './error.js';
29
+ Object.defineProperty(exports, "__esModule", { value: true });
30
+ exports.parse = void 0;
31
+ const struct_js_1 = require("./struct.js");
32
+ const extract_js_1 = require("./extract.js");
33
+ const util_js_1 = require("./util.js");
34
+ const error_js_1 = require("./error.js");
32
35
  function peekTable(key, table, meta, type) {
33
36
  let t = table;
34
37
  let m = meta;
@@ -93,18 +96,18 @@ function peekTable(key, table, meta, type) {
93
96
  }
94
97
  return [k, t, state.c];
95
98
  }
96
- export function parse(toml) {
99
+ function parse(toml) {
97
100
  let res = {};
98
101
  let meta = {};
99
102
  let tbl = res;
100
103
  let m = meta;
101
- for (let ptr = skipVoid(toml, 0); ptr < toml.length;) {
104
+ for (let ptr = (0, util_js_1.skipVoid)(toml, 0); ptr < toml.length;) {
102
105
  if (toml[ptr] === '[') {
103
106
  let isTableArray = toml[++ptr] === '[';
104
- let k = parseKey(toml, ptr += +isTableArray, ']');
107
+ let k = (0, struct_js_1.parseKey)(toml, ptr += +isTableArray, ']');
105
108
  if (isTableArray) {
106
109
  if (toml[k[1] - 1] !== ']') {
107
- throw new TomlError('expected end of table declaration', {
110
+ throw new error_js_1.TomlError('expected end of table declaration', {
108
111
  toml: toml,
109
112
  ptr: k[1] - 1,
110
113
  });
@@ -113,7 +116,7 @@ export function parse(toml) {
113
116
  }
114
117
  let p = peekTable(k[0], res, meta, isTableArray ? 2 /* Type.ARRAY */ : 1 /* Type.EXPLICIT */);
115
118
  if (!p) {
116
- throw new TomlError('trying to redefine an already defined table or value', {
119
+ throw new error_js_1.TomlError('trying to redefine an already defined table or value', {
117
120
  toml: toml,
118
121
  ptr: ptr,
119
122
  });
@@ -123,26 +126,27 @@ export function parse(toml) {
123
126
  ptr = k[1];
124
127
  }
125
128
  else {
126
- let k = parseKey(toml, ptr);
129
+ let k = (0, struct_js_1.parseKey)(toml, ptr);
127
130
  let p = peekTable(k[0], tbl, m, 0 /* Type.DOTTED */);
128
131
  if (!p) {
129
- throw new TomlError('trying to redefine an already defined table or value', {
132
+ throw new error_js_1.TomlError('trying to redefine an already defined table or value', {
130
133
  toml: toml,
131
134
  ptr: ptr,
132
135
  });
133
136
  }
134
- let v = extractValue(toml, k[1]);
137
+ let v = (0, extract_js_1.extractValue)(toml, k[1]);
135
138
  p[1][p[0]] = v[0];
136
139
  ptr = v[1];
137
140
  }
138
- ptr = skipVoid(toml, ptr, true);
141
+ ptr = (0, util_js_1.skipVoid)(toml, ptr, true);
139
142
  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', {
143
+ throw new error_js_1.TomlError('each key-value declaration must be followed by an end-of-line', {
141
144
  toml: toml,
142
145
  ptr: ptr
143
146
  });
144
147
  }
145
- ptr = skipVoid(toml, ptr);
148
+ ptr = (0, util_js_1.skipVoid)(toml, ptr);
146
149
  }
147
150
  return res;
148
151
  }
152
+ exports.parse = parse;
@@ -25,6 +25,6 @@
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';
28
+ import { TomlDate } from './date.js';
29
29
  export declare function parseString(str: string, ptr?: number, endPtr?: number): string;
30
30
  export declare function parseValue(value: string, toml: string, ptr: number): boolean | number | TomlDate;
package/dist/primitive.js CHANGED
@@ -1,3 +1,4 @@
1
+ "use strict";
1
2
  /*!
2
3
  * Copyright (c) Squirrel Chat et al., All rights reserved.
3
4
  * SPDX-License-Identifier: BSD-3-Clause
@@ -25,9 +26,11 @@
25
26
  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26
27
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28
  */
28
- import { skipVoid } from './util.js';
29
- import TomlDate from './date.js';
30
- import TomlError from './error.js';
29
+ Object.defineProperty(exports, "__esModule", { value: true });
30
+ exports.parseValue = exports.parseString = void 0;
31
+ const util_js_1 = require("./util.js");
32
+ const date_js_1 = require("./date.js");
33
+ const error_js_1 = require("./error.js");
31
34
  let INT_REGEX = /^((0x[0-9a-fA-F](_?[0-9a-fA-F])*)|(([+-]|0[ob])?\d(_?\d)*))$/;
32
35
  let FLOAT_REGEX = /^[+-]?\d(_?\d)*(\.\d(_?\d)*)?([eE][+-]?\d(_?\d)*)?$/;
33
36
  let LEADING_ZERO = /^[+-]?0[0-9_]/;
@@ -41,7 +44,7 @@ let ESC_MAP = {
41
44
  '"': '"',
42
45
  '\\': '\\',
43
46
  };
44
- export function parseString(str, ptr = 0, endPtr = str.length) {
47
+ function parseString(str, ptr = 0, endPtr = str.length) {
45
48
  let isLiteral = str[ptr] === "'";
46
49
  let isMultiline = str[ptr++] === str[ptr] && str[ptr] === str[ptr + 1];
47
50
  if (isMultiline) {
@@ -59,14 +62,14 @@ export function parseString(str, ptr = 0, endPtr = str.length) {
59
62
  let c = str[ptr++];
60
63
  if (c === '\n' || (c === '\r' && str[ptr] === '\n')) {
61
64
  if (!isMultiline) {
62
- throw new TomlError('newlines are not allowed in strings', {
65
+ throw new error_js_1.TomlError('newlines are not allowed in strings', {
63
66
  toml: str,
64
67
  ptr: ptr - 1
65
68
  });
66
69
  }
67
70
  }
68
71
  else if ((c < '\x20' && c !== '\t') || c === '\x7f') {
69
- throw new TomlError('control characters are not allowed in strings', {
72
+ throw new error_js_1.TomlError('control characters are not allowed in strings', {
70
73
  toml: str,
71
74
  ptr: ptr - 1
72
75
  });
@@ -77,7 +80,7 @@ export function parseString(str, ptr = 0, endPtr = str.length) {
77
80
  // Unicode escape
78
81
  let code = str.slice(ptr, (ptr += (c === 'u' ? 4 : 8)));
79
82
  if (!ESCAPE_REGEX.test(code)) {
80
- throw new TomlError('invalid unicode escape', {
83
+ throw new error_js_1.TomlError('invalid unicode escape', {
81
84
  toml: str,
82
85
  ptr: tmp
83
86
  });
@@ -86,7 +89,7 @@ export function parseString(str, ptr = 0, endPtr = str.length) {
86
89
  parsed += String.fromCodePoint(parseInt(code, 16));
87
90
  }
88
91
  catch {
89
- throw new TomlError('invalid unicode escape', {
92
+ throw new error_js_1.TomlError('invalid unicode escape', {
90
93
  toml: str,
91
94
  ptr: tmp
92
95
  });
@@ -94,21 +97,21 @@ export function parseString(str, ptr = 0, endPtr = str.length) {
94
97
  }
95
98
  else if (isMultiline && (c === '\n' || c === ' ' || c === '\t' || c === '\r')) {
96
99
  // Multiline escape
97
- ptr = skipVoid(str, ptr - 1, true);
100
+ ptr = (0, util_js_1.skipVoid)(str, ptr - 1, true);
98
101
  if (str[ptr] !== '\n' && str[ptr] !== '\r') {
99
- throw new TomlError('invalid escape: only line-ending whitespace may be escaped', {
102
+ throw new error_js_1.TomlError('invalid escape: only line-ending whitespace may be escaped', {
100
103
  toml: str,
101
104
  ptr: tmp
102
105
  });
103
106
  }
104
- ptr = skipVoid(str, ptr);
107
+ ptr = (0, util_js_1.skipVoid)(str, ptr);
105
108
  }
106
109
  else if (c in ESC_MAP) {
107
110
  // Classic escape
108
111
  parsed += ESC_MAP[c];
109
112
  }
110
113
  else {
111
- throw new TomlError('unrecognized escape sequence', {
114
+ throw new error_js_1.TomlError('unrecognized escape sequence', {
112
115
  toml: str,
113
116
  ptr: tmp
114
117
  });
@@ -123,7 +126,8 @@ export function parseString(str, ptr = 0, endPtr = str.length) {
123
126
  }
124
127
  return parsed + str.slice(sliceStart, endPtr - 1);
125
128
  }
126
- export function parseValue(value, toml, ptr) {
129
+ exports.parseString = parseString;
130
+ function parseValue(value, toml, ptr) {
127
131
  // Constant values
128
132
  if (value === 'true')
129
133
  return true;
@@ -141,32 +145,33 @@ export function parseValue(value, toml, ptr) {
141
145
  let isInt;
142
146
  if ((isInt = INT_REGEX.test(value)) || FLOAT_REGEX.test(value)) {
143
147
  if (LEADING_ZERO.test(value)) {
144
- throw new TomlError('leading zeroes are not allowed', {
148
+ throw new error_js_1.TomlError('leading zeroes are not allowed', {
145
149
  toml: toml,
146
150
  ptr: ptr
147
151
  });
148
152
  }
149
153
  let numeric = +(value.replace(/_/g, ''));
150
154
  if (isNaN(numeric)) {
151
- throw new TomlError('invalid number', {
155
+ throw new error_js_1.TomlError('invalid number', {
152
156
  toml: toml,
153
157
  ptr: ptr
154
158
  });
155
159
  }
156
160
  if (isInt && !Number.isSafeInteger(numeric)) {
157
- throw new TomlError('integer value cannot be represented losslessly', {
161
+ throw new error_js_1.TomlError('integer value cannot be represented losslessly', {
158
162
  toml: toml,
159
163
  ptr: ptr
160
164
  });
161
165
  }
162
166
  return numeric;
163
167
  }
164
- let date = new TomlDate(value);
168
+ let date = new date_js_1.TomlDate(value);
165
169
  if (!date.isValid()) {
166
- throw new TomlError('invalid value', {
170
+ throw new error_js_1.TomlError('invalid value', {
167
171
  toml: toml,
168
172
  ptr: ptr
169
173
  });
170
174
  }
171
175
  return date;
172
176
  }
177
+ exports.parseValue = parseValue;
package/dist/stringify.js CHANGED
@@ -1,3 +1,4 @@
1
+ "use strict";
1
2
  /*!
2
3
  * Copyright (c) Squirrel Chat et al., All rights reserved.
3
4
  * SPDX-License-Identifier: BSD-3-Clause
@@ -25,6 +26,8 @@
25
26
  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26
27
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28
  */
29
+ Object.defineProperty(exports, "__esModule", { value: true });
30
+ exports.stringify = void 0;
28
31
  const BARE_KEY = /^[a-z0-9-_]+$/i;
29
32
  function extendedTypeOf(obj) {
30
33
  let type = typeof obj;
@@ -144,9 +147,10 @@ function stringifyTable(obj, prefix = '') {
144
147
  }
145
148
  return `${preamble}\n${tables}`.trim();
146
149
  }
147
- export function stringify(obj) {
150
+ function stringify(obj) {
148
151
  if (extendedTypeOf(obj) !== 'object') {
149
152
  throw new TypeError('stringify can only be called with an object');
150
153
  }
151
154
  return stringifyTable(obj);
152
155
  }
156
+ exports.stringify = stringify;
package/dist/struct.js CHANGED
@@ -1,3 +1,4 @@
1
+ "use strict";
1
2
  /*!
2
3
  * Copyright (c) Squirrel Chat et al., All rights reserved.
3
4
  * SPDX-License-Identifier: BSD-3-Clause
@@ -25,17 +26,19 @@
25
26
  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26
27
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28
  */
28
- import { parseString } from './primitive.js';
29
- import { extractValue } from './extract.js';
30
- import { skipComment, indexOfNewline, getStringEnd, skipVoid } from './util.js';
31
- import TomlError from './error.js';
29
+ Object.defineProperty(exports, "__esModule", { value: true });
30
+ exports.parseArray = exports.parseInlineTable = exports.parseKey = void 0;
31
+ const primitive_js_1 = require("./primitive.js");
32
+ const extract_js_1 = require("./extract.js");
33
+ const util_js_1 = require("./util.js");
34
+ const error_js_1 = require("./error.js");
32
35
  let KEY_PART_RE = /^[a-zA-Z0-9-_]+[ \t]*$/;
33
- export function parseKey(str, ptr, end = '=') {
36
+ function parseKey(str, ptr, end = '=') {
34
37
  let dot = ptr - 1;
35
38
  let parsed = [];
36
39
  let endPtr = str.indexOf(end, ptr);
37
40
  if (endPtr < 0) {
38
- throw new TomlError('incomplete key-value: cannot find end of key', {
41
+ throw new error_js_1.TomlError('incomplete key-value: cannot find end of key', {
39
42
  toml: str,
40
43
  ptr: ptr
41
44
  });
@@ -47,29 +50,29 @@ export function parseKey(str, ptr, end = '=') {
47
50
  // If it's a string
48
51
  if (c === '"' || c === "'") {
49
52
  if (c === str[ptr + 1] && c === str[ptr + 2]) {
50
- throw new TomlError('multiline strings are not allowed in keys', {
53
+ throw new error_js_1.TomlError('multiline strings are not allowed in keys', {
51
54
  toml: str,
52
55
  ptr: ptr,
53
56
  });
54
57
  }
55
- let eos = getStringEnd(str, ptr);
58
+ let eos = (0, util_js_1.getStringEnd)(str, ptr);
56
59
  if (eos < 0) {
57
- throw new TomlError('unfinished string encountered', {
60
+ throw new error_js_1.TomlError('unfinished string encountered', {
58
61
  toml: str,
59
62
  ptr: ptr,
60
63
  });
61
64
  }
62
65
  dot = str.indexOf('.', eos);
63
66
  let strEnd = str.slice(eos, dot < 0 || dot > endPtr ? endPtr : dot);
64
- let newLine = indexOfNewline(strEnd);
67
+ let newLine = (0, util_js_1.indexOfNewline)(strEnd);
65
68
  if (newLine > -1) {
66
- throw new TomlError('newlines are not allowed in keys', {
69
+ throw new error_js_1.TomlError('newlines are not allowed in keys', {
67
70
  toml: str,
68
71
  ptr: ptr + dot + newLine,
69
72
  });
70
73
  }
71
74
  if (strEnd.trimStart()) {
72
- throw new TomlError('found extra tokens after the string part', {
75
+ throw new error_js_1.TomlError('found extra tokens after the string part', {
73
76
  toml: str,
74
77
  ptr: eos,
75
78
  });
@@ -77,20 +80,20 @@ export function parseKey(str, ptr, end = '=') {
77
80
  if (endPtr < eos) {
78
81
  endPtr = str.indexOf(end, eos);
79
82
  if (endPtr < 0) {
80
- throw new TomlError('incomplete key-value: cannot find end of key', {
83
+ throw new error_js_1.TomlError('incomplete key-value: cannot find end of key', {
81
84
  toml: str,
82
85
  ptr: ptr,
83
86
  });
84
87
  }
85
88
  }
86
- parsed.push(parseString(str, ptr, eos));
89
+ parsed.push((0, primitive_js_1.parseString)(str, ptr, eos));
87
90
  }
88
91
  else {
89
92
  // Normal raw key part consumption and validation
90
93
  dot = str.indexOf('.', ptr);
91
94
  let part = str.slice(ptr, dot < 0 || dot > endPtr ? endPtr : dot);
92
95
  if (!KEY_PART_RE.test(part)) {
93
- throw new TomlError('only letter, numbers, dashes and underscores are allowed in keys', {
96
+ throw new error_js_1.TomlError('only letter, numbers, dashes and underscores are allowed in keys', {
94
97
  toml: str,
95
98
  ptr: ptr,
96
99
  });
@@ -100,9 +103,10 @@ export function parseKey(str, ptr, end = '=') {
100
103
  }
101
104
  // Until there's no more dot
102
105
  } while (dot + 1 && dot < endPtr);
103
- return [parsed, skipVoid(str, endPtr + 1, true, true)];
106
+ return [parsed, (0, util_js_1.skipVoid)(str, endPtr + 1, true, true)];
104
107
  }
105
- export function parseInlineTable(str, ptr) {
108
+ exports.parseKey = parseKey;
109
+ function parseInlineTable(str, ptr) {
106
110
  let res = {};
107
111
  let seen = new Set();
108
112
  let c;
@@ -110,19 +114,19 @@ export function parseInlineTable(str, ptr) {
110
114
  ptr++;
111
115
  while ((c = str[ptr++]) !== '}' && c) {
112
116
  if (c === '\n') {
113
- throw new TomlError('newlines are not allowed in inline tables', {
117
+ throw new error_js_1.TomlError('newlines are not allowed in inline tables', {
114
118
  toml: str,
115
119
  ptr: ptr - 1
116
120
  });
117
121
  }
118
122
  else if (c === '#') {
119
- throw new TomlError('inline tables cannot contain comments', {
123
+ throw new error_js_1.TomlError('inline tables cannot contain comments', {
120
124
  toml: str,
121
125
  ptr: ptr - 1
122
126
  });
123
127
  }
124
128
  else if (c === ',') {
125
- throw new TomlError('expected key-value, found comma', {
129
+ throw new error_js_1.TomlError('expected key-value, found comma', {
126
130
  toml: str,
127
131
  ptr: ptr - 1
128
132
  });
@@ -137,7 +141,7 @@ export function parseInlineTable(str, ptr) {
137
141
  t = hasOwn ? t[k] : (t[k] = {});
138
142
  k = key[i];
139
143
  if ((hasOwn = Object.hasOwn(t, k)) && (typeof t[k] !== 'object' || seen.has(t[k]))) {
140
- throw new TomlError('trying to redefine an already defined value', {
144
+ throw new error_js_1.TomlError('trying to redefine an already defined value', {
141
145
  toml: str,
142
146
  ptr: ptr
143
147
  });
@@ -147,12 +151,12 @@ export function parseInlineTable(str, ptr) {
147
151
  }
148
152
  }
149
153
  if (hasOwn) {
150
- throw new TomlError('trying to redefine an already defined value', {
154
+ throw new error_js_1.TomlError('trying to redefine an already defined value', {
151
155
  toml: str,
152
156
  ptr: ptr
153
157
  });
154
158
  }
155
- let [value, valueEndPtr] = extractValue(str, keyEndPtr, '}');
159
+ let [value, valueEndPtr] = (0, extract_js_1.extractValue)(str, keyEndPtr, '}');
156
160
  seen.add(value);
157
161
  t[k] = value;
158
162
  ptr = valueEndPtr;
@@ -160,43 +164,45 @@ export function parseInlineTable(str, ptr) {
160
164
  }
161
165
  }
162
166
  if (comma) {
163
- throw new TomlError('trailing commas are not allowed in inline tables', {
167
+ throw new error_js_1.TomlError('trailing commas are not allowed in inline tables', {
164
168
  toml: str,
165
169
  ptr: comma
166
170
  });
167
171
  }
168
172
  if (!c) {
169
- throw new TomlError('unfinished table encountered', {
173
+ throw new error_js_1.TomlError('unfinished table encountered', {
170
174
  toml: str,
171
175
  ptr: ptr
172
176
  });
173
177
  }
174
178
  return [res, ptr];
175
179
  }
176
- export function parseArray(str, ptr) {
180
+ exports.parseInlineTable = parseInlineTable;
181
+ function parseArray(str, ptr) {
177
182
  let res = [];
178
183
  let c;
179
184
  ptr++;
180
185
  while ((c = str[ptr++]) !== ']' && c) {
181
186
  if (c === ',') {
182
- throw new TomlError('expected value, found comma', {
187
+ throw new error_js_1.TomlError('expected value, found comma', {
183
188
  toml: str,
184
189
  ptr: ptr - 1
185
190
  });
186
191
  }
187
192
  else if (c === '#')
188
- ptr = skipComment(str, ptr);
193
+ ptr = (0, util_js_1.skipComment)(str, ptr);
189
194
  else if (c !== ' ' && c !== '\t' && c !== '\n' && c !== '\r') {
190
- let e = extractValue(str, ptr - 1, ']');
195
+ let e = (0, extract_js_1.extractValue)(str, ptr - 1, ']');
191
196
  res.push(e[0]);
192
197
  ptr = e[1];
193
198
  }
194
199
  }
195
200
  if (!c) {
196
- throw new TomlError('unfinished array encountered', {
201
+ throw new error_js_1.TomlError('unfinished array encountered', {
197
202
  toml: str,
198
203
  ptr: ptr
199
204
  });
200
205
  }
201
206
  return [res, ptr];
202
207
  }
208
+ exports.parseArray = parseArray;
package/dist/util.d.ts CHANGED
@@ -25,7 +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
- import TomlDate from './date.js';
28
+ import type { TomlDate } from './date.js';
29
29
  export type TomlPrimitive = string | number | boolean | TomlDate | {
30
30
  [key: string]: TomlPrimitive;
31
31
  } | TomlPrimitive[];
package/dist/util.js CHANGED
@@ -1,3 +1,4 @@
1
+ "use strict";
1
2
  /*!
2
3
  * Copyright (c) Squirrel Chat et al., All rights reserved.
3
4
  * SPDX-License-Identifier: BSD-3-Clause
@@ -25,14 +26,17 @@
25
26
  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26
27
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28
  */
28
- import TomlError from './error.js';
29
- export function indexOfNewline(str, start = 0, end = str.length) {
29
+ Object.defineProperty(exports, "__esModule", { value: true });
30
+ exports.getStringEnd = exports.skipUntil = exports.skipVoid = exports.skipComment = exports.indexOfNewline = void 0;
31
+ const error_js_1 = require("./error.js");
32
+ function indexOfNewline(str, start = 0, end = str.length) {
30
33
  let idx = str.indexOf('\n', start);
31
34
  if (str[idx - 1] === '\r')
32
35
  idx--;
33
36
  return idx <= end ? idx : -1;
34
37
  }
35
- export function skipComment(str, ptr) {
38
+ exports.indexOfNewline = indexOfNewline;
39
+ function skipComment(str, ptr) {
36
40
  for (let i = ptr; i < str.length; i++) {
37
41
  let c = str[i];
38
42
  if (c === '\n')
@@ -40,7 +44,7 @@ export function skipComment(str, ptr) {
40
44
  if (c === '\r' && str[i + 1] === '\n')
41
45
  return i + 1;
42
46
  if ((c < '\x20' && c !== '\t') || c === '\x7f') {
43
- throw new TomlError('control characters are not allowed in comments', {
47
+ throw new error_js_1.TomlError('control characters are not allowed in comments', {
44
48
  toml: str,
45
49
  ptr: ptr,
46
50
  });
@@ -48,7 +52,8 @@ export function skipComment(str, ptr) {
48
52
  }
49
53
  return str.length;
50
54
  }
51
- export function skipVoid(str, ptr, banNewLines, banComments) {
55
+ exports.skipComment = skipComment;
56
+ function skipVoid(str, ptr, banNewLines, banComments) {
52
57
  let c;
53
58
  while ((c = str[ptr]) === ' ' || c === '\t' || (!banNewLines && (c === '\n' || c === '\r' && str[ptr + 1] === '\n')))
54
59
  ptr++;
@@ -56,7 +61,8 @@ export function skipVoid(str, ptr, banNewLines, banComments) {
56
61
  ? ptr
57
62
  : skipVoid(str, skipComment(str, ptr), banNewLines);
58
63
  }
59
- export function skipUntil(str, ptr, sep, end, banNewLines = false) {
64
+ exports.skipVoid = skipVoid;
65
+ function skipUntil(str, ptr, sep, end, banNewLines = false) {
60
66
  if (!end) {
61
67
  ptr = indexOfNewline(str, ptr);
62
68
  return ptr < 0 ? str.length : ptr;
@@ -76,12 +82,13 @@ export function skipUntil(str, ptr, sep, end, banNewLines = false) {
76
82
  return i;
77
83
  }
78
84
  }
79
- throw new TomlError('cannot find end of structure', {
85
+ throw new error_js_1.TomlError('cannot find end of structure', {
80
86
  toml: str,
81
87
  ptr: ptr
82
88
  });
83
89
  }
84
- export function getStringEnd(str, seek) {
90
+ exports.skipUntil = skipUntil;
91
+ function getStringEnd(str, seek) {
85
92
  let first = str[seek];
86
93
  let target = first === str[seek + 1] && str[seek + 1] === str[seek + 2]
87
94
  ? str.slice(seek, seek + 3)
@@ -101,3 +108,4 @@ export function getStringEnd(str, seek) {
101
108
  }
102
109
  return seek;
103
110
  }
111
+ exports.getStringEnd = getStringEnd;
package/package.json CHANGED
@@ -1,19 +1,21 @@
1
1
  {
2
2
  "name": "smol-toml",
3
- "version": "1.1.4",
3
+ "version": "1.2.1",
4
4
  "keywords": [
5
5
  "toml",
6
6
  "parser",
7
7
  "serializer"
8
8
  ],
9
9
  "description": "A small, fast, and correct TOML parser/serializer",
10
- "repository": "git@github.com:squirrelchat/smol-toml.git",
10
+ "repository": {
11
+ "type": "git",
12
+ "url": "git+ssh://git@github.com/squirrelchat/smol-toml.git"
13
+ },
11
14
  "author": "Cynthia <cyyynthia@borkenware.com>",
12
15
  "license": "BSD-3-Clause",
13
- "type": "module",
14
16
  "engines": {
15
17
  "node": ">= 18",
16
- "pnpm": ">= 8"
18
+ "pnpm": ">= 9"
17
19
  },
18
20
  "scripts": {
19
21
  "build": "tsc",
@@ -24,20 +26,15 @@
24
26
  "devDependencies": {
25
27
  "@iarna/toml": "3.0.0",
26
28
  "@ltd/j-toml": "^1.38.0",
27
- "@tsconfig/node-lts": "^20.1.1",
28
- "@tsconfig/strictest": "^2.0.2",
29
- "@types/node": "^20.11.5",
30
- "@vitest/ui": "^1.2.1",
29
+ "@tsconfig/node-lts": "^20.1.3",
30
+ "@tsconfig/strictest": "^2.0.5",
31
+ "@types/node": "^20.12.11",
32
+ "@vitest/ui": "^1.6.0",
31
33
  "fast-toml": "^0.5.4",
32
- "typescript": "^5.3.3",
33
- "vitest": "^1.2.1"
34
- },
35
- "exports": {
36
- ".": {
37
- "types": "./dist/index.d.ts",
38
- "default": "./dist/index.js"
39
- }
34
+ "typescript": "^5.4.5",
35
+ "vitest": "^1.6.0"
40
36
  },
37
+ "main": "./dist/index.js",
41
38
  "types": "./dist/index.d.ts",
42
39
  "files": [
43
40
  "README.md",