@vizejs/vite-plugin-musea 0.429.1 → 0.430.1

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 (68) hide show
  1. package/dist/a11y/index.d.mts +1 -1
  2. package/dist/a11y/index.mjs +1 -1
  3. package/dist/{a11y-Ci9EEv6F.mjs → a11y-BbFK942j.mjs} +66 -15
  4. package/dist/a11y-BbFK942j.mjs.map +1 -0
  5. package/dist/api-gMwahZKm.d.mts +112 -0
  6. package/dist/api-gMwahZKm.d.mts.map +1 -0
  7. package/dist/cli/index.d.mts +1 -1
  8. package/dist/cli/index.d.mts.map +1 -1
  9. package/dist/cli/index.mjs +79 -33
  10. package/dist/cli/index.mjs.map +1 -1
  11. package/dist/gallery/assets/{MonacoEditor-BIjYdDrA.js → MonacoEditor-CnzIyKMy.js} +2 -2
  12. package/dist/gallery/assets/{cssMode-C5PB9d_X.js → cssMode-DZ_me5CG.js} +1 -1
  13. package/dist/gallery/assets/{editor.api-tyf2wJeZ.js → editor.api-CjD4Hpms.js} +1 -1
  14. package/dist/gallery/assets/{freemarker2-Df2SP4C4.js → freemarker2-F7z49Hfe.js} +1 -1
  15. package/dist/gallery/assets/{handlebars-CbFr-5KQ.js → handlebars-Dt4eGgf-.js} +1 -1
  16. package/dist/gallery/assets/{html-C1ubjnt5.js → html-B1zmbcur.js} +1 -1
  17. package/dist/gallery/assets/{htmlMode-9FYaGqmo.js → htmlMode-DmDwpA4v.js} +1 -1
  18. package/dist/gallery/assets/{index-D81pMC9f.css → index-C4vm-yqv.css} +1 -1
  19. package/dist/gallery/assets/{index-BjW1cVGf.js → index-vJ3ftuqF.js} +3 -3
  20. package/dist/gallery/assets/{javascript-DjzYR9ls.js → javascript-CLKbyvz8.js} +1 -1
  21. package/dist/gallery/assets/{jsonMode-BRxSdIjW.js → jsonMode-sms9-L2I.js} +1 -1
  22. package/dist/gallery/assets/{liquid-DD0LqlcF.js → liquid-CesACmVT.js} +1 -1
  23. package/dist/gallery/assets/{lspLanguageFeatures-C0f4qlAU.js → lspLanguageFeatures-C8BR-41u.js} +1 -1
  24. package/dist/gallery/assets/{mdx-DtcWR2Lx.js → mdx-Cd93KUo_.js} +1 -1
  25. package/dist/gallery/assets/{python-C1OlrT9L.js → python-8gi7tgMv.js} +1 -1
  26. package/dist/gallery/assets/{razor-BN2Zj1B9.js → razor-sOyhBXSy.js} +1 -1
  27. package/dist/gallery/assets/{register-CTEjv03I.js → register-C-_4TcWq.js} +2 -2
  28. package/dist/gallery/assets/{toggleHighContrast-BELgo5Kd.js → toggleHighContrast-BCHobRx5.js} +1 -1
  29. package/dist/gallery/assets/{tsMode-Bd8a8shj.js → tsMode-BkQQD7P8.js} +1 -1
  30. package/dist/gallery/assets/{typescript-DLlFIuFu.js → typescript-XiwOdN8G.js} +1 -1
  31. package/dist/gallery/assets/{vs-YCtNwrNl.js → vs-Coo3fK7w.js} +3 -3
  32. package/dist/gallery/assets/{workers-CBv4Qjp-.js → workers-Cypb28_F.js} +1 -1
  33. package/dist/gallery/assets/{xml-wUPbJH_s.js → xml-CN1ixSLs.js} +1 -1
  34. package/dist/gallery/assets/{yaml-B52zgDg-.js → yaml-l30MdsZA.js} +1 -1
  35. package/dist/gallery/index.html +2 -2
  36. package/dist/{gallery-qE5deHL0.mjs → gallery-CIcrB07g.mjs} +2 -2
  37. package/dist/{gallery-qE5deHL0.mjs.map → gallery-CIcrB07g.mjs.map} +1 -1
  38. package/dist/index-C5evpfmF.d.mts +81 -0
  39. package/dist/index-C5evpfmF.d.mts.map +1 -0
  40. package/dist/index.d.mts +5 -4
  41. package/dist/index.d.mts.map +1 -1
  42. package/dist/index.mjs +33 -9
  43. package/dist/index.mjs.map +1 -1
  44. package/dist/options-CZYdDtTW.mjs +581 -0
  45. package/dist/options-CZYdDtTW.mjs.map +1 -0
  46. package/dist/{plugin-CIrKPW8K.d.mts → plugin-DkFXWcCD.d.mts} +11 -2
  47. package/dist/plugin-DkFXWcCD.d.mts.map +1 -0
  48. package/dist/{template-DNhEgY8-.mjs → template-DDl7rsgo.mjs} +2 -2
  49. package/dist/{template-DNhEgY8-.mjs.map → template-DDl7rsgo.mjs.map} +1 -1
  50. package/dist/utils-DeMLVlNS.mjs +628 -0
  51. package/dist/utils-DeMLVlNS.mjs.map +1 -0
  52. package/dist/{vrt-DVub2B6r.d.mts → vrt-3T_e4bJ3.d.mts} +7 -1
  53. package/dist/vrt-3T_e4bJ3.d.mts.map +1 -0
  54. package/dist/{vrt-BPwRc95_.d.mts → vrt-6iDBfqNg.d.mts} +2 -2
  55. package/dist/{vrt-BPwRc95_.d.mts.map → vrt-6iDBfqNg.d.mts.map} +1 -1
  56. package/dist/{vrt-UxzWFygI.mjs → vrt-VuGK9wTX.mjs} +11 -4
  57. package/dist/vrt-VuGK9wTX.mjs.map +1 -0
  58. package/dist/vrt.d.mts +1 -1
  59. package/dist/vrt.mjs +1 -1
  60. package/package.json +4 -4
  61. package/dist/a11y-Ci9EEv6F.mjs.map +0 -1
  62. package/dist/index-HVtO9FK5.d.mts +0 -170
  63. package/dist/index-HVtO9FK5.d.mts.map +0 -1
  64. package/dist/options-Cd7bzLGr.mjs +0 -1142
  65. package/dist/options-Cd7bzLGr.mjs.map +0 -1
  66. package/dist/plugin-CIrKPW8K.d.mts.map +0 -1
  67. package/dist/vrt-DVub2B6r.d.mts.map +0 -1
  68. package/dist/vrt-UxzWFygI.mjs.map +0 -1
