@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.
- package/CHANGELOG.md +11 -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 +69 -61
- package/dist/add/add-cli.js +36 -18
- package/dist/add/add-file-with-factory.js +2 -0
- package/dist/add/add-functions.js +250 -75
- package/dist/add/add-http-route.d.ts +19 -10
- package/dist/add/add-http-route.js +152 -66
- package/dist/add/add-http-routes.d.ts +5 -0
- package/dist/add/add-http-routes.js +159 -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.js +14 -9
- 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.js +18 -12
- package/dist/add/add-rpc-invocations.js +14 -0
- 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-workflow-graph.d.ts +3 -2
- package/dist/add/add-workflow-graph.js +143 -406
- package/dist/add/add-workflow.js +6 -4
- package/dist/error-codes.d.ts +14 -1
- package/dist/error-codes.js +19 -1
- package/dist/index.d.ts +9 -8
- package/dist/index.js +5 -4
- package/dist/inspector.d.ts +1 -1
- package/dist/inspector.js +91 -14
- 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 +163 -39
- package/dist/utils/compute-required-schemas.d.ts +4 -0
- package/dist/utils/compute-required-schemas.js +41 -0
- package/dist/utils/contract-hashes.d.ts +35 -0
- package/dist/utils/contract-hashes.js +202 -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/ensure-function-metadata.d.ts +5 -2
- 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.js +107 -23
- 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 +7 -30
- package/dist/utils/middleware.js +80 -66
- package/dist/utils/permissions.d.ts +2 -2
- package/dist/utils/permissions.js +10 -10
- package/dist/utils/post-process.d.ts +9 -10
- package/dist/utils/post-process.js +231 -24
- package/dist/utils/resolve-external-package.d.ts +12 -0
- package/dist/utils/resolve-external-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 +59 -22
- package/dist/utils/serialize-inspector-state.js +92 -20
- 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/workflow/dsl/deserialize-dsl-workflow.js +34 -102
- 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.js +11 -6
- package/package.json +14 -4
- package/src/add/add-ai-agent.ts +468 -0
- package/src/add/add-channel.ts +82 -79
- package/src/add/add-cli.ts +49 -20
- package/src/add/add-file-with-factory.ts +2 -0
- package/src/add/add-functions.ts +330 -86
- package/src/add/add-http-route.ts +245 -88
- package/src/add/add-http-routes.ts +228 -0
- package/src/add/add-keyed-wiring.ts +151 -0
- package/src/add/add-mcp-prompt.ts +26 -15
- package/src/add/add-mcp-resource.ts +27 -15
- package/src/add/add-middleware.ts +482 -80
- package/src/add/add-permission.ts +199 -40
- package/src/add/add-queue-worker.ts +24 -19
- package/src/add/add-rpc-invocations.ts +17 -0
- package/src/add/add-schedule.ts +16 -11
- 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-workflow-graph.ts +180 -522
- package/src/add/add-workflow.ts +5 -4
- package/src/error-codes.ts +24 -1
- package/src/index.ts +22 -13
- package/src/inspector.ts +129 -17
- package/src/schema-generator.ts +1 -0
- package/src/types-map.ts +12 -1
- package/src/types.ts +175 -58
- package/src/utils/compute-required-schemas.ts +49 -0
- package/src/utils/contract-hashes.test.ts +528 -0
- package/src/utils/contract-hashes.ts +290 -0
- package/src/utils/custom-types-generator.ts +88 -0
- package/src/utils/detect-schema-vendor.ts +90 -0
- package/src/utils/ensure-function-metadata.ts +324 -7
- 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 +34 -20
- package/src/utils/filter-inspector-state.ts +140 -31
- 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 +129 -67
- package/src/utils/permissions.test.ts +35 -12
- package/src/utils/permissions.ts +10 -10
- package/src/utils/post-process.ts +283 -43
- package/src/utils/resolve-external-package.ts +42 -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 +163 -40
- 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/workflow/dsl/deserialize-dsl-workflow.ts +43 -119
- package/src/utils/workflow/dsl/extract-dsl-workflow.ts +24 -4
- 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 +12 -6
- 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
|
@@ -1,214 +1,55 @@
|
|
|
1
1
|
import * as ts from 'typescript';
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
if (ts.isIdentifier(node)) {
|
|
13
|
-
const sym = checker.getSymbolAtLocation(node);
|
|
14
|
-
if (sym) {
|
|
15
|
-
let resolvedSym = sym;
|
|
16
|
-
if (resolvedSym.flags & ts.SymbolFlags.Alias) {
|
|
17
|
-
resolvedSym = checker.getAliasedSymbol(resolvedSym) ?? resolvedSym;
|
|
18
|
-
}
|
|
19
|
-
const decls = resolvedSym.declarations ?? [];
|
|
20
|
-
if (decls.length > 0) {
|
|
21
|
-
// Start with the declaration, not the reference
|
|
22
|
-
const decl = decls[0];
|
|
23
|
-
// If it's a variable declaration with a function initializer, use the function directly
|
|
24
|
-
if (ts.isVariableDeclaration(decl) &&
|
|
25
|
-
decl.initializer &&
|
|
26
|
-
(ts.isFunctionExpression(decl.initializer) ||
|
|
27
|
-
ts.isArrowFunction(decl.initializer))) {
|
|
28
|
-
target = decl.initializer;
|
|
29
|
-
// Return early - we found the function directly
|
|
30
|
-
const sf = target.getSourceFile();
|
|
31
|
-
const relativePath = toRelativePath(sf.fileName, rootDir);
|
|
32
|
-
const file = relativePath.replace(/[^A-Za-z0-9_]/g, '_');
|
|
33
|
-
const { line, character } = ts.getLineAndCharacterOfPosition(sf, target.getStart());
|
|
34
|
-
return `pikkuFn_${file}_L${line + 1}C${character + 1}`;
|
|
35
|
-
}
|
|
36
|
-
// Otherwise continue resolution with the declaration
|
|
37
|
-
node = decl;
|
|
38
|
-
target = decl;
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
// In an object literal property value, first try to resolve the identifier
|
|
43
|
-
if (ts.isPropertyAssignment(node.parent) &&
|
|
44
|
-
node === node.parent.initializer &&
|
|
45
|
-
ts.isIdentifier(node)) {
|
|
46
|
-
const sym = checker.getSymbolAtLocation(node);
|
|
47
|
-
if (sym) {
|
|
48
|
-
// Process the symbol to find the real declaration
|
|
49
|
-
let resolvedSym = sym;
|
|
50
|
-
if (resolvedSym.flags & ts.SymbolFlags.Alias) {
|
|
51
|
-
resolvedSym = checker.getAliasedSymbol(resolvedSym) ?? resolvedSym;
|
|
52
|
-
}
|
|
53
|
-
const decls = resolvedSym.declarations ?? [];
|
|
54
|
-
if (decls.length > 0) {
|
|
55
|
-
// Found a declaration - use it as our new target
|
|
56
|
-
const decl = decls[0];
|
|
57
|
-
if (!decl) {
|
|
58
|
-
throw new Error('No declaration found');
|
|
59
|
-
}
|
|
60
|
-
// If it's a variable declaration with an initializer function, use that
|
|
61
|
-
if (ts.isVariableDeclaration(decl) && decl.initializer) {
|
|
62
|
-
if (ts.isFunctionExpression(decl.initializer) ||
|
|
63
|
-
ts.isArrowFunction(decl.initializer)) {
|
|
64
|
-
target = decl.initializer;
|
|
65
|
-
// Return early - we found the function directly
|
|
66
|
-
const sf = target.getSourceFile();
|
|
67
|
-
const relativePath = toRelativePath(sf.fileName, rootDir);
|
|
68
|
-
const file = relativePath.replace(/[^A-Za-z0-9_]/g, '_');
|
|
69
|
-
const { line, character } = ts.getLineAndCharacterOfPosition(sf, target.getStart());
|
|
70
|
-
return `pikkuFn_${file}_L${line + 1}C${character + 1}`;
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
else if (ts.isFunctionDeclaration(decl)) {
|
|
74
|
-
// Already a function declaration
|
|
75
|
-
target = decl;
|
|
76
|
-
// Return early
|
|
77
|
-
const sf = target.getSourceFile();
|
|
78
|
-
const relativePath = toRelativePath(sf.fileName, rootDir);
|
|
79
|
-
const file = relativePath.replace(/[^A-Za-z0-9_]/g, '_');
|
|
80
|
-
const { line, character } = ts.getLineAndCharacterOfPosition(sf, target.getStart());
|
|
81
|
-
return `pikkuFn_${file}_L${line + 1}C${character + 1}`;
|
|
82
|
-
}
|
|
83
|
-
// If we didn't return early, continue with this declaration
|
|
84
|
-
node = decl;
|
|
85
|
-
target = decl;
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
const seen = new Set();
|
|
90
|
-
for (let depth = 0; depth < 10; depth++) {
|
|
91
|
-
if (!ts.isIdentifier(node) || seen.has(node))
|
|
92
|
-
break;
|
|
93
|
-
seen.add(node);
|
|
94
|
-
let sym = checker.getSymbolAtLocation(node);
|
|
95
|
-
if (!sym)
|
|
96
|
-
break;
|
|
97
|
-
if (sym.flags & ts.SymbolFlags.Alias) {
|
|
98
|
-
sym = checker.getAliasedSymbol(sym) ?? sym;
|
|
99
|
-
}
|
|
100
|
-
const allDecls = sym.declarations ?? [];
|
|
101
|
-
// prefer real .ts/.tsx implementation files
|
|
102
|
-
const implDecls = allDecls.filter((d) => !d.getSourceFile().isDeclarationFile);
|
|
103
|
-
const decls = implDecls.length ? implDecls : allDecls;
|
|
104
|
-
let didResolve = false;
|
|
105
|
-
for (const decl of decls) {
|
|
106
|
-
// 1) direct function foo() {} or function-expression
|
|
107
|
-
if (ts.isFunctionDeclaration(decl) ||
|
|
108
|
-
ts.isFunctionExpression(decl) ||
|
|
109
|
-
ts.isArrowFunction(decl)) {
|
|
110
|
-
target = decl;
|
|
111
|
-
didResolve = true;
|
|
112
|
-
break;
|
|
113
|
-
}
|
|
114
|
-
// 2) const foo = () => {} or foo = function() {}
|
|
115
|
-
if (ts.isVariableDeclaration(decl) && decl.initializer) {
|
|
116
|
-
const init = decl.initializer;
|
|
117
|
-
if (ts.isFunctionExpression(init) || ts.isArrowFunction(init)) {
|
|
118
|
-
target = init;
|
|
119
|
-
didResolve = true;
|
|
120
|
-
break;
|
|
121
|
-
}
|
|
122
|
-
// 2b) const foo = bar; (follow the next identifier)
|
|
123
|
-
if (ts.isIdentifier(init)) {
|
|
124
|
-
node = init;
|
|
125
|
-
target = init;
|
|
126
|
-
didResolve = true;
|
|
127
|
-
break;
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
// 3) Handle shorthand property assignments: { foo } (equivalent to { foo: foo })
|
|
131
|
-
if (ts.isShorthandPropertyAssignment(decl)) {
|
|
132
|
-
// Get the symbol for the shorthand property
|
|
133
|
-
const shorthandSym = checker.getShorthandAssignmentValueSymbol(decl);
|
|
134
|
-
if (shorthandSym &&
|
|
135
|
-
shorthandSym.declarations &&
|
|
136
|
-
shorthandSym.declarations.length > 0) {
|
|
137
|
-
// Use the first declaration as our new target
|
|
138
|
-
const shorthandDecl = shorthandSym.declarations[0];
|
|
139
|
-
target = shorthandDecl;
|
|
140
|
-
if (!shorthandDecl) {
|
|
141
|
-
throw new Error('No shorthand declaration found');
|
|
142
|
-
}
|
|
143
|
-
// Check the type of declaration and extract the appropriate identifier to continue resolving
|
|
144
|
-
if (ts.isVariableDeclaration(shorthandDecl) &&
|
|
145
|
-
ts.isIdentifier(shorthandDecl.name)) {
|
|
146
|
-
node = shorthandDecl.name;
|
|
147
|
-
didResolve = true;
|
|
148
|
-
break;
|
|
149
|
-
}
|
|
150
|
-
else if (ts.isFunctionDeclaration(shorthandDecl) &&
|
|
151
|
-
shorthandDecl.name &&
|
|
152
|
-
ts.isIdentifier(shorthandDecl.name)) {
|
|
153
|
-
node = shorthandDecl.name;
|
|
154
|
-
didResolve = true;
|
|
155
|
-
break;
|
|
156
|
-
}
|
|
157
|
-
else if (ts.isParameter(shorthandDecl) &&
|
|
158
|
-
ts.isIdentifier(shorthandDecl.name)) {
|
|
159
|
-
node = shorthandDecl.name;
|
|
160
|
-
didResolve = true;
|
|
161
|
-
break;
|
|
162
|
-
}
|
|
163
|
-
else if (ts.isPropertyDeclaration(shorthandDecl) &&
|
|
164
|
-
ts.isIdentifier(shorthandDecl.name)) {
|
|
165
|
-
node = shorthandDecl.name;
|
|
166
|
-
didResolve = true;
|
|
167
|
-
break;
|
|
168
|
-
}
|
|
169
|
-
else if (ts.isMethodDeclaration(shorthandDecl) &&
|
|
170
|
-
ts.isIdentifier(shorthandDecl.name)) {
|
|
171
|
-
node = shorthandDecl.name;
|
|
172
|
-
didResolve = true;
|
|
173
|
-
break;
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
// 4) Handle method declarations in classes/objects
|
|
178
|
-
if (ts.isMethodDeclaration(decl)) {
|
|
179
|
-
target = decl;
|
|
180
|
-
didResolve = true;
|
|
181
|
-
break;
|
|
182
|
-
}
|
|
183
|
-
// you can add more cases here if your setup uses imports, etc.
|
|
184
|
-
}
|
|
185
|
-
if (!didResolve)
|
|
186
|
-
break;
|
|
187
|
-
}
|
|
188
|
-
const sf = target.getSourceFile();
|
|
189
|
-
const relativePath = toRelativePath(sf.fileName, rootDir);
|
|
190
|
-
const file = relativePath.replace(/[^A-Za-z0-9_]/g, '_');
|
|
191
|
-
const { line, character } = ts.getLineAndCharacterOfPosition(sf, target.getStart());
|
|
192
|
-
return `pikkuFn_${file}_L${line + 1}C${character + 1}`;
|
|
2
|
+
import { randomUUID } from 'crypto';
|
|
3
|
+
export function makeContextBasedId(wiringType, ...segments) {
|
|
4
|
+
return [wiringType, ...segments].join(':');
|
|
5
|
+
}
|
|
6
|
+
export function funcIdToTypeName(id) {
|
|
7
|
+
return id
|
|
8
|
+
.split(/[^a-zA-Z0-9]/)
|
|
9
|
+
.filter(Boolean)
|
|
10
|
+
.map((s) => s.charAt(0).toUpperCase() + s.slice(1))
|
|
11
|
+
.join('');
|
|
193
12
|
}
|
|
194
|
-
/**
|
|
195
|
-
* Updated function to extract and prioritize function names correctly
|
|
196
|
-
* This function follows the priority:
|
|
197
|
-
* 1. Object with a name property
|
|
198
|
-
* 2. Exported name
|
|
199
|
-
* 3. Fallback to deterministic name
|
|
200
|
-
*/
|
|
201
13
|
export function extractFunctionName(callExpr, checker, rootDir) {
|
|
202
14
|
const parent = callExpr.parent;
|
|
203
15
|
// Initialize the result
|
|
204
16
|
const result = {
|
|
205
|
-
|
|
206
|
-
name: '',
|
|
17
|
+
pikkuFuncId: '',
|
|
18
|
+
name: '',
|
|
207
19
|
exportedName: null,
|
|
208
|
-
localName: null,
|
|
209
20
|
propertyName: null,
|
|
210
21
|
explicitName: null,
|
|
22
|
+
isHelper: false,
|
|
211
23
|
};
|
|
24
|
+
const workflowHelpers = new Set([
|
|
25
|
+
'workflow',
|
|
26
|
+
'workflowStart',
|
|
27
|
+
'workflowStatus',
|
|
28
|
+
'graphStart',
|
|
29
|
+
]);
|
|
30
|
+
if (ts.isCallExpression(callExpr) &&
|
|
31
|
+
ts.isIdentifier(callExpr.expression) &&
|
|
32
|
+
workflowHelpers.has(callExpr.expression.text)) {
|
|
33
|
+
const helperName = callExpr.expression.text;
|
|
34
|
+
const [firstArg, secondArg] = callExpr.arguments;
|
|
35
|
+
if (firstArg && ts.isStringLiteral(firstArg)) {
|
|
36
|
+
const workflowName = firstArg.text;
|
|
37
|
+
let funcName;
|
|
38
|
+
if (helperName === 'graphStart' &&
|
|
39
|
+
secondArg &&
|
|
40
|
+
ts.isStringLiteral(secondArg)) {
|
|
41
|
+
funcName = `${helperName}:${workflowName}:${secondArg.text}`;
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
funcName = `${helperName}:${workflowName}`;
|
|
45
|
+
}
|
|
46
|
+
result.pikkuFuncId = funcName;
|
|
47
|
+
result.name = funcName;
|
|
48
|
+
result.explicitName = funcName;
|
|
49
|
+
result.isHelper = true;
|
|
50
|
+
return result;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
212
53
|
// Special case for wireHTTP: if this is an identifier within an object literal,
|
|
213
54
|
// it might be coming from the HTTP route handling flow
|
|
214
55
|
if (ts.isIdentifier(callExpr) &&
|
|
@@ -234,25 +75,19 @@ export function extractFunctionName(callExpr, checker, rootDir) {
|
|
|
234
75
|
if (firstArg &&
|
|
235
76
|
(ts.isArrowFunction(firstArg) ||
|
|
236
77
|
ts.isFunctionExpression(firstArg))) {
|
|
237
|
-
// Use the function directly for position calculation
|
|
238
|
-
result.pikkuFuncName = makeDeterministicAnonName(firstArg, checker, rootDir);
|
|
239
78
|
// Continue with name extraction
|
|
240
79
|
if (ts.isIdentifier(parent.name)) {
|
|
241
80
|
result.propertyName = parent.name.text;
|
|
242
81
|
}
|
|
243
|
-
// Check if the variable is exported
|
|
244
82
|
if (ts.isVariableDeclaration(decl) &&
|
|
245
|
-
isNamedExport(decl) &&
|
|
83
|
+
isNamedExport(decl, checker) &&
|
|
246
84
|
ts.isIdentifier(decl.name)) {
|
|
247
85
|
result.exportedName = decl.name.text;
|
|
248
|
-
|
|
249
|
-
result.pikkuFuncName = decl.name.text;
|
|
86
|
+
result.pikkuFuncId = decl.name.text;
|
|
250
87
|
}
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
result.localName = decl.name.text;
|
|
88
|
+
if (!result.pikkuFuncId) {
|
|
89
|
+
result.pikkuFuncId = `__temp_${randomUUID()}`;
|
|
254
90
|
}
|
|
255
|
-
// Apply name priority logic
|
|
256
91
|
populateNameByPriority(result);
|
|
257
92
|
return result;
|
|
258
93
|
}
|
|
@@ -261,9 +96,6 @@ export function extractFunctionName(callExpr, checker, rootDir) {
|
|
|
261
96
|
}
|
|
262
97
|
}
|
|
263
98
|
}
|
|
264
|
-
// Keep track of the original call expression for position-based naming
|
|
265
|
-
let originalCallExpr = callExpr;
|
|
266
|
-
// For direct pikku function calls where callExpr is the call expression itself
|
|
267
99
|
if (ts.isCallExpression(callExpr)) {
|
|
268
100
|
const { expression, arguments: args } = callExpr;
|
|
269
101
|
// Check if this is a pikku function call (pikkuFunc, pikkuSessionlessFunc, etc)
|
|
@@ -327,29 +159,19 @@ export function extractFunctionName(callExpr, checker, rootDir) {
|
|
|
327
159
|
ts.isFunctionExpression(firstArg))) {
|
|
328
160
|
// mainFunc = firstArg
|
|
329
161
|
// Check if the variable is exported
|
|
330
|
-
if (isNamedExport(funcDecl) &&
|
|
162
|
+
if (isNamedExport(funcDecl, checker) &&
|
|
331
163
|
ts.isIdentifier(funcDecl.name)) {
|
|
332
164
|
result.exportedName = funcDecl.name.text;
|
|
333
165
|
}
|
|
334
|
-
else if (ts.isIdentifier(funcDecl.name)) {
|
|
335
|
-
// If not exported, still capture the variable name
|
|
336
|
-
result.localName = funcDecl.name.text;
|
|
337
|
-
}
|
|
338
166
|
break;
|
|
339
167
|
}
|
|
340
168
|
}
|
|
341
169
|
else if (ts.isFunctionExpression(funcDecl.initializer) ||
|
|
342
170
|
ts.isArrowFunction(funcDecl.initializer)) {
|
|
343
|
-
|
|
344
|
-
// Check if the variable is exported
|
|
345
|
-
if (isNamedExport(funcDecl) &&
|
|
171
|
+
if (isNamedExport(funcDecl, checker) &&
|
|
346
172
|
ts.isIdentifier(funcDecl.name)) {
|
|
347
173
|
result.exportedName = funcDecl.name.text;
|
|
348
174
|
}
|
|
349
|
-
else if (ts.isIdentifier(funcDecl.name)) {
|
|
350
|
-
// If not exported, still capture the variable name
|
|
351
|
-
result.localName = funcDecl.name.text;
|
|
352
|
-
}
|
|
353
175
|
break;
|
|
354
176
|
}
|
|
355
177
|
}
|
|
@@ -361,11 +183,6 @@ export function extractFunctionName(callExpr, checker, rootDir) {
|
|
|
361
183
|
ts.isIdentifier(funcDecl.name)) {
|
|
362
184
|
result.exportedName = funcDecl.name.text;
|
|
363
185
|
}
|
|
364
|
-
else if (funcDecl.name &&
|
|
365
|
-
ts.isIdentifier(funcDecl.name)) {
|
|
366
|
-
// If not exported, still capture the function name
|
|
367
|
-
result.localName = funcDecl.name.text;
|
|
368
|
-
}
|
|
369
186
|
break;
|
|
370
187
|
}
|
|
371
188
|
}
|
|
@@ -407,29 +224,19 @@ export function extractFunctionName(callExpr, checker, rootDir) {
|
|
|
407
224
|
ts.isFunctionExpression(firstArg))) {
|
|
408
225
|
// mainFunc = firstArg
|
|
409
226
|
// Check if the variable is exported
|
|
410
|
-
if (isNamedExport(shorthandDecl) &&
|
|
227
|
+
if (isNamedExport(shorthandDecl, checker) &&
|
|
411
228
|
ts.isIdentifier(shorthandDecl.name)) {
|
|
412
229
|
result.exportedName = shorthandDecl.name.text;
|
|
413
230
|
}
|
|
414
|
-
else if (ts.isIdentifier(shorthandDecl.name)) {
|
|
415
|
-
// If not exported, still capture the variable name
|
|
416
|
-
result.localName = shorthandDecl.name.text;
|
|
417
|
-
}
|
|
418
231
|
break;
|
|
419
232
|
}
|
|
420
233
|
}
|
|
421
234
|
else if (ts.isFunctionExpression(shorthandDecl.initializer) ||
|
|
422
235
|
ts.isArrowFunction(shorthandDecl.initializer)) {
|
|
423
|
-
|
|
424
|
-
// Check if the variable is exported
|
|
425
|
-
if (isNamedExport(shorthandDecl) &&
|
|
236
|
+
if (isNamedExport(shorthandDecl, checker) &&
|
|
426
237
|
ts.isIdentifier(shorthandDecl.name)) {
|
|
427
238
|
result.exportedName = shorthandDecl.name.text;
|
|
428
239
|
}
|
|
429
|
-
else if (ts.isIdentifier(shorthandDecl.name)) {
|
|
430
|
-
// If not exported, still capture the variable name
|
|
431
|
-
result.localName = shorthandDecl.name.text;
|
|
432
|
-
}
|
|
433
240
|
break;
|
|
434
241
|
}
|
|
435
242
|
}
|
|
@@ -441,11 +248,6 @@ export function extractFunctionName(callExpr, checker, rootDir) {
|
|
|
441
248
|
ts.isIdentifier(shorthandDecl.name)) {
|
|
442
249
|
result.exportedName = shorthandDecl.name.text;
|
|
443
250
|
}
|
|
444
|
-
else if (shorthandDecl.name &&
|
|
445
|
-
ts.isIdentifier(shorthandDecl.name)) {
|
|
446
|
-
// If not exported, still capture the function name
|
|
447
|
-
result.localName = shorthandDecl.name.text;
|
|
448
|
-
}
|
|
449
251
|
break;
|
|
450
252
|
}
|
|
451
253
|
}
|
|
@@ -472,9 +274,6 @@ export function extractFunctionName(callExpr, checker, rootDir) {
|
|
|
472
274
|
if (ts.isCallExpression(decl.initializer) &&
|
|
473
275
|
ts.isIdentifier(decl.initializer.expression) &&
|
|
474
276
|
decl.initializer.expression.text.startsWith('pikku')) {
|
|
475
|
-
// Update originalCallExpr to use the call expression position
|
|
476
|
-
// instead of the variable declaration position
|
|
477
|
-
originalCallExpr = decl.initializer;
|
|
478
277
|
// Check for object with 'override' property in first argument
|
|
479
278
|
const firstArg = decl.initializer.arguments[0];
|
|
480
279
|
if (firstArg && ts.isObjectLiteralExpression(firstArg)) {
|
|
@@ -497,26 +296,17 @@ export function extractFunctionName(callExpr, checker, rootDir) {
|
|
|
497
296
|
}
|
|
498
297
|
}
|
|
499
298
|
// Check if the variable is exported
|
|
500
|
-
if (isNamedExport(decl) && ts.isIdentifier(decl.name)) {
|
|
299
|
+
if (isNamedExport(decl, checker) && ts.isIdentifier(decl.name)) {
|
|
501
300
|
result.exportedName = decl.name.text;
|
|
502
301
|
}
|
|
503
|
-
else if (ts.isIdentifier(decl.name)) {
|
|
504
|
-
// If not explicitly set by name property above, set functionName
|
|
505
|
-
if (!result.localName) {
|
|
506
|
-
result.localName = decl.name.text;
|
|
507
|
-
}
|
|
508
|
-
}
|
|
509
302
|
}
|
|
510
303
|
else if (ts.isFunctionExpression(decl.initializer) ||
|
|
511
304
|
ts.isArrowFunction(decl.initializer)) {
|
|
512
305
|
// mainFunc = decl.initializer
|
|
513
306
|
// Check if the variable is exported
|
|
514
|
-
if (isNamedExport(decl) && ts.isIdentifier(decl.name)) {
|
|
307
|
+
if (isNamedExport(decl, checker) && ts.isIdentifier(decl.name)) {
|
|
515
308
|
result.exportedName = decl.name.text;
|
|
516
309
|
}
|
|
517
|
-
else if (ts.isIdentifier(decl.name)) {
|
|
518
|
-
result.localName = decl.name.text;
|
|
519
|
-
}
|
|
520
310
|
}
|
|
521
311
|
}
|
|
522
312
|
else if (ts.isFunctionDeclaration(decl)) {
|
|
@@ -527,27 +317,15 @@ export function extractFunctionName(callExpr, checker, rootDir) {
|
|
|
527
317
|
ts.isIdentifier(decl.name)) {
|
|
528
318
|
result.exportedName = decl.name.text;
|
|
529
319
|
}
|
|
530
|
-
else if (decl.name && ts.isIdentifier(decl.name)) {
|
|
531
|
-
result.localName = decl.name.text;
|
|
532
|
-
}
|
|
533
320
|
}
|
|
534
321
|
}
|
|
535
322
|
}
|
|
536
323
|
}
|
|
537
|
-
// Generate the deterministic function name based on the original call expression
|
|
538
|
-
// (the config), not the resolved inner function. This ensures the metadata key
|
|
539
|
-
// matches what will be looked up at runtime when referencing the config object.
|
|
540
|
-
result.pikkuFuncName = makeDeterministicAnonName(originalCallExpr, checker, rootDir);
|
|
541
|
-
// Continue with regular name extraction for remaining cases
|
|
542
324
|
// 1) const foo = pikkuFunc(...)
|
|
543
325
|
if (ts.isVariableDeclaration(parent) && ts.isIdentifier(parent.name)) {
|
|
544
|
-
if (isNamedExport(parent)) {
|
|
326
|
+
if (isNamedExport(parent, checker)) {
|
|
545
327
|
result.exportedName = parent.name.text;
|
|
546
328
|
}
|
|
547
|
-
else {
|
|
548
|
-
// Still capture the variable name even if not exported
|
|
549
|
-
result.localName = parent.name.text;
|
|
550
|
-
}
|
|
551
329
|
}
|
|
552
330
|
// 2) { foo: pikkuFunc(...) }
|
|
553
331
|
else if (ts.isPropertyAssignment(parent) && ts.isIdentifier(parent.name)) {
|
|
@@ -559,8 +337,8 @@ export function extractFunctionName(callExpr, checker, rootDir) {
|
|
|
559
337
|
result.propertyName = parent.name.text;
|
|
560
338
|
}
|
|
561
339
|
// 3) Handle any remaining cases for pikkuFunc({ override: '…', func: … })
|
|
562
|
-
else if (ts.isCallExpression(
|
|
563
|
-
const firstArg =
|
|
340
|
+
else if (ts.isCallExpression(callExpr)) {
|
|
341
|
+
const firstArg = callExpr.arguments[0];
|
|
564
342
|
if (firstArg && ts.isObjectLiteralExpression(firstArg)) {
|
|
565
343
|
for (const prop of firstArg.properties) {
|
|
566
344
|
if (ts.isPropertyAssignment(prop) &&
|
|
@@ -577,9 +355,14 @@ export function extractFunctionName(callExpr, checker, rootDir) {
|
|
|
577
355
|
}
|
|
578
356
|
// Apply name priority logic
|
|
579
357
|
populateNameByPriority(result);
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
358
|
+
if (result.explicitName) {
|
|
359
|
+
result.pikkuFuncId = result.explicitName;
|
|
360
|
+
}
|
|
361
|
+
else if (result.exportedName) {
|
|
362
|
+
result.pikkuFuncId = result.exportedName;
|
|
363
|
+
}
|
|
364
|
+
else {
|
|
365
|
+
result.pikkuFuncId = `__temp_${randomUUID()}`;
|
|
583
366
|
}
|
|
584
367
|
return result;
|
|
585
368
|
}
|
|
@@ -595,32 +378,44 @@ export function populateNameByPriority(result) {
|
|
|
595
378
|
else if (result.exportedName) {
|
|
596
379
|
result.name = result.exportedName;
|
|
597
380
|
}
|
|
598
|
-
// Priority 3: If we have a property name, use that
|
|
599
|
-
// else if (result.propertyName) {
|
|
600
|
-
// result.name = result.propertyName
|
|
601
|
-
// }
|
|
602
381
|
// Fallback: Use the deterministic name, but we could shorten it in the future
|
|
603
382
|
else {
|
|
604
|
-
// For now, just use the full
|
|
605
|
-
result.name = result.
|
|
383
|
+
// For now, just use the full pikkuFuncId
|
|
384
|
+
result.name = result.pikkuFuncId;
|
|
606
385
|
}
|
|
607
386
|
}
|
|
608
387
|
/**
|
|
609
388
|
* Helper function to check if a variable declaration is a named export
|
|
610
389
|
*/
|
|
611
|
-
export function isNamedExport(declaration) {
|
|
390
|
+
export function isNamedExport(declaration, checker) {
|
|
612
391
|
let parent = declaration.parent;
|
|
613
392
|
if (!parent)
|
|
614
393
|
return false;
|
|
615
|
-
// Check if it's part of a variable declaration list
|
|
616
394
|
if (ts.isVariableDeclarationList(parent)) {
|
|
617
395
|
parent = parent.parent;
|
|
618
396
|
if (!parent)
|
|
619
397
|
return false;
|
|
620
|
-
// Check if it's in an export declaration
|
|
621
398
|
if (ts.isVariableStatement(parent)) {
|
|
622
|
-
|
|
623
|
-
|
|
399
|
+
if (parent.modifiers?.some((m) => m.kind === ts.SyntaxKind.ExportKeyword)) {
|
|
400
|
+
return true;
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
if (checker && ts.isIdentifier(declaration.name)) {
|
|
405
|
+
const sourceFile = declaration.getSourceFile();
|
|
406
|
+
const sourceFileSymbol = checker.getSymbolAtLocation(sourceFile);
|
|
407
|
+
if (sourceFileSymbol) {
|
|
408
|
+
const exports = checker.getExportsOfModule(sourceFileSymbol);
|
|
409
|
+
const declSymbol = checker.getSymbolAtLocation(declaration.name);
|
|
410
|
+
if (declSymbol) {
|
|
411
|
+
return exports.some((exp) => {
|
|
412
|
+
let resolved = exp;
|
|
413
|
+
if (resolved.flags & ts.SymbolFlags.Alias) {
|
|
414
|
+
resolved = checker.getAliasedSymbol(resolved) ?? resolved;
|
|
415
|
+
}
|
|
416
|
+
return resolved === declSymbol;
|
|
417
|
+
});
|
|
418
|
+
}
|
|
624
419
|
}
|
|
625
420
|
}
|
|
626
421
|
return false;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import * as ts from 'typescript';
|
|
2
|
-
import { FunctionServicesMeta } from '@pikku/core';
|
|
2
|
+
import { FunctionServicesMeta, FunctionWiresMeta } from '@pikku/core';
|
|
3
3
|
/**
|
|
4
4
|
* Extract services from a function's first parameter destructuring pattern
|
|
5
5
|
*/
|
|
6
6
|
export declare function extractServicesFromFunction(handlerNode: ts.FunctionExpression | ts.ArrowFunction): FunctionServicesMeta;
|
|
7
|
+
export declare function extractUsedWires(handlerNode: ts.FunctionExpression | ts.ArrowFunction, paramIndex: number): FunctionWiresMeta;
|
|
@@ -21,9 +21,33 @@ export function extractServicesFromFunction(handlerNode) {
|
|
|
21
21
|
}
|
|
22
22
|
}
|
|
23
23
|
}
|
|
24
|
-
else if (ts.isIdentifier(firstParam.name)
|
|
24
|
+
else if (ts.isIdentifier(firstParam.name) &&
|
|
25
|
+
!firstParam.name.text.startsWith('_')) {
|
|
25
26
|
services.optimized = false;
|
|
26
27
|
}
|
|
27
28
|
}
|
|
28
29
|
return services;
|
|
29
30
|
}
|
|
31
|
+
export function extractUsedWires(handlerNode, paramIndex) {
|
|
32
|
+
const param = handlerNode.parameters[paramIndex];
|
|
33
|
+
if (param && ts.isObjectBindingPattern(param.name)) {
|
|
34
|
+
const wires = [];
|
|
35
|
+
for (const elem of param.name.elements) {
|
|
36
|
+
const propertyName = elem.propertyName && ts.isIdentifier(elem.propertyName)
|
|
37
|
+
? elem.propertyName.text
|
|
38
|
+
: ts.isIdentifier(elem.name)
|
|
39
|
+
? elem.name.text
|
|
40
|
+
: undefined;
|
|
41
|
+
if (propertyName) {
|
|
42
|
+
wires.push(propertyName);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
return { optimized: true, wires };
|
|
46
|
+
}
|
|
47
|
+
if (param &&
|
|
48
|
+
ts.isIdentifier(param.name) &&
|
|
49
|
+
!param.name.text.startsWith('_')) {
|
|
50
|
+
return { optimized: false, wires: [] };
|
|
51
|
+
}
|
|
52
|
+
return { optimized: true, wires: [] };
|
|
53
|
+
}
|