crabatool 1.0.706 → 1.0.707

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/.eslintrc.json CHANGED
@@ -11,11 +11,19 @@
11
11
  "ecmaVersion": "latest",
12
12
  "sourceType": "script"
13
13
  },
14
+ "plugins": [],
14
15
  "rules": {
15
16
  "semi": "off",
16
17
  "no-redeclare": "off",
17
18
  //"no-unused-vars": "off",
18
19
  "missingSemi": "off",
20
+ "no-restricted-syntax": [
21
+ "error",
22
+ {
23
+ "selector": "ForInStatement",
24
+ "message": "1. 如果当前是数组,不建议使用for..in循环,会遍历出原型链的方法容易出现意外问题,可以改用forEach和普通for循环;2. 如果是对象,就可以用for..in;3.for of有兼容性不能用"
25
+ }
26
+ ],
19
27
  "comma-dangle": [
20
28
  "error",
21
29
  {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "crabatool",
3
- "version": "1.0.706",
3
+ "version": "1.0.707",
4
4
  "description": "crabatool",
5
5
  "main": "index.js",
6
6
  "bin": {
@@ -62,6 +62,7 @@
62
62
  "eslint-plugin-native-ie": "0.1.2",
63
63
  "express": "^4.17.3",
64
64
  "express-session": "^1.17.1",
65
+ "fast-xml-parser": "^5.2.5",
65
66
  "fs": "^0.0.1-security",
66
67
  "htmlparser2": "^8.0.1",
67
68
  "http-proxy-middleware": "^2.0.6",
@@ -0,0 +1,154 @@
1
+ const { XMLParser, XMLBuilder } = require('fast-xml-parser');
2
+ const fs = require('fs');
3
+ const path = require('path');
4
+
5
+ var config = require('../lib/config.js');
6
+
7
+ // const webPath = config.webPath
8
+ const webPath = "/Users/yj/Desktop/carpaevery/www"
9
+ const propKey = ':@';
10
+ const parseConfig = {
11
+ alwaysCreateTextNode: true,
12
+ attributeNamePrefix: '',
13
+ // attributesGroupName: 'properties',
14
+ textNodeName: '#text',
15
+ ignoreAttributes: false,
16
+ removeNSPrefix: true,
17
+ parseNodeValue: true,
18
+ parseAttributeValue: false,
19
+ allowBooleanAttributes: true,
20
+ trimValues: true,
21
+ cdataTagName: '#cdata',
22
+ preserveOrder: true,
23
+ numberParseOptions: {
24
+ hex: false,
25
+ leadingZeros: true,
26
+ }
27
+ }
28
+ // 黑名单目录列表
29
+ const blacklistDirs = [
30
+ 'node_modules',
31
+ '.git',
32
+ '.svn',
33
+ '.vscode',
34
+ 'dist',
35
+ 'build',
36
+ 'temp',
37
+ 'tmp',
38
+ '.idea',
39
+ '__pycache__'
40
+ ];
41
+
42
+ //黑名单标签列表
43
+ const blacklistTags = [
44
+ '?xml',
45
+ '#text',
46
+ 'Style'
47
+ ];
48
+
49
+ const parser = new XMLParser(parseConfig);
50
+ const builder = new XMLBuilder();
51
+
52
+ function parseGspx(filePath) {
53
+ const xml = fs.readFileSync(filePath, 'utf8');
54
+ const json = parser.parse(xml);
55
+ return json;
56
+ }
57
+
58
+ // [
59
+ // { '?xml': [ [Object] ], ':@': { version: '1.0', encoding: 'UTF-8' } },
60
+ // {
61
+ // Page: [ [Object], [Object], [Object] ],
62
+ // ':@': {
63
+ // Title: '订单处理',
64
+ // ActiveControl: 'null',
65
+ // CssClass: 'pd0 shglPage',
66
+ // ActionType: 'www.demo.ddclAction, /demo/ddcl.js'
67
+ // }
68
+ // }
69
+ // ]
70
+
71
+ // 1.遍历config.webPath下的所有gspx文件
72
+ // 2.读取.gspx文件,转换为json
73
+ // 3.遍历json,找到所有节点
74
+ // 3.1 找到所有节点后,判断节点是否包含ID或DataField属性
75
+ // 3.2 如果包含,不用管
76
+ // 3.3 如果不包含,则给节点添加ID
77
+ // 4.给每个节点添加id
78
+ // 5.保存gspx文件
79
+ function addNodeId(json, filter) {
80
+ if (!json.length) return;
81
+
82
+ for (const item of json) {
83
+ const tagName = getTagName(item);
84
+ if (blacklistTags.includes(tagName)) continue; // 如果标签名在黑名单中,则跳过
85
+ if (!isUpperCase(tagName[0])) continue; // 如果标签名第一个字符不是大写字母,则跳过
86
+
87
+ const childNodes = item[tagName];
88
+ let properties = item[propKey]
89
+ if (!properties) {
90
+ properties = item[propKey] = {};
91
+ }
92
+
93
+ if (childNodes.length) { // 如果节点有子节点,则递归处理子节点
94
+ addNodeId(childNodes, filter);
95
+ }
96
+
97
+ if (!filter(properties, tagName)) { // 如果节点不包含ID或DataField属性,则给节点添加ID
98
+ }
99
+ }
100
+ }
101
+
102
+ function getTagName(json) {
103
+ return Object.keys(json).find(key => Array.isArray(json[key]));
104
+ }
105
+
106
+ function isUpperCase(char) {
107
+ if (char >= 'A' && char <= 'Z') {
108
+ return true;
109
+ } else {
110
+ return false;
111
+ }
112
+ }
113
+
114
+ function saveGspx(filePath, json) {
115
+ const xml = builder.build(json);
116
+ fs.writeFileSync(filePath, xml);
117
+ }
118
+
119
+ const filter = (item, tagName) => (tagName === 'Page' || item.ID || item.DataField);
120
+
121
+ function readGspxFile(filePath, basePath = webPath) {
122
+ const files = fs.readdirSync(filePath);
123
+ files.forEach(file => {
124
+ const fullPath = path.join(filePath, file);
125
+ const relativePath = path.relative(basePath, fullPath);
126
+
127
+ if (fs.lstatSync(fullPath).isDirectory()) {
128
+ // 检查是否在黑名单中
129
+ if (blacklistDirs.includes(file)) {
130
+ console.log(`跳过黑名单目录: ${relativePath}/`);
131
+ return;
132
+ }
133
+ // 如果是目录,递归处理
134
+ // console.log(`目录: ${relativePath}/`);
135
+ readGspxFile(fullPath, basePath);
136
+ } else if (file.endsWith('.gspx')) {
137
+ // 如果是gspx文件,处理文件
138
+ // console.log(`处理文件: ${relativePath}`);
139
+ const json = parseGspx(fullPath);
140
+ addNodeId(json, filter);
141
+ // saveGspx(fullPath, json);
142
+ }
143
+ });
144
+ }
145
+
146
+ function start() {
147
+ readGspxFile(webPath);
148
+ }
149
+
150
+ start();
151
+
152
+
153
+
154
+
package/tool/checkjs.js CHANGED
@@ -18,7 +18,7 @@ var fileSize = 300;
18
18
  var blackList = ['agency.js', 'jquery.js', 'craba.min.js', 'crabaEx.min.js', 'crabaNgp.js', 'echarts-all.js', 'echarts.min.js', 'math.min.js', 'craba.rollup.min.js'];
19
19
 
20
20
  // 语法规则,不能包含这些关键词
21
- var dangerousJs = ['\\slet\\s', '\\sconst\\s', '\=\>\\s?\\(?\\{', '\\sawait\\s', '\\.then\\(', '\\sdebugger\\s'];// 'for\\s*\\(\\s*var\\s*\\w+\\s*in'];
21
+ var dangerousJs = ['\=\>\\s?\\(?\\{', '\\sawait\\s', '\\.then\\(', '\\sdebugger\\s'];// 'for\\s*\\(\\s*var\\s*\\w+\\s*in'];
22
22
 
23
23
  // gspx无用标签的修改建议
24
24
  var warnTagsInfo = {
@@ -58,6 +58,7 @@ module.exports.start = async function() {
58
58
  var errDatas = {};
59
59
  var undefDatas = {};
60
60
  var trimErrDatas = {};
61
+ var forinDatas = {};
61
62
  var warnDatas = {};
62
63
  var infoDatas = {};
63
64
  var bigList = [];
@@ -115,6 +116,7 @@ module.exports.start = async function() {
115
116
  var infoList = [];
116
117
  var ieList = [];
117
118
  var undefList = [];
119
+ var forinList = [];
118
120
  var res = eslintResults[0];
119
121
  res.messages.forEach((item) => {
120
122
  var reg = new RegExp(/'\$\w+'\sis\snot\sdefined\./);
@@ -133,6 +135,8 @@ module.exports.start = async function() {
133
135
  } else if (item.ruleId.includes('comma-dangle')) {
134
136
  list = ieList;
135
137
  item.message += '多余的逗号';
138
+ } else if (item.ruleId.includes('no-restricted-syntax')) {
139
+ list = forinList;
136
140
  } else if (item.ruleId.indexOf('no-unused-vars') > -1) {
137
141
  if (item.message && (item.message.includes("'sender'") || item.message.includes("'eventArgs'")) || item.message.includes("'args'")) {
138
142
  return;
@@ -150,6 +154,9 @@ module.exports.start = async function() {
150
154
  if (ieList.length > 0) {
151
155
  errDatas[filePath] = ieList;
152
156
  }
157
+ if (forinList.length > 0) {
158
+ forinDatas[filePath] = forinList;
159
+ }
153
160
  if (infoList.length > 0) {
154
161
  infoDatas[filePath] = infoList;
155
162
  }
@@ -194,6 +201,7 @@ module.exports.start = async function() {
194
201
  var trimErrKeys = Object.keys(trimErrDatas);
195
202
  var errKeys = Object.keys(errDatas);
196
203
  var undefKeys = Object.keys(undefDatas);
204
+ var forinKeys = Object.keys(forinDatas);
197
205
  var warnKeys = Object.keys(warnDatas);
198
206
  var infoKeys = Object.keys(infoDatas);
199
207
  var reportData = {
@@ -236,6 +244,7 @@ module.exports.start = async function() {
236
244
  info.push("| ------ | ------ | ----- |");
237
245
  info.push(`| js语法兼容性 | ${errKeys.length}个 |${calc(errKeys.length, jsFiles.length)}|`);
238
246
  info.push(`| js语法undefined | ${undefKeys.length}个 |${calc(undefKeys.length, jsFiles.length)}|`);
247
+ info.push(`| for..in语法 | ${forinKeys.length}个 |${calc(forinKeys.length, jsFiles.length)}|`);
239
248
  info.push(`| trim、trimEnd或trimStart异常数 | ${trimErrKeys.length}个 |${calc(trimErrKeys.length, jsFiles.length)}|`);
240
249
  info.push(`| 语法警告文件数Warn | ${warnKeys.length}个 |${calc(warnKeys.length, jsFiles.length)}|`);
241
250
  info.push(`| 语法提示文件数Info | ${infoKeys.length}个 |${calc(infoKeys.length, jsFiles.length)}|`);
@@ -256,6 +265,7 @@ module.exports.start = async function() {
256
265
  reportData.data = {
257
266
  errorCount: errKeys.length,
258
267
  undefCount: undefKeys.length, // 未定义总数
268
+ forinCount: forinKeys.length,
259
269
  warnCount: warnKeys.length,
260
270
  tipCount: infoKeys.length,
261
271
  fileSize: fileSize,
@@ -284,6 +294,7 @@ module.exports.start = async function() {
284
294
  //if (errKeys.length > 0) {
285
295
  webhookList.push(`1. js语法兼容性:${errKeys.length}个,占比${calc(errKeys.length, jsFiles.length)}`);
286
296
  webhookList.push(`1. js语法undefined:${undefKeys.length}个,占比${calc(undefKeys.length, jsFiles.length)}`);
297
+ webhookList.push(`1. for..in语法:${forinKeys.length}个,占比${calc(forinKeys.length, jsFiles.length)}`);
287
298
 
288
299
  // 随机显示5个异常文件到钉钉消息
289
300
  var errCount = reportData.data.errCount + reportData.data.undefCount;
@@ -368,6 +379,26 @@ module.exports.start = async function() {
368
379
  });
369
380
  }
370
381
 
382
+ if (forinKeys.length > 0) {
383
+ detail.push("");
384
+ detail.push(`# ${forinKeys.length}个for in(建议修复)`);
385
+ detail.push(`::: tip`);
386
+ detail.push(`1. 如果当前是数组,不建议使用for..in循环,会遍历出原型链的方法容易出现意外问题,可以改用forEach和普通for循环;2. 如果是对象,就可以用for..in;3.for of有兼容性不能用`);
387
+ detail.push(`:::`);
388
+ forinKeys.forEach((fileName, index) => {
389
+
390
+ detail.push(`${index + 1}. ${fileName}`);
391
+
392
+ var infoList = forinDatas[fileName];
393
+ detail.push("| 类型 | 行号 | 列号 | 说明 |");
394
+ detail.push("| ----- | ------ | ---- | ---- |");
395
+ infoList.forEach((item) => {
396
+ detail.push(`| ${item.char.trim()} | ${item.line || '-'} | ${item.column || '-'} | ${item.msg || '-'} |`);
397
+ sonar.issues.push(getSonarEntity('未定义', modName, item.char.trim(), item.msg, fileName, item.line, item.column, item.endLine));
398
+ });
399
+ });
400
+ }
401
+
371
402
 
372
403
  if (trimErrKeys.length > 0) {
373
404
  detail.push("");