@pikku/inspector 0.11.2 → 0.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (182) hide show
  1. package/CHANGELOG.md +11 -1
  2. package/OPTIMIZATION-PLAN.md +195 -0
  3. package/dist/add/add-ai-agent.d.ts +2 -0
  4. package/dist/add/add-ai-agent.js +314 -0
  5. package/dist/add/add-channel.js +69 -61
  6. package/dist/add/add-cli.js +36 -18
  7. package/dist/add/add-file-with-factory.js +2 -0
  8. package/dist/add/add-functions.js +250 -75
  9. package/dist/add/add-http-route.d.ts +19 -10
  10. package/dist/add/add-http-route.js +152 -66
  11. package/dist/add/add-http-routes.d.ts +5 -0
  12. package/dist/add/add-http-routes.js +159 -0
  13. package/dist/add/add-keyed-wiring.d.ts +12 -0
  14. package/dist/add/add-keyed-wiring.js +97 -0
  15. package/dist/add/add-mcp-prompt.js +14 -9
  16. package/dist/add/add-mcp-resource.js +14 -9
  17. package/dist/add/add-middleware.d.ts +1 -4
  18. package/dist/add/add-middleware.js +364 -79
  19. package/dist/add/add-permission.d.ts +1 -1
  20. package/dist/add/add-permission.js +152 -40
  21. package/dist/add/add-queue-worker.js +18 -12
  22. package/dist/add/add-rpc-invocations.js +14 -0
  23. package/dist/add/add-schedule.js +11 -5
  24. package/dist/add/add-secret.d.ts +3 -0
  25. package/dist/add/add-secret.js +82 -0
  26. package/dist/add/add-trigger.d.ts +2 -0
  27. package/dist/add/add-trigger.js +87 -0
  28. package/dist/add/add-variable.d.ts +1 -0
  29. package/dist/add/add-variable.js +8 -0
  30. package/dist/add/add-workflow-graph.d.ts +3 -2
  31. package/dist/add/add-workflow-graph.js +143 -406
  32. package/dist/add/add-workflow.js +6 -4
  33. package/dist/error-codes.d.ts +14 -1
  34. package/dist/error-codes.js +19 -1
  35. package/dist/index.d.ts +9 -8
  36. package/dist/index.js +5 -4
  37. package/dist/inspector.d.ts +1 -1
  38. package/dist/inspector.js +91 -14
  39. package/dist/schema-generator.d.ts +1 -0
  40. package/dist/schema-generator.js +1 -0
  41. package/dist/types-map.js +10 -1
  42. package/dist/types.d.ts +163 -39
  43. package/dist/utils/compute-required-schemas.d.ts +4 -0
  44. package/dist/utils/compute-required-schemas.js +41 -0
  45. package/dist/utils/contract-hashes.d.ts +35 -0
  46. package/dist/utils/contract-hashes.js +202 -0
  47. package/dist/utils/custom-types-generator.d.ts +9 -0
  48. package/dist/utils/custom-types-generator.js +71 -0
  49. package/dist/utils/detect-schema-vendor.d.ts +22 -0
  50. package/dist/utils/detect-schema-vendor.js +76 -0
  51. package/dist/utils/ensure-function-metadata.d.ts +5 -2
  52. package/dist/utils/ensure-function-metadata.js +220 -6
  53. package/dist/utils/extract-function-name.d.ts +5 -16
  54. package/dist/utils/extract-function-name.js +86 -291
  55. package/dist/utils/extract-services.d.ts +2 -1
  56. package/dist/utils/extract-services.js +25 -1
  57. package/dist/utils/filter-inspector-state.js +107 -23
  58. package/dist/utils/get-property-value.d.ts +6 -1
  59. package/dist/utils/get-property-value.js +28 -3
  60. package/dist/utils/hash.d.ts +2 -0
  61. package/dist/utils/hash.js +23 -0
  62. package/dist/utils/middleware.d.ts +7 -30
  63. package/dist/utils/middleware.js +80 -66
  64. package/dist/utils/permissions.d.ts +2 -2
  65. package/dist/utils/permissions.js +10 -10
  66. package/dist/utils/post-process.d.ts +9 -10
  67. package/dist/utils/post-process.js +231 -24
  68. package/dist/utils/resolve-external-package.d.ts +12 -0
  69. package/dist/utils/resolve-external-package.js +34 -0
  70. package/dist/utils/resolve-function-types.d.ts +6 -0
  71. package/dist/utils/resolve-function-types.js +29 -0
  72. package/dist/utils/resolve-identifier.d.ts +10 -0
  73. package/dist/utils/resolve-identifier.js +36 -0
  74. package/dist/utils/resolve-versions.d.ts +2 -0
  75. package/dist/utils/resolve-versions.js +78 -0
  76. package/dist/utils/schema-generator.d.ts +9 -0
  77. package/dist/utils/schema-generator.js +209 -0
  78. package/dist/utils/serialize-inspector-state.d.ts +59 -22
  79. package/dist/utils/serialize-inspector-state.js +92 -20
  80. package/dist/utils/serialize-mcp-json.d.ts +2 -0
  81. package/dist/utils/serialize-mcp-json.js +99 -0
  82. package/dist/utils/serialize-middleware-groups-meta.d.ts +12 -0
  83. package/dist/utils/serialize-middleware-groups-meta.js +28 -0
  84. package/dist/utils/serialize-openapi-json.d.ts +85 -0
  85. package/dist/utils/serialize-openapi-json.js +151 -0
  86. package/dist/utils/serialize-permissions-groups-meta.d.ts +6 -0
  87. package/dist/utils/serialize-permissions-groups-meta.js +31 -0
  88. package/dist/utils/workflow/dsl/deserialize-dsl-workflow.js +34 -102
  89. package/dist/utils/workflow/dsl/extract-dsl-workflow.js +23 -4
  90. package/dist/utils/workflow/graph/convert-dsl-to-graph.js +12 -10
  91. package/dist/utils/workflow/graph/finalize-workflow-wires.d.ts +3 -0
  92. package/dist/utils/workflow/graph/finalize-workflow-wires.js +276 -0
  93. package/dist/utils/workflow/graph/finalize-workflows.d.ts +2 -0
  94. package/dist/utils/workflow/graph/finalize-workflows.js +75 -0
  95. package/dist/utils/workflow/graph/index.d.ts +2 -0
  96. package/dist/utils/workflow/graph/index.js +2 -0
  97. package/dist/utils/workflow/graph/serialize-workflow-graph.d.ts +0 -8
  98. package/dist/utils/workflow/graph/serialize-workflow-graph.js +1 -3
  99. package/dist/utils/workflow/graph/workflow-graph.types.d.ts +53 -79
  100. package/dist/utils/workflow/graph/workflow-graph.types.js +1 -1
  101. package/dist/visit.js +11 -6
  102. package/package.json +14 -4
  103. package/src/add/add-ai-agent.ts +468 -0
  104. package/src/add/add-channel.ts +82 -79
  105. package/src/add/add-cli.ts +49 -20
  106. package/src/add/add-file-with-factory.ts +2 -0
  107. package/src/add/add-functions.ts +330 -86
  108. package/src/add/add-http-route.ts +245 -88
  109. package/src/add/add-http-routes.ts +228 -0
  110. package/src/add/add-keyed-wiring.ts +151 -0
  111. package/src/add/add-mcp-prompt.ts +26 -15
  112. package/src/add/add-mcp-resource.ts +27 -15
  113. package/src/add/add-middleware.ts +482 -80
  114. package/src/add/add-permission.ts +199 -40
  115. package/src/add/add-queue-worker.ts +24 -19
  116. package/src/add/add-rpc-invocations.ts +17 -0
  117. package/src/add/add-schedule.ts +16 -11
  118. package/src/add/add-secret.ts +140 -0
  119. package/src/add/add-trigger.ts +154 -0
  120. package/src/add/add-variable.ts +9 -0
  121. package/src/add/add-workflow-graph.ts +180 -522
  122. package/src/add/add-workflow.ts +5 -4
  123. package/src/error-codes.ts +24 -1
  124. package/src/index.ts +22 -13
  125. package/src/inspector.ts +129 -17
  126. package/src/schema-generator.ts +1 -0
  127. package/src/types-map.ts +12 -1
  128. package/src/types.ts +175 -58
  129. package/src/utils/compute-required-schemas.ts +49 -0
  130. package/src/utils/contract-hashes.test.ts +528 -0
  131. package/src/utils/contract-hashes.ts +290 -0
  132. package/src/utils/custom-types-generator.ts +88 -0
  133. package/src/utils/detect-schema-vendor.ts +90 -0
  134. package/src/utils/ensure-function-metadata.ts +324 -7
  135. package/src/utils/extract-function-name.ts +101 -351
  136. package/src/utils/extract-services.ts +35 -2
  137. package/src/utils/filter-inspector-state.test.ts +34 -20
  138. package/src/utils/filter-inspector-state.ts +140 -31
  139. package/src/utils/get-property-value.ts +42 -4
  140. package/src/utils/hash.ts +26 -0
  141. package/src/utils/middleware.test.ts +204 -0
  142. package/src/utils/middleware.ts +129 -67
  143. package/src/utils/permissions.test.ts +35 -12
  144. package/src/utils/permissions.ts +10 -10
  145. package/src/utils/post-process.ts +283 -43
  146. package/src/utils/resolve-external-package.ts +42 -0
  147. package/src/utils/resolve-function-types.ts +42 -0
  148. package/src/utils/resolve-identifier.ts +46 -0
  149. package/src/utils/resolve-versions.test.ts +249 -0
  150. package/src/utils/resolve-versions.ts +105 -0
  151. package/src/utils/schema-generator.ts +329 -0
  152. package/src/utils/serialize-inspector-state.ts +163 -40
  153. package/src/utils/serialize-mcp-json.ts +145 -0
  154. package/src/utils/serialize-middleware-groups-meta.ts +33 -0
  155. package/src/utils/serialize-openapi-json.ts +277 -0
  156. package/src/utils/serialize-permissions-groups-meta.ts +35 -0
  157. package/src/utils/test-data/inspector-state.json +69 -66
  158. package/src/utils/workflow/dsl/deserialize-dsl-workflow.ts +43 -119
  159. package/src/utils/workflow/dsl/extract-dsl-workflow.ts +24 -4
  160. package/src/utils/workflow/graph/convert-dsl-to-graph.ts +17 -10
  161. package/src/utils/workflow/graph/finalize-workflow-wires.ts +310 -0
  162. package/src/utils/workflow/graph/finalize-workflows.ts +100 -0
  163. package/src/utils/workflow/graph/index.ts +5 -0
  164. package/src/utils/workflow/graph/serialize-workflow-graph.ts +1 -8
  165. package/src/utils/workflow/graph/workflow-graph.types.ts +29 -78
  166. package/src/visit.ts +12 -6
  167. package/tsconfig.tsbuildinfo +1 -1
  168. package/dist/add/add-forge-credential.d.ts +0 -8
  169. package/dist/add/add-forge-credential.js +0 -77
  170. package/dist/add/add-forge-node.d.ts +0 -7
  171. package/dist/add/add-forge-node.js +0 -77
  172. package/dist/add/add-mcp-tool.d.ts +0 -2
  173. package/dist/add/add-mcp-tool.js +0 -81
  174. package/dist/utils/extract-service-metadata.d.ts +0 -19
  175. package/dist/utils/extract-service-metadata.js +0 -244
  176. package/dist/utils/write-service-metadata.d.ts +0 -13
  177. package/dist/utils/write-service-metadata.js +0 -37
  178. package/src/add/add-forge-credential.ts +0 -119
  179. package/src/add/add-forge-node.ts +0 -132
  180. package/src/add/add-mcp-tool.ts +0 -141
  181. package/src/utils/extract-service-metadata.ts +0 -353
  182. package/src/utils/write-service-metadata.ts +0 -51
