@vizejs/nuxt 0.159.0 → 0.161.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 (2) hide show
  1. package/dist/index.mjs +87 -24
  2. package/package.json +5 -5
package/dist/index.mjs CHANGED
@@ -7,6 +7,7 @@ import path from "node:path";
7
7
  import { createHash } from "node:crypto";
8
8
  //#region src/components.ts
9
9
  const COMPONENT_CALL_RE = /_?resolveComponent\s*\(\s*["'`]([^"'`]+)["'`]\s*(?:,\s*[^)]+)?\)/g;
10
+ const COMPONENTS_IMPORT_RE = /import\s+(?!type\b)\{([^}]*)\}\s+from\s+(["'])#components\2\s*;?/g;
10
11
  const COMPONENT_EXT_RE = /\.(?:[cm]?js|ts|vue)$/;
11
12
  const DTS_COMPONENT_RE = /^export const (\w+): (?:LazyComponent<)?typeof import\((["'])(.+?)\2\)(?:\.([A-Za-z_$][\w$]*)|\[['"]([A-Za-z_$][\w$]*)['"]\])>?/;
12
13
  const DTS_EXT_RE = /\.d\.ts$/;
@@ -23,6 +24,7 @@ const RUNTIME_COMPONENT_DIRS = [
23
24
  "dist/runtime/components/nuxt4",
24
25
  "runtime/components"
25
26
  ];
27
+ const IMPORT_SPECIFIER_RE = /^(type\s+)?([A-Za-z_$][\w$]*)(?:\s+as\s+([A-Za-z_$][\w$]*))?$/;
26
28
  function toKebabCase(name) {
27
29
  return name.replace(/([a-z0-9])([A-Z])/g, "$1-$2").replace(/_/g, "-").toLowerCase();
28
30
  }
@@ -56,16 +58,70 @@ function detectComponentMode(filePath) {
56
58
  if (CLIENT_COMPONENT_RE.test(filePath)) return "client";
57
59
  if (SERVER_COMPONENT_RE.test(filePath)) return "server";
58
60
  }
59
- function createComponentImport(filePath, exportName, lazy) {
61
+ function normalizeComponentMode(mode) {
62
+ return mode === "client" || mode === "server" ? mode : void 0;
63
+ }
64
+ function parseComponentImportSpecifier(raw) {
65
+ const trimmed = raw.trim();
66
+ if (!trimmed) return null;
67
+ const match = trimmed.match(IMPORT_SPECIFIER_RE);
68
+ if (!match) return null;
69
+ const [, typeKeyword, importedName, localName] = match;
70
+ return {
71
+ importedName,
72
+ localName: localName || importedName,
73
+ typeOnly: Boolean(typeKeyword)
74
+ };
75
+ }
76
+ function splitComponentImportSpecifiers(specifiers) {
77
+ return specifiers.split(",").map((specifier) => specifier.trim()).filter(Boolean);
78
+ }
79
+ function createComponentImport(filePath, exportName, lazy, mode) {
60
80
  const componentImport = {
61
81
  exportName,
62
82
  filePath
63
83
  };
64
84
  if (lazy) componentImport.lazy = true;
65
- const mode = detectComponentMode(filePath);
66
- if (mode) componentImport.mode = mode;
85
+ const resolvedMode = normalizeComponentMode(mode) ?? detectComponentMode(filePath);
86
+ if (resolvedMode) componentImport.mode = resolvedMode;
67
87
  return componentImport;
68
88
  }
89
+ function addResolvedComponentBinding(componentImports, resolved, variableName, rawVariableName) {
90
+ let needsCreateClientOnly = false;
91
+ let needsDefineAsyncComponent = false;
92
+ if (resolved.lazy) {
93
+ needsDefineAsyncComponent = true;
94
+ const exportAccessor = resolved.exportName === "default" ? "module.default" : `module[${JSON.stringify(resolved.exportName)}]`;
95
+ if (resolved.mode === "client") {
96
+ needsCreateClientOnly = true;
97
+ componentImports.push(`const ${variableName} = __nuxt_define_async_component(() => import(${JSON.stringify(resolved.filePath)}).then((module) => __nuxt_create_client_only(${exportAccessor})));`);
98
+ } else componentImports.push(`const ${variableName} = __nuxt_define_async_component(() => import(${JSON.stringify(resolved.filePath)}).then((module) => ${exportAccessor}));`);
99
+ return {
100
+ needsCreateClientOnly,
101
+ needsDefineAsyncComponent
102
+ };
103
+ }
104
+ if (resolved.exportName === "default") {
105
+ if (resolved.mode === "client") {
106
+ needsCreateClientOnly = true;
107
+ componentImports.push(`import ${rawVariableName} from ${JSON.stringify(resolved.filePath)};`);
108
+ componentImports.push(`const ${variableName} = __nuxt_create_client_only(${rawVariableName});`);
109
+ } else componentImports.push(`import ${variableName} from ${JSON.stringify(resolved.filePath)};`);
110
+ return {
111
+ needsCreateClientOnly,
112
+ needsDefineAsyncComponent
113
+ };
114
+ }
115
+ if (resolved.mode === "client") {
116
+ needsCreateClientOnly = true;
117
+ componentImports.push(`import { ${resolved.exportName} as ${rawVariableName} } from ${JSON.stringify(resolved.filePath)};`);
118
+ componentImports.push(`const ${variableName} = __nuxt_create_client_only(${rawVariableName});`);
119
+ } else componentImports.push(`import { ${resolved.exportName} as ${variableName} } from ${JSON.stringify(resolved.filePath)};`);
120
+ return {
121
+ needsCreateClientOnly,
122
+ needsDefineAsyncComponent
123
+ };
124
+ }
69
125
  function getNuxtComponentDtsFiles(rootDir, buildDir) {
70
126
  const candidates = [
71
127
  path.join(buildDir, "components.d.ts"),
@@ -153,7 +209,7 @@ function createNuxtComponentResolver(options) {
153
209
  return {
154
210
  register(components) {
155
211
  for (const component of components) {
156
- const resolved = createComponentImport(component.filePath, component.export || "default");
212
+ const resolved = createComponentImport(component.filePath, component.export || "default", false, component.mode);
157
213
  addComponentAlias(registered, component.pascalName, resolved);
158
214
  addComponentAlias(registered, component.kebabName, resolved);
159
215
  addComponentAlias(registered, component.name, resolved);
@@ -175,9 +231,32 @@ function injectNuxtComponentImports(code, resolveComponentImport) {
175
231
  const componentImports = [];
176
232
  const importedComponents = /* @__PURE__ */ new Map();
177
233
  let counter = 0;
234
+ let importCounter = 0;
178
235
  let needsDefineAsyncComponent = false;
179
236
  let needsCreateClientOnly = false;
180
- const nextCode = code.replace(COMPONENT_CALL_RE, (match, name) => {
237
+ const nextCode = code.replace(COMPONENTS_IMPORT_RE, (match, specifiers) => {
238
+ const unresolvedSpecifiers = [];
239
+ let changed = false;
240
+ for (const rawSpecifier of splitComponentImportSpecifiers(specifiers)) {
241
+ const specifier = parseComponentImportSpecifier(rawSpecifier);
242
+ if (!specifier || specifier.typeOnly) {
243
+ unresolvedSpecifiers.push(rawSpecifier);
244
+ continue;
245
+ }
246
+ const resolved = resolveComponentImport(specifier.importedName);
247
+ if (!resolved) {
248
+ unresolvedSpecifiers.push(rawSpecifier);
249
+ continue;
250
+ }
251
+ changed = true;
252
+ const result = addResolvedComponentBinding(componentImports, resolved, specifier.localName, `__nuxt_import_component_${importCounter++}_raw`);
253
+ needsCreateClientOnly ||= result.needsCreateClientOnly;
254
+ needsDefineAsyncComponent ||= result.needsDefineAsyncComponent;
255
+ }
256
+ if (!changed) return match;
257
+ if (unresolvedSpecifiers.length === 0) return "";
258
+ return `import { ${unresolvedSpecifiers.join(", ")} } from "#components";`;
259
+ }).replace(COMPONENT_CALL_RE, (match, name) => {
181
260
  const resolved = resolveComponentImport(name);
182
261
  if (!resolved) return match;
183
262
  const importKey = `${resolved.exportName}\u0000${resolved.filePath}\u0000${resolved.lazy ? "lazy" : "eager"}\u0000${resolved.mode ?? "default"}`;
@@ -185,25 +264,9 @@ function injectNuxtComponentImports(code, resolveComponentImport) {
185
264
  if (!variableName) {
186
265
  variableName = `__nuxt_component_${counter++}`;
187
266
  importedComponents.set(importKey, variableName);
188
- if (resolved.lazy) {
189
- needsDefineAsyncComponent = true;
190
- const exportAccessor = resolved.exportName === "default" ? "module.default" : `module[${JSON.stringify(resolved.exportName)}]`;
191
- if (resolved.mode === "client") {
192
- needsCreateClientOnly = true;
193
- componentImports.push(`const ${variableName} = __nuxt_define_async_component(() => import(${JSON.stringify(resolved.filePath)}).then((module) => __nuxt_create_client_only(${exportAccessor})));`);
194
- } else componentImports.push(`const ${variableName} = __nuxt_define_async_component(() => import(${JSON.stringify(resolved.filePath)}).then((module) => ${exportAccessor}));`);
195
- } else if (resolved.exportName === "default") if (resolved.mode === "client") {
196
- needsCreateClientOnly = true;
197
- const rawVariableName = `${variableName}_raw`;
198
- componentImports.push(`import ${rawVariableName} from ${JSON.stringify(resolved.filePath)};`);
199
- componentImports.push(`const ${variableName} = __nuxt_create_client_only(${rawVariableName});`);
200
- } else componentImports.push(`import ${variableName} from ${JSON.stringify(resolved.filePath)};`);
201
- else if (resolved.mode === "client") {
202
- needsCreateClientOnly = true;
203
- const rawVariableName = `${variableName}_raw`;
204
- componentImports.push(`import { ${resolved.exportName} as ${rawVariableName} } from ${JSON.stringify(resolved.filePath)};`);
205
- componentImports.push(`const ${variableName} = __nuxt_create_client_only(${rawVariableName});`);
206
- } else componentImports.push(`import { ${resolved.exportName} as ${variableName} } from ${JSON.stringify(resolved.filePath)};`);
267
+ const result = addResolvedComponentBinding(componentImports, resolved, variableName, `${variableName}_raw`);
268
+ needsCreateClientOnly ||= result.needsCreateClientOnly;
269
+ needsDefineAsyncComponent ||= result.needsDefineAsyncComponent;
207
270
  }
208
271
  return variableName;
209
272
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vizejs/nuxt",
3
- "version": "0.159.0",
3
+ "version": "0.161.0",
4
4
  "description": "Nuxt module for Vize - compiler, musea gallery, linter, and type checker",
5
5
  "keywords": [
6
6
  "compiler",
@@ -41,10 +41,10 @@
41
41
  },
42
42
  "dependencies": {
43
43
  "@nuxt/kit": "4.4.6",
44
- "@vizejs/musea-nuxt": "0.159.0",
45
- "@vizejs/vite-plugin": "0.159.0",
46
- "@vizejs/vite-plugin-musea": "0.159.0",
47
- "vize": "0.159.0"
44
+ "@vizejs/musea-nuxt": "0.161.0",
45
+ "@vizejs/vite-plugin": "0.161.0",
46
+ "@vizejs/vite-plugin-musea": "0.161.0",
47
+ "vize": "0.161.0"
48
48
  },
49
49
  "devDependencies": {
50
50
  "typescript": "6.0.3",