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.
Files changed (214) hide show
  1. package/dist/lib/constants.mjs +1 -2
  2. package/dist/lib/e2e/browser.d.mts +10 -0
  3. package/dist/lib/e2e/browser.mjs +123 -0
  4. package/dist/lib/e2e/dev.d.mts +8 -0
  5. package/dist/lib/e2e/dev.mjs +242 -0
  6. package/dist/lib/e2e/environment.d.mts +10 -0
  7. package/dist/lib/e2e/environment.mjs +210 -0
  8. package/dist/lib/e2e/index.d.mts +8 -0
  9. package/dist/lib/e2e/index.mjs +8 -0
  10. package/dist/lib/e2e/poll.d.mts +8 -0
  11. package/dist/lib/e2e/poll.mjs +31 -0
  12. package/dist/lib/e2e/release.d.mts +56 -0
  13. package/dist/lib/e2e/release.mjs +559 -0
  14. package/dist/lib/e2e/retry.d.mts +4 -0
  15. package/dist/lib/e2e/retry.mjs +16 -0
  16. package/dist/lib/e2e/setup.d.mts +2 -0
  17. package/dist/lib/e2e/setup.mjs +1 -0
  18. package/dist/lib/e2e/tarball.d.mts +14 -0
  19. package/dist/lib/e2e/tarball.mjs +99 -0
  20. package/dist/lib/e2e/testHarness.d.mts +132 -0
  21. package/dist/lib/e2e/testHarness.mjs +436 -0
  22. package/dist/lib/e2e/types.d.mts +32 -0
  23. package/dist/lib/getShortName.mjs +6 -2
  24. package/dist/lib/getShortName.test.d.mts +1 -0
  25. package/dist/lib/getShortName.test.mjs +25 -0
  26. package/dist/lib/getSrcPaths.js +2 -2
  27. package/dist/lib/hasPkgScript.d.mts +4 -1
  28. package/dist/lib/hasPkgScript.mjs +9 -6
  29. package/dist/lib/hasPkgScript.test.d.mts +1 -0
  30. package/dist/lib/hasPkgScript.test.mjs +33 -0
  31. package/dist/lib/jsonUtils.mjs +3 -0
  32. package/dist/lib/jsonUtils.test.d.mts +1 -0
  33. package/dist/lib/jsonUtils.test.mjs +90 -0
  34. package/dist/lib/normalizeModulePath.d.mts +5 -0
  35. package/dist/lib/normalizeModulePath.mjs +1 -1
  36. package/dist/lib/normalizeModulePath.test.d.mts +1 -0
  37. package/dist/lib/{normalizeModulePath.test.js → normalizeModulePath.test.mjs} +21 -2
  38. package/dist/lib/setupEnvFiles.mjs +2 -2
  39. package/dist/lib/smokeTests/artifacts.mjs +2 -2
  40. package/dist/lib/smokeTests/browser.d.mts +1 -1
  41. package/dist/lib/smokeTests/browser.mjs +8 -100
  42. package/dist/lib/smokeTests/cleanup.mjs +6 -9
  43. package/dist/lib/smokeTests/codeUpdates.mjs +5 -5
  44. package/dist/lib/smokeTests/development.mjs +3 -224
  45. package/dist/lib/smokeTests/environment.d.mts +3 -11
  46. package/dist/lib/smokeTests/environment.mjs +17 -151
  47. package/dist/lib/smokeTests/release.d.mts +2 -49
  48. package/dist/lib/smokeTests/release.mjs +4 -504
  49. package/dist/lib/smokeTests/reporting.mjs +2 -2
  50. package/dist/lib/smokeTests/runSmokeTests.mjs +4 -4
  51. package/dist/lib/smokeTests/utils.mjs +3 -3
  52. package/dist/lib/testUtils/stubEnvVars.mjs +1 -1
  53. package/dist/llms/rules/middleware.d.ts +1 -1
  54. package/dist/llms/rules/middleware.js +4 -4
  55. package/dist/runtime/client/client.d.ts +2 -2
  56. package/dist/runtime/client/client.js +2 -2
  57. package/dist/runtime/client/navigation.test.js +1 -1
  58. package/dist/runtime/client/types.d.ts +1 -1
  59. package/dist/runtime/entries/client.d.ts +2 -2
  60. package/dist/runtime/entries/client.js +2 -2
  61. package/dist/runtime/entries/router.d.ts +1 -1
  62. package/dist/runtime/entries/router.js +1 -1
  63. package/dist/runtime/entries/worker.d.ts +5 -6
  64. package/dist/runtime/entries/worker.js +5 -6
  65. package/dist/runtime/imports/worker.js +1 -1
  66. package/dist/runtime/lib/auth/session.d.ts +2 -2
  67. package/dist/runtime/lib/auth/session.js +5 -5
  68. package/dist/runtime/lib/db/DOWorkerDialect.d.ts +1 -1
  69. package/dist/runtime/lib/db/DOWorkerDialect.js +1 -1
  70. package/dist/runtime/lib/db/SqliteDurableObject.js +2 -2
  71. package/dist/runtime/lib/db/index.d.ts +2 -2
  72. package/dist/runtime/lib/db/index.js +2 -2
  73. package/dist/runtime/lib/db/migrations.d.ts +1 -1
  74. package/dist/runtime/lib/db/typeInference/builders/alterTable.d.ts +3 -3
  75. package/dist/runtime/lib/db/typeInference/builders/columnDefinition.d.ts +1 -1
  76. package/dist/runtime/lib/db/typeInference/builders/createTable.d.ts +2 -2
  77. package/dist/runtime/lib/db/typeInference/builders/createView.d.ts +1 -1
  78. package/dist/runtime/lib/db/typeInference/builders/dropTable.d.ts +1 -1
  79. package/dist/runtime/lib/db/typeInference/builders/dropView.d.ts +1 -1
  80. package/dist/runtime/lib/db/typeInference/builders/schema.d.ts +3 -3
  81. package/dist/runtime/lib/db/typeInference/database.d.ts +2 -2
  82. package/dist/runtime/lib/memoizeOnId.test.d.ts +1 -0
  83. package/dist/runtime/lib/memoizeOnId.test.js +49 -0
  84. package/dist/runtime/lib/realtime/client.js +2 -2
  85. package/dist/runtime/lib/realtime/durableObject.js +1 -1
  86. package/dist/runtime/lib/realtime/protocol.test.d.ts +1 -0
  87. package/dist/runtime/lib/realtime/protocol.test.js +107 -0
  88. package/dist/runtime/lib/realtime/shared.test.d.ts +1 -0
  89. package/dist/runtime/lib/realtime/shared.test.js +18 -0
  90. package/dist/runtime/lib/realtime/validateUpgradeRequest.test.d.ts +1 -0
  91. package/dist/runtime/lib/realtime/validateUpgradeRequest.test.js +66 -0
  92. package/dist/runtime/lib/realtime/worker.d.ts +1 -1
  93. package/dist/runtime/lib/realtime/worker.js +2 -2
  94. package/dist/runtime/lib/router.d.ts +1 -1
  95. package/dist/runtime/lib/router.js +40 -22
  96. package/dist/runtime/lib/router.test.js +591 -3
  97. package/dist/runtime/lib/rwContext.d.ts +22 -0
  98. package/dist/runtime/lib/rwContext.js +1 -0
  99. package/dist/runtime/lib/stitchDocumentAndAppStreams.d.ts +18 -0
  100. package/dist/runtime/lib/stitchDocumentAndAppStreams.js +143 -0
  101. package/dist/runtime/lib/turnstile/useTurnstile.js +1 -1
  102. package/dist/runtime/lib/turnstile/verifyTurnstileToken.d.ts +2 -1
  103. package/dist/runtime/lib/turnstile/verifyTurnstileToken.js +6 -6
  104. package/dist/runtime/lib/turnstile/verifyTurnstileToken.test.d.ts +1 -0
  105. package/dist/runtime/lib/turnstile/verifyTurnstileToken.test.js +49 -0
  106. package/dist/runtime/register/worker.d.ts +1 -1
  107. package/dist/runtime/register/worker.js +34 -22
  108. package/dist/runtime/render/assembleDocument.d.ts +6 -0
  109. package/dist/runtime/render/assembleDocument.js +22 -0
  110. package/dist/runtime/render/createThenableFromReadableStream.d.ts +1 -0
  111. package/dist/runtime/render/createThenableFromReadableStream.js +9 -0
  112. package/dist/runtime/render/normalizeActionResult.d.ts +1 -0
  113. package/dist/runtime/render/normalizeActionResult.js +43 -0
  114. package/dist/runtime/render/preloads.d.ts +3 -3
  115. package/dist/runtime/render/preloads.js +2 -3
  116. package/dist/runtime/render/{renderRscThenableToHtmlStream.d.ts → renderDocumentHtmlStream.d.ts} +3 -3
  117. package/dist/runtime/render/renderDocumentHtmlStream.js +39 -0
  118. package/dist/runtime/render/renderHtmlStream.d.ts +7 -0
  119. package/dist/runtime/render/renderHtmlStream.js +31 -0
  120. package/dist/runtime/render/renderToRscStream.d.ts +5 -3
  121. package/dist/runtime/render/renderToRscStream.js +12 -41
  122. package/dist/runtime/render/renderToStream.d.ts +3 -2
  123. package/dist/runtime/render/renderToStream.js +17 -10
  124. package/dist/runtime/render/stylesheets.d.ts +2 -2
  125. package/dist/runtime/render/stylesheets.js +2 -3
  126. package/dist/runtime/requestInfo/types.d.ts +0 -2
  127. package/dist/runtime/requestInfo/worker.d.ts +1 -1
  128. package/dist/runtime/requestInfo/worker.js +1 -9
  129. package/dist/runtime/script.js +1 -1
  130. package/dist/runtime/ssrBridge.d.ts +3 -2
  131. package/dist/runtime/ssrBridge.js +3 -2
  132. package/dist/runtime/worker.d.ts +2 -1
  133. package/dist/runtime/worker.js +13 -16
  134. package/dist/scripts/addon.d.mts +1 -0
  135. package/dist/scripts/addon.mjs +75 -0
  136. package/dist/scripts/debug-sync.mjs +106 -137
  137. package/dist/scripts/ensure-deploy-env.mjs +6 -6
  138. package/dist/scripts/migrate-new.mjs +3 -4
  139. package/dist/scripts/smoke-test.mjs +2 -2
  140. package/dist/scripts/worker-run.mjs +7 -9
  141. package/dist/vite/buildApp.d.mts +2 -1
  142. package/dist/vite/buildApp.mjs +10 -6
  143. package/dist/vite/checkIsUsingPrisma.d.mts +4 -0
  144. package/dist/vite/checkIsUsingPrisma.mjs +2 -2
  145. package/dist/vite/checkIsUsingPrisma.test.d.mts +1 -0
  146. package/dist/vite/checkIsUsingPrisma.test.mjs +30 -0
  147. package/dist/vite/configPlugin.mjs +55 -15
  148. package/dist/vite/createDirectiveLookupPlugin.d.mts +9 -0
  149. package/dist/vite/createDirectiveLookupPlugin.mjs +34 -30
  150. package/dist/vite/createDirectiveLookupPlugin.test.d.mts +1 -0
  151. package/dist/vite/createDirectiveLookupPlugin.test.mjs +40 -0
  152. package/dist/vite/createViteAwareResolver.d.mts +1 -2
  153. package/dist/vite/createViteAwareResolver.mjs +1 -1
  154. package/dist/vite/directiveModulesDevPlugin.d.mts +4 -1
  155. package/dist/vite/directiveModulesDevPlugin.mjs +9 -8
  156. package/dist/vite/directiveModulesDevPlugin.test.d.mts +1 -0
  157. package/dist/vite/directiveModulesDevPlugin.test.mjs +59 -0
  158. package/dist/vite/directivesPlugin.d.mts +1 -0
  159. package/dist/vite/directivesPlugin.mjs +4 -4
  160. package/dist/vite/directivesPlugin.test.d.mts +1 -0
  161. package/dist/vite/directivesPlugin.test.mjs +24 -0
  162. package/dist/vite/ensureAliasArray.test.d.mts +1 -0
  163. package/dist/vite/ensureAliasArray.test.mjs +71 -0
  164. package/dist/vite/findSpecifiers.mjs +3 -2
  165. package/dist/vite/findSpecifiers.test.d.mts +1 -0
  166. package/dist/vite/findSpecifiers.test.mjs +202 -0
  167. package/dist/vite/findSsrSpecifiers.mjs +1 -1
  168. package/dist/vite/findSsrSpecifiers.test.d.mts +1 -0
  169. package/dist/vite/findSsrSpecifiers.test.mjs +99 -0
  170. package/dist/vite/getViteEsbuild.mjs +1 -1
  171. package/dist/vite/hasDirective.d.mts +6 -3
  172. package/dist/vite/hasDirective.mjs +43 -27
  173. package/dist/vite/hasDirective.test.d.mts +1 -0
  174. package/dist/vite/hasDirective.test.mjs +107 -0
  175. package/dist/vite/index.d.mts +1 -1
  176. package/dist/vite/invalidateCacheIfPrismaClientChanged.mjs +2 -2
  177. package/dist/vite/isJsFile.test.d.mts +1 -0
  178. package/dist/vite/isJsFile.test.mjs +38 -0
  179. package/dist/vite/{reactConditionsResolverPlugin.d.mts → knownDepsResolverPlugin.d.mts} +3 -3
  180. package/dist/vite/{reactConditionsResolverPlugin.mjs → knownDepsResolverPlugin.mjs} +29 -24
  181. package/dist/vite/linkerPlugin.d.mts +8 -0
  182. package/dist/vite/linkerPlugin.mjs +32 -24
  183. package/dist/vite/linkerPlugin.test.d.mts +1 -0
  184. package/dist/vite/linkerPlugin.test.mjs +41 -0
  185. package/dist/vite/miniflareHMRPlugin.d.mts +5 -0
  186. package/dist/vite/miniflareHMRPlugin.mjs +7 -7
  187. package/dist/vite/miniflareHMRPlugin.test.d.mts +1 -0
  188. package/dist/vite/miniflareHMRPlugin.test.mjs +42 -0
  189. package/dist/vite/prismaPlugin.mjs +1 -1
  190. package/dist/vite/redwoodPlugin.d.mts +9 -0
  191. package/dist/vite/redwoodPlugin.mjs +44 -20
  192. package/dist/vite/redwoodPlugin.test.d.mts +1 -0
  193. package/dist/vite/redwoodPlugin.test.mjs +34 -0
  194. package/dist/vite/resolveForcedPaths.d.mts +4 -0
  195. package/dist/vite/resolveForcedPaths.mjs +9 -0
  196. package/dist/vite/runDirectivesScan.d.mts +22 -1
  197. package/dist/vite/runDirectivesScan.mjs +109 -61
  198. package/dist/vite/runDirectivesScan.test.d.mts +1 -0
  199. package/dist/vite/runDirectivesScan.test.mjs +73 -0
  200. package/dist/vite/ssrBridgePlugin.mjs +10 -3
  201. package/dist/vite/transformClientComponents.mjs +8 -6
  202. package/dist/vite/transformClientComponents.test.mjs +117 -59
  203. package/dist/vite/transformJsxScriptTagsPlugin.mjs +1 -1
  204. package/dist/vite/transformJsxScriptTagsPlugin.test.mjs +2 -2
  205. package/dist/vite/transformServerFunctions.d.mts +1 -1
  206. package/dist/vite/transformServerFunctions.mjs +5 -5
  207. package/dist/vite/transformServerFunctions.test.mjs +3 -3
  208. package/package.json +61 -47
  209. package/dist/runtime/imports/resolveSSRValue.d.ts +0 -1
  210. package/dist/runtime/imports/resolveSSRValue.js +0 -8
  211. package/dist/runtime/render/renderRscThenableToHtmlStream.js +0 -54
  212. package/dist/runtime/render/transformRscToHtmlStream.d.ts +0 -8
  213. package/dist/runtime/render/transformRscToHtmlStream.js +0 -19
  214. /package/dist/lib/{normalizeModulePath.test.d.ts → e2e/types.mjs} +0 -0
