@xuda.io/runtime-bundle
Version:
The Xuda Runtime Bundle refers to a collection of scripts and libraries packaged together to provide the necessary runtime environment for executing plugins or components in the Xuda platform.
401 lines (345 loc) • 11.8 kB
JavaScript
export class XudaModule {
constructor(e) {
this.func = e.func;
this.glb = e.glb;
this.SESSION_OBJ = e.SESSION_OBJ;
this.SESSION_ID = e.SESSION_ID;
this.APP_OBJ = e.APP_OBJ;
this.dsSession = e.dsSession;
this.job_id = e.job_id;
this._session = this.SESSION_OBJ[this.SESSION_ID];
return this;
}
async get_field_value(field_id) {
if (!field_id) {
console.error('xu.getFieldValue: field_id cannot be empty');
return false;
}
let ret_get_value = await this.func.datasource.get_value(this.SESSION_ID, field_id, this.dsSession);
if (!ret_get_value.found) {
console.error(`xu.getFieldValue: ${field_id} field not found`);
return false;
}
return ret_get_value.ret.value;
}
async set_field_value(field_id, value, avoid_refresh) {
if (!field_id) {
console.error('xu.setFieldValue: field_id cannot be empty');
return false;
}
if (typeof value === 'undefined') {
console.error(`xu.setFieldValue: ${field_id} - value cannot be undefined`);
return false;
}
let ret_get_value = await this.func.datasource.get_value(this.SESSION_ID, field_id, this.dsSession);
if (!ret_get_value.found) {
console.error(`xu.setFieldValue: ${field_id} field not found`);
return false;
}
let _ds = this._session.DS_GLB[ret_get_value.dsSessionP];
const datasource_changes = {
[_ds.dsSession]: {
[ret_get_value.currentRecordId]: { [field_id]: value },
},
};
return await this.func.datasource.update(this.SESSION_ID, datasource_changes, null, avoid_refresh);
}
async invoke_event(event_id) {
if (!event_id) {
console.error('xu.invokeEvent: event_id cannot be empty');
return false;
}
let ds;
for await (const [key, val] of Object.entries(Object.assign([], this._session.DS_GLB).reverse())) {
let ds_val = val;
let ds_key = ds_val.dsSession;
const _view_obj = await this.func.utils.VIEWS_OBJ.get(this.SESSION_ID, ds_val.prog_id);
if (_.isEmpty(_view_obj.progEvents)) continue;
if (ds) break;
for await (const [key, val] of Object.entries(_view_obj.progEvents)) {
if (val?.data?.type === 'user_defined' && val.data.event_name === event_id) {
ds = ds_key;
break;
}
}
}
if (typeof ds === 'undefined') {
this.reject('xu.invokeEvent error', `${event_id} event_id not found`, this.job_id);
return false;
}
return this.func.events.validate(this.SESSION_ID, 'user_defined', ds, event_id);
}
async read_drive(filename, cb) {
try {
const response = await fetch(`https://${this._session.domain}/workspace-drive/` + filename + '&' + this._session.gtp_token);
if (cb) {
return cb(await response.json());
}
return await response.json();
} catch (e) {
console.error(e);
this.reject('xu.readDrive error', e, this.job_id);
}
}
async write_drive(stream, filename, make_public, cb) {
var data = {
app_id: this._session.app_id,
gtp_token: this._session.gtp_token,
app_token: this._session.app_token,
req_from_api: 'true',
public: make_public ? 'true' : '',
};
const form = new FormData();
for (const [key, val] of Object.entries(data)) {
form.append(key, val);
}
form.append('file', stream, filename);
try {
const response = await fetch(this.func.common.get_url(this.SESSION_ID, 'rpi', 'runtime_upload_file'), {
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify(form),
});
if (cb) {
return cb(await response.json());
}
return await response.json();
} catch (e) {
console.error(e);
this.reject('xu.writeDrive error', e, this.job_id);
}
}
resolve(cb, job_id) {
if (job_id) {
this.func.events.delete_job(this.SESSION_ID, job_id);
}
if (cb) {
cb();
}
}
reject(msg, details, job_id) {
if (job_id) {
this.func.events.delete_job(this.SESSION_ID, job_id);
}
this.log('E', msg, details);
}
log(type, msg, details) {
this.func.utils.debug_report(this.SESSION_ID, msg, details, type);
}
alert(type, display, msg, details) {
this.func.utils.alerts.execute(
this.SESSION_ID,
type, // error, warn, info, log
display, // console, modal, toast, browser
details,
msg,
);
}
async call_project_api(prog_id, params, cb) {
const _prog_obj = await this.func.utils.DOCS_OBJ.get(this.SESSION_ID, prog_id);
if (_prog_obj?.properties?.menuType !== 'api') {
return this.reject('xu.callApiProgram error', `${prog_id} is not an API program`, this.job_id);
}
// also call internal API if call made from the server itself
if (this._session.engine_mode === 'live_preview' || typeof IS_PROCESS_SERVER !== 'undefined') {
const ret = await this.func.datasource.prepare(this.SESSION_ID, prog_id, null, 0, null, null, null, null, null, null, 'api', null, null, null, params);
try {
const _ds = this._session.DS_GLB[ret.dsSessionP];
if (typeof _ds.api_rendered_output === 'undefined' || typeof _ds.tree_obj.apiOutput === 'undefined' || !_ds.tree_obj.apiOutput) {
throw new Error('undefined api_rendered_output/apiOutput');
}
if (_ds.tree_obj.apiOutput === 'json') {
try {
return JSON5.parse(_ds.api_rendered_output);
} catch (err) {
console.error(err);
return {};
}
}
return _ds.api_rendered_output;
} catch (e) {
this.reject('xu.call_project_api error', e.message || e, this.job_id);
}
}
// miniapp
if (['miniapp'].includes(this._session.engine_mode)) {
try {
const response = await fetch(`https://${this._session.domain}/api`, {
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({ ...params, ...{ prog_id } }),
});
if (cb) {
return cb(await response.json());
}
return await response.json();
} catch (e) {
console.error(e);
this.reject('xu.get_table_data error', e, this.job_id);
}
}
// deployments
try {
const response = await fetch(`https://${this._session.domain}/execute_api_program`, {
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({ ...params, ...{ prog_id } }),
});
if (cb) {
return cb(await response.json());
}
return await response.json();
} catch (e) {
console.error(e);
this.reject('xu.get_table_data error', e, this.job_id);
}
}
async call_system_api(api_method, payload = {}, cb) {
try {
let body = {
...{
app_id: this._session.app_id,
app_id_query: this._session.app_id,
app_token: this._session.app_token,
},
...payload,
};
const response = await fetch(`https://${this._session.domain}/cpi/${api_method}`, {
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify(body),
});
// if (!response.ok) {
// return { code: response.status, data: response.statusText };
// }
const json = await response.json();
if (cb) {
return cb(json);
}
return json;
} catch (e) {
console.error(e);
this.reject('xu.call_system_api error', e, this.job_id);
}
}
async call_external_api(method, url, payload = {}, cb) {
try {
let json = {
...{
app_id: this._session.app_id,
app_id_query: this._session.app_id,
app_token: this._session.app_token,
},
...payload,
};
const response = await fetch(`https://${url}`, {
method,
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify(json),
});
if (cb) {
return cb(await response.json());
}
return await response.json();
} catch (e) {
console.error(e);
this.reject('xu.call_external_api error', e, this.job_id);
}
}
async call_javascript(prog_id, params = {}, evaluate = false) {
try {
const module = await this.func.common.get_module(this.SESSION_ID, 'xuda-event-javascript-module.mjs');
const result = await module.call_javascript(this.SESSION_ID, this.job_id, { prog: prog_id, parameters: params }, this.dsSession, evaluate);
return result;
} catch (e) {
console.error(e);
this.reject('xu.call_javascript error', e, this.job_id);
}
}
async dbs_create(table_id, data, cb) {
const _table_obj = await this.func.utils.DOCS_OBJ.get(this.SESSION_ID, table_id);
if (_table_obj?.properties?.menuType !== 'table') {
return this.reject('xu.dbsCreate error', `${table_id} is not a table`, this.job_id);
}
try {
const ret = await this.func.common.db(this.SESSION_ID, 'dbs_create', { table_id, table_data: data });
if (cb) {
return cb(ret);
}
return ret;
} catch (e) {
console.error(e);
this.reject('xu.dbs_create error', e, this.job_id);
}
}
async dbs_read(table_id, selector = {}, fields = [], sort, limit = 999, skip, cb) {
const _table_obj = await this.func.utils.DOCS_OBJ.get(this.SESSION_ID, table_id);
if (_table_obj?.properties?.menuType !== 'table') {
return this.reject('xu.dbsRead error', `${table_id} is not a table`, this.job_id);
}
let data = { fields, table_id, dataSourceFilterModelType: 'query', filterModelMongo: selector, limit, skip, sort };
try {
const ret = await this.func.common.db(this.SESSION_ID, 'dbs_read', data);
if (cb) {
return cb(ret);
}
return ret;
} catch (e) {
console.error(e);
this.reject('xu.dbs_read error', e, this.job_id);
}
}
async dbs_update(table_id, row_id, data, cb) {
const _table_obj = await this.func.utils.DOCS_OBJ.get(this.SESSION_ID, table_id);
if (_table_obj?.properties?.menuType !== 'table') {
return this.reject('xu.dbsUpdate error', `${table_id} is not a table`, this.job_id);
}
if (!row_id) {
return this.reject('xu.dbsDelete error', `row_id is a mandatory field`, this.job_id);
}
try {
const ret = await this.func.common.db(this.SESSION_ID, 'dbs_update', { table_id, row_id, table_data: data });
if (cb) {
return cb(ret);
}
return ret;
} catch (e) {
console.error(e);
this.reject('xu.dbs_update error', e, this.job_id);
}
}
async dbs_delete(table_id, row_id, cb) {
const _table_obj = await this.func.utils.DOCS_OBJ.get(this.SESSION_ID, table_id);
if (_table_obj?.properties?.menuType !== 'table') {
return this.reject('xu.dbsDelete error', `${table_id} is not a table`, this.job_id);
}
if (!row_id) {
return this.reject('xu.dbsDelete error', `row_id is a mandatory field`, this.job_id);
}
try {
const ret = await this.func.common.db(this.SESSION_ID, 'dbs_delete', { table_id, ids: [row_id] });
if (cb) {
return cb(ret);
}
return ret;
} catch (e) {
console.error(e);
this.reject('xu.dbs_delete error', e, this.job_id);
}
}
}