@lowlighter/xml 6.0.1 → 8.0.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 +77 -22
- package/_parser.d.ts +45 -0
- package/_parser.js +266 -0
- package/_types.d.ts +29 -0
- package/_types.js +2 -0
- package/bench/assets/medium.xml +1 -1
- package/bench/assets/small.xml +1 -1
- package/bench/bench.ts +6 -2
- package/deno.lock +17 -97
- package/mod.d.ts +3 -0
- package/mod.js +3 -0
- package/package.json +27 -23
- package/parse.d.ts +81 -0
- package/parse.js +227 -0
- package/stringify.d.ts +79 -0
- package/stringify.js +263 -0
- package/wasm/parse.d.ts +77 -0
- package/wasm/parse.js +123 -0
- package/wasm/wasm_xml_parser.js +3 -0
- package/_types.ts +0 -49
- package/_types_test.ts +0 -1
- package/deno.jsonc +0 -97
- package/mod.mjs +0 -1
- package/mod.ts +0 -3
- package/mod_test.ts +0 -1
- package/parse.mjs +0 -1
- package/parse.ts +0 -442
- package/parse_test.ts +0 -1303
- package/stringify.mjs +0 -1
- package/stringify.ts +0 -287
- package/stringify_test.ts +0 -303
- package/wasm_xml_parser/Cargo.lock +0 -159
- package/wasm_xml_parser/Cargo.toml +0 -16
- package/wasm_xml_parser/src/lib.rs +0 -234
- package/wasm_xml_parser/wasm_xml_parser.js +0 -2
package/README.md
CHANGED
|
@@ -28,7 +28,7 @@ console.log(parse(`
|
|
|
28
28
|
|
|
29
29
|
// Parse a file
|
|
30
30
|
using file = await Deno.open("bench/assets/small.xml")
|
|
31
|
-
console.log(parse(file))
|
|
31
|
+
console.log(await parse(file.readable))
|
|
32
32
|
```
|
|
33
33
|
|
|
34
34
|
### Stringifying objects to XML
|
|
@@ -51,7 +51,7 @@ console.log(stringify({
|
|
|
51
51
|
|
|
52
52
|
## ✨ Features
|
|
53
53
|
|
|
54
|
-
- Based on
|
|
54
|
+
- Based on [`@std/xml`](https://jsr.io/@std/xml).
|
|
55
55
|
- Support for `XML.parse` and `XML.stringify` in the style of the `JSON` global.
|
|
56
56
|
- Support for `<!-- -->` comments.
|
|
57
57
|
- Support for XML entities (`&`, `&`, `&`, …).
|
|
@@ -64,14 +64,75 @@ console.log(stringify({
|
|
|
64
64
|
- Support for custom `reviver` and `replacer` functions
|
|
65
65
|
- Support for metadata stored into non-enumerable properties (advanced usage).
|
|
66
66
|
|
|
67
|
+
## 🕊️ Migrating from `7.x.x` to `8.x.x`
|
|
68
|
+
|
|
69
|
+
### Using `@std/xml` instead of `quick-xml` as parser
|
|
70
|
+
|
|
71
|
+
The parser is now backed by [`@std/xml`](https://jsr.io/@std/xml) instead of a WASM-compiled binding of the [quick-xml](https://github.com/tafia/quick-xml) Rust package.
|
|
72
|
+
|
|
73
|
+
This change reduces the maintenance burden of the library while relying on a standardized parser.
|
|
74
|
+
|
|
75
|
+
The WASM parser from `7.x.x` is still available in the `@libs/xml/wasm/parse` export. While the TypeScript layer will continue being updated, the underlying WASM module that serves quick-xml tokenization won't.
|
|
76
|
+
|
|
77
|
+
### Exported types are now PascalCase
|
|
78
|
+
|
|
79
|
+
```diff ts
|
|
80
|
+
- import type { stringify_options, stringifyable, xml_document, xml_node, xml_text } from "jsr:@libs/xml@7/stringify"
|
|
81
|
+
+ import type { StringifyOptions, Stringifyable, XmlDocument, XmlNode, XmlText } from "jsr:@libs/xml@8/stringify"
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### Unsupported options in the default export
|
|
85
|
+
|
|
86
|
+
> Note: described options are still available in the legacy WASM backend from `@libs/xml/wasm/parse` export.
|
|
87
|
+
|
|
88
|
+
The `revive.entities` option of `parse` has been removed, XML entities are now always decoded. If you need values in their escaped form, re-escape them with `escape` from [`@std/html/entities`](https://jsr.io/@std/html):
|
|
89
|
+
|
|
90
|
+
```diff ts
|
|
91
|
+
- const document = parse(text, { revive: { entities: false } })
|
|
92
|
+
+ import { escape } from "jsr:@std/html/entities"
|
|
93
|
+
+ const document = parse(text)
|
|
94
|
+
+ // Apply `escape()` on values where the escaped form is needed
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
The `mode: "html"` option of `parse` has been temporarily removed, as `@std/xml` only supports strict XML.
|
|
98
|
+
|
|
99
|
+
```diff ts
|
|
100
|
+
- import { parse } from "jsr:@libs/xml@8/parse"
|
|
101
|
+
+ import { parse } from "jsr:@libs/xml@8/wasm/parse"
|
|
102
|
+
const document = parse(text, { mode: "html" })
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
Passing a `ReaderSync` to `parse` is no longer supported. You can still pass a `Reader` to `parse` but the result is now asynchronous.
|
|
106
|
+
|
|
107
|
+
```diff
|
|
108
|
+
using file = await Deno.open("bench/assets/small.xml")
|
|
109
|
+
- console.log(parse(file))
|
|
110
|
+
+ console.log(await parse(file.readable))
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
## 🕊️ Migrating from `6.x.x` to `7.x.x`
|
|
114
|
+
|
|
115
|
+
For both `stringify` and `parse`, the type `options` has been renamed and prefixed by their scope for more clarity.
|
|
116
|
+
|
|
117
|
+
```diff ts
|
|
118
|
+
- import type { options } from "jsr:@libs/xml@6/stringify"
|
|
119
|
+
+ import type { stringify_options } from "jsr:@libs/xml@7/stringify"
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
```diff ts
|
|
123
|
+
- import type { options } from "jsr:@libs/xml@6/parse"
|
|
124
|
+
+ import type { parse_options } from "jsr:@libs/xml@7/parse"
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
If you didn't use these typings, no further changes are required.
|
|
128
|
+
|
|
67
129
|
## 🕊️ Migrating from `5.x.x` to `6.x.x`
|
|
68
130
|
|
|
69
131
|
Version `6.x.x` and onwards require Deno `2.x.x` or later.
|
|
70
132
|
|
|
71
133
|
## 🕊️ Migrating from `4.x.x` to `5.x.x`
|
|
72
134
|
|
|
73
|
-
Prior to version version `5.0.0`, this library was fully written in TypeScript.
|
|
74
|
-
It now uses a WASM-compiled binding of the [quick-xml](https://github.com/tafia/quick-xml) Rust package, which provides better performance while allowing us to support more features.
|
|
135
|
+
Prior to version version `5.0.0`, this library was fully written in TypeScript. It now uses a WASM-compiled binding of the [quick-xml](https://github.com/tafia/quick-xml) Rust package, which provides better performance while allowing us to support more features.
|
|
75
136
|
|
|
76
137
|
### Internal API changes
|
|
77
138
|
|
|
@@ -138,8 +199,7 @@ Processing instructions (like XML stylesheets) are now parsed the same way as re
|
|
|
138
199
|
|
|
139
200
|
### Mixed content support
|
|
140
201
|
|
|
141
|
-
This breaks any existing code that was expecting mixed content to always be a string.
|
|
142
|
-
Now, mixed content nodes will be parsed as usual, and the `#text` property will contain the "inner text" of the node.
|
|
202
|
+
This breaks any existing code that was expecting mixed content to always be a string. Now, mixed content nodes will be parsed as usual, and the `#text` property will contain the "inner text" of the node.
|
|
143
203
|
|
|
144
204
|
Note that `#text` is actually a getter that recursively gets the `#text` of children nodes (ignoring comment nodes), so it'll also handle nested mixed content correctly.
|
|
145
205
|
|
|
@@ -159,11 +219,9 @@ Note that `#text` is actually a getter that recursively gets the `#text` of chil
|
|
|
159
219
|
|
|
160
220
|
### Comments
|
|
161
221
|
|
|
162
|
-
Comments have been moved into `"#comments"` property.
|
|
163
|
-
Note that this property is now always an array, even if there is only one comment.
|
|
222
|
+
Comments have been moved into `"#comments"` property. Note that this property is now always an array, even if there is only one comment.
|
|
164
223
|
|
|
165
|
-
Additionally, you can find comments into the `~children` property by searching for nodes with `"~name": "~comment"`.
|
|
166
|
-
If you call the `#text` getter on a parent node containing comments, it will return the inner text without comments.
|
|
224
|
+
Additionally, you can find comments into the `~children` property by searching for nodes with `"~name": "~comment"`. If you call the `#text` getter on a parent node containing comments, it will return the inner text without comments.
|
|
167
225
|
|
|
168
226
|
```xml
|
|
169
227
|
<root><!--some comment--></root>
|
|
@@ -189,8 +247,7 @@ Parsing options are categorized into 4 groups:
|
|
|
189
247
|
- `revive`, which can `trim` content (unless `xml:space="preserve"`), unescape xml `entities`, revive `booleans` and `numbers`
|
|
190
248
|
- You can also provide a `custom` reviver function (applied after other revivals) that will be called on each attribute and node
|
|
191
249
|
- _Note that signature of the reviver function has changed_
|
|
192
|
-
- `mode`, which can be either `xml` or `html`.
|
|
193
|
-
Choosing the latter will be more permissive than the former.
|
|
250
|
+
- `mode`, which can be either `xml` or `html`. Choosing the latter will be more permissive than the former.
|
|
194
251
|
|
|
195
252
|
```diff js
|
|
196
253
|
const options = {
|
|
@@ -212,7 +269,7 @@ Please refer to the [documentation](https://jsr.io/@libs/xml/doc) for more infor
|
|
|
212
269
|
|
|
213
270
|
The `parse()` function supports any `ReaderSync`, which means you can pass directly a file reader for example.
|
|
214
271
|
|
|
215
|
-
```ts
|
|
272
|
+
```ts ignore
|
|
216
273
|
import { parse } from "./parse.ts"
|
|
217
274
|
parse(await Deno.readTextFile("example.xml"))
|
|
218
275
|
```
|
|
@@ -248,8 +305,7 @@ Please refer to the [documentation](https://jsr.io/@libs/xml/doc) for more infor
|
|
|
248
305
|
|
|
249
306
|
### Stringifying content
|
|
250
307
|
|
|
251
|
-
Please refer to the above section about API changes.
|
|
252
|
-
If you were handling XML document properties, using the `$XML` symbol or `#comment` property, or dealing with mixed nodes content, you'll most likely need to update your code.
|
|
308
|
+
Please refer to the above section about API changes. If you were handling XML document properties, using the `$XML` symbol or `#comment` property, or dealing with mixed nodes content, you'll most likely need to update your code.
|
|
253
309
|
|
|
254
310
|
Additionally, the library now provides `comment()` and `cdata()` helpers to respectively create comment and CDATA nodes:
|
|
255
311
|
|
|
@@ -287,27 +343,26 @@ stringify({
|
|
|
287
343
|
</root>
|
|
288
344
|
```
|
|
289
345
|
|
|
290
|
-
Note that while you can _theoretically_ use internal API properties, currently, we strongly advise against doing so.
|
|
291
|
-
|
|
292
|
-
Setting `~name` manually might lead to unexpected behaviors, especially if it differs from the parent key.
|
|
346
|
+
Note that while you can _theoretically_ use internal API properties, currently, we strongly advise against doing so. Supporting `~children` might be added in the future ([#57](https://github.com/lowlighter/libs/issues/57)) for mixed content, but its behavior is not yet well
|
|
347
|
+
defined. Setting `~name` manually might lead to unexpected behaviors, especially if it differs from the parent key.
|
|
293
348
|
|
|
294
349
|
> [!TIP]
|
|
295
|
-
> For more type-safety, write `satisfies Partial<
|
|
350
|
+
> For more type-safety, write `satisfies Partial<XmlDocument>` after whatever you pass into `stringify`, like so:
|
|
296
351
|
>
|
|
297
352
|
> <!-- TODO(lishaduck): Add ts highlighting once denoland/deno#24164 is resolved -->
|
|
298
353
|
>
|
|
299
354
|
> ```
|
|
300
|
-
> import { stringify, type
|
|
355
|
+
> import { stringify, type XmlDocument } from "./stringify.ts"
|
|
301
356
|
>
|
|
302
357
|
> const ast = {
|
|
303
358
|
> "@version": "1.0",
|
|
304
359
|
> "@encoding": "UTF-8",
|
|
305
360
|
> "root": {},
|
|
306
|
-
> } satisfies Partial<
|
|
361
|
+
> } satisfies Partial<XmlDocument>
|
|
307
362
|
> const result = stringify(ast)
|
|
308
363
|
> ```
|
|
309
364
|
>
|
|
310
|
-
> We expose lax typing, but `Partial<
|
|
365
|
+
> We expose lax typing, but `Partial<XmlDocument>` uses the stricter typing we use internally.
|
|
311
366
|
|
|
312
367
|
## 📜 License and credits
|
|
313
368
|
|
package/_parser.d.ts
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared internals between the std-based ({@link ./parse.ts}) and WASM-based ({@link ./wasm/parse.ts}) XML parsers.
|
|
3
|
+
* @module
|
|
4
|
+
*/ import type { Nullable, XmlNode } from "./_types.js";
|
|
5
|
+
/** XML parser `clean` options. */ export type CleanOptions = {
|
|
6
|
+
/** Remove attributes from result. */ attributes?: boolean;
|
|
7
|
+
/** Remove comments from result. */ comments?: boolean;
|
|
8
|
+
/** Remove XML doctype from result. */ doctype?: boolean;
|
|
9
|
+
/** Remove XML processing instructions from result. */ instructions?: boolean;
|
|
10
|
+
};
|
|
11
|
+
/** XML parser `flatten` options. */ export type FlattenOptions = {
|
|
12
|
+
/** If node only contains attributes values (i.e. with key starting with `@`), it'll be flattened as a regular object without `@` prefixes. */ attributes?: boolean;
|
|
13
|
+
/** If node only contains a `#text` value, it'll be flattened as a string (defaults to `true`). */ text?: boolean;
|
|
14
|
+
/** If node does not contains any attribute or text, it'll be flattened to `null` (defaults to `true`). */ empty?: boolean;
|
|
15
|
+
};
|
|
16
|
+
/** XML parser `revive` options. */ export type ReviveOptions = {
|
|
17
|
+
/**
|
|
18
|
+
* Trim texts (this is applied before other revivals, defaults to `true`).
|
|
19
|
+
* It honors `xml:space="preserve"` attribute.
|
|
20
|
+
*/ trim?: boolean;
|
|
21
|
+
/**
|
|
22
|
+
* Revive XML entities (defaults to `true`).
|
|
23
|
+
* Automatically unescape XML entities and replace common entities with their respective characters.
|
|
24
|
+
*/ entities?: boolean;
|
|
25
|
+
/** Revive booleans (matching `/^(?:[Tt]rue|[Ff]alse)$/`).*/ booleans?: boolean;
|
|
26
|
+
/**
|
|
27
|
+
* Revive finite numbers.
|
|
28
|
+
* Note that the version of the XML prolog is always treated as a string to avoid breaking documents.
|
|
29
|
+
*/ numbers?: boolean;
|
|
30
|
+
/**
|
|
31
|
+
* Custom reviver (this is applied after other revivals).
|
|
32
|
+
* When it is applied on an attribute, `key` and `value` will be given.
|
|
33
|
+
* When it is applied on a node, both `key` and `value` will be `null`.
|
|
34
|
+
* Return `undefined` to delete either the attribute or the tag.
|
|
35
|
+
*/ custom?: Reviver;
|
|
36
|
+
};
|
|
37
|
+
/**
|
|
38
|
+
* Custom XML parser reviver.
|
|
39
|
+
* It can be used to change the way some nodes are parsed.
|
|
40
|
+
*/ export type Reviver = (args: {
|
|
41
|
+
name: string;
|
|
42
|
+
key: Nullable<string>;
|
|
43
|
+
value: Nullable<string>;
|
|
44
|
+
node: Readonly<XmlNode>;
|
|
45
|
+
}) => unknown;
|
package/_parser.js
ADDED
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared internals between the std-based ({@link ./parse.ts}) and WASM-based ({@link ./wasm/parse.ts}) XML parsers.
|
|
3
|
+
* @module
|
|
4
|
+
*/ // Imports
|
|
5
|
+
/** Apply parser option defaults and post-process the parsed document. */ export function finalize(xml, options) {
|
|
6
|
+
options ??= {};
|
|
7
|
+
options.revive ??= {};
|
|
8
|
+
options.revive.trim ??= true;
|
|
9
|
+
options.revive.entities ??= true;
|
|
10
|
+
options.flatten ??= {};
|
|
11
|
+
options.flatten.text ??= true;
|
|
12
|
+
options.flatten.empty ??= true;
|
|
13
|
+
if (!Object.keys(xml).length) throw new SyntaxError("Malformed XML document: empty document or no root node detected");
|
|
14
|
+
return postprocess(xml, options);
|
|
15
|
+
}
|
|
16
|
+
/** Attach a processing instruction under `#instructions` with array-grouping. */ export function xml_instruction(xml, name, raw) {
|
|
17
|
+
const instruction = Object.assign(xml_node(name, {
|
|
18
|
+
parent: xml
|
|
19
|
+
}), xml_attributes(raw));
|
|
20
|
+
xml["#instructions"] ??= {};
|
|
21
|
+
switch(true){
|
|
22
|
+
case Array.isArray(xml["#instructions"][name]):
|
|
23
|
+
;
|
|
24
|
+
xml["#instructions"][name].push(instruction);
|
|
25
|
+
break;
|
|
26
|
+
case name in xml["#instructions"]:
|
|
27
|
+
xml["#instructions"][name] = [
|
|
28
|
+
xml["#instructions"][name],
|
|
29
|
+
instruction
|
|
30
|
+
];
|
|
31
|
+
break;
|
|
32
|
+
default:
|
|
33
|
+
xml["#instructions"][name] = instruction;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
/** Parse xml attributes. */ export function xml_attributes(raw) {
|
|
37
|
+
const attributes = {};
|
|
38
|
+
for (const [_, name, __, value] of raw.matchAll(/(?<name>[A-Za-z_][-\w.:]*)=(["'])(?<value>(?:(?!\2).)*)(\2)/g))attributes[`@${name}`] = value;
|
|
39
|
+
return attributes;
|
|
40
|
+
}
|
|
41
|
+
/** Parse xml doctype. */ export function xml_doctype(raw) {
|
|
42
|
+
const node = {};
|
|
43
|
+
const { attributes: _attributes, elements: _elements = "" } = raw.match(/^(?<attributes>[^\[]*)(?:\[(?<elements>[\s\S]*)\])?/)?.groups;
|
|
44
|
+
// Parse attributes
|
|
45
|
+
raw = raw.replace(`[${_elements}]`, "");
|
|
46
|
+
for (const [match, __, name] of _attributes.matchAll(/(["'])(?<name>(?:(?!\1).)*)(\1)/g)){
|
|
47
|
+
node[`@${name}`] = "";
|
|
48
|
+
raw = raw.replace(match, "");
|
|
49
|
+
}
|
|
50
|
+
raw.split(/\s+/).filter(Boolean).forEach((name)=>node[`@${name}`] = "");
|
|
51
|
+
// Parse elements
|
|
52
|
+
for (const [_, name, value] of _elements.matchAll(/<!ELEMENT\s+(?<name>\w+)\s+\((?<value>[^\)]+)\)/g))node[name] = value;
|
|
53
|
+
return node;
|
|
54
|
+
}
|
|
55
|
+
/** Create a new text node. */ export function xml_text(value, { type = "~text", parent = null } = {}) {
|
|
56
|
+
const text = Object.defineProperties({}, {
|
|
57
|
+
["~parent"]: {
|
|
58
|
+
enumerable: false,
|
|
59
|
+
writable: false,
|
|
60
|
+
value: parent
|
|
61
|
+
},
|
|
62
|
+
["~name"]: {
|
|
63
|
+
enumerable: false,
|
|
64
|
+
writable: false,
|
|
65
|
+
value: type
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
text["#text"] = value;
|
|
69
|
+
if (parent) parent["~children"].push(text);
|
|
70
|
+
return text;
|
|
71
|
+
}
|
|
72
|
+
/** Create a new element node and attach it under its parent's enumerable key with array-grouping. */ export function xml_element(name, parent) {
|
|
73
|
+
const node = xml_node(name, {
|
|
74
|
+
parent
|
|
75
|
+
});
|
|
76
|
+
switch(true){
|
|
77
|
+
case Array.isArray(parent[node["~name"]]):
|
|
78
|
+
;
|
|
79
|
+
parent[node["~name"]].push(node);
|
|
80
|
+
break;
|
|
81
|
+
case node["~name"] in parent:
|
|
82
|
+
parent[node["~name"]] = [
|
|
83
|
+
parent[node["~name"]],
|
|
84
|
+
node
|
|
85
|
+
];
|
|
86
|
+
break;
|
|
87
|
+
default:
|
|
88
|
+
parent[node["~name"]] = node;
|
|
89
|
+
}
|
|
90
|
+
return node;
|
|
91
|
+
}
|
|
92
|
+
/** Create a new node. */ export function xml_node(name, { parent = null } = {}) {
|
|
93
|
+
const node = Object.defineProperties({}, {
|
|
94
|
+
["~parent"]: {
|
|
95
|
+
enumerable: false,
|
|
96
|
+
writable: false,
|
|
97
|
+
value: parent
|
|
98
|
+
},
|
|
99
|
+
["~name"]: {
|
|
100
|
+
enumerable: false,
|
|
101
|
+
writable: false,
|
|
102
|
+
value: name
|
|
103
|
+
},
|
|
104
|
+
["~children"]: {
|
|
105
|
+
enumerable: false,
|
|
106
|
+
writable: true,
|
|
107
|
+
value: []
|
|
108
|
+
},
|
|
109
|
+
["#text"]: {
|
|
110
|
+
enumerable: false,
|
|
111
|
+
configurable: true,
|
|
112
|
+
get () {
|
|
113
|
+
const children = this["~children"].filter((node)=>node["~name"] !== "~comment");
|
|
114
|
+
// If xml:space is not set to "preserve", concatenate text nodes and trim them while removing empty ones
|
|
115
|
+
if (this["@xml:space"] !== "preserve") return children.map((child)=>child["#text"]).filter(Boolean).join(" ");
|
|
116
|
+
// If xml:space is set to "preserve", concatenate text nodes without trimming them
|
|
117
|
+
// In case of mixed content, add a space between mixed nodes if needed
|
|
118
|
+
let text = "";
|
|
119
|
+
for(let i = 0; i < children.length; i++){
|
|
120
|
+
const spaced = i && +children[i - 1]["~name"].startsWith("~") ^ +children[i]["~name"].startsWith("~") && !children[i - 1]["#text"].endsWith(" ") && !children[i]["#text"].startsWith(" ");
|
|
121
|
+
text += `${spaced ? " " : ""}${children[i]["#text"]}`;
|
|
122
|
+
}
|
|
123
|
+
return text;
|
|
124
|
+
}
|
|
125
|
+
},
|
|
126
|
+
["#comments"]: {
|
|
127
|
+
enumerable: false,
|
|
128
|
+
configurable: true,
|
|
129
|
+
get () {
|
|
130
|
+
return this["~children"].filter((node)=>node["~name"] === "~comment").map((node)=>node["#text"]);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
});
|
|
134
|
+
if (parent) parent["~children"].push(node);
|
|
135
|
+
return node;
|
|
136
|
+
}
|
|
137
|
+
/** Post-process xml node. */ function postprocess(node, options) {
|
|
138
|
+
// Clean XML document if required
|
|
139
|
+
if (node["~name"] === "~xml") {
|
|
140
|
+
if (options?.clean?.doctype) delete node["#doctype"];
|
|
141
|
+
if (options?.clean?.instructions) {
|
|
142
|
+
;
|
|
143
|
+
node["~children"] = node["~children"].filter((child)=>!(child["~name"] in (node["#instructions"] ?? {})));
|
|
144
|
+
delete node["#instructions"];
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
// Clean node and enable enumerable properties if required
|
|
148
|
+
if (node["~children"]) {
|
|
149
|
+
if (options?.clean?.comments) {
|
|
150
|
+
;
|
|
151
|
+
node["~children"] = node["~children"].filter((child)=>child["~name"] !== "~comment");
|
|
152
|
+
}
|
|
153
|
+
if (options?.revive?.trim) node["~children"].forEach((child)=>/^~(?:text|cdata|comment)$/.test(child["~name"]) ? child["#text"] = revive(child, "#text", {
|
|
154
|
+
revive: {
|
|
155
|
+
trim: node["@xml:space"] !== "preserve"
|
|
156
|
+
}
|
|
157
|
+
}) : null);
|
|
158
|
+
if (node["~children"].some((child)=>/^~(?:text|cdata)$/.test(child["~name"]) && child["#text"].trim().length + (node["@xml:space"] === "preserve" ? 1 : 0) * child["#text"].length)) Object.defineProperty(node, "#text", {
|
|
159
|
+
enumerable: true,
|
|
160
|
+
configurable: true
|
|
161
|
+
});
|
|
162
|
+
if (node["~children"].some((child)=>child["~name"] === "~comment")) Object.defineProperty(node, "#comments", {
|
|
163
|
+
enumerable: true,
|
|
164
|
+
configurable: true
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
// Process child nodes
|
|
168
|
+
for (const [key, value] of Object.entries(node)){
|
|
169
|
+
// Skip comments
|
|
170
|
+
if (key === "#comments") continue;
|
|
171
|
+
// Clean attributes if required
|
|
172
|
+
if (options?.clean?.attributes && key.startsWith("@")) {
|
|
173
|
+
delete node[key];
|
|
174
|
+
continue;
|
|
175
|
+
}
|
|
176
|
+
// Revive attribute value if required
|
|
177
|
+
if (key.startsWith("@")) {
|
|
178
|
+
node[key] = revive(node, key, options);
|
|
179
|
+
if (node[key] === undefined) delete node[key];
|
|
180
|
+
continue;
|
|
181
|
+
}
|
|
182
|
+
// Handle other nodes
|
|
183
|
+
if (Array.isArray(value)) {
|
|
184
|
+
node[key] = Object.defineProperties(value.map((child)=>postprocess(child, options)), {
|
|
185
|
+
["~parent"]: {
|
|
186
|
+
enumerable: false,
|
|
187
|
+
writable: false,
|
|
188
|
+
value: node
|
|
189
|
+
},
|
|
190
|
+
["~name"]: {
|
|
191
|
+
enumerable: false,
|
|
192
|
+
writable: false,
|
|
193
|
+
value: key
|
|
194
|
+
}
|
|
195
|
+
});
|
|
196
|
+
} else if (typeof value === "object" && value) {
|
|
197
|
+
node[key] = postprocess(value, options);
|
|
198
|
+
}
|
|
199
|
+
if (node[key] === undefined) delete node[key];
|
|
200
|
+
}
|
|
201
|
+
// Revive text if required
|
|
202
|
+
const keys = Object.keys(node);
|
|
203
|
+
if (keys.includes("#text")) {
|
|
204
|
+
const _options = {
|
|
205
|
+
...options,
|
|
206
|
+
revive: {
|
|
207
|
+
...options?.revive,
|
|
208
|
+
trim: options?.revive?.trim && node["@xml:space"] !== "preserve"
|
|
209
|
+
}
|
|
210
|
+
};
|
|
211
|
+
Object.defineProperty(node, "#text", {
|
|
212
|
+
enumerable: true,
|
|
213
|
+
configurable: true,
|
|
214
|
+
value: revive(node, "#text", _options)
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
// Custom revival if required
|
|
218
|
+
if (options?.revive?.custom) {
|
|
219
|
+
if (options.revive.custom({
|
|
220
|
+
name: node["~name"],
|
|
221
|
+
key: null,
|
|
222
|
+
value: null,
|
|
223
|
+
node: node
|
|
224
|
+
}) === undefined) return undefined;
|
|
225
|
+
}
|
|
226
|
+
// Flatten object if required
|
|
227
|
+
if (options?.flatten?.text && keys.length === 1 && keys.includes("#text")) return node["#text"];
|
|
228
|
+
if (options?.flatten?.attributes && keys.length && keys.every((key)=>key.startsWith("@"))) {
|
|
229
|
+
for (const key of keys){
|
|
230
|
+
node[key.slice(1)] = node[key];
|
|
231
|
+
delete node[key];
|
|
232
|
+
}
|
|
233
|
+
return node;
|
|
234
|
+
}
|
|
235
|
+
if (!keys.length) return options?.flatten?.empty ? null : options?.flatten?.text ? "" : Object.defineProperty(node, "#text", {
|
|
236
|
+
enumerable: true,
|
|
237
|
+
configurable: true,
|
|
238
|
+
value: ""
|
|
239
|
+
});
|
|
240
|
+
return node;
|
|
241
|
+
}
|
|
242
|
+
/** Entities */ const entities = {
|
|
243
|
+
"<": "<",
|
|
244
|
+
">": ">",
|
|
245
|
+
"'": "'",
|
|
246
|
+
""": '"',
|
|
247
|
+
"&": "&"
|
|
248
|
+
};
|
|
249
|
+
/** Revive value. */ function revive(node, key, options) {
|
|
250
|
+
let value = node[key];
|
|
251
|
+
if (options?.revive?.trim) value = value.trim();
|
|
252
|
+
if (options?.revive?.entities) {
|
|
253
|
+
value = value.replaceAll(/&#(?<hex>x?)(?<code>[A-Fa-f\d]+);/g, (_, hex, code)=>String.fromCharCode(Number.parseInt(code, hex ? 16 : 10)));
|
|
254
|
+
for (const [entity, character] of Object.entries(entities))value = value.replaceAll(entity, character);
|
|
255
|
+
}
|
|
256
|
+
if (options?.revive?.numbers && value.length && Number.isFinite(Number(value)) && !(node["~name"] === "~xml" && key === "@version")) value = Number(value);
|
|
257
|
+
if (options?.revive?.booleans && /^(?:[Tt]rue|[Ff]alse)$/.test(value)) value = /^[Tt]rue$/.test(value);
|
|
258
|
+
if (options?.revive?.custom) return options.revive.custom({
|
|
259
|
+
name: node["~name"],
|
|
260
|
+
key,
|
|
261
|
+
value,
|
|
262
|
+
node: node
|
|
263
|
+
});
|
|
264
|
+
return value;
|
|
265
|
+
}
|
|
266
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImZpbGU6Ly8vaG9tZS9ydW5uZXIvd29yay9saWJzL2xpYnMvQGxpYnMveG1sL19wYXJzZXIudHMiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBTaGFyZWQgaW50ZXJuYWxzIGJldHdlZW4gdGhlIHN0ZC1iYXNlZCAoe0BsaW5rIC4vcGFyc2UudHN9KSBhbmQgV0FTTS1iYXNlZCAoe0BsaW5rIC4vd2FzbS9wYXJzZS50c30pIFhNTCBwYXJzZXJzLlxuICogQG1vZHVsZVxuICovXG5cbi8vIEltcG9ydHNcbmltcG9ydCB0eXBlIHsgTnVsbGFibGUsIFhtbERvY3VtZW50LCBYbWxOb2RlLCBYbWxUZXh0IH0gZnJvbSBcIi4vX3R5cGVzLmpzXCJcblxuLyoqIFhNTCBwYXJzZXIgYGNsZWFuYCBvcHRpb25zLiAqL1xuZXhwb3J0IHR5cGUgQ2xlYW5PcHRpb25zID0ge1xuICAvKiogUmVtb3ZlIGF0dHJpYnV0ZXMgZnJvbSByZXN1bHQuICovXG4gIGF0dHJpYnV0ZXM/OiBib29sZWFuXG4gIC8qKiBSZW1vdmUgY29tbWVudHMgZnJvbSByZXN1bHQuICovXG4gIGNvbW1lbnRzPzogYm9vbGVhblxuICAvKiogUmVtb3ZlIFhNTCBkb2N0eXBlIGZyb20gcmVzdWx0LiAqL1xuICBkb2N0eXBlPzogYm9vbGVhblxuICAvKiogUmVtb3ZlIFhNTCBwcm9jZXNzaW5nIGluc3RydWN0aW9ucyBmcm9tIHJlc3VsdC4gKi9cbiAgaW5zdHJ1Y3Rpb25zPzogYm9vbGVhblxufVxuXG4vKiogWE1MIHBhcnNlciBgZmxhdHRlbmAgb3B0aW9ucy4gKi9cbmV4cG9ydCB0eXBlIEZsYXR0ZW5PcHRpb25zID0ge1xuICAvKiogSWYgbm9kZSBvbmx5IGNvbnRhaW5zIGF0dHJpYnV0ZXMgdmFsdWVzIChpLmUuIHdpdGgga2V5IHN0YXJ0aW5nIHdpdGggYEBgKSwgaXQnbGwgYmUgZmxhdHRlbmVkIGFzIGEgcmVndWxhciBvYmplY3Qgd2l0aG91dCBgQGAgcHJlZml4ZXMuICovXG4gIGF0dHJpYnV0ZXM/OiBib29sZWFuXG4gIC8qKiBJZiBub2RlIG9ubHkgY29udGFpbnMgYSBgI3RleHRgIHZhbHVlLCBpdCdsbCBiZSBmbGF0dGVuZWQgYXMgYSBzdHJpbmcgKGRlZmF1bHRzIHRvIGB0cnVlYCkuICovXG4gIHRleHQ/OiBib29sZWFuXG4gIC8qKiBJZiBub2RlIGRvZXMgbm90IGNvbnRhaW5zIGFueSBhdHRyaWJ1dGUgb3IgdGV4dCwgaXQnbGwgYmUgZmxhdHRlbmVkIHRvIGBudWxsYCAoZGVmYXVsdHMgdG8gYHRydWVgKS4gKi9cbiAgZW1wdHk/OiBib29sZWFuXG59XG5cbi8qKiBYTUwgcGFyc2VyIGByZXZpdmVgIG9wdGlvbnMuICovXG5leHBvcnQgdHlwZSBSZXZpdmVPcHRpb25zID0ge1xuICAvKipcbiAgICogVHJpbSB0ZXh0cyAodGhpcyBpcyBhcHBsaWVkIGJlZm9yZSBvdGhlciByZXZpdmFscywgZGVmYXVsdHMgdG8gYHRydWVgKS5cbiAgICogSXQgaG9ub3JzIGB4bWw6c3BhY2U9XCJwcmVzZXJ2ZVwiYCBhdHRyaWJ1dGUuXG4gICAqL1xuICB0cmltPzogYm9vbGVhblxuICAvKipcbiAgICogUmV2aXZlIFhNTCBlbnRpdGllcyAoZGVmYXVsdHMgdG8gYHRydWVgKS5cbiAgICogQXV0b21hdGljYWxseSB1bmVzY2FwZSBYTUwgZW50aXRpZXMgYW5kIHJlcGxhY2UgY29tbW9uIGVudGl0aWVzIHdpdGggdGhlaXIgcmVzcGVjdGl2ZSBjaGFyYWN0ZXJzLlxuICAgKi9cbiAgZW50aXRpZXM/OiBib29sZWFuXG4gIC8qKiBSZXZpdmUgYm9vbGVhbnMgKG1hdGNoaW5nIGAvXig/OltUdF1ydWV8W0ZmXWFsc2UpJC9gKS4qL1xuICBib29sZWFucz86IGJvb2xlYW5cbiAgLyoqXG4gICAqIFJldml2ZSBmaW5pdGUgbnVtYmVycy5cbiAgICogTm90ZSB0aGF0IHRoZSB2ZXJzaW9uIG9mIHRoZSBYTUwgcHJvbG9nIGlzIGFsd2F5cyB0cmVhdGVkIGFzIGEgc3RyaW5nIHRvIGF2b2lkIGJyZWFraW5nIGRvY3VtZW50cy5cbiAgICovXG4gIG51bWJlcnM/OiBib29sZWFuXG4gIC8qKlxuICAgKiBDdXN0b20gcmV2aXZlciAodGhpcyBpcyBhcHBsaWVkIGFmdGVyIG90aGVyIHJldml2YWxzKS5cbiAgICogV2hlbiBpdCBpcyBhcHBsaWVkIG9uIGFuIGF0dHJpYnV0ZSwgYGtleWAgYW5kIGB2YWx1ZWAgd2lsbCBiZSBnaXZlbi5cbiAgICogV2hlbiBpdCBpcyBhcHBsaWVkIG9uIGEgbm9kZSwgYm90aCBga2V5YCBhbmQgYHZhbHVlYCB3aWxsIGJlIGBudWxsYC5cbiAgICogUmV0dXJuIGB1bmRlZmluZWRgIHRvIGRlbGV0ZSBlaXRoZXIgdGhlIGF0dHJpYnV0ZSBvciB0aGUgdGFnLlxuICAgKi9cbiAgY3VzdG9tPzogUmV2aXZlclxufVxuXG4vKipcbiAqIEN1c3RvbSBYTUwgcGFyc2VyIHJldml2ZXIuXG4gKiBJdCBjYW4gYmUgdXNlZCB0byBjaGFuZ2UgdGhlIHdheSBzb21lIG5vZGVzIGFyZSBwYXJzZWQuXG4gKi9cbmV4cG9ydCB0eXBlIFJldml2ZXIgPSAoYXJnczogeyBuYW1lOiBzdHJpbmc7IGtleTogTnVsbGFibGU8c3RyaW5nPjsgdmFsdWU6IE51bGxhYmxlPHN0cmluZz47IG5vZGU6IFJlYWRvbmx5PFhtbE5vZGU+IH0pID0+IHVua25vd25cblxuLyoqIEJhY2tlbmQtYWdub3N0aWMgcGFyc2VyIG9wdGlvbnMgKGVhY2ggYmFja2VuZCBleHRlbmRzIGl0IHdpdGggaXRzIG93biBzdXBwb3J0ZWQgYG1vZGVgKS4gKi9cbmV4cG9ydCB0eXBlIFBhcnNlck9wdGlvbnMgPSB7XG4gIC8qKiBSZW1vdmUgZWxlbWVudHMgZnJvbSByZXN1bHQuICovXG4gIGNsZWFuPzogQ2xlYW5PcHRpb25zXG4gIC8qKiBGbGF0dGVuIHJlc3VsdCBkZXBlbmRpbmcgb24gbm9kZSBjb250ZW50LiAqL1xuICBmbGF0dGVuPzogRmxhdHRlbk9wdGlvbnNcbiAgLyoqIFJldml2ZSByZXN1bHQuICovXG4gIHJldml2ZT86IFJldml2ZU9wdGlvbnNcbn1cblxuLyoqIEFwcGx5IHBhcnNlciBvcHRpb24gZGVmYXVsdHMgYW5kIHBvc3QtcHJvY2VzcyB0aGUgcGFyc2VkIGRvY3VtZW50LiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGZpbmFsaXplKHhtbDogWG1sRG9jdW1lbnQsIG9wdGlvbnM/OiBQYXJzZXJPcHRpb25zKTogWG1sRG9jdW1lbnQge1xuICBvcHRpb25zID8/PSB7fVxuICBvcHRpb25zLnJldml2ZSA/Pz0ge31cbiAgb3B0aW9ucy5yZXZpdmUudHJpbSA/Pz0gdHJ1ZVxuICBvcHRpb25zLnJldml2ZS5lbnRpdGllcyA/Pz0gdHJ1ZVxuICBvcHRpb25zLmZsYXR0ZW4gPz89IHt9XG4gIG9wdGlvbnMuZmxhdHRlbi50ZXh0ID8/PSB0cnVlXG4gIG9wdGlvbnMuZmxhdHRlbi5lbXB0eSA/Pz0gdHJ1ZVxuICBpZiAoIU9iamVjdC5rZXlzKHhtbCkubGVuZ3RoKVxuICAgIHRocm93IG5ldyBTeW50YXhFcnJvcihcIk1hbGZvcm1lZCBYTUwgZG9jdW1lbnQ6IGVtcHR5IGRvY3VtZW50IG9yIG5vIHJvb3Qgbm9kZSBkZXRlY3RlZFwiKVxuICByZXR1cm4gcG9zdHByb2Nlc3MoeG1sLCBvcHRpb25zKSBhcyBYbWxEb2N1bWVudFxufVxuXG4vKiogQXR0YWNoIGEgcHJvY2Vzc2luZyBpbnN0cnVjdGlvbiB1bmRlciBgI2luc3RydWN0aW9uc2Agd2l0aCBhcnJheS1ncm91cGluZy4gICovXG5leHBvcnQgZnVuY3Rpb24geG1sX2luc3RydWN0aW9uKHhtbDogWG1sRG9jdW1lbnQsIG5hbWU6IHN0cmluZywgcmF3OiBzdHJpbmcpOiB2b2lkIHtcbiAgY29uc3QgaW5zdHJ1Y3Rpb24gPSBPYmplY3QuYXNzaWduKHhtbF9ub2RlKG5hbWUsIHsgcGFyZW50OiB4bWwgfSksIHhtbF9hdHRyaWJ1dGVzKHJhdykpXG4gIHhtbFtcIiNpbnN0cnVjdGlvbnNcIl0gPz89IHt9XG4gIHN3aXRjaCAodHJ1ZSkge1xuICAgIGNhc2UgQXJyYXkuaXNBcnJheSh4bWxbXCIjaW5zdHJ1Y3Rpb25zXCJdW25hbWVdKTpcbiAgICAgIDsoeG1sW1wiI2luc3RydWN0aW9uc1wiXVtuYW1lXSBhcyBBcnJheTxYbWxOb2RlPikucHVzaChpbnN0cnVjdGlvbilcbiAgICAgIGJyZWFrXG4gICAgY2FzZSBuYW1lIGluIHhtbFtcIiNpbnN0cnVjdGlvbnNcIl06XG4gICAgICB4bWxbXCIjaW5zdHJ1Y3Rpb25zXCJdW25hbWVdID0gW3htbFtcIiNpbnN0cnVjdGlvbnNcIl1bbmFtZV0gYXMgWG1sTm9kZSwgaW5zdHJ1Y3Rpb25dXG4gICAgICBicmVha1xuICAgIGRlZmF1bHQ6XG4gICAgICB4bWxbXCIjaW5zdHJ1Y3Rpb25zXCJdW25hbWVdID0gaW5zdHJ1Y3Rpb25cbiAgfVxufVxuXG4vKiogUGFyc2UgeG1sIGF0dHJpYnV0ZXMuICovXG5leHBvcnQgZnVuY3Rpb24geG1sX2F0dHJpYnV0ZXMocmF3OiBzdHJpbmcpOiBSZWNvcmQ8UHJvcGVydHlLZXksIHN0cmluZz4ge1xuICBjb25zdCBhdHRyaWJ1dGVzID0ge30gYXMgUmVjb3JkPFByb3BlcnR5S2V5LCBzdHJpbmc+XG4gIGZvciAoY29uc3QgW18sIG5hbWUsIF9fLCB2YWx1ZV0gb2YgcmF3Lm1hdGNoQWxsKC8oPzxuYW1lPltBLVphLXpfXVstXFx3LjpdKik9KFtcIiddKSg/PHZhbHVlPig/Oig/IVxcMikuKSopKFxcMikvZykpXG4gICAgYXR0cmlidXRlc1tgQCR7bmFtZX1gXSA9IHZhbHVlXG4gIHJldHVybiBhdHRyaWJ1dGVzXG59XG5cbi8qKiBQYXJzZSB4bWwgZG9jdHlwZS4gKi9cbmV4cG9ydCBmdW5jdGlvbiB4bWxfZG9jdHlwZShyYXc6IHN0cmluZyk6IFhtbE5vZGUge1xuICBjb25zdCBub2RlID0ge30gYXMgWG1sTm9kZVxuICBjb25zdCB7IGF0dHJpYnV0ZXM6IF9hdHRyaWJ1dGVzLCBlbGVtZW50czogX2VsZW1lbnRzID0gXCJcIiB9ID0gcmF3Lm1hdGNoKC9eKD88YXR0cmlidXRlcz5bXlxcW10qKSg/OlxcWyg/PGVsZW1lbnRzPltcXHNcXFNdKilcXF0pPy8pPy5ncm91cHMhXG4gIC8vIFBhcnNlIGF0dHJpYnV0ZXNcbiAgcmF3ID0gcmF3LnJlcGxhY2UoYFske19lbGVtZW50c31dYCwgXCJcIilcbiAgZm9yIChjb25zdCBbbWF0Y2gsIF9fLCBuYW1lXSBvZiBfYXR0cmlidXRlcy5tYXRjaEFsbCgvKFtcIiddKSg/PG5hbWU+KD86KD8hXFwxKS4pKikoXFwxKS9nKSkge1xuICAgIG5vZGVbYEAke25hbWV9YF0gPSBcIlwiXG4gICAgcmF3ID0gcmF3LnJlcGxhY2UobWF0Y2gsIFwiXCIpXG4gIH1cbiAgcmF3LnNwbGl0KC9cXHMrLykuZmlsdGVyKEJvb2xlYW4pLmZvckVhY2goKG5hbWUpID0+IG5vZGVbYEAke25hbWV9YF0gPSBcIlwiKVxuICAvLyBQYXJzZSBlbGVtZW50c1xuICBmb3IgKGNvbnN0IFtfLCBuYW1lLCB2YWx1ZV0gb2YgX2VsZW1lbnRzLm1hdGNoQWxsKC88IUVMRU1FTlRcXHMrKD88bmFtZT5cXHcrKVxccytcXCgoPzx2YWx1ZT5bXlxcKV0rKVxcKS9nKSlcbiAgICBub2RlW25hbWVdID0gdmFsdWVcbiAgcmV0dXJuIG5vZGVcbn1cblxuLyoqIENyZWF0ZSBhIG5ldyB0ZXh0IG5vZGUuICovXG5leHBvcnQgZnVuY3Rpb24geG1sX3RleHQodmFsdWU6IHN0cmluZywgeyB0eXBlID0gXCJ+dGV4dFwiIGFzIFwifnRleHRcIiB8IFwifmNkYXRhXCIgfCBcIn5jb21tZW50XCIsIHBhcmVudCA9IG51bGwgYXMgTnVsbGFibGU8WG1sTm9kZT4gfSA9IHt9KTogWG1sVGV4dCB7XG4gIGNvbnN0IHRleHQgPSBPYmplY3QuZGVmaW5lUHJvcGVydGllcyh7fSwge1xuICAgIFtcIn5wYXJlbnRcIl06IHsgZW51bWVyYWJsZTogZmFsc2UsIHdyaXRhYmxlOiBmYWxzZSwgdmFsdWU6IHBhcmVudCB9LFxuICAgIFtcIn5uYW1lXCJdOiB7IGVudW1lcmFibGU6IGZhbHNlLCB3cml0YWJsZTogZmFsc2UsIHZhbHVlOiB0eXBlIH0sXG4gIH0pIGFzIFhtbFRleHRcbiAgdGV4dFtcIiN0ZXh0XCJdID0gdmFsdWVcbiAgaWYgKHBhcmVudClcbiAgICBwYXJlbnRbXCJ+Y2hpbGRyZW5cIl0ucHVzaCh0ZXh0KVxuICByZXR1cm4gdGV4dFxufVxuXG4vKiogQ3JlYXRlIGEgbmV3IGVsZW1lbnQgbm9kZSBhbmQgYXR0YWNoIGl0IHVuZGVyIGl0cyBwYXJlbnQncyBlbnVtZXJhYmxlIGtleSB3aXRoIGFycmF5LWdyb3VwaW5nLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHhtbF9lbGVtZW50KG5hbWU6IHN0cmluZywgcGFyZW50OiBYbWxOb2RlKTogWG1sTm9kZSB7XG4gIGNvbnN0IG5vZGUgPSB4bWxfbm9kZShuYW1lLCB7IHBhcmVudCB9KVxuICBzd2l0Y2ggKHRydWUpIHtcbiAgICBjYXNlIEFycmF5LmlzQXJyYXkocGFyZW50W25vZGVbXCJ+bmFtZVwiXV0pOlxuICAgICAgOyhwYXJlbnRbbm9kZVtcIn5uYW1lXCJdXSBhcyBBcnJheTxYbWxOb2RlPikucHVzaChub2RlKVxuICAgICAgYnJlYWtcbiAgICBjYXNlIG5vZGVbXCJ+bmFtZVwiXSBpbiBwYXJlbnQ6XG4gICAgICBwYXJlbnRbbm9kZVtcIn5uYW1lXCJdXSA9IFtwYXJlbnRbbm9kZVtcIn5uYW1lXCJdXSwgbm9kZV1cbiAgICAgIGJyZWFrXG4gICAgZGVmYXVsdDpcbiAgICAgIHBhcmVudFtub2RlW1wifm5hbWVcIl1dID0gbm9kZVxuICB9XG4gIHJldHVybiBub2RlXG59XG5cbi8qKiBDcmVhdGUgYSBuZXcgbm9kZS4gKi9cbmV4cG9ydCBmdW5jdGlvbiB4bWxfbm9kZShuYW1lOiBzdHJpbmcsIHsgcGFyZW50ID0gbnVsbCBhcyBOdWxsYWJsZTxYbWxOb2RlPiB9ID0ge30pOiBYbWxOb2RlIHtcbiAgY29uc3Qgbm9kZSA9IE9iamVjdC5kZWZpbmVQcm9wZXJ0aWVzKHt9LCB7XG4gICAgW1wifnBhcmVudFwiXTogeyBlbnVtZXJhYmxlOiBmYWxzZSwgd3JpdGFibGU6IGZhbHNlLCB2YWx1ZTogcGFyZW50IH0sXG4gICAgW1wifm5hbWVcIl06IHsgZW51bWVyYWJsZTogZmFsc2UsIHdyaXRhYmxlOiBmYWxzZSwgdmFsdWU6IG5hbWUgfSxcbiAgICBbXCJ+Y2hpbGRyZW5cIl06IHsgZW51bWVyYWJsZTogZmFsc2UsIHdyaXRhYmxlOiB0cnVlLCB2YWx1ZTogW10gfSxcbiAgICBbXCIjdGV4dFwiXToge1xuICAgICAgZW51bWVyYWJsZTogZmFsc2UsXG4gICAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgICBnZXQodGhpczogWG1sTm9kZSkge1xuICAgICAgICBjb25zdCBjaGlsZHJlbiA9IHRoaXNbXCJ+Y2hpbGRyZW5cIl0uZmlsdGVyKChub2RlKSA9PiBub2RlW1wifm5hbWVcIl0gIT09IFwifmNvbW1lbnRcIilcbiAgICAgICAgLy8gSWYgeG1sOnNwYWNlIGlzIG5vdCBzZXQgdG8gXCJwcmVzZXJ2ZVwiLCBjb25jYXRlbmF0ZSB0ZXh0IG5vZGVzIGFuZCB0cmltIHRoZW0gd2hpbGUgcmVtb3ZpbmcgZW1wdHkgb25lc1xuICAgICAgICBpZiAodGhpc1tcIkB4bWw6c3BhY2VcIl0gIT09IFwicHJlc2VydmVcIilcbiAgICAgICAgICByZXR1cm4gY2hpbGRyZW4ubWFwKChjaGlsZCkgPT4gY2hpbGRbXCIjdGV4dFwiXSkuZmlsdGVyKEJvb2xlYW4pLmpvaW4oXCIgXCIpXG4gICAgICAgIC8vIElmIHhtbDpzcGFjZSBpcyBzZXQgdG8gXCJwcmVzZXJ2ZVwiLCBjb25jYXRlbmF0ZSB0ZXh0IG5vZGVzIHdpdGhvdXQgdHJpbW1pbmcgdGhlbVxuICAgICAgICAvLyBJbiBjYXNlIG9mIG1peGVkIGNvbnRlbnQsIGFkZCBhIHNwYWNlIGJldHdlZW4gbWl4ZWQgbm9kZXMgaWYgbmVlZGVkXG4gICAgICAgIGxldCB0ZXh0ID0gXCJcIlxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGNoaWxkcmVuLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgY29uc3Qgc3BhY2VkID0gaSAmJiAoK2NoaWxkcmVuW2kgLSAxXVtcIn5uYW1lXCJdLnN0YXJ0c1dpdGgoXCJ+XCIpIF4gK2NoaWxkcmVuW2ldW1wifm5hbWVcIl0uc3RhcnRzV2l0aChcIn5cIikpICYmICghY2hpbGRyZW5baSAtIDFdW1wiI3RleHRcIl0uZW5kc1dpdGgoXCIgXCIpKSAmJiAoIWNoaWxkcmVuW2ldW1wiI3RleHRcIl0uc3RhcnRzV2l0aChcIiBcIikpXG4gICAgICAgICAgdGV4dCArPSBgJHtzcGFjZWQgPyBcIiBcIiA6IFwiXCJ9JHtjaGlsZHJlbltpXVtcIiN0ZXh0XCJdfWBcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGV4dFxuICAgICAgfSxcbiAgICB9LFxuICAgIFtcIiNjb21tZW50c1wiXToge1xuICAgICAgZW51bWVyYWJsZTogZmFsc2UsXG4gICAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgICBnZXQodGhpczogWG1sTm9kZSkge1xuICAgICAgICByZXR1cm4gdGhpc1tcIn5jaGlsZHJlblwiXS5maWx0ZXIoKG5vZGUpID0+IG5vZGVbXCJ+bmFtZVwiXSA9PT0gXCJ+Y29tbWVudFwiKS5tYXAoKG5vZGUpID0+IG5vZGVbXCIjdGV4dFwiXSEpXG4gICAgICB9LFxuICAgIH0sXG4gIH0pIGFzIFhtbE5vZGVcbiAgaWYgKHBhcmVudClcbiAgICBwYXJlbnRbXCJ+Y2hpbGRyZW5cIl0ucHVzaChub2RlKVxuICByZXR1cm4gbm9kZVxufVxuXG4vKiogUG9zdC1wcm9jZXNzIHhtbCBub2RlLiAqL1xuZnVuY3Rpb24gcG9zdHByb2Nlc3Mobm9kZTogWG1sTm9kZSwgb3B0aW9uczogUGFyc2VyT3B0aW9ucykge1xuICAvLyBDbGVhbiBYTUwgZG9jdW1lbnQgaWYgcmVxdWlyZWRcbiAgaWYgKG5vZGVbXCJ+bmFtZVwiXSA9PT0gXCJ+eG1sXCIpIHtcbiAgICBpZiAob3B0aW9ucz8uY2xlYW4/LmRvY3R5cGUpXG4gICAgICBkZWxldGUgbm9kZVtcIiNkb2N0eXBlXCJdXG4gICAgaWYgKG9wdGlvbnM/LmNsZWFuPy5pbnN0cnVjdGlvbnMpIHtcbiAgICAgIDsobm9kZSBhcyBSZWNvcmQ8UHJvcGVydHlLZXksIHVua25vd24+KVtcIn5jaGlsZHJlblwiXSA9IG5vZGVbXCJ+Y2hpbGRyZW5cIl0uZmlsdGVyKChjaGlsZCkgPT4gIShjaGlsZFtcIn5uYW1lXCJdIGluICgobm9kZSBhcyBYbWxEb2N1bWVudClbXCIjaW5zdHJ1Y3Rpb25zXCJdID8/IHt9KSkpXG4gICAgICBkZWxldGUgbm9kZVtcIiNpbnN0cnVjdGlvbnNcIl1cbiAgICB9XG4gIH1cbiAgLy8gQ2xlYW4gbm9kZSBhbmQgZW5hYmxlIGVudW1lcmFibGUgcHJvcGVydGllcyBpZiByZXF1aXJlZFxuICBpZiAobm9kZVtcIn5jaGlsZHJlblwiXSkge1xuICAgIGlmIChvcHRpb25zPy5jbGVhbj8uY29tbWVudHMpIHtcbiAgICAgIDsobm9kZSBhcyBSZWNvcmQ8UHJvcGVydHlLZXksIHVua25vd24+KVtcIn5jaGlsZHJlblwiXSA9IG5vZGVbXCJ+Y2hpbGRyZW5cIl0uZmlsdGVyKChjaGlsZCkgPT4gY2hpbGRbXCJ+bmFtZVwiXSAhPT0gXCJ+Y29tbWVudFwiKVxuICAgIH1cbiAgICBpZiAob3B0aW9ucz8ucmV2aXZlPy50cmltKVxuICAgICAgbm9kZVtcIn5jaGlsZHJlblwiXS5mb3JFYWNoKChjaGlsZCkgPT4gL15+KD86dGV4dHxjZGF0YXxjb21tZW50KSQvLnRlc3QoY2hpbGRbXCJ+bmFtZVwiXSkgPyAoY2hpbGQgYXMgUmVjb3JkPFByb3BlcnR5S2V5LCB1bmtub3duPilbXCIjdGV4dFwiXSA9IHJldml2ZShjaGlsZCwgXCIjdGV4dFwiLCB7IHJldml2ZTogeyB0cmltOiBub2RlW1wiQHhtbDpzcGFjZVwiXSAhPT0gXCJwcmVzZXJ2ZVwiIH0gfSkgOiBudWxsKVxuICAgIGlmIChub2RlW1wifmNoaWxkcmVuXCJdLnNvbWUoKGNoaWxkKSA9PiAoL15+KD86dGV4dHxjZGF0YSkkLy50ZXN0KGNoaWxkW1wifm5hbWVcIl0pKSAmJiAoY2hpbGRbXCIjdGV4dFwiXS50cmltKCkubGVuZ3RoICsgKG5vZGVbXCJAeG1sOnNwYWNlXCJdID09PSBcInByZXNlcnZlXCIgPyAxIDogMCkgKiBjaGlsZFtcIiN0ZXh0XCJdLmxlbmd0aCkpKVxuICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KG5vZGUsIFwiI3RleHRcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBjb25maWd1cmFibGU6IHRydWUgfSlcbiAgICBpZiAobm9kZVtcIn5jaGlsZHJlblwiXS5zb21lKChjaGlsZCkgPT4gY2hpbGRbXCJ+bmFtZVwiXSA9PT0gXCJ+Y29tbWVudFwiKSlcbiAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShub2RlLCBcIiNjb21tZW50c1wiLCB7IGVudW1lcmFibGU6IHRydWUsIGNvbmZpZ3VyYWJsZTogdHJ1ZSB9KVxuICB9XG4gIC8vIFByb2Nlc3MgY2hpbGQgbm9kZXNcbiAgZm9yIChjb25zdCBba2V5LCB2YWx1ZV0gb2YgT2JqZWN0LmVudHJpZXMobm9kZSkpIHtcbiAgICAvLyBTa2lwIGNvbW1lbnRzXG4gICAgaWYgKGtleSA9PT0gXCIjY29tbWVudHNcIilcbiAgICAgIGNvbnRpbnVlXG4gICAgLy8gQ2xlYW4gYXR0cmlidXRlcyBpZiByZXF1aXJlZFxuICAgIGlmICgob3B0aW9ucz8uY2xlYW4/LmF0dHJpYnV0ZXMpICYmIChrZXkuc3RhcnRzV2l0aChcIkBcIikpKSB7XG4gICAgICBkZWxldGUgbm9kZVtrZXldXG4gICAgICBjb250aW51ZVxuICAgIH1cbiAgICAvLyBSZXZpdmUgYXR0cmlidXRlIHZhbHVlIGlmIHJlcXVpcmVkXG4gICAgaWYgKGtleS5zdGFydHNXaXRoKFwiQFwiKSkge1xuICAgICAgbm9kZVtrZXldID0gcmV2aXZlKG5vZGUsIGtleSwgb3B0aW9ucylcbiAgICAgIGlmIChub2RlW2tleV0gPT09IHVuZGVmaW5lZClcbiAgICAgICAgZGVsZXRlIG5vZGVba2V5XVxuICAgICAgY29udGludWVcbiAgICB9XG4gICAgLy8gSGFuZGxlIG90aGVyIG5vZGVzXG4gICAgaWYgKEFycmF5LmlzQXJyYXkodmFsdWUpKSB7XG4gICAgICBub2RlW2tleV0gPSBPYmplY3QuZGVmaW5lUHJvcGVydGllcyh2YWx1ZS5tYXAoKGNoaWxkKSA9PiBwb3N0cHJvY2VzcyhjaGlsZCwgb3B0aW9ucykpLCB7XG4gICAgICAgIFtcIn5wYXJlbnRcIl06IHsgZW51bWVyYWJsZTogZmFsc2UsIHdyaXRhYmxlOiBmYWxzZSwgdmFsdWU6IG5vZGUgfSxcbiAgICAgICAgW1wifm5hbWVcIl06IHsgZW51bWVyYWJsZTogZmFsc2UsIHdyaXRhYmxlOiBmYWxzZSwgdmFsdWU6IGtleSB9LFxuICAgICAgfSlcbiAgICB9IGVsc2UgaWYgKCh0eXBlb2YgdmFsdWUgPT09IFwib2JqZWN0XCIpICYmIHZhbHVlKSB7XG4gICAgICBub2RlW2tleV0gPSBwb3N0cHJvY2Vzcyh2YWx1ZSBhcyBYbWxOb2RlLCBvcHRpb25zKVxuICAgIH1cbiAgICBpZiAobm9kZVtrZXldID09PSB1bmRlZmluZWQpXG4gICAgICBkZWxldGUgbm9kZVtrZXldXG4gIH1cbiAgLy8gUmV2aXZlIHRleHQgaWYgcmVxdWlyZWRcbiAgY29uc3Qga2V5cyA9IE9iamVjdC5rZXlzKG5vZGUpXG4gIGlmIChrZXlzLmluY2x1ZGVzKFwiI3RleHRcIikpIHtcbiAgICBjb25zdCBfb3B0aW9ucyA9IHsgLi4ub3B0aW9ucywgcmV2aXZlOiB7IC4uLm9wdGlvbnM/LnJldml2ZSwgdHJpbTogKG9wdGlvbnM/LnJldml2ZT8udHJpbSkgJiYgKG5vZGVbXCJAeG1sOnNwYWNlXCJdICE9PSBcInByZXNlcnZlXCIpIH0gfVxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShub2RlLCBcIiN0ZXh0XCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgY29uZmlndXJhYmxlOiB0cnVlLCB2YWx1ZTogcmV2aXZlKG5vZGUsIFwiI3RleHRcIiwgX29wdGlvbnMpIH0pXG4gIH1cbiAgLy8gQ3VzdG9tIHJldml2YWwgaWYgcmVxdWlyZWRcbiAgaWYgKG9wdGlvbnM/LnJldml2ZT8uY3VzdG9tKSB7XG4gICAgaWYgKG9wdGlvbnMucmV2aXZlLmN1c3RvbSh7IG5hbWU6IG5vZGVbXCJ+bmFtZVwiXSwga2V5OiBudWxsLCB2YWx1ZTogbnVsbCwgbm9kZTogbm9kZSBhcyBYbWxOb2RlIH0pID09PSB1bmRlZmluZWQpXG4gICAgICByZXR1cm4gdW5kZWZpbmVkXG4gIH1cbiAgLy8gRmxhdHRlbiBvYmplY3QgaWYgcmVxdWlyZWRcbiAgaWYgKChvcHRpb25zPy5mbGF0dGVuPy50ZXh0KSAmJiAoa2V5cy5sZW5ndGggPT09IDEpICYmIChrZXlzLmluY2x1ZGVzKFwiI3RleHRcIikpKVxuICAgIHJldHVybiBub2RlW1wiI3RleHRcIl1cbiAgaWYgKChvcHRpb25zPy5mbGF0dGVuPy5hdHRyaWJ1dGVzKSAmJiAoa2V5cy5sZW5ndGgpICYmIChrZXlzLmV2ZXJ5KChrZXkpID0+IGtleS5zdGFydHNXaXRoKFwiQFwiKSkpKSB7XG4gICAgZm9yIChjb25zdCBrZXkgb2Yga2V5cykge1xuICAgICAgbm9kZVtrZXkuc2xpY2UoMSldID0gbm9kZVtrZXldXG4gICAgICBkZWxldGUgbm9kZVtrZXldXG4gICAgfVxuICAgIHJldHVybiBub2RlXG4gIH1cbiAgaWYgKCFrZXlzLmxlbmd0aClcbiAgICByZXR1cm4gKG9wdGlvbnM/LmZsYXR0ZW4/LmVtcHR5KSA/IG51bGwgOiAob3B0aW9ucz8uZmxhdHRlbj8udGV4dCkgPyBcIlwiIDogT2JqZWN0LmRlZmluZVByb3BlcnR5KG5vZGUsIFwiI3RleHRcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBjb25maWd1cmFibGU6IHRydWUsIHZhbHVlOiBcIlwiIH0pXG4gIHJldHVybiBub2RlXG59XG5cbi8qKiBFbnRpdGllcyAqL1xuY29uc3QgZW50aXRpZXMgPSB7XG4gIFwiJmx0O1wiOiBcIjxcIixcbiAgXCImZ3Q7XCI6IFwiPlwiLFxuICBcIiZhcG9zO1wiOiBcIidcIixcbiAgXCImcXVvdDtcIjogJ1wiJyxcbiAgXCImYW1wO1wiOiBcIiZcIiwgLy9LZWVwIGxhc3Rcbn0gYXMgY29uc3RcblxuLyoqIFJldml2ZSB2YWx1ZS4gKi9cbmZ1bmN0aW9uIHJldml2ZShub2RlOiBYbWxOb2RlIHwgWG1sVGV4dCwga2V5OiBzdHJpbmcsIG9wdGlvbnM6IFBhcnNlck9wdGlvbnMpIHtcbiAgbGV0IHZhbHVlID0gKG5vZGUgYXMgWG1sTm9kZSlba2V5XSBhcyBzdHJpbmdcbiAgaWYgKG9wdGlvbnM/LnJldml2ZT8udHJpbSlcbiAgICB2YWx1ZSA9IHZhbHVlLnRyaW0oKVxuICBpZiAob3B0aW9ucz8ucmV2aXZlPy5lbnRpdGllcykge1xuICAgIHZhbHVlID0gdmFsdWUucmVwbGFjZUFsbCgvJiMoPzxoZXg+eD8pKD88Y29kZT5bQS1GYS1mXFxkXSspOy9nLCAoXywgaGV4LCBjb2RlKSA9PiBTdHJpbmcuZnJvbUNoYXJDb2RlKE51bWJlci5wYXJzZUludChjb2RlLCBoZXggPyAxNiA6IDEwKSkpXG4gICAgZm9yIChjb25zdCBbZW50aXR5LCBjaGFyYWN0ZXJdIG9mIE9iamVjdC5lbnRyaWVzKGVudGl0aWVzKSlcbiAgICAgIHZhbHVlID0gdmFsdWUucmVwbGFjZUFsbChlbnRpdHksIGNoYXJhY3RlcilcbiAgfVxuICBpZiAoKG9wdGlvbnM/LnJldml2ZT8ubnVtYmVycykgJiYgKHZhbHVlLmxlbmd0aCkgJiYgKE51bWJlci5pc0Zpbml0ZShOdW1iZXIodmFsdWUpKSkgJiYgKCEoKG5vZGVbXCJ+bmFtZVwiXSA9PT0gXCJ+eG1sXCIpICYmIChrZXkgPT09IFwiQHZlcnNpb25cIikpKSlcbiAgICB2YWx1ZSA9IE51bWJlcih2YWx1ZSkgYXMgdW5rbm93biBhcyBzdHJpbmdcbiAgaWYgKChvcHRpb25zPy5yZXZpdmU/LmJvb2xlYW5zKSAmJiAoL14oPzpbVHRdcnVlfFtGZl1hbHNlKSQvLnRlc3QodmFsdWUpKSlcbiAgICB2YWx1ZSA9IC9eW1R0XXJ1ZSQvLnRlc3QodmFsdWUpIGFzIHVua25vd24gYXMgc3RyaW5nXG4gIGlmIChvcHRpb25zPy5yZXZpdmU/LmN1c3RvbSlcbiAgICByZXR1cm4gb3B0aW9ucy5yZXZpdmUuY3VzdG9tKHsgbmFtZTogbm9kZVtcIn5uYW1lXCJdLCBrZXksIHZhbHVlLCBub2RlOiBub2RlIGFzIFhtbE5vZGUgfSlcbiAgcmV0dXJuIHZhbHVlXG59XG4iXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7OztDQUdDLEdBRUQsVUFBVTtBQXFFVix1RUFBdUUsR0FDdkUsT0FBTyxTQUFTLFNBQVMsR0FBZ0IsRUFBRSxPQUF1QjtFQUNoRSxZQUFZLENBQUM7RUFDYixRQUFRLE1BQU0sS0FBSyxDQUFDO0VBQ3BCLFFBQVEsTUFBTSxDQUFDLElBQUksS0FBSztFQUN4QixRQUFRLE1BQU0sQ0FBQyxRQUFRLEtBQUs7RUFDNUIsUUFBUSxPQUFPLEtBQUssQ0FBQztFQUNyQixRQUFRLE9BQU8sQ0FBQyxJQUFJLEtBQUs7RUFDekIsUUFBUSxPQUFPLENBQUMsS0FBSyxLQUFLO0VBQzFCLElBQUksQ0FBQyxPQUFPLElBQUksQ0FBQyxLQUFLLE1BQU0sRUFDMUIsTUFBTSxJQUFJLFlBQVk7RUFDeEIsT0FBTyxZQUFZLEtBQUs7QUFDMUI7QUFFQSxnRkFBZ0YsR0FDaEYsT0FBTyxTQUFTLGdCQUFnQixHQUFnQixFQUFFLElBQVksRUFBRSxHQUFXO0VBQ3pFLE1BQU0sY0FBYyxPQUFPLE1BQU0sQ0FBQyxTQUFTLE1BQU07SUFBRSxRQUFRO0VBQUksSUFBSSxlQUFlO0VBQ2xGLEdBQUcsQ0FBQyxnQkFBZ0IsS0FBSyxDQUFDO0VBQzFCLE9BQVE7SUFDTixLQUFLLE1BQU0sT0FBTyxDQUFDLEdBQUcsQ0FBQyxnQkFBZ0IsQ0FBQyxLQUFLOztNQUN6QyxHQUFHLENBQUMsZ0JBQWdCLENBQUMsS0FBSyxDQUFvQixJQUFJLENBQUM7TUFDckQ7SUFDRixLQUFLLFFBQVEsR0FBRyxDQUFDLGdCQUFnQjtNQUMvQixHQUFHLENBQUMsZ0JBQWdCLENBQUMsS0FBSyxHQUFHO1FBQUMsR0FBRyxDQUFDLGdCQUFnQixDQUFDLEtB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
|
package/_types.d.ts
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/** Nullable type. */ export type Nullable<T> = T | null;
|
|
2
|
+
/** XML text node. */ export type XmlText = {
|
|
3
|
+
/** Parent node. */ readonly ["~parent"]: XmlNode;
|
|
4
|
+
/** Tag name (`~text` for text nodes, `~cdata` for CDATA nodes and `~comment` for comment nodes). */ readonly ["~name"]: string;
|
|
5
|
+
/** Text content. */ ["#text"]: string;
|
|
6
|
+
};
|
|
7
|
+
/** XML node. */ export type XmlNode = {
|
|
8
|
+
/** Tag name (`~xml` for XML prolog, other nodes will be given their respective tag name). */ readonly ["~name"]: string;
|
|
9
|
+
/** Child nodes. */ readonly ["~children"]: Array<XmlNode | XmlText>;
|
|
10
|
+
/** Comments. */ readonly ["#comments"]?: Array<string>;
|
|
11
|
+
/** Text content. */ readonly ["#text"]: string;
|
|
12
|
+
[key: string]: unknown;
|
|
13
|
+
};
|
|
14
|
+
/** XML document. */ export type XmlDocument = XmlNode & {
|
|
15
|
+
/** XML version. */ ["@version"]?: `1.${number}`;
|
|
16
|
+
/** XML character encoding. */ ["@encoding"]?: string;
|
|
17
|
+
/** XML standalone. */ ["@standalone"]?: "yes" | "no";
|
|
18
|
+
/** XML doctype. */ ["#doctype"]?: XmlNode;
|
|
19
|
+
/** XML instructions. */ ["#instructions"]?: {
|
|
20
|
+
[key: string]: XmlNode | Array<XmlNode>;
|
|
21
|
+
};
|
|
22
|
+
};
|
|
23
|
+
/** Synchronous reader. */ export type ReaderSync = {
|
|
24
|
+
/** Read synchronously some data into a buffer and returns the number of bytes read. */ readSync(buffer: Uint8Array): Nullable<number>;
|
|
25
|
+
};
|
|
26
|
+
/** A laxer type for what can be stringified. We won’t ever create this, but we’ll accept it. */ export type Stringifyable = Partial<Omit<XmlDocument, "@version" | "@standalone"> & {
|
|
27
|
+
"@version": string;
|
|
28
|
+
"@standalone": string;
|
|
29
|
+
}>;
|
package/_types.js
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
/** Nullable type. */
|
|
2
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImZpbGU6Ly8vaG9tZS9ydW5uZXIvd29yay9saWJzL2xpYnMvQGxpYnMveG1sL190eXBlcy50cyJdLCJzb3VyY2VzQ29udGVudCI6WyIvKiogTnVsbGFibGUgdHlwZS4gKi9cbmV4cG9ydCB0eXBlIE51bGxhYmxlPFQ+ID0gVCB8IG51bGxcblxuLyoqIFhNTCB0ZXh0IG5vZGUuICovXG5leHBvcnQgdHlwZSBYbWxUZXh0ID0ge1xuICAvKiogUGFyZW50IG5vZGUuICovXG4gIHJlYWRvbmx5IFtcIn5wYXJlbnRcIl06IFhtbE5vZGVcbiAgLyoqIFRhZyBuYW1lIChgfnRleHRgIGZvciB0ZXh0IG5vZGVzLCBgfmNkYXRhYCBmb3IgQ0RBVEEgbm9kZXMgYW5kIGB+Y29tbWVudGAgZm9yIGNvbW1lbnQgbm9kZXMpLiAqL1xuICByZWFkb25seSBbXCJ+bmFtZVwiXTogc3RyaW5nXG4gIC8qKiBUZXh0IGNvbnRlbnQuICovXG4gIFtcIiN0ZXh0XCJdOiBzdHJpbmdcbn1cblxuLyoqIFhNTCBub2RlLiAqL1xuZXhwb3J0IHR5cGUgWG1sTm9kZSA9IHtcbiAgLyoqIFRhZyBuYW1lIChgfnhtbGAgZm9yIFhNTCBwcm9sb2csIG90aGVyIG5vZGVzIHdpbGwgYmUgZ2l2ZW4gdGhlaXIgcmVzcGVjdGl2ZSB0YWcgbmFtZSkuICovXG4gIHJlYWRvbmx5IFtcIn5uYW1lXCJdOiBzdHJpbmdcbiAgLyoqIENoaWxkIG5vZGVzLiAqL1xuICByZWFkb25seSBbXCJ+Y2hpbGRyZW5cIl06IEFycmF5PFhtbE5vZGUgfCBYbWxUZXh0PlxuICAvKiogQ29tbWVudHMuICovXG4gIHJlYWRvbmx5IFtcIiNjb21tZW50c1wiXT86IEFycmF5PHN0cmluZz5cbiAgLyoqIFRleHQgY29udGVudC4gKi9cbiAgcmVhZG9ubHkgW1wiI3RleHRcIl06IHN0cmluZ1xuICAvLyBTaWduYXR1cmVcbiAgW2tleTogc3RyaW5nXTogdW5rbm93blxufVxuXG4vKiogWE1MIGRvY3VtZW50LiAqL1xuZXhwb3J0IHR5cGUgWG1sRG9jdW1lbnQgPSBYbWxOb2RlICYge1xuICAvKiogWE1MIHZlcnNpb24uICovXG4gIFtcIkB2ZXJzaW9uXCJdPzogYDEuJHtudW1iZXJ9YFxuICAvKiogWE1MIGNoYXJhY3RlciBlbmNvZGluZy4gKi9cbiAgW1wiQGVuY29kaW5nXCJdPzogc3RyaW5nXG4gIC8qKiBYTUwgc3RhbmRhbG9uZS4gKi9cbiAgW1wiQHN0YW5kYWxvbmVcIl0/OiBcInllc1wiIHwgXCJub1wiXG4gIC8qKiBYTUwgZG9jdHlwZS4gKi9cbiAgW1wiI2RvY3R5cGVcIl0/OiBYbWxOb2RlXG4gIC8qKiBYTUwgaW5zdHJ1Y3Rpb25zLiAqL1xuICBbXCIjaW5zdHJ1Y3Rpb25zXCJdPzogeyBba2V5OiBzdHJpbmddOiBYbWxOb2RlIHwgQXJyYXk8WG1sTm9kZT4gfVxufVxuXG4vKiogU3luY2hyb25vdXMgcmVhZGVyLiAqL1xuZXhwb3J0IHR5cGUgUmVhZGVyU3luYyA9IHtcbiAgLyoqIFJlYWQgc3luY2hyb25vdXNseSBzb21lIGRhdGEgaW50byBhIGJ1ZmZlciBhbmQgcmV0dXJucyB0aGUgbnVtYmVyIG9mIGJ5dGVzIHJlYWQuICovXG4gIHJlYWRTeW5jKGJ1ZmZlcjogVWludDhBcnJheSk6IE51bGxhYmxlPG51bWJlcj5cbn1cblxuLyoqIEEgbGF4ZXIgdHlwZSBmb3Igd2hhdCBjYW4gYmUgc3RyaW5naWZpZWQuIFdlIHdvbuKAmXQgZXZlciBjcmVhdGUgdGhpcywgYnV0IHdl4oCZbGwgYWNjZXB0IGl0LiAqL1xuZXhwb3J0IHR5cGUgU3RyaW5naWZ5YWJsZSA9IFBhcnRpYWw8T21pdDxYbWxEb2N1bWVudCwgXCJAdmVyc2lvblwiIHwgXCJAc3RhbmRhbG9uZVwiPiAmIHsgXCJAdmVyc2lvblwiOiBzdHJpbmc7IFwiQHN0YW5kYWxvbmVcIjogc3RyaW5nIH0+XG4iXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsbUJBQW1CLEdBQ25CIn0=
|
package/bench/assets/medium.xml
CHANGED
package/bench/assets/small.xml
CHANGED
package/bench/bench.ts
CHANGED
|
@@ -1,12 +1,16 @@
|
|
|
1
|
-
|
|
1
|
+
// deno-lint-ignore-file no-external-import no-import-prefix
|
|
2
|
+
import { expandGlob } from "jsr:@std/fs@1/expand-glob"
|
|
2
3
|
import { parse } from "../mod.ts"
|
|
4
|
+
import { parse as parseWasm } from "../wasm/parse.ts"
|
|
5
|
+
import { parse as parse_v7 } from "jsr:@libs/xml@7.0.4/parse"
|
|
6
|
+
import { parse as parse_v6 } from "jsr:@libs/xml@6.0.8/parse"
|
|
3
7
|
import { parse as parse_v5 } from "jsr:@libs/xml@5.0.2/parse"
|
|
4
8
|
import { parse as parse_v4 } from "https://deno.land/x/xml@4.0.0/parse.ts"
|
|
5
9
|
import { parse as parse_v3 } from "https://deno.land/x/xml@3.0.2/parse.ts"
|
|
6
10
|
|
|
7
11
|
for await (const { name, path } of expandGlob("**/!(x-)*.xml", { globstar: true })) {
|
|
8
12
|
const { size } = await (await Deno.open(path)).stat()
|
|
9
|
-
for (const [func, f] of Object.entries({ parse, parse_v5, parse_v4, parse_v3 })) {
|
|
13
|
+
for (const [func, f] of Object.entries<(content: string) => unknown>({ parse, parseWasm, parse_v7, parse_v6, parse_v5, parse_v4, parse_v3 })) {
|
|
10
14
|
Deno.bench(`${func}(): ${name}, ${size}b)`, async function (t) {
|
|
11
15
|
const content = await Deno.readTextFile(path)
|
|
12
16
|
t.start()
|