@nokecy/qc-ui 1.0.66 → 1.0.67

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 (123) hide show
  1. package/dist/cjs/components/RegexEditor/core/RegexEditor.d.ts +34 -0
  2. package/dist/cjs/components/RegexEditor/core/RegexEditor.js +223 -0
  3. package/dist/cjs/components/RegexEditor/core/RegexEditor.less +119 -0
  4. package/dist/cjs/components/RegexEditor/core/extensions/errorMarker.d.ts +49 -0
  5. package/dist/cjs/components/RegexEditor/core/extensions/errorMarker.js +158 -0
  6. package/dist/cjs/components/RegexEditor/core/types.d.ts +79 -0
  7. package/dist/cjs/components/RegexEditor/core/types.js +5 -0
  8. package/dist/cjs/components/RegexEditor/hooks/index.d.ts +9 -0
  9. package/dist/cjs/components/RegexEditor/hooks/index.js +19 -0
  10. package/dist/cjs/components/RegexEditor/hooks/useRegexTester.d.ts +95 -0
  11. package/dist/cjs/components/RegexEditor/hooks/useRegexTester.js +234 -0
  12. package/dist/cjs/components/RegexEditor/hooks/useRegexValidation.d.ts +71 -0
  13. package/dist/cjs/components/RegexEditor/hooks/useRegexValidation.js +215 -0
  14. package/dist/cjs/components/RegexEditor/hooks/useTemplateManager.d.ts +64 -0
  15. package/dist/cjs/components/RegexEditor/hooks/useTemplateManager.js +438 -0
  16. package/dist/cjs/components/RegexEditor/index.d.ts +16 -0
  17. package/dist/cjs/components/RegexEditor/index.js +232 -0
  18. package/dist/cjs/components/RegexEditor/templates/TemplateSelector.d.ts +36 -0
  19. package/dist/cjs/components/RegexEditor/templates/TemplateSelector.js +322 -0
  20. package/dist/cjs/components/RegexEditor/templates/builtinTemplates.d.ts +36 -0
  21. package/dist/cjs/components/RegexEditor/templates/builtinTemplates.js +340 -0
  22. package/dist/cjs/components/RegexEditor/templates/index.d.ts +10 -0
  23. package/dist/cjs/components/RegexEditor/templates/index.js +184 -0
  24. package/dist/cjs/components/RegexEditor/templates/storage.d.ts +74 -0
  25. package/dist/cjs/components/RegexEditor/templates/storage.js +337 -0
  26. package/dist/cjs/components/RegexEditor/templates/templateManager.d.ts +67 -0
  27. package/dist/cjs/components/RegexEditor/templates/templateManager.js +277 -0
  28. package/dist/cjs/components/RegexEditor/templates/types.d.ts +111 -0
  29. package/dist/cjs/components/RegexEditor/templates/types.js +94 -0
  30. package/dist/cjs/components/RegexEditor/testing/types.d.ts +55 -0
  31. package/dist/cjs/components/RegexEditor/testing/types.js +5 -0
  32. package/dist/cjs/components/RegexEditor/validation/complexity.d.ts +22 -0
  33. package/dist/cjs/components/RegexEditor/validation/complexity.js +196 -0
  34. package/dist/cjs/components/RegexEditor/validation/parser.d.ts +53 -0
  35. package/dist/cjs/components/RegexEditor/validation/parser.js +129 -0
  36. package/dist/cjs/components/RegexEditor/validation/types.d.ts +146 -0
  37. package/dist/cjs/components/RegexEditor/validation/types.js +5 -0
  38. package/dist/cjs/components/RegexEditor/validation/validator.d.ts +60 -0
  39. package/dist/cjs/components/RegexEditor/validation/validator.js +218 -0
  40. package/dist/cjs/components/RegexEditor/visualizer/FlagsSelector.d.ts +20 -0
  41. package/dist/cjs/components/RegexEditor/visualizer/FlagsSelector.js +98 -0
  42. package/dist/cjs/components/RegexEditor/visualizer/MatchItem.d.ts +25 -0
  43. package/dist/cjs/components/RegexEditor/visualizer/MatchItem.js +201 -0
  44. package/dist/cjs/components/RegexEditor/visualizer/RegexRailroadDiagram.d.ts +32 -0
  45. package/dist/cjs/components/RegexEditor/visualizer/RegexRailroadDiagram.js +192 -0
  46. package/dist/cjs/components/RegexEditor/visualizer/RegexTester.d.ts +22 -0
  47. package/dist/cjs/components/RegexEditor/visualizer/RegexTester.js +255 -0
  48. package/dist/cjs/components/RegexEditor/visualizer/astToRailroad.d.ts +19 -0
  49. package/dist/cjs/components/RegexEditor/visualizer/astToRailroad.js +155 -0
  50. package/dist/cjs/components/RegexEditor/visualizer/index.d.ts +12 -0
  51. package/dist/cjs/components/RegexEditor/visualizer/index.js +76 -0
  52. package/dist/cjs/components/RegexEditor/visualizer/types.d.ts +131 -0
  53. package/dist/cjs/components/RegexEditor/visualizer/types.js +5 -0
  54. package/dist/cjs/components/RegexEditor/visualizer/utils.d.ts +106 -0
  55. package/dist/cjs/components/RegexEditor/visualizer/utils.js +268 -0
  56. package/dist/cjs/index.d.ts +3 -1
  57. package/dist/cjs/index.js +55 -0
  58. package/dist/cjs/standardFormDialog/useStandardFormSchema.d.ts +1 -1
  59. package/dist/cjs/standardFormDialog/withStandardForm.d.ts +2 -2
  60. package/dist/cjs/types/railroad-diagrams.d.ts +59 -0
  61. package/dist/cjs/types/regexp-tree.d.ts +175 -0
  62. package/dist/esm/components/RegexEditor/core/RegexEditor.d.ts +34 -0
  63. package/dist/esm/components/RegexEditor/core/RegexEditor.js +214 -0
  64. package/dist/esm/components/RegexEditor/core/RegexEditor.less +119 -0
  65. package/dist/esm/components/RegexEditor/core/extensions/errorMarker.d.ts +49 -0
  66. package/dist/esm/components/RegexEditor/core/extensions/errorMarker.js +154 -0
  67. package/dist/esm/components/RegexEditor/core/types.d.ts +79 -0
  68. package/dist/esm/components/RegexEditor/core/types.js +1 -0
  69. package/dist/esm/components/RegexEditor/hooks/index.d.ts +9 -0
  70. package/dist/esm/components/RegexEditor/hooks/index.js +8 -0
  71. package/dist/esm/components/RegexEditor/hooks/useRegexTester.d.ts +95 -0
  72. package/dist/esm/components/RegexEditor/hooks/useRegexTester.js +230 -0
  73. package/dist/esm/components/RegexEditor/hooks/useRegexValidation.d.ts +71 -0
  74. package/dist/esm/components/RegexEditor/hooks/useRegexValidation.js +211 -0
  75. package/dist/esm/components/RegexEditor/hooks/useTemplateManager.d.ts +64 -0
  76. package/dist/esm/components/RegexEditor/hooks/useTemplateManager.js +430 -0
  77. package/dist/esm/components/RegexEditor/index.d.ts +16 -0
  78. package/dist/esm/components/RegexEditor/index.js +27 -0
  79. package/dist/esm/components/RegexEditor/templates/TemplateSelector.d.ts +36 -0
  80. package/dist/esm/components/RegexEditor/templates/TemplateSelector.js +316 -0
  81. package/dist/esm/components/RegexEditor/templates/builtinTemplates.d.ts +36 -0
  82. package/dist/esm/components/RegexEditor/templates/builtinTemplates.js +335 -0
  83. package/dist/esm/components/RegexEditor/templates/index.d.ts +10 -0
  84. package/dist/esm/components/RegexEditor/templates/index.js +19 -0
  85. package/dist/esm/components/RegexEditor/templates/storage.d.ts +74 -0
  86. package/dist/esm/components/RegexEditor/templates/storage.js +335 -0
  87. package/dist/esm/components/RegexEditor/templates/templateManager.d.ts +67 -0
  88. package/dist/esm/components/RegexEditor/templates/templateManager.js +274 -0
  89. package/dist/esm/components/RegexEditor/templates/types.d.ts +111 -0
  90. package/dist/esm/components/RegexEditor/templates/types.js +90 -0
  91. package/dist/esm/components/RegexEditor/testing/types.d.ts +55 -0
  92. package/dist/esm/components/RegexEditor/testing/types.js +1 -0
  93. package/dist/esm/components/RegexEditor/validation/complexity.d.ts +22 -0
  94. package/dist/esm/components/RegexEditor/validation/complexity.js +190 -0
  95. package/dist/esm/components/RegexEditor/validation/parser.d.ts +53 -0
  96. package/dist/esm/components/RegexEditor/validation/parser.js +123 -0
  97. package/dist/esm/components/RegexEditor/validation/types.d.ts +145 -0
  98. package/dist/esm/components/RegexEditor/validation/types.js +1 -0
  99. package/dist/esm/components/RegexEditor/validation/validator.d.ts +60 -0
  100. package/dist/esm/components/RegexEditor/validation/validator.js +213 -0
  101. package/dist/esm/components/RegexEditor/visualizer/FlagsSelector.d.ts +20 -0
  102. package/dist/esm/components/RegexEditor/visualizer/FlagsSelector.js +93 -0
  103. package/dist/esm/components/RegexEditor/visualizer/MatchItem.d.ts +25 -0
  104. package/dist/esm/components/RegexEditor/visualizer/MatchItem.js +194 -0
  105. package/dist/esm/components/RegexEditor/visualizer/RegexRailroadDiagram.d.ts +32 -0
  106. package/dist/esm/components/RegexEditor/visualizer/RegexRailroadDiagram.js +186 -0
  107. package/dist/esm/components/RegexEditor/visualizer/RegexTester.d.ts +22 -0
  108. package/dist/esm/components/RegexEditor/visualizer/RegexTester.js +248 -0
  109. package/dist/esm/components/RegexEditor/visualizer/astToRailroad.d.ts +18 -0
  110. package/dist/esm/components/RegexEditor/visualizer/astToRailroad.js +150 -0
  111. package/dist/esm/components/RegexEditor/visualizer/index.d.ts +12 -0
  112. package/dist/esm/components/RegexEditor/visualizer/index.js +17 -0
  113. package/dist/esm/components/RegexEditor/visualizer/types.d.ts +131 -0
  114. package/dist/esm/components/RegexEditor/visualizer/types.js +1 -0
  115. package/dist/esm/components/RegexEditor/visualizer/utils.d.ts +106 -0
  116. package/dist/esm/components/RegexEditor/visualizer/utils.js +256 -0
  117. package/dist/esm/index.d.ts +3 -1
  118. package/dist/esm/index.js +5 -2
  119. package/dist/esm/types/railroad-diagrams.d.ts +59 -0
  120. package/dist/esm/types/regexp-tree.d.ts +175 -0
  121. package/dist/umd/qc-ui.min.css +1 -1
  122. package/dist/umd/qc-ui.min.js +1 -1
  123. package/package.json +23 -7
