keycloakify 11.4.0-rc.0 → 11.4.0

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 (93) hide show
  1. package/README.md +2 -0
  2. package/account/i18n/noJsx/getI18n.js +5 -7
  3. package/account/i18n/noJsx/getI18n.js.map +1 -1
  4. package/account/i18n/withJsx/useI18n.js +15 -4
  5. package/account/i18n/withJsx/useI18n.js.map +1 -1
  6. package/bin/20.index.js +0 -85
  7. package/bin/33.index.js +55 -212
  8. package/bin/356.index.js +106 -45
  9. package/bin/36.index.js +1 -2922
  10. package/bin/{526.index.js → 392.index.js} +89 -3
  11. package/bin/40.index.js +1 -86
  12. package/bin/453.index.js +85 -22
  13. package/bin/573.index.js +4 -86
  14. package/bin/653.index.js +752 -0
  15. package/bin/658.index.js +197 -0
  16. package/bin/735.index.js +343 -116
  17. package/bin/786.index.js +78 -14
  18. package/bin/805.index.js +15 -18
  19. package/bin/921.index.js +79 -18
  20. package/bin/97.index.js +64 -13
  21. package/bin/main.js +165 -86
  22. package/bin/shared/constants.d.ts +2 -0
  23. package/bin/shared/constants.js +3 -1
  24. package/bin/shared/constants.js.map +1 -1
  25. package/bin/start-keycloak/startViteDevServer.d.ts +7 -0
  26. package/bin/tools/crawlAsync.d.ts +1 -1
  27. package/bin/tools/isTrackedByGit.d.ts +3 -0
  28. package/bin/tools/runPrettier.d.ts +5 -5
  29. package/bin/tools/untrackFromGit.d.ts +3 -0
  30. package/lib/getKcClsx.js +1 -2
  31. package/lib/getKcClsx.js.map +1 -1
  32. package/login/KcContext/KcContext.d.ts +2 -2
  33. package/login/KcContext/kcContextMocks.d.ts +1 -1
  34. package/login/TemplateProps.d.ts +0 -1
  35. package/login/i18n/noJsx/getI18n.js +5 -7
  36. package/login/i18n/noJsx/getI18n.js.map +1 -1
  37. package/login/i18n/withJsx/useI18n.js +15 -4
  38. package/login/i18n/withJsx/useI18n.js.map +1 -1
  39. package/login/pages/LoginConfigTotp.js +1 -1
  40. package/login/pages/LoginConfigTotp.js.map +1 -1
  41. package/login/pages/LoginPasskeysConditionalAuthenticate.js +16 -18
  42. package/login/pages/LoginPasskeysConditionalAuthenticate.js.map +1 -1
  43. package/package.json +17 -7
  44. package/src/account/i18n/noJsx/getI18n.tsx +5 -7
  45. package/src/account/i18n/withJsx/useI18n.tsx +18 -4
  46. package/src/bin/eject-page.ts +28 -10
  47. package/src/bin/initialize-account-theme/initializeAccountTheme_singlePage.ts +3 -18
  48. package/src/bin/initialize-account-theme/updateAccountThemeImplementationInConfig.ts +1 -2
  49. package/src/bin/keycloakify/generateFtl/kcContextDeclarationTemplate.ftl +39 -0
  50. package/src/bin/keycloakify/generateResources/generateResources.ts +6 -2
  51. package/src/bin/main.ts +51 -4
  52. package/src/bin/postinstall/getUiModuleFileSourceCodeReadyToBeCopied.ts +30 -19
  53. package/src/bin/postinstall/installUiModulesPeerDependencies.ts +3 -3
  54. package/src/bin/postinstall/managedGitignoreFile.ts +4 -3
  55. package/src/bin/postinstall/postinstall.ts +24 -2
  56. package/src/bin/postinstall/uiModuleMeta.ts +14 -9
  57. package/src/bin/shared/buildContext.ts +1 -2
  58. package/src/bin/shared/constants.ts +4 -1
  59. package/src/bin/start-keycloak/myrealm-realm-25.json +21 -34
  60. package/src/bin/start-keycloak/myrealm-realm-26.json +32 -35
  61. package/src/bin/start-keycloak/start-keycloak.ts +93 -1
  62. package/src/bin/start-keycloak/startViteDevServer.ts +39 -0
  63. package/src/bin/tools/crawlAsync.ts +6 -6
  64. package/src/bin/tools/isTrackedByGit.ts +29 -0
  65. package/src/bin/tools/listInstalledModules.ts +1 -2
  66. package/src/bin/tools/npmInstall.ts +396 -1
  67. package/src/bin/tools/runPrettier.ts +63 -14
  68. package/src/bin/tools/untrackFromGit.ts +24 -0
  69. package/src/bin/tsconfig.json +1 -1
  70. package/src/bin/update-kc-gen.ts +17 -2
  71. package/src/lib/getKcClsx.ts +1 -2
  72. package/src/login/KcContext/KcContext.ts +2 -2
  73. package/src/login/KcContext/kcContextMocks.ts +1 -1
  74. package/src/login/TemplateProps.ts +0 -1
  75. package/src/login/i18n/noJsx/getI18n.tsx +5 -7
  76. package/src/login/i18n/withJsx/useI18n.tsx +18 -4
  77. package/src/login/pages/LoginConfigTotp.tsx +18 -20
  78. package/src/login/pages/LoginPasskeysConditionalAuthenticate.tsx +51 -52
  79. package/src/tools/StatefulObservable/StatefulObservable.ts +1 -2
  80. package/src/tools/deepAssign.ts +1 -2
  81. package/src/tools/extractLastParenthesisContent.ts +43 -0
  82. package/src/vite-plugin/vite-plugin.ts +67 -0
  83. package/stories/login/pages/Info.stories.tsx +3 -39
  84. package/tools/StatefulObservable/StatefulObservable.js +1 -2
  85. package/tools/StatefulObservable/StatefulObservable.js.map +1 -1
  86. package/tools/deepAssign.js +1 -2
  87. package/tools/deepAssign.js.map +1 -1
  88. package/tools/extractLastParenthesisContent.d.ts +6 -0
  89. package/tools/extractLastParenthesisContent.js +36 -0
  90. package/tools/extractLastParenthesisContent.js.map +1 -0
  91. package/vite-plugin/index.js +326 -186
  92. package/bin/124.index.js +0 -348
  93. package/stories/login/pages/LoginDeviceVerifyUserCode.stories.tsx +0 -18
