@pikku/inspector 0.6.4 → 0.7.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 +16 -0
- package/dist/add-channel.d.ts +12 -2
- package/dist/add-channel.js +336 -109
- package/dist/add-functions.d.ts +7 -0
- package/dist/add-functions.js +269 -0
- package/dist/add-http-route.d.ts +15 -3
- package/dist/add-http-route.js +69 -80
- package/dist/add-schedule.d.ts +1 -1
- package/dist/add-schedule.js +14 -4
- package/dist/inspector.js +14 -4
- package/dist/types.d.ts +7 -10
- package/dist/utils.d.ts +21 -27
- package/dist/utils.js +631 -211
- package/dist/visit.d.ts +2 -1
- package/dist/visit.js +9 -4
- package/package.json +2 -2
- package/src/add-channel.ts +442 -140
- package/src/add-functions.ts +376 -0
- package/src/add-http-route.ts +94 -109
- package/src/add-schedule.ts +24 -4
- package/src/inspector.ts +17 -5
- package/src/types.ts +8 -12
- package/src/utils.ts +778 -286
- package/src/visit.ts +16 -6
- package/tsconfig.tsbuildinfo +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# @pikku/inspector
|
|
2
2
|
|
|
3
|
+
## 0.7.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- ebfb786: fix: only inspect function calls with pikku\*func in name
|
|
8
|
+
|
|
9
|
+
## 0.7.0
|
|
10
|
+
|
|
11
|
+
This has changed significantly. The inspector now finds all functions and then links them to events.
|
|
12
|
+
|
|
13
|
+
This means we can now get:
|
|
14
|
+
|
|
15
|
+
- RPCs out of the box
|
|
16
|
+
- Schemas are per function, not event
|
|
17
|
+
- Supports inline functions, external functions, anonymous functions
|
|
18
|
+
|
|
3
19
|
## 0.6.4
|
|
4
20
|
|
|
5
21
|
### Patch Changes
|
package/dist/add-channel.d.ts
CHANGED
|
@@ -1,3 +1,13 @@
|
|
|
1
1
|
import * as ts from 'typescript';
|
|
2
|
-
import {
|
|
3
|
-
|
|
2
|
+
import type { ChannelMeta } from '@pikku/core/channel';
|
|
3
|
+
import type { InspectorFilters, InspectorState } from './types.js';
|
|
4
|
+
/**
|
|
5
|
+
* Build out the nested message-routes by looking up each handler
|
|
6
|
+
* in state.functions.meta instead of re-inferring it here.
|
|
7
|
+
*/
|
|
8
|
+
export declare function addMessagesRoutes(obj: ts.ObjectLiteralExpression, state: InspectorState, checker: ts.TypeChecker): ChannelMeta['messageRoutes'];
|
|
9
|
+
/**
|
|
10
|
+
* Inspect addChannel calls, look up all handlers in state.functions.meta,
|
|
11
|
+
* and emit one entry into state.channels.meta.
|
|
12
|
+
*/
|
|
13
|
+
export declare function addChannel(node: ts.Node, checker: ts.TypeChecker, state: InspectorState, filters: InspectorFilters): void;
|
package/dist/add-channel.js
CHANGED
|
@@ -2,128 +2,355 @@ import * as ts from 'typescript';
|
|
|
2
2
|
import { getPropertyValue } from './get-property-value.js';
|
|
3
3
|
import { pathToRegexp } from 'path-to-regexp';
|
|
4
4
|
import { getInputTypes } from './add-http-route.js';
|
|
5
|
-
import {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
return
|
|
5
|
+
import { extractFunctionName, getPropertyAssignmentInitializer, matchesFilters, } from './utils.js';
|
|
6
|
+
/**
|
|
7
|
+
* Safely get the “initializer” expression of a property-like AST node:
|
|
8
|
+
* - for `foo: expr`, returns `expr`
|
|
9
|
+
* - for `{ foo }` shorthand, returns the identifier `foo`
|
|
10
|
+
* - otherwise, returns undefined
|
|
11
|
+
*/
|
|
12
|
+
function getInitializerOf(elem) {
|
|
13
|
+
if (ts.isPropertyAssignment(elem)) {
|
|
14
|
+
return elem.initializer;
|
|
15
15
|
}
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
if (!ts.isObjectLiteralExpression(initializer)) {
|
|
19
|
-
console.log('onMessageRoute is not an object literal.');
|
|
20
|
-
return {};
|
|
16
|
+
if (ts.isShorthandPropertyAssignment(elem)) {
|
|
17
|
+
return elem.name;
|
|
21
18
|
}
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
19
|
+
return undefined;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Resolve a handler expression (Identifier, CallExpression, or { func })
|
|
23
|
+
* into its underlying function name.
|
|
24
|
+
*/
|
|
25
|
+
function getHandlerNameFromExpression(expr, checker) {
|
|
26
|
+
// Handle direct identifier case (which includes shorthand properties)
|
|
27
|
+
if (ts.isIdentifier(expr)) {
|
|
28
|
+
const sym = checker.getSymbolAtLocation(expr);
|
|
29
|
+
if (sym) {
|
|
30
|
+
let resolvedSym = sym;
|
|
31
|
+
if (resolvedSym.flags & ts.SymbolFlags.Alias) {
|
|
32
|
+
resolvedSym = checker.getAliasedSymbol(resolvedSym) ?? resolvedSym;
|
|
33
|
+
}
|
|
34
|
+
// Try to get declarations
|
|
35
|
+
const decls = resolvedSym.declarations ?? [];
|
|
36
|
+
if (decls.length > 0) {
|
|
37
|
+
const decl = decls[0];
|
|
38
|
+
// For variable declarations, look at the initializer
|
|
39
|
+
if (ts.isVariableDeclaration(decl) && decl.initializer) {
|
|
40
|
+
if (ts.isCallExpression(decl.initializer) ||
|
|
41
|
+
ts.isArrowFunction(decl.initializer) ||
|
|
42
|
+
ts.isFunctionExpression(decl.initializer)) {
|
|
43
|
+
// Extract function name from the declaration's initializer
|
|
44
|
+
const { pikkuFuncName } = extractFunctionName(decl.initializer, checker);
|
|
45
|
+
return pikkuFuncName;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
// For function declarations, use directly
|
|
49
|
+
else if (ts.isFunctionDeclaration(decl)) {
|
|
50
|
+
const { pikkuFuncName } = extractFunctionName(decl, checker);
|
|
51
|
+
return pikkuFuncName;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
// Fallback: try to extract directly from the identifier
|
|
56
|
+
const { pikkuFuncName } = extractFunctionName(expr, checker);
|
|
57
|
+
return pikkuFuncName;
|
|
58
|
+
}
|
|
59
|
+
// Handle call expressions
|
|
60
|
+
if (ts.isCallExpression(expr)) {
|
|
61
|
+
const { pikkuFuncName } = extractFunctionName(expr, checker);
|
|
62
|
+
return pikkuFuncName;
|
|
63
|
+
}
|
|
64
|
+
// Handle object literals with 'func' property
|
|
65
|
+
if (ts.isObjectLiteralExpression(expr)) {
|
|
66
|
+
const fnProp = getPropertyAssignmentInitializer(expr, 'func', true, checker);
|
|
67
|
+
if (fnProp) {
|
|
68
|
+
return getHandlerNameFromExpression(fnProp, checker);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
return null;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Build out the nested message-routes by looking up each handler
|
|
75
|
+
* in state.functions.meta instead of re-inferring it here.
|
|
76
|
+
*/
|
|
77
|
+
export function addMessagesRoutes(obj, state, checker) {
|
|
78
|
+
const result = {};
|
|
79
|
+
const onMsgRouteProp = getPropertyAssignmentInitializer(obj, 'onMessageRoute', true, checker);
|
|
80
|
+
if (!onMsgRouteProp)
|
|
81
|
+
return result;
|
|
82
|
+
if (!onMsgRouteProp || !ts.isObjectLiteralExpression(onMsgRouteProp))
|
|
83
|
+
return result;
|
|
84
|
+
for (const chanElem of onMsgRouteProp.properties) {
|
|
85
|
+
const chanInit = getInitializerOf(chanElem);
|
|
86
|
+
if (!chanInit || !ts.isObjectLiteralExpression(chanInit))
|
|
87
|
+
continue;
|
|
88
|
+
const channelKey = chanElem.name.getText();
|
|
89
|
+
result[channelKey] = {};
|
|
90
|
+
for (const routeElem of chanInit.properties) {
|
|
91
|
+
const init = getInitializerOf(routeElem);
|
|
92
|
+
if (!init)
|
|
93
|
+
continue;
|
|
94
|
+
const routeKey = routeElem.name.getText();
|
|
95
|
+
// For shorthand properties, we need to resolve the identifier to its declaration
|
|
96
|
+
if (ts.isShorthandPropertyAssignment(routeElem)) {
|
|
97
|
+
// Get the symbol for the shorthand property
|
|
98
|
+
const shorthandSym = checker.getShorthandAssignmentValueSymbol(routeElem);
|
|
99
|
+
if (shorthandSym &&
|
|
100
|
+
shorthandSym.declarations &&
|
|
101
|
+
shorthandSym.declarations.length > 0) {
|
|
102
|
+
const shorthandDecl = shorthandSym.declarations[0];
|
|
103
|
+
if (!shorthandDecl) {
|
|
104
|
+
throw new Error(`No declaration found for shorthand property '${routeKey}'`);
|
|
105
|
+
}
|
|
106
|
+
// Handle import specifiers
|
|
107
|
+
if (ts.isImportSpecifier(shorthandDecl)) {
|
|
108
|
+
// Get the imported symbol
|
|
109
|
+
const importedSymbol = checker.getSymbolAtLocation(shorthandDecl.name);
|
|
110
|
+
if (importedSymbol) {
|
|
111
|
+
// Try to resolve the alias to get the original symbol
|
|
112
|
+
let resolvedSymbol = importedSymbol;
|
|
113
|
+
if (resolvedSymbol.flags & ts.SymbolFlags.Alias) {
|
|
114
|
+
resolvedSymbol =
|
|
115
|
+
checker.getAliasedSymbol(resolvedSymbol) ?? resolvedSymbol;
|
|
116
|
+
}
|
|
117
|
+
// Try to get the declarations of the resolved symbol
|
|
118
|
+
const importDecls = resolvedSymbol.declarations ?? [];
|
|
119
|
+
if (importDecls.length > 0) {
|
|
120
|
+
const importDecl = importDecls[0];
|
|
121
|
+
// Handle different kinds of declarations
|
|
122
|
+
if (ts.isVariableDeclaration(importDecl) &&
|
|
123
|
+
importDecl.initializer) {
|
|
124
|
+
// Extract from the initializer if it's a function
|
|
125
|
+
if (ts.isArrowFunction(importDecl.initializer) ||
|
|
126
|
+
ts.isFunctionExpression(importDecl.initializer) ||
|
|
127
|
+
ts.isCallExpression(importDecl.initializer)) {
|
|
128
|
+
const { pikkuFuncName } = extractFunctionName(importDecl.initializer, checker);
|
|
129
|
+
const handlerName = pikkuFuncName;
|
|
130
|
+
// Look up in the registry
|
|
131
|
+
const fnMeta = state.functions.meta[handlerName];
|
|
132
|
+
if (fnMeta) {
|
|
133
|
+
result[channelKey][routeKey] = {
|
|
134
|
+
pikkuFuncName: handlerName,
|
|
135
|
+
inputs: fnMeta.inputs ?? null,
|
|
136
|
+
outputs: fnMeta.outputs ?? null,
|
|
137
|
+
};
|
|
138
|
+
continue;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
else if (ts.isFunctionDeclaration(importDecl)) {
|
|
143
|
+
// Extract from the function declaration
|
|
144
|
+
const { pikkuFuncName } = extractFunctionName(importDecl, checker);
|
|
145
|
+
const handlerName = pikkuFuncName;
|
|
146
|
+
// Look up in the registry
|
|
147
|
+
const fnMeta = state.functions.meta[handlerName];
|
|
148
|
+
if (fnMeta) {
|
|
149
|
+
result[channelKey][routeKey] = {
|
|
150
|
+
pikkuFuncName: handlerName,
|
|
151
|
+
inputs: fnMeta.inputs ?? null,
|
|
152
|
+
outputs: fnMeta.outputs ?? null,
|
|
153
|
+
};
|
|
154
|
+
continue;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
else if (ts.isExportSpecifier(importDecl)) {
|
|
158
|
+
// For re-exports, we need to follow another level of indirection
|
|
159
|
+
const exportSymbol = checker.getSymbolAtLocation(importDecl.name);
|
|
160
|
+
if (exportSymbol) {
|
|
161
|
+
let resolvedExportSymbol = exportSymbol;
|
|
162
|
+
if (resolvedExportSymbol.flags & ts.SymbolFlags.Alias) {
|
|
163
|
+
resolvedExportSymbol =
|
|
164
|
+
checker.getAliasedSymbol(resolvedExportSymbol) ??
|
|
165
|
+
resolvedExportSymbol;
|
|
166
|
+
}
|
|
167
|
+
const exportDecls = resolvedExportSymbol.declarations ?? [];
|
|
168
|
+
if (exportDecls.length > 0) {
|
|
169
|
+
const exportDecl = exportDecls[0];
|
|
170
|
+
if (ts.isVariableDeclaration(exportDecl) &&
|
|
171
|
+
exportDecl.initializer) {
|
|
172
|
+
const { pikkuFuncName } = extractFunctionName(exportDecl.initializer, checker);
|
|
173
|
+
const handlerName = pikkuFuncName;
|
|
174
|
+
const fnMeta = state.functions.meta[handlerName];
|
|
175
|
+
if (fnMeta) {
|
|
176
|
+
result[channelKey][routeKey] = {
|
|
177
|
+
pikkuFuncName: handlerName,
|
|
178
|
+
inputs: fnMeta.inputs ?? null,
|
|
179
|
+
outputs: fnMeta.outputs ?? null,
|
|
180
|
+
};
|
|
181
|
+
continue;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
else if (ts.isFunctionDeclaration(exportDecl)) {
|
|
185
|
+
const { pikkuFuncName } = extractFunctionName(exportDecl, checker);
|
|
186
|
+
const handlerName = pikkuFuncName;
|
|
187
|
+
const fnMeta = state.functions.meta[handlerName];
|
|
188
|
+
if (fnMeta) {
|
|
189
|
+
result[channelKey][routeKey] = {
|
|
190
|
+
pikkuFuncName: handlerName,
|
|
191
|
+
inputs: fnMeta.inputs ?? null,
|
|
192
|
+
outputs: fnMeta.outputs ?? null,
|
|
193
|
+
};
|
|
194
|
+
continue;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
// As a fallback, try to look up by name
|
|
203
|
+
const funcName = shorthandDecl.name.getText();
|
|
204
|
+
// Look for any function in the registry that ends with this name
|
|
205
|
+
const possibleMatch = Object.keys(state.functions.meta).find((key) => {
|
|
206
|
+
const parts = key.split('_');
|
|
207
|
+
const filename = parts[parts.length - 3] || '';
|
|
208
|
+
return filename.endsWith(funcName);
|
|
37
209
|
});
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
210
|
+
if (possibleMatch) {
|
|
211
|
+
const fnMeta = state.functions.meta[possibleMatch];
|
|
212
|
+
if (!fnMeta) {
|
|
213
|
+
console.error(`No function metadata found for handler '${possibleMatch}'`);
|
|
214
|
+
continue;
|
|
215
|
+
}
|
|
216
|
+
result[channelKey][routeKey] = {
|
|
217
|
+
pikkuFuncName: possibleMatch,
|
|
218
|
+
inputs: fnMeta.inputs ?? null,
|
|
219
|
+
outputs: fnMeta.outputs ?? null,
|
|
220
|
+
};
|
|
221
|
+
continue;
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
else {
|
|
225
|
+
// Handle other declaration types (variable, function, etc.)
|
|
226
|
+
let actualFunction = undefined;
|
|
227
|
+
if (ts.isVariableDeclaration(shorthandDecl)) {
|
|
228
|
+
// Check if it has an initializer
|
|
229
|
+
if (shorthandDecl.initializer) {
|
|
230
|
+
// If it's a function expression or similar, use that
|
|
231
|
+
if (ts.isArrowFunction(shorthandDecl.initializer) ||
|
|
232
|
+
ts.isFunctionExpression(shorthandDecl.initializer) ||
|
|
233
|
+
ts.isCallExpression(shorthandDecl.initializer)) {
|
|
234
|
+
actualFunction = shorthandDecl.initializer;
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
else if (ts.isFunctionDeclaration(shorthandDecl)) {
|
|
239
|
+
actualFunction = shorthandDecl;
|
|
240
|
+
}
|
|
241
|
+
// If we found the actual function, extract its name
|
|
242
|
+
if (actualFunction) {
|
|
243
|
+
// Extract the function name directly from the actual function
|
|
244
|
+
const { pikkuFuncName } = extractFunctionName(actualFunction, checker);
|
|
245
|
+
const handlerName = pikkuFuncName;
|
|
246
|
+
// Now use this handlerName to look up in the registry
|
|
247
|
+
const fnMeta = state.functions.meta[handlerName];
|
|
248
|
+
if (fnMeta) {
|
|
249
|
+
result[channelKey][routeKey] = {
|
|
250
|
+
pikkuFuncName: handlerName,
|
|
251
|
+
inputs: fnMeta.inputs ?? null,
|
|
252
|
+
outputs: fnMeta.outputs ?? null,
|
|
253
|
+
};
|
|
254
|
+
continue; // Skip the normal processing below
|
|
255
|
+
}
|
|
256
|
+
}
|
|
42
257
|
}
|
|
43
258
|
}
|
|
44
259
|
}
|
|
45
|
-
|
|
46
|
-
|
|
260
|
+
// Normal processing for non-shorthand properties
|
|
261
|
+
const handlerName = getHandlerNameFromExpression(init, checker);
|
|
262
|
+
if (!handlerName) {
|
|
263
|
+
console.error(`Could not resolve handler for message route '${routeKey}'`);
|
|
264
|
+
continue;
|
|
47
265
|
}
|
|
266
|
+
const fnMeta = state.functions.meta[handlerName];
|
|
267
|
+
if (!fnMeta) {
|
|
268
|
+
console.error(`No function metadata found for handler '${handlerName}'`);
|
|
269
|
+
continue;
|
|
270
|
+
}
|
|
271
|
+
result[channelKey][routeKey] = {
|
|
272
|
+
pikkuFuncName: handlerName,
|
|
273
|
+
inputs: fnMeta.inputs ?? null,
|
|
274
|
+
outputs: fnMeta.outputs ?? null,
|
|
275
|
+
};
|
|
48
276
|
}
|
|
49
|
-
else {
|
|
50
|
-
console.warn(`Property "${property.getText()}" is a ${ts.SyntaxKind[property.kind]}`);
|
|
51
|
-
}
|
|
52
|
-
});
|
|
53
|
-
return messageTypes;
|
|
54
|
-
};
|
|
55
|
-
export const addChannel = (node, checker, state, filters) => {
|
|
56
|
-
if (!ts.isCallExpression(node)) {
|
|
57
|
-
return;
|
|
58
277
|
}
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
278
|
+
return result;
|
|
279
|
+
}
|
|
280
|
+
/**
|
|
281
|
+
* Inspect addChannel calls, look up all handlers in state.functions.meta,
|
|
282
|
+
* and emit one entry into state.channels.meta.
|
|
283
|
+
*/
|
|
284
|
+
export function addChannel(node, checker, state, filters) {
|
|
285
|
+
if (!ts.isCallExpression(node))
|
|
64
286
|
return;
|
|
65
|
-
}
|
|
66
|
-
if (!
|
|
287
|
+
const { expression, arguments: args } = node;
|
|
288
|
+
if (!ts.isIdentifier(expression) || expression.text !== 'addChannel')
|
|
289
|
+
return;
|
|
290
|
+
const first = args[0];
|
|
291
|
+
if (!first || !ts.isObjectLiteralExpression(first))
|
|
292
|
+
return;
|
|
293
|
+
const obj = first;
|
|
294
|
+
const name = getPropertyValue(obj, 'name');
|
|
295
|
+
const route = getPropertyValue(obj, 'route') ?? '';
|
|
296
|
+
if (!name) {
|
|
297
|
+
console.error('Channel name is required');
|
|
67
298
|
return;
|
|
68
299
|
}
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
return result;
|
|
92
|
-
}, []);
|
|
300
|
+
// path parameters
|
|
301
|
+
const params = route
|
|
302
|
+
? pathToRegexp(route)
|
|
303
|
+
.keys.filter((k) => k.type === 'param')
|
|
304
|
+
.map((k) => k.name)
|
|
305
|
+
: [];
|
|
306
|
+
const docs = getPropertyValue(obj, 'docs');
|
|
307
|
+
const tags = getPropertyValue(obj, 'tags');
|
|
308
|
+
const query = getPropertyValue(obj, 'query');
|
|
309
|
+
if (!matchesFilters(filters, { tags }, { type: 'channel', name }))
|
|
310
|
+
return;
|
|
311
|
+
const connect = getPropertyAssignmentInitializer(obj, 'onConnect', false, checker);
|
|
312
|
+
const disconnect = getPropertyAssignmentInitializer(obj, 'onDisconnect', false, checker);
|
|
313
|
+
// default onMessage handler
|
|
314
|
+
let message = null;
|
|
315
|
+
const onMsgProp = getPropertyAssignmentInitializer(obj, 'onMessage', false, checker);
|
|
316
|
+
if (onMsgProp) {
|
|
317
|
+
const handlerName = onMsgProp && getHandlerNameFromExpression(onMsgProp, checker);
|
|
318
|
+
const fnMeta = handlerName && state.functions.meta[handlerName];
|
|
319
|
+
if (!fnMeta) {
|
|
320
|
+
console.error(`No function metadata for onMessage handler '${handlerName}'`);
|
|
321
|
+
throw new Error();
|
|
93
322
|
}
|
|
94
323
|
else {
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
const disconnect = !!getPropertyAssignment(obj, 'onDisconnect');
|
|
102
|
-
const { inputs, outputs, type } = getFunctionTypes(checker, obj, {
|
|
103
|
-
funcName: 'onMessage',
|
|
104
|
-
inputIndex: 0,
|
|
105
|
-
outputIndex: 1,
|
|
106
|
-
typesMap: state.channels.typesMap,
|
|
107
|
-
});
|
|
108
|
-
const message = { inputs, outputs, type };
|
|
109
|
-
const messageRoutes = addMessagesRoutes(obj, checker, state.channels.typesMap);
|
|
110
|
-
if (!matchesFilters(filters, { tags }, { type: 'channel', name })) {
|
|
111
|
-
return;
|
|
324
|
+
message = {
|
|
325
|
+
pikkuFuncName: extractFunctionName(onMsgProp, checker)
|
|
326
|
+
.pikkuFuncName,
|
|
327
|
+
inputs: fnMeta.inputs ?? null,
|
|
328
|
+
outputs: fnMeta.outputs ?? null,
|
|
329
|
+
};
|
|
112
330
|
}
|
|
113
|
-
state.channels.files.add(node.getSourceFile().fileName);
|
|
114
|
-
state.channels.meta.push({
|
|
115
|
-
name,
|
|
116
|
-
route,
|
|
117
|
-
input: inputType,
|
|
118
|
-
params: paramsValues.length > 0 ? paramsValues : undefined,
|
|
119
|
-
query: queryValues.length > 0 ? queryValues : undefined,
|
|
120
|
-
inputTypes: getInputTypes(state.channels.metaInputTypes, 'get', inputType, queryValues, paramsValues),
|
|
121
|
-
connect,
|
|
122
|
-
disconnect,
|
|
123
|
-
message: message || undefined,
|
|
124
|
-
messageRoutes,
|
|
125
|
-
docs,
|
|
126
|
-
tags,
|
|
127
|
-
});
|
|
128
331
|
}
|
|
129
|
-
|
|
332
|
+
// nested message-routes
|
|
333
|
+
const messageRoutes = addMessagesRoutes(obj, state, checker);
|
|
334
|
+
// record into state
|
|
335
|
+
state.channels.files.add(node.getSourceFile().fileName);
|
|
336
|
+
state.channels.meta[name] = {
|
|
337
|
+
name,
|
|
338
|
+
route,
|
|
339
|
+
input: null,
|
|
340
|
+
params: params.length ? params : undefined,
|
|
341
|
+
query: query?.length ? query : undefined,
|
|
342
|
+
inputTypes: getInputTypes(state.channels.metaInputTypes, 'get', message?.inputs?.[0] ?? null, query, params),
|
|
343
|
+
connectPikkuFuncName: connect
|
|
344
|
+
? extractFunctionName(connect, checker).pikkuFuncName
|
|
345
|
+
: null,
|
|
346
|
+
connect: !!connect,
|
|
347
|
+
disconnectPikkuFuncName: disconnect
|
|
348
|
+
? extractFunctionName(disconnect, checker).pikkuFuncName
|
|
349
|
+
: null,
|
|
350
|
+
disconnect: !!disconnect,
|
|
351
|
+
message,
|
|
352
|
+
messageRoutes,
|
|
353
|
+
docs: docs ?? undefined,
|
|
354
|
+
tags: tags ?? undefined,
|
|
355
|
+
};
|
|
356
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import * as ts from 'typescript';
|
|
2
|
+
import { InspectorState, InspectorFilters } from './types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Inspect pikkuFunc calls, extract input/output and first-arg destructuring,
|
|
5
|
+
* then push into state.functions.meta.
|
|
6
|
+
*/
|
|
7
|
+
export declare function addFunctions(node: ts.Node, checker: ts.TypeChecker, state: InspectorState, filters: InspectorFilters): void;
|