keycloakify 11.4.0-rc.0 → 11.4.1
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.
- package/README.md +2 -0
- package/account/i18n/noJsx/getI18n.js +5 -7
- package/account/i18n/noJsx/getI18n.js.map +1 -1
- package/account/i18n/withJsx/useI18n.js +15 -4
- package/account/i18n/withJsx/useI18n.js.map +1 -1
- package/bin/20.index.js +0 -85
- package/bin/33.index.js +55 -212
- package/bin/356.index.js +106 -45
- package/bin/36.index.js +1 -2922
- package/bin/{526.index.js → 392.index.js} +107 -3
- package/bin/40.index.js +1 -86
- package/bin/453.index.js +85 -22
- package/bin/573.index.js +5 -86
- package/bin/653.index.js +752 -0
- package/bin/658.index.js +197 -0
- package/bin/735.index.js +343 -116
- package/bin/786.index.js +78 -14
- package/bin/805.index.js +15 -18
- package/bin/921.index.js +79 -18
- package/bin/97.index.js +64 -13
- package/bin/main.js +165 -86
- package/bin/shared/constants.d.ts +2 -0
- package/bin/shared/constants.js +3 -1
- package/bin/shared/constants.js.map +1 -1
- package/bin/start-keycloak/startViteDevServer.d.ts +8 -0
- package/bin/tools/crawlAsync.d.ts +1 -1
- package/bin/tools/isTrackedByGit.d.ts +3 -0
- package/bin/tools/runPrettier.d.ts +5 -5
- package/bin/tools/untrackFromGit.d.ts +3 -0
- package/lib/getKcClsx.js +1 -2
- package/lib/getKcClsx.js.map +1 -1
- package/login/KcContext/KcContext.d.ts +2 -2
- package/login/KcContext/kcContextMocks.d.ts +1 -1
- package/login/TemplateProps.d.ts +0 -1
- package/login/i18n/noJsx/getI18n.js +5 -7
- package/login/i18n/noJsx/getI18n.js.map +1 -1
- package/login/i18n/withJsx/useI18n.js +15 -4
- package/login/i18n/withJsx/useI18n.js.map +1 -1
- package/login/pages/LoginConfigTotp.js +1 -1
- package/login/pages/LoginConfigTotp.js.map +1 -1
- package/login/pages/LoginPasskeysConditionalAuthenticate.js +16 -18
- package/login/pages/LoginPasskeysConditionalAuthenticate.js.map +1 -1
- package/package.json +17 -7
- package/src/account/i18n/noJsx/getI18n.tsx +5 -7
- package/src/account/i18n/withJsx/useI18n.tsx +18 -4
- package/src/bin/eject-page.ts +28 -10
- package/src/bin/initialize-account-theme/initializeAccountTheme_singlePage.ts +3 -18
- package/src/bin/initialize-account-theme/updateAccountThemeImplementationInConfig.ts +1 -2
- package/src/bin/keycloakify/generateFtl/generateFtl.ts +6 -1
- package/src/bin/keycloakify/generateFtl/kcContextDeclarationTemplate.ftl +39 -0
- package/src/bin/keycloakify/generateResources/generateResources.ts +6 -2
- package/src/bin/main.ts +51 -4
- package/src/bin/postinstall/getUiModuleFileSourceCodeReadyToBeCopied.ts +30 -19
- package/src/bin/postinstall/installUiModulesPeerDependencies.ts +3 -3
- package/src/bin/postinstall/managedGitignoreFile.ts +4 -3
- package/src/bin/postinstall/postinstall.ts +24 -2
- package/src/bin/postinstall/uiModuleMeta.ts +14 -9
- package/src/bin/shared/buildContext.ts +1 -2
- package/src/bin/shared/constants.ts +4 -1
- package/src/bin/start-keycloak/myrealm-realm-25.json +21 -34
- package/src/bin/start-keycloak/myrealm-realm-26.json +32 -35
- package/src/bin/start-keycloak/start-keycloak.ts +94 -1
- package/src/bin/start-keycloak/startViteDevServer.ts +66 -0
- package/src/bin/tools/crawlAsync.ts +6 -6
- package/src/bin/tools/isTrackedByGit.ts +29 -0
- package/src/bin/tools/listInstalledModules.ts +1 -2
- package/src/bin/tools/npmInstall.ts +396 -1
- package/src/bin/tools/runPrettier.ts +63 -14
- package/src/bin/tools/untrackFromGit.ts +24 -0
- package/src/bin/tsconfig.json +1 -1
- package/src/bin/update-kc-gen.ts +17 -2
- package/src/lib/getKcClsx.ts +1 -2
- package/src/login/KcContext/KcContext.ts +2 -2
- package/src/login/KcContext/kcContextMocks.ts +1 -1
- package/src/login/TemplateProps.ts +0 -1
- package/src/login/i18n/noJsx/getI18n.tsx +5 -7
- package/src/login/i18n/withJsx/useI18n.tsx +18 -4
- package/src/login/pages/LoginConfigTotp.tsx +18 -20
- package/src/login/pages/LoginPasskeysConditionalAuthenticate.tsx +51 -52
- package/src/tools/StatefulObservable/StatefulObservable.ts +1 -2
- package/src/tools/deepAssign.ts +1 -2
- package/src/tools/extractLastParenthesisContent.ts +43 -0
- package/src/vite-plugin/vite-plugin.ts +67 -0
- package/stories/login/pages/Info.stories.tsx +3 -39
- package/tools/StatefulObservable/StatefulObservable.js +1 -2
- package/tools/StatefulObservable/StatefulObservable.js.map +1 -1
- package/tools/deepAssign.js +1 -2
- package/tools/deepAssign.js.map +1 -1
- package/tools/extractLastParenthesisContent.d.ts +6 -0
- package/tools/extractLastParenthesisContent.js +36 -0
- package/tools/extractLastParenthesisContent.js.map +1 -0
- package/vite-plugin/index.js +326 -186
- package/bin/124.index.js +0 -348
- 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
|
31
|
+
type PrettierAndConfigHash = {
|
29
32
|
prettier: typeof import("prettier");
|
30
|
-
|
33
|
+
configHash: string;
|
31
34
|
};
|
32
35
|
|
33
|
-
|
36
|
+
getPrettier.cache = id<PrettierAndConfigHash | undefined>(undefined);
|
34
37
|
|
35
|
-
export async function
|
38
|
+
export async function getPrettier(): Promise<PrettierAndConfigHash> {
|
36
39
|
assert(getIsPrettierAvailable());
|
37
40
|
|
38
|
-
if (
|
39
|
-
return
|
41
|
+
if (getPrettier.cache !== undefined) {
|
42
|
+
return getPrettier.cache;
|
40
43
|
}
|
41
44
|
|
42
|
-
|
45
|
+
let prettier = id<typeof import("prettier") | undefined>(undefined);
|
43
46
|
|
44
|
-
|
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
|
-
|
81
|
+
configHash
|
47
82
|
};
|
48
83
|
|
49
|
-
|
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
|
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, {
|
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
|
+
}
|
package/src/bin/tsconfig.json
CHANGED
package/src/bin/update-kc-gen.ts
CHANGED
@@ -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
|
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
|
-
|
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`,
|
package/src/lib/getKcClsx.ts
CHANGED
@@ -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.
|
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
|
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.
|
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
|
-
|
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 (
|
177
|
-
return
|
174
|
+
if (lastParenthesisContent !== undefined) {
|
175
|
+
return lastParenthesisContent;
|
178
176
|
}
|
179
177
|
|
180
178
|
return supportedEntry.label;
|