@@ -1,7 +1,14 @@
1
1
  import * as fs from "fs";
2
- import { join as pathJoin } from "path";
2
+ import { join as pathJoin, dirname as pathDirname } from "path";
3
3
  import * as child_process from "child_process";
4
4
  import chalk from "chalk";
5
+ import { z } from "zod";
6
+ import { assert, type Equals, is } from "tsafe/assert";
7
+ import { id } from "tsafe/id";
8
+ import { objectKeys } from "tsafe/objectKeys";
9
+ import { getAbsoluteAndInOsFormatPath } from "./getAbsoluteAndInOsFormatPath";
10
+ import { exclude } from "tsafe/exclude";
11
+ import { rmSync } from "./fs.rmSync";
5
12
 
6
13
  export function npmInstall(params: { packageJsonDirPath: string }) {
7
14
  const { packageJsonDirPath } = params;
@@ -48,6 +55,27 @@ export function npmInstall(params: { packageJsonDirPath: string }) {
48
55
 
49
56
  console.log(`Installing the new dependencies...`);
50
57
 
58
+ install_without_breaking_links: {
59
+ if (packageManagerBinName !== "yarn") {
60
+ break install_without_breaking_links;
61
+ }
62
+
63
+ const garronejLinkInfos = getGarronejLinkInfos({ packageJsonDirPath });
64
+
65
+ if (garronejLinkInfos === undefined) {
66
+ break install_without_breaking_links;
67
+ }
68
+
69
+ console.log(chalk.green("Installing in a way that won't break the links..."));
70
+
71
+ installWithoutBreakingLinks({
72
+ packageJsonDirPath,
73
+ garronejLinkInfos
74
+ });
75
+
76
+ return;
77
+ }
78
+
51
79
  try {
52
80
  child_process.execSync(`${packageManagerBinName} install`, {
53
81
  cwd: packageJsonDirPath,
@@ -61,3 +89,370 @@ export function npmInstall(params: { packageJsonDirPath: string }) {
61
89
  );
62
90
  }
63
91
  }
92
+
93
+ function getGarronejLinkInfos(params: {
94
+ packageJsonDirPath: string;
95
+ }): { linkedModuleNames: string[]; yarnHomeDirPath: string } | undefined {
96
+ const { packageJsonDirPath } = params;
97
+
98
+ const nodeModuleDirPath = pathJoin(packageJsonDirPath, "node_modules");
99
+
100
+ if (!fs.existsSync(nodeModuleDirPath)) {
101
+ return undefined;
102
+ }
103
+
104
+ const linkedModuleNames: string[] = [];
105
+
106
+ let yarnHomeDirPath: string | undefined = undefined;
107
+
108
+ const getIsLinkedByGarronejScript = (path: string) => {
109
+ let realPath: string;
110
+
111
+ try {
112
+ realPath = fs.readlinkSync(path);
113
+ } catch {
114
+ return false;
115
+ }
116
+
117
+ const doesIncludeYarnHome = realPath.includes(".yarn_home");
118
+
119
+ if (!doesIncludeYarnHome) {
120
+ return false;
121
+ }
122
+
123
+ set_yarnHomeDirPath: {
124
+ if (yarnHomeDirPath !== undefined) {
125
+ break set_yarnHomeDirPath;
126
+ }
127
+
128
+ const [firstElement] = getAbsoluteAndInOsFormatPath({
129
+ pathIsh: realPath,
130
+ cwd: pathDirname(path)
131
+ }).split(".yarn_home");
132
+
133
+ yarnHomeDirPath = pathJoin(firstElement, ".yarn_home");
134
+ }
135
+
136
+ return true;
137
+ };
138
+
139
+ for (const basename of fs.readdirSync(nodeModuleDirPath)) {
140
+ const path = pathJoin(nodeModuleDirPath, basename);
141
+
142
+ if (fs.lstatSync(path).isSymbolicLink()) {
143
+ if (basename.startsWith("@")) {
144
+ return undefined;
145
+ }
146
+
147
+ if (!getIsLinkedByGarronejScript(path)) {
148
+ return undefined;
149
+ }
150
+
151
+ linkedModuleNames.push(basename);
152
+ continue;
153
+ }
154
+
155
+ if (!fs.lstatSync(path).isDirectory()) {
156
+ continue;
157
+ }
158
+
159
+ if (basename.startsWith("@")) {
160
+ for (const subBasename of fs.readdirSync(path)) {
161
+ const subPath = pathJoin(path, subBasename);
162
+
163
+ if (!fs.lstatSync(subPath).isSymbolicLink()) {
164
+ continue;
165
+ }
166
+
167
+ if (!getIsLinkedByGarronejScript(subPath)) {
168
+ return undefined;
169
+ }
170
+
171
+ linkedModuleNames.push(`${basename}/${subBasename}`);
172
+ }
173
+ }
174
+ }
175
+
176
+ if (yarnHomeDirPath === undefined) {
177
+ return undefined;
178
+ }
179
+
180
+ return { linkedModuleNames, yarnHomeDirPath };
181
+ }
182
+
183
+ function installWithoutBreakingLinks(params: {
184
+ packageJsonDirPath: string;
185
+ garronejLinkInfos: Exclude<ReturnType<typeof getGarronejLinkInfos>, undefined>;
186
+ }) {
187
+ const {
188
+ packageJsonDirPath,
189
+ garronejLinkInfos: { linkedModuleNames, yarnHomeDirPath }
190
+ } = params;
191
+
192
+ const parsedPackageJson = (() => {
193
+ const packageJsonFilePath = pathJoin(packageJsonDirPath, "package.json");
194
+
195
+ type ParsedPackageJson = {
196
+ scripts?: Record<string, string>;
197
+ };
198
+
199
+ const zParsedPackageJson = (() => {
200
+ type TargetType = ParsedPackageJson;
201
+
202
+ const zTargetType = z.object({
203
+ scripts: z.record(z.string()).optional()
204
+ });
205
+
206
+ type InferredType = z.infer<typeof zTargetType>;
207
+
208
+ assert<Equals<TargetType, InferredType>>;
209
+
210
+ return id<z.ZodType<TargetType>>(zTargetType);
211
+ })();
212
+
213
+ const parsedPackageJson = JSON.parse(
214
+ fs.readFileSync(packageJsonFilePath).toString("utf8")
215
+ ) as unknown;
216
+
217
+ zParsedPackageJson.parse(parsedPackageJson);
218
+ assert(is<ParsedPackageJson>(parsedPackageJson));
219
+
220
+ return parsedPackageJson;
221
+ })();
222
+
223
+ const isImplementedScriptByName = {
224
+ postinstall: false,
225
+ prepare: false
226
+ };
227
+
228
+ delete_postinstall_script: {
229
+ if (parsedPackageJson.scripts === undefined) {
230
+ break delete_postinstall_script;
231
+ }
232
+
233
+ for (const scriptName of objectKeys(isImplementedScriptByName)) {
234
+ if (parsedPackageJson.scripts[scriptName] === undefined) {
235
+ continue;
236
+ }
237
+
238
+ isImplementedScriptByName[scriptName] = true;
239
+
240
+ delete parsedPackageJson.scripts[scriptName];
241
+ }
242
+ }
243
+
244
+ const tmpProjectDirPath = pathJoin(yarnHomeDirPath, "tmpProject");
245
+
246
+ if (fs.existsSync(tmpProjectDirPath)) {
247
+ rmSync(tmpProjectDirPath, { recursive: true });
248
+ }
249
+
250
+ fs.mkdirSync(tmpProjectDirPath, { recursive: true });
251
+
252
+ fs.writeFileSync(
253
+ pathJoin(tmpProjectDirPath, "package.json"),
254
+ JSON.stringify(parsedPackageJson, undefined, 4)
255
+ );
256
+
257
+ const YARN_LOCK = "yarn.lock";
258
+
259
+ fs.copyFileSync(
260
+ pathJoin(packageJsonDirPath, YARN_LOCK),
261
+ pathJoin(tmpProjectDirPath, YARN_LOCK)
262
+ );
263
+
264
+ child_process.execSync(`yarn install`, {
265
+ cwd: tmpProjectDirPath,
266
+ stdio: "inherit"
267
+ });
268
+
269
+ // NOTE: Moving the modules from the tmp project to the actual project
270
+ // without messing up the links.
271
+ {
272
+ const { getAreSameVersions } = (() => {
273
+ type ParsedPackageJson = {
274
+ version: string;
275
+ };
276
+
277
+ const zParsedPackageJson = (() => {
278
+ type TargetType = ParsedPackageJson;
279
+
280
+ const zTargetType = z.object({
281
+ version: z.string()
282
+ });
283
+
284
+ type InferredType = z.infer<typeof zTargetType>;
285
+
286
+ assert<Equals<TargetType, InferredType>>;
287
+
288
+ return id<z.ZodType<TargetType>>(zTargetType);
289
+ })();
290
+
291
+ function readVersion(params: { moduleDirPath: string }): string {
292
+ const { moduleDirPath } = params;
293
+
294
+ const packageJsonFilePath = pathJoin(moduleDirPath, "package.json");
295
+
296
+ const packageJson = JSON.parse(
297
+ fs.readFileSync(packageJsonFilePath).toString("utf8")
298
+ );
299
+
300
+ zParsedPackageJson.parse(packageJson);
301
+ assert(is<ParsedPackageJson>(packageJson));
302
+
303
+ return packageJson.version;
304
+ }
305
+
306
+ function getAreSameVersions(params: {
307
+ moduleDirPath_a: string;
308
+ moduleDirPath_b: string;
309
+ }): boolean {
310
+ const { moduleDirPath_a, moduleDirPath_b } = params;
311
+
312
+ return (
313
+ readVersion({ moduleDirPath: moduleDirPath_a }) ===
314
+ readVersion({ moduleDirPath: moduleDirPath_b })
315
+ );
316
+ }
317
+
318
+ return { getAreSameVersions };
319
+ })();
320
+
321
+ const nodeModulesDirPath_tmpProject = pathJoin(tmpProjectDirPath, "node_modules");
322
+ const nodeModulesDirPath = pathJoin(packageJsonDirPath, "node_modules");
323
+
324
+ const modulePaths = fs
325
+ .readdirSync(nodeModulesDirPath_tmpProject)
326
+ .map(basename => {
327
+ if (basename.startsWith(".")) {
328
+ return undefined;
329
+ }
330
+
331
+ const path = pathJoin(nodeModulesDirPath_tmpProject, basename);
332
+
333
+ if (basename.startsWith("@")) {
334
+ return fs
335
+ .readdirSync(path)
336
+ .map(subBasename => {
337
+ if (subBasename.startsWith(".")) {
338
+ return undefined;
339
+ }
340
+
341
+ const subPath = pathJoin(path, subBasename);
342
+
343
+ if (!fs.lstatSync(subPath).isDirectory()) {
344
+ return undefined;
345
+ }
346
+
347
+ return {
348
+ moduleName: `${basename}/${subBasename}`,
349
+ moduleDirPath_tmpProject: subPath,
350
+ moduleDirPath: pathJoin(
351
+ nodeModulesDirPath,
352
+ basename,
353
+ subBasename
354
+ )
355
+ };
356
+ })
357
+ .filter(exclude(undefined));
358
+ }
359
+
360
+ if (!fs.lstatSync(path).isDirectory()) {
361
+ return undefined;
362
+ }
363
+
364
+ return [
365
+ {
366
+ moduleName: basename,
367
+ moduleDirPath_tmpProject: path,
368
+ moduleDirPath: pathJoin(nodeModulesDirPath, basename)
369
+ }
370
+ ];
371
+ })
372
+ .filter(exclude(undefined))
373
+ .flat();
374
+
375
+ for (const {
376
+ moduleName,
377
+ moduleDirPath,
378
+ moduleDirPath_tmpProject
379
+ } of modulePaths) {
380
+ if (linkedModuleNames.includes(moduleName)) {
381
+ continue;
382
+ }
383
+
384
+ let doesTargetModuleExist = false;
385
+
386
+ skip_condition: {
387
+ if (!fs.existsSync(moduleDirPath)) {
388
+ break skip_condition;
389
+ }
390
+
391
+ doesTargetModuleExist = true;
392
+
393
+ const areSameVersions = getAreSameVersions({
394
+ moduleDirPath_a: moduleDirPath,
395
+ moduleDirPath_b: moduleDirPath_tmpProject
396
+ });
397
+
398
+ if (!areSameVersions) {
399
+ break skip_condition;
400
+ }
401
+
402
+ continue;
403
+ }
404
+
405
+ if (doesTargetModuleExist) {
406
+ rmSync(moduleDirPath, { recursive: true });
407
+ }
408
+
409
+ {
410
+ const dirPath = pathDirname(moduleDirPath);
411
+
412
+ if (!fs.existsSync(dirPath)) {
413
+ fs.mkdirSync(dirPath, { recursive: true });
414
+ }
415
+ }
416
+
417
+ fs.renameSync(moduleDirPath_tmpProject, moduleDirPath);
418
+ }
419
+
420
+ move_bin: {
421
+ const binDirPath_tmpProject = pathJoin(nodeModulesDirPath_tmpProject, ".bin");
422
+ const binDirPath = pathJoin(nodeModulesDirPath, ".bin");
423
+
424
+ if (!fs.existsSync(binDirPath_tmpProject)) {
425
+ break move_bin;
426
+ }
427
+
428
+ for (const basename of fs.readdirSync(binDirPath_tmpProject)) {
429
+ const path_tmpProject = pathJoin(binDirPath_tmpProject, basename);
430
+ const path = pathJoin(binDirPath, basename);
431
+
432
+ if (fs.existsSync(path)) {
433
+ continue;
434
+ }
435
+
436
+ fs.renameSync(path_tmpProject, path);
437
+ }
438
+ }
439
+ }
440
+
441
+ fs.cpSync(
442
+ pathJoin(tmpProjectDirPath, YARN_LOCK),
443
+ pathJoin(packageJsonDirPath, YARN_LOCK)
444
+ );
445
+
446
+ rmSync(tmpProjectDirPath, { recursive: true });
447
+
448
+ for (const scriptName of objectKeys(isImplementedScriptByName)) {
449
+ if (!isImplementedScriptByName[scriptName]) {
450
+ continue;
451
+ }
452
+
453
+ child_process.execSync(`yarn run ${scriptName}`, {
454
+ cwd: packageJsonDirPath,
455
+ stdio: "inherit"
456
+ });
457
+ }
458
+ }
@@ -1,9 +1,12 @@
1
1
  import { getNodeModulesBinDirPath } from "./nodeModulesBinDirPath";
2
- import { join as pathJoin } from "path";
2
+ import { join as pathJoin, resolve as pathResolve } from "path";
3
3
  import * as fsPr from "fs/promises";
4
4
  import { id } from "tsafe/id";
5
- import { assert } from "tsafe/assert";
5
+ import { assert, is } from "tsafe/assert";
6
6
  import chalk from "chalk";
7
+ import * as crypto from "crypto";
8
+ import { symToStr } from "tsafe/symToStr";
9
+ import { readThisNpmPackageVersion } from "./readThisNpmPackageVersion";
7
10
 
8
11
  getIsPrettierAvailable.cache = id<boolean | undefined>(undefined);
9
12
 
@@ -25,28 +28,60 @@ export async function getIsPrettierAvailable(): Promise<boolean> {
25
28
  return isPrettierAvailable;
26
29
  }
27
30
 
28
- type PrettierAndConfig = {
31
+ type PrettierAndConfigHash = {
29
32
  prettier: typeof import("prettier");
30
- config: import("prettier").Options | null;
33
+ configHash: string;
31
34
  };
32
35
 
33
- getPrettierAndConfig.cache = id<PrettierAndConfig | undefined>(undefined);
36
+ getPrettier.cache = id<PrettierAndConfigHash | undefined>(undefined);
34
37
 
35
- export async function getPrettierAndConfig(): Promise<PrettierAndConfig> {
38
+ export async function getPrettier(): Promise<PrettierAndConfigHash> {
36
39
  assert(getIsPrettierAvailable());
37
40
 
38
- if (getPrettierAndConfig.cache !== undefined) {
39
- return getPrettierAndConfig.cache;
41
+ if (getPrettier.cache !== undefined) {
42
+ return getPrettier.cache;
40
43
  }
41
44
 
42
- const prettier = await import("prettier");
45
+ let prettier = id<typeof import("prettier") | undefined>(undefined);
43
46
 
44
- const prettierAndConfig: PrettierAndConfig = {
47
+ import_prettier: {
48
+ // NOTE: When module is linked we want to make sure we import the correct version
49
+ // of prettier, that is the one of the project, not the one of this repo.
50
+ // So we do a sketchy eval to bypass ncc.
51
+ // We make sure to only do that when linking, otherwise we import properly.
52
+ if (readThisNpmPackageVersion().startsWith("0.0.0")) {
53
+ eval(
54
+ `${symToStr({ prettier })} = require("${pathResolve(pathJoin(getNodeModulesBinDirPath(), "..", "prettier"))}")`
55
+ );
56
+
57
+ assert(!is<undefined>(prettier));
58
+
59
+ break import_prettier;
60
+ }
61
+
62
+ prettier = await import("prettier");
63
+ }
64
+
65
+ const configHash = await (async () => {
66
+ const configFilePath = await prettier.resolveConfigFile(
67
+ pathJoin(getNodeModulesBinDirPath(), "..")
68
+ );
69
+
70
+ if (configFilePath === null) {
71
+ return "";
72
+ }
73
+
74
+ const data = await fsPr.readFile(configFilePath);
75
+
76
+ return crypto.createHash("sha256").update(data).digest("hex");
77
+ })();
78
+
79
+ const prettierAndConfig: PrettierAndConfigHash = {
45
80
  prettier,
46
- config: await prettier.resolveConfig(pathJoin(getNodeModulesBinDirPath(), ".."))
81
+ configHash
47
82
  };
48
83
 
49
- getPrettierAndConfig.cache = prettierAndConfig;
84
+ getPrettier.cache = prettierAndConfig;
50
85
 
51
86
  return prettierAndConfig;
52
87
  }
@@ -60,9 +95,23 @@ export async function runPrettier(params: {
60
95
  let formattedSourceCode: string;
61
96
 
62
97
  try {
63
- const { prettier, config } = await getPrettierAndConfig();
98
+ const { prettier } = await getPrettier();
99
+
100
+ const { ignored, inferredParser } = await prettier.getFileInfo(filePath, {
101
+ resolveConfig: true
102
+ });
103
+
104
+ if (ignored) {
105
+ return sourceCode;
106
+ }
107
+
108
+ const config = await prettier.resolveConfig(filePath);
64
109
 
65
- formattedSourceCode = await prettier.format(sourceCode, { ...config, filePath });
110
+ formattedSourceCode = await prettier.format(sourceCode, {
111
+ ...config,
112
+ filePath,
113
+ parser: inferredParser ?? undefined
114
+ });
66
115
  } catch (error) {
67
116
  console.log(
68
117
  chalk.red(
@@ -0,0 +1,24 @@
1
+ import * as child_process from "child_process";
2
+ import { dirname as pathDirname, basename as pathBasename } from "path";
3
+ import { Deferred } from "evt/tools/Deferred";
4
+
5
+ export async function untrackFromGit(params: { filePath: string }): Promise<void> {
6
+ const { filePath } = params;
7
+
8
+ const dDone = new Deferred<void>();
9
+
10
+ child_process.exec(
11
+ `git rm --cached ${pathBasename(filePath)}`,
12
+ { cwd: pathDirname(filePath) },
13
+ error => {
14
+ if (error !== null) {
15
+ dDone.reject(error);
16
+ return;
17
+ }
18
+
19
+ dDone.resolve();
20
+ }
21
+ );
22
+
23
+ await dDone.pr;
24
+ }
@@ -10,5 +10,5 @@
10
10
  "rootDir": "."
11
11
  },
12
12
  "include": ["**/*.ts", "**/*.tsx"],
13
- "exclude": ["initialize-account-theme/src", "initialize-admin-theme/src"]
13
+ "exclude": ["initialize-account-theme/src"]
14
14
  }
@@ -9,6 +9,16 @@ import { getIsPrettierAvailable, runPrettier } from "./tools/runPrettier";
9
9
  export async function command(params: { buildContext: BuildContext }) {
10
10
  const { buildContext } = params;
11
11
 
12
+ run_copy_assets_to_public: {
13
+ if (buildContext.bundler !== "webpack") {
14
+ break run_copy_assets_to_public;
15
+ }
16
+
17
+ const { command } = await import("./copy-keycloak-resources-to-public");
18
+
19
+ await command({ buildContext });
20
+ }
21
+
12
22
  const { hasBeenHandled } = maybeDelegateCommandToCustomHandler({
13
23
  commandName: "update-kc-gen",
14
24
  buildContext
@@ -18,7 +28,7 @@ export async function command(params: { buildContext: BuildContext }) {
18
28
  return;
19
29
  }
20
30
 
21
- const filePath = pathJoin(buildContext.themeSrcDirPath, "kc-gen.tsx");
31
+ const filePath = pathJoin(buildContext.themeSrcDirPath, "kc.gen.tsx");
22
32
 
23
33
  const hasLoginTheme = buildContext.implementedThemeTypes.login.isImplemented;
24
34
  const hasAccountTheme = buildContext.implementedThemeTypes.account.isImplemented;
@@ -52,7 +62,12 @@ export async function command(params: { buildContext: BuildContext }) {
52
62
  2
53
63
  )};`,
54
64
  ``,
55
- `type KcContext =`,
65
+ `/**`,
66
+ ` * NOTE: Do not import this type except maybe in your entrypoint. `,
67
+ ` * If you need to import the KcContext import it either from src/login/KcContext.ts or src/account/KcContext.ts.`,
68
+ ` * Depending on the theme type you are working on.`,
69
+ ` */`,
70
+ `export type KcContext =`,
56
71
  hasLoginTheme && ` | import("./login/KcContext").KcContext`,
57
72
  hasAccountTheme && ` | import("./account/KcContext").KcContext`,
58
73
  hasAdminTheme && ` | import("./admin/KcContext").KcContext`,
@@ -1,8 +1,7 @@
1
1
  import type { Param0 } from "tsafe";
2
2
  import { type CxArg, clsx_withTransform } from "../tools/clsx_withTransform";
3
3
  import { clsx } from "../tools/clsx";
4
- import { assert } from "tsafe/assert";
5
- import { is } from "tsafe/is";
4
+ import { assert, is } from "tsafe/assert";
6
5
 
7
6
  export function createGetKcClsx<ClassKey extends string>(params: {
8
7
  defaultClasses: Record<ClassKey, string | undefined>;
@@ -33,7 +33,7 @@ export type KcContext =
33
33
  | KcContext.LoginResetPassword
34
34
  | KcContext.LoginVerifyEmail
35
35
  | KcContext.Terms
36
- | KcContext.LoginDeviceVerifyUserCode
36
+ | KcContext.LoginOauth2DeviceVerifyUserCode
37
37
  | KcContext.LoginOauthGrant
38
38
  | KcContext.LoginOtp
39
39
  | KcContext.LoginUsername
@@ -277,7 +277,7 @@ export declare namespace KcContext {
277
277
  __localizationRealmOverridesTermsText?: string;
278
278
  };
279
279
 
280
- export type LoginDeviceVerifyUserCode = Common & {
280
+ export type LoginOauth2DeviceVerifyUserCode = Common & {
281
281
  pageId: "login-oauth2-device-verify-user-code.ftl";
282
282
  url: {
283
283
  oauth2DeviceVerificationAction: string;
@@ -290,7 +290,7 @@ export const kcContextMocks = [
290
290
  ...kcContextCommonMock,
291
291
  pageId: "terms.ftl"
292
292
  }),
293
- id<KcContext.LoginDeviceVerifyUserCode>({
293
+ id<KcContext.LoginOauth2DeviceVerifyUserCode>({
294
294
  ...kcContextCommonMock,
295
295
  pageId: "login-oauth2-device-verify-user-code.ftl",
296
296
  url: loginUrl
@@ -11,7 +11,6 @@ export type TemplateProps<KcContext, I18n> = {
11
11
  displayInfo?: boolean;
12
12
  displayMessage?: boolean;
13
13
  displayRequiredFields?: boolean;
14
- showAnotherWayIfPresent?: boolean;
15
14
  headerNode: ReactNode;
16
15
  socialProvidersNode?: ReactNode;
17
16
  infoNode?: ReactNode;
@@ -1,11 +1,11 @@
1
1
  import "keycloakify/tools/Object.fromEntries";
2
- import { assert } from "tsafe/assert";
2
+ import { assert, is } from "tsafe/assert";
3
+ import { extractLastParenthesisContent } from "keycloakify/tools/extractLastParenthesisContent";
3
4
  import messages_defaultSet_fallbackLanguage from "../messages_defaultSet/en";
4
5
  import { fetchMessages_defaultSet } from "../messages_defaultSet";
5
6
  import type { KcContext } from "../../KcContext";
6
7
  import { FALLBACK_LANGUAGE_TAG } from "keycloakify/bin/shared/constants";
7
8
  import { id } from "tsafe/id";
8
- import { is } from "tsafe/is";
9
9
  import { Reflect } from "tsafe/Reflect";
10
10
  import {
11
11
  type LanguageTag as LanguageTag_defaultSet,
@@ -169,12 +169,10 @@ export function createGetI18n<
169
169
  break from_server;
170
170
  }
171
171
 
172
- // cspell: disable-next-line
173
- // from "Espagnol (Español)" we want to extract "Español"
174
- const match = supportedEntry.label.match(/[^(]+\(([^)]+)\)/);
172
+ const lastParenthesisContent = extractLastParenthesisContent(supportedEntry.label);
175
173
 
176
- if (match !== null) {
177
- return match[1];
174
+ if (lastParenthesisContent !== undefined) {
175
+ return lastParenthesisContent;
178
176
  }
179
177
 
180
178
  return supportedEntry.label;