Compare commits

...

22 Commits

Author SHA1 Message Date
d8b00da3a1 Update tss-react 2022-09-08 15:27:41 +02:00
a24945bc1b Bump version 2022-09-08 15:18:21 +02:00
158759493f Merge pull request #170 from Tasyp/feature/silent
feat: add silent flag
2022-09-08 15:17:45 +02:00
36e32d6ddc Update src/bin/download-builtin-keycloak-theme.ts 2022-09-08 15:13:21 +02:00
84908e2ec0 Update src/bin/generate-i18n-messages.ts 2022-09-08 15:13:15 +02:00
a2dc51d811 Update src/bin/create-keycloak-email-directory.ts 2022-09-08 15:13:09 +02:00
fb3b0e2c29 fix: make sure external assets flag is a boolean 2022-09-08 15:46:27 +03:00
1a3e4c68bb test: update tests to include silent flag 2022-09-08 15:43:03 +03:00
11b2342da0 feat: add silent flag 2022-09-08 13:52:10 +03:00
80d4a808d3 Update readme 2022-09-07 13:45:34 +02:00
da4146eb59 Bump version (changelog ignore) 2022-09-07 13:40:18 +02:00
a0be35db8b Fix compat with StrictMode react 18 2022-09-07 13:39:54 +02:00
14db9cd523 Merge branch 'main' of https://github.com/InseeFrLab/keycloakify 2022-09-07 12:02:35 +02:00
0c315385dd Update fix tests 2022-09-07 12:00:23 +02:00
c0a0eb02fb Remove Open collectivity 2022-09-07 11:59:42 +02:00
ee407c32ad Create FUNDING.yaml 2022-09-07 11:53:18 +02:00
9262d21829 Bump version 2022-09-07 11:50:41 +02:00
a13f710325 Important fix for --external-assets 2022-09-07 11:50:24 +02:00
eac1a6036f Merge branch 'main' of https://github.com/InseeFrLab/keycloakify 2022-09-07 11:26:18 +02:00
987f3d7586 Bump version (changelog ignore) 2022-09-07 11:26:10 +02:00
875322669c Rename isAppAndKeycloakServerSharingSameDomain to areAppAndKeycloakServerSharingSameDomain #145 2022-09-07 11:25:46 +02:00
33a264b3d0 Update README.md 2022-09-07 00:32:38 +02:00
19 changed files with 153 additions and 61 deletions

4
.github/FUNDING.yaml vendored Normal file
View File

@ -0,0 +1,4 @@
# These are supported funding model platforms
github: [garronej]
custom: ['https://www.ringerhq.com/experts/garronej']

View File

