@vizejs/vite-plugin-musea 0.77.0 → 0.81.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.
Files changed (62) hide show
  1. package/dist/a11y-DNCg2qCB.mjs.map +1 -1
  2. package/dist/autogen-3-y1d0ou.mjs.map +1 -1
  3. package/dist/cli/index.mjs.map +1 -1
  4. package/dist/gallery/assets/{MonacoEditor-TuCyx-Gp.js → MonacoEditor-BAL3w4pf.js} +2 -2
  5. package/dist/gallery/assets/codicon-ngg6Pgfi.ttf +0 -0
  6. package/dist/gallery/assets/{css.worker-BXrDisZh.js → css.worker-Wv5dxAWO.js} +43 -42
  7. package/dist/gallery/assets/cssMode-DTjSpNAL.js +1 -0
  8. package/dist/gallery/assets/editor-BnkT-hT5.css +1 -0
  9. package/dist/gallery/assets/editor.api2-CIEJpqKT.js +872 -0
  10. package/dist/gallery/assets/editor.main-DU-sPy-k.js +6 -0
  11. package/dist/gallery/assets/editor.worker-Bd9IXS8d.js +26 -0
  12. package/dist/gallery/assets/freemarker2-DZuwWwqM.js +3 -0
  13. package/dist/gallery/assets/handlebars-C6CWcO31.js +1 -0
  14. package/dist/gallery/assets/html-DTPfnMqY.js +1 -0
  15. package/dist/gallery/assets/html.worker-CQP8QQsS.js +502 -0
  16. package/dist/gallery/assets/htmlMode-DmLB9Bik.js +1 -0
  17. package/dist/gallery/assets/index-DjSpyxD0.js +68 -0
  18. package/dist/gallery/assets/{javascript-Qm0EF72X.js → javascript-dFy7cqCx.js} +1 -1
  19. package/dist/gallery/assets/json.worker-DzV-CpCQ.js +58 -0
  20. package/dist/gallery/assets/jsonMode-Bge74JBI.js +7 -0
  21. package/dist/gallery/assets/{kotlin-C7EpOAJu.js → kotlin-DemwFMfK.js} +1 -1
  22. package/dist/gallery/assets/liquid-H5lVD6p3.js +1 -0
  23. package/dist/gallery/assets/lspLanguageFeatures-CkkzJ5B0.js +4 -0
  24. package/dist/gallery/assets/mdx-DuMAerqf.js +1 -0
  25. package/dist/gallery/assets/monaco.contribution-Cn9RKjKZ.js +2 -0
  26. package/dist/gallery/assets/python-BqM-0Ttj.js +1 -0
  27. package/dist/gallery/assets/razor-BDNVe10U.js +1 -0
  28. package/dist/gallery/assets/ts.worker-METxwbDZ.js +67719 -0
  29. package/dist/gallery/assets/tsMode-uoOez2iL.js +11 -0
  30. package/dist/gallery/assets/typescript-DI6pcvqw.js +1 -0
  31. package/dist/gallery/assets/workers-DS42og38.js +1 -0
  32. package/dist/gallery/assets/xml-ChP0eqUe.js +1 -0
  33. package/dist/gallery/assets/yaml-DCdtNHC4.js +1 -0
  34. package/dist/gallery/index.html +1 -1
  35. package/dist/index.mjs.map +1 -1
  36. package/dist/vrt-CjFf5GR0.mjs.map +1 -1
  37. package/package.json +12 -12
  38. package/dist/gallery/assets/codicon-DCmgc-ay.ttf +0 -0
  39. package/dist/gallery/assets/cssMode-C5ElWrKz.js +0 -4
  40. package/dist/gallery/assets/editor-B55U_qvj.css +0 -1
  41. package/dist/gallery/assets/editor-F8AxQWwE.css +0 -1
  42. package/dist/gallery/assets/editor.api-Dg4HiaTn.js +0 -644
  43. package/dist/gallery/assets/editor.main-CzTLJrBa.js +0 -63
  44. package/dist/gallery/assets/editor.worker-B0BIIYAR.js +0 -12
  45. package/dist/gallery/assets/freemarker2-c1gKcrCi.js +0 -3
  46. package/dist/gallery/assets/handlebars-Fqfz2stm.js +0 -1
  47. package/dist/gallery/assets/html-C3wpwtqe.js +0 -1
  48. package/dist/gallery/assets/html.worker-_AJvPiQl.js +0 -495
  49. package/dist/gallery/assets/htmlMode-BPlC6qLL.js +0 -4
  50. package/dist/gallery/assets/index-CvbQ61X6.js +0 -63
  51. package/dist/gallery/assets/json.worker-3yqvOk70.js +0 -51
  52. package/dist/gallery/assets/jsonMode-CCq0MXPr.js +0 -10
  53. package/dist/gallery/assets/liquid-CzYkv_Qc.js +0 -1
  54. package/dist/gallery/assets/mdx-xyVg7KoH.js +0 -1
  55. package/dist/gallery/assets/monaco.contribution-CXoI9Pg-.js +0 -2
  56. package/dist/gallery/assets/python-B2WgPXNA.js +0 -1
  57. package/dist/gallery/assets/razor-7GxUKS2u.js +0 -1
  58. package/dist/gallery/assets/ts.worker-B0Jjxwwp.js +0 -51339
  59. package/dist/gallery/assets/tsMode-BrY6umAI.js +0 -11
  60. package/dist/gallery/assets/typescript-Dk29is8D.js +0 -1
  61. package/dist/gallery/assets/xml-DqhaxMt2.js +0 -1
  62. package/dist/gallery/assets/yaml-D4vqVKjP.js +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"a11y-DNCg2qCB.mjs","names":[],"sources":["../src/a11y/report.ts","../src/a11y/index.ts"],"sourcesContent":["/**\n * A11y report generation for Musea.\n *\n * Generates HTML and JSON reports from accessibility audit results,\n * plus summary statistics computation.\n */\n\nimport type { A11yResult } from \"../types/index.js\";\nimport type { A11ySummary } from \"./index.js\";\nimport path from \"node:path\";\n\n/**\n * Compute a11y summary statistics from results.\n */\nexport function computeA11ySummary(results: A11yResult[]): A11ySummary {\n const components = new Set(results.map((r) => r.artPath));\n const allViolations = results.flatMap((r) => r.violations);\n\n return {\n totalComponents: components.size,\n totalVariants: results.length,\n totalViolations: allViolations.length,\n criticalCount: allViolations.filter((v) => v.impact === \"critical\").length,\n seriousCount: allViolations.filter((v) => v.impact === \"serious\").length,\n moderateCount: allViolations.filter((v) => v.impact === \"moderate\").length,\n minorCount: allViolations.filter((v) => v.impact === \"minor\").length,\n };\n}\n\n/**\n * Generate HTML report from a11y results.\n */\nexport function generateA11yHtmlReport(results: A11yResult[], summary: A11ySummary): string {\n const timestamp = new Date().toLocaleString(\"ja-JP\", {\n year: \"numeric\",\n month: \"2-digit\",\n day: \"2-digit\",\n hour: \"2-digit\",\n minute: \"2-digit\",\n });\n\n const impactColor = (impact: string): string => {\n switch (impact) {\n case \"critical\":\n return \"#f87171\";\n case \"serious\":\n return \"#fb923c\";\n case \"moderate\":\n return \"#fbbf24\";\n case \"minor\":\n return \"#60a5fa\";\n default:\n return \"#7b8494\";\n }\n };\n\n const resultItems = results\n .filter((r) => r.violations.length > 0)\n .map((r) => {\n const artName = path.basename(r.artPath, \".art.vue\");\n const violationRows = r.violations\n .map(\n (v) => `\n <tr>\n <td><span style=\"color:${impactColor(v.impact)};font-weight:600;text-transform:uppercase;font-size:0.6875rem\">${escapeHtml(v.impact)}</span></td>\n <td><code>${escapeHtml(v.id)}</code></td>\n <td>${escapeHtml(v.description)}</td>\n <td>${v.nodes}</td>\n <td>${v.helpUrl ? `<a href=\"${escapeHtml(v.helpUrl)}\" target=\"_blank\" style=\"color:#60a5fa\">docs</a>` : \"\"}</td>\n </tr>`,\n )\n .join(\"\");\n\n return `\n <div class=\"result\">\n <div class=\"result-header\">\n <div class=\"result-info\">\n <span class=\"result-name\">${escapeHtml(artName)} / ${escapeHtml(r.variantName)}</span>\n <span class=\"result-count\">${r.violations.length} violation(s)</span>\n </div>\n </div>\n <table class=\"violations-table\">\n <thead><tr><th>Impact</th><th>Rule</th><th>Description</th><th>Nodes</th><th>Help</th></tr></thead>\n <tbody>${violationRows}</tbody>\n </table>\n </div>`;\n })\n .join(\"\");\n\n return `<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n <title>A11y Report - Musea</title>\n <style>\n :root {\n --musea-bg-primary: #0d0d0d;\n --musea-bg-secondary: #1a1815;\n --musea-bg-tertiary: #252220;\n --musea-accent: #a34828;\n --musea-text: #e6e9f0;\n --musea-text-muted: #7b8494;\n --musea-border: #3a3530;\n }\n * { box-sizing: border-box; margin: 0; padding: 0; }\n body {\n font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;\n background: var(--musea-bg-primary);\n color: var(--musea-text);\n min-height: 100vh;\n line-height: 1.5;\n }\n .header {\n background: var(--musea-bg-secondary);\n border-bottom: 1px solid var(--musea-border);\n padding: 1rem 2rem;\n display: flex;\n align-items: center;\n justify-content: space-between;\n }\n .logo { font-size: 1.25rem; font-weight: 700; color: var(--musea-accent); }\n .header-meta { color: var(--musea-text-muted); font-size: 0.8125rem; }\n .main { max-width: 1200px; margin: 0 auto; padding: 2rem; }\n .summary { display: grid; grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); gap: 1rem; margin-bottom: 2rem; }\n .stat { background: var(--musea-bg-secondary); border: 1px solid var(--musea-border); border-radius: 8px; padding: 1rem; text-align: center; }\n .stat-value { font-size: 1.75rem; font-weight: 700; font-variant-numeric: tabular-nums; }\n .stat-label { color: var(--musea-text-muted); font-size: 0.75rem; text-transform: uppercase; letter-spacing: 0.08em; }\n .stat.critical .stat-value { color: #f87171; }\n .stat.serious .stat-value { color: #fb923c; }\n .stat.moderate .stat-value { color: #fbbf24; }\n .stat.minor .stat-value { color: #60a5fa; }\n .stat.total .stat-value { color: var(--musea-text); }\n .results { display: flex; flex-direction: column; gap: 1rem; }\n .result { background: var(--musea-bg-secondary); border: 1px solid var(--musea-border); border-radius: 8px; overflow: hidden; }\n .result-header { padding: 1rem; background: var(--musea-bg-tertiary); display: flex; justify-content: space-between; align-items: center; }\n .result-name { font-weight: 600; }\n .result-count { color: var(--musea-text-muted); font-size: 0.8125rem; }\n .violations-table { width: 100%; border-collapse: collapse; font-size: 0.8125rem; }\n .violations-table th { padding: 0.75rem 1rem; text-align: left; color: var(--musea-text-muted); font-weight: 500; font-size: 0.6875rem; text-transform: uppercase; letter-spacing: 0.08em; border-bottom: 1px solid var(--musea-border); }\n .violations-table td { padding: 0.75rem 1rem; border-bottom: 1px solid var(--musea-border); }\n .violations-table code { background: var(--musea-bg-tertiary); padding: 0.125rem 0.375rem; border-radius: 3px; font-size: 0.75rem; }\n .all-clear { background: rgba(74, 222, 128, 0.1); border: 1px solid rgba(74, 222, 128, 0.2); border-radius: 8px; padding: 2rem; text-align: center; }\n .all-clear-text { color: #4ade80; font-weight: 600; }\n </style>\n</head>\n<body>\n <header class=\"header\">\n <div><span class=\"logo\">Musea</span> <span style=\"color:var(--musea-text-muted);font-size:0.875rem;margin-left:1rem\">Accessibility Report</span></div>\n <div class=\"header-meta\">${timestamp}</div>\n </header>\n <main class=\"main\">\n <div class=\"summary\">\n <div class=\"stat total\"><div class=\"stat-value\">${summary.totalViolations}</div><div class=\"stat-label\">Violations</div></div>\n <div class=\"stat critical\"><div class=\"stat-value\">${summary.criticalCount}</div><div class=\"stat-label\">Critical</div></div>\n <div class=\"stat serious\"><div class=\"stat-value\">${summary.seriousCount}</div><div class=\"stat-label\">Serious</div></div>\n <div class=\"stat moderate\"><div class=\"stat-value\">${summary.moderateCount}</div><div class=\"stat-label\">Moderate</div></div>\n <div class=\"stat minor\"><div class=\"stat-value\">${summary.minorCount}</div><div class=\"stat-label\">Minor</div></div>\n </div>\n ${\n summary.totalViolations === 0\n ? `<div class=\"all-clear\"><div class=\"all-clear-text\">No accessibility violations found across ${summary.totalVariants} variant(s)</div></div>`\n : `<div class=\"results\">${resultItems}</div>`\n }\n </main>\n</body>\n</html>`;\n}\n\n/**\n * Generate JSON report for CI integration.\n */\nexport function generateA11yJsonReport(results: A11yResult[]): string {\n const summary = computeA11ySummary(results);\n return JSON.stringify(\n {\n timestamp: new Date().toISOString(),\n summary,\n results: results.map((r) => ({\n art: path.basename(r.artPath, \".art.vue\"),\n variant: r.variantName,\n violations: r.violations,\n passes: r.passes,\n incomplete: r.incomplete,\n })),\n },\n null,\n 2,\n );\n}\n\nfunction escapeHtml(str: string): string {\n return str\n .replace(/&/g, \"&amp;\")\n .replace(/</g, \"&lt;\")\n .replace(/>/g, \"&gt;\")\n .replace(/\"/g, \"&quot;\")\n .replace(/'/g, \"&#x27;\");\n}\n","/**\n * Accessibility (a11y) testing module for Musea.\n * Uses axe-core for automated accessibility auditing via Playwright.\n */\n\nimport type { Page } from \"playwright\";\nimport type {\n ArtFileInfo,\n A11yResult,\n A11yViolation,\n A11yOptions,\n ViewportConfig,\n} from \"../types/index.js\";\nimport type { MuseaVrtRunner } from \"../vrt.js\";\n\nimport { computeA11ySummary, generateA11yHtmlReport, generateA11yJsonReport } from \"./report.js\";\n\n// Re-export report functions so consumers importing from a11y.js still work\nexport { computeA11ySummary, generateA11yHtmlReport, generateA11yJsonReport } from \"./report.js\";\n\n/**\n * A11y audit summary.\n */\nexport interface A11ySummary {\n totalComponents: number;\n totalVariants: number;\n totalViolations: number;\n criticalCount: number;\n seriousCount: number;\n moderateCount: number;\n minorCount: number;\n}\n\n/**\n * axe-core result shape (subset).\n */\ninterface AxeResult {\n violations: Array<{\n id: string;\n impact: string;\n description: string;\n helpUrl: string;\n nodes: Array<unknown>;\n }>;\n passes: Array<unknown>;\n incomplete: Array<unknown>;\n}\n\n/**\n * A11y runner using axe-core via Playwright.\n */\nexport class MuseaA11yRunner {\n private options: Required<A11yOptions>;\n\n constructor(options: A11yOptions = {}) {\n this.options = {\n enabled: options.enabled ?? true,\n includeRules: options.includeRules ?? [],\n excludeRules: options.excludeRules ?? [],\n level: options.level ?? \"AA\",\n };\n }\n\n /**\n * Run a11y audits on all art file variants.\n * Reuses VRT runner's browser if available.\n */\n async runAudits(\n artFiles: ArtFileInfo[],\n baseUrl: string,\n vrtRunner?: MuseaVrtRunner,\n ): Promise<A11yResult[]> {\n const results: A11yResult[] = [];\n const defaultViewport: ViewportConfig = { width: 1280, height: 720, name: \"desktop\" };\n\n for (const art of artFiles) {\n for (const variant of art.variants) {\n if (variant.skipVrt) continue;\n\n let page: Page | null = null;\n let context: { page: Page; context: { close(): Promise<void> } } | null = null;\n\n try {\n if (vrtRunner) {\n context = await vrtRunner.createPage(defaultViewport);\n page = context.page;\n } else {\n // Standalone mode: launch own browser\n const { chromium } = await import(\"playwright\");\n const browser = await chromium.launch({ headless: true });\n const ctx = await browser.newContext({\n viewport: { width: defaultViewport.width, height: defaultViewport.height },\n });\n page = await ctx.newPage();\n context = { page, context: ctx };\n }\n\n const variantUrl = this.buildVariantUrl(baseUrl, art.path, variant.name);\n await page.goto(variantUrl, { waitUntil: \"networkidle\" });\n await page.waitForSelector(\".musea-variant\", { timeout: 10000 });\n await page.waitForTimeout(200);\n\n const result = await this.auditPage(page, art.path, variant.name);\n results.push(result);\n } catch (error) {\n results.push({\n artPath: art.path,\n variantName: variant.name,\n violations: [\n {\n id: \"audit-error\",\n impact: \"critical\",\n description: `Audit failed: ${error instanceof Error ? error.message : String(error)}`,\n helpUrl: \"\",\n nodes: 0,\n },\n ],\n passes: 0,\n incomplete: 0,\n });\n } finally {\n if (context) {\n await context.context.close();\n }\n }\n }\n }\n\n return results;\n }\n\n /**\n * Audit a single page using axe-core.\n */\n async auditPage(page: Page, artPath: string, variantName: string): Promise<A11yResult> {\n // Inject axe-core into the page\n const axeSource = await this.getAxeSource();\n await page.evaluate(axeSource);\n\n // Build axe-core run options\n const runOptions = this.buildAxeOptions();\n\n // Run axe-core\n const axeResult = (await page.evaluate((opts) => {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return (window as any).axe.run(document, opts);\n }, runOptions)) as AxeResult;\n\n // Map to our result format\n const violations: A11yViolation[] = axeResult.violations.map((v) => ({\n id: v.id,\n impact: v.impact as A11yViolation[\"impact\"],\n description: v.description,\n helpUrl: v.helpUrl,\n nodes: v.nodes.length,\n }));\n\n return {\n artPath,\n variantName,\n violations,\n passes: axeResult.passes.length,\n incomplete: axeResult.incomplete.length,\n };\n }\n\n /**\n * Get summary statistics from results.\n */\n getSummary(results: A11yResult[]): A11ySummary {\n return computeA11ySummary(results);\n }\n\n /**\n * Generate HTML report.\n */\n generateHtmlReport(results: A11yResult[]): string {\n const summary = this.getSummary(results);\n return generateA11yHtmlReport(results, summary);\n }\n\n /**\n * Generate JSON report for CI integration.\n */\n generateJsonReport(results: A11yResult[]): string {\n return generateA11yJsonReport(results);\n }\n\n /**\n * Get axe-core source code for injection.\n */\n private async getAxeSource(): Promise<string> {\n try {\n const axeCore = await import(\"axe-core\");\n return axeCore.source;\n } catch {\n throw new Error(\n \"axe-core is not installed. Install it as a peer dependency: npm install axe-core\",\n );\n }\n }\n\n /**\n * Build axe-core run options from configuration.\n */\n private buildAxeOptions(): Record<string, unknown> {\n const runOnly: Record<string, unknown> = {};\n\n // Set WCAG level\n const tags: string[] = [];\n switch (this.options.level) {\n case \"A\":\n tags.push(\"wcag2a\", \"wcag21a\");\n break;\n case \"AA\":\n tags.push(\"wcag2a\", \"wcag2aa\", \"wcag21a\", \"wcag21aa\", \"wcag22aa\");\n break;\n case \"AAA\":\n tags.push(\"wcag2a\", \"wcag2aa\", \"wcag2aaa\", \"wcag21a\", \"wcag21aa\", \"wcag22aa\");\n break;\n }\n\n if (tags.length > 0) {\n runOnly.type = \"tag\";\n runOnly.values = tags;\n }\n\n const rules: Record<string, { enabled: boolean }> = {};\n\n for (const ruleId of this.options.includeRules) {\n rules[ruleId] = { enabled: true };\n }\n for (const ruleId of this.options.excludeRules) {\n rules[ruleId] = { enabled: false };\n }\n\n return {\n ...(Object.keys(runOnly).length > 0 ? { runOnly } : {}),\n ...(Object.keys(rules).length > 0 ? { rules } : {}),\n };\n }\n\n private buildVariantUrl(baseUrl: string, artPath: string, variantName: string): string {\n const encodedPath = encodeURIComponent(artPath);\n const encodedVariant = encodeURIComponent(variantName);\n return `${baseUrl}/__musea__/preview?art=${encodedPath}&variant=${encodedVariant}`;\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"a11y-DNCg2qCB.mjs","names":[],"sources":["../src/a11y/report.ts","../src/a11y/index.ts"],"sourcesContent":["/**\n * A11y report generation for Musea.\n *\n * Generates HTML and JSON reports from accessibility audit results,\n * plus summary statistics computation.\n */\n\nimport type { A11yResult } from \"../types/index.js\";\nimport type { A11ySummary } from \"./index.js\";\nimport path from \"node:path\";\n\n/**\n * Compute a11y summary statistics from results.\n */\nexport function computeA11ySummary(results: A11yResult[]): A11ySummary {\n const components = new Set(results.map((r) => r.artPath));\n const allViolations = results.flatMap((r) => r.violations);\n\n return {\n totalComponents: components.size,\n totalVariants: results.length,\n totalViolations: allViolations.length,\n criticalCount: allViolations.filter((v) => v.impact === \"critical\").length,\n seriousCount: allViolations.filter((v) => v.impact === \"serious\").length,\n moderateCount: allViolations.filter((v) => v.impact === \"moderate\").length,\n minorCount: allViolations.filter((v) => v.impact === \"minor\").length,\n };\n}\n\n/**\n * Generate HTML report from a11y results.\n */\nexport function generateA11yHtmlReport(results: A11yResult[], summary: A11ySummary): string {\n const timestamp = new Date().toLocaleString(\"ja-JP\", {\n year: \"numeric\",\n month: \"2-digit\",\n day: \"2-digit\",\n hour: \"2-digit\",\n minute: \"2-digit\",\n });\n\n const impactColor = (impact: string): string => {\n switch (impact) {\n case \"critical\":\n return \"#f87171\";\n case \"serious\":\n return \"#fb923c\";\n case \"moderate\":\n return \"#fbbf24\";\n case \"minor\":\n return \"#60a5fa\";\n default:\n return \"#7b8494\";\n }\n };\n\n const resultItems = results\n .filter((r) => r.violations.length > 0)\n .map((r) => {\n const artName = path.basename(r.artPath, \".art.vue\");\n const violationRows = r.violations\n .map(\n (v) => `\n <tr>\n <td><span style=\"color:${impactColor(v.impact)};font-weight:600;text-transform:uppercase;font-size:0.6875rem\">${escapeHtml(v.impact)}</span></td>\n <td><code>${escapeHtml(v.id)}</code></td>\n <td>${escapeHtml(v.description)}</td>\n <td>${v.nodes}</td>\n <td>${v.helpUrl ? `<a href=\"${escapeHtml(v.helpUrl)}\" target=\"_blank\" style=\"color:#60a5fa\">docs</a>` : \"\"}</td>\n </tr>`,\n )\n .join(\"\");\n\n return `\n <div class=\"result\">\n <div class=\"result-header\">\n <div class=\"result-info\">\n <span class=\"result-name\">${escapeHtml(artName)} / ${escapeHtml(r.variantName)}</span>\n <span class=\"result-count\">${r.violations.length} violation(s)</span>\n </div>\n </div>\n <table class=\"violations-table\">\n <thead><tr><th>Impact</th><th>Rule</th><th>Description</th><th>Nodes</th><th>Help</th></tr></thead>\n <tbody>${violationRows}</tbody>\n </table>\n </div>`;\n })\n .join(\"\");\n\n return `<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n <title>A11y Report - Musea</title>\n <style>\n :root {\n --musea-bg-primary: #0d0d0d;\n --musea-bg-secondary: #1a1815;\n --musea-bg-tertiary: #252220;\n --musea-accent: #a34828;\n --musea-text: #e6e9f0;\n --musea-text-muted: #7b8494;\n --musea-border: #3a3530;\n }\n * { box-sizing: border-box; margin: 0; padding: 0; }\n body {\n font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;\n background: var(--musea-bg-primary);\n color: var(--musea-text);\n min-height: 100vh;\n line-height: 1.5;\n }\n .header {\n background: var(--musea-bg-secondary);\n border-bottom: 1px solid var(--musea-border);\n padding: 1rem 2rem;\n display: flex;\n align-items: center;\n justify-content: space-between;\n }\n .logo { font-size: 1.25rem; font-weight: 700; color: var(--musea-accent); }\n .header-meta { color: var(--musea-text-muted); font-size: 0.8125rem; }\n .main { max-width: 1200px; margin: 0 auto; padding: 2rem; }\n .summary { display: grid; grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); gap: 1rem; margin-bottom: 2rem; }\n .stat { background: var(--musea-bg-secondary); border: 1px solid var(--musea-border); border-radius: 8px; padding: 1rem; text-align: center; }\n .stat-value { font-size: 1.75rem; font-weight: 700; font-variant-numeric: tabular-nums; }\n .stat-label { color: var(--musea-text-muted); font-size: 0.75rem; text-transform: uppercase; letter-spacing: 0.08em; }\n .stat.critical .stat-value { color: #f87171; }\n .stat.serious .stat-value { color: #fb923c; }\n .stat.moderate .stat-value { color: #fbbf24; }\n .stat.minor .stat-value { color: #60a5fa; }\n .stat.total .stat-value { color: var(--musea-text); }\n .results { display: flex; flex-direction: column; gap: 1rem; }\n .result { background: var(--musea-bg-secondary); border: 1px solid var(--musea-border); border-radius: 8px; overflow: hidden; }\n .result-header { padding: 1rem; background: var(--musea-bg-tertiary); display: flex; justify-content: space-between; align-items: center; }\n .result-name { font-weight: 600; }\n .result-count { color: var(--musea-text-muted); font-size: 0.8125rem; }\n .violations-table { width: 100%; border-collapse: collapse; font-size: 0.8125rem; }\n .violations-table th { padding: 0.75rem 1rem; text-align: left; color: var(--musea-text-muted); font-weight: 500; font-size: 0.6875rem; text-transform: uppercase; letter-spacing: 0.08em; border-bottom: 1px solid var(--musea-border); }\n .violations-table td { padding: 0.75rem 1rem; border-bottom: 1px solid var(--musea-border); }\n .violations-table code { background: var(--musea-bg-tertiary); padding: 0.125rem 0.375rem; border-radius: 3px; font-size: 0.75rem; }\n .all-clear { background: rgba(74, 222, 128, 0.1); border: 1px solid rgba(74, 222, 128, 0.2); border-radius: 8px; padding: 2rem; text-align: center; }\n .all-clear-text { color: #4ade80; font-weight: 600; }\n </style>\n</head>\n<body>\n <header class=\"header\">\n <div><span class=\"logo\">Musea</span> <span style=\"color:var(--musea-text-muted);font-size:0.875rem;margin-left:1rem\">Accessibility Report</span></div>\n <div class=\"header-meta\">${timestamp}</div>\n </header>\n <main class=\"main\">\n <div class=\"summary\">\n <div class=\"stat total\"><div class=\"stat-value\">${summary.totalViolations}</div><div class=\"stat-label\">Violations</div></div>\n <div class=\"stat critical\"><div class=\"stat-value\">${summary.criticalCount}</div><div class=\"stat-label\">Critical</div></div>\n <div class=\"stat serious\"><div class=\"stat-value\">${summary.seriousCount}</div><div class=\"stat-label\">Serious</div></div>\n <div class=\"stat moderate\"><div class=\"stat-value\">${summary.moderateCount}</div><div class=\"stat-label\">Moderate</div></div>\n <div class=\"stat minor\"><div class=\"stat-value\">${summary.minorCount}</div><div class=\"stat-label\">Minor</div></div>\n </div>\n ${\n summary.totalViolations === 0\n ? `<div class=\"all-clear\"><div class=\"all-clear-text\">No accessibility violations found across ${summary.totalVariants} variant(s)</div></div>`\n : `<div class=\"results\">${resultItems}</div>`\n }\n </main>\n</body>\n</html>`;\n}\n\n/**\n * Generate JSON report for CI integration.\n */\nexport function generateA11yJsonReport(results: A11yResult[]): string {\n const summary = computeA11ySummary(results);\n return JSON.stringify(\n {\n timestamp: new Date().toISOString(),\n summary,\n results: results.map((r) => ({\n art: path.basename(r.artPath, \".art.vue\"),\n variant: r.variantName,\n violations: r.violations,\n passes: r.passes,\n incomplete: r.incomplete,\n })),\n },\n null,\n 2,\n );\n}\n\nfunction escapeHtml(str: string): string {\n return str\n .replace(/&/g, \"&amp;\")\n .replace(/</g, \"&lt;\")\n .replace(/>/g, \"&gt;\")\n .replace(/\"/g, \"&quot;\")\n .replace(/'/g, \"&#x27;\");\n}\n","/**\n * Accessibility (a11y) testing module for Musea.\n * Uses axe-core for automated accessibility auditing via Playwright.\n */\n\nimport type { Page } from \"playwright\";\nimport type {\n ArtFileInfo,\n A11yResult,\n A11yViolation,\n A11yOptions,\n ViewportConfig,\n} from \"../types/index.js\";\nimport type { MuseaVrtRunner } from \"../vrt.js\";\n\nimport { computeA11ySummary, generateA11yHtmlReport, generateA11yJsonReport } from \"./report.js\";\n\n// Re-export report functions so consumers importing from a11y.js still work\nexport { computeA11ySummary, generateA11yHtmlReport, generateA11yJsonReport } from \"./report.js\";\n\n/**\n * A11y audit summary.\n */\nexport interface A11ySummary {\n totalComponents: number;\n totalVariants: number;\n totalViolations: number;\n criticalCount: number;\n seriousCount: number;\n moderateCount: number;\n minorCount: number;\n}\n\n/**\n * axe-core result shape (subset).\n */\ninterface AxeResult {\n violations: Array<{\n id: string;\n impact: string;\n description: string;\n helpUrl: string;\n nodes: Array<unknown>;\n }>;\n passes: Array<unknown>;\n incomplete: Array<unknown>;\n}\n\n/**\n * A11y runner using axe-core via Playwright.\n */\nexport class MuseaA11yRunner {\n private options: Required<A11yOptions>;\n\n constructor(options: A11yOptions = {}) {\n this.options = {\n enabled: options.enabled ?? true,\n includeRules: options.includeRules ?? [],\n excludeRules: options.excludeRules ?? [],\n level: options.level ?? \"AA\",\n };\n }\n\n /**\n * Run a11y audits on all art file variants.\n * Reuses VRT runner's browser if available.\n */\n async runAudits(\n artFiles: ArtFileInfo[],\n baseUrl: string,\n vrtRunner?: MuseaVrtRunner,\n ): Promise<A11yResult[]> {\n const results: A11yResult[] = [];\n const defaultViewport: ViewportConfig = { width: 1280, height: 720, name: \"desktop\" };\n\n for (const art of artFiles) {\n for (const variant of art.variants) {\n if (variant.skipVrt) continue;\n\n let page: Page | null = null;\n let context: { page: Page; context: { close(): Promise<void> } } | null = null;\n\n try {\n if (vrtRunner) {\n context = await vrtRunner.createPage(defaultViewport);\n page = context.page;\n } else {\n // Standalone mode: launch own browser\n const { chromium } = await import(\"playwright\");\n const browser = await chromium.launch({ headless: true });\n const ctx = await browser.newContext({\n viewport: { width: defaultViewport.width, height: defaultViewport.height },\n });\n page = await ctx.newPage();\n context = { page, context: ctx };\n }\n\n const variantUrl = this.buildVariantUrl(baseUrl, art.path, variant.name);\n await page.goto(variantUrl, { waitUntil: \"networkidle\" });\n await page.waitForSelector(\".musea-variant\", { timeout: 10000 });\n await page.waitForTimeout(200);\n\n const result = await this.auditPage(page, art.path, variant.name);\n results.push(result);\n } catch (error) {\n results.push({\n artPath: art.path,\n variantName: variant.name,\n violations: [\n {\n id: \"audit-error\",\n impact: \"critical\",\n description: `Audit failed: ${error instanceof Error ? error.message : String(error)}`,\n helpUrl: \"\",\n nodes: 0,\n },\n ],\n passes: 0,\n incomplete: 0,\n });\n } finally {\n if (context) {\n await context.context.close();\n }\n }\n }\n }\n\n return results;\n }\n\n /**\n * Audit a single page using axe-core.\n */\n async auditPage(page: Page, artPath: string, variantName: string): Promise<A11yResult> {\n // Inject axe-core into the page\n const axeSource = await this.getAxeSource();\n await page.evaluate(axeSource);\n\n // Build axe-core run options\n const runOptions = this.buildAxeOptions();\n\n // Run axe-core\n const axeResult = (await page.evaluate((opts) => {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return (window as any).axe.run(document, opts);\n }, runOptions)) as AxeResult;\n\n // Map to our result format\n const violations: A11yViolation[] = axeResult.violations.map((v) => ({\n id: v.id,\n impact: v.impact as A11yViolation[\"impact\"],\n description: v.description,\n helpUrl: v.helpUrl,\n nodes: v.nodes.length,\n }));\n\n return {\n artPath,\n variantName,\n violations,\n passes: axeResult.passes.length,\n incomplete: axeResult.incomplete.length,\n };\n }\n\n /**\n * Get summary statistics from results.\n */\n getSummary(results: A11yResult[]): A11ySummary {\n return computeA11ySummary(results);\n }\n\n /**\n * Generate HTML report.\n */\n generateHtmlReport(results: A11yResult[]): string {\n const summary = this.getSummary(results);\n return generateA11yHtmlReport(results, summary);\n }\n\n /**\n * Generate JSON report for CI integration.\n */\n generateJsonReport(results: A11yResult[]): string {\n return generateA11yJsonReport(results);\n }\n\n /**\n * Get axe-core source code for injection.\n */\n private async getAxeSource(): Promise<string> {\n try {\n const axeCore = await import(\"axe-core\");\n return axeCore.source;\n } catch {\n throw new Error(\n \"axe-core is not installed. Install it as a peer dependency: npm install axe-core\",\n );\n }\n }\n\n /**\n * Build axe-core run options from configuration.\n */\n private buildAxeOptions(): Record<string, unknown> {\n const runOnly: Record<string, unknown> = {};\n\n // Set WCAG level\n const tags: string[] = [];\n switch (this.options.level) {\n case \"A\":\n tags.push(\"wcag2a\", \"wcag21a\");\n break;\n case \"AA\":\n tags.push(\"wcag2a\", \"wcag2aa\", \"wcag21a\", \"wcag21aa\", \"wcag22aa\");\n break;\n case \"AAA\":\n tags.push(\"wcag2a\", \"wcag2aa\", \"wcag2aaa\", \"wcag21a\", \"wcag21aa\", \"wcag22aa\");\n break;\n }\n\n if (tags.length > 0) {\n runOnly.type = \"tag\";\n runOnly.values = tags;\n }\n\n const rules: Record<string, { enabled: boolean }> = {};\n\n for (const ruleId of this.options.includeRules) {\n rules[ruleId] = { enabled: true };\n }\n for (const ruleId of this.options.excludeRules) {\n rules[ruleId] = { enabled: false };\n }\n\n return {\n ...(Object.keys(runOnly).length > 0 ? { runOnly } : {}),\n ...(Object.keys(rules).length > 0 ? { rules } : {}),\n };\n }\n\n private buildVariantUrl(baseUrl: string, artPath: string, variantName: string): string {\n const encodedPath = encodeURIComponent(artPath);\n const encodedVariant = encodeURIComponent(variantName);\n return `${baseUrl}/__musea__/preview?art=${encodedPath}&variant=${encodedVariant}`;\n }\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"autogen-3-y1d0ou.mjs","names":[],"sources":["../src/autogen/fallback.ts","../src/autogen/index.ts"],"sourcesContent":["/**\n * JS-based fallback for variant auto-generation.\n *\n * Used when the native Rust binding is not available. Provides simple\n * regex-based prop extraction, minimal art file generation, and a pure\n * JS variant generator.\n */\n\nimport path from \"node:path\";\n\nimport type { AutogenOptions, AutogenOutput, GeneratedVariant, PropDefinition } from \"./index.js\";\n\n/**\n * Simple prop extraction fallback (when native binding not available).\n */\nexport function extractPropsSimple(source: string): PropDefinition[] {\n const props: PropDefinition[] = [];\n\n // Match defineProps<{ ... }>() or defineProps({ ... })\n const propsMatch = source.match(/defineProps\\s*<\\s*\\{([^}]*)\\}\\s*>/s);\n\n if (propsMatch) {\n const propsBlock = propsMatch[1];\n const propLines = propsBlock.split(\"\\n\");\n\n for (const line of propLines) {\n const propMatch = line.trim().match(/^(\\w+)(\\?)?:\\s*(.+?)\\s*;?\\s*$/);\n if (propMatch) {\n props.push({\n name: propMatch[1],\n propType: propMatch[3].replace(/,\\s*$/, \"\"),\n required: !propMatch[2],\n });\n }\n }\n }\n\n return props;\n}\n\n/**\n * Minimal art file for components with no props.\n */\nexport function generateMinimalArt(componentName: string, componentPath: string): string {\n return `<art title=\"${componentName}\" component=\"${componentPath}\">\n <variant name=\"Default\" default>\n <${componentName} />\n </variant>\n</art>\n\n<script setup lang=\"ts\">\nimport ${componentName} from '${componentPath}'\n</script>\n`;\n}\n\n/**\n * JS-based variant generation fallback.\n */\nexport function generateArtFileJs(\n componentPath: string,\n props: PropDefinition[],\n options: AutogenOptions,\n): AutogenOutput {\n const componentName = path.basename(componentPath, \".vue\");\n const relPath = `./${path.basename(componentPath)}`;\n const maxVariants = options.maxVariants ?? 20;\n const variants: GeneratedVariant[] = [];\n\n // Default variant\n if (options.includeDefault !== false) {\n const defaultProps: Record<string, unknown> = {};\n for (const prop of props) {\n if (prop.defaultValue !== undefined) {\n defaultProps[prop.name] = prop.defaultValue;\n }\n }\n variants.push({\n name: \"Default\",\n isDefault: true,\n props: defaultProps,\n description: `${componentName} with default props`,\n });\n }\n\n // Enum variants\n if (options.includeEnumVariants !== false) {\n for (const prop of props) {\n const unionValues = parseUnionType(prop.propType);\n for (const val of unionValues) {\n if (variants.length >= maxVariants) break;\n const name =\n typeof val === \"string\" ? toPascalCase(val) : `${toPascalCase(prop.name)}_${String(val)}`;\n variants.push({\n name,\n isDefault: false,\n props: { [prop.name]: val },\n description: `${prop.name} = ${JSON.stringify(val)}`,\n });\n }\n }\n }\n\n // Boolean toggle variants\n if (options.includeBooleanToggles !== false) {\n for (const prop of props) {\n if (variants.length >= maxVariants) break;\n if (prop.propType.toLowerCase() === \"boolean\") {\n const nonDefault = prop.defaultValue === true ? false : true;\n variants.push({\n name: nonDefault ? toPascalCase(prop.name) : `No${toPascalCase(prop.name)}`,\n isDefault: false,\n props: { [prop.name]: nonDefault },\n description: `${prop.name} = ${nonDefault}`,\n });\n }\n }\n }\n\n // Generate art file content\n let content = `<art title=\"${componentName}\" component=\"${relPath}\">\\n`;\n for (const variant of variants) {\n const attrs = variant.isDefault ? `name=\"${variant.name}\" default` : `name=\"${variant.name}\"`;\n content += ` <variant ${attrs}>\\n`;\n\n const propsStr = Object.entries(variant.props)\n .map(([k, v]) => {\n if (typeof v === \"string\") return `${k}=\"${v}\"`;\n if (typeof v === \"boolean\" && v) return k;\n if (typeof v === \"boolean\" && !v) return `:${k}=\"false\"`;\n return `:${k}=\"${JSON.stringify(v)}\"`;\n })\n .join(\" \");\n\n content += ` <${componentName}${propsStr ? \" \" + propsStr : \"\"} />\\n`;\n content += ` </variant>\\n\\n`;\n }\n content += `</art>\\n\\n<script setup lang=\"ts\">\\nimport ${componentName} from '${relPath}'\\n</script>\\n`;\n\n return {\n variants,\n artFileContent: content,\n componentName,\n };\n}\n\nexport function parseUnionType(typeStr: string): unknown[] {\n const trimmed = typeStr.trim();\n if (!trimmed.includes(\"|\")) return [];\n\n if (trimmed.includes(\"'\") || trimmed.includes('\"')) {\n return trimmed\n .split(\"|\")\n .map((s) => s.trim().replace(/^['\"]|['\"]$/g, \"\"))\n .filter((s) => s.length > 0);\n }\n\n const parts = trimmed.split(\"|\").map((s) => s.trim());\n if (parts.every((p) => !isNaN(Number(p)))) {\n return parts.map(Number);\n }\n\n return [];\n}\n\nexport function toPascalCase(str: string): string {\n return str\n .split(/[\\s\\-_]+/)\n .filter(Boolean)\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1))\n .join(\"\");\n}\n","/**\n * Variant auto-generation module.\n * Generates .art.vue files from component prop analysis.\n *\n * JS-based fallback logic (extractPropsSimple, generateMinimalArt,\n * generateArtFileJs, and helpers) is extracted into `fallback.ts`.\n */\n\nimport { createRequire } from \"node:module\";\nimport fs from \"node:fs\";\nimport path from \"node:path\";\n\nimport { extractPropsSimple, generateMinimalArt, generateArtFileJs } from \"./fallback.js\";\n\n/**\n * Autogen configuration options.\n */\nexport interface AutogenOptions {\n /** Maximum number of variants to generate (default: 20) */\n maxVariants?: number;\n /** Include a \"Default\" variant with all default values (default: true) */\n includeDefault?: boolean;\n /** Include boolean toggle variants (default: true) */\n includeBooleanToggles?: boolean;\n /** Include enum/union variants (default: true) */\n includeEnumVariants?: boolean;\n /** Include boundary value variants for numbers (default: false) */\n includeBoundaryValues?: boolean;\n /** Include empty string variants for optional strings (default: false) */\n includeEmptyStrings?: boolean;\n}\n\n/**\n * Prop definition for variant generation.\n */\nexport interface PropDefinition {\n name: string;\n propType: string;\n required: boolean;\n defaultValue?: unknown;\n}\n\n/**\n * Generated variant.\n */\nexport interface GeneratedVariant {\n name: string;\n isDefault: boolean;\n props: Record<string, unknown>;\n description?: string;\n}\n\n/**\n * Autogen output.\n */\nexport interface AutogenOutput {\n variants: GeneratedVariant[];\n artFileContent: string;\n componentName: string;\n}\n\n// Native binding types\ninterface NativeAutogen {\n generateVariants?: (\n componentPath: string,\n props: Array<{\n name: string;\n prop_type: string;\n required: boolean;\n default_value?: unknown;\n }>,\n config?: {\n max_variants?: number;\n include_default?: boolean;\n include_boolean_toggles?: boolean;\n include_enum_variants?: boolean;\n include_boundary_values?: boolean;\n include_empty_strings?: boolean;\n },\n ) => {\n variants: Array<{\n name: string;\n is_default: boolean;\n props: Record<string, unknown>;\n description?: string;\n }>;\n art_file_content: string;\n component_name: string;\n };\n analyzeSfc?: (\n source: string,\n options?: { filename?: string },\n ) => {\n props: Array<{ name: string; type: string; required: boolean; default_value?: unknown }>;\n emits: string[];\n };\n}\n\nlet native: NativeAutogen | null = null;\n\nfunction loadNative(): NativeAutogen {\n if (native) return native;\n const require = createRequire(import.meta.url);\n try {\n native = require(\"@vizejs/native\") as NativeAutogen;\n return native;\n } catch (e) {\n throw new Error(\n `Failed to load @vizejs/native. Make sure it's installed and built:\\n${String(e)}`,\n );\n }\n}\n\n/**\n * Generate .art.vue file for a component.\n *\n * @param componentPath - Path to the Vue component file\n * @param options - Auto-generation options\n * @returns Generated .art.vue content and metadata\n */\nexport async function generateArtFile(\n componentPath: string,\n options: AutogenOptions = {},\n): Promise<AutogenOutput> {\n const absolutePath = path.resolve(componentPath);\n const source = await fs.promises.readFile(absolutePath, \"utf-8\");\n\n const binding = loadNative();\n\n // Analyze component to extract props\n let props: PropDefinition[];\n if (binding.analyzeSfc) {\n const analysis = binding.analyzeSfc(source, { filename: absolutePath });\n props = analysis.props.map((p) => ({\n name: p.name,\n propType: p.type,\n required: p.required,\n defaultValue: p.default_value,\n }));\n } else {\n // Fallback: simple regex-based prop extraction\n props = extractPropsSimple(source);\n }\n\n if (props.length === 0) {\n // No props found: generate minimal art file\n const componentName = path.basename(componentPath, \".vue\");\n const relPath = `./${path.basename(componentPath)}`;\n return {\n variants: [{ name: \"Default\", isDefault: true, props: {} }],\n artFileContent: generateMinimalArt(componentName, relPath),\n componentName,\n };\n }\n\n // Use native variant generation if available\n if (binding.generateVariants) {\n const nativeProps = props.map((p) => ({\n name: p.name,\n prop_type: p.propType,\n required: p.required,\n default_value: p.defaultValue,\n }));\n\n const relPath = `./${path.basename(componentPath)}`;\n const result = binding.generateVariants(relPath, nativeProps, {\n max_variants: options.maxVariants,\n include_default: options.includeDefault,\n include_boolean_toggles: options.includeBooleanToggles,\n include_enum_variants: options.includeEnumVariants,\n include_boundary_values: options.includeBoundaryValues,\n include_empty_strings: options.includeEmptyStrings,\n });\n\n return {\n variants: result.variants.map((v) => ({\n name: v.name,\n isDefault: v.is_default,\n props: v.props,\n description: v.description,\n })),\n artFileContent: result.art_file_content,\n componentName: result.component_name,\n };\n }\n\n // Fallback: JS-based generation\n return generateArtFileJs(componentPath, props, options);\n}\n\n/**\n * Write generated .art.vue file to disk.\n */\nexport async function writeArtFile(\n componentPath: string,\n options: AutogenOptions = {},\n outputPath?: string,\n): Promise<string> {\n const output = await generateArtFile(componentPath, options);\n\n const targetPath = outputPath ?? componentPath.replace(/\\.vue$/, \".art.vue\");\n\n await fs.promises.mkdir(path.dirname(targetPath), { recursive: true });\n await fs.promises.writeFile(targetPath, output.artFileContent, \"utf-8\");\n\n return targetPath;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"autogen-3-y1d0ou.mjs","names":[],"sources":["../src/autogen/fallback.ts","../src/autogen/index.ts"],"sourcesContent":["/**\n * JS-based fallback for variant auto-generation.\n *\n * Used when the native Rust binding is not available. Provides simple\n * regex-based prop extraction, minimal art file generation, and a pure\n * JS variant generator.\n */\n\nimport path from \"node:path\";\n\nimport type { AutogenOptions, AutogenOutput, GeneratedVariant, PropDefinition } from \"./index.js\";\n\n/**\n * Simple prop extraction fallback (when native binding not available).\n */\nexport function extractPropsSimple(source: string): PropDefinition[] {\n const props: PropDefinition[] = [];\n\n // Match defineProps<{ ... }>() or defineProps({ ... })\n const propsMatch = source.match(/defineProps\\s*<\\s*\\{([^}]*)\\}\\s*>/s);\n\n if (propsMatch) {\n const propsBlock = propsMatch[1];\n const propLines = propsBlock.split(\"\\n\");\n\n for (const line of propLines) {\n const propMatch = line.trim().match(/^(\\w+)(\\?)?:\\s*(.+?)\\s*;?\\s*$/);\n if (propMatch) {\n props.push({\n name: propMatch[1],\n propType: propMatch[3].replace(/,\\s*$/, \"\"),\n required: !propMatch[2],\n });\n }\n }\n }\n\n return props;\n}\n\n/**\n * Minimal art file for components with no props.\n */\nexport function generateMinimalArt(componentName: string, componentPath: string): string {\n return `<art title=\"${componentName}\" component=\"${componentPath}\">\n <variant name=\"Default\" default>\n <${componentName} />\n </variant>\n</art>\n\n<script setup lang=\"ts\">\nimport ${componentName} from '${componentPath}'\n</script>\n`;\n}\n\n/**\n * JS-based variant generation fallback.\n */\nexport function generateArtFileJs(\n componentPath: string,\n props: PropDefinition[],\n options: AutogenOptions,\n): AutogenOutput {\n const componentName = path.basename(componentPath, \".vue\");\n const relPath = `./${path.basename(componentPath)}`;\n const maxVariants = options.maxVariants ?? 20;\n const variants: GeneratedVariant[] = [];\n\n // Default variant\n if (options.includeDefault !== false) {\n const defaultProps: Record<string, unknown> = {};\n for (const prop of props) {\n if (prop.defaultValue !== undefined) {\n defaultProps[prop.name] = prop.defaultValue;\n }\n }\n variants.push({\n name: \"Default\",\n isDefault: true,\n props: defaultProps,\n description: `${componentName} with default props`,\n });\n }\n\n // Enum variants\n if (options.includeEnumVariants !== false) {\n for (const prop of props) {\n const unionValues = parseUnionType(prop.propType);\n for (const val of unionValues) {\n if (variants.length >= maxVariants) break;\n const name =\n typeof val === \"string\" ? toPascalCase(val) : `${toPascalCase(prop.name)}_${String(val)}`;\n variants.push({\n name,\n isDefault: false,\n props: { [prop.name]: val },\n description: `${prop.name} = ${JSON.stringify(val)}`,\n });\n }\n }\n }\n\n // Boolean toggle variants\n if (options.includeBooleanToggles !== false) {\n for (const prop of props) {\n if (variants.length >= maxVariants) break;\n if (prop.propType.toLowerCase() === \"boolean\") {\n const nonDefault = prop.defaultValue === true ? false : true;\n variants.push({\n name: nonDefault ? toPascalCase(prop.name) : `No${toPascalCase(prop.name)}`,\n isDefault: false,\n props: { [prop.name]: nonDefault },\n description: `${prop.name} = ${nonDefault}`,\n });\n }\n }\n }\n\n // Generate art file content\n let content = `<art title=\"${componentName}\" component=\"${relPath}\">\\n`;\n for (const variant of variants) {\n const attrs = variant.isDefault ? `name=\"${variant.name}\" default` : `name=\"${variant.name}\"`;\n content += ` <variant ${attrs}>\\n`;\n\n const propsStr = Object.entries(variant.props)\n .map(([k, v]) => {\n if (typeof v === \"string\") return `${k}=\"${v}\"`;\n if (typeof v === \"boolean\" && v) return k;\n if (typeof v === \"boolean\" && !v) return `:${k}=\"false\"`;\n return `:${k}=\"${JSON.stringify(v)}\"`;\n })\n .join(\" \");\n\n content += ` <${componentName}${propsStr ? \" \" + propsStr : \"\"} />\\n`;\n content += ` </variant>\\n\\n`;\n }\n content += `</art>\\n\\n<script setup lang=\"ts\">\\nimport ${componentName} from '${relPath}'\\n</script>\\n`;\n\n return {\n variants,\n artFileContent: content,\n componentName,\n };\n}\n\nexport function parseUnionType(typeStr: string): unknown[] {\n const trimmed = typeStr.trim();\n if (!trimmed.includes(\"|\")) return [];\n\n if (trimmed.includes(\"'\") || trimmed.includes('\"')) {\n return trimmed\n .split(\"|\")\n .map((s) => s.trim().replace(/^['\"]|['\"]$/g, \"\"))\n .filter((s) => s.length > 0);\n }\n\n const parts = trimmed.split(\"|\").map((s) => s.trim());\n if (parts.every((p) => !isNaN(Number(p)))) {\n return parts.map(Number);\n }\n\n return [];\n}\n\nexport function toPascalCase(str: string): string {\n return str\n .split(/[\\s\\-_]+/)\n .filter(Boolean)\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1))\n .join(\"\");\n}\n","/**\n * Variant auto-generation module.\n * Generates .art.vue files from component prop analysis.\n *\n * JS-based fallback logic (extractPropsSimple, generateMinimalArt,\n * generateArtFileJs, and helpers) is extracted into `fallback.ts`.\n */\n\nimport { createRequire } from \"node:module\";\nimport fs from \"node:fs\";\nimport path from \"node:path\";\n\nimport { extractPropsSimple, generateMinimalArt, generateArtFileJs } from \"./fallback.js\";\n\n/**\n * Autogen configuration options.\n */\nexport interface AutogenOptions {\n /** Maximum number of variants to generate (default: 20) */\n maxVariants?: number;\n /** Include a \"Default\" variant with all default values (default: true) */\n includeDefault?: boolean;\n /** Include boolean toggle variants (default: true) */\n includeBooleanToggles?: boolean;\n /** Include enum/union variants (default: true) */\n includeEnumVariants?: boolean;\n /** Include boundary value variants for numbers (default: false) */\n includeBoundaryValues?: boolean;\n /** Include empty string variants for optional strings (default: false) */\n includeEmptyStrings?: boolean;\n}\n\n/**\n * Prop definition for variant generation.\n */\nexport interface PropDefinition {\n name: string;\n propType: string;\n required: boolean;\n defaultValue?: unknown;\n}\n\n/**\n * Generated variant.\n */\nexport interface GeneratedVariant {\n name: string;\n isDefault: boolean;\n props: Record<string, unknown>;\n description?: string;\n}\n\n/**\n * Autogen output.\n */\nexport interface AutogenOutput {\n variants: GeneratedVariant[];\n artFileContent: string;\n componentName: string;\n}\n\n// Native binding types\ninterface NativeAutogen {\n generateVariants?: (\n componentPath: string,\n props: Array<{\n name: string;\n prop_type: string;\n required: boolean;\n default_value?: unknown;\n }>,\n config?: {\n max_variants?: number;\n include_default?: boolean;\n include_boolean_toggles?: boolean;\n include_enum_variants?: boolean;\n include_boundary_values?: boolean;\n include_empty_strings?: boolean;\n },\n ) => {\n variants: Array<{\n name: string;\n is_default: boolean;\n props: Record<string, unknown>;\n description?: string;\n }>;\n art_file_content: string;\n component_name: string;\n };\n analyzeSfc?: (\n source: string,\n options?: { filename?: string },\n ) => {\n props: Array<{ name: string; type: string; required: boolean; default_value?: unknown }>;\n emits: string[];\n };\n}\n\nlet native: NativeAutogen | null = null;\n\nfunction loadNative(): NativeAutogen {\n if (native) return native;\n const require = createRequire(import.meta.url);\n try {\n native = require(\"@vizejs/native\") as NativeAutogen;\n return native;\n } catch (e) {\n throw new Error(\n `Failed to load @vizejs/native. Make sure it's installed and built:\\n${String(e)}`,\n );\n }\n}\n\n/**\n * Generate .art.vue file for a component.\n *\n * @param componentPath - Path to the Vue component file\n * @param options - Auto-generation options\n * @returns Generated .art.vue content and metadata\n */\nexport async function generateArtFile(\n componentPath: string,\n options: AutogenOptions = {},\n): Promise<AutogenOutput> {\n const absolutePath = path.resolve(componentPath);\n const source = await fs.promises.readFile(absolutePath, \"utf-8\");\n\n const binding = loadNative();\n\n // Analyze component to extract props\n let props: PropDefinition[];\n if (binding.analyzeSfc) {\n const analysis = binding.analyzeSfc(source, { filename: absolutePath });\n props = analysis.props.map((p) => ({\n name: p.name,\n propType: p.type,\n required: p.required,\n defaultValue: p.default_value,\n }));\n } else {\n // Fallback: simple regex-based prop extraction\n props = extractPropsSimple(source);\n }\n\n if (props.length === 0) {\n // No props found: generate minimal art file\n const componentName = path.basename(componentPath, \".vue\");\n const relPath = `./${path.basename(componentPath)}`;\n return {\n variants: [{ name: \"Default\", isDefault: true, props: {} }],\n artFileContent: generateMinimalArt(componentName, relPath),\n componentName,\n };\n }\n\n // Use native variant generation if available\n if (binding.generateVariants) {\n const nativeProps = props.map((p) => ({\n name: p.name,\n prop_type: p.propType,\n required: p.required,\n default_value: p.defaultValue,\n }));\n\n const relPath = `./${path.basename(componentPath)}`;\n const result = binding.generateVariants(relPath, nativeProps, {\n max_variants: options.maxVariants,\n include_default: options.includeDefault,\n include_boolean_toggles: options.includeBooleanToggles,\n include_enum_variants: options.includeEnumVariants,\n include_boundary_values: options.includeBoundaryValues,\n include_empty_strings: options.includeEmptyStrings,\n });\n\n return {\n variants: result.variants.map((v) => ({\n name: v.name,\n isDefault: v.is_default,\n props: v.props,\n description: v.description,\n })),\n artFileContent: result.art_file_content,\n componentName: result.component_name,\n };\n }\n\n // Fallback: JS-based generation\n return generateArtFileJs(componentPath, props, options);\n}\n\n/**\n * Write generated .art.vue file to disk.\n */\nexport async function writeArtFile(\n componentPath: string,\n options: AutogenOptions = {},\n outputPath?: string,\n): Promise<string> {\n const output = await generateArtFile(componentPath, options);\n\n const targetPath = outputPath ?? componentPath.replace(/\\.vue$/, \".art.vue\");\n\n await fs.promises.mkdir(path.dirname(targetPath), { recursive: true });\n await fs.promises.writeFile(targetPath, output.artFileContent, \"utf-8\");\n\n return targetPath;\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../../src/cli/utils.ts","../../src/cli/commands.ts","../../src/cli/index.ts"],"sourcesContent":["/**\n * CLI utility functions for art file scanning and parsing.\n *\n * Extracted from cli.ts to keep file sizes manageable.\n */\n\nimport fs from \"node:fs\";\nimport path from \"node:path\";\n\nimport type { ArtFileInfo } from \"../types/index.js\";\n\n/** Recursively scan a directory for .art.vue files. */\nexport async function scanArtFiles(root: string): Promise<string[]> {\n const files: string[] = [];\n\n async function scan(dir: string): Promise<void> {\n const entries = await fs.promises.readdir(dir, { withFileTypes: true });\n\n for (const entry of entries) {\n const fullPath = path.join(dir, entry.name);\n\n // Skip node_modules and dist\n if (entry.name === \"node_modules\" || entry.name === \"dist\") {\n continue;\n }\n\n if (entry.isDirectory()) {\n await scan(fullPath);\n } else if (entry.isFile() && entry.name.endsWith(\".art.vue\")) {\n files.push(fullPath);\n }\n }\n }\n\n await scan(root);\n return files;\n}\n\n/** Parse a single .art.vue file into an ArtFileInfo structure. */\nexport async function parseArtFile(filePath: string): Promise<ArtFileInfo | null> {\n try {\n const source = await fs.promises.readFile(filePath, \"utf-8\");\n\n // Simple parsing - in production, use @vizejs/native\n const titleMatch = source.match(/<art[^>]*\\stitle=[\"']([^\"']+)[\"']/);\n const componentMatch = source.match(/<art[^>]*\\scomponent=[\"']([^\"']+)[\"']/);\n const categoryMatch = source.match(/<art[^>]*\\scategory=[\"']([^\"']+)[\"']/);\n\n const variants: ArtFileInfo[\"variants\"] = [];\n const variantRegex = /<variant\\s+([^>]*)>([\\s\\S]*?)<\\/variant>/g;\n let match;\n\n while ((match = variantRegex.exec(source)) !== null) {\n const attrs = match[1];\n const template = match[2].trim();\n\n const nameMatch = attrs.match(/name=[\"']([^\"']+)[\"']/);\n const isDefault = /\\bdefault\\b/.test(attrs);\n const skipVrt = /\\bskip-vrt\\b/.test(attrs);\n\n if (nameMatch) {\n variants.push({\n name: nameMatch[1],\n template,\n isDefault,\n skipVrt,\n });\n }\n }\n\n return {\n path: filePath,\n metadata: {\n title: titleMatch?.[1] || path.basename(filePath, \".art.vue\"),\n component: componentMatch?.[1],\n category: categoryMatch?.[1],\n tags: [],\n status: \"ready\",\n },\n variants,\n hasScriptSetup: /<script\\s+setup/.test(source),\n hasScript: /<script(?!\\s+setup)/.test(source),\n styleCount: (source.match(/<style/g) || []).length,\n };\n } catch (error) {\n console.error(`Failed to parse ${filePath}:`, error);\n return null;\n }\n}\n","/**\n * CLI command handlers for the Musea VRT tool.\n *\n * Extracted from cli.ts to keep file sizes manageable.\n * Contains the runVrt, runApprove, runClean, and runGenerate command implementations.\n */\n\nimport fs from \"node:fs\";\nimport path from \"node:path\";\n\nimport { MuseaVrtRunner, generateVrtReport, generateVrtJsonReport } from \"../vrt.js\";\nimport type { ArtFileInfo, VrtOptions } from \"../types/index.js\";\n\nimport type { CliOptions } from \"./index.js\";\n\nexport async function runVrt(options: CliOptions, artFiles: ArtFileInfo[]): Promise<void> {\n const totalVariants = artFiles.reduce(\n (sum, art) => sum + art.variants.filter((v) => !v.skipVrt).length,\n 0,\n );\n\n console.log(` Testing ${totalVariants} variant(s) across ${artFiles.length} art file(s)\\n`);\n\n // Initialize VRT runner\n const vrtOptions: VrtOptions = {\n snapshotDir: path.join(options.output, \"snapshots\"),\n threshold: options.threshold,\n };\n\n const runner = new MuseaVrtRunner({\n ...vrtOptions,\n ci: options.ci ? { failOnDiff: true, jsonReport: options.json } : undefined,\n });\n\n try {\n console.log(\" Launching browser...\");\n await runner.init();\n\n console.log(\" Running visual regression tests...\\n\");\n\n // Run tests\n const results = await runner.runAllTests(artFiles, options.baseUrl);\n const summary = runner.getSummary(results);\n\n // Print results\n console.log(\" Results:\");\n console.log(\" ---------\");\n console.log(` Passed: ${summary.passed}`);\n console.log(` Failed: ${summary.failed}`);\n console.log(` New: ${summary.new}`);\n console.log(` Skipped: ${summary.skipped}`);\n console.log(` Total: ${summary.total}`);\n console.log(` Duration: ${(summary.duration / 1000).toFixed(2)}s\\n`);\n\n // Run a11y audits if requested\n if (options.a11y) {\n console.log(\" Running accessibility audits...\\n\");\n try {\n const { MuseaA11yRunner } = await import(\"../a11y/index.js\");\n const a11yRunner = new MuseaA11yRunner();\n const a11yResults = await a11yRunner.runAudits(artFiles, options.baseUrl, runner);\n const a11ySummary = a11yRunner.getSummary(a11yResults);\n\n console.log(\" A11y Results:\");\n console.log(\" -------------\");\n console.log(` Components: ${a11ySummary.totalComponents}`);\n console.log(` Variants: ${a11ySummary.totalVariants}`);\n console.log(` Violations: ${a11ySummary.totalViolations}`);\n console.log(` Critical: ${a11ySummary.criticalCount}`);\n console.log(` Serious: ${a11ySummary.seriousCount}\\n`);\n\n // Generate a11y report\n const reportDir = options.output;\n await fs.promises.mkdir(reportDir, { recursive: true });\n\n if (options.json) {\n const a11yJson = a11yRunner.generateJsonReport(a11yResults);\n const a11yPath = path.join(reportDir, \"a11y-report.json\");\n await fs.promises.writeFile(a11yPath, a11yJson);\n console.log(` A11y JSON report: ${a11yPath}\\n`);\n } else {\n const a11yHtml = a11yRunner.generateHtmlReport(a11yResults);\n const a11yPath = path.join(reportDir, \"a11y-report.html\");\n await fs.promises.writeFile(a11yPath, a11yHtml);\n console.log(` A11y HTML report: ${a11yPath}\\n`);\n }\n\n // CI mode - exit with error on critical/serious violations\n if (options.ci && (a11ySummary.criticalCount > 0 || a11ySummary.seriousCount > 0)) {\n console.log(\" CI mode: Accessibility violations found\\n\");\n process.exit(1);\n }\n } catch (e) {\n console.warn(\" A11y audits skipped:\", e instanceof Error ? e.message : String(e));\n console.warn(\" Make sure axe-core is installed: npm install axe-core\\n\");\n }\n }\n\n // Update baselines if requested\n if (options.update) {\n console.log(\" Updating baselines...\");\n const updated = await runner.updateBaselines(results);\n console.log(` Updated ${updated} baseline(s)\\n`);\n }\n\n // Generate VRT report\n const reportDir = options.output;\n await fs.promises.mkdir(reportDir, { recursive: true });\n\n if (options.json) {\n const jsonReport = generateVrtJsonReport(results, summary);\n const jsonPath = path.join(reportDir, \"vrt-report.json\");\n await fs.promises.writeFile(jsonPath, jsonReport);\n console.log(` JSON report: ${jsonPath}\\n`);\n } else {\n const htmlReport = generateVrtReport(results, summary);\n const htmlPath = path.join(reportDir, \"vrt-report.html\");\n await fs.promises.writeFile(htmlPath, htmlReport);\n console.log(` HTML report: ${htmlPath}\\n`);\n }\n\n // CI mode - exit with error if failures\n if (options.ci && summary.failed > 0) {\n console.log(\" CI mode: Exiting with error due to failures\\n\");\n process.exit(1);\n }\n } finally {\n await runner.close();\n }\n}\n\nexport async function runApprove(options: CliOptions, artFiles: ArtFileInfo[]): Promise<void> {\n const vrtOptions: VrtOptions = {\n snapshotDir: path.join(options.output, \"snapshots\"),\n threshold: options.threshold,\n };\n\n const runner = new MuseaVrtRunner(vrtOptions);\n\n try {\n console.log(\" Launching browser...\");\n await runner.init();\n\n console.log(\" Running tests to find diffs...\\n\");\n\n const results = await runner.runAllTests(artFiles, options.baseUrl);\n const failed = results.filter((r) => !r.passed && !r.error);\n\n if (failed.length === 0) {\n console.log(\" No failed tests to approve.\\n\");\n return;\n }\n\n const pattern = options.pattern;\n if (pattern) {\n console.log(` Approving snapshots matching: ${pattern}\\n`);\n } else {\n console.log(` Approving all ${failed.length} failed snapshot(s)...\\n`);\n }\n\n const approved = await runner.approveResults(results, pattern);\n console.log(` Approved ${approved} snapshot(s)\\n`);\n } finally {\n await runner.close();\n }\n}\n\nexport async function runClean(options: CliOptions, artFiles: ArtFileInfo[]): Promise<void> {\n const vrtOptions: VrtOptions = {\n snapshotDir: path.join(options.output, \"snapshots\"),\n threshold: options.threshold,\n };\n\n const runner = new MuseaVrtRunner(vrtOptions);\n\n console.log(\" Scanning for orphaned snapshots...\\n\");\n\n const cleaned = await runner.cleanOrphans(artFiles);\n\n if (cleaned === 0) {\n console.log(\" No orphaned snapshots found.\\n\");\n } else {\n console.log(`\\n Cleaned ${cleaned} orphaned snapshot(s)\\n`);\n }\n}\n\nexport async function runGenerate(options: CliOptions): Promise<void> {\n if (!options.componentPath) {\n console.error(\" Error: Missing component path.\");\n console.error(\" Usage: musea-vrt generate <component.vue>\\n\");\n process.exit(1);\n }\n\n const componentPath = path.resolve(options.componentPath);\n\n // Check file exists\n try {\n await fs.promises.access(componentPath);\n } catch {\n console.error(` Error: File not found: ${componentPath}\\n`);\n process.exit(1);\n }\n\n console.log(` Generating art file for: ${path.relative(process.cwd(), componentPath)}\\n`);\n\n try {\n const { writeArtFile } = await import(\"../autogen/index.js\");\n const outputPath = await writeArtFile(componentPath);\n const relOutput = path.relative(process.cwd(), outputPath);\n\n console.log(` Generated: ${relOutput}\\n`);\n } catch (e) {\n console.error(\" Generation failed:\", e instanceof Error ? e.message : String(e));\n process.exit(1);\n }\n}\n","#!/usr/bin/env node\n/**\n * Musea CLI\n *\n * Usage:\n * musea-vrt [command] [options]\n *\n * Commands:\n * (default) Run VRT tests\n * approve [pat] Approve failed snapshots (optionally filtered by pattern)\n * clean Remove orphaned snapshots\n *\n * Options:\n * -u, --update Update baseline snapshots\n * -c, --config Path to vite config (default: vite.config.ts)\n * -o, --output Output directory for reports (default: .vize)\n * -t, --threshold Diff threshold percentage (default: 0.1)\n * --json Output JSON report instead of HTML\n * --ci CI mode - exit with non-zero code on failures\n * --a11y Run accessibility audits alongside VRT\n * -h, --help Show help\n */\n\nimport type { ArtFileInfo } from \"../types/index.js\";\nimport { scanArtFiles, parseArtFile } from \"./utils.js\";\nimport { runVrt, runApprove, runClean, runGenerate } from \"./commands.js\";\n\ntype Command = \"run\" | \"approve\" | \"clean\" | \"generate\";\n\nexport interface CliOptions {\n command: Command;\n update: boolean;\n config: string;\n output: string;\n threshold: number;\n json: boolean;\n ci: boolean;\n a11y: boolean;\n help: boolean;\n baseUrl: string;\n pattern?: string;\n componentPath?: string;\n}\n\nfunction parseArgs(args: string[]): CliOptions {\n const options: CliOptions = {\n command: \"run\",\n update: false,\n config: \"vite.config.ts\",\n output: \".vize\",\n threshold: 0.1,\n json: false,\n ci: false,\n a11y: false,\n help: false,\n baseUrl: \"http://localhost:5173\",\n };\n\n let i = 0;\n\n // Check for subcommand as first arg\n if (args.length > 0 && !args[0].startsWith(\"-\")) {\n const sub = args[0];\n if (sub === \"approve\") {\n options.command = \"approve\";\n i = 1;\n // Optional pattern argument after approve\n if (args.length > 1 && !args[1].startsWith(\"-\")) {\n options.pattern = args[1];\n i = 2;\n }\n } else if (sub === \"clean\") {\n options.command = \"clean\";\n i = 1;\n } else if (sub === \"generate\") {\n options.command = \"generate\";\n i = 1;\n // Required component path argument\n if (args.length > 1 && !args[1].startsWith(\"-\")) {\n options.componentPath = args[1];\n i = 2;\n }\n }\n }\n\n for (; i < args.length; i++) {\n const arg = args[i];\n switch (arg) {\n case \"-u\":\n case \"--update\":\n options.update = true;\n break;\n case \"-c\":\n case \"--config\":\n options.config = args[++i] || \"vite.config.ts\";\n break;\n case \"-o\":\n case \"--output\":\n options.output = args[++i] || \".vize\";\n break;\n case \"-t\":\n case \"--threshold\":\n options.threshold = parseFloat(args[++i]) || 0.1;\n break;\n case \"--json\":\n options.json = true;\n break;\n case \"--ci\":\n options.ci = true;\n break;\n case \"--a11y\":\n options.a11y = true;\n break;\n case \"-b\":\n case \"--base-url\":\n options.baseUrl = args[++i] || \"http://localhost:5173\";\n break;\n case \"-h\":\n case \"--help\":\n options.help = true;\n break;\n }\n }\n\n return options;\n}\n\nfunction printHelp(): void {\n console.log(`\nMusea VRT - Visual Regression Testing for Component Gallery\n\nUsage:\n musea-vrt [command] [options]\n\nCommands:\n (default) Run VRT tests\n approve [pattern] Approve failed snapshots and update baselines\n Optional pattern filters which snapshots to approve\n clean Remove orphaned snapshots (no matching art/variant)\n generate <component> Auto-generate .art.vue from a Vue component\n\nOptions:\n -u, --update Update baseline snapshots with current screenshots\n -c, --config <path> Path to vite config file (default: vite.config.ts)\n -o, --output <dir> Output directory for reports (default: .vize)\n -t, --threshold <n> Diff threshold percentage (default: 0.1)\n -b, --base-url <url> Base URL for dev server (default: http://localhost:5173)\n --json Output JSON report instead of HTML\n --ci CI mode - exit with non-zero code on failures\n --a11y Run accessibility audits alongside VRT\n -h, --help Show this help message\n\nExamples:\n # Run VRT tests\n musea-vrt\n\n # Update baseline snapshots\n musea-vrt -u\n\n # Run with custom threshold\n musea-vrt -t 0.5\n\n # CI mode with JSON output\n musea-vrt --ci --json\n\n # Run with accessibility audits\n musea-vrt --a11y\n\n # Approve all failed snapshots\n musea-vrt approve\n\n # Approve specific snapshots by pattern\n musea-vrt approve \"Button/*\"\n\n # Clean orphaned snapshots\n musea-vrt clean\n\n # Auto-generate .art.vue from component\n musea-vrt generate src/components/Button.vue\n\n # Custom base URL\n musea-vrt -b http://localhost:3000\n`);\n}\n\nasync function main(): Promise<void> {\n const args = process.argv.slice(2);\n const options = parseArgs(args);\n\n if (options.help) {\n printHelp();\n process.exit(0);\n }\n\n const cwd = process.cwd();\n\n console.log(\"\\n Musea VRT\");\n console.log(\" =========\\n\");\n\n // Handle generate command early (doesn't need art file scanning)\n if (options.command === \"generate\") {\n try {\n await runGenerate(options);\n } catch (error) {\n console.error(\"\\n Error:\", error);\n process.exit(1);\n }\n return;\n }\n\n // Scan for art files\n console.log(\" Scanning for art files...\");\n const artFilePaths = await scanArtFiles(cwd);\n\n if (artFilePaths.length === 0) {\n console.log(\" No art files found.\\n\");\n process.exit(0);\n }\n\n console.log(` Found ${artFilePaths.length} art file(s)\\n`);\n\n // Parse art files\n const artFiles: ArtFileInfo[] = [];\n for (const filePath of artFilePaths) {\n const art = await parseArtFile(filePath);\n if (art) {\n artFiles.push(art);\n }\n }\n\n try {\n switch (options.command) {\n case \"run\":\n await runVrt(options, artFiles);\n break;\n case \"approve\":\n await runApprove(options, artFiles);\n break;\n case \"clean\":\n await runClean(options, artFiles);\n break;\n case \"generate\":\n // Handled above before art file scanning\n break;\n }\n } catch (error) {\n console.error(\"\\n Error:\", error);\n process.exit(1);\n }\n}\n\nmain().catch((error) => {\n console.error(\"Fatal error:\", error);\n process.exit(1);\n});\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../../src/cli/utils.ts","../../src/cli/commands.ts","../../src/cli/index.ts"],"sourcesContent":["/**\n * CLI utility functions for art file scanning and parsing.\n *\n * Extracted from cli.ts to keep file sizes manageable.\n */\n\nimport fs from \"node:fs\";\nimport path from \"node:path\";\n\nimport type { ArtFileInfo } from \"../types/index.js\";\n\n/** Recursively scan a directory for .art.vue files. */\nexport async function scanArtFiles(root: string): Promise<string[]> {\n const files: string[] = [];\n\n async function scan(dir: string): Promise<void> {\n const entries = await fs.promises.readdir(dir, { withFileTypes: true });\n\n for (const entry of entries) {\n const fullPath = path.join(dir, entry.name);\n\n // Skip node_modules and dist\n if (entry.name === \"node_modules\" || entry.name === \"dist\") {\n continue;\n }\n\n if (entry.isDirectory()) {\n await scan(fullPath);\n } else if (entry.isFile() && entry.name.endsWith(\".art.vue\")) {\n files.push(fullPath);\n }\n }\n }\n\n await scan(root);\n return files;\n}\n\n/** Parse a single .art.vue file into an ArtFileInfo structure. */\nexport async function parseArtFile(filePath: string): Promise<ArtFileInfo | null> {\n try {\n const source = await fs.promises.readFile(filePath, \"utf-8\");\n\n // Simple parsing - in production, use @vizejs/native\n const titleMatch = source.match(/<art[^>]*\\stitle=[\"']([^\"']+)[\"']/);\n const componentMatch = source.match(/<art[^>]*\\scomponent=[\"']([^\"']+)[\"']/);\n const categoryMatch = source.match(/<art[^>]*\\scategory=[\"']([^\"']+)[\"']/);\n\n const variants: ArtFileInfo[\"variants\"] = [];\n const variantRegex = /<variant\\s+([^>]*)>([\\s\\S]*?)<\\/variant>/g;\n let match;\n\n while ((match = variantRegex.exec(source)) !== null) {\n const attrs = match[1];\n const template = match[2].trim();\n\n const nameMatch = attrs.match(/name=[\"']([^\"']+)[\"']/);\n const isDefault = /\\bdefault\\b/.test(attrs);\n const skipVrt = /\\bskip-vrt\\b/.test(attrs);\n\n if (nameMatch) {\n variants.push({\n name: nameMatch[1],\n template,\n isDefault,\n skipVrt,\n });\n }\n }\n\n return {\n path: filePath,\n metadata: {\n title: titleMatch?.[1] || path.basename(filePath, \".art.vue\"),\n component: componentMatch?.[1],\n category: categoryMatch?.[1],\n tags: [],\n status: \"ready\",\n },\n variants,\n hasScriptSetup: /<script\\s+setup/.test(source),\n hasScript: /<script(?!\\s+setup)/.test(source),\n styleCount: (source.match(/<style/g) || []).length,\n };\n } catch (error) {\n console.error(`Failed to parse ${filePath}:`, error);\n return null;\n }\n}\n","/**\n * CLI command handlers for the Musea VRT tool.\n *\n * Extracted from cli.ts to keep file sizes manageable.\n * Contains the runVrt, runApprove, runClean, and runGenerate command implementations.\n */\n\nimport fs from \"node:fs\";\nimport path from \"node:path\";\n\nimport { MuseaVrtRunner, generateVrtReport, generateVrtJsonReport } from \"../vrt.js\";\nimport type { ArtFileInfo, VrtOptions } from \"../types/index.js\";\n\nimport type { CliOptions } from \"./index.js\";\n\nexport async function runVrt(options: CliOptions, artFiles: ArtFileInfo[]): Promise<void> {\n const totalVariants = artFiles.reduce(\n (sum, art) => sum + art.variants.filter((v) => !v.skipVrt).length,\n 0,\n );\n\n console.log(` Testing ${totalVariants} variant(s) across ${artFiles.length} art file(s)\\n`);\n\n // Initialize VRT runner\n const vrtOptions: VrtOptions = {\n snapshotDir: path.join(options.output, \"snapshots\"),\n threshold: options.threshold,\n };\n\n const runner = new MuseaVrtRunner({\n ...vrtOptions,\n ci: options.ci ? { failOnDiff: true, jsonReport: options.json } : undefined,\n });\n\n try {\n console.log(\" Launching browser...\");\n await runner.init();\n\n console.log(\" Running visual regression tests...\\n\");\n\n // Run tests\n const results = await runner.runAllTests(artFiles, options.baseUrl);\n const summary = runner.getSummary(results);\n\n // Print results\n console.log(\" Results:\");\n console.log(\" ---------\");\n console.log(` Passed: ${summary.passed}`);\n console.log(` Failed: ${summary.failed}`);\n console.log(` New: ${summary.new}`);\n console.log(` Skipped: ${summary.skipped}`);\n console.log(` Total: ${summary.total}`);\n console.log(` Duration: ${(summary.duration / 1000).toFixed(2)}s\\n`);\n\n // Run a11y audits if requested\n if (options.a11y) {\n console.log(\" Running accessibility audits...\\n\");\n try {\n const { MuseaA11yRunner } = await import(\"../a11y/index.js\");\n const a11yRunner = new MuseaA11yRunner();\n const a11yResults = await a11yRunner.runAudits(artFiles, options.baseUrl, runner);\n const a11ySummary = a11yRunner.getSummary(a11yResults);\n\n console.log(\" A11y Results:\");\n console.log(\" -------------\");\n console.log(` Components: ${a11ySummary.totalComponents}`);\n console.log(` Variants: ${a11ySummary.totalVariants}`);\n console.log(` Violations: ${a11ySummary.totalViolations}`);\n console.log(` Critical: ${a11ySummary.criticalCount}`);\n console.log(` Serious: ${a11ySummary.seriousCount}\\n`);\n\n // Generate a11y report\n const reportDir = options.output;\n await fs.promises.mkdir(reportDir, { recursive: true });\n\n if (options.json) {\n const a11yJson = a11yRunner.generateJsonReport(a11yResults);\n const a11yPath = path.join(reportDir, \"a11y-report.json\");\n await fs.promises.writeFile(a11yPath, a11yJson);\n console.log(` A11y JSON report: ${a11yPath}\\n`);\n } else {\n const a11yHtml = a11yRunner.generateHtmlReport(a11yResults);\n const a11yPath = path.join(reportDir, \"a11y-report.html\");\n await fs.promises.writeFile(a11yPath, a11yHtml);\n console.log(` A11y HTML report: ${a11yPath}\\n`);\n }\n\n // CI mode - exit with error on critical/serious violations\n if (options.ci && (a11ySummary.criticalCount > 0 || a11ySummary.seriousCount > 0)) {\n console.log(\" CI mode: Accessibility violations found\\n\");\n process.exit(1);\n }\n } catch (e) {\n console.warn(\" A11y audits skipped:\", e instanceof Error ? e.message : String(e));\n console.warn(\" Make sure axe-core is installed: npm install axe-core\\n\");\n }\n }\n\n // Update baselines if requested\n if (options.update) {\n console.log(\" Updating baselines...\");\n const updated = await runner.updateBaselines(results);\n console.log(` Updated ${updated} baseline(s)\\n`);\n }\n\n // Generate VRT report\n const reportDir = options.output;\n await fs.promises.mkdir(reportDir, { recursive: true });\n\n if (options.json) {\n const jsonReport = generateVrtJsonReport(results, summary);\n const jsonPath = path.join(reportDir, \"vrt-report.json\");\n await fs.promises.writeFile(jsonPath, jsonReport);\n console.log(` JSON report: ${jsonPath}\\n`);\n } else {\n const htmlReport = generateVrtReport(results, summary);\n const htmlPath = path.join(reportDir, \"vrt-report.html\");\n await fs.promises.writeFile(htmlPath, htmlReport);\n console.log(` HTML report: ${htmlPath}\\n`);\n }\n\n // CI mode - exit with error if failures\n if (options.ci && summary.failed > 0) {\n console.log(\" CI mode: Exiting with error due to failures\\n\");\n process.exit(1);\n }\n } finally {\n await runner.close();\n }\n}\n\nexport async function runApprove(options: CliOptions, artFiles: ArtFileInfo[]): Promise<void> {\n const vrtOptions: VrtOptions = {\n snapshotDir: path.join(options.output, \"snapshots\"),\n threshold: options.threshold,\n };\n\n const runner = new MuseaVrtRunner(vrtOptions);\n\n try {\n console.log(\" Launching browser...\");\n await runner.init();\n\n console.log(\" Running tests to find diffs...\\n\");\n\n const results = await runner.runAllTests(artFiles, options.baseUrl);\n const failed = results.filter((r) => !r.passed && !r.error);\n\n if (failed.length === 0) {\n console.log(\" No failed tests to approve.\\n\");\n return;\n }\n\n const pattern = options.pattern;\n if (pattern) {\n console.log(` Approving snapshots matching: ${pattern}\\n`);\n } else {\n console.log(` Approving all ${failed.length} failed snapshot(s)...\\n`);\n }\n\n const approved = await runner.approveResults(results, pattern);\n console.log(` Approved ${approved} snapshot(s)\\n`);\n } finally {\n await runner.close();\n }\n}\n\nexport async function runClean(options: CliOptions, artFiles: ArtFileInfo[]): Promise<void> {\n const vrtOptions: VrtOptions = {\n snapshotDir: path.join(options.output, \"snapshots\"),\n threshold: options.threshold,\n };\n\n const runner = new MuseaVrtRunner(vrtOptions);\n\n console.log(\" Scanning for orphaned snapshots...\\n\");\n\n const cleaned = await runner.cleanOrphans(artFiles);\n\n if (cleaned === 0) {\n console.log(\" No orphaned snapshots found.\\n\");\n } else {\n console.log(`\\n Cleaned ${cleaned} orphaned snapshot(s)\\n`);\n }\n}\n\nexport async function runGenerate(options: CliOptions): Promise<void> {\n if (!options.componentPath) {\n console.error(\" Error: Missing component path.\");\n console.error(\" Usage: musea-vrt generate <component.vue>\\n\");\n process.exit(1);\n }\n\n const componentPath = path.resolve(options.componentPath);\n\n // Check file exists\n try {\n await fs.promises.access(componentPath);\n } catch {\n console.error(` Error: File not found: ${componentPath}\\n`);\n process.exit(1);\n }\n\n console.log(` Generating art file for: ${path.relative(process.cwd(), componentPath)}\\n`);\n\n try {\n const { writeArtFile } = await import(\"../autogen/index.js\");\n const outputPath = await writeArtFile(componentPath);\n const relOutput = path.relative(process.cwd(), outputPath);\n\n console.log(` Generated: ${relOutput}\\n`);\n } catch (e) {\n console.error(\" Generation failed:\", e instanceof Error ? e.message : String(e));\n process.exit(1);\n }\n}\n","#!/usr/bin/env node\n/**\n * Musea CLI\n *\n * Usage:\n * musea-vrt [command] [options]\n *\n * Commands:\n * (default) Run VRT tests\n * approve [pat] Approve failed snapshots (optionally filtered by pattern)\n * clean Remove orphaned snapshots\n *\n * Options:\n * -u, --update Update baseline snapshots\n * -c, --config Path to vite config (default: vite.config.ts)\n * -o, --output Output directory for reports (default: .vize)\n * -t, --threshold Diff threshold percentage (default: 0.1)\n * --json Output JSON report instead of HTML\n * --ci CI mode - exit with non-zero code on failures\n * --a11y Run accessibility audits alongside VRT\n * -h, --help Show help\n */\n\nimport type { ArtFileInfo } from \"../types/index.js\";\nimport { scanArtFiles, parseArtFile } from \"./utils.js\";\nimport { runVrt, runApprove, runClean, runGenerate } from \"./commands.js\";\n\ntype Command = \"run\" | \"approve\" | \"clean\" | \"generate\";\n\nexport interface CliOptions {\n command: Command;\n update: boolean;\n config: string;\n output: string;\n threshold: number;\n json: boolean;\n ci: boolean;\n a11y: boolean;\n help: boolean;\n baseUrl: string;\n pattern?: string;\n componentPath?: string;\n}\n\nfunction parseArgs(args: string[]): CliOptions {\n const options: CliOptions = {\n command: \"run\",\n update: false,\n config: \"vite.config.ts\",\n output: \".vize\",\n threshold: 0.1,\n json: false,\n ci: false,\n a11y: false,\n help: false,\n baseUrl: \"http://localhost:5173\",\n };\n\n let i = 0;\n\n // Check for subcommand as first arg\n if (args.length > 0 && !args[0].startsWith(\"-\")) {\n const sub = args[0];\n if (sub === \"approve\") {\n options.command = \"approve\";\n i = 1;\n // Optional pattern argument after approve\n if (args.length > 1 && !args[1].startsWith(\"-\")) {\n options.pattern = args[1];\n i = 2;\n }\n } else if (sub === \"clean\") {\n options.command = \"clean\";\n i = 1;\n } else if (sub === \"generate\") {\n options.command = \"generate\";\n i = 1;\n // Required component path argument\n if (args.length > 1 && !args[1].startsWith(\"-\")) {\n options.componentPath = args[1];\n i = 2;\n }\n }\n }\n\n for (; i < args.length; i++) {\n const arg = args[i];\n switch (arg) {\n case \"-u\":\n case \"--update\":\n options.update = true;\n break;\n case \"-c\":\n case \"--config\":\n options.config = args[++i] || \"vite.config.ts\";\n break;\n case \"-o\":\n case \"--output\":\n options.output = args[++i] || \".vize\";\n break;\n case \"-t\":\n case \"--threshold\":\n options.threshold = parseFloat(args[++i]) || 0.1;\n break;\n case \"--json\":\n options.json = true;\n break;\n case \"--ci\":\n options.ci = true;\n break;\n case \"--a11y\":\n options.a11y = true;\n break;\n case \"-b\":\n case \"--base-url\":\n options.baseUrl = args[++i] || \"http://localhost:5173\";\n break;\n case \"-h\":\n case \"--help\":\n options.help = true;\n break;\n }\n }\n\n return options;\n}\n\nfunction printHelp(): void {\n console.log(`\nMusea VRT - Visual Regression Testing for Component Gallery\n\nUsage:\n musea-vrt [command] [options]\n\nCommands:\n (default) Run VRT tests\n approve [pattern] Approve failed snapshots and update baselines\n Optional pattern filters which snapshots to approve\n clean Remove orphaned snapshots (no matching art/variant)\n generate <component> Auto-generate .art.vue from a Vue component\n\nOptions:\n -u, --update Update baseline snapshots with current screenshots\n -c, --config <path> Path to vite config file (default: vite.config.ts)\n -o, --output <dir> Output directory for reports (default: .vize)\n -t, --threshold <n> Diff threshold percentage (default: 0.1)\n -b, --base-url <url> Base URL for dev server (default: http://localhost:5173)\n --json Output JSON report instead of HTML\n --ci CI mode - exit with non-zero code on failures\n --a11y Run accessibility audits alongside VRT\n -h, --help Show this help message\n\nExamples:\n # Run VRT tests\n musea-vrt\n\n # Update baseline snapshots\n musea-vrt -u\n\n # Run with custom threshold\n musea-vrt -t 0.5\n\n # CI mode with JSON output\n musea-vrt --ci --json\n\n # Run with accessibility audits\n musea-vrt --a11y\n\n # Approve all failed snapshots\n musea-vrt approve\n\n # Approve specific snapshots by pattern\n musea-vrt approve \"Button/*\"\n\n # Clean orphaned snapshots\n musea-vrt clean\n\n # Auto-generate .art.vue from component\n musea-vrt generate src/components/Button.vue\n\n # Custom base URL\n musea-vrt -b http://localhost:3000\n`);\n}\n\nasync function main(): Promise<void> {\n const args = process.argv.slice(2);\n const options = parseArgs(args);\n\n if (options.help) {\n printHelp();\n process.exit(0);\n }\n\n const cwd = process.cwd();\n\n console.log(\"\\n Musea VRT\");\n console.log(\" =========\\n\");\n\n // Handle generate command early (doesn't need art file scanning)\n if (options.command === \"generate\") {\n try {\n await runGenerate(options);\n } catch (error) {\n console.error(\"\\n Error:\", error);\n process.exit(1);\n }\n return;\n }\n\n // Scan for art files\n console.log(\" Scanning for art files...\");\n const artFilePaths = await scanArtFiles(cwd);\n\n if (artFilePaths.length === 0) {\n console.log(\" No art files found.\\n\");\n process.exit(0);\n }\n\n console.log(` Found ${artFilePaths.length} art file(s)\\n`);\n\n // Parse art files\n const artFiles: ArtFileInfo[] = [];\n for (const filePath of artFilePaths) {\n const art = await parseArtFile(filePath);\n if (art) {\n artFiles.push(art);\n }\n }\n\n try {\n switch (options.command) {\n case \"run\":\n await runVrt(options, artFiles);\n break;\n case \"approve\":\n await runApprove(options, artFiles);\n break;\n case \"clean\":\n await runClean(options, artFiles);\n break;\n case \"generate\":\n // Handled above before art file scanning\n break;\n }\n } catch (error) {\n console.error(\"\\n Error:\", error);\n process.exit(1);\n }\n}\n\nmain().catch((error) => {\n console.error(\"Fatal error:\", error);\n process.exit(1);\n});\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/editor.main-CzTLJrBa.js","assets/index-CvbQ61X6.js","assets/index-CwT3Ex21.css","assets/editor.api-Dg4HiaTn.js","assets/editor-B55U_qvj.css","assets/monaco.contribution-CXoI9Pg-.js","assets/editor-F8AxQWwE.css"])))=>i.map(i=>d[i]);
