mm_eslint 1.1.6 → 1.1.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.
Files changed (2) hide show
  1. package/index.js +128 -3
  2. package/package.json +1 -1
package/index.js CHANGED
@@ -189,6 +189,25 @@ class Detector {
189
189
  'setup', 'init', 'internal', 'private', 'helper', 'util'
190
190
  ],
191
191
 
192
+ // 忽略词列表:这些词汇在命名检测时会被忽略,不进行长度和风格检测
193
+ ignore_words: {
194
+ // 类名忽略词:这些词汇在类名中允许使用,即使超过8个字符
195
+ class: [
196
+ "Controller", "Middleware", "Component", "Repository", "Validator",
197
+ "Transformer", "Serializer", "Interceptor", "Decorator", "Provider"
198
+ ],
199
+ // 方法名忽略词:这些词汇在方法名中允许使用,即使超过8个字符
200
+ method: [
201
+ "middleware", "controller", "component", "repository", "validator",
202
+ "transformer", "serializer", "interceptor", "decorator", "provider"
203
+ ],
204
+ // 函数名忽略词:这些词汇在函数名中允许使用,即使超过8个字符
205
+ function: [
206
+ "middleware", "controller", "component", "repository", "validator",
207
+ "transformer", "serializer", "interceptor", "decorator", "provider"
208
+ ]
209
+ },
210
+
192
211
  // 废话词
