@kasperpeulen/vitest-plugin-nextjs 0.0.0-alpha.0 → 0.1.0-alpha.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 (250) hide show
  1. package/README.md +249 -2
  2. package/dist/_virtual/_rolldown/runtime.js +14 -0
  3. package/dist/action-ids.d.ts +18 -0
  4. package/dist/action-ids.js +44 -0
  5. package/dist/adapter.d.ts +8 -0
  6. package/dist/adapter.js +12 -0
  7. package/dist/app-requests.d.ts +63 -0
  8. package/dist/app-requests.js +253 -0
  9. package/dist/browser-context.d.ts +24 -0
  10. package/dist/browser-context.js +157 -0
  11. package/dist/build-output.d.ts +68 -0
  12. package/dist/build-output.js +216 -0
  13. package/dist/build.d.ts +26 -0
  14. package/dist/build.js +39 -0
  15. package/dist/built-files.d.ts +9 -0
  16. package/dist/built-files.js +22 -0
  17. package/dist/cache.d.ts +44 -0
  18. package/dist/cache.js +99 -0
  19. package/dist/client-components.d.ts +3 -0
  20. package/dist/client-components.js +4 -0
  21. package/dist/client-file-key.d.ts +5 -0
  22. package/dist/client-file-key.js +5 -0
  23. package/dist/client-files.d.ts +83 -0
  24. package/dist/client-files.js +186 -0
  25. package/dist/client-graph.d.ts +94 -0
  26. package/dist/client-graph.js +266 -0
  27. package/dist/client-modules.d.ts +10 -0
  28. package/dist/client-modules.js +43 -0
  29. package/dist/client.d.ts +42 -0
  30. package/dist/client.js +263 -0
  31. package/dist/commonjs.d.ts +44 -0
  32. package/dist/commonjs.js +111 -0
  33. package/dist/compat/browser/client.d.ts +19 -0
  34. package/dist/compat/browser/client.js +13 -0
  35. package/dist/compat/build.d.ts +145 -0
  36. package/dist/compat/build.js +149 -0
  37. package/dist/compat/checks.d.ts +16 -0
  38. package/dist/compat/checks.js +148 -0
  39. package/dist/compat/patches.d.ts +13 -0
  40. package/dist/compat/patches.js +30 -0
  41. package/dist/compat/paths.d.ts +74 -0
  42. package/dist/compat/paths.js +160 -0
  43. package/dist/compat/rsc/handlers.d.ts +2 -0
  44. package/dist/compat/rsc/handlers.js +2 -0
  45. package/dist/compat/rsc/prerender.d.ts +10 -0
  46. package/dist/compat/rsc/prerender.js +9 -0
  47. package/dist/compat/server/headers.d.ts +3 -0
  48. package/dist/compat/server/headers.js +3 -0
  49. package/dist/compat/ssr/build-output.d.ts +4 -0
  50. package/dist/compat/ssr/build-output.js +3 -0
  51. package/dist/compat/ssr/cache.d.ts +6 -0
  52. package/dist/compat/ssr/cache.js +6 -0
  53. package/dist/compat/ssr/handler.d.ts +8 -0
  54. package/dist/compat/ssr/handler.js +8 -0
  55. package/dist/compat/ssr/node-server.d.ts +5 -0
  56. package/dist/compat/ssr/node-server.js +4 -0
  57. package/dist/compat/ssr/render-errors.d.ts +4 -0
  58. package/dist/compat/ssr/render-errors.js +4 -0
  59. package/dist/compat/ssr/senders.d.ts +6 -0
  60. package/dist/compat/ssr/senders.js +6 -0
  61. package/dist/compat/types.d.ts +8 -0
  62. package/dist/compat/types.js +1 -0
  63. package/dist/compile.d.ts +31 -0
  64. package/dist/compile.js +140 -0
  65. package/dist/disk.d.ts +16 -0
  66. package/dist/disk.js +13 -0
  67. package/dist/document-loads.d.ts +15 -0
  68. package/dist/document-loads.js +53 -0
  69. package/dist/document.d.ts +79 -0
  70. package/dist/document.js +328 -0
  71. package/dist/downloads.d.ts +15 -0
  72. package/dist/downloads.js +71 -0
  73. package/dist/esm-require.d.ts +11 -0
  74. package/dist/esm-require.js +32 -0
  75. package/dist/fast-crypto/index.js +1093 -0
  76. package/dist/fast-crypto.d.ts +20 -0
  77. package/dist/fast-crypto.js +151 -0
  78. package/dist/flight.d.ts +19 -0
  79. package/dist/flight.js +42 -0
  80. package/dist/form-submission.d.ts +15 -0
  81. package/dist/form-submission.js +27 -0
  82. package/dist/from-page.d.ts +5 -0
  83. package/dist/from-page.js +44 -0
  84. package/dist/globals.d.ts +1 -0
  85. package/dist/globals.js +197 -0
  86. package/dist/host-document.d.ts +26 -0
  87. package/dist/host-document.js +34 -0
  88. package/dist/index.d.ts +280 -0
  89. package/dist/index.js +281 -0
  90. package/dist/internal.d.ts +2 -0
  91. package/dist/internal.js +3 -0
  92. package/dist/leftovers.d.ts +11 -0
  93. package/dist/leftovers.js +55 -0
  94. package/dist/mode.d.ts +169 -0
  95. package/dist/mode.js +31 -0
  96. package/dist/node/LICENSES.md +3540 -0
  97. package/dist/node/assert/strict.js +29 -0
  98. package/dist/node/assert.js +3044 -0
  99. package/dist/node/buffer.js +1499 -0
  100. package/dist/node/child_process.js +45 -0
  101. package/dist/node/cluster.js +85 -0
  102. package/dist/node/console.js +96 -0
  103. package/dist/node/constants.js +495 -0
  104. package/dist/node/crypto.js +1388 -0
  105. package/dist/node/dgram.js +78 -0
  106. package/dist/node/diagnostics_channel.js +122 -0
  107. package/dist/node/dns/promises.js +129 -0
  108. package/dist/node/dns.js +137 -0
  109. package/dist/node/domain.js +43 -0
  110. package/dist/node/events.js +1155 -0
  111. package/dist/node/fs/promises.js +40 -0
  112. package/dist/node/fs.js +10375 -0
  113. package/dist/node/http.js +326 -0
  114. package/dist/node/http2.js +305 -0
  115. package/dist/node/https.js +57 -0
  116. package/dist/node/inspector/promises.js +66 -0
  117. package/dist/node/inspector.js +76 -0
  118. package/dist/node/module.js +205 -0
  119. package/dist/node/net.js +392 -0
  120. package/dist/node/os.js +259 -0
  121. package/dist/node/path/posix.js +25 -0
  122. package/dist/node/path/win32.js +25 -0
  123. package/dist/node/path.js +384 -0
  124. package/dist/node/perf_hooks.js +313 -0
  125. package/dist/node/process.js +452 -0
  126. package/dist/node/punycode.js +178 -0
  127. package/dist/node/querystring.js +934 -0
  128. package/dist/node/readline/promises.js +71 -0
  129. package/dist/node/readline.js +56 -0
  130. package/dist/node/repl.js +44 -0
  131. package/dist/node/sqlite.js +22 -0
  132. package/dist/node/stream/consumers.js +47 -0
  133. package/dist/node/stream/promises.js +6 -0
  134. package/dist/node/stream/web.js +52 -0
  135. package/dist/node/stream.js +4323 -0
  136. package/dist/node/string_decoder.js +276 -0
  137. package/dist/node/sys.js +6 -0
  138. package/dist/node/timers/promises.js +71 -0
  139. package/dist/node/timers.js +133 -0
  140. package/dist/node/tls.js +122 -0
  141. package/dist/node/trace_events.js +23 -0
  142. package/dist/node/tty.js +69 -0
  143. package/dist/node/url.js +1426 -0
  144. package/dist/node/util/types.js +1456 -0
  145. package/dist/node/util.js +4807 -0
  146. package/dist/node/v8.js +160 -0
  147. package/dist/node/vm.js +88 -0
  148. package/dist/node/wasi.js +16 -0
  149. package/dist/node/worker_threads.js +123 -0
  150. package/dist/node/zlib.js +1396 -0
  151. package/dist/node-builtins.d.ts +40 -0
  152. package/dist/node-builtins.js +74 -0
  153. package/dist/node-on-page.d.ts +46 -0
  154. package/dist/node-on-page.js +101 -0
  155. package/dist/node-platform.d.ts +36 -0
  156. package/dist/node-platform.js +152 -0
  157. package/dist/node-rendered.d.ts +21 -0
  158. package/dist/node-rendered.js +26 -0
  159. package/dist/node-server.d.ts +46 -0
  160. package/dist/node-server.js +193 -0
  161. package/dist/optimizer-cache-key.d.ts +26 -0
  162. package/dist/optimizer-cache-key.js +73 -0
  163. package/dist/own-package.d.ts +1 -0
  164. package/dist/own-package.js +6 -0
  165. package/dist/page-store.d.ts +33 -0
  166. package/dist/page-store.js +80 -0
  167. package/dist/page-timers.d.ts +22 -0
  168. package/dist/page-timers.js +47 -0
  169. package/dist/page.d.ts +112 -0
  170. package/dist/page.js +549 -0
  171. package/dist/paths.d.ts +13 -0
  172. package/dist/paths.js +47 -0
  173. package/dist/plugin.d.ts +22 -0
  174. package/dist/plugin.js +995 -0
  175. package/dist/prerender-verdict.d.ts +8 -0
  176. package/dist/prerender-verdict.js +67 -0
  177. package/dist/project/context.d.ts +546 -0
  178. package/dist/project/context.js +111 -0
  179. package/dist/project/entries.d.ts +42 -0
  180. package/dist/project/entries.js +189 -0
  181. package/dist/project/env-worker.d.ts +1 -0
  182. package/dist/project/env-worker.js +9 -0
  183. package/dist/project/env.d.ts +36 -0
  184. package/dist/project/env.js +82 -0
  185. package/dist/project/layers.d.ts +31 -0
  186. package/dist/project/layers.js +150 -0
  187. package/dist/project/loaders.d.ts +71 -0
  188. package/dist/project/loaders.js +300 -0
  189. package/dist/project/metadata.d.ts +8 -0
  190. package/dist/project/metadata.js +34 -0
  191. package/dist/project/module-exports.d.ts +29 -0
  192. package/dist/project/module-exports.js +77 -0
  193. package/dist/project/routes.d.ts +19 -0
  194. package/dist/project/routes.js +92 -0
  195. package/dist/project/routing.d.ts +46 -0
  196. package/dist/project/routing.js +280 -0
  197. package/dist/project/transform.d.ts +8 -0
  198. package/dist/project/transform.js +110 -0
  199. package/dist/project/webpack.d.ts +46 -0
  200. package/dist/project/webpack.js +160 -0
  201. package/dist/project.d.ts +264 -0
  202. package/dist/project.js +58 -0
  203. package/dist/registry-global.d.ts +5 -0
  204. package/dist/registry-global.js +5 -0
  205. package/dist/registry.d.ts +241 -0
  206. package/dist/registry.js +30 -0
  207. package/dist/route-chunks.d.ts +13 -0
  208. package/dist/route-chunks.js +32 -0
  209. package/dist/route-lookup.d.ts +34 -0
  210. package/dist/route-lookup.js +207 -0
  211. package/dist/routes-ahead-shared.d.ts +17 -0
  212. package/dist/routes-ahead-shared.js +9 -0
  213. package/dist/routes-ahead.d.ts +10 -0
  214. package/dist/routes-ahead.js +54 -0
  215. package/dist/rsc.d.ts +19 -0
  216. package/dist/rsc.js +171 -0
  217. package/dist/server-action.d.ts +9 -0
  218. package/dist/server-action.js +15 -0
  219. package/dist/server-code.d.ts +176 -0
  220. package/dist/server-code.js +357 -0
  221. package/dist/server-in-front.d.ts +37 -0
  222. package/dist/server-in-front.js +90 -0
  223. package/dist/server-layers.d.ts +22 -0
  224. package/dist/server-layers.js +33 -0
  225. package/dist/setup-browser.d.ts +1 -0
  226. package/dist/setup-browser.js +8 -0
  227. package/dist/setup-node.d.ts +1 -0
  228. package/dist/setup-node.js +6 -0
  229. package/dist/setup.d.ts +8 -0
  230. package/dist/setup.js +62 -0
  231. package/dist/speed-features.d.ts +13 -0
  232. package/dist/speed-features.js +95 -0
  233. package/dist/ssr.d.ts +70 -0
  234. package/dist/ssr.js +480 -0
  235. package/dist/static-build.d.ts +36 -0
  236. package/dist/static-build.js +92 -0
  237. package/dist/storage.d.ts +31 -0
  238. package/dist/storage.js +94 -0
  239. package/dist/styles-shared.d.ts +137 -0
  240. package/dist/styles-shared.js +124 -0
  241. package/dist/styles.d.ts +102 -0
  242. package/dist/styles.js +730 -0
  243. package/dist/stylesheet-versions.d.ts +17 -0
  244. package/dist/stylesheet-versions.js +43 -0
  245. package/dist/tester.html +10 -0
  246. package/dist/use-cache.d.ts +15 -0
  247. package/dist/use-cache.js +93 -0
  248. package/dist/vitest-version.d.ts +6 -0
  249. package/dist/vitest-version.js +12 -0
  250. package/package.json +125 -4
