keycloakify 9.4.0-rc.1 → 9.4.0-rc.11
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/PUBLIC_URL.d.ts +5 -0
- package/PUBLIC_URL.js +15 -0
- package/PUBLIC_URL.js.map +1 -0
- package/account/kcContext/createGetKcContext.js +7 -4
- package/account/kcContext/createGetKcContext.js.map +1 -1
- package/account/kcContext/kcContextMocks.js +3 -5
- package/account/kcContext/kcContextMocks.js.map +1 -1
- 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 +12 -1
- package/bin/copy-keycloak-resources-to-public.js +133 -70
- 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 +37 -27
- 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/initialize-email-theme.js +2 -4
- package/bin/initialize-email-theme.js.map +1 -1
- package/bin/keycloakify/buildOptions/buildOptions.d.ts +1 -1
- package/bin/keycloakify/buildOptions/buildOptions.js +56 -32
- 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/generateFtl/ftl_object_to_js_code_declaring_an_object.ftl +8 -0
- package/bin/keycloakify/generateFtl/generateFtl.js +2 -1
- package/bin/keycloakify/generateFtl/generateFtl.js.map +1 -1
- package/bin/keycloakify/generateStartKeycloakTestingContainer.js +0 -1
- package/bin/keycloakify/generateStartKeycloakTestingContainer.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.map +1 -1
- package/bin/keycloakify/keycloakify.js +11 -16
- package/bin/keycloakify/keycloakify.js.map +1 -1
- package/bin/keycloakify/replacers/replaceImportsInJsCode/webpack.js +0 -5
- package/bin/keycloakify/replacers/replaceImportsInJsCode/webpack.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/bin/tools/transformCodebase.js +5 -5
- package/bin/tools/transformCodebase.js.map +1 -1
- package/lib/BASE_URL.d.ts +10 -0
- package/lib/BASE_URL.js +38 -0
- package/lib/BASE_URL.js.map +1 -0
- package/lib/isStorybook.d.ts +1 -0
- package/lib/isStorybook.js +3 -0
- package/lib/isStorybook.js.map +1 -0
- package/lib/keycloakJsAdapter.d.ts +4 -0
- package/lib/keycloakJsAdapter.js +4 -0
- package/lib/keycloakJsAdapter.js.map +1 -1
- package/login/kcContext/createGetKcContext.js +7 -4
- package/login/kcContext/createGetKcContext.js.map +1 -1
- package/login/kcContext/kcContextMocks.js +3 -5
- package/login/kcContext/kcContextMocks.js.map +1 -1
- package/package.json +56 -23
- package/src/PUBLIC_URL.ts +21 -0
- package/src/account/kcContext/createGetKcContext.ts +8 -5
- package/src/account/kcContext/kcContextMocks.ts +3 -5
- package/src/bin/constants.ts +1 -1
- package/src/bin/copy-keycloak-resources-to-public.ts +73 -12
- package/src/bin/download-builtin-keycloak-theme.ts +40 -27
- package/src/bin/downloadAndUnzip.ts +203 -0
- package/src/bin/eject-keycloak-page.ts +6 -3
- package/src/bin/initialize-email-theme.ts +1 -4
- package/src/bin/keycloakify/buildOptions/buildOptions.ts +35 -35
- 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/generateFtl/ftl_object_to_js_code_declaring_an_object.ftl +8 -0
- package/src/bin/keycloakify/generateFtl/generateFtl.ts +3 -2
- package/src/bin/keycloakify/generateStartKeycloakTestingContainer.ts +0 -1
- 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 +1 -0
- package/src/bin/keycloakify/keycloakify.ts +13 -19
- package/src/bin/keycloakify/replacers/replaceImportsInJsCode/webpack.ts +0 -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/bin/tools/transformCodebase.ts +6 -5
- package/src/lib/BASE_URL.ts +44 -0
- package/src/lib/isStorybook.ts +3 -0
- package/src/lib/keycloakJsAdapter.ts +4 -0
- package/src/login/kcContext/createGetKcContext.ts +8 -5
- package/src/login/kcContext/kcContextMocks.ts +3 -5
- package/src/vite-plugin/vite-plugin.ts +12 -11
- package/vite-plugin/tsconfig.tsbuildinfo +1 -1
- package/vite-plugin/vite-plugin.js +11 -11
- 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/bin/tools/pathJoin.d.ts +0 -1
- package/bin/tools/pathJoin.js +0 -15
- package/bin/tools/pathJoin.js.map +0 -1
- package/src/bin/keycloakify/buildOptions/getKeycloakifyBuildDirPath.ts +0 -33
- package/src/bin/tools/downloadAndUnzip.ts +0 -301
- package/src/bin/tools/pathJoin.ts +0 -6
- package/src/vite-plugin/config.json +0 -232
@@ -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
|
})();
|
@@ -11,17 +11,14 @@ import { getThemeSrcDirPath } from "./getThemeSrcDirPath";
|
|
11
11
|
import { rmSync } from "./tools/fs.rmSync";
|
12
12
|
|
13
13
|
export async function main() {
|
14
|
-
const reactAppRootDirPath = process.cwd();
|
15
|
-
|
16
14
|
const buildOptions = readBuildOptions({
|
17
|
-
reactAppRootDirPath,
|
18
15
|
"processArgv": process.argv.slice(2)
|
19
16
|
});
|
20
17
|
|
21
18
|
const logger = getLogger({ "isSilent": buildOptions.isSilent });
|
22
19
|
|
23
20
|
const { themeSrcDirPath } = getThemeSrcDirPath({
|
24
|
-
reactAppRootDirPath
|
21
|
+
"reactAppRootDirPath": buildOptions.reactAppRootDirPath
|
25
22
|
});
|
26
23
|
|
27
24
|
const emailThemeSrcDirPath = pathJoin(themeSrcDirPath, "email");
|
@@ -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,18 +31,23 @@ export type BuildOptions = {
|
|
28
31
|
urlPathname: string | undefined;
|
29
32
|
assetsDirPath: string;
|
30
33
|
doBuildRetrocompatAccountTheme: boolean;
|
34
|
+
npmWorkspaceRootDirPath: string;
|
31
35
|
};
|
32
36
|
|
33
|
-
export function readBuildOptions(params: {
|
34
|
-
const {
|
37
|
+
export function readBuildOptions(params: { processArgv: string[] }): BuildOptions {
|
38
|
+
const { processArgv } = params;
|
35
39
|
|
36
|
-
const
|
40
|
+
const { reactAppRootDirPath } = getReactAppRootDirPath({ processArgv });
|
41
|
+
|
42
|
+
const { cacheDirPath } = getCacheDirPath({ reactAppRootDirPath });
|
43
|
+
|
44
|
+
const { resolvedViteConfig } = readResolvedViteConfig({ cacheDirPath });
|
37
45
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
46
|
+
if (resolvedViteConfig === undefined && fs.existsSync(pathJoin(reactAppRootDirPath, "vite.config.ts"))) {
|
47
|
+
throw new Error("Keycloakify's Vite plugin output not found");
|
48
|
+
}
|
49
|
+
|
50
|
+
const parsedPackageJson = readParsedPackageJson({ reactAppRootDirPath });
|
43
51
|
|
44
52
|
const themeNames = (() => {
|
45
53
|
if (parsedPackageJson.keycloakify?.themeName === undefined) {
|
@@ -58,12 +66,6 @@ export function readBuildOptions(params: { reactAppRootDirPath: string; processA
|
|
58
66
|
return parsedPackageJson.keycloakify.themeName;
|
59
67
|
})();
|
60
68
|
|
61
|
-
const { keycloakifyBuildDirPath } = getKeycloakifyBuildDirPath({
|
62
|
-
"parsedPackageJson_keycloakify_keycloakifyBuildDirPath": parsedPackageJson.keycloakify?.keycloakifyBuildDirPath,
|
63
|
-
reactAppRootDirPath,
|
64
|
-
"bundler": resolvedViteConfig !== undefined ? "vite" : "webpack"
|
65
|
-
});
|
66
|
-
|
67
69
|
const reactAppBuildDirPath = (() => {
|
68
70
|
webpack: {
|
69
71
|
if (resolvedViteConfig !== undefined) {
|
@@ -83,13 +85,13 @@ export function readBuildOptions(params: { reactAppRootDirPath: string; processA
|
|
83
85
|
return pathJoin(reactAppRootDirPath, resolvedViteConfig.buildDir);
|
84
86
|
})();
|
85
87
|
|
88
|
+
const argv = parseArgv(processArgv);
|
89
|
+
|
90
|
+
const { npmWorkspaceRootDirPath } = getNpmWorkspaceRootDirPath({ reactAppRootDirPath });
|
91
|
+
|
86
92
|
return {
|
87
93
|
"bundler": resolvedViteConfig !== undefined ? "vite" : "webpack",
|
88
|
-
"isSilent":
|
89
|
-
const argv = parseArgv(processArgv);
|
90
|
-
|
91
|
-
return typeof argv["silent"] === "boolean" ? argv["silent"] : false;
|
92
|
-
})(),
|
94
|
+
"isSilent": typeof argv["silent"] === "boolean" ? argv["silent"] : false,
|
93
95
|
"themeVersion": process.env.KEYCLOAKIFY_THEME_VERSION ?? parsedPackageJson.version ?? "0.0.0",
|
94
96
|
themeNames,
|
95
97
|
"extraThemeProperties": parsedPackageJson.keycloakify?.extraThemeProperties,
|
@@ -113,7 +115,16 @@ export function readBuildOptions(params: { reactAppRootDirPath: string; processA
|
|
113
115
|
"loginThemeResourcesFromKeycloakVersion": parsedPackageJson.keycloakify?.loginThemeResourcesFromKeycloakVersion ?? "11.0.3",
|
114
116
|
reactAppRootDirPath,
|
115
117
|
reactAppBuildDirPath,
|
116
|
-
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
|
+
})(),
|
117
128
|
"publicDirPath": (() => {
|
118
129
|
webpack: {
|
119
130
|
if (resolvedViteConfig !== undefined) {
|
@@ -132,19 +143,7 @@ export function readBuildOptions(params: { reactAppRootDirPath: string; processA
|
|
132
143
|
|
133
144
|
return pathJoin(reactAppRootDirPath, resolvedViteConfig.publicDir);
|
134
145
|
})(),
|
135
|
-
|
136
|
-
(() => {
|
137
|
-
if (process.env.XDG_CACHE_HOME !== undefined) {
|
138
|
-
return getAbsoluteAndInOsFormatPath({
|
139
|
-
"pathIsh": process.env.XDG_CACHE_HOME,
|
140
|
-
"cwd": reactAppRootDirPath
|
141
|
-
});
|
142
|
-
}
|
143
|
-
|
144
|
-
return pathJoin(reactAppRootDirPath, "node_modules", ".cache");
|
145
|
-
})(),
|
146
|
-
"keycloakify"
|
147
|
-
),
|
146
|
+
cacheDirPath,
|
148
147
|
"urlPathname": (() => {
|
149
148
|
webpack: {
|
150
149
|
if (resolvedViteConfig !== undefined) {
|
@@ -180,6 +179,7 @@ export function readBuildOptions(params: { reactAppRootDirPath: string; processA
|
|
180
179
|
|
181
180
|
return pathJoin(reactAppBuildDirPath, resolvedViteConfig.assetsDir);
|
182
181
|
})(),
|
183
|
-
"doBuildRetrocompatAccountTheme": parsedPackageJson.keycloakify?.doBuildRetrocompatAccountTheme ?? true
|
182
|
+
"doBuildRetrocompatAccountTheme": parsedPackageJson.keycloakify?.doBuildRetrocompatAccountTheme ?? true,
|
183
|
+
npmWorkspaceRootDirPath
|
184
184
|
};
|
185
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
|
+
}
|
@@ -5,7 +5,6 @@ import { z } from "zod";
|
|
5
5
|
import { join as pathJoin } from "path";
|
6
6
|
import { resolvedViteConfigJsonBasename } from "../../constants";
|
7
7
|
import type { OptionalIfCanBeUndefined } from "../../tools/OptionalIfCanBeUndefined";
|
8
|
-
import { getKeycloakifyBuildDirPath } from "./getKeycloakifyBuildDirPath";
|
9
8
|
|
10
9
|
export type ResolvedViteConfig = {
|
11
10
|
buildDir: string;
|
@@ -28,31 +27,18 @@ const zResolvedViteConfig = z.object({
|
|
28
27
|
assert<Equals<Got, Expected>>();
|
29
28
|
}
|
30
29
|
|
31
|
-
export function readResolvedViteConfig(params: {
|
32
|
-
|
33
|
-
|
34
|
-
}
|
35
|
-
| {
|
36
|
-
resolvedViteConfig: ResolvedViteConfig;
|
37
|
-
}
|
38
|
-
| undefined {
|
39
|
-
const { reactAppRootDirPath, parsedPackageJson_keycloakify_keycloakifyBuildDirPath } = params;
|
30
|
+
export function readResolvedViteConfig(params: { cacheDirPath: string }): {
|
31
|
+
resolvedViteConfig: ResolvedViteConfig | undefined;
|
32
|
+
} {
|
33
|
+
const { cacheDirPath } = params;
|
40
34
|
|
41
|
-
const
|
35
|
+
const resolvedViteConfigJsonFilePath = pathJoin(cacheDirPath, resolvedViteConfigJsonBasename);
|
42
36
|
|
43
|
-
if (!fs.existsSync(
|
44
|
-
return undefined;
|
37
|
+
if (!fs.existsSync(resolvedViteConfigJsonFilePath)) {
|
38
|
+
return { "resolvedViteConfig": undefined };
|
45
39
|
}
|
46
40
|
|
47
|
-
const { keycloakifyBuildDirPath } = getKeycloakifyBuildDirPath({
|
48
|
-
reactAppRootDirPath,
|
49
|
-
parsedPackageJson_keycloakify_keycloakifyBuildDirPath,
|
50
|
-
"bundler": "vite"
|
51
|
-
});
|
52
|
-
|
53
41
|
const resolvedViteConfig = (() => {
|
54
|
-
const resolvedViteConfigJsonFilePath = pathJoin(keycloakifyBuildDirPath, resolvedViteConfigJsonBasename);
|
55
|
-
|
56
42
|
if (!fs.existsSync(resolvedViteConfigJsonFilePath)) {
|
57
43
|
throw new Error("Missing Keycloakify Vite plugin output.");
|
58
44
|
}
|
@@ -408,6 +408,14 @@
|
|
408
408
|
out["themeName"] = "KEYCLOAKIFY_THEME_NAME_cXxKd3xEer";
|
409
409
|
out["pageId"] = "${pageId}";
|
410
410
|
|
411
|
+
try {
|
412
|
+
|
413
|
+
out["url"]["resourcesCommonPath"] = out["url"]["resourcesPath"] + "/" + "RESOURCES_COMMON_cLsLsMrtDkpVv";
|
414
|
+
|
415
|
+
} catch(error) {
|
416
|
+
|
417
|
+
}
|
418
|
+
|
411
419
|
return out;
|
412
420
|
|
413
421
|
})()
|
@@ -7,7 +7,7 @@ import { join as pathJoin } from "path";
|
|
7
7
|
import { objectKeys } from "tsafe/objectKeys";
|
8
8
|
import type { BuildOptions } from "../buildOptions";
|
9
9
|
import { assert } from "tsafe/assert";
|
10
|
-
import { type ThemeType, nameOfTheGlobal, basenameOfTheKeycloakifyResourcesDir } from "../../constants";
|
10
|
+
import { type ThemeType, nameOfTheGlobal, basenameOfTheKeycloakifyResourcesDir, resources_common } from "../../constants";
|
11
11
|
|
12
12
|
export type BuildOptionsLike = {
|
13
13
|
bundler: "vite" | "webpack";
|
@@ -105,7 +105,8 @@ export function generateFtlFilesCodeFactory(params: {
|
|
105
105
|
.replace("KEYCLOAKIFY_VERSION_xEdKd3xEdr", keycloakifyVersion)
|
106
106
|
.replace("KEYCLOAKIFY_THEME_VERSION_sIgKd3xEdr3dx", buildOptions.themeVersion)
|
107
107
|
.replace("KEYCLOAKIFY_THEME_TYPE_dExKd3xEdr", themeType)
|
108
|
-
.replace("KEYCLOAKIFY_THEME_NAME_cXxKd3xEer", themeName)
|
108
|
+
.replace("KEYCLOAKIFY_THEME_NAME_cXxKd3xEer", themeName)
|
109
|
+
.replace("RESOURCES_COMMON_cLsLsMrtDkpVv", resources_common),
|
109
110
|
"<!-- xIdLqMeOedErIdLsPdNdI9dSlxI -->": [
|
110
111
|
"<#if scripts??>",
|
111
112
|
" <#list scripts as script>",
|
@@ -30,7 +30,6 @@ export function generateStartKeycloakTestingContainer(params: { jarFilePath: str
|
|
30
30
|
Buffer.from(
|
31
31
|
[
|
32
32
|
"#!/usr/bin/env bash",
|
33
|
-
`# If you want to test with Keycloak version prior to 23 use the retrocompat-${pathBasename(jarFilePath)}`,
|
34
33
|
"",
|
35
34
|
`docker rm ${containerName} || true`,
|
36
35
|
"",
|
@@ -6,38 +6,27 @@ import { generateStartKeycloakTestingContainer } from "./generateStartKeycloakTe
|
|
6
6
|
import * as fs from "fs";
|
7
7
|
import { readBuildOptions } from "./buildOptions";
|
8
8
|
import { getLogger } from "../tools/logger";
|
9
|
-
import { assert } from "tsafe/assert";
|
10
9
|
import { getThemeSrcDirPath } from "../getThemeSrcDirPath";
|
11
|
-
import {
|
10
|
+
import { getThisCodebaseRootDirPath } from "../tools/getThisCodebaseRootDirPath";
|
11
|
+
import { readThisNpmProjectVersion } from "../tools/readThisNpmProjectVersion";
|
12
12
|
|
13
13
|
export async function main() {
|
14
|
-
const reactAppRootDirPath = process.cwd();
|
15
|
-
|
16
14
|
const buildOptions = readBuildOptions({
|
17
|
-
reactAppRootDirPath,
|
18
15
|
"processArgv": process.argv.slice(2)
|
19
16
|
});
|
20
17
|
|
21
18
|
const logger = getLogger({ "isSilent": buildOptions.isSilent });
|
22
19
|
logger.log("🔏 Building the keycloak theme...⌚");
|
23
20
|
|
24
|
-
const
|
25
|
-
|
26
|
-
const { themeSrcDirPath } = getThemeSrcDirPath({ reactAppRootDirPath });
|
21
|
+
const { themeSrcDirPath } = getThemeSrcDirPath({ "reactAppRootDirPath": buildOptions.reactAppRootDirPath });
|
27
22
|
|
28
23
|
for (const themeName of buildOptions.themeNames) {
|
29
24
|
await generateTheme({
|
30
25
|
themeName,
|
31
26
|
themeSrcDirPath,
|
32
|
-
"keycloakifySrcDirPath": pathJoin(
|
33
|
-
|
34
|
-
|
35
|
-
const version = JSON.parse(fs.readFileSync(pathJoin(keycloakifyDirPath, "package.json")).toString("utf8"))["version"];
|
36
|
-
|
37
|
-
assert(typeof version === "string");
|
38
|
-
|
39
|
-
return version;
|
40
|
-
})()
|
27
|
+
"keycloakifySrcDirPath": pathJoin(getThisCodebaseRootDirPath(), "src"),
|
28
|
+
"keycloakifyVersion": readThisNpmProjectVersion(),
|
29
|
+
buildOptions
|
41
30
|
});
|
42
31
|
}
|
43
32
|
|
@@ -83,12 +72,17 @@ export async function main() {
|
|
83
72
|
"",
|
84
73
|
...(!buildOptions.doCreateJar
|
85
74
|
? []
|
86
|
-
: [
|
75
|
+
: [
|
76
|
+
`✅ Your keycloak theme has been generated and bundled into .${pathSep}${pathRelative(
|
77
|
+
buildOptions.reactAppRootDirPath,
|
78
|
+
jarFilePath
|
79
|
+
)} 🚀`
|
80
|
+
]),
|
87
81
|
"",
|
88
82
|
`To test your theme locally you can spin up a Keycloak ${containerKeycloakVersion} container image with the theme pre loaded by running:`,
|
89
83
|
"",
|
90
84
|
`👉 $ .${pathSep}${pathRelative(
|
91
|
-
reactAppRootDirPath,
|
85
|
+
buildOptions.reactAppRootDirPath,
|
92
86
|
pathJoin(buildOptions.keycloakifyBuildDirPath, generateStartKeycloakTestingContainer.basename)
|
93
87
|
)} 👈`,
|
94
88
|
``,
|