@pikku/inspector 0.9.4 → 0.9.6-next.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 +14 -0
- package/dist/{add-channel.d.ts → add/add-channel.d.ts} +2 -2
- package/dist/{add-channel.js → add/add-channel.js} +12 -5
- package/dist/add/add-cli.d.ts +5 -0
- package/dist/add/add-cli.js +461 -0
- package/dist/{add-file-extends-core-type.d.ts → add/add-file-extends-core-type.d.ts} +2 -2
- package/dist/{add-file-extends-core-type.js → add/add-file-extends-core-type.js} +17 -5
- package/dist/{add-file-with-config.d.ts → add/add-file-with-config.d.ts} +1 -1
- package/dist/{add-file-with-config.js → add/add-file-with-config.js} +1 -1
- package/dist/{add-file-with-factory.d.ts → add/add-file-with-factory.d.ts} +1 -1
- package/dist/{add-file-with-factory.js → add/add-file-with-factory.js} +4 -4
- package/dist/add/add-functions.d.ts +6 -0
- package/dist/{add-functions.js → add/add-functions.js} +26 -6
- package/dist/{add-http-route.d.ts → add/add-http-route.d.ts} +2 -3
- package/dist/{add-http-route.js → add/add-http-route.js} +10 -4
- package/dist/add/add-mcp-prompt.d.ts +2 -0
- package/dist/{add-mcp-prompt.js → add/add-mcp-prompt.js} +10 -4
- package/dist/add/add-mcp-resource.d.ts +2 -0
- package/dist/{add-mcp-resource.js → add/add-mcp-resource.js} +10 -4
- package/dist/add/add-mcp-tool.d.ts +2 -0
- package/dist/{add-mcp-tool.js → add/add-mcp-tool.js} +10 -4
- package/dist/add/add-middleware.d.ts +5 -0
- package/dist/add/add-middleware.js +251 -0
- package/dist/add/add-permission.d.ts +6 -0
- package/dist/{add-permission.js → add/add-permission.js} +4 -3
- package/dist/add/add-queue-worker.d.ts +2 -0
- package/dist/{add-queue-worker.js → add/add-queue-worker.js} +10 -4
- package/dist/{add-rpc-invocations.d.ts → add/add-rpc-invocations.d.ts} +1 -1
- package/dist/add/add-schedule.d.ts +2 -0
- package/dist/{add-schedule.js → add/add-schedule.js} +10 -4
- package/dist/index.d.ts +2 -0
- package/dist/index.js +1 -0
- package/dist/inspector.d.ts +2 -3
- package/dist/inspector.js +19 -8
- package/dist/types.d.ts +79 -0
- package/dist/{utils.d.ts → utils/extract-function-name.d.ts} +7 -15
- package/dist/{utils.js → utils/extract-function-name.js} +23 -142
- package/dist/utils/extract-services.d.ts +6 -0
- package/dist/utils/extract-services.js +29 -0
- package/dist/utils/filter-utils.d.ts +9 -0
- package/dist/utils/filter-utils.js +45 -0
- package/dist/utils/get-files-and-methods.d.ts +21 -0
- package/dist/utils/get-files-and-methods.js +60 -0
- package/dist/utils/middleware.d.ts +39 -0
- package/dist/utils/middleware.js +157 -0
- package/dist/utils/type-utils.d.ts +3 -0
- package/dist/utils/type-utils.js +50 -0
- package/dist/visit.d.ts +3 -3
- package/dist/visit.js +33 -30
- package/package.json +3 -4
- package/run-tests.sh +1 -1
- package/src/{add-channel.ts → add/add-channel.ts} +19 -19
- package/src/add/add-cli.ts +663 -0
- package/src/{add-file-extends-core-type.ts → add/add-file-extends-core-type.ts} +21 -6
- package/src/{add-file-with-config.ts → add/add-file-with-config.ts} +2 -2
- package/src/{add-file-with-factory.ts → add/add-file-with-factory.ts} +5 -5
- package/src/{add-functions.ts → add/add-functions.ts} +30 -15
- package/src/{add-http-route.ts → add/add-http-route.ts} +23 -14
- package/src/{add-mcp-prompt.ts → add/add-mcp-prompt.ts} +18 -15
- package/src/{add-mcp-resource.ts → add/add-mcp-resource.ts} +18 -15
- package/src/{add-mcp-tool.ts → add/add-mcp-tool.ts} +18 -15
- package/src/add/add-middleware.ts +326 -0
- package/src/{add-permission.ts → add/add-permission.ts} +4 -8
- package/src/{add-queue-worker.ts → add/add-queue-worker.ts} +17 -14
- package/src/{add-rpc-invocations.ts → add/add-rpc-invocations.ts} +1 -1
- package/src/{add-schedule.ts → add/add-schedule.ts} +17 -14
- package/src/index.ts +5 -0
- package/src/inspector.ts +20 -17
- package/src/types.ts +92 -0
- package/src/{utils.ts → utils/extract-function-name.ts} +25 -199
- package/src/utils/extract-services.ts +35 -0
- package/src/{utils.test.ts → utils/filter-utils.test.ts} +2 -2
- package/src/utils/filter-utils.ts +72 -0
- package/src/utils/get-files-and-methods.ts +143 -0
- package/src/utils/middleware.ts +234 -0
- package/src/utils/type-utils.ts +74 -0
- package/src/visit.ts +47 -33
- package/tsconfig.tsbuildinfo +1 -1
- package/dist/add-functions.d.ts +0 -7
- package/dist/add-mcp-prompt.d.ts +0 -3
- package/dist/add-mcp-resource.d.ts +0 -3
- package/dist/add-mcp-tool.d.ts +0 -3
- package/dist/add-middleware.d.ts +0 -7
- package/dist/add-middleware.js +0 -35
- package/dist/add-permission.d.ts +0 -7
- package/dist/add-queue-worker.d.ts +0 -3
- package/dist/add-schedule.d.ts +0 -3
- package/src/add-middleware.ts +0 -51
- /package/dist/{add-rpc-invocations.js → add/add-rpc-invocations.js} +0 -0
- /package/dist/{does-type-extend-core-type.d.ts → utils/does-type-extend-core-type.d.ts} +0 -0
- /package/dist/{does-type-extend-core-type.js → utils/does-type-extend-core-type.js} +0 -0
- /package/dist/{get-property-value.d.ts → utils/get-property-value.d.ts} +0 -0
- /package/dist/{get-property-value.js → utils/get-property-value.js} +0 -0
- /package/src/{does-type-extend-core-type.ts → utils/does-type-extend-core-type.ts} +0 -0
- /package/src/{get-property-value.ts → utils/get-property-value.ts} +0 -0
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
export { inspect } from './inspector.js';
|
|
2
|
+
export { getFilesAndMethods } from './utils/get-files-and-methods.js';
|
|
2
3
|
export type { TypesMap } from './types-map.js';
|
|
3
4
|
export type * from './types.js';
|
|
4
5
|
export type { InspectorState } from './types.js';
|
|
6
|
+
export type { FilesAndMethods, FilesAndMethodsErrors, } from './utils/get-files-and-methods.js';
|
package/dist/index.js
CHANGED
package/dist/inspector.d.ts
CHANGED
|
@@ -1,3 +1,2 @@
|
|
|
1
|
-
import { InspectorState,
|
|
2
|
-
export declare const
|
|
3
|
-
export declare const inspect: (logger: InspectorLogger, routeFiles: string[], filters: InspectorFilters) => InspectorState;
|
|
1
|
+
import { InspectorState, InspectorLogger, InspectorOptions } from './types.js';
|
|
2
|
+
export declare const inspect: (logger: InspectorLogger, routeFiles: string[], options?: InspectorOptions) => InspectorState;
|
package/dist/inspector.js
CHANGED
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
import * as ts from 'typescript';
|
|
2
2
|
import { visitSetup, visitRoutes } from './visit.js';
|
|
3
3
|
import { TypesMap } from './types-map.js';
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
};
|
|
7
|
-
export const inspect = (logger, routeFiles, filters) => {
|
|
4
|
+
import { getFilesAndMethods } from './utils/get-files-and-methods.js';
|
|
5
|
+
export const inspect = (logger, routeFiles, options = {}) => {
|
|
8
6
|
const program = ts.createProgram(routeFiles, {
|
|
9
7
|
target: ts.ScriptTarget.ESNext,
|
|
10
8
|
module: ts.ModuleKind.CommonJS,
|
|
@@ -15,12 +13,17 @@ export const inspect = (logger, routeFiles, filters) => {
|
|
|
15
13
|
singletonServicesTypeImportMap: new Map(),
|
|
16
14
|
sessionServicesTypeImportMap: new Map(),
|
|
17
15
|
userSessionTypeImportMap: new Map(),
|
|
16
|
+
configTypeImportMap: new Map(),
|
|
18
17
|
singletonServicesFactories: new Map(),
|
|
19
18
|
sessionServicesFactories: new Map(),
|
|
20
19
|
configFactories: new Map(),
|
|
20
|
+
filesAndMethods: {},
|
|
21
|
+
filesAndMethodsErrors: new Map(),
|
|
22
|
+
typesLookup: new Map(),
|
|
21
23
|
functions: {
|
|
22
24
|
typesMap: new TypesMap(),
|
|
23
25
|
meta: {},
|
|
26
|
+
files: new Map(),
|
|
24
27
|
},
|
|
25
28
|
http: {
|
|
26
29
|
metaInputTypes: new Map(),
|
|
@@ -34,6 +37,7 @@ export const inspect = (logger, routeFiles, filters) => {
|
|
|
34
37
|
options: {},
|
|
35
38
|
},
|
|
36
39
|
files: new Set(),
|
|
40
|
+
routeMiddleware: new Map(),
|
|
37
41
|
},
|
|
38
42
|
channels: {
|
|
39
43
|
files: new Set(),
|
|
@@ -60,8 +64,13 @@ export const inspect = (logger, routeFiles, filters) => {
|
|
|
60
64
|
promptsMeta: {},
|
|
61
65
|
files: new Set(),
|
|
62
66
|
},
|
|
67
|
+
cli: {
|
|
68
|
+
meta: {},
|
|
69
|
+
files: new Set(),
|
|
70
|
+
},
|
|
63
71
|
middleware: {
|
|
64
72
|
meta: {},
|
|
73
|
+
tagMiddleware: new Map(),
|
|
65
74
|
},
|
|
66
75
|
permissions: {
|
|
67
76
|
meta: {},
|
|
@@ -69,13 +78,15 @@ export const inspect = (logger, routeFiles, filters) => {
|
|
|
69
78
|
};
|
|
70
79
|
// First sweep: add all functions
|
|
71
80
|
for (const sourceFile of sourceFiles) {
|
|
72
|
-
ts.forEachChild(sourceFile, (child) => visitSetup(checker, child, state,
|
|
81
|
+
ts.forEachChild(sourceFile, (child) => visitSetup(logger, checker, child, state, options));
|
|
73
82
|
}
|
|
74
83
|
// Second sweep: add all transports
|
|
75
84
|
for (const sourceFile of sourceFiles) {
|
|
76
|
-
ts.forEachChild(sourceFile, (child) => visitRoutes(checker, child, state,
|
|
85
|
+
ts.forEachChild(sourceFile, (child) => visitRoutes(logger, checker, child, state, options));
|
|
77
86
|
}
|
|
78
|
-
//
|
|
79
|
-
|
|
87
|
+
// Populate filesAndMethods
|
|
88
|
+
const { result, errors } = getFilesAndMethods(state, options.types);
|
|
89
|
+
state.filesAndMethods = result;
|
|
90
|
+
state.filesAndMethodsErrors = errors;
|
|
80
91
|
return state;
|
|
81
92
|
};
|
package/dist/types.d.ts
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
|
+
import * as ts from 'typescript';
|
|
1
2
|
import { ChannelsMeta } from '@pikku/core/channel';
|
|
2
3
|
import { HTTPWiringsMeta } from '@pikku/core/http';
|
|
3
4
|
import { ScheduledTasksMeta } from '@pikku/core/scheduler';
|
|
4
5
|
import { queueWorkersMeta } from '@pikku/core/queue';
|
|
5
6
|
import { MCPResourceMeta, MCPToolMeta, MCPPromptMeta } from '@pikku/core';
|
|
7
|
+
import { CLIMeta } from '@pikku/core';
|
|
6
8
|
import { TypesMap } from './types-map.js';
|
|
7
9
|
import { FunctionsMeta, FunctionServicesMeta } from '@pikku/core';
|
|
8
10
|
export type PathToNameAndType = Map<string, {
|
|
@@ -15,14 +17,27 @@ export type MetaInputTypes = Map<string, {
|
|
|
15
17
|
params: string[] | undefined;
|
|
16
18
|
body: string[] | undefined;
|
|
17
19
|
}>;
|
|
20
|
+
export interface MiddlewareGroupMeta {
|
|
21
|
+
exportName: string | null;
|
|
22
|
+
sourceFile: string;
|
|
23
|
+
position: number;
|
|
24
|
+
services: FunctionServicesMeta;
|
|
25
|
+
middlewareCount: number;
|
|
26
|
+
isFactory: boolean;
|
|
27
|
+
}
|
|
18
28
|
export interface InspectorHTTPState {
|
|
19
29
|
metaInputTypes: MetaInputTypes;
|
|
20
30
|
meta: HTTPWiringsMeta;
|
|
21
31
|
files: Set<string>;
|
|
32
|
+
routeMiddleware: Map<string, MiddlewareGroupMeta>;
|
|
22
33
|
}
|
|
23
34
|
export interface InspectorFunctionState {
|
|
24
35
|
typesMap: TypesMap;
|
|
25
36
|
meta: FunctionsMeta;
|
|
37
|
+
files: Map<string, {
|
|
38
|
+
path: string;
|
|
39
|
+
exportedName: string;
|
|
40
|
+
}>;
|
|
26
41
|
}
|
|
27
42
|
export interface InspectorChannelState {
|
|
28
43
|
meta: ChannelsMeta;
|
|
@@ -34,7 +49,9 @@ export interface InspectorMiddlewareState {
|
|
|
34
49
|
sourceFile: string;
|
|
35
50
|
position: number;
|
|
36
51
|
exportedName: string | null;
|
|
52
|
+
factory?: boolean;
|
|
37
53
|
}>;
|
|
54
|
+
tagMiddleware: Map<string, MiddlewareGroupMeta>;
|
|
38
55
|
}
|
|
39
56
|
export interface InspectorPermissionState {
|
|
40
57
|
meta: Record<string, {
|
|
@@ -49,19 +66,77 @@ export type InspectorFilters = {
|
|
|
49
66
|
types?: string[];
|
|
50
67
|
directories?: string[];
|
|
51
68
|
};
|
|
69
|
+
export type InspectorOptions = Partial<{
|
|
70
|
+
types: Partial<{
|
|
71
|
+
configFileType: string;
|
|
72
|
+
userSessionType: string;
|
|
73
|
+
singletonServicesFactoryType: string;
|
|
74
|
+
sessionServicesFactoryType: string;
|
|
75
|
+
}>;
|
|
76
|
+
filters: InspectorFilters;
|
|
77
|
+
}>;
|
|
52
78
|
export interface InspectorLogger {
|
|
53
79
|
info: (message: string) => void;
|
|
54
80
|
error: (message: string) => void;
|
|
55
81
|
warn: (message: string) => void;
|
|
56
82
|
debug: (message: string) => void;
|
|
57
83
|
}
|
|
84
|
+
export type AddWiring = (logger: InspectorLogger, node: ts.Node, checker: ts.TypeChecker, state: InspectorState, options: InspectorOptions) => void;
|
|
85
|
+
export interface InspectorFilesAndMethods {
|
|
86
|
+
userSessionType?: {
|
|
87
|
+
file: string;
|
|
88
|
+
variable: string;
|
|
89
|
+
type: string;
|
|
90
|
+
typePath: string;
|
|
91
|
+
};
|
|
92
|
+
sessionServicesType?: {
|
|
93
|
+
file: string;
|
|
94
|
+
variable: string;
|
|
95
|
+
type: string;
|
|
96
|
+
typePath: string;
|
|
97
|
+
};
|
|
98
|
+
singletonServicesType?: {
|
|
99
|
+
file: string;
|
|
100
|
+
variable: string;
|
|
101
|
+
type: string;
|
|
102
|
+
typePath: string;
|
|
103
|
+
};
|
|
104
|
+
pikkuConfigType?: {
|
|
105
|
+
file: string;
|
|
106
|
+
variable: string;
|
|
107
|
+
type: string;
|
|
108
|
+
typePath: string;
|
|
109
|
+
};
|
|
110
|
+
pikkuConfigFactory?: {
|
|
111
|
+
file: string;
|
|
112
|
+
variable: string;
|
|
113
|
+
type: string;
|
|
114
|
+
typePath: string;
|
|
115
|
+
};
|
|
116
|
+
singletonServicesFactory?: {
|
|
117
|
+
file: string;
|
|
118
|
+
variable: string;
|
|
119
|
+
type: string;
|
|
120
|
+
typePath: string;
|
|
121
|
+
};
|
|
122
|
+
sessionServicesFactory?: {
|
|
123
|
+
file: string;
|
|
124
|
+
variable: string;
|
|
125
|
+
type: string;
|
|
126
|
+
typePath: string;
|
|
127
|
+
};
|
|
128
|
+
}
|
|
58
129
|
export interface InspectorState {
|
|
59
130
|
singletonServicesTypeImportMap: PathToNameAndType;
|
|
60
131
|
sessionServicesTypeImportMap: PathToNameAndType;
|
|
61
132
|
userSessionTypeImportMap: PathToNameAndType;
|
|
133
|
+
configTypeImportMap: PathToNameAndType;
|
|
62
134
|
singletonServicesFactories: PathToNameAndType;
|
|
63
135
|
sessionServicesFactories: PathToNameAndType;
|
|
64
136
|
configFactories: PathToNameAndType;
|
|
137
|
+
filesAndMethods: InspectorFilesAndMethods;
|
|
138
|
+
filesAndMethodsErrors: Map<string, PathToNameAndType>;
|
|
139
|
+
typesLookup: Map<string, ts.Type[]>;
|
|
65
140
|
http: InspectorHTTPState;
|
|
66
141
|
functions: InspectorFunctionState;
|
|
67
142
|
channels: InspectorChannelState;
|
|
@@ -92,6 +167,10 @@ export interface InspectorState {
|
|
|
92
167
|
promptsMeta: MCPPromptMeta;
|
|
93
168
|
files: Set<string>;
|
|
94
169
|
};
|
|
170
|
+
cli: {
|
|
171
|
+
meta: CLIMeta;
|
|
172
|
+
files: Set<string>;
|
|
173
|
+
};
|
|
95
174
|
middleware: InspectorMiddlewareState;
|
|
96
175
|
permissions: InspectorPermissionState;
|
|
97
176
|
}
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
import * as ts from 'typescript';
|
|
2
|
-
|
|
3
|
-
import { PikkuWiringTypes, FunctionServicesMeta } from '@pikku/core';
|
|
4
|
-
type ExtractedFunctionName = {
|
|
2
|
+
export type ExtractedFunctionName = {
|
|
5
3
|
pikkuFuncName: string;
|
|
6
4
|
name: string;
|
|
7
5
|
explicitName: string | null;
|
|
@@ -23,17 +21,11 @@ export declare function makeDeterministicAnonName(start: ts.Node, checker: ts.Ty
|
|
|
23
21
|
* 3. Fallback to deterministic name
|
|
24
22
|
*/
|
|
25
23
|
export declare function extractFunctionName(callExpr: ts.Node, checker: ts.TypeChecker): ExtractedFunctionName;
|
|
26
|
-
export declare const extractTypeKeys: (type: ts.Type) => string[];
|
|
27
|
-
export declare function getPropertyAssignmentInitializer(obj: ts.ObjectLiteralExpression, propName: string, followShorthand?: boolean, checker?: ts.TypeChecker): ts.Expression | undefined;
|
|
28
|
-
export declare const matchesFilters: (filters: InspectorFilters, params: {
|
|
29
|
-
tags?: string[];
|
|
30
|
-
}, meta: {
|
|
31
|
-
type: PikkuWiringTypes;
|
|
32
|
-
name: string;
|
|
33
|
-
filePath?: string;
|
|
34
|
-
}, logger: InspectorLogger) => boolean;
|
|
35
24
|
/**
|
|
36
|
-
*
|
|
25
|
+
* Helper function to populate the 'name' field based on priority
|
|
26
|
+
*/
|
|
27
|
+
export declare function populateNameByPriority(result: ExtractedFunctionName): void;
|
|
28
|
+
/**
|
|
29
|
+
* Helper function to check if a variable declaration is a named export
|
|
37
30
|
*/
|
|
38
|
-
export declare function
|
|
39
|
-
export {};
|
|
31
|
+
export declare function isNamedExport(declaration: ts.VariableDeclaration): boolean;
|
|
@@ -256,9 +256,8 @@ export function extractFunctionName(callExpr, checker) {
|
|
|
256
256
|
}
|
|
257
257
|
}
|
|
258
258
|
}
|
|
259
|
-
//
|
|
260
|
-
let
|
|
261
|
-
let originalCallExpr = callExpr; // Keep track of the original call expression for name extraction
|
|
259
|
+
// Keep track of the original call expression for position-based naming
|
|
260
|
+
let originalCallExpr = callExpr;
|
|
262
261
|
// For direct pikku function calls where callExpr is the call expression itself
|
|
263
262
|
if (ts.isCallExpression(callExpr)) {
|
|
264
263
|
const { expression, arguments: args } = callExpr;
|
|
@@ -284,7 +283,7 @@ export function extractFunctionName(callExpr, checker) {
|
|
|
284
283
|
const firstArg = args[0];
|
|
285
284
|
if (ts.isArrowFunction(firstArg) ||
|
|
286
285
|
ts.isFunctionExpression(firstArg)) {
|
|
287
|
-
mainFunc = firstArg
|
|
286
|
+
// mainFunc = firstArg // Use the arrow function directly instead of the call expression
|
|
288
287
|
}
|
|
289
288
|
}
|
|
290
289
|
}
|
|
@@ -321,7 +320,7 @@ export function extractFunctionName(callExpr, checker) {
|
|
|
321
320
|
if (firstArg &&
|
|
322
321
|
(ts.isArrowFunction(firstArg) ||
|
|
323
322
|
ts.isFunctionExpression(firstArg))) {
|
|
324
|
-
mainFunc = firstArg
|
|
323
|
+
// mainFunc = firstArg
|
|
325
324
|
// Check if the variable is exported
|
|
326
325
|
if (isNamedExport(funcDecl) &&
|
|
327
326
|
ts.isIdentifier(funcDecl.name)) {
|
|
@@ -336,7 +335,7 @@ export function extractFunctionName(callExpr, checker) {
|
|
|
336
335
|
}
|
|
337
336
|
else if (ts.isFunctionExpression(funcDecl.initializer) ||
|
|
338
337
|
ts.isArrowFunction(funcDecl.initializer)) {
|
|
339
|
-
mainFunc = funcDecl.initializer
|
|
338
|
+
// mainFunc = funcDecl.initializer
|
|
340
339
|
// Check if the variable is exported
|
|
341
340
|
if (isNamedExport(funcDecl) &&
|
|
342
341
|
ts.isIdentifier(funcDecl.name)) {
|
|
@@ -350,7 +349,7 @@ export function extractFunctionName(callExpr, checker) {
|
|
|
350
349
|
}
|
|
351
350
|
}
|
|
352
351
|
else if (ts.isFunctionDeclaration(funcDecl)) {
|
|
353
|
-
mainFunc = funcDecl
|
|
352
|
+
// mainFunc = funcDecl
|
|
354
353
|
// Check if the function is exported
|
|
355
354
|
if (funcDecl.modifiers?.some((m) => m.kind === ts.SyntaxKind.ExportKeyword) &&
|
|
356
355
|
funcDecl.name &&
|
|
@@ -368,14 +367,14 @@ export function extractFunctionName(callExpr, checker) {
|
|
|
368
367
|
}
|
|
369
368
|
else {
|
|
370
369
|
// If we can't resolve the symbol, use the identifier itself
|
|
371
|
-
mainFunc = prop.initializer
|
|
370
|
+
// mainFunc = prop.initializer
|
|
372
371
|
}
|
|
373
372
|
break;
|
|
374
373
|
}
|
|
375
374
|
else if (ts.isFunctionExpression(prop.initializer) ||
|
|
376
375
|
ts.isArrowFunction(prop.initializer)) {
|
|
377
376
|
// func: () => {} or func: function() {} - use directly
|
|
378
|
-
mainFunc = prop.initializer
|
|
377
|
+
// mainFunc = prop.initializer
|
|
379
378
|
break;
|
|
380
379
|
}
|
|
381
380
|
}
|
|
@@ -401,7 +400,7 @@ export function extractFunctionName(callExpr, checker) {
|
|
|
401
400
|
if (firstArg &&
|
|
402
401
|
(ts.isArrowFunction(firstArg) ||
|
|
403
402
|
ts.isFunctionExpression(firstArg))) {
|
|
404
|
-
mainFunc = firstArg
|
|
403
|
+
// mainFunc = firstArg
|
|
405
404
|
// Check if the variable is exported
|
|
406
405
|
if (isNamedExport(shorthandDecl) &&
|
|
407
406
|
ts.isIdentifier(shorthandDecl.name)) {
|
|
@@ -416,7 +415,7 @@ export function extractFunctionName(callExpr, checker) {
|
|
|
416
415
|
}
|
|
417
416
|
else if (ts.isFunctionExpression(shorthandDecl.initializer) ||
|
|
418
417
|
ts.isArrowFunction(shorthandDecl.initializer)) {
|
|
419
|
-
mainFunc = shorthandDecl.initializer
|
|
418
|
+
// mainFunc = shorthandDecl.initializer
|
|
420
419
|
// Check if the variable is exported
|
|
421
420
|
if (isNamedExport(shorthandDecl) &&
|
|
422
421
|
ts.isIdentifier(shorthandDecl.name)) {
|
|
@@ -430,7 +429,7 @@ export function extractFunctionName(callExpr, checker) {
|
|
|
430
429
|
}
|
|
431
430
|
}
|
|
432
431
|
else if (ts.isFunctionDeclaration(shorthandDecl)) {
|
|
433
|
-
mainFunc = shorthandDecl
|
|
432
|
+
// mainFunc = shorthandDecl
|
|
434
433
|
// Check if the function is exported
|
|
435
434
|
if (shorthandDecl.modifiers?.some((m) => m.kind === ts.SyntaxKind.ExportKeyword) &&
|
|
436
435
|
shorthandDecl.name &&
|
|
@@ -468,6 +467,9 @@ export function extractFunctionName(callExpr, checker) {
|
|
|
468
467
|
if (ts.isCallExpression(decl.initializer) &&
|
|
469
468
|
ts.isIdentifier(decl.initializer.expression) &&
|
|
470
469
|
decl.initializer.expression.text.startsWith('pikku')) {
|
|
470
|
+
// Update originalCallExpr to use the call expression position
|
|
471
|
+
// instead of the variable declaration position
|
|
472
|
+
originalCallExpr = decl.initializer;
|
|
471
473
|
// Check for object with 'name' property in first argument
|
|
472
474
|
const firstArg = decl.initializer.arguments[0];
|
|
473
475
|
if (firstArg && ts.isObjectLiteralExpression(firstArg)) {
|
|
@@ -486,7 +488,7 @@ export function extractFunctionName(callExpr, checker) {
|
|
|
486
488
|
if (firstArg &&
|
|
487
489
|
(ts.isArrowFunction(firstArg) ||
|
|
488
490
|
ts.isFunctionExpression(firstArg))) {
|
|
489
|
-
mainFunc = firstArg
|
|
491
|
+
// mainFunc = firstArg
|
|
490
492
|
}
|
|
491
493
|
}
|
|
492
494
|
// Check if the variable is exported
|
|
@@ -502,7 +504,7 @@ export function extractFunctionName(callExpr, checker) {
|
|
|
502
504
|
}
|
|
503
505
|
else if (ts.isFunctionExpression(decl.initializer) ||
|
|
504
506
|
ts.isArrowFunction(decl.initializer)) {
|
|
505
|
-
mainFunc = decl.initializer
|
|
507
|
+
// mainFunc = decl.initializer
|
|
506
508
|
// Check if the variable is exported
|
|
507
509
|
if (isNamedExport(decl) && ts.isIdentifier(decl.name)) {
|
|
508
510
|
result.exportedName = decl.name.text;
|
|
@@ -513,7 +515,7 @@ export function extractFunctionName(callExpr, checker) {
|
|
|
513
515
|
}
|
|
514
516
|
}
|
|
515
517
|
else if (ts.isFunctionDeclaration(decl)) {
|
|
516
|
-
mainFunc = decl
|
|
518
|
+
// mainFunc = decl
|
|
517
519
|
// Check if the function is exported
|
|
518
520
|
if (decl.modifiers?.some((m) => m.kind === ts.SyntaxKind.ExportKeyword) &&
|
|
519
521
|
decl.name &&
|
|
@@ -527,8 +529,10 @@ export function extractFunctionName(callExpr, checker) {
|
|
|
527
529
|
}
|
|
528
530
|
}
|
|
529
531
|
}
|
|
530
|
-
//
|
|
531
|
-
|
|
532
|
+
// Generate the deterministic function name based on the original call expression
|
|
533
|
+
// (the config), not the resolved inner function. This ensures the metadata key
|
|
534
|
+
// matches what will be looked up at runtime when referencing the config object.
|
|
535
|
+
result.pikkuFuncName = makeDeterministicAnonName(originalCallExpr, checker);
|
|
532
536
|
// Continue with regular name extraction for remaining cases
|
|
533
537
|
// 1) const foo = pikkuFunc(...)
|
|
534
538
|
if (ts.isVariableDeclaration(parent) && ts.isIdentifier(parent.name)) {
|
|
@@ -577,7 +581,7 @@ export function extractFunctionName(callExpr, checker) {
|
|
|
577
581
|
/**
|
|
578
582
|
* Helper function to populate the 'name' field based on priority
|
|
579
583
|
*/
|
|
580
|
-
function populateNameByPriority(result) {
|
|
584
|
+
export function populateNameByPriority(result) {
|
|
581
585
|
// Priority 1: If we have an explict name, use that
|
|
582
586
|
if (result.explicitName) {
|
|
583
587
|
result.name = result.explicitName;
|
|
@@ -599,7 +603,7 @@ function populateNameByPriority(result) {
|
|
|
599
603
|
/**
|
|
600
604
|
* Helper function to check if a variable declaration is a named export
|
|
601
605
|
*/
|
|
602
|
-
function isNamedExport(declaration) {
|
|
606
|
+
export function isNamedExport(declaration) {
|
|
603
607
|
let parent = declaration.parent;
|
|
604
608
|
if (!parent)
|
|
605
609
|
return false;
|
|
@@ -616,126 +620,3 @@ function isNamedExport(declaration) {
|
|
|
616
620
|
}
|
|
617
621
|
return false;
|
|
618
622
|
}
|
|
619
|
-
// Until here
|
|
620
|
-
export const extractTypeKeys = (type) => {
|
|
621
|
-
return type.getProperties().map((symbol) => symbol.getName());
|
|
622
|
-
};
|
|
623
|
-
export function getPropertyAssignmentInitializer(obj, propName, followShorthand = false, checker) {
|
|
624
|
-
for (const prop of obj.properties) {
|
|
625
|
-
// ① foo: () => {}
|
|
626
|
-
if (ts.isPropertyAssignment(prop) &&
|
|
627
|
-
ts.isIdentifier(prop.name) &&
|
|
628
|
-
prop.name.text === propName) {
|
|
629
|
-
return prop.initializer;
|
|
630
|
-
}
|
|
631
|
-
// ② foo() { … }
|
|
632
|
-
if (ts.isMethodDeclaration(prop) &&
|
|
633
|
-
ts.isIdentifier(prop.name) &&
|
|
634
|
-
prop.name.text === propName) {
|
|
635
|
-
return prop.name; // the method node *is* the function
|
|
636
|
-
}
|
|
637
|
-
// ③ { foo } (shorthand)
|
|
638
|
-
if (followShorthand &&
|
|
639
|
-
ts.isShorthandPropertyAssignment(prop) &&
|
|
640
|
-
prop.name.text === propName) {
|
|
641
|
-
if (!checker)
|
|
642
|
-
return prop.name; // best effort without a checker
|
|
643
|
-
let sym = checker.getSymbolAtLocation(prop.name);
|
|
644
|
-
if (sym && sym.flags & ts.SymbolFlags.Alias) {
|
|
645
|
-
sym = checker.getAliasedSymbol(sym);
|
|
646
|
-
}
|
|
647
|
-
const decl = sym?.declarations?.[0];
|
|
648
|
-
// const foo = () => {}
|
|
649
|
-
if (decl &&
|
|
650
|
-
ts.isVariableDeclaration(decl) &&
|
|
651
|
-
decl.initializer &&
|
|
652
|
-
(ts.isArrowFunction(decl.initializer) ||
|
|
653
|
-
ts.isFunctionExpression(decl.initializer))) {
|
|
654
|
-
return decl.initializer;
|
|
655
|
-
}
|
|
656
|
-
// function foo() {}
|
|
657
|
-
if (decl &&
|
|
658
|
-
(ts.isFunctionDeclaration(decl) ||
|
|
659
|
-
ts.isArrowFunction(decl) ||
|
|
660
|
-
ts.isFunctionExpression(decl))) {
|
|
661
|
-
return decl;
|
|
662
|
-
}
|
|
663
|
-
// fallback – just give back the identifier
|
|
664
|
-
return prop.name;
|
|
665
|
-
}
|
|
666
|
-
}
|
|
667
|
-
return undefined;
|
|
668
|
-
}
|
|
669
|
-
export const matchesFilters = (filters, params, meta, logger) => {
|
|
670
|
-
// If no filters are provided, allow everything
|
|
671
|
-
if (Object.keys(filters).length === 0) {
|
|
672
|
-
return true;
|
|
673
|
-
}
|
|
674
|
-
// If all filter arrays are empty, allow everything
|
|
675
|
-
if ((!filters.tags || filters.tags.length === 0) &&
|
|
676
|
-
(!filters.types || filters.types.length === 0) &&
|
|
677
|
-
(!filters.directories || filters.directories.length === 0)) {
|
|
678
|
-
return true;
|
|
679
|
-
}
|
|
680
|
-
// Check type filter
|
|
681
|
-
if (filters.types && filters.types.length > 0) {
|
|
682
|
-
if (!filters.types.includes(meta.type)) {
|
|
683
|
-
logger.debug(`⒡ Filtered by type: ${meta.type}:${meta.name}`);
|
|
684
|
-
return false;
|
|
685
|
-
}
|
|
686
|
-
}
|
|
687
|
-
// Check directory filter
|
|
688
|
-
if (filters.directories && filters.directories.length > 0) {
|
|
689
|
-
if (!meta.filePath) {
|
|
690
|
-
logger.debug(`⒡ Filtered by directory: ${meta.type}:${meta.name} (${meta.filePath})`);
|
|
691
|
-
return false;
|
|
692
|
-
}
|
|
693
|
-
const matchesDirectory = filters.directories.some((dir) => {
|
|
694
|
-
// Normalize paths for comparison
|
|
695
|
-
const normalizedFilePath = meta.filePath.replace(/\\/g, '/');
|
|
696
|
-
const normalizedDir = dir.replace(/\\/g, '/');
|
|
697
|
-
return normalizedFilePath.includes(normalizedDir);
|
|
698
|
-
});
|
|
699
|
-
if (!matchesDirectory) {
|
|
700
|
-
logger.debug(`⒡ Filtered by directory: ${meta.type}:${meta.name} (${meta.filePath})`);
|
|
701
|
-
return false;
|
|
702
|
-
}
|
|
703
|
-
}
|
|
704
|
-
// Check tag filter
|
|
705
|
-
if (filters.tags && filters.tags.length > 0) {
|
|
706
|
-
if (!params.tags ||
|
|
707
|
-
!filters.tags.some((tag) => params.tags.includes(tag))) {
|
|
708
|
-
logger.debug(`⒡ Filtered by tags: ${meta.type}:${meta.name}`);
|
|
709
|
-
return false;
|
|
710
|
-
}
|
|
711
|
-
}
|
|
712
|
-
return true;
|
|
713
|
-
};
|
|
714
|
-
/**
|
|
715
|
-
* Extract services from a function's first parameter destructuring pattern
|
|
716
|
-
*/
|
|
717
|
-
export function extractServicesFromFunction(handlerNode) {
|
|
718
|
-
const services = {
|
|
719
|
-
optimized: true,
|
|
720
|
-
services: [],
|
|
721
|
-
};
|
|
722
|
-
const firstParam = handlerNode.parameters[0];
|
|
723
|
-
if (firstParam) {
|
|
724
|
-
if (ts.isObjectBindingPattern(firstParam.name)) {
|
|
725
|
-
for (const elem of firstParam.name.elements) {
|
|
726
|
-
const original = elem.propertyName && ts.isIdentifier(elem.propertyName)
|
|
727
|
-
? elem.propertyName.text
|
|
728
|
-
: ts.isIdentifier(elem.name)
|
|
729
|
-
? elem.name.text
|
|
730
|
-
: undefined;
|
|
731
|
-
if (original) {
|
|
732
|
-
services.services.push(original);
|
|
733
|
-
}
|
|
734
|
-
}
|
|
735
|
-
}
|
|
736
|
-
else if (ts.isIdentifier(firstParam.name)) {
|
|
737
|
-
services.optimized = false;
|
|
738
|
-
}
|
|
739
|
-
}
|
|
740
|
-
return services;
|
|
741
|
-
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import * as ts from 'typescript';
|
|
2
|
+
import { FunctionServicesMeta } from '@pikku/core';
|
|
3
|
+
/**
|
|
4
|
+
* Extract services from a function's first parameter destructuring pattern
|
|
5
|
+
*/
|
|
6
|
+
export declare function extractServicesFromFunction(handlerNode: ts.FunctionExpression | ts.ArrowFunction): FunctionServicesMeta;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import * as ts from 'typescript';
|
|
2
|
+
/**
|
|
3
|
+
* Extract services from a function's first parameter destructuring pattern
|
|
4
|
+
*/
|
|
5
|
+
export function extractServicesFromFunction(handlerNode) {
|
|
6
|
+
const services = {
|
|
7
|
+
optimized: true,
|
|
8
|
+
services: [],
|
|
9
|
+
};
|
|
10
|
+
const firstParam = handlerNode.parameters[0];
|
|
11
|
+
if (firstParam) {
|
|
12
|
+
if (ts.isObjectBindingPattern(firstParam.name)) {
|
|
13
|
+
for (const elem of firstParam.name.elements) {
|
|
14
|
+
const original = elem.propertyName && ts.isIdentifier(elem.propertyName)
|
|
15
|
+
? elem.propertyName.text
|
|
16
|
+
: ts.isIdentifier(elem.name)
|
|
17
|
+
? elem.name.text
|
|
18
|
+
: undefined;
|
|
19
|
+
if (original) {
|
|
20
|
+
services.services.push(original);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
else if (ts.isIdentifier(firstParam.name)) {
|
|
25
|
+
services.optimized = false;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
return services;
|
|
29
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { InspectorFilters, InspectorLogger } from '../types.js';
|
|
2
|
+
import { PikkuWiringTypes } from '@pikku/core';
|
|
3
|
+
export declare const matchesFilters: (filters: InspectorFilters, params: {
|
|
4
|
+
tags?: string[];
|
|
5
|
+
}, meta: {
|
|
6
|
+
type: PikkuWiringTypes;
|
|
7
|
+
name: string;
|
|
8
|
+
filePath?: string;
|
|
9
|
+
}, logger: InspectorLogger) => boolean;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
export const matchesFilters = (filters, params, meta, logger) => {
|
|
2
|
+
// If no filters are provided, allow everything
|
|
3
|
+
if (Object.keys(filters).length === 0) {
|
|
4
|
+
return true;
|
|
5
|
+
}
|
|
6
|
+
// If all filter arrays are empty, allow everything
|
|
7
|
+
if ((!filters.tags || filters.tags.length === 0) &&
|
|
8
|
+
(!filters.types || filters.types.length === 0) &&
|
|
9
|
+
(!filters.directories || filters.directories.length === 0)) {
|
|
10
|
+
return true;
|
|
11
|
+
}
|
|
12
|
+
// Check type filter
|
|
13
|
+
if (filters.types && filters.types.length > 0) {
|
|
14
|
+
if (!filters.types.includes(meta.type)) {
|
|
15
|
+
logger.debug(`⒡ Filtered by type: ${meta.type}:${meta.name}`);
|
|
16
|
+
return false;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
// Check directory filter
|
|
20
|
+
if (filters.directories && filters.directories.length > 0) {
|
|
21
|
+
if (!meta.filePath) {
|
|
22
|
+
logger.debug(`⒡ Filtered by directory: ${meta.type}:${meta.name} (${meta.filePath})`);
|
|
23
|
+
return false;
|
|
24
|
+
}
|
|
25
|
+
const matchesDirectory = filters.directories.some((dir) => {
|
|
26
|
+
// Normalize paths for comparison
|
|
27
|
+
const normalizedFilePath = meta.filePath.replace(/\\/g, '/');
|
|
28
|
+
const normalizedDir = dir.replace(/\\/g, '/');
|
|
29
|
+
return normalizedFilePath.includes(normalizedDir);
|
|
30
|
+
});
|
|
31
|
+
if (!matchesDirectory) {
|
|
32
|
+
logger.debug(`⒡ Filtered by directory: ${meta.type}:${meta.name} (${meta.filePath})`);
|
|
33
|
+
return false;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
// Check tag filter
|
|
37
|
+
if (filters.tags && filters.tags.length > 0) {
|
|
38
|
+
if (!params.tags ||
|
|
39
|
+
!filters.tags.some((tag) => params.tags.includes(tag))) {
|
|
40
|
+
logger.debug(`⒡ Filtered by tags: ${meta.type}:${meta.name}`);
|
|
41
|
+
return false;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
return true;
|
|
45
|
+
};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { PathToNameAndType, InspectorState, InspectorOptions } from '../types.js';
|
|
2
|
+
interface Meta {
|
|
3
|
+
file: string;
|
|
4
|
+
variable: string;
|
|
5
|
+
type: string;
|
|
6
|
+
typePath: string;
|
|
7
|
+
}
|
|
8
|
+
export type FilesAndMethods = {
|
|
9
|
+
userSessionType: Meta;
|
|
10
|
+
sessionServicesType: Meta;
|
|
11
|
+
singletonServicesType: Meta;
|
|
12
|
+
pikkuConfigFactory: Meta;
|
|
13
|
+
singletonServicesFactory: Meta;
|
|
14
|
+
sessionServicesFactory: Meta;
|
|
15
|
+
};
|
|
16
|
+
export type FilesAndMethodsErrors = Map<string, PathToNameAndType>;
|
|
17
|
+
export declare const getFilesAndMethods: ({ singletonServicesTypeImportMap, sessionServicesTypeImportMap, userSessionTypeImportMap, sessionServicesFactories, singletonServicesFactories, configFactories, }: InspectorState, { configFileType, userSessionType, singletonServicesFactoryType, sessionServicesFactoryType, }?: InspectorOptions["types"]) => {
|
|
18
|
+
result: Partial<FilesAndMethods>;
|
|
19
|
+
errors: FilesAndMethodsErrors;
|
|
20
|
+
};
|
|
21
|
+
export {};
|