@zhin.js/host-http 1.0.14 → 1.0.15
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.
|
@@ -55,6 +55,18 @@ export interface ConsoleRpcExtendedCtx {
|
|
|
55
55
|
workroomKnowledgeControl?: ConsoleWorkroomKnowledgeControlPort;
|
|
56
56
|
}
|
|
57
57
|
export interface ConsoleWorkroomProfileControlPort {
|
|
58
|
+
getPlanningStatus(projectId: string, authenticatedPrincipal?: Readonly<{
|
|
59
|
+
principalId: string;
|
|
60
|
+
}>): Promise<unknown>;
|
|
61
|
+
bootstrapPlanning(command: Readonly<{
|
|
62
|
+
operationId: string;
|
|
63
|
+
projectId: string;
|
|
64
|
+
expectedRegistryRevision: number;
|
|
65
|
+
includeTools?: readonly string[];
|
|
66
|
+
includeSkills?: readonly string[];
|
|
67
|
+
}>, authenticatedPrincipal: Readonly<{
|
|
68
|
+
principalId: string;
|
|
69
|
+
}>): Promise<unknown>;
|
|
58
70
|
publishPack(command: Readonly<{
|
|
59
71
|
operationId: string;
|
|
60
72
|
pack: unknown;
|
|
@@ -95,6 +95,8 @@ export async function dispatchExtendedConsoleRpc(type, data, ctx) {
|
|
|
95
95
|
});
|
|
96
96
|
case 'endpoint.delete_friend':
|
|
97
97
|
return deleteFriend(d, ctx);
|
|
98
|
+
case 'workroom.profile.status':
|
|
99
|
+
case 'workroom.profile.bootstrap':
|
|
98
100
|
case 'workroom.profile.pack.publish':
|
|
99
101
|
case 'workroom.profile.publish':
|
|
100
102
|
case 'workroom.profile.rollback':
|
|
@@ -118,11 +120,31 @@ async function mutateWorkroomProfile(type, data, ctx) {
|
|
|
118
120
|
if (forbidden in data)
|
|
119
121
|
return { error: `Console Workroom Profile request cannot carry ${forbidden}` };
|
|
120
122
|
}
|
|
123
|
+
if (type === 'workroom.profile.status') {
|
|
124
|
+
try {
|
|
125
|
+
return { data: await control.getPlanningStatus(requiredRpcText(data.projectId, 'projectId'), ctx.authenticatedPrincipal) };
|
|
126
|
+
}
|
|
127
|
+
catch (error) {
|
|
128
|
+
return { error: errorMessage(error) };
|
|
129
|
+
}
|
|
130
|
+
}
|
|
121
131
|
const principal = ctx.authenticatedPrincipal;
|
|
122
132
|
if (!principal)
|
|
123
133
|
return { error: 'Workroom Profile control requires an authenticated principal' };
|
|
124
134
|
try {
|
|
125
135
|
const operationId = requiredRpcText(data.operationId, 'operationId');
|
|
136
|
+
if (type === 'workroom.profile.bootstrap') {
|
|
137
|
+
const projectId = requiredRpcText(data.projectId, 'projectId');
|
|
138
|
+
const includeTools = optionalRpcTextArray(data.includeTools, 'includeTools');
|
|
139
|
+
const includeSkills = optionalRpcTextArray(data.includeSkills, 'includeSkills');
|
|
140
|
+
return { data: await control.bootstrapPlanning(Object.freeze({
|
|
141
|
+
operationId,
|
|
142
|
+
projectId,
|
|
143
|
+
expectedRegistryRevision: requiredRpcInteger(data.expectedRegistryRevision, 'expectedRegistryRevision', -1),
|
|
144
|
+
...(includeTools ? { includeTools } : {}),
|
|
145
|
+
...(includeSkills ? { includeSkills } : {}),
|
|
146
|
+
}), principal) };
|
|
147
|
+
}
|
|
126
148
|
if (type === 'workroom.profile.pack.publish') {
|
|
127
149
|
return { data: await control.publishPack(Object.freeze({ operationId, pack: requiredRpcValue(data.pack, 'pack') }), principal) };
|
|
128
150
|
}
|
|
@@ -205,6 +227,16 @@ function requiredRpcText(value, name) {
|
|
|
205
227
|
function optionalRpcText(value, name) {
|
|
206
228
|
return value === undefined ? undefined : requiredRpcText(value, name);
|
|
207
229
|
}
|
|
230
|
+
function optionalRpcTextArray(value, name) {
|
|
231
|
+
if (value === undefined)
|
|
232
|
+
return undefined;
|
|
233
|
+
if (!Array.isArray(value))
|
|
234
|
+
throw new Error(`${name} is invalid`);
|
|
235
|
+
const result = value.map((item, index) => requiredRpcText(item, `${name}.${index}`));
|
|
236
|
+
if (new Set(result).size !== result.length)
|
|
237
|
+
throw new Error(`${name} contains duplicates`);
|
|
238
|
+
return Object.freeze(result);
|
|
239
|
+
}
|
|
208
240
|
function requiredRpcInteger(value, name, minimum = 1) {
|
|
209
241
|
if (!Number.isSafeInteger(value) || Number(value) < minimum)
|
|
210
242
|
throw new Error(`${name} is invalid`);
|
package/package.json
CHANGED
|
@@ -66,6 +66,15 @@ export interface ConsoleRpcExtendedCtx {
|
|
|
66
66
|
}
|
|
67
67
|
|
|
68
68
|
export interface ConsoleWorkroomProfileControlPort {
|
|
69
|
+
getPlanningStatus(projectId: string,
|
|
70
|
+
authenticatedPrincipal?: Readonly<{ principalId: string }>): Promise<unknown>;
|
|
71
|
+
bootstrapPlanning(command: Readonly<{
|
|
72
|
+
operationId: string;
|
|
73
|
+
projectId: string;
|
|
74
|
+
expectedRegistryRevision: number;
|
|
75
|
+
includeTools?: readonly string[];
|
|
76
|
+
includeSkills?: readonly string[];
|
|
77
|
+
}>, authenticatedPrincipal: Readonly<{ principalId: string }>): Promise<unknown>;
|
|
69
78
|
publishPack(command: Readonly<{ operationId: string; pack: unknown }>,
|
|
70
79
|
authenticatedPrincipal: Readonly<{ principalId: string }>): Promise<unknown>;
|
|
71
80
|
publishProfile(command: Readonly<{
|
|
@@ -258,6 +267,8 @@ export async function dispatchExtendedConsoleRpc(
|
|
|
258
267
|
case 'endpoint.delete_friend':
|
|
259
268
|
return deleteFriend(d, ctx);
|
|
260
269
|
|
|
270
|
+
case 'workroom.profile.status':
|
|
271
|
+
case 'workroom.profile.bootstrap':
|
|
261
272
|
case 'workroom.profile.pack.publish':
|
|
262
273
|
case 'workroom.profile.publish':
|
|
263
274
|
case 'workroom.profile.rollback':
|
|
@@ -275,7 +286,8 @@ export async function dispatchExtendedConsoleRpc(
|
|
|
275
286
|
}
|
|
276
287
|
|
|
277
288
|
async function mutateWorkroomProfile(
|
|
278
|
-
type: 'workroom.profile.
|
|
289
|
+
type: 'workroom.profile.status' | 'workroom.profile.bootstrap'
|
|
290
|
+
| 'workroom.profile.pack.publish' | 'workroom.profile.publish'
|
|
279
291
|
| 'workroom.profile.rollback' | 'workroom.profile.policy.publish',
|
|
280
292
|
data: Record<string, unknown>,
|
|
281
293
|
ctx: ConsoleRpcExtendedCtx,
|
|
@@ -287,10 +299,36 @@ async function mutateWorkroomProfile(
|
|
|
287
299
|
]) {
|
|
288
300
|
if (forbidden in data) return { error: `Console Workroom Profile request cannot carry ${forbidden}` };
|
|
289
301
|
}
|
|
302
|
+
if (type === 'workroom.profile.status') {
|
|
303
|
+
try {
|
|
304
|
+
return { data: await control.getPlanningStatus(
|
|
305
|
+
requiredRpcText(data.projectId, 'projectId'),
|
|
306
|
+
ctx.authenticatedPrincipal,
|
|
307
|
+
) };
|
|
308
|
+
} catch (error) {
|
|
309
|
+
return { error: errorMessage(error) };
|
|
310
|
+
}
|
|
311
|
+
}
|
|
290
312
|
const principal = ctx.authenticatedPrincipal;
|
|
291
313
|
if (!principal) return { error: 'Workroom Profile control requires an authenticated principal' };
|
|
292
314
|
try {
|
|
293
315
|
const operationId = requiredRpcText(data.operationId, 'operationId');
|
|
316
|
+
if (type === 'workroom.profile.bootstrap') {
|
|
317
|
+
const projectId = requiredRpcText(data.projectId, 'projectId');
|
|
318
|
+
const includeTools = optionalRpcTextArray(data.includeTools, 'includeTools');
|
|
319
|
+
const includeSkills = optionalRpcTextArray(data.includeSkills, 'includeSkills');
|
|
320
|
+
return { data: await control.bootstrapPlanning(Object.freeze({
|
|
321
|
+
operationId,
|
|
322
|
+
projectId,
|
|
323
|
+
expectedRegistryRevision: requiredRpcInteger(
|
|
324
|
+
data.expectedRegistryRevision,
|
|
325
|
+
'expectedRegistryRevision',
|
|
326
|
+
-1,
|
|
327
|
+
),
|
|
328
|
+
...(includeTools ? { includeTools } : {}),
|
|
329
|
+
...(includeSkills ? { includeSkills } : {}),
|
|
330
|
+
}), principal) };
|
|
331
|
+
}
|
|
294
332
|
if (type === 'workroom.profile.pack.publish') {
|
|
295
333
|
return { data: await control.publishPack(Object.freeze({ operationId, pack: requiredRpcValue(data.pack, 'pack') }), principal) };
|
|
296
334
|
}
|
|
@@ -374,6 +412,14 @@ function optionalRpcText(value: unknown, name: string): string | undefined {
|
|
|
374
412
|
return value === undefined ? undefined : requiredRpcText(value, name);
|
|
375
413
|
}
|
|
376
414
|
|
|
415
|
+
function optionalRpcTextArray(value: unknown, name: string): readonly string[] | undefined {
|
|
416
|
+
if (value === undefined) return undefined;
|
|
417
|
+
if (!Array.isArray(value)) throw new Error(`${name} is invalid`);
|
|
418
|
+
const result = value.map((item, index) => requiredRpcText(item, `${name}.${index}`));
|
|
419
|
+
if (new Set(result).size !== result.length) throw new Error(`${name} contains duplicates`);
|
|
420
|
+
return Object.freeze(result);
|
|
421
|
+
}
|
|
422
|
+
|
|
377
423
|
function requiredRpcInteger(value: unknown, name: string, minimum = 1): number {
|
|
378
424
|
if (!Number.isSafeInteger(value) || Number(value) < minimum) throw new Error(`${name} is invalid`);
|
|
379
425
|
return Number(value);
|