@xapi-js/core 1.2.0 → 1.3.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/dist/index.cjs +415 -185
- package/dist/index.d.cts +85 -26
- package/dist/index.d.ts +85 -26
- package/dist/index.js +412 -161
- package/package.json +1 -5
package/dist/index.js
CHANGED
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
import { StaxXmlWriterSync } from "stax-xml";
|
|
2
|
-
import * as txml from "txml";
|
|
3
|
-
|
|
4
1
|
//#region src/types.ts
|
|
5
2
|
/**
|
|
6
3
|
* Defines the possible types of rows in an X-API dataset (e.g., "insert", "update", "delete").
|
|
@@ -138,18 +135,18 @@ var XapiRoot = class {
|
|
|
138
135
|
return this.datasets.length;
|
|
139
136
|
}
|
|
140
137
|
/**
|
|
141
|
-
*
|
|
142
|
-
* @returns An
|
|
138
|
+
* Returns all parameters as an array.
|
|
139
|
+
* @returns An array of parameters.
|
|
143
140
|
*/
|
|
144
|
-
|
|
145
|
-
|
|
141
|
+
getParameters() {
|
|
142
|
+
return this.parameters.params;
|
|
146
143
|
}
|
|
147
144
|
/**
|
|
148
|
-
*
|
|
149
|
-
* @returns An
|
|
145
|
+
* Returns all datasets as an array.
|
|
146
|
+
* @returns An array of datasets.
|
|
150
147
|
*/
|
|
151
|
-
|
|
152
|
-
|
|
148
|
+
getDatasets() {
|
|
149
|
+
return this.datasets;
|
|
153
150
|
}
|
|
154
151
|
};
|
|
155
152
|
/**
|
|
@@ -277,25 +274,25 @@ var Dataset = class {
|
|
|
277
274
|
} else throw new Error(`Row index ${rowIdx} out of bounds in dataset ${this.id}`);
|
|
278
275
|
}
|
|
279
276
|
/**
|
|
280
|
-
*
|
|
281
|
-
* @returns An
|
|
277
|
+
* Returns all constant column definitions as an array.
|
|
278
|
+
* @returns An array of constant columns.
|
|
282
279
|
*/
|
|
283
|
-
|
|
284
|
-
|
|
280
|
+
getConstColumns() {
|
|
281
|
+
return this.constColumns;
|
|
285
282
|
}
|
|
286
283
|
/**
|
|
287
|
-
*
|
|
288
|
-
* @returns An
|
|
284
|
+
* Returns all column definitions as an array.
|
|
285
|
+
* @returns An array of columns.
|
|
289
286
|
*/
|
|
290
|
-
|
|
291
|
-
|
|
287
|
+
getColumns() {
|
|
288
|
+
return this.columns;
|
|
292
289
|
}
|
|
293
290
|
/**
|
|
294
|
-
*
|
|
295
|
-
* @returns An
|
|
291
|
+
* Returns all rows in the dataset as an array.
|
|
292
|
+
* @returns An array of rows.
|
|
296
293
|
*/
|
|
297
|
-
|
|
298
|
-
|
|
294
|
+
getRows() {
|
|
295
|
+
return this.rows;
|
|
299
296
|
}
|
|
300
297
|
/**
|
|
301
298
|
* Returns the number of column definitions.
|
|
@@ -338,18 +335,6 @@ function makeParseEntities() {
|
|
|
338
335
|
return entities$1;
|
|
339
336
|
}
|
|
340
337
|
/**
|
|
341
|
-
* Creates an array of entities for writing XML, including control characters.
|
|
342
|
-
* @returns An array of objects, each with an `entity` (e.g., "") and its `value` (e.g., "\x01").
|
|
343
|
-
*/
|
|
344
|
-
function makeWriterEntities() {
|
|
345
|
-
const entities$1 = [];
|
|
346
|
-
for (let i = 1; i <= 32; i++) entities$1.push({
|
|
347
|
-
entity: `&#${i};`,
|
|
348
|
-
value: String.fromCharCode(i)
|
|
349
|
-
});
|
|
350
|
-
return entities$1;
|
|
351
|
-
}
|
|
352
|
-
/**
|
|
353
338
|
* Converts a Base64 string to a Uint8Array.
|
|
354
339
|
* @param base64String - The Base64 string to convert.
|
|
355
340
|
* @returns A Uint8Array.
|
|
@@ -520,15 +505,291 @@ function convertToString(value, type) {
|
|
|
520
505
|
const entities = makeParseEntities();
|
|
521
506
|
function _unescapeXml(str) {
|
|
522
507
|
if (!str) return str;
|
|
508
|
+
let result = str.replace(/</g, "<").replace(/>/g, ">").replace(/"/g, "\"").replace(/'/g, "'").replace(/&/g, "&");
|
|
523
509
|
const regex = new RegExp(entities.map((e) => e.entity).join("|"), "g");
|
|
524
|
-
|
|
510
|
+
result = result.replace(regex, (match) => {
|
|
525
511
|
const entity = entities.find((e) => e.entity === match);
|
|
526
512
|
return entity ? entity.value : match;
|
|
527
513
|
});
|
|
514
|
+
return result;
|
|
528
515
|
}
|
|
529
516
|
function isXapiRoot(value) {
|
|
530
517
|
return value instanceof XapiRoot;
|
|
531
518
|
}
|
|
519
|
+
/**
|
|
520
|
+
* Escapes XML special characters in a string.
|
|
521
|
+
* @param str - The string to escape.
|
|
522
|
+
* @returns The escaped string.
|
|
523
|
+
*/
|
|
524
|
+
function escapeXml(str) {
|
|
525
|
+
return str.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
526
|
+
}
|
|
527
|
+
/**
|
|
528
|
+
* Encodes control characters as XML entities, excluding standard whitespace.
|
|
529
|
+
* Encodes 0x01-0x08, 0x0B-0x0C, 0x0E-0x1F but NOT 0x09 (tab), 0x0A (LF), 0x0D (CR), 0x20 (space).
|
|
530
|
+
* @param str - The string to encode.
|
|
531
|
+
* @returns The encoded string.
|
|
532
|
+
*/
|
|
533
|
+
function encodeControlChars(str) {
|
|
534
|
+
let result = "";
|
|
535
|
+
for (let i = 0; i < str.length; i++) {
|
|
536
|
+
const charCode = str.charCodeAt(i);
|
|
537
|
+
if (charCode >= 1 && charCode <= 8 || charCode >= 11 && charCode <= 12 || charCode >= 14 && charCode <= 31) result += `&#${charCode};`;
|
|
538
|
+
else result += str[i];
|
|
539
|
+
}
|
|
540
|
+
return result;
|
|
541
|
+
}
|
|
542
|
+
/**
|
|
543
|
+
* A string builder for generating formatted XML.
|
|
544
|
+
*/
|
|
545
|
+
var XmlStringBuilder = class {
|
|
546
|
+
lines = [];
|
|
547
|
+
indentLevel = 0;
|
|
548
|
+
indentString = " ";
|
|
549
|
+
/**
|
|
550
|
+
* Writes the XML declaration.
|
|
551
|
+
* @param version - The XML version (default: "1.0").
|
|
552
|
+
* @param encoding - The encoding (default: "UTF-8").
|
|
553
|
+
*/
|
|
554
|
+
writeDeclaration(version = "1.0", encoding = "UTF-8") {
|
|
555
|
+
this.lines.push(`<?xml version="${version}" encoding="${encoding}"?>`);
|
|
556
|
+
}
|
|
557
|
+
/**
|
|
558
|
+
* Writes a start element tag.
|
|
559
|
+
* @param name - The element name.
|
|
560
|
+
* @param attributes - Optional attributes object.
|
|
561
|
+
* @param selfClosing - Whether to create a self-closing tag.
|
|
562
|
+
*/
|
|
563
|
+
writeStartElement(name, attributes, selfClosing) {
|
|
564
|
+
let tag = `${this.indentString.repeat(this.indentLevel)}<${name}`;
|
|
565
|
+
if (attributes) for (const [key, value] of Object.entries(attributes)) {
|
|
566
|
+
const encodedValue = encodeControlChars(escapeXml(value));
|
|
567
|
+
tag += ` ${key}="${encodedValue}"`;
|
|
568
|
+
}
|
|
569
|
+
if (selfClosing) {
|
|
570
|
+
tag += "/>";
|
|
571
|
+
this.lines.push(tag);
|
|
572
|
+
} else {
|
|
573
|
+
tag += ">";
|
|
574
|
+
this.lines.push(tag);
|
|
575
|
+
this.indentLevel++;
|
|
576
|
+
}
|
|
577
|
+
}
|
|
578
|
+
/**
|
|
579
|
+
* Writes an end element tag.
|
|
580
|
+
* @param name - The element name.
|
|
581
|
+
*/
|
|
582
|
+
writeEndElement(name) {
|
|
583
|
+
this.indentLevel--;
|
|
584
|
+
const indent = this.indentString.repeat(this.indentLevel);
|
|
585
|
+
this.lines.push(`${indent}</${name}>`);
|
|
586
|
+
}
|
|
587
|
+
/**
|
|
588
|
+
* Writes an element with text content.
|
|
589
|
+
* @param name - The element name.
|
|
590
|
+
* @param attributes - Optional attributes object.
|
|
591
|
+
* @param text - The text content.
|
|
592
|
+
*/
|
|
593
|
+
writeElementWithText(name, attributes, text) {
|
|
594
|
+
let tag = `${this.indentString.repeat(this.indentLevel)}<${name}`;
|
|
595
|
+
if (attributes) for (const [key, value] of Object.entries(attributes)) {
|
|
596
|
+
const encodedValue = encodeControlChars(escapeXml(value));
|
|
597
|
+
tag += ` ${key}="${encodedValue}"`;
|
|
598
|
+
}
|
|
599
|
+
const encodedText = encodeControlChars(escapeXml(text));
|
|
600
|
+
tag += `>${encodedText}</${name}>`;
|
|
601
|
+
this.lines.push(tag);
|
|
602
|
+
}
|
|
603
|
+
/**
|
|
604
|
+
* Returns the generated XML string.
|
|
605
|
+
* @returns The complete XML string with line breaks.
|
|
606
|
+
*/
|
|
607
|
+
toString() {
|
|
608
|
+
return this.lines.join("\n") + "\n";
|
|
609
|
+
}
|
|
610
|
+
};
|
|
611
|
+
/**
|
|
612
|
+
* Parses XML string into an XML node structure.
|
|
613
|
+
* This is a lightweight parser optimized for X-API XML structure.
|
|
614
|
+
*
|
|
615
|
+
* @param xml - The XML string to parse.
|
|
616
|
+
* @returns An array of parsed XML nodes.
|
|
617
|
+
*/
|
|
618
|
+
function parseXml(xml) {
|
|
619
|
+
if (!xml || xml.trim() === "") return [];
|
|
620
|
+
return new XapiXmlParser(xml).parse();
|
|
621
|
+
}
|
|
622
|
+
/**
|
|
623
|
+
* A lightweight XML parser optimized for X-API structure.
|
|
624
|
+
*/
|
|
625
|
+
var XapiXmlParser = class {
|
|
626
|
+
xml;
|
|
627
|
+
pos = 0;
|
|
628
|
+
length;
|
|
629
|
+
constructor(xml) {
|
|
630
|
+
this.xml = xml;
|
|
631
|
+
this.length = xml.length;
|
|
632
|
+
}
|
|
633
|
+
parse() {
|
|
634
|
+
const nodes = [];
|
|
635
|
+
while (this.pos < this.length) {
|
|
636
|
+
this.skipWhitespace();
|
|
637
|
+
if (this.pos >= this.length) break;
|
|
638
|
+
if (this.peek(5) === "<?xml") {
|
|
639
|
+
this.skipUntil("?>");
|
|
640
|
+
this.pos += 2;
|
|
641
|
+
continue;
|
|
642
|
+
}
|
|
643
|
+
if (this.peek(4) === "<!--") {
|
|
644
|
+
this.skipUntil("-->");
|
|
645
|
+
this.pos += 3;
|
|
646
|
+
continue;
|
|
647
|
+
}
|
|
648
|
+
if (this.current() === "<") {
|
|
649
|
+
const node = this.parseElement();
|
|
650
|
+
if (node) nodes.push(node);
|
|
651
|
+
} else this.pos++;
|
|
652
|
+
}
|
|
653
|
+
return nodes;
|
|
654
|
+
}
|
|
655
|
+
parseElement() {
|
|
656
|
+
if (this.current() !== "<") return null;
|
|
657
|
+
this.pos++;
|
|
658
|
+
if (this.current() === "/") return null;
|
|
659
|
+
const tagName = this.parseTagName();
|
|
660
|
+
if (!tagName) return null;
|
|
661
|
+
const node = { tagName };
|
|
662
|
+
const attributes = this.parseAttributes();
|
|
663
|
+
if (attributes && Object.keys(attributes).length > 0) node.attributes = attributes;
|
|
664
|
+
this.skipWhitespace();
|
|
665
|
+
if (this.peek(2) === "/>") {
|
|
666
|
+
this.pos += 2;
|
|
667
|
+
return node;
|
|
668
|
+
}
|
|
669
|
+
if (this.current() === ">") this.pos++;
|
|
670
|
+
const children = [];
|
|
671
|
+
let textContent = "";
|
|
672
|
+
while (this.pos < this.length) {
|
|
673
|
+
if (this.peek(9) === "<![CDATA[") {
|
|
674
|
+
const cdataText = this.parseCDATA();
|
|
675
|
+
if (cdataText !== null) textContent += cdataText;
|
|
676
|
+
continue;
|
|
677
|
+
}
|
|
678
|
+
if (this.peek(2) === "</") {
|
|
679
|
+
if (textContent) children.push(textContent);
|
|
680
|
+
this.pos += 2;
|
|
681
|
+
this.skipUntil(">");
|
|
682
|
+
this.pos++;
|
|
683
|
+
break;
|
|
684
|
+
}
|
|
685
|
+
if (this.current() === "<") {
|
|
686
|
+
if (textContent.trim()) {
|
|
687
|
+
children.push(textContent);
|
|
688
|
+
textContent = "";
|
|
689
|
+
}
|
|
690
|
+
const child = this.parseElement();
|
|
691
|
+
if (child) children.push(child);
|
|
692
|
+
} else {
|
|
693
|
+
textContent += this.current();
|
|
694
|
+
this.pos++;
|
|
695
|
+
}
|
|
696
|
+
}
|
|
697
|
+
if (children.length > 0) node.children = children;
|
|
698
|
+
return node;
|
|
699
|
+
}
|
|
700
|
+
parseTagName() {
|
|
701
|
+
let name = "";
|
|
702
|
+
while (this.pos < this.length) {
|
|
703
|
+
const ch = this.current();
|
|
704
|
+
if (ch === " " || ch === " " || ch === "\n" || ch === "\r" || ch === ">" || ch === "/") break;
|
|
705
|
+
name += ch;
|
|
706
|
+
this.pos++;
|
|
707
|
+
}
|
|
708
|
+
return name;
|
|
709
|
+
}
|
|
710
|
+
parseAttributes() {
|
|
711
|
+
const attrs = {};
|
|
712
|
+
while (this.pos < this.length) {
|
|
713
|
+
this.skipWhitespace();
|
|
714
|
+
const ch = this.current();
|
|
715
|
+
if (ch === ">" || ch === "/" || this.peek(2) === "/>") break;
|
|
716
|
+
const attrName = this.parseAttributeName();
|
|
717
|
+
if (!attrName) break;
|
|
718
|
+
this.skipWhitespace();
|
|
719
|
+
if (this.current() === "=") this.pos++;
|
|
720
|
+
this.skipWhitespace();
|
|
721
|
+
attrs[attrName] = this.parseAttributeValue();
|
|
722
|
+
}
|
|
723
|
+
return Object.keys(attrs).length > 0 ? attrs : void 0;
|
|
724
|
+
}
|
|
725
|
+
parseAttributeName() {
|
|
726
|
+
let name = "";
|
|
727
|
+
while (this.pos < this.length) {
|
|
728
|
+
const ch = this.current();
|
|
729
|
+
if (ch === "=" || ch === " " || ch === " " || ch === "\n" || ch === "\r" || ch === ">" || ch === "/") break;
|
|
730
|
+
name += ch;
|
|
731
|
+
this.pos++;
|
|
732
|
+
}
|
|
733
|
+
return name;
|
|
734
|
+
}
|
|
735
|
+
parseAttributeValue() {
|
|
736
|
+
let value = "";
|
|
737
|
+
const quote = this.current();
|
|
738
|
+
if (quote !== "\"" && quote !== "'") {
|
|
739
|
+
while (this.pos < this.length) {
|
|
740
|
+
const ch = this.current();
|
|
741
|
+
if (ch === " " || ch === " " || ch === "\n" || ch === "\r" || ch === ">" || ch === "/") break;
|
|
742
|
+
value += ch;
|
|
743
|
+
this.pos++;
|
|
744
|
+
}
|
|
745
|
+
return value;
|
|
746
|
+
}
|
|
747
|
+
this.pos++;
|
|
748
|
+
while (this.pos < this.length) {
|
|
749
|
+
const ch = this.current();
|
|
750
|
+
if (ch === quote) {
|
|
751
|
+
this.pos++;
|
|
752
|
+
break;
|
|
753
|
+
}
|
|
754
|
+
value += ch;
|
|
755
|
+
this.pos++;
|
|
756
|
+
}
|
|
757
|
+
return value;
|
|
758
|
+
}
|
|
759
|
+
parseCDATA() {
|
|
760
|
+
if (this.peek(9) !== "<![CDATA[") return null;
|
|
761
|
+
this.pos += 9;
|
|
762
|
+
let content = "";
|
|
763
|
+
while (this.pos < this.length) {
|
|
764
|
+
if (this.peek(3) === "]]>") {
|
|
765
|
+
this.pos += 3;
|
|
766
|
+
break;
|
|
767
|
+
}
|
|
768
|
+
content += this.current();
|
|
769
|
+
this.pos++;
|
|
770
|
+
}
|
|
771
|
+
return content;
|
|
772
|
+
}
|
|
773
|
+
skipWhitespace() {
|
|
774
|
+
while (this.pos < this.length) {
|
|
775
|
+
const ch = this.current();
|
|
776
|
+
if (ch !== " " && ch !== " " && ch !== "\n" && ch !== "\r") break;
|
|
777
|
+
this.pos++;
|
|
778
|
+
}
|
|
779
|
+
}
|
|
780
|
+
skipUntil(target) {
|
|
781
|
+
while (this.pos < this.length) {
|
|
782
|
+
if (this.peek(target.length) === target) break;
|
|
783
|
+
this.pos++;
|
|
784
|
+
}
|
|
785
|
+
}
|
|
786
|
+
current() {
|
|
787
|
+
return this.xml[this.pos];
|
|
788
|
+
}
|
|
789
|
+
peek(length) {
|
|
790
|
+
return this.xml.substring(this.pos, this.pos + length);
|
|
791
|
+
}
|
|
792
|
+
};
|
|
532
793
|
|
|
533
794
|
//#endregion
|
|
534
795
|
//#region src/handler.ts
|
|
@@ -545,12 +806,12 @@ function initXapi(options) {
|
|
|
545
806
|
_options = { ...options };
|
|
546
807
|
}
|
|
547
808
|
/**
|
|
548
|
-
* Parses an XML string into an XapiRoot object using
|
|
809
|
+
* Parses an XML string into an XapiRoot object using custom parser.
|
|
549
810
|
* @param xml - The string containing the XML data.
|
|
550
|
-
* @returns
|
|
811
|
+
* @returns An XapiRoot object.
|
|
551
812
|
*/
|
|
552
813
|
function parse(xml) {
|
|
553
|
-
const parsedXml =
|
|
814
|
+
const parsedXml = parseXml(xml);
|
|
554
815
|
const xapiRoot = new XapiRoot();
|
|
555
816
|
let rootElement;
|
|
556
817
|
for (let i = 0; i < parsedXml.length; i++) if (parsedXml[i].tagName === "Root") {
|
|
@@ -561,6 +822,7 @@ function parse(xml) {
|
|
|
561
822
|
const rootChildren = rootElement.children;
|
|
562
823
|
if (rootChildren && rootChildren.length > 0) for (let i = 0; i < rootChildren.length; i++) {
|
|
563
824
|
const child = rootChildren[i];
|
|
825
|
+
if (typeof child === "string") continue;
|
|
564
826
|
const tagName = child.tagName;
|
|
565
827
|
if (tagName === "Parameters") parseParameters(child, xapiRoot);
|
|
566
828
|
else if (tagName === "Dataset") {
|
|
@@ -573,6 +835,7 @@ function parse(xml) {
|
|
|
573
835
|
let rowsElement;
|
|
574
836
|
if (datasetChildren) for (let j = 0; j < datasetChildren.length; j++) {
|
|
575
837
|
const datasetChild = datasetChildren[j];
|
|
838
|
+
if (typeof datasetChild === "string") continue;
|
|
576
839
|
const childTagName = datasetChild.tagName;
|
|
577
840
|
if (childTagName === "ColumnInfo") columnInfoElement = datasetChild;
|
|
578
841
|
else if (childTagName === "Rows") rowsElement = datasetChild;
|
|
@@ -589,89 +852,93 @@ function parseValue(value, type = "STRING") {
|
|
|
589
852
|
return _options.parseToTypes ? convertToColumnType(value, type) : value;
|
|
590
853
|
}
|
|
591
854
|
function parseColumnInfo(columnInfoElement, dataset) {
|
|
592
|
-
if (!columnInfoElement) throw new InvalidXmlError("ColumnInfo element is missing in the dataset");
|
|
855
|
+
if (!columnInfoElement || typeof columnInfoElement === "string") throw new InvalidXmlError("ColumnInfo element is missing in the dataset");
|
|
593
856
|
const children = columnInfoElement.children;
|
|
594
857
|
if (!children) return;
|
|
595
858
|
for (let i = 0; i < children.length; i++) {
|
|
596
859
|
const colInfo = children[i];
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
860
|
+
if (typeof colInfo !== "string") {
|
|
861
|
+
const tagName = colInfo.tagName;
|
|
862
|
+
if (tagName === "ConstColumn") {
|
|
863
|
+
const attrs = colInfo.attributes;
|
|
864
|
+
const sizeStr = attrs?.size;
|
|
865
|
+
dataset.addConstColumn({
|
|
866
|
+
id: attrs?.id,
|
|
867
|
+
size: sizeStr ? parseInt(sizeStr, 10) : 0,
|
|
868
|
+
type: attrs?.type || "STRING",
|
|
869
|
+
value: parseValue(attrs?.value, attrs?.type)
|
|
870
|
+
});
|
|
871
|
+
} else if (tagName === "Column") {
|
|
872
|
+
const attrs = colInfo.attributes;
|
|
873
|
+
const sizeStr = attrs?.size;
|
|
874
|
+
dataset.addColumn({
|
|
875
|
+
id: attrs?.id,
|
|
876
|
+
size: sizeStr ? parseInt(sizeStr, 10) : 0,
|
|
877
|
+
type: attrs?.type || "STRING"
|
|
878
|
+
});
|
|
879
|
+
}
|
|
615
880
|
}
|
|
616
881
|
}
|
|
617
882
|
}
|
|
618
883
|
function parseRows(rowsElement, dataset) {
|
|
884
|
+
if (typeof rowsElement === "string") return;
|
|
619
885
|
const rows = rowsElement?.children;
|
|
620
886
|
if (!rows) return;
|
|
621
887
|
const datasetRows = dataset.rows;
|
|
622
888
|
for (let i = 0; i < rows.length; i++) {
|
|
623
889
|
const r = rows[i];
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
const columnInfo = dataset.getColumnInfo(colId);
|
|
638
|
-
if (!columnInfo) throw new InvalidXmlError(`Column with id ${colId} not found in dataset ${dataset.id}`);
|
|
639
|
-
const castedValue = parseValue(value, columnInfo.type);
|
|
640
|
-
currentRow.cols.push({
|
|
641
|
-
id: colId,
|
|
642
|
-
value: castedValue
|
|
643
|
-
});
|
|
644
|
-
} else if (colTagName === "OrgRow") {
|
|
645
|
-
const orgRow = [];
|
|
646
|
-
currentRow.orgRow = orgRow;
|
|
647
|
-
const orgCols = col.children;
|
|
648
|
-
if (!orgCols) continue;
|
|
649
|
-
for (let k = 0; k < orgCols.length; k++) {
|
|
650
|
-
const orgCol = orgCols[k];
|
|
651
|
-
if (orgCol.tagName === "Col") {
|
|
652
|
-
const colId = orgCol.attributes?.id;
|
|
653
|
-
const value = orgCol.children?.[0];
|
|
890
|
+
if (typeof r !== "string") {
|
|
891
|
+
const tagName = r.tagName;
|
|
892
|
+
if (tagName === "Row") {
|
|
893
|
+
const currentRow = datasetRows[dataset.newRow()];
|
|
894
|
+
currentRow.type = r.attributes?.type || void 0;
|
|
895
|
+
const cols = r.children;
|
|
896
|
+
if (cols) for (let j = 0; j < cols.length; j++) {
|
|
897
|
+
const col = cols[j];
|
|
898
|
+
if (typeof col !== "string") {
|
|
899
|
+
const colTagName = col.tagName;
|
|
900
|
+
if (colTagName === "Col") {
|
|
901
|
+
const colId = col.attributes?.id;
|
|
902
|
+
const value = col.children?.[0];
|
|
654
903
|
const columnInfo = dataset.getColumnInfo(colId);
|
|
904
|
+
if (!columnInfo) throw new InvalidXmlError(`Column with id ${colId} not found in dataset ${dataset.id}`);
|
|
655
905
|
const castedValue = parseValue(value, columnInfo.type);
|
|
656
|
-
|
|
906
|
+
currentRow.cols.push({
|
|
657
907
|
id: colId,
|
|
658
908
|
value: castedValue
|
|
659
909
|
});
|
|
910
|
+
} else if (colTagName === "OrgRow") {
|
|
911
|
+
const orgRow = [];
|
|
912
|
+
currentRow.orgRow = orgRow;
|
|
913
|
+
const orgCols = col.children;
|
|
914
|
+
if (orgCols) for (let k = 0; k < orgCols.length; k++) {
|
|
915
|
+
const orgCol = orgCols[k];
|
|
916
|
+
if (typeof orgCol !== "string" && orgCol.tagName === "Col") {
|
|
917
|
+
const colId = orgCol.attributes?.id;
|
|
918
|
+
const value = orgCol.children?.[0];
|
|
919
|
+
const castedValue = parseValue(value, dataset.getColumnInfo(colId).type);
|
|
920
|
+
orgRow.push({
|
|
921
|
+
id: colId,
|
|
922
|
+
value: castedValue
|
|
923
|
+
});
|
|
924
|
+
}
|
|
925
|
+
}
|
|
660
926
|
}
|
|
661
927
|
}
|
|
662
928
|
}
|
|
663
|
-
}
|
|
664
|
-
|
|
665
|
-
|
|
929
|
+
} else if (tagName === "Col") throw new InvalidXmlError("Row must be defined before Col");
|
|
930
|
+
else if (tagName === "OrgRow") throw new InvalidXmlError("Row must be defined before OrgRow");
|
|
931
|
+
}
|
|
666
932
|
}
|
|
667
933
|
}
|
|
668
934
|
function parseParameters(parametersElement, xapiRoot) {
|
|
935
|
+
if (typeof parametersElement === "string") return;
|
|
669
936
|
if (!parametersElement) return;
|
|
670
937
|
const children = parametersElement.children;
|
|
671
938
|
if (!children) return;
|
|
672
939
|
for (let i = 0; i < children.length; i++) {
|
|
673
940
|
const p = children[i];
|
|
674
|
-
if (p.tagName === "Parameter") {
|
|
941
|
+
if (typeof p !== "string" && p.tagName === "Parameter") {
|
|
675
942
|
const attrs = p.attributes;
|
|
676
943
|
const id = attrs?.id;
|
|
677
944
|
const type = attrs?.type || "STRING";
|
|
@@ -685,90 +952,74 @@ function parseParameters(parametersElement, xapiRoot) {
|
|
|
685
952
|
}
|
|
686
953
|
}
|
|
687
954
|
function write(root) {
|
|
688
|
-
const
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
indentString: " ",
|
|
692
|
-
prettyPrint: true
|
|
693
|
-
});
|
|
694
|
-
writer.writeStartDocument("1.0", "UTF-8");
|
|
695
|
-
writer.writeStartElement("Root", { attributes: {
|
|
955
|
+
const builder = new XmlStringBuilder();
|
|
956
|
+
builder.writeDeclaration("1.0", "UTF-8");
|
|
957
|
+
builder.writeStartElement("Root", {
|
|
696
958
|
xmlns: _options.xapiVersion?.xmlns || NexaVersion.xmlns,
|
|
697
959
|
version: _options.xapiVersion?.version || NexaVersion.version
|
|
698
|
-
}
|
|
699
|
-
if (root.parameterSize() > 0) writeParameters(
|
|
960
|
+
});
|
|
961
|
+
if (root.parameterSize() > 0) writeParameters(builder, root.getParameters());
|
|
700
962
|
if (root.datasetSize() > 0) {
|
|
701
|
-
|
|
702
|
-
for (const dataset of root.
|
|
703
|
-
|
|
963
|
+
builder.writeStartElement("Datasets");
|
|
964
|
+
for (const dataset of root.getDatasets()) writeDataset(builder, dataset);
|
|
965
|
+
builder.writeEndElement("Datasets");
|
|
704
966
|
}
|
|
705
|
-
|
|
706
|
-
return
|
|
967
|
+
builder.writeEndElement("Root");
|
|
968
|
+
return builder.toString();
|
|
707
969
|
}
|
|
708
|
-
function writeParameters(
|
|
709
|
-
if (
|
|
710
|
-
|
|
711
|
-
for (const parameter of
|
|
712
|
-
|
|
713
|
-
if (parameter.type !== void 0)
|
|
714
|
-
if (parameter.value !== void 0) if (typeof parameter.value === "string")
|
|
715
|
-
else if (parameter.value instanceof Date)
|
|
716
|
-
else if (parameter.value instanceof Uint8Array)
|
|
717
|
-
else
|
|
718
|
-
|
|
970
|
+
function writeParameters(builder, parameters) {
|
|
971
|
+
if (parameters) {
|
|
972
|
+
builder.writeStartElement("Parameters");
|
|
973
|
+
for (const parameter of parameters) {
|
|
974
|
+
const attrs = { id: parameter.id };
|
|
975
|
+
if (parameter.type !== void 0) attrs.type = parameter.type;
|
|
976
|
+
if (parameter.value !== void 0) if (typeof parameter.value === "string") attrs.value = parameter.value;
|
|
977
|
+
else if (parameter.value instanceof Date) attrs.value = dateToString(parameter.value, parameter.type);
|
|
978
|
+
else if (parameter.value instanceof Uint8Array) attrs.value = uint8ArrayToBase64(parameter.value);
|
|
979
|
+
else attrs.value = String(parameter.value);
|
|
980
|
+
builder.writeStartElement("Parameter", attrs, true);
|
|
719
981
|
}
|
|
720
|
-
|
|
982
|
+
builder.writeEndElement("Parameters");
|
|
721
983
|
}
|
|
722
984
|
}
|
|
723
|
-
function writeDataset(
|
|
724
|
-
|
|
985
|
+
function writeDataset(builder, dataset) {
|
|
986
|
+
builder.writeStartElement("Dataset", { id: dataset.id });
|
|
725
987
|
if (dataset.constColumnSize() > 0 || dataset.columnSize() > 0) {
|
|
726
|
-
|
|
727
|
-
for (const constCol of dataset.
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
size: String(col.size),
|
|
740
|
-
type: col.type
|
|
741
|
-
},
|
|
742
|
-
selfClosing: true
|
|
743
|
-
});
|
|
744
|
-
writer.writeEndElement();
|
|
988
|
+
builder.writeStartElement("ColumnInfo");
|
|
989
|
+
for (const constCol of dataset.getConstColumns()) builder.writeStartElement("ConstColumn", {
|
|
990
|
+
id: constCol.id,
|
|
991
|
+
size: String(constCol.size),
|
|
992
|
+
type: constCol.type,
|
|
993
|
+
value: constCol.value !== void 0 ? String(constCol.value) : ""
|
|
994
|
+
}, true);
|
|
995
|
+
for (const col of dataset.getColumns()) builder.writeStartElement("Column", {
|
|
996
|
+
id: col.id,
|
|
997
|
+
size: String(col.size),
|
|
998
|
+
type: col.type
|
|
999
|
+
}, true);
|
|
1000
|
+
builder.writeEndElement("ColumnInfo");
|
|
745
1001
|
}
|
|
746
|
-
|
|
747
|
-
for (const row of dataset.
|
|
748
|
-
if (row.type)
|
|
749
|
-
else
|
|
750
|
-
for (const col of row.cols) writeColumn(
|
|
1002
|
+
builder.writeStartElement("Rows");
|
|
1003
|
+
for (const row of dataset.getRows()) {
|
|
1004
|
+
if (row.type) builder.writeStartElement("Row", { type: row.type });
|
|
1005
|
+
else builder.writeStartElement("Row");
|
|
1006
|
+
for (const col of row.cols) writeColumn(builder, dataset, col);
|
|
751
1007
|
if (row.orgRow && row.orgRow.length > 0) {
|
|
752
|
-
|
|
753
|
-
for (const orgCol of row.orgRow) writeColumn(
|
|
754
|
-
|
|
1008
|
+
builder.writeStartElement("OrgRow");
|
|
1009
|
+
for (const orgCol of row.orgRow) writeColumn(builder, dataset, orgCol);
|
|
1010
|
+
builder.writeEndElement("OrgRow");
|
|
755
1011
|
}
|
|
756
|
-
|
|
1012
|
+
builder.writeEndElement("Row");
|
|
757
1013
|
}
|
|
758
|
-
|
|
759
|
-
|
|
1014
|
+
builder.writeEndElement("Rows");
|
|
1015
|
+
builder.writeEndElement("Dataset");
|
|
760
1016
|
}
|
|
761
|
-
function writeColumn(
|
|
1017
|
+
function writeColumn(builder, dataset, col) {
|
|
762
1018
|
if (col.value !== void 0 && col.value !== null) {
|
|
763
1019
|
const colInfo = dataset.getColumnInfo(col.id);
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
writer.writeEndElement();
|
|
767
|
-
} else writer.writeStartElement("Col", {
|
|
768
|
-
attributes: { id: col.id },
|
|
769
|
-
selfClosing: true
|
|
770
|
-
});
|
|
1020
|
+
builder.writeElementWithText("Col", { id: col.id }, convertToString(col.value, colInfo.type));
|
|
1021
|
+
} else builder.writeStartElement("Col", { id: col.id }, true);
|
|
771
1022
|
}
|
|
772
1023
|
|
|
773
1024
|
//#endregion
|
|
774
|
-
export { ColumnTypeError, Dataset, InvalidXmlError, NexaVersion, StringWritableStream, XapiRoot, XplatformVersion, _unescapeXml, arrayBufferToString, base64ToUint8Array, columnType, convertToColumnType, convertToString, dateToString, initXapi, isXapiRoot, makeParseEntities,
|
|
1025
|
+
export { ColumnTypeError, Dataset, InvalidXmlError, NexaVersion, StringWritableStream, XapiRoot, XmlStringBuilder, XplatformVersion, _unescapeXml, arrayBufferToString, base64ToUint8Array, columnType, convertToColumnType, convertToString, dateToString, encodeControlChars, escapeXml, initXapi, isXapiRoot, makeParseEntities, parse, parseXml, rowType, stringToDate, stringToReadableStream, uint8ArrayToBase64, write };
|