@forzalabs/remora 1.0.21 → 1.1.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.
Files changed (111) hide show
  1. package/actions/automap.js +26 -42
  2. package/actions/compile.js +27 -43
  3. package/actions/create_consumer.js +24 -40
  4. package/actions/create_producer.js +16 -32
  5. package/actions/debug.js +18 -34
  6. package/actions/deploy.js +30 -46
  7. package/actions/discover.js +13 -29
  8. package/actions/init.js +29 -45
  9. package/actions/mock.js +16 -32
  10. package/actions/run.js +34 -52
  11. package/actions/sample.js +42 -58
  12. package/index.js +38 -43
  13. package/package.json +4 -4
  14. package/workers/ExecutorWorker.js +18 -32
  15. package/Constants.js +0 -34
  16. package/core/Affirm.js +0 -42
  17. package/core/Algo.js +0 -160
  18. package/core/dste/DSTE.js +0 -113
  19. package/core/logger/DebugLogService.js +0 -48
  20. package/core/logger/DevelopmentLogService.js +0 -70
  21. package/core/logger/LocalLogService.js +0 -70
  22. package/core/logger/Logger.js +0 -54
  23. package/database/DatabaseEngine.js +0 -149
  24. package/database/DatabaseStructure.js +0 -27
  25. package/definitions/DatasetDefinitions.js +0 -2
  26. package/definitions/ExecutorDefinitions.js +0 -2
  27. package/definitions/ProcessENV.js +0 -2
  28. package/definitions/agents/DestinationDriver.js +0 -2
  29. package/definitions/agents/SourceDriver.js +0 -2
  30. package/definitions/cli.js +0 -2
  31. package/definitions/database/ApiKeys.js +0 -2
  32. package/definitions/database/Stored.js +0 -7
  33. package/definitions/database/UsageStat.js +0 -2
  34. package/definitions/database/User.js +0 -2
  35. package/definitions/json_schemas/consumer-schema.json +0 -1226
  36. package/definitions/json_schemas/producer-schema.json +0 -308
  37. package/definitions/json_schemas/project-schema.json +0 -100
  38. package/definitions/json_schemas/source-schema.json +0 -249
  39. package/definitions/requests/ConsumerRequest.js +0 -2
  40. package/definitions/requests/Developer.js +0 -2
  41. package/definitions/requests/Mapping.js +0 -2
  42. package/definitions/requests/ProducerRequest.js +0 -2
  43. package/definitions/requests/Request.js +0 -2
  44. package/definitions/resources/Compiled.js +0 -2
  45. package/definitions/resources/Consumer.js +0 -2
  46. package/definitions/resources/Environment.js +0 -2
  47. package/definitions/resources/Library.js +0 -2
  48. package/definitions/resources/Producer.js +0 -2
  49. package/definitions/resources/Project.js +0 -2
  50. package/definitions/resources/Schema.js +0 -2
  51. package/definitions/resources/Source.js +0 -2
  52. package/definitions/temp.js +0 -2
  53. package/definitions/transform/Transformations.js +0 -2
  54. package/drivers/DeltaShareDriver.js +0 -186
  55. package/drivers/DriverFactory.js +0 -72
  56. package/drivers/DriverHelper.js +0 -248
  57. package/drivers/HttpApiDriver.js +0 -208
  58. package/drivers/RedshiftDriver.js +0 -184
  59. package/drivers/files/LocalDestinationDriver.js +0 -146
  60. package/drivers/files/LocalSourceDriver.js +0 -405
  61. package/drivers/s3/S3DestinationDriver.js +0 -197
  62. package/drivers/s3/S3SourceDriver.js +0 -495
  63. package/engines/CryptoEngine.js +0 -75
  64. package/engines/Environment.js +0 -170
  65. package/engines/ProcessENVManager.js +0 -83
  66. package/engines/RandomEngine.js +0 -47
  67. package/engines/SecretManager.js +0 -23
  68. package/engines/UserManager.js +0 -66
  69. package/engines/ai/AutoMapperEngine.js +0 -37
  70. package/engines/ai/DeveloperEngine.js +0 -497
  71. package/engines/ai/LLM.js +0 -255
  72. package/engines/consumer/ConsumerManager.js +0 -218
  73. package/engines/consumer/ConsumerOnFinishManager.js +0 -202
  74. package/engines/dataset/Dataset.js +0 -824
  75. package/engines/dataset/DatasetManager.js +0 -211
  76. package/engines/dataset/DatasetRecord.js +0 -120
  77. package/engines/dataset/DatasetRecordPool.js +0 -77
  78. package/engines/execution/RequestExecutor.js +0 -67
  79. package/engines/parsing/CSVParser.js +0 -60
  80. package/engines/parsing/LineParser.js +0 -71
  81. package/engines/parsing/ParseCompression.js +0 -101
  82. package/engines/parsing/ParseHelper.js +0 -18
  83. package/engines/parsing/ParseManager.js +0 -54
  84. package/engines/parsing/XLSParser.js +0 -87
  85. package/engines/parsing/XMLParser.js +0 -115
  86. package/engines/producer/ProducerEngine.js +0 -127
  87. package/engines/producer/ProducerManager.js +0 -43
  88. package/engines/scheduler/CronScheduler.js +0 -222
  89. package/engines/scheduler/QueueManager.js +0 -314
  90. package/engines/schema/SchemaValidator.js +0 -67
  91. package/engines/transform/JoinEngine.js +0 -232
  92. package/engines/transform/TransformationEngine.js +0 -277
  93. package/engines/transform/TypeCaster.js +0 -59
  94. package/engines/usage/DataframeManager.js +0 -55
  95. package/engines/usage/UsageDataManager.js +0 -151
  96. package/engines/usage/UsageManager.js +0 -65
  97. package/engines/validation/Validator.js +0 -216
  98. package/executors/ConsumerExecutor.js +0 -280
  99. package/executors/Executor.js +0 -177
  100. package/executors/ExecutorOrchestrator.js +0 -331
  101. package/executors/ExecutorPerformance.js +0 -17
  102. package/executors/ExecutorProgress.js +0 -54
  103. package/executors/ExecutorScope.js +0 -52
  104. package/executors/OutputExecutor.js +0 -118
  105. package/executors/ProducerExecutor.js +0 -108
  106. package/helper/Helper.js +0 -149
  107. package/helper/Logger.js +0 -84
  108. package/helper/Runtime.js +0 -20
  109. package/helper/Settings.js +0 -13
  110. package/licencing/LicenceManager.js +0 -64
  111. package/settings.js +0 -12
