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 0000000..6a64ac6 Binary files /dev/null and b/test/fixtures/todo/app/assets/images/logo.png differ diff --git a/test/hanami-assets.test.ts b/test/hanami-assets.test.ts index ce53203..d29785a 100644 --- a/test/hanami-assets.test.ts +++ b/test/hanami-assets.test.ts @@ -126,6 +126,14 @@ describe("hanami-assets", () => { 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"], }, });