@fincity/kirun-js 3.1.4 → 3.2.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.
Files changed (40) hide show
  1. package/__tests__/engine/dsl/GraphDebugTest.ts +316 -0
  2. package/__tests__/engine/runtime/expression/ExpressionParsingTest.ts +402 -14
  3. package/dist/index.js +15 -1
  4. package/dist/index.js.map +1 -1
  5. package/dist/module.js +15 -1
  6. package/dist/module.js.map +1 -1
  7. package/dist/types.d.ts +416 -0
  8. package/dist/types.d.ts.map +1 -1
  9. package/package.json +1 -1
  10. package/src/engine/dsl/DSLCompiler.ts +104 -0
  11. package/src/engine/dsl/index.ts +30 -0
  12. package/src/engine/dsl/lexer/DSLLexer.ts +518 -0
  13. package/src/engine/dsl/lexer/DSLToken.ts +74 -0
  14. package/src/engine/dsl/lexer/Keywords.ts +80 -0
  15. package/src/engine/dsl/lexer/LexerError.ts +37 -0
  16. package/src/engine/dsl/monaco/DSLFunctionProvider.ts +187 -0
  17. package/src/engine/dsl/parser/DSLParser.ts +1075 -0
  18. package/src/engine/dsl/parser/DSLParserError.ts +29 -0
  19. package/src/engine/dsl/parser/ast/ASTNode.ts +23 -0
  20. package/src/engine/dsl/parser/ast/ArgumentNode.ts +43 -0
  21. package/src/engine/dsl/parser/ast/ComplexValueNode.ts +22 -0
  22. package/src/engine/dsl/parser/ast/EventDeclNode.ts +27 -0
  23. package/src/engine/dsl/parser/ast/ExpressionNode.ts +33 -0
  24. package/src/engine/dsl/parser/ast/FunctionCallNode.ts +29 -0
  25. package/src/engine/dsl/parser/ast/FunctionDefNode.ts +37 -0
  26. package/src/engine/dsl/parser/ast/ParameterDeclNode.ts +25 -0
  27. package/src/engine/dsl/parser/ast/SchemaLiteralNode.ts +26 -0
  28. package/src/engine/dsl/parser/ast/SchemaNode.ts +23 -0
  29. package/src/engine/dsl/parser/ast/StatementNode.ts +41 -0
  30. package/src/engine/dsl/parser/ast/index.ts +14 -0
  31. package/src/engine/dsl/transformer/ASTToJSON.ts +378 -0
  32. package/src/engine/dsl/transformer/ExpressionHandler.ts +48 -0
  33. package/src/engine/dsl/transformer/JSONToText.ts +694 -0
  34. package/src/engine/dsl/transformer/SchemaTransformer.ts +110 -0
  35. package/src/engine/model/FunctionDefinition.ts +23 -0
  36. package/src/engine/runtime/expression/Expression.ts +5 -1
  37. package/src/engine/runtime/expression/ExpressionEvaluator.ts +152 -139
  38. package/src/engine/runtime/expression/ExpressionParser.ts +80 -27
  39. package/src/engine/util/duplicate.ts +3 -1
  40. package/src/index.ts +1 -0
