@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.
532 lines (458 loc) • 12.2 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);
}
}
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);
}
}
}