Compare commits

...

9 Commits

8 changed files with 61 additions and 78 deletions

View File

@ -1,6 +1,6 @@
{ {
"name": "keycloakify", "name": "keycloakify",
"version": "9.4.0-rc.2", "version": "9.4.0-rc.5",
"description": "Create Keycloak themes using React", "description": "Create Keycloak themes using React",
"repository": { "repository": {
"type": "git", "type": "git",

13
src/PUBLIC_URL.ts Normal file
View File

@ -0,0 +1,13 @@
import { nameOfTheGlobal, basenameOfTheKeycloakifyResourcesDir } from "keycloakify/bin/constants";
/**
* This is an equivalent of process.env.PUBLIC_URL thay you can use in Webpack projects.
* This works both in your main app and in your Keycloak theme.
*/
export const PUBLIC_URL = (() => {
const kcContext = (window as any)[nameOfTheGlobal];
return kcContext === undefined || process.env.NODE_ENV === "development"
? process.env.PUBLIC_URL
: `${kcContext.url.resourcesPath}/${basenameOfTheKeycloakifyResourcesDir}`;
})();

View File

@ -62,9 +62,9 @@ export async function downloadBuiltinKeycloakTheme(params: { keycloakVersion: st
// Note, this is an optimization for reducing the size of the jar // Note, this is an optimization for reducing the size of the jar
remove_unused_node_modules: { remove_unused_node_modules: {
const pathOfNodeModules = pathJoin(destDirPath, "keycloak", "common", "resources", "node_modules"); const nodeModuleDirPath = pathJoin(destDirPath, "keycloak", "common", "resources", "node_modules");
if (!fs.existsSync(pathOfNodeModules)) { if (!fs.existsSync(nodeModuleDirPath)) {
break remove_unused_node_modules; break remove_unused_node_modules;
} }
@ -114,8 +114,8 @@ export async function downloadBuiltinKeycloakTheme(params: { keycloakVersion: st
]; ];
transformCodebase({ transformCodebase({
"srcDirPath": pathOfNodeModules, "srcDirPath": nodeModuleDirPath,
"destDirPath": pathOfNodeModules, "destDirPath": nodeModuleDirPath,
"transformSourceCode": ({ sourceCode, fileRelativePath }) => { "transformSourceCode": ({ sourceCode, fileRelativePath }) => {
if (fileRelativePath.endsWith(".map")) { if (fileRelativePath.endsWith(".map")) {
return undefined; return undefined;
@ -140,6 +140,33 @@ export async function downloadBuiltinKeycloakTheme(params: { keycloakVersion: st
}); });
} }
// Just like node_modules
remove_unused_lib: {
const libDirPath = pathJoin(destDirPath, "keycloak", "common", "resources", "lib");
if (!fs.existsSync(libDirPath)) {
break remove_unused_lib;
}
const toDeletePerfixes = ["ui-ace", "filesaver", "fileupload", "angular", "ui-ace", "pficon"];
transformCodebase({
"srcDirPath": libDirPath,
"destDirPath": libDirPath,
"transformSourceCode": ({ sourceCode, fileRelativePath }) => {
if (fileRelativePath.endsWith(".map")) {
return undefined;
}
if (toDeletePerfixes.find(prefix => fileRelativePath.startsWith(prefix)) !== undefined) {
return undefined;
}
return { "modifiedSourceCode": sourceCode };
}
});
}
last_account_v1_transformations: { last_account_v1_transformations: {
if (lastKeycloakVersionWithAccountV1 !== keycloakVersion) { if (lastKeycloakVersionWithAccountV1 !== keycloakVersion) {
break last_account_v1_transformations; break last_account_v1_transformations;
@ -182,38 +209,25 @@ export async function downloadBuiltinKeycloakTheme(params: { keycloakVersion: st
); );
} }
// Note, this is an optimization for reducing the size of the jar // Note, this is an optimization for reducing the size of the jar,
// For this version we know exactly which resources are used.
{ {
const nodeModulesDirPath = pathJoin(destDirPath, "keycloak", "common", "resources"); const nodeModulesDirPath = pathJoin(destDirPath, "keycloak", "common", "resources", "node_modules");
const usedCommonResourceRelativeFilePaths = [ const toKeepPrefixes = [
...["patternfly.min.css", "patternfly-additions.min.css", "patternfly-additions.min.css"].map(fileBasename => ...["patternfly.min.css", "patternfly-additions.min.css", "patternfly-additions.min.css"].map(fileBasename =>
pathJoin("patternfly", "dist", "css", fileBasename) pathJoin("patternfly", "dist", "css", fileBasename)
), ),
...[ pathJoin("patternfly", "dist", "fonts")
"OpenSans-Light-webfont.woff2",
"OpenSans-Regular-webfont.woff2",
"OpenSans-Bold-webfont.woff2",
"OpenSans-Semibold-webfont.woff2",
"OpenSans-Bold-webfont.woff",
"OpenSans-Light-webfont.woff",
"OpenSans-Regular-webfont.woff",
"OpenSans-Semibold-webfont.woff",
"OpenSans-Regular-webfont.ttf",
"OpenSans-Light-webfont.ttf",
"OpenSans-Semibold-webfont.ttf",
"OpenSans-Bold-webfont.ttf"
].map(fileBasename => pathJoin("patternfly", "dist", "fonts", fileBasename))
]; ];
transformCodebase({ transformCodebase({
"srcDirPath": nodeModulesDirPath, "srcDirPath": nodeModulesDirPath,
"destDirPath": nodeModulesDirPath, "destDirPath": nodeModulesDirPath,
"transformSourceCode": ({ sourceCode, fileRelativePath }) => { "transformSourceCode": ({ sourceCode, fileRelativePath }) => {
if (!usedCommonResourceRelativeFilePaths.includes(fileRelativePath)) { if (toKeepPrefixes.find(prefix => fileRelativePath.startsWith(prefix)) === undefined) {
return undefined; return undefined;
} }
return { "modifiedSourceCode": sourceCode }; return { "modifiedSourceCode": sourceCode };
} }
}); });

View File

@ -30,7 +30,6 @@ export function generateStartKeycloakTestingContainer(params: { jarFilePath: str
Buffer.from( Buffer.from(
[ [
"#!/usr/bin/env bash", "#!/usr/bin/env bash",
`# If you want to test with Keycloak version prior to 23 use the retrocompat-${pathBasename(jarFilePath)}`,
"", "",
`docker rm ${containerName} || true`, `docker rm ${containerName} || true`,
"", "",

View File

@ -29,20 +29,6 @@ export function replaceImportsInJsCode_webpack(params: { jsCode: string; buildOp
); );
} }
// d={NODE_ENV:"production",PUBLIC_URL:"/foo-bar",WDS_SOCKET_HOST
// d={NODE_ENV:"production",PUBLIC_URL:"",WDS_SOCKET_HOST
// ->
// ... PUBLIC_URL:window.kcContext.url.resourcesPath+"/build" ...
fixedJsCode = fixedJsCode.replace(
new RegExp(
`NODE_ENV:"production",PUBLIC_URL:"${
buildOptions.urlPathname !== undefined ? replaceAll(buildOptions.urlPathname.slice(0, -1), "/", "\\/") : ""
}"`,
"g"
),
`NODE_ENV:"production",PUBLIC_URL:window.${nameOfTheGlobal}.url.resourcesPath+"/${basenameOfTheKeycloakifyResourcesDir}"`
);
// Example: "static/ or "foo/bar/" // Example: "static/ or "foo/bar/"
const staticDir = (() => { const staticDir = (() => {
let out = pathRelative(buildOptions.reactAppBuildDirPath, buildOptions.assetsDirPath); let out = pathRelative(buildOptions.reactAppBuildDirPath, buildOptions.assetsDirPath);

View File

@ -17,13 +17,14 @@ type TransformSourceCode = (params: { sourceCode: Buffer; filePath: string; file
* */ * */
export function transformCodebase(params: { srcDirPath: string; destDirPath: string; transformSourceCode?: TransformSourceCode }) { export function transformCodebase(params: { srcDirPath: string; destDirPath: string; transformSourceCode?: TransformSourceCode }) {
const { srcDirPath, transformSourceCode } = params; const { srcDirPath, transformSourceCode } = params;
let { destDirPath } = params;
const isTargetSameAsSource = path.relative(srcDirPath, destDirPath) === ""; const isTargetSameAsSource = path.relative(srcDirPath, params.destDirPath) === "";
if (isTargetSameAsSource) { const destDirPath = isTargetSameAsSource ? path.join(srcDirPath, "..", "tmp_xOsPdkPsTdzPs34sOkHs") : params.destDirPath;
destDirPath = path.join(srcDirPath, "..", "tmp_xOsPdkPsTdzPs34sOkHs");
} fs.mkdirSync(destDirPath, {
"recursive": true
});
for (const fileRelativePath of crawl({ "dirPath": srcDirPath, "returnedPathsType": "relative to dirPath" })) { for (const fileRelativePath of crawl({ "dirPath": srcDirPath, "returnedPathsType": "relative to dirPath" })) {
const filePath = path.join(srcDirPath, fileRelativePath); const filePath = path.join(srcDirPath, fileRelativePath);

View File

@ -36,6 +36,10 @@ export declare namespace keycloak_js {
} }
/** /**
* @deprecated: This will be removed in the next major version.
* If you use this, please copy paste the code into your project.
* Better yet migrate away from keycloak-js and use https://docs.oidc-spa.dev instead.
*
* NOTE: This is just a slightly modified version of the default adapter in keycloak-js * NOTE: This is just a slightly modified version of the default adapter in keycloak-js
* The goal here is just to be able to inject search param in url before keycloak redirect. * The goal here is just to be able to inject search param in url before keycloak redirect.
* Our use case for it is to pass over the login screen the states of useGlobalState * Our use case for it is to pass over the login screen the states of useGlobalState

View File

@ -361,40 +361,6 @@ describe("js replacer - webpack", () => {
expect(isSameCode(fixedJsCode, fixedJsCodeExpected)).toBe(true); expect(isSameCode(fixedJsCode, fixedJsCodeExpected)).toBe(true);
}); });
it("replaceImportsInJsCode_webpack - 4", () => {
const jsCodeUntransformed = `d={NODE_ENV:"production",PUBLIC_URL:"",WDS_SOCKET_HOST`;
const { fixedJsCode } = replaceImportsInJsCode_webpack({
"jsCode": jsCodeUntransformed,
"buildOptions": {
"reactAppBuildDirPath": "/Users/someone/github/keycloakify-starter/build",
"assetsDirPath": "/Users/someone/github/keycloakify-starter/dist/build/static",
"urlPathname": undefined
}
});
const fixedJsCodeExpected = `d={NODE_ENV:"production",PUBLIC_URL:window.${nameOfTheGlobal}.url.resourcesPath+"/${basenameOfTheKeycloakifyResourcesDir}",WDS_SOCKET_HOST`;
expect(isSameCode(fixedJsCode, fixedJsCodeExpected)).toBe(true);
});
it("replaceImportsInJsCode_webpack - 5", () => {
const jsCodeUntransformed = `d={NODE_ENV:"production",PUBLIC_URL:"/foo-bar",WDS_SOCKET_HOST`;
const { fixedJsCode } = replaceImportsInJsCode_webpack({
"jsCode": jsCodeUntransformed,
"buildOptions": {
"reactAppBuildDirPath": "/Users/someone/github/keycloakify-starter/build",
"assetsDirPath": "/Users/someone/github/keycloakify-starter/dist/build/static",
"urlPathname": "/foo-bar/"
}
});
const fixedJsCodeExpected = `d={NODE_ENV:"production",PUBLIC_URL:window.${nameOfTheGlobal}.url.resourcesPath+"/${basenameOfTheKeycloakifyResourcesDir}",WDS_SOCKET_HOST`;
expect(isSameCode(fixedJsCode, fixedJsCodeExpected)).toBe(true);
});
}); });
describe("css replacer", () => { describe("css replacer", () => {