diff --git a/src/bin/eject-file.ts b/src/bin/eject-file.ts deleted file mode 100644 index 18d70ca9..00000000 --- a/src/bin/eject-file.ts +++ /dev/null @@ -1,68 +0,0 @@ -import type { BuildContext } from "./shared/buildContext"; -import { getUiModuleFileSourceCodeReadyToBeCopied } from "./postinstall/getUiModuleFileSourceCodeReadyToBeCopied"; -import { getAbsoluteAndInOsFormatPath } from "./tools/getAbsoluteAndInOsFormatPath"; -import { relative as pathRelative, dirname as pathDirname, join as pathJoin } from "path"; -import { getUiModuleMetas } from "./postinstall/uiModuleMeta"; -import { getInstalledModuleDirPath } from "./tools/getInstalledModuleDirPath"; -import * as fsPr from "fs/promises"; -import { - readManagedGitignoreFile, - writeManagedGitignoreFile -} from "./postinstall/managedGitignoreFile"; - -export async function command(params: { - buildContext: BuildContext; - cliCommandOptions: { - file: string; - }; -}) { - const { buildContext, cliCommandOptions } = params; - - const fileRelativePath = pathRelative( - buildContext.themeSrcDirPath, - getAbsoluteAndInOsFormatPath({ - cwd: buildContext.themeSrcDirPath, - pathIsh: cliCommandOptions.file - }) - ); - - const uiModuleMetas = await getUiModuleMetas({ buildContext }); - - const uiModuleMeta = uiModuleMetas.find(({ files }) => - files.map(({ fileRelativePath }) => fileRelativePath).includes(fileRelativePath) - ); - - if (!uiModuleMeta) { - throw new Error(`No UI module found for the file ${fileRelativePath}`); - } - - const uiModuleDirPath = await getInstalledModuleDirPath({ - moduleName: uiModuleMeta.moduleName, - packageJsonDirPath: pathDirname(buildContext.packageJsonFilePath), - projectDirPath: buildContext.projectDirPath - }); - - const sourceCode = await getUiModuleFileSourceCodeReadyToBeCopied({ - buildContext, - fileRelativePath, - isForEjection: true, - uiModuleName: uiModuleMeta.moduleName, - uiModuleDirPath, - uiModuleVersion: uiModuleMeta.version - }); - - await fsPr.writeFile( - pathJoin(buildContext.themeSrcDirPath, fileRelativePath), - sourceCode - ); - - const { ejectedFilesRelativePaths } = await readManagedGitignoreFile({ - buildContext - }); - - await writeManagedGitignoreFile({ - buildContext, - uiModuleMetas, - ejectedFilesRelativePaths: [...ejectedFilesRelativePaths, fileRelativePath] - }); -} diff --git a/src/bin/eject-page.ts b/src/bin/eject-page.ts index e411c9a6..ddaf152e 100644 --- a/src/bin/eject-page.ts +++ b/src/bin/eject-page.ts @@ -67,9 +67,7 @@ export async function command(params: { buildContext: BuildContext }) { })(); if (themeType === "admin") { - console.log( - "Use `npx keycloakify eject-file` command instead, see documentation" - ); + console.log("Use `npx keycloakify own` command instead, see documentation"); process.exit(-1); } diff --git a/src/bin/main.ts b/src/bin/main.ts index d737c692..f74eb5f4 100644 --- a/src/bin/main.ts +++ b/src/bin/main.ts @@ -262,37 +262,38 @@ program program .command<{ - file: string; + path: string; }>({ - name: "eject-file", + name: "own", description: [ "WARNING: Not usable yet, will be used for future features", "Take ownership over a given file" ].join(" ") }) .option({ - key: "file", + key: "path", name: (() => { - const long = "file"; - const short = "f"; + const long = "path"; + const short = "p"; optionsKeys.push(long, short); return { long, short }; })(), description: [ - "Relative path of the file relative to the directory of your keycloak theme source", - "Example `--file src/login/page/Login.tsx`" + "Relative path of the file or the directory that you want to take ownership over.", + "The path is relative to your theme directory.", + "Example `--path admin/page/Login.tsx`" ].join(" ") }) .task({ skip, - handler: async ({ projectDirPath, file }) => { - const { command } = await import("./eject-file"); + handler: async ({ projectDirPath, path }) => { + const { command } = await import("./own"); await command({ buildContext: getBuildContext({ projectDirPath }), - cliCommandOptions: { file } + cliCommandOptions: { path } }); } }); diff --git a/src/bin/own.ts b/src/bin/own.ts new file mode 100644 index 00000000..2cbf52c8 --- /dev/null +++ b/src/bin/own.ts @@ -0,0 +1,96 @@ +import type { BuildContext } from "./shared/buildContext"; +import { getUiModuleFileSourceCodeReadyToBeCopied } from "./postinstall/getUiModuleFileSourceCodeReadyToBeCopied"; +import { getAbsoluteAndInOsFormatPath } from "./tools/getAbsoluteAndInOsFormatPath"; +import { relative as pathRelative, dirname as pathDirname, join as pathJoin } from "path"; +import { getUiModuleMetas } from "./postinstall/uiModuleMeta"; +import { getInstalledModuleDirPath } from "./tools/getInstalledModuleDirPath"; +import * as fsPr from "fs/promises"; +import { + readManagedGitignoreFile, + writeManagedGitignoreFile +} from "./postinstall/managedGitignoreFile"; +import { isInside } from "./tools/isInside"; +import chalk from "chalk"; + +export async function command(params: { + buildContext: BuildContext; + cliCommandOptions: { + path: string; + }; +}) { + const { buildContext, cliCommandOptions } = params; + + const fileOrDirectoryRelativePath = pathRelative( + buildContext.themeSrcDirPath, + getAbsoluteAndInOsFormatPath({ + cwd: buildContext.themeSrcDirPath, + pathIsh: cliCommandOptions.path + }) + ); + + const uiModuleMetas = await getUiModuleMetas({ buildContext }); + + const fileRelativePaths = uiModuleMetas + .map(({ files }) => + files + .map(({ fileRelativePath }) => fileRelativePath) + .filter( + fileRelativePath => + fileRelativePath === fileOrDirectoryRelativePath || + isInside({ + dirPath: fileOrDirectoryRelativePath, + filePath: fileRelativePath + }) + ) + ) + .flat(); + + if (fileRelativePaths.length === 0) { + console.log( + chalk.yellow("There is no UI module files matching the provided path.") + ); + process.exit(1); + } + + for (const fileRelativePath of fileRelativePaths) { + const uiModuleMeta = uiModuleMetas.find(({ files }) => + files + .map(({ fileRelativePath }) => fileRelativePath) + .includes(fileRelativePath) + ); + + if (!uiModuleMeta) { + throw new Error(`No UI module found for the file ${fileRelativePath}`); + } + + const uiModuleDirPath = await getInstalledModuleDirPath({ + moduleName: uiModuleMeta.moduleName, + packageJsonDirPath: pathDirname(buildContext.packageJsonFilePath), + projectDirPath: buildContext.projectDirPath + }); + + const sourceCode = await getUiModuleFileSourceCodeReadyToBeCopied({ + buildContext, + fileRelativePath, + isForEjection: true, + uiModuleName: uiModuleMeta.moduleName, + uiModuleDirPath, + uiModuleVersion: uiModuleMeta.version + }); + + await fsPr.writeFile( + pathJoin(buildContext.themeSrcDirPath, fileRelativePath), + sourceCode + ); + + const { ejectedFilesRelativePaths } = await readManagedGitignoreFile({ + buildContext + }); + + await writeManagedGitignoreFile({ + buildContext, + uiModuleMetas, + ejectedFilesRelativePaths: [...ejectedFilesRelativePaths, fileRelativePath] + }); + } +} diff --git a/src/bin/postinstall/getUiModuleFileSourceCodeReadyToBeCopied.ts b/src/bin/postinstall/getUiModuleFileSourceCodeReadyToBeCopied.ts index fe3f6e81..a89605b0 100644 --- a/src/bin/postinstall/getUiModuleFileSourceCodeReadyToBeCopied.ts +++ b/src/bin/postinstall/getUiModuleFileSourceCodeReadyToBeCopied.ts @@ -40,7 +40,7 @@ export async function getUiModuleFileSourceCodeReadyToBeCopied(params: { : [ `WARNING: Before modifying this file run the following command:`, ``, - `$ npx keycloakify eject-file --file '${fileRelativePath.split(pathSep).join("/")}'`, + `$ npx keycloakify own --path '${fileRelativePath.split(pathSep).join("/")}'`, ``, `This file comes from ${uiModuleName} version ${uiModuleVersion}.`, `This file has been copied over to your repo by your postinstall script: \`npx keycloakify postinstall\`` @@ -93,7 +93,7 @@ function addCommentToSourceCode(params: { `` ].join("\n");