@pikku/inspector 0.11.2 → 0.12.1
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 +36 -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 +81 -61
- package/dist/add/add-cli.d.ts +1 -1
- package/dist/add/add-cli.js +42 -19
- package/dist/add/add-file-extends-core-type.d.ts +1 -1
- package/dist/add/add-file-with-config.d.ts +1 -1
- package/dist/add/add-file-with-factory.d.ts +1 -1
- package/dist/add/add-file-with-factory.js +2 -0
- package/dist/add/add-functions.d.ts +1 -1
- package/dist/add/add-functions.js +256 -82
- package/dist/add/add-http-route.d.ts +20 -10
- package/dist/add/add-http-route.js +156 -66
- package/dist/add/add-http-routes.d.ts +5 -0
- package/dist/add/add-http-routes.js +160 -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.d.ts +1 -1
- package/dist/add/add-mcp-prompt.js +14 -9
- package/dist/add/add-mcp-resource.d.ts +1 -1
- 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.d.ts +1 -1
- package/dist/add/add-queue-worker.js +18 -12
- package/dist/add/add-rpc-invocations.d.ts +3 -3
- package/dist/add/add-rpc-invocations.js +24 -10
- package/dist/add/add-schedule.d.ts +1 -1
- 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-wire-addon.d.ts +7 -0
- package/dist/add/add-wire-addon.js +70 -0
- package/dist/add/add-workflow-graph.d.ts +3 -2
- package/dist/add/add-workflow-graph.js +143 -406
- package/dist/add/add-workflow.d.ts +1 -1
- package/dist/add/add-workflow.js +6 -4
- package/dist/error-codes.d.ts +15 -1
- package/dist/error-codes.js +20 -1
- package/dist/index.d.ts +9 -8
- package/dist/index.js +5 -4
- package/dist/inspector.d.ts +2 -2
- package/dist/inspector.js +95 -15
- 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 -50
- package/dist/utils/compute-required-schemas.d.ts +4 -0
- package/dist/utils/compute-required-schemas.js +40 -0
- package/dist/utils/contract-hashes.d.ts +52 -0
- package/dist/utils/contract-hashes.js +269 -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/does-type-extend-core-type.d.ts +1 -1
- package/dist/utils/ensure-function-metadata.d.ts +6 -3
- 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 +86 -291
- package/dist/utils/extract-services.d.ts +2 -1
- package/dist/utils/extract-services.js +25 -1
- package/dist/utils/filter-inspector-state.d.ts +1 -1
- package/dist/utils/filter-inspector-state.js +107 -23
- package/dist/utils/filter-utils.d.ts +2 -2
- package/dist/utils/get-files-and-methods.d.ts +1 -1
- package/dist/utils/get-property-value.d.ts +6 -1
- package/dist/utils/get-property-value.js +28 -3
- package/dist/utils/hash.d.ts +2 -0
- package/dist/utils/hash.js +23 -0
- package/dist/utils/middleware.d.ts +9 -32
- package/dist/utils/middleware.js +80 -66
- package/dist/utils/permissions.d.ts +4 -4
- package/dist/utils/permissions.js +10 -10
- package/dist/utils/post-process.d.ts +11 -11
- package/dist/utils/post-process.js +247 -24
- package/dist/utils/resolve-addon-package.d.ts +16 -0
- package/dist/utils/resolve-addon-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 +70 -23
- package/dist/utils/serialize-inspector-state.js +98 -22
- 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/validate-auth-sessionless.d.ts +3 -0
- package/dist/utils/validate-auth-sessionless.js +14 -0
- package/dist/utils/workflow/dsl/deserialize-dsl-workflow.js +34 -102
- package/dist/utils/workflow/dsl/extract-dsl-workflow.d.ts +1 -1
- package/dist/utils/workflow/dsl/extract-dsl-workflow.js +23 -4
- package/dist/utils/workflow/graph/convert-dsl-to-graph.js +12 -10
- 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 +2 -0
- package/dist/utils/workflow/graph/index.js +2 -0
- package/dist/utils/workflow/graph/serialize-workflow-graph.d.ts +0 -8
- package/dist/utils/workflow/graph/serialize-workflow-graph.js +1 -3
- package/dist/utils/workflow/graph/workflow-graph.types.d.ts +53 -79
- package/dist/utils/workflow/graph/workflow-graph.types.js +1 -1
- package/dist/visit.d.ts +1 -1
- package/dist/visit.js +13 -6
- package/package.json +14 -4
- package/src/add/add-ai-agent.ts +468 -0
- package/src/add/add-channel.ts +103 -79
- package/src/add/add-cli.ts +68 -24
- package/src/add/add-file-extends-core-type.ts +1 -1
- package/src/add/add-file-with-config.ts +1 -1
- package/src/add/add-file-with-factory.ts +3 -1
- package/src/add/add-functions.ts +349 -103
- package/src/add/add-http-route.ts +263 -89
- package/src/add/add-http-routes.ts +229 -0
- package/src/add/add-keyed-wiring.ts +151 -0
- package/src/add/add-mcp-prompt.ts +27 -16
- package/src/add/add-mcp-resource.ts +28 -16
- package/src/add/add-middleware.ts +482 -80
- package/src/add/add-permission.ts +199 -40
- package/src/add/add-queue-worker.ts +25 -20
- package/src/add/add-rpc-invocations.ts +28 -11
- package/src/add/add-schedule.ts +17 -12
- 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-wire-addon.ts +80 -0
- package/src/add/add-workflow-graph.ts +180 -522
- package/src/add/add-workflow.ts +7 -6
- package/src/error-codes.ts +25 -1
- package/src/index.ts +23 -13
- package/src/inspector.ts +139 -19
- package/src/schema-generator.ts +1 -0
- package/src/types-map.ts +12 -1
- package/src/types.ts +199 -69
- package/src/utils/compute-required-schemas.ts +48 -0
- package/src/utils/contract-hashes.test.ts +553 -0
- package/src/utils/contract-hashes.ts +386 -0
- package/src/utils/custom-types-generator.ts +88 -0
- package/src/utils/detect-schema-vendor.ts +90 -0
- package/src/utils/does-type-extend-core-type.ts +1 -1
- package/src/utils/ensure-function-metadata.ts +325 -8
- package/src/utils/extract-function-name.ts +101 -351
- package/src/utils/extract-services.ts +35 -2
- package/src/utils/filter-inspector-state.test.ts +37 -25
- package/src/utils/filter-inspector-state.ts +146 -32
- package/src/utils/filter-utils.test.ts +1 -1
- package/src/utils/filter-utils.ts +2 -2
- package/src/utils/get-files-and-methods.ts +1 -1
- package/src/utils/get-property-value.ts +42 -4
- package/src/utils/hash.ts +26 -0
- package/src/utils/middleware.test.ts +204 -0
- package/src/utils/middleware.ts +131 -69
- package/src/utils/permissions.test.ts +35 -12
- package/src/utils/permissions.ts +12 -12
- package/src/utils/post-process.ts +306 -44
- package/src/utils/resolve-addon-package.ts +49 -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 +184 -43
- 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/validate-auth-sessionless.ts +29 -0
- package/src/utils/workflow/dsl/deserialize-dsl-workflow.ts +43 -119
- package/src/utils/workflow/dsl/extract-dsl-workflow.ts +26 -6
- package/src/utils/workflow/graph/convert-dsl-to-graph.ts +17 -10
- 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 +5 -0
- package/src/utils/workflow/graph/serialize-workflow-graph.ts +1 -8
- package/src/utils/workflow/graph/workflow-graph.types.ts +29 -78
- package/src/visit.ts +19 -7
- package/tsconfig.tsbuildinfo +1 -1
- package/dist/add/add-forge-credential.d.ts +0 -8
- package/dist/add/add-forge-credential.js +0 -77
- package/dist/add/add-forge-node.d.ts +0 -7
- package/dist/add/add-forge-node.js +0 -77
- 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-forge-credential.ts +0 -119
- package/src/add/add-forge-node.ts +0 -132
- 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,11 +1,9 @@
|
|
|
1
1
|
import { test, describe } from 'node:test'
|
|
2
2
|
import { strict as assert } from 'node:assert'
|
|
3
3
|
import { filterInspectorState } from './filter-inspector-state.js'
|
|
4
|
-
import { InspectorState, InspectorFilters } from '../types.js'
|
|
5
|
-
import {
|
|
6
|
-
|
|
7
|
-
SerializableInspectorState,
|
|
8
|
-
} from './serialize-inspector-state.js'
|
|
4
|
+
import type { InspectorState, InspectorFilters } from '../types.js'
|
|
5
|
+
import type { SerializableInspectorState } from './serialize-inspector-state.js'
|
|
6
|
+
import { deserializeInspectorState } from './serialize-inspector-state.js'
|
|
9
7
|
import { readFileSync } from 'node:fs'
|
|
10
8
|
import { fileURLToPath } from 'node:url'
|
|
11
9
|
import { dirname, join } from 'node:path'
|
|
@@ -46,7 +44,7 @@ function createMockInspectorState(): Omit<InspectorState, 'typesLookup'> {
|
|
|
46
44
|
meta: {
|
|
47
45
|
get: {
|
|
48
46
|
'/api/users': {
|
|
49
|
-
|
|
47
|
+
pikkuFuncId: 'getUsers',
|
|
50
48
|
route: '/api/users',
|
|
51
49
|
method: 'GET',
|
|
52
50
|
tags: ['api', 'public'],
|
|
@@ -54,7 +52,7 @@ function createMockInspectorState(): Omit<InspectorState, 'typesLookup'> {
|
|
|
54
52
|
permissions: [],
|
|
55
53
|
},
|
|
56
54
|
'/admin/settings': {
|
|
57
|
-
|
|
55
|
+
pikkuFuncId: 'getAdminSettings',
|
|
58
56
|
route: '/admin/settings',
|
|
59
57
|
method: 'GET',
|
|
60
58
|
tags: ['admin'],
|
|
@@ -64,7 +62,7 @@ function createMockInspectorState(): Omit<InspectorState, 'typesLookup'> {
|
|
|
64
62
|
},
|
|
65
63
|
post: {
|
|
66
64
|
'/api/users': {
|
|
67
|
-
|
|
65
|
+
pikkuFuncId: 'createUser',
|
|
68
66
|
route: '/api/users',
|
|
69
67
|
method: 'POST',
|
|
70
68
|
tags: ['api'],
|
|
@@ -152,13 +150,13 @@ function createMockInspectorState(): Omit<InspectorState, 'typesLookup'> {
|
|
|
152
150
|
channels: {
|
|
153
151
|
meta: {
|
|
154
152
|
'chat-channel': {
|
|
155
|
-
|
|
153
|
+
pikkuFuncId: 'handleChatMessage',
|
|
156
154
|
tags: ['realtime', 'public'],
|
|
157
155
|
middleware: [],
|
|
158
156
|
permissions: [],
|
|
159
157
|
},
|
|
160
158
|
'admin-channel': {
|
|
161
|
-
|
|
159
|
+
pikkuFuncId: 'handleAdminMessage',
|
|
162
160
|
tags: ['realtime', 'admin'],
|
|
163
161
|
middleware: [{ type: 'wire', name: 'authMiddleware' }],
|
|
164
162
|
permissions: [],
|
|
@@ -169,13 +167,13 @@ function createMockInspectorState(): Omit<InspectorState, 'typesLookup'> {
|
|
|
169
167
|
scheduledTasks: {
|
|
170
168
|
meta: {
|
|
171
169
|
'daily-report': {
|
|
172
|
-
|
|
170
|
+
pikkuFuncId: 'dailyReport',
|
|
173
171
|
schedule: '0 0 * * *',
|
|
174
172
|
tags: ['cron', 'reports'],
|
|
175
173
|
middleware: [],
|
|
176
174
|
},
|
|
177
175
|
'hourly-cleanup': {
|
|
178
|
-
|
|
176
|
+
pikkuFuncId: 'hourlyCleanup',
|
|
179
177
|
schedule: '0 * * * *',
|
|
180
178
|
tags: ['cron', 'maintenance'],
|
|
181
179
|
middleware: [],
|
|
@@ -186,20 +184,27 @@ function createMockInspectorState(): Omit<InspectorState, 'typesLookup'> {
|
|
|
186
184
|
queueWorkers: {
|
|
187
185
|
meta: {
|
|
188
186
|
'email-worker': {
|
|
189
|
-
|
|
190
|
-
|
|
187
|
+
pikkuFuncId: 'sendEmailWorker',
|
|
188
|
+
name: 'email-queue',
|
|
191
189
|
tags: ['queue', 'email'],
|
|
192
190
|
middleware: [],
|
|
193
191
|
},
|
|
194
192
|
'notification-worker': {
|
|
195
|
-
|
|
196
|
-
|
|
193
|
+
pikkuFuncId: 'sendNotificationWorker',
|
|
194
|
+
name: 'notification-queue',
|
|
197
195
|
tags: ['queue', 'notifications'],
|
|
198
196
|
middleware: [],
|
|
199
197
|
},
|
|
200
198
|
},
|
|
201
199
|
files: new Set(['/test/project/src/workers/email.ts']),
|
|
202
200
|
},
|
|
201
|
+
workflows: {
|
|
202
|
+
meta: {},
|
|
203
|
+
files: new Map(),
|
|
204
|
+
graphMeta: {},
|
|
205
|
+
graphFiles: new Map(),
|
|
206
|
+
invokedWorkflows: new Set(),
|
|
207
|
+
},
|
|
203
208
|
rpc: {
|
|
204
209
|
internalMeta: {},
|
|
205
210
|
internalFiles: new Map(),
|
|
@@ -212,7 +217,7 @@ function createMockInspectorState(): Omit<InspectorState, 'typesLookup'> {
|
|
|
212
217
|
'search-tool': {
|
|
213
218
|
name: 'search-tool',
|
|
214
219
|
description: 'Search tool',
|
|
215
|
-
|
|
220
|
+
pikkuFuncId: 'mcpSearchTool',
|
|
216
221
|
tags: ['mcp', 'search'],
|
|
217
222
|
middleware: [],
|
|
218
223
|
permissions: [],
|
|
@@ -220,7 +225,7 @@ function createMockInspectorState(): Omit<InspectorState, 'typesLookup'> {
|
|
|
220
225
|
'analyze-tool': {
|
|
221
226
|
name: 'analyze-tool',
|
|
222
227
|
description: 'Analyze tool',
|
|
223
|
-
|
|
228
|
+
pikkuFuncId: 'mcpAnalyzeTool',
|
|
224
229
|
tags: ['mcp', 'analytics'],
|
|
225
230
|
middleware: [],
|
|
226
231
|
permissions: [],
|
|
@@ -231,7 +236,7 @@ function createMockInspectorState(): Omit<InspectorState, 'typesLookup'> {
|
|
|
231
236
|
title: 'Docs Resource',
|
|
232
237
|
description: 'Documentation resource',
|
|
233
238
|
uri: 'docs://resource',
|
|
234
|
-
|
|
239
|
+
pikkuFuncId: 'mcpDocsResource',
|
|
235
240
|
tags: ['mcp', 'docs'],
|
|
236
241
|
middleware: [],
|
|
237
242
|
permissions: [],
|
|
@@ -241,7 +246,7 @@ function createMockInspectorState(): Omit<InspectorState, 'typesLookup'> {
|
|
|
241
246
|
'help-prompt': {
|
|
242
247
|
name: 'help-prompt',
|
|
243
248
|
description: 'Help prompt',
|
|
244
|
-
|
|
249
|
+
pikkuFuncId: 'mcpHelpPrompt',
|
|
245
250
|
tags: ['mcp', 'help'],
|
|
246
251
|
middleware: [],
|
|
247
252
|
permissions: [],
|
|
@@ -255,14 +260,14 @@ function createMockInspectorState(): Omit<InspectorState, 'typesLookup'> {
|
|
|
255
260
|
'my-cli': {
|
|
256
261
|
commands: {
|
|
257
262
|
build: {
|
|
258
|
-
|
|
263
|
+
pikkuFuncId: 'cliCommand',
|
|
259
264
|
tags: ['cli', 'build'],
|
|
260
265
|
middleware: [],
|
|
261
266
|
positionals: [],
|
|
262
267
|
options: {},
|
|
263
268
|
} as any,
|
|
264
269
|
test: {
|
|
265
|
-
|
|
270
|
+
pikkuFuncId: 'cliTestCommand',
|
|
266
271
|
tags: ['cli', 'test'],
|
|
267
272
|
middleware: [],
|
|
268
273
|
positionals: [],
|
|
@@ -275,11 +280,18 @@ function createMockInspectorState(): Omit<InspectorState, 'typesLookup'> {
|
|
|
275
280
|
files: new Set(['/test/project/src/cli/commands.ts']),
|
|
276
281
|
},
|
|
277
282
|
middleware: {
|
|
278
|
-
|
|
283
|
+
definitions: {},
|
|
284
|
+
instances: {},
|
|
285
|
+
tagMiddleware: new Map(),
|
|
286
|
+
},
|
|
287
|
+
channelMiddleware: {
|
|
288
|
+
definitions: {},
|
|
289
|
+
instances: {},
|
|
279
290
|
tagMiddleware: new Map(),
|
|
280
291
|
},
|
|
281
292
|
permissions: {
|
|
282
|
-
|
|
293
|
+
definitions: {},
|
|
294
|
+
instances: {},
|
|
283
295
|
tagPermissions: new Map(),
|
|
284
296
|
},
|
|
285
297
|
serviceAggregation: {
|
|
@@ -413,7 +425,7 @@ describe('filterInspectorState', () => {
|
|
|
413
425
|
|
|
414
426
|
assert.equal(Object.keys(result.http.meta.get).length, 1)
|
|
415
427
|
assert.ok(result.http.meta.get['/api/users'])
|
|
416
|
-
assert.equal(result.http.meta.get['/api/users'].
|
|
428
|
+
assert.equal(result.http.meta.get['/api/users'].pikkuFuncId, 'getUsers')
|
|
417
429
|
})
|
|
418
430
|
|
|
419
431
|
test('should filter HTTP routes by name wildcard', () => {
|
|
@@ -1,7 +1,15 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import type {
|
|
2
|
+
InspectorState,
|
|
3
|
+
InspectorFilters,
|
|
4
|
+
InspectorLogger,
|
|
5
|
+
} from '../types.js'
|
|
6
|
+
import type { PikkuWiringTypes } from '@pikku/core'
|
|
7
|
+
import { parseVersionedId } from '@pikku/core'
|
|
3
8
|
import { aggregateRequiredServices } from './post-process.js'
|
|
4
9
|
|
|
10
|
+
// Module-level Set to track warned groups across multiple filter calls
|
|
11
|
+
const globalWarnedGroups = new Set<string>()
|
|
12
|
+
|
|
5
13
|
/**
|
|
6
14
|
* Match a value against a pattern with wildcard support
|
|
7
15
|
* Supports "*" at the beginning, end, or both (e.g., "send*", "*Payment", "*process*")
|
|
@@ -39,8 +47,10 @@ function matchesFilters(
|
|
|
39
47
|
filePath?: string
|
|
40
48
|
httpRoute?: string
|
|
41
49
|
httpMethod?: string
|
|
50
|
+
groupBasePath?: string
|
|
42
51
|
},
|
|
43
|
-
logger: InspectorLogger
|
|
52
|
+
logger: InspectorLogger,
|
|
53
|
+
warnedGroups?: Set<string>
|
|
44
54
|
): boolean {
|
|
45
55
|
// If no filters, allow everything
|
|
46
56
|
if (Object.keys(filters).length === 0) return true
|
|
@@ -87,10 +97,13 @@ function matchesFilters(
|
|
|
87
97
|
}
|
|
88
98
|
}
|
|
89
99
|
|
|
90
|
-
// Check name filter
|
|
100
|
+
// Check name filter (match against both full ID and base name for versioned functions)
|
|
91
101
|
if (filters.names && filters.names.length > 0) {
|
|
92
|
-
const
|
|
93
|
-
|
|
102
|
+
const { baseName } = parseVersionedId(meta.name)
|
|
103
|
+
const nameMatches = filters.names.some(
|
|
104
|
+
(pattern) =>
|
|
105
|
+
matchesWildcard(meta.name, pattern) ||
|
|
106
|
+
(baseName !== meta.name && matchesWildcard(baseName, pattern))
|
|
94
107
|
)
|
|
95
108
|
if (!nameMatches) {
|
|
96
109
|
logger.debug(`⒡ Filtered by name: ${meta.type}:${meta.name}`)
|
|
@@ -107,6 +120,23 @@ function matchesFilters(
|
|
|
107
120
|
logger.debug(`⒡ Filtered by HTTP route: ${meta.httpRoute}`)
|
|
108
121
|
return false
|
|
109
122
|
}
|
|
123
|
+
|
|
124
|
+
// If route is part of a wireHTTPRoutes group, check if filter is at group level
|
|
125
|
+
if (meta.groupBasePath && warnedGroups) {
|
|
126
|
+
const groupMatches = filters.httpRoutes.some(
|
|
127
|
+
(pattern) =>
|
|
128
|
+
matchesWildcard(meta.groupBasePath!, pattern) ||
|
|
129
|
+
matchesWildcard(meta.groupBasePath! + '/*', pattern)
|
|
130
|
+
)
|
|
131
|
+
if (!groupMatches && !warnedGroups.has(meta.groupBasePath)) {
|
|
132
|
+
warnedGroups.add(meta.groupBasePath)
|
|
133
|
+
logger.warn(
|
|
134
|
+
`Filtering within wireHTTPRoutes group is not yet supported. ` +
|
|
135
|
+
`Route '${meta.httpRoute}' is part of group '${meta.groupBasePath}'. ` +
|
|
136
|
+
`Use '--httpRoutes=${meta.groupBasePath}/*' to filter the entire group.`
|
|
137
|
+
)
|
|
138
|
+
}
|
|
139
|
+
}
|
|
110
140
|
}
|
|
111
141
|
|
|
112
142
|
// Check HTTP method filter
|
|
@@ -181,6 +211,11 @@ export function filterInspectorState(
|
|
|
181
211
|
meta: JSON.parse(JSON.stringify(state.channels.meta)),
|
|
182
212
|
files: new Set<string>(), // Will be repopulated with filtered files
|
|
183
213
|
},
|
|
214
|
+
triggers: {
|
|
215
|
+
...state.triggers,
|
|
216
|
+
meta: JSON.parse(JSON.stringify(state.triggers?.meta ?? {})),
|
|
217
|
+
files: new Set<string>(),
|
|
218
|
+
},
|
|
184
219
|
scheduledTasks: {
|
|
185
220
|
...state.scheduledTasks,
|
|
186
221
|
meta: JSON.parse(JSON.stringify(state.scheduledTasks.meta)),
|
|
@@ -198,7 +233,12 @@ export function filterInspectorState(
|
|
|
198
233
|
JSON.stringify(state.mcpEndpoints.resourcesMeta)
|
|
199
234
|
),
|
|
200
235
|
promptsMeta: JSON.parse(JSON.stringify(state.mcpEndpoints.promptsMeta)),
|
|
201
|
-
files: new Set<string>(),
|
|
236
|
+
files: new Set<string>(),
|
|
237
|
+
},
|
|
238
|
+
agents: {
|
|
239
|
+
...state.agents,
|
|
240
|
+
agentsMeta: JSON.parse(JSON.stringify(state.agents?.agentsMeta ?? {})),
|
|
241
|
+
files: new Map(),
|
|
202
242
|
},
|
|
203
243
|
cli: {
|
|
204
244
|
...state.cli,
|
|
@@ -214,31 +254,31 @@ export function filterInspectorState(
|
|
|
214
254
|
const routeMeta = routes[route]
|
|
215
255
|
|
|
216
256
|
// Get function file path for directory filtering
|
|
217
|
-
const funcFile = filteredState.functions.files.get(
|
|
218
|
-
routeMeta.pikkuFuncName
|
|
219
|
-
)
|
|
257
|
+
const funcFile = filteredState.functions.files.get(routeMeta.pikkuFuncId)
|
|
220
258
|
const filePath = funcFile?.path
|
|
221
259
|
|
|
222
260
|
const matches = matchesFilters(
|
|
223
261
|
filters,
|
|
224
262
|
{
|
|
225
263
|
type: 'http' as PikkuWiringTypes,
|
|
226
|
-
name: routeMeta.
|
|
264
|
+
name: routeMeta.pikkuFuncId, // Use function name, not route
|
|
227
265
|
tags: routeMeta.tags,
|
|
228
266
|
filePath,
|
|
229
267
|
httpRoute: routeMeta.route,
|
|
230
268
|
httpMethod: routeMeta.method,
|
|
269
|
+
groupBasePath: routeMeta.groupBasePath,
|
|
231
270
|
},
|
|
232
|
-
logger
|
|
271
|
+
logger,
|
|
272
|
+
globalWarnedGroups
|
|
233
273
|
)
|
|
234
274
|
|
|
235
275
|
if (!matches) {
|
|
236
276
|
delete routes[route]
|
|
237
277
|
} else {
|
|
238
278
|
// Track used functions/middleware/permissions
|
|
239
|
-
if (routeMeta.
|
|
279
|
+
if (routeMeta.pikkuFuncId) {
|
|
240
280
|
filteredState.serviceAggregation.usedFunctions.add(
|
|
241
|
-
routeMeta.
|
|
281
|
+
routeMeta.pikkuFuncId
|
|
242
282
|
)
|
|
243
283
|
}
|
|
244
284
|
extractWireNames(routeMeta.middleware).forEach((name: string) =>
|
|
@@ -275,9 +315,9 @@ export function filterInspectorState(
|
|
|
275
315
|
if (!matches) {
|
|
276
316
|
delete filteredState.channels.meta[name]
|
|
277
317
|
} else {
|
|
278
|
-
if (channelMeta.
|
|
318
|
+
if (channelMeta.pikkuFuncId) {
|
|
279
319
|
filteredState.serviceAggregation.usedFunctions.add(
|
|
280
|
-
channelMeta.
|
|
320
|
+
channelMeta.pikkuFuncId
|
|
281
321
|
)
|
|
282
322
|
}
|
|
283
323
|
extractWireNames(channelMeta.middleware).forEach((name: string) =>
|
|
@@ -294,6 +334,35 @@ export function filterInspectorState(
|
|
|
294
334
|
filteredState.channels.files = new Set(state.channels.files)
|
|
295
335
|
}
|
|
296
336
|
|
|
337
|
+
// Filter triggers
|
|
338
|
+
for (const name of Object.keys(filteredState.triggers.meta)) {
|
|
339
|
+
const triggerMeta = filteredState.triggers.meta[name]
|
|
340
|
+
const matches = matchesFilters(
|
|
341
|
+
filters,
|
|
342
|
+
{
|
|
343
|
+
type: 'trigger' as PikkuWiringTypes,
|
|
344
|
+
name,
|
|
345
|
+
tags: triggerMeta.tags,
|
|
346
|
+
},
|
|
347
|
+
logger
|
|
348
|
+
)
|
|
349
|
+
|
|
350
|
+
if (!matches) {
|
|
351
|
+
delete filteredState.triggers.meta[name]
|
|
352
|
+
} else {
|
|
353
|
+
if (triggerMeta.pikkuFuncId) {
|
|
354
|
+
filteredState.serviceAggregation.usedFunctions.add(
|
|
355
|
+
triggerMeta.pikkuFuncId
|
|
356
|
+
)
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
// Repopulate triggers.files if any triggers remain
|
|
362
|
+
if (Object.keys(filteredState.triggers.meta).length > 0) {
|
|
363
|
+
filteredState.triggers.files = new Set(state.triggers.files)
|
|
364
|
+
}
|
|
365
|
+
|
|
297
366
|
// Filter scheduled tasks
|
|
298
367
|
for (const name of Object.keys(filteredState.scheduledTasks.meta)) {
|
|
299
368
|
const taskMeta = filteredState.scheduledTasks.meta[name]
|
|
@@ -310,10 +379,8 @@ export function filterInspectorState(
|
|
|
310
379
|
if (!matches) {
|
|
311
380
|
delete filteredState.scheduledTasks.meta[name]
|
|
312
381
|
} else {
|
|
313
|
-
if (taskMeta.
|
|
314
|
-
filteredState.serviceAggregation.usedFunctions.add(
|
|
315
|
-
taskMeta.pikkuFuncName
|
|
316
|
-
)
|
|
382
|
+
if (taskMeta.pikkuFuncId) {
|
|
383
|
+
filteredState.serviceAggregation.usedFunctions.add(taskMeta.pikkuFuncId)
|
|
317
384
|
}
|
|
318
385
|
extractWireNames(taskMeta.middleware).forEach((name: string) =>
|
|
319
386
|
filteredState.serviceAggregation.usedMiddleware.add(name)
|
|
@@ -342,9 +409,9 @@ export function filterInspectorState(
|
|
|
342
409
|
if (!matches) {
|
|
343
410
|
delete filteredState.queueWorkers.meta[name]
|
|
344
411
|
} else {
|
|
345
|
-
if (workerMeta.
|
|
412
|
+
if (workerMeta.pikkuFuncId) {
|
|
346
413
|
filteredState.serviceAggregation.usedFunctions.add(
|
|
347
|
-
workerMeta.
|
|
414
|
+
workerMeta.pikkuFuncId
|
|
348
415
|
)
|
|
349
416
|
}
|
|
350
417
|
extractWireNames(workerMeta.middleware).forEach((name: string) =>
|
|
@@ -374,10 +441,8 @@ export function filterInspectorState(
|
|
|
374
441
|
if (!matches) {
|
|
375
442
|
delete filteredState.mcpEndpoints.toolsMeta[name]
|
|
376
443
|
} else {
|
|
377
|
-
if (toolMeta.
|
|
378
|
-
filteredState.serviceAggregation.usedFunctions.add(
|
|
379
|
-
toolMeta.pikkuFuncName
|
|
380
|
-
)
|
|
444
|
+
if (toolMeta.pikkuFuncId) {
|
|
445
|
+
filteredState.serviceAggregation.usedFunctions.add(toolMeta.pikkuFuncId)
|
|
381
446
|
}
|
|
382
447
|
extractWireNames(toolMeta.middleware).forEach((name: string) =>
|
|
383
448
|
filteredState.serviceAggregation.usedMiddleware.add(name)
|
|
@@ -404,9 +469,9 @@ export function filterInspectorState(
|
|
|
404
469
|
if (!matches) {
|
|
405
470
|
delete filteredState.mcpEndpoints.resourcesMeta[name]
|
|
406
471
|
} else {
|
|
407
|
-
if (resourceMeta.
|
|
472
|
+
if (resourceMeta.pikkuFuncId) {
|
|
408
473
|
filteredState.serviceAggregation.usedFunctions.add(
|
|
409
|
-
resourceMeta.
|
|
474
|
+
resourceMeta.pikkuFuncId
|
|
410
475
|
)
|
|
411
476
|
}
|
|
412
477
|
extractWireNames(resourceMeta.middleware).forEach((name: string) =>
|
|
@@ -434,9 +499,9 @@ export function filterInspectorState(
|
|
|
434
499
|
if (!matches) {
|
|
435
500
|
delete filteredState.mcpEndpoints.promptsMeta[name]
|
|
436
501
|
} else {
|
|
437
|
-
if (promptMeta.
|
|
502
|
+
if (promptMeta.pikkuFuncId) {
|
|
438
503
|
filteredState.serviceAggregation.usedFunctions.add(
|
|
439
|
-
promptMeta.
|
|
504
|
+
promptMeta.pikkuFuncId
|
|
440
505
|
)
|
|
441
506
|
}
|
|
442
507
|
extractWireNames(promptMeta.middleware).forEach((name: string) =>
|
|
@@ -457,6 +522,40 @@ export function filterInspectorState(
|
|
|
457
522
|
filteredState.mcpEndpoints.files = new Set(state.mcpEndpoints.files)
|
|
458
523
|
}
|
|
459
524
|
|
|
525
|
+
// Filter AI agents
|
|
526
|
+
for (const name of Object.keys(filteredState.agents.agentsMeta)) {
|
|
527
|
+
const agentMeta = filteredState.agents.agentsMeta[name]
|
|
528
|
+
const matches = matchesFilters(
|
|
529
|
+
filters,
|
|
530
|
+
{
|
|
531
|
+
type: 'agent' as PikkuWiringTypes,
|
|
532
|
+
name,
|
|
533
|
+
tags: agentMeta.tags,
|
|
534
|
+
},
|
|
535
|
+
logger
|
|
536
|
+
)
|
|
537
|
+
|
|
538
|
+
if (!matches) {
|
|
539
|
+
delete filteredState.agents.agentsMeta[name]
|
|
540
|
+
} else {
|
|
541
|
+
if (agentMeta.pikkuFuncId) {
|
|
542
|
+
filteredState.serviceAggregation.usedFunctions.add(
|
|
543
|
+
agentMeta.pikkuFuncId
|
|
544
|
+
)
|
|
545
|
+
}
|
|
546
|
+
extractWireNames(agentMeta.middleware).forEach((name: string) =>
|
|
547
|
+
filteredState.serviceAggregation.usedMiddleware.add(name)
|
|
548
|
+
)
|
|
549
|
+
extractWireNames(agentMeta.permissions).forEach((name: string) =>
|
|
550
|
+
filteredState.serviceAggregation.usedPermissions.add(name)
|
|
551
|
+
)
|
|
552
|
+
}
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
if (Object.keys(filteredState.agents.agentsMeta).length > 0) {
|
|
556
|
+
filteredState.agents.files = new Map(state.agents.files)
|
|
557
|
+
}
|
|
558
|
+
|
|
460
559
|
// Filter CLI programs (note: CLI filtering might be more complex with nested commands)
|
|
461
560
|
const referencedRenderers = new Set<string>()
|
|
462
561
|
|
|
@@ -479,9 +578,9 @@ export function filterInspectorState(
|
|
|
479
578
|
if (!matches) {
|
|
480
579
|
delete programMeta.commands[commandName]
|
|
481
580
|
} else {
|
|
482
|
-
if (commandMeta.
|
|
581
|
+
if (commandMeta.pikkuFuncId) {
|
|
483
582
|
filteredState.serviceAggregation.usedFunctions.add(
|
|
484
|
-
commandMeta.
|
|
583
|
+
commandMeta.pikkuFuncId
|
|
485
584
|
)
|
|
486
585
|
}
|
|
487
586
|
extractWireNames(commandMeta.middleware).forEach((name: string) =>
|
|
@@ -517,6 +616,21 @@ export function filterInspectorState(
|
|
|
517
616
|
filteredState.cli.files = new Set(state.cli.files)
|
|
518
617
|
}
|
|
519
618
|
|
|
619
|
+
// Post-filter version expansion: include all versions of matched functions
|
|
620
|
+
const includedBaseNames = new Set<string>()
|
|
621
|
+
for (const funcId of filteredState.serviceAggregation.usedFunctions) {
|
|
622
|
+
const { baseName } = parseVersionedId(funcId)
|
|
623
|
+
includedBaseNames.add(baseName)
|
|
624
|
+
}
|
|
625
|
+
if (includedBaseNames.size > 0) {
|
|
626
|
+
for (const funcId of Object.keys(state.functions.meta)) {
|
|
627
|
+
const { baseName } = parseVersionedId(funcId)
|
|
628
|
+
if (includedBaseNames.has(baseName)) {
|
|
629
|
+
filteredState.serviceAggregation.usedFunctions.add(funcId)
|
|
630
|
+
}
|
|
631
|
+
}
|
|
632
|
+
}
|
|
633
|
+
|
|
520
634
|
// Recalculate requiredServices based on filtered functions/middleware/permissions
|
|
521
635
|
// Need to cast to InspectorState temporarily for aggregateRequiredServices
|
|
522
636
|
const stateForAggregation = filteredState as InspectorState
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { test, describe } from 'node:test'
|
|
2
2
|
import { strict as assert } from 'node:assert'
|
|
3
|
-
import { InspectorFilters } from '../types'
|
|
3
|
+
import type { InspectorFilters } from '../types'
|
|
4
4
|
import { matchesFilters, matchesWildcard } from './filter-utils'
|
|
5
5
|
|
|
6
6
|
describe('matchesFilters', () => {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { InspectorFilters, InspectorLogger } from '../types.js'
|
|
2
|
-
import { PikkuWiringTypes } from '@pikku/core'
|
|
1
|
+
import type { InspectorFilters, InspectorLogger } from '../types.js'
|
|
2
|
+
import type { PikkuWiringTypes } from '@pikku/core'
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Match a value against a pattern with wildcard support
|
|
@@ -1,10 +1,36 @@
|
|
|
1
1
|
import * as ts from 'typescript'
|
|
2
2
|
import { ErrorCode } from '../error-codes.js'
|
|
3
3
|
|
|
4
|
+
/**
|
|
5
|
+
* Extracts an array of strings from an object property.
|
|
6
|
+
*/
|
|
7
|
+
export const getArrayPropertyValue = (
|
|
8
|
+
obj: ts.ObjectLiteralExpression,
|
|
9
|
+
propertyName: string
|
|
10
|
+
): string[] | null => {
|
|
11
|
+
const property = obj.properties.find(
|
|
12
|
+
(p) =>
|
|
13
|
+
ts.isPropertyAssignment(p) &&
|
|
14
|
+
ts.isIdentifier(p.name) &&
|
|
15
|
+
p.name.text === propertyName
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
if (property && ts.isPropertyAssignment(property)) {
|
|
19
|
+
const initializer = property.initializer
|
|
20
|
+
if (ts.isArrayLiteralExpression(initializer)) {
|
|
21
|
+
return initializer.elements
|
|
22
|
+
.filter(ts.isStringLiteral)
|
|
23
|
+
.map((element) => element.text)
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
return null
|
|
28
|
+
}
|
|
29
|
+
|
|
4
30
|
export const getPropertyValue = (
|
|
5
31
|
obj: ts.ObjectLiteralExpression,
|
|
6
32
|
propertyName: string
|
|
7
|
-
): string | string[] | null | boolean => {
|
|
33
|
+
): string | string[] | number | null | boolean => {
|
|
8
34
|
const property = obj.properties.find(
|
|
9
35
|
(p) =>
|
|
10
36
|
ts.isPropertyAssignment(p) &&
|
|
@@ -41,7 +67,13 @@ export const getPropertyValue = (
|
|
|
41
67
|
return false
|
|
42
68
|
}
|
|
43
69
|
|
|
44
|
-
|
|
70
|
+
if (ts.isNumericLiteral(initializer)) {
|
|
71
|
+
if (propertyName === 'name' || propertyName === 'schedule') {
|
|
72
|
+
return initializer.text
|
|
73
|
+
}
|
|
74
|
+
return Number(initializer.text)
|
|
75
|
+
}
|
|
76
|
+
|
|
45
77
|
if (
|
|
46
78
|
ts.isStringLiteral(initializer) ||
|
|
47
79
|
ts.isNoSubstitutionTemplateLiteral(initializer)
|
|
@@ -49,7 +81,6 @@ export const getPropertyValue = (
|
|
|
49
81
|
return initializer.text
|
|
50
82
|
}
|
|
51
83
|
|
|
52
|
-
// Handle other initializer types if necessary
|
|
53
84
|
return initializer.getText()
|
|
54
85
|
}
|
|
55
86
|
|
|
@@ -70,6 +101,7 @@ export const getCommonWireMetaData = (
|
|
|
70
101
|
wiringName: string | null,
|
|
71
102
|
logger?: { critical: (code: ErrorCode, message: string) => void }
|
|
72
103
|
): {
|
|
104
|
+
disabled?: true
|
|
73
105
|
title?: string
|
|
74
106
|
tags?: string[]
|
|
75
107
|
summary?: string
|
|
@@ -77,6 +109,7 @@ export const getCommonWireMetaData = (
|
|
|
77
109
|
errors?: string[]
|
|
78
110
|
} => {
|
|
79
111
|
const metadata: {
|
|
112
|
+
disabled?: true
|
|
80
113
|
title?: string
|
|
81
114
|
tags?: string[]
|
|
82
115
|
summary?: string
|
|
@@ -88,7 +121,12 @@ export const getCommonWireMetaData = (
|
|
|
88
121
|
if (ts.isPropertyAssignment(prop) && ts.isIdentifier(prop.name)) {
|
|
89
122
|
const propName = prop.name.text
|
|
90
123
|
|
|
91
|
-
if (
|
|
124
|
+
if (
|
|
125
|
+
propName === 'disabled' &&
|
|
126
|
+
prop.initializer.kind === ts.SyntaxKind.TrueKeyword
|
|
127
|
+
) {
|
|
128
|
+
metadata.disabled = true
|
|
129
|
+
} else if (propName === 'title' && ts.isStringLiteral(prop.initializer)) {
|
|
92
130
|
metadata.title = prop.initializer.text
|
|
93
131
|
} else if (
|
|
94
132
|
propName === 'summary' &&
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { createHash } from 'crypto'
|
|
2
|
+
|
|
3
|
+
export function canonicalJSON(obj: unknown): string {
|
|
4
|
+
return JSON.stringify(sortDeep(obj))
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
function sortDeep(value: unknown): unknown {
|
|
8
|
+
if (value === null || value === undefined) {
|
|
9
|
+
return value
|
|
10
|
+
}
|
|
11
|
+
if (Array.isArray(value)) {
|
|
12
|
+
return value.map(sortDeep)
|
|
13
|
+
}
|
|
14
|
+
if (typeof value === 'object') {
|
|
15
|
+
const sorted: Record<string, unknown> = {}
|
|
16
|
+
for (const key of Object.keys(value as Record<string, unknown>).sort()) {
|
|
17
|
+
sorted[key] = sortDeep((value as Record<string, unknown>)[key])
|
|
18
|
+
}
|
|
19
|
+
return sorted
|
|
20
|
+
}
|
|
21
|
+
return value
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export function hashString(input: string, length: number = 16): string {
|
|
25
|
+
return createHash('sha256').update(input).digest('hex').slice(0, length)
|
|
26
|
+
}
|