@dommaker/harness 0.12.0 → 0.12.2
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/README.md +70 -174
- package/dist/cli/commands/check.d.ts.map +1 -1
- package/dist/cli/commands/check.js +6 -9
- package/dist/cli/commands/check.js.map +1 -1
- package/dist/cli/commands/report.d.ts.map +1 -1
- package/dist/cli/commands/report.js +5 -8
- package/dist/cli/commands/report.js.map +1 -1
- package/dist/cli/commands/sync-docs.js +7 -5
- package/dist/cli/commands/sync-docs.js.map +1 -1
- package/dist/constraints/registry.d.ts +2 -1
- package/dist/constraints/registry.d.ts.map +1 -1
- package/dist/constraints/registry.js +7 -7
- package/dist/constraints/registry.js.map +1 -1
- package/dist/constraints/types.d.ts +2 -2
- package/dist/constraints/types.d.ts.map +1 -1
- package/dist/context/session-manager.d.ts +24 -7
- package/dist/context/session-manager.d.ts.map +1 -1
- package/dist/context/session-manager.js +71 -12
- package/dist/context/session-manager.js.map +1 -1
- package/dist/core/constraints/check-cache.d.ts +38 -0
- package/dist/core/constraints/check-cache.d.ts.map +1 -0
- package/dist/core/constraints/check-cache.js +75 -0
- package/dist/core/constraints/check-cache.js.map +1 -0
- package/dist/core/constraints/checker.d.ts +48 -10
- package/dist/core/constraints/checker.d.ts.map +1 -1
- package/dist/core/constraints/checker.js +160 -44
- package/dist/core/constraints/checker.js.map +1 -1
- package/dist/core/constraints/definitions.d.ts.map +1 -1
- package/dist/core/constraints/definitions.js +165 -28
- package/dist/core/constraints/definitions.js.map +1 -1
- package/dist/core/constraints/interceptor.d.ts +1 -0
- package/dist/core/constraints/interceptor.d.ts.map +1 -1
- package/dist/core/constraints/interceptor.js +38 -44
- package/dist/core/constraints/interceptor.js.map +1 -1
- package/dist/failure/constraint-handler.d.ts +83 -0
- package/dist/failure/constraint-handler.d.ts.map +1 -0
- package/dist/failure/constraint-handler.js +140 -0
- package/dist/failure/constraint-handler.js.map +1 -0
- package/dist/failure/index.d.ts +1 -0
- package/dist/failure/index.d.ts.map +1 -1
- package/dist/failure/index.js +7 -1
- package/dist/failure/index.js.map +1 -1
- package/dist/hooks/bootstrap.d.ts +50 -0
- package/dist/hooks/bootstrap.d.ts.map +1 -0
- package/dist/hooks/bootstrap.js +137 -0
- package/dist/hooks/bootstrap.js.map +1 -0
- package/dist/hooks/index.d.ts +11 -0
- package/dist/hooks/index.d.ts.map +1 -0
- package/dist/hooks/index.js +32 -0
- package/dist/hooks/index.js.map +1 -0
- package/dist/hooks/pipeline.d.ts +36 -0
- package/dist/hooks/pipeline.d.ts.map +1 -0
- package/dist/hooks/pipeline.js +135 -0
- package/dist/hooks/pipeline.js.map +1 -0
- package/dist/hooks/registry.d.ts +50 -0
- package/dist/hooks/registry.d.ts.map +1 -0
- package/dist/hooks/registry.js +81 -0
- package/dist/hooks/registry.js.map +1 -0
- package/dist/hooks/types.d.ts +75 -0
- package/dist/hooks/types.d.ts.map +1 -0
- package/dist/hooks/types.js +9 -0
- package/dist/hooks/types.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/presets/index.d.ts +1 -1
- package/dist/presets/index.d.ts.map +1 -1
- package/dist/presets/index.js +2 -1
- package/dist/presets/index.js.map +1 -1
- package/dist/presets/standard.d.ts +17 -0
- package/dist/presets/standard.d.ts.map +1 -1
- package/dist/presets/standard.js +50 -1
- package/dist/presets/standard.js.map +1 -1
- package/dist/types/constraint.d.ts +2 -0
- package/dist/types/constraint.d.ts.map +1 -1
- package/dist/types/constraint.js.map +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* ConstraintViolationHandler — 约束违规统一处理(S4)
|
|
4
|
+
*
|
|
5
|
+
* 问题:ConstraintViolationError 在 4 个调用点有 4 种行为:
|
|
6
|
+
* 1. 抛异常阻断(checker.ts / interceptor.ts)
|
|
7
|
+
* 2. 返回 null(report.ts catch 后返回空数据)
|
|
8
|
+
* 3. 返回 403 HTTP 状态
|
|
9
|
+
* 4. console.warn 静默吞掉
|
|
10
|
+
*
|
|
11
|
+
* 解决:提供 3 种标准化处理策略,消除 ad-hoc catch 行为。
|
|
12
|
+
*/
|
|
13
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
+
exports.ConstraintViolationHandler = void 0;
|
|
15
|
+
exports.executeWithBlock = executeWithBlock;
|
|
16
|
+
exports.executeWithCollect = executeWithCollect;
|
|
17
|
+
exports.executeWithSafeBoolean = executeWithSafeBoolean;
|
|
18
|
+
/**
|
|
19
|
+
* 约束违规处理器
|
|
20
|
+
*
|
|
21
|
+
* 用法:
|
|
22
|
+
* ```typescript
|
|
23
|
+
* const handler = new ConstraintViolationHandler();
|
|
24
|
+
*
|
|
25
|
+
* // 策略 1: BLOCK — 抛异常阻断(Iron Laws 默认)
|
|
26
|
+
* await handler.execute(checkFn, 'BLOCK');
|
|
27
|
+
*
|
|
28
|
+
* // 策略 2: COLLECT — 收集违规不抛异常(用于报告生成)
|
|
29
|
+
* const result = await handler.execute(checkFn, 'COLLECT');
|
|
30
|
+
* // result.checkResult 总是有值
|
|
31
|
+
*
|
|
32
|
+
* // 策略 3: SAFE_BOOLEAN — 返回真/假(用于 canProceed 类方法)
|
|
33
|
+
* const ok = await handler.execute(checkFn, 'SAFE_BOOLEAN');
|
|
34
|
+
* // ok.hasViolation 为 true/false
|
|
35
|
+
* ```
|
|
36
|
+
*/
|
|
37
|
+
class ConstraintViolationHandler {
|
|
38
|
+
/**
|
|
39
|
+
* 执行约束检查并统一处理结果
|
|
40
|
+
*
|
|
41
|
+
* @param checkFn 约束检查函数(可能抛出 ConstraintViolationError)
|
|
42
|
+
* @param strategy 处理策略
|
|
43
|
+
* @returns 标准化结果
|
|
44
|
+
*/
|
|
45
|
+
async execute(checkFn, strategy) {
|
|
46
|
+
switch (strategy) {
|
|
47
|
+
case 'BLOCK':
|
|
48
|
+
return this.handleBlock(checkFn);
|
|
49
|
+
case 'COLLECT':
|
|
50
|
+
return this.handleCollect(checkFn);
|
|
51
|
+
case 'SAFE_BOOLEAN':
|
|
52
|
+
return this.handleSafeBoolean(checkFn);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* BLOCK 策略:违规即抛出,无违规返回结果
|
|
57
|
+
*/
|
|
58
|
+
async handleBlock(checkFn) {
|
|
59
|
+
const result = await checkFn();
|
|
60
|
+
return {
|
|
61
|
+
strategy: 'BLOCK',
|
|
62
|
+
checkResult: result,
|
|
63
|
+
hasViolation: !result.passed,
|
|
64
|
+
violationCount: result.ironLaws.filter(r => !r.satisfied).length,
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* COLLECT 策略:捕获异常,收集所有违规,不抛出
|
|
69
|
+
*/
|
|
70
|
+
async handleCollect(checkFn) {
|
|
71
|
+
try {
|
|
72
|
+
const result = await checkFn();
|
|
73
|
+
const ironViolations = result.ironLaws.filter(r => !r.satisfied).length;
|
|
74
|
+
const guideViolations = result.warningCount;
|
|
75
|
+
return {
|
|
76
|
+
strategy: 'COLLECT',
|
|
77
|
+
checkResult: result,
|
|
78
|
+
hasViolation: !result.passed || guideViolations > 0,
|
|
79
|
+
violationCount: ironViolations + guideViolations,
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
catch {
|
|
83
|
+
// 捕获 ConstraintViolationError,返回失败结果
|
|
84
|
+
const empty = {
|
|
85
|
+
ironLaws: [],
|
|
86
|
+
guidelines: [],
|
|
87
|
+
tips: [],
|
|
88
|
+
passed: false,
|
|
89
|
+
warningCount: 0,
|
|
90
|
+
tipCount: 0,
|
|
91
|
+
};
|
|
92
|
+
return {
|
|
93
|
+
strategy: 'COLLECT',
|
|
94
|
+
checkResult: empty,
|
|
95
|
+
hasViolation: true,
|
|
96
|
+
violationCount: 1,
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* SAFE_BOOLEAN 策略:不抛异常,只返回 boolean
|
|
102
|
+
*/
|
|
103
|
+
async handleSafeBoolean(checkFn) {
|
|
104
|
+
try {
|
|
105
|
+
const result = await checkFn();
|
|
106
|
+
return {
|
|
107
|
+
strategy: 'SAFE_BOOLEAN',
|
|
108
|
+
hasViolation: !result.passed,
|
|
109
|
+
violationCount: result.ironLaws.filter(r => !r.satisfied).length,
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
catch {
|
|
113
|
+
return {
|
|
114
|
+
strategy: 'SAFE_BOOLEAN',
|
|
115
|
+
hasViolation: true,
|
|
116
|
+
violationCount: 1,
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
exports.ConstraintViolationHandler = ConstraintViolationHandler;
|
|
122
|
+
/**
|
|
123
|
+
* 快捷:BLOCK 策略执行检查
|
|
124
|
+
*/
|
|
125
|
+
async function executeWithBlock(checkFn) {
|
|
126
|
+
return new ConstraintViolationHandler().execute(checkFn, 'BLOCK');
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* 快捷:COLLECT 策略执行检查
|
|
130
|
+
*/
|
|
131
|
+
async function executeWithCollect(checkFn) {
|
|
132
|
+
return new ConstraintViolationHandler().execute(checkFn, 'COLLECT');
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* 快捷:SAFE_BOOLEAN 策略执行检查
|
|
136
|
+
*/
|
|
137
|
+
async function executeWithSafeBoolean(checkFn) {
|
|
138
|
+
return new ConstraintViolationHandler().execute(checkFn, 'SAFE_BOOLEAN');
|
|
139
|
+
}
|
|
140
|
+
//# sourceMappingURL=constraint-handler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constraint-handler.js","sourceRoot":"","sources":["../../src/failure/constraint-handler.ts"],"names":[],"mappings":"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"}
|
package/dist/failure/index.d.ts
CHANGED
|
@@ -7,4 +7,5 @@
|
|
|
7
7
|
export * from './types';
|
|
8
8
|
export { ErrorClassifier, createErrorClassifier, classifyError, getFailureLevel, type ErrorClassifierConfig, } from './classifier';
|
|
9
9
|
export { FailureRecorder, createFailureRecorder, type FailureRecorderConfig, } from './recorder';
|
|
10
|
+
export { ConstraintViolationHandler, executeWithBlock, executeWithCollect, executeWithSafeBoolean, type ViolationStrategy, type ViolationHandlingResult, } from './constraint-handler';
|
|
10
11
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/failure/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,cAAc,SAAS,CAAC;AAGxB,OAAO,EACL,eAAe,EACf,qBAAqB,EACrB,aAAa,EACb,eAAe,EACf,KAAK,qBAAqB,GAC3B,MAAM,cAAc,CAAC;AAGtB,OAAO,EACL,eAAe,EACf,qBAAqB,EACrB,KAAK,qBAAqB,GAC3B,MAAM,YAAY,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/failure/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,cAAc,SAAS,CAAC;AAGxB,OAAO,EACL,eAAe,EACf,qBAAqB,EACrB,aAAa,EACb,eAAe,EACf,KAAK,qBAAqB,GAC3B,MAAM,cAAc,CAAC;AAGtB,OAAO,EACL,eAAe,EACf,qBAAqB,EACrB,KAAK,qBAAqB,GAC3B,MAAM,YAAY,CAAC;AAGpB,OAAO,EACL,0BAA0B,EAC1B,gBAAgB,EAChB,kBAAkB,EAClB,sBAAsB,EACtB,KAAK,iBAAiB,EACtB,KAAK,uBAAuB,GAC7B,MAAM,sBAAsB,CAAC"}
|
package/dist/failure/index.js
CHANGED
|
@@ -20,7 +20,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
20
20
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
21
21
|
};
|
|
22
22
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
23
|
-
exports.createFailureRecorder = exports.FailureRecorder = exports.getFailureLevel = exports.classifyError = exports.createErrorClassifier = exports.ErrorClassifier = void 0;
|
|
23
|
+
exports.executeWithSafeBoolean = exports.executeWithCollect = exports.executeWithBlock = exports.ConstraintViolationHandler = exports.createFailureRecorder = exports.FailureRecorder = exports.getFailureLevel = exports.classifyError = exports.createErrorClassifier = exports.ErrorClassifier = void 0;
|
|
24
24
|
// 类型
|
|
25
25
|
__exportStar(require("./types"), exports);
|
|
26
26
|
// 分类器
|
|
@@ -33,4 +33,10 @@ Object.defineProperty(exports, "getFailureLevel", { enumerable: true, get: funct
|
|
|
33
33
|
var recorder_1 = require("./recorder");
|
|
34
34
|
Object.defineProperty(exports, "FailureRecorder", { enumerable: true, get: function () { return recorder_1.FailureRecorder; } });
|
|
35
35
|
Object.defineProperty(exports, "createFailureRecorder", { enumerable: true, get: function () { return recorder_1.createFailureRecorder; } });
|
|
36
|
+
// 约束违规处理(S4:统一处理策略)
|
|
37
|
+
var constraint_handler_1 = require("./constraint-handler");
|
|
38
|
+
Object.defineProperty(exports, "ConstraintViolationHandler", { enumerable: true, get: function () { return constraint_handler_1.ConstraintViolationHandler; } });
|
|
39
|
+
Object.defineProperty(exports, "executeWithBlock", { enumerable: true, get: function () { return constraint_handler_1.executeWithBlock; } });
|
|
40
|
+
Object.defineProperty(exports, "executeWithCollect", { enumerable: true, get: function () { return constraint_handler_1.executeWithCollect; } });
|
|
41
|
+
Object.defineProperty(exports, "executeWithSafeBoolean", { enumerable: true, get: function () { return constraint_handler_1.executeWithSafeBoolean; } });
|
|
36
42
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/failure/index.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;;;;;;;;;;;;;;;AAEH,KAAK;AACL,0CAAwB;AAExB,MAAM;AACN,2CAMsB;AALpB,6GAAA,eAAe,OAAA;AACf,mHAAA,qBAAqB,OAAA;AACrB,2GAAA,aAAa,OAAA;AACb,6GAAA,eAAe,OAAA;AAIjB,MAAM;AACN,uCAIoB;AAHlB,2GAAA,eAAe,OAAA;AACf,iHAAA,qBAAqB,OAAA"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/failure/index.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;;;;;;;;;;;;;;;AAEH,KAAK;AACL,0CAAwB;AAExB,MAAM;AACN,2CAMsB;AALpB,6GAAA,eAAe,OAAA;AACf,mHAAA,qBAAqB,OAAA;AACrB,2GAAA,aAAa,OAAA;AACb,6GAAA,eAAe,OAAA;AAIjB,MAAM;AACN,uCAIoB;AAHlB,2GAAA,eAAe,OAAA;AACf,iHAAA,qBAAqB,OAAA;AAIvB,oBAAoB;AACpB,2DAO8B;AAN5B,gIAAA,0BAA0B,OAAA;AAC1B,sHAAA,gBAAgB,OAAA;AAChB,wHAAA,kBAAkB,OAAA;AAClB,4HAAA,sBAAsB,OAAA"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Harness Bootstrap — 统一初始化入口(Phase 1)
|
|
3
|
+
*
|
|
4
|
+
* 解决:
|
|
5
|
+
* - S9: ProjectConfigLoader 异步加载,不阻塞事件循环
|
|
6
|
+
* - S2: 提供单例 SessionManager 生命周期管理
|
|
7
|
+
*
|
|
8
|
+
* Consumer 用法:
|
|
9
|
+
* ```typescript
|
|
10
|
+
* const harness = await bootstrapHarness('/path/to/project');
|
|
11
|
+
* // harness.checker, harness.config, harness.hooks, harness.sessions
|
|
12
|
+
* ```
|
|
13
|
+
*/
|
|
14
|
+
import { ConstraintChecker } from '../core/constraints/checker';
|
|
15
|
+
import { SessionManager } from '../context/session-manager';
|
|
16
|
+
import { HookRegistry } from './registry';
|
|
17
|
+
import { HookPipeline } from './pipeline';
|
|
18
|
+
import type { MergedConstraintsConfig } from '../types/project-config';
|
|
19
|
+
import type { HookDefinition } from './types';
|
|
20
|
+
/**
|
|
21
|
+
* Bootstrap 结果
|
|
22
|
+
*/
|
|
23
|
+
export interface HarnessBootstrap {
|
|
24
|
+
/** 约束检查器 */
|
|
25
|
+
checker: ConstraintChecker;
|
|
26
|
+
/** 会话管理器 */
|
|
27
|
+
sessions: SessionManager;
|
|
28
|
+
/** Hook 注册表 */
|
|
29
|
+
hooks: HookRegistry;
|
|
30
|
+
/** Hook 管线 */
|
|
31
|
+
pipeline: HookPipeline;
|
|
32
|
+
/** 项目路径 */
|
|
33
|
+
projectPath: string;
|
|
34
|
+
/** 合并后的约束配置 */
|
|
35
|
+
mergedConstraints: MergedConstraintsConfig;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* 初始化 harness 运行环境(异步,不阻塞事件循环)
|
|
39
|
+
*
|
|
40
|
+
* @param projectPath 项目根路径
|
|
41
|
+
* @param hookDefinitions 可选,初始化时注册的 hook
|
|
42
|
+
*/
|
|
43
|
+
export declare function bootstrapHarness(projectPath?: string, hookDefinitions?: HookDefinition[]): Promise<HarnessBootstrap>;
|
|
44
|
+
/**
|
|
45
|
+
* 同步 bootstrap(兼容不支持 top-level await 的环境)
|
|
46
|
+
*
|
|
47
|
+
* 配置加载仍为同步(readFileSync),其他组件初始化同上。
|
|
48
|
+
*/
|
|
49
|
+
export declare function bootstrapHarnessSync(projectPath?: string, hookDefinitions?: HookDefinition[]): HarnessBootstrap;
|
|
50
|
+
//# sourceMappingURL=bootstrap.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bootstrap.d.ts","sourceRoot":"","sources":["../../src/hooks/bootstrap.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAE5D,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AACvE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAiC9C;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,YAAY;IACZ,OAAO,EAAE,iBAAiB,CAAC;IAC3B,YAAY;IACZ,QAAQ,EAAE,cAAc,CAAC;IACzB,eAAe;IACf,KAAK,EAAE,YAAY,CAAC;IACpB,cAAc;IACd,QAAQ,EAAE,YAAY,CAAC;IACvB,WAAW;IACX,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe;IACf,iBAAiB,EAAE,uBAAuB,CAAC;CAC5C;AAED;;;;;GAKG;AACH,wBAAsB,gBAAgB,CACpC,WAAW,CAAC,EAAE,MAAM,EACpB,eAAe,CAAC,EAAE,cAAc,EAAE,GACjC,OAAO,CAAC,gBAAgB,CAAC,CA2B3B;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAClC,WAAW,CAAC,EAAE,MAAM,EACpB,eAAe,CAAC,EAAE,cAAc,EAAE,GACjC,gBAAgB,CA0BlB"}
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Harness Bootstrap — 统一初始化入口(Phase 1)
|
|
4
|
+
*
|
|
5
|
+
* 解决:
|
|
6
|
+
* - S9: ProjectConfigLoader 异步加载,不阻塞事件循环
|
|
7
|
+
* - S2: 提供单例 SessionManager 生命周期管理
|
|
8
|
+
*
|
|
9
|
+
* Consumer 用法:
|
|
10
|
+
* ```typescript
|
|
11
|
+
* const harness = await bootstrapHarness('/path/to/project');
|
|
12
|
+
* // harness.checker, harness.config, harness.hooks, harness.sessions
|
|
13
|
+
* ```
|
|
14
|
+
*/
|
|
15
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
16
|
+
if (k2 === undefined) k2 = k;
|
|
17
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
18
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
19
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
20
|
+
}
|
|
21
|
+
Object.defineProperty(o, k2, desc);
|
|
22
|
+
}) : (function(o, m, k, k2) {
|
|
23
|
+
if (k2 === undefined) k2 = k;
|
|
24
|
+
o[k2] = m[k];
|
|
25
|
+
}));
|
|
26
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
27
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
28
|
+
}) : function(o, v) {
|
|
29
|
+
o["default"] = v;
|
|
30
|
+
});
|
|
31
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
32
|
+
var ownKeys = function(o) {
|
|
33
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
34
|
+
var ar = [];
|
|
35
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
36
|
+
return ar;
|
|
37
|
+
};
|
|
38
|
+
return ownKeys(o);
|
|
39
|
+
};
|
|
40
|
+
return function (mod) {
|
|
41
|
+
if (mod && mod.__esModule) return mod;
|
|
42
|
+
var result = {};
|
|
43
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
44
|
+
__setModuleDefault(result, mod);
|
|
45
|
+
return result;
|
|
46
|
+
};
|
|
47
|
+
})();
|
|
48
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
49
|
+
exports.bootstrapHarness = bootstrapHarness;
|
|
50
|
+
exports.bootstrapHarnessSync = bootstrapHarnessSync;
|
|
51
|
+
const checker_1 = require("../core/constraints/checker");
|
|
52
|
+
const session_manager_1 = require("../context/session-manager");
|
|
53
|
+
const project_config_loader_1 = require("../core/project-config-loader");
|
|
54
|
+
const registry_1 = require("./registry");
|
|
55
|
+
const pipeline_1 = require("./pipeline");
|
|
56
|
+
/**
|
|
57
|
+
* 异步加载项目配置(S9:异步 I/O)
|
|
58
|
+
*/
|
|
59
|
+
async function loadConfigAsync(projectPath) {
|
|
60
|
+
// 使用动态 import 避免同步 readFileSync 阻塞事件循环
|
|
61
|
+
const { promises: fs } = await Promise.resolve().then(() => __importStar(require('fs')));
|
|
62
|
+
const path = await Promise.resolve().then(() => __importStar(require('path')));
|
|
63
|
+
const yaml = await Promise.resolve().then(() => __importStar(require('js-yaml')));
|
|
64
|
+
const loader = new project_config_loader_1.ProjectConfigLoader(projectPath);
|
|
65
|
+
// 异步读取主配置
|
|
66
|
+
const configPath = path.join(projectPath, '.harness', 'config.yml');
|
|
67
|
+
try {
|
|
68
|
+
await fs.access(configPath);
|
|
69
|
+
const content = await fs.readFile(configPath, 'utf-8');
|
|
70
|
+
const loaded = yaml.load(content);
|
|
71
|
+
loader.load(); // 同步回退作为 fallback
|
|
72
|
+
}
|
|
73
|
+
catch {
|
|
74
|
+
loader.load(); // 文件不存在,使用默认配置
|
|
75
|
+
}
|
|
76
|
+
return {
|
|
77
|
+
config: loader.getConfig(),
|
|
78
|
+
mergedConstraints: loader.mergeConstraints(),
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* 初始化 harness 运行环境(异步,不阻塞事件循环)
|
|
83
|
+
*
|
|
84
|
+
* @param projectPath 项目根路径
|
|
85
|
+
* @param hookDefinitions 可选,初始化时注册的 hook
|
|
86
|
+
*/
|
|
87
|
+
async function bootstrapHarness(projectPath, hookDefinitions) {
|
|
88
|
+
const resolvedPath = projectPath || process.cwd();
|
|
89
|
+
// 1. 异步加载配置(S9 fix)
|
|
90
|
+
const { config: _config, mergedConstraints } = await loadConfigAsync(resolvedPath);
|
|
91
|
+
// 2. 初始化核心组件
|
|
92
|
+
const checker = checker_1.ConstraintChecker.getInstance();
|
|
93
|
+
checker.setCustomConfig(mergedConstraints);
|
|
94
|
+
const sessions = new session_manager_1.SessionManager(resolvedPath);
|
|
95
|
+
const hooks = new registry_1.HookRegistry();
|
|
96
|
+
const pipeline = new pipeline_1.HookPipeline(hooks);
|
|
97
|
+
// 3. 注册初始 hook
|
|
98
|
+
if (hookDefinitions) {
|
|
99
|
+
hooks.registerAll(hookDefinitions);
|
|
100
|
+
}
|
|
101
|
+
return {
|
|
102
|
+
checker,
|
|
103
|
+
sessions,
|
|
104
|
+
hooks,
|
|
105
|
+
pipeline,
|
|
106
|
+
projectPath: resolvedPath,
|
|
107
|
+
mergedConstraints,
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* 同步 bootstrap(兼容不支持 top-level await 的环境)
|
|
112
|
+
*
|
|
113
|
+
* 配置加载仍为同步(readFileSync),其他组件初始化同上。
|
|
114
|
+
*/
|
|
115
|
+
function bootstrapHarnessSync(projectPath, hookDefinitions) {
|
|
116
|
+
const resolvedPath = projectPath || process.cwd();
|
|
117
|
+
const loader = new project_config_loader_1.ProjectConfigLoader(resolvedPath);
|
|
118
|
+
loader.load();
|
|
119
|
+
const mergedConstraints = loader.mergeConstraints();
|
|
120
|
+
const checker = checker_1.ConstraintChecker.getInstance();
|
|
121
|
+
checker.setCustomConfig(mergedConstraints);
|
|
122
|
+
const sessions = new session_manager_1.SessionManager(resolvedPath);
|
|
123
|
+
const hooks = new registry_1.HookRegistry();
|
|
124
|
+
const pipeline = new pipeline_1.HookPipeline(hooks);
|
|
125
|
+
if (hookDefinitions) {
|
|
126
|
+
hooks.registerAll(hookDefinitions);
|
|
127
|
+
}
|
|
128
|
+
return {
|
|
129
|
+
checker,
|
|
130
|
+
sessions,
|
|
131
|
+
hooks,
|
|
132
|
+
pipeline,
|
|
133
|
+
projectPath: resolvedPath,
|
|
134
|
+
mergedConstraints,
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
//# sourceMappingURL=bootstrap.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bootstrap.js","sourceRoot":"","sources":["../../src/hooks/bootstrap.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hooks 模块
|
|
3
|
+
*
|
|
4
|
+
* 通用 hook 管线:注册 → 排序 → 错误隔离 → 采样执行。
|
|
5
|
+
* 无业务逻辑,consumer 自行定义 hook 名称和语义。
|
|
6
|
+
*/
|
|
7
|
+
export * from './types';
|
|
8
|
+
export { HookRegistry } from './registry';
|
|
9
|
+
export { HookPipeline } from './pipeline';
|
|
10
|
+
export { bootstrapHarness, bootstrapHarnessSync, type HarnessBootstrap, } from './bootstrap';
|
|
11
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/hooks/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,cAAc,SAAS,CAAC;AACxB,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EACL,gBAAgB,EAChB,oBAAoB,EACpB,KAAK,gBAAgB,GACtB,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Hooks 模块
|
|
4
|
+
*
|
|
5
|
+
* 通用 hook 管线:注册 → 排序 → 错误隔离 → 采样执行。
|
|
6
|
+
* 无业务逻辑,consumer 自行定义 hook 名称和语义。
|
|
7
|
+
*/
|
|
8
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
9
|
+
if (k2 === undefined) k2 = k;
|
|
10
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
11
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
12
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
13
|
+
}
|
|
14
|
+
Object.defineProperty(o, k2, desc);
|
|
15
|
+
}) : (function(o, m, k, k2) {
|
|
16
|
+
if (k2 === undefined) k2 = k;
|
|
17
|
+
o[k2] = m[k];
|
|
18
|
+
}));
|
|
19
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
20
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
21
|
+
};
|
|
22
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
23
|
+
exports.bootstrapHarnessSync = exports.bootstrapHarness = exports.HookPipeline = exports.HookRegistry = void 0;
|
|
24
|
+
__exportStar(require("./types"), exports);
|
|
25
|
+
var registry_1 = require("./registry");
|
|
26
|
+
Object.defineProperty(exports, "HookRegistry", { enumerable: true, get: function () { return registry_1.HookRegistry; } });
|
|
27
|
+
var pipeline_1 = require("./pipeline");
|
|
28
|
+
Object.defineProperty(exports, "HookPipeline", { enumerable: true, get: function () { return pipeline_1.HookPipeline; } });
|
|
29
|
+
var bootstrap_1 = require("./bootstrap");
|
|
30
|
+
Object.defineProperty(exports, "bootstrapHarness", { enumerable: true, get: function () { return bootstrap_1.bootstrapHarness; } });
|
|
31
|
+
Object.defineProperty(exports, "bootstrapHarnessSync", { enumerable: true, get: function () { return bootstrap_1.bootstrapHarnessSync; } });
|
|
32
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/hooks/index.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;;;;;;;;;;;;;;;AAEH,0CAAwB;AACxB,uCAA0C;AAAjC,wGAAA,YAAY,OAAA;AACrB,uCAA0C;AAAjC,wGAAA,YAAY,OAAA;AACrB,yCAIqB;AAHnB,6GAAA,gBAAgB,OAAA;AAChB,iHAAA,oBAAoB,OAAA"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HookPipeline — hook 有序执行、错误隔离、采样
|
|
3
|
+
*
|
|
4
|
+
* 执行顺序:before hooks → consumer operation → after hooks
|
|
5
|
+
* 每个 hook 独立 try/catch,单个 hook 失败不影���其他 hook。
|
|
6
|
+
*/
|
|
7
|
+
import type { HookPhase, PipelineResult } from './types';
|
|
8
|
+
import type { HookRegistry } from './registry';
|
|
9
|
+
export declare class HookPipeline<C = unknown> {
|
|
10
|
+
private registry;
|
|
11
|
+
constructor(registry: HookRegistry<C, unknown>);
|
|
12
|
+
/**
|
|
13
|
+
* 执行指定 phase 的所有 enabled hook
|
|
14
|
+
*
|
|
15
|
+
* @param phase hook 时机
|
|
16
|
+
* @param context 传递给每个 hook 的上下文
|
|
17
|
+
* @returns 管线执行结果
|
|
18
|
+
*/
|
|
19
|
+
run(phase: HookPhase, context: C): Promise<PipelineResult>;
|
|
20
|
+
/**
|
|
21
|
+
* 执行 before + after 全套管线
|
|
22
|
+
*
|
|
23
|
+
* @param context 上下文
|
|
24
|
+
* @param operation 业务操作(在 before 和 after 之间执行)
|
|
25
|
+
* @returns 管线结果 + 操作结果
|
|
26
|
+
*/
|
|
27
|
+
runFull<R>(context: C, operation: () => Promise<R>): Promise<{
|
|
28
|
+
pipelineResult: PipelineResult;
|
|
29
|
+
operationResult?: R;
|
|
30
|
+
}>;
|
|
31
|
+
/**
|
|
32
|
+
* 执行单个 hook(带采样和错误隔离)
|
|
33
|
+
*/
|
|
34
|
+
private executeOne;
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=pipeline.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pipeline.d.ts","sourceRoot":"","sources":["../../src/hooks/pipeline.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAEV,SAAS,EAET,cAAc,EACf,MAAM,SAAS,CAAC;AACjB,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE/C,qBAAa,YAAY,CAAC,CAAC,GAAG,OAAO;IACnC,OAAO,CAAC,QAAQ,CAA2B;gBAE/B,QAAQ,EAAE,YAAY,CAAC,CAAC,EAAE,OAAO,CAAC;IAI9C;;;;;;OAMG;IACG,GAAG,CACP,KAAK,EAAE,SAAS,EAChB,OAAO,EAAE,CAAC,GACT,OAAO,CAAC,cAAc,CAAC;IA2B1B;;;;;;OAMG;IACG,OAAO,CAAC,CAAC,EACb,OAAO,EAAE,CAAC,EACV,SAAS,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAC1B,OAAO,CAAC;QAAE,cAAc,EAAE,cAAc,CAAC;QAAC,eAAe,CAAC,EAAE,CAAC,CAAA;KAAE,CAAC;IAwCnE;;OAEG;YACW,UAAU;CA4CzB"}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* HookPipeline — hook 有序执行、错误隔离、采样
|
|
4
|
+
*
|
|
5
|
+
* 执行顺序:before hooks → consumer operation → after hooks
|
|
6
|
+
* 每个 hook 独立 try/catch,单个 hook 失败不影���其他 hook。
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.HookPipeline = void 0;
|
|
10
|
+
class HookPipeline {
|
|
11
|
+
registry;
|
|
12
|
+
constructor(registry) {
|
|
13
|
+
this.registry = registry;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* 执行指定 phase 的所有 enabled hook
|
|
17
|
+
*
|
|
18
|
+
* @param phase hook 时机
|
|
19
|
+
* @param context 传递给每个 hook 的上下文
|
|
20
|
+
* @returns 管线执行结果
|
|
21
|
+
*/
|
|
22
|
+
async run(phase, context) {
|
|
23
|
+
const hooks = this.registry.getEnabled(phase);
|
|
24
|
+
const records = [];
|
|
25
|
+
const blockedBy = [];
|
|
26
|
+
const warnings = [];
|
|
27
|
+
let passed = true;
|
|
28
|
+
for (const hook of hooks) {
|
|
29
|
+
const record = await this.executeOne(hook, context);
|
|
30
|
+
records.push(record);
|
|
31
|
+
if (!record.passed) {
|
|
32
|
+
if (hook.errorStrategy === 'block') {
|
|
33
|
+
passed = false;
|
|
34
|
+
blockedBy.push(hook.name);
|
|
35
|
+
break; // blocking hook 失败,停止执行后续 hook
|
|
36
|
+
}
|
|
37
|
+
if (hook.errorStrategy === 'warn') {
|
|
38
|
+
warnings.push(hook.name);
|
|
39
|
+
}
|
|
40
|
+
// 'ignore' 策略静默跳过
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return { passed, records, blockedBy, warnings };
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* 执行 before + after 全套管线
|
|
47
|
+
*
|
|
48
|
+
* @param context 上下文
|
|
49
|
+
* @param operation 业务操作(在 before 和 after 之间执行)
|
|
50
|
+
* @returns 管线结果 + 操作结果
|
|
51
|
+
*/
|
|
52
|
+
async runFull(context, operation) {
|
|
53
|
+
// 1. Before hooks
|
|
54
|
+
const beforeResult = await this.run('before', context);
|
|
55
|
+
if (!beforeResult.passed) {
|
|
56
|
+
return { pipelineResult: beforeResult };
|
|
57
|
+
}
|
|
58
|
+
// 2. Execute operation
|
|
59
|
+
let operationResult;
|
|
60
|
+
try {
|
|
61
|
+
operationResult = await operation();
|
|
62
|
+
}
|
|
63
|
+
catch (err) {
|
|
64
|
+
// 操作失败:仍执行 after hooks,但传递错误信息
|
|
65
|
+
const afterResult = await this.run('after', {
|
|
66
|
+
...context,
|
|
67
|
+
_operationError: err.message,
|
|
68
|
+
});
|
|
69
|
+
return {
|
|
70
|
+
pipelineResult: {
|
|
71
|
+
passed: false,
|
|
72
|
+
records: [...beforeResult.records, ...afterResult.records],
|
|
73
|
+
blockedBy: [...beforeResult.blockedBy, '_operation'],
|
|
74
|
+
warnings: [...beforeResult.warnings, ...afterResult.warnings],
|
|
75
|
+
},
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
// 3. After hooks
|
|
79
|
+
const afterResult = await this.run('after', context);
|
|
80
|
+
return {
|
|
81
|
+
pipelineResult: {
|
|
82
|
+
passed: beforeResult.passed && afterResult.passed,
|
|
83
|
+
records: [...beforeResult.records, ...afterResult.records],
|
|
84
|
+
blockedBy: [...beforeResult.blockedBy, ...afterResult.blockedBy],
|
|
85
|
+
warnings: [...beforeResult.warnings, ...afterResult.warnings],
|
|
86
|
+
},
|
|
87
|
+
operationResult,
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* 执行单个 hook(带采样和错误隔离)
|
|
92
|
+
*/
|
|
93
|
+
async executeOne(hook, context) {
|
|
94
|
+
const startedAt = Date.now();
|
|
95
|
+
// 采样检查
|
|
96
|
+
if (hook.sampleRate !== undefined && hook.sampleRate < 1) {
|
|
97
|
+
if (Math.random() > hook.sampleRate) {
|
|
98
|
+
return {
|
|
99
|
+
hookName: hook.name,
|
|
100
|
+
phase: hook.phase,
|
|
101
|
+
startedAt,
|
|
102
|
+
completedAt: Date.now(),
|
|
103
|
+
durationMs: 0,
|
|
104
|
+
passed: true,
|
|
105
|
+
sampled: true,
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
try {
|
|
110
|
+
const result = await hook.execute(context);
|
|
111
|
+
return {
|
|
112
|
+
hookName: hook.name,
|
|
113
|
+
phase: hook.phase,
|
|
114
|
+
startedAt,
|
|
115
|
+
completedAt: Date.now(),
|
|
116
|
+
durationMs: Date.now() - startedAt,
|
|
117
|
+
passed: result.passed !== false,
|
|
118
|
+
error: result.error,
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
catch (err) {
|
|
122
|
+
return {
|
|
123
|
+
hookName: hook.name,
|
|
124
|
+
phase: hook.phase,
|
|
125
|
+
startedAt,
|
|
126
|
+
completedAt: Date.now(),
|
|
127
|
+
durationMs: Date.now() - startedAt,
|
|
128
|
+
passed: false,
|
|
129
|
+
error: err.message,
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
exports.HookPipeline = HookPipeline;
|
|
135
|
+
//# sourceMappingURL=pipeline.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pipeline.js","sourceRoot":"","sources":["../../src/hooks/pipeline.ts"],"names":[],"mappings":"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"}
|