@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/CHANGELOG.md CHANGED
@@ -1,5 +1,38 @@
1
1
  # @pikku/inspector
2
2
 
3
+ ## 0.9.0
4
+
5
+ ### Breaking Changes
6
+
7
+ - Normalized all transports to use "wirings" instead of events/routes/transports for consistency across the framework
8
+
9
+ ## 0.8.1
10
+
11
+ ### Patch Changes
12
+
13
+ - 44e3ff4: feat: enhance CLI filtering with type and directory filters
14
+
15
+ - Add --types filter to filter by PikkuEventTypes (http, channel, queue, scheduler, rpc, mcp)
16
+ - Add --directories filter to filter by file paths/directories
17
+ - All filters (tags, types, directories) now work together with AND logic
18
+ - Add comprehensive logging interface to inspector package
19
+ - Add comprehensive test suite for matchesFilters function
20
+ - Support cross-platform path handling
21
+
22
+ - 7c592b8: feat: support for required services and improved service configuration
23
+
24
+ This release includes several enhancements to service management and configuration:
25
+
26
+ - Added support for required services configuration
27
+ - Improved service discovery and registration
28
+ - Added typed RPC clients for service communication
29
+ - Updated middleware to run per function
30
+
31
+ - Updated dependencies [3261090]
32
+ - Updated dependencies [7c592b8]
33
+ - Updated dependencies [30a082f]
34
+ - @pikku/core@0.8.1
35
+
3
36
  ## 0.8.0
4
37
 
5
38
  ### Major Features
@@ -1,13 +1,13 @@
1
1
  import * as ts from 'typescript';
2
2
  import type { ChannelMeta } from '@pikku/core/channel';
3
- import type { InspectorFilters, InspectorState } from './types.js';
3
+ import type { InspectorFilters, InspectorState, InspectorLogger } from './types.js';
4
4
  /**
5
5
  * Build out the nested message-routes by looking up each handler
6
6
  * in state.functions.meta instead of re-inferring it here.
7
7
  */
8
- export declare function addMessagesRoutes(obj: ts.ObjectLiteralExpression, state: InspectorState, checker: ts.TypeChecker): ChannelMeta['messageRoutes'];
8
+ export declare function addMessagesRoutes(obj: ts.ObjectLiteralExpression, state: InspectorState, checker: ts.TypeChecker): ChannelMeta['messageWirings'];
9
9
  /**
10
10
  * Inspect addChannel calls, look up all handlers in state.functions.meta,
11
11
  * and emit one entry into state.channels.meta.
12
12
  */
13
- export declare function addChannel(node: ts.Node, checker: ts.TypeChecker, state: InspectorState, filters: InspectorFilters): void;
13
+ export declare function addChannel(node: ts.Node, checker: ts.TypeChecker, state: InspectorState, filters: InspectorFilters, logger: InspectorLogger): void;
@@ -1,7 +1,7 @@
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 { PikkuEventTypes } from '@pikku/core';
4
+ import { PikkuWiringTypes } from '@pikku/core';
5
5
  import { extractFunctionName, getPropertyAssignmentInitializer, matchesFilters, } from './utils.js';
6
6
  /**
7
7
  * Safely get the “initializer” expression of a property-like AST node:
@@ -76,7 +76,7 @@ function getHandlerNameFromExpression(expr, checker) {
76
76
  */
