@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,4 +1,7 @@
|
|
|
1
|
+
import { parseVersionedId } from '@pikku/core';
|
|
1
2
|
import { aggregateRequiredServices } from './post-process.js';
|
|
3
|
+
// Module-level Set to track warned groups across multiple filter calls
|
|
4
|
+
const globalWarnedGroups = new Set();
|
|
2
5
|
/**
|
|
3
6
|
* Match a value against a pattern with wildcard support
|
|
4
7
|
* Supports "*" at the beginning, end, or both (e.g., "send*", "*Payment", "*process*")
|
|
@@ -27,7 +30,7 @@ function matchesWildcard(value, pattern) {
|
|
|
27
30
|
/**
|
|
28
31
|
* Check if metadata matches the given filters
|
|
29
32
|
*/
|
|
30
|
-
function matchesFilters(filters, meta, logger) {
|
|
33
|
+
function matchesFilters(filters, meta, logger, warnedGroups) {
|
|
31
34
|
// If no filters, allow everything
|
|
32
35
|
if (Object.keys(filters).length === 0)
|
|
33
36
|
return true;
|
|
@@ -66,9 +69,11 @@ function matchesFilters(filters, meta, logger) {
|
|
|
66
69
|
return false;
|
|
67
70
|
}
|
|
68
71
|
}
|
|
69
|
-
// Check name filter
|
|
72
|
+
// Check name filter (match against both full ID and base name for versioned functions)
|
|
70
73
|
if (filters.names && filters.names.length > 0) {
|
|
71
|
-
const
|
|
74
|
+
const { baseName } = parseVersionedId(meta.name);
|
|
75
|
+
const nameMatches = filters.names.some((pattern) => matchesWildcard(meta.name, pattern) ||
|
|
76
|
+
(baseName !== meta.name && matchesWildcard(baseName, pattern)));
|
|
72
77
|
if (!nameMatches) {
|
|
73
78
|
logger.debug(`⒡ Filtered by name: ${meta.type}:${meta.name}`);
|
|
74
79
|
return false;
|
|
@@ -81,6 +86,17 @@ function matchesFilters(filters, meta, logger) {
|
|
|
81
86
|
logger.debug(`⒡ Filtered by HTTP route: ${meta.httpRoute}`);
|
|
82
87
|
return false;
|
|
83
88
|
}
|
|
89
|
+
// If route is part of a wireHTTPRoutes group, check if filter is at group level
|
|
90
|
+
if (meta.groupBasePath && warnedGroups) {
|
|
91
|
+
const groupMatches = filters.httpRoutes.some((pattern) => matchesWildcard(meta.groupBasePath, pattern) ||
|
|
92
|
+
matchesWildcard(meta.groupBasePath + '/*', pattern));
|
|
93
|
+
if (!groupMatches && !warnedGroups.has(meta.groupBasePath)) {
|
|
94
|
+
warnedGroups.add(meta.groupBasePath);
|
|
95
|
+
logger.warn(`Filtering within wireHTTPRoutes group is not yet supported. ` +
|
|
96
|
+
`Route '${meta.httpRoute}' is part of group '${meta.groupBasePath}'. ` +
|
|
97
|
+
`Use '--httpRoutes=${meta.groupBasePath}/*' to filter the entire group.`);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
84
100
|
}
|
|
85
101
|
// Check HTTP method filter
|
|
86
102
|
if (filters.httpMethods &&
|
|
@@ -143,6 +159,11 @@ export function filterInspectorState(state, filters, logger) {
|
|
|
143
159
|
meta: JSON.parse(JSON.stringify(state.channels.meta)),
|
|
144
160
|
files: new Set(), // Will be repopulated with filtered files
|
|
145
161
|
},
|
|
162
|
+
triggers: {
|
|
163
|
+
...state.triggers,
|
|
164
|
+
meta: JSON.parse(JSON.stringify(state.triggers?.meta ?? {})),
|
|
165
|
+
files: new Set(),
|
|
166
|
+
},
|
|
146
167
|
scheduledTasks: {
|
|
147
168
|
...state.scheduledTasks,
|
|
148
169
|
meta: JSON.parse(JSON.stringify(state.scheduledTasks.meta)),
|
|
@@ -158,7 +179,12 @@ export function filterInspectorState(state, filters, logger) {
|
|
|
158
179
|
toolsMeta: JSON.parse(JSON.stringify(state.mcpEndpoints.toolsMeta)),
|
|
159
180
|
resourcesMeta: JSON.parse(JSON.stringify(state.mcpEndpoints.resourcesMeta)),
|
|
160
181
|
promptsMeta: JSON.parse(JSON.stringify(state.mcpEndpoints.promptsMeta)),
|
|
161
|
-
files: new Set(),
|
|
182
|
+
files: new Set(),
|
|
183
|
+
},
|
|
184
|
+
agents: {
|
|
185
|
+
...state.agents,
|
|
186
|
+
agentsMeta: JSON.parse(JSON.stringify(state.agents?.agentsMeta ?? {})),
|
|
187
|
+
files: new Map(),
|
|
162
188
|
},
|
|
163
189
|
cli: {
|
|
164
190
|
...state.cli,
|
|
@@ -172,23 +198,24 @@ export function filterInspectorState(state, filters, logger) {
|
|
|
172
198
|
for (const route of Object.keys(routes)) {
|
|
173
199
|
const routeMeta = routes[route];
|
|
174
200
|
// Get function file path for directory filtering
|
|
175
|
-
const funcFile = filteredState.functions.files.get(routeMeta.
|
|
201
|
+
const funcFile = filteredState.functions.files.get(routeMeta.pikkuFuncId);
|
|
176
202
|
const filePath = funcFile?.path;
|
|
177
203
|
const matches = matchesFilters(filters, {
|
|
178
204
|
type: 'http',
|
|
179
|
-
name: routeMeta.
|
|
205
|
+
name: routeMeta.pikkuFuncId, // Use function name, not route
|
|
180
206
|
tags: routeMeta.tags,
|
|
181
207
|
filePath,
|
|
182
208
|
httpRoute: routeMeta.route,
|
|
183
209
|
httpMethod: routeMeta.method,
|
|
184
|
-
|
|
210
|
+
groupBasePath: routeMeta.groupBasePath,
|
|
211
|
+
}, logger, globalWarnedGroups);
|
|
185
212
|
if (!matches) {
|
|
186
213
|
delete routes[route];
|
|
187
214
|
}
|
|
188
215
|
else {
|
|
189
216
|
// Track used functions/middleware/permissions
|
|
190
|
-
if (routeMeta.
|
|
191
|
-
filteredState.serviceAggregation.usedFunctions.add(routeMeta.
|
|
217
|
+
if (routeMeta.pikkuFuncId) {
|
|
218
|
+
filteredState.serviceAggregation.usedFunctions.add(routeMeta.pikkuFuncId);
|
|
192
219
|
}
|
|
193
220
|
extractWireNames(routeMeta.middleware).forEach((name) => filteredState.serviceAggregation.usedMiddleware.add(name));
|
|
194
221
|
extractWireNames(routeMeta.permissions).forEach((name) => filteredState.serviceAggregation.usedPermissions.add(name));
|
|
@@ -212,8 +239,8 @@ export function filterInspectorState(state, filters, logger) {
|
|
|
212
239
|
delete filteredState.channels.meta[name];
|
|
213
240
|
}
|
|
214
241
|
else {
|
|
215
|
-
if (channelMeta.
|
|
216
|
-
filteredState.serviceAggregation.usedFunctions.add(channelMeta.
|
|
242
|
+
if (channelMeta.pikkuFuncId) {
|
|
243
|
+
filteredState.serviceAggregation.usedFunctions.add(channelMeta.pikkuFuncId);
|
|
217
244
|
}
|
|
218
245
|
extractWireNames(channelMeta.middleware).forEach((name) => filteredState.serviceAggregation.usedMiddleware.add(name));
|
|
219
246
|
extractWireNames(channelMeta.permissions).forEach((name) => filteredState.serviceAggregation.usedPermissions.add(name));
|
|
@@ -223,6 +250,27 @@ export function filterInspectorState(state, filters, logger) {
|
|
|
223
250
|
if (Object.keys(filteredState.channels.meta).length > 0) {
|
|
224
251
|
filteredState.channels.files = new Set(state.channels.files);
|
|
225
252
|
}
|
|
253
|
+
// Filter triggers
|
|
254
|
+
for (const name of Object.keys(filteredState.triggers.meta)) {
|
|
255
|
+
const triggerMeta = filteredState.triggers.meta[name];
|
|
256
|
+
const matches = matchesFilters(filters, {
|
|
257
|
+
type: 'trigger',
|
|
258
|
+
name,
|
|
259
|
+
tags: triggerMeta.tags,
|
|
260
|
+
}, logger);
|
|
261
|
+
if (!matches) {
|
|
262
|
+
delete filteredState.triggers.meta[name];
|
|
263
|
+
}
|
|
264
|
+
else {
|
|
265
|
+
if (triggerMeta.pikkuFuncId) {
|
|
266
|
+
filteredState.serviceAggregation.usedFunctions.add(triggerMeta.pikkuFuncId);
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
// Repopulate triggers.files if any triggers remain
|
|
271
|
+
if (Object.keys(filteredState.triggers.meta).length > 0) {
|
|
272
|
+
filteredState.triggers.files = new Set(state.triggers.files);
|
|
273
|
+
}
|
|
226
274
|
// Filter scheduled tasks
|
|
227
275
|
for (const name of Object.keys(filteredState.scheduledTasks.meta)) {
|
|
228
276
|
const taskMeta = filteredState.scheduledTasks.meta[name];
|
|
@@ -235,8 +283,8 @@ export function filterInspectorState(state, filters, logger) {
|
|
|
235
283
|
delete filteredState.scheduledTasks.meta[name];
|
|
236
284
|
}
|
|
237
285
|
else {
|
|
238
|
-
if (taskMeta.
|
|
239
|
-
filteredState.serviceAggregation.usedFunctions.add(taskMeta.
|
|
286
|
+
if (taskMeta.pikkuFuncId) {
|
|
287
|
+
filteredState.serviceAggregation.usedFunctions.add(taskMeta.pikkuFuncId);
|
|
240
288
|
}
|
|
241
289
|
extractWireNames(taskMeta.middleware).forEach((name) => filteredState.serviceAggregation.usedMiddleware.add(name));
|
|
242
290
|
}
|
|
@@ -257,8 +305,8 @@ export function filterInspectorState(state, filters, logger) {
|
|
|
257
305
|
delete filteredState.queueWorkers.meta[name];
|
|
258
306
|
}
|
|
259
307
|
else {
|
|
260
|
-
if (workerMeta.
|
|
261
|
-
filteredState.serviceAggregation.usedFunctions.add(workerMeta.
|
|
308
|
+
if (workerMeta.pikkuFuncId) {
|
|
309
|
+
filteredState.serviceAggregation.usedFunctions.add(workerMeta.pikkuFuncId);
|
|
262
310
|
}
|
|
263
311
|
extractWireNames(workerMeta.middleware).forEach((name) => filteredState.serviceAggregation.usedMiddleware.add(name));
|
|
264
312
|
}
|
|
@@ -279,8 +327,8 @@ export function filterInspectorState(state, filters, logger) {
|
|
|
279
327
|
delete filteredState.mcpEndpoints.toolsMeta[name];
|
|
280
328
|
}
|
|
281
329
|
else {
|
|
282
|
-
if (toolMeta.
|
|
283
|
-
filteredState.serviceAggregation.usedFunctions.add(toolMeta.
|
|
330
|
+
if (toolMeta.pikkuFuncId) {
|
|
331
|
+
filteredState.serviceAggregation.usedFunctions.add(toolMeta.pikkuFuncId);
|
|
284
332
|
}
|
|
285
333
|
extractWireNames(toolMeta.middleware).forEach((name) => filteredState.serviceAggregation.usedMiddleware.add(name));
|
|
286
334
|
extractWireNames(toolMeta.permissions).forEach((name) => filteredState.serviceAggregation.usedPermissions.add(name));
|
|
@@ -298,8 +346,8 @@ export function filterInspectorState(state, filters, logger) {
|
|
|
298
346
|
delete filteredState.mcpEndpoints.resourcesMeta[name];
|
|
299
347
|
}
|
|
300
348
|
else {
|
|
301
|
-
if (resourceMeta.
|
|
302
|
-
filteredState.serviceAggregation.usedFunctions.add(resourceMeta.
|
|
349
|
+
if (resourceMeta.pikkuFuncId) {
|
|
350
|
+
filteredState.serviceAggregation.usedFunctions.add(resourceMeta.pikkuFuncId);
|
|
303
351
|
}
|
|
304
352
|
extractWireNames(resourceMeta.middleware).forEach((name) => filteredState.serviceAggregation.usedMiddleware.add(name));
|
|
305
353
|
extractWireNames(resourceMeta.permissions).forEach((name) => filteredState.serviceAggregation.usedPermissions.add(name));
|
|
@@ -317,8 +365,8 @@ export function filterInspectorState(state, filters, logger) {
|
|
|
317
365
|
delete filteredState.mcpEndpoints.promptsMeta[name];
|
|
318
366
|
}
|
|
319
367
|
else {
|
|
320
|
-
if (promptMeta.
|
|
321
|
-
filteredState.serviceAggregation.usedFunctions.add(promptMeta.
|
|
368
|
+
if (promptMeta.pikkuFuncId) {
|
|
369
|
+
filteredState.serviceAggregation.usedFunctions.add(promptMeta.pikkuFuncId);
|
|
322
370
|
}
|
|
323
371
|
extractWireNames(promptMeta.middleware).forEach((name) => filteredState.serviceAggregation.usedMiddleware.add(name));
|
|
324
372
|
extractWireNames(promptMeta.permissions).forEach((name) => filteredState.serviceAggregation.usedPermissions.add(name));
|
|
@@ -331,6 +379,28 @@ export function filterInspectorState(state, filters, logger) {
|
|
|
331
379
|
if (hasMcpEndpoints) {
|
|
332
380
|
filteredState.mcpEndpoints.files = new Set(state.mcpEndpoints.files);
|
|
333
381
|
}
|
|
382
|
+
// Filter AI agents
|
|
383
|
+
for (const name of Object.keys(filteredState.agents.agentsMeta)) {
|
|
384
|
+
const agentMeta = filteredState.agents.agentsMeta[name];
|
|
385
|
+
const matches = matchesFilters(filters, {
|
|
386
|
+
type: 'agent',
|
|
387
|
+
name,
|
|
388
|
+
tags: agentMeta.tags,
|
|
389
|
+
}, logger);
|
|
390
|
+
if (!matches) {
|
|
391
|
+
delete filteredState.agents.agentsMeta[name];
|
|
392
|
+
}
|
|
393
|
+
else {
|
|
394
|
+
if (agentMeta.pikkuFuncId) {
|
|
395
|
+
filteredState.serviceAggregation.usedFunctions.add(agentMeta.pikkuFuncId);
|
|
396
|
+
}
|
|
397
|
+
extractWireNames(agentMeta.middleware).forEach((name) => filteredState.serviceAggregation.usedMiddleware.add(name));
|
|
398
|
+
extractWireNames(agentMeta.permissions).forEach((name) => filteredState.serviceAggregation.usedPermissions.add(name));
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
if (Object.keys(filteredState.agents.agentsMeta).length > 0) {
|
|
402
|
+
filteredState.agents.files = new Map(state.agents.files);
|
|
403
|
+
}
|
|
334
404
|
// Filter CLI programs (note: CLI filtering might be more complex with nested commands)
|
|
335
405
|
const referencedRenderers = new Set();
|
|
336
406
|
for (const programName of Object.keys(filteredState.cli.meta.programs)) {
|
|
@@ -347,8 +417,8 @@ export function filterInspectorState(state, filters, logger) {
|
|
|
347
417
|
delete programMeta.commands[commandName];
|
|
348
418
|
}
|
|
349
419
|
else {
|
|
350
|
-
if (commandMeta.
|
|
351
|
-
filteredState.serviceAggregation.usedFunctions.add(commandMeta.
|
|
420
|
+
if (commandMeta.pikkuFuncId) {
|
|
421
|
+
filteredState.serviceAggregation.usedFunctions.add(commandMeta.pikkuFuncId);
|
|
352
422
|
}
|
|
353
423
|
extractWireNames(commandMeta.middleware).forEach((name) => filteredState.serviceAggregation.usedMiddleware.add(name));
|
|
354
424
|
// Track referenced renderers
|
|
@@ -374,6 +444,20 @@ export function filterInspectorState(state, filters, logger) {
|
|
|
374
444
|
if (hasCliPrograms || hasCliRenderers) {
|
|
375
445
|
filteredState.cli.files = new Set(state.cli.files);
|
|
376
446
|
}
|
|
447
|
+
// Post-filter version expansion: include all versions of matched functions
|
|
448
|
+
const includedBaseNames = new Set();
|
|
449
|
+
for (const funcId of filteredState.serviceAggregation.usedFunctions) {
|
|
450
|
+
const { baseName } = parseVersionedId(funcId);
|
|
451
|
+
includedBaseNames.add(baseName);
|
|
452
|
+
}
|
|
453
|
+
if (includedBaseNames.size > 0) {
|
|
454
|
+
for (const funcId of Object.keys(state.functions.meta)) {
|
|
455
|
+
const { baseName } = parseVersionedId(funcId);
|
|
456
|
+
if (includedBaseNames.has(baseName)) {
|
|
457
|
+
filteredState.serviceAggregation.usedFunctions.add(funcId);
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
}
|
|
377
461
|
// Recalculate requiredServices based on filtered functions/middleware/permissions
|
|
378
462
|
// Need to cast to InspectorState temporarily for aggregateRequiredServices
|
|
379
463
|
const stateForAggregation = filteredState;
|
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
import * as ts from 'typescript';
|
|
2
2
|
import { ErrorCode } from '../error-codes.js';
|
|
3
|
-
export declare const getPropertyValue: (obj: ts.ObjectLiteralExpression, propertyName: string) => string | string[] | null | boolean;
|
|
4
3
|
/**
|
|
5
|
-
* Extracts
|
|
4
|
+
* Extracts an array of strings from an object property.
|
|
5
|
+
*/
|
|
6
|
+
export declare const getArrayPropertyValue: (obj: ts.ObjectLiteralExpression, propertyName: string) => string[] | null;
|
|
7
|
+
export declare const getPropertyValue: (obj: ts.ObjectLiteralExpression, propertyName: string) => string | string[] | number | null | boolean;
|
|
8
|
+
/**
|
|
9
|
+
* Extracts common wire metadata (title, tags, summary, description, errors) directly from an object
|
|
6
10
|
* @param obj - The TypeScript object literal expression to extract metadata from
|
|
7
11
|
* @param wiringType - The type of wiring (e.g., 'HTTP route', 'Channel', 'Queue worker')
|
|
8
12
|
* @param wiringName - The name/identifier of the wiring (e.g., route path, channel name)
|
|
@@ -12,6 +16,8 @@ export declare const getPropertyValue: (obj: ts.ObjectLiteralExpression, propert
|
|
|
12
16
|
export declare const getCommonWireMetaData: (obj: ts.ObjectLiteralExpression, wiringType: string, wiringName: string | null, logger?: {
|
|
13
17
|
critical: (code: ErrorCode, message: string) => void;
|
|
14
18
|
}) => {
|
|
19
|
+
disabled?: true;
|
|
20
|
+
title?: string;
|
|
15
21
|
tags?: string[];
|
|
16
22
|
summary?: string;
|
|
17
23
|
description?: string;
|
|
@@ -1,5 +1,22 @@
|
|
|
1
1
|
import * as ts from 'typescript';
|
|
2
2
|
import { ErrorCode } from '../error-codes.js';
|
|
3
|
+
/**
|
|
4
|
+
* Extracts an array of strings from an object property.
|
|
5
|
+
*/
|
|
6
|
+
export const getArrayPropertyValue = (obj, propertyName) => {
|
|
7
|
+
const property = obj.properties.find((p) => ts.isPropertyAssignment(p) &&
|
|
8
|
+
ts.isIdentifier(p.name) &&
|
|
9
|
+
p.name.text === propertyName);
|
|
10
|
+
if (property && ts.isPropertyAssignment(property)) {
|
|
11
|
+
const initializer = property.initializer;
|
|
12
|
+
if (ts.isArrayLiteralExpression(initializer)) {
|
|
13
|
+
return initializer.elements
|
|
14
|
+
.filter(ts.isStringLiteral)
|
|
15
|
+
.map((element) => element.text);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
return null;
|
|
19
|
+
};
|
|
3
20
|
export const getPropertyValue = (obj, propertyName) => {
|
|
4
21
|
const property = obj.properties.find((p) => ts.isPropertyAssignment(p) &&
|
|
5
22
|
ts.isIdentifier(p.name) &&
|
|
@@ -26,18 +43,22 @@ export const getPropertyValue = (obj, propertyName) => {
|
|
|
26
43
|
if (initializer.kind === ts.SyntaxKind.FalseKeyword) {
|
|
27
44
|
return false;
|
|
28
45
|
}
|
|
29
|
-
|
|
46
|
+
if (ts.isNumericLiteral(initializer)) {
|
|
47
|
+
if (propertyName === 'name' || propertyName === 'schedule') {
|
|
48
|
+
return initializer.text;
|
|
49
|
+
}
|
|
50
|
+
return Number(initializer.text);
|
|
51
|
+
}
|
|
30
52
|
if (ts.isStringLiteral(initializer) ||
|
|
31
53
|
ts.isNoSubstitutionTemplateLiteral(initializer)) {
|
|
32
54
|
return initializer.text;
|
|
33
55
|
}
|
|
34
|
-
// Handle other initializer types if necessary
|
|
35
56
|
return initializer.getText();
|
|
36
57
|
}
|
|
37
58
|
return null;
|
|
38
59
|
};
|
|
39
60
|
/**
|
|
40
|
-
* Extracts common wire metadata (tags, summary, description, errors) directly from an object
|
|
61
|
+
* Extracts common wire metadata (title, tags, summary, description, errors) directly from an object
|
|
41
62
|
* @param obj - The TypeScript object literal expression to extract metadata from
|
|
42
63
|
* @param wiringType - The type of wiring (e.g., 'HTTP route', 'Channel', 'Queue worker')
|
|
43
64
|
* @param wiringName - The name/identifier of the wiring (e.g., route path, channel name)
|
|
@@ -49,7 +70,15 @@ export const getCommonWireMetaData = (obj, wiringType, wiringName, logger) => {
|
|
|
49
70
|
obj.properties.forEach((prop) => {
|
|
50
71
|
if (ts.isPropertyAssignment(prop) && ts.isIdentifier(prop.name)) {
|
|
51
72
|
const propName = prop.name.text;
|
|
52
|
-
if (propName === '
|
|
73
|
+
if (propName === 'disabled' &&
|
|
74
|
+
prop.initializer.kind === ts.SyntaxKind.TrueKeyword) {
|
|
75
|
+
metadata.disabled = true;
|
|
76
|
+
}
|
|
77
|
+
else if (propName === 'title' && ts.isStringLiteral(prop.initializer)) {
|
|
78
|
+
metadata.title = prop.initializer.text;
|
|
79
|
+
}
|
|
80
|
+
else if (propName === 'summary' &&
|
|
81
|
+
ts.isStringLiteral(prop.initializer)) {
|
|
53
82
|
metadata.summary = prop.initializer.text;
|
|
54
83
|
}
|
|
55
84
|
else if (propName === 'description' &&
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { createHash } from 'crypto';
|
|
2
|
+
export function canonicalJSON(obj) {
|
|
3
|
+
return JSON.stringify(sortDeep(obj));
|
|
4
|
+
}
|
|
5
|
+
function sortDeep(value) {
|
|
6
|
+
if (value === null || value === undefined) {
|
|
7
|
+
return value;
|
|
8
|
+
}
|
|
9
|
+
if (Array.isArray(value)) {
|
|
10
|
+
return value.map(sortDeep);
|
|
11
|
+
}
|
|
12
|
+
if (typeof value === 'object') {
|
|
13
|
+
const sorted = {};
|
|
14
|
+
for (const key of Object.keys(value).sort()) {
|
|
15
|
+
sorted[key] = sortDeep(value[key]);
|
|
16
|
+
}
|
|
17
|
+
return sorted;
|
|
18
|
+
}
|
|
19
|
+
return value;
|
|
20
|
+
}
|
|
21
|
+
export function hashString(input, length = 16) {
|
|
22
|
+
return createHash('sha256').update(input).digest('hex').slice(0, length);
|
|
23
|
+
}
|
|
@@ -1,39 +1,16 @@
|
|
|
1
1
|
import * as ts from 'typescript';
|
|
2
2
|
import { MiddlewareMetadata } from '@pikku/core';
|
|
3
3
|
import { InspectorState } from '../types.js';
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
4
|
+
export interface MiddlewareRef {
|
|
5
|
+
definitionId: string;
|
|
6
|
+
isFactoryCall: boolean;
|
|
7
|
+
}
|
|
8
|
+
export declare function extractMiddlewareRefs(arrayNode: ts.Expression, checker: ts.TypeChecker, rootDir: string): MiddlewareRef[];
|
|
9
9
|
export declare function extractMiddlewarePikkuNames(arrayNode: ts.Expression, checker: ts.TypeChecker, rootDir: string): string[];
|
|
10
|
-
/**
|
|
11
|
-
* Get middleware array from an object literal expression property
|
|
12
|
-
* Returns the initializer node for the 'middleware' property if it exists
|
|
13
|
-
*/
|
|
14
10
|
export declare function getMiddlewareNode(obj: ts.ObjectLiteralExpression): ts.Expression | undefined;
|
|
15
|
-
/**
|
|
16
|
-
* Check if a route matches a pattern with wildcards
|
|
17
|
-
* Pattern can be exact match or use * as wildcard
|
|
18
|
-
* e.g., '/api/*' matches '/api/users', '/api/posts/123', etc.
|
|
19
|
-
*/
|
|
20
11
|
export declare function routeMatchesPattern(route: string, pattern: string): boolean;
|
|
21
|
-
/**
|
|
22
|
-
* Resolve middleware for an HTTP wiring based on:
|
|
23
|
-
* 1. Global HTTP middleware (addd([...]))
|
|
24
|
-
* 2. Route-specific HTTP middleware (addHTTPMiddleware('/pattern', [...]))
|
|
25
|
-
* 3. Tag-based middleware (addMiddleware('tag', [...]))
|
|
26
|
-
* 4. Explicit wiring middleware (wireHTTP({ middleware: [...] }))
|
|
27
|
-
* Returns undefined if no middleware is found, otherwise returns array with at least one item
|
|
28
|
-
*/
|
|
29
12
|
export declare function resolveHTTPMiddleware(state: InspectorState, route: string, tags: string[] | undefined, explicitMiddlewareNode: ts.Expression | undefined, checker: ts.TypeChecker): MiddlewareMetadata[] | undefined;
|
|
30
|
-
/**
|
|
31
|
-
* Convenience wrapper: Extract middleware node from object and resolve
|
|
32
|
-
* Use this in add-* files for cleaner code
|
|
33
|
-
*/
|
|
34
13
|
export declare function resolveMiddleware(state: InspectorState, obj: ts.ObjectLiteralExpression, tags: string[] | undefined, checker: ts.TypeChecker): MiddlewareMetadata[] | undefined;
|
|
35
|
-
/**
|
|
36
|
-
* Convenience wrapper for HTTP: Extract middleware and resolve with HTTP-specific logic
|
|
37
|
-
* Use this in add-http-route.ts for cleaner code
|
|
38
|
-
*/
|
|
39
14
|
export declare function resolveHTTPMiddlewareFromObject(state: InspectorState, route: string, obj: ts.ObjectLiteralExpression, tags: string[] | undefined, checker: ts.TypeChecker): MiddlewareMetadata[] | undefined;
|
|
15
|
+
export declare function resolveAIMiddleware(state: InspectorState, obj: ts.ObjectLiteralExpression, checker: ts.TypeChecker): MiddlewareMetadata[] | undefined;
|
|
16
|
+
export declare function resolveChannelMiddleware(state: InspectorState, obj: ts.ObjectLiteralExpression, tags: string[] | undefined, checker: ts.TypeChecker): MiddlewareMetadata[] | undefined;
|
package/dist/utils/middleware.js
CHANGED
|
@@ -1,80 +1,64 @@
|
|
|
1
1
|
import * as ts from 'typescript';
|
|
2
2
|
import { extractFunctionName } from './extract-function-name.js';
|
|
3
|
-
|
|
4
|
-
* Extract middleware pikkuFuncNames from an array literal expression
|
|
5
|
-
* Resolves each identifier to its pikkuFuncName using extractFunctionName
|
|
6
|
-
* Also handles call expressions (like logCommandInfoAndTime({...}))
|
|
7
|
-
*/
|
|
8
|
-
export function extractMiddlewarePikkuNames(arrayNode, checker, rootDir) {
|
|
3
|
+
export function extractMiddlewareRefs(arrayNode, checker, rootDir) {
|
|
9
4
|
if (!ts.isArrayLiteralExpression(arrayNode)) {
|
|
10
5
|
return [];
|
|
11
6
|
}
|
|
12
|
-
const
|
|
7
|
+
const refs = [];
|
|
13
8
|
for (const element of arrayNode.elements) {
|
|
14
9
|
if (ts.isIdentifier(element)) {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
10
|
+
const { pikkuFuncId } = extractFunctionName(element, checker, rootDir);
|
|
11
|
+
refs.push({
|
|
12
|
+
definitionId: pikkuFuncId.startsWith('__temp_')
|
|
13
|
+
? element.text
|
|
14
|
+
: pikkuFuncId,
|
|
15
|
+
isFactoryCall: false,
|
|
16
|
+
});
|
|
18
17
|
}
|
|
19
18
|
else if (ts.isCallExpression(element)) {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
19
|
+
const { pikkuFuncId } = extractFunctionName(element.expression, checker, rootDir);
|
|
20
|
+
refs.push({
|
|
21
|
+
definitionId: pikkuFuncId.startsWith('__temp_') &&
|
|
22
|
+
ts.isIdentifier(element.expression)
|
|
23
|
+
? element.expression.text
|
|
24
|
+
: pikkuFuncId,
|
|
25
|
+
isFactoryCall: true,
|
|
26
|
+
});
|
|
24
27
|
}
|
|
25
28
|
}
|
|
26
|
-
return
|
|
29
|
+
return refs;
|
|
30
|
+
}
|
|
31
|
+
export function extractMiddlewarePikkuNames(arrayNode, checker, rootDir) {
|
|
32
|
+
return extractMiddlewareRefs(arrayNode, checker, rootDir).map((r) => r.definitionId);
|
|
27
33
|
}
|
|
28
|
-
/**
|
|
29
|
-
* Get middleware array from an object literal expression property
|
|
30
|
-
* Returns the initializer node for the 'middleware' property if it exists
|
|
31
|
-
*/
|
|
32
34
|
export function getMiddlewareNode(obj) {
|
|
33
35
|
const middlewareProp = obj.properties.find((p) => ts.isPropertyAssignment(p) &&
|
|
34
36
|
ts.isIdentifier(p.name) &&
|
|
35
37
|
p.name.text === 'middleware');
|
|
36
38
|
return middlewareProp?.initializer;
|
|
37
39
|
}
|
|
38
|
-
/**
|
|
39
|
-
* Check if a route matches a pattern with wildcards
|
|
40
|
-
* Pattern can be exact match or use * as wildcard
|
|
41
|
-
* e.g., '/api/*' matches '/api/users', '/api/posts/123', etc.
|
|
42
|
-
*/
|
|
43
40
|
export function routeMatchesPattern(route, pattern) {
|
|
44
41
|
if (route === pattern)
|
|
45
42
|
return true;
|
|
46
|
-
// Convert pattern to regex: replace * with .*
|
|
47
43
|
const regexPattern = pattern
|
|
48
|
-
.replace(/[.+?^${}()|[\]\\]/g, '\\$&')
|
|
49
|
-
.replace(/\*/g, '.*');
|
|
44
|
+
.replace(/[.+?^${}()|[\]\\]/g, '\\$&')
|
|
45
|
+
.replace(/\*/g, '.*');
|
|
50
46
|
const regex = new RegExp(`^${regexPattern}$`);
|
|
51
47
|
return regex.test(route);
|
|
52
48
|
}
|
|
53
|
-
/**
|
|
54
|
-
* Resolve middleware for an HTTP wiring based on:
|
|
55
|
-
* 1. Global HTTP middleware (addd([...]))
|
|
56
|
-
* 2. Route-specific HTTP middleware (addHTTPMiddleware('/pattern', [...]))
|
|
57
|
-
* 3. Tag-based middleware (addMiddleware('tag', [...]))
|
|
58
|
-
* 4. Explicit wiring middleware (wireHTTP({ middleware: [...] }))
|
|
59
|
-
* Returns undefined if no middleware is found, otherwise returns array with at least one item
|
|
60
|
-
*/
|
|
61
49
|
export function resolveHTTPMiddleware(state, route, tags, explicitMiddlewareNode, checker) {
|
|
62
50
|
const resolved = [];
|
|
63
|
-
// 1. HTTP route middleware groups (includes '*' for global)
|
|
64
51
|
for (const [pattern, _groupMeta] of state.http.routeMiddleware.entries()) {
|
|
65
52
|
if (routeMatchesPattern(route, pattern)) {
|
|
66
|
-
// Just reference the group by route pattern
|
|
67
53
|
resolved.push({
|
|
68
54
|
type: 'http',
|
|
69
55
|
route: pattern,
|
|
70
56
|
});
|
|
71
57
|
}
|
|
72
58
|
}
|
|
73
|
-
// 2. Tag-based middleware groups
|
|
74
59
|
if (tags && tags.length > 0) {
|
|
75
60
|
for (const tag of tags) {
|
|
76
61
|
if (state.middleware.tagMiddleware.has(tag)) {
|
|
77
|
-
// Just reference the group by tag
|
|
78
62
|
resolved.push({
|
|
79
63
|
type: 'tag',
|
|
80
64
|
tag,
|
|
@@ -82,32 +66,24 @@ export function resolveHTTPMiddleware(state, route, tags, explicitMiddlewareNode
|
|
|
82
66
|
}
|
|
83
67
|
}
|
|
84
68
|
}
|
|
85
|
-
// 3. Explicit wire middleware (inline is OK here)
|
|
86
69
|
if (explicitMiddlewareNode) {
|
|
87
70
|
const middlewareNames = extractMiddlewarePikkuNames(explicitMiddlewareNode, checker, state.rootDir);
|
|
88
71
|
for (const name of middlewareNames) {
|
|
89
|
-
const
|
|
72
|
+
const def = state.middleware.definitions[name];
|
|
90
73
|
resolved.push({
|
|
91
74
|
type: 'wire',
|
|
92
75
|
name,
|
|
93
|
-
inline:
|
|
76
|
+
inline: def?.exportedName === null,
|
|
94
77
|
});
|
|
95
78
|
}
|
|
96
79
|
}
|
|
97
80
|
return resolved.length > 0 ? resolved : undefined;
|
|
98
81
|
}
|
|
99
|
-
/**
|
|
100
|
-
* Resolve tag-based and explicit middleware (common logic for wires and functions)
|
|
101
|
-
* 1. Tag-based middleware (addMiddleware('tag', [...]))
|
|
102
|
-
* 2. Explicit middleware (wireHTTP/pikkuFunc({ middleware: [...] }))
|
|
103
|
-
*/
|
|
104
82
|
function resolveTagAndExplicitMiddleware(state, tags, explicitMiddlewareNode, checker) {
|
|
105
83
|
const resolved = [];
|
|
106
|
-
// 1. Tag-based middleware groups
|
|
107
84
|
if (tags && tags.length > 0) {
|
|
108
85
|
for (const tag of tags) {
|
|
109
86
|
if (state.middleware.tagMiddleware.has(tag)) {
|
|
110
|
-
// Just reference the group by tag
|
|
111
87
|
resolved.push({
|
|
112
88
|
type: 'tag',
|
|
113
89
|
tag,
|
|
@@ -115,43 +91,81 @@ function resolveTagAndExplicitMiddleware(state, tags, explicitMiddlewareNode, ch
|
|
|
115
91
|
}
|
|
116
92
|
}
|
|
117
93
|
}
|
|
118
|
-
// 2. Explicit middleware (inline is OK here - used directly in wire/function)
|
|
119
94
|
if (explicitMiddlewareNode) {
|
|
120
95
|
const middlewareNames = extractMiddlewarePikkuNames(explicitMiddlewareNode, checker, state.rootDir);
|
|
121
96
|
for (const name of middlewareNames) {
|
|
122
|
-
const
|
|
97
|
+
const def = state.middleware.definitions[name];
|
|
123
98
|
resolved.push({
|
|
124
99
|
type: 'wire',
|
|
125
100
|
name,
|
|
126
|
-
inline:
|
|
101
|
+
inline: def?.exportedName === null,
|
|
127
102
|
});
|
|
128
103
|
}
|
|
129
104
|
}
|
|
130
105
|
return resolved;
|
|
131
106
|
}
|
|
132
|
-
/**
|
|
133
|
-
* Resolve middleware for a function based on:
|
|
134
|
-
* 1. Tag-based middleware (addMiddleware('tag', [...]))
|
|
135
|
-
* 2. Explicit function middleware (pikkuFunc({ middleware: [...] }))
|
|
136
|
-
* Returns undefined if no middleware is found, otherwise returns array with at least one item
|
|
137
|
-
*/
|
|
138
107
|
function resolveFunctionMiddlewareInternal(state, tags, explicitMiddlewareNode, checker) {
|
|
139
108
|
const resolved = resolveTagAndExplicitMiddleware(state, tags, explicitMiddlewareNode, checker);
|
|
140
109
|
return resolved.length > 0 ? resolved : undefined;
|
|
141
110
|
}
|
|
142
|
-
/**
|
|
143
|
-
* Convenience wrapper: Extract middleware node from object and resolve
|
|
144
|
-
* Use this in add-* files for cleaner code
|
|
145
|
-
*/
|
|
146
111
|
export function resolveMiddleware(state, obj, tags, checker) {
|
|
147
112
|
const explicitMiddlewareNode = getMiddlewareNode(obj);
|
|
148
113
|
return resolveFunctionMiddlewareInternal(state, tags, explicitMiddlewareNode, checker);
|
|
149
114
|
}
|
|
150
|
-
/**
|
|
151
|
-
* Convenience wrapper for HTTP: Extract middleware and resolve with HTTP-specific logic
|
|
152
|
-
* Use this in add-http-route.ts for cleaner code
|
|
153
|
-
*/
|
|
154
115
|
export function resolveHTTPMiddlewareFromObject(state, route, obj, tags, checker) {
|
|
155
116
|
const explicitMiddlewareNode = getMiddlewareNode(obj);
|
|
156
117
|
return resolveHTTPMiddleware(state, route, tags, explicitMiddlewareNode, checker);
|
|
157
118
|
}
|
|
119
|
+
function getAIMiddlewareNode(obj) {
|
|
120
|
+
const prop = obj.properties.find((p) => ts.isPropertyAssignment(p) &&
|
|
121
|
+
ts.isIdentifier(p.name) &&
|
|
122
|
+
p.name.text === 'aiMiddleware');
|
|
123
|
+
return prop?.initializer;
|
|
124
|
+
}
|
|
125
|
+
export function resolveAIMiddleware(state, obj, checker) {
|
|
126
|
+
const explicitNode = getAIMiddlewareNode(obj);
|
|
127
|
+
if (!explicitNode)
|
|
128
|
+
return undefined;
|
|
129
|
+
const names = extractMiddlewarePikkuNames(explicitNode, checker, state.rootDir);
|
|
130
|
+
const resolved = names.map((name) => {
|
|
131
|
+
const def = state.aiMiddleware.definitions[name];
|
|
132
|
+
return {
|
|
133
|
+
type: 'wire',
|
|
134
|
+
name,
|
|
135
|
+
inline: def?.exportedName === null,
|
|
136
|
+
};
|
|
137
|
+
});
|
|
138
|
+
return resolved.length > 0 ? resolved : undefined;
|
|
139
|
+
}
|
|
140
|
+
function getChannelMiddlewareNode(obj) {
|
|
141
|
+
const prop = obj.properties.find((p) => ts.isPropertyAssignment(p) &&
|
|
142
|
+
ts.isIdentifier(p.name) &&
|
|
143
|
+
p.name.text === 'channelMiddleware');
|
|
144
|
+
return prop?.initializer;
|
|
145
|
+
}
|
|
146
|
+
export function resolveChannelMiddleware(state, obj, tags, checker) {
|
|
147
|
+
const resolved = [];
|
|
148
|
+
if (tags && tags.length > 0) {
|
|
149
|
+
for (const tag of tags) {
|
|
150
|
+
if (state.channelMiddleware.tagMiddleware.has(tag)) {
|
|
151
|
+
resolved.push({
|
|
152
|
+
type: 'tag',
|
|
153
|
+
tag,
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
const explicitNode = getChannelMiddlewareNode(obj);
|
|
159
|
+
if (explicitNode) {
|
|
160
|
+
const names = extractMiddlewarePikkuNames(explicitNode, checker, state.rootDir);
|
|
161
|
+
for (const name of names) {
|
|
162
|
+
const def = state.channelMiddleware.definitions[name];
|
|
163
|
+
resolved.push({
|
|
164
|
+
type: 'wire',
|
|
165
|
+
name,
|
|
166
|
+
inline: def?.exportedName === null,
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
return resolved.length > 0 ? resolved : undefined;
|
|
171
|
+
}
|