193
212
  forbidden_words: {
194
213
  // 类废话词:禁止在类名中使用的冗余拼接词汇(统一小写)
@@ -211,8 +230,8 @@ class Detector {
211
230
  "data", "result", "output", "input", "param", "params", "parameter", "parameters",
212
231
  "value", "values", "item", "items",
213
232
  // 通用处理词汇(动词已经表达了处理,这些名词是冗余的)
214
- "process", "handler", "processor", "manager", "controller", "service", "provider",
215
- "factory", "builder", "adapter", "decorator", "proxy", "facade", "mediator",
233
+ "process", "processor", "provider",
234
+ "builder", "adapter", "decorator", "proxy", "facade", "mediator",
216
235
  "observer", "strategy", "command", "visitor", "iterator", "template",
217
236
  "flyweight", "memento", "interpreter",
218
237
  // 临时缓存词汇(动词已经表达了操作,这些名词是冗余的)
@@ -388,7 +407,7 @@ class Detector {
388
407
  Object.keys(config).forEach((key) => {
389
408
  if (merged_cfg[key] && typeof merged_cfg[key] === "object" && !Array.isArray(merged_cfg[key])) {
390
409
  // 如果是对象配置(如规则配置),则深度合并
391
- merged_cfg[key] = { ...merged_cfg[key], ...config[key] };
410
+ merged_cfg[key] = this._deepMerge(merged_cfg[key], config[key]);
392
411
 
393
412
  // 处理字符串形式的正则表达式
394
413
  if (typeof merged_cfg[key].regex === "string") {
@@ -419,6 +438,37 @@ class Detector {
419
438
  this.config = merged_cfg;
420
439
  this._initRule();
421
440
  }
441
+
442
+ /**
443
+ * 深度合并两个对象
444
+ * @param {Object} target 目标对象
445
+ * @param {Object} source 源对象
446
+ * @returns {Object} 合并后的对象
447
+ * @private
448
+ */
449
+ _deepMerge(target, source) {
450
+ const result = { ...target };
451
+
452
+ Object.keys(source).forEach((key) => {
453
+ const source_val = source[key];
454
+ const target_val = target[key];
455
+
456
+ if (Array.isArray(source_val) && Array.isArray(target_val)) {
457
+ // 如果是数组,则合并数组(去重)
458
+ result[key] = [...new Set([...target_val, ...source_val])];
459
+ } else if (typeof source_val === 'object' && source_val !== null &&
460
+ typeof target_val === 'object' && target_val !== null &&
461
+ !Array.isArray(source_val) && !Array.isArray(target_val)) {
462
+ // 如果是对象,则递归深度合并
463
+ result[key] = this._deepMerge(target_val, source_val);
464
+ } else {
465
+ // 其他情况直接覆盖
466
+ result[key] = source_val;
467
+ }
468
+ });
469
+
470
+ return result;
471
+ }
422
472
  }
423
473
 
424
474
  /**
@@ -482,6 +532,16 @@ Detector.prototype._checkName = function (rule_type, name) {
482
532
  const warnings = [];
483
533
  const recommendations = [];
484
534
 
535
+ // 首先检查是否为忽略词,如果是则跳过其他检测
536
+ if (this._isIgnoreWord(name, rule_type)) {
537
+ return {
538
+ valid: true,
539
+ errors: [],
540
+ warnings: [],
541
+ recommendations: []
542
+ };
543
+ }
544
+
485
545
  this._checkNameLength(name, config, errors);
486
546
  this._checkNameFormat(name, rule_type, config, errors);
487
547
  this._checkBadWords(name, config, errors);
@@ -1504,6 +1564,44 @@ Detector.prototype._isCompoundName = function (name) {
1504
1564
  return false;
1505
1565
  };
1506
1566
 
1567
+ /**
1568
+ * 检查是否为忽略词
1569
+ * @param {string} name - 名称
1570
+ * @param {string} rule_type - 规则类型
1571
+ * @returns {boolean} 是否为忽略词
1572
+ * @private
1573
+ */
1574
+ Detector.prototype._isIgnoreWord = function (name, rule_type) {
1575
+ // 获取忽略词配置
1576
+ const ignore_words_config = this.config.ignore_words;
1577
+ if (!ignore_words_config) {
1578
+ return false;
1579
+ }
1580
+
1581
+ // 根据规则类型获取对应的忽略词列表
1582
+ let ignore_list = [];
1583
+ if (rule_type === "class-name") {
1584
+ ignore_list = ignore_words_config.class || [];
1585
+ } else if (rule_type === "method-name") {
1586
+ ignore_list = ignore_words_config.method || [];
1587
+ } else if (rule_type === "function-name") {
1588
+ ignore_list = ignore_words_config.function || [];
1589
+ }
1590
+
1591
+ // 检查名称是否完全匹配忽略词列表中的任何一个词
1592
+ // 支持精确匹配和包含匹配(如果名称包含忽略词,则整个名称都被忽略)
1593
+ // 支持大小写不敏感匹配
1594
+ const name_lower = name.toLowerCase();
1595
+ for (const ignore_word of ignore_list) {
1596
+ const ignore_word_lower = ignore_word.toLowerCase();
1597
+ if (name_lower === ignore_word_lower || name_lower.includes(ignore_word_lower)) {
1598
+ return true;
1599
+ }
1600
+ }
1601
+
1602
+ return false;
1603
+ };
1604
+
1507
1605
  /**
1508
1606
  * 检查推荐词并生成推荐建议
1509
1607
  * @param {string} name - 名称
@@ -1660,6 +1758,15 @@ const class_name_rule = {
1660
1758
  single_word: { type: "boolean" },
1661
1759
  single_word_len: { type: "number" },
1662
1760
  styles: { type: "array", items: { type: "string" } },
1761
+ ignore_words: {
1762
+ type: "object",
1763
+ properties: {
1764
+ class: { type: "array", items: { type: "string" } },
1765
+ method: { type: "array", items: { type: "string" } },
1766
+ function: { type: "array", items: { type: "string" } }
1767
+ },
1768
+ additionalProperties: false
1769
+ }
1663
1770
  },
1664
1771
  additionalProperties: false,
1665
1772
  },
@@ -1708,6 +1815,15 @@ const function_name_rule = {
1708
1815
  single_word: { type: "boolean" },
1709
1816
  single_word_len: { type: "number" },
1710
1817
  styles: { type: "array", items: { type: "string" } },
1818
+ ignore_words: {
1819
+ type: "object",
1820
+ properties: {
1821
+ class: { type: "array", items: { type: "string" } },
1822
+ method: { type: "array", items: { type: "string" } },
1823
+ function: { type: "array", items: { type: "string" } }
1824
+ },
1825
+ additionalProperties: false
1826
+ }
1711
1827
  },
1712
1828
  additionalProperties: false,
1713
1829
  },
@@ -1775,6 +1891,15 @@ const method_name_rule = {
1775
1891
  single_word: { type: "boolean" },
1776
1892
  single_word_len: { type: "number" },
1777
1893
  styles: { type: "array", items: { type: "string" } },
1894
+ ignore_words: {
1895
+ type: "object",
1896
+ properties: {
1897
+ class: { type: "array", items: { type: "string" } },
1898
+ method: { type: "array", items: { type: "string" } },
1899
+ function: { type: "array", items: { type: "string" } }
1900
+ },
1901
+ additionalProperties: false
1902
+ }
1778
1903
  },
1779
1904
  additionalProperties: false,
1780
1905
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mm_eslint",
3
- "version": "1.1.6",
3
+ "version": "1.1.8",
4
4
  "description": "ESLint plugin for naming conventions - PascalCase, camelCase, snake_case, and UPPER_SNAKE_CASE naming rules",
5
5
  "main": "index.js",
6
6
  "keywords": [