Implement a mechanism to overload kcContext
This commit is contained in:
@ -1,7 +1,7 @@
|
||||
|
||||
import type { PageId } from "../../bin/build-keycloak-theme/generateFtl";
|
||||
import type { KcLanguageTag } from "../i18n/KcLanguageTag";
|
||||
import { doExtends } from "evt/tools/typeSafety/doExtends";
|
||||
import { doExtends } from "tsafe/doExtends";
|
||||
import type { MessageKey } from "../i18n/useKcMessage";
|
||||
import type { LanguageLabel } from "../i18n/KcLanguageTag";
|
||||
|
||||
@ -150,7 +150,8 @@ export declare namespace KcContextBase {
|
||||
pageId: "error.ftl";
|
||||
client?: {
|
||||
baseUrl?: string;
|
||||
}
|
||||
},
|
||||
message: NonNullable<Common["message"]>;
|
||||
};
|
||||
|
||||
export type LoginResetPassword = Common & {
|
||||
|
@ -1,28 +1,93 @@
|
||||
|
||||
import type { KcContextBase } from "./KcContextBase";
|
||||
import type { KcContextBase } from "./KcContextBase";
|
||||
import { kcContextMocks, kcContextCommonMock } from "./kcContextMocks";
|
||||
import { ftlValuesGlobalName } from "../../bin/build-keycloak-theme/ftlValuesGlobalName";
|
||||
import type { AndByDiscriminatingKey } from "../tools/AndByDiscriminatingKey";
|
||||
import type { DeepPartial } from "../tools/DeepPartial";
|
||||
import { deepAssign } from "../tools/deepAssign";
|
||||
|
||||
export function getKcContext<KcContextExtended extends { pageId: string; } = never>(
|
||||
|
||||
export type ExtendsKcContextBase<
|
||||
KcContextExtended extends ({ pageId: string; } | undefined)
|
||||
> =
|
||||
KcContextExtended extends undefined ?
|
||||
KcContextBase :
|
||||
AndByDiscriminatingKey<
|
||||
"pageId",
|
||||
KcContextExtended & KcContextBase.Common,
|
||||
KcContextBase
|
||||
>;
|
||||
|
||||
export function getKcContext<KcContextExtended extends ({ pageId: string; } | undefined) = undefined>(
|
||||
params?: {
|
||||
mockPageId?: KcContextBase["pageId"] | KcContextExtended["pageId"];
|
||||
kcContextExtendedMock?: KcContextExtended[];
|
||||
mockPageId?: ExtendsKcContextBase<KcContextExtended>["pageId"];
|
||||
mockData?: readonly DeepPartial<ExtendsKcContextBase<KcContextExtended>>[];
|
||||
}
|
||||
): { kcContext: (KcContextBase | KcContextExtended & KcContextBase.Common) | undefined; } {
|
||||
): { kcContext: ExtendsKcContextBase<KcContextExtended> | undefined; } {
|
||||
|
||||
const { mockPageId, kcContextExtendedMock } = params ?? { "mockPageId": false };
|
||||
const {
|
||||
mockPageId,
|
||||
mockData
|
||||
} = params ?? {};
|
||||
|
||||
if (mockPageId !== undefined) {
|
||||
|
||||
return {
|
||||
"pageId": mockPageId,
|
||||
...(kcContextMocks.find(({ pageId }) => pageId === mockPageId) ?? kcContextCommonMock),
|
||||
...(kcContextExtendedMock?.find(({ pageId }) => pageId === mockPageId) ?? {})
|
||||
} as any;
|
||||
//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 = { "pageId": mockPageId };
|
||||
|
||||
deepAssign({
|
||||
"target": kcContext,
|
||||
"source": kcContextCommonMock
|
||||
});
|
||||
|
||||
if (kcContextDefaultMock !== undefined) {
|
||||
|
||||
deepAssign({
|
||||
"target": kcContext,
|
||||
"source": kcContextDefaultMock
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
if (partialKcContextCustomMock !== undefined) {
|
||||
|
||||
deepAssign({
|
||||
"target": kcContext,
|
||||
"source": partialKcContextCustomMock
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
return { kcContext };
|
||||
|
||||
}
|
||||
|
||||
return (window as any)[ftlValuesGlobalName];
|
||||
return {
|
||||
"kcContext":
|
||||
typeof window === "undefined" ?
|
||||
undefined :
|
||||
(window as any)[ftlValuesGlobalName]
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -5,12 +5,15 @@ import { getKcLanguageTagLabel } from "../../i18n/KcLanguageTag";
|
||||
//NOTE: Aside because we want to be able to import them from node
|
||||
import { resourcesCommonPath, resourcesPath } from "./urlResourcesPath";
|
||||
import { id } from "tsafe/id";
|
||||
import { join as pathJoin } from "path";
|
||||
|
||||
const PUBLIC_URL = process.env["PUBLIC_URL"] ?? "/";
|
||||
|
||||
export const kcContextCommonMock: KcContextBase.Common = {
|
||||
"url": {
|
||||
"loginAction": "#",
|
||||
"resourcesPath": `${process.env["PUBLIC_URL"]}/${resourcesPath}`,
|
||||
"resourcesCommonPath": `${process.env["PUBLIC_URL"]}/${resourcesCommonPath}`,
|
||||
"resourcesPath": pathJoin(PUBLIC_URL, resourcesPath),
|
||||
"resourcesCommonPath": pathJoin(PUBLIC_URL, resourcesCommonPath),
|
||||
"loginRestartFlowUrl": "/auth/realms/myrealm/login-actions/restart?client_id=account&tab_id=HoAx28ja4xg",
|
||||
"loginUrl": "/auth/realms/myrealm/login-actions/authenticate?client_id=account&tab_id=HoAx28ja4xg",
|
||||
},
|
||||
@ -95,7 +98,8 @@ export const kcContextCommonMock: KcContextBase.Common = {
|
||||
"languageTag": "tr"
|
||||
}
|
||||
],
|
||||
"current": null as any
|
||||
//"current": null as any
|
||||
"current": "English"
|
||||
},
|
||||
"auth": {
|
||||
"showUsername": false,
|
||||
@ -110,6 +114,7 @@ export const kcContextCommonMock: KcContextBase.Common = {
|
||||
"isAppInitiatedAction": false,
|
||||
};
|
||||
|
||||
|
||||
Object.defineProperty(
|
||||
kcContextCommonMock.locale!,
|
||||
"current",
|
||||
@ -188,6 +193,10 @@ export const kcContextMocks: KcContextBase[] = [
|
||||
"pageId": "error.ftl",
|
||||
"client": {
|
||||
"baseUrl": "#"
|
||||
},
|
||||
"message": {
|
||||
"type": "error",
|
||||
"summary": "This is the error message"
|
||||
}
|
||||
}),
|
||||
id<KcContextBase.LoginResetPassword>({
|
||||
|
43
src/lib/getKcContext/typeHelper.ts
Normal file
43
src/lib/getKcContext/typeHelper.ts
Normal file
@ -0,0 +1,43 @@
|
||||
|
||||
|
||||
|
||||
import { KcContextBase } from "./KcContextBase";
|
||||
import type { AndByDiscriminatingKey } from "../tools/AndByDiscriminatingKey";
|
||||
|
||||
|
||||
export type ExtendsKcContextBase<KcContextExtended extends { pageId: string; }>=
|
||||
AndByDiscriminatingKey<
|
||||
"pageId",
|
||||
KcContextExtended & KcContextBase.Common,
|
||||
KcContextBase
|
||||
>;
|
||||
|
||||
type KcContextExtended =
|
||||
{ pageId: "register.ftl"; authorizedMailDomains: string[]; } |
|
||||
{ pageId: "my-extra-page-1.ftl"; } |
|
||||
{ pageId: "my-extra-page-2.ftl"; someCustomValue: string; };
|
||||
|
||||
const y: ExtendsKcContextBase<KcContextExtended> = null as any;
|
||||
|
||||
|
||||
if (y.pageId === "register.ftl") {
|
||||
|
||||
y.authorizedMailDomains;
|
||||
|
||||
y.realm.displayName;
|
||||
|
||||
y.register
|
||||
|
||||
}
|
||||
|
||||
if (y.pageId === "my-extra-page-1.ftl") {
|
||||
y.realm.displayName;
|
||||
}
|
||||
|
||||
if (y.pageId === "my-extra-page-2.ftl") {
|
||||
|
||||
y.realm
|
||||
y.someCustomValue
|
||||
|
||||
}
|
||||
|
Reference in New Issue
Block a user