@xapi-js/core 1.1.1 → 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/README.md +11 -28
- package/dist/index.cjs +1003 -756
- package/dist/index.d.cts +304 -241
- package/dist/index.d.ts +304 -241
- package/dist/index.js +977 -697
- package/package.json +2 -6
package/dist/index.cjs
CHANGED
|
@@ -1,805 +1,1052 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __create = Object.create;
|
|
3
|
-
var __defProp = Object.defineProperty;
|
|
4
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
-
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
-
var __export = (target, all) => {
|
|
9
|
-
for (var name in all)
|
|
10
|
-
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
-
};
|
|
12
|
-
var __copyProps = (to, from, except, desc) => {
|
|
13
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
-
for (let key of __getOwnPropNames(from))
|
|
15
|
-
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
-
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
-
}
|
|
18
|
-
return to;
|
|
19
|
-
};
|
|
20
|
-
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
-
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
-
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
-
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
-
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
-
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
-
mod
|
|
27
|
-
));
|
|
28
|
-
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
-
|
|
30
|
-
// src/index.ts
|
|
31
|
-
var index_exports = {};
|
|
32
|
-
__export(index_exports, {
|
|
33
|
-
ColumnTypeError: () => ColumnTypeError,
|
|
34
|
-
Dataset: () => Dataset,
|
|
35
|
-
InvalidXmlError: () => InvalidXmlError,
|
|
36
|
-
NexaVersion: () => NexaVersion,
|
|
37
|
-
StringWritableStream: () => StringWritableStream,
|
|
38
|
-
XapiRoot: () => XapiRoot,
|
|
39
|
-
XplatformVersion: () => XplatformVersion,
|
|
40
|
-
_unescapeXml: () => _unescapeXml,
|
|
41
|
-
arrayBufferToString: () => arrayBufferToString,
|
|
42
|
-
base64ToUint8Array: () => base64ToUint8Array,
|
|
43
|
-
columnType: () => columnType,
|
|
44
|
-
convertToColumnType: () => convertToColumnType,
|
|
45
|
-
convertToString: () => convertToString,
|
|
46
|
-
dateToString: () => dateToString,
|
|
47
|
-
initXapi: () => initXapi,
|
|
48
|
-
makeParseEntities: () => makeParseEntities,
|
|
49
|
-
makeWriterEntities: () => makeWriterEntities,
|
|
50
|
-
parse: () => parse2,
|
|
51
|
-
rowType: () => rowType,
|
|
52
|
-
stringToDate: () => stringToDate,
|
|
53
|
-
stringToReadableStream: () => stringToReadableStream,
|
|
54
|
-
uint8ArrayToBase64: () => uint8ArrayToBase64,
|
|
55
|
-
write: () => write,
|
|
56
|
-
writeString: () => writeString
|
|
57
|
-
});
|
|
58
|
-
module.exports = __toCommonJS(index_exports);
|
|
59
1
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
2
|
+
//#region src/types.ts
|
|
3
|
+
/**
|
|
4
|
+
* Defines the possible types of rows in an X-API dataset (e.g., "insert", "update", "delete").
|
|
5
|
+
*/
|
|
6
|
+
const rowType = [
|
|
7
|
+
"insert",
|
|
8
|
+
"update",
|
|
9
|
+
"delete"
|
|
10
|
+
];
|
|
11
|
+
/**
|
|
12
|
+
* Defines the possible data types for columns in an X-API dataset.
|
|
13
|
+
*/
|
|
14
|
+
const columnType = [
|
|
15
|
+
"STRING",
|
|
16
|
+
"INT",
|
|
17
|
+
"FLOAT",
|
|
18
|
+
"DECIMAL",
|
|
19
|
+
"BIGDECIMAL",
|
|
20
|
+
"DATE",
|
|
21
|
+
"DATETIME",
|
|
22
|
+
"TIME",
|
|
23
|
+
"BLOB"
|
|
24
|
+
];
|
|
25
|
+
/**
|
|
26
|
+
* Xplatform version definition for X-API XML.
|
|
27
|
+
*/
|
|
28
|
+
const XplatformVersion = {
|
|
29
|
+
xmlns: "http://www.tobesoft.com/platform/Dataset",
|
|
30
|
+
version: "4000"
|
|
70
31
|
};
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
32
|
+
/**
|
|
33
|
+
* Nexacro version definition for X-API XML.
|
|
34
|
+
*/
|
|
35
|
+
const NexaVersion = {
|
|
36
|
+
xmlns: "http://www.nexacroplatform.com/platform/dataset",
|
|
37
|
+
version: "4000"
|
|
74
38
|
};
|
|
39
|
+
/**
|
|
40
|
+
* Custom error class for column type related issues.
|
|
41
|
+
*/
|
|
75
42
|
var ColumnTypeError = class extends Error {
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
43
|
+
constructor(message) {
|
|
44
|
+
super(message);
|
|
45
|
+
this.name = "ColumnTypeError";
|
|
46
|
+
}
|
|
80
47
|
};
|
|
81
48
|
var InvalidXmlError = class extends Error {
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
49
|
+
constructor(message) {
|
|
50
|
+
super(message);
|
|
51
|
+
this.name = "InvalidXmlError";
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
//#endregion
|
|
56
|
+
//#region src/xapi-data.ts
|
|
57
|
+
/**
|
|
58
|
+
* Represents the root of an X-API XML structure, containing datasets and parameters.
|
|
59
|
+
*/
|
|
60
|
+
var XapiRoot = class {
|
|
61
|
+
/** An array of datasets within the X-API root. */
|
|
62
|
+
datasets = [];
|
|
63
|
+
/** Parameters associated with the X-API root. */
|
|
64
|
+
parameters = { params: [] };
|
|
65
|
+
/**
|
|
66
|
+
* Creates an instance of XapiRoot.
|
|
67
|
+
* @param datasets - Initial array of datasets.
|
|
68
|
+
* @param parameters - Initial parameters.
|
|
69
|
+
*/
|
|
70
|
+
constructor(datasets = [], parameters = { params: [] }) {
|
|
71
|
+
this.datasets = datasets;
|
|
72
|
+
this.parameters = parameters;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Adds a dataset to the X-API root.
|
|
76
|
+
* @param dataset - The dataset to add.
|
|
77
|
+
*/
|
|
78
|
+
addDataset(dataset) {
|
|
79
|
+
this.datasets.push(dataset);
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Retrieves a dataset by its ID.
|
|
83
|
+
* @param id - The ID of the dataset to retrieve.
|
|
84
|
+
* @returns The Dataset object, or undefined if not found.
|
|
85
|
+
*/
|
|
86
|
+
getDataset(id) {
|
|
87
|
+
return this.datasets.find((dataset) => dataset.id === id);
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Adds a parameter to the X-API root.
|
|
91
|
+
* @param parameter - The parameter to add.
|
|
92
|
+
*/
|
|
93
|
+
addParameter(parameter) {
|
|
94
|
+
this.parameters.params.push(parameter);
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Retrieves a parameter by its ID.
|
|
98
|
+
* @param id - The ID of the parameter to retrieve.
|
|
99
|
+
* @returns The Parameter object, or undefined if not found.
|
|
100
|
+
*/
|
|
101
|
+
getParameter(id) {
|
|
102
|
+
return this.parameters.params.find((param) => param.id === id);
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Sets all parameters for the X-API root.
|
|
106
|
+
* @param parameters - The XapiParameters object to set.
|
|
107
|
+
*/
|
|
108
|
+
setParameters(parameters) {
|
|
109
|
+
this.parameters = parameters;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Sets the value of a specific parameter, or adds it if it doesn't exist.
|
|
113
|
+
* @param id - The ID of the parameter.
|
|
114
|
+
* @param value - The value to set for the parameter.
|
|
115
|
+
*/
|
|
116
|
+
setParameter(id, value) {
|
|
117
|
+
const param = this.parameters.params.find((p) => p.id === id);
|
|
118
|
+
if (param) param.value = value;
|
|
119
|
+
else this.addParameter({
|
|
120
|
+
id,
|
|
121
|
+
value
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Returns the number of parameters.
|
|
126
|
+
* @returns The count of parameters.
|
|
127
|
+
*/
|
|
128
|
+
parameterSize() {
|
|
129
|
+
return this.parameters.params.length;
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Returns the number of datasets.
|
|
133
|
+
* @returns The count of datasets.
|
|
134
|
+
*/
|
|
135
|
+
datasetSize() {
|
|
136
|
+
return this.datasets.length;
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Returns all parameters as an array.
|
|
140
|
+
* @returns An array of parameters.
|
|
141
|
+
*/
|
|
142
|
+
getParameters() {
|
|
143
|
+
return this.parameters.params;
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Returns all datasets as an array.
|
|
147
|
+
* @returns An array of datasets.
|
|
148
|
+
*/
|
|
149
|
+
getDatasets() {
|
|
150
|
+
return this.datasets;
|
|
151
|
+
}
|
|
152
|
+
};
|
|
153
|
+
/**
|
|
154
|
+
* Represents a dataset within an X-API XML structure.
|
|
155
|
+
*/
|
|
156
|
+
var Dataset = class {
|
|
157
|
+
/** The ID of the dataset. */
|
|
158
|
+
id;
|
|
159
|
+
constColumns = [];
|
|
160
|
+
columns = [];
|
|
161
|
+
/** An array of rows in the dataset. */
|
|
162
|
+
rows = [];
|
|
163
|
+
_columnIndexMap = /* @__PURE__ */ new Map();
|
|
164
|
+
/**
|
|
165
|
+
* Creates an instance of Dataset.
|
|
166
|
+
* @param id - The ID of the dataset.
|
|
167
|
+
* @param constColumns - Initial array of constant columns.
|
|
168
|
+
* @param columns - Initial array of columns.
|
|
169
|
+
* @param rows - Initial array of rows.
|
|
170
|
+
*/
|
|
171
|
+
constructor(id, constColumns = [], columns = [], rows = []) {
|
|
172
|
+
this.id = id;
|
|
173
|
+
this.constColumns = constColumns;
|
|
174
|
+
this.columns = columns;
|
|
175
|
+
this.rows = rows;
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Adds a column definition to the dataset.
|
|
179
|
+
* @param column - The column definition to add.
|
|
180
|
+
*/
|
|
181
|
+
addColumn(column) {
|
|
182
|
+
this.columns.push(column);
|
|
183
|
+
this._columnIndexMap.set(column.id, this.columns.length - 1);
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Adds a constant column definition to the dataset.
|
|
187
|
+
* @param column - The constant column definition to add.
|
|
188
|
+
*/
|
|
189
|
+
addConstColumn(column) {
|
|
190
|
+
this.constColumns.push(column);
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Creates a new empty row and adds it to the dataset.
|
|
194
|
+
* @returns The index of the newly created row.
|
|
195
|
+
*/
|
|
196
|
+
newRow() {
|
|
197
|
+
this.rows.push({ cols: [] });
|
|
198
|
+
return this.rows.length - 1;
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Adds an existing row to the dataset.
|
|
202
|
+
* @param row - The row to add.
|
|
203
|
+
*/
|
|
204
|
+
addRow(row) {
|
|
205
|
+
this.rows.push(row);
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
208
|
+
* Retrieves the index of a column by its ID.
|
|
209
|
+
* @param columnId - The ID of the column.
|
|
210
|
+
* @returns The index of the column, or undefined if not found.
|
|
211
|
+
*/
|
|
212
|
+
getColumnIndex(columnId) {
|
|
213
|
+
return this._columnIndexMap.get(columnId);
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* Retrieves the column definition by its ID.
|
|
217
|
+
* @param columnId - The ID of the column.
|
|
218
|
+
* @returns The Column object, or undefined if not found.
|
|
219
|
+
*/
|
|
220
|
+
getColumnInfo(columnId) {
|
|
221
|
+
const colIndex = this.getColumnIndex(columnId);
|
|
222
|
+
if (colIndex !== void 0) return this.columns[colIndex];
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
225
|
+
* Retrieves the constant column definition by its ID.
|
|
226
|
+
* @param columnId - The ID of the constant column.
|
|
227
|
+
* @returns The ConstColumn object, or undefined if not found.
|
|
228
|
+
*/
|
|
229
|
+
getConstColumnInfo(columnId) {
|
|
230
|
+
return this.constColumns.find((col) => col.id === columnId);
|
|
231
|
+
}
|
|
232
|
+
/**
|
|
233
|
+
* Retrieves the value of a column in a specific row.
|
|
234
|
+
* @param rowIdx - The index of the row.
|
|
235
|
+
* @param columnId - The ID of the column.
|
|
236
|
+
* @returns The value of the column, or undefined if the row or column is not found.
|
|
237
|
+
* @throws {Error} if the column ID is not found in the dataset.
|
|
238
|
+
*/
|
|
239
|
+
getColumn(rowIdx, columnId) {
|
|
240
|
+
if (rowIdx < this.rows.length) {
|
|
241
|
+
const colIndex = this.getColumnIndex(columnId);
|
|
242
|
+
if (colIndex === void 0) throw new Error(`Column with id ${columnId} not found in dataset ${this.id}`);
|
|
243
|
+
return this.rows[rowIdx].cols[colIndex]?.value;
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* Retrieves the original value of a column in a specific row (for OrgRow).
|
|
248
|
+
* @param rowIdx - The index of the row.
|
|
249
|
+
* @param columnId - The ID of the column.
|
|
250
|
+
* @returns The original value of the column, or undefined if the row or column is not found.
|
|
251
|
+
* @throws {Error} if the column ID is not found in the dataset.
|
|
252
|
+
*/
|
|
253
|
+
getOrgColumn(rowIdx, columnId) {
|
|
254
|
+
if (rowIdx < this.rows.length) {
|
|
255
|
+
const colIndex = this.getColumnIndex(columnId);
|
|
256
|
+
if (colIndex === void 0) throw new Error(`Column with id ${columnId} not found in dataset ${this.id}`);
|
|
257
|
+
return (this.rows[rowIdx].orgRow?.[colIndex])?.value;
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
/**
|
|
261
|
+
* Sets the value of a column in a specific row.
|
|
262
|
+
* @param rowIdx - The index of the row.
|
|
263
|
+
* @param columnId - The ID of the column.
|
|
264
|
+
* @param value - The value to set.
|
|
265
|
+
* @throws {Error} if the row index is out of bounds or the column ID is not found.
|
|
266
|
+
*/
|
|
267
|
+
setColumn(rowIdx, columnId, value) {
|
|
268
|
+
if (rowIdx < this.rows.length) {
|
|
269
|
+
const colIndex = this.getColumnIndex(columnId);
|
|
270
|
+
if (colIndex === void 0) throw new Error(`Column with id ${columnId} not found in dataset ${this.id}`);
|
|
271
|
+
this.rows[rowIdx].cols[colIndex] = {
|
|
272
|
+
id: columnId,
|
|
273
|
+
value
|
|
274
|
+
};
|
|
275
|
+
} else throw new Error(`Row index ${rowIdx} out of bounds in dataset ${this.id}`);
|
|
276
|
+
}
|
|
277
|
+
/**
|
|
278
|
+
* Returns all constant column definitions as an array.
|
|
279
|
+
* @returns An array of constant columns.
|
|
280
|
+
*/
|
|
281
|
+
getConstColumns() {
|
|
282
|
+
return this.constColumns;
|
|
283
|
+
}
|
|
284
|
+
/**
|
|
285
|
+
* Returns all column definitions as an array.
|
|
286
|
+
* @returns An array of columns.
|
|
287
|
+
*/
|
|
288
|
+
getColumns() {
|
|
289
|
+
return this.columns;
|
|
290
|
+
}
|
|
291
|
+
/**
|
|
292
|
+
* Returns all rows in the dataset as an array.
|
|
293
|
+
* @returns An array of rows.
|
|
294
|
+
*/
|
|
295
|
+
getRows() {
|
|
296
|
+
return this.rows;
|
|
297
|
+
}
|
|
298
|
+
/**
|
|
299
|
+
* Returns the number of column definitions.
|
|
300
|
+
* @returns The count of columns.
|
|
301
|
+
*/
|
|
302
|
+
columnSize() {
|
|
303
|
+
return this.columns.length;
|
|
304
|
+
}
|
|
305
|
+
/**
|
|
306
|
+
* Returns the number of constant column definitions.
|
|
307
|
+
* @returns The count of constant columns.
|
|
308
|
+
*/
|
|
309
|
+
constColumnSize() {
|
|
310
|
+
return this.constColumns.length;
|
|
311
|
+
}
|
|
312
|
+
/**
|
|
313
|
+
* Returns the number of rows in the dataset.
|
|
314
|
+
* @returns The count of rows.
|
|
315
|
+
*/
|
|
316
|
+
rowSize() {
|
|
317
|
+
return this.rows.length;
|
|
318
|
+
}
|
|
86
319
|
};
|
|
87
320
|
|
|
88
|
-
|
|
321
|
+
//#endregion
|
|
322
|
+
//#region src/utils.ts
|
|
89
323
|
function arrayBufferToString(buffer) {
|
|
90
|
-
|
|
91
|
-
return decoder.decode(buffer);
|
|
324
|
+
return new TextDecoder().decode(buffer);
|
|
92
325
|
}
|
|
326
|
+
/**
|
|
327
|
+
* Creates an array of entities for parsing XML, including control characters.
|
|
328
|
+
* @returns An array of objects, each with an `entity` (e.g., "") and its `value` (e.g., "\x01").
|
|
329
|
+
*/
|
|
93
330
|
function makeParseEntities() {
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
function makeWriterEntities() {
|
|
101
|
-
const entities2 = [];
|
|
102
|
-
for (let i = 1; i <= 32; i++) {
|
|
103
|
-
entities2.push({ entity: `&#${i};`, value: String.fromCharCode(i) });
|
|
104
|
-
}
|
|
105
|
-
return entities2;
|
|
331
|
+
const entities$1 = [];
|
|
332
|
+
for (let i = 1; i <= 32; i++) entities$1.push({
|
|
333
|
+
entity: `&#${i};`,
|
|
334
|
+
value: String.fromCharCode(i)
|
|
335
|
+
});
|
|
336
|
+
return entities$1;
|
|
106
337
|
}
|
|
338
|
+
/**
|
|
339
|
+
* Converts a Base64 string to a Uint8Array.
|
|
340
|
+
* @param base64String - The Base64 string to convert.
|
|
341
|
+
* @returns A Uint8Array.
|
|
342
|
+
*/
|
|
107
343
|
function base64ToUint8Array(base64String) {
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
}
|
|
113
|
-
return bytes;
|
|
344
|
+
const binaryString = atob(base64String);
|
|
345
|
+
const bytes = new Uint8Array(binaryString.length);
|
|
346
|
+
for (let i = 0; i < binaryString.length; i++) bytes[i] = binaryString.charCodeAt(i);
|
|
347
|
+
return bytes;
|
|
114
348
|
}
|
|
349
|
+
/**
|
|
350
|
+
* Converts a Uint8Array to a Base64 string.
|
|
351
|
+
* @param uint8Array - The Uint8Array to convert.
|
|
352
|
+
* @returns A Base64 string.
|
|
353
|
+
*/
|
|
115
354
|
function uint8ArrayToBase64(uint8Array) {
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
}
|
|
120
|
-
return btoa(binaryString);
|
|
355
|
+
let binaryString = "";
|
|
356
|
+
for (let i = 0; i < uint8Array.length; i++) binaryString += String.fromCharCode(uint8Array[i]);
|
|
357
|
+
return btoa(binaryString);
|
|
121
358
|
}
|
|
359
|
+
/**
|
|
360
|
+
* Converts a string representation of a date/time to a Date object.
|
|
361
|
+
* Supports "yyyyMMdd", "yyyyMMddHHmmss", "yyyyMMddHHmmssSSS", and "HHmmss" formats.
|
|
362
|
+
* @param value - The string to convert.
|
|
363
|
+
* @returns A Date object if the string is a valid date/time, otherwise undefined.
|
|
364
|
+
*/
|
|
122
365
|
function stringToDate(value) {
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
if (year < 1970 || year > 9999 || month < 0 || month > 11 || day < 1 || day > 31 || hours < 0 || hours > 23 || minutes < 0 || minutes > 59 || seconds < 0 || seconds > 59 || milliseconds < 0 || milliseconds > 999) {
|
|
156
|
-
return void 0;
|
|
157
|
-
}
|
|
158
|
-
const date = new Date(year, month, day, hours, minutes, seconds, milliseconds);
|
|
159
|
-
if (isNaN(date.getTime())) {
|
|
160
|
-
return void 0;
|
|
161
|
-
}
|
|
162
|
-
return date;
|
|
366
|
+
if (!value) return void 0;
|
|
367
|
+
let year;
|
|
368
|
+
let month;
|
|
369
|
+
let day;
|
|
370
|
+
let hours = 0;
|
|
371
|
+
let minutes = 0;
|
|
372
|
+
let seconds = 0;
|
|
373
|
+
let milliseconds = 0;
|
|
374
|
+
if (value.length < 6 || value.length > 16) return;
|
|
375
|
+
if (value.length >= 8) {
|
|
376
|
+
year = parseInt(value.substring(0, 4), 10);
|
|
377
|
+
month = parseInt(value.substring(4, 6), 10) - 1;
|
|
378
|
+
day = parseInt(value.substring(6, 8), 10);
|
|
379
|
+
} else {
|
|
380
|
+
year = 1970;
|
|
381
|
+
month = 0;
|
|
382
|
+
day = 1;
|
|
383
|
+
}
|
|
384
|
+
if (value.length === 6) {
|
|
385
|
+
hours = parseInt(value.substring(0, 2), 10);
|
|
386
|
+
minutes = parseInt(value.substring(2, 4), 10);
|
|
387
|
+
seconds = parseInt(value.substring(4, 6), 10);
|
|
388
|
+
} else if (value.length >= 10) {
|
|
389
|
+
hours = parseInt(value.substring(8, 10), 10);
|
|
390
|
+
minutes = parseInt(value.substring(10, 12), 10);
|
|
391
|
+
seconds = parseInt(value.substring(12, 14), 10);
|
|
392
|
+
}
|
|
393
|
+
if (value.length === 16) milliseconds = parseInt(value.substring(14, 16), 10);
|
|
394
|
+
if (year < 1970 || year > 9999 || month < 0 || month > 11 || day < 1 || day > 31 || hours < 0 || hours > 23 || minutes < 0 || minutes > 59 || seconds < 0 || seconds > 59 || milliseconds < 0 || milliseconds > 999) return;
|
|
395
|
+
const date = new Date(year, month, day, hours, minutes, seconds, milliseconds);
|
|
396
|
+
if (isNaN(date.getTime())) return;
|
|
397
|
+
return date;
|
|
163
398
|
}
|
|
399
|
+
/**
|
|
400
|
+
* Converts a Date object to a string representation based on the specified column type.
|
|
401
|
+
* @param date - The Date object to convert.
|
|
402
|
+
* @param type - The column type ("DATE", "DATETIME", or "TIME").
|
|
403
|
+
* @returns A string representation of the date/time.
|
|
404
|
+
*/
|
|
164
405
|
function dateToString(date, type) {
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
return `${hours}${minutes}${seconds}`;
|
|
178
|
-
default:
|
|
179
|
-
return "";
|
|
180
|
-
}
|
|
406
|
+
const year = date.getFullYear().toString().padStart(4, "0");
|
|
407
|
+
const month = (date.getMonth() + 1).toString().padStart(2, "0");
|
|
408
|
+
const day = date.getDate().toString().padStart(2, "0");
|
|
409
|
+
const hours = date.getHours().toString().padStart(2, "0");
|
|
410
|
+
const minutes = date.getMinutes().toString().padStart(2, "0");
|
|
411
|
+
const seconds = date.getSeconds().toString().padStart(2, "0");
|
|
412
|
+
switch (type) {
|
|
413
|
+
case "DATE": return `${year}${month}${day}`;
|
|
414
|
+
case "DATETIME": return `${year}${month}${day}${hours}${minutes}${seconds}`;
|
|
415
|
+
case "TIME": return `${hours}${minutes}${seconds}`;
|
|
416
|
+
default: return "";
|
|
417
|
+
}
|
|
181
418
|
}
|
|
419
|
+
/**
|
|
420
|
+
* A WritableStream that collects all written Uint8Array chunks and provides them as a single string.
|
|
421
|
+
*/
|
|
182
422
|
var StringWritableStream = class extends WritableStream {
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
423
|
+
result = "";
|
|
424
|
+
constructor() {
|
|
425
|
+
const decoder = new TextDecoder();
|
|
426
|
+
super({
|
|
427
|
+
write: (chunk) => {
|
|
428
|
+
this.result += decoder.decode(chunk, { stream: true });
|
|
429
|
+
},
|
|
430
|
+
close: () => {
|
|
431
|
+
this.result += decoder.decode();
|
|
432
|
+
}
|
|
433
|
+
});
|
|
434
|
+
}
|
|
435
|
+
/**
|
|
436
|
+
* Returns the collected string result.
|
|
437
|
+
* @returns The concatenated string from all written chunks.
|
|
438
|
+
*/
|
|
439
|
+
getResult() {
|
|
440
|
+
return this.result;
|
|
441
|
+
}
|
|
202
442
|
};
|
|
443
|
+
/**
|
|
444
|
+
* Converts a string to a ReadableStream of Uint8Array.
|
|
445
|
+
* @param str - The string to convert.
|
|
446
|
+
* @returns A ReadableStream containing the string as Uint8Array.
|
|
447
|
+
*/
|
|
203
448
|
function stringToReadableStream(str) {
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
controller.close();
|
|
210
|
-
}
|
|
211
|
-
});
|
|
449
|
+
const bytes = new TextEncoder().encode(str);
|
|
450
|
+
return new ReadableStream({ start(controller) {
|
|
451
|
+
controller.enqueue(bytes);
|
|
452
|
+
controller.close();
|
|
453
|
+
} });
|
|
212
454
|
}
|
|
455
|
+
/**
|
|
456
|
+
* Converts a value to the specified ColumnType.
|
|
457
|
+
* @param value - The value to convert.
|
|
458
|
+
* @param type - The target ColumnType.
|
|
459
|
+
* @returns The converted value, or the original value if conversion fails or is not applicable.
|
|
460
|
+
* @throws {ColumnTypeError} if the column type is unsupported.
|
|
461
|
+
*/
|
|
213
462
|
function convertToColumnType(value, type) {
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
return value;
|
|
237
|
-
default:
|
|
238
|
-
throw new ColumnTypeError(`Unsupported column type: ${type}`);
|
|
239
|
-
}
|
|
463
|
+
switch (type) {
|
|
464
|
+
case "INT":
|
|
465
|
+
case "BIGDECIMAL":
|
|
466
|
+
const intValue = parseInt(value, 10);
|
|
467
|
+
return isNaN(intValue) ? value : intValue;
|
|
468
|
+
case "FLOAT":
|
|
469
|
+
const floatValue = parseFloat(value);
|
|
470
|
+
return isNaN(floatValue) ? value : floatValue;
|
|
471
|
+
case "DECIMAL":
|
|
472
|
+
const decimalValue = parseFloat(value);
|
|
473
|
+
return isNaN(decimalValue) ? value : decimalValue;
|
|
474
|
+
case "DATE":
|
|
475
|
+
case "DATETIME":
|
|
476
|
+
case "TIME": return stringToDate(value) || value;
|
|
477
|
+
case "BLOB": try {
|
|
478
|
+
return base64ToUint8Array(value);
|
|
479
|
+
} catch {
|
|
480
|
+
return value;
|
|
481
|
+
}
|
|
482
|
+
case "STRING": return value;
|
|
483
|
+
default: throw new ColumnTypeError(`Unsupported column type: ${type}`);
|
|
484
|
+
}
|
|
240
485
|
}
|
|
486
|
+
/**
|
|
487
|
+
* Converts an XapiValueType to its string representation based on the specified ColumnType.
|
|
488
|
+
* @param value - The value to convert.
|
|
489
|
+
* @param type - The ColumnType to guide the conversion.
|
|
490
|
+
* @returns The string representation of the value.
|
|
491
|
+
*/
|
|
241
492
|
function convertToString(value, type) {
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
case "STRING":
|
|
255
|
-
return String(value);
|
|
256
|
-
default:
|
|
257
|
-
return String(value);
|
|
258
|
-
}
|
|
493
|
+
switch (type) {
|
|
494
|
+
case "INT":
|
|
495
|
+
case "BIGDECIMAL":
|
|
496
|
+
case "FLOAT":
|
|
497
|
+
case "DECIMAL": return String(value);
|
|
498
|
+
case "DATE":
|
|
499
|
+
case "DATETIME":
|
|
500
|
+
case "TIME": return dateToString(value, type);
|
|
501
|
+
case "BLOB": return uint8ArrayToBase64(value);
|
|
502
|
+
case "STRING": return String(value);
|
|
503
|
+
default: return String(value);
|
|
504
|
+
}
|
|
259
505
|
}
|
|
260
|
-
|
|
506
|
+
const entities = makeParseEntities();
|
|
261
507
|
function _unescapeXml(str) {
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
508
|
+
if (!str) return str;
|
|
509
|
+
let result = str.replace(/</g, "<").replace(/>/g, ">").replace(/"/g, "\"").replace(/'/g, "'").replace(/&/g, "&");
|
|
510
|
+
const regex = new RegExp(entities.map((e) => e.entity).join("|"), "g");
|
|
511
|
+
result = result.replace(regex, (match) => {
|
|
512
|
+
const entity = entities.find((e) => e.entity === match);
|
|
513
|
+
return entity ? entity.value : match;
|
|
514
|
+
});
|
|
515
|
+
return result;
|
|
268
516
|
}
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
for (const dataset of this.datasets) {
|
|
364
|
-
yield dataset;
|
|
365
|
-
}
|
|
366
|
-
}
|
|
517
|
+
function isXapiRoot(value) {
|
|
518
|
+
return value instanceof XapiRoot;
|
|
519
|
+
}
|
|
520
|
+
/**
|
|
521
|
+
* Escapes XML special characters in a string.
|
|
522
|
+
* @param str - The string to escape.
|
|
523
|
+
* @returns The escaped string.
|
|
524
|
+
*/
|
|
525
|
+
function escapeXml(str) {
|
|
526
|
+
return str.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
527
|
+
}
|
|
528
|
+
/**
|
|
529
|
+
* Encodes control characters as XML entities, excluding standard whitespace.
|
|
530
|
+
* Encodes 0x01-0x08, 0x0B-0x0C, 0x0E-0x1F but NOT 0x09 (tab), 0x0A (LF), 0x0D (CR), 0x20 (space).
|
|
531
|
+
* @param str - The string to encode.
|
|
532
|
+
* @returns The encoded string.
|
|
533
|
+
*/
|
|
534
|
+
function encodeControlChars(str) {
|
|
535
|
+
let result = "";
|
|
536
|
+
for (let i = 0; i < str.length; i++) {
|
|
537
|
+
const charCode = str.charCodeAt(i);
|
|
538
|
+
if (charCode >= 1 && charCode <= 8 || charCode >= 11 && charCode <= 12 || charCode >= 14 && charCode <= 31) result += `&#${charCode};`;
|
|
539
|
+
else result += str[i];
|
|
540
|
+
}
|
|
541
|
+
return result;
|
|
542
|
+
}
|
|
543
|
+
/**
|
|
544
|
+
* A string builder for generating formatted XML.
|
|
545
|
+
*/
|
|
546
|
+
var XmlStringBuilder = class {
|
|
547
|
+
lines = [];
|
|
548
|
+
indentLevel = 0;
|
|
549
|
+
indentString = " ";
|
|
550
|
+
/**
|
|
551
|
+
* Writes the XML declaration.
|
|
552
|
+
* @param version - The XML version (default: "1.0").
|
|
553
|
+
* @param encoding - The encoding (default: "UTF-8").
|
|
554
|
+
*/
|
|
555
|
+
writeDeclaration(version = "1.0", encoding = "UTF-8") {
|
|
556
|
+
this.lines.push(`<?xml version="${version}" encoding="${encoding}"?>`);
|
|
557
|
+
}
|
|
558
|
+
/**
|
|
559
|
+
* Writes a start element tag.
|
|
560
|
+
* @param name - The element name.
|
|
561
|
+
* @param attributes - Optional attributes object.
|
|
562
|
+
* @param selfClosing - Whether to create a self-closing tag.
|
|
563
|
+
*/
|
|
564
|
+
writeStartElement(name, attributes, selfClosing) {
|
|
565
|
+
let tag = `${this.indentString.repeat(this.indentLevel)}<${name}`;
|
|
566
|
+
if (attributes) for (const [key, value] of Object.entries(attributes)) {
|
|
567
|
+
const encodedValue = encodeControlChars(escapeXml(value));
|
|
568
|
+
tag += ` ${key}="${encodedValue}"`;
|
|
569
|
+
}
|
|
570
|
+
if (selfClosing) {
|
|
571
|
+
tag += "/>";
|
|
572
|
+
this.lines.push(tag);
|
|
573
|
+
} else {
|
|
574
|
+
tag += ">";
|
|
575
|
+
this.lines.push(tag);
|
|
576
|
+
this.indentLevel++;
|
|
577
|
+
}
|
|
578
|
+
}
|
|
579
|
+
/**
|
|
580
|
+
* Writes an end element tag.
|
|
581
|
+
* @param name - The element name.
|
|
582
|
+
*/
|
|
583
|
+
writeEndElement(name) {
|
|
584
|
+
this.indentLevel--;
|
|
585
|
+
const indent = this.indentString.repeat(this.indentLevel);
|
|
586
|
+
this.lines.push(`${indent}</${name}>`);
|
|
587
|
+
}
|
|
588
|
+
/**
|
|
589
|
+
* Writes an element with text content.
|
|
590
|
+
* @param name - The element name.
|
|
591
|
+
* @param attributes - Optional attributes object.
|
|
592
|
+
* @param text - The text content.
|
|
593
|
+
*/
|
|
594
|
+
writeElementWithText(name, attributes, text) {
|
|
595
|
+
let tag = `${this.indentString.repeat(this.indentLevel)}<${name}`;
|
|
596
|
+
if (attributes) for (const [key, value] of Object.entries(attributes)) {
|
|
597
|
+
const encodedValue = encodeControlChars(escapeXml(value));
|
|
598
|
+
tag += ` ${key}="${encodedValue}"`;
|
|
599
|
+
}
|
|
600
|
+
const encodedText = encodeControlChars(escapeXml(text));
|
|
601
|
+
tag += `>${encodedText}</${name}>`;
|
|
602
|
+
this.lines.push(tag);
|
|
603
|
+
}
|
|
604
|
+
/**
|
|
605
|
+
* Returns the generated XML string.
|
|
606
|
+
* @returns The complete XML string with line breaks.
|
|
607
|
+
*/
|
|
608
|
+
toString() {
|
|
609
|
+
return this.lines.join("\n") + "\n";
|
|
610
|
+
}
|
|
367
611
|
};
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
612
|
+
/**
|
|
613
|
+
* Parses XML string into an XML node structure.
|
|
614
|
+
* This is a lightweight parser optimized for X-API XML structure.
|
|
615
|
+
*
|
|
616
|
+
* @param xml - The XML string to parse.
|
|
617
|
+
* @returns An array of parsed XML nodes.
|
|
618
|
+
*/
|
|
619
|
+
function parseXml(xml) {
|
|
620
|
+
if (!xml || xml.trim() === "") return [];
|
|
621
|
+
return new XapiXmlParser(xml).parse();
|
|
622
|
+
}
|
|
623
|
+
/**
|
|
624
|
+
* A lightweight XML parser optimized for X-API structure.
|
|
625
|
+
*/
|
|
626
|
+
var XapiXmlParser = class {
|
|
627
|
+
xml;
|
|
628
|
+
pos = 0;
|
|
629
|
+
length;
|
|
630
|
+
constructor(xml) {
|
|
631
|
+
this.xml = xml;
|
|
632
|
+
this.length = xml.length;
|
|
633
|
+
}
|
|
634
|
+
parse() {
|
|
635
|
+
const nodes = [];
|
|
636
|
+
while (this.pos < this.length) {
|
|
637
|
+
this.skipWhitespace();
|
|
638
|
+
if (this.pos >= this.length) break;
|
|
639
|
+
if (this.peek(5) === "<?xml") {
|
|
640
|
+
this.skipUntil("?>");
|
|
641
|
+
this.pos += 2;
|
|
642
|
+
continue;
|
|
643
|
+
}
|
|
644
|
+
if (this.peek(4) === "<!--") {
|
|
645
|
+
this.skipUntil("-->");
|
|
646
|
+
this.pos += 3;
|
|
647
|
+
continue;
|
|
648
|
+
}
|
|
649
|
+
if (this.current() === "<") {
|
|
650
|
+
const node = this.parseElement();
|
|
651
|
+
if (node) nodes.push(node);
|
|
652
|
+
} else this.pos++;
|
|
653
|
+
}
|
|
654
|
+
return nodes;
|
|
655
|
+
}
|
|
656
|
+
parseElement() {
|
|
657
|
+
if (this.current() !== "<") return null;
|
|
658
|
+
this.pos++;
|
|
659
|
+
if (this.current() === "/") return null;
|
|
660
|
+
const tagName = this.parseTagName();
|
|
661
|
+
if (!tagName) return null;
|
|
662
|
+
const node = { tagName };
|
|
663
|
+
const attributes = this.parseAttributes();
|
|
664
|
+
if (attributes && Object.keys(attributes).length > 0) node.attributes = attributes;
|
|
665
|
+
this.skipWhitespace();
|
|
666
|
+
if (this.peek(2) === "/>") {
|
|
667
|
+
this.pos += 2;
|
|
668
|
+
return node;
|
|
669
|
+
}
|
|
670
|
+
if (this.current() === ">") this.pos++;
|
|
671
|
+
const children = [];
|
|
672
|
+
let textContent = "";
|
|
673
|
+
while (this.pos < this.length) {
|
|
674
|
+
if (this.peek(9) === "<![CDATA[") {
|
|
675
|
+
const cdataText = this.parseCDATA();
|
|
676
|
+
if (cdataText !== null) textContent += cdataText;
|
|
677
|
+
continue;
|
|
678
|
+
}
|
|
679
|
+
if (this.peek(2) === "</") {
|
|
680
|
+
if (textContent) children.push(textContent);
|
|
681
|
+
this.pos += 2;
|
|
682
|
+
this.skipUntil(">");
|
|
683
|
+
this.pos++;
|
|
684
|
+
break;
|
|
685
|
+
}
|
|
686
|
+
if (this.current() === "<") {
|
|
687
|
+
if (textContent.trim()) {
|
|
688
|
+
children.push(textContent);
|
|
689
|
+
textContent = "";
|
|
690
|
+
}
|
|
691
|
+
const child = this.parseElement();
|
|
692
|
+
if (child) children.push(child);
|
|
693
|
+
} else {
|
|
694
|
+
textContent += this.current();
|
|
695
|
+
this.pos++;
|
|
696
|
+
}
|
|
697
|
+
}
|
|
698
|
+
if (children.length > 0) node.children = children;
|
|
699
|
+
return node;
|
|
700
|
+
}
|
|
701
|
+
parseTagName() {
|
|
702
|
+
let name = "";
|
|
703
|
+
while (this.pos < this.length) {
|
|
704
|
+
const ch = this.current();
|
|
705
|
+
if (ch === " " || ch === " " || ch === "\n" || ch === "\r" || ch === ">" || ch === "/") break;
|
|
706
|
+
name += ch;
|
|
707
|
+
this.pos++;
|
|
708
|
+
}
|
|
709
|
+
return name;
|
|
710
|
+
}
|
|
711
|
+
parseAttributes() {
|
|
712
|
+
const attrs = {};
|
|
713
|
+
while (this.pos < this.length) {
|
|
714
|
+
this.skipWhitespace();
|
|
715
|
+
const ch = this.current();
|
|
716
|
+
if (ch === ">" || ch === "/" || this.peek(2) === "/>") break;
|
|
717
|
+
const attrName = this.parseAttributeName();
|
|
718
|
+
if (!attrName) break;
|
|
719
|
+
this.skipWhitespace();
|
|
720
|
+
if (this.current() === "=") this.pos++;
|
|
721
|
+
this.skipWhitespace();
|
|
722
|
+
attrs[attrName] = this.parseAttributeValue();
|
|
723
|
+
}
|
|
724
|
+
return Object.keys(attrs).length > 0 ? attrs : void 0;
|
|
725
|
+
}
|
|
726
|
+
parseAttributeName() {
|
|
727
|
+
let name = "";
|
|
728
|
+
while (this.pos < this.length) {
|
|
729
|
+
const ch = this.current();
|
|
730
|
+
if (ch === "=" || ch === " " || ch === " " || ch === "\n" || ch === "\r" || ch === ">" || ch === "/") break;
|
|
731
|
+
name += ch;
|
|
732
|
+
this.pos++;
|
|
733
|
+
}
|
|
734
|
+
return name;
|
|
735
|
+
}
|
|
736
|
+
parseAttributeValue() {
|
|
737
|
+
let value = "";
|
|
738
|
+
const quote = this.current();
|
|
739
|
+
if (quote !== "\"" && quote !== "'") {
|
|
740
|
+
while (this.pos < this.length) {
|
|
741
|
+
const ch = this.current();
|
|
742
|
+
if (ch === " " || ch === " " || ch === "\n" || ch === "\r" || ch === ">" || ch === "/") break;
|
|
743
|
+
value += ch;
|
|
744
|
+
this.pos++;
|
|
745
|
+
}
|
|
746
|
+
return value;
|
|
747
|
+
}
|
|
748
|
+
this.pos++;
|
|
749
|
+
while (this.pos < this.length) {
|
|
750
|
+
const ch = this.current();
|
|
751
|
+
if (ch === quote) {
|
|
752
|
+
this.pos++;
|
|
753
|
+
break;
|
|
754
|
+
}
|
|
755
|
+
value += ch;
|
|
756
|
+
this.pos++;
|
|
757
|
+
}
|
|
758
|
+
return value;
|
|
759
|
+
}
|
|
760
|
+
parseCDATA() {
|
|
761
|
+
if (this.peek(9) !== "<![CDATA[") return null;
|
|
762
|
+
this.pos += 9;
|
|
763
|
+
let content = "";
|
|
764
|
+
while (this.pos < this.length) {
|
|
765
|
+
if (this.peek(3) === "]]>") {
|
|
766
|
+
this.pos += 3;
|
|
767
|
+
break;
|
|
768
|
+
}
|
|
769
|
+
content += this.current();
|
|
770
|
+
this.pos++;
|
|
771
|
+
}
|
|
772
|
+
return content;
|
|
773
|
+
}
|
|
774
|
+
skipWhitespace() {
|
|
775
|
+
while (this.pos < this.length) {
|
|
776
|
+
const ch = this.current();
|
|
777
|
+
if (ch !== " " && ch !== " " && ch !== "\n" && ch !== "\r") break;
|
|
778
|
+
this.pos++;
|
|
779
|
+
}
|
|
780
|
+
}
|
|
781
|
+
skipUntil(target) {
|
|
782
|
+
while (this.pos < this.length) {
|
|
783
|
+
if (this.peek(target.length) === target) break;
|
|
784
|
+
this.pos++;
|
|
785
|
+
}
|
|
786
|
+
}
|
|
787
|
+
current() {
|
|
788
|
+
return this.xml[this.pos];
|
|
789
|
+
}
|
|
790
|
+
peek(length) {
|
|
791
|
+
return this.xml.substring(this.pos, this.pos + length);
|
|
792
|
+
}
|
|
549
793
|
};
|
|
550
794
|
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
var _options = {
|
|
557
|
-
...defaultOptions
|
|
795
|
+
//#endregion
|
|
796
|
+
//#region src/handler.ts
|
|
797
|
+
let _options = {
|
|
798
|
+
xapiVersion: NexaVersion,
|
|
799
|
+
parseToTypes: true
|
|
558
800
|
};
|
|
801
|
+
/**
|
|
802
|
+
* Initializes the X-API handler with the provided options.
|
|
803
|
+
* @param options - The options to initialize the X-API handler.
|
|
804
|
+
* @returns void
|
|
805
|
+
*/
|
|
559
806
|
function initXapi(options) {
|
|
560
|
-
|
|
561
|
-
...options
|
|
562
|
-
};
|
|
807
|
+
_options = { ...options };
|
|
563
808
|
}
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
809
|
+
/**
|
|
810
|
+
* Parses an XML string into an XapiRoot object using custom parser.
|
|
811
|
+
* @param xml - The string containing the XML data.
|
|
812
|
+
* @returns An XapiRoot object.
|
|
813
|
+
*/
|
|
814
|
+
function parse(xml) {
|
|
815
|
+
const parsedXml = parseXml(xml);
|
|
816
|
+
const xapiRoot = new XapiRoot();
|
|
817
|
+
let rootElement;
|
|
818
|
+
for (let i = 0; i < parsedXml.length; i++) if (parsedXml[i].tagName === "Root") {
|
|
819
|
+
rootElement = parsedXml[i];
|
|
820
|
+
break;
|
|
821
|
+
}
|
|
822
|
+
if (rootElement === void 0) return xapiRoot;
|
|
823
|
+
const rootChildren = rootElement.children;
|
|
824
|
+
if (rootChildren && rootChildren.length > 0) for (let i = 0; i < rootChildren.length; i++) {
|
|
825
|
+
const child = rootChildren[i];
|
|
826
|
+
if (typeof child === "string") continue;
|
|
827
|
+
const tagName = child.tagName;
|
|
828
|
+
if (tagName === "Parameters") parseParameters(child, xapiRoot);
|
|
829
|
+
else if (tagName === "Dataset") {
|
|
830
|
+
if (!child.attributes || !child.attributes.id) throw new InvalidXmlError("Dataset element must have an 'id' attribute");
|
|
831
|
+
const datasetId = child.attributes.id;
|
|
832
|
+
const dataset = new Dataset(datasetId);
|
|
833
|
+
xapiRoot.addDataset(dataset);
|
|
834
|
+
const datasetChildren = child.children;
|
|
835
|
+
let columnInfoElement;
|
|
836
|
+
let rowsElement;
|
|
837
|
+
if (datasetChildren) for (let j = 0; j < datasetChildren.length; j++) {
|
|
838
|
+
const datasetChild = datasetChildren[j];
|
|
839
|
+
if (typeof datasetChild === "string") continue;
|
|
840
|
+
const childTagName = datasetChild.tagName;
|
|
841
|
+
if (childTagName === "ColumnInfo") columnInfoElement = datasetChild;
|
|
842
|
+
else if (childTagName === "Rows") rowsElement = datasetChild;
|
|
843
|
+
if (columnInfoElement && rowsElement) break;
|
|
844
|
+
}
|
|
845
|
+
parseColumnInfo(columnInfoElement, dataset);
|
|
846
|
+
parseRows(rowsElement, dataset);
|
|
847
|
+
}
|
|
848
|
+
}
|
|
849
|
+
return xapiRoot;
|
|
590
850
|
}
|
|
591
851
|
function parseValue(value, type = "STRING") {
|
|
592
|
-
|
|
593
|
-
|
|
852
|
+
value = _unescapeXml(value);
|
|
853
|
+
return _options.parseToTypes ? convertToColumnType(value, type) : value;
|
|
594
854
|
}
|
|
595
855
|
function parseColumnInfo(columnInfoElement, dataset) {
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
856
|
+
if (!columnInfoElement || typeof columnInfoElement === "string") throw new InvalidXmlError("ColumnInfo element is missing in the dataset");
|
|
857
|
+
const children = columnInfoElement.children;
|
|
858
|
+
if (!children) return;
|
|
859
|
+
for (let i = 0; i < children.length; i++) {
|
|
860
|
+
const colInfo = children[i];
|
|
861
|
+
if (typeof colInfo !== "string") {
|
|
862
|
+
const tagName = colInfo.tagName;
|
|
863
|
+
if (tagName === "ConstColumn") {
|
|
864
|
+
const attrs = colInfo.attributes;
|
|
865
|
+
const sizeStr = attrs?.size;
|
|
866
|
+
dataset.addConstColumn({
|
|
867
|
+
id: attrs?.id,
|
|
868
|
+
size: sizeStr ? parseInt(sizeStr, 10) : 0,
|
|
869
|
+
type: attrs?.type || "STRING",
|
|
870
|
+
value: parseValue(attrs?.value, attrs?.type)
|
|
871
|
+
});
|
|
872
|
+
} else if (tagName === "Column") {
|
|
873
|
+
const attrs = colInfo.attributes;
|
|
874
|
+
const sizeStr = attrs?.size;
|
|
875
|
+
dataset.addColumn({
|
|
876
|
+
id: attrs?.id,
|
|
877
|
+
size: sizeStr ? parseInt(sizeStr, 10) : 0,
|
|
878
|
+
type: attrs?.type || "STRING"
|
|
879
|
+
});
|
|
880
|
+
}
|
|
881
|
+
}
|
|
882
|
+
}
|
|
613
883
|
}
|
|
614
884
|
function parseRows(rowsElement, dataset) {
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
885
|
+
if (typeof rowsElement === "string") return;
|
|
886
|
+
const rows = rowsElement?.children;
|
|
887
|
+
if (!rows) return;
|
|
888
|
+
const datasetRows = dataset.rows;
|
|
889
|
+
for (let i = 0; i < rows.length; i++) {
|
|
890
|
+
const r = rows[i];
|
|
891
|
+
if (typeof r !== "string") {
|
|
892
|
+
const tagName = r.tagName;
|
|
893
|
+
if (tagName === "Row") {
|
|
894
|
+
const currentRow = datasetRows[dataset.newRow()];
|
|
895
|
+
currentRow.type = r.attributes?.type || void 0;
|
|
896
|
+
const cols = r.children;
|
|
897
|
+
if (cols) for (let j = 0; j < cols.length; j++) {
|
|
898
|
+
const col = cols[j];
|
|
899
|
+
if (typeof col !== "string") {
|
|
900
|
+
const colTagName = col.tagName;
|
|
901
|
+
if (colTagName === "Col") {
|
|
902
|
+
const colId = col.attributes?.id;
|
|
903
|
+
const value = col.children?.[0];
|
|
904
|
+
const columnInfo = dataset.getColumnInfo(colId);
|
|
905
|
+
if (!columnInfo) throw new InvalidXmlError(`Column with id ${colId} not found in dataset ${dataset.id}`);
|
|
906
|
+
const castedValue = parseValue(value, columnInfo.type);
|
|
907
|
+
currentRow.cols.push({
|
|
908
|
+
id: colId,
|
|
909
|
+
value: castedValue
|
|
910
|
+
});
|
|
911
|
+
} else if (colTagName === "OrgRow") {
|
|
912
|
+
const orgRow = [];
|
|
913
|
+
currentRow.orgRow = orgRow;
|
|
914
|
+
const orgCols = col.children;
|
|
915
|
+
if (orgCols) for (let k = 0; k < orgCols.length; k++) {
|
|
916
|
+
const orgCol = orgCols[k];
|
|
917
|
+
if (typeof orgCol !== "string" && orgCol.tagName === "Col") {
|
|
918
|
+
const colId = orgCol.attributes?.id;
|
|
919
|
+
const value = orgCol.children?.[0];
|
|
920
|
+
const castedValue = parseValue(value, dataset.getColumnInfo(colId).type);
|
|
921
|
+
orgRow.push({
|
|
922
|
+
id: colId,
|
|
923
|
+
value: castedValue
|
|
924
|
+
});
|
|
925
|
+
}
|
|
926
|
+
}
|
|
927
|
+
}
|
|
928
|
+
}
|
|
929
|
+
}
|
|
930
|
+
} else if (tagName === "Col") throw new InvalidXmlError("Row must be defined before Col");
|
|
931
|
+
else if (tagName === "OrgRow") throw new InvalidXmlError("Row must be defined before OrgRow");
|
|
932
|
+
}
|
|
933
|
+
}
|
|
648
934
|
}
|
|
649
935
|
function parseParameters(parametersElement, xapiRoot) {
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
936
|
+
if (typeof parametersElement === "string") return;
|
|
937
|
+
if (!parametersElement) return;
|
|
938
|
+
const children = parametersElement.children;
|
|
939
|
+
if (!children) return;
|
|
940
|
+
for (let i = 0; i < children.length; i++) {
|
|
941
|
+
const p = children[i];
|
|
942
|
+
if (typeof p !== "string" && p.tagName === "Parameter") {
|
|
943
|
+
const attrs = p.attributes;
|
|
944
|
+
const id = attrs?.id;
|
|
945
|
+
const type = attrs?.type || "STRING";
|
|
946
|
+
const value = p.children?.[0];
|
|
947
|
+
xapiRoot.addParameter({
|
|
948
|
+
id,
|
|
949
|
+
type,
|
|
950
|
+
value: parseValue(value, type)
|
|
951
|
+
});
|
|
952
|
+
}
|
|
953
|
+
}
|
|
663
954
|
}
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
955
|
+
function write(root) {
|
|
956
|
+
const builder = new XmlStringBuilder();
|
|
957
|
+
builder.writeDeclaration("1.0", "UTF-8");
|
|
958
|
+
builder.writeStartElement("Root", {
|
|
959
|
+
xmlns: _options.xapiVersion?.xmlns || NexaVersion.xmlns,
|
|
960
|
+
version: _options.xapiVersion?.version || NexaVersion.version
|
|
961
|
+
});
|
|
962
|
+
if (root.parameterSize() > 0) writeParameters(builder, root.getParameters());
|
|
963
|
+
if (root.datasetSize() > 0) {
|
|
964
|
+
builder.writeStartElement("Datasets");
|
|
965
|
+
for (const dataset of root.getDatasets()) writeDataset(builder, dataset);
|
|
966
|
+
builder.writeEndElement("Datasets");
|
|
967
|
+
}
|
|
968
|
+
builder.writeEndElement("Root");
|
|
969
|
+
return builder.toString();
|
|
668
970
|
}
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
});
|
|
684
|
-
if (root.parameterSize() > 0) {
|
|
685
|
-
await writeParameters(writer, root.iterParameters());
|
|
686
|
-
}
|
|
687
|
-
if (root.datasetSize() > 0) {
|
|
688
|
-
await writer.writeStartElement("Datasets");
|
|
689
|
-
for (const dataset of root.iterDatasets()) {
|
|
690
|
-
await writeDataset(writer, dataset);
|
|
691
|
-
}
|
|
692
|
-
await writer.writeEndElement();
|
|
693
|
-
}
|
|
694
|
-
await writer.writeEndElement();
|
|
971
|
+
function writeParameters(builder, parameters) {
|
|
972
|
+
if (parameters) {
|
|
973
|
+
builder.writeStartElement("Parameters");
|
|
974
|
+
for (const parameter of parameters) {
|
|
975
|
+
const attrs = { id: parameter.id };
|
|
976
|
+
if (parameter.type !== void 0) attrs.type = parameter.type;
|
|
977
|
+
if (parameter.value !== void 0) if (typeof parameter.value === "string") attrs.value = parameter.value;
|
|
978
|
+
else if (parameter.value instanceof Date) attrs.value = dateToString(parameter.value, parameter.type);
|
|
979
|
+
else if (parameter.value instanceof Uint8Array) attrs.value = uint8ArrayToBase64(parameter.value);
|
|
980
|
+
else attrs.value = String(parameter.value);
|
|
981
|
+
builder.writeStartElement("Parameter", attrs, true);
|
|
982
|
+
}
|
|
983
|
+
builder.writeEndElement("Parameters");
|
|
984
|
+
}
|
|
695
985
|
}
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
986
|
+
function writeDataset(builder, dataset) {
|
|
987
|
+
builder.writeStartElement("Dataset", { id: dataset.id });
|
|
988
|
+
if (dataset.constColumnSize() > 0 || dataset.columnSize() > 0) {
|
|
989
|
+
builder.writeStartElement("ColumnInfo");
|
|
990
|
+
for (const constCol of dataset.getConstColumns()) builder.writeStartElement("ConstColumn", {
|
|
991
|
+
id: constCol.id,
|
|
992
|
+
size: String(constCol.size),
|
|
993
|
+
type: constCol.type,
|
|
994
|
+
value: constCol.value !== void 0 ? String(constCol.value) : ""
|
|
995
|
+
}, true);
|
|
996
|
+
for (const col of dataset.getColumns()) builder.writeStartElement("Column", {
|
|
997
|
+
id: col.id,
|
|
998
|
+
size: String(col.size),
|
|
999
|
+
type: col.type
|
|
1000
|
+
}, true);
|
|
1001
|
+
builder.writeEndElement("ColumnInfo");
|
|
1002
|
+
}
|
|
1003
|
+
builder.writeStartElement("Rows");
|
|
1004
|
+
for (const row of dataset.getRows()) {
|
|
1005
|
+
if (row.type) builder.writeStartElement("Row", { type: row.type });
|
|
1006
|
+
else builder.writeStartElement("Row");
|
|
1007
|
+
for (const col of row.cols) writeColumn(builder, dataset, col);
|
|
1008
|
+
if (row.orgRow && row.orgRow.length > 0) {
|
|
1009
|
+
builder.writeStartElement("OrgRow");
|
|
1010
|
+
for (const orgCol of row.orgRow) writeColumn(builder, dataset, orgCol);
|
|
1011
|
+
builder.writeEndElement("OrgRow");
|
|
1012
|
+
}
|
|
1013
|
+
builder.writeEndElement("Row");
|
|
1014
|
+
}
|
|
1015
|
+
builder.writeEndElement("Rows");
|
|
1016
|
+
builder.writeEndElement("Dataset");
|
|
719
1017
|
}
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
await writer.writeStartElement("ConstColumn", {
|
|
726
|
-
attributes: {
|
|
727
|
-
id: constCol.id,
|
|
728
|
-
size: String(constCol.size),
|
|
729
|
-
type: constCol.type,
|
|
730
|
-
value: constCol.value !== void 0 ? String(constCol.value) : ""
|
|
731
|
-
},
|
|
732
|
-
selfClosing: true
|
|
733
|
-
});
|
|
734
|
-
}
|
|
735
|
-
for (const col of dataset.iterColumns()) {
|
|
736
|
-
await writer.writeStartElement("Column", {
|
|
737
|
-
attributes: {
|
|
738
|
-
id: col.id,
|
|
739
|
-
size: String(col.size),
|
|
740
|
-
type: col.type
|
|
741
|
-
},
|
|
742
|
-
selfClosing: true
|
|
743
|
-
});
|
|
744
|
-
}
|
|
745
|
-
await writer.writeEndElement();
|
|
746
|
-
}
|
|
747
|
-
await writer.writeStartElement("Rows");
|
|
748
|
-
for (const row of dataset.iterRows()) {
|
|
749
|
-
if (row.type) {
|
|
750
|
-
await writer.writeStartElement("Row", { attributes: { type: row.type } });
|
|
751
|
-
} else {
|
|
752
|
-
await writer.writeStartElement("Row");
|
|
753
|
-
}
|
|
754
|
-
for (const col of row.cols) {
|
|
755
|
-
await writeColumn(writer, dataset, col);
|
|
756
|
-
}
|
|
757
|
-
if (row.orgRow && row.orgRow.length > 0) {
|
|
758
|
-
await writer.writeStartElement("OrgRow");
|
|
759
|
-
for (const orgCol of row.orgRow) {
|
|
760
|
-
await writeColumn(writer, dataset, orgCol);
|
|
761
|
-
}
|
|
762
|
-
await writer.writeEndElement();
|
|
763
|
-
}
|
|
764
|
-
await writer.writeEndElement();
|
|
765
|
-
}
|
|
766
|
-
await writer.writeEndElement();
|
|
767
|
-
await writer.writeEndElement();
|
|
1018
|
+
function writeColumn(builder, dataset, col) {
|
|
1019
|
+
if (col.value !== void 0 && col.value !== null) {
|
|
1020
|
+
const colInfo = dataset.getColumnInfo(col.id);
|
|
1021
|
+
builder.writeElementWithText("Col", { id: col.id }, convertToString(col.value, colInfo.type));
|
|
1022
|
+
} else builder.writeStartElement("Col", { id: col.id }, true);
|
|
768
1023
|
}
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
parse,
|
|
799
|
-
rowType,
|
|
800
|
-
stringToDate,
|
|
801
|
-
stringToReadableStream,
|
|
802
|
-
uint8ArrayToBase64,
|
|
803
|
-
write,
|
|
804
|
-
writeString
|
|
805
|
-
});
|
|
1024
|
+
|
|
1025
|
+
//#endregion
|
|
1026
|
+
exports.ColumnTypeError = ColumnTypeError;
|
|
1027
|
+
exports.Dataset = Dataset;
|
|
1028
|
+
exports.InvalidXmlError = InvalidXmlError;
|
|
1029
|
+
exports.NexaVersion = NexaVersion;
|
|
1030
|
+
exports.StringWritableStream = StringWritableStream;
|
|
1031
|
+
exports.XapiRoot = XapiRoot;
|
|
1032
|
+
exports.XmlStringBuilder = XmlStringBuilder;
|
|
1033
|
+
exports.XplatformVersion = XplatformVersion;
|
|
1034
|
+
exports._unescapeXml = _unescapeXml;
|
|
1035
|
+
exports.arrayBufferToString = arrayBufferToString;
|
|
1036
|
+
exports.base64ToUint8Array = base64ToUint8Array;
|
|
1037
|
+
exports.columnType = columnType;
|
|
1038
|
+
exports.convertToColumnType = convertToColumnType;
|
|
1039
|
+
exports.convertToString = convertToString;
|
|
1040
|
+
exports.dateToString = dateToString;
|
|
1041
|
+
exports.encodeControlChars = encodeControlChars;
|
|
1042
|
+
exports.escapeXml = escapeXml;
|
|
1043
|
+
exports.initXapi = initXapi;
|
|
1044
|
+
exports.isXapiRoot = isXapiRoot;
|
|
1045
|
+
exports.makeParseEntities = makeParseEntities;
|
|
1046
|
+
exports.parse = parse;
|
|
1047
|
+
exports.parseXml = parseXml;
|
|
1048
|
+
exports.rowType = rowType;
|
|
1049
|
+
exports.stringToDate = stringToDate;
|
|
1050
|
+
exports.stringToReadableStream = stringToReadableStream;
|
|
1051
|
+
exports.uint8ArrayToBase64 = uint8ArrayToBase64;
|
|
1052
|
+
exports.write = write;
|