ddm-plugin-dubbo-support 0.0.5 → 0.0.7
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.
- package/LICENSE +201 -201
- package/README.md +49 -49
- package/dist/i18n.js +3 -0
- package/dist/index.js +98 -42
- package/dist/renderer.js +320 -187
- package/package.json +144 -51
- package/dist/renderIndex.js +0 -292
- package/public/.DS_Store +0 -0
- package/public/jar/.DS_Store +0 -0
package/dist/index.js
CHANGED
|
@@ -29,12 +29,12 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
29
29
|
|
|
30
30
|
|
|
31
31
|
class TelnetInvoker {
|
|
32
|
-
/**
|
|
33
|
-
* 调用Dubbo接口
|
|
34
|
-
* @param {Provider} provder 提供者信息
|
|
35
|
-
* @param {*} methodInfo 方法名
|
|
36
|
-
* @param {*} code 参数信息
|
|
37
|
-
* @returns
|
|
32
|
+
/**
|
|
33
|
+
* 调用Dubbo接口
|
|
34
|
+
* @param {Provider} provder 提供者信息
|
|
35
|
+
* @param {*} methodInfo 方法名
|
|
36
|
+
* @param {*} code 参数信息
|
|
37
|
+
* @returns
|
|
38
38
|
*/
|
|
39
39
|
invokeMethod(provder, methodInfo, code) {
|
|
40
40
|
const telnetPort = provder.qosPort || provder.port;
|
|
@@ -88,16 +88,16 @@ class TelnetInvoker {
|
|
|
88
88
|
});
|
|
89
89
|
tSocket.write(_common_TelnetUtils_js__WEBPACK_IMPORTED_MODULE_5__["default"].buildInvokeCommand({
|
|
90
90
|
serviceName,
|
|
91
|
-
method: methodInfo.
|
|
91
|
+
method: methodInfo.methodName,
|
|
92
92
|
params
|
|
93
93
|
}));
|
|
94
94
|
});
|
|
95
95
|
}
|
|
96
96
|
|
|
97
|
-
/**
|
|
98
|
-
* 解析响应信息
|
|
99
|
-
* @param {String} result
|
|
100
|
-
* @returns
|
|
97
|
+
/**
|
|
98
|
+
* 解析响应信息
|
|
99
|
+
* @param {String} result
|
|
100
|
+
* @returns
|
|
101
101
|
*/
|
|
102
102
|
resolveResponse(result) {
|
|
103
103
|
// dubbo返回格式分为三部分,第一部分为
|
|
@@ -661,7 +661,7 @@ class AppProxy {
|
|
|
661
661
|
/***/ ((module) => {
|
|
662
662
|
|
|
663
663
|
"use strict";
|
|
664
|
-
module.exports = /*#__PURE__*/JSON.parse('{"name":"ddm-plugin-dubbo-support","version":"0.0.
|
|
664
|
+
module.exports = /*#__PURE__*/JSON.parse('{"name":"ddm-plugin-dubbo-support","version":"0.0.7","description":"Dubbo-Desktop-Manager插件-支持Dubbo框架","main":"dist/index.js","rendererMain":"dist/renderer.js","i18nMain":"dist/i18n.js","files":["README.md","logo.png","public/**","dist/**","docs/**","java-invoke/**"],"scripts":{"dev":"webpack","gen:keywords":"node ./scripts/gen-keywords.js","prepublishOnly":"npm run gen:keywords","publish":"webpack && npm publish"},"keywords":["Dubbo-Desktop-Manager","ddm-plugin","ddm","dubbo","dubbo service invoke","dubbo manager","dubbo console","dubbo admin","-","-s","-su","-sup","-supp","-suppo","-suppor","-support","b","bb","bbo","bbo-","bbo-s","bbo-su","bbo-sup","bbo-supp","bbo-suppo","bbo-suppor","bbo-support","bo","bo-","bo-s","bo-su","bo-sup","bo-supp","bo-suppo","bo-suppor","bo-support","d","du","dub","dubb","dubbo-","dubbo-s","dubbo-su","dubbo-sup","dubbo-supp","dubbo-suppo","dubbo-suppor","dubbo-support","o","o-","o-s","o-su","o-sup","o-supp","o-suppo","o-suppor","o-support","or","ort","p","po","por","port","pp","ppo","ppor","pport","r","rt","s","su","sup","supp","suppo","suppor","support","t","u","ub","ubb","ubbo","ubbo-","ubbo-s","ubbo-su","ubbo-sup","ubbo-supp","ubbo-suppo","ubbo-suppor","ubbo-support","up","upp","uppo","uppor","upport"],"homepage":"https://github.com/ddm-plugin/ddm-plugin-dubbo-support","author":"qiaolin","license":"Apache 2.0","devDependencies":{"@babel/core":"^7.24.7","babel-cli":"^6.26.0","babel-loader":"^8.2.5","css-loader":"^6.11.0","js-yaml":"^4.1.0","json-bigint":"^1.0.0","moment":"^2.29.1","node-zookeeper-client":"^1.1.1","qs":"^6.11.0","style-loader":"^3.3.4","telnet-stream":"^1.0.5","urijs":"^1.19.11","vue":"^2.6.11","vue-loader":"15.11.1","vue-style-loader":"^4.1.3","vue-template-compiler":"^2.6.11","webpack":"^5.92.1","webpack-cli":"^5.1.4"},"engines":{"ddm":">=1.1.0 <3.0.0"}}');
|
|
665
665
|
|
|
666
666
|
/***/ }),
|
|
667
667
|
/* 16 */
|
|
@@ -4505,10 +4505,10 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
4505
4505
|
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
4506
4506
|
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
|
|
4507
4507
|
/* harmony export */ });
|
|
4508
|
-
/**
|
|
4509
|
-
* 执行结果
|
|
4510
|
-
* @param {String}} data 响应的数据
|
|
4511
|
-
* @param {*} elapsedTime 耗时
|
|
4508
|
+
/**
|
|
4509
|
+
* 执行结果
|
|
4510
|
+
* @param {String}} data 响应的数据
|
|
4511
|
+
* @param {*} elapsedTime 耗时
|
|
4512
4512
|
*/
|
|
4513
4513
|
class InvokeResult {
|
|
4514
4514
|
constructor(data, elapsedTime) {
|
|
@@ -4529,8 +4529,8 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
4529
4529
|
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
4530
4530
|
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
|
|
4531
4531
|
/* harmony export */ });
|
|
4532
|
-
/**
|
|
4533
|
-
* 构建invoke命令
|
|
4532
|
+
/**
|
|
4533
|
+
* 构建invoke命令
|
|
4534
4534
|
*/
|
|
4535
4535
|
function buildInvokeCommand({
|
|
4536
4536
|
serviceName,
|
|
@@ -4607,7 +4607,7 @@ class JavaInvoker {
|
|
|
4607
4607
|
protocol: provder.protocol,
|
|
4608
4608
|
address: `${ip}:${port}`,
|
|
4609
4609
|
version: provder.version,
|
|
4610
|
-
method: methodInfo.
|
|
4610
|
+
method: methodInfo.methodName,
|
|
4611
4611
|
argsList: this.getMethodParameterTypes(methodInfo),
|
|
4612
4612
|
dataList: dataList
|
|
4613
4613
|
};
|
|
@@ -4743,6 +4743,12 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
4743
4743
|
|
|
4744
4744
|
|
|
4745
4745
|
const PRIVDER_PREFIX = "/dubbo";
|
|
4746
|
+
|
|
4747
|
+
/**
|
|
4748
|
+
* Zookeeper 数据源操作类,提供 Dubbo 服务的注册、查询、配置等功能。
|
|
4749
|
+
* @typedef {import('@/main/@types/DataSource').DataSource} DataSource
|
|
4750
|
+
* @implements {DataSource}
|
|
4751
|
+
*/
|
|
4746
4752
|
class ZookeeperDataSource {
|
|
4747
4753
|
constructor(app, invoker) {
|
|
4748
4754
|
this.invoker = invoker;
|
|
@@ -4781,6 +4787,8 @@ class ZookeeperDataSource {
|
|
|
4781
4787
|
metadata.methods.forEach(method => {
|
|
4782
4788
|
methodList.push({
|
|
4783
4789
|
...method,
|
|
4790
|
+
name: `${method.name}(${method.parameterTypes.map(pp => pp.substring(pp.lastIndexOf(".") + 1))})`,
|
|
4791
|
+
methodName: method.name,
|
|
4784
4792
|
defaultParameter: JSON.stringify(_main_generator_ParamGeneratorAdapter__WEBPACK_IMPORTED_MODULE_5__["default"].generateParam(metadata, method.name), null, 2) || "[]"
|
|
4785
4793
|
});
|
|
4786
4794
|
});
|
|
@@ -4864,7 +4872,7 @@ class ZookeeperDataSource {
|
|
|
4864
4872
|
weight: urlData.params.weight,
|
|
4865
4873
|
deprecated: urlData.params.deprecated,
|
|
4866
4874
|
protocol: urlData.protocol,
|
|
4867
|
-
methods: urlData.params.methods.split(","),
|
|
4875
|
+
methods: Array.from(new Set((urlData.params.methods || "").split(",").filter(Boolean))),
|
|
4868
4876
|
generic: urlData.params.generic,
|
|
4869
4877
|
providerVersion: urlData.params.revision,
|
|
4870
4878
|
dubboVersion: urlData.params.release,
|
|
@@ -27032,10 +27040,10 @@ class DubboConfigurationUtils {
|
|
|
27032
27040
|
return doc;
|
|
27033
27041
|
}
|
|
27034
27042
|
|
|
27035
|
-
/**
|
|
27036
|
-
* 获取被禁用的提供者地址列表
|
|
27037
|
-
* @param {string} serviceName
|
|
27038
|
-
* @param {string[]} versions 多个版本
|
|
27043
|
+
/**
|
|
27044
|
+
* 获取被禁用的提供者地址列表
|
|
27045
|
+
* @param {string} serviceName
|
|
27046
|
+
* @param {string[]} versions 多个版本
|
|
27039
27047
|
*/
|
|
27040
27048
|
async getDisableAddresses(doc) {
|
|
27041
27049
|
if (!doc || !doc.configs) {
|
|
@@ -27072,8 +27080,8 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
27072
27080
|
|
|
27073
27081
|
|
|
27074
27082
|
class ParamGeneratorAdapter {
|
|
27075
|
-
/**
|
|
27076
|
-
* 生成参数
|
|
27083
|
+
/**
|
|
27084
|
+
* 生成参数
|
|
27077
27085
|
*/
|
|
27078
27086
|
generateParam(mateData, methodName) {
|
|
27079
27087
|
// 当前提供者使用的dubbo版本
|
|
@@ -27098,12 +27106,12 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
27098
27106
|
/* harmony import */ var _ValueGenerator_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(221);
|
|
27099
27107
|
|
|
27100
27108
|
|
|
27101
|
-
/**
|
|
27102
|
-
* Dubbo2.7+版本 参数生成器
|
|
27109
|
+
/**
|
|
27110
|
+
* Dubbo2.7+版本 参数生成器
|
|
27103
27111
|
*/
|
|
27104
27112
|
class ParamGeneratorDubbo2_7 {
|
|
27105
|
-
/**
|
|
27106
|
-
* 生成参数
|
|
27113
|
+
/**
|
|
27114
|
+
* 生成参数
|
|
27107
27115
|
*/
|
|
27108
27116
|
generateParam(mateData, methodName) {
|
|
27109
27117
|
const method = this.findMethodInfo(mateData, methodName);
|
|
@@ -48657,13 +48665,13 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
48657
48665
|
/* harmony import */ var _ValueGenerator_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(221);
|
|
48658
48666
|
|
|
48659
48667
|
|
|
48660
|
-
/**
|
|
48661
|
-
* Dubbo3+版本 参数生成器
|
|
48668
|
+
/**
|
|
48669
|
+
* Dubbo3+版本 参数生成器
|
|
48662
48670
|
*/
|
|
48663
48671
|
|
|
48664
48672
|
class ParamGeneratorDubbo3 {
|
|
48665
|
-
/**
|
|
48666
|
-
* 生成参数
|
|
48673
|
+
/**
|
|
48674
|
+
* 生成参数
|
|
48667
48675
|
*/
|
|
48668
48676
|
generateParam(mateData, methodName) {
|
|
48669
48677
|
let method = mateData.methods.find(m => methodName == m.name);
|
|
@@ -48838,17 +48846,25 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
48838
48846
|
|
|
48839
48847
|
|
|
48840
48848
|
|
|
48849
|
+
|
|
48850
|
+
/**
|
|
48851
|
+
* Nacos 数据源操作类,提供 Dubbo 服务的注册、查询、配置等功能。
|
|
48852
|
+
* @typedef {import('@/main/@types/DataSource').DataSource} DataSource
|
|
48853
|
+
* @implements {DataSource}
|
|
48854
|
+
*/
|
|
48841
48855
|
class NacosDataSource {
|
|
48842
48856
|
constructor(appCore, invoker) {
|
|
48843
48857
|
this.appCore = appCore;
|
|
48844
48858
|
this.invoker = invoker;
|
|
48859
|
+
this.tokenCache = new Map();
|
|
48845
48860
|
}
|
|
48846
48861
|
async getServiceList(dataSourceInfo) {
|
|
48847
48862
|
const params = {
|
|
48848
48863
|
pageNo: 1,
|
|
48849
48864
|
pageSize: 100,
|
|
48850
48865
|
namespaceId: dataSourceInfo.namespaceId || "",
|
|
48851
|
-
groupName: dataSourceInfo.groupName || ""
|
|
48866
|
+
groupName: dataSourceInfo.groupName || "",
|
|
48867
|
+
accessToken: this.getAccessToken(dataSourceInfo)
|
|
48852
48868
|
};
|
|
48853
48869
|
// `http://127.0.0.1:8848/nacos/v1/ns/service/list?pageNo=1&pageSize=20`
|
|
48854
48870
|
const url = `${dataSourceInfo.address}/nacos/v1/ns/service/list`;
|
|
@@ -48894,7 +48910,8 @@ class NacosDataSource {
|
|
|
48894
48910
|
const params = {
|
|
48895
48911
|
serviceName: serviceInfo.uniqueServiceName,
|
|
48896
48912
|
namespaceId: dataSourceInfo.namespaceId || "",
|
|
48897
|
-
groupName: dataSourceInfo.groupName || ""
|
|
48913
|
+
groupName: dataSourceInfo.groupName || "",
|
|
48914
|
+
accessToken: this.getAccessToken(dataSourceInfo)
|
|
48898
48915
|
};
|
|
48899
48916
|
const response = await this.appCore.axios.get(url, {
|
|
48900
48917
|
params
|
|
@@ -48917,6 +48934,8 @@ class NacosDataSource {
|
|
|
48917
48934
|
metadata.methods.forEach(method => {
|
|
48918
48935
|
methodList.push({
|
|
48919
48936
|
...method,
|
|
48937
|
+
name: `${method.name}(${method.parameterTypes.map(pp => pp.substring(pp.lastIndexOf(".") + 1))})`,
|
|
48938
|
+
methodName: method.name,
|
|
48920
48939
|
defaultParameter: JSON.stringify(_main_generator_ParamGeneratorAdapter__WEBPACK_IMPORTED_MODULE_4__["default"].generateParam(metadata, method.name), null, 2) || "[]"
|
|
48921
48940
|
});
|
|
48922
48941
|
});
|
|
@@ -48941,7 +48960,8 @@ class NacosDataSource {
|
|
|
48941
48960
|
let params = {
|
|
48942
48961
|
serviceName: serviceInfo.uniqueServiceName,
|
|
48943
48962
|
namespaceId: dataSourceInfo.namespaceId || "",
|
|
48944
|
-
groupName: dataSourceInfo.groupName || ""
|
|
48963
|
+
groupName: dataSourceInfo.groupName || "",
|
|
48964
|
+
accessToken: this.getAccessToken(dataSourceInfo)
|
|
48945
48965
|
};
|
|
48946
48966
|
let response = await this.appCore.axios.get(url, {
|
|
48947
48967
|
params
|
|
@@ -48985,7 +49005,8 @@ class NacosDataSource {
|
|
|
48985
49005
|
dataId: this.buildDataId(providerInfo),
|
|
48986
49006
|
group: dataSourceInfo.group || 'dubbo',
|
|
48987
49007
|
namespaceId: dataSourceInfo.namespaceId || "",
|
|
48988
|
-
tenant: dataSourceInfo.namespaceId || ""
|
|
49008
|
+
tenant: dataSourceInfo.namespaceId || "",
|
|
49009
|
+
accessToken: this.getAccessToken(dataSourceInfo)
|
|
48989
49010
|
};
|
|
48990
49011
|
|
|
48991
49012
|
// 有配置项,保存,反之删除
|
|
@@ -49009,7 +49030,8 @@ class NacosDataSource {
|
|
|
49009
49030
|
group: dataSourceInfo.group || 'dubbo',
|
|
49010
49031
|
namespaceId: dataSourceInfo.namespaceId || "",
|
|
49011
49032
|
tenant: dataSourceInfo.namespaceId || "",
|
|
49012
|
-
show: 'all'
|
|
49033
|
+
show: 'all',
|
|
49034
|
+
accessToken: this.getAccessToken(dataSourceInfo)
|
|
49013
49035
|
};
|
|
49014
49036
|
const response = await this.appCore.axios.get(url, {
|
|
49015
49037
|
params
|
|
@@ -49019,6 +49041,22 @@ class NacosDataSource {
|
|
|
49019
49041
|
}
|
|
49020
49042
|
return null;
|
|
49021
49043
|
}
|
|
49044
|
+
async getAccessToken(dataSourceInfo) {
|
|
49045
|
+
if (!dataSourceInfo.username) {
|
|
49046
|
+
return null;
|
|
49047
|
+
}
|
|
49048
|
+
|
|
49049
|
+
// http://127.0.0.1:8848/nacos/v1/auth/login
|
|
49050
|
+
let url = `${dataSourceInfo.address}/nacos/v1/auth/login`;
|
|
49051
|
+
let params = {
|
|
49052
|
+
username: dataSourceInfo.username,
|
|
49053
|
+
password: dataSourceInfo.password
|
|
49054
|
+
};
|
|
49055
|
+
|
|
49056
|
+
// 调用登录接口
|
|
49057
|
+
const response = await this.appCore.axios.post(url, qs__WEBPACK_IMPORTED_MODULE_5___default().stringify(params));
|
|
49058
|
+
return response.data.accessToken;
|
|
49059
|
+
}
|
|
49022
49060
|
buildMataDataPath(providerInfo) {
|
|
49023
49061
|
let {
|
|
49024
49062
|
application,
|
|
@@ -49052,7 +49090,7 @@ class NacosDataSource {
|
|
|
49052
49090
|
weight: data.weight,
|
|
49053
49091
|
disabled: !data.enabled,
|
|
49054
49092
|
generic: metadata.generic,
|
|
49055
|
-
methods: metadata.methods.split(","),
|
|
49093
|
+
methods: Array.from(new Set((metadata.methods || "").split(",").filter(Boolean))),
|
|
49056
49094
|
// 2.7x就是dubbo端口,3.0之后是指定的端口
|
|
49057
49095
|
protocol: metadata.protocol,
|
|
49058
49096
|
qosPort: data.qosPort || data.port
|
|
@@ -51661,6 +51699,12 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
51661
51699
|
|
|
51662
51700
|
|
|
51663
51701
|
|
|
51702
|
+
|
|
51703
|
+
/**
|
|
51704
|
+
* Dubbo Admin 数据源操作类,提供 Dubbo 服务的注册、查询、配置等功能。
|
|
51705
|
+
* @typedef {import('@/main/@types/DataSource').DataSource} DataSource
|
|
51706
|
+
* @implements {DataSource}
|
|
51707
|
+
*/
|
|
51664
51708
|
class DubboAdminDataSource {
|
|
51665
51709
|
constructor(appCore) {
|
|
51666
51710
|
this.appCore = appCore;
|
|
@@ -51707,6 +51751,8 @@ class DubboAdminDataSource {
|
|
|
51707
51751
|
data.metadata.methods.forEach(method => {
|
|
51708
51752
|
methodList.push({
|
|
51709
51753
|
...method,
|
|
51754
|
+
name: `${method.name}(${method.parameterTypes.map(pp => pp.substring(pp.lastIndexOf(".") + 1))})`,
|
|
51755
|
+
methodName: method.name,
|
|
51710
51756
|
defaultParameter: JSON.stringify(_main_generator_ParamGeneratorAdapter__WEBPACK_IMPORTED_MODULE_4__["default"].generateParam(data.metadata, method.name), null, 2) || "[]"
|
|
51711
51757
|
});
|
|
51712
51758
|
});
|
|
@@ -51727,6 +51773,9 @@ class DubboAdminDataSource {
|
|
|
51727
51773
|
}
|
|
51728
51774
|
async getConsumerList(dataSourceInfo, serviceInfo) {
|
|
51729
51775
|
const data = await this.getServiceData(dataSourceInfo, serviceInfo);
|
|
51776
|
+
if (!data || !data.consumers) {
|
|
51777
|
+
return [];
|
|
51778
|
+
}
|
|
51730
51779
|
let array = new Array();
|
|
51731
51780
|
for (let i = 0; i < data.consumers.length; i++) {
|
|
51732
51781
|
array.push(this.parseConsumerInfo(data.consumers[i]));
|
|
@@ -51741,6 +51790,9 @@ class DubboAdminDataSource {
|
|
|
51741
51790
|
'Authorization': await this.getToken(dataSourceInfo)
|
|
51742
51791
|
}
|
|
51743
51792
|
});
|
|
51793
|
+
if (!response.data || !response.data.application) {
|
|
51794
|
+
throw new Error(this.appCore.pluginT('dubbo.dubboAdmin.errorGetServiceData'));
|
|
51795
|
+
}
|
|
51744
51796
|
return response.data;
|
|
51745
51797
|
}
|
|
51746
51798
|
async disableProvider(dataSourceInfo, serviceInfo, providerInfo) {
|
|
@@ -51805,7 +51857,7 @@ class DubboAdminDataSource {
|
|
|
51805
51857
|
const startTime = new Date().getTime();
|
|
51806
51858
|
const data = {
|
|
51807
51859
|
service: serviceInfo.uniqueServiceName,
|
|
51808
|
-
method: methodInfo.
|
|
51860
|
+
method: methodInfo.methodName,
|
|
51809
51861
|
parameterTypes: this.getMethodParameterTypes(methodInfo),
|
|
51810
51862
|
params: JSON.parse(code)
|
|
51811
51863
|
};
|
|
@@ -51850,7 +51902,7 @@ class DubboAdminDataSource {
|
|
|
51850
51902
|
group: "",
|
|
51851
51903
|
providerVersion: urlData.params.revision,
|
|
51852
51904
|
dubboVersion: urlData.params.release,
|
|
51853
|
-
methods: urlData.params.methods.split(","),
|
|
51905
|
+
methods: Array.from(new Set((urlData.params.methods || "").split(",").filter(Boolean))),
|
|
51854
51906
|
protocol: urlData.protocol,
|
|
51855
51907
|
generic: urlData.params.generic,
|
|
51856
51908
|
deprecated: urlData.params.deprecated,
|
|
@@ -52006,6 +52058,10 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
52006
52058
|
|
|
52007
52059
|
|
|
52008
52060
|
|
|
52061
|
+
|
|
52062
|
+
/**
|
|
52063
|
+
* @param {import('@/main/@types/AppPlugin').AppPlugin} app
|
|
52064
|
+
*/
|
|
52009
52065
|
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (app => {
|
|
52010
52066
|
Map.prototype.computeIfAbsent = async function (key, fun) {
|
|
52011
52067
|
if (!this.has(key)) {
|