keycloakify 9.4.0-rc.9 → 9.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 +4 -0
- package/account/i18n/baseMessages/index.d.ts +358 -0
- package/account/i18n/baseMessages/index.js +2 -1
- package/account/i18n/baseMessages/index.js.map +1 -1
- package/account/pages/PageProps.d.ts +3 -2
- package/bin/constants.d.ts +1 -1
- package/bin/constants.js +1 -1
- package/bin/constants.js.map +1 -1
- package/bin/copy-keycloak-resources-to-public.d.ts +13 -1
- package/bin/copy-keycloak-resources-to-public.js +134 -68
- package/bin/copy-keycloak-resources-to-public.js.map +1 -1
- package/bin/download-builtin-keycloak-theme.d.ts +1 -0
- package/bin/download-builtin-keycloak-theme.js +2 -3
- package/bin/download-builtin-keycloak-theme.js.map +1 -1
- package/bin/{tools/downloadAndUnzip.d.ts → downloadAndUnzip.d.ts} +6 -6
- package/bin/downloadAndUnzip.js +255 -0
- package/bin/downloadAndUnzip.js.map +1 -0
- package/bin/eject-keycloak-page.js +6 -3
- package/bin/eject-keycloak-page.js.map +1 -1
- package/bin/keycloakify/buildOptions/buildOptions.d.ts +1 -0
- package/bin/keycloakify/buildOptions/buildOptions.js +54 -39
- package/bin/keycloakify/buildOptions/buildOptions.js.map +1 -1
- package/bin/keycloakify/buildOptions/getCacheDirPath.d.ts +5 -0
- package/bin/keycloakify/buildOptions/getCacheDirPath.js +22 -0
- package/bin/keycloakify/buildOptions/getCacheDirPath.js.map +1 -0
- package/bin/keycloakify/buildOptions/getNpmWorkspaceRootDirPath.d.ts +5 -0
- package/bin/keycloakify/buildOptions/getNpmWorkspaceRootDirPath.js +86 -0
- package/bin/keycloakify/buildOptions/getNpmWorkspaceRootDirPath.js.map +1 -0
- package/bin/keycloakify/buildOptions/getReactAppRootDirPath.d.ts +5 -0
- package/bin/keycloakify/buildOptions/getReactAppRootDirPath.js +26 -0
- package/bin/keycloakify/buildOptions/getReactAppRootDirPath.js.map +1 -0
- package/bin/keycloakify/buildOptions/resolvedViteConfig.d.ts +3 -4
- package/bin/keycloakify/buildOptions/resolvedViteConfig.js +4 -11
- package/bin/keycloakify/buildOptions/resolvedViteConfig.js.map +1 -1
- package/bin/keycloakify/generateTheme/bringInAccountV1.d.ts +1 -0
- package/bin/keycloakify/generateTheme/bringInAccountV1.js.map +1 -1
- package/bin/keycloakify/generateTheme/downloadKeycloakStaticResources.d.ts +1 -0
- package/bin/keycloakify/generateTheme/downloadKeycloakStaticResources.js.map +1 -1
- package/bin/keycloakify/generateTheme/generateTheme.d.ts +1 -0
- package/bin/keycloakify/generateTheme/generateTheme.js +7 -3
- package/bin/keycloakify/generateTheme/generateTheme.js.map +1 -1
- package/bin/keycloakify/keycloakify.js +8 -12
- package/bin/keycloakify/keycloakify.js.map +1 -1
- package/bin/tools/fetchProxyOptions.d.ts +5 -0
- package/bin/tools/fetchProxyOptions.js +172 -0
- package/bin/tools/fetchProxyOptions.js.map +1 -0
- package/bin/tools/fs.existsAsync.d.ts +1 -0
- package/bin/tools/fs.existsAsync.js +86 -0
- package/bin/tools/fs.existsAsync.js.map +1 -0
- package/bin/tools/getThisCodebaseRootDirPath.d.ts +1 -0
- package/bin/tools/{getProjectRoot.js → getThisCodebaseRootDirPath.js} +7 -7
- package/bin/tools/getThisCodebaseRootDirPath.js.map +1 -0
- package/bin/tools/grant-exec-perms.js +6 -4
- package/bin/tools/grant-exec-perms.js.map +1 -1
- package/bin/tools/readThisNpmProjectVersion.d.ts +1 -0
- package/bin/tools/readThisNpmProjectVersion.js +37 -0
- package/bin/tools/readThisNpmProjectVersion.js.map +1 -0
- package/lib/isStorybook.js +1 -2
- package/lib/isStorybook.js.map +1 -1
- package/login/i18n/baseMessages/index.d.ts +458 -0
- package/login/i18n/baseMessages/index.js +2 -1
- package/login/i18n/baseMessages/index.js.map +1 -1
- package/login/pages/PageProps.d.ts +3 -2
- package/package.json +41 -19
- package/src/account/i18n/baseMessages/index.ts +2 -1
- package/src/account/pages/PageProps.ts +3 -2
- package/src/bin/constants.ts +1 -1
- package/src/bin/copy-keycloak-resources-to-public.ts +75 -9
- package/src/bin/download-builtin-keycloak-theme.ts +3 -3
- package/src/bin/downloadAndUnzip.ts +203 -0
- package/src/bin/eject-keycloak-page.ts +6 -3
- package/src/bin/keycloakify/buildOptions/buildOptions.ts +28 -39
- package/src/bin/keycloakify/buildOptions/getCacheDirPath.ts +25 -0
- package/src/bin/keycloakify/buildOptions/getNpmWorkspaceRootDirPath.ts +49 -0
- package/src/bin/keycloakify/buildOptions/getReactAppRootDirPath.ts +23 -0
- package/src/bin/keycloakify/buildOptions/resolvedViteConfig.ts +7 -21
- package/src/bin/keycloakify/generateTheme/bringInAccountV1.ts +1 -0
- package/src/bin/keycloakify/generateTheme/downloadKeycloakStaticResources.ts +1 -0
- package/src/bin/keycloakify/generateTheme/generateTheme.ts +9 -2
- package/src/bin/keycloakify/keycloakify.ts +8 -14
- package/src/bin/tools/fetchProxyOptions.ts +73 -0
- package/src/bin/tools/fs.existsAsync.ts +11 -0
- package/src/bin/tools/{getProjectRoot.ts → getThisCodebaseRootDirPath.ts} +4 -4
- package/src/bin/tools/grant-exec-perms.ts +5 -3
- package/src/bin/tools/readThisNpmProjectVersion.ts +12 -0
- package/src/lib/isStorybook.ts +1 -3
- package/src/login/i18n/baseMessages/index.ts +2 -1
- package/src/login/pages/PageProps.ts +3 -2
- package/src/vite-plugin/vite-plugin.ts +48 -25
- package/vite-plugin/tsconfig.tsbuildinfo +1 -1
- package/vite-plugin/vite-plugin.d.ts +1 -2
- package/vite-plugin/vite-plugin.js +35 -20
- package/vite-plugin/vite-plugin.js.map +1 -1
- package/bin/keycloakify/buildOptions/getKeycloakifyBuildDirPath.d.ts +0 -7
- package/bin/keycloakify/buildOptions/getKeycloakifyBuildDirPath.js +0 -27
- package/bin/keycloakify/buildOptions/getKeycloakifyBuildDirPath.js.map +0 -1
- package/bin/tools/downloadAndUnzip.js +0 -445
- package/bin/tools/downloadAndUnzip.js.map +0 -1
- package/bin/tools/getProjectRoot.d.ts +0 -1
- package/bin/tools/getProjectRoot.js.map +0 -1
- package/src/bin/keycloakify/buildOptions/getKeycloakifyBuildDirPath.ts +0 -33
- package/src/bin/tools/downloadAndUnzip.ts +0 -301
- package/src/vite-plugin/config.json +0 -232
@@ -1,16 +1,17 @@
|
|
1
1
|
//This code was automatically generated by running scripts/generate-i18n-messages.ts
|
2
2
|
//PLEASE DO NOT EDIT MANUALLY
|
3
|
+
import * as en from "./en";
|
3
4
|
|
4
5
|
export async function getMessages(currentLanguageTag: string) {
|
5
6
|
const { default: messages } = await (() => {
|
6
7
|
switch (currentLanguageTag) {
|
8
|
+
case "en": return en;
|
7
9
|
case "ar": return import("./ar");
|
8
10
|
case "ca": return import("./ca");
|
9
11
|
case "cs": return import("./cs");
|
10
12
|
case "da": return import("./da");
|
11
13
|
case "de": return import("./de");
|
12
14
|
case "el": return import("./el");
|
13
|
-
case "en": return import("./en");
|
14
15
|
case "es": return import("./es");
|
15
16
|
case "fa": return import("./fa");
|
16
17
|
case "fi": return import("./fi");
|
@@ -1,10 +1,11 @@
|
|
1
1
|
import type { I18n } from "keycloakify/account/i18n";
|
2
2
|
import type { TemplateProps, ClassKey } from "keycloakify/account/TemplateProps";
|
3
3
|
import type { LazyOrNot } from "keycloakify/tools/LazyOrNot";
|
4
|
+
import type { KcContext } from "keycloakify/account/kcContext";
|
4
5
|
|
5
|
-
export type PageProps<KcContext, I18nExtended extends I18n> = {
|
6
|
+
export type PageProps<NarowedKcContext = KcContext, I18nExtended extends I18n = I18n> = {
|
6
7
|
Template: LazyOrNot<(props: TemplateProps<any, any>) => JSX.Element | null>;
|
7
|
-
kcContext:
|
8
|
+
kcContext: NarowedKcContext;
|
8
9
|
i18n: I18nExtended;
|
9
10
|
doUseDefaultCss: boolean;
|
10
11
|
classes?: Partial<Record<ClassKey, string>>;
|
package/src/bin/constants.ts
CHANGED
@@ -2,7 +2,7 @@ export const nameOfTheGlobal = "kcContext";
|
|
2
2
|
export const keycloak_resources = "keycloak-resources";
|
3
3
|
export const resources_common = "resources-common";
|
4
4
|
export const lastKeycloakVersionWithAccountV1 = "21.1.2";
|
5
|
-
export const resolvedViteConfigJsonBasename = ".
|
5
|
+
export const resolvedViteConfigJsonBasename = "vite.json";
|
6
6
|
export const basenameOfTheKeycloakifyResourcesDir = "build";
|
7
7
|
|
8
8
|
export const themeTypes = ["login", "account"] as const;
|
@@ -1,17 +1,44 @@
|
|
1
1
|
#!/usr/bin/env node
|
2
2
|
|
3
|
-
import { downloadKeycloakStaticResources } from "./keycloakify/generateTheme/downloadKeycloakStaticResources";
|
3
|
+
import { downloadKeycloakStaticResources, type BuildOptionsLike } from "./keycloakify/generateTheme/downloadKeycloakStaticResources";
|
4
4
|
import { join as pathJoin, relative as pathRelative } from "path";
|
5
5
|
import { readBuildOptions } from "./keycloakify/buildOptions";
|
6
6
|
import { themeTypes, keycloak_resources, lastKeycloakVersionWithAccountV1 } from "./constants";
|
7
|
+
import { readThisNpmProjectVersion } from "./tools/readThisNpmProjectVersion";
|
8
|
+
import { assert, type Equals } from "tsafe/assert";
|
7
9
|
import * as fs from "fs";
|
10
|
+
import { rmSync } from "./tools/fs.rmSync";
|
8
11
|
|
9
|
-
|
10
|
-
const
|
11
|
-
|
12
|
+
export async function copyKeycloakResourcesToPublic(params: { processArgv: string[] }) {
|
13
|
+
const { processArgv } = params;
|
14
|
+
|
15
|
+
const buildOptions = readBuildOptions({ processArgv });
|
16
|
+
|
17
|
+
const destDirPath = pathJoin(buildOptions.publicDirPath, keycloak_resources);
|
18
|
+
|
19
|
+
const keycloakifyBuildinfoFilePath = pathJoin(destDirPath, "keycloakify.buildinfo");
|
20
|
+
|
21
|
+
const { keycloakifyBuildinfoRaw } = generateKeycloakifyBuildinfoRaw({
|
22
|
+
destDirPath,
|
23
|
+
"keycloakifyVersion": readThisNpmProjectVersion(),
|
24
|
+
buildOptions
|
12
25
|
});
|
13
26
|
|
14
|
-
|
27
|
+
skip_if_already_done: {
|
28
|
+
if (!fs.existsSync(keycloakifyBuildinfoFilePath)) {
|
29
|
+
break skip_if_already_done;
|
30
|
+
}
|
31
|
+
|
32
|
+
const keycloakifyBuildinfoRaw_previousRun = fs.readFileSync(keycloakifyBuildinfoFilePath).toString("utf8");
|
33
|
+
|
34
|
+
if (keycloakifyBuildinfoRaw_previousRun !== keycloakifyBuildinfoRaw) {
|
35
|
+
break skip_if_already_done;
|
36
|
+
}
|
37
|
+
|
38
|
+
return;
|
39
|
+
}
|
40
|
+
|
41
|
+
rmSync(destDirPath, { "force": true, "recursive": true });
|
15
42
|
|
16
43
|
for (const themeType of themeTypes) {
|
17
44
|
await downloadKeycloakStaticResources({
|
@@ -24,13 +51,13 @@ import * as fs from "fs";
|
|
24
51
|
}
|
25
52
|
})(),
|
26
53
|
themeType,
|
27
|
-
"themeDirPath":
|
54
|
+
"themeDirPath": destDirPath,
|
28
55
|
buildOptions
|
29
56
|
});
|
30
57
|
}
|
31
58
|
|
32
59
|
fs.writeFileSync(
|
33
|
-
pathJoin(
|
60
|
+
pathJoin(destDirPath, "README.txt"),
|
34
61
|
Buffer.from(
|
35
62
|
// prettier-ignore
|
36
63
|
[
|
@@ -42,5 +69,44 @@ import * as fs from "fs";
|
|
42
69
|
|
43
70
|
fs.writeFileSync(pathJoin(buildOptions.publicDirPath, keycloak_resources, ".gitignore"), Buffer.from("*", "utf8"));
|
44
71
|
|
45
|
-
|
46
|
-
}
|
72
|
+
fs.writeFileSync(keycloakifyBuildinfoFilePath, Buffer.from(keycloakifyBuildinfoRaw, "utf8"));
|
73
|
+
}
|
74
|
+
|
75
|
+
export function generateKeycloakifyBuildinfoRaw(params: {
|
76
|
+
destDirPath: string;
|
77
|
+
keycloakifyVersion: string;
|
78
|
+
buildOptions: BuildOptionsLike & {
|
79
|
+
loginThemeResourcesFromKeycloakVersion: string;
|
80
|
+
};
|
81
|
+
}) {
|
82
|
+
const { destDirPath, keycloakifyVersion, buildOptions } = params;
|
83
|
+
|
84
|
+
const { cacheDirPath, npmWorkspaceRootDirPath, loginThemeResourcesFromKeycloakVersion, ...rest } = buildOptions;
|
85
|
+
|
86
|
+
assert<Equals<typeof rest, {}>>(true);
|
87
|
+
|
88
|
+
const keycloakifyBuildinfoRaw = JSON.stringify(
|
89
|
+
{
|
90
|
+
keycloakifyVersion,
|
91
|
+
"buildOptions": {
|
92
|
+
loginThemeResourcesFromKeycloakVersion,
|
93
|
+
"cacheDirPath": pathRelative(destDirPath, cacheDirPath),
|
94
|
+
"npmWorkspaceRootDirPath": pathRelative(destDirPath, npmWorkspaceRootDirPath)
|
95
|
+
}
|
96
|
+
},
|
97
|
+
null,
|
98
|
+
2
|
99
|
+
);
|
100
|
+
|
101
|
+
return { keycloakifyBuildinfoRaw };
|
102
|
+
}
|
103
|
+
|
104
|
+
async function main() {
|
105
|
+
await copyKeycloakResourcesToPublic({
|
106
|
+
"processArgv": process.argv.slice(2)
|
107
|
+
});
|
108
|
+
}
|
109
|
+
|
110
|
+
if (require.main === module) {
|
111
|
+
main();
|
112
|
+
}
|
@@ -1,6 +1,6 @@
|
|
1
1
|
#!/usr/bin/env node
|
2
2
|
import { join as pathJoin } from "path";
|
3
|
-
import { downloadAndUnzip } from "./
|
3
|
+
import { downloadAndUnzip } from "./downloadAndUnzip";
|
4
4
|
import { promptKeycloakVersion } from "./promptKeycloakVersion";
|
5
5
|
import { getLogger } from "./tools/logger";
|
6
6
|
import { readBuildOptions, type BuildOptions } from "./keycloakify/buildOptions";
|
@@ -13,6 +13,7 @@ import { transformCodebase } from "./tools/transformCodebase";
|
|
13
13
|
|
14
14
|
export type BuildOptionsLike = {
|
15
15
|
cacheDirPath: string;
|
16
|
+
npmWorkspaceRootDirPath: string;
|
16
17
|
};
|
17
18
|
|
18
19
|
assert<BuildOptions extends BuildOptionsLike ? true : false>();
|
@@ -21,11 +22,10 @@ export async function downloadBuiltinKeycloakTheme(params: { keycloakVersion: st
|
|
21
22
|
const { keycloakVersion, destDirPath, buildOptions } = params;
|
22
23
|
|
23
24
|
await downloadAndUnzip({
|
24
|
-
"doUseCache": true,
|
25
|
-
"cacheDirPath": buildOptions.cacheDirPath,
|
26
25
|
destDirPath,
|
27
26
|
"url": `https://github.com/keycloak/keycloak/archive/refs/tags/${keycloakVersion}.zip`,
|
28
27
|
"specificDirsToExtract": ["", "-community"].map(ext => `keycloak-${keycloakVersion}/themes/src/main/resources${ext}/theme`),
|
28
|
+
buildOptions,
|
29
29
|
"preCacheTransform": {
|
30
30
|
"actionCacheId": "npm install and build",
|
31
31
|
"action": async ({ destDirPath }) => {
|
@@ -0,0 +1,203 @@
|
|
1
|
+
import { createHash } from "crypto";
|
2
|
+
import { mkdir, writeFile, unlink } from "fs/promises";
|
3
|
+
import fetch from "make-fetch-happen";
|
4
|
+
import { dirname as pathDirname, join as pathJoin, basename as pathBasename } from "path";
|
5
|
+
import { assert } from "tsafe/assert";
|
6
|
+
import { transformCodebase } from "./tools/transformCodebase";
|
7
|
+
import { unzip, zip } from "./tools/unzip";
|
8
|
+
import { rm } from "./tools/fs.rm";
|
9
|
+
import * as child_process from "child_process";
|
10
|
+
import { existsAsync } from "./tools/fs.existsAsync";
|
11
|
+
import type { BuildOptions } from "./keycloakify/buildOptions";
|
12
|
+
import { getProxyFetchOptions } from "./tools/fetchProxyOptions";
|
13
|
+
|
14
|
+
export type BuildOptionsLike = {
|
15
|
+
cacheDirPath: string;
|
16
|
+
npmWorkspaceRootDirPath: string;
|
17
|
+
};
|
18
|
+
|
19
|
+
assert<BuildOptions extends BuildOptionsLike ? true : false>();
|
20
|
+
|
21
|
+
export async function downloadAndUnzip(params: {
|
22
|
+
url: string;
|
23
|
+
destDirPath: string;
|
24
|
+
specificDirsToExtract?: string[];
|
25
|
+
preCacheTransform?: {
|
26
|
+
actionCacheId: string;
|
27
|
+
action: (params: { destDirPath: string }) => Promise<void>;
|
28
|
+
};
|
29
|
+
buildOptions: BuildOptionsLike;
|
30
|
+
}) {
|
31
|
+
const { url, destDirPath, specificDirsToExtract, preCacheTransform, buildOptions } = params;
|
32
|
+
|
33
|
+
const { extractDirPath, zipFilePath } = (() => {
|
34
|
+
const zipFileBasenameWithoutExt = generateFileNameFromURL({
|
35
|
+
url,
|
36
|
+
"preCacheTransform":
|
37
|
+
preCacheTransform === undefined
|
38
|
+
? undefined
|
39
|
+
: {
|
40
|
+
"actionCacheId": preCacheTransform.actionCacheId,
|
41
|
+
"actionFootprint": preCacheTransform.action.toString()
|
42
|
+
}
|
43
|
+
});
|
44
|
+
|
45
|
+
const zipFilePath = pathJoin(buildOptions.cacheDirPath, `${zipFileBasenameWithoutExt}.zip`);
|
46
|
+
const extractDirPath = pathJoin(buildOptions.cacheDirPath, `tmp_unzip_${zipFileBasenameWithoutExt}`);
|
47
|
+
|
48
|
+
return { zipFilePath, extractDirPath };
|
49
|
+
})();
|
50
|
+
|
51
|
+
download_zip_and_transform: {
|
52
|
+
if (await existsAsync(zipFilePath)) {
|
53
|
+
break download_zip_and_transform;
|
54
|
+
}
|
55
|
+
|
56
|
+
const { response, isFromRemoteCache } = await (async () => {
|
57
|
+
const proxyFetchOptions = await getProxyFetchOptions({
|
58
|
+
"npmWorkspaceRootDirPath": buildOptions.npmWorkspaceRootDirPath
|
59
|
+
});
|
60
|
+
|
61
|
+
const response = await fetch(
|
62
|
+
`https://github.com/keycloakify/keycloakify/releases/download/v0.0.1/${pathBasename(zipFilePath)}`,
|
63
|
+
proxyFetchOptions
|
64
|
+
);
|
65
|
+
|
66
|
+
if (response.status === 200) {
|
67
|
+
return {
|
68
|
+
response,
|
69
|
+
"isFromRemoteCache": true
|
70
|
+
};
|
71
|
+
}
|
72
|
+
|
73
|
+
return {
|
74
|
+
"response": await fetch(url, proxyFetchOptions),
|
75
|
+
"isFromRemoteCache": false
|
76
|
+
};
|
77
|
+
})();
|
78
|
+
|
79
|
+
await mkdir(pathDirname(zipFilePath), { "recursive": true });
|
80
|
+
|
81
|
+
/**
|
82
|
+
* The correct way to fix this is to upgrade node-fetch beyond 3.2.5
|
83
|
+
* (see https://github.com/node-fetch/node-fetch/issues/1295#issuecomment-1144061991.)
|
84
|
+
* Unfortunately, octokit (a dependency of keycloakify) also uses node-fetch, and
|
85
|
+
* does not support node-fetch 3.x. So we stick around with this band-aid until
|
86
|
+
* octokit upgrades.
|
87
|
+
*/
|
88
|
+
response.body?.setMaxListeners(Number.MAX_VALUE);
|
89
|
+
assert(typeof response.body !== "undefined" && response.body != null);
|
90
|
+
|
91
|
+
await writeFile(zipFilePath, response.body);
|
92
|
+
|
93
|
+
if (isFromRemoteCache) {
|
94
|
+
break download_zip_and_transform;
|
95
|
+
}
|
96
|
+
|
97
|
+
if (specificDirsToExtract === undefined && preCacheTransform === undefined) {
|
98
|
+
break download_zip_and_transform;
|
99
|
+
}
|
100
|
+
|
101
|
+
await unzip(zipFilePath, extractDirPath, specificDirsToExtract);
|
102
|
+
|
103
|
+
try {
|
104
|
+
await preCacheTransform?.action({
|
105
|
+
"destDirPath": extractDirPath
|
106
|
+
});
|
107
|
+
} catch (error) {
|
108
|
+
await Promise.all([rm(extractDirPath, { "recursive": true }), unlink(zipFilePath)]);
|
109
|
+
|
110
|
+
throw error;
|
111
|
+
}
|
112
|
+
|
113
|
+
await unlink(zipFilePath);
|
114
|
+
|
115
|
+
await zip(extractDirPath, zipFilePath);
|
116
|
+
|
117
|
+
await rm(extractDirPath, { "recursive": true });
|
118
|
+
|
119
|
+
upload_to_remot_cache_if_admin: {
|
120
|
+
const githubToken = process.env["KEYCLOAKIFY_ADMIN_GITHUB_PERSONAL_ACCESS_TOKEN"];
|
121
|
+
|
122
|
+
if (githubToken === undefined) {
|
123
|
+
break upload_to_remot_cache_if_admin;
|
124
|
+
}
|
125
|
+
|
126
|
+
console.log("uploading to remote cache");
|
127
|
+
|
128
|
+
try {
|
129
|
+
child_process.execSync(`which putasset`);
|
130
|
+
} catch {
|
131
|
+
child_process.execSync(`npm install -g putasset`);
|
132
|
+
}
|
133
|
+
|
134
|
+
try {
|
135
|
+
child_process.execFileSync("putasset", [
|
136
|
+
"--owner",
|
137
|
+
"keycloakify",
|
138
|
+
"--repo",
|
139
|
+
"keycloakify",
|
140
|
+
"--tag",
|
141
|
+
"v0.0.1",
|
142
|
+
"--filename",
|
143
|
+
zipFilePath,
|
144
|
+
"--token",
|
145
|
+
githubToken
|
146
|
+
]);
|
147
|
+
} catch {
|
148
|
+
console.log("upload failed, asset probably already exists in remote cache");
|
149
|
+
}
|
150
|
+
}
|
151
|
+
}
|
152
|
+
|
153
|
+
await unzip(zipFilePath, extractDirPath);
|
154
|
+
|
155
|
+
transformCodebase({
|
156
|
+
"srcDirPath": extractDirPath,
|
157
|
+
"destDirPath": destDirPath
|
158
|
+
});
|
159
|
+
|
160
|
+
await rm(extractDirPath, { "recursive": true });
|
161
|
+
}
|
162
|
+
|
163
|
+
function generateFileNameFromURL(params: {
|
164
|
+
url: string;
|
165
|
+
preCacheTransform:
|
166
|
+
| {
|
167
|
+
actionCacheId: string;
|
168
|
+
actionFootprint: string;
|
169
|
+
}
|
170
|
+
| undefined;
|
171
|
+
}): string {
|
172
|
+
const { preCacheTransform } = params;
|
173
|
+
|
174
|
+
// Parse the URL
|
175
|
+
const url = new URL(params.url);
|
176
|
+
|
177
|
+
// Extract pathname and remove leading slashes
|
178
|
+
let fileName = url.pathname.replace(/^\//, "").replace(/\//g, "_");
|
179
|
+
|
180
|
+
// Optionally, add query parameters replacing special characters
|
181
|
+
if (url.search) {
|
182
|
+
fileName += url.search.replace(/[&=?]/g, "-");
|
183
|
+
}
|
184
|
+
|
185
|
+
// Replace any characters that are not valid in filenames
|
186
|
+
fileName = fileName.replace(/[^a-zA-Z0-9-_]/g, "");
|
187
|
+
|
188
|
+
// Trim or pad the fileName to a specific length
|
189
|
+
fileName = fileName.substring(0, 50);
|
190
|
+
|
191
|
+
add_pre_cache_transform: {
|
192
|
+
if (preCacheTransform === undefined) {
|
193
|
+
break add_pre_cache_transform;
|
194
|
+
}
|
195
|
+
|
196
|
+
// Sanitize actionCacheId the same way as other components
|
197
|
+
const sanitizedActionCacheId = preCacheTransform.actionCacheId.replace(/[^a-zA-Z0-9-_]/g, "_");
|
198
|
+
|
199
|
+
fileName += `_${sanitizedActionCacheId}_${createHash("sha256").update(preCacheTransform.actionFootprint).digest("hex").substring(0, 5)}`;
|
200
|
+
}
|
201
|
+
|
202
|
+
return fileName;
|
203
|
+
}
|
@@ -1,6 +1,6 @@
|
|
1
1
|
#!/usr/bin/env node
|
2
2
|
|
3
|
-
import {
|
3
|
+
import { getThisCodebaseRootDirPath } from "./tools/getThisCodebaseRootDirPath";
|
4
4
|
import cliSelect from "cli-select";
|
5
5
|
import { loginThemePageIds, accountThemePageIds, type LoginThemePageId, type AccountThemePageId } from "./keycloakify/generateFtl";
|
6
6
|
import { capitalize } from "tsafe/capitalize";
|
@@ -11,11 +11,14 @@ import { kebabCaseToCamelCase } from "./tools/kebabCaseToSnakeCase";
|
|
11
11
|
import { assert, Equals } from "tsafe/assert";
|
12
12
|
import { getThemeSrcDirPath } from "./getThemeSrcDirPath";
|
13
13
|
import { themeTypes, type ThemeType } from "./constants";
|
14
|
+
import { getReactAppRootDirPath } from "./keycloakify/buildOptions/getReactAppRootDirPath";
|
14
15
|
|
15
16
|
(async () => {
|
16
17
|
console.log("Select a theme type");
|
17
18
|
|
18
|
-
const reactAppRootDirPath =
|
19
|
+
const { reactAppRootDirPath } = getReactAppRootDirPath({
|
20
|
+
"processArgv": process.argv.slice(2)
|
21
|
+
});
|
19
22
|
|
20
23
|
const { value: themeType } = await cliSelect<ThemeType>({
|
21
24
|
"values": [...themeTypes]
|
@@ -55,7 +58,7 @@ import { themeTypes, type ThemeType } from "./constants";
|
|
55
58
|
process.exit(-1);
|
56
59
|
}
|
57
60
|
|
58
|
-
await writeFile(targetFilePath, await readFile(pathJoin(
|
61
|
+
await writeFile(targetFilePath, await readFile(pathJoin(getThisCodebaseRootDirPath(), "src", themeType, "pages", pageBasename)));
|
59
62
|
|
60
63
|
console.log(`${pathRelative(process.cwd(), targetFilePath)} created`);
|
61
64
|
})();
|
@@ -4,7 +4,10 @@ import { join as pathJoin } from "path";
|
|
4
4
|
import parseArgv from "minimist";
|
5
5
|
import { getAbsoluteAndInOsFormatPath } from "../../tools/getAbsoluteAndInOsFormatPath";
|
6
6
|
import { readResolvedViteConfig } from "./resolvedViteConfig";
|
7
|
-
import
|
7
|
+
import * as fs from "fs";
|
8
|
+
import { getCacheDirPath } from "./getCacheDirPath";
|
9
|
+
import { getReactAppRootDirPath } from "./getReactAppRootDirPath";
|
10
|
+
import { getNpmWorkspaceRootDirPath } from "./getNpmWorkspaceRootDirPath";
|
8
11
|
|
9
12
|
/** Consolidated build option gathered form CLI arguments and config in package.json */
|
10
13
|
export type BuildOptions = {
|
@@ -28,34 +31,24 @@ export type BuildOptions = {
|
|
28
31
|
urlPathname: string | undefined;
|
29
32
|
assetsDirPath: string;
|
30
33
|
doBuildRetrocompatAccountTheme: boolean;
|
34
|
+
npmWorkspaceRootDirPath: string;
|
31
35
|
};
|
32
36
|
|
33
37
|
export function readBuildOptions(params: { processArgv: string[] }): BuildOptions {
|
34
38
|
const { processArgv } = params;
|
35
39
|
|
36
|
-
const
|
40
|
+
const { reactAppRootDirPath } = getReactAppRootDirPath({ processArgv });
|
37
41
|
|
38
|
-
const
|
39
|
-
const arg = argv["project"] ?? argv["p"];
|
42
|
+
const { cacheDirPath } = getCacheDirPath({ reactAppRootDirPath });
|
40
43
|
|
41
|
-
|
42
|
-
return process.cwd();
|
43
|
-
}
|
44
|
+
const { resolvedViteConfig } = readResolvedViteConfig({ cacheDirPath });
|
44
45
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
});
|
49
|
-
})();
|
46
|
+
if (resolvedViteConfig === undefined && fs.existsSync(pathJoin(reactAppRootDirPath, "vite.config.ts"))) {
|
47
|
+
throw new Error("Keycloakify's Vite plugin output not found");
|
48
|
+
}
|
50
49
|
|
51
50
|
const parsedPackageJson = readParsedPackageJson({ reactAppRootDirPath });
|
52
51
|
|
53
|
-
const { resolvedViteConfig } =
|
54
|
-
readResolvedViteConfig({
|
55
|
-
"parsedPackageJson_keycloakify_keycloakifyBuildDirPath": parsedPackageJson.keycloakify?.keycloakifyBuildDirPath,
|
56
|
-
reactAppRootDirPath
|
57
|
-
}) ?? {};
|
58
|
-
|
59
52
|
const themeNames = (() => {
|
60
53
|
if (parsedPackageJson.keycloakify?.themeName === undefined) {
|
61
54
|
return [
|
@@ -73,12 +66,6 @@ export function readBuildOptions(params: { processArgv: string[] }): BuildOption
|
|
73
66
|
return parsedPackageJson.keycloakify.themeName;
|
74
67
|
})();
|
75
68
|
|
76
|
-
const { keycloakifyBuildDirPath } = getKeycloakifyBuildDirPath({
|
77
|
-
"parsedPackageJson_keycloakify_keycloakifyBuildDirPath": parsedPackageJson.keycloakify?.keycloakifyBuildDirPath,
|
78
|
-
reactAppRootDirPath,
|
79
|
-
"bundler": resolvedViteConfig !== undefined ? "vite" : "webpack"
|
80
|
-
});
|
81
|
-
|
82
69
|
const reactAppBuildDirPath = (() => {
|
83
70
|
webpack: {
|
84
71
|
if (resolvedViteConfig !== undefined) {
|
@@ -98,6 +85,10 @@ export function readBuildOptions(params: { processArgv: string[] }): BuildOption
|
|
98
85
|
return pathJoin(reactAppRootDirPath, resolvedViteConfig.buildDir);
|
99
86
|
})();
|
100
87
|
|
88
|
+
const argv = parseArgv(processArgv);
|
89
|
+
|
90
|
+
const { npmWorkspaceRootDirPath } = getNpmWorkspaceRootDirPath({ reactAppRootDirPath });
|
91
|
+
|
101
92
|
return {
|
102
93
|
"bundler": resolvedViteConfig !== undefined ? "vite" : "webpack",
|
103
94
|
"isSilent": typeof argv["silent"] === "boolean" ? argv["silent"] : false,
|
@@ -124,7 +115,16 @@ export function readBuildOptions(params: { processArgv: string[] }): BuildOption
|
|
124
115
|
"loginThemeResourcesFromKeycloakVersion": parsedPackageJson.keycloakify?.loginThemeResourcesFromKeycloakVersion ?? "11.0.3",
|
125
116
|
reactAppRootDirPath,
|
126
117
|
reactAppBuildDirPath,
|
127
|
-
keycloakifyBuildDirPath
|
118
|
+
"keycloakifyBuildDirPath": (() => {
|
119
|
+
if (parsedPackageJson.keycloakify?.keycloakifyBuildDirPath !== undefined) {
|
120
|
+
return getAbsoluteAndInOsFormatPath({
|
121
|
+
"pathIsh": parsedPackageJson.keycloakify?.keycloakifyBuildDirPath,
|
122
|
+
"cwd": reactAppRootDirPath
|
123
|
+
});
|
124
|
+
}
|
125
|
+
|
126
|
+
return resolvedViteConfig?.buildDir === undefined ? "build_keycloak" : `${resolvedViteConfig.buildDir}_keycloak`;
|
127
|
+
})(),
|
128
128
|
"publicDirPath": (() => {
|
129
129
|
webpack: {
|
130
130
|
if (resolvedViteConfig !== undefined) {
|
@@ -143,19 +143,7 @@ export function readBuildOptions(params: { processArgv: string[] }): BuildOption
|
|
143
143
|
|
144
144
|
return pathJoin(reactAppRootDirPath, resolvedViteConfig.publicDir);
|
145
145
|
})(),
|
146
|
-
|
147
|
-
(() => {
|
148
|
-
if (process.env.XDG_CACHE_HOME !== undefined) {
|
149
|
-
return getAbsoluteAndInOsFormatPath({
|
150
|
-
"pathIsh": process.env.XDG_CACHE_HOME,
|
151
|
-
"cwd": reactAppRootDirPath
|
152
|
-
});
|
153
|
-
}
|
154
|
-
|
155
|
-
return pathJoin(reactAppRootDirPath, "node_modules", ".cache");
|
156
|
-
})(),
|
157
|
-
"keycloakify"
|
158
|
-
),
|
146
|
+
cacheDirPath,
|
159
147
|
"urlPathname": (() => {
|
160
148
|
webpack: {
|
161
149
|
if (resolvedViteConfig !== undefined) {
|
@@ -191,6 +179,7 @@ export function readBuildOptions(params: { processArgv: string[] }): BuildOption
|
|
191
179
|
|
192
180
|
return pathJoin(reactAppBuildDirPath, resolvedViteConfig.assetsDir);
|
193
181
|
})(),
|
194
|
-
"doBuildRetrocompatAccountTheme": parsedPackageJson.keycloakify?.doBuildRetrocompatAccountTheme ?? true
|
182
|
+
"doBuildRetrocompatAccountTheme": parsedPackageJson.keycloakify?.doBuildRetrocompatAccountTheme ?? true,
|
183
|
+
npmWorkspaceRootDirPath
|
195
184
|
};
|
196
185
|
}
|
@@ -0,0 +1,25 @@
|
|
1
|
+
import { join as pathJoin } from "path";
|
2
|
+
import { getAbsoluteAndInOsFormatPath } from "../../tools/getAbsoluteAndInOsFormatPath";
|
3
|
+
import { getNpmWorkspaceRootDirPath } from "./getNpmWorkspaceRootDirPath";
|
4
|
+
|
5
|
+
export function getCacheDirPath(params: { reactAppRootDirPath: string }) {
|
6
|
+
const { reactAppRootDirPath } = params;
|
7
|
+
|
8
|
+
const { npmWorkspaceRootDirPath } = getNpmWorkspaceRootDirPath({ reactAppRootDirPath });
|
9
|
+
|
10
|
+
const cacheDirPath = pathJoin(
|
11
|
+
(() => {
|
12
|
+
if (process.env.XDG_CACHE_HOME !== undefined) {
|
13
|
+
return getAbsoluteAndInOsFormatPath({
|
14
|
+
"pathIsh": process.env.XDG_CACHE_HOME,
|
15
|
+
"cwd": reactAppRootDirPath
|
16
|
+
});
|
17
|
+
}
|
18
|
+
|
19
|
+
return pathJoin(npmWorkspaceRootDirPath, "node_modules", ".cache");
|
20
|
+
})(),
|
21
|
+
"keycloakify"
|
22
|
+
);
|
23
|
+
|
24
|
+
return { cacheDirPath };
|
25
|
+
}
|
@@ -0,0 +1,49 @@
|
|
1
|
+
import * as child_process from "child_process";
|
2
|
+
import { join as pathJoin, resolve as pathResolve, sep as pathSep } from "path";
|
3
|
+
import { assert } from "tsafe/assert";
|
4
|
+
|
5
|
+
let cache:
|
6
|
+
| {
|
7
|
+
reactAppRootDirPath: string;
|
8
|
+
npmWorkspaceRootDirPath: string;
|
9
|
+
}
|
10
|
+
| undefined = undefined;
|
11
|
+
|
12
|
+
export function getNpmWorkspaceRootDirPath(params: { reactAppRootDirPath: string }) {
|
13
|
+
const { reactAppRootDirPath } = params;
|
14
|
+
|
15
|
+
use_cache: {
|
16
|
+
if (cache === undefined || cache.reactAppRootDirPath !== reactAppRootDirPath) {
|
17
|
+
break use_cache;
|
18
|
+
}
|
19
|
+
|
20
|
+
const { npmWorkspaceRootDirPath } = cache;
|
21
|
+
|
22
|
+
return { npmWorkspaceRootDirPath };
|
23
|
+
}
|
24
|
+
|
25
|
+
const npmWorkspaceRootDirPath = (function callee(depth: number): string {
|
26
|
+
const cwd = pathResolve(pathJoin(...[reactAppRootDirPath, ...Array(depth).fill("..")]));
|
27
|
+
|
28
|
+
try {
|
29
|
+
child_process.execSync("npm config get", { cwd: cwd });
|
30
|
+
} catch (error) {
|
31
|
+
if (String(error).includes("ENOWORKSPACES")) {
|
32
|
+
assert(cwd !== pathSep, "NPM workspace not found");
|
33
|
+
|
34
|
+
return callee(depth + 1);
|
35
|
+
}
|
36
|
+
|
37
|
+
throw error;
|
38
|
+
}
|
39
|
+
|
40
|
+
return cwd;
|
41
|
+
})(0);
|
42
|
+
|
43
|
+
cache = {
|
44
|
+
reactAppRootDirPath,
|
45
|
+
npmWorkspaceRootDirPath
|
46
|
+
};
|
47
|
+
|
48
|
+
return { npmWorkspaceRootDirPath };
|
49
|
+
}
|
@@ -0,0 +1,23 @@
|
|
1
|
+
import parseArgv from "minimist";
|
2
|
+
import { getAbsoluteAndInOsFormatPath } from "../../tools/getAbsoluteAndInOsFormatPath";
|
3
|
+
|
4
|
+
export function getReactAppRootDirPath(params: { processArgv: string[] }) {
|
5
|
+
const { processArgv } = params;
|
6
|
+
|
7
|
+
const argv = parseArgv(processArgv);
|
8
|
+
|
9
|
+
const reactAppRootDirPath = (() => {
|
10
|
+
const arg = argv["project"] ?? argv["p"];
|
11
|
+
|
12
|
+
if (typeof arg !== "string") {
|
13
|
+
return process.cwd();
|
14
|
+
}
|
15
|
+
|
16
|
+
return getAbsoluteAndInOsFormatPath({
|
17
|
+
"pathIsh": arg,
|
18
|
+
"cwd": process.cwd()
|
19
|
+
});
|
20
|
+
})();
|
21
|
+
|
22
|
+
return { reactAppRootDirPath };
|
23
|
+
}
|