@pikku/inspector 0.11.0 → 0.11.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 -1
- package/dist/add/add-channel.js +11 -10
- package/dist/add/add-file-with-factory.js +10 -10
- package/dist/add/add-functions.js +57 -43
- package/dist/add/add-http-route.js +5 -4
- package/dist/add/add-mcp-prompt.js +6 -5
- package/dist/add/add-mcp-resource.js +6 -5
- package/dist/add/add-mcp-tool.js +6 -5
- package/dist/add/add-middleware.js +1 -1
- package/dist/add/add-permission.js +1 -1
- package/dist/add/add-queue-worker.js +6 -5
- package/dist/add/add-schedule.js +5 -4
- package/dist/add/add-workflow.d.ts +1 -1
- package/dist/add/add-workflow.js +92 -66
- package/dist/error-codes.d.ts +1 -0
- package/dist/error-codes.js +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +1 -0
- package/dist/inspector.js +10 -6
- package/dist/types.d.ts +21 -8
- package/dist/utils/extract-function-node.d.ts +10 -0
- package/dist/utils/extract-function-node.js +38 -0
- package/dist/utils/extract-node-value.d.ts +8 -0
- package/dist/utils/extract-node-value.js +24 -0
- package/dist/utils/extract-service-metadata.d.ts +19 -0
- package/dist/utils/extract-service-metadata.js +244 -0
- package/dist/utils/get-files-and-methods.d.ts +3 -3
- package/dist/utils/get-files-and-methods.js +3 -3
- package/dist/utils/get-property-value.d.ts +13 -6
- package/dist/utils/get-property-value.js +51 -43
- package/dist/utils/post-process.d.ts +9 -0
- package/dist/utils/post-process.js +30 -3
- package/dist/utils/serialize-inspector-state.d.ts +18 -5
- package/dist/utils/serialize-inspector-state.js +12 -10
- package/dist/utils/write-service-metadata.d.ts +13 -0
- package/dist/utils/write-service-metadata.js +37 -0
- package/dist/visit.js +2 -2
- package/dist/workflow/extract-simple-workflow.d.ts +15 -0
- package/dist/workflow/extract-simple-workflow.js +803 -0
- package/dist/workflow/patterns.d.ts +39 -0
- package/dist/workflow/patterns.js +138 -0
- package/dist/workflow/validation.d.ts +28 -0
- package/dist/workflow/validation.js +124 -0
- package/package.json +4 -4
- package/src/add/add-channel.ts +37 -17
- package/src/add/add-file-with-factory.ts +10 -10
- package/src/add/add-functions.ts +72 -56
- package/src/add/add-http-route.ts +10 -5
- package/src/add/add-mcp-prompt.ts +11 -7
- package/src/add/add-mcp-resource.ts +11 -7
- package/src/add/add-mcp-tool.ts +11 -7
- package/src/add/add-middleware.ts +1 -1
- package/src/add/add-permission.ts +1 -1
- package/src/add/add-queue-worker.ts +11 -12
- package/src/add/add-schedule.ts +10 -5
- package/src/add/add-workflow.ts +120 -110
- package/src/error-codes.ts +1 -0
- package/src/index.ts +2 -0
- package/src/inspector.ts +16 -6
- package/src/types.ts +18 -8
- package/src/utils/extract-function-node.ts +58 -0
- package/src/utils/extract-node-value.ts +31 -0
- package/src/utils/extract-service-metadata.ts +353 -0
- package/src/utils/filter-inspector-state.test.ts +3 -3
- package/src/utils/filter-utils.test.ts +45 -51
- package/src/utils/get-files-and-methods.ts +11 -11
- package/src/utils/get-property-value.ts +60 -53
- package/src/utils/permissions.test.ts +3 -3
- package/src/utils/post-process.ts +56 -3
- package/src/utils/serialize-inspector-state.ts +28 -18
- package/src/utils/test-data/inspector-state.json +9 -9
- package/src/utils/write-service-metadata.ts +51 -0
- package/src/visit.ts +3 -3
- package/src/workflow/extract-simple-workflow.ts +1035 -0
- package/src/workflow/patterns.ts +182 -0
- package/src/workflow/validation.ts +153 -0
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import * as ts from 'typescript';
|
|
2
|
+
/**
|
|
3
|
+
* Pattern detection helpers for simple workflow extraction
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Check if a call expression is workflow.do()
|
|
7
|
+
*/
|
|
8
|
+
export declare function isWorkflowDoCall(node: ts.CallExpression, checker: ts.TypeChecker): boolean;
|
|
9
|
+
/**
|
|
10
|
+
* Check if a call expression is workflow.sleep()
|
|
11
|
+
*/
|
|
12
|
+
export declare function isWorkflowSleepCall(node: ts.CallExpression, checker: ts.TypeChecker): boolean;
|
|
13
|
+
/**
|
|
14
|
+
* Check if an expression is Promise.all(array.map(...))
|
|
15
|
+
*/
|
|
16
|
+
export declare function isParallelFanout(node: ts.CallExpression): boolean;
|
|
17
|
+
/**
|
|
18
|
+
* Check if an expression is Promise.all([...])
|
|
19
|
+
*/
|
|
20
|
+
export declare function isParallelGroup(node: ts.CallExpression): boolean;
|
|
21
|
+
/**
|
|
22
|
+
* Check if a for statement is a valid sequential fanout (for..of)
|
|
23
|
+
*/
|
|
24
|
+
export declare function isSequentialFanout(node: ts.ForOfStatement): boolean;
|
|
25
|
+
/**
|
|
26
|
+
* Extract the variable name from a for..of statement
|
|
27
|
+
*/
|
|
28
|
+
export declare function extractForOfVariable(node: ts.ForOfStatement): {
|
|
29
|
+
itemVar: string;
|
|
30
|
+
sourceVar: string;
|
|
31
|
+
} | null;
|
|
32
|
+
/**
|
|
33
|
+
* Check if a type is an array type
|
|
34
|
+
*/
|
|
35
|
+
export declare function isArrayType(type: ts.Type, checker: ts.TypeChecker): boolean;
|
|
36
|
+
/**
|
|
37
|
+
* Get the source text of a node (for condition expressions)
|
|
38
|
+
*/
|
|
39
|
+
export declare function getSourceText(node: ts.Node): string;
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import * as ts from 'typescript';
|
|
2
|
+
/**
|
|
3
|
+
* Pattern detection helpers for simple workflow extraction
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Check if a call expression is workflow.do()
|
|
7
|
+
*/
|
|
8
|
+
export function isWorkflowDoCall(node, checker) {
|
|
9
|
+
if (!ts.isPropertyAccessExpression(node.expression)) {
|
|
10
|
+
return false;
|
|
11
|
+
}
|
|
12
|
+
const propAccess = node.expression;
|
|
13
|
+
return (propAccess.name.text === 'do' &&
|
|
14
|
+
ts.isIdentifier(propAccess.expression) &&
|
|
15
|
+
propAccess.expression.text === 'workflow');
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Check if a call expression is workflow.sleep()
|
|
19
|
+
*/
|
|
20
|
+
export function isWorkflowSleepCall(node, checker) {
|
|
21
|
+
if (!ts.isPropertyAccessExpression(node.expression)) {
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
24
|
+
const propAccess = node.expression;
|
|
25
|
+
return (propAccess.name.text === 'sleep' &&
|
|
26
|
+
ts.isIdentifier(propAccess.expression) &&
|
|
27
|
+
propAccess.expression.text === 'workflow');
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Check if an expression is Promise.all(array.map(...))
|
|
31
|
+
*/
|
|
32
|
+
export function isParallelFanout(node) {
|
|
33
|
+
// Promise.all(...)
|
|
34
|
+
if (!ts.isPropertyAccessExpression(node.expression)) {
|
|
35
|
+
return false;
|
|
36
|
+
}
|
|
37
|
+
const propAccess = node.expression;
|
|
38
|
+
if (!ts.isIdentifier(propAccess.expression) ||
|
|
39
|
+
propAccess.expression.text !== 'Promise' ||
|
|
40
|
+
propAccess.name.text !== 'all') {
|
|
41
|
+
return false;
|
|
42
|
+
}
|
|
43
|
+
// Check if argument is array.map(...)
|
|
44
|
+
const arg = node.arguments[0];
|
|
45
|
+
if (!arg || !ts.isCallExpression(arg)) {
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
if (!ts.isPropertyAccessExpression(arg.expression)) {
|
|
49
|
+
return false;
|
|
50
|
+
}
|
|
51
|
+
return arg.expression.name.text === 'map';
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Check if an expression is Promise.all([...])
|
|
55
|
+
*/
|
|
56
|
+
export function isParallelGroup(node) {
|
|
57
|
+
// Promise.all(...)
|
|
58
|
+
if (!ts.isPropertyAccessExpression(node.expression)) {
|
|
59
|
+
return false;
|
|
60
|
+
}
|
|
61
|
+
const propAccess = node.expression;
|
|
62
|
+
if (!ts.isIdentifier(propAccess.expression) ||
|
|
63
|
+
propAccess.expression.text !== 'Promise' ||
|
|
64
|
+
propAccess.name.text !== 'all') {
|
|
65
|
+
return false;
|
|
66
|
+
}
|
|
67
|
+
// Check if argument is an array literal
|
|
68
|
+
const arg = node.arguments[0];
|
|
69
|
+
return !!arg && ts.isArrayLiteralExpression(arg);
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Check if a for statement is a valid sequential fanout (for..of)
|
|
73
|
+
*/
|
|
74
|
+
export function isSequentialFanout(node) {
|
|
75
|
+
// Must have const declaration
|
|
76
|
+
if (!ts.isVariableDeclarationList(node.initializer)) {
|
|
77
|
+
return false;
|
|
78
|
+
}
|
|
79
|
+
const declList = node.initializer;
|
|
80
|
+
if (!(declList.flags & ts.NodeFlags.Const)) {
|
|
81
|
+
return false;
|
|
82
|
+
}
|
|
83
|
+
// Must have exactly one declaration
|
|
84
|
+
if (declList.declarations.length !== 1) {
|
|
85
|
+
return false;
|
|
86
|
+
}
|
|
87
|
+
return true;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Extract the variable name from a for..of statement
|
|
91
|
+
*/
|
|
92
|
+
export function extractForOfVariable(node) {
|
|
93
|
+
if (!ts.isVariableDeclarationList(node.initializer)) {
|
|
94
|
+
return null;
|
|
95
|
+
}
|
|
96
|
+
const decl = node.initializer.declarations[0];
|
|
97
|
+
if (!ts.isIdentifier(decl.name)) {
|
|
98
|
+
return null;
|
|
99
|
+
}
|
|
100
|
+
const itemVar = decl.name.text;
|
|
101
|
+
// Extract source variable
|
|
102
|
+
let sourceVar = null;
|
|
103
|
+
if (ts.isIdentifier(node.expression)) {
|
|
104
|
+
sourceVar = node.expression.text;
|
|
105
|
+
}
|
|
106
|
+
else if (ts.isPropertyAccessExpression(node.expression) &&
|
|
107
|
+
ts.isIdentifier(node.expression.expression)) {
|
|
108
|
+
// Handle data.memberEmails
|
|
109
|
+
sourceVar = node.expression.expression.text;
|
|
110
|
+
}
|
|
111
|
+
if (!sourceVar) {
|
|
112
|
+
return null;
|
|
113
|
+
}
|
|
114
|
+
return { itemVar, sourceVar };
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Check if a type is an array type
|
|
118
|
+
*/
|
|
119
|
+
export function isArrayType(type, checker) {
|
|
120
|
+
// Check if it's an array type
|
|
121
|
+
if (checker.isArrayType(type)) {
|
|
122
|
+
return true;
|
|
123
|
+
}
|
|
124
|
+
// Check if it's a tuple type
|
|
125
|
+
if (type.flags & ts.TypeFlags.Object) {
|
|
126
|
+
const objectType = type;
|
|
127
|
+
if (objectType.objectFlags & ts.ObjectFlags.Tuple) {
|
|
128
|
+
return true;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
return false;
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Get the source text of a node (for condition expressions)
|
|
135
|
+
*/
|
|
136
|
+
export function getSourceText(node) {
|
|
137
|
+
return node.getText().trim();
|
|
138
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import * as ts from 'typescript';
|
|
2
|
+
/**
|
|
3
|
+
* Validation rules for simple workflows
|
|
4
|
+
*/
|
|
5
|
+
export interface ValidationError {
|
|
6
|
+
message: string;
|
|
7
|
+
node: ts.Node;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Check if a node contains only allowed patterns
|
|
11
|
+
*
|
|
12
|
+
* Allowed patterns:
|
|
13
|
+
* - VariableStatement (const/let declarations)
|
|
14
|
+
* - ExpressionStatement (await workflow.do, await workflow.sleep, await Promise.all)
|
|
15
|
+
* - IfStatement (branches)
|
|
16
|
+
* - ForOfStatement (sequential fanout)
|
|
17
|
+
* - ReturnStatement
|
|
18
|
+
* - Block (containers)
|
|
19
|
+
*/
|
|
20
|
+
export declare function validateNoDisallowedPatterns(node: ts.Node): ValidationError[];
|
|
21
|
+
/**
|
|
22
|
+
* Validate that all workflow.do calls are awaited
|
|
23
|
+
*/
|
|
24
|
+
export declare function validateAwaitedCalls(node: ts.Node): ValidationError[];
|
|
25
|
+
/**
|
|
26
|
+
* Combine all validation errors into a single error message
|
|
27
|
+
*/
|
|
28
|
+
export declare function formatValidationErrors(errors: ValidationError[]): string;
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import * as ts from 'typescript';
|
|
2
|
+
/**
|
|
3
|
+
* Check if a node contains only allowed patterns
|
|
4
|
+
*
|
|
5
|
+
* Allowed patterns:
|
|
6
|
+
* - VariableStatement (const/let declarations)
|
|
7
|
+
* - ExpressionStatement (await workflow.do, await workflow.sleep, await Promise.all)
|
|
8
|
+
* - IfStatement (branches)
|
|
9
|
+
* - ForOfStatement (sequential fanout)
|
|
10
|
+
* - ReturnStatement
|
|
11
|
+
* - Block (containers)
|
|
12
|
+
*/
|
|
13
|
+
export function validateNoDisallowedPatterns(node) {
|
|
14
|
+
const errors = [];
|
|
15
|
+
function visitBlock(block) {
|
|
16
|
+
for (const statement of block.statements) {
|
|
17
|
+
if (ts.isVariableStatement(statement) ||
|
|
18
|
+
ts.isExpressionStatement(statement) ||
|
|
19
|
+
ts.isIfStatement(statement) ||
|
|
20
|
+
ts.isForOfStatement(statement) ||
|
|
21
|
+
ts.isReturnStatement(statement)) {
|
|
22
|
+
// Allowed statement type - recurse into it
|
|
23
|
+
visitNode(statement);
|
|
24
|
+
}
|
|
25
|
+
else {
|
|
26
|
+
// Unknown/disallowed statement type
|
|
27
|
+
const nodeType = ts.SyntaxKind[statement.kind];
|
|
28
|
+
errors.push({
|
|
29
|
+
message: `Statement type '${nodeType}' is not allowed in simple workflows. Allowed: const/let, if/else, for..of, return, and workflow calls. If this should be supported, please report the node type: ${nodeType}`,
|
|
30
|
+
node: statement,
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
function visitNode(node) {
|
|
36
|
+
// Disallow while and do-while
|
|
37
|
+
if (ts.isWhileStatement(node) || ts.isDoStatement(node)) {
|
|
38
|
+
errors.push({
|
|
39
|
+
message: 'while and do-while loops are not allowed in simple workflows',
|
|
40
|
+
node,
|
|
41
|
+
});
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
// Disallow for and for-in loops
|
|
45
|
+
if (ts.isForInStatement(node) || ts.isForStatement(node)) {
|
|
46
|
+
errors.push({
|
|
47
|
+
message: 'for and for-in loops are not allowed in simple workflows. Use for-of instead.',
|
|
48
|
+
node,
|
|
49
|
+
});
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
// Check for inline workflow.do
|
|
53
|
+
if (ts.isCallExpression(node)) {
|
|
54
|
+
if (ts.isPropertyAccessExpression(node.expression)) {
|
|
55
|
+
const propAccess = node.expression;
|
|
56
|
+
if (propAccess.name.text === 'do' &&
|
|
57
|
+
ts.isIdentifier(propAccess.expression) &&
|
|
58
|
+
propAccess.expression.text === 'workflow') {
|
|
59
|
+
const secondArg = node.arguments[1];
|
|
60
|
+
if (secondArg &&
|
|
61
|
+
(ts.isArrowFunction(secondArg) ||
|
|
62
|
+
ts.isFunctionExpression(secondArg))) {
|
|
63
|
+
errors.push({
|
|
64
|
+
message: 'Inline workflow.do with function argument is not allowed in simple workflows. Use RPC form instead.',
|
|
65
|
+
node,
|
|
66
|
+
});
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
// Recurse into blocks
|
|
73
|
+
if (ts.isBlock(node)) {
|
|
74
|
+
visitBlock(node);
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
ts.forEachChild(node, visitNode);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
visitNode(node);
|
|
81
|
+
return errors;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Validate that all workflow.do calls are awaited
|
|
85
|
+
*/
|
|
86
|
+
export function validateAwaitedCalls(node) {
|
|
87
|
+
const errors = [];
|
|
88
|
+
function visit(node, parentIsAwait = false) {
|
|
89
|
+
if (ts.isCallExpression(node)) {
|
|
90
|
+
if (ts.isPropertyAccessExpression(node.expression)) {
|
|
91
|
+
const propAccess = node.expression;
|
|
92
|
+
if ((propAccess.name.text === 'do' || propAccess.name.text === 'sleep') &&
|
|
93
|
+
ts.isIdentifier(propAccess.expression) &&
|
|
94
|
+
propAccess.expression.text === 'workflow') {
|
|
95
|
+
if (!parentIsAwait) {
|
|
96
|
+
errors.push({
|
|
97
|
+
message: `workflow.${propAccess.name.text}() must be awaited`,
|
|
98
|
+
node,
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
if (ts.isAwaitExpression(node)) {
|
|
106
|
+
// Mark child as awaited
|
|
107
|
+
ts.forEachChild(node.expression, (child) => visit(child, true));
|
|
108
|
+
}
|
|
109
|
+
else {
|
|
110
|
+
ts.forEachChild(node, (child) => visit(child, false));
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
visit(node);
|
|
114
|
+
return errors;
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Combine all validation errors into a single error message
|
|
118
|
+
*/
|
|
119
|
+
export function formatValidationErrors(errors) {
|
|
120
|
+
if (errors.length === 0) {
|
|
121
|
+
return '';
|
|
122
|
+
}
|
|
123
|
+
return errors.map((err) => `- ${err.message}`).join('\n');
|
|
124
|
+
}
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pikku/inspector",
|
|
3
|
-
"version": "0.11.
|
|
3
|
+
"version": "0.11.1",
|
|
4
4
|
"author": "yasser.fadl@gmail.com",
|
|
5
|
-
"license": "
|
|
5
|
+
"license": "BUSL-1.1",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"module": "dist/index.js",
|
|
8
8
|
"main": "dist/index.js",
|
|
@@ -16,12 +16,12 @@
|
|
|
16
16
|
"test:coverage": "bash run-tests.sh --coverage"
|
|
17
17
|
},
|
|
18
18
|
"dependencies": {
|
|
19
|
-
"@pikku/core": "^0.11.
|
|
19
|
+
"@pikku/core": "^0.11.1",
|
|
20
20
|
"path-to-regexp": "^8.3.0",
|
|
21
21
|
"typescript": "^5.9"
|
|
22
22
|
},
|
|
23
23
|
"devDependencies": {
|
|
24
|
-
"@types/node": "^24.
|
|
24
|
+
"@types/node": "^24.10.1"
|
|
25
25
|
},
|
|
26
26
|
"engines": {
|
|
27
27
|
"node": ">=18"
|
package/src/add/add-channel.ts
CHANGED
|
@@ -2,10 +2,9 @@ import * as ts from 'typescript'
|
|
|
2
2
|
import { ErrorCode } from '../error-codes.js'
|
|
3
3
|
import {
|
|
4
4
|
getPropertyValue,
|
|
5
|
-
|
|
5
|
+
getCommonWireMetaData,
|
|
6
6
|
} from '../utils/get-property-value.js'
|
|
7
7
|
import { pathToRegexp } from 'path-to-regexp'
|
|
8
|
-
import { PikkuDocs } from '@pikku/core'
|
|
9
8
|
import { extractFunctionName } from '../utils/extract-function-name.js'
|
|
10
9
|
import { getPropertyAssignmentInitializer } from '../utils/type-utils.js'
|
|
11
10
|
import type { ChannelMessageMeta, ChannelMeta } from '@pikku/core/channel'
|
|
@@ -206,7 +205,12 @@ export function addMessagesRoutes(
|
|
|
206
205
|
if (fnMeta) {
|
|
207
206
|
// Resolve middleware for this route
|
|
208
207
|
const routeTags = ts.isObjectLiteralExpression(init)
|
|
209
|
-
?
|
|
208
|
+
? getCommonWireMetaData(
|
|
209
|
+
init,
|
|
210
|
+
'Channel message',
|
|
211
|
+
routeKey,
|
|
212
|
+
logger
|
|
213
|
+
).tags
|
|
210
214
|
: undefined
|
|
211
215
|
const routeMiddleware = ts.isObjectLiteralExpression(init)
|
|
212
216
|
? resolveMiddleware(state, init, routeTags, checker)
|
|
@@ -233,7 +237,12 @@ export function addMessagesRoutes(
|
|
|
233
237
|
if (fnMeta) {
|
|
234
238
|
// Resolve middleware for this route
|
|
235
239
|
const routeTags = ts.isObjectLiteralExpression(init)
|
|
236
|
-
?
|
|
240
|
+
? getCommonWireMetaData(
|
|
241
|
+
init,
|
|
242
|
+
'Channel message',
|
|
243
|
+
routeKey,
|
|
244
|
+
logger
|
|
245
|
+
).tags
|
|
237
246
|
: undefined
|
|
238
247
|
const routeMiddleware = ts.isObjectLiteralExpression(init)
|
|
239
248
|
? resolveMiddleware(state, init, routeTags, checker)
|
|
@@ -277,12 +286,12 @@ export function addMessagesRoutes(
|
|
|
277
286
|
if (fnMeta) {
|
|
278
287
|
// Resolve middleware for this route
|
|
279
288
|
const routeTags = ts.isObjectLiteralExpression(init)
|
|
280
|
-
?
|
|
289
|
+
? getCommonWireMetaData(
|
|
281
290
|
init,
|
|
282
|
-
'
|
|
283
|
-
|
|
291
|
+
'Channel message',
|
|
292
|
+
routeKey,
|
|
284
293
|
logger
|
|
285
|
-
)
|
|
294
|
+
).tags
|
|
286
295
|
: undefined
|
|
287
296
|
const routeMiddleware = ts.isObjectLiteralExpression(
|
|
288
297
|
init
|
|
@@ -308,12 +317,12 @@ export function addMessagesRoutes(
|
|
|
308
317
|
if (fnMeta) {
|
|
309
318
|
// Resolve middleware for this route
|
|
310
319
|
const routeTags = ts.isObjectLiteralExpression(init)
|
|
311
|
-
?
|
|
320
|
+
? getCommonWireMetaData(
|
|
312
321
|
init,
|
|
313
|
-
'
|
|
314
|
-
|
|
322
|
+
'Channel message',
|
|
323
|
+
routeKey,
|
|
315
324
|
logger
|
|
316
|
-
)
|
|
325
|
+
).tags
|
|
317
326
|
: undefined
|
|
318
327
|
const routeMiddleware = ts.isObjectLiteralExpression(
|
|
319
328
|
init
|
|
@@ -396,7 +405,12 @@ export function addMessagesRoutes(
|
|
|
396
405
|
if (fnMeta) {
|
|
397
406
|
// Resolve middleware for this route
|
|
398
407
|
const routeTags = ts.isObjectLiteralExpression(init)
|
|
399
|
-
?
|
|
408
|
+
? getCommonWireMetaData(
|
|
409
|
+
init,
|
|
410
|
+
'Channel message',
|
|
411
|
+
routeKey,
|
|
412
|
+
logger
|
|
413
|
+
).tags
|
|
400
414
|
: undefined
|
|
401
415
|
const routeMiddleware = ts.isObjectLiteralExpression(init)
|
|
402
416
|
? resolveMiddleware(state, init, routeTags, checker)
|
|
@@ -438,7 +452,7 @@ export function addMessagesRoutes(
|
|
|
438
452
|
// Resolve middleware and permissions for this route
|
|
439
453
|
// Check if the route config is an object literal with middleware/permissions
|
|
440
454
|
const routeTags = ts.isObjectLiteralExpression(init)
|
|
441
|
-
?
|
|
455
|
+
? getCommonWireMetaData(init, 'Channel message', routeKey, logger).tags
|
|
442
456
|
: undefined
|
|
443
457
|
const routeMiddleware = ts.isObjectLiteralExpression(init)
|
|
444
458
|
? resolveMiddleware(state, init, routeTags, checker)
|
|
@@ -487,8 +501,12 @@ export const addChannel: AddWiring = (
|
|
|
487
501
|
.map((k) => k.name)
|
|
488
502
|
: []
|
|
489
503
|
|
|
490
|
-
const
|
|
491
|
-
|
|
504
|
+
const { tags, summary, description, errors } = getCommonWireMetaData(
|
|
505
|
+
obj,
|
|
506
|
+
'Channel',
|
|
507
|
+
name,
|
|
508
|
+
logger
|
|
509
|
+
)
|
|
492
510
|
const query = getPropertyValue(obj, 'query') as string[] | []
|
|
493
511
|
|
|
494
512
|
const connect = getPropertyAssignmentInitializer(
|
|
@@ -602,7 +620,9 @@ export const addChannel: AddWiring = (
|
|
|
602
620
|
: null,
|
|
603
621
|
message,
|
|
604
622
|
messageWirings,
|
|
605
|
-
|
|
623
|
+
summary,
|
|
624
|
+
description,
|
|
625
|
+
errors,
|
|
606
626
|
tags: tags ?? undefined,
|
|
607
627
|
middleware,
|
|
608
628
|
}
|
|
@@ -6,7 +6,7 @@ import { extractServicesFromFunction } from '../utils/extract-services.js'
|
|
|
6
6
|
const wrapperFunctionMap: Record<string, string> = {
|
|
7
7
|
pikkuConfig: 'CreateConfig',
|
|
8
8
|
pikkuServices: 'CreateSingletonServices',
|
|
9
|
-
|
|
9
|
+
pikkuWireServices: 'CreateWireServices',
|
|
10
10
|
}
|
|
11
11
|
|
|
12
12
|
export const addFileWithFactory = (
|
|
@@ -54,9 +54,9 @@ export const addFileWithFactory = (
|
|
|
54
54
|
})
|
|
55
55
|
methods.set(fileName, variables)
|
|
56
56
|
|
|
57
|
-
// Extract singleton services for
|
|
57
|
+
// Extract singleton services for CreateWireServices factories
|
|
58
58
|
if (
|
|
59
|
-
expectedTypeName === '
|
|
59
|
+
expectedTypeName === 'CreateWireServices' &&
|
|
60
60
|
state &&
|
|
61
61
|
callExpression.arguments.length > 0
|
|
62
62
|
) {
|
|
@@ -74,7 +74,7 @@ export const addFileWithFactory = (
|
|
|
74
74
|
|
|
75
75
|
if (functionNode) {
|
|
76
76
|
const servicesMeta = extractServicesFromFunction(functionNode)
|
|
77
|
-
state.
|
|
77
|
+
state.wireServicesMeta.set(variableName, servicesMeta.services)
|
|
78
78
|
}
|
|
79
79
|
}
|
|
80
80
|
|
|
@@ -109,9 +109,9 @@ export const addFileWithFactory = (
|
|
|
109
109
|
})
|
|
110
110
|
methods.set(fileName, variables)
|
|
111
111
|
|
|
112
|
-
// Extract singleton services for
|
|
112
|
+
// Extract singleton services for CreateWireServices factories
|
|
113
113
|
if (
|
|
114
|
-
expectedTypeName === '
|
|
114
|
+
expectedTypeName === 'CreateWireServices' &&
|
|
115
115
|
state &&
|
|
116
116
|
node.initializer
|
|
117
117
|
) {
|
|
@@ -124,7 +124,7 @@ export const addFileWithFactory = (
|
|
|
124
124
|
|
|
125
125
|
if (functionNode) {
|
|
126
126
|
const servicesMeta = extractServicesFromFunction(functionNode)
|
|
127
|
-
state.
|
|
127
|
+
state.wireServicesMeta.set(variableName, servicesMeta.services)
|
|
128
128
|
}
|
|
129
129
|
}
|
|
130
130
|
}
|
|
@@ -149,9 +149,9 @@ export const addFileWithFactory = (
|
|
|
149
149
|
})
|
|
150
150
|
methods.set(fileName, variables)
|
|
151
151
|
|
|
152
|
-
// Extract singleton services for
|
|
152
|
+
// Extract singleton services for CreateWireServices factories
|
|
153
153
|
if (
|
|
154
|
-
expectedTypeName === '
|
|
154
|
+
expectedTypeName === 'CreateWireServices' &&
|
|
155
155
|
state &&
|
|
156
156
|
node.initializer
|
|
157
157
|
) {
|
|
@@ -167,7 +167,7 @@ export const addFileWithFactory = (
|
|
|
167
167
|
|
|
168
168
|
if (functionNode) {
|
|
169
169
|
const servicesMeta = extractServicesFromFunction(functionNode)
|
|
170
|
-
state.
|
|
170
|
+
state.wireServicesMeta.set(variableName, servicesMeta.services)
|
|
171
171
|
}
|
|
172
172
|
}
|
|
173
173
|
}
|