@pikku/inspector 0.8.0 → 0.9.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.
Files changed (43) hide show
  1. package/CHANGELOG.md +33 -0
  2. package/dist/add-channel.d.ts +3 -3
  3. package/dist/add-channel.js +8 -7
  4. package/dist/add-file-extends-core-type.js +0 -1
  5. package/dist/add-functions.d.ts +2 -2
  6. package/dist/add-functions.js +2 -3
  7. package/dist/add-http-route.d.ts +3 -3
  8. package/dist/add-http-route.js +6 -5
  9. package/dist/add-mcp-prompt.d.ts +2 -2
  10. package/dist/add-mcp-prompt.js +6 -5
  11. package/dist/add-mcp-resource.d.ts +2 -2
  12. package/dist/add-mcp-resource.js +6 -5
  13. package/dist/add-mcp-tool.d.ts +2 -2
  14. package/dist/add-mcp-tool.js +6 -5
  15. package/dist/add-queue-worker.d.ts +2 -2
  16. package/dist/add-queue-worker.js +5 -4
  17. package/dist/add-schedule.d.ts +2 -2
  18. package/dist/add-schedule.js +5 -4
  19. package/dist/inspector.d.ts +2 -2
  20. package/dist/inspector.js +3 -3
  21. package/dist/types.d.ts +10 -2
  22. package/dist/utils.d.ts +5 -4
  23. package/dist/utils.js +41 -6
  24. package/dist/visit.d.ts +3 -3
  25. package/dist/visit.js +12 -12
  26. package/lcov.info +4606 -0
  27. package/package.json +2 -2
  28. package/run-tests.sh +0 -0
  29. package/src/add-channel.ts +22 -10
  30. package/src/add-file-extends-core-type.ts +0 -2
  31. package/src/add-functions.ts +4 -6
  32. package/src/add-http-route.ts +10 -6
  33. package/src/add-mcp-prompt.ts +10 -6
  34. package/src/add-mcp-resource.ts +10 -6
  35. package/src/add-mcp-tool.ts +10 -6
  36. package/src/add-queue-worker.ts +9 -5
  37. package/src/add-schedule.ts +9 -5
  38. package/src/inspector.ts +4 -2
  39. package/src/types.ts +11 -2
  40. package/src/utils.test.ts +484 -0
  41. package/src/utils.ts +59 -9
  42. package/src/visit.ts +19 -13
  43. package/tsconfig.tsbuildinfo +1 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pikku/inspector",
3
- "version": "0.8.0",
3
+ "version": "0.9.0",
4
4
  "author": "yasser.fadl@gmail.com",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -17,7 +17,7 @@
17
17
  "test:coverage": "bash run-tests.sh --coverage"
18
18
  },
19
19
  "dependencies": {
20
- "@pikku/core": "^0.8.0",
20
+ "@pikku/core": "^0.9.0",
21
21
  "path-to-regexp": "^8.2.0",
22
22
  "typescript": "^5.6"
23
23
  },
package/run-tests.sh CHANGED
File without changes
@@ -1,14 +1,18 @@
1
1
  import * as ts from 'typescript'
2
2
  import { getPropertyValue } from './get-property-value.js'
3
3
  import { pathToRegexp } from 'path-to-regexp'
4
- import { APIDocs, PikkuEventTypes } from '@pikku/core'
4
+ import { APIDocs, PikkuWiringTypes } from '@pikku/core'
5
5
  import {
6
6
  extractFunctionName,
7
7
  getPropertyAssignmentInitializer,
8
8
  matchesFilters,
9
9
  } from './utils.js'
10
10
  import type { ChannelMessageMeta, ChannelMeta } from '@pikku/core/channel'
11
- import type { InspectorFilters, InspectorState } from './types.js'
11
+ import type {
12
+ InspectorFilters,
13
+ InspectorState,
14
+ InspectorLogger,
15
+ } from './types.js'
12
16
 