@@ -1,405 +0,0 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || (function () {
19
- var ownKeys = function(o) {
20
- ownKeys = Object.getOwnPropertyNames || function (o) {
21
- var ar = [];
22
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
- return ar;
24
- };
25
- return ownKeys(o);
26
- };
27
- return function (mod) {
28
- if (mod && mod.__esModule) return mod;
29
- var result = {};
30
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
- __setModuleDefault(result, mod);
32
- return result;
33
- };
34
- })();
35
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
36
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
37
- return new (P || (P = Promise))(function (resolve, reject) {
38
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
39
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
40
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
41
- step((generator = generator.apply(thisArg, _arguments || [])).next());
42
- });
43
- };
44
- var __asyncValues = (this && this.__asyncValues) || function (o) {
45
- if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
46
- var m = o[Symbol.asyncIterator], i;
47
- return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i);
48
- function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }
49
- function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }
50
- };
51
- var __importDefault = (this && this.__importDefault) || function (mod) {
52
- return (mod && mod.__esModule) ? mod : { "default": mod };
53
- };
54
- Object.defineProperty(exports, "__esModule", { value: true });
55
- const fs = __importStar(require("fs"));
56
- const path_1 = __importDefault(require("path"));
57
- const readline_1 = __importDefault(require("readline"));
58
- const Affirm_1 = __importDefault(require("../../core/Affirm"));
59
- const Algo_1 = __importDefault(require("../../core/Algo"));
60
- const xlsx_1 = __importDefault(require("xlsx"));
61
- const XMLParser_1 = __importDefault(require("../../engines/parsing/XMLParser")); // Added XMLParser import
62
- const XLSParser_1 = __importDefault(require("../../engines/parsing/XLSParser"));
63
- const Helper_1 = __importDefault(require("../../helper/Helper"));
64
- const ParseHelper_1 = __importDefault(require("../../engines/parsing/ParseHelper"));
65
- const Logger_1 = __importDefault(require("../../helper/Logger"));
66
- const DriverHelper_1 = __importDefault(require("../DriverHelper"));
67
- const ExecutorScope_1 = __importDefault(require("../../executors/ExecutorScope"));
68
- const ParseCompression_1 = __importDefault(require("../../engines/parsing/ParseCompression"));
69
- class LocalSourceDriver {
70
- constructor() {
71
- this.init = (source) => __awaiter(this, void 0, void 0, function* () {
72
- const fileURL = source.authentication['path'];
73
- (0, Affirm_1.default)(fileURL, `Missing file path in the authentication of source "${source.name}"`);
74
- const exist = fs.existsSync(fileURL);
75
- (0, Affirm_1.default)(exist, `The path (${fileURL}) for source "${source.name}" does NOT exist.`);
76
- this._path = source.authentication['path'];
77
- return this;
78
- });
79
- this.readAll = (request) => __awaiter(this, void 0, void 0, function* () {
80
- (0, Affirm_1.default)(this._path, `Invalid path`);
81
- (0, Affirm_1.default)(request, `Invalid download request`);
82
- (0, Affirm_1.default)(request.fileKey, `Invalid file key for download request`);
83
- (0, Affirm_1.default)(request.fileType, `Invalid file type for download request`);
84
- const { fileKey } = request;
85
- if (fileKey.includes('%')) {
86
- const allFileKeys = this.listFiles(fileKey);
87
- Logger_1.default.log(`Matched ${allFileKeys.length} files, copying to locally and creating unified dataset.`);
88
- const firstPath = path_1.default.join(this._path, allFileKeys[0]);
89
- const headerLine = (yield DriverHelper_1.default.quickReadFile(firstPath, 1))[0];
90
- const promises = allFileKeys.map((x, i) => this._get(Object.assign(Object.assign({}, request), { fileKey: x }), headerLine, i));
91
- const results = yield Promise.all(promises);
92
- return results.flat();
93
- }
94
- else {
95
- return yield this._get(request, '');
96
- }
97
- });
98
- this.readLinesInRange = (request) => __awaiter(this, void 0, void 0, function* () {
99
- (0, Affirm_1.default)(this._path, `Invalid path`);
100
- (0, Affirm_1.default)(request, 'Invalid read options');
101
- (0, Affirm_1.default)(request.fileKey, 'Invalid file key');
102
- (0, Affirm_1.default)(request.fileType, `Invalid file type`);
103
- (0, Affirm_1.default)(request.options, `Invalid request options`);
104
- Affirm_1.default.hasValue(request.options.lineFrom, `Invalid request options line from`);
105
- Affirm_1.default.hasValue(request.options.lineTo, `Invalid request options line to`);
106
- const { fileKey } = request;
107
- if (fileKey.includes('%')) {
108
- const allFileKeys = this.listFiles(fileKey);
109
- Logger_1.default.log(`Matched ${allFileKeys.length} files, copying to locally and creating unified dataset.`);
110
- const firstPath = path_1.default.join(this._path, allFileKeys[0]);
111
- const headerLine = (yield DriverHelper_1.default.quickReadFile(firstPath, 1))[0];
112
- const promises = allFileKeys.map((x, i) => this._get(Object.assign(Object.assign({}, request), { fileKey: x }), headerLine, i));
113
- const results = yield Promise.all(promises);
114
- return results.flat();
115
- }
116
- else {
117
- return yield this._get(request, '');
118
- }
119
- });
120
- this.download = (dataset) => __awaiter(this, void 0, void 0, function* () {
121
- (0, Affirm_1.default)(this._path, `Invalid path`);
122
- (0, Affirm_1.default)(dataset, `Invalid dataset`);
123
- const file = dataset.getFile();
124
- (0, Affirm_1.default)(file, 'Invalid dataset file');
125
- (0, Affirm_1.default)(file.fileKey, 'Invalid file key');
126
- (0, Affirm_1.default)(file.fileType, `Invalid file type`);
127
- const includeSourceFilename = file.includeSourceFilename === true;
128
- const copyLocally = (fileKey_1, headerLine_1, ...args_1) => __awaiter(this, [fileKey_1, headerLine_1, ...args_1], void 0, function* (fileKey, headerLine, appendMode = false, sourceFilename, stream) {
129
- const sourceFilePath = path_1.default.join(this._path, fileKey);
130
- (0, Affirm_1.default)(fs.existsSync(sourceFilePath), `Source file does not exist: ${sourceFilePath}`);
131
- // Copy and validate header in a single stream pass
132
- const readStream = fs.createReadStream(sourceFilePath);
133
- let streamToUse = readStream;
134
- if (['XLS', 'XLSX'].includes(file.fileType))
135
- streamToUse = stream;
136
- else
137
- streamToUse = readStream;
138
- return DriverHelper_1.default.appendToUnifiedFile({
139
- stream: streamToUse,
140
- fileKey,
141
- destinationPath: dataset.getPath(),
142
- append: appendMode,
143
- headerLine,
144
- fileType: file.fileType,
145
- hasHeaderRow: file.hasHeaderRow,
146
- delimiter: dataset.getDelimiter(),
147
- sourceFilename
148
- });
149
- });
150
- // this function copy the local file on the temporary file and retrive the number of line.
151
- const handleFileAndGetLineCount = (fileKey, appendMode, fileType, sourceFilename) => __awaiter(this, void 0, void 0, function* () {
152
- let totalLineCount;
153
- let streamXLS;
154
- switch (fileType) {
155
- case 'XLS':
156
- case 'XLSX':
157
- streamXLS = (yield XLSParser_1.default.getStreamXls(path_1.default.join(this._path, fileKey), file.sheetName));
158
- totalLineCount = yield copyLocally(fileKey, dataset.getFirstLine(), appendMode, sourceFilename, streamXLS);
159
- break;
160
- default:
161
- totalLineCount = yield copyLocally(fileKey, dataset.getFirstLine(), appendMode, sourceFilename);
162
- break;
163
- }
164
- return totalLineCount;
165
- });
166
- const { fileKey } = file;
167
- let totalLineCount = 0;
168
- let sourceFilename;
169
- if (fileKey.includes('%')) {
170
- const allFileKeys = this.listFiles(fileKey);
171
- yield DriverHelper_1.default.setHeaderFromFile(allFileKeys[0], file, this._path, dataset);
172
- Logger_1.default.log(`Matched ${allFileKeys.length} files, copying locally and creating unified dataset.`);
173
- Affirm_1.default.hasItems(allFileKeys, `The file key "${fileKey}" doesn't have any matches in path "${this._path}".`);
174
- totalLineCount = 0;
175
- // Copy files sequentially to avoid file conflicts
176
- for (let i = 0; i < allFileKeys.length; i++) {
177
- const currentFileKey = allFileKeys[i];
178
- // Pass the filename (just the basename) if includeSourceFilename is enabled
179
- const sourceFilename = includeSourceFilename ? path_1.default.basename(currentFileKey) : undefined;
180
- totalLineCount += yield handleFileAndGetLineCount(currentFileKey, i > 0, file.fileType, sourceFilename); // Append mode for subsequent files
181
- }
182
- dataset.setCount(totalLineCount);
183
- return dataset;
184
- }
185
- else {
186
- sourceFilename = includeSourceFilename ? path_1.default.basename(fileKey) : undefined;
187
- yield DriverHelper_1.default.setHeaderFromFile(fileKey, file, this._path, dataset);
188
- totalLineCount = (yield handleFileAndGetLineCount(fileKey, false, file.fileType, sourceFilename));
189
- dataset.setCount(totalLineCount);
190
- return dataset;
191
- }
192
- });
193
- this.exist = (producer) => __awaiter(this, void 0, void 0, function* () {
194
- (0, Affirm_1.default)(this._path, `Invalid path`);
195
- (0, Affirm_1.default)(producer, `Invalid producer`);
196
- const fileKey = producer.settings.fileKey;
197
- (0, Affirm_1.default)(fileKey, `Invalid file key for download request`);
198
- if (fileKey.includes('%')) {
199
- const allFileKeys = this.listFiles(fileKey);
200
- return allFileKeys.length > 0;
201
- }
202
- else {
203
- const fileUrl = path_1.default.join(this._path, fileKey);
204
- return fs.existsSync(fileUrl);
205
- }
206
- });
207
- this._readLines = (fileUri, lineFrom, lineTo) => __awaiter(this, void 0, void 0, function* () {
208
- var _a, e_1, _b, _c;
209
- const stream = fs.createReadStream(fileUri);
210
- const reader = readline_1.default.createInterface({ input: stream, crlfDelay: Infinity });
211
- const lines = [];
212
- let lineCounter = 0;
213
- try {
214
- for (var _d = true, reader_1 = __asyncValues(reader), reader_1_1; reader_1_1 = yield reader_1.next(), _a = reader_1_1.done, !_a; _d = true) {
215
- _c = reader_1_1.value;
216
- _d = false;
217
- const line = _c;
218
- if (Algo_1.default.hasVal(lineFrom) && Algo_1.default.hasVal(lineTo)) {
219
- if (lineCounter >= lineFrom && lineCounter < lineTo) {
220
- if (line && line.length > 0)
221
- lines.push(line);
222
- }
223
- lineCounter++;
224
- if (lineCounter >= lineTo)
225
- break;
226
- }
227
- else {
228
- if (line && line.length > 0)
229
- lines.push(line);
230
- }
231
- }
232
- }
233
- catch (e_1_1) { e_1 = { error: e_1_1 }; }
234
- finally {
235
- try {
236
- if (!_d && !_a && (_b = reader_1.return)) yield _b.call(reader_1);
237
- }
238
- finally { if (e_1) throw e_1.error; }
239
- }
240
- reader.close();
241
- stream.close();
242
- return lines;
243
- });
244
- this._readExcelLines = (fileUri, sheetName, lineFrom, lineTo) => __awaiter(this, void 0, void 0, function* () {
245
- const excel = xlsx_1.default.readFile(fileUri);
246
- let targetSheetName = sheetName;
247
- if (!targetSheetName) {
248
- (0, Affirm_1.default)(excel.SheetNames.length > 0, 'The Excel file has no sheets.');
249
- targetSheetName = excel.SheetNames[0];
250
- }
251
- else {
252
- (0, Affirm_1.default)(excel.SheetNames.includes(targetSheetName), `The sheet "${targetSheetName}" doesn't exist in the excel (available: ${excel.SheetNames.join(', ')})`);
253
- }
254
- const sheet = excel.Sheets[targetSheetName];
255
- const csv = xlsx_1.default.utils.sheet_to_csv(sheet);
256
- const lines = csv.split('\n');
257
- if (Algo_1.default.hasVal(lineFrom) && Algo_1.default.hasVal(lineTo))
258
- return lines.slice(lineFrom, lineTo + 1);
259
- else
260
- return lines;
261
- });
262
- this._readXmlLines = (fileUri, lineFrom, lineTo) => __awaiter(this, void 0, void 0, function* () {
263
- const fileContent = fs.readFileSync(fileUri, 'utf-8');
264
- const jsonData = XMLParser_1.default.xmlToJson(fileContent);
265
- // Convert JSON data to string lines. This might need adjustment based on XML structure.
266
- // Assuming jsonData is an array of objects, where each object is a record.
267
- let lines = Array.isArray(jsonData) ? jsonData.map(item => JSON.stringify(item)) : [JSON.stringify(jsonData)];
268
- if (Algo_1.default.hasVal(lineFrom) && Algo_1.default.hasVal(lineTo)) {
269
- lines = lines.slice(lineFrom, lineTo + 1);
270
- }
271
- return lines;
272
- });
273
- this._get = (request, headerLine, index) => __awaiter(this, void 0, void 0, function* () {
274
- const { fileKey, fileType, options } = request;
275
- let lineFrom, lineTo, sheetName, hasHeaderRow;
276
- if (options) {
277
- lineFrom = options.lineFrom;
278
- lineTo = options.lineTo;
279
- sheetName = options.sheetName;
280
- hasHeaderRow = options.hasHeaderRow;
281
- }
282
- const fileUrl = path_1.default.join(this._path, fileKey);
283
- let lines = [];
284
- switch (fileType) {
285
- case 'CSV':
286
- case 'JSON':
287
- case 'JSONL':
288
- case 'TXT':
289
- if (Algo_1.default.hasVal(lineFrom) && Algo_1.default.hasVal(lineTo))
290
- lines = yield this._readLines(fileUrl, lineFrom, lineTo);
291
- else
292
- lines = yield this._readLines(fileUrl);
293
- break;
294
- case 'XLS':
295
- case 'XLSX':
296
- if (Algo_1.default.hasVal(lineFrom) && Algo_1.default.hasVal(lineTo))
297
- lines = yield this._readExcelLines(fileUrl, sheetName, lineFrom, lineTo);
298
- else
299
- lines = yield this._readExcelLines(fileUrl, sheetName);
300
- break;
301
- case 'XML':
302
- if (Algo_1.default.hasVal(lineFrom) && Algo_1.default.hasVal(lineTo))
303
- lines = yield this._readXmlLines(fileUrl, lineFrom, lineTo);
304
- else
305
- lines = yield this._readXmlLines(fileUrl);
306
- break;
307
- }
308
- const firstLine = lines[0];
309
- if (headerLine && headerLine.trim() !== '' && firstLine.trim() !== headerLine.trim()) {
310
- const msg = `Error creating unified dataset: file "${fileKey}" has a different header line than the other files in this dataset\n\t-${fileKey}: ${firstLine}\n\t-main: ${headerLine}`;
311
- Logger_1.default.log(msg);
312
- throw new Error(msg);
313
- }
314
- // If this is not the first file read in a pattern match AND the file type has an header,
315
- // then I need to remove the header from the resulting lines or the header will be duplicated
316
- if (index > 0 && ParseHelper_1.default.shouldHaveHeader(fileType, hasHeaderRow)) {
317
- lines = lines.slice(1);
318
- }
319
- return lines;
320
- });
321
- this.listFiles = (filekeyPattern) => {
322
- (0, Affirm_1.default)(this._path, 'Path not initialized');
323
- try {
324
- // Get all files in the directory (recursively if needed)
325
- const getAllFiles = (dirPath, basePath = '') => {
326
- const files = [];
327
- const items = fs.readdirSync(dirPath);
328
- for (const item of items) {
329
- const fullPath = path_1.default.join(dirPath, item);
330
- const relativePath = basePath ? path_1.default.join(basePath, item) : item;
331
- const stats = fs.statSync(fullPath);
332
- if (stats.isDirectory()) {
333
- // Recursively get files from subdirectories
334
- files.push(...getAllFiles(fullPath, relativePath));
335
- }
336
- else if (stats.isFile()) {
337
- files.push(relativePath);
338
- }
339
- }
340
- return files;
341
- };
342
- const allFiles = getAllFiles(this._path);
343
- return Helper_1.default.matchPattern(filekeyPattern, allFiles);
344
- }
345
- catch (error) {
346
- throw new Error(`Failed to list files in directory "${this._path}": ${error.message}`);
347
- }
348
- };
349
- this.readFile = (fileKey) => {
350
- (0, Affirm_1.default)(this._path, 'Path not initialized');
351
- (0, Affirm_1.default)(fileKey, 'Invalid file key');
352
- const filePath = path_1.default.join(this._path, fileKey);
353
- (0, Affirm_1.default)(fs.existsSync(filePath), `Source file does not exist: ${filePath}`);
354
- return fs.readFileSync(filePath);
355
- };
356
- this.deleteFile = (fileKey) => {
357
- (0, Affirm_1.default)(this._path, 'Path not initialized');
358
- (0, Affirm_1.default)(fileKey, 'Invalid file key');
359
- const filePath = path_1.default.join(this._path, fileKey);
360
- if (fs.existsSync(filePath)) {
361
- fs.unlinkSync(filePath);
362
- }
363
- };
364
- this.moveFile = (sourceFileKey, destinationPath, destinationFileKey) => {
365
- (0, Affirm_1.default)(this._path, 'Path not initialized');
366
- (0, Affirm_1.default)(sourceFileKey, 'Invalid source file key');
367
- (0, Affirm_1.default)(destinationPath, 'Invalid destination path');
368
- (0, Affirm_1.default)(destinationFileKey, 'Invalid destination file key');
369
- const sourceFilePath = path_1.default.join(this._path, sourceFileKey);
370
- const destinationFilePath = path_1.default.join(destinationPath, destinationFileKey);
371
- (0, Affirm_1.default)(fs.existsSync(sourceFilePath), `Source file does not exist: ${sourceFilePath}`);
372
- // Ensure destination directory exists
373
- const destinationDir = path_1.default.dirname(destinationFilePath);
374
- if (!fs.existsSync(destinationDir)) {
375
- fs.mkdirSync(destinationDir, { recursive: true });
376
- }
377
- fs.renameSync(sourceFilePath, destinationFilePath);
378
- };
379
- this.ready = (request) => __awaiter(this, void 0, void 0, function* () {
380
- (0, Affirm_1.default)(request, 'Invalid ready request');
381
- const { producer, scope } = request;
382
- // TODO: extra logic for encoded files (xml, xls, ...) to be decoded and prepared locally as a plain CSV
383
- // then return the uri to this new temporary file
384
- const { fileKey, compressionType } = producer.settings;
385
- if (fileKey.includes('%')) {
386
- const allFileKeys = this.listFiles(fileKey);
387
- const allFilePaths = [];
388
- for (const fileKey of allFileKeys) {
389
- const executionPath = ExecutorScope_1.default.getProducerPath(scope, producer, fileKey);
390
- ExecutorScope_1.default.ensurePath(executionPath);
391
- const localPath = yield ParseCompression_1.default.decompressToFile(compressionType, fileKey, this._path, executionPath);
392
- allFilePaths.push(localPath);
393
- }
394
- return { files: allFilePaths.map(x => ({ fullUri: x })) };
395
- }
396
- else {
397
- const executionPath = ExecutorScope_1.default.getProducerPath(scope, producer, fileKey);
398
- ExecutorScope_1.default.ensurePath(executionPath);
399
- const localPath = yield ParseCompression_1.default.decompressToFile(compressionType, fileKey, this._path, executionPath);
400
- return { files: [{ fullUri: localPath }] };
401
- }
402
- });
403
- }
404
- }
405
- exports.default = LocalSourceDriver;
@@ -1,197 +0,0 @@
1
- "use strict";
2
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
- return new (P || (P = Promise))(function (resolve, reject) {
5
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
- step((generator = generator.apply(thisArg, _arguments || [])).next());
9
- });
10
- };
11
- var __asyncValues = (this && this.__asyncValues) || function (o) {
12
- if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
13
- var m = o[Symbol.asyncIterator], i;
14
- return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i);
15
- function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }
16
- function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }
17
- };
18
- var __await = (this && this.__await) || function (v) { return this instanceof __await ? (this.v = v, this) : new __await(v); }
19
- var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) {
20
- if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
21
- var g = generator.apply(thisArg, _arguments || []), i, q = [];
22
- return i = Object.create((typeof AsyncIterator === "function" ? AsyncIterator : Object).prototype), verb("next"), verb("throw"), verb("return", awaitReturn), i[Symbol.asyncIterator] = function () { return this; }, i;
23
- function awaitReturn(f) { return function (v) { return Promise.resolve(v).then(f, reject); }; }
24
- function verb(n, f) { if (g[n]) { i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; if (f) i[n] = f(i[n]); } }
25
- function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }
26
- function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }
27
- function fulfill(value) { resume("next", value); }
28
- function reject(value) { resume("throw", value); }
29
- function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }
30
- };
31
- var __importDefault = (this && this.__importDefault) || function (mod) {
32
- return (mod && mod.__esModule) ? mod : { "default": mod };
33
- };
34
- Object.defineProperty(exports, "__esModule", { value: true });
35
- const client_s3_1 = require("@aws-sdk/client-s3");
36
- const Affirm_1 = __importDefault(require("../../core/Affirm"));
37
- const SecretManager_1 = __importDefault(require("../../engines/SecretManager"));
38
- const path_1 = __importDefault(require("path"));
39
- const fs_1 = __importDefault(require("fs"));
40
- const readline_1 = __importDefault(require("readline"));
41
- class S3DestinationDriver {
42
- constructor() {
43
- this.init = (source) => __awaiter(this, void 0, void 0, function* () {
44
- this._bucketName = source.authentication['bucket'];
45
- const sessionToken = SecretManager_1.default.replaceSecret(source.authentication['sessionToken']);
46
- const config = {
47
- region: source.authentication['region'],
48
- credentials: {
49
- accessKeyId: SecretManager_1.default.replaceSecret(source.authentication['accessKey']),
50
- secretAccessKey: SecretManager_1.default.replaceSecret(source.authentication['secretKey']),
51
- sessionToken: sessionToken ? sessionToken : undefined
52
- }
53
- };
54
- this._client = new client_s3_1.S3Client(config);
55
- // TODO: is there a way to test if the connection was successful? like a query or scan that I can do?
56
- return this;
57
- });
58
- this.copyFromS3 = (sourceBucket, sourceFileKey, destinationFileKey) => __awaiter(this, void 0, void 0, function* () {
59
- (0, Affirm_1.default)(this._client, 'S3 client not yet initialized, call "init()" first');
60
- (0, Affirm_1.default)(sourceBucket, 'Invalid source bucket');
61
- (0, Affirm_1.default)(sourceFileKey, 'Invalid source file key');
62
- (0, Affirm_1.default)(destinationFileKey, 'Invalid destination file key');
63
- yield this._client.send(new client_s3_1.CopyObjectCommand({
64
- CopySource: `${sourceBucket}/${sourceFileKey}`,
65
- Bucket: this._bucketName,
66
- Key: destinationFileKey
67
- }));
68
- });
69
- this.saveFile = (fileKey, content) => __awaiter(this, void 0, void 0, function* () {
70
- (0, Affirm_1.default)(this._client, 'S3 client not yet initialized, call "init()" first');
71
- (0, Affirm_1.default)(fileKey, 'Invalid file key');
72
- (0, Affirm_1.default)(content, 'Invalid content');
73
- yield this._client.send(new client_s3_1.PutObjectCommand({
74
- Bucket: this._bucketName,
75
- Key: fileKey,
76
- Body: content
77
- }));
78
- });
79
- this.move = (fromPath, toName) => __awaiter(this, void 0, void 0, function* () {
80
- (0, Affirm_1.default)(fromPath, 'Invalid source path');
81
- (0, Affirm_1.default)(toName, 'Invalid destination name');
82
- (0, Affirm_1.default)(fs_1.default.existsSync(fromPath), `Source file does not exist: ${fromPath}`);
83
- const readStream = fs_1.default.createReadStream(fromPath);
84
- return this._multipartUpload(toName, readStream);
85
- });
86
- this.transformAndMove = (fromPath, transform, toName) => __awaiter(this, void 0, void 0, function* () {
87
- (0, Affirm_1.default)(fromPath, 'Invalid source path');
88
- (0, Affirm_1.default)(transform, 'Invalid transform function');
89
- (0, Affirm_1.default)(toName, 'Invalid destination name');
90
- (0, Affirm_1.default)(fs_1.default.existsSync(fromPath), `Source file does not exist: ${fromPath}`);
91
- const reader = fs_1.default.createReadStream(fromPath);
92
- const lineReader = readline_1.default.createInterface({ input: reader, crlfDelay: Infinity });
93
- const transformedLines = function () {
94
- return __asyncGenerator(this, arguments, function* () {
95
- var _a, e_1, _b, _c;
96
- try {
97
- for (var _d = true, lineReader_1 = __asyncValues(lineReader), lineReader_1_1; lineReader_1_1 = yield __await(lineReader_1.next()), _a = lineReader_1_1.done, !_a; _d = true) {
98
- _c = lineReader_1_1.value;
99
- _d = false;
100
- const line = _c;
101
- yield yield __await(transform(line) + '\n');
102
- }
103
- }
104
- catch (e_1_1) { e_1 = { error: e_1_1 }; }
105
- finally {
106
- try {
107
- if (!_d && !_a && (_b = lineReader_1.return)) yield __await(_b.call(lineReader_1));
108
- }
109
- finally { if (e_1) throw e_1.error; }
110
- }
111
- });
112
- };
113
- return this._multipartUpload(toName, transformedLines());
114
- });
115
- this._multipartUpload = (toName, dataSource) => __awaiter(this, void 0, void 0, function* () {
116
- var _a, dataSource_1, dataSource_1_1;
117
- var _b, e_2, _c, _d;
118
- let uploadId;
119
- try {
120
- // Create the multipart upload
121
- const createMultipartUploadRes = yield this._client.send(new client_s3_1.CreateMultipartUploadCommand({
122
- Bucket: this._bucketName,
123
- Key: toName
124
- }));
125
- uploadId = createMultipartUploadRes.UploadId;
126
- (0, Affirm_1.default)(uploadId, 'Failed to initiate multipart upload');
127
- const uploadedParts = [];
128
- let partNumber = 1;
129
- const MIN_PART_SIZE = 5 * 1024 * 1024; // 5MB
130
- let accumulatedBuffer = Buffer.alloc(0);
131
- const uploadPart = (buffer) => __awaiter(this, void 0, void 0, function* () {
132
- const uploadPartRes = yield this._client.send(new client_s3_1.UploadPartCommand({
133
- Bucket: this._bucketName,
134
- Key: toName,
135
- UploadId: uploadId,
136
- PartNumber: partNumber,
137
- Body: buffer
138
- }));
139
- uploadedParts.push({
140
- PartNumber: partNumber,
141
- ETag: uploadPartRes.ETag
142
- });
143
- partNumber++;
144
- });
145
- try {
146
- for (_a = true, dataSource_1 = __asyncValues(dataSource); dataSource_1_1 = yield dataSource_1.next(), _b = dataSource_1_1.done, !_b; _a = true) {
147
- _d = dataSource_1_1.value;
148
- _a = false;
149
- const chunk = _d;
150
- const chunkBuffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);
151
- accumulatedBuffer = Buffer.concat([accumulatedBuffer, chunkBuffer]);
152
- // If accumulated buffer is at least 5MB, upload it as a part
153
- while (accumulatedBuffer.length >= MIN_PART_SIZE) {
154
- const partBuffer = accumulatedBuffer.subarray(0, MIN_PART_SIZE);
155
- accumulatedBuffer = accumulatedBuffer.subarray(MIN_PART_SIZE);
156
- yield uploadPart(partBuffer);
157
- }
158
- }
159
- }
160
- catch (e_2_1) { e_2 = { error: e_2_1 }; }
161
- finally {
162
- try {
163
- if (!_a && !_b && (_c = dataSource_1.return)) yield _c.call(dataSource_1);
164
- }
165
- finally { if (e_2) throw e_2.error; }
166
- }
167
- // Upload any remaining data as the final part (even if smaller than 5MB)
168
- if (accumulatedBuffer.length > 0) {
169
- yield uploadPart(accumulatedBuffer);
170
- }
171
- // Complete the multipart upload
172
- const completeRes = yield this._client.send(new client_s3_1.CompleteMultipartUploadCommand({
173
- Bucket: this._bucketName,
174
- Key: toName,
175
- UploadId: uploadId,
176
- MultipartUpload: {
177
- Parts: uploadedParts
178
- }
179
- }));
180
- (0, Affirm_1.default)(completeRes.$metadata.httpStatusCode === 200, `Failed to complete multipart upload for "${toName}": status code ${completeRes.$metadata.httpStatusCode}`);
181
- return { res: true, key: path_1.default.join(this._bucketName, toName), bucket: this._bucketName };
182
- }
183
- catch (error) {
184
- // If anything fails, make sure to abort the multipart upload
185
- if (uploadId) {
186
- yield this._client.send(new client_s3_1.AbortMultipartUploadCommand({
187
- Bucket: this._bucketName,
188
- Key: toName,
189
- UploadId: uploadId
190
- }));
191
- }
192
- throw error;
193
- }
194
- });
195
- }
196
- }
197
- exports.default = S3DestinationDriver;