@lcap/nasl 3.8.0-beta.6 → 3.8.0-beta.8
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/.mocharc.js +1 -0
- package/out/common/BaseNode.d.ts +19 -3
- package/out/common/BaseNode.js +85 -7
- package/out/common/BaseNode.js.map +1 -1
- package/out/concepts/AbstractInterface__.js.map +1 -1
- package/out/concepts/Annotation__.js +1 -1
- package/out/concepts/Annotation__.js.map +1 -1
- package/out/concepts/App__.d.ts +3 -0
- package/out/concepts/App__.js +964 -4
- package/out/concepts/App__.js.map +1 -1
- package/out/concepts/Argument__.js +3 -3
- package/out/concepts/Argument__.js.map +1 -1
- package/out/concepts/BatchAssignment__.d.ts +1 -1
- package/out/concepts/BatchAssignment__.js +3 -3
- package/out/concepts/BatchAssignment__.js.map +1 -1
- package/out/concepts/BindAttribute__.js +5 -6
- package/out/concepts/BindAttribute__.js.map +1 -1
- package/out/concepts/BindDirective__.js +3 -4
- package/out/concepts/BindDirective__.js.map +1 -1
- package/out/concepts/BusinessComponent__.d.ts +2 -0
- package/out/concepts/BusinessComponent__.js +48 -0
- package/out/concepts/BusinessComponent__.js.map +1 -1
- package/out/concepts/BusinessLogic__.d.ts +1 -0
- package/out/concepts/BusinessLogic__.js +10 -0
- package/out/concepts/BusinessLogic__.js.map +1 -1
- package/out/concepts/CallEvent__.d.ts +2 -0
- package/out/concepts/CallEvent__.js +75 -0
- package/out/concepts/CallEvent__.js.map +1 -1
- package/out/concepts/CallInterface__.d.ts +1 -0
- package/out/concepts/CallInterface__.js +26 -15
- package/out/concepts/CallInterface__.js.map +1 -1
- package/out/concepts/CallLogic__.d.ts +4 -0
- package/out/concepts/CallLogic__.js +59 -3
- package/out/concepts/CallLogic__.js.map +1 -1
- package/out/concepts/Entity__.d.ts +3 -3
- package/out/concepts/Entity__.js +4 -0
- package/out/concepts/Entity__.js.map +1 -1
- package/out/concepts/Event__.d.ts +2 -0
- package/out/concepts/Event__.js +30 -0
- package/out/concepts/Event__.js.map +1 -1
- package/out/concepts/FrontendType__.d.ts +2 -0
- package/out/concepts/FrontendType__.js +32 -0
- package/out/concepts/FrontendType__.js.map +1 -1
- package/out/concepts/Frontend__.d.ts +2 -0
- package/out/concepts/Frontend__.js +48 -0
- package/out/concepts/Frontend__.js.map +1 -1
- package/out/concepts/IfStatement__.js +6 -6
- package/out/concepts/IfStatement__.js.map +1 -1
- package/out/concepts/InterfaceParam__.d.ts +1 -0
- package/out/concepts/InterfaceParam__.js +23 -4
- package/out/concepts/InterfaceParam__.js.map +1 -1
- package/out/concepts/Interface__.d.ts +2 -1
- package/out/concepts/Interface__.js +29 -5
- package/out/concepts/Interface__.js.map +1 -1
- package/out/concepts/JSBlock__.d.ts +1 -0
- package/out/concepts/JSBlock__.js +6 -0
- package/out/concepts/JSBlock__.js.map +1 -1
- package/out/concepts/LogicDeclaration__.d.ts +1 -0
- package/out/concepts/LogicDeclaration__.js +58 -7
- package/out/concepts/LogicDeclaration__.js.map +1 -1
- package/out/concepts/Logic__.js +32 -22
- package/out/concepts/Logic__.js.map +1 -1
- package/out/concepts/MatchCase__.js +1 -2
- package/out/concepts/MatchCase__.js.map +1 -1
- package/out/concepts/Match__.js +3 -18
- package/out/concepts/Match__.js.map +1 -1
- package/out/concepts/MemberExpression__.js +1 -1
- package/out/concepts/MemberExpression__.js.map +1 -1
- package/out/concepts/Module__.d.ts +2 -0
- package/out/concepts/Module__.js +64 -0
- package/out/concepts/Module__.js.map +1 -1
- package/out/concepts/NewComposite__.d.ts +1 -1
- package/out/concepts/NewComposite__.js +3 -3
- package/out/concepts/NewComposite__.js.map +1 -1
- package/out/concepts/Paginate__.d.ts +1 -0
- package/out/concepts/Paginate__.js +15 -7
- package/out/concepts/Paginate__.js.map +1 -1
- package/out/concepts/QueryFromExpression__.js +2 -2
- package/out/concepts/QueryFromExpression__.js.map +1 -1
- package/out/concepts/StringLiteral__.js +3 -4
- package/out/concepts/StringLiteral__.js.map +1 -1
- package/out/concepts/TypeAnnotation__.js +1 -0
- package/out/concepts/TypeAnnotation__.js.map +1 -1
- package/out/concepts/ViewElement__.d.ts +2 -0
- package/out/concepts/ViewElement__.js +10 -7
- package/out/concepts/ViewElement__.js.map +1 -1
- package/out/concepts/View__.d.ts +1 -0
- package/out/concepts/View__.js +55 -1
- package/out/concepts/View__.js.map +1 -1
- package/out/generator/genBundleFiles.js +61 -51
- package/out/generator/genBundleFiles.js.map +1 -1
- package/out/generator/genHash.d.ts +2 -2
- package/out/generator/genHash.js +30 -30
- package/out/generator/genHash.js.map +1 -1
- package/out/generator/permission.d.ts +8 -1
- package/out/generator/permission.js +321 -23
- package/out/generator/permission.js.map +1 -1
- package/out/generator/release-body/body.js +18 -4
- package/out/generator/release-body/body.js.map +1 -1
- package/out/generator/release-body/data.js +6 -2
- package/out/generator/release-body/data.js.map +1 -1
- package/out/generator/release-body/utils.js +3 -3
- package/out/generator/release-body/utils.js.map +1 -1
- package/out/generator/release-body/validation.js +2 -2
- package/out/generator/release-body/validation.js.map +1 -1
- package/out/index.d.ts +1 -1
- package/out/index.js.map +1 -1
- package/out/natural/genNaturalTS.d.ts +2 -2
- package/out/natural/genNaturalTS.js +7 -7
- package/out/natural/genNaturalTS.js.map +1 -1
- package/out/natural/getContext/getUILib.js +9 -5
- package/out/natural/getContext/getUILib.js.map +1 -1
- package/out/natural/getContext/index.d.ts +1 -1
- package/out/natural/getContext/index.js +15 -9
- package/out/natural/getContext/index.js.map +1 -1
- package/out/natural/transformTS2UI.js +30 -11
- package/out/natural/transformTS2UI.js.map +1 -1
- package/out/natural/transformTSCode.js +30 -11
- package/out/natural/transformTSCode.js.map +1 -1
- package/out/server/entity2LogicNamespace.d.ts +2 -2
- package/out/server/entity2LogicNamespace.js +321 -310
- package/out/server/entity2LogicNamespace.js.map +1 -1
- package/out/server/extendBaseNode.js +29 -18
- package/out/server/extendBaseNode.js.map +1 -1
- package/out/server/naslServer.d.ts +1 -1
- package/out/server/naslServer.js +32 -18
- package/out/server/naslServer.js.map +1 -1
- package/out/server/translator.js +12 -0
- package/out/server/translator.js.map +1 -1
- package/out/service/storage/init.d.ts +2 -0
- package/out/service/storage/init.js +20 -1
- package/out/service/storage/init.js.map +1 -1
- package/out/templator/genCreateBlock.js +3 -3
- package/out/templator/genCreateBlock.js.map +1 -1
- package/out/templator/genCurdEditMultipleKeyBlock.js +2 -2
- package/out/templator/genCurdEditMultipleKeyBlock.js.map +1 -1
- package/out/templator/genCurdMultipleKeyBlock.js +4 -4
- package/out/templator/genCurdMultipleKeyBlock.js.map +1 -1
- package/out/templator/genEditTableBlock.js +1 -1
- package/out/templator/genEditTableBlock.js.map +1 -1
- package/out/templator/genGetBlock.js.map +1 -1
- package/out/templator/genGridViewBlock.js.map +1 -1
- package/out/templator/genSelectBlock.js.map +1 -1
- package/out/templator/genTableBlock.js.map +1 -1
- package/out/templator/genUpdateBlock.js +3 -3
- package/out/templator/genUpdateBlock.js.map +1 -1
- package/out/templator/utils.js +1 -1
- package/out/templator/utils.js.map +1 -1
- package/package.json +5 -5
- package/sandbox/stdlib/nasl.util.ts +4 -1
- package/src/common/BaseNode.ts +91 -11
- package/src/concepts/AbstractInterface__.ts +1 -0
- package/src/concepts/Annotation__.ts +1 -1
- package/src/concepts/App__.ts +104 -4
- package/src/concepts/Argument__.ts +3 -3
- package/src/concepts/BatchAssignment__.ts +3 -3
- package/src/concepts/BindAttribute__.ts +5 -6
- package/src/concepts/BindDirective__.ts +3 -4
- package/src/concepts/BusinessComponent__.ts +54 -1
- package/src/concepts/BusinessLogic__.ts +10 -1
- package/src/concepts/CallEvent__.ts +66 -0
- package/src/concepts/CallInterface__.ts +21 -9
- package/src/concepts/CallLogic__.ts +59 -3
- package/src/concepts/Entity__.ts +7 -1
- package/src/concepts/Event__.ts +32 -0
- package/src/concepts/FrontendType__.ts +34 -1
- package/src/concepts/Frontend__.ts +51 -0
- package/src/concepts/IfStatement__.ts +6 -6
- package/src/concepts/InterfaceParam__.ts +23 -4
- package/src/concepts/Interface__.ts +29 -5
- package/src/concepts/JSBlock__.ts +5 -0
- package/src/concepts/LogicDeclaration__.ts +65 -7
- package/src/concepts/Logic__.ts +34 -25
- package/src/concepts/MatchCase__.ts +1 -2
- package/src/concepts/Match__.ts +3 -21
- package/src/concepts/MemberExpression__.ts +1 -1
- package/src/concepts/Module__.ts +75 -0
- package/src/concepts/NewComposite__.ts +3 -3
- package/src/concepts/Paginate__.ts +14 -7
- package/src/concepts/QueryFromExpression__.ts +2 -2
- package/src/concepts/StringLiteral__.ts +3 -4
- package/src/concepts/TypeAnnotation__.ts +1 -0
- package/src/concepts/ViewElement__.ts +11 -7
- package/src/concepts/View__.ts +56 -1
- package/src/generator/genBundleFiles.ts +67 -54
- package/src/generator/genHash.ts +32 -6
- package/src/generator/permission.ts +333 -23
- package/src/generator/release-body/body.ts +24 -5
- package/src/generator/release-body/data.ts +7 -2
- package/src/generator/release-body/utils.ts +3 -3
- package/src/generator/release-body/validation.ts +1 -1
- package/src/index.ts +13 -1
- package/src/natural/genNaturalTS.ts +9 -7
- package/src/natural/getContext/getUILib.ts +9 -5
- package/src/natural/getContext/index.ts +17 -11
- package/src/natural/transformTS2UI.ts +28 -11
- package/src/natural/transformTSCode.ts +28 -11
- package/src/server/entity2LogicNamespace.ts +13 -1
- package/src/server/extendBaseNode.ts +32 -22
- package/src/server/naslServer.ts +42 -25
- package/src/server/translator.ts +15 -0
- package/src/service/storage/init.ts +26 -0
- package/src/templator/genCreateBlock.ts +4 -4
- package/src/templator/genCurdEditMultipleKeyBlock.ts +2 -2
- package/src/templator/genCurdMultipleKeyBlock.ts +7 -7
- package/src/templator/genEditTableBlock.ts +4 -4
- package/src/templator/genGetBlock.ts +1 -1
- package/src/templator/genGridViewBlock.ts +2 -2
- package/src/templator/genSelectBlock.ts +3 -3
- package/src/templator/genTableBlock.ts +2 -2
- package/src/templator/genUpdateBlock.ts +6 -6
- package/src/templator/utils.ts +1 -1
- package/test/concepts/call-logic/__snapshots__/getQuickInfoOffset.spec.ts.snap +1 -1
- package/test/concepts/call-logic/__snapshots__/toEmbeddedTS.spec.ts.snap +1 -1
- package/test/concepts/string-literal/__snapshots__/toVue.spec.ts.snap +1 -1
- package/test/concepts/view-element/__snapshots__/toEmbeddedTS.spec.ts.snap +75 -75
- package/test/concepts/view-element/__snapshots__/toVue.spec.ts.snap +6 -2
|
@@ -176,7 +176,6 @@ function genRouteFiles(routes: Route[], defaultRoute: string,config?: any) {
|
|
|
176
176
|
// 生成路由文件列表
|
|
177
177
|
const routeFiles: any[] = [];
|
|
178
178
|
function routeToFile(route: Route) {
|
|
179
|
-
console.log(route, 'route');
|
|
180
179
|
if (route?.component?.script) {
|
|
181
180
|
const content = genExportComponetCode(route.component);
|
|
182
181
|
const lazyPath = getCompletePath(null, content, config);
|
|
@@ -236,6 +235,7 @@ export function genBundleFiles(app: App, frontend: Frontend, config: Config) {
|
|
|
236
235
|
try {
|
|
237
236
|
config?.debug && genBreakpoints(app);
|
|
238
237
|
app.curDeployEnv = config.env
|
|
238
|
+
console.time('toVueOptions');
|
|
239
239
|
|
|
240
240
|
utils.traverse(
|
|
241
241
|
(current) => {
|
|
@@ -252,6 +252,7 @@ export function genBundleFiles(app: App, frontend: Frontend, config: Config) {
|
|
|
252
252
|
} as View,
|
|
253
253
|
}
|
|
254
254
|
);
|
|
255
|
+
console.timeEnd('toVueOptions');
|
|
255
256
|
|
|
256
257
|
businessComponents.forEach((businessComponent) => {
|
|
257
258
|
const frontendI18nEnabled = frontend?.i18nInfo?.enabled
|
|
@@ -543,8 +544,16 @@ export function genBundleFiles(app: App, frontend: Frontend, config: Config) {
|
|
|
543
544
|
} else if(window.parent.isGlobalScaleTop) {
|
|
544
545
|
// 点击跳转到外部页面时,通知顶层页面
|
|
545
546
|
document.body.addEventListener('click', (e) => {
|
|
546
|
-
if(e.target.href)
|
|
547
|
-
|
|
547
|
+
if(!e.target.href) return;
|
|
548
|
+
if(typeof e.target.href !== 'string') return;
|
|
549
|
+
if(e.target.tagName !== 'A') return;
|
|
550
|
+
try {
|
|
551
|
+
const url = new URL(e.target.href);
|
|
552
|
+
if(url.host !== location.host){
|
|
553
|
+
parent.location.href = e.target.href;
|
|
554
|
+
}
|
|
555
|
+
} catch(err) {
|
|
556
|
+
console.error(err);
|
|
548
557
|
}
|
|
549
558
|
});
|
|
550
559
|
}
|
|
@@ -618,8 +627,8 @@ export function genBundleFiles(app: App, frontend: Frontend, config: Config) {
|
|
|
618
627
|
}
|
|
619
628
|
return response.text();
|
|
620
629
|
}).then(function(scriptText) {
|
|
621
|
-
var func = new Function(scriptText);
|
|
622
|
-
var result = func();
|
|
630
|
+
var func = new Function('importComponent', scriptText);
|
|
631
|
+
var result = func(window.importComponent);
|
|
623
632
|
return result;
|
|
624
633
|
})
|
|
625
634
|
.catch(error => {
|
|
@@ -879,9 +888,7 @@ export function genBundleFiles(app: App, frontend: Frontend, config: Config) {
|
|
|
879
888
|
|
|
880
889
|
|
|
881
890
|
|
|
882
|
-
console.time('genHash')
|
|
883
891
|
let bundleMinPath = completePath + getCompletePath(getBundleFileName(), content, config);
|
|
884
|
-
console.timeEnd('genHash');
|
|
885
892
|
|
|
886
893
|
const otherJsList = (frontend as any)?.appletsConfig?.enable ? ['//res.wx.qq.com/open/js/jweixin-1.3.2.js'] : [];
|
|
887
894
|
|
|
@@ -1018,45 +1025,7 @@ export function genBundleFiles(app: App, frontend: Frontend, config: Config) {
|
|
|
1018
1025
|
},
|
|
1019
1026
|
...routerFiles,
|
|
1020
1027
|
];
|
|
1021
|
-
|
|
1022
|
-
// 导出源码才处理
|
|
1023
|
-
if (config.isExport && Array.isArray(assets) && assets.length) {
|
|
1024
|
-
function replaceContentFilePath(content: string) {
|
|
1025
|
-
const assetsMap = config.assetsMap;
|
|
1026
|
-
// 正则
|
|
1027
|
-
const regex = utils.transAssetsToRegx(assets, 'fileUrl');
|
|
1028
|
-
content = content.replace(regex, (url) => {
|
|
1029
|
-
const asset: Asset = utils.getAssetFromAssetsMap(assetsMap, url);
|
|
1030
|
-
if (asset) {
|
|
1031
|
-
const basePath = frontend?.basePath;
|
|
1032
|
-
const assetName = asset.name;
|
|
1033
|
-
const assetDir = basePath ? `${basePath}/assets/${assetName}` : `/assets/${assetName}`;
|
|
1034
|
-
let path = assetDir;
|
|
1035
|
-
const sysPrefixPath = frontend?.app?.sysPrefixPath;
|
|
1036
|
-
if (sysPrefixPath) {
|
|
1037
|
-
path = `${sysPrefixPath}${assetDir}`;
|
|
1038
|
-
}
|
|
1039
|
-
globalConfig.assets.push({
|
|
1040
|
-
path: assetDir,
|
|
1041
|
-
isDir: false,
|
|
1042
|
-
url,
|
|
1043
|
-
});
|
|
1044
|
-
const encodeAssetName = encodeURIComponent(assetName);
|
|
1045
|
-
let encodeAssetDir = basePath ? `${basePath}/assets/${encodeAssetName}` : `/assets/${encodeAssetName}`;
|
|
1046
|
-
if (sysPrefixPath) {
|
|
1047
|
-
encodeAssetDir = `${sysPrefixPath}${encodeAssetDir}`;
|
|
1048
|
-
}
|
|
1049
|
-
return encodeAssetDir;
|
|
1050
|
-
}
|
|
1051
|
-
return url;
|
|
1052
|
-
});
|
|
1053
|
-
return content;
|
|
1054
|
-
}
|
|
1055
|
-
outputs.forEach((output) => {
|
|
1056
|
-
output.content = replaceContentFilePath(output.content || '');
|
|
1057
|
-
})
|
|
1058
|
-
}
|
|
1059
|
-
console.log('outputs', outputs)
|
|
1028
|
+
processAssetsInOutputs(outputs, frontend, config);
|
|
1060
1029
|
return outputs;
|
|
1061
1030
|
}
|
|
1062
1031
|
|
|
@@ -1067,11 +1036,11 @@ export async function genFrontendBundleFiles(app: App, frontends: Array<Frontend
|
|
|
1067
1036
|
for (const frontend of frontends) {
|
|
1068
1037
|
if(frontend.frameworkKind === 'react'){
|
|
1069
1038
|
const files: {path: string, content: string}[] = await compileNASLToReactDist(app, frontend, config as any);
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
);
|
|
1039
|
+
const outputs = files.map((x) => {
|
|
1040
|
+
return { name: x.path, content: x.content };
|
|
1041
|
+
});
|
|
1042
|
+
processAssetsInOutputs(outputs, frontend, config);
|
|
1043
|
+
result.push(...outputs);
|
|
1075
1044
|
}else{
|
|
1076
1045
|
const data = await genBundleFiles(app, frontend, config);
|
|
1077
1046
|
result.push(...data);
|
|
@@ -1143,7 +1112,6 @@ export function getOneFiles(options: { view: View; action: string; cacheRouterDa
|
|
|
1143
1112
|
}
|
|
1144
1113
|
currentView = currentView.parentNode;
|
|
1145
1114
|
}
|
|
1146
|
-
console.log(currentRoute);
|
|
1147
1115
|
|
|
1148
1116
|
function addOrUpdateRoute(routes: Route[], newRoute: Route) {
|
|
1149
1117
|
const existingRoute = routes.find((route) => route.path === newRoute.path);
|
|
@@ -1181,7 +1149,6 @@ export function getOneFiles(options: { view: View; action: string; cacheRouterDa
|
|
|
1181
1149
|
} else {
|
|
1182
1150
|
addOrUpdateRoute(cacheRouters, currentRoute);
|
|
1183
1151
|
}
|
|
1184
|
-
console.log(cacheRouters, 111);
|
|
1185
1152
|
const routerFiles = genRouteFiles(cacheRouters, null);
|
|
1186
1153
|
const completePath = `${cacheRouterData.baseUrl}${frontend.basePath || ''}/`;
|
|
1187
1154
|
const outputs = routerFiles;
|
|
@@ -1195,6 +1162,52 @@ export function getOneFiles(options: { view: View; action: string; cacheRouterDa
|
|
|
1195
1162
|
item.ideVersion = cacheRouterData.ideVersion;
|
|
1196
1163
|
}
|
|
1197
1164
|
});
|
|
1198
|
-
console.log('outputs: ', outputs);
|
|
1199
1165
|
return outputs;
|
|
1200
1166
|
}
|
|
1167
|
+
|
|
1168
|
+
function processAssetsInOutputs(
|
|
1169
|
+
outputs: { name: string; content: string }[],
|
|
1170
|
+
frontend: Frontend,
|
|
1171
|
+
config: Config
|
|
1172
|
+
) {
|
|
1173
|
+
const assets = config.assets;
|
|
1174
|
+
// 导出源码才处理
|
|
1175
|
+
if (config.isExport && Array.isArray(assets) && assets.length) {
|
|
1176
|
+
function replaceContentFilePath(content: string) {
|
|
1177
|
+
const assetsMap = config.assetsMap;
|
|
1178
|
+
// 正则
|
|
1179
|
+
const regex = utils.transAssetsToRegx(assets, 'fileUrl');
|
|
1180
|
+
content = content.replace(regex, (url) => {
|
|
1181
|
+
const asset: Asset = utils.getAssetFromAssetsMap(assetsMap, url);
|
|
1182
|
+
if (asset) {
|
|
1183
|
+
const basePath = frontend?.basePath;
|
|
1184
|
+
const assetName = asset.name;
|
|
1185
|
+
const assetDir = basePath ? `${basePath}/assets/${assetName}` : `/assets/${assetName}`;
|
|
1186
|
+
let path = assetDir;
|
|
1187
|
+
const sysPrefixPath = frontend?.app?.sysPrefixPath;
|
|
1188
|
+
if (sysPrefixPath) {
|
|
1189
|
+
path = `${sysPrefixPath}${assetDir}`;
|
|
1190
|
+
}
|
|
1191
|
+
globalConfig.assets.push({
|
|
1192
|
+
path: assetDir,
|
|
1193
|
+
isDir: false,
|
|
1194
|
+
url,
|
|
1195
|
+
});
|
|
1196
|
+
const encodeAssetName = encodeURIComponent(assetName);
|
|
1197
|
+
let encodeAssetDir = basePath
|
|
1198
|
+
? `${basePath}/assets/${encodeAssetName}`
|
|
1199
|
+
: `/assets/${encodeAssetName}`;
|
|
1200
|
+
if (sysPrefixPath) {
|
|
1201
|
+
encodeAssetDir = `${sysPrefixPath}${encodeAssetDir}`;
|
|
1202
|
+
}
|
|
1203
|
+
return encodeAssetDir;
|
|
1204
|
+
}
|
|
1205
|
+
return url;
|
|
1206
|
+
});
|
|
1207
|
+
return content;
|
|
1208
|
+
}
|
|
1209
|
+
outputs.forEach((output) => {
|
|
1210
|
+
output.content = replaceContentFilePath(output.content || '');
|
|
1211
|
+
});
|
|
1212
|
+
}
|
|
1213
|
+
}
|
package/src/generator/genHash.ts
CHANGED
|
@@ -1,13 +1,39 @@
|
|
|
1
|
-
|
|
1
|
+
// cyrb53 (c) 2018 bryc (github.com/bryc). License: Public domain. Attribution appreciated.
|
|
2
|
+
// A fast and simple 64-bit (or 53-bit) string hash function with decent collision resistance.
|
|
3
|
+
// Largely inspired by MurmurHash2/3, but with a focus on speed/simplicity.
|
|
4
|
+
// See https://stackoverflow.com/questions/7616461/generate-a-hash-from-string-in-javascript/52171480#52171480
|
|
5
|
+
// https://github.com/bryc/code/blob/master/jshash/experimental/cyrb53.js
|
|
6
|
+
const cyrb64 = (str : string, seed = 0) => {
|
|
7
|
+
let h1 = 0xdeadbeef ^ seed, h2 = 0x41c6ce57 ^ seed;
|
|
8
|
+
for(let i = 0, ch; i < str.length; i++) {
|
|
9
|
+
ch = str.charCodeAt(i);
|
|
10
|
+
h1 = Math.imul(h1 ^ ch, 2654435761);
|
|
11
|
+
h2 = Math.imul(h2 ^ ch, 1597334677);
|
|
12
|
+
}
|
|
13
|
+
h1 = Math.imul(h1 ^ (h1 >>> 16), 2246822507);
|
|
14
|
+
h1 ^= Math.imul(h2 ^ (h2 >>> 13), 3266489909);
|
|
15
|
+
h2 = Math.imul(h2 ^ (h2 >>> 16), 2246822507);
|
|
16
|
+
h2 ^= Math.imul(h1 ^ (h1 >>> 13), 3266489909);
|
|
17
|
+
// For a single 53-bit numeric return value we could return
|
|
18
|
+
// 4294967296 * (2097151 & h2) + (h1 >>> 0);
|
|
19
|
+
// but we instead return the full 64-bit value:
|
|
20
|
+
return [h2>>>0, h1>>>0];
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
// An improved, *insecure* 64-bit hash that's short, fast, and has no dependencies.
|
|
24
|
+
// Output is always 14 characters.
|
|
25
|
+
const cyrb64Hash = (str : string, seed = 0) => {
|
|
26
|
+
const [h2, h1] = cyrb64(str, seed);
|
|
27
|
+
return h2.toString(36).padStart(7, '0') + h1.toString(36).padStart(7, '0');
|
|
28
|
+
}
|
|
29
|
+
|
|
2
30
|
|
|
3
31
|
/**
|
|
4
32
|
*
|
|
5
33
|
* @param 文件内容 content
|
|
6
|
-
* @returns
|
|
34
|
+
* @returns cyrb64 弱 hash,取前 8 位
|
|
7
35
|
*/
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
return hash.slice(0, 8);
|
|
11
|
-
}
|
|
36
|
+
|
|
37
|
+
export const genHash = (str : string) => cyrb64Hash(str, 0).slice(0, 8);
|
|
12
38
|
|
|
13
39
|
export default genHash;
|
|
@@ -15,6 +15,8 @@ import {
|
|
|
15
15
|
BindStyle,
|
|
16
16
|
BindDirective,
|
|
17
17
|
Connector,
|
|
18
|
+
Identifier,
|
|
19
|
+
Event,
|
|
18
20
|
} from '../concepts';
|
|
19
21
|
import { processToTreeFragment } from '../server/process2LogicNamespace';
|
|
20
22
|
|
|
@@ -145,14 +147,14 @@ function removeRedundantResourceData(resources: ResourceNode[][]) {
|
|
|
145
147
|
resources.sort((a, b) => wm.get(a).length - wm.get(b).length);
|
|
146
148
|
|
|
147
149
|
const res: ResourceNode[][] = [];
|
|
148
|
-
const
|
|
150
|
+
const hashes: string[] = [];
|
|
149
151
|
|
|
150
152
|
for (const resource of resources) {
|
|
151
153
|
const hash = wm.get(resource);
|
|
152
|
-
if (
|
|
154
|
+
if (hashes.some((h) => hash.endsWith(h))) continue;
|
|
153
155
|
|
|
154
156
|
res.push(resource);
|
|
155
|
-
|
|
157
|
+
hashes.push(hash);
|
|
156
158
|
}
|
|
157
159
|
return res;
|
|
158
160
|
}
|
|
@@ -278,7 +280,7 @@ function checkUploadAuth(uploaders: Map<string, ViewElement[]>) {
|
|
|
278
280
|
// 如果开启控制权限-component,没开启权限-page
|
|
279
281
|
uploaders.forEach((value, key) => {
|
|
280
282
|
const authValue: ResourceNode[] = [];
|
|
281
|
-
value.
|
|
283
|
+
value.forEach((node) => {
|
|
282
284
|
if (node instanceof ViewElement && node.view) {
|
|
283
285
|
const path = node.auth ? node.authPath : `${node.view.path}`;
|
|
284
286
|
const type = node.auth ? 'component' : 'page';
|
|
@@ -290,25 +292,29 @@ function checkUploadAuth(uploaders: Map<string, ViewElement[]>) {
|
|
|
290
292
|
});
|
|
291
293
|
return res;
|
|
292
294
|
}
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
flag =
|
|
296
|
-
|
|
295
|
+
|
|
296
|
+
function checkPageAndUploadAuth(uploaders: Map<string, ViewElement[]>, key: string): boolean {
|
|
297
|
+
let flag: boolean = false;
|
|
298
|
+
|
|
299
|
+
uploaders.get(key).forEach((node) => {
|
|
300
|
+
if (node.view instanceof View) {
|
|
297
301
|
// 当前页面未开启权限且文件上传组件也未开启权限
|
|
298
|
-
if (!
|
|
299
|
-
|
|
302
|
+
if (!node.view.auth && node instanceof ViewElement && !node.auth) {
|
|
303
|
+
flag = true;
|
|
300
304
|
}
|
|
301
305
|
} else if (node.getAncestor('BusinessComponent')) {
|
|
302
|
-
|
|
306
|
+
flag = true;
|
|
303
307
|
}
|
|
304
308
|
});
|
|
309
|
+
|
|
305
310
|
return flag;
|
|
306
311
|
}
|
|
312
|
+
|
|
307
313
|
function convertArray(arr: ResourceNode[]) {
|
|
308
314
|
return arr.map((item: any) => [item]);
|
|
309
315
|
}
|
|
310
|
-
|
|
311
|
-
|
|
316
|
+
|
|
317
|
+
export async function genPermissionDataOld(app: App) {
|
|
312
318
|
openCache();
|
|
313
319
|
const logicPageResourceDtoList: { [key: string]: ResourceNode[][]; } = {};
|
|
314
320
|
const { logics, processLogics } = getAllLogics(app);
|
|
@@ -316,31 +322,335 @@ export async function genPermissionData(app: App) {
|
|
|
316
322
|
for (const logic of [...logics, ...processLogics]) {
|
|
317
323
|
const resources = await findResourcesOfLogic(logic, uploaders);
|
|
318
324
|
if (resources.length === 0) continue;
|
|
319
|
-
const service = logics.includes(logic)
|
|
325
|
+
const service = logics.includes(logic)
|
|
326
|
+
? logic.toService()
|
|
327
|
+
: (logic.toProcessService() as { url: { method: string; path: string; }; });
|
|
320
328
|
const key = `${service.url.path}:${service.url.method}`;
|
|
321
329
|
logicPageResourceDtoList[key] = resources;
|
|
322
330
|
}
|
|
323
|
-
const
|
|
324
|
-
if (
|
|
325
|
-
|
|
331
|
+
const authVals = checkUploadAuth(uploaders);
|
|
332
|
+
if (authVals?.length) {
|
|
333
|
+
authVals.forEach((item) => {
|
|
326
334
|
const { key, authValue } = item;
|
|
327
335
|
if (key.startsWith('/upload' || '/api/')) {
|
|
328
|
-
logicPageResourceDtoList[`${key}:POST`] = checkPageAndUploadAuth(uploaders, key)
|
|
336
|
+
logicPageResourceDtoList[`${key}:POST`] = checkPageAndUploadAuth(uploaders, key) ? [[]] : convertArray(authValue);
|
|
329
337
|
}
|
|
330
338
|
});
|
|
331
339
|
}
|
|
332
340
|
logicPageResourceDtoList['/upload/download_files:POST'] = callLogicUploadList;
|
|
333
341
|
closeCache();
|
|
334
|
-
// console.timeEnd('xxx');
|
|
335
342
|
return logicPageResourceDtoList;
|
|
336
343
|
}
|
|
344
|
+
|
|
345
|
+
|
|
346
|
+
|
|
347
|
+
function generateServiceKey(logic : Logic, kind : 'server' | 'process') {
|
|
348
|
+
let service : { url: { method: string; path: string; }};
|
|
349
|
+
if (kind === 'server') {
|
|
350
|
+
service = logic.toService()
|
|
351
|
+
} else if (kind === 'process') {
|
|
352
|
+
service = (logic.toProcessService() as { url: { method: string; path: string; }; })
|
|
353
|
+
} else {
|
|
354
|
+
throw new Error('Invalid service key kind')
|
|
355
|
+
}
|
|
356
|
+
const key = `${service.url.path}:${service.url.method}`;
|
|
357
|
+
return key;
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
function createArrayOnAdd<K, V>(k : K, v : V, m: Map<K, Array<V>>) {
|
|
361
|
+
if (m.get(k)) {
|
|
362
|
+
m.get(k).push(v);
|
|
363
|
+
} else {
|
|
364
|
+
m.set(k, [v]);
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
// 需要区分:前端逻辑、后端逻辑、流程逻辑
|
|
369
|
+
// 需要的信息:后端逻辑、流程逻辑的 service path;逻辑调用到其定义的映射;
|
|
370
|
+
// 流程逻辑 call 的 getCallNode() 每次都不同
|
|
371
|
+
// 表单验证 $refs.validate 的定义缺少 calleewholeKey 且访问时会抛异常
|
|
372
|
+
// 不跳过 playground 草稿区内容:赫基有用到 JS代码块,在代码块里调用逻辑。JS代码块里的引用没有识别出来。但恰巧在草稿区的东西,提供了引用关系。赫基项目,删除了草稿区的东西会导致401。
|
|
373
|
+
export function genPermissionData(app: App): { [key: string]: ResourceNode[][]; } {
|
|
374
|
+
type TraverseCtx = { viewElement : ViewElement, viewElements: Set<ViewElement>, thisLogic : Logic, bindEvent : BindEvent, event : Event, view : View};
|
|
375
|
+
type LogicCtx = { view : View, viewElements : Set<ViewElement> }
|
|
376
|
+
type FrontendLogicCtx = { view : View, viewElements : Set<ViewElement>, thisLogic : Logic }
|
|
377
|
+
|
|
378
|
+
function clearCtx(ctx: TraverseCtx) {
|
|
379
|
+
ctx.viewElement = null;
|
|
380
|
+
ctx.viewElements = new Set();
|
|
381
|
+
ctx.thisLogic = null;
|
|
382
|
+
ctx.bindEvent = null;
|
|
383
|
+
ctx.event = null;
|
|
384
|
+
ctx.view = null;
|
|
385
|
+
}
|
|
386
|
+
const { logics : tmpLogics, processLogics : tmpProcessLogics } = getAllLogics(app);
|
|
387
|
+
|
|
388
|
+
// 调用后端逻辑的Map
|
|
389
|
+
const backendLogicCallCtx : Map<string, Array<LogicCtx>> = new Map();
|
|
390
|
+
|
|
391
|
+
// 调用前端逻辑的Map
|
|
392
|
+
const frontendLogicCallCtx: Array<FrontendLogicCtx> = [];
|
|
393
|
+
|
|
394
|
+
// from calleeWholeKey to Logic,消除流程逻辑每次找到的定义都是即时演算生成的,地址不同的问题。
|
|
395
|
+
const frontNdCache = new Map<string, Logic>();
|
|
396
|
+
const processNdCache = new Map<string, Logic>();
|
|
397
|
+
const serverNdCache = new Map<string, Logic>();
|
|
398
|
+
|
|
399
|
+
tmpProcessLogics.forEach(l => processNdCache.set(l.calleewholeKey, l));
|
|
400
|
+
tmpLogics.forEach(l => serverNdCache.set(l.calleewholeKey, l));
|
|
401
|
+
|
|
402
|
+
// 上传组件
|
|
403
|
+
const uploaders = new Map<string, Array<ViewElement>>();
|
|
404
|
+
const callLogicUploadList = new Map<string, any>();
|
|
405
|
+
let callLogicUploadFlag = false;
|
|
406
|
+
|
|
407
|
+
const defToCalls : Map<Logic, Array<CallLogic>> = new Map();
|
|
408
|
+
app.frontendTypes.forEach((frontendType) => {
|
|
409
|
+
frontendType.traverseChildrenWithContext((nd, ctx : TraverseCtx) => {
|
|
410
|
+
switch (nd.concept) {
|
|
411
|
+
case 'ViewElement': {
|
|
412
|
+
ctx.thisLogic = null;
|
|
413
|
+
ctx.viewElement = nd;
|
|
414
|
+
ctx.viewElements = new Set(ctx.viewElements); // if use ctx.viewElements.add(node) directly, will encounter a SEVERE slow down. For example, 3s vs 12s
|
|
415
|
+
ctx.viewElements.add(nd);
|
|
416
|
+
// collect uploaders
|
|
417
|
+
if (nd.tag?.includes('uploader')) {
|
|
418
|
+
const urlAttr = nd.bindAttrs.find((item : BindAttribute) => item.name === 'url');
|
|
419
|
+
const url = urlAttr?.value;
|
|
420
|
+
if (url) {
|
|
421
|
+
if (!uploaders.has(url)) uploaders.set(url, [nd]);
|
|
422
|
+
else uploaders.get(url).push(nd);
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
break;
|
|
426
|
+
}
|
|
427
|
+
case 'BindEvent': ctx.bindEvent = nd; break;
|
|
428
|
+
case 'Event': ctx.event = nd; break;
|
|
429
|
+
case 'CallLogic': {
|
|
430
|
+
const { thisLogic, event, bindEvent, view, viewElement, viewElements } = ctx;
|
|
431
|
+
createArrayOnAdd(thisLogic, nd, defToCalls);
|
|
432
|
+
if (viewElement || bindEvent || event) {
|
|
433
|
+
const [kind, logicDecl] = (nd as CallLogic).getCallNodeUsingCache(frontNdCache, serverNdCache, processNdCache);
|
|
434
|
+
switch (kind) {
|
|
435
|
+
case 'server': {
|
|
436
|
+
const key = generateServiceKey(logicDecl, 'server');
|
|
437
|
+
createArrayOnAdd(key, { view, viewElements }, backendLogicCallCtx);
|
|
438
|
+
break;
|
|
439
|
+
}
|
|
440
|
+
case 'process': {
|
|
441
|
+
const key = generateServiceKey(logicDecl, 'process');
|
|
442
|
+
createArrayOnAdd(key, { view, viewElements }, backendLogicCallCtx);
|
|
443
|
+
break;
|
|
444
|
+
}
|
|
445
|
+
case 'front': {
|
|
446
|
+
frontendLogicCallCtx.push({ view, viewElements, thisLogic: logicDecl });
|
|
447
|
+
break;
|
|
448
|
+
}
|
|
449
|
+
default: throw new Error('Invalid logic kind');
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
// 收集 callLogicUploadList
|
|
454
|
+
if (nd?.calleeName?.includes('downloadFile') && nd?.calleeNamespace === 'nasl.io' && !callLogicUploadFlag) {
|
|
455
|
+
// ViewElement 权限优先
|
|
456
|
+
if (viewElement instanceof ViewElement && viewElement?.auth) {
|
|
457
|
+
callLogicUploadList.set(viewElement?.authPath, [{
|
|
458
|
+
type: 'component',
|
|
459
|
+
path: viewElement?.authPath
|
|
460
|
+
}]);
|
|
461
|
+
} else if (view instanceof View && view?.auth) {
|
|
462
|
+
callLogicUploadList.set(view?.authPath, [{
|
|
463
|
+
type: 'page',
|
|
464
|
+
path: view?.authPath
|
|
465
|
+
}]);
|
|
466
|
+
} else {
|
|
467
|
+
// 如果开启权限和未开启权限都有,以未开启权限为准,清空 map,设置为 [[]]
|
|
468
|
+
callLogicUploadFlag = true;
|
|
469
|
+
callLogicUploadList.clear()
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
break;
|
|
473
|
+
}
|
|
474
|
+
case 'BindAttribute': {
|
|
475
|
+
if (nd.name === 'dataSource'
|
|
476
|
+
&& nd.type === 'dynamic'
|
|
477
|
+
&& nd.expression instanceof Identifier
|
|
478
|
+
&& (ctx.view) // View | BusinessComponent
|
|
479
|
+
) {
|
|
480
|
+
const viewLogics = ctx.view.logics; // Array<Logic> | Array<BusinessLogic>
|
|
481
|
+
const identName = nd.expression.name;
|
|
482
|
+
const logic = viewLogics.find((viewLogic : any) => {
|
|
483
|
+
return viewLogic?.name === identName;
|
|
484
|
+
});
|
|
485
|
+
if (logic) {
|
|
486
|
+
const { viewElements, view } = ctx;
|
|
487
|
+
frontendLogicCallCtx.push({ viewElements, view, thisLogic: logic });
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
break;
|
|
491
|
+
}
|
|
492
|
+
case 'Logic': ctx.thisLogic = nd; break;
|
|
493
|
+
case 'BusinessLogic': ctx.thisLogic = nd; break;
|
|
494
|
+
case 'View': clearCtx(ctx); ctx.view = nd; break;
|
|
495
|
+
case 'Identifier': {
|
|
496
|
+
// 参数选了函数名。高阶函数。
|
|
497
|
+
if (nd?.namespace === "app.logics") {
|
|
498
|
+
const key = `/api/lcplogics/${nd.name}:POST`;
|
|
499
|
+
createArrayOnAdd(key, { view: ctx.view, viewElements: ctx.viewElements }, backendLogicCallCtx);
|
|
500
|
+
}
|
|
501
|
+
// 草稿区也可能有这种 concept 是 Identifier 的调用
|
|
502
|
+
if (ctx?.view) {
|
|
503
|
+
const viewLogics = ctx.view.logics; // Array<Logic> | Array<BusinessLogic>
|
|
504
|
+
const identName = nd.name;
|
|
505
|
+
const logic = viewLogics.find((viewLogic : any) => {
|
|
506
|
+
return viewLogic?.name === identName;
|
|
507
|
+
});
|
|
508
|
+
if (logic) {
|
|
509
|
+
const { viewElements, view } = ctx;
|
|
510
|
+
frontendLogicCallCtx.push({ viewElements, view, thisLogic: logic });
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
break;
|
|
514
|
+
}
|
|
515
|
+
case 'BusinessComponent': clearCtx(ctx); ctx.view = nd; break;
|
|
516
|
+
default: break;
|
|
517
|
+
}
|
|
518
|
+
});
|
|
519
|
+
});
|
|
520
|
+
|
|
521
|
+
frontendLogicCallCtx.forEach(({ view, viewElements, thisLogic }) => {
|
|
522
|
+
const findCallBackendLogic = ([kind, l] : ['process' | 'server' | 'front', Logic]) => {
|
|
523
|
+
if (!l) {
|
|
524
|
+
return;
|
|
525
|
+
}
|
|
526
|
+
switch (kind) {
|
|
527
|
+
case 'server': {
|
|
528
|
+
const key = generateServiceKey(l, 'server');
|
|
529
|
+
createArrayOnAdd(key, { view, viewElements }, backendLogicCallCtx);
|
|
530
|
+
break;
|
|
531
|
+
}
|
|
532
|
+
case 'process': {
|
|
533
|
+
const key = generateServiceKey(l, 'process');
|
|
534
|
+
createArrayOnAdd(key, { view, viewElements }, backendLogicCallCtx);
|
|
535
|
+
break;
|
|
536
|
+
}
|
|
537
|
+
case 'front': {
|
|
538
|
+
const lgcCalls : Array<CallLogic> = defToCalls.get(l);
|
|
539
|
+
lgcCalls?.forEach( call => findCallBackendLogic(call.getCallNodeUsingCache(frontNdCache, serverNdCache, processNdCache)));
|
|
540
|
+
break;
|
|
541
|
+
}
|
|
542
|
+
default: {
|
|
543
|
+
throw new Error('Invalid logic kind in frontendLogicCallCtx');
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
};
|
|
547
|
+
findCallBackendLogic(['front', thisLogic]);
|
|
548
|
+
});
|
|
549
|
+
|
|
550
|
+
const logicPageResourceDtoList: { [key: string]: ResourceNode[][]; } = {};
|
|
551
|
+
backendLogicCallCtx.forEach((ctx, key) => {
|
|
552
|
+
const resources: ResourceNode[][] = [];
|
|
553
|
+
ctx?.forEach(({ viewElements, view }) => {
|
|
554
|
+
const pathInfos: Array<ResourceNode> = [];
|
|
555
|
+
viewElements?.forEach((viewElement) => {
|
|
556
|
+
if (viewElement?.auth) {
|
|
557
|
+
pathInfos.push({
|
|
558
|
+
path: viewElement?.authPath,
|
|
559
|
+
type: 'component',
|
|
560
|
+
});
|
|
561
|
+
}
|
|
562
|
+
});
|
|
563
|
+
let viewIter : BaseNode = view;
|
|
564
|
+
while (viewIter) {
|
|
565
|
+
if (viewIter instanceof View && viewIter.auth) {
|
|
566
|
+
pathInfos.push({
|
|
567
|
+
path: viewIter.authPath,
|
|
568
|
+
type: 'page',
|
|
569
|
+
});
|
|
570
|
+
}
|
|
571
|
+
viewIter = viewIter.parentNode;
|
|
572
|
+
}
|
|
573
|
+
resources.push(pathInfos);
|
|
574
|
+
});
|
|
575
|
+
logicPageResourceDtoList[key] = optimizeResourceData(resources);
|
|
576
|
+
});
|
|
577
|
+
|
|
578
|
+
const authVals = checkUploadAuth(uploaders);
|
|
579
|
+
if (authVals?.length) {
|
|
580
|
+
authVals.forEach((item) => {
|
|
581
|
+
const { key, authValue } = item;
|
|
582
|
+
if (key.startsWith('/upload' || '/api/')) {
|
|
583
|
+
logicPageResourceDtoList[`${key}:POST`] =
|
|
584
|
+
checkPageAndUploadAuth(uploaders, key) ? [[]] : convertArray(authValue);
|
|
585
|
+
}
|
|
586
|
+
});
|
|
587
|
+
}
|
|
588
|
+
logicPageResourceDtoList['/upload/download_files:POST'] =
|
|
589
|
+
callLogicUploadList.size === 0 ? [[]] : Array.from(callLogicUploadList.values());
|
|
590
|
+
|
|
591
|
+
return logicPageResourceDtoList;
|
|
592
|
+
}
|
|
593
|
+
|
|
337
594
|
export function genLogicAuthFlag(app: App) {
|
|
338
595
|
let flag = false;
|
|
339
|
-
app.
|
|
340
|
-
if (flag) return;
|
|
341
|
-
|
|
596
|
+
app.traverseStrictChildrenStopWhen((node) => {
|
|
342
597
|
if ((node instanceof View || node instanceof ViewElement) && node.auth) flag = true;
|
|
343
|
-
});
|
|
598
|
+
}, (nd) => (nd instanceof View || nd instanceof ViewElement) && Boolean(nd.auth), []);
|
|
344
599
|
|
|
345
600
|
return flag;
|
|
346
601
|
}
|
|
602
|
+
|
|
603
|
+
|
|
604
|
+
function compareResourceNode(a: ResourceNode, b: ResourceNode) {
|
|
605
|
+
if (a.path < b.path) {
|
|
606
|
+
return -1;
|
|
607
|
+
}
|
|
608
|
+
if (a.path > b.path) {
|
|
609
|
+
return 1;
|
|
610
|
+
}
|
|
611
|
+
if (a.type < b.type) {
|
|
612
|
+
return -1;
|
|
613
|
+
}
|
|
614
|
+
if (a.type > b.type) {
|
|
615
|
+
return 1;
|
|
616
|
+
}
|
|
617
|
+
return 0;
|
|
618
|
+
}
|
|
619
|
+
|
|
620
|
+
function compareResourceNodeList(a: Array<ResourceNode>, b: Array<ResourceNode>) {
|
|
621
|
+
a.sort(compareResourceNode);
|
|
622
|
+
b.sort(compareResourceNode);
|
|
623
|
+
for (let i = 0; i < a.length; i++) {
|
|
624
|
+
const result = compareResourceNode(a[i], b[i]);
|
|
625
|
+
if (result !== 0) {
|
|
626
|
+
return result;
|
|
627
|
+
}
|
|
628
|
+
}
|
|
629
|
+
return 0;
|
|
630
|
+
}
|
|
631
|
+
|
|
632
|
+
export function sortResourceDtoMap<K>(m : Map<K, Array<Array<ResourceNode>>>){
|
|
633
|
+
const keys = Array.from(m.keys()).sort();
|
|
634
|
+
const sortedMap = new Map<K,Array<Array<ResourceNode>>>();
|
|
635
|
+
keys.forEach((key) => {
|
|
636
|
+
sortedMap.set(key, m.get(key).sort(compareResourceNodeList));
|
|
637
|
+
});
|
|
638
|
+
|
|
639
|
+
keys.forEach((key) => {
|
|
640
|
+
sortedMap.get(key).forEach((item) => {
|
|
641
|
+
item.sort(compareResourceNode);
|
|
642
|
+
});
|
|
643
|
+
});
|
|
644
|
+
return sortedMap;
|
|
645
|
+
}
|
|
646
|
+
|
|
647
|
+
export async function testWithOldPermissionResult(app: App, newRes : { [key: string]: ResourceNode[][]; }) {
|
|
648
|
+
const newResMap = sortResourceDtoMap(new Map(Object.entries(newRes)));
|
|
649
|
+
console.log('newResMap', newResMap)
|
|
650
|
+
const oldRes : { [key: string]: ResourceNode[][]; } = await genPermissionDataOld(app);
|
|
651
|
+
const oldResMap = sortResourceDtoMap(new Map(Object.entries(oldRes)));
|
|
652
|
+
console.log('oldResMap', oldResMap)
|
|
653
|
+
|
|
654
|
+
console.log("oldLogicPageResourceDtoListMap === newLogicPageResourceDtoListMap?",
|
|
655
|
+
JSON.stringify(Array.from(newResMap.entries())) === JSON.stringify(Array.from(oldResMap.entries())));
|
|
656
|
+
}
|