@pikku/inspector 0.12.10 → 0.12.12
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 +21 -9
- package/dist/add/add-cli.js +10 -3
- package/dist/add/add-credential.js +2 -1
- package/dist/add/add-functions.js +99 -5
- package/dist/add/add-http-route.js +44 -6
- package/dist/add/add-keyed-wiring.js +3 -1
- package/dist/add/add-middleware.js +33 -4
- package/dist/add/add-permission.js +7 -7
- package/dist/add/add-workflow-graph.js +20 -1
- package/dist/error-codes.d.ts +2 -0
- package/dist/error-codes.js +2 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/inspector.js +2 -5
- package/dist/types.d.ts +10 -19
- package/dist/utils/extract-function-name.js +6 -0
- package/dist/utils/filter-inspector-state.js +187 -59
- package/dist/utils/filter-utils.js +13 -5
- package/dist/utils/get-property-value.d.ts +10 -0
- package/dist/utils/get-property-value.js +30 -0
- package/dist/utils/post-process.d.ts +2 -3
- package/dist/utils/post-process.js +3 -23
- package/dist/utils/resolve-addon-package.d.ts +4 -5
- package/dist/utils/resolve-addon-package.js +64 -16
- package/dist/utils/resolve-deploy-target.d.ts +28 -0
- package/dist/utils/resolve-deploy-target.js +56 -0
- package/dist/utils/resolve-versions.js +79 -0
- package/dist/utils/schema-generator.js +31 -12
- package/dist/utils/validate-auth-sessionless.d.ts +1 -1
- package/package.json +2 -2
- package/src/add/add-cli.ts +10 -3
- package/src/add/add-credential.ts +3 -0
- package/src/add/add-functions.test.ts +318 -0
- package/src/add/add-functions.ts +164 -6
- package/src/add/add-gateway.ts +5 -1
- package/src/add/add-http-route.ts +54 -7
- package/src/add/add-keyed-wiring.ts +7 -1
- package/src/add/add-mcp-prompt.ts +5 -1
- package/src/add/add-mcp-resource.ts +5 -1
- package/src/add/add-middleware.ts +42 -4
- package/src/add/add-permission.ts +7 -7
- package/src/add/add-schedule.ts +5 -1
- package/src/add/add-workflow-graph.ts +19 -1
- package/src/add/wire-name-literal.test.ts +114 -0
- package/src/error-codes.ts +2 -0
- package/src/index.ts +1 -0
- package/src/inspector.ts +1 -5
- package/src/types.ts +19 -15
- package/src/utils/extract-function-name.ts +8 -0
- package/src/utils/filter-inspector-state.test.ts +168 -64
- package/src/utils/filter-inspector-state.ts +290 -64
- package/src/utils/filter-utils.test.ts +30 -15
- package/src/utils/filter-utils.ts +14 -5
- package/src/utils/get-property-value.ts +40 -0
- package/src/utils/post-process.ts +3 -38
- package/src/utils/resolve-addon-package.ts +65 -14
- package/src/utils/resolve-deploy-target.test.ts +105 -0
- package/src/utils/resolve-deploy-target.ts +63 -0
- package/src/utils/resolve-versions.test.ts +108 -0
- package/src/utils/resolve-versions.ts +86 -0
- package/src/utils/schema-generator.ts +37 -13
- package/src/utils/validate-auth-sessionless.ts +1 -1
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -6,6 +6,7 @@ import type {
|
|
|
6
6
|
import type { PikkuWiringTypes } from '@pikku/core'
|
|
7
7
|
import { parseVersionedId } from '@pikku/core'
|
|
8
8
|
import { aggregateRequiredServices } from './post-process.js'
|
|
9
|
+
import { resolveDeployTarget } from './resolve-deploy-target.js'
|
|
9
10
|
|
|
10
11
|
// Module-level Set to track warned groups across multiple filter calls
|
|
11
12
|
const globalWarnedGroups = new Set<string>()
|
|
@@ -35,6 +36,59 @@ function matchesWildcard(value: string, pattern: string): boolean {
|
|
|
35
36
|
return value === pattern
|
|
36
37
|
}
|
|
37
38
|
|
|
39
|
+
function collectSourceFiles(
|
|
40
|
+
value: unknown,
|
|
41
|
+
sourceFiles = new Set<string>(),
|
|
42
|
+
seen = new Set<object>()
|
|
43
|
+
): Set<string> {
|
|
44
|
+
if (typeof value === 'string') {
|
|
45
|
+
return sourceFiles
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
if (Array.isArray(value)) {
|
|
49
|
+
for (const entry of value) {
|
|
50
|
+
collectSourceFiles(entry, sourceFiles, seen)
|
|
51
|
+
}
|
|
52
|
+
return sourceFiles
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
if (!value || typeof value !== 'object') {
|
|
56
|
+
return sourceFiles
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
if (seen.has(value)) {
|
|
60
|
+
return sourceFiles
|
|
61
|
+
}
|
|
62
|
+
seen.add(value)
|
|
63
|
+
|
|
64
|
+
if ('sourceFile' in value && typeof value.sourceFile === 'string') {
|
|
65
|
+
sourceFiles.add(value.sourceFile)
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
for (const nestedValue of Object.values(value)) {
|
|
69
|
+
collectSourceFiles(nestedValue, sourceFiles, seen)
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
return sourceFiles
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
function repopulateFileSetFromMeta(
|
|
76
|
+
meta: unknown,
|
|
77
|
+
fallbackFiles: Set<string>,
|
|
78
|
+
hasEntries: boolean
|
|
79
|
+
): Set<string> {
|
|
80
|
+
const sourceFiles = collectSourceFiles(meta)
|
|
81
|
+
if (sourceFiles.size > 0) {
|
|
82
|
+
return sourceFiles
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
if (hasEntries) {
|
|
86
|
+
return new Set(fallbackFiles)
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
return new Set<string>()
|
|
90
|
+
}
|
|
91
|
+
|
|
38
92
|
/**
|
|
39
93
|
* Check if metadata matches the given filters
|
|
40
94
|
*/
|
|
@@ -50,7 +104,10 @@ function matchesFilters(
|
|
|
50
104
|
groupBasePath?: string
|
|
51
105
|
},
|
|
52
106
|
logger: InspectorLogger,
|
|
53
|
-
warnedGroups?: Set<string
|
|
107
|
+
warnedGroups?: Set<string>,
|
|
108
|
+
// Set of pikkuFuncIds to keep based on the deploy filter; null when
|
|
109
|
+
// the deploy filter is inactive.
|
|
110
|
+
keptByDeploy?: Set<string> | null
|
|
54
111
|
): boolean {
|
|
55
112
|
// If no filters, allow everything
|
|
56
113
|
if (Object.keys(filters).length === 0) return true
|
|
@@ -59,18 +116,41 @@ function matchesFilters(
|
|
|
59
116
|
if (
|
|
60
117
|
(!filters.names || filters.names.length === 0) &&
|
|
61
118
|
(!filters.tags || filters.tags.length === 0) &&
|
|
62
|
-
(!filters.
|
|
119
|
+
(!filters.wires || filters.wires.length === 0) &&
|
|
120
|
+
(!filters.excludeWires || filters.excludeWires.length === 0) &&
|
|
63
121
|
(!filters.directories || filters.directories.length === 0) &&
|
|
64
122
|
(!filters.httpRoutes || filters.httpRoutes.length === 0) &&
|
|
65
|
-
(!filters.httpMethods || filters.httpMethods.length === 0)
|
|
123
|
+
(!filters.httpMethods || filters.httpMethods.length === 0) &&
|
|
124
|
+
(!filters.target || filters.target.length === 0) &&
|
|
125
|
+
(!filters.excludeNames || filters.excludeNames.length === 0) &&
|
|
126
|
+
(!filters.excludeTags || filters.excludeTags.length === 0) &&
|
|
127
|
+
(!filters.excludeWires || filters.excludeWires.length === 0) &&
|
|
128
|
+
(!filters.excludeDirectories || filters.excludeDirectories.length === 0) &&
|
|
129
|
+
(!filters.excludeHttpRoutes || filters.excludeHttpRoutes.length === 0) &&
|
|
130
|
+
(!filters.excludeHttpMethods || filters.excludeHttpMethods.length === 0) &&
|
|
131
|
+
(!filters.excludeTarget || filters.excludeTarget.length === 0)
|
|
66
132
|
) {
|
|
67
133
|
return true
|
|
68
134
|
}
|
|
69
135
|
|
|
70
|
-
//
|
|
71
|
-
if (
|
|
72
|
-
|
|
73
|
-
|
|
136
|
+
// Deploy-target include filter (computed once per filterInspectorState call).
|
|
137
|
+
if (keptByDeploy && !keptByDeploy.has(meta.name)) {
|
|
138
|
+
logger.debug(`⒡ Filtered by deploy include: ${meta.type}:${meta.name}`)
|
|
139
|
+
return false
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// Check wire include filter
|
|
143
|
+
if (filters.wires && filters.wires.length > 0) {
|
|
144
|
+
if (!filters.wires.includes(meta.type)) {
|
|
145
|
+
logger.debug(`⒡ Filtered by wire include: ${meta.type}:${meta.name}`)
|
|
146
|
+
return false
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// Check wire exclude filter
|
|
151
|
+
if (filters.excludeWires && filters.excludeWires.length > 0) {
|
|
152
|
+
if (filters.excludeWires.includes(meta.type)) {
|
|
153
|
+
logger.debug(`⒡ Filtered by wire exclude: ${meta.type}:${meta.name}`)
|
|
74
154
|
return false
|
|
75
155
|
}
|
|
76
156
|
}
|
|
@@ -89,35 +169,55 @@ function matchesFilters(
|
|
|
89
169
|
}
|
|
90
170
|
}
|
|
91
171
|
|
|
92
|
-
// Check tag filter
|
|
172
|
+
// Check tag include filter
|
|
93
173
|
if (filters.tags && filters.tags.length > 0) {
|
|
94
174
|
if (!meta.tags || !filters.tags.some((tag) => meta.tags!.includes(tag))) {
|
|
95
|
-
logger.debug(`⒡ Filtered by tags: ${meta.type}:${meta.name}`)
|
|
175
|
+
logger.debug(`⒡ Filtered by tags include: ${meta.type}:${meta.name}`)
|
|
96
176
|
return false
|
|
97
177
|
}
|
|
98
178
|
}
|
|
99
179
|
|
|
100
|
-
// Check
|
|
180
|
+
// Check tag exclude filter
|
|
181
|
+
if (filters.excludeTags && filters.excludeTags.length > 0) {
|
|
182
|
+
if (
|
|
183
|
+
meta.tags &&
|
|
184
|
+
filters.excludeTags.some((tag) => meta.tags!.includes(tag))
|
|
185
|
+
) {
|
|
186
|
+
logger.debug(`⒡ Filtered by tags exclude: ${meta.type}:${meta.name}`)
|
|
187
|
+
return false
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
const { baseName } = parseVersionedId(meta.name)
|
|
192
|
+
const matchesNamePattern = (pattern: string) =>
|
|
193
|
+
matchesWildcard(meta.name, pattern) ||
|
|
194
|
+
(baseName !== meta.name && matchesWildcard(baseName, pattern))
|
|
195
|
+
|
|
196
|
+
// Check name include filter (match against both full ID and base name for versioned functions)
|
|
101
197
|
if (filters.names && filters.names.length > 0) {
|
|
102
|
-
const
|
|
103
|
-
const nameMatches = filters.names.some(
|
|
104
|
-
(pattern) =>
|
|
105
|
-
matchesWildcard(meta.name, pattern) ||
|
|
106
|
-
(baseName !== meta.name && matchesWildcard(baseName, pattern))
|
|
107
|
-
)
|
|
198
|
+
const nameMatches = filters.names.some(matchesNamePattern)
|
|
108
199
|
if (!nameMatches) {
|
|
109
|
-
logger.debug(`⒡ Filtered by name: ${meta.type}:${meta.name}`)
|
|
200
|
+
logger.debug(`⒡ Filtered by name include: ${meta.type}:${meta.name}`)
|
|
201
|
+
return false
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
// Check name exclude filter
|
|
206
|
+
if (filters.excludeNames && filters.excludeNames.length > 0) {
|
|
207
|
+
if (filters.excludeNames.some(matchesNamePattern)) {
|
|
208
|
+
logger.debug(`⒡ Filtered by name exclude: ${meta.type}:${meta.name}`)
|
|
110
209
|
return false
|
|
111
210
|
}
|
|
112
211
|
}
|
|
113
212
|
|
|
114
|
-
|
|
213
|
+
const matchesRoutePattern = (pattern: string) =>
|
|
214
|
+
!!meta.httpRoute && matchesWildcard(meta.httpRoute, pattern)
|
|
215
|
+
|
|
216
|
+
// Check HTTP route include filter
|
|
115
217
|
if (filters.httpRoutes && filters.httpRoutes.length > 0 && meta.httpRoute) {
|
|
116
|
-
const routeMatches = filters.httpRoutes.some(
|
|
117
|
-
matchesWildcard(meta.httpRoute!, pattern)
|
|
118
|
-
)
|
|
218
|
+
const routeMatches = filters.httpRoutes.some(matchesRoutePattern)
|
|
119
219
|
if (!routeMatches) {
|
|
120
|
-
logger.debug(`⒡ Filtered by HTTP route: ${meta.httpRoute}`)
|
|
220
|
+
logger.debug(`⒡ Filtered by HTTP route include: ${meta.httpRoute}`)
|
|
121
221
|
return false
|
|
122
222
|
}
|
|
123
223
|
|
|
@@ -139,15 +239,40 @@ function matchesFilters(
|
|
|
139
239
|
}
|
|
140
240
|
}
|
|
141
241
|
|
|
142
|
-
// Check HTTP
|
|
242
|
+
// Check HTTP route exclude filter
|
|
243
|
+
if (
|
|
244
|
+
filters.excludeHttpRoutes &&
|
|
245
|
+
filters.excludeHttpRoutes.length > 0 &&
|
|
246
|
+
meta.httpRoute
|
|
247
|
+
) {
|
|
248
|
+
if (filters.excludeHttpRoutes.some(matchesRoutePattern)) {
|
|
249
|
+
logger.debug(`⒡ Filtered by HTTP route exclude: ${meta.httpRoute}`)
|
|
250
|
+
return false
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
const normalizedMethod = meta.httpMethod?.toUpperCase()
|
|
255
|
+
|
|
256
|
+
// Check HTTP method include filter
|
|
143
257
|
if (
|
|
144
258
|
filters.httpMethods &&
|
|
145
259
|
filters.httpMethods.length > 0 &&
|
|
146
|
-
|
|
260
|
+
normalizedMethod
|
|
147
261
|
) {
|
|
148
|
-
const normalizedMethod = meta.httpMethod.toUpperCase()
|
|
149
262
|
if (!filters.httpMethods.includes(normalizedMethod)) {
|
|
150
|
-
logger.debug(`⒡ Filtered by HTTP method: ${meta.httpMethod}`)
|
|
263
|
+
logger.debug(`⒡ Filtered by HTTP method include: ${meta.httpMethod}`)
|
|
264
|
+
return false
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
// Check HTTP method exclude filter
|
|
269
|
+
if (
|
|
270
|
+
filters.excludeHttpMethods &&
|
|
271
|
+
filters.excludeHttpMethods.length > 0 &&
|
|
272
|
+
normalizedMethod
|
|
273
|
+
) {
|
|
274
|
+
if (filters.excludeHttpMethods.includes(normalizedMethod)) {
|
|
275
|
+
logger.debug(`⒡ Filtered by HTTP method exclude: ${meta.httpMethod}`)
|
|
151
276
|
return false
|
|
152
277
|
}
|
|
153
278
|
}
|
|
@@ -183,14 +308,47 @@ export function filterInspectorState(
|
|
|
183
308
|
Object.keys(filters).length === 0 ||
|
|
184
309
|
((!filters.names || filters.names.length === 0) &&
|
|
185
310
|
(!filters.tags || filters.tags.length === 0) &&
|
|
186
|
-
(!filters.
|
|
311
|
+
(!filters.wires || filters.wires.length === 0) &&
|
|
312
|
+
(!filters.excludeWires || filters.excludeWires.length === 0) &&
|
|
187
313
|
(!filters.directories || filters.directories.length === 0) &&
|
|
188
314
|
(!filters.httpRoutes || filters.httpRoutes.length === 0) &&
|
|
189
|
-
(!filters.httpMethods || filters.httpMethods.length === 0)
|
|
315
|
+
(!filters.httpMethods || filters.httpMethods.length === 0) &&
|
|
316
|
+
(!filters.target || filters.target.length === 0) &&
|
|
317
|
+
(!filters.excludeNames || filters.excludeNames.length === 0) &&
|
|
318
|
+
(!filters.excludeTags || filters.excludeTags.length === 0) &&
|
|
319
|
+
(!filters.excludeWires || filters.excludeWires.length === 0) &&
|
|
320
|
+
(!filters.excludeDirectories ||
|
|
321
|
+
filters.excludeDirectories.length === 0) &&
|
|
322
|
+
(!filters.excludeHttpRoutes || filters.excludeHttpRoutes.length === 0) &&
|
|
323
|
+
(!filters.excludeHttpMethods ||
|
|
324
|
+
filters.excludeHttpMethods.length === 0) &&
|
|
325
|
+
(!filters.excludeTarget || filters.excludeTarget.length === 0))
|
|
190
326
|
) {
|
|
191
327
|
return state
|
|
192
328
|
}
|
|
193
329
|
|
|
330
|
+
// Precompute kept-function set for the deploy filter (if active).
|
|
331
|
+
// resolveDeployTarget throws IncompatibleDeployTargetError when an
|
|
332
|
+
// explicit deploy: 'serverless' clashes with serverlessIncompatible.
|
|
333
|
+
let keptByDeploy: Set<string> | null = null
|
|
334
|
+
if (
|
|
335
|
+
(filters.target && filters.target.length > 0) ||
|
|
336
|
+
(filters.excludeTarget && filters.excludeTarget.length > 0)
|
|
337
|
+
) {
|
|
338
|
+
const allowed = filters.target ? new Set(filters.target) : null
|
|
339
|
+
const excluded = filters.excludeTarget
|
|
340
|
+
? new Set(filters.excludeTarget)
|
|
341
|
+
: null
|
|
342
|
+
const incompatible = new Set(filters.serverlessIncompatible ?? [])
|
|
343
|
+
keptByDeploy = new Set<string>()
|
|
344
|
+
for (const [funcId, funcMeta] of Object.entries(state.functions.meta)) {
|
|
345
|
+
const target = resolveDeployTarget(funcMeta as any, incompatible, funcId)
|
|
346
|
+
if (allowed && !allowed.has(target)) continue
|
|
347
|
+
if (excluded && excluded.has(target)) continue
|
|
348
|
+
keptByDeploy.add(funcId)
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
|
|
194
352
|
// Snapshot the original workflow graph meta before filtering prunes it
|
|
195
353
|
const originalGraphMeta = {
|
|
196
354
|
...((state as InspectorState).workflows?.graphMeta ?? {}),
|
|
@@ -292,7 +450,8 @@ export function filterInspectorState(
|
|
|
292
450
|
groupBasePath: routeMeta.groupBasePath,
|
|
293
451
|
},
|
|
294
452
|
logger,
|
|
295
|
-
globalWarnedGroups
|
|
453
|
+
globalWarnedGroups,
|
|
454
|
+
keptByDeploy
|
|
296
455
|
)
|
|
297
456
|
|
|
298
457
|
if (!matches) {
|
|
@@ -356,7 +515,11 @@ export function filterInspectorState(
|
|
|
356
515
|
name,
|
|
357
516
|
tags: channelMeta.tags,
|
|
358
517
|
},
|
|
359
|
-
logger
|
|
518
|
+
logger,
|
|
519
|
+
|
|
520
|
+
undefined,
|
|
521
|
+
|
|
522
|
+
keptByDeploy
|
|
360
523
|
)
|
|
361
524
|
|
|
362
525
|
if (!matches) {
|
|
@@ -405,10 +568,11 @@ export function filterInspectorState(
|
|
|
405
568
|
}
|
|
406
569
|
}
|
|
407
570
|
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
571
|
+
filteredState.channels.files = repopulateFileSetFromMeta(
|
|
572
|
+
filteredState.channels.meta,
|
|
573
|
+
state.channels.files,
|
|
574
|
+
Object.keys(filteredState.channels.meta).length > 0
|
|
575
|
+
)
|
|
412
576
|
|
|
413
577
|
// Filter triggers
|
|
414
578
|
for (const name of Object.keys(filteredState.triggers.meta)) {
|
|
@@ -420,7 +584,11 @@ export function filterInspectorState(
|
|
|
420
584
|
name,
|
|
421
585
|
tags: triggerMeta.tags,
|
|
422
586
|
},
|
|
423
|
-
logger
|
|
587
|
+
logger,
|
|
588
|
+
|
|
589
|
+
undefined,
|
|
590
|
+
|
|
591
|
+
keptByDeploy
|
|
424
592
|
)
|
|
425
593
|
|
|
426
594
|
if (!matches) {
|
|
@@ -434,10 +602,11 @@ export function filterInspectorState(
|
|
|
434
602
|
}
|
|
435
603
|
}
|
|
436
604
|
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
605
|
+
filteredState.triggers.files = repopulateFileSetFromMeta(
|
|
606
|
+
filteredState.triggers.meta,
|
|
607
|
+
state.triggers.files,
|
|
608
|
+
Object.keys(filteredState.triggers.meta).length > 0
|
|
609
|
+
)
|
|
441
610
|
|
|
442
611
|
// Filter scheduled tasks
|
|
443
612
|
for (const name of Object.keys(filteredState.scheduledTasks.meta)) {
|
|
@@ -449,7 +618,11 @@ export function filterInspectorState(
|
|
|
449
618
|
name,
|
|
450
619
|
tags: taskMeta.tags,
|
|
451
620
|
},
|
|
452
|
-
logger
|
|
621
|
+
logger,
|
|
622
|
+
|
|
623
|
+
undefined,
|
|
624
|
+
|
|
625
|
+
keptByDeploy
|
|
453
626
|
)
|
|
454
627
|
|
|
455
628
|
if (!matches) {
|
|
@@ -464,10 +637,11 @@ export function filterInspectorState(
|
|
|
464
637
|
}
|
|
465
638
|
}
|
|
466
639
|
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
640
|
+
filteredState.scheduledTasks.files = repopulateFileSetFromMeta(
|
|
641
|
+
filteredState.scheduledTasks.meta,
|
|
642
|
+
state.scheduledTasks.files,
|
|
643
|
+
Object.keys(filteredState.scheduledTasks.meta).length > 0
|
|
644
|
+
)
|
|
471
645
|
|
|
472
646
|
// Filter queue workers
|
|
473
647
|
for (const name of Object.keys(filteredState.queueWorkers.meta)) {
|
|
@@ -479,7 +653,11 @@ export function filterInspectorState(
|
|
|
479
653
|
name,
|
|
480
654
|
tags: workerMeta.tags,
|
|
481
655
|
},
|
|
482
|
-
logger
|
|
656
|
+
logger,
|
|
657
|
+
|
|
658
|
+
undefined,
|
|
659
|
+
|
|
660
|
+
keptByDeploy
|
|
483
661
|
)
|
|
484
662
|
|
|
485
663
|
if (!matches) {
|
|
@@ -502,10 +680,11 @@ export function filterInspectorState(
|
|
|
502
680
|
}
|
|
503
681
|
}
|
|
504
682
|
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
683
|
+
filteredState.queueWorkers.files = repopulateFileSetFromMeta(
|
|
684
|
+
filteredState.queueWorkers.meta,
|
|
685
|
+
state.queueWorkers.files,
|
|
686
|
+
Object.keys(filteredState.queueWorkers.meta).length > 0
|
|
687
|
+
)
|
|
509
688
|
|
|
510
689
|
// Filter MCP tools
|
|
511
690
|
for (const name of Object.keys(filteredState.mcpEndpoints.toolsMeta)) {
|
|
@@ -517,7 +696,11 @@ export function filterInspectorState(
|
|
|
517
696
|
name,
|
|
518
697
|
tags: toolMeta.tags,
|
|
519
698
|
},
|
|
520
|
-
logger
|
|
699
|
+
logger,
|
|
700
|
+
|
|
701
|
+
undefined,
|
|
702
|
+
|
|
703
|
+
keptByDeploy
|
|
521
704
|
)
|
|
522
705
|
|
|
523
706
|
if (!matches) {
|
|
@@ -545,7 +728,11 @@ export function filterInspectorState(
|
|
|
545
728
|
name,
|
|
546
729
|
tags: resourceMeta.tags,
|
|
547
730
|
},
|
|
548
|
-
logger
|
|
731
|
+
logger,
|
|
732
|
+
|
|
733
|
+
undefined,
|
|
734
|
+
|
|
735
|
+
keptByDeploy
|
|
549
736
|
)
|
|
550
737
|
|
|
551
738
|
if (!matches) {
|
|
@@ -575,7 +762,11 @@ export function filterInspectorState(
|
|
|
575
762
|
name,
|
|
576
763
|
tags: promptMeta.tags,
|
|
577
764
|
},
|
|
578
|
-
logger
|
|
765
|
+
logger,
|
|
766
|
+
|
|
767
|
+
undefined,
|
|
768
|
+
|
|
769
|
+
keptByDeploy
|
|
579
770
|
)
|
|
580
771
|
|
|
581
772
|
if (!matches) {
|
|
@@ -595,14 +786,20 @@ export function filterInspectorState(
|
|
|
595
786
|
}
|
|
596
787
|
}
|
|
597
788
|
|
|
598
|
-
// Repopulate mcpEndpoints.files
|
|
789
|
+
// Repopulate mcpEndpoints.files from surviving endpoint metadata
|
|
599
790
|
const hasMcpEndpoints =
|
|
600
791
|
Object.keys(filteredState.mcpEndpoints.toolsMeta).length > 0 ||
|
|
601
792
|
Object.keys(filteredState.mcpEndpoints.resourcesMeta).length > 0 ||
|
|
602
793
|
Object.keys(filteredState.mcpEndpoints.promptsMeta).length > 0
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
794
|
+
filteredState.mcpEndpoints.files = repopulateFileSetFromMeta(
|
|
795
|
+
{
|
|
796
|
+
toolsMeta: filteredState.mcpEndpoints.toolsMeta,
|
|
797
|
+
resourcesMeta: filteredState.mcpEndpoints.resourcesMeta,
|
|
798
|
+
promptsMeta: filteredState.mcpEndpoints.promptsMeta,
|
|
799
|
+
},
|
|
800
|
+
state.mcpEndpoints.files,
|
|
801
|
+
hasMcpEndpoints
|
|
802
|
+
)
|
|
606
803
|
|
|
607
804
|
// Filter AI agents
|
|
608
805
|
for (const name of Object.keys(filteredState.agents.agentsMeta)) {
|
|
@@ -614,7 +811,11 @@ export function filterInspectorState(
|
|
|
614
811
|
name,
|
|
615
812
|
tags: agentMeta.tags,
|
|
616
813
|
},
|
|
617
|
-
logger
|
|
814
|
+
logger,
|
|
815
|
+
|
|
816
|
+
undefined,
|
|
817
|
+
|
|
818
|
+
keptByDeploy
|
|
618
819
|
)
|
|
619
820
|
|
|
620
821
|
if (!matches) {
|
|
@@ -654,7 +855,11 @@ export function filterInspectorState(
|
|
|
654
855
|
name: commandName,
|
|
655
856
|
tags: commandMeta.tags,
|
|
656
857
|
},
|
|
657
|
-
logger
|
|
858
|
+
logger,
|
|
859
|
+
|
|
860
|
+
undefined,
|
|
861
|
+
|
|
862
|
+
keptByDeploy
|
|
658
863
|
)
|
|
659
864
|
|
|
660
865
|
if (!matches) {
|
|
@@ -690,13 +895,15 @@ export function filterInspectorState(
|
|
|
690
895
|
}
|
|
691
896
|
}
|
|
692
897
|
|
|
693
|
-
// Repopulate cli.files
|
|
898
|
+
// Repopulate cli.files from surviving program/renderer metadata
|
|
694
899
|
const hasCliPrograms = Object.keys(filteredState.cli.meta.programs).length > 0
|
|
695
900
|
const hasCliRenderers =
|
|
696
901
|
Object.keys(filteredState.cli.meta.renderers || {}).length > 0
|
|
697
|
-
|
|
698
|
-
filteredState.cli.
|
|
699
|
-
|
|
902
|
+
filteredState.cli.files = repopulateFileSetFromMeta(
|
|
903
|
+
filteredState.cli.meta,
|
|
904
|
+
state.cli.files,
|
|
905
|
+
hasCliPrograms || hasCliRenderers
|
|
906
|
+
)
|
|
700
907
|
|
|
701
908
|
// Direct function filtering: functions that match the names/tags/directories
|
|
702
909
|
// filters should be included even if no wiring (HTTP, scheduler, etc.) references them.
|
|
@@ -722,7 +929,11 @@ export function filterInspectorState(
|
|
|
722
929
|
tags: funcMeta.tags,
|
|
723
930
|
filePath,
|
|
724
931
|
},
|
|
725
|
-
logger
|
|
932
|
+
logger,
|
|
933
|
+
|
|
934
|
+
undefined,
|
|
935
|
+
|
|
936
|
+
keptByDeploy
|
|
726
937
|
)
|
|
727
938
|
|
|
728
939
|
if (matches) {
|
|
@@ -786,12 +997,17 @@ export function filterInspectorState(
|
|
|
786
997
|
}
|
|
787
998
|
}
|
|
788
999
|
|
|
789
|
-
// Prune workflow graphs whose function was filtered out
|
|
1000
|
+
// Prune workflow graphs whose function was filtered out — UNLESS the
|
|
1001
|
+
// workflow's own name is in the filter (covers pikkuWorkflowGraph,
|
|
1002
|
+
// which doesn't register a function meta, so its pikkuFuncId never
|
|
1003
|
+
// ends up in usedFunctions even when callers explicitly want it).
|
|
1004
|
+
const filterNamesSet = new Set(filters.names ?? [])
|
|
790
1005
|
const workflowKeys = new Set([
|
|
791
1006
|
...Object.keys(filteredState.workflows.graphMeta),
|
|
792
1007
|
...Object.keys(filteredState.workflows.meta),
|
|
793
1008
|
])
|
|
794
1009
|
for (const name of workflowKeys) {
|
|
1010
|
+
if (filterNamesSet.has(name)) continue
|
|
795
1011
|
const graphMeta = filteredState.workflows.graphMeta[name]
|
|
796
1012
|
const workflowMeta = filteredState.workflows.meta[name]
|
|
797
1013
|
// Check both graphMeta.pikkuFuncId and meta.pikkuFuncId
|
|
@@ -866,6 +1082,16 @@ export function filterInspectorState(
|
|
|
866
1082
|
}
|
|
867
1083
|
}
|
|
868
1084
|
|
|
1085
|
+
// workflowService internally calls queueService (via queueStepWorker /
|
|
1086
|
+
// queueOrchestrator). Any unit that needs workflowService also needs
|
|
1087
|
+
// queueService for the transitive enqueue calls — covers
|
|
1088
|
+
// workflow-starter, graph-starter, workflow-runner, etc.
|
|
1089
|
+
if (
|
|
1090
|
+
filteredState.serviceAggregation.requiredServices.has('workflowService')
|
|
1091
|
+
) {
|
|
1092
|
+
filteredState.serviceAggregation.requiredServices.add('queueService')
|
|
1093
|
+
}
|
|
1094
|
+
|
|
869
1095
|
// Recalculate requiredServices based on filtered functions/middleware/permissions
|
|
870
1096
|
// Need to cast to InspectorState temporarily for aggregateRequiredServices
|
|
871
1097
|
const stateForAggregation = filteredState as InspectorState
|
|
@@ -31,7 +31,7 @@ describe('matchesFilters', () => {
|
|
|
31
31
|
test('should return true when all filter arrays are empty', () => {
|
|
32
32
|
const filters: InspectorFilters = {
|
|
33
33
|
tags: [],
|
|
34
|
-
|
|
34
|
+
wires: [],
|
|
35
35
|
directories: [],
|
|
36
36
|
}
|
|
37
37
|
|
|
@@ -108,10 +108,10 @@ describe('matchesFilters', () => {
|
|
|
108
108
|
})
|
|
109
109
|
})
|
|
110
110
|
|
|
111
|
-
describe('
|
|
112
|
-
test('should return true when
|
|
111
|
+
describe('Wire filtering', () => {
|
|
112
|
+
test('should return true when wire matches', () => {
|
|
113
113
|
const filters: InspectorFilters = {
|
|
114
|
-
|
|
114
|
+
wires: ['http', 'channel'],
|
|
115
115
|
}
|
|
116
116
|
|
|
117
117
|
const result = matchesFilters(
|
|
@@ -124,9 +124,9 @@ describe('matchesFilters', () => {
|
|
|
124
124
|
assert.equal(result, true)
|
|
125
125
|
})
|
|
126
126
|
|
|
127
|
-
test('should return false when
|
|
127
|
+
test('should return false when wire does not match', () => {
|
|
128
128
|
const filters: InspectorFilters = {
|
|
129
|
-
|
|
129
|
+
wires: ['channel', 'queue'],
|
|
130
130
|
}
|
|
131
131
|
|
|
132
132
|
const result = matchesFilters(
|
|
@@ -144,7 +144,7 @@ describe('matchesFilters', () => {
|
|
|
144
144
|
|
|
145
145
|
eventTypes.forEach((eventType) => {
|
|
146
146
|
const filters: InspectorFilters = {
|
|
147
|
-
|
|
147
|
+
wires: [eventType],
|
|
148
148
|
}
|
|
149
149
|
|
|
150
150
|
const result = matchesFilters(
|
|
@@ -154,9 +154,24 @@ describe('matchesFilters', () => {
|
|
|
154
154
|
mockLogger
|
|
155
155
|
)
|
|
156
156
|
|
|
157
|
-
assert.equal(result, true, `Should match for
|
|
157
|
+
assert.equal(result, true, `Should match for wire: ${eventType}`)
|
|
158
158
|
})
|
|
159
159
|
})
|
|
160
|
+
|
|
161
|
+
test('should exclude matching wires', () => {
|
|
162
|
+
const filters: InspectorFilters = {
|
|
163
|
+
excludeWires: ['queue', 'scheduler'],
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
const result = matchesFilters(
|
|
167
|
+
filters,
|
|
168
|
+
{ tags: ['test'] },
|
|
169
|
+
{ type: 'queue', name: 'email-worker' },
|
|
170
|
+
mockLogger
|
|
171
|
+
)
|
|
172
|
+
|
|
173
|
+
assert.equal(result, false)
|
|
174
|
+
})
|
|
160
175
|
})
|
|
161
176
|
|
|
162
177
|
describe('Directory filtering', () => {
|
|
@@ -275,7 +290,7 @@ describe('matchesFilters', () => {
|
|
|
275
290
|
test('should return true when all filters pass', () => {
|
|
276
291
|
const filters: InspectorFilters = {
|
|
277
292
|
tags: ['api'],
|
|
278
|
-
|
|
293
|
+
wires: ['http'],
|
|
279
294
|
directories: ['src/api'],
|
|
280
295
|
}
|
|
281
296
|
|
|
@@ -296,7 +311,7 @@ describe('matchesFilters', () => {
|
|
|
296
311
|
test('should return false when type filter fails (even if others pass)', () => {
|
|
297
312
|
const filters: InspectorFilters = {
|
|
298
313
|
tags: ['api'],
|
|
299
|
-
|
|
314
|
+
wires: ['channel'],
|
|
300
315
|
directories: ['src/api'],
|
|
301
316
|
}
|
|
302
317
|
|
|
@@ -317,7 +332,7 @@ describe('matchesFilters', () => {
|
|
|
317
332
|
test('should return false when directory filter fails (even if others pass)', () => {
|
|
318
333
|
const filters: InspectorFilters = {
|
|
319
334
|
tags: ['api'],
|
|
320
|
-
|
|
335
|
+
wires: ['http'],
|
|
321
336
|
directories: ['src/internal'],
|
|
322
337
|
}
|
|
323
338
|
|
|
@@ -338,7 +353,7 @@ describe('matchesFilters', () => {
|
|
|
338
353
|
test('should return false when tag filter fails (even if others pass)', () => {
|
|
339
354
|
const filters: InspectorFilters = {
|
|
340
355
|
tags: ['internal'],
|
|
341
|
-
|
|
356
|
+
wires: ['http'],
|
|
342
357
|
directories: ['src/api'],
|
|
343
358
|
}
|
|
344
359
|
|
|
@@ -375,7 +390,7 @@ describe('matchesFilters', () => {
|
|
|
375
390
|
|
|
376
391
|
test('should handle empty meta name', () => {
|
|
377
392
|
const filters: InspectorFilters = {
|
|
378
|
-
|
|
393
|
+
wires: ['channel'],
|
|
379
394
|
}
|
|
380
395
|
|
|
381
396
|
const result = matchesFilters(
|
|
@@ -443,7 +458,7 @@ describe('matchesFilters', () => {
|
|
|
443
458
|
|
|
444
459
|
test('should handle multiple matching types', () => {
|
|
445
460
|
const filters: InspectorFilters = {
|
|
446
|
-
|
|
461
|
+
wires: ['http', 'channel'],
|
|
447
462
|
}
|
|
448
463
|
|
|
449
464
|
const result = matchesFilters(
|
|
@@ -724,7 +739,7 @@ describe('matchesFilters', () => {
|
|
|
724
739
|
test('should return true when all filters including new ones pass', () => {
|
|
725
740
|
const filters: InspectorFilters = {
|
|
726
741
|
tags: ['api'],
|
|
727
|
-
|
|
742
|
+
wires: ['http'],
|
|
728
743
|
httpRoutes: ['/api/*'],
|
|
729
744
|
httpMethods: ['GET'],
|
|
730
745
|
}
|