@budibase/server 2.6.19-alpha.30 → 2.6.19-alpha.34
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/builder/assets/{index.8469b14c.css → index.a96c516c.css} +1 -1
- package/builder/assets/{index.3dd3d237.js → index.b6e30d5b.js} +3 -3
- package/builder/index.html +2 -2
- package/dist/automation.js +148 -90
- package/dist/automation.js.map +3 -3
- package/dist/index.js +234 -164
- package/dist/index.js.map +3 -3
- package/dist/query.js +27 -13
- package/dist/query.js.map +2 -2
- package/package.json +9 -8
- package/src/automations/logging/index.ts +21 -0
- package/src/environment.ts +1 -0
- package/src/middleware/builder.ts +22 -13
- package/src/threads/automation.ts +49 -28
- package/src/threads/index.ts +9 -3
- package/src/threads/utils.ts +2 -0
- package/src/utilities/fileSystem/app.ts +14 -4
package/builder/index.html
CHANGED
|
@@ -8,8 +8,8 @@
|
|
|
8
8
|
<link rel="preconnect" href="https://fonts.gstatic.com" />
|
|
9
9
|
<link href="https://fonts.googleapis.com/css2?family=Source+Sans+Pro:wght@400;600;700&display=swap"
|
|
10
10
|
rel="stylesheet" />
|
|
11
|
-
<script type="module" crossorigin src="/builder/assets/index.
|
|
12
|
-
<link rel="stylesheet" href="/builder/assets/index.
|
|
11
|
+
<script type="module" crossorigin src="/builder/assets/index.b6e30d5b.js"></script>
|
|
12
|
+
<link rel="stylesheet" href="/builder/assets/index.a96c516c.css">
|
|
13
13
|
</head>
|
|
14
14
|
|
|
15
15
|
<body id="app">
|
package/dist/automation.js
CHANGED
|
@@ -128,6 +128,7 @@ var init_environment = __esm({
|
|
|
128
128
|
ENABLE_ANALYTICS: process.env.ENABLE_ANALYTICS,
|
|
129
129
|
SELF_HOSTED: process.env.SELF_HOSTED,
|
|
130
130
|
HTTP_MB_LIMIT: process.env.HTTP_MB_LIMIT,
|
|
131
|
+
FORKED_PROCESS_NAME: process.env.FORKED_PROCESS_NAME || "main",
|
|
131
132
|
// old
|
|
132
133
|
CLIENT_ID: process.env.CLIENT_ID,
|
|
133
134
|
_set(key, value) {
|
|
@@ -3440,9 +3441,76 @@ var init_users3 = __esm({
|
|
|
3440
3441
|
// ../backend-core/src/redis/redlockImpl.ts
|
|
3441
3442
|
var redlockImpl_exports = {};
|
|
3442
3443
|
__export(redlockImpl_exports, {
|
|
3443
|
-
doWithLock: () => doWithLock
|
|
3444
|
+
doWithLock: () => doWithLock,
|
|
3445
|
+
newRedlock: () => newRedlock
|
|
3444
3446
|
});
|
|
3445
|
-
|
|
3447
|
+
async function getClient(type, opts) {
|
|
3448
|
+
if (type === "custom" /* CUSTOM */) {
|
|
3449
|
+
return newRedlock(opts);
|
|
3450
|
+
}
|
|
3451
|
+
if (environment_default2.isTest() && type !== "try_once" /* TRY_ONCE */) {
|
|
3452
|
+
return newRedlock(OPTIONS.TEST);
|
|
3453
|
+
}
|
|
3454
|
+
switch (type) {
|
|
3455
|
+
case "try_once" /* TRY_ONCE */: {
|
|
3456
|
+
return newRedlock(OPTIONS.TRY_ONCE);
|
|
3457
|
+
}
|
|
3458
|
+
case "try_twice" /* TRY_TWICE */: {
|
|
3459
|
+
return newRedlock(OPTIONS.TRY_TWICE);
|
|
3460
|
+
}
|
|
3461
|
+
case "default" /* DEFAULT */: {
|
|
3462
|
+
return newRedlock(OPTIONS.DEFAULT);
|
|
3463
|
+
}
|
|
3464
|
+
case "delay_500" /* DELAY_500 */: {
|
|
3465
|
+
return newRedlock(OPTIONS.DELAY_500);
|
|
3466
|
+
}
|
|
3467
|
+
default: {
|
|
3468
|
+
throw new Error(`Could not get redlock client: ${type}`);
|
|
3469
|
+
}
|
|
3470
|
+
}
|
|
3471
|
+
}
|
|
3472
|
+
async function newRedlock(opts = {}) {
|
|
3473
|
+
let options2 = { ...OPTIONS.DEFAULT, ...opts };
|
|
3474
|
+
const redisWrapper = await getLockClient();
|
|
3475
|
+
const client3 = redisWrapper.getClient();
|
|
3476
|
+
return new import_redlock.default([client3], options2);
|
|
3477
|
+
}
|
|
3478
|
+
function getLockName(opts) {
|
|
3479
|
+
const prefix = opts.systemLock ? "system" : getTenantId();
|
|
3480
|
+
let name = `lock:${prefix}_${opts.name}`;
|
|
3481
|
+
if (opts.resource) {
|
|
3482
|
+
name = name + `_${opts.resource}`;
|
|
3483
|
+
}
|
|
3484
|
+
return name;
|
|
3485
|
+
}
|
|
3486
|
+
async function doWithLock(opts, task) {
|
|
3487
|
+
const redlock = await getClient(opts.type, opts.customOptions);
|
|
3488
|
+
let lock;
|
|
3489
|
+
try {
|
|
3490
|
+
const name = getLockName(opts);
|
|
3491
|
+
lock = await redlock.lock(name, opts.ttl);
|
|
3492
|
+
const result = await task();
|
|
3493
|
+
return { executed: true, result };
|
|
3494
|
+
} catch (e) {
|
|
3495
|
+
console.warn("lock error");
|
|
3496
|
+
if (e.name === "LockError") {
|
|
3497
|
+
if (opts.type === "try_once" /* TRY_ONCE */) {
|
|
3498
|
+
return { executed: false };
|
|
3499
|
+
} else {
|
|
3500
|
+
console.error(e);
|
|
3501
|
+
throw e;
|
|
3502
|
+
}
|
|
3503
|
+
} else {
|
|
3504
|
+
console.error(e);
|
|
3505
|
+
throw e;
|
|
3506
|
+
}
|
|
3507
|
+
} finally {
|
|
3508
|
+
if (lock) {
|
|
3509
|
+
await lock.unlock();
|
|
3510
|
+
}
|
|
3511
|
+
}
|
|
3512
|
+
}
|
|
3513
|
+
var import_redlock, OPTIONS;
|
|
3446
3514
|
var init_redlockImpl = __esm({
|
|
3447
3515
|
"../backend-core/src/redis/redlockImpl.ts"() {
|
|
3448
3516
|
import_redlock = __toESM(require("redlock"));
|
|
@@ -3450,33 +3518,14 @@ var init_redlockImpl = __esm({
|
|
|
3450
3518
|
init_src();
|
|
3451
3519
|
init_context2();
|
|
3452
3520
|
init_environment3();
|
|
3453
|
-
getClient = async (type, opts) => {
|
|
3454
|
-
if (type === "custom" /* CUSTOM */) {
|
|
3455
|
-
return newRedlock(opts);
|
|
3456
|
-
}
|
|
3457
|
-
if (environment_default2.isTest() && type !== "try_once" /* TRY_ONCE */) {
|
|
3458
|
-
return newRedlock(OPTIONS.TEST);
|
|
3459
|
-
}
|
|
3460
|
-
switch (type) {
|
|
3461
|
-
case "try_once" /* TRY_ONCE */: {
|
|
3462
|
-
return newRedlock(OPTIONS.TRY_ONCE);
|
|
3463
|
-
}
|
|
3464
|
-
case "default" /* DEFAULT */: {
|
|
3465
|
-
return newRedlock(OPTIONS.DEFAULT);
|
|
3466
|
-
}
|
|
3467
|
-
case "delay_500" /* DELAY_500 */: {
|
|
3468
|
-
return newRedlock(OPTIONS.DELAY_500);
|
|
3469
|
-
}
|
|
3470
|
-
default: {
|
|
3471
|
-
throw new Error(`Could not get redlock client: ${type}`);
|
|
3472
|
-
}
|
|
3473
|
-
}
|
|
3474
|
-
};
|
|
3475
3521
|
OPTIONS = {
|
|
3476
3522
|
TRY_ONCE: {
|
|
3477
3523
|
// immediately throws an error if the lock is already held
|
|
3478
3524
|
retryCount: 0
|
|
3479
3525
|
},
|
|
3526
|
+
TRY_TWICE: {
|
|
3527
|
+
retryCount: 1
|
|
3528
|
+
},
|
|
3480
3529
|
TEST: {
|
|
3481
3530
|
// higher retry count in unit tests
|
|
3482
3531
|
// due to high contention.
|
|
@@ -3503,44 +3552,6 @@ var init_redlockImpl = __esm({
|
|
|
3503
3552
|
retryDelay: 500
|
|
3504
3553
|
}
|
|
3505
3554
|
};
|
|
3506
|
-
newRedlock = async (opts = {}) => {
|
|
3507
|
-
let options2 = { ...OPTIONS.DEFAULT, ...opts };
|
|
3508
|
-
const redisWrapper = await getLockClient();
|
|
3509
|
-
const client3 = redisWrapper.getClient();
|
|
3510
|
-
return new import_redlock.default([client3], options2);
|
|
3511
|
-
};
|
|
3512
|
-
doWithLock = async (opts, task) => {
|
|
3513
|
-
const redlock = await getClient(opts.type, opts.customOptions);
|
|
3514
|
-
let lock;
|
|
3515
|
-
try {
|
|
3516
|
-
const prefix = opts.systemLock ? "system" : getTenantId();
|
|
3517
|
-
let name = `lock:${prefix}_${opts.name}`;
|
|
3518
|
-
if (opts.resource) {
|
|
3519
|
-
name = name + `_${opts.resource}`;
|
|
3520
|
-
}
|
|
3521
|
-
lock = await redlock.lock(name, opts.ttl);
|
|
3522
|
-
const result = await task();
|
|
3523
|
-
return { executed: true, result };
|
|
3524
|
-
} catch (e) {
|
|
3525
|
-
console.warn("lock error");
|
|
3526
|
-
if (e.name === "LockError") {
|
|
3527
|
-
if (opts.type === "try_once" /* TRY_ONCE */) {
|
|
3528
|
-
console.warn(e);
|
|
3529
|
-
return { executed: false };
|
|
3530
|
-
} else {
|
|
3531
|
-
console.error(e);
|
|
3532
|
-
throw e;
|
|
3533
|
-
}
|
|
3534
|
-
} else {
|
|
3535
|
-
console.error(e);
|
|
3536
|
-
throw e;
|
|
3537
|
-
}
|
|
3538
|
-
} finally {
|
|
3539
|
-
if (lock) {
|
|
3540
|
-
await lock.unlock();
|
|
3541
|
-
}
|
|
3542
|
-
}
|
|
3543
|
-
};
|
|
3544
3555
|
}
|
|
3545
3556
|
});
|
|
3546
3557
|
|
|
@@ -3647,6 +3658,7 @@ var init_logger = __esm({
|
|
|
3647
3658
|
}
|
|
3648
3659
|
const mergingObject = {
|
|
3649
3660
|
err: error,
|
|
3661
|
+
pid: process.pid,
|
|
3650
3662
|
...contextObject
|
|
3651
3663
|
};
|
|
3652
3664
|
if (objects.length) {
|
|
@@ -26770,8 +26782,10 @@ function makeVariableKey(queryId, variable) {
|
|
|
26770
26782
|
}
|
|
26771
26783
|
function threadSetup() {
|
|
26772
26784
|
if (environment_default.isTest() || environment_default.DISABLE_THREADING || !environment_default.isInThread()) {
|
|
26785
|
+
console.debug(`[${environment_default.FORKED_PROCESS_NAME}] thread setup skipped`);
|
|
26773
26786
|
return;
|
|
26774
26787
|
}
|
|
26788
|
+
console.debug(`[${environment_default.FORKED_PROCESS_NAME}] thread setup running`);
|
|
26775
26789
|
init8();
|
|
26776
26790
|
}
|
|
26777
26791
|
async function checkCacheForDynamicVariable(queryId, variable) {
|
|
@@ -26845,13 +26859,17 @@ var _Thread = class {
|
|
|
26845
26859
|
this.count = opts.count ? opts.count : 1;
|
|
26846
26860
|
this.disableThreading = this.shouldDisableThreading();
|
|
26847
26861
|
if (!this.disableThreading) {
|
|
26862
|
+
console.debug(
|
|
26863
|
+
`[${environment_default.FORKED_PROCESS_NAME}] initialising worker farm type=${type}`
|
|
26864
|
+
);
|
|
26848
26865
|
const workerOpts = {
|
|
26849
26866
|
autoStart: true,
|
|
26850
26867
|
maxConcurrentWorkers: this.count,
|
|
26851
26868
|
workerOptions: {
|
|
26852
26869
|
env: {
|
|
26853
26870
|
...process.env,
|
|
26854
|
-
FORKED_PROCESS: "1"
|
|
26871
|
+
FORKED_PROCESS: "1",
|
|
26872
|
+
FORKED_PROCESS_NAME: type
|
|
26855
26873
|
}
|
|
26856
26874
|
}
|
|
26857
26875
|
};
|
|
@@ -26861,6 +26879,10 @@ var _Thread = class {
|
|
|
26861
26879
|
}
|
|
26862
26880
|
this.workers = (0, import_worker_farm.default)(workerOpts, typeToFile(type), ["execute"]);
|
|
26863
26881
|
_Thread.workerRefs.push(this.workers);
|
|
26882
|
+
} else {
|
|
26883
|
+
console.debug(
|
|
26884
|
+
`[${environment_default.FORKED_PROCESS_NAME}] skipping worker farm type=${type}`
|
|
26885
|
+
);
|
|
26864
26886
|
}
|
|
26865
26887
|
}
|
|
26866
26888
|
shouldDisableThreading() {
|
|
@@ -26872,9 +26894,7 @@ var _Thread = class {
|
|
|
26872
26894
|
function fire(worker) {
|
|
26873
26895
|
worker.execute(job, (err, response2) => {
|
|
26874
26896
|
if (err && err.type === "TimeoutError") {
|
|
26875
|
-
reject(
|
|
26876
|
-
new Error(`Query response time exceeded ${timeout2}ms timeout.`)
|
|
26877
|
-
);
|
|
26897
|
+
reject(new Error(`Thread timeout exceeded ${timeout2}ms timeout.`));
|
|
26878
26898
|
} else if (err) {
|
|
26879
26899
|
reject(err);
|
|
26880
26900
|
} else {
|
|
@@ -31950,10 +31970,29 @@ init_constants6();
|
|
|
31950
31970
|
init_environment();
|
|
31951
31971
|
init_src4();
|
|
31952
31972
|
init_src2();
|
|
31973
|
+
var import_object_sizeof = __toESM(require("object-sizeof"));
|
|
31974
|
+
var MAX_LOG_SIZE_MB = 5;
|
|
31975
|
+
var MB_IN_BYTES = 1024 * 1024;
|
|
31976
|
+
function sanitiseResults(results) {
|
|
31977
|
+
const message = `[removed] - max results size of ${MAX_LOG_SIZE_MB}MB exceeded`;
|
|
31978
|
+
for (let step of results.steps) {
|
|
31979
|
+
step.inputs = {
|
|
31980
|
+
message
|
|
31981
|
+
};
|
|
31982
|
+
step.outputs = {
|
|
31983
|
+
message,
|
|
31984
|
+
success: step.outputs.success
|
|
31985
|
+
};
|
|
31986
|
+
}
|
|
31987
|
+
}
|
|
31953
31988
|
async function storeLog2(automation, results) {
|
|
31954
31989
|
if (environment_default.DISABLE_AUTOMATION_LOGS) {
|
|
31955
31990
|
return;
|
|
31956
31991
|
}
|
|
31992
|
+
const bytes = (0, import_object_sizeof.default)(results);
|
|
31993
|
+
if (bytes / MB_IN_BYTES > MAX_LOG_SIZE_MB) {
|
|
31994
|
+
sanitiseResults(results);
|
|
31995
|
+
}
|
|
31957
31996
|
await automations_exports.logs.storeLog(automation, results);
|
|
31958
31997
|
}
|
|
31959
31998
|
|
|
@@ -31962,6 +32001,7 @@ init_src();
|
|
|
31962
32001
|
init_src2();
|
|
31963
32002
|
var import_string_templates8 = __toESM(require_src2());
|
|
31964
32003
|
var import_fp8 = require("lodash/fp");
|
|
32004
|
+
var import_perf_hooks2 = require("perf_hooks");
|
|
31965
32005
|
init_utils15();
|
|
31966
32006
|
init_environment();
|
|
31967
32007
|
utils_default.threadSetup();
|
|
@@ -31969,8 +32009,8 @@ var FILTER_STEP_ID = BUILTIN_ACTION_DEFINITIONS.FILTER.stepId;
|
|
|
31969
32009
|
var LOOP_STEP_ID = BUILTIN_ACTION_DEFINITIONS.LOOP.stepId;
|
|
31970
32010
|
var CRON_STEP_ID2 = definitions.CRON.stepId;
|
|
31971
32011
|
var STOPPED_STATUS = { success: true, status: "stopped" /* STOPPED */ };
|
|
31972
|
-
function getLoopIterations(loopStep
|
|
31973
|
-
|
|
32012
|
+
function getLoopIterations(loopStep) {
|
|
32013
|
+
let binding = loopStep.inputs.binding;
|
|
31974
32014
|
if (!binding) {
|
|
31975
32015
|
return 0;
|
|
31976
32016
|
}
|
|
@@ -31986,7 +32026,6 @@ var Orchestrator = class {
|
|
|
31986
32026
|
constructor(job) {
|
|
31987
32027
|
let automation = job.data.automation;
|
|
31988
32028
|
let triggerOutput = job.data.event;
|
|
31989
|
-
let timeout2 = job.data.event.timeout;
|
|
31990
32029
|
const metadata = triggerOutput.metadata;
|
|
31991
32030
|
this._chainCount = metadata ? metadata.automationChainCount : 0;
|
|
31992
32031
|
this._appId = triggerOutput.appId;
|
|
@@ -32120,7 +32159,7 @@ var Orchestrator = class {
|
|
|
32120
32159
|
});
|
|
32121
32160
|
}
|
|
32122
32161
|
async execute() {
|
|
32123
|
-
var _a;
|
|
32162
|
+
var _a, _b;
|
|
32124
32163
|
this._context.env = await getEnvironmentVariables2();
|
|
32125
32164
|
let automation = this._automation;
|
|
32126
32165
|
let stopped = false;
|
|
@@ -32139,6 +32178,7 @@ var Orchestrator = class {
|
|
|
32139
32178
|
return;
|
|
32140
32179
|
}
|
|
32141
32180
|
}
|
|
32181
|
+
const start2 = import_perf_hooks2.performance.now();
|
|
32142
32182
|
for (let step of automation.definition.steps) {
|
|
32143
32183
|
if (timeoutFlag) {
|
|
32144
32184
|
break;
|
|
@@ -32157,20 +32197,16 @@ var Orchestrator = class {
|
|
|
32157
32197
|
}
|
|
32158
32198
|
if (loopStep) {
|
|
32159
32199
|
input = await (0, import_string_templates8.processObject)(loopStep.inputs, this._context);
|
|
32160
|
-
iterations = getLoopIterations(loopStep
|
|
32200
|
+
iterations = getLoopIterations(loopStep);
|
|
32161
32201
|
}
|
|
32162
32202
|
for (let index2 = 0; index2 < iterations; index2++) {
|
|
32163
32203
|
let originalStepInput = (0, import_fp8.cloneDeep)(step.inputs);
|
|
32164
32204
|
if (loopStep && input.binding) {
|
|
32165
|
-
let newInput = await (0, import_string_templates8.processObject)(
|
|
32166
|
-
loopStep.inputs,
|
|
32167
|
-
(0, import_fp8.cloneDeep)(this._context)
|
|
32168
|
-
);
|
|
32169
32205
|
let tempOutput = { items: loopSteps, iterations: iterationCount };
|
|
32170
32206
|
try {
|
|
32171
|
-
|
|
32207
|
+
loopStep.inputs.binding = typecastForLooping(
|
|
32172
32208
|
loopStep,
|
|
32173
|
-
|
|
32209
|
+
loopStep.inputs
|
|
32174
32210
|
);
|
|
32175
32211
|
} catch (err) {
|
|
32176
32212
|
this.updateContextAndOutput(loopStepNumber, step, tempOutput, {
|
|
@@ -32183,7 +32219,7 @@ var Orchestrator = class {
|
|
|
32183
32219
|
}
|
|
32184
32220
|
let item = [];
|
|
32185
32221
|
if (typeof loopStep.inputs.binding === "string" && loopStep.inputs.option === "String") {
|
|
32186
|
-
item = stringSplit(
|
|
32222
|
+
item = stringSplit(loopStep.inputs.binding);
|
|
32187
32223
|
} else if (Array.isArray(loopStep.inputs.binding)) {
|
|
32188
32224
|
item = loopStep.inputs.binding;
|
|
32189
32225
|
}
|
|
@@ -32326,7 +32362,21 @@ var Orchestrator = class {
|
|
|
32326
32362
|
loopSteps = [];
|
|
32327
32363
|
}
|
|
32328
32364
|
}
|
|
32329
|
-
|
|
32365
|
+
const end2 = import_perf_hooks2.performance.now();
|
|
32366
|
+
const executionTime = end2 - start2;
|
|
32367
|
+
console.info(`Execution time: ${executionTime} milliseconds`, {
|
|
32368
|
+
_logKey: "automation",
|
|
32369
|
+
executionTime
|
|
32370
|
+
});
|
|
32371
|
+
try {
|
|
32372
|
+
await storeLog2(this._automation, this.executionOutput);
|
|
32373
|
+
} catch (e) {
|
|
32374
|
+
if (e.status === 413 && ((_b = e.request) == null ? void 0 : _b.data)) {
|
|
32375
|
+
delete e.request.data;
|
|
32376
|
+
e.request.data = { message: "removed due to large size" };
|
|
32377
|
+
}
|
|
32378
|
+
logging_exports.logAlert("Error writing automation log", e);
|
|
32379
|
+
}
|
|
32330
32380
|
if (isProdAppID2(this._appId) && isRecurring(automation) && metadata) {
|
|
32331
32381
|
await this.updateMetadata(metadata);
|
|
32332
32382
|
}
|
|
@@ -32335,20 +32385,28 @@ var Orchestrator = class {
|
|
|
32335
32385
|
};
|
|
32336
32386
|
function execute3(job, callback) {
|
|
32337
32387
|
const appId = job.data.event.appId;
|
|
32388
|
+
const automationId = job.data.automation._id;
|
|
32338
32389
|
if (!appId) {
|
|
32339
32390
|
throw new Error("Unable to execute, event doesn't contain app ID.");
|
|
32340
32391
|
}
|
|
32341
|
-
|
|
32342
|
-
|
|
32343
|
-
|
|
32344
|
-
|
|
32345
|
-
|
|
32346
|
-
|
|
32347
|
-
|
|
32348
|
-
|
|
32349
|
-
|
|
32350
|
-
|
|
32351
|
-
|
|
32392
|
+
if (!automationId) {
|
|
32393
|
+
throw new Error("Unable to execute, event doesn't contain automation ID.");
|
|
32394
|
+
}
|
|
32395
|
+
return context_exports.doInAutomationContext({
|
|
32396
|
+
appId,
|
|
32397
|
+
automationId,
|
|
32398
|
+
task: async () => {
|
|
32399
|
+
const envVars = await getEnvironmentVariables2();
|
|
32400
|
+
await context_exports.doInEnvironmentContext(envVars, async () => {
|
|
32401
|
+
const automationOrchestrator = new Orchestrator(job);
|
|
32402
|
+
try {
|
|
32403
|
+
const response2 = await automationOrchestrator.execute();
|
|
32404
|
+
callback(null, response2);
|
|
32405
|
+
} catch (err) {
|
|
32406
|
+
callback(err);
|
|
32407
|
+
}
|
|
32408
|
+
});
|
|
32409
|
+
}
|
|
32352
32410
|
});
|
|
32353
32411
|
}
|
|
32354
32412
|
function executeSynchronously(job) {
|