@kumori/aurora-backend-handler 1.1.24 → 1.1.26
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/api/marketplace-api-service.ts +26 -77
- package/backend-handler.ts +352 -330
- package/event-helper.ts +9 -0
- package/event-names.ts +3 -0
- package/helpers/marketplace-helper.ts +109 -0
- package/package.json +1 -1
- package/websocket-manager.ts +54 -0
package/event-helper.ts
CHANGED
|
@@ -406,6 +406,9 @@ export class EventHelper {
|
|
|
406
406
|
deletionError: this.createEvent<Service>(EventNames.MarketplaceItemDeletionError).publish,
|
|
407
407
|
loadItems: this.createEvent<string[]>(EventNames.LoadMarketplaceItems).publish,
|
|
408
408
|
itemsLoaded: this.createEvent<MarketplaceItem[]>(EventNames.MarketplaceItemsLoaded).publish,
|
|
409
|
+
loadSchema: this.createEvent<string>(EventNames.LoadMarketplaceSchema).publish,
|
|
410
|
+
schemaLoaded: this.createEvent<MarketplaceItem>(EventNames.MarketplaceSchemaLoaded).publish,
|
|
411
|
+
schemaLoadError: this.createEvent<string>(EventNames.MarketplaceSchemaLoadError).publish,
|
|
409
412
|
},
|
|
410
413
|
subscribe: {
|
|
411
414
|
deployItem: this.createEvent<MarketplaceService>(EventNames.DeployMarketplaceItem).subscribe,
|
|
@@ -419,6 +422,9 @@ export class EventHelper {
|
|
|
419
422
|
deletionError: this.createEvent<Service>(EventNames.MarketplaceItemDeletionError).subscribe,
|
|
420
423
|
loadItems: this.createEvent<string[]>(EventNames.LoadMarketplaceItems).subscribe,
|
|
421
424
|
itemsLoaded: this.createEvent<MarketplaceItem[]>(EventNames.MarketplaceItemsLoaded).subscribe,
|
|
425
|
+
loadSchema: this.createEvent<string>(EventNames.LoadMarketplaceSchema).subscribe,
|
|
426
|
+
schemaLoaded: this.createEvent<MarketplaceItem>(EventNames.MarketplaceSchemaLoaded).subscribe,
|
|
427
|
+
schemaLoadError: this.createEvent<string>(EventNames.MarketplaceSchemaLoadError).subscribe,
|
|
422
428
|
},
|
|
423
429
|
unsubscribe: {
|
|
424
430
|
deployItem: this.createEvent<MarketplaceService>(EventNames.DeployMarketplaceItem).unsubscribe,
|
|
@@ -432,6 +438,9 @@ export class EventHelper {
|
|
|
432
438
|
deletionError: this.createEvent<Service>(EventNames.MarketplaceItemDeletionError).unsubscribe,
|
|
433
439
|
loadItems: this.createEvent<string[]>(EventNames.LoadMarketplaceItems).unsubscribe,
|
|
434
440
|
itemsLoaded: this.createEvent<MarketplaceItem[]>(EventNames.MarketplaceItemsLoaded).unsubscribe,
|
|
441
|
+
loadSchema: this.createEvent<string>(EventNames.LoadMarketplaceSchema).unsubscribe,
|
|
442
|
+
schemaLoaded: this.createEvent<MarketplaceItem>(EventNames.MarketplaceSchemaLoaded).unsubscribe,
|
|
443
|
+
schemaLoadError: this.createEvent<string>(EventNames.MarketplaceSchemaLoadError).unsubscribe,
|
|
435
444
|
},
|
|
436
445
|
};
|
|
437
446
|
}
|
package/event-names.ts
CHANGED
|
@@ -117,6 +117,9 @@ export enum EventNames {
|
|
|
117
117
|
MarketplaceItemDeletionError = "marketplaceItemDeletionError",
|
|
118
118
|
LoadMarketplaceItems = "loadMarketplaceItems",
|
|
119
119
|
MarketplaceItemsLoaded = "marketplaceItemsLoaded",
|
|
120
|
+
LoadMarketplaceSchema = "loadMarketplaceSchema",
|
|
121
|
+
MarketplaceSchemaLoaded = "marketplaceSchemaLoaded",
|
|
122
|
+
MarketplaceSchemaLoadError = "marketplaceSchemaLoadError",
|
|
120
123
|
// * Resource
|
|
121
124
|
CreateResource = "createResource",
|
|
122
125
|
ResourceCreated = "resourceCreated",
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
export const processMarketplaceSchemaResponse = (rawEntry: any, nameKey: string) => {
|
|
2
|
+
const roles: string[] = rawEntry.roles || [];
|
|
3
|
+
const roleName = roles.join(", ");
|
|
4
|
+
const schemas = rawEntry.schemas || [];
|
|
5
|
+
|
|
6
|
+
const processSchema = (schema: any) => {
|
|
7
|
+
const parameters: any[] = [];
|
|
8
|
+
const resources: any[] = [];
|
|
9
|
+
const channels: any[] = [];
|
|
10
|
+
|
|
11
|
+
const configProps = schema.properties?.config?.properties;
|
|
12
|
+
if (configProps) {
|
|
13
|
+
Object.entries(configProps).forEach(([key, value]: [string, any]) => {
|
|
14
|
+
parameters.push({
|
|
15
|
+
name: key,
|
|
16
|
+
type: value.type || "string",
|
|
17
|
+
required: schema.properties?.config?.required?.includes(key) || false,
|
|
18
|
+
defaultValue: value.default ?? value.enum?.[0] ?? value.const ?? undefined,
|
|
19
|
+
});
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const volumeTypes = ["Registered", "NonReplicated", "Persisted", "Volatile", "Ephemeral", "Persistent"];
|
|
24
|
+
const isVolumeResource = (v: any): boolean => {
|
|
25
|
+
if (!v.oneOf) return false;
|
|
26
|
+
return v.oneOf.some((o: any) => {
|
|
27
|
+
if (o.oneOf) return o.oneOf.some((n: any) => volumeTypes.includes(n?.properties?.$kdsl?.const?.NamedType?.Name));
|
|
28
|
+
return volumeTypes.includes(o?.properties?.$kdsl?.const?.NamedType?.Name);
|
|
29
|
+
});
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
const resourceProps = schema.properties?.resource;
|
|
33
|
+
if (resourceProps?.properties) {
|
|
34
|
+
Object.entries(resourceProps.properties).forEach(([key, value]: [string, any]) => {
|
|
35
|
+
if (isVolumeResource(value)) {
|
|
36
|
+
resources.push({
|
|
37
|
+
name: key,
|
|
38
|
+
type: "volume",
|
|
39
|
+
required: resourceProps.required?.includes(key) || false,
|
|
40
|
+
});
|
|
41
|
+
} else {
|
|
42
|
+
const typeName = value.properties?.["$kdsl"]?.const?.NamedType?.Name;
|
|
43
|
+
const resourceType = typeName ? typeName.toLowerCase() : Object.keys(value.properties || {})[0];
|
|
44
|
+
const inner = value.properties?.[resourceType] || value.properties?.inner;
|
|
45
|
+
const defaultValue =
|
|
46
|
+
inner?.default !== undefined
|
|
47
|
+
? String(inner.default)
|
|
48
|
+
: inner?.enum?.[0]
|
|
49
|
+
? String(inner.enum[0])
|
|
50
|
+
: undefined;
|
|
51
|
+
resources.push({
|
|
52
|
+
name: key,
|
|
53
|
+
type: resourceType || "string",
|
|
54
|
+
required: resourceProps.required?.includes(key) || false,
|
|
55
|
+
defaultValue,
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const srvProps = schema.properties?.srv?.properties;
|
|
62
|
+
if (srvProps) {
|
|
63
|
+
(["client", "server", "duplex"] as const).forEach((channelType) => {
|
|
64
|
+
if (srvProps[channelType]?.properties) {
|
|
65
|
+
Object.entries(srvProps[channelType].properties).forEach(([channelName, channelData]: [string, any]) => {
|
|
66
|
+
const port = channelData.properties?.port?.const || channelData.properties?.port?.enum?.[0];
|
|
67
|
+
const protocol = channelData.properties?.protocol?.const || channelData.properties?.protocol?.enum?.[0];
|
|
68
|
+
channels.push({
|
|
69
|
+
name: channelName,
|
|
70
|
+
type: channelType,
|
|
71
|
+
resource: port && protocol ? { type: "port", value: `${protocol}:${port}` } : undefined,
|
|
72
|
+
});
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
return { parameters, resources, channels };
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
if (schemas.length > 0 && schemas[0].oneOf) {
|
|
82
|
+
const processedVariants: any[] = [];
|
|
83
|
+
for (const schemaRef of schemas[0].oneOf) {
|
|
84
|
+
const refKey = schemaRef.$ref?.replace("#/$defs/", "");
|
|
85
|
+
const actualSchema = schemas[0].$defs?.[refKey];
|
|
86
|
+
if (actualSchema) {
|
|
87
|
+
const result = processSchema(actualSchema);
|
|
88
|
+
processedVariants.push({ name: nameKey, roleName, roles, variant: refKey, ...result });
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
return {
|
|
92
|
+
parameters: processedVariants[0]?.parameters || [],
|
|
93
|
+
resources: processedVariants[0]?.resources || [],
|
|
94
|
+
channels: processedVariants[0]?.channels || [],
|
|
95
|
+
name: nameKey,
|
|
96
|
+
roleName,
|
|
97
|
+
roles,
|
|
98
|
+
hasVariants: true,
|
|
99
|
+
variants: processedVariants,
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
if (schemas[0]) {
|
|
104
|
+
const result = processSchema(schemas[0]);
|
|
105
|
+
return { ...result, name: nameKey, roleName, roles, hasVariants: false };
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
return { parameters: [], resources: [], channels: [], name: nameKey, roleName, roles, hasVariants: false };
|
|
109
|
+
};
|
package/package.json
CHANGED
package/websocket-manager.ts
CHANGED
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
ClusterToken,
|
|
7
7
|
Environment,
|
|
8
8
|
Instance,
|
|
9
|
+
MarketplaceItem,
|
|
9
10
|
Notification,
|
|
10
11
|
Organization,
|
|
11
12
|
Plan,
|
|
@@ -73,6 +74,7 @@ import { handleLinkEvent } from "./helpers/link-helper";
|
|
|
73
74
|
import { eventHelper } from "./backend-handler";
|
|
74
75
|
import { Revision } from "@kumori/aurora-interfaces/interfaces/revision-interface";
|
|
75
76
|
import { requestRevisionData } from "./api/service-api-service";
|
|
77
|
+
import { processMarketplaceSchemaResponse } from "./helpers/marketplace-helper";
|
|
76
78
|
|
|
77
79
|
let WebSocketClass: any;
|
|
78
80
|
|
|
@@ -2038,3 +2040,55 @@ const resolveServiceStatus = (service: Service): Service => {
|
|
|
2038
2040
|
status: currentRevision.status,
|
|
2039
2041
|
};
|
|
2040
2042
|
};
|
|
2043
|
+
export const fetchAndStoreMarketplaceSchema = async (
|
|
2044
|
+
item: MarketplaceItem,
|
|
2045
|
+
): Promise<void> => {
|
|
2046
|
+
const tenantsWithItem: string[] = [];
|
|
2047
|
+
tenantsMap.forEach((tenantEntry, tenantId) => {
|
|
2048
|
+
const hasItem = (tenantEntry.marketplaceItems || []).some(
|
|
2049
|
+
(i) => i.name === item.name && i.domain === item.domain,
|
|
2050
|
+
);
|
|
2051
|
+
if (hasItem) tenantsWithItem.push(tenantId);
|
|
2052
|
+
});
|
|
2053
|
+
|
|
2054
|
+
if (tenantsWithItem.length === 0) return;
|
|
2055
|
+
|
|
2056
|
+
await Promise.all(
|
|
2057
|
+
tenantsWithItem.map(async (tenantId) => {
|
|
2058
|
+
try {
|
|
2059
|
+
const response = await makeGlobalWebSocketRequest(
|
|
2060
|
+
"marketplace:artifact_schema",
|
|
2061
|
+
{
|
|
2062
|
+
tenant: tenantId,
|
|
2063
|
+
module: item.name,
|
|
2064
|
+
version: item.version,
|
|
2065
|
+
domain: item.domain,
|
|
2066
|
+
artifact: item.artifact,
|
|
2067
|
+
},
|
|
2068
|
+
30000,
|
|
2069
|
+
"GET",
|
|
2070
|
+
tenantId,
|
|
2071
|
+
);
|
|
2072
|
+
|
|
2073
|
+
const data = response?.data;
|
|
2074
|
+
if (!data) return;
|
|
2075
|
+
|
|
2076
|
+
const nameKeys = Object.keys(data);
|
|
2077
|
+
const schema = processMarketplaceSchemaResponse(data[nameKeys[0]], nameKeys[0]);
|
|
2078
|
+
|
|
2079
|
+
const tenantEntry = tenantsMap.get(tenantId);
|
|
2080
|
+
if (tenantEntry) {
|
|
2081
|
+
tenantEntry.marketplaceItems = tenantEntry.marketplaceItems.map((i) =>
|
|
2082
|
+
i.name === item.name && i.domain === item.domain ? { ...i, schema } : i,
|
|
2083
|
+
);
|
|
2084
|
+
tenantsMap.set(tenantId, tenantEntry);
|
|
2085
|
+
}
|
|
2086
|
+
} catch (error) {
|
|
2087
|
+
console.error(`Error loading schema for tenant ${tenantId}:`, error);
|
|
2088
|
+
}
|
|
2089
|
+
}),
|
|
2090
|
+
);
|
|
2091
|
+
|
|
2092
|
+
rebuildHierarchy();
|
|
2093
|
+
await updateUserWithPlatformInfo();
|
|
2094
|
+
};
|