@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.
- package/dist/cjs/components/RegexEditor/core/RegexEditor.d.ts +34 -0
- package/dist/cjs/components/RegexEditor/core/RegexEditor.js +223 -0
- package/dist/cjs/components/RegexEditor/core/RegexEditor.less +119 -0
- package/dist/cjs/components/RegexEditor/core/extensions/errorMarker.d.ts +49 -0
- package/dist/cjs/components/RegexEditor/core/extensions/errorMarker.js +158 -0
- package/dist/cjs/components/RegexEditor/core/types.d.ts +79 -0
- package/dist/cjs/components/RegexEditor/core/types.js +5 -0
- package/dist/cjs/components/RegexEditor/hooks/index.d.ts +9 -0
- package/dist/cjs/components/RegexEditor/hooks/index.js +19 -0
- package/dist/cjs/components/RegexEditor/hooks/useRegexTester.d.ts +95 -0
- package/dist/cjs/components/RegexEditor/hooks/useRegexTester.js +234 -0
- package/dist/cjs/components/RegexEditor/hooks/useRegexValidation.d.ts +71 -0
- package/dist/cjs/components/RegexEditor/hooks/useRegexValidation.js +215 -0
- package/dist/cjs/components/RegexEditor/hooks/useTemplateManager.d.ts +64 -0
- package/dist/cjs/components/RegexEditor/hooks/useTemplateManager.js +438 -0
- package/dist/cjs/components/RegexEditor/index.d.ts +16 -0
- package/dist/cjs/components/RegexEditor/index.js +232 -0
- package/dist/cjs/components/RegexEditor/templates/TemplateSelector.d.ts +36 -0
- package/dist/cjs/components/RegexEditor/templates/TemplateSelector.js +322 -0
- package/dist/cjs/components/RegexEditor/templates/builtinTemplates.d.ts +36 -0
- package/dist/cjs/components/RegexEditor/templates/builtinTemplates.js +340 -0
- package/dist/cjs/components/RegexEditor/templates/index.d.ts +10 -0
- package/dist/cjs/components/RegexEditor/templates/index.js +184 -0
- package/dist/cjs/components/RegexEditor/templates/storage.d.ts +74 -0
- package/dist/cjs/components/RegexEditor/templates/storage.js +337 -0
- package/dist/cjs/components/RegexEditor/templates/templateManager.d.ts +67 -0
- package/dist/cjs/components/RegexEditor/templates/templateManager.js +277 -0
- package/dist/cjs/components/RegexEditor/templates/types.d.ts +111 -0
- package/dist/cjs/components/RegexEditor/templates/types.js +94 -0
- package/dist/cjs/components/RegexEditor/testing/types.d.ts +55 -0
- package/dist/cjs/components/RegexEditor/testing/types.js +5 -0
- package/dist/cjs/components/RegexEditor/validation/complexity.d.ts +22 -0
- package/dist/cjs/components/RegexEditor/validation/complexity.js +196 -0
- package/dist/cjs/components/RegexEditor/validation/parser.d.ts +53 -0
- package/dist/cjs/components/RegexEditor/validation/parser.js +129 -0
- package/dist/cjs/components/RegexEditor/validation/types.d.ts +146 -0
- package/dist/cjs/components/RegexEditor/validation/types.js +5 -0
- package/dist/cjs/components/RegexEditor/validation/validator.d.ts +60 -0
- package/dist/cjs/components/RegexEditor/validation/validator.js +218 -0
- package/dist/cjs/components/RegexEditor/visualizer/FlagsSelector.d.ts +20 -0
- package/dist/cjs/components/RegexEditor/visualizer/FlagsSelector.js +98 -0
- package/dist/cjs/components/RegexEditor/visualizer/MatchItem.d.ts +25 -0
- package/dist/cjs/components/RegexEditor/visualizer/MatchItem.js +201 -0
- package/dist/cjs/components/RegexEditor/visualizer/RegexRailroadDiagram.d.ts +32 -0
- package/dist/cjs/components/RegexEditor/visualizer/RegexRailroadDiagram.js +192 -0
- package/dist/cjs/components/RegexEditor/visualizer/RegexTester.d.ts +22 -0
- package/dist/cjs/components/RegexEditor/visualizer/RegexTester.js +255 -0
- package/dist/cjs/components/RegexEditor/visualizer/astToRailroad.d.ts +19 -0
- package/dist/cjs/components/RegexEditor/visualizer/astToRailroad.js +155 -0
- package/dist/cjs/components/RegexEditor/visualizer/index.d.ts +12 -0
- package/dist/cjs/components/RegexEditor/visualizer/index.js +76 -0
- package/dist/cjs/components/RegexEditor/visualizer/types.d.ts +131 -0
- package/dist/cjs/components/RegexEditor/visualizer/types.js +5 -0
- package/dist/cjs/components/RegexEditor/visualizer/utils.d.ts +106 -0
- package/dist/cjs/components/RegexEditor/visualizer/utils.js +268 -0
- package/dist/cjs/index.d.ts +3 -1
- package/dist/cjs/index.js +55 -0
- package/dist/cjs/standardFormDialog/useStandardFormSchema.d.ts +1 -1
- package/dist/cjs/standardFormDialog/withStandardForm.d.ts +2 -2
- package/dist/cjs/types/railroad-diagrams.d.ts +59 -0
- package/dist/cjs/types/regexp-tree.d.ts +175 -0
- package/dist/esm/components/RegexEditor/core/RegexEditor.d.ts +34 -0
- package/dist/esm/components/RegexEditor/core/RegexEditor.js +214 -0
- package/dist/esm/components/RegexEditor/core/RegexEditor.less +119 -0
- package/dist/esm/components/RegexEditor/core/extensions/errorMarker.d.ts +49 -0
- package/dist/esm/components/RegexEditor/core/extensions/errorMarker.js +154 -0
- package/dist/esm/components/RegexEditor/core/types.d.ts +79 -0
- package/dist/esm/components/RegexEditor/core/types.js +1 -0
- package/dist/esm/components/RegexEditor/hooks/index.d.ts +9 -0
- package/dist/esm/components/RegexEditor/hooks/index.js +8 -0
- package/dist/esm/components/RegexEditor/hooks/useRegexTester.d.ts +95 -0
- package/dist/esm/components/RegexEditor/hooks/useRegexTester.js +230 -0
- package/dist/esm/components/RegexEditor/hooks/useRegexValidation.d.ts +71 -0
- package/dist/esm/components/RegexEditor/hooks/useRegexValidation.js +211 -0
- package/dist/esm/components/RegexEditor/hooks/useTemplateManager.d.ts +64 -0
- package/dist/esm/components/RegexEditor/hooks/useTemplateManager.js +430 -0
- package/dist/esm/components/RegexEditor/index.d.ts +16 -0
- package/dist/esm/components/RegexEditor/index.js +27 -0
- package/dist/esm/components/RegexEditor/templates/TemplateSelector.d.ts +36 -0
- package/dist/esm/components/RegexEditor/templates/TemplateSelector.js +316 -0
- package/dist/esm/components/RegexEditor/templates/builtinTemplates.d.ts +36 -0
- package/dist/esm/components/RegexEditor/templates/builtinTemplates.js +335 -0
- package/dist/esm/components/RegexEditor/templates/index.d.ts +10 -0
- package/dist/esm/components/RegexEditor/templates/index.js +19 -0
- package/dist/esm/components/RegexEditor/templates/storage.d.ts +74 -0
- package/dist/esm/components/RegexEditor/templates/storage.js +335 -0
- package/dist/esm/components/RegexEditor/templates/templateManager.d.ts +67 -0
- package/dist/esm/components/RegexEditor/templates/templateManager.js +274 -0
- package/dist/esm/components/RegexEditor/templates/types.d.ts +111 -0
- package/dist/esm/components/RegexEditor/templates/types.js +90 -0
- package/dist/esm/components/RegexEditor/testing/types.d.ts +55 -0
- package/dist/esm/components/RegexEditor/testing/types.js +1 -0
- package/dist/esm/components/RegexEditor/validation/complexity.d.ts +22 -0
- package/dist/esm/components/RegexEditor/validation/complexity.js +190 -0
- package/dist/esm/components/RegexEditor/validation/parser.d.ts +53 -0
- package/dist/esm/components/RegexEditor/validation/parser.js +123 -0
- package/dist/esm/components/RegexEditor/validation/types.d.ts +145 -0
- package/dist/esm/components/RegexEditor/validation/types.js +1 -0
- package/dist/esm/components/RegexEditor/validation/validator.d.ts +60 -0
- package/dist/esm/components/RegexEditor/validation/validator.js +213 -0
- package/dist/esm/components/RegexEditor/visualizer/FlagsSelector.d.ts +20 -0
- package/dist/esm/components/RegexEditor/visualizer/FlagsSelector.js +93 -0
- package/dist/esm/components/RegexEditor/visualizer/MatchItem.d.ts +25 -0
- package/dist/esm/components/RegexEditor/visualizer/MatchItem.js +194 -0
- package/dist/esm/components/RegexEditor/visualizer/RegexRailroadDiagram.d.ts +32 -0
- package/dist/esm/components/RegexEditor/visualizer/RegexRailroadDiagram.js +186 -0
- package/dist/esm/components/RegexEditor/visualizer/RegexTester.d.ts +22 -0
- package/dist/esm/components/RegexEditor/visualizer/RegexTester.js +248 -0
- package/dist/esm/components/RegexEditor/visualizer/astToRailroad.d.ts +18 -0
- package/dist/esm/components/RegexEditor/visualizer/astToRailroad.js +150 -0
- package/dist/esm/components/RegexEditor/visualizer/index.d.ts +12 -0
- package/dist/esm/components/RegexEditor/visualizer/index.js +17 -0
- package/dist/esm/components/RegexEditor/visualizer/types.d.ts +131 -0
- package/dist/esm/components/RegexEditor/visualizer/types.js +1 -0
- package/dist/esm/components/RegexEditor/visualizer/utils.d.ts +106 -0
- package/dist/esm/components/RegexEditor/visualizer/utils.js +256 -0
- package/dist/esm/index.d.ts +3 -1
- package/dist/esm/index.js +5 -2
- package/dist/esm/types/railroad-diagrams.d.ts +59 -0
- package/dist/esm/types/regexp-tree.d.ts +175 -0
- package/dist/umd/qc-ui.min.css +1 -1
- package/dist/umd/qc-ui.min.js +1 -1
- package/package.json +23 -7
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* useRegexTester Hook
|
|
3
|
+
*
|
|
4
|
+
* @module RegexEditor/hooks/useRegexTester
|
|
5
|
+
* @description 提供正则测试功能的 React Hook
|
|
6
|
+
*/
|
|
7
|
+
import type { RegexFlags, MatchResult } from '../visualizer/types';
|
|
8
|
+
/**
|
|
9
|
+
* Hook 配置选项
|
|
10
|
+
*/
|
|
11
|
+
export interface UseRegexTesterOptions {
|
|
12
|
+
/** 初始测试文本 */
|
|
13
|
+
initialTestText?: string;
|
|
14
|
+
/** 初始标志 */
|
|
15
|
+
initialFlags?: RegexFlags;
|
|
16
|
+
/** 最大匹配数量 */
|
|
17
|
+
maxMatches?: number;
|
|
18
|
+
/** 匹配超时时间 (毫秒) */
|
|
19
|
+
matchTimeout?: number;
|
|
20
|
+
/** 匹配结果回调 */
|
|
21
|
+
onMatchResults?: (results: MatchResult[]) => void;
|
|
22
|
+
/** 防抖延迟 (毫秒) */
|
|
23
|
+
debounceDelay?: number;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Hook 返回值
|
|
27
|
+
*/
|
|
28
|
+
export interface UseRegexTesterResult {
|
|
29
|
+
/** 测试文本 */
|
|
30
|
+
testText: string;
|
|
31
|
+
/** 设置测试文本 */
|
|
32
|
+
setTestText: (text: string) => void;
|
|
33
|
+
/** 标志 */
|
|
34
|
+
flags: RegexFlags;
|
|
35
|
+
/** 设置标志 */
|
|
36
|
+
setFlags: (flags: RegexFlags) => void;
|
|
37
|
+
/** 匹配结果 */
|
|
38
|
+
matches: MatchResult[];
|
|
39
|
+
/** 是否正在匹配 */
|
|
40
|
+
isMatching: boolean;
|
|
41
|
+
/** 匹配错误 */
|
|
42
|
+
error: string | null;
|
|
43
|
+
/** 是否有效的正则表达式 */
|
|
44
|
+
isValid: boolean;
|
|
45
|
+
/** 清空测试文本 */
|
|
46
|
+
clearTestText: () => void;
|
|
47
|
+
/** 重新匹配 */
|
|
48
|
+
rematch: () => void;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* 正则测试 Hook
|
|
52
|
+
*
|
|
53
|
+
* @param pattern - 正则表达式模式
|
|
54
|
+
* @param options - 配置选项
|
|
55
|
+
* @returns Hook 结果
|
|
56
|
+
*
|
|
57
|
+
* @example
|
|
58
|
+
* ```tsx
|
|
59
|
+
* const {
|
|
60
|
+
* testText,
|
|
61
|
+
* setTestText,
|
|
62
|
+
* flags,
|
|
63
|
+
* setFlags,
|
|
64
|
+
* matches,
|
|
65
|
+
* isValid,
|
|
66
|
+
* } = useRegexTester(pattern, {
|
|
67
|
+
* initialTestText: 'test@example.com',
|
|
68
|
+
* initialFlags: { global: true },
|
|
69
|
+
* });
|
|
70
|
+
* ```
|
|
71
|
+
*/
|
|
72
|
+
export declare function useRegexTester(pattern: string, options?: UseRegexTesterOptions): UseRegexTesterResult;
|
|
73
|
+
/**
|
|
74
|
+
* 替换预览 Hook
|
|
75
|
+
*
|
|
76
|
+
* @param pattern - 正则表达式模式
|
|
77
|
+
* @param text - 原始文本
|
|
78
|
+
* @param replaceText - 替换文本
|
|
79
|
+
* @param flags - 标志
|
|
80
|
+
* @returns 替换结果和错误
|
|
81
|
+
*
|
|
82
|
+
* @example
|
|
83
|
+
* ```tsx
|
|
84
|
+
* const { result, error } = useReplacePreview(
|
|
85
|
+
* '(\\d+)',
|
|
86
|
+
* 'abc 123 def',
|
|
87
|
+
* 'NUM:$1',
|
|
88
|
+
* { global: true }
|
|
89
|
+
* );
|
|
90
|
+
* ```
|
|
91
|
+
*/
|
|
92
|
+
export declare function useReplacePreview(pattern: string, text: string, replaceText: string, flags?: RegexFlags): {
|
|
93
|
+
result: string | null;
|
|
94
|
+
error: string | null;
|
|
95
|
+
};
|
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.useRegexTester = useRegexTester;
|
|
7
|
+
exports.useReplacePreview = useReplacePreview;
|
|
8
|
+
var _react = require("react");
|
|
9
|
+
var _utils = require("../visualizer/utils");
|
|
10
|
+
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
|
|
11
|
+
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
|
12
|
+
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
|
|
13
|
+
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
|
|
14
|
+
function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
|
|
15
|
+
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; } /**
|
|
16
|
+
* useRegexTester Hook
|
|
17
|
+
*
|
|
18
|
+
* @module RegexEditor/hooks/useRegexTester
|
|
19
|
+
* @description 提供正则测试功能的 React Hook
|
|
20
|
+
*/
|
|
21
|
+
/**
|
|
22
|
+
* Hook 配置选项
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Hook 返回值
|
|
27
|
+
*/
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* 正则测试 Hook
|
|
31
|
+
*
|
|
32
|
+
* @param pattern - 正则表达式模式
|
|
33
|
+
* @param options - 配置选项
|
|
34
|
+
* @returns Hook 结果
|
|
35
|
+
*
|
|
36
|
+
* @example
|
|
37
|
+
* ```tsx
|
|
38
|
+
* const {
|
|
39
|
+
* testText,
|
|
40
|
+
* setTestText,
|
|
41
|
+
* flags,
|
|
42
|
+
* setFlags,
|
|
43
|
+
* matches,
|
|
44
|
+
* isValid,
|
|
45
|
+
* } = useRegexTester(pattern, {
|
|
46
|
+
* initialTestText: 'test@example.com',
|
|
47
|
+
* initialFlags: { global: true },
|
|
48
|
+
* });
|
|
49
|
+
* ```
|
|
50
|
+
*/
|
|
51
|
+
function useRegexTester(pattern) {
|
|
52
|
+
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
53
|
+
var _options$initialTestT = options.initialTestText,
|
|
54
|
+
initialTestText = _options$initialTestT === void 0 ? '' : _options$initialTestT,
|
|
55
|
+
_options$initialFlags = options.initialFlags,
|
|
56
|
+
initialFlags = _options$initialFlags === void 0 ? {
|
|
57
|
+
global: true
|
|
58
|
+
} : _options$initialFlags,
|
|
59
|
+
_options$maxMatches = options.maxMatches,
|
|
60
|
+
maxMatches = _options$maxMatches === void 0 ? 1000 : _options$maxMatches,
|
|
61
|
+
_options$matchTimeout = options.matchTimeout,
|
|
62
|
+
matchTimeout = _options$matchTimeout === void 0 ? 5000 : _options$matchTimeout,
|
|
63
|
+
onMatchResults = options.onMatchResults,
|
|
64
|
+
_options$debounceDela = options.debounceDelay,
|
|
65
|
+
debounceDelay = _options$debounceDela === void 0 ? 300 : _options$debounceDela;
|
|
66
|
+
|
|
67
|
+
// 状态
|
|
68
|
+
var _useState = (0, _react.useState)(initialTestText),
|
|
69
|
+
_useState2 = _slicedToArray(_useState, 2),
|
|
70
|
+
testText = _useState2[0],
|
|
71
|
+
setTestText = _useState2[1];
|
|
72
|
+
var _useState3 = (0, _react.useState)(initialFlags),
|
|
73
|
+
_useState4 = _slicedToArray(_useState3, 2),
|
|
74
|
+
flags = _useState4[0],
|
|
75
|
+
setFlags = _useState4[1];
|
|
76
|
+
var _useState5 = (0, _react.useState)(false),
|
|
77
|
+
_useState6 = _slicedToArray(_useState5, 2),
|
|
78
|
+
isMatching = _useState6[0],
|
|
79
|
+
setIsMatching = _useState6[1];
|
|
80
|
+
var _useState7 = (0, _react.useState)(null),
|
|
81
|
+
_useState8 = _slicedToArray(_useState7, 2),
|
|
82
|
+
error = _useState8[0],
|
|
83
|
+
setError = _useState8[1];
|
|
84
|
+
var _useState9 = (0, _react.useState)(pattern),
|
|
85
|
+
_useState10 = _slicedToArray(_useState9, 2),
|
|
86
|
+
debouncedPattern = _useState10[0],
|
|
87
|
+
setDebouncedPattern = _useState10[1];
|
|
88
|
+
var _useState11 = (0, _react.useState)(testText),
|
|
89
|
+
_useState12 = _slicedToArray(_useState11, 2),
|
|
90
|
+
debouncedText = _useState12[0],
|
|
91
|
+
setDebouncedText = _useState12[1];
|
|
92
|
+
|
|
93
|
+
// 防抖: 模式变化
|
|
94
|
+
(0, _react.useEffect)(function () {
|
|
95
|
+
var timer = setTimeout(function () {
|
|
96
|
+
setDebouncedPattern(pattern);
|
|
97
|
+
}, debounceDelay);
|
|
98
|
+
return function () {
|
|
99
|
+
return clearTimeout(timer);
|
|
100
|
+
};
|
|
101
|
+
}, [pattern, debounceDelay]);
|
|
102
|
+
|
|
103
|
+
// 防抖: 文本变化
|
|
104
|
+
(0, _react.useEffect)(function () {
|
|
105
|
+
var timer = setTimeout(function () {
|
|
106
|
+
setDebouncedText(testText);
|
|
107
|
+
}, debounceDelay);
|
|
108
|
+
return function () {
|
|
109
|
+
return clearTimeout(timer);
|
|
110
|
+
};
|
|
111
|
+
}, [testText, debounceDelay]);
|
|
112
|
+
|
|
113
|
+
// 检查正则表达式是否有效
|
|
114
|
+
var isValid = (0, _react.useMemo)(function () {
|
|
115
|
+
return (0, _utils.isValidRegex)(debouncedPattern, flags);
|
|
116
|
+
}, [debouncedPattern, flags]);
|
|
117
|
+
|
|
118
|
+
// 执行匹配
|
|
119
|
+
var matches = (0, _react.useMemo)(function () {
|
|
120
|
+
// 清空错误
|
|
121
|
+
setError(null);
|
|
122
|
+
|
|
123
|
+
// 空模式或空文本
|
|
124
|
+
if (!debouncedPattern || !debouncedText) {
|
|
125
|
+
return [];
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// 无效正则
|
|
129
|
+
if (!isValid) {
|
|
130
|
+
setError('无效的正则表达式');
|
|
131
|
+
return [];
|
|
132
|
+
}
|
|
133
|
+
try {
|
|
134
|
+
setIsMatching(true);
|
|
135
|
+
var _results = (0, _utils.performMatch)(debouncedPattern, debouncedText, flags, maxMatches, matchTimeout);
|
|
136
|
+
if (_results === null) {
|
|
137
|
+
setError('匹配失败或超时');
|
|
138
|
+
return [];
|
|
139
|
+
}
|
|
140
|
+
return _results;
|
|
141
|
+
} catch (err) {
|
|
142
|
+
var errorMessage = err instanceof Error ? err.message : '未知错误';
|
|
143
|
+
setError("\u5339\u914D\u9519\u8BEF: ".concat(errorMessage));
|
|
144
|
+
return [];
|
|
145
|
+
} finally {
|
|
146
|
+
setIsMatching(false);
|
|
147
|
+
}
|
|
148
|
+
}, [debouncedPattern, debouncedText, flags, isValid, maxMatches, matchTimeout]);
|
|
149
|
+
|
|
150
|
+
// 通知匹配结果
|
|
151
|
+
(0, _react.useEffect)(function () {
|
|
152
|
+
if (onMatchResults) {
|
|
153
|
+
onMatchResults(matches);
|
|
154
|
+
}
|
|
155
|
+
}, [matches, onMatchResults]);
|
|
156
|
+
|
|
157
|
+
// 清空测试文本
|
|
158
|
+
var clearTestText = (0, _react.useCallback)(function () {
|
|
159
|
+
setTestText('');
|
|
160
|
+
}, []);
|
|
161
|
+
|
|
162
|
+
// 重新匹配 (强制刷新)
|
|
163
|
+
var rematch = (0, _react.useCallback)(function () {
|
|
164
|
+
setDebouncedPattern(pattern);
|
|
165
|
+
setDebouncedText(testText);
|
|
166
|
+
}, [pattern, testText]);
|
|
167
|
+
return {
|
|
168
|
+
testText: testText,
|
|
169
|
+
setTestText: setTestText,
|
|
170
|
+
flags: flags,
|
|
171
|
+
setFlags: setFlags,
|
|
172
|
+
matches: matches,
|
|
173
|
+
isMatching: isMatching,
|
|
174
|
+
error: error,
|
|
175
|
+
isValid: isValid,
|
|
176
|
+
clearTestText: clearTestText,
|
|
177
|
+
rematch: rematch
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* 替换预览 Hook
|
|
183
|
+
*
|
|
184
|
+
* @param pattern - 正则表达式模式
|
|
185
|
+
* @param text - 原始文本
|
|
186
|
+
* @param replaceText - 替换文本
|
|
187
|
+
* @param flags - 标志
|
|
188
|
+
* @returns 替换结果和错误
|
|
189
|
+
*
|
|
190
|
+
* @example
|
|
191
|
+
* ```tsx
|
|
192
|
+
* const { result, error } = useReplacePreview(
|
|
193
|
+
* '(\\d+)',
|
|
194
|
+
* 'abc 123 def',
|
|
195
|
+
* 'NUM:$1',
|
|
196
|
+
* { global: true }
|
|
197
|
+
* );
|
|
198
|
+
* ```
|
|
199
|
+
*/
|
|
200
|
+
function useReplacePreview(pattern, text, replaceText, flags) {
|
|
201
|
+
return (0, _react.useMemo)(function () {
|
|
202
|
+
if (!pattern || !text) {
|
|
203
|
+
return {
|
|
204
|
+
result: null,
|
|
205
|
+
error: null
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
if (!(0, _utils.isValidRegex)(pattern, flags)) {
|
|
209
|
+
return {
|
|
210
|
+
result: null,
|
|
211
|
+
error: '无效的正则表达式'
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
try {
|
|
215
|
+
var result = (0, _utils.performReplace)(pattern, text, replaceText, flags);
|
|
216
|
+
if (result === null) {
|
|
217
|
+
return {
|
|
218
|
+
result: null,
|
|
219
|
+
error: '替换失败'
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
return {
|
|
223
|
+
result: result,
|
|
224
|
+
error: null
|
|
225
|
+
};
|
|
226
|
+
} catch (err) {
|
|
227
|
+
var errorMessage = err instanceof Error ? err.message : '未知错误';
|
|
228
|
+
return {
|
|
229
|
+
result: null,
|
|
230
|
+
error: "\u66FF\u6362\u9519\u8BEF: ".concat(errorMessage)
|
|
231
|
+
};
|
|
232
|
+
}
|
|
233
|
+
}, [pattern, text, replaceText, flags]);
|
|
234
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* useRegexValidation Hook
|
|
3
|
+
*
|
|
4
|
+
* @description
|
|
5
|
+
* React Hook 用于正则表达式验证,集成解析、验证、复杂度分析。
|
|
6
|
+
* 提供去抖优化和完整的状态管理。
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```tsx
|
|
10
|
+
* const { validationResult, complexity, isValidating } = useRegexValidation(pattern);
|
|
11
|
+
*
|
|
12
|
+
* if (validationResult?.valid) {
|
|
13
|
+
* console.log('验证通过');
|
|
14
|
+
* } else {
|
|
15
|
+
* console.error('错误:', validationResult?.errors);
|
|
16
|
+
* }
|
|
17
|
+
*
|
|
18
|
+
* if (complexity?.backtrackingRisk === 'high') {
|
|
19
|
+
* console.warn('高回溯风险:', complexity.suggestions);
|
|
20
|
+
* }
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
import type { ValidationResult, ComplexityMetrics } from '../validation/types';
|
|
24
|
+
/**
|
|
25
|
+
* useRegexValidation Hook 返回值
|
|
26
|
+
*/
|
|
27
|
+
export interface UseRegexValidationResult {
|
|
28
|
+
/** 验证结果 */
|
|
29
|
+
validationResult: ValidationResult | null;
|
|
30
|
+
/** 复杂度分析结果 */
|
|
31
|
+
complexity: ComplexityMetrics | null;
|
|
32
|
+
/** 是否正在验证 */
|
|
33
|
+
isValidating: boolean;
|
|
34
|
+
/** 手动触发验证 */
|
|
35
|
+
validate: (value: string) => Promise<void>;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* 正则表达式验证 Hook
|
|
39
|
+
*
|
|
40
|
+
* @param pattern - 正则表达式字符串
|
|
41
|
+
* @param options - 配置选项
|
|
42
|
+
* @param options.debounceMs - 去抖延迟时间(默认 300ms)
|
|
43
|
+
* @returns {UseRegexValidationResult} 验证结果和方法
|
|
44
|
+
*
|
|
45
|
+
* @remarks
|
|
46
|
+
* 该 Hook 提供以下功能:
|
|
47
|
+
* - 自动验证: 监听 pattern 变化并自动触发验证
|
|
48
|
+
* - 去抖优化: 300ms 防抖延迟,避免频繁验证
|
|
49
|
+
* - 完整状态: validationResult, complexity, isValidating
|
|
50
|
+
* - 手动验证: 提供 validate 方法支持手动触发
|
|
51
|
+
*
|
|
52
|
+
* @example
|
|
53
|
+
* ```tsx
|
|
54
|
+
* function MyComponent() {
|
|
55
|
+
* const [pattern, setPattern] = useState('');
|
|
56
|
+
* const { validationResult, complexity, isValidating } = useRegexValidation(pattern);
|
|
57
|
+
*
|
|
58
|
+
* return (
|
|
59
|
+
* <div>
|
|
60
|
+
* <input value={pattern} onChange={e => setPattern(e.target.value)} />
|
|
61
|
+
* {isValidating && <Spin />}
|
|
62
|
+
* {validationResult?.errors.map(err => <Alert key={err.type} message={err.message} />)}
|
|
63
|
+
* {complexity && <Badge>性能评分: {complexity.performanceScore}</Badge>}
|
|
64
|
+
* </div>
|
|
65
|
+
* );
|
|
66
|
+
* }
|
|
67
|
+
* ```
|
|
68
|
+
*/
|
|
69
|
+
export declare const useRegexValidation: (pattern: string, options?: {
|
|
70
|
+
debounceMs?: number | undefined;
|
|
71
|
+
}) => UseRegexValidationResult;
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
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); }
|
|
4
|
+
Object.defineProperty(exports, "__esModule", {
|
|
5
|
+
value: true
|
|
6
|
+
});
|
|
7
|
+
exports.useRegexValidation = void 0;
|
|
8
|
+
var _debounce2 = _interopRequireDefault(require("lodash-es/debounce"));
|
|
9
|
+
var _react = require("react");
|
|
10
|
+
var _parser = require("../validation/parser");
|
|
11
|
+
var _validator = require("../validation/validator");
|
|
12
|
+
var _complexity = require("../validation/complexity");
|
|
13
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
14
|
+
function _regeneratorRuntime() { "use strict"; /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/facebook/regenerator/blob/main/LICENSE */ _regeneratorRuntime = function _regeneratorRuntime() { return e; }; var t, e = {}, r = Object.prototype, n = r.hasOwnProperty, o = Object.defineProperty || function (t, e, r) { t[e] = r.value; }, i = "function" == typeof Symbol ? Symbol : {}, a = i.iterator || "@@iterator", c = i.asyncIterator || "@@asyncIterator", u = i.toStringTag || "@@toStringTag"; function define(t, e, r) { return Object.defineProperty(t, e, { value: r, enumerable: !0, configurable: !0, writable: !0 }), t[e]; } try { define({}, ""); } catch (t) { define = function define(t, e, r) { return t[e] = r; }; } function wrap(t, e, r, n) { var i = e && e.prototype instanceof Generator ? e : Generator, a = Object.create(i.prototype), c = new Context(n || []); return o(a, "_invoke", { value: makeInvokeMethod(t, r, c) }), a; } function tryCatch(t, e, r) { try { return { type: "normal", arg: t.call(e, r) }; } catch (t) { return { type: "throw", arg: t }; } } e.wrap = wrap; var h = "suspendedStart", l = "suspendedYield", f = "executing", s = "completed", y = {}; function Generator() {} function GeneratorFunction() {} function GeneratorFunctionPrototype() {} var p = {}; define(p, a, function () { return this; }); var d = Object.getPrototypeOf, v = d && d(d(values([]))); v && v !== r && n.call(v, a) && (p = v); var g = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(p); function defineIteratorMethods(t) { ["next", "throw", "return"].forEach(function (e) { define(t, e, function (t) { return this._invoke(e, t); }); }); } function AsyncIterator(t, e) { function invoke(r, o, i, a) { var c = tryCatch(t[r], t, o); if ("throw" !== c.type) { var u = c.arg, h = u.value; return h && "object" == _typeof(h) && n.call(h, "__await") ? e.resolve(h.__await).then(function (t) { invoke("next", t, i, a); }, function (t) { invoke("throw", t, i, a); }) : e.resolve(h).then(function (t) { u.value = t, i(u); }, function (t) { return invoke("throw", t, i, a); }); } a(c.arg); } var r; o(this, "_invoke", { value: function value(t, n) { function callInvokeWithMethodAndArg() { return new e(function (e, r) { invoke(t, n, e, r); }); } return r = r ? r.then(callInvokeWithMethodAndArg, callInvokeWithMethodAndArg) : callInvokeWithMethodAndArg(); } }); } function makeInvokeMethod(e, r, n) { var o = h; return function (i, a) { if (o === f) throw new Error("Generator is already running"); if (o === s) { if ("throw" === i) throw a; return { value: t, done: !0 }; } for (n.method = i, n.arg = a;;) { var c = n.delegate; if (c) { var u = maybeInvokeDelegate(c, n); if (u) { if (u === y) continue; return u; } } if ("next" === n.method) n.sent = n._sent = n.arg;else if ("throw" === n.method) { if (o === h) throw o = s, n.arg; n.dispatchException(n.arg); } else "return" === n.method && n.abrupt("return", n.arg); o = f; var p = tryCatch(e, r, n); if ("normal" === p.type) { if (o = n.done ? s : l, p.arg === y) continue; return { value: p.arg, done: n.done }; } "throw" === p.type && (o = s, n.method = "throw", n.arg = p.arg); } }; } function maybeInvokeDelegate(e, r) { var n = r.method, o = e.iterator[n]; if (o === t) return r.delegate = null, "throw" === n && e.iterator.return && (r.method = "return", r.arg = t, maybeInvokeDelegate(e, r), "throw" === r.method) || "return" !== n && (r.method = "throw", r.arg = new TypeError("The iterator does not provide a '" + n + "' method")), y; var i = tryCatch(o, e.iterator, r.arg); if ("throw" === i.type) return r.method = "throw", r.arg = i.arg, r.delegate = null, y; var a = i.arg; return a ? a.done ? (r[e.resultName] = a.value, r.next = e.nextLoc, "return" !== r.method && (r.method = "next", r.arg = t), r.delegate = null, y) : a : (r.method = "throw", r.arg = new TypeError("iterator result is not an object"), r.delegate = null, y); } function pushTryEntry(t) { var e = { tryLoc: t[0] }; 1 in t && (e.catchLoc = t[1]), 2 in t && (e.finallyLoc = t[2], e.afterLoc = t[3]), this.tryEntries.push(e); } function resetTryEntry(t) { var e = t.completion || {}; e.type = "normal", delete e.arg, t.completion = e; } function Context(t) { this.tryEntries = [{ tryLoc: "root" }], t.forEach(pushTryEntry, this), this.reset(!0); } function values(e) { if (e || "" === e) { var r = e[a]; if (r) return r.call(e); if ("function" == typeof e.next) return e; if (!isNaN(e.length)) { var o = -1, i = function next() { for (; ++o < e.length;) if (n.call(e, o)) return next.value = e[o], next.done = !1, next; return next.value = t, next.done = !0, next; }; return i.next = i; } } throw new TypeError(_typeof(e) + " is not iterable"); } return GeneratorFunction.prototype = GeneratorFunctionPrototype, o(g, "constructor", { value: GeneratorFunctionPrototype, configurable: !0 }), o(GeneratorFunctionPrototype, "constructor", { value: GeneratorFunction, configurable: !0 }), GeneratorFunction.displayName = define(GeneratorFunctionPrototype, u, "GeneratorFunction"), e.isGeneratorFunction = function (t) { var e = "function" == typeof t && t.constructor; return !!e && (e === GeneratorFunction || "GeneratorFunction" === (e.displayName || e.name)); }, e.mark = function (t) { return Object.setPrototypeOf ? Object.setPrototypeOf(t, GeneratorFunctionPrototype) : (t.__proto__ = GeneratorFunctionPrototype, define(t, u, "GeneratorFunction")), t.prototype = Object.create(g), t; }, e.awrap = function (t) { return { __await: t }; }, defineIteratorMethods(AsyncIterator.prototype), define(AsyncIterator.prototype, c, function () { return this; }), e.AsyncIterator = AsyncIterator, e.async = function (t, r, n, o, i) { void 0 === i && (i = Promise); var a = new AsyncIterator(wrap(t, r, n, o), i); return e.isGeneratorFunction(r) ? a : a.next().then(function (t) { return t.done ? t.value : a.next(); }); }, defineIteratorMethods(g), define(g, u, "Generator"), define(g, a, function () { return this; }), define(g, "toString", function () { return "[object Generator]"; }), e.keys = function (t) { var e = Object(t), r = []; for (var n in e) r.push(n); return r.reverse(), function next() { for (; r.length;) { var t = r.pop(); if (t in e) return next.value = t, next.done = !1, next; } return next.done = !0, next; }; }, e.values = values, Context.prototype = { constructor: Context, reset: function reset(e) { if (this.prev = 0, this.next = 0, this.sent = this._sent = t, this.done = !1, this.delegate = null, this.method = "next", this.arg = t, this.tryEntries.forEach(resetTryEntry), !e) for (var r in this) "t" === r.charAt(0) && n.call(this, r) && !isNaN(+r.slice(1)) && (this[r] = t); }, stop: function stop() { this.done = !0; var t = this.tryEntries[0].completion; if ("throw" === t.type) throw t.arg; return this.rval; }, dispatchException: function dispatchException(e) { if (this.done) throw e; var r = this; function handle(n, o) { return a.type = "throw", a.arg = e, r.next = n, o && (r.method = "next", r.arg = t), !!o; } for (var o = this.tryEntries.length - 1; o >= 0; --o) { var i = this.tryEntries[o], a = i.completion; if ("root" === i.tryLoc) return handle("end"); if (i.tryLoc <= this.prev) { var c = n.call(i, "catchLoc"), u = n.call(i, "finallyLoc"); if (c && u) { if (this.prev < i.catchLoc) return handle(i.catchLoc, !0); if (this.prev < i.finallyLoc) return handle(i.finallyLoc); } else if (c) { if (this.prev < i.catchLoc) return handle(i.catchLoc, !0); } else { if (!u) throw new Error("try statement without catch or finally"); if (this.prev < i.finallyLoc) return handle(i.finallyLoc); } } } }, abrupt: function abrupt(t, e) { for (var r = this.tryEntries.length - 1; r >= 0; --r) { var o = this.tryEntries[r]; if (o.tryLoc <= this.prev && n.call(o, "finallyLoc") && this.prev < o.finallyLoc) { var i = o; break; } } i && ("break" === t || "continue" === t) && i.tryLoc <= e && e <= i.finallyLoc && (i = null); var a = i ? i.completion : {}; return a.type = t, a.arg = e, i ? (this.method = "next", this.next = i.finallyLoc, y) : this.complete(a); }, complete: function complete(t, e) { if ("throw" === t.type) throw t.arg; return "break" === t.type || "continue" === t.type ? this.next = t.arg : "return" === t.type ? (this.rval = this.arg = t.arg, this.method = "return", this.next = "end") : "normal" === t.type && e && (this.next = e), y; }, finish: function finish(t) { for (var e = this.tryEntries.length - 1; e >= 0; --e) { var r = this.tryEntries[e]; if (r.finallyLoc === t) return this.complete(r.completion, r.afterLoc), resetTryEntry(r), y; } }, catch: function _catch(t) { for (var e = this.tryEntries.length - 1; e >= 0; --e) { var r = this.tryEntries[e]; if (r.tryLoc === t) { var n = r.completion; if ("throw" === n.type) { var o = n.arg; resetTryEntry(r); } return o; } } throw new Error("illegal catch attempt"); }, delegateYield: function delegateYield(e, r, n) { return this.delegate = { iterator: values(e), resultName: r, nextLoc: n }, "next" === this.method && (this.arg = t), y; } }, e; }
|
|
15
|
+
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }
|
|
16
|
+
function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }
|
|
17
|
+
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
|
|
18
|
+
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
|
19
|
+
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
|
|
20
|
+
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
|
|
21
|
+
function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
|
|
22
|
+
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; } /**
|
|
23
|
+
* useRegexValidation Hook
|
|
24
|
+
*
|
|
25
|
+
* @description
|
|
26
|
+
* React Hook 用于正则表达式验证,集成解析、验证、复杂度分析。
|
|
27
|
+
* 提供去抖优化和完整的状态管理。
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
* ```tsx
|
|
31
|
+
* const { validationResult, complexity, isValidating } = useRegexValidation(pattern);
|
|
32
|
+
*
|
|
33
|
+
* if (validationResult?.valid) {
|
|
34
|
+
* console.log('验证通过');
|
|
35
|
+
* } else {
|
|
36
|
+
* console.error('错误:', validationResult?.errors);
|
|
37
|
+
* }
|
|
38
|
+
*
|
|
39
|
+
* if (complexity?.backtrackingRisk === 'high') {
|
|
40
|
+
* console.warn('高回溯风险:', complexity.suggestions);
|
|
41
|
+
* }
|
|
42
|
+
* ```
|
|
43
|
+
*/
|
|
44
|
+
/**
|
|
45
|
+
* useRegexValidation Hook 返回值
|
|
46
|
+
*/
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* 正则表达式验证 Hook
|
|
50
|
+
*
|
|
51
|
+
* @param pattern - 正则表达式字符串
|
|
52
|
+
* @param options - 配置选项
|
|
53
|
+
* @param options.debounceMs - 去抖延迟时间(默认 300ms)
|
|
54
|
+
* @returns {UseRegexValidationResult} 验证结果和方法
|
|
55
|
+
*
|
|
56
|
+
* @remarks
|
|
57
|
+
* 该 Hook 提供以下功能:
|
|
58
|
+
* - 自动验证: 监听 pattern 变化并自动触发验证
|
|
59
|
+
* - 去抖优化: 300ms 防抖延迟,避免频繁验证
|
|
60
|
+
* - 完整状态: validationResult, complexity, isValidating
|
|
61
|
+
* - 手动验证: 提供 validate 方法支持手动触发
|
|
62
|
+
*
|
|
63
|
+
* @example
|
|
64
|
+
* ```tsx
|
|
65
|
+
* function MyComponent() {
|
|
66
|
+
* const [pattern, setPattern] = useState('');
|
|
67
|
+
* const { validationResult, complexity, isValidating } = useRegexValidation(pattern);
|
|
68
|
+
*
|
|
69
|
+
* return (
|
|
70
|
+
* <div>
|
|
71
|
+
* <input value={pattern} onChange={e => setPattern(e.target.value)} />
|
|
72
|
+
* {isValidating && <Spin />}
|
|
73
|
+
* {validationResult?.errors.map(err => <Alert key={err.type} message={err.message} />)}
|
|
74
|
+
* {complexity && <Badge>性能评分: {complexity.performanceScore}</Badge>}
|
|
75
|
+
* </div>
|
|
76
|
+
* );
|
|
77
|
+
* }
|
|
78
|
+
* ```
|
|
79
|
+
*/
|
|
80
|
+
var useRegexValidation = exports.useRegexValidation = function useRegexValidation(pattern) {
|
|
81
|
+
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
82
|
+
var _options$debounceMs = options.debounceMs,
|
|
83
|
+
debounceMs = _options$debounceMs === void 0 ? 300 : _options$debounceMs;
|
|
84
|
+
|
|
85
|
+
// 状态
|
|
86
|
+
var _useState = (0, _react.useState)(null),
|
|
87
|
+
_useState2 = _slicedToArray(_useState, 2),
|
|
88
|
+
validationResult = _useState2[0],
|
|
89
|
+
setValidationResult = _useState2[1];
|
|
90
|
+
var _useState3 = (0, _react.useState)(null),
|
|
91
|
+
_useState4 = _slicedToArray(_useState3, 2),
|
|
92
|
+
complexity = _useState4[0],
|
|
93
|
+
setComplexity = _useState4[1];
|
|
94
|
+
var _useState5 = (0, _react.useState)(false),
|
|
95
|
+
_useState6 = _slicedToArray(_useState5, 2),
|
|
96
|
+
isValidating = _useState6[0],
|
|
97
|
+
setIsValidating = _useState6[1];
|
|
98
|
+
|
|
99
|
+
// 验证函数
|
|
100
|
+
var validate = (0, _react.useCallback)( /*#__PURE__*/function () {
|
|
101
|
+
var _ref = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(value) {
|
|
102
|
+
var parseResult, allErrors, errors, warnings, infos, complexityMetrics;
|
|
103
|
+
return _regeneratorRuntime().wrap(function _callee$(_context) {
|
|
104
|
+
while (1) switch (_context.prev = _context.next) {
|
|
105
|
+
case 0:
|
|
106
|
+
if (value) {
|
|
107
|
+
_context.next = 4;
|
|
108
|
+
break;
|
|
109
|
+
}
|
|
110
|
+
setValidationResult(null);
|
|
111
|
+
setComplexity(null);
|
|
112
|
+
return _context.abrupt("return");
|
|
113
|
+
case 4:
|
|
114
|
+
setIsValidating(true);
|
|
115
|
+
_context.prev = 5;
|
|
116
|
+
// 1. 解析正则表达式
|
|
117
|
+
parseResult = (0, _parser.parseRegex)(value);
|
|
118
|
+
if (parseResult.success) {
|
|
119
|
+
_context.next = 11;
|
|
120
|
+
break;
|
|
121
|
+
}
|
|
122
|
+
// 解析失败
|
|
123
|
+
setValidationResult({
|
|
124
|
+
valid: false,
|
|
125
|
+
errors: [parseResult.error],
|
|
126
|
+
warnings: [],
|
|
127
|
+
infos: [],
|
|
128
|
+
pattern: value
|
|
129
|
+
});
|
|
130
|
+
setComplexity(null);
|
|
131
|
+
return _context.abrupt("return");
|
|
132
|
+
case 11:
|
|
133
|
+
// 2. 语法验证
|
|
134
|
+
allErrors = (0, _validator.validateRegex)(parseResult.ast); // 3. 分类错误、警告和信息
|
|
135
|
+
errors = allErrors.filter(function (e) {
|
|
136
|
+
return e.severity === 'error';
|
|
137
|
+
});
|
|
138
|
+
warnings = allErrors.filter(function (e) {
|
|
139
|
+
return e.severity === 'warning';
|
|
140
|
+
});
|
|
141
|
+
infos = allErrors.filter(function (e) {
|
|
142
|
+
return e.severity === 'info';
|
|
143
|
+
}); // 4. 复杂度分析
|
|
144
|
+
complexityMetrics = (0, _complexity.analyzeComplexity)(parseResult.ast); // 5. 更新状态
|
|
145
|
+
setValidationResult({
|
|
146
|
+
valid: errors.length === 0,
|
|
147
|
+
// 只有错误才影响 valid 状态
|
|
148
|
+
errors: errors,
|
|
149
|
+
warnings: warnings,
|
|
150
|
+
infos: infos,
|
|
151
|
+
pattern: value
|
|
152
|
+
});
|
|
153
|
+
setComplexity(complexityMetrics);
|
|
154
|
+
_context.next = 25;
|
|
155
|
+
break;
|
|
156
|
+
case 20:
|
|
157
|
+
_context.prev = 20;
|
|
158
|
+
_context.t0 = _context["catch"](5);
|
|
159
|
+
// 异常处理
|
|
160
|
+
console.error('Validation error:', _context.t0);
|
|
161
|
+
setValidationResult({
|
|
162
|
+
valid: false,
|
|
163
|
+
errors: [{
|
|
164
|
+
type: 'unknown_error',
|
|
165
|
+
message: '验证过程出错',
|
|
166
|
+
position: {
|
|
167
|
+
start: 0,
|
|
168
|
+
end: value.length
|
|
169
|
+
},
|
|
170
|
+
severity: 'error'
|
|
171
|
+
}],
|
|
172
|
+
warnings: [],
|
|
173
|
+
infos: [],
|
|
174
|
+
pattern: value
|
|
175
|
+
});
|
|
176
|
+
setComplexity(null);
|
|
177
|
+
case 25:
|
|
178
|
+
_context.prev = 25;
|
|
179
|
+
setIsValidating(false);
|
|
180
|
+
return _context.finish(25);
|
|
181
|
+
case 28:
|
|
182
|
+
case "end":
|
|
183
|
+
return _context.stop();
|
|
184
|
+
}
|
|
185
|
+
}, _callee, null, [[5, 20, 25, 28]]);
|
|
186
|
+
}));
|
|
187
|
+
return function (_x) {
|
|
188
|
+
return _ref.apply(this, arguments);
|
|
189
|
+
};
|
|
190
|
+
}(), []);
|
|
191
|
+
|
|
192
|
+
// 防抖验证函数
|
|
193
|
+
// 使用 useRef 保存防抖函数,避免在每次渲染时重新创建
|
|
194
|
+
var debouncedValidateRef = (0, _react.useRef)((0, _debounce2.default)(function (value) {
|
|
195
|
+
validate(value);
|
|
196
|
+
}, debounceMs));
|
|
197
|
+
|
|
198
|
+
// 监听 pattern 变化
|
|
199
|
+
(0, _react.useEffect)(function () {
|
|
200
|
+
debouncedValidateRef.current(pattern);
|
|
201
|
+
|
|
202
|
+
// 清理函数: 组件卸载时取消防抖
|
|
203
|
+
return function () {
|
|
204
|
+
debouncedValidateRef.current.cancel();
|
|
205
|
+
};
|
|
206
|
+
}, [pattern]);
|
|
207
|
+
|
|
208
|
+
// 返回结果
|
|
209
|
+
return {
|
|
210
|
+
validationResult: validationResult,
|
|
211
|
+
complexity: complexity,
|
|
212
|
+
isValidating: isValidating,
|
|
213
|
+
validate: validate
|
|
214
|
+
};
|
|
215
|
+
};
|