@vizejs/musea-nuxt 0.269.0 → 0.270.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -1,50 +1,34 @@
1
- import { createRequire } from "node:module";
2
1
  import path from "node:path";
3
2
  import { fileURLToPath } from "node:url";
4
- import { computed, defineComponent, h, reactive, ref } from "vue";
5
- //#region \0rolldown/runtime.js
6
- var __require = /* @__PURE__ */ createRequire(import.meta.url);
7
- //#endregion
3
+ import { computed, defineComponent, h, reactive, ref, toValue } from "vue";
8
4
  //#region src/plugin.ts
9
5
  const VIRTUAL_IMPORTS_ID = "\0musea-nuxt:imports";
10
- const VIRTUAL_IMPORTS_MODULE = "#imports";
11
6
  const VIRTUAL_NUXT_COMPONENTS_ID = "\0musea-nuxt:components";
7
+ const NUXT_IMPORT_IDS = new Set([
8
+ "#imports",
9
+ "#app",
10
+ "#build",
11
+ "nuxt/app"
12
+ ]);
13
+ const NUXT_COMPONENT_IDS = new Set([
14
+ "#components",
15
+ "#build/components",
16
+ "nuxt/dist/app/components"
17
+ ]);
12
18
  function createNuxtMuseaPlugin(options = {}) {
13
19
  const srcDir = path.dirname(fileURLToPath(import.meta.url));
14
20
  return {
15
21
  name: "vite-plugin-musea-nuxt",
16
22
  enforce: "pre",
17
- config() {
18
- return { resolve: { alias: {
19
- "#imports": VIRTUAL_IMPORTS_MODULE,
20
- "#app": VIRTUAL_IMPORTS_MODULE,
21
- "#build": VIRTUAL_IMPORTS_MODULE
22
- } } };
23
- },
24
23
  resolveId(id) {
25
- if (id === VIRTUAL_IMPORTS_MODULE || id === "#imports" || id === "#app" || id === "#build") return VIRTUAL_IMPORTS_ID;
26
- if (id === "#components" || id === "nuxt/dist/app/components") return VIRTUAL_NUXT_COMPONENTS_ID;
24
+ if (NUXT_COMPONENT_IDS.has(id)) return VIRTUAL_NUXT_COMPONENTS_ID;
25
+ if (NUXT_IMPORT_IDS.has(id) || id.startsWith("#app/") || id.startsWith("#build/")) return VIRTUAL_IMPORTS_ID;
27
26
  return null;
28
27
  },
29
28
  load(id) {
30
29
  if (id === VIRTUAL_IMPORTS_ID) return generateImportsModule(srcDir, options);
31
30
  if (id === VIRTUAL_NUXT_COMPONENTS_ID) return generateComponentsModule(srcDir);
32
31
  return null;
33
- },
34
- transform(code, id) {
35
- if (id.endsWith(".vue") || id.endsWith(".art.vue")) {
36
- if (code.includes("<NuxtLink") || code.includes("<nuxt-link")) {
37
- if (!code.includes("NuxtLink")) {
38
- const importLine = `import { NuxtLink } from '${VIRTUAL_IMPORTS_MODULE}';\n`;
39
- const lastImportIdx = code.lastIndexOf("import ");
40
- if (lastImportIdx !== -1) {
41
- const lineEnd = code.indexOf("\n", lastImportIdx);
42
- code = code.slice(0, lineEnd + 1) + importLine + code.slice(lineEnd + 1);
43
- }
44
- }
45
- }
46
- }
47
- return code;
48
32
  }
49
33
  };
50
34
  }
@@ -56,15 +40,10 @@ function generateImportsModule(srcDir, options) {
56
40
  export * from '${autoImportsPath}';
57
41
 
58
42
  // Configure mocks with provided options
59
- import { _setRouteConfig } from '${path.join(srcDir, "mocks", "composables.js").replace(/\\/g, "/")}';
60
- import { _setFetchMocks } from '${path.join(srcDir, "mocks", "data.js").replace(/\\/g, "/")}';
61
- import { _setRuntimeConfig, _setStateMocks } from '${path.join(srcDir, "mocks", "runtime.js").replace(/\\/g, "/")}';
43
+ import { configureNuxtMuseaMocks } from '${path.join(srcDir, "context.js").replace(/\\/g, "/")}';
62
44
 
63
45
  const _config = ${configJson};
64
- _setRouteConfig(_config.route);
65
- _setFetchMocks(_config.fetchMocks ?? {});
66
- _setRuntimeConfig(_config.runtimeConfig);
67
- _setStateMocks(_config.stateMocks ?? {});
46
+ configureNuxtMuseaMocks(_config);
68
47
  `;
69
48
  }
70
49
  function generateComponentsModule(srcDir) {
@@ -77,122 +56,184 @@ export {
77
56
  NuxtLayout,
78
57
  NuxtLoadingIndicator,
79
58
  NuxtErrorBoundary,
59
+ NuxtRouteAnnouncer,
60
+ NuxtWelcome,
61
+ NuxtIsland,
62
+ NuxtClientFallback,
63
+ NuxtImg,
64
+ NuxtPicture,
80
65
  } from '${path.join(srcDir, "mocks", "components.js").replace(/\\/g, "/")}';
81
66
  `;
82
67
  }
