@vizejs/vite-plugin-musea 0.291.0 → 0.303.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -637,6 +637,19 @@ function __museaInitAddons(container, variantName, extraCaptureEvents = []) {
637
637
  script.onerror = reject;
638
638
  document.head.appendChild(script);
639
639
  });
640
+ // A load event is not proof the vendor script exists. axe-core is
641
+ // an optional peer, so a static export can ship without it, and a
642
+ // static host is free to answer the missing asset with an SPA
643
+ // fallback: 200 plus HTML. The script tag then "loads" fine and
644
+ // window.axe is still undefined, which surfaced downstream as an
645
+ // opaque "cannot read properties of undefined" instead of the real
646
+ // cause.
647
+ if (!window.axe) {
648
+ throw new Error(
649
+ 'axe-core did not load from ' + script.src +
650
+ ' - install axe-core so the gallery can ship it, and check that the path is served as JavaScript rather than an SPA fallback'
651
+ );
652
+ }
640
653
  }
641
654
  // Run axe-core on the .musea-variant container only (not the full document)
642
655
  const context = document.querySelector('.musea-variant') || document;
@@ -2913,19 +2926,6 @@ async function handleArtDocs(ctx, match, sendJson, sendError) {
2913
2926
  }
2914
2927
  }
2915
2928
  /** GET /api/arts/:path/variants/:name/a11y */
2916
- function handleArtA11y(ctx, match, sendJson, sendError) {
2917
- const artPath = decodeUrlComponent(match[1], "art path");
2918
- decodeUrlComponent(match[2], "variant name");
2919
- if (!ctx.artFiles.get(artPath)) {
2920
- sendError("Art not found", 404);
2921
- return;
2922
- }
2923
- sendJson({
2924
- violations: [],
2925
- passes: 0,
2926
- incomplete: 0
2927
- });
2928
- }
2929
2929
  //#endregion
2930
2930
  //#region src/api-routes/post-handlers.ts
2931
2931
  /** POST /api/preview-with-props */
