@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,6 @@
|
|
|
1
|
+
import { NEXT_CACHE_IMPLICIT_TAG_ID } from "next/dist/lib/constants.js";
|
|
2
|
+
import { IncrementalCache } from "next/dist/server/lib/incremental-cache/index.js";
|
|
3
|
+
import { tagsManifest } from "next/dist/server/lib/incremental-cache/tags-manifest.external";
|
|
4
|
+
import { nodeFs } from "next/dist/server/lib/node-fs-methods.js";
|
|
5
|
+
import { initializeCacheHandlers, registerCustomCacheHandlers, setCacheHandler } from "next/dist/server/use-cache/handlers.js";
|
|
6
|
+
export { IncrementalCache, NEXT_CACHE_IMPLICIT_TAG_ID, initializeCacheHandlers, nodeFs, registerCustomCacheHandlers, setCacheHandler, tagsManifest };
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { NEXT_CACHE_IMPLICIT_TAG_ID } from "next/dist/lib/constants.js";
|
|
2
|
+
import { IncrementalCache } from "next/dist/server/lib/incremental-cache/index.js";
|
|
3
|
+
import { tagsManifest } from "next/dist/server/lib/incremental-cache/tags-manifest.external";
|
|
4
|
+
import { nodeFs } from "next/dist/server/lib/node-fs-methods.js";
|
|
5
|
+
import { initializeCacheHandlers, registerCustomCacheHandlers, setCacheHandler } from "next/dist/server/use-cache/handlers.js";
|
|
6
|
+
export { IncrementalCache, NEXT_CACHE_IMPLICIT_TAG_ID, initializeCacheHandlers, nodeFs, registerCustomCacheHandlers, setCacheHandler, tagsManifest };
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { normalizeNextQueryParam } from "next/dist/server/web/utils.js";
|
|
2
|
+
import { NEXT_REWRITTEN_PATH_HEADER, NEXT_REWRITTEN_QUERY_HEADER, NEXT_ROUTER_PREFETCH_HEADER, NEXT_RSC_UNION_QUERY, RSC_HEADER } from "next/dist/client/components/app-router-headers.js";
|
|
3
|
+
import { isRSCRequestHeader } from "next/dist/server/lib/is-rsc-request.js";
|
|
4
|
+
import * as appPageModule from "next/dist/server/route-modules/app-page/module.js";
|
|
5
|
+
import { getIsPossibleServerAction } from "next/dist/server/lib/server-action-request-meta.js";
|
|
6
|
+
import { getRouteMatcher } from "next/dist/shared/lib/router/utils/route-matcher.js";
|
|
7
|
+
import { getRouteRegex } from "next/dist/shared/lib/router/utils/route-regex.js";
|
|
8
|
+
export { NEXT_REWRITTEN_PATH_HEADER, NEXT_REWRITTEN_QUERY_HEADER, NEXT_ROUTER_PREFETCH_HEADER, NEXT_RSC_UNION_QUERY, RSC_HEADER, appPageModule, getIsPossibleServerAction, getRouteMatcher, getRouteRegex, isRSCRequestHeader, normalizeNextQueryParam };
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { normalizeNextQueryParam } from "next/dist/server/web/utils.js";
|
|
2
|
+
import { NEXT_REWRITTEN_PATH_HEADER, NEXT_REWRITTEN_QUERY_HEADER, NEXT_ROUTER_PREFETCH_HEADER, NEXT_RSC_UNION_QUERY, RSC_HEADER } from "next/dist/client/components/app-router-headers.js";
|
|
3
|
+
import { isRSCRequestHeader } from "next/dist/server/lib/is-rsc-request.js";
|
|
4
|
+
import * as appPageModule from "next/dist/server/route-modules/app-page/module.js";
|
|
5
|
+
import { getIsPossibleServerAction } from "next/dist/server/lib/server-action-request-meta.js";
|
|
6
|
+
import { getRouteMatcher } from "next/dist/shared/lib/router/utils/route-matcher.js";
|
|
7
|
+
import { getRouteRegex } from "next/dist/shared/lib/router/utils/route-regex.js";
|
|
8
|
+
export { NEXT_REWRITTEN_PATH_HEADER, NEXT_REWRITTEN_QUERY_HEADER, NEXT_ROUTER_PREFETCH_HEADER, NEXT_RSC_UNION_QUERY, RSC_HEADER, appPageModule, getIsPossibleServerAction, getRouteMatcher, getRouteRegex, isRSCRequestHeader, normalizeNextQueryParam };
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { fromNodeOutgoingHttpHeaders, toNodeOutgoingHttpHeaders } from "next/dist/server/web/utils.js";
|
|
2
|
+
import { isDynamicServerError } from "next/dist/client/components/hooks-server-context.js";
|
|
3
|
+
import { MockedResponse } from "next/dist/server/lib/mock-request.js";
|
|
4
|
+
import { RequestMeta } from "next/dist/server/request-meta.js";
|
|
5
|
+
export { MockedResponse, type RequestMeta, fromNodeOutgoingHttpHeaders, isDynamicServerError, toNodeOutgoingHttpHeaders };
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { fromNodeOutgoingHttpHeaders, toNodeOutgoingHttpHeaders } from "next/dist/server/web/utils.js";
|
|
2
|
+
import { isDynamicServerError } from "next/dist/client/components/hooks-server-context.js";
|
|
3
|
+
import { MockedResponse } from "next/dist/server/lib/mock-request.js";
|
|
4
|
+
export { MockedResponse, fromNodeOutgoingHttpHeaders, isDynamicServerError, toNodeOutgoingHttpHeaders };
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { getAccessFallbackHTTPStatus, isHTTPAccessFallbackError } from "next/dist/client/components/http-access-fallback/http-access-fallback.js";
|
|
2
|
+
import { getRedirectStatusCodeFromError, getURLFromRedirectError } from "next/dist/client/components/redirect.js";
|
|
3
|
+
import { isRedirectError } from "next/dist/client/components/redirect-error.js";
|
|
4
|
+
export { getAccessFallbackHTTPStatus, getRedirectStatusCodeFromError, getURLFromRedirectError, isHTTPAccessFallbackError, isRedirectError };
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { getAccessFallbackHTTPStatus, isHTTPAccessFallbackError } from "next/dist/client/components/http-access-fallback/http-access-fallback.js";
|
|
2
|
+
import { getRedirectStatusCodeFromError, getURLFromRedirectError } from "next/dist/client/components/redirect.js";
|
|
3
|
+
import { isRedirectError } from "next/dist/client/components/redirect-error.js";
|
|
4
|
+
export { getAccessFallbackHTTPStatus, getRedirectStatusCodeFromError, getURLFromRedirectError, isHTTPAccessFallbackError, isRedirectError };
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { NodeNextResponse } from "next/dist/server/base-http/node.js";
|
|
2
|
+
import { generateETag } from "next/dist/server/lib/etag.js";
|
|
3
|
+
import RenderResult from "next/dist/server/render-result.js";
|
|
4
|
+
import { sendRenderResult } from "next/dist/server/send-payload.js";
|
|
5
|
+
import { sendResponse } from "next/dist/server/send-response.js";
|
|
6
|
+
export { NodeNextResponse, RenderResult, generateETag, sendRenderResult, sendResponse };
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { NodeNextResponse } from "next/dist/server/base-http/node.js";
|
|
2
|
+
import { generateETag } from "next/dist/server/lib/etag.js";
|
|
3
|
+
import RenderResult from "next/dist/server/render-result.js";
|
|
4
|
+
import { sendRenderResult } from "next/dist/server/send-payload.js";
|
|
5
|
+
import { sendResponse } from "next/dist/server/send-response.js";
|
|
6
|
+
export { NodeNextResponse, RenderResult, generateETag, sendRenderResult, sendResponse };
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { RoutesManifest } from "next/dist/build/index.js";
|
|
2
|
+
import { AdapterOutputs } from "next/dist/build/adapter/build-complete.js";
|
|
3
|
+
import { ProxyMatcher } from "next/dist/build/analysis/get-page-static-info.js";
|
|
4
|
+
import { AppLoaderOptions } from "next/dist/build/webpack/loaders/next-app-loader/index.js";
|
|
5
|
+
import { EdgeFunctionDefinition, MiddlewareManifest } from "next/dist/build/webpack/plugins/middleware-plugin.js";
|
|
6
|
+
import { Header } from "next/dist/lib/load-custom-routes.js";
|
|
7
|
+
import { NextConfigComplete } from "next/dist/server/config-shared.js";
|
|
8
|
+
export { type AdapterOutputs, type AppLoaderOptions, type EdgeFunctionDefinition, type Header, type MiddlewareManifest, type NextConfigComplete, type ProxyMatcher, type RoutesManifest };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { NextLayer, NextProject } from "./project.js";
|
|
2
|
+
import { Plugin } from "vite";
|
|
3
|
+
|
|
4
|
+
//#region src/compile.d.ts
|
|
5
|
+
/**
|
|
6
|
+
* The call of a `next/font` function whose CSS a module is, by the module's
|
|
7
|
+
* id: the import the SWC transform turns the call into. Nothing for any other
|
|
8
|
+
* module.
|
|
9
|
+
*/
|
|
10
|
+
declare function fontRequestOf(id: string): string | undefined;
|
|
11
|
+
declare function createDependencyCompilePlugin(getProject: () => NextProject, layer: NextLayer, isAppCode: (file: string, layer: NextLayer) => boolean): {
|
|
12
|
+
name: string;
|
|
13
|
+
resolveId(source: string): {
|
|
14
|
+
id: string;
|
|
15
|
+
external: boolean;
|
|
16
|
+
} | undefined;
|
|
17
|
+
transform(code: string, id: string): Promise<{
|
|
18
|
+
code: string;
|
|
19
|
+
map: string | null;
|
|
20
|
+
} | undefined>;
|
|
21
|
+
};
|
|
22
|
+
declare function createScanCompilePlugin(getProject: () => NextProject, layer: NextLayer, isAppCode: (file: string, layer: NextLayer) => boolean): {
|
|
23
|
+
name: string;
|
|
24
|
+
transform(code: string, id: string): Promise<{
|
|
25
|
+
code: string;
|
|
26
|
+
map: string | null;
|
|
27
|
+
} | undefined>;
|
|
28
|
+
};
|
|
29
|
+
declare function createCompilePlugin(getProject: () => NextProject, layerOf: (environment: string) => NextLayer | undefined, isAppCode: (file: string, layer: NextLayer) => boolean): Plugin;
|
|
30
|
+
//#endregion
|
|
31
|
+
export { createCompilePlugin, createDependencyCompilePlugin, createScanCompilePlugin, fontRequestOf };
|
package/dist/compile.js
ADDED
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import { linked } from "./styles.js";
|
|
2
|
+
import { normalizePath } from "vite";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import fs from "node:fs";
|
|
5
|
+
import { withBuiltFiles } from "@kasperpeulen/vitest-plugin-rsc/internal/static-build";
|
|
6
|
+
//#region src/compile.ts
|
|
7
|
+
const fontPrefix = "\0vitest-plugin-rsc/next-font/";
|
|
8
|
+
const fontRequest = /^next\/font\/(?:google|local)\/target\.css\?/;
|
|
9
|
+
/**
|
|
10
|
+
* The call of a `next/font` function whose CSS a module is, by the module's
|
|
11
|
+
* id: the import the SWC transform turns the call into. Nothing for any other
|
|
12
|
+
* module.
|
|
13
|
+
*/
|
|
14
|
+
function fontRequestOf(id) {
|
|
15
|
+
if (!id.startsWith(fontPrefix)) return void 0;
|
|
16
|
+
const name = id.slice(29).split("?")[0];
|
|
17
|
+
if (!name.endsWith(".css")) return void 0;
|
|
18
|
+
return Buffer.from(name.slice(0, -4), "base64url").toString();
|
|
19
|
+
}
|
|
20
|
+
const sourceFile = /\.(?:tsx|ts|jsx|js|mjs)$/;
|
|
21
|
+
function createDependencyCompilePlugin(getProject, layer, isAppCode) {
|
|
22
|
+
return {
|
|
23
|
+
name: "vitest-plugin-rsc:next-compile-dependency",
|
|
24
|
+
resolveId(source) {
|
|
25
|
+
if (fontRequest.test(source)) return {
|
|
26
|
+
id: source,
|
|
27
|
+
external: true
|
|
28
|
+
};
|
|
29
|
+
},
|
|
30
|
+
async transform(code, id) {
|
|
31
|
+
if (!/\.[cm]?js$/.test(id) || !/\bnext\/font\b/.test(code) || isAppCode(id, layer)) return;
|
|
32
|
+
if (!path.relative(getProject().nextDir, id).startsWith("..")) return;
|
|
33
|
+
const compiled = await getProject().compile(code, id, layer);
|
|
34
|
+
return compiled && {
|
|
35
|
+
code: compiled.code,
|
|
36
|
+
map: compiled.map ?? null
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
function createScanCompilePlugin(getProject, layer, isAppCode) {
|
|
42
|
+
return {
|
|
43
|
+
name: `vitest-plugin-rsc:next-compile-scan:${layer}`,
|
|
44
|
+
async transform(code, id) {
|
|
45
|
+
if (id.includes("?") || !sourceFile.test(id) || !isAppCode(id, layer)) return;
|
|
46
|
+
const compiled = await getProject().compile(code, id, layer).catch(() => void 0);
|
|
47
|
+
if (!compiled || compiled.refused) return;
|
|
48
|
+
return {
|
|
49
|
+
code: compiled.code,
|
|
50
|
+
map: compiled.map ?? null
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
function createCompilePlugin(getProject, layerOf, isAppCode) {
|
|
56
|
+
return {
|
|
57
|
+
name: "vitest-plugin-rsc:next-compile",
|
|
58
|
+
enforce: "pre",
|
|
59
|
+
configureServer(server) {
|
|
60
|
+
const serveFile = async (request, response) => {
|
|
61
|
+
server.middlewares.handle(request, response, (error) => {
|
|
62
|
+
response.statusCode = error ? 500 : 404;
|
|
63
|
+
response.end();
|
|
64
|
+
});
|
|
65
|
+
};
|
|
66
|
+
const serve = async (request, response) => {
|
|
67
|
+
const project = getProject();
|
|
68
|
+
if (await project.optimizeImage(request, response, serveFile)) return true;
|
|
69
|
+
const file = project.readEmittedFile(new URL(request.url, "http://n").pathname);
|
|
70
|
+
if (!file) return false;
|
|
71
|
+
response.setHeader("content-type", file.contentType);
|
|
72
|
+
response.end(file.body);
|
|
73
|
+
return true;
|
|
74
|
+
};
|
|
75
|
+
server.middlewares.use(async (request, response, next) => {
|
|
76
|
+
let served;
|
|
77
|
+
try {
|
|
78
|
+
served = await serve(request, response);
|
|
79
|
+
} catch (error) {
|
|
80
|
+
server.config.logger.error(`vitest-plugin-rsc: ${request.url} failed. ${String(error)}`);
|
|
81
|
+
response.statusCode = 500;
|
|
82
|
+
response.end("Internal Server Error");
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
if (!served) next();
|
|
86
|
+
});
|
|
87
|
+
},
|
|
88
|
+
async resolveId(source, importer, options) {
|
|
89
|
+
if (source.startsWith(fontPrefix)) return source;
|
|
90
|
+
if (fontRequest.test(source)) return `${fontPrefix}${Buffer.from(source).toString("base64url")}.js`;
|
|
91
|
+
const layer = layerOf(this.environment.name);
|
|
92
|
+
const candidates = layer && getProject().webpackAliasOf(source, layer);
|
|
93
|
+
for (const candidate of candidates ?? []) {
|
|
94
|
+
const resolved = await this.resolve(candidate, importer, {
|
|
95
|
+
...options,
|
|
96
|
+
skipSelf: true
|
|
97
|
+
});
|
|
98
|
+
if (resolved) return resolved;
|
|
99
|
+
}
|
|
100
|
+
},
|
|
101
|
+
async load(id) {
|
|
102
|
+
const built = (code, language) => {
|
|
103
|
+
if (this.environment.mode !== "build") return code;
|
|
104
|
+
const pathnames = getProject().emittedFiles().map((file) => file.pathname);
|
|
105
|
+
return withBuiltFiles(code, pathnames, language);
|
|
106
|
+
};
|
|
107
|
+
if (id.startsWith(fontPrefix)) {
|
|
108
|
+
const name = id.slice(29).split("?")[0];
|
|
109
|
+
const key = name.replace(/\.(?:js|css)$/, "");
|
|
110
|
+
const request = Buffer.from(key, "base64url").toString();
|
|
111
|
+
const { css, exports } = await getProject().loadFont(request);
|
|
112
|
+
if (name.endsWith(".css")) return built(css, "css");
|
|
113
|
+
const stylesheet = linked(`${fontPrefix}${key}.css`, this.environment.mode === "build");
|
|
114
|
+
return `import ${JSON.stringify(stylesheet)};\nexport default ${JSON.stringify(exports)};\n`;
|
|
115
|
+
}
|
|
116
|
+
const layer = layerOf(this.environment.name);
|
|
117
|
+
if (!layer || id.includes("?")) return;
|
|
118
|
+
if (getProject().webpackRuleOf(id, layer) && fs.existsSync(id)) return {
|
|
119
|
+
code: await getProject().loadWithWebpackRule(id, layer),
|
|
120
|
+
moduleType: "js"
|
|
121
|
+
};
|
|
122
|
+
if (!getProject().isImage(id) || !fs.existsSync(id)) return;
|
|
123
|
+
return built(await getProject().loadImage(id), "js");
|
|
124
|
+
},
|
|
125
|
+
async transform(code, id) {
|
|
126
|
+
const layer = layerOf(this.environment.name);
|
|
127
|
+
if (!layer || id.includes("?")) return;
|
|
128
|
+
if (!sourceFile.test(id) && !getProject().webpackRuleOf(id, layer)?.compile) return;
|
|
129
|
+
if (!isAppCode(id, layer) || !fs.existsSync(id)) return;
|
|
130
|
+
if (id.startsWith(`${normalizePath(this.environment.config.cacheDir)}/`)) return;
|
|
131
|
+
const compiled = await getProject().compile(code, id, layer);
|
|
132
|
+
return compiled && {
|
|
133
|
+
code: compiled.code,
|
|
134
|
+
map: compiled.map ?? null
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
//#endregion
|
|
140
|
+
export { createCompilePlugin, createDependencyCompilePlugin, createScanCompilePlugin, fontRequestOf };
|
package/dist/disk.d.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
//#region src/disk.d.ts
|
|
2
|
+
/** The global the disk is on. */
|
|
3
|
+
declare const diskGlobal = "__vitest_plugin_rsc_disk__";
|
|
4
|
+
/** The disk: the `fs` of memfs, and what empties it. */
|
|
5
|
+
type Disk = {
|
|
6
|
+
fs: Record<string, any>;
|
|
7
|
+
reset(): void;
|
|
8
|
+
};
|
|
9
|
+
/**
|
|
10
|
+
* Empties the disk, as it is before any test: nothing but `/tmp`, which
|
|
11
|
+
* `os.tmpdir()` names. Closes what watches a file of it, which would see the
|
|
12
|
+
* next test's files otherwise. Nothing to do while no module imports `fs`.
|
|
13
|
+
*/
|
|
14
|
+
declare function resetDisk(): void;
|
|
15
|
+
//#endregion
|
|
16
|
+
export { Disk, diskGlobal, resetDisk };
|
package/dist/disk.js
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
//#region src/disk.ts
|
|
2
|
+
/** The global the disk is on. */
|
|
3
|
+
const diskGlobal = "__vitest_plugin_rsc_disk__";
|
|
4
|
+
/**
|
|
5
|
+
* Empties the disk, as it is before any test: nothing but `/tmp`, which
|
|
6
|
+
* `os.tmpdir()` names. Closes what watches a file of it, which would see the
|
|
7
|
+
* next test's files otherwise. Nothing to do while no module imports `fs`.
|
|
8
|
+
*/
|
|
9
|
+
function resetDisk() {
|
|
10
|
+
globalThis[diskGlobal]?.reset();
|
|
11
|
+
}
|
|
12
|
+
//#endregion
|
|
13
|
+
export { diskGlobal, resetDisk };
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { PageStore } from "./page-store.js";
|
|
2
|
+
|
|
3
|
+
//#region src/document-loads.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* What a navigation does in a browser context of the app, whose store is
|
|
6
|
+
* `from`. The app can leave its page without its router:
|
|
7
|
+
* `location.assign()`, a `<form>` or an `<a>` that React does not handle,
|
|
8
|
+
* Next's own fallback when a client-side navigation is not possible. For a
|
|
9
|
+
* browser that is a page load. Here it would replace the test with the app,
|
|
10
|
+
* so `navigate()` loads the page the way `renderServer()` does instead, or
|
|
11
|
+
* downloads what a browser would.
|
|
12
|
+
*/
|
|
13
|
+
declare function followNavigation(event: Event, from: PageStore): void;
|
|
14
|
+
//#endregion
|
|
15
|
+
export { followNavigation };
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { openedAt } from "./registry.js";
|
|
2
|
+
import { leftTheApp } from "./app-requests.js";
|
|
3
|
+
import { documentUrl } from "./document.js";
|
|
4
|
+
import { enctypeOf, formBody } from "./form-submission.js";
|
|
5
|
+
import { fromPage } from "./from-page.js";
|
|
6
|
+
import { currentPage, leavePage, navigate, noRouter } from "./page.js";
|
|
7
|
+
//#region src/document-loads.ts
|
|
8
|
+
import.meta.hot?.on("vite:beforeFullReload", ({ path }) => {
|
|
9
|
+
if (reloadsDocument(path)) return leavePage("a reload of the page");
|
|
10
|
+
});
|
|
11
|
+
import.meta.hot?.on("vite:ws:disconnect", () => leavePage("a lost connection to the dev server"));
|
|
12
|
+
function reloadsDocument(path) {
|
|
13
|
+
if (!path?.endsWith(".html") || path === "/index.html") return true;
|
|
14
|
+
const pagePath = decodeURI(new URL(documentUrl()).pathname);
|
|
15
|
+
const payloadPath = (import.meta.env?.BASE_URL ?? "/") + path.slice(1);
|
|
16
|
+
return pagePath === payloadPath || pagePath.endsWith("/") && `${pagePath}index.html` === payloadPath;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* What a navigation does in a browser context of the app, whose store is
|
|
20
|
+
* `from`. The app can leave its page without its router:
|
|
21
|
+
* `location.assign()`, a `<form>` or an `<a>` that React does not handle,
|
|
22
|
+
* Next's own fallback when a client-side navigation is not possible. For a
|
|
23
|
+
* browser that is a page load. Here it would replace the test with the app,
|
|
24
|
+
* so `navigate()` loads the page the way `renderServer()` does instead, or
|
|
25
|
+
* downloads what a browser would.
|
|
26
|
+
*/
|
|
27
|
+
function followNavigation(event, from) {
|
|
28
|
+
const { destination, hashChange, formData, downloadRequest, navigationType, sourceElement } = event;
|
|
29
|
+
if (destination.sameDocument) currentPage()?.nodeOnPage?.at(new URL(destination.url).pathname);
|
|
30
|
+
if (destination.sameDocument || hashChange || !event.cancelable) return;
|
|
31
|
+
const url = new URL(destination.url);
|
|
32
|
+
if (downloadRequest !== null && (url.protocol === "blob:" || url.protocol === "data:")) return;
|
|
33
|
+
if (destination.url === documentUrl()) return;
|
|
34
|
+
if (url.origin === window.location.origin && openedAt(url)?.node) {
|
|
35
|
+
event.preventDefault();
|
|
36
|
+
leavePage("a navigation to the host's document").catch(() => {}).then(() => window.location.reload());
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
event.preventDefault();
|
|
40
|
+
if (url.origin !== window.location.origin) {
|
|
41
|
+
reportError(currentPage() ? leftTheApp(url) : noRouter(url));
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
navigate(url, fromPage(url, {
|
|
45
|
+
method: formData ? "POST" : "GET",
|
|
46
|
+
headers: { accept: "text/html" },
|
|
47
|
+
body: formData && formBody(formData, enctypeOf(sourceElement))
|
|
48
|
+
})[1], downloadRequest, from, navigationType === "push").catch((error) => {
|
|
49
|
+
if (!(error instanceof DOMException && error.name === "AbortError")) reportError(error);
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
//#endregion
|
|
53
|
+
export { followNavigation };
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
//#region src/document.d.ts
|
|
2
|
+
/** An entry of the history: its URL and its state. */
|
|
3
|
+
type HistoryEntry = {
|
|
4
|
+
url: string;
|
|
5
|
+
state: unknown;
|
|
6
|
+
};
|
|
7
|
+
/**
|
|
8
|
+
* Keeps the properties `keys` of `target`, the document or one of its
|
|
9
|
+
* elements, as the pages are left, until it is called again: the marks of
|
|
10
|
+
* React DOM on the root of an app that renders the pages after its first
|
|
11
|
+
* (`renderAgain()` in client.tsx). Without `keys` they are no longer kept,
|
|
12
|
+
* and the app that kept them removes them.
|
|
13
|
+
*/
|
|
14
|
+
declare function keepProperties(target: object, keys?: Iterable<PropertyKey>): void;
|
|
15
|
+
/**
|
|
16
|
+
* The URL of the document without the page that is open: the runner's, which
|
|
17
|
+
* the page shows as its own while it is open.
|
|
18
|
+
*/
|
|
19
|
+
declare function documentUrl(): string;
|
|
20
|
+
/**
|
|
21
|
+
* Starts the files of the route of the page that loads next, as the server
|
|
22
|
+
* renders it: `stylesheets` as Next links them, in the CORS mode of
|
|
23
|
+
* `crossOrigin`, and `modules`. By their URLs. They go with that page.
|
|
24
|
+
*/
|
|
25
|
+
declare function preloadPage({
|
|
26
|
+
stylesheets,
|
|
27
|
+
crossOrigin,
|
|
28
|
+
modules
|
|
29
|
+
}: {
|
|
30
|
+
stylesheets: string[];
|
|
31
|
+
crossOrigin: string | undefined;
|
|
32
|
+
modules: string[];
|
|
33
|
+
}): void;
|
|
34
|
+
/**
|
|
35
|
+
* Replaces the page in this document with the one the server sent as `html`:
|
|
36
|
+
* its `<head>` first, the rest once the stylesheets of the `<head>` have
|
|
37
|
+
* loaded, and runs its inline scripts in document order once the stylesheets
|
|
38
|
+
* of the rest have too. Resolves then, and without running them for a page
|
|
39
|
+
* that was left in the meantime.
|
|
40
|
+
*
|
|
41
|
+
* The page is there in full before the app starts, so the document has loaded
|
|
42
|
+
* by the time Next's client looks: it reads the Flight payload that Next's
|
|
43
|
+
* inline scripts left in `self.__next_f`, and hydrates.
|
|
44
|
+
*
|
|
45
|
+
* With a `container`, the page is the one of a node, which renders no
|
|
46
|
+
* `<html>` or `<body>`, and what is in the document stays the test's. What
|
|
47
|
+
* the HTML parser puts in `<body>` goes in the container: the node, with the
|
|
48
|
+
* scripts it renders, and after it the scripts of Next and React.
|
|
49
|
+
*
|
|
50
|
+
* The page takes the entry of the history that the document is at, or with
|
|
51
|
+
* `after` gets one of its own, after that entry. With `inKeptApp`, leaving
|
|
52
|
+
* the page leaves what the app added to the `<head>`: see `unloadKeptApp()`.
|
|
53
|
+
* React's inline scripts get timers of the page's own, which leaving the
|
|
54
|
+
* page clears.
|
|
55
|
+
*
|
|
56
|
+
* Returns what takes React DOM's properties off the nodes of this page,
|
|
57
|
+
* before its root unmounts: React takes the nodes out of the document as it
|
|
58
|
+
* does, and leaves its fiber on a text node. A node that outlives the page
|
|
59
|
+
* then keeps no fiber of it: the one that an assertion of the test holds
|
|
60
|
+
* until it ends, or the one under the pointer. Once the page is left, it
|
|
61
|
+
* does nothing: leaving took them off already. Nothing for a page of a kept
|
|
62
|
+
* app, whose root outlives the page.
|
|
63
|
+
*/
|
|
64
|
+
declare function loadDocument(html: string, url: string, container?: Element, after?: HistoryEntry, inKeptApp?: boolean): Promise<() => void>;
|
|
65
|
+
/** `self.$RC` of a page. */
|
|
66
|
+
declare const streamedContentQueue: PropertyDescriptor;
|
|
67
|
+
/**
|
|
68
|
+
* Takes back what the code of the kept app added to the `<head>` as its pages
|
|
69
|
+
* were open, once the app is left: see `loadDocument()`. With `withGlobals`,
|
|
70
|
+
* also the globals of Next and React on `window` that point into it.
|
|
71
|
+
*/
|
|
72
|
+
declare function unloadKeptApp(withGlobals?: boolean): void;
|
|
73
|
+
/**
|
|
74
|
+
* Leaves the page, and the one that was loading: the document is as it was
|
|
75
|
+
* before the page, but for what a kept app keeps (`unloadKeptApp()`).
|
|
76
|
+
*/
|
|
77
|
+
declare function unloadDocument(): void;
|
|
78
|
+
//#endregion
|
|
79
|
+
export { HistoryEntry, documentUrl, keepProperties, loadDocument, preloadPage, streamedContentQueue, unloadDocument, unloadKeptApp };
|