@ -27,7 +27,14 @@
<a href="https://www.keycloakify.dev">Home</a> <a href="https://www.keycloakify.dev">Home</a>
- -
<a href="https://docs.keycloakify.dev">Documentation</a> <a href="https://docs.keycloakify.dev">Documentation</a>
</p> </p>
<p align="center"> ---- Project starter / Demo setup ---- </p>
<p align="center">
<a href="https://github.com/garronej/keycloakify-starter">CSS Level customization</a>
-
<a href="https://github.com/garronej/keycloakify-advanced-starter">Component Level customization</a>
</p>
<p align="center"> ---- </p>
</p> </p>
@ -37,7 +44,7 @@
</p> </p>
> 🗣 V6 have been released 🎉 > 🗣 V6 have been released 🎉
> [It features major improvements](/#600). > [It features major improvements](https://github.com/InseeFrLab/keycloakify#600).
> Checkout [the migration guide](https://docs.keycloakify.dev/v5-to-v6). > Checkout [the migration guide](https://docs.keycloakify.dev/v5-to-v6).
# Changelog highlights # Changelog highlights

View File

@ -1,6 +1,6 @@
{ {
"name": "keycloakify", "name": "keycloakify",
"version": "6.0.0", "version": "6.1.0",
"description": "Keycloak theme generator for Reacts app", "description": "Keycloak theme generator for Reacts app",
"repository": { "repository": {
"type": "git", "type": "git",
@ -60,6 +60,7 @@
"devDependencies": { "devDependencies": {
"@emotion/react": "^11.4.1", "@emotion/react": "^11.4.1",
"@types/memoizee": "^0.4.7", "@types/memoizee": "^0.4.7",
"@types/minimist": "^1.2.2",
"@types/node": "^17.0.25", "@types/node": "^17.0.25",
"@types/react": "18.0.9", "@types/react": "18.0.9",
"copyfiles": "^2.4.1", "copyfiles": "^2.4.1",
@ -78,12 +79,13 @@
"evt": "^2.4.0", "evt": "^2.4.0",
"memoizee": "^0.4.15", "memoizee": "^0.4.15",
"minimal-polyfills": "^2.2.2", "minimal-polyfills": "^2.2.2",
"minimist": "^1.2.6",
"path-browserify": "^1.0.1", "path-browserify": "^1.0.1",
"powerhooks": "^0.20.15", "powerhooks": "^0.20.15",
"react-markdown": "^5.0.3", "react-markdown": "^5.0.3",
"scripting-tools": "^0.19.13", "scripting-tools": "^0.19.13",
"tsafe": "^1.0.1", "tsafe": "^1.0.1",
"tss-react": "^4.1.1", "tss-react": "^4.1.3",
"zod": "^3.17.10" "zod": "^3.17.10"
} }
} }

View File

@ -6,11 +6,15 @@ import { join as pathJoin, basename as pathBasename } from "path";
import { transformCodebase } from "./tools/transformCodebase"; import { transformCodebase } from "./tools/transformCodebase";
import { promptKeycloakVersion } from "./promptKeycloakVersion"; import { promptKeycloakVersion } from "./promptKeycloakVersion";
import * as fs from "fs"; import * as fs from "fs";
import { getCliOptions } from "./tools/cliOptions";
import { getLogger } from "./tools/logger";
if (require.main === module) { if (require.main === module) {
(async () => { (async () => {
const { isSilent } = getCliOptions(process.argv.slice(2));
const logger = getLogger({ isSilent });
if (fs.existsSync(keycloakThemeEmailDirPath)) { if (fs.existsSync(keycloakThemeEmailDirPath)) {
console.log(`There is already a ./${pathBasename(keycloakThemeEmailDirPath)} directory in your project. Aborting.`); logger.warn(`There is already a ./${pathBasename(keycloakThemeEmailDirPath)} directory in your project. Aborting.`);
process.exit(-1); process.exit(-1);
} }
@ -21,7 +25,8 @@ if (require.main === module) {
downloadBuiltinKeycloakTheme({ downloadBuiltinKeycloakTheme({
keycloakVersion, keycloakVersion,
"destDirPath": builtinKeycloakThemeTmpDirPath "destDirPath": builtinKeycloakThemeTmpDirPath,
isSilent
}); });
transformCodebase({ transformCodebase({
@ -29,7 +34,7 @@ if (require.main === module) {
"destDirPath": keycloakThemeEmailDirPath "destDirPath": keycloakThemeEmailDirPath
}); });
console.log(`./${pathBasename(keycloakThemeEmailDirPath)} ready to be customized`); logger.log(`./${pathBasename(keycloakThemeEmailDirPath)} ready to be customized`);
fs.rmSync(builtinKeycloakThemeTmpDirPath, { "recursive": true, "force": true }); fs.rmSync(builtinKeycloakThemeTmpDirPath, { "recursive": true, "force": true });
})(); })();

View File

@ -4,31 +4,37 @@ import { keycloakThemeBuildingDirPath } from "./keycloakify";
import { join as pathJoin } from "path"; import { join as pathJoin } from "path";
import { downloadAndUnzip } from "./tools/downloadAndUnzip"; import { downloadAndUnzip } from "./tools/downloadAndUnzip";
import { promptKeycloakVersion } from "./promptKeycloakVersion"; import { promptKeycloakVersion } from "./promptKeycloakVersion";
import { getCliOptions } from "./tools/cliOptions";
import { getLogger } from "./tools/logger";
export function downloadBuiltinKeycloakTheme(params: { keycloakVersion: string; destDirPath: string }) { export function downloadBuiltinKeycloakTheme(params: { keycloakVersion: string; destDirPath: string; isSilent: boolean }) {
const { keycloakVersion, destDirPath } = params; const { keycloakVersion, destDirPath, isSilent } = params;
for (const ext of ["", "-community"]) { for (const ext of ["", "-community"]) {
downloadAndUnzip({ downloadAndUnzip({
"destDirPath": destDirPath, "destDirPath": destDirPath,
"url": `https://github.com/keycloak/keycloak/archive/refs/tags/${keycloakVersion}.zip`, "url": `https://github.com/keycloak/keycloak/archive/refs/tags/${keycloakVersion}.zip`,
"pathOfDirToExtractInArchive": `keycloak-${keycloakVersion}/themes/src/main/resources${ext}/theme`, "pathOfDirToExtractInArchive": `keycloak-${keycloakVersion}/themes/src/main/resources${ext}/theme`,
"cacheDirPath": pathJoin(keycloakThemeBuildingDirPath, ".cache") "cacheDirPath": pathJoin(keycloakThemeBuildingDirPath, ".cache"),
isSilent
}); });
} }
} }
if (require.main === module) { if (require.main === module) {
(async () => { (async () => {
const { isSilent } = getCliOptions(process.argv.slice(2));
const logger = getLogger({ isSilent });
const { keycloakVersion } = await promptKeycloakVersion(); const { keycloakVersion } = await promptKeycloakVersion();
const destDirPath = pathJoin(keycloakThemeBuildingDirPath, "src", "main", "resources", "theme"); const destDirPath = pathJoin(keycloakThemeBuildingDirPath, "src", "main", "resources", "theme");
console.log(`Downloading builtins theme of Keycloak ${keycloakVersion} here ${destDirPath}`); logger.log(`Downloading builtins theme of Keycloak ${keycloakVersion} here ${destDirPath}`);
downloadBuiltinKeycloakTheme({ downloadBuiltinKeycloakTheme({
keycloakVersion, keycloakVersion,
destDirPath destDirPath,
isSilent
}); });
})(); })();
} }

View File

@ -5,6 +5,8 @@ import { crawl } from "./tools/crawl";
import { downloadBuiltinKeycloakTheme } from "./download-builtin-keycloak-theme"; import { downloadBuiltinKeycloakTheme } from "./download-builtin-keycloak-theme";
import { getProjectRoot } from "./tools/getProjectRoot"; import { getProjectRoot } from "./tools/getProjectRoot";
import { rm_rf, rm_r } from "./tools/rm"; import { rm_rf, rm_r } from "./tools/rm";
import { getCliOptions } from "./tools/cliOptions";
import { getLogger } from "./tools/logger";
//NOTE: To run without argument when we want to generate src/i18n/generated_kcMessages files, //NOTE: To run without argument when we want to generate src/i18n/generated_kcMessages files,
// update the version array for generating for newer version. // update the version array for generating for newer version.
@ -12,8 +14,11 @@ import { rm_rf, rm_r } from "./tools/rm";
//@ts-ignore //@ts-ignore
const propertiesParser = require("properties-parser"); const propertiesParser = require("properties-parser");
const { isSilent } = getCliOptions(process.argv.slice(2));
const logger = getLogger({ isSilent });
for (const keycloakVersion of ["11.0.3", "15.0.2", "18.0.1"]) { for (const keycloakVersion of ["11.0.3", "15.0.2", "18.0.1"]) {
console.log({ keycloakVersion }); logger.log(JSON.stringify({ keycloakVersion }));
const tmpDirPath = pathJoin(getProjectRoot(), "tmp_xImOef9dOd44"); const tmpDirPath = pathJoin(getProjectRoot(), "tmp_xImOef9dOd44");
@ -21,7 +26,8 @@ for (const keycloakVersion of ["11.0.3", "15.0.2", "18.0.1"]) {
downloadBuiltinKeycloakTheme({ downloadBuiltinKeycloakTheme({
keycloakVersion, keycloakVersion,
"destDirPath": tmpDirPath "destDirPath": tmpDirPath,
isSilent
}); });
type Dictionary = { [idiomId: string]: string }; type Dictionary = { [idiomId: string]: string };
@ -75,7 +81,7 @@ for (const keycloakVersion of ["11.0.3", "15.0.2", "18.0.1"]) {
) )
); );
console.log(`${filePath} wrote`); logger.log(`${filePath} wrote`);
}); });
}); });
} }

