@pikku/inspector 0.12.0 → 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.
Files changed (109) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/dist/add/add-ai-agent.d.ts +1 -1
  3. package/dist/add/add-ai-agent.js +1 -1
  4. package/dist/add/add-channel.js +12 -0
  5. package/dist/add/add-cli.d.ts +1 -1
  6. package/dist/add/add-cli.js +6 -1
  7. package/dist/add/add-file-extends-core-type.d.ts +1 -1
  8. package/dist/add/add-file-with-config.d.ts +1 -1
  9. package/dist/add/add-file-with-factory.d.ts +1 -1
  10. package/dist/add/add-file-with-factory.js +2 -2
  11. package/dist/add/add-functions.d.ts +1 -1
  12. package/dist/add/add-functions.js +6 -7
  13. package/dist/add/add-http-route.d.ts +3 -2
  14. package/dist/add/add-http-route.js +5 -1
  15. package/dist/add/add-http-routes.d.ts +1 -1
  16. package/dist/add/add-http-routes.js +1 -0
  17. package/dist/add/add-keyed-wiring.d.ts +1 -1
  18. package/dist/add/add-mcp-prompt.d.ts +1 -1
  19. package/dist/add/add-mcp-resource.d.ts +1 -1
  20. package/dist/add/add-queue-worker.d.ts +1 -1
  21. package/dist/add/add-rpc-invocations.d.ts +3 -3
  22. package/dist/add/add-rpc-invocations.js +10 -10
  23. package/dist/add/add-schedule.d.ts +1 -1
  24. package/dist/add/add-secret.d.ts +1 -1
  25. package/dist/add/add-trigger.d.ts +1 -1
  26. package/dist/add/add-trigger.js +2 -2
  27. package/dist/add/add-wire-addon.d.ts +7 -0
  28. package/dist/add/add-wire-addon.js +70 -0
  29. package/dist/add/add-workflow.d.ts +1 -1
  30. package/dist/error-codes.d.ts +1 -0
  31. package/dist/error-codes.js +1 -0
  32. package/dist/index.d.ts +1 -1
  33. package/dist/inspector.d.ts +1 -1
  34. package/dist/inspector.js +7 -4
  35. package/dist/types.d.ts +26 -20
  36. package/dist/utils/compute-required-schemas.js +1 -2
  37. package/dist/utils/contract-hashes.d.ts +20 -3
  38. package/dist/utils/contract-hashes.js +77 -10
  39. package/dist/utils/custom-types-generator.d.ts +1 -1
  40. package/dist/utils/detect-schema-vendor.d.ts +1 -1
  41. package/dist/utils/does-type-extend-core-type.d.ts +1 -1
  42. package/dist/utils/ensure-function-metadata.d.ts +1 -1
  43. package/dist/utils/extract-services.d.ts +1 -1
  44. package/dist/utils/filter-inspector-state.d.ts +1 -1
  45. package/dist/utils/filter-utils.d.ts +2 -2
  46. package/dist/utils/get-files-and-methods.d.ts +1 -1
  47. package/dist/utils/middleware.d.ts +2 -2
  48. package/dist/utils/permissions.d.ts +2 -2
  49. package/dist/utils/post-process.d.ts +4 -3
  50. package/dist/utils/post-process.js +24 -8
  51. package/dist/utils/resolve-addon-package.d.ts +16 -0
  52. package/dist/utils/{resolve-external-package.js → resolve-addon-package.js} +8 -8
  53. package/dist/utils/schema-generator.d.ts +2 -2
  54. package/dist/utils/serialize-inspector-state.d.ts +13 -3
  55. package/dist/utils/serialize-inspector-state.js +6 -2
  56. package/dist/utils/validate-auth-sessionless.d.ts +3 -0
  57. package/dist/utils/validate-auth-sessionless.js +14 -0
  58. package/dist/utils/workflow/dsl/extract-dsl-workflow.d.ts +1 -1
  59. package/dist/visit.d.ts +1 -1
  60. package/dist/visit.js +2 -0
  61. package/package.json +2 -2
  62. package/src/add/add-ai-agent.ts +2 -2
  63. package/src/add/add-channel.ts +21 -0
  64. package/src/add/add-cli.ts +19 -4
  65. package/src/add/add-file-extends-core-type.ts +1 -1
  66. package/src/add/add-file-with-config.ts +1 -1
  67. package/src/add/add-file-with-factory.ts +3 -3
  68. package/src/add/add-functions.ts +21 -19
  69. package/src/add/add-http-route.ts +19 -2
  70. package/src/add/add-http-routes.ts +2 -1
  71. package/src/add/add-keyed-wiring.ts +1 -1
  72. package/src/add/add-mcp-prompt.ts +1 -1
  73. package/src/add/add-mcp-resource.ts +1 -1
  74. package/src/add/add-queue-worker.ts +1 -1
  75. package/src/add/add-rpc-invocations.ts +11 -11
  76. package/src/add/add-schedule.ts +1 -1
  77. package/src/add/add-secret.ts +1 -1
  78. package/src/add/add-trigger.ts +4 -4
  79. package/src/add/add-wire-addon.ts +80 -0
  80. package/src/add/add-workflow.ts +2 -2
  81. package/src/error-codes.ts +1 -0
  82. package/src/index.ts +1 -0
  83. package/src/inspector.ts +13 -5
  84. package/src/types.ts +33 -20
  85. package/src/utils/compute-required-schemas.ts +1 -2
  86. package/src/utils/contract-hashes.test.ts +30 -5
  87. package/src/utils/contract-hashes.ts +110 -14
  88. package/src/utils/custom-types-generator.ts +1 -1
  89. package/src/utils/detect-schema-vendor.ts +1 -1
  90. package/src/utils/does-type-extend-core-type.ts +1 -1
  91. package/src/utils/ensure-function-metadata.ts +1 -1
  92. package/src/utils/extract-services.ts +1 -1
  93. package/src/utils/filter-inspector-state.test.ts +3 -5
  94. package/src/utils/filter-inspector-state.ts +7 -2
  95. package/src/utils/filter-utils.test.ts +1 -1
  96. package/src/utils/filter-utils.ts +2 -2
  97. package/src/utils/get-files-and-methods.ts +1 -1
  98. package/src/utils/middleware.ts +2 -2
  99. package/src/utils/permissions.ts +2 -2
  100. package/src/utils/post-process.ts +34 -12
  101. package/src/utils/{resolve-external-package.ts → resolve-addon-package.ts} +17 -10
  102. package/src/utils/resolve-versions.test.ts +1 -1
  103. package/src/utils/schema-generator.ts +4 -4
  104. package/src/utils/serialize-inspector-state.ts +23 -5
  105. package/src/utils/validate-auth-sessionless.ts +29 -0
  106. package/src/utils/workflow/dsl/extract-dsl-workflow.ts +2 -2
  107. package/src/visit.ts +7 -1
  108. package/tsconfig.tsbuildinfo +1 -1
  109. package/dist/utils/resolve-external-package.d.ts +0 -12
