@pikku/inspector 0.11.2 → 0.12.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +36 -1
- package/OPTIMIZATION-PLAN.md +195 -0
- package/dist/add/add-ai-agent.d.ts +2 -0
- package/dist/add/add-ai-agent.js +314 -0
- package/dist/add/add-channel.js +81 -61
- package/dist/add/add-cli.d.ts +1 -1
- package/dist/add/add-cli.js +42 -19
- package/dist/add/add-file-extends-core-type.d.ts +1 -1
- package/dist/add/add-file-with-config.d.ts +1 -1
- package/dist/add/add-file-with-factory.d.ts +1 -1
- package/dist/add/add-file-with-factory.js +2 -0
- package/dist/add/add-functions.d.ts +1 -1
- package/dist/add/add-functions.js +256 -82
- package/dist/add/add-http-route.d.ts +20 -10
- package/dist/add/add-http-route.js +156 -66
- package/dist/add/add-http-routes.d.ts +5 -0
- package/dist/add/add-http-routes.js +160 -0
- package/dist/add/add-keyed-wiring.d.ts +12 -0
- package/dist/add/add-keyed-wiring.js +97 -0
- package/dist/add/add-mcp-prompt.d.ts +1 -1
- package/dist/add/add-mcp-prompt.js +14 -9
- package/dist/add/add-mcp-resource.d.ts +1 -1
- package/dist/add/add-mcp-resource.js +14 -9
- package/dist/add/add-middleware.d.ts +1 -4
- package/dist/add/add-middleware.js +364 -79
- package/dist/add/add-permission.d.ts +1 -1
- package/dist/add/add-permission.js +152 -40
- package/dist/add/add-queue-worker.d.ts +1 -1
- package/dist/add/add-queue-worker.js +18 -12
- package/dist/add/add-rpc-invocations.d.ts +3 -3
- package/dist/add/add-rpc-invocations.js +24 -10
- package/dist/add/add-schedule.d.ts +1 -1
- package/dist/add/add-schedule.js +11 -5
- package/dist/add/add-secret.d.ts +3 -0
- package/dist/add/add-secret.js +82 -0
- package/dist/add/add-trigger.d.ts +2 -0
- package/dist/add/add-trigger.js +87 -0
- package/dist/add/add-variable.d.ts +1 -0
- package/dist/add/add-variable.js +8 -0
- package/dist/add/add-wire-addon.d.ts +7 -0
- package/dist/add/add-wire-addon.js +70 -0
- package/dist/add/add-workflow-graph.d.ts +3 -2
- package/dist/add/add-workflow-graph.js +143 -406
- package/dist/add/add-workflow.d.ts +1 -1
- package/dist/add/add-workflow.js +6 -4
- package/dist/error-codes.d.ts +15 -1
- package/dist/error-codes.js +20 -1
- package/dist/index.d.ts +9 -8
- package/dist/index.js +5 -4
- package/dist/inspector.d.ts +2 -2
- package/dist/inspector.js +95 -15
- package/dist/schema-generator.d.ts +1 -0
- package/dist/schema-generator.js +1 -0
- package/dist/types-map.js +10 -1
- package/dist/types.d.ts +180 -50
- package/dist/utils/compute-required-schemas.d.ts +4 -0
- package/dist/utils/compute-required-schemas.js +40 -0
- package/dist/utils/contract-hashes.d.ts +52 -0
- package/dist/utils/contract-hashes.js +269 -0
- package/dist/utils/custom-types-generator.d.ts +9 -0
- package/dist/utils/custom-types-generator.js +71 -0
- package/dist/utils/detect-schema-vendor.d.ts +22 -0
- package/dist/utils/detect-schema-vendor.js +76 -0
- package/dist/utils/does-type-extend-core-type.d.ts +1 -1
- package/dist/utils/ensure-function-metadata.d.ts +6 -3
- package/dist/utils/ensure-function-metadata.js +220 -6
- package/dist/utils/extract-function-name.d.ts +5 -16
- package/dist/utils/extract-function-name.js +86 -291
- package/dist/utils/extract-services.d.ts +2 -1
- package/dist/utils/extract-services.js +25 -1
- package/dist/utils/filter-inspector-state.d.ts +1 -1
- package/dist/utils/filter-inspector-state.js +107 -23
- package/dist/utils/filter-utils.d.ts +2 -2
- package/dist/utils/get-files-and-methods.d.ts +1 -1
- package/dist/utils/get-property-value.d.ts +6 -1
- package/dist/utils/get-property-value.js +28 -3
- package/dist/utils/hash.d.ts +2 -0
- package/dist/utils/hash.js +23 -0
- package/dist/utils/middleware.d.ts +9 -32
- package/dist/utils/middleware.js +80 -66
- package/dist/utils/permissions.d.ts +4 -4
- package/dist/utils/permissions.js +10 -10
- package/dist/utils/post-process.d.ts +11 -11
- package/dist/utils/post-process.js +247 -24
- package/dist/utils/resolve-addon-package.d.ts +16 -0
- package/dist/utils/resolve-addon-package.js +34 -0
- package/dist/utils/resolve-function-types.d.ts +6 -0
- package/dist/utils/resolve-function-types.js +29 -0
- package/dist/utils/resolve-identifier.d.ts +10 -0
- package/dist/utils/resolve-identifier.js +36 -0
- package/dist/utils/resolve-versions.d.ts +2 -0
- package/dist/utils/resolve-versions.js +78 -0
- package/dist/utils/schema-generator.d.ts +9 -0
- package/dist/utils/schema-generator.js +209 -0
- package/dist/utils/serialize-inspector-state.d.ts +70 -23
- package/dist/utils/serialize-inspector-state.js +98 -22
- package/dist/utils/serialize-mcp-json.d.ts +2 -0
- package/dist/utils/serialize-mcp-json.js +99 -0
- package/dist/utils/serialize-middleware-groups-meta.d.ts +12 -0
- package/dist/utils/serialize-middleware-groups-meta.js +28 -0
- package/dist/utils/serialize-openapi-json.d.ts +85 -0
- package/dist/utils/serialize-openapi-json.js +151 -0
- package/dist/utils/serialize-permissions-groups-meta.d.ts +6 -0
- package/dist/utils/serialize-permissions-groups-meta.js +31 -0
- package/dist/utils/validate-auth-sessionless.d.ts +3 -0
- package/dist/utils/validate-auth-sessionless.js +14 -0
- package/dist/utils/workflow/dsl/deserialize-dsl-workflow.js +34 -102
- package/dist/utils/workflow/dsl/extract-dsl-workflow.d.ts +1 -1
- package/dist/utils/workflow/dsl/extract-dsl-workflow.js +23 -4
- package/dist/utils/workflow/graph/convert-dsl-to-graph.js +12 -10
- package/dist/utils/workflow/graph/finalize-workflow-wires.d.ts +3 -0
- package/dist/utils/workflow/graph/finalize-workflow-wires.js +276 -0
- package/dist/utils/workflow/graph/finalize-workflows.d.ts +2 -0
- package/dist/utils/workflow/graph/finalize-workflows.js +75 -0
- package/dist/utils/workflow/graph/index.d.ts +2 -0
- package/dist/utils/workflow/graph/index.js +2 -0
- package/dist/utils/workflow/graph/serialize-workflow-graph.d.ts +0 -8
- package/dist/utils/workflow/graph/serialize-workflow-graph.js +1 -3
- package/dist/utils/workflow/graph/workflow-graph.types.d.ts +53 -79
- package/dist/utils/workflow/graph/workflow-graph.types.js +1 -1
- package/dist/visit.d.ts +1 -1
- package/dist/visit.js +13 -6
- package/package.json +14 -4
- package/src/add/add-ai-agent.ts +468 -0
- package/src/add/add-channel.ts +103 -79
- package/src/add/add-cli.ts +68 -24
- package/src/add/add-file-extends-core-type.ts +1 -1
- package/src/add/add-file-with-config.ts +1 -1
- package/src/add/add-file-with-factory.ts +3 -1
- package/src/add/add-functions.ts +349 -103
- package/src/add/add-http-route.ts +263 -89
- package/src/add/add-http-routes.ts +229 -0
- package/src/add/add-keyed-wiring.ts +151 -0
- package/src/add/add-mcp-prompt.ts +27 -16
- package/src/add/add-mcp-resource.ts +28 -16
- package/src/add/add-middleware.ts +482 -80
- package/src/add/add-permission.ts +199 -40
- package/src/add/add-queue-worker.ts +25 -20
- package/src/add/add-rpc-invocations.ts +28 -11
- package/src/add/add-schedule.ts +17 -12
- package/src/add/add-secret.ts +140 -0
- package/src/add/add-trigger.ts +154 -0
- package/src/add/add-variable.ts +9 -0
- package/src/add/add-wire-addon.ts +80 -0
- package/src/add/add-workflow-graph.ts +180 -522
- package/src/add/add-workflow.ts +7 -6
- package/src/error-codes.ts +25 -1
- package/src/index.ts +23 -13
- package/src/inspector.ts +139 -19
- package/src/schema-generator.ts +1 -0
- package/src/types-map.ts +12 -1
- package/src/types.ts +199 -69
- package/src/utils/compute-required-schemas.ts +48 -0
- package/src/utils/contract-hashes.test.ts +553 -0
- package/src/utils/contract-hashes.ts +386 -0
- package/src/utils/custom-types-generator.ts +88 -0
- package/src/utils/detect-schema-vendor.ts +90 -0
- package/src/utils/does-type-extend-core-type.ts +1 -1
- package/src/utils/ensure-function-metadata.ts +325 -8
- package/src/utils/extract-function-name.ts +101 -351
- package/src/utils/extract-services.ts +35 -2
- package/src/utils/filter-inspector-state.test.ts +37 -25
- package/src/utils/filter-inspector-state.ts +146 -32
- package/src/utils/filter-utils.test.ts +1 -1
- package/src/utils/filter-utils.ts +2 -2
- package/src/utils/get-files-and-methods.ts +1 -1
- package/src/utils/get-property-value.ts +42 -4
- package/src/utils/hash.ts +26 -0
- package/src/utils/middleware.test.ts +204 -0
- package/src/utils/middleware.ts +131 -69
- package/src/utils/permissions.test.ts +35 -12
- package/src/utils/permissions.ts +12 -12
- package/src/utils/post-process.ts +306 -44
- package/src/utils/resolve-addon-package.ts +49 -0
- package/src/utils/resolve-function-types.ts +42 -0
- package/src/utils/resolve-identifier.ts +46 -0
- package/src/utils/resolve-versions.test.ts +249 -0
- package/src/utils/resolve-versions.ts +105 -0
- package/src/utils/schema-generator.ts +329 -0
- package/src/utils/serialize-inspector-state.ts +184 -43
- package/src/utils/serialize-mcp-json.ts +145 -0
- package/src/utils/serialize-middleware-groups-meta.ts +33 -0
- package/src/utils/serialize-openapi-json.ts +277 -0
- package/src/utils/serialize-permissions-groups-meta.ts +35 -0
- package/src/utils/test-data/inspector-state.json +69 -66
- package/src/utils/validate-auth-sessionless.ts +29 -0
- package/src/utils/workflow/dsl/deserialize-dsl-workflow.ts +43 -119
- package/src/utils/workflow/dsl/extract-dsl-workflow.ts +26 -6
- package/src/utils/workflow/graph/convert-dsl-to-graph.ts +17 -10
- package/src/utils/workflow/graph/finalize-workflow-wires.ts +310 -0
- package/src/utils/workflow/graph/finalize-workflows.ts +100 -0
- package/src/utils/workflow/graph/index.ts +5 -0
- package/src/utils/workflow/graph/serialize-workflow-graph.ts +1 -8
- package/src/utils/workflow/graph/workflow-graph.types.ts +29 -78
- package/src/visit.ts +19 -7
- package/tsconfig.tsbuildinfo +1 -1
- package/dist/add/add-forge-credential.d.ts +0 -8
- package/dist/add/add-forge-credential.js +0 -77
- package/dist/add/add-forge-node.d.ts +0 -7
- package/dist/add/add-forge-node.js +0 -77
- package/dist/add/add-mcp-tool.d.ts +0 -2
- package/dist/add/add-mcp-tool.js +0 -81
- package/dist/utils/extract-service-metadata.d.ts +0 -19
- package/dist/utils/extract-service-metadata.js +0 -244
- package/dist/utils/write-service-metadata.d.ts +0 -13
- package/dist/utils/write-service-metadata.js +0 -37
- package/src/add/add-forge-credential.ts +0 -119
- package/src/add/add-forge-node.ts +0 -132
- package/src/add/add-mcp-tool.ts +0 -141
- package/src/utils/extract-service-metadata.ts +0 -353
- package/src/utils/write-service-metadata.ts +0 -51
package/src/add/add-functions.ts
CHANGED
|
@@ -1,16 +1,24 @@
|
|
|
1
1
|
import * as ts from 'typescript'
|
|
2
|
-
import { AddWiring } from '../types.js'
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
2
|
+
import type { AddWiring, SchemaRef } from '../types.js'
|
|
3
|
+
import { detectSchemaVendorOrError } from '../utils/detect-schema-vendor.js'
|
|
4
|
+
import type { TypesMap } from '../types-map.js'
|
|
5
|
+
import {
|
|
6
|
+
extractFunctionName,
|
|
7
|
+
funcIdToTypeName,
|
|
8
|
+
} from '../utils/extract-function-name.js'
|
|
5
9
|
import { extractFunctionNode } from '../utils/extract-function-node.js'
|
|
6
|
-
import {
|
|
10
|
+
import { extractUsedWires } from '../utils/extract-services.js'
|
|
11
|
+
import type { FunctionServicesMeta } from '@pikku/core'
|
|
12
|
+
import { formatVersionedId } from '@pikku/core'
|
|
7
13
|
import {
|
|
8
14
|
getPropertyValue,
|
|
9
15
|
getCommonWireMetaData,
|
|
10
16
|
} from '../utils/get-property-value.js'
|
|
11
17
|
import { resolveMiddleware } from '../utils/middleware.js'
|
|
12
18
|
import { resolvePermissions } from '../utils/permissions.js'
|
|
19
|
+
import { extractWireNames } from '../utils/post-process.js'
|
|
13
20
|
import { ErrorCode } from '../error-codes.js'
|
|
21
|
+
import type { NodeType } from '@pikku/core/node'
|
|
14
22
|
|
|
15
23
|
const isValidVariableName = (name: string) => {
|
|
16
24
|
const regex = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/
|
|
@@ -22,7 +30,8 @@ const nullifyTypes = (type: string | null) => {
|
|
|
22
30
|
type === 'void' ||
|
|
23
31
|
type === 'undefined' ||
|
|
24
32
|
type === 'unknown' ||
|
|
25
|
-
type === 'any'
|
|
33
|
+
type === 'any' ||
|
|
34
|
+
type === 'null'
|
|
26
35
|
) {
|
|
27
36
|
return null
|
|
28
37
|
}
|
|
@@ -186,8 +195,8 @@ const getNamesAndTypes = (
|
|
|
186
195
|
return { names: [], types: [] }
|
|
187
196
|
}
|
|
188
197
|
|
|
189
|
-
// 1) Handle an explicit void (or undefined) type up front
|
|
190
|
-
if (type.flags & ts.TypeFlags.VoidLike) {
|
|
198
|
+
// 1) Handle an explicit void (or undefined or null) type up front
|
|
199
|
+
if (type.flags & (ts.TypeFlags.VoidLike | ts.TypeFlags.Null)) {
|
|
191
200
|
return {
|
|
192
201
|
names: [],
|
|
193
202
|
types: [],
|
|
@@ -205,13 +214,12 @@ const getNamesAndTypes = (
|
|
|
205
214
|
const firstName = rawNames[0]
|
|
206
215
|
if (rawNames.length > 1 || (firstName && !isValidVariableName(firstName))) {
|
|
207
216
|
const aliasType = rawNames.join(' | ')
|
|
208
|
-
const aliasName =
|
|
209
|
-
funcName.charAt(0).toUpperCase() + funcName.slice(1) + direction
|
|
217
|
+
const aliasName = funcIdToTypeName(funcName) + direction
|
|
210
218
|
|
|
211
219
|
// record the alias in your TypesMap
|
|
212
|
-
const references = rawTypes
|
|
213
|
-
|
|
214
|
-
|
|
220
|
+
const references = rawTypes.flatMap((t) =>
|
|
221
|
+
resolveTypeImports(t, typesMap, true, checker)
|
|
222
|
+
)
|
|
215
223
|
|
|
216
224
|
typesMap.addCustomType(aliasName, aliasType, references)
|
|
217
225
|
|
|
@@ -222,19 +230,17 @@ const getNamesAndTypes = (
|
|
|
222
230
|
}
|
|
223
231
|
|
|
224
232
|
// 4) Single, valid name → inline it
|
|
225
|
-
const uniqueNames = rawNames
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
})
|
|
237
|
-
.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
|
+
})
|
|
238
244
|
|
|
239
245
|
return {
|
|
240
246
|
names: uniqueNames,
|
|
@@ -252,7 +258,6 @@ const isPrimitiveType = (type: ts.Type): boolean => {
|
|
|
252
258
|
ts.TypeFlags.Void |
|
|
253
259
|
ts.TypeFlags.Undefined |
|
|
254
260
|
ts.TypeFlags.Null |
|
|
255
|
-
ts.TypeFlags.Any |
|
|
256
261
|
ts.TypeFlags.Unknown |
|
|
257
262
|
ts.TypeFlags.VoidLike
|
|
258
263
|
|
|
@@ -286,7 +291,13 @@ function unwrapPromise(checker: ts.TypeChecker, type: ts.Type): ts.Type {
|
|
|
286
291
|
* Inspect pikkuFunc calls, extract input/output and first-arg destructuring,
|
|
287
292
|
* then push into state.functions.meta.
|
|
288
293
|
*/
|
|
289
|
-
export const addFunctions: AddWiring = (
|
|
294
|
+
export const addFunctions: AddWiring = (
|
|
295
|
+
logger,
|
|
296
|
+
node,
|
|
297
|
+
checker,
|
|
298
|
+
state,
|
|
299
|
+
options
|
|
300
|
+
) => {
|
|
290
301
|
if (!ts.isCallExpression(node)) return
|
|
291
302
|
|
|
292
303
|
const { expression, arguments: args, typeArguments } = node
|
|
@@ -309,8 +320,15 @@ export const addFunctions: AddWiring = (logger, node, checker, state) => {
|
|
|
309
320
|
|
|
310
321
|
if (args.length === 0) return
|
|
311
322
|
|
|
312
|
-
|
|
313
|
-
|
|
323
|
+
let { pikkuFuncId, name, explicitName, exportedName } = extractFunctionName(
|
|
324
|
+
node,
|
|
325
|
+
checker,
|
|
326
|
+
state.rootDir
|
|
327
|
+
)
|
|
328
|
+
|
|
329
|
+
if (!pikkuFuncId || pikkuFuncId.startsWith('__temp_')) {
|
|
330
|
+
return
|
|
331
|
+
}
|
|
314
332
|
|
|
315
333
|
let title: string | undefined
|
|
316
334
|
let tags: string[] | undefined
|
|
@@ -318,8 +336,16 @@ export const addFunctions: AddWiring = (logger, node, checker, state) => {
|
|
|
318
336
|
let description: string | undefined
|
|
319
337
|
let errors: string[] | undefined
|
|
320
338
|
let expose: boolean | undefined
|
|
321
|
-
let
|
|
339
|
+
let remote: boolean | undefined
|
|
340
|
+
let mcp: boolean | undefined
|
|
341
|
+
let readonly_: boolean | undefined
|
|
342
|
+
let requiresApproval: boolean | undefined
|
|
343
|
+
let version: number | undefined
|
|
322
344
|
let objectNode: ts.ObjectLiteralExpression | undefined
|
|
345
|
+
let nodeDisplayName: string | null = null
|
|
346
|
+
let nodeCategory: string | null = null
|
|
347
|
+
let nodeType: NodeType | null = null
|
|
348
|
+
let nodeErrorOutput: boolean | null = null
|
|
323
349
|
|
|
324
350
|
// Extract the function node using shared utility
|
|
325
351
|
const firstArg = args[0]!
|
|
@@ -329,22 +355,24 @@ export const addFunctions: AddWiring = (logger, node, checker, state) => {
|
|
|
329
355
|
isDirectFunction,
|
|
330
356
|
} = extractFunctionNode(firstArg, checker)
|
|
331
357
|
|
|
332
|
-
// Variables to hold
|
|
333
|
-
let
|
|
334
|
-
|
|
335
|
-
let outputZodSchemaRef: { variableName: string; sourceFile: string } | null =
|
|
336
|
-
null
|
|
358
|
+
// Variables to hold schema references if provided
|
|
359
|
+
let inputSchemaRef: SchemaRef | null = null
|
|
360
|
+
let outputSchemaRef: SchemaRef | null = null
|
|
337
361
|
|
|
338
|
-
// Helper to resolve schema identifier to its actual source file
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
362
|
+
// Helper to resolve schema identifier to its actual source file and detect vendor.
|
|
363
|
+
// Logs a fatal error and returns null if vendor cannot be determined.
|
|
364
|
+
const resolveSchemaRef = (
|
|
365
|
+
identifier: ts.Identifier,
|
|
366
|
+
context: string
|
|
367
|
+
): SchemaRef | null => {
|
|
342
368
|
const symbol = checker.getSymbolAtLocation(identifier)
|
|
343
369
|
if (!symbol) return null
|
|
344
370
|
|
|
345
371
|
const decl = symbol.valueDeclaration || symbol.declarations?.[0]
|
|
346
372
|
if (!decl) return null
|
|
347
373
|
|
|
374
|
+
let sourceFile: string
|
|
375
|
+
|
|
348
376
|
// If it's an import specifier, resolve the aliased symbol to get the actual source
|
|
349
377
|
if (ts.isImportSpecifier(decl)) {
|
|
350
378
|
const aliasedSymbol = checker.getAliasedSymbol(symbol)
|
|
@@ -352,18 +380,30 @@ export const addFunctions: AddWiring = (logger, node, checker, state) => {
|
|
|
352
380
|
const aliasedDecl =
|
|
353
381
|
aliasedSymbol.valueDeclaration || aliasedSymbol.declarations?.[0]
|
|
354
382
|
if (aliasedDecl) {
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
}
|
|
383
|
+
sourceFile = aliasedDecl.getSourceFile().fileName
|
|
384
|
+
} else {
|
|
385
|
+
return null
|
|
359
386
|
}
|
|
387
|
+
} else {
|
|
388
|
+
return null
|
|
360
389
|
}
|
|
390
|
+
} else {
|
|
391
|
+
sourceFile = decl.getSourceFile().fileName
|
|
361
392
|
}
|
|
362
393
|
|
|
363
|
-
|
|
394
|
+
const vendor = detectSchemaVendorOrError(
|
|
395
|
+
identifier,
|
|
396
|
+
checker,
|
|
397
|
+
logger,
|
|
398
|
+
context,
|
|
399
|
+
sourceFile
|
|
400
|
+
)
|
|
401
|
+
if (!vendor) return null
|
|
402
|
+
|
|
364
403
|
return {
|
|
365
404
|
variableName: identifier.text,
|
|
366
|
-
sourceFile
|
|
405
|
+
sourceFile,
|
|
406
|
+
vendor,
|
|
367
407
|
}
|
|
368
408
|
}
|
|
369
409
|
|
|
@@ -371,35 +411,95 @@ export const addFunctions: AddWiring = (logger, node, checker, state) => {
|
|
|
371
411
|
if (ts.isObjectLiteralExpression(firstArg)) {
|
|
372
412
|
objectNode = firstArg
|
|
373
413
|
const metadata = getCommonWireMetaData(firstArg, 'Function', name, logger)
|
|
414
|
+
if (metadata.disabled) return
|
|
374
415
|
title = metadata.title
|
|
375
416
|
tags = metadata.tags
|
|
376
417
|
summary = metadata.summary
|
|
377
418
|
description = metadata.description
|
|
378
419
|
errors = metadata.errors
|
|
379
420
|
expose = getPropertyValue(firstArg, 'expose') as boolean | undefined
|
|
380
|
-
|
|
421
|
+
remote = getPropertyValue(firstArg, 'remote') as boolean | undefined
|
|
422
|
+
mcp = getPropertyValue(firstArg, 'mcp') as boolean | undefined
|
|
423
|
+
readonly_ = getPropertyValue(firstArg, 'readonly') as boolean | undefined
|
|
424
|
+
requiresApproval = getPropertyValue(firstArg, 'requiresApproval') as
|
|
425
|
+
| boolean
|
|
426
|
+
| undefined
|
|
427
|
+
|
|
428
|
+
const versionRaw = getPropertyValue(firstArg, 'version')
|
|
429
|
+
if (versionRaw !== null && versionRaw !== undefined) {
|
|
430
|
+
const parsed = Number(versionRaw)
|
|
431
|
+
if (Number.isInteger(parsed) && parsed >= 1) {
|
|
432
|
+
version = parsed
|
|
433
|
+
}
|
|
434
|
+
}
|
|
381
435
|
|
|
382
|
-
// Extract
|
|
436
|
+
// Extract node config from nested object
|
|
437
|
+
for (const prop of firstArg.properties) {
|
|
438
|
+
if (
|
|
439
|
+
ts.isPropertyAssignment(prop) &&
|
|
440
|
+
ts.isIdentifier(prop.name) &&
|
|
441
|
+
prop.name.text === 'node' &&
|
|
442
|
+
ts.isObjectLiteralExpression(prop.initializer)
|
|
443
|
+
) {
|
|
444
|
+
const nodeObj = prop.initializer
|
|
445
|
+
nodeDisplayName = getPropertyValue(nodeObj, 'displayName') as
|
|
446
|
+
| string
|
|
447
|
+
| null
|
|
448
|
+
nodeCategory = getPropertyValue(nodeObj, 'category') as string | null
|
|
449
|
+
nodeType = getPropertyValue(nodeObj, 'type') as NodeType | null
|
|
450
|
+
nodeErrorOutput = getPropertyValue(nodeObj, 'errorOutput') as
|
|
451
|
+
| boolean
|
|
452
|
+
| null
|
|
453
|
+
|
|
454
|
+
if (!nodeDisplayName) {
|
|
455
|
+
logger.critical(
|
|
456
|
+
ErrorCode.MISSING_NAME,
|
|
457
|
+
`Function '${name}' node config is missing the required 'displayName' property.`
|
|
458
|
+
)
|
|
459
|
+
}
|
|
460
|
+
if (!nodeCategory) {
|
|
461
|
+
logger.critical(
|
|
462
|
+
ErrorCode.MISSING_NAME,
|
|
463
|
+
`Function '${name}' node config is missing the required 'category' property.`
|
|
464
|
+
)
|
|
465
|
+
}
|
|
466
|
+
if (!nodeType) {
|
|
467
|
+
logger.critical(
|
|
468
|
+
ErrorCode.MISSING_NAME,
|
|
469
|
+
`Function '${name}' node config is missing the required 'type' property.`
|
|
470
|
+
)
|
|
471
|
+
} else if (!['trigger', 'action', 'end'].includes(nodeType)) {
|
|
472
|
+
logger.critical(
|
|
473
|
+
ErrorCode.INVALID_VALUE,
|
|
474
|
+
`Function '${name}' node config has invalid type '${nodeType}'. Must be 'trigger', 'action', or 'end'.`
|
|
475
|
+
)
|
|
476
|
+
}
|
|
477
|
+
break
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
// Extract schema variable names from input/output properties
|
|
383
482
|
for (const prop of firstArg.properties) {
|
|
384
483
|
if (ts.isPropertyAssignment(prop) && ts.isIdentifier(prop.name)) {
|
|
385
484
|
const propName = prop.name.text
|
|
386
485
|
if (propName === 'input' || propName === 'output') {
|
|
387
486
|
if (ts.isIdentifier(prop.initializer)) {
|
|
388
|
-
// Good - it's a variable reference, resolve its actual source file
|
|
389
|
-
const
|
|
487
|
+
// Good - it's a variable reference, resolve its actual source file and vendor
|
|
488
|
+
const context = `Function '${name}' ${propName}`
|
|
489
|
+
const ref = resolveSchemaRef(prop.initializer, context)
|
|
390
490
|
if (ref) {
|
|
391
491
|
if (propName === 'input') {
|
|
392
|
-
|
|
492
|
+
inputSchemaRef = ref
|
|
393
493
|
} else {
|
|
394
|
-
|
|
494
|
+
outputSchemaRef = ref
|
|
395
495
|
}
|
|
396
496
|
}
|
|
397
497
|
} else if (ts.isCallExpression(prop.initializer)) {
|
|
398
498
|
// Bad - it's an inline expression
|
|
399
|
-
const schemaName = `${
|
|
499
|
+
const schemaName = `${funcIdToTypeName(name)}${propName.charAt(0).toUpperCase() + propName.slice(1)}`
|
|
400
500
|
logger.critical(
|
|
401
|
-
ErrorCode.
|
|
402
|
-
`Inline
|
|
501
|
+
ErrorCode.INLINE_SCHEMA,
|
|
502
|
+
`Inline schemas are not supported for '${propName}' in '${name}'.\n` +
|
|
403
503
|
` Extract to an exported variable:\n` +
|
|
404
504
|
` export const ${schemaName} = ${prop.initializer.getText()}\n` +
|
|
405
505
|
` Then use: ${propName}: ${schemaName}`
|
|
@@ -410,6 +510,14 @@ export const addFunctions: AddWiring = (logger, node, checker, state) => {
|
|
|
410
510
|
}
|
|
411
511
|
}
|
|
412
512
|
|
|
513
|
+
if (version !== undefined) {
|
|
514
|
+
const baseName = explicitName || exportedName || pikkuFuncId
|
|
515
|
+
pikkuFuncId = formatVersionedId(baseName, version)
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
const isMCPToolFunc = expression.text === 'pikkuMCPToolFunc'
|
|
519
|
+
const mcpEnabled = mcp || isMCPToolFunc
|
|
520
|
+
|
|
413
521
|
// Pick the handler: use resolvedFunc when it exists and is a function, otherwise fall back to handlerNode
|
|
414
522
|
const handler =
|
|
415
523
|
resolvedFunc &&
|
|
@@ -419,10 +527,11 @@ export const addFunctions: AddWiring = (logger, node, checker, state) => {
|
|
|
419
527
|
|
|
420
528
|
// Validate that we got a valid function
|
|
421
529
|
if (!ts.isArrowFunction(handler) && !ts.isFunctionExpression(handler)) {
|
|
422
|
-
logger.error(`• No valid 'func' property found for ${
|
|
530
|
+
logger.error(`• No valid 'func' property found for ${pikkuFuncId}.`)
|
|
423
531
|
// Create stub metadata to prevent "function not found" errors in wirings
|
|
424
|
-
state.functions.meta[
|
|
425
|
-
|
|
532
|
+
state.functions.meta[pikkuFuncId] = {
|
|
533
|
+
pikkuFuncId,
|
|
534
|
+
functionType: 'user',
|
|
426
535
|
name,
|
|
427
536
|
services: { optimized: false, services: [] },
|
|
428
537
|
inputSchemaName: null,
|
|
@@ -453,43 +562,31 @@ export const addFunctions: AddWiring = (logger, node, checker, state) => {
|
|
|
453
562
|
services.services.push(original)
|
|
454
563
|
}
|
|
455
564
|
}
|
|
456
|
-
} else if (
|
|
565
|
+
} else if (
|
|
566
|
+
ts.isIdentifier(firstParam.name) &&
|
|
567
|
+
!firstParam.name.text.startsWith('_')
|
|
568
|
+
) {
|
|
457
569
|
services.optimized = false
|
|
458
570
|
}
|
|
459
571
|
}
|
|
460
572
|
|
|
461
|
-
|
|
462
|
-
const usedWires: string[] = []
|
|
463
|
-
const thirdParam = handler.parameters[2]
|
|
464
|
-
if (thirdParam && ts.isObjectBindingPattern(thirdParam.name)) {
|
|
465
|
-
for (const elem of thirdParam.name.elements) {
|
|
466
|
-
const propertyName =
|
|
467
|
-
elem.propertyName && ts.isIdentifier(elem.propertyName)
|
|
468
|
-
? elem.propertyName.text
|
|
469
|
-
: ts.isIdentifier(elem.name)
|
|
470
|
-
? elem.name.text
|
|
471
|
-
: undefined
|
|
472
|
-
if (propertyName) {
|
|
473
|
-
usedWires.push(propertyName)
|
|
474
|
-
}
|
|
475
|
-
}
|
|
476
|
-
}
|
|
573
|
+
const wires = extractUsedWires(handler, 2)
|
|
477
574
|
|
|
478
575
|
// --- Generics → ts.Type[], unwrapped from Promise ---
|
|
479
576
|
const genericTypes: ts.Type[] = (typeArguments ?? [])
|
|
480
577
|
.map((tn) => checker.getTypeFromTypeNode(tn))
|
|
481
578
|
.map((t) => unwrapPromise(checker, t))
|
|
482
579
|
|
|
483
|
-
const capitalizedName =
|
|
580
|
+
const capitalizedName = funcIdToTypeName(name)
|
|
484
581
|
|
|
485
582
|
// --- Input Extraction ---
|
|
486
583
|
let inputNames: string[] = []
|
|
487
584
|
let inputTypes: ts.Type[] = []
|
|
488
585
|
|
|
489
|
-
if (
|
|
586
|
+
if (inputSchemaRef) {
|
|
490
587
|
const schemaName = `${capitalizedName}Input`
|
|
491
588
|
inputNames = [schemaName]
|
|
492
|
-
state.
|
|
589
|
+
state.schemaLookup.set(schemaName, inputSchemaRef)
|
|
493
590
|
state.functions.typesMap.addCustomType(schemaName, 'unknown', [])
|
|
494
591
|
} else if (genericTypes.length >= 1 && genericTypes[0]) {
|
|
495
592
|
// Fall back to extracting from generic type arguments
|
|
@@ -511,7 +608,7 @@ export const addFunctions: AddWiring = (logger, node, checker, state) => {
|
|
|
511
608
|
checker,
|
|
512
609
|
state.functions.typesMap,
|
|
513
610
|
'Input',
|
|
514
|
-
|
|
611
|
+
pikkuFuncId,
|
|
515
612
|
paramType
|
|
516
613
|
)
|
|
517
614
|
inputNames = result.names
|
|
@@ -522,10 +619,10 @@ export const addFunctions: AddWiring = (logger, node, checker, state) => {
|
|
|
522
619
|
// --- Output Extraction ---
|
|
523
620
|
let outputNames: string[] = []
|
|
524
621
|
|
|
525
|
-
if (
|
|
622
|
+
if (outputSchemaRef) {
|
|
526
623
|
const schemaName = `${capitalizedName}Output`
|
|
527
624
|
outputNames = [schemaName]
|
|
528
|
-
state.
|
|
625
|
+
state.schemaLookup.set(schemaName, outputSchemaRef)
|
|
529
626
|
state.functions.typesMap.addCustomType(schemaName, 'unknown', [])
|
|
530
627
|
} else if (genericTypes.length >= 2) {
|
|
531
628
|
outputNames = getNamesAndTypes(
|
|
@@ -544,12 +641,55 @@ export const addFunctions: AddWiring = (logger, node, checker, state) => {
|
|
|
544
641
|
checker,
|
|
545
642
|
state.functions.typesMap,
|
|
546
643
|
'Output',
|
|
547
|
-
|
|
644
|
+
pikkuFuncId,
|
|
548
645
|
unwrapped
|
|
549
646
|
).names
|
|
550
647
|
}
|
|
551
648
|
}
|
|
552
649
|
|
|
650
|
+
const mcpOutputTypes: Record<string, string> = {
|
|
651
|
+
pikkuMCPResourceFunc: 'MCPResourceResponse',
|
|
652
|
+
pikkuMCPToolFunc: 'MCPToolResponse',
|
|
653
|
+
pikkuMCPPromptFunc: 'MCPPromptResponse',
|
|
654
|
+
}
|
|
655
|
+
const mcpOutputType = mcpOutputTypes[expression.text]
|
|
656
|
+
if (mcpOutputType && outputNames[0] !== mcpOutputType) {
|
|
657
|
+
let resolved = false
|
|
658
|
+
const rawSymbol = checker.getSymbolAtLocation(expression)
|
|
659
|
+
const funcSymbol =
|
|
660
|
+
rawSymbol && rawSymbol.flags & ts.SymbolFlags.Alias
|
|
661
|
+
? checker.getAliasedSymbol(rawSymbol)
|
|
662
|
+
: rawSymbol
|
|
663
|
+
const funcDecls = funcSymbol?.getDeclarations() || []
|
|
664
|
+
for (const funcDecl of funcDecls) {
|
|
665
|
+
if (resolved) break
|
|
666
|
+
const mcpTypeSymbol = checker.resolveName(
|
|
667
|
+
mcpOutputType,
|
|
668
|
+
funcDecl,
|
|
669
|
+
ts.SymbolFlags.Type,
|
|
670
|
+
false
|
|
671
|
+
)
|
|
672
|
+
if (mcpTypeSymbol) {
|
|
673
|
+
const aliased =
|
|
674
|
+
mcpTypeSymbol.flags & ts.SymbolFlags.Alias
|
|
675
|
+
? checker.getAliasedSymbol(mcpTypeSymbol)
|
|
676
|
+
: mcpTypeSymbol
|
|
677
|
+
const typeDecl = aliased?.getDeclarations()?.[0]
|
|
678
|
+
if (typeDecl) {
|
|
679
|
+
const path = typeDecl.getSourceFile().fileName
|
|
680
|
+
if (!state.functions.typesMap.exists(mcpOutputType, path)) {
|
|
681
|
+
state.functions.typesMap.addType(mcpOutputType, path)
|
|
682
|
+
}
|
|
683
|
+
resolved = true
|
|
684
|
+
}
|
|
685
|
+
}
|
|
686
|
+
}
|
|
687
|
+
if (!resolved) {
|
|
688
|
+
state.functions.typesMap.addCustomType(mcpOutputType, mcpOutputType, [])
|
|
689
|
+
}
|
|
690
|
+
outputNames = [mcpOutputType]
|
|
691
|
+
}
|
|
692
|
+
|
|
553
693
|
if (inputNames.length > 1) {
|
|
554
694
|
logger.warn(
|
|
555
695
|
'More than one input type detected, only the first one will be used as a schema.'
|
|
@@ -558,30 +698,69 @@ export const addFunctions: AddWiring = (logger, node, checker, state) => {
|
|
|
558
698
|
|
|
559
699
|
// Store the input type for later use
|
|
560
700
|
if (inputTypes.length > 0) {
|
|
561
|
-
state.typesLookup.set(
|
|
701
|
+
state.typesLookup.set(pikkuFuncId, inputTypes)
|
|
562
702
|
}
|
|
563
703
|
|
|
564
704
|
// --- resolve middleware ---
|
|
565
|
-
|
|
705
|
+
let middleware = objectNode
|
|
566
706
|
? resolveMiddleware(state, objectNode, tags, checker)
|
|
567
707
|
: undefined
|
|
568
708
|
|
|
569
709
|
// --- resolve permissions ---
|
|
570
|
-
|
|
710
|
+
let permissions = objectNode
|
|
571
711
|
? resolvePermissions(state, objectNode, tags, checker)
|
|
572
712
|
: undefined
|
|
573
713
|
|
|
574
|
-
|
|
575
|
-
|
|
714
|
+
if (options.tags?.length) {
|
|
715
|
+
tags = [...new Set([...(tags || []), ...options.tags])]
|
|
716
|
+
const tagEntries = options.tags.map((tag) => ({
|
|
717
|
+
type: 'tag' as const,
|
|
718
|
+
tag,
|
|
719
|
+
}))
|
|
720
|
+
const existingMiddlewareTags = new Set(
|
|
721
|
+
(middleware || [])
|
|
722
|
+
.filter((m) => m.type === 'tag')
|
|
723
|
+
.map((m) => (m as any).tag)
|
|
724
|
+
)
|
|
725
|
+
const newMiddleware = tagEntries.filter(
|
|
726
|
+
(e) => !existingMiddlewareTags.has(e.tag)
|
|
727
|
+
)
|
|
728
|
+
if (newMiddleware.length > 0) {
|
|
729
|
+
middleware = [...(middleware || []), ...newMiddleware]
|
|
730
|
+
}
|
|
731
|
+
const existingPermissionTags = new Set(
|
|
732
|
+
(permissions || [])
|
|
733
|
+
.filter((p) => p.type === 'tag')
|
|
734
|
+
.map((p) => (p as any).tag)
|
|
735
|
+
)
|
|
736
|
+
const newPermissions = tagEntries.filter(
|
|
737
|
+
(e) => !existingPermissionTags.has(e.tag)
|
|
738
|
+
)
|
|
739
|
+
if (newPermissions.length > 0) {
|
|
740
|
+
permissions = [...(permissions || []), ...newPermissions]
|
|
741
|
+
}
|
|
742
|
+
}
|
|
743
|
+
|
|
744
|
+
const sessionless = expression.text !== 'pikkuFunc'
|
|
745
|
+
|
|
746
|
+
state.functions.meta[pikkuFuncId] = {
|
|
747
|
+
pikkuFuncId,
|
|
748
|
+
functionType: 'user',
|
|
749
|
+
funcWrapper: expression.text,
|
|
750
|
+
sessionless,
|
|
576
751
|
name,
|
|
577
752
|
services,
|
|
578
|
-
|
|
753
|
+
wires: wires.wires.length > 0 || !wires.optimized ? wires : undefined,
|
|
579
754
|
inputSchemaName: inputNames[0] ?? null,
|
|
580
755
|
outputSchemaName: outputNames[0] ?? null,
|
|
581
756
|
inputs: inputNames.filter((n) => n !== 'void') ?? null,
|
|
582
757
|
outputs: outputNames.filter((n) => n !== 'void') ?? null,
|
|
583
758
|
expose: expose || undefined,
|
|
584
|
-
|
|
759
|
+
remote: remote || undefined,
|
|
760
|
+
mcp: mcpEnabled || undefined,
|
|
761
|
+
readonly: readonly_ || undefined,
|
|
762
|
+
requiresApproval: requiresApproval || undefined,
|
|
763
|
+
version,
|
|
585
764
|
title,
|
|
586
765
|
tags: tags || undefined,
|
|
587
766
|
summary,
|
|
@@ -592,20 +771,78 @@ export const addFunctions: AddWiring = (logger, node, checker, state) => {
|
|
|
592
771
|
isDirectFunction,
|
|
593
772
|
}
|
|
594
773
|
|
|
595
|
-
//
|
|
596
|
-
if (
|
|
597
|
-
state.
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
774
|
+
// Populate node metadata if node config is present
|
|
775
|
+
if (nodeDisplayName && nodeCategory && nodeType) {
|
|
776
|
+
state.nodes.files.add(node.getSourceFile().fileName)
|
|
777
|
+
state.nodes.meta[pikkuFuncId] = {
|
|
778
|
+
name: pikkuFuncId,
|
|
779
|
+
displayName: nodeDisplayName,
|
|
780
|
+
category: nodeCategory,
|
|
781
|
+
type: nodeType,
|
|
782
|
+
rpc: pikkuFuncId,
|
|
783
|
+
description,
|
|
784
|
+
errorOutput: nodeErrorOutput ?? false,
|
|
785
|
+
inputSchemaName: inputNames[0] ?? null,
|
|
786
|
+
outputSchemaName: outputNames[0] ?? null,
|
|
787
|
+
tags,
|
|
788
|
+
}
|
|
789
|
+
}
|
|
790
|
+
|
|
791
|
+
if (mcpEnabled) {
|
|
792
|
+
if (!description) {
|
|
793
|
+
logger.critical(
|
|
794
|
+
ErrorCode.MISSING_DESCRIPTION,
|
|
795
|
+
`MCP tool '${name}' is missing a description.`
|
|
796
|
+
)
|
|
797
|
+
return
|
|
798
|
+
}
|
|
799
|
+
state.mcpEndpoints.files.add(node.getSourceFile().fileName)
|
|
800
|
+
state.mcpEndpoints.toolsMeta[name] = {
|
|
801
|
+
pikkuFuncId,
|
|
802
|
+
name,
|
|
803
|
+
title: title || undefined,
|
|
804
|
+
description,
|
|
805
|
+
summary,
|
|
806
|
+
errors,
|
|
807
|
+
tags,
|
|
808
|
+
inputSchema: inputNames[0] ?? null,
|
|
809
|
+
outputSchema: outputNames[0] ?? null,
|
|
810
|
+
middleware,
|
|
811
|
+
permissions,
|
|
812
|
+
}
|
|
813
|
+
state.serviceAggregation.usedFunctions.add(pikkuFuncId)
|
|
814
|
+
extractWireNames(middleware).forEach((n) =>
|
|
815
|
+
state.serviceAggregation.usedMiddleware.add(n)
|
|
816
|
+
)
|
|
817
|
+
extractWireNames(permissions).forEach((n) =>
|
|
818
|
+
state.serviceAggregation.usedPermissions.add(n)
|
|
819
|
+
)
|
|
601
820
|
}
|
|
602
821
|
|
|
603
822
|
// Workflow functions don't get registered as RPC functions,
|
|
604
|
-
// they are their own type handled by add-
|
|
823
|
+
// they are their own type handled by add-workflow
|
|
605
824
|
if (expression.text.includes('Workflow')) {
|
|
606
825
|
return
|
|
607
826
|
}
|
|
608
827
|
|
|
828
|
+
// Trigger and channel connect/disconnect functions are not callable via RPC
|
|
829
|
+
const nonRPCPatterns = [
|
|
830
|
+
/Trigger/i,
|
|
831
|
+
/ChannelConnection/i,
|
|
832
|
+
/ChannelDisconnection/i,
|
|
833
|
+
]
|
|
834
|
+
if (nonRPCPatterns.some((pattern) => pattern.test(expression.text))) {
|
|
835
|
+
return
|
|
836
|
+
}
|
|
837
|
+
|
|
838
|
+
// Store function file location for wiring generation
|
|
839
|
+
if (exportedName) {
|
|
840
|
+
state.functions.files.set(pikkuFuncId, {
|
|
841
|
+
path: node.getSourceFile().fileName,
|
|
842
|
+
exportedName,
|
|
843
|
+
})
|
|
844
|
+
}
|
|
845
|
+
|
|
609
846
|
if (exportedName || explicitName) {
|
|
610
847
|
if (!exportedName) {
|
|
611
848
|
logger.error(
|
|
@@ -614,28 +851,37 @@ export const addFunctions: AddWiring = (logger, node, checker, state) => {
|
|
|
614
851
|
return
|
|
615
852
|
}
|
|
616
853
|
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
state.rpc.invokedFunctions.add(pikkuFuncName)
|
|
854
|
+
if (remote) {
|
|
855
|
+
state.rpc.invokedFunctions.add(pikkuFuncId)
|
|
620
856
|
}
|
|
621
857
|
|
|
622
858
|
if (expose) {
|
|
623
|
-
state.rpc.exposedMeta[name] =
|
|
859
|
+
state.rpc.exposedMeta[name] = pikkuFuncId
|
|
624
860
|
state.rpc.exposedFiles.set(name, {
|
|
625
861
|
path: node.getSourceFile().fileName,
|
|
626
862
|
exportedName,
|
|
627
863
|
})
|
|
628
864
|
// Track exposed RPC function for service aggregation
|
|
629
|
-
state.serviceAggregation.usedFunctions.add(
|
|
865
|
+
state.serviceAggregation.usedFunctions.add(pikkuFuncId)
|
|
630
866
|
}
|
|
631
867
|
|
|
632
868
|
// We add it to internal meta to allow autocomplete for everything
|
|
633
|
-
state.rpc.internalMeta[name] =
|
|
869
|
+
state.rpc.internalMeta[name] = pikkuFuncId
|
|
870
|
+
|
|
871
|
+
if (version !== undefined) {
|
|
872
|
+
state.rpc.internalMeta[pikkuFuncId] = pikkuFuncId
|
|
873
|
+
state.rpc.invokedFunctions.add(pikkuFuncId)
|
|
874
|
+
}
|
|
634
875
|
|
|
635
876
|
// But we only import the actual function if it's actually invoked to keep
|
|
636
877
|
// bundle size down
|
|
637
|
-
if (
|
|
638
|
-
state.rpc.
|
|
878
|
+
if (
|
|
879
|
+
state.rpc.invokedFunctions.has(pikkuFuncId) ||
|
|
880
|
+
expose ||
|
|
881
|
+
remote ||
|
|
882
|
+
mcpEnabled
|
|
883
|
+
) {
|
|
884
|
+
state.rpc.internalFiles.set(pikkuFuncId, {
|
|
639
885
|
path: node.getSourceFile().fileName,
|
|
640
886
|
exportedName,
|
|
641
887
|
})
|