2024-06-06 07:41:01 +02:00
|
|
|
import { getThisCodebaseRootDirPath } from "./tools/getThisCodebaseRootDirPath";
|
|
|
|
import cliSelect from "cli-select";
|
|
|
|
import {
|
2024-07-13 19:33:59 +02:00
|
|
|
LOGIN_THEME_PAGE_IDS,
|
|
|
|
ACCOUNT_THEME_PAGE_IDS,
|
2024-06-06 07:41:01 +02:00
|
|
|
type LoginThemePageId,
|
|
|
|
type AccountThemePageId,
|
2024-10-26 21:23:18 +02:00
|
|
|
THEME_TYPES
|
2024-06-06 07:41:01 +02:00
|
|
|
} 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";
|
|
|
|
import { assert, Equals } from "tsafe/assert";
|
2024-10-05 20:30:09 +02:00
|
|
|
import type { BuildContext } from "./shared/buildContext";
|
2024-06-06 07:41:01 +02:00
|
|
|
import chalk from "chalk";
|
2024-11-09 14:02:19 +01:00
|
|
|
import { runPrettier, getIsPrettierAvailable } from "./tools/runPrettier";
|
2024-10-25 04:12:07 +02:00
|
|
|
import { maybeDelegateCommandToCustomHandler } from "./shared/customHandler_delegate";
|
2024-06-06 07:41:01 +02:00
|
|
|
|
2024-10-05 20:30:09 +02:00
|
|
|
export async function command(params: { buildContext: BuildContext }) {
|
|
|
|
const { buildContext } = params;
|
2024-06-06 07:41:01 +02:00
|
|
|
|
2024-10-25 04:12:07 +02:00
|
|
|
const { hasBeenHandled } = maybeDelegateCommandToCustomHandler({
|
|
|
|
commandName: "add-story",
|
|
|
|
buildContext
|
|
|
|
});
|
|
|
|
|
|
|
|
if (hasBeenHandled) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2024-06-06 07:41:01 +02:00
|
|
|
console.log(chalk.cyan("Theme type:"));
|
|
|
|
|
2024-07-28 19:37:15 +02:00
|
|
|
const themeType = await (async () => {
|
|
|
|
const values = THEME_TYPES.filter(themeType => {
|
2024-07-28 19:33:27 +02:00
|
|
|
switch (themeType) {
|
|
|
|
case "account":
|
|
|
|
return buildContext.implementedThemeTypes.account.isImplemented;
|
|
|
|
case "login":
|
|
|
|
return buildContext.implementedThemeTypes.login.isImplemented;
|
2024-10-26 21:23:18 +02:00
|
|
|
case "admin":
|
|
|
|
return buildContext.implementedThemeTypes.admin.isImplemented;
|
2024-07-28 19:33:27 +02:00
|
|
|
}
|
|
|
|
assert<Equals<typeof themeType, never>>(false);
|
2024-07-28 19:37:15 +02:00
|
|
|
});
|
|
|
|
|
|
|
|
assert(values.length > 0, "No theme is implemented in this project");
|
|
|
|
|
|
|
|
if (values.length === 1) {
|
|
|
|
return values[0];
|
|
|
|
}
|
|
|
|
|
2024-10-26 21:23:18 +02:00
|
|
|
const { value } = await cliSelect({
|
2024-07-28 19:37:15 +02:00
|
|
|
values
|
|
|
|
}).catch(() => {
|
|
|
|
process.exit(-1);
|
|
|
|
});
|
|
|
|
|
|
|
|
return value;
|
|
|
|
})();
|
2024-06-06 07:41:01 +02:00
|
|
|
|
2024-07-28 19:33:27 +02:00
|
|
|
if (
|
|
|
|
themeType === "account" &&
|
|
|
|
(assert(buildContext.implementedThemeTypes.account.isImplemented),
|
|
|
|
buildContext.implementedThemeTypes.account.type === "Single-Page")
|
|
|
|
) {
|
|
|
|
console.log(
|
|
|
|
`${chalk.red("✗")} Sorry, there is no Storybook support for Single-Page Account themes.`
|
|
|
|
);
|
|
|
|
|
|
|
|
process.exit(0);
|
2024-10-26 21:23:18 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (themeType === "admin") {
|
|
|
|
console.log(
|
2025-02-02 18:25:40 +01:00
|
|
|
`${chalk.red("✗")} Sorry, there is no Storybook support for the Admin UI.`
|
2024-10-26 21:23:18 +02:00
|
|
|
);
|
|
|
|
|
|
|
|
process.exit(0);
|
|
|
|
return;
|
2024-07-28 19:33:27 +02:00
|
|
|
}
|
|
|
|
|
2024-06-06 07:41:01 +02:00
|
|
|
console.log(`→ ${themeType}`);
|
|
|
|
|
|
|
|
console.log(chalk.cyan("Select the page you want to create a Storybook for:"));
|
|
|
|
|
|
|
|
const { value: pageId } = await cliSelect<LoginThemePageId | AccountThemePageId>({
|
|
|
|
values: (() => {
|
|
|
|
switch (themeType) {
|
|
|
|
case "login":
|
2024-07-13 19:33:59 +02:00
|
|
|
return [...LOGIN_THEME_PAGE_IDS];
|
2024-06-06 07:41:01 +02:00
|
|
|
case "account":
|
2024-07-13 19:33:59 +02:00
|
|
|
return [...ACCOUNT_THEME_PAGE_IDS];
|
2024-06-06 07:41:01 +02:00
|
|
|
}
|
|
|
|
assert<Equals<typeof themeType, never>>(false);
|
|
|
|
})()
|
|
|
|
}).catch(() => {
|
|
|
|
process.exit(-1);
|
|
|
|
});
|
|
|
|
|
|
|
|
console.log(`→ ${pageId}`);
|
|
|
|
|
|
|
|
const componentBasename = capitalize(kebabCaseToCamelCase(pageId)).replace(
|
|
|
|
/ftl$/,
|
|
|
|
"stories.tsx"
|
|
|
|
);
|
|
|
|
|
|
|
|
const targetFilePath = pathJoin(
|
2024-06-16 01:29:15 +02:00
|
|
|
buildContext.themeSrcDirPath,
|
2024-06-06 07:41:01 +02:00
|
|
|
themeType,
|
|
|
|
"pages",
|
|
|
|
componentBasename
|
|
|
|
);
|
|
|
|
|
|
|
|
if (fs.existsSync(targetFilePath)) {
|
|
|
|
console.log(`${pathRelative(process.cwd(), targetFilePath)} already exists`);
|
|
|
|
|
|
|
|
process.exit(-1);
|
|
|
|
}
|
|
|
|
|
2024-11-09 14:02:19 +01:00
|
|
|
let sourceCode = fs
|
2024-06-06 07:41:01 +02:00
|
|
|
.readFileSync(
|
|
|
|
pathJoin(
|
|
|
|
getThisCodebaseRootDirPath(),
|
|
|
|
"stories",
|
|
|
|
themeType,
|
|
|
|
"pages",
|
|
|
|
componentBasename
|
|
|
|
)
|
|
|
|
)
|
2024-06-06 09:13:40 +02:00
|
|
|
.toString("utf8")
|
2024-06-28 06:46:26 +02:00
|
|
|
.replace('import React from "react";\n', "")
|
|
|
|
.replace(/from "[./]+dist\//, 'from "keycloakify/');
|
2024-06-06 09:13:40 +02:00
|
|
|
|
2024-11-09 14:02:19 +01:00
|
|
|
run_prettier: {
|
|
|
|
if (!(await getIsPrettierAvailable())) {
|
|
|
|
break run_prettier;
|
|
|
|
}
|
|
|
|
|
|
|
|
sourceCode = await runPrettier({
|
|
|
|
filePath: targetFilePath,
|
|
|
|
sourceCode: sourceCode
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2024-06-06 09:13:40 +02:00
|
|
|
{
|
|
|
|
const targetDirPath = pathDirname(targetFilePath);
|
|
|
|
|
|
|
|
if (!fs.existsSync(targetDirPath)) {
|
|
|
|
fs.mkdirSync(targetDirPath, { recursive: true });
|
|
|
|
}
|
|
|
|
}
|
2024-06-06 07:41:01 +02:00
|
|
|
|
2024-11-09 14:02:19 +01:00
|
|
|
fs.writeFileSync(targetFilePath, Buffer.from(sourceCode, "utf8"));
|
2024-10-25 00:20:35 +00:00
|
|
|
|
2024-06-06 07:41:01 +02:00
|
|
|
console.log(
|
2024-06-06 09:13:40 +02:00
|
|
|
[
|
|
|
|
`${chalk.green("✓")} ${chalk.bold(
|
|
|
|
pathJoin(".", pathRelative(process.cwd(), targetFilePath))
|
|
|
|
)} copy pasted from the Keycloakify source code into your project`,
|
2024-06-15 11:27:03 +02:00
|
|
|
`You can start storybook with ${chalk.bold("npm run storybook")}`
|
2024-06-06 09:13:40 +02:00
|
|
|
].join("\n")
|
2024-06-06 07:41:01 +02:00
|
|
|
);
|
|
|
|
}
|