rwsdk 1.0.0-alpha.2 → 1.0.0-alpha.20-test.20250929144616
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lib/constants.mjs +1 -2
- package/dist/lib/e2e/browser.d.mts +10 -0
- package/dist/lib/e2e/browser.mjs +123 -0
- package/dist/lib/e2e/dev.d.mts +8 -0
- package/dist/lib/e2e/dev.mjs +242 -0
- package/dist/lib/e2e/environment.d.mts +10 -0
- package/dist/lib/e2e/environment.mjs +210 -0
- package/dist/lib/e2e/index.d.mts +8 -0
- package/dist/lib/e2e/index.mjs +8 -0
- package/dist/lib/e2e/poll.d.mts +8 -0
- package/dist/lib/e2e/poll.mjs +31 -0
- package/dist/lib/e2e/release.d.mts +56 -0
- package/dist/lib/e2e/release.mjs +559 -0
- package/dist/lib/e2e/retry.d.mts +4 -0
- package/dist/lib/e2e/retry.mjs +16 -0
- package/dist/lib/e2e/setup.d.mts +2 -0
- package/dist/lib/e2e/setup.mjs +1 -0
- package/dist/lib/e2e/tarball.d.mts +14 -0
- package/dist/lib/e2e/tarball.mjs +99 -0
- package/dist/lib/e2e/testHarness.d.mts +132 -0
- package/dist/lib/e2e/testHarness.mjs +436 -0
- package/dist/lib/e2e/types.d.mts +32 -0
- package/dist/lib/getShortName.mjs +6 -2
- package/dist/lib/getShortName.test.d.mts +1 -0
- package/dist/lib/getShortName.test.mjs +25 -0
- package/dist/lib/getSrcPaths.js +2 -2
- package/dist/lib/hasPkgScript.d.mts +4 -1
- package/dist/lib/hasPkgScript.mjs +9 -6
- package/dist/lib/hasPkgScript.test.d.mts +1 -0
- package/dist/lib/hasPkgScript.test.mjs +33 -0
- package/dist/lib/jsonUtils.mjs +3 -0
- package/dist/lib/jsonUtils.test.d.mts +1 -0
- package/dist/lib/jsonUtils.test.mjs +90 -0
- package/dist/lib/normalizeModulePath.d.mts +5 -0
- package/dist/lib/normalizeModulePath.mjs +1 -1
- package/dist/lib/normalizeModulePath.test.d.mts +1 -0
- package/dist/lib/{normalizeModulePath.test.js → normalizeModulePath.test.mjs} +21 -2
- package/dist/lib/setupEnvFiles.mjs +2 -2
- package/dist/lib/smokeTests/artifacts.mjs +2 -2
- package/dist/lib/smokeTests/browser.d.mts +1 -1
- package/dist/lib/smokeTests/browser.mjs +8 -100
- package/dist/lib/smokeTests/cleanup.mjs +6 -9
- package/dist/lib/smokeTests/codeUpdates.mjs +5 -5
- package/dist/lib/smokeTests/development.mjs +3 -224
- package/dist/lib/smokeTests/environment.d.mts +3 -11
- package/dist/lib/smokeTests/environment.mjs +17 -151
- package/dist/lib/smokeTests/release.d.mts +2 -49
- package/dist/lib/smokeTests/release.mjs +4 -504
- package/dist/lib/smokeTests/reporting.mjs +2 -2
- package/dist/lib/smokeTests/runSmokeTests.mjs +4 -4
- package/dist/lib/smokeTests/utils.mjs +3 -3
- package/dist/lib/testUtils/stubEnvVars.mjs +1 -1
- package/dist/llms/rules/middleware.d.ts +1 -1
- package/dist/llms/rules/middleware.js +4 -4
- package/dist/runtime/client/client.d.ts +2 -2
- package/dist/runtime/client/client.js +2 -2
- package/dist/runtime/client/navigation.test.js +1 -1
- package/dist/runtime/client/types.d.ts +1 -1
- package/dist/runtime/entries/client.d.ts +2 -2
- package/dist/runtime/entries/client.js +2 -2
- package/dist/runtime/entries/router.d.ts +1 -1
- package/dist/runtime/entries/router.js +1 -1
- package/dist/runtime/entries/worker.d.ts +5 -6
- package/dist/runtime/entries/worker.js +5 -6
- package/dist/runtime/imports/worker.js +1 -1
- package/dist/runtime/lib/auth/session.d.ts +2 -2
- package/dist/runtime/lib/auth/session.js +5 -5
- package/dist/runtime/lib/db/DOWorkerDialect.d.ts +1 -1
- package/dist/runtime/lib/db/DOWorkerDialect.js +1 -1
- package/dist/runtime/lib/db/SqliteDurableObject.js +2 -2
- package/dist/runtime/lib/db/index.d.ts +2 -2
- package/dist/runtime/lib/db/index.js +2 -2
- package/dist/runtime/lib/db/migrations.d.ts +1 -1
- package/dist/runtime/lib/db/typeInference/builders/alterTable.d.ts +3 -3
- package/dist/runtime/lib/db/typeInference/builders/columnDefinition.d.ts +1 -1
- package/dist/runtime/lib/db/typeInference/builders/createTable.d.ts +2 -2
- package/dist/runtime/lib/db/typeInference/builders/createView.d.ts +1 -1
- package/dist/runtime/lib/db/typeInference/builders/dropTable.d.ts +1 -1
- package/dist/runtime/lib/db/typeInference/builders/dropView.d.ts +1 -1
- package/dist/runtime/lib/db/typeInference/builders/schema.d.ts +3 -3
- package/dist/runtime/lib/db/typeInference/database.d.ts +2 -2
- package/dist/runtime/lib/memoizeOnId.test.d.ts +1 -0
- package/dist/runtime/lib/memoizeOnId.test.js +49 -0
- package/dist/runtime/lib/realtime/client.js +2 -2
- package/dist/runtime/lib/realtime/durableObject.js +1 -1
- package/dist/runtime/lib/realtime/protocol.test.d.ts +1 -0
- package/dist/runtime/lib/realtime/protocol.test.js +107 -0
- package/dist/runtime/lib/realtime/shared.test.d.ts +1 -0
- package/dist/runtime/lib/realtime/shared.test.js +18 -0
- package/dist/runtime/lib/realtime/validateUpgradeRequest.test.d.ts +1 -0
- package/dist/runtime/lib/realtime/validateUpgradeRequest.test.js +66 -0
- package/dist/runtime/lib/realtime/worker.d.ts +1 -1
- package/dist/runtime/lib/realtime/worker.js +2 -2
- package/dist/runtime/lib/router.d.ts +1 -1
- package/dist/runtime/lib/router.js +40 -22
- package/dist/runtime/lib/router.test.js +591 -3
- package/dist/runtime/lib/rwContext.d.ts +22 -0
- package/dist/runtime/lib/rwContext.js +1 -0
- package/dist/runtime/lib/stitchDocumentAndAppStreams.d.ts +18 -0
- package/dist/runtime/lib/stitchDocumentAndAppStreams.js +143 -0
- package/dist/runtime/lib/turnstile/useTurnstile.js +1 -1
- package/dist/runtime/lib/turnstile/verifyTurnstileToken.d.ts +2 -1
- package/dist/runtime/lib/turnstile/verifyTurnstileToken.js +6 -6
- package/dist/runtime/lib/turnstile/verifyTurnstileToken.test.d.ts +1 -0
- package/dist/runtime/lib/turnstile/verifyTurnstileToken.test.js +49 -0
- package/dist/runtime/register/worker.d.ts +1 -1
- package/dist/runtime/register/worker.js +34 -22
- package/dist/runtime/render/assembleDocument.d.ts +6 -0
- package/dist/runtime/render/assembleDocument.js +22 -0
- package/dist/runtime/render/createThenableFromReadableStream.d.ts +1 -0
- package/dist/runtime/render/createThenableFromReadableStream.js +9 -0
- package/dist/runtime/render/normalizeActionResult.d.ts +1 -0
- package/dist/runtime/render/normalizeActionResult.js +43 -0
- package/dist/runtime/render/preloads.d.ts +3 -3
- package/dist/runtime/render/preloads.js +2 -3
- package/dist/runtime/render/{renderRscThenableToHtmlStream.d.ts → renderDocumentHtmlStream.d.ts} +3 -3
- package/dist/runtime/render/renderDocumentHtmlStream.js +39 -0
- package/dist/runtime/render/renderHtmlStream.d.ts +7 -0
- package/dist/runtime/render/renderHtmlStream.js +31 -0
- package/dist/runtime/render/renderToRscStream.d.ts +5 -3
- package/dist/runtime/render/renderToRscStream.js +12 -41
- package/dist/runtime/render/renderToStream.d.ts +3 -2
- package/dist/runtime/render/renderToStream.js +17 -10
- package/dist/runtime/render/stylesheets.d.ts +2 -2
- package/dist/runtime/render/stylesheets.js +2 -3
- package/dist/runtime/requestInfo/types.d.ts +0 -2
- package/dist/runtime/requestInfo/worker.d.ts +1 -1
- package/dist/runtime/requestInfo/worker.js +1 -9
- package/dist/runtime/script.js +1 -1
- package/dist/runtime/ssrBridge.d.ts +3 -2
- package/dist/runtime/ssrBridge.js +3 -2
- package/dist/runtime/worker.d.ts +2 -1
- package/dist/runtime/worker.js +13 -16
- package/dist/scripts/addon.d.mts +1 -0
- package/dist/scripts/addon.mjs +75 -0
- package/dist/scripts/debug-sync.mjs +106 -137
- package/dist/scripts/ensure-deploy-env.mjs +6 -6
- package/dist/scripts/migrate-new.mjs +3 -4
- package/dist/scripts/smoke-test.mjs +2 -2
- package/dist/scripts/worker-run.mjs +7 -9
- package/dist/vite/buildApp.d.mts +2 -1
- package/dist/vite/buildApp.mjs +10 -6
- package/dist/vite/checkIsUsingPrisma.d.mts +4 -0
- package/dist/vite/checkIsUsingPrisma.mjs +2 -2
- package/dist/vite/checkIsUsingPrisma.test.d.mts +1 -0
- package/dist/vite/checkIsUsingPrisma.test.mjs +30 -0
- package/dist/vite/configPlugin.mjs +55 -15
- package/dist/vite/createDirectiveLookupPlugin.d.mts +9 -0
- package/dist/vite/createDirectiveLookupPlugin.mjs +34 -30
- package/dist/vite/createDirectiveLookupPlugin.test.d.mts +1 -0
- package/dist/vite/createDirectiveLookupPlugin.test.mjs +40 -0
- package/dist/vite/createViteAwareResolver.d.mts +1 -2
- package/dist/vite/createViteAwareResolver.mjs +1 -1
- package/dist/vite/directiveModulesDevPlugin.d.mts +4 -1
- package/dist/vite/directiveModulesDevPlugin.mjs +9 -8
- package/dist/vite/directiveModulesDevPlugin.test.d.mts +1 -0
- package/dist/vite/directiveModulesDevPlugin.test.mjs +59 -0
- package/dist/vite/directivesPlugin.d.mts +1 -0
- package/dist/vite/directivesPlugin.mjs +4 -4
- package/dist/vite/directivesPlugin.test.d.mts +1 -0
- package/dist/vite/directivesPlugin.test.mjs +24 -0
- package/dist/vite/ensureAliasArray.test.d.mts +1 -0
- package/dist/vite/ensureAliasArray.test.mjs +71 -0
- package/dist/vite/findSpecifiers.mjs +3 -2
- package/dist/vite/findSpecifiers.test.d.mts +1 -0
- package/dist/vite/findSpecifiers.test.mjs +202 -0
- package/dist/vite/findSsrSpecifiers.mjs +1 -1
- package/dist/vite/findSsrSpecifiers.test.d.mts +1 -0
- package/dist/vite/findSsrSpecifiers.test.mjs +99 -0
- package/dist/vite/getViteEsbuild.mjs +1 -1
- package/dist/vite/hasDirective.d.mts +6 -3
- package/dist/vite/hasDirective.mjs +43 -27
- package/dist/vite/hasDirective.test.d.mts +1 -0
- package/dist/vite/hasDirective.test.mjs +107 -0
- package/dist/vite/index.d.mts +1 -1
- package/dist/vite/invalidateCacheIfPrismaClientChanged.mjs +2 -2
- package/dist/vite/isJsFile.test.d.mts +1 -0
- package/dist/vite/isJsFile.test.mjs +38 -0
- package/dist/vite/{reactConditionsResolverPlugin.d.mts → knownDepsResolverPlugin.d.mts} +3 -3
- package/dist/vite/{reactConditionsResolverPlugin.mjs → knownDepsResolverPlugin.mjs} +29 -24
- package/dist/vite/linkerPlugin.d.mts +8 -0
- package/dist/vite/linkerPlugin.mjs +32 -24
- package/dist/vite/linkerPlugin.test.d.mts +1 -0
- package/dist/vite/linkerPlugin.test.mjs +41 -0
- package/dist/vite/miniflareHMRPlugin.d.mts +5 -0
- package/dist/vite/miniflareHMRPlugin.mjs +7 -7
- package/dist/vite/miniflareHMRPlugin.test.d.mts +1 -0
- package/dist/vite/miniflareHMRPlugin.test.mjs +42 -0
- package/dist/vite/prismaPlugin.mjs +1 -1
- package/dist/vite/redwoodPlugin.d.mts +9 -0
- package/dist/vite/redwoodPlugin.mjs +44 -20
- package/dist/vite/redwoodPlugin.test.d.mts +1 -0
- package/dist/vite/redwoodPlugin.test.mjs +34 -0
- package/dist/vite/resolveForcedPaths.d.mts +4 -0
- package/dist/vite/resolveForcedPaths.mjs +9 -0
- package/dist/vite/runDirectivesScan.d.mts +22 -1
- package/dist/vite/runDirectivesScan.mjs +109 -61
- package/dist/vite/runDirectivesScan.test.d.mts +1 -0
- package/dist/vite/runDirectivesScan.test.mjs +73 -0
- package/dist/vite/ssrBridgePlugin.mjs +10 -3
- package/dist/vite/transformClientComponents.mjs +8 -6
- package/dist/vite/transformClientComponents.test.mjs +117 -59
- package/dist/vite/transformJsxScriptTagsPlugin.mjs +1 -1
- package/dist/vite/transformJsxScriptTagsPlugin.test.mjs +2 -2
- package/dist/vite/transformServerFunctions.d.mts +1 -1
- package/dist/vite/transformServerFunctions.mjs +5 -5
- package/dist/vite/transformServerFunctions.test.mjs +3 -3
- package/package.json +61 -47
- package/dist/runtime/imports/resolveSSRValue.d.ts +0 -1
- package/dist/runtime/imports/resolveSSRValue.js +0 -8
- package/dist/runtime/render/renderRscThenableToHtmlStream.js +0 -54
- package/dist/runtime/render/transformRscToHtmlStream.d.ts +0 -8
- package/dist/runtime/render/transformRscToHtmlStream.js +0 -19
- /package/dist/lib/{normalizeModulePath.test.d.ts → e2e/types.mjs} +0 -0
package/dist/vite/buildApp.d.mts
CHANGED
|
@@ -6,10 +6,11 @@ import type { ViteBuilder } from "vite";
|
|
|
6
6
|
*
|
|
7
7
|
* @see docs/architecture/productionBuildProcess.md
|
|
8
8
|
*/
|
|
9
|
-
export declare function buildApp({ builder, clientEntryPoints, clientFiles, serverFiles, projectRootDir, }: {
|
|
9
|
+
export declare function buildApp({ builder, clientEntryPoints, clientFiles, serverFiles, projectRootDir, workerEntryPathname, }: {
|
|
10
10
|
builder: ViteBuilder;
|
|
11
11
|
clientEntryPoints: Set<string>;
|
|
12
12
|
clientFiles: Set<string>;
|
|
13
13
|
serverFiles: Set<string>;
|
|
14
14
|
projectRootDir: string;
|
|
15
|
+
workerEntryPathname: string;
|
|
15
16
|
}): Promise<void>;
|
package/dist/vite/buildApp.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { resolve } from "node:path";
|
|
2
1
|
import debug from "debug";
|
|
2
|
+
import { resolve } from "node:path";
|
|
3
3
|
import { runDirectivesScan } from "./runDirectivesScan.mjs";
|
|
4
4
|
const log = debug("rwsdk:vite:build-app");
|
|
5
5
|
/**
|
|
@@ -9,13 +9,14 @@ const log = debug("rwsdk:vite:build-app");
|
|
|
9
9
|
*
|
|
10
10
|
* @see docs/architecture/productionBuildProcess.md
|
|
11
11
|
*/
|
|
12
|
-
export async function buildApp({ builder, clientEntryPoints, clientFiles, serverFiles, projectRootDir, }) {
|
|
12
|
+
export async function buildApp({ builder, clientEntryPoints, clientFiles, serverFiles, projectRootDir, workerEntryPathname, }) {
|
|
13
13
|
const workerEnv = builder.environments.worker;
|
|
14
14
|
await runDirectivesScan({
|
|
15
15
|
rootConfig: builder.config,
|
|
16
16
|
environments: builder.environments,
|
|
17
17
|
clientFiles,
|
|
18
18
|
serverFiles,
|
|
19
|
+
entries: [workerEntryPathname],
|
|
19
20
|
});
|
|
20
21
|
console.log("Building worker to discover used client components...");
|
|
21
22
|
process.env.RWSDK_BUILD_PASS = "worker";
|
|
@@ -42,11 +43,14 @@ export async function buildApp({ builder, clientEntryPoints, clientFiles, server
|
|
|
42
43
|
// Re-configure the worker environment for the linking pass
|
|
43
44
|
const workerConfig = workerEnv.config;
|
|
44
45
|
workerConfig.build.emptyOutDir = false;
|
|
46
|
+
// context(justinvdm, 22 Sep 2025): This is a workaround to satisfy the
|
|
47
|
+
// Cloudflare plugin's expectation of an entry chunk named `index`. The plugin
|
|
48
|
+
// now manages the worker build, so we no longer set rollup options
|
|
49
|
+
// directly. Instead, we re-point the original entry to the intermediate
|
|
50
|
+
// worker bundle from the first pass. This allows the linker pass to re-use
|
|
51
|
+
// the same plugin-driven configuration while bundling the final worker.
|
|
45
52
|
workerConfig.build.rollupOptions.input = {
|
|
46
|
-
|
|
47
|
-
};
|
|
48
|
-
workerConfig.build.rollupOptions.output = {
|
|
49
|
-
entryFileNames: "worker.js",
|
|
53
|
+
index: resolve(projectRootDir, "dist", "worker", "index.js"),
|
|
50
54
|
};
|
|
51
55
|
await builder.build(workerEnv);
|
|
52
56
|
console.log("Build complete!");
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
export type PrismaCheckResult = {
|
|
2
2
|
isUsingPrisma: boolean;
|
|
3
3
|
};
|
|
4
|
+
export declare const isUsingPrisma: ({ projectRootDir, resolver, }: {
|
|
5
|
+
projectRootDir: string;
|
|
6
|
+
resolver?: (path: string, request: string) => string | false;
|
|
7
|
+
}) => boolean;
|
|
4
8
|
export declare const checkPrismaStatus: ({ projectRootDir, }: {
|
|
5
9
|
projectRootDir: string;
|
|
6
10
|
}) => PrismaCheckResult;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import enhancedResolve from "enhanced-resolve";
|
|
2
|
-
const isUsingPrisma = ({ projectRootDir }) => {
|
|
2
|
+
export const isUsingPrisma = ({ projectRootDir, resolver = enhancedResolve.sync, }) => {
|
|
3
3
|
try {
|
|
4
|
-
const prismaClientPath =
|
|
4
|
+
const prismaClientPath = resolver(projectRootDir, "@prisma/client");
|
|
5
5
|
if (!prismaClientPath) {
|
|
6
6
|
return false;
|
|
7
7
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import { isUsingPrisma } from "./checkIsUsingPrisma.mjs";
|
|
3
|
+
describe("isUsingPrisma", () => {
|
|
4
|
+
it("should return true if prisma client is resolved", () => {
|
|
5
|
+
const resolver = () => "/path/to/prisma/client";
|
|
6
|
+
const result = isUsingPrisma({
|
|
7
|
+
projectRootDir: "/test/project",
|
|
8
|
+
resolver: resolver,
|
|
9
|
+
});
|
|
10
|
+
expect(result).toBe(true);
|
|
11
|
+
});
|
|
12
|
+
it("should return false if prisma client is not resolved", () => {
|
|
13
|
+
const resolver = () => false;
|
|
14
|
+
const result = isUsingPrisma({
|
|
15
|
+
projectRootDir: "/test/project",
|
|
16
|
+
resolver: resolver,
|
|
17
|
+
});
|
|
18
|
+
expect(result).toBe(false);
|
|
19
|
+
});
|
|
20
|
+
it("should return false if resolver throws", () => {
|
|
21
|
+
const resolver = () => {
|
|
22
|
+
throw new Error("Module not found");
|
|
23
|
+
};
|
|
24
|
+
const result = isUsingPrisma({
|
|
25
|
+
projectRootDir: "/test/project",
|
|
26
|
+
resolver: resolver,
|
|
27
|
+
});
|
|
28
|
+
expect(result).toBe(false);
|
|
29
|
+
});
|
|
30
|
+
});
|
|
@@ -1,13 +1,11 @@
|
|
|
1
|
-
import path, { resolve } from "node:path";
|
|
2
1
|
import enhancedResolve from "enhanced-resolve";
|
|
3
|
-
import
|
|
2
|
+
import path, { resolve } from "node:path";
|
|
4
3
|
import { INTERMEDIATE_SSR_BRIDGE_PATH } from "../lib/constants.mjs";
|
|
5
4
|
import { buildApp } from "./buildApp.mjs";
|
|
6
5
|
import { externalModules } from "./constants.mjs";
|
|
7
|
-
const log = debug("rwsdk:vite:config");
|
|
8
6
|
export const configPlugin = ({ silent, projectRootDir, workerEntryPathname, clientFiles, serverFiles, clientEntryPoints, }) => ({
|
|
9
7
|
name: "rwsdk:config",
|
|
10
|
-
config: async (_) => {
|
|
8
|
+
config: async (_, { command }) => {
|
|
11
9
|
const mode = process.env.NODE_ENV;
|
|
12
10
|
const workerConfig = {
|
|
13
11
|
resolve: {
|
|
@@ -33,7 +31,17 @@ export const configPlugin = ({ silent, projectRootDir, workerEntryPathname, clie
|
|
|
33
31
|
},
|
|
34
32
|
optimizeDeps: {
|
|
35
33
|
noDiscovery: false,
|
|
36
|
-
include: [
|
|
34
|
+
include: [
|
|
35
|
+
"rwsdk/__ssr_bridge",
|
|
36
|
+
"rwsdk/auth",
|
|
37
|
+
"rwsdk/constants",
|
|
38
|
+
"rwsdk/db",
|
|
39
|
+
"rwsdk/debug",
|
|
40
|
+
"rwsdk/realtime/durableObject",
|
|
41
|
+
"rwsdk/realtime/worker",
|
|
42
|
+
"rwsdk/router",
|
|
43
|
+
"rwsdk/worker",
|
|
44
|
+
],
|
|
37
45
|
exclude: [],
|
|
38
46
|
entries: [workerEntryPathname],
|
|
39
47
|
esbuildOptions: {
|
|
@@ -49,14 +57,6 @@ export const configPlugin = ({ silent, projectRootDir, workerEntryPathname, clie
|
|
|
49
57
|
emitAssets: true,
|
|
50
58
|
emptyOutDir: false,
|
|
51
59
|
ssr: true,
|
|
52
|
-
rollupOptions: {
|
|
53
|
-
output: {
|
|
54
|
-
inlineDynamicImports: true,
|
|
55
|
-
},
|
|
56
|
-
input: {
|
|
57
|
-
worker: workerEntryPathname,
|
|
58
|
-
},
|
|
59
|
-
},
|
|
60
60
|
},
|
|
61
61
|
};
|
|
62
62
|
const baseConfig = {
|
|
@@ -88,7 +88,13 @@ export const configPlugin = ({ silent, projectRootDir, workerEntryPathname, clie
|
|
|
88
88
|
},
|
|
89
89
|
optimizeDeps: {
|
|
90
90
|
noDiscovery: false,
|
|
91
|
-
include: [
|
|
91
|
+
include: [
|
|
92
|
+
"rwsdk/client",
|
|
93
|
+
"rwsdk/constants",
|
|
94
|
+
"rwsdk/debug",
|
|
95
|
+
"rwsdk/realtime/client",
|
|
96
|
+
"rwsdk/turnstile",
|
|
97
|
+
],
|
|
92
98
|
entries: [],
|
|
93
99
|
esbuildOptions: {
|
|
94
100
|
jsx: "automatic",
|
|
@@ -115,7 +121,18 @@ export const configPlugin = ({ silent, projectRootDir, workerEntryPathname, clie
|
|
|
115
121
|
noDiscovery: false,
|
|
116
122
|
entries: [workerEntryPathname],
|
|
117
123
|
exclude: externalModules,
|
|
118
|
-
include: [
|
|
124
|
+
include: [
|
|
125
|
+
"rwsdk/__ssr",
|
|
126
|
+
"rwsdk/__ssr_bridge",
|
|
127
|
+
"rwsdk/client",
|
|
128
|
+
"rwsdk/constants",
|
|
129
|
+
"rwsdk/debug",
|
|
130
|
+
"rwsdk/realtime/client",
|
|
131
|
+
"rwsdk/router",
|
|
132
|
+
"rwsdk/worker",
|
|
133
|
+
"rwsdk/realtime/durableObject",
|
|
134
|
+
"rwsdk/realtime/worker",
|
|
135
|
+
],
|
|
119
136
|
esbuildOptions: {
|
|
120
137
|
jsx: "automatic",
|
|
121
138
|
jsxImportSource: "react",
|
|
@@ -136,8 +153,30 @@ export const configPlugin = ({ silent, projectRootDir, workerEntryPathname, clie
|
|
|
136
153
|
outDir: path.dirname(INTERMEDIATE_SSR_BRIDGE_PATH),
|
|
137
154
|
rollupOptions: {
|
|
138
155
|
output: {
|
|
156
|
+
// context(justinvdm, 15 Sep 2025): The SSR bundle is a
|
|
157
|
+
// pre-compiled artifact. When the linker pass bundles it into
|
|
158
|
+
// the intermediate worker bundle (another pre-compiled
|
|
159
|
+
// artifact), Rollup merges their top-level scopes. Since both
|
|
160
|
+
// may have identical minified identifiers (e.g., `l0`), this
|
|
161
|
+
// causes a redeclaration error. To solve this, we wrap the SSR
|
|
162
|
+
// bundle in an exporting IIFE. This creates a scope boundary,
|
|
163
|
+
// preventing symbol collisions while producing a valid,
|
|
164
|
+
// tree-shakeable ES module. The inline plugin below removes the
|
|
165
|
+
// original `export` statement from the bundle to prevent syntax
|
|
166
|
+
// errors.
|
|
139
167
|
inlineDynamicImports: true,
|
|
168
|
+
banner: `export const { renderHtmlStream, ssrLoadModule, ssrWebpackRequire, ssrGetModuleExport, createThenableFromReadableStream } = (function() {`,
|
|
169
|
+
footer: `return { renderHtmlStream, ssrLoadModule, ssrWebpackRequire, ssrGetModuleExport, createThenableFromReadableStream };\n})();`,
|
|
140
170
|
},
|
|
171
|
+
plugins: [
|
|
172
|
+
{
|
|
173
|
+
name: "rwsdk:ssr-bridge-exports",
|
|
174
|
+
renderChunk(code) {
|
|
175
|
+
// Remove the original export statement as it's now handled by the banner/footer
|
|
176
|
+
return code.replace(/export\s*{[^}]+};?/, "");
|
|
177
|
+
},
|
|
178
|
+
},
|
|
179
|
+
],
|
|
141
180
|
},
|
|
142
181
|
},
|
|
143
182
|
},
|
|
@@ -154,6 +193,7 @@ export const configPlugin = ({ silent, projectRootDir, workerEntryPathname, clie
|
|
|
154
193
|
clientEntryPoints,
|
|
155
194
|
clientFiles,
|
|
156
195
|
serverFiles,
|
|
196
|
+
workerEntryPathname,
|
|
157
197
|
});
|
|
158
198
|
},
|
|
159
199
|
},
|
|
@@ -1,4 +1,13 @@
|
|
|
1
1
|
import { Plugin } from "vite";
|
|
2
|
+
export declare function generateLookupMap({ files, isDev, kind, exportName, }: {
|
|
3
|
+
files: Set<string>;
|
|
4
|
+
isDev: boolean;
|
|
5
|
+
kind: "client" | "server";
|
|
6
|
+
exportName: string;
|
|
7
|
+
}): {
|
|
8
|
+
code: string;
|
|
9
|
+
map: import("magic-string").SourceMap;
|
|
10
|
+
};
|
|
2
11
|
interface DirectiveLookupConfig {
|
|
3
12
|
kind: "client" | "server";
|
|
4
13
|
directive: "use client" | "use server";
|
|
@@ -1,7 +1,34 @@
|
|
|
1
|
+
import debug from "debug";
|
|
1
2
|
import MagicString from "magic-string";
|
|
2
3
|
import path from "path";
|
|
3
|
-
import debug from "debug";
|
|
4
4
|
import { VENDOR_CLIENT_BARREL_EXPORT_PATH, VENDOR_SERVER_BARREL_EXPORT_PATH, } from "../lib/constants.mjs";
|
|
5
|
+
export function generateLookupMap({ files, isDev, kind, exportName, }) {
|
|
6
|
+
const s = new MagicString(`
|
|
7
|
+
export const ${exportName} = {
|
|
8
|
+
${Array.from(files)
|
|
9
|
+
.map((file) => {
|
|
10
|
+
if (file.includes("node_modules") && isDev) {
|
|
11
|
+
const barrelPath = kind === "client"
|
|
12
|
+
? VENDOR_CLIENT_BARREL_EXPORT_PATH
|
|
13
|
+
: VENDOR_SERVER_BARREL_EXPORT_PATH;
|
|
14
|
+
return `
|
|
15
|
+
"${file}": () => import("${barrelPath}").then(m => m.default["${file}"]),
|
|
16
|
+
`;
|
|
17
|
+
}
|
|
18
|
+
else {
|
|
19
|
+
return `
|
|
20
|
+
"${file}": () => import("${file}"),
|
|
21
|
+
`;
|
|
22
|
+
}
|
|
23
|
+
})
|
|
24
|
+
.join("")}
|
|
25
|
+
};
|
|
26
|
+
`);
|
|
27
|
+
return {
|
|
28
|
+
code: s.toString(),
|
|
29
|
+
map: s.generateMap(),
|
|
30
|
+
};
|
|
31
|
+
}
|
|
5
32
|
export const createDirectiveLookupPlugin = async ({ projectRootDir, files, config, }) => {
|
|
6
33
|
const debugNamespace = `rwsdk:vite:${config.pluginName}`;
|
|
7
34
|
const log = debug(debugNamespace);
|
|
@@ -121,35 +148,12 @@ export const createDirectiveLookupPlugin = async ({ projectRootDir, files, confi
|
|
|
121
148
|
log("Loading %s module with %d files", config.virtualModuleName, files.size);
|
|
122
149
|
const environment = this.environment?.name || "client";
|
|
123
150
|
log("Current environment: %s, isDev: %s", environment, isDev);
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
.
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
? VENDOR_CLIENT_BARREL_EXPORT_PATH
|
|
131
|
-
: VENDOR_SERVER_BARREL_EXPORT_PATH;
|
|
132
|
-
return `
|
|
133
|
-
"${file}": () => import("${barrelPath}").then(m => m.default["${file}"]),
|
|
134
|
-
`;
|
|
135
|
-
}
|
|
136
|
-
else {
|
|
137
|
-
return `
|
|
138
|
-
"${file}": () => import("${file}"),
|
|
139
|
-
`;
|
|
140
|
-
}
|
|
141
|
-
})
|
|
142
|
-
.join("")}
|
|
143
|
-
};
|
|
144
|
-
`);
|
|
145
|
-
const code = s.toString();
|
|
146
|
-
const map = s.generateMap();
|
|
147
|
-
log("Generated virtual module code length: %d", code.length);
|
|
148
|
-
process.env.VERBOSE && log("Generated virtual module code: %s", code);
|
|
149
|
-
return {
|
|
150
|
-
code,
|
|
151
|
-
map,
|
|
152
|
-
};
|
|
151
|
+
return generateLookupMap({
|
|
152
|
+
files,
|
|
153
|
+
isDev,
|
|
154
|
+
kind: config.kind,
|
|
155
|
+
exportName: config.exportName,
|
|
156
|
+
});
|
|
153
157
|
}
|
|
154
158
|
},
|
|
155
159
|
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import { VENDOR_CLIENT_BARREL_EXPORT_PATH, VENDOR_SERVER_BARREL_EXPORT_PATH, } from "../lib/constants.mjs";
|
|
3
|
+
import { generateLookupMap } from "./createDirectiveLookupPlugin.mjs";
|
|
4
|
+
describe("generateLookupMap", () => {
|
|
5
|
+
const files = new Set([
|
|
6
|
+
"src/app.js",
|
|
7
|
+
"node_modules/lib-a/index.js",
|
|
8
|
+
"src/component.tsx",
|
|
9
|
+
]);
|
|
10
|
+
it("should generate correct map for client in dev", () => {
|
|
11
|
+
const result = generateLookupMap({
|
|
12
|
+
files,
|
|
13
|
+
isDev: true,
|
|
14
|
+
kind: "client",
|
|
15
|
+
exportName: "clientLookup",
|
|
16
|
+
});
|
|
17
|
+
expect(result.code).toContain("export const clientLookup = {");
|
|
18
|
+
expect(result.code).toContain(`"src/app.js": () => import("src/app.js")`);
|
|
19
|
+
expect(result.code).toContain(`"node_modules/lib-a/index.js": () => import("${VENDOR_CLIENT_BARREL_EXPORT_PATH}").then(m => m.default["node_modules/lib-a/index.js"])`);
|
|
20
|
+
});
|
|
21
|
+
it("should generate correct map for server in dev", () => {
|
|
22
|
+
const result = generateLookupMap({
|
|
23
|
+
files,
|
|
24
|
+
isDev: true,
|
|
25
|
+
kind: "server",
|
|
26
|
+
exportName: "serverLookup",
|
|
27
|
+
});
|
|
28
|
+
expect(result.code).toContain("export const serverLookup = {");
|
|
29
|
+
expect(result.code).toContain(`"node_modules/lib-a/index.js": () => import("${VENDOR_SERVER_BARREL_EXPORT_PATH}").then(m => m.default["node_modules/lib-a/index.js"])`);
|
|
30
|
+
});
|
|
31
|
+
it("should generate correct map for prod (isDev: false)", () => {
|
|
32
|
+
const result = generateLookupMap({
|
|
33
|
+
files,
|
|
34
|
+
isDev: false,
|
|
35
|
+
kind: "client",
|
|
36
|
+
exportName: "clientLookup",
|
|
37
|
+
});
|
|
38
|
+
expect(result.code).toContain(`"node_modules/lib-a/index.js": () => import("node_modules/lib-a/index.js")`);
|
|
39
|
+
});
|
|
40
|
+
});
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import resolve, { ResolveOptions } from "enhanced-resolve";
|
|
2
|
-
import { ResolvedConfig } from "vite";
|
|
3
|
-
import { Environment } from "vite";
|
|
2
|
+
import { Environment, ResolvedConfig } from "vite";
|
|
4
3
|
export declare const mapViteResolveToEnhancedResolveOptions: (viteConfig: ResolvedConfig, envName: string) => ResolveOptions;
|
|
5
4
|
export declare const createViteAwareResolver: (viteConfig: ResolvedConfig, environment: Environment) => resolve.ResolveFunctionAsync;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
+
import createDebug from "debug";
|
|
1
2
|
import resolve from "enhanced-resolve";
|
|
2
3
|
import fs from "fs";
|
|
3
4
|
import path from "path";
|
|
4
|
-
import createDebug from "debug";
|
|
5
5
|
import { normalizeModulePath } from "../lib/normalizeModulePath.mjs";
|
|
6
6
|
const debug = createDebug("rwsdk:vite:enhanced-resolve-plugin");
|
|
7
7
|
// Enhanced-resolve plugin that wraps Vite plugin resolution
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import { Plugin } from "vite";
|
|
2
|
-
export declare const
|
|
2
|
+
export declare const generateVendorBarrelContent: (files: Set<string>, projectRootDir: string) => string;
|
|
3
|
+
export declare const generateAppBarrelContent: (files: Set<string>, projectRootDir: string) => string;
|
|
4
|
+
export declare const directiveModulesDevPlugin: ({ clientFiles, serverFiles, projectRootDir, workerEntryPathname, }: {
|
|
3
5
|
clientFiles: Set<string>;
|
|
4
6
|
serverFiles: Set<string>;
|
|
5
7
|
projectRootDir: string;
|
|
8
|
+
workerEntryPathname: string;
|
|
6
9
|
}) => Plugin;
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { mkdirSync, mkdtempSync, writeFileSync } from "node:fs";
|
|
2
2
|
import os from "os";
|
|
3
|
-
import
|
|
3
|
+
import path from "path";
|
|
4
|
+
import { VENDOR_CLIENT_BARREL_EXPORT_PATH, VENDOR_CLIENT_BARREL_PATH, VENDOR_SERVER_BARREL_EXPORT_PATH, VENDOR_SERVER_BARREL_PATH, } from "../lib/constants.mjs";
|
|
4
5
|
import { normalizeModulePath } from "../lib/normalizeModulePath.mjs";
|
|
5
|
-
import { VENDOR_CLIENT_BARREL_PATH, VENDOR_SERVER_BARREL_PATH, VENDOR_CLIENT_BARREL_EXPORT_PATH, VENDOR_SERVER_BARREL_EXPORT_PATH, } from "../lib/constants.mjs";
|
|
6
6
|
import { runDirectivesScan } from "./runDirectivesScan.mjs";
|
|
7
|
-
const generateVendorBarrelContent = (files, projectRootDir) => {
|
|
7
|
+
export const generateVendorBarrelContent = (files, projectRootDir) => {
|
|
8
8
|
const imports = [...files]
|
|
9
9
|
.filter((file) => file.includes("node_modules"))
|
|
10
10
|
.map((file, i) => `import * as M${i} from '${normalizeModulePath(file, projectRootDir, {
|
|
@@ -19,7 +19,7 @@ const generateVendorBarrelContent = (files, projectRootDir) => {
|
|
|
19
19
|
"\n};";
|
|
20
20
|
return `${imports}\n\n${exports}`;
|
|
21
21
|
};
|
|
22
|
-
const generateAppBarrelContent = (files, projectRootDir
|
|
22
|
+
export const generateAppBarrelContent = (files, projectRootDir) => {
|
|
23
23
|
return [...files]
|
|
24
24
|
.filter((file) => !file.includes("node_modules"))
|
|
25
25
|
.map((file) => {
|
|
@@ -30,7 +30,7 @@ const generateAppBarrelContent = (files, projectRootDir, barrelFilePath) => {
|
|
|
30
30
|
})
|
|
31
31
|
.join("\n");
|
|
32
32
|
};
|
|
33
|
-
export const directiveModulesDevPlugin = ({ clientFiles, serverFiles, projectRootDir, }) => {
|
|
33
|
+
export const directiveModulesDevPlugin = ({ clientFiles, serverFiles, projectRootDir, workerEntryPathname, }) => {
|
|
34
34
|
const { promise: scanPromise, resolve: resolveScanPromise } = Promise.withResolvers();
|
|
35
35
|
const tempDir = mkdtempSync(path.join(os.tmpdir(), "rwsdk-"));
|
|
36
36
|
const APP_CLIENT_BARREL_PATH = path.join(tempDir, "app-client-barrel.js");
|
|
@@ -47,6 +47,7 @@ export const directiveModulesDevPlugin = ({ clientFiles, serverFiles, projectRoo
|
|
|
47
47
|
environments: server.environments,
|
|
48
48
|
clientFiles,
|
|
49
49
|
serverFiles,
|
|
50
|
+
entries: [workerEntryPathname],
|
|
50
51
|
}).then(() => {
|
|
51
52
|
// context(justinvdm, 11 Sep 2025): For vendor barrels, we write the
|
|
52
53
|
// files directly to disk after the scan. For app barrels, we use a
|
|
@@ -83,7 +84,7 @@ export const directiveModulesDevPlugin = ({ clientFiles, serverFiles, projectRoo
|
|
|
83
84
|
env.optimizeDeps.include ??= [];
|
|
84
85
|
const entries = (env.optimizeDeps.entries = castArray(env.optimizeDeps.entries ?? []));
|
|
85
86
|
env.optimizeDeps.include.push(VENDOR_CLIENT_BARREL_EXPORT_PATH, VENDOR_SERVER_BARREL_EXPORT_PATH);
|
|
86
|
-
if (envName === "client") {
|
|
87
|
+
if (envName === "client" || envName === "ssr") {
|
|
87
88
|
entries.push(APP_CLIENT_BARREL_PATH);
|
|
88
89
|
}
|
|
89
90
|
else if (envName === "worker") {
|
|
@@ -129,7 +130,7 @@ export const directiveModulesDevPlugin = ({ clientFiles, serverFiles, projectRoo
|
|
|
129
130
|
build.onLoad({ filter: /.*/, namespace: "rwsdk-app-barrel-ns" }, (args) => {
|
|
130
131
|
const isServerBarrel = args.path.includes("app-server-barrel");
|
|
131
132
|
const files = isServerBarrel ? serverFiles : clientFiles;
|
|
132
|
-
const content = generateAppBarrelContent(files, projectRootDir
|
|
133
|
+
const content = generateAppBarrelContent(files, projectRootDir);
|
|
133
134
|
return {
|
|
134
135
|
contents: content,
|
|
135
136
|
loader: "js",
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import { generateAppBarrelContent, generateVendorBarrelContent, } from "./directiveModulesDevPlugin.mjs";
|
|
3
|
+
describe("directiveModulesDevPlugin helpers", () => {
|
|
4
|
+
const projectRootDir = "/Users/test/project";
|
|
5
|
+
describe("generateVendorBarrelContent", () => {
|
|
6
|
+
it("should generate correct content for vendor files", () => {
|
|
7
|
+
const files = new Set([
|
|
8
|
+
"node_modules/lib-a/index.js",
|
|
9
|
+
"src/app.js",
|
|
10
|
+
"node_modules/lib-b/component.tsx",
|
|
11
|
+
]);
|
|
12
|
+
const content = generateVendorBarrelContent(files, projectRootDir);
|
|
13
|
+
const expected = `import * as M0 from '${projectRootDir}/node_modules/lib-a/index.js';
|
|
14
|
+
import * as M1 from '${projectRootDir}/node_modules/lib-b/component.tsx';
|
|
15
|
+
|
|
16
|
+
export default {
|
|
17
|
+
'/node_modules/lib-a/index.js': M0,
|
|
18
|
+
'/node_modules/lib-b/component.tsx': M1,
|
|
19
|
+
};`;
|
|
20
|
+
expect(content).toEqual(expected);
|
|
21
|
+
});
|
|
22
|
+
it("should return empty content if no vendor files", () => {
|
|
23
|
+
const files = new Set(["src/app.js", "src/component.tsx"]);
|
|
24
|
+
const content = generateVendorBarrelContent(files, projectRootDir);
|
|
25
|
+
expect(content).toEqual("\n\nexport default {\n\n};");
|
|
26
|
+
});
|
|
27
|
+
it("should handle an empty file set", () => {
|
|
28
|
+
const files = new Set();
|
|
29
|
+
const content = generateVendorBarrelContent(files, projectRootDir);
|
|
30
|
+
expect(content).toEqual("\n\nexport default {\n\n};");
|
|
31
|
+
});
|
|
32
|
+
});
|
|
33
|
+
describe("generateAppBarrelContent", () => {
|
|
34
|
+
it("should generate correct content for app files", () => {
|
|
35
|
+
const files = new Set([
|
|
36
|
+
"src/app.js",
|
|
37
|
+
"node_modules/lib-a/index.js",
|
|
38
|
+
"src/component.tsx",
|
|
39
|
+
]);
|
|
40
|
+
const content = generateAppBarrelContent(files, projectRootDir);
|
|
41
|
+
const expected = `import "${projectRootDir}/src/app.js";
|
|
42
|
+
import "${projectRootDir}/src/component.tsx";`;
|
|
43
|
+
expect(content).toEqual(expected);
|
|
44
|
+
});
|
|
45
|
+
it("should return empty content if no app files", () => {
|
|
46
|
+
const files = new Set([
|
|
47
|
+
"node_modules/lib-a/index.js",
|
|
48
|
+
"node_modules/lib-b/component.tsx",
|
|
49
|
+
]);
|
|
50
|
+
const content = generateAppBarrelContent(files, projectRootDir);
|
|
51
|
+
expect(content).toEqual("");
|
|
52
|
+
});
|
|
53
|
+
it("should handle an empty file set", () => {
|
|
54
|
+
const files = new Set();
|
|
55
|
+
const content = generateAppBarrelContent(files, projectRootDir);
|
|
56
|
+
expect(content).toEqual("");
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
});
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import path from "node:path";
|
|
2
|
-
import fs from "node:fs/promises";
|
|
3
1
|
import debug from "debug";
|
|
2
|
+
import fs from "node:fs/promises";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { normalizeModulePath } from "../lib/normalizeModulePath.mjs";
|
|
4
5
|
import { transformClientComponents } from "./transformClientComponents.mjs";
|
|
5
6
|
import { transformServerFunctions } from "./transformServerFunctions.mjs";
|
|
6
|
-
import { normalizeModulePath } from "../lib/normalizeModulePath.mjs";
|
|
7
7
|
const log = debug("rwsdk:vite:rsc-directives-plugin");
|
|
8
|
-
const getLoader = (filePath) => {
|
|
8
|
+
export const getLoader = (filePath) => {
|
|
9
9
|
const ext = path.extname(filePath).slice(1);
|
|
10
10
|
switch (ext) {
|
|
11
11
|
case "mjs":
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import { getLoader } from "./directivesPlugin.mjs";
|
|
3
|
+
describe("getLoader", () => {
|
|
4
|
+
const testCases = [
|
|
5
|
+
{ path: "file.js", expected: "js" },
|
|
6
|
+
{ path: "file.mjs", expected: "js" },
|
|
7
|
+
{ path: "file.cjs", expected: "js" },
|
|
8
|
+
{ path: "file.ts", expected: "ts" },
|
|
9
|
+
{ path: "file.mts", expected: "ts" },
|
|
10
|
+
{ path: "file.cts", expected: "ts" },
|
|
11
|
+
{ path: "file.jsx", expected: "jsx" },
|
|
12
|
+
{ path: "file.tsx", expected: "tsx" },
|
|
13
|
+
{ path: "/path/to/component.ts", expected: "ts" },
|
|
14
|
+
{ path: "../relative/path.jsx", expected: "jsx" },
|
|
15
|
+
{ path: "file.css", expected: "js" }, // default case
|
|
16
|
+
{ path: "file.json", expected: "js" }, // default case
|
|
17
|
+
{ path: "file", expected: "js" }, // no extension
|
|
18
|
+
];
|
|
19
|
+
testCases.forEach(({ path, expected }) => {
|
|
20
|
+
it(`should return "${expected}" for "${path}"`, () => {
|
|
21
|
+
expect(getLoader(path)).toBe(expected);
|
|
22
|
+
});
|
|
23
|
+
});
|
|
24
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import { ensureAliasArray } from "./ensureAliasArray.mjs";
|
|
3
|
+
describe("ensureAliasArray", () => {
|
|
4
|
+
it("should create resolve and alias array if resolve is undefined", () => {
|
|
5
|
+
const config = {};
|
|
6
|
+
const result = ensureAliasArray(config);
|
|
7
|
+
expect(result).toEqual([]);
|
|
8
|
+
expect(config.resolve?.alias).toEqual([]);
|
|
9
|
+
expect(result).toBe(config.resolve?.alias);
|
|
10
|
+
});
|
|
11
|
+
it("should create alias array if alias is undefined", () => {
|
|
12
|
+
const config = { resolve: {} };
|
|
13
|
+
const result = ensureAliasArray(config);
|
|
14
|
+
expect(result).toEqual([]);
|
|
15
|
+
expect(config.resolve?.alias).toEqual([]);
|
|
16
|
+
expect(result).toBe(config.resolve?.alias);
|
|
17
|
+
});
|
|
18
|
+
it("should convert an alias object to an array", () => {
|
|
19
|
+
const config = {
|
|
20
|
+
resolve: {
|
|
21
|
+
alias: {
|
|
22
|
+
find: "/replacement",
|
|
23
|
+
another: "/another-replacement",
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
};
|
|
27
|
+
const result = ensureAliasArray(config);
|
|
28
|
+
const expected = [
|
|
29
|
+
{ find: "find", replacement: "/replacement" },
|
|
30
|
+
{ find: "another", replacement: "/another-replacement" },
|
|
31
|
+
];
|
|
32
|
+
expect(result).toEqual(expected);
|
|
33
|
+
expect(config.resolve?.alias).toEqual(expected);
|
|
34
|
+
expect(result).toBe(config.resolve?.alias);
|
|
35
|
+
});
|
|
36
|
+
it("should return a clone of an existing alias array", () => {
|
|
37
|
+
const originalAlias = [{ find: "find", replacement: "/replacement" }];
|
|
38
|
+
const config = {
|
|
39
|
+
resolve: {
|
|
40
|
+
alias: originalAlias,
|
|
41
|
+
},
|
|
42
|
+
};
|
|
43
|
+
const result = ensureAliasArray(config);
|
|
44
|
+
expect(result).toEqual(originalAlias);
|
|
45
|
+
expect(result).not.toBe(originalAlias);
|
|
46
|
+
expect(config.resolve?.alias).toEqual(originalAlias);
|
|
47
|
+
expect(config.resolve?.alias).not.toBe(originalAlias);
|
|
48
|
+
});
|
|
49
|
+
it("should handle an empty alias object", () => {
|
|
50
|
+
const config = {
|
|
51
|
+
resolve: {
|
|
52
|
+
alias: {},
|
|
53
|
+
},
|
|
54
|
+
};
|
|
55
|
+
const result = ensureAliasArray(config);
|
|
56
|
+
expect(result).toEqual([]);
|
|
57
|
+
expect(config.resolve?.alias).toEqual([]);
|
|
58
|
+
});
|
|
59
|
+
it("should handle an empty alias array", () => {
|
|
60
|
+
const config = {
|
|
61
|
+
resolve: {
|
|
62
|
+
alias: [],
|
|
63
|
+
},
|
|
64
|
+
};
|
|
65
|
+
const originalAlias = config.resolve?.alias;
|
|
66
|
+
const result = ensureAliasArray(config);
|
|
67
|
+
expect(result).toEqual([]);
|
|
68
|
+
expect(config.resolve?.alias).toEqual([]);
|
|
69
|
+
expect(result).not.toBe(originalAlias);
|
|
70
|
+
});
|
|
71
|
+
});
|