@nuxt/test-utils 3.22.0 → 4.0.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.
@@ -1,8 +1,9 @@
1
1
  import { createFetch } from "ofetch";
2
2
  import { joinURL } from "ufo";
3
- import { createApp, defineEventHandler, toNodeListener } from "h3";
3
+ import { defineEventHandler } from "./h3.mjs";
4
4
  import { createRouter as createRadixRouter, exportMatcher, toRouteMatcher } from "radix3";
5
- import { fetchNodeRequestHandler } from "node-mock-http";
5
+ import { createFetchForH3V1 } from "./h3-v1.mjs";
6
+ import { createFetchForH3V2 } from "./h3-v2.mjs";
6
7
  export async function setupWindow(win, environmentOptions) {
7
8
  win.__NUXT_VITEST_ENVIRONMENT__ = true;
8
9
  win.__NUXT__ = {
@@ -15,16 +16,6 @@ export async function setupWindow(win, environmentOptions) {
15
16
  data: {},
16
17
  state: {}
17
18
  };
18
- const rootId = environmentOptions.nuxt.rootId || "nuxt-test";
19
- let el;
20
- try {
21
- el = win.document.querySelector(rootId);
22
- } catch {
23
- }
24
- if (el) {
25
- return () => {
26
- };
27
- }
28
19
  const consoleInfo = console.info;
29
20
  console.info = (...args) => {
30
21
  if (args[0] === "<Suspense> is an experimental feature and its API will likely change.") {
@@ -33,9 +24,8 @@ export async function setupWindow(win, environmentOptions) {
33
24
  return consoleInfo(...args);
34
25
  };
35
26
  const app = win.document.createElement("div");
36
- app.id = rootId;
27
+ app.id = environmentOptions.nuxt.rootId || "nuxt-test";
37
28
  win.document.body.appendChild(app);
38
- const h3App = createApp();
39
29
  if (!win.fetch || !("Request" in win)) {
40
30
  await import("node-fetch-native/polyfill");
41
31
  win.URLSearchParams = globalThis.URLSearchParams;
@@ -49,37 +39,11 @@ export async function setupWindow(win, environmentOptions) {
49
39
  }
50
40
  };
51
41
  }
52
- const nodeHandler = toNodeListener(h3App);
53
- const registry = /* @__PURE__ */ new Set();
54
- const _fetch = fetch;
55
- win.fetch = async (input, _init) => {
56
- let url;
57
- let init = _init;
58
- if (typeof input === "string") {
59
- url = input;
60
- } else if (input instanceof URL) {
61
- url = input.toString();
62
- } else {
63
- url = input.url;
64
- init = {
65
- method: init?.method ?? input.method,
66
- body: init?.body ?? input.body,
67
- headers: init?.headers ?? input.headers
68
- };
69
- }
70
- const base = url.split("?")[0];
71
- if (registry.has(base) || registry.has(url)) {
72
- url = "/_" + url;
73
- }
74
- if (url.startsWith("/")) {
75
- const response = await fetchNodeRequestHandler(nodeHandler, url, init);
76
- return normalizeFetchResponse(response);
77
- }
78
- return _fetch(input, _init);
79
- };
42
+ const res = environmentOptions.nuxt.h3Version === 2 ? await createFetchForH3V2() : await createFetchForH3V1();
43
+ win.fetch = res.fetch;
80
44
  win.$fetch = createFetch({ fetch: win.fetch, Headers: win.Headers });
81
- win.__registry = registry;
82
- win.__app = h3App;
45
+ win.__registry = res.registry;
46
+ win.__app = res.h3App;
83
47
  const timestamp = Date.now();
84
48
  const routeRulesMatcher = toRouteMatcher(
85
49
  createRadixRouter({ routes: environmentOptions.nuxtRouteRules || {} })
@@ -92,14 +56,14 @@ export async function setupWindow(win, environmentOptions) {
92
56
  );
93
57
  const manifestBaseRoutePath = joinURL("/_", manifestOutputPath);
94
58
  const buildId = win.__NUXT__.config?.app.buildId || "test";
95
- h3App.use(
59
+ res.h3App.use(
96
60
  `${manifestBaseRoutePath}/latest.json`,
97
61
  defineEventHandler(() => ({
98
62
  id: buildId,
99
63
  timestamp
100
64
  }))
101
65
  );
102
- h3App.use(
66
+ res.h3App.use(
103
67
  `${manifestBaseRoutePath}/meta/${buildId}.json`,
104
68
  defineEventHandler(() => ({
105
69
  id: buildId,
@@ -108,38 +72,9 @@ export async function setupWindow(win, environmentOptions) {
108
72
  prerendered: []
109
73
  }))
110
74
  );
111
- registry.add(`${manifestOutputPath}/latest.json`);
112
- registry.add(`${manifestOutputPath}/meta/${buildId}.json`);
75
+ res.registry.add(`${manifestOutputPath}/latest.json`);
76
+ res.registry.add(`${manifestOutputPath}/meta/${buildId}.json`);
113
77
  return () => {
114
78
  console.info = consoleInfo;
115
79
  };
116
80
  }
117
- function normalizeFetchResponse(response) {
118
- if (!response.headers.has("set-cookie")) {
119
- return response;
120
- }
121
- return new Response(response.body, {
122
- status: response.status,
123
- statusText: response.statusText,
124
- headers: normalizeCookieHeaders(response.headers)
125
- });
126
- }
127
- function normalizeCookieHeader(header = "") {
128
- return splitCookiesString(joinHeaders(header));
129
- }
130
- function normalizeCookieHeaders(headers) {
131
- const outgoingHeaders = new Headers();
132
- for (const [name, header] of headers) {
133
- if (name === "set-cookie") {
134
- for (const cookie of normalizeCookieHeader(header)) {
135
- outgoingHeaders.append("set-cookie", cookie);
136
- }
137
- } else {
138
- outgoingHeaders.set(name, joinHeaders(header));
139
- }
140
- }
141
- return outgoingHeaders;
142
- }
143
- function joinHeaders(value) {
144
- return Array.isArray(value) ? value.join(", ") : String(value);
145
- }
@@ -0,0 +1,6 @@
1
+ import type { GenericApp } from '../../vitest-environment';
2
+ export declare function createFetchForH3V1(): Promise<{
3
+ h3App: GenericApp;
4
+ registry: Set<string>;
5
+ fetch: typeof fetch;
6
+ }>;
@@ -0,0 +1,69 @@
1
+ export async function createFetchForH3V1() {
2
+ const [{ createApp, toNodeListener }, { fetchNodeRequestHandler }] = await Promise.all([
3
+ import("h3"),
4
+ import("node-mock-http")
5
+ ]);
6
+ const h3App = createApp();
7
+ const nodeHandler = toNodeListener(h3App);
8
+ const registry = /* @__PURE__ */ new Set();
9
+ const _fetch = fetch;
10
+ const h3Fetch = (async (input, _init) => {
11
+ let url;
12
+ let init = _init;
13
+ if (typeof input === "string") {
14
+ url = input;
15
+ } else if (input instanceof URL) {
16
+ url = input.toString();
17
+ } else {
18
+ url = input.url;
19
+ init = {
20
+ method: init?.method ?? input.method,
21
+ body: init?.body ?? input.body,
22
+ headers: init?.headers ?? input.headers
23
+ };
24
+ }
25
+ const base = url.split("?")[0];
26
+ if (registry.has(base) || registry.has(url)) {
27
+ url = "/_" + url;
28
+ }
29
+ if (url.startsWith("/")) {
30
+ const response = await fetchNodeRequestHandler(nodeHandler, url, init);
31
+ return normalizeFetchResponse(response);
32
+ }
33
+ return _fetch(input, _init);
34
+ });
35
+ return {
36
+ h3App,
37
+ registry,
38
+ fetch: h3Fetch
39
+ };
40
+ }
41
+ function normalizeFetchResponse(response) {
42
+ if (!response.headers.has("set-cookie")) {
43
+ return response;
44
+ }
45
+ return new Response(response.body, {
46
+ status: response.status,
47
+ statusText: response.statusText,
48
+ headers: normalizeCookieHeaders(response.headers)
49
+ });
50
+ }
51
+ function normalizeCookieHeader(header = "") {
52
+ return splitCookiesString(joinHeaders(header));
53
+ }
54
+ function normalizeCookieHeaders(headers) {
55
+ const outgoingHeaders = new Headers();
56
+ for (const [name, header] of headers) {
57
+ if (name === "set-cookie") {
58
+ for (const cookie of normalizeCookieHeader(header)) {
59
+ outgoingHeaders.append("set-cookie", cookie);
60
+ }
61
+ } else {
62
+ outgoingHeaders.set(name, joinHeaders(header));
63
+ }
64
+ }
65
+ return outgoingHeaders;
66
+ }
67
+ function joinHeaders(value) {
68
+ return Array.isArray(value) ? value.join(", ") : String(value);
69
+ }
@@ -0,0 +1,6 @@
1
+ import type { GenericApp } from '../../vitest-environment';
2
+ export declare function createFetchForH3V2(): Promise<{
3
+ h3App: GenericApp;
4
+ registry: Set<string>;
5
+ fetch: typeof fetch;
6
+ }>;
@@ -0,0 +1,35 @@
1
+ export async function createFetchForH3V2() {
2
+ const { H3 } = await import("h3-next/generic");
3
+ const h3App = new H3();
4
+ const registry = /* @__PURE__ */ new Set();
5
+ const _fetch = fetch;
6
+ const h3Fetch = (async (input, _init) => {
7
+ let url;
8
+ let init = _init;
9
+ if (typeof input === "string") {
10
+ url = input;
11
+ } else if (input instanceof URL) {
12
+ url = input.toString();
13
+ } else {
14
+ url = input.url;
15
+ init = {
16
+ method: init?.method ?? input.method,
17
+ body: init?.body ?? input.body,
18
+ headers: init?.headers ?? input.headers
19
+ };
20
+ }
21
+ const base = url.split("?")[0];
22
+ if (registry.has(base) || registry.has(url)) {
23
+ return h3App.fetch(new Request("/_" + url, init));
24
+ }
25
+ if (url.startsWith("/")) {
26
+ return new Response("Not Found", { status: 404, statusText: "Not Found" });
27
+ }
28
+ return _fetch(input, _init);
29
+ });
30
+ return {
31
+ h3App,
32
+ registry,
33
+ fetch: h3Fetch
34
+ };
35
+ }
@@ -0,0 +1,3 @@
1
+ type RawHandler = () => unknown | Promise<unknown>;
2
+ export declare function defineEventHandler(handler: RawHandler): RawHandler;
3
+ export {};
@@ -0,0 +1,3 @@
1
+ export function defineEventHandler(handler) {
2
+ return Object.assign(handler, { __is_handler__: true });
3
+ }
@@ -1,7 +1,7 @@
1
1
  import { config } from "@vue/test-utils";
2
2
  const PLUGIN_NAME = "nuxt-test-utils";
3
3
  export function getVueWrapperPlugin() {
4
- const installed = config.plugins.VueWrapper.installedPlugins.find(({ options: options2 }) => options2._name === PLUGIN_NAME);
4
+ const installed = config.plugins.VueWrapper.installedPlugins.find(({ options: options2 }) => options2?._name === PLUGIN_NAME);
5
5
  if (installed) return installed.options;
6
6
  const options = createPluginOptions();
7
7
  config.plugins.VueWrapper.install((instance, options2) => {
@@ -1,4 +1,5 @@
1
- import { EventHandler, HTTPMethod } from 'h3';
1
+ import { EventHandler } from 'h3';
2
+ import { HTTPMethod } from 'h3-next';
2
3
  import { SetupContext, RenderFunction, ComputedOptions, MethodOptions, ComponentOptionsMixin, EmitsOptions, ComponentInjectOptions, ComponentOptionsWithoutProps, ComponentOptionsWithArrayProps, ComponentPropsOptions, ComponentOptionsWithObjectProps } from 'vue';
3
4
  import { mount } from '@vue/test-utils';
4
5
  import { RouteLocationRaw } from 'vue-router';
@@ -57,7 +58,7 @@ declare function registerEndpoint(url: string, options: EventHandler | {
57
58
  * ```
58
59
  * @see https://nuxt.com/docs/getting-started/testing#mocknuxtimport
59
60
  */
60
- declare function mockNuxtImport<T = unknown>(_target: string | T, _factory: () => T | Promise<T>): void;
61
+ declare function mockNuxtImport<T = unknown>(_target: string | T, _factory: (original: T) => T | Promise<T>): void;
61
62
  /**
62
63
  * `mockComponent` allows you to mock Nuxt's component.
63
64
  * @param path - component name in PascalCase, or the relative path of the component.
@@ -1,41 +1,36 @@
1
- import { defineEventHandler } from 'h3';
2
1
  import { mount } from '@vue/test-utils';
3
- import { reactive, h as h$1, Suspense, nextTick as nextTick$1, getCurrentInstance, onErrorCaptured, effectScope } from 'vue';
2
+ import { reactive, h as h$1, Suspense, nextTick, getCurrentInstance, onErrorCaptured, effectScope } from 'vue';
4
3
  import { defu } from 'defu';
5
4
  import { defineComponent, useRouter, h, tryUseNuxtApp } from '#imports';
6
5
  import NuxtRoot from '#build/root-component.mjs';
7
6
 
8
- const endpointRegistry = {};
7
+ function getEndpointRegistry() {
8
+ const app = window.__app ?? {};
9
+ return app._registeredEndpointRegistry ||= {};
10
+ }
11
+ function findEndpointRegistryHandlers(url) {
12
+ const endpointRegistry = getEndpointRegistry();
13
+ const pathname = url.replace(/[?#].*$/, "");
14
+ for (const [key, handlers] of Object.entries(endpointRegistry)) {
15
+ if (key === url || key === pathname) {
16
+ if (handlers?.length) {
17
+ return handlers;
18
+ }
19
+ }
20
+ }
21
+ }
9
22
  function registerEndpoint(url, options) {
10
23
  const app = window.__app;
11
24
  if (!app) {
12
25
  throw new Error("registerEndpoint() can only be used in a `@nuxt/test-utils` runtime environment");
13
26
  }
14
- const config = typeof options === "function" ? { handler: options, method: void 0, once: false } : options;
15
- config.handler = defineEventHandler(config.handler);
16
- const hasBeenRegistered = window.__registry.has(url);
27
+ const config = typeof options === "function" ? { url, handler: options, method: void 0, once: false } : { ...options, url };
28
+ config.handler = Object.assign(config.handler, { __is_handler__: true });
29
+ const endpointRegistry = getEndpointRegistry();
17
30
  endpointRegistry[url] ||= [];
18
31
  endpointRegistry[url].push(config);
19
- if (!hasBeenRegistered) {
20
- window.__registry.add(url);
21
- app.use("/_" + url, defineEventHandler(async (event) => {
22
- const latestHandler = [...endpointRegistry[url] || []].reverse().find((config2) => config2.method ? event.method === config2.method : true);
23
- if (!latestHandler) return;
24
- const result = await latestHandler.handler(event);
25
- if (!latestHandler.once) return result;
26
- const index = endpointRegistry[url]?.indexOf(latestHandler);
27
- if (index === void 0 || index === -1) return result;
28
- endpointRegistry[url]?.splice(index, 1);
29
- if (endpointRegistry[url]?.length === 0) {
30
- window.__registry.delete(url);
31
- }
32
- return result;
33
- }), {
34
- match(_, event) {
35
- return endpointRegistry[url]?.some((config2) => config2.method ? event?.method === config2.method : true) ?? false;
36
- }
37
- });
38
- }
32
+ window.__registry.add(url);
33
+ app._registered ||= registerGlobalHandler(app);
39
34
  return () => {
40
35
  endpointRegistry[url]?.splice(endpointRegistry[url].indexOf(config), 1);
41
36
  if (endpointRegistry[url]?.length === 0) {
@@ -53,6 +48,33 @@ function mockComponent(_path, _component) {
53
48
  "mockComponent() is a macro and it did not get transpiled. This may be an internal bug of @nuxt/test-utils."
54
49
  );
55
50
  }
51
+ const handler = Object.assign(async (event) => {
52
+ const url = "url" in event && event.url ? (event.url.pathname + event.url.search).replace(/^\/_/, "") : event.path.replace(/^\/_/, "");
53
+ const registeredHandlers = findEndpointRegistryHandlers(url);
54
+ const latestHandler = [...registeredHandlers || []].reverse().find((config) => config.method ? event.method === config.method : true);
55
+ if (!latestHandler) return;
56
+ const result = await latestHandler.handler(event);
57
+ if (!latestHandler.once) return result;
58
+ const index = registeredHandlers?.indexOf(latestHandler);
59
+ if (index === void 0 || index === -1) return result;
60
+ registeredHandlers?.splice(index, 1);
61
+ if (registeredHandlers?.length === 0) {
62
+ window.__registry.delete(latestHandler.url);
63
+ }
64
+ return result;
65
+ }, { __is_handler__: true });
66
+ function registerGlobalHandler(app) {
67
+ app.use(handler, {
68
+ match: (...args) => {
69
+ const [eventOrPath, _event = eventOrPath] = args;
70
+ const url = typeof eventOrPath === "string" ? eventOrPath.replace(/^\/_/, "") : (eventOrPath.url.pathname + eventOrPath.url.search).replace(/^\/_/, "");
71
+ const event = _event;
72
+ const registeredHandlers = findEndpointRegistryHandlers(url);
73
+ return registeredHandlers?.some((config) => config.method ? event?.method === config.method : true) ?? false;
74
+ }
75
+ });
76
+ return true;
77
+ }
56
78
 
57
79
  const RouterLink = defineComponent({
58
80
  functional: true,
@@ -192,7 +214,7 @@ function wrapperSuspended(component, options, {
192
214
  render: wrappedRender(() => h$1(
193
215
  Suspense,
194
216
  {
195
- onResolve: () => nextTick$1().then(() => {
217
+ onResolve: () => nextTick().then(() => {
196
218
  if (isMountSettled) return;
197
219
  isMountSettled = true;
198
220
  wrapper.setupState = setupState;
@@ -1,6 +1,7 @@
1
- import { Browser, Page, Response as Response$1, BrowserContextOptions, LaunchOptions } from 'playwright-core';
1
+ import { Page, Response as Response$1, BrowserContextOptions, Browser, LaunchOptions } from 'playwright-core';
2
2
  import { NuxtConfig, Nuxt } from '@nuxt/schema';
3
3
  import { exec } from 'tinyexec';
4
+ import { $Fetch } from 'ofetch';
4
5
 
5
6
  declare function createBrowser(): Promise<void>;
6
7
  declare function getBrowser(): Promise<Browser>;
@@ -20,7 +21,7 @@ interface StartServerOptions {
20
21
  declare function startServer(options?: StartServerOptions): Promise<void>;
21
22
  declare function stopServer(): Promise<void>;
22
23
  declare function fetch(path: string, options?: RequestInit): Promise<Response>;
23
- declare const $fetch: (typeof globalThis)["$fetch"];
24
+ declare const $fetch: "$fetch" extends keyof typeof globalThis ? typeof globalThis.$fetch : $Fetch;
24
25
  declare function url(path: string): string;
25
26
 
26
27
  type TestRunner = 'vitest' | 'jest' | 'cucumber' | 'bun';
@@ -115,5 +116,5 @@ interface TestHooks {
115
116
  ctx: TestContext;
116
117
  }
117
118
 
118
- export { $fetch as $, createBrowser as c, createPage as d, stopServer as e, fetch as f, getBrowser as g, startServer as s, url as u, waitForHydration as w };
119
- export type { GotoOptions as G, NuxtPage as N, StartServerOptions as S, TestOptions as T, TestHooks as a, TestContext as b, TestRunner as h };
119
+ export { $fetch as $, createBrowser as d, createPage as e, fetch as f, getBrowser as g, stopServer as h, startServer as s, url as u, waitForHydration as w };
120
+ export type { GotoOptions as G, NuxtPage as N, StartServerOptions as S, TestOptions as T, TestHooks as a, TestContext as b, TestRunner as c };
@@ -1,6 +1,6 @@
1
1
  import { x } from 'tinyexec';
2
2
  import { getRandomPort, waitForPort } from 'get-port-please';
3
- import { $fetch as $fetch$1, fetch as fetch$1 } from 'ofetch';
3
+ import { createFetch, fetch as fetch$1 } from 'ofetch';
4
4
  import { resolve as resolve$1 } from 'pathe';
5
5
  import { withTrailingSlash, joinURL } from 'ufo';
6
6
  import { resolve } from 'node:path';
@@ -72,6 +72,7 @@ function exposeContextToEnv() {
72
72
  process.env.NUXT_TEST_CONTEXT = JSON.stringify({ options, browser, url });
73
73
  }
74
74
 
75
+ const globalFetch = globalThis.fetch || fetch$1;
75
76
  async function startServer(options = {}) {
76
77
  const ctx = useTestContext();
77
78
  await stopServer();
@@ -144,10 +145,11 @@ async function stopServer() {
144
145
  }
145
146
  }
146
147
  function fetch(path, options) {
147
- return fetch$1(url(path), options);
148
+ return globalFetch(url(path), options);
148
149
  }
149
- const $fetch = function(path, options) {
150
- return $fetch$1(url(path), options);
150
+ const _$fetch = createFetch({ fetch: globalFetch });
151
+ const $fetch = function $fetch2(path, options) {
152
+ return _$fetch(url(path), options);
151
153
  };
152
154
  function url(path) {
153
155
  const ctx = useTestContext();
@@ -1,4 +1,4 @@
1
- import { u as useTestContext, d as url, c as createTestContext, a as startServer, b as stopServer, s as setTestContext } from './test-utils.C_clWQBc.mjs';
1
+ import { u as useTestContext, d as url, c as createTestContext, a as startServer, b as stopServer, s as setTestContext } from './test-utils.BsmyE2FA.mjs';
2
2
  import { existsSync, promises } from 'node:fs';
3
3
  import { resolve } from 'node:path';
4
4
  import { defu } from 'defu';
@@ -117,10 +117,10 @@ async function buildFixture() {
117
117
  async function setupBun(hooks) {
118
118
  const bunTest = await import('bun:test');
119
119
  hooks.ctx.mockFn = bunTest.mock;
120
- bunTest.beforeAll(hooks.beforeAll);
120
+ bunTest.beforeAll(hooks.beforeAll, hooks.ctx.options.setupTimeout);
121
121
  bunTest.beforeEach(hooks.beforeEach);
122
122
  bunTest.afterEach(hooks.afterEach);
123
- bunTest.afterAll(hooks.afterAll);
123
+ bunTest.afterAll(hooks.afterAll, hooks.ctx.options.teardownTimeout);
124
124
  }
125
125
 
126
126
  async function setupCucumber(hooks) {
@@ -209,4 +209,4 @@ async function setup(options = {}) {
209
209
  await setupFn(hooks);
210
210
  }
211
211
 
212
- export { createPage as a, buildFixture as b, createBrowser as c, createTest as d, setup as e, getBrowser as g, loadFixture as l, setupMaps as s, waitForHydration as w };
212
+ export { createPage as a, buildFixture as b, createBrowser as c, createTest as d, setupMaps as e, getBrowser as g, loadFixture as l, setup as s, waitForHydration as w };
@@ -1,13 +1,25 @@
1
1
  import { Environment } from 'vitest/environments';
2
- import { App } from 'h3';
2
+ import { H3Event as H3Event$1 } from 'h3';
3
+ import { H3Event } from 'h3-next';
3
4
  import { $Fetch } from 'nitropack';
4
- import { JSDOMOptions, HappyDOMOptions } from 'vitest/node';
5
+ import { EnvironmentOptions } from 'vitest/node';
5
6
 
6
7
  declare const _default: Environment;
7
8
 
8
9
  type NuxtBuiltinEnvironment = 'happy-dom' | 'jsdom';
10
+ interface GenericAppUse {
11
+ (route: string, handler: (event: H3Event | H3Event$1) => unknown, options?: {
12
+ match: (...args: [string, H3Event$1 | undefined] | [H3Event]) => boolean;
13
+ }): void;
14
+ (handler: (event: H3Event | H3Event$1) => unknown, options?: {
15
+ match: (...args: [string, H3Event$1 | undefined] | [H3Event]) => boolean;
16
+ }): void;
17
+ }
18
+ interface GenericApp {
19
+ use: GenericAppUse;
20
+ }
9
21
  interface NuxtWindow extends Window {
10
- __app: App;
22
+ __app?: GenericApp;
11
23
  __registry: Set<string>;
12
24
  __NUXT_VITEST_ENVIRONMENT__?: boolean;
13
25
  __NUXT__: Record<string, unknown>;
@@ -17,8 +29,8 @@ interface NuxtWindow extends Window {
17
29
  Headers: typeof Headers;
18
30
  }
19
31
  interface EnvironmentNuxtOptions {
20
- jsdom?: JSDOMOptions;
21
- happyDom?: HappyDOMOptions;
32
+ jsdom?: EnvironmentOptions['jsdom'];
33
+ happyDom?: EnvironmentOptions['happyDOM'];
22
34
  }
23
35
  type EnvironmentNuxt = (global: typeof globalThis, options: EnvironmentNuxtOptions) => Promise<{
24
36
  window: NuxtWindow;
@@ -26,4 +38,4 @@ type EnvironmentNuxt = (global: typeof globalThis, options: EnvironmentNuxtOptio
26
38
  }>;
27
39
 
28
40
  export { _default as default };
29
- export type { EnvironmentNuxt, EnvironmentNuxtOptions, NuxtBuiltinEnvironment, NuxtWindow };
41
+ export type { EnvironmentNuxt, EnvironmentNuxtOptions, GenericApp, NuxtBuiltinEnvironment, NuxtWindow };