@pikku/inspector 0.11.1 → 0.12.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/CHANGELOG.md +26 -1
- package/OPTIMIZATION-PLAN.md +195 -0
- package/dist/add/add-ai-agent.d.ts +2 -0
- package/dist/add/add-ai-agent.js +314 -0
- package/dist/add/add-channel.js +69 -61
- package/dist/add/add-cli.js +36 -18
- package/dist/add/add-file-with-factory.js +2 -0
- package/dist/add/add-functions.js +327 -59
- package/dist/add/add-http-route.d.ts +19 -10
- package/dist/add/add-http-route.js +153 -44
- package/dist/add/add-http-routes.d.ts +5 -0
- package/dist/add/add-http-routes.js +159 -0
- package/dist/add/add-keyed-wiring.d.ts +12 -0
- package/dist/add/add-keyed-wiring.js +97 -0
- package/dist/add/add-mcp-prompt.js +14 -9
- package/dist/add/add-mcp-resource.js +14 -9
- package/dist/add/add-middleware.d.ts +1 -4
- package/dist/add/add-middleware.js +364 -79
- package/dist/add/add-permission.d.ts +1 -1
- package/dist/add/add-permission.js +152 -40
- package/dist/add/add-queue-worker.js +18 -12
- package/dist/add/add-rpc-invocations.d.ts +3 -0
- package/dist/add/add-rpc-invocations.js +65 -25
- package/dist/add/add-schedule.js +11 -5
- package/dist/add/add-secret.d.ts +3 -0
- package/dist/add/add-secret.js +82 -0
- package/dist/add/add-trigger.d.ts +2 -0
- package/dist/add/add-trigger.js +87 -0
- package/dist/add/add-variable.d.ts +1 -0
- package/dist/add/add-variable.js +8 -0
- package/dist/add/add-workflow-graph.d.ts +7 -0
- package/dist/add/add-workflow-graph.js +396 -0
- package/dist/add/add-workflow.js +124 -26
- package/dist/error-codes.d.ts +16 -1
- package/dist/error-codes.js +21 -1
- package/dist/index.d.ts +9 -5
- package/dist/index.js +5 -2
- package/dist/inspector.d.ts +1 -1
- package/dist/inspector.js +106 -13
- package/dist/schema-generator.d.ts +1 -0
- package/dist/schema-generator.js +1 -0
- package/dist/types-map.js +10 -1
- package/dist/types.d.ts +180 -30
- package/dist/utils/compute-required-schemas.d.ts +4 -0
- package/dist/utils/compute-required-schemas.js +41 -0
- package/dist/utils/contract-hashes.d.ts +35 -0
- package/dist/utils/contract-hashes.js +202 -0
- package/dist/utils/custom-types-generator.d.ts +9 -0
- package/dist/utils/custom-types-generator.js +71 -0
- package/dist/utils/detect-schema-vendor.d.ts +22 -0
- package/dist/utils/detect-schema-vendor.js +76 -0
- package/dist/utils/ensure-function-metadata.d.ts +5 -2
- package/dist/utils/ensure-function-metadata.js +220 -6
- package/dist/utils/extract-function-name.d.ts +5 -16
- package/dist/utils/extract-function-name.js +93 -298
- package/dist/utils/extract-services.d.ts +2 -1
- package/dist/utils/extract-services.js +25 -1
- package/dist/utils/filter-inspector-state.js +107 -23
- package/dist/utils/get-property-value.d.ts +8 -2
- package/dist/utils/get-property-value.js +33 -4
- package/dist/utils/hash.d.ts +2 -0
- package/dist/utils/hash.js +23 -0
- package/dist/utils/middleware.d.ts +7 -30
- package/dist/utils/middleware.js +80 -66
- package/dist/utils/permissions.d.ts +2 -2
- package/dist/utils/permissions.js +10 -10
- package/dist/utils/post-process.d.ts +9 -10
- package/dist/utils/post-process.js +231 -24
- package/dist/utils/resolve-external-package.d.ts +12 -0
- package/dist/utils/resolve-external-package.js +34 -0
- package/dist/utils/resolve-function-types.d.ts +6 -0
- package/dist/utils/resolve-function-types.js +29 -0
- package/dist/utils/resolve-identifier.d.ts +10 -0
- package/dist/utils/resolve-identifier.js +36 -0
- package/dist/utils/resolve-versions.d.ts +2 -0
- package/dist/utils/resolve-versions.js +78 -0
- package/dist/utils/schema-generator.d.ts +9 -0
- package/dist/utils/schema-generator.js +209 -0
- package/dist/utils/serialize-inspector-state.d.ts +73 -13
- package/dist/utils/serialize-inspector-state.js +102 -6
- package/dist/utils/serialize-mcp-json.d.ts +2 -0
- package/dist/utils/serialize-mcp-json.js +99 -0
- package/dist/utils/serialize-middleware-groups-meta.d.ts +12 -0
- package/dist/utils/serialize-middleware-groups-meta.js +28 -0
- package/dist/utils/serialize-openapi-json.d.ts +85 -0
- package/dist/utils/serialize-openapi-json.js +151 -0
- package/dist/utils/serialize-permissions-groups-meta.d.ts +6 -0
- package/dist/utils/serialize-permissions-groups-meta.js +31 -0
- package/dist/utils/workflow/dsl/deserialize-dsl-workflow.d.ts +24 -0
- package/dist/utils/workflow/dsl/deserialize-dsl-workflow.js +830 -0
- package/dist/{workflow/extract-simple-workflow.d.ts → utils/workflow/dsl/extract-dsl-workflow.d.ts} +4 -2
- package/dist/{workflow/extract-simple-workflow.js → utils/workflow/dsl/extract-dsl-workflow.js} +572 -72
- package/dist/utils/workflow/dsl/index.d.ts +7 -0
- package/dist/utils/workflow/dsl/index.js +7 -0
- package/dist/{workflow → utils/workflow/dsl}/patterns.d.ts +21 -0
- package/dist/{workflow → utils/workflow/dsl}/patterns.js +90 -10
- package/dist/{workflow → utils/workflow/dsl}/validation.d.ts +2 -0
- package/dist/{workflow → utils/workflow/dsl}/validation.js +25 -7
- package/dist/utils/workflow/graph/convert-dsl-to-graph.d.ts +13 -0
- package/dist/utils/workflow/graph/convert-dsl-to-graph.js +318 -0
- package/dist/utils/workflow/graph/finalize-workflow-wires.d.ts +3 -0
- package/dist/utils/workflow/graph/finalize-workflow-wires.js +276 -0
- package/dist/utils/workflow/graph/finalize-workflows.d.ts +2 -0
- package/dist/utils/workflow/graph/finalize-workflows.js +75 -0
- package/dist/utils/workflow/graph/index.d.ts +8 -0
- package/dist/utils/workflow/graph/index.js +8 -0
- package/dist/utils/workflow/graph/serialize-workflow-graph.d.ts +35 -0
- package/dist/utils/workflow/graph/serialize-workflow-graph.js +150 -0
- package/dist/utils/workflow/graph/workflow-graph.types.d.ts +203 -0
- package/dist/utils/workflow/graph/workflow-graph.types.js +38 -0
- package/dist/visit.js +13 -2
- package/package.json +26 -4
- package/src/add/add-ai-agent.ts +468 -0
- package/src/add/add-channel.ts +82 -79
- package/src/add/add-cli.ts +49 -20
- package/src/add/add-file-with-factory.ts +2 -0
- package/src/add/add-functions.ts +429 -71
- package/src/add/add-http-route.ts +246 -65
- package/src/add/add-http-routes.ts +228 -0
- package/src/add/add-keyed-wiring.ts +151 -0
- package/src/add/add-mcp-prompt.ts +26 -15
- package/src/add/add-mcp-resource.ts +27 -15
- package/src/add/add-middleware.ts +482 -80
- package/src/add/add-permission.ts +199 -40
- package/src/add/add-queue-worker.ts +24 -19
- package/src/add/add-rpc-invocations.ts +78 -31
- package/src/add/add-schedule.ts +16 -11
- package/src/add/add-secret.ts +140 -0
- package/src/add/add-trigger.ts +154 -0
- package/src/add/add-variable.ts +9 -0
- package/src/add/add-workflow-graph.ts +522 -0
- package/src/add/add-workflow.ts +117 -30
- package/src/error-codes.ts +26 -1
- package/src/index.ts +27 -8
- package/src/inspector.ts +145 -17
- package/src/schema-generator.ts +1 -0
- package/src/types-map.ts +12 -1
- package/src/types.ts +192 -51
- package/src/utils/compute-required-schemas.ts +49 -0
- package/src/utils/contract-hashes.test.ts +528 -0
- package/src/utils/contract-hashes.ts +290 -0
- package/src/utils/custom-types-generator.ts +88 -0
- package/src/utils/detect-schema-vendor.ts +90 -0
- package/src/utils/ensure-function-metadata.ts +324 -7
- package/src/utils/extract-function-name.ts +108 -358
- package/src/utils/extract-services.ts +35 -2
- package/src/utils/filter-inspector-state.test.ts +34 -20
- package/src/utils/filter-inspector-state.ts +140 -31
- package/src/utils/get-property-value.ts +50 -5
- package/src/utils/hash.ts +26 -0
- package/src/utils/middleware.test.ts +204 -0
- package/src/utils/middleware.ts +129 -67
- package/src/utils/permissions.test.ts +35 -12
- package/src/utils/permissions.ts +10 -10
- package/src/utils/post-process.ts +283 -43
- package/src/utils/resolve-external-package.ts +42 -0
- package/src/utils/resolve-function-types.ts +42 -0
- package/src/utils/resolve-identifier.ts +46 -0
- package/src/utils/resolve-versions.test.ts +249 -0
- package/src/utils/resolve-versions.ts +105 -0
- package/src/utils/schema-generator.ts +329 -0
- package/src/utils/serialize-inspector-state.ts +181 -20
- package/src/utils/serialize-mcp-json.ts +145 -0
- package/src/utils/serialize-middleware-groups-meta.ts +33 -0
- package/src/utils/serialize-openapi-json.ts +277 -0
- package/src/utils/serialize-permissions-groups-meta.ts +35 -0
- package/src/utils/test-data/inspector-state.json +69 -66
- package/src/utils/workflow/dsl/deserialize-dsl-workflow.ts +1104 -0
- package/src/{workflow/extract-simple-workflow.ts → utils/workflow/dsl/extract-dsl-workflow.ts} +678 -85
- package/src/utils/workflow/dsl/index.ts +11 -0
- package/src/{workflow → utils/workflow/dsl}/patterns.ts +108 -11
- package/src/{workflow → utils/workflow/dsl}/validation.ts +34 -7
- package/src/utils/workflow/graph/convert-dsl-to-graph.ts +422 -0
- package/src/utils/workflow/graph/finalize-workflow-wires.ts +310 -0
- package/src/utils/workflow/graph/finalize-workflows.ts +100 -0
- package/src/utils/workflow/graph/index.ts +11 -0
- package/src/utils/workflow/graph/serialize-workflow-graph.ts +216 -0
- package/src/utils/workflow/graph/workflow-graph.types.ts +231 -0
- package/src/visit.ts +14 -2
- package/tsconfig.tsbuildinfo +1 -1
- package/dist/add/add-mcp-tool.d.ts +0 -2
- package/dist/add/add-mcp-tool.js +0 -81
- package/dist/utils/extract-service-metadata.d.ts +0 -19
- package/dist/utils/extract-service-metadata.js +0 -244
- package/dist/utils/write-service-metadata.d.ts +0 -13
- package/dist/utils/write-service-metadata.js +0 -37
- package/src/add/add-mcp-tool.ts +0 -141
- package/src/utils/extract-service-metadata.ts +0 -353
- package/src/utils/write-service-metadata.ts +0 -51
|
@@ -1,21 +1,33 @@
|
|
|
1
1
|
import * as ts from 'typescript';
|
|
2
|
-
import { extractFunctionName, isNamedExport, } from '../utils/extract-function-name.js';
|
|
3
|
-
import { extractServicesFromFunction } from '../utils/extract-services.js';
|
|
4
|
-
import {
|
|
2
|
+
import { extractFunctionName, isNamedExport, makeContextBasedId, } from '../utils/extract-function-name.js';
|
|
3
|
+
import { extractServicesFromFunction, extractUsedWires, } from '../utils/extract-services.js';
|
|
4
|
+
import { extractMiddlewareRefs } from '../utils/middleware.js';
|
|
5
5
|
import { getPropertyValue } from '../utils/get-property-value.js';
|
|
6
6
|
import { getPropertyAssignmentInitializer } from '../utils/type-utils.js';
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
function renameTempDefinitions(state, definitionIds, groupType, groupKey, storeKey = 'middleware') {
|
|
8
|
+
const tempIndices = definitionIds
|
|
9
|
+
.map((name, i) => (name.startsWith('__temp_') ? i : -1))
|
|
10
|
+
.filter((i) => i >= 0);
|
|
11
|
+
for (const idx of tempIndices) {
|
|
12
|
+
const oldId = definitionIds[idx];
|
|
13
|
+
const newId = tempIndices.length === 1
|
|
14
|
+
? makeContextBasedId(groupType, groupKey)
|
|
15
|
+
: makeContextBasedId(groupType, groupKey, String(idx));
|
|
16
|
+
const existing = state[storeKey].definitions[oldId];
|
|
17
|
+
if (existing) {
|
|
18
|
+
delete state[storeKey].definitions[oldId];
|
|
19
|
+
state[storeKey].definitions[newId] = existing;
|
|
20
|
+
}
|
|
21
|
+
definitionIds[idx] = newId;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
10
24
|
export const addMiddleware = (logger, node, checker, state) => {
|
|
11
25
|
if (!ts.isCallExpression(node))
|
|
12
26
|
return;
|
|
13
27
|
const { expression, arguments: args } = node;
|
|
14
|
-
// only handle specific function calls
|
|
15
28
|
if (!ts.isIdentifier(expression)) {
|
|
16
29
|
return;
|
|
17
30
|
}
|
|
18
|
-
// Handle pikkuMiddleware(...) - individual middleware function definition
|
|
19
31
|
if (expression.text === 'pikkuMiddleware') {
|
|
20
32
|
const arg = args[0];
|
|
21
33
|
if (!arg)
|
|
@@ -23,14 +35,11 @@ export const addMiddleware = (logger, node, checker, state) => {
|
|
|
23
35
|
let actualHandler;
|
|
24
36
|
let name;
|
|
25
37
|
let description;
|
|
26
|
-
// Check if using object syntax: pikkuMiddleware({ func: ..., name: '...', description: '...' })
|
|
27
38
|
if (ts.isObjectLiteralExpression(arg)) {
|
|
28
|
-
// Extract name and description metadata
|
|
29
39
|
const nameValue = getPropertyValue(arg, 'name');
|
|
30
40
|
const descValue = getPropertyValue(arg, 'description');
|
|
31
41
|
name = typeof nameValue === 'string' ? nameValue : undefined;
|
|
32
42
|
description = typeof descValue === 'string' ? descValue : undefined;
|
|
33
|
-
// Extract the func property
|
|
34
43
|
const fnProp = getPropertyAssignmentInitializer(arg, 'func', true, checker);
|
|
35
44
|
if (!fnProp ||
|
|
36
45
|
(!ts.isArrowFunction(fnProp) && !ts.isFunctionExpression(fnProp))) {
|
|
@@ -47,9 +56,26 @@ export const addMiddleware = (logger, node, checker, state) => {
|
|
|
47
56
|
return;
|
|
48
57
|
}
|
|
49
58
|
const services = extractServicesFromFunction(actualHandler);
|
|
50
|
-
const
|
|
51
|
-
|
|
59
|
+
const wires = extractUsedWires(actualHandler, 1);
|
|
60
|
+
let { pikkuFuncId, exportedName } = extractFunctionName(node, checker, state.rootDir);
|
|
61
|
+
if (pikkuFuncId.startsWith('__temp_')) {
|
|
62
|
+
if (ts.isVariableDeclaration(node.parent) &&
|
|
63
|
+
ts.isIdentifier(node.parent.name)) {
|
|
64
|
+
pikkuFuncId = node.parent.name.text;
|
|
65
|
+
}
|
|
66
|
+
else if (ts.isPropertyAssignment(node.parent) &&
|
|
67
|
+
ts.isIdentifier(node.parent.name)) {
|
|
68
|
+
pikkuFuncId = node.parent.name.text;
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
logger.error(`• pikkuMiddleware() must be assigned to a variable or object property. ` +
|
|
72
|
+
`Extract it to a const: const myMiddleware = pikkuMiddleware(...)`);
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
state.middleware.definitions[pikkuFuncId] = {
|
|
52
77
|
services,
|
|
78
|
+
wires: wires.wires.length > 0 || !wires.optimized ? wires : undefined,
|
|
53
79
|
sourceFile: node.getSourceFile().fileName,
|
|
54
80
|
position: node.getStart(),
|
|
55
81
|
exportedName,
|
|
@@ -59,7 +85,6 @@ export const addMiddleware = (logger, node, checker, state) => {
|
|
|
59
85
|
logger.debug(`• Found middleware with services: ${services.services.join(', ')}${name ? ` (name: ${name})` : ''}${description ? ` (description: ${description})` : ''}`);
|
|
60
86
|
return;
|
|
61
87
|
}
|
|
62
|
-
// Handle pikkuMiddlewareFactory(...) - middleware factory function
|
|
63
88
|
if (expression.text === 'pikkuMiddlewareFactory') {
|
|
64
89
|
const factoryNode = args[0];
|
|
65
90
|
if (!factoryNode)
|
|
@@ -69,10 +94,13 @@ export const addMiddleware = (logger, node, checker, state) => {
|
|
|
69
94
|
logger.error(`• Handler for pikkuMiddlewareFactory is not a function.`);
|
|
70
95
|
return;
|
|
71
96
|
}
|
|
72
|
-
// Extract services by looking inside the factory function body
|
|
73
|
-
// The factory should return pikkuMiddleware(...), so we need to find that call
|
|
74
|
-
// If no wrapper is found, extract from the factory's returned function directly
|
|
75
97
|
let services = { optimized: false, services: [] };
|
|
98
|
+
let wires = {
|
|
99
|
+
optimized: true,
|
|
100
|
+
wires: [],
|
|
101
|
+
};
|
|
102
|
+
let name;
|
|
103
|
+
let description;
|
|
76
104
|
const findPikkuMiddlewareCall = (node) => {
|
|
77
105
|
if (ts.isCallExpression(node)) {
|
|
78
106
|
const expr = node.expression;
|
|
@@ -84,46 +112,70 @@ export const addMiddleware = (logger, node, checker, state) => {
|
|
|
84
112
|
};
|
|
85
113
|
const pikkuMiddlewareCall = findPikkuMiddlewareCall(factoryNode);
|
|
86
114
|
if (pikkuMiddlewareCall && pikkuMiddlewareCall.arguments[0]) {
|
|
87
|
-
const
|
|
88
|
-
if (ts.
|
|
89
|
-
|
|
90
|
-
|
|
115
|
+
const middlewareArg = pikkuMiddlewareCall.arguments[0];
|
|
116
|
+
if (ts.isObjectLiteralExpression(middlewareArg)) {
|
|
117
|
+
const nameValue = getPropertyValue(middlewareArg, 'name');
|
|
118
|
+
const descValue = getPropertyValue(middlewareArg, 'description');
|
|
119
|
+
name = typeof nameValue === 'string' ? nameValue : undefined;
|
|
120
|
+
description = typeof descValue === 'string' ? descValue : undefined;
|
|
121
|
+
const fnProp = getPropertyAssignmentInitializer(middlewareArg, 'func', true, checker);
|
|
122
|
+
if (fnProp &&
|
|
123
|
+
(ts.isArrowFunction(fnProp) || ts.isFunctionExpression(fnProp))) {
|
|
124
|
+
services = extractServicesFromFunction(fnProp);
|
|
125
|
+
wires = extractUsedWires(fnProp, 1);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
else if (ts.isArrowFunction(middlewareArg) ||
|
|
129
|
+
ts.isFunctionExpression(middlewareArg)) {
|
|
130
|
+
services = extractServicesFromFunction(middlewareArg);
|
|
131
|
+
wires = extractUsedWires(middlewareArg, 1);
|
|
91
132
|
}
|
|
92
133
|
}
|
|
93
134
|
else {
|
|
94
|
-
// No pikkuMiddleware wrapper found - extract from factory's return value directly
|
|
95
|
-
// Factory pattern: (config) => (services, wire, next) => { ... }
|
|
96
135
|
if (ts.isArrowFunction(factoryNode) ||
|
|
97
136
|
ts.isFunctionExpression(factoryNode)) {
|
|
98
137
|
const factoryBody = factoryNode.body;
|
|
99
|
-
// Check if the body is an arrow function (direct return)
|
|
100
138
|
if (ts.isArrowFunction(factoryBody) ||
|
|
101
139
|
ts.isFunctionExpression(factoryBody)) {
|
|
102
140
|
services = extractServicesFromFunction(factoryBody);
|
|
141
|
+
wires = extractUsedWires(factoryBody, 1);
|
|
103
142
|
}
|
|
104
143
|
}
|
|
105
144
|
}
|
|
106
|
-
|
|
107
|
-
|
|
145
|
+
let { pikkuFuncId, exportedName } = extractFunctionName(node, checker, state.rootDir);
|
|
146
|
+
if (pikkuFuncId.startsWith('__temp_')) {
|
|
147
|
+
if (ts.isVariableDeclaration(node.parent) &&
|
|
148
|
+
ts.isIdentifier(node.parent.name)) {
|
|
149
|
+
pikkuFuncId = node.parent.name.text;
|
|
150
|
+
}
|
|
151
|
+
else if (ts.isPropertyAssignment(node.parent) &&
|
|
152
|
+
ts.isIdentifier(node.parent.name)) {
|
|
153
|
+
pikkuFuncId = node.parent.name.text;
|
|
154
|
+
}
|
|
155
|
+
else {
|
|
156
|
+
logger.error(`• pikkuMiddlewareFactory() must be assigned to a variable or object property. ` +
|
|
157
|
+
`Extract it to a const: const myMiddleware = pikkuMiddlewareFactory(...)`);
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
state.middleware.definitions[pikkuFuncId] = {
|
|
108
162
|
services,
|
|
163
|
+
wires: wires.wires.length > 0 || !wires.optimized ? wires : undefined,
|
|
109
164
|
sourceFile: node.getSourceFile().fileName,
|
|
110
165
|
position: node.getStart(),
|
|
111
166
|
exportedName,
|
|
112
167
|
factory: true,
|
|
168
|
+
name,
|
|
169
|
+
description,
|
|
113
170
|
};
|
|
114
|
-
logger.debug(`• Found middleware factory with services: ${services.services.join(', ')}`);
|
|
171
|
+
logger.debug(`• Found middleware factory with services: ${services.services.join(', ')}${name ? ` (name: ${name})` : ''}${description ? ` (description: ${description})` : ''}`);
|
|
115
172
|
return;
|
|
116
173
|
}
|
|
117
|
-
// Handle addMiddleware('tag', [middleware1, middleware2])
|
|
118
|
-
// Supports two patterns:
|
|
119
|
-
// 1. export const x = () => addMiddleware('tag', [...]) (factory - tree-shakeable)
|
|
120
|
-
// 2. export const x = addMiddleware('tag', [...]) (direct - no tree-shaking)
|
|
121
174
|
if (expression.text === 'addMiddleware') {
|
|
122
175
|
const tagArg = args[0];
|
|
123
176
|
const middlewareArrayArg = args[1];
|
|
124
177
|
if (!tagArg || !middlewareArrayArg)
|
|
125
178
|
return;
|
|
126
|
-
// Extract tag name
|
|
127
179
|
let tag;
|
|
128
180
|
if (ts.isStringLiteral(tagArg)) {
|
|
129
181
|
tag = tagArg.text;
|
|
@@ -132,43 +184,47 @@ export const addMiddleware = (logger, node, checker, state) => {
|
|
|
132
184
|
logger.warn(`• addMiddleware call without valid tag string`);
|
|
133
185
|
return;
|
|
134
186
|
}
|
|
135
|
-
// Check if middleware array is a literal array
|
|
136
187
|
if (!ts.isArrayLiteralExpression(middlewareArrayArg)) {
|
|
137
188
|
logger.error(`• addMiddleware('${tag}', ...) must have a literal array as second argument`);
|
|
138
189
|
return;
|
|
139
190
|
}
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
if (middlewareNames.length === 0) {
|
|
191
|
+
const refs = extractMiddlewareRefs(middlewareArrayArg, checker, state.rootDir);
|
|
192
|
+
if (refs.length === 0) {
|
|
143
193
|
logger.warn(`• addMiddleware('${tag}', ...) has empty middleware array`);
|
|
144
194
|
return;
|
|
145
195
|
}
|
|
146
|
-
|
|
196
|
+
const definitionIds = refs.map((r) => r.definitionId);
|
|
197
|
+
renameTempDefinitions(state, definitionIds, 'tag', tag);
|
|
198
|
+
const sourceFile = node.getSourceFile().fileName;
|
|
199
|
+
const instanceIds = [];
|
|
200
|
+
for (let i = 0; i < refs.length; i++) {
|
|
201
|
+
const instanceId = makeContextBasedId('tag', tag, String(i));
|
|
202
|
+
state.middleware.instances[instanceId] = {
|
|
203
|
+
definitionId: definitionIds[i],
|
|
204
|
+
sourceFile,
|
|
205
|
+
position: node.getStart(),
|
|
206
|
+
isFactoryCall: refs[i].isFactoryCall,
|
|
207
|
+
};
|
|
208
|
+
instanceIds.push(instanceId);
|
|
209
|
+
}
|
|
147
210
|
const allServices = new Set();
|
|
148
|
-
for (const
|
|
149
|
-
const
|
|
150
|
-
if (
|
|
151
|
-
for (const service of
|
|
211
|
+
for (const defId of definitionIds) {
|
|
212
|
+
const def = state.middleware.definitions[defId];
|
|
213
|
+
if (def?.services) {
|
|
214
|
+
for (const service of def.services.services) {
|
|
152
215
|
allServices.add(service);
|
|
153
216
|
}
|
|
154
217
|
}
|
|
155
218
|
}
|
|
156
|
-
// Check if this call is wrapped in a factory function
|
|
157
|
-
// We need to walk up the tree to see if the parent is: const x = () => addMiddleware(...)
|
|
158
219
|
let isFactory = false;
|
|
159
220
|
let exportedName = null;
|
|
160
221
|
let parent = node.parent;
|
|
161
|
-
// Check if parent is arrow function: () => addMiddleware(...)
|
|
162
222
|
if (parent && ts.isArrowFunction(parent)) {
|
|
163
|
-
// Check if arrow function has no parameters
|
|
164
223
|
if (parent.parameters.length === 0) {
|
|
165
224
|
isFactory = true;
|
|
166
|
-
// For factories, we need to check the arrow function's parent for the export name
|
|
167
|
-
// const apiTagMiddleware = () => addMiddleware(...)
|
|
168
225
|
const arrowParent = parent.parent;
|
|
169
226
|
if (arrowParent && ts.isVariableDeclaration(arrowParent)) {
|
|
170
227
|
if (ts.isIdentifier(arrowParent.name)) {
|
|
171
|
-
// Check if it's exported
|
|
172
228
|
if (isNamedExport(arrowParent)) {
|
|
173
229
|
exportedName = arrowParent.name.text;
|
|
174
230
|
}
|
|
@@ -176,41 +232,34 @@ export const addMiddleware = (logger, node, checker, state) => {
|
|
|
176
232
|
}
|
|
177
233
|
}
|
|
178
234
|
}
|
|
179
|
-
// If not a factory, get export name from the call expression itself
|
|
180
235
|
if (!isFactory) {
|
|
181
236
|
const extracted = extractFunctionName(node, checker, state.rootDir);
|
|
182
237
|
exportedName = extracted.exportedName;
|
|
183
238
|
}
|
|
184
|
-
// Log warning if not using factory pattern
|
|
185
239
|
if (!isFactory && exportedName) {
|
|
186
240
|
logger.warn(`• Middleware group '${exportedName}' for tag '${tag}' is not wrapped in a factory function. ` +
|
|
187
241
|
`For tree-shaking, use: export const ${exportedName} = () => addMiddleware('${tag}', [...])`);
|
|
188
242
|
}
|
|
189
|
-
// Store group metadata
|
|
190
243
|
state.middleware.tagMiddleware.set(tag, {
|
|
191
244
|
exportName: exportedName,
|
|
192
|
-
sourceFile
|
|
245
|
+
sourceFile,
|
|
193
246
|
position: node.getStart(),
|
|
194
247
|
services: {
|
|
195
248
|
optimized: false,
|
|
196
249
|
services: Array.from(allServices),
|
|
197
250
|
},
|
|
198
|
-
|
|
251
|
+
count: refs.length,
|
|
252
|
+
instanceIds,
|
|
199
253
|
isFactory,
|
|
200
254
|
});
|
|
201
|
-
logger.debug(`• Found tag middleware group: ${tag} -> [${
|
|
255
|
+
logger.debug(`• Found tag middleware group: ${tag} -> [${instanceIds.join(', ')}] (${isFactory ? 'factory' : 'direct'})`);
|
|
202
256
|
return;
|
|
203
257
|
}
|
|
204
|
-
// Handle addHTTPMiddleware(pattern, [middleware1, middleware2])
|
|
205
|
-
// Supports two patterns:
|
|
206
|
-
// 1. export const x = () => addHTTPMiddleware('*', [...]) (factory - tree-shakeable)
|
|
207
|
-
// 2. export const x = addHTTPMiddleware('*', [...]) (direct - no tree-shaking)
|
|
208
258
|
if (expression.text === 'addHTTPMiddleware') {
|
|
209
259
|
const patternArg = args[0];
|
|
210
260
|
const middlewareArrayArg = args[1];
|
|
211
261
|
if (!patternArg || !middlewareArrayArg)
|
|
212
262
|
return;
|
|
213
|
-
// Extract route pattern
|
|
214
263
|
let pattern;
|
|
215
264
|
if (ts.isStringLiteral(patternArg)) {
|
|
216
265
|
pattern = patternArg.text;
|
|
@@ -219,42 +268,47 @@ export const addMiddleware = (logger, node, checker, state) => {
|
|
|
219
268
|
logger.warn(`• addHTTPMiddleware call without valid pattern string`);
|
|
220
269
|
return;
|
|
221
270
|
}
|
|
222
|
-
// Check if middleware array is a literal array
|
|
223
271
|
if (!ts.isArrayLiteralExpression(middlewareArrayArg)) {
|
|
224
272
|
logger.error(`• addHTTPMiddleware('${pattern}', ...) must have a literal array as second argument`);
|
|
225
273
|
return;
|
|
226
274
|
}
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
if (middlewareNames.length === 0) {
|
|
275
|
+
const refs = extractMiddlewareRefs(middlewareArrayArg, checker, state.rootDir);
|
|
276
|
+
if (refs.length === 0) {
|
|
230
277
|
logger.warn(`• addHTTPMiddleware('${pattern}', ...) has empty middleware array`);
|
|
231
278
|
return;
|
|
232
279
|
}
|
|
233
|
-
|
|
280
|
+
const definitionIds = refs.map((r) => r.definitionId);
|
|
281
|
+
renameTempDefinitions(state, definitionIds, 'http', pattern);
|
|
282
|
+
const sourceFile = node.getSourceFile().fileName;
|
|
283
|
+
const instanceIds = [];
|
|
284
|
+
for (let i = 0; i < refs.length; i++) {
|
|
285
|
+
const instanceId = makeContextBasedId('http', pattern, String(i));
|
|
286
|
+
state.middleware.instances[instanceId] = {
|
|
287
|
+
definitionId: definitionIds[i],
|
|
288
|
+
sourceFile,
|
|
289
|
+
position: node.getStart(),
|
|
290
|
+
isFactoryCall: refs[i].isFactoryCall,
|
|
291
|
+
};
|
|
292
|
+
instanceIds.push(instanceId);
|
|
293
|
+
}
|
|
234
294
|
const allServices = new Set();
|
|
235
|
-
for (const
|
|
236
|
-
const
|
|
237
|
-
if (
|
|
238
|
-
for (const service of
|
|
295
|
+
for (const defId of definitionIds) {
|
|
296
|
+
const def = state.middleware.definitions[defId];
|
|
297
|
+
if (def?.services) {
|
|
298
|
+
for (const service of def.services.services) {
|
|
239
299
|
allServices.add(service);
|
|
240
300
|
}
|
|
241
301
|
}
|
|
242
302
|
}
|
|
243
|
-
// Check if this call is wrapped in a factory function
|
|
244
303
|
let isFactory = false;
|
|
245
304
|
let exportedName = null;
|
|
246
305
|
let parent = node.parent;
|
|
247
|
-
// Check if parent is arrow function: () => addHTTPMiddleware(...)
|
|
248
306
|
if (parent && ts.isArrowFunction(parent)) {
|
|
249
|
-
// Check if arrow function has no parameters
|
|
250
307
|
if (parent.parameters.length === 0) {
|
|
251
308
|
isFactory = true;
|
|
252
|
-
// For factories, we need to check the arrow function's parent for the export name
|
|
253
|
-
// const apiRouteMiddleware = () => addHTTPMiddleware(...)
|
|
254
309
|
const arrowParent = parent.parent;
|
|
255
310
|
if (arrowParent && ts.isVariableDeclaration(arrowParent)) {
|
|
256
311
|
if (ts.isIdentifier(arrowParent.name)) {
|
|
257
|
-
// Check if it's exported
|
|
258
312
|
if (isNamedExport(arrowParent)) {
|
|
259
313
|
exportedName = arrowParent.name.text;
|
|
260
314
|
}
|
|
@@ -262,29 +316,260 @@ export const addMiddleware = (logger, node, checker, state) => {
|
|
|
262
316
|
}
|
|
263
317
|
}
|
|
264
318
|
}
|
|
265
|
-
// If not a factory, get export name from the call expression itself
|
|
266
319
|
if (!isFactory) {
|
|
267
320
|
const extracted = extractFunctionName(node, checker, state.rootDir);
|
|
268
321
|
exportedName = extracted.exportedName;
|
|
269
322
|
}
|
|
270
|
-
// Log warning if not using factory pattern
|
|
271
323
|
if (!isFactory && exportedName) {
|
|
272
324
|
logger.warn(`• HTTP middleware group '${exportedName}' for pattern '${pattern}' is not wrapped in a factory function. ` +
|
|
273
325
|
`For tree-shaking, use: export const ${exportedName} = () => addHTTPMiddleware('${pattern}', [...])`);
|
|
274
326
|
}
|
|
275
|
-
// Store group metadata
|
|
276
327
|
state.http.routeMiddleware.set(pattern, {
|
|
277
328
|
exportName: exportedName,
|
|
329
|
+
sourceFile,
|
|
330
|
+
position: node.getStart(),
|
|
331
|
+
services: {
|
|
332
|
+
optimized: false,
|
|
333
|
+
services: Array.from(allServices),
|
|
334
|
+
},
|
|
335
|
+
count: refs.length,
|
|
336
|
+
instanceIds,
|
|
337
|
+
isFactory,
|
|
338
|
+
});
|
|
339
|
+
logger.debug(`• Found HTTP route middleware group: ${pattern} -> [${instanceIds.join(', ')}] (${isFactory ? 'factory' : 'direct'})`);
|
|
340
|
+
return;
|
|
341
|
+
}
|
|
342
|
+
if (expression.text === 'pikkuChannelMiddleware') {
|
|
343
|
+
const arg = args[0];
|
|
344
|
+
if (!arg)
|
|
345
|
+
return;
|
|
346
|
+
let actualHandler;
|
|
347
|
+
if (ts.isArrowFunction(arg) || ts.isFunctionExpression(arg)) {
|
|
348
|
+
actualHandler = arg;
|
|
349
|
+
}
|
|
350
|
+
else {
|
|
351
|
+
logger.error(`• Handler for pikkuChannelMiddleware is not a function.`);
|
|
352
|
+
return;
|
|
353
|
+
}
|
|
354
|
+
const services = extractServicesFromFunction(actualHandler);
|
|
355
|
+
let { pikkuFuncId, exportedName } = extractFunctionName(node, checker, state.rootDir);
|
|
356
|
+
if (pikkuFuncId.startsWith('__temp_')) {
|
|
357
|
+
if (ts.isVariableDeclaration(node.parent) &&
|
|
358
|
+
ts.isIdentifier(node.parent.name)) {
|
|
359
|
+
pikkuFuncId = node.parent.name.text;
|
|
360
|
+
}
|
|
361
|
+
else if (ts.isPropertyAssignment(node.parent) &&
|
|
362
|
+
ts.isIdentifier(node.parent.name)) {
|
|
363
|
+
pikkuFuncId = node.parent.name.text;
|
|
364
|
+
}
|
|
365
|
+
else {
|
|
366
|
+
logger.error(`• pikkuChannelMiddleware() must be assigned to a variable or object property. ` +
|
|
367
|
+
`Extract it to a const: const myMiddleware = pikkuChannelMiddleware(...)`);
|
|
368
|
+
return;
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
state.channelMiddleware.definitions[pikkuFuncId] = {
|
|
372
|
+
services,
|
|
278
373
|
sourceFile: node.getSourceFile().fileName,
|
|
279
374
|
position: node.getStart(),
|
|
375
|
+
exportedName,
|
|
376
|
+
};
|
|
377
|
+
logger.debug(`• Found channel middleware with services: ${services.services.join(', ')}`);
|
|
378
|
+
return;
|
|
379
|
+
}
|
|
380
|
+
if (expression.text === 'pikkuChannelMiddlewareFactory') {
|
|
381
|
+
const factoryNode = args[0];
|
|
382
|
+
if (!factoryNode)
|
|
383
|
+
return;
|
|
384
|
+
if (!ts.isArrowFunction(factoryNode) &&
|
|
385
|
+
!ts.isFunctionExpression(factoryNode)) {
|
|
386
|
+
logger.error(`• Handler for pikkuChannelMiddlewareFactory is not a function.`);
|
|
387
|
+
return;
|
|
388
|
+
}
|
|
389
|
+
let services = { optimized: false, services: [] };
|
|
390
|
+
const findPikkuChannelMiddlewareCall = (n) => {
|
|
391
|
+
if (ts.isCallExpression(n)) {
|
|
392
|
+
const expr = n.expression;
|
|
393
|
+
if (ts.isIdentifier(expr) && expr.text === 'pikkuChannelMiddleware') {
|
|
394
|
+
return n;
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
return ts.forEachChild(n, findPikkuChannelMiddlewareCall);
|
|
398
|
+
};
|
|
399
|
+
const channelMiddlewareCall = findPikkuChannelMiddlewareCall(factoryNode);
|
|
400
|
+
if (channelMiddlewareCall && channelMiddlewareCall.arguments[0]) {
|
|
401
|
+
const middlewareHandler = channelMiddlewareCall.arguments[0];
|
|
402
|
+
if (ts.isArrowFunction(middlewareHandler) ||
|
|
403
|
+
ts.isFunctionExpression(middlewareHandler)) {
|
|
404
|
+
services = extractServicesFromFunction(middlewareHandler);
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
else {
|
|
408
|
+
if (ts.isArrowFunction(factoryNode) ||
|
|
409
|
+
ts.isFunctionExpression(factoryNode)) {
|
|
410
|
+
const factoryBody = factoryNode.body;
|
|
411
|
+
if (ts.isArrowFunction(factoryBody) ||
|
|
412
|
+
ts.isFunctionExpression(factoryBody)) {
|
|
413
|
+
services = extractServicesFromFunction(factoryBody);
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
let { pikkuFuncId, exportedName } = extractFunctionName(node, checker, state.rootDir);
|
|
418
|
+
if (pikkuFuncId.startsWith('__temp_')) {
|
|
419
|
+
if (ts.isVariableDeclaration(node.parent) &&
|
|
420
|
+
ts.isIdentifier(node.parent.name)) {
|
|
421
|
+
pikkuFuncId = node.parent.name.text;
|
|
422
|
+
}
|
|
423
|
+
else if (ts.isPropertyAssignment(node.parent) &&
|
|
424
|
+
ts.isIdentifier(node.parent.name)) {
|
|
425
|
+
pikkuFuncId = node.parent.name.text;
|
|
426
|
+
}
|
|
427
|
+
else {
|
|
428
|
+
logger.error(`• pikkuChannelMiddlewareFactory() must be assigned to a variable or object property. ` +
|
|
429
|
+
`Extract it to a const: const myMiddleware = pikkuChannelMiddlewareFactory(...)`);
|
|
430
|
+
return;
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
state.channelMiddleware.definitions[pikkuFuncId] = {
|
|
434
|
+
services,
|
|
435
|
+
sourceFile: node.getSourceFile().fileName,
|
|
436
|
+
position: node.getStart(),
|
|
437
|
+
exportedName,
|
|
438
|
+
factory: true,
|
|
439
|
+
};
|
|
440
|
+
logger.debug(`• Found channel middleware factory with services: ${services.services.join(', ')}`);
|
|
441
|
+
return;
|
|
442
|
+
}
|
|
443
|
+
if (expression.text === 'pikkuAIMiddleware') {
|
|
444
|
+
const arg = args[0];
|
|
445
|
+
if (!arg)
|
|
446
|
+
return;
|
|
447
|
+
if (!ts.isObjectLiteralExpression(arg)) {
|
|
448
|
+
logger.error(`• pikkuAIMiddleware() requires an object literal argument.`);
|
|
449
|
+
return;
|
|
450
|
+
}
|
|
451
|
+
const allServices = new Set();
|
|
452
|
+
for (const prop of arg.properties) {
|
|
453
|
+
if (ts.isPropertyAssignment(prop) &&
|
|
454
|
+
(ts.isArrowFunction(prop.initializer) ||
|
|
455
|
+
ts.isFunctionExpression(prop.initializer))) {
|
|
456
|
+
const hookServices = extractServicesFromFunction(prop.initializer);
|
|
457
|
+
for (const s of hookServices.services) {
|
|
458
|
+
allServices.add(s);
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
const services = {
|
|
463
|
+
optimized: allServices.size > 0,
|
|
464
|
+
services: Array.from(allServices),
|
|
465
|
+
};
|
|
466
|
+
let { pikkuFuncId, exportedName } = extractFunctionName(node, checker, state.rootDir);
|
|
467
|
+
if (pikkuFuncId.startsWith('__temp_')) {
|
|
468
|
+
if (ts.isVariableDeclaration(node.parent) &&
|
|
469
|
+
ts.isIdentifier(node.parent.name)) {
|
|
470
|
+
pikkuFuncId = node.parent.name.text;
|
|
471
|
+
}
|
|
472
|
+
else if (ts.isPropertyAssignment(node.parent) &&
|
|
473
|
+
ts.isIdentifier(node.parent.name)) {
|
|
474
|
+
pikkuFuncId = node.parent.name.text;
|
|
475
|
+
}
|
|
476
|
+
else {
|
|
477
|
+
logger.error(`• pikkuAIMiddleware() must be assigned to a variable or object property. ` +
|
|
478
|
+
`Extract it to a const: const myMiddleware = pikkuAIMiddleware(...)`);
|
|
479
|
+
return;
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
state.aiMiddleware.definitions[pikkuFuncId] = {
|
|
483
|
+
services,
|
|
484
|
+
sourceFile: node.getSourceFile().fileName,
|
|
485
|
+
position: node.getStart(),
|
|
486
|
+
exportedName,
|
|
487
|
+
};
|
|
488
|
+
logger.debug(`• Found AI middleware with services: ${services.services.join(', ')}`);
|
|
489
|
+
return;
|
|
490
|
+
}
|
|
491
|
+
if (expression.text === 'addChannelMiddleware') {
|
|
492
|
+
const tagArg = args[0];
|
|
493
|
+
const middlewareArrayArg = args[1];
|
|
494
|
+
if (!tagArg || !middlewareArrayArg)
|
|
495
|
+
return;
|
|
496
|
+
let tag;
|
|
497
|
+
if (ts.isStringLiteral(tagArg)) {
|
|
498
|
+
tag = tagArg.text;
|
|
499
|
+
}
|
|
500
|
+
if (!tag) {
|
|
501
|
+
logger.warn(`• addChannelMiddleware call without valid tag string`);
|
|
502
|
+
return;
|
|
503
|
+
}
|
|
504
|
+
if (!ts.isArrayLiteralExpression(middlewareArrayArg)) {
|
|
505
|
+
logger.error(`• addChannelMiddleware('${tag}', ...) must have a literal array as second argument`);
|
|
506
|
+
return;
|
|
507
|
+
}
|
|
508
|
+
const refs = extractMiddlewareRefs(middlewareArrayArg, checker, state.rootDir);
|
|
509
|
+
if (refs.length === 0) {
|
|
510
|
+
logger.warn(`• addChannelMiddleware('${tag}', ...) has empty middleware array`);
|
|
511
|
+
return;
|
|
512
|
+
}
|
|
513
|
+
const definitionIds = refs.map((r) => r.definitionId);
|
|
514
|
+
renameTempDefinitions(state, definitionIds, 'tag', tag, 'channelMiddleware');
|
|
515
|
+
const sourceFile = node.getSourceFile().fileName;
|
|
516
|
+
const instanceIds = [];
|
|
517
|
+
for (let i = 0; i < refs.length; i++) {
|
|
518
|
+
const instanceId = makeContextBasedId('tag', tag, String(i));
|
|
519
|
+
state.channelMiddleware.instances[instanceId] = {
|
|
520
|
+
definitionId: definitionIds[i],
|
|
521
|
+
sourceFile,
|
|
522
|
+
position: node.getStart(),
|
|
523
|
+
isFactoryCall: refs[i].isFactoryCall,
|
|
524
|
+
};
|
|
525
|
+
instanceIds.push(instanceId);
|
|
526
|
+
}
|
|
527
|
+
const allServices = new Set();
|
|
528
|
+
for (const defId of definitionIds) {
|
|
529
|
+
const def = state.channelMiddleware.definitions[defId];
|
|
530
|
+
if (def?.services) {
|
|
531
|
+
for (const service of def.services.services) {
|
|
532
|
+
allServices.add(service);
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
let isFactory = false;
|
|
537
|
+
let exportedName = null;
|
|
538
|
+
let parent = node.parent;
|
|
539
|
+
if (parent && ts.isArrowFunction(parent)) {
|
|
540
|
+
if (parent.parameters.length === 0) {
|
|
541
|
+
isFactory = true;
|
|
542
|
+
const arrowParent = parent.parent;
|
|
543
|
+
if (arrowParent && ts.isVariableDeclaration(arrowParent)) {
|
|
544
|
+
if (ts.isIdentifier(arrowParent.name)) {
|
|
545
|
+
if (isNamedExport(arrowParent)) {
|
|
546
|
+
exportedName = arrowParent.name.text;
|
|
547
|
+
}
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
}
|
|
551
|
+
}
|
|
552
|
+
if (!isFactory) {
|
|
553
|
+
const extracted = extractFunctionName(node, checker, state.rootDir);
|
|
554
|
+
exportedName = extracted.exportedName;
|
|
555
|
+
}
|
|
556
|
+
if (!isFactory && exportedName) {
|
|
557
|
+
logger.warn(`• Channel middleware group '${exportedName}' for tag '${tag}' is not wrapped in a factory function. ` +
|
|
558
|
+
`For tree-shaking, use: export const ${exportedName} = () => addChannelMiddleware('${tag}', [...])`);
|
|
559
|
+
}
|
|
560
|
+
state.channelMiddleware.tagMiddleware.set(tag, {
|
|
561
|
+
exportName: exportedName,
|
|
562
|
+
sourceFile,
|
|
563
|
+
position: node.getStart(),
|
|
280
564
|
services: {
|
|
281
565
|
optimized: false,
|
|
282
566
|
services: Array.from(allServices),
|
|
283
567
|
},
|
|
284
|
-
|
|
568
|
+
count: refs.length,
|
|
569
|
+
instanceIds,
|
|
285
570
|
isFactory,
|
|
286
571
|
});
|
|
287
|
-
logger.debug(`• Found
|
|
572
|
+
logger.debug(`• Found tag channel middleware group: ${tag} -> [${instanceIds.join(', ')}] (${isFactory ? 'factory' : 'direct'})`);
|
|
288
573
|
return;
|
|
289
574
|
}
|
|
290
575
|
};
|