@common-stack/server-stack 7.2.1-alpha.5 → 7.2.1-alpha.51
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/lib/MainStackServer.cjs +30 -12
- package/lib/MainStackServer.cjs.map +1 -1
- package/lib/MainStackServer.mjs +31 -13
- package/lib/MainStackServer.mjs.map +1 -1
- package/lib/config/env-config.cjs +2 -2
- package/lib/config/env-config.cjs.map +1 -1
- package/lib/config/env-config.mjs +2 -2
- package/lib/config/env-config.mjs.map +1 -1
- package/lib/infrastructure/infrastructure-factory.cjs +59 -14
- package/lib/infrastructure/infrastructure-factory.cjs.map +1 -1
- package/lib/infrastructure/infrastructure-factory.d.ts +3 -0
- package/lib/infrastructure/infrastructure-factory.mjs +59 -14
- package/lib/infrastructure/infrastructure-factory.mjs.map +1 -1
- package/lib/infrastructure/inngest-factory.cjs +23 -2
- package/lib/infrastructure/inngest-factory.cjs.map +1 -1
- package/lib/infrastructure/inngest-factory.mjs +23 -2
- package/lib/infrastructure/inngest-factory.mjs.map +1 -1
- package/lib/inngest/handler-factory.d.ts +6 -0
- package/lib/inngest/middleware/auto-resolve-invoke.middleware.cjs +275 -0
- package/lib/inngest/middleware/auto-resolve-invoke.middleware.cjs.map +1 -0
- package/lib/inngest/middleware/auto-resolve-invoke.middleware.d.ts +111 -0
- package/lib/inngest/middleware/auto-resolve-invoke.middleware.mjs +275 -0
- package/lib/inngest/middleware/auto-resolve-invoke.middleware.mjs.map +1 -0
- package/lib/inngest/middleware/function-reference-helper.cjs +363 -0
- package/lib/inngest/middleware/function-reference-helper.cjs.map +1 -0
- package/lib/inngest/middleware/function-reference-helper.d.ts +211 -0
- package/lib/inngest/middleware/function-reference-helper.mjs +363 -0
- package/lib/inngest/middleware/function-reference-helper.mjs.map +1 -0
- package/lib/inngest/middleware/index.d.ts +31 -0
- package/lib/inngest/middleware/types.d.ts +162 -0
- package/lib/inngest/setup.cjs +30 -13
- package/lib/inngest/setup.cjs.map +1 -1
- package/lib/inngest/setup.mjs +30 -13
- package/lib/inngest/setup.mjs.map +1 -1
- package/lib/servers/ExpressApp.cjs +1 -1
- package/lib/servers/ExpressApp.cjs.map +1 -1
- package/lib/servers/ExpressApp.mjs +1 -1
- package/lib/servers/ExpressApp.mjs.map +1 -1
- package/package.json +7 -6
- package/lib/plugins/invalidateCachePlugin.test.d.ts +0 -1
- package/lib/plugins/response-cache-plugin.test.d.ts +0 -1
- package/lib/utils/add-shareable-directive-to-schema.test.d.ts +0 -1
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auto-Resolve Invoke Middleware for Inngest
|
|
3
|
+
*
|
|
4
|
+
* Makes the `function` parameter optional in step.invoke() by automatically
|
|
5
|
+
* resolving functions from the registry based on step names.
|
|
6
|
+
*
|
|
7
|
+
* Usage:
|
|
8
|
+
* ```typescript
|
|
9
|
+
* const inngest = new Inngest({
|
|
10
|
+
* middleware: [
|
|
11
|
+
* createFunctionMapperMiddleware(), // Required first
|
|
12
|
+
* createAutoResolveInvokeMiddleware(), // Then this
|
|
13
|
+
* ]
|
|
14
|
+
* });
|
|
15
|
+
*
|
|
16
|
+
* // In your functions
|
|
17
|
+
* async ({ step }) => {
|
|
18
|
+
* // Function auto-resolved from step name!
|
|
19
|
+
* await step.invoke('user-create', {
|
|
20
|
+
* data: { email: 'test@example.com' }
|
|
21
|
+
* });
|
|
22
|
+
* }
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
/**
|
|
26
|
+
* Creates middleware that auto-resolves functions for step.invoke()
|
|
27
|
+
*
|
|
28
|
+
* IMPORTANT: This middleware requires functions to be provided explicitly.
|
|
29
|
+
* Use `createAutoResolveInvokeMiddlewareWithFunctions()` helper instead,
|
|
30
|
+
* or pass functions manually after calling serve().
|
|
31
|
+
*
|
|
32
|
+
* Resolution strategy (in order):
|
|
33
|
+
* 1. If function explicitly provided → use it
|
|
34
|
+
* 2. Try custom mappings
|
|
35
|
+
* 3. Try exact match with function ID
|
|
36
|
+
* 4. Try stripping configured prefixes
|
|
37
|
+
* 5. Throw error or return null (based on throwOnNotFound)
|
|
38
|
+
*/
|
|
39
|
+
function createAutoResolveInvokeMiddleware(options = {}) {
|
|
40
|
+
const { mappings = {}, stripPrefixes = ['invoke-', 'call-'], caseSensitive = false, throwOnNotFound = true, debug = false, } = options;
|
|
41
|
+
// Function registry (populated manually or via helper)
|
|
42
|
+
const registry = new Map();
|
|
43
|
+
let registryPopulated = false;
|
|
44
|
+
const log = (...args) => {
|
|
45
|
+
if (debug) {
|
|
46
|
+
console.log('[AutoResolveInvoke]', ...args);
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
/**
|
|
50
|
+
* Auto-resolve function from step name
|
|
51
|
+
*/
|
|
52
|
+
const autoResolveFunction = (stepId) => {
|
|
53
|
+
const searchId = caseSensitive ? stepId : stepId.toLowerCase();
|
|
54
|
+
log(`Attempting to resolve function for step: "${stepId}" (search: "${searchId}")`);
|
|
55
|
+
// Strategy 1: Try custom mapping first
|
|
56
|
+
if (mappings[stepId]) {
|
|
57
|
+
const mappedId = mappings[stepId];
|
|
58
|
+
const mappedKey = caseSensitive ? mappedId : mappedId.toLowerCase();
|
|
59
|
+
const resolvedFn = registry.get(mappedKey);
|
|
60
|
+
if (resolvedFn) {
|
|
61
|
+
log(`✓ Resolved "${stepId}" via mapping to "${mappedId}"`);
|
|
62
|
+
return resolvedFn;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
// Strategy 2: Try exact match
|
|
66
|
+
let resolvedFn = registry.get(searchId);
|
|
67
|
+
if (resolvedFn) {
|
|
68
|
+
log(`✓ Resolved "${stepId}" via exact match`);
|
|
69
|
+
return resolvedFn;
|
|
70
|
+
}
|
|
71
|
+
// Strategy 3: Try stripping prefixes
|
|
72
|
+
for (const prefix of stripPrefixes) {
|
|
73
|
+
const prefixLower = caseSensitive ? prefix : prefix.toLowerCase();
|
|
74
|
+
if (searchId.startsWith(prefixLower)) {
|
|
75
|
+
const stripped = searchId.substring(prefix.length);
|
|
76
|
+
resolvedFn = registry.get(stripped);
|
|
77
|
+
if (resolvedFn) {
|
|
78
|
+
log(`✓ Resolved "${stepId}" by stripping prefix "${prefix}" → "${stripped}"`);
|
|
79
|
+
return resolvedFn;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
// Strategy 4: Not found
|
|
84
|
+
if (throwOnNotFound) {
|
|
85
|
+
const available = Array.from(registry.keys());
|
|
86
|
+
const availableList = available.length > 10
|
|
87
|
+
? available.slice(0, 10).join(', ') + `, ... (${available.length - 10} more)`
|
|
88
|
+
: available.join(', ');
|
|
89
|
+
throw new Error(`[AutoResolveInvoke] Cannot resolve function for step "${stepId}". ` +
|
|
90
|
+
`Available functions: ${availableList}. ` +
|
|
91
|
+
`Tip: Ensure the function ID matches the step name, or configure custom mappings.`);
|
|
92
|
+
}
|
|
93
|
+
log(`✗ Could not resolve function for step "${stepId}"`);
|
|
94
|
+
return null;
|
|
95
|
+
};
|
|
96
|
+
/**
|
|
97
|
+
* Transform Input Handler: Wrap step.invoke to auto-resolve functions
|
|
98
|
+
*/
|
|
99
|
+
const transformInputHandler = (inputCtx) => {
|
|
100
|
+
log('transformInput called, context keys:', Object.keys(inputCtx));
|
|
101
|
+
// Extract step object from various possible locations
|
|
102
|
+
const step = inputCtx.step || inputCtx.steps || (inputCtx.ctx && inputCtx.ctx.step);
|
|
103
|
+
if (!step) {
|
|
104
|
+
log('⚠ No step object found, trying to find it in context');
|
|
105
|
+
return inputCtx;
|
|
106
|
+
}
|
|
107
|
+
// Check if registry has functions
|
|
108
|
+
if (registry.size === 0) {
|
|
109
|
+
console.warn('[AutoResolveInvoke] ⚠ Function registry is empty. Auto-resolve will not work.');
|
|
110
|
+
console.warn('[AutoResolveInvoke] Tip: Ensure functions are registered before middleware initialization.');
|
|
111
|
+
return inputCtx;
|
|
112
|
+
}
|
|
113
|
+
log(`✓ Found step object, registry has ${registry.size} functions`);
|
|
114
|
+
/**
|
|
115
|
+
* Wrap step.invoke with auto-resolution
|
|
116
|
+
*/
|
|
117
|
+
const wrappedStep = new Proxy(step, {
|
|
118
|
+
get(target, prop) {
|
|
119
|
+
// Intercept invoke method
|
|
120
|
+
if (prop === 'invoke') {
|
|
121
|
+
return async (stepId, opts = {}) => {
|
|
122
|
+
log(`invoke() called with stepId: "${stepId}", has explicit function:`, !!opts.function);
|
|
123
|
+
// If function not provided, auto-resolve it
|
|
124
|
+
if (!opts.function) {
|
|
125
|
+
const resolvedFn = autoResolveFunction(stepId);
|
|
126
|
+
if (resolvedFn) {
|
|
127
|
+
opts = { ...opts, function: resolvedFn };
|
|
128
|
+
log(`Auto-resolved function for step "${stepId}"`);
|
|
129
|
+
}
|
|
130
|
+
else {
|
|
131
|
+
log(`No function resolved for step "${stepId}", will use original behavior`);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
else {
|
|
135
|
+
log(`Using explicit function for step "${stepId}"`);
|
|
136
|
+
}
|
|
137
|
+
// Call original invoke method
|
|
138
|
+
return target.invoke(stepId, opts);
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
// Pass through all other step methods unchanged
|
|
142
|
+
const value = target[prop];
|
|
143
|
+
return typeof value === 'function' ? value.bind(target) : value;
|
|
144
|
+
},
|
|
145
|
+
});
|
|
146
|
+
// Return modified context with wrapped step
|
|
147
|
+
return {
|
|
148
|
+
...inputCtx,
|
|
149
|
+
step: wrappedStep,
|
|
150
|
+
steps: wrappedStep,
|
|
151
|
+
ctx: inputCtx.ctx
|
|
152
|
+
? {
|
|
153
|
+
...inputCtx.ctx,
|
|
154
|
+
step: wrappedStep,
|
|
155
|
+
resolveFunction: autoResolveFunction,
|
|
156
|
+
}
|
|
157
|
+
: undefined,
|
|
158
|
+
};
|
|
159
|
+
};
|
|
160
|
+
// Expose method to populate registry
|
|
161
|
+
const middleware = {
|
|
162
|
+
name: 'auto-resolve-invoke-middleware',
|
|
163
|
+
// Method to populate registry (called by helper or manually)
|
|
164
|
+
_populateRegistry(functions) {
|
|
165
|
+
if (registryPopulated) {
|
|
166
|
+
log('Registry already populated, skipping');
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
if (!Array.isArray(functions) || functions.length === 0) {
|
|
170
|
+
console.warn('[AutoResolveInvoke] No functions provided to populate registry');
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
173
|
+
log('Populating registry with', functions.length, 'functions');
|
|
174
|
+
try {
|
|
175
|
+
functions.forEach((fn, index) => {
|
|
176
|
+
try {
|
|
177
|
+
if (!fn) {
|
|
178
|
+
console.warn(`[AutoResolveInvoke] Skipping null/undefined function at index ${index}`);
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
// Get the ID - it might be a property or a method
|
|
182
|
+
let fnId;
|
|
183
|
+
if (typeof fn.id === 'function') {
|
|
184
|
+
fnId = fn.id(); // Call the id method
|
|
185
|
+
console.log(`[AutoResolveInvoke] Function at index ${index} has id() method, returned: ${fnId}`);
|
|
186
|
+
}
|
|
187
|
+
else if (typeof fn.id === 'string') {
|
|
188
|
+
fnId = fn.id;
|
|
189
|
+
}
|
|
190
|
+
else {
|
|
191
|
+
console.warn(`[AutoResolveInvoke] Skipping function at index ${index} - id is ${typeof fn.id}:`, fn.id);
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
|
+
if (!fnId) {
|
|
195
|
+
console.warn(`[AutoResolveInvoke] Skipping function at index ${index} - empty ID`);
|
|
196
|
+
return;
|
|
197
|
+
}
|
|
198
|
+
const key = caseSensitive ? fnId : fnId.toLowerCase();
|
|
199
|
+
registry.set(key, fn);
|
|
200
|
+
log(`Registered: ${fnId} (key: ${key})`);
|
|
201
|
+
}
|
|
202
|
+
catch (fnError) {
|
|
203
|
+
console.error(`[AutoResolveInvoke] Error processing function at index ${index}:`, fnError);
|
|
204
|
+
throw fnError;
|
|
205
|
+
}
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
catch (loopError) {
|
|
209
|
+
console.error('[AutoResolveInvoke] Error during function registration loop:', loopError);
|
|
210
|
+
throw loopError;
|
|
211
|
+
}
|
|
212
|
+
registryPopulated = true;
|
|
213
|
+
console.log(`[AutoResolveInvoke] ✅ Registered ${registry.size} functions for auto-resolution`);
|
|
214
|
+
if (debug && registry.size > 0) {
|
|
215
|
+
console.log('[AutoResolveInvoke] Available function IDs:', Array.from(registry.keys()).join(', '));
|
|
216
|
+
}
|
|
217
|
+
},
|
|
218
|
+
/**
|
|
219
|
+
* Initialize: Build function registry from registered functions
|
|
220
|
+
*
|
|
221
|
+
* Note: In Inngest v3+, middleware init receives { client }, not { functions }.
|
|
222
|
+
* Functions are registered separately via serve({ client, functions }).
|
|
223
|
+
* We register functions lazily during transformInput instead.
|
|
224
|
+
*/
|
|
225
|
+
init: (initCtx) => {
|
|
226
|
+
log('Init hook called with context:', Object.keys(initCtx));
|
|
227
|
+
// In modern Inngest, we can't access functions during init
|
|
228
|
+
// The registry will be populated during transformInput when we have access to function context
|
|
229
|
+
log('Middleware initialized - function registry will be populated on first use');
|
|
230
|
+
// Return lifecycle hooks (required by Inngest middleware API)
|
|
231
|
+
// transformInput must be inside onFunctionRun for Inngest v3
|
|
232
|
+
return {
|
|
233
|
+
onFunctionRun: (ctx) => {
|
|
234
|
+
log('onFunctionRun called, context keys:', Object.keys(ctx));
|
|
235
|
+
return {
|
|
236
|
+
transformInput: transformInputHandler,
|
|
237
|
+
};
|
|
238
|
+
},
|
|
239
|
+
onSendEvent: () => ({}),
|
|
240
|
+
};
|
|
241
|
+
},
|
|
242
|
+
};
|
|
243
|
+
return middleware;
|
|
244
|
+
}
|
|
245
|
+
/**
|
|
246
|
+
* Helper: Create middleware configured for common-stack WorkflowNamespace patterns
|
|
247
|
+
*
|
|
248
|
+
* Handles your naming convention where:
|
|
249
|
+
* - Function IDs: 'aicode-code-agent', 'project-mgmt-main-workflow'
|
|
250
|
+
* - Event Names: 'aicode/code-agent-trigger', 'project-mgmt-main-workflow/trigger'
|
|
251
|
+
*
|
|
252
|
+
* Example usage:
|
|
253
|
+
* ```typescript
|
|
254
|
+
* // In your workflow
|
|
255
|
+
* await step.invoke('aicode-code-agent', { data: {...} });
|
|
256
|
+
* // Resolves to function with ID 'aicode-code-agent'
|
|
257
|
+
*
|
|
258
|
+
* await step.invoke('project-mgmt-create-from-template', { data: {...} });
|
|
259
|
+
* // Resolves to function with ID 'project-mgmt-create-from-template'
|
|
260
|
+
* ```
|
|
261
|
+
*/
|
|
262
|
+
function createCommonStackAutoResolveMiddleware(options) {
|
|
263
|
+
return createAutoResolveInvokeMiddleware({
|
|
264
|
+
// Strip common suffixes
|
|
265
|
+
stripPrefixes: ['-function', '-workflow'],
|
|
266
|
+
// Case-insensitive for flexibility
|
|
267
|
+
caseSensitive: false,
|
|
268
|
+
// Throw helpful errors
|
|
269
|
+
throwOnNotFound: true,
|
|
270
|
+
// Custom mappings if provided
|
|
271
|
+
mappings: options?.customMappings,
|
|
272
|
+
// Debug mode
|
|
273
|
+
debug: options?.debug || false,
|
|
274
|
+
});
|
|
275
|
+
}export{createAutoResolveInvokeMiddleware,createCommonStackAutoResolveMiddleware};//# sourceMappingURL=auto-resolve-invoke.middleware.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auto-resolve-invoke.middleware.mjs","sources":["../../../src/inngest/middleware/auto-resolve-invoke.middleware.ts"],"sourcesContent":[null],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,363 @@
|
|
|
1
|
+
'use strict';/**
|
|
2
|
+
* Function Reference Helper for Inngest
|
|
3
|
+
*
|
|
4
|
+
* Provides automatic function reference resolution for all registered functions.
|
|
5
|
+
* Instead of manually importing functions, you can reference them by ID.
|
|
6
|
+
*
|
|
7
|
+
* This combines:
|
|
8
|
+
* 1. Inngest's native `referenceFunction()` pattern
|
|
9
|
+
* 2. Automatic registry from all Feature-registered functions
|
|
10
|
+
* 3. Type-safe helpers for common patterns
|
|
11
|
+
*
|
|
12
|
+
* Usage:
|
|
13
|
+
* ```typescript
|
|
14
|
+
* // Instead of:
|
|
15
|
+
* import { someFunction } from '../other-module';
|
|
16
|
+
* await step.invoke('call-it', { function: someFunction, data: {...} });
|
|
17
|
+
*
|
|
18
|
+
* // You can do:
|
|
19
|
+
* await step.invoke('call-it', {
|
|
20
|
+
* function: ctx.resolveFunction('some-function-id'),
|
|
21
|
+
* data: {...}
|
|
22
|
+
* });
|
|
23
|
+
*
|
|
24
|
+
* // Or even simpler (if middleware auto-resolve enabled):
|
|
25
|
+
* await step.invoke('some-function-id', { data: {...} });
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
28
|
+
/**
|
|
29
|
+
* Global function registry
|
|
30
|
+
* Populated by setup.ts after all functions are loaded
|
|
31
|
+
*/
|
|
32
|
+
class FunctionRegistry {
|
|
33
|
+
functions = new Map();
|
|
34
|
+
initialized = false;
|
|
35
|
+
/**
|
|
36
|
+
* Register all functions from Feature system
|
|
37
|
+
*/
|
|
38
|
+
register(functions) {
|
|
39
|
+
if (this.initialized) {
|
|
40
|
+
console.warn('[FunctionRegistry] Already initialized, skipping re-registration');
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
console.log(`[FunctionRegistry] Registering ${functions.length} functions...`);
|
|
44
|
+
functions.forEach((fn, index) => {
|
|
45
|
+
try {
|
|
46
|
+
if (!fn) {
|
|
47
|
+
console.warn(`[FunctionRegistry] Skipping null function at index ${index}`);
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
// Get function ID (might be method or property)
|
|
51
|
+
let fnId;
|
|
52
|
+
if (typeof fn.id === 'function') {
|
|
53
|
+
fnId = fn.id();
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
fnId = String(fn.id);
|
|
57
|
+
}
|
|
58
|
+
if (!fnId) {
|
|
59
|
+
console.warn(`[FunctionRegistry] Skipping function at index ${index} - empty ID`);
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
this.functions.set(fnId, fn);
|
|
63
|
+
// Also register lowercase version for case-insensitive lookup
|
|
64
|
+
this.functions.set(fnId.toLowerCase(), fn);
|
|
65
|
+
}
|
|
66
|
+
catch (error) {
|
|
67
|
+
console.error(`[FunctionRegistry] Error registering function at index ${index}:`, error);
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
this.initialized = true;
|
|
71
|
+
const uniqueCount = Array.from(new Set(this.functions.values())).length;
|
|
72
|
+
console.log(`[FunctionRegistry] ✅ Registered ${uniqueCount} unique functions`);
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Get function by ID (case-insensitive)
|
|
76
|
+
*/
|
|
77
|
+
get(functionId) {
|
|
78
|
+
// Try exact match first
|
|
79
|
+
let fn = this.functions.get(functionId);
|
|
80
|
+
if (fn)
|
|
81
|
+
return fn;
|
|
82
|
+
// Try lowercase match
|
|
83
|
+
fn = this.functions.get(functionId.toLowerCase());
|
|
84
|
+
if (fn)
|
|
85
|
+
return fn;
|
|
86
|
+
return undefined;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Check if function exists
|
|
90
|
+
*/
|
|
91
|
+
has(functionId) {
|
|
92
|
+
return this.functions.has(functionId) || this.functions.has(functionId.toLowerCase());
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Get all registered function IDs
|
|
96
|
+
*/
|
|
97
|
+
getAllIds() {
|
|
98
|
+
const uniqueFunctions = Array.from(new Set(this.functions.values()));
|
|
99
|
+
return uniqueFunctions
|
|
100
|
+
.map((fn) => {
|
|
101
|
+
if (typeof fn.id === 'function') {
|
|
102
|
+
return fn.id();
|
|
103
|
+
}
|
|
104
|
+
return String(fn.id);
|
|
105
|
+
})
|
|
106
|
+
.filter(Boolean);
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Get count of registered functions
|
|
110
|
+
*/
|
|
111
|
+
get count() {
|
|
112
|
+
return Array.from(new Set(this.functions.values())).length;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Check if registry is initialized
|
|
116
|
+
*/
|
|
117
|
+
get isInitialized() {
|
|
118
|
+
return this.initialized;
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Clear registry (for testing)
|
|
122
|
+
*/
|
|
123
|
+
clear() {
|
|
124
|
+
this.functions.clear();
|
|
125
|
+
this.initialized = false;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
// Global singleton instance
|
|
129
|
+
const globalFunctionRegistry = new FunctionRegistry();
|
|
130
|
+
/**
|
|
131
|
+
* Reference a function by its ID
|
|
132
|
+
* Similar to Inngest's native referenceFunction, but automatically uses global registry
|
|
133
|
+
*
|
|
134
|
+
* @param functionIdOrOptions - The ID of the function or options object with functionId
|
|
135
|
+
* @returns The function reference to use in step.invoke()
|
|
136
|
+
*
|
|
137
|
+
* @example
|
|
138
|
+
* ```typescript
|
|
139
|
+
* // Simple usage
|
|
140
|
+
* const userCreateFn = referenceFunction('user-create');
|
|
141
|
+
*
|
|
142
|
+
* // Type-safe usage
|
|
143
|
+
* const computePi = referenceFunction({ functionId: 'compute-pi' });
|
|
144
|
+
*
|
|
145
|
+
* await step.invoke('create-user', {
|
|
146
|
+
* function: userCreateFn,
|
|
147
|
+
* data: { email: 'user@example.com' }
|
|
148
|
+
* });
|
|
149
|
+
* ```
|
|
150
|
+
*/
|
|
151
|
+
function referenceFunction(functionIdOrOptions) {
|
|
152
|
+
const functionId = typeof functionIdOrOptions === 'string' ? functionIdOrOptions : functionIdOrOptions.functionId;
|
|
153
|
+
if (!globalFunctionRegistry.isInitialized) {
|
|
154
|
+
throw new Error(`[referenceFunction] Function registry not initialized yet. ` +
|
|
155
|
+
`Ensure setupInngestFunctions() has completed before using referenceFunction().`);
|
|
156
|
+
}
|
|
157
|
+
const fn = globalFunctionRegistry.get(functionId);
|
|
158
|
+
if (!fn) {
|
|
159
|
+
const available = globalFunctionRegistry.getAllIds();
|
|
160
|
+
const suggestions = available.filter((id) => id.toLowerCase().includes(functionId.toLowerCase())).slice(0, 5);
|
|
161
|
+
let errorMsg = `[referenceFunction] Function "${functionId}" not found in registry.`;
|
|
162
|
+
if (suggestions.length > 0) {
|
|
163
|
+
errorMsg += `\n\nDid you mean one of these?\n - ${suggestions.join('\n - ')}`;
|
|
164
|
+
}
|
|
165
|
+
else {
|
|
166
|
+
errorMsg += `\n\nAvailable functions (${available.length} total):\n - ${available.slice(0, 10).join('\n - ')}`;
|
|
167
|
+
if (available.length > 10) {
|
|
168
|
+
errorMsg += `\n ... and ${available.length - 10} more`;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
throw new Error(errorMsg);
|
|
172
|
+
}
|
|
173
|
+
return fn;
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Batch reference multiple functions at once
|
|
177
|
+
* Useful for orchestrator workflows that call many functions
|
|
178
|
+
*
|
|
179
|
+
* @example
|
|
180
|
+
* ```typescript
|
|
181
|
+
* const { userCreate, emailSend, analyticsTrack } = referenceFunctions([
|
|
182
|
+
* 'user-create',
|
|
183
|
+
* 'email-send-welcome',
|
|
184
|
+
* 'analytics-track-event'
|
|
185
|
+
* ]);
|
|
186
|
+
*
|
|
187
|
+
* await step.invoke('create-user', { function: userCreate, data: {...} });
|
|
188
|
+
* await step.invoke('send-email', { function: emailSend, data: {...} });
|
|
189
|
+
* await step.invoke('track', { function: analyticsTrack, data: {...} });
|
|
190
|
+
* ```
|
|
191
|
+
*/
|
|
192
|
+
function referenceFunctions(functionIds) {
|
|
193
|
+
const result = {};
|
|
194
|
+
for (const functionId of functionIds) {
|
|
195
|
+
result[functionId] = referenceFunction(functionId);
|
|
196
|
+
}
|
|
197
|
+
return result;
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* Check if a function is registered
|
|
201
|
+
* Useful for conditional logic
|
|
202
|
+
*
|
|
203
|
+
* @example
|
|
204
|
+
* ```typescript
|
|
205
|
+
* if (hasFunctionReference('email-send-welcome')) {
|
|
206
|
+
* const emailFn = referenceFunction('email-send-welcome');
|
|
207
|
+
* await step.invoke('send-email', { function: emailFn, data: {...} });
|
|
208
|
+
* }
|
|
209
|
+
* ```
|
|
210
|
+
*/
|
|
211
|
+
function hasFunctionReference(functionId) {
|
|
212
|
+
return globalFunctionRegistry.has(functionId);
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* Get all available function IDs
|
|
216
|
+
* Useful for debugging and introspection
|
|
217
|
+
*
|
|
218
|
+
* @example
|
|
219
|
+
* ```typescript
|
|
220
|
+
* console.log('Available functions:', getAvailableFunctions());
|
|
221
|
+
* ```
|
|
222
|
+
*/
|
|
223
|
+
function getAvailableFunctions() {
|
|
224
|
+
return globalFunctionRegistry.getAllIds();
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* Resolve a workflow-style or ID-style function reference to an Inngest function reference.
|
|
228
|
+
*
|
|
229
|
+
* Supported inputs:
|
|
230
|
+
* - Exact function id: "user-create"
|
|
231
|
+
* - Workflow-style: "WORKFLOWNAME.Function/trigger" or "WORKFLOWNAME.Function.trigger"
|
|
232
|
+
*
|
|
233
|
+
* The resolver will first try the exact ID as provided. If not found it will
|
|
234
|
+
* normalize the string by replacing separators ("/", ".") with dashes and
|
|
235
|
+
* collapsing non-alphanumerics, then lower-case the result. Example:
|
|
236
|
+
*
|
|
237
|
+
* WORKFLOWNAME.Function/trigger -> workflowname-function-trigger
|
|
238
|
+
*
|
|
239
|
+
* If still not found, it will throw the same helpful error as `referenceFunction`.
|
|
240
|
+
*/
|
|
241
|
+
function resolveFunctionId(functionRef) {
|
|
242
|
+
const raw = typeof functionRef === 'string' ? functionRef : functionRef.functionId;
|
|
243
|
+
if (!raw || typeof raw !== 'string') {
|
|
244
|
+
throw new Error('[resolveFunctionId] Invalid function reference');
|
|
245
|
+
}
|
|
246
|
+
// Try direct lookup first
|
|
247
|
+
if (globalFunctionRegistry.has(raw)) {
|
|
248
|
+
return referenceFunction(raw);
|
|
249
|
+
}
|
|
250
|
+
// Normalize common workflow-style patterns into kebab-case id
|
|
251
|
+
let normalized = raw
|
|
252
|
+
// Replace separators with dashes
|
|
253
|
+
.replace(/[\/\.\s]+/g, '-')
|
|
254
|
+
// Insert dashes between camelCase / PascalCase boundaries (aB -> a-B)
|
|
255
|
+
.replace(/([a-z0-9])([A-Z])/g, '$1-$2')
|
|
256
|
+
// Remove non-alphanumeric/dash characters
|
|
257
|
+
.replace(/[^a-zA-Z0-9-]+/g, '-')
|
|
258
|
+
// Collapse multiple dashes
|
|
259
|
+
.replace(/-+/g, '-')
|
|
260
|
+
// Trim dashes
|
|
261
|
+
.replace(/(^-|-$)/g, '')
|
|
262
|
+
.toLowerCase();
|
|
263
|
+
if (globalFunctionRegistry.has(normalized)) {
|
|
264
|
+
return referenceFunction(normalized);
|
|
265
|
+
}
|
|
266
|
+
// As a last resort, try lowercasing the raw input
|
|
267
|
+
if (globalFunctionRegistry.has(raw.toLowerCase())) {
|
|
268
|
+
return referenceFunction(raw.toLowerCase());
|
|
269
|
+
}
|
|
270
|
+
// Not found - rethrow a helpful error from referenceFunction to show suggestions
|
|
271
|
+
return referenceFunction(normalized);
|
|
272
|
+
}
|
|
273
|
+
/**
|
|
274
|
+
* Combined middleware: Reference + Auto-Resolve
|
|
275
|
+
* Provides both manual and automatic function resolution
|
|
276
|
+
*
|
|
277
|
+
* @example
|
|
278
|
+
* ```typescript
|
|
279
|
+
* const inngest = new Inngest({
|
|
280
|
+
* middleware: [createCombinedFunctionMiddleware()],
|
|
281
|
+
* });
|
|
282
|
+
*
|
|
283
|
+
* // Method 1: Manual reference
|
|
284
|
+
* const userFn = ctx.resolveFunction('user-create');
|
|
285
|
+
* await step.invoke('create-user', { function: userFn, data: {...} });
|
|
286
|
+
*
|
|
287
|
+
* // Method 2: Automatic (if function ID matches)
|
|
288
|
+
* await step.invoke('user-create', { data: {...} }); // Auto-resolved!
|
|
289
|
+
* ```
|
|
290
|
+
*/
|
|
291
|
+
function createCombinedFunctionMiddleware(options) {
|
|
292
|
+
const { autoResolve = true, caseSensitive = false, debug = false } = options || {};
|
|
293
|
+
const log = (...args) => {
|
|
294
|
+
if (debug) {
|
|
295
|
+
console.log('[CombinedFunctionMiddleware]', ...args);
|
|
296
|
+
}
|
|
297
|
+
};
|
|
298
|
+
return {
|
|
299
|
+
name: 'combined-function-middleware',
|
|
300
|
+
init() {
|
|
301
|
+
return {
|
|
302
|
+
onFunctionRun({ ctx }) {
|
|
303
|
+
// Inject reference helpers
|
|
304
|
+
ctx.resolveFunction = referenceFunction;
|
|
305
|
+
ctx.resolveFunctions = referenceFunctions;
|
|
306
|
+
ctx.hasFunction = hasFunctionReference;
|
|
307
|
+
ctx.getAvailableFunctions = getAvailableFunctions;
|
|
308
|
+
ctx.resolveFunctionId = resolveFunctionId;
|
|
309
|
+
return {
|
|
310
|
+
transformInput(inputCtx) {
|
|
311
|
+
// Inject into context
|
|
312
|
+
if (inputCtx.ctx) {
|
|
313
|
+
inputCtx.ctx.resolveFunction = referenceFunction;
|
|
314
|
+
inputCtx.ctx.resolveFunctions = referenceFunctions;
|
|
315
|
+
inputCtx.ctx.hasFunction = hasFunctionReference;
|
|
316
|
+
inputCtx.ctx.getAvailableFunctions = getAvailableFunctions;
|
|
317
|
+
inputCtx.ctx.resolveFunctionId = resolveFunctionId;
|
|
318
|
+
}
|
|
319
|
+
// Inject helper functions into step object for inline editor support
|
|
320
|
+
// The actual step object that gets passed to workflow functions is inputCtx.ctx.step
|
|
321
|
+
// inputCtx.step is the step data array, inputCtx.ctx.step is the step object with methods
|
|
322
|
+
const stepObject = (inputCtx.ctx && inputCtx.ctx.step);
|
|
323
|
+
log('Checking step object - inputCtx.step:', !!inputCtx.step, 'inputCtx.steps:', !!inputCtx.steps, 'inputCtx.ctx.step:', !!stepObject, 'found step object:', !!stepObject);
|
|
324
|
+
if (stepObject) {
|
|
325
|
+
// Make referenceFunction available as step.referenceFunction()
|
|
326
|
+
stepObject.referenceFunction = referenceFunction;
|
|
327
|
+
stepObject.hasFunction = hasFunctionReference;
|
|
328
|
+
stepObject.getAvailableFunctions = getAvailableFunctions;
|
|
329
|
+
stepObject.resolveFunctionId = resolveFunctionId;
|
|
330
|
+
log('✅ Injected referenceFunction into step object');
|
|
331
|
+
}
|
|
332
|
+
else {
|
|
333
|
+
log('❌ No step object found in inputCtx.ctx.step');
|
|
334
|
+
}
|
|
335
|
+
// Auto-resolve if enabled
|
|
336
|
+
if (autoResolve && stepObject) {
|
|
337
|
+
const originalInvoke = stepObject.invoke;
|
|
338
|
+
stepObject.invoke = async (stepId, opts = {}) => {
|
|
339
|
+
log(`invoke() called: "${stepId}", has function:`, !!opts.function);
|
|
340
|
+
// Auto-resolve if no function provided
|
|
341
|
+
if (!opts.function) {
|
|
342
|
+
try {
|
|
343
|
+
const fn = referenceFunction(stepId);
|
|
344
|
+
opts = { ...opts, function: fn };
|
|
345
|
+
log(`✅ Auto-resolved function for step "${stepId}"`);
|
|
346
|
+
}
|
|
347
|
+
catch (error) {
|
|
348
|
+
log(`⚠️ Could not auto-resolve "${stepId}":`, error.message);
|
|
349
|
+
// Continue with original behavior
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
return originalInvoke.call(stepObject, stepId, opts);
|
|
353
|
+
};
|
|
354
|
+
}
|
|
355
|
+
return inputCtx;
|
|
356
|
+
},
|
|
357
|
+
};
|
|
358
|
+
},
|
|
359
|
+
onSendEvent: () => ({}),
|
|
360
|
+
};
|
|
361
|
+
},
|
|
362
|
+
};
|
|
363
|
+
}exports.createCombinedFunctionMiddleware=createCombinedFunctionMiddleware;exports.getAvailableFunctions=getAvailableFunctions;exports.globalFunctionRegistry=globalFunctionRegistry;exports.hasFunctionReference=hasFunctionReference;exports.referenceFunction=referenceFunction;exports.referenceFunctions=referenceFunctions;exports.resolveFunctionId=resolveFunctionId;//# sourceMappingURL=function-reference-helper.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"function-reference-helper.cjs","sources":["../../../src/inngest/middleware/function-reference-helper.ts"],"sourcesContent":[null],"names":[],"mappings":"aAAA;;;;;;;;;;;;;;;;;;;;;;;;;;AA0BG;AAIH;;;AAGG;AACH,MAAM,gBAAgB,CAAA;AACV,IAAA,SAAS,GAAG,IAAI,GAAG,EAA+B,CAAC;IACnD,WAAW,GAAG,KAAK,CAAC;AAE5B;;AAEG;AACH,IAAA,QAAQ,CAAC,SAAgC,EAAA;AACrC,QAAA,IAAI,IAAI,CAAC,WAAW,EAAE;AAClB,YAAA,OAAO,CAAC,IAAI,CAAC,kEAAkE,CAAC,CAAC;YACjF,OAAO;SACV;QAED,OAAO,CAAC,GAAG,CAAC,CAAA,+BAAA,EAAkC,SAAS,CAAC,MAAM,CAAe,aAAA,CAAA,CAAC,CAAC;QAE/E,SAAS,CAAC,OAAO,CAAC,CAAC,EAAE,EAAE,KAAK,KAAI;AAC5B,YAAA,IAAI;gBACA,IAAI,CAAC,EAAE,EAAE;AACL,oBAAA,OAAO,CAAC,IAAI,CAAC,sDAAsD,KAAK,CAAA,CAAE,CAAC,CAAC;oBAC5E,OAAO;iBACV;;AAGD,gBAAA,IAAI,IAAY,CAAC;AACjB,gBAAA,IAAI,OAAO,EAAE,CAAC,EAAE,KAAK,UAAU,EAAE;AAC7B,oBAAA,IAAI,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC;iBAClB;qBAAM;AACH,oBAAA,IAAI,GAAG,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;iBACxB;gBAED,IAAI,CAAC,IAAI,EAAE;AACP,oBAAA,OAAO,CAAC,IAAI,CAAC,iDAAiD,KAAK,CAAA,WAAA,CAAa,CAAC,CAAC;oBAClF,OAAO;iBACV;gBAED,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;;AAE7B,gBAAA,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,EAAE,CAAC,CAAC;aAC9C;YAAC,OAAO,KAAK,EAAE;gBACZ,OAAO,CAAC,KAAK,CAAC,CAAA,uDAAA,EAA0D,KAAK,CAAG,CAAA,CAAA,EAAE,KAAK,CAAC,CAAC;aAC5F;AACL,SAAC,CAAC,CAAC;AAEH,QAAA,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;AACxB,QAAA,MAAM,WAAW,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC;AACxE,QAAA,OAAO,CAAC,GAAG,CAAC,mCAAmC,WAAW,CAAA,iBAAA,CAAmB,CAAC,CAAC;KAClF;AAED;;AAEG;AACH,IAAA,GAAG,CAAC,UAAkB,EAAA;;QAElB,IAAI,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;AACxC,QAAA,IAAI,EAAE;AAAE,YAAA,OAAO,EAAE,CAAC;;AAGlB,QAAA,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,UAAU,CAAC,WAAW,EAAE,CAAC,CAAC;AAClD,QAAA,IAAI,EAAE;AAAE,YAAA,OAAO,EAAE,CAAC;AAElB,QAAA,OAAO,SAAS,CAAC;KACpB;AAED;;AAEG;AACH,IAAA,GAAG,CAAC,UAAkB,EAAA;QAClB,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,UAAU,CAAC,WAAW,EAAE,CAAC,CAAC;KACzF;AAED;;AAEG;IACH,SAAS,GAAA;AACL,QAAA,MAAM,eAAe,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;AACrE,QAAA,OAAO,eAAe;AACjB,aAAA,GAAG,CAAC,CAAC,EAAE,KAAI;AACR,YAAA,IAAI,OAAO,EAAE,CAAC,EAAE,KAAK,UAAU,EAAE;AAC7B,gBAAA,OAAO,EAAE,CAAC,EAAE,EAAE,CAAC;aAClB;AACD,YAAA,OAAO,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;AACzB,SAAC,CAAC;aACD,MAAM,CAAC,OAAO,CAAC,CAAC;KACxB;AAED;;AAEG;AACH,IAAA,IAAI,KAAK,GAAA;AACL,QAAA,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC;KAC9D;AAED;;AAEG;AACH,IAAA,IAAI,aAAa,GAAA;QACb,OAAO,IAAI,CAAC,WAAW,CAAC;KAC3B;AAED;;AAEG;IACH,KAAK,GAAA;AACD,QAAA,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,CAAC;AACvB,QAAA,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;KAC5B;AACJ,CAAA;AAED;AACa,MAAA,sBAAsB,GAAG,IAAI,gBAAgB,GAAG;AAE7D;;;;;;;;;;;;;;;;;;;;AAoBG;AACG,SAAU,iBAAiB,CAC7B,mBAAoD,EAAA;AAEpD,IAAA,MAAM,UAAU,GAAG,OAAO,mBAAmB,KAAK,QAAQ,GAAG,mBAAmB,GAAG,mBAAmB,CAAC,UAAU,CAAC;AAElH,IAAA,IAAI,CAAC,sBAAsB,CAAC,aAAa,EAAE;QACvC,MAAM,IAAI,KAAK,CACX,CAA6D,2DAAA,CAAA;AACzD,YAAA,CAAA,8EAAA,CAAgF,CACvF,CAAC;KACL;IAED,MAAM,EAAE,GAAG,sBAAsB,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;IAElD,IAAI,CAAC,EAAE,EAAE;AACL,QAAA,MAAM,SAAS,GAAG,sBAAsB,CAAC,SAAS,EAAE,CAAC;AACrD,QAAA,MAAM,WAAW,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,UAAU,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AAE9G,QAAA,IAAI,QAAQ,GAAG,CAAiC,8BAAA,EAAA,UAAU,0BAA0B,CAAC;AAErF,QAAA,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE;YACxB,QAAQ,IAAI,uCAAuC,WAAW,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA,CAAE,CAAC;SACnF;aAAM;YACH,QAAQ,IAAI,4BAA4B,SAAS,CAAC,MAAM,CAAiB,cAAA,EAAA,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;AACjH,YAAA,IAAI,SAAS,CAAC,MAAM,GAAG,EAAE,EAAE;gBACvB,QAAQ,IAAI,eAAe,SAAS,CAAC,MAAM,GAAG,EAAE,OAAO,CAAC;aAC3D;SACJ;AAED,QAAA,MAAM,IAAI,KAAK,CAAC,QAAQ,CAAC,CAAC;KAC7B;AAED,IAAA,OAAO,EAAO,CAAC;AACnB,CAAC;AAED;;;;;;;;;;;;;;;;AAgBG;AACG,SAAU,kBAAkB,CAC9B,WAAc,EAAA;IAEd,MAAM,MAAM,GAAQ,EAAE,CAAC;AAEvB,IAAA,KAAK,MAAM,UAAU,IAAI,WAAW,EAAE;QAClC,MAAM,CAAC,UAAU,CAAC,GAAG,iBAAiB,CAAC,UAAU,CAAC,CAAC;KACtD;AAED,IAAA,OAAO,MAAM,CAAC;AAClB,CAAC;AAED;;;;;;;;;;;AAWG;AACG,SAAU,oBAAoB,CAAC,UAAkB,EAAA;AACnD,IAAA,OAAO,sBAAsB,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;AAClD,CAAC;AAED;;;;;;;;AAQG;SACa,qBAAqB,GAAA;AACjC,IAAA,OAAO,sBAAsB,CAAC,SAAS,EAAE,CAAC;AAC9C,CAAC;AAED;;;;;;;;;;;;;;AAcG;AACG,SAAU,iBAAiB,CAAC,WAA4C,EAAA;AAC1E,IAAA,MAAM,GAAG,GAAG,OAAO,WAAW,KAAK,QAAQ,GAAG,WAAW,GAAG,WAAW,CAAC,UAAU,CAAC;IAEnF,IAAI,CAAC,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE;AACjC,QAAA,MAAM,IAAI,KAAK,CAAC,gDAAgD,CAAC,CAAC;KACrE;;AAGD,IAAA,IAAI,sBAAsB,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE;AACjC,QAAA,OAAO,iBAAiB,CAAC,GAAG,CAAC,CAAC;KACjC;;IAGD,IAAI,UAAU,GAAG,GAAG;;AAEf,SAAA,OAAO,CAAC,YAAY,EAAE,GAAG,CAAC;;AAE1B,SAAA,OAAO,CAAC,oBAAoB,EAAE,OAAO,CAAC;;AAEtC,SAAA,OAAO,CAAC,iBAAiB,EAAE,GAAG,CAAC;;AAE/B,SAAA,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC;;AAEnB,SAAA,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC;AACvB,SAAA,WAAW,EAAE,CAAC;AAEnB,IAAA,IAAI,sBAAsB,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE;AACxC,QAAA,OAAO,iBAAiB,CAAC,UAAU,CAAC,CAAC;KACxC;;IAGD,IAAI,sBAAsB,CAAC,GAAG,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,EAAE;AAC/C,QAAA,OAAO,iBAAiB,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,CAAC;KAC/C;;AAGD,IAAA,OAAO,iBAAiB,CAAC,UAAU,CAAC,CAAC;AACzC,CAAC;AA8DD;;;;;;;;;;;;;;;;;AAiBG;AACG,SAAU,gCAAgC,CAAC,OAOhD,EAAA;AACG,IAAA,MAAM,EAAE,WAAW,GAAG,IAAI,EAAE,aAAa,GAAG,KAAK,EAAE,KAAK,GAAG,KAAK,EAAE,GAAG,OAAO,IAAI,EAAE,CAAC;AAEnF,IAAA,MAAM,GAAG,GAAG,CAAC,GAAG,IAAW,KAAI;QAC3B,IAAI,KAAK,EAAE;YACP,OAAO,CAAC,GAAG,CAAC,8BAA8B,EAAE,GAAG,IAAI,CAAC,CAAC;SACxD;AACL,KAAC,CAAC;IAEF,OAAO;AACH,QAAA,IAAI,EAAE,8BAA8B;QAEpC,IAAI,GAAA;YACA,OAAO;gBACH,aAAa,CAAC,EAAE,GAAG,EAAO,EAAA;;AAEtB,oBAAA,GAAG,CAAC,eAAe,GAAG,iBAAiB,CAAC;AACxC,oBAAA,GAAG,CAAC,gBAAgB,GAAG,kBAAkB,CAAC;AAC1C,oBAAA,GAAG,CAAC,WAAW,GAAG,oBAAoB,CAAC;AACvC,oBAAA,GAAG,CAAC,qBAAqB,GAAG,qBAAqB,CAAC;AAClD,oBAAA,GAAG,CAAC,iBAAiB,GAAG,iBAAiB,CAAC;oBAC1C,OAAO;AACH,wBAAA,cAAc,CAAC,QAAa,EAAA;;AAExB,4BAAA,IAAI,QAAQ,CAAC,GAAG,EAAE;AACd,gCAAA,QAAQ,CAAC,GAAG,CAAC,eAAe,GAAG,iBAAiB,CAAC;AACjD,gCAAA,QAAQ,CAAC,GAAG,CAAC,gBAAgB,GAAG,kBAAkB,CAAC;AACnD,gCAAA,QAAQ,CAAC,GAAG,CAAC,WAAW,GAAG,oBAAoB,CAAC;AAChD,gCAAA,QAAQ,CAAC,GAAG,CAAC,qBAAqB,GAAG,qBAAqB,CAAC;AAC3D,gCAAA,QAAQ,CAAC,GAAG,CAAC,iBAAiB,GAAG,iBAAiB,CAAC;6BACtD;;;;AAID,4BAAA,MAAM,UAAU,IAAI,QAAQ,CAAC,GAAG,IAAI,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;AACvD,4BAAA,GAAG,CAAC,uCAAuC,EAAE,CAAC,CAAC,QAAQ,CAAC,IAAI,EAAE,iBAAiB,EAAE,CAAC,CAAC,QAAQ,CAAC,KAAK,EAAE,oBAAoB,EAAE,CAAC,CAAC,UAAU,EAAE,oBAAoB,EAAE,CAAC,CAAC,UAAU,CAAC,CAAC;4BAC3K,IAAI,UAAU,EAAE;;AAEZ,gCAAA,UAAU,CAAC,iBAAiB,GAAG,iBAAiB,CAAC;AACjD,gCAAA,UAAU,CAAC,WAAW,GAAG,oBAAoB,CAAC;AAC9C,gCAAA,UAAU,CAAC,qBAAqB,GAAG,qBAAqB,CAAC;AACzD,gCAAA,UAAU,CAAC,iBAAiB,GAAG,iBAAiB,CAAC;gCAEjD,GAAG,CAAC,+CAA+C,CAAC,CAAC;6BACxD;iCAAM;gCACH,GAAG,CAAC,6CAA6C,CAAC,CAAC;6BACtD;;AAED,4BAAA,IAAI,WAAW,IAAI,UAAU,EAAE;AAC3B,gCAAA,MAAM,cAAc,GAAG,UAAU,CAAC,MAAM,CAAC;gCACzC,UAAU,CAAC,MAAM,GAAG,OAAO,MAAc,EAAE,IAAA,GAAY,EAAE,KAAI;oCACzD,GAAG,CAAC,CAAqB,kBAAA,EAAA,MAAM,CAAkB,gBAAA,CAAA,EAAE,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;;AAEpE,oCAAA,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE;AAChB,wCAAA,IAAI;AACA,4CAAA,MAAM,EAAE,GAAG,iBAAiB,CAAC,MAAM,CAAC,CAAC;4CACrC,IAAI,GAAG,EAAE,GAAG,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC;AACjC,4CAAA,GAAG,CAAC,CAAA,mCAAA,EAAsC,MAAM,CAAA,CAAA,CAAG,CAAC,CAAC;yCACxD;wCAAC,OAAO,KAAK,EAAE;4CACZ,GAAG,CAAC,+BAA+B,MAAM,CAAA,EAAA,CAAI,EAAG,KAAe,CAAC,OAAO,CAAC,CAAC;;yCAE5E;qCACJ;oCAED,OAAO,cAAc,CAAC,IAAI,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC;AACzD,iCAAC,CAAC;6BACL;AAED,4BAAA,OAAO,QAAQ,CAAC;yBACnB;qBACJ,CAAC;iBACL;AACD,gBAAA,WAAW,EAAE,OAAO,EAAE,CAAC;aAC1B,CAAC;SACL;KACJ,CAAC;AACN"}
|