@forzalabs/remora 1.1.15 → 1.2.2
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/CHANGELOG.md +113 -0
- package/index.js +381 -124
- package/json_schemas/consumer-schema.json +107 -21
- package/package.json +1 -1
- package/workers/ExecutorWorker.js +371 -114
|
@@ -146,7 +146,7 @@ var require_has_flag = __commonJS({
|
|
|
146
146
|
var require_supports_colors = __commonJS({
|
|
147
147
|
"../../node_modules/logform/node_modules/@colors/colors/lib/system/supports-colors.js"(exports2, module2) {
|
|
148
148
|
"use strict";
|
|
149
|
-
var
|
|
149
|
+
var os3 = require("os");
|
|
150
150
|
var hasFlag = require_has_flag();
|
|
151
151
|
var env = process.env;
|
|
152
152
|
var forceColor = void 0;
|
|
@@ -184,7 +184,7 @@ var require_supports_colors = __commonJS({
|
|
|
184
184
|
}
|
|
185
185
|
var min = forceColor ? 1 : 0;
|
|
186
186
|
if (process.platform === "win32") {
|
|
187
|
-
var osRelease =
|
|
187
|
+
var osRelease = os3.release().split(".");
|
|
188
188
|
if (Number(process.versions.node.split(".")[0]) >= 8 && Number(osRelease[0]) >= 10 && Number(osRelease[2]) >= 10586) {
|
|
189
189
|
return Number(osRelease[2]) >= 14931 ? 3 : 2;
|
|
190
190
|
}
|
|
@@ -5428,7 +5428,7 @@ var require_winston_transport = __commonJS({
|
|
|
5428
5428
|
var require_console = __commonJS({
|
|
5429
5429
|
"../../packages/logger/node_modules/winston/lib/winston/transports/console.js"(exports2, module2) {
|
|
5430
5430
|
"use strict";
|
|
5431
|
-
var
|
|
5431
|
+
var os3 = require("os");
|
|
5432
5432
|
var { LEVEL, MESSAGE } = require_triple_beam();
|
|
5433
5433
|
var TransportStream = require_winston_transport();
|
|
5434
5434
|
module2.exports = class Console extends TransportStream {
|
|
@@ -5442,7 +5442,7 @@ var require_console = __commonJS({
|
|
|
5442
5442
|
this.name = options.name || "console";
|
|
5443
5443
|
this.stderrLevels = this._stringArrayToSet(options.stderrLevels);
|
|
5444
5444
|
this.consoleWarnLevels = this._stringArrayToSet(options.consoleWarnLevels);
|
|
5445
|
-
this.eol = typeof options.eol === "string" ? options.eol :
|
|
5445
|
+
this.eol = typeof options.eol === "string" ? options.eol : os3.EOL;
|
|
5446
5446
|
this.forceConsole = options.forceConsole || false;
|
|
5447
5447
|
this._consoleLog = console.log.bind(console);
|
|
5448
5448
|
this._consoleWarn = console.warn.bind(console);
|
|
@@ -9654,15 +9654,15 @@ var require_index_cjs = __commonJS({
|
|
|
9654
9654
|
};
|
|
9655
9655
|
}
|
|
9656
9656
|
function wrapConversion(toModel, graph) {
|
|
9657
|
-
const
|
|
9657
|
+
const path18 = [graph[toModel].parent, toModel];
|
|
9658
9658
|
let fn = convert$1[graph[toModel].parent][toModel];
|
|
9659
9659
|
let cur = graph[toModel].parent;
|
|
9660
9660
|
while (graph[cur].parent) {
|
|
9661
|
-
|
|
9661
|
+
path18.unshift(graph[cur].parent);
|
|
9662
9662
|
fn = link(convert$1[graph[cur].parent][cur], fn);
|
|
9663
9663
|
cur = graph[cur].parent;
|
|
9664
9664
|
}
|
|
9665
|
-
fn.conversion =
|
|
9665
|
+
fn.conversion = path18;
|
|
9666
9666
|
return fn;
|
|
9667
9667
|
}
|
|
9668
9668
|
function route(fromModel) {
|
|
@@ -10292,7 +10292,7 @@ var require_node2 = __commonJS({
|
|
|
10292
10292
|
var require_tail_file = __commonJS({
|
|
10293
10293
|
"../../packages/logger/node_modules/winston/lib/winston/tail-file.js"(exports2, module2) {
|
|
10294
10294
|
"use strict";
|
|
10295
|
-
var
|
|
10295
|
+
var fs19 = require("fs");
|
|
10296
10296
|
var { StringDecoder } = require("string_decoder");
|
|
10297
10297
|
var { Stream } = require_readable();
|
|
10298
10298
|
function noop() {
|
|
@@ -10313,7 +10313,7 @@ var require_tail_file = __commonJS({
|
|
|
10313
10313
|
stream.emit("end");
|
|
10314
10314
|
stream.emit("close");
|
|
10315
10315
|
};
|
|
10316
|
-
|
|
10316
|
+
fs19.open(options.file, "a+", "0644", (err, fd) => {
|
|
10317
10317
|
if (err) {
|
|
10318
10318
|
if (!iter) {
|
|
10319
10319
|
stream.emit("error", err);
|
|
@@ -10325,10 +10325,10 @@ var require_tail_file = __commonJS({
|
|
|
10325
10325
|
}
|
|
10326
10326
|
(function read() {
|
|
10327
10327
|
if (stream.destroyed) {
|
|
10328
|
-
|
|
10328
|
+
fs19.close(fd, noop);
|
|
10329
10329
|
return;
|
|
10330
10330
|
}
|
|
10331
|
-
return
|
|
10331
|
+
return fs19.read(fd, buffer, 0, buffer.length, pos, (error, bytes) => {
|
|
10332
10332
|
if (error) {
|
|
10333
10333
|
if (!iter) {
|
|
10334
10334
|
stream.emit("error", error);
|
|
@@ -10387,15 +10387,15 @@ var require_tail_file = __commonJS({
|
|
|
10387
10387
|
var require_file = __commonJS({
|
|
10388
10388
|
"../../packages/logger/node_modules/winston/lib/winston/transports/file.js"(exports2, module2) {
|
|
10389
10389
|
"use strict";
|
|
10390
|
-
var
|
|
10391
|
-
var
|
|
10390
|
+
var fs19 = require("fs");
|
|
10391
|
+
var path18 = require("path");
|
|
10392
10392
|
var asyncSeries = require_series();
|
|
10393
10393
|
var zlib2 = require("zlib");
|
|
10394
10394
|
var { MESSAGE } = require_triple_beam();
|
|
10395
10395
|
var { Stream, PassThrough } = require_readable();
|
|
10396
10396
|
var TransportStream = require_winston_transport();
|
|
10397
10397
|
var debug = require_node2()("winston:file");
|
|
10398
|
-
var
|
|
10398
|
+
var os3 = require("os");
|
|
10399
10399
|
var tailFile = require_tail_file();
|
|
10400
10400
|
module2.exports = class File extends TransportStream {
|
|
10401
10401
|
/**
|
|
@@ -10418,14 +10418,14 @@ var require_file = __commonJS({
|
|
|
10418
10418
|
this._onError = this._onError.bind(this);
|
|
10419
10419
|
if (options.filename || options.dirname) {
|
|
10420
10420
|
throwIf("filename or dirname", "stream");
|
|
10421
|
-
this._basename = this.filename = options.filename ?
|
|
10422
|
-
this.dirname = options.dirname ||
|
|
10421
|
+
this._basename = this.filename = options.filename ? path18.basename(options.filename) : "winston.log";
|
|
10422
|
+
this.dirname = options.dirname || path18.dirname(options.filename);
|
|
10423
10423
|
this.options = options.options || { flags: "a" };
|
|
10424
10424
|
} else if (options.stream) {
|
|
10425
10425
|
console.warn("options.stream will be removed in winston@4. Use winston.transports.Stream");
|
|
10426
10426
|
throwIf("stream", "filename", "maxsize");
|
|
10427
10427
|
this._dest = this._stream.pipe(this._setupStream(options.stream));
|
|
10428
|
-
this.dirname =
|
|
10428
|
+
this.dirname = path18.dirname(this._dest.path);
|
|
10429
10429
|
} else {
|
|
10430
10430
|
throw new Error("Cannot log to file without filename or stream.");
|
|
10431
10431
|
}
|
|
@@ -10433,7 +10433,7 @@ var require_file = __commonJS({
|
|
|
10433
10433
|
this.rotationFormat = options.rotationFormat || false;
|
|
10434
10434
|
this.zippedArchive = options.zippedArchive || false;
|
|
10435
10435
|
this.maxFiles = options.maxFiles || null;
|
|
10436
|
-
this.eol = typeof options.eol === "string" ? options.eol :
|
|
10436
|
+
this.eol = typeof options.eol === "string" ? options.eol : os3.EOL;
|
|
10437
10437
|
this.tailable = options.tailable || false;
|
|
10438
10438
|
this.lazy = options.lazy || false;
|
|
10439
10439
|
this._size = 0;
|
|
@@ -10588,11 +10588,11 @@ var require_file = __commonJS({
|
|
|
10588
10588
|
options = {};
|
|
10589
10589
|
}
|
|
10590
10590
|
options = normalizeQuery(options);
|
|
10591
|
-
const file =
|
|
10591
|
+
const file = path18.join(this.dirname, this.filename);
|
|
10592
10592
|
let buff = "";
|
|
10593
10593
|
let results = [];
|
|
10594
10594
|
let row = 0;
|
|
10595
|
-
const stream =
|
|
10595
|
+
const stream = fs19.createReadStream(file, {
|
|
10596
10596
|
encoding: "utf8"
|
|
10597
10597
|
});
|
|
10598
10598
|
stream.on("error", (err) => {
|
|
@@ -10693,7 +10693,7 @@ var require_file = __commonJS({
|
|
|
10693
10693
|
* TODO: Refactor me.
|
|
10694
10694
|
*/
|
|
10695
10695
|
stream(options = {}) {
|
|
10696
|
-
const file =
|
|
10696
|
+
const file = path18.join(this.dirname, this.filename);
|
|
10697
10697
|
const stream = new Stream();
|
|
10698
10698
|
const tail = {
|
|
10699
10699
|
file,
|
|
@@ -10743,8 +10743,8 @@ var require_file = __commonJS({
|
|
|
10743
10743
|
*/
|
|
10744
10744
|
stat(callback) {
|
|
10745
10745
|
const target = this._getFile();
|
|
10746
|
-
const fullpath =
|
|
10747
|
-
|
|
10746
|
+
const fullpath = path18.join(this.dirname, target);
|
|
10747
|
+
fs19.stat(fullpath, (err, stat) => {
|
|
10748
10748
|
if (err && err.code === "ENOENT") {
|
|
10749
10749
|
debug("ENOENT\xA0ok", fullpath);
|
|
10750
10750
|
this.filename = target;
|
|
@@ -10847,9 +10847,9 @@ var require_file = __commonJS({
|
|
|
10847
10847
|
* @returns {WritableStream} Stream that writes to disk for the active file.
|
|
10848
10848
|
*/
|
|
10849
10849
|
_createStream(source) {
|
|
10850
|
-
const fullpath =
|
|
10850
|
+
const fullpath = path18.join(this.dirname, this.filename);
|
|
10851
10851
|
debug("create stream start", fullpath, this.options);
|
|
10852
|
-
const dest =
|
|
10852
|
+
const dest = fs19.createWriteStream(fullpath, this.options).on("error", (err) => debug(err)).on("close", () => debug("close", dest.path, dest.bytesWritten)).on("open", () => {
|
|
10853
10853
|
debug("file open ok", fullpath);
|
|
10854
10854
|
this.emit("open", fullpath);
|
|
10855
10855
|
source.pipe(dest);
|
|
@@ -10872,16 +10872,16 @@ var require_file = __commonJS({
|
|
|
10872
10872
|
*/
|
|
10873
10873
|
_incFile(callback) {
|
|
10874
10874
|
debug("_incFile", this.filename);
|
|
10875
|
-
const ext =
|
|
10876
|
-
const basename =
|
|
10875
|
+
const ext = path18.extname(this._basename);
|
|
10876
|
+
const basename = path18.basename(this._basename, ext);
|
|
10877
10877
|
const tasks = [];
|
|
10878
10878
|
if (this.zippedArchive) {
|
|
10879
10879
|
tasks.push(
|
|
10880
10880
|
function(cb) {
|
|
10881
10881
|
const num = this._created > 0 && !this.tailable ? this._created : "";
|
|
10882
10882
|
this._compressFile(
|
|
10883
|
-
|
|
10884
|
-
|
|
10883
|
+
path18.join(this.dirname, `${basename}${num}${ext}`),
|
|
10884
|
+
path18.join(this.dirname, `${basename}${num}${ext}.gz`),
|
|
10885
10885
|
cb
|
|
10886
10886
|
);
|
|
10887
10887
|
}.bind(this)
|
|
@@ -10906,8 +10906,8 @@ var require_file = __commonJS({
|
|
|
10906
10906
|
* @private
|
|
10907
10907
|
*/
|
|
10908
10908
|
_getFile() {
|
|
10909
|
-
const ext =
|
|
10910
|
-
const basename =
|
|
10909
|
+
const ext = path18.extname(this._basename);
|
|
10910
|
+
const basename = path18.basename(this._basename, ext);
|
|
10911
10911
|
const isRotation = this.rotationFormat ? this.rotationFormat() : this._created;
|
|
10912
10912
|
return !this.tailable && this._created ? `${basename}${isRotation}${ext}` : `${basename}${ext}`;
|
|
10913
10913
|
}
|
|
@@ -10927,8 +10927,8 @@ var require_file = __commonJS({
|
|
|
10927
10927
|
const isOldest = oldest !== 0 ? oldest : "";
|
|
10928
10928
|
const isZipped = this.zippedArchive ? ".gz" : "";
|
|
10929
10929
|
const filePath = `${basename}${isOldest}${ext}${isZipped}`;
|
|
10930
|
-
const target =
|
|
10931
|
-
|
|
10930
|
+
const target = path18.join(this.dirname, filePath);
|
|
10931
|
+
fs19.unlink(target, callback);
|
|
10932
10932
|
}
|
|
10933
10933
|
/**
|
|
10934
10934
|
* Roll files forward based on integer, up to maxFiles. e.g. if base if
|
|
@@ -10950,20 +10950,20 @@ var require_file = __commonJS({
|
|
|
10950
10950
|
for (let x = this.maxFiles - 1; x > 1; x--) {
|
|
10951
10951
|
tasks.push(function(i, cb) {
|
|
10952
10952
|
let fileName = `${basename}${i - 1}${ext}${isZipped}`;
|
|
10953
|
-
const tmppath =
|
|
10954
|
-
|
|
10953
|
+
const tmppath = path18.join(this.dirname, fileName);
|
|
10954
|
+
fs19.exists(tmppath, (exists) => {
|
|
10955
10955
|
if (!exists) {
|
|
10956
10956
|
return cb(null);
|
|
10957
10957
|
}
|
|
10958
10958
|
fileName = `${basename}${i}${ext}${isZipped}`;
|
|
10959
|
-
|
|
10959
|
+
fs19.rename(tmppath, path18.join(this.dirname, fileName), cb);
|
|
10960
10960
|
});
|
|
10961
10961
|
}.bind(this, x));
|
|
10962
10962
|
}
|
|
10963
10963
|
asyncSeries(tasks, () => {
|
|
10964
|
-
|
|
10965
|
-
|
|
10966
|
-
|
|
10964
|
+
fs19.rename(
|
|
10965
|
+
path18.join(this.dirname, `${basename}${ext}${isZipped}`),
|
|
10966
|
+
path18.join(this.dirname, `${basename}1${ext}${isZipped}`),
|
|
10967
10967
|
callback
|
|
10968
10968
|
);
|
|
10969
10969
|
});
|
|
@@ -10977,22 +10977,22 @@ var require_file = __commonJS({
|
|
|
10977
10977
|
* @private
|
|
10978
10978
|
*/
|
|
10979
10979
|
_compressFile(src, dest, callback) {
|
|
10980
|
-
|
|
10980
|
+
fs19.access(src, fs19.F_OK, (err) => {
|
|
10981
10981
|
if (err) {
|
|
10982
10982
|
return callback();
|
|
10983
10983
|
}
|
|
10984
10984
|
var gzip = zlib2.createGzip();
|
|
10985
|
-
var inp =
|
|
10986
|
-
var out =
|
|
10985
|
+
var inp = fs19.createReadStream(src);
|
|
10986
|
+
var out = fs19.createWriteStream(dest);
|
|
10987
10987
|
out.on("finish", () => {
|
|
10988
|
-
|
|
10988
|
+
fs19.unlink(src, callback);
|
|
10989
10989
|
});
|
|
10990
10990
|
inp.pipe(gzip).pipe(out);
|
|
10991
10991
|
});
|
|
10992
10992
|
}
|
|
10993
10993
|
_createLogDirIfNotExist(dirPath) {
|
|
10994
|
-
if (!
|
|
10995
|
-
|
|
10994
|
+
if (!fs19.existsSync(dirPath)) {
|
|
10995
|
+
fs19.mkdirSync(dirPath, { recursive: true });
|
|
10996
10996
|
}
|
|
10997
10997
|
}
|
|
10998
10998
|
};
|
|
@@ -11076,9 +11076,9 @@ var require_http = __commonJS({
|
|
|
11076
11076
|
};
|
|
11077
11077
|
const auth = options.params.auth || null;
|
|
11078
11078
|
delete options.params.auth;
|
|
11079
|
-
const
|
|
11079
|
+
const path18 = options.params.path || null;
|
|
11080
11080
|
delete options.params.path;
|
|
11081
|
-
this._request(options, auth,
|
|
11081
|
+
this._request(options, auth, path18, (err, res, body) => {
|
|
11082
11082
|
if (res && res.statusCode !== 200) {
|
|
11083
11083
|
err = new Error(`Invalid HTTP Status Code: ${res.statusCode}`);
|
|
11084
11084
|
}
|
|
@@ -11106,12 +11106,12 @@ var require_http = __commonJS({
|
|
|
11106
11106
|
method: "stream",
|
|
11107
11107
|
params: options
|
|
11108
11108
|
};
|
|
11109
|
-
const
|
|
11109
|
+
const path18 = options.params.path || null;
|
|
11110
11110
|
delete options.params.path;
|
|
11111
11111
|
const auth = options.params.auth || null;
|
|
11112
11112
|
delete options.params.auth;
|
|
11113
11113
|
let buff = "";
|
|
11114
|
-
const req = this._request(options, auth,
|
|
11114
|
+
const req = this._request(options, auth, path18);
|
|
11115
11115
|
stream.destroy = () => req.destroy();
|
|
11116
11116
|
req.on("data", (data) => {
|
|
11117
11117
|
data = (buff + data).split(/\n+/);
|
|
@@ -11137,14 +11137,14 @@ var require_http = __commonJS({
|
|
|
11137
11137
|
* @param {string} path - request path
|
|
11138
11138
|
* @param {function} callback - Continuation to respond to when complete.
|
|
11139
11139
|
*/
|
|
11140
|
-
_request(options, auth,
|
|
11140
|
+
_request(options, auth, path18, callback) {
|
|
11141
11141
|
options = options || {};
|
|
11142
11142
|
auth = auth || this.auth;
|
|
11143
|
-
|
|
11143
|
+
path18 = path18 || this.path || "";
|
|
11144
11144
|
if (this.batch) {
|
|
11145
|
-
this._doBatch(options, callback, auth,
|
|
11145
|
+
this._doBatch(options, callback, auth, path18);
|
|
11146
11146
|
} else {
|
|
11147
|
-
this._doRequest(options, callback, auth,
|
|
11147
|
+
this._doRequest(options, callback, auth, path18);
|
|
11148
11148
|
}
|
|
11149
11149
|
}
|
|
11150
11150
|
/**
|
|
@@ -11154,18 +11154,18 @@ var require_http = __commonJS({
|
|
|
11154
11154
|
* @param {Object?} auth - authentication options
|
|
11155
11155
|
* @param {string} path - request path
|
|
11156
11156
|
*/
|
|
11157
|
-
_doBatch(options, callback, auth,
|
|
11157
|
+
_doBatch(options, callback, auth, path18) {
|
|
11158
11158
|
this.batchOptions.push(options);
|
|
11159
11159
|
if (this.batchOptions.length === 1) {
|
|
11160
11160
|
const me = this;
|
|
11161
11161
|
this.batchCallback = callback;
|
|
11162
11162
|
this.batchTimeoutID = setTimeout(function() {
|
|
11163
11163
|
me.batchTimeoutID = -1;
|
|
11164
|
-
me._doBatchRequest(me.batchCallback, auth,
|
|
11164
|
+
me._doBatchRequest(me.batchCallback, auth, path18);
|
|
11165
11165
|
}, this.batchInterval);
|
|
11166
11166
|
}
|
|
11167
11167
|
if (this.batchOptions.length === this.batchCount) {
|
|
11168
|
-
this._doBatchRequest(this.batchCallback, auth,
|
|
11168
|
+
this._doBatchRequest(this.batchCallback, auth, path18);
|
|
11169
11169
|
}
|
|
11170
11170
|
}
|
|
11171
11171
|
/**
|
|
@@ -11174,14 +11174,14 @@ var require_http = __commonJS({
|
|
|
11174
11174
|
* @param {Object?} auth - authentication options
|
|
11175
11175
|
* @param {string} path - request path
|
|
11176
11176
|
*/
|
|
11177
|
-
_doBatchRequest(callback, auth,
|
|
11177
|
+
_doBatchRequest(callback, auth, path18) {
|
|
11178
11178
|
if (this.batchTimeoutID > 0) {
|
|
11179
11179
|
clearTimeout(this.batchTimeoutID);
|
|
11180
11180
|
this.batchTimeoutID = -1;
|
|
11181
11181
|
}
|
|
11182
11182
|
const batchOptionsCopy = this.batchOptions.slice();
|
|
11183
11183
|
this.batchOptions = [];
|
|
11184
|
-
this._doRequest(batchOptionsCopy, callback, auth,
|
|
11184
|
+
this._doRequest(batchOptionsCopy, callback, auth, path18);
|
|
11185
11185
|
}
|
|
11186
11186
|
/**
|
|
11187
11187
|
* Make a request to a winstond server or any http server which can
|
|
@@ -11191,7 +11191,7 @@ var require_http = __commonJS({
|
|
|
11191
11191
|
* @param {Object?} auth - authentication options
|
|
11192
11192
|
* @param {string} path - request path
|
|
11193
11193
|
*/
|
|
11194
|
-
_doRequest(options, callback, auth,
|
|
11194
|
+
_doRequest(options, callback, auth, path18) {
|
|
11195
11195
|
const headers = Object.assign({}, this.headers);
|
|
11196
11196
|
if (auth && auth.bearer) {
|
|
11197
11197
|
headers.Authorization = `Bearer ${auth.bearer}`;
|
|
@@ -11201,7 +11201,7 @@ var require_http = __commonJS({
|
|
|
11201
11201
|
method: "POST",
|
|
11202
11202
|
host: this.host,
|
|
11203
11203
|
port: this.port,
|
|
11204
|
-
path: `/${
|
|
11204
|
+
path: `/${path18.replace(/^\//, "")}`,
|
|
11205
11205
|
headers,
|
|
11206
11206
|
auth: auth && auth.username && auth.password ? `${auth.username}:${auth.password}` : "",
|
|
11207
11207
|
agent: this.agent
|
|
@@ -11236,7 +11236,7 @@ var require_stream3 = __commonJS({
|
|
|
11236
11236
|
"use strict";
|
|
11237
11237
|
var isStream = require_is_stream();
|
|
11238
11238
|
var { MESSAGE } = require_triple_beam();
|
|
11239
|
-
var
|
|
11239
|
+
var os3 = require("os");
|
|
11240
11240
|
var TransportStream = require_winston_transport();
|
|
11241
11241
|
module2.exports = class Stream extends TransportStream {
|
|
11242
11242
|
/**
|
|
@@ -11252,7 +11252,7 @@ var require_stream3 = __commonJS({
|
|
|
11252
11252
|
this._stream = options.stream;
|
|
11253
11253
|
this._stream.setMaxListeners(Infinity);
|
|
11254
11254
|
this.isObjectMode = options.stream._writableState.objectMode;
|
|
11255
|
-
this.eol = typeof options.eol === "string" ? options.eol :
|
|
11255
|
+
this.eol = typeof options.eol === "string" ? options.eol : os3.EOL;
|
|
11256
11256
|
}
|
|
11257
11257
|
/**
|
|
11258
11258
|
* Core logging method exposed to Winston.
|
|
@@ -11635,7 +11635,7 @@ var require_exception_stream = __commonJS({
|
|
|
11635
11635
|
var require_exception_handler = __commonJS({
|
|
11636
11636
|
"../../packages/logger/node_modules/winston/lib/winston/exception-handler.js"(exports2, module2) {
|
|
11637
11637
|
"use strict";
|
|
11638
|
-
var
|
|
11638
|
+
var os3 = require("os");
|
|
11639
11639
|
var asyncForEach = require_forEach();
|
|
11640
11640
|
var debug = require_node2()("winston:exception");
|
|
11641
11641
|
var once = require_one_time();
|
|
@@ -11730,8 +11730,8 @@ var require_exception_handler = __commonJS({
|
|
|
11730
11730
|
*/
|
|
11731
11731
|
getOsInfo() {
|
|
11732
11732
|
return {
|
|
11733
|
-
loadavg:
|
|
11734
|
-
uptime:
|
|
11733
|
+
loadavg: os3.loadavg(),
|
|
11734
|
+
uptime: os3.uptime()
|
|
11735
11735
|
};
|
|
11736
11736
|
}
|
|
11737
11737
|
/**
|
|
@@ -11873,7 +11873,7 @@ var require_rejection_stream = __commonJS({
|
|
|
11873
11873
|
var require_rejection_handler = __commonJS({
|
|
11874
11874
|
"../../packages/logger/node_modules/winston/lib/winston/rejection-handler.js"(exports2, module2) {
|
|
11875
11875
|
"use strict";
|
|
11876
|
-
var
|
|
11876
|
+
var os3 = require("os");
|
|
11877
11877
|
var asyncForEach = require_forEach();
|
|
11878
11878
|
var debug = require_node2()("winston:rejection");
|
|
11879
11879
|
var once = require_one_time();
|
|
@@ -11970,8 +11970,8 @@ var require_rejection_handler = __commonJS({
|
|
|
11970
11970
|
*/
|
|
11971
11971
|
getOsInfo() {
|
|
11972
11972
|
return {
|
|
11973
|
-
loadavg:
|
|
11974
|
-
uptime:
|
|
11973
|
+
loadavg: os3.loadavg(),
|
|
11974
|
+
uptime: os3.uptime()
|
|
11975
11975
|
};
|
|
11976
11976
|
}
|
|
11977
11977
|
/**
|
|
@@ -13351,6 +13351,10 @@ var Logger = class {
|
|
|
13351
13351
|
console.info(message);
|
|
13352
13352
|
FileLogService_default.write("INFO", String(message));
|
|
13353
13353
|
};
|
|
13354
|
+
this.warn = (message) => {
|
|
13355
|
+
console.warn(message);
|
|
13356
|
+
FileLogService_default.write("WARN", String(message));
|
|
13357
|
+
};
|
|
13354
13358
|
this.flush = () => FileLogService_default.flush();
|
|
13355
13359
|
this.close = () => FileLogService_default.close();
|
|
13356
13360
|
this.error = (error) => {
|
|
@@ -13494,7 +13498,7 @@ var import_promises = __toESM(require("fs/promises"), 1);
|
|
|
13494
13498
|
|
|
13495
13499
|
// ../../packages/constants/src/Constants.ts
|
|
13496
13500
|
var CONSTANTS = {
|
|
13497
|
-
cliVersion: "1.1
|
|
13501
|
+
cliVersion: "1.2.1",
|
|
13498
13502
|
backendVersion: 1,
|
|
13499
13503
|
backendPort: 5088,
|
|
13500
13504
|
workerVersion: 2,
|
|
@@ -14217,7 +14221,7 @@ var Environment = new EnvironmentClass();
|
|
|
14217
14221
|
var Environment_default = Environment;
|
|
14218
14222
|
|
|
14219
14223
|
// ../../packages/executors/src/ConsumerExecutor.ts
|
|
14220
|
-
var
|
|
14224
|
+
var import_path15 = __toESM(require("path"));
|
|
14221
14225
|
var import_fs9 = __toESM(require("fs"));
|
|
14222
14226
|
var import_readline6 = __toESM(require("readline"));
|
|
14223
14227
|
var import_promises8 = __toESM(require("fs/promises"));
|
|
@@ -14602,6 +14606,11 @@ var AutoMapperEngineClass = class {
|
|
|
14602
14606
|
};
|
|
14603
14607
|
var AutoMapperEngine = new AutoMapperEngineClass();
|
|
14604
14608
|
|
|
14609
|
+
// ../../packages/engines/src/producer/ProducerEngine.ts
|
|
14610
|
+
var fs11 = __toESM(require("fs"), 1);
|
|
14611
|
+
var os = __toESM(require("os"), 1);
|
|
14612
|
+
var import_path11 = __toESM(require("path"), 1);
|
|
14613
|
+
|
|
14605
14614
|
// ../../packages/drivers/src/DeltaShareDriver.ts
|
|
14606
14615
|
var DeltaShareSourceDriver = class {
|
|
14607
14616
|
constructor() {
|
|
@@ -15436,8 +15445,8 @@ var HttpClientClass = class {
|
|
|
15436
15445
|
throw new Error(err.message ?? "An error occurred on GET.");
|
|
15437
15446
|
}
|
|
15438
15447
|
};
|
|
15439
|
-
this.getWorkerUrl = (
|
|
15440
|
-
const cleanPath =
|
|
15448
|
+
this.getWorkerUrl = (path18) => {
|
|
15449
|
+
const cleanPath = path18.startsWith("/") ? path18.substring(1) : path18;
|
|
15441
15450
|
return `${this.workerHost}/${cleanPath}`;
|
|
15442
15451
|
};
|
|
15443
15452
|
this.workerHost = ProcessENVManager_default.getEnvVariable("REMORA_WORKER_HOST") || "http://worker:5069";
|
|
@@ -16507,12 +16516,12 @@ var noopTracker = { _operations: {}, measure: () => {
|
|
|
16507
16516
|
}, getOperations: () => ({}) };
|
|
16508
16517
|
var ProducerEngineClass = class {
|
|
16509
16518
|
constructor() {
|
|
16510
|
-
this.readFile = async (producer, options) => {
|
|
16519
|
+
this.readFile = async (producer, options, sourceOverride) => {
|
|
16511
16520
|
Affirm_default(producer, "Invalid producer");
|
|
16512
16521
|
Affirm_default(options, "Invalid options");
|
|
16513
16522
|
if (options.readmode === "lines")
|
|
16514
16523
|
Affirm_default(options.lines, "Invalid lines");
|
|
16515
|
-
const source = Environment_default.getSource(producer.source);
|
|
16524
|
+
const source = sourceOverride ?? Environment_default.getSource(producer.source);
|
|
16516
16525
|
Affirm_default(source, `No source found for producer "${producer.name}" with name "${producer.source}"`);
|
|
16517
16526
|
const driver = await DriverFactory_default.instantiateSource(source);
|
|
16518
16527
|
Affirm_default(driver, `No driver found for producer "${producer.name}" with driver type "${source.engine}"`);
|
|
@@ -16586,8 +16595,22 @@ var ProducerEngineClass = class {
|
|
|
16586
16595
|
case "local":
|
|
16587
16596
|
case "aws-s3":
|
|
16588
16597
|
case "delta-share": {
|
|
16589
|
-
const
|
|
16590
|
-
|
|
16598
|
+
const { compressionType } = producer.settings;
|
|
16599
|
+
let tempDir = null;
|
|
16600
|
+
try {
|
|
16601
|
+
let effectiveProducer = producer;
|
|
16602
|
+
let effectiveSource = source;
|
|
16603
|
+
if (compressionType) {
|
|
16604
|
+
tempDir = fs11.mkdtempSync(import_path11.default.join(os.tmpdir(), "remora-sample-"));
|
|
16605
|
+
const decompressedFileKey = await this._decompressForSampling(producer, source, tempDir);
|
|
16606
|
+
effectiveProducer = { ...producer, settings: { ...producer.settings, fileKey: decompressedFileKey, compressionType: void 0 } };
|
|
16607
|
+
effectiveSource = { ...source, authentication: { ...source.authentication, path: tempDir } };
|
|
16608
|
+
}
|
|
16609
|
+
const fileData = await this.readFile(effectiveProducer, { readmode: "lines", lines: { from: 0, to: sampleSize } }, effectiveSource);
|
|
16610
|
+
rawData = fileData.data;
|
|
16611
|
+
} finally {
|
|
16612
|
+
if (tempDir) fs11.rmSync(tempDir, { recursive: true, force: true });
|
|
16613
|
+
}
|
|
16591
16614
|
break;
|
|
16592
16615
|
}
|
|
16593
16616
|
default:
|
|
@@ -16672,13 +16695,54 @@ var ProducerEngineClass = class {
|
|
|
16672
16695
|
}
|
|
16673
16696
|
return dimensions;
|
|
16674
16697
|
};
|
|
16698
|
+
this._decompressForSampling = async (producer, source, tempDir) => {
|
|
16699
|
+
const { fileKey, compressionType } = producer.settings;
|
|
16700
|
+
const sourcePath = source.authentication["path"];
|
|
16701
|
+
switch (compressionType?.toUpperCase()) {
|
|
16702
|
+
case "GZ": {
|
|
16703
|
+
const decompressedName = fileKey.replace(/\.gz$/i, "");
|
|
16704
|
+
const outputPath = import_path11.default.join(tempDir, decompressedName);
|
|
16705
|
+
const outputDir = import_path11.default.dirname(outputPath);
|
|
16706
|
+
if (!fs11.existsSync(outputDir)) fs11.mkdirSync(outputDir, { recursive: true });
|
|
16707
|
+
await ParseCompression_default.decompressToFile(compressionType, fileKey, sourcePath, outputPath);
|
|
16708
|
+
return decompressedName;
|
|
16709
|
+
}
|
|
16710
|
+
case "ZIP":
|
|
16711
|
+
case "TAR": {
|
|
16712
|
+
const extractDir = import_path11.default.join(tempDir, "extracted");
|
|
16713
|
+
await ParseCompression_default.decompressToFile(compressionType, fileKey, sourcePath, extractDir);
|
|
16714
|
+
const files = this._findFilesRecursive(extractDir);
|
|
16715
|
+
Affirm_default(files.length > 0, `No files found after decompressing "${fileKey}"`);
|
|
16716
|
+
const firstFile = files[0];
|
|
16717
|
+
const relativePath = import_path11.default.relative(extractDir, firstFile);
|
|
16718
|
+
const destPath = import_path11.default.join(tempDir, relativePath);
|
|
16719
|
+
const destDir = import_path11.default.dirname(destPath);
|
|
16720
|
+
if (!fs11.existsSync(destDir)) fs11.mkdirSync(destDir, { recursive: true });
|
|
16721
|
+
fs11.renameSync(firstFile, destPath);
|
|
16722
|
+
return relativePath;
|
|
16723
|
+
}
|
|
16724
|
+
default:
|
|
16725
|
+
throw new Error(`Unsupported compression type "${compressionType}" for producer "${producer.name}"`);
|
|
16726
|
+
}
|
|
16727
|
+
};
|
|
16728
|
+
this._findFilesRecursive = (dir) => {
|
|
16729
|
+
const results = [];
|
|
16730
|
+
for (const entry of fs11.readdirSync(dir)) {
|
|
16731
|
+
const fullPath = import_path11.default.join(dir, entry);
|
|
16732
|
+
if (fs11.statSync(fullPath).isDirectory())
|
|
16733
|
+
results.push(...this._findFilesRecursive(fullPath));
|
|
16734
|
+
else
|
|
16735
|
+
results.push(fullPath);
|
|
16736
|
+
}
|
|
16737
|
+
return results;
|
|
16738
|
+
};
|
|
16675
16739
|
}
|
|
16676
16740
|
};
|
|
16677
16741
|
var ProducerEngine = new ProducerEngineClass();
|
|
16678
16742
|
var ProducerEngine_default = ProducerEngine;
|
|
16679
16743
|
|
|
16680
16744
|
// ../../packages/engines/src/ai/DeveloperEngine.ts
|
|
16681
|
-
var
|
|
16745
|
+
var import_path12 = __toESM(require("path"), 1);
|
|
16682
16746
|
var import_promises6 = __toESM(require("fs/promises"), 1);
|
|
16683
16747
|
var import_dayjs2 = __toESM(require("dayjs"), 1);
|
|
16684
16748
|
var import_customParseFormat2 = __toESM(require("dayjs/plugin/customParseFormat"), 1);
|
|
@@ -16705,7 +16769,7 @@ var DeveloperEngineClass = class {
|
|
|
16705
16769
|
_version: producer._version ?? 1
|
|
16706
16770
|
};
|
|
16707
16771
|
mappedProducer["$schema"] = producer["$schema"];
|
|
16708
|
-
const producerPath =
|
|
16772
|
+
const producerPath = import_path12.default.join(process.cwd(), "remora", "producers", `${producer.name}.json`);
|
|
16709
16773
|
await import_promises6.default.writeFile(producerPath, JSON.stringify(mappedProducer, null, 4), "utf-8");
|
|
16710
16774
|
return { producer: mappedProducer, fields: typeDefinitions };
|
|
16711
16775
|
};
|
|
@@ -16964,8 +17028,8 @@ var DeveloperEngineClass = class {
|
|
|
16964
17028
|
Affirm_default(fileType, "Producer must have a fileType setting for mock data generation");
|
|
16965
17029
|
const mockRecords = this.generateMockRecords(producer.dimensions, records);
|
|
16966
17030
|
const basePath = source.authentication.path || process.cwd();
|
|
16967
|
-
const filePath =
|
|
16968
|
-
await import_promises6.default.mkdir(
|
|
17031
|
+
const filePath = import_path12.default.join(basePath, fileKey.replace("%", "mock"));
|
|
17032
|
+
await import_promises6.default.mkdir(import_path12.default.dirname(filePath), { recursive: true });
|
|
16969
17033
|
const content = this.formatMockData(mockRecords, fileType, delimiter);
|
|
16970
17034
|
await import_promises6.default.writeFile(filePath, content, "utf-8");
|
|
16971
17035
|
return { filePath, recordCount: records };
|
|
@@ -17812,6 +17876,112 @@ var TransformationEngineClass = class {
|
|
|
17812
17876
|
var TransformationEngine = new TransformationEngineClass();
|
|
17813
17877
|
var TransformationEngine_default = TransformationEngine;
|
|
17814
17878
|
|
|
17879
|
+
// ../../packages/engines/src/transform/DataValidationEngine.ts
|
|
17880
|
+
var DataValidationEngineClass = class {
|
|
17881
|
+
constructor() {
|
|
17882
|
+
this.applyValidations = (value, validations, fieldKey) => {
|
|
17883
|
+
for (const validation of validations) {
|
|
17884
|
+
const passed = this.evaluateRule(value, validation.rule);
|
|
17885
|
+
if (!passed) {
|
|
17886
|
+
return {
|
|
17887
|
+
valid: false,
|
|
17888
|
+
message: this.buildMessage(value, validation.rule, fieldKey),
|
|
17889
|
+
onFail: validation.onFail
|
|
17890
|
+
};
|
|
17891
|
+
}
|
|
17892
|
+
}
|
|
17893
|
+
return { valid: true };
|
|
17894
|
+
};
|
|
17895
|
+
this.evaluateRule = (value, rule) => {
|
|
17896
|
+
if ("required" in rule)
|
|
17897
|
+
return Algo_default.hasVal(value);
|
|
17898
|
+
if ("min" in rule) {
|
|
17899
|
+
if (!Algo_default.hasVal(value)) return true;
|
|
17900
|
+
const num = Number(value);
|
|
17901
|
+
return !isNaN(num) && num >= rule.min;
|
|
17902
|
+
}
|
|
17903
|
+
if ("max" in rule) {
|
|
17904
|
+
if (!Algo_default.hasVal(value)) return true;
|
|
17905
|
+
const num = Number(value);
|
|
17906
|
+
return !isNaN(num) && num <= rule.max;
|
|
17907
|
+
}
|
|
17908
|
+
if ("regex" in rule) {
|
|
17909
|
+
if (!Algo_default.hasVal(value)) return true;
|
|
17910
|
+
return new RegExp(rule.regex).test(String(value));
|
|
17911
|
+
}
|
|
17912
|
+
if ("min_length" in rule) {
|
|
17913
|
+
if (!Algo_default.hasVal(value)) return true;
|
|
17914
|
+
return String(value).length >= rule.min_length;
|
|
17915
|
+
}
|
|
17916
|
+
if ("max_length" in rule) {
|
|
17917
|
+
if (!Algo_default.hasVal(value)) return true;
|
|
17918
|
+
return String(value).length <= rule.max_length;
|
|
17919
|
+
}
|
|
17920
|
+
if ("in" in rule) {
|
|
17921
|
+
return rule.in.includes(value);
|
|
17922
|
+
}
|
|
17923
|
+
if ("not_in" in rule) {
|
|
17924
|
+
return !rule.not_in.includes(value);
|
|
17925
|
+
}
|
|
17926
|
+
return true;
|
|
17927
|
+
};
|
|
17928
|
+
this.buildMessage = (value, rule, fieldKey) => {
|
|
17929
|
+
const preview = Algo_default.hasVal(value) ? JSON.stringify(value) : "null/undefined";
|
|
17930
|
+
if ("required" in rule) return `Field "${fieldKey}" is required but got ${preview}`;
|
|
17931
|
+
if ("min" in rule) return `Field "${fieldKey}" value ${preview} is below minimum ${rule.min}`;
|
|
17932
|
+
if ("max" in rule) return `Field "${fieldKey}" value ${preview} exceeds maximum ${rule.max}`;
|
|
17933
|
+
if ("regex" in rule) return `Field "${fieldKey}" value ${preview} does not match pattern "${rule.regex}"`;
|
|
17934
|
+
if ("min_length" in rule) return `Field "${fieldKey}" value ${preview} is shorter than minimum length ${rule.min_length}`;
|
|
17935
|
+
if ("max_length" in rule) return `Field "${fieldKey}" value ${preview} exceeds maximum length ${rule.max_length}`;
|
|
17936
|
+
if ("in" in rule) return `Field "${fieldKey}" value ${preview} is not in the allowed values`;
|
|
17937
|
+
if ("not_in" in rule) return `Field "${fieldKey}" value ${preview} is in the disallowed values`;
|
|
17938
|
+
return `Field "${fieldKey}" failed validation`;
|
|
17939
|
+
};
|
|
17940
|
+
this.evaluateDatasetValidations = (validations, context) => {
|
|
17941
|
+
const results = [];
|
|
17942
|
+
for (const validation of validations) {
|
|
17943
|
+
const result = this.evaluateDatasetRule(validation, context);
|
|
17944
|
+
if (result) results.push(result);
|
|
17945
|
+
}
|
|
17946
|
+
return results;
|
|
17947
|
+
};
|
|
17948
|
+
this.extractUniqueFieldKeys = (validations) => {
|
|
17949
|
+
return validations.filter((v) => "unique_fields" in v.rule).flatMap((v) => v.rule.unique_fields);
|
|
17950
|
+
};
|
|
17951
|
+
this.hasRule = (validations, ruleKey) => {
|
|
17952
|
+
return validations.some((v) => ruleKey in v.rule);
|
|
17953
|
+
};
|
|
17954
|
+
this.evaluateDatasetRule = (validation, context) => {
|
|
17955
|
+
const { rule, onFail } = validation;
|
|
17956
|
+
const { rowCount, hasDuplicateRows, duplicateFields } = context;
|
|
17957
|
+
if ("not_empty" in rule) {
|
|
17958
|
+
if (rowCount === 0)
|
|
17959
|
+
return { message: "Dataset is empty", onFail };
|
|
17960
|
+
}
|
|
17961
|
+
if ("min_rows" in rule) {
|
|
17962
|
+
if (rowCount < rule.min_rows)
|
|
17963
|
+
return { message: `Dataset has ${rowCount} rows, expected at least ${rule.min_rows}`, onFail };
|
|
17964
|
+
}
|
|
17965
|
+
if ("max_rows" in rule) {
|
|
17966
|
+
if (rowCount > rule.max_rows)
|
|
17967
|
+
return { message: `Dataset has ${rowCount} rows, expected at most ${rule.max_rows}`, onFail };
|
|
17968
|
+
}
|
|
17969
|
+
if ("no_duplicates" in rule) {
|
|
17970
|
+
if (hasDuplicateRows)
|
|
17971
|
+
return { message: "Dataset contains duplicate rows", onFail };
|
|
17972
|
+
}
|
|
17973
|
+
if ("unique_fields" in rule) {
|
|
17974
|
+
const failedFields = rule.unique_fields.filter((f) => duplicateFields.includes(f));
|
|
17975
|
+
if (failedFields.length > 0)
|
|
17976
|
+
return { message: `Duplicate values found in field(s): ${failedFields.join(", ")}`, onFail };
|
|
17977
|
+
}
|
|
17978
|
+
return null;
|
|
17979
|
+
};
|
|
17980
|
+
}
|
|
17981
|
+
};
|
|
17982
|
+
var DataValidationEngine = new DataValidationEngineClass();
|
|
17983
|
+
var DataValidationEngine_default = DataValidationEngine;
|
|
17984
|
+
|
|
17815
17985
|
// ../../packages/engines/src/usage/DataframeManager.ts
|
|
17816
17986
|
var DataframeManagerClass = class {
|
|
17817
17987
|
fill(points, from, to, onlyLastValue, maintainLastValue) {
|
|
@@ -18309,10 +18479,10 @@ var UsageManager = new UsageManagerClass();
|
|
|
18309
18479
|
var UsageManager_default = UsageManager;
|
|
18310
18480
|
|
|
18311
18481
|
// ../../packages/executors/src/OutputExecutor.ts
|
|
18312
|
-
var
|
|
18482
|
+
var fs14 = __toESM(require("fs"));
|
|
18313
18483
|
|
|
18314
18484
|
// ../../packages/executors/src/ExecutorScope.ts
|
|
18315
|
-
var
|
|
18485
|
+
var import_path13 = __toESM(require("path"));
|
|
18316
18486
|
var import_fs8 = __toESM(require("fs"));
|
|
18317
18487
|
var import_promises7 = __toESM(require("fs/promises"));
|
|
18318
18488
|
var ExecutorScopeClass2 = class {
|
|
@@ -18320,7 +18490,7 @@ var ExecutorScopeClass2 = class {
|
|
|
18320
18490
|
this.WORKERS_FOLDER = "workers";
|
|
18321
18491
|
this.PRODUCERS_FOLDER = "producers";
|
|
18322
18492
|
this.getWorkerPath = (scope, workerId) => {
|
|
18323
|
-
return
|
|
18493
|
+
return import_path13.default.join(
|
|
18324
18494
|
Constants_default.defaults.REMORA_PATH,
|
|
18325
18495
|
Constants_default.defaults.PRODUCER_TEMP_FOLDER,
|
|
18326
18496
|
// A specific execution sits entirely in this folder, so at the end it's safe to delete it entirely
|
|
@@ -18330,7 +18500,7 @@ var ExecutorScopeClass2 = class {
|
|
|
18330
18500
|
);
|
|
18331
18501
|
};
|
|
18332
18502
|
this.getProducerPath = (scope, producer, sourceFileKey) => {
|
|
18333
|
-
return
|
|
18503
|
+
return import_path13.default.join(
|
|
18334
18504
|
Constants_default.defaults.REMORA_PATH,
|
|
18335
18505
|
Constants_default.defaults.PRODUCER_TEMP_FOLDER,
|
|
18336
18506
|
// A specific execution sits entirely in this folder, so at the end it's safe to delete it entirely
|
|
@@ -18341,7 +18511,7 @@ var ExecutorScopeClass2 = class {
|
|
|
18341
18511
|
);
|
|
18342
18512
|
};
|
|
18343
18513
|
this.getMainPath = (scope) => {
|
|
18344
|
-
return
|
|
18514
|
+
return import_path13.default.join(
|
|
18345
18515
|
Constants_default.defaults.REMORA_PATH,
|
|
18346
18516
|
Constants_default.defaults.PRODUCER_TEMP_FOLDER,
|
|
18347
18517
|
scope.folder,
|
|
@@ -18349,7 +18519,7 @@ var ExecutorScopeClass2 = class {
|
|
|
18349
18519
|
);
|
|
18350
18520
|
};
|
|
18351
18521
|
this.clearScope = async (scope) => {
|
|
18352
|
-
const scopePath =
|
|
18522
|
+
const scopePath = import_path13.default.join(
|
|
18353
18523
|
Constants_default.defaults.REMORA_PATH,
|
|
18354
18524
|
Constants_default.defaults.PRODUCER_TEMP_FOLDER,
|
|
18355
18525
|
scope.folder
|
|
@@ -18359,7 +18529,7 @@ var ExecutorScopeClass2 = class {
|
|
|
18359
18529
|
}
|
|
18360
18530
|
};
|
|
18361
18531
|
this.ensurePath = (fileUri) => {
|
|
18362
|
-
const dir =
|
|
18532
|
+
const dir = import_path13.default.dirname(fileUri);
|
|
18363
18533
|
if (!import_fs8.default.existsSync(dir))
|
|
18364
18534
|
import_fs8.default.mkdirSync(dir, { recursive: true });
|
|
18365
18535
|
if (!import_fs8.default.existsSync(fileUri))
|
|
@@ -18371,7 +18541,7 @@ var ExecutorScope2 = new ExecutorScopeClass2();
|
|
|
18371
18541
|
var ExecutorScope_default2 = ExecutorScope2;
|
|
18372
18542
|
|
|
18373
18543
|
// ../../packages/executors/src/OutputExecutor.ts
|
|
18374
|
-
var
|
|
18544
|
+
var import_path14 = __toESM(require("path"));
|
|
18375
18545
|
var OutputExecutorClass = class {
|
|
18376
18546
|
constructor() {
|
|
18377
18547
|
this._getInternalRecordFormat = (consumer) => {
|
|
@@ -18417,13 +18587,13 @@ var OutputExecutorClass = class {
|
|
|
18417
18587
|
for (const output of consumer.outputs) {
|
|
18418
18588
|
const destination = Environment_default.getSource(output.exportDestination);
|
|
18419
18589
|
const driver = await DriverFactory_default.instantiateDestination(destination);
|
|
18420
|
-
const currentPath =
|
|
18590
|
+
const currentPath = import_path14.default.dirname(ExecutorScope_default2.getMainPath(scope));
|
|
18421
18591
|
const destinationName = this._composeFileName(consumer, output, this._getExtension(output));
|
|
18422
18592
|
Logger_default.log(`Exporting consumer "${consumer.name}" to "${output.exportDestination}" as ${output.format} (${destinationName})`);
|
|
18423
|
-
const filenameArray =
|
|
18593
|
+
const filenameArray = fs14.readdirSync(currentPath).filter((filename) => filename.includes(".dataset"));
|
|
18424
18594
|
for (const filename in filenameArray) {
|
|
18425
18595
|
const destinationPath = this.getCompletedPath(destinationName, filename);
|
|
18426
|
-
const startingPath =
|
|
18596
|
+
const startingPath = import_path14.default.join(currentPath, filenameArray[filename]);
|
|
18427
18597
|
if (output.format === internalFormat) {
|
|
18428
18598
|
results.push(await driver.move(startingPath, destinationPath));
|
|
18429
18599
|
} else {
|
|
@@ -18483,8 +18653,8 @@ var OutputExecutor_default = OutputExecutor;
|
|
|
18483
18653
|
var ConsumerExecutorClass = class {
|
|
18484
18654
|
constructor() {
|
|
18485
18655
|
this._getWorkPath = (consumer, executionId) => {
|
|
18486
|
-
const execFolder =
|
|
18487
|
-
const workPath =
|
|
18656
|
+
const execFolder = import_path15.default.join(consumer.name, executionId);
|
|
18657
|
+
const workPath = import_path15.default.join("./remora", Constants_default.defaults.PRODUCER_TEMP_FOLDER, execFolder, ".dataset");
|
|
18488
18658
|
return workPath;
|
|
18489
18659
|
};
|
|
18490
18660
|
this._clearWorkPath = async (workPath) => {
|
|
@@ -18495,7 +18665,7 @@ var ConsumerExecutorClass = class {
|
|
|
18495
18665
|
} catch (error) {
|
|
18496
18666
|
}
|
|
18497
18667
|
try {
|
|
18498
|
-
const dir =
|
|
18668
|
+
const dir = import_path15.default.dirname(workPath);
|
|
18499
18669
|
if (import_fs9.default.existsSync(dir)) {
|
|
18500
18670
|
await import_promises8.default.rmdir(dir);
|
|
18501
18671
|
}
|
|
@@ -18503,7 +18673,7 @@ var ConsumerExecutorClass = class {
|
|
|
18503
18673
|
}
|
|
18504
18674
|
};
|
|
18505
18675
|
this._ensurePath = (pathUri) => {
|
|
18506
|
-
const dir =
|
|
18676
|
+
const dir = import_path15.default.dirname(pathUri);
|
|
18507
18677
|
if (!import_fs9.default.existsSync(dir))
|
|
18508
18678
|
import_fs9.default.mkdirSync(dir, { recursive: true });
|
|
18509
18679
|
if (!import_fs9.default.existsSync(pathUri))
|
|
@@ -18570,6 +18740,32 @@ var ConsumerExecutorClass = class {
|
|
|
18570
18740
|
}
|
|
18571
18741
|
}
|
|
18572
18742
|
}
|
|
18743
|
+
for (const field of fields) {
|
|
18744
|
+
const { cField } = field;
|
|
18745
|
+
const fieldKey = cField.alias ?? cField.key;
|
|
18746
|
+
if (cField.validate && cField.validate.length > 0) {
|
|
18747
|
+
const result = DataValidationEngine_default.applyValidations(record[fieldKey], cField.validate, fieldKey);
|
|
18748
|
+
if (!result.valid) {
|
|
18749
|
+
const errorMessage = `Validation failed for field "${fieldKey}" (index: ${recordIndex}): ${result.message}`;
|
|
18750
|
+
switch (result.onFail) {
|
|
18751
|
+
case "set_default":
|
|
18752
|
+
record[fieldKey] = cField.default;
|
|
18753
|
+
break;
|
|
18754
|
+
case "skip":
|
|
18755
|
+
return null;
|
|
18756
|
+
case "warn":
|
|
18757
|
+
Logger_default.warn(errorMessage);
|
|
18758
|
+
break;
|
|
18759
|
+
case "fail":
|
|
18760
|
+
default: {
|
|
18761
|
+
const err = new Error(errorMessage);
|
|
18762
|
+
Logger_default.error(err);
|
|
18763
|
+
throw err;
|
|
18764
|
+
}
|
|
18765
|
+
}
|
|
18766
|
+
}
|
|
18767
|
+
}
|
|
18768
|
+
}
|
|
18573
18769
|
try {
|
|
18574
18770
|
for (const dimension of dimensions) {
|
|
18575
18771
|
const field = fields.find((x) => x.cField.key === dimension.name);
|
|
@@ -18810,6 +19006,48 @@ var ConsumerExecutorClass = class {
|
|
|
18810
19006
|
return false;
|
|
18811
19007
|
}
|
|
18812
19008
|
};
|
|
19009
|
+
this.processDatasetValidation = async (consumer, datasetPath) => {
|
|
19010
|
+
const validations = consumer.validate;
|
|
19011
|
+
if (!validations || validations.length === 0) return [];
|
|
19012
|
+
const internalRecordFormat = OutputExecutor_default._getInternalRecordFormat(consumer);
|
|
19013
|
+
const internalFields = ConsumerManager_default.getExpandedFields(consumer);
|
|
19014
|
+
let rowCount = 0;
|
|
19015
|
+
const seenRows = /* @__PURE__ */ new Set();
|
|
19016
|
+
const fieldValueSets = /* @__PURE__ */ new Map();
|
|
19017
|
+
let hasDuplicateRows = false;
|
|
19018
|
+
const duplicateFields = [];
|
|
19019
|
+
const uniqueFieldKeys = DataValidationEngine_default.extractUniqueFieldKeys(validations);
|
|
19020
|
+
const checkDuplicateRows = DataValidationEngine_default.hasRule(validations, "no_duplicates");
|
|
19021
|
+
for (const fieldKey of uniqueFieldKeys) {
|
|
19022
|
+
fieldValueSets.set(fieldKey, /* @__PURE__ */ new Set());
|
|
19023
|
+
}
|
|
19024
|
+
const reader = import_fs9.default.createReadStream(datasetPath);
|
|
19025
|
+
const lineReader = import_readline6.default.createInterface({ input: reader, crlfDelay: Infinity });
|
|
19026
|
+
for await (const line of lineReader) {
|
|
19027
|
+
rowCount++;
|
|
19028
|
+
if (checkDuplicateRows) {
|
|
19029
|
+
if (seenRows.has(line))
|
|
19030
|
+
hasDuplicateRows = true;
|
|
19031
|
+
else
|
|
19032
|
+
seenRows.add(line);
|
|
19033
|
+
}
|
|
19034
|
+
if (uniqueFieldKeys.length > 0) {
|
|
19035
|
+
const record = internalRecordFormat === "CSV" || internalRecordFormat === "TXT" ? LineParser_default._internalParseCSV(line, internalFields) : LineParser_default._internalParseJSON(line);
|
|
19036
|
+
for (const fieldKey of uniqueFieldKeys) {
|
|
19037
|
+
const valueSet = fieldValueSets.get(fieldKey);
|
|
19038
|
+
const val = String(record[fieldKey] ?? "");
|
|
19039
|
+
if (valueSet.has(val)) {
|
|
19040
|
+
if (!duplicateFields.includes(fieldKey))
|
|
19041
|
+
duplicateFields.push(fieldKey);
|
|
19042
|
+
} else {
|
|
19043
|
+
valueSet.add(val);
|
|
19044
|
+
}
|
|
19045
|
+
}
|
|
19046
|
+
}
|
|
19047
|
+
}
|
|
19048
|
+
lineReader.close();
|
|
19049
|
+
return DataValidationEngine_default.evaluateDatasetValidations(validations, { rowCount, hasDuplicateRows, duplicateFields });
|
|
19050
|
+
};
|
|
18813
19051
|
/**
|
|
18814
19052
|
* Compares two values, handling numbers, strings, and dates
|
|
18815
19053
|
* Returns: negative if a < b, positive if a > b, 0 if equal
|
|
@@ -18835,7 +19073,7 @@ var import_fs10 = __toESM(require("fs"));
|
|
|
18835
19073
|
var import_readline7 = __toESM(require("readline"));
|
|
18836
19074
|
|
|
18837
19075
|
// ../../packages/executors/src/ProducerExecutor.ts
|
|
18838
|
-
var
|
|
19076
|
+
var import_path16 = __toESM(require("path"));
|
|
18839
19077
|
var ProducerExecutorClass = class {
|
|
18840
19078
|
constructor() {
|
|
18841
19079
|
this.ready = async (producer, scope) => {
|
|
@@ -18859,7 +19097,7 @@ var ProducerExecutorClass = class {
|
|
|
18859
19097
|
counter = performance.now();
|
|
18860
19098
|
for (const dimension of dimensions) {
|
|
18861
19099
|
if (dimension.prodDimension.sourceFilename === true)
|
|
18862
|
-
record[dimension.name] =
|
|
19100
|
+
record[dimension.name] = import_path16.default.basename(chunk.fileUri);
|
|
18863
19101
|
const maskType = ProducerManager_default.getMask(dimension.prodDimension);
|
|
18864
19102
|
if (Algo_default.hasVal(maskType))
|
|
18865
19103
|
record[dimension.name] = CryptoEngine_default.hashValue(maskType, record[dimension.name]?.toString(), dimension.prodDimension.type);
|
|
@@ -19049,7 +19287,7 @@ var Executor_default = Executor;
|
|
|
19049
19287
|
var import_os = __toESM(require("os"));
|
|
19050
19288
|
var import_fs11 = __toESM(require("fs"));
|
|
19051
19289
|
var import_promises9 = __toESM(require("fs/promises"));
|
|
19052
|
-
var
|
|
19290
|
+
var import_path17 = __toESM(require("path"));
|
|
19053
19291
|
var import_workerpool = __toESM(require("workerpool"));
|
|
19054
19292
|
|
|
19055
19293
|
// ../../packages/executors/src/ExecutorProgress.ts
|
|
@@ -19107,7 +19345,7 @@ var ExecutorProgress = class {
|
|
|
19107
19345
|
var ExecutorProgress_default = ExecutorProgress;
|
|
19108
19346
|
|
|
19109
19347
|
// ../../packages/executors/src/ExecutorWriter.ts
|
|
19110
|
-
var
|
|
19348
|
+
var fs17 = __toESM(require("fs"));
|
|
19111
19349
|
var import_readline8 = __toESM(require("readline"));
|
|
19112
19350
|
var ExecutorWriter = class {
|
|
19113
19351
|
constructor() {
|
|
@@ -19124,11 +19362,11 @@ var ExecutorWriter = class {
|
|
|
19124
19362
|
};
|
|
19125
19363
|
this.splitBySize = async (scope, sourcePath) => {
|
|
19126
19364
|
const maxOutputFileSize = scope.limitFileSize * this.FAKE_GB;
|
|
19127
|
-
const readStream =
|
|
19365
|
+
const readStream = fs17.createReadStream(sourcePath);
|
|
19128
19366
|
const reader = import_readline8.default.createInterface({ input: readStream, crlfDelay: Infinity });
|
|
19129
19367
|
let writerIndex = 0;
|
|
19130
19368
|
let destPath = this.getCompletedPath(sourcePath, writerIndex);
|
|
19131
|
-
let writeStream =
|
|
19369
|
+
let writeStream = fs17.createWriteStream(destPath, { flags: "a" });
|
|
19132
19370
|
for await (const line of reader) {
|
|
19133
19371
|
if (readStream.bytesRead > maxOutputFileSize * (writerIndex + 1)) {
|
|
19134
19372
|
writeStream.end();
|
|
@@ -19138,7 +19376,7 @@ var ExecutorWriter = class {
|
|
|
19138
19376
|
});
|
|
19139
19377
|
writerIndex++;
|
|
19140
19378
|
destPath = this.getCompletedPath(sourcePath, writerIndex);
|
|
19141
|
-
writeStream =
|
|
19379
|
+
writeStream = fs17.createWriteStream(destPath, { flags: "a" });
|
|
19142
19380
|
}
|
|
19143
19381
|
writeStream.write(line + "\n");
|
|
19144
19382
|
}
|
|
@@ -19147,7 +19385,7 @@ var ExecutorWriter = class {
|
|
|
19147
19385
|
writeStream.on("finish", resolve);
|
|
19148
19386
|
writeStream.on("error", reject);
|
|
19149
19387
|
});
|
|
19150
|
-
await
|
|
19388
|
+
await fs17.promises.unlink(sourcePath);
|
|
19151
19389
|
};
|
|
19152
19390
|
/**
|
|
19153
19391
|
* Manage the Writestream for main.dataset
|
|
@@ -19217,7 +19455,7 @@ var ExecutorOrchestratorClass = class {
|
|
|
19217
19455
|
};
|
|
19218
19456
|
const workerPath = this._getWorkerPath();
|
|
19219
19457
|
Logger_default.log(`Initializing worker pool from ${workerPath} (heap limit: ${Constants_default.defaults.MIN_RUNTIME_HEAP_MB}MB)`);
|
|
19220
|
-
return import_workerpool.default.pool(
|
|
19458
|
+
return import_workerpool.default.pool(import_path17.default.join(workerPath, "ExecutorWorker.js"), options);
|
|
19221
19459
|
};
|
|
19222
19460
|
this.launch = async (request) => {
|
|
19223
19461
|
Affirm_default(request, "Invalid options");
|
|
@@ -19227,7 +19465,7 @@ var ExecutorOrchestratorClass = class {
|
|
|
19227
19465
|
const tracker = new ExecutorPerformance_default();
|
|
19228
19466
|
const _progress = new ExecutorProgress_default(logProgress);
|
|
19229
19467
|
const { usageId } = UsageManager_default.startUsage(consumer, details);
|
|
19230
|
-
const scope = { id: usageId, folder: `${consumer.name}_${usageId}`, workersId: [], limitFileSize: consumer.
|
|
19468
|
+
const scope = { id: usageId, folder: `${consumer.name}_${usageId}`, workersId: [], limitFileSize: consumer.maximumFileSize };
|
|
19231
19469
|
const pool = this.createPool();
|
|
19232
19470
|
try {
|
|
19233
19471
|
const start = performance.now();
|
|
@@ -19322,6 +19560,30 @@ var ExecutorOrchestratorClass = class {
|
|
|
19322
19560
|
postOperation.totalOutputCount = unifiedOutputCount;
|
|
19323
19561
|
Logger_default.log(`[${usageId}] Pivot complete: ${unifiedOutputCount} rows in ${Math.round(performance.now() - counter)}ms`);
|
|
19324
19562
|
}
|
|
19563
|
+
if (consumer.validate && consumer.validate.length > 0) {
|
|
19564
|
+
Logger_default.log(`[${usageId}] Running dataset-level validations`);
|
|
19565
|
+
counter = performance.now();
|
|
19566
|
+
const validationResults = await ConsumerExecutor_default.processDatasetValidation(consumer, ExecutorScope_default2.getMainPath(scope));
|
|
19567
|
+
tracker.measure("dataset-validation", performance.now() - counter);
|
|
19568
|
+
for (const result of validationResults) {
|
|
19569
|
+
if (result.onFail === "fail") {
|
|
19570
|
+
const err = new Error(`Dataset validation failed for consumer "${consumer.name}": ${result.message}`);
|
|
19571
|
+
Logger_default.error(err);
|
|
19572
|
+
throw err;
|
|
19573
|
+
} else if (result.onFail === "warn") {
|
|
19574
|
+
Logger_default.warn(`Dataset validation warning for consumer "${consumer.name}": ${result.message}`);
|
|
19575
|
+
}
|
|
19576
|
+
}
|
|
19577
|
+
Logger_default.log(`[${usageId}] Dataset validations complete in ${Math.round(performance.now() - counter)}ms`);
|
|
19578
|
+
}
|
|
19579
|
+
if (scope.limitFileSize) {
|
|
19580
|
+
Logger_default.log(`[${usageId}] Splitting output by size limit (${scope.limitFileSize})`);
|
|
19581
|
+
counter = performance.now();
|
|
19582
|
+
const writer = new ExecutorWriter_default();
|
|
19583
|
+
await writer.splitBySize(scope, ExecutorScope_default2.getMainPath(scope));
|
|
19584
|
+
tracker.measure("split-by-size", performance.now() - counter);
|
|
19585
|
+
Logger_default.log(`[${usageId}] Split complete in ${Math.round(performance.now() - counter)}ms`);
|
|
19586
|
+
}
|
|
19325
19587
|
counter = performance.now();
|
|
19326
19588
|
Logger_default.log(`[${usageId}] Exporting results to ${consumer.outputs.length} output(s)`);
|
|
19327
19589
|
const exportRes = await OutputExecutor_default.exportResult(consumer, ConsumerManager_default.getExpandedFields(consumer), scope);
|
|
@@ -19429,20 +19691,19 @@ var ExecutorOrchestratorClass = class {
|
|
|
19429
19691
|
this._getWorkerPath = () => {
|
|
19430
19692
|
const currentDir = __dirname;
|
|
19431
19693
|
if (ProcessENVManager_default.getEnvVariable("NODE_ENV") === "dev" || ProcessENVManager_default.getEnvVariable("NODE_ENV") === "development")
|
|
19432
|
-
return
|
|
19694
|
+
return import_path17.default.resolve("./.build/workers");
|
|
19433
19695
|
const forcedPath = ProcessENVManager_default.getEnvVariable("REMORA_WORKERS_PATH");
|
|
19434
19696
|
if (forcedPath && forcedPath.length > 0)
|
|
19435
|
-
return
|
|
19697
|
+
return import_path17.default.join(__dirname, forcedPath);
|
|
19436
19698
|
if (!currentDir.includes(".build")) {
|
|
19437
|
-
return
|
|
19699
|
+
return import_path17.default.join(__dirname, "../workers");
|
|
19438
19700
|
} else {
|
|
19439
|
-
return
|
|
19701
|
+
return import_path17.default.resolve("./.build/workers");
|
|
19440
19702
|
}
|
|
19441
19703
|
};
|
|
19442
19704
|
this.reconcileExecutorThreadsResults = async (scope, executorResults, tracker) => {
|
|
19443
19705
|
const mainPath = ExecutorScope_default2.getMainPath(scope);
|
|
19444
19706
|
ConsumerExecutor_default._ensurePath(mainPath);
|
|
19445
|
-
const writer = new ExecutorWriter_default();
|
|
19446
19707
|
if (executorResults.length > 1) {
|
|
19447
19708
|
Logger_default.log(`[${scope.id}] Merging ${executorResults.length} worker output files into ${mainPath}`);
|
|
19448
19709
|
const perf = performance.now();
|
|
@@ -19458,10 +19719,6 @@ var ExecutorOrchestratorClass = class {
|
|
|
19458
19719
|
Logger_default.log(`[${scope.id}] Single worker \u2014 renaming output to ${mainPath}`);
|
|
19459
19720
|
await import_promises9.default.rename(executorResults[0].resultUri, mainPath);
|
|
19460
19721
|
}
|
|
19461
|
-
if (scope.limitFileSize) {
|
|
19462
|
-
Logger_default.log(`[${scope.id}] Splitting output by size limit (${scope.limitFileSize})`);
|
|
19463
|
-
await writer.splitBySize(scope, mainPath);
|
|
19464
|
-
}
|
|
19465
19722
|
return mainPath;
|
|
19466
19723
|
};
|
|
19467
19724
|
this.performCleanupOperations = async (scope, tracker) => {
|