@@ -1,12 +1,172 @@
1
+ import * as ts from 'typescript';
2
+ import { funcIdToTypeName } from './extract-function-name.js';
3
+ import { getCommonWireMetaData } from './get-property-value.js';
4
+ import { resolveMiddleware } from './middleware.js';
5
+ import { resolvePermissions } from './permissions.js';
6
+ function isVoidLike(type) {
7
+ return !!(type.flags &
8
+ (ts.TypeFlags.Void | ts.TypeFlags.Undefined | ts.TypeFlags.VoidLike));
9
+ }
10
+ function isPromiseOfVoid(checker, type) {
11
+ if (!type?.symbol)
12
+ return false;
13
+ const isPromise = type.symbol.name === 'Promise' &&
14
+ checker.getFullyQualifiedName(type.symbol).includes('Promise');
15
+ if (!isPromise)
16
+ return false;
17
+ const inner = type.aliasTypeArguments?.[0] ??
18
+ type.typeArguments?.[0];
19
+ return !!inner && isVoidLike(inner);
20
+ }
21
+ function unwrapPromise(checker, type) {
22
+ if (type.isUnion()) {
23
+ const nonVoid = type.types.filter((t) => !isVoidLike(t) && !isPromiseOfVoid(checker, t));
24
+ if (nonVoid.length === 1) {
25
+ return unwrapPromise(checker, nonVoid[0]);
26
+ }
27
+ if (nonVoid.length > 1) {
28
+ return unwrapPromise(checker, nonVoid[0]);
29
+ }
30
+ return type;
31
+ }
32
+ if (!type?.symbol)
33
+ return type;
34
+ const isPromise = type.symbol.name === 'Promise' &&
35
+ checker.getFullyQualifiedName(type.symbol).includes('Promise');
36
+ if (isPromise && type.aliasTypeArguments?.length === 1) {
37
+ return type.aliasTypeArguments[0];
38
+ }
39
+ if (isPromise && type.typeArguments?.length === 1) {
40
+ return type.typeArguments[0];
41
+ }
42
+ return type;
43
+ }
44
+ function resolveTypeName(checker, type, state, funcName, direction) {
45
+ if (type.flags & (ts.TypeFlags.VoidLike | ts.TypeFlags.Null))
46
+ return null;
47
+ const typeStr = checker.typeToString(type, undefined, ts.TypeFormatFlags.NoTruncation);
48
+ if (!typeStr ||
49
+ typeStr === 'void' ||
50
+ typeStr === 'undefined' ||
51
+ typeStr === 'null')
52
+ return null;
53
+ const isSimpleName = /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(typeStr);
54
+ if (isSimpleName) {
55
+ const symbol = type.aliasSymbol || type.getSymbol();
56
+ if (symbol) {
57
+ const decl = symbol.getDeclarations()?.[0];
58
+ if (decl) {
59
+ const path = decl.getSourceFile().fileName;
60
+ if (!state.functions.typesMap.exists(typeStr, path)) {
61
+ state.functions.typesMap.addType(typeStr, path);
62
+ }
63
+ }
64
+ }
65
+ return typeStr;
66
+ }
67
+ const aliasName = funcIdToTypeName(funcName) + direction;
68
+ state.functions.typesMap.addCustomType(aliasName, typeStr, []);
69
+ return aliasName;
70
+ }
71
+ function getFirstCallSignature(type) {
72
+ const sigs = type.getCallSignatures();
73
+ if (sigs.length > 0)
74
+ return sigs[0];
75
+ if (type.isUnion()) {
76
+ for (const member of type.types) {
77
+ const memberSigs = member.getCallSignatures();
78
+ if (memberSigs.length > 0)
79
+ return memberSigs[0];
80
+ }
81
+ }
82
+ return undefined;
83
+ }
84
+ function resolveFromConfigTypeArgs(state, pikkuFuncId, configType, checker, meta) {
85
+ const typeArgs = configType.aliasTypeArguments ??
86
+ configType.typeArguments;
87
+ if (!typeArgs || typeArgs.length < 2)
88
+ return;
89
+ const inputType = typeArgs[0];
90
+ const outputType = typeArgs[1];
91
+ if (!meta.inputs || meta.inputs.length === 0) {
92
+ const inputName = resolveTypeName(checker, inputType, state, pikkuFuncId, 'Input');
93
+ if (inputName) {
94
+ meta.inputs = [inputName];
95
+ meta.inputSchemaName = inputName;
96
+ }
97
+ }
98
+ if (!meta.outputs || meta.outputs.length === 0) {
99
+ const resolvedOutput = unwrapPromise(checker, outputType);
100
+ const outputName = resolveTypeName(checker, resolvedOutput, state, pikkuFuncId, 'Output');
101
+ if (outputName) {
102
+ meta.outputs = [outputName];
103
+ meta.outputSchemaName = outputName;
104
+ }
105
+ }
106
+ }
107
+ function resolveFuncConfigTypes(state, pikkuFuncId, funcInitializer, checker) {
108
+ const meta = state.functions.meta[pikkuFuncId];
109
+ if (!meta || (meta.inputs && meta.inputs.length > 0))
110
+ return;
111
+ const configType = checker.getTypeAtLocation(funcInitializer);
112
+ const funcProp = configType.getProperty('func');
113
+ if (!funcProp)
114
+ return;
115
+ const funcType = checker.getTypeOfSymbolAtLocation(funcProp, funcInitializer);
116
+ const sig = getFirstCallSignature(funcType);
117
+ if (!sig)
118
+ return;
119
+ const params = sig.getParameters();
120
+ if (params.length >= 2) {
121
+ const inputType = checker.getTypeOfSymbolAtLocation(params[1], funcInitializer);
122
+ const inputName = resolveTypeName(checker, inputType, state, pikkuFuncId, 'Input');
123
+ if (inputName) {
124
+ meta.inputs = [inputName];
125
+ meta.inputSchemaName = inputName;
126
+ }
127
+ }
128
+ const rawReturnType = checker.getReturnTypeOfSignature(sig);
129
+ const outputType = unwrapPromise(checker, rawReturnType);
130
+ const outputName = resolveTypeName(checker, outputType, state, pikkuFuncId, 'Output');
131
+ if (outputName) {
132
+ meta.outputs = [outputName];
133
+ meta.outputSchemaName = outputName;
134
+ }
135
+ resolveFromConfigTypeArgs(state, pikkuFuncId, configType, checker, meta);
136
+ }
137
+ function resolveToPikkuFuncCall(node, checker) {
138
+ if (ts.isCallExpression(node) &&
139
+ ts.isIdentifier(node.expression) &&
140
+ node.expression.text.startsWith('pikku')) {
141
+ return node;
142
+ }
143
+ if (ts.isIdentifier(node)) {
144
+ const sym = checker.getSymbolAtLocation(node);
145
+ if (sym) {
146
+ let resolved = sym;
147
+ if (resolved.flags & ts.SymbolFlags.Alias) {
148
+ resolved = checker.getAliasedSymbol(resolved) ?? resolved;
149
+ }
150
+ const decl = resolved.declarations?.[0];
151
+ if (decl && ts.isVariableDeclaration(decl) && decl.initializer) {
152
+ return resolveToPikkuFuncCall(decl.initializer, checker);
153
+ }
154
+ }
155
+ }
156
+ return null;
157
+ }
1
158
  /**
2
- * Ensures that function metadata exists for a given pikkuFuncName.
159
+ * Ensures that function metadata exists for a given pikkuFuncId.
3
160
  * Creates stub metadata if it doesn't exist (useful for inline functions).
161
+ * When funcInitializer and checker are provided, resolves types and
162
+ * extracts tags/middleware/permissions from the pikkuFunc() config.
4
163
  */
