@frontmcp/sdk 0.3.0 → 0.4.0
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/LICENSE +201 -0
- package/README.md +192 -164
- package/package.json +7 -4
- package/src/__test-utils__/fixtures/hook.fixtures.d.ts +46 -0
- package/src/__test-utils__/fixtures/hook.fixtures.js +114 -0
- package/src/__test-utils__/fixtures/hook.fixtures.js.map +1 -0
- package/src/__test-utils__/fixtures/index.d.ts +7 -0
- package/src/__test-utils__/fixtures/index.js +11 -0
- package/src/__test-utils__/fixtures/index.js.map +1 -0
- package/src/__test-utils__/fixtures/plugin.fixtures.d.ts +46 -0
- package/src/__test-utils__/fixtures/plugin.fixtures.js +127 -0
- package/src/__test-utils__/fixtures/plugin.fixtures.js.map +1 -0
- package/src/__test-utils__/fixtures/provider.fixtures.d.ts +69 -0
- package/src/__test-utils__/fixtures/provider.fixtures.js +131 -0
- package/src/__test-utils__/fixtures/provider.fixtures.js.map +1 -0
- package/src/__test-utils__/fixtures/scope.fixtures.d.ts +14 -0
- package/src/__test-utils__/fixtures/scope.fixtures.js +59 -0
- package/src/__test-utils__/fixtures/scope.fixtures.js.map +1 -0
- package/src/__test-utils__/fixtures/tool.fixtures.d.ts +36 -0
- package/src/__test-utils__/fixtures/tool.fixtures.js +91 -0
- package/src/__test-utils__/fixtures/tool.fixtures.js.map +1 -0
- package/src/__test-utils__/helpers/assertion.helpers.d.ts +45 -0
- package/src/__test-utils__/helpers/assertion.helpers.js +153 -0
- package/src/__test-utils__/helpers/assertion.helpers.js.map +1 -0
- package/src/__test-utils__/helpers/async.helpers.d.ts +48 -0
- package/src/__test-utils__/helpers/async.helpers.js +112 -0
- package/src/__test-utils__/helpers/async.helpers.js.map +1 -0
- package/src/__test-utils__/helpers/index.d.ts +6 -0
- package/src/__test-utils__/helpers/index.js +10 -0
- package/src/__test-utils__/helpers/index.js.map +1 -0
- package/src/__test-utils__/helpers/setup.helpers.d.ts +54 -0
- package/src/__test-utils__/helpers/setup.helpers.js +106 -0
- package/src/__test-utils__/helpers/setup.helpers.js.map +1 -0
- package/src/__test-utils__/index.d.ts +9 -0
- package/src/__test-utils__/index.js +14 -0
- package/src/__test-utils__/index.js.map +1 -0
- package/src/__test-utils__/mocks/flow-instance.mock.d.ts +50 -0
- package/src/__test-utils__/mocks/flow-instance.mock.js +72 -0
- package/src/__test-utils__/mocks/flow-instance.mock.js.map +1 -0
- package/src/__test-utils__/mocks/hook-registry.mock.d.ts +25 -0
- package/src/__test-utils__/mocks/hook-registry.mock.js +65 -0
- package/src/__test-utils__/mocks/hook-registry.mock.js.map +1 -0
- package/src/__test-utils__/mocks/index.d.ts +8 -0
- package/src/__test-utils__/mocks/index.js +12 -0
- package/src/__test-utils__/mocks/index.js.map +1 -0
- package/src/__test-utils__/mocks/plugin-registry.mock.d.ts +43 -0
- package/src/__test-utils__/mocks/plugin-registry.mock.js +70 -0
- package/src/__test-utils__/mocks/plugin-registry.mock.js.map +1 -0
- package/src/__test-utils__/mocks/provider-registry.mock.d.ts +39 -0
- package/src/__test-utils__/mocks/provider-registry.mock.js +72 -0
- package/src/__test-utils__/mocks/provider-registry.mock.js.map +1 -0
- package/src/__test-utils__/mocks/tool-registry.mock.d.ts +43 -0
- package/src/__test-utils__/mocks/tool-registry.mock.js +79 -0
- package/src/__test-utils__/mocks/tool-registry.mock.js.map +1 -0
- package/src/app/app.utils.js.map +1 -1
- package/src/app/instances/app.local.instance.js +8 -11
- package/src/app/instances/app.local.instance.js.map +1 -1
- package/src/auth/auth.registry.d.ts +2 -2
- package/src/auth/auth.registry.js +3 -3
- package/src/auth/auth.registry.js.map +1 -1
- package/src/auth/flows/oauth.authorize.flow.d.ts +8 -8
- package/src/auth/flows/oauth.register.flow.d.ts +4 -4
- package/src/auth/flows/oauth.token.flow.d.ts +4 -4
- package/src/auth/flows/well-known.jwks.flow.d.ts +12 -12
- package/src/auth/flows/well-known.oauth-authorization-server.flow.d.ts +8 -8
- package/src/auth/flows/well-known.prm.flow.d.ts +4 -4
- package/src/auth/instances/instance.local-primary-auth.d.ts +3 -2
- package/src/auth/instances/instance.local-primary-auth.js +4 -2
- package/src/auth/instances/instance.local-primary-auth.js.map +1 -1
- package/src/auth/instances/instance.remote-primary-auth.d.ts +3 -2
- package/src/auth/instances/instance.remote-primary-auth.js +3 -1
- package/src/auth/instances/instance.remote-primary-auth.js.map +1 -1
- package/src/auth/jwks/jwks.service.js +0 -1
- package/src/auth/jwks/jwks.service.js.map +1 -1
- package/src/common/decorators/tool.decorator.d.ts +97 -36
- package/src/common/decorators/tool.decorator.js +0 -1
- package/src/common/decorators/tool.decorator.js.map +1 -1
- package/src/common/entries/scope.entry.d.ts +1 -0
- package/src/common/entries/scope.entry.js +6 -0
- package/src/common/entries/scope.entry.js.map +1 -1
- package/src/common/entries/tool.entry.d.ts +54 -11
- package/src/common/entries/tool.entry.js +19 -0
- package/src/common/entries/tool.entry.js.map +1 -1
- package/src/common/interfaces/internal/registry.interface.d.ts +10 -2
- package/src/common/interfaces/internal/registry.interface.js.map +1 -1
- package/src/common/interfaces/plugin.interface.d.ts +1 -1
- package/src/common/interfaces/plugin.interface.js.map +1 -1
- package/src/common/interfaces/tool.interface.d.ts +12 -7
- package/src/common/interfaces/tool.interface.js +1 -1
- package/src/common/interfaces/tool.interface.js.map +1 -1
- package/src/common/metadata/front-mcp.metadata.d.ts +145 -145
- package/src/common/metadata/hook.metadata.d.ts +4 -2
- package/src/common/metadata/hook.metadata.js.map +1 -1
- package/src/common/metadata/prompt.metadata.d.ts +28 -28
- package/src/common/metadata/prompt.metadata.js.map +1 -1
- package/src/common/metadata/resource.metadata.d.ts +54 -54
- package/src/common/metadata/tool.metadata.d.ts +190 -7
- package/src/common/metadata/tool.metadata.js +41 -6
- package/src/common/metadata/tool.metadata.js.map +1 -1
- package/src/common/records/scope.record.d.ts +2 -2
- package/src/common/records/scope.record.js.map +1 -1
- package/src/common/schemas/http-output.schema.d.ts +106 -106
- package/src/common/tokens/tool.tokens.js.map +1 -1
- package/src/common/types/options/logging.options.d.ts +1 -2
- package/src/common/types/options/logging.options.js +1 -9
- package/src/common/types/options/logging.options.js.map +1 -1
- package/src/common/types/options/server-info.options.d.ts +19 -19
- package/src/errors/error-handler.d.ts +65 -0
- package/src/errors/error-handler.js +107 -0
- package/src/errors/error-handler.js.map +1 -0
- package/src/errors/index.d.ts +2 -0
- package/src/errors/index.js +26 -0
- package/src/errors/index.js.map +1 -0
- package/src/errors/mcp.error.d.ts +156 -0
- package/src/errors/mcp.error.js +243 -0
- package/src/errors/mcp.error.js.map +1 -0
- package/src/flows/flow.instance.js +7 -6
- package/src/flows/flow.instance.js.map +1 -1
- package/src/flows/flow.registry.js +1 -1
- package/src/flows/flow.registry.js.map +1 -1
- package/src/front-mcp/front-mcp.providers.d.ts +20 -20
- package/src/hooks/hook.registry.d.ts +5 -3
- package/src/hooks/hook.registry.js +13 -1
- package/src/hooks/hook.registry.js.map +1 -1
- package/src/plugin/plugin.registry.d.ts +7 -2
- package/src/plugin/plugin.registry.js +23 -11
- package/src/plugin/plugin.registry.js.map +1 -1
- package/src/prompt/prompt.registry.js +1 -0
- package/src/prompt/prompt.registry.js.map +1 -1
- package/src/resource/resource.registry.js +1 -0
- package/src/resource/resource.registry.js.map +1 -1
- package/src/scope/scope.instance.js +8 -2
- package/src/scope/scope.instance.js.map +1 -1
- package/src/scope/scope.registry.js +3 -2
- package/src/scope/scope.registry.js.map +1 -1
- package/src/scope/scope.utils.js +6 -4
- package/src/scope/scope.utils.js.map +1 -1
- package/src/store/adapters/store.memory.adapter.js +3 -1
- package/src/store/adapters/store.memory.adapter.js.map +1 -1
- package/src/tool/flows/call-tool.flow.d.ts +1012 -676
- package/src/tool/flows/call-tool.flow.js +94 -61
- package/src/tool/flows/call-tool.flow.js.map +1 -1
- package/src/tool/flows/tools-list.flow.d.ts +347 -590
- package/src/tool/flows/tools-list.flow.js +76 -49
- package/src/tool/flows/tools-list.flow.js.map +1 -1
- package/src/tool/tool.instance.d.ts +27 -8
- package/src/tool/tool.instance.js +40 -5
- package/src/tool/tool.instance.js.map +1 -1
- package/src/tool/tool.registry.js +19 -21
- package/src/tool/tool.registry.js.map +1 -1
- package/src/tool/tool.utils.d.ts +3 -2
- package/src/tool/tool.utils.js +377 -14
- package/src/tool/tool.utils.js.map +1 -1
- package/src/transport/adapters/transport.sse.adapter.js +2 -1
- package/src/transport/adapters/transport.sse.adapter.js.map +1 -1
- package/src/transport/adapters/transport.streamable-http.adapter.js.map +1 -1
- package/src/transport/flows/handle.sse.flow.js +6 -13
- package/src/transport/flows/handle.sse.flow.js.map +1 -1
- package/src/transport/flows/handle.streamable-http.flow.js +1 -0
- package/src/transport/flows/handle.streamable-http.flow.js.map +1 -1
- package/src/transport/mcp-handlers/call-tool-request.handler.d.ts +1 -1
- package/src/transport/mcp-handlers/call-tool-request.handler.js +10 -5
- package/src/transport/mcp-handlers/call-tool-request.handler.js.map +1 -1
- package/src/transport/mcp-handlers/index.d.ts +151 -268
- package/src/transport/mcp-handlers/list-tools-request.handler.d.ts +124 -216
- package/src/transport/transport.local.js +1 -0
- package/src/transport/transport.local.js.map +1 -1
- package/src/utils/string.utils.js +1 -1
- package/src/utils/string.utils.js.map +1 -1
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.GenericServerError = exports.UnauthorizedError = exports.QuotaExceededError = exports.RateLimitError = exports.ToolExecutionError = exports.InvalidMethodError = exports.InvalidOutputError = exports.InvalidInputError = exports.ToolNotFoundError = exports.InternalMcpError = exports.PublicMcpError = exports.McpError = void 0;
|
|
4
|
+
exports.isPublicError = isPublicError;
|
|
5
|
+
exports.toMcpError = toMcpError;
|
|
6
|
+
exports.formatMcpErrorResponse = formatMcpErrorResponse;
|
|
7
|
+
// errors/mcp.error.ts
|
|
8
|
+
const crypto_1 = require("crypto");
|
|
9
|
+
/**
|
|
10
|
+
* Base class for all MCP-related errors
|
|
11
|
+
*/
|
|
12
|
+
class McpError extends Error {
|
|
13
|
+
/**
|
|
14
|
+
* Unique error ID for tracking in logs
|
|
15
|
+
*/
|
|
16
|
+
errorId;
|
|
17
|
+
constructor(message, errorId) {
|
|
18
|
+
super(message);
|
|
19
|
+
this.name = this.constructor.name;
|
|
20
|
+
this.errorId = errorId || this.generateErrorId();
|
|
21
|
+
Error.captureStackTrace(this, this.constructor);
|
|
22
|
+
}
|
|
23
|
+
generateErrorId() {
|
|
24
|
+
return `err_${(0, crypto_1.randomBytes)(8).toString('hex')}`;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Get the internal error message (for logging)
|
|
28
|
+
*/
|
|
29
|
+
getInternalMessage() {
|
|
30
|
+
return this.message;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Convert to MCP error response format
|
|
34
|
+
*/
|
|
35
|
+
toMcpError(isDevelopment = false) {
|
|
36
|
+
const message = isDevelopment ? this.getInternalMessage() : this.getPublicMessage();
|
|
37
|
+
return {
|
|
38
|
+
content: [
|
|
39
|
+
{
|
|
40
|
+
type: 'text',
|
|
41
|
+
text: message,
|
|
42
|
+
},
|
|
43
|
+
],
|
|
44
|
+
isError: true,
|
|
45
|
+
_meta: {
|
|
46
|
+
errorId: this.errorId,
|
|
47
|
+
code: this.code,
|
|
48
|
+
timestamp: new Date().toISOString(),
|
|
49
|
+
...(isDevelopment && { stack: this.stack }),
|
|
50
|
+
},
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
exports.McpError = McpError;
|
|
55
|
+
/**
|
|
56
|
+
* Public errors - safe to expose to clients
|
|
57
|
+
* These include validation errors, not found errors, etc.
|
|
58
|
+
*/
|
|
59
|
+
class PublicMcpError extends McpError {
|
|
60
|
+
isPublic = true;
|
|
61
|
+
statusCode;
|
|
62
|
+
code;
|
|
63
|
+
constructor(message, code = 'PUBLIC_ERROR', statusCode = 400) {
|
|
64
|
+
super(message);
|
|
65
|
+
this.code = code;
|
|
66
|
+
this.statusCode = statusCode;
|
|
67
|
+
}
|
|
68
|
+
getPublicMessage() {
|
|
69
|
+
return this.message;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
exports.PublicMcpError = PublicMcpError;
|
|
73
|
+
/**
|
|
74
|
+
* Internal errors - should not expose details to clients
|
|
75
|
+
* These are server errors, unexpected failures, etc.
|
|
76
|
+
*/
|
|
77
|
+
class InternalMcpError extends McpError {
|
|
78
|
+
isPublic = false;
|
|
79
|
+
statusCode = 500;
|
|
80
|
+
code;
|
|
81
|
+
constructor(message, code = 'INTERNAL_ERROR') {
|
|
82
|
+
super(message);
|
|
83
|
+
this.code = code;
|
|
84
|
+
}
|
|
85
|
+
getPublicMessage() {
|
|
86
|
+
return `Internal FrontMCP error. Please contact support with error ID: ${this.errorId}`;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
exports.InternalMcpError = InternalMcpError;
|
|
90
|
+
// ============================================================================
|
|
91
|
+
// Specific Error Classes
|
|
92
|
+
// ============================================================================
|
|
93
|
+
/**
|
|
94
|
+
* Tool didn't find an error
|
|
95
|
+
*/
|
|
96
|
+
class ToolNotFoundError extends PublicMcpError {
|
|
97
|
+
constructor(toolName) {
|
|
98
|
+
super(`Tool "${toolName}" not found`, 'TOOL_NOT_FOUND', 404);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
exports.ToolNotFoundError = ToolNotFoundError;
|
|
102
|
+
/**
|
|
103
|
+
* Invalid input validation error
|
|
104
|
+
*/
|
|
105
|
+
class InvalidInputError extends PublicMcpError {
|
|
106
|
+
validationErrors;
|
|
107
|
+
constructor(message = 'Invalid input: validation failed', validationErrors) {
|
|
108
|
+
super(message, 'INVALID_INPUT', 400);
|
|
109
|
+
this.validationErrors = validationErrors;
|
|
110
|
+
}
|
|
111
|
+
getInternalMessage() {
|
|
112
|
+
return this.message + (this.validationErrors ? `\nDetails: ${JSON.stringify(this.validationErrors, null, 2)}` : '');
|
|
113
|
+
}
|
|
114
|
+
getPublicMessage() {
|
|
115
|
+
if (this.validationErrors) {
|
|
116
|
+
return `${this.message}\nDetails: ${JSON.stringify(this.validationErrors, null, 2)}`;
|
|
117
|
+
}
|
|
118
|
+
return this.message;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
exports.InvalidInputError = InvalidInputError;
|
|
122
|
+
/**
|
|
123
|
+
* Invalid output validation error (internal - don't expose schema details)
|
|
124
|
+
*/
|
|
125
|
+
class InvalidOutputError extends InternalMcpError {
|
|
126
|
+
hasCustomErrorId;
|
|
127
|
+
constructor(errorId) {
|
|
128
|
+
super('Tool output validation failed', 'INVALID_OUTPUT');
|
|
129
|
+
this.hasCustomErrorId = !!errorId;
|
|
130
|
+
if (errorId) {
|
|
131
|
+
this.errorId = errorId;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
getPublicMessage() {
|
|
135
|
+
// If a custom errorId was provided (e.g., request ID), include it for correlation
|
|
136
|
+
// Otherwise, use a simpler message since the auto-generated ID isn't meaningful to users
|
|
137
|
+
if (this.hasCustomErrorId) {
|
|
138
|
+
return `Output validation failed. Please contact support with error ID: ${this.errorId}`;
|
|
139
|
+
}
|
|
140
|
+
return 'Output validation failed. Please contact support.';
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
exports.InvalidOutputError = InvalidOutputError;
|
|
144
|
+
/**
|
|
145
|
+
* Invalid method error
|
|
146
|
+
*/
|
|
147
|
+
class InvalidMethodError extends PublicMcpError {
|
|
148
|
+
constructor(method, expected) {
|
|
149
|
+
super(`Invalid method "${method}". Expected "${expected}"`, 'INVALID_METHOD', 400);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
exports.InvalidMethodError = InvalidMethodError;
|
|
153
|
+
/**
|
|
154
|
+
* Tool execution error (internal)
|
|
155
|
+
*/
|
|
156
|
+
class ToolExecutionError extends InternalMcpError {
|
|
157
|
+
originalError;
|
|
158
|
+
constructor(toolName, originalError) {
|
|
159
|
+
super(`Tool "${toolName}" execution failed: ${originalError?.message || 'Unknown error'}`, 'TOOL_EXECUTION_ERROR');
|
|
160
|
+
this.originalError = originalError;
|
|
161
|
+
}
|
|
162
|
+
getInternalMessage() {
|
|
163
|
+
if (this.originalError?.stack) {
|
|
164
|
+
return `${this.message}\n\nOriginal error:\n${this.originalError.stack}`;
|
|
165
|
+
}
|
|
166
|
+
return this.message;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
exports.ToolExecutionError = ToolExecutionError;
|
|
170
|
+
/**
|
|
171
|
+
* Rate limit error
|
|
172
|
+
*/
|
|
173
|
+
class RateLimitError extends PublicMcpError {
|
|
174
|
+
constructor(retryAfter) {
|
|
175
|
+
const message = retryAfter ? `Rate limit exceeded. Retry after ${retryAfter} seconds` : 'Rate limit exceeded';
|
|
176
|
+
super(message, 'RATE_LIMIT_EXCEEDED', 429);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
exports.RateLimitError = RateLimitError;
|
|
180
|
+
/**
|
|
181
|
+
* Quota exceeded error
|
|
182
|
+
*/
|
|
183
|
+
class QuotaExceededError extends PublicMcpError {
|
|
184
|
+
constructor(quotaType = 'usage') {
|
|
185
|
+
super(`${quotaType} quota exceeded`, 'QUOTA_EXCEEDED', 429);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
exports.QuotaExceededError = QuotaExceededError;
|
|
189
|
+
/**
|
|
190
|
+
* Unauthorized error
|
|
191
|
+
*/
|
|
192
|
+
class UnauthorizedError extends PublicMcpError {
|
|
193
|
+
constructor(message = 'Unauthorized') {
|
|
194
|
+
super(message, 'UNAUTHORIZED', 401);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
exports.UnauthorizedError = UnauthorizedError;
|
|
198
|
+
/**
|
|
199
|
+
* Generic server error wrapper
|
|
200
|
+
*/
|
|
201
|
+
class GenericServerError extends InternalMcpError {
|
|
202
|
+
originalError;
|
|
203
|
+
constructor(message, originalError) {
|
|
204
|
+
super(message, 'SERVER_ERROR');
|
|
205
|
+
this.originalError = originalError;
|
|
206
|
+
}
|
|
207
|
+
getInternalMessage() {
|
|
208
|
+
if (this.originalError?.stack) {
|
|
209
|
+
return `${this.message}\n\nOriginal error:\n${this.originalError.stack}`;
|
|
210
|
+
}
|
|
211
|
+
return this.message;
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
exports.GenericServerError = GenericServerError;
|
|
215
|
+
// ============================================================================
|
|
216
|
+
// Error Utilities
|
|
217
|
+
// ============================================================================
|
|
218
|
+
/**
|
|
219
|
+
* Check if the error is a public error that can be safely shown to users
|
|
220
|
+
*/
|
|
221
|
+
function isPublicError(error) {
|
|
222
|
+
return error instanceof McpError && error.isPublic;
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
225
|
+
* Convert any error to an MCP error
|
|
226
|
+
*/
|
|
227
|
+
function toMcpError(error) {
|
|
228
|
+
if (error instanceof McpError) {
|
|
229
|
+
return error;
|
|
230
|
+
}
|
|
231
|
+
if (error instanceof Error) {
|
|
232
|
+
return new GenericServerError(error.message, error);
|
|
233
|
+
}
|
|
234
|
+
return new GenericServerError(String(error));
|
|
235
|
+
}
|
|
236
|
+
/**
|
|
237
|
+
* Format error for MCP response
|
|
238
|
+
*/
|
|
239
|
+
function formatMcpErrorResponse(error, isDevelopment = process.env['NODE_ENV'] !== 'production') {
|
|
240
|
+
const mcpError = toMcpError(error);
|
|
241
|
+
return mcpError.toMcpError(isDevelopment);
|
|
242
|
+
}
|
|
243
|
+
//# sourceMappingURL=mcp.error.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp.error.js","sourceRoot":"","sources":["../../../src/errors/mcp.error.ts"],"names":[],"mappings":"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","sourcesContent":["// errors/mcp.error.ts\nimport { randomBytes } from 'crypto';\n\n/**\n * Base class for all MCP-related errors\n */\nexport abstract class McpError extends Error {\n /**\n * Unique error ID for tracking in logs\n */\n errorId: string;\n\n /**\n * Whether this error should expose details to the client\n */\n abstract readonly isPublic: boolean;\n\n /**\n * HTTP status code equivalent (for reference)\n */\n abstract readonly statusCode: number;\n\n /**\n * Error code for categorization\n */\n abstract readonly code: string;\n\n protected constructor(message: string, errorId?: string) {\n super(message);\n this.name = this.constructor.name;\n this.errorId = errorId || this.generateErrorId();\n Error.captureStackTrace(this, this.constructor);\n }\n\n private generateErrorId(): string {\n return `err_${randomBytes(8).toString('hex')}`;\n }\n\n /**\n * Get the public-facing error message\n */\n abstract getPublicMessage(): string;\n\n /**\n * Get the internal error message (for logging)\n */\n getInternalMessage(): string {\n return this.message;\n }\n\n /**\n * Convert to MCP error response format\n */\n toMcpError(isDevelopment = false): {\n content: Array<{ type: 'text'; text: string }>;\n isError: true;\n _meta?: {\n errorId: string;\n code: string;\n timestamp: string;\n stack?: string;\n };\n } {\n const message = isDevelopment ? this.getInternalMessage() : this.getPublicMessage();\n\n return {\n content: [\n {\n type: 'text',\n text: message,\n },\n ],\n isError: true,\n _meta: {\n errorId: this.errorId,\n code: this.code,\n timestamp: new Date().toISOString(),\n ...(isDevelopment && { stack: this.stack }),\n },\n };\n }\n}\n\n/**\n * Public errors - safe to expose to clients\n * These include validation errors, not found errors, etc.\n */\nexport class PublicMcpError extends McpError {\n readonly isPublic = true;\n readonly statusCode: number;\n readonly code: string;\n\n constructor(message: string, code = 'PUBLIC_ERROR', statusCode = 400) {\n super(message);\n this.code = code;\n this.statusCode = statusCode;\n }\n\n getPublicMessage(): string {\n return this.message;\n }\n}\n\n/**\n * Internal errors - should not expose details to clients\n * These are server errors, unexpected failures, etc.\n */\nexport class InternalMcpError extends McpError {\n readonly isPublic = false;\n readonly statusCode = 500;\n readonly code: string;\n\n constructor(message: string, code = 'INTERNAL_ERROR') {\n super(message);\n this.code = code;\n }\n\n getPublicMessage(): string {\n return `Internal FrontMCP error. Please contact support with error ID: ${this.errorId}`;\n }\n}\n\n// ============================================================================\n// Specific Error Classes\n// ============================================================================\n\n/**\n * Tool didn't find an error\n */\nexport class ToolNotFoundError extends PublicMcpError {\n constructor(toolName: string) {\n super(`Tool \"${toolName}\" not found`, 'TOOL_NOT_FOUND', 404);\n }\n}\n\n/**\n * Invalid input validation error\n */\nexport class InvalidInputError extends PublicMcpError {\n readonly validationErrors?: any;\n\n constructor(message = 'Invalid input: validation failed', validationErrors?: any) {\n super(message, 'INVALID_INPUT', 400);\n this.validationErrors = validationErrors;\n }\n\n override getInternalMessage(): string {\n return this.message + (this.validationErrors ? `\\nDetails: ${JSON.stringify(this.validationErrors, null, 2)}` : '');\n }\n override getPublicMessage(): string {\n if (this.validationErrors) {\n return `${this.message}\\nDetails: ${JSON.stringify(this.validationErrors, null, 2)}`;\n }\n return this.message;\n }\n}\n\n/**\n * Invalid output validation error (internal - don't expose schema details)\n */\nexport class InvalidOutputError extends InternalMcpError {\n private readonly hasCustomErrorId: boolean;\n\n constructor(errorId?: string) {\n super('Tool output validation failed', 'INVALID_OUTPUT');\n this.hasCustomErrorId = !!errorId;\n if (errorId) {\n this.errorId = errorId;\n }\n }\n\n override getPublicMessage(): string {\n // If a custom errorId was provided (e.g., request ID), include it for correlation\n // Otherwise, use a simpler message since the auto-generated ID isn't meaningful to users\n if (this.hasCustomErrorId) {\n return `Output validation failed. Please contact support with error ID: ${this.errorId}`;\n }\n return 'Output validation failed. Please contact support.';\n }\n}\n\n/**\n * Invalid method error\n */\nexport class InvalidMethodError extends PublicMcpError {\n constructor(method: string, expected: string) {\n super(`Invalid method \"${method}\". Expected \"${expected}\"`, 'INVALID_METHOD', 400);\n }\n}\n\n/**\n * Tool execution error (internal)\n */\nexport class ToolExecutionError extends InternalMcpError {\n readonly originalError?: Error;\n\n constructor(toolName: string, originalError?: Error) {\n super(`Tool \"${toolName}\" execution failed: ${originalError?.message || 'Unknown error'}`, 'TOOL_EXECUTION_ERROR');\n this.originalError = originalError;\n }\n\n override getInternalMessage(): string {\n if (this.originalError?.stack) {\n return `${this.message}\\n\\nOriginal error:\\n${this.originalError.stack}`;\n }\n return this.message;\n }\n}\n\n/**\n * Rate limit error\n */\nexport class RateLimitError extends PublicMcpError {\n constructor(retryAfter?: number) {\n const message = retryAfter ? `Rate limit exceeded. Retry after ${retryAfter} seconds` : 'Rate limit exceeded';\n super(message, 'RATE_LIMIT_EXCEEDED', 429);\n }\n}\n\n/**\n * Quota exceeded error\n */\nexport class QuotaExceededError extends PublicMcpError {\n constructor(quotaType = 'usage') {\n super(`${quotaType} quota exceeded`, 'QUOTA_EXCEEDED', 429);\n }\n}\n\n/**\n * Unauthorized error\n */\nexport class UnauthorizedError extends PublicMcpError {\n constructor(message = 'Unauthorized') {\n super(message, 'UNAUTHORIZED', 401);\n }\n}\n\n/**\n * Generic server error wrapper\n */\nexport class GenericServerError extends InternalMcpError {\n readonly originalError?: Error;\n\n constructor(message: string, originalError?: Error) {\n super(message, 'SERVER_ERROR');\n this.originalError = originalError;\n }\n\n override getInternalMessage(): string {\n if (this.originalError?.stack) {\n return `${this.message}\\n\\nOriginal error:\\n${this.originalError.stack}`;\n }\n return this.message;\n }\n}\n\n// ============================================================================\n// Error Utilities\n// ============================================================================\n\n/**\n * Check if the error is a public error that can be safely shown to users\n */\nexport function isPublicError(error: any): error is PublicMcpError {\n return error instanceof McpError && error.isPublic;\n}\n\n/**\n * Convert any error to an MCP error\n */\nexport function toMcpError(error: any): McpError {\n if (error instanceof McpError) {\n return error;\n }\n\n if (error instanceof Error) {\n return new GenericServerError(error.message, error);\n }\n\n return new GenericServerError(String(error));\n}\n\n/**\n * Format error for MCP response\n */\nexport function formatMcpErrorResponse(error: any, isDevelopment: boolean = process.env['NODE_ENV'] !== 'production') {\n const mcpError = toMcpError(error);\n return mcpError.toMcpError(isDevelopment);\n}\n"]}
|
|
@@ -100,7 +100,10 @@ class FlowInstance extends common_1.FlowEntry {
|
|
|
100
100
|
let stages = (0, flow_stages_1.cloneStageMap)(baseStages);
|
|
101
101
|
// Compute next order base after any class-defined entries.
|
|
102
102
|
let orderBase = Math.max(0, ...Object.values(stages).flatMap((list) => list.map((e) => e._order ?? 0))) + 1;
|
|
103
|
-
|
|
103
|
+
// Get tool owner ID if this is a tool call flow
|
|
104
|
+
// The tool owner ID is set by the CallToolFlow.findTool stage
|
|
105
|
+
const toolOwnerId = input?._toolOwnerId;
|
|
106
|
+
const initialInjectedHooks = this.hooks.getFlowHooksForOwner(name, toolOwnerId) ?? [];
|
|
104
107
|
let context;
|
|
105
108
|
let contextReady = false;
|
|
106
109
|
const materializeAndMerge = async (newHooks, opts) => {
|
|
@@ -133,8 +136,7 @@ class FlowInstance extends common_1.FlowEntry {
|
|
|
133
136
|
// Initial registry hooks should not pre-empt stages; they just get registered
|
|
134
137
|
await materializeAndMerge(initialInjectedHooks, { orderStart: -1_000_000 });
|
|
135
138
|
// Refresh order base to be after everything currently present
|
|
136
|
-
orderBase =
|
|
137
|
-
Math.max(0, ...Object.values(stages).flatMap((list) => list.map((e) => e._order ?? 0))) + 1;
|
|
139
|
+
orderBase = Math.max(0, ...Object.values(stages).flatMap((list) => list.map((e) => e._order ?? 0))) + 1;
|
|
138
140
|
let responded;
|
|
139
141
|
// Robust list runner (doesn't skip mid-run insertions)
|
|
140
142
|
const runList = async (key, opts) => {
|
|
@@ -190,8 +192,7 @@ class FlowInstance extends common_1.FlowEntry {
|
|
|
190
192
|
bodyOutcome = res;
|
|
191
193
|
if (res.outcome !== 'ok' && res.outcome !== 'respond') {
|
|
192
194
|
// fail/abort/next/handled/unknown → do NOT run did
|
|
193
|
-
|
|
194
|
-
throw res.control;
|
|
195
|
+
return res;
|
|
195
196
|
}
|
|
196
197
|
}
|
|
197
198
|
// 4) didStage (run once regardless of body respond)
|
|
@@ -227,7 +228,7 @@ class FlowInstance extends common_1.FlowEntry {
|
|
|
227
228
|
// else keep going
|
|
228
229
|
}
|
|
229
230
|
else if (res.outcome !== 'ok') {
|
|
230
|
-
return res
|
|
231
|
+
return res;
|
|
231
232
|
}
|
|
232
233
|
}
|
|
233
234
|
return { outcome: 'ok' };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"flow.instance.js","sourceRoot":"","sources":["../../../src/flows/flow.instance.ts"],"names":[],"mappings":"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","sourcesContent":["// noinspection ExceptionCaughtLocallyJS\n// flows/flow.instance.ts\n\nimport 'reflect-metadata';\nimport {\n FlowControl,\n FlowCtxOf,\n FlowEntry,\n FlowInputOf,\n FlowName,\n FlowOutputOf,\n FlowPlan,\n FlowRecord,\n FlowStagesOf,\n FlowType,\n HookEntry,\n HookMetadata,\n Reference,\n ServerRequest,\n Token,\n Type,\n} from '../common';\nimport ProviderRegistry from '../provider/provider.registry';\nimport {\n collectFlowHookMap,\n StageMap,\n cloneStageMap,\n mergeHookMetasIntoStageMap,\n} from './flow.stages';\nimport {writeHttpResponse} from '../server/server.validation';\nimport {Scope} from '../scope';\nimport HookRegistry from '../hooks/hook.registry';\nimport {rpcError} from \"../transport/transport.error\";\n\ntype StageOutcome =\n | 'ok'\n | 'respond'\n | 'next'\n | 'handled'\n | 'fail'\n | 'abort'\n | 'unknown_error';\n\ninterface StageResult {\n outcome: StageOutcome;\n control?: FlowControl | Error;\n}\n\nconst CAP = (s: string) => (s ? s[0].toUpperCase() + s.slice(1) : s);\nconst WILL = (s: string) => `will${CAP(s)}`;\nconst DID = (s: string) => `did${CAP(s)}`;\nconst AROUND = (s: string) => `around${CAP(s)}`;\n\nfunction parseTypedKey(k: string): { base: string; type?: 'will' | 'did' | 'around' } {\n const lc = k.toLowerCase();\n if (lc.startsWith('will') && k.length > 4) return {base: k.slice(4, 5).toLowerCase() + k.slice(5), type: 'will'};\n if (lc.startsWith('did') && k.length > 3) return {base: k.slice(3, 4).toLowerCase() + k.slice(4), type: 'did'};\n if (lc.startsWith('around') && k.length > 6) return {base: k.slice(6, 7).toLowerCase() + k.slice(7), type: 'around'};\n return {base: k};\n}\n\nexport class FlowInstance<Name extends FlowName> extends FlowEntry<Name> {\n readonly deps: Reference[];\n readonly globalProviders: ProviderRegistry;\n private plan: FlowPlan<never>;\n private FlowClass: FlowType;\n private stages: StageMap<FlowType>;\n private hooks: HookRegistry;\n\n constructor(\n scope: Scope,\n record: FlowRecord,\n deps: Set<Reference>,\n globalProviders: ProviderRegistry,\n ) {\n super(scope, record);\n this.deps = [...deps];\n this.globalProviders = globalProviders;\n this.FlowClass = this.record.provide;\n this.ready = this.initialize();\n this.plan = this.record.metadata.plan;\n this.hooks = scope.providers.getHooksRegistry();\n }\n\n protected async initialize() {\n const server = this.globalProviders.getActiveServer();\n\n this.stages = collectFlowHookMap(this.FlowClass);\n\n const {middleware} = this.metadata;\n if (middleware) {\n const path = typeof middleware.path === 'string' ? middleware.path : '';\n server.registerMiddleware(path, async (request, response, next) => {\n const canActivate = await this.canActivate(request);\n if (!canActivate) return next();\n\n try {\n const result = await this.run(\n {request, response, next} as any,\n new Map(),\n );\n if (result) return writeHttpResponse(response, result);\n } catch (e) {\n if (e instanceof FlowControl) {\n switch (e.type) {\n case 'abort':\n return writeHttpResponse(response, {kind: 'text', status: 500, body: 'Aborted'});\n case 'fail':\n return writeHttpResponse(response, {kind: 'text', status: 500, body: 'Internal Server Error'});\n case 'handled':\n return;\n case 'next':\n return next();\n case 'respond':\n return writeHttpResponse(response, e.output as any);\n }\n }\n // eslint-disable-next-line no-console\n console.error(e);\n return writeHttpResponse(response, {\n kind: 'text',\n status: 500,\n body: 'Internal Server Error',\n });\n }\n\n return next();\n });\n }\n\n return Promise.resolve();\n }\n\n async canActivate(request: ServerRequest): Promise<boolean> {\n if (this.method && request.method !== this.method) return false;\n\n const canActivate = this.metadata.middleware?.canActivate ?? [];\n if ((this.FlowClass as any)['canActivate']) {\n canActivate.push((this.FlowClass as any)['canActivate']);\n }\n if (canActivate.length === 0) return true;\n\n const results = await Promise.all(canActivate.map((m) => m(request, this.scope)));\n return results.every((r) => r);\n }\n\n async run(\n input: FlowInputOf<Name>,\n deps: Map<Token, Type>,\n ): Promise<FlowOutputOf<Name> | undefined> {\n const scope = this.globalProviders.getActiveScope();\n const {FlowClass, plan, name} = this;\n\n // Clone stages so we can merge injections safely per run.\n const baseStages = this.stages;\n let stages: StageMap<any> = cloneStageMap(baseStages);\n\n // Compute next order base after any class-defined entries.\n let orderBase =\n Math.max(\n 0,\n ...Object.values(stages).flatMap((list) => list.map((e: any) => e._order ?? 0)),\n ) + 1;\n\n const initialInjectedHooks =\n (this.hooks.getFlowHooks(name) as HookEntry<\n FlowInputOf<Name>,\n Name,\n FlowStagesOf<Name>,\n FlowCtxOf<Name>\n >[]) ?? [];\n\n let context: any;\n let contextReady = false;\n\n const materializeAndMerge = async (\n newHooks: HookEntry<FlowInputOf<Name>, Name, FlowStagesOf<Name>, FlowCtxOf<Name>>[],\n opts?: { orderStart?: number },\n ) => {\n if (!newHooks?.length || !contextReady) return;\n\n const metas: HookMetadata[] = [];\n for (const h of newHooks) {\n try {\n metas.push(h.metadata);\n } catch (e) {\n // eslint-disable-next-line no-console\n console.warn('[flow] Ignoring injected hook that failed to materialize:', e);\n }\n }\n\n if (metas.length) {\n const start = opts?.orderStart ?? orderBase;\n mergeHookMetasIntoStageMap(FlowClass, stages, metas, start);\n if (opts?.orderStart === undefined) orderBase += metas.length;\n }\n };\n\n const appendContextHooks = async (\n hooks: HookEntry<FlowInputOf<Name>, Name, FlowStagesOf<Name>, FlowCtxOf<Name>>[],\n ) => {\n await materializeAndMerge(hooks);\n };\n\n // Construct flow instance\n context = new FlowClass(this.metadata, input, scope, appendContextHooks, deps);\n\n // Now injections can materialize\n contextReady = true;\n\n // Initial registry hooks should not pre-empt stages; they just get registered\n await materializeAndMerge(initialInjectedHooks, {orderStart: -1_000_000});\n\n // Refresh order base to be after everything currently present\n orderBase =\n Math.max(\n 0,\n ...Object.values(stages).flatMap((list) => list.map((e: any) => e._order ?? 0)),\n ) + 1;\n\n let responded: FlowOutputOf<Name> | undefined;\n\n // Robust list runner (doesn't skip mid-run insertions)\n const runList = async (\n key: string,\n opts?: { ignoreRespond?: boolean },\n ): Promise<StageResult> => {\n const getList = () => ((stages as any)[key] ?? []) as Array<{ method: (ctx: any) => Promise<void> }>;\n const seen = new Set<any>();\n\n while (true) {\n const list = getList();\n const item = list.find((e) => !seen.has(e));\n if (!item) break;\n seen.add(item);\n\n try {\n await item.method(context);\n } catch (e: any) {\n if (e instanceof FlowControl) {\n if (e.type === 'respond') {\n if (!opts?.ignoreRespond) {\n responded = e.output as FlowOutputOf<Name>;\n return {outcome: 'respond', control: e};\n }\n continue;\n }\n return {outcome: e.type, control: e};\n }\n return {outcome: 'unknown_error', control: e as Error};\n }\n }\n return {outcome: 'ok'};\n };\n\n // Run exactly one stage in order: will → around → stage → did (did runs once)\n const runOneStage = async (\n stageName: string,\n stopOnRespond: boolean,\n ): Promise<StageResult> => {\n // 1) willStage\n {\n const res = await runList(WILL(stageName));\n if (res.outcome === 'respond' && stopOnRespond) return res;\n if (res.outcome !== 'ok' && res.outcome !== 'respond') return res;\n }\n\n // 2) aroundStage (acts as pre-handlers unless you later add true wrapping)\n {\n const res = await runList(AROUND(stageName));\n if (res.outcome === 'respond' && stopOnRespond) return res;\n if (res.outcome !== 'ok' && res.outcome !== 'respond') return res;\n }\n\n // 3) stage\n let bodyOutcome: StageResult = {outcome: 'ok'};\n {\n const res = await runList(stageName, {ignoreRespond: false});\n bodyOutcome = res;\n if (res.outcome !== 'ok' && res.outcome !== 'respond') {\n // fail/abort/next/handled/unknown → do NOT run did\n // return res;/\n throw res.control\n }\n }\n\n // 4) didStage (run once regardless of body respond)\n {\n const res = await runList(DID(stageName), {ignoreRespond: true});\n if (res.outcome !== 'ok' && res.outcome !== 'respond') return res;\n }\n\n if (bodyOutcome.outcome === 'respond') return bodyOutcome;\n return {outcome: 'ok'};\n };\n\n // IMPORTANT: ignore typed stage names in plan arrays.\n // Only base stage names in the plan drive execution; typed hooks run *with* their base.\n const runStageGroup = async (\n group: Array<string> | undefined,\n stopOnRespond: boolean,\n opts?: { ignoreRespond?: boolean },\n ): Promise<StageResult> => {\n if (!group || group.length === 0) return {outcome: 'ok'};\n\n const seenBase = new Set<string>();\n for (const rawKey of group) {\n const {base, type} = parseTypedKey(rawKey);\n if (type) {\n // Soft warning once per typed key occurrence (optional)\n // console.warn(`[flow] Ignoring typed stage \"${rawKey}\" in plan; hooks will run with base \"${base}\".`);\n continue; // Do not run typed keys as standalone stages\n }\n if (seenBase.has(base)) continue;\n seenBase.add(base);\n\n const res = await runOneStage(base, stopOnRespond);\n if (res.outcome === 'respond') {\n if (stopOnRespond) return res;\n // else keep going\n } else if (res.outcome !== 'ok') {\n return res.control?.['output'] ?? res.outcome;\n }\n }\n return {outcome: 'ok'};\n };\n\n const runErrorStage = async () => {\n await runStageGroup((plan as any).error, false, {ignoreRespond: true});\n };\n\n const runFinalizeStage = async () => {\n await runStageGroup((plan as any).finalize, false);\n };\n\n try {\n // ---------- PRE ----------\n {\n const pre = await runStageGroup((plan as any).pre, true);\n if (pre.outcome === 'respond') {\n const post = await runStageGroup((plan as any).post, false);\n if (post.outcome === 'unknown_error' || post.outcome === 'fail') {\n try {\n await runErrorStage();\n } finally {\n await runFinalizeStage();\n }\n if (post.outcome === 'fail') throw post.control!;\n throw post.control!;\n }\n if (post.outcome === 'abort' || post.outcome === 'next' || post.outcome === 'handled') {\n await runFinalizeStage();\n throw post.control as FlowControl;\n }\n await runFinalizeStage();\n return responded;\n }\n if (pre.outcome === 'unknown_error' || pre.outcome === 'fail') {\n try {\n await runErrorStage();\n } finally {\n await runFinalizeStage();\n }\n if (pre.outcome === 'fail') throw pre.control!;\n throw pre.control!;\n }\n if (pre.outcome === 'abort' || pre.outcome === 'next' || pre.outcome === 'handled') {\n await runFinalizeStage();\n throw pre.control as FlowControl;\n }\n }\n\n // ---------- EXECUTE ----------\n if (!responded) {\n const exec = await runStageGroup((plan as any).execute, true);\n if (exec.outcome === 'respond') {\n // continue to post + finalize\n } else if (exec.outcome === 'unknown_error' || exec.outcome === 'fail') {\n try {\n await runErrorStage();\n } finally {\n await runFinalizeStage();\n }\n if (exec.outcome === 'fail') throw exec.control!;\n throw exec.control!;\n } else if (exec.outcome === 'abort' || exec.outcome === 'next' || exec.outcome === 'handled') {\n await runFinalizeStage();\n throw exec.control as FlowControl;\n }\n }\n\n // ---------- POST ----------\n {\n const post = await runStageGroup((plan as any).post, false);\n if (post.outcome === 'unknown_error' || post.outcome === 'fail') {\n try {\n await runErrorStage();\n } finally {\n await runFinalizeStage();\n }\n if (post.outcome === 'fail') throw post.control!;\n throw post.control!;\n }\n if (post.outcome === 'abort' || post.outcome === 'next' || post.outcome === 'handled') {\n await runFinalizeStage();\n throw post.control as FlowControl;\n }\n }\n\n // ---------- FINALIZE ----------\n await runFinalizeStage();\n\n return responded;\n } catch (e) {\n throw e;\n }\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"flow.instance.js","sourceRoot":"","sources":["../../../src/flows/flow.instance.ts"],"names":[],"mappings":"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","sourcesContent":["// noinspection ExceptionCaughtLocallyJS\n// flows/flow.instance.ts\n\nimport 'reflect-metadata';\nimport {\n FlowControl,\n FlowCtxOf,\n FlowEntry,\n FlowInputOf,\n FlowName,\n FlowOutputOf,\n FlowPlan,\n FlowRecord,\n FlowStagesOf,\n FlowType,\n HookEntry,\n HookMetadata,\n Reference,\n ServerRequest,\n Token,\n Type,\n} from '../common';\nimport ProviderRegistry from '../provider/provider.registry';\nimport { collectFlowHookMap, StageMap, cloneStageMap, mergeHookMetasIntoStageMap } from './flow.stages';\nimport { writeHttpResponse } from '../server/server.validation';\nimport { Scope } from '../scope';\nimport HookRegistry from '../hooks/hook.registry';\nimport { rpcError } from '../transport/transport.error';\n\ntype StageOutcome = 'ok' | 'respond' | 'next' | 'handled' | 'fail' | 'abort' | 'unknown_error';\n\ninterface StageResult {\n outcome: StageOutcome;\n control?: FlowControl | Error;\n}\n\nconst CAP = (s: string) => (s ? s[0].toUpperCase() + s.slice(1) : s);\nconst WILL = (s: string) => `will${CAP(s)}`;\nconst DID = (s: string) => `did${CAP(s)}`;\nconst AROUND = (s: string) => `around${CAP(s)}`;\n\nfunction parseTypedKey(k: string): { base: string; type?: 'will' | 'did' | 'around' } {\n const lc = k.toLowerCase();\n if (lc.startsWith('will') && k.length > 4) return { base: k.slice(4, 5).toLowerCase() + k.slice(5), type: 'will' };\n if (lc.startsWith('did') && k.length > 3) return { base: k.slice(3, 4).toLowerCase() + k.slice(4), type: 'did' };\n if (lc.startsWith('around') && k.length > 6)\n return { base: k.slice(6, 7).toLowerCase() + k.slice(7), type: 'around' };\n return { base: k };\n}\n\nexport class FlowInstance<Name extends FlowName> extends FlowEntry<Name> {\n readonly deps: Reference[];\n readonly globalProviders: ProviderRegistry;\n private plan: FlowPlan<never>;\n private FlowClass: FlowType;\n private stages: StageMap<FlowType>;\n private hooks: HookRegistry;\n\n constructor(scope: Scope, record: FlowRecord, deps: Set<Reference>, globalProviders: ProviderRegistry) {\n super(scope, record);\n this.deps = [...deps];\n this.globalProviders = globalProviders;\n this.FlowClass = this.record.provide;\n this.ready = this.initialize();\n this.plan = this.record.metadata.plan;\n this.hooks = scope.providers.getHooksRegistry();\n }\n\n protected async initialize() {\n const server = this.globalProviders.getActiveServer();\n\n this.stages = collectFlowHookMap(this.FlowClass);\n\n const { middleware } = this.metadata;\n if (middleware) {\n const path = typeof middleware.path === 'string' ? middleware.path : '';\n server.registerMiddleware(path, async (request, response, next) => {\n const canActivate = await this.canActivate(request);\n if (!canActivate) return next();\n\n try {\n const result = await this.run({ request, response, next } as any, new Map());\n if (result) return writeHttpResponse(response, result);\n } catch (e) {\n if (e instanceof FlowControl) {\n switch (e.type) {\n case 'abort':\n return writeHttpResponse(response, { kind: 'text', status: 500, body: 'Aborted' });\n case 'fail':\n return writeHttpResponse(response, { kind: 'text', status: 500, body: 'Internal Server Error' });\n case 'handled':\n return;\n case 'next':\n return next();\n case 'respond':\n return writeHttpResponse(response, e.output as any);\n }\n }\n // eslint-disable-next-line no-console\n console.error(e);\n return writeHttpResponse(response, {\n kind: 'text',\n status: 500,\n body: 'Internal Server Error',\n });\n }\n\n return next();\n });\n }\n\n return Promise.resolve();\n }\n\n async canActivate(request: ServerRequest): Promise<boolean> {\n if (this.method && request.method !== this.method) return false;\n\n const canActivate = this.metadata.middleware?.canActivate ?? [];\n if ((this.FlowClass as any)['canActivate']) {\n canActivate.push((this.FlowClass as any)['canActivate']);\n }\n if (canActivate.length === 0) return true;\n\n const results = await Promise.all(canActivate.map((m) => m(request, this.scope)));\n return results.every((r) => r);\n }\n\n async run(input: FlowInputOf<Name>, deps: Map<Token, Type>): Promise<FlowOutputOf<Name> | undefined> {\n const scope = this.globalProviders.getActiveScope();\n const { FlowClass, plan, name } = this;\n\n // Clone stages so we can merge injections safely per run.\n const baseStages = this.stages;\n let stages: StageMap<any> = cloneStageMap(baseStages);\n\n // Compute next order base after any class-defined entries.\n let orderBase = Math.max(0, ...Object.values(stages).flatMap((list) => list.map((e: any) => e._order ?? 0))) + 1;\n\n // Get tool owner ID if this is a tool call flow\n // The tool owner ID is set by the CallToolFlow.findTool stage\n const toolOwnerId = (input as any)?._toolOwnerId;\n\n const initialInjectedHooks =\n (this.hooks.getFlowHooksForOwner(name, toolOwnerId) as HookEntry<\n FlowInputOf<Name>,\n Name,\n FlowStagesOf<Name>,\n FlowCtxOf<Name>\n >[]) ?? [];\n\n let context: any;\n let contextReady = false;\n\n const materializeAndMerge = async (\n newHooks: HookEntry<FlowInputOf<Name>, Name, FlowStagesOf<Name>, FlowCtxOf<Name>>[],\n opts?: { orderStart?: number },\n ) => {\n if (!newHooks?.length || !contextReady) return;\n\n const metas: HookMetadata[] = [];\n for (const h of newHooks) {\n try {\n metas.push(h.metadata);\n } catch (e) {\n // eslint-disable-next-line no-console\n console.warn('[flow] Ignoring injected hook that failed to materialize:', e);\n }\n }\n\n if (metas.length) {\n const start = opts?.orderStart ?? orderBase;\n mergeHookMetasIntoStageMap(FlowClass, stages, metas, start);\n if (opts?.orderStart === undefined) orderBase += metas.length;\n }\n };\n\n const appendContextHooks = async (\n hooks: HookEntry<FlowInputOf<Name>, Name, FlowStagesOf<Name>, FlowCtxOf<Name>>[],\n ) => {\n await materializeAndMerge(hooks);\n };\n\n // Construct flow instance\n context = new FlowClass(this.metadata, input, scope, appendContextHooks, deps);\n\n // Now injections can materialize\n contextReady = true;\n\n // Initial registry hooks should not pre-empt stages; they just get registered\n await materializeAndMerge(initialInjectedHooks, { orderStart: -1_000_000 });\n\n // Refresh order base to be after everything currently present\n orderBase = Math.max(0, ...Object.values(stages).flatMap((list) => list.map((e: any) => e._order ?? 0))) + 1;\n\n let responded: FlowOutputOf<Name> | undefined;\n\n // Robust list runner (doesn't skip mid-run insertions)\n const runList = async (key: string, opts?: { ignoreRespond?: boolean }): Promise<StageResult> => {\n const getList = () => ((stages as any)[key] ?? []) as Array<{ method: (ctx: any) => Promise<void> }>;\n const seen = new Set<any>();\n\n while (true) {\n const list = getList();\n const item = list.find((e) => !seen.has(e));\n if (!item) break;\n seen.add(item);\n\n try {\n await item.method(context);\n } catch (e: any) {\n if (e instanceof FlowControl) {\n if (e.type === 'respond') {\n if (!opts?.ignoreRespond) {\n responded = e.output as FlowOutputOf<Name>;\n return { outcome: 'respond', control: e };\n }\n continue;\n }\n return { outcome: e.type, control: e };\n }\n return { outcome: 'unknown_error', control: e as Error };\n }\n }\n return { outcome: 'ok' };\n };\n\n // Run exactly one stage in order: will → around → stage → did (did runs once)\n const runOneStage = async (stageName: string, stopOnRespond: boolean): Promise<StageResult> => {\n // 1) willStage\n {\n const res = await runList(WILL(stageName));\n if (res.outcome === 'respond' && stopOnRespond) return res;\n if (res.outcome !== 'ok' && res.outcome !== 'respond') return res;\n }\n\n // 2) aroundStage (acts as pre-handlers unless you later add true wrapping)\n {\n const res = await runList(AROUND(stageName));\n if (res.outcome === 'respond' && stopOnRespond) return res;\n if (res.outcome !== 'ok' && res.outcome !== 'respond') return res;\n }\n\n // 3) stage\n let bodyOutcome: StageResult = { outcome: 'ok' };\n {\n const res = await runList(stageName, { ignoreRespond: false });\n bodyOutcome = res;\n if (res.outcome !== 'ok' && res.outcome !== 'respond') {\n // fail/abort/next/handled/unknown → do NOT run did\n return res;\n }\n }\n\n // 4) didStage (run once regardless of body respond)\n {\n const res = await runList(DID(stageName), { ignoreRespond: true });\n if (res.outcome !== 'ok' && res.outcome !== 'respond') return res;\n }\n\n if (bodyOutcome.outcome === 'respond') return bodyOutcome;\n return { outcome: 'ok' };\n };\n\n // IMPORTANT: ignore typed stage names in plan arrays.\n // Only base stage names in the plan drive execution; typed hooks run *with* their base.\n const runStageGroup = async (\n group: Array<string> | undefined,\n stopOnRespond: boolean,\n opts?: { ignoreRespond?: boolean },\n ): Promise<StageResult> => {\n if (!group || group.length === 0) return { outcome: 'ok' };\n\n const seenBase = new Set<string>();\n for (const rawKey of group) {\n const { base, type } = parseTypedKey(rawKey);\n if (type) {\n // Soft warning once per typed key occurrence (optional)\n // console.warn(`[flow] Ignoring typed stage \"${rawKey}\" in plan; hooks will run with base \"${base}\".`);\n continue; // Do not run typed keys as standalone stages\n }\n if (seenBase.has(base)) continue;\n seenBase.add(base);\n\n const res = await runOneStage(base, stopOnRespond);\n if (res.outcome === 'respond') {\n if (stopOnRespond) return res;\n // else keep going\n } else if (res.outcome !== 'ok') {\n return res;\n }\n }\n return { outcome: 'ok' };\n };\n\n const runErrorStage = async () => {\n await runStageGroup((plan as any).error, false, { ignoreRespond: true });\n };\n\n const runFinalizeStage = async () => {\n await runStageGroup((plan as any).finalize, false);\n };\n\n try {\n // ---------- PRE ----------\n {\n const pre = await runStageGroup((plan as any).pre, true);\n if (pre.outcome === 'respond') {\n const post = await runStageGroup((plan as any).post, false);\n if (post.outcome === 'unknown_error' || post.outcome === 'fail') {\n try {\n await runErrorStage();\n } finally {\n await runFinalizeStage();\n }\n if (post.outcome === 'fail') throw post.control!;\n throw post.control!;\n }\n if (post.outcome === 'abort' || post.outcome === 'next' || post.outcome === 'handled') {\n await runFinalizeStage();\n throw post.control as FlowControl;\n }\n await runFinalizeStage();\n return responded;\n }\n if (pre.outcome === 'unknown_error' || pre.outcome === 'fail') {\n try {\n await runErrorStage();\n } finally {\n await runFinalizeStage();\n }\n if (pre.outcome === 'fail') throw pre.control!;\n throw pre.control!;\n }\n if (pre.outcome === 'abort' || pre.outcome === 'next' || pre.outcome === 'handled') {\n await runFinalizeStage();\n throw pre.control as FlowControl;\n }\n }\n\n // ---------- EXECUTE ----------\n if (!responded) {\n const exec = await runStageGroup((plan as any).execute, true);\n if (exec.outcome === 'respond') {\n // continue to post + finalize\n } else if (exec.outcome === 'unknown_error' || exec.outcome === 'fail') {\n try {\n await runErrorStage();\n } finally {\n await runFinalizeStage();\n }\n if (exec.outcome === 'fail') throw exec.control!;\n throw exec.control!;\n } else if (exec.outcome === 'abort' || exec.outcome === 'next' || exec.outcome === 'handled') {\n await runFinalizeStage();\n throw exec.control as FlowControl;\n }\n }\n\n // ---------- POST ----------\n {\n const post = await runStageGroup((plan as any).post, false);\n if (post.outcome === 'unknown_error' || post.outcome === 'fail') {\n try {\n await runErrorStage();\n } finally {\n await runFinalizeStage();\n }\n if (post.outcome === 'fail') throw post.control!;\n throw post.control!;\n }\n if (post.outcome === 'abort' || post.outcome === 'next' || post.outcome === 'handled') {\n await runFinalizeStage();\n throw post.control as FlowControl;\n }\n }\n\n // ---------- FINALIZE ----------\n await runFinalizeStage();\n\n return responded;\n } catch (e) {\n throw e;\n }\n }\n}\n"]}
|
|
@@ -32,7 +32,7 @@ class FlowRegistry extends regsitry_1.RegistryAbstract {
|
|
|
32
32
|
}
|
|
33
33
|
else {
|
|
34
34
|
if (!this.providers.get(d)) {
|
|
35
|
-
throw new Error(`
|
|
35
|
+
throw new Error(`Flow ${(0, token_utils_1.tokenName)(token)} depends on ${(0, token_utils_1.tokenName)(d)}, which is not registered.`);
|
|
36
36
|
}
|
|
37
37
|
this.graph.get(token).add(d);
|
|
38
38
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"flow.registry.js","sourceRoot":"","sources":["../../../src/flows/flow.registry.ts"],"names":[],"mappings":";;AACA,0CAAuE;AACvE,sCAA+G;AAC/G,6CAA6C;AAC7C,sDAAiD;AACjD,mDAA+C;AAE/C,MAAqB,YAAa,SAAQ,2BAAgE;IACxG,YAAY,SAA2B,EAAE,IAAgB;QACvD,KAAK,CAAC,cAAc,EAAE,SAAS,EAAE,IAAI,CAAC,CAAC;IACzC,CAAC;IAEkB,QAAQ,CAAC,IAAgB;QAC1C,MAAM,MAAM,GAAG,IAAI,GAAG,EAAS,CAAC;QAChC,MAAM,IAAI,GAAG,IAAI,GAAG,EAAqB,CAAC;QAC1C,MAAM,KAAK,GAAG,IAAI,GAAG,EAAqB,CAAC;QAE3C,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;YACvB,MAAM,GAAG,GAAG,IAAA,0BAAa,EAAC,GAAG,CAAC,CAAC;YAC/B,MAAM,OAAO,GAAG,GAAG,CAAC,OAAO,CAAC;YAC5B,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;YACpB,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;YACvB,KAAK,CAAC,GAAG,CAAC,OAAO,EAAE,IAAI,GAAG,EAAE,CAAC,CAAC;QAChC,CAAC;QAED,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;IACjC,CAAC;IAGS,UAAU;QAClB,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChC,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAE,CAAC;YAClC,MAAM,IAAI,GAAG,GAAG,CAAC,QAAQ,CAAC,SAAS,IAAI,EAAE,CAAC;YAE1C,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;gBACrB,IAAI,CAAC,IAAI,mBAAU,EAAE,CAAC;oBACpB,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAE,CAAC,GAAG,CAAC,mBAAU,CAAC,CAAC;gBACzC,CAAC;qBAAM,CAAC;oBACN,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;wBAC3B,MAAM,IAAI,KAAK,CAAC,
|
|
1
|
+
{"version":3,"file":"flow.registry.js","sourceRoot":"","sources":["../../../src/flows/flow.registry.ts"],"names":[],"mappings":"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","sourcesContent":["import ProviderRegistry from '../provider/provider.registry';\nimport { RegistryAbstract, RegistryBuildMapResult } from '../regsitry';\nimport { FlowInputOf, FlowName, FlowOutputOf, FlowRecord, FlowType, ScopeEntry, Token, Type } from '../common';\nimport { normalizeFlow } from './flow.utils';\nimport { tokenName } from '../utils/token.utils';\nimport { FlowInstance } from './flow.instance';\n\nexport default class FlowRegistry extends RegistryAbstract<FlowInstance<FlowName>, FlowRecord, FlowType[]> {\n constructor(providers: ProviderRegistry, list: FlowType[]) {\n super('FlowRegistry', providers, list);\n }\n\n protected override buildMap(list: FlowType[]): RegistryBuildMapResult<FlowRecord> {\n const tokens = new Set<Token>();\n const defs = new Map<Token, FlowRecord>();\n const graph = new Map<Token, Set<Token>>();\n\n for (const raw of list) {\n const rec = normalizeFlow(raw);\n const provide = rec.provide;\n tokens.add(provide);\n defs.set(provide, rec);\n graph.set(provide, new Set());\n }\n\n return { tokens, defs, graph };\n }\n\n\n protected buildGraph() {\n for (const token of this.tokens) {\n const rec = this.defs.get(token)!;\n const deps = rec.metadata.dependsOn ?? [];\n\n for (const d of deps) {\n if (d == ScopeEntry) {\n this.graph.get(token)!.add(ScopeEntry);\n } else {\n if (!this.providers.get(d)) {\n throw new Error(`Flow ${tokenName(token)} depends on ${tokenName(d)}, which is not registered.`);\n }\n this.graph.get(token)!.add(d);\n }\n }\n }\n }\n\n /** Instantiate adapters, run fetch/transform, and populate registries. */\n protected async initialize(): Promise<void> {\n\n const readyArr: Promise<void>[] = [];\n for (const token of this.tokens) {\n const instance = this.initializeOne(token);\n readyArr.push(instance.ready);\n }\n await Promise.all(readyArr);\n }\n\n private initializeOne(token: Token) {\n const rec = this.defs.get(token)!;\n const deps = this.graph.get(token)!;\n\n const instance = new FlowInstance(this.providers.getActiveScope(), rec, deps, this.providers);\n this.instances.set(rec.metadata.name, instance);\n return instance;\n }\n\n\n async registryFlows(rawFlows: FlowType[]): Promise<void> {\n const readyArr: Promise<void>[] = [];\n for (const raw of rawFlows) {\n const rec = normalizeFlow(raw);\n const provide = rec.provide;\n this.tokens.add(provide);\n this.defs.set(provide, rec);\n this.graph.set(provide, new Set());\n readyArr.push(this.initializeOne(provide).ready);\n }\n await Promise.all(readyArr);\n }\n\n\n runFlow<Name extends FlowName>(name: Name, input: FlowInputOf<Name>, deps?: Map<Token, Type>): Promise<FlowOutputOf<Name> | undefined> {\n const flow = this.instances.get(name);\n if (!flow) {\n throw new Error(`Flow ${name} is not registered`);\n }\n return flow.run(input, deps ?? new Map());\n }\n}\n"]}
|
|
@@ -5,11 +5,11 @@ export declare function createMcpGlobalProviders(metadata: FrontMcpConfigType):
|
|
|
5
5
|
name: string;
|
|
6
6
|
version: string;
|
|
7
7
|
title?: string | undefined;
|
|
8
|
-
icons?:
|
|
9
|
-
src:
|
|
10
|
-
mimeType
|
|
11
|
-
sizes
|
|
12
|
-
}
|
|
8
|
+
icons?: {
|
|
9
|
+
src: string;
|
|
10
|
+
mimeType?: string | undefined;
|
|
11
|
+
sizes?: string[] | undefined;
|
|
12
|
+
}[] | undefined;
|
|
13
13
|
websiteUrl?: string | undefined;
|
|
14
14
|
};
|
|
15
15
|
apps: import("../common").Type<unknown>[];
|
|
@@ -71,11 +71,11 @@ export declare function createMcpGlobalProviders(metadata: FrontMcpConfigType):
|
|
|
71
71
|
name: string;
|
|
72
72
|
version: string;
|
|
73
73
|
title?: string | undefined;
|
|
74
|
-
icons?:
|
|
75
|
-
src:
|
|
76
|
-
mimeType
|
|
77
|
-
sizes
|
|
78
|
-
}
|
|
74
|
+
icons?: {
|
|
75
|
+
src: string;
|
|
76
|
+
mimeType?: string | undefined;
|
|
77
|
+
sizes?: string[] | undefined;
|
|
78
|
+
}[] | undefined;
|
|
79
79
|
websiteUrl?: string | undefined;
|
|
80
80
|
};
|
|
81
81
|
apps: import("../common").Type<unknown>[];
|
|
@@ -103,11 +103,11 @@ export declare function createMcpGlobalProviders(metadata: FrontMcpConfigType):
|
|
|
103
103
|
name: string;
|
|
104
104
|
version: string;
|
|
105
105
|
title?: string | undefined;
|
|
106
|
-
icons?:
|
|
107
|
-
src:
|
|
108
|
-
mimeType
|
|
109
|
-
sizes
|
|
110
|
-
}
|
|
106
|
+
icons?: {
|
|
107
|
+
src: string;
|
|
108
|
+
mimeType?: string | undefined;
|
|
109
|
+
sizes?: string[] | undefined;
|
|
110
|
+
}[] | undefined;
|
|
111
111
|
websiteUrl?: string | undefined;
|
|
112
112
|
};
|
|
113
113
|
apps: import("../common").Type<unknown>[];
|
|
@@ -169,11 +169,11 @@ export declare function createMcpGlobalProviders(metadata: FrontMcpConfigType):
|
|
|
169
169
|
name: string;
|
|
170
170
|
version: string;
|
|
171
171
|
title?: string | undefined;
|
|
172
|
-
icons?:
|
|
173
|
-
src:
|
|
174
|
-
mimeType
|
|
175
|
-
sizes
|
|
176
|
-
}
|
|
172
|
+
icons?: {
|
|
173
|
+
src: string;
|
|
174
|
+
mimeType?: string | undefined;
|
|
175
|
+
sizes?: string[] | undefined;
|
|
176
|
+
}[] | undefined;
|
|
177
177
|
websiteUrl?: string | undefined;
|
|
178
178
|
};
|
|
179
179
|
apps: import("../common").Type<unknown>[];
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { FlowCtxOf, FlowInputOf, FlowName, FlowStagesOf, HookEntry, HookRecord, HookRegistryInterface, HookType, ScopeEntry, Token } from
|
|
2
|
-
import { RegistryAbstract, RegistryBuildMapResult } from
|
|
3
|
-
import ProviderRegistry from
|
|
1
|
+
import { FlowCtxOf, FlowInputOf, FlowName, FlowStagesOf, HookEntry, HookRecord, HookRegistryInterface, HookType, ScopeEntry, Token } from '../common';
|
|
2
|
+
import { RegistryAbstract, RegistryBuildMapResult } from '../regsitry';
|
|
3
|
+
import ProviderRegistry from '../provider/provider.registry';
|
|
4
4
|
export default class HookRegistry extends RegistryAbstract<HookEntry, HookRecord, HookType[]> implements HookRegistryInterface {
|
|
5
5
|
scope: ScopeEntry;
|
|
6
6
|
/** Historical records by class (kept if you still want access to raw records) */
|
|
@@ -23,6 +23,8 @@ export default class HookRegistry extends RegistryAbstract<HookEntry, HookRecord
|
|
|
23
23
|
private indexByFlowStage;
|
|
24
24
|
private initializeOne;
|
|
25
25
|
registerHooks(embedded: boolean, ...records: HookRecord[]): Promise<void[]>;
|
|
26
|
+
/** Hooks for a given *flow*, filtered by owner if provided, sorted by priority (desc). */
|
|
27
|
+
getFlowHooksForOwner<Name extends FlowName>(flow: Name, ownerId?: string): HookEntry<FlowInputOf<Name>, Name, FlowStagesOf<Name>, FlowCtxOf<Name>>[];
|
|
26
28
|
/** Hooks defined on a given *class* (metadata.target), sorted by priority (desc). */
|
|
27
29
|
getClsHooks(token: Token): HookEntry[];
|
|
28
30
|
/** All hooks (instances, unordered) */
|
|
@@ -12,7 +12,7 @@ class HookRegistry extends regsitry_1.RegistryAbstract {
|
|
|
12
12
|
hooksByFlow = new Map();
|
|
13
13
|
hooksByFlowStage = new Map();
|
|
14
14
|
constructor(providers, list) {
|
|
15
|
-
super(
|
|
15
|
+
super('HookRegistry', providers, list);
|
|
16
16
|
this.scope = this.providers.getActiveScope();
|
|
17
17
|
}
|
|
18
18
|
buildMap() {
|
|
@@ -114,6 +114,18 @@ class HookRegistry extends regsitry_1.RegistryAbstract {
|
|
|
114
114
|
}
|
|
115
115
|
return Promise.all(readyArr);
|
|
116
116
|
}
|
|
117
|
+
/** Hooks for a given *flow*, filtered by owner if provided, sorted by priority (desc). */
|
|
118
|
+
getFlowHooksForOwner(flow, ownerId) {
|
|
119
|
+
const allHooks = this.getFlowHooks(flow);
|
|
120
|
+
if (!ownerId) {
|
|
121
|
+
return allHooks;
|
|
122
|
+
}
|
|
123
|
+
// Filter hooks to only include those that belong to the same owner or have no owner (global hooks)
|
|
124
|
+
return allHooks.filter((hook) => {
|
|
125
|
+
const hookOwner = hook.metadata.owner;
|
|
126
|
+
return !hookOwner || hookOwner.id === ownerId;
|
|
127
|
+
});
|
|
128
|
+
}
|
|
117
129
|
/** Hooks defined on a given *class* (metadata.target), sorted by priority (desc). */
|
|
118
130
|
getClsHooks(token) {
|
|
119
131
|
return this.entriesByCls.get(token) ?? [];
|