@pikku/inspector 0.12.75 → 0.12.81
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 +330 -0
- package/dist/add/add-analytics.d.ts +9 -0
- package/dist/add/add-analytics.js +178 -0
- package/dist/add/add-auth.js +0 -54
- package/dist/add/add-feature-flag.d.ts +2 -0
- package/dist/add/add-feature-flag.js +162 -0
- package/dist/add/add-wire-addon.js +1 -0
- package/dist/add/add-wire-remote-addon.js +1 -0
- package/dist/index.d.ts +3 -1
- package/dist/index.js +3 -1
- package/dist/inspector.js +4 -0
- package/dist/surface/collect-surface.d.ts +58 -0
- package/dist/surface/collect-surface.js +613 -0
- package/dist/types.d.ts +20 -11
- package/dist/utils/filter-inspector-state.js +14 -0
- package/dist/utils/post-process.js +15 -0
- package/dist/utils/read-module-specifiers.d.ts +8 -0
- package/dist/utils/read-module-specifiers.js +23 -0
- package/dist/utils/read-tsconfig-out-dir.d.ts +5 -0
- package/dist/utils/read-tsconfig-out-dir.js +12 -0
- package/dist/utils/resolve-deploy-target.d.ts +7 -0
- package/dist/utils/resolve-deploy-target.js +15 -7
- package/dist/utils/serialize-inspector-state.d.ts +5 -0
- package/dist/utils/serialize-inspector-state.js +8 -0
- package/dist/visit.js +4 -0
- package/package.json +16 -6
- package/run-tests.sh +21 -6
- package/src/add/add-addon-bans.ts +0 -85
- package/src/add/add-agent-scorer.test.ts +0 -197
- package/src/add/add-agent-scorer.ts +0 -83
- package/src/add/add-agent.test.ts +0 -87
- package/src/add/add-agent.ts +0 -638
- package/src/add/add-approval-description.ts +0 -76
- package/src/add/add-auth.test.ts +0 -791
- package/src/add/add-auth.ts +0 -424
- package/src/add/add-channel.ts +0 -778
- package/src/add/add-cli-renderers.test.ts +0 -74
- package/src/add/add-cli.ts +0 -1006
- package/src/add/add-credential.ts +0 -186
- package/src/add/add-feature.test.ts +0 -306
- package/src/add/add-feature.ts +0 -253
- package/src/add/add-file-extends-core-type.ts +0 -66
- package/src/add/add-file-with-config.ts +0 -45
- package/src/add/add-file-with-factory.test.ts +0 -134
- package/src/add/add-file-with-factory.ts +0 -288
- package/src/add/add-functions.test.ts +0 -743
- package/src/add/add-functions.ts +0 -1548
- package/src/add/add-gateway.ts +0 -143
- package/src/add/add-http-route-ref.test.ts +0 -149
- package/src/add/add-http-route.ts +0 -530
- package/src/add/add-http-routes.ts +0 -471
- package/src/add/add-keyed-wiring.ts +0 -180
- package/src/add/add-mcp-prompt.ts +0 -157
- package/src/add/add-mcp-resource.ts +0 -175
- package/src/add/add-middleware.test.ts +0 -196
- package/src/add/add-middleware.ts +0 -879
- package/src/add/add-permission-auth.test.ts +0 -59
- package/src/add/add-permission.ts +0 -311
- package/src/add/add-personas.test.ts +0 -406
- package/src/add/add-personas.ts +0 -287
- package/src/add/add-queue-worker.ts +0 -117
- package/src/add/add-rpc-invocations.test.ts +0 -287
- package/src/add/add-rpc-invocations.ts +0 -221
- package/src/add/add-scenario-step.test.ts +0 -509
- package/src/add/add-schedule.ts +0 -120
- package/src/add/add-scope.test.ts +0 -419
- package/src/add/add-scope.ts +0 -221
- package/src/add/add-secret.ts +0 -10
- package/src/add/add-subject-scenario-steps.test.ts +0 -161
- package/src/add/add-system-role.test.ts +0 -297
- package/src/add/add-system-role.ts +0 -162
- package/src/add/add-trigger.ts +0 -165
- package/src/add/add-variable.ts +0 -10
- package/src/add/add-wire-addon.test.ts +0 -185
- package/src/add/add-wire-addon.ts +0 -146
- package/src/add/add-wire-remote-addon.ts +0 -80
- package/src/add/add-workflow-edge-cases.test.ts +0 -201
- package/src/add/add-workflow-fanout.test.ts +0 -166
- package/src/add/add-workflow-graph-foreach.test.ts +0 -174
- package/src/add/add-workflow-graph-input.test.ts +0 -94
- package/src/add/add-workflow-graph-notes.test.ts +0 -74
- package/src/add/add-workflow-graph.ts +0 -644
- package/src/add/add-workflow-on-error.test.ts +0 -118
- package/src/add/add-workflow-return-switch.test.ts +0 -121
- package/src/add/add-workflow-silent-drops.test.ts +0 -261
- package/src/add/add-workflow-sleep-expression.test.ts +0 -96
- package/src/add/add-workflow.test.ts +0 -155
- package/src/add/add-workflow.ts +0 -482
- package/src/add/addon-bans.test.ts +0 -121
- package/src/add/addon-contracts.test.ts +0 -221
- package/src/add/allow-escape-hatches.test.ts +0 -144
- package/src/add/audit-meta.test.ts +0 -75
- package/src/add/classified-sink-check.test.ts +0 -347
- package/src/add/config-value-metadata.test.ts +0 -263
- package/src/add/dynamic-import-check.test.ts +0 -119
- package/src/add/expect-eventually-scenario-only.test.ts +0 -108
- package/src/add/function-body-span.test.ts +0 -96
- package/src/add/inline-wiring-function.test.ts +0 -104
- package/src/add/pii-check.test.ts +0 -258
- package/src/add/rpc-type-cast.test.ts +0 -123
- package/src/add/scenario-instrumentation.test.ts +0 -89
- package/src/add/scenario-instrumentation.ts +0 -42
- package/src/add/scenario-marker.test.ts +0 -89
- package/src/add/scenario-not-extractable.test.ts +0 -159
- package/src/add/scenario-services.test.ts +0 -103
- package/src/add/scenario-skip.test.ts +0 -83
- package/src/add/validate-workflow-graph-addons.test.ts +0 -102
- package/src/add/wire-name-literal.test.ts +0 -117
- package/src/error-codes-emitted.test.ts +0 -76
- package/src/error-codes.ts +0 -145
- package/src/index.ts +0 -66
- package/src/inspector.ts +0 -575
- package/src/schema-generator.ts +0 -1
- package/src/source-file-cache.ts +0 -73
- package/src/tsconfig-paths.test.ts +0 -90
- package/src/types-map.ts +0 -141
- package/src/types.ts +0 -775
- package/src/utils/annotate-http-route-auth.test.ts +0 -161
- package/src/utils/annotate-http-route-auth.ts +0 -53
- package/src/utils/check-classified-sinks.ts +0 -215
- package/src/utils/check-pii-output.ts +0 -120
- package/src/utils/compute-diagnostics.test.ts +0 -106
- package/src/utils/compute-required-schemas.ts +0 -48
- package/src/utils/contract-hashes.test.ts +0 -553
- package/src/utils/contract-hashes.ts +0 -387
- package/src/utils/custom-types-generator.test.ts +0 -124
- package/src/utils/custom-types-generator.ts +0 -150
- package/src/utils/detect-schema-vendor.test.ts +0 -123
- package/src/utils/detect-schema-vendor.ts +0 -120
- package/src/utils/does-type-extend-core-type.ts +0 -53
- package/src/utils/ensure-function-metadata.ts +0 -385
- package/src/utils/extract-function-name.ts +0 -612
- package/src/utils/extract-function-node.ts +0 -70
- package/src/utils/extract-node-value.test.ts +0 -117
- package/src/utils/extract-node-value.ts +0 -172
- package/src/utils/extract-secret-usage.test.ts +0 -81
- package/src/utils/extract-secret-usage.ts +0 -73
- package/src/utils/extract-services.ts +0 -70
- package/src/utils/extract-surface-usage.test.ts +0 -147
- package/src/utils/extract-surface-usage.ts +0 -121
- package/src/utils/filter-inspector-state.test.ts +0 -2232
- package/src/utils/filter-inspector-state.ts +0 -1298
- package/src/utils/filter-utils.test.ts +0 -843
- package/src/utils/filter-utils.ts +0 -161
- package/src/utils/find-root-dir.ts +0 -68
- package/src/utils/find-zod-transform.test.ts +0 -70
- package/src/utils/find-zod-transform.ts +0 -103
- package/src/utils/get-exported-variable-name.ts +0 -48
- package/src/utils/get-files-and-methods.ts +0 -157
- package/src/utils/get-property-value.test.ts +0 -141
- package/src/utils/get-property-value.ts +0 -331
- package/src/utils/hash.ts +0 -26
- package/src/utils/literal-properties.ts +0 -97
- package/src/utils/load-addon-functions-meta.test.ts +0 -157
- package/src/utils/load-addon-functions-meta.ts +0 -508
- package/src/utils/load-addon-scopes.test.ts +0 -138
- package/src/utils/middleware.test.ts +0 -204
- package/src/utils/middleware.ts +0 -303
- package/src/utils/nested-project-filter.test.ts +0 -53
- package/src/utils/nested-project-filter.ts +0 -28
- package/src/utils/permissions-shorthand.test.ts +0 -79
- package/src/utils/permissions.test.ts +0 -125
- package/src/utils/permissions.ts +0 -129
- package/src/utils/post-process.test.ts +0 -1094
- package/src/utils/post-process.ts +0 -1604
- package/src/utils/resolve-addon-package.ts +0 -106
- package/src/utils/resolve-core-type.test.ts +0 -142
- package/src/utils/resolve-core-type.ts +0 -35
- package/src/utils/resolve-deploy-target.test.ts +0 -135
- package/src/utils/resolve-deploy-target.ts +0 -65
- package/src/utils/resolve-function-meta.ts +0 -25
- package/src/utils/resolve-function-types.ts +0 -42
- package/src/utils/resolve-identifier.ts +0 -46
- package/src/utils/resolve-ref-contract.ts +0 -71
- package/src/utils/resolve-versions.test.ts +0 -499
- package/src/utils/resolve-versions.ts +0 -228
- package/src/utils/schema-cache.test.ts +0 -124
- package/src/utils/schema-generator.test.ts +0 -272
- package/src/utils/schema-generator.ts +0 -780
- package/src/utils/secret-alias-services.test.ts +0 -146
- package/src/utils/secret-alias-services.ts +0 -58
- package/src/utils/serialize-inspector-state.ts +0 -742
- package/src/utils/serialize-mcp-json.ts +0 -150
- package/src/utils/serialize-middleware-groups-meta.ts +0 -36
- package/src/utils/serialize-openapi-json.ts +0 -277
- package/src/utils/serialize-permissions-groups-meta.ts +0 -7
- package/src/utils/single-declaration.ts +0 -57
- package/src/utils/type-utils.ts +0 -145
- package/src/utils/validate-auth-sessionless.ts +0 -30
- package/src/utils/validate-exposed-functions-gated.test.ts +0 -230
- package/src/utils/validate-exposed-functions-gated.ts +0 -103
- package/src/utils/validate-tags-resolve-to-middleware.test.ts +0 -108
- package/src/utils/validate-tags-resolve-to-middleware.ts +0 -48
- package/src/utils/workflow/derive-workflow-plan.test.ts +0 -178
- package/src/utils/workflow/derive-workflow-plan.ts +0 -117
- package/src/utils/workflow/dsl/deserialize-dsl-workflow.ts +0 -1465
- package/src/utils/workflow/dsl/deserialize-fanout-body.test.ts +0 -71
- package/src/utils/workflow/dsl/deserialize-fanout-fidelity.test.ts +0 -99
- package/src/utils/workflow/dsl/deserialize-graph-next.test.ts +0 -161
- package/src/utils/workflow/dsl/deserialize-roundtrip-bindings.test.ts +0 -121
- package/src/utils/workflow/dsl/deserialize-roundtrip-values.test.ts +0 -116
- package/src/utils/workflow/dsl/deserialize-roundtrip.test.ts +0 -145
- package/src/utils/workflow/dsl/extract-approval-policy.test.ts +0 -71
- package/src/utils/workflow/dsl/extract-dsl-workflow.ts +0 -2254
- package/src/utils/workflow/dsl/index.ts +0 -11
- package/src/utils/workflow/dsl/patterns.ts +0 -440
- package/src/utils/workflow/dsl/validation.ts +0 -203
- package/src/utils/workflow/graph/convert-dsl-to-graph-skip.test.ts +0 -35
- package/src/utils/workflow/graph/convert-dsl-to-graph.ts +0 -543
- package/src/utils/workflow/graph/fanout-node-identity.test.ts +0 -105
- package/src/utils/workflow/graph/finalize-workflow-wires.ts +0 -310
- package/src/utils/workflow/graph/finalize-workflows.test.ts +0 -50
- package/src/utils/workflow/graph/finalize-workflows.ts +0 -130
- package/src/utils/workflow/graph/index.ts +0 -28
- package/src/utils/workflow/graph/serialize-workflow-graph.ts +0 -240
- package/src/utils/workflow/graph/workflow-graph.types.ts +0 -281
- package/src/visit.ts +0 -181
- package/tsconfig.json +0 -19
- package/tsconfig.tsbuildinfo +0 -1
|
@@ -1,157 +0,0 @@
|
|
|
1
|
-
import * as ts from 'typescript'
|
|
2
|
-
import {
|
|
3
|
-
getPropertyValue,
|
|
4
|
-
getCommonWireMetaData,
|
|
5
|
-
} from '../utils/get-property-value.js'
|
|
6
|
-
import { extractWireNames } from '../utils/post-process.js'
|
|
7
|
-
import { ensureFunctionMetadata } from '../utils/ensure-function-metadata.js'
|
|
8
|
-
import type { AddWiring } from '../types.js'
|
|
9
|
-
import {
|
|
10
|
-
extractFunctionName,
|
|
11
|
-
makeContextBasedId,
|
|
12
|
-
} from '../utils/extract-function-name.js'
|
|
13
|
-
import { getPropertyAssignmentInitializer } from '../utils/type-utils.js'
|
|
14
|
-
import { resolveMiddleware } from '../utils/middleware.js'
|
|
15
|
-
import { resolvePermissions } from '../utils/permissions.js'
|
|
16
|
-
import { resolveAddonName } from '../utils/resolve-addon-package.js'
|
|
17
|
-
import { ErrorCode } from '../error-codes.js'
|
|
18
|
-
|
|
19
|
-
export const addMCPPrompt: AddWiring = (
|
|
20
|
-
logger,
|
|
21
|
-
node,
|
|
22
|
-
checker,
|
|
23
|
-
state,
|
|
24
|
-
options
|
|
25
|
-
) => {
|
|
26
|
-
if (!ts.isCallExpression(node)) {
|
|
27
|
-
return
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
const args = node.arguments
|
|
31
|
-
const firstArg = args[0]
|
|
32
|
-
const expression = node.expression
|
|
33
|
-
|
|
34
|
-
// Check if the call is to wireMCPPrompt
|
|
35
|
-
if (!ts.isIdentifier(expression) || expression.text !== 'wireMCPPrompt') {
|
|
36
|
-
return
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
if (!firstArg) {
|
|
40
|
-
return
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
if (ts.isObjectLiteralExpression(firstArg)) {
|
|
44
|
-
const obj = firstArg
|
|
45
|
-
|
|
46
|
-
const nameValue = getPropertyValue(obj, 'name') as string | null
|
|
47
|
-
const { disabled, tags, summary, description, errors } =
|
|
48
|
-
getCommonWireMetaData(obj, 'MCP prompt', nameValue, logger, checker)
|
|
49
|
-
|
|
50
|
-
if (disabled) return
|
|
51
|
-
|
|
52
|
-
const funcInitializer = getPropertyAssignmentInitializer(
|
|
53
|
-
obj,
|
|
54
|
-
'func',
|
|
55
|
-
true,
|
|
56
|
-
checker
|
|
57
|
-
)
|
|
58
|
-
if (!funcInitializer) {
|
|
59
|
-
logger.critical(
|
|
60
|
-
ErrorCode.MISSING_FUNC,
|
|
61
|
-
`No valid 'func' property for MCP prompt '${nameValue}'.`
|
|
62
|
-
)
|
|
63
|
-
return
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
const extracted = extractFunctionName(
|
|
67
|
-
funcInitializer,
|
|
68
|
-
checker,
|
|
69
|
-
state.rootDir
|
|
70
|
-
)
|
|
71
|
-
let pikkuFuncId = extracted.pikkuFuncId
|
|
72
|
-
if (pikkuFuncId.startsWith('__temp_') && nameValue) {
|
|
73
|
-
pikkuFuncId = makeContextBasedId('mcp', 'prompt', nameValue)
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
const packageName = ts.isIdentifier(funcInitializer)
|
|
77
|
-
? resolveAddonName(
|
|
78
|
-
funcInitializer,
|
|
79
|
-
checker,
|
|
80
|
-
state.rpc.wireAddonDeclarations
|
|
81
|
-
)
|
|
82
|
-
: null
|
|
83
|
-
|
|
84
|
-
ensureFunctionMetadata(
|
|
85
|
-
state,
|
|
86
|
-
pikkuFuncId,
|
|
87
|
-
nameValue || undefined,
|
|
88
|
-
funcInitializer,
|
|
89
|
-
checker,
|
|
90
|
-
extracted.isHelper
|
|
91
|
-
)
|
|
92
|
-
|
|
93
|
-
if (!nameValue) {
|
|
94
|
-
logger.critical(
|
|
95
|
-
ErrorCode.MISSING_NAME,
|
|
96
|
-
"MCP prompt is missing the required 'name' property."
|
|
97
|
-
)
|
|
98
|
-
return
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
if (!description) {
|
|
102
|
-
logger.critical(
|
|
103
|
-
ErrorCode.MISSING_DESCRIPTION,
|
|
104
|
-
`MCP prompt '${nameValue}' is missing a description.`
|
|
105
|
-
)
|
|
106
|
-
return
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
// lookup existing function metadata
|
|
110
|
-
const fnMeta = state.functions.meta[pikkuFuncId]
|
|
111
|
-
if (!fnMeta) {
|
|
112
|
-
logger.critical(
|
|
113
|
-
ErrorCode.FUNCTION_METADATA_NOT_FOUND,
|
|
114
|
-
`No function metadata found for '${pikkuFuncId}'.`
|
|
115
|
-
)
|
|
116
|
-
return
|
|
117
|
-
}
|
|
118
|
-
const inputSchema = fnMeta.inputs?.[0] || null
|
|
119
|
-
const outputSchema = fnMeta.outputs?.[0] || null
|
|
120
|
-
|
|
121
|
-
if (!fnMeta.outputSchemaName) {
|
|
122
|
-
fnMeta.outputSchemaName = 'MCPPromptResponse'
|
|
123
|
-
fnMeta.outputs = ['MCPPromptResponse']
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
// --- resolve middleware ---
|
|
127
|
-
const middleware = resolveMiddleware(state, obj, tags, checker)
|
|
128
|
-
|
|
129
|
-
// --- resolve permissions ---
|
|
130
|
-
const permissions = resolvePermissions(state, obj, tags, checker)
|
|
131
|
-
|
|
132
|
-
// --- track used functions/middleware/permissions for service aggregation ---
|
|
133
|
-
state.serviceAggregation.usedFunctions.add(pikkuFuncId)
|
|
134
|
-
extractWireNames(middleware).forEach((name) =>
|
|
135
|
-
state.serviceAggregation.usedMiddleware.add(name)
|
|
136
|
-
)
|
|
137
|
-
extractWireNames(permissions).forEach((name) =>
|
|
138
|
-
state.serviceAggregation.usedPermissions.add(name)
|
|
139
|
-
)
|
|
140
|
-
|
|
141
|
-
state.mcpEndpoints.files.add(node.getSourceFile().fileName)
|
|
142
|
-
|
|
143
|
-
state.mcpEndpoints.promptsMeta[nameValue] = {
|
|
144
|
-
pikkuFuncId,
|
|
145
|
-
...(packageName && { packageName }),
|
|
146
|
-
name: nameValue,
|
|
147
|
-
description,
|
|
148
|
-
summary,
|
|
149
|
-
errors,
|
|
150
|
-
tags,
|
|
151
|
-
inputSchema,
|
|
152
|
-
outputSchema,
|
|
153
|
-
arguments: [], // Will be populated by CLI during serialization
|
|
154
|
-
middleware,
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
}
|
|
@@ -1,175 +0,0 @@
|
|
|
1
|
-
import * as ts from 'typescript'
|
|
2
|
-
import {
|
|
3
|
-
getPropertyValue,
|
|
4
|
-
getCommonWireMetaData,
|
|
5
|
-
} from '../utils/get-property-value.js'
|
|
6
|
-
import { extractWireNames } from '../utils/post-process.js'
|
|
7
|
-
import { ensureFunctionMetadata } from '../utils/ensure-function-metadata.js'
|
|
8
|
-
import type { AddWiring } from '../types.js'
|
|
9
|
-
import {
|
|
10
|
-
extractFunctionName,
|
|
11
|
-
makeContextBasedId,
|
|
12
|
-
} from '../utils/extract-function-name.js'
|
|
13
|
-
import { getPropertyAssignmentInitializer } from '../utils/type-utils.js'
|
|
14
|
-
import { resolveMiddleware } from '../utils/middleware.js'
|
|
15
|
-
import { resolvePermissions } from '../utils/permissions.js'
|
|
16
|
-
import { resolveAddonName } from '../utils/resolve-addon-package.js'
|
|
17
|
-
import { ErrorCode } from '../error-codes.js'
|
|
18
|
-
|
|
19
|
-
export const addMCPResource: AddWiring = (
|
|
20
|
-
logger,
|
|
21
|
-
node,
|
|
22
|
-
checker,
|
|
23
|
-
state,
|
|
24
|
-
options
|
|
25
|
-
) => {
|
|
26
|
-
if (!ts.isCallExpression(node)) {
|
|
27
|
-
return
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
const args = node.arguments
|
|
31
|
-
const firstArg = args[0]
|
|
32
|
-
const expression = node.expression
|
|
33
|
-
|
|
34
|
-
// Check if the call is to wireMCPResource
|
|
35
|
-
if (!ts.isIdentifier(expression) || expression.text !== 'wireMCPResource') {
|
|
36
|
-
return
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
if (!firstArg) {
|
|
40
|
-
return
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
if (ts.isObjectLiteralExpression(firstArg)) {
|
|
44
|
-
const obj = firstArg
|
|
45
|
-
|
|
46
|
-
const uriValue = getPropertyValue(obj, 'uri') as string | null
|
|
47
|
-
const titleValue = getPropertyValue(obj, 'title') as string | null
|
|
48
|
-
const { disabled, tags, summary, description, errors } =
|
|
49
|
-
getCommonWireMetaData(obj, 'MCP resource', uriValue, logger, checker)
|
|
50
|
-
|
|
51
|
-
if (disabled) return
|
|
52
|
-
|
|
53
|
-
const streamingValue = getPropertyValue(obj, 'streaming') as boolean | null
|
|
54
|
-
|
|
55
|
-
if (streamingValue === true) {
|
|
56
|
-
logger.warn(
|
|
57
|
-
`MCP resource '${uriValue}' has streaming enabled, but streaming is not yet supported.`
|
|
58
|
-
)
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
const funcInitializer = getPropertyAssignmentInitializer(
|
|
62
|
-
obj,
|
|
63
|
-
'func',
|
|
64
|
-
true,
|
|
65
|
-
checker
|
|
66
|
-
)
|
|
67
|
-
if (!funcInitializer) {
|
|
68
|
-
logger.critical(
|
|
69
|
-
ErrorCode.MISSING_FUNC,
|
|
70
|
-
`No valid 'func' property for MCP resource '${uriValue}'.`
|
|
71
|
-
)
|
|
72
|
-
return
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
const extracted = extractFunctionName(
|
|
76
|
-
funcInitializer,
|
|
77
|
-
checker,
|
|
78
|
-
state.rootDir
|
|
79
|
-
)
|
|
80
|
-
let pikkuFuncId = extracted.pikkuFuncId
|
|
81
|
-
if (pikkuFuncId.startsWith('__temp_') && uriValue) {
|
|
82
|
-
pikkuFuncId = makeContextBasedId('mcp', 'resource', uriValue)
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
const packageName = ts.isIdentifier(funcInitializer)
|
|
86
|
-
? resolveAddonName(
|
|
87
|
-
funcInitializer,
|
|
88
|
-
checker,
|
|
89
|
-
state.rpc.wireAddonDeclarations
|
|
90
|
-
)
|
|
91
|
-
: null
|
|
92
|
-
|
|
93
|
-
ensureFunctionMetadata(
|
|
94
|
-
state,
|
|
95
|
-
pikkuFuncId,
|
|
96
|
-
uriValue || undefined,
|
|
97
|
-
funcInitializer,
|
|
98
|
-
checker,
|
|
99
|
-
extracted.isHelper
|
|
100
|
-
)
|
|
101
|
-
|
|
102
|
-
if (!uriValue) {
|
|
103
|
-
logger.critical(
|
|
104
|
-
ErrorCode.MISSING_URI,
|
|
105
|
-
"MCP resource is missing the required 'uri' property."
|
|
106
|
-
)
|
|
107
|
-
return
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
if (!titleValue) {
|
|
111
|
-
logger.critical(
|
|
112
|
-
ErrorCode.MISSING_TITLE,
|
|
113
|
-
`MCP resource '${uriValue}' is missing the required 'title' property.`
|
|
114
|
-
)
|
|
115
|
-
return
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
if (!description) {
|
|
119
|
-
logger.critical(
|
|
120
|
-
ErrorCode.MISSING_DESCRIPTION,
|
|
121
|
-
`MCP resource '${uriValue}' is missing a description.`
|
|
122
|
-
)
|
|
123
|
-
return
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
// lookup existing function metadata
|
|
127
|
-
const fnMeta = state.functions.meta[pikkuFuncId]
|
|
128
|
-
if (!fnMeta) {
|
|
129
|
-
logger.critical(
|
|
130
|
-
ErrorCode.FUNCTION_METADATA_NOT_FOUND,
|
|
131
|
-
`No function metadata found for '${pikkuFuncId}'.`
|
|
132
|
-
)
|
|
133
|
-
return
|
|
134
|
-
}
|
|
135
|
-
const inputSchema = fnMeta.inputs?.[0] || null
|
|
136
|
-
const outputSchema = fnMeta.outputs?.[0] || null
|
|
137
|
-
|
|
138
|
-
if (!fnMeta.outputSchemaName) {
|
|
139
|
-
fnMeta.outputSchemaName = 'MCPResourceResponse'
|
|
140
|
-
fnMeta.outputs = ['MCPResourceResponse']
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
// --- resolve middleware ---
|
|
144
|
-
const middleware = resolveMiddleware(state, obj, tags, checker)
|
|
145
|
-
|
|
146
|
-
// --- resolve permissions ---
|
|
147
|
-
const permissions = resolvePermissions(state, obj, tags, checker)
|
|
148
|
-
|
|
149
|
-
// --- track used functions/middleware/permissions for service aggregation ---
|
|
150
|
-
state.serviceAggregation.usedFunctions.add(pikkuFuncId)
|
|
151
|
-
extractWireNames(middleware).forEach((name) =>
|
|
152
|
-
state.serviceAggregation.usedMiddleware.add(name)
|
|
153
|
-
)
|
|
154
|
-
extractWireNames(permissions).forEach((name) =>
|
|
155
|
-
state.serviceAggregation.usedPermissions.add(name)
|
|
156
|
-
)
|
|
157
|
-
|
|
158
|
-
state.mcpEndpoints.files.add(node.getSourceFile().fileName)
|
|
159
|
-
|
|
160
|
-
state.mcpEndpoints.resourcesMeta[uriValue] = {
|
|
161
|
-
pikkuFuncId,
|
|
162
|
-
...(packageName && { packageName }),
|
|
163
|
-
uri: uriValue,
|
|
164
|
-
title: titleValue,
|
|
165
|
-
description,
|
|
166
|
-
summary,
|
|
167
|
-
errors,
|
|
168
|
-
...(streamingValue !== null && { streaming: streamingValue }),
|
|
169
|
-
tags,
|
|
170
|
-
inputSchema,
|
|
171
|
-
outputSchema,
|
|
172
|
-
middleware,
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
}
|
|
@@ -1,196 +0,0 @@
|
|
|
1
|
-
import { strict as assert } from 'assert'
|
|
2
|
-
import { describe, test } from 'node:test'
|
|
3
|
-
import { mkdtemp, rm, writeFile } from 'node:fs/promises'
|
|
4
|
-
import { tmpdir } from 'node:os'
|
|
5
|
-
import { join } from 'node:path'
|
|
6
|
-
import { inspect } from '../inspector.js'
|
|
7
|
-
import type { ErrorCode } from '../error-codes.js'
|
|
8
|
-
import type { InspectorLogger, MiddlewareGroupMeta } from '../types.js'
|
|
9
|
-
|
|
10
|
-
const makeLogger = (criticals: Array<{ code: ErrorCode; message: string }>) =>
|
|
11
|
-
({
|
|
12
|
-
debug: () => {},
|
|
13
|
-
info: () => {},
|
|
14
|
-
warn: () => {},
|
|
15
|
-
error: () => {},
|
|
16
|
-
diagnostic: ({ code, message }) => {
|
|
17
|
-
criticals.push({ code, message })
|
|
18
|
-
},
|
|
19
|
-
critical: (code: ErrorCode, message: string) => {
|
|
20
|
-
criticals.push({ code, message })
|
|
21
|
-
},
|
|
22
|
-
hasCriticalErrors: () => criticals.length > 0,
|
|
23
|
-
}) satisfies InspectorLogger
|
|
24
|
-
|
|
25
|
-
/** Every file that registered middleware for one pattern or tag. */
|
|
26
|
-
const sourceFiles = (group: MiddlewareGroupMeta | undefined): string[] =>
|
|
27
|
-
group
|
|
28
|
-
? [
|
|
29
|
-
group.sourceFile,
|
|
30
|
-
...(group.additionalRegistrations ?? []).map((r) => r.sourceFile),
|
|
31
|
-
]
|
|
32
|
-
: []
|
|
33
|
-
|
|
34
|
-
/** Runs the inspector over files written into a throwaway directory. */
|
|
35
|
-
const withProject = async (
|
|
36
|
-
prefix: string,
|
|
37
|
-
files: Record<string, string[]>,
|
|
38
|
-
assertions: (state: Awaited<ReturnType<typeof inspect>>) => void
|
|
39
|
-
) => {
|
|
40
|
-
const rootDir = await mkdtemp(join(tmpdir(), prefix))
|
|
41
|
-
const paths: string[] = []
|
|
42
|
-
for (const [name, lines] of Object.entries(files)) {
|
|
43
|
-
const path = join(rootDir, name)
|
|
44
|
-
await writeFile(path, lines.join('\n'))
|
|
45
|
-
paths.push(path)
|
|
46
|
-
}
|
|
47
|
-
try {
|
|
48
|
-
assertions(await inspect(makeLogger([]), paths, { rootDir }))
|
|
49
|
-
} finally {
|
|
50
|
-
await rm(rootDir, { recursive: true, force: true })
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
describe('addMiddleware inspector', () => {
|
|
55
|
-
describe('two files registering the same HTTP pattern', () => {
|
|
56
|
-
// The group is keyed by pattern, so the second call used to overwrite the
|
|
57
|
-
// first. Codegen emits imports from what is stored, so the losing file was
|
|
58
|
-
// never imported and its middleware never registered — an app could lose
|
|
59
|
-
// its session bridge to an unrelated '*' group and see nothing go wrong
|
|
60
|
-
// until a request arrived without a session.
|
|
61
|
-
const project = {
|
|
62
|
-
'session.ts': [
|
|
63
|
-
"import { addHTTPMiddleware, pikkuMiddleware } from '#pikku'",
|
|
64
|
-
'export const sessionMiddleware = () =>',
|
|
65
|
-
" addHTTPMiddleware('*', [",
|
|
66
|
-
' pikkuMiddleware(async (_s, _w, next) => next()),',
|
|
67
|
-
' ])',
|
|
68
|
-
],
|
|
69
|
-
'logging.ts': [
|
|
70
|
-
"import { addHTTPMiddleware, pikkuMiddleware } from '#pikku'",
|
|
71
|
-
'export const loggingMiddleware = () =>',
|
|
72
|
-
" addHTTPMiddleware('*', [",
|
|
73
|
-
' pikkuMiddleware(async (_s, _w, next) => next()),',
|
|
74
|
-
' ])',
|
|
75
|
-
],
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
test('keeps both registrations', async () => {
|
|
79
|
-
await withProject('pikku-mw-http-collide-', project, (state) => {
|
|
80
|
-
const group = state.http.routeMiddleware.get('*')
|
|
81
|
-
assert.ok(group, "expected a group for '*'")
|
|
82
|
-
assert.equal(
|
|
83
|
-
sourceFiles(group).length,
|
|
84
|
-
2,
|
|
85
|
-
'both files must survive, or one middleware silently stops running'
|
|
86
|
-
)
|
|
87
|
-
})
|
|
88
|
-
})
|
|
89
|
-
|
|
90
|
-
test('keeps both export names, so both can be imported', async () => {
|
|
91
|
-
await withProject('pikku-mw-http-names-', project, (state) => {
|
|
92
|
-
const group = state.http.routeMiddleware.get('*')!
|
|
93
|
-
const names = [
|
|
94
|
-
group.exportName,
|
|
95
|
-
...(group.additionalRegistrations ?? []).map((r) => r.exportName),
|
|
96
|
-
]
|
|
97
|
-
assert.deepEqual(names.sort(), [
|
|
98
|
-
'loggingMiddleware',
|
|
99
|
-
'sessionMiddleware',
|
|
100
|
-
])
|
|
101
|
-
})
|
|
102
|
-
})
|
|
103
|
-
|
|
104
|
-
test('unions the services both registrations need', async () => {
|
|
105
|
-
await withProject('pikku-mw-http-services-', project, (state) => {
|
|
106
|
-
const group = state.http.routeMiddleware.get('*')!
|
|
107
|
-
assert.equal(
|
|
108
|
-
new Set(group.services.services).size,
|
|
109
|
-
group.services.services.length,
|
|
110
|
-
'services must not repeat when two groups merge'
|
|
111
|
-
)
|
|
112
|
-
})
|
|
113
|
-
})
|
|
114
|
-
})
|
|
115
|
-
|
|
116
|
-
test('a single registration is unchanged', async () => {
|
|
117
|
-
await withProject(
|
|
118
|
-
'pikku-mw-http-single-',
|
|
119
|
-
{
|
|
120
|
-
'session.ts': [
|
|
121
|
-
"import { addHTTPMiddleware, pikkuMiddleware } from '#pikku'",
|
|
122
|
-
'export const sessionMiddleware = () =>',
|
|
123
|
-
" addHTTPMiddleware('*', [",
|
|
124
|
-
' pikkuMiddleware(async (_s, _w, next) => next()),',
|
|
125
|
-
' ])',
|
|
126
|
-
],
|
|
127
|
-
},
|
|
128
|
-
(state) => {
|
|
129
|
-
const group = state.http.routeMiddleware.get('*')!
|
|
130
|
-
assert.equal(group.exportName, 'sessionMiddleware')
|
|
131
|
-
assert.equal(
|
|
132
|
-
group.additionalRegistrations,
|
|
133
|
-
undefined,
|
|
134
|
-
'nothing to merge means nothing extra to serialize'
|
|
135
|
-
)
|
|
136
|
-
}
|
|
137
|
-
)
|
|
138
|
-
})
|
|
139
|
-
|
|
140
|
-
test('different patterns stay separate groups', async () => {
|
|
141
|
-
await withProject(
|
|
142
|
-
'pikku-mw-http-distinct-',
|
|
143
|
-
{
|
|
144
|
-
'session.ts': [
|
|
145
|
-
"import { addHTTPMiddleware, pikkuMiddleware } from '#pikku'",
|
|
146
|
-
'export const sessionMiddleware = () =>',
|
|
147
|
-
" addHTTPMiddleware('*', [",
|
|
148
|
-
' pikkuMiddleware(async (_s, _w, next) => next()),',
|
|
149
|
-
' ])',
|
|
150
|
-
],
|
|
151
|
-
'api.ts': [
|
|
152
|
-
"import { addHTTPMiddleware, pikkuMiddleware } from '#pikku'",
|
|
153
|
-
'export const apiMiddleware = () =>',
|
|
154
|
-
" addHTTPMiddleware('/api/*', [",
|
|
155
|
-
' pikkuMiddleware(async (_s, _w, next) => next()),',
|
|
156
|
-
' ])',
|
|
157
|
-
],
|
|
158
|
-
},
|
|
159
|
-
(state) => {
|
|
160
|
-
assert.equal(sourceFiles(state.http.routeMiddleware.get('*')).length, 1)
|
|
161
|
-
assert.equal(
|
|
162
|
-
sourceFiles(state.http.routeMiddleware.get('/api/*')).length,
|
|
163
|
-
1
|
|
164
|
-
)
|
|
165
|
-
}
|
|
166
|
-
)
|
|
167
|
-
})
|
|
168
|
-
|
|
169
|
-
test('two files registering the same tag keep both registrations', async () => {
|
|
170
|
-
await withProject(
|
|
171
|
-
'pikku-mw-tag-collide-',
|
|
172
|
-
{
|
|
173
|
-
'session.ts': [
|
|
174
|
-
"import { addTagMiddleware, pikkuMiddleware } from '#pikku'",
|
|
175
|
-
'export const sessionTag = () =>',
|
|
176
|
-
" addTagMiddleware('api', [",
|
|
177
|
-
' pikkuMiddleware(async (_s, _w, next) => next()),',
|
|
178
|
-
' ])',
|
|
179
|
-
],
|
|
180
|
-
'logging.ts': [
|
|
181
|
-
"import { addTagMiddleware, pikkuMiddleware } from '#pikku'",
|
|
182
|
-
'export const loggingTag = () =>',
|
|
183
|
-
" addTagMiddleware('api', [",
|
|
184
|
-
' pikkuMiddleware(async (_s, _w, next) => next()),',
|
|
185
|
-
' ])',
|
|
186
|
-
],
|
|
187
|
-
},
|
|
188
|
-
(state) => {
|
|
189
|
-
assert.equal(
|
|
190
|
-
sourceFiles(state.middleware.tagMiddleware.get('api')).length,
|
|
191
|
-
2
|
|
192
|
-
)
|
|
193
|
-
}
|
|
194
|
-
)
|
|
195
|
-
})
|
|
196
|
-
})
|