77
77
  export function addMessagesRoutes(obj, state, checker) {
78
78
  const result = {};
79
- const onMsgRouteProp = getPropertyAssignmentInitializer(obj, 'onMessageRoute', true, checker);
79
+ const onMsgRouteProp = getPropertyAssignmentInitializer(obj, 'onMessageWiring', true, checker);
80
80
  if (!onMsgRouteProp)
81
81
  return result;
82
82
  if (!onMsgRouteProp || !ts.isObjectLiteralExpression(onMsgRouteProp))
@@ -267,11 +267,11 @@ export function addMessagesRoutes(obj, state, checker) {
267
267
  * Inspect addChannel calls, look up all handlers in state.functions.meta,
268
268
  * and emit one entry into state.channels.meta.
269
269
  */
270
- export function addChannel(node, checker, state, filters) {
270
+ export function addChannel(node, checker, state, filters, logger) {
271
271
  if (!ts.isCallExpression(node))
272
272
  return;
273
273
  const { expression, arguments: args } = node;
274
- if (!ts.isIdentifier(expression) || expression.text !== 'addChannel')
274
+ if (!ts.isIdentifier(expression) || expression.text !== 'wireChannel')
275
275
  return;
276
276
  const first = args[0];
277
277
  if (!first || !ts.isObjectLiteralExpression(first))
@@ -292,7 +292,8 @@ export function addChannel(node, checker, state, filters) {
292
292
  const docs = getPropertyValue(obj, 'docs');
293
293
  const tags = getPropertyValue(obj, 'tags');
294
294
  const query = getPropertyValue(obj, 'query');
295
- if (!matchesFilters(filters, { tags }, { type: PikkuEventTypes.channel, name }))
295
+ const filePath = node.getSourceFile().fileName;
296
+ if (!matchesFilters(filters, { tags }, { type: PikkuWiringTypes.channel, name, filePath }, logger))
296
297
  return;
297
298
  const connect = getPropertyAssignmentInitializer(obj, 'onConnect', false, checker);
298
299
  const disconnect = getPropertyAssignmentInitializer(obj, 'onDisconnect', false, checker);
@@ -314,7 +315,7 @@ export function addChannel(node, checker, state, filters) {
314
315
  }
315
316
  }
316
317
  // nested message-routes
317
- const messageRoutes = addMessagesRoutes(obj, state, checker);
318
+ const messageWirings = addMessagesRoutes(obj, state, checker);
318
319
  // record into state
319
320
  state.channels.files.add(node.getSourceFile().fileName);
320
321
  state.channels.meta[name] = {
@@ -340,7 +341,7 @@ export function addChannel(node, checker, state, filters) {
340
341
  }
341
342
  : null,
342
343
  message,
343
- messageRoutes,
344
+ messageWirings,
344
345
  docs: docs ?? undefined,
345
346
  tags: tags ?? undefined,
346
347
  };
@@ -1,5 +1,4 @@
1
1
  import * as ts from 'typescript';
2
- // const VRAMEWORK_TYPES = ['CoreConfig', 'CoreService', 'CoreServices', 'CoreSingletonService', 'CoreSessionService']
3
2
  export const addFileExtendsCoreType = (node, checker, methods, expectedTypeName) => {
4
3
  if (ts.isClassDeclaration(node) || ts.isInterfaceDeclaration(node)) {
5
4
  const fileName = node.getSourceFile().fileName;
@@ -1,7 +1,7 @@
1
1
  import * as ts from 'typescript';
2
- import { InspectorState, InspectorFilters } from './types.js';
2
+ import { InspectorState, InspectorFilters, InspectorLogger } from './types.js';
3
3
  /**
4
4
  * Inspect pikkuFunc calls, extract input/output and first-arg destructuring,
5
5
  * then push into state.functions.meta.
6
6
  */
7
- export declare function addFunctions(node: ts.Node, checker: ts.TypeChecker, state: InspectorState, filters: InspectorFilters): void;
7
+ export declare function addFunctions(node: ts.Node, checker: ts.TypeChecker, state: InspectorState, filters: InspectorFilters, logger: InspectorLogger): void;
@@ -171,7 +171,7 @@ function unwrapPromise(checker, type) {
171
171
  * Inspect pikkuFunc calls, extract input/output and first-arg destructuring,
172
172
  * then push into state.functions.meta.
173
173
  */
174
- export function addFunctions(node, checker, state, filters) {
174
+ export function addFunctions(node, checker, state, filters, logger) {
175
175
  if (!ts.isCallExpression(node))
176
176
  return;
177
177
  const { expression, arguments: args, typeArguments } = node;
@@ -226,8 +226,7 @@ export function addFunctions(node, checker, state, filters) {
226
226
  }
227
227
  }
228
228
  }
229
- else if (ts.isIdentifier(firstParam.name) &&
230
- !firstParam.name.text.startsWith('_')) {
229
+ else if (ts.isIdentifier(firstParam.name)) {
231
230
  services.optimized = false;
232
231
  }
233
232
  }
@@ -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
  /**
4
4
  * Populate metaInputTypes for a given route based on method, input type,
5
5
  * query and params. Returns undefined (we only mutate metaTypes).
@@ -10,7 +10,7 @@ export declare const getInputTypes: (metaTypes: Map<string, {
10
10
  body?: string[];
11
11
  }>, methodType: string, inputType: string | null, queryValues: string[], paramsValues: string[]) => undefined;
12
12
  /**
13
- * Simplified addHTTPRoute: re-uses function metadata from state.functions.meta
13
+ * Simplified wireHTTP: re-uses function metadata from state.functions.meta
14
14
  * instead of re-inferring types here.
15
15
  */
16
- export declare const addHTTPRoute: (node: ts.Node, checker: ts.TypeChecker, state: InspectorState, filters: InspectorFilters) => void;
16
+ export declare const addHTTPRoute: (node: ts.Node, checker: ts.TypeChecker, state: InspectorState, filters: InspectorFilters, logger: InspectorLogger) => void;
@@ -1,7 +1,7 @@
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 { PikkuEventTypes } from '@pikku/core';
4
+ import { PikkuWiringTypes } from '@pikku/core';
5
5
  import { extractFunctionName, getPropertyAssignmentInitializer, matchesFilters, } from './utils.js';
6
6
  /**
7
7
  * Populate metaInputTypes for a given route based on method, input type,
@@ -20,15 +20,15 @@ export const getInputTypes = (metaTypes, methodType, inputType, queryValues, par
20
20
  return;
21
21
  };
22
22
  /**
23
- * Simplified addHTTPRoute: re-uses function metadata from state.functions.meta
23
+ * Simplified wireHTTP: re-uses function metadata from state.functions.meta
24
24
  * instead of re-inferring types here.
25
25
  */
26
- export const addHTTPRoute = (node, checker, state, filters) => {
26
+ export const addHTTPRoute = (node, checker, state, filters, logger) => {
27
27
  // only look at calls
28
28
  if (!ts.isCallExpression(node))
29
29
  return;
30
30
  const { expression, arguments: args } = node;
31
- if (!ts.isIdentifier(expression) || expression.text !== 'addHTTPRoute')
31
+ if (!ts.isIdentifier(expression) || expression.text !== 'wireHTTP')
32
32
  return;
33
33
  // must pass an object literal
34
34
  const firstArg = args[0];
@@ -45,7 +45,8 @@ export const addHTTPRoute = (node, checker, state, filters) => {
45
45
  const docs = getPropertyValue(obj, 'docs') || undefined;
46
46
  const tags = getPropertyValue(obj, 'tags') || undefined;
47
47
  const query = getPropertyValue(obj, 'query') || [];
48
- if (!matchesFilters(filters, { tags }, { type: PikkuEventTypes.http, name: route })) {
48
+ const filePath = node.getSourceFile().fileName;
49
+ if (!matchesFilters(filters, { tags }, { type: PikkuWiringTypes.http, name: route, filePath }, logger)) {
49
50
  return;
50
51
  }
51
52
  // --- find the referenced function ---
@@ -1,3 +1,3 @@
1
1
  import * as ts from 'typescript';
2
- import { InspectorFilters, InspectorState } from './types.js';
3
- export declare const addMCPPrompt: (node: ts.Node, checker: ts.TypeChecker, state: InspectorState, filters: InspectorFilters) => void;
2
+ import { InspectorFilters, InspectorState, InspectorLogger } from './types.js';
3
+ export declare const addMCPPrompt: (node: ts.Node, checker: ts.TypeChecker, state: InspectorState, filters: InspectorFilters, logger: InspectorLogger) => void;
@@ -1,16 +1,16 @@
1
1
  import * as ts from 'typescript';
2
2
  import { getPropertyValue } from './get-property-value.js';
3
- import { PikkuEventTypes } from '@pikku/core';
3
+ import { PikkuWiringTypes } from '@pikku/core';
4
4
  import { extractFunctionName, getPropertyAssignmentInitializer, matchesFilters, } from './utils.js';
5
- export const addMCPPrompt = (node, checker, state, filters) => {
5
+ export const addMCPPrompt = (node, checker, state, filters, logger) => {
6
6
  if (!ts.isCallExpression(node)) {
7
7
  return;
8
8
  }
9
9
  const args = node.arguments;
10
10
  const firstArg = args[0];
11
11
  const expression = node.expression;
12
- // Check if the call is to addMCPPrompt
13
- if (!ts.isIdentifier(expression) || expression.text !== 'addMCPPrompt') {
12
+ // Check if the call is to wireMCPPrompt
13
+ if (!ts.isIdentifier(expression) || expression.text !== 'wireMCPPrompt') {
14
14
  return;
15
15
  }
16
16
  if (!firstArg) {
@@ -35,7 +35,8 @@ export const addMCPPrompt = (node, checker, state, filters) => {
35
35
  console.error(`• MCP prompt '${nameValue}' is missing a description.`);
36
36
  return;
37
37
  }
38
- if (!matchesFilters(filters, { tags }, { type: PikkuEventTypes.mcp, name: nameValue })) {
38
+ const filePath = node.getSourceFile().fileName;
39
+ if (!matchesFilters(filters, { tags }, { type: PikkuWiringTypes.mcp, name: nameValue, filePath }, logger)) {
39
40
  return;
40
41
  }
41
42
  // lookup existing function metadata
@@ -1,3 +1,3 @@
1
1
  import * as ts from 'typescript';
2
- import { InspectorFilters, InspectorState } from './types.js';
3
- export declare const addMCPResource: (node: ts.Node, checker: ts.TypeChecker, state: InspectorState, filters: InspectorFilters) => void;
2
+ import { InspectorFilters, InspectorState, InspectorLogger } from './types.js';
3
+ export declare const addMCPResource: (node: ts.Node, checker: ts.TypeChecker, state: InspectorState, filters: InspectorFilters, logger: InspectorLogger) => void;
@@ -1,16 +1,16 @@
1
1
  import * as ts from 'typescript';
2
2
  import { getPropertyValue } from './get-property-value.js';
3
- import { PikkuEventTypes } from '@pikku/core';
3
+ import { PikkuWiringTypes } from '@pikku/core';
4
4
  import { extractFunctionName, getPropertyAssignmentInitializer, matchesFilters, } from './utils.js';
5
- export const addMCPResource = (node, checker, state, filters) => {
5
+ export const addMCPResource = (node, checker, state, filters, logger) => {
6
6
  if (!ts.isCallExpression(node)) {
7
7
  return;
8
8
  }
9
9
  const args = node.arguments;
10
10
  const firstArg = args[0];
11
11
  const expression = node.expression;
12
- // Check if the call is to addMCPResource
13
- if (!ts.isIdentifier(expression) || expression.text !== 'addMCPResource') {
12
+ // Check if the call is to wireMCPResource
13
+ if (!ts.isIdentifier(expression) || expression.text !== 'wireMCPResource') {
14
14
  return;
15
15
  }
16
16
  if (!firstArg) {
@@ -41,7 +41,8 @@ export const addMCPResource = (node, checker, state, filters) => {
41
41
  console.error(`• MCP resource '${uriValue}' is missing a description.`);
42
42
  return;
43
43
  }
44
- if (!matchesFilters(filters, { tags }, { type: PikkuEventTypes.mcp, name: uriValue })) {
44
+ const filePath = node.getSourceFile().fileName;
45
+ if (!matchesFilters(filters, { tags }, { type: PikkuWiringTypes.mcp, name: uriValue, filePath }, logger)) {
45
46
  return;
46
47
  }
47
48
  // lookup existing function metadata
@@ -1,3 +1,3 @@
1
1
  import * as ts from 'typescript';
2
- import { InspectorFilters, InspectorState } from './types.js';
3
- export declare const addMCPTool: (node: ts.Node, checker: ts.TypeChecker, state: InspectorState, filters: InspectorFilters) => void;
2
+ import { InspectorFilters, InspectorState, InspectorLogger } from './types.js';
3
+ export declare const addMCPTool: (node: ts.Node, checker: ts.TypeChecker, state: InspectorState, filters: InspectorFilters, logger: InspectorLogger) => void;
@@ -1,16 +1,16 @@
1
1
  import * as ts from 'typescript';
2
2
  import { getPropertyValue } from './get-property-value.js';
3
- import { PikkuEventTypes } from '@pikku/core';
3
+ import { PikkuWiringTypes } from '@pikku/core';
4
4
  import { extractFunctionName, getPropertyAssignmentInitializer, matchesFilters, } from './utils.js';
5
- export const addMCPTool = (node, checker, state, filters) => {
5
+ export const addMCPTool = (node, checker, state, filters, logger) => {
6
6
  if (!ts.isCallExpression(node)) {
7
7
  return;
8
8
  }
9
9
  const args = node.arguments;
10
10
  const firstArg = args[0];
11
11
  const expression = node.expression;
12
- // Check if the call is to addMCPTool
13
- if (!ts.isIdentifier(expression) || expression.text !== 'addMCPTool') {
12
+ // Check if the call is to wireMCPTool
13
+ if (!ts.isIdentifier(expression) || expression.text !== 'wireMCPTool') {
14
14
  return;
15
15
  }
16
16
  if (!firstArg) {
@@ -37,7 +37,8 @@ export const addMCPTool = (node, checker, state, filters) => {
37
37
  console.error(`• MCP tool '${nameValue}' is missing a description.`);
38
38
  return;
39
39
  }
40
- if (!matchesFilters(filters, { tags }, { type: PikkuEventTypes.mcp, name: nameValue })) {
40
+ const filePath = node.getSourceFile().fileName;
41
+ if (!matchesFilters(filters, { tags }, { type: PikkuWiringTypes.mcp, name: nameValue, filePath }, logger)) {
41
42
  return;
42
43
  }
43
44
  // lookup existing function metadata
@@ -1,3 +1,3 @@
1
1
  import * as ts from 'typescript';
2
- import { InspectorFilters, InspectorState } from './types.js';
3
- export declare const addQueueWorker: (node: ts.Node, checker: ts.TypeChecker, state: InspectorState, filters: InspectorFilters) => void;
2
+ import { InspectorFilters, InspectorState, InspectorLogger } from './types.js';
3
+ export declare const addQueueWorker: (node: ts.Node, checker: ts.TypeChecker, state: InspectorState, filters: InspectorFilters, logger: InspectorLogger) => void;
@@ -1,8 +1,8 @@
1
1
  import * as ts from 'typescript';
2
2
  import { getPropertyValue } from './get-property-value.js';
3
- import { PikkuEventTypes } from '@pikku/core';
3
+ import { PikkuWiringTypes } from '@pikku/core';
4
4
  import { extractFunctionName, getPropertyAssignmentInitializer, matchesFilters, } from './utils.js';
5
- export const addQueueWorker = (node, checker, state, filters) => {
5
+ export const addQueueWorker = (node, checker, state, filters, logger) => {
6
6
  if (!ts.isCallExpression(node)) {
7
7
  return;
8
8
  }
@@ -10,7 +10,7 @@ export const addQueueWorker = (node, checker, state, filters) => {
10
10
  const firstArg = args[0];
11
11
  const expression = node.expression;
12
12
  // Check if the call is to addQueueWorker
13
- if (!ts.isIdentifier(expression) || expression.text !== 'addQueueWorker') {
13
+ if (!ts.isIdentifier(expression) || expression.text !== 'wireQueueWorker') {
14
14
  return;
15
15
  }
16
16
  if (!firstArg) {
@@ -32,7 +32,8 @@ export const addQueueWorker = (node, checker, state, filters) => {
32
32
  console.error(`• No 'queueName' provided for queue processor function '${pikkuFuncName}'.`);
33
33
  return;
34
34
  }
35
- if (!matchesFilters(filters, { tags }, { type: PikkuEventTypes.queue, name: queueName })) {
35
+ const filePath = node.getSourceFile().fileName;
36
+ if (!matchesFilters(filters, { tags }, { type: PikkuWiringTypes.queue, name: queueName, filePath }, logger)) {
36
37
  console.info(`• Skipping queue processor '${pikkuFuncName}' for queue '${queueName}' due to filter mismatch.`);
37
38
  return;
38
39
  }
@@ -1,3 +1,3 @@
1
1
  import * as ts from 'typescript';
2
- import { InspectorFilters, InspectorState } from './types.js';
3
- export declare const addSchedule: (node: ts.Node, checker: ts.TypeChecker, state: InspectorState, filters: InspectorFilters) => void;
2
+ import { InspectorFilters, InspectorState, InspectorLogger } from './types.js';
3
+ export declare const addSchedule: (node: ts.Node, checker: ts.TypeChecker, state: InspectorState, filters: InspectorFilters, logger: InspectorLogger) => void;
@@ -1,8 +1,8 @@
1
1
  import * as ts from 'typescript';
2
2
  import { getPropertyValue } from './get-property-value.js';
3
- import { PikkuEventTypes } from '@pikku/core';
3
+ import { PikkuWiringTypes } from '@pikku/core';
4
4
  import { extractFunctionName, getPropertyAssignmentInitializer, matchesFilters, } from './utils.js';
5
- export const addSchedule = (node, checker, state, filters) => {
5
+ export const addSchedule = (node, checker, state, filters, logger) => {
6
6
  if (!ts.isCallExpression(node)) {
7
7
  return;
8
8
  }
@@ -10,7 +10,7 @@ export const addSchedule = (node, checker, state, filters) => {
10
10
  const firstArg = args[0];
11
11
  const expression = node.expression;
12
12
  // Check if the call is to addScheduledTask
13
- if (!ts.isIdentifier(expression) || expression.text !== 'addScheduledTask') {
13
+ if (!ts.isIdentifier(expression) || expression.text !== 'wireScheduler') {
14
14
  return;
15
15
  }
16
16
  if (!firstArg) {
@@ -31,7 +31,8 @@ export const addSchedule = (node, checker, state, filters) => {
31
31
  if (!nameValue || !scheduleValue) {
32
32
  return;
33
33
  }
34
- if (!matchesFilters(filters, { tags }, { type: PikkuEventTypes.scheduled, name: nameValue })) {
34
+ const filePath = node.getSourceFile().fileName;
35
+ if (!matchesFilters(filters, { tags }, { type: PikkuWiringTypes.scheduler, name: nameValue, filePath }, logger)) {
35
36
  return;
36
37
  }
37
38
  state.scheduledTasks.files.add(node.getSourceFile().fileName);
@@ -1,3 +1,3 @@
1
- import { InspectorState, InspectorHTTPState, InspectorFilters } from './types.js';
1
+ import { InspectorState, InspectorHTTPState, InspectorFilters, InspectorLogger } from './types.js';
2
2
  export declare const normalizeHTTPTypes: (httpState: InspectorHTTPState) => InspectorHTTPState;
3
- export declare const inspect: (routeFiles: string[], filters: InspectorFilters) => InspectorState;
3
+ export declare const inspect: (logger: InspectorLogger, routeFiles: string[], filters: InspectorFilters) => InspectorState;
package/dist/inspector.js CHANGED
@@ -4,7 +4,7 @@ import { TypesMap } from './types-map.js';
4
4
  export const normalizeHTTPTypes = (httpState) => {
5
5
  return httpState;
6
6
  };
7
- export const inspect = (routeFiles, filters) => {
7
+ export const inspect = (logger, routeFiles, filters) => {
8
8
  const program = ts.createProgram(routeFiles, {
9
9
  target: ts.ScriptTarget.ESNext,
10
10
  module: ts.ModuleKind.CommonJS,
@@ -52,11 +52,11 @@ export const inspect = (routeFiles, filters) => {
52
52
  };
53
53
  // First sweep: add all functions
54
54
  for (const sourceFile of sourceFiles) {
55
- ts.forEachChild(sourceFile, (child) => visitSetup(checker, child, state, filters));
55
+ ts.forEachChild(sourceFile, (child) => visitSetup(checker, child, state, filters, logger));
56
56
  }
57
57
  // Second sweep: add all transports
58
58
  for (const sourceFile of sourceFiles) {
59
- ts.forEachChild(sourceFile, (child) => visitRoutes(checker, child, state, filters));
59
+ ts.forEachChild(sourceFile, (child) => visitRoutes(checker, child, state, filters, logger));
60
60
  }
61
61
  // Normalise the typesMap
62
62
  state.http = normalizeHTTPTypes(state.http);
package/dist/types.d.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';
@@ -18,7 +18,7 @@ export type MetaInputTypes = Map<string, {
18
18
  }>;
19
19
  export interface InspectorHTTPState {
20
20
  metaInputTypes: MetaInputTypes;
21
- meta: HTTPRoutesMeta;
21
+ meta: HTTPWiringsMeta;
22
22
  files: Set<string>;
23
23
  }
24
24
  export interface InspectorFunctionState {
@@ -35,7 +35,15 @@ export interface InspectorChannelState {
35
35
  }
36
36
  export type InspectorFilters = {
37
37
  tags?: string[];
38
+ types?: string[];
39
+ directories?: string[];
38
40
  };
41
+ export interface InspectorLogger {
42
+ info: (message: string) => void;
43
+ error: (message: string) => void;
44
+ warn: (message: string) => void;
45
+ debug: (message: string) => void;
46
+ }
39
47
  export interface InspectorState {
40
48
  singletonServicesTypeImportMap: PathToNameAndType;
41
49
  sessionServicesTypeImportMap: PathToNameAndType;
package/dist/utils.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import * as ts from 'typescript';
2
- import { InspectorFilters } from './types.js';
3
- import { PikkuEventTypes } from '@pikku/core';
2
+ import { InspectorFilters, InspectorLogger } from './types.js';
3
+ import { PikkuWiringTypes } from '@pikku/core';
4
4
  type ExtractedFunctionName = {
5
5
  pikkuFuncName: string;
6
6
  name: string;
@@ -28,7 +28,8 @@ export declare function getPropertyAssignmentInitializer(obj: ts.ObjectLiteralEx
28
28
  export declare const matchesFilters: (filters: InspectorFilters, params: {
29
29
  tags?: string[];
30
30
  }, meta: {
31
- type: PikkuEventTypes;
31
+ type: PikkuWiringTypes;
32
32
  name: string;
33
- }) => boolean;
33
+ filePath?: string;
34
+ }, logger: InspectorLogger) => boolean;
34
35
  export {};
package/dist/utils.js CHANGED
@@ -204,7 +204,7 @@ export function extractFunctionName(callExpr, checker) {
204
204
  propertyName: null,
205
205
  explicitName: null,
206
206
  };
207
- // Special case for addHTTPRoute: if this is an identifier within an object literal,
207
+ // Special case for wireHTTP: if this is an identifier within an object literal,
208
208
  // it might be coming from the HTTP route handling flow
209
209
  if (ts.isIdentifier(callExpr) &&
210
210
  callExpr.parent &&
@@ -660,13 +660,48 @@ export function getPropertyAssignmentInitializer(obj, propName, followShorthand
660
660
  }
661
661
  return undefined;
662
662
  }
663
- export const matchesFilters = (filters, params, meta) => {
664
- if (Object.keys(filters).length === 0 || filters.tags?.length === 0) {
663
+ export const matchesFilters = (filters, params, meta, logger) => {
664
+ // If no filters are provided, allow everything
665
+ if (Object.keys(filters).length === 0) {
665
666
  return true;
666
667
  }
667
- if (filters.tags?.some((tag) => params.tags?.includes(tag))) {
668
+ // If all filter arrays are empty, allow everything
669
+ if ((!filters.tags || filters.tags.length === 0) &&
670
+ (!filters.types || filters.types.length === 0) &&
671
+ (!filters.directories || filters.directories.length === 0)) {
668
672
  return true;
669
673
  }
670
- console.debug(`⒡ Filtered: ${meta.type}:${meta.name}`);
671
- return false;
674
+ // Check type filter
675
+ if (filters.types && filters.types.length > 0) {
676
+ if (!filters.types.includes(meta.type)) {
677
+ logger.debug(`⒡ Filtered by type: ${meta.type}:${meta.name}`);
678
+ return false;
679
+ }
680
+ }
681
+ // Check directory filter
682
+ if (filters.directories && filters.directories.length > 0) {
683
+ if (!meta.filePath) {
684
+ logger.debug(`⒡ Filtered by directory: ${meta.type}:${meta.name} (${meta.filePath})`);
685
+ return false;
686
+ }
687
+ const matchesDirectory = filters.directories.some((dir) => {
688
+ // Normalize paths for comparison
689
+ const normalizedFilePath = meta.filePath.replace(/\\/g, '/');
690
+ const normalizedDir = dir.replace(/\\/g, '/');
691
+ return normalizedFilePath.includes(normalizedDir);
692
+ });
693
+ if (!matchesDirectory) {
694
+ logger.debug(`⒡ Filtered by directory: ${meta.type}:${meta.name} (${meta.filePath})`);
695
+ return false;
696
+ }
697
+ }
698
+ // Check tag filter
699
+ if (filters.tags && filters.tags.length > 0) {
700
+ if (!params.tags ||
701
+ !filters.tags.some((tag) => params.tags.includes(tag))) {
702
+ logger.debug(`⒡ Filtered by tags: ${meta.type}:${meta.name}`);
703
+ return false;
704
+ }
705
+ }
706
+ return true;
672
707
  };
package/dist/visit.d.ts CHANGED
@@ -1,4 +1,4 @@
1
1
  import * as ts from 'typescript';
2
- import { InspectorFilters, InspectorState } from './types.js';
3
- export declare const visitSetup: (checker: ts.TypeChecker, node: ts.Node, state: InspectorState, filters: InspectorFilters) => void;
4
- export declare const visitRoutes: (checker: ts.TypeChecker, node: ts.Node, state: InspectorState, filters: InspectorFilters) => void;
2
+ import { InspectorFilters, InspectorState, InspectorLogger } from './types.js';
3
+ export declare const visitSetup: (checker: ts.TypeChecker, node: ts.Node, state: InspectorState, filters: InspectorFilters, logger: InspectorLogger) => void;
4
+ export declare const visitRoutes: (checker: ts.TypeChecker, node: ts.Node, state: InspectorState, filters: InspectorFilters, logger: InspectorLogger) => void;
package/dist/visit.js CHANGED
@@ -9,23 +9,23 @@ import { addMCPTool } from './add-mcp-tool.js';
9
9
  import { addMCPPrompt } from './add-mcp-prompt.js';
10
10
  import { addFunctions } from './add-functions.js';
11
11
  import { addChannel } from './add-channel.js';
12
- export const visitSetup = (checker, node, state, filters) => {
12
+ export const visitSetup = (checker, node, state, filters, logger) => {
13
13
  addFileExtendsCoreType(node, checker, state.singletonServicesTypeImportMap, 'CoreSingletonServices');
14
14
  addFileExtendsCoreType(node, checker, state.sessionServicesTypeImportMap, 'CoreServices');
15
15
  addFileExtendsCoreType(node, checker, state.userSessionTypeImportMap, 'CoreUserSession');
16
16
  addFileWithFactory(node, checker, state.singletonServicesFactories, 'CreateSingletonServices');
17
17
  addFileWithFactory(node, checker, state.sessionServicesFactories, 'CreateSessionServices');
18
18
  addFileWithFactory(node, checker, state.configFactories, 'CreateConfig');
19
- addFunctions(node, checker, state, filters);
20
- ts.forEachChild(node, (child) => visitSetup(checker, child, state, filters));
19
+ addFunctions(node, checker, state, filters, logger);
20
+ ts.forEachChild(node, (child) => visitSetup(checker, child, state, filters, logger));
21
21
  };
22
- export const visitRoutes = (checker, node, state, filters) => {
23
- addHTTPRoute(node, checker, state, filters);
24
- addSchedule(node, checker, state, filters);
25
- addQueueWorker(node, checker, state, filters);
26
- addChannel(node, checker, state, filters);
27
- addMCPResource(node, checker, state, filters);
28
- addMCPTool(node, checker, state, filters);
29
- addMCPPrompt(node, checker, state, filters);
30
- ts.forEachChild(node, (child) => visitRoutes(checker, child, state, filters));
22
+ export const visitRoutes = (checker, node, state, filters, logger) => {
23
+ addHTTPRoute(node, checker, state, filters, logger);
24
+ addSchedule(node, checker, state, filters, logger);
25
+ addQueueWorker(node, checker, state, filters, logger);
26
+ addChannel(node, checker, state, filters, logger);
27
+ addMCPResource(node, checker, state, filters, logger);
28
+ addMCPTool(node, checker, state, filters, logger);
29
+ addMCPPrompt(node, checker, state, filters, logger);
30
+ ts.forEachChild(node, (child) => visitRoutes(checker, child, state, filters, logger));
31
31
  };