@kumori/aurora-backend-handler 1.1.25 → 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/backend-handler.ts +10 -14
- package/helpers/marketplace-helper.ts +109 -0
- package/package.json +1 -1
- package/websocket-manager.ts +48 -11
package/backend-handler.ts
CHANGED
|
@@ -54,8 +54,8 @@ import {
|
|
|
54
54
|
import EventHelper, { RegistryUpdatePayload } from "./event-helper";
|
|
55
55
|
import { environment } from "./environment";
|
|
56
56
|
import {
|
|
57
|
+
fetchAndStoreMarketplaceSchema,
|
|
57
58
|
initializeGlobalWebSocketClient,
|
|
58
|
-
loadMarketplaceItemSchema,
|
|
59
59
|
updateUserComplete,
|
|
60
60
|
} from "./websocket-manager";
|
|
61
61
|
import {
|
|
@@ -1016,19 +1016,15 @@ export class BackendHandler {
|
|
|
1016
1016
|
eventHelper.marketplace.unsubscribe.loadItems(loadItemsCb),
|
|
1017
1017
|
);
|
|
1018
1018
|
const loadSchemaCb = async (payload: string) => {
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
console.error(`Error loading schema for marketplace item:`, error);
|
|
1029
|
-
eventHelper.marketplace.publish.schemaLoadError(payload);
|
|
1030
|
-
}
|
|
1031
|
-
};
|
|
1019
|
+
try {
|
|
1020
|
+
const { item } = JSON.parse(payload) as { item: MarketplaceItem };
|
|
1021
|
+
await fetchAndStoreMarketplaceSchema(item);
|
|
1022
|
+
eventHelper.marketplace.publish.schemaLoaded(item);
|
|
1023
|
+
} catch (error) {
|
|
1024
|
+
console.error(`Error loading schema for marketplace item:`, error);
|
|
1025
|
+
eventHelper.marketplace.publish.schemaLoadError(payload);
|
|
1026
|
+
}
|
|
1027
|
+
};
|
|
1032
1028
|
|
|
1033
1029
|
eventHelper.marketplace.subscribe.loadSchema(loadSchemaCb);
|
|
1034
1030
|
this.unsubscribeFunctions.push(() =>
|
|
@@ -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
|
@@ -74,6 +74,7 @@ import { handleLinkEvent } from "./helpers/link-helper";
|
|
|
74
74
|
import { eventHelper } from "./backend-handler";
|
|
75
75
|
import { Revision } from "@kumori/aurora-interfaces/interfaces/revision-interface";
|
|
76
76
|
import { requestRevisionData } from "./api/service-api-service";
|
|
77
|
+
import { processMarketplaceSchemaResponse } from "./helpers/marketplace-helper";
|
|
77
78
|
|
|
78
79
|
let WebSocketClass: any;
|
|
79
80
|
|
|
@@ -2039,19 +2040,55 @@ const resolveServiceStatus = (service: Service): Service => {
|
|
|
2039
2040
|
status: currentRevision.status,
|
|
2040
2041
|
};
|
|
2041
2042
|
};
|
|
2042
|
-
export const
|
|
2043
|
+
export const fetchAndStoreMarketplaceSchema = async (
|
|
2043
2044
|
item: MarketplaceItem,
|
|
2044
|
-
schema: any,
|
|
2045
2045
|
): Promise<void> => {
|
|
2046
|
-
const
|
|
2047
|
-
|
|
2048
|
-
|
|
2049
|
-
i.name === item.name && i.domain === item.domain
|
|
2050
|
-
? { ...i, schema }
|
|
2051
|
-
: i,
|
|
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,
|
|
2052
2050
|
);
|
|
2053
|
-
|
|
2054
|
-
}
|
|
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
|
+
|
|
2055
2092
|
rebuildHierarchy();
|
|
2056
2093
|
await updateUserWithPlatformInfo();
|
|
2057
|
-
};
|
|
2094
|
+
};
|