@xuda.io/xuda-studio-checker.min 1.0.19 → 1.0.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/index.mjs +2 -2
  2. package/package.json +1 -1
package/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- var app_obj,progs_obj,_,progs_str,hide_not_in_use_check,is_server,deployments,UglifyJS,JSON5,_conf,warn_plugin_check,z;const PROTECTED_VARS=["_NULL","_THIS","_FOR_KEY","_FOR_VAL","_ROWNO","_ROWID","_ROWDOC","_KEY","_VAL"];const ALL_MENU_TYPE=["globals","component","ai_agent","batch","get_data","set_data","alert","javascript","api","table","folder"];const program_ref_triggers_arr=["call_page","call_modal","call_popover","get_data","set_data","batch","call_native_javascript","call_evaluate_javascript","call_alert","alter_ui_element","create_ui_element","update","raise_event"];export const init=function(app_obj_in,progs_obj_in={},_in,_hide_not_in_use_check,is_server_in,deployments_in=[],UglifyJS_in,JSON5_in,_conf_in,_warn_plugin_check,_z){app_obj=app_obj_in;progs_obj=progs_obj_in;progs_str=JSON.stringify(progs_obj);hide_not_in_use_check=_hide_not_in_use_check;_=_in;is_server=is_server_in;deployments=deployments_in;UglifyJS=UglifyJS_in;JSON5=JSON5_in;_conf=_conf_in;warn_plugin_check=_warn_plugin_check;z=_z};export const check=function(doc){var ret=[];var dependency_progs=[];const addValidationError=(code,data,type="E",category="document",ref=null,id=null,not_in_use=false)=>{const error={code:code,data:data,type:type,category:category};if(ref)error.ref=ref;if(id)error.id=id;if(not_in_use)error.not_in_use=not_in_use;ret.push(error)};if(_.isEmpty(doc)){addValidationError("CHK_MSG_OBJ_GEN_110","doc in empty");return{check_errors:ret,check_warnings:[],doc:doc,dependency_progs:[]}}let critical_error=false;ret=check_structure(doc,critical_error);if(!critical_error){doc.studio_meta.not_in_use=false;if(doc.properties.menuType!=="folder"){if(doc.properties.menuType!=="table"){if(is_server){for(let val of deployments){if(val.deploy_data?.prog_id===doc._id){if(!doc.studio_meta.used_by_deployment_ids){doc.studio_meta.used_by_deployment_ids=[]}doc.studio_meta.used_by_deployment_ids.push(val._id)}}}if(!doc.studio_meta.used_by_deployment_id){const check_programs_are_active=function(arr){if(!arr.length)return false;var count=0;for(let val of arr){if(progs_obj?.[val.prog_id]?.studio_meta?.not_in_use){count++;break}}return count!==arr.length};if(!hide_not_in_use_check){const ret_prog_in_use=find_trigger_property_value_in_progs(doc,program_ref_triggers_arr,"prog",doc._id);if(!ret_prog_in_use||!check_programs_are_active(ret_prog_in_use)){const ret_panel_prog_in_use=find_panel_prog_in_progs(doc,doc._id);if(!ret_panel_prog_in_use||!check_programs_are_active(ret_panel_prog_in_use)){const ret_fieldValue_in_use=find_prog_in_fieldset_fieldValue_progs(doc,doc._id);if(!ret_fieldValue_in_use||!check_programs_are_active(ret_fieldValue_in_use)){doc.studio_meta.not_in_use=true}}}}}ret=[...ret,...check_prog_events(doc)];dependency_progs=find_trigger_property_value_in_progs(doc,program_ref_triggers_arr,"prog",null,true)||[];dependency_progs=[...dependency_progs,...find_panel_prog_in_progs(doc,null,true)||[]]}else{if(!hide_not_in_use_check){if(!find_table_in_progs(doc,doc._id)){doc.studio_meta.not_in_use=true}}}}switch(doc.properties.menuType){case"globals":ret=[...ret,...check_globals(doc)];break;case"table":ret=[...ret,...check_table(doc)];break;case"component":ret=[...ret,...check_component(doc)];break;case"javascript":ret=[...ret,...check_javascript(doc)];break;case"get_data":ret=[...ret,...check_get_data(doc)];break;case"set_data":ret=[...ret,...check_set_data(doc)];break;case"batch":ret=[...ret,...check_batch(doc)];break;case"api":ret=[...ret,...check_api(doc)];break;case"alert":ret=[...ret,...check_alert(doc)];break;case"route":ret=[...ret,...check_route(doc)];break;case"ai_agent":ret=[...ret,...check_ai_agent(doc)];break;case"folder":break;default:addValidationError("CHK_MSG_GEN_050",`invalid ${doc.properties.menuType} properties.menuType`,"E","prog",doc._id,doc._id);break}}var final_ret={check_errors:[],check_warnings:[],doc:doc,dependency_progs:dependency_progs};for(let[key,val]of Object.entries(ret)){if(val.type==="E"){final_ret.check_errors.push(val)}if(val.type==="W"){final_ret.check_warnings.push(val)}}return final_ret};export const check_structure=function(doc,critical_error){var ret=[];const addValidationError=(code,data)=>{ret.push({code:code,data:data,type:"E",category:"document",structure_error:true})};if(!app_obj||!_.isObject(app_obj)||_.isEmpty(app_obj)){addValidationError("CHK_MSG_OBJ_GEN_002","invalid app_obj");critical_error=true;return ret}if(!doc||!_.isObject(doc)||_.isEmpty(doc)){addValidationError("CHK_MSG_OBJ_GEN_004","doc is not a object");critical_error=true;return ret}try{JSON5.parse(JSON.stringify(doc))}catch(err){addValidationError("CHK_MSG_OBJ_GEN_005","error parsing JSON doc");critical_error=true;return ret}if(!doc?.properties){critical_error=true;const msg=`doc.property object is undefined`;addValidationError("CHK_MSG_OBJ_GEN_000",msg);return ret}if(!doc?.studio_meta){critical_error=true;const msg=`doc.studio_meta object is undefined`;addValidationError("CHK_MSG_OBJ_GEN_000",msg);return ret}if(!doc?.properties?.menuType){critical_error=true;const msg=`doc.property.menuType is mandatory`;addValidationError("CHK_MSG_OBJ_GEN_000",msg);return ret}if(!doc?.properties?.menuName){critical_error=true;const msg=`doc.property.menuName is mandatory`;addValidationError("CHK_MSG_OBJ_GEN_000",msg);return ret}if(z){const schema=get_zod_schema(doc.properties.menuType);const result=schema.safeParse(doc);if(!result.success){result.error.errors.forEach(error=>{const msg=`${error.message}: ${error.path}(${error.expected})`;addValidationError("CHK_MSG_OBJ_GEN_000",msg)});critical_error=true;return ret}}if(!doc._id){addValidationError("CHK_MSG_OBJ_GEN_050","missing _id value")}if(doc?.studio_meta?.source==="studio ai"&&doc?.properties?.menuType&&doc._id&&doc._id.substr(0,7)!==new_node_id(doc.properties.menuType,doc.app_id).substr(0,7)){addValidationError("CHK_MSG_OBJ_GEN_051","invalid _id value (e.g: 5b1_tbl_a953848a71c5)")}if(!doc._rev){if(progs_obj?.[doc._id]){addValidationError("CHK_MSG_OBJ_GEN_052","duplicate doc _id")}}if(!doc.properties){addValidationError("CHK_MSG_OBJ_GEN_100","missing properties object")}else{if(!_.isObject(doc.properties)){addValidationError("CHK_MSG_OBJ_GEN_102","invalid properties object")}else{if(!doc.properties.menuType){addValidationError("CHK_MSG_OBJ_GEN_104","missing properties.menuType")}else if(!ALL_MENU_TYPE.includes(doc.properties.menuType)){addValidationError("CHK_MSG_OBJ_GEN_105",`invalid properties.menuType (valid values: ${ALL_MENU_TYPE.join(",")})`)}if(!doc.properties.menuName){addValidationError("CHK_MSG_OBJ_GEN_106","missing properties.menuName")}}}if(!doc.studio_meta){addValidationError("CHK_MSG_OBJ_GEN_112","missing studio_meta property")}else{if(!_.isObject(doc.studio_meta)){addValidationError("CHK_MSG_OBJ_GEN_112","invalid studio_meta object")}else{if(!doc.studio_meta.parentId){addValidationError("CHK_MSG_OBJ_GEN_114","missing studio_meta.parentId value")}else{let menuType=doc?.properties?.menuType==="globals"?"globals":doc?.properties?.menuType==="table"?"database":doc?.properties?.menuType==="route"?"routes":doc?.properties?.menuType==="ai_agent"?"ai_agents":"programs";if(doc.studio_meta.parentId!==menuType&&!progs_obj[doc.studio_meta.parentId]){addValidationError("CHK_MSG_OBJ_GEN_116","invalid studio_meta.parentId value")}}}}const check_progFields=function(){if(!doc.progFields)return;var ids=[];if(!_.isArray(doc.progFields)){addValidationError("CHK_MSG_OBJ_GEN_402","invalid progFields Array property");return}const validTypes=["virtual","table","expression","datasource"];const validFieldTypes=["string","number","boolean","array","object"];for(let val of doc.progFields){if(!_.isObject(val)){addValidationError("CHK_MSG_OBJ_GEN_404",`Invalid progFields object `);continue}if(!val.id){addValidationError("CHK_MSG_OBJ_GEN_406","Missing progFields ID property")}const fieldId=val.id?`(${val.id})`:"";if(val.id){if(ids.includes(val.id)){addValidationError("CHK_MSG_OBJ_GEN_408",`Duplicate progFields ID (${val.id})`);continue}ids.push(val.id)}if(!_.isObject(val.data)){addValidationError("CHK_MSG_OBJ_GEN_410",`Invalid progFields data object ${fieldId}`)}else{if(!val.data.field_id){addValidationError("CHK_MSG_OBJ_GEN_412",`Missing progFields field_id property ${fieldId}`)}if(!val.data.type){addValidationError("CHK_MSG_OBJ_GEN_414",`Missing progFields type property ${fieldId}`)}else if(!validTypes.includes(val.data.type)){addValidationError("CHK_MSG_OBJ_GEN_415",`Invalid progFields type "${val.data.type}" ${fieldId}. Must be one of: ${validTypes.join(", ")}`)}}if(!_.isObject(val.props)){addValidationError("CHK_MSG_OBJ_GEN_416",`Invalid progFields props object ${fieldId}`)}else{if(!val.props.fieldType){addValidationError("CHK_MSG_OBJ_GEN_418",`Missing progFields fieldType property ${fieldId}`)}else if(!validFieldTypes.includes(val.props.fieldType)){addValidationError("CHK_MSG_OBJ_GEN_419",`Invalid progFields fieldType "${val.props.fieldType}" ${fieldId}. Must be one of: ${validFieldTypes.join(", ")}`)}if(!_.isObject(val.props.propExpressions)){addValidationError("CHK_MSG_OBJ_GEN_4120",`Invalid progFields propExpressions object ${fieldId}`)}else{const allowedProps=["fieldValue","fieldType"];const actualProps=Object.keys(val.props.propExpressions);const invalidProps=actualProps.filter(prop=>!allowedProps.includes(prop));if(invalidProps.length>0){addValidationError("CHK_MSG_OBJ_GEN_4121",`Invalid propExpressions properties: ${invalidProps.join(", ")} ${fieldId}. Only allowed: ${allowedProps.join(", ")}`)}}}check_workflow(val.workflow)}};const check_progEvents=function(){if(!doc.progEvents)return;var ids=[];if(!_.isArray(doc.progEvents)){addValidationError("CHK_MSG_OBJ_GEN_502","invalid progEvents Array property");return}for(let val of doc.progEvents){if(!_.isObject(val)){addValidationError("CHK_MSG_OBJ_GEN_504","invalid progEvents object property");continue}if(!val.id){addValidationError("CHK_MSG_OBJ_GEN_506","missing progEvents.id property");continue}if(ids.includes(val.id)){addValidationError("CHK_MSG_OBJ_GEN_508",`${val.id} id must be unique in progEvents property`);continue}ids.push(val.id);if(!_.isObject(val.data)){addValidationError("CHK_MSG_OBJ_GEN_510","invalid progEvents.data object property");continue}if(typeof val.data.condition==="undefined"){addValidationError("CHK_MSG_OBJ_GEN_512","undefined progEvents.data.condition string property")}if(typeof val.data.event_name==="undefined"){addValidationError("CHK_MSG_OBJ_GEN_514","undefined progEvents.data.event_name string property")}if(typeof val.data.properties==="undefined"){addValidationError("CHK_MSG_OBJ_GEN_516","undefined progEvents.data.properties string property")}if(typeof val.data.type==="undefined"){addValidationError("CHK_MSG_OBJ_GEN_518","undefined progEvents.data.type string property")}if(!_.isArray(val.data.parameters)){addValidationError("CHK_MSG_OBJ_GEN_522","invalid progEvents.data.parameters Array property")}if(!_.isObject(val.props)){addValidationError("CHK_MSG_OBJ_GEN_522","invalid progEvents.props Object property")}check_workflow(val.workflow)}};const check_workflow=function(workflow){if(!workflow)return;var ids=[];if(!_.isArray(workflow)){addValidationError("CHK_MSG_OBJ_GEN_850","invalid workflow Array property");return}for(let val of workflow){if(!_.isObject(val)){addValidationError("CHK_MSG_OBJ_GEN_852","invalid workflow item object property");continue}if(!val.id){addValidationError("CHK_MSG_OBJ_GEN_854","missing workflow.id property");continue}if(ids.includes(val.id)){addValidationError("CHK_MSG_OBJ_GEN_856",`${val.id} id must be unique in workflow property`);continue}ids.push(val.id);if(!_.isObject(val.data)){addValidationError("CHK_MSG_OBJ_GEN_858","invalid workflow.data Object property")}if(!_.isObject(val.props)){addValidationError("CHK_MSG_OBJ_GEN_860","invalid workflow.props item object property")}}};const check_progDataSource=function(){if(!doc.progDataSource)return;if(!_.isObject(doc.progDataSource)){addValidationError("CHK_MSG_OBJ_GEN_602","invalid progDataSource Object property");return}if(typeof doc.progDataSource.dataSourceType==="undefined"){addValidationError("CHK_MSG_OBJ_GEN_604","undefined progDataSource.dataSourceType string property")}};const check_progUi=function(){if(!doc.progUi)return;if(!_.isArray(doc.progUi)){addValidationError("CHK_MSG_OBJ_GEN_702","invalid progUi Array property");return}var ids=[];const run_tree=function(node){for(let item of node){if(!_.isObject(item)){addValidationError("CHK_MSG_OBJ_GEN_704","invalid progUi item Object property");continue}if(!item.id){addValidationError("CHK_MSG_OBJ_GEN_712","missing progUi id item property")}if(item?.id){if(item?.type==="comment"){addValidationError("CHK_MSG_OBJ_GEN_705",`Comment type is not supported in progUi (${item.id})`);continue}if(item?.type==="text"){addValidationError("CHK_MSG_OBJ_GEN_706",`Text type is not supported in progUi (${item.id}). Convert to "element" type and add a "text" property instead`);continue}if(item?.attributes&&!_.isObject(item.attributes)){addValidationError("CHK_MSG_OBJ_GEN_707",`Invalid progUi attributes object property (${item.id})`)}if(typeof item.type==="undefined"){addValidationError("CHK_MSG_OBJ_GEN_708",`Missing progUi type property (${item.id})`)}if(typeof item.tagName==="undefined"){addValidationError("CHK_MSG_OBJ_GEN_710",`Missing progUi tagName property (${item.id})`)}if(item.id!=="root"&&doc?.studio_meta?.source==="studio ai"&&!detectCryptoString(item.id.replace("node-","").replace("ui-","")).uuid){addValidationError("CHK_MSG_OBJ_GEN_713",`ProgUi item ID must be in UUID format (${item.id})`)}if(ids.includes(item.id)){addValidationError("CHK_MSG_OBJ_GEN_714",`Duplicate progUi item ID found (${item.id})`);continue}ids.push(item.id)}check_workflow(item.workflow);if(item.children){run_tree(item.children)}}};run_tree(doc.progUi)};if(doc.properties&&doc.properties.menuType){switch(doc.properties.menuType){case"table":if(!doc.tableFields){addValidationError("CHK_MSG_OBJ_GEN_200","missing tableFields property")}else{if(!_.isArray(doc.tableFields)){addValidationError("CHK_MSG_OBJ_GEN_202","invalid tableFields Array property")}else{var ids=[];for(let val of doc.tableFields){if(!_.isObject(val)){addValidationError("CHK_MSG_OBJ_GEN_204","invalid tableFields object property");continue}if(!val.id){addValidationError("CHK_MSG_OBJ_GEN_206","missing tableFields.id property");continue}if(ids.includes(val.id)){addValidationError("CHK_MSG_OBJ_GEN_208",`${val.id} id must be unique in tableFields property`);continue}ids.push(val.id);if(!_.isObject(val.data)){addValidationError("CHK_MSG_OBJ_GEN_210","invalid tableFields.data object property");continue}if(!val.data.field_id){addValidationError("CHK_MSG_OBJ_GEN_212","invalid tableFields.data.field_id property")}if(!_.isObject(val.props)){addValidationError("CHK_MSG_OBJ_GEN_214","invalid tableFields.props object property");continue}if(!val.props.fieldType){addValidationError("CHK_MSG_OBJ_GEN_216","invalid tableFields.props.fieldType property")}}}}if(!doc.tableIndexes){addValidationError("CHK_MSG_OBJ_GEN_302","missing tableIndexes property")}else if(!_.isArray(doc.tableIndexes)){addValidationError("CHK_MSG_OBJ_GEN_302","invalid tableIndexes Array property")}else{var index_ids=[];for(let val of doc.tableIndexes){if(!_.isObject(val)){addValidationError("CHK_MSG_OBJ_GEN_304","invalid tableIndexes object property");continue}if(!val.id){addValidationError("CHK_MSG_OBJ_GEN_306","missing tableIndexes.id property");continue}if(index_ids.includes(val.id)){addValidationError("CHK_MSG_OBJ_GEN_308",`${val.id} id must be unique in tableIndexes property`);continue}index_ids.push(val.id);if(!_.isObject(val.data)){addValidationError("CHK_MSG_OBJ_GEN_310","invalid tableIndexes.data object property");continue}if(!val.data.name){addValidationError("CHK_MSG_OBJ_GEN_312","invalid tableIndexes.data.name property")}if(!_.isArray(val.data.keys)){addValidationError("CHK_MSG_OBJ_GEN_312","invalid tableIndexes.data.keys Array property")}}}break;case"globals":check_progFields();check_progEvents();break;case"get_data":case"set_data":case"batch":case"api":check_progFields();check_progEvents();check_progDataSource();break;case"component":check_progFields();check_progEvents();check_progDataSource();check_progUi();if(doc.properties&&typeof doc.properties.uiFramework==="undefined"){addValidationError("CHK_MSG_OBJ_GEN_120","undefined properties.uiFramework string property")}if(doc.properties&&typeof doc.properties.renderType==="undefined"){addValidationError("CHK_MSG_OBJ_GEN_122","undefined properties.renderType string property")}break;case"alert":break;case"javascript":break;case"folder":break;default:break}}return ret};const check_table=function(doc){var ret=[];if(!doc.properties.databaseSocket){ret.push({code:"CHK_MSG_TBL_GEN_010",data:"database socket not defined",type:doc.studio_meta.not_in_use?"W":"E",category:`table`,ref:doc._id,id:doc._id})}else{if(!app_obj?.app_plugins_purchased?.[doc.properties.databaseSocket]){ret.push({code:"CHK_MSG_TBL_GEN_0020",data:`invalid ${doc.properties.databaseSocket} database socket`,type:doc.studio_meta.not_in_use||warn_plugin_check?"W":"E",category:`table`,ref:doc._id,id:doc._id})}else{if(!app_obj.app_plugins_purchased[doc.properties.databaseSocket].installed){ret.push({code:"CHK_MSG_TBL_GEN_030",data:`${doc.properties.databaseSocket} database socket not installed`,type:doc.studio_meta.not_in_use?"W":"E",category:`table`,ref:doc._id,id:doc._id})}}}if(doc.tableIndexes?.length&&!doc?.tableFields?.length){ret.push({code:"CHK_MSG_TBL_FLD_090",data:`table has no fields`,type:doc.studio_meta.not_in_use?"W":"E",category:`table`,ref:doc._id,id:doc._id})}var name_counts_obj={};for(let field of doc.tableFields){if(!field?.data?.field_id){ret.push({code:"CHK_MSG_TBL_FLD_100",data:`missing field_id`,type:doc.studio_meta.not_in_use?"W":"E",category:`table`,ref:field.id,id:`${doc._id}-${field.id}`})}else{if(!/^[A-Za-z]+[\w\-\:\.]*$/.test(field.data.field_id)){ret.push({code:"CHK_MSG_TBL_FLD_020",data:`invalid field_id`,type:doc.studio_meta.not_in_use?"W":"E",category:`table`,ref:field.id,id:`${doc._id}-${field.id}`})}if(!name_counts_obj[field.data.field_id]){name_counts_obj[field.data.field_id]=1}else{name_counts_obj[field.data.field_id]++}if(!hide_not_in_use_check){if(!find_field_in_progs(doc,field.data.field_id)){ret.push({code:"CHK_MSG_TBL_FLD_022",data:`table field "${field.data.field_id}" not in use`,type:"W",category:`table`,ref:doc._id,not_in_use:true,id:`${doc._id}-${field.id}`})}}}}for(let[key,val]of Object.entries(name_counts_obj)){if(val>1){ret.push({code:"CHK_MSG_TBL_FLD_200",data:`duplicate field id for ${key}`,type:doc.studio_meta.not_in_use?"W":"E",id:`${doc._id}-${key}`})}}if(!doc.tableIndexes?.length){if(doc.properties.databaseSocket!=="@xuda.io/xuda-dbs-plugin-xuda"){ret.push({code:"CHK_MSG_TBL_IDX_040",data:`at least one index has to be defined`,type:doc.studio_meta.not_in_use?"W":"E",id:`${doc._id}`})}}else{let found_unique;for(let index of doc.tableIndexes){if(index?.data?.unique){found_unique=true}if(!index?.data?.name){ret.push({code:"CHK_MSG_TBL_IDX_060",data:`tableIndexes.data.name cannot be empty in "${index.id}" index`,type:doc.studio_meta.not_in_use?"W":"E",id:`${doc._id}`})}if(!index?.data?.keys?.length){ret.push({code:"CHK_MSG_TBL_IDX_070",data:`tableIndexes.data.keys cannot be empty in "${index.id}" index`,type:doc.studio_meta.not_in_use?"W":"E",id:`${doc._id}-${index.id}`})}else{for(let key of index.data.keys){if(!doc.tableFields||!_.isArray(doc.tableFields)||!find_item_by_key(doc.tableFields,"field_id",key)){ret.push({code:"CHK_MSG_TBL_IDX_080",data:`invalid key ${key} in tableIndexes.data.keys for "${index.id}" index`,type:doc.studio_meta.not_in_use?"W":"E",id:`${doc._id}-${index.id}-${key}`})}}}}}if(!doc?.tableFields?.length){ret.push({code:"CHK_MSG_TBL_FLD_012",data:`table has no fields`,type:"W",id:`${doc._id}`})}for(let field of doc.tableFields){if(!["string","number","boolean","object","array","date"].includes(field?.props?.fieldType)){ret.push({code:"CHK_MSG_TBL_FLD_022",data:`invalid fieldType for field ${field?.data?.field_id}`,type:"E",id:`${doc._id}-${field.id}`})}}return ret};const check_globals=function(doc){var ret=[];ret=[...ret,...check_prog_fieldset(doc)];return ret};const check_component=function(doc){var ret=[];if(!doc.properties.uiFramework){ret.push({code:"CHK_MSG_PRG_COM_010",data:"component Ui Framework not defined",type:doc.studio_meta.not_in_use?"W":"E",category:`component`,ref:doc._id,id:`${doc._id}`})}else{if(!app_obj?.app_plugins_purchased?.[doc.properties.uiFramework]){ret.push({code:"CHK_MSG_PRG_COM_020",data:`invalid ${doc.properties.uiFramework} Ui Framework`,type:doc.studio_meta.not_in_use?"W":"E",category:`component`,ref:doc._id,id:`${doc._id}`})}else{if(!app_obj.app_plugins_purchased[doc.properties.uiFramework].installed){ret.push({code:"CHK_MSG_PRG_COM_030",data:`${doc.properties.uiFramework} Ui Framework not installed`,type:doc.studio_meta.not_in_use?"W":"E",category:`component`,ref:doc._id,id:`${doc._id}`})}}}ret=[...ret,...check_prog_fieldset(doc)];ret=[...ret,...check_prog_parameters(doc)];ret=[...ret,...check_prog_datasource(doc)];if(doc.progUi){var xu_tree_id_counts_obj={};const run_tree=function(node){for(let item of node){if(item.xu_tree_id){if(!xu_tree_id_counts_obj[item.xu_tree_id]){xu_tree_id_counts_obj[item.xu_tree_id]=1}else{xu_tree_id_counts_obj[item.xu_tree_id]++}}if(item.attributes){var name_counts_obj={};for(let[key,val]of Object.entries(item.attributes)){if(!key){ret.push({code:"CHK_MSG_PRG_GUI_010",data:`missing attribute in tree_id ${item.id}`,type:doc.studio_meta.not_in_use?"W":"E",category:`component_ui`,ref:item.id,id:`${doc._id}-${item.id}-${key}`})}else{if(key.substr(0,6)==="xu-exp"){ret=[...ret,...check_prog_expression(doc,val,item.id,"ui_attribute")]}else{if(!/^[A-Za-z]+[\w\-\:\.]*$/.test(key)){ret.push({code:"CHK_MSG_PRG_GUI_020",data:`invalid attribute "${key}" in tag "${item.tagName}" "${item.id}"`,type:doc.studio_meta.not_in_use?"W":"E",category:`component_ui`,ref:item.id,id:`${doc._id}-${item.id}-${key}`})}}if(key.substr(0,6)==="xu-on:"){if(!_.isEmpty(val)){for(let trigger_item of val){ret=[...ret,...check_prog_triggers(doc,trigger_item.workflow,"ui_trigger",item.id,item.attributes.tree_id)]}}}if(!name_counts_obj[key]){name_counts_obj[key]=1}else{name_counts_obj[key]++}}}for(let[key,val]of Object.entries(name_counts_obj)){if(val>1){ret.push({code:"CHK_MSG_PRG_GUI_200",data:`duplicate attribute id for ${key} in tree_id ${item.attribute.tree_id}`,type:doc.studio_meta.not_in_use?"W":"E",category:`component_ui`,ref:doc._id,id:`${doc._id}-${item.id}-${key}`})}}}if(item.children){run_tree(item.children)}}};run_tree(doc.progUi);for(let[key,val]of Object.entries(xu_tree_id_counts_obj)){if(val>1){ret.push({code:"CHK_MSG_PRG_GUI_250",data:`duplicate tree_id "${key}"`,type:"W",category:`component_ui`,ref:doc._id,id:`${doc._id}-${key}`})}}}return ret};const check_get_data=function(doc){var ret=[];ret=[...ret,...check_prog_fieldset(doc)];ret=[...ret,...check_prog_parameters(doc)];ret=[...ret,...check_prog_datasource(doc)];return ret};const check_batch=function(doc){var ret=[];ret=[...ret,...check_prog_fieldset(doc)];ret=[...ret,...check_prog_parameters(doc)];ret=[...ret,...check_prog_datasource(doc)];return ret};const check_api=function(doc){var ret=[];ret=[...ret,...check_prog_fieldset(doc)];ret=[...ret,...check_prog_parameters(doc)];ret=[...ret,...check_prog_datasource(doc)];return ret};const check_set_data=function(doc){var ret=[];ret=[...ret,...check_prog_fieldset(doc)];ret=[...ret,...check_prog_parameters(doc)];ret=[...ret,...check_prog_datasource(doc)];return ret};const check_alert=function(doc){var ret=[];if(_.isEmpty(doc.alertData)){ret.push({code:"CHK_MSG_PRG_ART_010",data:`no alert properties defined`,type:doc.studio_meta.not_in_use?"W":"E",category:`alert`,ref:doc._id,id:`${doc._id}`})}else{if(!doc.alertData.alertType){ret.push({code:"CHK_MSG_PRG_ART_020",data:`missing alert type property`,type:doc.studio_meta.not_in_use?"W":"E",category:`alert`,ref:doc._id,id:`${doc._id}`})}if(!doc.alertData.alertDisplay){ret.push({code:"CHK_MSG_PRG_ART_030",data:`missing alert display property`,type:doc.studio_meta.not_in_use?"W":"E",category:`alert`,ref:doc._id,id:`${doc._id}`})}if(!doc.alertData.alertTitle&&!doc.alertData.alertTitleFx&&!doc.alertData.alertBody&&!doc.alertData.alertBodyFx){ret.push({code:"CHK_MSG_PRG_ART_032",data:`missing alert title and body value`,type:"W",category:`alert`,ref:doc._id,id:`${doc._id}`})}}return ret};const check_route=function(doc){var ret=[];if(_.isEmpty(doc?.routeMenu?.menu)){ret.push({code:"CHK_MSG_RTE_MNU_010",data:`no route properties defined`,type:doc.studio_meta.not_in_use?"W":"E",category:`alert`,ref:doc._id,id:`${doc._id}`})}else{function checkMenuItems(menu){let flatMenu={};function recurse(items){for(let item of items){if(!item.prog_id){ret.push({code:"CHK_MSG_RTE_MNU_020",data:`no program to call has been defined`,type:doc.studio_meta.not_in_use?"W":"E",category:`alert`,ref:item.id,id:`${doc._id}`});continue}if(!progs_obj?.[item.prog_id]){ret.push({code:"CHK_MSG_RTE_MNU_030",data:`program ${item.prog_id} not exist`,type:doc.studio_meta.not_in_use?"W":"E",category:`alert`,ref:item.id,id:`${doc._id}`});continue}if(item.children&&item.children.length>0){recurse(item.children)}}}recurse(menu);return flatMenu}checkMenuItems(doc.routeMenu.menu)}return ret};const check_ai_agent=function(doc){var ret=[];return ret};const check_prog_fieldset=function(doc){var ret=[];if(!doc.progFields||_.isEmpty(doc.progFields)){if(doc.progDataSource.dataSourceTableId){ret.push({code:"CHK_MSG_PRG_FLD_012",data:`datasource table defined but fieldset is empty`,type:"W",category:"fieldset",id:`${doc._id}`})}}else{var name_counts_obj={};for(let field of doc.progFields){if(!field?.data?.field_id){ret.push({code:"CHK_MSG_PRG_FLD_010",data:`missing field_id`,type:doc.studio_meta.not_in_use?"W":"E",category:"fieldset",ref:field.id,id:`${doc._id}-${field.id}`})}else{if(!/^[A-Za-z]+[\w\-\:\.]*$/.test(field.data.field_id)&&!PROTECTED_VARS.includes(field.data.field_id)){ret.push({code:"CHK_MSG_PRG_FLD_020",data:`invalid ${field.data.field_id} field_id`,type:doc.studio_meta.not_in_use?"W":"E",category:"fieldset",ref:field.id,id:`${doc._id}-${field.id}`})}if(!name_counts_obj[field.data.field_id]){name_counts_obj[field.data.field_id]=1}else{name_counts_obj[field.data.field_id]++}if(!hide_not_in_use_check){if(!find_field_in_progs(doc,field.data.field_id)){var found_parameter_out_match;if(!_.isEmpty(doc.properties.progParams)){for(let parameter_item of doc.properties.progParams){if(parameter_item.data.dir==="out"&&parameter_item.data.parameter===field.data.field_id){found_parameter_out_match=true;break}}}if(!found_parameter_out_match){ret.push({code:"CHK_MSG_PRG_FLD_022",data:`field "${field.data.field_id}" not in use`,type:"W",category:"fieldset",ref:field.id,not_in_use:true,id:`${doc._id}-${field.id}`})}}}}if(!field?.data?.type){ret.push({code:"CHK_MSG_PRG_FLD_030",data:`missing field type`,type:doc.studio_meta.not_in_use?"W":"E",category:"fieldset",ref:field.id,id:`${doc._id}-${field.id}`});return ret}else{switch(field.data.type){case"virtual":break;case"exp":if(!field?.props?.fieldValue||!field?.props?.propExpressions?.fieldValue){ret.push({code:"CHK_MSG_PRG_FLD_070",data:`invalid value or value expression for ${field.data.field_id} field type Exp`,type:doc.studio_meta.not_in_use?"W":"E",category:"fieldset",ref:field.id,id:`${doc._id}-${field.id}`})}break;case"table":if(doc.properties.menuType==="globals"){ret.push({code:"CHK_MSG_PRG_FLD_040",data:`invalid field type for ${field.data.field_id} in globals`,type:doc.studio_meta.not_in_use?"W":"E",category:"fieldset",ref:field.id,id:`${doc._id}-${field.id}`})}else{if(!doc.progDataSource||_.isEmpty(doc.progDataSource)||!doc.progDataSource.dataSourceType||doc.progDataSource.dataSourceType==="none"){ret.push({code:"CHK_MSG_PRG_FLD_300",data:`undefined datasource for ${field.data.field_id} field`,type:doc.studio_meta.not_in_use?"W":"E",category:"fieldset",ref:field.id,id:`${doc._id}-${field.id}`});return ret}else{var ret_dsc=check_prog_datasource(doc);if(ret_dsc.length)return ret;var _datasource_table_arr=progs_obj?.[doc.progDataSource.dataSourceTableId]?.tableFields;if(!_datasource_table_arr){ret.push({code:"CHK_MSG_PRG_FLD_310",data:`no fields found in datasource table ${doc.progDataSource.dataSourceTableId} `,type:doc.studio_meta.not_in_use?"W":"E",category:"fieldset",ref:field.id,id:`${doc._id}-${field.id}`});return ret}if(!find_item_by_key(_datasource_table_arr,"field_id",field.data.field_id)){if(!doc.progDataSource.dataSourceReduce||field.data.field_id!=="REDUCE_VALUE"){ret.push({code:"CHK_MSG_PRG_FLD_320",data:`invalid field ${field.data.field_id} in datasource table`,type:doc.studio_meta.not_in_use?"W":"E",category:"fieldset",ref:field.id,id:`${doc._id}-${field.id}`});return ret}}}}break;default:ret.push({code:"CHK_MSG_PRG_FLD_060",data:`invalid field type for ${field.data.field_id}`,type:doc.studio_meta.not_in_use?"W":"E",category:"fieldset",ref:field.id,id:`${doc._id}-${field.id}`});return ret;break}}if(!field?.props?.fieldType&&!field?.props?.propExpressions?.fieldType){ret.push({code:"CHK_MSG_PRG_FLD_130",data:`missing field fieldType`,type:doc.studio_meta.not_in_use?"W":"E",category:"fieldset",ref:field.id,id:`${doc._id}-${field.id}`});return ret}else if(field.props.fieldType){switch(field.props.fieldType){case"string":if(field?.props?.fieldValue&&typeof field.props.fieldValue!=="string"){ret.push({code:"CHK_MSG_PRG_FLD_200",data:`invalid value type ${field.props.fieldType} for ${field.data.field_id} field`,type:doc.studio_meta.not_in_use?"W":"E",category:"fieldset",ref:field.id,id:`${doc._id}-${field.id}`})}break;case"number":case"boolean":if(field?.props?.fieldValue){if(_.isNaN(_.toNumber(field?.props?.fieldValue))){ret.push({code:"CHK_MSG_PRG_FLD_210",data:`invalid value type ${field.props.fieldType} for ${field.data.field_id} field`,type:"E",category:"fieldset",ref:field.id,id:`${doc._id}-${field.id}`})}}break;case"object":case"array":if(field?.props?.fieldValue){try{JSON5.parse(field.props.fieldValue)}catch(err){ret.push({code:"CHK_MSG_PRG_FLD_220",data:`invalid value type "${field.props.fieldType}" for "${field.data.field_id}" field`,type:doc.studio_meta.not_in_use?"W":"E",category:"fieldset",ref:field.id,id:`${doc._id}-${field.id}`})}}break;default:ret.push({code:"CHK_MSG_PRG_FLD_160",data:`invalid field fieldType for ${field.data.field_id}`,type:doc.studio_meta.not_in_use?"W":"E",category:"fieldset",ref:field.id,id:`${doc._id}-${field.id}`});return ret;break}}if(!_.isEmpty(field.workflow)){ret=[...ret,...check_prog_triggers(doc,field.workflow,"field",field.id,field.data.field_id)]}}for(let[key,val]of Object.entries(name_counts_obj)){if(val>1){ret.push({code:"CHK_MSG_PRG_FLD_200",data:`duplicate field id for ${key}`,type:doc.studio_meta.not_in_use?"W":"E",category:"fieldset",id:`${doc._id}-${key}`})}}}return ret};const check_prog_events=function(doc){var ret=[];if(!doc.progEvents||_.isEmpty(doc.progEvents))return ret;var name_counts_obj={};for(let event_item of doc.progEvents){switch(event_item?.data?.type){case"user_defined":if(!event_item.data.event_name){ret.push({code:"CHK_MSG_PRG_EVT_010",data:`missing event name for ${event_item.id}`,type:"W",category:"event",ref:event_item.id,id:`${doc._id}-${event_item.id}`});continue}else{if(!/^[A-Za-z]+[\w\-\:\.]*$/.test(event_item.data.event_name)){ret.push({code:"CHK_MSG_PRG_EVT_020",data:`invalid event name for event "${event_item.data.event_name||event_item.data.type}"`,type:doc.studio_meta.not_in_use?"W":"E",category:"event",ref:event_item.id,id:`${doc._id}-${event_item.id}`})}if(!hide_not_in_use_check){const ret_event_id_use=find_trigger_property_value_in_progs(doc,["raise_event"],"event",event_item.data.event_name);if(!ret_event_id_use?.length){ret.push({code:"CHK_MSG_PRG_EVT_112",data:`event "${event_item.data.event_name}" not in use`,type:"W",category:"event",ref:event_item.id,not_in_use:true,id:`${doc._id}-${event_item.id}`})}}}if(event_item.data.condition){ret=[...ret,...check_prog_expression(doc,event_item.data.condition,event_item.id,"condition")]}else{if(!name_counts_obj[event_item.id]){name_counts_obj[event_item.id]=1}else{name_counts_obj[event_item.id]++}}break;case"screen_ready":case"client_interval":if(doc.properties.menuType!=="component"){ret.push({code:"CHK_MSG_PRG_EVT_030",data:`event type "${event_item.data.type}" only allowed for "${doc.properties.menuType}" in event "${event_item.data.event_name||event_item.data.type}"`,type:doc.studio_meta.not_in_use?"W":"E",category:"event",ref:event_item.id,id:`${doc._id}-${event_item.id}`})}if(event_item.data.type==="client_interval"&&!event_item.data.properties){ret.push({code:"CHK_MSG_PRG_EVT_035",data:`empty interval property in event "${event_item.data.event_name||event_item.data.type}"`,type:doc.studio_meta.not_in_use?"W":"E",category:"event",ref:event_item.id,id:`${doc._id}-${event_item.id}`})}break;case"on_load":case"on_exit":case"before_record":case"after_record":case"record_not_found":case"locate_not_found":break;default:ret.push({code:"CHK_MSG_PRG_EVT_018",data:`invalid event type for ${event_item.id}`,type:doc.studio_meta.not_in_use?"W":"E",category:"event",ref:event_item.id,id:`${doc._id}-${event_item.id}`});break}if(!_.isEmpty(event_item.workflow)){ret=[...ret,...check_prog_triggers(doc,event_item.workflow,"event",event_item.id,event_item.data.event_name||event_item.data.type)]}else{ret.push({code:"CHK_MSG_PRG_EVT_022",data:`event "${event_item.data.event_name||event_item.data.type}" is empty`,type:"W",category:"event",ref:event_item.id,id:`${doc._id}-${event_item.id}`})}}for(let[key,val]of Object.entries(name_counts_obj)){if(val>1){ret.push({code:"CHK_MSG_PRG_EVT_102",data:`duplicate "${key}" event `,type:"W",category:"event",id:`${doc._id}-${event_item.id}-${key}`})}}return ret};const check_prog_triggers=function(doc,workflow,source_type,source_id,source_name){var ret=[];if(!workflow||_.isEmpty(workflow))return ret;const check_target_program_parameters=function(trigger_item){if(!trigger_item.data.name.prog)return;const target_program_parameters_arr=progs_obj?.[trigger_item.data.name.prog]?.properties?.progParams||[];if(trigger_item?.data?.name?.parameters&&!_.isEmpty(trigger_item.data.name.parameters)){for(let[key,val]of Object.entries(trigger_item.data.name.parameters)){const param_ret=find_item_by_key(target_program_parameters_arr,"parameter",key);if(_.isEmpty(param_ret)){ret.push({code:"CHK_MSG_PRG_TRG_370",data:`parameter "${key}" not found in the target program "${progs_obj?.[trigger_item.data.name.prog].properties.menuName}" parameter list in ${source_type} "${source_name}" trigger`,type:"W",category:`${source_type}_trigger`,ref:trigger_item.id,source_id:source_id,id:`${doc._id}-${source_id}-${trigger_item.id}-${key}`});return}if(param_ret.data.dir!=="in"&&val.value){const ret_local_field=find_item_by_key(doc.progFields,"field_id",val.value);if(!ret_local_field){let ret_parent_field;const check_parent_program=function(prog_id){let parent_prog_id=progs_obj?.[prog_id]?.studio_meta?.parentId;if(parent_prog_id&&progs_obj?.[parent_prog_id]){ret_parent_field=find_item_by_key(progs_obj?.[parent_prog_id]?.progFields||[],"field_id",val.value);if(!ret_parent_field){return check_parent_program(parent_prog_id)}}};check_parent_program(doc._id);if(!ret_parent_field){const ret_global_field=find_item_by_key(progs_obj?.[`global_${app_obj._id}`]?.progFields||[],"field_id",val.value);if(!ret_global_field){ret.push({code:"CHK_MSG_PRG_TRG_372",data:`"${val.value}" parameter "Out" not found in the program Dataset in ${source_type} "${source_name}" trigger`,type:"W",category:`${source_type}_trigger`,ref:trigger_item.id,source_id:source_id,id:`${doc._id}-${source_id}-${trigger_item.id}-${key}`})}}}}}}else{if(target_program_parameters_arr.length){ret.push({code:"CHK_MSG_PRG_TRG_374",data:`found parameters in "${progs_obj?.[trigger_item.data.name.prog].properties.menuName}" but empty parameter to exchange in ${source_type} "${source_name}" trigger`,type:"W",category:`${source_type}_trigger`,ref:trigger_item.id,source_id:source_id,id:`${doc._id}-${source_id}-${trigger_item.id}`})}}};for(let trigger_item of workflow){const get_prog_id=function(){let _prop=trigger_item.data?.name?.properties;let _prog_id=trigger_item.data.name.prog_id||_prop?.["xu-exp:prog"];return _prog_id};const err_type=doc.studio_meta.not_in_use?"W":trigger_item.data.enabled?"E":"W";switch(trigger_item?.data?.action){case"comment":break;case"update":if(!trigger_item?.data?.name?.value){ret.push({code:"CHK_MSG_PRG_TRG_020",data:`no value to update in ${source_type} "${source_name}" trigger`,type:err_type,category:`${source_type}_trigger`,ref:trigger_item.id,source_id:source_id,id:`${doc._id}-${source_id}-${trigger_item.id}`})}else{const validate_update_function=function(exp){var viewFields=[];try{var json=JSON5.parse(exp.replace(/\n/gi,""));for(const[key,val]of Object.entries(json)){let id=key.substr(1,key.length-1);viewFields.push({val:val,id:id})}return viewFields}catch(e){if(!exp){return}if(exp.substr(exp.length-1,1)===";")exp=exp.substr(0,exp.length-1);var exp_arr=exp.split(/;\s*(?=(?:[^"]|"[^"]*")*$)/g);if(exp_arr?.length){for(let val of exp_arr){var pos=val.indexOf(":");var seg=[val.substring(0,pos),val.substring(pos+1)];if(seg&&seg.length===2){let id=seg[0].substr(1,seg[0].length);viewFields.push({id:id,val:seg[1]})}else{ret.push({code:"CHK_MSG_PRG_TRG_040",data:`invalid json; too many segments in${source_type} "${source_name}" trigger`,type:err_type,category:`${source_type}_trigger`,ref:trigger_item.id,source_id:source_id,id:`${doc._id}-${source_id}-${trigger_item.id}`})}}}return viewFields}};const ret_update_fields_arr=validate_update_function(trigger_item.data.name.value);if(!ret_update_fields_arr.length){ret.push({code:"CHK_MSG_PRG_TRG_050",data:`no fields to update in ${source_type} "${source_name}" trigger`,type:err_type,category:`${source_type}_trigger`,ref:trigger_item.id,source_id:source_id,id:`${doc._id}-${source_id}-${trigger_item.id}`})}else{for(let val of ret_update_fields_arr){const ret_fields=find_field_in_progs(doc,val.id);if(!ret_fields){ret.push({code:"CHK_MSG_PRG_TRG_060",data:`field "${val.id}" not found in the project programs for update in ${source_type} "${source_name}" trigger`,type:err_type,category:`${source_type}_trigger`,ref:trigger_item.id,source_id:source_id,id:`${doc._id}-${source_id}-${trigger_item.id}`})}}}}break;case"raise_event":if(!trigger_item?.data?.name?.event&&!trigger_item?.data?.name?.properties["xu-exp:event"]){ret.push({code:"CHK_MSG_PRG_TRG_100",data:`invalid event name for "${trigger_item.data.action}" in ${source_type} "${source_name}" trigger`,type:err_type,category:`${source_type}_trigger`,ref:trigger_item.id,source_id:source_id,id:`${doc._id}-${source_id}-${trigger_item.id}`})}else if(trigger_item?.data?.name?.event){if(!/^[A-Za-z]+[\w\-\:\.]*$/.test(trigger_item.data.name.event)){ret.push({code:"CHK_MSG_PRG_TRG_110",data:`invalid event name ${trigger_item.data.name.event} in ${source_type} "${source_name}" trigger`,type:err_type,category:`${source_type}_trigger`,ref:trigger_item.id,source_id:source_id,id:`${doc._id}-${source_id}-${trigger_item.id}`})}else{const ret_event_name=find_event_id_in_progs(doc,trigger_item.data.name.event);if(!ret_event_name.length){ret.push({code:"CHK_MSG_PRG_TRG_120",data:`call performed to non exist event name called from "${trigger_item.data.name.event}" in ${source_type} "${source_name}" trigger`,type:err_type,category:`${source_type}_trigger`,ref:trigger_item.id,source_id:source_id,id:`${doc._id}-${source_id}-${trigger_item.id}`})}else{if(ret_event_name.length===1&&!_.isEmpty(trigger_item.data.name.parameters)){for(let[key,val]of Object.entries(trigger_item.data.name.parameters)){if(_.isEmpty(progs_obj?.[ret_event_name[0].prog_id].progFields)){if(!find_item_by_key(progs_obj?.[ret_event_name[0].prog_id].progFields,"field_id",key)){ret.push({code:"CHK_MSG_PRG_TRG_130",data:`parameter "${key}" not exist in the dataset of the target program called from event name "${trigger_item.data.name.event}" in ${source_type} "${source_name}" trigger`,type:"W",category:`${source_type}_trigger`,ref:trigger_item.id,source_id:source_id,id:`${doc._id}-${source_id}-${trigger_item.id}-${key}`})}}}}}}}break;case"call_page":case"call_modal":case"call_popover":if(!trigger_item.data.name.prog){if(!trigger_item.data?.name?.properties?.["xu-exp:prog"]){ret.push({code:"CHK_MSG_PRG_TRG_310",data:`empty program to call in ${source_type} "${source_name}" trigger`,type:err_type,category:`${source_type}_trigger`,ref:trigger_item.id,source_id:source_id,id:`${doc._id}-${source_id}-${trigger_item.id}`})}}else{if(!progs_obj?.[trigger_item.data.name.prog]){ret.push({code:"CHK_MSG_PRG_TRG_320",data:`invalid program to call in ${source_type} "${source_name}" trigger`,type:err_type,category:`${source_type}_trigger`,ref:trigger_item.id,source_id:source_id,id:`${doc._id}-${source_id}-${trigger_item.id}`})}else{if(progs_obj?.[trigger_item.data.name.prog].properties.menuType!=="component"){ret.push({code:"CHK_MSG_PRG_TRG_334",data:`invalid program type "${trigger_item.data.action}" to call in ${source_type} "${source_name}" trigger`,type:err_type,category:`${source_type}_trigger`,ref:trigger_item.id,source_id:source_id,id:`${doc._id}-${source_id}-${trigger_item.id}`})}else{check_target_program_parameters(trigger_item)}}}break;case"call_project_api":if(!trigger_item.data.name.prog){if(!trigger_item.data?.name?.properties?.["xu-exp:prog"]){ret.push({code:"CHK_MSG_PRG_TRG_310",data:`empty program to call in ${source_type} "${source_name}" trigger`,type:err_type,category:`${source_type}_trigger`,ref:trigger_item.id,source_id:source_id,id:`${doc._id}-${source_id}-${trigger_item.id}`})}}else{if(!progs_obj?.[trigger_item.data.name.prog]){ret.push({code:"CHK_MSG_PRG_TRG_320",data:`invalid program to call in ${source_type} "${source_name}" trigger`,type:err_type,category:`${source_type}_trigger`,ref:trigger_item.id,source_id:source_id,id:`${doc._id}-${source_id}-${trigger_item.id}`})}else{if(progs_obj?.[trigger_item.data.name.prog].properties.menuType!=="api"){ret.push({code:"CHK_MSG_PRG_TRG_334",data:`invalid program type "${trigger_item.data.action}" to call in ${source_type} "${source_name}" trigger`,type:err_type,category:`${source_type}_trigger`,ref:trigger_item.id,source_id:source_id,id:`${doc._id}-${source_id}-${trigger_item.id}`})}else{check_target_program_parameters(trigger_item)}}}break;case"call_system_api":{const _api_method=trigger_item.data.name.api_method;if(!_api_method){ret.push({code:"CHK_MSG_PRG_TRG_380",data:`api_method not defined in ${source_type} "${source_name}" trigger`,type:err_type,category:`${source_type}_trigger`,ref:trigger_item.id,source_id:source_id,id:`${doc._id}-${source_id}-${trigger_item.id}`})}else{if(typeof _conf!=="undefined"){if(!_conf.cpi_methods[_api_method]){ret.push({code:"CHK_MSG_PRG_TRG_382",data:`api method ${_api_method} unrecognized in ${source_type} "${source_name}" trigger`,type:err_type,category:`${source_type}_trigger`,ref:trigger_item.id,source_id:source_id,id:`${doc._id}-${source_id}-${trigger_item.id}`})}else{if(_conf.cpi_methods[_api_method].private){return ret.push({code:"CHK_MSG_PRG_TRG_384",data:`api method ${_api_method} is private in ${source_type} "${source_name}" trigger`,type:err_type,category:`${source_type}_trigger`,ref:trigger_item.id,source_id:source_id,id:`${doc._id}-${source_id}-${trigger_item.id}`})}if(_conf.cpi_methods[_api_method].fields){for(let[key,val]of Object.entries(_conf.cpi_methods[_api_method].fields)){if(val.mandatory&&!trigger_item.data.name?.payload?.[key]){ret.push({code:"CHK_MSG_PRG_TRG_386",data:`field ${key} for api method ${_api_method} is mandatory field in ${source_type} "${source_name}" trigger`,type:err_type,category:`${source_type}_trigger`,ref:trigger_item.id,source_id:source_id,id:`${doc._id}-${source_id}-${trigger_item.id}`})}}}}}}break}case"call_external_api":{if(!trigger_item.data.name.method){ret.push({code:"CHK_MSG_PRG_TRG_388",data:`method not defined in ${source_type} "${source_name}" trigger`,type:err_type,category:`${source_type}_trigger`,ref:trigger_item.id,source_id:source_id,id:`${doc._id}-${source_id}-${trigger_item.id}`})}if(!trigger_item.data.name.url){ret.push({code:"CHK_MSG_PRG_TRG_389",data:`url not defined in ${source_type} "${source_name}" trigger`,type:err_type,category:`${source_type}_trigger`,ref:trigger_item.id,source_id:source_id,id:`${doc._id}-${source_id}-${trigger_item.id}`})}break}case"get_data":case"set_data":case"batch":case"call_native_javascript":case"call_evaluate_javascript":case"call_alert":if(!trigger_item.data.name.prog){if(!trigger_item.data?.name?.properties?.["xu-exp:prog"]){ret.push({code:"CHK_MSG_PRG_TRG_310",data:`empty program to call in ${source_type} "${source_name}" trigger`,type:err_type,category:`${source_type}_trigger`,ref:trigger_item.id,source_id:source_id,id:`${doc._id}-${source_id}-${trigger_item.id}`})}}else{if(!progs_obj?.[trigger_item.data.name.prog]){ret.push({code:"CHK_MSG_PRG_TRG_320",data:`invalid program to call in ${source_type} "${source_name}" trigger`,type:err_type,category:`${source_type}_trigger`,ref:trigger_item.id,source_id:source_id,id:`${doc._id}-${source_id}-${trigger_item.id}`})}else{if(progs_obj?.[trigger_item.data.name.prog].properties.menuType!==trigger_item.data.action){if(["call_native_javascript","call_evaluate_javascript"].includes(trigger_item.data.action)&&progs_obj?.[trigger_item.data.name.prog].properties.menuType==="javascript"){continue}if(["call_alert"].includes(trigger_item.data.action)&&progs_obj?.[trigger_item.data.name.prog].properties.menuType==="alert"){continue}ret.push({code:"CHK_MSG_PRG_TRG_330",data:`call set to "${trigger_item.data.action}" but found "${progs_obj?.[trigger_item.data.name.prog].properties.menuType}" instead in ${source_type} "${source_name}" trigger`,type:err_type,category:`${source_type}_trigger`,ref:trigger_item.id,source_id:source_id,id:`${doc._id}-${source_id}-${trigger_item.id}`})}else{check_target_program_parameters(trigger_item)}}}break;case"execute_native_javascript":case"execute_evaluate_javascript":check_prog_expression(doc,trigger_item.data.name.value,trigger_item.id,"script");break;case"emit_event":if(!trigger_item?.data?.name?.value){ret.push({code:"CHK_MSG_PRG_TRG_800",data:`no event defined for "emit_event" in ${source_type} "${source_name}" trigger`,type:err_type,category:`alert`,ref:doc._id,id:`${doc._id}-${source_id}-${trigger_item.id}`})}else{if(!/^[A-Za-z]+[\w\-\:\.]*$/.test(trigger_item.data.name.value)){ret.push({code:"CHK_MSG_PRG_TRG_810",data:`invalid event name ${trigger_item.data.name.value} in ${source_type} "${source_name}" trigger`,type:err_type,category:`${source_type}_trigger`,ref:trigger_item.id,source_id:source_id,id:`${doc._id}-${source_id}-${trigger_item.id}`})}}break;case"alert":if(_.isEmpty(trigger_item.data.name)){ret.push({code:"CHK_MSG_PRG_TRG_610",data:`no alert properties defined`,type:err_type,category:`alert`,ref:doc._id,id:`${doc._id}-${source_id}-${trigger_item.id}`})}else{if(!trigger_item.data.name.alertType){ret.push({code:"CHK_MSG_PRG_TRG_612",data:`missing alert type property`,type:err_type,category:`alert`,ref:doc._id,id:`${doc._id}-${source_id}-${trigger_item.id}`})}if(!trigger_item.data.name.alertDisplay){ret.push({code:"CHK_MSG_PRG_TRG_614",data:`missing alert display property`,type:err_type,category:`alert`,ref:doc._id,id:`${doc._id}-${source_id}-${trigger_item.id}`})}if(!trigger_item.data.name.alertTitle){ret.push({code:"CHK_MSG_PRG_TRG_616",data:`missing alert title property`,type:"W",category:`alert`,ref:doc._id,id:`${doc._id}-${source_id}-${trigger_item.id}`})}if(!trigger_item.data.name.alertBody){ret.push({code:"CHK_MSG_PRG_TRG_618",data:`missing alert body property`,type:"W",category:`alert`,ref:doc._id,id:`${doc._id}-${source_id}-${trigger_item.id}`})}}break;case"loader_on":case"loader_off":if(doc.properties.menuType!=="component"){ret.push({code:"CHK_MSG_PRG_TRG_400",data:`"${trigger_item.data.action}" can only be executed by component in ${source_type} "${source_name}" trigger`,type:err_type,category:`${source_type}_trigger`,ref:trigger_item.id,source_id:source_id,id:`${doc._id}-${source_id}-${trigger_item.id}`})}break;case"invoke_action":if(doc.properties.menuType!=="component"){ret.push({code:"CHK_MSG_PRG_TRG_400",data:`"${trigger_item.data.action}" can only be executed by component in ${source_type} "${source_name}" trigger`,type:err_type,category:`${source_type}_trigger`,ref:trigger_item.id,source_id:source_id,id:`${doc._id}-${source_id}-${trigger_item.id}`})}if(!["act_next","act_prev","act_first","act_last","act_reload","act_refresh","act_print","act_save","act_delete"].includes(trigger_item.data.name.value)){ret.push({code:"CHK_MSG_PRG_TRG_400",data:`invalid "${trigger_item.data.name.value}" for "${trigger_item.data.action}" in ${source_type} "${source_name}" trigger`,type:err_type,category:`${source_type}_trigger`,ref:trigger_item.id,source_id:source_id,id:`${doc._id}-${source_id}-${trigger_item.id}`})}break;case"delay":if(!trigger_item?.data?.name?.value){ret.push({code:"CHK_MSG_PRG_TRG_520",data:`empty delay value in ${source_type} "${source_name}" trigger`,type:err_type,category:`${source_type}_trigger`,ref:trigger_item.id,source_id:source_id,id:`${doc._id}-${source_id}-${trigger_item.id}`})}break;case"call_library":if(!trigger_item?.data?.name?.plugin_name){ret.push({code:"CHK_MSG_PRG_TRG_510",data:`empty library value in ${source_type} "${source_name}" trigger`,type:err_type,category:`${source_type}_trigger`,ref:trigger_item.id,source_id:source_id,id:`${doc._id}-${source_id}-${trigger_item.id}`})}else{if(!trigger_item?.data?.name?.library_method){ret.push({code:"CHK_MSG_PRG_TRG_516",data:`empty library ${trigger_item.data.name.plugin_name} method in ${source_type} "${source_name}" trigger`,type:err_type,category:`${source_type}_trigger`,ref:trigger_item.id,source_id:source_id,id:`${doc._id}-${source_id}-${trigger_item.id}`})}if(!app_obj?.app_plugins_purchased?.[trigger_item.data.name.plugin_name]){ret.push({code:"CHK_MSG_PRG_TRG_512",data:`invalid library call ${trigger_item.data.name.plugin_name} in ${source_type} "${source_name}" trigger`,type:err_type,category:`${source_type}_trigger`,ref:trigger_item.id,source_id:source_id,id:`${doc._id}-${source_id}-${trigger_item.id}`})}else{if(!app_obj.app_plugins_purchased[trigger_item.data.name.plugin_name].installed){ret.push({code:"CHK_MSG_PRG_TRG_514",data:` library "${trigger_item.data.name.plugin_name}" not installed in ${source_type} "${source_name}" trigger`,type:err_type,category:`${source_type}_trigger`,ref:trigger_item.id,source_id:source_id,id:`${doc._id}-${source_id}-${trigger_item.id}`})}}}break;case"alter_ui_element":case"create_ui_element":case"info_ui_element":case"remove_ui_element":case"empty_ui_element":case"cache_ui_element":case"load_ui_element":ret.push({code:"CHK_MSG_PRG_TRG_900",data:`deprecated "${trigger_item?.data?.action}" action in ${source_type} "${source_name}" trigger`,type:err_type,category:`${source_type}_trigger`,ref:trigger_item.id,source_id:source_id,id:`${doc._id}-${source_id}-${trigger_item.id}`});break;default:ret.push({code:"CHK_MSG_PRG_TRG_008",data:`invalid trigger type "${trigger_item.data.action}" for ${source_type} "${source_name}" trigger`,type:err_type,category:`${source_type}_trigger`,ref:trigger_item.id,source_id:source_id,id:`${doc._id}-${source_id}-${trigger_item.id}`});break}if(trigger_item.props.condition){ret=[...ret,...check_prog_expression(doc,trigger_item.props.condition,trigger_item.id,"condition")]}}return ret};const check_prog_datasource=function(doc){var ret=[];if(!doc.progDataSource||_.isEmpty(doc.progDataSource)||!doc.progDataSource.dataSourceType||doc.progDataSource.dataSourceType==="none"){return ret}switch(doc.progDataSource.dataSourceType){case"table":if(!doc.progDataSource.dataSourceTableId&&!doc?.progDataSource?.dataSourceTableIdExp){ret.push({code:"CHK_MSG_PRG_DSC_010",data:`missing table id for datasource`,type:"E",id:`${doc._id}`});return ret}else{if(doc.progDataSource.dataSourceTableId&&!progs_obj?.[doc.progDataSource.dataSourceTableId]){ret.push({code:"CHK_MSG_PRG_DSC_030",data:`invalid table id ${doc.progDataSource.dataSourceTableId} for datasource`,type:"E",id:`${doc._id}`});return ret}let found_error;function arraysEqual(arr1,arr2){if(arr1.length!==arr2.length)return false;let sortedArr1=arr1.slice().sort();let sortedArr2=arr2.slice().sort();for(let i=0;i<sortedArr1.length;i++){if(sortedArr1[i]!==sortedArr2[i])return false}return true}if(doc.progDataSource.dataSourceIndexesObj){const table_indexes_arr=progs_obj?.[doc.progDataSource.dataSourceTableId]?.tableIndexes;for(let[index_id,index_data]of Object.entries(doc.progDataSource.dataSourceIndexesObj)){if(table_indexes_arr||!find_item_by_id(table_indexes_arr,index_id)){ret.push({code:"CHK_MSG_PRG_DSC_032",data:`find invalid index in table ${progs_obj?.[doc.progDataSource.dataSourceTableId]?.properties?.menuName||doc.progDataSource.dataSourceTableId} for index ${index_id} in dataSourceIndexesObj`,type:"E",id:`${doc._id}`});found_error=true;break}let prog_keys=[];for(let[field_id,val]of Object.entries(index_data)){prog_keys.push(field_id)}if(!arraysEqual(prog_keys,table_indexes_arr.keys)){ret.push({code:"CHK_MSG_PRG_DSC_034",data:`find in-consist index keys in table ${progs_obj?.[doc.progDataSource.dataSourceTableId]?.properties?.menuName||doc.progDataSource.dataSourceTableId} for index ${index_id} in dataSourceIndexesObj`,type:"E",id:`${doc._id}`});found_error=true;break}}if(found_error)return ret}}if(doc.properties.menuType!=="set_data"){if(!doc.progDataSource.dataSourceIndexId&&!doc.progDataSource.dataSourceIndexIdExp){ret.push({code:"CHK_MSG_PRG_DSC_042",data:`index not defined for the datasource table`,type:"W",id:`${doc._id}`})}else if(doc.progDataSource.dataSourceIndexId){if(!progs_obj?.[doc.progDataSource.dataSourceTableId]?.tableIndexes){ret.push({code:"CHK_MSG_PRG_DSC_030",data:`invalid table id ${doc.progDataSource.dataSourceTableId} for datasource`,type:"E",id:`${doc._id}`});return ret}else{const table_indexes_arr=progs_obj?.[doc.progDataSource.dataSourceTableId].tableIndexes;if(!find_item_by_id(table_indexes_arr,doc.progDataSource.dataSourceIndexId)){ret.push({code:"CHK_MSG_PRG_DSC_040",data:`invalid index in table ${progs_obj?.[doc.progDataSource.dataSourceTableId]?.properties?.menuName||doc.progDataSource.dataSourceTableId} for index ${doc.progDataSource.dataSourceIndexId}`,type:"E",id:`${doc._id}`});return ret}}}if(!doc.progDataSource.dataSourceSort&&!doc.progDataSource.dataSourceSortExp){ret.push({code:"CHK_MSG_PRG_DSC_200",data:`missing sort value for datasource`,type:"E",id:`${doc._id}`})}else if(doc.progDataSource.dataSourceSort){if(!["asc","des"].includes(doc.progDataSource.dataSourceSort)){ret.push({code:"CHK_MSG_PRG_DSC_210",data:`invalid sort value for datasource`,type:"E",id:`${doc._id}`})}}if(doc.progDataSource.dataSourceSkip&&typeof doc.progDataSource.dataSourceSkip!=="number"){ret.push({code:"CHK_MSG_PRG_DSC_220",data:`invalid skip value for datasource`,type:"E",id:`${doc._id}`})}if(doc.progDataSource.dataSourceLimit&&typeof doc.progDataSource.dataSourceLimit!=="number"){ret.push({code:"CHK_MSG_PRG_DSC_230",data:`invalid limit value for datasource`,type:"E",id:`${doc._id}`})}}break;default:ret.push({code:"CHK_MSG_PRG_DSC_040",data:`invalid datasource type ${doc.progDataSource.dataSourceType}`,type:"E",id:`${doc._id}`});break}return ret};const check_prog_parameters=function(doc){var ret=[];if(!doc?.properties?.progParams)return ret;var name_counts_obj={};for(let parameter of doc.properties.progParams){if(!parameter?.data?.parameter){ret.push({code:"CHK_MSG_PRG_PRM_010",data:`missing parameter name`,type:doc.studio_meta.not_in_use?"W":"E",category:"parameter",ref:parameter.id,id:`${doc._id}-${parameter.id}`})}else{if(!/^[A-Za-z]+[\w\-\:\.]*$/.test(parameter.data.parameter)){ret.push({code:"CHK_MSG_PRG_PRM_020",data:`invalid parameter name`,type:doc.studio_meta.not_in_use?"W":"E",category:"parameter",ref:parameter.id,id:`${doc._id}-${parameter.id}`})}if(!name_counts_obj[parameter.data.parameter]){name_counts_obj[parameter.data.parameter]=1}else{name_counts_obj[parameter.data.parameter]++}if(!hide_not_in_use_check){if(parameter.data.dir==="in"){if(!find_field_in_progs(doc,parameter.data.parameter)){ret.push({code:"CHK_MSG_PRG_PRM_022",data:`parameter "${parameter.data.parameter}" not in use`,type:"W",category:"parameter",ref:parameter.id,not_in_use:true,id:`${doc._id}-${parameter.id}`})}}}}if(!parameter?.data?.type){ret.push({code:"CHK_MSG_PRG_PRM_030",data:`missing parameter type for ${parameter.data.parameter}`,type:doc.studio_meta.not_in_use?"W":"E",category:"parameter",ref:parameter.id,id:`${doc._id}-${parameter.id}`});return ret}else{switch(parameter.data.type){case"string":break;case"number":case"boolean":break;case"object":break;case"array":break;default:ret.push({code:"CHK_MSG_PRG_PRM_040",data:`invalid parameter type "${parameter.data.type}" for ${parameter.data.parameter}`,type:doc.studio_meta.not_in_use?"W":"E",category:"parameter",ref:parameter.id,id:`${doc._id}-${parameter.id}`});return ret;break}}if(!parameter?.data?.dir){ret.push({code:"CHK_MSG_PRG_PRM_080",data:`missing parameter dir for ${parameter.data.parameter}`,type:doc.studio_meta.not_in_use?"W":"E",category:"parameter",ref:parameter.id,id:`${doc._id}-${parameter.id}`});return ret}else{switch(parameter.data.dir){case"in":break;case"out":if(!find_item_by_key(doc.progFields,"field_id",parameter.data.parameter)){ret.push({code:"CHK_MSG_PRG_PRM_100",data:`missing parameter return in the fieldset for ${parameter.data.parameter}`,type:doc.studio_meta.not_in_use?"W":"E",category:"parameter",ref:parameter.id,id:`${doc._id}-${parameter.id}`})}break;default:ret.push({code:"CHK_MSG_PRG_PRM_090",data:`invalid parameter dir for ${parameter.data.parameter}`,type:doc.studio_meta.not_in_use?"W":"E",category:"parameter",ref:parameter.id,id:`${doc._id}-${parameter.id}`});return ret;break}}}for(let[key,val]of Object.entries(name_counts_obj)){if(val>1){ret.push({code:"CHK_MSG_PRG_PRM_050",data:`duplicate parameter name for ${key}`,type:doc.studio_meta.not_in_use?"W":"E",category:"parameter",ref:parameter.id,id:`${doc._id}-${parameter.id}-${key}`})}}return ret};const check_javascript=function(doc){var ret=[];if(!doc?.scriptData?.value){ret.push({code:"CHK_MSG_PRG_JVS_012",data:"no script to run",type:"W",id:`${doc._id}`})}else{}return ret};const find_item_by_key=function(arr,key,val){return arr.find(function(e){return e.data[key]===val})};const find_item_by_id=function(arr,val){return arr.find(function(e){return e.id===val})};const find_field_in_progs=function(doc,field_id,prog_id){const regex=new RegExp(`@${field_id}\\b`);if(!regex.test(progs_str)){return}var ret=[];for(let[key,prog]of Object.entries(progs_obj)){var fields_arr=[];if(prog.tableFields){fields_arr=prog.tableFields}if(prog.progFields){fields_arr=prog.progFields}if(_.isEmpty(fields_arr)){continue}for(let field_item of fields_arr){if(field_item.data.field_id===field_id){ret.push({prog_id:prog._id,field_item:field_item,properties:prog.properties})}}}return ret};const check_prog_expression=function(doc,exp,path,category){var ret=[];if(!exp)return ret;if(!UglifyJS)return ret;const regex=/@\w+/g;const matches=exp.match(regex);var field_matches={};try{if(matches){for(let field of matches){const ret_field=find_field_in_progs(doc,field.substr(1));if(!ret_field){ret.push({code:"CHK_MSG_PRG_EXP_012",data:`field "${field}" not found in the project datasets using expression "${exp.substr(0,20)}.." in ${path}`,type:"W",category:category,source_id:path,id:`${doc._id}-${path}-${field}`})}else{field_matches[field]=ret_field}}}}catch(error){debugger}if(!_.isEmpty(ret)){return ret}if(_.isEmpty(field_matches)){var options={warnings:true};var result=UglifyJS.minify(exp,options);if(result.error){ret.push({code:"CHK_MSG_PRG_EXP_022",data:`expression error ${result.error.message} in ${exp.substr(0,20)}.. in ${path}`,type:doc.studio_meta.not_in_use?"W":"E",category:category,details:result.error,source_id:path,id:`${doc._id}-${path}`})}if(result.warnings){ret.push({code:"CHK_MSG_PRG_EXP_024",data:`expression warning ${result.warnings[0]} in ${exp.substr(0,20)}.. in ${path}`,type:"W",category:category,details:result.warnings,source_id:path,id:`${doc._id}-${path}`})}}else{var clean_exp=exp;var field_type="string";var skip_eval;for(let[key,val]of Object.entries(field_matches)){if(val.length>1){var field_ind_found_in_current_program;for(let[ret_key,ret_val]of Object.entries(val)){if(ret_val.prog_id===doc._id){field_ind_found_in_current_program=ret_key;break}}if(typeof field_ind_found_in_current_program==="undefined"){skip_eval=true;break}else{field_type=val[field_ind_found_in_current_program]?.field_item?.props?.fieldType}}else{field_type=val[0]?.field_item?.props?.fieldType}switch(field_type){case"string":clean_exp=clean_exp.replaceAll(key,"''");break;case"number":case"boolean":case"bool":clean_exp=clean_exp.replaceAll(key,"0");break;case"object":clean_exp=clean_exp.replaceAll(key,"{}");break;case"array":clean_exp=clean_exp.replaceAll(key,"[]");break;default:break}}if(!skip_eval){var options={warnings:true};var result=UglifyJS.minify(clean_exp,options);if(result.error){ret.push({code:"CHK_MSG_PRG_EXP_026",data:`expression error ${result.error.message} in ${exp.substr(0,20)}.. in ${path}`,type:doc.studio_meta.not_in_use?"W":"E",category:category,details:result.error,source_id:path,id:`${doc._id}-${path}`})}if(result.warnings){ret.push({code:"CHK_MSG_PRG_EXP_028",data:`expression warning ${result.warnings[0]} in ${exp.substr(0,20)}.. in ${path}`,type:"W",category:category,details:result.warnings,source_id:path,id:`${doc._id}-${path}`})}}}return ret};const find_event_id_in_progs=function(doc,event_id){var ret=[];for(let[key,prog]of Object.entries(progs_obj)){if(!prog.progEvents||_.isEmpty(prog.progEvents)){continue}for(let event_item of prog.progEvents){if(event_item.data.event_name===event_id){ret.push({prog_id:prog._id,event_item:event_item,properties:prog.properties})}}}if(!ret.length)return false;return ret};const find_xu_tree_id_in_progs=function(doc,xu_tree_id){var ret=[];for(let[key,prog]of Object.entries(progs_obj)){if(!prog.progUi||_.isEmpty(prog.progUi)){continue}const run_tree=function(node){for(let item of node){if(item.xu_tree_id===xu_tree_id){ret.push({prog_id:prog._id,item:item,properties:prog.properties})}if(item.children){run_tree(item.children)}}};run_tree(prog.progUi)}if(!ret.length)return false;return ret};const find_trigger_property_value_in_progs=function(doc,triggers_arr,property,value,search_in_doc_prog_only){var ret=[];const find_in_triggers=function(prog,workflow){if(!workflow)return;try{for(let val of workflow){if(triggers_arr.includes(val?.data?.action)){const str=JSON.stringify(val);const regex=new RegExp(`\\b${value}\\b`);if(value===null||val?.data?.name?.[property]===value||regex.test(str)){if(val?.data?.name?.[property]){ret.push({prog_id:prog._id,val:val,properties:prog.properties,prop_value:val?.data?.name?.[property]})}else{ret.push({prog_id:prog._id,val:val,properties:prog.properties})}}}}}catch(error){console.error(doc._id,workflow)}};const run_program_search=function(prog){if(prog?.progEvents&&!_.isEmpty(prog.progEvents)){for(let event_item of prog.progEvents){if(event_item.workflow){find_in_triggers(prog,event_item.workflow)}}}if(prog?.progFields&&!_.isEmpty(prog.progFields)){for(let field_item of prog.progFields){if(field_item.workflow){find_in_triggers(prog,field_item.workflow)}}}if(prog?.progUi&&!_.isEmpty(prog.progUi)){const run_tree=function(node){try{for(let item of node){if(item.attributes){for(let[key,val]of Object.entries(item.attributes)){if(key.substr(0,6)==="xu-on:"){if(!_.isEmpty(val)){for(let trigger_item of val){find_in_triggers(prog,trigger_item.workflow)}}}}}if(item.children){run_tree(item.children)}}}catch(error){console.error("find in ui workflow",error)}};run_tree(prog.progUi)}};if(!search_in_doc_prog_only){for(let[key,prog]of Object.entries(progs_obj)){run_program_search(prog)}}else{run_program_search(progs_obj?.[doc._id])}if(!ret.length)return false;return ret};const find_panel_prog_in_progs=function(doc,prog_id,search_in_doc_prog_only){var ret=[];const find_in_prog=function(prog){if(_.isEmpty(prog?.progUi))return;const run_tree=function(node){for(let item of node){if(item.tagName==="xu-panel"){const str=JSON.stringify(item);const regex=new RegExp(`\\b${prog_id}\\b`);if(prog_id===null||item?.attributes?.program?.prog===prog_id||regex.test(str)){if(item?.attributes?.program?.prog){ret.push({prog_id:prog._id,item:item,prop_value:item.attributes.program.prog})}else{ret.push({prog_id:prog._id,item:item})}}}if(item.children){run_tree(item.children)}}};run_tree(prog.progUi)};if(!search_in_doc_prog_only){for(let[key,prog]of Object.entries(progs_obj)){find_in_prog(prog)}}else{find_in_prog(progs_obj?.[doc._id])}if(!ret.length)return false;return ret};const find_table_in_progs=function(doc,table_id,search_in_doc_prog_only){var ret=[];const find_in_prog=function(prog){if(!prog.progDataSource||_.isEmpty(prog.progDataSource)||prog.progDataSource.dataSourceType!=="table"){return}if(prog.progDataSource.dataSourceTableId===table_id||prog.progDataSource?.dataSourceTableIdExp?.includes(table_id)){ret.push({prog_id:prog._id})}};if(!search_in_doc_prog_only){for(let[key,prog]of Object.entries(progs_obj)){find_in_prog(prog)}}else{find_in_prog(progs_obj?.[doc._id])}if(!ret.length)return false;return ret};const find_prog_in_fieldset_fieldValue_progs=function(doc,prog_id,search_in_doc_prog_only){var ret=[];const find_in_prog=function(prog){if(!prog.progFields)return;for(let field_item of prog.progFields){const str=JSON.stringify(field_item);const regex=new RegExp(`\\b${prog_id}\\b`);if(prog_id===null||field_item?.props?.fieldValue===prog_id||regex.test(str)){if(field_item?.props?.fieldValue){ret.push({prog_id:prog._id,field_item:field_item,properties:prog.properties,prop_value:field_item.props.fieldValue})}else{ret.push({prog_id:prog._id,field_item:field_item,properties:prog.properties})}}}};if(!search_in_doc_prog_only){for(let[key,prog]of Object.entries(progs_obj)){find_in_prog(prog)}}else{find_in_prog(progs_obj?.[doc._id])}if(!ret.length)return false;return ret};const new_node_id=function(type,app_id){const abbreviate=word=>{if(word.length<=3){return word}let abbreviation=word[0];const vowels="aeiou";for(let i=1;i<word.length&&abbreviation.length<3;i++){if(!vowels.includes(word[i].toLowerCase())){abbreviation+=word[i]}}if(abbreviation.length<3){abbreviation=word.substring(0,3)}return abbreviation};var last12uuid=crypto.randomUUID().split("-")[4];if(type){var menuAbbreviated=abbreviate(type.replaceAll("_",""));return`${app_id.substr(app_id.length-3)}_${menuAbbreviated}_${last12uuid}`}return app_id.substr(app_id.length-3)+"_"+last12uuid};function detectCryptoString(str){const patterns={uuid:/^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i};const results={};for(const[type,pattern]of Object.entries(patterns)){results[type]=pattern.test(str)}return results}export const get_zod_schema=function(type){const UuidSchema=z.string().uuid().describe(`UUID format identifier`);const TimestampSchema=z.number().describe(`Unix timestamp in milliseconds`);const StudioMetaSchema=z.object({created:TimestampSchema.describe(`Timestamp when the ${type} was created`),createdByUid:z.string().describe(`User ID of the ${type} creator`),checkedInUserId:z.string().describe(`Last user ID who checked in the ${type}`),checkedInUserName:z.string().describe(`Display name of the last user who modified`),savedByUid:z.string().describe(`User ID who last saved the ${type}`),parentId:z.string().describe(`Parent container ID (default: "programs")`),source:z.string().optional().describe(`Source of creation (e.g., "studio ai", "studio ide")`),ui_preview_sizes:z.object({w:z.number().describe(`Preview width`),h:z.number().describe(`Preview height`),l:z.number().describe(`Left position`),t:z.number().describe(`Top position`)}).optional().describe(`Optional UI preview layout hints for visual editors`)}).describe(`Studio metadata for tracking creation, modification, and organizational information`);const ProgParamSchema=z.object({id:z.union([z.string(),z.number()]).describe(`Unique identifier for the parameter`),data:z.object({dir:z.union([z.literal(`in`),z.literal(`out`)]).describe(`Parameter direction: "in" for input parameters, "out" for output parameters`),parameter:z.string().describe(`Parameter name used for referencing in code and workflows`),type:z.union([z.literal(`string`),z.literal(`number`),z.literal(`boolean`),z.literal(`array`),z.literal(`object`)]).describe(`Expected data type of the parameter value`)}).describe(`Core parameter configuration including direction, name, and type`),props:z.object({}).optional().describe(`Additional parameter properties (reserved for future use)`)}).describe(`Input/output parameter definition for ${type} interface`);const ProgFieldSchema=z.object({id:UuidSchema.describe(`Unique UUID identifier for the field`),data:z.object({type:z.union([z.literal(`virtual`),z.literal(`table`),z.literal(`expression`),z.literal(`datasource`)]).describe(`Field type: virtual=variable, table=field from datasource table, expression=holds expression without evaluation, datasource=iterable datasource object/array`),field_id:z.string().describe(`The unique field name used for referencing`)}).describe(`Core field configuration defining its type and identifier`),props:z.object({fieldType:z.union([z.literal(`string`),z.literal(`number`),z.literal(`boolean`),z.literal(`array`),z.literal(`object`)]).describe(`Data type held by the field`),propExpressions:z.object({fieldValue:z.string().optional().describe(`Expression or static value for the field`),fieldType:z.string().optional().describe(`Dynamic field type expression`)}).strict().describe(`Property expressions - only fieldValue and fieldType are allowed`)}).describe(`Field properties including data type and expressions`),workflow:z.array(z.any()).optional().describe(`Optional workflow actions triggered by field changes`)}).describe(`Internal field definition used by the ${type} for data management`);const WorkflowActionSchema=z.object({id:z.union([UuidSchema,z.string(),z.number()]).describe(`Unique identifier for the workflow step`),data:z.object({action:z.union([z.literal(`call_modal`).describe(`Opens a ${type} as a modal dialog`),z.literal(`call_popover`).describe(`Opens a ${type} as a popover overlay`),z.literal(`call_page`).describe(`Navigates to or opens a page ${type}`),z.literal(`call_native_javascript`).describe(`Calls a JavaScript program by ID`),z.literal(`execute_native_javascript`).describe(`Executes inline JavaScript code`),z.literal(`call_evaluate_javascript`).describe(`Calls JavaScript program with argument evaluation`),z.literal(`execute_evaluate_javascript`).describe(`Evaluates and runs dynamic JavaScript expressions`),z.literal(`emit_event`).describe(`Emits a JavaScript event`),z.literal(`loader_on`).describe(`Shows loading indicator`),z.literal(`loader_off`).describe(`Hides loading indicator`),z.literal(`invoke_action`).describe(`Executes system-level actions (refresh, save, etc.)`),z.literal(`update`).describe(`Updates variable values or field data`),z.literal(`raise_event`).describe(`Triggers internal application events`),z.literal(`get_data`).describe(`Executes a get_data program for data retrieval`),z.literal(`set_data`).describe(`Executes a set_data program for data persistence`),z.literal(`batch`).describe(`Executes a batch program for bulk operations`),z.literal(`call_project_api`).describe(`Calls an API program within the current project`),z.literal(`call_external_api`).describe(`Makes HTTP requests to external APIs`),z.literal(`call_system_api`).describe(`Invokes system-level API methods`),z.literal(`alert`).describe(`Displays alert messages (modal, inline, etc.)`),z.literal(`call_alert`).describe(`Calls an alert program by ID`),z.literal(`comment`).describe(`Adds descriptive documentation to workflow`),z.literal(`delay`).describe(`Pauses workflow execution for specified duration`)]).describe(`The specific workflow action type to execute`),name:z.object({properties:z.object({}).optional().describe(`Action-specific properties configuration`),parameters:z.object({doc_in:z.object({value:z.string().optional().describe(`Static parameter value`),fx:z.string().optional().describe(`Dynamic expression referencing variables`)}).optional().describe(`Input parameter for data retrieval`),class_id:z.object({value:z.string().optional().describe(`Static parameter value`),fx:z.string().optional().describe(`Dynamic expression referencing variables`)}).optional().describe(`Class ID parameter for data operations`)}).catchall(z.object({value:z.string().optional().describe(`Static parameter value`),fx:z.string().optional().describe(`Dynamic expression referencing variables`)})).optional().describe(`Input parameters with static values or dynamic expressions`),prog:z.string().optional().describe(`Program ID to call (for call_* actions)`),value:z.string().optional().describe(`Value for action (comments, JavaScript code, variable assignments, delay duration)`),event:z.string().optional().describe(`Event name to trigger (for raise_event action)`),outputField:z.string().optional().describe(`Output variable to store action results (for set_data)`),url:z.string().optional().describe(`External API endpoint URL`),method:z.union([z.literal(`GET`),z.literal(`POST`),z.literal(`PUT`),z.literal(`DELETE`),z.literal(`PATCH`)]).optional().describe(`HTTP method for API calls`),api_method:z.string().optional().describe(`System-level method to invoke`),payload:z.object({}).optional().describe(`Data payload for API calls`),createLog:z.boolean().optional().describe(`Whether to create a log entry for alerts`),alertDisplay:z.union([z.literal(`modal`),z.literal(`inline`),z.literal(`toast`)]).optional().describe(`Alert display type`),alertType:z.union([z.literal(`error`),z.literal(`warning`),z.literal(`info`),z.literal(`success`)]).optional().describe(`Alert message type`),alertTitle:z.string().optional().describe(`Alert title text`),alertBody:z.string().optional().describe(`Alert body message content`)}).describe(`Action-specific configuration and parameters`),enabled:z.boolean().describe(`Whether the workflow step is active and will execute`)}).describe(`Core workflow action definition with type-specific validation`),props:z.object({condition:z.string().optional().describe(`Optional expression that must evaluate to true for action to execute`),async:z.boolean().optional().describe(`Whether to execute asynchronously without waiting for completion`)}).optional().describe(`Additional execution behavior configuration`)}).describe(`Individual workflow action step with comprehensive validation for all supported action types`);const ProgEventSchema=z.object({id:UuidSchema.describe(`Unique UUID identifier for the event`),data:z.object({type:z.union([z.literal(`on_load`),z.literal(`on_exit`),z.literal(`before_record`),z.literal(`after_record`),z.literal(`record_not_found`),z.literal(`locate_not_found`),z.literal(`screen_ready`),z.literal(`client_interval`),z.literal(`user_defined`)]).describe(`Event type defining when the event triggers during ${type} lifecycle`),event_name:z.string().describe(`Reference name for the event`),properties:z.string().describe(`Additional event properties (usually empty)`),condition:z.string().describe(`Optional condition expression to determine when event should fire`),parameters:z.array(z.any()).describe(`Array of parameter mappings for the event`)}).describe(`Core event configuration defining trigger conditions and parameters`),props:z.object({propExpressions:z.object({}).optional().describe(`Property expressions for dynamic event behavior`)}).describe(`Additional event properties and expressions`),workflow:z.array(WorkflowActionSchema).optional().describe(`Array of workflow actions to execute when event triggers`)}).describe(`Component lifecycle event with associated triggers and workflow actions`);const UiAttributesSchema=z.record(z.union([z.string(),z.number(),z.boolean(),z.object({}),z.array(z.object({handler:z.string().describe(`Event handler type`),props:z.object({}).optional().describe(`Handler-specific properties`),workflow:z.array(WorkflowActionSchema).optional().describe(`Workflow actions to execute on event`)}))])).refine(attrs=>{const xuAttributes=Object.keys(attrs).filter(key=>key.startsWith(`xu-`));for(const attr of xuAttributes){const value=attrs[attr];if(attr===`xu-bind`&&typeof value!==`string`){return false}if(attr===`xu-render`&&typeof value!==`string`){return false}if(attr===`xu-show`&&typeof value!==`string`){return false}if(attr===`xu-for`&&typeof value!==`string`){return false}if([`xu-for-key`,`xu-for-val`].includes(attr)&&typeof value!==`string`){return false}if(attr.startsWith(`xu-on:`)&&!Array.isArray(value)){return false}if(attr===`xu-class`){if(typeof value!==`string`&&typeof value!==`object`){return false}}if(attr===`xu-store`){if(typeof value!==`string`&&typeof value!==`object`){return false}}if([`xu-text`,`xu-html`,`xu-content`,`xu-ref`].includes(attr)&&typeof value!==`string`){return false}if(attr.startsWith(`xu-exp:`)&&typeof value!==`string`){return false}if([`xu-style`,`xu-style-global`,`xu-script`,`xu-cdn`,`xu-ui-plugin`,`xu-viewport`].includes(attr)&&typeof value!==`string`){return false}}return true},{message:`Invalid Xuda attribute configuration`}).describe(`HTML attributes and Xuda-specific directives for UI elements. Supported Xuda attributes with examples:
1
+ var app_obj,progs_obj,_,progs_str,hide_not_in_use_check,is_server,deployments,UglifyJS,JSON5,_conf,warn_plugin_check,z;const PROTECTED_VARS=["_NULL","_THIS","_FOR_KEY","_FOR_VAL","_ROWNO","_ROWID","_ROWDOC","_KEY","_VAL"];const ALL_MENU_TYPE=["globals","component","ai_agent","batch","get_data","set_data","alert","javascript","api","table","folder"];const program_ref_triggers_arr=["call_page","call_modal","call_popover","get_data","set_data","batch","call_native_javascript","call_evaluate_javascript","call_alert","alter_ui_element","create_ui_element","update","raise_event"];export const init=function(app_obj_in,progs_obj_in={},_in,_hide_not_in_use_check,is_server_in,deployments_in=[],UglifyJS_in,JSON5_in,_conf_in,_warn_plugin_check,_z){app_obj=app_obj_in;progs_obj=progs_obj_in;progs_str=JSON.stringify(progs_obj);hide_not_in_use_check=_hide_not_in_use_check;_=_in;is_server=is_server_in;deployments=deployments_in;UglifyJS=UglifyJS_in;JSON5=JSON5_in;_conf=_conf_in;warn_plugin_check=_warn_plugin_check;z=_z};export const check=function(doc){var ret=[];var dependency_progs=[];const addValidationError=(code,data,type="E",category="document",ref=null,id=null,not_in_use=false)=>{const error={code:code,data:data,type:type,category:category};if(ref)error.ref=ref;if(id)error.id=id;if(not_in_use)error.not_in_use=not_in_use;ret.push(error)};if(_.isEmpty(doc)){addValidationError("CHK_MSG_OBJ_GEN_110","doc in empty");return{check_errors:ret,check_warnings:[],doc:doc,dependency_progs:[]}}let critical_error=false;ret=check_structure(doc,critical_error);if(!critical_error){doc.studio_meta.not_in_use=false;if(doc.properties.menuType!=="folder"){if(doc.properties.menuType!=="table"){if(is_server){for(let val of deployments){if(val.deploy_data?.prog_id===doc._id){if(!doc.studio_meta.used_by_deployment_ids){doc.studio_meta.used_by_deployment_ids=[]}doc.studio_meta.used_by_deployment_ids.push(val._id)}}}if(!doc.studio_meta.used_by_deployment_id){const check_programs_are_active=function(arr){if(!arr.length)return false;var count=0;for(let val of arr){if(progs_obj?.[val.prog_id]?.studio_meta?.not_in_use){count++;break}}return count!==arr.length};if(!hide_not_in_use_check){const ret_prog_in_use=find_trigger_property_value_in_progs(doc,program_ref_triggers_arr,"prog",doc._id);if(!ret_prog_in_use||!check_programs_are_active(ret_prog_in_use)){const ret_panel_prog_in_use=find_panel_prog_in_progs(doc,doc._id);if(!ret_panel_prog_in_use||!check_programs_are_active(ret_panel_prog_in_use)){const ret_fieldValue_in_use=find_prog_in_fieldset_fieldValue_progs(doc,doc._id);if(!ret_fieldValue_in_use||!check_programs_are_active(ret_fieldValue_in_use)){doc.studio_meta.not_in_use=true}}}}}ret=[...ret,...check_prog_events(doc)];dependency_progs=find_trigger_property_value_in_progs(doc,program_ref_triggers_arr,"prog",null,true)||[];dependency_progs=[...dependency_progs,...find_panel_prog_in_progs(doc,null,true)||[]]}else{if(!hide_not_in_use_check){if(!find_table_in_progs(doc,doc._id)){doc.studio_meta.not_in_use=true}}}}switch(doc.properties.menuType){case"globals":ret=[...ret,...check_globals(doc)];break;case"table":ret=[...ret,...check_table(doc)];break;case"component":ret=[...ret,...check_component(doc)];break;case"javascript":ret=[...ret,...check_javascript(doc)];break;case"get_data":ret=[...ret,...check_get_data(doc)];break;case"set_data":ret=[...ret,...check_set_data(doc)];break;case"batch":ret=[...ret,...check_batch(doc)];break;case"api":ret=[...ret,...check_api(doc)];break;case"alert":ret=[...ret,...check_alert(doc)];break;case"route":ret=[...ret,...check_route(doc)];break;case"ai_agent":ret=[...ret,...check_ai_agent(doc)];break;case"folder":break;default:addValidationError("CHK_MSG_GEN_050",`invalid ${doc.properties.menuType} properties.menuType`,"E","prog",doc._id,doc._id);break}}var final_ret={check_errors:[],check_warnings:[],doc:doc,dependency_progs:dependency_progs};for(let[key,val]of Object.entries(ret)){if(val.type==="E"){final_ret.check_errors.push(val)}if(val.type==="W"){final_ret.check_warnings.push(val)}}return final_ret};export const check_structure=function(doc,critical_error){var ret=[];const addValidationError=(code,data)=>{ret.push({code:code,data:data,type:"E",category:"document",structure_error:true})};if(!app_obj||!_.isObject(app_obj)||_.isEmpty(app_obj)){addValidationError("CHK_MSG_OBJ_GEN_002","invalid app_obj");critical_error=true;return ret}if(!doc||!_.isObject(doc)||_.isEmpty(doc)){addValidationError("CHK_MSG_OBJ_GEN_004","doc is not a object");critical_error=true;return ret}try{JSON5.parse(JSON.stringify(doc))}catch(err){addValidationError("CHK_MSG_OBJ_GEN_005","error parsing JSON doc");critical_error=true;return ret}if(!doc?.properties){critical_error=true;const msg=`doc.property object is undefined`;addValidationError("CHK_MSG_OBJ_GEN_000",msg);return ret}if(!doc?.studio_meta){critical_error=true;const msg=`doc.studio_meta object is undefined`;addValidationError("CHK_MSG_OBJ_GEN_000",msg);return ret}if(!doc?.properties?.menuType){critical_error=true;const msg=`doc.property.menuType is mandatory`;addValidationError("CHK_MSG_OBJ_GEN_000",msg);return ret}if(!doc?.properties?.menuName){critical_error=true;const msg=`doc.property.menuName is mandatory`;addValidationError("CHK_MSG_OBJ_GEN_000",msg);return ret}if(z){const schema=get_zod_schema(doc.properties.menuType);const result=schema.safeParse(doc);if(!result.success){result.error.errors.forEach(error=>{const msg=`${error.message}: ${error.path}(${error.expected})`;addValidationError("CHK_MSG_OBJ_GEN_000",msg)});critical_error=true;return ret}}if(!doc._id){addValidationError("CHK_MSG_OBJ_GEN_050","missing _id value")}if(doc?.studio_meta?.source==="studio ai"&&doc?.properties?.menuType&&doc._id&&doc._id.substr(0,7)!==new_node_id(doc.properties.menuType,doc.app_id).substr(0,7)){addValidationError("CHK_MSG_OBJ_GEN_051","invalid _id value (e.g: 5b1_tbl_a953848a71c5)")}if(!doc._rev){if(progs_obj?.[doc._id]){addValidationError("CHK_MSG_OBJ_GEN_052","duplicate doc _id")}}if(!doc.properties){addValidationError("CHK_MSG_OBJ_GEN_100","missing properties object")}else{if(!_.isObject(doc.properties)){addValidationError("CHK_MSG_OBJ_GEN_102","invalid properties object")}else{if(!doc.properties.menuType){addValidationError("CHK_MSG_OBJ_GEN_104","missing properties.menuType")}else if(!ALL_MENU_TYPE.includes(doc.properties.menuType)){addValidationError("CHK_MSG_OBJ_GEN_105",`invalid properties.menuType (valid values: ${ALL_MENU_TYPE.join(",")})`)}if(!doc.properties.menuName){addValidationError("CHK_MSG_OBJ_GEN_106","missing properties.menuName")}}}if(!doc.studio_meta){addValidationError("CHK_MSG_OBJ_GEN_112","missing studio_meta property")}else{if(!_.isObject(doc.studio_meta)){addValidationError("CHK_MSG_OBJ_GEN_112","invalid studio_meta object")}else{if(!doc.studio_meta.parentId){addValidationError("CHK_MSG_OBJ_GEN_114","missing studio_meta.parentId value")}else{let menuType=doc?.properties?.menuType==="globals"?"globals":doc?.properties?.menuType==="table"?"database":doc?.properties?.menuType==="route"?"routes":doc?.properties?.menuType==="ai_agent"?"ai_agents":"programs";if(doc.studio_meta.parentId!==menuType&&!progs_obj[doc.studio_meta.parentId]){addValidationError("CHK_MSG_OBJ_GEN_116","invalid studio_meta.parentId value")}}}}const check_progFields=function(){if(!doc.progFields)return;var ids=[];if(!_.isArray(doc.progFields)){addValidationError("CHK_MSG_OBJ_GEN_402","invalid progFields Array property");return}const validTypes=["virtual","table","expression","datasource"];const validFieldTypes=["string","number","boolean","array","object"];for(let val of doc.progFields){if(!_.isObject(val)){addValidationError("CHK_MSG_OBJ_GEN_404",`Invalid progFields object `);continue}if(!val.id){addValidationError("CHK_MSG_OBJ_GEN_406","Missing progFields ID property")}const fieldId=val.id?`(${val.id})`:"";if(val.id){if(ids.includes(val.id)){addValidationError("CHK_MSG_OBJ_GEN_408",`Duplicate progFields ID (${val.id})`);continue}ids.push(val.id)}if(!_.isObject(val.data)){addValidationError("CHK_MSG_OBJ_GEN_410",`Invalid progFields data object ${fieldId}`)}else{if(!val.data.field_id){addValidationError("CHK_MSG_OBJ_GEN_412",`Missing progFields field_id property ${fieldId}`)}if(!val.data.type){addValidationError("CHK_MSG_OBJ_GEN_414",`Missing progFields type property ${fieldId}`)}else if(!validTypes.includes(val.data.type)){addValidationError("CHK_MSG_OBJ_GEN_415",`Invalid progFields type "${val.data.type}" ${fieldId}. Must be one of: ${validTypes.join(", ")}`)}}if(!_.isObject(val.props)){addValidationError("CHK_MSG_OBJ_GEN_416",`Invalid progFields props object ${fieldId}`)}else{if(!val.props.fieldType){addValidationError("CHK_MSG_OBJ_GEN_418",`Missing progFields fieldType property ${fieldId}`)}else if(!validFieldTypes.includes(val.props.fieldType)){addValidationError("CHK_MSG_OBJ_GEN_419",`Invalid progFields fieldType "${val.props.fieldType}" ${fieldId}. Must be one of: ${validFieldTypes.join(", ")}`)}if(!_.isObject(val.props.propExpressions)){addValidationError("CHK_MSG_OBJ_GEN_4120",`Invalid progFields propExpressions object ${fieldId}`)}else{const allowedProps=["fieldValue","fieldType"];const actualProps=Object.keys(val.props.propExpressions);const invalidProps=actualProps.filter(prop=>!allowedProps.includes(prop));if(invalidProps.length>0){addValidationError("CHK_MSG_OBJ_GEN_4121",`Invalid propExpressions properties: ${invalidProps.join(", ")} ${fieldId}. Only allowed: ${allowedProps.join(", ")}`)}}}check_workflow(val.workflow)}};const check_progEvents=function(){if(!doc.progEvents)return;var ids=[];if(!_.isArray(doc.progEvents)){addValidationError("CHK_MSG_OBJ_GEN_502","invalid progEvents Array property");return}for(let val of doc.progEvents){if(!_.isObject(val)){addValidationError("CHK_MSG_OBJ_GEN_504","invalid progEvents object property");continue}if(!val.id){addValidationError("CHK_MSG_OBJ_GEN_506","missing progEvents.id property");continue}if(ids.includes(val.id)){addValidationError("CHK_MSG_OBJ_GEN_508",`${val.id} id must be unique in progEvents property`);continue}ids.push(val.id);if(!_.isObject(val.data)){addValidationError("CHK_MSG_OBJ_GEN_510","invalid progEvents.data object property");continue}if(typeof val.data.condition==="undefined"){addValidationError("CHK_MSG_OBJ_GEN_512","undefined progEvents.data.condition string property")}if(typeof val.data.event_name==="undefined"){addValidationError("CHK_MSG_OBJ_GEN_514","undefined progEvents.data.event_name string property")}if(typeof val.data.properties==="undefined"){addValidationError("CHK_MSG_OBJ_GEN_516","undefined progEvents.data.properties string property")}if(typeof val.data.type==="undefined"){addValidationError("CHK_MSG_OBJ_GEN_518","undefined progEvents.data.type string property")}if(!_.isArray(val.data.parameters)){addValidationError("CHK_MSG_OBJ_GEN_522","invalid progEvents.data.parameters Array property")}if(!_.isObject(val.props)){addValidationError("CHK_MSG_OBJ_GEN_522","invalid progEvents.props Object property")}check_workflow(val.workflow)}};const check_workflow=function(workflow){if(!workflow)return;var ids=[];if(!_.isArray(workflow)){addValidationError("CHK_MSG_OBJ_GEN_850","invalid workflow Array property");return}for(let val of workflow){if(!_.isObject(val)){addValidationError("CHK_MSG_OBJ_GEN_852","invalid workflow item object property");continue}if(!val.id){addValidationError("CHK_MSG_OBJ_GEN_854","missing workflow.id property");continue}if(ids.includes(val.id)){addValidationError("CHK_MSG_OBJ_GEN_856",`${val.id} id must be unique in workflow property`);continue}ids.push(val.id);if(!_.isObject(val.data)){addValidationError("CHK_MSG_OBJ_GEN_858","invalid workflow.data Object property")}if(!_.isObject(val.props)){addValidationError("CHK_MSG_OBJ_GEN_860","invalid workflow.props item object property")}}};const check_progDataSource=function(){if(!doc.progDataSource)return;if(!_.isObject(doc.progDataSource)){addValidationError("CHK_MSG_OBJ_GEN_602","invalid progDataSource Object property");return}if(typeof doc.progDataSource.dataSourceType==="undefined"){addValidationError("CHK_MSG_OBJ_GEN_604","undefined progDataSource.dataSourceType string property")}};const check_progUi=function(){if(!doc.progUi)return;if(!_.isArray(doc.progUi)){addValidationError("CHK_MSG_OBJ_GEN_702","invalid progUi Array property");return}var ids=[];const run_tree=function(node){for(let item of node){if(!_.isObject(item)){addValidationError("CHK_MSG_OBJ_GEN_704","invalid progUi item Object property");continue}if(!item.id&&item?.type!=="comment"){addValidationError("CHK_MSG_OBJ_GEN_712","missing progUi id item property")}if(item?.id){if(item?.type==="comment"){addValidationError("CHK_MSG_OBJ_GEN_705",`Comment type is not supported in progUi (${item.id})`);continue}if(item?.type==="text"){addValidationError("CHK_MSG_OBJ_GEN_706",`Text type is not supported in progUi (${item.id}). Convert to "element" type and add a "text" property instead`);continue}if(item?.attributes&&!_.isObject(item.attributes)){addValidationError("CHK_MSG_OBJ_GEN_707",`Invalid progUi attributes object property (${item.id})`)}if(typeof item.type==="undefined"){addValidationError("CHK_MSG_OBJ_GEN_708",`Missing progUi type property (${item.id})`)}if(typeof item.tagName==="undefined"){addValidationError("CHK_MSG_OBJ_GEN_710",`Missing progUi tagName property (${item.id})`)}if(item.id!=="root"&&doc?.studio_meta?.source==="studio ai"&&!detectCryptoString(item.id.replace("node-","").replace("ui-","")).uuid){addValidationError("CHK_MSG_OBJ_GEN_713",`ProgUi item ID must be in UUID format (${item.id})`)}if(ids.includes(item.id)){addValidationError("CHK_MSG_OBJ_GEN_714",`Duplicate progUi item ID found (${item.id})`);continue}ids.push(item.id)}check_workflow(item.workflow);if(item.children){run_tree(item.children)}}};run_tree(doc.progUi)};if(doc.properties&&doc.properties.menuType){switch(doc.properties.menuType){case"table":if(!doc.tableFields){addValidationError("CHK_MSG_OBJ_GEN_200","missing tableFields property")}else{if(!_.isArray(doc.tableFields)){addValidationError("CHK_MSG_OBJ_GEN_202","invalid tableFields Array property")}else{var ids=[];for(let val of doc.tableFields){if(!_.isObject(val)){addValidationError("CHK_MSG_OBJ_GEN_204","invalid tableFields object property");continue}if(!val.id){addValidationError("CHK_MSG_OBJ_GEN_206","missing tableFields.id property");continue}if(ids.includes(val.id)){addValidationError("CHK_MSG_OBJ_GEN_208",`${val.id} id must be unique in tableFields property`);continue}ids.push(val.id);if(!_.isObject(val.data)){addValidationError("CHK_MSG_OBJ_GEN_210","invalid tableFields.data object property");continue}if(!val.data.field_id){addValidationError("CHK_MSG_OBJ_GEN_212","invalid tableFields.data.field_id property")}if(!_.isObject(val.props)){addValidationError("CHK_MSG_OBJ_GEN_214","invalid tableFields.props object property");continue}if(!val.props.fieldType){addValidationError("CHK_MSG_OBJ_GEN_216","invalid tableFields.props.fieldType property")}}}}if(!doc.tableIndexes){addValidationError("CHK_MSG_OBJ_GEN_302","missing tableIndexes property")}else if(!_.isArray(doc.tableIndexes)){addValidationError("CHK_MSG_OBJ_GEN_302","invalid tableIndexes Array property")}else{var index_ids=[];for(let val of doc.tableIndexes){if(!_.isObject(val)){addValidationError("CHK_MSG_OBJ_GEN_304","invalid tableIndexes object property");continue}if(!val.id){addValidationError("CHK_MSG_OBJ_GEN_306","missing tableIndexes.id property");continue}if(index_ids.includes(val.id)){addValidationError("CHK_MSG_OBJ_GEN_308",`${val.id} id must be unique in tableIndexes property`);continue}index_ids.push(val.id);if(!_.isObject(val.data)){addValidationError("CHK_MSG_OBJ_GEN_310","invalid tableIndexes.data object property");continue}if(!val.data.name){addValidationError("CHK_MSG_OBJ_GEN_312","invalid tableIndexes.data.name property")}if(!_.isArray(val.data.keys)){addValidationError("CHK_MSG_OBJ_GEN_312","invalid tableIndexes.data.keys Array property")}}}break;case"globals":check_progFields();check_progEvents();break;case"get_data":case"set_data":case"batch":case"api":check_progFields();check_progEvents();check_progDataSource();break;case"component":check_progFields();check_progEvents();check_progDataSource();check_progUi();if(doc.properties&&typeof doc.properties.uiFramework==="undefined"){addValidationError("CHK_MSG_OBJ_GEN_120","undefined properties.uiFramework string property")}if(doc.properties&&typeof doc.properties.renderType==="undefined"){addValidationError("CHK_MSG_OBJ_GEN_122","undefined properties.renderType string property")}break;case"alert":break;case"javascript":break;case"folder":break;default:break}}return ret};const check_table=function(doc){var ret=[];if(!doc.properties.databaseSocket){ret.push({code:"CHK_MSG_TBL_GEN_010",data:"database socket not defined",type:doc.studio_meta.not_in_use?"W":"E",category:`table`,ref:doc._id,id:doc._id})}else{if(!app_obj?.app_plugins_purchased?.[doc.properties.databaseSocket]){ret.push({code:"CHK_MSG_TBL_GEN_0020",data:`invalid ${doc.properties.databaseSocket} database socket`,type:doc.studio_meta.not_in_use||warn_plugin_check?"W":"E",category:`table`,ref:doc._id,id:doc._id})}else{if(!app_obj.app_plugins_purchased[doc.properties.databaseSocket].installed){ret.push({code:"CHK_MSG_TBL_GEN_030",data:`${doc.properties.databaseSocket} database socket not installed`,type:doc.studio_meta.not_in_use?"W":"E",category:`table`,ref:doc._id,id:doc._id})}}}if(doc.tableIndexes?.length&&!doc?.tableFields?.length){ret.push({code:"CHK_MSG_TBL_FLD_090",data:`table has no fields`,type:doc.studio_meta.not_in_use?"W":"E",category:`table`,ref:doc._id,id:doc._id})}var name_counts_obj={};for(let field of doc.tableFields){if(!field?.data?.field_id){ret.push({code:"CHK_MSG_TBL_FLD_100",data:`missing field_id`,type:doc.studio_meta.not_in_use?"W":"E",category:`table`,ref:field.id,id:`${doc._id}-${field.id}`})}else{if(!/^[A-Za-z]+[\w\-\:\.]*$/.test(field.data.field_id)){ret.push({code:"CHK_MSG_TBL_FLD_020",data:`invalid field_id`,type:doc.studio_meta.not_in_use?"W":"E",category:`table`,ref:field.id,id:`${doc._id}-${field.id}`})}if(!name_counts_obj[field.data.field_id]){name_counts_obj[field.data.field_id]=1}else{name_counts_obj[field.data.field_id]++}if(!hide_not_in_use_check){if(!find_field_in_progs(doc,field.data.field_id)){ret.push({code:"CHK_MSG_TBL_FLD_022",data:`table field "${field.data.field_id}" not in use`,type:"W",category:`table`,ref:doc._id,not_in_use:true,id:`${doc._id}-${field.id}`})}}}}for(let[key,val]of Object.entries(name_counts_obj)){if(val>1){ret.push({code:"CHK_MSG_TBL_FLD_200",data:`duplicate field id for ${key}`,type:doc.studio_meta.not_in_use?"W":"E",id:`${doc._id}-${key}`})}}if(!doc.tableIndexes?.length){if(doc.properties.databaseSocket!=="@xuda.io/xuda-dbs-plugin-xuda"){ret.push({code:"CHK_MSG_TBL_IDX_040",data:`at least one index has to be defined`,type:doc.studio_meta.not_in_use?"W":"E",id:`${doc._id}`})}}else{let found_unique;for(let index of doc.tableIndexes){if(index?.data?.unique){found_unique=true}if(!index?.data?.name){ret.push({code:"CHK_MSG_TBL_IDX_060",data:`tableIndexes.data.name cannot be empty in "${index.id}" index`,type:doc.studio_meta.not_in_use?"W":"E",id:`${doc._id}`})}if(!index?.data?.keys?.length){ret.push({code:"CHK_MSG_TBL_IDX_070",data:`tableIndexes.data.keys cannot be empty in "${index.id}" index`,type:doc.studio_meta.not_in_use?"W":"E",id:`${doc._id}-${index.id}`})}else{for(let key of index.data.keys){if(!doc.tableFields||!_.isArray(doc.tableFields)||!find_item_by_key(doc.tableFields,"field_id",key)){ret.push({code:"CHK_MSG_TBL_IDX_080",data:`invalid key ${key} in tableIndexes.data.keys for "${index.id}" index`,type:doc.studio_meta.not_in_use?"W":"E",id:`${doc._id}-${index.id}-${key}`})}}}}}if(!doc?.tableFields?.length){ret.push({code:"CHK_MSG_TBL_FLD_012",data:`table has no fields`,type:"W",id:`${doc._id}`})}for(let field of doc.tableFields){if(!["string","number","boolean","object","array","date"].includes(field?.props?.fieldType)){ret.push({code:"CHK_MSG_TBL_FLD_022",data:`invalid fieldType for field ${field?.data?.field_id}`,type:"E",id:`${doc._id}-${field.id}`})}}return ret};const check_globals=function(doc){var ret=[];ret=[...ret,...check_prog_fieldset(doc)];return ret};const check_component=function(doc){var ret=[];if(!doc.properties.uiFramework){ret.push({code:"CHK_MSG_PRG_COM_010",data:"component Ui Framework not defined",type:doc.studio_meta.not_in_use?"W":"E",category:`component`,ref:doc._id,id:`${doc._id}`})}else{if(!app_obj?.app_plugins_purchased?.[doc.properties.uiFramework]){ret.push({code:"CHK_MSG_PRG_COM_020",data:`invalid ${doc.properties.uiFramework} Ui Framework`,type:doc.studio_meta.not_in_use?"W":"E",category:`component`,ref:doc._id,id:`${doc._id}`})}else{if(!app_obj.app_plugins_purchased[doc.properties.uiFramework].installed){ret.push({code:"CHK_MSG_PRG_COM_030",data:`${doc.properties.uiFramework} Ui Framework not installed`,type:doc.studio_meta.not_in_use?"W":"E",category:`component`,ref:doc._id,id:`${doc._id}`})}}}ret=[...ret,...check_prog_fieldset(doc)];ret=[...ret,...check_prog_parameters(doc)];ret=[...ret,...check_prog_datasource(doc)];if(doc.progUi){var xu_tree_id_counts_obj={};const run_tree=function(node){for(let item of node){if(item.xu_tree_id){if(!xu_tree_id_counts_obj[item.xu_tree_id]){xu_tree_id_counts_obj[item.xu_tree_id]=1}else{xu_tree_id_counts_obj[item.xu_tree_id]++}}if(item.attributes){var name_counts_obj={};for(let[key,val]of Object.entries(item.attributes)){if(!key){ret.push({code:"CHK_MSG_PRG_GUI_010",data:`missing attribute in tree_id ${item.id}`,type:doc.studio_meta.not_in_use?"W":"E",category:`component_ui`,ref:item.id,id:`${doc._id}-${item.id}-${key}`})}else{if(key.substr(0,6)==="xu-exp"){ret=[...ret,...check_prog_expression(doc,val,item.id,"ui_attribute")]}else{if(!/^[A-Za-z]+[\w\-\:\.]*$/.test(key)){ret.push({code:"CHK_MSG_PRG_GUI_020",data:`invalid attribute "${key}" in tag "${item.tagName}" "${item.id}"`,type:doc.studio_meta.not_in_use?"W":"E",category:`component_ui`,ref:item.id,id:`${doc._id}-${item.id}-${key}`})}}if(key.substr(0,6)==="xu-on:"){if(!_.isEmpty(val)){for(let trigger_item of val){ret=[...ret,...check_prog_triggers(doc,trigger_item.workflow,"ui_trigger",item.id,item.attributes.tree_id)]}}}if(!name_counts_obj[key]){name_counts_obj[key]=1}else{name_counts_obj[key]++}}}for(let[key,val]of Object.entries(name_counts_obj)){if(val>1){ret.push({code:"CHK_MSG_PRG_GUI_200",data:`duplicate attribute id for ${key} in tree_id ${item.attribute.tree_id}`,type:doc.studio_meta.not_in_use?"W":"E",category:`component_ui`,ref:doc._id,id:`${doc._id}-${item.id}-${key}`})}}}if(item.children){run_tree(item.children)}}};run_tree(doc.progUi);for(let[key,val]of Object.entries(xu_tree_id_counts_obj)){if(val>1){ret.push({code:"CHK_MSG_PRG_GUI_250",data:`duplicate tree_id "${key}"`,type:"W",category:`component_ui`,ref:doc._id,id:`${doc._id}-${key}`})}}}return ret};const check_get_data=function(doc){var ret=[];ret=[...ret,...check_prog_fieldset(doc)];ret=[...ret,...check_prog_parameters(doc)];ret=[...ret,...check_prog_datasource(doc)];return ret};const check_batch=function(doc){var ret=[];ret=[...ret,...check_prog_fieldset(doc)];ret=[...ret,...check_prog_parameters(doc)];ret=[...ret,...check_prog_datasource(doc)];return ret};const check_api=function(doc){var ret=[];ret=[...ret,...check_prog_fieldset(doc)];ret=[...ret,...check_prog_parameters(doc)];ret=[...ret,...check_prog_datasource(doc)];return ret};const check_set_data=function(doc){var ret=[];ret=[...ret,...check_prog_fieldset(doc)];ret=[...ret,...check_prog_parameters(doc)];ret=[...ret,...check_prog_datasource(doc)];return ret};const check_alert=function(doc){var ret=[];if(_.isEmpty(doc.alertData)){ret.push({code:"CHK_MSG_PRG_ART_010",data:`no alert properties defined`,type:doc.studio_meta.not_in_use?"W":"E",category:`alert`,ref:doc._id,id:`${doc._id}`})}else{if(!doc.alertData.alertType){ret.push({code:"CHK_MSG_PRG_ART_020",data:`missing alert type property`,type:doc.studio_meta.not_in_use?"W":"E",category:`alert`,ref:doc._id,id:`${doc._id}`})}if(!doc.alertData.alertDisplay){ret.push({code:"CHK_MSG_PRG_ART_030",data:`missing alert display property`,type:doc.studio_meta.not_in_use?"W":"E",category:`alert`,ref:doc._id,id:`${doc._id}`})}if(!doc.alertData.alertTitle&&!doc.alertData.alertTitleFx&&!doc.alertData.alertBody&&!doc.alertData.alertBodyFx){ret.push({code:"CHK_MSG_PRG_ART_032",data:`missing alert title and body value`,type:"W",category:`alert`,ref:doc._id,id:`${doc._id}`})}}return ret};const check_route=function(doc){var ret=[];if(_.isEmpty(doc?.routeMenu?.menu)){ret.push({code:"CHK_MSG_RTE_MNU_010",data:`no route properties defined`,type:doc.studio_meta.not_in_use?"W":"E",category:`alert`,ref:doc._id,id:`${doc._id}`})}else{function checkMenuItems(menu){let flatMenu={};function recurse(items){for(let item of items){if(!item.prog_id){ret.push({code:"CHK_MSG_RTE_MNU_020",data:`no program to call has been defined`,type:doc.studio_meta.not_in_use?"W":"E",category:`alert`,ref:item.id,id:`${doc._id}`});continue}if(!progs_obj?.[item.prog_id]){ret.push({code:"CHK_MSG_RTE_MNU_030",data:`program ${item.prog_id} not exist`,type:doc.studio_meta.not_in_use?"W":"E",category:`alert`,ref:item.id,id:`${doc._id}`});continue}if(item.children&&item.children.length>0){recurse(item.children)}}}recurse(menu);return flatMenu}checkMenuItems(doc.routeMenu.menu)}return ret};const check_ai_agent=function(doc){var ret=[];return ret};const check_prog_fieldset=function(doc){var ret=[];if(!doc.progFields||_.isEmpty(doc.progFields)){if(doc.progDataSource.dataSourceTableId){ret.push({code:"CHK_MSG_PRG_FLD_012",data:`datasource table defined but fieldset is empty`,type:"W",category:"fieldset",id:`${doc._id}`})}}else{var name_counts_obj={};for(let field of doc.progFields){if(!field?.data?.field_id){ret.push({code:"CHK_MSG_PRG_FLD_010",data:`missing field_id`,type:doc.studio_meta.not_in_use?"W":"E",category:"fieldset",ref:field.id,id:`${doc._id}-${field.id}`})}else{if(!/^[A-Za-z]+[\w\-\:\.]*$/.test(field.data.field_id)&&!PROTECTED_VARS.includes(field.data.field_id)){ret.push({code:"CHK_MSG_PRG_FLD_020",data:`invalid ${field.data.field_id} field_id`,type:doc.studio_meta.not_in_use?"W":"E",category:"fieldset",ref:field.id,id:`${doc._id}-${field.id}`})}if(!name_counts_obj[field.data.field_id]){name_counts_obj[field.data.field_id]=1}else{name_counts_obj[field.data.field_id]++}if(!hide_not_in_use_check){if(!find_field_in_progs(doc,field.data.field_id)){var found_parameter_out_match;if(!_.isEmpty(doc.properties.progParams)){for(let parameter_item of doc.properties.progParams){if(parameter_item.data.dir==="out"&&parameter_item.data.parameter===field.data.field_id){found_parameter_out_match=true;break}}}if(!found_parameter_out_match){ret.push({code:"CHK_MSG_PRG_FLD_022",data:`field "${field.data.field_id}" not in use`,type:"W",category:"fieldset",ref:field.id,not_in_use:true,id:`${doc._id}-${field.id}`})}}}}if(!field?.data?.type){ret.push({code:"CHK_MSG_PRG_FLD_030",data:`missing field type`,type:doc.studio_meta.not_in_use?"W":"E",category:"fieldset",ref:field.id,id:`${doc._id}-${field.id}`});return ret}else{switch(field.data.type){case"virtual":break;case"exp":if(!field?.props?.fieldValue||!field?.props?.propExpressions?.fieldValue){ret.push({code:"CHK_MSG_PRG_FLD_070",data:`invalid value or value expression for ${field.data.field_id} field type Exp`,type:doc.studio_meta.not_in_use?"W":"E",category:"fieldset",ref:field.id,id:`${doc._id}-${field.id}`})}break;case"table":if(doc.properties.menuType==="globals"){ret.push({code:"CHK_MSG_PRG_FLD_040",data:`invalid field type for ${field.data.field_id} in globals`,type:doc.studio_meta.not_in_use?"W":"E",category:"fieldset",ref:field.id,id:`${doc._id}-${field.id}`})}else{if(!doc.progDataSource||_.isEmpty(doc.progDataSource)||!doc.progDataSource.dataSourceType||doc.progDataSource.dataSourceType==="none"){ret.push({code:"CHK_MSG_PRG_FLD_300",data:`undefined datasource for ${field.data.field_id} field`,type:doc.studio_meta.not_in_use?"W":"E",category:"fieldset",ref:field.id,id:`${doc._id}-${field.id}`});return ret}else{var ret_dsc=check_prog_datasource(doc);if(ret_dsc.length)return ret;var _datasource_table_arr=progs_obj?.[doc.progDataSource.dataSourceTableId]?.tableFields;if(!_datasource_table_arr){ret.push({code:"CHK_MSG_PRG_FLD_310",data:`no fields found in datasource table ${doc.progDataSource.dataSourceTableId} `,type:doc.studio_meta.not_in_use?"W":"E",category:"fieldset",ref:field.id,id:`${doc._id}-${field.id}`});return ret}if(!find_item_by_key(_datasource_table_arr,"field_id",field.data.field_id)){if(!doc.progDataSource.dataSourceReduce||field.data.field_id!=="REDUCE_VALUE"){ret.push({code:"CHK_MSG_PRG_FLD_320",data:`invalid field ${field.data.field_id} in datasource table`,type:doc.studio_meta.not_in_use?"W":"E",category:"fieldset",ref:field.id,id:`${doc._id}-${field.id}`});return ret}}}}break;default:ret.push({code:"CHK_MSG_PRG_FLD_060",data:`invalid field type for ${field.data.field_id}`,type:doc.studio_meta.not_in_use?"W":"E",category:"fieldset",ref:field.id,id:`${doc._id}-${field.id}`});return ret;break}}if(!field?.props?.fieldType&&!field?.props?.propExpressions?.fieldType){ret.push({code:"CHK_MSG_PRG_FLD_130",data:`missing field fieldType`,type:doc.studio_meta.not_in_use?"W":"E",category:"fieldset",ref:field.id,id:`${doc._id}-${field.id}`});return ret}else if(field.props.fieldType){switch(field.props.fieldType){case"string":if(field?.props?.fieldValue&&typeof field.props.fieldValue!=="string"){ret.push({code:"CHK_MSG_PRG_FLD_200",data:`invalid value type ${field.props.fieldType} for ${field.data.field_id} field`,type:doc.studio_meta.not_in_use?"W":"E",category:"fieldset",ref:field.id,id:`${doc._id}-${field.id}`})}break;case"number":case"boolean":if(field?.props?.fieldValue){if(_.isNaN(_.toNumber(field?.props?.fieldValue))){ret.push({code:"CHK_MSG_PRG_FLD_210",data:`invalid value type ${field.props.fieldType} for ${field.data.field_id} field`,type:"E",category:"fieldset",ref:field.id,id:`${doc._id}-${field.id}`})}}break;case"object":case"array":if(field?.props?.fieldValue){try{JSON5.parse(field.props.fieldValue)}catch(err){ret.push({code:"CHK_MSG_PRG_FLD_220",data:`invalid value type "${field.props.fieldType}" for "${field.data.field_id}" field`,type:doc.studio_meta.not_in_use?"W":"E",category:"fieldset",ref:field.id,id:`${doc._id}-${field.id}`})}}break;default:ret.push({code:"CHK_MSG_PRG_FLD_160",data:`invalid field fieldType for ${field.data.field_id}`,type:doc.studio_meta.not_in_use?"W":"E",category:"fieldset",ref:field.id,id:`${doc._id}-${field.id}`});return ret;break}}if(!_.isEmpty(field.workflow)){ret=[...ret,...check_prog_triggers(doc,field.workflow,"field",field.id,field.data.field_id)]}}for(let[key,val]of Object.entries(name_counts_obj)){if(val>1){ret.push({code:"CHK_MSG_PRG_FLD_200",data:`duplicate field id for ${key}`,type:doc.studio_meta.not_in_use?"W":"E",category:"fieldset",id:`${doc._id}-${key}`})}}}return ret};const check_prog_events=function(doc){var ret=[];if(!doc.progEvents||_.isEmpty(doc.progEvents))return ret;var name_counts_obj={};for(let event_item of doc.progEvents){switch(event_item?.data?.type){case"user_defined":if(!event_item.data.event_name){ret.push({code:"CHK_MSG_PRG_EVT_010",data:`missing event name for ${event_item.id}`,type:"W",category:"event",ref:event_item.id,id:`${doc._id}-${event_item.id}`});continue}else{if(!/^[A-Za-z]+[\w\-\:\.]*$/.test(event_item.data.event_name)){ret.push({code:"CHK_MSG_PRG_EVT_020",data:`invalid event name for event "${event_item.data.event_name||event_item.data.type}"`,type:doc.studio_meta.not_in_use?"W":"E",category:"event",ref:event_item.id,id:`${doc._id}-${event_item.id}`})}if(!hide_not_in_use_check){const ret_event_id_use=find_trigger_property_value_in_progs(doc,["raise_event"],"event",event_item.data.event_name);if(!ret_event_id_use?.length){ret.push({code:"CHK_MSG_PRG_EVT_112",data:`event "${event_item.data.event_name}" not in use`,type:"W",category:"event",ref:event_item.id,not_in_use:true,id:`${doc._id}-${event_item.id}`})}}}if(event_item.data.condition){ret=[...ret,...check_prog_expression(doc,event_item.data.condition,event_item.id,"condition")]}else{if(!name_counts_obj[event_item.id]){name_counts_obj[event_item.id]=1}else{name_counts_obj[event_item.id]++}}break;case"screen_ready":case"client_interval":if(doc.properties.menuType!=="component"){ret.push({code:"CHK_MSG_PRG_EVT_030",data:`event type "${event_item.data.type}" only allowed for "${doc.properties.menuType}" in event "${event_item.data.event_name||event_item.data.type}"`,type:doc.studio_meta.not_in_use?"W":"E",category:"event",ref:event_item.id,id:`${doc._id}-${event_item.id}`})}if(event_item.data.type==="client_interval"&&!event_item.data.properties){ret.push({code:"CHK_MSG_PRG_EVT_035",data:`empty interval property in event "${event_item.data.event_name||event_item.data.type}"`,type:doc.studio_meta.not_in_use?"W":"E",category:"event",ref:event_item.id,id:`${doc._id}-${event_item.id}`})}break;case"on_load":case"on_exit":case"before_record":case"after_record":case"record_not_found":case"locate_not_found":break;default:ret.push({code:"CHK_MSG_PRG_EVT_018",data:`invalid event type for ${event_item.id}`,type:doc.studio_meta.not_in_use?"W":"E",category:"event",ref:event_item.id,id:`${doc._id}-${event_item.id}`});break}if(!_.isEmpty(event_item.workflow)){ret=[...ret,...check_prog_triggers(doc,event_item.workflow,"event",event_item.id,event_item.data.event_name||event_item.data.type)]}else{ret.push({code:"CHK_MSG_PRG_EVT_022",data:`event "${event_item.data.event_name||event_item.data.type}" is empty`,type:"W",category:"event",ref:event_item.id,id:`${doc._id}-${event_item.id}`})}}for(let[key,val]of Object.entries(name_counts_obj)){if(val>1){ret.push({code:"CHK_MSG_PRG_EVT_102",data:`duplicate "${key}" event `,type:"W",category:"event",id:`${doc._id}-${event_item.id}-${key}`})}}return ret};const check_prog_triggers=function(doc,workflow,source_type,source_id,source_name){var ret=[];if(!workflow||_.isEmpty(workflow))return ret;const check_target_program_parameters=function(trigger_item){if(!trigger_item.data.name.prog)return;const target_program_parameters_arr=progs_obj?.[trigger_item.data.name.prog]?.properties?.progParams||[];if(trigger_item?.data?.name?.parameters&&!_.isEmpty(trigger_item.data.name.parameters)){for(let[key,val]of Object.entries(trigger_item.data.name.parameters)){const param_ret=find_item_by_key(target_program_parameters_arr,"parameter",key);if(_.isEmpty(param_ret)){ret.push({code:"CHK_MSG_PRG_TRG_370",data:`parameter "${key}" not found in the target program "${progs_obj?.[trigger_item.data.name.prog].properties.menuName}" parameter list in ${source_type} "${source_name}" trigger`,type:"W",category:`${source_type}_trigger`,ref:trigger_item.id,source_id:source_id,id:`${doc._id}-${source_id}-${trigger_item.id}-${key}`});return}if(param_ret.data.dir!=="in"&&val.value){const ret_local_field=find_item_by_key(doc.progFields,"field_id",val.value);if(!ret_local_field){let ret_parent_field;const check_parent_program=function(prog_id){let parent_prog_id=progs_obj?.[prog_id]?.studio_meta?.parentId;if(parent_prog_id&&progs_obj?.[parent_prog_id]){ret_parent_field=find_item_by_key(progs_obj?.[parent_prog_id]?.progFields||[],"field_id",val.value);if(!ret_parent_field){return check_parent_program(parent_prog_id)}}};check_parent_program(doc._id);if(!ret_parent_field){const ret_global_field=find_item_by_key(progs_obj?.[`global_${app_obj._id}`]?.progFields||[],"field_id",val.value);if(!ret_global_field){ret.push({code:"CHK_MSG_PRG_TRG_372",data:`"${val.value}" parameter "Out" not found in the program Dataset in ${source_type} "${source_name}" trigger`,type:"W",category:`${source_type}_trigger`,ref:trigger_item.id,source_id:source_id,id:`${doc._id}-${source_id}-${trigger_item.id}-${key}`})}}}}}}else{if(target_program_parameters_arr.length){ret.push({code:"CHK_MSG_PRG_TRG_374",data:`found parameters in "${progs_obj?.[trigger_item.data.name.prog].properties.menuName}" but empty parameter to exchange in ${source_type} "${source_name}" trigger`,type:"W",category:`${source_type}_trigger`,ref:trigger_item.id,source_id:source_id,id:`${doc._id}-${source_id}-${trigger_item.id}`})}}};for(let trigger_item of workflow){const get_prog_id=function(){let _prop=trigger_item.data?.name?.properties;let _prog_id=trigger_item.data.name.prog_id||_prop?.["xu-exp:prog"];return _prog_id};const err_type=doc.studio_meta.not_in_use?"W":trigger_item.data.enabled?"E":"W";switch(trigger_item?.data?.action){case"comment":break;case"update":if(!trigger_item?.data?.name?.value){ret.push({code:"CHK_MSG_PRG_TRG_020",data:`no value to update in ${source_type} "${source_name}" trigger`,type:err_type,category:`${source_type}_trigger`,ref:trigger_item.id,source_id:source_id,id:`${doc._id}-${source_id}-${trigger_item.id}`})}else{const validate_update_function=function(exp){var viewFields=[];try{var json=JSON5.parse(exp.replace(/\n/gi,""));for(const[key,val]of Object.entries(json)){let id=key.substr(1,key.length-1);viewFields.push({val:val,id:id})}return viewFields}catch(e){if(!exp){return}if(exp.substr(exp.length-1,1)===";")exp=exp.substr(0,exp.length-1);var exp_arr=exp.split(/;\s*(?=(?:[^"]|"[^"]*")*$)/g);if(exp_arr?.length){for(let val of exp_arr){var pos=val.indexOf(":");var seg=[val.substring(0,pos),val.substring(pos+1)];if(seg&&seg.length===2){let id=seg[0].substr(1,seg[0].length);viewFields.push({id:id,val:seg[1]})}else{ret.push({code:"CHK_MSG_PRG_TRG_040",data:`invalid json; too many segments in${source_type} "${source_name}" trigger`,type:err_type,category:`${source_type}_trigger`,ref:trigger_item.id,source_id:source_id,id:`${doc._id}-${source_id}-${trigger_item.id}`})}}}return viewFields}};const ret_update_fields_arr=validate_update_function(trigger_item.data.name.value);if(!ret_update_fields_arr.length){ret.push({code:"CHK_MSG_PRG_TRG_050",data:`no fields to update in ${source_type} "${source_name}" trigger`,type:err_type,category:`${source_type}_trigger`,ref:trigger_item.id,source_id:source_id,id:`${doc._id}-${source_id}-${trigger_item.id}`})}else{for(let val of ret_update_fields_arr){const ret_fields=find_field_in_progs(doc,val.id);if(!ret_fields){ret.push({code:"CHK_MSG_PRG_TRG_060",data:`field "${val.id}" not found in the project programs for update in ${source_type} "${source_name}" trigger`,type:err_type,category:`${source_type}_trigger`,ref:trigger_item.id,source_id:source_id,id:`${doc._id}-${source_id}-${trigger_item.id}`})}}}}break;case"raise_event":if(!trigger_item?.data?.name?.event&&!trigger_item?.data?.name?.properties["xu-exp:event"]){ret.push({code:"CHK_MSG_PRG_TRG_100",data:`invalid event name for "${trigger_item.data.action}" in ${source_type} "${source_name}" trigger`,type:err_type,category:`${source_type}_trigger`,ref:trigger_item.id,source_id:source_id,id:`${doc._id}-${source_id}-${trigger_item.id}`})}else if(trigger_item?.data?.name?.event){if(!/^[A-Za-z]+[\w\-\:\.]*$/.test(trigger_item.data.name.event)){ret.push({code:"CHK_MSG_PRG_TRG_110",data:`invalid event name ${trigger_item.data.name.event} in ${source_type} "${source_name}" trigger`,type:err_type,category:`${source_type}_trigger`,ref:trigger_item.id,source_id:source_id,id:`${doc._id}-${source_id}-${trigger_item.id}`})}else{const ret_event_name=find_event_id_in_progs(doc,trigger_item.data.name.event);if(!ret_event_name.length){ret.push({code:"CHK_MSG_PRG_TRG_120",data:`call performed to non exist event name called from "${trigger_item.data.name.event}" in ${source_type} "${source_name}" trigger`,type:err_type,category:`${source_type}_trigger`,ref:trigger_item.id,source_id:source_id,id:`${doc._id}-${source_id}-${trigger_item.id}`})}else{if(ret_event_name.length===1&&!_.isEmpty(trigger_item.data.name.parameters)){for(let[key,val]of Object.entries(trigger_item.data.name.parameters)){if(_.isEmpty(progs_obj?.[ret_event_name[0].prog_id].progFields)){if(!find_item_by_key(progs_obj?.[ret_event_name[0].prog_id].progFields,"field_id",key)){ret.push({code:"CHK_MSG_PRG_TRG_130",data:`parameter "${key}" not exist in the dataset of the target program called from event name "${trigger_item.data.name.event}" in ${source_type} "${source_name}" trigger`,type:"W",category:`${source_type}_trigger`,ref:trigger_item.id,source_id:source_id,id:`${doc._id}-${source_id}-${trigger_item.id}-${key}`})}}}}}}}break;case"call_page":case"call_modal":case"call_popover":if(!trigger_item.data.name.prog){if(!trigger_item.data?.name?.properties?.["xu-exp:prog"]){ret.push({code:"CHK_MSG_PRG_TRG_310",data:`empty program to call in ${source_type} "${source_name}" trigger`,type:err_type,category:`${source_type}_trigger`,ref:trigger_item.id,source_id:source_id,id:`${doc._id}-${source_id}-${trigger_item.id}`})}}else{if(!progs_obj?.[trigger_item.data.name.prog]){ret.push({code:"CHK_MSG_PRG_TRG_320",data:`invalid program to call in ${source_type} "${source_name}" trigger`,type:err_type,category:`${source_type}_trigger`,ref:trigger_item.id,source_id:source_id,id:`${doc._id}-${source_id}-${trigger_item.id}`})}else{if(progs_obj?.[trigger_item.data.name.prog].properties.menuType!=="component"){ret.push({code:"CHK_MSG_PRG_TRG_334",data:`invalid program type "${trigger_item.data.action}" to call in ${source_type} "${source_name}" trigger`,type:err_type,category:`${source_type}_trigger`,ref:trigger_item.id,source_id:source_id,id:`${doc._id}-${source_id}-${trigger_item.id}`})}else{check_target_program_parameters(trigger_item)}}}break;case"call_project_api":if(!trigger_item.data.name.prog){if(!trigger_item.data?.name?.properties?.["xu-exp:prog"]){ret.push({code:"CHK_MSG_PRG_TRG_310",data:`empty program to call in ${source_type} "${source_name}" trigger`,type:err_type,category:`${source_type}_trigger`,ref:trigger_item.id,source_id:source_id,id:`${doc._id}-${source_id}-${trigger_item.id}`})}}else{if(!progs_obj?.[trigger_item.data.name.prog]){ret.push({code:"CHK_MSG_PRG_TRG_320",data:`invalid program to call in ${source_type} "${source_name}" trigger`,type:err_type,category:`${source_type}_trigger`,ref:trigger_item.id,source_id:source_id,id:`${doc._id}-${source_id}-${trigger_item.id}`})}else{if(progs_obj?.[trigger_item.data.name.prog].properties.menuType!=="api"){ret.push({code:"CHK_MSG_PRG_TRG_334",data:`invalid program type "${trigger_item.data.action}" to call in ${source_type} "${source_name}" trigger`,type:err_type,category:`${source_type}_trigger`,ref:trigger_item.id,source_id:source_id,id:`${doc._id}-${source_id}-${trigger_item.id}`})}else{check_target_program_parameters(trigger_item)}}}break;case"call_system_api":{const _api_method=trigger_item.data.name.api_method;if(!_api_method){ret.push({code:"CHK_MSG_PRG_TRG_380",data:`api_method not defined in ${source_type} "${source_name}" trigger`,type:err_type,category:`${source_type}_trigger`,ref:trigger_item.id,source_id:source_id,id:`${doc._id}-${source_id}-${trigger_item.id}`})}else{if(typeof _conf!=="undefined"){if(!_conf.cpi_methods[_api_method]){ret.push({code:"CHK_MSG_PRG_TRG_382",data:`api method ${_api_method} unrecognized in ${source_type} "${source_name}" trigger`,type:err_type,category:`${source_type}_trigger`,ref:trigger_item.id,source_id:source_id,id:`${doc._id}-${source_id}-${trigger_item.id}`})}else{if(_conf.cpi_methods[_api_method].private){return ret.push({code:"CHK_MSG_PRG_TRG_384",data:`api method ${_api_method} is private in ${source_type} "${source_name}" trigger`,type:err_type,category:`${source_type}_trigger`,ref:trigger_item.id,source_id:source_id,id:`${doc._id}-${source_id}-${trigger_item.id}`})}if(_conf.cpi_methods[_api_method].fields){for(let[key,val]of Object.entries(_conf.cpi_methods[_api_method].fields)){if(val.mandatory&&!trigger_item.data.name?.payload?.[key]){ret.push({code:"CHK_MSG_PRG_TRG_386",data:`field ${key} for api method ${_api_method} is mandatory field in ${source_type} "${source_name}" trigger`,type:err_type,category:`${source_type}_trigger`,ref:trigger_item.id,source_id:source_id,id:`${doc._id}-${source_id}-${trigger_item.id}`})}}}}}}break}case"call_external_api":{if(!trigger_item.data.name.method){ret.push({code:"CHK_MSG_PRG_TRG_388",data:`method not defined in ${source_type} "${source_name}" trigger`,type:err_type,category:`${source_type}_trigger`,ref:trigger_item.id,source_id:source_id,id:`${doc._id}-${source_id}-${trigger_item.id}`})}if(!trigger_item.data.name.url){ret.push({code:"CHK_MSG_PRG_TRG_389",data:`url not defined in ${source_type} "${source_name}" trigger`,type:err_type,category:`${source_type}_trigger`,ref:trigger_item.id,source_id:source_id,id:`${doc._id}-${source_id}-${trigger_item.id}`})}break}case"get_data":case"set_data":case"batch":case"call_native_javascript":case"call_evaluate_javascript":case"call_alert":if(!trigger_item.data.name.prog){if(!trigger_item.data?.name?.properties?.["xu-exp:prog"]){ret.push({code:"CHK_MSG_PRG_TRG_310",data:`empty program to call in ${source_type} "${source_name}" trigger`,type:err_type,category:`${source_type}_trigger`,ref:trigger_item.id,source_id:source_id,id:`${doc._id}-${source_id}-${trigger_item.id}`})}}else{if(!progs_obj?.[trigger_item.data.name.prog]){ret.push({code:"CHK_MSG_PRG_TRG_320",data:`invalid program to call in ${source_type} "${source_name}" trigger`,type:err_type,category:`${source_type}_trigger`,ref:trigger_item.id,source_id:source_id,id:`${doc._id}-${source_id}-${trigger_item.id}`})}else{if(progs_obj?.[trigger_item.data.name.prog].properties.menuType!==trigger_item.data.action){if(["call_native_javascript","call_evaluate_javascript"].includes(trigger_item.data.action)&&progs_obj?.[trigger_item.data.name.prog].properties.menuType==="javascript"){continue}if(["call_alert"].includes(trigger_item.data.action)&&progs_obj?.[trigger_item.data.name.prog].properties.menuType==="alert"){continue}ret.push({code:"CHK_MSG_PRG_TRG_330",data:`call set to "${trigger_item.data.action}" but found "${progs_obj?.[trigger_item.data.name.prog].properties.menuType}" instead in ${source_type} "${source_name}" trigger`,type:err_type,category:`${source_type}_trigger`,ref:trigger_item.id,source_id:source_id,id:`${doc._id}-${source_id}-${trigger_item.id}`})}else{check_target_program_parameters(trigger_item)}}}break;case"execute_native_javascript":case"execute_evaluate_javascript":check_prog_expression(doc,trigger_item.data.name.value,trigger_item.id,"script");break;case"emit_event":if(!trigger_item?.data?.name?.value){ret.push({code:"CHK_MSG_PRG_TRG_800",data:`no event defined for "emit_event" in ${source_type} "${source_name}" trigger`,type:err_type,category:`alert`,ref:doc._id,id:`${doc._id}-${source_id}-${trigger_item.id}`})}else{if(!/^[A-Za-z]+[\w\-\:\.]*$/.test(trigger_item.data.name.value)){ret.push({code:"CHK_MSG_PRG_TRG_810",data:`invalid event name ${trigger_item.data.name.value} in ${source_type} "${source_name}" trigger`,type:err_type,category:`${source_type}_trigger`,ref:trigger_item.id,source_id:source_id,id:`${doc._id}-${source_id}-${trigger_item.id}`})}}break;case"alert":if(_.isEmpty(trigger_item.data.name)){ret.push({code:"CHK_MSG_PRG_TRG_610",data:`no alert properties defined`,type:err_type,category:`alert`,ref:doc._id,id:`${doc._id}-${source_id}-${trigger_item.id}`})}else{if(!trigger_item.data.name.alertType){ret.push({code:"CHK_MSG_PRG_TRG_612",data:`missing alert type property`,type:err_type,category:`alert`,ref:doc._id,id:`${doc._id}-${source_id}-${trigger_item.id}`})}if(!trigger_item.data.name.alertDisplay){ret.push({code:"CHK_MSG_PRG_TRG_614",data:`missing alert display property`,type:err_type,category:`alert`,ref:doc._id,id:`${doc._id}-${source_id}-${trigger_item.id}`})}if(!trigger_item.data.name.alertTitle){ret.push({code:"CHK_MSG_PRG_TRG_616",data:`missing alert title property`,type:"W",category:`alert`,ref:doc._id,id:`${doc._id}-${source_id}-${trigger_item.id}`})}if(!trigger_item.data.name.alertBody){ret.push({code:"CHK_MSG_PRG_TRG_618",data:`missing alert body property`,type:"W",category:`alert`,ref:doc._id,id:`${doc._id}-${source_id}-${trigger_item.id}`})}}break;case"loader_on":case"loader_off":if(doc.properties.menuType!=="component"){ret.push({code:"CHK_MSG_PRG_TRG_400",data:`"${trigger_item.data.action}" can only be executed by component in ${source_type} "${source_name}" trigger`,type:err_type,category:`${source_type}_trigger`,ref:trigger_item.id,source_id:source_id,id:`${doc._id}-${source_id}-${trigger_item.id}`})}break;case"invoke_action":if(doc.properties.menuType!=="component"){ret.push({code:"CHK_MSG_PRG_TRG_400",data:`"${trigger_item.data.action}" can only be executed by component in ${source_type} "${source_name}" trigger`,type:err_type,category:`${source_type}_trigger`,ref:trigger_item.id,source_id:source_id,id:`${doc._id}-${source_id}-${trigger_item.id}`})}if(!["act_next","act_prev","act_first","act_last","act_reload","act_refresh","act_print","act_save","act_delete"].includes(trigger_item.data.name.value)){ret.push({code:"CHK_MSG_PRG_TRG_400",data:`invalid "${trigger_item.data.name.value}" for "${trigger_item.data.action}" in ${source_type} "${source_name}" trigger`,type:err_type,category:`${source_type}_trigger`,ref:trigger_item.id,source_id:source_id,id:`${doc._id}-${source_id}-${trigger_item.id}`})}break;case"delay":if(!trigger_item?.data?.name?.value){ret.push({code:"CHK_MSG_PRG_TRG_520",data:`empty delay value in ${source_type} "${source_name}" trigger`,type:err_type,category:`${source_type}_trigger`,ref:trigger_item.id,source_id:source_id,id:`${doc._id}-${source_id}-${trigger_item.id}`})}break;case"call_library":if(!trigger_item?.data?.name?.plugin_name){ret.push({code:"CHK_MSG_PRG_TRG_510",data:`empty library value in ${source_type} "${source_name}" trigger`,type:err_type,category:`${source_type}_trigger`,ref:trigger_item.id,source_id:source_id,id:`${doc._id}-${source_id}-${trigger_item.id}`})}else{if(!trigger_item?.data?.name?.library_method){ret.push({code:"CHK_MSG_PRG_TRG_516",data:`empty library ${trigger_item.data.name.plugin_name} method in ${source_type} "${source_name}" trigger`,type:err_type,category:`${source_type}_trigger`,ref:trigger_item.id,source_id:source_id,id:`${doc._id}-${source_id}-${trigger_item.id}`})}if(!app_obj?.app_plugins_purchased?.[trigger_item.data.name.plugin_name]){ret.push({code:"CHK_MSG_PRG_TRG_512",data:`invalid library call ${trigger_item.data.name.plugin_name} in ${source_type} "${source_name}" trigger`,type:err_type,category:`${source_type}_trigger`,ref:trigger_item.id,source_id:source_id,id:`${doc._id}-${source_id}-${trigger_item.id}`})}else{if(!app_obj.app_plugins_purchased[trigger_item.data.name.plugin_name].installed){ret.push({code:"CHK_MSG_PRG_TRG_514",data:` library "${trigger_item.data.name.plugin_name}" not installed in ${source_type} "${source_name}" trigger`,type:err_type,category:`${source_type}_trigger`,ref:trigger_item.id,source_id:source_id,id:`${doc._id}-${source_id}-${trigger_item.id}`})}}}break;case"alter_ui_element":case"create_ui_element":case"info_ui_element":case"remove_ui_element":case"empty_ui_element":case"cache_ui_element":case"load_ui_element":ret.push({code:"CHK_MSG_PRG_TRG_900",data:`deprecated "${trigger_item?.data?.action}" action in ${source_type} "${source_name}" trigger`,type:err_type,category:`${source_type}_trigger`,ref:trigger_item.id,source_id:source_id,id:`${doc._id}-${source_id}-${trigger_item.id}`});break;default:ret.push({code:"CHK_MSG_PRG_TRG_008",data:`invalid trigger type "${trigger_item.data.action}" for ${source_type} "${source_name}" trigger`,type:err_type,category:`${source_type}_trigger`,ref:trigger_item.id,source_id:source_id,id:`${doc._id}-${source_id}-${trigger_item.id}`});break}if(trigger_item.props.condition){ret=[...ret,...check_prog_expression(doc,trigger_item.props.condition,trigger_item.id,"condition")]}}return ret};const check_prog_datasource=function(doc){var ret=[];if(!doc.progDataSource||_.isEmpty(doc.progDataSource)||!doc.progDataSource.dataSourceType||doc.progDataSource.dataSourceType==="none"){return ret}switch(doc.progDataSource.dataSourceType){case"table":if(!doc.progDataSource.dataSourceTableId&&!doc?.progDataSource?.dataSourceTableIdExp){ret.push({code:"CHK_MSG_PRG_DSC_010",data:`missing table id for datasource`,type:"E",id:`${doc._id}`});return ret}else{if(doc.progDataSource.dataSourceTableId&&!progs_obj?.[doc.progDataSource.dataSourceTableId]){ret.push({code:"CHK_MSG_PRG_DSC_030",data:`invalid table id ${doc.progDataSource.dataSourceTableId} for datasource`,type:"E",id:`${doc._id}`});return ret}let found_error;function arraysEqual(arr1,arr2){if(arr1.length!==arr2.length)return false;let sortedArr1=arr1.slice().sort();let sortedArr2=arr2.slice().sort();for(let i=0;i<sortedArr1.length;i++){if(sortedArr1[i]!==sortedArr2[i])return false}return true}if(doc.progDataSource.dataSourceIndexesObj){const table_indexes_arr=progs_obj?.[doc.progDataSource.dataSourceTableId]?.tableIndexes;for(let[index_id,index_data]of Object.entries(doc.progDataSource.dataSourceIndexesObj)){if(table_indexes_arr||!find_item_by_id(table_indexes_arr,index_id)){ret.push({code:"CHK_MSG_PRG_DSC_032",data:`find invalid index in table ${progs_obj?.[doc.progDataSource.dataSourceTableId]?.properties?.menuName||doc.progDataSource.dataSourceTableId} for index ${index_id} in dataSourceIndexesObj`,type:"E",id:`${doc._id}`});found_error=true;break}let prog_keys=[];for(let[field_id,val]of Object.entries(index_data)){prog_keys.push(field_id)}if(!arraysEqual(prog_keys,table_indexes_arr.keys)){ret.push({code:"CHK_MSG_PRG_DSC_034",data:`find in-consist index keys in table ${progs_obj?.[doc.progDataSource.dataSourceTableId]?.properties?.menuName||doc.progDataSource.dataSourceTableId} for index ${index_id} in dataSourceIndexesObj`,type:"E",id:`${doc._id}`});found_error=true;break}}if(found_error)return ret}}if(doc.properties.menuType!=="set_data"){if(!doc.progDataSource.dataSourceIndexId&&!doc.progDataSource.dataSourceIndexIdExp){ret.push({code:"CHK_MSG_PRG_DSC_042",data:`index not defined for the datasource table`,type:"W",id:`${doc._id}`})}else if(doc.progDataSource.dataSourceIndexId){if(!progs_obj?.[doc.progDataSource.dataSourceTableId]?.tableIndexes){ret.push({code:"CHK_MSG_PRG_DSC_030",data:`invalid table id ${doc.progDataSource.dataSourceTableId} for datasource`,type:"E",id:`${doc._id}`});return ret}else{const table_indexes_arr=progs_obj?.[doc.progDataSource.dataSourceTableId].tableIndexes;if(!find_item_by_id(table_indexes_arr,doc.progDataSource.dataSourceIndexId)){ret.push({code:"CHK_MSG_PRG_DSC_040",data:`invalid index in table ${progs_obj?.[doc.progDataSource.dataSourceTableId]?.properties?.menuName||doc.progDataSource.dataSourceTableId} for index ${doc.progDataSource.dataSourceIndexId}`,type:"E",id:`${doc._id}`});return ret}}}if(!doc.progDataSource.dataSourceSort&&!doc.progDataSource.dataSourceSortExp){ret.push({code:"CHK_MSG_PRG_DSC_200",data:`missing sort value for datasource`,type:"E",id:`${doc._id}`})}else if(doc.progDataSource.dataSourceSort){if(!["asc","des"].includes(doc.progDataSource.dataSourceSort)){ret.push({code:"CHK_MSG_PRG_DSC_210",data:`invalid sort value for datasource`,type:"E",id:`${doc._id}`})}}if(doc.progDataSource.dataSourceSkip&&typeof doc.progDataSource.dataSourceSkip!=="number"){ret.push({code:"CHK_MSG_PRG_DSC_220",data:`invalid skip value for datasource`,type:"E",id:`${doc._id}`})}if(doc.progDataSource.dataSourceLimit&&typeof doc.progDataSource.dataSourceLimit!=="number"){ret.push({code:"CHK_MSG_PRG_DSC_230",data:`invalid limit value for datasource`,type:"E",id:`${doc._id}`})}}break;default:ret.push({code:"CHK_MSG_PRG_DSC_040",data:`invalid datasource type ${doc.progDataSource.dataSourceType}`,type:"E",id:`${doc._id}`});break}return ret};const check_prog_parameters=function(doc){var ret=[];if(!doc?.properties?.progParams)return ret;var name_counts_obj={};for(let parameter of doc.properties.progParams){if(!parameter?.data?.parameter){ret.push({code:"CHK_MSG_PRG_PRM_010",data:`missing parameter name`,type:doc.studio_meta.not_in_use?"W":"E",category:"parameter",ref:parameter.id,id:`${doc._id}-${parameter.id}`})}else{if(!/^[A-Za-z]+[\w\-\:\.]*$/.test(parameter.data.parameter)){ret.push({code:"CHK_MSG_PRG_PRM_020",data:`invalid parameter name`,type:doc.studio_meta.not_in_use?"W":"E",category:"parameter",ref:parameter.id,id:`${doc._id}-${parameter.id}`})}if(!name_counts_obj[parameter.data.parameter]){name_counts_obj[parameter.data.parameter]=1}else{name_counts_obj[parameter.data.parameter]++}if(!hide_not_in_use_check){if(parameter.data.dir==="in"){if(!find_field_in_progs(doc,parameter.data.parameter)){ret.push({code:"CHK_MSG_PRG_PRM_022",data:`parameter "${parameter.data.parameter}" not in use`,type:"W",category:"parameter",ref:parameter.id,not_in_use:true,id:`${doc._id}-${parameter.id}`})}}}}if(!parameter?.data?.type){ret.push({code:"CHK_MSG_PRG_PRM_030",data:`missing parameter type for ${parameter.data.parameter}`,type:doc.studio_meta.not_in_use?"W":"E",category:"parameter",ref:parameter.id,id:`${doc._id}-${parameter.id}`});return ret}else{switch(parameter.data.type){case"string":break;case"number":case"boolean":break;case"object":break;case"array":break;default:ret.push({code:"CHK_MSG_PRG_PRM_040",data:`invalid parameter type "${parameter.data.type}" for ${parameter.data.parameter}`,type:doc.studio_meta.not_in_use?"W":"E",category:"parameter",ref:parameter.id,id:`${doc._id}-${parameter.id}`});return ret;break}}if(!parameter?.data?.dir){ret.push({code:"CHK_MSG_PRG_PRM_080",data:`missing parameter dir for ${parameter.data.parameter}`,type:doc.studio_meta.not_in_use?"W":"E",category:"parameter",ref:parameter.id,id:`${doc._id}-${parameter.id}`});return ret}else{switch(parameter.data.dir){case"in":break;case"out":if(!find_item_by_key(doc.progFields,"field_id",parameter.data.parameter)){ret.push({code:"CHK_MSG_PRG_PRM_100",data:`missing parameter return in the fieldset for ${parameter.data.parameter}`,type:doc.studio_meta.not_in_use?"W":"E",category:"parameter",ref:parameter.id,id:`${doc._id}-${parameter.id}`})}break;default:ret.push({code:"CHK_MSG_PRG_PRM_090",data:`invalid parameter dir for ${parameter.data.parameter}`,type:doc.studio_meta.not_in_use?"W":"E",category:"parameter",ref:parameter.id,id:`${doc._id}-${parameter.id}`});return ret;break}}}for(let[key,val]of Object.entries(name_counts_obj)){if(val>1){ret.push({code:"CHK_MSG_PRG_PRM_050",data:`duplicate parameter name for ${key}`,type:doc.studio_meta.not_in_use?"W":"E",category:"parameter",ref:parameter.id,id:`${doc._id}-${parameter.id}-${key}`})}}return ret};const check_javascript=function(doc){var ret=[];if(!doc?.scriptData?.value){ret.push({code:"CHK_MSG_PRG_JVS_012",data:"no script to run",type:"W",id:`${doc._id}`})}else{}return ret};const find_item_by_key=function(arr,key,val){return arr.find(function(e){return e.data[key]===val})};const find_item_by_id=function(arr,val){return arr.find(function(e){return e.id===val})};const find_field_in_progs=function(doc,field_id,prog_id){const regex=new RegExp(`@${field_id}\\b`);if(!regex.test(progs_str)){return}var ret=[];for(let[key,prog]of Object.entries(progs_obj)){var fields_arr=[];if(prog.tableFields){fields_arr=prog.tableFields}if(prog.progFields){fields_arr=prog.progFields}if(_.isEmpty(fields_arr)){continue}for(let field_item of fields_arr){if(field_item.data.field_id===field_id){ret.push({prog_id:prog._id,field_item:field_item,properties:prog.properties})}}}return ret};const check_prog_expression=function(doc,exp,path,category){var ret=[];if(!exp)return ret;if(!UglifyJS)return ret;const regex=/@\w+/g;const matches=exp.match(regex);var field_matches={};try{if(matches){for(let field of matches){const ret_field=find_field_in_progs(doc,field.substr(1));if(!ret_field){ret.push({code:"CHK_MSG_PRG_EXP_012",data:`field "${field}" not found in the project datasets using expression "${exp.substr(0,20)}.." in ${path}`,type:"W",category:category,source_id:path,id:`${doc._id}-${path}-${field}`})}else{field_matches[field]=ret_field}}}}catch(error){debugger}if(!_.isEmpty(ret)){return ret}if(_.isEmpty(field_matches)){var options={warnings:true};var result=UglifyJS.minify(exp,options);if(result.error){ret.push({code:"CHK_MSG_PRG_EXP_022",data:`expression error ${result.error.message} in ${exp.substr(0,20)}.. in ${path}`,type:doc.studio_meta.not_in_use?"W":"E",category:category,details:result.error,source_id:path,id:`${doc._id}-${path}`})}if(result.warnings){ret.push({code:"CHK_MSG_PRG_EXP_024",data:`expression warning ${result.warnings[0]} in ${exp.substr(0,20)}.. in ${path}`,type:"W",category:category,details:result.warnings,source_id:path,id:`${doc._id}-${path}`})}}else{var clean_exp=exp;var field_type="string";var skip_eval;for(let[key,val]of Object.entries(field_matches)){if(val.length>1){var field_ind_found_in_current_program;for(let[ret_key,ret_val]of Object.entries(val)){if(ret_val.prog_id===doc._id){field_ind_found_in_current_program=ret_key;break}}if(typeof field_ind_found_in_current_program==="undefined"){skip_eval=true;break}else{field_type=val[field_ind_found_in_current_program]?.field_item?.props?.fieldType}}else{field_type=val[0]?.field_item?.props?.fieldType}switch(field_type){case"string":clean_exp=clean_exp.replaceAll(key,"''");break;case"number":case"boolean":case"bool":clean_exp=clean_exp.replaceAll(key,"0");break;case"object":clean_exp=clean_exp.replaceAll(key,"{}");break;case"array":clean_exp=clean_exp.replaceAll(key,"[]");break;default:break}}if(!skip_eval){var options={warnings:true};var result=UglifyJS.minify(clean_exp,options);if(result.error){ret.push({code:"CHK_MSG_PRG_EXP_026",data:`expression error ${result.error.message} in ${exp.substr(0,20)}.. in ${path}`,type:doc.studio_meta.not_in_use?"W":"E",category:category,details:result.error,source_id:path,id:`${doc._id}-${path}`})}if(result.warnings){ret.push({code:"CHK_MSG_PRG_EXP_028",data:`expression warning ${result.warnings[0]} in ${exp.substr(0,20)}.. in ${path}`,type:"W",category:category,details:result.warnings,source_id:path,id:`${doc._id}-${path}`})}}}return ret};const find_event_id_in_progs=function(doc,event_id){var ret=[];for(let[key,prog]of Object.entries(progs_obj)){if(!prog.progEvents||_.isEmpty(prog.progEvents)){continue}for(let event_item of prog.progEvents){if(event_item.data.event_name===event_id){ret.push({prog_id:prog._id,event_item:event_item,properties:prog.properties})}}}if(!ret.length)return false;return ret};const find_xu_tree_id_in_progs=function(doc,xu_tree_id){var ret=[];for(let[key,prog]of Object.entries(progs_obj)){if(!prog.progUi||_.isEmpty(prog.progUi)){continue}const run_tree=function(node){for(let item of node){if(item.xu_tree_id===xu_tree_id){ret.push({prog_id:prog._id,item:item,properties:prog.properties})}if(item.children){run_tree(item.children)}}};run_tree(prog.progUi)}if(!ret.length)return false;return ret};const find_trigger_property_value_in_progs=function(doc,triggers_arr,property,value,search_in_doc_prog_only){var ret=[];const find_in_triggers=function(prog,workflow){if(!workflow)return;try{for(let val of workflow){if(triggers_arr.includes(val?.data?.action)){const str=JSON.stringify(val);const regex=new RegExp(`\\b${value}\\b`);if(value===null||val?.data?.name?.[property]===value||regex.test(str)){if(val?.data?.name?.[property]){ret.push({prog_id:prog._id,val:val,properties:prog.properties,prop_value:val?.data?.name?.[property]})}else{ret.push({prog_id:prog._id,val:val,properties:prog.properties})}}}}}catch(error){console.error(doc._id,workflow)}};const run_program_search=function(prog){if(prog?.progEvents&&!_.isEmpty(prog.progEvents)){for(let event_item of prog.progEvents){if(event_item.workflow){find_in_triggers(prog,event_item.workflow)}}}if(prog?.progFields&&!_.isEmpty(prog.progFields)){for(let field_item of prog.progFields){if(field_item.workflow){find_in_triggers(prog,field_item.workflow)}}}if(prog?.progUi&&!_.isEmpty(prog.progUi)){const run_tree=function(node){try{for(let item of node){if(item.attributes){for(let[key,val]of Object.entries(item.attributes)){if(key.substr(0,6)==="xu-on:"){if(!_.isEmpty(val)){for(let trigger_item of val){find_in_triggers(prog,trigger_item.workflow)}}}}}if(item.children){run_tree(item.children)}}}catch(error){console.error("find in ui workflow",error)}};run_tree(prog.progUi)}};if(!search_in_doc_prog_only){for(let[key,prog]of Object.entries(progs_obj)){run_program_search(prog)}}else{run_program_search(progs_obj?.[doc._id])}if(!ret.length)return false;return ret};const find_panel_prog_in_progs=function(doc,prog_id,search_in_doc_prog_only){var ret=[];const find_in_prog=function(prog){if(_.isEmpty(prog?.progUi))return;const run_tree=function(node){for(let item of node){if(item.tagName==="xu-panel"){const str=JSON.stringify(item);const regex=new RegExp(`\\b${prog_id}\\b`);if(prog_id===null||item?.attributes?.program?.prog===prog_id||regex.test(str)){if(item?.attributes?.program?.prog){ret.push({prog_id:prog._id,item:item,prop_value:item.attributes.program.prog})}else{ret.push({prog_id:prog._id,item:item})}}}if(item.children){run_tree(item.children)}}};run_tree(prog.progUi)};if(!search_in_doc_prog_only){for(let[key,prog]of Object.entries(progs_obj)){find_in_prog(prog)}}else{find_in_prog(progs_obj?.[doc._id])}if(!ret.length)return false;return ret};const find_table_in_progs=function(doc,table_id,search_in_doc_prog_only){var ret=[];const find_in_prog=function(prog){if(!prog.progDataSource||_.isEmpty(prog.progDataSource)||prog.progDataSource.dataSourceType!=="table"){return}if(prog.progDataSource.dataSourceTableId===table_id||prog.progDataSource?.dataSourceTableIdExp?.includes(table_id)){ret.push({prog_id:prog._id})}};if(!search_in_doc_prog_only){for(let[key,prog]of Object.entries(progs_obj)){find_in_prog(prog)}}else{find_in_prog(progs_obj?.[doc._id])}if(!ret.length)return false;return ret};const find_prog_in_fieldset_fieldValue_progs=function(doc,prog_id,search_in_doc_prog_only){var ret=[];const find_in_prog=function(prog){if(!prog.progFields)return;for(let field_item of prog.progFields){const str=JSON.stringify(field_item);const regex=new RegExp(`\\b${prog_id}\\b`);if(prog_id===null||field_item?.props?.fieldValue===prog_id||regex.test(str)){if(field_item?.props?.fieldValue){ret.push({prog_id:prog._id,field_item:field_item,properties:prog.properties,prop_value:field_item.props.fieldValue})}else{ret.push({prog_id:prog._id,field_item:field_item,properties:prog.properties})}}}};if(!search_in_doc_prog_only){for(let[key,prog]of Object.entries(progs_obj)){find_in_prog(prog)}}else{find_in_prog(progs_obj?.[doc._id])}if(!ret.length)return false;return ret};const new_node_id=function(type,app_id){const abbreviate=word=>{if(word.length<=3){return word}let abbreviation=word[0];const vowels="aeiou";for(let i=1;i<word.length&&abbreviation.length<3;i++){if(!vowels.includes(word[i].toLowerCase())){abbreviation+=word[i]}}if(abbreviation.length<3){abbreviation=word.substring(0,3)}return abbreviation};var last12uuid=crypto.randomUUID().split("-")[4];if(type){var menuAbbreviated=abbreviate(type.replaceAll("_",""));return`${app_id.substr(app_id.length-3)}_${menuAbbreviated}_${last12uuid}`}return app_id.substr(app_id.length-3)+"_"+last12uuid};function detectCryptoString(str){const patterns={uuid:/^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i};const results={};for(const[type,pattern]of Object.entries(patterns)){results[type]=pattern.test(str)}return results}export const get_zod_schema=function(type){const UuidSchema=z.string().uuid().describe(`UUID format identifier`);const TimestampSchema=z.number().describe(`Unix timestamp in milliseconds`);const StudioMetaSchema=z.object({created:TimestampSchema.describe(`Timestamp when the ${type} was created`),createdByUid:z.string().describe(`User ID of the ${type} creator`),checkedInUserId:z.string().describe(`Last user ID who checked in the ${type}`),checkedInUserName:z.string().describe(`Display name of the last user who modified`),savedByUid:z.string().describe(`User ID who last saved the ${type}`),parentId:z.string().describe(`Parent container ID (default: "programs")`),source:z.string().optional().describe(`Source of creation (e.g., "studio ai", "studio ide")`),ui_preview_sizes:z.object({w:z.number().describe(`Preview width`),h:z.number().describe(`Preview height`),l:z.number().describe(`Left position`),t:z.number().describe(`Top position`)}).optional().describe(`Optional UI preview layout hints for visual editors`)}).describe(`Studio metadata for tracking creation, modification, and organizational information`);const ProgParamSchema=z.object({id:z.union([z.string(),z.number()]).describe(`Unique identifier for the parameter`),data:z.object({dir:z.union([z.literal(`in`),z.literal(`out`)]).describe(`Parameter direction: "in" for input parameters, "out" for output parameters`),parameter:z.string().describe(`Parameter name used for referencing in code and workflows`),type:z.union([z.literal(`string`),z.literal(`number`),z.literal(`boolean`),z.literal(`array`),z.literal(`object`)]).describe(`Expected data type of the parameter value`)}).describe(`Core parameter configuration including direction, name, and type`),props:z.object({}).optional().describe(`Additional parameter properties (reserved for future use)`)}).describe(`Input/output parameter definition for ${type} interface`);const ProgFieldSchema=z.object({id:UuidSchema.describe(`Unique UUID identifier for the field`),data:z.object({type:z.union([z.literal(`virtual`),z.literal(`table`),z.literal(`expression`),z.literal(`datasource`)]).describe(`Field type: virtual=variable, table=field from datasource table, expression=holds expression without evaluation, datasource=iterable datasource object/array`),field_id:z.string().describe(`The unique field name used for referencing`)}).describe(`Core field configuration defining its type and identifier`),props:z.object({fieldType:z.union([z.literal(`string`),z.literal(`number`),z.literal(`boolean`),z.literal(`array`),z.literal(`object`)]).describe(`Data type held by the field`),propExpressions:z.object({fieldValue:z.string().optional().describe(`Expression or static value for the field`),fieldType:z.string().optional().describe(`Dynamic field type expression`)}).strict().describe(`Property expressions - only fieldValue and fieldType are allowed`)}).describe(`Field properties including data type and expressions`),workflow:z.array(z.any()).optional().describe(`Optional workflow actions triggered by field changes`)}).describe(`Internal field definition used by the ${type} for data management`);const WorkflowActionSchema=z.object({id:z.union([UuidSchema,z.string(),z.number()]).describe(`Unique identifier for the workflow step`),data:z.object({action:z.union([z.literal(`call_modal`).describe(`Opens a ${type} as a modal dialog`),z.literal(`call_popover`).describe(`Opens a ${type} as a popover overlay`),z.literal(`call_page`).describe(`Navigates to or opens a page ${type}`),z.literal(`call_native_javascript`).describe(`Calls a JavaScript program by ID`),z.literal(`execute_native_javascript`).describe(`Executes inline JavaScript code`),z.literal(`call_evaluate_javascript`).describe(`Calls JavaScript program with argument evaluation`),z.literal(`execute_evaluate_javascript`).describe(`Evaluates and runs dynamic JavaScript expressions`),z.literal(`emit_event`).describe(`Emits a JavaScript event`),z.literal(`loader_on`).describe(`Shows loading indicator`),z.literal(`loader_off`).describe(`Hides loading indicator`),z.literal(`invoke_action`).describe(`Executes system-level actions (refresh, save, etc.)`),z.literal(`update`).describe(`Updates variable values or field data`),z.literal(`raise_event`).describe(`Triggers internal application events`),z.literal(`get_data`).describe(`Executes a get_data program for data retrieval`),z.literal(`set_data`).describe(`Executes a set_data program for data persistence`),z.literal(`batch`).describe(`Executes a batch program for bulk operations`),z.literal(`call_project_api`).describe(`Calls an API program within the current project`),z.literal(`call_external_api`).describe(`Makes HTTP requests to external APIs`),z.literal(`call_system_api`).describe(`Invokes system-level API methods`),z.literal(`alert`).describe(`Displays alert messages (modal, inline, etc.)`),z.literal(`call_alert`).describe(`Calls an alert program by ID`),z.literal(`comment`).describe(`Adds descriptive documentation to workflow`),z.literal(`delay`).describe(`Pauses workflow execution for specified duration`)]).describe(`The specific workflow action type to execute`),name:z.object({properties:z.object({}).optional().describe(`Action-specific properties configuration`),parameters:z.object({doc_in:z.object({value:z.string().optional().describe(`Static parameter value`),fx:z.string().optional().describe(`Dynamic expression referencing variables`)}).optional().describe(`Input parameter for data retrieval`),class_id:z.object({value:z.string().optional().describe(`Static parameter value`),fx:z.string().optional().describe(`Dynamic expression referencing variables`)}).optional().describe(`Class ID parameter for data operations`)}).catchall(z.object({value:z.string().optional().describe(`Static parameter value`),fx:z.string().optional().describe(`Dynamic expression referencing variables`)})).optional().describe(`Input parameters with static values or dynamic expressions`),prog:z.string().optional().describe(`Program ID to call (for call_* actions)`),value:z.string().optional().describe(`Value for action (comments, JavaScript code, variable assignments, delay duration)`),event:z.string().optional().describe(`Event name to trigger (for raise_event action)`),outputField:z.string().optional().describe(`Output variable to store action results (for set_data)`),url:z.string().optional().describe(`External API endpoint URL`),method:z.union([z.literal(`GET`),z.literal(`POST`),z.literal(`PUT`),z.literal(`DELETE`),z.literal(`PATCH`)]).optional().describe(`HTTP method for API calls`),api_method:z.string().optional().describe(`System-level method to invoke`),payload:z.object({}).optional().describe(`Data payload for API calls`),createLog:z.boolean().optional().describe(`Whether to create a log entry for alerts`),alertDisplay:z.union([z.literal(`modal`),z.literal(`inline`),z.literal(`toast`)]).optional().describe(`Alert display type`),alertType:z.union([z.literal(`error`),z.literal(`warning`),z.literal(`info`),z.literal(`success`)]).optional().describe(`Alert message type`),alertTitle:z.string().optional().describe(`Alert title text`),alertBody:z.string().optional().describe(`Alert body message content`)}).describe(`Action-specific configuration and parameters`),enabled:z.boolean().describe(`Whether the workflow step is active and will execute`)}).describe(`Core workflow action definition with type-specific validation`),props:z.object({condition:z.string().optional().describe(`Optional expression that must evaluate to true for action to execute`),async:z.boolean().optional().describe(`Whether to execute asynchronously without waiting for completion`)}).optional().describe(`Additional execution behavior configuration`)}).describe(`Individual workflow action step with comprehensive validation for all supported action types`);const ProgEventSchema=z.object({id:UuidSchema.describe(`Unique UUID identifier for the event`),data:z.object({type:z.union([z.literal(`on_load`),z.literal(`on_exit`),z.literal(`before_record`),z.literal(`after_record`),z.literal(`record_not_found`),z.literal(`locate_not_found`),z.literal(`screen_ready`),z.literal(`client_interval`),z.literal(`user_defined`)]).describe(`Event type defining when the event triggers during ${type} lifecycle`),event_name:z.string().describe(`Reference name for the event`),properties:z.string().describe(`Additional event properties (usually empty)`),condition:z.string().describe(`Optional condition expression to determine when event should fire`),parameters:z.array(z.any()).describe(`Array of parameter mappings for the event`)}).describe(`Core event configuration defining trigger conditions and parameters`),props:z.object({propExpressions:z.object({}).optional().describe(`Property expressions for dynamic event behavior`)}).describe(`Additional event properties and expressions`),workflow:z.array(WorkflowActionSchema).optional().describe(`Array of workflow actions to execute when event triggers`)}).describe(`Component lifecycle event with associated triggers and workflow actions`);const UiAttributesSchema=z.record(z.union([z.string(),z.number(),z.boolean(),z.object({}),z.array(z.object({handler:z.string().describe(`Event handler type`),props:z.object({}).optional().describe(`Handler-specific properties`),workflow:z.array(WorkflowActionSchema).optional().describe(`Workflow actions to execute on event`)}))])).refine(attrs=>{const xuAttributes=Object.keys(attrs).filter(key=>key.startsWith(`xu-`));for(const attr of xuAttributes){const value=attrs[attr];if(attr===`xu-bind`&&typeof value!==`string`){return false}if(attr===`xu-render`&&typeof value!==`string`){return false}if(attr===`xu-show`&&typeof value!==`string`){return false}if(attr===`xu-for`&&typeof value!==`string`){return false}if([`xu-for-key`,`xu-for-val`].includes(attr)&&typeof value!==`string`){return false}if(attr.startsWith(`xu-on:`)&&!Array.isArray(value)){return false}if(attr===`xu-class`){if(typeof value!==`string`&&typeof value!==`object`){return false}}if(attr===`xu-store`){if(typeof value!==`string`&&typeof value!==`object`){return false}}if([`xu-text`,`xu-html`,`xu-content`,`xu-ref`].includes(attr)&&typeof value!==`string`){return false}if(attr.startsWith(`xu-exp:`)&&typeof value!==`string`){return false}if([`xu-style`,`xu-style-global`,`xu-script`,`xu-cdn`,`xu-ui-plugin`,`xu-viewport`].includes(attr)&&typeof value!==`string`){return false}}return true},{message:`Invalid Xuda attribute configuration`}).describe(`HTML attributes and Xuda-specific directives for UI elements. Supported Xuda attributes with examples:
2
2
 
3
3
  - xu-bind: Creates two-way data binding between input elements and progFields
4
4
  Example: xu-bind="user_name_field"
@@ -47,4 +47,4 @@ var app_obj,progs_obj,_,progs_str,hide_not_in_use_check,is_server,deployments,Ug
47
47
  Example: xu-store="{'temp_var':'@calculated_value','status':'ready'}"
48
48
 
49
49
  - xu-viewport: Handles viewport-based logic during rendering
50
- Example: xu-viewport="@mobile_view"`);const UiElementSchema=z.lazy(()=>z.object({id:z.union([z.literal(`root`),UuidSchema,z.string().regex(/^node-[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i),z.string().regex(/^ui-[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i)]).describe(`Element identifier: "root" for top-level, prefixed UUIDs like "ui-791ca98a-e284-4413-af0a-96e5527c338b"`),type:z.literal(`element`).describe(`Element type - only "element" allowed (no "comment" or "text" types)`),tagName:z.string().describe(`HTML tag name for the element (e.g., "div", "span", "input")`),attributes:UiAttributesSchema.optional().describe(`HTML attributes and Xuda directives (e.g., class, xu-bind, xu-on)`),content:z.string().optional().describe(`Text content for the element (replaces deprecated "text" type)`),text:z.string().optional().describe(`Alternative text property for element content`),children:z.array(UiElementSchema).optional().describe(`Array of child elements nested within this element`),workflow:z.array(WorkflowActionSchema).optional().describe(`Workflow actions associated with this UI element`),path:z.array(z.number()).optional().describe("Array representing the element`s position in the UI tree"),code:z.string().optional().describe(`Generated HTML code representation`),editCode:z.boolean().optional().describe(`Flag indicating if element is in code editing mode`),$folded:z.boolean().optional().describe(`UI editor state - whether element tree is collapsed`)}).describe(`UI element following Himalaya.js structure with Xuda extensions, 1. generate unique id using UUID for every item of the progUi (except the root node, leave the root node as is),2. never use "comment" or "text" type, 3. convert "text" type to "element" and add a text property instead next to the type property `));const DataSourceSchema=z.object({dataSourceType:z.union([z.literal(`table`).describe(`Connect to structured table from global Table Repository`),z.literal(`array`).describe(`Use static or dynamically populated array`),z.literal(`json`).describe(`Load structured data in JSON format`),z.literal(`csv`).describe(`Load data from CSV source`),z.literal(`none`).describe(`No data source attached - self-contained logic unit`),z.literal(``).describe(`Empty string indicating no datasource configured`)]).optional().describe(`Type of data source defining how data is retrieved and processed`),dataSourceFilterModelType:z.union([z.literal(`index`).describe(`Use predefined index with from/to values for fast range filtering`),z.literal(`query`).describe(`Use jQuery Mongo syntax for advanced conditional filters and logical rules`)]).optional().describe(`Filtering approach for table sources`),dataSourceSort:z.union([z.literal(`asc`),z.literal(`desc`)]).optional().describe(`Global sort direction for retrieved data`),dataSourceTableId:z.string().optional().describe(`Reference to table ID in Table Repository when dataSourceType is "table"`),dataSourceIndexId:z.string().optional().describe(`Default index ID used for efficient data lookup and filtering`),dataSourceIndexesObj:z.record(z.record(z.object({from:z.string().describe(`Starting value for index range (can be dynamic expression like @uid_in)`),locate_from:z.string().optional().describe(`Additional locate parameter for range start`),locate_to:z.string().optional().describe(`Additional locate parameter for range end`),to:z.string().describe(`Ending value for index range (can be dynamic expression)`),key:z.string().describe(`Field name being indexed and filtered`)}).describe(`Index field configuration with range values`))).optional().describe(`Index configurations mapped by index ID, defining field ranges and conditions for efficient filtering`),dataSourceReduce:z.boolean().optional().describe(`Whether to reduce results to single aggregated value (count, sum, avg) - requires DBS plugin`),filterModelMongo:z.object({}).optional().describe(`Static MongoDB-style filter query object built using jQuery QueryBuilder`),filterModelMongoFx:z.string().optional().describe(`Dynamic reference to input field containing filter query object (overrides filterModelMongo)`),sortModel:z.array(z.object({field_id:z.string().describe(`Field identifier to sort by`),sort_dir:z.union([z.literal(`asc`),z.literal(`desc`)]).describe(`Sort direction for this specific field`)})).optional().describe(`Array of field-level sorting rules for multi-column sorting`),dataSourceRealtime:z.boolean().optional().describe(`Enable real-time updates when source data changes (table sources only, requires @xuda.io/xuds-dbs-plugin-xuda)`),datafieldsOutputField:z.string().optional().describe(`Field name where raw query results will be stored within parent hierarchy`),dataSourceLimit:z.number().optional().describe(`Maximum number of rows or iterations to return for pagination`),dataSourceSkip:z.number().optional().describe(`Number of rows to skip before returning results, useful for pagination offset`),dataSourceUrl:z.string().optional().describe(`External URL endpoint for loading array/CSV/JSON data from REST APIs or static files`),dataSourceInputField:z.string().optional().describe(`Dynamic field reference in UI or app context for data source values (alternative to external URL)`)}).describe(`Comprehensive data source configuration defining how logic units retrieve, filter, and process data from tables, arrays, APIs, or external sources`);let properties_obj={menuType:z.literal(type).describe(`defines the object category`),menuName:z.string().describe(`Internal name displayed in the Studio interface`)};let properties=z.object(properties_obj).describe(`Core ${type} properties defining behavior, access, and UI framework settings`);const progFields=z.array(ProgFieldSchema).describe(`Defines the internal working fields of the ${type}. These include real and virtual fields used for data binding, user interaction, intermediate logic, and expression evaluation.`);const progEvents=z.array(ProgEventSchema).optional().describe(`Defines all functional logic associated with the ${type}. Events support lifecycle hooks (like on_load, screen_ready, client_interval), event-based workflow, custom utility functions, and conditional logic.`);const progUi=z.array(UiElementSchema).describe(`Describes the rendered interface in a structured JSON format, derived from Himalaya.js (HTML-to-JSON). Each node can be bound to logic via attributes such as xu-exp, bind, for, and trigger. This enables conditional rendering, looping constructs, inline script execution, and seamless integration with workflow.`);const progDataSource=DataSourceSchema.describe(`Defines where the ${type} pulls or binds its data from, such as a database table, external service, or static source.`);let main_obj={_id:z.string().regex(/^[a-zA-Z0-9_]+$/).describe(`Unique ${type} identifier with format constraints`),app_id:z.string().describe(`Reference to the parent application this ${type} belongs to`),stat:z.union([z.literal(1),z.literal(2),z.literal(3),z.literal(4)]).describe(`Document status: 1=draft, 2=review, 3=active, 4=archived`),docType:z.literal(`studio`).describe(`Always "studio" - indicates this is a Studio-authored ${type}`),docDate:TimestampSchema.describe(`Unix timestamp when the ${type} document was created`),ts:TimestampSchema.describe(`Unix timestamp of the most recent modification`),order_ts:TimestampSchema.describe(`Timestamp used for ordering components in the Studio interface`),description:z.string().optional().describe(`Describe in short the ${type}`),studio_meta:StudioMetaSchema};let XudaComponentSchema=z.object(main_obj);main_obj.properties=properties;switch(type){case`globals`:XudaComponentSchema.describe(`The globals object in the Xuda platform defines a universal logic layer shared across all programs, components, and workflows. It provides a centralized and consistent structure for declaring global fields, utility functions, and event-driven logic, ensuring logic reusability and reducing redundancy across the application.`);main_obj.progFields=progFields;main_obj.progEvents=progEvents;break;case`table`:XudaComponentSchema.describe(`The Table Object represents a data entity and serves as the structural definition for interacting with external databases. It supports integration via pluggable connectors, allowing seamless connection to various database engines such as MySQL, CouchDB, and others (see available database plugins for the full list).`);properties_obj.databaseSocket=z.string().default("@xuda.io/xuda-dbs-plugin-xuda").describe("Database driver to use for the table");const XudaFieldType=z.enum(["string","number","boolean","array","object","date"]).describe("Data type for table fields");const IndexDataSchema=z.object({name:z.string().describe("Name of the index"),unique:z.boolean().describe("If true, ensures no duplicates for indexed fields"),keys:z.array(z.string()).describe("List of field names used in this index"),props:z.object({}).describe("")});const TableIndexSchema=z.object({id:z.string().uuid().describe("Unique uuid identifier for the index"),data:IndexDataSchema.describe("Contains keys, uniqueness setting, and index name")});const FieldPropsSchema=z.object({fieldType:XudaFieldType.describe('Data type: "string", "number", "boolean", "array", "object", or "date"'),label:z.string().describe("the name of the field")});const FieldDataSchema=z.object({field_id:z.string().describe("Field identifier used in logic or database operations")});const TableFieldSchema=z.object({id:z.string().uuid().describe("Unique uuid of the field object"),data:FieldDataSchema.describe("Contains the logical field ID"),props:FieldPropsSchema.describe("Properties of the field including data type")});main_obj.tableIndexes=z.array(TableIndexSchema).describe("Defines indexing rules for efficient lookups and uniqueness constraints");main_obj.tableFields=z.array(TableFieldSchema).describe("Defines each field used in the table and its data type");break;case`folder`:XudaComponentSchema.describe(`The Folder is a non-executable, project-level container represented as a structured JSON object. It is used to define a hierarchical structure for organizing application assets within the Xuda environment. Although it does not execute any logic at runtime, the folder object plays an essential role in shaping the overall architecture of a project by logically grouping related objects such as components, APIs, tables, datasets, and other program entities.`);break;case`component`:XudaComponentSchema.describe(`The component object in the Xuda platform defines a modular, self-contained program unit that encapsulates both front-end presentation and back-end logic. It serves as a reusable UI component that supports a full execution lifecycle, making it ideal for constructing low-code applications that are maintainable, scalable, and highly interactive. A component is engineered to allow seamless integration of logic, data, and rendering, enabling developers to build sophisticated interactive views without redundant code. Each component instance supports input/output parameters, can communicate with other components or programs, and can be dynamically rendered as a page, modal, or embedded panel.`);properties_obj.frameworkProperties=z.object({}).optional().describe(`Framework-specific rendering extensions and configuration`);properties_obj.renderType=z.string().describe(`Component layout type (e.g., "form", "grid", "list")`);properties_obj.rwMode=z.union([z.literal(`R`),z.literal(`W`),z.literal(`RW`)]).describe(`Access mode: R=read-only, W=write-only, RW=read-write`);properties_obj.uiFramework=z.string().describe(`Selected UI framework plugin (e.g., @xuda.io/xuda-framework-plugin-tailwind)`);properties_obj.menuTitle=z.string().optional().describe(`Display title for Studio UI or routing usage`);properties_obj.progParams=z.array(ProgParamSchema).optional().describe(`Array of input/output parameter definitions for ${type} interface`);main_obj.progDataSource=progDataSource;main_obj.progFields=progFields;main_obj.progEvents=progEvents;main_obj.progUi=progUi;break;case`get_data`:XudaComponentSchema.describe(`The Get Data Object defines a lightweight, read-only program unit designed to retrieve data from a structured source such as a table, array, or remote dataset. It is used to extract specific values, perform indexed lookups, and support transformations through reduce or conditional logic. This object is typically used when a logic program requires only data retrieval without the need to iterate or mutate records. It supports output parameter mapping and can be embedded into workflows and alerts for dynamic value extraction.`);properties_obj.frameworkProperties=z.object({}).optional().describe(`Framework-specific rendering extensions and configuration`);properties_obj.progParams=z.array(ProgParamSchema).optional().describe(`Array of input/output parameter definitions for ${type} interface`);main_obj.progDataSource=progDataSource;main_obj.progFields=progFields;main_obj.progEvents=progEvents;break;case`set_data`:XudaComponentSchema.describe(`The set_data object defines a program-level functional unit responsible for writing data to a specified table. It can be invoked from any program and is designed to handle create, update, and delete operations in a structured and reusable way. The object includes properties to determine the type of operation being performed and supports an optional flag to create a new record if one does not already exist. In addition to its core structure, the set_data object includes a parameter interface property that defines input and output parameters. This allows values to be passed into the function and returned to the calling context, enabling flexible, context-aware data handling.`);properties_obj.progParams=z.array(ProgParamSchema).optional().describe(`Array of input/output parameter definitions for ${type} interface`);properties_obj.crudMode=z.enum(["C","U","D"]).describe("Operation mode: C = Create, U = Update, D = Delete");properties_obj.crudMode=z.boolean().describe("If true, allows record creation if not found");main_obj.progDataSource=progDataSource;main_obj.progFields=progFields;main_obj.progEvents=progEvents;break;case`batch`:XudaComponentSchema.describe(`The Batch Object defines a program-level execution unit tailored for iterative, record-by-record operations across datasets. It enables controlled loops over structured data sources or arrays, making it a foundational element for multi-record processing, automation flows, and background job orchestration. The batch object can be invoked from within any Xuda logic program and serves as a reusable execution block for bulk workflows, such as saving multiple records, transforming arrays, or triggering chained program logic. It accepts dynamic input and output parameters, which allow context-aware execution and return values that can be consumed downstream.The batch unit also includes lifecycle hooks and event workflow, enabling custom logic at specific points within the loop (e.g., before/after each record or on error conditions). This supports advanced control, transformation, and external interactions during iterative processing.`);properties_obj.progParams=z.array(ProgParamSchema).optional().describe(`Array of input/output parameter definitions for ${type} interface`);main_obj.progDataSource=progDataSource;main_obj.progFields=progFields;main_obj.progEvents=progEvents;break;case`api`:XudaComponentSchema.describe(`The API Program-Level Logic Unit is a program-level logic unit represented as a structured JSON object that exposes backend functionality through internal or external interfaces. It can be invoked internally via the call_project_api method or externally through the api/mcp endpoint, enabling controlled access to application-level logic and data services. Acting as an orchestration layer, the API unit enables coordination of multiple subordinate logic units such as get_data, set_data, and batch, allowing compound workflows, transactional operations, and conditional executions to be encapsulated within a single, callable endpoint. This design abstracts complexity and promotes composability of business logic across the application. The API unit includes an interface definition for parameter binding, specifying dynamic input and output mappings. This supports stateless, context-aware executions where external values can be passed into the API call, and structured results returned to the calling layer. Response format configuration is also supported, with output types including json, text, html, and others—allowing precise control over the serialization and consumption of API responses.`);properties_obj.progParams=z.array(ProgParamSchema).optional().describe(`Array of input/output parameter definitions for ${type} interface`);const ApiOutputFormat=z.enum(["json","html","text","xml","csv","pdf"]).describe("Format of the API response: json, html, text, xml, csv, pdf, etc.");properties_obj.apiOutput=ApiOutputFormat.describe("Format of the API response: json, html, text, etc.");main_obj.progDataSource=progDataSource;main_obj.progFields=progFields;main_obj.progEvents=progEvents;main_obj.scriptData=z.object({value:z.string().describe("The return payload template as a stringified object. Placeholder bindings (e.g., @CS_Id) are replaced at runtime")});break;case`alert`:XudaComponentSchema.describe(`The Alert Object is a program-level UI unit in the Xuda platform used to deliver contextual messages and notifications to users or developers at runtime. These alerts can be triggered from within logic flows and offer various display formats (such as toast, modal, browser alert, or console message) based on the use case. The alert object is defined using a structured JSON format and can be embedded in broader program logic. It supports both static and dynamic content, and can optionally create log entries to support audit trails and debugging workflows.`);properties_obj.progParams=z.array(ProgParamSchema).optional().describe(`Array of input/output parameter definitions for ${type} interface`);const AlertType=z.enum(["info","success","warning","error"]);const AlertDisplay=z.enum(["toast","modal","browser","console"]);main_obj.alertData=z.object({alertDisplay:AlertDisplay.describe('Mode of display: "toast", "modal", "browser", or "console"'),alertType:AlertType.describe('Type of message: "warning", "error", "info", or "success"'),alertTitle:z.string().describe("Main content of the alert shown to the user"),alertTitleFx:z.string().optional().describe("Optional dynamic override (e.g., @msg_v) for alert content"),createLog:z.boolean().describe("Whether to generate a system log entry associated with the alert")});break;case`javascript`:XudaComponentSchema.describe(`The javascript object is a functional unit designed to execute JavaScript code within the application context. It can be called from any program using methods such as call_native_javascript, call_evaluate_javascript, execute_native_javascript, or execute_evaluate_javascript. This object includes the following key property: Script – Contains the JavaScript code to be executed, along with any declared dependencies required for execution. The javascript object is ideal for performing advanced logic, custom client-side behavior, or dynamic scripting that extends the capabilities of low-code flows. Xuda also exposes a set of built-in API methods that can be easily called from JavaScript units. These include actions like reading from or writing to Drive, interacting with the Studio API, or performing database operations such as create, update, and delete. These ready-to-use APIs simplify common tasks and allow you to focus on building functionality instead of writing boilerplate code. By centralizing script execution in a modular and reusable way, the JavaScript unit enhances flexibility, promotes clean architecture, and empowers developers to go beyond standard configuration with native scripting power.`);properties_obj.progParams=z.array(ProgParamSchema).optional().describe(`Array of input/output parameter definitions for ${type} interface`);main_obj.scriptData=z.object({value:z.string().describe("JavaScript code to be executed"),dependencies:z.record(z.string()).optional().describe("Optional. Key-value map of external packages required")});break;default:break}return XudaComponentSchema};export const get_fields_z_schema=function(fields={},exclude_props=[],data={}){let inputSchema={};const get_z_item=function(key,val){let prop={};if(val.type==="object"&&val.items){for(const[item_key,item_val]of Object.entries(val.items.properties)){prop[item_key]=get_z_item(item_key,item_val);if(!val?.items?.required?.includes(item_key)){prop[item_key]=prop[item_key].nullable()}}}if(val.type==="array"){prop=get_z_item("",val.items)}let _z=z[val.type](prop);if(!val.mandatory){_z=_z.nullable()}if(val.enum){_z=z.enum(val.enum)}if(data[item_key]){_z=z.default(data[item_key])}let valid_values="";if(val.options){valid_values=val.options.join(", ")}if(val.description){const desc=val.name||key.replace(/_/g," ").replace(/\b(\w)/g,(_,char)=>char.toUpperCase());_z=_z.describe((desc?desc+" - ":"")+val.description+(valid_values?" Valid values: "+valid_values:""))}return _z};try{for(const[key,val]of Object.entries(fields)){if(exclude_props.includes(key))continue;inputSchema[key]=get_z_item(key,val)}return inputSchema}catch(error){debugger}};
50
+ Example: xu-viewport="@mobile_view"`);const UiElementSchema=z.lazy(()=>z.object({id:z.union([z.literal(`root`),UuidSchema,z.string().regex(/^node-[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i),z.string().regex(/^ui-[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i)]).describe(`Element identifier: "root" for top-level, prefixed UUIDs like "ui-791ca98a-e284-4413-af0a-96e5527c338b"`),type:z.literal(`element`).describe(`Element type - only "element" allowed (no "comment" or "text" types)`),tagName:z.string().describe(`HTML tag name for the element (e.g., "div", "span", "input")`),attributes:UiAttributesSchema.optional().describe(`HTML attributes and Xuda directives (e.g., class, xu-bind, xu-on)`),content:z.string().optional().describe(`Text content for the element (replaces deprecated "text" type)`),text:z.string().optional().describe(`Alternative text property for element content`),children:z.array(UiElementSchema).optional().describe(`Array of child elements nested within this element`),workflow:z.array(WorkflowActionSchema).optional().describe(`Workflow actions associated with this UI element`),path:z.array(z.number()).optional().describe("Array representing the element`s position in the UI tree"),code:z.string().optional().describe(`Generated HTML code representation`),editCode:z.boolean().optional().describe(`Flag indicating if element is in code editing mode`),$folded:z.boolean().optional().describe(`UI editor state - whether element tree is collapsed`)}).describe(`UI element following Himalaya.js structure with Xuda extensions, 1. generate unique id using UUID for every item of the progUi (except the root node, leave the root node as is),2. never use "comment" or "text" type, 3. convert "text" type to "element" and add a text property instead next to the type property `));const DataSourceSchema=z.object({dataSourceType:z.union([z.literal(`table`).describe(`Connect to structured table from global Table Repository`),z.literal(`array`).describe(`Use static or dynamically populated array`),z.literal(`json`).describe(`Load structured data in JSON format`),z.literal(`csv`).describe(`Load data from CSV source`),z.literal(`none`).describe(`No data source attached - self-contained logic unit`),z.literal(``).describe(`Empty string indicating no datasource configured`)]).optional().describe(`Type of data source defining how data is retrieved and processed`),dataSourceFilterModelType:z.union([z.literal(`index`).describe(`Use predefined index with from/to values for fast range filtering`),z.literal(`query`).describe(`Use jQuery Mongo syntax for advanced conditional filters and logical rules`)]).optional().describe(`Filtering approach for table sources`),dataSourceSort:z.union([z.literal(`asc`),z.literal(`desc`)]).optional().describe(`Global sort direction for retrieved data`),dataSourceTableId:z.string().optional().describe(`Reference to table ID in Table Repository when dataSourceType is "table"`),dataSourceIndexId:z.string().optional().describe(`Default index ID used for efficient data lookup and filtering`),dataSourceIndexesObj:z.record(z.record(z.object({from:z.string().describe(`Starting value for index range (can be dynamic expression like @uid_in)`),locate_from:z.string().optional().describe(`Additional locate parameter for range start`),locate_to:z.string().optional().describe(`Additional locate parameter for range end`),to:z.string().describe(`Ending value for index range (can be dynamic expression)`),key:z.string().describe(`Field name being indexed and filtered`)}).describe(`Index field configuration with range values`))).optional().describe(`Index configurations mapped by index ID, defining field ranges and conditions for efficient filtering`),dataSourceReduce:z.boolean().optional().describe(`Whether to reduce results to single aggregated value (count, sum, avg) - requires DBS plugin`),filterModelMongo:z.object({}).optional().describe(`Static MongoDB-style filter query object built using jQuery QueryBuilder`),filterModelMongoFx:z.string().optional().describe(`Dynamic reference to input field containing filter query object (overrides filterModelMongo)`),sortModel:z.array(z.object({field_id:z.string().describe(`Field identifier to sort by`),sort_dir:z.union([z.literal(`asc`),z.literal(`desc`)]).describe(`Sort direction for this specific field`)})).optional().describe(`Array of field-level sorting rules for multi-column sorting`),dataSourceRealtime:z.boolean().optional().describe(`Enable real-time updates when source data changes (table sources only, requires @xuda.io/xuds-dbs-plugin-xuda)`),datafieldsOutputField:z.string().optional().describe(`Field name where raw query results will be stored within parent hierarchy`),dataSourceLimit:z.number().optional().describe(`Maximum number of rows or iterations to return for pagination`),dataSourceSkip:z.number().optional().describe(`Number of rows to skip before returning results, useful for pagination offset`),dataSourceUrl:z.string().optional().describe(`External URL endpoint for loading array/CSV/JSON data from REST APIs or static files`),dataSourceInputField:z.string().optional().describe(`Dynamic field reference in UI or app context for data source values (alternative to external URL)`)}).describe(`Comprehensive data source configuration defining how logic units retrieve, filter, and process data from tables, arrays, APIs, or external sources`);let properties_obj={menuType:z.literal(type).describe(`defines the object category`),menuName:z.string().describe(`Internal name displayed in the Studio interface`)};let properties=z.object(properties_obj).describe(`Core ${type} properties defining behavior, access, and UI framework settings`);const progFields=z.array(ProgFieldSchema).describe(`Defines the internal working fields of the ${type}. These include real and virtual fields used for data binding, user interaction, intermediate logic, and expression evaluation.`);const progEvents=z.array(ProgEventSchema).optional().describe(`Defines all functional logic associated with the ${type}. Events support lifecycle hooks (like on_load, screen_ready, client_interval), event-based workflow, custom utility functions, and conditional logic.`);const progUi=z.array(UiElementSchema).describe(`Describes the rendered interface in a structured JSON format, derived from Himalaya.js (HTML-to-JSON). Each node can be bound to logic via attributes such as xu-exp, bind, for, and trigger. This enables conditional rendering, looping constructs, inline script execution, and seamless integration with workflow.`);const progDataSource=DataSourceSchema.describe(`Defines where the ${type} pulls or binds its data from, such as a database table, external service, or static source.`);let main_obj={_id:z.string().regex(/^[a-zA-Z0-9_]+$/).describe(`Unique ${type} identifier with format constraints`),app_id:z.string().describe(`Reference to the parent application this ${type} belongs to`),stat:z.union([z.literal(1),z.literal(2),z.literal(3),z.literal(4)]).describe(`Document status: 1=draft, 2=review, 3=active, 4=archived`),docType:z.literal(`studio`).describe(`Always "studio" - indicates this is a Studio-authored ${type}`),docDate:TimestampSchema.describe(`Unix timestamp when the ${type} document was created`),ts:TimestampSchema.describe(`Unix timestamp of the most recent modification`),order_ts:TimestampSchema.describe(`Timestamp used for ordering components in the Studio interface`),description:z.string().optional().describe(`Describe in short the ${type}`),studio_meta:StudioMetaSchema};let XudaComponentSchema=z.object(main_obj);main_obj.properties=properties;switch(type){case`globals`:XudaComponentSchema.describe(`The globals object in the Xuda platform defines a universal logic layer shared across all programs, components, and workflows. It provides a centralized and consistent structure for declaring global fields, utility functions, and event-driven logic, ensuring logic reusability and reducing redundancy across the application.`);main_obj.progFields=progFields;main_obj.progEvents=progEvents;break;case`table`:XudaComponentSchema.describe(`The Table Object represents a data entity and serves as the structural definition for interacting with external databases. It supports integration via pluggable connectors, allowing seamless connection to various database engines such as MySQL, CouchDB, and others (see available database plugins for the full list).`);properties_obj.databaseSocket=z.string().default("@xuda.io/xuda-dbs-plugin-xuda").describe("Database driver to use for the table");const XudaFieldType=z.enum(["string","number","boolean","array","object","date"]).describe("Data type for table fields");const IndexDataSchema=z.object({name:z.string().describe("Name of the index"),unique:z.boolean().describe("If true, ensures no duplicates for indexed fields"),keys:z.array(z.string()).describe("List of field names used in this index"),props:z.object({}).describe("")});const TableIndexSchema=z.object({id:z.string().uuid().describe("Unique uuid identifier for the index"),data:IndexDataSchema.describe("Contains keys, uniqueness setting, and index name")});const FieldPropsSchema=z.object({fieldType:XudaFieldType.describe('Data type: "string", "number", "boolean", "array", "object", or "date"'),label:z.string().describe("the name of the field")});const FieldDataSchema=z.object({field_id:z.string().describe("Field identifier used in logic or database operations")});const TableFieldSchema=z.object({id:z.string().uuid().describe("Unique uuid of the field object"),data:FieldDataSchema.describe("Contains the logical field ID"),props:FieldPropsSchema.describe("Properties of the field including data type")});main_obj.tableIndexes=z.array(TableIndexSchema).describe("Defines indexing rules for efficient lookups and uniqueness constraints");main_obj.tableFields=z.array(TableFieldSchema).describe("Defines each field used in the table and its data type");break;case`folder`:XudaComponentSchema.describe(`The Folder is a non-executable, project-level container represented as a structured JSON object. It is used to define a hierarchical structure for organizing application assets within the Xuda environment. Although it does not execute any logic at runtime, the folder object plays an essential role in shaping the overall architecture of a project by logically grouping related objects such as components, APIs, tables, datasets, and other program entities.`);break;case`component`:XudaComponentSchema.describe(`The component object in the Xuda platform defines a modular, self-contained program unit that encapsulates both front-end presentation and back-end logic. It serves as a reusable UI component that supports a full execution lifecycle, making it ideal for constructing low-code applications that are maintainable, scalable, and highly interactive. A component is engineered to allow seamless integration of logic, data, and rendering, enabling developers to build sophisticated interactive views without redundant code. Each component instance supports input/output parameters, can communicate with other components or programs, and can be dynamically rendered as a page, modal, or embedded panel.`);properties_obj.frameworkProperties=z.object({}).optional().describe(`Framework-specific rendering extensions and configuration`);properties_obj.renderType=z.string().describe(`Component layout type (e.g., "form", "grid", "list")`);properties_obj.rwMode=z.union([z.literal(`R`),z.literal(`W`),z.literal(`RW`)]).describe(`Access mode: R=read-only, W=write-only, RW=read-write`);properties_obj.uiFramework=z.string().describe(`Selected UI framework plugin (e.g., @xuda.io/xuda-framework-plugin-tailwind)`);properties_obj.menuTitle=z.string().optional().describe(`Display title for Studio UI or routing usage`);properties_obj.progParams=z.array(ProgParamSchema).optional().describe(`Array of input/output parameter definitions for ${type} interface`);main_obj.progDataSource=progDataSource;main_obj.progFields=progFields;main_obj.progEvents=progEvents;main_obj.progUi=progUi;break;case`get_data`:XudaComponentSchema.describe(`The Get Data Object defines a lightweight, read-only program unit designed to retrieve data from a structured source such as a table, array, or remote dataset. It is used to extract specific values, perform indexed lookups, and support transformations through reduce or conditional logic. This object is typically used when a logic program requires only data retrieval without the need to iterate or mutate records. It supports output parameter mapping and can be embedded into workflows and alerts for dynamic value extraction.`);properties_obj.frameworkProperties=z.object({}).optional().describe(`Framework-specific rendering extensions and configuration`);properties_obj.progParams=z.array(ProgParamSchema).optional().describe(`Array of input/output parameter definitions for ${type} interface`);main_obj.progDataSource=progDataSource;main_obj.progFields=progFields;main_obj.progEvents=progEvents;break;case`set_data`:XudaComponentSchema.describe(`The set_data object defines a program-level functional unit responsible for writing data to a specified table. It can be invoked from any program and is designed to handle create, update, and delete operations in a structured and reusable way. The object includes properties to determine the type of operation being performed and supports an optional flag to create a new record if one does not already exist. In addition to its core structure, the set_data object includes a parameter interface property that defines input and output parameters. This allows values to be passed into the function and returned to the calling context, enabling flexible, context-aware data handling.`);properties_obj.progParams=z.array(ProgParamSchema).optional().describe(`Array of input/output parameter definitions for ${type} interface`);properties_obj.crudMode=z.enum(["C","U","D"]).describe("Operation mode: C = Create, U = Update, D = Delete");properties_obj.crudMode=z.boolean().describe("If true, allows record creation if not found");main_obj.progDataSource=progDataSource;main_obj.progFields=progFields;main_obj.progEvents=progEvents;break;case`batch`:XudaComponentSchema.describe(`The Batch Object defines a program-level execution unit tailored for iterative, record-by-record operations across datasets. It enables controlled loops over structured data sources or arrays, making it a foundational element for multi-record processing, automation flows, and background job orchestration. The batch object can be invoked from within any Xuda logic program and serves as a reusable execution block for bulk workflows, such as saving multiple records, transforming arrays, or triggering chained program logic. It accepts dynamic input and output parameters, which allow context-aware execution and return values that can be consumed downstream.The batch unit also includes lifecycle hooks and event workflow, enabling custom logic at specific points within the loop (e.g., before/after each record or on error conditions). This supports advanced control, transformation, and external interactions during iterative processing.`);properties_obj.progParams=z.array(ProgParamSchema).optional().describe(`Array of input/output parameter definitions for ${type} interface`);main_obj.progDataSource=progDataSource;main_obj.progFields=progFields;main_obj.progEvents=progEvents;break;case`api`:XudaComponentSchema.describe(`The API Program-Level Logic Unit is a program-level logic unit represented as a structured JSON object that exposes backend functionality through internal or external interfaces. It can be invoked internally via the call_project_api method or externally through the api/mcp endpoint, enabling controlled access to application-level logic and data services. Acting as an orchestration layer, the API unit enables coordination of multiple subordinate logic units such as get_data, set_data, and batch, allowing compound workflows, transactional operations, and conditional executions to be encapsulated within a single, callable endpoint. This design abstracts complexity and promotes composability of business logic across the application. The API unit includes an interface definition for parameter binding, specifying dynamic input and output mappings. This supports stateless, context-aware executions where external values can be passed into the API call, and structured results returned to the calling layer. Response format configuration is also supported, with output types including json, text, html, and others—allowing precise control over the serialization and consumption of API responses.`);properties_obj.progParams=z.array(ProgParamSchema).optional().describe(`Array of input/output parameter definitions for ${type} interface`);const ApiOutputFormat=z.enum(["json","html","text","xml","csv","pdf"]).describe("Format of the API response: json, html, text, xml, csv, pdf, etc.");properties_obj.apiOutput=ApiOutputFormat.describe("Format of the API response: json, html, text, etc.");main_obj.progDataSource=progDataSource;main_obj.progFields=progFields;main_obj.progEvents=progEvents;main_obj.scriptData=z.object({value:z.string().describe("The return payload template as a stringified object. Placeholder bindings (e.g., @CS_Id) are replaced at runtime")});break;case`alert`:XudaComponentSchema.describe(`The Alert Object is a program-level UI unit in the Xuda platform used to deliver contextual messages and notifications to users or developers at runtime. These alerts can be triggered from within logic flows and offer various display formats (such as toast, modal, browser alert, or console message) based on the use case. The alert object is defined using a structured JSON format and can be embedded in broader program logic. It supports both static and dynamic content, and can optionally create log entries to support audit trails and debugging workflows.`);properties_obj.progParams=z.array(ProgParamSchema).optional().describe(`Array of input/output parameter definitions for ${type} interface`);const AlertType=z.enum(["info","success","warning","error"]);const AlertDisplay=z.enum(["toast","modal","browser","console"]);main_obj.alertData=z.object({alertDisplay:AlertDisplay.describe('Mode of display: "toast", "modal", "browser", or "console"'),alertType:AlertType.describe('Type of message: "warning", "error", "info", or "success"'),alertTitle:z.string().describe("Main content of the alert shown to the user"),alertTitleFx:z.string().optional().describe("Optional dynamic override (e.g., @msg_v) for alert content"),createLog:z.boolean().describe("Whether to generate a system log entry associated with the alert")});break;case`javascript`:XudaComponentSchema.describe(`The javascript object is a functional unit designed to execute JavaScript code within the application context. It can be called from any program using methods such as call_native_javascript, call_evaluate_javascript, execute_native_javascript, or execute_evaluate_javascript. This object includes the following key property: Script – Contains the JavaScript code to be executed, along with any declared dependencies required for execution. The javascript object is ideal for performing advanced logic, custom client-side behavior, or dynamic scripting that extends the capabilities of low-code flows. Xuda also exposes a set of built-in API methods that can be easily called from JavaScript units. These include actions like reading from or writing to Drive, interacting with the Studio API, or performing database operations such as create, update, and delete. These ready-to-use APIs simplify common tasks and allow you to focus on building functionality instead of writing boilerplate code. By centralizing script execution in a modular and reusable way, the JavaScript unit enhances flexibility, promotes clean architecture, and empowers developers to go beyond standard configuration with native scripting power.`);properties_obj.progParams=z.array(ProgParamSchema).optional().describe(`Array of input/output parameter definitions for ${type} interface`);main_obj.scriptData=z.object({value:z.string().describe("JavaScript code to be executed"),dependencies:z.record(z.string()).optional().describe("Optional. Key-value map of external packages required")});break;default:break}return XudaComponentSchema};export const get_fields_z_schema=function(fields={},exclude_props=[],data={}){let inputSchema={};const get_z_item=function(key,val){let prop={};if(val.type==="object"&&val.items){for(const[item_key,item_val]of Object.entries(val.items.properties)){prop[item_key]=get_z_item(item_key,item_val);if(!val?.items?.required?.includes(item_key)){prop[item_key]=prop[item_key].nullable()}}}if(val.type==="array"){prop=get_z_item("",val.items)}let _z=z[val.type](prop);if(!val.mandatory){_z=_z.nullable()}if(val.enum){_z=z.enum(val.enum)}if(data[key]){_z=z.default(data[key])}let valid_values="";if(val.options){valid_values=val.options.join(", ")}if(val.description){const desc=val.name||key.replace(/_/g," ").replace(/\b(\w)/g,(_,char)=>char.toUpperCase());_z=_z.describe((desc?desc+" - ":"")+val.description+(valid_values?" Valid values: "+valid_values:""))}return _z};try{for(const[key,val]of Object.entries(fields)){if(exclude_props.includes(key))continue;inputSchema[key]=get_z_item(key,val)}return inputSchema}catch(error){debugger}};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xuda.io/xuda-studio-checker.min",
3
- "version": "1.0.19",
3
+ "version": "1.0.21",
4
4
  "main": "index.mjs",
5
5
  "type": "module",
6
6
  "description": "Auto-generated build for xuda-studio-checker.min.mjs",