keycloakify 10.0.0-rc.77 → 10.0.0-rc.78

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 (62) hide show
  1. package/account/i18n/i18n.d.ts +4 -4
  2. package/account/i18n/i18n.js +12 -34
  3. package/account/i18n/i18n.js.map +1 -1
  4. package/account/i18n/index.d.ts +1 -1
  5. package/account/i18n/index.js +1 -1
  6. package/account/i18n/index.js.map +1 -1
  7. package/account/i18n/useI18n.d.ts +13 -0
  8. package/account/i18n/useI18n.js +26 -0
  9. package/account/i18n/useI18n.js.map +1 -0
  10. package/bin/440.index.js +15 -19
  11. package/bin/751.index.js +0 -2
  12. package/bin/shared/constants.d.ts +0 -1
  13. package/bin/shared/constants.js +0 -1
  14. package/bin/shared/constants.js.map +1 -1
  15. package/login/KcContext/KcContext.d.ts +5 -1
  16. package/login/KcContext/KcContext.js +0 -1
  17. package/login/KcContext/KcContext.js.map +1 -1
  18. package/login/KcContext/kcContextMocks.js +4 -1
  19. package/login/KcContext/kcContextMocks.js.map +1 -1
  20. package/login/i18n/i18n.d.ts +7 -4
  21. package/login/i18n/i18n.js +23 -38
  22. package/login/i18n/i18n.js.map +1 -1
  23. package/login/i18n/index.d.ts +1 -1
  24. package/login/i18n/index.js +1 -1
  25. package/login/i18n/index.js.map +1 -1
  26. package/login/i18n/useI18n.d.ts +13 -0
  27. package/login/i18n/useI18n.js +26 -0
  28. package/login/i18n/useI18n.js.map +1 -0
  29. package/login/lib/useDownloadTerms.d.ts +5 -4
  30. package/login/lib/useDownloadTerms.js +26 -5
  31. package/login/lib/useDownloadTerms.js.map +1 -1
  32. package/login/pages/Register.js +7 -6
  33. package/login/pages/Register.js.map +1 -1
  34. package/login/pages/Terms.d.ts +1 -1
  35. package/login/pages/Terms.js +6 -4
  36. package/login/pages/Terms.js.map +1 -1
  37. package/package.json +15 -7
  38. package/src/account/i18n/i18n.tsx +19 -53
  39. package/src/account/i18n/index.ts +1 -1
  40. package/src/account/i18n/useI18n.ts +44 -0
  41. package/src/bin/keycloakify/generateFtl/generateFtl.ts +1 -6
  42. package/src/bin/keycloakify/generateFtl/kcContextDeclarationTemplate.ftl +8 -1
  43. package/src/bin/keycloakify/generateResources/generateMessageProperties.ts +23 -17
  44. package/src/bin/shared/constants.ts +0 -2
  45. package/src/login/KcContext/KcContext.ts +6 -14
  46. package/src/login/KcContext/kcContextMocks.ts +4 -1
  47. package/src/login/i18n/i18n.tsx +37 -58
  48. package/src/login/i18n/index.ts +1 -1
  49. package/src/login/i18n/useI18n.ts +44 -0
  50. package/src/login/lib/useDownloadTerms.tsx +88 -0
  51. package/src/login/pages/Register.tsx +12 -12
  52. package/src/login/pages/Terms.tsx +12 -11
  53. package/src/tools/react-markdown.ts +3 -0
  54. package/tools/react-markdown.d.ts +3 -0
  55. package/tools/react-markdown.js +4 -0
  56. package/tools/react-markdown.js.map +1 -0
  57. package/vite-plugin/index.js +0 -2
  58. package/src/login/lib/useDownloadTerms.ts +0 -57
  59. package/src/tools/Markdown.ts +0 -3
  60. package/tools/Markdown.d.ts +0 -2
  61. package/tools/Markdown.js +0 -3
  62. package/tools/Markdown.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"Terms.js","sourceRoot":"","sources":["../../src/login/pages/Terms.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,4BAA4B,CAAC;AACtD,OAAO,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAC;AACzD,OAAO,EAAE,gBAAgB,EAAE,MAAM,wCAAwC,CAAC;AAK1E,MAAM,CAAC,OAAO,UAAU,KAAK,CAAC,KAAmE;IAC7F,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,eAAe,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,KAAK,CAAC;IAEtE,MAAM,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC;QACzB,eAAe;QACf,OAAO;KACV,CAAC,CAAC;IAEH,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;IAE7B,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,SAAS,CAAC;IAElC,MAAM,EAAE,kBAAkB,EAAE,aAAa,EAAE,gBAAgB,EAAE,GAAG,gBAAgB,EAAE,CAAC;IAEnF,IAAI,CAAC,kBAAkB,EAAE;QACrB,OAAO,IAAI,CAAC;KACf;IAED,OAAO,CACH,MAAC,QAAQ,kBACL,SAAS,EAAE,SAAS,EACpB,IAAI,EAAE,IAAI,EACV,eAAe,EAAE,eAAe,EAChC,OAAO,EAAE,OAAO,EAChB,cAAc,EAAE,KAAK,EACrB,UAAU,EAAE,GAAG,CAAC,YAAY,CAAC,iBAE7B,4BAAK,EAAE,EAAC,eAAe,EAAC,IAAI,EAAE,gBAAgB,MAAK,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,kBAAkB,CAAA,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,SAAS,gBACxG,KAAC,QAAQ,cAAE,aAAa,GAAY,IAClC,EACN,8BAAM,SAAS,EAAC,cAAc,EAAC,MAAM,EAAE,GAAG,CAAC,WAAW,EAAE,MAAM,EAAC,MAAM,iBACjE,gBACI,SAAS,EAAE,MAAM,CAAC,eAAe,EAAE,eAAe,EAAE,eAAe,EAAE,sBAAsB,EAAE,oBAAoB,CAAC,EAClH,IAAI,EAAC,QAAQ,EACb,EAAE,EAAC,WAAW,EACd,IAAI,EAAC,QAAQ,EACb,KAAK,EAAE,MAAM,CAAC,UAAU,CAAC,GAC3B,EACF,gBACI,SAAS,EAAE,MAAM,CAAC,eAAe,EAAE,sBAAsB,EAAE,oBAAoB,CAAC,EAChF,IAAI,EAAC,QAAQ,EACb,EAAE,EAAC,YAAY,EACf,IAAI,EAAC,QAAQ,EACb,KAAK,EAAE,MAAM,CAAC,WAAW,CAAC,GAC5B,KACC,EACP,cAAK,SAAS,EAAC,UAAU,GAAG,KACrB,CACd,CAAC;AACN,CAAC"}
