diff --git a/src/bin/initialize-admin-theme.ts b/src/bin/initialize-admin-theme.ts index a1eb46cc..24706406 100644 --- a/src/bin/initialize-admin-theme.ts +++ b/src/bin/initialize-admin-theme.ts @@ -4,7 +4,7 @@ import * as fs from "fs"; import { maybeDelegateCommandToCustomHandler } from "./shared/customHandler_delegate"; import { assert, is, type Equals } from "tsafe/assert"; import { id } from "tsafe/id"; -import { addPostinstallScriptIfNotPresent } from "./shared/addPostinstallScriptIfNotPresent"; +import { addSyncExtensionsToPostinstallScript } from "./shared/addSyncExtensionsToPostinstallScript"; import { getIsPrettierAvailable, runPrettier } from "./tools/runPrettier"; import { npmInstall } from "./tools/npmInstall"; import * as child_process from "child_process"; @@ -74,7 +74,7 @@ export async function command(params: { buildContext: BuildContext }) { return parsedPackageJson; })(); - addPostinstallScriptIfNotPresent({ + addSyncExtensionsToPostinstallScript({ parsedPackageJson, buildContext }); diff --git a/src/bin/main.ts b/src/bin/main.ts index 7deaae6a..cf99ef40 100644 --- a/src/bin/main.ts +++ b/src/bin/main.ts @@ -248,13 +248,30 @@ program program .command({ - name: "postinstall", - description: "Initialize all the Keycloakify UI modules installed in the project." + name: "sync-extensions", + description: [ + "Synchronizes all installed Keycloakify extension modules with your project.", + "", + "Example of extension modules: '@keycloakify/keycloak-account-ui', '@keycloakify/keycloak-admin-ui', '@keycloakify/keycloak-ui-shared'", + "", + "This command ensures that:", + "- All required files from installed extensions are copied into your project.", + "- The copied files are correctly ignored by Git to help you distinguish between your custom source files", + " and those provided by the extensions.", + "- Peer dependencies declared by the extensions are automatically added to your package.json.", + "", + "You can safely run this command multiple times. It will only update the files and dependencies if needed,", + "ensuring your project stays in sync with the installed extensions.", + "", + "Typical usage:", + "- Should be run as a postinstall script of your project.", + "" + ].join("\n") }) .task({ skip, handler: async ({ projectDirPath }) => { - const { command } = await import("./postinstall"); + const { command } = await import("./sync-extensions"); await command({ buildContext: getBuildContext({ projectDirPath }) }); } @@ -267,9 +284,20 @@ program }>({ name: "own", description: [ - "WARNING: Not usable yet, will be used for future features", - "Take ownership over a given file" - ].join(" ") + "Manages ownership of auto-generated files provided by Keycloakify extensions.", + "", + "This command allows you to take ownership of a specific file or directory generated", + "by an extension. Once owned, you can freely modify and version-control the file.", + "", + "You can also use the --revert flag to relinquish ownership and restore the file", + "or directory to its original auto-generated state.", + "", + "For convenience, the exact command to take ownership of any file is included as a comment", + "in the header of each extension-generated file.", + "", + "Examples:", + "$ npx keycloakify own --path admin/KcPage.tsx" + ].join("\n") }) .option({ key: "path", @@ -282,9 +310,9 @@ program return { long, short }; })(), description: [ - "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`" + "Specifies the relative path of the file or directory to take ownership of.", + "This path should be relative to your theme directory.", + "Example: `--path 'admin/KcPage.tsx'`" ].join(" ") }) .option({ @@ -296,7 +324,10 @@ program return name; })(), - description: "Revert ownership claim over a given file or directory.", + description: [ + "Restores a file or directory to its original auto-generated state,", + "removing your ownership claim and reverting any modifications." + ].join(" "), defaultValue: false }) .task({ diff --git a/src/bin/own.ts b/src/bin/own.ts index 9c024972..83f3b6be 100644 --- a/src/bin/own.ts +++ b/src/bin/own.ts @@ -1,18 +1,18 @@ 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 { getExtensionModuleFileSourceCodeReadyToBeCopied } from "./sync-extensions/getExtensionModuleFileSourceCodeReadyToBeCopied"; +import type { ExtensionModuleMeta } from "./sync-extensions/extensionModuleMeta"; +import { command as command_syncExtensions } from "./sync-extensions/sync-extension"; import { readManagedGitignoreFile, writeManagedGitignoreFile -} from "./postinstall/managedGitignoreFile"; +} from "./sync-extensions/managedGitignoreFile"; +import { getExtensionModuleMetas } from "./sync-extensions/extensionModuleMeta"; +import { getAbsoluteAndInOsFormatPath } from "./tools/getAbsoluteAndInOsFormatPath"; +import { relative as pathRelative, dirname as pathDirname, join as pathJoin } from "path"; +import { getInstalledModuleDirPath } from "./tools/getInstalledModuleDirPath"; +import * as fsPr from "fs/promises"; import { isInside } from "./tools/isInside"; import chalk from "chalk"; -import type { UiModuleMeta } from "./postinstall/uiModuleMeta"; -import { command as command_postinstall } from "./postinstall"; export async function command(params: { buildContext: BuildContext; @@ -23,9 +23,9 @@ export async function command(params: { }) { const { buildContext, cliCommandOptions } = params; - const uiModuleMetas = await getUiModuleMetas({ buildContext }); + const extensionModuleMetas = await getExtensionModuleMetas({ buildContext }); - const { targetFileRelativePathsByUiModuleMeta } = await (async () => { + const { targetFileRelativePathsByExtensionModuleMeta } = await (async () => { const fileOrDirectoryRelativePath = pathRelative( buildContext.themeSrcDirPath, getAbsoluteAndInOsFormatPath({ @@ -34,10 +34,10 @@ export async function command(params: { }) ); - const arr = uiModuleMetas - .map(uiModuleMeta => ({ - uiModuleMeta, - fileRelativePaths: uiModuleMeta.files + const arr = extensionModuleMetas + .map(extensionModuleMeta => ({ + extensionModuleMeta, + fileRelativePaths: extensionModuleMeta.files .map(({ fileRelativePath }) => fileRelativePath) .filter( fileRelativePath => @@ -50,18 +50,26 @@ export async function command(params: { })) .filter(({ fileRelativePaths }) => fileRelativePaths.length !== 0); - const targetFileRelativePathsByUiModuleMeta = new Map(); + const targetFileRelativePathsByExtensionModuleMeta = new Map< + ExtensionModuleMeta, + string[] + >(); - for (const { uiModuleMeta, fileRelativePaths } of arr) { - targetFileRelativePathsByUiModuleMeta.set(uiModuleMeta, fileRelativePaths); + for (const { extensionModuleMeta, fileRelativePaths } of arr) { + targetFileRelativePathsByExtensionModuleMeta.set( + extensionModuleMeta, + fileRelativePaths + ); } - return { targetFileRelativePathsByUiModuleMeta }; + return { targetFileRelativePathsByExtensionModuleMeta }; })(); - if (targetFileRelativePathsByUiModuleMeta.size === 0) { + if (targetFileRelativePathsByExtensionModuleMeta.size === 0) { console.log( - chalk.yellow("There is no UI module files matching the provided path.") + chalk.yellow( + "There is no Keycloakify extension modules files matching the provided path." + ) ); process.exit(1); } @@ -72,34 +80,34 @@ export async function command(params: { }); await (cliCommandOptions.isRevert ? command_revert : command_own)({ - uiModuleMetas, - targetFileRelativePathsByUiModuleMeta, + extensionModuleMetas, + targetFileRelativePathsByExtensionModuleMeta, ownedFilesRelativePaths_current, buildContext }); } type Params_subcommands = { - uiModuleMetas: UiModuleMeta[]; - targetFileRelativePathsByUiModuleMeta: Map; + extensionModuleMetas: ExtensionModuleMeta[]; + targetFileRelativePathsByExtensionModuleMeta: Map; ownedFilesRelativePaths_current: string[]; buildContext: BuildContext; }; async function command_own(params: Params_subcommands) { const { - uiModuleMetas, - targetFileRelativePathsByUiModuleMeta, + extensionModuleMetas, + targetFileRelativePathsByExtensionModuleMeta, ownedFilesRelativePaths_current, buildContext } = params; await writeManagedGitignoreFile({ buildContext, - uiModuleMetas, + extensionModuleMetas, ownedFilesRelativePaths: [ ...ownedFilesRelativePaths_current, - ...Array.from(targetFileRelativePathsByUiModuleMeta.values()) + ...Array.from(targetFileRelativePathsByExtensionModuleMeta.values()) .flat() .filter( fileRelativePath => @@ -111,11 +119,11 @@ async function command_own(params: Params_subcommands) { const writeActions: (() => Promise)[] = []; for (const [ - uiModuleMeta, + extensionModuleMeta, fileRelativePaths - ] of targetFileRelativePathsByUiModuleMeta.entries()) { - const uiModuleDirPath = await getInstalledModuleDirPath({ - moduleName: uiModuleMeta.moduleName, + ] of targetFileRelativePathsByExtensionModuleMeta.entries()) { + const extensionModuleDirPath = await getInstalledModuleDirPath({ + moduleName: extensionModuleMeta.moduleName, packageJsonDirPath: pathDirname(buildContext.packageJsonFilePath), projectDirPath: buildContext.projectDirPath }); @@ -129,13 +137,13 @@ async function command_own(params: Params_subcommands) { } writeActions.push(async () => { - const sourceCode = await getUiModuleFileSourceCodeReadyToBeCopied({ + const sourceCode = await getExtensionModuleFileSourceCodeReadyToBeCopied({ buildContext, fileRelativePath, isOwnershipAction: true, - uiModuleName: uiModuleMeta.moduleName, - uiModuleDirPath, - uiModuleVersion: uiModuleMeta.version + extensionModuleName: extensionModuleMeta.moduleName, + extensionModuleDirPath, + extensionModuleVersion: extensionModuleMeta.version }); await fsPr.writeFile( @@ -158,14 +166,14 @@ async function command_own(params: Params_subcommands) { async function command_revert(params: Params_subcommands) { const { - uiModuleMetas, - targetFileRelativePathsByUiModuleMeta, + extensionModuleMetas, + targetFileRelativePathsByExtensionModuleMeta, ownedFilesRelativePaths_current, buildContext } = params; const ownedFilesRelativePaths_toRemove = Array.from( - targetFileRelativePathsByUiModuleMeta.values() + targetFileRelativePathsByExtensionModuleMeta.values() ) .flat() .filter(fileRelativePath => { @@ -190,12 +198,12 @@ async function command_revert(params: Params_subcommands) { await writeManagedGitignoreFile({ buildContext, - uiModuleMetas, + extensionModuleMetas, ownedFilesRelativePaths: ownedFilesRelativePaths_current.filter( fileRelativePath => !ownedFilesRelativePaths_toRemove.includes(fileRelativePath) ) }); - await command_postinstall({ buildContext }); + await command_syncExtensions({ buildContext }); } diff --git a/src/bin/postinstall/index.ts b/src/bin/postinstall/index.ts deleted file mode 100644 index 7f1cc290..00000000 --- a/src/bin/postinstall/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from "./postinstall"; diff --git a/src/bin/shared/addPostinstallScriptIfNotPresent.ts b/src/bin/shared/addSyncExtensionsToPostinstallScript.ts similarity index 94% rename from src/bin/shared/addPostinstallScriptIfNotPresent.ts rename to src/bin/shared/addSyncExtensionsToPostinstallScript.ts index d7094c96..78d71353 100644 --- a/src/bin/shared/addPostinstallScriptIfNotPresent.ts +++ b/src/bin/shared/addSyncExtensionsToPostinstallScript.ts @@ -9,13 +9,13 @@ export type BuildContextLike = { assert(); -export function addPostinstallScriptIfNotPresent(params: { +export function addSyncExtensionsToPostinstallScript(params: { parsedPackageJson: { scripts?: Record }; buildContext: BuildContextLike; }) { const { parsedPackageJson, buildContext } = params; - const cmd_base = "keycloakify postinstall"; + const cmd_base = "keycloakify sync-extensions"; const projectCliOptionValue = (() => { const packageJsonDirPath = pathDirname(buildContext.packageJsonFilePath); diff --git a/src/bin/postinstall/uiModuleMeta.ts b/src/bin/sync-extensions/extensionModuleMeta.ts similarity index 75% rename from src/bin/postinstall/uiModuleMeta.ts rename to src/bin/sync-extensions/extensionModuleMeta.ts index 9c978f12..3cc7d8d3 100644 --- a/src/bin/postinstall/uiModuleMeta.ts +++ b/src/bin/sync-extensions/extensionModuleMeta.ts @@ -10,15 +10,15 @@ import { crawlAsync } from "../tools/crawlAsync"; import { getIsPrettierAvailable, getPrettier } from "../tools/runPrettier"; import { readThisNpmPackageVersion } from "../tools/readThisNpmPackageVersion"; import { - getUiModuleFileSourceCodeReadyToBeCopied, - type BuildContextLike as BuildContextLike_getUiModuleFileSourceCodeReadyToBeCopied -} from "./getUiModuleFileSourceCodeReadyToBeCopied"; + getExtensionModuleFileSourceCodeReadyToBeCopied, + type BuildContextLike as BuildContextLike_getExtensionModuleFileSourceCodeReadyToBeCopied +} from "./getExtensionModuleFileSourceCodeReadyToBeCopied"; import * as crypto from "crypto"; import { KEYCLOAK_THEME } from "../shared/constants"; import { exclude } from "tsafe/exclude"; import { isAmong } from "tsafe/isAmong"; -export type UiModuleMeta = { +export type ExtensionModuleMeta = { moduleName: string; version: string; files: { @@ -29,8 +29,8 @@ export type UiModuleMeta = { peerDependencies: Record; }; -const zUiModuleMeta = (() => { - type ExpectedType = UiModuleMeta; +const zExtensionModuleMeta = (() => { + type ExpectedType = ExtensionModuleMeta; const zTargetType = z.object({ moduleName: z.string(), @@ -56,7 +56,7 @@ type ParsedCacheFile = { keycloakifyVersion: string; prettierConfigHash: string | null; thisFilePath: string; - uiModuleMetas: UiModuleMeta[]; + extensionModuleMetas: ExtensionModuleMeta[]; }; const zParsedCacheFile = (() => { @@ -66,7 +66,7 @@ const zParsedCacheFile = (() => { keycloakifyVersion: z.string(), prettierConfigHash: z.union([z.string(), z.null()]), thisFilePath: z.string(), - uiModuleMetas: z.array(zUiModuleMeta) + extensionModuleMetas: z.array(zExtensionModuleMeta) }); type InferredType = z.infer; @@ -76,10 +76,10 @@ const zParsedCacheFile = (() => { return id>(zTargetType); })(); -const CACHE_FILE_RELATIVE_PATH = pathJoin("ui-modules", "cache.json"); +const CACHE_FILE_RELATIVE_PATH = pathJoin("extension-modules", "cache.json"); export type BuildContextLike = - BuildContextLike_getUiModuleFileSourceCodeReadyToBeCopied & { + BuildContextLike_getExtensionModuleFileSourceCodeReadyToBeCopied & { cacheDirPath: string; packageJsonFilePath: string; projectDirPath: string; @@ -87,9 +87,9 @@ export type BuildContextLike = assert(); -export async function getUiModuleMetas(params: { +export async function getExtensionModuleMetas(params: { buildContext: BuildContextLike; -}): Promise { +}): Promise { const { buildContext } = params; const cacheFilePath = pathJoin(buildContext.cacheDirPath, CACHE_FILE_RELATIVE_PATH); @@ -106,7 +106,7 @@ export async function getUiModuleMetas(params: { return configHash; })(); - const installedUiModules = await (async () => { + const installedExtensionModules = await (async () => { const installedModulesWithKeycloakifyInTheName = await listInstalledModules({ packageJsonFilePath: buildContext.packageJsonFilePath, projectDirPath: buildContext.packageJsonFilePath, @@ -134,7 +134,7 @@ export async function getUiModuleMetas(params: { return await fsPr.readFile(cacheFilePath); })(); - const uiModuleMetas_cacheUpToDate: UiModuleMeta[] = await (async () => { + const extensionModuleMetas_cacheUpToDate: ExtensionModuleMeta[] = await (async () => { const parsedCacheFile: ParsedCacheFile | undefined = await (async () => { if (cacheContent === undefined) { return undefined; @@ -177,45 +177,51 @@ export async function getUiModuleMetas(params: { return []; } - const uiModuleMetas_cacheUpToDate = parsedCacheFile.uiModuleMetas.filter( - uiModuleMeta => { - const correspondingInstalledUiModule = installedUiModules.find( - installedUiModule => - installedUiModule.moduleName === uiModuleMeta.moduleName - ); + const extensionModuleMetas_cacheUpToDate = + parsedCacheFile.extensionModuleMetas.filter(extensionModuleMeta => { + const correspondingInstalledExtensionModule = + installedExtensionModules.find( + installedExtensionModule => + installedExtensionModule.moduleName === + extensionModuleMeta.moduleName + ); - if (correspondingInstalledUiModule === undefined) { + if (correspondingInstalledExtensionModule === undefined) { return false; } - return correspondingInstalledUiModule.version === uiModuleMeta.version; - } - ); + return ( + correspondingInstalledExtensionModule.version === + extensionModuleMeta.version + ); + }); - return uiModuleMetas_cacheUpToDate; + return extensionModuleMetas_cacheUpToDate; })(); - const uiModuleMetas = await Promise.all( - installedUiModules.map( + const extensionModuleMetas = await Promise.all( + installedExtensionModules.map( async ({ moduleName, version, peerDependencies, dirPath - }): Promise => { + }): Promise => { use_cache: { - const uiModuleMeta_cache = uiModuleMetas_cacheUpToDate.find( - uiModuleMeta => uiModuleMeta.moduleName === moduleName - ); + const extensionModuleMeta_cache = + extensionModuleMetas_cacheUpToDate.find( + extensionModuleMeta => + extensionModuleMeta.moduleName === moduleName + ); - if (uiModuleMeta_cache === undefined) { + if (extensionModuleMeta_cache === undefined) { break use_cache; } - return uiModuleMeta_cache; + return extensionModuleMeta_cache; } - const files: UiModuleMeta["files"] = []; + const files: ExtensionModuleMeta["files"] = []; { const srcDirPath = pathJoin(dirPath, KEYCLOAK_THEME); @@ -225,13 +231,13 @@ export async function getUiModuleMetas(params: { returnedPathsType: "relative to dirPath", onFileFound: async fileRelativePath => { const sourceCode = - await getUiModuleFileSourceCodeReadyToBeCopied({ + await getExtensionModuleFileSourceCodeReadyToBeCopied({ buildContext, fileRelativePath, isOwnershipAction: false, - uiModuleDirPath: dirPath, - uiModuleName: moduleName, - uiModuleVersion: version + extensionModuleDirPath: dirPath, + extensionModuleName: moduleName, + extensionModuleVersion: version }); const hash = computeHash(sourceCode); @@ -261,7 +267,7 @@ export async function getUiModuleMetas(params: { }); } - return id({ + return id({ moduleName, version, files, @@ -281,7 +287,7 @@ export async function getUiModuleMetas(params: { keycloakifyVersion, prettierConfigHash, thisFilePath: cacheFilePath, - uiModuleMetas + extensionModuleMetas }); const cacheContent_new = Buffer.from( @@ -306,7 +312,7 @@ export async function getUiModuleMetas(params: { await fsPr.writeFile(cacheFilePath, cacheContent_new); } - return uiModuleMetas; + return extensionModuleMetas; } export function computeHash(data: Buffer) { diff --git a/src/bin/postinstall/getUiModuleFileSourceCodeReadyToBeCopied.ts b/src/bin/sync-extensions/getExtensionModuleFileSourceCodeReadyToBeCopied.ts similarity index 83% rename from src/bin/postinstall/getUiModuleFileSourceCodeReadyToBeCopied.ts rename to src/bin/sync-extensions/getExtensionModuleFileSourceCodeReadyToBeCopied.ts index c8f55f70..6dcebe3b 100644 --- a/src/bin/postinstall/getUiModuleFileSourceCodeReadyToBeCopied.ts +++ b/src/bin/sync-extensions/getExtensionModuleFileSourceCodeReadyToBeCopied.ts @@ -11,25 +11,27 @@ export type BuildContextLike = { assert(); -export async function getUiModuleFileSourceCodeReadyToBeCopied(params: { +export async function getExtensionModuleFileSourceCodeReadyToBeCopied(params: { buildContext: BuildContextLike; fileRelativePath: string; isOwnershipAction: boolean; - uiModuleDirPath: string; - uiModuleName: string; - uiModuleVersion: string; + extensionModuleDirPath: string; + extensionModuleName: string; + extensionModuleVersion: string; }): Promise { const { buildContext, - uiModuleDirPath, + extensionModuleDirPath, fileRelativePath, isOwnershipAction, - uiModuleName, - uiModuleVersion + extensionModuleName, + extensionModuleVersion } = params; let sourceCode = ( - await fsPr.readFile(pathJoin(uiModuleDirPath, KEYCLOAK_THEME, fileRelativePath)) + await fsPr.readFile( + pathJoin(extensionModuleDirPath, KEYCLOAK_THEME, fileRelativePath) + ) ).toString("utf8"); sourceCode = addCommentToSourceCode({ @@ -40,18 +42,18 @@ export async function getUiModuleFileSourceCodeReadyToBeCopied(params: { return isOwnershipAction ? [ - `This file has been claimed for ownership from ${uiModuleName} version ${uiModuleVersion}.`, + `This file has been claimed for ownership from ${extensionModuleName} version ${extensionModuleVersion}.`, `To relinquish ownership and restore this file to its original content, run the following command:`, ``, - `$ npx keycloakify own --revert --path '${path}'` + `$ npx keycloakify own --path '${path}' --revert` ] : [ `WARNING: Before modifying this file, run the following command:`, ``, `$ npx keycloakify own --path '${path}'`, ``, - `This file is provided by ${uiModuleName} version ${uiModuleVersion}.`, - `It was copied into your repository by the postinstall script: \`keycloakify postinstall\`.` + `This file is provided by ${extensionModuleName} version ${extensionModuleVersion}.`, + `It was copied into your repository by the postinstall script: \`keycloakify sync-extensions\`.` ]; })() }); diff --git a/src/bin/sync-extensions/index.ts b/src/bin/sync-extensions/index.ts new file mode 100644 index 00000000..d91bb8e2 --- /dev/null +++ b/src/bin/sync-extensions/index.ts @@ -0,0 +1 @@ +export * from "./sync-extension"; diff --git a/src/bin/postinstall/installUiModulesPeerDependencies.ts b/src/bin/sync-extensions/installExtensionModulesPeerDependencies.ts similarity index 83% rename from src/bin/postinstall/installUiModulesPeerDependencies.ts rename to src/bin/sync-extensions/installExtensionModulesPeerDependencies.ts index 416e0fd5..602e3ede 100644 --- a/src/bin/postinstall/installUiModulesPeerDependencies.ts +++ b/src/bin/sync-extensions/installExtensionModulesPeerDependencies.ts @@ -1,6 +1,6 @@ import { assert, type Equals, is } from "tsafe/assert"; import type { BuildContext } from "../shared/buildContext"; -import type { UiModuleMeta } from "./uiModuleMeta"; +import type { ExtensionModuleMeta } from "./extensionModuleMeta"; import { z } from "zod"; import { id } from "tsafe/id"; import * as fsPr from "fs/promises"; @@ -16,29 +16,29 @@ export type BuildContextLike = { assert(); -export type UiModuleMetaLike = { +export type ExtensionModuleMetaLike = { moduleName: string; peerDependencies: Record; }; -assert(); +assert(); -export async function installUiModulesPeerDependencies(params: { +export async function installExtensionModulesPeerDependencies(params: { buildContext: BuildContextLike; - uiModuleMetas: UiModuleMetaLike[]; + extensionModuleMetas: ExtensionModuleMetaLike[]; }): Promise { - const { buildContext, uiModuleMetas } = params; + const { buildContext, extensionModuleMetas } = params; - const { uiModulesPerDependencies } = (() => { - const uiModulesPerDependencies: Record = {}; + const { extensionModulesPerDependencies } = (() => { + const extensionModulesPerDependencies: Record = {}; - for (const { peerDependencies } of uiModuleMetas) { + for (const { peerDependencies } of extensionModuleMetas) { for (const [peerDependencyName, versionRange_candidate] of Object.entries( peerDependencies )) { const versionRange = (() => { const versionRange_current = - uiModulesPerDependencies[peerDependencyName]; + extensionModulesPerDependencies[peerDependencyName]; if (versionRange_current === undefined) { return versionRange_candidate; @@ -76,11 +76,11 @@ export async function installUiModulesPeerDependencies(params: { return versionRange; })(); - uiModulesPerDependencies[peerDependencyName] = versionRange; + extensionModulesPerDependencies[peerDependencyName] = versionRange; } } - return { uiModulesPerDependencies }; + return { extensionModulesPerDependencies }; })(); const parsedPackageJson = await (async () => { @@ -117,7 +117,9 @@ export async function installUiModulesPeerDependencies(params: { const parsedPackageJson_before = JSON.parse(JSON.stringify(parsedPackageJson)); - for (const [moduleName, versionRange] of Object.entries(uiModulesPerDependencies)) { + for (const [moduleName, versionRange] of Object.entries( + extensionModulesPerDependencies + )) { if (moduleName.startsWith("@types/")) { (parsedPackageJson.devDependencies ??= {})[moduleName] = versionRange; continue; diff --git a/src/bin/postinstall/managedGitignoreFile.ts b/src/bin/sync-extensions/managedGitignoreFile.ts similarity index 88% rename from src/bin/postinstall/managedGitignoreFile.ts rename to src/bin/sync-extensions/managedGitignoreFile.ts index 0c0ea791..a9e3d4a5 100644 --- a/src/bin/postinstall/managedGitignoreFile.ts +++ b/src/bin/sync-extensions/managedGitignoreFile.ts @@ -7,7 +7,7 @@ import { } from "path"; import { assert } from "tsafe/assert"; import type { BuildContext } from "../shared/buildContext"; -import type { UiModuleMeta } from "./uiModuleMeta"; +import type { ExtensionModuleMeta } from "./extensionModuleMeta"; import { existsAsync } from "../tools/fs.existsAsync"; import { getAbsoluteAndInOsFormatPath } from "../tools/getAbsoluteAndInOsFormatPath"; @@ -22,12 +22,12 @@ const DELIMITER_END = `# === Owned files end =====`; export async function writeManagedGitignoreFile(params: { buildContext: BuildContextLike; - uiModuleMetas: UiModuleMeta[]; + extensionModuleMetas: ExtensionModuleMeta[]; ownedFilesRelativePaths: string[]; }): Promise { - const { buildContext, uiModuleMetas, ownedFilesRelativePaths } = params; + const { buildContext, extensionModuleMetas, ownedFilesRelativePaths } = params; - if (uiModuleMetas.length === 0) { + if (extensionModuleMetas.length === 0) { return; } @@ -43,10 +43,10 @@ export async function writeManagedGitignoreFile(params: { .map(line => `# ${line}`), DELIMITER_END, ``, - ...uiModuleMetas - .map(uiModuleMeta => [ - `# === ${uiModuleMeta.moduleName} v${uiModuleMeta.version} ===`, - ...uiModuleMeta.files + ...extensionModuleMetas + .map(extensionModuleMeta => [ + `# === ${extensionModuleMeta.moduleName} v${extensionModuleMeta.version} ===`, + ...extensionModuleMeta.files .map(({ fileRelativePath }) => fileRelativePath) .filter( fileRelativePath => diff --git a/src/bin/postinstall/postinstall.ts b/src/bin/sync-extensions/sync-extension.ts similarity index 84% rename from src/bin/postinstall/postinstall.ts rename to src/bin/sync-extensions/sync-extension.ts index 523d3887..7c1d5ee1 100644 --- a/src/bin/postinstall/postinstall.ts +++ b/src/bin/sync-extensions/sync-extension.ts @@ -1,6 +1,6 @@ import type { BuildContext } from "../shared/buildContext"; -import { getUiModuleMetas, computeHash } from "./uiModuleMeta"; -import { installUiModulesPeerDependencies } from "./installUiModulesPeerDependencies"; +import { getExtensionModuleMetas, computeHash } from "./extensionModuleMeta"; +import { installExtensionModulesPeerDependencies } from "./installExtensionModulesPeerDependencies"; import { readManagedGitignoreFile, writeManagedGitignoreFile @@ -15,11 +15,11 @@ import { untrackFromGit } from "../tools/untrackFromGit"; export async function command(params: { buildContext: BuildContext }) { const { buildContext } = params; - const uiModuleMetas = await getUiModuleMetas({ buildContext }); + const extensionModuleMetas = await getExtensionModuleMetas({ buildContext }); - await installUiModulesPeerDependencies({ + await installExtensionModulesPeerDependencies({ buildContext, - uiModuleMetas + extensionModuleMetas }); const { ownedFilesRelativePaths } = await readManagedGitignoreFile({ @@ -29,14 +29,14 @@ export async function command(params: { buildContext: BuildContext }) { await writeManagedGitignoreFile({ buildContext, ownedFilesRelativePaths, - uiModuleMetas + extensionModuleMetas }); await Promise.all( - uiModuleMetas - .map(uiModuleMeta => + extensionModuleMetas + .map(extensionModuleMeta => Promise.all( - uiModuleMeta.files.map( + extensionModuleMeta.files.map( async ({ fileRelativePath, copyableFilePath, hash }) => { if (ownedFilesRelativePaths.includes(fileRelativePath)) { return; diff --git a/src/bin/tools/listInstalledModules.ts b/src/bin/tools/listInstalledModules.ts index 2a9d801b..d173c73c 100644 --- a/src/bin/tools/listInstalledModules.ts +++ b/src/bin/tools/listInstalledModules.ts @@ -24,7 +24,7 @@ export async function listInstalledModules(params: { packageJsonFilePath }); - const uiModuleNames = ( + const extensionModuleNames = ( [parsedPackageJson.dependencies, parsedPackageJson.devDependencies] as const ) .filter(exclude(undefined)) @@ -33,7 +33,7 @@ export async function listInstalledModules(params: { .filter(moduleName => filter({ moduleName })); const result = await Promise.all( - uiModuleNames.map(async moduleName => { + extensionModuleNames.map(async moduleName => { const dirPath = await getInstalledModuleDirPath({ moduleName, packageJsonDirPath: pathDirname(packageJsonFilePath),