Meta progaming for detecting static assets usage a build time
This commit is contained in:
parent
1c25b69160
commit
3c2820dc31
@ -3,7 +3,6 @@ import { removeDuplicates } from "evt/tools/reducers/removeDuplicates";
|
||||
import { join as pathJoin } from "path";
|
||||
import * as fs from "fs";
|
||||
import type { ThemeType } from "../generateFtl";
|
||||
import { exclude } from "tsafe/exclude";
|
||||
|
||||
/** Assumes the theme type exists */
|
||||
export function readFieldNameUsage(params: { keycloakifySrcDirPath: string; themeSrcDirPath: string; themeType: ThemeType }): string[] {
|
||||
@ -11,9 +10,7 @@ export function readFieldNameUsage(params: { keycloakifySrcDirPath: string; them
|
||||
|
||||
const fieldNames: string[] = [];
|
||||
|
||||
for (const srcDirPath of ([pathJoin(keycloakifySrcDirPath, themeType), pathJoin(themeSrcDirPath, themeType)] as const).filter(
|
||||
exclude(undefined)
|
||||
)) {
|
||||
for (const srcDirPath of [pathJoin(keycloakifySrcDirPath, themeType), pathJoin(themeSrcDirPath, themeType)]) {
|
||||
const filePaths = crawl({ "dirPath": srcDirPath, "returnedPathsType": "absolute" }).filter(filePath => /\.(ts|tsx|js|jsx)$/.test(filePath));
|
||||
|
||||
for (const filePath of filePaths) {
|
||||
|
@ -0,0 +1,87 @@
|
||||
import { crawl } from "../../tools/crawl";
|
||||
import { join as pathJoin } from "path";
|
||||
import * as fs from "fs";
|
||||
import type { ThemeType } from "../generateFtl";
|
||||
|
||||
/** Assumes the theme type exists */
|
||||
export function readStaticResourcesUsage(params: { keycloakifySrcDirPath: string; themeSrcDirPath: string; themeType: ThemeType }): {
|
||||
resourcesCommonFilePaths: string[];
|
||||
resourcesFilePaths: string[];
|
||||
} {
|
||||
const { keycloakifySrcDirPath, themeSrcDirPath, themeType } = params;
|
||||
|
||||
const resourcesCommonFilePaths = new Set<string>();
|
||||
const resourcesFilePaths = new Set<string>();
|
||||
|
||||
for (const srcDirPath of [pathJoin(keycloakifySrcDirPath, themeType), pathJoin(themeSrcDirPath, themeType)]) {
|
||||
const filePaths = crawl({ "dirPath": srcDirPath, "returnedPathsType": "absolute" }).filter(filePath => /\.(ts|tsx|js|jsx)$/.test(filePath));
|
||||
|
||||
for (const filePath of filePaths) {
|
||||
const rawSourceFile = fs.readFileSync(filePath).toString("utf8");
|
||||
|
||||
if (!rawSourceFile.includes("resourcesCommonPath")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!rawSourceFile.includes("resourcesPath")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const wrap = readPaths({ rawSourceFile });
|
||||
|
||||
wrap.resourcesCommonFilePaths.forEach(filePath => resourcesCommonFilePaths.add(filePath));
|
||||
wrap.resourcesFilePaths.forEach(filePath => resourcesFilePaths.add(filePath));
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
"resourcesCommonFilePaths": Array.from(resourcesCommonFilePaths),
|
||||
"resourcesFilePaths": Array.from(resourcesFilePaths)
|
||||
};
|
||||
}
|
||||
|
||||
/** Exported for testing purpose */
|
||||
export function readPaths(params: { rawSourceFile: string }): {
|
||||
resourcesCommonFilePaths: string[];
|
||||
resourcesFilePaths: string[];
|
||||
} {
|
||||
const { rawSourceFile } = params;
|
||||
|
||||
const resourcesCommonFilePaths = new Set<string>();
|
||||
const resourcesFilePaths = new Set<string>();
|
||||
|
||||
for (const isCommon of [true, false]) {
|
||||
const set = isCommon ? resourcesCommonFilePaths : resourcesFilePaths;
|
||||
|
||||
{
|
||||
const regexp = new RegExp(`resources${isCommon ? "Common" : ""}Path\\s*}([^\`]+)\``, "g");
|
||||
|
||||
const matches = [...rawSourceFile.matchAll(regexp)];
|
||||
|
||||
for (const match of matches) {
|
||||
const filePath = match[1];
|
||||
|
||||
set.add(filePath);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
const regexp = new RegExp(`resources${isCommon ? "Common" : ""}Path\\s*[+,]\\s*["']([^"'\`]+)["'\`]`, "g");
|
||||
|
||||
const matches = [...rawSourceFile.matchAll(regexp)];
|
||||
|
||||
for (const match of matches) {
|
||||
const filePath = match[1];
|
||||
|
||||
set.add(filePath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const removePrefixSlash = (filePath: string) => (filePath.startsWith("/") ? filePath.slice(1) : filePath);
|
||||
|
||||
return {
|
||||
"resourcesCommonFilePaths": Array.from(resourcesCommonFilePaths).map(removePrefixSlash),
|
||||
"resourcesFilePaths": Array.from(resourcesFilePaths).map(removePrefixSlash)
|
||||
};
|
||||
}
|
91
test/bin/readStaticResourcesUsage.spec.ts
Normal file
91
test/bin/readStaticResourcesUsage.spec.ts
Normal file
@ -0,0 +1,91 @@
|
||||
import { readPaths } from "keycloakify/bin/keycloakify/generateTheme/readStaticResourcesUsage";
|
||||
import { same } from "evt/tools/inDepth/same";
|
||||
import { expect, it, describe } from "vitest";
|
||||
|
||||
describe("Ensure it's able to extract used Keycloak resources", () => {
|
||||
const expectedPaths = {
|
||||
"resourcesCommonFilePaths": [
|
||||
"node_modules/patternfly/dist/css/patternfly.min.css",
|
||||
"node_modules/patternfly/dist/css/patternfly-additions.min.css",
|
||||
"lib/zocial/zocial.css"
|
||||
],
|
||||
"resourcesFilePaths": ["css/login.css"]
|
||||
};
|
||||
|
||||
it("works with coding style n°1", () => {
|
||||
const paths = readPaths({
|
||||
"rawSourceFile": `
|
||||
const { isReady } = usePrepareTemplate({
|
||||
"doFetchDefaultThemeResources": doUseDefaultCss,
|
||||
"styles": [
|
||||
\`\${url.resourcesCommonPath}/node_modules/patternfly/dist/css/patternfly.min.css\`,
|
||||
\`\${
|
||||
url.resourcesCommonPath
|
||||
}/node_modules/patternfly/dist/css/patternfly-additions.min.css\`,
|
||||
\`\${resourcesCommonPath }/lib/zocial/zocial.css\`,
|
||||
\`\${url.resourcesPath}/css/login.css\`
|
||||
],
|
||||
"htmlClassName": getClassName("kcHtmlClass"),
|
||||
"bodyClassName": undefined
|
||||
});
|
||||
`
|
||||
});
|
||||
|
||||
expect(same(paths, expectedPaths)).toBe(true);
|
||||
});
|
||||
|
||||
it("works with coding style n°2", () => {
|
||||
const paths = readPaths({
|
||||
"rawSourceFile": `
|
||||
|
||||
const { isReady } = usePrepareTemplate({
|
||||
"doFetchDefaultThemeResources": doUseDefaultCss,
|
||||
"styles": [
|
||||
url.resourcesCommonPath + "/node_modules/patternfly/dist/css/patternfly.min.css",
|
||||
url.resourcesCommonPath + '/node_modules/patternfly/dist/css/patternfly-additions.min.css',
|
||||
url.resourcesCommonPath
|
||||
+ "/lib/zocial/zocial.css",
|
||||
url.resourcesPath +
|
||||
'/css/login.css'
|
||||
],
|
||||
"htmlClassName": getClassName("kcHtmlClass"),
|
||||
"bodyClassName": undefined
|
||||
});
|
||||
|
||||
|
||||
`
|
||||
});
|
||||
|
||||
console.log(paths);
|
||||
console.log(expectedPaths);
|
||||
|
||||
expect(same(paths, expectedPaths)).toBe(true);
|
||||
});
|
||||
|
||||
it("works with coding style n°3", () => {
|
||||
const paths = readPaths({
|
||||
"rawSourceFile": `
|
||||
|
||||
const { isReady } = usePrepareTemplate({
|
||||
"doFetchDefaultThemeResources": doUseDefaultCss,
|
||||
"styles": [
|
||||
path.join(resourcesCommonPath,"/node_modules/patternfly/dist/css/patternfly.min.css"),
|
||||
path.join(url.resourcesCommonPath, '/node_modules/patternfly/dist/css/patternfly-additions.min.css'),
|
||||
path.join(url.resourcesCommonPath,
|
||||
"/lib/zocial/zocial.css"),
|
||||
pathJoin(
|
||||
url.resourcesPath,
|
||||
'css/login.css'
|
||||
)
|
||||
],
|
||||
"htmlClassName": getClassName("kcHtmlClass"),
|
||||
"bodyClassName": undefined
|
||||
});
|
||||
|
||||
|
||||
`
|
||||
});
|
||||
|
||||
expect(same(paths, expectedPaths)).toBe(true);
|
||||
});
|
||||
});
|
Loading…
x
Reference in New Issue
Block a user