@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.
@@ -34922,7 +34922,7 @@ func.UI.component.init_xu_nav = function ($container, $nav) {
34922
34922
  };
34923
34923
  func.expression = {};
34924
34924
 
34925
- 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) {
34925
+ 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) {
34926
34926
  class xu_class {
34927
34927
  async get() {
34928
34928
  var ret;
@@ -35042,7 +35042,7 @@ func.expression.get = async function (SESSION_ID, valP, dsSessionP, sourceP, row
35042
35042
  // var split = [];
35043
35043
  var var_Arr = [];
35044
35044
  const split = func.expression.parse(ret) || [];
35045
- console.log(valP, split);
35045
+ // console.log(valP, split);
35046
35046
  for await (const [arr_key, val] of Object.entries(split)) {
35047
35047
  // run each field
35048
35048
  const key = Number(arr_key);
@@ -35276,6 +35276,177 @@ func.expression.get = async function (SESSION_ID, valP, dsSessionP, sourceP, row
35276
35276
  return new_class.get();
35277
35277
  };
35278
35278
 
35279
+ 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) {
35280
+ const evalJson = (text) => eval(`(${text})`);
35281
+ const replaceQuotes = (str) => {
35282
+ for (const [key, val] of Object.entries(fields)) {
35283
+ if (typeof val === 'string') str = str.replace(`"${val}"`, val.replace(/"/g, ''));
35284
+ }
35285
+ return str;
35286
+ };
35287
+
35288
+ let ret, error, warning, var_error_found;
35289
+ const fields = { ...fieldsP };
35290
+
35291
+ // Initial value processing
35292
+ if (valP === null || typeof valP === 'undefined') ret = '';
35293
+ else if (typeof valP === 'boolean') ret = valP ? 'Y' : 'N';
35294
+ else ret = valP.toString();
35295
+
35296
+ ret = ret.replace(/\&/g, '&');
35297
+ ret = func.utils.replace_studio_drive_url(SESSION_ID, ret);
35298
+
35299
+ // End results helper
35300
+ const endResults = () => {
35301
+ if (['update', 'javascript'].includes(sourceP) && typeof ret === 'string') {
35302
+ ret = replaceQuotes(ret);
35303
+ }
35304
+ if ((error || warning) && SESSION_OBJ[SESSION_ID]?.DS_GLB[dsSessionP]) {
35305
+ func.utils.debug.log(SESSION_ID, SESSION_OBJ[SESSION_ID].DS_GLB[dsSessionP].nodeId, {
35306
+ module: 'expression',
35307
+ action: sourceP,
35308
+ source: calling_fieldIdP,
35309
+ prop: ret,
35310
+ details: ret,
35311
+ result: ret,
35312
+ error,
35313
+ warning,
35314
+ fields: null,
35315
+ type: 'exp',
35316
+ prog_id: SESSION_OBJ[SESSION_ID].DS_GLB[dsSessionP].prog_id,
35317
+ debug_info: debug_infoP,
35318
+ });
35319
+ }
35320
+ return { result: ret, fields, error, warning, req: valP, var_error_found };
35321
+ };
35322
+
35323
+ // Handle non-variable cases
35324
+ const handleNonVariable = async () => {
35325
+ try {
35326
+ if (sourceP !== 'arguments') {
35327
+ if (ret.startsWith('_DATE_')) ret = ret.slice(6);
35328
+ else if (/^\d{4}-\d{2}-\d{2}$/.test(ret) || ret === 'self') return endResults();
35329
+ else ret = await func.expression.secure_eval(SESSION_ID, sourceP, ret, jobNo, dsSessionP, js_script_callback);
35330
+ } else {
35331
+ ret = ret.replace(/_NULL/gi, '');
35332
+ }
35333
+ return endResults();
35334
+ } catch (err) {
35335
+ error = err.message;
35336
+ return endResults();
35337
+ }
35338
+ };
35339
+
35340
+ // Early return for simple cases
35341
+ if (!func.expression.validate_variables(valP)) return await handleNonVariable();
35342
+ if (glb.emailRegex.test(await func.expression.secure_eval(SESSION_ID, sourceP, valP, jobNo, dsSessionP, js_script_callback))) {
35343
+ return await handleNonVariable();
35344
+ }
35345
+
35346
+ // Parse and process variables
35347
+ const split = func.expression.parse(ret) || [];
35348
+ const var_Arr = await Promise.all(
35349
+ split.map(async (val, key) => {
35350
+ const result = { value: val.value, fieldId: val.fieldId };
35351
+
35352
+ if (!val.fieldId) return result;
35353
+
35354
+ // Handle _THIS substitution
35355
+ if (val.fieldId.startsWith('_THIS') && calling_fieldIdP) {
35356
+ result.fieldId = val.fieldId.length === 5 ? calling_fieldIdP : calling_fieldIdP + val.fieldId.slice(5);
35357
+ }
35358
+
35359
+ // Fetch value from datasource
35360
+ const { ret: fetchedValue, fieldIdP } = await func.datasource.get_value(SESSION_ID, result.fieldId, dsSessionP, rowIdP);
35361
+ result.value = fetchedValue?.value ?? (sourceP === 'exp' ? fetchedValue?.value : '""');
35362
+ result.type = fetchedValue?.type;
35363
+
35364
+ // Handle iteration
35365
+ if (iterate_info) {
35366
+ if (iterate_info.iterator_key === fieldIdP) result.value = iterate_info._key;
35367
+ if (iterate_info.iterator_val === fieldIdP) result.value = iterate_info._val;
35368
+ }
35369
+
35370
+ // Process nested properties
35371
+ if (val.value.includes('[') || val.value.includes('.')) {
35372
+ const { property1, property2 } = await func.expression.get_property(val.value);
35373
+ const data = fetchedValue?.type === 'object' ? fetchedValue.value : fetchedValue?.prop;
35374
+
35375
+ if (key > 0 && val.value.includes(']') && !val.value.includes('[') && split[key - 1].value) {
35376
+ const prevData = split[key - 1].value;
35377
+ result.value = prevData[fieldIdP];
35378
+ if (val.value.includes('.') && prevData[fieldIdP]) {
35379
+ result.value = prevData[fieldIdP][property2] ?? '';
35380
+ }
35381
+ } else if (data) {
35382
+ if (property1) result.value = data[property1] ?? '';
35383
+ if (property2) result.value = (property1 ? data[property1]?.[property2] : data[property2]) ?? '';
35384
+ }
35385
+ }
35386
+
35387
+ fields[fieldIdP] = result.value;
35388
+ return result;
35389
+ }),
35390
+ );
35391
+
35392
+ // Final evaluation
35393
+ try {
35394
+ const res = var_Arr.map((val, key) => {
35395
+ if (sourceP === 'UI Property EXP' || sourceP === 'UI Attr EXP') {
35396
+ const { changed, value } = func.utils.get_drive_url(SESSION_ID, val.value, sourceP === 'UI Attr EXP' && var_Arr.length > 1);
35397
+ if (changed) return value;
35398
+ }
35399
+
35400
+ let value = val.value;
35401
+ if (var_Arr.length > 1) {
35402
+ if (!['DbQuery', 'alert', 'exp', 'api_rendered_output'].includes(sourceP) && ['string', 'date'].includes(val.type)) {
35403
+ value = `\`${value}\``;
35404
+ } else if (sourceP === 'api_rendered_output' && api_output_type === 'json' && ['string', 'date'].includes(val.type)) {
35405
+ value = `"${value}"`;
35406
+ }
35407
+ }
35408
+
35409
+ if (val.fieldId && typeof value === 'string') {
35410
+ if (['query', 'condition', 'range', 'sort', 'locate'].includes(sourceP)) value = value.replace(/↵|\r\n|\n|\r/g, '');
35411
+ if (['init', 'update', 'virtual'].includes(sourceP)) value = value.replace(/↵|\r\n|\n|\r/g, '\\n');
35412
+ if (typeof IS_PROCESS_SERVER !== 'undefined') value = value.replace(/↵|\r\n|\n|\r/g, '<br>');
35413
+ fields[val.fieldId] = value;
35414
+ }
35415
+
35416
+ if (typeof value === 'object' && var_Arr.length > 1) {
35417
+ value = Array.isArray(value) || var_Arr[key + 1]?.value?.includes('.') ? JSON.stringify(value) : `(${JSON.stringify(value)})`;
35418
+ }
35419
+
35420
+ if (!val.type === 'exp' && sourceP !== 'exp' && typeof value === 'string' && value.startsWith('@')) {
35421
+ warning = `Error encoding ${value}`;
35422
+ var_error_found = true;
35423
+ return '0';
35424
+ }
35425
+ return value;
35426
+ });
35427
+
35428
+ ret = res.length === 1 ? res[0] : res.join('');
35429
+ if (var_Arr.some((v) => v.type === 'exp') && sourceP !== 'exp' && !secondPassP) {
35430
+ const exp = await func.expression.get(SESSION_ID, ret, dsSessionP, sourceP, rowIdP, sourceActionP, true, calling_fieldIdP, fields, debug_infoP);
35431
+ ret = exp.res?.[0] ?? exp.result;
35432
+ Object.assign(fields, exp.fields);
35433
+ } else if (!secondPassP && !['arguments', 'api_rendered_output', 'DbQuery'].includes(sourceP)) {
35434
+ ret = await func.expression.secure_eval(SESSION_ID, sourceP, ret, jobNo, dsSessionP, js_script_callback);
35435
+ } else if (sourceP === 'DbQuery') {
35436
+ ret = JSON.stringify(evalJson(ret));
35437
+ }
35438
+
35439
+ if (typeof ret === 'string' && ret.startsWith('@')) {
35440
+ error = 'Error encoding @ var';
35441
+ var_error_found = true;
35442
+ }
35443
+ } catch (err) {
35444
+ error = err.message;
35445
+ }
35446
+
35447
+ return endResults();
35448
+ };
35449
+
35279
35450
  func.expression.parse_org = function (strP) {
35280
35451
  var extract_str = function (strP, posP) {
35281
35452
  if (!posP) posP = 0;
@@ -35457,7 +35628,7 @@ func.expression.parse = function (input) {
35457
35628
  return segments;
35458
35629
  };
35459
35630
 
35460
- func.expression.get_property = async function (valP) {
35631
+ func.expression.get_property_org = async function (valP) {
35461
35632
  async function secure_eval(val) {
35462
35633
  if (typeof IS_PROCESS_SERVER === 'undefined') {
35463
35634
  try {
@@ -35495,21 +35666,73 @@ func.expression.get_property = async function (valP) {
35495
35666
  property2: property2,
35496
35667
  };
35497
35668
  };
35498
- func.expression.validate_constant = function (valP) {
35669
+
35670
+ func.expression.get_property = async function (valP) {
35671
+ if (typeof valP !== 'string') return { property1: undefined, property2: undefined };
35672
+
35673
+ const secureEval = async (expr) => {
35674
+ if (typeof IS_PROCESS_SERVER === 'undefined') {
35675
+ try {
35676
+ return eval(expr);
35677
+ } catch (err) {
35678
+ console.error(err);
35679
+ return undefined;
35680
+ }
35681
+ }
35682
+ try {
35683
+ const vm = new VM.VM({
35684
+ sandbox: {
35685
+ func,
35686
+ SESSION_ID,
35687
+ SESSION_OBJ: { [SESSION_ID]: SESSION_OBJ[SESSION_ID] },
35688
+ },
35689
+ timeout: 1000,
35690
+ allowAsync: false,
35691
+ });
35692
+ return await vm.run(expr);
35693
+ } catch {
35694
+ return undefined; // Simplified error handling
35695
+ }
35696
+ };
35697
+
35698
+ let property1, property2;
35699
+ const bracketStart = valP.indexOf('[');
35700
+ const bracketEnd = valP.indexOf(']');
35701
+
35702
+ if (bracketStart > -1 && bracketEnd > bracketStart) {
35703
+ const expr = valP.slice(bracketStart + 1, bracketEnd);
35704
+ property1 = await secureEval(expr);
35705
+ }
35706
+
35707
+ const dotIndex = valP.indexOf('.');
35708
+ if (dotIndex > -1) {
35709
+ property2 = valP.slice(dotIndex + 1);
35710
+ }
35711
+
35712
+ return { property1, property2 };
35713
+ };
35714
+
35715
+ func.expression.validate_constant_org = function (valP) {
35499
35716
  var patt = /["']/;
35500
35717
  if (typeof valP === 'string' && patt.test(valP.substr(0, 1)) && patt.test(valP.substr(0, valP.length - 1))) return true;
35501
35718
  else return false;
35502
35719
  };
35503
- func.expression.validate_variables = function (valP) {
35720
+ func.expression.validate_variables_org = function (valP) {
35504
35721
  if (typeof valP === 'string' && valP.indexOf('@') > -1) return true;
35505
35722
  else return false;
35506
35723
  };
35507
- func.expression.remove_quotes = function (valP) {
35724
+ func.expression.remove_quotes_org = function (valP) {
35508
35725
  if (func.expression.validate_constant(valP)) return valP.substr(1, valP.length - 2);
35509
35726
  else return valP;
35510
35727
  };
35511
35728
 
35512
- func.expression.secure_eval = async function (SESSION_ID, sourceP, val, job_id, dsSessionP, js_script_callback, evt) {
35729
+ func.expression.validate_constant = (valP) => typeof valP === 'string' && /^["'].*["']$/.test(valP);
35730
+
35731
+ func.expression.validate_variables = (valP) => typeof valP === 'string' && valP.includes('@');
35732
+
35733
+ func.expression.remove_quotes = (valP) => (func.expression.validate_constant(valP) && typeof valP === 'string' ? valP.slice(1, -1) : valP);
35734
+
35735
+ func.expression.secure_eval_org = async function (SESSION_ID, sourceP, val, job_id, dsSessionP, js_script_callback, evt) {
35513
35736
  const api_utils = await func.common.get_module(SESSION_ID, 'xuda-api-library.mjs', {
35514
35737
  func,
35515
35738
  glb,
@@ -35610,6 +35833,90 @@ func.expression.secure_eval = async function (SESSION_ID, sourceP, val, job_id,
35610
35833
  }
35611
35834
  }
35612
35835
  };
35836
+
35837
+ func.expression.secure_eval = async function (SESSION_ID, sourceP, val, job_id, dsSessionP, js_script_callback, evt) {
35838
+ if (typeof val !== 'string') return val;
35839
+
35840
+ const xu = await func.common.get_module(SESSION_ID, 'xuda-api-library.mjs', {
35841
+ func,
35842
+ glb,
35843
+ SESSION_OBJ,
35844
+ SESSION_ID,
35845
+ APP_OBJ,
35846
+ dsSession: dsSessionP,
35847
+ job_id,
35848
+ });
35849
+
35850
+ const isServer = typeof IS_PROCESS_SERVER !== 'undefined' || typeof IS_DOCKER !== 'undefined';
35851
+
35852
+ // Client-side execution
35853
+ if (!isServer) {
35854
+ try {
35855
+ return eval(val);
35856
+ } catch {
35857
+ try {
35858
+ return JSON5.parse(val);
35859
+ } catch {
35860
+ return val;
35861
+ }
35862
+ }
35863
+ }
35864
+
35865
+ // Server-side execution
35866
+ const sandbox = {
35867
+ func,
35868
+ xu,
35869
+ SESSION_ID,
35870
+ SESSION_OBJ: { [SESSION_ID]: SESSION_OBJ[SESSION_ID] },
35871
+ callback: js_script_callback,
35872
+ job_id,
35873
+ ...(sourceP === 'javascript' ? { axios, got, FormData } : {}),
35874
+ };
35875
+
35876
+ const handleError = (err) => {
35877
+ console.error('Execution error:', err);
35878
+ func.events.delete_job(SESSION_ID, job_id);
35879
+ if (isServer && !SESSION_OBJ[SESSION_ID].crawler) {
35880
+ if (sourceP === 'javascript') {
35881
+ __.rpi.write_log(SESSION_OBJ[SESSION_ID].app_id, 'error', 'worker', 'vm error', err, null, val, 'func.expression.get.secure_eval');
35882
+ } else {
35883
+ __.db.add_error_log(SESSION_OBJ[SESSION_ID].app_id, 'api', err);
35884
+ }
35885
+ }
35886
+ return val; // Fallback to original value
35887
+ };
35888
+
35889
+ if (sourceP === 'javascript') {
35890
+ process.on('uncaughtException', handleError);
35891
+ try {
35892
+ const dir = path.join(_conf.studio_drive_path, SESSION_OBJ[SESSION_ID].app_id, 'node_modules');
35893
+ 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 });
35894
+ const vm = new VM.NodeVM({
35895
+ require: { external: true },
35896
+ sandbox,
35897
+ timeout: 60000,
35898
+ });
35899
+ return await vm.run(script, { filename: dir, dirname: dir });
35900
+ } catch (err) {
35901
+ return handleError(err);
35902
+ }
35903
+ }
35904
+
35905
+ try {
35906
+ const vm = new VM.VM({
35907
+ sandbox,
35908
+ timeout: 1000,
35909
+ allowAsync: false,
35910
+ });
35911
+ return await vm.run(val);
35912
+ } catch {
35913
+ try {
35914
+ return JSON5.parse(val);
35915
+ } catch {
35916
+ return val;
35917
+ }
35918
+ }
35919
+ };
35613
35920
  func.events = {};
35614
35921
  func.events.validate = async function (SESSION_ID, triggerP, dsSessionP, eventIdP, sourceP, argumentsP, return_validation_onlyP) {
35615
35922
  var _session = SESSION_OBJ[SESSION_ID];