@forzalabs/remora 0.0.28 → 0.0.30

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/Constants.js CHANGED
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const CONSTANTS = {
4
- cliVersion: '0.0.28',
4
+ cliVersion: '0.0.30',
5
5
  lambdaVersion: 1,
6
6
  port: 5069,
7
7
  defaults: {
@@ -68,9 +68,11 @@
68
68
  "enum": [
69
69
  "hash",
70
70
  "mask",
71
- "crypt"
71
+ "crypt",
72
+ "random",
73
+ "seeded-random"
72
74
  ],
73
- "description": "Masking type to apply to this dimension"
75
+ "description": "Masking type to apply to this dimension. 'hash' replaces with a hashed value. 'mask' replaces characters with a mask character. 'crypt' encrypts the value. 'random' replaces with a random value. 'seeded-random' replaces with a random value generated from a seed."
74
76
  }
75
77
  },
76
78
  "required": [
@@ -135,7 +137,8 @@
135
137
  "CSV",
136
138
  "TXT",
137
139
  "XLS",
138
- "XLSX"
140
+ "XLSX",
141
+ "XML"
139
142
  ],
140
143
  "description": "The type of file to read"
141
144
  },
@@ -59,6 +59,7 @@ const readline_1 = __importDefault(require("readline"));
59
59
  const Affirm_1 = __importDefault(require("../core/Affirm"));
60
60
  const Algo_1 = __importDefault(require("../core/Algo"));
61
61
  const xlsx_1 = __importDefault(require("xlsx"));
