@pikku/inspector 0.11.1 → 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 +26 -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 +327 -59
- package/dist/add/add-http-route.d.ts +19 -10
- package/dist/add/add-http-route.js +153 -44
- 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.d.ts +3 -0
- package/dist/add/add-rpc-invocations.js +65 -25
- 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 +7 -0
- package/dist/add/add-workflow-graph.js +396 -0
- package/dist/add/add-workflow.js +124 -26
- package/dist/error-codes.d.ts +16 -1
- package/dist/error-codes.js +21 -1
- package/dist/index.d.ts +9 -5
- package/dist/index.js +5 -2
- package/dist/inspector.d.ts +1 -1
- package/dist/inspector.js +106 -13
- 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 +180 -30
- 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 +93 -298
- 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 +8 -2
- package/dist/utils/get-property-value.js +33 -4
- 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 +73 -13
- package/dist/utils/serialize-inspector-state.js +102 -6
- 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.d.ts +24 -0
- package/dist/utils/workflow/dsl/deserialize-dsl-workflow.js +830 -0
- package/dist/{workflow/extract-simple-workflow.d.ts → utils/workflow/dsl/extract-dsl-workflow.d.ts} +4 -2
- package/dist/{workflow/extract-simple-workflow.js → utils/workflow/dsl/extract-dsl-workflow.js} +572 -72
- package/dist/utils/workflow/dsl/index.d.ts +7 -0
- package/dist/utils/workflow/dsl/index.js +7 -0
- package/dist/{workflow → utils/workflow/dsl}/patterns.d.ts +21 -0
- package/dist/{workflow → utils/workflow/dsl}/patterns.js +90 -10
- package/dist/{workflow → utils/workflow/dsl}/validation.d.ts +2 -0
- package/dist/{workflow → utils/workflow/dsl}/validation.js +25 -7
- package/dist/utils/workflow/graph/convert-dsl-to-graph.d.ts +13 -0
- package/dist/utils/workflow/graph/convert-dsl-to-graph.js +318 -0
- 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 +8 -0
- package/dist/utils/workflow/graph/index.js +8 -0
- package/dist/utils/workflow/graph/serialize-workflow-graph.d.ts +35 -0
- package/dist/utils/workflow/graph/serialize-workflow-graph.js +150 -0
- package/dist/utils/workflow/graph/workflow-graph.types.d.ts +203 -0
- package/dist/utils/workflow/graph/workflow-graph.types.js +38 -0
- package/dist/visit.js +13 -2
- package/package.json +26 -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 +429 -71
- package/src/add/add-http-route.ts +246 -65
- 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 +78 -31
- 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 +522 -0
- package/src/add/add-workflow.ts +117 -30
- package/src/error-codes.ts +26 -1
- package/src/index.ts +27 -8
- package/src/inspector.ts +145 -17
- package/src/schema-generator.ts +1 -0
- package/src/types-map.ts +12 -1
- package/src/types.ts +192 -51
- 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 +108 -358
- 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 +50 -5
- 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 +181 -20
- 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 +1104 -0
- package/src/{workflow/extract-simple-workflow.ts → utils/workflow/dsl/extract-dsl-workflow.ts} +678 -85
- package/src/utils/workflow/dsl/index.ts +11 -0
- package/src/{workflow → utils/workflow/dsl}/patterns.ts +108 -11
- package/src/{workflow → utils/workflow/dsl}/validation.ts +34 -7
- package/src/utils/workflow/graph/convert-dsl-to-graph.ts +422 -0
- 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 +11 -0
- package/src/utils/workflow/graph/serialize-workflow-graph.ts +216 -0
- package/src/utils/workflow/graph/workflow-graph.types.ts +231 -0
- package/src/visit.ts +14 -2
- package/tsconfig.tsbuildinfo +1 -1
- 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-mcp-tool.ts +0 -141
- package/src/utils/extract-service-metadata.ts +0 -353
- package/src/utils/write-service-metadata.ts +0 -51
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import * as ts from 'typescript';
|
|
2
|
+
import type { SchemaVendor, InspectorLogger } from '../types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Detect the schema vendor by tracing the type back to its library origin.
|
|
5
|
+
* This handles locally-defined schemas like `export const MySchema = z.object({...})`
|
|
6
|
+
* by checking where the type itself originates from.
|
|
7
|
+
*
|
|
8
|
+
* Supports multiple schema libraries in the same project (e.g., during migration
|
|
9
|
+
* from one library to another).
|
|
10
|
+
*/
|
|
11
|
+
export declare const detectSchemaVendor: (identifier: ts.Identifier, checker: ts.TypeChecker) => SchemaVendor;
|
|
12
|
+
/**
|
|
13
|
+
* Detect schema vendor and log a fatal error if unknown.
|
|
14
|
+
* Returns the vendor if successful, or undefined if unknown (after logging error).
|
|
15
|
+
*
|
|
16
|
+
* @param identifier - The TypeScript identifier for the schema variable
|
|
17
|
+
* @param checker - TypeScript type checker
|
|
18
|
+
* @param logger - Inspector logger for error reporting
|
|
19
|
+
* @param context - Description of what the schema is for (e.g., "Credential 'myCredential'")
|
|
20
|
+
* @param sourceFile - Source file path for error message
|
|
21
|
+
*/
|
|
22
|
+
export declare const detectSchemaVendorOrError: (identifier: ts.Identifier, checker: ts.TypeChecker, logger: InspectorLogger, context: string, sourceFile: string) => Exclude<SchemaVendor, "unknown"> | undefined;
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { ErrorCode } from '../error-codes.js';
|
|
2
|
+
/**
|
|
3
|
+
* Detect the schema vendor by tracing the type back to its library origin.
|
|
4
|
+
* This handles locally-defined schemas like `export const MySchema = z.object({...})`
|
|
5
|
+
* by checking where the type itself originates from.
|
|
6
|
+
*
|
|
7
|
+
* Supports multiple schema libraries in the same project (e.g., during migration
|
|
8
|
+
* from one library to another).
|
|
9
|
+
*/
|
|
10
|
+
export const detectSchemaVendor = (identifier, checker) => {
|
|
11
|
+
const type = checker.getTypeAtLocation(identifier);
|
|
12
|
+
if (!type)
|
|
13
|
+
return 'unknown';
|
|
14
|
+
// Check the type's symbol declarations to find the library origin
|
|
15
|
+
const checkTypeOrigin = (t) => {
|
|
16
|
+
const symbol = t.getSymbol() || t.aliasSymbol;
|
|
17
|
+
if (symbol) {
|
|
18
|
+
const decls = symbol.getDeclarations();
|
|
19
|
+
if (decls) {
|
|
20
|
+
for (const decl of decls) {
|
|
21
|
+
const fileName = decl.getSourceFile().fileName;
|
|
22
|
+
if (fileName.includes('node_modules/zod'))
|
|
23
|
+
return 'zod';
|
|
24
|
+
if (fileName.includes('node_modules/valibot'))
|
|
25
|
+
return 'valibot';
|
|
26
|
+
if (fileName.includes('node_modules/arktype'))
|
|
27
|
+
return 'arktype';
|
|
28
|
+
if (fileName.includes('node_modules/@effect/schema'))
|
|
29
|
+
return 'effect';
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
// Check base types for class/interface hierarchies
|
|
34
|
+
const baseTypes = t.getBaseTypes?.();
|
|
35
|
+
if (baseTypes) {
|
|
36
|
+
for (const baseType of baseTypes) {
|
|
37
|
+
const result = checkTypeOrigin(baseType);
|
|
38
|
+
if (result)
|
|
39
|
+
return result;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
return null;
|
|
43
|
+
};
|
|
44
|
+
const vendor = checkTypeOrigin(type);
|
|
45
|
+
if (vendor)
|
|
46
|
+
return vendor;
|
|
47
|
+
// Fallback: check type arguments (for generic types like z.ZodObject<...>)
|
|
48
|
+
if (type.typeArguments) {
|
|
49
|
+
for (const arg of type.typeArguments || []) {
|
|
50
|
+
const result = checkTypeOrigin(arg);
|
|
51
|
+
if (result)
|
|
52
|
+
return result;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return 'unknown';
|
|
56
|
+
};
|
|
57
|
+
/**
|
|
58
|
+
* Detect schema vendor and log a fatal error if unknown.
|
|
59
|
+
* Returns the vendor if successful, or undefined if unknown (after logging error).
|
|
60
|
+
*
|
|
61
|
+
* @param identifier - The TypeScript identifier for the schema variable
|
|
62
|
+
* @param checker - TypeScript type checker
|
|
63
|
+
* @param logger - Inspector logger for error reporting
|
|
64
|
+
* @param context - Description of what the schema is for (e.g., "Credential 'myCredential'")
|
|
65
|
+
* @param sourceFile - Source file path for error message
|
|
66
|
+
*/
|
|
67
|
+
export const detectSchemaVendorOrError = (identifier, checker, logger, context, sourceFile) => {
|
|
68
|
+
const vendor = detectSchemaVendor(identifier, checker);
|
|
69
|
+
if (vendor === 'unknown') {
|
|
70
|
+
logger.critical(ErrorCode.INLINE_SCHEMA, `${context} schema vendor could not be determined from '${sourceFile}'. ` +
|
|
71
|
+
`Supported vendors: zod, valibot, arktype, @effect/schema. ` +
|
|
72
|
+
`Ensure your schema is imported from a supported validation library.`);
|
|
73
|
+
return undefined;
|
|
74
|
+
}
|
|
75
|
+
return vendor;
|
|
76
|
+
};
|
|
@@ -1,6 +1,9 @@
|
|
|
1
|
+
import * as ts from 'typescript';
|
|
1
2
|
import { InspectorState } from '../types.js';
|
|
2
3
|
/**
|
|
3
|
-
* Ensures that function metadata exists for a given
|
|
4
|
+
* Ensures that function metadata exists for a given pikkuFuncId.
|
|
4
5
|
* Creates stub metadata if it doesn't exist (useful for inline functions).
|
|
6
|
+
* When funcInitializer and checker are provided, resolves types and
|
|
7
|
+
* extracts tags/middleware/permissions from the pikkuFunc() config.
|
|
5
8
|
*/
|
|
6
|
-
export declare function ensureFunctionMetadata(state: InspectorState,
|
|
9
|
+
export declare function ensureFunctionMetadata(state: InspectorState, pikkuFuncId: string, fallbackName?: string, funcInitializer?: ts.Node, checker?: ts.TypeChecker, isHelper?: boolean): void;
|
|
@@ -1,12 +1,172 @@
|
|
|
1
|
+
import * as ts from 'typescript';
|
|
2
|
+
import { funcIdToTypeName } from './extract-function-name.js';
|
|
3
|
+
import { getCommonWireMetaData } from './get-property-value.js';
|
|
4
|
+
import { resolveMiddleware } from './middleware.js';
|
|
5
|
+
import { resolvePermissions } from './permissions.js';
|
|
6
|
+
function isVoidLike(type) {
|
|
7
|
+
return !!(type.flags &
|
|
8
|
+
(ts.TypeFlags.Void | ts.TypeFlags.Undefined | ts.TypeFlags.VoidLike));
|
|
9
|
+
}
|
|
10
|
+
function isPromiseOfVoid(checker, type) {
|
|
11
|
+
if (!type?.symbol)
|
|
12
|
+
return false;
|
|
13
|
+
const isPromise = type.symbol.name === 'Promise' &&
|
|
14
|
+
checker.getFullyQualifiedName(type.symbol).includes('Promise');
|
|
15
|
+
if (!isPromise)
|
|
16
|
+
return false;
|
|
17
|
+
const inner = type.aliasTypeArguments?.[0] ??
|
|
18
|
+
type.typeArguments?.[0];
|
|
19
|
+
return !!inner && isVoidLike(inner);
|
|
20
|
+
}
|
|
21
|
+
function unwrapPromise(checker, type) {
|
|
22
|
+
if (type.isUnion()) {
|
|
23
|
+
const nonVoid = type.types.filter((t) => !isVoidLike(t) && !isPromiseOfVoid(checker, t));
|
|
24
|
+
if (nonVoid.length === 1) {
|
|
25
|
+
return unwrapPromise(checker, nonVoid[0]);
|
|
26
|
+
}
|
|
27
|
+
if (nonVoid.length > 1) {
|
|
28
|
+
return unwrapPromise(checker, nonVoid[0]);
|
|
29
|
+
}
|
|
30
|
+
return type;
|
|
31
|
+
}
|
|
32
|
+
if (!type?.symbol)
|
|
33
|
+
return type;
|
|
34
|
+
const isPromise = type.symbol.name === 'Promise' &&
|
|
35
|
+
checker.getFullyQualifiedName(type.symbol).includes('Promise');
|
|
36
|
+
if (isPromise && type.aliasTypeArguments?.length === 1) {
|
|
37
|
+
return type.aliasTypeArguments[0];
|
|
38
|
+
}
|
|
39
|
+
if (isPromise && type.typeArguments?.length === 1) {
|
|
40
|
+
return type.typeArguments[0];
|
|
41
|
+
}
|
|
42
|
+
return type;
|
|
43
|
+
}
|
|
44
|
+
function resolveTypeName(checker, type, state, funcName, direction) {
|
|
45
|
+
if (type.flags & (ts.TypeFlags.VoidLike | ts.TypeFlags.Null))
|
|
46
|
+
return null;
|
|
47
|
+
const typeStr = checker.typeToString(type, undefined, ts.TypeFormatFlags.NoTruncation);
|
|
48
|
+
if (!typeStr ||
|
|
49
|
+
typeStr === 'void' ||
|
|
50
|
+
typeStr === 'undefined' ||
|
|
51
|
+
typeStr === 'null')
|
|
52
|
+
return null;
|
|
53
|
+
const isSimpleName = /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(typeStr);
|
|
54
|
+
if (isSimpleName) {
|
|
55
|
+
const symbol = type.aliasSymbol || type.getSymbol();
|
|
56
|
+
if (symbol) {
|
|
57
|
+
const decl = symbol.getDeclarations()?.[0];
|
|
58
|
+
if (decl) {
|
|
59
|
+
const path = decl.getSourceFile().fileName;
|
|
60
|
+
if (!state.functions.typesMap.exists(typeStr, path)) {
|
|
61
|
+
state.functions.typesMap.addType(typeStr, path);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
return typeStr;
|
|
66
|
+
}
|
|
67
|
+
const aliasName = funcIdToTypeName(funcName) + direction;
|
|
68
|
+
state.functions.typesMap.addCustomType(aliasName, typeStr, []);
|
|
69
|
+
return aliasName;
|
|
70
|
+
}
|
|
71
|
+
function getFirstCallSignature(type) {
|
|
72
|
+
const sigs = type.getCallSignatures();
|
|
73
|
+
if (sigs.length > 0)
|
|
74
|
+
return sigs[0];
|
|
75
|
+
if (type.isUnion()) {
|
|
76
|
+
for (const member of type.types) {
|
|
77
|
+
const memberSigs = member.getCallSignatures();
|
|
78
|
+
if (memberSigs.length > 0)
|
|
79
|
+
return memberSigs[0];
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
return undefined;
|
|
83
|
+
}
|
|
84
|
+
function resolveFromConfigTypeArgs(state, pikkuFuncId, configType, checker, meta) {
|
|
85
|
+
const typeArgs = configType.aliasTypeArguments ??
|
|
86
|
+
configType.typeArguments;
|
|
87
|
+
if (!typeArgs || typeArgs.length < 2)
|
|
88
|
+
return;
|
|
89
|
+
const inputType = typeArgs[0];
|
|
90
|
+
const outputType = typeArgs[1];
|
|
91
|
+
if (!meta.inputs || meta.inputs.length === 0) {
|
|
92
|
+
const inputName = resolveTypeName(checker, inputType, state, pikkuFuncId, 'Input');
|
|
93
|
+
if (inputName) {
|
|
94
|
+
meta.inputs = [inputName];
|
|
95
|
+
meta.inputSchemaName = inputName;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
if (!meta.outputs || meta.outputs.length === 0) {
|
|
99
|
+
const resolvedOutput = unwrapPromise(checker, outputType);
|
|
100
|
+
const outputName = resolveTypeName(checker, resolvedOutput, state, pikkuFuncId, 'Output');
|
|
101
|
+
if (outputName) {
|
|
102
|
+
meta.outputs = [outputName];
|
|
103
|
+
meta.outputSchemaName = outputName;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
function resolveFuncConfigTypes(state, pikkuFuncId, funcInitializer, checker) {
|
|
108
|
+
const meta = state.functions.meta[pikkuFuncId];
|
|
109
|
+
if (!meta || (meta.inputs && meta.inputs.length > 0))
|
|
110
|
+
return;
|
|
111
|
+
const configType = checker.getTypeAtLocation(funcInitializer);
|
|
112
|
+
const funcProp = configType.getProperty('func');
|
|
113
|
+
if (!funcProp)
|
|
114
|
+
return;
|
|
115
|
+
const funcType = checker.getTypeOfSymbolAtLocation(funcProp, funcInitializer);
|
|
116
|
+
const sig = getFirstCallSignature(funcType);
|
|
117
|
+
if (!sig)
|
|
118
|
+
return;
|
|
119
|
+
const params = sig.getParameters();
|
|
120
|
+
if (params.length >= 2) {
|
|
121
|
+
const inputType = checker.getTypeOfSymbolAtLocation(params[1], funcInitializer);
|
|
122
|
+
const inputName = resolveTypeName(checker, inputType, state, pikkuFuncId, 'Input');
|
|
123
|
+
if (inputName) {
|
|
124
|
+
meta.inputs = [inputName];
|
|
125
|
+
meta.inputSchemaName = inputName;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
const rawReturnType = checker.getReturnTypeOfSignature(sig);
|
|
129
|
+
const outputType = unwrapPromise(checker, rawReturnType);
|
|
130
|
+
const outputName = resolveTypeName(checker, outputType, state, pikkuFuncId, 'Output');
|
|
131
|
+
if (outputName) {
|
|
132
|
+
meta.outputs = [outputName];
|
|
133
|
+
meta.outputSchemaName = outputName;
|
|
134
|
+
}
|
|
135
|
+
resolveFromConfigTypeArgs(state, pikkuFuncId, configType, checker, meta);
|
|
136
|
+
}
|
|
137
|
+
function resolveToPikkuFuncCall(node, checker) {
|
|
138
|
+
if (ts.isCallExpression(node) &&
|
|
139
|
+
ts.isIdentifier(node.expression) &&
|
|
140
|
+
node.expression.text.startsWith('pikku')) {
|
|
141
|
+
return node;
|
|
142
|
+
}
|
|
143
|
+
if (ts.isIdentifier(node)) {
|
|
144
|
+
const sym = checker.getSymbolAtLocation(node);
|
|
145
|
+
if (sym) {
|
|
146
|
+
let resolved = sym;
|
|
147
|
+
if (resolved.flags & ts.SymbolFlags.Alias) {
|
|
148
|
+
resolved = checker.getAliasedSymbol(resolved) ?? resolved;
|
|
149
|
+
}
|
|
150
|
+
const decl = resolved.declarations?.[0];
|
|
151
|
+
if (decl && ts.isVariableDeclaration(decl) && decl.initializer) {
|
|
152
|
+
return resolveToPikkuFuncCall(decl.initializer, checker);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
return null;
|
|
157
|
+
}
|
|
1
158
|
/**
|
|
2
|
-
* Ensures that function metadata exists for a given
|
|
159
|
+
* Ensures that function metadata exists for a given pikkuFuncId.
|
|
3
160
|
* Creates stub metadata if it doesn't exist (useful for inline functions).
|
|
161
|
+
* When funcInitializer and checker are provided, resolves types and
|
|
162
|
+
* extracts tags/middleware/permissions from the pikkuFunc() config.
|
|
4
163
|
*/
|
|
5
|
-
export function ensureFunctionMetadata(state,
|
|
6
|
-
if (!state.functions.meta[
|
|
7
|
-
state.functions.meta[
|
|
8
|
-
|
|
9
|
-
|
|
164
|
+
export function ensureFunctionMetadata(state, pikkuFuncId, fallbackName, funcInitializer, checker, isHelper) {
|
|
165
|
+
if (!state.functions.meta[pikkuFuncId]) {
|
|
166
|
+
state.functions.meta[pikkuFuncId] = {
|
|
167
|
+
pikkuFuncId,
|
|
168
|
+
functionType: isHelper ? 'helper' : 'inline',
|
|
169
|
+
name: fallbackName || pikkuFuncId,
|
|
10
170
|
services: { optimized: false, services: [] },
|
|
11
171
|
inputSchemaName: null,
|
|
12
172
|
outputSchemaName: null,
|
|
@@ -15,4 +175,58 @@ export function ensureFunctionMetadata(state, pikkuFuncName, fallbackName) {
|
|
|
15
175
|
middleware: undefined,
|
|
16
176
|
};
|
|
17
177
|
}
|
|
178
|
+
const meta = state.functions.meta[pikkuFuncId];
|
|
179
|
+
if (funcInitializer && checker) {
|
|
180
|
+
let pikkuFuncCall = null;
|
|
181
|
+
if (ts.isCallExpression(funcInitializer)) {
|
|
182
|
+
pikkuFuncCall = funcInitializer;
|
|
183
|
+
resolveFuncConfigTypes(state, pikkuFuncId, pikkuFuncCall, checker);
|
|
184
|
+
if (!state.typesLookup.has(pikkuFuncId)) {
|
|
185
|
+
populateTypesLookup(state, pikkuFuncId, pikkuFuncCall, checker);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
else {
|
|
189
|
+
pikkuFuncCall = resolveToPikkuFuncCall(funcInitializer, checker);
|
|
190
|
+
}
|
|
191
|
+
if (pikkuFuncCall) {
|
|
192
|
+
const firstArg = pikkuFuncCall.arguments[0];
|
|
193
|
+
if (firstArg && ts.isObjectLiteralExpression(firstArg)) {
|
|
194
|
+
if (!meta.tags) {
|
|
195
|
+
const { tags } = getCommonWireMetaData(firstArg, 'Function', fallbackName || pikkuFuncId);
|
|
196
|
+
if (tags) {
|
|
197
|
+
meta.tags = tags;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
if (!meta.middleware) {
|
|
201
|
+
meta.middleware = resolveMiddleware(state, firstArg, meta.tags, checker);
|
|
202
|
+
}
|
|
203
|
+
if (!meta.permissions) {
|
|
204
|
+
meta.permissions = resolvePermissions(state, firstArg, meta.tags, checker);
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
function populateTypesLookup(state, pikkuFuncId, funcInitializer, checker) {
|
|
211
|
+
const typeArgs = funcInitializer.typeArguments;
|
|
212
|
+
if (typeArgs && typeArgs.length >= 1) {
|
|
213
|
+
const inputType = checker.getTypeFromTypeNode(typeArgs[0]);
|
|
214
|
+
state.typesLookup.set(pikkuFuncId, [inputType]);
|
|
215
|
+
return;
|
|
216
|
+
}
|
|
217
|
+
const configType = checker.getTypeAtLocation(funcInitializer);
|
|
218
|
+
const funcProp = configType.getProperty('func');
|
|
219
|
+
if (!funcProp)
|
|
220
|
+
return;
|
|
221
|
+
const funcType = checker.getTypeOfSymbolAtLocation(funcProp, funcInitializer);
|
|
222
|
+
const sig = getFirstCallSignature(funcType);
|
|
223
|
+
if (!sig)
|
|
224
|
+
return;
|
|
225
|
+
const params = sig.getParameters();
|
|
226
|
+
if (params.length >= 2) {
|
|
227
|
+
const inputType = checker.getTypeOfSymbolAtLocation(params[1], funcInitializer);
|
|
228
|
+
if (!(inputType.flags & ts.TypeFlags.VoidLike)) {
|
|
229
|
+
state.typesLookup.set(pikkuFuncId, [inputType]);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
18
232
|
}
|
|
@@ -1,25 +1,14 @@
|
|
|
1
1
|
import * as ts from 'typescript';
|
|
2
2
|
export type ExtractedFunctionName = {
|
|
3
|
-
|
|
3
|
+
pikkuFuncId: string;
|
|
4
4
|
name: string;
|
|
5
5
|
explicitName: string | null;
|
|
6
6
|
exportedName: string | null;
|
|
7
|
-
localName: string | null;
|
|
8
7
|
propertyName: string | null;
|
|
8
|
+
isHelper: boolean;
|
|
9
9
|
};
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
* but if it's an Identifier pointing to a function, resolve it back
|
|
13
|
-
* to the function's declaration (so you get the true source location).
|
|
14
|
-
*/
|
|
15
|
-
export declare function makeDeterministicAnonName(start: ts.Node, checker: ts.TypeChecker, rootDir: string): string;
|
|
16
|
-
/**
|
|
17
|
-
* Updated function to extract and prioritize function names correctly
|
|
18
|
-
* This function follows the priority:
|
|
19
|
-
* 1. Object with a name property
|
|
20
|
-
* 2. Exported name
|
|
21
|
-
* 3. Fallback to deterministic name
|
|
22
|
-
*/
|
|
10
|
+
export declare function makeContextBasedId(wiringType: string, ...segments: string[]): string;
|
|
11
|
+
export declare function funcIdToTypeName(id: string): string;
|
|
23
12
|
export declare function extractFunctionName(callExpr: ts.Node, checker: ts.TypeChecker, rootDir: string): ExtractedFunctionName;
|
|
24
13
|
/**
|
|
25
14
|
* Helper function to populate the 'name' field based on priority
|
|
@@ -28,4 +17,4 @@ export declare function populateNameByPriority(result: ExtractedFunctionName): v
|
|
|
28
17
|
/**
|
|
29
18
|
* Helper function to check if a variable declaration is a named export
|
|
30
19
|
*/
|
|
31
|
-
export declare function isNamedExport(declaration: ts.VariableDeclaration): boolean;
|
|
20
|
+
export declare function isNamedExport(declaration: ts.VariableDeclaration, checker?: ts.TypeChecker): boolean;
|