@ls-stack/utils 3.10.0 → 3.11.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/lib/xmlSerializer.cjs +128 -0
- package/lib/xmlSerializer.d.cts +14 -0
- package/lib/xmlSerializer.d.ts +14 -0
- package/lib/xmlSerializer.js +92 -0
- package/package.json +5 -1
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/xmlSerializer.ts
|
|
21
|
+
var xmlSerializer_exports = {};
|
|
22
|
+
__export(xmlSerializer_exports, {
|
|
23
|
+
serializeXML: () => serializeXML
|
|
24
|
+
});
|
|
25
|
+
module.exports = __toCommonJS(xmlSerializer_exports);
|
|
26
|
+
|
|
27
|
+
// src/arrayUtils.ts
|
|
28
|
+
function filterAndMap(array, mapFilter) {
|
|
29
|
+
const result = [];
|
|
30
|
+
let i = -1;
|
|
31
|
+
for (const item of array) {
|
|
32
|
+
i += 1;
|
|
33
|
+
const filterResult = mapFilter(item, i);
|
|
34
|
+
if (filterResult !== false) {
|
|
35
|
+
result.push(filterResult);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return result;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// src/xmlSerializer.ts
|
|
42
|
+
var XML_TAG_NAME_REGEX = /^[a-zA-Z_][a-zA-Z0-9._-]*$/;
|
|
43
|
+
var XML_PREFIX_REGEX = /^xml/i;
|
|
44
|
+
var XML_ESCAPE_MAP = {
|
|
45
|
+
"&": "&",
|
|
46
|
+
"<": "<",
|
|
47
|
+
">": ">",
|
|
48
|
+
'"': """,
|
|
49
|
+
"'": "'"
|
|
50
|
+
};
|
|
51
|
+
var XML_ESCAPE_REGEX = /[&<>"']/g;
|
|
52
|
+
function serializeXML(node, options) {
|
|
53
|
+
return serializeWithLevel(node, options, 0);
|
|
54
|
+
}
|
|
55
|
+
function serializeWithLevel(node, options = {}, level) {
|
|
56
|
+
const { name, attributes = {}, children, escapeText: nodeEscapeText } = node;
|
|
57
|
+
const {
|
|
58
|
+
indent,
|
|
59
|
+
escapeText: globalEscapeText = true,
|
|
60
|
+
validateTagName = "throw"
|
|
61
|
+
} = options;
|
|
62
|
+
const shouldEscapeText = nodeEscapeText !== void 0 ? nodeEscapeText : globalEscapeText;
|
|
63
|
+
const indentStr = indent ? getIndentString(indent, level) : "";
|
|
64
|
+
const newline = indent ? "\n" : "";
|
|
65
|
+
if (validateTagName) {
|
|
66
|
+
if (!isValidXmlTagName(name)) {
|
|
67
|
+
if (validateTagName === "throw") {
|
|
68
|
+
throw new Error(`Invalid XML tag name: "${name}"`);
|
|
69
|
+
}
|
|
70
|
+
return "";
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
const attributesStr = filterAndMap(
|
|
74
|
+
Object.entries(attributes),
|
|
75
|
+
([key, value]) => value !== null && value !== void 0 ? `${key}="${escapeXml(String(value))}"` : false
|
|
76
|
+
).join(" ");
|
|
77
|
+
const attributesPart = attributesStr ? ` ${attributesStr}` : "";
|
|
78
|
+
if (children === void 0) {
|
|
79
|
+
return `${indentStr}<${name}${attributesPart} />`;
|
|
80
|
+
}
|
|
81
|
+
if (typeof children === "string") {
|
|
82
|
+
const processedText = shouldEscapeText ? escapeXml(children) : children;
|
|
83
|
+
if (processedText.includes("\n") && indent) {
|
|
84
|
+
const lines = processedText.split("\n");
|
|
85
|
+
const contentIndent = getIndentString(indent, level + 1);
|
|
86
|
+
const indentedLines = lines.map((line, index) => {
|
|
87
|
+
if (line.trim() === "") return "";
|
|
88
|
+
return index === 0 ? line : contentIndent + line;
|
|
89
|
+
});
|
|
90
|
+
const indentedText = indentedLines.join("\n");
|
|
91
|
+
return `${indentStr}<${name}${attributesPart}>
|
|
92
|
+
${contentIndent}${indentedText}
|
|
93
|
+
${indentStr}</${name}>`;
|
|
94
|
+
}
|
|
95
|
+
return `${indentStr}<${name}${attributesPart}>${processedText}</${name}>`;
|
|
96
|
+
}
|
|
97
|
+
if (children.length === 0) {
|
|
98
|
+
return `${indentStr}<${name}${attributesPart}></${name}>`;
|
|
99
|
+
}
|
|
100
|
+
const serializedChildren = filterAndMap(children, (child) => {
|
|
101
|
+
if (!child) return false;
|
|
102
|
+
const serializedChild = serializeWithLevel(child, options, level + 1);
|
|
103
|
+
return serializedChild || false;
|
|
104
|
+
});
|
|
105
|
+
if (serializedChildren.length === 0) {
|
|
106
|
+
return `${indentStr}<${name}${attributesPart}></${name}>`;
|
|
107
|
+
}
|
|
108
|
+
const childrenStr = serializedChildren.join(newline);
|
|
109
|
+
return `${indentStr}<${name}${attributesPart}>${newline}${childrenStr}${newline}${indentStr}</${name}>`;
|
|
110
|
+
}
|
|
111
|
+
function getIndentString(indent, level) {
|
|
112
|
+
if (typeof indent === "string") {
|
|
113
|
+
return indent.repeat(level);
|
|
114
|
+
}
|
|
115
|
+
return " ".repeat(indent * level);
|
|
116
|
+
}
|
|
117
|
+
function isValidXmlTagName(name) {
|
|
118
|
+
if (!name) return false;
|
|
119
|
+
if (XML_PREFIX_REGEX.test(name)) return false;
|
|
120
|
+
return XML_TAG_NAME_REGEX.test(name);
|
|
121
|
+
}
|
|
122
|
+
function escapeXml(text) {
|
|
123
|
+
return text.replace(XML_ESCAPE_REGEX, (char) => XML_ESCAPE_MAP[char]);
|
|
124
|
+
}
|
|
125
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
126
|
+
0 && (module.exports = {
|
|
127
|
+
serializeXML
|
|
128
|
+
});
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
type XMLNode = {
|
|
2
|
+
name: string;
|
|
3
|
+
attributes?: Record<string, string | number | boolean | null | undefined>;
|
|
4
|
+
children?: (XMLNode | null | undefined | false)[] | string;
|
|
5
|
+
escapeText?: boolean;
|
|
6
|
+
};
|
|
7
|
+
type SerializeOptions = {
|
|
8
|
+
indent?: number | string;
|
|
9
|
+
escapeText?: boolean;
|
|
10
|
+
validateTagName?: 'throw' | 'reject' | false;
|
|
11
|
+
};
|
|
12
|
+
declare function serializeXML(node: XMLNode, options?: SerializeOptions): string;
|
|
13
|
+
|
|
14
|
+
export { type SerializeOptions, type XMLNode, serializeXML };
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
type XMLNode = {
|
|
2
|
+
name: string;
|
|
3
|
+
attributes?: Record<string, string | number | boolean | null | undefined>;
|
|
4
|
+
children?: (XMLNode | null | undefined | false)[] | string;
|
|
5
|
+
escapeText?: boolean;
|
|
6
|
+
};
|
|
7
|
+
type SerializeOptions = {
|
|
8
|
+
indent?: number | string;
|
|
9
|
+
escapeText?: boolean;
|
|
10
|
+
validateTagName?: 'throw' | 'reject' | false;
|
|
11
|
+
};
|
|
12
|
+
declare function serializeXML(node: XMLNode, options?: SerializeOptions): string;
|
|
13
|
+
|
|
14
|
+
export { type SerializeOptions, type XMLNode, serializeXML };
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import {
|
|
2
|
+
filterAndMap
|
|
3
|
+
} from "./chunk-UTFE4P3P.js";
|
|
4
|
+
import "./chunk-3XCS7FVO.js";
|
|
5
|
+
|
|
6
|
+
// src/xmlSerializer.ts
|
|
7
|
+
var XML_TAG_NAME_REGEX = /^[a-zA-Z_][a-zA-Z0-9._-]*$/;
|
|
8
|
+
var XML_PREFIX_REGEX = /^xml/i;
|
|
9
|
+
var XML_ESCAPE_MAP = {
|
|
10
|
+
"&": "&",
|
|
11
|
+
"<": "<",
|
|
12
|
+
">": ">",
|
|
13
|
+
'"': """,
|
|
14
|
+
"'": "'"
|
|
15
|
+
};
|
|
16
|
+
var XML_ESCAPE_REGEX = /[&<>"']/g;
|
|
17
|
+
function serializeXML(node, options) {
|
|
18
|
+
return serializeWithLevel(node, options, 0);
|
|
19
|
+
}
|
|
20
|
+
function serializeWithLevel(node, options = {}, level) {
|
|
21
|
+
const { name, attributes = {}, children, escapeText: nodeEscapeText } = node;
|
|
22
|
+
const {
|
|
23
|
+
indent,
|
|
24
|
+
escapeText: globalEscapeText = true,
|
|
25
|
+
validateTagName = "throw"
|
|
26
|
+
} = options;
|
|
27
|
+
const shouldEscapeText = nodeEscapeText !== void 0 ? nodeEscapeText : globalEscapeText;
|
|
28
|
+
const indentStr = indent ? getIndentString(indent, level) : "";
|
|
29
|
+
const newline = indent ? "\n" : "";
|
|
30
|
+
if (validateTagName) {
|
|
31
|
+
if (!isValidXmlTagName(name)) {
|
|
32
|
+
if (validateTagName === "throw") {
|
|
33
|
+
throw new Error(`Invalid XML tag name: "${name}"`);
|
|
34
|
+
}
|
|
35
|
+
return "";
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
const attributesStr = filterAndMap(
|
|
39
|
+
Object.entries(attributes),
|
|
40
|
+
([key, value]) => value !== null && value !== void 0 ? `${key}="${escapeXml(String(value))}"` : false
|
|
41
|
+
).join(" ");
|
|
42
|
+
const attributesPart = attributesStr ? ` ${attributesStr}` : "";
|
|
43
|
+
if (children === void 0) {
|
|
44
|
+
return `${indentStr}<${name}${attributesPart} />`;
|
|
45
|
+
}
|
|
46
|
+
if (typeof children === "string") {
|
|
47
|
+
const processedText = shouldEscapeText ? escapeXml(children) : children;
|
|
48
|
+
if (processedText.includes("\n") && indent) {
|
|
49
|
+
const lines = processedText.split("\n");
|
|
50
|
+
const contentIndent = getIndentString(indent, level + 1);
|
|
51
|
+
const indentedLines = lines.map((line, index) => {
|
|
52
|
+
if (line.trim() === "") return "";
|
|
53
|
+
return index === 0 ? line : contentIndent + line;
|
|
54
|
+
});
|
|
55
|
+
const indentedText = indentedLines.join("\n");
|
|
56
|
+
return `${indentStr}<${name}${attributesPart}>
|
|
57
|
+
${contentIndent}${indentedText}
|
|
58
|
+
${indentStr}</${name}>`;
|
|
59
|
+
}
|
|
60
|
+
return `${indentStr}<${name}${attributesPart}>${processedText}</${name}>`;
|
|
61
|
+
}
|
|
62
|
+
if (children.length === 0) {
|
|
63
|
+
return `${indentStr}<${name}${attributesPart}></${name}>`;
|
|
64
|
+
}
|
|
65
|
+
const serializedChildren = filterAndMap(children, (child) => {
|
|
66
|
+
if (!child) return false;
|
|
67
|
+
const serializedChild = serializeWithLevel(child, options, level + 1);
|
|
68
|
+
return serializedChild || false;
|
|
69
|
+
});
|
|
70
|
+
if (serializedChildren.length === 0) {
|
|
71
|
+
return `${indentStr}<${name}${attributesPart}></${name}>`;
|
|
72
|
+
}
|
|
73
|
+
const childrenStr = serializedChildren.join(newline);
|
|
74
|
+
return `${indentStr}<${name}${attributesPart}>${newline}${childrenStr}${newline}${indentStr}</${name}>`;
|
|
75
|
+
}
|
|
76
|
+
function getIndentString(indent, level) {
|
|
77
|
+
if (typeof indent === "string") {
|
|
78
|
+
return indent.repeat(level);
|
|
79
|
+
}
|
|
80
|
+
return " ".repeat(indent * level);
|
|
81
|
+
}
|
|
82
|
+
function isValidXmlTagName(name) {
|
|
83
|
+
if (!name) return false;
|
|
84
|
+
if (XML_PREFIX_REGEX.test(name)) return false;
|
|
85
|
+
return XML_TAG_NAME_REGEX.test(name);
|
|
86
|
+
}
|
|
87
|
+
function escapeXml(text) {
|
|
88
|
+
return text.replace(XML_ESCAPE_REGEX, (char) => XML_ESCAPE_MAP[char]);
|
|
89
|
+
}
|
|
90
|
+
export {
|
|
91
|
+
serializeXML
|
|
92
|
+
};
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ls-stack/utils",
|
|
3
3
|
"description": "Typescript utils",
|
|
4
|
-
"version": "3.
|
|
4
|
+
"version": "3.11.0",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"files": [
|
|
7
7
|
"lib"
|
|
@@ -154,6 +154,10 @@
|
|
|
154
154
|
"import": "./lib/typingUtils.js",
|
|
155
155
|
"require": "./lib/typingUtils.cjs"
|
|
156
156
|
},
|
|
157
|
+
"./xmlSerializer": {
|
|
158
|
+
"import": "./lib/xmlSerializer.js",
|
|
159
|
+
"require": "./lib/xmlSerializer.cjs"
|
|
160
|
+
},
|
|
157
161
|
"./yamlStringify": {
|
|
158
162
|
"import": "./lib/yamlStringify.js",
|
|
159
163
|
"require": "./lib/yamlStringify.cjs"
|