diff --git a/scripts/generate-json-schema.ts b/scripts/generate-json-schema.ts deleted file mode 100644 index 81c2899d..00000000 --- a/scripts/generate-json-schema.ts +++ /dev/null @@ -1,14 +0,0 @@ -import fs from "fs"; -import path from "path"; -import zodToJsonSchema from "zod-to-json-schema"; -import { zParsedPackageJson } from "../src/bin/keycloakify/parsedPackageJson"; - -const jsonSchemaName = "keycloakifyPackageJsonSchema"; -const jsonSchema = zodToJsonSchema(zParsedPackageJson, jsonSchemaName); - -const baseProperties = { - // merges package.json schema with keycloakify properties - "allOf": [{ "$ref": "https://json.schemastore.org/package.json" }, { "$ref": jsonSchemaName }] -}; - -fs.writeFileSync(path.join(process.cwd(), "keycloakify-json-schema.json"), JSON.stringify({ ...baseProperties, ...jsonSchema }, null, 2)); diff --git a/src/bin/constants.ts b/src/bin/constants.ts index 279e773a..4a8b4023 100644 --- a/src/bin/constants.ts +++ b/src/bin/constants.ts @@ -2,7 +2,7 @@ export const nameOfTheGlobal = "kcContext"; export const keycloak_resources = "keycloak-resources"; export const resources_common = "resources-common"; export const lastKeycloakVersionWithAccountV1 = "21.1.2"; -export const resolvedViteConfigJsonBasename = ".keycloakifyViteConfig.json"; +export const resolvedViteConfigJsonBasename = "vite.json"; export const basenameOfTheKeycloakifyResourcesDir = "build"; export const themeTypes = ["login", "account"] as const; diff --git a/src/bin/eject-keycloak-page.ts b/src/bin/eject-keycloak-page.ts index 71d70483..19332bd1 100644 --- a/src/bin/eject-keycloak-page.ts +++ b/src/bin/eject-keycloak-page.ts @@ -11,11 +11,14 @@ import { kebabCaseToCamelCase } from "./tools/kebabCaseToSnakeCase"; import { assert, Equals } from "tsafe/assert"; import { getThemeSrcDirPath } from "./getThemeSrcDirPath"; import { themeTypes, type ThemeType } from "./constants"; +import { getReactAppRootDirPath } from "./keycloakify/buildOptions/getReactAppRootDirPath"; (async () => { console.log("Select a theme type"); - const reactAppRootDirPath = process.cwd(); + const { reactAppRootDirPath } = getReactAppRootDirPath({ + "processArgv": process.argv.slice(2) + }); const { value: themeType } = await cliSelect({ "values": [...themeTypes] diff --git a/src/bin/keycloakify/buildOptions/buildOptions.ts b/src/bin/keycloakify/buildOptions/buildOptions.ts index 6045721a..5b5f36d9 100644 --- a/src/bin/keycloakify/buildOptions/buildOptions.ts +++ b/src/bin/keycloakify/buildOptions/buildOptions.ts @@ -4,7 +4,9 @@ import { join as pathJoin } from "path"; import parseArgv from "minimist"; import { getAbsoluteAndInOsFormatPath } from "../../tools/getAbsoluteAndInOsFormatPath"; import { readResolvedViteConfig } from "./resolvedViteConfig"; -import { getKeycloakifyBuildDirPath } from "./getKeycloakifyBuildDirPath"; +import * as fs from "fs"; +import { getCacheDirPath } from "./getCacheDirPath"; +import { getReactAppRootDirPath } from "./getReactAppRootDirPath"; /** Consolidated build option gathered form CLI arguments and config in package.json */ export type BuildOptions = { @@ -33,29 +35,18 @@ export type BuildOptions = { export function readBuildOptions(params: { processArgv: string[] }): BuildOptions { const { processArgv } = params; - const argv = parseArgv(processArgv); + const { reactAppRootDirPath } = getReactAppRootDirPath({ processArgv }); - const reactAppRootDirPath = (() => { - const arg = argv["project"] ?? argv["p"]; + const { cacheDirPath } = getCacheDirPath({ reactAppRootDirPath }); - if (typeof arg !== "string") { - return process.cwd(); - } + const { resolvedViteConfig } = readResolvedViteConfig({ cacheDirPath }); - return getAbsoluteAndInOsFormatPath({ - "pathIsh": arg, - "cwd": process.cwd() - }); - })(); + if (resolvedViteConfig === undefined && fs.existsSync(pathJoin(reactAppRootDirPath, "vite.config.ts"))) { + throw new Error("Keycloakify's Vite plugin output not found"); + } const parsedPackageJson = readParsedPackageJson({ reactAppRootDirPath }); - const { resolvedViteConfig } = - readResolvedViteConfig({ - "parsedPackageJson_keycloakify_keycloakifyBuildDirPath": parsedPackageJson.keycloakify?.keycloakifyBuildDirPath, - reactAppRootDirPath - }) ?? {}; - const themeNames = (() => { if (parsedPackageJson.keycloakify?.themeName === undefined) { return [ @@ -73,12 +64,6 @@ export function readBuildOptions(params: { processArgv: string[] }): BuildOption return parsedPackageJson.keycloakify.themeName; })(); - const { keycloakifyBuildDirPath } = getKeycloakifyBuildDirPath({ - "parsedPackageJson_keycloakify_keycloakifyBuildDirPath": parsedPackageJson.keycloakify?.keycloakifyBuildDirPath, - reactAppRootDirPath, - "bundler": resolvedViteConfig !== undefined ? "vite" : "webpack" - }); - const reactAppBuildDirPath = (() => { webpack: { if (resolvedViteConfig !== undefined) { @@ -98,6 +83,8 @@ export function readBuildOptions(params: { processArgv: string[] }): BuildOption return pathJoin(reactAppRootDirPath, resolvedViteConfig.buildDir); })(); + const argv = parseArgv(processArgv); + return { "bundler": resolvedViteConfig !== undefined ? "vite" : "webpack", "isSilent": typeof argv["silent"] === "boolean" ? argv["silent"] : false, @@ -124,7 +111,16 @@ export function readBuildOptions(params: { processArgv: string[] }): BuildOption "loginThemeResourcesFromKeycloakVersion": parsedPackageJson.keycloakify?.loginThemeResourcesFromKeycloakVersion ?? "11.0.3", reactAppRootDirPath, reactAppBuildDirPath, - keycloakifyBuildDirPath, + "keycloakifyBuildDirPath": (() => { + if (parsedPackageJson.keycloakify?.keycloakifyBuildDirPath !== undefined) { + return getAbsoluteAndInOsFormatPath({ + "pathIsh": parsedPackageJson.keycloakify?.keycloakifyBuildDirPath, + "cwd": reactAppRootDirPath + }); + } + + return resolvedViteConfig?.buildDir === undefined ? "build_keycloak" : `${resolvedViteConfig.buildDir}_keycloak`; + })(), "publicDirPath": (() => { webpack: { if (resolvedViteConfig !== undefined) { @@ -143,19 +139,7 @@ export function readBuildOptions(params: { processArgv: string[] }): BuildOption return pathJoin(reactAppRootDirPath, resolvedViteConfig.publicDir); })(), - "cacheDirPath": pathJoin( - (() => { - if (process.env.XDG_CACHE_HOME !== undefined) { - return getAbsoluteAndInOsFormatPath({ - "pathIsh": process.env.XDG_CACHE_HOME, - "cwd": reactAppRootDirPath - }); - } - - return pathJoin(reactAppRootDirPath, "node_modules", ".cache"); - })(), - "keycloakify" - ), + cacheDirPath, "urlPathname": (() => { webpack: { if (resolvedViteConfig !== undefined) { diff --git a/src/bin/keycloakify/buildOptions/getCacheDirPath.ts b/src/bin/keycloakify/buildOptions/getCacheDirPath.ts new file mode 100644 index 00000000..4e553155 --- /dev/null +++ b/src/bin/keycloakify/buildOptions/getCacheDirPath.ts @@ -0,0 +1,23 @@ +import { join as pathJoin } from "path"; +import { getAbsoluteAndInOsFormatPath } from "../../tools/getAbsoluteAndInOsFormatPath"; + +export function getCacheDirPath(params: { reactAppRootDirPath: string }) { + const { reactAppRootDirPath } = params; + + const cacheDirPath = pathJoin( + (() => { + if (process.env.XDG_CACHE_HOME !== undefined) { + return getAbsoluteAndInOsFormatPath({ + "pathIsh": process.env.XDG_CACHE_HOME, + "cwd": reactAppRootDirPath + }); + } + + // TODO: Recursively look up + return pathJoin(reactAppRootDirPath, "node_modules", ".cache"); + })(), + "keycloakify" + ); + + return { cacheDirPath }; +} diff --git a/src/bin/keycloakify/buildOptions/getKeycloakifyBuildDirPath.ts b/src/bin/keycloakify/buildOptions/getKeycloakifyBuildDirPath.ts deleted file mode 100644 index 5246fadb..00000000 --- a/src/bin/keycloakify/buildOptions/getKeycloakifyBuildDirPath.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { getAbsoluteAndInOsFormatPath } from "../../tools/getAbsoluteAndInOsFormatPath"; -import { join as pathJoin } from "path"; - -export function getKeycloakifyBuildDirPath(params: { - reactAppRootDirPath: string; - parsedPackageJson_keycloakify_keycloakifyBuildDirPath: string | undefined; - bundler: "vite" | "webpack"; -}) { - const { reactAppRootDirPath, parsedPackageJson_keycloakify_keycloakifyBuildDirPath, bundler } = params; - - const keycloakifyBuildDirPath = (() => { - if (parsedPackageJson_keycloakify_keycloakifyBuildDirPath !== undefined) { - getAbsoluteAndInOsFormatPath({ - "pathIsh": parsedPackageJson_keycloakify_keycloakifyBuildDirPath, - "cwd": reactAppRootDirPath - }); - } - - return pathJoin( - reactAppRootDirPath, - `${(() => { - switch (bundler) { - case "vite": - return "dist"; - case "webpack": - return "build"; - } - })()}_keycloak` - ); - })(); - - return { keycloakifyBuildDirPath }; -} diff --git a/src/bin/keycloakify/buildOptions/getReactAppRootDirPath.ts b/src/bin/keycloakify/buildOptions/getReactAppRootDirPath.ts new file mode 100644 index 00000000..49b9e9d3 --- /dev/null +++ b/src/bin/keycloakify/buildOptions/getReactAppRootDirPath.ts @@ -0,0 +1,23 @@ +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 }; +} diff --git a/src/bin/keycloakify/buildOptions/resolvedViteConfig.ts b/src/bin/keycloakify/buildOptions/resolvedViteConfig.ts index 6646b795..4d4fd3fe 100644 --- a/src/bin/keycloakify/buildOptions/resolvedViteConfig.ts +++ b/src/bin/keycloakify/buildOptions/resolvedViteConfig.ts @@ -5,7 +5,6 @@ import { z } from "zod"; import { join as pathJoin } from "path"; import { resolvedViteConfigJsonBasename } from "../../constants"; import type { OptionalIfCanBeUndefined } from "../../tools/OptionalIfCanBeUndefined"; -import { getKeycloakifyBuildDirPath } from "./getKeycloakifyBuildDirPath"; export type ResolvedViteConfig = { buildDir: string; @@ -28,31 +27,18 @@ const zResolvedViteConfig = z.object({ assert>(); } -export function readResolvedViteConfig(params: { - reactAppRootDirPath: string; - parsedPackageJson_keycloakify_keycloakifyBuildDirPath: string | undefined; -}): - | { - resolvedViteConfig: ResolvedViteConfig; - } - | undefined { - const { reactAppRootDirPath, parsedPackageJson_keycloakify_keycloakifyBuildDirPath } = params; +export function readResolvedViteConfig(params: { cacheDirPath: string }): { + resolvedViteConfig: ResolvedViteConfig | undefined; +} { + const { cacheDirPath } = params; - const viteConfigTsFilePath = pathJoin(reactAppRootDirPath, "vite.config.ts"); + const resolvedViteConfigJsonFilePath = pathJoin(cacheDirPath, resolvedViteConfigJsonBasename); - if (!fs.existsSync(viteConfigTsFilePath)) { - return undefined; + if (!fs.existsSync(resolvedViteConfigJsonFilePath)) { + return { "resolvedViteConfig": undefined }; } - const { keycloakifyBuildDirPath } = getKeycloakifyBuildDirPath({ - reactAppRootDirPath, - parsedPackageJson_keycloakify_keycloakifyBuildDirPath, - "bundler": "vite" - }); - const resolvedViteConfig = (() => { - const resolvedViteConfigJsonFilePath = pathJoin(keycloakifyBuildDirPath, resolvedViteConfigJsonBasename); - if (!fs.existsSync(resolvedViteConfigJsonFilePath)) { throw new Error("Missing Keycloakify Vite plugin output."); } diff --git a/src/vite-plugin/vite-plugin.ts b/src/vite-plugin/vite-plugin.ts index 6bec4d71..b2655202 100644 --- a/src/vite-plugin/vite-plugin.ts +++ b/src/vite-plugin/vite-plugin.ts @@ -1,11 +1,10 @@ import { join as pathJoin, relative as pathRelative, sep as pathSep } from "path"; -import { readParsedPackageJson } from "../bin/keycloakify/buildOptions/parsedPackageJson"; import type { Plugin } from "vite"; import { assert } from "tsafe/assert"; import * as fs from "fs"; import { resolvedViteConfigJsonBasename, nameOfTheGlobal, basenameOfTheKeycloakifyResourcesDir, keycloak_resources } from "../bin/constants"; import type { ResolvedViteConfig } from "../bin/keycloakify/buildOptions/resolvedViteConfig"; -import { getKeycloakifyBuildDirPath } from "../bin/keycloakify/buildOptions/getKeycloakifyBuildDirPath"; +import { getCacheDirPath } from "../bin/keycloakify/buildOptions/getCacheDirPath"; import { replaceAll } from "../bin/tools/String.prototype.replaceAll"; import { id } from "tsafe/id"; import { rm } from "../bin/tools/fs.rm"; @@ -40,19 +39,16 @@ export function keycloakify(): Plugin { buildDirPath = pathJoin(reactAppRootDirPath, resolvedConfig.build.outDir); - const { keycloakifyBuildDirPath } = getKeycloakifyBuildDirPath({ - "parsedPackageJson_keycloakify_keycloakifyBuildDirPath": readParsedPackageJson({ reactAppRootDirPath }).keycloakify - ?.keycloakifyBuildDirPath, - reactAppRootDirPath, - "bundler": "vite" + const { cacheDirPath } = getCacheDirPath({ + reactAppRootDirPath }); - if (!fs.existsSync(keycloakifyBuildDirPath)) { - fs.mkdirSync(keycloakifyBuildDirPath); + if (!fs.existsSync(cacheDirPath)) { + fs.mkdirSync(cacheDirPath); } fs.writeFileSync( - pathJoin(keycloakifyBuildDirPath, resolvedViteConfigJsonBasename), + pathJoin(cacheDirPath, resolvedViteConfigJsonBasename), Buffer.from( JSON.stringify( id({