keycloakify 10.0.0-rc.40 → 10.0.0-rc.41

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.
Files changed (219) hide show
  1. package/account/DefaultPage.d.ts +5 -0
  2. package/account/{Fallback.js → DefaultPage.js} +2 -2
  3. package/account/DefaultPage.js.map +1 -0
  4. package/account/Template.d.ts +2 -1
  5. package/account/Template.js +2 -3
  6. package/account/Template.js.map +1 -1
  7. package/account/TemplateProps.d.ts +3 -3
  8. package/account/i18n/i18n.d.ts +3 -1
  9. package/account/i18n/i18n.js +2 -2
  10. package/account/i18n/i18n.js.map +1 -1
  11. package/account/i18n/index.d.ts +4 -8
  12. package/account/i18n/index.js +1 -4
  13. package/account/i18n/index.js.map +1 -1
  14. package/account/pages/Account.d.ts +2 -1
  15. package/account/pages/Account.js +3 -4
  16. package/account/pages/Account.js.map +1 -1
  17. package/account/pages/Applications.d.ts +2 -1
  18. package/account/pages/Applications.js +3 -4
  19. package/account/pages/Applications.js.map +1 -1
  20. package/account/pages/FederatedIdentity.d.ts +2 -1
  21. package/account/pages/FederatedIdentity.js +3 -4
  22. package/account/pages/FederatedIdentity.js.map +1 -1
  23. package/account/pages/Log.d.ts +2 -1
  24. package/account/pages/Log.js +3 -4
  25. package/account/pages/Log.js.map +1 -1
  26. package/account/pages/PageProps.d.ts +4 -4
  27. package/account/pages/Password.d.ts +2 -1
  28. package/account/pages/Password.js +3 -3
  29. package/account/pages/Password.js.map +1 -1
  30. package/account/pages/Sessions.d.ts +2 -1
  31. package/account/pages/Sessions.js +3 -4
  32. package/account/pages/Sessions.js.map +1 -1
  33. package/account/pages/Totp.d.ts +2 -1
  34. package/account/pages/Totp.js +3 -4
  35. package/account/pages/Totp.js.map +1 -1
  36. package/bin/538.index.js +37 -2
  37. package/login/{Fallback.d.ts → DefaultPage.d.ts} +4 -3
  38. package/login/{Fallback.js → DefaultPage.js} +2 -2
  39. package/login/DefaultPage.js.map +1 -0
  40. package/login/Template.d.ts +2 -1
  41. package/login/Template.js +2 -3
  42. package/login/Template.js.map +1 -1
  43. package/login/TemplateProps.d.ts +3 -3
  44. package/login/UserProfileFormFields.d.ts +2 -1
  45. package/login/UserProfileFormFields.js +3 -4
  46. package/login/UserProfileFormFields.js.map +1 -1
  47. package/login/i18n/i18n.d.ts +3 -1
  48. package/login/i18n/i18n.js +1 -1
  49. package/login/i18n/i18n.js.map +1 -1
  50. package/login/i18n/index.d.ts +4 -8
  51. package/login/i18n/index.js +1 -4
  52. package/login/i18n/index.js.map +1 -1
  53. package/login/lib/useUserProfileForm.d.ts +2 -0
  54. package/login/lib/useUserProfileForm.js +5 -5
  55. package/login/lib/useUserProfileForm.js.map +1 -1
  56. package/login/pages/Code.d.ts +2 -1
  57. package/login/pages/Code.js +3 -4
  58. package/login/pages/Code.js.map +1 -1
  59. package/login/pages/DeleteAccountConfirm.d.ts +2 -1
  60. package/login/pages/DeleteAccountConfirm.js +3 -4
  61. package/login/pages/DeleteAccountConfirm.js.map +1 -1
  62. package/login/pages/DeleteCredential.d.ts +2 -1
  63. package/login/pages/DeleteCredential.js +3 -4
  64. package/login/pages/DeleteCredential.js.map +1 -1
  65. package/login/pages/Error.d.ts +2 -1
  66. package/login/pages/Error.js +3 -4
  67. package/login/pages/Error.js.map +1 -1
  68. package/login/pages/FrontchannelLogout.d.ts +2 -1
  69. package/login/pages/FrontchannelLogout.js +3 -4
  70. package/login/pages/FrontchannelLogout.js.map +1 -1
  71. package/login/pages/IdpReviewUserProfile.d.ts +2 -1
  72. package/login/pages/IdpReviewUserProfile.js +3 -4
  73. package/login/pages/IdpReviewUserProfile.js.map +1 -1
  74. package/login/pages/Info.d.ts +2 -1
  75. package/login/pages/Info.js +3 -4
  76. package/login/pages/Info.js.map +1 -1
  77. package/login/pages/Login.d.ts +2 -1
  78. package/login/pages/Login.js +2 -4
  79. package/login/pages/Login.js.map +1 -1
  80. package/login/pages/LoginConfigTotp.d.ts +2 -1
  81. package/login/pages/LoginConfigTotp.js +2 -4
  82. package/login/pages/LoginConfigTotp.js.map +1 -1
  83. package/login/pages/LoginIdpLinkConfirm.d.ts +2 -1
  84. package/login/pages/LoginIdpLinkConfirm.js +3 -4
  85. package/login/pages/LoginIdpLinkConfirm.js.map +1 -1
  86. package/login/pages/LoginIdpLinkEmail.d.ts +2 -1
  87. package/login/pages/LoginIdpLinkEmail.js +3 -4
  88. package/login/pages/LoginIdpLinkEmail.js.map +1 -1
  89. package/login/pages/LoginOauth2DeviceVerifyUserCode.d.ts +2 -1
  90. package/login/pages/LoginOauth2DeviceVerifyUserCode.js +3 -4
  91. package/login/pages/LoginOauth2DeviceVerifyUserCode.js.map +1 -1
  92. package/login/pages/LoginOauthGrant.d.ts +2 -1
  93. package/login/pages/LoginOauthGrant.js +3 -4
  94. package/login/pages/LoginOauthGrant.js.map +1 -1
  95. package/login/pages/LoginOtp.d.ts +2 -1
  96. package/login/pages/LoginOtp.js +3 -4
  97. package/login/pages/LoginOtp.js.map +1 -1
  98. package/login/pages/LoginPageExpired.d.ts +2 -1
  99. package/login/pages/LoginPageExpired.js +3 -4
  100. package/login/pages/LoginPageExpired.js.map +1 -1
  101. package/login/pages/LoginPassword.d.ts +2 -1
  102. package/login/pages/LoginPassword.js +2 -4
  103. package/login/pages/LoginPassword.js.map +1 -1
  104. package/login/pages/LoginRecoveryAuthnCodeConfig.d.ts +2 -1
  105. package/login/pages/LoginRecoveryAuthnCodeConfig.js +2 -4
  106. package/login/pages/LoginRecoveryAuthnCodeConfig.js.map +1 -1
  107. package/login/pages/LoginRecoveryAuthnCodeInput.d.ts +2 -1
  108. package/login/pages/LoginRecoveryAuthnCodeInput.js +3 -4
  109. package/login/pages/LoginRecoveryAuthnCodeInput.js.map +1 -1
  110. package/login/pages/LoginResetOtp.d.ts +2 -1
  111. package/login/pages/LoginResetOtp.js +3 -4
  112. package/login/pages/LoginResetOtp.js.map +1 -1
  113. package/login/pages/LoginResetPassword.d.ts +2 -1
  114. package/login/pages/LoginResetPassword.js +3 -4
  115. package/login/pages/LoginResetPassword.js.map +1 -1
  116. package/login/pages/LoginUpdatePassword.d.ts +2 -1
  117. package/login/pages/LoginUpdatePassword.js +2 -4
  118. package/login/pages/LoginUpdatePassword.js.map +1 -1
  119. package/login/pages/LoginUpdateProfile.d.ts +2 -1
  120. package/login/pages/LoginUpdateProfile.js +3 -4
  121. package/login/pages/LoginUpdateProfile.js.map +1 -1
  122. package/login/pages/LoginUsername.d.ts +2 -1
  123. package/login/pages/LoginUsername.js +3 -4
  124. package/login/pages/LoginUsername.js.map +1 -1
  125. package/login/pages/LoginVerifyEmail.d.ts +2 -1
  126. package/login/pages/LoginVerifyEmail.js +3 -4
  127. package/login/pages/LoginVerifyEmail.js.map +1 -1
  128. package/login/pages/LoginX509Info.d.ts +2 -1
  129. package/login/pages/LoginX509Info.js +3 -4
  130. package/login/pages/LoginX509Info.js.map +1 -1
  131. package/login/pages/LogoutConfirm.d.ts +2 -1
  132. package/login/pages/LogoutConfirm.js +3 -4
  133. package/login/pages/LogoutConfirm.js.map +1 -1
  134. package/login/pages/PageProps.d.ts +4 -4
  135. package/login/pages/Register.d.ts +2 -1
  136. package/login/pages/Register.js +2 -4
  137. package/login/pages/Register.js.map +1 -1
  138. package/login/pages/SamlPostForm.d.ts +2 -1
  139. package/login/pages/SamlPostForm.js +3 -4
  140. package/login/pages/SamlPostForm.js.map +1 -1
  141. package/login/pages/SelectAuthenticator.d.ts +2 -1
  142. package/login/pages/SelectAuthenticator.js +3 -4
  143. package/login/pages/SelectAuthenticator.js.map +1 -1
  144. package/login/pages/Terms.d.ts +2 -1
  145. package/login/pages/Terms.js +3 -4
  146. package/login/pages/Terms.js.map +1 -1
  147. package/login/pages/UpdateEmail.d.ts +2 -1
  148. package/login/pages/UpdateEmail.js +2 -4
  149. package/login/pages/UpdateEmail.js.map +1 -1
  150. package/login/pages/WebauthnAuthenticate.d.ts +2 -1
  151. package/login/pages/WebauthnAuthenticate.js +3 -4
  152. package/login/pages/WebauthnAuthenticate.js.map +1 -1
  153. package/login/pages/WebauthnError.d.ts +2 -1
  154. package/login/pages/WebauthnError.js +3 -4
  155. package/login/pages/WebauthnError.js.map +1 -1
  156. package/login/pages/WebauthnRegister.d.ts +2 -1
  157. package/login/pages/WebauthnRegister.js +2 -4
  158. package/login/pages/WebauthnRegister.js.map +1 -1
  159. package/package.json +9 -9
  160. package/src/account/{Fallback.tsx → DefaultPage.tsx} +3 -2
  161. package/src/account/Template.tsx +4 -4
  162. package/src/account/TemplateProps.ts +4 -3
  163. package/src/account/i18n/i18n.tsx +3 -3
  164. package/src/account/i18n/index.ts +4 -9
  165. package/src/account/pages/Account.tsx +5 -5
  166. package/src/account/pages/Applications.tsx +5 -5
  167. package/src/account/pages/FederatedIdentity.tsx +5 -5
  168. package/src/account/pages/Log.tsx +5 -5
  169. package/src/account/pages/PageProps.ts +4 -4
  170. package/src/account/pages/Password.tsx +5 -4
  171. package/src/account/pages/Sessions.tsx +5 -5
  172. package/src/account/pages/Totp.tsx +5 -5
  173. package/src/bin/shared/generateKcGenTs.ts +46 -36
  174. package/src/login/{Fallback.tsx → DefaultPage.tsx} +4 -3
  175. package/src/login/Template.tsx +4 -3
  176. package/src/login/TemplateProps.ts +3 -4
  177. package/src/login/UserProfileFormFields.tsx +5 -5
  178. package/src/login/i18n/i18n.tsx +2 -2
  179. package/src/login/i18n/index.ts +4 -9
  180. package/src/login/lib/useUserProfileForm.tsx +8 -6
  181. package/src/login/pages/Code.tsx +5 -4
  182. package/src/login/pages/DeleteAccountConfirm.tsx +5 -5
  183. package/src/login/pages/DeleteCredential.tsx +5 -4
  184. package/src/login/pages/Error.tsx +12 -5
  185. package/src/login/pages/FrontchannelLogout.tsx +5 -4
  186. package/src/login/pages/IdpReviewUserProfile.tsx +6 -4
  187. package/src/login/pages/Info.tsx +5 -4
  188. package/src/login/pages/Login.tsx +4 -4
  189. package/src/login/pages/LoginConfigTotp.tsx +4 -6
  190. package/src/login/pages/LoginIdpLinkConfirm.tsx +5 -5
  191. package/src/login/pages/LoginIdpLinkEmail.tsx +11 -5
  192. package/src/login/pages/LoginOauth2DeviceVerifyUserCode.tsx +11 -5
  193. package/src/login/pages/LoginOauthGrant.tsx +5 -4
  194. package/src/login/pages/LoginOtp.tsx +5 -4
  195. package/src/login/pages/LoginPageExpired.tsx +5 -5
  196. package/src/login/pages/LoginPassword.tsx +4 -4
  197. package/src/login/pages/LoginRecoveryAuthnCodeConfig.tsx +10 -5
  198. package/src/login/pages/LoginRecoveryAuthnCodeInput.tsx +5 -4
  199. package/src/login/pages/LoginResetOtp.tsx +5 -4
  200. package/src/login/pages/LoginResetPassword.tsx +5 -4
  201. package/src/login/pages/LoginUpdatePassword.tsx +4 -4
  202. package/src/login/pages/LoginUpdateProfile.tsx +6 -4
  203. package/src/login/pages/LoginUsername.tsx +5 -4
  204. package/src/login/pages/LoginVerifyEmail.tsx +5 -4
  205. package/src/login/pages/LoginX509Info.tsx +5 -5
  206. package/src/login/pages/LogoutConfirm.tsx +5 -5
  207. package/src/login/pages/PageProps.ts +4 -4
  208. package/src/login/pages/Register.tsx +12 -5
  209. package/src/login/pages/SamlPostForm.tsx +5 -5
  210. package/src/login/pages/SelectAuthenticator.tsx +5 -4
  211. package/src/login/pages/Terms.tsx +12 -5
  212. package/src/login/pages/UpdateEmail.tsx +5 -4
  213. package/src/login/pages/WebauthnAuthenticate.tsx +5 -4
  214. package/src/login/pages/WebauthnError.tsx +12 -5
  215. package/src/login/pages/WebauthnRegister.tsx +4 -4
  216. package/vite-plugin/index.js +48 -24
  217. package/account/Fallback.d.ts +0 -4
  218. package/account/Fallback.js.map +0 -1
  219. package/login/Fallback.js.map +0 -1