5
- export function ensureFunctionMetadata(state, pikkuFuncName, fallbackName) {
6
- if (!state.functions.meta[pikkuFuncName]) {
7
- state.functions.meta[pikkuFuncName] = {
8
- pikkuFuncName,
9
- name: fallbackName || pikkuFuncName,
164
+ export function ensureFunctionMetadata(state, pikkuFuncId, fallbackName, funcInitializer, checker, isHelper) {
165
+ if (!state.functions.meta[pikkuFuncId]) {
166
+ state.functions.meta[pikkuFuncId] = {
167
+ pikkuFuncId,
168
+ functionType: isHelper ? 'helper' : 'inline',
169
+ name: fallbackName || pikkuFuncId,
10
170
  services: { optimized: false, services: [] },
11
171
  inputSchemaName: null,
12
172
  outputSchemaName: null,
@@ -15,4 +175,58 @@ export function ensureFunctionMetadata(state, pikkuFuncName, fallbackName) {
15
175
  middleware: undefined,
16
176
  };
17
177
  }
178
+ const meta = state.functions.meta[pikkuFuncId];
179
+ if (funcInitializer && checker) {
180
+ let pikkuFuncCall = null;
181
+ if (ts.isCallExpression(funcInitializer)) {
182
+ pikkuFuncCall = funcInitializer;
183
+ resolveFuncConfigTypes(state, pikkuFuncId, pikkuFuncCall, checker);
184
+ if (!state.typesLookup.has(pikkuFuncId)) {
185
+ populateTypesLookup(state, pikkuFuncId, pikkuFuncCall, checker);
186
+ }
187
+ }
188
+ else {
189
+ pikkuFuncCall = resolveToPikkuFuncCall(funcInitializer, checker);
190
+ }
191
+ if (pikkuFuncCall) {
192
+ const firstArg = pikkuFuncCall.arguments[0];
193
+ if (firstArg && ts.isObjectLiteralExpression(firstArg)) {
194
+ if (!meta.tags) {
195
+ const { tags } = getCommonWireMetaData(firstArg, 'Function', fallbackName || pikkuFuncId);
196
+ if (tags) {
197
+ meta.tags = tags;
198
+ }
199
+ }
200
+ if (!meta.middleware) {
201
+ meta.middleware = resolveMiddleware(state, firstArg, meta.tags, checker);
202
+ }
203
+ if (!meta.permissions) {
204
+ meta.permissions = resolvePermissions(state, firstArg, meta.tags, checker);
205
+ }
206
+ }
207
+ }
208
+ }
209
+ }
210
+ function populateTypesLookup(state, pikkuFuncId, funcInitializer, checker) {
211
+ const typeArgs = funcInitializer.typeArguments;
212
+ if (typeArgs && typeArgs.length >= 1) {
213
+ const inputType = checker.getTypeFromTypeNode(typeArgs[0]);
214
+ state.typesLookup.set(pikkuFuncId, [inputType]);
215
+ return;
216
+ }
217
+ const configType = checker.getTypeAtLocation(funcInitializer);
218
+ const funcProp = configType.getProperty('func');
219
+ if (!funcProp)
220
+ return;
221
+ const funcType = checker.getTypeOfSymbolAtLocation(funcProp, funcInitializer);
222
+ const sig = getFirstCallSignature(funcType);
223
+ if (!sig)
224
+ return;
225
+ const params = sig.getParameters();
226
+ if (params.length >= 2) {
227
+ const inputType = checker.getTypeOfSymbolAtLocation(params[1], funcInitializer);
228
+ if (!(inputType.flags & ts.TypeFlags.VoidLike)) {
229
+ state.typesLookup.set(pikkuFuncId, [inputType]);
230
+ }
231
+ }
18
232
  }
@@ -1,25 +1,14 @@
1
1
  import * as ts from 'typescript';
2
2
  export type ExtractedFunctionName = {
3
- pikkuFuncName: string;
3
+ pikkuFuncId: string;
4
4
  name: string;
5
5
  explicitName: string | null;
6
6
  exportedName: string | null;
7
- localName: string | null;
8
7
  propertyName: string | null;
8
+ isHelper: boolean;
9
9
  };
10
- /**
11
- * Generate a deterministic "anonymous" name for any expression node,
12
- * but if it's an Identifier pointing to a function, resolve it back
13
- * to the function's declaration (so you get the true source location).
14
- */
15
- export declare function makeDeterministicAnonName(start: ts.Node, checker: ts.TypeChecker, rootDir: string): string;
16
- /**
17
- * Updated function to extract and prioritize function names correctly
18
- * This function follows the priority:
19
- * 1. Object with a name property
20
- * 2. Exported name
21
- * 3. Fallback to deterministic name
22
- */
10
+ export declare function makeContextBasedId(wiringType: string, ...segments: string[]): string;
11
+ export declare function funcIdToTypeName(id: string): string;
23
12
  export declare function extractFunctionName(callExpr: ts.Node, checker: ts.TypeChecker, rootDir: string): ExtractedFunctionName;
24
13
  /**
25
14
  * Helper function to populate the 'name' field based on priority
@@ -28,4 +17,4 @@ export declare function populateNameByPriority(result: ExtractedFunctionName): v
28
17
  /**
29
18
  * Helper function to check if a variable declaration is a named export
30
19
  */
31
- export declare function isNamedExport(declaration: ts.VariableDeclaration): boolean;
20
+ export declare function isNamedExport(declaration: ts.VariableDeclaration, checker?: ts.TypeChecker): boolean;