diff --git a/registry/blocks/carousel-circle-1/carousel-circle-1.html b/registry/blocks/carousel-circle-1/carousel-circle-1.html index 88f94f8ca0..c9da58b5f1 100644 --- a/registry/blocks/carousel-circle-1/carousel-circle-1.html +++ b/registry/blocks/carousel-circle-1/carousel-circle-1.html @@ -628,7 +628,8 @@ const varUrl = (v) => (v && typeof v === "object" ? v.url || v.src || "" : v || ""); if (REG) { const srcs = REG.imageVars.map( - (id, i) => varUrl(V[id]) || DATA.cards[i % DATA.cards.length].file, + (id, i) => + varUrl(V[id]) || "assets/carousel-images/" + DATA.cards[i % DATA.cards.length].file, ); DATA.cards = await Promise.all( srcs.map(async (src, i) => { diff --git a/registry/blocks/carousel-circle-2/carousel-circle-2.html b/registry/blocks/carousel-circle-2/carousel-circle-2.html index 63eff2bf13..2be49ff521 100644 --- a/registry/blocks/carousel-circle-2/carousel-circle-2.html +++ b/registry/blocks/carousel-circle-2/carousel-circle-2.html @@ -628,7 +628,8 @@ const varUrl = (v) => (v && typeof v === "object" ? v.url || v.src || "" : v || ""); if (REG) { const srcs = REG.imageVars.map( - (id, i) => varUrl(V[id]) || DATA.cards[i % DATA.cards.length].file, + (id, i) => + varUrl(V[id]) || "assets/carousel-images/" + DATA.cards[i % DATA.cards.length].file, ); DATA.cards = await Promise.all( srcs.map(async (src, i) => { diff --git a/registry/blocks/carousel-circle-3/carousel-circle-3.html b/registry/blocks/carousel-circle-3/carousel-circle-3.html index f84efe754c..36894b19bc 100644 --- a/registry/blocks/carousel-circle-3/carousel-circle-3.html +++ b/registry/blocks/carousel-circle-3/carousel-circle-3.html @@ -628,7 +628,8 @@ const varUrl = (v) => (v && typeof v === "object" ? v.url || v.src || "" : v || ""); if (REG) { const srcs = REG.imageVars.map( - (id, i) => varUrl(V[id]) || DATA.cards[i % DATA.cards.length].file, + (id, i) => + varUrl(V[id]) || "assets/carousel-images/" + DATA.cards[i % DATA.cards.length].file, ); DATA.cards = await Promise.all( srcs.map(async (src, i) => { diff --git a/registry/blocks/carousel-circle-4/carousel-circle-4.html b/registry/blocks/carousel-circle-4/carousel-circle-4.html index 47af0c728d..1486f6d017 100644 --- a/registry/blocks/carousel-circle-4/carousel-circle-4.html +++ b/registry/blocks/carousel-circle-4/carousel-circle-4.html @@ -628,7 +628,8 @@ const varUrl = (v) => (v && typeof v === "object" ? v.url || v.src || "" : v || ""); if (REG) { const srcs = REG.imageVars.map( - (id, i) => varUrl(V[id]) || DATA.cards[i % DATA.cards.length].file, + (id, i) => + varUrl(V[id]) || "assets/carousel-images/" + DATA.cards[i % DATA.cards.length].file, ); DATA.cards = await Promise.all( srcs.map(async (src, i) => { diff --git a/registry/blocks/carousel-circle-5/carousel-circle-5.html b/registry/blocks/carousel-circle-5/carousel-circle-5.html index 718aba5518..3e3e826f5b 100644 --- a/registry/blocks/carousel-circle-5/carousel-circle-5.html +++ b/registry/blocks/carousel-circle-5/carousel-circle-5.html @@ -628,7 +628,8 @@ const varUrl = (v) => (v && typeof v === "object" ? v.url || v.src || "" : v || ""); if (REG) { const srcs = REG.imageVars.map( - (id, i) => varUrl(V[id]) || DATA.cards[i % DATA.cards.length].file, + (id, i) => + varUrl(V[id]) || "assets/carousel-images/" + DATA.cards[i % DATA.cards.length].file, ); DATA.cards = await Promise.all( srcs.map(async (src, i) => { diff --git a/registry/blocks/carousel-orbit-1/carousel-orbit-1.html b/registry/blocks/carousel-orbit-1/carousel-orbit-1.html index 9d2ca52c78..fdd1f3dedf 100644 --- a/registry/blocks/carousel-orbit-1/carousel-orbit-1.html +++ b/registry/blocks/carousel-orbit-1/carousel-orbit-1.html @@ -650,7 +650,8 @@ const varUrl = (v) => (v && typeof v === "object" ? v.url || v.src || "" : v || ""); if (REG) { const srcs = REG.imageVars.map( - (id, i) => varUrl(V[id]) || DATA.cards[i % DATA.cards.length].file, + (id, i) => + varUrl(V[id]) || "assets/carousel-images/" + DATA.cards[i % DATA.cards.length].file, ); DATA.cards = await Promise.all( srcs.map(async (src, i) => { diff --git a/registry/blocks/carousel-orbit-2/carousel-orbit-2.html b/registry/blocks/carousel-orbit-2/carousel-orbit-2.html index 61d80eb386..99a9019af0 100644 --- a/registry/blocks/carousel-orbit-2/carousel-orbit-2.html +++ b/registry/blocks/carousel-orbit-2/carousel-orbit-2.html @@ -650,7 +650,8 @@ const varUrl = (v) => (v && typeof v === "object" ? v.url || v.src || "" : v || ""); if (REG) { const srcs = REG.imageVars.map( - (id, i) => varUrl(V[id]) || DATA.cards[i % DATA.cards.length].file, + (id, i) => + varUrl(V[id]) || "assets/carousel-images/" + DATA.cards[i % DATA.cards.length].file, ); DATA.cards = await Promise.all( srcs.map(async (src, i) => { diff --git a/registry/blocks/carousel-orbit-3/carousel-orbit-3.html b/registry/blocks/carousel-orbit-3/carousel-orbit-3.html index 257bf717b3..c07cb23073 100644 --- a/registry/blocks/carousel-orbit-3/carousel-orbit-3.html +++ b/registry/blocks/carousel-orbit-3/carousel-orbit-3.html @@ -650,7 +650,8 @@ const varUrl = (v) => (v && typeof v === "object" ? v.url || v.src || "" : v || ""); if (REG) { const srcs = REG.imageVars.map( - (id, i) => varUrl(V[id]) || DATA.cards[i % DATA.cards.length].file, + (id, i) => + varUrl(V[id]) || "assets/carousel-images/" + DATA.cards[i % DATA.cards.length].file, ); DATA.cards = await Promise.all( srcs.map(async (src, i) => { diff --git a/registry/blocks/carousel-orbit-4/carousel-orbit-4.html b/registry/blocks/carousel-orbit-4/carousel-orbit-4.html index e529a037a7..d1cfeeac9f 100644 --- a/registry/blocks/carousel-orbit-4/carousel-orbit-4.html +++ b/registry/blocks/carousel-orbit-4/carousel-orbit-4.html @@ -666,7 +666,8 @@ const varUrl = (v) => (v && typeof v === "object" ? v.url || v.src || "" : v || ""); if (REG) { const srcs = REG.imageVars.map( - (id, i) => varUrl(V[id]) || DATA.cards[i % DATA.cards.length].file, + (id, i) => + varUrl(V[id]) || "assets/carousel-images/" + DATA.cards[i % DATA.cards.length].file, ); DATA.cards = await Promise.all( srcs.map(async (src, i) => { diff --git a/registry/blocks/carousel-orbit-5/carousel-orbit-5.html b/registry/blocks/carousel-orbit-5/carousel-orbit-5.html index ca047c5157..c9a1706de8 100644 --- a/registry/blocks/carousel-orbit-5/carousel-orbit-5.html +++ b/registry/blocks/carousel-orbit-5/carousel-orbit-5.html @@ -650,7 +650,8 @@ const varUrl = (v) => (v && typeof v === "object" ? v.url || v.src || "" : v || ""); if (REG) { const srcs = REG.imageVars.map( - (id, i) => varUrl(V[id]) || DATA.cards[i % DATA.cards.length].file, + (id, i) => + varUrl(V[id]) || "assets/carousel-images/" + DATA.cards[i % DATA.cards.length].file, ); DATA.cards = await Promise.all( srcs.map(async (src, i) => { diff --git a/registry/blocks/carousel-path-1/carousel-path-1.html b/registry/blocks/carousel-path-1/carousel-path-1.html index 6774c4209e..6470f31baa 100644 --- a/registry/blocks/carousel-path-1/carousel-path-1.html +++ b/registry/blocks/carousel-path-1/carousel-path-1.html @@ -672,7 +672,8 @@ const varUrl = (v) => (v && typeof v === "object" ? v.url || v.src || "" : v || ""); if (REG) { const srcs = REG.imageVars.map( - (id, i) => varUrl(V[id]) || DATA.cards[i % DATA.cards.length].file, + (id, i) => + varUrl(V[id]) || "assets/carousel-images/" + DATA.cards[i % DATA.cards.length].file, ); DATA.cards = await Promise.all( srcs.map(async (src, i) => { diff --git a/registry/blocks/carousel-path-2/carousel-path-2.html b/registry/blocks/carousel-path-2/carousel-path-2.html index 417bcd8904..dff6db7621 100644 --- a/registry/blocks/carousel-path-2/carousel-path-2.html +++ b/registry/blocks/carousel-path-2/carousel-path-2.html @@ -629,7 +629,8 @@ const varUrl = (v) => (v && typeof v === "object" ? v.url || v.src || "" : v || ""); if (REG) { const srcs = REG.imageVars.map( - (id, i) => varUrl(V[id]) || DATA.cards[i % DATA.cards.length].file, + (id, i) => + varUrl(V[id]) || "assets/carousel-images/" + DATA.cards[i % DATA.cards.length].file, ); DATA.cards = await Promise.all( srcs.map(async (src, i) => { diff --git a/registry/blocks/carousel-path-3/carousel-path-3.html b/registry/blocks/carousel-path-3/carousel-path-3.html index 5dd866b7ca..781ba59627 100644 --- a/registry/blocks/carousel-path-3/carousel-path-3.html +++ b/registry/blocks/carousel-path-3/carousel-path-3.html @@ -643,7 +643,8 @@ const varUrl = (v) => (v && typeof v === "object" ? v.url || v.src || "" : v || ""); if (REG) { const srcs = REG.imageVars.map( - (id, i) => varUrl(V[id]) || DATA.cards[i % DATA.cards.length].file, + (id, i) => + varUrl(V[id]) || "assets/carousel-images/" + DATA.cards[i % DATA.cards.length].file, ); DATA.cards = await Promise.all( srcs.map(async (src, i) => { diff --git a/registry/blocks/carousel-path-4/carousel-path-4.html b/registry/blocks/carousel-path-4/carousel-path-4.html index b75a769378..bcfc20d73c 100644 --- a/registry/blocks/carousel-path-4/carousel-path-4.html +++ b/registry/blocks/carousel-path-4/carousel-path-4.html @@ -672,7 +672,8 @@ const varUrl = (v) => (v && typeof v === "object" ? v.url || v.src || "" : v || ""); if (REG) { const srcs = REG.imageVars.map( - (id, i) => varUrl(V[id]) || DATA.cards[i % DATA.cards.length].file, + (id, i) => + varUrl(V[id]) || "assets/carousel-images/" + DATA.cards[i % DATA.cards.length].file, ); DATA.cards = await Promise.all( srcs.map(async (src, i) => { diff --git a/registry/blocks/carousel-path-5/carousel-path-5.html b/registry/blocks/carousel-path-5/carousel-path-5.html index 32390f07b2..e173a4e77d 100644 --- a/registry/blocks/carousel-path-5/carousel-path-5.html +++ b/registry/blocks/carousel-path-5/carousel-path-5.html @@ -671,7 +671,8 @@ const varUrl = (v) => (v && typeof v === "object" ? v.url || v.src || "" : v || ""); if (REG) { const srcs = REG.imageVars.map( - (id, i) => varUrl(V[id]) || DATA.cards[i % DATA.cards.length].file, + (id, i) => + varUrl(V[id]) || "assets/carousel-images/" + DATA.cards[i % DATA.cards.length].file, ); DATA.cards = await Promise.all( srcs.map(async (src, i) => { diff --git a/registry/blocks/carousel-text-circle-1/carousel-text-circle-1.html b/registry/blocks/carousel-text-circle-1/carousel-text-circle-1.html index 34ffb7a9c9..4b5e22f227 100644 --- a/registry/blocks/carousel-text-circle-1/carousel-text-circle-1.html +++ b/registry/blocks/carousel-text-circle-1/carousel-text-circle-1.html @@ -669,7 +669,8 @@ const varUrl = (v) => (v && typeof v === "object" ? v.url || v.src || "" : v || ""); if (REG) { const srcs = REG.imageVars.map( - (id, i) => varUrl(V[id]) || DATA.cards[i % DATA.cards.length].file, + (id, i) => + varUrl(V[id]) || "assets/carousel-images/" + DATA.cards[i % DATA.cards.length].file, ); DATA.cards = await Promise.all( srcs.map(async (src, i) => { diff --git a/registry/blocks/carousel-text-circle-2/carousel-text-circle-2.html b/registry/blocks/carousel-text-circle-2/carousel-text-circle-2.html index 901771fbfe..6378e8334f 100644 --- a/registry/blocks/carousel-text-circle-2/carousel-text-circle-2.html +++ b/registry/blocks/carousel-text-circle-2/carousel-text-circle-2.html @@ -669,7 +669,8 @@ const varUrl = (v) => (v && typeof v === "object" ? v.url || v.src || "" : v || ""); if (REG) { const srcs = REG.imageVars.map( - (id, i) => varUrl(V[id]) || DATA.cards[i % DATA.cards.length].file, + (id, i) => + varUrl(V[id]) || "assets/carousel-images/" + DATA.cards[i % DATA.cards.length].file, ); DATA.cards = await Promise.all( srcs.map(async (src, i) => { diff --git a/registry/blocks/carousel-text-circle-3/carousel-text-circle-3.html b/registry/blocks/carousel-text-circle-3/carousel-text-circle-3.html index 12450db1e6..aa5434cdee 100644 --- a/registry/blocks/carousel-text-circle-3/carousel-text-circle-3.html +++ b/registry/blocks/carousel-text-circle-3/carousel-text-circle-3.html @@ -669,7 +669,8 @@ const varUrl = (v) => (v && typeof v === "object" ? v.url || v.src || "" : v || ""); if (REG) { const srcs = REG.imageVars.map( - (id, i) => varUrl(V[id]) || DATA.cards[i % DATA.cards.length].file, + (id, i) => + varUrl(V[id]) || "assets/carousel-images/" + DATA.cards[i % DATA.cards.length].file, ); DATA.cards = await Promise.all( srcs.map(async (src, i) => { diff --git a/registry/blocks/carousel-text-circle-4/carousel-text-circle-4.html b/registry/blocks/carousel-text-circle-4/carousel-text-circle-4.html index 8b07b94d9e..d6fa6f74cc 100644 --- a/registry/blocks/carousel-text-circle-4/carousel-text-circle-4.html +++ b/registry/blocks/carousel-text-circle-4/carousel-text-circle-4.html @@ -669,7 +669,8 @@ const varUrl = (v) => (v && typeof v === "object" ? v.url || v.src || "" : v || ""); if (REG) { const srcs = REG.imageVars.map( - (id, i) => varUrl(V[id]) || DATA.cards[i % DATA.cards.length].file, + (id, i) => + varUrl(V[id]) || "assets/carousel-images/" + DATA.cards[i % DATA.cards.length].file, ); DATA.cards = await Promise.all( srcs.map(async (src, i) => { diff --git a/registry/blocks/carousel-text-circle-5/carousel-text-circle-5.html b/registry/blocks/carousel-text-circle-5/carousel-text-circle-5.html index 00e584b5c2..e7ed9d668d 100644 --- a/registry/blocks/carousel-text-circle-5/carousel-text-circle-5.html +++ b/registry/blocks/carousel-text-circle-5/carousel-text-circle-5.html @@ -669,7 +669,8 @@ const varUrl = (v) => (v && typeof v === "object" ? v.url || v.src || "" : v || ""); if (REG) { const srcs = REG.imageVars.map( - (id, i) => varUrl(V[id]) || DATA.cards[i % DATA.cards.length].file, + (id, i) => + varUrl(V[id]) || "assets/carousel-images/" + DATA.cards[i % DATA.cards.length].file, ); DATA.cards = await Promise.all( srcs.map(async (src, i) => { diff --git a/registry/blocks/carousel-vision-1/carousel-vision-1.html b/registry/blocks/carousel-vision-1/carousel-vision-1.html index e71d8a39ae..33334d2f03 100644 --- a/registry/blocks/carousel-vision-1/carousel-vision-1.html +++ b/registry/blocks/carousel-vision-1/carousel-vision-1.html @@ -632,7 +632,8 @@ const varUrl = (v) => (v && typeof v === "object" ? v.url || v.src || "" : v || ""); if (REG) { const srcs = REG.imageVars.map( - (id, i) => varUrl(V[id]) || DATA.cards[i % DATA.cards.length].file, + (id, i) => + varUrl(V[id]) || "assets/carousel-images/" + DATA.cards[i % DATA.cards.length].file, ); DATA.cards = await Promise.all( srcs.map(async (src, i) => { diff --git a/registry/blocks/carousel-vision-2/carousel-vision-2.html b/registry/blocks/carousel-vision-2/carousel-vision-2.html index edfc82bdff..e71cd9629f 100644 --- a/registry/blocks/carousel-vision-2/carousel-vision-2.html +++ b/registry/blocks/carousel-vision-2/carousel-vision-2.html @@ -632,7 +632,8 @@ const varUrl = (v) => (v && typeof v === "object" ? v.url || v.src || "" : v || ""); if (REG) { const srcs = REG.imageVars.map( - (id, i) => varUrl(V[id]) || DATA.cards[i % DATA.cards.length].file, + (id, i) => + varUrl(V[id]) || "assets/carousel-images/" + DATA.cards[i % DATA.cards.length].file, ); DATA.cards = await Promise.all( srcs.map(async (src, i) => { diff --git a/registry/blocks/carousel-vision-3/carousel-vision-3.html b/registry/blocks/carousel-vision-3/carousel-vision-3.html index 5c46502124..e9d0e27dfe 100644 --- a/registry/blocks/carousel-vision-3/carousel-vision-3.html +++ b/registry/blocks/carousel-vision-3/carousel-vision-3.html @@ -632,7 +632,8 @@ const varUrl = (v) => (v && typeof v === "object" ? v.url || v.src || "" : v || ""); if (REG) { const srcs = REG.imageVars.map( - (id, i) => varUrl(V[id]) || DATA.cards[i % DATA.cards.length].file, + (id, i) => + varUrl(V[id]) || "assets/carousel-images/" + DATA.cards[i % DATA.cards.length].file, ); DATA.cards = await Promise.all( srcs.map(async (src, i) => { diff --git a/registry/blocks/carousel-vision-4/carousel-vision-4.html b/registry/blocks/carousel-vision-4/carousel-vision-4.html index 633480a496..9f101318df 100644 --- a/registry/blocks/carousel-vision-4/carousel-vision-4.html +++ b/registry/blocks/carousel-vision-4/carousel-vision-4.html @@ -639,7 +639,8 @@ const varUrl = (v) => (v && typeof v === "object" ? v.url || v.src || "" : v || ""); if (REG) { const srcs = REG.imageVars.map( - (id, i) => varUrl(V[id]) || DATA.cards[i % DATA.cards.length].file, + (id, i) => + varUrl(V[id]) || "assets/carousel-images/" + DATA.cards[i % DATA.cards.length].file, ); DATA.cards = await Promise.all( srcs.map(async (src, i) => { diff --git a/registry/blocks/carousel-vision-5/carousel-vision-5.html b/registry/blocks/carousel-vision-5/carousel-vision-5.html index ea02154c60..a58968f501 100644 --- a/registry/blocks/carousel-vision-5/carousel-vision-5.html +++ b/registry/blocks/carousel-vision-5/carousel-vision-5.html @@ -632,7 +632,8 @@ const varUrl = (v) => (v && typeof v === "object" ? v.url || v.src || "" : v || ""); if (REG) { const srcs = REG.imageVars.map( - (id, i) => varUrl(V[id]) || DATA.cards[i % DATA.cards.length].file, + (id, i) => + varUrl(V[id]) || "assets/carousel-images/" + DATA.cards[i % DATA.cards.length].file, ); DATA.cards = await Promise.all( srcs.map(async (src, i) => { diff --git a/scripts/catalog/carousel-fallback.test.ts b/scripts/catalog/carousel-fallback.test.ts new file mode 100644 index 0000000000..71a0129216 --- /dev/null +++ b/scripts/catalog/carousel-fallback.test.ts @@ -0,0 +1,34 @@ +import { describe, expect, it } from "vitest"; +import { readdirSync, readFileSync } from "node:fs"; +import { join } from "node:path"; + +const blocksDir = join(import.meta.dirname, "..", "..", "registry", "blocks"); + +// The carousels draw each card from its image variable, or from the block's own +// sample image when the variable resolves to nothing. +const FALLBACK = /varUrl\(V\[id\]\)\s*\|\|\s*([^\n]*)DATA\.cards\[i % DATA\.cards\.length\]\.file/g; + +function carousels(): Array<{ block: string; prefixes: string[] }> { + return readdirSync(blocksDir, { withFileTypes: true }) + .filter((entry) => entry.isDirectory()) + .map(({ name }) => ({ + block: name, + html: readFileSync(join(blocksDir, name, `${name}.html`), "utf8"), + })) + .filter(({ html }) => html.includes("varUrl(V[id])")) + .map(({ block, html }) => ({ + block, + prefixes: [...html.matchAll(FALLBACK)].map((match) => match[1] ?? ""), + })); +} + +describe("carousel image fallback", () => { + it("loads the sample image from the block's assets folder, not a bare file name", () => { + const found = carousels(); + expect(found.length).toBeGreaterThan(0); + for (const { block, prefixes } of found) { + expect(prefixes.length, block).toBeGreaterThan(0); + for (const prefix of prefixes) expect(prefix, block).toContain('"assets/carousel-images/" +'); + } + }); +});