feat: expose canonical module display URLs

This commit is contained in:
ekklesia
2026-09-30 18:20:40 -05:00
parent f445a83ea5
commit 3ca6b2cb32
21 changed files with 123 additions and 16 deletions
+18 -1
View File
@@ -39,6 +39,7 @@ const inventoryPayload = {
{
contributions: [],
api: { baseUrl: "/api/v1/modules/example" },
display: { url: "/display/example" },
id: "example",
permissions: ["example.records.read"],
realtime: { baseUrl: "/api/v1/module-realtime/example" },
@@ -51,6 +52,7 @@ const inventoryPayload = {
const calendarDescriptor: HostModuleUiDescriptor = {
contributions: [],
apiBaseUrl: "/api/v1/modules/calendar",
displayPageUrl: undefined,
id: "calendar",
permissions: [],
realtimeBaseUrl: "/api/v1/module-realtime/calendar",
@@ -72,6 +74,7 @@ const navigationPayload = {
module: {
contributions: [],
api: { baseUrl: "/api/v1/modules/calendar" },
display: null,
id: "calendar",
permissions: [],
realtime: { baseUrl: "/api/v1/module-realtime/calendar" },
@@ -86,6 +89,7 @@ const navigationPayload = {
const exampleDescriptor: HostModuleUiDescriptor = {
contributions: [],
apiBaseUrl: "/api/v1/modules/example",
displayPageUrl: "/display/example",
id: "example",
permissions: ["example.records.read"],
realtimeBaseUrl: "/api/v1/module-realtime/example",
@@ -409,6 +413,7 @@ describe("module UI host context", () => {
const calendar: HostModuleUiDescriptor = {
contributions: [],
apiBaseUrl: "/api/v1/modules/calendar",
displayPageUrl: undefined,
id: "calendar",
permissions: [],
realtimeBaseUrl: "/api/v1/module-realtime/calendar",
@@ -438,7 +443,18 @@ describe("module UI host context", () => {
expect(none.has("core.authorization.grants.manage")).toBe(false);
});
it("exposes exactly the six contract members and the browser principal", () => {
it("exposes the host-owned display page at the API origin in split-origin deployments", () => {
const { implementation } = recordingFetch();
const context = createModuleUiContext({
config: { apiBaseUrl: "https://api.example.test", fetch: implementation },
descriptor: exampleDescriptor,
principal: { kind: "authenticated", userId: "user-1" },
});
expect(context.display?.url).toBe("https://api.example.test/display/example");
});
it("exposes exactly the seven contract members and the browser principal", () => {
const { implementation } = recordingFetch();
const context = contextFor(implementation);
@@ -446,6 +462,7 @@ describe("module UI host context", () => {
expect(Object.keys(context).sort()).toEqual([
"api",
"contributions",
"display",
"moduleId",
"permissions",
"principal",