@kapeta/local-cluster-service 0.48.2 → 0.48.4
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/cjs/src/storm/codegen.js +10 -1
- package/dist/cjs/src/storm/event-parser.d.ts +4 -4
- package/dist/cjs/src/storm/event-parser.js +39 -36
- package/dist/cjs/src/storm/events.d.ts +3 -0
- package/dist/esm/src/storm/codegen.js +10 -1
- package/dist/esm/src/storm/event-parser.d.ts +4 -4
- package/dist/esm/src/storm/event-parser.js +39 -36
- package/dist/esm/src/storm/events.d.ts +3 -0
- package/package.json +1 -1
- package/src/storm/codegen.ts +10 -3
- package/src/storm/event-parser.ts +43 -40
- package/src/storm/events.ts +3 -0
package/CHANGELOG.md
CHANGED
@@ -1,3 +1,17 @@
|
|
1
|
+
## [0.48.4](https://github.com/kapetacom/local-cluster-service/compare/v0.48.3...v0.48.4) (2024-06-03)
|
2
|
+
|
3
|
+
|
4
|
+
### Bug Fixes
|
5
|
+
|
6
|
+
* Also prettify the kaplang on the event itself ([#158](https://github.com/kapetacom/local-cluster-service/issues/158)) ([63c27d2](https://github.com/kapetacom/local-cluster-service/commit/63c27d2e026b3e8ad4fbe1c181c402c42f7dec95))
|
7
|
+
|
8
|
+
## [0.48.3](https://github.com/kapetacom/local-cluster-service/compare/v0.48.2...v0.48.3) (2024-06-03)
|
9
|
+
|
10
|
+
|
11
|
+
### Bug Fixes
|
12
|
+
|
13
|
+
* Added missing instance and block refs ([dc77a7c](https://github.com/kapetacom/local-cluster-service/commit/dc77a7c480d4ed70e1dc8dc5c1b13093d739e20c))
|
14
|
+
|
1
15
|
## [0.48.2](https://github.com/kapetacom/local-cluster-service/compare/v0.48.1...v0.48.2) (2024-06-03)
|
2
16
|
|
3
17
|
|
@@ -34,6 +34,7 @@ exports.StormCodegen = void 0;
|
|
34
34
|
const codegen_1 = require("@kapeta/codegen");
|
35
35
|
const codeGeneratorManager_1 = require("../codeGeneratorManager");
|
36
36
|
const stormClient_1 = require("./stormClient");
|
37
|
+
const event_parser_1 = require("./event-parser");
|
37
38
|
const stream_1 = require("./stream");
|
38
39
|
const promises_1 = require("fs/promises");
|
39
40
|
const path_1 = __importStar(require("path"));
|
@@ -70,6 +71,7 @@ class StormCodegen {
|
|
70
71
|
handleUiOutput(blockUri, aiName, data) {
|
71
72
|
switch (data.type) {
|
72
73
|
case 'SCREEN':
|
74
|
+
const ref = blockUri.toNormalizedString();
|
73
75
|
this.out.emit('data', {
|
74
76
|
type: 'SCREEN',
|
75
77
|
reason: data.reason,
|
@@ -77,6 +79,8 @@ class StormCodegen {
|
|
77
79
|
payload: {
|
78
80
|
...data.payload,
|
79
81
|
blockName: aiName,
|
82
|
+
blockRef: ref,
|
83
|
+
instanceId: event_parser_1.StormEventParser.toInstanceIdFromRef(ref),
|
80
84
|
},
|
81
85
|
});
|
82
86
|
case 'FILE':
|
@@ -86,6 +90,7 @@ class StormCodegen {
|
|
86
90
|
handleFileOutput(blockUri, aiName, data) {
|
87
91
|
switch (data.type) {
|
88
92
|
case 'FILE':
|
93
|
+
const ref = blockUri.toNormalizedString();
|
89
94
|
this.emitFile(blockUri, aiName, data.payload.filename, data.payload.content, data.reason);
|
90
95
|
return {
|
91
96
|
type: 'FILE',
|
@@ -93,6 +98,8 @@ class StormCodegen {
|
|
93
98
|
payload: {
|
94
99
|
filename: data.payload.filename,
|
95
100
|
content: data.payload.content,
|
101
|
+
blockRef: ref,
|
102
|
+
instanceId: event_parser_1.StormEventParser.toInstanceIdFromRef(ref),
|
96
103
|
},
|
97
104
|
};
|
98
105
|
}
|
@@ -171,6 +178,7 @@ class StormCodegen {
|
|
171
178
|
}
|
172
179
|
emitFile(uri, blockName, filename, content, reason = 'File generated') {
|
173
180
|
const basePath = this.getBasePath(uri.fullName);
|
181
|
+
const ref = uri.toNormalizedString();
|
174
182
|
this.out.emit('data', {
|
175
183
|
type: 'FILE',
|
176
184
|
reason,
|
@@ -180,7 +188,8 @@ class StormCodegen {
|
|
180
188
|
path: (0, path_1.join)(basePath, filename),
|
181
189
|
content: content,
|
182
190
|
blockName,
|
183
|
-
blockRef:
|
191
|
+
blockRef: ref,
|
192
|
+
instanceId: event_parser_1.StormEventParser.toInstanceIdFromRef(ref),
|
184
193
|
},
|
185
194
|
});
|
186
195
|
}
|
@@ -41,6 +41,10 @@ export interface StormOptions {
|
|
41
41
|
}
|
42
42
|
export declare function resolveOptions(): Promise<StormOptions>;
|
43
43
|
export declare class StormEventParser {
|
44
|
+
static toInstanceId(handle: string, blockName: string): string;
|
45
|
+
static toInstanceIdFromRef(ref: string): string;
|
46
|
+
static toSafeName(name: string): string;
|
47
|
+
static toRef(handle: string, name: string): KapetaURI;
|
44
48
|
private events;
|
45
49
|
private planName;
|
46
50
|
private planDescription;
|
@@ -58,11 +62,7 @@ export declare class StormEventParser {
|
|
58
62
|
getEvents(): StormEvent[];
|
59
63
|
isValid(): boolean;
|
60
64
|
getError(): string;
|
61
|
-
private toInstanceId;
|
62
|
-
private toInstanceIdFromRef;
|
63
65
|
toResult(handle: string): StormDefinitions;
|
64
|
-
private toSafeName;
|
65
|
-
private toRef;
|
66
66
|
toBlockDefinitions(handle: string): {
|
67
67
|
[key: string]: BlockDefinitionInfo;
|
68
68
|
};
|
@@ -105,6 +105,19 @@ async function resolveOptions() {
|
|
105
105
|
}
|
106
106
|
exports.resolveOptions = resolveOptions;
|
107
107
|
class StormEventParser {
|
108
|
+
static toInstanceId(handle, blockName) {
|
109
|
+
const ref = this.toRef(handle, blockName);
|
110
|
+
return this.toInstanceIdFromRef(ref.toNormalizedString());
|
111
|
+
}
|
112
|
+
static toInstanceIdFromRef(ref) {
|
113
|
+
return (0, uuid_1.v5)((0, nodejs_utils_1.normalizeKapetaUri)(ref), uuid_1.v5.URL);
|
114
|
+
}
|
115
|
+
static toSafeName(name) {
|
116
|
+
return name.toLowerCase().replace(/[^0-9a-z-]/gi, '');
|
117
|
+
}
|
118
|
+
static toRef(handle, name) {
|
119
|
+
return (0, nodejs_utils_1.parseKapetaUri)(handle + '/' + this.toSafeName(name) + ':local');
|
120
|
+
}
|
108
121
|
events = [];
|
109
122
|
planName = '';
|
110
123
|
planDescription = '';
|
@@ -141,8 +154,8 @@ class StormEventParser {
|
|
141
154
|
models: [],
|
142
155
|
types: [],
|
143
156
|
};
|
144
|
-
evt.payload.blockRef =
|
145
|
-
evt.payload.instanceId =
|
157
|
+
evt.payload.blockRef = StormEventParser.toRef(handle, evt.payload.name).toNormalizedString();
|
158
|
+
evt.payload.instanceId = StormEventParser.toInstanceIdFromRef(evt.payload.blockRef);
|
146
159
|
break;
|
147
160
|
case 'PLAN_RETRY':
|
148
161
|
this.reset();
|
@@ -153,28 +166,31 @@ class StormEventParser {
|
|
153
166
|
break;
|
154
167
|
case 'CREATE_API':
|
155
168
|
blockInfo = this.blocks[evt.payload.blockName];
|
156
|
-
|
157
|
-
|
158
|
-
evt.payload.
|
169
|
+
evt.payload.content = prettifyKaplang(evt.payload.content);
|
170
|
+
blockInfo.apis.push(evt.payload.content);
|
171
|
+
evt.payload.blockRef = StormEventParser.toRef(handle, evt.payload.blockName).toNormalizedString();
|
172
|
+
evt.payload.instanceId = StormEventParser.toInstanceIdFromRef(evt.payload.blockRef);
|
159
173
|
const api = blockInfo.resources.find((r) => r.type == 'API');
|
160
174
|
evt.payload.resourceName = api?.name;
|
161
175
|
break;
|
162
176
|
case 'CREATE_MODEL':
|
163
177
|
blockInfo = this.blocks[evt.payload.blockName];
|
164
|
-
|
165
|
-
|
166
|
-
evt.payload.
|
178
|
+
evt.payload.content = prettifyKaplang(evt.payload.content);
|
179
|
+
blockInfo.models.push(evt.payload.content);
|
180
|
+
evt.payload.blockRef = StormEventParser.toRef(handle, evt.payload.blockName).toNormalizedString();
|
181
|
+
evt.payload.instanceId = StormEventParser.toInstanceIdFromRef(evt.payload.blockRef);
|
167
182
|
const database = blockInfo.resources.find((r) => r.type == 'DATABASE');
|
168
183
|
evt.payload.resourceName = database?.name;
|
169
184
|
break;
|
170
185
|
case 'CREATE_TYPE':
|
171
|
-
|
172
|
-
evt.payload.
|
173
|
-
evt.payload.
|
186
|
+
evt.payload.content = prettifyKaplang(evt.payload.content);
|
187
|
+
this.blocks[evt.payload.blockName].types.push(evt.payload.content);
|
188
|
+
evt.payload.blockRef = StormEventParser.toRef(handle, evt.payload.blockName).toNormalizedString();
|
189
|
+
evt.payload.instanceId = StormEventParser.toInstanceIdFromRef(evt.payload.blockRef);
|
174
190
|
break;
|
175
191
|
case 'CREATE_CONNECTION':
|
176
|
-
evt.payload.fromBlockId =
|
177
|
-
evt.payload.toBlockId =
|
192
|
+
evt.payload.fromBlockId = StormEventParser.toInstanceId(handle, evt.payload.fromComponent);
|
193
|
+
evt.payload.toBlockId = StormEventParser.toInstanceId(handle, evt.payload.toComponent);
|
178
194
|
this.connections.push(evt.payload);
|
179
195
|
break;
|
180
196
|
default:
|
@@ -196,20 +212,13 @@ class StormEventParser {
|
|
196
212
|
getError() {
|
197
213
|
return this.error;
|
198
214
|
}
|
199
|
-
toInstanceId(handle, blockName) {
|
200
|
-
const ref = this.toRef(handle, blockName);
|
201
|
-
return this.toInstanceIdFromRef(ref.toNormalizedString());
|
202
|
-
}
|
203
|
-
toInstanceIdFromRef(ref) {
|
204
|
-
return (0, uuid_1.v5)((0, nodejs_utils_1.normalizeKapetaUri)(ref), uuid_1.v5.URL);
|
205
|
-
}
|
206
215
|
toResult(handle) {
|
207
|
-
const planRef =
|
216
|
+
const planRef = StormEventParser.toRef(handle, this.planName ?? 'undefined');
|
208
217
|
const blockDefinitions = this.toBlockDefinitions(handle);
|
209
218
|
const refIdMap = {};
|
210
219
|
const blocks = Object.entries(blockDefinitions).map(([ref, block]) => {
|
211
220
|
// Create a deterministic uuid
|
212
|
-
const id =
|
221
|
+
const id = StormEventParser.toInstanceIdFromRef(ref);
|
213
222
|
refIdMap[ref] = id;
|
214
223
|
return {
|
215
224
|
id,
|
@@ -229,8 +238,8 @@ class StormEventParser {
|
|
229
238
|
this.connections
|
230
239
|
.filter((connection) => connection.fromResourceType === 'API' && connection.toResourceType === 'CLIENT')
|
231
240
|
.forEach((apiConnection) => {
|
232
|
-
const apiProviderRef =
|
233
|
-
const clientConsumerRef =
|
241
|
+
const apiProviderRef = StormEventParser.toRef(handle, apiConnection.fromComponent);
|
242
|
+
const clientConsumerRef = StormEventParser.toRef(handle, apiConnection.toComponent);
|
234
243
|
const apiProviderBlock = blockDefinitions[apiProviderRef.toNormalizedString()];
|
235
244
|
if (!apiProviderBlock) {
|
236
245
|
console.warn('API provider not found: %s', apiConnection.fromComponent, apiConnection);
|
@@ -283,8 +292,8 @@ class StormEventParser {
|
|
283
292
|
clientResource.spec.source = apiResource.spec.source;
|
284
293
|
});
|
285
294
|
const connections = this.connections.map((connection) => {
|
286
|
-
const fromRef =
|
287
|
-
const toRef =
|
295
|
+
const fromRef = StormEventParser.toRef(handle, connection.fromComponent);
|
296
|
+
const toRef = StormEventParser.toRef(handle, connection.toComponent);
|
288
297
|
return {
|
289
298
|
port: {
|
290
299
|
type: this.toPortType(connection.fromResourceType),
|
@@ -317,16 +326,10 @@ class StormEventParser {
|
|
317
326
|
blocks: Object.values(blockDefinitions),
|
318
327
|
};
|
319
328
|
}
|
320
|
-
toSafeName(name) {
|
321
|
-
return name.toLowerCase().replace(/[^0-9a-z-]/gi, '');
|
322
|
-
}
|
323
|
-
toRef(handle, name) {
|
324
|
-
return (0, nodejs_utils_1.parseKapetaUri)(handle + '/' + this.toSafeName(name) + ':local');
|
325
|
-
}
|
326
329
|
toBlockDefinitions(handle) {
|
327
330
|
const result = {};
|
328
331
|
Object.entries(this.blocks).forEach(([, blockInfo]) => {
|
329
|
-
const blockRef =
|
332
|
+
const blockRef = StormEventParser.toRef(handle, blockInfo.name);
|
330
333
|
const blockDefinitionInfo = {
|
331
334
|
uri: blockRef,
|
332
335
|
aiName: blockInfo.name,
|
@@ -530,7 +533,7 @@ class StormEventParser {
|
|
530
533
|
if (connection.fromResourceType !== 'API') {
|
531
534
|
return;
|
532
535
|
}
|
533
|
-
const fromRef =
|
536
|
+
const fromRef = StormEventParser.toRef(handle, connection.fromComponent);
|
534
537
|
const apiProviderBlock = blockDefinitions[fromRef.toNormalizedString()];
|
535
538
|
if (!apiProviderBlock) {
|
536
539
|
console.warn('Provider block not found: %s', connection.fromComponent, connection);
|
@@ -585,8 +588,8 @@ class StormEventParser {
|
|
585
588
|
}
|
586
589
|
let options = {};
|
587
590
|
if (kind.includes('java')) {
|
588
|
-
const groupId = `ai.${
|
589
|
-
const artifactId =
|
591
|
+
const groupId = `ai.${StormEventParser.toSafeName(handle)}`;
|
592
|
+
const artifactId = StormEventParser.toSafeName(this.planName);
|
590
593
|
options = {
|
591
594
|
groupId,
|
592
595
|
artifactId,
|
@@ -112,6 +112,8 @@ export interface StormEventScreen {
|
|
112
112
|
created: number;
|
113
113
|
payload: {
|
114
114
|
blockName: string;
|
115
|
+
blockRef?: string;
|
116
|
+
instanceId?: string;
|
115
117
|
name: string;
|
116
118
|
template: string;
|
117
119
|
description: string;
|
@@ -138,6 +140,7 @@ export interface StormEventFile {
|
|
138
140
|
content: string;
|
139
141
|
blockName: string;
|
140
142
|
blockRef: string;
|
143
|
+
instanceId: string;
|
141
144
|
};
|
142
145
|
}
|
143
146
|
export interface StormEventDone {
|
@@ -34,6 +34,7 @@ exports.StormCodegen = void 0;
|
|
34
34
|
const codegen_1 = require("@kapeta/codegen");
|
35
35
|
const codeGeneratorManager_1 = require("../codeGeneratorManager");
|
36
36
|
const stormClient_1 = require("./stormClient");
|
37
|
+
const event_parser_1 = require("./event-parser");
|
37
38
|
const stream_1 = require("./stream");
|
38
39
|
const promises_1 = require("fs/promises");
|
39
40
|
const path_1 = __importStar(require("path"));
|
@@ -70,6 +71,7 @@ class StormCodegen {
|
|
70
71
|
handleUiOutput(blockUri, aiName, data) {
|
71
72
|
switch (data.type) {
|
72
73
|
case 'SCREEN':
|
74
|
+
const ref = blockUri.toNormalizedString();
|
73
75
|
this.out.emit('data', {
|
74
76
|
type: 'SCREEN',
|
75
77
|
reason: data.reason,
|
@@ -77,6 +79,8 @@ class StormCodegen {
|
|
77
79
|
payload: {
|
78
80
|
...data.payload,
|
79
81
|
blockName: aiName,
|
82
|
+
blockRef: ref,
|
83
|
+
instanceId: event_parser_1.StormEventParser.toInstanceIdFromRef(ref),
|
80
84
|
},
|
81
85
|
});
|
82
86
|
case 'FILE':
|
@@ -86,6 +90,7 @@ class StormCodegen {
|
|
86
90
|
handleFileOutput(blockUri, aiName, data) {
|
87
91
|
switch (data.type) {
|
88
92
|
case 'FILE':
|
93
|
+
const ref = blockUri.toNormalizedString();
|
89
94
|
this.emitFile(blockUri, aiName, data.payload.filename, data.payload.content, data.reason);
|
90
95
|
return {
|
91
96
|
type: 'FILE',
|
@@ -93,6 +98,8 @@ class StormCodegen {
|
|
93
98
|
payload: {
|
94
99
|
filename: data.payload.filename,
|
95
100
|
content: data.payload.content,
|
101
|
+
blockRef: ref,
|
102
|
+
instanceId: event_parser_1.StormEventParser.toInstanceIdFromRef(ref),
|
96
103
|
},
|
97
104
|
};
|
98
105
|
}
|
@@ -171,6 +178,7 @@ class StormCodegen {
|
|
171
178
|
}
|
172
179
|
emitFile(uri, blockName, filename, content, reason = 'File generated') {
|
173
180
|
const basePath = this.getBasePath(uri.fullName);
|
181
|
+
const ref = uri.toNormalizedString();
|
174
182
|
this.out.emit('data', {
|
175
183
|
type: 'FILE',
|
176
184
|
reason,
|
@@ -180,7 +188,8 @@ class StormCodegen {
|
|
180
188
|
path: (0, path_1.join)(basePath, filename),
|
181
189
|
content: content,
|
182
190
|
blockName,
|
183
|
-
blockRef:
|
191
|
+
blockRef: ref,
|
192
|
+
instanceId: event_parser_1.StormEventParser.toInstanceIdFromRef(ref),
|
184
193
|
},
|
185
194
|
});
|
186
195
|
}
|
@@ -41,6 +41,10 @@ export interface StormOptions {
|
|
41
41
|
}
|
42
42
|
export declare function resolveOptions(): Promise<StormOptions>;
|
43
43
|
export declare class StormEventParser {
|
44
|
+
static toInstanceId(handle: string, blockName: string): string;
|
45
|
+
static toInstanceIdFromRef(ref: string): string;
|
46
|
+
static toSafeName(name: string): string;
|
47
|
+
static toRef(handle: string, name: string): KapetaURI;
|
44
48
|
private events;
|
45
49
|
private planName;
|
46
50
|
private planDescription;
|
@@ -58,11 +62,7 @@ export declare class StormEventParser {
|
|
58
62
|
getEvents(): StormEvent[];
|
59
63
|
isValid(): boolean;
|
60
64
|
getError(): string;
|
61
|
-
private toInstanceId;
|
62
|
-
private toInstanceIdFromRef;
|
63
65
|
toResult(handle: string): StormDefinitions;
|
64
|
-
private toSafeName;
|
65
|
-
private toRef;
|
66
66
|
toBlockDefinitions(handle: string): {
|
67
67
|
[key: string]: BlockDefinitionInfo;
|
68
68
|
};
|
@@ -105,6 +105,19 @@ async function resolveOptions() {
|
|
105
105
|
}
|
106
106
|
exports.resolveOptions = resolveOptions;
|
107
107
|
class StormEventParser {
|
108
|
+
static toInstanceId(handle, blockName) {
|
109
|
+
const ref = this.toRef(handle, blockName);
|
110
|
+
return this.toInstanceIdFromRef(ref.toNormalizedString());
|
111
|
+
}
|
112
|
+
static toInstanceIdFromRef(ref) {
|
113
|
+
return (0, uuid_1.v5)((0, nodejs_utils_1.normalizeKapetaUri)(ref), uuid_1.v5.URL);
|
114
|
+
}
|
115
|
+
static toSafeName(name) {
|
116
|
+
return name.toLowerCase().replace(/[^0-9a-z-]/gi, '');
|
117
|
+
}
|
118
|
+
static toRef(handle, name) {
|
119
|
+
return (0, nodejs_utils_1.parseKapetaUri)(handle + '/' + this.toSafeName(name) + ':local');
|
120
|
+
}
|
108
121
|
events = [];
|
109
122
|
planName = '';
|
110
123
|
planDescription = '';
|
@@ -141,8 +154,8 @@ class StormEventParser {
|
|
141
154
|
models: [],
|
142
155
|
types: [],
|
143
156
|
};
|
144
|
-
evt.payload.blockRef =
|
145
|
-
evt.payload.instanceId =
|
157
|
+
evt.payload.blockRef = StormEventParser.toRef(handle, evt.payload.name).toNormalizedString();
|
158
|
+
evt.payload.instanceId = StormEventParser.toInstanceIdFromRef(evt.payload.blockRef);
|
146
159
|
break;
|
147
160
|
case 'PLAN_RETRY':
|
148
161
|
this.reset();
|
@@ -153,28 +166,31 @@ class StormEventParser {
|
|
153
166
|
break;
|
154
167
|
case 'CREATE_API':
|
155
168
|
blockInfo = this.blocks[evt.payload.blockName];
|
156
|
-
|
157
|
-
|
158
|
-
evt.payload.
|
169
|
+
evt.payload.content = prettifyKaplang(evt.payload.content);
|
170
|
+
blockInfo.apis.push(evt.payload.content);
|
171
|
+
evt.payload.blockRef = StormEventParser.toRef(handle, evt.payload.blockName).toNormalizedString();
|
172
|
+
evt.payload.instanceId = StormEventParser.toInstanceIdFromRef(evt.payload.blockRef);
|
159
173
|
const api = blockInfo.resources.find((r) => r.type == 'API');
|
160
174
|
evt.payload.resourceName = api?.name;
|
161
175
|
break;
|
162
176
|
case 'CREATE_MODEL':
|
163
177
|
blockInfo = this.blocks[evt.payload.blockName];
|
164
|
-
|
165
|
-
|
166
|
-
evt.payload.
|
178
|
+
evt.payload.content = prettifyKaplang(evt.payload.content);
|
179
|
+
blockInfo.models.push(evt.payload.content);
|
180
|
+
evt.payload.blockRef = StormEventParser.toRef(handle, evt.payload.blockName).toNormalizedString();
|
181
|
+
evt.payload.instanceId = StormEventParser.toInstanceIdFromRef(evt.payload.blockRef);
|
167
182
|
const database = blockInfo.resources.find((r) => r.type == 'DATABASE');
|
168
183
|
evt.payload.resourceName = database?.name;
|
169
184
|
break;
|
170
185
|
case 'CREATE_TYPE':
|
171
|
-
|
172
|
-
evt.payload.
|
173
|
-
evt.payload.
|
186
|
+
evt.payload.content = prettifyKaplang(evt.payload.content);
|
187
|
+
this.blocks[evt.payload.blockName].types.push(evt.payload.content);
|
188
|
+
evt.payload.blockRef = StormEventParser.toRef(handle, evt.payload.blockName).toNormalizedString();
|
189
|
+
evt.payload.instanceId = StormEventParser.toInstanceIdFromRef(evt.payload.blockRef);
|
174
190
|
break;
|
175
191
|
case 'CREATE_CONNECTION':
|
176
|
-
evt.payload.fromBlockId =
|
177
|
-
evt.payload.toBlockId =
|
192
|
+
evt.payload.fromBlockId = StormEventParser.toInstanceId(handle, evt.payload.fromComponent);
|
193
|
+
evt.payload.toBlockId = StormEventParser.toInstanceId(handle, evt.payload.toComponent);
|
178
194
|
this.connections.push(evt.payload);
|
179
195
|
break;
|
180
196
|
default:
|
@@ -196,20 +212,13 @@ class StormEventParser {
|
|
196
212
|
getError() {
|
197
213
|
return this.error;
|
198
214
|
}
|
199
|
-
toInstanceId(handle, blockName) {
|
200
|
-
const ref = this.toRef(handle, blockName);
|
201
|
-
return this.toInstanceIdFromRef(ref.toNormalizedString());
|
202
|
-
}
|
203
|
-
toInstanceIdFromRef(ref) {
|
204
|
-
return (0, uuid_1.v5)((0, nodejs_utils_1.normalizeKapetaUri)(ref), uuid_1.v5.URL);
|
205
|
-
}
|
206
215
|
toResult(handle) {
|
207
|
-
const planRef =
|
216
|
+
const planRef = StormEventParser.toRef(handle, this.planName ?? 'undefined');
|
208
217
|
const blockDefinitions = this.toBlockDefinitions(handle);
|
209
218
|
const refIdMap = {};
|
210
219
|
const blocks = Object.entries(blockDefinitions).map(([ref, block]) => {
|
211
220
|
// Create a deterministic uuid
|
212
|
-
const id =
|
221
|
+
const id = StormEventParser.toInstanceIdFromRef(ref);
|
213
222
|
refIdMap[ref] = id;
|
214
223
|
return {
|
215
224
|
id,
|
@@ -229,8 +238,8 @@ class StormEventParser {
|
|
229
238
|
this.connections
|
230
239
|
.filter((connection) => connection.fromResourceType === 'API' && connection.toResourceType === 'CLIENT')
|
231
240
|
.forEach((apiConnection) => {
|
232
|
-
const apiProviderRef =
|
233
|
-
const clientConsumerRef =
|
241
|
+
const apiProviderRef = StormEventParser.toRef(handle, apiConnection.fromComponent);
|
242
|
+
const clientConsumerRef = StormEventParser.toRef(handle, apiConnection.toComponent);
|
234
243
|
const apiProviderBlock = blockDefinitions[apiProviderRef.toNormalizedString()];
|
235
244
|
if (!apiProviderBlock) {
|
236
245
|
console.warn('API provider not found: %s', apiConnection.fromComponent, apiConnection);
|
@@ -283,8 +292,8 @@ class StormEventParser {
|
|
283
292
|
clientResource.spec.source = apiResource.spec.source;
|
284
293
|
});
|
285
294
|
const connections = this.connections.map((connection) => {
|
286
|
-
const fromRef =
|
287
|
-
const toRef =
|
295
|
+
const fromRef = StormEventParser.toRef(handle, connection.fromComponent);
|
296
|
+
const toRef = StormEventParser.toRef(handle, connection.toComponent);
|
288
297
|
return {
|
289
298
|
port: {
|
290
299
|
type: this.toPortType(connection.fromResourceType),
|
@@ -317,16 +326,10 @@ class StormEventParser {
|
|
317
326
|
blocks: Object.values(blockDefinitions),
|
318
327
|
};
|
319
328
|
}
|
320
|
-
toSafeName(name) {
|
321
|
-
return name.toLowerCase().replace(/[^0-9a-z-]/gi, '');
|
322
|
-
}
|
323
|
-
toRef(handle, name) {
|
324
|
-
return (0, nodejs_utils_1.parseKapetaUri)(handle + '/' + this.toSafeName(name) + ':local');
|
325
|
-
}
|
326
329
|
toBlockDefinitions(handle) {
|
327
330
|
const result = {};
|
328
331
|
Object.entries(this.blocks).forEach(([, blockInfo]) => {
|
329
|
-
const blockRef =
|
332
|
+
const blockRef = StormEventParser.toRef(handle, blockInfo.name);
|
330
333
|
const blockDefinitionInfo = {
|
331
334
|
uri: blockRef,
|
332
335
|
aiName: blockInfo.name,
|
@@ -530,7 +533,7 @@ class StormEventParser {
|
|
530
533
|
if (connection.fromResourceType !== 'API') {
|
531
534
|
return;
|
532
535
|
}
|
533
|
-
const fromRef =
|
536
|
+
const fromRef = StormEventParser.toRef(handle, connection.fromComponent);
|
534
537
|
const apiProviderBlock = blockDefinitions[fromRef.toNormalizedString()];
|
535
538
|
if (!apiProviderBlock) {
|
536
539
|
console.warn('Provider block not found: %s', connection.fromComponent, connection);
|
@@ -585,8 +588,8 @@ class StormEventParser {
|
|
585
588
|
}
|
586
589
|
let options = {};
|
587
590
|
if (kind.includes('java')) {
|
588
|
-
const groupId = `ai.${
|
589
|
-
const artifactId =
|
591
|
+
const groupId = `ai.${StormEventParser.toSafeName(handle)}`;
|
592
|
+
const artifactId = StormEventParser.toSafeName(this.planName);
|
590
593
|
options = {
|
591
594
|
groupId,
|
592
595
|
artifactId,
|
@@ -112,6 +112,8 @@ export interface StormEventScreen {
|
|
112
112
|
created: number;
|
113
113
|
payload: {
|
114
114
|
blockName: string;
|
115
|
+
blockRef?: string;
|
116
|
+
instanceId?: string;
|
115
117
|
name: string;
|
116
118
|
template: string;
|
117
119
|
description: string;
|
@@ -138,6 +140,7 @@ export interface StormEventFile {
|
|
138
140
|
content: string;
|
139
141
|
blockName: string;
|
140
142
|
blockRef: string;
|
143
|
+
instanceId: string;
|
141
144
|
};
|
142
145
|
}
|
143
146
|
export interface StormEventDone {
|
package/package.json
CHANGED
package/src/storm/codegen.ts
CHANGED
@@ -9,7 +9,7 @@ import { BlockDefinition } from '@kapeta/schemas';
|
|
9
9
|
import { codeGeneratorManager } from '../codeGeneratorManager';
|
10
10
|
import { STORM_ID, stormClient } from './stormClient';
|
11
11
|
import { StormEvent, StormEventFile } from './events';
|
12
|
-
import { BlockDefinitionInfo } from './event-parser';
|
12
|
+
import { BlockDefinitionInfo, StormEventParser } from './event-parser';
|
13
13
|
import { ConversationItem, StormFileImplementationPrompt, StormFileInfo, StormStream } from './stream';
|
14
14
|
import { KapetaURI } from '@kapeta/nodejs-utils';
|
15
15
|
import { writeFile } from 'fs/promises';
|
@@ -56,6 +56,7 @@ export class StormCodegen {
|
|
56
56
|
private handleUiOutput(blockUri: KapetaURI, aiName: string, data: StormEvent) {
|
57
57
|
switch (data.type) {
|
58
58
|
case 'SCREEN':
|
59
|
+
const ref = blockUri.toNormalizedString();
|
59
60
|
this.out.emit('data', {
|
60
61
|
type: 'SCREEN',
|
61
62
|
reason: data.reason,
|
@@ -63,6 +64,8 @@ export class StormCodegen {
|
|
63
64
|
payload: {
|
64
65
|
...data.payload,
|
65
66
|
blockName: aiName,
|
67
|
+
blockRef: ref,
|
68
|
+
instanceId: StormEventParser.toInstanceIdFromRef(ref),
|
66
69
|
},
|
67
70
|
});
|
68
71
|
case 'FILE':
|
@@ -73,6 +76,7 @@ export class StormCodegen {
|
|
73
76
|
private handleFileOutput(blockUri: KapetaURI, aiName: string, data: StormEvent) {
|
74
77
|
switch (data.type) {
|
75
78
|
case 'FILE':
|
79
|
+
const ref = blockUri.toNormalizedString();
|
76
80
|
this.emitFile(blockUri, aiName, data.payload.filename, data.payload.content, data.reason);
|
77
81
|
return {
|
78
82
|
type: 'FILE',
|
@@ -80,6 +84,8 @@ export class StormCodegen {
|
|
80
84
|
payload: {
|
81
85
|
filename: data.payload.filename,
|
82
86
|
content: data.payload.content,
|
87
|
+
blockRef: ref,
|
88
|
+
instanceId: StormEventParser.toInstanceIdFromRef(ref),
|
83
89
|
},
|
84
90
|
} as StormEventFile;
|
85
91
|
}
|
@@ -192,7 +198,7 @@ export class StormCodegen {
|
|
192
198
|
reason: string = 'File generated'
|
193
199
|
) {
|
194
200
|
const basePath = this.getBasePath(uri.fullName);
|
195
|
-
|
201
|
+
const ref = uri.toNormalizedString();
|
196
202
|
this.out.emit('data', {
|
197
203
|
type: 'FILE',
|
198
204
|
reason,
|
@@ -202,7 +208,8 @@ export class StormCodegen {
|
|
202
208
|
path: join(basePath, filename),
|
203
209
|
content: content,
|
204
210
|
blockName,
|
205
|
-
blockRef:
|
211
|
+
blockRef: ref,
|
212
|
+
instanceId: StormEventParser.toInstanceIdFromRef(ref),
|
206
213
|
},
|
207
214
|
} satisfies StormEventFile);
|
208
215
|
}
|
@@ -201,6 +201,23 @@ export async function resolveOptions(): Promise<StormOptions> {
|
|
201
201
|
}
|
202
202
|
|
203
203
|
export class StormEventParser {
|
204
|
+
public static toInstanceId(handle: string, blockName: string) {
|
205
|
+
const ref = this.toRef(handle, blockName);
|
206
|
+
return this.toInstanceIdFromRef(ref.toNormalizedString());
|
207
|
+
}
|
208
|
+
|
209
|
+
public static toInstanceIdFromRef(ref: string) {
|
210
|
+
return uuid(normalizeKapetaUri(ref), uuid.URL);
|
211
|
+
}
|
212
|
+
|
213
|
+
public static toSafeName(name: string): string {
|
214
|
+
return name.toLowerCase().replace(/[^0-9a-z-]/gi, '');
|
215
|
+
}
|
216
|
+
|
217
|
+
public static toRef(handle: string, name: string) {
|
218
|
+
return parseKapetaUri(handle + '/' + this.toSafeName(name) + ':local');
|
219
|
+
}
|
220
|
+
|
204
221
|
private events: StormEvent[] = [];
|
205
222
|
private planName: string = '';
|
206
223
|
private planDescription: string = '';
|
@@ -240,8 +257,8 @@ export class StormEventParser {
|
|
240
257
|
models: [],
|
241
258
|
types: [],
|
242
259
|
};
|
243
|
-
evt.payload.blockRef =
|
244
|
-
evt.payload.instanceId =
|
260
|
+
evt.payload.blockRef = StormEventParser.toRef(handle, evt.payload.name).toNormalizedString();
|
261
|
+
evt.payload.instanceId = StormEventParser.toInstanceIdFromRef(evt.payload.blockRef);
|
245
262
|
break;
|
246
263
|
case 'PLAN_RETRY':
|
247
264
|
this.reset();
|
@@ -252,31 +269,34 @@ export class StormEventParser {
|
|
252
269
|
break;
|
253
270
|
case 'CREATE_API':
|
254
271
|
blockInfo = this.blocks[evt.payload.blockName];
|
255
|
-
|
256
|
-
|
257
|
-
evt.payload.
|
272
|
+
evt.payload.content = prettifyKaplang(evt.payload.content);
|
273
|
+
blockInfo.apis.push(evt.payload.content);
|
274
|
+
evt.payload.blockRef = StormEventParser.toRef(handle, evt.payload.blockName).toNormalizedString();
|
275
|
+
evt.payload.instanceId = StormEventParser.toInstanceIdFromRef(evt.payload.blockRef);
|
258
276
|
|
259
277
|
const api = blockInfo.resources.find((r) => r.type == 'API');
|
260
278
|
evt.payload.resourceName = api?.name;
|
261
279
|
break;
|
262
280
|
case 'CREATE_MODEL':
|
263
281
|
blockInfo = this.blocks[evt.payload.blockName];
|
264
|
-
|
265
|
-
|
266
|
-
evt.payload.
|
282
|
+
evt.payload.content = prettifyKaplang(evt.payload.content);
|
283
|
+
blockInfo.models.push(evt.payload.content);
|
284
|
+
evt.payload.blockRef = StormEventParser.toRef(handle, evt.payload.blockName).toNormalizedString();
|
285
|
+
evt.payload.instanceId = StormEventParser.toInstanceIdFromRef(evt.payload.blockRef);
|
267
286
|
|
268
287
|
const database = blockInfo.resources.find((r) => r.type == 'DATABASE');
|
269
288
|
evt.payload.resourceName = database?.name;
|
270
289
|
break;
|
271
290
|
|
272
291
|
case 'CREATE_TYPE':
|
273
|
-
|
274
|
-
evt.payload.
|
275
|
-
evt.payload.
|
292
|
+
evt.payload.content = prettifyKaplang(evt.payload.content);
|
293
|
+
this.blocks[evt.payload.blockName].types.push(evt.payload.content);
|
294
|
+
evt.payload.blockRef = StormEventParser.toRef(handle, evt.payload.blockName).toNormalizedString();
|
295
|
+
evt.payload.instanceId = StormEventParser.toInstanceIdFromRef(evt.payload.blockRef);
|
276
296
|
break;
|
277
297
|
case 'CREATE_CONNECTION':
|
278
|
-
evt.payload.fromBlockId =
|
279
|
-
evt.payload.toBlockId =
|
298
|
+
evt.payload.fromBlockId = StormEventParser.toInstanceId(handle, evt.payload.fromComponent);
|
299
|
+
evt.payload.toBlockId = StormEventParser.toInstanceId(handle, evt.payload.toComponent);
|
280
300
|
this.connections.push(evt.payload);
|
281
301
|
break;
|
282
302
|
|
@@ -304,22 +324,13 @@ export class StormEventParser {
|
|
304
324
|
return this.error;
|
305
325
|
}
|
306
326
|
|
307
|
-
private toInstanceId(handle: string, blockName: string) {
|
308
|
-
const ref = this.toRef(handle, blockName);
|
309
|
-
return this.toInstanceIdFromRef(ref.toNormalizedString());
|
310
|
-
}
|
311
|
-
|
312
|
-
private toInstanceIdFromRef(ref: string) {
|
313
|
-
return uuid(normalizeKapetaUri(ref), uuid.URL);
|
314
|
-
}
|
315
|
-
|
316
327
|
public toResult(handle: string): StormDefinitions {
|
317
|
-
const planRef =
|
328
|
+
const planRef = StormEventParser.toRef(handle, this.planName ?? 'undefined');
|
318
329
|
const blockDefinitions = this.toBlockDefinitions(handle);
|
319
330
|
const refIdMap: { [key: string]: string } = {};
|
320
331
|
const blocks = Object.entries(blockDefinitions).map(([ref, block]) => {
|
321
332
|
// Create a deterministic uuid
|
322
|
-
const id =
|
333
|
+
const id = StormEventParser.toInstanceIdFromRef(ref);
|
323
334
|
refIdMap[ref] = id;
|
324
335
|
return {
|
325
336
|
id,
|
@@ -340,8 +351,8 @@ export class StormEventParser {
|
|
340
351
|
this.connections
|
341
352
|
.filter((connection) => connection.fromResourceType === 'API' && connection.toResourceType === 'CLIENT')
|
342
353
|
.forEach((apiConnection) => {
|
343
|
-
const apiProviderRef =
|
344
|
-
const clientConsumerRef =
|
354
|
+
const apiProviderRef = StormEventParser.toRef(handle, apiConnection.fromComponent);
|
355
|
+
const clientConsumerRef = StormEventParser.toRef(handle, apiConnection.toComponent);
|
345
356
|
const apiProviderBlock = blockDefinitions[apiProviderRef.toNormalizedString()];
|
346
357
|
if (!apiProviderBlock) {
|
347
358
|
console.warn('API provider not found: %s', apiConnection.fromComponent, apiConnection);
|
@@ -418,8 +429,8 @@ export class StormEventParser {
|
|
418
429
|
});
|
419
430
|
|
420
431
|
const connections: Connection[] = this.connections.map((connection) => {
|
421
|
-
const fromRef =
|
422
|
-
const toRef =
|
432
|
+
const fromRef = StormEventParser.toRef(handle, connection.fromComponent);
|
433
|
+
const toRef = StormEventParser.toRef(handle, connection.toComponent);
|
423
434
|
|
424
435
|
return {
|
425
436
|
port: {
|
@@ -456,19 +467,11 @@ export class StormEventParser {
|
|
456
467
|
};
|
457
468
|
}
|
458
469
|
|
459
|
-
private toSafeName(name: string): string {
|
460
|
-
return name.toLowerCase().replace(/[^0-9a-z-]/gi, '');
|
461
|
-
}
|
462
|
-
|
463
|
-
private toRef(handle: string, name: string) {
|
464
|
-
return parseKapetaUri(handle + '/' + this.toSafeName(name) + ':local');
|
465
|
-
}
|
466
|
-
|
467
470
|
public toBlockDefinitions(handle: string): { [key: string]: BlockDefinitionInfo } {
|
468
471
|
const result: { [key: string]: BlockDefinitionInfo } = {};
|
469
472
|
|
470
473
|
Object.entries(this.blocks).forEach(([, blockInfo]) => {
|
471
|
-
const blockRef =
|
474
|
+
const blockRef = StormEventParser.toRef(handle, blockInfo.name);
|
472
475
|
|
473
476
|
const blockDefinitionInfo: BlockDefinitionInfo = {
|
474
477
|
uri: blockRef,
|
@@ -690,7 +693,7 @@ export class StormEventParser {
|
|
690
693
|
return;
|
691
694
|
}
|
692
695
|
|
693
|
-
const fromRef =
|
696
|
+
const fromRef = StormEventParser.toRef(handle, connection.fromComponent);
|
694
697
|
|
695
698
|
const apiProviderBlock = blockDefinitions[fromRef.toNormalizedString()];
|
696
699
|
if (!apiProviderBlock) {
|
@@ -771,8 +774,8 @@ export class StormEventParser {
|
|
771
774
|
let options: { [key: string]: any } = {};
|
772
775
|
|
773
776
|
if (kind.includes('java')) {
|
774
|
-
const groupId = `ai.${
|
775
|
-
const artifactId =
|
777
|
+
const groupId = `ai.${StormEventParser.toSafeName(handle)}`;
|
778
|
+
const artifactId = StormEventParser.toSafeName(this.planName);
|
776
779
|
options = {
|
777
780
|
groupId,
|
778
781
|
artifactId,
|
package/src/storm/events.ts
CHANGED
@@ -140,6 +140,8 @@ export interface StormEventScreen {
|
|
140
140
|
created: number;
|
141
141
|
payload: {
|
142
142
|
blockName: string;
|
143
|
+
blockRef?: string;
|
144
|
+
instanceId?: string;
|
143
145
|
name: string;
|
144
146
|
template: string;
|
145
147
|
description: string;
|
@@ -168,6 +170,7 @@ export interface StormEventFile {
|
|
168
170
|
content: string;
|
169
171
|
blockName: string;
|
170
172
|
blockRef: string;
|
173
|
+
instanceId: string;
|
171
174
|
};
|
172
175
|
}
|
173
176
|
|