keycloak_theme/src/bin/eject-page.ts

177 lines
5.6 KiB
TypeScript
Raw Normal View History

#!/usr/bin/env node
import { getThisCodebaseRootDirPath } from "./tools/getThisCodebaseRootDirPath";
import cliSelect from "cli-select";
2024-05-19 04:02:36 +02:00
import {
loginThemePageIds,
accountThemePageIds,
type LoginThemePageId,
type AccountThemePageId,
themeTypes,
type ThemeType
} from "./shared/constants";
import { capitalize } from "tsafe/capitalize";
import * as fs from "fs";
import { join as pathJoin, relative as pathRelative, dirname as pathDirname } from "path";
import { kebabCaseToCamelCase } from "./tools/kebabCaseToSnakeCase";
2023-03-20 00:03:15 +01:00
import { assert, Equals } from "tsafe/assert";
import { getThemeSrcDirPath } from "./shared/getThemeSrcDirPath";
import type { CliCommandOptions } from "./main";
import { readBuildOptions } from "./shared/buildOptions";
2024-05-19 10:23:38 +02:00
import chalk from "chalk";
export async function command(params: { cliCommandOptions: CliCommandOptions }) {
const { cliCommandOptions } = params;
2023-03-20 00:03:15 +01:00
const buildOptions = readBuildOptions({
cliCommandOptions
});
2023-09-03 23:26:34 +02:00
2024-05-19 10:23:38 +02:00
console.log(chalk.cyan("Theme type:"));
2023-03-20 00:03:15 +01:00
const { value: themeType } = await cliSelect<ThemeType>({
2024-05-20 15:48:51 +02:00
values: [...themeTypes]
}).catch(() => {
process.exit(-1);
});
2024-05-19 10:23:38 +02:00
console.log(`${themeType}`);
console.log(chalk.cyan("Select the page you want to customize:"));
2023-03-20 00:03:15 +01:00
const { value: pageId } = await cliSelect<LoginThemePageId | AccountThemePageId>({
2024-05-20 15:48:51 +02:00
values: (() => {
2023-03-20 00:03:15 +01:00
switch (themeType) {
case "login":
return [...loginThemePageIds];
case "account":
return [...accountThemePageIds];
}
assert<Equals<typeof themeType, never>>(false);
})()
}).catch(() => {
process.exit(-1);
});
2024-05-19 10:23:38 +02:00
console.log(`${pageId}`);
2024-05-20 15:48:51 +02:00
const componentPageBasename = capitalize(kebabCaseToCamelCase(pageId)).replace(
/ftl$/,
"tsx"
);
2024-05-20 15:48:51 +02:00
const { themeSrcDirPath } = getThemeSrcDirPath({
reactAppRootDirPath: buildOptions.reactAppRootDirPath
});
2023-03-25 04:56:17 +01:00
2024-05-20 15:48:51 +02:00
const targetFilePath = pathJoin(
themeSrcDirPath,
themeType,
"pages",
componentPageBasename
);
if (fs.existsSync(targetFilePath)) {
2024-05-20 15:48:51 +02:00
console.log(
`${pageId} is already ejected, ${pathRelative(
process.cwd(),
targetFilePath
)} already exists`
);
process.exit(-1);
}
{
const targetDirPath = pathDirname(targetFilePath);
if (!fs.existsSync(targetDirPath)) {
2024-05-20 15:48:51 +02:00
fs.mkdirSync(targetDirPath, { recursive: true });
}
}
const componentPageContent = fs
2024-05-20 15:48:51 +02:00
.readFileSync(
pathJoin(
getThisCodebaseRootDirPath(),
"src",
themeType,
"pages",
componentPageBasename
)
)
.toString("utf8");
fs.writeFileSync(targetFilePath, Buffer.from(componentPageContent, "utf8"));
const userProfileFormFieldComponentName = "UserProfileFormFields";
console.log(
[
``,
2024-05-19 10:23:38 +02:00
`${chalk.green("✓")} ${chalk.bold(
pathJoin(".", pathRelative(process.cwd(), targetFilePath))
)} copy pasted from the Keycloakify source code into your project`,
``,
`You now need to update your page router:`,
``,
2024-05-20 15:48:51 +02:00
`${chalk.bold(
pathJoin(
".",
pathRelative(process.cwd(), themeSrcDirPath),
themeType,
"KcApp.tsx"
)
)}:`,
2024-05-19 10:23:38 +02:00
chalk.grey("```"),
`// ...`,
``,
2024-05-20 15:48:51 +02:00
chalk.green(
`+const ${componentPageBasename.replace(
/.tsx$/,
""
)} = lazy(() => import("./pages/${componentPageBasename}"));`
),
2024-05-19 10:23:38 +02:00
...[
``,
` export default function KcApp(props: { kcContext: KcContext; }) {`,
``,
` // ...`,
``,
` return (`,
` <Suspense>`,
` {(() => {`,
` switch (kcContext.pageId) {`,
` // ...`,
`+ case "${pageId}": return (`,
`+ <Login`,
`+ {...{ kcContext, i18n, classes }}`,
`+ Template={Template}`,
...(!componentPageContent.includes(userProfileFormFieldComponentName)
? []
2024-05-20 15:48:51 +02:00
: [
`+ ${userProfileFormFieldComponentName}={${userProfileFormFieldComponentName}}`
]),
2024-05-19 10:23:38 +02:00
`+ doUseDefaultCss={true}`,
`+ />`,
`+ );`,
` default: return <Fallback /* .. */ />;`,
` }`,
` })()}`,
` </Suspense>`,
` );`,
` }`
].map(line => {
if (line.startsWith("+")) {
return chalk.green(line);
}
if (line.startsWith("-")) {
return chalk.red(line);
}
return chalk.grey(line);
}),
chalk.grey("```")
].join("\n")
);
}