@xapi-js/core 1.5.0 → 1.6.1

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 CHANGED
@@ -14,11 +14,16 @@ const rowType = [
14
14
  const columnType = [
15
15
  "STRING",
16
16
  "INT",
17
+ "LONG",
17
18
  "FLOAT",
19
+ "DOUBLE",
18
20
  "DECIMAL",
19
21
  "BIGDECIMAL",
22
+ "BIG_DECIMAL",
23
+ "BOOLEAN",
20
24
  "DATE",
21
25
  "DATETIME",
26
+ "DATE_TIME",
22
27
  "TIME",
23
28
  "BLOB"
24
29
  ];
@@ -368,8 +373,23 @@ function uint8ArrayToBase64(uint8Array) {
368
373
  * @param value - The string to convert.
369
374
  * @returns A Date object if the string is a valid date/time, otherwise undefined.
370
375
  */
371
- function stringToDate(value) {
376
+ function stringToDate(value, type) {
372
377
  if (!value) return void 0;
378
+ const normalizedType = type ? normalizeColumnType(type) : void 0;
379
+ if (normalizedType === "TIME") {
380
+ if (value.length !== 6 && value.length !== 9) return void 0;
381
+ const hours = parseInt(value.substring(0, 2), 10);
382
+ const minutes = parseInt(value.substring(2, 4), 10);
383
+ const seconds = parseInt(value.substring(4, 6), 10);
384
+ const milliseconds = value.length === 9 ? parseInt(value.substring(6, 9), 10) : 0;
385
+ if ([
386
+ hours,
387
+ minutes,
388
+ seconds,
389
+ milliseconds
390
+ ].some(Number.isNaN) || hours > 23 || minutes > 59 || seconds > 59 || milliseconds > 999) return void 0;
391
+ return new Date(1970, 0, 1, hours, minutes, seconds, milliseconds);
392
+ }
373
393
  let year;
374
394
  let month;
375
395
  let day;
@@ -377,7 +397,7 @@ function stringToDate(value) {
377
397
  let minutes = 0;
378
398
  let seconds = 0;
379
399
  let milliseconds = 0;
380
- if (value.length < 6 || value.length > 16) return;
400
+ if (value.length < 6 || value.length > (normalizedType ? 17 : 16)) return;
381
401
  if (value.length >= 8) {
382
402
  year = parseInt(value.substring(0, 4), 10);
383
403
  month = parseInt(value.substring(4, 6), 10) - 1;
@@ -396,7 +416,10 @@ function stringToDate(value) {
396
416
  minutes = parseInt(value.substring(10, 12), 10);
397
417
  seconds = parseInt(value.substring(12, 14), 10);
398
418
  }
399
- if (value.length === 16) milliseconds = parseInt(value.substring(14, 16), 10);
419
+ if (value.length === 16 || value.length === 17) {
420
+ milliseconds = parseInt(value.substring(14, value.length), 10);
421
+ if (value.length === 16 && normalizedType) milliseconds *= 10;
422
+ }
400
423
  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;
401
424
  const date = new Date(year, month, day, hours, minutes, seconds, milliseconds);
402
425
  if (isNaN(date.getTime())) return;
@@ -415,10 +438,10 @@ function dateToString(date, type) {
415
438
  const hours = date.getHours().toString().padStart(2, "0");
416
439
  const minutes = date.getMinutes().toString().padStart(2, "0");
417
440
  const seconds = date.getSeconds().toString().padStart(2, "0");
418
- switch (type) {
441
+ switch (normalizeColumnType(type)) {
419
442
  case "DATE": return `${year}${month}${day}`;
420
- case "DATETIME": return `${year}${month}${day}${hours}${minutes}${seconds}`;
421
- case "TIME": return `${hours}${minutes}${seconds}`;
443
+ case "DATETIME": return `${year}${month}${day}${hours}${minutes}${seconds}${date.getMilliseconds() ? date.getMilliseconds().toString().padStart(3, "0") : ""}`;
444
+ case "TIME": return `${hours}${minutes}${seconds}${date.getMilliseconds() ? date.getMilliseconds().toString().padStart(3, "0") : ""}`;
422
445
  default: return "";
423
446
  }
424
447
  }
@@ -466,12 +489,16 @@ function stringToReadableStream(str) {
466
489
  * @throws {ColumnTypeError} if the column type is unsupported.
467
490
  */
468
491
  function convertToColumnType(value, type) {
469
- switch (type) {
492
+ const normalizedType = normalizeColumnType(type);
493
+ switch (normalizeColumnType(type)) {
470
494
  case "INT":
471
495
  const intValue = parseInt(value, 10);
472
496
  return isNaN(intValue) ? value : intValue;
473
497
  case "FLOAT":
498
+ case "DOUBLE":
499
+ case "LONG":
474
500
  case "BIGDECIMAL":
501
+ case "BIG_DECIMAL":
475
502
  const floatValue = parseFloat(value);
476
503
  return isNaN(floatValue) ? value : floatValue;
477
504
  case "DECIMAL":
@@ -479,14 +506,29 @@ function convertToColumnType(value, type) {
479
506
  return isNaN(decimalValue) ? value : decimalValue;
480
507
  case "DATE":
481
508
  case "DATETIME":
482
- case "TIME": return stringToDate(value) || value;
509
+ case "DATE_TIME":
510
+ case "TIME": return stringToDate(value, normalizedType) || value;
511
+ case "BOOLEAN":
512
+ if (value === "true" || value === "1" || value === 1 || value === true) return true;
513
+ if (value === "false" || value === "0" || value === 0 || value === false) return false;
514
+ return value;
483
515
  case "BLOB": try {
484
516
  return base64ToUint8Array(value);
485
517
  } catch {
486
518
  return value;
487
519
  }
488
520
  case "STRING": return value;
489
- default: throw new ColumnTypeError(`Unsupported column type: ${type}`);
521
+ default: throw new ColumnTypeError(`Unsupported column type: ${normalizedType}`);
522
+ }
523
+ }
524
+ /** Normalizes X-API/Java type spellings to the names used by Dataset XML. */
525
+ function normalizeColumnType(type) {
526
+ const normalized = type?.replace(/[- ]/g, "_").toUpperCase();
527
+ switch (normalized) {
528
+ case "DATE_TIME": return "DATETIME";
529
+ case "BIG_DECIMAL": return "BIGDECIMAL";
530
+ case "BOOL": return "BOOLEAN";
531
+ default: return normalized || "STRING";
490
532
  }
491
533
  }
492
534
  /**
@@ -498,12 +540,17 @@ function convertToColumnType(value, type) {
498
540
  function convertToString(value, type) {
499
541
  switch (type) {
500
542
  case "INT":
543
+ case "LONG":
501
544
  case "BIGDECIMAL":
545
+ case "BIG_DECIMAL":
502
546
  case "FLOAT":
547
+ case "DOUBLE":
503
548
  case "DECIMAL": return String(value);
549
+ case "BOOLEAN": return value ? "true" : "false";
504
550
  case "DATE":
505
551
  case "DATETIME":
506
- case "TIME": return dateToString(value, type);
552
+ case "DATE_TIME":
553
+ case "TIME": return dateToString(value, normalizeColumnType(type));
507
554
  case "BLOB": return uint8ArrayToBase64(value);
508
555
  case "STRING": return String(value);
509
556
  default: return String(value);
@@ -928,8 +975,9 @@ function parseColumnInfo(columnInfoElement, dataset) {
928
975
  dataset.addConstColumn({
929
976
  id: attrs?.id,
930
977
  size: sizeStr ? parseInt(sizeStr, 10) : 0,
931
- type: attrs?.type || "STRING",
932
- value: parseValue(attrs?.value, attrs?.type)
978
+ type: normalizeColumnType(attrs?.type),
979
+ value: parseValue(attrs?.value, attrs?.type),
980
+ rawValue: attrs?.value
933
981
  });
934
982
  } else if (tagName === "Column") {
935
983
  const attrs = colInfo.attributes;
@@ -937,7 +985,7 @@ function parseColumnInfo(columnInfoElement, dataset) {
937
985
  dataset.addColumn({
938
986
  id: attrs?.id,
939
987
  size: sizeStr ? parseInt(sizeStr, 10) : 0,
940
- type: attrs?.type || "STRING"
988
+ type: normalizeColumnType(attrs?.type)
941
989
  });
942
990
  }
943
991
  }
@@ -967,7 +1015,8 @@ function parseRows(rowsElement, dataset) {
967
1015
  const castedValue = parseValue(value, columnInfo.type);
968
1016
  currentRow.cols.push({
969
1017
  id: colId,
970
- value: castedValue
1018
+ value: castedValue,
1019
+ rawValue: value
971
1020
  });
972
1021
  } else if (colTagName === "OrgRow") {
973
1022
  const orgRow = [];
@@ -981,7 +1030,8 @@ function parseRows(rowsElement, dataset) {
981
1030
  const castedValue = parseValue(value, dataset.getColumnInfo(colId).type);
982
1031
  orgRow.push({
983
1032
  id: colId,
984
- value: castedValue
1033
+ value: castedValue,
1034
+ rawValue: value
985
1035
  });
986
1036
  }
987
1037
  }
@@ -1005,8 +1055,9 @@ function parseParameters(parametersElement, xapiRoot) {
1005
1055
  const value = p.children?.[0] ?? attrs?.value;
1006
1056
  xapiRoot.addParameter({
1007
1057
  id,
1008
- type,
1009
- value: parseValue(value, type)
1058
+ type: normalizeColumnType(type),
1059
+ value: parseValue(value, type),
1060
+ rawValue: value
1010
1061
  });
1011
1062
  }
1012
1063
  }
@@ -1031,7 +1082,7 @@ function writeParameters(builder, parameters) {
1031
1082
  builder.writeStartElement("Parameters");
1032
1083
  for (const parameter of parameters) {
1033
1084
  const attrs = { id: parameter.id };
1034
- if (parameter.type !== void 0) attrs.type = parameter.type;
1085
+ if (parameter.type !== void 0) attrs.type = normalizeColumnType(parameter.type);
1035
1086
  if (parameter.value !== void 0) if (typeof parameter.value === "string") attrs.value = parameter.value;
1036
1087
  else if (parameter.value instanceof Date) attrs.value = dateToString(parameter.value, parameter.type);
1037
1088
  else if (parameter.value instanceof Uint8Array) attrs.value = uint8ArrayToBase64(parameter.value);
@@ -1047,13 +1098,13 @@ function writeDataset(builder, dataset) {
1047
1098
  for (const constCol of dataset.getConstColumns()) builder.writeStartElement("ConstColumn", {
1048
1099
  id: constCol.id,
1049
1100
  size: String(constCol.size),
1050
- type: constCol.type,
1101
+ type: normalizeColumnType(constCol.type),
1051
1102
  value: constCol.value !== void 0 ? String(constCol.value) : ""
1052
1103
  }, true);
1053
1104
  for (const col of dataset.getColumns()) builder.writeStartElement("Column", {
1054
1105
  id: col.id,
1055
1106
  size: String(col.size),
1056
- type: col.type
1107
+ type: normalizeColumnType(col.type)
1057
1108
  }, true);
1058
1109
  builder.writeEndElement("ColumnInfo");
1059
1110
  }
@@ -1080,14 +1131,30 @@ function writeColumn(builder, dataset, col) {
1080
1131
  }
1081
1132
  //#endregion
1082
1133
  //#region src/schema.ts
1134
+ const schemaCache = /* @__PURE__ */ new WeakMap();
1135
+ function compileSchema(schema) {
1136
+ const cached = schemaCache.get(schema);
1137
+ if (cached) return cached;
1138
+ const compiled = {
1139
+ parameters: new Map(Object.entries(schema.parameters)),
1140
+ datasets: new Map(Object.entries(schema.datasets).map(([id, dataset]) => [id, { columns: new Map(Object.entries(dataset.columns)) }]))
1141
+ };
1142
+ schemaCache.set(schema, compiled);
1143
+ return compiled;
1144
+ }
1083
1145
  const defaultSizes = {
1084
1146
  STRING: 256,
1085
1147
  INT: 10,
1148
+ LONG: 19,
1086
1149
  FLOAT: 20,
1150
+ DOUBLE: 20,
1087
1151
  DECIMAL: 20,
1088
1152
  BIGDECIMAL: 30,
1153
+ BIG_DECIMAL: 30,
1154
+ BOOLEAN: 5,
1089
1155
  DATE: 8,
1090
1156
  DATETIME: 17,
1157
+ DATE_TIME: 17,
1091
1158
  TIME: 6,
1092
1159
  BLOB: 1e3
1093
1160
  };
@@ -1121,11 +1188,16 @@ function defineOperation(definition) {
1121
1188
  const xapi = {
1122
1189
  string: (options) => column("STRING", options),
1123
1190
  int: (options) => column("INT", options),
1191
+ long: (options) => column("LONG", options),
1124
1192
  float: (options) => column("FLOAT", options),
1193
+ double: (options) => column("DOUBLE", options),
1125
1194
  decimal: (options) => column("DECIMAL", options),
1126
1195
  bigdecimal: (options) => column("BIGDECIMAL", options),
1196
+ bigDecimal: (options) => column("BIG_DECIMAL", options),
1197
+ boolean: (options) => column("BOOLEAN", options),
1127
1198
  date: (options) => column("DATE", options),
1128
1199
  datetime: (options) => column("DATETIME", options),
1200
+ dateTime: (options) => column("DATE_TIME", options),
1129
1201
  time: (options) => column("TIME", options),
1130
1202
  blob: (options) => column("BLOB", options),
1131
1203
  dataset: defineDataset,
@@ -1134,7 +1206,8 @@ const xapi = {
1134
1206
  };
1135
1207
  function encodeRoot(schema, value) {
1136
1208
  const root = new XapiRoot();
1137
- for (const [id, parameterSchema] of Object.entries(schema.parameters)) {
1209
+ const compiled = compileSchema(schema);
1210
+ for (const [id, parameterSchema] of compiled.parameters) {
1138
1211
  const parameterValue = value.parameters[id];
1139
1212
  if (parameterValue !== void 0 || !parameterSchema.optional) root.addParameter({
1140
1213
  id,
@@ -1142,30 +1215,39 @@ function encodeRoot(schema, value) {
1142
1215
  value: parameterValue
1143
1216
  });
1144
1217
  }
1145
- for (const [datasetId, datasetSchema] of Object.entries(schema.datasets)) {
1218
+ for (const [datasetId, datasetDefinition] of compiled.datasets) {
1146
1219
  const dataset = new Dataset(datasetId);
1147
- for (const [id, columnSchema] of Object.entries(datasetSchema.columns)) dataset.addColumn({
1220
+ for (const [id, columnSchema] of datasetDefinition.columns) dataset.addColumn({
1148
1221
  id,
1149
1222
  type: columnSchema.type,
1150
1223
  size: columnSchema.size
1151
1224
  });
1152
1225
  const rows = value.datasets[datasetId];
1226
+ const columnIds = [...datasetDefinition.columns.keys()];
1153
1227
  for (const row of rows) {
1154
1228
  const rowIndex = dataset.newRow();
1155
- for (const id of Object.keys(datasetSchema.columns)) dataset.setColumn(rowIndex, id, row[id]);
1229
+ dataset.rows[rowIndex].type = row.$rowType;
1230
+ for (const id of columnIds) dataset.setColumn(rowIndex, id, row[id]);
1231
+ if (row.$orgRow) dataset.rows[rowIndex].orgRow = Object.entries(row.$orgRow).map(([id, value]) => ({
1232
+ id,
1233
+ value
1234
+ }));
1156
1235
  }
1157
1236
  root.addDataset(dataset);
1158
1237
  }
1159
1238
  return root;
1160
1239
  }
1161
1240
  function decodeRoot(schema, root) {
1241
+ const compiled = compileSchema(schema);
1162
1242
  const parameters = {};
1163
- for (const id of Object.keys(schema.parameters)) {
1164
- const value = root.getParameter(id)?.value;
1165
- if (value !== void 0) parameters[id] = value;
1243
+ for (const [id, parameterSchema] of compiled.parameters) {
1244
+ const parameter = root.getParameter(id);
1245
+ const value = parameter?.rawValue !== void 0 ? parameter.rawValue : parameter?.value;
1246
+ if (value !== void 0) parameters[id] = convertToColumnType(value, parameterSchema.type);
1166
1247
  }
1167
1248
  const datasets = {};
1168
- for (const [datasetId, datasetSchema] of Object.entries(schema.datasets)) {
1249
+ for (const [datasetId, datasetDefinition] of compiled.datasets) {
1250
+ const schemaColumns = datasetDefinition.columns;
1169
1251
  const dataset = root.getDataset(datasetId);
1170
1252
  if (!dataset) {
1171
1253
  datasets[datasetId] = [];
@@ -1174,7 +1256,20 @@ function decodeRoot(schema, root) {
1174
1256
  const constants = Object.fromEntries(dataset.getConstColumns().map(({ id, value }) => [id, value]));
1175
1257
  datasets[datasetId] = dataset.getRows().map((row) => {
1176
1258
  const value = { ...constants };
1177
- for (const column of row.cols) if (column.id in datasetSchema.columns) value[column.id] = column.value;
1259
+ for (const column of row.cols) {
1260
+ const columnSchema = schemaColumns.get(column.id);
1261
+ if (columnSchema) {
1262
+ const rawValue = column.rawValue !== void 0 ? column.rawValue : column.value;
1263
+ value[column.id] = rawValue === void 0 ? void 0 : convertToColumnType(rawValue, columnSchema.type);
1264
+ }
1265
+ }
1266
+ if (row.type) value.$rowType = row.type;
1267
+ if (row.orgRow) value.$orgRow = Object.fromEntries(row.orgRow.flatMap((column) => {
1268
+ const columnSchema = schemaColumns.get(column.id);
1269
+ if (!columnSchema) return [];
1270
+ const rawValue = column.rawValue !== void 0 ? column.rawValue : column.value;
1271
+ return [[column.id, rawValue === void 0 ? void 0 : convertToColumnType(rawValue, columnSchema.type)]];
1272
+ }));
1178
1273
  return value;
1179
1274
  });
1180
1275
  }
@@ -1184,6 +1279,138 @@ function decodeRoot(schema, root) {
1184
1279
  };
1185
1280
  }
1186
1281
  //#endregion
1282
+ //#region src/codec.ts
1283
+ const rowTypes = {
1284
+ N: void 0,
1285
+ I: "insert",
1286
+ U: "update",
1287
+ D: "delete",
1288
+ O: void 0
1289
+ };
1290
+ function sizeOf(size, type) {
1291
+ if (size !== void 0) return Number(size);
1292
+ return type === "STRING" ? 255 : 0;
1293
+ }
1294
+ function jsonValue(value, type) {
1295
+ if (value === null || value === void 0) return void 0;
1296
+ return convertToColumnType(typeof value === "string" ? value : String(value), normalizeColumnType(type));
1297
+ }
1298
+ function jsonRawValue(value) {
1299
+ return value === null || value === void 0 ? void 0 : String(value);
1300
+ }
1301
+ function jsonWireValue(value, type) {
1302
+ if (value === void 0) return void 0;
1303
+ if (value instanceof Date) return dateToString(value, type);
1304
+ if (value instanceof Uint8Array) return uint8ArrayToBase64(value);
1305
+ return value;
1306
+ }
1307
+ function columnsToObject(columns) {
1308
+ return Object.fromEntries(columns.map((column) => [column.id, column.value]));
1309
+ }
1310
+ function readRow(dataset, row) {
1311
+ const rowType = rowTypes[row._RowType_ ?? "N"];
1312
+ if (row._RowType_ === "O") {
1313
+ const previous = dataset.rows[dataset.rows.length - 1];
1314
+ if (previous?.type !== "update") return;
1315
+ previous.orgRow = dataset.getColumns().filter((column) => Object.prototype.hasOwnProperty.call(row, column.id)).map((column) => ({
1316
+ id: column.id,
1317
+ value: jsonValue(row[column.id], column.type),
1318
+ rawValue: jsonRawValue(row[column.id])
1319
+ }));
1320
+ return;
1321
+ }
1322
+ const index = dataset.newRow();
1323
+ dataset.rows[index].type = rowType;
1324
+ for (const column of dataset.getColumns()) if (Object.prototype.hasOwnProperty.call(row, column.id)) dataset.rows[index].cols.push({
1325
+ id: column.id,
1326
+ value: jsonValue(row[column.id], column.type),
1327
+ rawValue: jsonRawValue(row[column.id])
1328
+ });
1329
+ }
1330
+ function readJson(value) {
1331
+ const root = new XapiRoot();
1332
+ for (const parameter of value.Parameters ?? []) {
1333
+ const type = normalizeColumnType(parameter.type);
1334
+ root.addParameter({
1335
+ id: parameter.id,
1336
+ type,
1337
+ value: jsonValue(parameter.value, type),
1338
+ rawValue: jsonRawValue(parameter.value)
1339
+ });
1340
+ }
1341
+ for (const source of value.Datasets ?? []) {
1342
+ const dataset = new Dataset(source.id);
1343
+ for (const column of source.ColumnInfo.ConstColumn ?? []) {
1344
+ const type = normalizeColumnType(column.type);
1345
+ dataset.addConstColumn({
1346
+ id: column.id,
1347
+ type,
1348
+ size: sizeOf(column.size, type),
1349
+ value: jsonValue(column.value, type),
1350
+ rawValue: jsonRawValue(column.value)
1351
+ });
1352
+ }
1353
+ for (const column of source.ColumnInfo.Column) {
1354
+ const type = normalizeColumnType(column.type);
1355
+ dataset.addColumn({
1356
+ id: column.id,
1357
+ type,
1358
+ size: sizeOf(column.size, type)
1359
+ });
1360
+ }
1361
+ for (const row of source.Rows) readRow(dataset, row);
1362
+ root.addDataset(dataset);
1363
+ }
1364
+ return root;
1365
+ }
1366
+ function writeJson(root) {
1367
+ return {
1368
+ version: "1.0",
1369
+ ...root.parameterSize() ? { Parameters: root.getParameters().map((parameter) => ({
1370
+ id: parameter.id,
1371
+ ...parameter.type ? { type: parameter.type } : {},
1372
+ ...parameter.value !== void 0 ? { value: jsonWireValue(parameter.value, parameter.type ?? "STRING") } : {}
1373
+ })) } : {},
1374
+ ...root.datasetSize() ? { Datasets: root.getDatasets().map((dataset) => ({
1375
+ id: dataset.id,
1376
+ ColumnInfo: {
1377
+ ...dataset.constColumnSize() ? { ConstColumn: dataset.getConstColumns().map((column) => ({
1378
+ id: column.id,
1379
+ type: column.type,
1380
+ size: column.size,
1381
+ value: jsonWireValue(column.value, column.type)
1382
+ })) } : {},
1383
+ Column: dataset.getColumns().map((column) => ({
1384
+ id: column.id,
1385
+ type: column.type,
1386
+ size: column.size
1387
+ }))
1388
+ },
1389
+ Rows: dataset.getRows().flatMap((row) => {
1390
+ const current = {
1391
+ _RowType_: row.type === "insert" ? "I" : row.type === "update" ? "U" : row.type === "delete" ? "D" : "N",
1392
+ ...columnsToObject(row.cols)
1393
+ };
1394
+ if (!row.orgRow) return [current];
1395
+ return [current, {
1396
+ _RowType_: "O",
1397
+ ...columnsToObject(row.orgRow)
1398
+ }];
1399
+ })
1400
+ })) } : {}
1401
+ };
1402
+ }
1403
+ const nexacroJsonCodec = {
1404
+ serialize: writeJson,
1405
+ deserialize: readJson
1406
+ };
1407
+ function parseJson(value) {
1408
+ return nexacroJsonCodec.deserialize(JSON.parse(value));
1409
+ }
1410
+ function writeJsonString(root) {
1411
+ return JSON.stringify(nexacroJsonCodec.serialize(root));
1412
+ }
1413
+ //#endregion
1187
1414
  exports.ColumnTypeError = ColumnTypeError;
1188
1415
  exports.Dataset = Dataset;
1189
1416
  exports.InvalidXmlError = InvalidXmlError;
@@ -1209,11 +1436,15 @@ exports.escapeXml = escapeXml;
1209
1436
  exports.initXapi = initXapi;
1210
1437
  exports.isXapiRoot = isXapiRoot;
1211
1438
  exports.makeParseEntities = makeParseEntities;
1439
+ exports.nexacroJsonCodec = nexacroJsonCodec;
1440
+ exports.normalizeColumnType = normalizeColumnType;
1212
1441
  exports.parse = parse;
1442
+ exports.parseJson = parseJson;
1213
1443
  exports.parseXml = parseXml;
1214
1444
  exports.rowType = rowType;
1215
1445
  exports.stringToDate = stringToDate;
1216
1446
  exports.stringToReadableStream = stringToReadableStream;
1217
1447
  exports.uint8ArrayToBase64 = uint8ArrayToBase64;
1218
1448
  exports.write = write;
1449
+ exports.writeJsonString = writeJsonString;
1219
1450
  exports.xapi = xapi;
package/dist/index.d.cts CHANGED
@@ -2,7 +2,7 @@
2
2
  /**
3
3
  * Represents the possible data types for X-API values.
4
4
  */
5
- type XapiValueType = string | number | Uint8Array | Date | undefined;
5
+ type XapiValueType = string | number | boolean | Uint8Array | Date | undefined;
6
6
  /**
7
7
  * Represents a column within a row of an X-API dataset.
8
8
  */
@@ -11,6 +11,8 @@ interface Col {
11
11
  id: string;
12
12
  /** The value of the column. */
13
13
  value?: XapiValueType;
14
+ /** Original wire value. XML and SSV values are strings before schema conversion. */
15
+ rawValue?: string;
14
16
  }
15
17
  /**
16
18
  * Defines the possible types of rows in an X-API dataset (e.g., "insert", "update", "delete").
@@ -41,7 +43,7 @@ interface Rows {
41
43
  /**
42
44
  * Defines the possible data types for columns in an X-API dataset.
43
45
  */
44
- declare const columnType: readonly ["STRING", "INT", "FLOAT", "DECIMAL", "BIGDECIMAL", "DATE", "DATETIME", "TIME", "BLOB"];
46
+ declare const columnType: readonly ["STRING", "INT", "LONG", "FLOAT", "DOUBLE", "DECIMAL", "BIGDECIMAL", "BIG_DECIMAL", "BOOLEAN", "DATE", "DATETIME", "DATE_TIME", "TIME", "BLOB"];
45
47
  /**
46
48
  * Type representing the data type of a column.
47
49
  */
@@ -62,6 +64,7 @@ interface Column {
62
64
  */
63
65
  type ConstColumn = Column & {
64
66
  value: XapiValueType;
67
+ rawValue?: string;
65
68
  };
66
69
  /**
67
70
  * Represents the column information section of an X-API dataset.
@@ -82,6 +85,8 @@ interface Parameter {
82
85
  type?: ColumnType;
83
86
  /** The value of the parameter. */
84
87
  value?: XapiValueType;
88
+ /** Original wire value before conversion. */
89
+ rawValue?: string;
85
90
  }
86
91
  /**
87
92
  * Represents a collection of parameters in an X-API request/response.
@@ -366,14 +371,14 @@ declare function uint8ArrayToBase64(uint8Array: Uint8Array): string;
366
371
  * @param value - The string to convert.
367
372
  * @returns A Date object if the string is a valid date/time, otherwise undefined.
368
373
  */
369
- declare function stringToDate(value: string): Date | undefined;
374
+ declare function stringToDate(value: string, type?: ColumnType): Date | undefined;
370
375
  /**
371
376
  * Converts a Date object to a string representation based on the specified column type.
372
377
  * @param date - The Date object to convert.
373
378
  * @param type - The column type ("DATE", "DATETIME", or "TIME").
374
379
  * @returns A string representation of the date/time.
375
380
  */
376
- declare function dateToString(date: Date, type: Extract<ColumnType, "DATE" | "DATETIME" | "TIME">): string;
381
+ declare function dateToString(date: Date, type: Extract<ColumnType, "DATE" | "DATETIME" | "DATE_TIME" | "TIME">): string;
377
382
  /**
378
383
  * A WritableStream that collects all written Uint8Array chunks and provides them as a single string.
379
384
  */
@@ -400,6 +405,8 @@ declare function stringToReadableStream(str: string): ReadableStream<Uint8Array>
400
405
  * @throws {ColumnTypeError} if the column type is unsupported.
401
406
  */
402
407
  declare function convertToColumnType(value: XapiValueType, type: ColumnType): XapiValueType;
408
+ /** Normalizes X-API/Java type spellings to the names used by Dataset XML. */
409
+ declare function normalizeColumnType(type?: string): ColumnType;
403
410
  /**
404
411
  * Converts an XapiValueType to its string representation based on the specified ColumnType.
405
412
  * @param value - The value to convert.
@@ -473,11 +480,16 @@ declare function parseXml(xml: string): XmlNode[];
473
480
  type XapiTypeMap = {
474
481
  STRING: string;
475
482
  INT: number;
483
+ LONG: number;
476
484
  FLOAT: number;
485
+ DOUBLE: number;
477
486
  DECIMAL: number;
478
487
  BIGDECIMAL: number;
488
+ BIG_DECIMAL: number;
489
+ BOOLEAN: boolean;
479
490
  DATE: Date;
480
491
  DATETIME: Date;
492
+ DATE_TIME: Date;
481
493
  TIME: Date;
482
494
  BLOB: Uint8Array;
483
495
  };
@@ -506,7 +518,15 @@ interface XapiOperation<Request extends XapiRootSchema = XapiRootSchema, Respons
506
518
  type RequiredColumnKeys<Columns extends XapiColumns> = { [Key in keyof Columns]-?: Columns[Key]["optional"] extends true ? never : Key; }[keyof Columns];
507
519
  type OptionalColumnKeys<Columns extends XapiColumns> = { [Key in keyof Columns]-?: Columns[Key]["optional"] extends true ? Key : never; }[keyof Columns];
508
520
  type InferColumns<Columns extends XapiColumns> = { [Key in RequiredColumnKeys<Columns>]: XapiTypeMap[Columns[Key]["type"]]; } & { [Key in OptionalColumnKeys<Columns>]?: XapiTypeMap[Columns[Key]["type"]]; };
509
- type InferDataset<Schema extends XapiDatasetSchema> = InferColumns<Schema["columns"]>[];
521
+ /**
522
+ * A schema row remains assignable from the old plain object shape, while
523
+ * retaining the Nexacro row metadata when an operation needs it.
524
+ */
525
+ type InferDatasetRow<Schema extends XapiDatasetSchema> = InferColumns<Schema["columns"]> & {
526
+ $rowType?: RowType;
527
+ $orgRow?: Partial<InferColumns<Schema["columns"]>>;
528
+ };
529
+ type InferDataset<Schema extends XapiDatasetSchema> = InferDatasetRow<Schema>[];
510
530
  type InferRoot<Schema extends XapiRootSchema> = {
511
531
  parameters: InferColumns<Schema["parameters"]>;
512
532
  datasets: { [Key in keyof Schema["datasets"]]: InferDataset<Schema["datasets"][Key]>; };
@@ -529,11 +549,16 @@ declare function defineOperation<const Request extends XapiRootSchema, const Res
529
549
  declare const xapi: {
530
550
  readonly string: <const Optional extends boolean = false>(options?: ColumnOptions<Optional>) => XapiColumnSchema<"STRING", Optional>;
531
551
  readonly int: <const Optional extends boolean = false>(options?: ColumnOptions<Optional>) => XapiColumnSchema<"INT", Optional>;
552
+ readonly long: <const Optional extends boolean = false>(options?: ColumnOptions<Optional>) => XapiColumnSchema<"LONG", Optional>;
532
553
  readonly float: <const Optional extends boolean = false>(options?: ColumnOptions<Optional>) => XapiColumnSchema<"FLOAT", Optional>;
554
+ readonly double: <const Optional extends boolean = false>(options?: ColumnOptions<Optional>) => XapiColumnSchema<"DOUBLE", Optional>;
533
555
  readonly decimal: <const Optional extends boolean = false>(options?: ColumnOptions<Optional>) => XapiColumnSchema<"DECIMAL", Optional>;
534
556
  readonly bigdecimal: <const Optional extends boolean = false>(options?: ColumnOptions<Optional>) => XapiColumnSchema<"BIGDECIMAL", Optional>;
557
+ readonly bigDecimal: <const Optional extends boolean = false>(options?: ColumnOptions<Optional>) => XapiColumnSchema<"BIG_DECIMAL", Optional>;
558
+ readonly boolean: <const Optional extends boolean = false>(options?: ColumnOptions<Optional>) => XapiColumnSchema<"BOOLEAN", Optional>;
535
559
  readonly date: <const Optional extends boolean = false>(options?: ColumnOptions<Optional>) => XapiColumnSchema<"DATE", Optional>;
536
560
  readonly datetime: <const Optional extends boolean = false>(options?: ColumnOptions<Optional>) => XapiColumnSchema<"DATETIME", Optional>;
561
+ readonly dateTime: <const Optional extends boolean = false>(options?: ColumnOptions<Optional>) => XapiColumnSchema<"DATE_TIME", Optional>;
537
562
  readonly time: <const Optional extends boolean = false>(options?: ColumnOptions<Optional>) => XapiColumnSchema<"TIME", Optional>;
538
563
  readonly blob: <const Optional extends boolean = false>(options?: ColumnOptions<Optional>) => XapiColumnSchema<"BLOB", Optional>;
539
564
  readonly dataset: typeof defineDataset;
@@ -543,4 +568,43 @@ declare const xapi: {
543
568
  declare function encodeRoot<Schema extends XapiRootSchema>(schema: Schema, value: InferRoot<Schema>): XapiRoot;
544
569
  declare function decodeRoot<Schema extends XapiRootSchema>(schema: Schema, root: XapiRoot): InferRoot<Schema>;
545
570
  //#endregion
546
- export { Col, Column, ColumnInfo, ColumnType, ColumnTypeError, ConstColumn, Dataset, InferColumns, InferDataset, InferRoot, InvalidXmlError, NexaVersion, Parameter, RequestOf, ResponseOf, Row, RowType, Rows, StringWritableStream, XapiColumnSchema, XapiColumns, XapiDatasetSchema, XapiDatasets, XapiOperation, XapiOptions, XapiParameters, XapiRoot, XapiRootSchema, XapiTypeMap, XapiValueType, XapiVersion, XmlNode, XmlStringBuilder, XplatformVersion, _unescapeXml, arrayBufferToString, base64ToUint8Array, columnType, convertToColumnType, convertToString, dateToString, decodeRoot, defineDataset, defineOperation, defineRoot, encodeControlChars, encodeRoot, escapeXml, initXapi, isXapiRoot, makeParseEntities, parse, parseXml, rowType, stringToDate, stringToReadableStream, uint8ArrayToBase64, write, xapi };
571
+ //#region src/codec.d.ts
572
+ /** The wire representation used by Nexacro's Dataset JSON format. */
573
+ interface NexacroJsonParameter {
574
+ id: string;
575
+ type?: ColumnType;
576
+ value?: string | number | boolean;
577
+ }
578
+ interface NexacroJsonColumn {
579
+ id: string;
580
+ type?: ColumnType;
581
+ size?: number | string;
582
+ value?: string | number | boolean;
583
+ }
584
+ interface NexacroJsonRow {
585
+ _RowType_?: "N" | "I" | "U" | "D" | "O";
586
+ [columnId: string]: unknown;
587
+ }
588
+ interface NexacroJsonDataset {
589
+ id: string;
590
+ ColumnInfo: {
591
+ ConstColumn?: NexacroJsonColumn[];
592
+ Column: NexacroJsonColumn[];
593
+ };
594
+ Rows: NexacroJsonRow[];
595
+ }
596
+ interface NexacroJsonRoot {
597
+ version: "1.0";
598
+ Parameters?: NexacroJsonParameter[];
599
+ Datasets?: NexacroJsonDataset[];
600
+ }
601
+ /** A serializer boundary around the X-API internal model. */
602
+ interface XapiCodec<Serialized> {
603
+ serialize(root: XapiRoot): Serialized;
604
+ deserialize(value: Serialized): XapiRoot;
605
+ }
606
+ declare const nexacroJsonCodec: XapiCodec<NexacroJsonRoot>;
607
+ declare function parseJson(value: string): XapiRoot;
608
+ declare function writeJsonString(root: XapiRoot): string;
609
+ //#endregion
610
+ export { Col, Column, ColumnInfo, ColumnType, ColumnTypeError, ConstColumn, Dataset, InferColumns, InferDataset, InferDatasetRow, InferRoot, InvalidXmlError, NexaVersion, NexacroJsonColumn, NexacroJsonDataset, NexacroJsonParameter, NexacroJsonRoot, NexacroJsonRow, Parameter, RequestOf, ResponseOf, Row, RowType, Rows, StringWritableStream, XapiCodec, XapiColumnSchema, XapiColumns, XapiDatasetSchema, XapiDatasets, XapiOperation, XapiOptions, XapiParameters, XapiRoot, XapiRootSchema, XapiTypeMap, XapiValueType, XapiVersion, XmlNode, XmlStringBuilder, XplatformVersion, _unescapeXml, arrayBufferToString, base64ToUint8Array, columnType, convertToColumnType, convertToString, dateToString, decodeRoot, defineDataset, defineOperation, defineRoot, encodeControlChars, encodeRoot, escapeXml, initXapi, isXapiRoot, makeParseEntities, nexacroJsonCodec, normalizeColumnType, parse, parseJson, parseXml, rowType, stringToDate, stringToReadableStream, uint8ArrayToBase64, write, writeJsonString, xapi };
package/dist/index.d.ts CHANGED
@@ -2,7 +2,7 @@
2
2
  /**
3
3
  * Represents the possible data types for X-API values.
4
4
  */
5
- type XapiValueType = string | number | Uint8Array | Date | undefined;
5
+ type XapiValueType = string | number | boolean | Uint8Array | Date | undefined;
6
6
  /**
7
7
  * Represents a column within a row of an X-API dataset.
8
8
  */
@@ -11,6 +11,8 @@ interface Col {
11
11
  id: string;
12
12
  /** The value of the column. */
13
13
  value?: XapiValueType;
14
+ /** Original wire value. XML and SSV values are strings before schema conversion. */
15
+ rawValue?: string;
14
16
  }
15
17
  /**
16
18
  * Defines the possible types of rows in an X-API dataset (e.g., "insert", "update", "delete").
@@ -41,7 +43,7 @@ interface Rows {
41
43
  /**
42
44
  * Defines the possible data types for columns in an X-API dataset.
43
45
  */
44
- declare const columnType: readonly ["STRING", "INT", "FLOAT", "DECIMAL", "BIGDECIMAL", "DATE", "DATETIME", "TIME", "BLOB"];
46
+ declare const columnType: readonly ["STRING", "INT", "LONG", "FLOAT", "DOUBLE", "DECIMAL", "BIGDECIMAL", "BIG_DECIMAL", "BOOLEAN", "DATE", "DATETIME", "DATE_TIME", "TIME", "BLOB"];
45
47
  /**
46
48
  * Type representing the data type of a column.
47
49
  */
@@ -62,6 +64,7 @@ interface Column {
62
64
  */
63
65
  type ConstColumn = Column & {
64
66
  value: XapiValueType;
67
+ rawValue?: string;
65
68
  };
66
69
  /**
67
70
  * Represents the column information section of an X-API dataset.
@@ -82,6 +85,8 @@ interface Parameter {
82
85
  type?: ColumnType;
83
86
  /** The value of the parameter. */
84
87
  value?: XapiValueType;
88
+ /** Original wire value before conversion. */
89
+ rawValue?: string;
85
90
  }
86
91
  /**
87
92
  * Represents a collection of parameters in an X-API request/response.
@@ -366,14 +371,14 @@ declare function uint8ArrayToBase64(uint8Array: Uint8Array): string;
366
371
  * @param value - The string to convert.
367
372
  * @returns A Date object if the string is a valid date/time, otherwise undefined.
368
373
  */
369
- declare function stringToDate(value: string): Date | undefined;
374
+ declare function stringToDate(value: string, type?: ColumnType): Date | undefined;
370
375
  /**
371
376
  * Converts a Date object to a string representation based on the specified column type.
372
377
  * @param date - The Date object to convert.
373
378
  * @param type - The column type ("DATE", "DATETIME", or "TIME").
374
379
  * @returns A string representation of the date/time.
375
380
  */
376
- declare function dateToString(date: Date, type: Extract<ColumnType, "DATE" | "DATETIME" | "TIME">): string;
381
+ declare function dateToString(date: Date, type: Extract<ColumnType, "DATE" | "DATETIME" | "DATE_TIME" | "TIME">): string;
377
382
  /**
378
383
  * A WritableStream that collects all written Uint8Array chunks and provides them as a single string.
379
384
  */
@@ -400,6 +405,8 @@ declare function stringToReadableStream(str: string): ReadableStream<Uint8Array>
400
405
  * @throws {ColumnTypeError} if the column type is unsupported.
401
406
  */
402
407
  declare function convertToColumnType(value: XapiValueType, type: ColumnType): XapiValueType;
408
+ /** Normalizes X-API/Java type spellings to the names used by Dataset XML. */
409
+ declare function normalizeColumnType(type?: string): ColumnType;
403
410
  /**
404
411
  * Converts an XapiValueType to its string representation based on the specified ColumnType.
405
412
  * @param value - The value to convert.
@@ -473,11 +480,16 @@ declare function parseXml(xml: string): XmlNode[];
473
480
  type XapiTypeMap = {
474
481
  STRING: string;
475
482
  INT: number;
483
+ LONG: number;
476
484
  FLOAT: number;
485
+ DOUBLE: number;
477
486
  DECIMAL: number;
478
487
  BIGDECIMAL: number;
488
+ BIG_DECIMAL: number;
489
+ BOOLEAN: boolean;
479
490
  DATE: Date;
480
491
  DATETIME: Date;
492
+ DATE_TIME: Date;
481
493
  TIME: Date;
482
494
  BLOB: Uint8Array;
483
495
  };
@@ -506,7 +518,15 @@ interface XapiOperation<Request extends XapiRootSchema = XapiRootSchema, Respons
506
518
  type RequiredColumnKeys<Columns extends XapiColumns> = { [Key in keyof Columns]-?: Columns[Key]["optional"] extends true ? never : Key; }[keyof Columns];
507
519
  type OptionalColumnKeys<Columns extends XapiColumns> = { [Key in keyof Columns]-?: Columns[Key]["optional"] extends true ? Key : never; }[keyof Columns];
508
520
  type InferColumns<Columns extends XapiColumns> = { [Key in RequiredColumnKeys<Columns>]: XapiTypeMap[Columns[Key]["type"]]; } & { [Key in OptionalColumnKeys<Columns>]?: XapiTypeMap[Columns[Key]["type"]]; };
509
- type InferDataset<Schema extends XapiDatasetSchema> = InferColumns<Schema["columns"]>[];
521
+ /**
522
+ * A schema row remains assignable from the old plain object shape, while
523
+ * retaining the Nexacro row metadata when an operation needs it.
524
+ */
525
+ type InferDatasetRow<Schema extends XapiDatasetSchema> = InferColumns<Schema["columns"]> & {
526
+ $rowType?: RowType;
527
+ $orgRow?: Partial<InferColumns<Schema["columns"]>>;
528
+ };
529
+ type InferDataset<Schema extends XapiDatasetSchema> = InferDatasetRow<Schema>[];
510
530
  type InferRoot<Schema extends XapiRootSchema> = {
511
531
  parameters: InferColumns<Schema["parameters"]>;
512
532
  datasets: { [Key in keyof Schema["datasets"]]: InferDataset<Schema["datasets"][Key]>; };
@@ -529,11 +549,16 @@ declare function defineOperation<const Request extends XapiRootSchema, const Res
529
549
  declare const xapi: {
530
550
  readonly string: <const Optional extends boolean = false>(options?: ColumnOptions<Optional>) => XapiColumnSchema<"STRING", Optional>;
531
551
  readonly int: <const Optional extends boolean = false>(options?: ColumnOptions<Optional>) => XapiColumnSchema<"INT", Optional>;
552
+ readonly long: <const Optional extends boolean = false>(options?: ColumnOptions<Optional>) => XapiColumnSchema<"LONG", Optional>;
532
553
  readonly float: <const Optional extends boolean = false>(options?: ColumnOptions<Optional>) => XapiColumnSchema<"FLOAT", Optional>;
554
+ readonly double: <const Optional extends boolean = false>(options?: ColumnOptions<Optional>) => XapiColumnSchema<"DOUBLE", Optional>;
533
555
  readonly decimal: <const Optional extends boolean = false>(options?: ColumnOptions<Optional>) => XapiColumnSchema<"DECIMAL", Optional>;
534
556
  readonly bigdecimal: <const Optional extends boolean = false>(options?: ColumnOptions<Optional>) => XapiColumnSchema<"BIGDECIMAL", Optional>;
557
+ readonly bigDecimal: <const Optional extends boolean = false>(options?: ColumnOptions<Optional>) => XapiColumnSchema<"BIG_DECIMAL", Optional>;
558
+ readonly boolean: <const Optional extends boolean = false>(options?: ColumnOptions<Optional>) => XapiColumnSchema<"BOOLEAN", Optional>;
535
559
  readonly date: <const Optional extends boolean = false>(options?: ColumnOptions<Optional>) => XapiColumnSchema<"DATE", Optional>;
536
560
  readonly datetime: <const Optional extends boolean = false>(options?: ColumnOptions<Optional>) => XapiColumnSchema<"DATETIME", Optional>;
561
+ readonly dateTime: <const Optional extends boolean = false>(options?: ColumnOptions<Optional>) => XapiColumnSchema<"DATE_TIME", Optional>;
537
562
  readonly time: <const Optional extends boolean = false>(options?: ColumnOptions<Optional>) => XapiColumnSchema<"TIME", Optional>;
538
563
  readonly blob: <const Optional extends boolean = false>(options?: ColumnOptions<Optional>) => XapiColumnSchema<"BLOB", Optional>;
539
564
  readonly dataset: typeof defineDataset;
@@ -543,4 +568,43 @@ declare const xapi: {
543
568
  declare function encodeRoot<Schema extends XapiRootSchema>(schema: Schema, value: InferRoot<Schema>): XapiRoot;
544
569
  declare function decodeRoot<Schema extends XapiRootSchema>(schema: Schema, root: XapiRoot): InferRoot<Schema>;
545
570
  //#endregion
546
- export { Col, Column, ColumnInfo, ColumnType, ColumnTypeError, ConstColumn, Dataset, InferColumns, InferDataset, InferRoot, InvalidXmlError, NexaVersion, Parameter, RequestOf, ResponseOf, Row, RowType, Rows, StringWritableStream, XapiColumnSchema, XapiColumns, XapiDatasetSchema, XapiDatasets, XapiOperation, XapiOptions, XapiParameters, XapiRoot, XapiRootSchema, XapiTypeMap, XapiValueType, XapiVersion, XmlNode, XmlStringBuilder, XplatformVersion, _unescapeXml, arrayBufferToString, base64ToUint8Array, columnType, convertToColumnType, convertToString, dateToString, decodeRoot, defineDataset, defineOperation, defineRoot, encodeControlChars, encodeRoot, escapeXml, initXapi, isXapiRoot, makeParseEntities, parse, parseXml, rowType, stringToDate, stringToReadableStream, uint8ArrayToBase64, write, xapi };
571
+ //#region src/codec.d.ts
572
+ /** The wire representation used by Nexacro's Dataset JSON format. */
573
+ interface NexacroJsonParameter {
574
+ id: string;
575
+ type?: ColumnType;
576
+ value?: string | number | boolean;
577
+ }
578
+ interface NexacroJsonColumn {
579
+ id: string;
580
+ type?: ColumnType;
581
+ size?: number | string;
582
+ value?: string | number | boolean;
583
+ }
584
+ interface NexacroJsonRow {
585
+ _RowType_?: "N" | "I" | "U" | "D" | "O";
586
+ [columnId: string]: unknown;
587
+ }
588
+ interface NexacroJsonDataset {
589
+ id: string;
590
+ ColumnInfo: {
591
+ ConstColumn?: NexacroJsonColumn[];
592
+ Column: NexacroJsonColumn[];
593
+ };
594
+ Rows: NexacroJsonRow[];
595
+ }
596
+ interface NexacroJsonRoot {
597
+ version: "1.0";
598
+ Parameters?: NexacroJsonParameter[];
599
+ Datasets?: NexacroJsonDataset[];
600
+ }
601
+ /** A serializer boundary around the X-API internal model. */
602
+ interface XapiCodec<Serialized> {
603
+ serialize(root: XapiRoot): Serialized;
604
+ deserialize(value: Serialized): XapiRoot;
605
+ }
606
+ declare const nexacroJsonCodec: XapiCodec<NexacroJsonRoot>;
607
+ declare function parseJson(value: string): XapiRoot;
608
+ declare function writeJsonString(root: XapiRoot): string;
609
+ //#endregion
610
+ export { Col, Column, ColumnInfo, ColumnType, ColumnTypeError, ConstColumn, Dataset, InferColumns, InferDataset, InferDatasetRow, InferRoot, InvalidXmlError, NexaVersion, NexacroJsonColumn, NexacroJsonDataset, NexacroJsonParameter, NexacroJsonRoot, NexacroJsonRow, Parameter, RequestOf, ResponseOf, Row, RowType, Rows, StringWritableStream, XapiCodec, XapiColumnSchema, XapiColumns, XapiDatasetSchema, XapiDatasets, XapiOperation, XapiOptions, XapiParameters, XapiRoot, XapiRootSchema, XapiTypeMap, XapiValueType, XapiVersion, XmlNode, XmlStringBuilder, XplatformVersion, _unescapeXml, arrayBufferToString, base64ToUint8Array, columnType, convertToColumnType, convertToString, dateToString, decodeRoot, defineDataset, defineOperation, defineRoot, encodeControlChars, encodeRoot, escapeXml, initXapi, isXapiRoot, makeParseEntities, nexacroJsonCodec, normalizeColumnType, parse, parseJson, parseXml, rowType, stringToDate, stringToReadableStream, uint8ArrayToBase64, write, writeJsonString, xapi };
package/dist/index.js CHANGED
@@ -13,11 +13,16 @@ const rowType = [
13
13
  const columnType = [
14
14
  "STRING",
15
15
  "INT",
16
+ "LONG",
16
17
  "FLOAT",
18
+ "DOUBLE",
17
19
  "DECIMAL",
18
20
  "BIGDECIMAL",
21
+ "BIG_DECIMAL",
22
+ "BOOLEAN",
19
23
  "DATE",
20
24
  "DATETIME",
25
+ "DATE_TIME",
21
26
  "TIME",
22
27
  "BLOB"
23
28
  ];
@@ -367,8 +372,23 @@ function uint8ArrayToBase64(uint8Array) {
367
372
  * @param value - The string to convert.
368
373
  * @returns A Date object if the string is a valid date/time, otherwise undefined.
369
374
  */
370
- function stringToDate(value) {
375
+ function stringToDate(value, type) {
371
376
  if (!value) return void 0;
377
+ const normalizedType = type ? normalizeColumnType(type) : void 0;
378
+ if (normalizedType === "TIME") {
379
+ if (value.length !== 6 && value.length !== 9) return void 0;
380
+ const hours = parseInt(value.substring(0, 2), 10);
381
+ const minutes = parseInt(value.substring(2, 4), 10);
382
+ const seconds = parseInt(value.substring(4, 6), 10);
383
+ const milliseconds = value.length === 9 ? parseInt(value.substring(6, 9), 10) : 0;
384
+ if ([
385
+ hours,
386
+ minutes,
387
+ seconds,
388
+ milliseconds
389
+ ].some(Number.isNaN) || hours > 23 || minutes > 59 || seconds > 59 || milliseconds > 999) return void 0;
390
+ return new Date(1970, 0, 1, hours, minutes, seconds, milliseconds);
391
+ }
372
392
  let year;
373
393
  let month;
374
394
  let day;
@@ -376,7 +396,7 @@ function stringToDate(value) {
376
396
  let minutes = 0;
377
397
  let seconds = 0;
378
398
  let milliseconds = 0;
379
- if (value.length < 6 || value.length > 16) return;
399
+ if (value.length < 6 || value.length > (normalizedType ? 17 : 16)) return;
380
400
  if (value.length >= 8) {
381
401
  year = parseInt(value.substring(0, 4), 10);
382
402
  month = parseInt(value.substring(4, 6), 10) - 1;
@@ -395,7 +415,10 @@ function stringToDate(value) {
395
415
  minutes = parseInt(value.substring(10, 12), 10);
396
416
  seconds = parseInt(value.substring(12, 14), 10);
397
417
  }
398
- if (value.length === 16) milliseconds = parseInt(value.substring(14, 16), 10);
418
+ if (value.length === 16 || value.length === 17) {
419
+ milliseconds = parseInt(value.substring(14, value.length), 10);
420
+ if (value.length === 16 && normalizedType) milliseconds *= 10;
421
+ }
399
422
  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;
400
423
  const date = new Date(year, month, day, hours, minutes, seconds, milliseconds);
401
424
  if (isNaN(date.getTime())) return;
@@ -414,10 +437,10 @@ function dateToString(date, type) {
414
437
  const hours = date.getHours().toString().padStart(2, "0");
415
438
  const minutes = date.getMinutes().toString().padStart(2, "0");
416
439
  const seconds = date.getSeconds().toString().padStart(2, "0");
417
- switch (type) {
440
+ switch (normalizeColumnType(type)) {
418
441
  case "DATE": return `${year}${month}${day}`;
419
- case "DATETIME": return `${year}${month}${day}${hours}${minutes}${seconds}`;
420
- case "TIME": return `${hours}${minutes}${seconds}`;
442
+ case "DATETIME": return `${year}${month}${day}${hours}${minutes}${seconds}${date.getMilliseconds() ? date.getMilliseconds().toString().padStart(3, "0") : ""}`;
443
+ case "TIME": return `${hours}${minutes}${seconds}${date.getMilliseconds() ? date.getMilliseconds().toString().padStart(3, "0") : ""}`;
421
444
  default: return "";
422
445
  }
423
446
  }
@@ -465,12 +488,16 @@ function stringToReadableStream(str) {
465
488
  * @throws {ColumnTypeError} if the column type is unsupported.
466
489
  */
467
490
  function convertToColumnType(value, type) {
468
- switch (type) {
491
+ const normalizedType = normalizeColumnType(type);
492
+ switch (normalizeColumnType(type)) {
469
493
  case "INT":
470
494
  const intValue = parseInt(value, 10);
471
495
  return isNaN(intValue) ? value : intValue;
472
496
  case "FLOAT":
497
+ case "DOUBLE":
498
+ case "LONG":
473
499
  case "BIGDECIMAL":
500
+ case "BIG_DECIMAL":
474
501
  const floatValue = parseFloat(value);
475
502
  return isNaN(floatValue) ? value : floatValue;
476
503
  case "DECIMAL":
@@ -478,14 +505,29 @@ function convertToColumnType(value, type) {
478
505
  return isNaN(decimalValue) ? value : decimalValue;
479
506
  case "DATE":
480
507
  case "DATETIME":
481
- case "TIME": return stringToDate(value) || value;
508
+ case "DATE_TIME":
509
+ case "TIME": return stringToDate(value, normalizedType) || value;
510
+ case "BOOLEAN":
511
+ if (value === "true" || value === "1" || value === 1 || value === true) return true;
512
+ if (value === "false" || value === "0" || value === 0 || value === false) return false;
513
+ return value;
482
514
  case "BLOB": try {
483
515
  return base64ToUint8Array(value);
484
516
  } catch {
485
517
  return value;
486
518
  }
487
519
  case "STRING": return value;
488
- default: throw new ColumnTypeError(`Unsupported column type: ${type}`);
520
+ default: throw new ColumnTypeError(`Unsupported column type: ${normalizedType}`);
521
+ }
522
+ }
523
+ /** Normalizes X-API/Java type spellings to the names used by Dataset XML. */
524
+ function normalizeColumnType(type) {
525
+ const normalized = type?.replace(/[- ]/g, "_").toUpperCase();
526
+ switch (normalized) {
527
+ case "DATE_TIME": return "DATETIME";
528
+ case "BIG_DECIMAL": return "BIGDECIMAL";
529
+ case "BOOL": return "BOOLEAN";
530
+ default: return normalized || "STRING";
489
531
  }
490
532
  }
491
533
  /**
@@ -497,12 +539,17 @@ function convertToColumnType(value, type) {
497
539
  function convertToString(value, type) {
498
540
  switch (type) {
499
541
  case "INT":
542
+ case "LONG":
500
543
  case "BIGDECIMAL":
544
+ case "BIG_DECIMAL":
501
545
  case "FLOAT":
546
+ case "DOUBLE":
502
547
  case "DECIMAL": return String(value);
548
+ case "BOOLEAN": return value ? "true" : "false";
503
549
  case "DATE":
504
550
  case "DATETIME":
505
- case "TIME": return dateToString(value, type);
551
+ case "DATE_TIME":
552
+ case "TIME": return dateToString(value, normalizeColumnType(type));
506
553
  case "BLOB": return uint8ArrayToBase64(value);
507
554
  case "STRING": return String(value);
508
555
  default: return String(value);
@@ -927,8 +974,9 @@ function parseColumnInfo(columnInfoElement, dataset) {
927
974
  dataset.addConstColumn({
928
975
  id: attrs?.id,
929
976
  size: sizeStr ? parseInt(sizeStr, 10) : 0,
930
- type: attrs?.type || "STRING",
931
- value: parseValue(attrs?.value, attrs?.type)
977
+ type: normalizeColumnType(attrs?.type),
978
+ value: parseValue(attrs?.value, attrs?.type),
979
+ rawValue: attrs?.value
932
980
  });
933
981
  } else if (tagName === "Column") {
934
982
  const attrs = colInfo.attributes;
@@ -936,7 +984,7 @@ function parseColumnInfo(columnInfoElement, dataset) {
936
984
  dataset.addColumn({
937
985
  id: attrs?.id,
938
986
  size: sizeStr ? parseInt(sizeStr, 10) : 0,
939
- type: attrs?.type || "STRING"
987
+ type: normalizeColumnType(attrs?.type)
940
988
  });
941
989
  }
942
990
  }
@@ -966,7 +1014,8 @@ function parseRows(rowsElement, dataset) {
966
1014
  const castedValue = parseValue(value, columnInfo.type);
967
1015
  currentRow.cols.push({
968
1016
  id: colId,
969
- value: castedValue
1017
+ value: castedValue,
1018
+ rawValue: value
970
1019
  });
971
1020
  } else if (colTagName === "OrgRow") {
972
1021
  const orgRow = [];
@@ -980,7 +1029,8 @@ function parseRows(rowsElement, dataset) {
980
1029
  const castedValue = parseValue(value, dataset.getColumnInfo(colId).type);
981
1030
  orgRow.push({
982
1031
  id: colId,
983
- value: castedValue
1032
+ value: castedValue,
1033
+ rawValue: value
984
1034
  });
985
1035
  }
986
1036
  }
@@ -1004,8 +1054,9 @@ function parseParameters(parametersElement, xapiRoot) {
1004
1054
  const value = p.children?.[0] ?? attrs?.value;
1005
1055
  xapiRoot.addParameter({
1006
1056
  id,
1007
- type,
1008
- value: parseValue(value, type)
1057
+ type: normalizeColumnType(type),
1058
+ value: parseValue(value, type),
1059
+ rawValue: value
1009
1060
  });
1010
1061
  }
1011
1062
  }
@@ -1030,7 +1081,7 @@ function writeParameters(builder, parameters) {
1030
1081
  builder.writeStartElement("Parameters");
1031
1082
  for (const parameter of parameters) {
1032
1083
  const attrs = { id: parameter.id };
1033
- if (parameter.type !== void 0) attrs.type = parameter.type;
1084
+ if (parameter.type !== void 0) attrs.type = normalizeColumnType(parameter.type);
1034
1085
  if (parameter.value !== void 0) if (typeof parameter.value === "string") attrs.value = parameter.value;
1035
1086
  else if (parameter.value instanceof Date) attrs.value = dateToString(parameter.value, parameter.type);
1036
1087
  else if (parameter.value instanceof Uint8Array) attrs.value = uint8ArrayToBase64(parameter.value);
@@ -1046,13 +1097,13 @@ function writeDataset(builder, dataset) {
1046
1097
  for (const constCol of dataset.getConstColumns()) builder.writeStartElement("ConstColumn", {
1047
1098
  id: constCol.id,
1048
1099
  size: String(constCol.size),
1049
- type: constCol.type,
1100
+ type: normalizeColumnType(constCol.type),
1050
1101
  value: constCol.value !== void 0 ? String(constCol.value) : ""
1051
1102
  }, true);
1052
1103
  for (const col of dataset.getColumns()) builder.writeStartElement("Column", {
1053
1104
  id: col.id,
1054
1105
  size: String(col.size),
1055
- type: col.type
1106
+ type: normalizeColumnType(col.type)
1056
1107
  }, true);
1057
1108
  builder.writeEndElement("ColumnInfo");
1058
1109
  }
@@ -1079,14 +1130,30 @@ function writeColumn(builder, dataset, col) {
1079
1130
  }
1080
1131
  //#endregion
1081
1132
  //#region src/schema.ts
1133
+ const schemaCache = /* @__PURE__ */ new WeakMap();
1134
+ function compileSchema(schema) {
1135
+ const cached = schemaCache.get(schema);
1136
+ if (cached) return cached;
1137
+ const compiled = {
1138
+ parameters: new Map(Object.entries(schema.parameters)),
1139
+ datasets: new Map(Object.entries(schema.datasets).map(([id, dataset]) => [id, { columns: new Map(Object.entries(dataset.columns)) }]))
1140
+ };
1141
+ schemaCache.set(schema, compiled);
1142
+ return compiled;
1143
+ }
1082
1144
  const defaultSizes = {
1083
1145
  STRING: 256,
1084
1146
  INT: 10,
1147
+ LONG: 19,
1085
1148
  FLOAT: 20,
1149
+ DOUBLE: 20,
1086
1150
  DECIMAL: 20,
1087
1151
  BIGDECIMAL: 30,
1152
+ BIG_DECIMAL: 30,
1153
+ BOOLEAN: 5,
1088
1154
  DATE: 8,
1089
1155
  DATETIME: 17,
1156
+ DATE_TIME: 17,
1090
1157
  TIME: 6,
1091
1158
  BLOB: 1e3
1092
1159
  };
@@ -1120,11 +1187,16 @@ function defineOperation(definition) {
1120
1187
  const xapi = {
1121
1188
  string: (options) => column("STRING", options),
1122
1189
  int: (options) => column("INT", options),
1190
+ long: (options) => column("LONG", options),
1123
1191
  float: (options) => column("FLOAT", options),
1192
+ double: (options) => column("DOUBLE", options),
1124
1193
  decimal: (options) => column("DECIMAL", options),
1125
1194
  bigdecimal: (options) => column("BIGDECIMAL", options),
1195
+ bigDecimal: (options) => column("BIG_DECIMAL", options),
1196
+ boolean: (options) => column("BOOLEAN", options),
1126
1197
  date: (options) => column("DATE", options),
1127
1198
  datetime: (options) => column("DATETIME", options),
1199
+ dateTime: (options) => column("DATE_TIME", options),
1128
1200
  time: (options) => column("TIME", options),
1129
1201
  blob: (options) => column("BLOB", options),
1130
1202
  dataset: defineDataset,
@@ -1133,7 +1205,8 @@ const xapi = {
1133
1205
  };
1134
1206
  function encodeRoot(schema, value) {
1135
1207
  const root = new XapiRoot();
1136
- for (const [id, parameterSchema] of Object.entries(schema.parameters)) {
1208
+ const compiled = compileSchema(schema);
1209
+ for (const [id, parameterSchema] of compiled.parameters) {
1137
1210
  const parameterValue = value.parameters[id];
1138
1211
  if (parameterValue !== void 0 || !parameterSchema.optional) root.addParameter({
1139
1212
  id,
@@ -1141,30 +1214,39 @@ function encodeRoot(schema, value) {
1141
1214
  value: parameterValue
1142
1215
  });
1143
1216
  }
1144
- for (const [datasetId, datasetSchema] of Object.entries(schema.datasets)) {
1217
+ for (const [datasetId, datasetDefinition] of compiled.datasets) {
1145
1218
  const dataset = new Dataset(datasetId);
1146
- for (const [id, columnSchema] of Object.entries(datasetSchema.columns)) dataset.addColumn({
1219
+ for (const [id, columnSchema] of datasetDefinition.columns) dataset.addColumn({
1147
1220
  id,
1148
1221
  type: columnSchema.type,
1149
1222
  size: columnSchema.size
1150
1223
  });
1151
1224
  const rows = value.datasets[datasetId];
1225
+ const columnIds = [...datasetDefinition.columns.keys()];
1152
1226
  for (const row of rows) {
1153
1227
  const rowIndex = dataset.newRow();
1154
- for (const id of Object.keys(datasetSchema.columns)) dataset.setColumn(rowIndex, id, row[id]);
1228
+ dataset.rows[rowIndex].type = row.$rowType;
1229
+ for (const id of columnIds) dataset.setColumn(rowIndex, id, row[id]);
1230
+ if (row.$orgRow) dataset.rows[rowIndex].orgRow = Object.entries(row.$orgRow).map(([id, value]) => ({
1231
+ id,
1232
+ value
1233
+ }));
1155
1234
  }
1156
1235
  root.addDataset(dataset);
1157
1236
  }
1158
1237
  return root;
1159
1238
  }
1160
1239
  function decodeRoot(schema, root) {
1240
+ const compiled = compileSchema(schema);
1161
1241
  const parameters = {};
1162
- for (const id of Object.keys(schema.parameters)) {
1163
- const value = root.getParameter(id)?.value;
1164
- if (value !== void 0) parameters[id] = value;
1242
+ for (const [id, parameterSchema] of compiled.parameters) {
1243
+ const parameter = root.getParameter(id);
1244
+ const value = parameter?.rawValue !== void 0 ? parameter.rawValue : parameter?.value;
1245
+ if (value !== void 0) parameters[id] = convertToColumnType(value, parameterSchema.type);
1165
1246
  }
1166
1247
  const datasets = {};
1167
- for (const [datasetId, datasetSchema] of Object.entries(schema.datasets)) {
1248
+ for (const [datasetId, datasetDefinition] of compiled.datasets) {
1249
+ const schemaColumns = datasetDefinition.columns;
1168
1250
  const dataset = root.getDataset(datasetId);
1169
1251
  if (!dataset) {
1170
1252
  datasets[datasetId] = [];
@@ -1173,7 +1255,20 @@ function decodeRoot(schema, root) {
1173
1255
  const constants = Object.fromEntries(dataset.getConstColumns().map(({ id, value }) => [id, value]));
1174
1256
  datasets[datasetId] = dataset.getRows().map((row) => {
1175
1257
  const value = { ...constants };
1176
- for (const column of row.cols) if (column.id in datasetSchema.columns) value[column.id] = column.value;
1258
+ for (const column of row.cols) {
1259
+ const columnSchema = schemaColumns.get(column.id);
1260
+ if (columnSchema) {
1261
+ const rawValue = column.rawValue !== void 0 ? column.rawValue : column.value;
1262
+ value[column.id] = rawValue === void 0 ? void 0 : convertToColumnType(rawValue, columnSchema.type);
1263
+ }
1264
+ }
1265
+ if (row.type) value.$rowType = row.type;
1266
+ if (row.orgRow) value.$orgRow = Object.fromEntries(row.orgRow.flatMap((column) => {
1267
+ const columnSchema = schemaColumns.get(column.id);
1268
+ if (!columnSchema) return [];
1269
+ const rawValue = column.rawValue !== void 0 ? column.rawValue : column.value;
1270
+ return [[column.id, rawValue === void 0 ? void 0 : convertToColumnType(rawValue, columnSchema.type)]];
1271
+ }));
1177
1272
  return value;
1178
1273
  });
1179
1274
  }
@@ -1183,4 +1278,136 @@ function decodeRoot(schema, root) {
1183
1278
  };
1184
1279
  }
1185
1280
  //#endregion
1186
- export { ColumnTypeError, Dataset, InvalidXmlError, NexaVersion, StringWritableStream, XapiRoot, XmlStringBuilder, XplatformVersion, _unescapeXml, arrayBufferToString, base64ToUint8Array, columnType, convertToColumnType, convertToString, dateToString, decodeRoot, defineDataset, defineOperation, defineRoot, encodeControlChars, encodeRoot, escapeXml, initXapi, isXapiRoot, makeParseEntities, parse, parseXml, rowType, stringToDate, stringToReadableStream, uint8ArrayToBase64, write, xapi };
1281
+ //#region src/codec.ts
1282
+ const rowTypes = {
1283
+ N: void 0,
1284
+ I: "insert",
1285
+ U: "update",
1286
+ D: "delete",
1287
+ O: void 0
1288
+ };
1289
+ function sizeOf(size, type) {
1290
+ if (size !== void 0) return Number(size);
1291
+ return type === "STRING" ? 255 : 0;
1292
+ }
1293
+ function jsonValue(value, type) {
1294
+ if (value === null || value === void 0) return void 0;
1295
+ return convertToColumnType(typeof value === "string" ? value : String(value), normalizeColumnType(type));
1296
+ }
1297
+ function jsonRawValue(value) {
1298
+ return value === null || value === void 0 ? void 0 : String(value);
1299
+ }
1300
+ function jsonWireValue(value, type) {
1301
+ if (value === void 0) return void 0;
1302
+ if (value instanceof Date) return dateToString(value, type);
1303
+ if (value instanceof Uint8Array) return uint8ArrayToBase64(value);
1304
+ return value;
1305
+ }
1306
+ function columnsToObject(columns) {
1307
+ return Object.fromEntries(columns.map((column) => [column.id, column.value]));
1308
+ }
1309
+ function readRow(dataset, row) {
1310
+ const rowType = rowTypes[row._RowType_ ?? "N"];
1311
+ if (row._RowType_ === "O") {
1312
+ const previous = dataset.rows[dataset.rows.length - 1];
1313
+ if (previous?.type !== "update") return;
1314
+ previous.orgRow = dataset.getColumns().filter((column) => Object.prototype.hasOwnProperty.call(row, column.id)).map((column) => ({
1315
+ id: column.id,
1316
+ value: jsonValue(row[column.id], column.type),
1317
+ rawValue: jsonRawValue(row[column.id])
1318
+ }));
1319
+ return;
1320
+ }
1321
+ const index = dataset.newRow();
1322
+ dataset.rows[index].type = rowType;
1323
+ for (const column of dataset.getColumns()) if (Object.prototype.hasOwnProperty.call(row, column.id)) dataset.rows[index].cols.push({
1324
+ id: column.id,
1325
+ value: jsonValue(row[column.id], column.type),
1326
+ rawValue: jsonRawValue(row[column.id])
1327
+ });
1328
+ }
1329
+ function readJson(value) {
1330
+ const root = new XapiRoot();
1331
+ for (const parameter of value.Parameters ?? []) {
1332
+ const type = normalizeColumnType(parameter.type);
1333
+ root.addParameter({
1334
+ id: parameter.id,
1335
+ type,
1336
+ value: jsonValue(parameter.value, type),
1337
+ rawValue: jsonRawValue(parameter.value)
1338
+ });
1339
+ }
1340
+ for (const source of value.Datasets ?? []) {
1341
+ const dataset = new Dataset(source.id);
1342
+ for (const column of source.ColumnInfo.ConstColumn ?? []) {
1343
+ const type = normalizeColumnType(column.type);
1344
+ dataset.addConstColumn({
1345
+ id: column.id,
1346
+ type,
1347
+ size: sizeOf(column.size, type),
1348
+ value: jsonValue(column.value, type),
1349
+ rawValue: jsonRawValue(column.value)
1350
+ });
1351
+ }
1352
+ for (const column of source.ColumnInfo.Column) {
1353
+ const type = normalizeColumnType(column.type);
1354
+ dataset.addColumn({
1355
+ id: column.id,
1356
+ type,
1357
+ size: sizeOf(column.size, type)
1358
+ });
1359
+ }
1360
+ for (const row of source.Rows) readRow(dataset, row);
1361
+ root.addDataset(dataset);
1362
+ }
1363
+ return root;
1364
+ }
1365
+ function writeJson(root) {
1366
+ return {
1367
+ version: "1.0",
1368
+ ...root.parameterSize() ? { Parameters: root.getParameters().map((parameter) => ({
1369
+ id: parameter.id,
1370
+ ...parameter.type ? { type: parameter.type } : {},
1371
+ ...parameter.value !== void 0 ? { value: jsonWireValue(parameter.value, parameter.type ?? "STRING") } : {}
1372
+ })) } : {},
1373
+ ...root.datasetSize() ? { Datasets: root.getDatasets().map((dataset) => ({
1374
+ id: dataset.id,
1375
+ ColumnInfo: {
1376
+ ...dataset.constColumnSize() ? { ConstColumn: dataset.getConstColumns().map((column) => ({
1377
+ id: column.id,
1378
+ type: column.type,
1379
+ size: column.size,
1380
+ value: jsonWireValue(column.value, column.type)
1381
+ })) } : {},
1382
+ Column: dataset.getColumns().map((column) => ({
1383
+ id: column.id,
1384
+ type: column.type,
1385
+ size: column.size
1386
+ }))
1387
+ },
1388
+ Rows: dataset.getRows().flatMap((row) => {
1389
+ const current = {
1390
+ _RowType_: row.type === "insert" ? "I" : row.type === "update" ? "U" : row.type === "delete" ? "D" : "N",
1391
+ ...columnsToObject(row.cols)
1392
+ };
1393
+ if (!row.orgRow) return [current];
1394
+ return [current, {
1395
+ _RowType_: "O",
1396
+ ...columnsToObject(row.orgRow)
1397
+ }];
1398
+ })
1399
+ })) } : {}
1400
+ };
1401
+ }
1402
+ const nexacroJsonCodec = {
1403
+ serialize: writeJson,
1404
+ deserialize: readJson
1405
+ };
1406
+ function parseJson(value) {
1407
+ return nexacroJsonCodec.deserialize(JSON.parse(value));
1408
+ }
1409
+ function writeJsonString(root) {
1410
+ return JSON.stringify(nexacroJsonCodec.serialize(root));
1411
+ }
1412
+ //#endregion
1413
+ export { ColumnTypeError, Dataset, InvalidXmlError, NexaVersion, StringWritableStream, XapiRoot, XmlStringBuilder, XplatformVersion, _unescapeXml, arrayBufferToString, base64ToUint8Array, columnType, convertToColumnType, convertToString, dateToString, decodeRoot, defineDataset, defineOperation, defineRoot, encodeControlChars, encodeRoot, escapeXml, initXapi, isXapiRoot, makeParseEntities, nexacroJsonCodec, normalizeColumnType, parse, parseJson, parseXml, rowType, stringToDate, stringToReadableStream, uint8ArrayToBase64, write, writeJsonString, xapi };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@xapi-js/core",
3
3
  "type": "module",
4
- "version": "1.5.0",
4
+ "version": "1.6.1",
5
5
  "main": "./dist/index.cjs",
6
6
  "module": "./dist/index.js",
7
7
  "types": "./dist/index.d.ts",