@@ -1,4 +1,4 @@
1
- import { parse as sgParse, Lang as SgLang, Lang } from "@ast-grep/napi";
1
+ import { Lang, Lang as SgLang, parse as sgParse } from "@ast-grep/napi";
2
2
  import path from "path";
3
3
  // These patterns are used to match import statements in code for SSR transformations.
4
4
  export const IMPORT_PATTERNS = [
@@ -178,7 +178,8 @@ export function findExports(id, code, log) {
178
178
  });
179
179
  logger("Found default export: %s", name);
180
180
  }
181
- else if (matchText.includes("export {")) {
181
+ else if (matchText.includes("export {") &&
182
+ !match.getMatch("MODULE")) {
182
183
  // Local export declaration
183
184
  const exportListMatch = matchText.match(/export\s*\{\s*([^}]+)\s*\}/);
184
185
  if (exportListMatch) {
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,202 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { findExports, findImportSpecifiers } from "./findSpecifiers.mjs";
3
+ function dedupeImports(imports) {
4
+ const seen = new Set();
5
+ return imports.filter((imp) => {
6
+ const key = `${imp.s}:${imp.e}`;
7
+ if (seen.has(key)) {
8
+ return false;
9
+ }
10
+ seen.add(key);
11
+ return true;
12
+ });
13
+ }
14
+ describe("findSpecifiers", () => {
15
+ describe("findImportSpecifiers", () => {
16
+ it("should find various import types", () => {
17
+ const code = `
18
+ import { a } from "module-a";
19
+ import b from 'module-b';
20
+ import * as c from "module-c";
21
+ import "module-d";
22
+ const e = import('module-e');
23
+ const f = require("module-f");
24
+ `;
25
+ const results = findImportSpecifiers("test.ts", code, []);
26
+ const specifiers = dedupeImports(results).map((r) => r.raw);
27
+ expect(specifiers).toEqual([
28
+ "module-a",
29
+ "module-c",
30
+ "module-b",
31
+ "module-d",
32
+ "module-e",
33
+ "module-f",
34
+ ]);
35
+ });
36
+ it("should find re-exports", () => {
37
+ const code = `
38
+ export { a } from "module-a";
39
+ export * from 'module-b';
40
+ `;
41
+ const results = findImportSpecifiers("test.ts", code, []);
42
+ const specifiers = dedupeImports(results).map((r) => r.raw);
43
+ expect(specifiers).toEqual(["module-a", "module-b"]);
44
+ });
45
+ it("should ignore specified patterns", () => {
46
+ const code = `
47
+ import { a } from "module-a";
48
+ import b from 'module-b';
49
+ import c from "ignored-module";
50
+ `;
51
+ const results = findImportSpecifiers("test.ts", code, [/ignored/]);
52
+ const specifiers = dedupeImports(results).map((r) => r.raw);
53
+ expect(specifiers).toEqual(["module-a", "module-b"]);
54
+ });
55
+ it("should ignore virtual modules", () => {
56
+ const code = `import a from "virtual:my-virtual-module";`;
57
+ const results = findImportSpecifiers("test.ts", code, []);
58
+ expect(results).toHaveLength(0);
59
+ });
60
+ it("should ignore __rwsdknossr modules", () => {
61
+ const code = `import a from "some-module?__rwsdknossr";`;
62
+ const results = findImportSpecifiers("test.ts", code, []);
63
+ expect(results).toHaveLength(0);
64
+ });
65
+ it("should handle tsx files", () => {
66
+ const code = `
67
+ import React from 'react';
68
+ const App = () => <div>Hello</div>;
69
+ export default App;
70
+ `;
71
+ const results = findImportSpecifiers("test.tsx", code, []);
72
+ const specifiers = dedupeImports(results).map((r) => r.raw);
73
+ expect(specifiers).toEqual(["react"]);
74
+ });
75
+ it("should return correct positions", () => {
76
+ const code = `import { a } from "module-a";`;
77
+ const results = findImportSpecifiers("test.ts", code, []);
78
+ const deduped = dedupeImports(results);
79
+ expect(deduped).toHaveLength(1);
80
+ expect(deduped[0].s).toBe(19);
81
+ expect(deduped[0].e).toBe(27);
82
+ expect(code.substring(deduped[0].s, deduped[0].e)).toBe("module-a");
83
+ });
84
+ });
85
+ describe("findExports", () => {
86
+ it("should find named exports (const, let, function)", () => {
87
+ const code = `
88
+ export const a = 1;
89
+ export let b = 2;
90
+ export function c() {}
91
+ export async function d() {}
92
+ `;
93
+ const results = findExports("test.ts", code);
94
+ expect(results).toEqual([
95
+ { name: "a", isDefault: false },
96
+ { name: "b", isDefault: false },
97
+ { name: "c", isDefault: false },
98
+ { name: "d", isDefault: false },
99
+ ]);
100
+ });
101
+ it("should find default exports", () => {
102
+ const code = `
103
+ export default function myFunc() {}
104
+ const b = 1;
105
+ export default b;
106
+ `;
107
+ const results = findExports("test.ts", code);
108
+ expect(results).toEqual([
109
+ { name: "myFunc", isDefault: true },
110
+ { name: "default", isDefault: true },
111
+ ]);
112
+ });
113
+ it("should find export declarations", () => {
114
+ const code = `
115
+ const a = 1;
116
+ const b = 2;
117
+ export { a, b as c };
118
+ `;
119
+ const results = findExports("test.ts", code);
120
+ expect(results).toEqual([
121
+ {
122
+ name: "a",
123
+ isDefault: false,
124
+ alias: undefined,
125
+ originalName: "a",
126
+ },
127
+ {
128
+ name: "c",
129
+ isDefault: false,
130
+ alias: "c",
131
+ originalName: "b",
132
+ },
133
+ ]);
134
+ });
135
+ it("should find re-exports", () => {
136
+ const code = `
137
+ export { a, b as c } from 'module-a';
138
+ export { default as d } from 'module-b';
139
+ `;
140
+ const results = findExports("test.ts", code);
141
+ expect(results).toEqual([
142
+ {
143
+ name: "a",
144
+ isDefault: false,
145
+ alias: undefined,
146
+ originalName: "a",
147
+ isReExport: true,
148
+ moduleSpecifier: "module-a",
149
+ },
150
+ {
151
+ name: "c",
152
+ isDefault: false,
153
+ alias: "c",
154
+ originalName: "b",
155
+ isReExport: true,
156
+ moduleSpecifier: "module-a",
157
+ },
158
+ {
159
+ name: "d",
160
+ isDefault: true,
161
+ alias: "d",
162
+ originalName: "default",
163
+ isReExport: true,
164
+ moduleSpecifier: "module-b",
165
+ },
166
+ {
167
+ alias: undefined,
168
+ isDefault: false,
169
+ name: "a",
170
+ originalName: "a",
171
+ },
172
+ {
173
+ alias: "c",
174
+ isDefault: false,
175
+ name: "c",
176
+ originalName: "b",
177
+ },
178
+ {
179
+ alias: "d",
180
+ isDefault: true,
181
+ name: "d",
182
+ originalName: "default",
183
+ },
184
+ ]);
185
+ });
186
+ it("should handle mixed exports", () => {
187
+ const code = `
188
+ export const a = 1;
189
+ export default function b() {}
190
+ const c = 3;
191
+ export { c };
192
+ `;
193
+ const results = findExports("test.tsx", code);
194
+ expect(results).toEqual([
195
+ { name: "a", isDefault: false },
196
+ { name: "b", isDefault: true },
197
+ { isDefault: true, name: "default" },
198
+ { name: "c", isDefault: false, originalName: "c", alias: undefined },
199
+ ]);
200
+ });
201
+ });
202
+ });
@@ -1,4 +1,4 @@
1
- import { parse as sgParse, Lang as SgLang, Lang } from "@ast-grep/napi";
1
+ import { Lang, Lang as SgLang, parse as sgParse } from "@ast-grep/napi";
2
2
  import path from "path";
3
3
  /**
4
4
  * Finds callsites for __vite_ssr_import__ and __vite_ssr_dynamic_import__ with their ranges.
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,99 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { findSsrImportCallSites } from "./findSsrSpecifiers.mjs";
3
+ describe("findSsrImportCallSites", () => {
4
+ it("should find __vite_ssr_import__ with double quotes", () => {
5
+ const code = `const a = __vite_ssr_import__("module-a");`;
6
+ const results = findSsrImportCallSites("test.ts", code);
7
+ expect(results).toHaveLength(1);
8
+ expect(results[0]).toEqual({
9
+ start: 10,
10
+ end: 41,
11
+ specifier: "module-a",
12
+ kind: "import",
13
+ });
14
+ });
15
+ it("should find __vite_ssr_import__ with single quotes", () => {
16
+ const code = `const a = __vite_ssr_import__('module-a');`;
17
+ const results = findSsrImportCallSites("test.ts", code);
18
+ expect(results).toHaveLength(1);
19
+ expect(results[0]).toEqual({
20
+ start: 10,
21
+ end: 41,
22
+ specifier: "module-a",
23
+ kind: "import",
24
+ });
25
+ });
26
+ it("should find __vite_ssr_dynamic_import__ with double quotes", () => {
27
+ const code = `const a = __vite_ssr_dynamic_import__("module-a");`;
28
+ const results = findSsrImportCallSites("test.ts", code);
29
+ expect(results).toHaveLength(1);
30
+ expect(results[0]).toEqual({
31
+ start: 10,
32
+ end: 49,
33
+ specifier: "module-a",
34
+ kind: "dynamic_import",
35
+ });
36
+ });
37
+ it("should find __vite_ssr_dynamic_import__ with single quotes", () => {
38
+ const code = `const a = __vite_ssr_dynamic_import__('module-a');`;
39
+ const results = findSsrImportCallSites("test.ts", code);
40
+ expect(results).toHaveLength(1);
41
+ expect(results[0]).toEqual({
42
+ start: 10,
43
+ end: 49,
44
+ specifier: "module-a",
45
+ kind: "dynamic_import",
46
+ });
47
+ });
48
+ it("should find calls with additional arguments", () => {
49
+ const code = `const a = __vite_ssr_import__('module-a', { ssr: true });`;
50
+ const results = findSsrImportCallSites("test.ts", code);
51
+ expect(results).toHaveLength(1);
52
+ expect(results[0]).toEqual({
53
+ start: 10,
54
+ end: 56,
55
+ specifier: "module-a",
56
+ kind: "import",
57
+ });
58
+ });
59
+ it("should find a mix of different calls", () => {
60
+ const code = `
61
+ const a = __vite_ssr_import__("module-a");
62
+ const b = __vite_ssr_dynamic_import__('module-b');
63
+ `;
64
+ const results = findSsrImportCallSites("test.ts", code);
65
+ expect(results).toHaveLength(2);
66
+ expect(results).toEqual(expect.arrayContaining([
67
+ {
68
+ start: 17,
69
+ end: 48,
70
+ specifier: "module-a",
71
+ kind: "import",
72
+ },
73
+ {
74
+ start: 66,
75
+ end: 105,
76
+ specifier: "module-b",
77
+ kind: "dynamic_import",
78
+ },
79
+ ]));
80
+ });
81
+ it("should return correct ranges for replacement", () => {
82
+ const code = `__vite_ssr_import__("module-a")`;
83
+ const results = findSsrImportCallSites("test.ts", code);
84
+ expect(results).toHaveLength(1);
85
+ const { start, end } = results[0];
86
+ expect(code.substring(start, end)).toBe('__vite_ssr_import__("module-a")');
87
+ });
88
+ it("should return an empty array when no calls are found", () => {
89
+ const code = `import a from "module-a";`;
90
+ const results = findSsrImportCallSites("test.ts", code);
91
+ expect(results).toHaveLength(0);
92
+ });
93
+ it("should handle tsx files correctly", () => {
94
+ const code = `const a = () => <div>{__vite_ssr_import__("module-a")}</div>;`;
95
+ const results = findSsrImportCallSites("test.tsx", code);
96
+ expect(results).toHaveLength(1);
97
+ expect(results[0].specifier).toBe("module-a");
98
+ });
99
+ });
@@ -1,5 +1,5 @@
1
- import path from "node:path";
2
1
  import { createRequire } from "node:module";
2
+ import path from "node:path";
3
3
  const require = createRequire(import.meta.url);
4
4
  export async function getViteEsbuild(projectRootDir) {
5
5
  const vitePath = require.resolve("vite/package.json", {
@@ -1,7 +1,10 @@
1
1
  /**
2
2
  * Efficiently checks if a React directive (e.g., "use server", "use client")
3
- * is present in the code. Optimized for performance with a two-step approach:
4
- * 1. Quick string search to see if directive exists anywhere
5
- * 2. Line-by-line check only if the directive might be present
3
+ * is present in the code.
4
+ *
5
+ * This function is optimized for performance by only checking the first few
6
+ * lines of the code, as directives must appear at the very top of a file.
7
+ * It handles comments, whitespace, and any valid directive prologue
8
+ * (e.g., "use strict").
6
9
  */
7
10
  export declare function hasDirective(code: string, directive: string): boolean;
@@ -1,54 +1,70 @@
1
1
  /**
2
2
  * Efficiently checks if a React directive (e.g., "use server", "use client")
3
- * is present in the code. Optimized for performance with a two-step approach:
4
- * 1. Quick string search to see if directive exists anywhere
5
- * 2. Line-by-line check only if the directive might be present
3
+ * is present in the code.
4
+ *
5
+ * This function is optimized for performance by only checking the first few
6
+ * lines of the code, as directives must appear at the very top of a file.
7
+ * It handles comments, whitespace, and any valid directive prologue
8
+ * (e.g., "use strict").
6
9
  */
7
10
  export function hasDirective(code, directive) {
8
- // Quick performance check: if directive doesn't exist anywhere, skip line checking
9
- const singleQuoteDirective = `'${directive}'`;
10
- const doubleQuoteDirective = `"${directive}"`;
11
- if (!code.includes(singleQuoteDirective) &&
12
- !code.includes(doubleQuoteDirective)) {
13
- return false;
14
- }
15
- // Split into lines and check each one
16
- const lines = code.split("\n");
11
+ const lines = code.slice(0, 512).split("\n"); // Check first ~512 chars
17
12
  let inMultiLineComment = false;
13
+ let foundUseClient = false;
14
+ let foundTargetDirective = false;
15
+ const doubleQuoteDirective = `"${directive}"`;
16
+ const singleQuoteDirective = `'${directive}'`;
17
+ const doubleQuoteUseClient = `"use client"`;
18
+ const singleQuoteUseClient = `'use client'`;
18
19
  for (const line of lines) {
19
20
  const trimmedLine = line.trim();
20
- // Skip empty lines
21
21
  if (trimmedLine.length === 0) {
22
22
  continue;
23
23
  }
24
- // Handle multi-line comments
25
- if (trimmedLine.startsWith("/*")) {
26
- inMultiLineComment = true;
27
- // Check if the comment ends on the same line
24
+ if (inMultiLineComment) {
28
25
  if (trimmedLine.includes("*/")) {
29
26
  inMultiLineComment = false;
30
27
  }
31
28
  continue;
32
29
  }
33
- if (inMultiLineComment) {
34
- // Check if this line ends the multi-line comment
35
- if (trimmedLine.includes("*/")) {
36
- inMultiLineComment = false;
30
+ if (trimmedLine.startsWith("/*")) {
31
+ if (!trimmedLine.includes("*/")) {
32
+ inMultiLineComment = true;
37
33
  }
38
34
  continue;
39
35
  }
40
- // Skip single-line comments
41
36
  if (trimmedLine.startsWith("//")) {
42
37
  continue;
43
38
  }
44
- // Check if this line starts with the directive
39
+ const cleanedLine = trimmedLine.endsWith(";")
40
+ ? trimmedLine.slice(0, -1)
41
+ : trimmedLine;
42
+ if (trimmedLine.startsWith(doubleQuoteUseClient) ||
43
+ trimmedLine.startsWith(singleQuoteUseClient)) {
44
+ foundUseClient = true;
45
+ if (directive === "use client") {
46
+ return true;
47
+ }
48
+ }
45
49
  if (trimmedLine.startsWith(doubleQuoteDirective) ||
46
50
  trimmedLine.startsWith(singleQuoteDirective)) {
47
- return true;
51
+ foundTargetDirective = true;
52
+ if (directive !== "use server") {
53
+ return true;
54
+ }
48
55
  }
49
- // If we hit a non-empty, non-comment line that's not a directive, we can stop
50
- // (directives must be at the top of the file/scope, after comments)
56
+ // Any other string literal is part of a valid directive prologue.
57
+ // We can continue searching.
58
+ if (trimmedLine.startsWith('"') || trimmedLine.startsWith("'")) {
59
+ continue;
60
+ }
61
+ // If we encounter any other non-directive, non-comment, non-string-literal
62
+ // line of code, the directive prologue is over. Stop.
51
63
  break;
52
64
  }
53
- return false;
65
+ // If looking for 'use server' and 'use client' was found, return false (client takes priority)
66
+ if (directive === "use server" && foundUseClient) {
67
+ return false;
68
+ }
69
+ return foundTargetDirective;
54
70
  }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,107 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { hasDirective } from "./hasDirective.mjs";
3
+ describe("hasDirective", () => {
4
+ it('should find "use client" directive', () => {
5
+ const code = `"use client"; import React from "react";`;
6
+ expect(hasDirective(code, "use client")).toBe(true);
7
+ });
8
+ it('should find "use server" directive', () => {
9
+ const code = `'use server'; export async function myAction() {}`;
10
+ expect(hasDirective(code, "use server")).toBe(true);
11
+ });
12
+ it("should not find a directive that is not there", () => {
13
+ const code = `import React from "react";`;
14
+ expect(hasDirective(code, "use client")).toBe(false);
15
+ });
16
+ it('should find "use client" directive with single quotes', () => {
17
+ const code = `'use client'; import React from "react";`;
18
+ expect(hasDirective(code, "use client")).toBe(true);
19
+ });
20
+ it("should find directive when preceded by comments and whitespace", () => {
21
+ const code = `
22
+ // This is a client component
23
+ /* And here is another comment */
24
+
25
+ "use client";
26
+ import React from 'react';
27
+ export default () => <div>Hello</div>;
28
+ `;
29
+ expect(hasDirective(code, "use client")).toBe(true);
30
+ });
31
+ it('should find "use client" directive when preceded by "use strict"', () => {
32
+ const code = `
33
+ "use strict";
34
+ "use client";
35
+ import React from 'react';
36
+ export default () => <div>Hello</div>;
37
+ `;
38
+ expect(hasDirective(code, "use client")).toBe(true);
39
+ });
40
+ it('should find "use server" directive when preceded by "use strict" and comments', () => {
41
+ const code = `
42
+ // server stuff
43
+ "use strict";
44
+ /* another comment */
45
+ "use server";
46
+ export async function myAction() {}
47
+ `;
48
+ expect(hasDirective(code, "use server")).toBe(true);
49
+ });
50
+ it("should find directive when preceded by another string literal directive", () => {
51
+ const code = `
52
+ "use awesome"; // Some other directive
53
+ "use client";
54
+ import React from 'react';
55
+ export default () => <div>Hello</div>;
56
+ `;
57
+ expect(hasDirective(code, "use client")).toBe(true);
58
+ });
59
+ it("should return false if no directive is present", () => {
60
+ const code = `import React from "react";
61
+ export default () => <div>Hello</div>;`;
62
+ expect(hasDirective(code, "use client")).toBe(false);
63
+ });
64
+ it("should return false if the directive is commented out", () => {
65
+ const code = `// "use client";
66
+ import React from "react";
67
+ export default () => <div>Hello</div>;`;
68
+ expect(hasDirective(code, "use client")).toBe(false);
69
+ });
70
+ it("should return false if the directive appears after code", () => {
71
+ const code = `import React from "react";
72
+ "use client";
73
+ export default () => <div>Hello</div>;`;
74
+ expect(hasDirective(code, "use client")).toBe(false);
75
+ });
76
+ it("should handle multi-line comments correctly", () => {
77
+ const code = `
78
+ /*
79
+ * "use client";
80
+ */
81
+ import React from "react";
82
+ `;
83
+ expect(hasDirective(code, "use client")).toBe(false);
84
+ });
85
+ it("should handle code with no whitespace", () => {
86
+ const code = `"use client";import React from "react";`;
87
+ expect(hasDirective(code, "use client")).toBe(true);
88
+ });
89
+ it("should handle empty code", () => {
90
+ const code = "";
91
+ expect(hasDirective(code, "use client")).toBe(false);
92
+ });
93
+ it("should handle code with only whitespace", () => {
94
+ const code = " \n\t ";
95
+ expect(hasDirective(code, "use client")).toBe(false);
96
+ });
97
+ it("should handle files with only comments", () => {
98
+ const code = `// comment 1
99
+ /* comment 2 */`;
100
+ expect(hasDirective(code, "use client")).toBe(false);
101
+ });
102
+ it("should prioritize 'use client' over 'use server'", () => {
103
+ const code = `'use client';\n'use server';\nconsole.log('hello');`;
104
+ expect(hasDirective(code, "use client")).toBe(true);
105
+ expect(hasDirective(code, "use server")).toBe(false);
106
+ });
107
+ });
@@ -1 +1 @@
1
- export { type RedwoodPluginOptions, redwoodPlugin as redwood, } from "./redwoodPlugin.mjs";
1
+ export { redwoodPlugin as redwood, type RedwoodPluginOptions, } from "./redwoodPlugin.mjs";
@@ -1,6 +1,6 @@
1
- import { resolve } from "node:path";
2
- import { remove, pathExists } from "fs-extra";
1
+ import { pathExists, remove } from "fs-extra";
3
2
  import { stat } from "node:fs/promises";
3
+ import { resolve } from "node:path";
4
4
  export const invalidateCacheIfPrismaClientChanged = async ({ projectRootDir, }) => {
5
5
  const viteDepsCachePath = resolve(projectRootDir, "node_modules", ".vite", `deps_worker`, `@prisma_client.js`);
6
6
  // Get mtimes for comparison
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,38 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { isJsFile } from "./isJsFile.mjs";
3
+ describe("isJsFile", () => {
4
+ const matchingExtensions = [
5
+ "file.js",
6
+ "file.jsx",
7
+ "file.ts",
8
+ "file.tsx",
9
+ "file.mjs",
10
+ "file.mts",
11
+ "file.cjs",
12
+ "file.cts",
13
+ "/path/to/component.js",
14
+ "../relative/path.tsx",
15
+ ];
16
+ const nonMatchingExtensions = [
17
+ "file.css",
18
+ "file.html",
19
+ "file.json",
20
+ "file.txt",
21
+ "file.js.map",
22
+ "file_js",
23
+ "filejs",
24
+ "",
25
+ "no-extension",
26
+ "/path/to/image.png",
27
+ ];
28
+ matchingExtensions.forEach((filepath) => {
29
+ it(`should return true for "${filepath}"`, () => {
30
+ expect(isJsFile(filepath)).toBe(true);
31
+ });
32
+ });
33
+ nonMatchingExtensions.forEach((filepath) => {
34
+ it(`should return false for "${filepath}"`, () => {
35
+ expect(isJsFile(filepath)).toBe(false);
36
+ });
37
+ });
38
+ });
@@ -1,6 +1,6 @@
1
- import { Plugin } from "vite";
2
1
  import enhancedResolve from "enhanced-resolve";
3
- export declare const ENV_REACT_IMPORTS: {
2
+ import { Plugin } from "vite";
3
+ export declare const ENV_PREDEFINED_IMPORTS: {
4
4
  worker: string[];
5
5
  ssr: string[];
6
6
  client: string[];
@@ -10,6 +10,6 @@ export declare const ENV_RESOLVERS: {
10
10
  worker: enhancedResolve.ResolveFunction;
11
11
  client: enhancedResolve.ResolveFunction;
12
12
  };
13
- export declare const reactConditionsResolverPlugin: ({ projectRootDir, }: {
13
+ export declare const knownDepsResolverPlugin: ({ projectRootDir, }: {
14
14
  projectRootDir: string;
15
15
  }) => Plugin[];