@@ -5,15 +5,15 @@ import { getKcClsx } from "keycloakify/account/lib/kcClsx";
5
5
  import { useInsertLinkTags } from "keycloakify/tools/useInsertLinkTags";
6
6
  import { useSetClassName } from "keycloakify/tools/useSetClassName";
7
7
  import type { TemplateProps } from "keycloakify/account/TemplateProps";
8
+ import type { I18n } from "./i18n";
8
9
  import type { KcContext } from "./KcContext";
9
- import { useI18n } from "./i18n";
10
10
 
11
- export default function Template(props: TemplateProps<KcContext>) {
12
- const { kcContext, doUseDefaultCss, active, classes, children } = props;
11
+ export default function Template(props: TemplateProps<KcContext, I18n>) {
12
+ const { kcContext, i18n, doUseDefaultCss, active, classes, children } = props;
13
13
 
14
14
  const { kcClsx } = getKcClsx({ doUseDefaultCss, classes });
15
15
 
16
- const { msg, msgStr, getChangeLocalUrl, labelBySupportedLanguageTag, currentLanguageTag } = useI18n({ kcContext });
16
+ const { msg, msgStr, getChangeLocalUrl, labelBySupportedLanguageTag, currentLanguageTag } = i18n;
17
17
 
18
18
  const { locale, url, features, realm, message, referrer } = kcContext;
19
19
 
@@ -1,12 +1,13 @@
1
1
  import type { ReactNode } from "react";
2
- import type { KcContext } from "./KcContext";
3
2
 
4
- export type TemplateProps<KcContext extends KcContext.Common> = {
3
+ export type TemplateProps<KcContext, I18n> = {
5
4
  kcContext: KcContext;
5
+ i18n: I18n;
6
6
  doUseDefaultCss: boolean;
7
- active: string;
8
7
  classes?: Partial<Record<ClassKey, string>>;
9
8
  children: ReactNode;
9
+
10
+ active: string;
10
11
  };
11
12
 
12
13
  export type ClassKey =
@@ -130,7 +130,7 @@ function createGetI18n<ExtraMessageKey extends string = never>(extraMessages: {
130
130
  extraMessages: extraMessages[partialI18n.currentLanguageTag]
131
131
  });
132
132
 
133
- const isCurrentLanguageFallbackLanguage = partialI18n.currentLanguageTag !== fallbackLanguageTag;
133
+ const isCurrentLanguageFallbackLanguage = partialI18n.currentLanguageTag === fallbackLanguageTag;
134
134
 
135
135
  const result: Result = {
136
136
  i18n: {
@@ -175,7 +175,7 @@ export function createUseI18n<ExtraMessageKey extends string = never>(extraMessa
175
175
 
176
176
  const { getI18n } = createGetI18n(extraMessages);
177
177
 
178
- function useI18n(params: { kcContext: KcContextLike }): I18n {
178
+ function useI18n(params: { kcContext: KcContextLike }): { i18n: I18n } {
179
179
  const { kcContext } = params;
180
180
 
181
181
  const { i18n, prI18n_currentLanguage } = getI18n({ kcContext });
@@ -198,7 +198,7 @@ export function createUseI18n<ExtraMessageKey extends string = never>(extraMessa
198
198
  };
199
199
  }, []);
200
200
 
201
- return i18n_toReturn;
201
+ return { i18n: i18n_toReturn };
202
202
  }
203
203
 
204
204
  return { useI18n, ofTypeI18n: Reflect<I18n>() };
@@ -1,10 +1,5 @@
1
- export type { MessageKey } from "./i18n";
2
- import { createUseI18n } from "./i18n";
3
- export { createUseI18n };
1
+ import type { GenericI18n, MessageKey, KcContextLike } from "./i18n";
2
+ export type { MessageKey, KcContextLike };
3
+ export type I18n = GenericI18n<MessageKey>;
4
+ export { createUseI18n } from "./i18n";
4
5
  export { fallbackLanguageTag } from "./i18n";
5
-
6
- const { useI18n, ofTypeI18n } = createUseI18n({});
7
-
8
- export type I18n = typeof ofTypeI18n;
9
-
10
- export { useI18n };
@@ -2,10 +2,10 @@ import { clsx } from "keycloakify/tools/clsx";
2
2
  import type { PageProps } from "keycloakify/account/pages/PageProps";
3
3
  import { getKcClsx } from "keycloakify/account/lib/kcClsx";
4
4
  import type { KcContext } from "../KcContext";
5
- import { useI18n } from "../i18n";
5
+ import type { I18n } from "../i18n";
6
6
 
7
- export default function Account(props: PageProps<Extract<KcContext, { pageId: "account.ftl" }>>) {
8
- const { kcContext, doUseDefaultCss, Template } = props;
7
+ export default function Account(props: PageProps<Extract<KcContext, { pageId: "account.ftl" }>, I18n>) {
8
+ const { kcContext, i18n, doUseDefaultCss, Template } = props;
9
9
 
10
10
  const classes = {
11
11
  ...props.classes,
@@ -19,10 +19,10 @@ export default function Account(props: PageProps<Extract<KcContext, { pageId: "a
19
19
 
20
20
  const { url, realm, messagesPerField, stateChecker, account, referrer } = kcContext;
21
21
 
22
- const { msg } = useI18n({ kcContext });
22
+ const { msg } = i18n;
23
23
 
24
24
  return (
25
- <Template {...{ kcContext, doUseDefaultCss, classes }} active="account">
25
+ <Template {...{ kcContext, i18n, doUseDefaultCss, classes }} active="account">
26
26
  <div className="row">
27
27
  <div className="col-md-10">
28
28
  <h2>{msg("editAccountHtmlTitle")}</h2>
@@ -1,10 +1,10 @@
1
1
  import { getKcClsx } from "keycloakify/account/lib/kcClsx";
2
2
  import type { PageProps } from "keycloakify/account/pages/PageProps";
3
3
  import type { KcContext } from "../KcContext";
4
- import { useI18n } from "../i18n";
4
+ import type { I18n } from "../i18n";
5
5
 
6
- export default function Applications(props: PageProps<Extract<KcContext, { pageId: "applications.ftl" }>>) {
7
- const { kcContext, doUseDefaultCss, classes, Template } = props;
6
+ export default function Applications(props: PageProps<Extract<KcContext, { pageId: "applications.ftl" }>, I18n>) {
7
+ const { kcContext, i18n, doUseDefaultCss, classes, Template } = props;
8
8
 
9
9
  const { kcClsx } = getKcClsx({
10
10
  doUseDefaultCss,
@@ -17,10 +17,10 @@ export default function Applications(props: PageProps<Extract<KcContext, { pageI
17
17
  stateChecker
18
18
  } = kcContext;
19
19
 
20
- const { msg, advancedMsg } = useI18n({ kcContext });
20
+ const { msg, advancedMsg } = i18n;
21
21
 
22
22
  return (
23
- <Template {...{ kcContext, doUseDefaultCss, classes }} active="applications">
23
+ <Template {...{ kcContext, i18n, doUseDefaultCss, classes }} active="applications">
24
24
  <div className="row">
25
25
  <div className="col-md-10">
26
26
  <h2>{msg("applicationsHtmlTitle")}</h2>
@@ -1,14 +1,14 @@
1
1
  import type { PageProps } from "keycloakify/account/pages/PageProps";
2
2
  import type { KcContext } from "../KcContext";
3
- import { useI18n } from "../i18n";
3
+ import type { I18n } from "../i18n";
4
4
 
5
- export default function FederatedIdentity(props: PageProps<Extract<KcContext, { pageId: "federatedIdentity.ftl" }>>) {
6
- const { kcContext, doUseDefaultCss, classes, Template } = props;
5
+ export default function FederatedIdentity(props: PageProps<Extract<KcContext, { pageId: "federatedIdentity.ftl" }>, I18n>) {
6
+ const { kcContext, i18n, doUseDefaultCss, classes, Template } = props;
7
7
 
8
8
  const { url, federatedIdentity, stateChecker } = kcContext;
9
- const { msg } = useI18n({ kcContext });
9
+ const { msg } = i18n;
10
10
  return (
11
- <Template {...{ kcContext, doUseDefaultCss, classes }} active="federatedIdentity">
11
+ <Template {...{ kcContext, i18n, doUseDefaultCss, classes }} active="federatedIdentity">
12
12
  <div className="main-layout social">
13
13
  <div className="row">
14
14
  <div className="col-md-10">
@@ -2,10 +2,10 @@ import type { Key } from "react";
2
2
  import { getKcClsx } from "keycloakify/account/lib/kcClsx";
3
3
  import type { PageProps } from "keycloakify/account/pages/PageProps";
4
4
  import type { KcContext } from "../KcContext";
5
- import { useI18n } from "../i18n";
5
+ import type { I18n } from "../i18n";
6
6
 
7
- export default function Log(props: PageProps<Extract<KcContext, { pageId: "log.ftl" }>>) {
8
- const { kcContext, doUseDefaultCss, classes, Template } = props;
7
+ export default function Log(props: PageProps<Extract<KcContext, { pageId: "log.ftl" }>, I18n>) {
8
+ const { kcContext, i18n, doUseDefaultCss, classes, Template } = props;
9
9
 
10
10
  const { kcClsx } = getKcClsx({
11
11
  doUseDefaultCss,
@@ -14,10 +14,10 @@ export default function Log(props: PageProps<Extract<KcContext, { pageId: "log.f
14
14
 
15
15
  const { log } = kcContext;
16
16
 
17
- const { msg } = useI18n({ kcContext });
17
+ const { msg } = i18n;
18
18
 
19
19
  return (
20
- <Template {...{ kcContext, doUseDefaultCss, classes }} active="log">
20
+ <Template {...{ kcContext, i18n, doUseDefaultCss, classes }} active="log">
21
21
  <div className={kcClsx("kcContentWrapperClass")}>
22
22
  <div className="col-md-10">
23
23
  <h2>{msg("accountLogHtmlTitle")}</h2>
@@ -1,10 +1,10 @@
1
- import type { TemplateProps, ClassKey } from "keycloakify/account/TemplateProps";
1
+ import { type TemplateProps, type ClassKey } from "keycloakify/account/TemplateProps";
2
2
  import type { LazyOrNot } from "keycloakify/tools/LazyOrNot";
3
- import type { KcContext } from "../KcContext";
4
3
 
5
- export type PageProps<NarrowedKcContext = KcContext> = {
6
- Template: LazyOrNot<(props: TemplateProps<any>) => JSX.Element | null>;
4
+ export type PageProps<NarrowedKcContext, I18n> = {
5
+ Template: LazyOrNot<(props: TemplateProps<any, any>) => JSX.Element | null>;
7
6
  kcContext: NarrowedKcContext;
7
+ i18n: I18n;
8
8
  doUseDefaultCss: boolean;
9
9
  classes?: Partial<Record<ClassKey, string>>;
10
10
  };
@@ -3,10 +3,10 @@ import { clsx } from "keycloakify/tools/clsx";
3
3
  import { getKcClsx } from "keycloakify/account/lib/kcClsx";
4
4
  import type { PageProps } from "keycloakify/account/pages/PageProps";
5
5
  import type { KcContext } from "../KcContext";
6
- import { useI18n } from "../i18n";
6
+ import type { I18n } from "../i18n";
7
7
 
8
- export default function Password(props: PageProps<Extract<KcContext, { pageId: "password.ftl" }>>) {
9
- const { kcContext, doUseDefaultCss, Template } = props;
8
+ export default function Password(props: PageProps<Extract<KcContext, { pageId: "password.ftl" }>, I18n>) {
9
+ const { kcContext, i18n, doUseDefaultCss, Template } = props;
10
10
 
11
11
  const classes = {
12
12
  ...props.classes,
@@ -20,7 +20,7 @@ export default function Password(props: PageProps<Extract<KcContext, { pageId: "
20
20
 
21
21
  const { url, password, account, stateChecker } = kcContext;
22
22
 
23
- const { msgStr, msg } = useI18n({ kcContext });
23
+ const { msgStr, msg } = i18n;
24
24
 
25
25
  const [currentPassword, setCurrentPassword] = useState("");
26
26
  const [newPassword, setNewPassword] = useState("");
@@ -77,6 +77,7 @@ export default function Password(props: PageProps<Extract<KcContext, { pageId: "
77
77
  return kcContext.message;
78
78
  })()
79
79
  },
80
+ i18n,
80
81
  doUseDefaultCss,
81
82
  classes
82
83
  }}
@@ -1,10 +1,10 @@
1
1
  import { getKcClsx } from "keycloakify/account/lib/kcClsx";
2
2
  import type { PageProps } from "keycloakify/account/pages/PageProps";
3
3
  import type { KcContext } from "../KcContext";
4
- import { useI18n } from "../i18n";
4
+ import type { I18n } from "../i18n";
5
5
 
6
- export default function Sessions(props: PageProps<Extract<KcContext, { pageId: "sessions.ftl" }>>) {
7
- const { kcContext, doUseDefaultCss, Template, classes } = props;
6
+ export default function Sessions(props: PageProps<Extract<KcContext, { pageId: "sessions.ftl" }>, I18n>) {
7
+ const { kcContext, i18n, doUseDefaultCss, Template, classes } = props;
8
8
 
9
9
  const { kcClsx } = getKcClsx({
10
10
  doUseDefaultCss,
@@ -13,9 +13,9 @@ export default function Sessions(props: PageProps<Extract<KcContext, { pageId: "
13
13
 
14
14
  const { url, stateChecker, sessions } = kcContext;
15
15
 
16
- const { msg } = useI18n({ kcContext });
16
+ const { msg } = i18n;
17
17
  return (
18
- <Template {...{ kcContext, doUseDefaultCss, classes }} active="sessions">
18
+ <Template {...{ kcContext, i18n, doUseDefaultCss, classes }} active="sessions">
19
19
  <div className={kcClsx("kcContentWrapperClass")}>
20
20
  <div className="col-md-10">
21
21
  <h2>{msg("sessionsHtmlTitle")}</h2>
@@ -2,10 +2,10 @@ import { clsx } from "keycloakify/tools/clsx";
2
2
  import { getKcClsx } from "keycloakify/account/lib/kcClsx";
3
3
  import type { PageProps } from "keycloakify/account/pages/PageProps";
4
4
  import type { KcContext } from "../KcContext";
5
- import { useI18n } from "../i18n";
5
+ import type { I18n } from "../i18n";
6
6
 
7
- export default function Totp(props: PageProps<Extract<KcContext, { pageId: "totp.ftl" }>>) {
8
- const { kcContext, doUseDefaultCss, Template, classes } = props;
7
+ export default function Totp(props: PageProps<Extract<KcContext, { pageId: "totp.ftl" }>, I18n>) {
8
+ const { kcContext, i18n, doUseDefaultCss, Template, classes } = props;
9
9
 
10
10
  const { kcClsx } = getKcClsx({
11
11
  doUseDefaultCss,
@@ -14,7 +14,7 @@ export default function Totp(props: PageProps<Extract<KcContext, { pageId: "totp
14
14
 
15
15
  const { totp, mode, url, messagesPerField, stateChecker } = kcContext;
16
16
 
17
- const { msg, msgStr, advancedMsg } = useI18n({ kcContext });
17
+ const { msg, msgStr, advancedMsg } = i18n;
18
18
 
19
19
  const algToKeyUriAlg: Record<(typeof kcContext)["totp"]["policy"]["algorithm"], string> = {
20
20
  HmacSHA1: "SHA1",
@@ -23,7 +23,7 @@ export default function Totp(props: PageProps<Extract<KcContext, { pageId: "totp
23
23
  };
24
24
 
25
25
  return (
26
- <Template {...{ kcContext, doUseDefaultCss, classes }} active="totp">
26
+ <Template {...{ kcContext, i18n, doUseDefaultCss, classes }} active="totp">
27
27
  <>
28
28
  <div className="row">
29
29
  <div className="col-md-10">
@@ -3,6 +3,7 @@ import type { BuildContext } from "./buildContext";
3
3
  import { getThemeSrcDirPath } from "./getThemeSrcDirPath";
4
4
  import * as fs from "fs/promises";
5
5
  import { join as pathJoin } from "path";
6
+ import { existsAsync } from "../tools/fs.existsAsync";
6
7
 
7
8
  export type BuildContextLike = {
8
9
  projectDirPath: string;
@@ -21,41 +22,50 @@ export async function generateKcGenTs(params: {
21
22
  projectDirPath: buildContext.projectDirPath
22
23
  });
23
24
 
24
- await fs.writeFile(
25
- pathJoin(themeSrcDirPath, "kc.gen.ts"),
26
- Buffer.from(
27
- [
28
- `/* prettier-ignore-start */`,
29
- ``,
30
- `/* eslint-disable */`,
31
- ``,
32
- `// @ts-nocheck`,
33
- ``,
34
- `// noinspection JSUnusedGlobalSymbols`,
35
- ``,
36
- `// This file is auto-generated by Keycloakify`,
37
- ``,
38
- `export type ThemeName = ${buildContext.themeNames.map(themeName => `"${themeName}"`).join(" | ")};`,
39
- ``,
40
- `export const themeNames: ThemeName[] = [${buildContext.themeNames.map(themeName => `"${themeName}"`).join(", ")}];`,
41
- ``,
42
- `export type KcEnvName = ${buildContext.environmentVariables.length === 0 ? "never" : buildContext.environmentVariables.map(({ name }) => `"${name}"`).join(" | ")};`,
43
- ``,
44
- `export const KcEnvNames: KcEnvName[] = [${buildContext.environmentVariables.map(({ name }) => `"${name}"`).join(", ")}];`,
45
- ``,
46
- `export const kcEnvDefaults: Record<KcEnvName, string> = ${JSON.stringify(
47
- Object.fromEntries(
48
- buildContext.environmentVariables.map(
49
- ({ name, default: defaultValue }) => [name, defaultValue]
50
- )
51
- ),
52
- null,
53
- 2
54
- )};`,
55
- ``,
56
- `/* prettier-ignore-end */`
57
- ].join("\n"),
58
- "utf8"
59
- )
25
+ const filePath = pathJoin(themeSrcDirPath, "kc.gen.ts");
26
+
27
+ const currentContent = (await existsAsync(filePath))
28
+ ? await fs.readFile(filePath)
29
+ : undefined;
30
+
31
+ const newContent = Buffer.from(
32
+ [
33
+ `/* prettier-ignore-start */`,
34
+ ``,
35
+ `/* eslint-disable */`,
36
+ ``,
37
+ `// @ts-nocheck`,
38
+ ``,
39
+ `// noinspection JSUnusedGlobalSymbols`,
40
+ ``,
41
+ `// This file is auto-generated by Keycloakify`,
42
+ ``,
43
+ `export type ThemeName = ${buildContext.themeNames.map(themeName => `"${themeName}"`).join(" | ")};`,
44
+ ``,
45
+ `export const themeNames: ThemeName[] = [${buildContext.themeNames.map(themeName => `"${themeName}"`).join(", ")}];`,
46
+ ``,
47
+ `export type KcEnvName = ${buildContext.environmentVariables.length === 0 ? "never" : buildContext.environmentVariables.map(({ name }) => `"${name}"`).join(" | ")};`,
48
+ ``,
49
+ `export const KcEnvNames: KcEnvName[] = [${buildContext.environmentVariables.map(({ name }) => `"${name}"`).join(", ")}];`,
50
+ ``,
51
+ `export const kcEnvDefaults: Record<KcEnvName, string> = ${JSON.stringify(
52
+ Object.fromEntries(
53
+ buildContext.environmentVariables.map(
54
+ ({ name, default: defaultValue }) => [name, defaultValue]
55
+ )
56
+ ),
57
+ null,
58
+ 2
59
+ )};`,
60
+ ``,
61
+ `/* prettier-ignore-end */`
62
+ ].join("\n"),
63
+ "utf8"
60
64
  );
65
+
66
+ if (currentContent !== undefined && currentContent.equals(newContent)) {
67
+ return;
68
+ }
69
+
70
+ await fs.writeFile(filePath, newContent);
61
71
  }
@@ -2,7 +2,8 @@ import { lazy, Suspense } from "react";
2
2
  import { assert, type Equals } from "tsafe/assert";
3
3
  import type { LazyOrNot } from "keycloakify/tools/LazyOrNot";
4
4
  import type { PageProps } from "keycloakify/login/pages/PageProps";
5
- import type { KcContext } from "./KcContext";
5
+ import type { I18n } from "keycloakify/login/i18n";
6
+ import type { KcContext } from "keycloakify/login/KcContext";
6
7
  import type { UserProfileFormFieldsProps } from "keycloakify/login/UserProfileFormFields";
7
8
 
8
9
  const Login = lazy(() => import("keycloakify/login/pages/Login"));
@@ -40,12 +41,12 @@ const LoginResetOtp = lazy(() => import("keycloakify/login/pages/LoginResetOtp")
40
41
  const LoginX509Info = lazy(() => import("keycloakify/login/pages/LoginX509Info"));
41
42
  const WebauthnError = lazy(() => import("keycloakify/login/pages/WebauthnError"));
42
43
 
43
- type FallbackProps = PageProps<KcContext> & {
44
+ type DefaultPageProps = PageProps<KcContext, I18n> & {
44
45
  UserProfileFormFields: LazyOrNot<(props: UserProfileFormFieldsProps) => JSX.Element>;
45
46
  doMakeUserConfirmPassword: boolean;
46
47
  };
47
48
 
48
- export default function Fallback(props: FallbackProps) {
49
+ export default function DefaultPage(props: DefaultPageProps) {
49
50
  const { kcContext, ...rest } = props;
50
51
 
51
52
  return (
@@ -6,10 +6,10 @@ import { getKcClsx } from "keycloakify/login/lib/kcClsx";
6
6
  import { useInsertScriptTags } from "keycloakify/tools/useInsertScriptTags";
7
7
  import { useInsertLinkTags } from "keycloakify/tools/useInsertLinkTags";
8
8
  import { useSetClassName } from "keycloakify/tools/useSetClassName";
9
+ import type { I18n } from "./i18n";
9
10
  import type { KcContext } from "./KcContext";
10
- import { useI18n } from "./i18n";
11
11
 
12
- export default function Template(props: TemplateProps<KcContext>) {
12
+ export default function Template(props: TemplateProps<KcContext, I18n>) {
13
13
  const {
14
14
  displayInfo = false,
15
15
  displayMessage = true,
@@ -21,6 +21,7 @@ export default function Template(props: TemplateProps<KcContext>) {
21
21
  documentTitle,
22
22
  bodyClassName,
23
23
  kcContext,
24
+ i18n,
24
25
  doUseDefaultCss,
25
26
  classes,
26
27
  children
@@ -28,7 +29,7 @@ export default function Template(props: TemplateProps<KcContext>) {
28
29
 
29
30
  const { kcClsx } = getKcClsx({ doUseDefaultCss, classes });
30
31
 
31
- const { msg, msgStr, getChangeLocalUrl, labelBySupportedLanguageTag, currentLanguageTag } = useI18n({ kcContext });
32
+ const { msg, msgStr, getChangeLocalUrl, labelBySupportedLanguageTag, currentLanguageTag } = i18n;
32
33
 
33
34
  const { realm, locale, auth, url, message, isAppInitiatedAction, authenticationSession, scripts } = kcContext;
34
35
 
@@ -1,10 +1,11 @@
1
1
  import type { ReactNode } from "react";
2
- import type { KcContext } from "./KcContext";
3
2
 
4
- export type TemplateProps<KcContext extends KcContext.Common> = {
3
+ export type TemplateProps<KcContext, I18n> = {
5
4
  kcContext: KcContext;
5
+ i18n: I18n;
6
6
  doUseDefaultCss: boolean;
7
7
  classes?: Partial<Record<ClassKey, string>>;
8
+ children: ReactNode;
8
9
 
9
10
  displayInfo?: boolean;
10
11
  displayMessage?: boolean;
@@ -16,8 +17,6 @@ export type TemplateProps<KcContext extends KcContext.Common> = {
16
17
  infoNode?: ReactNode;
17
18
  documentTitle?: string;
18
19
  bodyClassName?: string;
19
-
20
- children: ReactNode;
21
20
  };
22
21
 
23
22
  export type ClassKey =
@@ -9,10 +9,11 @@ import {
9
9
  type FormFieldError
10
10
  } from "keycloakify/login/lib/useUserProfileForm";
11
11
  import type { Attribute } from "keycloakify/login/KcContext";
12
- import { useI18n, type I18n } from "./i18n";
12
+ import type { I18n } from "./i18n";
13
13
 
14
14
  export type UserProfileFormFieldsProps = {
15
15
  kcContext: KcContextLike;
16
+ i18n: I18n;
16
17
  kcClsx: KcClsx;
17
18
  onIsFormSubmittableValueChange: (isFormSubmittable: boolean) => void;
18
19
  doMakeUserConfirmPassword: boolean;
@@ -30,15 +31,16 @@ type BeforeAfterFieldProps = {
30
31
  };
31
32
 
32
33
  export default function UserProfileFormFields(props: UserProfileFormFieldsProps) {
33
- const { kcContext, kcClsx, onIsFormSubmittableValueChange, doMakeUserConfirmPassword, BeforeField, AfterField } = props;
34
+ const { kcContext, i18n, kcClsx, onIsFormSubmittableValueChange, doMakeUserConfirmPassword, BeforeField, AfterField } = props;
34
35
 
35
- const { advancedMsg } = useI18n({ kcContext });
36
+ const { advancedMsg } = i18n;
36
37
 
37
38
  const {
38
39
  formState: { formFieldStates, isFormSubmittable },
39
40
  dispatchFormAction
40
41
  } = useUserProfileForm({
41
42
  kcContext,
43
+ i18n,
42
44
  doMakeUserConfirmPassword
43
45
  });
44
46
 
@@ -46,8 +48,6 @@ export default function UserProfileFormFields(props: UserProfileFormFieldsProps)
46
48
  onIsFormSubmittableValueChange(isFormSubmittable);
47
49
  }, [isFormSubmittable]);
48
50
 
49
- const i18n = useI18n({ kcContext });
50
-
51
51
  const groupNameRef = { current: "" };
52
52
 
53
53
  return (
@@ -177,7 +177,7 @@ export function createUseI18n<ExtraMessageKey extends string = never>(extraMessa
177
177
 
178
178
  const { getI18n } = createGetI18n(extraMessages);
179
179
 
180
- function useI18n(params: { kcContext: KcContextLike }): I18n {
180
+ function useI18n(params: { kcContext: KcContextLike }): { i18n: I18n } {
181
181
  const { kcContext } = params;
182
182
 
183
183
  const { i18n, prI18n_currentLanguage } = getI18n({ kcContext });
@@ -200,7 +200,7 @@ export function createUseI18n<ExtraMessageKey extends string = never>(extraMessa
200
200
  };
201
201
  }, []);
202
202
 
203
- return i18n_toReturn;
203
+ return { i18n: i18n_toReturn };
204
204
  }
205
205
 
206
206
  return { useI18n, ofTypeI18n: Reflect<I18n>() };
@@ -1,10 +1,5 @@
1
- export type { MessageKey, KcContextLike } from "./i18n";
2
- import { createUseI18n } from "./i18n";
3
- export { createUseI18n };
1
+ import type { GenericI18n, MessageKey, KcContextLike } from "./i18n";
2
+ export type { MessageKey, KcContextLike };
3
+ export type I18n = GenericI18n<MessageKey>;
4
+ export { createUseI18n } from "./i18n";
4
5
  export { fallbackLanguageTag } from "./i18n";
5
-
6
- const { useI18n, ofTypeI18n } = createUseI18n({});
7
-
8
- export type I18n = typeof ofTypeI18n;
9
-
10
- export { useI18n };
@@ -11,7 +11,7 @@ import type { PasswordPolicies, Attribute, Validators } from "keycloakify/login/
11
11
  import type { KcContext } from "../KcContext";
12
12
  import type { MessageKey } from "keycloakify/login/i18n";
13
13
  import { KcContextLike as KcContextLike_i18n } from "keycloakify/login/i18n";
14
- import { useI18n } from "../i18n";
14
+ import type { I18n } from "../i18n";
15
15
 
16
16
  export type FormFieldError = {
17
17
  errorMessage: JSX.Element;
@@ -83,6 +83,7 @@ assert<Extract<KcContext.Register, { pageId: "register.ftl" }> extends KcContext
83
83
 
84
84
  export type ParamsOfUseUserProfileForm = {
85
85
  kcContext: KcContextLike;
86
+ i18n: I18n;
86
87
  doMakeUserConfirmPassword: boolean;
87
88
  };
88
89
 
@@ -105,7 +106,7 @@ namespace internal {
105
106
  }
106
107
 
107
108
  export function useUserProfileForm(params: ParamsOfUseUserProfileForm): ReturnTypeOfUseUserProfileForm {
108
- const { kcContext, doMakeUserConfirmPassword } = params;
109
+ const { kcContext, i18n, doMakeUserConfirmPassword } = params;
109
110
 
110
111
  const { insertScriptTags } = useInsertScriptTags({
111
112
  componentOrHookName: "useUserProfileForm",
@@ -122,7 +123,8 @@ export function useUserProfileForm(params: ParamsOfUseUserProfileForm): ReturnTy
122
123
  }, []);
123
124
 
124
125
  const { getErrors } = useGetErrors({
125
- kcContext
126
+ kcContext,
127
+ i18n
126
128
  });
127
129
 
128
130
  const initialState = useMemo((): internal.State => {
@@ -523,12 +525,12 @@ type KcContextLike_useGetErrors = KcContextLike_i18n & {
523
525
 
524
526
  assert<KcContextLike extends KcContextLike_useGetErrors ? true : false>();
525
527
 
526
- function useGetErrors(params: { kcContext: KcContextLike_useGetErrors }) {
527
- const { kcContext } = params;
528
+ function useGetErrors(params: { kcContext: KcContextLike_useGetErrors; i18n: I18n }) {
529
+ const { kcContext, i18n } = params;
528
530
 
529
531
  const { messagesPerField, passwordPolicies } = kcContext;
530
532
 
531
- const { msg, msgStr, advancedMsg, advancedMsgStr } = useI18n({ kcContext });
533
+ const { msg, msgStr, advancedMsg, advancedMsgStr } = i18n;
532
534
 
533
535
  const getErrors = useConstCallback(
534
536
  (params: {
@@ -1,10 +1,10 @@
1
1
  import { getKcClsx } from "keycloakify/login/lib/kcClsx";
2
2
  import type { PageProps } from "keycloakify/login/pages/PageProps";
3
3
  import type { KcContext } from "../KcContext";
4
- import { useI18n } from "../i18n";
4
+ import type { I18n } from "../i18n";
5
5
 
6
- export default function Code(props: PageProps<Extract<KcContext, { pageId: "code.ftl" }>>) {
7
- const { kcContext, doUseDefaultCss, Template, classes } = props;
6
+ export default function Code(props: PageProps<Extract<KcContext, { pageId: "code.ftl" }>, I18n>) {
7
+ const { kcContext, i18n, doUseDefaultCss, Template, classes } = props;
8
8
 
9
9
  const { kcClsx } = getKcClsx({
10
10
  doUseDefaultCss,
@@ -13,11 +13,12 @@ export default function Code(props: PageProps<Extract<KcContext, { pageId: "code
13
13
 
14
14
  const { code } = kcContext;
15
15
 
16
- const { msg } = useI18n({ kcContext });
16
+ const { msg } = i18n;
17
17
 
18
18
  return (
19
19
  <Template
20
20
  kcContext={kcContext}
21
+ i18n={i18n}
21
22
  doUseDefaultCss={doUseDefaultCss}
22
23
  classes={classes}
23
24
  headerNode={code.success ? msg("codeSuccessTitle") : msg("codeErrorTitle", code.error)}