@alilc/lowcode-renderer-core
Version:
renderer core
300 lines (295 loc) • 10.2 kB
JavaScript
import _extends from "@babel/runtime/helpers/extends";
import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/objectWithoutPropertiesLoose";
var _excluded = ["uri", "url", "method", "headers", "params"],
_excluded2 = ["headers"];
/* eslint-disable no-console */
/* eslint-disable max-len */
/* eslint-disable object-curly-newline */
import { isJSFunction } from '@alilc/lowcode-utils';
import { transformArrayToMap, transformStringToFunction } from './common';
import { jsonp, request, get, post } from './request';
import logger from './logger';
var DS_STATUS = {
INIT: 'init',
LOADING: 'loading',
LOADED: 'loaded',
ERROR: 'error'
};
/**
* do request for standard DataSourceType
* @param {DataSourceType} type type of DataSourceItem
* @param {any} options
*/
export function doRequest(type, options) {
// eslint-disable-next-line prefer-const
var uri = options.uri,
url = options.url,
_options$method = options.method,
method = _options$method === void 0 ? 'GET' : _options$method,
headers = options.headers,
params = options.params,
otherProps = _objectWithoutPropertiesLoose(options, _excluded);
otherProps = otherProps || {};
if (type === 'jsonp') {
return jsonp(uri, params, otherProps);
}
if (type === 'fetch') {
switch (method.toUpperCase()) {
case 'GET':
return get(uri, params, headers, otherProps);
case 'POST':
return post(uri, params, headers, otherProps);
default:
return request(uri, method, params, headers, otherProps);
}
}
logger.log("Engine default dataSource does not support type:[" + type + "] dataSource request!", options);
}
// TODO: according to protocol, we should implement errorHandler/shouldFetch/willFetch/requestHandler and isSync controll.
export var DataHelper = /*#__PURE__*/function () {
function DataHelper(comp, config, appHelper, parser) {
/**
* host object that will be "this" object when excuting dataHandler
*
* @type {*}
* @memberof DataHelper
*/
this.host = void 0;
/**
* data source config
*
* @type {DataSource}
* @memberof DataHelper
*/
this.config = void 0;
/**
* a parser function which will be called to process config data
* which eventually will call common/utils.processData() to process data
* (originalConfig) => parsedConfig
* @type {*}
* @memberof DataHelper
*/
this.parser = void 0;
/**
* config.list
*
* @type {any[]}
* @memberof DataHelper
*/
this.ajaxList = void 0;
this.ajaxMap = void 0;
this.dataSourceMap = void 0;
this.appHelper = void 0;
this.host = comp;
this.config = config || {};
this.parser = parser;
this.ajaxList = (config === null || config === void 0 ? void 0 : config.list) || [];
this.ajaxMap = transformArrayToMap(this.ajaxList, 'id');
this.dataSourceMap = this.generateDataSourceMap();
this.appHelper = appHelper;
}
// 更新config,只会更新配置,状态保存;
var _proto = DataHelper.prototype;
_proto.updateConfig = function updateConfig(config) {
var _config,
_this = this;
if (config === void 0) {
config = {};
}
this.config = config;
this.ajaxList = ((_config = config) === null || _config === void 0 ? void 0 : _config.list) || [];
var ajaxMap = transformArrayToMap(this.ajaxList, 'id');
// 删除已经移除的接口
Object.keys(this.ajaxMap).forEach(function (key) {
if (!ajaxMap[key]) {
delete _this.dataSourceMap[key];
}
});
this.ajaxMap = ajaxMap;
// 添加未加入到dataSourceMap中的接口
this.ajaxList.forEach(function (item) {
if (!_this.dataSourceMap[item.id]) {
_this.dataSourceMap[item.id] = {
status: DS_STATUS.INIT,
load: function load() {
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}
// @ts-ignore
return _this.getDataSource.apply(_this, [item.id].concat(args));
}
};
}
});
return this.dataSourceMap;
};
_proto.generateDataSourceMap = function generateDataSourceMap() {
var _this2 = this;
var res = {};
this.ajaxList.forEach(function (item) {
res[item.id] = {
status: DS_STATUS.INIT,
load: function load() {
for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
args[_key2] = arguments[_key2];
}
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
return _this2.getDataSource.apply(_this2, [item.id].concat(args));
}
};
});
return res;
};
_proto.updateDataSourceMap = function updateDataSourceMap(id, data, error) {
this.dataSourceMap[id].error = error || undefined;
this.dataSourceMap[id].data = data;
this.dataSourceMap[id].status = error ? DS_STATUS.ERROR : DS_STATUS.LOADED;
}
/**
* get all dataSourceItems which marked as isInit === true
* @private
* @returns
* @memberof DataHelper
*/;
_proto.getInitDataSourseConfigs = function getInitDataSourseConfigs() {
var _this3 = this;
var initConfigs = this.parser(this.ajaxList).filter(function (item) {
// according to [spec](https://lowcode-engine.cn/lowcode), isInit should be boolean true to be working
if (item.isInit === true) {
_this3.dataSourceMap[item.id].status = DS_STATUS.LOADING;
return true;
}
return false;
});
return initConfigs;
}
/**
* process all dataSourceItems which marked as isInit === true, and get dataSource request results.
* @public
* @returns
* @memberof DataHelper
*/;
_proto.getInitData = function getInitData() {
var _this4 = this;
var initSyncData = this.getInitDataSourseConfigs();
// 所有 datasource 的 datahandler
return this.asyncDataHandler(initSyncData).then(function (res) {
var dataHandler = _this4.config.dataHandler;
return _this4.handleData(null, dataHandler, res, null);
});
};
_proto.getDataSource = function getDataSource(id, params, otherOptions, callback) {
var req = this.parser(this.ajaxMap[id]);
var options = req.options || {};
var callbackFn = callback;
var otherOptionsObj = otherOptions;
if (typeof otherOptions === 'function') {
callbackFn = otherOptions;
otherOptionsObj = {};
}
var _ref = otherOptionsObj || {},
headers = _ref.headers,
otherProps = _objectWithoutPropertiesLoose(_ref, _excluded2);
if (!req) {
logger.warn("getDataSource API named " + id + " not exist");
return;
}
return this.asyncDataHandler([_extends({}, req, {
options: _extends({}, options, {
// 支持参数为array的情况,当参数为array时,不做参数合并
params: Array.isArray(options.params) || Array.isArray(params) ? params || options.params : _extends({}, options.params, params),
headers: _extends({}, options.headers, headers)
}, otherProps)
})]).then(function (res) {
try {
callbackFn && callbackFn(res && res[id]);
} catch (e) {
logger.error('load请求回调函数报错', e);
}
return res && res[id];
})["catch"](function (err) {
try {
callbackFn && callbackFn(null, err);
} catch (e) {
logger.error('load请求回调函数报错', e);
}
return err;
});
};
_proto.asyncDataHandler = function asyncDataHandler(asyncDataList) {
var _this5 = this;
return new Promise(function (resolve, reject) {
var allReq = [];
asyncDataList.forEach(function (req) {
var id = req.id,
type = req.type;
// TODO: need refactoring to remove 'legao' related logic
if (!id || !type || type === 'legao') {
return;
}
allReq.push(req);
});
if (allReq.length === 0) {
resolve({});
}
var res = {};
Promise.all(allReq.map(function (item) {
return new Promise(function (innerResolve) {
var type = item.type,
id = item.id,
dataHandler = item.dataHandler,
options = item.options;
var fetchHandler = function fetchHandler(data, error) {
res[id] = _this5.handleData(id, dataHandler, data, error);
_this5.updateDataSourceMap(id, res[id], error);
innerResolve({});
};
var doFetch = function doFetch(innerType, innerOptions) {
var _doRequest;
(_doRequest = doRequest(innerType, innerOptions)) === null || _doRequest === void 0 ? void 0 : _doRequest.then(function (data) {
fetchHandler(data, undefined);
})["catch"](function (err) {
fetchHandler(undefined, err);
});
};
_this5.dataSourceMap[id].status = DS_STATUS.LOADING;
doFetch(type, options);
});
})).then(function () {
resolve(res);
})["catch"](function (e) {
reject(e);
});
});
}
/**
* process data using dataHandler
*
* @param {(string | null)} id request id, will be used in error message, can be null
* @param {*} dataHandler
* @param {*} data
* @param {*} error
* @returns
* @memberof DataHelper
*/;
_proto.handleData = function handleData(id, dataHandler, data, error) {
var dataHandlerFun = dataHandler;
if (isJSFunction(dataHandler)) {
dataHandlerFun = transformStringToFunction(dataHandler.value);
}
if (!dataHandlerFun || typeof dataHandlerFun !== 'function') {
return data;
}
try {
return dataHandlerFun.call(this.host, data, error);
} catch (e) {
if (id) {
logger.error("[" + id + "]\u5355\u4E2A\u8BF7\u6C42\u6570\u636E\u5904\u7406\u51FD\u6570\u8FD0\u884C\u51FA\u9519", e);
} else {
logger.error('请求数据处理函数运行出错', e);
}
}
};
return DataHelper;
}();