2
- import{a as e,c as t,d as n,f as r,i,l as a,n as o,o as s,r as c,s as l,t as u,u as d}from"./index-CvbQ61X6.js";function f(e){return new Worker(`/__musea__/assets/editor.worker-B0BIIYAR.js`,{name:e?.name})}function p(e){return new Worker(`/__musea__/assets/json.worker-3yqvOk70.js`,{name:e?.name})}function m(e){return new Worker(`/__musea__/assets/css.worker-BXrDisZh.js`,{name:e?.name})}function h(e){return new Worker(`/__musea__/assets/html.worker-_AJvPiQl.js`,{name:e?.name})}function g(e){return new Worker(`/__musea__/assets/ts.worker-B0Jjxwwp.js`,{name:e?.name})}var _=o(s({__name:`MonacoEditor`,props:{modelValue:{},language:{},theme:{},height:{},readOnly:{type:Boolean},completionItems:{}},emits:[`update:modelValue`],setup(o,{emit:s}){let _=o,v=s,{resolvedTheme:y}=c(),b=n(null),x=null,S=null,C=null,w=i(()=>y.value===`dark`?`musea-dark`:`musea-light`);t(async()=>{b.value&&(self.MonacoEnvironment={getWorker(e,t){switch(t){case`json`:return new p;case`css`:case`scss`:case`less`:return new m;case`html`:case`handlebars`:case`razor`:return new h;case`typescript`:case`javascript`:return new g;default:return new f}}},S=await u(()=>import(`./editor.main-CzTLJrBa.js`),__vite__mapDeps([0,1,2,3,4,5,6])),S.editor.defineTheme(`musea-dark`,{base:`vs-dark`,inherit:!0,rules:[],colors:{"editor.background":`#1a1a1a`,"editor.foreground":`#e5e5e5`,"editor.lineHighlightBackground":`#252525`,"editorCursor.foreground":`#e07048`,"editor.selectionBackground":`#3d3d3d`}}),S.editor.defineTheme(`musea-light`,{base:`vs`,inherit:!0,rules:[],colors:{"editor.background":`#ddd9cd`,"editor.foreground":`#121212`,"editor.lineHighlightBackground":`#d4d0c4`,"editorCursor.foreground":`#121212`,"editor.selectionBackground":`#c8c4b8`}}),_.completionItems&&_.completionItems.length>0&&T(S,_.completionItems),x=S.editor.create(b.value,{value:_.modelValue,language:_.language||`html`,theme:_.theme||w.value,minimap:{enabled:!1},fontSize:12,lineNumbers:`on`,lineNumbersMinChars:3,scrollBeyondLastLine:!1,wordWrap:`on`,automaticLayout:!0,readOnly:_.readOnly||!1,padding:{top:8,bottom:8},renderLineHighlight:`line`,scrollbar:{vertical:`auto`,horizontal:`auto`,verticalScrollbarSize:8,horizontalScrollbarSize:8},overviewRulerLanes:0,hideCursorInOverviewRuler:!0,overviewRulerBorder:!1,folding:!1,tabSize:2}),x.onDidChangeModelContent(()=>{v(`update:modelValue`,x?.getValue()||``)}))});function T(e,t){C?.dispose(),C=e.languages.registerCompletionItemProvider(`css`,{triggerCharacters:[`-`,`(`],provideCompletionItems(n,r){let i=n.getLineContent(r.lineNumber).substring(0,r.column-1),a=/var\(\s*-*$/.test(i),o=/:\s*[^;]*$/.test(i);if(!a&&!o)return{suggestions:[]};let s=n.getWordUntilPosition(r),c={startLineNumber:r.lineNumber,startColumn:s.startColumn,endLineNumber:r.lineNumber,endColumn:s.endColumn};return{suggestions:t.map(t=>{let n=`--${t.replace(/\./g,`-`)}`;return{label:n,kind:e.languages.CompletionItemKind.Variable,detail:`Design token: ${t}`,insertText:a?n:`var(${n})`,range:c,sortText:`0`+t}})}}}),C=e.languages.registerCompletionItemProvider(`html`,{triggerCharacters:[`-`,`(`],provideCompletionItems(n,r){let i=n.getLineContent(r.lineNumber).substring(0,r.column-1),a=/var\(\s*-*$/.test(i),o=/:\s*[^;]*$/.test(i);if(!a&&!o)return{suggestions:[]};let s=n.getWordUntilPosition(r),c={startLineNumber:r.lineNumber,startColumn:s.startColumn,endLineNumber:r.lineNumber,endColumn:s.endColumn};return{suggestions:t.map(t=>{let n=`--${t.replace(/\./g,`-`)}`;return{label:n,kind:e.languages.CompletionItemKind.Variable,detail:`Design token: ${t}`,insertText:a?n:`var(${n})`,range:c,sortText:`0`+t}})}}})}return l(()=>{C?.dispose(),x?.dispose()}),d(()=>_.modelValue,e=>{x&&x.getValue()!==e&&x.setValue(e)}),d(()=>_.language,e=>{if(x&&S&&e){let t=x.getModel();t&&S.editor.setModelLanguage(t,e)}}),d(()=>_.completionItems,e=>{S&&e&&e.length>0&&T(S,e)}),d(w,e=>{S&&!_.theme&&S.editor.setTheme(e)}),(t,n)=>(a(),e(`div`,{ref_key:`containerRef`,ref:b,class:`monaco-container`,style:r({height:o.height||`120px`})},null,4))}}),[[`__scopeId`,`data-v-bbc42d64`]]);export{_ as default};
1
+ const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/editor.main-DU-sPy-k.js","assets/index-DjSpyxD0.js","assets/index-CwT3Ex21.css","assets/editor.api2-CIEJpqKT.js","assets/editor-BnkT-hT5.css","assets/workers-DS42og38.js","assets/monaco.contribution-Cn9RKjKZ.js"])))=>i.map(i=>d[i]);
2
+ import{a as e,c as t,d as n,f as r,i,l as a,n as o,o as s,r as c,s as l,t as u,u as d}from"./index-DjSpyxD0.js";function f(e){return new Worker(`/__musea__/assets/editor.worker-Bd9IXS8d.js`,{name:e?.name})}function p(e){return new Worker(`/__musea__/assets/json.worker-DzV-CpCQ.js`,{name:e?.name})}function m(e){return new Worker(`/__musea__/assets/css.worker-Wv5dxAWO.js`,{name:e?.name})}function h(e){return new Worker(`/__musea__/assets/html.worker-CQP8QQsS.js`,{name:e?.name})}function g(e){return new Worker(`/__musea__/assets/ts.worker-METxwbDZ.js`,{name:e?.name})}var _=o(s({__name:`MonacoEditor`,props:{modelValue:{},language:{},theme:{},height:{},readOnly:{type:Boolean},completionItems:{}},emits:[`update:modelValue`],setup(o,{emit:s}){let _=o,v=s,{resolvedTheme:y}=c(),b=n(null),x=null,S=null,C=null,w=i(()=>y.value===`dark`?`musea-dark`:`musea-light`);t(async()=>{b.value&&(self.MonacoEnvironment={getWorker(e,t){switch(t){case`json`:return new p;case`css`:case`scss`:case`less`:return new m;case`html`:case`handlebars`:case`razor`:return new h;case`typescript`:case`javascript`:return new g;default:return new f}}},S=await u(()=>import(`./editor.main-DU-sPy-k.js`),__vite__mapDeps([0,1,2,3,4,5,6])),S.editor.defineTheme(`musea-dark`,{base:`vs-dark`,inherit:!0,rules:[],colors:{"editor.background":`#1a1a1a`,"editor.foreground":`#e5e5e5`,"editor.lineHighlightBackground":`#252525`,"editorCursor.foreground":`#e07048`,"editor.selectionBackground":`#3d3d3d`}}),S.editor.defineTheme(`musea-light`,{base:`vs`,inherit:!0,rules:[],colors:{"editor.background":`#ddd9cd`,"editor.foreground":`#121212`,"editor.lineHighlightBackground":`#d4d0c4`,"editorCursor.foreground":`#121212`,"editor.selectionBackground":`#c8c4b8`}}),_.completionItems&&_.completionItems.length>0&&T(S,_.completionItems),x=S.editor.create(b.value,{value:_.modelValue,language:_.language||`html`,theme:_.theme||w.value,minimap:{enabled:!1},fontSize:12,lineNumbers:`on`,lineNumbersMinChars:3,scrollBeyondLastLine:!1,wordWrap:`on`,automaticLayout:!0,readOnly:_.readOnly||!1,padding:{top:8,bottom:8},renderLineHighlight:`line`,scrollbar:{vertical:`auto`,horizontal:`auto`,verticalScrollbarSize:8,horizontalScrollbarSize:8},overviewRulerLanes:0,hideCursorInOverviewRuler:!0,overviewRulerBorder:!1,folding:!1,tabSize:2}),x.onDidChangeModelContent(()=>{v(`update:modelValue`,x?.getValue()||``)}))});function T(e,t){C?.dispose(),C=e.languages.registerCompletionItemProvider(`css`,{triggerCharacters:[`-`,`(`],provideCompletionItems(n,r){let i=n.getLineContent(r.lineNumber).substring(0,r.column-1),a=/var\(\s*-*$/.test(i),o=/:\s*[^;]*$/.test(i);if(!a&&!o)return{suggestions:[]};let s=n.getWordUntilPosition(r),c={startLineNumber:r.lineNumber,startColumn:s.startColumn,endLineNumber:r.lineNumber,endColumn:s.endColumn};return{suggestions:t.map(t=>{let n=`--${t.replace(/\./g,`-`)}`;return{label:n,kind:e.languages.CompletionItemKind.Variable,detail:`Design token: ${t}`,insertText:a?n:`var(${n})`,range:c,sortText:`0`+t}})}}}),C=e.languages.registerCompletionItemProvider(`html`,{triggerCharacters:[`-`,`(`],provideCompletionItems(n,r){let i=n.getLineContent(r.lineNumber).substring(0,r.column-1),a=/var\(\s*-*$/.test(i),o=/:\s*[^;]*$/.test(i);if(!a&&!o)return{suggestions:[]};let s=n.getWordUntilPosition(r),c={startLineNumber:r.lineNumber,startColumn:s.startColumn,endLineNumber:r.lineNumber,endColumn:s.endColumn};return{suggestions:t.map(t=>{let n=`--${t.replace(/\./g,`-`)}`;return{label:n,kind:e.languages.CompletionItemKind.Variable,detail:`Design token: ${t}`,insertText:a?n:`var(${n})`,range:c,sortText:`0`+t}})}}})}return l(()=>{C?.dispose(),x?.dispose()}),d(()=>_.modelValue,e=>{x&&x.getValue()!==e&&x.setValue(e)}),d(()=>_.language,e=>{if(x&&S&&e){let t=x.getModel();t&&S.editor.setModelLanguage(t,e)}}),d(()=>_.completionItems,e=>{S&&e&&e.length>0&&T(S,e)}),d(w,e=>{S&&!_.theme&&S.editor.setTheme(e)}),(t,n)=>(a(),e(`div`,{ref_key:`containerRef`,ref:b,class:`monaco-container`,style:r({height:o.height||`120px`})},null,4))}}),[[`__scopeId`,`data-v-bbc42d64`]]);export{_ as default};