62
+ const XMLParser_1 = __importDefault(require("../engines/parsing/XMLParser")); // Added XMLParser import
62
63
  class LocalSourceDriver {
63
64
  constructor() {
64
65
  this.init = (source) => __awaiter(this, void 0, void 0, function* () {
@@ -85,6 +86,8 @@ class LocalSourceDriver {
85
86
  case 'XLS':
86
87
  case 'XLSX':
87
88
  return yield this._readExcelLines(fileUrl, options === null || options === void 0 ? void 0 : options.sheetName);
89
+ case 'XML':
90
+ return yield this._readXmlLines(fileUrl);
88
91
  }
89
92
  });
90
93
  this.readLinesInRange = (request) => __awaiter(this, void 0, void 0, function* () {
@@ -106,6 +109,8 @@ class LocalSourceDriver {
106
109
  case 'XLS':
107
110
  case 'XLSX':
108
111
  return yield this._readExcelLines(fileUrl, sheetName, lineFrom, lineTo);
112
+ case 'XML':
113
+ return yield this._readXmlLines(fileUrl, lineFrom, lineTo);
109
114
  }
110
115
  });
111
116
  this.exist = (producer) => __awaiter(this, void 0, void 0, function* () {
@@ -169,6 +174,17 @@ class LocalSourceDriver {
169
174
  else
170
175
  return lines;
171
176
  });
177
+ this._readXmlLines = (fileUri, lineFrom, lineTo) => __awaiter(this, void 0, void 0, function* () {
178
+ const fileContent = fs.readFileSync(fileUri, 'utf-8');
179
+ const jsonData = XMLParser_1.default.xmlToJson(fileContent);
180
+ // Convert JSON data to string lines. This might need adjustment based on XML structure.
181
+ // Assuming jsonData is an array of objects, where each object is a record.
182
+ let lines = Array.isArray(jsonData) ? jsonData.map(item => JSON.stringify(item)) : [JSON.stringify(jsonData)];
183
+ if (Algo_1.default.hasVal(lineFrom) && Algo_1.default.hasVal(lineTo)) {
184
+ lines = lines.slice(lineFrom, lineTo + 1);
185
+ }
186
+ return lines;
187
+ });
172
188
  }
173
189
  }
174
190
  exports.LocalSourceDriver = LocalSourceDriver;
@@ -26,6 +26,7 @@ const SecretManager_1 = __importDefault(require("../engines/SecretManager"));
26
26
  const readline_1 = __importDefault(require("readline"));
27
27
  const Algo_1 = __importDefault(require("../core/Algo"));
28
28
  const xlsx_1 = __importDefault(require("xlsx"));
29
+ const XMLParser_1 = __importDefault(require("../engines/parsing/XMLParser")); // Added XMLParser import
29
30
  class S3DestinationDriver {
30
31
  constructor() {
31
32
  this.init = (source) => __awaiter(this, void 0, void 0, function* () {
@@ -149,6 +150,8 @@ class S3SourceDriver {
149
150
  case 'XLS':
150
151
  case 'XLSX':
151
152
  return yield this._readExcelLines(stream, options === null || options === void 0 ? void 0 : options.sheetName);
153
+ case 'XML':
154
+ return yield this._readXmlLines(stream);
152
155
  }
153
156
  });
154
157
  this.readLinesInRange = (request) => __awaiter(this, void 0, void 0, function* () {
@@ -172,6 +175,8 @@ class S3SourceDriver {
172
175
  case 'XLS':
173
176
  case 'XLSX':
174
177
  return yield this._readExcelLines(stream, sheetName, lineFrom, lineTo);
178
+ case 'XML':
179
+ return yield this._readXmlLines(stream, lineFrom, lineTo);
175
180
  }
176
181
  });
177
182
  this.exist = (producer) => __awaiter(this, void 0, void 0, function* () {
@@ -255,6 +260,34 @@ class S3SourceDriver {
255
260
  else
256
261
  return lines;
257
262
  });
263
+ this._readXmlLines = (stream, lineFrom, lineTo) => __awaiter(this, void 0, void 0, function* () {
264
+ var _a, stream_2, stream_2_1;
265
+ var _b, e_3, _c, _d;
266
+ const chunks = [];
267
+ try {
268
+ for (_a = true, stream_2 = __asyncValues(stream); stream_2_1 = yield stream_2.next(), _b = stream_2_1.done, !_b; _a = true) {
269
+ _d = stream_2_1.value;
270
+ _a = false;
271
+ const chunk = _d;
272
+ chunks.push(chunk);
273
+ }
274
+ }
275
+ catch (e_3_1) { e_3 = { error: e_3_1 }; }
276
+ finally {
277
+ try {
278
+ if (!_a && !_b && (_c = stream_2.return)) yield _c.call(stream_2);
279
+ }
280
+ finally { if (e_3) throw e_3.error; }
281
+ }
282
+ const buffer = Buffer.concat(chunks);
283
+ const jsonData = XMLParser_1.default.xmlToJson(buffer);
284
+ // Convert JSON data to string lines. This might need adjustment based on XML structure.
285
+ let lines = Array.isArray(jsonData) ? jsonData.map(item => JSON.stringify(item)) : [JSON.stringify(jsonData)];
286
+ if (Algo_1.default.hasVal(lineFrom) && Algo_1.default.hasVal(lineTo)) {
287
+ lines = lines.slice(lineFrom, lineTo + 1);
288
+ }
289
+ return lines;
290
+ });
258
291
  }
259
292
  }
260
293
  exports.S3SourceDriver = S3SourceDriver;
@@ -5,6 +5,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  const crypto_1 = __importDefault(require("crypto"));
7
7
  const Algo_1 = __importDefault(require("../core/Algo"));
8
+ const RandomEngine_1 = __importDefault(require("./RandomEngine"));
8
9
  class CryptoEngineClass {
9
10
  constructor() {
10
11
  this.hashQuery = (maskType, fieldReference, fieldName) => {
@@ -24,7 +25,7 @@ class CryptoEngineClass {
24
25
  this.valueToHash = (value) => {
25
26
  return crypto_1.default.createHash('sha256').update(JSON.stringify(value)).digest('hex');
26
27
  };
27
- this.hashValue = (maskType, value) => {
28
+ this.hashValue = (maskType, value, valueType) => {
28
29
  if (!Algo_1.default.hasVal(value))
29
30
  return value;
30
31
  if (!Algo_1.default.hasVal(maskType))
@@ -32,6 +33,24 @@ class CryptoEngineClass {
32
33
  switch (maskType) {
33
34
  case 'hash':
34
35
  return this.valueToHash(value);
36
+ case 'random': {
37
+ switch (valueType) {
38
+ case 'datetime': return RandomEngine_1.default.rngDate();
39
+ case 'number': return RandomEngine_1.default.rng();
40
+ case 'string': return this.valueToHash(value);
41
+ default:
42
+ throw new Error('Not implemented yet');
43
+ }
44
+ }
45
+ case 'seeded-random': {
46
+ switch (valueType) {
47
+ case 'datetime': return RandomEngine_1.default.sRngDate(value);
48
+ case 'number': return RandomEngine_1.default.sRng(value);
49
+ case 'string': return this.valueToHash(value);
50
+ default:
51
+ throw new Error('Not implemented yet');
52
+ }
53
+ }
35
54
  case 'crypt':
36
55
  throw new Error('Not implemented yet');
37
56
  case 'mask':
@@ -19,7 +19,7 @@ const Environment_1 = __importDefault(require("./Environment"));
19
19
  const FileCompiler_1 = __importDefault(require("./file/FileCompiler"));
20
20
  const SQLCompiler_1 = __importDefault(require("./sql/SQLCompiler"));
21
21
  const SQLUtils_1 = __importDefault(require("./sql/SQLUtils"));
22
- const ParseManager_1 = __importDefault(require("./ParseManager"));
22
+ const ParseManager_1 = __importDefault(require("./parsing/ParseManager"));
23
23
  class ProducerEngineClass {
24
24
  constructor() {
25
25
  this.compile = (producer) => {
@@ -107,9 +107,27 @@ class ProducerEngineClass {
107
107
  case 'JSONL':
108
108
  case 'JSON': {
109
109
  if (lines.length === 1) {
110
- lines = lines[0].split('\n');
110
+ // Attempt to handle cases where a single line might contain multiple JSON objects separated by newlines
111
+ // Or if the entire file content is a single JSON array stringified.
112
+ try {
113
+ const parsedAsArray = JSON.parse(lines[0]);
114
+ if (Array.isArray(parsedAsArray)) {
115
+ return { data: parsedAsArray, dataType: 'array-of-json' };
116
+ }
117
+ }
118
+ catch (error) {
119
+ // If parsing as array fails, proceed to split by newline
120
+ console.warn('Failed to parse single line as JSON array, splitting by newline:', error);
121
+ }
122
+ lines = lines[0].split('\\n');
111
123
  }
112
- const json = lines.map(x => JSON.parse(x));
124
+ const json = lines.filter(line => line.trim() !== '').map(x => JSON.parse(x));
125
+ return { data: json, dataType: 'array-of-json' };
126
+ }
127
+ case 'XML': {
128
+ // The driver's _readXmlLines method now returns an array of JSON strings.
129
+ // Each string needs to be parsed into a JSON object.
130
+ const json = lines.filter(line => line.trim() !== '').map(x => JSON.parse(x));
113
131
  return { data: json, dataType: 'array-of-json' };
114
132
  }
115
133
  default:
@@ -155,6 +173,19 @@ class ProducerEngineClass {
155
173
  sampleData = sampleData.slice(0, sampleSize);
156
174
  break;
157
175
  }
176
+ case 'XML': {
177
+ // fileData.data from readFile for XML is now an array of JSON objects
178
+ if (fileData.dataType === 'array-of-json' && Array.isArray(fileData.data)) {
179
+ sampleData = fileData.data;
180
+ }
181
+ else {
182
+ // Fallback or error handling if data is not in expected format
183
+ console.warn('Unexpected data format for XML in readSampleData');
184
+ sampleData = [];
185
+ }
186
+ sampleData = sampleData.slice(0, sampleSize);
187
+ break;
188
+ }
158
189
  default: {
159
190
  sampleData = fileData.data;
160
191
  break;
@@ -0,0 +1,35 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const seedrandom_1 = __importDefault(require("seedrandom"));
7
+ const Algo_1 = __importDefault(require("../core/Algo"));
8
+ class RandomEngineClass {
9
+ constructor() {
10
+ this.rng = (min, max) => {
11
+ const rng = Math.random;
12
+ if (Algo_1.default.hasVal(min) || Algo_1.default.hasVal(max))
13
+ return Math.floor(rng() * (max - min + 1)) + min;
14
+ else
15
+ return rng();
16
+ };
17
+ this.sRng = (seed, min, max) => {
18
+ const rng = (0, seedrandom_1.default)(String(seed));
19
+ if (Algo_1.default.hasVal(min) || Algo_1.default.hasVal(max))
20
+ return Math.floor(rng() * (max - min + 1)) + min;
21
+ else
22
+ return rng();
23
+ };
24
+ this.rngDate = (min, max) => {
25
+ const randomNumber = this.rng(min, max);
26
+ return new Date(randomNumber).toJSON();
27
+ };
28
+ this.sRngDate = (seed, min, max) => {
29
+ const randomNumber = this.sRng(seed, min, max);
30
+ return new Date(randomNumber).toJSON();
31
+ };
32
+ }
33
+ }
34
+ const RandomEngine = new RandomEngineClass();
35
+ exports.default = RandomEngine;
@@ -33,15 +33,16 @@ class PostProcessorClass {
33
33
  const groups = Algo_1.default.groupBy(items, groupingRule.groupingKey);
34
34
  const projections = [];
35
35
  groups.forEach(gItems => {
36
- var _a;
36
+ var _a, _b, _c;
37
37
  const projected = {};
38
38
  const first = gItems[0];
39
39
  for (const field of allFields) {
40
40
  const { key, alias, grouping } = field.cField;
41
41
  const fieldKey = alias !== null && alias !== void 0 ? alias : key;
42
42
  const maskType = (_a = field.dimension) === null || _a === void 0 ? void 0 : _a.mask;
43
+ const fieldType = (_c = (_b = field.dimension) === null || _b === void 0 ? void 0 : _b.type) !== null && _c !== void 0 ? _c : 'string';
43
44
  if (!field.cField.grouping) {
44
- projected[fieldKey] = CryptoEngine_1.default.hashValue(maskType, first[fieldKey]);
45
+ projected[fieldKey] = CryptoEngine_1.default.hashValue(maskType, first[fieldKey], fieldType);
45
46
  }
46
47
  else {
47
48
  const { subFields } = grouping;
@@ -64,7 +65,7 @@ class PostProcessorClass {
64
65
  const fieldType = (_c = (_b = field.dimension) === null || _b === void 0 ? void 0 : _b.type) !== null && _c !== void 0 ? _c : 'string';
65
66
  const fieldValue = this._getFieldValue(x, field);
66
67
  if (Algo_1.default.hasVal(maskType))
67
- projected[fieldKey] = CryptoEngine_1.default.hashValue(maskType, fieldValue);
68
+ projected[fieldKey] = CryptoEngine_1.default.hashValue(maskType, fieldValue, fieldType);
68
69
  else
69
70
  projected[fieldKey] = TypeCaster_1.default.cast(fieldValue, fieldType);
70
71
  }
@@ -87,9 +88,10 @@ class PostProcessorClass {
87
88
  const columns = FileCompiler_1.default.compileProducer(producer, source);
88
89
  (0, Affirm_1.default)(columns, `Invalid columns from compilation for producer "${producer.name}"`);
89
90
  const unpackDimension = (item, dimension) => {
90
- var _a;
91
+ var _a, _b, _c;
91
92
  const { nameInProducer, aliasInProducer } = dimension;
92
93
  const maskType = (_a = dimension.dimension.mask) !== null && _a !== void 0 ? _a : undefined;
94
+ const fieldType = (_c = (_b = dimension.dimension) === null || _b === void 0 ? void 0 : _b.type) !== null && _c !== void 0 ? _c : 'string';
93
95
  const keys = aliasInProducer.split('.');
94
96
  let prevValue = item;
95
97
  for (const key of keys) {
@@ -114,7 +116,7 @@ class PostProcessorClass {
114
116
  prevValue = prevValue === null || prevValue === void 0 ? void 0 : prevValue[key];
115
117
  }
116
118
  }
117
- prevValue = CryptoEngine_1.default.hashValue(maskType, prevValue);
119
+ prevValue = CryptoEngine_1.default.hashValue(maskType, prevValue, fieldType);
118
120
  const res = { [nameInProducer]: prevValue };
119
121
  return res;
120
122
  };
@@ -17,7 +17,7 @@ const DriverFactory_1 = __importDefault(require("../../drivers/DriverFactory"));
17
17
  const ConsumerEngine_1 = __importDefault(require("../consumer/ConsumerEngine"));
18
18
  const PostProcessor_1 = __importDefault(require("../consumer/PostProcessor"));
19
19
  const FileExporter_1 = __importDefault(require("../file/FileExporter"));
20
- const ParseManager_1 = __importDefault(require("../ParseManager"));
20
+ const ParseManager_1 = __importDefault(require("../parsing/ParseManager"));
21
21
  const ProducerEngine_1 = __importDefault(require("../ProducerEngine"));
22
22
  const SQLBuilder_1 = __importDefault(require("../sql/SQLBuilder"));
23
23
  const SQLCompiler_1 = __importDefault(require("../sql/SQLCompiler"));
@@ -104,7 +104,8 @@ class ExecutionPlannerClas {
104
104
  plan.push({ type: 'read-file-lines', producer, lines: { from: (_a = options.offset) !== null && _a !== void 0 ? _a : 0, to: options.limit ? (options.offset + options.limit) : undefined } });
105
105
  else
106
106
  plan.push({ type: 'read-file-whole', producer });
107
- if (((_b = producer.settings.fileType) === null || _b === void 0 ? void 0 : _b.toUpperCase()) === 'CSV')
107
+ const fileType = (_b = producer.settings.fileType) === null || _b === void 0 ? void 0 : _b.toUpperCase();
108
+ if (fileType === 'CSV' || fileType === 'TXT' || fileType === 'XLS' || fileType === 'XLSX')
108
109
  plan.push({ type: 'csv-to-json', producer });
109
110
  if (producer.dimensions.some(x => { var _a, _b; return ((_a = x.alias) === null || _a === void 0 ? void 0 : _a.includes('{')) || ((_b = x.alias) === null || _b === void 0 ? void 0 : _b.includes('[')); }))
110
111
  plan.push({ type: 'nested-field-unpacking', producer });
@@ -0,0 +1,75 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const Affirm_1 = __importDefault(require("../../core/Affirm"));
7
+ const Environment_1 = __importDefault(require("../Environment"));
8
+ const FileCompiler_1 = __importDefault(require("../file/FileCompiler"));
9
+ class ParseManagerClass {
10
+ constructor() {
11
+ this.csvToJson = (csv, producer) => {
12
+ (0, Affirm_1.default)(csv, 'Invalid csv content');
13
+ Affirm_1.default.hasValue(csv.length, 'Invalid csv content length');
14
+ return this.csvLinesToJson(csv, producer);
15
+ };
16
+ this.csvLinesToJson = (lines, producer, discover) => {
17
+ var _a;
18
+ (0, Affirm_1.default)(lines, 'Invalid csv lines');
19
+ Affirm_1.default.hasValue(lines.length, 'Invalid csv lines length');
20
+ const delimiterChar = (_a = producer.settings.delimiter) !== null && _a !== void 0 ? _a : ',';
21
+ const { header, records } = this._getClassifiedRows(lines, delimiterChar, producer);
22
+ const headerColumns = this._extractHeader(header, delimiterChar, producer, discover);
23
+ const rows = records.map(x => x.split(delimiterChar).map(k => k.trim()));
24
+ const result = [];
25
+ for (const row of rows) {
26
+ const rowObject = {};
27
+ for (let i = 0; i < headerColumns.length; i++) {
28
+ const column = headerColumns[i];
29
+ rowObject[column.saveAs] = row[column.index];
30
+ }
31
+ result.push(rowObject);
32
+ }
33
+ return result;
34
+ };
35
+ this._getClassifiedRows = (lines, delimiterChar, producer) => {
36
+ if (producer.settings.fileType === 'TXT' && !producer.settings.hasHeaderRow) {
37
+ // If the file is a TXT and there isn't an header row, then I add a fake one that maps directly to the producer
38
+ const source = Environment_1.default.getSource(producer.source);
39
+ const columns = FileCompiler_1.default.compileProducer(producer, source);
40
+ return {
41
+ header: columns.map(x => x.nameInProducer).join(delimiterChar),
42
+ records: lines
43
+ };
44
+ }
45
+ else {
46
+ return {
47
+ header: lines[0],
48
+ records: lines.slice(1)
49
+ };
50
+ }
51
+ };
52
+ this._extractHeader = (headerLine, delimiter, producer, discover) => {
53
+ var _a;
54
+ (0, Affirm_1.default)(headerLine, `Invalid CSV header line for producer "${producer.name}"`);
55
+ (0, Affirm_1.default)(delimiter, 'Invalid CSV delimiter');
56
+ (0, Affirm_1.default)(producer, 'Invalid producer');
57
+ const source = Environment_1.default.getSource(producer.source);
58
+ const columns = FileCompiler_1.default.compileProducer(producer, source);
59
+ const headerColumns = headerLine.split(delimiter).map(x => x.trim());
60
+ // If I'm discovering the file, then it means that the dimensions are not set, so I use the ones that I get from the file directly
61
+ if (discover)
62
+ columns.push(...headerColumns.map(x => ({ nameInProducer: x })));
63
+ const csvColumns = [];
64
+ for (const pColumn of columns) {
65
+ const columnKey = (_a = pColumn.aliasInProducer) !== null && _a !== void 0 ? _a : pColumn.nameInProducer;
66
+ const csvColumnIndex = headerColumns.findIndex(x => x === columnKey);
67
+ (0, Affirm_1.default)(csvColumnIndex > -1, `The column "${pColumn.nameInProducer}" (with key "${columnKey}") of producer "${producer.name}" doesn't exist in the underlying dataset.`);
68
+ csvColumns.push({ index: csvColumnIndex, name: columnKey, saveAs: pColumn.nameInProducer });
69
+ }
70
+ return csvColumns;
71
+ };
72
+ }
73
+ }
74
+ const ParseManager = new ParseManagerClass();
75
+ exports.default = ParseManager;
@@ -0,0 +1,59 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const fast_xml_parser_1 = require("fast-xml-parser");
7
+ const Affirm_1 = __importDefault(require("../../core/Affirm"));
8
+ const DEFAULT_OPTIONS = {
9
+ attributeNamePrefix: '@_',
10
+ ignoreAttributes: false,
11
+ parseAttributeValue: true,
12
+ parseTagValue: true,
13
+ trimValues: true,
14
+ isArray: () => {
15
+ return false;
16
+ }
17
+ };
18
+ class XMLParserClass {
19
+ constructor(options) {
20
+ this.xmlToJson = (xmlData) => {
21
+ (0, Affirm_1.default)(xmlData, 'XML data cannot be empty');
22
+ try {
23
+ const parsedData = this._parser.parse(xmlData);
24
+ if (typeof parsedData === 'object' && parsedData !== null) {
25
+ const rootKeys = Object.keys(parsedData);
26
+ if (rootKeys.length === 1) {
27
+ const potentialArray = parsedData[rootKeys[0]];
28
+ if (Array.isArray(potentialArray)) {
29
+ return potentialArray;
30
+ }
31
+ if (typeof potentialArray === 'object' && potentialArray !== null) {
32
+ const innerKeys = Object.keys(potentialArray);
33
+ if (innerKeys.length === 1 && Array.isArray(potentialArray[innerKeys[0]])) {
34
+ return potentialArray[innerKeys[0]];
35
+ }
36
+ if (Array.isArray(potentialArray)) {
37
+ return potentialArray;
38
+ }
39
+ const values = Object.values(potentialArray).filter(Array.isArray);
40
+ if (values.length === 1 && Array.isArray(values[0])) {
41
+ return values[0];
42
+ }
43
+ return [potentialArray];
44
+ }
45
+ return [potentialArray];
46
+ }
47
+ }
48
+ return parsedData;
49
+ }
50
+ catch (error) {
51
+ console.error('Error parsing XML:', error);
52
+ throw new Error('Failed to parse XML data.');
53
+ }
54
+ };
55
+ this._parser = new fast_xml_parser_1.XMLParser(Object.assign(Object.assign({}, DEFAULT_OPTIONS), options)); // Use 'as any' if type issues persist with library
56
+ }
57
+ }
58
+ const XMLParser = new XMLParserClass();
59
+ exports.default = XMLParser;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@forzalabs/remora",
3
- "version": "0.0.28",
3
+ "version": "0.0.30",
4
4
  "description": "A powerful CLI tool for seamless data translation.",
5
5
  "main": "index.js",
6
6
  "private": false,
@@ -43,6 +43,7 @@
43
43
  "commander": "^10.0.0",
44
44
  "cross-env": "^7.0.3",
45
45
  "dotenv": "^16.0.3",
46
+ "fast-xml-parser": "^5.2.3",
46
47
  "fs-extra": "^11.1.0",
47
48
  "inquirer": "^8.2.5",
48
49
  "json-schema": "^0.4.0",
@@ -54,6 +55,7 @@
54
55
  "ora": "^5.4.1",
55
56
  "react": "^18.2.0",
56
57
  "react-dom": "^18.2.0",
58
+ "seedrandom": "^3.0.5",
57
59
  "xlsx": "^0.18.5",
58
60
  "zod": "^3.24.2"
59
61
  },