@xuda.io/runtime-bundle 1.0.489 → 1.0.491
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/js/xuda-runtime-bundle.js +314 -7
- package/js/xuda-runtime-bundle.min.js +1 -1
- package/js/xuda-runtime-slim.js +314 -7
- package/js/xuda-runtime-slim.min.es.js +314 -7
- package/js/xuda-runtime-slim.min.js +1 -1
- package/js/xuda-server-bundle.min.mjs +1 -1
- package/js/xuda-server-bundle.mjs +314 -7
- package/js/xuda-worker-bundle.js +314 -7
- package/js/xuda-worker-bundle.min.js +1 -1
- package/package.json +1 -1
package/js/xuda-runtime-slim.js
CHANGED
|
@@ -10474,7 +10474,7 @@ func.events.invoke = async function (event_id) {
|
|
|
10474
10474
|
};
|
|
10475
10475
|
func.expression = {};
|
|
10476
10476
|
|
|
10477
|
-
func.expression.
|
|
10477
|
+
func.expression.get_org = async function (SESSION_ID, valP, dsSessionP, sourceP, rowIdP, sourceActionP, secondPassP, calling_fieldIdP, fieldsP, debug_infoP, iterate_info, js_script_callback, jobNo, api_output_type) {
|
|
10478
10478
|
class xu_class {
|
|
10479
10479
|
async get() {
|
|
10480
10480
|
var ret;
|
|
@@ -10594,7 +10594,7 @@ func.expression.get = async function (SESSION_ID, valP, dsSessionP, sourceP, row
|
|
|
10594
10594
|
// var split = [];
|
|
10595
10595
|
var var_Arr = [];
|
|
10596
10596
|
const split = func.expression.parse(ret) || [];
|
|
10597
|
-
console.log(valP, split);
|
|
10597
|
+
// console.log(valP, split);
|
|
10598
10598
|
for await (const [arr_key, val] of Object.entries(split)) {
|
|
10599
10599
|
// run each field
|
|
10600
10600
|
const key = Number(arr_key);
|
|
@@ -10828,6 +10828,177 @@ func.expression.get = async function (SESSION_ID, valP, dsSessionP, sourceP, row
|
|
|
10828
10828
|
return new_class.get();
|
|
10829
10829
|
};
|
|
10830
10830
|
|
|
10831
|
+
func.expression.get = async function (SESSION_ID, valP, dsSessionP, sourceP, rowIdP, sourceActionP, secondPassP, calling_fieldIdP, fieldsP = {}, debug_infoP, iterate_info, js_script_callback, jobNo, api_output_type) {
|
|
10832
|
+
const evalJson = (text) => eval(`(${text})`);
|
|
10833
|
+
const replaceQuotes = (str) => {
|
|
10834
|
+
for (const [key, val] of Object.entries(fields)) {
|
|
10835
|
+
if (typeof val === 'string') str = str.replace(`"${val}"`, val.replace(/"/g, ''));
|
|
10836
|
+
}
|
|
10837
|
+
return str;
|
|
10838
|
+
};
|
|
10839
|
+
|
|
10840
|
+
let ret, error, warning, var_error_found;
|
|
10841
|
+
const fields = { ...fieldsP };
|
|
10842
|
+
|
|
10843
|
+
// Initial value processing
|
|
10844
|
+
if (valP === null || typeof valP === 'undefined') ret = '';
|
|
10845
|
+
else if (typeof valP === 'boolean') ret = valP ? 'Y' : 'N';
|
|
10846
|
+
else ret = valP.toString();
|
|
10847
|
+
|
|
10848
|
+
ret = ret.replace(/\&/g, '&');
|
|
10849
|
+
ret = func.utils.replace_studio_drive_url(SESSION_ID, ret);
|
|
10850
|
+
|
|
10851
|
+
// End results helper
|
|
10852
|
+
const endResults = () => {
|
|
10853
|
+
if (['update', 'javascript'].includes(sourceP) && typeof ret === 'string') {
|
|
10854
|
+
ret = replaceQuotes(ret);
|
|
10855
|
+
}
|
|
10856
|
+
if ((error || warning) && SESSION_OBJ[SESSION_ID]?.DS_GLB[dsSessionP]) {
|
|
10857
|
+
func.utils.debug.log(SESSION_ID, SESSION_OBJ[SESSION_ID].DS_GLB[dsSessionP].nodeId, {
|
|
10858
|
+
module: 'expression',
|
|
10859
|
+
action: sourceP,
|
|
10860
|
+
source: calling_fieldIdP,
|
|
10861
|
+
prop: ret,
|
|
10862
|
+
details: ret,
|
|
10863
|
+
result: ret,
|
|
10864
|
+
error,
|
|
10865
|
+
warning,
|
|
10866
|
+
fields: null,
|
|
10867
|
+
type: 'exp',
|
|
10868
|
+
prog_id: SESSION_OBJ[SESSION_ID].DS_GLB[dsSessionP].prog_id,
|
|
10869
|
+
debug_info: debug_infoP,
|
|
10870
|
+
});
|
|
10871
|
+
}
|
|
10872
|
+
return { result: ret, fields, error, warning, req: valP, var_error_found };
|
|
10873
|
+
};
|
|
10874
|
+
|
|
10875
|
+
// Handle non-variable cases
|
|
10876
|
+
const handleNonVariable = async () => {
|
|
10877
|
+
try {
|
|
10878
|
+
if (sourceP !== 'arguments') {
|
|
10879
|
+
if (ret.startsWith('_DATE_')) ret = ret.slice(6);
|
|
10880
|
+
else if (/^\d{4}-\d{2}-\d{2}$/.test(ret) || ret === 'self') return endResults();
|
|
10881
|
+
else ret = await func.expression.secure_eval(SESSION_ID, sourceP, ret, jobNo, dsSessionP, js_script_callback);
|
|
10882
|
+
} else {
|
|
10883
|
+
ret = ret.replace(/_NULL/gi, '');
|
|
10884
|
+
}
|
|
10885
|
+
return endResults();
|
|
10886
|
+
} catch (err) {
|
|
10887
|
+
error = err.message;
|
|
10888
|
+
return endResults();
|
|
10889
|
+
}
|
|
10890
|
+
};
|
|
10891
|
+
|
|
10892
|
+
// Early return for simple cases
|
|
10893
|
+
if (!func.expression.validate_variables(valP)) return await handleNonVariable();
|
|
10894
|
+
if (glb.emailRegex.test(await func.expression.secure_eval(SESSION_ID, sourceP, valP, jobNo, dsSessionP, js_script_callback))) {
|
|
10895
|
+
return await handleNonVariable();
|
|
10896
|
+
}
|
|
10897
|
+
|
|
10898
|
+
// Parse and process variables
|
|
10899
|
+
const split = func.expression.parse(ret) || [];
|
|
10900
|
+
const var_Arr = await Promise.all(
|
|
10901
|
+
split.map(async (val, key) => {
|
|
10902
|
+
const result = { value: val.value, fieldId: val.fieldId };
|
|
10903
|
+
|
|
10904
|
+
if (!val.fieldId) return result;
|
|
10905
|
+
|
|
10906
|
+
// Handle _THIS substitution
|
|
10907
|
+
if (val.fieldId.startsWith('_THIS') && calling_fieldIdP) {
|
|
10908
|
+
result.fieldId = val.fieldId.length === 5 ? calling_fieldIdP : calling_fieldIdP + val.fieldId.slice(5);
|
|
10909
|
+
}
|
|
10910
|
+
|
|
10911
|
+
// Fetch value from datasource
|
|
10912
|
+
const { ret: fetchedValue, fieldIdP } = await func.datasource.get_value(SESSION_ID, result.fieldId, dsSessionP, rowIdP);
|
|
10913
|
+
result.value = fetchedValue?.value ?? (sourceP === 'exp' ? fetchedValue?.value : '""');
|
|
10914
|
+
result.type = fetchedValue?.type;
|
|
10915
|
+
|
|
10916
|
+
// Handle iteration
|
|
10917
|
+
if (iterate_info) {
|
|
10918
|
+
if (iterate_info.iterator_key === fieldIdP) result.value = iterate_info._key;
|
|
10919
|
+
if (iterate_info.iterator_val === fieldIdP) result.value = iterate_info._val;
|
|
10920
|
+
}
|
|
10921
|
+
|
|
10922
|
+
// Process nested properties
|
|
10923
|
+
if (val.value.includes('[') || val.value.includes('.')) {
|
|
10924
|
+
const { property1, property2 } = await func.expression.get_property(val.value);
|
|
10925
|
+
const data = fetchedValue?.type === 'object' ? fetchedValue.value : fetchedValue?.prop;
|
|
10926
|
+
|
|
10927
|
+
if (key > 0 && val.value.includes(']') && !val.value.includes('[') && split[key - 1].value) {
|
|
10928
|
+
const prevData = split[key - 1].value;
|
|
10929
|
+
result.value = prevData[fieldIdP];
|
|
10930
|
+
if (val.value.includes('.') && prevData[fieldIdP]) {
|
|
10931
|
+
result.value = prevData[fieldIdP][property2] ?? '';
|
|
10932
|
+
}
|
|
10933
|
+
} else if (data) {
|
|
10934
|
+
if (property1) result.value = data[property1] ?? '';
|
|
10935
|
+
if (property2) result.value = (property1 ? data[property1]?.[property2] : data[property2]) ?? '';
|
|
10936
|
+
}
|
|
10937
|
+
}
|
|
10938
|
+
|
|
10939
|
+
fields[fieldIdP] = result.value;
|
|
10940
|
+
return result;
|
|
10941
|
+
}),
|
|
10942
|
+
);
|
|
10943
|
+
|
|
10944
|
+
// Final evaluation
|
|
10945
|
+
try {
|
|
10946
|
+
const res = var_Arr.map((val, key) => {
|
|
10947
|
+
if (sourceP === 'UI Property EXP' || sourceP === 'UI Attr EXP') {
|
|
10948
|
+
const { changed, value } = func.utils.get_drive_url(SESSION_ID, val.value, sourceP === 'UI Attr EXP' && var_Arr.length > 1);
|
|
10949
|
+
if (changed) return value;
|
|
10950
|
+
}
|
|
10951
|
+
|
|
10952
|
+
let value = val.value;
|
|
10953
|
+
if (var_Arr.length > 1) {
|
|
10954
|
+
if (!['DbQuery', 'alert', 'exp', 'api_rendered_output'].includes(sourceP) && ['string', 'date'].includes(val.type)) {
|
|
10955
|
+
value = `\`${value}\``;
|
|
10956
|
+
} else if (sourceP === 'api_rendered_output' && api_output_type === 'json' && ['string', 'date'].includes(val.type)) {
|
|
10957
|
+
value = `"${value}"`;
|
|
10958
|
+
}
|
|
10959
|
+
}
|
|
10960
|
+
|
|
10961
|
+
if (val.fieldId && typeof value === 'string') {
|
|
10962
|
+
if (['query', 'condition', 'range', 'sort', 'locate'].includes(sourceP)) value = value.replace(/↵|\r\n|\n|\r/g, '');
|
|
10963
|
+
if (['init', 'update', 'virtual'].includes(sourceP)) value = value.replace(/↵|\r\n|\n|\r/g, '\\n');
|
|
10964
|
+
if (typeof IS_PROCESS_SERVER !== 'undefined') value = value.replace(/↵|\r\n|\n|\r/g, '<br>');
|
|
10965
|
+
fields[val.fieldId] = value;
|
|
10966
|
+
}
|
|
10967
|
+
|
|
10968
|
+
if (typeof value === 'object' && var_Arr.length > 1) {
|
|
10969
|
+
value = Array.isArray(value) || var_Arr[key + 1]?.value?.includes('.') ? JSON.stringify(value) : `(${JSON.stringify(value)})`;
|
|
10970
|
+
}
|
|
10971
|
+
|
|
10972
|
+
if (!val.type === 'exp' && sourceP !== 'exp' && typeof value === 'string' && value.startsWith('@')) {
|
|
10973
|
+
warning = `Error encoding ${value}`;
|
|
10974
|
+
var_error_found = true;
|
|
10975
|
+
return '0';
|
|
10976
|
+
}
|
|
10977
|
+
return value;
|
|
10978
|
+
});
|
|
10979
|
+
|
|
10980
|
+
ret = res.length === 1 ? res[0] : res.join('');
|
|
10981
|
+
if (var_Arr.some((v) => v.type === 'exp') && sourceP !== 'exp' && !secondPassP) {
|
|
10982
|
+
const exp = await func.expression.get(SESSION_ID, ret, dsSessionP, sourceP, rowIdP, sourceActionP, true, calling_fieldIdP, fields, debug_infoP);
|
|
10983
|
+
ret = exp.res?.[0] ?? exp.result;
|
|
10984
|
+
Object.assign(fields, exp.fields);
|
|
10985
|
+
} else if (!secondPassP && !['arguments', 'api_rendered_output', 'DbQuery'].includes(sourceP)) {
|
|
10986
|
+
ret = await func.expression.secure_eval(SESSION_ID, sourceP, ret, jobNo, dsSessionP, js_script_callback);
|
|
10987
|
+
} else if (sourceP === 'DbQuery') {
|
|
10988
|
+
ret = JSON.stringify(evalJson(ret));
|
|
10989
|
+
}
|
|
10990
|
+
|
|
10991
|
+
if (typeof ret === 'string' && ret.startsWith('@')) {
|
|
10992
|
+
error = 'Error encoding @ var';
|
|
10993
|
+
var_error_found = true;
|
|
10994
|
+
}
|
|
10995
|
+
} catch (err) {
|
|
10996
|
+
error = err.message;
|
|
10997
|
+
}
|
|
10998
|
+
|
|
10999
|
+
return endResults();
|
|
11000
|
+
};
|
|
11001
|
+
|
|
10831
11002
|
func.expression.parse_org = function (strP) {
|
|
10832
11003
|
var extract_str = function (strP, posP) {
|
|
10833
11004
|
if (!posP) posP = 0;
|
|
@@ -11009,7 +11180,7 @@ func.expression.parse = function (input) {
|
|
|
11009
11180
|
return segments;
|
|
11010
11181
|
};
|
|
11011
11182
|
|
|
11012
|
-
func.expression.
|
|
11183
|
+
func.expression.get_property_org = async function (valP) {
|
|
11013
11184
|
async function secure_eval(val) {
|
|
11014
11185
|
if (typeof IS_PROCESS_SERVER === 'undefined') {
|
|
11015
11186
|
try {
|
|
@@ -11047,21 +11218,73 @@ func.expression.get_property = async function (valP) {
|
|
|
11047
11218
|
property2: property2,
|
|
11048
11219
|
};
|
|
11049
11220
|
};
|
|
11050
|
-
|
|
11221
|
+
|
|
11222
|
+
func.expression.get_property = async function (valP) {
|
|
11223
|
+
if (typeof valP !== 'string') return { property1: undefined, property2: undefined };
|
|
11224
|
+
|
|
11225
|
+
const secureEval = async (expr) => {
|
|
11226
|
+
if (typeof IS_PROCESS_SERVER === 'undefined') {
|
|
11227
|
+
try {
|
|
11228
|
+
return eval(expr);
|
|
11229
|
+
} catch (err) {
|
|
11230
|
+
console.error(err);
|
|
11231
|
+
return undefined;
|
|
11232
|
+
}
|
|
11233
|
+
}
|
|
11234
|
+
try {
|
|
11235
|
+
const vm = new VM.VM({
|
|
11236
|
+
sandbox: {
|
|
11237
|
+
func,
|
|
11238
|
+
SESSION_ID,
|
|
11239
|
+
SESSION_OBJ: { [SESSION_ID]: SESSION_OBJ[SESSION_ID] },
|
|
11240
|
+
},
|
|
11241
|
+
timeout: 1000,
|
|
11242
|
+
allowAsync: false,
|
|
11243
|
+
});
|
|
11244
|
+
return await vm.run(expr);
|
|
11245
|
+
} catch {
|
|
11246
|
+
return undefined; // Simplified error handling
|
|
11247
|
+
}
|
|
11248
|
+
};
|
|
11249
|
+
|
|
11250
|
+
let property1, property2;
|
|
11251
|
+
const bracketStart = valP.indexOf('[');
|
|
11252
|
+
const bracketEnd = valP.indexOf(']');
|
|
11253
|
+
|
|
11254
|
+
if (bracketStart > -1 && bracketEnd > bracketStart) {
|
|
11255
|
+
const expr = valP.slice(bracketStart + 1, bracketEnd);
|
|
11256
|
+
property1 = await secureEval(expr);
|
|
11257
|
+
}
|
|
11258
|
+
|
|
11259
|
+
const dotIndex = valP.indexOf('.');
|
|
11260
|
+
if (dotIndex > -1) {
|
|
11261
|
+
property2 = valP.slice(dotIndex + 1);
|
|
11262
|
+
}
|
|
11263
|
+
|
|
11264
|
+
return { property1, property2 };
|
|
11265
|
+
};
|
|
11266
|
+
|
|
11267
|
+
func.expression.validate_constant_org = function (valP) {
|
|
11051
11268
|
var patt = /["']/;
|
|
11052
11269
|
if (typeof valP === 'string' && patt.test(valP.substr(0, 1)) && patt.test(valP.substr(0, valP.length - 1))) return true;
|
|
11053
11270
|
else return false;
|
|
11054
11271
|
};
|
|
11055
|
-
func.expression.
|
|
11272
|
+
func.expression.validate_variables_org = function (valP) {
|
|
11056
11273
|
if (typeof valP === 'string' && valP.indexOf('@') > -1) return true;
|
|
11057
11274
|
else return false;
|
|
11058
11275
|
};
|
|
11059
|
-
func.expression.
|
|
11276
|
+
func.expression.remove_quotes_org = function (valP) {
|
|
11060
11277
|
if (func.expression.validate_constant(valP)) return valP.substr(1, valP.length - 2);
|
|
11061
11278
|
else return valP;
|
|
11062
11279
|
};
|
|
11063
11280
|
|
|
11064
|
-
func.expression.
|
|
11281
|
+
func.expression.validate_constant = (valP) => typeof valP === 'string' && /^["'].*["']$/.test(valP);
|
|
11282
|
+
|
|
11283
|
+
func.expression.validate_variables = (valP) => typeof valP === 'string' && valP.includes('@');
|
|
11284
|
+
|
|
11285
|
+
func.expression.remove_quotes = (valP) => (func.expression.validate_constant(valP) && typeof valP === 'string' ? valP.slice(1, -1) : valP);
|
|
11286
|
+
|
|
11287
|
+
func.expression.secure_eval_org = async function (SESSION_ID, sourceP, val, job_id, dsSessionP, js_script_callback, evt) {
|
|
11065
11288
|
const api_utils = await func.common.get_module(SESSION_ID, 'xuda-api-library.mjs', {
|
|
11066
11289
|
func,
|
|
11067
11290
|
glb,
|
|
@@ -11162,6 +11385,90 @@ func.expression.secure_eval = async function (SESSION_ID, sourceP, val, job_id,
|
|
|
11162
11385
|
}
|
|
11163
11386
|
}
|
|
11164
11387
|
};
|
|
11388
|
+
|
|
11389
|
+
func.expression.secure_eval = async function (SESSION_ID, sourceP, val, job_id, dsSessionP, js_script_callback, evt) {
|
|
11390
|
+
if (typeof val !== 'string') return val;
|
|
11391
|
+
|
|
11392
|
+
const xu = await func.common.get_module(SESSION_ID, 'xuda-api-library.mjs', {
|
|
11393
|
+
func,
|
|
11394
|
+
glb,
|
|
11395
|
+
SESSION_OBJ,
|
|
11396
|
+
SESSION_ID,
|
|
11397
|
+
APP_OBJ,
|
|
11398
|
+
dsSession: dsSessionP,
|
|
11399
|
+
job_id,
|
|
11400
|
+
});
|
|
11401
|
+
|
|
11402
|
+
const isServer = typeof IS_PROCESS_SERVER !== 'undefined' || typeof IS_DOCKER !== 'undefined';
|
|
11403
|
+
|
|
11404
|
+
// Client-side execution
|
|
11405
|
+
if (!isServer) {
|
|
11406
|
+
try {
|
|
11407
|
+
return eval(val);
|
|
11408
|
+
} catch {
|
|
11409
|
+
try {
|
|
11410
|
+
return JSON5.parse(val);
|
|
11411
|
+
} catch {
|
|
11412
|
+
return val;
|
|
11413
|
+
}
|
|
11414
|
+
}
|
|
11415
|
+
}
|
|
11416
|
+
|
|
11417
|
+
// Server-side execution
|
|
11418
|
+
const sandbox = {
|
|
11419
|
+
func,
|
|
11420
|
+
xu,
|
|
11421
|
+
SESSION_ID,
|
|
11422
|
+
SESSION_OBJ: { [SESSION_ID]: SESSION_OBJ[SESSION_ID] },
|
|
11423
|
+
callback: js_script_callback,
|
|
11424
|
+
job_id,
|
|
11425
|
+
...(sourceP === 'javascript' ? { axios, got, FormData } : {}),
|
|
11426
|
+
};
|
|
11427
|
+
|
|
11428
|
+
const handleError = (err) => {
|
|
11429
|
+
console.error('Execution error:', err);
|
|
11430
|
+
func.events.delete_job(SESSION_ID, job_id);
|
|
11431
|
+
if (isServer && !SESSION_OBJ[SESSION_ID].crawler) {
|
|
11432
|
+
if (sourceP === 'javascript') {
|
|
11433
|
+
__.rpi.write_log(SESSION_OBJ[SESSION_ID].app_id, 'error', 'worker', 'vm error', err, null, val, 'func.expression.get.secure_eval');
|
|
11434
|
+
} else {
|
|
11435
|
+
__.db.add_error_log(SESSION_OBJ[SESSION_ID].app_id, 'api', err);
|
|
11436
|
+
}
|
|
11437
|
+
}
|
|
11438
|
+
return val; // Fallback to original value
|
|
11439
|
+
};
|
|
11440
|
+
|
|
11441
|
+
if (sourceP === 'javascript') {
|
|
11442
|
+
process.on('uncaughtException', handleError);
|
|
11443
|
+
try {
|
|
11444
|
+
const dir = path.join(_conf.studio_drive_path, SESSION_OBJ[SESSION_ID].app_id, 'node_modules');
|
|
11445
|
+
const script = new VM.VMScript(`try { ${val} } catch (e) { func.api.error(SESSION_ID, "nodejs error", e); console.error(e); func.events.delete_job(SESSION_ID, "${job_id}"); }`, { filename: dir, dirname: dir });
|
|
11446
|
+
const vm = new VM.NodeVM({
|
|
11447
|
+
require: { external: true },
|
|
11448
|
+
sandbox,
|
|
11449
|
+
timeout: 60000,
|
|
11450
|
+
});
|
|
11451
|
+
return await vm.run(script, { filename: dir, dirname: dir });
|
|
11452
|
+
} catch (err) {
|
|
11453
|
+
return handleError(err);
|
|
11454
|
+
}
|
|
11455
|
+
}
|
|
11456
|
+
|
|
11457
|
+
try {
|
|
11458
|
+
const vm = new VM.VM({
|
|
11459
|
+
sandbox,
|
|
11460
|
+
timeout: 1000,
|
|
11461
|
+
allowAsync: false,
|
|
11462
|
+
});
|
|
11463
|
+
return await vm.run(val);
|
|
11464
|
+
} catch {
|
|
11465
|
+
try {
|
|
11466
|
+
return JSON5.parse(val);
|
|
11467
|
+
} catch {
|
|
11468
|
+
return val;
|
|
11469
|
+
}
|
|
11470
|
+
}
|
|
11471
|
+
};
|
|
11165
11472
|
func.UI.screen = {};
|
|
11166
11473
|
func.UI.screen.init = async function (SESSION_ID, prog_id, sourceScreenP, callingDataSource_objP, $callingContainerP, triggerIdP, rowIdP, jobNoP, is_panelP, parameters_obj_inP, source_functionP, call_screen_propertiesP) {
|
|
11167
11474
|
if (!prog_id) return console.error('program is empty');
|