@@ -0,0 +1,187 @@
1
+ import { Function } from '../../function/Function';
2
+ import { Repository } from '../../Repository';
3
+ import { KIRunFunctionRepository } from '../../repository/KIRunFunctionRepository';
4
+
5
+ export interface FunctionInfo {
6
+ namespace: string;
7
+ name: string;
8
+ fullName: string;
9
+ parameters: ParameterInfo[];
10
+ events: EventInfo[];
11
+ description?: string;
12
+ }
13
+
14
+ export interface ParameterInfo {
15
+ name: string;
16
+ type: string;
17
+ required: boolean;
18
+ }
19
+
20
+ export interface EventInfo {
21
+ name: string;
22
+ parameters: { [key: string]: string };
23
+ }
24
+
25
+ /**
26
+ * DSL Function Provider
27
+ * Provides list of available functions for Monaco autocomplete
28
+ */
29
+ export class DSLFunctionProvider {
30
+ private static readonly cachedFunctions: Map<Repository<Function>, FunctionInfo[]> = new Map();
31
+
32
+ /**
33
+ * Get all available functions from repository
34
+ * Uses repository.filter("") to dynamically discover all available functions
35
+ */
36
+ public static async getAllFunctions(
37
+ repo?: Repository<Function>,
38
+ ): Promise<FunctionInfo[]> {
39
+ const functionRepo = repo || new KIRunFunctionRepository();
40
+
41
+ // Check cache for this specific repository
42
+ if (this.cachedFunctions.has(functionRepo)) {
43
+ return this.cachedFunctions.get(functionRepo)!;
44
+ }
45
+
46
+ // Use filter("") to get all function names from the repository
47
+ const allFunctionNames = await functionRepo.filter('');
48
+
49
+ // Parse all function names and fetch in parallel for better performance
50
+ const fetchPromises = allFunctionNames.map(async (fullName): Promise<FunctionInfo | null> => {
51
+ const lastDotIndex = fullName.lastIndexOf('.');
52
+ if (lastDotIndex === -1) return null;
53
+
54
+ const namespace = fullName.substring(0, lastDotIndex);
55
+ const name = fullName.substring(lastDotIndex + 1);
56
+
57
+ try {
58
+ const func = await functionRepo.find(namespace, name);
59
+ if (func) {
60
+ return {
61
+ namespace,
62
+ name,
63
+ fullName,
64
+ parameters: this.extractParameters(func),
65
+ events: this.extractEvents(func),
66
+ description: '',
67
+ };
68
+ }
69
+ } catch {
70
+ // Function not found or error, skip
71
+ }
72
+ return null;
73
+ });
74
+
75
+ const results = await Promise.all(fetchPromises);
76
+ const functions = results.filter((f): f is FunctionInfo => f !== null);
77
+
78
+ // Cache the results for this repository
79
+ this.cachedFunctions.set(functionRepo, functions);
80
+
81
+ return functions;
82
+ }
83
+
84
+ /**
85
+ * Get functions by namespace
86
+ */
87
+ public static async getFunctionsByNamespace(
88
+ namespace: string,
89
+ repo?: Repository<Function>,
90
+ ): Promise<FunctionInfo[]> {
91
+ const allFunctions = await this.getAllFunctions(repo);
92
+ return allFunctions.filter((f) => f.namespace === namespace);
93
+ }
94
+
95
+ /**
96
+ * Get all unique namespaces
97
+ */
98
+ public static async getAllNamespaces(repo?: Repository<Function>): Promise<string[]> {
99
+ const allFunctions = await this.getAllFunctions(repo);
100
+ const namespaces = new Set(allFunctions.map((f) => f.namespace));
101
+ return Array.from(namespaces).sort();
102
+ }
103
+
104
+ /**
105
+ * Clear cached functions
106
+ */
107
+ public static clearCache(repo?: Repository<Function>): void {
108
+ if (repo) {
109
+ this.cachedFunctions.delete(repo);
110
+ } else {
111
+ this.cachedFunctions.clear();
112
+ }
113
+ }
114
+
115
+ /**
116
+ * Extract parameter info from function
117
+ */
118
+ private static extractParameters(func: Function): ParameterInfo[] {
119
+ const signature = func.getSignature();
120
+ const parameters = signature.getParameters();
121
+ const paramInfos: ParameterInfo[] = [];
122
+
123
+ if (parameters) {
124
+ for (const [name, param] of parameters) {
125
+ const schema = param.getSchema();
126
+ paramInfos.push({
127
+ name,
128
+ type: this.getSchemaType(schema),
129
+ // Parameter is required if it has no default value
130
+ required: schema?.getDefaultValue() === undefined,
131
+ });
132
+ }
133
+ }
134
+
135
+ return paramInfos;
136
+ }
137
+
138
+ /**
139
+ * Extract event info from function
140
+ */
141
+ private static extractEvents(func: Function): EventInfo[] {
142
+ const signature = func.getSignature();
143
+ const events = signature.getEvents();
144
+ const eventInfos: EventInfo[] = [];
145
+
146
+ if (events) {
147
+ for (const [name, event] of events) {
148
+ const params: { [key: string]: string } = {};
149
+ const eventParams = event.getParameters();
150
+ if (eventParams) {
151
+ for (const [paramName, schema] of eventParams) {
152
+ params[paramName] = this.getSchemaType(schema);
153
+ }
154
+ }
155
+ eventInfos.push({
156
+ name,
157
+ parameters: params,
158
+ });
159
+ }
160
+ }
161
+
162
+ return eventInfos;
163
+ }
164
+
165
+ /**
166
+ * Get schema type as string
167
+ */
168
+ private static getSchemaType(schema: any): string {
169
+ if (!schema) return 'Any';
170
+
171
+ const type = schema.getType?.();
172
+ if (!type) return 'Any';
173
+
174
+ // Type is either SingleType or MultipleType
175
+ // Get the allowed schema types and convert to readable string
176
+ const allowedTypes = type.getAllowedSchemaTypes?.();
177
+ if (allowedTypes && allowedTypes.size > 0) {
178
+ const typeNames = Array.from(allowedTypes);
179
+ if (typeNames.length === 1) {
180
+ return String(typeNames[0]); // SchemaType enum values are strings like 'String', 'Integer'
181
+ }
182
+ return typeNames.join(' | ');
183
+ }
184
+
185
+ return 'Any';
186
+ }
187
+ }