@palettelab/sdk 0.1.20 → 0.1.21
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/README.md +45 -1
- package/dist/components/index.d.mts +1 -1
- package/dist/components/index.d.ts +1 -1
- package/dist/hooks/index.d.mts +2 -2
- package/dist/hooks/index.d.ts +2 -2
- package/dist/{index-D0i35Hem.d.ts → index-CGSwI4TZ.d.ts} +1 -1
- package/dist/{index-DsfTFnZb.d.mts → index-CmY9M7Rg.d.mts} +1 -1
- package/dist/index.d.mts +163 -4
- package/dist/index.d.ts +163 -4
- package/dist/index.js +255 -1
- package/dist/index.mjs +250 -1
- package/dist/{plugin-dpLzOtF6.d.mts → plugin-DXqw6d0s.d.mts} +37 -1
- package/dist/{plugin-dpLzOtF6.d.ts → plugin-DXqw6d0s.d.ts} +37 -1
- package/dist/router/index.d.mts +2 -2
- package/dist/router/index.d.ts +2 -2
- package/dist/types/index.d.mts +1 -1
- package/dist/types/index.d.ts +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -20,6 +20,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
20
20
|
// src/index.ts
|
|
21
21
|
var src_exports = {};
|
|
22
22
|
__export(src_exports, {
|
|
23
|
+
BrokerCallError: () => BrokerCallError,
|
|
23
24
|
DataRoomClient: () => DataRoomClient,
|
|
24
25
|
Link: () => Link,
|
|
25
26
|
OrganizationClient: () => OrganizationClient,
|
|
@@ -31,12 +32,14 @@ __export(src_exports, {
|
|
|
31
32
|
UserClient: () => UserClient,
|
|
32
33
|
apiFetch: () => apiFetch,
|
|
33
34
|
apiUpload: () => apiUpload,
|
|
35
|
+
broker: () => broker,
|
|
34
36
|
createMockPlatformContext: () => createMockPlatformContext,
|
|
35
37
|
createPaletteClient: () => createPaletteClient,
|
|
36
38
|
createSandboxBridge: () => createSandboxBridge,
|
|
37
39
|
dataRooms: () => dataRooms,
|
|
38
40
|
disconnectConnection: () => disconnectConnection,
|
|
39
41
|
errorFromResponse: () => errorFromResponse,
|
|
42
|
+
events: () => events,
|
|
40
43
|
getBaseUrl: () => getBaseUrl,
|
|
41
44
|
getConnections: () => getConnections,
|
|
42
45
|
getInstallConfig: () => getInstallConfig,
|
|
@@ -47,7 +50,9 @@ __export(src_exports, {
|
|
|
47
50
|
isSandboxRuntime: () => isSandboxRuntime,
|
|
48
51
|
normalizePaletteLanguage: () => normalizePaletteLanguage,
|
|
49
52
|
notFound: () => notFound,
|
|
53
|
+
palette: () => palette,
|
|
50
54
|
requireConnection: () => requireConnection,
|
|
55
|
+
servicesProxy: () => servicesProxy,
|
|
51
56
|
setBaseUrl: () => setBaseUrl,
|
|
52
57
|
startConnection: () => startConnection,
|
|
53
58
|
translate: () => translate,
|
|
@@ -385,6 +390,238 @@ var DataRoomClient = class {
|
|
|
385
390
|
};
|
|
386
391
|
var dataRooms = new DataRoomClient();
|
|
387
392
|
|
|
393
|
+
// src/services.ts
|
|
394
|
+
var BrokerCallError = class extends Error {
|
|
395
|
+
constructor(message, target, status) {
|
|
396
|
+
super(message);
|
|
397
|
+
this.target = target;
|
|
398
|
+
this.status = status;
|
|
399
|
+
this.name = "BrokerCallError";
|
|
400
|
+
}
|
|
401
|
+
};
|
|
402
|
+
var CALLER_HEADER = "X-Palette-Caller-App";
|
|
403
|
+
function currentPluginId() {
|
|
404
|
+
if (typeof window === "undefined") return void 0;
|
|
405
|
+
const match = window.location.pathname.match(/\/apps\/([^/?#]+)/);
|
|
406
|
+
return match ? decodeURIComponent(match[1]) : void 0;
|
|
407
|
+
}
|
|
408
|
+
async function brokerCallDirect(target, payload, options = {}) {
|
|
409
|
+
const callerAppId = options.callerAppId ?? currentPluginId();
|
|
410
|
+
const headers = {};
|
|
411
|
+
if (callerAppId) headers[CALLER_HEADER] = callerAppId;
|
|
412
|
+
const res = await apiFetch("/api/v1/os-broker/dispatch", {
|
|
413
|
+
method: "POST",
|
|
414
|
+
headers,
|
|
415
|
+
body: JSON.stringify({ target, payload: payload ?? {}, caller_app_id: callerAppId }),
|
|
416
|
+
signal: options.signal
|
|
417
|
+
});
|
|
418
|
+
if (!res.ok) {
|
|
419
|
+
let detail;
|
|
420
|
+
try {
|
|
421
|
+
detail = (await res.json()).detail;
|
|
422
|
+
} catch {
|
|
423
|
+
detail = res.statusText;
|
|
424
|
+
}
|
|
425
|
+
throw new BrokerCallError(detail ?? `broker dispatch failed: ${res.status}`, target, res.status);
|
|
426
|
+
}
|
|
427
|
+
const body = await res.json();
|
|
428
|
+
return body.result;
|
|
429
|
+
}
|
|
430
|
+
async function brokerCallSandboxed(target, payload, options = {}) {
|
|
431
|
+
return sandboxRequest({
|
|
432
|
+
kind: "palette.broker.call",
|
|
433
|
+
target,
|
|
434
|
+
payload: payload ?? {},
|
|
435
|
+
callerAppId: options.callerAppId
|
|
436
|
+
});
|
|
437
|
+
}
|
|
438
|
+
async function brokerEmitDirect(target, payload, options = {}) {
|
|
439
|
+
const callerAppId = options.callerAppId ?? currentPluginId();
|
|
440
|
+
if (!callerAppId) {
|
|
441
|
+
throw new BrokerCallError(
|
|
442
|
+
"events.emit requires a caller app id \u2014 only plugins may emit declared events",
|
|
443
|
+
target
|
|
444
|
+
);
|
|
445
|
+
}
|
|
446
|
+
const res = await apiFetch("/api/v1/os-broker/events/emit", {
|
|
447
|
+
method: "POST",
|
|
448
|
+
headers: { [CALLER_HEADER]: callerAppId },
|
|
449
|
+
body: JSON.stringify({ target, payload: payload ?? {}, caller_app_id: callerAppId }),
|
|
450
|
+
signal: options.signal
|
|
451
|
+
});
|
|
452
|
+
if (!res.ok) {
|
|
453
|
+
let detail;
|
|
454
|
+
try {
|
|
455
|
+
detail = (await res.json()).detail;
|
|
456
|
+
} catch {
|
|
457
|
+
detail = res.statusText;
|
|
458
|
+
}
|
|
459
|
+
throw new BrokerCallError(detail ?? `event emit failed: ${res.status}`, target, res.status);
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
async function brokerEmitSandboxed(target, payload, options = {}) {
|
|
463
|
+
await sandboxRequest({
|
|
464
|
+
kind: "palette.broker.emit",
|
|
465
|
+
target,
|
|
466
|
+
payload: payload ?? {},
|
|
467
|
+
callerAppId: options.callerAppId
|
|
468
|
+
});
|
|
469
|
+
}
|
|
470
|
+
function sandboxRequest(message) {
|
|
471
|
+
if (typeof window === "undefined") {
|
|
472
|
+
return Promise.reject(new BrokerCallError("sandbox bridge unavailable", message.target));
|
|
473
|
+
}
|
|
474
|
+
return new Promise((resolve, reject) => {
|
|
475
|
+
const id = `${Date.now()}.${Math.random().toString(36).slice(2)}`;
|
|
476
|
+
const onMessage = (ev) => {
|
|
477
|
+
const data = ev.data;
|
|
478
|
+
if (!data || data.id !== id) return;
|
|
479
|
+
window.removeEventListener("message", onMessage);
|
|
480
|
+
if (data.error) {
|
|
481
|
+
reject(new BrokerCallError(data.error.message, message.target, data.error.status));
|
|
482
|
+
} else {
|
|
483
|
+
resolve(data.result);
|
|
484
|
+
}
|
|
485
|
+
};
|
|
486
|
+
window.addEventListener("message", onMessage);
|
|
487
|
+
window.parent?.postMessage({ ...message, id }, "*");
|
|
488
|
+
});
|
|
489
|
+
}
|
|
490
|
+
var broker = {
|
|
491
|
+
async call(target, payload, options) {
|
|
492
|
+
return isSandboxRuntime() ? brokerCallSandboxed(target, payload, options) : brokerCallDirect(target, payload, options);
|
|
493
|
+
},
|
|
494
|
+
async emit(target, payload, options) {
|
|
495
|
+
if (isSandboxRuntime()) return brokerEmitSandboxed(target, payload, options);
|
|
496
|
+
return brokerEmitDirect(target, payload, options);
|
|
497
|
+
}
|
|
498
|
+
};
|
|
499
|
+
function servicesProxy(namespaceVersion) {
|
|
500
|
+
if (!namespaceVersion.includes("/")) {
|
|
501
|
+
throw new BrokerCallError("namespaceVersion must look like 'org/v1'", namespaceVersion);
|
|
502
|
+
}
|
|
503
|
+
const buildProxy = (segments) => new Proxy(function() {
|
|
504
|
+
}, {
|
|
505
|
+
get(_target, prop) {
|
|
506
|
+
if (typeof prop !== "string") return void 0;
|
|
507
|
+
return buildProxy([...segments, prop]);
|
|
508
|
+
},
|
|
509
|
+
apply(_target, _thisArg, args) {
|
|
510
|
+
const method = segments.join(".");
|
|
511
|
+
if (!method) {
|
|
512
|
+
throw new BrokerCallError("missing method name", namespaceVersion);
|
|
513
|
+
}
|
|
514
|
+
const [payload, options] = args;
|
|
515
|
+
return broker.call(`${namespaceVersion}#${method}`, payload, options);
|
|
516
|
+
}
|
|
517
|
+
});
|
|
518
|
+
return buildProxy([]);
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
// src/events.ts
|
|
522
|
+
var SUBSCRIBERS = /* @__PURE__ */ new Map();
|
|
523
|
+
var activeStream = null;
|
|
524
|
+
var activeStreamUrl = null;
|
|
525
|
+
var sandboxBound = false;
|
|
526
|
+
function currentPluginId2() {
|
|
527
|
+
if (typeof window === "undefined") return void 0;
|
|
528
|
+
const match = window.location.pathname.match(/\/apps\/([^/?#]+)/);
|
|
529
|
+
return match ? decodeURIComponent(match[1]) : void 0;
|
|
530
|
+
}
|
|
531
|
+
function streamUrl() {
|
|
532
|
+
const params = new URLSearchParams();
|
|
533
|
+
const targets = Array.from(SUBSCRIBERS.keys());
|
|
534
|
+
if (targets.length) params.set("targets", targets.join(","));
|
|
535
|
+
const callerAppId = currentPluginId2();
|
|
536
|
+
if (callerAppId) params.set("caller_app_id", callerAppId);
|
|
537
|
+
const query = params.toString();
|
|
538
|
+
return `/api/v1/os-broker/events/stream${query ? `?${query}` : ""}`;
|
|
539
|
+
}
|
|
540
|
+
function ensureStream() {
|
|
541
|
+
if (activeStream || typeof window === "undefined") return;
|
|
542
|
+
activeStreamUrl = streamUrl();
|
|
543
|
+
activeStream = new EventSource(activeStreamUrl, { withCredentials: true });
|
|
544
|
+
activeStream.onmessage = (ev) => {
|
|
545
|
+
try {
|
|
546
|
+
const data = JSON.parse(ev.data);
|
|
547
|
+
const handlers = SUBSCRIBERS.get(data.target);
|
|
548
|
+
if (!handlers) return;
|
|
549
|
+
for (const handler of handlers) {
|
|
550
|
+
try {
|
|
551
|
+
handler(data.payload, data.meta);
|
|
552
|
+
} catch (err) {
|
|
553
|
+
console.error("palette.events handler threw", err);
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
} catch (err) {
|
|
557
|
+
console.warn("palette.events: malformed event", err);
|
|
558
|
+
}
|
|
559
|
+
};
|
|
560
|
+
activeStream.onerror = () => {
|
|
561
|
+
};
|
|
562
|
+
}
|
|
563
|
+
function refreshStream() {
|
|
564
|
+
if (typeof window === "undefined" || isSandboxRuntime()) return;
|
|
565
|
+
const nextUrl = streamUrl();
|
|
566
|
+
if (activeStream && activeStreamUrl === nextUrl) return;
|
|
567
|
+
activeStream?.close();
|
|
568
|
+
activeStream = null;
|
|
569
|
+
activeStreamUrl = null;
|
|
570
|
+
if (SUBSCRIBERS.size > 0) ensureStream();
|
|
571
|
+
}
|
|
572
|
+
function ensureSandboxBound() {
|
|
573
|
+
if (sandboxBound || typeof window === "undefined") return;
|
|
574
|
+
sandboxBound = true;
|
|
575
|
+
window.addEventListener("message", (ev) => {
|
|
576
|
+
const data = ev.data;
|
|
577
|
+
if (!data || data.kind !== "palette.broker.event" || !data.target) return;
|
|
578
|
+
const handlers = SUBSCRIBERS.get(data.target);
|
|
579
|
+
if (!handlers) return;
|
|
580
|
+
const meta = data.meta ?? { target: data.target, organizationId: null, occurredAt: (/* @__PURE__ */ new Date()).toISOString() };
|
|
581
|
+
for (const handler of handlers) {
|
|
582
|
+
try {
|
|
583
|
+
handler(data.payload, meta);
|
|
584
|
+
} catch (err) {
|
|
585
|
+
console.error("palette.events handler threw", err);
|
|
586
|
+
}
|
|
587
|
+
}
|
|
588
|
+
});
|
|
589
|
+
}
|
|
590
|
+
var events = {
|
|
591
|
+
on(target, handler) {
|
|
592
|
+
let handlers = SUBSCRIBERS.get(target);
|
|
593
|
+
if (!handlers) {
|
|
594
|
+
handlers = /* @__PURE__ */ new Set();
|
|
595
|
+
SUBSCRIBERS.set(target, handlers);
|
|
596
|
+
}
|
|
597
|
+
handlers.add(handler);
|
|
598
|
+
if (isSandboxRuntime()) {
|
|
599
|
+
ensureSandboxBound();
|
|
600
|
+
window.parent?.postMessage({ kind: "palette.broker.subscribe", target }, "*");
|
|
601
|
+
} else {
|
|
602
|
+
refreshStream();
|
|
603
|
+
}
|
|
604
|
+
return () => {
|
|
605
|
+
handlers.delete(handler);
|
|
606
|
+
if (handlers.size === 0) {
|
|
607
|
+
SUBSCRIBERS.delete(target);
|
|
608
|
+
if (isSandboxRuntime()) {
|
|
609
|
+
window.parent?.postMessage({ kind: "palette.broker.unsubscribe", target }, "*");
|
|
610
|
+
} else {
|
|
611
|
+
refreshStream();
|
|
612
|
+
}
|
|
613
|
+
}
|
|
614
|
+
};
|
|
615
|
+
},
|
|
616
|
+
async emit(target, payload) {
|
|
617
|
+
await broker.emit(target, payload);
|
|
618
|
+
},
|
|
619
|
+
/** Diagnostic: list active subscriptions in this page. */
|
|
620
|
+
active() {
|
|
621
|
+
return Array.from(SUBSCRIBERS.keys());
|
|
622
|
+
}
|
|
623
|
+
};
|
|
624
|
+
|
|
388
625
|
// src/permissions.ts
|
|
389
626
|
function hasPermission(ctx, permission) {
|
|
390
627
|
return ctx.permissions?.includes(permission) ?? false;
|
|
@@ -714,9 +951,21 @@ function createPaletteClient(ctx) {
|
|
|
714
951
|
success: (message) => ctx?.showToast(message, "success"),
|
|
715
952
|
error: (message) => ctx?.showToast(message, "error"),
|
|
716
953
|
info: (message) => ctx?.showToast(message, "info")
|
|
717
|
-
}
|
|
954
|
+
},
|
|
955
|
+
/**
|
|
956
|
+
* OS-broker RPC. Typed entry point: `palette.services("org/v1").members.list({...})`.
|
|
957
|
+
* The proxy resolves a dotted method chain into a qualified target string
|
|
958
|
+
* and dispatches via the broker (in-process for plugins on the host,
|
|
959
|
+
* postMessage for sandboxed iframe apps).
|
|
960
|
+
*/
|
|
961
|
+
services: (namespaceVersion) => servicesProxy(namespaceVersion),
|
|
962
|
+
/** Low-level broker accessor when you don't want the typed proxy. */
|
|
963
|
+
broker,
|
|
964
|
+
/** OS-broker pub/sub. `events.on(target, fn)` returns an unsubscribe function. */
|
|
965
|
+
events
|
|
718
966
|
};
|
|
719
967
|
}
|
|
968
|
+
var palette = createPaletteClient();
|
|
720
969
|
|
|
721
970
|
// src/i18n.ts
|
|
722
971
|
var import_react3 = require("react");
|
|
@@ -1179,6 +1428,7 @@ function usePluginChat(agentId) {
|
|
|
1179
1428
|
}
|
|
1180
1429
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1181
1430
|
0 && (module.exports = {
|
|
1431
|
+
BrokerCallError,
|
|
1182
1432
|
DataRoomClient,
|
|
1183
1433
|
Link,
|
|
1184
1434
|
OrganizationClient,
|
|
@@ -1190,12 +1440,14 @@ function usePluginChat(agentId) {
|
|
|
1190
1440
|
UserClient,
|
|
1191
1441
|
apiFetch,
|
|
1192
1442
|
apiUpload,
|
|
1443
|
+
broker,
|
|
1193
1444
|
createMockPlatformContext,
|
|
1194
1445
|
createPaletteClient,
|
|
1195
1446
|
createSandboxBridge,
|
|
1196
1447
|
dataRooms,
|
|
1197
1448
|
disconnectConnection,
|
|
1198
1449
|
errorFromResponse,
|
|
1450
|
+
events,
|
|
1199
1451
|
getBaseUrl,
|
|
1200
1452
|
getConnections,
|
|
1201
1453
|
getInstallConfig,
|
|
@@ -1206,7 +1458,9 @@ function usePluginChat(agentId) {
|
|
|
1206
1458
|
isSandboxRuntime,
|
|
1207
1459
|
normalizePaletteLanguage,
|
|
1208
1460
|
notFound,
|
|
1461
|
+
palette,
|
|
1209
1462
|
requireConnection,
|
|
1463
|
+
servicesProxy,
|
|
1210
1464
|
setBaseUrl,
|
|
1211
1465
|
startConnection,
|
|
1212
1466
|
translate,
|
package/dist/index.mjs
CHANGED
|
@@ -317,6 +317,238 @@ var DataRoomClient = class {
|
|
|
317
317
|
};
|
|
318
318
|
var dataRooms = new DataRoomClient();
|
|
319
319
|
|
|
320
|
+
// src/services.ts
|
|
321
|
+
var BrokerCallError = class extends Error {
|
|
322
|
+
constructor(message, target, status) {
|
|
323
|
+
super(message);
|
|
324
|
+
this.target = target;
|
|
325
|
+
this.status = status;
|
|
326
|
+
this.name = "BrokerCallError";
|
|
327
|
+
}
|
|
328
|
+
};
|
|
329
|
+
var CALLER_HEADER = "X-Palette-Caller-App";
|
|
330
|
+
function currentPluginId() {
|
|
331
|
+
if (typeof window === "undefined") return void 0;
|
|
332
|
+
const match = window.location.pathname.match(/\/apps\/([^/?#]+)/);
|
|
333
|
+
return match ? decodeURIComponent(match[1]) : void 0;
|
|
334
|
+
}
|
|
335
|
+
async function brokerCallDirect(target, payload, options = {}) {
|
|
336
|
+
const callerAppId = options.callerAppId ?? currentPluginId();
|
|
337
|
+
const headers = {};
|
|
338
|
+
if (callerAppId) headers[CALLER_HEADER] = callerAppId;
|
|
339
|
+
const res = await apiFetch("/api/v1/os-broker/dispatch", {
|
|
340
|
+
method: "POST",
|
|
341
|
+
headers,
|
|
342
|
+
body: JSON.stringify({ target, payload: payload ?? {}, caller_app_id: callerAppId }),
|
|
343
|
+
signal: options.signal
|
|
344
|
+
});
|
|
345
|
+
if (!res.ok) {
|
|
346
|
+
let detail;
|
|
347
|
+
try {
|
|
348
|
+
detail = (await res.json()).detail;
|
|
349
|
+
} catch {
|
|
350
|
+
detail = res.statusText;
|
|
351
|
+
}
|
|
352
|
+
throw new BrokerCallError(detail ?? `broker dispatch failed: ${res.status}`, target, res.status);
|
|
353
|
+
}
|
|
354
|
+
const body = await res.json();
|
|
355
|
+
return body.result;
|
|
356
|
+
}
|
|
357
|
+
async function brokerCallSandboxed(target, payload, options = {}) {
|
|
358
|
+
return sandboxRequest({
|
|
359
|
+
kind: "palette.broker.call",
|
|
360
|
+
target,
|
|
361
|
+
payload: payload ?? {},
|
|
362
|
+
callerAppId: options.callerAppId
|
|
363
|
+
});
|
|
364
|
+
}
|
|
365
|
+
async function brokerEmitDirect(target, payload, options = {}) {
|
|
366
|
+
const callerAppId = options.callerAppId ?? currentPluginId();
|
|
367
|
+
if (!callerAppId) {
|
|
368
|
+
throw new BrokerCallError(
|
|
369
|
+
"events.emit requires a caller app id \u2014 only plugins may emit declared events",
|
|
370
|
+
target
|
|
371
|
+
);
|
|
372
|
+
}
|
|
373
|
+
const res = await apiFetch("/api/v1/os-broker/events/emit", {
|
|
374
|
+
method: "POST",
|
|
375
|
+
headers: { [CALLER_HEADER]: callerAppId },
|
|
376
|
+
body: JSON.stringify({ target, payload: payload ?? {}, caller_app_id: callerAppId }),
|
|
377
|
+
signal: options.signal
|
|
378
|
+
});
|
|
379
|
+
if (!res.ok) {
|
|
380
|
+
let detail;
|
|
381
|
+
try {
|
|
382
|
+
detail = (await res.json()).detail;
|
|
383
|
+
} catch {
|
|
384
|
+
detail = res.statusText;
|
|
385
|
+
}
|
|
386
|
+
throw new BrokerCallError(detail ?? `event emit failed: ${res.status}`, target, res.status);
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
async function brokerEmitSandboxed(target, payload, options = {}) {
|
|
390
|
+
await sandboxRequest({
|
|
391
|
+
kind: "palette.broker.emit",
|
|
392
|
+
target,
|
|
393
|
+
payload: payload ?? {},
|
|
394
|
+
callerAppId: options.callerAppId
|
|
395
|
+
});
|
|
396
|
+
}
|
|
397
|
+
function sandboxRequest(message) {
|
|
398
|
+
if (typeof window === "undefined") {
|
|
399
|
+
return Promise.reject(new BrokerCallError("sandbox bridge unavailable", message.target));
|
|
400
|
+
}
|
|
401
|
+
return new Promise((resolve, reject) => {
|
|
402
|
+
const id = `${Date.now()}.${Math.random().toString(36).slice(2)}`;
|
|
403
|
+
const onMessage = (ev) => {
|
|
404
|
+
const data = ev.data;
|
|
405
|
+
if (!data || data.id !== id) return;
|
|
406
|
+
window.removeEventListener("message", onMessage);
|
|
407
|
+
if (data.error) {
|
|
408
|
+
reject(new BrokerCallError(data.error.message, message.target, data.error.status));
|
|
409
|
+
} else {
|
|
410
|
+
resolve(data.result);
|
|
411
|
+
}
|
|
412
|
+
};
|
|
413
|
+
window.addEventListener("message", onMessage);
|
|
414
|
+
window.parent?.postMessage({ ...message, id }, "*");
|
|
415
|
+
});
|
|
416
|
+
}
|
|
417
|
+
var broker = {
|
|
418
|
+
async call(target, payload, options) {
|
|
419
|
+
return isSandboxRuntime() ? brokerCallSandboxed(target, payload, options) : brokerCallDirect(target, payload, options);
|
|
420
|
+
},
|
|
421
|
+
async emit(target, payload, options) {
|
|
422
|
+
if (isSandboxRuntime()) return brokerEmitSandboxed(target, payload, options);
|
|
423
|
+
return brokerEmitDirect(target, payload, options);
|
|
424
|
+
}
|
|
425
|
+
};
|
|
426
|
+
function servicesProxy(namespaceVersion) {
|
|
427
|
+
if (!namespaceVersion.includes("/")) {
|
|
428
|
+
throw new BrokerCallError("namespaceVersion must look like 'org/v1'", namespaceVersion);
|
|
429
|
+
}
|
|
430
|
+
const buildProxy = (segments) => new Proxy(function() {
|
|
431
|
+
}, {
|
|
432
|
+
get(_target, prop) {
|
|
433
|
+
if (typeof prop !== "string") return void 0;
|
|
434
|
+
return buildProxy([...segments, prop]);
|
|
435
|
+
},
|
|
436
|
+
apply(_target, _thisArg, args) {
|
|
437
|
+
const method = segments.join(".");
|
|
438
|
+
if (!method) {
|
|
439
|
+
throw new BrokerCallError("missing method name", namespaceVersion);
|
|
440
|
+
}
|
|
441
|
+
const [payload, options] = args;
|
|
442
|
+
return broker.call(`${namespaceVersion}#${method}`, payload, options);
|
|
443
|
+
}
|
|
444
|
+
});
|
|
445
|
+
return buildProxy([]);
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
// src/events.ts
|
|
449
|
+
var SUBSCRIBERS = /* @__PURE__ */ new Map();
|
|
450
|
+
var activeStream = null;
|
|
451
|
+
var activeStreamUrl = null;
|
|
452
|
+
var sandboxBound = false;
|
|
453
|
+
function currentPluginId2() {
|
|
454
|
+
if (typeof window === "undefined") return void 0;
|
|
455
|
+
const match = window.location.pathname.match(/\/apps\/([^/?#]+)/);
|
|
456
|
+
return match ? decodeURIComponent(match[1]) : void 0;
|
|
457
|
+
}
|
|
458
|
+
function streamUrl() {
|
|
459
|
+
const params = new URLSearchParams();
|
|
460
|
+
const targets = Array.from(SUBSCRIBERS.keys());
|
|
461
|
+
if (targets.length) params.set("targets", targets.join(","));
|
|
462
|
+
const callerAppId = currentPluginId2();
|
|
463
|
+
if (callerAppId) params.set("caller_app_id", callerAppId);
|
|
464
|
+
const query = params.toString();
|
|
465
|
+
return `/api/v1/os-broker/events/stream${query ? `?${query}` : ""}`;
|
|
466
|
+
}
|
|
467
|
+
function ensureStream() {
|
|
468
|
+
if (activeStream || typeof window === "undefined") return;
|
|
469
|
+
activeStreamUrl = streamUrl();
|
|
470
|
+
activeStream = new EventSource(activeStreamUrl, { withCredentials: true });
|
|
471
|
+
activeStream.onmessage = (ev) => {
|
|
472
|
+
try {
|
|
473
|
+
const data = JSON.parse(ev.data);
|
|
474
|
+
const handlers = SUBSCRIBERS.get(data.target);
|
|
475
|
+
if (!handlers) return;
|
|
476
|
+
for (const handler of handlers) {
|
|
477
|
+
try {
|
|
478
|
+
handler(data.payload, data.meta);
|
|
479
|
+
} catch (err) {
|
|
480
|
+
console.error("palette.events handler threw", err);
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
} catch (err) {
|
|
484
|
+
console.warn("palette.events: malformed event", err);
|
|
485
|
+
}
|
|
486
|
+
};
|
|
487
|
+
activeStream.onerror = () => {
|
|
488
|
+
};
|
|
489
|
+
}
|
|
490
|
+
function refreshStream() {
|
|
491
|
+
if (typeof window === "undefined" || isSandboxRuntime()) return;
|
|
492
|
+
const nextUrl = streamUrl();
|
|
493
|
+
if (activeStream && activeStreamUrl === nextUrl) return;
|
|
494
|
+
activeStream?.close();
|
|
495
|
+
activeStream = null;
|
|
496
|
+
activeStreamUrl = null;
|
|
497
|
+
if (SUBSCRIBERS.size > 0) ensureStream();
|
|
498
|
+
}
|
|
499
|
+
function ensureSandboxBound() {
|
|
500
|
+
if (sandboxBound || typeof window === "undefined") return;
|
|
501
|
+
sandboxBound = true;
|
|
502
|
+
window.addEventListener("message", (ev) => {
|
|
503
|
+
const data = ev.data;
|
|
504
|
+
if (!data || data.kind !== "palette.broker.event" || !data.target) return;
|
|
505
|
+
const handlers = SUBSCRIBERS.get(data.target);
|
|
506
|
+
if (!handlers) return;
|
|
507
|
+
const meta = data.meta ?? { target: data.target, organizationId: null, occurredAt: (/* @__PURE__ */ new Date()).toISOString() };
|
|
508
|
+
for (const handler of handlers) {
|
|
509
|
+
try {
|
|
510
|
+
handler(data.payload, meta);
|
|
511
|
+
} catch (err) {
|
|
512
|
+
console.error("palette.events handler threw", err);
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
});
|
|
516
|
+
}
|
|
517
|
+
var events = {
|
|
518
|
+
on(target, handler) {
|
|
519
|
+
let handlers = SUBSCRIBERS.get(target);
|
|
520
|
+
if (!handlers) {
|
|
521
|
+
handlers = /* @__PURE__ */ new Set();
|
|
522
|
+
SUBSCRIBERS.set(target, handlers);
|
|
523
|
+
}
|
|
524
|
+
handlers.add(handler);
|
|
525
|
+
if (isSandboxRuntime()) {
|
|
526
|
+
ensureSandboxBound();
|
|
527
|
+
window.parent?.postMessage({ kind: "palette.broker.subscribe", target }, "*");
|
|
528
|
+
} else {
|
|
529
|
+
refreshStream();
|
|
530
|
+
}
|
|
531
|
+
return () => {
|
|
532
|
+
handlers.delete(handler);
|
|
533
|
+
if (handlers.size === 0) {
|
|
534
|
+
SUBSCRIBERS.delete(target);
|
|
535
|
+
if (isSandboxRuntime()) {
|
|
536
|
+
window.parent?.postMessage({ kind: "palette.broker.unsubscribe", target }, "*");
|
|
537
|
+
} else {
|
|
538
|
+
refreshStream();
|
|
539
|
+
}
|
|
540
|
+
}
|
|
541
|
+
};
|
|
542
|
+
},
|
|
543
|
+
async emit(target, payload) {
|
|
544
|
+
await broker.emit(target, payload);
|
|
545
|
+
},
|
|
546
|
+
/** Diagnostic: list active subscriptions in this page. */
|
|
547
|
+
active() {
|
|
548
|
+
return Array.from(SUBSCRIBERS.keys());
|
|
549
|
+
}
|
|
550
|
+
};
|
|
551
|
+
|
|
320
552
|
// src/permissions.ts
|
|
321
553
|
function hasPermission(ctx, permission) {
|
|
322
554
|
return ctx.permissions?.includes(permission) ?? false;
|
|
@@ -646,9 +878,21 @@ function createPaletteClient(ctx) {
|
|
|
646
878
|
success: (message) => ctx?.showToast(message, "success"),
|
|
647
879
|
error: (message) => ctx?.showToast(message, "error"),
|
|
648
880
|
info: (message) => ctx?.showToast(message, "info")
|
|
649
|
-
}
|
|
881
|
+
},
|
|
882
|
+
/**
|
|
883
|
+
* OS-broker RPC. Typed entry point: `palette.services("org/v1").members.list({...})`.
|
|
884
|
+
* The proxy resolves a dotted method chain into a qualified target string
|
|
885
|
+
* and dispatches via the broker (in-process for plugins on the host,
|
|
886
|
+
* postMessage for sandboxed iframe apps).
|
|
887
|
+
*/
|
|
888
|
+
services: (namespaceVersion) => servicesProxy(namespaceVersion),
|
|
889
|
+
/** Low-level broker accessor when you don't want the typed proxy. */
|
|
890
|
+
broker,
|
|
891
|
+
/** OS-broker pub/sub. `events.on(target, fn)` returns an unsubscribe function. */
|
|
892
|
+
events
|
|
650
893
|
};
|
|
651
894
|
}
|
|
895
|
+
var palette = createPaletteClient();
|
|
652
896
|
|
|
653
897
|
// src/i18n.ts
|
|
654
898
|
import { useCallback } from "react";
|
|
@@ -1119,6 +1363,7 @@ function usePluginChat(agentId) {
|
|
|
1119
1363
|
};
|
|
1120
1364
|
}
|
|
1121
1365
|
export {
|
|
1366
|
+
BrokerCallError,
|
|
1122
1367
|
DataRoomClient,
|
|
1123
1368
|
Link,
|
|
1124
1369
|
OrganizationClient,
|
|
@@ -1130,12 +1375,14 @@ export {
|
|
|
1130
1375
|
UserClient,
|
|
1131
1376
|
apiFetch,
|
|
1132
1377
|
apiUpload,
|
|
1378
|
+
broker,
|
|
1133
1379
|
createMockPlatformContext,
|
|
1134
1380
|
createPaletteClient,
|
|
1135
1381
|
createSandboxBridge,
|
|
1136
1382
|
dataRooms,
|
|
1137
1383
|
disconnectConnection,
|
|
1138
1384
|
errorFromResponse,
|
|
1385
|
+
events,
|
|
1139
1386
|
getBaseUrl,
|
|
1140
1387
|
getConnections,
|
|
1141
1388
|
getInstallConfig,
|
|
@@ -1146,7 +1393,9 @@ export {
|
|
|
1146
1393
|
isSandboxRuntime,
|
|
1147
1394
|
normalizePaletteLanguage,
|
|
1148
1395
|
notFound,
|
|
1396
|
+
palette,
|
|
1149
1397
|
requireConnection,
|
|
1398
|
+
servicesProxy,
|
|
1150
1399
|
setBaseUrl,
|
|
1151
1400
|
startConnection,
|
|
1152
1401
|
translate,
|
|
@@ -119,6 +119,7 @@ interface PluginManifest {
|
|
|
119
119
|
connections?: PluginConnectionDefinition[];
|
|
120
120
|
provides?: PluginProvidesDefinition;
|
|
121
121
|
requires?: PluginRequiresDefinition;
|
|
122
|
+
consumes?: PluginConsumesDefinition;
|
|
122
123
|
public_routes?: string[];
|
|
123
124
|
rate_limit?: {
|
|
124
125
|
per_minute?: number;
|
|
@@ -148,10 +149,36 @@ interface PluginServiceDefinition {
|
|
|
148
149
|
description?: string;
|
|
149
150
|
permissions?: string[];
|
|
150
151
|
routes?: PluginServiceRouteDefinition[];
|
|
152
|
+
methods?: PluginServiceMethodDefinition[];
|
|
153
|
+
}
|
|
154
|
+
interface PluginServiceMethodDefinition {
|
|
155
|
+
id?: string;
|
|
156
|
+
name?: string;
|
|
157
|
+
scope?: string;
|
|
158
|
+
version?: string;
|
|
159
|
+
label?: string;
|
|
160
|
+
description?: string;
|
|
161
|
+
input_schema?: Record<string, unknown> | string;
|
|
162
|
+
input?: Record<string, unknown> | string;
|
|
163
|
+
output_schema?: Record<string, unknown> | string;
|
|
164
|
+
output?: Record<string, unknown> | string;
|
|
165
|
+
route_method?: "GET" | "POST" | "PUT" | "PATCH" | "DELETE";
|
|
166
|
+
route_path?: string;
|
|
167
|
+
}
|
|
168
|
+
interface PluginEventDefinition {
|
|
169
|
+
id?: string;
|
|
170
|
+
topic?: string;
|
|
171
|
+
name?: string;
|
|
172
|
+
version?: string;
|
|
173
|
+
label?: string;
|
|
174
|
+
description?: string;
|
|
175
|
+
payload_schema?: Record<string, unknown> | string;
|
|
176
|
+
schema?: Record<string, unknown> | string;
|
|
151
177
|
}
|
|
152
178
|
interface PluginProvidesDefinition {
|
|
179
|
+
namespace?: string;
|
|
153
180
|
services?: PluginServiceDefinition[];
|
|
154
|
-
events?: string
|
|
181
|
+
events?: Array<string | PluginEventDefinition>;
|
|
155
182
|
}
|
|
156
183
|
interface PluginAppDependencyDefinition {
|
|
157
184
|
id: string;
|
|
@@ -167,6 +194,15 @@ interface PluginRequiresDefinition {
|
|
|
167
194
|
services?: PluginServiceDependencyDefinition[];
|
|
168
195
|
events?: string[];
|
|
169
196
|
}
|
|
197
|
+
interface PluginConsumedBrokerTargetDefinition {
|
|
198
|
+
target: string;
|
|
199
|
+
required?: boolean;
|
|
200
|
+
reason?: string;
|
|
201
|
+
}
|
|
202
|
+
interface PluginConsumesDefinition {
|
|
203
|
+
services?: Array<string | PluginConsumedBrokerTargetDefinition>;
|
|
204
|
+
events?: Array<string | PluginConsumedBrokerTargetDefinition>;
|
|
205
|
+
}
|
|
170
206
|
interface PluginAgentDefinition {
|
|
171
207
|
name: string;
|
|
172
208
|
field: string;
|