@kapeta/local-cluster-service 0.55.2 → 0.55.3
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 +7 -0
- package/definitions.d.ts +1 -1
- package/dist/cjs/src/storm/event-parser.d.ts +2 -1
- package/dist/cjs/src/storm/event-parser.js +37 -9
- package/dist/cjs/src/storm/routes.js +1 -1
- package/dist/cjs/test/storm/blog-events.json +860 -0
- package/dist/cjs/test/storm/codegen.test.js +2 -2
- package/dist/cjs/test/storm/event-parser.test.js +25 -7
- package/dist/cjs/test/storm/predefined-user-events.json +9 -0
- package/dist/esm/src/storm/event-parser.d.ts +2 -1
- package/dist/esm/src/storm/event-parser.js +37 -9
- package/dist/esm/src/storm/routes.js +1 -1
- package/dist/esm/test/storm/blog-events.json +860 -0
- package/dist/esm/test/storm/codegen.test.js +2 -2
- package/dist/esm/test/storm/event-parser.test.js +25 -7
- package/dist/esm/test/storm/predefined-user-events.json +9 -0
- package/package.json +1 -1
- package/src/storm/event-parser.ts +60 -25
- package/src/storm/routes.ts +1 -1
- package/test/storm/blog-events.json +860 -0
- package/test/storm/codegen.test.ts +4 -2
- package/test/storm/event-parser.test.ts +27 -7
- package/test/storm/predefined-user-events.json +9 -0
@@ -26,8 +26,8 @@ describe('codegen', () => {
|
|
26
26
|
await codegen.process();
|
27
27
|
const stormEvents = await codegenPromise;
|
28
28
|
expect(stormEvents.filter((event) => event.type === 'FILE_DONE').length).toBeGreaterThan(1);
|
29
|
-
expect(stormEvents.filter((event) => event.type === 'FILE_DONE' && event.payload.filename.endsWith('UserDTO.java'))
|
30
|
-
.toBe(1);
|
29
|
+
expect(stormEvents.filter((event) => event.type === 'FILE_DONE' && event.payload.filename.endsWith('UserDTO.java'))
|
30
|
+
.length).toBe(1);
|
31
31
|
expect(stormEvents.at(-1).type).toBe('BLOCK_READY');
|
32
32
|
});
|
33
33
|
});
|
@@ -11,9 +11,10 @@ exports.parserOptions = void 0;
|
|
11
11
|
const event_parser_1 = require("../../src/storm/event-parser");
|
12
12
|
const simple_blog_events_json_1 = __importDefault(require("./simple-blog-events.json"));
|
13
13
|
const predefined_user_events_json_1 = __importDefault(require("./predefined-user-events.json"));
|
14
|
+
const blog_events_json_1 = __importDefault(require("./blog-events.json"));
|
14
15
|
exports.parserOptions = {
|
15
16
|
serviceKind: 'kapeta/block-service:local',
|
16
|
-
serviceLanguage: 'kapeta/language-target-
|
17
|
+
serviceLanguage: 'kapeta/language-target-java-spring-boot:local',
|
17
18
|
frontendKind: 'kapeta/block-type-frontend:local',
|
18
19
|
frontendLanguage: 'kapeta/language-target-react-ts:local',
|
19
20
|
cliKind: 'kapeta/block-type-cli:local',
|
@@ -27,7 +28,7 @@ exports.parserOptions = {
|
|
27
28
|
publisherKind: 'kapeta/resource-type-publisher:local',
|
28
29
|
subscriberKind: 'kapeta/resource-type-subscriber:local',
|
29
30
|
databaseKind: 'kapeta/block-type-database:local',
|
30
|
-
apiKind: 'kapeta/
|
31
|
+
apiKind: 'kapeta/resource-type-rest-api:local',
|
31
32
|
clientKind: 'kapeta/block-type-client:local',
|
32
33
|
webPageKind: 'kapeta/block-type-web-page:local',
|
33
34
|
webFragmentKind: 'kapeta/block-type-web-fragment:local',
|
@@ -176,7 +177,7 @@ describe('event-parser', () => {
|
|
176
177
|
const blogService = result.blocks.find((block) => block.aiName === 'blog-service');
|
177
178
|
expect(blogService).toBeDefined();
|
178
179
|
expect(blogService?.content).toBeDefined();
|
179
|
-
const apiProviders = blogService?.content?.spec?.providers?.filter((provider) => provider.kind === 'kapeta/
|
180
|
+
const apiProviders = blogService?.content?.spec?.providers?.filter((provider) => provider.kind === 'kapeta/resource-type-rest-api:local');
|
180
181
|
expect(apiProviders).toBeDefined();
|
181
182
|
expect(apiProviders.length).toBe(2);
|
182
183
|
expect(apiProviders['0'].spec.source.value).not.toBe('');
|
@@ -190,9 +191,26 @@ describe('event-parser', () => {
|
|
190
191
|
}
|
191
192
|
const result = await parser.toResult('kapeta');
|
192
193
|
expect(result.blocks.length).toBe(1);
|
193
|
-
|
194
|
-
expect(
|
195
|
-
expect(
|
196
|
-
expect(
|
194
|
+
const block = result.blocks[0];
|
195
|
+
expect(block.content.metadata.title).toBe('user-service');
|
196
|
+
expect(block.content.metadata.title).toBe('user-service');
|
197
|
+
expect(block.content.metadata.name).toBe('kapeta/user-service');
|
198
|
+
expect(block.archetype).toBeDefined();
|
199
|
+
expect(block.content.spec.target?.options).toBeDefined();
|
200
|
+
expect(block.content.spec.target?.options.groupId).toBe('ai.kapeta');
|
201
|
+
expect(block.content.spec.target?.options.artifactId).toBe('blogplatform');
|
202
|
+
expect(block.content.spec.target?.options.basePackage).toBe('ai.kapeta.blogplatform');
|
203
|
+
});
|
204
|
+
it('ensure post-service has api', async () => {
|
205
|
+
const events = blog_events_json_1.default;
|
206
|
+
const parser = new event_parser_1.StormEventParser(exports.parserOptions);
|
207
|
+
for (const event of events) {
|
208
|
+
await parser.processEvent('kapeta', event);
|
209
|
+
}
|
210
|
+
const result = await parser.toResult('kapeta', true);
|
211
|
+
const postService = result.blocks.find((block) => block.aiName === 'post-service');
|
212
|
+
expect(postService).toBeDefined();
|
213
|
+
expect(postService?.content?.spec?.providers?.length).toBe(1);
|
214
|
+
expect(postService?.content?.spec?.providers[0].spec.source.value.startsWith('controller')).toBeTruthy();
|
197
215
|
});
|
198
216
|
});
|
@@ -1,4 +1,13 @@
|
|
1
1
|
[
|
2
|
+
{
|
3
|
+
"type": "CREATE_PLAN_PROPERTIES",
|
4
|
+
"reason": "Define the properties for the plan itself",
|
5
|
+
"payload": {
|
6
|
+
"description": "A blogging platform with user management, post management, and comment management functionalities.",
|
7
|
+
"name": "Blog Platform"
|
8
|
+
},
|
9
|
+
"created": 1720768973436
|
10
|
+
},
|
2
11
|
{
|
3
12
|
"type": "CREATE_BLOCK",
|
4
13
|
"reason": "Handles user registration, authentication, and authorization.",
|
package/package.json
CHANGED
@@ -76,6 +76,7 @@ export interface StormOptions {
|
|
76
76
|
desktopKind: string;
|
77
77
|
desktopLanguage: string;
|
78
78
|
gatewayKind: string;
|
79
|
+
[key: string]: string;
|
79
80
|
}
|
80
81
|
|
81
82
|
function prettifyKaplang(source: string) {
|
@@ -288,7 +289,7 @@ export class StormEventParser {
|
|
288
289
|
this.blocks[evt.payload.name] = {
|
289
290
|
...evt.payload,
|
290
291
|
apis: apis ?? [],
|
291
|
-
models: models ??[],
|
292
|
+
models: models ?? [],
|
292
293
|
types: types ?? [],
|
293
294
|
};
|
294
295
|
evt.payload.blockRef = StormEventParser.toRef(handle, evt.payload.name).toNormalizedString();
|
@@ -364,7 +365,7 @@ export class StormEventParser {
|
|
364
365
|
return this.error;
|
365
366
|
}
|
366
367
|
|
367
|
-
public async toResult(handle: string): Promise<StormDefinitions> {
|
368
|
+
public async toResult(handle: string, warn: boolean = false): Promise<StormDefinitions> {
|
368
369
|
const planRef = StormEventParser.toRef(handle, this.planName || 'undefined');
|
369
370
|
const blockDefinitions = await this.toBlockDefinitions(handle);
|
370
371
|
const refIdMap: { [key: string]: string } = {};
|
@@ -409,12 +410,14 @@ export class StormEventParser {
|
|
409
410
|
);
|
410
411
|
|
411
412
|
if (!apiResource) {
|
412
|
-
|
413
|
-
|
414
|
-
|
415
|
-
|
416
|
-
|
417
|
-
|
413
|
+
if (warn) {
|
414
|
+
console.warn(
|
415
|
+
'API resource not found: %s on %s',
|
416
|
+
apiConnection.fromResource,
|
417
|
+
apiProviderRef.toNormalizedString(),
|
418
|
+
apiConnection
|
419
|
+
);
|
420
|
+
}
|
418
421
|
return;
|
419
422
|
}
|
420
423
|
|
@@ -428,12 +431,14 @@ export class StormEventParser {
|
|
428
431
|
});
|
429
432
|
|
430
433
|
if (!clientResource) {
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
|
436
|
-
|
434
|
+
if (warn) {
|
435
|
+
console.warn(
|
436
|
+
'Client resource not found: %s on %s',
|
437
|
+
apiConnection.toResource,
|
438
|
+
clientConsumerRef.toNormalizedString(),
|
439
|
+
apiConnection
|
440
|
+
);
|
441
|
+
}
|
437
442
|
return;
|
438
443
|
}
|
439
444
|
|
@@ -487,7 +492,7 @@ export class StormEventParser {
|
|
487
492
|
blockId: refIdMap[fromRef.toNormalizedString()],
|
488
493
|
resourceName: connection.fromResource,
|
489
494
|
},
|
490
|
-
mapping: this.toConnectionMapping(handle, connection, blockDefinitions),
|
495
|
+
mapping: this.toConnectionMapping(handle, connection, blockDefinitions, warn),
|
491
496
|
} satisfies Connection;
|
492
497
|
});
|
493
498
|
|
@@ -521,7 +526,7 @@ export class StormEventParser {
|
|
521
526
|
let blockDefinitionInfo: BlockDefinitionInfo;
|
522
527
|
|
523
528
|
if (blockInfo.archetype) {
|
524
|
-
blockDefinitionInfo = await this.resolveArchetypeBlockDefinition(blockRef, blockInfo);
|
529
|
+
blockDefinitionInfo = await this.resolveArchetypeBlockDefinition(blockRef, blockInfo, handle);
|
525
530
|
} else {
|
526
531
|
blockDefinitionInfo = this.createBlockDefinitionInfo(blockRef, blockInfo, handle);
|
527
532
|
}
|
@@ -697,7 +702,7 @@ export class StormEventParser {
|
|
697
702
|
if (firstEntry) {
|
698
703
|
firstEntry.spec.source.value += api + '\n\n';
|
699
704
|
} else {
|
700
|
-
|
705
|
+
// this might be ok as we might receive api and types before resources from the ai-service
|
701
706
|
}
|
702
707
|
}
|
703
708
|
});
|
@@ -770,7 +775,8 @@ export class StormEventParser {
|
|
770
775
|
private toConnectionMapping(
|
771
776
|
handle: string,
|
772
777
|
connection: StormConnection,
|
773
|
-
blockDefinitions: { [key: string]: BlockDefinitionInfo }
|
778
|
+
blockDefinitions: { [key: string]: BlockDefinitionInfo },
|
779
|
+
warn: boolean
|
774
780
|
): any {
|
775
781
|
if (connection.fromResourceType !== 'API') {
|
776
782
|
return;
|
@@ -789,12 +795,14 @@ export class StormEventParser {
|
|
789
795
|
);
|
790
796
|
|
791
797
|
if (!apiResource) {
|
792
|
-
|
793
|
-
|
794
|
-
|
795
|
-
|
796
|
-
|
797
|
-
|
798
|
+
if (warn) {
|
799
|
+
console.warn(
|
800
|
+
'API resource not found: %s on %s',
|
801
|
+
connection.fromResource,
|
802
|
+
fromRef.toNormalizedString(),
|
803
|
+
connection
|
804
|
+
);
|
805
|
+
}
|
798
806
|
return;
|
799
807
|
}
|
800
808
|
|
@@ -888,16 +896,43 @@ export class StormEventParser {
|
|
888
896
|
|
889
897
|
private async resolveArchetypeBlockDefinition(
|
890
898
|
blockRef: KapetaURI,
|
891
|
-
blockInfo: StormBlockInfoFilled
|
899
|
+
blockInfo: StormBlockInfoFilled,
|
900
|
+
handle: string
|
892
901
|
): Promise<BlockDefinitionInfo> {
|
893
902
|
const predefinedBlock = PREDEFINED_BLOCKS.get(blockInfo.archetype!);
|
894
903
|
if (!predefinedBlock) {
|
895
904
|
throw new Error('Predefined block not found for archetype [' + blockInfo.archetype + ']');
|
896
905
|
}
|
897
906
|
|
907
|
+
const target = this.toBlockTarget(handle, blockInfo.type);
|
908
|
+
|
898
909
|
const blockDefinition = await predefinedBlock.getBlockDefinition();
|
899
910
|
_.set(blockDefinition!, ['metadata', 'name'], blockRef.fullName);
|
900
911
|
_.set(blockDefinition!, ['metadata', 'title'], blockRef.name);
|
912
|
+
_.set(blockDefinition!, ['spec', 'target', 'options'], target?.options);
|
913
|
+
|
914
|
+
const options: StormOptions = this.options;
|
915
|
+
|
916
|
+
function getKind(kind: string): string | undefined {
|
917
|
+
for (const prop in options) {
|
918
|
+
if (options.hasOwnProperty(prop)) {
|
919
|
+
const value = options[prop];
|
920
|
+
if (value.startsWith(kind)) {
|
921
|
+
return value;
|
922
|
+
}
|
923
|
+
}
|
924
|
+
}
|
925
|
+
}
|
926
|
+
|
927
|
+
blockDefinition!.kind = getKind(parseKapetaUri(blockDefinition!.kind).fullName) ?? blockDefinition!.kind;
|
928
|
+
for (const provider of blockDefinition!.spec.providers ?? []) {
|
929
|
+
provider.kind = getKind(parseKapetaUri(provider.kind).fullName) ?? provider.kind;
|
930
|
+
}
|
931
|
+
for (const consumer of blockDefinition!.spec.consumers ?? []) {
|
932
|
+
consumer.kind = getKind(parseKapetaUri(consumer.kind).fullName) ?? consumer.kind;
|
933
|
+
}
|
934
|
+
blockDefinition!.spec.target!.kind =
|
935
|
+
getKind(parseKapetaUri(blockDefinition!.spec.target!.kind).fullName) ?? blockDefinition!.spec.target!.kind;
|
901
936
|
|
902
937
|
return {
|
903
938
|
uri: blockRef.toNormalizedString(),
|
package/src/storm/routes.ts
CHANGED
@@ -103,7 +103,7 @@ router.post('/:handle/all', async (req: KapetaBodyRequest, res: Response) => {
|
|
103
103
|
return;
|
104
104
|
}
|
105
105
|
|
106
|
-
const result = await eventParser.toResult(handle);
|
106
|
+
const result = await eventParser.toResult(handle, true);
|
107
107
|
|
108
108
|
if (metaStream.isAborted()) {
|
109
109
|
return;
|