Factorize getBuildOptions

This commit is contained in:
Joseph Garrone 2024-05-16 08:23:37 +02:00
parent 8cf0f96401
commit 14fe55e5c4
5 changed files with 86 additions and 110 deletions

View File

@ -1,10 +1,13 @@
import { parse as urlParse } from "url"; import { parse as urlParse } from "url";
import { readParsedPackageJson } from "./parsedPackageJson";
import { join as pathJoin } from "path"; import { join as pathJoin } from "path";
import { getAbsoluteAndInOsFormatPath } from "../../tools/getAbsoluteAndInOsFormatPath"; import { getAbsoluteAndInOsFormatPath } from "../tools/getAbsoluteAndInOsFormatPath";
import { getResolvedViteConfig } from "./resolvedViteConfig"; import { getNpmWorkspaceRootDirPath } from "../tools/getNpmWorkspaceRootDirPath";
import { getNpmWorkspaceRootDirPath } from "../../tools/getNpmWorkspaceRootDirPath"; import type { CliCommandOptions } from "../main";
import type { CliCommandOptions } from "../../main"; import { z } from "zod";
import * as fs from "fs";
import { assert } from "tsafe";
import * as child_process from "child_process";
import { vitePluginSubScriptEnvNames } from "./constants";
/** Consolidated build option gathered form CLI arguments and config in package.json */ /** Consolidated build option gathered form CLI arguments and config in package.json */
export type BuildOptions = { export type BuildOptions = {
@ -30,6 +33,23 @@ export type BuildOptions = {
npmWorkspaceRootDirPath: string; npmWorkspaceRootDirPath: string;
}; };
export type UserProvidedBuildOptions = {
extraThemeProperties?: string[];
artifactId?: string;
groupId?: string;
loginThemeResourcesFromKeycloakVersion?: string;
keycloakifyBuildDirPath?: string;
themeName?: string | string[];
};
export type ResolvedViteConfig = {
buildDir: string;
publicDir: string;
assetsDir: string;
urlPathname: string | undefined;
userProvidedBuildOptions: UserProvidedBuildOptions;
};
export function readBuildOptions(params: { cliCommandOptions: CliCommandOptions }): BuildOptions { export function readBuildOptions(params: { cliCommandOptions: CliCommandOptions }): BuildOptions {
const { cliCommandOptions } = params; const { cliCommandOptions } = params;
@ -44,14 +64,67 @@ export function readBuildOptions(params: { cliCommandOptions: CliCommandOptions
}); });
})(); })();
const { resolvedViteConfig } = getResolvedViteConfig({ const { resolvedViteConfig } = (() => {
reactAppRootDirPath if (fs.readdirSync(reactAppRootDirPath).find(fileBasename => fileBasename.startsWith("vite.config")) === undefined) {
return { "resolvedViteConfig": undefined };
}
const output = child_process
.execSync("npx vite", {
"cwd": reactAppRootDirPath,
"env": {
...process.env,
[vitePluginSubScriptEnvNames.resolveViteConfig]: "true"
}
})
.toString("utf8");
assert(output.includes(vitePluginSubScriptEnvNames.resolveViteConfig), "Seems like the Keycloakify's Vite plugin is not installed.");
const resolvedViteConfigStr = output.split(vitePluginSubScriptEnvNames.resolveViteConfig).reverse()[0];
const resolvedViteConfig: ResolvedViteConfig = JSON.parse(resolvedViteConfigStr);
return { resolvedViteConfig };
})();
const parsedPackageJson = (() => {
type ParsedPackageJson = {
name: string;
version?: string;
homepage?: string;
keycloakify?: UserProvidedBuildOptions & { reactAppBuildDirPath?: string };
};
const zParsedPackageJson = z.object({
"name": z.string(),
"version": z.string().optional(),
"homepage": z.string().optional(),
"keycloakify": z
.object({
"extraThemeProperties": z.array(z.string()).optional(),
"artifactId": z.string().optional(),
"groupId": z.string().optional(),
"loginThemeResourcesFromKeycloakVersion": z.string().optional(),
"reactAppBuildDirPath": z.string().optional(),
"keycloakifyBuildDirPath": z.string().optional(),
"themeName": z.union([z.string(), z.array(z.string())]).optional()
})
.optional()
}); });
const { keycloakify: userProvidedBuildOptionsFromPackageJson, ...parsedPackageJson } = readParsedPackageJson({ reactAppRootDirPath }); {
type Got = ReturnType<(typeof zParsedPackageJson)["parse"]>;
type Expected = ParsedPackageJson;
assert<Got extends Expected ? true : false>();
assert<Expected extends Got ? true : false>();
}
const userProvidedBuildOptions = { return zParsedPackageJson.parse(JSON.parse(fs.readFileSync(pathJoin(reactAppRootDirPath, "package.json")).toString("utf8")));
...userProvidedBuildOptionsFromPackageJson, })();
const userProvidedBuildOptions: UserProvidedBuildOptions = {
...parsedPackageJson.keycloakify,
...resolvedViteConfig?.userProvidedBuildOptions ...resolvedViteConfig?.userProvidedBuildOptions
}; };
@ -78,9 +151,9 @@ export function readBuildOptions(params: { cliCommandOptions: CliCommandOptions
break webpack; break webpack;
} }
if (userProvidedBuildOptions.reactAppBuildDirPath !== undefined) { if (parsedPackageJson.keycloakify?.reactAppBuildDirPath !== undefined) {
return getAbsoluteAndInOsFormatPath({ return getAbsoluteAndInOsFormatPath({
"pathIsh": userProvidedBuildOptions.reactAppBuildDirPath, "pathIsh": parsedPackageJson.keycloakify.reactAppBuildDirPath,
"cwd": reactAppRootDirPath "cwd": reactAppRootDirPath
}); });
} }

