bin general reresh, introducing termost
This commit is contained in:
parent
931e002b12
commit
d4f03b6b9e
@ -28,11 +28,7 @@
|
|||||||
"build-storybook": "yarn build && yarn copy-keycloak-resources-to-storybook-static && build-storybook"
|
"build-storybook": "yarn build && yarn copy-keycloak-resources-to-storybook-static && build-storybook"
|
||||||
},
|
},
|
||||||
"bin": {
|
"bin": {
|
||||||
"copy-keycloak-resources-to-public": "dist/bin/copy-keycloak-resources-to-public.js",
|
"keycloakify": "dist/bin/main.js"
|
||||||
"download-builtin-keycloak-theme": "dist/bin/download-builtin-keycloak-theme.js",
|
|
||||||
"eject-keycloak-page": "dist/bin/eject-keycloak-page.js",
|
|
||||||
"initialize-email-theme": "dist/bin/initialize-email-theme.js",
|
|
||||||
"keycloakify": "dist/bin/keycloakify/index.js"
|
|
||||||
},
|
},
|
||||||
"lint-staged": {
|
"lint-staged": {
|
||||||
"*.{ts,tsx,json,md}": [
|
"*.{ts,tsx,json,md}": [
|
||||||
@ -124,6 +120,7 @@
|
|||||||
"yauzl": "^2.10.0",
|
"yauzl": "^2.10.0",
|
||||||
"yazl": "^2.5.1",
|
"yazl": "^2.5.1",
|
||||||
"zod": "^3.17.10",
|
"zod": "^3.17.10",
|
||||||
"magic-string": "^0.30.7"
|
"magic-string": "^0.30.7",
|
||||||
|
"termost": "^0.12.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@ import "minimal-polyfills/Object.fromEntries";
|
|||||||
import * as fs from "fs";
|
import * as fs from "fs";
|
||||||
import { join as pathJoin, relative as pathRelative, dirname as pathDirname, sep as pathSep } from "path";
|
import { join as pathJoin, relative as pathRelative, dirname as pathDirname, sep as pathSep } from "path";
|
||||||
import { crawl } from "../src/bin/tools/crawl";
|
import { crawl } from "../src/bin/tools/crawl";
|
||||||
import { downloadBuiltinKeycloakTheme } from "../src/bin/download-builtin-keycloak-theme";
|
import { downloadBuiltinKeycloakTheme } from "../src/bin/shared/downloadBuiltinKeycloakTheme";
|
||||||
import { getThisCodebaseRootDirPath } from "../src/bin/tools/getThisCodebaseRootDirPath";
|
import { getThisCodebaseRootDirPath } from "../src/bin/tools/getThisCodebaseRootDirPath";
|
||||||
import { getLogger } from "../src/bin/tools/logger";
|
import { getLogger } from "../src/bin/tools/logger";
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { nameOfTheGlobal, basenameOfTheKeycloakifyResourcesDir } from "keycloakify/bin/constants";
|
import { nameOfTheGlobal, basenameOfTheKeycloakifyResourcesDir } from "keycloakify/bin/shared/constants";
|
||||||
import { assert } from "tsafe/assert";
|
import { assert } from "tsafe/assert";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -4,7 +4,7 @@ export default Fallback;
|
|||||||
|
|
||||||
export { getKcContext } from "keycloakify/account/kcContext/getKcContext";
|
export { getKcContext } from "keycloakify/account/kcContext/getKcContext";
|
||||||
export { createGetKcContext } from "keycloakify/account/kcContext/createGetKcContext";
|
export { createGetKcContext } from "keycloakify/account/kcContext/createGetKcContext";
|
||||||
export type { AccountThemePageId as PageId } from "keycloakify/bin/keycloakify/generateFtl";
|
export type { AccountThemePageId as PageId } from "keycloakify/bin/shared/pageIds";
|
||||||
export { createUseI18n } from "keycloakify/account/i18n/i18n";
|
export { createUseI18n } from "keycloakify/account/i18n/i18n";
|
||||||
|
|
||||||
export type { PageProps } from "keycloakify/account/pages/PageProps";
|
export type { PageProps } from "keycloakify/account/pages/PageProps";
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import type { AccountThemePageId } from "keycloakify/bin/keycloakify/generateFtl";
|
import type { AccountThemePageId } from "keycloakify/bin/shared/pageIds";
|
||||||
import { assert } from "tsafe/assert";
|
import { assert } from "tsafe/assert";
|
||||||
import type { Equals } from "tsafe";
|
import type { Equals } from "tsafe";
|
||||||
import { type ThemeType } from "keycloakify/bin/constants";
|
import { type ThemeType } from "keycloakify/bin/shared/constants";
|
||||||
|
|
||||||
export type KcContext =
|
export type KcContext =
|
||||||
| KcContext.Password
|
| KcContext.Password
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import type { AndByDiscriminatingKey } from "keycloakify/tools/AndByDiscriminatingKey";
|
import type { AndByDiscriminatingKey } from "keycloakify/tools/AndByDiscriminatingKey";
|
||||||
import { nameOfTheGlobal } from "keycloakify/bin/constants";
|
import { nameOfTheGlobal } from "keycloakify/bin/shared/constants";
|
||||||
import type { KcContext } from "./KcContext";
|
import type { KcContext } from "./KcContext";
|
||||||
|
|
||||||
export type ExtendKcContext<KcContextExtension extends { pageId: string }> = [KcContextExtension] extends [never]
|
export type ExtendKcContext<KcContextExtension extends { pageId: string }> = [KcContextExtension] extends [never]
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import "minimal-polyfills/Object.fromEntries";
|
import "minimal-polyfills/Object.fromEntries";
|
||||||
import { resources_common, keycloak_resources } from "keycloakify/bin/constants";
|
import { resources_common, keycloak_resources } from "keycloakify/bin/shared/constants";
|
||||||
import { id } from "tsafe/id";
|
import { id } from "tsafe/id";
|
||||||
import type { KcContext } from "./KcContext";
|
import type { KcContext } from "./KcContext";
|
||||||
import { BASE_URL } from "keycloakify/lib/BASE_URL";
|
import { BASE_URL } from "keycloakify/lib/BASE_URL";
|
||||||
|
@ -1,112 +1,16 @@
|
|||||||
#!/usr/bin/env node
|
import { copyKeycloakResourcesToPublic } from "./shared/copyKeycloakResourcesToPublic";
|
||||||
|
import { readBuildOptions } from "./shared/buildOptions";
|
||||||
|
import type { CliCommandOptions } from "./main";
|
||||||
|
|
||||||
import { downloadKeycloakStaticResources, type BuildOptionsLike } from "./keycloakify/generateTheme/downloadKeycloakStaticResources";
|
export async function command(params: { cliCommandOptions: CliCommandOptions }) {
|
||||||
import { join as pathJoin, relative as pathRelative } from "path";
|
const { cliCommandOptions } = params;
|
||||||
import { readBuildOptions } from "./keycloakify/buildOptions";
|
|
||||||
import { themeTypes, keycloak_resources, lastKeycloakVersionWithAccountV1 } from "./constants";
|
|
||||||
import { readThisNpmProjectVersion } from "./tools/readThisNpmProjectVersion";
|
|
||||||
import { assert, type Equals } from "tsafe/assert";
|
|
||||||
import * as fs from "fs";
|
|
||||||
import { rmSync } from "./tools/fs.rmSync";
|
|
||||||
|
|
||||||
export async function copyKeycloakResourcesToPublic(params: { processArgv: string[] }) {
|
const buildOptions = readBuildOptions({ cliCommandOptions });
|
||||||
const { processArgv } = params;
|
|
||||||
|
|
||||||
const buildOptions = readBuildOptions({ processArgv });
|
|
||||||
|
|
||||||
const destDirPath = pathJoin(buildOptions.publicDirPath, keycloak_resources);
|
|
||||||
|
|
||||||
const keycloakifyBuildinfoFilePath = pathJoin(destDirPath, "keycloakify.buildinfo");
|
|
||||||
|
|
||||||
const { keycloakifyBuildinfoRaw } = generateKeycloakifyBuildinfoRaw({
|
|
||||||
destDirPath,
|
|
||||||
"keycloakifyVersion": readThisNpmProjectVersion(),
|
|
||||||
buildOptions
|
|
||||||
});
|
|
||||||
|
|
||||||
skip_if_already_done: {
|
|
||||||
if (!fs.existsSync(keycloakifyBuildinfoFilePath)) {
|
|
||||||
break skip_if_already_done;
|
|
||||||
}
|
|
||||||
|
|
||||||
const keycloakifyBuildinfoRaw_previousRun = fs.readFileSync(keycloakifyBuildinfoFilePath).toString("utf8");
|
|
||||||
|
|
||||||
if (keycloakifyBuildinfoRaw_previousRun !== keycloakifyBuildinfoRaw) {
|
|
||||||
break skip_if_already_done;
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
rmSync(destDirPath, { "force": true, "recursive": true });
|
|
||||||
|
|
||||||
for (const themeType of themeTypes) {
|
|
||||||
await downloadKeycloakStaticResources({
|
|
||||||
"keycloakVersion": (() => {
|
|
||||||
switch (themeType) {
|
|
||||||
case "login":
|
|
||||||
return buildOptions.loginThemeResourcesFromKeycloakVersion;
|
|
||||||
case "account":
|
|
||||||
return lastKeycloakVersionWithAccountV1;
|
|
||||||
}
|
|
||||||
})(),
|
|
||||||
themeType,
|
|
||||||
"themeDirPath": destDirPath,
|
|
||||||
buildOptions
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
fs.writeFileSync(
|
|
||||||
pathJoin(destDirPath, "README.txt"),
|
|
||||||
Buffer.from(
|
|
||||||
// prettier-ignore
|
|
||||||
[
|
|
||||||
"This is just a test folder that helps develop",
|
|
||||||
"the login and register page without having to run a Keycloak container"
|
|
||||||
].join(" ")
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
fs.writeFileSync(pathJoin(buildOptions.publicDirPath, keycloak_resources, ".gitignore"), Buffer.from("*", "utf8"));
|
|
||||||
|
|
||||||
fs.writeFileSync(keycloakifyBuildinfoFilePath, Buffer.from(keycloakifyBuildinfoRaw, "utf8"));
|
|
||||||
}
|
|
||||||
|
|
||||||
export function generateKeycloakifyBuildinfoRaw(params: {
|
|
||||||
destDirPath: string;
|
|
||||||
keycloakifyVersion: string;
|
|
||||||
buildOptions: BuildOptionsLike & {
|
|
||||||
loginThemeResourcesFromKeycloakVersion: string;
|
|
||||||
};
|
|
||||||
}) {
|
|
||||||
const { destDirPath, keycloakifyVersion, buildOptions } = params;
|
|
||||||
|
|
||||||
const { cacheDirPath, npmWorkspaceRootDirPath, loginThemeResourcesFromKeycloakVersion, ...rest } = buildOptions;
|
|
||||||
|
|
||||||
assert<Equals<typeof rest, {}>>(true);
|
|
||||||
|
|
||||||
const keycloakifyBuildinfoRaw = JSON.stringify(
|
|
||||||
{
|
|
||||||
keycloakifyVersion,
|
|
||||||
"buildOptions": {
|
|
||||||
loginThemeResourcesFromKeycloakVersion,
|
|
||||||
"cacheDirPath": pathRelative(destDirPath, cacheDirPath),
|
|
||||||
"npmWorkspaceRootDirPath": pathRelative(destDirPath, npmWorkspaceRootDirPath)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
null,
|
|
||||||
2
|
|
||||||
);
|
|
||||||
|
|
||||||
return { keycloakifyBuildinfoRaw };
|
|
||||||
}
|
|
||||||
|
|
||||||
async function main() {
|
|
||||||
await copyKeycloakResourcesToPublic({
|
await copyKeycloakResourcesToPublic({
|
||||||
"processArgv": process.argv.slice(2)
|
"buildOptions": {
|
||||||
|
...buildOptions,
|
||||||
|
"publicDirPath": buildOptions.reactAppRootDirPath
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (require.main === module) {
|
|
||||||
main();
|
|
||||||
}
|
|
||||||
|
@ -1,282 +1,24 @@
|
|||||||
#!/usr/bin/env node
|
|
||||||
import { join as pathJoin } from "path";
|
import { join as pathJoin } from "path";
|
||||||
import { downloadAndUnzip } from "./downloadAndUnzip";
|
import { promptKeycloakVersion } from "./shared/promptKeycloakVersion";
|
||||||
import { promptKeycloakVersion } from "./promptKeycloakVersion";
|
import { readBuildOptions } from "./shared/buildOptions";
|
||||||
|
import { downloadBuiltinKeycloakTheme } from "./shared/downloadBuiltinKeycloakTheme";
|
||||||
|
import type { CliCommandOptions } from "./main";
|
||||||
import { getLogger } from "./tools/logger";
|
import { getLogger } from "./tools/logger";
|
||||||
import { readBuildOptions, type BuildOptions } from "./keycloakify/buildOptions";
|
|
||||||
import { assert } from "tsafe/assert";
|
|
||||||
import * as child_process from "child_process";
|
|
||||||
import * as fs from "fs";
|
|
||||||
import { rmSync } from "./tools/fs.rmSync";
|
|
||||||
import { lastKeycloakVersionWithAccountV1 } from "./constants";
|
|
||||||
import { transformCodebase } from "./tools/transformCodebase";
|
|
||||||
|
|
||||||
export type BuildOptionsLike = {
|
export async function command(params: { cliCommandOptions: CliCommandOptions }) {
|
||||||
cacheDirPath: string;
|
const { cliCommandOptions } = params;
|
||||||
npmWorkspaceRootDirPath: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
assert<BuildOptions extends BuildOptionsLike ? true : false>();
|
|
||||||
|
|
||||||
export async function downloadBuiltinKeycloakTheme(params: { keycloakVersion: string; destDirPath: string; buildOptions: BuildOptionsLike }) {
|
|
||||||
const { keycloakVersion, destDirPath, buildOptions } = params;
|
|
||||||
|
|
||||||
await downloadAndUnzip({
|
|
||||||
destDirPath,
|
|
||||||
"url": `https://github.com/keycloak/keycloak/archive/refs/tags/${keycloakVersion}.zip`,
|
|
||||||
"specificDirsToExtract": ["", "-community"].map(ext => `keycloak-${keycloakVersion}/themes/src/main/resources${ext}/theme`),
|
|
||||||
buildOptions,
|
|
||||||
"preCacheTransform": {
|
|
||||||
"actionCacheId": "npm install and build",
|
|
||||||
"action": async ({ destDirPath }) => {
|
|
||||||
install_common_node_modules: {
|
|
||||||
const commonResourcesDirPath = pathJoin(destDirPath, "keycloak", "common", "resources");
|
|
||||||
|
|
||||||
if (!fs.existsSync(commonResourcesDirPath)) {
|
|
||||||
break install_common_node_modules;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!fs.existsSync(pathJoin(commonResourcesDirPath, "package.json"))) {
|
|
||||||
break install_common_node_modules;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fs.existsSync(pathJoin(commonResourcesDirPath, "node_modules"))) {
|
|
||||||
break install_common_node_modules;
|
|
||||||
}
|
|
||||||
|
|
||||||
child_process.execSync("npm install --omit=dev", {
|
|
||||||
"cwd": commonResourcesDirPath,
|
|
||||||
"stdio": "ignore"
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
repatriate_common_resources_from_base_login_theme: {
|
|
||||||
const baseLoginThemeResourceDir = pathJoin(destDirPath, "base", "login", "resources");
|
|
||||||
|
|
||||||
if (!fs.existsSync(baseLoginThemeResourceDir)) {
|
|
||||||
break repatriate_common_resources_from_base_login_theme;
|
|
||||||
}
|
|
||||||
|
|
||||||
transformCodebase({
|
|
||||||
"srcDirPath": baseLoginThemeResourceDir,
|
|
||||||
"destDirPath": pathJoin(destDirPath, "keycloak", "login", "resources")
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
install_and_move_to_common_resources_generated_in_keycloak_v2: {
|
|
||||||
if (!fs.readFileSync(pathJoin(destDirPath, "keycloak", "login", "theme.properties")).toString("utf8").includes("web_modules")) {
|
|
||||||
break install_and_move_to_common_resources_generated_in_keycloak_v2;
|
|
||||||
}
|
|
||||||
|
|
||||||
const accountV2DirSrcDirPath = pathJoin(destDirPath, "keycloak.v2", "account", "src");
|
|
||||||
|
|
||||||
if (!fs.existsSync(accountV2DirSrcDirPath)) {
|
|
||||||
break install_and_move_to_common_resources_generated_in_keycloak_v2;
|
|
||||||
}
|
|
||||||
|
|
||||||
const packageManager = fs.existsSync(pathJoin(accountV2DirSrcDirPath, "pnpm-lock.yaml")) ? "pnpm" : "npm";
|
|
||||||
|
|
||||||
if (packageManager === "pnpm") {
|
|
||||||
try {
|
|
||||||
child_process.execSync(`which pnpm`);
|
|
||||||
} catch {
|
|
||||||
console.log(`Installing pnpm globally`);
|
|
||||||
child_process.execSync(`npm install -g pnpm`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
child_process.execSync(`${packageManager} install`, { "cwd": accountV2DirSrcDirPath, "stdio": "ignore" });
|
|
||||||
|
|
||||||
const packageJsonFilePath = pathJoin(accountV2DirSrcDirPath, "package.json");
|
|
||||||
|
|
||||||
const packageJsonRaw = fs.readFileSync(packageJsonFilePath);
|
|
||||||
|
|
||||||
const parsedPackageJson = JSON.parse(packageJsonRaw.toString("utf8"));
|
|
||||||
|
|
||||||
parsedPackageJson.scripts.build = parsedPackageJson.scripts.build
|
|
||||||
.replace(`${packageManager} run check-types`, "true")
|
|
||||||
.replace(`${packageManager} run babel`, "true");
|
|
||||||
|
|
||||||
fs.writeFileSync(packageJsonFilePath, Buffer.from(JSON.stringify(parsedPackageJson, null, 2), "utf8"));
|
|
||||||
|
|
||||||
child_process.execSync(`${packageManager} run build`, { "cwd": accountV2DirSrcDirPath, "stdio": "ignore" });
|
|
||||||
|
|
||||||
fs.writeFileSync(packageJsonFilePath, packageJsonRaw);
|
|
||||||
|
|
||||||
fs.rmSync(pathJoin(accountV2DirSrcDirPath, "node_modules"), { "recursive": true });
|
|
||||||
}
|
|
||||||
|
|
||||||
remove_keycloak_v2: {
|
|
||||||
const keycloakV2DirPath = pathJoin(destDirPath, "keycloak.v2");
|
|
||||||
|
|
||||||
if (!fs.existsSync(keycloakV2DirPath)) {
|
|
||||||
break remove_keycloak_v2;
|
|
||||||
}
|
|
||||||
|
|
||||||
rmSync(keycloakV2DirPath, { "recursive": true });
|
|
||||||
}
|
|
||||||
|
|
||||||
// Note, this is an optimization for reducing the size of the jar
|
|
||||||
remove_unused_node_modules: {
|
|
||||||
const nodeModuleDirPath = pathJoin(destDirPath, "keycloak", "common", "resources", "node_modules");
|
|
||||||
|
|
||||||
if (!fs.existsSync(nodeModuleDirPath)) {
|
|
||||||
break remove_unused_node_modules;
|
|
||||||
}
|
|
||||||
|
|
||||||
const toDeletePerfixes = [
|
|
||||||
"angular",
|
|
||||||
"bootstrap",
|
|
||||||
"rcue",
|
|
||||||
"font-awesome",
|
|
||||||
"ng-file-upload",
|
|
||||||
pathJoin("patternfly", "dist", "sass"),
|
|
||||||
pathJoin("patternfly", "dist", "less"),
|
|
||||||
pathJoin("patternfly", "dist", "js"),
|
|
||||||
"d3",
|
|
||||||
pathJoin("jquery", "src"),
|
|
||||||
"c3",
|
|
||||||
"core-js",
|
|
||||||
"eonasdan-bootstrap-datetimepicker",
|
|
||||||
"moment",
|
|
||||||
"react",
|
|
||||||
"patternfly-bootstrap-treeview",
|
|
||||||
"popper.js",
|
|
||||||
"tippy.js",
|
|
||||||
"jquery-match-height",
|
|
||||||
"google-code-prettify",
|
|
||||||
"patternfly-bootstrap-combobox",
|
|
||||||
"focus-trap",
|
|
||||||
"tabbable",
|
|
||||||
"scheduler",
|
|
||||||
"@types",
|
|
||||||
"datatables.net",
|
|
||||||
"datatables.net-colreorder",
|
|
||||||
"tslib",
|
|
||||||
"prop-types",
|
|
||||||
"file-selector",
|
|
||||||
"datatables.net-colreorder-bs",
|
|
||||||
"object-assign",
|
|
||||||
"warning",
|
|
||||||
"js-tokens",
|
|
||||||
"loose-envify",
|
|
||||||
"prop-types-extra",
|
|
||||||
"attr-accept",
|
|
||||||
"datatables.net-select",
|
|
||||||
"drmonty-datatables-colvis",
|
|
||||||
"datatables.net-bs",
|
|
||||||
pathJoin("@patternfly", "react"),
|
|
||||||
pathJoin("@patternfly", "patternfly", "docs")
|
|
||||||
];
|
|
||||||
|
|
||||||
transformCodebase({
|
|
||||||
"srcDirPath": nodeModuleDirPath,
|
|
||||||
"destDirPath": nodeModuleDirPath,
|
|
||||||
"transformSourceCode": ({ sourceCode, fileRelativePath }) => {
|
|
||||||
if (fileRelativePath.endsWith(".map")) {
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (toDeletePerfixes.find(prefix => fileRelativePath.startsWith(prefix)) !== undefined) {
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fileRelativePath.startsWith(pathJoin("patternfly", "dist", "fonts"))) {
|
|
||||||
if (
|
|
||||||
!fileRelativePath.endsWith(".woff2") &&
|
|
||||||
!fileRelativePath.endsWith(".woff") &&
|
|
||||||
!fileRelativePath.endsWith(".ttf")
|
|
||||||
) {
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return { "modifiedSourceCode": sourceCode };
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Just like node_modules
|
|
||||||
remove_unused_lib: {
|
|
||||||
const libDirPath = pathJoin(destDirPath, "keycloak", "common", "resources", "lib");
|
|
||||||
|
|
||||||
if (!fs.existsSync(libDirPath)) {
|
|
||||||
break remove_unused_lib;
|
|
||||||
}
|
|
||||||
|
|
||||||
const toDeletePerfixes = ["ui-ace", "filesaver", "fileupload", "angular", "ui-ace"];
|
|
||||||
|
|
||||||
transformCodebase({
|
|
||||||
"srcDirPath": libDirPath,
|
|
||||||
"destDirPath": libDirPath,
|
|
||||||
"transformSourceCode": ({ sourceCode, fileRelativePath }) => {
|
|
||||||
if (fileRelativePath.endsWith(".map")) {
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (toDeletePerfixes.find(prefix => fileRelativePath.startsWith(prefix)) !== undefined) {
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
return { "modifiedSourceCode": sourceCode };
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
last_account_v1_transformations: {
|
|
||||||
if (lastKeycloakVersionWithAccountV1 !== keycloakVersion) {
|
|
||||||
break last_account_v1_transformations;
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
const accountCssFilePath = pathJoin(destDirPath, "keycloak", "account", "resources", "css", "account.css");
|
|
||||||
|
|
||||||
fs.writeFileSync(
|
|
||||||
accountCssFilePath,
|
|
||||||
Buffer.from(fs.readFileSync(accountCssFilePath).toString("utf8").replace("top: -34px;", "top: -34px !important;"), "utf8")
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Note, this is an optimization for reducing the size of the jar,
|
|
||||||
// For this version we know exactly which resources are used.
|
|
||||||
{
|
|
||||||
const nodeModulesDirPath = pathJoin(destDirPath, "keycloak", "common", "resources", "node_modules");
|
|
||||||
|
|
||||||
const toKeepPrefixes = [
|
|
||||||
...["patternfly.min.css", "patternfly-additions.min.css", "patternfly-additions.min.css"].map(fileBasename =>
|
|
||||||
pathJoin("patternfly", "dist", "css", fileBasename)
|
|
||||||
),
|
|
||||||
pathJoin("patternfly", "dist", "fonts")
|
|
||||||
];
|
|
||||||
|
|
||||||
transformCodebase({
|
|
||||||
"srcDirPath": nodeModulesDirPath,
|
|
||||||
"destDirPath": nodeModulesDirPath,
|
|
||||||
"transformSourceCode": ({ sourceCode, fileRelativePath }) => {
|
|
||||||
if (toKeepPrefixes.find(prefix => fileRelativePath.startsWith(prefix)) === undefined) {
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
return { "modifiedSourceCode": sourceCode };
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
async function main() {
|
|
||||||
const buildOptions = readBuildOptions({
|
const buildOptions = readBuildOptions({
|
||||||
"processArgv": process.argv.slice(2)
|
cliCommandOptions
|
||||||
});
|
});
|
||||||
|
|
||||||
const logger = getLogger({ "isSilent": buildOptions.isSilent });
|
const { log } = getLogger({ "isSilent": buildOptions.isSilent });
|
||||||
|
|
||||||
const { keycloakVersion } = await promptKeycloakVersion();
|
const { keycloakVersion } = await promptKeycloakVersion();
|
||||||
|
|
||||||
const destDirPath = pathJoin(buildOptions.keycloakifyBuildDirPath, "src", "main", "resources", "theme");
|
const destDirPath = pathJoin(buildOptions.keycloakifyBuildDirPath, "src", "main", "resources", "theme");
|
||||||
|
|
||||||
logger.log(`Downloading builtins theme of Keycloak ${keycloakVersion} here ${destDirPath}`);
|
log(`Downloading builtins theme of Keycloak ${keycloakVersion} here ${destDirPath}`);
|
||||||
|
|
||||||
await downloadBuiltinKeycloakTheme({
|
await downloadBuiltinKeycloakTheme({
|
||||||
keycloakVersion,
|
keycloakVersion,
|
||||||
@ -284,7 +26,3 @@ async function main() {
|
|||||||
buildOptions
|
buildOptions
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (require.main === module) {
|
|
||||||
main();
|
|
||||||
}
|
|
||||||
|
@ -2,24 +2,27 @@
|
|||||||
|
|
||||||
import { getThisCodebaseRootDirPath } from "./tools/getThisCodebaseRootDirPath";
|
import { getThisCodebaseRootDirPath } from "./tools/getThisCodebaseRootDirPath";
|
||||||
import cliSelect from "cli-select";
|
import cliSelect from "cli-select";
|
||||||
import { loginThemePageIds, accountThemePageIds, type LoginThemePageId, type AccountThemePageId } from "./keycloakify/generateFtl";
|
import { loginThemePageIds, accountThemePageIds, type LoginThemePageId, type AccountThemePageId } from "./shared/pageIds";
|
||||||
import { capitalize } from "tsafe/capitalize";
|
import { capitalize } from "tsafe/capitalize";
|
||||||
import { readFile, writeFile } from "fs/promises";
|
import { readFile, writeFile } from "fs/promises";
|
||||||
import { existsSync } from "fs";
|
import { existsSync } from "fs";
|
||||||
import { join as pathJoin, relative as pathRelative } from "path";
|
import { join as pathJoin, relative as pathRelative } from "path";
|
||||||
import { kebabCaseToCamelCase } from "./tools/kebabCaseToSnakeCase";
|
import { kebabCaseToCamelCase } from "./tools/kebabCaseToSnakeCase";
|
||||||
import { assert, Equals } from "tsafe/assert";
|
import { assert, Equals } from "tsafe/assert";
|
||||||
import { getThemeSrcDirPath } from "./getThemeSrcDirPath";
|
import { getThemeSrcDirPath } from "./shared/getThemeSrcDirPath";
|
||||||
import { themeTypes, type ThemeType } from "./constants";
|
import { themeTypes, type ThemeType } from "./shared/constants";
|
||||||
import { getReactAppRootDirPath } from "./keycloakify/buildOptions/getReactAppRootDirPath";
|
import type { CliCommandOptions } from "./main";
|
||||||
|
import { readBuildOptions } from "./shared/buildOptions";
|
||||||
|
|
||||||
(async () => {
|
export async function command(params: { cliCommandOptions: CliCommandOptions }) {
|
||||||
console.log("Select a theme type");
|
const { cliCommandOptions } = params;
|
||||||
|
|
||||||
const { reactAppRootDirPath } = getReactAppRootDirPath({
|
const buildOptions = readBuildOptions({
|
||||||
"processArgv": process.argv.slice(2)
|
cliCommandOptions
|
||||||
});
|
});
|
||||||
|
|
||||||
|
console.log("Select a theme type");
|
||||||
|
|
||||||
const { value: themeType } = await cliSelect<ThemeType>({
|
const { value: themeType } = await cliSelect<ThemeType>({
|
||||||
"values": [...themeTypes]
|
"values": [...themeTypes]
|
||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
@ -48,7 +51,7 @@ import { getReactAppRootDirPath } from "./keycloakify/buildOptions/getReactAppRo
|
|||||||
|
|
||||||
const pageBasename = capitalize(kebabCaseToCamelCase(pageId)).replace(/ftl$/, "tsx");
|
const pageBasename = capitalize(kebabCaseToCamelCase(pageId)).replace(/ftl$/, "tsx");
|
||||||
|
|
||||||
const { themeSrcDirPath } = getThemeSrcDirPath({ reactAppRootDirPath });
|
const { themeSrcDirPath } = getThemeSrcDirPath({ "reactAppRootDirPath": buildOptions.reactAppRootDirPath });
|
||||||
|
|
||||||
const targetFilePath = pathJoin(themeSrcDirPath, themeType, "pages", pageBasename);
|
const targetFilePath = pathJoin(themeSrcDirPath, themeType, "pages", pageBasename);
|
||||||
|
|
||||||
@ -61,4 +64,4 @@ import { getReactAppRootDirPath } from "./keycloakify/buildOptions/getReactAppRo
|
|||||||
await writeFile(targetFilePath, await readFile(pathJoin(getThisCodebaseRootDirPath(), "src", themeType, "pages", pageBasename)));
|
await writeFile(targetFilePath, await readFile(pathJoin(getThisCodebaseRootDirPath(), "src", themeType, "pages", pageBasename)));
|
||||||
|
|
||||||
console.log(`${pathRelative(process.cwd(), targetFilePath)} created`);
|
console.log(`${pathRelative(process.cwd(), targetFilePath)} created`);
|
||||||
})();
|
}
|
||||||
|
@ -1,19 +1,18 @@
|
|||||||
#!/usr/bin/env node
|
import { downloadBuiltinKeycloakTheme } from "./shared/downloadBuiltinKeycloakTheme";
|
||||||
|
|
||||||
import { downloadBuiltinKeycloakTheme } from "./download-builtin-keycloak-theme";
|
|
||||||
import { join as pathJoin, relative as pathRelative } from "path";
|
import { join as pathJoin, relative as pathRelative } from "path";
|
||||||
import { transformCodebase } from "./tools/transformCodebase";
|
import { transformCodebase } from "./tools/transformCodebase";
|
||||||
import { promptKeycloakVersion } from "./promptKeycloakVersion";
|
import { promptKeycloakVersion } from "./shared/promptKeycloakVersion";
|
||||||
import { readBuildOptions } from "./keycloakify/buildOptions";
|
import { readBuildOptions } from "./shared/buildOptions";
|
||||||
import * as fs from "fs";
|
import * as fs from "fs";
|
||||||
import { getLogger } from "./tools/logger";
|
import { getLogger } from "./tools/logger";
|
||||||
import { getThemeSrcDirPath } from "./getThemeSrcDirPath";
|
import { getThemeSrcDirPath } from "./shared/getThemeSrcDirPath";
|
||||||
import { rmSync } from "./tools/fs.rmSync";
|
import { rmSync } from "./tools/fs.rmSync";
|
||||||
|
import type { CliCommandOptions } from "./main";
|
||||||
|
|
||||||
export async function main() {
|
export async function command(params: { cliCommandOptions: CliCommandOptions }) {
|
||||||
const buildOptions = readBuildOptions({
|
const { cliCommandOptions } = params;
|
||||||
"processArgv": process.argv.slice(2)
|
|
||||||
});
|
const buildOptions = readBuildOptions({ cliCommandOptions });
|
||||||
|
|
||||||
const logger = getLogger({ "isSilent": buildOptions.isSilent });
|
const logger = getLogger({ "isSilent": buildOptions.isSilent });
|
||||||
|
|
||||||
@ -54,7 +53,3 @@ export async function main() {
|
|||||||
|
|
||||||
rmSync(builtinKeycloakThemeTmpDirPath, { "recursive": true, "force": true });
|
rmSync(builtinKeycloakThemeTmpDirPath, { "recursive": true, "force": true });
|
||||||
}
|
}
|
||||||
|
|
||||||
if (require.main === module) {
|
|
||||||
main();
|
|
||||||
}
|
|
||||||
|
@ -2,9 +2,9 @@ import { assert, type Equals } from "tsafe/assert";
|
|||||||
import type { KeycloakAccountV1Version, KeycloakThemeAdditionalInfoExtensionVersion } from "./extensionVersions";
|
import type { KeycloakAccountV1Version, KeycloakThemeAdditionalInfoExtensionVersion } from "./extensionVersions";
|
||||||
import { join as pathJoin, dirname as pathDirname } from "path";
|
import { join as pathJoin, dirname as pathDirname } from "path";
|
||||||
import { transformCodebase } from "../../tools/transformCodebase";
|
import { transformCodebase } from "../../tools/transformCodebase";
|
||||||
import type { BuildOptions } from "../buildOptions";
|
import type { BuildOptions } from "../../shared/buildOptions";
|
||||||
import * as fs from "fs/promises";
|
import * as fs from "fs/promises";
|
||||||
import { accountV1ThemeName } from "../../constants";
|
import { accountV1ThemeName } from "../../shared/constants";
|
||||||
import { generatePom, BuildOptionsLike as BuildOptionsLike_generatePom } from "./generatePom";
|
import { generatePom, BuildOptionsLike as BuildOptionsLike_generatePom } from "./generatePom";
|
||||||
import { existsSync, readFileSync } from "fs";
|
import { existsSync, readFileSync } from "fs";
|
||||||
import { isInside } from "../../tools/isInside";
|
import { isInside } from "../../tools/isInside";
|
||||||
|
@ -3,7 +3,7 @@ import { exclude } from "tsafe/exclude";
|
|||||||
import { keycloakAccountV1Versions, keycloakThemeAdditionalInfoExtensionVersions } from "./extensionVersions";
|
import { keycloakAccountV1Versions, keycloakThemeAdditionalInfoExtensionVersions } from "./extensionVersions";
|
||||||
import { getKeycloakVersionRangeForJar } from "./getKeycloakVersionRangeForJar";
|
import { getKeycloakVersionRangeForJar } from "./getKeycloakVersionRangeForJar";
|
||||||
import { buildJar, BuildOptionsLike as BuildOptionsLike_buildJar } from "./buildJar";
|
import { buildJar, BuildOptionsLike as BuildOptionsLike_buildJar } from "./buildJar";
|
||||||
import type { BuildOptions } from "../buildOptions";
|
import type { BuildOptions } from "../../shared/buildOptions";
|
||||||
|
|
||||||
export type BuildOptionsLike = BuildOptionsLike_buildJar & {
|
export type BuildOptionsLike = BuildOptionsLike_buildJar & {
|
||||||
keycloakifyBuildDirPath: string;
|
keycloakifyBuildDirPath: string;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { assert } from "tsafe/assert";
|
import { assert } from "tsafe/assert";
|
||||||
import type { BuildOptions } from "../buildOptions";
|
import type { BuildOptions } from "../../shared/buildOptions";
|
||||||
import type { KeycloakAccountV1Version, KeycloakThemeAdditionalInfoExtensionVersion } from "./extensionVersions";
|
import type { KeycloakAccountV1Version, KeycloakThemeAdditionalInfoExtensionVersion } from "./extensionVersions";
|
||||||
|
|
||||||
export type BuildOptionsLike = {
|
export type BuildOptionsLike = {
|
||||||
|
@ -1,23 +0,0 @@
|
|||||||
import parseArgv from "minimist";
|
|
||||||
import { getAbsoluteAndInOsFormatPath } from "../../tools/getAbsoluteAndInOsFormatPath";
|
|
||||||
|
|
||||||
export function getReactAppRootDirPath(params: { processArgv: string[] }) {
|
|
||||||
const { processArgv } = params;
|
|
||||||
|
|
||||||
const argv = parseArgv(processArgv);
|
|
||||||
|
|
||||||
const reactAppRootDirPath = (() => {
|
|
||||||
const arg = argv["project"] ?? argv["p"];
|
|
||||||
|
|
||||||
if (typeof arg !== "string") {
|
|
||||||
return process.cwd();
|
|
||||||
}
|
|
||||||
|
|
||||||
return getAbsoluteAndInOsFormatPath({
|
|
||||||
"pathIsh": arg,
|
|
||||||
"cwd": process.cwd()
|
|
||||||
});
|
|
||||||
})();
|
|
||||||
|
|
||||||
return { reactAppRootDirPath };
|
|
||||||
}
|
|
@ -1 +0,0 @@
|
|||||||
export * from "./buildOptions";
|
|
@ -4,9 +4,9 @@ import { generateCssCodeToDefineGlobals } from "../replacers/replaceImportsInCss
|
|||||||
import { replaceImportsInInlineCssCode } from "../replacers/replaceImportsInInlineCssCode";
|
import { replaceImportsInInlineCssCode } from "../replacers/replaceImportsInInlineCssCode";
|
||||||
import * as fs from "fs";
|
import * as fs from "fs";
|
||||||
import { join as pathJoin } from "path";
|
import { join as pathJoin } from "path";
|
||||||
import type { BuildOptions } from "../buildOptions";
|
import type { BuildOptions } from "../../shared/buildOptions";
|
||||||
import { assert } from "tsafe/assert";
|
import { assert } from "tsafe/assert";
|
||||||
import { type ThemeType, nameOfTheGlobal, basenameOfTheKeycloakifyResourcesDir, resources_common } from "../../constants";
|
import { type ThemeType, nameOfTheGlobal, basenameOfTheKeycloakifyResourcesDir, resources_common } from "../../shared/constants";
|
||||||
|
|
||||||
export type BuildOptionsLike = {
|
export type BuildOptionsLike = {
|
||||||
bundler: "vite" | "webpack";
|
bundler: "vite" | "webpack";
|
||||||
|
@ -1,2 +1 @@
|
|||||||
export * from "./generateFtl";
|
export * from "./generateFtl";
|
||||||
export * from "./pageId";
|
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
import * as fs from "fs";
|
import * as fs from "fs";
|
||||||
import { join as pathJoin, relative as pathRelative, basename as pathBasename } from "path";
|
import { join as pathJoin, relative as pathRelative, basename as pathBasename } from "path";
|
||||||
import { assert } from "tsafe/assert";
|
import { assert } from "tsafe/assert";
|
||||||
import type { BuildOptions } from "./buildOptions";
|
import type { BuildOptions } from "../shared/buildOptions";
|
||||||
import { accountV1ThemeName } from "../constants";
|
import { accountV1ThemeName } from "../shared/constants";
|
||||||
|
|
||||||
export type BuildOptionsLike = {
|
export type BuildOptionsLike = {
|
||||||
keycloakifyBuildDirPath: string;
|
keycloakifyBuildDirPath: string;
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
import * as fs from "fs";
|
import * as fs from "fs";
|
||||||
import { join as pathJoin } from "path";
|
import { join as pathJoin } from "path";
|
||||||
import { assert } from "tsafe/assert";
|
import { assert } from "tsafe/assert";
|
||||||
import type { BuildOptions } from "../buildOptions";
|
import type { BuildOptions } from "../../shared/buildOptions";
|
||||||
import { resources_common, lastKeycloakVersionWithAccountV1, accountV1ThemeName } from "../../constants";
|
import { resources_common, lastKeycloakVersionWithAccountV1, accountV1ThemeName } from "../../shared/constants";
|
||||||
import { downloadBuiltinKeycloakTheme } from "../../download-builtin-keycloak-theme";
|
import { downloadBuiltinKeycloakTheme } from "../../shared/downloadBuiltinKeycloakTheme";
|
||||||
import { transformCodebase } from "../../tools/transformCodebase";
|
import { transformCodebase } from "../../tools/transformCodebase";
|
||||||
import { rmSync } from "../../tools/fs.rmSync";
|
import { rmSync } from "../../tools/fs.rmSync";
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import type { ThemeType } from "../../constants";
|
import type { ThemeType } from "../../shared/constants";
|
||||||
import { crawl } from "../../tools/crawl";
|
import { crawl } from "../../tools/crawl";
|
||||||
import { join as pathJoin } from "path";
|
import { join as pathJoin } from "path";
|
||||||
import { readFileSync } from "fs";
|
import { readFileSync } from "fs";
|
||||||
|
@ -3,18 +3,19 @@ import * as fs from "fs";
|
|||||||
import { join as pathJoin, resolve as pathResolve, dirname as pathDirname } from "path";
|
import { join as pathJoin, resolve as pathResolve, dirname as pathDirname } from "path";
|
||||||
import { replaceImportsInJsCode } from "../replacers/replaceImportsInJsCode";
|
import { replaceImportsInJsCode } from "../replacers/replaceImportsInJsCode";
|
||||||
import { replaceImportsInCssCode } from "../replacers/replaceImportsInCssCode";
|
import { replaceImportsInCssCode } from "../replacers/replaceImportsInCssCode";
|
||||||
import { generateFtlFilesCodeFactory, loginThemePageIds, accountThemePageIds } from "../generateFtl";
|
import { generateFtlFilesCodeFactory } from "../generateFtl";
|
||||||
|
import { loginThemePageIds, accountThemePageIds } from "../../shared/pageIds";
|
||||||
import {
|
import {
|
||||||
type ThemeType,
|
type ThemeType,
|
||||||
lastKeycloakVersionWithAccountV1,
|
lastKeycloakVersionWithAccountV1,
|
||||||
keycloak_resources,
|
keycloak_resources,
|
||||||
accountV1ThemeName,
|
accountV1ThemeName,
|
||||||
basenameOfTheKeycloakifyResourcesDir
|
basenameOfTheKeycloakifyResourcesDir
|
||||||
} from "../../constants";
|
} from "../../shared/constants";
|
||||||
import { isInside } from "../../tools/isInside";
|
import { isInside } from "../../tools/isInside";
|
||||||
import type { BuildOptions } from "../buildOptions";
|
import type { BuildOptions } from "../../shared/buildOptions";
|
||||||
import { assert, type Equals } from "tsafe/assert";
|
import { assert, type Equals } from "tsafe/assert";
|
||||||
import { downloadKeycloakStaticResources } from "./downloadKeycloakStaticResources";
|
import { downloadKeycloakStaticResources } from "../../shared/downloadKeycloakStaticResources";
|
||||||
import { readFieldNameUsage } from "./readFieldNameUsage";
|
import { readFieldNameUsage } from "./readFieldNameUsage";
|
||||||
import { readExtraPagesNames } from "./readExtraPageNames";
|
import { readExtraPagesNames } from "./readExtraPageNames";
|
||||||
import { generateMessageProperties } from "./generateMessageProperties";
|
import { generateMessageProperties } from "./generateMessageProperties";
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { join as pathJoin } from "path";
|
import { join as pathJoin } from "path";
|
||||||
import type { BuildOptions } from "../buildOptions";
|
import type { BuildOptions } from "../../shared/buildOptions";
|
||||||
import { assert } from "tsafe/assert";
|
import { assert } from "tsafe/assert";
|
||||||
import { generateSrcMainResources, type BuildOptionsLike as BuildOptionsLike_generateSrcMainResources } from "./generateSrcMainResources";
|
import { generateSrcMainResources, type BuildOptionsLike as BuildOptionsLike_generateSrcMainResources } from "./generateSrcMainResources";
|
||||||
import { generateThemeVariations } from "./generateThemeVariants";
|
import { generateThemeVariations } from "./generateThemeVariants";
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
import { crawl } from "../../tools/crawl";
|
import { crawl } from "../../tools/crawl";
|
||||||
import { accountThemePageIds, loginThemePageIds } from "../generateFtl";
|
import { accountThemePageIds, loginThemePageIds } from "../../shared/pageIds";
|
||||||
import { id } from "tsafe/id";
|
import { id } from "tsafe/id";
|
||||||
import { removeDuplicates } from "evt/tools/reducers/removeDuplicates";
|
import { removeDuplicates } from "evt/tools/reducers/removeDuplicates";
|
||||||
import * as fs from "fs";
|
import * as fs from "fs";
|
||||||
import { join as pathJoin } from "path";
|
import { join as pathJoin } from "path";
|
||||||
import type { ThemeType } from "../../constants";
|
import type { ThemeType } from "../../shared/constants";
|
||||||
|
|
||||||
export function readExtraPagesNames(params: { themeSrcDirPath: string; themeType: ThemeType }): string[] {
|
export function readExtraPagesNames(params: { themeSrcDirPath: string; themeType: ThemeType }): string[] {
|
||||||
const { themeSrcDirPath, themeType } = params;
|
const { themeSrcDirPath, themeType } = params;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { crawl } from "../../tools/crawl";
|
import { crawl } from "../../tools/crawl";
|
||||||
import { join as pathJoin } from "path";
|
import { join as pathJoin } from "path";
|
||||||
import * as fs from "fs";
|
import * as fs from "fs";
|
||||||
import type { ThemeType } from "../../constants";
|
import type { ThemeType } from "../../shared/constants";
|
||||||
|
|
||||||
/** Assumes the theme type exists */
|
/** Assumes the theme type exists */
|
||||||
export function readFieldNameUsage(params: { keycloakifySrcDirPath: string; themeSrcDirPath: string; themeType: ThemeType }): string[] {
|
export function readFieldNameUsage(params: { keycloakifySrcDirPath: string; themeSrcDirPath: string; themeType: ThemeType }): string[] {
|
||||||
|
@ -1,8 +1 @@
|
|||||||
#!/usr/bin/env node
|
|
||||||
|
|
||||||
export * from "./keycloakify";
|
export * from "./keycloakify";
|
||||||
import { main } from "./keycloakify";
|
|
||||||
|
|
||||||
if (require.main === module) {
|
|
||||||
main();
|
|
||||||
}
|
|
||||||
|
@ -3,18 +3,19 @@ import { join as pathJoin, relative as pathRelative, sep as pathSep } from "path
|
|||||||
import * as child_process from "child_process";
|
import * as child_process from "child_process";
|
||||||
import { generateStartKeycloakTestingContainer } from "./generateStartKeycloakTestingContainer";
|
import { generateStartKeycloakTestingContainer } from "./generateStartKeycloakTestingContainer";
|
||||||
import * as fs from "fs";
|
import * as fs from "fs";
|
||||||
import { readBuildOptions } from "./buildOptions";
|
import { readBuildOptions } from "../shared/buildOptions";
|
||||||
import { getLogger } from "../tools/logger";
|
import { getLogger } from "../tools/logger";
|
||||||
import { getThemeSrcDirPath } from "../getThemeSrcDirPath";
|
import { getThemeSrcDirPath } from "../shared/getThemeSrcDirPath";
|
||||||
import { getThisCodebaseRootDirPath } from "../tools/getThisCodebaseRootDirPath";
|
import { getThisCodebaseRootDirPath } from "../tools/getThisCodebaseRootDirPath";
|
||||||
import { readThisNpmProjectVersion } from "../tools/readThisNpmProjectVersion";
|
import { readThisNpmProjectVersion } from "../tools/readThisNpmProjectVersion";
|
||||||
import { keycloakifyBuildOptionsForPostPostBuildScriptEnvName } from "../constants";
|
import { vitePluginSubScriptEnvNames } from "../shared/constants";
|
||||||
import { buildJars } from "./buildJars";
|
import { buildJars } from "./buildJars";
|
||||||
|
import type { CliCommandOptions } from "../main";
|
||||||
|
|
||||||
export async function main() {
|
export async function command(params: { cliCommandOptions: CliCommandOptions }) {
|
||||||
const buildOptions = readBuildOptions({
|
const { cliCommandOptions } = params;
|
||||||
"processArgv": process.argv.slice(2)
|
|
||||||
});
|
const buildOptions = readBuildOptions({ cliCommandOptions });
|
||||||
|
|
||||||
const logger = getLogger({ "isSilent": buildOptions.isSilent });
|
const logger = getLogger({ "isSilent": buildOptions.isSilent });
|
||||||
logger.log("🔏 Building the keycloak theme...⌚");
|
logger.log("🔏 Building the keycloak theme...⌚");
|
||||||
@ -45,7 +46,7 @@ export async function main() {
|
|||||||
"cwd": buildOptions.reactAppRootDirPath,
|
"cwd": buildOptions.reactAppRootDirPath,
|
||||||
"env": {
|
"env": {
|
||||||
...process.env,
|
...process.env,
|
||||||
[keycloakifyBuildOptionsForPostPostBuildScriptEnvName]: JSON.stringify(buildOptions)
|
[vitePluginSubScriptEnvNames.runPostBuildScript]: JSON.stringify(buildOptions)
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import * as crypto from "crypto";
|
import * as crypto from "crypto";
|
||||||
import type { BuildOptions } from "../buildOptions";
|
import type { BuildOptions } from "../../shared/buildOptions";
|
||||||
import { assert } from "tsafe/assert";
|
import { assert } from "tsafe/assert";
|
||||||
import { basenameOfTheKeycloakifyResourcesDir } from "../../constants";
|
import { basenameOfTheKeycloakifyResourcesDir } from "../../shared/constants";
|
||||||
|
|
||||||
export type BuildOptionsLike = {
|
export type BuildOptionsLike = {
|
||||||
urlPathname: string | undefined;
|
urlPathname: string | undefined;
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import type { BuildOptions } from "../buildOptions";
|
import type { BuildOptions } from "../../shared/buildOptions";
|
||||||
import { assert } from "tsafe/assert";
|
import { assert } from "tsafe/assert";
|
||||||
import { basenameOfTheKeycloakifyResourcesDir } from "../../constants";
|
import { basenameOfTheKeycloakifyResourcesDir } from "../../shared/constants";
|
||||||
|
|
||||||
export type BuildOptionsLike = {
|
export type BuildOptionsLike = {
|
||||||
urlPathname: string | undefined;
|
urlPathname: string | undefined;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { assert } from "tsafe/assert";
|
import { assert } from "tsafe/assert";
|
||||||
import type { BuildOptions } from "../../buildOptions";
|
import type { BuildOptions } from "../../../shared/buildOptions";
|
||||||
import { replaceImportsInJsCode_vite } from "./vite";
|
import { replaceImportsInJsCode_vite } from "./vite";
|
||||||
import { replaceImportsInJsCode_webpack } from "./webpack";
|
import { replaceImportsInJsCode_webpack } from "./webpack";
|
||||||
import * as fs from "fs";
|
import * as fs from "fs";
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { nameOfTheGlobal, basenameOfTheKeycloakifyResourcesDir } from "../../../constants";
|
import { nameOfTheGlobal, basenameOfTheKeycloakifyResourcesDir } from "../../../shared/constants";
|
||||||
import { assert } from "tsafe/assert";
|
import { assert } from "tsafe/assert";
|
||||||
import type { BuildOptions } from "../../buildOptions";
|
import type { BuildOptions } from "../../../shared/buildOptions";
|
||||||
import * as nodePath from "path";
|
import * as nodePath from "path";
|
||||||
import { replaceAll } from "../../../tools/String.prototype.replaceAll";
|
import { replaceAll } from "../../../tools/String.prototype.replaceAll";
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { nameOfTheGlobal, basenameOfTheKeycloakifyResourcesDir } from "../../../constants";
|
import { nameOfTheGlobal, basenameOfTheKeycloakifyResourcesDir } from "../../../shared/constants";
|
||||||
import { assert } from "tsafe/assert";
|
import { assert } from "tsafe/assert";
|
||||||
import type { BuildOptions } from "../../buildOptions";
|
import type { BuildOptions } from "../../../shared/buildOptions";
|
||||||
import * as nodePath from "path";
|
import * as nodePath from "path";
|
||||||
import { replaceAll } from "../../../tools/String.prototype.replaceAll";
|
import { replaceAll } from "../../../tools/String.prototype.replaceAll";
|
||||||
|
|
||||||
|
87
src/bin/main.ts
Normal file
87
src/bin/main.ts
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
|
||||||
|
import { termost } from "termost";
|
||||||
|
|
||||||
|
export type CliCommandOptions = {
|
||||||
|
isSilent: boolean;
|
||||||
|
reactAppRootDirPath: string | undefined;
|
||||||
|
};
|
||||||
|
|
||||||
|
const program = termost<CliCommandOptions>("keycloakify");
|
||||||
|
|
||||||
|
program
|
||||||
|
.option({
|
||||||
|
"key": "reactAppRootDirPath",
|
||||||
|
"name": { "long": "project", "short": "p" },
|
||||||
|
"description": "https://docs.keycloakify.dev/build-options#project-or-p-cli-option",
|
||||||
|
"defaultValue": undefined
|
||||||
|
})
|
||||||
|
.option({
|
||||||
|
"key": "isSilent",
|
||||||
|
"name": "silent",
|
||||||
|
"description": "https://docs.keycloakify.dev/build-options#silent",
|
||||||
|
"defaultValue": false
|
||||||
|
});
|
||||||
|
|
||||||
|
program
|
||||||
|
.command({
|
||||||
|
"name": "build",
|
||||||
|
"description": "Build the theme (default subcommand)."
|
||||||
|
})
|
||||||
|
.task({
|
||||||
|
"handler": async cliCommandOptions => {
|
||||||
|
const { command } = await import("./keycloakify");
|
||||||
|
return command({ cliCommandOptions });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
program
|
||||||
|
.command({
|
||||||
|
"name": "download-builtin-keycloak-theme",
|
||||||
|
"description": "Download the built-in Keycloak theme."
|
||||||
|
})
|
||||||
|
.task({
|
||||||
|
"handler": async cliCommandOptions => {
|
||||||
|
const { command } = await import("./download-builtin-keycloak-theme");
|
||||||
|
return command({ cliCommandOptions });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
program
|
||||||
|
.command({
|
||||||
|
"name": "eject-keycloak-page",
|
||||||
|
"description": "Eject a Keycloak page."
|
||||||
|
})
|
||||||
|
.task({
|
||||||
|
"handler": async cliCommandOptions => {
|
||||||
|
const { command } = await import("./eject-keycloak-page");
|
||||||
|
return command({ cliCommandOptions });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
program
|
||||||
|
.command({
|
||||||
|
"name": "initialize-email-theme",
|
||||||
|
"description": "Initialize an email theme."
|
||||||
|
})
|
||||||
|
.task({
|
||||||
|
"handler": async cliCommandOptions => {
|
||||||
|
const { command } = await import("./initialize-email-theme");
|
||||||
|
return command({ cliCommandOptions });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
program
|
||||||
|
.command({
|
||||||
|
"name": "copy-keycloak-resources-to-public",
|
||||||
|
"description": [
|
||||||
|
"Copy Keycloak default theme resources to the public directory.",
|
||||||
|
"This command is meant to be explicitly used in Webpack projects only."
|
||||||
|
].join("\n")
|
||||||
|
})
|
||||||
|
.task({
|
||||||
|
"handler": async cliCommandOptions => {
|
||||||
|
const { command } = await import("./copy-keycloak-resources-to-public");
|
||||||
|
return command({ cliCommandOptions });
|
||||||
|
}
|
||||||
|
});
|
@ -1,13 +1,12 @@
|
|||||||
import { parse as urlParse } from "url";
|
import { parse as urlParse } from "url";
|
||||||
import { readParsedPackageJson } from "./parsedPackageJson";
|
import { readParsedPackageJson } from "./parsedPackageJson";
|
||||||
import { join as pathJoin } from "path";
|
import { join as pathJoin } from "path";
|
||||||
import parseArgv from "minimist";
|
|
||||||
import { getAbsoluteAndInOsFormatPath } from "../../tools/getAbsoluteAndInOsFormatPath";
|
import { getAbsoluteAndInOsFormatPath } from "../../tools/getAbsoluteAndInOsFormatPath";
|
||||||
import { readResolvedViteConfig } from "./resolvedViteConfig";
|
import { getResolvedViteConfig } from "./resolvedViteConfig";
|
||||||
import * as fs from "fs";
|
|
||||||
import { getCacheDirPath } from "./getCacheDirPath";
|
import { getCacheDirPath } from "./getCacheDirPath";
|
||||||
import { getReactAppRootDirPath } from "./getReactAppRootDirPath";
|
import { getReactAppRootDirPath } from "./getReactAppRootDirPath";
|
||||||
import { getNpmWorkspaceRootDirPath } from "./getNpmWorkspaceRootDirPath";
|
import { getNpmWorkspaceRootDirPath } from "./getNpmWorkspaceRootDirPath";
|
||||||
|
import type { CliCommandOptions } from "../../main";
|
||||||
|
|
||||||
/** Consolidated build option gathered form CLI arguments and config in package.json */
|
/** Consolidated build option gathered form CLI arguments and config in package.json */
|
||||||
export type BuildOptions = {
|
export type BuildOptions = {
|
||||||
@ -32,18 +31,17 @@ export type BuildOptions = {
|
|||||||
npmWorkspaceRootDirPath: string;
|
npmWorkspaceRootDirPath: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export function readBuildOptions(params: { processArgv: string[] }): BuildOptions {
|
export function readBuildOptions(params: { cliCommandOptions: CliCommandOptions }): BuildOptions {
|
||||||
const { processArgv } = params;
|
const { cliCommandOptions } = params;
|
||||||
|
|
||||||
const { reactAppRootDirPath } = getReactAppRootDirPath({ processArgv });
|
const { reactAppRootDirPath } = getReactAppRootDirPath({ cliCommandOptions });
|
||||||
|
|
||||||
const { cacheDirPath } = getCacheDirPath({ reactAppRootDirPath });
|
const { cacheDirPath } = getCacheDirPath({ reactAppRootDirPath });
|
||||||
|
|
||||||
const { resolvedViteConfig } = readResolvedViteConfig({ cacheDirPath });
|
const { resolvedViteConfig } = getResolvedViteConfig({
|
||||||
|
cacheDirPath,
|
||||||
if (resolvedViteConfig === undefined && fs.existsSync(pathJoin(reactAppRootDirPath, "vite.config.ts"))) {
|
reactAppRootDirPath
|
||||||
throw new Error("Keycloakify's Vite plugin output not found");
|
});
|
||||||
}
|
|
||||||
|
|
||||||
const { keycloakify: userProvidedBuildOptionsFromPackageJson, ...parsedPackageJson } = readParsedPackageJson({ reactAppRootDirPath });
|
const { keycloakify: userProvidedBuildOptionsFromPackageJson, ...parsedPackageJson } = readParsedPackageJson({ reactAppRootDirPath });
|
||||||
|
|
||||||
@ -88,13 +86,11 @@ export function readBuildOptions(params: { processArgv: string[] }): BuildOption
|
|||||||
return pathJoin(reactAppRootDirPath, resolvedViteConfig.buildDir);
|
return pathJoin(reactAppRootDirPath, resolvedViteConfig.buildDir);
|
||||||
})();
|
})();
|
||||||
|
|
||||||
const argv = parseArgv(processArgv);
|
|
||||||
|
|
||||||
const { npmWorkspaceRootDirPath } = getNpmWorkspaceRootDirPath({ reactAppRootDirPath });
|
const { npmWorkspaceRootDirPath } = getNpmWorkspaceRootDirPath({ reactAppRootDirPath });
|
||||||
|
|
||||||
return {
|
return {
|
||||||
"bundler": resolvedViteConfig !== undefined ? "vite" : "webpack",
|
"bundler": resolvedViteConfig !== undefined ? "vite" : "webpack",
|
||||||
"isSilent": typeof argv["silent"] === "boolean" ? argv["silent"] : false,
|
"isSilent": cliCommandOptions.isSilent,
|
||||||
"themeVersion": process.env.KEYCLOAKIFY_THEME_VERSION ?? parsedPackageJson.version ?? "0.0.0",
|
"themeVersion": process.env.KEYCLOAKIFY_THEME_VERSION ?? parsedPackageJson.version ?? "0.0.0",
|
||||||
themeNames,
|
themeNames,
|
||||||
"extraThemeProperties": userProvidedBuildOptions.extraThemeProperties,
|
"extraThemeProperties": userProvidedBuildOptions.extraThemeProperties,
|
26
src/bin/shared/buildOptions/getReactAppRootDirPath.ts
Normal file
26
src/bin/shared/buildOptions/getReactAppRootDirPath.ts
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
import { getAbsoluteAndInOsFormatPath } from "../../tools/getAbsoluteAndInOsFormatPath";
|
||||||
|
import { assert } from "tsafe/assert";
|
||||||
|
import type { CliCommandOptions } from "../../main";
|
||||||
|
|
||||||
|
type CliCommandOptionsLike = {
|
||||||
|
reactAppRootDirPath: string | undefined;
|
||||||
|
};
|
||||||
|
|
||||||
|
assert<CliCommandOptions extends CliCommandOptionsLike ? true : false>();
|
||||||
|
|
||||||
|
export function getReactAppRootDirPath(params: { cliCommandOptions: CliCommandOptionsLike }) {
|
||||||
|
const { cliCommandOptions } = params;
|
||||||
|
|
||||||
|
const reactAppRootDirPath = (() => {
|
||||||
|
if (cliCommandOptions.reactAppRootDirPath === undefined) {
|
||||||
|
return process.cwd();
|
||||||
|
}
|
||||||
|
|
||||||
|
return getAbsoluteAndInOsFormatPath({
|
||||||
|
"pathIsh": cliCommandOptions.reactAppRootDirPath,
|
||||||
|
"cwd": process.cwd()
|
||||||
|
});
|
||||||
|
})();
|
||||||
|
|
||||||
|
return { reactAppRootDirPath };
|
||||||
|
}
|
3
src/bin/shared/buildOptions/index.ts
Normal file
3
src/bin/shared/buildOptions/index.ts
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
export * from "./buildOptions";
|
||||||
|
export type { UserProvidedBuildOptions } from "./UserProvidedBuildOptions";
|
||||||
|
export type { ResolvedViteConfig } from "./resolvedViteConfig";
|
@ -3,9 +3,10 @@ import { assert } from "tsafe";
|
|||||||
import type { Equals } from "tsafe";
|
import type { Equals } from "tsafe";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
import { join as pathJoin } from "path";
|
import { join as pathJoin } from "path";
|
||||||
import { resolvedViteConfigJsonBasename } from "../../constants";
|
|
||||||
import type { OptionalIfCanBeUndefined } from "../../tools/OptionalIfCanBeUndefined";
|
import type { OptionalIfCanBeUndefined } from "../../tools/OptionalIfCanBeUndefined";
|
||||||
import { UserProvidedBuildOptions, zUserProvidedBuildOptions } from "./UserProvidedBuildOptions";
|
import { UserProvidedBuildOptions, zUserProvidedBuildOptions } from "./UserProvidedBuildOptions";
|
||||||
|
import * as child_process from "child_process";
|
||||||
|
import { vitePluginSubScriptEnvNames } from "../constants";
|
||||||
|
|
||||||
export type ResolvedViteConfig = {
|
export type ResolvedViteConfig = {
|
||||||
buildDir: string;
|
buildDir: string;
|
||||||
@ -30,17 +31,25 @@ const zResolvedViteConfig = z.object({
|
|||||||
assert<Equals<Got, Expected>>();
|
assert<Equals<Got, Expected>>();
|
||||||
}
|
}
|
||||||
|
|
||||||
export function readResolvedViteConfig(params: { cacheDirPath: string }): {
|
export function getResolvedViteConfig(params: { cacheDirPath: string; reactAppRootDirPath: string }): {
|
||||||
resolvedViteConfig: ResolvedViteConfig | undefined;
|
resolvedViteConfig: ResolvedViteConfig | undefined;
|
||||||
} {
|
} {
|
||||||
const { cacheDirPath } = params;
|
const { cacheDirPath, reactAppRootDirPath } = params;
|
||||||
|
|
||||||
const resolvedViteConfigJsonFilePath = pathJoin(cacheDirPath, resolvedViteConfigJsonBasename);
|
const resolvedViteConfigJsonFilePath = pathJoin(cacheDirPath, "vite.json");
|
||||||
|
|
||||||
if (!fs.existsSync(resolvedViteConfigJsonFilePath)) {
|
if (fs.readdirSync(reactAppRootDirPath).find(fileBasename => fileBasename.startsWith("vite.config")) === undefined) {
|
||||||
return { "resolvedViteConfig": undefined };
|
return { "resolvedViteConfig": undefined };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
child_process.execSync("npx vite", {
|
||||||
|
"cwd": reactAppRootDirPath,
|
||||||
|
"env": {
|
||||||
|
...process.env,
|
||||||
|
[vitePluginSubScriptEnvNames.createResolvedViteConfig]: resolvedViteConfigJsonFilePath
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
const resolvedViteConfig = (() => {
|
const resolvedViteConfig = (() => {
|
||||||
if (!fs.existsSync(resolvedViteConfigJsonFilePath)) {
|
if (!fs.existsSync(resolvedViteConfigJsonFilePath)) {
|
||||||
throw new Error("Missing Keycloakify Vite plugin output.");
|
throw new Error("Missing Keycloakify Vite plugin output.");
|
@ -2,7 +2,6 @@ export const nameOfTheGlobal = "kcContext";
|
|||||||
export const keycloak_resources = "keycloak-resources";
|
export const keycloak_resources = "keycloak-resources";
|
||||||
export const resources_common = "resources-common";
|
export const resources_common = "resources-common";
|
||||||
export const lastKeycloakVersionWithAccountV1 = "21.1.2";
|
export const lastKeycloakVersionWithAccountV1 = "21.1.2";
|
||||||
export const resolvedViteConfigJsonBasename = "vite.json";
|
|
||||||
export const basenameOfTheKeycloakifyResourcesDir = "build";
|
export const basenameOfTheKeycloakifyResourcesDir = "build";
|
||||||
|
|
||||||
export const themeTypes = ["login", "account"] as const;
|
export const themeTypes = ["login", "account"] as const;
|
||||||
@ -10,4 +9,7 @@ export const accountV1ThemeName = "account-v1";
|
|||||||
|
|
||||||
export type ThemeType = (typeof themeTypes)[number];
|
export type ThemeType = (typeof themeTypes)[number];
|
||||||
|
|
||||||
export const keycloakifyBuildOptionsForPostPostBuildScriptEnvName = "KEYCLOAKIFY_BUILD_OPTIONS_POST_POST_BUILD_SCRIPT";
|
export const vitePluginSubScriptEnvNames = {
|
||||||
|
"runPostBuildScript": "KEYCLOAKIFY_RUN_POST_BUILD_SCRIPT",
|
||||||
|
"createResolvedViteConfig": "KEYCLOAKIFY_CREATE_RESOLVED_VITE_CONFIG"
|
||||||
|
};
|
87
src/bin/shared/copyKeycloakResourcesToPublic.ts
Normal file
87
src/bin/shared/copyKeycloakResourcesToPublic.ts
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
import {
|
||||||
|
downloadKeycloakStaticResources,
|
||||||
|
type BuildOptionsLike as BuildOptionsLike_downloadKeycloakStaticResources
|
||||||
|
} from "./downloadKeycloakStaticResources";
|
||||||
|
import { join as pathJoin, relative as pathRelative } from "path";
|
||||||
|
import { themeTypes, keycloak_resources, lastKeycloakVersionWithAccountV1 } from "../shared/constants";
|
||||||
|
import { readThisNpmProjectVersion } from "../tools/readThisNpmProjectVersion";
|
||||||
|
import { assert } from "tsafe/assert";
|
||||||
|
import * as fs from "fs";
|
||||||
|
import { rmSync } from "../tools/fs.rmSync";
|
||||||
|
import type { BuildOptions } from "./buildOptions";
|
||||||
|
|
||||||
|
export type BuildOptionsLike = BuildOptionsLike_downloadKeycloakStaticResources & {
|
||||||
|
loginThemeResourcesFromKeycloakVersion: string;
|
||||||
|
publicDirPath: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
assert<BuildOptions extends BuildOptionsLike ? true : false>();
|
||||||
|
|
||||||
|
export async function copyKeycloakResourcesToPublic(params: { buildOptions: BuildOptionsLike }) {
|
||||||
|
const { buildOptions } = params;
|
||||||
|
|
||||||
|
const destDirPath = pathJoin(buildOptions.publicDirPath, keycloak_resources);
|
||||||
|
|
||||||
|
const keycloakifyBuildinfoFilePath = pathJoin(destDirPath, "keycloakify.buildinfo");
|
||||||
|
|
||||||
|
const keycloakifyBuildinfoRaw = JSON.stringify(
|
||||||
|
{
|
||||||
|
destDirPath,
|
||||||
|
"keycloakifyVersion": readThisNpmProjectVersion(),
|
||||||
|
"buildOptions": {
|
||||||
|
"loginThemeResourcesFromKeycloakVersion": readThisNpmProjectVersion(),
|
||||||
|
"cacheDirPath": pathRelative(destDirPath, buildOptions.cacheDirPath),
|
||||||
|
"npmWorkspaceRootDirPath": pathRelative(destDirPath, buildOptions.npmWorkspaceRootDirPath)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
null,
|
||||||
|
2
|
||||||
|
);
|
||||||
|
|
||||||
|
skip_if_already_done: {
|
||||||
|
if (!fs.existsSync(keycloakifyBuildinfoFilePath)) {
|
||||||
|
break skip_if_already_done;
|
||||||
|
}
|
||||||
|
|
||||||
|
const keycloakifyBuildinfoRaw_previousRun = fs.readFileSync(keycloakifyBuildinfoFilePath).toString("utf8");
|
||||||
|
|
||||||
|
if (keycloakifyBuildinfoRaw_previousRun !== keycloakifyBuildinfoRaw) {
|
||||||
|
break skip_if_already_done;
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
rmSync(destDirPath, { "force": true, "recursive": true });
|
||||||
|
|
||||||
|
for (const themeType of themeTypes) {
|
||||||
|
await downloadKeycloakStaticResources({
|
||||||
|
"keycloakVersion": (() => {
|
||||||
|
switch (themeType) {
|
||||||
|
case "login":
|
||||||
|
return buildOptions.loginThemeResourcesFromKeycloakVersion;
|
||||||
|
case "account":
|
||||||
|
return lastKeycloakVersionWithAccountV1;
|
||||||
|
}
|
||||||
|
})(),
|
||||||
|
themeType,
|
||||||
|
"themeDirPath": destDirPath,
|
||||||
|
buildOptions
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
fs.writeFileSync(
|
||||||
|
pathJoin(destDirPath, "README.txt"),
|
||||||
|
Buffer.from(
|
||||||
|
// prettier-ignore
|
||||||
|
[
|
||||||
|
"This is just a test folder that helps develop",
|
||||||
|
"the login and register page without having to run a Keycloak container"
|
||||||
|
].join(" ")
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
fs.writeFileSync(pathJoin(buildOptions.publicDirPath, keycloak_resources, ".gitignore"), Buffer.from("*", "utf8"));
|
||||||
|
|
||||||
|
fs.writeFileSync(keycloakifyBuildinfoFilePath, Buffer.from(keycloakifyBuildinfoRaw, "utf8"));
|
||||||
|
}
|
@ -3,13 +3,13 @@ import { mkdir, writeFile, unlink } from "fs/promises";
|
|||||||
import fetch from "make-fetch-happen";
|
import fetch from "make-fetch-happen";
|
||||||
import { dirname as pathDirname, join as pathJoin, basename as pathBasename } from "path";
|
import { dirname as pathDirname, join as pathJoin, basename as pathBasename } from "path";
|
||||||
import { assert } from "tsafe/assert";
|
import { assert } from "tsafe/assert";
|
||||||
import { transformCodebase } from "./tools/transformCodebase";
|
import { transformCodebase } from "../tools/transformCodebase";
|
||||||
import { unzip, zip } from "./tools/unzip";
|
import { unzip, zip } from "../tools/unzip";
|
||||||
import { rm } from "./tools/fs.rm";
|
import { rm } from "../tools/fs.rm";
|
||||||
import * as child_process from "child_process";
|
import * as child_process from "child_process";
|
||||||
import { existsAsync } from "./tools/fs.existsAsync";
|
import { existsAsync } from "../tools/fs.existsAsync";
|
||||||
import type { BuildOptions } from "./keycloakify/buildOptions";
|
import type { BuildOptions } from "./buildOptions";
|
||||||
import { getProxyFetchOptions } from "./tools/fetchProxyOptions";
|
import { getProxyFetchOptions } from "../tools/fetchProxyOptions";
|
||||||
|
|
||||||
export type BuildOptionsLike = {
|
export type BuildOptionsLike = {
|
||||||
cacheDirPath: string;
|
cacheDirPath: string;
|
264
src/bin/shared/downloadBuiltinKeycloakTheme.ts
Normal file
264
src/bin/shared/downloadBuiltinKeycloakTheme.ts
Normal file
@ -0,0 +1,264 @@
|
|||||||
|
import { join as pathJoin } from "path";
|
||||||
|
import { downloadAndUnzip } from "./downloadAndUnzip";
|
||||||
|
import { type BuildOptions } from "./buildOptions";
|
||||||
|
import { assert } from "tsafe/assert";
|
||||||
|
import * as child_process from "child_process";
|
||||||
|
import * as fs from "fs";
|
||||||
|
import { rmSync } from "../tools/fs.rmSync";
|
||||||
|
import { lastKeycloakVersionWithAccountV1 } from "./constants";
|
||||||
|
import { transformCodebase } from "../tools/transformCodebase";
|
||||||
|
|
||||||
|
export type BuildOptionsLike = {
|
||||||
|
cacheDirPath: string;
|
||||||
|
npmWorkspaceRootDirPath: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
assert<BuildOptions extends BuildOptionsLike ? true : false>();
|
||||||
|
|
||||||
|
export async function downloadBuiltinKeycloakTheme(params: { keycloakVersion: string; destDirPath: string; buildOptions: BuildOptionsLike }) {
|
||||||
|
const { keycloakVersion, destDirPath, buildOptions } = params;
|
||||||
|
|
||||||
|
await downloadAndUnzip({
|
||||||
|
destDirPath,
|
||||||
|
"url": `https://github.com/keycloak/keycloak/archive/refs/tags/${keycloakVersion}.zip`,
|
||||||
|
"specificDirsToExtract": ["", "-community"].map(ext => `keycloak-${keycloakVersion}/themes/src/main/resources${ext}/theme`),
|
||||||
|
buildOptions,
|
||||||
|
"preCacheTransform": {
|
||||||
|
"actionCacheId": "npm install and build",
|
||||||
|
"action": async ({ destDirPath }) => {
|
||||||
|
install_common_node_modules: {
|
||||||
|
const commonResourcesDirPath = pathJoin(destDirPath, "keycloak", "common", "resources");
|
||||||
|
|
||||||
|
if (!fs.existsSync(commonResourcesDirPath)) {
|
||||||
|
break install_common_node_modules;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!fs.existsSync(pathJoin(commonResourcesDirPath, "package.json"))) {
|
||||||
|
break install_common_node_modules;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fs.existsSync(pathJoin(commonResourcesDirPath, "node_modules"))) {
|
||||||
|
break install_common_node_modules;
|
||||||
|
}
|
||||||
|
|
||||||
|
child_process.execSync("npm install --omit=dev", {
|
||||||
|
"cwd": commonResourcesDirPath,
|
||||||
|
"stdio": "ignore"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
repatriate_common_resources_from_base_login_theme: {
|
||||||
|
const baseLoginThemeResourceDir = pathJoin(destDirPath, "base", "login", "resources");
|
||||||
|
|
||||||
|
if (!fs.existsSync(baseLoginThemeResourceDir)) {
|
||||||
|
break repatriate_common_resources_from_base_login_theme;
|
||||||
|
}
|
||||||
|
|
||||||
|
transformCodebase({
|
||||||
|
"srcDirPath": baseLoginThemeResourceDir,
|
||||||
|
"destDirPath": pathJoin(destDirPath, "keycloak", "login", "resources")
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
install_and_move_to_common_resources_generated_in_keycloak_v2: {
|
||||||
|
if (!fs.readFileSync(pathJoin(destDirPath, "keycloak", "login", "theme.properties")).toString("utf8").includes("web_modules")) {
|
||||||
|
break install_and_move_to_common_resources_generated_in_keycloak_v2;
|
||||||
|
}
|
||||||
|
|
||||||
|
const accountV2DirSrcDirPath = pathJoin(destDirPath, "keycloak.v2", "account", "src");
|
||||||
|
|
||||||
|
if (!fs.existsSync(accountV2DirSrcDirPath)) {
|
||||||
|
break install_and_move_to_common_resources_generated_in_keycloak_v2;
|
||||||
|
}
|
||||||
|
|
||||||
|
const packageManager = fs.existsSync(pathJoin(accountV2DirSrcDirPath, "pnpm-lock.yaml")) ? "pnpm" : "npm";
|
||||||
|
|
||||||
|
if (packageManager === "pnpm") {
|
||||||
|
try {
|
||||||
|
child_process.execSync(`which pnpm`);
|
||||||
|
} catch {
|
||||||
|
console.log(`Installing pnpm globally`);
|
||||||
|
child_process.execSync(`npm install -g pnpm`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
child_process.execSync(`${packageManager} install`, { "cwd": accountV2DirSrcDirPath, "stdio": "ignore" });
|
||||||
|
|
||||||
|
const packageJsonFilePath = pathJoin(accountV2DirSrcDirPath, "package.json");
|
||||||
|
|
||||||
|
const packageJsonRaw = fs.readFileSync(packageJsonFilePath);
|
||||||
|
|
||||||
|
const parsedPackageJson = JSON.parse(packageJsonRaw.toString("utf8"));
|
||||||
|
|
||||||
|
parsedPackageJson.scripts.build = parsedPackageJson.scripts.build
|
||||||
|
.replace(`${packageManager} run check-types`, "true")
|
||||||
|
.replace(`${packageManager} run babel`, "true");
|
||||||
|
|
||||||
|
fs.writeFileSync(packageJsonFilePath, Buffer.from(JSON.stringify(parsedPackageJson, null, 2), "utf8"));
|
||||||
|
|
||||||
|
child_process.execSync(`${packageManager} run build`, { "cwd": accountV2DirSrcDirPath, "stdio": "ignore" });
|
||||||
|
|
||||||
|
fs.writeFileSync(packageJsonFilePath, packageJsonRaw);
|
||||||
|
|
||||||
|
fs.rmSync(pathJoin(accountV2DirSrcDirPath, "node_modules"), { "recursive": true });
|
||||||
|
}
|
||||||
|
|
||||||
|
remove_keycloak_v2: {
|
||||||
|
const keycloakV2DirPath = pathJoin(destDirPath, "keycloak.v2");
|
||||||
|
|
||||||
|
if (!fs.existsSync(keycloakV2DirPath)) {
|
||||||
|
break remove_keycloak_v2;
|
||||||
|
}
|
||||||
|
|
||||||
|
rmSync(keycloakV2DirPath, { "recursive": true });
|
||||||
|
}
|
||||||
|
|
||||||
|
// Note, this is an optimization for reducing the size of the jar
|
||||||
|
remove_unused_node_modules: {
|
||||||
|
const nodeModuleDirPath = pathJoin(destDirPath, "keycloak", "common", "resources", "node_modules");
|
||||||
|
|
||||||
|
if (!fs.existsSync(nodeModuleDirPath)) {
|
||||||
|
break remove_unused_node_modules;
|
||||||
|
}
|
||||||
|
|
||||||
|
const toDeletePerfixes = [
|
||||||
|
"angular",
|
||||||
|
"bootstrap",
|
||||||
|
"rcue",
|
||||||
|
"font-awesome",
|
||||||
|
"ng-file-upload",
|
||||||
|
pathJoin("patternfly", "dist", "sass"),
|
||||||
|
pathJoin("patternfly", "dist", "less"),
|
||||||
|
pathJoin("patternfly", "dist", "js"),
|
||||||
|
"d3",
|
||||||
|
pathJoin("jquery", "src"),
|
||||||
|
"c3",
|
||||||
|
"core-js",
|
||||||
|
"eonasdan-bootstrap-datetimepicker",
|
||||||
|
"moment",
|
||||||
|
"react",
|
||||||
|
"patternfly-bootstrap-treeview",
|
||||||
|
"popper.js",
|
||||||
|
"tippy.js",
|
||||||
|
"jquery-match-height",
|
||||||
|
"google-code-prettify",
|
||||||
|
"patternfly-bootstrap-combobox",
|
||||||
|
"focus-trap",
|
||||||
|
"tabbable",
|
||||||
|
"scheduler",
|
||||||
|
"@types",
|
||||||
|
"datatables.net",
|
||||||
|
"datatables.net-colreorder",
|
||||||
|
"tslib",
|
||||||
|
"prop-types",
|
||||||
|
"file-selector",
|
||||||
|
"datatables.net-colreorder-bs",
|
||||||
|
"object-assign",
|
||||||
|
"warning",
|
||||||
|
"js-tokens",
|
||||||
|
"loose-envify",
|
||||||
|
"prop-types-extra",
|
||||||
|
"attr-accept",
|
||||||
|
"datatables.net-select",
|
||||||
|
"drmonty-datatables-colvis",
|
||||||
|
"datatables.net-bs",
|
||||||
|
pathJoin("@patternfly", "react"),
|
||||||
|
pathJoin("@patternfly", "patternfly", "docs")
|
||||||
|
];
|
||||||
|
|
||||||
|
transformCodebase({
|
||||||
|
"srcDirPath": nodeModuleDirPath,
|
||||||
|
"destDirPath": nodeModuleDirPath,
|
||||||
|
"transformSourceCode": ({ sourceCode, fileRelativePath }) => {
|
||||||
|
if (fileRelativePath.endsWith(".map")) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (toDeletePerfixes.find(prefix => fileRelativePath.startsWith(prefix)) !== undefined) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fileRelativePath.startsWith(pathJoin("patternfly", "dist", "fonts"))) {
|
||||||
|
if (
|
||||||
|
!fileRelativePath.endsWith(".woff2") &&
|
||||||
|
!fileRelativePath.endsWith(".woff") &&
|
||||||
|
!fileRelativePath.endsWith(".ttf")
|
||||||
|
) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return { "modifiedSourceCode": sourceCode };
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Just like node_modules
|
||||||
|
remove_unused_lib: {
|
||||||
|
const libDirPath = pathJoin(destDirPath, "keycloak", "common", "resources", "lib");
|
||||||
|
|
||||||
|
if (!fs.existsSync(libDirPath)) {
|
||||||
|
break remove_unused_lib;
|
||||||
|
}
|
||||||
|
|
||||||
|
const toDeletePerfixes = ["ui-ace", "filesaver", "fileupload", "angular", "ui-ace"];
|
||||||
|
|
||||||
|
transformCodebase({
|
||||||
|
"srcDirPath": libDirPath,
|
||||||
|
"destDirPath": libDirPath,
|
||||||
|
"transformSourceCode": ({ sourceCode, fileRelativePath }) => {
|
||||||
|
if (fileRelativePath.endsWith(".map")) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (toDeletePerfixes.find(prefix => fileRelativePath.startsWith(prefix)) !== undefined) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
return { "modifiedSourceCode": sourceCode };
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
last_account_v1_transformations: {
|
||||||
|
if (lastKeycloakVersionWithAccountV1 !== keycloakVersion) {
|
||||||
|
break last_account_v1_transformations;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const accountCssFilePath = pathJoin(destDirPath, "keycloak", "account", "resources", "css", "account.css");
|
||||||
|
|
||||||
|
fs.writeFileSync(
|
||||||
|
accountCssFilePath,
|
||||||
|
Buffer.from(fs.readFileSync(accountCssFilePath).toString("utf8").replace("top: -34px;", "top: -34px !important;"), "utf8")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Note, this is an optimization for reducing the size of the jar,
|
||||||
|
// For this version we know exactly which resources are used.
|
||||||
|
{
|
||||||
|
const nodeModulesDirPath = pathJoin(destDirPath, "keycloak", "common", "resources", "node_modules");
|
||||||
|
|
||||||
|
const toKeepPrefixes = [
|
||||||
|
...["patternfly.min.css", "patternfly-additions.min.css", "patternfly-additions.min.css"].map(fileBasename =>
|
||||||
|
pathJoin("patternfly", "dist", "css", fileBasename)
|
||||||
|
),
|
||||||
|
pathJoin("patternfly", "dist", "fonts")
|
||||||
|
];
|
||||||
|
|
||||||
|
transformCodebase({
|
||||||
|
"srcDirPath": nodeModulesDirPath,
|
||||||
|
"destDirPath": nodeModulesDirPath,
|
||||||
|
"transformSourceCode": ({ sourceCode, fileRelativePath }) => {
|
||||||
|
if (toKeepPrefixes.find(prefix => fileRelativePath.startsWith(prefix)) === undefined) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
return { "modifiedSourceCode": sourceCode };
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
@ -1,11 +1,11 @@
|
|||||||
import { transformCodebase } from "../../tools/transformCodebase";
|
import { transformCodebase } from "../tools/transformCodebase";
|
||||||
import { join as pathJoin } from "path";
|
import { join as pathJoin } from "path";
|
||||||
import { downloadBuiltinKeycloakTheme } from "../../download-builtin-keycloak-theme";
|
import { downloadBuiltinKeycloakTheme } from "./downloadBuiltinKeycloakTheme";
|
||||||
import { resources_common, type ThemeType } from "../../constants";
|
import { resources_common, type ThemeType } from "./constants";
|
||||||
import { BuildOptions } from "../buildOptions";
|
import type { BuildOptions } from "./buildOptions";
|
||||||
import { assert } from "tsafe/assert";
|
import { assert } from "tsafe/assert";
|
||||||
import * as crypto from "crypto";
|
import * as crypto from "crypto";
|
||||||
import { rmSync } from "../../tools/fs.rmSync";
|
import { rmSync } from "../tools/fs.rmSync";
|
||||||
|
|
||||||
export type BuildOptionsLike = {
|
export type BuildOptionsLike = {
|
||||||
cacheDirPath: string;
|
cacheDirPath: string;
|
@ -1,6 +1,6 @@
|
|||||||
import * as fs from "fs";
|
import * as fs from "fs";
|
||||||
import { exclude } from "tsafe";
|
import { exclude } from "tsafe";
|
||||||
import { crawl } from "./tools/crawl";
|
import { crawl } from "../tools/crawl";
|
||||||
import { join as pathJoin } from "path";
|
import { join as pathJoin } from "path";
|
||||||
import { themeTypes } from "./constants";
|
import { themeTypes } from "./constants";
|
||||||
|
|
@ -1,4 +1,4 @@
|
|||||||
import { getLatestsSemVersionedTagFactory } from "./tools/octokit-addons/getLatestsSemVersionedTag";
|
import { getLatestsSemVersionedTagFactory } from "../tools/octokit-addons/getLatestsSemVersionedTag";
|
||||||
import { Octokit } from "@octokit/rest";
|
import { Octokit } from "@octokit/rest";
|
||||||
import cliSelect from "cli-select";
|
import cliSelect from "cli-select";
|
||||||
import { lastKeycloakVersionWithAccountV1 } from "./constants";
|
import { lastKeycloakVersionWithAccountV1 } from "./constants";
|
@ -5,7 +5,7 @@ export default Fallback;
|
|||||||
export { useDownloadTerms } from "keycloakify/login/lib/useDownloadTerms";
|
export { useDownloadTerms } from "keycloakify/login/lib/useDownloadTerms";
|
||||||
export { getKcContext } from "keycloakify/login/kcContext/getKcContext";
|
export { getKcContext } from "keycloakify/login/kcContext/getKcContext";
|
||||||
export { createGetKcContext } from "keycloakify/login/kcContext/createGetKcContext";
|
export { createGetKcContext } from "keycloakify/login/kcContext/createGetKcContext";
|
||||||
export type { LoginThemePageId as PageId } from "keycloakify/bin/keycloakify/generateFtl";
|
export type { LoginThemePageId as PageId } from "keycloakify/bin/shared/pageIds";
|
||||||
export { createUseI18n } from "keycloakify/login/i18n/i18n";
|
export { createUseI18n } from "keycloakify/login/i18n/i18n";
|
||||||
|
|
||||||
export type { PageProps } from "keycloakify/login/pages/PageProps";
|
export type { PageProps } from "keycloakify/login/pages/PageProps";
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import type { LoginThemePageId } from "keycloakify/bin/keycloakify/generateFtl";
|
import type { LoginThemePageId } from "keycloakify/bin/shared/pageIds";
|
||||||
import { type ThemeType } from "keycloakify/bin/constants";
|
import { type ThemeType } from "keycloakify/bin/shared/constants";
|
||||||
import { assert } from "tsafe/assert";
|
import { assert } from "tsafe/assert";
|
||||||
import type { Equals } from "tsafe";
|
import type { Equals } from "tsafe";
|
||||||
import type { MessageKey } from "../i18n/i18n";
|
import type { MessageKey } from "../i18n/i18n";
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import type { KcContext } from "./KcContext";
|
import type { KcContext } from "./KcContext";
|
||||||
import type { AndByDiscriminatingKey } from "keycloakify/tools/AndByDiscriminatingKey";
|
import type { AndByDiscriminatingKey } from "keycloakify/tools/AndByDiscriminatingKey";
|
||||||
import { nameOfTheGlobal } from "keycloakify/bin/constants";
|
import { nameOfTheGlobal } from "keycloakify/bin/shared/constants";
|
||||||
|
|
||||||
export type ExtendKcContext<KcContextExtension extends { pageId: string }> = [KcContextExtension] extends [never]
|
export type ExtendKcContext<KcContextExtension extends { pageId: string }> = [KcContextExtension] extends [never]
|
||||||
? KcContext
|
? KcContext
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
import "minimal-polyfills/Object.fromEntries";
|
import "minimal-polyfills/Object.fromEntries";
|
||||||
import type { KcContext, Attribute } from "./KcContext";
|
import type { KcContext, Attribute } from "./KcContext";
|
||||||
import { resources_common, keycloak_resources } from "keycloakify/bin/constants";
|
import { resources_common, keycloak_resources } from "keycloakify/bin/shared/constants";
|
||||||
import { id } from "tsafe/id";
|
import { id } from "tsafe/id";
|
||||||
import { assert, type Equals } from "tsafe/assert";
|
import { assert, type Equals } from "tsafe/assert";
|
||||||
import type { LoginThemePageId } from "keycloakify/bin/keycloakify/generateFtl";
|
import type { LoginThemePageId } from "keycloakify/bin/shared/pageIds";
|
||||||
import { BASE_URL } from "keycloakify/lib/BASE_URL";
|
import { BASE_URL } from "keycloakify/lib/BASE_URL";
|
||||||
|
|
||||||
const attributes: Attribute[] = [
|
const attributes: Attribute[] = [
|
||||||
|
@ -1,21 +1,12 @@
|
|||||||
import { join as pathJoin, relative as pathRelative, sep as pathSep } from "path";
|
import { join as pathJoin, relative as pathRelative, sep as pathSep, dirname as pathDirname } from "path";
|
||||||
import type { Plugin } from "vite";
|
import type { Plugin } from "vite";
|
||||||
import * as fs from "fs";
|
import * as fs from "fs";
|
||||||
import {
|
import { nameOfTheGlobal, basenameOfTheKeycloakifyResourcesDir, keycloak_resources, vitePluginSubScriptEnvNames } from "../bin/shared/constants";
|
||||||
resolvedViteConfigJsonBasename,
|
|
||||||
nameOfTheGlobal,
|
|
||||||
basenameOfTheKeycloakifyResourcesDir,
|
|
||||||
keycloak_resources,
|
|
||||||
keycloakifyBuildOptionsForPostPostBuildScriptEnvName
|
|
||||||
} from "../bin/constants";
|
|
||||||
import type { ResolvedViteConfig } from "../bin/keycloakify/buildOptions/resolvedViteConfig";
|
|
||||||
import { getCacheDirPath } from "../bin/keycloakify/buildOptions/getCacheDirPath";
|
|
||||||
import { id } from "tsafe/id";
|
import { id } from "tsafe/id";
|
||||||
import { rm } from "../bin/tools/fs.rm";
|
import { rm } from "../bin/tools/fs.rm";
|
||||||
import { copyKeycloakResourcesToPublic } from "../bin/copy-keycloak-resources-to-public";
|
import { copyKeycloakResourcesToPublic } from "../bin/shared/copyKeycloakResourcesToPublic";
|
||||||
import { assert } from "tsafe/assert";
|
import { assert } from "tsafe/assert";
|
||||||
import type { BuildOptions } from "../bin/keycloakify/buildOptions";
|
import { readBuildOptions, type BuildOptions, type UserProvidedBuildOptions, type ResolvedViteConfig } from "../bin/shared/buildOptions";
|
||||||
import type { UserProvidedBuildOptions } from "../bin/keycloakify/buildOptions/UserProvidedBuildOptions";
|
|
||||||
import MagicString from "magic-string";
|
import MagicString from "magic-string";
|
||||||
|
|
||||||
export type Params = UserProvidedBuildOptions & {
|
export type Params = UserProvidedBuildOptions & {
|
||||||
@ -36,20 +27,14 @@ export function keycloakify(params?: Params) {
|
|||||||
"configResolved": async resolvedConfig => {
|
"configResolved": async resolvedConfig => {
|
||||||
shouldGenerateSourcemap = resolvedConfig.build.sourcemap !== false;
|
shouldGenerateSourcemap = resolvedConfig.build.sourcemap !== false;
|
||||||
|
|
||||||
run_post_build_script: {
|
run_post_build_script_case: {
|
||||||
const buildOptionJson = process.env[keycloakifyBuildOptionsForPostPostBuildScriptEnvName];
|
const postBuildArgJson = process.env[vitePluginSubScriptEnvNames.runPostBuildScript];
|
||||||
|
|
||||||
if (buildOptionJson === undefined) {
|
if (postBuildArgJson === undefined) {
|
||||||
break run_post_build_script;
|
break run_post_build_script_case;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (postBuild === undefined) {
|
await postBuild?.(JSON.parse(postBuildArgJson));
|
||||||
process.exit(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
const buildOptions: BuildOptions = JSON.parse(buildOptionJson);
|
|
||||||
|
|
||||||
await postBuild(buildOptions);
|
|
||||||
|
|
||||||
process.exit(0);
|
process.exit(0);
|
||||||
}
|
}
|
||||||
@ -86,34 +71,49 @@ export function keycloakify(params?: Params) {
|
|||||||
|
|
||||||
buildDirPath = pathJoin(reactAppRootDirPath, resolvedConfig.build.outDir);
|
buildDirPath = pathJoin(reactAppRootDirPath, resolvedConfig.build.outDir);
|
||||||
|
|
||||||
const { cacheDirPath } = getCacheDirPath({
|
create_resolved_vite_config_case: {
|
||||||
reactAppRootDirPath
|
const resolvedViteConfigJsonFilePath = process.env[vitePluginSubScriptEnvNames.createResolvedViteConfig];
|
||||||
});
|
|
||||||
|
|
||||||
if (!fs.existsSync(cacheDirPath)) {
|
if (resolvedViteConfigJsonFilePath === undefined) {
|
||||||
fs.mkdirSync(cacheDirPath, { "recursive": true });
|
break create_resolved_vite_config_case;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const dirPath = pathDirname(resolvedViteConfigJsonFilePath);
|
||||||
|
|
||||||
|
if (!fs.existsSync(dirPath)) {
|
||||||
|
fs.mkdirSync(dirPath, { "recursive": true });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fs.writeFileSync(
|
||||||
|
resolvedViteConfigJsonFilePath,
|
||||||
|
Buffer.from(
|
||||||
|
JSON.stringify(
|
||||||
|
id<ResolvedViteConfig>({
|
||||||
|
"publicDir": pathRelative(reactAppRootDirPath, resolvedConfig.publicDir),
|
||||||
|
"assetsDir": resolvedConfig.build.assetsDir,
|
||||||
|
"buildDir": resolvedConfig.build.outDir,
|
||||||
|
urlPathname,
|
||||||
|
userProvidedBuildOptions
|
||||||
|
}),
|
||||||
|
null,
|
||||||
|
2
|
||||||
|
),
|
||||||
|
"utf8"
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
process.exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
fs.writeFileSync(
|
|
||||||
pathJoin(cacheDirPath, resolvedViteConfigJsonBasename),
|
|
||||||
Buffer.from(
|
|
||||||
JSON.stringify(
|
|
||||||
id<ResolvedViteConfig>({
|
|
||||||
"publicDir": pathRelative(reactAppRootDirPath, resolvedConfig.publicDir),
|
|
||||||
"assetsDir": resolvedConfig.build.assetsDir,
|
|
||||||
"buildDir": resolvedConfig.build.outDir,
|
|
||||||
urlPathname,
|
|
||||||
userProvidedBuildOptions
|
|
||||||
}),
|
|
||||||
null,
|
|
||||||
2
|
|
||||||
),
|
|
||||||
"utf8"
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
await copyKeycloakResourcesToPublic({
|
await copyKeycloakResourcesToPublic({
|
||||||
"processArgv": ["--project", reactAppRootDirPath]
|
"buildOptions": readBuildOptions({
|
||||||
|
"cliCommandOptions": {
|
||||||
|
"isSilent": true,
|
||||||
|
reactAppRootDirPath
|
||||||
|
}
|
||||||
|
})
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
"transform": (code, id) => {
|
"transform": (code, id) => {
|
||||||
|
@ -5,7 +5,7 @@ import { replaceImportsInInlineCssCode } from "keycloakify/bin/keycloakify/repla
|
|||||||
import { same } from "evt/tools/inDepth/same";
|
import { same } from "evt/tools/inDepth/same";
|
||||||
import { expect, it, describe } from "vitest";
|
import { expect, it, describe } from "vitest";
|
||||||
import { isSameCode } from "../tools/isSameCode";
|
import { isSameCode } from "../tools/isSameCode";
|
||||||
import { basenameOfTheKeycloakifyResourcesDir, nameOfTheGlobal } from "keycloakify/bin/constants";
|
import { basenameOfTheKeycloakifyResourcesDir, nameOfTheGlobal } from "keycloakify/bin/shared/constants";
|
||||||
|
|
||||||
describe("js replacer - vite", () => {
|
describe("js replacer - vite", () => {
|
||||||
it("replaceImportsInJsCode_vite - 1", () => {
|
it("replaceImportsInJsCode_vite - 1", () => {
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { downloadAndUnzip } from "keycloakify/bin/downloadAndUnzip";
|
import { downloadAndUnzip } from "keycloakify/bin/shared/downloadAndUnzip";
|
||||||
import { join as pathJoin } from "path";
|
import { join as pathJoin } from "path";
|
||||||
import { getThisCodebaseRootDirPath } from "keycloakify/bin/tools/getThisCodebaseRootDirPath";
|
import { getThisCodebaseRootDirPath } from "keycloakify/bin/tools/getThisCodebaseRootDirPath";
|
||||||
|
|
||||||
|
87
yarn.lock
87
yarn.lock
@ -3802,6 +3802,13 @@ ansi-escapes@^4.3.0:
|
|||||||
dependencies:
|
dependencies:
|
||||||
type-fest "^0.21.3"
|
type-fest "^0.21.3"
|
||||||
|
|
||||||
|
ansi-escapes@^5.0.0:
|
||||||
|
version "5.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-5.0.0.tgz#b6a0caf0eef0c41af190e9a749e0c00ec04bb2a6"
|
||||||
|
integrity sha512-5GFMVX8HqE/TB+FuBJGuO5XG0WrsA6ptUqoODaT/n9mmUaZFkqnBueB4leqGBCmrUHnCnC4PCZTCd0E7QQ83bA==
|
||||||
|
dependencies:
|
||||||
|
type-fest "^1.0.2"
|
||||||
|
|
||||||
ansi-html-community@0.0.8, ansi-html-community@^0.0.8:
|
ansi-html-community@0.0.8, ansi-html-community@^0.0.8:
|
||||||
version "0.0.8"
|
version "0.0.8"
|
||||||
resolved "https://registry.yarnpkg.com/ansi-html-community/-/ansi-html-community-0.0.8.tgz#69fbc4d6ccbe383f9736934ae34c3f8290f1bf41"
|
resolved "https://registry.yarnpkg.com/ansi-html-community/-/ansi-html-community-0.0.8.tgz#69fbc4d6ccbe383f9736934ae34c3f8290f1bf41"
|
||||||
@ -3841,7 +3848,7 @@ ansi-styles@^5.0.0:
|
|||||||
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-5.2.0.tgz#07449690ad45777d1924ac2abb2fc8895dba836b"
|
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-5.2.0.tgz#07449690ad45777d1924ac2abb2fc8895dba836b"
|
||||||
integrity sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==
|
integrity sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==
|
||||||
|
|
||||||
ansi-styles@^6.0.0:
|
ansi-styles@^6.0.0, ansi-styles@^6.1.0:
|
||||||
version "6.2.1"
|
version "6.2.1"
|
||||||
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-6.2.1.tgz#0e62320cf99c21afff3b3012192546aacbfb05c5"
|
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-6.2.1.tgz#0e62320cf99c21afff3b3012192546aacbfb05c5"
|
||||||
integrity sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==
|
integrity sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==
|
||||||
@ -4872,6 +4879,13 @@ cli-cursor@^3.1.0:
|
|||||||
dependencies:
|
dependencies:
|
||||||
restore-cursor "^3.1.0"
|
restore-cursor "^3.1.0"
|
||||||
|
|
||||||
|
cli-cursor@^4.0.0:
|
||||||
|
version "4.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-4.0.0.tgz#3cecfe3734bf4fe02a8361cbdc0f6fe28c6a57ea"
|
||||||
|
integrity sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==
|
||||||
|
dependencies:
|
||||||
|
restore-cursor "^4.0.0"
|
||||||
|
|
||||||
cli-select@^1.1.2:
|
cli-select@^1.1.2:
|
||||||
version "1.1.2"
|
version "1.1.2"
|
||||||
resolved "https://registry.yarnpkg.com/cli-select/-/cli-select-1.1.2.tgz#456dced464b3346ca661b16a0e37fc4b28db4818"
|
resolved "https://registry.yarnpkg.com/cli-select/-/cli-select-1.1.2.tgz#456dced464b3346ca661b16a0e37fc4b28db4818"
|
||||||
@ -4988,7 +5002,7 @@ colorette@^1.2.2, colorette@^1.4.0:
|
|||||||
resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.4.0.tgz#5190fbb87276259a86ad700bff2c6d6faa3fca40"
|
resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.4.0.tgz#5190fbb87276259a86ad700bff2c6d6faa3fca40"
|
||||||
integrity sha512-Y2oEozpomLn7Q3HFP7dpww7AtMJplbM9lGZP6RDfHqmbeRjiwRg4n6VM6j4KLmRke85uWEI7JqF17f3pqdRA0g==
|
integrity sha512-Y2oEozpomLn7Q3HFP7dpww7AtMJplbM9lGZP6RDfHqmbeRjiwRg4n6VM6j4KLmRke85uWEI7JqF17f3pqdRA0g==
|
||||||
|
|
||||||
colorette@^2.0.16:
|
colorette@^2.0.16, colorette@^2.0.20:
|
||||||
version "2.0.20"
|
version "2.0.20"
|
||||||
resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.20.tgz#9eb793e6833067f7235902fcd3b09917a000a95a"
|
resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.20.tgz#9eb793e6833067f7235902fcd3b09917a000a95a"
|
||||||
integrity sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==
|
integrity sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==
|
||||||
@ -5833,6 +5847,14 @@ enquirer@^2.3.6:
|
|||||||
dependencies:
|
dependencies:
|
||||||
ansi-colors "^4.1.1"
|
ansi-colors "^4.1.1"
|
||||||
|
|
||||||
|
enquirer@^2.4.1:
|
||||||
|
version "2.4.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/enquirer/-/enquirer-2.4.1.tgz#93334b3fbd74fc7097b224ab4a8fb7e40bf4ae56"
|
||||||
|
integrity sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==
|
||||||
|
dependencies:
|
||||||
|
ansi-colors "^4.1.1"
|
||||||
|
strip-ansi "^6.0.1"
|
||||||
|
|
||||||
entities@^2.0.0:
|
entities@^2.0.0:
|
||||||
version "2.2.0"
|
version "2.2.0"
|
||||||
resolved "https://registry.yarnpkg.com/entities/-/entities-2.2.0.tgz#098dc90ebb83d8dffa089d55256b351d34c4da55"
|
resolved "https://registry.yarnpkg.com/entities/-/entities-2.2.0.tgz#098dc90ebb83d8dffa089d55256b351d34c4da55"
|
||||||
@ -6179,6 +6201,11 @@ event-emitter@^0.3.5:
|
|||||||
d "1"
|
d "1"
|
||||||
es5-ext "~0.10.14"
|
es5-ext "~0.10.14"
|
||||||
|
|
||||||
|
eventemitter3@^5.0.1:
|
||||||
|
version "5.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-5.0.1.tgz#53f5ffd0a492ac800721bb42c66b841de96423c4"
|
||||||
|
integrity sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==
|
||||||
|
|
||||||
events@^3.0.0, events@^3.2.0:
|
events@^3.0.0, events@^3.2.0:
|
||||||
version "3.3.0"
|
version "3.3.0"
|
||||||
resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400"
|
resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400"
|
||||||
@ -8200,6 +8227,18 @@ listr2@^3.12.2:
|
|||||||
through "^2.3.8"
|
through "^2.3.8"
|
||||||
wrap-ansi "^7.0.0"
|
wrap-ansi "^7.0.0"
|
||||||
|
|
||||||
|
listr2@^7.0.1:
|
||||||
|
version "7.0.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/listr2/-/listr2-7.0.2.tgz#3aa3e1549dfaf3c57ab5eeaba754da3b87f33063"
|
||||||
|
integrity sha512-rJysbR9GKIalhTbVL2tYbF2hVyDnrf7pFUZBwjPaMIdadYHmeT+EVi/Bu3qd7ETQPahTotg2WRCatXwRBW554g==
|
||||||
|
dependencies:
|
||||||
|
cli-truncate "^3.1.0"
|
||||||
|
colorette "^2.0.20"
|
||||||
|
eventemitter3 "^5.0.1"
|
||||||
|
log-update "^5.0.1"
|
||||||
|
rfdc "^1.3.0"
|
||||||
|
wrap-ansi "^8.1.0"
|
||||||
|
|
||||||
load-json-file@^1.0.0:
|
load-json-file@^1.0.0:
|
||||||
version "1.1.0"
|
version "1.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0"
|
resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0"
|
||||||
@ -8296,6 +8335,17 @@ log-update@^4.0.0:
|
|||||||
slice-ansi "^4.0.0"
|
slice-ansi "^4.0.0"
|
||||||
wrap-ansi "^6.2.0"
|
wrap-ansi "^6.2.0"
|
||||||
|
|
||||||
|
log-update@^5.0.1:
|
||||||
|
version "5.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/log-update/-/log-update-5.0.1.tgz#9e928bf70cb183c1f0c9e91d9e6b7115d597ce09"
|
||||||
|
integrity sha512-5UtUDQ/6edw4ofyljDNcOVJQ4c7OjDro4h3y8e1GQL5iYElYclVHJ3zeWchylvMaKnDbDilC8irOVyexnA/Slw==
|
||||||
|
dependencies:
|
||||||
|
ansi-escapes "^5.0.0"
|
||||||
|
cli-cursor "^4.0.0"
|
||||||
|
slice-ansi "^5.0.0"
|
||||||
|
strip-ansi "^7.0.1"
|
||||||
|
wrap-ansi "^8.0.1"
|
||||||
|
|
||||||
loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.4.0:
|
loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.4.0:
|
||||||
version "1.4.0"
|
version "1.4.0"
|
||||||
resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf"
|
resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf"
|
||||||
@ -10505,6 +10555,14 @@ restore-cursor@^3.1.0:
|
|||||||
onetime "^5.1.0"
|
onetime "^5.1.0"
|
||||||
signal-exit "^3.0.2"
|
signal-exit "^3.0.2"
|
||||||
|
|
||||||
|
restore-cursor@^4.0.0:
|
||||||
|
version "4.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-4.0.0.tgz#519560a4318975096def6e609d44100edaa4ccb9"
|
||||||
|
integrity sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==
|
||||||
|
dependencies:
|
||||||
|
onetime "^5.1.0"
|
||||||
|
signal-exit "^3.0.2"
|
||||||
|
|
||||||
ret@~0.1.10:
|
ret@~0.1.10:
|
||||||
version "0.1.15"
|
version "0.1.15"
|
||||||
resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc"
|
resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc"
|
||||||
@ -11222,7 +11280,7 @@ string-argv@0.3.1:
|
|||||||
is-fullwidth-code-point "^3.0.0"
|
is-fullwidth-code-point "^3.0.0"
|
||||||
strip-ansi "^6.0.1"
|
strip-ansi "^6.0.1"
|
||||||
|
|
||||||
string-width@^5.0.0:
|
string-width@^5.0.0, string-width@^5.0.1:
|
||||||
version "5.1.2"
|
version "5.1.2"
|
||||||
resolved "https://registry.yarnpkg.com/string-width/-/string-width-5.1.2.tgz#14f8daec6d81e7221d2a357e668cab73bdbca794"
|
resolved "https://registry.yarnpkg.com/string-width/-/string-width-5.1.2.tgz#14f8daec6d81e7221d2a357e668cab73bdbca794"
|
||||||
integrity sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==
|
integrity sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==
|
||||||
@ -11487,6 +11545,15 @@ telejson@^6.0.8:
|
|||||||
lodash "^4.17.21"
|
lodash "^4.17.21"
|
||||||
memoizerific "^1.11.3"
|
memoizerific "^1.11.3"
|
||||||
|
|
||||||
|
termost@^0.12.0:
|
||||||
|
version "0.12.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/termost/-/termost-0.12.0.tgz#ca15c83fe3b2dfc83be0dcf4215aafad3bc6c018"
|
||||||
|
integrity sha512-7MbYVQvdhaZHSy/mO8TM6yXcDTS2wkeLiWIwoUL43n6wo4NSO38V3GNsBRlI4zcl8vQzm+bmqplyqOTYVZCpFw==
|
||||||
|
dependencies:
|
||||||
|
enquirer "^2.4.1"
|
||||||
|
listr2 "^7.0.1"
|
||||||
|
picocolors "^1.0.0"
|
||||||
|
|
||||||
terser-webpack-plugin@^1.4.3:
|
terser-webpack-plugin@^1.4.3:
|
||||||
version "1.4.5"
|
version "1.4.5"
|
||||||
resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-1.4.5.tgz#a217aefaea330e734ffacb6120ec1fa312d6040b"
|
resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-1.4.5.tgz#a217aefaea330e734ffacb6120ec1fa312d6040b"
|
||||||
@ -11800,6 +11867,11 @@ type-fest@^0.8.1:
|
|||||||
resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d"
|
resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d"
|
||||||
integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==
|
integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==
|
||||||
|
|
||||||
|
type-fest@^1.0.2:
|
||||||
|
version "1.4.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-1.4.0.tgz#e9fb813fe3bf1744ec359d55d1affefa76f14be1"
|
||||||
|
integrity sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==
|
||||||
|
|
||||||
type-is@~1.6.18:
|
type-is@~1.6.18:
|
||||||
version "1.6.18"
|
version "1.6.18"
|
||||||
resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131"
|
resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131"
|
||||||
@ -12592,6 +12664,15 @@ wrap-ansi@^7.0.0:
|
|||||||
string-width "^4.1.0"
|
string-width "^4.1.0"
|
||||||
strip-ansi "^6.0.0"
|
strip-ansi "^6.0.0"
|
||||||
|
|
||||||
|
wrap-ansi@^8.0.1, wrap-ansi@^8.1.0:
|
||||||
|
version "8.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214"
|
||||||
|
integrity sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==
|
||||||
|
dependencies:
|
||||||
|
ansi-styles "^6.1.0"
|
||||||
|
string-width "^5.0.1"
|
||||||
|
strip-ansi "^7.0.1"
|
||||||
|
|
||||||
wrappy@1:
|
wrappy@1:
|
||||||
version "1.0.2"
|
version "1.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
|
resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user