import type { KcContextBase, Attribute } from "./KcContextBase"; import { kcContextMocks, kcContextCommonMock } from "./kcContextMocks"; import type { DeepPartial } from "../tools/DeepPartial"; import { deepAssign } from "../tools/deepAssign"; import { id } from "tsafe/id"; import { exclude } from "tsafe/exclude"; import { assert } from "tsafe/assert"; import type { ExtendsKcContextBase } from "./getKcContextFromWindow"; import { getKcContextFromWindow } from "./getKcContextFromWindow"; export function getKcContext(params?: { mockPageId?: ExtendsKcContextBase["pageId"]; mockData?: readonly DeepPartial>[]; }): { kcContext: ExtendsKcContextBase | undefined } { const { mockPageId, mockData } = params ?? {}; if (mockPageId !== undefined) { //TODO maybe trow if no mock fo custom page const kcContextDefaultMock = kcContextMocks.find(({ pageId }) => pageId === mockPageId); const partialKcContextCustomMock = mockData?.find(({ pageId }) => pageId === mockPageId); if (kcContextDefaultMock === undefined && partialKcContextCustomMock === undefined) { console.warn( [ `WARNING: You declared the non build in page ${mockPageId} but you didn't `, `provide mock data needed to debug the page outside of Keycloak as you are trying to do now.`, `Please check the documentation of the getKcContext function`, ].join("\n"), ); } const kcContext: any = {}; deepAssign({ "target": kcContext, "source": kcContextDefaultMock !== undefined ? kcContextDefaultMock : { "pageId": mockPageId, ...kcContextCommonMock }, }); if (partialKcContextCustomMock !== undefined) { deepAssign({ "target": kcContext, "source": partialKcContextCustomMock, }); if (partialKcContextCustomMock.pageId === "register-user-profile.ftl") { assert(kcContextDefaultMock?.pageId === "register-user-profile.ftl"); const { attributes } = kcContextDefaultMock.profile; id(kcContext).profile.attributes = []; id(kcContext).profile.attributesByName = {}; const partialAttributes = [ ...((partialKcContextCustomMock as DeepPartial).profile?.attributes ?? []), ].filter(exclude(undefined)); attributes.forEach(attribute => { const partialAttribute = partialAttributes.find(({ name }) => name === attribute.name); const augmentedAttribute: Attribute = {} as any; deepAssign({ "target": augmentedAttribute, "source": attribute, }); if (partialAttribute !== undefined) { partialAttributes.splice(partialAttributes.indexOf(partialAttribute), 1); deepAssign({ "target": augmentedAttribute, "source": partialAttribute, }); } id(kcContext).profile.attributes.push(augmentedAttribute); id(kcContext).profile.attributesByName[augmentedAttribute.name] = augmentedAttribute; }); partialAttributes.forEach(partialAttribute => { const { name } = partialAttribute; assert(name !== undefined, "If you define a mock attribute it must have at least a name"); id(kcContext).profile.attributes.push(partialAttribute as any); id(kcContext).profile.attributesByName[name] = partialAttribute as any; }); } } return { kcContext }; } return { "kcContext": getKcContextFromWindow() }; }