@@ -1,16 +1,18 @@
1
- import ts, { TypeChecker } from 'typescript'
2
- import {
1
+ import type { TypeChecker } from 'typescript'
2
+ import ts from 'typescript'
3
+ import type {
3
4
  AddWiring,
4
5
  InspectorLogger,
5
6
  InspectorOptions,
6
7
  InspectorState,
7
8
  } from '../types.js'
8
- import { CLIProgramMeta, CLICommandMeta } from '@pikku/core/cli'
9
+ import type { CLIProgramMeta, CLICommandMeta } from '@pikku/core/cli'
9
10
  import { extractFunctionName } from '../utils/extract-function-name.js'
10
11
  import { resolveMiddleware } from '../utils/middleware.js'
11
12
  import { extractWireNames } from '../utils/post-process.js'
12
13
  import { getPropertyValue } from '../utils/get-property-value.js'
13
14
  import { resolveIdentifier } from '../utils/resolve-identifier.js'
15
+ import { validateAuthSessionless } from '../utils/validate-auth-sessionless.js'
14
16
 
15
17
  // Track if we've warned about missing Config type to avoid duplicate warnings
16
18
  const configTypeWarningShown = new Set<string>()
@@ -453,12 +455,25 @@ function processCommand(
453
455
  }
454
456
  }
455
457
 
458
+ // --- validate auth/sessionless ---
459
+ if (
460
+ meta.pikkuFuncId &&
461
+ !validateAuthSessionless(
462
+ logger,
463
+ node,
464
+ inspectorState,
465
+ meta.pikkuFuncId,
466
+ `CLI command '${name}'`
467
+ )
468
+ ) {
469
+ return null
470
+ }
471
+
456
472
  // --- track used functions/middleware for service aggregation ---
457
473
  inspectorState.serviceAggregation.usedFunctions.add(meta.pikkuFuncId)
458
474
  extractWireNames(meta.middleware).forEach((name) =>
459
475
  inspectorState.serviceAggregation.usedMiddleware.add(name)
460
476
  )
461
- // Note: subcommands are tracked recursively when they're processed
462
477
 
463
478
  return meta
464
479
  }
@@ -1,5 +1,5 @@
1
1
  import * as ts from 'typescript'
2
- import { PathToNameAndType, InspectorState } from '../types.js'
2
+ import type { PathToNameAndType, InspectorState } from '../types.js'
3
3
 
