keycloakify 10.0.0-rc.90 → 10.0.0-rc.91
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/bin/193.index.js +3 -3
- package/bin/{751.index.js → 31.index.js} +180 -131
- package/bin/440.index.js +7 -12
- package/bin/453.index.js +1 -1
- package/bin/526.index.js +78 -65
- package/bin/538.index.js +1 -1
- package/bin/{837.index.js → 893.index.js} +7 -89
- package/bin/932.index.js +2 -2
- package/bin/97.index.js +1 -1
- package/bin/main.js +7 -7
- package/bin/shared/buildContext.d.ts +9 -2
- package/bin/shared/buildContext.js.map +1 -1
- package/bin/shared/copyKeycloakResourcesToPublic.js.map +1 -1
- package/bin/shared/downloadKeycloakDefaultTheme.d.ts +2 -1
- package/bin/shared/downloadKeycloakDefaultTheme.js.map +1 -1
- package/package.json +7 -9
- package/src/bin/keycloakify/generateFtl/generateFtl.ts +14 -10
- package/src/bin/keycloakify/generateResources/generateResourcesForMainTheme.ts +2 -1
- package/src/bin/keycloakify/keycloakify.ts +1 -7
- package/src/bin/keycloakify/replacers/replaceImportsInJsCode/replaceImportsInJsCode.ts +2 -2
- package/src/bin/shared/buildContext.ts +168 -92
- package/src/bin/shared/copyKeycloakResourcesToPublic.ts +1 -4
- package/src/bin/shared/downloadKeycloakDefaultTheme.ts +2 -2
- package/src/bin/start-keycloak/appBuild.ts +130 -90
- package/src/bin/start-keycloak/keycloakifyBuild.ts +0 -1
- package/src/bin/start-keycloak/start-keycloak.ts +1 -1
- package/src/bin/tools/{downloadAndExtractArchive/downloadAndExtractArchive.ts → downloadAndExtractArchive.ts} +9 -17
- package/src/bin/tools/{downloadAndExtractArchive/fetchProxyOptions.ts → fetchProxyOptions.ts} +52 -60
- package/vite-plugin/index.js +187 -228
- package/src/bin/tools/downloadAndExtractArchive/index.ts +0 -1
- package/src/bin/tools/getNpmWorkspaceRootDirPath.ts +0 -84
@@ -1,16 +1,14 @@
|
|
1
1
|
import * as child_process from "child_process";
|
2
2
|
import { Deferred } from "evt/tools/Deferred";
|
3
3
|
import { assert } from "tsafe/assert";
|
4
|
-
import { is } from "tsafe/is";
|
5
4
|
import type { BuildContext } from "../shared/buildContext";
|
6
|
-
import
|
7
|
-
import { join as pathJoin } from "path";
|
5
|
+
import chalk from "chalk";
|
6
|
+
import { sep as pathSep, join as pathJoin } from "path";
|
8
7
|
|
9
8
|
export type BuildContextLike = {
|
10
9
|
projectDirPath: string;
|
11
10
|
keycloakifyBuildDirPath: string;
|
12
|
-
bundler: "
|
13
|
-
npmWorkspaceRootDirPath: string;
|
11
|
+
bundler: BuildContext["bundler"];
|
14
12
|
projectBuildDirPath: string;
|
15
13
|
};
|
16
14
|
|
@@ -21,95 +19,27 @@ export async function appBuild(params: {
|
|
21
19
|
}): Promise<{ isAppBuildSuccess: boolean }> {
|
22
20
|
const { buildContext } = params;
|
23
21
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
args: ["vite", "build"],
|
32
|
-
cwd: buildContext.projectDirPath
|
33
|
-
};
|
34
|
-
case "webpack": {
|
35
|
-
for (const dirPath of [
|
36
|
-
buildContext.projectDirPath,
|
37
|
-
buildContext.npmWorkspaceRootDirPath
|
38
|
-
]) {
|
39
|
-
try {
|
40
|
-
const parsedPackageJson = JSON.parse(
|
41
|
-
fs
|
42
|
-
.readFileSync(pathJoin(dirPath, "package.json"))
|
43
|
-
.toString("utf8")
|
44
|
-
);
|
45
|
-
|
46
|
-
const [scriptName] =
|
47
|
-
Object.entries(parsedPackageJson.scripts).find(
|
48
|
-
([, scriptValue]) => {
|
49
|
-
assert(is<string>(scriptValue));
|
50
|
-
if (
|
51
|
-
scriptValue.includes("webpack") &&
|
52
|
-
scriptValue.includes("--mode production")
|
53
|
-
) {
|
54
|
-
return true;
|
55
|
-
}
|
56
|
-
|
57
|
-
if (
|
58
|
-
scriptValue.includes("react-scripts") &&
|
59
|
-
scriptValue.includes("build")
|
60
|
-
) {
|
61
|
-
return true;
|
62
|
-
}
|
63
|
-
|
64
|
-
if (
|
65
|
-
scriptValue.includes("react-app-rewired") &&
|
66
|
-
scriptValue.includes("build")
|
67
|
-
) {
|
68
|
-
return true;
|
69
|
-
}
|
70
|
-
|
71
|
-
if (
|
72
|
-
scriptValue.includes("craco") &&
|
73
|
-
scriptValue.includes("build")
|
74
|
-
) {
|
75
|
-
return true;
|
76
|
-
}
|
77
|
-
|
78
|
-
if (
|
79
|
-
scriptValue.includes("ng") &&
|
80
|
-
scriptValue.includes("build")
|
81
|
-
) {
|
82
|
-
return true;
|
83
|
-
}
|
84
|
-
|
85
|
-
return false;
|
86
|
-
}
|
87
|
-
) ?? [];
|
88
|
-
|
89
|
-
if (scriptName === undefined) {
|
90
|
-
continue;
|
91
|
-
}
|
92
|
-
|
93
|
-
return {
|
94
|
-
command: "npm",
|
95
|
-
args: ["run", scriptName],
|
96
|
-
cwd: dirPath
|
97
|
-
};
|
98
|
-
} catch {
|
99
|
-
continue;
|
100
|
-
}
|
101
|
-
}
|
22
|
+
switch (buildContext.bundler.type) {
|
23
|
+
case "vite":
|
24
|
+
return appBuild_vite({ buildContext });
|
25
|
+
case "webpack":
|
26
|
+
return appBuild_webpack({ buildContext });
|
27
|
+
}
|
28
|
+
}
|
102
29
|
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
30
|
+
async function appBuild_vite(params: {
|
31
|
+
buildContext: BuildContextLike;
|
32
|
+
}): Promise<{ isAppBuildSuccess: boolean }> {
|
33
|
+
const { buildContext } = params;
|
34
|
+
|
35
|
+
assert(buildContext.bundler.type === "vite");
|
109
36
|
|
110
37
|
const dResult = new Deferred<{ isSuccess: boolean }>();
|
111
38
|
|
112
|
-
const child = child_process.spawn(
|
39
|
+
const child = child_process.spawn("npx", ["vite", "build"], {
|
40
|
+
cwd: buildContext.projectDirPath,
|
41
|
+
shell: true
|
42
|
+
});
|
113
43
|
|
114
44
|
child.stdout.on("data", data => {
|
115
45
|
if (data.toString("utf8").includes("gzip:")) {
|
@@ -127,3 +57,113 @@ export async function appBuild(params: {
|
|
127
57
|
|
128
58
|
return { isAppBuildSuccess: isSuccess };
|
129
59
|
}
|
60
|
+
|
61
|
+
async function appBuild_webpack(params: {
|
62
|
+
buildContext: BuildContextLike;
|
63
|
+
}): Promise<{ isAppBuildSuccess: boolean }> {
|
64
|
+
const { buildContext } = params;
|
65
|
+
|
66
|
+
assert(buildContext.bundler.type === "webpack");
|
67
|
+
|
68
|
+
const entries = Object.entries(buildContext.bundler.packageJsonScripts).filter(
|
69
|
+
([, scriptCommand]) => scriptCommand.includes("keycloakify build")
|
70
|
+
);
|
71
|
+
|
72
|
+
if (entries.length === 0) {
|
73
|
+
console.log(
|
74
|
+
chalk.red(
|
75
|
+
[
|
76
|
+
`You should have a script in your package.json at ${buildContext.bundler.packageJsonDirPath}`,
|
77
|
+
`that includes the 'keycloakify build' command`
|
78
|
+
].join(" ")
|
79
|
+
)
|
80
|
+
);
|
81
|
+
process.exit(-1);
|
82
|
+
}
|
83
|
+
|
84
|
+
const entry =
|
85
|
+
entries.length === 1
|
86
|
+
? entries[0]
|
87
|
+
: entries.find(([scriptName]) => scriptName === "build-keycloak-theme");
|
88
|
+
|
89
|
+
if (entry === undefined) {
|
90
|
+
console.log(
|
91
|
+
chalk.red(
|
92
|
+
"There's multiple candidate script for building your app, name one 'build-keycloak-theme'"
|
93
|
+
)
|
94
|
+
);
|
95
|
+
process.exit(-1);
|
96
|
+
}
|
97
|
+
|
98
|
+
const [scriptName, scriptCommand] = entry;
|
99
|
+
|
100
|
+
const { appBuildSubCommands } = (() => {
|
101
|
+
const appBuildSubCommands: string[] = [];
|
102
|
+
|
103
|
+
for (const subCmd of scriptCommand.split("&&").map(s => s.trim())) {
|
104
|
+
if (subCmd.includes("keycloakify build")) {
|
105
|
+
break;
|
106
|
+
}
|
107
|
+
|
108
|
+
appBuildSubCommands.push(subCmd);
|
109
|
+
}
|
110
|
+
|
111
|
+
return { appBuildSubCommands };
|
112
|
+
})();
|
113
|
+
|
114
|
+
if (appBuildSubCommands.length === 0) {
|
115
|
+
console.log(
|
116
|
+
chalk.red(
|
117
|
+
`Your ${scriptName} script should look like "... && keycloakify build ..."`
|
118
|
+
)
|
119
|
+
);
|
120
|
+
process.exit(-1);
|
121
|
+
}
|
122
|
+
|
123
|
+
for (const subCommand of appBuildSubCommands) {
|
124
|
+
const dIsSuccess = new Deferred<boolean>();
|
125
|
+
|
126
|
+
child_process.exec(
|
127
|
+
subCommand,
|
128
|
+
{
|
129
|
+
cwd: buildContext.bundler.packageJsonDirPath,
|
130
|
+
env: {
|
131
|
+
...process.env,
|
132
|
+
PATH: (() => {
|
133
|
+
const separator = pathSep === "/" ? ":" : ";";
|
134
|
+
|
135
|
+
return [
|
136
|
+
pathJoin(
|
137
|
+
buildContext.bundler.packageJsonDirPath,
|
138
|
+
"node_modules",
|
139
|
+
".bin"
|
140
|
+
),
|
141
|
+
...(process.env.PATH ?? "").split(separator)
|
142
|
+
].join(separator);
|
143
|
+
})()
|
144
|
+
}
|
145
|
+
},
|
146
|
+
(error, stdout, stderr) => {
|
147
|
+
if (error) {
|
148
|
+
dIsSuccess.resolve(false);
|
149
|
+
|
150
|
+
console.log(chalk.red(`Error running: '${subCommand}'`));
|
151
|
+
console.log(stdout);
|
152
|
+
console.log(stderr);
|
153
|
+
|
154
|
+
return;
|
155
|
+
}
|
156
|
+
|
157
|
+
dIsSuccess.resolve(true);
|
158
|
+
}
|
159
|
+
);
|
160
|
+
|
161
|
+
const isSuccess = await dIsSuccess.pr;
|
162
|
+
|
163
|
+
if (!isSuccess) {
|
164
|
+
return { isAppBuildSuccess: false };
|
165
|
+
}
|
166
|
+
}
|
167
|
+
|
168
|
+
return { isAppBuildSuccess: true };
|
169
|
+
}
|
@@ -121,7 +121,7 @@ export async function command(params: { cliCommandOptions: CliCommandOptions })
|
|
121
121
|
if (!isAppBuildSuccess) {
|
122
122
|
console.log(
|
123
123
|
chalk.red(
|
124
|
-
`App build failed, exiting. Try
|
124
|
+
`App build failed, exiting. Try building your app (e.g 'npm run build') and see what's wrong.`
|
125
125
|
)
|
126
126
|
);
|
127
127
|
process.exit(1);
|
@@ -1,12 +1,12 @@
|
|
1
|
-
import fetch from "make-fetch-happen";
|
1
|
+
import fetch, { type FetchOptions } from "make-fetch-happen";
|
2
2
|
import { mkdir, unlink, writeFile, readdir, readFile } from "fs/promises";
|
3
3
|
import { dirname as pathDirname, join as pathJoin } from "path";
|
4
4
|
import { assert } from "tsafe/assert";
|
5
|
-
import { extractArchive } from "
|
6
|
-
import { existsAsync } from "
|
7
|
-
|
5
|
+
import { extractArchive } from "./extractArchive";
|
6
|
+
import { existsAsync } from "./fs.existsAsync";
|
7
|
+
|
8
8
|
import * as crypto from "crypto";
|
9
|
-
import { rm } from "
|
9
|
+
import { rm } from "./fs.rm";
|
10
10
|
|
11
11
|
export async function downloadAndExtractArchive(params: {
|
12
12
|
url: string;
|
@@ -20,15 +20,10 @@ export async function downloadAndExtractArchive(params: {
|
|
20
20
|
}) => Promise<void>;
|
21
21
|
}) => Promise<void>;
|
22
22
|
cacheDirPath: string;
|
23
|
-
|
23
|
+
fetchOptions: FetchOptions | undefined;
|
24
24
|
}): Promise<{ extractedDirPath: string }> {
|
25
|
-
const {
|
26
|
-
|
27
|
-
uniqueIdOfOnOnArchiveFile,
|
28
|
-
onArchiveFile,
|
29
|
-
cacheDirPath,
|
30
|
-
npmWorkspaceRootDirPath
|
31
|
-
} = params;
|
25
|
+
const { url, uniqueIdOfOnOnArchiveFile, onArchiveFile, cacheDirPath, fetchOptions } =
|
26
|
+
params;
|
32
27
|
|
33
28
|
const archiveFileBasename = url.split("?")[0].split("/").reverse()[0];
|
34
29
|
|
@@ -55,10 +50,7 @@ export async function downloadAndExtractArchive(params: {
|
|
55
50
|
|
56
51
|
await mkdir(pathDirname(archiveFilePath), { recursive: true });
|
57
52
|
|
58
|
-
const response = await fetch(
|
59
|
-
url,
|
60
|
-
await getProxyFetchOptions({ npmWorkspaceRootDirPath })
|
61
|
-
);
|
53
|
+
const response = await fetch(url, fetchOptions);
|
62
54
|
|
63
55
|
response.body?.setMaxListeners(Number.MAX_VALUE);
|
64
56
|
assert(typeof response.body !== "undefined" && response.body != null);
|
package/src/bin/tools/{downloadAndExtractArchive/fetchProxyOptions.ts → fetchProxyOptions.ts}
RENAMED
@@ -1,61 +1,40 @@
|
|
1
|
-
import { exec as execCallback } from "child_process";
|
2
|
-
import { readFile } from "fs/promises";
|
3
1
|
import { type FetchOptions } from "make-fetch-happen";
|
4
|
-
import
|
5
|
-
|
6
|
-
function ensureArray<T>(arg0: T | T[]) {
|
7
|
-
return Array.isArray(arg0) ? arg0 : typeof arg0 === "undefined" ? [] : [arg0];
|
8
|
-
}
|
9
|
-
|
10
|
-
function ensureSingleOrNone<T>(arg0: T | T[]) {
|
11
|
-
if (!Array.isArray(arg0)) return arg0;
|
12
|
-
if (arg0.length === 0) return undefined;
|
13
|
-
if (arg0.length === 1) return arg0[0];
|
14
|
-
throw new Error(
|
15
|
-
"Illegal configuration, expected a single value but found multiple: " +
|
16
|
-
arg0.map(String).join(", ")
|
17
|
-
);
|
18
|
-
}
|
19
|
-
|
20
|
-
type NPMConfig = Record<string, string | string[]>;
|
21
|
-
|
22
|
-
/**
|
23
|
-
* Get npm configuration as map
|
24
|
-
*/
|
25
|
-
async function getNmpConfig(params: { npmWorkspaceRootDirPath: string }) {
|
26
|
-
const { npmWorkspaceRootDirPath } = params;
|
27
|
-
|
28
|
-
const exec = promisify(execCallback);
|
29
|
-
|
30
|
-
const stdout = await exec("npm config get", {
|
31
|
-
encoding: "utf8",
|
32
|
-
cwd: npmWorkspaceRootDirPath
|
33
|
-
}).then(({ stdout }) => stdout);
|
34
|
-
|
35
|
-
const npmConfigReducer = (cfg: NPMConfig, [key, value]: [string, string]) =>
|
36
|
-
key in cfg
|
37
|
-
? { ...cfg, [key]: [...ensureArray(cfg[key]), value] }
|
38
|
-
: { ...cfg, [key]: value };
|
39
|
-
|
40
|
-
return stdout
|
41
|
-
.split("\n")
|
42
|
-
.filter(line => !line.startsWith(";"))
|
43
|
-
.map(line => line.trim())
|
44
|
-
.map(line => line.split("=", 2) as [string, string])
|
45
|
-
.reduce(npmConfigReducer, {} as NPMConfig);
|
46
|
-
}
|
2
|
+
import * as child_process from "child_process";
|
3
|
+
import * as fs from "fs";
|
47
4
|
|
48
5
|
export type ProxyFetchOptions = Pick<
|
49
6
|
FetchOptions,
|
50
7
|
"proxy" | "noProxy" | "strictSSL" | "cert" | "ca"
|
51
8
|
>;
|
52
9
|
|
53
|
-
export
|
54
|
-
|
55
|
-
}):
|
56
|
-
const {
|
57
|
-
|
58
|
-
const cfg =
|
10
|
+
export function getProxyFetchOptions(params: {
|
11
|
+
npmConfigGetCwd: string;
|
12
|
+
}): ProxyFetchOptions {
|
13
|
+
const { npmConfigGetCwd } = params;
|
14
|
+
|
15
|
+
const cfg = (() => {
|
16
|
+
const output = child_process
|
17
|
+
.execSync("npm config get", {
|
18
|
+
cwd: npmConfigGetCwd
|
19
|
+
})
|
20
|
+
.toString("utf8");
|
21
|
+
|
22
|
+
return output
|
23
|
+
.split("\n")
|
24
|
+
.filter(line => !line.startsWith(";"))
|
25
|
+
.map(line => line.trim())
|
26
|
+
.map(line => line.split("=", 2) as [string, string])
|
27
|
+
.reduce(
|
28
|
+
(
|
29
|
+
cfg: Record<string, string | string[]>,
|
30
|
+
[key, value]: [string, string]
|
31
|
+
) =>
|
32
|
+
key in cfg
|
33
|
+
? { ...cfg, [key]: [...ensureArray(cfg[key]), value] }
|
34
|
+
: { ...cfg, [key]: value },
|
35
|
+
{}
|
36
|
+
);
|
37
|
+
})();
|
59
38
|
|
60
39
|
const proxy = ensureSingleOrNone(cfg["https-proxy"] ?? cfg["proxy"]);
|
61
40
|
const noProxy = cfg["noproxy"] ?? cfg["no-proxy"];
|
@@ -71,17 +50,16 @@ export async function getProxyFetchOptions(params: {
|
|
71
50
|
|
72
51
|
if (typeof cafile !== "undefined" && cafile !== "null") {
|
73
52
|
ca.push(
|
74
|
-
...(
|
75
|
-
|
76
|
-
return arr
|
77
|
-
.map((_, i) => i % size == 0 && arr.slice(i, i + size))
|
78
|
-
.filter(Boolean) as T[][];
|
79
|
-
}
|
80
|
-
|
81
|
-
const cafileContent = await readFile(cafile, "utf-8");
|
53
|
+
...(() => {
|
54
|
+
const cafileContent = fs.readFileSync(cafile).toString("utf8");
|
82
55
|
|
83
56
|
const newLinePlaceholder = "NEW_LINE_PLACEHOLDER_xIsPsK23svt";
|
84
57
|
|
58
|
+
const chunks = <T>(arr: T[], size: number = 2) =>
|
59
|
+
arr
|
60
|
+
.map((_, i) => i % size == 0 && arr.slice(i, i + size))
|
61
|
+
.filter(Boolean) as T[][];
|
62
|
+
|
85
63
|
return chunks(cafileContent.split(/(-----END CERTIFICATE-----)/), 2).map(
|
86
64
|
ca =>
|
87
65
|
ca
|
@@ -90,7 +68,7 @@ export async function getProxyFetchOptions(params: {
|
|
90
68
|
.replace(new RegExp(`^${newLinePlaceholder}`), "")
|
91
69
|
.replace(new RegExp(newLinePlaceholder, "g"), "\\n")
|
92
70
|
);
|
93
|
-
})()
|
71
|
+
})()
|
94
72
|
);
|
95
73
|
}
|
96
74
|
|
@@ -102,3 +80,17 @@ export async function getProxyFetchOptions(params: {
|
|
102
80
|
ca: ca.length === 0 ? undefined : ca
|
103
81
|
};
|
104
82
|
}
|
83
|
+
|
84
|
+
function ensureArray<T>(arg0: T | T[]) {
|
85
|
+
return Array.isArray(arg0) ? arg0 : typeof arg0 === "undefined" ? [] : [arg0];
|
86
|
+
}
|
87
|
+
|
88
|
+
function ensureSingleOrNone<T>(arg0: T | T[]) {
|
89
|
+
if (!Array.isArray(arg0)) return arg0;
|
90
|
+
if (arg0.length === 0) return undefined;
|
91
|
+
if (arg0.length === 1) return arg0[0];
|
92
|
+
throw new Error(
|
93
|
+
"Illegal configuration, expected a single value but found multiple: " +
|
94
|
+
arg0.map(String).join(", ")
|
95
|
+
);
|
96
|
+
}
|