View File

@ -11,7 +11,7 @@ type ParsedPackageJson = {
keycloakify?: { keycloakify?: {
extraPages?: string[]; extraPages?: string[];
extraThemeProperties?: string[]; extraThemeProperties?: string[];
isAppAndKeycloakServerSharingSameDomain?: boolean; areAppAndKeycloakServerSharingSameDomain?: boolean;
}; };
}; };
@ -23,7 +23,7 @@ const zParsedPackageJson = z.object({
.object({ .object({
"extraPages": z.array(z.string()).optional(), "extraPages": z.array(z.string()).optional(),
"extraThemeProperties": z.array(z.string()).optional(), "extraThemeProperties": z.array(z.string()).optional(),
"isAppAndKeycloakServerSharingSameDomain": z.boolean().optional() "areAppAndKeycloakServerSharingSameDomain": z.boolean().optional()
}) })
.optional() .optional()
}); });
@ -35,6 +35,7 @@ export type BuildOptions = BuildOptions.Standalone | BuildOptions.ExternalAssets
export namespace BuildOptions { export namespace BuildOptions {
export type Common = { export type Common = {
isSilent: boolean;
version: string; version: string;
themeName: string; themeName: string;
extraPages?: string[]; extraPages?: string[];
@ -56,11 +57,11 @@ export namespace BuildOptions {
}; };
export type SameDomain = CommonExternalAssets & { export type SameDomain = CommonExternalAssets & {
isAppAndKeycloakServerSharingSameDomain: true; areAppAndKeycloakServerSharingSameDomain: true;
}; };
export type DifferentDomains = CommonExternalAssets & { export type DifferentDomains = CommonExternalAssets & {
isAppAndKeycloakServerSharingSameDomain: false; areAppAndKeycloakServerSharingSameDomain: false;
urlOrigin: string; urlOrigin: string;
urlPathname: string | undefined; urlPathname: string | undefined;
}; };
@ -71,8 +72,9 @@ export function readBuildOptions(params: {
packageJson: string; packageJson: string;
CNAME: string | undefined; CNAME: string | undefined;
isExternalAssetsCliParamProvided: boolean; isExternalAssetsCliParamProvided: boolean;
isSilent: boolean;
}): BuildOptions { }): BuildOptions {
const { packageJson, CNAME, isExternalAssetsCliParamProvided } = params; const { packageJson, CNAME, isExternalAssetsCliParamProvided, isSilent } = params;
const parsedPackageJson = zParsedPackageJson.parse(JSON.parse(packageJson)); const parsedPackageJson = zParsedPackageJson.parse(JSON.parse(packageJson));
@ -130,7 +132,8 @@ export function readBuildOptions(params: {
})(), })(),
"version": version, "version": version,
extraPages, extraPages,
extraThemeProperties extraThemeProperties,
isSilent
}; };
})(); })();
@ -140,10 +143,10 @@ export function readBuildOptions(params: {
"isStandalone": false "isStandalone": false
}); });
if (parsedPackageJson.keycloakify?.isAppAndKeycloakServerSharingSameDomain) { if (parsedPackageJson.keycloakify?.areAppAndKeycloakServerSharingSameDomain) {
return id<BuildOptions.ExternalAssets.SameDomain>({ return id<BuildOptions.ExternalAssets.SameDomain>({
...commonExternalAssets, ...commonExternalAssets,
"isAppAndKeycloakServerSharingSameDomain": true "areAppAndKeycloakServerSharingSameDomain": true
}); });
} else { } else {
assert( assert(
@ -155,14 +158,14 @@ export function readBuildOptions(params: {
"public/CNAME file.", "public/CNAME file.",
"Alternatively, if your app and the Keycloak server are on the same domain, ", "Alternatively, if your app and the Keycloak server are on the same domain, ",
"eg https://example.com is your app and https://example.com/auth is the keycloak", "eg https://example.com is your app and https://example.com/auth is the keycloak",
'admin UI, you can set "keycloakify": { "isAppAndKeycloakServerSharingSameDomain": true }', 'admin UI, you can set "keycloakify": { "areAppAndKeycloakServerSharingSameDomain": true }',
"in your package.json" "in your package.json"
].join(" ") ].join(" ")
); );
return id<BuildOptions.ExternalAssets.DifferentDomains>({ return id<BuildOptions.ExternalAssets.DifferentDomains>({
...commonExternalAssets, ...commonExternalAssets,
"isAppAndKeycloakServerSharingSameDomain": false, "areAppAndKeycloakServerSharingSameDomain": false,
"urlOrigin": url.origin, "urlOrigin": url.origin,
"urlPathname": url.pathname "urlPathname": url.pathname
}); });

View File

@ -46,11 +46,11 @@ export namespace BuildOptionsLike {
}; };
export type SameDomain = CommonExternalAssets & { export type SameDomain = CommonExternalAssets & {
isAppAndKeycloakServerSharingSameDomain: true; areAppAndKeycloakServerSharingSameDomain: true;
}; };
export type DifferentDomains = CommonExternalAssets & { export type DifferentDomains = CommonExternalAssets & {
isAppAndKeycloakServerSharingSameDomain: false; areAppAndKeycloakServerSharingSameDomain: false;
urlOrigin: string; urlOrigin: string;
urlPathname: string | undefined; urlPathname: string | undefined;
}; };
@ -76,7 +76,7 @@ export function generateFtlFilesCodeFactory(params: {
const $ = cheerio.load(indexHtmlCode); const $ = cheerio.load(indexHtmlCode);
fix_imports_statements: { fix_imports_statements: {
if (!buildOptions.isStandalone && buildOptions.isAppAndKeycloakServerSharingSameDomain) { if (!buildOptions.isStandalone && buildOptions.areAppAndKeycloakServerSharingSameDomain) {
break fix_imports_statements; break fix_imports_statements;
} }

View File

@ -11,6 +11,7 @@ import { isInside } from "../tools/isInside";
import type { BuildOptions } from "./BuildOptions"; import type { BuildOptions } from "./BuildOptions";
import { assert } from "tsafe/assert"; import { assert } from "tsafe/assert";
import { Reflect } from "tsafe/Reflect"; import { Reflect } from "tsafe/Reflect";
import { getLogger } from "../tools/logger";
export type BuildOptionsLike = BuildOptionsLike.Standalone | BuildOptionsLike.ExternalAssets; export type BuildOptionsLike = BuildOptionsLike.Standalone | BuildOptionsLike.ExternalAssets;
@ -19,6 +20,7 @@ export namespace BuildOptionsLike {
themeName: string; themeName: string;
extraPages?: string[]; extraPages?: string[];
extraThemeProperties?: string[]; extraThemeProperties?: string[];
isSilent: boolean;
}; };
export type Standalone = Common & { export type Standalone = Common & {
@ -34,11 +36,11 @@ export namespace BuildOptionsLike {
}; };
export type SameDomain = CommonExternalAssets & { export type SameDomain = CommonExternalAssets & {
isAppAndKeycloakServerSharingSameDomain: true; areAppAndKeycloakServerSharingSameDomain: true;
}; };
export type DifferentDomains = CommonExternalAssets & { export type DifferentDomains = CommonExternalAssets & {
isAppAndKeycloakServerSharingSameDomain: false; areAppAndKeycloakServerSharingSameDomain: false;
urlOrigin: string; urlOrigin: string;
urlPathname: string | undefined; urlPathname: string | undefined;
}; };
@ -60,6 +62,7 @@ export function generateKeycloakThemeResources(params: {
}): { doBundlesEmailTemplate: boolean } { }): { doBundlesEmailTemplate: boolean } {
const { reactAppBuildDirPath, keycloakThemeBuildingDirPath, keycloakThemeEmailDirPath, keycloakVersion, buildOptions } = params; const { reactAppBuildDirPath, keycloakThemeBuildingDirPath, keycloakThemeEmailDirPath, keycloakVersion, buildOptions } = params;
const logger = getLogger({ isSilent: buildOptions.isSilent });
const themeDirPath = pathJoin(keycloakThemeBuildingDirPath, "src", "main", "resources", "theme", buildOptions.themeName, "login"); const themeDirPath = pathJoin(keycloakThemeBuildingDirPath, "src", "main", "resources", "theme", buildOptions.themeName, "login");
let allCssGlobalsToDefine: Record<string, string> = {}; let allCssGlobalsToDefine: Record<string, string> = {};
@ -97,7 +100,7 @@ export function generateKeycloakThemeResources(params: {
} }
if (/\.js?$/i.test(filePath)) { if (/\.js?$/i.test(filePath)) {
if (!buildOptions.isStandalone && buildOptions.isAppAndKeycloakServerSharingSameDomain) { if (!buildOptions.isStandalone && buildOptions.areAppAndKeycloakServerSharingSameDomain) {
return undefined; return undefined;
} }
@ -117,7 +120,7 @@ export function generateKeycloakThemeResources(params: {
email: { email: {
if (!fs.existsSync(keycloakThemeEmailDirPath)) { if (!fs.existsSync(keycloakThemeEmailDirPath)) {
console.log( logger.log(
[ [
`Not bundling email template because ${pathBasename(keycloakThemeEmailDirPath)} does not exist`, `Not bundling email template because ${pathBasename(keycloakThemeEmailDirPath)} does not exist`,
`To start customizing the email template, run: 👉 npx create-keycloak-email-directory 👈` `To start customizing the email template, run: 👉 npx create-keycloak-email-directory 👈`
@ -154,7 +157,8 @@ export function generateKeycloakThemeResources(params: {
downloadBuiltinKeycloakTheme({ downloadBuiltinKeycloakTheme({
keycloakVersion, keycloakVersion,
"destDirPath": tmpDirPath "destDirPath": tmpDirPath,
isSilent: buildOptions.isSilent
}); });
const themeResourcesDirPath = pathJoin(themeDirPath, "resources"); const themeResourcesDirPath = pathJoin(themeDirPath, "resources");

View File

@ -5,6 +5,8 @@ import * as child_process from "child_process";
import { generateStartKeycloakTestingContainer } from "./generateStartKeycloakTestingContainer"; import { generateStartKeycloakTestingContainer } from "./generateStartKeycloakTestingContainer";
import * as fs from "fs"; import * as fs from "fs";
import { readBuildOptions } from "./BuildOptions"; import { readBuildOptions } from "./BuildOptions";
import { getLogger } from "../tools/logger";
import { getCliOptions } from "../tools/cliOptions";
const reactProjectDirPath = process.cwd(); const reactProjectDirPath = process.cwd();
@ -12,7 +14,9 @@ export const keycloakThemeBuildingDirPath = pathJoin(reactProjectDirPath, "build
export const keycloakThemeEmailDirPath = pathJoin(keycloakThemeBuildingDirPath, "..", "keycloak_email"); export const keycloakThemeEmailDirPath = pathJoin(keycloakThemeBuildingDirPath, "..", "keycloak_email");
export function main() { export function main() {
console.log("🔏 Building the keycloak theme...⌚"); const { isSilent, hasExternalAssets } = getCliOptions(process.argv.slice(2));
const logger = getLogger({ isSilent });
logger.log("🔏 Building the keycloak theme...⌚");
const buildOptions = readBuildOptions({ const buildOptions = readBuildOptions({
"packageJson": fs.readFileSync(pathJoin(reactProjectDirPath, "package.json")).toString("utf8"), "packageJson": fs.readFileSync(pathJoin(reactProjectDirPath, "package.json")).toString("utf8"),
@ -25,7 +29,8 @@ export function main() {
return fs.readFileSync(cnameFilePath).toString("utf8"); return fs.readFileSync(cnameFilePath).toString("utf8");
})(), })(),
"isExternalAssetsCliParamProvided": process.argv[2]?.toLowerCase() === "--external-assets" "isExternalAssetsCliParamProvided": hasExternalAssets,
"isSilent": isSilent
}); });
const { doBundlesEmailTemplate } = generateKeycloakThemeResources({ const { doBundlesEmailTemplate } = generateKeycloakThemeResources({
@ -59,7 +64,7 @@ export function main() {
buildOptions buildOptions
}); });
console.log( logger.log(
[ [
"", "",
`✅ Your keycloak theme has been generated and bundled into ./${pathRelative(reactProjectDirPath, jarFilePath)} 🚀`, `✅ Your keycloak theme has been generated and bundled into ./${pathRelative(reactProjectDirPath, jarFilePath)} 🚀`,

View File

@ -57,7 +57,7 @@ export function replaceImportsFromStaticInJsCode(params: { jsCode: string; build
: ` : `
var p= ""; var p= "";
Object.defineProperty(${n}, "p", { Object.defineProperty(${n}, "p", {
get: function() { return "${ftlValuesGlobalName}" in window ? "${buildOptions.urlOrigin}" : p; }, get: function() { return "${ftlValuesGlobalName}" in window ? "${buildOptions.urlOrigin}/" : p; },
set: function (value){ p = value;} set: function (value){ p = value;}
}); });
` `
@ -73,13 +73,13 @@ export function replaceImportsFromStaticInJsCode(params: { jsCode: string; build
.replace(/([a-zA-Z]+\.[a-zA-Z]+)\+"static\//g, (...[, group]) => .replace(/([a-zA-Z]+\.[a-zA-Z]+)\+"static\//g, (...[, group]) =>
buildOptions.isStandalone buildOptions.isStandalone
? `window.${ftlValuesGlobalName}.url.resourcesPath + "/build/static/` ? `window.${ftlValuesGlobalName}.url.resourcesPath + "/build/static/`
: `("${ftlValuesGlobalName}" in window ? "${buildOptions.urlOrigin}" : ${group}) + "static/` : `("${ftlValuesGlobalName}" in window ? "${buildOptions.urlOrigin}/" : ${group}) + "static/`
) )
//TODO: Write a test case for this //TODO: Write a test case for this
.replace(/".chunk.css",([a-zA-Z])+=([a-zA-Z]+\.[a-zA-Z]+)\+([a-zA-Z]+),/, (...[, group1, group2, group3]) => .replace(/".chunk.css",([a-zA-Z])+=([a-zA-Z]+\.[a-zA-Z]+)\+([a-zA-Z]+),/, (...[, group1, group2, group3]) =>
buildOptions.isStandalone buildOptions.isStandalone
? `".chunk.css",${group1} = window.${ftlValuesGlobalName}.url.resourcesPath + "/build/" + ${group3},` ? `".chunk.css",${group1} = window.${ftlValuesGlobalName}.url.resourcesPath + "/build/" + ${group3},`
: `".chunk.css",${group1} = ("${ftlValuesGlobalName}" in window ? "${buildOptions.urlOrigin}" : ${group2}) + ${group3},` : `".chunk.css",${group1} = ("${ftlValuesGlobalName}" in window ? "${buildOptions.urlOrigin}/" : ${group2}) + ${group3},`
); );
return { fixedJsCode }; return { fixedJsCode };

View File

@ -0,0 +1,15 @@
import parseArgv from "minimist";
export type CliOptions = {
isSilent: boolean;
hasExternalAssets: boolean;
};
export const getCliOptions = (processArgv: string[]): CliOptions => {
const argv = parseArgv(processArgv);
return {
isSilent: typeof argv["silent"] === "boolean" ? argv["silent"] : false,
hasExternalAssets: typeof argv["external-assets"] === "boolean" ? argv["external-assets"] : false
};
};

View File

@ -6,7 +6,13 @@ import { rm, rm_rf } from "./rm";
import * as crypto from "crypto"; import * as crypto from "crypto";
/** assert url ends with .zip */ /** assert url ends with .zip */
export function downloadAndUnzip(params: { url: string; destDirPath: string; pathOfDirToExtractInArchive?: string; cacheDirPath: string }) { export function downloadAndUnzip(params: {
isSilent: boolean;
url: string;
destDirPath: string;
pathOfDirToExtractInArchive?: string;
cacheDirPath: string;
}) {
const { url, destDirPath, pathOfDirToExtractInArchive, cacheDirPath } = params; const { url, destDirPath, pathOfDirToExtractInArchive, cacheDirPath } = params;
const extractDirPath = pathJoin( const extractDirPath = pathJoin(
@ -54,7 +60,7 @@ export function downloadAndUnzip(params: { url: string; destDirPath: string; pat
const zipFileBasename = pathBasename(url); const zipFileBasename = pathBasename(url);
execSync(`curl -L ${url} -o ${zipFileBasename}`, { "cwd": extractDirPath }); execSync(`curl -L ${url} -o ${zipFileBasename} ${params.isSilent ? "-s" : ""}`, { "cwd": extractDirPath });
execSync(`unzip -o ${zipFileBasename}${pathOfDirToExtractInArchive === undefined ? "" : ` "${pathOfDirToExtractInArchive}/**/*"`}`, { execSync(`unzip -o ${zipFileBasename}${pathOfDirToExtractInArchive === undefined ? "" : ` "${pathOfDirToExtractInArchive}/**/*"`}`, {
"cwd": extractDirPath "cwd": extractDirPath

27
src/bin/tools/logger.ts Normal file
View File

@ -0,0 +1,27 @@
type LoggerOpts = {
force?: boolean;
};
type Logger = {
log: (message: string, opts?: LoggerOpts) => void;
warn: (message: string) => void;
error: (message: string) => void;
};
export const getLogger = ({ isSilent }: { isSilent?: boolean } = {}): Logger => {
return {
log: (message, { force } = {}) => {
if (isSilent && !force) {
return;
}
console.log(message);
},
warn: message => {
console.warn(message);
},
error: message => {
console.error(message);
}
};
};

View File

@ -83,8 +83,6 @@ export function __unsafe_useI18n<ExtraMessageKey extends string = never>(params:
return; return;
} }
let isMounted = true;
refHasStartedFetching.current = true; refHasStartedFetching.current = true;
(async () => { (async () => {
@ -144,10 +142,6 @@ export function __unsafe_useI18n<ExtraMessageKey extends string = never>(params:
})() })()
]).then(modules => modules.map(module => module.default)); ]).then(modules => modules.map(module => module.default));
if (!isMounted) {
return;
}
setI18n({ setI18n({
...createI18nTranslationFunctions({ ...createI18nTranslationFunctions({
"fallbackMessages": { "fallbackMessages": {
@ -180,10 +174,6 @@ export function __unsafe_useI18n<ExtraMessageKey extends string = never>(params:
) )
}); });
})(); })();
return () => {
isMounted = false;
};
}, []); }, []);
return i18n ?? null; return i18n ?? null;

View File

@ -14,6 +14,7 @@ generateKeycloakThemeResources({
"extraPages": ["my-custom-page.ftl"], "extraPages": ["my-custom-page.ftl"],
"extraThemeProperties": ["env=test"], "extraThemeProperties": ["env=test"],
"isStandalone": true, "isStandalone": true,
"urlPathname": "/keycloakify-demo-app/" "urlPathname": "/keycloakify-demo-app/",
"isSilent": false
} }
}); });

View File

@ -103,13 +103,13 @@ import { assetIsSameCode } from "../tools/assertIsSameCode";
const fixedJsCodeExpected = ` const fixedJsCodeExpected = `
function f() { function f() {
return ("kcContext" in window ? "https://demo-app.keycloakify.dev" : a.p) + "static/js/" + ({}[e] || e) + "." + { return ("kcContext" in window ? "https://demo-app.keycloakify.dev/" : a.p) + "static/js/" + ({}[e] || e) + "." + {
3: "0664cdc0" 3: "0664cdc0"
}[e] + ".chunk.js" }[e] + ".chunk.js"
} }
function sameAsF() { function sameAsF() {
return ("kcContext" in window ? "https://demo-app.keycloakify.dev" : a.p) + "static/js/" + ({}[e] || e) + "." + { return ("kcContext" in window ? "https://demo-app.keycloakify.dev/" : a.p) + "static/js/" + ({}[e] || e) + "." + {
3: "0664cdc0" 3: "0664cdc0"
}[e] + ".chunk.js" }[e] + ".chunk.js"
} }
@ -119,7 +119,7 @@ import { assetIsSameCode } from "../tools/assertIsSameCode";
if( pd === undefined || pd.configurable ){ if( pd === undefined || pd.configurable ){
var p= ""; var p= "";
Object.defineProperty(__webpack_require__, "p", { Object.defineProperty(__webpack_require__, "p", {
get: function() { return "kcContext" in window ? "https://demo-app.keycloakify.dev" : p; }, get: function() { return "kcContext" in window ? "https://demo-app.keycloakify.dev/" : p; },
set: function (value){ p = value; } set: function (value){ p = value; }
}); });
} }
@ -137,7 +137,7 @@ import { assetIsSameCode } from "../tools/assertIsSameCode";
if( pd === undefined || pd.configurable ){ if( pd === undefined || pd.configurable ){
var p= ""; var p= "";
Object.defineProperty(t, "p", { Object.defineProperty(t, "p", {
get: function() { return "kcContext" in window ? "https://demo-app.keycloakify.dev" : p; }, get: function() { return "kcContext" in window ? "https://demo-app.keycloakify.dev/" : p; },
set: function (value){ p = value; } set: function (value){ p = value; }
}); });
} }

View File

@ -8,6 +8,7 @@ export function setupSampleReactProject() {
downloadAndUnzip({ downloadAndUnzip({
"url": "https://github.com/InseeFrLab/keycloakify/releases/download/v0.0.1/sample_build_dir_and_package_json.zip", "url": "https://github.com/InseeFrLab/keycloakify/releases/download/v0.0.1/sample_build_dir_and_package_json.zip",
"destDirPath": sampleReactProjectDirPath, "destDirPath": sampleReactProjectDirPath,
"cacheDirPath": pathJoin(sampleReactProjectDirPath, "build_keycloak", ".cache") "cacheDirPath": pathJoin(sampleReactProjectDirPath, "build_keycloak", ".cache"),
"isSilent": false
}); });
} }

View File

@ -265,6 +265,11 @@
resolved "https://registry.yarnpkg.com/@types/memoizee/-/memoizee-0.4.8.tgz#04adc0c266a0f5d72db0556fdda2ba17dad9b519" resolved "https://registry.yarnpkg.com/@types/memoizee/-/memoizee-0.4.8.tgz#04adc0c266a0f5d72db0556fdda2ba17dad9b519"
integrity sha512-qDpXKGgwKywnQt/64fH1O0LiPA++QGIYeykEUiZ51HymKVRLnUSGcRuF60IfpPeeXiuRwiR/W4y7S5VzbrgLCA== integrity sha512-qDpXKGgwKywnQt/64fH1O0LiPA++QGIYeykEUiZ51HymKVRLnUSGcRuF60IfpPeeXiuRwiR/W4y7S5VzbrgLCA==
"@types/minimist@^1.2.2":
version "1.2.2"
resolved "https://registry.yarnpkg.com/@types/minimist/-/minimist-1.2.2.tgz#ee771e2ba4b3dc5b372935d549fd9617bf345b8c"
integrity sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ==
"@types/node@^17.0.25": "@types/node@^17.0.25":
version "17.0.45" version "17.0.45"
resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.45.tgz#2c0fafd78705e7a18b7906b5201a522719dc5190" resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.45.tgz#2c0fafd78705e7a18b7906b5201a522719dc5190"
@ -1188,6 +1193,11 @@ minimatch@^3.0.3, minimatch@^3.1.1:
dependencies: dependencies:
brace-expansion "^1.1.7" brace-expansion "^1.1.7"
minimist@^1.2.6:
version "1.2.6"
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.6.tgz#8637a5b759ea0d6e98702cfb3a9283323c93af44"
integrity sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==
mkdirp@^1.0.4: mkdirp@^1.0.4:
version "1.0.4" version "1.0.4"
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e"
@ -1733,10 +1743,10 @@ tslib@^2.1.0:
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.0.tgz#7cecaa7f073ce680a05847aa77be941098f36dc3" resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.0.tgz#7cecaa7f073ce680a05847aa77be941098f36dc3"
integrity sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ== integrity sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==
tss-react@^4.1.1: tss-react@^4.1.3:
version "4.1.1" version "4.1.3"
resolved "https://registry.yarnpkg.com/tss-react/-/tss-react-4.1.1.tgz#207220417e4b2f8eb26d8280ab9cdeb385063069" resolved "https://registry.yarnpkg.com/tss-react/-/tss-react-4.1.3.tgz#170a2edd85e32ba3b752416eeb45438c35e90243"
integrity sha512-K1U2s/GGw+XycUjJGztJsLUhwm8KJWz5afL5WZU3SwMeQsA+gbETM6bSxVk2/DXBdw9uYLL9jkSYPAXh0tfYBw== integrity sha512-Ul99aVoVngHY2nwFC87jZlGP+K3LfG9ZRakimOzRwgJz77f/zXWuY2FVzwaSc+OW804twNaxZZRtLlpagex8sg==
dependencies: dependencies:
"@emotion/cache" "*" "@emotion/cache" "*"
"@emotion/serialize" "*" "@emotion/serialize" "*"