13
17
  /**
14
18
  * Safely get the “initializer” expression of a property-like AST node:
@@ -103,11 +107,11 @@ export function addMessagesRoutes(
103
107
  obj: ts.ObjectLiteralExpression,
104
108
  state: InspectorState,
105
109
  checker: ts.TypeChecker
106
- ): ChannelMeta['messageRoutes'] {
107
- const result: ChannelMeta['messageRoutes'] = {}
110
+ ): ChannelMeta['messageWirings'] {
111
+ const result: ChannelMeta['messageWirings'] = {}
108
112
  const onMsgRouteProp = getPropertyAssignmentInitializer(
109
113
  obj,
110
- 'onMessageRoute',
114
+ 'onMessageWiring',
111
115
  true,
112
116
  checker
113
117
  )
@@ -363,11 +367,12 @@ export function addChannel(
363
367
  node: ts.Node,
364
368
  checker: ts.TypeChecker,
365
369
  state: InspectorState,
366
- filters: InspectorFilters
370
+ filters: InspectorFilters,
371
+ logger: InspectorLogger
367
372
  ) {
368
373
  if (!ts.isCallExpression(node)) return
369
374
  const { expression, arguments: args } = node
370
- if (!ts.isIdentifier(expression) || expression.text !== 'addChannel') return
375
+ if (!ts.isIdentifier(expression) || expression.text !== 'wireChannel') return
371
376
  const first = args[0]
372
377
  if (!first || !ts.isObjectLiteralExpression(first)) return
373
378
 
@@ -391,8 +396,15 @@ export function addChannel(
391
396
  const tags = getPropertyValue(obj, 'tags') as string[] | undefined
392
397
  const query = getPropertyValue(obj, 'query') as string[] | []
393
398
 
399
+ const filePath = node.getSourceFile().fileName
400
+
394
401
  if (
395
- !matchesFilters(filters, { tags }, { type: PikkuEventTypes.channel, name })
402
+ !matchesFilters(
403
+ filters,
404
+ { tags },
405
+ { type: PikkuWiringTypes.channel, name, filePath },
406
+ logger
407
+ )
396
408
  )
397
409
  return
398
410
 
@@ -436,7 +448,7 @@ export function addChannel(
436
448
  }
437
449
 
438
450
  // nested message-routes
439
- const messageRoutes = addMessagesRoutes(obj, state, checker)
451
+ const messageWirings = addMessagesRoutes(obj, state, checker)
440
452
 
441
453
  // record into state
442
454
  state.channels.files.add(node.getSourceFile().fileName)
@@ -463,7 +475,7 @@ export function addChannel(
463
475
  }
464
476
  : null,
465
477
  message,
466
- messageRoutes,
478
+ messageWirings,
467
479
  docs: docs ?? undefined,
468
480
  tags: tags ?? undefined,
469
481
  }
@@ -1,8 +1,6 @@
1
1
  import * as ts from 'typescript'
2
2
  import { PathToNameAndType } from './types.js'
3
3
 
4
- // const VRAMEWORK_TYPES = ['CoreConfig', 'CoreService', 'CoreServices', 'CoreSingletonService', 'CoreSessionService']
5
-
6
4
  export const addFileExtendsCoreType = (
7
5
  node: ts.Node,
8
6
  checker: ts.TypeChecker,
@@ -1,5 +1,5 @@
1
1
  import * as ts from 'typescript'
2
- import { InspectorState, InspectorFilters } from './types.js'
2
+ import { InspectorState, InspectorFilters, InspectorLogger } from './types.js'
3
3
  import { TypesMap } from './types-map.js'
4
4
  import {
5
5
  extractFunctionName,
@@ -231,7 +231,8 @@ export function addFunctions(
231
231
  node: ts.Node,
232
232
  checker: ts.TypeChecker,
233
233
  state: InspectorState,
234
- filters: InspectorFilters
234
+ filters: InspectorFilters,
235
+ logger: InspectorLogger
235
236
  ) {
236
237
  if (!ts.isCallExpression(node)) return
237
238
 
@@ -305,10 +306,7 @@ export function addFunctions(
305
306
  services.services.push(original)
306
307
  }
307
308
  }
308
- } else if (
309
- ts.isIdentifier(firstParam.name) &&
310
- !firstParam.name.text.startsWith('_')
311
- ) {
309
+ } else if (ts.isIdentifier(firstParam.name)) {
312
310
  services.optimized = false
313
311
  }
314
312
  }
@@ -2,13 +2,13 @@ import * as ts from 'typescript'
2
2
  import { getPropertyValue } from './get-property-value.js'
3
3
  import { pathToRegexp } from 'path-to-regexp'
4
4
  import { HTTPMethod } from '@pikku/core/http'
5
- import { APIDocs, PikkuEventTypes } from '@pikku/core'
5
+ import { APIDocs, PikkuWiringTypes } from '@pikku/core'
6
6
  import {
7
7
  extractFunctionName,
8
8
  getPropertyAssignmentInitializer,
9
9
  matchesFilters,
10
10
  } from './utils.js'
11
- import { InspectorState, InspectorFilters } from './types.js'
11
+ import { InspectorState, InspectorFilters, InspectorLogger } from './types.js'
12
12
 
13
13
  /**
14
14
  * Populate metaInputTypes for a given route based on method, input type,
@@ -36,20 +36,21 @@ export const getInputTypes = (
36
36
  }
37
37
 
38
38
  /**
39
- * Simplified addHTTPRoute: re-uses function metadata from state.functions.meta
39
+ * Simplified wireHTTP: re-uses function metadata from state.functions.meta
40
40
  * instead of re-inferring types here.
41
41
  */