package/dist/client.js ADDED
@@ -0,0 +1,263 @@
1
+ import { registry } from "./registry.js";
2
+ import { recordListeners } from "./leftovers.js";
3
+ import { registerModuleLoader } from "./client-modules.js";
4
+ import { AppRouter, HeadManagerContext, appBootstrap, callServer, createInitialRouterState, createMutableActionQueue, invalidateBfCache, invalidateEntirePrefetchCache, loadAppIndex } from "./compat/browser/client.js";
5
+ import { unstable_rethrow } from "next/navigation.js";
6
+ import { Fragment, StrictMode, useEffect } from "react";
7
+ import { flushSync } from "react-dom";
8
+ import ReactDOMClient from "react-dom/client";
9
+ import { createFromReadableStream } from "@vitejs/plugin-rsc/vendor/react-server-dom/client.browser";
10
+ import { setNodeOnPage } from "@kasperpeulen/vitest-plugin-nextjs/node-rendered";
11
+ import { jsx } from "react/jsx-runtime";
12
+ //#region src/client.tsx
13
+ let current;
14
+ function report(error) {
15
+ if (!current) return;
16
+ current.nodeOnPage?.errored(error);
17
+ if (!current.signal.aborted && !isNextControlFlow(error)) current.errors.push(error);
18
+ }
19
+ function reportingErrors(options, report) {
20
+ const { onCaughtError, onUncaughtError } = options ?? {};
21
+ if (!options || !onCaughtError || !onUncaughtError) return options;
22
+ return {
23
+ ...options,
24
+ onCaughtError(error, info) {
25
+ report(error);
26
+ onCaughtError(error, info);
27
+ },
28
+ onUncaughtError(error, info) {
29
+ report(error);
30
+ onUncaughtError(error, info);
31
+ }
32
+ };
33
+ }
34
+ function isNextControlFlow(error) {
35
+ try {
36
+ unstable_rethrow(error);
37
+ return false;
38
+ } catch (thrown) {
39
+ return thrown === error;
40
+ }
41
+ }
42
+ /**
43
+ * Hydrates the document, or with a `container`, the node of a test in it.
44
+ * Resolves once it has, with how to leave the page. Calls `loaded` once Next's
45
+ * client has loaded, before a module of the app has. A page of a node tells
46
+ * `nodeOnPage` what it does with the node: see node-rendered.tsx. The errors
47
+ * that React reports on the root of the app go in `errors`, in order, but
48
+ * for those of Next's control flow.
49
+ *
50
+ * Rejects once `signal` aborts, when the page is left before it has hydrated.
51
+ * What it started is gone by then: the root, and the listeners React added.
52
+ * A root that Next would create after that renders nothing.
53
+ */
54
+ async function start(loaded, container, signal, nodeOnPage, errors, keep = false) {
55
+ setNodeOnPage(nodeOnPage);
56
+ const page = {
57
+ signal,
58
+ errors,
59
+ nodeOnPage,
60
+ leaving: false
61
+ };
62
+ current = page;
63
+ let nextLoaded;
64
+ const forgetLoader = registerModuleLoader("browser", new Promise((resolve) => nextLoaded = resolve));
65
+ globalThis.__viteRscCallServer = callServer;
66
+ let root;
67
+ const listeners = [];
68
+ const { hydrateRoot, createRoot } = ReactDOMClient;
69
+ const keepRoot = (target, create) => {
70
+ if (signal.aborted) return {
71
+ render() {},
72
+ unmount() {}
73
+ };
74
+ const isApp = target === document;
75
+ const to = isApp && container ? container : target;
76
+ const added = (isApp && container ? [document, container] : [document]).map((of) => recordListeners(of));
77
+ listeners.push(...added);
78
+ try {
79
+ const created = create(to, isApp);
80
+ if (isApp) root = created;
81
+ return created;
82
+ } finally {
83
+ for (const recorded of added) recorded.stop();
84
+ }
85
+ };
86
+ ReactDOMClient.hydrateRoot = (target, children, options) => keepRoot(target, (to, isApp) => hydrateRoot(to, children, {
87
+ ...isApp ? reportingErrors(options, report) : options,
88
+ onRecoverableError(error, info) {
89
+ if (current?.leaving) return;
90
+ if (options?.onRecoverableError) options.onRecoverableError(error, info);
91
+ else reportError(error);
92
+ }
93
+ }));
94
+ ReactDOMClient.createRoot = (target, options) => keepRoot(target, (to, isApp) => createRoot(to, isApp ? reportingErrors(options, report) : options));
95
+ const leave = () => {
96
+ page.leaving = true;
97
+ forgetLoader();
98
+ root?.unmount();
99
+ for (const added of listeners) added.remove();
100
+ };
101
+ const firstSegments = [...documentSegments()];
102
+ try {
103
+ const { hydrate } = await loadAppIndex();
104
+ loaded();
105
+ nextLoaded();
106
+ signal.throwIfAborted();
107
+ const bootstrapScript = document.querySelector("script[src*='/_next/']");
108
+ if (!bootstrapScript) throw new Error("vitest-plugin-rsc: the response is not a page of the Next.js app");
109
+ Object.defineProperty(document, "currentScript", {
110
+ configurable: true,
111
+ value: bootstrapScript
112
+ });
113
+ try {
114
+ await new Promise((resolve, reject) => {
115
+ const abort = () => reject(signal.reason);
116
+ signal.addEventListener("abort", abort, { once: true });
117
+ globalThis.__NEXT_HYDRATED_CB = () => {
118
+ signal.removeEventListener("abort", abort);
119
+ resolve();
120
+ };
121
+ appBootstrap((assetPrefix) => {
122
+ hydrate([], assetPrefix).catch(reject);
123
+ });
124
+ });
125
+ } finally {
126
+ delete document.currentScript;
127
+ delete globalThis.__NEXT_HYDRATED_CB;
128
+ }
129
+ } catch (error) {
130
+ leave();
131
+ throw error;
132
+ } finally {
133
+ if (!signal.aborted) {
134
+ ReactDOMClient.hydrateRoot = hydrateRoot;
135
+ ReactDOMClient.createRoot = createRoot;
136
+ }
137
+ }
138
+ if (!root) throw new Error("vitest-plugin-rsc: Next.js did not create a React root on the document, which the plugin needs to leave the page.");
139
+ if (!keep) return {
140
+ unmount: leave,
141
+ leaveApp: leave
142
+ };
143
+ let globalError;
144
+ app = {
145
+ root,
146
+ renders: 0,
147
+ globalError: () => globalError ??= Promise.resolve(createFromReadableStream(documentPayload(firstSegments), { callServer })).then((payload) => payload.G, (error) => {
148
+ globalError = void 0;
149
+ throw error;
150
+ })
151
+ };
152
+ return {
153
+ unmount: () => leavePage(page, forgetLoader),
154
+ leaveApp() {
155
+ app = void 0;
156
+ leave();
157
+ }
158
+ };
159
+ }
160
+ let app;
161
+ function leavePage(page, forgetLoader) {
162
+ page.leaving = true;
163
+ forgetLoader();
164
+ flushSync(() => app?.root.render(null));
165
+ }
166
+ const documentSegments = () => self.__next_f ?? [];
167
+ function documentPayload(segments = documentSegments()) {
168
+ const encoder = new TextEncoder();
169
+ return new ReadableStream({ start(controller) {
170
+ for (const [kind, data = ""] of segments) if (kind === 1) controller.enqueue(encoder.encode(data));
171
+ else if (kind === 3) controller.enqueue(Uint8Array.from(atob(data), (c) => c.charCodeAt(0)));
172
+ controller.close();
173
+ } });
174
+ }
175
+ function streamOfBytes(bytes) {
176
+ return new ReadableStream({ start(controller) {
177
+ controller.enqueue(bytes);
178
+ controller.close();
179
+ } });
180
+ }
181
+ function Committed({ onCommit, children }) {
182
+ useEffect(onCommit, [onCommit]);
183
+ return children;
184
+ }
185
+ /**
186
+ * Renders the page in the document into the root of the app that `start()`
187
+ * kept, in place of the page before it: what Next's entry does as the page
188
+ * loads, without the entry, from the Flight payload in the document. The
189
+ * modules of the app stay, and so does its root, so this is no page load:
190
+ * its Flight payload is decoded, the router gets a state of its own from it,
191
+ * and a tree with a key of its own mounts.
192
+ * Resolves as `start()` does, once it has rendered.
193
+ *
194
+ * What the modules of the app keep stays from the page before: Next's caches
195
+ * of its router are emptied, but the state of a module of the app, or of a
196
+ * package, is still there.
197
+ */
198
+ async function renderAgain(signal, errors, flight) {
199
+ const kept = app;
200
+ if (!kept) throw new Error("vitest-plugin-rsc: there is no kept app to render the page in.");
201
+ setNodeOnPage(void 0);
202
+ const page = {
203
+ signal,
204
+ errors,
205
+ nodeOnPage: void 0,
206
+ leaving: false
207
+ };
208
+ current = page;
209
+ const forgetLoader = registerModuleLoader("browser");
210
+ globalThis.__viteRscCallServer = callServer;
211
+ invalidateEntirePrefetchCache(null, null);
212
+ invalidateBfCache();
213
+ try {
214
+ const payload = await createFromReadableStream(flight ? streamOfBytes(flight) : documentPayload(), { callServer });
215
+ const globalErrorState = payload.G ?? await kept.globalError();
216
+ signal.throwIfAborted();
217
+ registry.replacingRouter = true;
218
+ let actionQueue;
219
+ try {
220
+ actionQueue = createMutableActionQueue(createInitialRouterState({
221
+ navigatedAt: Date.now(),
222
+ initialRSCPayload: payload.c ? payload : {
223
+ ...payload,
224
+ c: (location.pathname + location.search).split("/")
225
+ },
226
+ initialFlightStreamForCache: null,
227
+ location: window.location
228
+ }));
229
+ } finally {
230
+ registry.replacingRouter = false;
231
+ }
232
+ const Strict = process.env.__NEXT_STRICT_MODE_APP ? StrictMode : Fragment;
233
+ await new Promise((resolve, reject) => {
234
+ const abort = () => reject(signal.reason);
235
+ signal.addEventListener("abort", abort, { once: true });
236
+ const committed = () => {
237
+ signal.removeEventListener("abort", abort);
238
+ resolve();
239
+ };
240
+ kept.root.render(/* @__PURE__ */ jsx(Strict, { children: /* @__PURE__ */ jsx(HeadManagerContext.Provider, {
241
+ value: { appDir: true },
242
+ children: /* @__PURE__ */ jsx(Committed, {
243
+ onCommit: committed,
244
+ children: /* @__PURE__ */ jsx(AppRouter, {
245
+ actionQueue,
246
+ globalErrorState
247
+ }, ++kept.renders)
248
+ })
249
+ }) }));
250
+ });
251
+ } catch (error) {
252
+ leavePage(page, forgetLoader);
253
+ throw error;
254
+ }
255
+ return {
256
+ unmount: () => leavePage(page, forgetLoader),
257
+ leaveApp() {
258
+ app = void 0;
259
+ }
260
+ };
261
+ }
262
+ //#endregion
263
+ export { renderAgain, start };
@@ -0,0 +1,44 @@
1
+ import { NextLayer } from "./project.js";
2
+ import { Plugin } from "vite";
3
+ import MagicString from "magic-string";
4
+
5
+ //#region src/commonjs.d.ts
6
+ declare const missingHelper = "const $$cjsMissing = (source) => { throw Object.assign(new Error(`Cannot find module '${source}'`), { code: \"MODULE_NOT_FOUND\" }); };\n";
7
+ /** What `compileCommonJs()` needs of the file. */
8
+ type CommonJsOptions = {
9
+ /** The language of the code: `parseAstAsync` of Vite takes TypeScript as well. */lang?: "js" | "jsx" | "ts" | "tsx";
10
+ /**
11
+ * Whether a `require()` in a `try` finds its module. A module that is not
12
+ * there throws when the call runs, so the `catch` runs, as it does with
13
+ * webpack. Without this, every `require()` is an import.
14
+ */
15
+ resolves?: (source: string) => Promise<boolean>;
16
+ /**
17
+ * Whether a `require()` of `source` returns the default export of its
18
+ * module: a module of Node.js that is Node's own, whose default export is
19
+ * its `module.exports`, where the namespace of `node:events` is not the
20
+ * class. Without this, a module of Node.js is the ES module of a stand-in.
21
+ */
22
+ requiresDefault?: (source: string) => boolean;
23
+ };
24
+ type Node = {
25
+ type: string;
26
+ start: number;
27
+ end: number;
28
+ [key: string]: unknown;
29
+ };
30
+ declare function walk(node: Node, parent?: Node): Generator<[Node, Node | undefined]>;
31
+ /** Compiles CommonJS in a module into ES module code. Nothing for a module without it. */
32
+ declare function compileCommonJs(code: string, {
33
+ lang,
34
+ resolves,
35
+ requiresDefault
36
+ }?: CommonJsOptions): Promise<{
37
+ code: string;
38
+ map: ReturnType<MagicString["generateMap"]>;
39
+ } | undefined>;
40
+ declare function createCommonJsPlugin(layerOf: (environment: string) => NextLayer | undefined, isAppCode: (file: string, layer: NextLayer) => boolean, /** Whether the layer imports Node's own module for `source`: see node-builtins.ts. */
41
+
42
+ isNativeNodeModule: (source: string, layer: NextLayer) => boolean): Plugin;
43
+ //#endregion
44
+ export { CommonJsOptions, Node, compileCommonJs, createCommonJsPlugin, missingHelper, walk };
@@ -0,0 +1,111 @@
1
+ import { parseAstAsync } from "vite";
2
+ import { init, parse } from "cjs-module-lexer";
3
+ import MagicString from "magic-string";
4
+ //#region src/commonjs.ts
5
+ /**
6
+ * The export of a module compiled here that a `require()` of it returns: its
7
+ * `module.exports`. A name, as Vite RSC reads the exports of a `"use client"`
8
+ * module and takes no string for one.
9
+ */
10
+ const moduleExports = "$$cjsModuleExports";
11
+ const requireHelper = `const $$cjsRequire = (ns) => ${JSON.stringify(moduleExports)} in ns ? ns[${JSON.stringify(moduleExports)}] : Object.prototype.toString.call(ns) === "[object Module]" || ns.__esModule ? ns : ns.default;\n`;
12
+ const missingHelper = "const $$cjsMissing = (source) => { throw Object.assign(new Error(`Cannot find module '${source}'`), { code: \"MODULE_NOT_FOUND\" }); };\n";
13
+ const defaultOnly = /\.(?:json|css|scss|sass|less|styl|stylus|pcss)(?:\?|$)/;
14
+ const isNode = (value) => typeof value === "object" && value !== null && typeof value.type === "string";
15
+ function* walk(node, parent) {
16
+ yield [node, parent];
17
+ for (const key in node) {
18
+ const value = node[key];
19
+ for (const child of Array.isArray(value) ? value : [value]) if (isNode(child)) yield* walk(child, node);
20
+ }
21
+ }
22
+ const isIdentifier = (node, name) => isNode(node) && node.type === "Identifier" && node.name === name;
23
+ const identifier = /^[A-Za-z_$][\w$]*$/;
24
+ /** Compiles CommonJS in a module into ES module code. Nothing for a module without it. */
25
+ async function compileCommonJs(code, { lang, resolves, requiresDefault = () => false } = {}) {
26
+ if (!/\brequire\s*\(|\bmodule\.exports\b|\bexports\.[\w$]+\s*=/.test(code)) return;
27
+ const ast = await parseAstAsync(code, { lang });
28
+ const requires = [];
29
+ let ownRequire = false;
30
+ let usesModule = false;
31
+ const tried = /* @__PURE__ */ new Set();
32
+ for (const [node] of walk(ast)) {
33
+ if (node.type !== "TryStatement") continue;
34
+ for (const [inner] of walk(node.block)) if (inner.type === "CallExpression") tried.add(inner);
35
+ }
36
+ for (const [node, parent] of walk(ast)) {
37
+ if (isIdentifier(node, "module") || isIdentifier(node, "exports")) {
38
+ if (!(parent?.type === "MemberExpression" && parent.property === node && !parent.computed || parent?.type === "Property" && parent.key === node && !parent.computed)) usesModule = true;
39
+ }
40
+ if (!isIdentifier(node, "require")) continue;
41
+ const args = parent?.arguments;
42
+ if (parent?.type === "CallExpression" && parent.callee === node) {
43
+ const [source] = args ?? [];
44
+ if (args?.length === 1 && source?.type === "Literal" && typeof source.value === "string") {
45
+ requires.push({
46
+ call: parent,
47
+ source: source.value,
48
+ tried: tried.has(parent)
49
+ });
50
+ continue;
51
+ }
52
+ }
53
+ if (parent?.type === "MemberExpression" && parent.object === node) continue;
54
+ ownRequire = true;
55
+ }
56
+ const isCommonJs = !ast.body.some((statement) => /^(?:Import|ExportNamed|ExportDefault|ExportAll)Declaration$/.test(statement.type)) && usesModule;
57
+ if (ownRequire || requires.length === 0 && !isCommonJs) return;
58
+ const output = new MagicString(code);
59
+ const imports = /* @__PURE__ */ new Map();
60
+ let missing = false;
61
+ for (const { call, source, tried } of requires) {
62
+ if (tried && resolves && !await resolves(source)) {
63
+ missing = true;
64
+ output.overwrite(call.start, call.end, `$$cjsMissing(${JSON.stringify(source)})`);
65
+ continue;
66
+ }
67
+ let name = imports.get(source);
68
+ if (!name) imports.set(source, name = `$$cjs${imports.size}`);
69
+ const value = defaultOnly.test(source) || requiresDefault(source) ? `${name}.default` : `$$cjsRequire(${name})`;
70
+ output.overwrite(call.start, call.end, value);
71
+ }
72
+ let header = [...imports].map(([source, name]) => `import * as ${name} from ${JSON.stringify(source)};\n`).join("");
73
+ if ([...imports.keys()].some((source) => !defaultOnly.test(source) && !requiresDefault(source))) header += requireHelper;
74
+ if (missing) header += missingHelper;
75
+ if (isCommonJs) {
76
+ header += "var module = { exports: {} }, exports = module.exports;\n";
77
+ let footer = `\nvar $$cjsExports = module.exports;\nexport { $$cjsExports as default, $$cjsExports as ${moduleExports} };\n`;
78
+ await init();
79
+ for (const name of new Set(parse(code).exports)) {
80
+ if (!identifier.test(name) || name === "default") continue;
81
+ footer += `var $$cjs_${name} = $$cjsExports.${name};\nexport { $$cjs_${name} as ${name} };\n`;
82
+ }
83
+ output.append(footer);
84
+ }
85
+ const afterDirectives = ast.body.find((statement) => !(statement.type === "ExpressionStatement" && "directive" in statement));
86
+ if (afterDirectives) output.appendLeft(afterDirectives.start, header);
87
+ else output.append(header);
88
+ return {
89
+ code: output.toString(),
90
+ map: output.generateMap({ hires: "boundary" })
91
+ };
92
+ }
93
+ function createCommonJsPlugin(layerOf, isAppCode, isNativeNodeModule) {
94
+ return {
95
+ name: "vitest-plugin-rsc:next-commonjs",
96
+ enforce: "pre",
97
+ async transform(code, id) {
98
+ const layer = layerOf(this.environment.name);
99
+ const file = id.split("?")[0];
100
+ const extension = /\.[cm]?([jt]sx?)$/.exec(file);
101
+ if (!layer || !extension || !isAppCode(file, layer)) return;
102
+ return compileCommonJs(code, {
103
+ lang: extension[1],
104
+ resolves: async (source) => await this.resolve(source, id) !== null,
105
+ requiresDefault: (source) => isNativeNodeModule(source, layer)
106
+ });
107
+ }
108
+ };
109
+ }
110
+ //#endregion
111
+ export { compileCommonJs, createCommonJsPlugin, missingHelper, walk };
@@ -0,0 +1,19 @@
1
+ import { appBootstrap } from "next/dist/client/app-bootstrap.js";
2
+ import { callServer } from "next/dist/client/app-call-server.js";
3
+ import AppRouter from "next/dist/client/components/app-router.js";
4
+ import { createMutableActionQueue } from "next/dist/client/components/app-router-instance.js";
5
+ import { createInitialRouterState } from "next/dist/client/components/router-reducer/create-initial-router-state.js";
6
+ import { invalidateBfCache } from "next/dist/client/components/segment-cache/bfcache.js";
7
+ import { invalidateEntirePrefetchCache } from "next/dist/client/components/segment-cache/cache.js";
8
+ import { HeadManagerContext } from "next/dist/shared/lib/head-manager-context.shared-runtime";
9
+ import * as _$next_dist_client_app_index0 from "next/dist/client/app-index.js";
10
+ import * as _$next_dist_client_router_transition_types0 from "next/dist/client/router-transition-types.js";
11
+
12
+ //#region src/compat/browser/client.d.ts
13
+ /** Next's client entry, which reads the Flight payload in the document as it loads. */
14
+ declare const loadAppIndex: () => Promise<{
15
+ default: typeof _$next_dist_client_app_index0;
16
+ hydrate(instrumentationModules: _$next_dist_client_router_transition_types0.ClientInstrumentationModules, assetPrefix: string): Promise<void>;
17
+ }>;
18
+ //#endregion
19
+ export { AppRouter, HeadManagerContext, appBootstrap, callServer, createInitialRouterState, createMutableActionQueue, invalidateBfCache, invalidateEntirePrefetchCache, loadAppIndex };
@@ -0,0 +1,13 @@
1
+ import { appBootstrap } from "next/dist/client/app-bootstrap.js";
2
+ import { callServer } from "next/dist/client/app-call-server.js";
3
+ import AppRouter from "next/dist/client/components/app-router.js";
4
+ import { createMutableActionQueue } from "next/dist/client/components/app-router-instance.js";
5
+ import { createInitialRouterState } from "next/dist/client/components/router-reducer/create-initial-router-state.js";
6
+ import { invalidateBfCache } from "next/dist/client/components/segment-cache/bfcache.js";
7
+ import { invalidateEntirePrefetchCache } from "next/dist/client/components/segment-cache/cache.js";
8
+ import { HeadManagerContext } from "next/dist/shared/lib/head-manager-context.shared-runtime";
9
+ //#region src/compat/browser/client.ts
10
+ /** Next's client entry, which reads the Flight payload in the document as it loads. */
11
+ const loadAppIndex = () => import("next/dist/client/app-index.js");
12
+ //#endregion
13
+ export { AppRouter, HeadManagerContext, appBootstrap, callServer, createInitialRouterState, createMutableActionQueue, invalidateBfCache, invalidateEntirePrefetchCache, loadAppIndex };
@@ -0,0 +1,145 @@
1
+ import { Loader } from "../project/loaders.js";
2
+ import { AppLoaderContext } from "../project/entries.js";
3
+ import * as _$next_dist_server_lib_incremental_cache_index0 from "next/dist/server/lib/incremental-cache/index.js";
4
+ import * as _$next_dist_shared_lib_router_utils_route_regex0 from "next/dist/shared/lib/router/utils/route-regex.js";
5
+ import * as _$next_dist_build_adapter_build_complete0 from "next/dist/build/adapter/build-complete.js";
6
+ import * as _$next_dist_build_analysis_get_page_static_info0 from "next/dist/build/analysis/get-page-static-info.js";
7
+ import * as _$next_dist_lib_load_custom_routes0 from "next/dist/lib/load-custom-routes.js";
8
+ import * as _$next_dist_build_route_discovery0 from "next/dist/build/route-discovery.js";
9
+ import * as _$next_dist_build_normalize_catchall_routes0 from "next/dist/build/normalize-catchall-routes.js";
10
+ import * as _$next_dist_shared_lib_router_utils_app_paths0 from "next/dist/shared/lib/router/utils/app-paths.js";
11
+ import * as _$next_dist_lib_is_app_route_route0 from "next/dist/lib/is-app-route-route.js";
12
+ import * as _$next_dist_lib_is_app_page_route0 from "next/dist/lib/is-app-page-route.js";
13
+ import * as _$next_dist_shared_lib_router_utils_interception_routes0 from "next/dist/shared/lib/router/utils/interception-routes.js";
14
+ import * as _$next_dist_shared_lib_errors_missing_canonical_interception_routes_error0 from "next/dist/shared/lib/errors/missing-canonical-interception-routes-error.js";
15
+ import * as _$next_dist_shared_lib_errors_incompatible_parallel_route_slots_error0 from "next/dist/shared/lib/errors/incompatible-parallel-route-slots-error.js";
16
+ import * as _$next_dist_shared_lib_errors_unmatched_app_pages_error0 from "next/dist/shared/lib/errors/unmatched-app-pages-error.js";
17
+ import * as _$next_dist_build_define_env0 from "next/dist/build/define-env.js";
18
+ import * as _$next_dist_lib_static_env0 from "next/dist/lib/static-env.js";
19
+ import * as _$next_dist_build_create_compiler_aliases0 from "next/dist/build/create-compiler-aliases.js";
20
+ import * as _$next_dist_lib_needs_experimental_react0 from "next/dist/lib/needs-experimental-react.js";
21
+ import * as _$next_dist_build_load_entrypoint0 from "next/dist/build/load-entrypoint.js";
22
+ import * as _$next_dist_build_swc_index0 from "next/dist/build/swc/index.js";
23
+ import * as _$next_dist_build_swc_options0 from "next/dist/build/swc/options.js";
24
+ import * as _$next_dist_build_load_jsconfig0 from "next/dist/build/load-jsconfig.js";
25
+ import * as _$next_dist_build_webpack_config_blocks_css_loaders_next_font0 from "next/dist/build/webpack/config/blocks/css/loaders/next-font.js";
26
+ import * as _$next_dist_build_webpack_config_blocks_css_plugins0 from "next/dist/build/webpack/config/blocks/css/plugins.js";
27
+ import * as _$next_dist_build_get_supported_browsers0 from "next/dist/build/get-supported-browsers.js";
28
+ import * as _$next_dist_build_webpack_config_blocks_css_loaders_modules0 from "next/dist/build/webpack/config/blocks/css/loaders/modules.js";
29
+ import * as _$next_dist_lib_find_config0 from "next/dist/lib/find-config.js";
30
+ import * as _$next_dist_server_image_optimizer0 from "next/dist/server/image-optimizer.js";
31
+ import * as _$next_dist_lib_generate_interception_routes_rewrites0 from "next/dist/lib/generate-interception-routes-rewrites.js";
32
+ import * as _$next_dist_build_generate_routes_manifest0 from "next/dist/build/generate-routes-manifest.js";
33
+ import * as _$next_dist_lib_bundler0 from "next/dist/lib/bundler.js";
34
+ import * as _$next_dist_lib_get_files_in_dir0 from "next/dist/lib/get-files-in-dir.js";
35
+ import * as _$next_dist_build_get_static_info_including_layouts0 from "next/dist/build/get-static-info-including-layouts.js";
36
+ import * as _$next_dist_build_entries0 from "next/dist/build/entries.js";
37
+ import * as _$next_dist_server_config0 from "next/dist/server/config.js";
38
+ import * as _$next_dist_lib_find_pages_dir0 from "next/dist/lib/find-pages-dir.js";
39
+ import * as _$next_dist_build_generate_build_id0 from "next/dist/build/generate-build-id.js";
40
+
41
+ //#region src/compat/build.d.ts
42
+ /**
43
+ * The build code of the `next` that `projectRequire` finds. `fail` stops the
44
+ * run with what differs, and the version of that `next`.
45
+ */
46
+ declare function loadNextBuild(projectRequire: NodeJS.Require, fail: (what: string, cause?: unknown) => never): {
47
+ loadConfig: typeof _$next_dist_server_config0.default;
48
+ PHASE_PRODUCTION_BUILD: "phase-production-build";
49
+ findPagesDir: typeof _$next_dist_lib_find_pages_dir0.findPagesDir;
50
+ generateBuildId: typeof _$next_dist_build_generate_build_id0.generateBuildId;
51
+ COMPILER_NAMES: {
52
+ readonly client: "client";
53
+ readonly server: "server";
54
+ readonly edgeServer: "edge-server";
55
+ };
56
+ APP_DIR_ALIAS: string;
57
+ MIDDLEWARE_FILENAME: string;
58
+ PROXY_FILENAME: string;
59
+ WEBPACK_LAYERS: {
60
+ GROUP: {
61
+ builtinReact: ("rsc" | "action-browser")[];
62
+ serverOnly: ("middleware" | "rsc" | "action-browser" | "instrument")[];
63
+ neutralTarget: ("api-node" | "api-edge")[];
64
+ clientOnly: ("ssr" | "app-pages-browser")[];
65
+ bundled: ("shared" | "middleware" | "rsc" | "ssr" | "action-browser" | "instrument" | "app-pages-browser")[];
66
+ appPages: ("rsc" | "ssr" | "action-browser" | "app-pages-browser")[];
67
+ };
68
+ shared: "shared";
69
+ reactServerComponents: "rsc";
70
+ serverSideRendering: "ssr";
71
+ actionBrowser: "action-browser";
72
+ apiNode: "api-node";
73
+ apiEdge: "api-edge";
74
+ middleware: "middleware";
75
+ instrument: "instrument";
76
+ edgeAsset: "edge-asset";
77
+ appPagesBrowser: "app-pages-browser";
78
+ pagesDirBrowser: "pages-dir-browser";
79
+ pagesDirEdge: "pages-dir-edge";
80
+ pagesDirNode: "pages-dir-node";
81
+ };
82
+ WEBPACK_RESOURCE_QUERIES: {
83
+ edgeSSREntry: string;
84
+ metadata: string;
85
+ metadataRoute: string;
86
+ metadataImageMeta: string;
87
+ };
88
+ discoverRoutes: typeof _$next_dist_build_route_discovery0.discoverRoutes;
89
+ createPagesMapping: typeof _$next_dist_build_route_discovery0.createPagesMapping;
90
+ normalizeCatchAllRoutes: typeof _$next_dist_build_normalize_catchall_routes0.normalizeCatchAllRoutes;
91
+ normalizeAppPath: typeof _$next_dist_shared_lib_router_utils_app_paths0.normalizeAppPath;
92
+ compareAppPaths: typeof _$next_dist_shared_lib_router_utils_app_paths0.compareAppPaths;
93
+ selectAppPageEntry: typeof _$next_dist_shared_lib_router_utils_app_paths0.selectAppPageEntry;
94
+ isAppRouteRoute: typeof _$next_dist_lib_is_app_route_route0.isAppRouteRoute;
95
+ isAppPageRoute: typeof _$next_dist_lib_is_app_page_route0.isAppPageRoute;
96
+ findMissingCanonicalInterceptionRoutes: typeof _$next_dist_shared_lib_router_utils_interception_routes0.findMissingCanonicalInterceptionRoutes;
97
+ MissingCanonicalInterceptionRoutesError: typeof _$next_dist_shared_lib_errors_missing_canonical_interception_routes_error0.MissingCanonicalInterceptionRoutesError;
98
+ IncompatibleParallelRouteSlotsError: typeof _$next_dist_shared_lib_errors_incompatible_parallel_route_slots_error0.IncompatibleParallelRouteSlotsError;
99
+ UnmatchedAppPagesError: typeof _$next_dist_shared_lib_errors_unmatched_app_pages_error0.UnmatchedAppPagesError;
100
+ getDefineEnv: typeof _$next_dist_build_define_env0.getDefineEnv;
101
+ getNextPublicEnvironmentVariables: typeof _$next_dist_lib_static_env0.getNextPublicEnvironmentVariables;
102
+ getNextConfigEnv: typeof _$next_dist_lib_static_env0.getNextConfigEnv;
103
+ SUPPORTED_NATIVE_MODULES: readonly ["buffer", "events", "assert", "util", "async_hooks"];
104
+ compilerAliases: typeof _$next_dist_build_create_compiler_aliases0;
105
+ needsExperimentalReact: typeof _$next_dist_lib_needs_experimental_react0.needsExperimentalReact;
106
+ loadEntrypoint: typeof _$next_dist_build_load_entrypoint0.loadEntrypoint;
107
+ nextAppLoader: (this: AppLoaderContext) => Promise<string>;
108
+ IncrementalCache: typeof _$next_dist_server_lib_incremental_cache_index0.IncrementalCache;
109
+ swc: typeof _$next_dist_build_swc_index0;
110
+ getLoaderSWCOptions: typeof _$next_dist_build_swc_options0.getLoaderSWCOptions;
111
+ loadJsConfig: typeof _$next_dist_build_load_jsconfig0.default;
112
+ getRSCModuleInformation: typeof _$next_dist_build_analysis_get_page_static_info0.getRSCModuleInformation;
113
+ getAppPageStaticInfo: typeof _$next_dist_build_analysis_get_page_static_info0.getAppPageStaticInfo;
114
+ nextImageLoaderRegex: RegExp;
115
+ nextImageLoader: Loader;
116
+ getNextFontLoader: typeof _$next_dist_build_webpack_config_blocks_css_loaders_next_font0.getNextFontLoader;
117
+ getPostCssPlugins: typeof _$next_dist_build_webpack_config_blocks_css_plugins0.getPostCssPlugins;
118
+ getSupportedBrowsers: typeof _$next_dist_build_get_supported_browsers0.getSupportedBrowsers;
119
+ getCssModuleLoader: typeof _$next_dist_build_webpack_config_blocks_css_loaders_modules0.getCssModuleLoader;
120
+ localByDefault: (options: {
121
+ mode: string;
122
+ }) => never;
123
+ findConfig: typeof _$next_dist_lib_find_config0.findConfig;
124
+ nextFontLoader: Loader;
125
+ nextRootParamsLoader: Loader;
126
+ imageOptimizer: typeof _$next_dist_server_image_optimizer0;
127
+ loadCustomRoutes: typeof _$next_dist_lib_load_custom_routes0.default;
128
+ generateInterceptionRoutesRewrites: typeof _$next_dist_lib_generate_interception_routes_rewrites0.generateInterceptionRoutesRewrites;
129
+ NEXT_URL: "next-url";
130
+ generateRoutesManifest: typeof _$next_dist_build_generate_routes_manifest0.generateRoutesManifest;
131
+ handleBuildComplete: typeof _$next_dist_build_adapter_build_complete0.handleBuildComplete;
132
+ Bundler: typeof _$next_dist_lib_bundler0.Bundler;
133
+ getFilesInDir: typeof _$next_dist_lib_get_files_in_dir0.getFilesInDir;
134
+ rootPageType: never;
135
+ getStaticInfoIncludingLayouts: typeof _$next_dist_build_get_static_info_including_layouts0.getStaticInfoIncludingLayouts;
136
+ getEdgeServerEntry: typeof _$next_dist_build_entries0.getEdgeServerEntry;
137
+ getNamedMiddlewareRegex: typeof _$next_dist_shared_lib_router_utils_route_regex0.getNamedMiddlewareRegex;
138
+ nextMiddlewareLoader: Loader;
139
+ getContentType: (extWithoutDot: string) => string | null;
140
+ getExtension: (contentType: string) => string | null;
141
+ nextMetadataImageLoader: Loader;
142
+ nextMetadataRouteLoader: Loader;
143
+ };
144
+ //#endregion
145
+ export { loadNextBuild };