xml-model 2.0.0-beta.1 → 2.0.0-beta.3
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/dist/_virtual/_rolldown/runtime.js +8 -0
- package/dist/index.d.ts +1 -2
- package/dist/index.js +5 -19
- package/dist/model.js +68 -62
- package/dist/node_modules/sax/lib/sax.js +1249 -0
- package/dist/node_modules/xml-js/lib/array-helper.js +13 -0
- package/dist/node_modules/xml-js/lib/index.js +19 -0
- package/dist/node_modules/xml-js/lib/js2xml.js +258 -0
- package/dist/node_modules/xml-js/lib/json2xml.js +22 -0
- package/dist/node_modules/xml-js/lib/options-helper.js +33 -0
- package/dist/node_modules/xml-js/lib/xml2js.js +246 -0
- package/dist/node_modules/xml-js/lib/xml2json.js +26 -0
- package/dist/util/kebab-case.js +24 -13
- package/dist/util/zod.js +16 -16
- package/dist/xml/codec.js +317 -363
- package/dist/xml/index.js +4 -17
- package/dist/xml/model.js +29 -33
- package/dist/xml/schema-meta.js +73 -81
- package/dist/xml/xml-js.d.ts +147 -5
- package/dist/xml/xml-js.js +99 -70
- package/package.json +20 -22
package/dist/xml/index.js
CHANGED
|
@@ -1,17 +1,4 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
import
|
|
5
|
-
export {
|
|
6
|
-
XML,
|
|
7
|
-
ZXMLCommentNode,
|
|
8
|
-
ZXMLElementNode,
|
|
9
|
-
ZXMLNode,
|
|
10
|
-
ZXMLRoot,
|
|
11
|
-
ZXMLTextNode,
|
|
12
|
-
normalizeCodecOptions,
|
|
13
|
-
registerDefault,
|
|
14
|
-
xml,
|
|
15
|
-
xmlModel
|
|
16
|
-
};
|
|
17
|
-
//# sourceMappingURL=index.js.map
|
|
1
|
+
import "./xml-js.js";
|
|
2
|
+
import "./schema-meta.js";
|
|
3
|
+
import "./codec.js";
|
|
4
|
+
import "./model.js";
|
package/dist/xml/model.js
CHANGED
|
@@ -1,37 +1,33 @@
|
|
|
1
|
-
import "zod";
|
|
2
|
-
import { XML } from "./xml-js.js";
|
|
3
1
|
import { model } from "../model.js";
|
|
4
|
-
import
|
|
2
|
+
import XML from "./xml-js.js";
|
|
5
3
|
import { root } from "./schema-meta.js";
|
|
4
|
+
import { XML_STATE, decode, encode } from "./codec.js";
|
|
5
|
+
import "zod";
|
|
6
|
+
//#region src/xml/model.ts
|
|
6
7
|
function xmlModel(schema, options) {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
static toXMLString(instance, options2 = {}) {
|
|
29
|
-
const xml = this.toXML(instance);
|
|
30
|
-
return XML.stringify(xml, options2);
|
|
31
|
-
}
|
|
32
|
-
};
|
|
8
|
+
const _schema = options ? root(schema, options) : schema;
|
|
9
|
+
return class extends model(_schema) {
|
|
10
|
+
static fromXML(input) {
|
|
11
|
+
if (typeof input === "string") input = XML.parse(input);
|
|
12
|
+
if (XML.isRoot(input)) input = XML.elementFromRoot(input);
|
|
13
|
+
const schema = this.dataSchema;
|
|
14
|
+
const inputData = decode(this.dataSchema, input);
|
|
15
|
+
const xmlState = inputData[XML_STATE];
|
|
16
|
+
const parsed = schema.parse(inputData);
|
|
17
|
+
parsed[XML_STATE] = xmlState;
|
|
18
|
+
return this.fromData(parsed);
|
|
19
|
+
}
|
|
20
|
+
static toXML(instance) {
|
|
21
|
+
const data = this.toData(instance);
|
|
22
|
+
return { elements: [encode(this.dataSchema, data)] };
|
|
23
|
+
}
|
|
24
|
+
static toXMLString(instance, options = {}) {
|
|
25
|
+
const xml = this.toXML(instance);
|
|
26
|
+
return XML.stringify(xml, options);
|
|
27
|
+
}
|
|
28
|
+
};
|
|
33
29
|
}
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
//# sourceMappingURL=model.js.map
|
|
30
|
+
//#endregion
|
|
31
|
+
export { xmlModel };
|
|
32
|
+
|
|
33
|
+
//# sourceMappingURL=model.js.map
|
package/dist/xml/schema-meta.js
CHANGED
|
@@ -1,96 +1,88 @@
|
|
|
1
|
+
import { getParentSchema, isZodType } from "../util/zod.js";
|
|
1
2
|
import "zod";
|
|
2
|
-
|
|
3
|
-
|
|
3
|
+
//#region src/xml/schema-meta.ts
|
|
4
|
+
var metaKey = "@@xml-model";
|
|
5
|
+
/** Merge `partial` into the schema's existing meta (shallow spread, no overwrite). */
|
|
4
6
|
function setMeta(schema, partial) {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
+
const existing = schema.meta()?.[metaKey] ?? {};
|
|
8
|
+
return schema.meta({ [metaKey]: {
|
|
9
|
+
...existing,
|
|
10
|
+
...partial
|
|
11
|
+
} });
|
|
7
12
|
}
|
|
8
13
|
function normalizePropOptions(options) {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
ctx.result.elements.push(res);
|
|
36
|
-
}
|
|
37
|
-
};
|
|
38
|
-
}
|
|
39
|
-
return partial;
|
|
14
|
+
if (!options) return {};
|
|
15
|
+
const partial = {};
|
|
16
|
+
if (options.tagname !== void 0) partial.propertyTagname = options.tagname;
|
|
17
|
+
if (options.inline !== void 0) partial.inlineProperty = options.inline;
|
|
18
|
+
if (options.match !== void 0) partial.propertyMatch = options.match;
|
|
19
|
+
if (options.decode !== void 0) {
|
|
20
|
+
const userDecode = options.decode;
|
|
21
|
+
partial.decodeAsProperty = function(ctx) {
|
|
22
|
+
const res = userDecode(ctx);
|
|
23
|
+
if (typeof res !== "undefined") Object.assign(ctx.result, res);
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
if (options.encode !== void 0) {
|
|
27
|
+
const userEncode = options.encode;
|
|
28
|
+
partial.encodeAsProperty = function(ctx) {
|
|
29
|
+
const { property } = ctx;
|
|
30
|
+
const res = userEncode(ctx);
|
|
31
|
+
if (typeof res === "undefined") return;
|
|
32
|
+
if (property.options.inlineProperty) ctx.result.elements.push(...res.elements);
|
|
33
|
+
else {
|
|
34
|
+
res.name = property.tagname;
|
|
35
|
+
ctx.result.elements.push(res);
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
return partial;
|
|
40
40
|
}
|
|
41
41
|
function root(optionsOrSchema, options) {
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
} else {
|
|
45
|
-
return { [metaKey]: optionsOrSchema };
|
|
46
|
-
}
|
|
42
|
+
if (isZodType(optionsOrSchema)) return setMeta(optionsOrSchema, options ?? {});
|
|
43
|
+
else return { [metaKey]: optionsOrSchema };
|
|
47
44
|
}
|
|
48
45
|
function prop(optionsOrSchema, options) {
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
} else {
|
|
52
|
-
return { [metaKey]: normalizePropOptions(optionsOrSchema) };
|
|
53
|
-
}
|
|
46
|
+
if (isZodType(optionsOrSchema)) return setMeta(optionsOrSchema, normalizePropOptions(options));
|
|
47
|
+
else return { [metaKey]: normalizePropOptions(optionsOrSchema) };
|
|
54
48
|
}
|
|
55
49
|
function attr(optionsOrSchema, options) {
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
} else {
|
|
73
|
-
return { [metaKey]: partial };
|
|
74
|
-
}
|
|
50
|
+
const opts = isZodType(optionsOrSchema) ? options ?? {} : optionsOrSchema ?? {};
|
|
51
|
+
const partial = {
|
|
52
|
+
decodeAsProperty(ctx) {
|
|
53
|
+
const { name, options: propOptions } = ctx.property;
|
|
54
|
+
const attrName = opts.name ?? name;
|
|
55
|
+
const attrValue = ctx.xml?.attributes[attrName];
|
|
56
|
+
ctx.result[name] = propOptions.schema.parse(attrValue);
|
|
57
|
+
},
|
|
58
|
+
encodeAsProperty(ctx) {
|
|
59
|
+
const { value, name } = ctx.property;
|
|
60
|
+
const attrName = opts.name ?? name;
|
|
61
|
+
ctx.result.attributes[attrName] = value.toString();
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
if (isZodType(optionsOrSchema)) return setMeta(optionsOrSchema, partial);
|
|
65
|
+
else return { [metaKey]: partial };
|
|
75
66
|
}
|
|
76
|
-
|
|
67
|
+
/** Namespace object for XML metadata helpers. */
|
|
68
|
+
var xml = {
|
|
69
|
+
root,
|
|
70
|
+
prop,
|
|
71
|
+
attr
|
|
72
|
+
};
|
|
77
73
|
function getOwnUserOptions(schema) {
|
|
78
|
-
|
|
79
|
-
return meta?.[metaKey] ?? {};
|
|
74
|
+
return schema.meta()?.[metaKey] ?? {};
|
|
80
75
|
}
|
|
81
76
|
function getUserOptions(schema) {
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
77
|
+
const own = getOwnUserOptions(schema);
|
|
78
|
+
const parentSchema = getParentSchema(schema);
|
|
79
|
+
if (!parentSchema) return own;
|
|
80
|
+
return {
|
|
81
|
+
...getUserOptions(parentSchema),
|
|
82
|
+
...own
|
|
83
|
+
};
|
|
87
84
|
}
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
prop,
|
|
93
|
-
root,
|
|
94
|
-
xml
|
|
95
|
-
};
|
|
96
|
-
//# sourceMappingURL=schema-meta.js.map
|
|
85
|
+
//#endregion
|
|
86
|
+
export { getUserOptions, root, xml };
|
|
87
|
+
|
|
88
|
+
//# sourceMappingURL=schema-meta.js.map
|
package/dist/xml/xml-js.d.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { Options, Element } from 'xml-js';
|
|
2
1
|
import { z } from 'zod';
|
|
3
2
|
export declare const ZXMLElementNode: z.ZodObject<{
|
|
4
3
|
type: z.ZodLiteral<"element">;
|
|
@@ -63,13 +62,156 @@ export type XMLRoot = {
|
|
|
63
62
|
};
|
|
64
63
|
type EmptyObj = Record<PropertyKey, never>;
|
|
65
64
|
export type XMLVoid = EmptyObj;
|
|
66
|
-
|
|
65
|
+
type IgnoreOptions = {
|
|
66
|
+
/** Whether to ignore the XML declaration (`<?xml?>`). @default false */
|
|
67
|
+
ignoreDeclaration?: boolean;
|
|
68
|
+
/** Whether to ignore processing instructions (`<?go there?>`). @default false */
|
|
69
|
+
ignoreInstruction?: boolean;
|
|
70
|
+
/** Whether to ignore element attributes. @default false */
|
|
71
|
+
ignoreAttributes?: boolean;
|
|
72
|
+
/** Whether to ignore comments (`<!-- -->`). @default false */
|
|
73
|
+
ignoreComment?: boolean;
|
|
74
|
+
/** Whether to ignore CData sections (`<![CDATA[ ]]>`). @default false */
|
|
75
|
+
ignoreCdata?: boolean;
|
|
76
|
+
/** Whether to ignore DOCTYPE declarations. @default false */
|
|
77
|
+
ignoreDoctype?: boolean;
|
|
78
|
+
/** Whether to ignore text content inside elements. @default false */
|
|
79
|
+
ignoreText?: boolean;
|
|
80
|
+
};
|
|
81
|
+
type ChangingKeyNames = {
|
|
82
|
+
/** Override the key name used for the declaration property. @default "declaration" */
|
|
83
|
+
declarationKey?: string;
|
|
84
|
+
/** Override the key name used for processing instructions. @default "instruction" */
|
|
85
|
+
instructionKey?: string;
|
|
86
|
+
/** Override the key name used for element attributes. @default "attributes" */
|
|
87
|
+
attributesKey?: string;
|
|
88
|
+
/** Override the key name used for text content. @default "text" */
|
|
89
|
+
textKey?: string;
|
|
90
|
+
/** Override the key name used for CData sections. @default "cdata" */
|
|
91
|
+
cdataKey?: string;
|
|
92
|
+
/** Override the key name used for DOCTYPE. @default "doctype" */
|
|
93
|
+
doctypeKey?: string;
|
|
94
|
+
/** Override the key name used for comments. @default "comment" */
|
|
95
|
+
commentKey?: string;
|
|
96
|
+
/** Override the key name used for the parent back-reference (when `addParent` is enabled). @default "parent" */
|
|
97
|
+
parentKey?: string;
|
|
98
|
+
/** Override the key name used for node type. @default "type" */
|
|
99
|
+
typeKey?: string;
|
|
100
|
+
/** Override the key name used for element name. @default "name" */
|
|
101
|
+
nameKey?: string;
|
|
102
|
+
/** Override the key name used for child elements array. @default "elements" */
|
|
103
|
+
elementsKey?: string;
|
|
104
|
+
};
|
|
105
|
+
/** Options for parsing XML into a JS object tree. */
|
|
106
|
+
export type ParseOptions = IgnoreOptions & ChangingKeyNames & {
|
|
107
|
+
/** Whether to trim whitespace surrounding text content. @default false */
|
|
108
|
+
trim?: boolean;
|
|
109
|
+
/**
|
|
110
|
+
* Whether to replace `&`, `<`, `>` with their XML entities in text nodes.
|
|
111
|
+
* @deprecated See https://github.com/nashwaan/xml-js/issues/26
|
|
112
|
+
* @default false
|
|
113
|
+
*/
|
|
114
|
+
sanitize?: boolean;
|
|
115
|
+
/** Whether to coerce numeric and boolean text values to their native JS types. @default false */
|
|
116
|
+
nativeType?: boolean;
|
|
117
|
+
/**
|
|
118
|
+
* Whether to add a `parent` property on each element pointing back to its parent.
|
|
119
|
+
* Useful for upward traversal but creates circular references.
|
|
120
|
+
* @default false
|
|
121
|
+
*/
|
|
122
|
+
addParent?: boolean;
|
|
123
|
+
/**
|
|
124
|
+
* Whether to always wrap sub-elements in an array, even when there is only one.
|
|
125
|
+
* Pass an array of element names to restrict this behaviour to those names only.
|
|
126
|
+
* Only applicable in compact mode.
|
|
127
|
+
* @default false
|
|
128
|
+
*/
|
|
129
|
+
alwaysArray?: boolean | Array<string>;
|
|
130
|
+
/**
|
|
131
|
+
* Whether to always emit an `elements` array even on empty elements.
|
|
132
|
+
* `<a></a>` becomes `{ elements: [{ type: "element", name: "a", elements: [] }] }`
|
|
133
|
+
* instead of `{ elements: [{ type: "element", name: "a" }] }`.
|
|
134
|
+
* Only applicable in non-compact mode.
|
|
135
|
+
* @default false
|
|
136
|
+
*/
|
|
137
|
+
alwaysChildren?: boolean;
|
|
138
|
+
/**
|
|
139
|
+
* Whether to parse the contents of processing instructions as attributes.
|
|
140
|
+
* `<?go to="there"?>` becomes `{ go: { attributes: { to: "there" } } }`
|
|
141
|
+
* instead of `{ go: 'to="there"' }`.
|
|
142
|
+
* @default false
|
|
143
|
+
*/
|
|
144
|
+
instructionHasAttributes?: boolean;
|
|
145
|
+
/** Whether to preserve whitespace-only text nodes that appear between elements. @default false */
|
|
146
|
+
captureSpacesBetweenElements?: boolean;
|
|
147
|
+
/** Custom processing hook called for each DOCTYPE value. */
|
|
148
|
+
doctypeFn?: (value: string, parentElement: object) => void;
|
|
149
|
+
/** Custom processing hook called for each processing instruction value. */
|
|
150
|
+
instructionFn?: (instructionValue: string, instructionName: string, parentElement: string) => void;
|
|
151
|
+
/** Custom processing hook called for each CData section. */
|
|
152
|
+
cdataFn?: (value: string, parentElement: object) => void;
|
|
153
|
+
/** Custom processing hook called for each comment. */
|
|
154
|
+
commentFn?: (value: string, parentElement: object) => void;
|
|
155
|
+
/** Custom processing hook called for each text node. */
|
|
156
|
+
textFn?: (value: string, parentElement: object) => void;
|
|
157
|
+
/** Custom processing hook called for each processing instruction name. */
|
|
158
|
+
instructionNameFn?: (instructionName: string, instructionValue: string, parentElement: string) => void;
|
|
159
|
+
/** Custom processing hook called for each element name. */
|
|
160
|
+
elementNameFn?: (value: string, parentElement: object) => void;
|
|
161
|
+
/** Custom processing hook called for each attribute name. */
|
|
162
|
+
attributeNameFn?: (attributeName: string, attributeValue: string, parentElement: string) => void;
|
|
163
|
+
/** Custom processing hook called for each attribute value. */
|
|
164
|
+
attributeValueFn?: (attributeValue: string, attributeName: string, parentElement: string) => void;
|
|
165
|
+
/** Custom processing hook called for the whole attributes object of an element. */
|
|
166
|
+
attributesFn?: (value: string, parentElement: string) => void;
|
|
167
|
+
};
|
|
67
168
|
declare function parse(xml: string, options?: ParseOptions): XMLRoot;
|
|
68
|
-
|
|
169
|
+
/** Options for serializing a JS object tree back to XML. */
|
|
170
|
+
export type StringifyOptions = IgnoreOptions & ChangingKeyNames & {
|
|
171
|
+
/** Number of spaces (or a string like `'\t'`) to use for indenting XML output. @default 0 */
|
|
172
|
+
spaces?: number | string;
|
|
173
|
+
/** Whether to indent text nodes onto their own line when `spaces` is set. @default false */
|
|
174
|
+
indentText?: boolean;
|
|
175
|
+
/** Whether to write CData sections on a new indented line. @default false */
|
|
176
|
+
indentCdata?: boolean;
|
|
177
|
+
/** Whether to print each attribute on its own indented line (when `spaces` is set). @default false */
|
|
178
|
+
indentAttributes?: boolean;
|
|
179
|
+
/** Whether to indent processing instructions onto their own line. @default false */
|
|
180
|
+
indentInstruction?: boolean;
|
|
181
|
+
/** Whether to emit empty elements as full tag pairs (`<a></a>`) instead of self-closing (`<a/>`). @default false */
|
|
182
|
+
fullTagEmptyElement?: boolean;
|
|
183
|
+
/** Whether to omit quotes around attribute values that are native JS types (numbers, booleans). @default false */
|
|
184
|
+
noQuotesForNativeAttributes?: boolean;
|
|
185
|
+
/** Custom processing hook called for each DOCTYPE value. */
|
|
186
|
+
doctypeFn?: (value: string, currentElementName: string, currentElementObj: object) => void;
|
|
187
|
+
/** Custom processing hook called for each processing instruction value. */
|
|
188
|
+
instructionFn?: (instructionValue: string, instructionName: string, currentElementName: string, currentElementObj: object) => void;
|
|
189
|
+
/** Custom processing hook called for each CData section. */
|
|
190
|
+
cdataFn?: (value: string, currentElementName: string, currentElementObj: object) => void;
|
|
191
|
+
/** Custom processing hook called for each comment. */
|
|
192
|
+
commentFn?: (value: string, currentElementName: string, currentElementObj: object) => void;
|
|
193
|
+
/** Custom processing hook called for each text node. */
|
|
194
|
+
textFn?: (value: string, currentElementName: string, currentElementObj: object) => void;
|
|
195
|
+
/** Custom processing hook called for each processing instruction name. */
|
|
196
|
+
instructionNameFn?: (instructionName: string, instructionValue: string, currentElementName: string, currentElementObj: object) => void;
|
|
197
|
+
/** Custom processing hook called for each element name. */
|
|
198
|
+
elementNameFn?: (value: string, currentElementName: string, currentElementObj: object) => void;
|
|
199
|
+
/** Custom processing hook called for each attribute name. */
|
|
200
|
+
attributeNameFn?: (attributeName: string, attributeValue: string, currentElementName: string, currentElementObj: object) => void;
|
|
201
|
+
/** Custom processing hook called for each attribute value. */
|
|
202
|
+
attributeValueFn?: (attributeValue: string, attributeName: string, currentElementName: string, currentElementObj: object) => void;
|
|
203
|
+
/** Custom processing hook called for the whole attributes object of an element. */
|
|
204
|
+
attributesFn?: (value: string, currentElementName: string, currentElementObj: object) => void;
|
|
205
|
+
/**
|
|
206
|
+
* Per-element override for `fullTagEmptyElement`.
|
|
207
|
+
* Return `true` to emit a full tag pair for the given element, `false` for self-closing.
|
|
208
|
+
*/
|
|
209
|
+
fullTagEmptyElementFn?: (currentElementName: string, currentElementObj: object) => void;
|
|
210
|
+
};
|
|
69
211
|
declare function stringify(xml: XMLRoot, options?: StringifyOptions): string;
|
|
70
|
-
declare function isRoot(xml:
|
|
212
|
+
declare function isRoot(xml: object): xml is XMLRoot;
|
|
71
213
|
declare function elementFromRoot(root: XMLRoot): XMLElementNode | undefined;
|
|
72
|
-
declare function isEmpty(xml:
|
|
214
|
+
declare function isEmpty(xml: object): xml is XMLVoid;
|
|
73
215
|
/**
|
|
74
216
|
* Extracts the text content from an element that has a single text child node.
|
|
75
217
|
*
|
package/dist/xml/xml-js.js
CHANGED
|
@@ -1,93 +1,122 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { require_lib } from "../node_modules/xml-js/lib/index.js";
|
|
2
2
|
import { z } from "zod";
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
3
|
+
//#region src/xml/xml-js.ts
|
|
4
|
+
var import_lib = require_lib();
|
|
5
|
+
var ZXMLElementNode = z.object({
|
|
6
|
+
type: z.literal("element"),
|
|
7
|
+
name: z.string(),
|
|
8
|
+
attributes: z.record(z.string(), z.string()).optional(),
|
|
9
|
+
get elements() {
|
|
10
|
+
return z.array(ZXMLNode).optional();
|
|
11
|
+
}
|
|
12
12
|
});
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
13
|
+
var ZXMLCommentNode = z.object({
|
|
14
|
+
type: z.literal("comment"),
|
|
15
|
+
comment: z.string()
|
|
16
|
+
});
|
|
17
|
+
var ZXMLTextNode = z.object({
|
|
18
|
+
type: z.literal("text"),
|
|
19
|
+
text: z.string()
|
|
20
|
+
});
|
|
21
|
+
var ZXMLNode = z.discriminatedUnion("type", [
|
|
22
|
+
ZXMLElementNode,
|
|
23
|
+
ZXMLCommentNode,
|
|
24
|
+
ZXMLTextNode
|
|
25
|
+
]);
|
|
26
|
+
var ZXMLRoot = z.object({ elements: z.array(ZXMLNode) });
|
|
17
27
|
function parse(xml, options = {}) {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
28
|
+
const strippedOptions = { ...options };
|
|
29
|
+
delete strippedOptions["compact"];
|
|
30
|
+
const res = (0, import_lib.xml2js)(xml, strippedOptions);
|
|
31
|
+
if ("elements" in res) return res;
|
|
32
|
+
throw new Error("Got empty XML");
|
|
23
33
|
}
|
|
24
34
|
function stringify(xml, options = {}) {
|
|
25
|
-
|
|
35
|
+
return (0, import_lib.js2xml)(xml, options);
|
|
26
36
|
}
|
|
27
37
|
function isRoot(xml) {
|
|
28
|
-
|
|
29
|
-
return keys.length === 1 && Array.isArray(xml.elements);
|
|
38
|
+
return Object.keys(xml).length === 1 && "elements" in xml && Array.isArray(xml.elements);
|
|
30
39
|
}
|
|
31
40
|
function elementFromRoot(root) {
|
|
32
|
-
|
|
41
|
+
return root.elements.find((el) => el.type === "element");
|
|
33
42
|
}
|
|
34
43
|
function isEmpty(xml) {
|
|
35
|
-
|
|
44
|
+
return Object.keys(xml).length === 0;
|
|
36
45
|
}
|
|
46
|
+
/**
|
|
47
|
+
* Extracts the text content from an element that has a single text child node.
|
|
48
|
+
*
|
|
49
|
+
* @param xml - An `XMLElement` expected to contain a single text node.
|
|
50
|
+
* @returns The text value, or an empty string when there are no child elements.
|
|
51
|
+
* @throws {TypeError} When the element has multiple or non-text children.
|
|
52
|
+
*/
|
|
37
53
|
function getContent(xml) {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
54
|
+
if (xml.elements?.length === 1) {
|
|
55
|
+
const content = xml.elements[0];
|
|
56
|
+
if (content.type === "text") return content.text;
|
|
57
|
+
}
|
|
58
|
+
if (!xml.elements) return "";
|
|
59
|
+
throw new TypeError(`can't get text from XMLElement: ${JSON.stringify(xml)}`);
|
|
44
60
|
}
|
|
45
61
|
function fromContent(content = "", tag, attributes) {
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
return el;
|
|
62
|
+
const elements = content ? [{
|
|
63
|
+
type: "text",
|
|
64
|
+
text: String(content)
|
|
65
|
+
}] : [];
|
|
66
|
+
if (!tag) return { elements };
|
|
67
|
+
const el = {
|
|
68
|
+
type: "element",
|
|
69
|
+
name: tag,
|
|
70
|
+
elements
|
|
71
|
+
};
|
|
72
|
+
if (attributes) el.attributes = attributes;
|
|
73
|
+
return el;
|
|
59
74
|
}
|
|
75
|
+
/**
|
|
76
|
+
* Appends a child element to `xml`, initialising the `elements` array if needed.
|
|
77
|
+
*
|
|
78
|
+
* @param xml - The parent element to modify.
|
|
79
|
+
* @param element - The child element to append.
|
|
80
|
+
*/
|
|
60
81
|
function addElement(xml, element) {
|
|
61
|
-
|
|
62
|
-
|
|
82
|
+
if (!xml.elements) xml.elements = [];
|
|
83
|
+
xml.elements.push(element);
|
|
63
84
|
}
|
|
85
|
+
/**
|
|
86
|
+
* Sets an attribute on an element, initialising the `attributes` map if needed.
|
|
87
|
+
*
|
|
88
|
+
* @param xml - The element to modify.
|
|
89
|
+
* @param attribute - The attribute name.
|
|
90
|
+
* @param value - The attribute value.
|
|
91
|
+
*/
|
|
64
92
|
function setAttribute(xml, attribute, value) {
|
|
65
|
-
|
|
66
|
-
|
|
93
|
+
if (!xml.attributes) xml.attributes = {};
|
|
94
|
+
xml.attributes[attribute] = value;
|
|
67
95
|
}
|
|
96
|
+
/**
|
|
97
|
+
* Removes an attribute from an element. Does nothing if the element has no attributes.
|
|
98
|
+
*
|
|
99
|
+
* @param xml - The element to modify.
|
|
100
|
+
* @param attribute - The attribute name to remove.
|
|
101
|
+
*/
|
|
68
102
|
function deleteAttribute(xml, attribute) {
|
|
69
|
-
|
|
70
|
-
|
|
103
|
+
if (!xml.attributes) return;
|
|
104
|
+
delete xml.attributes[attribute];
|
|
71
105
|
}
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
export {
|
|
85
|
-
XML,
|
|
86
|
-
ZXMLCommentNode,
|
|
87
|
-
ZXMLElementNode,
|
|
88
|
-
ZXMLNode,
|
|
89
|
-
ZXMLRoot,
|
|
90
|
-
ZXMLTextNode,
|
|
91
|
-
XML as default
|
|
106
|
+
/** Namespace object bundling all XML utility functions. */
|
|
107
|
+
var XML = {
|
|
108
|
+
parse,
|
|
109
|
+
stringify,
|
|
110
|
+
isRoot,
|
|
111
|
+
elementFromRoot,
|
|
112
|
+
isEmpty,
|
|
113
|
+
fromContent,
|
|
114
|
+
getContent,
|
|
115
|
+
addElement,
|
|
116
|
+
setAttribute,
|
|
117
|
+
deleteAttribute
|
|
92
118
|
};
|
|
93
|
-
//#
|
|
119
|
+
//#endregion
|
|
120
|
+
export { ZXMLCommentNode, ZXMLElementNode, ZXMLNode, ZXMLRoot, ZXMLTextNode, XML as default };
|
|
121
|
+
|
|
122
|
+
//# sourceMappingURL=xml-js.js.map
|