42
42
  export const addHTTPRoute = (
43
43
  node: ts.Node,
44
44
  checker: ts.TypeChecker,
45
45
  state: InspectorState,
46
- filters: InspectorFilters
46
+ filters: InspectorFilters,
47
+ logger: InspectorLogger
47
48
  ) => {
48
49
  // only look at calls
49
50
  if (!ts.isCallExpression(node)) return
50
51
 
51
52
  const { expression, arguments: args } = node
52
- if (!ts.isIdentifier(expression) || expression.text !== 'addHTTPRoute') return
53
+ if (!ts.isIdentifier(expression) || expression.text !== 'wireHTTP') return
53
54
 
54
55
  // must pass an object literal
55
56
  const firstArg = args[0]
@@ -69,11 +70,14 @@ export const addHTTPRoute = (
69
70
  const tags = (getPropertyValue(obj, 'tags') as string[]) || undefined
70
71
  const query = (getPropertyValue(obj, 'query') as string[]) || []
71
72
 
73
+ const filePath = node.getSourceFile().fileName
74
+
72
75
  if (
73
76
  !matchesFilters(
74
77
  filters,
75
78
  { tags },
76
- { type: PikkuEventTypes.http, name: route }
79
+ { type: PikkuWiringTypes.http, name: route, filePath },
80
+ logger
77
81
  )
78
82
  ) {
79
83
  return
@@ -1,7 +1,7 @@
1
1
  import * as ts from 'typescript'
2
2
  import { getPropertyValue } from './get-property-value.js'
3
- import { PikkuEventTypes } from '@pikku/core'
4
- import { InspectorFilters, InspectorState } from './types.js'
3
+ import { PikkuWiringTypes } from '@pikku/core'
4
+ import { InspectorFilters, InspectorState, InspectorLogger } from './types.js'
5
5
  import {
6
6
  extractFunctionName,
7
7
  getPropertyAssignmentInitializer,
@@ -12,7 +12,8 @@ export const addMCPPrompt = (
12
12
  node: ts.Node,
13
13
  checker: ts.TypeChecker,
14
14
  state: InspectorState,
15
- filters: InspectorFilters
15
+ filters: InspectorFilters,
16
+ logger: InspectorLogger
16
17
  ) => {
17
18
  if (!ts.isCallExpression(node)) {
18
19
  return
@@ -22,8 +23,8 @@ export const addMCPPrompt = (
22
23
  const firstArg = args[0]
23
24
  const expression = node.expression
24
25
 
25
- // Check if the call is to addMCPPrompt
26
- if (!ts.isIdentifier(expression) || expression.text !== 'addMCPPrompt') {
26
+ // Check if the call is to wireMCPPrompt
27
+ if (!ts.isIdentifier(expression) || expression.text !== 'wireMCPPrompt') {
27
28
  return
28
29
  }
29
30
 
@@ -66,11 +67,14 @@ export const addMCPPrompt = (
66
67
  return
67
68
  }
68
69
 
70
+ const filePath = node.getSourceFile().fileName
71
+
69
72
  if (
70
73
  !matchesFilters(
71
74
  filters,
72
75
  { tags },
73
- { type: PikkuEventTypes.mcp, name: nameValue }
76
+ { type: PikkuWiringTypes.mcp, name: nameValue, filePath },
77
+ logger
74
78
  )
75
79
  ) {
76
80
  return
@@ -1,7 +1,7 @@
1
1
  import * as ts from 'typescript'
2
2
  import { getPropertyValue } from './get-property-value.js'
3
- import { PikkuEventTypes } from '@pikku/core'
4
- import { InspectorFilters, InspectorState } from './types.js'
3
+ import { PikkuWiringTypes } from '@pikku/core'
4
+ import { InspectorFilters, InspectorState, InspectorLogger } from './types.js'
5
5
  import {
6
6
  extractFunctionName,
7
7
  getPropertyAssignmentInitializer,
@@ -12,7 +12,8 @@ export const addMCPResource = (
12
12
  node: ts.Node,
13
13
  checker: ts.TypeChecker,
14
14
  state: InspectorState,
15
- filters: InspectorFilters
15
+ filters: InspectorFilters,
16
+ logger: InspectorLogger
16
17
  ) => {
17
18
  if (!ts.isCallExpression(node)) {
18
19
  return
@@ -22,8 +23,8 @@ export const addMCPResource = (
22
23
  const firstArg = args[0]
23
24
  const expression = node.expression
24
25
 
25
- // Check if the call is to addMCPResource
26
- if (!ts.isIdentifier(expression) || expression.text !== 'addMCPResource') {
26
+ // Check if the call is to wireMCPResource
27
+ if (!ts.isIdentifier(expression) || expression.text !== 'wireMCPResource') {
27
28
  return
28
29
  }
29
30
 
@@ -77,11 +78,14 @@ export const addMCPResource = (
77
78
  return
78
79
  }
79
80
 
81
+ const filePath = node.getSourceFile().fileName
82
+
80
83
  if (
81
84
  !matchesFilters(
82
85
  filters,
83
86
  { tags },
84
- { type: PikkuEventTypes.mcp, name: uriValue }
87
+ { type: PikkuWiringTypes.mcp, name: uriValue, filePath },
88
+ logger
85
89
  )
86
90
  ) {
87
91
  return
@@ -1,7 +1,7 @@
1
1
  import * as ts from 'typescript'
2
2
  import { getPropertyValue } from './get-property-value.js'
3
- import { PikkuEventTypes } from '@pikku/core'
4
- import { InspectorFilters, InspectorState } from './types.js'
3
+ import { PikkuWiringTypes } from '@pikku/core'
4
+ import { InspectorFilters, InspectorState, InspectorLogger } from './types.js'
5
5
  import {
6
6
  extractFunctionName,
7
7
  getPropertyAssignmentInitializer,
@@ -12,7 +12,8 @@ export const addMCPTool = (
12
12
  node: ts.Node,
13
13
  checker: ts.TypeChecker,
14
14
  state: InspectorState,
15
- filters: InspectorFilters
15
+ filters: InspectorFilters,
16
+ logger: InspectorLogger
16
17
  ) => {
17
18
  if (!ts.isCallExpression(node)) {
18
19
  return
@@ -22,8 +23,8 @@ export const addMCPTool = (
22
23
  const firstArg = args[0]
23
24
  const expression = node.expression
24
25
 
25
- // Check if the call is to addMCPTool
26
- if (!ts.isIdentifier(expression) || expression.text !== 'addMCPTool') {
26
+ // Check if the call is to wireMCPTool
27
+ if (!ts.isIdentifier(expression) || expression.text !== 'wireMCPTool') {
27
28
  return
28
29
  }
29
30
 
@@ -68,11 +69,14 @@ export const addMCPTool = (
68
69
  return
69
70
  }
70
71
 
72
+ const filePath = node.getSourceFile().fileName
73
+
71
74
  if (
72
75
  !matchesFilters(
73
76
  filters,
74
77
  { tags },
75
- { type: PikkuEventTypes.mcp, name: nameValue }
78
+ { type: PikkuWiringTypes.mcp, name: nameValue, filePath },
79
+ logger
76
80
  )
77
81
  ) {
78
82
  return
@@ -1,7 +1,7 @@
1
1
  import * as ts from 'typescript'
2
2
  import { getPropertyValue } from './get-property-value.js'
3
- import { APIDocs, PikkuEventTypes } from '@pikku/core'
4
- import { InspectorFilters, InspectorState } from './types.js'
3
+ import { APIDocs, PikkuWiringTypes } from '@pikku/core'
4
+ import { InspectorFilters, InspectorState, InspectorLogger } from './types.js'
5
5
  import {
6
6
  extractFunctionName,
7
7
  getPropertyAssignmentInitializer,
@@ -12,7 +12,8 @@ export const addQueueWorker = (
12
12
  node: ts.Node,
13
13
  checker: ts.TypeChecker,
14
14
  state: InspectorState,
15
- filters: InspectorFilters
15
+ filters: InspectorFilters,
16
+ logger: InspectorLogger
16
17
  ) => {
17
18
  if (!ts.isCallExpression(node)) {
18
19
  return
@@ -23,7 +24,7 @@ export const addQueueWorker = (
23
24
  const expression = node.expression
24
25
 
25
26
  // Check if the call is to addQueueWorker
26
- if (!ts.isIdentifier(expression) || expression.text !== 'addQueueWorker') {
27
+ if (!ts.isIdentifier(expression) || expression.text !== 'wireQueueWorker') {
27
28
  return
28
29
  }
29
30
 
@@ -64,11 +65,14 @@ export const addQueueWorker = (
64
65
  return
65
66
  }
66
67
 
68
+ const filePath = node.getSourceFile().fileName
69
+
67
70
  if (
68
71
  !matchesFilters(
69
72
  filters,
70
73
  { tags },
71
- { type: PikkuEventTypes.queue, name: queueName }
74
+ { type: PikkuWiringTypes.queue, name: queueName, filePath },
75
+ logger
72
76
  )
73
77
  ) {
74
78
  console.info(
@@ -1,7 +1,7 @@
1
1
  import * as ts from 'typescript'
2
2
  import { getPropertyValue } from './get-property-value.js'
3
- import { APIDocs, PikkuEventTypes } from '@pikku/core'
4
- import { InspectorFilters, InspectorState } from './types.js'
3
+ import { APIDocs, PikkuWiringTypes } from '@pikku/core'
4
+ import { InspectorFilters, InspectorState, InspectorLogger } from './types.js'
5
5
  import {
6
6
  extractFunctionName,
7
7
  getPropertyAssignmentInitializer,
@@ -12,7 +12,8 @@ export const addSchedule = (
12
12
  node: ts.Node,
13
13
  checker: ts.TypeChecker,
14
14
  state: InspectorState,
15
- filters: InspectorFilters
15
+ filters: InspectorFilters,
16
+ logger: InspectorLogger
16
17
  ) => {
17
18
  if (!ts.isCallExpression(node)) {
18
19
  return
@@ -23,7 +24,7 @@ export const addSchedule = (
23
24
  const expression = node.expression
24
25
 
25
26
  // Check if the call is to addScheduledTask
26
- if (!ts.isIdentifier(expression) || expression.text !== 'addScheduledTask') {
27
+ if (!ts.isIdentifier(expression) || expression.text !== 'wireScheduler') {
27
28
  return
28
29
  }
29
30
 
@@ -61,11 +62,14 @@ export const addSchedule = (
61
62
  return
62
63
  }
63
64
 
65
+ const filePath = node.getSourceFile().fileName
66
+
64
67
  if (
65
68
  !matchesFilters(
66
69
  filters,
67
70
  { tags },
68
- { type: PikkuEventTypes.scheduled, name: nameValue }
71
+ { type: PikkuWiringTypes.scheduler, name: nameValue, filePath },
72
+ logger
69
73
  )
70
74
  ) {
71
75
  return
package/src/inspector.ts CHANGED
@@ -5,6 +5,7 @@ import {
5
5
  InspectorState,
6
6
  InspectorHTTPState,
7
7
  InspectorFilters,
8
+ InspectorLogger,
8
9
  } from './types.js'
9
10
 
10
11
  export const normalizeHTTPTypes = (
@@ -14,6 +15,7 @@ export const normalizeHTTPTypes = (
14
15
  }
15
16
 
16
17
  export const inspect = (
18
+ logger: InspectorLogger,
17
19
  routeFiles: string[],
18
20
  filters: InspectorFilters
19
21
  ): InspectorState => {
@@ -67,14 +69,14 @@ export const inspect = (
67
69
  // First sweep: add all functions
68
70
  for (const sourceFile of sourceFiles) {
69
71
  ts.forEachChild(sourceFile, (child) =>
70
- visitSetup(checker, child, state, filters)
72
+ visitSetup(checker, child, state, filters, logger)
71
73
  )
72
74
  }
73
75
 
74
76
  // Second sweep: add all transports
75
77
  for (const sourceFile of sourceFiles) {
76
78
  ts.forEachChild(sourceFile, (child) =>
77
- visitRoutes(checker, child, state, filters)
79
+ visitRoutes(checker, child, state, filters, logger)
78
80
  )
79
81
  }
80
82
 
package/src/types.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { ChannelsMeta } from '@pikku/core/channel'
2
- import { HTTPRoutesMeta } from '@pikku/core/http'
2
+ import { HTTPWiringsMeta } from '@pikku/core/http'
3
3
  import { ScheduledTasksMeta } from '@pikku/core/scheduler'
4
4
  import { queueWorkersMeta } from '@pikku/core/queue'
5
5
  import { MCPResourceMeta, MCPToolMeta, MCPPromptMeta } from '@pikku/core'
@@ -23,7 +23,7 @@ export type MetaInputTypes = Map<
23
23
 
24
24
  export interface InspectorHTTPState {
25
25
  metaInputTypes: MetaInputTypes
26
- meta: HTTPRoutesMeta
26
+ meta: HTTPWiringsMeta
27
27
  files: Set<string>
28
28
  }
29
29
 
@@ -40,6 +40,15 @@ export interface InspectorChannelState {
40
40
 
41
41
  export type InspectorFilters = {
42
42
  tags?: string[]
43
+ types?: string[]
44
+ directories?: string[]
45
+ }
46
+
47
+ export interface InspectorLogger {
48
+ info: (message: string) => void
49
+ error: (message: string) => void
50
+ warn: (message: string) => void
51
+ debug: (message: string) => void
43
52
  }
44
53
  export interface InspectorState {
45
54
  singletonServicesTypeImportMap: PathToNameAndType