1
+ {"version":3,"file":"Terms.js","sourceRoot":"","sources":["../../src/login/pages/Terms.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAC;AACzD,OAAO,EAAE,gBAAgB,EAAE,MAAM,wCAAwC,CAAC;AAK1E,MAAM,CAAC,OAAO,UAAU,KAAK,CAAC,KAAmE;IAC7F,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,eAAe,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,KAAK,CAAC;IAEtE,MAAM,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC;QACzB,eAAe;QACf,OAAO;KACV,CAAC,CAAC;IAEH,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;IAE7B,MAAM,EAAE,GAAG,EAAE,GAAG,SAAS,CAAC;IAE1B,OAAO,CACH,MAAC,QAAQ,kBACL,SAAS,EAAE,SAAS,EACpB,IAAI,EAAE,IAAI,EACV,eAAe,EAAE,eAAe,EAChC,OAAO,EAAE,OAAO,EAChB,cAAc,EAAE,KAAK,EACrB,UAAU,EAAE,GAAG,CAAC,YAAY,CAAC,iBAE7B,4BAAK,EAAE,EAAC,eAAe,gBAAE,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,KAAC,aAAa,KAAG,IAAO,EAC1F,8BAAM,SAAS,EAAC,cAAc,EAAC,MAAM,EAAE,GAAG,CAAC,WAAW,EAAE,MAAM,EAAC,MAAM,iBACjE,gBACI,SAAS,EAAE,MAAM,CAAC,eAAe,EAAE,eAAe,EAAE,eAAe,EAAE,sBAAsB,EAAE,oBAAoB,CAAC,EAClH,IAAI,EAAC,QAAQ,EACb,EAAE,EAAC,WAAW,EACd,IAAI,EAAC,QAAQ,EACb,KAAK,EAAE,MAAM,CAAC,UAAU,CAAC,GAC3B,EACF,gBACI,SAAS,EAAE,MAAM,CAAC,eAAe,EAAE,sBAAsB,EAAE,oBAAoB,CAAC,EAChF,IAAI,EAAC,QAAQ,EACb,EAAE,EAAC,YAAY,EACf,IAAI,EAAC,QAAQ,EACb,KAAK,EAAE,MAAM,CAAC,WAAW,CAAC,GAC5B,KACC,EACP,cAAK,SAAS,EAAC,UAAU,GAAG,KACrB,CACd,CAAC;AACN,CAAC;AAED,SAAS,aAAa;IAClB,MAAM,EAAE,kBAAkB,EAAE,aAAa,EAAE,aAAa,EAAE,GAAG,gBAAgB,EAAE,CAAC;IAEhF,IAAI,CAAC,kBAAkB,EAAE;QACrB,OAAO,IAAI,CAAC;KACf;IAED,OAAO,KAAC,aAAa,cAAE,aAAa,GAAiB,CAAC;AAC1D,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "keycloakify",
3
- "version": "10.0.0-rc.77",
3
+ "version": "10.0.0-rc.78",
4
4
  "description": "Create Keycloak themes using React",
5
5
  "repository": {
6
6
  "type": "git",
@@ -136,6 +136,9 @@
136
136
  "account/i18n/index.d.ts",
137
137
  "account/i18n/index.js",
138
138
  "account/i18n/index.js.map",
139
+ "account/i18n/useI18n.d.ts",
140
+ "account/i18n/useI18n.js",
141
+ "account/i18n/useI18n.js.map",
139
142
  "account/index.d.ts",
140
143
  "account/index.js",
141
144
  "account/index.js.map",
@@ -289,6 +292,9 @@
289
292
  "login/i18n/index.d.ts",
290
293
  "login/i18n/index.js",
291
294
  "login/i18n/index.js.map",
295
+ "login/i18n/useI18n.d.ts",
296
+ "login/i18n/useI18n.js",
297
+ "login/i18n/useI18n.js.map",
292
298
  "login/index.d.ts",
293
299
  "login/index.js",
294
300
  "login/index.js.map",
@@ -444,6 +450,7 @@
444
450
  "src/account/i18n/baseMessages/zh-CN.ts",
445
451
  "src/account/i18n/i18n.tsx",
446
452
  "src/account/i18n/index.ts",
453
+ "src/account/i18n/useI18n.ts",
447
454
  "src/account/index.ts",
448
455
  "src/account/lib/kcClsx.ts",
449
456
  "src/account/pages/Account.tsx",
@@ -572,9 +579,10 @@
572
579
  "src/login/i18n/baseMessages/zh-CN.ts",
573
580
  "src/login/i18n/i18n.tsx",
574
581
  "src/login/i18n/index.ts",
582
+ "src/login/i18n/useI18n.ts",
575
583
  "src/login/index.ts",
576
584
  "src/login/lib/kcClsx.ts",
577
- "src/login/lib/useDownloadTerms.ts",
585
+ "src/login/lib/useDownloadTerms.tsx",
578
586
  "src/login/lib/useUserProfileForm.tsx",
579
587
  "src/login/pages/Code.tsx",
580
588
  "src/login/pages/DeleteAccountConfirm.tsx",
@@ -616,7 +624,6 @@
616
624
  "src/tools/ExtractAfterStartingWith.ts",
617
625
  "src/tools/HTMLElement.prototype.prepend.ts",
618
626
  "src/tools/LazyOrNot.ts",
619
- "src/tools/Markdown.ts",
620
627
  "src/tools/Object.fromEntries.ts",
621
628
  "src/tools/StatefulObservable/README.md",
622
629
  "src/tools/StatefulObservable/StatefulObservable.ts",
@@ -632,6 +639,7 @@
632
639
  "src/tools/emailRegExp.ts",
633
640
  "src/tools/formatNumber.ts",
634
641
  "src/tools/pathBasename.ts",
642
+ "src/tools/react-markdown.ts",
635
643
  "src/tools/structuredCloneButFunctions.ts",
636
644
  "src/tools/useConst.ts",
637
645
  "src/tools/useConstCallback.ts",
@@ -699,9 +707,6 @@
699
707
  "tools/LazyOrNot.d.ts",
700
708
  "tools/LazyOrNot.js",
701
709
  "tools/LazyOrNot.js.map",
702
- "tools/Markdown.d.ts",
703
- "tools/Markdown.js",
704
- "tools/Markdown.js.map",
705
710
  "tools/Object.fromEntries.d.ts",
706
711
  "tools/Object.fromEntries.js",
707
712
  "tools/Object.fromEntries.js.map",
@@ -744,6 +749,9 @@
744
749
  "tools/pathBasename.d.ts",
745
750
  "tools/pathBasename.js",
746
751
  "tools/pathBasename.js.map",
752
+ "tools/react-markdown.d.ts",
753
+ "tools/react-markdown.js",
754
+ "tools/react-markdown.js.map",
747
755
  "tools/structuredCloneButFunctions.d.ts",
748
756
  "tools/structuredCloneButFunctions.js",
749
757
  "tools/structuredCloneButFunctions.js.map",
@@ -824,7 +832,7 @@
824
832
  "react": "*"
825
833
  },
826
834
  "dependencies": {
827
- "react-markdown": "^5.0.3",
835
+ "react-markdown": "^9.0.1",
828
836
  "tsafe": "^1.6.6"
829
837
  },
830
838
  "devDependencies": {
@@ -1,10 +1,8 @@
1
1
  import "keycloakify/tools/Object.fromEntries";
2
- import { useEffect, useState } from "react";
3
2
  import { assert } from "tsafe/assert";
4
3
  import messages_fallbackLanguage from "./baseMessages/en";
5
4
  import { getMessages } from "./baseMessages";
6
5
  import type { KcContext } from "../KcContext";
7
- import { Reflect } from "tsafe/Reflect";
8
6
 
9
7
  export const fallbackLanguageTag = "en";
10
8
 
@@ -88,7 +86,9 @@ export type GenericI18n<MessageKey extends string> = {
88
86
  isFetchingTranslations: boolean;
89
87
  };
90
88
 
91
- function createGetI18n<ExtraMessageKey extends string = never>(extraMessages: { [languageTag: string]: { [key in ExtraMessageKey]: string } }) {
89
+ export function createGetI18n<ExtraMessageKey extends string = never>(messageBundle: {
90
+ [languageTag: string]: { [key in ExtraMessageKey]: string };
91
+ }) {
92
92
  type I18n = GenericI18n<MessageKey | ExtraMessageKey>;
93
93
 
94
94
  type Result = { i18n: I18n; prI18n_currentLanguage: Promise<I18n> | undefined };
@@ -126,8 +126,8 @@ function createGetI18n<ExtraMessageKey extends string = never>(extraMessages: {
126
126
 
127
127
  const { createI18nTranslationFunctions } = createI18nTranslationFunctionsFactory<MessageKey, ExtraMessageKey>({
128
128
  messages_fallbackLanguage,
129
- extraMessages_fallbackLanguage: extraMessages[fallbackLanguageTag],
130
- extraMessages: extraMessages[partialI18n.currentLanguageTag]
129
+ messageBundle_fallbackLanguage: messageBundle[fallbackLanguageTag],
130
+ messageBundle_currentLanguage: messageBundle[partialI18n.currentLanguageTag]
131
131
  });
132
132
 
133
133
  const isCurrentLanguageFallbackLanguage = partialI18n.currentLanguageTag === fallbackLanguageTag;
@@ -135,17 +135,19 @@ function createGetI18n<ExtraMessageKey extends string = never>(extraMessages: {
135
135
  const result: Result = {
136
136
  i18n: {
137
137
  ...partialI18n,
138
- ...createI18nTranslationFunctions({ messages: undefined }),
138
+ ...createI18nTranslationFunctions({
139
+ messages_currentLanguage: isCurrentLanguageFallbackLanguage ? messages_fallbackLanguage : undefined
140
+ }),
139
141
  isFetchingTranslations: !isCurrentLanguageFallbackLanguage
140
142
  },
141
143
  prI18n_currentLanguage: isCurrentLanguageFallbackLanguage
142
144
  ? undefined
143
145
  : (async () => {
144
- const messages = await getMessages(partialI18n.currentLanguageTag);
146
+ const messages_currentLanguage = await getMessages(partialI18n.currentLanguageTag);
145
147
 
146
148
  const i18n_currentLanguage: I18n = {
147
149
  ...partialI18n,
148
- ...createI18nTranslationFunctions({ messages }),
150
+ ...createI18nTranslationFunctions({ messages_currentLanguage }),
149
151
  isFetchingTranslations: false
150
152
  };
151
153
 
@@ -168,66 +170,30 @@ function createGetI18n<ExtraMessageKey extends string = never>(extraMessages: {
168
170
  return { getI18n };
169
171
  }
170
172
 
171
- export function createUseI18n<ExtraMessageKey extends string = never>(extraMessages: {
172
- [languageTag: string]: { [key in ExtraMessageKey]: string };
173
- }) {
174
- type I18n = GenericI18n<MessageKey | ExtraMessageKey>;
175
-
176
- const { getI18n } = createGetI18n(extraMessages);
177
-
178
- function useI18n(params: { kcContext: KcContextLike }): { i18n: I18n } {
179
- const { kcContext } = params;
180
-
181
- const { i18n, prI18n_currentLanguage } = getI18n({ kcContext });
182
-
183
- const [i18n_toReturn, setI18n_toReturn] = useState<I18n>(i18n);
184
-
185
- useEffect(() => {
186
- let isActive = true;
187
-
188
- prI18n_currentLanguage?.then(i18n => {
189
- if (!isActive) {
190
- return;
191
- }
192
-
193
- setI18n_toReturn(i18n);
194
- });
195
-
196
- return () => {
197
- isActive = false;
198
- };
199
- }, []);
200
-
201
- return { i18n: i18n_toReturn };
202
- }
203
-
204
- return { useI18n, ofTypeI18n: Reflect<I18n>() };
205
- }
206
-
207
173
  function createI18nTranslationFunctionsFactory<MessageKey extends string, ExtraMessageKey extends string>(params: {
208
174
  messages_fallbackLanguage: Record<MessageKey, string>;
209
- extraMessages_fallbackLanguage: Record<ExtraMessageKey, string> | undefined;
210
- extraMessages: Partial<Record<ExtraMessageKey, string>> | undefined;
175
+ messageBundle_fallbackLanguage: Record<ExtraMessageKey, string> | undefined;
176
+ messageBundle_currentLanguage: Partial<Record<ExtraMessageKey, string>> | undefined;
211
177
  }) {
212
- const { extraMessages } = params;
178
+ const { messageBundle_currentLanguage } = params;
213
179
 
214
180
  const messages_fallbackLanguage = {
215
181
  ...params.messages_fallbackLanguage,
216
- ...params.extraMessages_fallbackLanguage
182
+ ...params.messageBundle_fallbackLanguage
217
183
  };
218
184
 
219
185
  function createI18nTranslationFunctions(params: {
220
- messages: Partial<Record<MessageKey, string>> | undefined;
186
+ messages_currentLanguage: Partial<Record<MessageKey, string>> | undefined;
221
187
  }): Pick<GenericI18n<MessageKey | ExtraMessageKey>, "msg" | "msgStr" | "advancedMsg" | "advancedMsgStr"> {
222
- const messages = {
223
- ...params.messages,
224
- ...extraMessages
188
+ const messages_currentLanguage = {
189
+ ...params.messages_currentLanguage,
190
+ ...messageBundle_currentLanguage
225
191
  };
226
192
 
227
193
  function resolveMsg(props: { key: string; args: (string | undefined)[]; doRenderAsHtml: boolean }): string | JSX.Element | undefined {
228
194
  const { key, args, doRenderAsHtml } = props;
229
195
 
230
- const messageOrUndefined: string | undefined = (messages as any)[key] ?? (messages_fallbackLanguage as any)[key];
196
+ const messageOrUndefined: string | undefined = (messages_currentLanguage as any)[key] ?? (messages_fallbackLanguage as any)[key];
231
197
 
232
198
  if (messageOrUndefined === undefined) {
233
199
  return undefined;
@@ -1,5 +1,5 @@
1
1
  import type { GenericI18n, MessageKey, KcContextLike } from "./i18n";
2
2
  export type { MessageKey, KcContextLike };
3
3
  export type I18n = GenericI18n<MessageKey>;
4
- export { createUseI18n } from "./i18n";
4
+ export { createUseI18n } from "./useI18n";
5
5
  export { fallbackLanguageTag } from "./i18n";
@@ -0,0 +1,44 @@
1
+ import { useEffect, useState } from "react";
2
+ import {
3
+ createGetI18n,
4
+ type GenericI18n,
5
+ type MessageKey,
6
+ type KcContextLike
7
+ } from "./i18n";
8
+ import { Reflect } from "tsafe/Reflect";
9
+
10
+ export function createUseI18n<ExtraMessageKey extends string = never>(extraMessages: {
11
+ [languageTag: string]: { [key in ExtraMessageKey]: string };
12
+ }) {
13
+ type I18n = GenericI18n<MessageKey | ExtraMessageKey>;
14
+
15
+ const { getI18n } = createGetI18n(extraMessages);
16
+
17
+ function useI18n(params: { kcContext: KcContextLike }): { i18n: I18n } {
18
+ const { kcContext } = params;
19
+
20
+ const { i18n, prI18n_currentLanguage } = getI18n({ kcContext });
21
+
22
+ const [i18n_toReturn, setI18n_toReturn] = useState<I18n>(i18n);
23
+
24
+ useEffect(() => {
25
+ let isActive = true;
26
+
27
+ prI18n_currentLanguage?.then(i18n => {
28
+ if (!isActive) {
29
+ return;
30
+ }
31
+
32
+ setI18n_toReturn(i18n);
33
+ });
34
+
35
+ return () => {
36
+ isActive = false;
37
+ };
38
+ }, []);
39
+
40
+ return { i18n: i18n_toReturn };
41
+ }
42
+
43
+ return { useI18n, ofTypeI18n: Reflect<I18n>() };
44
+ }
@@ -8,8 +8,7 @@ import { assert } from "tsafe/assert";
8
8
  import {
9
9
  type ThemeType,
10
10
  basenameOfTheKeycloakifyResourcesDir,
11
- resources_common,
12
- nameOfTheLocalizationRealmOverridesUserProfileProperty
11
+ resources_common
13
12
  } from "../../shared/constants";
14
13
  import { getThisCodebaseRootDirPath } from "../../tools/getThisCodebaseRootDirPath";
15
14
 
@@ -119,10 +118,6 @@ export function generateFtlFilesCodeFactory(params: {
119
118
  .replace("KEYCLOAKIFY_THEME_TYPE_dExKd3xEdr", themeType)
120
119
  .replace("KEYCLOAKIFY_THEME_NAME_cXxKd3xEer", themeName)
121
120
  .replace("RESOURCES_COMMON_cLsLsMrtDkpVv", resources_common)
122
- .replace(
123
- "lOCALIZATION_REALM_OVERRIDES_USER_PROFILE_PROPERTY_KEY_aaGLsPgGIdeeX",
124
- nameOfTheLocalizationRealmOverridesUserProfileProperty
125
- )
126
121
  .replace(
127
122
  "USER_DEFINED_EXCLUSIONS_eKsaY4ZsZ4eMr2",
128
123
  buildContext.kcContextExclusionsFtlCode ?? ""
@@ -33,8 +33,9 @@ kcContext.pageId = "${pageId}";
33
33
  if( kcContext.url && kcContext.url.resourcesPath ){
34
34
  kcContext.url.resourcesCommonPath = kcContext.url.resourcesPath + "/" + "RESOURCES_COMMON_cLsLsMrtDkpVv";
35
35
  }
36
+ kcContext["x-keycloakify"] = {};
36
37
  <#if profile?? && profile.attributes??>
37
- kcContext.lOCALIZATION_REALM_OVERRIDES_USER_PROFILE_PROPERTY_KEY_aaGLsPgGIdeeX = {
38
+ kcContext["x-keycloakify"].realmMessageBundleUserProfile = {
38
39
  <#list profile.attributes as attribute>
39
40
  <#if attribute.annotations?? && attribute.displayName??>
40
41
  "${attribute.displayName}": decodeHtmlEntities("${advancedMsg(attribute.displayName)?js_string}"),
@@ -61,6 +62,9 @@ if( kcContext.url && kcContext.url.resourcesPath ){
61
62
  </#list>
62
63
  };
63
64
  </#if>
65
+ <#if pageId == "terms.ftl" || termsAcceptanceRequired?? && termsAcceptanceRequired>
66
+ kcContext["x-keycloakify"].realmMessageBundleTermsText= decodeHtmlEntities("${msg("termsText")?js_string}");
67
+ </#if>
64
68
  attributes_to_attributesByName: {
65
69
  if( !kcContext.profile ){
66
70
  break attributes_to_attributesByName;
@@ -198,6 +202,9 @@ function decodeHtmlEntities(htmlStr){
198
202
  ) || (
199
203
  key == "execution" &&
200
204
  are_same_path(path, [])
205
+ ) || (
206
+ key == "entity" &&
207
+ are_same_path(path, ["user"])
201
208
  )
202
209
  >
203
210
  <#-- <#local out_seq += ["/*" + path?join(".") + "." + key + " excluded*/"]> -->
@@ -9,6 +9,8 @@ import * as babelParser from "@babel/parser";
9
9
  import babelGenerate from "@babel/generator";
10
10
  import * as babelTypes from "@babel/types";
11
11
  import { escapeStringForPropertiesFile } from "../../tools/escapeStringForPropertiesFile";
12
+ import { getThisCodebaseRootDirPath } from "../../tools/getThisCodebaseRootDirPath";
13
+ import * as fs from "fs";
12
14
 
13
15
  export function generateMessageProperties(params: {
14
16
  themeSrcDirPath: string;
@@ -39,10 +41,6 @@ export function generateMessageProperties(params: {
39
41
  readFileSync(file).toString("utf8").includes("createUseI18n")
40
42
  );
41
43
 
42
- if (files.length === 0) {
43
- return [];
44
- }
45
-
46
44
  const extraMessages = files
47
45
  .map(file => {
48
46
  const root = recast.parse(readFileSync(file).toString("utf8"), {
@@ -99,15 +97,28 @@ export function generateMessageProperties(params: {
99
97
  return extraMessages;
100
98
  });
101
99
 
102
- const languageTags = extraMessages
103
- .map(extraMessage => Object.keys(extraMessage))
104
- .flat()
105
- .reduce(...removeDuplicates<string>());
100
+ const languageTags = [
101
+ ...extraMessages.map(extraMessage => Object.keys(extraMessage)).flat(),
102
+ ...fs
103
+ .readdirSync(
104
+ pathJoin(
105
+ getThisCodebaseRootDirPath(),
106
+ "src",
107
+ themeType,
108
+ "i18n",
109
+ "baseMessages"
110
+ )
111
+ )
112
+ .filter(baseName => baseName !== "index.ts")
113
+ .map(baseName => baseName.replace(/\.ts$/, ""))
114
+ ].reduce(...removeDuplicates<string>());
106
115
 
107
116
  const keyValueMapByLanguageTag: Record<string, Record<string, string>> = {};
108
117
 
109
118
  for (const languageTag of languageTags) {
110
- const keyValueMap: Record<string, string> = {};
119
+ const keyValueMap: Record<string, string> = {
120
+ termsText: ""
121
+ };
111
122
 
112
123
  for (const extraMessage of extraMessages) {
113
124
  const keyValueMap_i = extraMessage[languageTag];
@@ -152,14 +163,9 @@ export function generateMessageProperties(params: {
152
163
 
153
164
  out.push({
154
165
  languageTag,
155
- propertiesFileSource: [
156
- "# This file was generated by keycloakify",
157
- "",
158
- "parent=base",
159
- "",
160
- propertiesFileSource,
161
- ""
162
- ].join("\n")
166
+ propertiesFileSource: ["", "parent=base", "", propertiesFileSource, ""].join(
167
+ "\n"
168
+ )
163
169
  });
164
170
  }
165
171
 
@@ -1,5 +1,3 @@
1
- export const nameOfTheLocalizationRealmOverridesUserProfileProperty =
2
- "__localizationRealmOverridesUserProfile";
3
1
  export const keycloak_resources = "keycloak-resources";
4
2
  export const resources_common = "resources-common";
5
3
  export const lastKeycloakVersionWithAccountV1 = "21.1.2";
@@ -1,8 +1,4 @@
1
- import type {
2
- ThemeType,
3
- LoginThemePageId,
4
- nameOfTheLocalizationRealmOverridesUserProfileProperty
5
- } from "keycloakify/bin/shared/constants";
1
+ import type { ThemeType, LoginThemePageId } from "keycloakify/bin/shared/constants";
6
2
  import type { ExtractAfterStartingWith } from "keycloakify/tools/ExtractAfterStartingWith";
7
3
  import type { ValueOf } from "keycloakify/tools/ValueOf";
8
4
  import { assert } from "tsafe/assert";
@@ -158,7 +154,10 @@ export declare namespace KcContext {
158
154
  ssoLoginInOtherTabsUrl: string;
159
155
  };
160
156
  properties: {};
161
- __localizationRealmOverridesUserProfile?: Record<string, string>;
157
+ "x-keycloakify": {
158
+ realmMessageBundleUserProfile: Record<string, string> | undefined;
159
+ realmMessageBundleTermsText: string | undefined;
160
+ };
162
161
  };
163
162
 
164
163
  export type SamlPostForm = Common & {
@@ -276,6 +275,7 @@ export declare namespace KcContext {
276
275
  lastName?: string;
277
276
  markedForEviction?: boolean;
278
277
  };
278
+ __localizationRealmOverridesTermsText?: string;
279
279
  };
280
280
 
281
281
  export type LoginDeviceVerifyUserCode = Common & {
@@ -772,11 +772,3 @@ export type PasswordPolicies = {
772
772
  /** Whether the password can be the email address */
773
773
  notEmail?: boolean;
774
774
  };
775
-
776
- assert<
777
- KcContext.Common extends Partial<
778
- Record<typeof nameOfTheLocalizationRealmOverridesUserProfileProperty, unknown>
779
- >
780
- ? true
781
- : false
782
- >();
@@ -161,7 +161,10 @@ export const kcContextCommonMock: KcContext.Common = {
161
161
  scripts: [],
162
162
  isAppInitiatedAction: false,
163
163
  properties: {},
164
- __localizationRealmOverridesUserProfile: {}
164
+ "x-keycloakify": {
165
+ realmMessageBundleUserProfile: undefined,
166
+ realmMessageBundleTermsText: undefined
167
+ }
165
168
  };
166
169
 
167
170
  const loginUrl = {
@@ -1,10 +1,8 @@
1
1
  import "keycloakify/tools/Object.fromEntries";
2
- import { useEffect, useState } from "react";
3
2
  import { assert } from "tsafe/assert";
4
3
  import messages_fallbackLanguage from "./baseMessages/en";
5
4
  import { getMessages } from "./baseMessages";
6
5
  import type { KcContext } from "../KcContext";
7
- import { Reflect } from "tsafe/Reflect";
8
6
 
9
7
  export const fallbackLanguageTag = "en";
10
8
 
@@ -13,7 +11,10 @@ export type KcContextLike = {
13
11
  currentLanguageTag: string;
14
12
  supported: { languageTag: string; url: string; label: string }[];
15
13
  };
16
- __localizationRealmOverridesUserProfile?: Record<string, string>;
14
+ "x-keycloakify": {
15
+ realmMessageBundleUserProfile: Record<string, string> | undefined;
16
+ realmMessageBundleTermsText: string | undefined;
17
+ };
17
18
  };
18
19
 
19
20
  assert<KcContext extends KcContextLike ? true : false>();
@@ -89,7 +90,9 @@ export type GenericI18n<MessageKey extends string> = {
89
90
  isFetchingTranslations: boolean;
90
91
  };
91
92
 
92
- function createGetI18n<ExtraMessageKey extends string = never>(extraMessages: { [languageTag: string]: { [key in ExtraMessageKey]: string } }) {
93
+ export function createGetI18n<ExtraMessageKey extends string = never>(messageBundle: {
94
+ [languageTag: string]: { [key in ExtraMessageKey]: string };
95
+ }) {
93
96
  type I18n = GenericI18n<MessageKey | ExtraMessageKey>;
94
97
 
95
98
  type Result = { i18n: I18n; prI18n_currentLanguage: Promise<I18n> | undefined };
@@ -127,9 +130,10 @@ function createGetI18n<ExtraMessageKey extends string = never>(extraMessages: {
127
130
 
128
131
  const { createI18nTranslationFunctions } = createI18nTranslationFunctionsFactory<MessageKey, ExtraMessageKey>({
129
132
  messages_fallbackLanguage,
130
- extraMessages_fallbackLanguage: extraMessages[fallbackLanguageTag],
131
- extraMessages: extraMessages[partialI18n.currentLanguageTag],
132
- __localizationRealmOverridesUserProfile: kcContext.__localizationRealmOverridesUserProfile
133
+ messageBundle_fallbackLanguage: messageBundle[fallbackLanguageTag],
134
+ messageBundle_currentLanguage: messageBundle[partialI18n.currentLanguageTag],
135
+ realmMessageBundleUserProfile: kcContext["x-keycloakify"].realmMessageBundleUserProfile,
136
+ realmMessageBundleTermsText: kcContext["x-keycloakify"].realmMessageBundleTermsText
133
137
  });
134
138
 
135
139
  const isCurrentLanguageFallbackLanguage = partialI18n.currentLanguageTag === fallbackLanguageTag;
@@ -137,17 +141,19 @@ function createGetI18n<ExtraMessageKey extends string = never>(extraMessages: {
137
141
  const result: Result = {
138
142
  i18n: {
139
143
  ...partialI18n,
140
- ...createI18nTranslationFunctions({ messages: undefined }),
144
+ ...createI18nTranslationFunctions({
145
+ messages_currentLanguage: isCurrentLanguageFallbackLanguage ? messages_fallbackLanguage : undefined
146
+ }),
141
147
  isFetchingTranslations: !isCurrentLanguageFallbackLanguage
142
148
  },
143
149
  prI18n_currentLanguage: isCurrentLanguageFallbackLanguage
144
150
  ? undefined
145
151
  : (async () => {
146
- const messages = await getMessages(partialI18n.currentLanguageTag);
152
+ const messages_currentLanguage = await getMessages(partialI18n.currentLanguageTag);
147
153
 
148
154
  const i18n_currentLanguage: I18n = {
149
155
  ...partialI18n,
150
- ...createI18nTranslationFunctions({ messages }),
156
+ ...createI18nTranslationFunctions({ messages_currentLanguage }),
151
157
  isFetchingTranslations: false
152
158
  };
153
159
 
@@ -170,67 +176,40 @@ function createGetI18n<ExtraMessageKey extends string = never>(extraMessages: {
170
176
  return { getI18n };
171
177
  }
172
178
 
173
- export function createUseI18n<ExtraMessageKey extends string = never>(extraMessages: {
174
- [languageTag: string]: { [key in ExtraMessageKey]: string };
175
- }) {
176
- type I18n = GenericI18n<MessageKey | ExtraMessageKey>;
177
-
178
- const { getI18n } = createGetI18n(extraMessages);
179
-
180
- function useI18n(params: { kcContext: KcContextLike }): { i18n: I18n } {
181
- const { kcContext } = params;
182
-
183
- const { i18n, prI18n_currentLanguage } = getI18n({ kcContext });
184
-
185
- const [i18n_toReturn, setI18n_toReturn] = useState<I18n>(i18n);
186
-
187
- useEffect(() => {
188
- let isActive = true;
189
-
190
- prI18n_currentLanguage?.then(i18n => {
191
- if (!isActive) {
192
- return;
193
- }
194
-
195
- setI18n_toReturn(i18n);
196
- });
197
-
198
- return () => {
199
- isActive = false;
200
- };
201
- }, []);
202
-
203
- return { i18n: i18n_toReturn };
204
- }
205
-
206
- return { useI18n, ofTypeI18n: Reflect<I18n>() };
207
- }
208
-
209
179
  function createI18nTranslationFunctionsFactory<MessageKey extends string, ExtraMessageKey extends string>(params: {
210
180
  messages_fallbackLanguage: Record<MessageKey, string>;
211
- extraMessages_fallbackLanguage: Record<ExtraMessageKey, string> | undefined;
212
- extraMessages: Partial<Record<ExtraMessageKey, string>> | undefined;
213
- __localizationRealmOverridesUserProfile: Record<string, string> | undefined;
181
+ messageBundle_fallbackLanguage: Record<ExtraMessageKey, string> | undefined;
182
+ messageBundle_currentLanguage: Partial<Record<ExtraMessageKey, string>> | undefined;
183
+ realmMessageBundleUserProfile: Record<string, string> | undefined;
184
+ realmMessageBundleTermsText: string | undefined;
214
185
  }) {
215
- const { __localizationRealmOverridesUserProfile, extraMessages } = params;
186
+ const { messageBundle_currentLanguage, realmMessageBundleUserProfile, realmMessageBundleTermsText } = params;
216
187
 
217
188
  const messages_fallbackLanguage = {
218
189
  ...params.messages_fallbackLanguage,
219
- ...params.extraMessages_fallbackLanguage
190
+ ...params.messageBundle_fallbackLanguage
220
191
  };
221
192
 
222
193
  function createI18nTranslationFunctions(params: {
223
- messages: Partial<Record<MessageKey, string>> | undefined;
194
+ messages_currentLanguage: Partial<Record<MessageKey, string>> | undefined;
224
195
  }): Pick<GenericI18n<MessageKey | ExtraMessageKey>, "msg" | "msgStr" | "advancedMsg" | "advancedMsgStr"> {
225
- const messages = {
226
- ...params.messages,
227
- ...extraMessages
196
+ const messages_currentLanguage = {
197
+ ...params.messages_currentLanguage,
198
+ ...messageBundle_currentLanguage
228
199
  };
229
200
 
230
201
  function resolveMsg(props: { key: string; args: (string | undefined)[]; doRenderAsHtml: boolean }): string | JSX.Element | undefined {
231
202
  const { key, args, doRenderAsHtml } = props;
232
203
 
233
- const messageOrUndefined: string | undefined = (messages as any)[key] ?? (messages_fallbackLanguage as any)[key];
204
+ const messageOrUndefined: string | undefined = (() => {
205
+ const messageOrUndefined = (messages_currentLanguage as any)[key] ?? (messages_fallbackLanguage as any)[key];
206
+
207
+ if (key === "termsText") {
208
+ return realmMessageBundleTermsText;
209
+ }
210
+
211
+ return messageOrUndefined;
212
+ })();
234
213
 
235
214
  if (messageOrUndefined === undefined) {
236
215
  return undefined;
@@ -281,8 +260,8 @@ function createI18nTranslationFunctionsFactory<MessageKey extends string, ExtraM
281
260
  function resolveMsgAdvanced(props: { key: string; args: (string | undefined)[]; doRenderAsHtml: boolean }): JSX.Element | string {
282
261
  const { key, args, doRenderAsHtml } = props;
283
262
 
284
- if (__localizationRealmOverridesUserProfile !== undefined && key in __localizationRealmOverridesUserProfile) {
285
- const resolvedMessage = __localizationRealmOverridesUserProfile[key];
263
+ if (realmMessageBundleUserProfile !== undefined && key in realmMessageBundleUserProfile) {
264
+ const resolvedMessage = realmMessageBundleUserProfile[key];
286
265
 
287
266
  return doRenderAsHtml ? (
288
267
  <span
@@ -1,5 +1,5 @@
1
1
  import type { GenericI18n, MessageKey, KcContextLike } from "./i18n";
2
2
  export type { MessageKey, KcContextLike };
3
3
  export type I18n = GenericI18n<MessageKey>;
4
- export { createUseI18n } from "./i18n";
4
+ export { createUseI18n } from "./useI18n";
5
5
  export { fallbackLanguageTag } from "./i18n";