@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.
- package/README.md +249 -2
- package/dist/_virtual/_rolldown/runtime.js +14 -0
- package/dist/action-ids.d.ts +18 -0
- package/dist/action-ids.js +44 -0
- package/dist/adapter.d.ts +8 -0
- package/dist/adapter.js +12 -0
- package/dist/app-requests.d.ts +63 -0
- package/dist/app-requests.js +253 -0
- package/dist/browser-context.d.ts +24 -0
- package/dist/browser-context.js +157 -0
- package/dist/build-output.d.ts +68 -0
- package/dist/build-output.js +216 -0
- package/dist/build.d.ts +26 -0
- package/dist/build.js +39 -0
- package/dist/built-files.d.ts +9 -0
- package/dist/built-files.js +22 -0
- package/dist/cache.d.ts +44 -0
- package/dist/cache.js +99 -0
- package/dist/client-components.d.ts +3 -0
- package/dist/client-components.js +4 -0
- package/dist/client-file-key.d.ts +5 -0
- package/dist/client-file-key.js +5 -0
- package/dist/client-files.d.ts +83 -0
- package/dist/client-files.js +186 -0
- package/dist/client-graph.d.ts +94 -0
- package/dist/client-graph.js +266 -0
- package/dist/client-modules.d.ts +10 -0
- package/dist/client-modules.js +43 -0
- package/dist/client.d.ts +42 -0
- package/dist/client.js +263 -0
- package/dist/commonjs.d.ts +44 -0
- package/dist/commonjs.js +111 -0
- package/dist/compat/browser/client.d.ts +19 -0
- package/dist/compat/browser/client.js +13 -0
- package/dist/compat/build.d.ts +145 -0
- package/dist/compat/build.js +149 -0
- package/dist/compat/checks.d.ts +16 -0
- package/dist/compat/checks.js +148 -0
- package/dist/compat/patches.d.ts +13 -0
- package/dist/compat/patches.js +30 -0
- package/dist/compat/paths.d.ts +74 -0
- package/dist/compat/paths.js +160 -0
- package/dist/compat/rsc/handlers.d.ts +2 -0
- package/dist/compat/rsc/handlers.js +2 -0
- package/dist/compat/rsc/prerender.d.ts +10 -0
- package/dist/compat/rsc/prerender.js +9 -0
- package/dist/compat/server/headers.d.ts +3 -0
- package/dist/compat/server/headers.js +3 -0
- package/dist/compat/ssr/build-output.d.ts +4 -0
- package/dist/compat/ssr/build-output.js +3 -0
- package/dist/compat/ssr/cache.d.ts +6 -0
- package/dist/compat/ssr/cache.js +6 -0
- package/dist/compat/ssr/handler.d.ts +8 -0
- package/dist/compat/ssr/handler.js +8 -0
- package/dist/compat/ssr/node-server.d.ts +5 -0
- package/dist/compat/ssr/node-server.js +4 -0
- package/dist/compat/ssr/render-errors.d.ts +4 -0
- package/dist/compat/ssr/render-errors.js +4 -0
- package/dist/compat/ssr/senders.d.ts +6 -0
- package/dist/compat/ssr/senders.js +6 -0
- package/dist/compat/types.d.ts +8 -0
- package/dist/compat/types.js +1 -0
- package/dist/compile.d.ts +31 -0
- package/dist/compile.js +140 -0
- package/dist/disk.d.ts +16 -0
- package/dist/disk.js +13 -0
- package/dist/document-loads.d.ts +15 -0
- package/dist/document-loads.js +53 -0
- package/dist/document.d.ts +79 -0
- package/dist/document.js +328 -0
- package/dist/downloads.d.ts +15 -0
- package/dist/downloads.js +71 -0
- package/dist/esm-require.d.ts +11 -0
- package/dist/esm-require.js +32 -0
- package/dist/fast-crypto/index.js +1093 -0
- package/dist/fast-crypto.d.ts +20 -0
- package/dist/fast-crypto.js +151 -0
- package/dist/flight.d.ts +19 -0
- package/dist/flight.js +42 -0
- package/dist/form-submission.d.ts +15 -0
- package/dist/form-submission.js +27 -0
- package/dist/from-page.d.ts +5 -0
- package/dist/from-page.js +44 -0
- package/dist/globals.d.ts +1 -0
- package/dist/globals.js +197 -0
- package/dist/host-document.d.ts +26 -0
- package/dist/host-document.js +34 -0
- package/dist/index.d.ts +280 -0
- package/dist/index.js +281 -0
- package/dist/internal.d.ts +2 -0
- package/dist/internal.js +3 -0
- package/dist/leftovers.d.ts +11 -0
- package/dist/leftovers.js +55 -0
- package/dist/mode.d.ts +169 -0
- package/dist/mode.js +31 -0
- package/dist/node/LICENSES.md +3540 -0
- package/dist/node/assert/strict.js +29 -0
- package/dist/node/assert.js +3044 -0
- package/dist/node/buffer.js +1499 -0
- package/dist/node/child_process.js +45 -0
- package/dist/node/cluster.js +85 -0
- package/dist/node/console.js +96 -0
- package/dist/node/constants.js +495 -0
- package/dist/node/crypto.js +1388 -0
- package/dist/node/dgram.js +78 -0
- package/dist/node/diagnostics_channel.js +122 -0
- package/dist/node/dns/promises.js +129 -0
- package/dist/node/dns.js +137 -0
- package/dist/node/domain.js +43 -0
- package/dist/node/events.js +1155 -0
- package/dist/node/fs/promises.js +40 -0
- package/dist/node/fs.js +10375 -0
- package/dist/node/http.js +326 -0
- package/dist/node/http2.js +305 -0
- package/dist/node/https.js +57 -0
- package/dist/node/inspector/promises.js +66 -0
- package/dist/node/inspector.js +76 -0
- package/dist/node/module.js +205 -0
- package/dist/node/net.js +392 -0
- package/dist/node/os.js +259 -0
- package/dist/node/path/posix.js +25 -0
- package/dist/node/path/win32.js +25 -0
- package/dist/node/path.js +384 -0
- package/dist/node/perf_hooks.js +313 -0
- package/dist/node/process.js +452 -0
- package/dist/node/punycode.js +178 -0
- package/dist/node/querystring.js +934 -0
- package/dist/node/readline/promises.js +71 -0
- package/dist/node/readline.js +56 -0
- package/dist/node/repl.js +44 -0
- package/dist/node/sqlite.js +22 -0
- package/dist/node/stream/consumers.js +47 -0
- package/dist/node/stream/promises.js +6 -0
- package/dist/node/stream/web.js +52 -0
- package/dist/node/stream.js +4323 -0
- package/dist/node/string_decoder.js +276 -0
- package/dist/node/sys.js +6 -0
- package/dist/node/timers/promises.js +71 -0
- package/dist/node/timers.js +133 -0
- package/dist/node/tls.js +122 -0
- package/dist/node/trace_events.js +23 -0
- package/dist/node/tty.js +69 -0
- package/dist/node/url.js +1426 -0
- package/dist/node/util/types.js +1456 -0
- package/dist/node/util.js +4807 -0
- package/dist/node/v8.js +160 -0
- package/dist/node/vm.js +88 -0
- package/dist/node/wasi.js +16 -0
- package/dist/node/worker_threads.js +123 -0
- package/dist/node/zlib.js +1396 -0
- package/dist/node-builtins.d.ts +40 -0
- package/dist/node-builtins.js +74 -0
- package/dist/node-on-page.d.ts +46 -0
- package/dist/node-on-page.js +101 -0
- package/dist/node-platform.d.ts +36 -0
- package/dist/node-platform.js +152 -0
- package/dist/node-rendered.d.ts +21 -0
- package/dist/node-rendered.js +26 -0
- package/dist/node-server.d.ts +46 -0
- package/dist/node-server.js +193 -0
- package/dist/optimizer-cache-key.d.ts +26 -0
- package/dist/optimizer-cache-key.js +73 -0
- package/dist/own-package.d.ts +1 -0
- package/dist/own-package.js +6 -0
- package/dist/page-store.d.ts +33 -0
- package/dist/page-store.js +80 -0
- package/dist/page-timers.d.ts +22 -0
- package/dist/page-timers.js +47 -0
- package/dist/page.d.ts +112 -0
- package/dist/page.js +549 -0
- package/dist/paths.d.ts +13 -0
- package/dist/paths.js +47 -0
- package/dist/plugin.d.ts +22 -0
- package/dist/plugin.js +995 -0
- package/dist/prerender-verdict.d.ts +8 -0
- package/dist/prerender-verdict.js +67 -0
- package/dist/project/context.d.ts +546 -0
- package/dist/project/context.js +111 -0
- package/dist/project/entries.d.ts +42 -0
- package/dist/project/entries.js +189 -0
- package/dist/project/env-worker.d.ts +1 -0
- package/dist/project/env-worker.js +9 -0
- package/dist/project/env.d.ts +36 -0
- package/dist/project/env.js +82 -0
- package/dist/project/layers.d.ts +31 -0
- package/dist/project/layers.js +150 -0
- package/dist/project/loaders.d.ts +71 -0
- package/dist/project/loaders.js +300 -0
- package/dist/project/metadata.d.ts +8 -0
- package/dist/project/metadata.js +34 -0
- package/dist/project/module-exports.d.ts +29 -0
- package/dist/project/module-exports.js +77 -0
- package/dist/project/routes.d.ts +19 -0
- package/dist/project/routes.js +92 -0
- package/dist/project/routing.d.ts +46 -0
- package/dist/project/routing.js +280 -0
- package/dist/project/transform.d.ts +8 -0
- package/dist/project/transform.js +110 -0
- package/dist/project/webpack.d.ts +46 -0
- package/dist/project/webpack.js +160 -0
- package/dist/project.d.ts +264 -0
- package/dist/project.js +58 -0
- package/dist/registry-global.d.ts +5 -0
- package/dist/registry-global.js +5 -0
- package/dist/registry.d.ts +241 -0
- package/dist/registry.js +30 -0
- package/dist/route-chunks.d.ts +13 -0
- package/dist/route-chunks.js +32 -0
- package/dist/route-lookup.d.ts +34 -0
- package/dist/route-lookup.js +207 -0
- package/dist/routes-ahead-shared.d.ts +17 -0
- package/dist/routes-ahead-shared.js +9 -0
- package/dist/routes-ahead.d.ts +10 -0
- package/dist/routes-ahead.js +54 -0
- package/dist/rsc.d.ts +19 -0
- package/dist/rsc.js +171 -0
- package/dist/server-action.d.ts +9 -0
- package/dist/server-action.js +15 -0
- package/dist/server-code.d.ts +176 -0
- package/dist/server-code.js +357 -0
- package/dist/server-in-front.d.ts +37 -0
- package/dist/server-in-front.js +90 -0
- package/dist/server-layers.d.ts +22 -0
- package/dist/server-layers.js +33 -0
- package/dist/setup-browser.d.ts +1 -0
- package/dist/setup-browser.js +8 -0
- package/dist/setup-node.d.ts +1 -0
- package/dist/setup-node.js +6 -0
- package/dist/setup.d.ts +8 -0
- package/dist/setup.js +62 -0
- package/dist/speed-features.d.ts +13 -0
- package/dist/speed-features.js +95 -0
- package/dist/ssr.d.ts +70 -0
- package/dist/ssr.js +480 -0
- package/dist/static-build.d.ts +36 -0
- package/dist/static-build.js +92 -0
- package/dist/storage.d.ts +31 -0
- package/dist/storage.js +94 -0
- package/dist/styles-shared.d.ts +137 -0
- package/dist/styles-shared.js +124 -0
- package/dist/styles.d.ts +102 -0
- package/dist/styles.js +730 -0
- package/dist/stylesheet-versions.d.ts +17 -0
- package/dist/stylesheet-versions.js +43 -0
- package/dist/tester.html +10 -0
- package/dist/use-cache.d.ts +15 -0
- package/dist/use-cache.js +93 -0
- package/dist/vitest-version.d.ts +6 -0
- package/dist/vitest-version.js +12 -0
- package/package.json +125 -4
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
import { actionModulePrefix, registry } from "./registry.js";
|
|
2
|
+
import { RSC_SUFFIX, normalizePagePath } from "./compat/ssr/build-output.js";
|
|
3
|
+
import { nextConfig, preview, routesManifest, routing } from "virtual:vitest-plugin-rsc/next-manifest";
|
|
4
|
+
//#region src/build-output.ts
|
|
5
|
+
const anyKey = (create) => new Proxy({}, {
|
|
6
|
+
get: (_, key) => typeof key === "string" ? create(key) : void 0,
|
|
7
|
+
has: () => true
|
|
8
|
+
});
|
|
9
|
+
const stylesheets = /* @__PURE__ */ new Map();
|
|
10
|
+
const fontFiles = /* @__PURE__ */ new Map();
|
|
11
|
+
function setStylesheets(of) {
|
|
12
|
+
for (const [file, entries] of Object.entries(of)) {
|
|
13
|
+
stylesheets.set(file, entries.map(({ path, content }) => content === void 0 ? {
|
|
14
|
+
path,
|
|
15
|
+
inlined: false
|
|
16
|
+
} : {
|
|
17
|
+
path,
|
|
18
|
+
inlined: true,
|
|
19
|
+
content
|
|
20
|
+
}));
|
|
21
|
+
const fonts = entries.flatMap((entry) => entry.fonts ?? []);
|
|
22
|
+
if (fonts.length === 0) fontFiles.delete(file);
|
|
23
|
+
else fontFiles.set(file, fonts.filter((font) => /\.p\.(?:woff|woff2|eot|ttf|otf)$/.test(font)));
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
const nextFontManifest = {
|
|
27
|
+
pages: {},
|
|
28
|
+
app: new Proxy({}, {
|
|
29
|
+
get: (_, key) => typeof key === "string" ? fontFiles.get(key) : void 0,
|
|
30
|
+
has: (_, key) => typeof key === "string" && fontFiles.has(key)
|
|
31
|
+
}),
|
|
32
|
+
appUsingSizeAdjust: false,
|
|
33
|
+
pagesUsingSizeAdjust: false
|
|
34
|
+
};
|
|
35
|
+
const clientReference = anyKey((id) => anyKey((name) => ({
|
|
36
|
+
id,
|
|
37
|
+
name,
|
|
38
|
+
chunks: [],
|
|
39
|
+
async: true
|
|
40
|
+
})));
|
|
41
|
+
const clientReferenceManifest = {
|
|
42
|
+
moduleLoading: {
|
|
43
|
+
prefix: "",
|
|
44
|
+
crossOrigin: null
|
|
45
|
+
},
|
|
46
|
+
clientModules: anyKey((id) => ({
|
|
47
|
+
id,
|
|
48
|
+
name: "*",
|
|
49
|
+
chunks: [],
|
|
50
|
+
async: true
|
|
51
|
+
})),
|
|
52
|
+
ssrModuleMapping: clientReference,
|
|
53
|
+
rscModuleMapping: clientReference,
|
|
54
|
+
entryCSSFiles: anyKey((file) => stylesheets.get(file) ?? []),
|
|
55
|
+
entryJSFiles: anyKey(() => [])
|
|
56
|
+
};
|
|
57
|
+
const buildManifest = {
|
|
58
|
+
polyfillFiles: [],
|
|
59
|
+
rootMainFiles: ["static/chunks/main-app.js"],
|
|
60
|
+
devFiles: [],
|
|
61
|
+
lowPriorityFiles: [],
|
|
62
|
+
pages: {}
|
|
63
|
+
};
|
|
64
|
+
let serverActions = {};
|
|
65
|
+
function setServerActions(ids) {
|
|
66
|
+
serverActions = Object.fromEntries(Array.from(ids, (id) => [id, {
|
|
67
|
+
workers: anyKey(() => ({
|
|
68
|
+
moduleId: actionModulePrefix + id,
|
|
69
|
+
async: true
|
|
70
|
+
})),
|
|
71
|
+
layer: {}
|
|
72
|
+
}]));
|
|
73
|
+
}
|
|
74
|
+
let prerenderManifest = {
|
|
75
|
+
version: 4,
|
|
76
|
+
routes: {},
|
|
77
|
+
dynamicRoutes: {},
|
|
78
|
+
notFoundRoutes: [],
|
|
79
|
+
preview
|
|
80
|
+
};
|
|
81
|
+
/**
|
|
82
|
+
* Lists what Next's build prerenders of a route, by its verdict: the entries
|
|
83
|
+
* of the prerender manifest that Next's handler reads. With them the handler
|
|
84
|
+
* prerenders a pathname at its first request, keeps it, and serves it from
|
|
85
|
+
* then on, as `next start` serves what the build prerendered. Without the
|
|
86
|
+
* `revalidate` the build writes: Next's cache reads it for a page the build
|
|
87
|
+
* prerendered, and here every page is first prerendered by the handler,
|
|
88
|
+
* which keeps the `revalidate` of the render with it.
|
|
89
|
+
*/
|
|
90
|
+
function recordRoute(route, verdict) {
|
|
91
|
+
if (!verdict) return;
|
|
92
|
+
const { pathname: srcRoute, kind } = route;
|
|
93
|
+
const dataRouteOf = (pathname) => kind === "page" ? `${normalizePagePath(pathname)}${RSC_SUFFIX}` : null;
|
|
94
|
+
for (const pathname of verdict.pathnames) prerenderManifest.routes[pathname] = {
|
|
95
|
+
srcRoute,
|
|
96
|
+
dataRoute: dataRouteOf(pathname)
|
|
97
|
+
};
|
|
98
|
+
if (verdict.fallback !== void 0) prerenderManifest = {
|
|
99
|
+
...prerenderManifest,
|
|
100
|
+
dynamicRoutes: {
|
|
101
|
+
...prerenderManifest.dynamicRoutes,
|
|
102
|
+
[srcRoute]: {
|
|
103
|
+
fallback: verdict.fallback,
|
|
104
|
+
dataRoute: dataRouteOf(srcRoute)
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
const built = /* @__PURE__ */ new Set();
|
|
110
|
+
/** Forgets what the build kept, as the server's cache forgets its entries. */
|
|
111
|
+
function forgetBuilt() {
|
|
112
|
+
built.clear();
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* A page as the build keeps it, which Next's handler is about to keep for
|
|
116
|
+
* `pathname`, at the first prerender of that pathname in this `generation`
|
|
117
|
+
* of the cache. The build keeps a page of a parallel route's slot without a
|
|
118
|
+
* status (`export/routes/app-page.js:126-141`), which `next start` serves
|
|
119
|
+
* with 200: a page whose other slots have no page for its path renders the
|
|
120
|
+
* not-found page there, which a page load shows, and a navigation, which
|
|
121
|
+
* keeps the other slots as they are, does not. Next's handler would keep
|
|
122
|
+
* the status of its render, 404, and Next's router takes a navigation that
|
|
123
|
+
* answers 404 for a page load. So the entry gets 200, in place: the handler
|
|
124
|
+
* answers the request of its prerender with the status of the entry it
|
|
125
|
+
* keeps, and otherwise with the one its render set. `route` is the source
|
|
126
|
+
* of the entry, the page, as Next's response cache hands it to the cache.
|
|
127
|
+
*/
|
|
128
|
+
function keptAsBuilt(pathname, value, { route }, generation) {
|
|
129
|
+
if (value?.kind !== "APP_PAGE" || !(pathname in prerenderManifest.routes)) return;
|
|
130
|
+
const key = `${generation}:${pathname}`;
|
|
131
|
+
if (built.has(key)) return;
|
|
132
|
+
built.add(key);
|
|
133
|
+
if (value.status !== void 0 && /\/@\w+/.test(route?.sourceRoute ?? "")) value.status = 200;
|
|
134
|
+
}
|
|
135
|
+
let hidden;
|
|
136
|
+
/**
|
|
137
|
+
* Hands Next's handler a manifest without `route` for `respond()`, the
|
|
138
|
+
* response of a prefetch: Next reads the manifest as it starts a request.
|
|
139
|
+
*/
|
|
140
|
+
async function withoutRoute(route, respond) {
|
|
141
|
+
const before = hidden;
|
|
142
|
+
hidden = route.pathname;
|
|
143
|
+
try {
|
|
144
|
+
return await respond();
|
|
145
|
+
} finally {
|
|
146
|
+
hidden = before;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
function currentPrerenderManifest() {
|
|
150
|
+
const route = hidden;
|
|
151
|
+
if (route === void 0 || !isPrerendered({
|
|
152
|
+
kind: "page",
|
|
153
|
+
page: "",
|
|
154
|
+
pathname: route
|
|
155
|
+
})) return prerenderManifest;
|
|
156
|
+
const { [route]: _, ...dynamicRoutes } = prerenderManifest.dynamicRoutes;
|
|
157
|
+
return {
|
|
158
|
+
...prerenderManifest,
|
|
159
|
+
routes: Object.fromEntries(Object.entries(prerenderManifest.routes).filter(([, entry]) => entry.srcRoute !== route)),
|
|
160
|
+
dynamicRoutes
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
/** Whether the build prerenders a route, or a pathname of it. */
|
|
164
|
+
function isPrerendered(route) {
|
|
165
|
+
return route.pathname in prerenderManifest.dynamicRoutes || Object.values(prerenderManifest.routes).some((entry) => entry.srcRoute === route.pathname);
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Takes a route out of what the build prerenders: for a render that read the
|
|
169
|
+
* request, which the build would have found as it prerendered the route.
|
|
170
|
+
* All of its pathnames: of a route with `generateStaticParams`, the build
|
|
171
|
+
* keeps those that did not read it, and here the others are not rendered yet.
|
|
172
|
+
*/
|
|
173
|
+
function demoteRoute(route) {
|
|
174
|
+
for (const [pathname, entry] of Object.entries(prerenderManifest.routes)) if (entry.srcRoute === route.pathname) delete prerenderManifest.routes[pathname];
|
|
175
|
+
if (route.pathname in prerenderManifest.dynamicRoutes) {
|
|
176
|
+
const { [route.pathname]: _, ...dynamicRoutes } = prerenderManifest.dynamicRoutes;
|
|
177
|
+
prerenderManifest = {
|
|
178
|
+
...prerenderManifest,
|
|
179
|
+
dynamicRoutes
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
const manifests = [
|
|
184
|
+
["routes-manifest.json", () => routesManifest],
|
|
185
|
+
["prerender-manifest.json", currentPrerenderManifest],
|
|
186
|
+
["preview-props.json", () => preview],
|
|
187
|
+
["fallback-build-manifest.json", () => ({})],
|
|
188
|
+
["build-manifest.json", () => buildManifest],
|
|
189
|
+
["next-font-manifest.json", () => nextFontManifest],
|
|
190
|
+
["_client-reference-manifest.js", () => ({ __RSC_MANIFEST: anyKey(() => clientReferenceManifest) })],
|
|
191
|
+
["server-reference-manifest.json", () => ({
|
|
192
|
+
node: serverActions,
|
|
193
|
+
edge: serverActions,
|
|
194
|
+
encryptionKey: ""
|
|
195
|
+
})],
|
|
196
|
+
["required-server-files.json", () => ({ config: nextConfig })],
|
|
197
|
+
["BUILD_ID", () => routing.buildId]
|
|
198
|
+
];
|
|
199
|
+
/** A file of `.next/`, by its path, as Next's `loadManifest()` reads it. */
|
|
200
|
+
function loadManifest(file) {
|
|
201
|
+
return manifests.find(([suffix]) => file.endsWith(suffix))?.[1]();
|
|
202
|
+
}
|
|
203
|
+
const nodeRouteDistDir = ".next/vitest-plugin-rsc-node";
|
|
204
|
+
const nothingPrerendered = {
|
|
205
|
+
...prerenderManifest,
|
|
206
|
+
routes: {},
|
|
207
|
+
dynamicRoutes: {}
|
|
208
|
+
};
|
|
209
|
+
registry.node = {
|
|
210
|
+
loadManifest,
|
|
211
|
+
evalManifest: loadManifest,
|
|
212
|
+
loadManifestFromRelativePath: ({ manifest, distDir }) => distDir === ".next/vitest-plugin-rsc-node" && manifest === "prerender-manifest.json" ? nothingPrerendered : loadManifest(manifest),
|
|
213
|
+
evalManifestFromRelativePath: ({ manifest }) => loadManifest(manifest)
|
|
214
|
+
};
|
|
215
|
+
//#endregion
|
|
216
|
+
export { demoteRoute, forgetBuilt, isPrerendered, keptAsBuilt, loadManifest, nodeRouteDistDir, prerenderManifest, recordRoute, setServerActions, setStylesheets, withoutRoute };
|
package/dist/build.d.ts
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { Rolldown } from "vite";
|
|
2
|
+
|
|
3
|
+
//#region src/build.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* The code that Next's runtime and React run: their development code, as
|
|
6
|
+
* `next dev` runs it, or their production code, as `next start` runs it after
|
|
7
|
+
* `next build`. The app's own `process.env.NODE_ENV` is the same for both:
|
|
8
|
+
* see docs/internals/next-routes.md, "Development Or Production".
|
|
9
|
+
*/
|
|
10
|
+
type NextBuild = "development" | "production";
|
|
11
|
+
declare const nextBuilds: readonly NextBuild[];
|
|
12
|
+
/**
|
|
13
|
+
* Makes `process.env.NODE_ENV` `"production"` in the files of Next: its
|
|
14
|
+
* runtime and the copies of React, React DOM, the scheduler and the Flight
|
|
15
|
+
* codec that it ships, which every layer runs on. React's entry files then
|
|
16
|
+
* pick its production build by themselves. The files of the app and of its
|
|
17
|
+
* other packages keep the `NODE_ENV` they have. For the dependency optimizer,
|
|
18
|
+
* which pre-bundles all of Next.
|
|
19
|
+
*
|
|
20
|
+
* A define, not a text replacement: Next's files also have `process.env.NODE_ENV`
|
|
21
|
+
* in strings, and assign it. Its name is in the hash of the pre-bundled
|
|
22
|
+
* dependencies, which then are not the ones of the development build.
|
|
23
|
+
*/
|
|
24
|
+
declare function nextProductionPlugin(nextDir: string): Rolldown.Plugin;
|
|
25
|
+
//#endregion
|
|
26
|
+
export { NextBuild, nextBuilds, nextProductionPlugin };
|
package/dist/build.js
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { normalizePath, transformWithOxc } from "vite";
|
|
2
|
+
//#region src/build.ts
|
|
3
|
+
const nextBuilds = ["development", "production"];
|
|
4
|
+
/**
|
|
5
|
+
* Makes `process.env.NODE_ENV` `"production"` in the files of Next: its
|
|
6
|
+
* runtime and the copies of React, React DOM, the scheduler and the Flight
|
|
7
|
+
* codec that it ships, which every layer runs on. React's entry files then
|
|
8
|
+
* pick its production build by themselves. The files of the app and of its
|
|
9
|
+
* other packages keep the `NODE_ENV` they have. For the dependency optimizer,
|
|
10
|
+
* which pre-bundles all of Next.
|
|
11
|
+
*
|
|
12
|
+
* A define, not a text replacement: Next's files also have `process.env.NODE_ENV`
|
|
13
|
+
* in strings, and assign it. Its name is in the hash of the pre-bundled
|
|
14
|
+
* dependencies, which then are not the ones of the development build.
|
|
15
|
+
*/
|
|
16
|
+
function nextProductionPlugin(nextDir) {
|
|
17
|
+
const dist = `${normalizePath(nextDir)}/dist/`.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
18
|
+
return {
|
|
19
|
+
name: "vitest-plugin-rsc:next-production",
|
|
20
|
+
transform: {
|
|
21
|
+
filter: {
|
|
22
|
+
id: new RegExp(`^${dist}.*\\.[cm]?js$`),
|
|
23
|
+
code: "process.env.NODE_ENV"
|
|
24
|
+
},
|
|
25
|
+
async handler(code, id) {
|
|
26
|
+
const { code: compiled, map } = await transformWithOxc(code, id, {
|
|
27
|
+
lang: "js",
|
|
28
|
+
define: { "process.env.NODE_ENV": "\"production\"" }
|
|
29
|
+
});
|
|
30
|
+
return {
|
|
31
|
+
code: compiled,
|
|
32
|
+
map
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
//#endregion
|
|
39
|
+
export { nextBuilds, nextProductionPlugin };
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { BuiltFiles } from "./styles-shared.js";
|
|
2
|
+
|
|
3
|
+
//#region src/built-files.d.ts
|
|
4
|
+
/** The URL of the directory of the build. Nothing with a dev server. */
|
|
5
|
+
declare const buildDirectory: string | undefined;
|
|
6
|
+
/** The files of the build. Only in a build, where `buildDirectory` is. */
|
|
7
|
+
declare function builtFiles(): Promise<BuiltFiles>;
|
|
8
|
+
//#endregion
|
|
9
|
+
export { buildDirectory, builtFiles };
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { registry } from "./registry.js";
|
|
2
|
+
import { builtFilesPath } from "./styles-shared.js";
|
|
3
|
+
import builtLayers from "virtual:vitest-plugin-rsc/layers";
|
|
4
|
+
//#region src/built-files.ts
|
|
5
|
+
/** The URL of the directory of the build. Nothing with a dev server. */
|
|
6
|
+
const buildDirectory = builtLayers && Object.values(builtLayers)[0]?.base;
|
|
7
|
+
let built;
|
|
8
|
+
/** The files of the build. Only in a build, where `buildDirectory` is. */
|
|
9
|
+
function builtFiles() {
|
|
10
|
+
if (!built) {
|
|
11
|
+
built = load(new URL(builtFilesPath, buildDirectory).href);
|
|
12
|
+
built.catch(() => built = void 0);
|
|
13
|
+
}
|
|
14
|
+
return built;
|
|
15
|
+
}
|
|
16
|
+
async function load(url) {
|
|
17
|
+
const response = await registry.network(url, { cache: "no-cache" });
|
|
18
|
+
if (!response.ok) throw new Error(`vitest-plugin-rsc: ${url} answered ${response.status}: ${await response.text()}`);
|
|
19
|
+
return await response.json();
|
|
20
|
+
}
|
|
21
|
+
//#endregion
|
|
22
|
+
export { buildDirectory, builtFiles };
|
package/dist/cache.d.ts
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { IncrementalCache } from "./compat/ssr/cache.js";
|
|
2
|
+
|
|
3
|
+
//#region src/cache.d.ts
|
|
4
|
+
declare global {
|
|
5
|
+
var __incrementalCache: IncrementalCache | undefined;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* The directory of the build on the server's disk, `.next/<generation>` in
|
|
9
|
+
* the host's directory of the server's files: `/.next/<generation>` in a
|
|
10
|
+
* browser.
|
|
11
|
+
*/
|
|
12
|
+
declare const buildDir: () => string;
|
|
13
|
+
/**
|
|
14
|
+
* Loads the cache handlers that `next.config` names, as Next's server does
|
|
15
|
+
* before its first request: `cacheHandler`, the class of the handler of this
|
|
16
|
+
* cache, and `cacheHandlers`, the handler of each kind of `"use cache"`.
|
|
17
|
+
* Without them, Next's own handlers keep the entries in memory.
|
|
18
|
+
*/
|
|
19
|
+
declare function loadCacheHandlers(): Promise<void>;
|
|
20
|
+
/**
|
|
21
|
+
* Puts the cache of the server back in the global Next reads it from. Next's
|
|
22
|
+
* route module leaves one of its own there. A request that was left can end
|
|
23
|
+
* long after its test: the cache is the one of now, not of that request.
|
|
24
|
+
*/
|
|
25
|
+
declare function restoreIncrementalCache(): void;
|
|
26
|
+
/**
|
|
27
|
+
* Gives a request the cache of the server, with the options that
|
|
28
|
+
* `getIncrementalCache()` of Next's server passes. Without headers it is the
|
|
29
|
+
* cache between requests, for a test that calls a cached function itself.
|
|
30
|
+
*/
|
|
31
|
+
declare function shareIncrementalCache(headers?: Headers): void;
|
|
32
|
+
/**
|
|
33
|
+
* Makes the server forget which tags were revalidated, and what it has
|
|
34
|
+
* cached: the entries are on the server's disk, which `cleanup()` empties
|
|
35
|
+
* after this. The generation keeps a cached function that was still running
|
|
36
|
+
* when its test ended from being found under its key. An app's own
|
|
37
|
+
* `cacheHandler` keeps the prerendered pages and route handlers where it
|
|
38
|
+
* does, under their pathnames: those are expired as `revalidatePath("/",
|
|
39
|
+
* "layout")` expires them, by the tag each of them has for the root layout.
|
|
40
|
+
* What the build prerenders stays: that is the app's code (build-output.ts).
|
|
41
|
+
*/
|
|
42
|
+
declare function resetCaches(): Promise<void>;
|
|
43
|
+
//#endregion
|
|
44
|
+
export { buildDir, loadCacheHandlers, resetCaches, restoreIncrementalCache, shareIncrementalCache };
|
package/dist/cache.js
ADDED
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { registry } from "./registry.js";
|
|
2
|
+
import { forgetBuilt, keptAsBuilt, prerenderManifest } from "./build-output.js";
|
|
3
|
+
import { IncrementalCache, NEXT_CACHE_IMPLICIT_TAG_ID, initializeCacheHandlers, nodeFs, registerCustomCacheHandlers, setCacheHandler, tagsManifest } from "./compat/ssr/cache.js";
|
|
4
|
+
import { nextConfig, preview } from "virtual:vitest-plugin-rsc/next-manifest";
|
|
5
|
+
import { cacheHandler, cacheHandlers } from "virtual:vitest-plugin-rsc/next-cache-handlers";
|
|
6
|
+
//#region src/cache.ts
|
|
7
|
+
let generation = 0;
|
|
8
|
+
/**
|
|
9
|
+
* The directory of the build on the server's disk, `.next/<generation>` in
|
|
10
|
+
* the host's directory of the server's files: `/.next/<generation>` in a
|
|
11
|
+
* browser.
|
|
12
|
+
*/
|
|
13
|
+
const buildDir = () => `${registry.serverDir()}/.next/${generation}`;
|
|
14
|
+
registry.cacheGeneration = () => generation;
|
|
15
|
+
registry.buildDir = buildDir;
|
|
16
|
+
let current;
|
|
17
|
+
let CurCacheHandler;
|
|
18
|
+
let loading;
|
|
19
|
+
const handlerOf = (module) => {
|
|
20
|
+
const handler = module.default || module;
|
|
21
|
+
return handler.default || handler;
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* Loads the cache handlers that `next.config` names, as Next's server does
|
|
25
|
+
* before its first request: `cacheHandler`, the class of the handler of this
|
|
26
|
+
* cache, and `cacheHandlers`, the handler of each kind of `"use cache"`.
|
|
27
|
+
* Without them, Next's own handlers keep the entries in memory.
|
|
28
|
+
*/
|
|
29
|
+
function loadCacheHandlers() {
|
|
30
|
+
loading ??= (async () => {
|
|
31
|
+
if (cacheHandler) CurCacheHandler = handlerOf(await cacheHandler());
|
|
32
|
+
initializeCacheHandlers(nextConfig.cacheMaxMemorySize);
|
|
33
|
+
await registerCustomCacheHandlers(async () => {
|
|
34
|
+
for (const [kind, load] of Object.entries(cacheHandlers)) setCacheHandler(kind, handlerOf(await load()));
|
|
35
|
+
});
|
|
36
|
+
})();
|
|
37
|
+
return loading;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Puts the cache of the server back in the global Next reads it from. Next's
|
|
41
|
+
* route module leaves one of its own there. A request that was left can end
|
|
42
|
+
* long after its test: the cache is the one of now, not of that request.
|
|
43
|
+
*/
|
|
44
|
+
function restoreIncrementalCache() {
|
|
45
|
+
globalThis.__incrementalCache = current;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Gives a request the cache of the server, with the options that
|
|
49
|
+
* `getIncrementalCache()` of Next's server passes. Without headers it is the
|
|
50
|
+
* cache between requests, for a test that calls a cached function itself.
|
|
51
|
+
*/
|
|
52
|
+
function shareIncrementalCache(headers = new registry.Headers()) {
|
|
53
|
+
const cache = new IncrementalCache({
|
|
54
|
+
fs: nodeFs,
|
|
55
|
+
serverDistDir: `${buildDir()}/server`,
|
|
56
|
+
dev: false,
|
|
57
|
+
minimalMode: false,
|
|
58
|
+
flushToDisk: true,
|
|
59
|
+
maxMemoryCacheSize: 0,
|
|
60
|
+
requestHeaders: Object.fromEntries(headers),
|
|
61
|
+
allowedRevalidateHeaderKeys: nextConfig.experimental.allowedRevalidateHeaderKeys,
|
|
62
|
+
fetchCacheKeyPrefix: `${nextConfig.experimental.fetchCacheKeyPrefix ?? ""}${generation}`,
|
|
63
|
+
previewProps: preview,
|
|
64
|
+
CurCacheHandler,
|
|
65
|
+
prerenderManifest
|
|
66
|
+
});
|
|
67
|
+
const set = cache.set.bind(cache);
|
|
68
|
+
cache.set = ((...args) => {
|
|
69
|
+
keptAsBuilt(args[0], args[1], args[2], generation);
|
|
70
|
+
return set(...args);
|
|
71
|
+
});
|
|
72
|
+
globalThis.__incrementalCache = current = cache;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Makes the server forget which tags were revalidated, and what it has
|
|
76
|
+
* cached: the entries are on the server's disk, which `cleanup()` empties
|
|
77
|
+
* after this. The generation keeps a cached function that was still running
|
|
78
|
+
* when its test ended from being found under its key. An app's own
|
|
79
|
+
* `cacheHandler` keeps the prerendered pages and route handlers where it
|
|
80
|
+
* does, under their pathnames: those are expired as `revalidatePath("/",
|
|
81
|
+
* "layout")` expires them, by the tag each of them has for the root layout.
|
|
82
|
+
* What the build prerenders stays: that is the app's code (build-output.ts).
|
|
83
|
+
*/
|
|
84
|
+
async function resetCaches() {
|
|
85
|
+
tagsManifest.clear();
|
|
86
|
+
forgetBuilt();
|
|
87
|
+
generation++;
|
|
88
|
+
shareIncrementalCache();
|
|
89
|
+
if (!CurCacheHandler || !hasPrerenders()) return;
|
|
90
|
+
const stored = realNow();
|
|
91
|
+
while (realNow() === stored) await new Promise((resolve) => nativeSetTimeout(resolve, 1));
|
|
92
|
+
await current.revalidateTag(`${NEXT_CACHE_IMPLICIT_TAG_ID}/layout`);
|
|
93
|
+
}
|
|
94
|
+
const realNow = Date.now.bind(Date);
|
|
95
|
+
const nativeSetTimeout = globalThis.setTimeout;
|
|
96
|
+
const hasPrerenders = () => Object.keys(prerenderManifest.routes).length > 0 || Object.keys(prerenderManifest.dynamicRoutes).length > 0;
|
|
97
|
+
shareIncrementalCache();
|
|
98
|
+
//#endregion
|
|
99
|
+
export { buildDir, loadCacheHandlers, resetCaches, restoreIncrementalCache, shareIncrementalCache };
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { Plugin, ResolvedConfig } from "vite";
|
|
2
|
+
|
|
3
|
+
//#region src/client-files.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* The file that a module of Vite is, by its id: the id, without the version
|
|
6
|
+
* a dev server adds for a dependency. Nothing for an id with another query.
|
|
7
|
+
*/
|
|
8
|
+
declare function fileOfModule(id: string): string | undefined;
|
|
9
|
+
/**
|
|
10
|
+
* The client reference of a module of the rsc layer, in Vite RSC's map of
|
|
11
|
+
* them. With a dev server, Vite RSC has a module in `node_modules` there by
|
|
12
|
+
* its file, without the version, unless the page imports it by the name of
|
|
13
|
+
* its package.
|
|
14
|
+
*/
|
|
15
|
+
declare function clientReferenceOfModule<Reference>(references: Record<string, Reference>, id: string): Reference | undefined;
|
|
16
|
+
/**
|
|
17
|
+
* What Vite RSC made of a module of the rsc layer with `"use client"`: a
|
|
18
|
+
* client reference, with the file's reference key. With a dev server that is
|
|
19
|
+
* the URL of the file in the browser layer, in a build a hash of the file.
|
|
20
|
+
*/
|
|
21
|
+
type ClientReference = {
|
|
22
|
+
referenceKey: string;
|
|
23
|
+
};
|
|
24
|
+
type ClientFilesOptions = {
|
|
25
|
+
/** The Vite environment of the rsc layer, which the host shares, and of the browser layer. */environments: {
|
|
26
|
+
rsc: string;
|
|
27
|
+
browser: string;
|
|
28
|
+
}; /** `@kasperpeulen/vitest-plugin-nextjs/testing-library`, and the file it is. */
|
|
29
|
+
testingLibrary: {
|
|
30
|
+
specifier: string;
|
|
31
|
+
file: string;
|
|
32
|
+
}; /** `@kasperpeulen/vitest-plugin-nextjs/client-components`, the other entry of a host. */
|
|
33
|
+
clientComponents: string; /** The file of the plugin that loads a client file: internal.ts. */
|
|
34
|
+
internal: string;
|
|
35
|
+
/**
|
|
36
|
+
* Whether a file is the host's: a test file or a setup file of Vitest, or a
|
|
37
|
+
* file of another host, like a story.
|
|
38
|
+
*/
|
|
39
|
+
isHostFile(file: string): boolean; /** Whether a file is a test file or a setup file of Vitest, not of another host. */
|
|
40
|
+
isTestFile(file: string): boolean; /** Whether an import is of a package of the host, by its name. */
|
|
41
|
+
isHostPackage(specifier: string): boolean;
|
|
42
|
+
/**
|
|
43
|
+
* The client reference that Vite RSC made of a module of the rsc layer, if
|
|
44
|
+
* it has `"use client"`: by the id of a module, else by its file, see
|
|
45
|
+
* `clientReferenceOfModule()`.
|
|
46
|
+
*/
|
|
47
|
+
clientReferenceOf(id: string, config: ResolvedConfig): ClientReference | undefined;
|
|
48
|
+
};
|
|
49
|
+
/**
|
|
50
|
+
* What the module of the rsc layer for a file with `"use client"` starts
|
|
51
|
+
* with, in front of the reference module, which has none of the code of the
|
|
52
|
+
* file: the export `clientFileKeyExport` with the file's reference key, by
|
|
53
|
+
* which `loadClientModule()` tells the module, see client-file-key.ts. For a
|
|
54
|
+
* file of the host, `load`, also the line that loads the file in the browser
|
|
55
|
+
* layer by that key, see client-graph.ts. With a dev server the key is the
|
|
56
|
+
* URL of the file in the browser layer. In a build it is a hash.
|
|
57
|
+
*/
|
|
58
|
+
declare function clientFileCode({
|
|
59
|
+
referenceKey
|
|
60
|
+
}: ClientReference, load?: {
|
|
61
|
+
internal: string;
|
|
62
|
+
}): string;
|
|
63
|
+
/** What `renderServer()` throws in a file with `"use client"`. */
|
|
64
|
+
declare const renderServerError: string;
|
|
65
|
+
/** What the page imports for a module of the host: see ../host-module.ts. */
|
|
66
|
+
declare function hostModuleCode(target: string, testingLibrary: ClientFilesOptions["testingLibrary"]): string;
|
|
67
|
+
/**
|
|
68
|
+
* Three plugins. One that says which modules are Vitest's files, which Vite
|
|
69
|
+
* RSC makes a reference of last. Before Vite RSC: the modules of the page
|
|
70
|
+
* for the browser layer, the error for a file with `"use client"` that mocks
|
|
71
|
+
* a module, before Vite RSC drops the code of the file, and with a dev
|
|
72
|
+
* server the change of the file's module in the rsc layer for a change of
|
|
73
|
+
* what the file imports in the browser layer. After Vite RSC, which made the file a
|
|
74
|
+
* reference: the line in front of that module, with the file's reference
|
|
75
|
+
* key, which for a file of the host loads the file in the browser layer by
|
|
76
|
+
* that key. Not a file without the directive: a test file without it renders
|
|
77
|
+
* with `renderServer()`, in a page with a graph of its own.
|
|
78
|
+
*/
|
|
79
|
+
declare function clientFiles(options: ClientFilesOptions): Plugin[];
|
|
80
|
+
/** The first call of the AST to a function of Vitest that mocks a module, like `vi.mock`. */
|
|
81
|
+
declare function findMocking(node: unknown): string | undefined;
|
|
82
|
+
//#endregion
|
|
83
|
+
export { ClientFilesOptions, ClientReference, clientFileCode, clientFiles, clientReferenceOfModule, fileOfModule, findMocking, hostModuleCode, renderServerError };
|