@@ -0,0 +1,146 @@
1
+ /**
2
+ * 正则表达式验证引擎 - 类型定义
3
+ *
4
+ * @module RegexEditor/validation/types
5
+ * @description 定义正则表达式解析、验证、复杂度分析相关的核心类型
6
+ */
7
+ /// <reference types="dist/cjs/types/regexp-tree" />
8
+ /// <reference types="src/types/regexp-tree" />
9
+ /// <reference types="dist/esm/types/regexp-tree" />
10
+ /// <reference types="regexp-tree" />
11
+ /**
12
+ * regexp-tree 的 AST 节点类型
13
+ *
14
+ * @remarks
15
+ * 使用 regexp-tree 库提供的官方类型定义。
16
+ * 节点包含 type, loc, expression 等属性,支持完整的类型推导。
17
+ *
18
+ * 注意: 'regexp-tree/ast' 子模块的类型声明在 src/types/regexp-tree-ast.d.ts 中定义
19
+ *
20
+ * @see https://github.com/DmitrySoshnikov/regexp-tree
21
+ */
22
+ import type { AstNode, AstRegExp as RegExpAstNode } from 'regexp-tree/ast';
23
+ export type ASTNode = AstNode;
24
+ export type AstRegExp = RegExpAstNode;
25
+ /**
26
+ * 正则表达式解析结果
27
+ *
28
+ * @interface ParseResult
29
+ * @property {boolean} success - 解析是否成功
30
+ * @property {ASTNode} [ast] - 抽象语法树节点(成功时存在)
31
+ * @property {string} pattern - 原始正则表达式字符串
32
+ * @property {RegexError} [error] - 解析错误信息(失败时存在)
33
+ *
34
+ * @example
35
+ * ```typescript
36
+ * const result = parseRegex('^LOT\\d{6}$');
37
+ * if (result.success) {
38
+ * console.log(result.ast);
39
+ * } else {
40
+ * console.error(result.error);
41
+ * }
42
+ * ```
43
+ */
44
+ export interface ParseResult {
45
+ success: boolean;
46
+ ast?: ASTNode;
47
+ pattern: string;
48
+ error?: RegexError;
49
+ }
50
+ /**
51
+ * 正则表达式验证结果
52
+ *
53
+ * @interface ValidationResult
54
+ * @property {boolean} valid - 验证是否通过(无错误,可能有警告)
55
+ * @property {RegexError[]} errors - 错误列表(仅包含 severity='error' 的项)
56
+ * @property {RegexError[]} warnings - 警告列表(仅包含 severity='warning' 的项)
57
+ * @property {RegexError[]} infos - 信息列表(仅包含 severity='info' 的项)
58
+ * @property {string} pattern - 被验证的正则表达式字符串
59
+ *
60
+ * @example
61
+ * ```typescript
62
+ * const result = validateRegex(pattern);
63
+ *
64
+ * if (result.errors.length > 0) {
65
+ * console.error('验证失败:', result.errors);
66
+ * } else if (result.warnings.length > 0) {
67
+ * console.warn('验证通过但有警告:', result.warnings);
68
+ * } else {
69
+ * console.log('验证完全通过');
70
+ * }
71
+ * ```
72
+ */
73
+ export interface ValidationResult {
74
+ valid: boolean;
75
+ errors: RegexError[];
76
+ warnings: RegexError[];
77
+ infos: RegexError[];
78
+ pattern: string;
79
+ }
80
+ /**
81
+ * 正则表达式错误信息
82
+ *
83
+ * @interface RegexError
84
+ * @property {string} type - 错误类型标识符
85
+ * @property {string} message - 人类可读的错误描述
86
+ * @property {Object} position - 错误位置范围
87
+ * @property {number} position.start - 起始位置(字符索引)
88
+ * @property {number} position.end - 结束位置(字符索引)
89
+ * @property {'error' | 'warning' | 'info'} severity - 严重程度
90
+ * @property {string} [suggestion] - 修复建议(可选)
91
+ *
92
+ * @example
93
+ * ```typescript
94
+ * const error: RegexError = {
95
+ * type: 'empty_group',
96
+ * message: '空的捕获组,建议使用非捕获组 (?:)',
97
+ * position: { start: 5, end: 7 },
98
+ * severity: 'warning',
99
+ * suggestion: '使用 (?:) 代替 ()'
100
+ * };
101
+ * ```
102
+ */
103
+ export interface RegexError {
104
+ type: string;
105
+ message: string;
106
+ position: {
107
+ start: number;
108
+ end: number;
109
+ };
110
+ severity: 'error' | 'warning' | 'info';
111
+ suggestion?: string;
112
+ }
113
+ /**
114
+ * 正则表达式复杂度指标
115
+ *
116
+ * @interface ComplexityMetrics
117
+ * @property {number} nodeCount - AST 节点总数
118
+ * @property {number} depth - 最大嵌套深度
119
+ * @property {number} alternationCount - 分支数量 (|)
120
+ * @property {number} quantifierCount - 量词数量 (+, *, {n,m})
121
+ * @property {number} groupCount - 捕获组数量
122
+ * @property {number} characterClassCount - 字符类数量 ([...])
123
+ * @property {'low' | 'medium' | 'high'} backtrackingRisk - 回溯风险等级
124
+ * @property {number} performanceScore - 性能评分 (0-100)
125
+ * @property {string[]} suggestions - 优化建议列表
126
+ *
127
+ * @example
128
+ * ```typescript
129
+ * const metrics = analyzeComplexity(ast);
130
+ * if (metrics.backtrackingRisk === 'high') {
131
+ * console.warn('高回溯风险:', metrics.suggestions);
132
+ * }
133
+ * console.log('性能评分:', metrics.performanceScore);
134
+ * ```
135
+ */
136
+ export interface ComplexityMetrics {
137
+ nodeCount: number;
138
+ depth: number;
139
+ alternationCount: number;
140
+ quantifierCount: number;
141
+ groupCount: number;
142
+ characterClassCount: number;
143
+ backtrackingRisk: 'low' | 'medium' | 'high';
144
+ performanceScore: number;
145
+ suggestions: string[];
146
+ }
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
@@ -0,0 +1,60 @@
1
+ /**
2
+ * 正则表达式语法验证器
3
+ *
4
+ * @module RegexEditor/validation/validator
5
+ * @description 检测正则表达式的常见语法错误和安全问题
6
+ *
7
+ * @remarks
8
+ * 该模块基于 regexp-tree AST 提供以下验证规则:
9
+ * 1. 空捕获组检测 - 检测 () 并建议使用 (?:)
10
+ * 2. 无效量词检测 - 检测 {min,max} 中 min > max
11
+ * 3. 嵌套量词检测 - 检测 (a+)+ 等导致灾难性回溯的模式
12
+ * 4. 未闭合组检测 - 通过解析错误自动检测
13
+ *
14
+ * @see {@link parseRegex} 用于解析正则表达式
15
+ */
16
+ import type { ASTNode, RegexError, ValidationResult } from './types';
17
+ /**
18
+ * 验证正则表达式 AST
19
+ *
20
+ * @param ast - 抽象语法树节点
21
+ * @returns {RegexError[]} 错误和警告列表
22
+ *
23
+ * @remarks
24
+ * 该函数遍历 AST 节点,应用以下验证规则:
25
+ * - 空捕获组 (警告)
26
+ * - 无效量词 (错误)
27
+ * - 嵌套量词/灾难性回溯 (错误)
28
+ *
29
+ * @example
30
+ * ```typescript
31
+ * const result = parseRegex('()test');
32
+ * const errors = validateRegex(result.ast!);
33
+ * console.log(errors); // [{ type: 'empty_group', severity: 'warning', ... }]
34
+ * ```
35
+ */
36
+ export declare const validateRegex: (ast: ASTNode) => RegexError[];
37
+ /**
38
+ * 整合验证流程: 解析 + 语法验证
39
+ *
40
+ * @param pattern - 正则表达式字符串
41
+ * @param flags - 可选的正则表达式标志
42
+ * @returns {ValidationResult} 完整的验证结果
43
+ *
44
+ * @remarks
45
+ * 该函数整合了以下步骤:
46
+ * 1. 解析正则表达式 {@link parseRegex}
47
+ * 2. 语法验证 {@link validateRegex}
48
+ * 3. 分类错误、警告和信息
49
+ *
50
+ * @example
51
+ * ```typescript
52
+ * const result = validatePattern('^LOT\\d{6}$');
53
+ * if (result.valid) {
54
+ * console.log('验证通过');
55
+ * } else {
56
+ * console.error('错误:', result.errors);
57
+ * }
58
+ * ```
59
+ */
60
+ export declare const validatePattern: (pattern: string, flags?: string) => ValidationResult;
@@ -0,0 +1,218 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.validateRegex = exports.validatePattern = void 0;
7
+ var _parser = require("./parser");
8
+ /**
9
+ * 正则表达式语法验证器
10
+ *
11
+ * @module RegexEditor/validation/validator
12
+ * @description 检测正则表达式的常见语法错误和安全问题
13
+ *
14
+ * @remarks
15
+ * 该模块基于 regexp-tree AST 提供以下验证规则:
16
+ * 1. 空捕获组检测 - 检测 () 并建议使用 (?:)
17
+ * 2. 无效量词检测 - 检测 {min,max} 中 min > max
18
+ * 3. 嵌套量词检测 - 检测 (a+)+ 等导致灾难性回溯的模式
19
+ * 4. 未闭合组检测 - 通过解析错误自动检测
20
+ *
21
+ * @see {@link parseRegex} 用于解析正则表达式
22
+ */
23
+
24
+ /**
25
+ * 验证正则表达式 AST
26
+ *
27
+ * @param ast - 抽象语法树节点
28
+ * @returns {RegexError[]} 错误和警告列表
29
+ *
30
+ * @remarks
31
+ * 该函数遍历 AST 节点,应用以下验证规则:
32
+ * - 空捕获组 (警告)
33
+ * - 无效量词 (错误)
34
+ * - 嵌套量词/灾难性回溯 (错误)
35
+ *
36
+ * @example
37
+ * ```typescript
38
+ * const result = parseRegex('()test');
39
+ * const errors = validateRegex(result.ast!);
40
+ * console.log(errors); // [{ type: 'empty_group', severity: 'warning', ... }]
41
+ * ```
42
+ */
43
+ var validateRegex = exports.validateRegex = function validateRegex(ast) {
44
+ var errors = [];
45
+
46
+ // 规则1: 检查空捕获组
47
+ (0, _parser.traverseAST)(ast, {
48
+ Group: function Group(path) {
49
+ var node = path.node;
50
+
51
+ // 检查是否是捕获组且为空
52
+ if (node.capturing) {
53
+ // 空组的判断条件:
54
+ // - expression 为 undefined/null
55
+ // - expression.type 为 'Empty'
56
+ // - expression.type 为 'Alternative' 且 expressions 为空数组
57
+ var expression = node.expression;
58
+ var isEmpty = !expression || expression.type === 'Empty' || expression.type === 'Alternative' && Array.isArray(expression.expressions) && expression.expressions.length === 0;
59
+ if (isEmpty) {
60
+ var _node$loc, _node$loc2;
61
+ errors.push({
62
+ type: 'empty_group',
63
+ message: '空的捕获组,建议使用非捕获组 (?:)',
64
+ position: {
65
+ start: ((_node$loc = node.loc) === null || _node$loc === void 0 ? void 0 : _node$loc.start) || 0,
66
+ end: ((_node$loc2 = node.loc) === null || _node$loc2 === void 0 ? void 0 : _node$loc2.end) || 0
67
+ },
68
+ severity: 'warning',
69
+ suggestion: '使用 (?:) 代替 ()'
70
+ });
71
+ }
72
+ }
73
+ }
74
+ });
75
+
76
+ // 规则2: 检查无效量词
77
+ (0, _parser.traverseAST)(ast, {
78
+ Repetition: function Repetition(path) {
79
+ var node = path.node;
80
+ var quantifier = node.quantifier;
81
+
82
+ // 检查 {min,max} 形式的量词
83
+ if (quantifier && quantifier.kind === 'Range') {
84
+ var from = quantifier.from;
85
+ var to = quantifier.to;
86
+
87
+ // 检查最小值是否大于最大值
88
+ if (typeof from === 'number' && typeof to === 'number' && from > to) {
89
+ var _node$loc3, _node$loc4;
90
+ errors.push({
91
+ type: 'invalid_quantifier',
92
+ message: "\u65E0\u6548\u7684\u91CF\u8BCD: {".concat(from, ",").concat(to, "} - \u6700\u5C0F\u503C\u4E0D\u80FD\u5927\u4E8E\u6700\u5927\u503C"),
93
+ position: {
94
+ start: ((_node$loc3 = node.loc) === null || _node$loc3 === void 0 ? void 0 : _node$loc3.start) || 0,
95
+ end: ((_node$loc4 = node.loc) === null || _node$loc4 === void 0 ? void 0 : _node$loc4.end) || 0
96
+ },
97
+ severity: 'error',
98
+ suggestion: "\u4F7F\u7528 {".concat(to, ",").concat(from, "} \u6216\u4FEE\u6539\u4E3A\u6B63\u786E\u7684\u8303\u56F4")
99
+ });
100
+ }
101
+ }
102
+ }
103
+ });
104
+
105
+ // 规则3: 检查嵌套量词(灾难性回溯风险)
106
+ (0, _parser.traverseAST)(ast, {
107
+ Repetition: function Repetition(path) {
108
+ var _node$expression;
109
+ var node = path.node;
110
+
111
+ // 检查量词内部是否包含另一个量词
112
+ // 模式: (a+)+, (a*)+, (a?)+, (a{n,m})+
113
+ if (((_node$expression = node.expression) === null || _node$expression === void 0 ? void 0 : _node$expression.type) === 'Group') {
114
+ var group = node.expression;
115
+ var innerExpression = group.expression;
116
+
117
+ // 检查组内表达式是否是量词
118
+ if ((innerExpression === null || innerExpression === void 0 ? void 0 : innerExpression.type) === 'Repetition') {
119
+ var _node$loc5, _node$loc6;
120
+ errors.push({
121
+ type: 'catastrophic_backtracking',
122
+ message: '嵌套的量词可能导致灾难性回溯',
123
+ position: {
124
+ start: ((_node$loc5 = node.loc) === null || _node$loc5 === void 0 ? void 0 : _node$loc5.start) || 0,
125
+ end: ((_node$loc6 = node.loc) === null || _node$loc6 === void 0 ? void 0 : _node$loc6.end) || 0
126
+ },
127
+ severity: 'error',
128
+ suggestion: '考虑使用原子组 (?>...) 或重新设计表达式'
129
+ });
130
+ }
131
+
132
+ // 检查更复杂的嵌套: (a|b)+c
133
+ // Alternative 包含 Repetition
134
+ if ((innerExpression === null || innerExpression === void 0 ? void 0 : innerExpression.type) === 'Alternative') {
135
+ var expressions = innerExpression.expressions || [];
136
+ var hasInnerQuantifier = expressions.some(function (expr) {
137
+ return expr.type === 'Repetition';
138
+ });
139
+ if (hasInnerQuantifier) {
140
+ var _node$loc7, _node$loc8;
141
+ errors.push({
142
+ type: 'catastrophic_backtracking',
143
+ message: '嵌套的量词可能导致灾难性回溯',
144
+ position: {
145
+ start: ((_node$loc7 = node.loc) === null || _node$loc7 === void 0 ? void 0 : _node$loc7.start) || 0,
146
+ end: ((_node$loc8 = node.loc) === null || _node$loc8 === void 0 ? void 0 : _node$loc8.end) || 0
147
+ },
148
+ severity: 'error',
149
+ suggestion: '考虑使用原子组 (?>...) 或重新设计表达式'
150
+ });
151
+ }
152
+ }
153
+ }
154
+ }
155
+ });
156
+ return errors;
157
+ };
158
+
159
+ /**
160
+ * 整合验证流程: 解析 + 语法验证
161
+ *
162
+ * @param pattern - 正则表达式字符串
163
+ * @param flags - 可选的正则表达式标志
164
+ * @returns {ValidationResult} 完整的验证结果
165
+ *
166
+ * @remarks
167
+ * 该函数整合了以下步骤:
168
+ * 1. 解析正则表达式 {@link parseRegex}
169
+ * 2. 语法验证 {@link validateRegex}
170
+ * 3. 分类错误、警告和信息
171
+ *
172
+ * @example
173
+ * ```typescript
174
+ * const result = validatePattern('^LOT\\d{6}$');
175
+ * if (result.valid) {
176
+ * console.log('验证通过');
177
+ * } else {
178
+ * console.error('错误:', result.errors);
179
+ * }
180
+ * ```
181
+ */
182
+ var validatePattern = exports.validatePattern = function validatePattern(pattern, flags) {
183
+ // 1. 解析正则表达式
184
+ var parseResult = (0, _parser.parseRegex)(pattern, flags);
185
+
186
+ // 解析失败,返回解析错误
187
+ if (!parseResult.success) {
188
+ return {
189
+ valid: false,
190
+ errors: parseResult.error ? [parseResult.error] : [],
191
+ warnings: [],
192
+ infos: [],
193
+ pattern: pattern
194
+ };
195
+ }
196
+
197
+ // 2. 语法验证
198
+ var allErrors = validateRegex(parseResult.ast);
199
+
200
+ // 3. 分类错误、警告和信息
201
+ var errors = allErrors.filter(function (e) {
202
+ return e.severity === 'error';
203
+ });
204
+ var warnings = allErrors.filter(function (e) {
205
+ return e.severity === 'warning';
206
+ });
207
+ var infos = allErrors.filter(function (e) {
208
+ return e.severity === 'info';
209
+ });
210
+ return {
211
+ valid: errors.length === 0,
212
+ // 只有错误才影响 valid 状态
213
+ errors: errors,
214
+ warnings: warnings,
215
+ infos: infos,
216
+ pattern: pattern
217
+ };
218
+ };
@@ -0,0 +1,20 @@
1
+ /**
2
+ * FlagsSelector 组件
3
+ *
4
+ * @module RegexEditor/visualizer/FlagsSelector
5
+ * @description 正则表达式标志选择器组件
6
+ */
7
+ import React from 'react';
8
+ import type { FlagsSelectorProps } from './types';
9
+ /**
10
+ * 标志选择器组件
11
+ *
12
+ * @example
13
+ * ```tsx
14
+ * <FlagsSelector
15
+ * value={{ global: true, ignoreCase: true }}
16
+ * onChange={(flags) => console.log(flags)}
17
+ * />
18
+ * ```
19
+ */
20
+ export declare const FlagsSelector: React.FC<FlagsSelectorProps>;
@@ -0,0 +1,98 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.FlagsSelector = void 0;
7
+ var _react = _interopRequireDefault(require("react"));
8
+ var _antd = require("antd");
9
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
10
+ function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
11
+ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
12
+ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
13
+ function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
14
+ function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : String(i); }
15
+ function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); } /**
16
+ * FlagsSelector 组件
17
+ *
18
+ * @module RegexEditor/visualizer/FlagsSelector
19
+ * @description 正则表达式标志选择器组件
20
+ */
21
+ /**
22
+ * 标志配置
23
+ */
24
+ var FLAG_CONFIG = [{
25
+ key: 'global',
26
+ label: 'g',
27
+ tooltip: '全局匹配 (global) - 查找所有匹配项'
28
+ }, {
29
+ key: 'ignoreCase',
30
+ label: 'i',
31
+ tooltip: '忽略大小写 (ignoreCase) - 不区分大小写'
32
+ }, {
33
+ key: 'multiline',
34
+ label: 'm',
35
+ tooltip: '多行模式 (multiline) - ^ 和 $ 匹配行首行尾'
36
+ }, {
37
+ key: 'dotAll',
38
+ label: 's',
39
+ tooltip: 'dotAll 模式 - . 匹配包括换行符在内的所有字符'
40
+ }, {
41
+ key: 'unicode',
42
+ label: 'u',
43
+ tooltip: 'Unicode 模式 - 启用 Unicode 匹配'
44
+ }, {
45
+ key: 'sticky',
46
+ label: 'y',
47
+ tooltip: '粘性匹配 (sticky) - 从 lastIndex 位置开始匹配'
48
+ }];
49
+
50
+ /**
51
+ * 标志选择器组件
52
+ *
53
+ * @example
54
+ * ```tsx
55
+ * <FlagsSelector
56
+ * value={{ global: true, ignoreCase: true }}
57
+ * onChange={(flags) => console.log(flags)}
58
+ * />
59
+ * ```
60
+ */
61
+ var FlagsSelector = exports.FlagsSelector = function FlagsSelector(_ref) {
62
+ var _ref$value = _ref.value,
63
+ value = _ref$value === void 0 ? {} : _ref$value,
64
+ onChange = _ref.onChange,
65
+ _ref$disabled = _ref.disabled,
66
+ disabled = _ref$disabled === void 0 ? false : _ref$disabled;
67
+ /**
68
+ * 处理标志变化
69
+ */
70
+ var handleChange = function handleChange(key) {
71
+ return function (e) {
72
+ if (onChange) {
73
+ onChange(_objectSpread(_objectSpread({}, value), {}, _defineProperty({}, key, e.target.checked)));
74
+ }
75
+ };
76
+ };
77
+ return /*#__PURE__*/_react.default.createElement(_antd.Space, {
78
+ size: "small"
79
+ }, /*#__PURE__*/_react.default.createElement("span", {
80
+ style: {
81
+ color: '#666'
82
+ }
83
+ }, "\u6807\u5FD7:"), FLAG_CONFIG.map(function (flag) {
84
+ return /*#__PURE__*/_react.default.createElement(_antd.Tooltip, {
85
+ key: flag.key,
86
+ title: flag.tooltip
87
+ }, /*#__PURE__*/_react.default.createElement(_antd.Checkbox, {
88
+ checked: value[flag.key],
89
+ onChange: handleChange(flag.key),
90
+ disabled: disabled
91
+ }, /*#__PURE__*/_react.default.createElement("code", {
92
+ style: {
93
+ fontSize: '13px',
94
+ fontWeight: 'bold'
95
+ }
96
+ }, flag.label)));
97
+ }));
98
+ };
@@ -0,0 +1,25 @@
1
+ /**
2
+ * MatchItem 组件
3
+ *
4
+ * @module RegexEditor/visualizer/MatchItem
5
+ * @description 匹配结果项组件
6
+ */
7
+ import React from 'react';
8
+ import type { MatchItemProps } from './types';
9
+ /**
10
+ * 匹配项组件
11
+ *
12
+ * @example
13
+ * ```tsx
14
+ * <MatchItem
15
+ * match={{
16
+ * index: 0,
17
+ * lastIndex: 3,
18
+ * fullMatch: 'abc',
19
+ * groups: ['abc', 'ab', 'c'],
20
+ * }}
21
+ * index={0}
22
+ * />
23
+ * ```
24
+ */
25
+ export declare const MatchItem: React.FC<MatchItemProps>;