View File

@ -1,21 +0,0 @@
import { z } from "zod";
export type UserProvidedBuildOptions = {
extraThemeProperties?: string[];
artifactId?: string;
groupId?: string;
loginThemeResourcesFromKeycloakVersion?: string;
reactAppBuildDirPath?: string;
keycloakifyBuildDirPath?: string;
themeName?: string | string[];
};
export const zUserProvidedBuildOptions = z.object({
"extraThemeProperties": z.array(z.string()).optional(),
"artifactId": z.string().optional(),
"groupId": z.string().optional(),
"loginThemeResourcesFromKeycloakVersion": z.string().optional(),
"reactAppBuildDirPath": z.string().optional(),
"keycloakifyBuildDirPath": z.string().optional(),
"themeName": z.union([z.string(), z.array(z.string())]).optional()
});

View File

@ -1,3 +0,0 @@
export * from "./buildOptions";
export type { UserProvidedBuildOptions } from "./UserProvidedBuildOptions";
export type { ResolvedViteConfig } from "./resolvedViteConfig";

View File

@ -1,32 +0,0 @@
import * as fs from "fs";
import { assert } from "tsafe";
import type { Equals } from "tsafe";
import { z } from "zod";
import { join as pathJoin } from "path";
import { type UserProvidedBuildOptions, zUserProvidedBuildOptions } from "./UserProvidedBuildOptions";
export type ParsedPackageJson = {
name: string;
version?: string;
homepage?: string;
keycloakify?: UserProvidedBuildOptions;
};
const zParsedPackageJson = z.object({
"name": z.string(),
"version": z.string().optional(),
"homepage": z.string().optional(),
"keycloakify": zUserProvidedBuildOptions.optional()
});
assert<Equals<ReturnType<(typeof zParsedPackageJson)["parse"]>, ParsedPackageJson>>();
let parsedPackageJson: undefined | ParsedPackageJson;
export function readParsedPackageJson(params: { reactAppRootDirPath: string }) {
const { reactAppRootDirPath } = params;
if (parsedPackageJson) {
return parsedPackageJson;
}
parsedPackageJson = zParsedPackageJson.parse(JSON.parse(fs.readFileSync(pathJoin(reactAppRootDirPath, "package.json")).toString("utf8")));
return parsedPackageJson;
}

View File

@ -1,41 +0,0 @@
import * as fs from "fs";
import { UserProvidedBuildOptions } from "./UserProvidedBuildOptions";
import * as child_process from "child_process";
import { vitePluginSubScriptEnvNames } from "../constants";
import { assert } from "tsafe/assert";
export type ResolvedViteConfig = {
buildDir: string;
publicDir: string;
assetsDir: string;
urlPathname: string | undefined;
userProvidedBuildOptions: UserProvidedBuildOptions;
};
export function getResolvedViteConfig(params: { reactAppRootDirPath: string }): {
resolvedViteConfig: ResolvedViteConfig | undefined;
} {
const { reactAppRootDirPath } = params;
if (fs.readdirSync(reactAppRootDirPath).find(fileBasename => fileBasename.startsWith("vite.config")) === undefined) {
return { "resolvedViteConfig": undefined };
}
const output = child_process
.execSync("npx vite", {
"cwd": reactAppRootDirPath,
"env": {
...process.env,
[vitePluginSubScriptEnvNames.resolveViteConfig]: "true"
}
})
.toString("utf8");
assert(output.includes(vitePluginSubScriptEnvNames.resolveViteConfig), "Seems like the Keycloakify's Vite plugin is not installed.");
const resolvedViteConfigStr = output.split(vitePluginSubScriptEnvNames.resolveViteConfig).reverse()[0];
const resolvedViteConfig: ResolvedViteConfig = JSON.parse(resolvedViteConfigStr);
return { resolvedViteConfig };
}