From fc88e1fbdb12941ffd5632bd7cb96db1ebea77a9 Mon Sep 17 00:00:00 2001 From: Luca Guidi Date: Tue, 14 Nov 2023 10:41:40 +0100 Subject: [PATCH] Ensure static assets coming from slices have the slice name prefix in dest URL --- dist/esbuild-plugin.js | 16 +++++++++++++++- src/esbuild-plugin.ts | 17 +++++++++++++++-- test/fixtures/todo/app/assets/images/logo.png | Bin 0 -> 3132 bytes test/hanami-assets.test.ts | 16 ++++++++++------ 4 files changed, 40 insertions(+), 9 deletions(-) create mode 100644 test/fixtures/todo/app/assets/images/logo.png diff --git a/dist/esbuild-plugin.js b/dist/esbuild-plugin.js index 44209e3..22d04d2 100644 --- a/dist/esbuild-plugin.js +++ b/dist/esbuild-plugin.js @@ -21,6 +21,11 @@ const hanamiEsbuild = (options = { ...defaults }) => { build.onEnd(async (result) => { const outputs = result.metafile?.outputs; const assetsManifest = {}; + const extractSliceName = (dirPath) => { + const regex = /^slices\/([^\/]+)/; + const match = dirPath.match(regex); + return match ? match[1] : null; + }; const calulateSourceUrl = (str) => { return normalizeUrl(str) .replace(/\/assets\//, "") @@ -45,6 +50,9 @@ const hanamiEsbuild = (options = { ...defaults }) => { const result = crypto.createHash("sha256").update(hashBytes).digest("hex"); return result.slice(0, 8).toUpperCase(); }; + const compactArray = (arr) => { + return arr.filter((token) => token !== null); + }; function extractEsbuildInputs(inputData) { const inputs = {}; for (const key in inputData) { @@ -87,7 +95,13 @@ const hanamiEsbuild = (options = { ...defaults }) => { const fileExtension = path.extname(srcPath); const baseName = path.basename(srcPath, fileExtension); const destFileName = [baseName, fileHash].filter((item) => item !== null).join("-") + fileExtension; - const destPath = path.join(options.destDir, path.relative(dirPath, srcPath).replace(file, destFileName)); + const sliceName = extractSliceName(dirPath); + const pathTokens = compactArray([ + options.destDir, + sliceName, + path.relative(dirPath, srcPath).replace(file, destFileName), + ]); + const destPath = path.join(...pathTokens); if (fs.lstatSync(srcPath).isDirectory()) { assets.push(...processAssetDirectory(destPath, inputs, options)); } diff --git a/src/esbuild-plugin.ts b/src/esbuild-plugin.ts index a59a427..3ef12aa 100644 --- a/src/esbuild-plugin.ts +++ b/src/esbuild-plugin.ts @@ -46,6 +46,12 @@ const hanamiEsbuild = (options: PluginOptions = { ...defaults }): Plugin => { const outputs = result.metafile?.outputs; const assetsManifest: Record = {}; + const extractSliceName = (dirPath: string): string | null => { + const regex = /^slices\/([^\/]+)/; + const match = dirPath.match(regex); + return match ? match[1] : null; + } + const calulateSourceUrl = (str: string): string => { return normalizeUrl(str) .replace(/\/assets\//, "") @@ -78,6 +84,10 @@ const hanamiEsbuild = (options: PluginOptions = { ...defaults }): Plugin => { return result.slice(0, 8).toUpperCase(); }; + const compactArray = (arr: Array): Array => { + return arr.filter((token): token is string => token !== null); + } + function extractEsbuildInputs(inputData: Record): Record { const inputs: Record = {}; @@ -137,10 +147,13 @@ const hanamiEsbuild = (options: PluginOptions = { ...defaults }): Plugin => { const baseName = path.basename(srcPath, fileExtension); const destFileName = [baseName, fileHash].filter((item) => item !== null).join("-") + fileExtension; - const destPath = path.join( + const sliceName = extractSliceName(dirPath); + const pathTokens = compactArray([ options.destDir, + sliceName, path.relative(dirPath, srcPath).replace(file, destFileName), - ); + ]); + const destPath = path.join(...pathTokens); if (fs.lstatSync(srcPath).isDirectory()) { assets.push(...processAssetDirectory(destPath, inputs, options)); diff --git a/test/fixtures/todo/app/assets/images/logo.png b/test/fixtures/todo/app/assets/images/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..6a64ac644fa736dd73c49bc40a4f43fa2f23483f GIT binary patch literal 3132 zcmV-C48!w@P)7JgA8Dt5f1W-^wO9c@`C_>cI zxCAVXu`nhnM1>$GCT=B(MuTO!BnD%Ol))I6C|2B}A>vk6SPTvjlp#1QvpU`MO!rK0 z@4ftSx`$>NXI}RV@KwE<>Gy7*d%kziJ@?#mZmasU0~`n32-E}b9qW#@W8EQe7w|Oj zIxsWm{^h_Q0pDPD?iftrhhaGICtybAvkzDY{1ylRR{>6-2Kd%sDWTso)H7JJb8#K; z4lw#C&&~o)M@)P#a6T{+Xac4Ki-0K5Fc6BUL7u}dU=?tEKiZl=IP

XawHP{NDon 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 { url: "/assets/background-UU2XY655.jpg", sri: ["sha384-M7QyKTUfzyVWNC4FoMYq0ypu7LDifAYWEtXRT5d6M3Prpau9t5wavW1216HhvCJc"], }, + "font.otf": { + url: "/assets/font-E1A70B27.otf", + sri: ["sha384-Lpm/oUsCQkOg41WyENyyB1zjaX/FB522VWlU44JKakwzwBxvu11le0ILkiPsR73K"], + }, + "logo.png": { + "url": "/assets/logo-C1EF77E4.png", + "sri": ["sha384-7q5x+ZjZrCoWwyV0BTyc8HUPf1xr+n9l77gwxmwywPWSe0PtopZj1T8NTUPFo0FI"], + }, "app.css": { url: "/assets/app-4HPGUYGF.css", sri: ["sha384-KsEObWWMvw+PouA5LgKpXohYpsOO4h9dL9pv7LwznkIg83/n1gkJo+S/oU/9Qb8Q"], @@ -138,12 +146,8 @@ describe("hanami-assets", () => { url: "/assets/admin/app-H646WNEB.js", sri: ["sha384-noZH9am6sCla+CnG7l+IGxBlTqo68Wz891fhqfIF1U2kgafUrRzZewAt0yA6jl15"], }, - "font.otf": { - url: "/assets/font-E1A70B27.otf", - sri: ["sha384-Lpm/oUsCQkOg41WyENyyB1zjaX/FB522VWlU44JKakwzwBxvu11le0ILkiPsR73K"], - }, - "logo.png": { - url: "/assets/logo-C1EF77E4.png", + "admin/logo.png": { + url: "/assets/admin/logo-C1EF77E4.png", sri: ["sha384-7q5x+ZjZrCoWwyV0BTyc8HUPf1xr+n9l77gwxmwywPWSe0PtopZj1T8NTUPFo0FI"], }, });