4
4
  export const addFileExtendsCoreType = (
5
5
  node: ts.Node,
@@ -1,6 +1,6 @@
1
1
  import * as ts from 'typescript'
2
2
  import { doesTypeExtendsCore } from '../utils/does-type-extend-core-type.js'
3
- import { PathToNameAndType } from '../types.js'
3
+ import type { PathToNameAndType } from '../types.js'
4
4
 
5
5
  export const addFileWithConfig = (
6
6
  node: ts.Node,
@@ -1,13 +1,13 @@
1
1
  import * as ts from 'typescript'
2
- import { PathToNameAndType, InspectorState } from '../types.js'
2
+ import type { PathToNameAndType, InspectorState } from '../types.js'
3
3
  import { extractServicesFromFunction } from '../utils/extract-services.js'
4
4
 
5
5
  // Mapping of wrapper function names to their corresponding types
6
6
  const wrapperFunctionMap: Record<string, string> = {
7
7
  pikkuConfig: 'CreateConfig',
8
- pikkuExternalConfig: 'CreateConfig',
8
+ pikkuAddonConfig: 'CreateConfig',
9
9
  pikkuServices: 'CreateSingletonServices',
10
- pikkuExternalServices: 'CreateSingletonServices',
10
+ pikkuAddonServices: 'CreateSingletonServices',
11
11
  pikkuWireServices: 'CreateWireServices',
12
12
  }
13
13
 
@@ -1,14 +1,15 @@
1
1
  import * as ts from 'typescript'
2
- import { AddWiring, SchemaRef } from '../types.js'
2
+ import type { AddWiring, SchemaRef } from '../types.js'
3
3
  import { detectSchemaVendorOrError } from '../utils/detect-schema-vendor.js'
4
- import { TypesMap } from '../types-map.js'
4
+ import type { TypesMap } from '../types-map.js'
5
5
  import {
6
6
  extractFunctionName,
7
7
  funcIdToTypeName,
8
8
  } from '../utils/extract-function-name.js'
9
9
  import { extractFunctionNode } from '../utils/extract-function-node.js'
10
10
  import { extractUsedWires } from '../utils/extract-services.js'
11
- import { FunctionServicesMeta, formatVersionedId } from '@pikku/core'
11
+ import type { FunctionServicesMeta } from '@pikku/core'
12
+ import { formatVersionedId } from '@pikku/core'
12
13
  import {
13
14
  getPropertyValue,
14
15
  getCommonWireMetaData,
@@ -216,9 +217,9 @@ const getNamesAndTypes = (
216
217
  const aliasName = funcIdToTypeName(funcName) + direction
217
218
 
218
219
  // record the alias in your TypesMap
219
- const references = rawTypes
220
- .map((t) => resolveTypeImports(t, typesMap, true, checker))
221
- .flat()
220
+ const references = rawTypes.flatMap((t) =>
221
+ resolveTypeImports(t, typesMap, true, checker)
222
+ )
222
223
 
223
224
  typesMap.addCustomType(aliasName, aliasType, references)
224
225
 
@@ -229,19 +230,17 @@ const getNamesAndTypes = (
229
230
  }
230
231
 
231
232
  // 4) Single, valid name → inline it
232
- const uniqueNames = rawNames
233
- .map((name, i) => {
234
- const t = rawTypes[i]
235
- if (!t) {
236
- throw new Error(`Expected type for name "${name}" in ${funcName}`)
237
- }
238
- if (isPrimitiveType(t)) {
239
- return name
240
- }
241
- // non-primitive: import/alias it inline
242
- return resolveTypeImports(t, typesMap, false, checker)
243
- })
244
- .flat()
233
+ const uniqueNames = rawNames.flatMap((name, i) => {
234
+ const t = rawTypes[i]
235
+ if (!t) {
236
+ throw new Error(`Expected type for name "${name}" in ${funcName}`)
237
+ }
238
+ if (isPrimitiveType(t)) {
239
+ return name
240
+ }
241
+ // non-primitive: import/alias it inline
242
+ return resolveTypeImports(t, typesMap, false, checker)
243
+ })
245
244
 
246
245
  return {
247
246
  names: uniqueNames,
@@ -339,6 +338,7 @@ export const addFunctions: AddWiring = (
339
338
  let expose: boolean | undefined
340
339
  let remote: boolean | undefined
341
340
  let mcp: boolean | undefined
341
+ let readonly_: boolean | undefined
342
342
  let requiresApproval: boolean | undefined
343
343
  let version: number | undefined
344
344
  let objectNode: ts.ObjectLiteralExpression | undefined
@@ -420,6 +420,7 @@ export const addFunctions: AddWiring = (
420
420
  expose = getPropertyValue(firstArg, 'expose') as boolean | undefined
421
421
  remote = getPropertyValue(firstArg, 'remote') as boolean | undefined
422
422
  mcp = getPropertyValue(firstArg, 'mcp') as boolean | undefined
423
+ readonly_ = getPropertyValue(firstArg, 'readonly') as boolean | undefined
423
424
  requiresApproval = getPropertyValue(firstArg, 'requiresApproval') as
424
425
  | boolean
425
426
  | undefined
@@ -757,6 +758,7 @@ export const addFunctions: AddWiring = (
757
758
  expose: expose || undefined,
758
759
  remote: remote || undefined,
759
760
  mcp: mcpEnabled || undefined,
761
+ readonly: readonly_ || undefined,
760
762
  requiresApproval: requiresApproval || undefined,
761
763
  version,
762
764
  title,
@@ -4,7 +4,7 @@ import {
4
4
  getCommonWireMetaData,
5
5
  } from '../utils/get-property-value.js'
6
6
  import { pathToRegexp } from 'path-to-regexp'
7
- import { HTTPMethod } from '@pikku/core/http'
7
+ import type { HTTPMethod } from '@pikku/core/http'
8
8
  import {
9
9
  extractFunctionName,
10
10
  makeContextBasedId,
@@ -13,12 +13,13 @@ import {
13
13
  getPropertyAssignmentInitializer,
14
14
  extractTypeKeys,
15
15
  } from '../utils/type-utils.js'
16
- import { AddWiring, InspectorState } from '../types.js'
16
+ import type { AddWiring, InspectorState } from '../types.js'
17
17
  import { resolveHTTPMiddlewareFromObject } from '../utils/middleware.js'
18
18
  import { resolveHTTPPermissionsFromObject } from '../utils/permissions.js'
19
19
  import { extractWireNames } from '../utils/post-process.js'
20
20
  import { ensureFunctionMetadata } from '../utils/ensure-function-metadata.js'
21
21
  import { ErrorCode } from '../error-codes.js'
22
+ import { validateAuthSessionless } from '../utils/validate-auth-sessionless.js'
22
23
  import { detectSchemaVendorOrError } from '../utils/detect-schema-vendor.js'
23
24
 
24
25
  import type { InspectorLogger } from '../types.js'
@@ -34,6 +35,7 @@ export interface RegisterHTTPRouteParams {
34
35
  sourceFile: ts.SourceFile
35
36
  basePath?: string
36
37
  inheritedTags?: string[]
38
+ inheritedAuth?: boolean
37
39
  }
38
40
 
39
41
  /**
@@ -140,6 +142,7 @@ export function registerHTTPRoute({
140
142
  sourceFile,
141
143
  basePath = '',
142
144
  inheritedTags = [],
145
+ inheritedAuth,
143
146
  }: RegisterHTTPRouteParams): void {
144
147
  // Extract route path
145
148
  const routePath = getPropertyValue(obj, 'route') as string | null
@@ -218,6 +221,20 @@ export function registerHTTPRoute({
218
221
  )
219
222
  return
220
223
  }
224
+
225
+ if (
226
+ !validateAuthSessionless(
227
+ logger,
228
+ obj,
229
+ state,
230
+ funcName,
231
+ `Route '${fullRoute}'`,
232
+ inheritedAuth
233
+ )
234
+ ) {
235
+ return
236
+ }
237
+
221
238
  const input = fnMeta.inputs?.[0] || null
222
239
 
223
240
  // Validate that route params and query params exist in function input type
@@ -1,6 +1,6 @@
1
1
  import * as ts from 'typescript'
2
2
  import { getPropertyValue } from '../utils/get-property-value.js'
3
- import { AddWiring, InspectorState, InspectorLogger } from '../types.js'
3
+ import type { AddWiring, InspectorState, InspectorLogger } from '../types.js'
4
4
  import { registerHTTPRoute } from './add-http-route.js'
5
5
  import { resolveIdentifier } from '../utils/resolve-identifier.js'
6
6
 
@@ -224,5 +224,6 @@ function processRoute(
224
224
  sourceFile,
225
225
  basePath: groupConfig.basePath,
226
226
  inheritedTags: groupConfig.tags,
227
+ inheritedAuth: groupConfig.auth,
227
228
  })
228
229
  }
@@ -1,6 +1,6 @@
1
1
  import * as ts from 'typescript'
2
2
  import { getPropertyValue } from '../utils/get-property-value.js'
3
- import { AddWiring, InspectorState } from '../types.js'
3
+ import type { AddWiring, InspectorState } from '../types.js'
4
4
  import { ErrorCode } from '../error-codes.js'
5
5
  import { detectSchemaVendorOrError } from '../utils/detect-schema-vendor.js'
6
6
 
@@ -5,7 +5,7 @@ import {
5
5
  } from '../utils/get-property-value.js'
6
6
  import { extractWireNames } from '../utils/post-process.js'
7
7
  import { ensureFunctionMetadata } from '../utils/ensure-function-metadata.js'
8
- import { AddWiring } from '../types.js'
8
+ import type { AddWiring } from '../types.js'
9
9
  import {
10
10
  extractFunctionName,
11
11
  makeContextBasedId,
@@ -5,7 +5,7 @@ import {
5
5
  } from '../utils/get-property-value.js'
6
6
  import { extractWireNames } from '../utils/post-process.js'
7
7
  import { ensureFunctionMetadata } from '../utils/ensure-function-metadata.js'
8
- import { AddWiring } from '../types.js'
8
+ import type { AddWiring } from '../types.js'
9
9
  import {
10
10
  extractFunctionName,
11
11
  makeContextBasedId,
@@ -3,7 +3,7 @@ import {
3
3
  getPropertyValue,
4
4
  getCommonWireMetaData,
5
5
  } from '../utils/get-property-value.js'
6
- import { AddWiring } from '../types.js'
6
+ import type { AddWiring } from '../types.js'
7
7
  import {
8
8
  extractFunctionName,
9
9
  makeContextBasedId,
@@ -1,5 +1,5 @@
1
1
  import * as ts from 'typescript'
2
- import { InspectorState, InspectorLogger } from '../types.js'
2
+ import type { InspectorState, InspectorLogger } from '../types.js'
3
3
 
4
4
  /**
5
5
  * Helper to extract namespace from a namespaced function reference like 'ext:hello'
@@ -14,31 +14,31 @@ function extractNamespace(functionRef: string): string | null {
14
14
 
15
15
  /**
16
16
  * Scan for rpc.invoke() calls to track which functions are actually being invoked
17
- * Also detects external package usage via:
17
+ * Also detects addon usage via:
18
18
  * - Namespaced calls: rpc.invoke('namespace:function')
19
- * - External helper: external('namespace:function')
19
+ * - Addon helper: addon('namespace:function')
20
20
  */
21
21
  export function addRPCInvocations(
22
22
  node: ts.Node,
23
23
  state: InspectorState,
24
24
  logger: InspectorLogger
25
25
  ) {
26
- // Look for call expressions: external('ext:hello') or rpc.invoke('...')
26
+ // Look for call expressions: addon('ext:hello') or rpc.invoke('...')
27
27
  if (ts.isCallExpression(node)) {
28
28
  const { expression, arguments: args } = node
29
29
 
30
- // Check for external('namespace:function') calls
31
- if (ts.isIdentifier(expression) && expression.text === 'external') {
30
+ // Check for addon('namespace:function') calls
31
+ if (ts.isIdentifier(expression) && expression.text === 'addon') {
32
32
  const [firstArg] = args
33
33
  if (firstArg && ts.isStringLiteral(firstArg)) {
34
34
  const functionRef = firstArg.text
35
- logger.debug(`• Found external() call: ${functionRef}`)
35
+ logger.debug(`• Found addon() call: ${functionRef}`)
36
36
  state.rpc.invokedFunctions.add(functionRef)
37
37
 
38
38
  const namespace = extractNamespace(functionRef)
39
39
  if (namespace) {
40
- logger.debug(` → External package detected: ${namespace}`)
41
- state.rpc.usedExternalPackages.add(namespace)
40
+ logger.debug(` → Addon detected: ${namespace}`)
41
+ state.rpc.usedAddons.add(namespace)
42
42
  }
43
43
  }
44
44
  }
@@ -76,8 +76,8 @@ export function addRPCInvocations(
76
76
 
77
77
  const namespace = extractNamespace(functionRef)
78
78
  if (namespace) {
79
- logger.debug(` → External package detected: ${namespace}`)
80
- state.rpc.usedExternalPackages.add(namespace)
79
+ logger.debug(` → Addon detected: ${namespace}`)
80
+ state.rpc.usedAddons.add(namespace)
81
81
  }
82
82
  }
83
83
  // Handle template literals like `function-${name}`
@@ -3,7 +3,7 @@ import {
3
3
  getPropertyValue,
4
4
  getCommonWireMetaData,
5
5
  } from '../utils/get-property-value.js'
6
- import { AddWiring } from '../types.js'
6
+ import type { AddWiring } from '../types.js'
7
7
  import {
8
8
  extractFunctionName,
9
9
  makeContextBasedId,
@@ -3,7 +3,7 @@ import {
3
3
  getPropertyValue,
4
4
  getArrayPropertyValue,
5
5
  } from '../utils/get-property-value.js'
6
- import { AddWiring } from '../types.js'
6
+ import type { AddWiring } from '../types.js'
7
7
  import { ErrorCode } from '../error-codes.js'
8
8
  import { createAddKeyedWiring } from './add-keyed-wiring.js'
9
9
 
@@ -3,7 +3,7 @@ import {
3
3
  getPropertyValue,
4
4
  getCommonWireMetaData,
5
5
  } from '../utils/get-property-value.js'
6
- import { AddWiring } from '../types.js'
6
+ import type { AddWiring } from '../types.js'
7
7
  import {
8
8
  extractFunctionName,
9
9
  makeContextBasedId,
@@ -11,7 +11,7 @@ import {
11
11
  import { getPropertyAssignmentInitializer } from '../utils/type-utils.js'
12
12
  import { resolveMiddleware } from '../utils/middleware.js'
13
13
  import { extractWireNames } from '../utils/post-process.js'
14
- import { resolveExternalPackageName } from '../utils/resolve-external-package.js'
14
+ import { resolveAddonName } from '../utils/resolve-addon-package.js'
15
15
 
16
16
  import { ErrorCode } from '../error-codes.js'
17
17
  export const addTrigger: AddWiring = (
@@ -138,10 +138,10 @@ const addWireTriggerSource: (
138
138
  }
139
139
 
140
140
  if (ts.isIdentifier(funcInitializer)) {
141
- const packageName = resolveExternalPackageName(
141
+ const packageName = resolveAddonName(
142
142
  funcInitializer,
143
143
  checker,
144
- options.externalPackages
144
+ state.rpc.wireAddonDeclarations
145
145
  )
146
146
  state.triggers.sourceMeta[nameValue] = {
147
147
  name: nameValue,
@@ -0,0 +1,80 @@
1
+ import * as ts from 'typescript'
2
+ import type { InspectorState, InspectorLogger } from '../types.js'
3
+
4
+ function parseStringRecord(
5
+ obj: ts.ObjectLiteralExpression
6
+ ): Record<string, string> {
7
+ const result: Record<string, string> = {}
8
+ for (const prop of obj.properties) {
9
+ if (!ts.isPropertyAssignment(prop)) continue
10
+ const keyNode = prop.name
11
+ const key = ts.isIdentifier(keyNode)
12
+ ? keyNode.text
13
+ : ts.isStringLiteral(keyNode)
14
+ ? keyNode.text
15
+ : undefined
16
+ if (key && ts.isStringLiteral(prop.initializer)) {
17
+ result[key] = prop.initializer.text
18
+ }
19
+ }
20
+ return result
21
+ }
22
+
23
+ /**
24
+ * Detect wireAddon({ name: '...', package: '...' }) call expressions and
25
+ * populate state.rpc.wireAddonDeclarations and state.rpc.usedAddons.
26
+ */
27
+ export function addWireAddon(
28
+ node: ts.Node,
29
+ state: InspectorState,
30
+ logger: InspectorLogger
31
+ ) {
32
+ if (!ts.isCallExpression(node)) return
33
+
34
+ const { expression, arguments: args } = node
35
+ if (!ts.isIdentifier(expression) || expression.text !== 'wireAddon') return
36
+
37
+ const [firstArg] = args
38
+ if (!firstArg || !ts.isObjectLiteralExpression(firstArg)) return
39
+
40
+ let name: string | undefined
41
+ let pkg: string | undefined
42
+ let rpcEndpoint: string | undefined
43
+ let secretOverrides: Record<string, string> | undefined
44
+ let variableOverrides: Record<string, string> | undefined
45
+
46
+ for (const prop of firstArg.properties) {
47
+ if (!ts.isPropertyAssignment(prop) || !ts.isIdentifier(prop.name)) continue
48
+
49
+ const key = prop.name.text
50
+ if (key === 'name' && ts.isStringLiteral(prop.initializer)) {
51
+ name = prop.initializer.text
52
+ } else if (key === 'package' && ts.isStringLiteral(prop.initializer)) {
53
+ pkg = prop.initializer.text
54
+ } else if (key === 'rpcEndpoint' && ts.isStringLiteral(prop.initializer)) {
55
+ rpcEndpoint = prop.initializer.text
56
+ } else if (
57
+ key === 'secretOverrides' &&
58
+ ts.isObjectLiteralExpression(prop.initializer)
59
+ ) {
60
+ secretOverrides = parseStringRecord(prop.initializer)
61
+ } else if (
62
+ key === 'variableOverrides' &&
63
+ ts.isObjectLiteralExpression(prop.initializer)
64
+ ) {
65
+ variableOverrides = parseStringRecord(prop.initializer)
66
+ }
67
+ }
68
+
69
+ if (!name || !pkg) return
70
+
71
+ logger.debug(`• Found wireAddon: ${name} → ${pkg}`)
72
+ state.rpc.wireAddonDeclarations.set(name, {
73
+ package: pkg,
74
+ rpcEndpoint,
75
+ secretOverrides,
76
+ variableOverrides,
77
+ })
78
+ state.rpc.usedAddons.add(name)
79
+ state.rpc.wireAddonFiles.add(node.getSourceFile().fileName)
80
+ }
@@ -1,9 +1,9 @@
1
1
  import * as ts from 'typescript'
2
- import { AddWiring, InspectorState } from '../types.js'
2
+ import type { AddWiring, InspectorState } from '../types.js'
3
3
  import { extractFunctionName } from '../utils/extract-function-name.js'
4
4
  import { extractFunctionNode } from '../utils/extract-function-node.js'
5
5
  import { ErrorCode } from '../error-codes.js'
6
- import { WorkflowStepMeta, WorkflowContext } from '@pikku/core/workflow'
6
+ import type { WorkflowStepMeta, WorkflowContext } from '@pikku/core/workflow'
7
7
  import {
8
8
  extractStringLiteral,
9
9
  isStringLike,
@@ -39,6 +39,7 @@ export enum ErrorCode {
39
39
  // HTTP Route errors
40
40
  ROUTE_PARAM_MISMATCH = 'PKU571',
41
41
  ROUTE_QUERY_MISMATCH = 'PKU572',
42
+ AUTH_DISABLED_REQUIRES_SESSIONLESS = 'PKU573',
42
43
 
43
44
  // Middleware/Permission errors
44
45
  MIDDLEWARE_HANDLER_INVALID = 'PKU685',
package/src/index.ts CHANGED
@@ -19,6 +19,7 @@ export {
19
19
  } from './utils/contract-hashes.js'
20
20
  export type {
21
21
  ContractEntry,
22
+ VersionHashEntry,
22
23
  VersionValidateError,
23
24
  VersionManifest,
24
25
  VersionManifestEntry,
package/src/inspector.ts CHANGED
@@ -2,14 +2,19 @@ import * as ts from 'typescript'
2
2
  import { performance } from 'perf_hooks'
3
3
  import { visitSetup, visitRoutes } from './visit.js'
4
4
  import { TypesMap } from './types-map.js'
5
- import { InspectorState, InspectorLogger, InspectorOptions } from './types.js'
5
+ import type {
6
+ InspectorState,
7
+ InspectorLogger,
8
+ InspectorOptions,
9
+ } from './types.js'
6
10
  import { getFilesAndMethods } from './utils/get-files-and-methods.js'
7
11
  import { findCommonAncestor } from './utils/find-root-dir.js'
8
12
  import {
9
13
  aggregateRequiredServices,
10
- validateSecretOverrides,
11
14
  validateAgentModels,
12
15
  validateAgentOverrides,
16
+ validateSecretOverrides,
17
+ validateVariableOverrides,
13
18
  computeResolvedIOTypes,
14
19
  computeMiddlewareGroupsMeta,
15
20
  computePermissionsGroupsMeta,
@@ -17,7 +22,7 @@ import {
17
22
  computeDiagnostics,
18
23
  } from './utils/post-process.js'
19
24
  import { generateOpenAPISpec } from './utils/serialize-openapi-json.js'
20
- import { pikkuState } from '@pikku/core'
25
+ import { pikkuState } from '@pikku/core/internal'
21
26
  import { resolveLatestVersions } from './utils/resolve-versions.js'
22
27
  import { finalizeWorkflows } from './utils/workflow/graph/finalize-workflows.js'
23
28
  import {
@@ -104,7 +109,9 @@ export function getInitialInspectorState(rootDir: string): InspectorState {
104
109
  exposedMeta: {},
105
110
  exposedFiles: new Map(),
106
111
  invokedFunctions: new Set(),
107
- usedExternalPackages: new Set(),
112
+ usedAddons: new Set(),
113
+ wireAddonDeclarations: new Map(),
114
+ wireAddonFiles: new Set(),
108
115
  },
109
116
  mcpEndpoints: {
110
117
  resourcesMeta: {},
@@ -312,9 +319,10 @@ export const inspect = async (
312
319
  )
313
320
  }
314
321
 
315
- validateSecretOverrides(logger, state, options.externalPackages)
316
322
  validateAgentModels(logger, state, options.modelConfig)
317
323
  validateAgentOverrides(logger, state, options.modelConfig)
324
+ validateSecretOverrides(logger, state)
325
+ validateVariableOverrides(logger, state)
318
326
  }
319
327
 
320
328
  return state
package/src/types.ts CHANGED
@@ -1,25 +1,29 @@
1
- import * as ts from 'typescript'
2
- import { ChannelsMeta } from '@pikku/core/channel'
3
- import { HTTPWiringsMeta } from '@pikku/core/http'
4
- import { ScheduledTasksMeta } from '@pikku/core/scheduler'
5
- import { TriggerMeta, TriggerSourceMeta } from '@pikku/core/trigger'
6
- import { QueueWorkersMeta } from '@pikku/core/queue'
7
- import { WorkflowsMeta } from '@pikku/core/workflow'
8
- import { MCPResourceMeta, MCPToolMeta, MCPPromptMeta } from '@pikku/core/mcp'
9
- import { AIAgentMeta } from '@pikku/core/ai-agent'
10
- import { CLIMeta } from '@pikku/core/cli'
11
- import { NodesMeta } from '@pikku/core/node'
12
- import { SecretDefinitions } from '@pikku/core/secret'
13
- import { VariableDefinitions } from '@pikku/core/variable'
14
- import { TypesMap } from './types-map.js'
15
- import {
1
+ import type * as ts from 'typescript'
2
+ import type { ChannelsMeta } from '@pikku/core/channel'
3
+ import type { HTTPWiringsMeta } from '@pikku/core/http'
4
+ import type { ScheduledTasksMeta } from '@pikku/core/scheduler'
5
+ import type { TriggerMeta, TriggerSourceMeta } from '@pikku/core/trigger'
6
+ import type { QueueWorkersMeta } from '@pikku/core/queue'
7
+ import type { WorkflowsMeta } from '@pikku/core/workflow'
8
+ import type {
9
+ MCPResourceMeta,
10
+ MCPToolMeta,
11
+ MCPPromptMeta,
12
+ } from '@pikku/core/mcp'
13
+ import type { AIAgentMeta } from '@pikku/core/ai-agent'
14
+ import type { CLIMeta } from '@pikku/core/cli'
15
+ import type { NodesMeta } from '@pikku/core/node'
16
+ import type { SecretDefinitions } from '@pikku/core/secret'
17
+ import type { VariableDefinitions } from '@pikku/core/variable'
18
+ import type { TypesMap } from './types-map.js'
19
+ import type {
16
20
  FunctionsMeta,
17
21
  FunctionServicesMeta,
18
22
  FunctionWiresMeta,
19
23
  JSONValue,
20
24
  } from '@pikku/core'
21
25
  import type { OpenAPISpecInfo } from './utils/serialize-openapi-json.js'
22
- import { ErrorCode } from './error-codes.js'
26
+ import type { ErrorCode } from './error-codes.js'
23
27
  import type {
24
28
  VersionManifest,
25
29
  VersionValidateError,
@@ -170,7 +174,7 @@ export type InspectorFilters = {
170
174
  httpMethods?: string[] // HTTP methods: "GET", "POST", "DELETE", etc.
171
175
  }
172
176
 
173
- export type ExternalPackageConfig = {
177
+ export type AddonConfig = {
174
178
  package: string
175
179
  rpcEndpoint?: string
176
180
  secretOverrides?: Record<string, string>
@@ -193,14 +197,13 @@ export type InspectorModelConfig = {
193
197
  export type InspectorOptions = Partial<{
194
198
  setupOnly: boolean
195
199
  rootDir: string
196
- isExternalPackage: boolean
200
+ isAddon: boolean
197
201
  types: Partial<{
198
202
  configFileType: string
199
203
  userSessionType: string
200
204
  singletonServicesFactoryType: string
201
205
  wireServicesFactoryType: string
202
206
  }>
203
- externalPackages: Record<string, ExternalPackageConfig>
204
207
  schemaConfig: {
205
208
  tsconfig: string
206
209
  schemasFromTypes?: string[]
@@ -326,7 +329,17 @@ export interface InspectorState {
326
329
  exposedMeta: Record<string, string>
327
330
  exposedFiles: Map<string, { path: string; exportedName: string }>
328
331
  invokedFunctions: Set<string>
329
- usedExternalPackages: Set<string>
332
+ usedAddons: Set<string>
333
+ wireAddonDeclarations: Map<
334
+ string,
335
+ {
336
+ package: string
337
+ rpcEndpoint?: string
338
+ secretOverrides?: Record<string, string>
339
+ variableOverrides?: Record<string, string>
340
+ }
341
+ >
342
+ wireAddonFiles: Set<string>
330
343
  }
331
344
  mcpEndpoints: {
332
345
  resourcesMeta: MCPResourceMeta
@@ -22,7 +22,7 @@ export function computeRequiredSchemas(
22
22
  ): Set<string> {
23
23
  return new Set<string>([
24
24
  ...Object.values(functionsMeta)
25
- .map(({ inputs, outputs }) => {
25
+ .flatMap(({ inputs, outputs }) => {
26
26
  const types: (string | undefined)[] = []
27
27
  if (inputs?.[0]) {
28
28
  try {
@@ -40,7 +40,6 @@ export function computeRequiredSchemas(
40
40
  }
41
41
  return types
42
42
  })
43
- .flat()
44
43
  .filter((s): s is string => !!s && !PRIMITIVE_TYPES.has(s)),
45
44
  ...typesMap.customTypes.keys(),
46
45
  ...(additionalTypes || []),