@@ -0,0 +1,581 @@
1
+ import { E as loadNative, S as resolveTrustedSourcePath, g as assertComponentSourcePath, s as toPascalCase, t as escapeHtml } from "./utils-DeMLVlNS.mjs";
2
+ import fs from "node:fs";
3
+ import path from "node:path";
4
+ import { createHash } from "node:crypto";
5
+ //#region src/component-source.ts
6
+ function allowedSourceRoots(root, scanRoots = []) {
7
+ return [...new Set([root, ...scanRoots].map((sourceRoot) => path.resolve(sourceRoot)))];
8
+ }
9
+ function resolveReadableArtPath(root, scanRoots, artPath) {
10
+ return resolveTrustedSourcePath(root, scanRoots, artPath, "art path");
11
+ }
12
+ function resolveComponentSourcePath(art, artPath, sourceRoots) {
13
+ const componentPath = art.isInline && art.componentPath ? art.componentPath : art.metadata.component ? path.isAbsolute(art.metadata.component) ? art.metadata.component : path.resolve(path.dirname(artPath), art.metadata.component) : null;
14
+ const [projectRoot, ...extraRoots] = sourceRoots;
15
+ if (!componentPath) return null;
16
+ const resolved = resolveTrustedSourcePath(projectRoot ?? ".", extraRoots, componentPath, "component path");
17
+ assertComponentSourcePath(resolved, "component path");
18
+ return resolved;
19
+ }
20
+ //#endregion
21
+ //#region src/art-module-vue2.ts
22
+ /**
23
+ * Legacy Vue 2 variant emission.
24
+ *
25
+ * Vue 2 has no `openBlock`/`createElementBlock` runtime, so the compiled Vue 3
26
+ * render functions the SFC pipeline produces cannot load there. Vue 2 galleries
27
+ * keep the runtime-compiled `template:` string they always had — the TypeScript
28
+ * fix in #3857 applies to Vue 3, which is what `.art.vue` with
29
+ * `<script setup lang="ts">` targets.
30
+ */
31
+ function escapeTemplateLiteral(str) {
32
+ return str.replace(/\\/g, "\\\\").replace(/`/g, "\\`").replace(/\$/g, "\\$");
33
+ }
34
+ function emitLegacyVariant(context) {
35
+ const { variantComponentName, variantName, template, componentTagName, componentBindingName, scriptSetup, hasSetup, isolatedSetup, setupReturn, importDeclaresName } = context;
36
+ const escapedTemplate = escapeTemplateLiteral(template);
37
+ const fullTemplate = `<div data-variant="${escapeTemplateLiteral(escapeHtml(variantName))}">${escapedTemplate}</div>`;
38
+ const componentNames = /* @__PURE__ */ new Map();
39
+ if (componentTagName) componentNames.set(componentTagName, componentBindingName);
40
+ if (scriptSetup) {
41
+ for (const name of scriptSetup.returnNames) if (/^[A-Z]/.test(name) && scriptSetup.imports.some((imp) => importDeclaresName(imp, name))) componentNames.set(name, name);
42
+ }
43
+ const components = componentNames.size > 0 ? ` components: { ${[...componentNames].map(([name, value]) => `${JSON.stringify(name)}: ${value}`).join(", ")} },\n` : "";
44
+ if (scriptSetup && hasSetup && isolatedSetup) return `
45
+ export const ${variantComponentName} = __museaDefineComponent({
46
+ name: '${variantComponentName}',
47
+ ${components} setup() {
48
+ ${scriptSetup.setupBody.join("\n")}
49
+ return ${setupReturn};
50
+ },
51
+ template: \`${fullTemplate}\`,
52
+ });
53
+ `;
54
+ if (scriptSetup && hasSetup) return `
55
+ export const ${variantComponentName} = __museaDefineComponent({
56
+ name: '${variantComponentName}',
57
+ ${components} setup() {
58
+ return __museaSharedSetup;
59
+ },
60
+ template: \`${fullTemplate}\`,
61
+ });
62
+ `;
63
+ return `
64
+ export const ${variantComponentName} = {
65
+ name: '${variantComponentName}',
66
+ ${components} template: \`${fullTemplate}\`,
67
+ };
68
+ `;
69
+ }
70
+ //#endregion
71
+ //#region src/art-component.ts
72
+ /**
73
+ * Resolve which component an art file demonstrates, and under what tag.
74
+ *
75
+ * Shared by the art module and by the per-variant SFC compiler (#3857) so both
76
+ * agree on the import path, the tag `<Self>` expands to, and the binding name.
77
+ * The parsed `<script setup>` is passed in rather than parsed here, so this
78
+ * module does not have to import back from `art-module.ts`.
79
+ */
80
+ function componentNameFromSource$1(source) {
81
+ const withoutQuery = source.split(/[?#]/, 1)[0] || source;
82
+ const filename = path.basename(withoutQuery);
83
+ const extension = path.extname(filename);
84
+ const name = toPascalCase(extension ? filename.slice(0, -extension.length) : filename);
85
+ return name === "Variant" ? "MuseaComponent" : name;
86
+ }
87
+ function resolveArtComponent(art, filePath, scriptSetup, options = {}) {
88
+ let componentImportPath;
89
+ let componentTagName;
90
+ let componentBindingName = "__MuseaComponent";
91
+ const defineArtComponentName = scriptSetup?.defineArtComponentName;
92
+ const defineArtComponentSource = scriptSetup?.defineArtComponentSource;
93
+ if (art.isInline && art.componentPath) {
94
+ componentImportPath = options.root ? resolveComponentSourcePath(art, filePath, allowedSourceRoots(options.root, options.scanRoots ?? [])) ?? void 0 : art.componentPath;
95
+ componentTagName = "MuseaComponent";
96
+ } else if (defineArtComponentSource || art.metadata.component) {
97
+ const componentSource = defineArtComponentSource ?? art.metadata.component;
98
+ if (componentSource) {
99
+ const sourceArt = componentSource === art.metadata.component ? art : {
100
+ ...art,
101
+ metadata: {
102
+ ...art.metadata,
103
+ component: componentSource
104
+ }
105
+ };
106
+ componentImportPath = options.root ? resolveComponentSourcePath(sourceArt, filePath, allowedSourceRoots(options.root, options.scanRoots ?? [])) ?? void 0 : path.isAbsolute(componentSource) ? componentSource : path.resolve(path.dirname(filePath), componentSource);
107
+ }
108
+ componentTagName = defineArtComponentName ?? (art.metadata.component ? componentNameFromSource$1(art.metadata.component) : "MuseaComponent");
109
+ componentBindingName = componentTagName;
110
+ }
111
+ return {
112
+ componentImportPath,
113
+ componentTagName,
114
+ componentBindingName
115
+ };
116
+ }
117
+ /** Expand `<Self>` in a variant template to the resolved component tag. */
118
+ function expandSelfTag(template, componentTagName) {
119
+ if (!componentTagName) return template;
120
+ return template.replace(/<Self(?=[\s/>])/g, `<${componentTagName}`).replace(/<\/Self\s*>/g, `</${componentTagName}>`);
121
+ }
122
+ //#endregion
123
+ //#region src/art-module.ts
124
+ /**
125
+ * Art module generation for Musea.
126
+ *
127
+ * Generates the virtual ES modules that represent parsed `.art.vue` files,
128
+ * including variant component definitions and script setup handling.
129
+ */
130
+ /**
131
+ * Extract the content of the first <script setup> block from a Vue SFC source.
132
+ */
133
+ function extractScriptSetupContent(source) {
134
+ return source.match(/<script\s+[^>]*setup[^>]*>([\s\S]*?)<\/script>/)?.[1]?.trim();
135
+ }
136
+ function extractScriptSetupIsolated(source) {
137
+ const match = source.match(/<script\s+([^>]*)\bsetup\b([^>]*)>/);
138
+ if (!match) return true;
139
+ const isolate = `${match[1] ?? ""} ${match[2] ?? ""}`.match(/\bisolate\s*=\s*(?:"([^"]*)"|'([^']*)'|([^\s>]+))/);
140
+ return (isolate?.[1] ?? isolate?.[2] ?? isolate?.[3]) !== "false";
141
+ }
142
+ function resolveRelativeSpecifier(specifier, artDir) {
143
+ if (!specifier.startsWith(".")) return specifier;
144
+ return path.resolve(artDir, specifier);
145
+ }
146
+ function rewriteRelativeImportStatement(statement, artDir) {
147
+ return statement.replace(/\bfrom\s+(['"])([^'"]+)\1/g, (_match, quote, specifier) => `from ${quote}${resolveRelativeSpecifier(specifier, artDir)}${quote}`).replace(/^(\s*import\s+)(['"])([^'"]+)\2(\s*;?\s*)$/s, (_match, prefix, quote, specifier, suffix) => `${prefix}${quote}${resolveRelativeSpecifier(specifier, artDir)}${quote}${suffix}`);
148
+ }
149
+ function countCharBalance(source, openChar, closeChar) {
150
+ let balance = 0;
151
+ for (const char of source) if (char === openChar) balance++;
152
+ else if (char === closeChar) balance--;
153
+ return balance;
154
+ }
155
+ function isCompleteImportStatement(statement) {
156
+ const trimmed = statement.trim();
157
+ if (!trimmed.startsWith("import ")) return false;
158
+ if (countCharBalance(statement, "{", "}") > 0) return false;
159
+ return /^import\s+[\s\S]+?\s+from\s+['"][^'"]+['"]\s*;?$/s.test(trimmed) || /^import\s+['"][^'"]+['"]\s*;?$/s.test(trimmed);
160
+ }
161
+ function splitTopLevelCommaList(source) {
162
+ const parts = [];
163
+ let current = "";
164
+ let braceDepth = 0;
165
+ let bracketDepth = 0;
166
+ let parenDepth = 0;
167
+ for (const char of source) {
168
+ if (char === "," && braceDepth === 0 && bracketDepth === 0 && parenDepth === 0) {
169
+ const trimmed = current.trim();
170
+ if (trimmed) parts.push(trimmed);
171
+ current = "";
172
+ continue;
173
+ }
174
+ current += char;
175
+ if (char === "{") braceDepth++;
176
+ else if (char === "}") braceDepth--;
177
+ else if (char === "[") bracketDepth++;
178
+ else if (char === "]") bracketDepth--;
179
+ else if (char === "(") parenDepth++;
180
+ else if (char === ")") parenDepth--;
181
+ }
182
+ const trimmed = current.trim();
183
+ if (trimmed) parts.push(trimmed);
184
+ return parts;
185
+ }
186
+ function collectImportedNames(statement, returnNames) {
187
+ const fromMatch = statement.replace(/\s+/g, " ").trim().replace(/;$/, "").match(/^import\s+(type\s+)?(.+?)\s+from\s+['"][^'"]+['"]$/);
188
+ if (!fromMatch) return;
189
+ if (fromMatch[1]) return;
190
+ const specifierParts = splitTopLevelCommaList(fromMatch[2].trim());
191
+ const defaultOrNamespace = specifierParts[0]?.trim() ?? "";
192
+ const trailing = specifierParts.slice(1).join(", ").trim();
193
+ if (defaultOrNamespace && !defaultOrNamespace.startsWith("{")) {
194
+ const namespaceMatch = defaultOrNamespace.match(/^\*\s+as\s+([A-Za-z_$][\w$]*)$/);
195
+ if (namespaceMatch) returnNames.add(namespaceMatch[1]);
196
+ else if (!defaultOrNamespace.startsWith("type ")) returnNames.add(defaultOrNamespace);
197
+ }
198
+ const namedBlock = defaultOrNamespace.startsWith("{") ? defaultOrNamespace : trailing.startsWith("{") ? trailing : "";
199
+ if (!namedBlock) return;
200
+ const namedContent = namedBlock.slice(1, -1);
201
+ for (const part of splitTopLevelCommaList(namedContent)) {
202
+ const trimmed = part.trim();
203
+ if (!trimmed || trimmed.startsWith("type ")) continue;
204
+ const alias = trimmed.split(/\s+as\s+/).pop()?.trim();
205
+ if (alias) returnNames.add(alias);
206
+ }
207
+ }
208
+ function importDeclaresName(statement, name) {
209
+ const names = /* @__PURE__ */ new Set();
210
+ collectImportedNames(statement, names);
211
+ return names.has(name);
212
+ }
213
+ function collectObjectDestructuredNames(statement, returnNames) {
214
+ const match = statement.match(/^(?:export\s+)?(?:const|let|var)\s+\{([\s\S]*?)\}\s*=/);
215
+ if (!match) return;
216
+ for (const part of splitTopLevelCommaList(match[1])) {
217
+ let name = part.trim();
218
+ if (!name) continue;
219
+ if (name.startsWith("...")) name = name.slice(3).trim();
220
+ else if (name.includes(":")) name = name.split(":").pop().trim();
221
+ else if (name.includes("=")) name = name.split("=")[0].trim();
222
+ if (name.includes("=")) name = name.split("=")[0].trim();
223
+ if (/^[A-Za-z_$][\w$]*$/.test(name)) returnNames.add(name);
224
+ }
225
+ }
226
+ function collectArrayDestructuredNames(statement, returnNames) {
227
+ const match = statement.match(/^(?:export\s+)?(?:const|let|var)\s+\[([\s\S]*?)\]\s*=/);
228
+ if (!match) return;
229
+ for (const part of splitTopLevelCommaList(match[1])) {
230
+ let name = part.trim();
231
+ if (!name) continue;
232
+ if (name.startsWith("...")) name = name.slice(3).trim();
233
+ if (name.includes("=")) name = name.split("=")[0].trim();
234
+ if (/^[A-Za-z_$][\w$]*$/.test(name)) returnNames.add(name);
235
+ }
236
+ }
237
+ function collectTopLevelReturnNames(setupBody, returnNames) {
238
+ let braceDepth = 0;
239
+ for (let i = 0; i < setupBody.length; i++) {
240
+ const line = setupBody[i];
241
+ const trimmed = line.trim();
242
+ if (braceDepth === 0) {
243
+ if (/^(?:export\s+)?(?:const|let|var)\s+\{/.test(trimmed)) {
244
+ const statementLines = [line];
245
+ let balance = countCharBalance(line, "{", "}") + countCharBalance(line, "[", "]") + countCharBalance(line, "(", ")");
246
+ while (balance > 0 && i + 1 < setupBody.length) {
247
+ i++;
248
+ statementLines.push(setupBody[i]);
249
+ balance += countCharBalance(setupBody[i], "{", "}") + countCharBalance(setupBody[i], "[", "]") + countCharBalance(setupBody[i], "(", ")");
250
+ }
251
+ collectObjectDestructuredNames(statementLines.join("\n"), returnNames);
252
+ continue;
253
+ }
254
+ if (/^(?:export\s+)?(?:const|let|var)\s+\[/.test(trimmed)) {
255
+ const statementLines = [line];
256
+ let balance = countCharBalance(line, "{", "}") + countCharBalance(line, "[", "]") + countCharBalance(line, "(", ")");
257
+ while (balance > 0 && i + 1 < setupBody.length) {
258
+ i++;
259
+ statementLines.push(setupBody[i]);
260
+ balance += countCharBalance(setupBody[i], "{", "}") + countCharBalance(setupBody[i], "[", "]") + countCharBalance(setupBody[i], "(", ")");
261
+ }
262
+ collectArrayDestructuredNames(statementLines.join("\n"), returnNames);
263
+ continue;
264
+ }
265
+ const constMatch = trimmed.match(/^(?:export\s+)?(?:const|let|var)\s+([A-Za-z_$][\w$]*)/);
266
+ if (constMatch) returnNames.add(constMatch[1]);
267
+ const functionMatch = trimmed.match(/^(?:export\s+)?(?:async\s+)?function\s+([A-Za-z_$][\w$]*)\s*\(/);
268
+ if (functionMatch) returnNames.add(functionMatch[1]);
269
+ const classMatch = trimmed.match(/^(?:export\s+)?class\s+([A-Za-z_$][\w$]*)\b/);
270
+ if (classMatch) returnNames.add(classMatch[1]);
271
+ }
272
+ braceDepth += countCharBalance(line, "{", "}");
273
+ }
274
+ }
275
+ /**
276
+ * Parse script setup content into imports and setup body.
277
+ * Returns the import lines, setup body lines, and all identifiers to expose.
278
+ */
279
+ function parseScriptSetupForArt(content) {
280
+ const lines = content.split("\n");
281
+ const imports = [];
282
+ const setupBody = [];
283
+ const returnNames = /* @__PURE__ */ new Set();
284
+ let currentImport = null;
285
+ const defineArtComponent = extractDefineArtComponent(content);
286
+ let defineArtBalance = 0;
287
+ for (const line of lines) {
288
+ const trimmed = line.trim();
289
+ if (defineArtBalance > 0) {
290
+ defineArtBalance += countCharBalance(line, "(", ")");
291
+ continue;
292
+ }
293
+ if (currentImport) {
294
+ currentImport.push(line);
295
+ const statement = currentImport.join("\n");
296
+ if (isCompleteImportStatement(statement)) {
297
+ imports.push(statement);
298
+ collectImportedNames(statement, returnNames);
299
+ currentImport = null;
300
+ }
301
+ continue;
302
+ }
303
+ if (trimmed.startsWith("import ")) {
304
+ currentImport = [line];
305
+ const statement = currentImport.join("\n");
306
+ if (isCompleteImportStatement(statement)) {
307
+ imports.push(statement);
308
+ collectImportedNames(statement, returnNames);
309
+ currentImport = null;
310
+ }
311
+ continue;
312
+ }
313
+ if (isDefineArtLine(trimmed)) {
314
+ defineArtBalance = Math.max(0, countCharBalance(line, "(", ")"));
315
+ continue;
316
+ }
317
+ setupBody.push(line);
318
+ }
319
+ if (currentImport) {
320
+ const statement = currentImport.join("\n");
321
+ imports.push(statement);
322
+ collectImportedNames(statement, returnNames);
323
+ }
324
+ collectTopLevelReturnNames(setupBody, returnNames);
325
+ returnNames.delete("type");
326
+ if (defineArtComponent.name) returnNames.delete(defineArtComponent.name);
327
+ return {
328
+ imports,
329
+ setupBody,
330
+ returnNames: [...returnNames],
331
+ defineArtComponentName: defineArtComponent.name,
332
+ defineArtComponentSource: defineArtComponent.source
333
+ };
334
+ }
335
+ function extractDefineArtComponent(content) {
336
+ const sourceMatch = content.match(/\bdefineArt\s*\(\s*(['"])([^'"]+)\1/);
337
+ if (sourceMatch) return {
338
+ name: componentNameFromSource(sourceMatch[2]),
339
+ source: sourceMatch[2]
340
+ };
341
+ return { name: content.match(/\bdefineArt\s*\(\s*([A-Za-z_$][\w$]*)/)?.[1] };
342
+ }
343
+ function componentNameFromSource(source) {
344
+ const withoutQuery = source.split(/[?#]/, 1)[0] || source;
345
+ const filename = path.basename(withoutQuery);
346
+ const extension = path.extname(filename);
347
+ const name = toPascalCase(extension ? filename.slice(0, -extension.length) : filename);
348
+ return name === "Variant" ? "MuseaComponent" : name;
349
+ }
350
+ function isDefineArtLine(trimmed) {
351
+ return /\bdefineArt\s*\(/.test(trimmed);
352
+ }
353
+ function generateArtModule(art, filePath, options = {}) {
354
+ let componentImportPath;
355
+ let componentTagName;
356
+ let componentBindingName = "__MuseaComponent";
357
+ const scriptSetup = art.scriptSetupContent ? parseScriptSetupForArt(art.scriptSetupContent) : null;
358
+ const defineArtComponentName = scriptSetup?.defineArtComponentName;
359
+ const defineArtComponentSource = scriptSetup?.defineArtComponentSource;
360
+ if (art.isInline && art.componentPath) {
361
+ componentImportPath = options.root ? resolveComponentSourcePath(art, filePath, allowedSourceRoots(options.root, options.scanRoots ?? [])) ?? void 0 : art.componentPath;
362
+ componentTagName = "MuseaComponent";
363
+ } else if (defineArtComponentSource || art.metadata.component) {
364
+ const componentSource = defineArtComponentSource ?? art.metadata.component;
365
+ if (componentSource) {
366
+ const sourceArt = componentSource === art.metadata.component ? art : {
367
+ ...art,
368
+ metadata: {
369
+ ...art.metadata,
370
+ component: componentSource
371
+ }
372
+ };
373
+ componentImportPath = options.root ? resolveComponentSourcePath(sourceArt, filePath, allowedSourceRoots(options.root, options.scanRoots ?? [])) ?? void 0 : path.isAbsolute(componentSource) ? componentSource : path.resolve(path.dirname(filePath), componentSource);
374
+ }
375
+ componentTagName = defineArtComponentName ?? (art.metadata.component ? componentNameFromSource(art.metadata.component) : "MuseaComponent");
376
+ componentBindingName = componentTagName;
377
+ }
378
+ const hasSetupBody = scriptSetup?.setupBody.some((line) => line.trim().length > 0) ?? false;
379
+ const hasSetup = !!scriptSetup && (hasSetupBody || scriptSetup.returnNames.length > 0);
380
+ let code = `
381
+ // Auto-generated module for: ${path.basename(filePath)}
382
+ `;
383
+ if (options.vueVersion === 2 && hasSetup) code += `import { defineComponent as __museaDefineComponent } from 'vue';\n`;
384
+ if (scriptSetup) {
385
+ const artDir = path.dirname(filePath);
386
+ for (const imp of scriptSetup.imports) {
387
+ const resolved = rewriteRelativeImportStatement(imp, artDir);
388
+ code += `${resolved}\n`;
389
+ }
390
+ }
391
+ if (componentImportPath && componentTagName) {
392
+ if (!scriptSetup?.imports.some((imp) => importDeclaresName(imp, componentBindingName))) code += `import ${componentBindingName} from ${JSON.stringify(componentImportPath)};\n`;
393
+ code += `export const __component__ = ${componentBindingName};\n`;
394
+ }
395
+ code += `
396
+ export const metadata = ${JSON.stringify(art.metadata)};
397
+ export const variants = ${JSON.stringify(art.variants)};
398
+ export const __styles__ = ${JSON.stringify(art.styleBlocks ?? [])};
399
+ `;
400
+ const setupReturn = `{ ${scriptSetup?.returnNames.join(", ") ?? ""} }`;
401
+ const isolatedSetup = art.scriptSetupIsolated !== false;
402
+ if (scriptSetup && hasSetup && !isolatedSetup) code += `
403
+ const __museaSharedSetup = (() => {
404
+ ${scriptSetup.setupBody.join("\n")}
405
+ return ${setupReturn};
406
+ })();
407
+ `;
408
+ for (const variant of art.variants) {
409
+ const variantComponentName = toPascalCase(variant.name);
410
+ const template = expandSelfTag(variant.template, componentTagName);
411
+ if (options.vueVersion === 2) {
412
+ code += emitLegacyVariant({
413
+ variantComponentName,
414
+ variantName: variant.name,
415
+ template,
416
+ componentTagName,
417
+ componentBindingName,
418
+ scriptSetup,
419
+ hasSetup,
420
+ isolatedSetup,
421
+ setupReturn,
422
+ importDeclaresName
423
+ });
424
+ continue;
425
+ }
426
+ const variantModuleId = `virtual:musea-variant:${filePath}:${encodeURIComponent(variant.name)}`;
427
+ code += `
428
+ import ${variantComponentName} from ${JSON.stringify(variantModuleId)};
429
+ export { ${variantComponentName} };
430
+ `;
431
+ }
432
+ const defaultVariant = art.variants.find((v) => v.isDefault) || art.variants[0];
433
+ if (defaultVariant) code += `
434
+ export default ${toPascalCase(defaultVariant.name)};
435
+ `;
436
+ return code;
437
+ }
438
+ //#endregion
439
+ //#region src/art-style.ts
440
+ function artScopeAttribute(filePath) {
441
+ return `data-v-${createHash("sha256").update(filePath).digest("hex").slice(0, 8)}`;
442
+ }
443
+ function stampScopeAttribute(template, scopeAttr) {
444
+ return template.replace(/<([A-Za-z][\w:.-]*)([^<>]*?)>/g, (match, tag, rest) => {
445
+ if (rest.includes(scopeAttr)) return match;
446
+ const selfClosing = /\/\s*$/.test(rest);
447
+ const attrs = selfClosing ? rest.replace(/\/\s*$/, "").trimEnd() : rest.trimEnd();
448
+ return `<${tag}${`${attrs.length > 0 && !attrs.startsWith(" ") && !attrs.startsWith("\n") ? " " : ""}${attrs}`.trimEnd()} ${scopeAttr}${selfClosing ? " /" : ""}>`;
449
+ });
450
+ }
451
+ //#endregion
452
+ //#region src/plugin/art-processing.ts
453
+ function extractArtTagAttributes(source) {
454
+ const artTagMatch = source.match(/<art\b([\s\S]*?)>/i);
455
+ if (!artTagMatch) return {};
456
+ const attributes = {};
457
+ for (const match of artTagMatch[1].matchAll(/([^\s=/>]+)(?:\s*=\s*(?:"([^"]*)"|'([^']*)'))?/g)) {
458
+ const name = match[1];
459
+ if (!name || name === "/") continue;
460
+ attributes[name] = match[2] ?? match[3] ?? true;
461
+ }
462
+ return attributes;
463
+ }
464
+ function parseActionEvents(value) {
465
+ if (typeof value !== "string") return void 0;
466
+ const events = value.split(",").map((eventName) => eventName.trim().toLowerCase()).filter(Boolean);
467
+ return events.length > 0 ? [...new Set(events)] : void 0;
468
+ }
469
+ function extractCustomArtMetadata(source) {
470
+ const attrs = extractArtTagAttributes(source);
471
+ const actionEvents = new Set(parseActionEvents(attrs["action-events"]) ?? []);
472
+ const captureMousemove = attrs["capture-mousemove"];
473
+ if (captureMousemove === true || captureMousemove === "true") actionEvents.add("mousemove");
474
+ return { actionEvents: actionEvents.size > 0 ? [...actionEvents] : void 0 };
475
+ }
476
+ function extractStyleBlocks(source, filePath) {
477
+ const styles = [];
478
+ for (const match of source.matchAll(/<style\b([^>]*)>([\s\S]*?)<\/style>/gi)) {
479
+ const attrs = match[1] ?? "";
480
+ const content = match[2]?.trim();
481
+ const lang = attrs.match(/\blang\s*=\s*["']([^"']+)["']/i)?.[1]?.toLowerCase();
482
+ if (!content) continue;
483
+ if (lang && lang !== "css") {
484
+ console.warn(`[musea] ${filePath}: <style lang="${lang}"> is not processed. Art styles are plain CSS.`);
485
+ continue;
486
+ }
487
+ styles.push({
488
+ content,
489
+ scoped: /\bscoped\b/i.test(attrs)
490
+ });
491
+ }
492
+ if (!styles.some((style) => style.scoped)) return { blocks: styles.map((style) => style.content) };
493
+ const scopeAttr = artScopeAttribute(filePath);
494
+ const scope = loadNative().scopeViteCssForPipeline;
495
+ return {
496
+ scopeAttr,
497
+ blocks: styles.map((style) => style.scoped && scope ? scope(style.content, scopeAttr) : style.content)
498
+ };
499
+ }
500
+ function formatArtProcessingError(root, filePath, error) {
501
+ const detail = error instanceof Error ? error.message || error.name : error == null ? "unknown error" : stringifyUnknown(error);
502
+ return `[musea] Failed to process ${path.relative(root, filePath) || filePath}: ${detail}`;
503
+ }
504
+ function stringifyUnknown(value) {
505
+ if (typeof value === "string") return value;
506
+ if (typeof value === "number" || typeof value === "boolean" || typeof value === "bigint") return value.toString();
507
+ try {
508
+ return JSON.stringify(value) ?? "unknown error";
509
+ } catch {
510
+ return "unknown error";
511
+ }
512
+ }
513
+ function reportArtStatusWarnings(binding, source, filename, warn = console.warn) {
514
+ const warnings = binding.parseArtStatusWarnings?.(source, { filename });
515
+ if (warnings == null) return;
516
+ for (const warning of warnings) warn(`[musea] ${warning}`);
517
+ }
518
+ async function processMuseaArtFile(filePath, ctx) {
519
+ try {
520
+ const source = await fs.promises.readFile(filePath, "utf-8");
521
+ const binding = loadNative();
522
+ const parsed = binding.parseArt(source, { filename: filePath });
523
+ reportArtStatusWarnings(binding, source, filePath);
524
+ const customMetadata = extractCustomArtMetadata(source);
525
+ if (!parsed.variants || parsed.variants.length === 0) return null;
526
+ const isInline = !filePath.endsWith(".art.vue");
527
+ const styles = isInline ? { blocks: [] } : extractStyleBlocks(source, filePath);
528
+ return {
529
+ path: filePath,
530
+ metadata: {
531
+ title: parsed.metadata.title || (isInline ? path.basename(filePath, ".vue") : ""),
532
+ description: parsed.metadata.description,
533
+ component: isInline ? void 0 : parsed.metadata.component,
534
+ category: parsed.metadata.category,
535
+ tags: parsed.metadata.tags,
536
+ status: parsed.metadata.status,
537
+ order: parsed.metadata.order,
538
+ actionEvents: customMetadata.actionEvents ?? parsed.metadata.actionEvents
539
+ },
540
+ variants: parsed.variants.map((v) => ({
541
+ name: v.name,
542
+ template: styles.scopeAttr ? stampScopeAttribute(v.template, styles.scopeAttr) : v.template,
543
+ isDefault: v.isDefault,
544
+ skipVrt: v.skipVrt
545
+ })),
546
+ hasScriptSetup: isInline ? false : parsed.hasScriptSetup,
547
+ scriptSetupContent: !isInline && parsed.hasScriptSetup ? extractScriptSetupContent(source) : void 0,
548
+ scriptSetupIsolated: !isInline && parsed.hasScriptSetup ? extractScriptSetupIsolated(source) : true,
549
+ hasScript: parsed.hasScript,
550
+ styleCount: parsed.styleCount,
551
+ styleBlocks: styles.blocks,
552
+ isInline,
553
+ componentPath: isInline ? filePath : void 0
554
+ };
555
+ } catch (error) {
556
+ const message = formatArtProcessingError(ctx.root, filePath, error);
557
+ if (ctx.command === "build") throw new Error(message);
558
+ (ctx.onError ?? console.error)(message);
559
+ return null;
560
+ }
561
+ }
562
+ //#endregion
563
+ //#region src/plugin/options.ts
564
+ const MUSEA_OPTIONS_KEY = "__vizeMuseaOptions";
565
+ function attachMuseaOptions(plugin, options) {
566
+ Object.defineProperty(plugin, MUSEA_OPTIONS_KEY, {
567
+ configurable: false,
568
+ enumerable: false,
569
+ value: options,
570
+ writable: false
571
+ });
572
+ return plugin;
573
+ }
574
+ function readMuseaOptions(plugin) {
575
+ if (!plugin || typeof plugin !== "object") return void 0;
576
+ return plugin[MUSEA_OPTIONS_KEY];
577
+ }
578
+ //#endregion
579
+ export { parseScriptSetupForArt as a, resolveArtComponent as c, resolveReadableArtPath as d, generateArtModule as i, allowedSourceRoots as l, readMuseaOptions as n, rewriteRelativeImportStatement as o, processMuseaArtFile as r, expandSelfTag as s, attachMuseaOptions as t, resolveComponentSourcePath as u };
580
+
581
+ //# sourceMappingURL=options-CZYdDtTW.mjs.map