@@ -3116,7 +3116,6 @@ function createApiMiddleware(ctx) {
3116
3116
  const paletteMatch = rest.match(/^(.+)\/palette$/);
3117
3117
  const analysisMatch = rest.match(/^(.+)\/analysis$/);
3118
3118
  const docsMatch = rest.match(/^(.+)\/docs$/);
3119
- const a11yMatch = rest.match(/^(.+)\/variants\/([^/]+)\/a11y$/);
3120
3119
  if (sourceMatch) {
3121
3120
  await handleArtSource(ctx, sourceMatch, sendJson, sendError);
3122
3121
  return;
@@ -3133,10 +3132,6 @@ function createApiMiddleware(ctx) {
3133
3132
  await handleArtDocs(ctx, docsMatch, sendJson, sendError);
3134
3133
  return;
3135
3134
  }
3136
- if (a11yMatch) {
3137
- handleArtA11y(ctx, a11yMatch, sendJson, sendError);
3138
- return;
3139
- }
3140
3135
  const artPath = decodeUrlComponent(rest, "art path");
3141
3136
  const art = ctx.artFiles.get(artPath);
3142
3137
  if (art) sendJson(art);
@@ -3364,13 +3359,9 @@ async function createStaticGalleryPayload(ctx) {
3364
3359
  const details = {};
3365
3360
  for (const art of arts) {
3366
3361
  previews[art.path] = {};
3367
- const a11y = {};
3368
3362
  for (const variant of art.variants) {
3369
3363
  const id = staticPreviewId(art.path, variant.name);
3370
3364
  previews[art.path][variant.name] = joinUrlPath(ctx.basePath, "preview", `${id}.html`);
3371
- a11y[variant.name] = await captureJson((sendJson, sendError) => {
3372
- handleArtA11y(apiCtx, artVariantMatch(art.path, variant.name), sendJson, sendError);
3373
- }, emptyA11y());
3374
3365
  }
3375
3366
  details[art.path] = {
3376
3367
  source: await captureJson((sendJson, sendError) => {
@@ -3390,8 +3381,7 @@ async function createStaticGalleryPayload(ctx) {
3390
3381
  }),
3391
3382
  docs: await captureJson((sendJson, sendError) => {
3392
3383
  return handleArtDocs(apiCtx, artMatch(art.path), sendJson, sendError);
3393
- }, emptyDocs(art)),
3394
- a11y
3384
+ }, emptyDocs(art))
3395
3385
  };
3396
3386
  }
3397
3387
  return {
@@ -3436,13 +3426,6 @@ async function captureJson(run, fallback) {
3436
3426
  function artMatch(artPath) {
3437
3427
  return ["", encodeURIComponent(artPath)];
3438
3428
  }
3439
- function artVariantMatch(artPath, variantName) {
3440
- return [
3441
- "",
3442
- encodeURIComponent(artPath),
3443
- encodeURIComponent(variantName)
3444
- ];
3445
- }
3446
3429
  function emptyPalette(art) {
3447
3430
  return {
3448
3431
  title: art.metadata.title,
@@ -3459,13 +3442,6 @@ function emptyDocs(art) {
3459
3442
  variant_count: art.variants.length
3460
3443
  };
3461
3444
  }
3462
- function emptyA11y() {
3463
- return {
3464
- violations: [],
3465
- passes: 0,
3466
- incomplete: 0
3467
- };
3468
- }
3469
3445
  function emptyTokens() {
3470
3446
  return {
3471
3447
  categories: [],
@@ -3492,13 +3468,82 @@ function publicBasePathFromViteBase(viteBase, basePath) {
3492
3468
  return viteBase && viteBase !== "/" && viteBase !== "./" ? joinUrlPath(viteBase, basePath) : basePath;
3493
3469
  }
3494
3470
  //#endregion
3471
+ //#region src/static-gallery-shell.ts
3472
+ const moduleDir = path.dirname(fileURLToPath(import.meta.url));
3473
+ function joinFileName(...parts) {
3474
+ return parts.filter(Boolean).join("/");
3475
+ }
3476
+ async function emitGalleryShell(emitFile, staticRoot, ctx, payload, galleryDistDir = resolveGalleryDistDir()) {
3477
+ if (!galleryDistDir) {
3478
+ const html = injectStaticGlobals(generateStaticFallbackGalleryHtml(ctx.basePath), ctx, payload);
3479
+ emitFile({
3480
+ type: "asset",
3481
+ fileName: joinFileName(staticRoot, "index.html"),
3482
+ source: html
3483
+ });
3484
+ return;
3485
+ }
3486
+ for (const filePath of await collectFiles(galleryDistDir)) {
3487
+ const relative = path.relative(galleryDistDir, filePath).split(path.sep).join("/");
3488
+ const target = joinFileName(staticRoot, relative);
3489
+ const content = await fs.promises.readFile(filePath);
3490
+ if (relative === "index.html") emitFile({
3491
+ type: "asset",
3492
+ fileName: target,
3493
+ source: injectStaticGlobals(rewriteGalleryBase(content.toString("utf-8"), ctx.basePath), ctx, payload)
3494
+ });
3495
+ else emitFile({
3496
+ type: "asset",
3497
+ fileName: target,
3498
+ source: rewriteGalleryTextAssetBase(content, relative, ctx.basePath)
3499
+ });
3500
+ }
3501
+ }
3502
+ function injectStaticGlobals(html, ctx, payload) {
3503
+ const script = `<script>${generateGalleryGlobalsScript({
3504
+ basePath: ctx.basePath,
3505
+ staticPreviews: payload.previews,
3506
+ themeConfig: ctx.themeConfig,
3507
+ tokenPreviewConfig: ctx.tokenPreviewConfig
3508
+ })}<\/script>`;
3509
+ return html.includes("</head>") ? html.replace("</head>", `${script}</head>`) : `${script}${html}`;
3510
+ }
3511
+ function generateStaticFallbackGalleryHtml(basePath) {
3512
+ return `<!DOCTYPE html>
3513
+ <html lang="en">
3514
+ <head>
3515
+ <meta charset="UTF-8">
3516
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
3517
+ <title>Musea - Component Gallery</title>
3518
+ <style>html,body{min-height:100%;margin:0}body{font-family:system-ui,sans-serif}</style>
3519
+ </head>
3520
+ <body>${generateGalleryBody(basePath)}
3521
+
3522
+ <script type="module">${generateGalleryScript(basePath)}
3523
+ <\/script>
3524
+ </body>
3525
+ </html>`;
3526
+ }
3527
+ function resolveGalleryDistDir() {
3528
+ return [path.join(moduleDir, "gallery"), path.resolve(moduleDir, "../dist/gallery")].find((candidate) => fs.existsSync(path.join(candidate, "index.html"))) ?? null;
3529
+ }
3530
+ async function collectFiles(dir) {
3531
+ const entries = await fs.promises.readdir(dir, { withFileTypes: true });
3532
+ const files = [];
3533
+ for (const entry of entries) {
3534
+ const filePath = path.join(dir, entry.name);
3535
+ if (entry.isDirectory()) files.push(...await collectFiles(filePath));
3536
+ else files.push(filePath);
3537
+ }
3538
+ return files;
3539
+ }
3540
+ //#endregion
3495
3541
  //#region src/static-export.ts
3496
3542
  const MUSEA_STATIC_BUILD_ENV = "VIZE_MUSEA_STATIC_BUILD";
3497
3543
  const VIRTUAL_STATIC_RUNTIME = "virtual:musea-static-runtime";
3498
3544
  const RESOLVED_STATIC_RUNTIME = "\0musea-static-runtime";
3499
3545
  const STATIC_RUNTIME_INPUT_NAME = "musea-static-runtime";
3500
3546
  const STATIC_USER_INPUT_NAME = "musea-static-entry";
3501
- const moduleDir = path.dirname(fileURLToPath(import.meta.url));
3502
3547
  function isMuseaStaticBuild() {
3503
3548
  return process.env[MUSEA_STATIC_BUILD_ENV] === "1";
3504
3549
  }
@@ -3579,49 +3624,6 @@ function findRuntimeFileName(bundle) {
3579
3624
  for (const item of Object.values(bundle)) if (item.type === "chunk" && item.name === "musea-static-runtime") return item.fileName;
3580
3625
  return null;
3581
3626
  }
3582
- async function emitGalleryShell(emitFile, staticRoot, ctx, payload) {
3583
- const galleryDir = resolveGalleryDistDir();
3584
- if (!galleryDir) {
3585
- const html = injectStaticGlobals(generateStaticFallbackGalleryHtml(ctx.basePath), ctx, payload);
3586
- emitFile({
3587
- type: "asset",
3588
- fileName: joinFileName(staticRoot, "index.html"),
3589
- source: html
3590
- });
3591
- return;
3592
- }
3593
- for (const filePath of await collectFiles(galleryDir)) {
3594
- const relative = path.relative(galleryDir, filePath).split(path.sep).join("/");
3595
- const target = joinFileName(staticRoot, relative);
3596
- const content = await fs.promises.readFile(filePath);
3597
- if (relative === "index.html") emitFile({
3598
- type: "asset",
3599
- fileName: target,
3600
- source: rewriteGalleryBase(injectStaticGlobals(content.toString("utf-8"), ctx, payload), ctx.basePath)
3601
- });
3602
- else emitFile({
3603
- type: "asset",
3604
- fileName: target,
3605
- source: rewriteGalleryTextAssetBase(content, relative, ctx.basePath)
3606
- });
3607
- }
3608
- }
3609
- function generateStaticFallbackGalleryHtml(basePath) {
3610
- return `<!DOCTYPE html>
3611
- <html lang="en">
3612
- <head>
3613
- <meta charset="UTF-8">
3614
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
3615
- <title>Musea - Component Gallery</title>
3616
- <style>html,body{min-height:100%;margin:0}body{font-family:system-ui,sans-serif}</style>
3617
- </head>
3618
- <body>${generateGalleryBody(basePath)}
3619
-
3620
- <script type="module">${generateGalleryScript(basePath)}
3621
- <\/script>
3622
- </body>
3623
- </html>`;
3624
- }
3625
3627
  function emitPreviewHtml(emitFile, staticRoot, runtimeFileName, basePath, artFiles) {
3626
3628
  const previewDir = joinFileName(staticRoot, "preview");
3627
3629
  const runtimeUrl = relativeUrl(previewDir, runtimeFileName);
@@ -3665,15 +3667,6 @@ function generateStaticPreviewHtml(art, variantName, previewId, basePath, runtim
3665
3667
  </body>
3666
3668
  </html>`;
3667
3669
  }
3668
- function injectStaticGlobals(html, ctx, payload) {
3669
- const script = `<script>${generateGalleryGlobalsScript({
3670
- basePath: ctx.basePath,
3671
- staticPreviews: payload.previews,
3672
- themeConfig: ctx.themeConfig,
3673
- tokenPreviewConfig: ctx.tokenPreviewConfig
3674
- })}<\/script>`;
3675
- return html.includes("</head>") ? html.replace("</head>", `${script}</head>`) : `${script}${html}`;
3676
- }
3677
3670
  function emitRootRedirect(emitFile, staticRoot, basePath) {
3678
3671
  if (!staticRoot) return;
3679
3672
  const target = joinUrlPath(basePath, "");
@@ -3692,27 +3685,13 @@ async function emitAxeVendor(emitFile, staticRoot) {
3692
3685
  fileName: joinFileName(staticRoot, "vendor/axe-core.min.js"),
3693
3686
  source
3694
3687
  });
3695
- } catch {}
3696
- }
3697
- function resolveGalleryDistDir() {
3698
- return [path.join(moduleDir, "gallery"), path.resolve(moduleDir, "../dist/gallery")].find((candidate) => fs.existsSync(path.join(candidate, "index.html"))) ?? null;
3699
- }
3700
- async function collectFiles(dir) {
3701
- const entries = await fs.promises.readdir(dir, { withFileTypes: true });
3702
- const files = [];
3703
- for (const entry of entries) {
3704
- const filePath = path.join(dir, entry.name);
3705
- if (entry.isDirectory()) files.push(...await collectFiles(filePath));
3706
- else files.push(filePath);
3688
+ } catch {
3689
+ console.warn("[musea] axe-core is not installed, so the exported gallery cannot run accessibility checks.\n Install it to enable the A11y panel in the static build: vp install -D axe-core");
3707
3690
  }
3708
- return files;
3709
3691
  }
3710
3692
  function staticRootFromBasePath(basePath) {
3711
3693
  return basePath.replace(/^\/+|\/+$/g, "");
3712
3694
  }
3713
- function joinFileName(...parts) {
3714
- return parts.filter(Boolean).join("/");
3715
- }
3716
3695
  function relativeUrl(fromDir, toFile) {
3717
3696
  const relative = path.posix.relative(fromDir || ".", toFile);
3718
3697
  return relative.startsWith(".") ? relative : `./${relative}`;