83
68
  //#endregion
84
- //#region src/mocks/composables.ts
85
- /**
86
- * Mock Nuxt routing composables.
87
- */
88
- let _routeConfig = {};
89
- /**
90
- * Mock useRoute - returns a reactive route object.
91
- */
92
- function useRoute() {
93
- return reactive({
94
- path: _routeConfig?.path ?? "/",
95
- name: _routeConfig?.name ?? "index",
96
- params: _routeConfig?.params ?? {},
97
- query: _routeConfig?.query ?? {},
98
- hash: _routeConfig?.hash ?? "",
99
- fullPath: _routeConfig?.fullPath ?? _routeConfig?.path ?? "/",
100
- meta: _routeConfig?.meta ?? {},
101
- matched: [],
102
- redirectedFrom: void 0
69
+ //#region src/context.ts
70
+ const DEFAULT_REQUEST_URL = "http://localhost:3000/";
71
+ const routeState = reactive(createRoute({}));
72
+ const runtimeConfigState = reactive({ public: {} });
73
+ const appConfigState = reactive({});
74
+ const requestState = reactive({
75
+ url: DEFAULT_REQUEST_URL,
76
+ headers: {}
77
+ });
78
+ const stateRefs = /* @__PURE__ */ new Map();
79
+ const cookieRefs = /* @__PURE__ */ new Map();
80
+ const callOnceKeys = /* @__PURE__ */ new Set();
81
+ const fetchMocksState = {};
82
+ const errorRef = ref(null);
83
+ let idCounter = 0;
84
+ function configureNuxtMuseaMocks(options = {}) {
85
+ setRouteConfig(options.route ?? {});
86
+ setRuntimeConfig(options.runtimeConfig ?? {});
87
+ setAppConfig(options.appConfig ?? {});
88
+ setFetchMocks(options.fetchMocks ?? {});
89
+ setStateMocks(options.stateMocks ?? {});
90
+ setCookieMocks(options.cookieMocks ?? {});
91
+ setRequestConfig(options.request ?? {});
92
+ }
93
+ function resetNuxtMuseaMocks() {
94
+ setRouteConfig({});
95
+ setRuntimeConfig({});
96
+ setAppConfig({});
97
+ setFetchMocks({});
98
+ setRequestConfig({});
99
+ stateRefs.clear();
100
+ cookieRefs.clear();
101
+ callOnceKeys.clear();
102
+ errorRef.value = null;
103
+ idCounter = 0;
104
+ }
105
+ function getRouteState() {
106
+ return routeState;
107
+ }
108
+ function setRouteConfig(config) {
109
+ Object.assign(routeState, createRoute(config));
110
+ }
111
+ function resolveNavigationTarget(target) {
112
+ if (typeof target === "string") return createRoute({ path: target });
113
+ return createRoute({
114
+ path: target.path,
115
+ name: target.name ?? null,
116
+ params: target.params,
117
+ query: target.query,
118
+ hash: target.hash,
119
+ meta: typeof target.meta === "object" && target.meta != null ? target.meta : void 0
103
120
  });
104
121
  }
105
- /**
106
- * Mock useRouter - returns a router-like object with no-op navigation.
107
- */
108
- function useRouter() {
109
- return {
110
- push: async (_to) => {},
111
- replace: async (_to) => {},
112
- back: () => {},
113
- forward: () => {},
114
- go: (_delta) => {},
115
- resolve: (to) => ({
116
- href: typeof to === "string" ? to : "/",
117
- route: useRoute()
118
- }),
119
- currentRoute: computed(() => useRoute()),
120
- addRoute: () => () => {},
121
- removeRoute: () => {},
122
- hasRoute: () => false,
123
- getRoutes: () => [],
124
- beforeEach: () => () => {},
125
- afterEach: () => () => {},
126
- onError: () => () => {},
127
- isReady: () => Promise.resolve(),
128
- options: {}
129
- };
122
+ function getRuntimeConfigState() {
123
+ return runtimeConfigState;
130
124
  }
131
- //#endregion
132
- //#region src/mocks/data.ts
133
- /**
134
- * Mock Nuxt data-fetching composables.
135
- */
136
- let _fetchMocks = {};
137
- function findMockData(key) {
138
- if (key in _fetchMocks) return _fetchMocks[key];
139
- for (const [pattern, data] of Object.entries(_fetchMocks)) if (key.includes(pattern)) return data;
125
+ function setRuntimeConfig(config) {
126
+ replaceRecord(runtimeConfigState, {
127
+ public: {},
128
+ ...config
129
+ });
140
130
  }
141
- /**
142
- * Mock useFetch - returns reactive data based on mock config.
143
- */
144
- function useFetch(url, _opts) {
145
- const data = ref(findMockData(typeof url === "function" ? url() : url) ?? null);
146
- const pending = ref(false);
147
- const error = ref(null);
148
- const status = ref("success");
149
- const refresh = async () => {};
150
- const execute = async () => {};
151
- return {
152
- data,
153
- pending,
154
- error,
155
- refresh,
156
- execute,
157
- status
158
- };
131
+ function getAppConfigState() {
132
+ return appConfigState;
159
133
  }
160
- /**
161
- * Mock useAsyncData - similar to useFetch but with key-based lookup.
162
- */
163
- function useAsyncData(key, _handler, _opts) {
164
- const data = ref(findMockData(key) ?? null);
165
- const pending = ref(false);
166
- const error = ref(null);
167
- const status = ref("success");
168
- const refresh = async () => {};
169
- const execute = async () => {};
134
+ function setAppConfig(config) {
135
+ replaceRecord(appConfigState, config);
136
+ }
137
+ function updateAppConfigState(config) {
138
+ Object.assign(appConfigState, config);
139
+ }
140
+ function getFetchMocks() {
141
+ return fetchMocksState;
142
+ }
143
+ function setFetchMocks(mocks) {
144
+ replaceRecord(fetchMocksState, mocks);
145
+ }
146
+ function getStateRef(key, init) {
147
+ const existing = stateRefs.get(key);
148
+ if (existing) return existing;
149
+ const state = ref(init ? init() : void 0);
150
+ stateRefs.set(key, state);
151
+ return state;
152
+ }
153
+ function setStateMocks(mocks) {
154
+ stateRefs.clear();
155
+ for (const [key, value] of Object.entries(mocks)) stateRefs.set(key, ref(value));
156
+ }
157
+ function clearStateRefs(keys) {
158
+ if (keys == null) {
159
+ stateRefs.clear();
160
+ return;
161
+ }
162
+ for (const key of Array.isArray(keys) ? keys : [keys]) stateRefs.delete(key);
163
+ }
164
+ function getCookieRef(name, init) {
165
+ const existing = cookieRefs.get(name);
166
+ if (existing) return existing;
167
+ const cookie = ref(init ? init() : void 0);
168
+ cookieRefs.set(name, cookie);
169
+ return cookie;
170
+ }
171
+ function setCookieMocks(mocks) {
172
+ cookieRefs.clear();
173
+ for (const [key, value] of Object.entries(mocks)) cookieRefs.set(key, ref(value));
174
+ }
175
+ function getRequestState() {
176
+ return requestState;
177
+ }
178
+ function setRequestConfig(request) {
179
+ requestState.url = request.url ?? DEFAULT_REQUEST_URL;
180
+ requestState.headers = { ...request.headers };
181
+ }
182
+ function getErrorRef() {
183
+ return errorRef;
184
+ }
185
+ function setError(error) {
186
+ errorRef.value = error;
187
+ }
188
+ function nextNuxtId() {
189
+ idCounter += 1;
190
+ return `musea-nuxt-${idCounter}`;
191
+ }
192
+ async function runCallOnce(key, fn) {
193
+ if (callOnceKeys.has(key)) return;
194
+ callOnceKeys.add(key);
195
+ return await fn();
196
+ }
197
+ function createRoute(config) {
198
+ const path = config.path ?? "/";
199
+ const query = { ...config.query };
200
+ const hash = normalizeHash(config.hash ?? "");
170
201
  return {
171
- data,
172
- pending,
173
- error,
174
- refresh,
175
- execute,
176
- status
202
+ path,
203
+ name: config.name ?? inferRouteName(path),
204
+ params: { ...config.params },
205
+ query,
206
+ hash,
207
+ fullPath: config.fullPath ?? buildFullPath(path, query, hash),
208
+ meta: { ...config.meta },
209
+ matched: [...config.matched ?? []],
210
+ redirectedFrom: config.redirectedFrom
177
211
  };
178
212
  }
179
- /**
180
- * Mock useLazyFetch - lazy variant of useFetch.
181
- */
182
- function useLazyFetch(url, opts) {
183
- return useFetch(url, {
184
- ...opts,
185
- lazy: true
186
- });
213
+ function inferRouteName(path) {
214
+ const normalized = path.replace(/^\/+|\/+$/g, "");
215
+ return normalized.length === 0 ? "index" : normalized.replace(/[^A-Za-z0-9_]+/g, "-");
187
216
  }
188
- /**
189
- * Mock useLazyAsyncData - lazy variant of useAsyncData.
190
- */
191
- function useLazyAsyncData(key, handler, opts) {
192
- return useAsyncData(key, handler, {
193
- ...opts,
194
- lazy: true
195
- });
217
+ function buildFullPath(path, query, hash) {
218
+ const searchParams = new URLSearchParams();
219
+ for (const [key, value] of Object.entries(query)) {
220
+ if (value == null) continue;
221
+ if (Array.isArray(value)) {
222
+ for (const item of value) searchParams.append(key, item);
223
+ continue;
224
+ }
225
+ searchParams.set(key, value);
226
+ }
227
+ const search = searchParams.toString();
228
+ return `${path}${search ? `?${search}` : ""}${hash}`;
229
+ }
230
+ function normalizeHash(hash) {
231
+ if (!hash) return "";
232
+ return hash.startsWith("#") ? hash : `#${hash}`;
233
+ }
234
+ function replaceRecord(target, value) {
235
+ for (const key of Object.keys(target)) delete target[key];
236
+ Object.assign(target, value);
196
237
  }
197
238
  //#endregion
198
239
  //#region src/mocks/navigation.ts
@@ -200,78 +241,78 @@ function useLazyAsyncData(key, handler, opts) {
200
241
  * Mock Nuxt navigation utilities.
201
242
  */
202
243
  /**
203
- * Mock navigateTo - no-op in gallery context.
244
+ * Mock navigateTo - updates the shared route state in gallery context.
204
245
  */
205
- function navigateTo(_to, _opts) {
246
+ function navigateTo(to, _opts) {
247
+ setRouteConfig(resolveNavigationTarget(to));
206
248
  return Promise.resolve();
207
249
  }
208
250
  /**
209
251
  * Mock abortNavigation - no-op in gallery context.
210
252
  */
211
253
  function abortNavigation(_err) {}
212
- //#endregion
213
- //#region src/mocks/head.ts
214
254
  /**
215
- * Mock Nuxt head management composables.
216
- * All are no-ops in the gallery context.
255
+ * Mock defineNuxtRouteMiddleware - returns the middleware function as-is.
217
256
  */
257
+ function defineNuxtRouteMiddleware(middleware) {
258
+ return middleware;
259
+ }
218
260
  /**
219
- * Mock useHead - no-op.
220
- */
221
- function useHead(_input) {}
222
- /**
223
- * Mock useSeoMeta - no-op.
224
- */
225
- function useSeoMeta(_input) {}
226
- //#endregion
227
- //#region src/mocks/runtime.ts
228
- /**
229
- * Mock Nuxt runtime composables.
261
+ * Mock definePageMeta - page metadata is handled by Nuxt at build time.
230
262
  */
231
- let _runtimeConfig = {};
232
- let _stateMocks = {};
263
+ function definePageMeta(_meta) {}
233
264
  /**
234
- * Mock useNuxtApp - returns a minimal Nuxt app-like object.
265
+ * Mock setPageLayout - no layout switching in isolated previews.
235
266
  */
236
- function useNuxtApp() {
237
- return {
238
- $config: reactive({
239
- public: _runtimeConfig?.public ?? {},
240
- ..._runtimeConfig
241
- }),
242
- provide: (_name, _value) => {},
243
- hook: (_name, _fn) => {},
244
- callHook: async (_name, ..._args) => {},
245
- vueApp: null,
246
- payload: reactive({
247
- data: {},
248
- state: {}
249
- }),
250
- isHydrating: false,
251
- runWithContext: (fn) => fn()
252
- };
267
+ function setPageLayout(_layout) {}
268
+ function prefetchComponents(_to) {
269
+ return Promise.resolve();
270
+ }
271
+ function preloadComponents(_to) {
272
+ return Promise.resolve();
253
273
  }
274
+ function preloadRouteComponents(_to) {
275
+ return Promise.resolve();
276
+ }
277
+ //#endregion
278
+ //#region src/mocks/composables.ts
254
279
  /**
255
- * Mock useRuntimeConfig - returns the configured runtime config.
280
+ * Mock Nuxt routing composables.
256
281
  */
257
- function useRuntimeConfig() {
258
- return reactive({
259
- public: _runtimeConfig?.public ?? {},
260
- ..._runtimeConfig
261
- });
262
- }
263
282
  /**
264
- * Mock useState - returns a ref initialized from mock config or init function.
283
+ * Mock useRoute - returns a reactive route object.
265
284
  */
266
- function useState(key, init) {
267
- if (key in _stateMocks) return ref(_stateMocks[key]);
268
- return ref(init ? init() : void 0);
285
+ function useRoute() {
286
+ return getRouteState();
269
287
  }
270
288
  /**
271
- * Mock useCookie - returns a ref-like cookie mock.
289
+ * Mock useRouter - returns a router-like object with no-op navigation.
272
290
  */
273
- function useCookie(_name, _opts) {
274
- return ref(void 0);
291
+ function useRouter() {
292
+ const navigate = async (to) => {
293
+ setRouteConfig(resolveNavigationTarget(to));
294
+ };
295
+ return {
296
+ push: navigate,
297
+ replace: navigate,
298
+ back: () => {},
299
+ forward: () => {},
300
+ go: (_delta) => {},
301
+ resolve: (to) => ({
302
+ href: resolveNavigationTarget(to).fullPath,
303
+ route: resolveNavigationTarget(to)
304
+ }),
305
+ currentRoute: computed(() => useRoute()),
306
+ addRoute: () => () => {},
307
+ removeRoute: () => {},
308
+ hasRoute: () => false,
309
+ getRoutes: () => [],
310
+ beforeEach: () => () => {},
311
+ afterEach: () => () => {},
312
+ onError: () => () => {},
313
+ isReady: () => Promise.resolve(),
314
+ options: {}
315
+ };
275
316
  }
276
317
  //#endregion
277
318
  //#region src/mocks/components.ts
@@ -323,27 +364,35 @@ const NuxtLink = defineComponent({
323
364
  exactActiveClass: {
324
365
  type: String,
325
366
  default: "router-link-exact-active"
367
+ },
368
+ custom: {
369
+ type: Boolean,
370
+ default: false
326
371
  }
327
372
  },
328
373
  setup(props, { slots }) {
329
374
  return () => {
330
- const to = props.href || props.to;
331
- if (props.external || typeof to === "string" && to.startsWith("http")) return h("a", {
332
- href: typeof to === "string" ? to : "/",
375
+ const target = props.href ?? props.to;
376
+ const href = typeof target === "string" ? target : routeTargetToHref(target);
377
+ const navigate = () => navigateTo(target, { replace: props.replace });
378
+ if (props.custom) return slots.default?.({
379
+ href,
380
+ navigate,
381
+ route: useRoute(),
382
+ isActive: false,
383
+ isExactActive: false
384
+ });
385
+ return h("a", {
386
+ "data-nuxt-link": "",
387
+ href,
333
388
  target: props.target,
334
- rel: props.rel ?? (props.target === "_blank" ? "noopener noreferrer" : void 0)
389
+ rel: props.rel ?? (props.target === "_blank" ? "noopener noreferrer" : void 0),
390
+ onClick: (event) => {
391
+ if (props.external || props.target === "_blank" || isExternalHref(href)) return;
392
+ event.preventDefault();
393
+ navigate();
394
+ }
335
395
  }, slots.default?.());
336
- try {
337
- const { RouterLink } = __require("vue-router");
338
- return h(RouterLink, {
339
- to,
340
- replace: props.replace,
341
- activeClass: props.activeClass,
342
- exactActiveClass: props.exactActiveClass
343
- }, slots);
344
- } catch {
345
- return h("a", { href: typeof to === "string" ? to : "/" }, slots.default?.());
346
- }
347
396
  };
348
397
  }
349
398
  });
@@ -373,12 +422,7 @@ const NuxtPage = defineComponent({
373
422
  setup(props, { slots }) {
374
423
  return () => {
375
424
  if (slots.default) return slots.default();
376
- try {
377
- const { RouterView } = __require("vue-router");
378
- return h(RouterView, { name: props.name });
379
- } catch {
380
- return h("div", { "data-nuxt-page": "" }, "NuxtPage placeholder");
381
- }
425
+ return h("div", { "data-nuxt-page": props.name }, "NuxtPage placeholder");
382
426
  };
383
427
  }
384
428
  });
@@ -428,6 +472,380 @@ const NuxtErrorBoundary = defineComponent({
428
472
  return () => slots.default?.() ?? null;
429
473
  }
430
474
  });
475
+ const NuxtRouteAnnouncer = defineComponent({
476
+ name: "NuxtRouteAnnouncer",
477
+ props: { politeness: {
478
+ type: String,
479
+ default: "polite"
480
+ } },
481
+ setup(props) {
482
+ return () => h("span", {
483
+ "aria-live": props.politeness,
484
+ "data-nuxt-route-announcer": "",
485
+ style: "position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0,0,0,0);"
486
+ });
487
+ }
488
+ });
489
+ const NuxtWelcome = defineComponent({
490
+ name: "NuxtWelcome",
491
+ setup() {
492
+ return () => h("div", { "data-nuxt-welcome": "" }, "NuxtWelcome placeholder");
493
+ }
494
+ });
495
+ const NuxtIsland = defineComponent({
496
+ name: "NuxtIsland",
497
+ setup(_props, { slots }) {
498
+ return () => slots.default?.() ?? null;
499
+ }
500
+ });
501
+ const NuxtClientFallback = defineComponent({
502
+ name: "NuxtClientFallback",
503
+ setup(_props, { slots }) {
504
+ return () => slots.default?.() ?? slots.fallback?.() ?? null;
505
+ }
506
+ });
507
+ const NuxtImg = defineComponent({
508
+ name: "NuxtImg",
509
+ props: {
510
+ src: {
511
+ type: String,
512
+ required: true
513
+ },
514
+ alt: {
515
+ type: String,
516
+ default: ""
517
+ },
518
+ width: {
519
+ type: [String, Number],
520
+ default: void 0
521
+ },
522
+ height: {
523
+ type: [String, Number],
524
+ default: void 0
525
+ }
526
+ },
527
+ setup(props, { attrs }) {
528
+ return () => h("img", {
529
+ ...attrs,
530
+ src: props.src,
531
+ alt: props.alt,
532
+ width: props.width,
533
+ height: props.height
534
+ });
535
+ }
536
+ });
537
+ const NuxtPicture = defineComponent({
538
+ name: "NuxtPicture",
539
+ props: {
540
+ src: {
541
+ type: String,
542
+ required: true
543
+ },
544
+ alt: {
545
+ type: String,
546
+ default: ""
547
+ }
548
+ },
549
+ setup(props, { attrs }) {
550
+ return () => h("picture", {}, [h("img", {
551
+ ...attrs,
552
+ src: props.src,
553
+ alt: props.alt
554
+ })]);
555
+ }
556
+ });
557
+ function routeTargetToHref(to) {
558
+ return resolveNavigationTarget(to).fullPath;
559
+ }
560
+ function isExternalHref(href) {
561
+ return /^(?:[a-z][a-z0-9+.-]*:)?\/\//i.test(href);
562
+ }
563
+ //#endregion
564
+ //#region src/mocks/runtime.ts
565
+ /**
566
+ * Mock Nuxt runtime composables.
567
+ */
568
+ /**
569
+ * Mock useNuxtApp - returns a minimal Nuxt app-like object.
570
+ */
571
+ function useNuxtApp() {
572
+ return {
573
+ $config: useRuntimeConfig(),
574
+ $router: useRouter(),
575
+ $route: useRoute(),
576
+ provide: (_name, _value) => {},
577
+ hook: (_name, _fn) => {},
578
+ callHook: async (_name, ..._args) => {},
579
+ vueApp: null,
580
+ payload: reactive({
581
+ data: {},
582
+ state: {}
583
+ }),
584
+ isHydrating: false,
585
+ runWithContext: (fn) => fn()
586
+ };
587
+ }
588
+ /**
589
+ * Mock useRuntimeConfig - returns the configured runtime config.
590
+ */
591
+ function useRuntimeConfig() {
592
+ return getRuntimeConfigState();
593
+ }
594
+ function useAppConfig() {
595
+ return getAppConfigState();
596
+ }
597
+ function updateAppConfig(config) {
598
+ updateAppConfigState(config);
599
+ }
600
+ /**
601
+ * Mock useState - returns a ref initialized from mock config or init function.
602
+ */
603
+ function useState(key, init) {
604
+ return getStateRef(key, init);
605
+ }
606
+ /**
607
+ * Mock useRequestHeaders - returns empty headers in gallery context.
608
+ */
609
+ function useRequestHeaders(_include) {
610
+ return { ...getRequestState().headers };
611
+ }
612
+ /**
613
+ * Mock useRequestEvent - returns undefined in gallery context.
614
+ */
615
+ function useRequestEvent() {}
616
+ /**
617
+ * Mock useRequestURL - returns current window location.
618
+ */
619
+ function useRequestURL() {
620
+ if (typeof window !== "undefined") return new URL(window.location.href);
621
+ return new URL(getRequestState().url);
622
+ }
623
+ /**
624
+ * Mock useCookie - returns a ref-like cookie mock.
625
+ */
626
+ function useCookie(name, opts) {
627
+ return getCookieRef(name, opts?.default);
628
+ }
629
+ /**
630
+ * Mock clearNuxtState - no-op.
631
+ */
632
+ function clearNuxtState(keys) {
633
+ clearStateRefs(keys);
634
+ }
635
+ /**
636
+ * Mock defineNuxtPlugin - returns the plugin function as-is.
637
+ */
638
+ function defineNuxtPlugin(plugin) {
639
+ return plugin;
640
+ }
641
+ function defineNuxtComponent(component) {
642
+ return component;
643
+ }
644
+ function onNuxtReady(callback) {
645
+ if (typeof queueMicrotask === "function") {
646
+ queueMicrotask(callback);
647
+ return;
648
+ }
649
+ Promise.resolve().then(callback);
650
+ }
651
+ function callOnce(keyOrFn, fn) {
652
+ if (typeof keyOrFn === "function") return runCallOnce("__default__", keyOrFn);
653
+ return runCallOnce(keyOrFn, fn ?? (() => void 0));
654
+ }
655
+ function useId() {
656
+ return nextNuxtId();
657
+ }
658
+ function reloadNuxtApp(_options) {
659
+ return Promise.resolve();
660
+ }
661
+ //#endregion
662
+ //#region src/app.ts
663
+ const builtInComponents = {
664
+ NuxtLink,
665
+ NuxtPage,
666
+ ClientOnly,
667
+ NuxtLayout,
668
+ NuxtLoadingIndicator,
669
+ NuxtErrorBoundary,
670
+ NuxtRouteAnnouncer,
671
+ NuxtWelcome,
672
+ NuxtIsland,
673
+ NuxtClientFallback,
674
+ NuxtImg,
675
+ NuxtPicture
676
+ };
677
+ function installNuxtMuseaMocks(app, options = {}) {
678
+ configureNuxtMuseaMocks(options);
679
+ for (const [name, component] of Object.entries(builtInComponents)) app.component(name, component);
680
+ app.config.globalProperties.$config = useRuntimeConfig();
681
+ app.config.globalProperties.$route = useRoute();
682
+ app.config.globalProperties.$router = useRouter();
683
+ app.provide("nuxt-app", useNuxtApp());
684
+ return app;
685
+ }
686
+ function createNuxtMuseaPreviewSetup(options = {}) {
687
+ return (app) => {
688
+ installNuxtMuseaMocks(app, options);
689
+ };
690
+ }
691
+ //#endregion
692
+ //#region src/mocks/data.ts
693
+ /**
694
+ * Mock Nuxt data-fetching composables.
695
+ */
696
+ function findMockData(key) {
697
+ const fetchMocks = getFetchMocks();
698
+ if (key in fetchMocks) return fetchMocks[key];
699
+ for (const [pattern, data] of Object.entries(fetchMocks)) if (key.includes(pattern)) return data;
700
+ }
701
+ /**
702
+ * Mock useFetch - returns reactive data based on mock config.
703
+ */
704
+ function useFetch(url, opts) {
705
+ return createAsyncDataResult(stringifyDataKey(toValue(url)), void 0, opts);
706
+ }
707
+ /**
708
+ * Mock useAsyncData - similar to useFetch but with key-based lookup.
709
+ */
710
+ function useAsyncData(key, handler, opts) {
711
+ return createAsyncDataResult(key, handler, opts);
712
+ }
713
+ /**
714
+ * Mock useLazyFetch - lazy variant of useFetch.
715
+ */
716
+ function useLazyFetch(url, opts) {
717
+ return useFetch(url, {
718
+ ...opts,
719
+ lazy: true
720
+ });
721
+ }
722
+ /**
723
+ * Mock useLazyAsyncData - lazy variant of useAsyncData.
724
+ */
725
+ function useLazyAsyncData(key, handler, opts) {
726
+ return useAsyncData(key, handler, {
727
+ ...opts,
728
+ lazy: true
729
+ });
730
+ }
731
+ function refreshNuxtData(_keys) {
732
+ return Promise.resolve();
733
+ }
734
+ function clearNuxtData(_keys) {}
735
+ function useNuxtData(key) {
736
+ return { data: ref(findMockData(key) ?? null) };
737
+ }
738
+ function useRequestFetch() {
739
+ return async (url) => {
740
+ return findMockData(stringifyDataKey(url));
741
+ };
742
+ }
743
+ function createAsyncDataResult(key, handler, opts = {}) {
744
+ const initial = resolveInitialData(key, opts);
745
+ const data = ref(initial);
746
+ const pending = ref(false);
747
+ const error = ref(null);
748
+ const status = ref(initial == null ? "idle" : "success");
749
+ const execute = async () => {
750
+ pending.value = true;
751
+ status.value = "pending";
752
+ error.value = null;
753
+ try {
754
+ const mockData = findMockData(key);
755
+ data.value = applyDataOptions(mockData !== void 0 ? mockData : handler ? await handler() : data.value, opts);
756
+ status.value = "success";
757
+ } catch (caught) {
758
+ error.value = caught instanceof Error ? caught : new Error(String(caught));
759
+ status.value = "error";
760
+ } finally {
761
+ pending.value = false;
762
+ }
763
+ };
764
+ if (opts.immediate !== false && opts.lazy !== true && initial == null && handler) execute();
765
+ return {
766
+ data,
767
+ pending,
768
+ error,
769
+ refresh: execute,
770
+ execute,
771
+ clear: () => {
772
+ data.value = null;
773
+ error.value = null;
774
+ pending.value = false;
775
+ status.value = "idle";
776
+ },
777
+ status
778
+ };
779
+ }
780
+ function resolveInitialData(key, opts) {
781
+ const mockData = findMockData(key);
782
+ if (mockData !== void 0) return applyDataOptions(mockData, opts);
783
+ return opts.default ? opts.default() : null;
784
+ }
785
+ function applyDataOptions(value, opts) {
786
+ const transformed = opts.transform ? opts.transform(value) : value;
787
+ if (!opts.pick || typeof transformed !== "object" || transformed == null) return transformed;
788
+ const picked = {};
789
+ for (const key of opts.pick) picked[key] = transformed[key];
790
+ return picked;
791
+ }
792
+ function stringifyDataKey(value) {
793
+ return typeof value === "string" ? value : value.toString();
794
+ }
795
+ //#endregion
796
+ //#region src/mocks/head.ts
797
+ function createHeadEntry() {
798
+ return {
799
+ dispose: () => {},
800
+ patch: (_input) => {},
801
+ pause: () => {},
802
+ resume: () => {}
803
+ };
804
+ }
805
+ /**
806
+ * Mock useHead - no-op.
807
+ */
808
+ function useHead(_input) {
809
+ return createHeadEntry();
810
+ }
811
+ /**
812
+ * Mock useSeoMeta - no-op.
813
+ */
814
+ function useSeoMeta(_input) {
815
+ return createHeadEntry();
816
+ }
817
+ /**
818
+ * Mock useHeadSafe - no-op.
819
+ */
820
+ function useHeadSafe(_input) {
821
+ return createHeadEntry();
822
+ }
823
+ /**
824
+ * Mock useServerSeoMeta - no-op.
825
+ */
826
+ function useServerSeoMeta(_input) {
827
+ return createHeadEntry();
828
+ }
829
+ //#endregion
830
+ //#region src/mocks/error.ts
831
+ function createError(input) {
832
+ const message = typeof input === "string" ? input : input.message ?? input.statusMessage ?? "Error";
833
+ const error = new Error(message);
834
+ if (typeof input === "object") Object.assign(error, input);
835
+ return error;
836
+ }
837
+ function showError(input) {
838
+ const error = createError(input);
839
+ setError(error);
840
+ return error;
841
+ }
842
+ function clearError(_options) {
843
+ setError(null);
844
+ return Promise.resolve();
845
+ }
846
+ function useError() {
847
+ return getErrorRef();
848
+ }
431
849
  //#endregion
432
850
  //#region src/index.ts
433
851
  /**
@@ -437,4 +855,4 @@ function nuxtMusea(options = {}) {
437
855
  return createNuxtMuseaPlugin(options);
438
856
  }
439
857
  //#endregion
440
- export { ClientOnly, NuxtErrorBoundary, NuxtLayout, NuxtLink, NuxtLoadingIndicator, NuxtPage, abortNavigation, navigateTo, nuxtMusea, useAsyncData, useCookie, useFetch, useHead, useLazyAsyncData, useLazyFetch, useNuxtApp, useRoute, useRouter, useRuntimeConfig, useSeoMeta, useState };
858
+ export { ClientOnly, NuxtClientFallback, NuxtErrorBoundary, NuxtImg, NuxtIsland, NuxtLayout, NuxtLink, NuxtLoadingIndicator, NuxtPage, NuxtPicture, NuxtRouteAnnouncer, NuxtWelcome, abortNavigation, callOnce, clearError, clearNuxtData, clearNuxtState, configureNuxtMuseaMocks, createError, createNuxtMuseaPreviewSetup, defineNuxtComponent, defineNuxtPlugin, defineNuxtRouteMiddleware, definePageMeta, getAppConfigState, getRouteState, getRuntimeConfigState, installNuxtMuseaMocks, navigateTo, nuxtMusea, onNuxtReady, prefetchComponents, preloadComponents, preloadRouteComponents, refreshNuxtData, reloadNuxtApp, resetNuxtMuseaMocks, setPageLayout, showError, updateAppConfig, useAppConfig, useAsyncData, useCookie, useError, useFetch, useHead, useHeadSafe, useId, useLazyAsyncData, useLazyFetch, useNuxtApp, useNuxtData, useRequestEvent, useRequestFetch, useRequestHeaders, useRequestURL, useRoute, useRouter, useRuntimeConfig, useSeoMeta, useServerSeoMeta, useState };