rwsdk 0.1.16 → 0.1.17-test.20250715200658

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 (298) hide show
  1. package/dist/lib/$.d.mts +8 -0
  2. package/dist/lib/$.mjs +5 -0
  3. package/dist/lib/constants.d.mts +4 -0
  4. package/dist/lib/constants.mjs +6 -0
  5. package/dist/lib/findWranglerConfig.d.mts +1 -0
  6. package/dist/lib/findWranglerConfig.mjs +12 -0
  7. package/dist/lib/getShortName.d.mts +1 -0
  8. package/dist/lib/getShortName.mjs +2 -0
  9. package/dist/lib/getSrcPaths.d.ts +15 -0
  10. package/dist/lib/getSrcPaths.js +80 -0
  11. package/dist/lib/hasPkgScript.d.mts +1 -0
  12. package/dist/lib/hasPkgScript.mjs +9 -0
  13. package/dist/lib/jsonUtils.d.mts +28 -0
  14. package/dist/lib/jsonUtils.mjs +167 -0
  15. package/dist/lib/setupEnvFiles.d.mts +4 -0
  16. package/dist/lib/setupEnvFiles.mjs +31 -0
  17. package/dist/lib/smokeTests/artifacts.d.mts +10 -0
  18. package/dist/lib/smokeTests/artifacts.mjs +164 -0
  19. package/dist/lib/smokeTests/browser.d.mts +48 -0
  20. package/dist/lib/smokeTests/browser.mjs +1041 -0
  21. package/dist/lib/smokeTests/cleanup.d.mts +5 -0
  22. package/dist/lib/smokeTests/cleanup.mjs +214 -0
  23. package/dist/lib/smokeTests/codeUpdates.d.mts +8 -0
  24. package/dist/lib/smokeTests/codeUpdates.mjs +229 -0
  25. package/dist/lib/smokeTests/constants.d.mts +5 -0
  26. package/dist/lib/smokeTests/constants.mjs +10 -0
  27. package/dist/lib/smokeTests/development.d.mts +11 -0
  28. package/dist/lib/smokeTests/development.mjs +209 -0
  29. package/dist/lib/smokeTests/environment.d.mts +14 -0
  30. package/dist/lib/smokeTests/environment.mjs +163 -0
  31. package/dist/lib/smokeTests/release.d.mts +61 -0
  32. package/dist/lib/smokeTests/release.mjs +526 -0
  33. package/dist/lib/smokeTests/reporting.d.mts +13 -0
  34. package/dist/lib/smokeTests/reporting.mjs +355 -0
  35. package/dist/lib/smokeTests/runSmokeTests.d.mts +5 -0
  36. package/dist/lib/smokeTests/runSmokeTests.mjs +144 -0
  37. package/dist/lib/smokeTests/state.d.mts +48 -0
  38. package/dist/lib/smokeTests/state.mjs +57 -0
  39. package/dist/lib/smokeTests/templates/SmokeTest.template.d.ts +1 -0
  40. package/dist/lib/smokeTests/templates/SmokeTest.template.js +81 -0
  41. package/dist/lib/smokeTests/templates/SmokeTestClient.template.d.ts +1 -0
  42. package/dist/lib/smokeTests/templates/SmokeTestClient.template.js +159 -0
  43. package/dist/lib/smokeTests/templates/smokeTestFunctions.template.d.ts +1 -0
  44. package/dist/lib/smokeTests/templates/smokeTestFunctions.template.js +19 -0
  45. package/dist/lib/smokeTests/types.d.mts +75 -0
  46. package/dist/lib/smokeTests/utils.d.mts +15 -0
  47. package/dist/lib/smokeTests/utils.mjs +147 -0
  48. package/dist/llms/index.d.ts +3 -0
  49. package/dist/llms/index.js +35 -0
  50. package/dist/llms/rules/interruptors.d.ts +1 -0
  51. package/dist/llms/rules/interruptors.js +243 -0
  52. package/dist/llms/rules/middleware.d.ts +1 -0
  53. package/dist/llms/rules/middleware.js +71 -0
  54. package/dist/llms/rules/react.d.ts +1 -0
  55. package/dist/llms/rules/react.js +106 -0
  56. package/dist/llms/rules/request-response.d.ts +1 -0
  57. package/dist/llms/rules/request-response.js +209 -0
  58. package/dist/runtime/client.d.ts +17 -0
  59. package/dist/runtime/client.js +74 -0
  60. package/dist/runtime/clientNavigation.d.ts +4 -0
  61. package/dist/runtime/clientNavigation.js +53 -0
  62. package/dist/runtime/clientNavigation.test.d.ts +1 -0
  63. package/dist/runtime/clientNavigation.test.js +55 -0
  64. package/dist/runtime/constants.d.ts +1 -0
  65. package/dist/runtime/constants.js +1 -0
  66. package/dist/runtime/entries/auth.d.ts +1 -0
  67. package/dist/runtime/entries/auth.js +1 -0
  68. package/dist/runtime/entries/client.d.ts +4 -0
  69. package/dist/runtime/entries/client.js +4 -0
  70. package/dist/runtime/entries/clientSSR.d.ts +1 -0
  71. package/dist/runtime/entries/clientSSR.js +1 -0
  72. package/dist/runtime/entries/no-react-server.d.ts +0 -0
  73. package/dist/runtime/entries/no-react-server.js +2 -0
  74. package/dist/runtime/entries/react-server-only.d.ts +0 -0
  75. package/dist/runtime/entries/react-server-only.js +2 -0
  76. package/dist/runtime/entries/router.d.ts +2 -0
  77. package/dist/runtime/entries/router.js +2 -0
  78. package/dist/runtime/entries/ssr.d.ts +1 -0
  79. package/dist/runtime/entries/ssr.js +1 -0
  80. package/dist/runtime/entries/worker.d.ts +9 -0
  81. package/dist/runtime/entries/worker.js +9 -0
  82. package/dist/runtime/error.d.ts +6 -0
  83. package/dist/runtime/error.js +8 -0
  84. package/dist/runtime/imports/ClientOnly.d.ts +3 -0
  85. package/dist/runtime/imports/ClientOnly.js +8 -0
  86. package/dist/runtime/imports/client.d.ts +4 -0
  87. package/dist/runtime/imports/client.js +33 -0
  88. package/dist/runtime/imports/ssr.d.ts +5 -0
  89. package/dist/runtime/imports/ssr.js +20 -0
  90. package/dist/runtime/imports/worker.d.ts +5 -0
  91. package/dist/runtime/imports/worker.js +22 -0
  92. package/dist/runtime/lib/auth/index.d.ts +1 -0
  93. package/dist/runtime/lib/auth/index.js +1 -0
  94. package/dist/runtime/lib/auth/session.d.ts +50 -0
  95. package/dist/runtime/lib/auth/session.js +148 -0
  96. package/dist/runtime/lib/db/DOWorkerDialect.d.ts +29 -0
  97. package/dist/runtime/lib/db/DOWorkerDialect.js +66 -0
  98. package/dist/runtime/lib/db/SqliteDurableObject.d.ts +14 -0
  99. package/dist/runtime/lib/db/SqliteDurableObject.js +42 -0
  100. package/dist/runtime/lib/db/createDb.d.ts +2 -0
  101. package/dist/runtime/lib/db/createDb.js +33 -0
  102. package/dist/runtime/lib/db/index.d.ts +4 -0
  103. package/dist/runtime/lib/db/index.js +3 -0
  104. package/dist/runtime/lib/db/migrations.d.ts +23 -0
  105. package/dist/runtime/lib/db/migrations.js +34 -0
  106. package/dist/runtime/lib/db/typeInference/assert.d.ts +2 -0
  107. package/dist/runtime/lib/db/typeInference/assert.js +1 -0
  108. package/dist/runtime/lib/db/typeInference/builders/alterColumn.d.ts +27 -0
  109. package/dist/runtime/lib/db/typeInference/builders/alterColumn.js +1 -0
  110. package/dist/runtime/lib/db/typeInference/builders/alterTable.d.ts +53 -0
  111. package/dist/runtime/lib/db/typeInference/builders/alterTable.js +1 -0
  112. package/dist/runtime/lib/db/typeInference/builders/columnDefinition.d.ts +26 -0
  113. package/dist/runtime/lib/db/typeInference/builders/columnDefinition.js +1 -0
  114. package/dist/runtime/lib/db/typeInference/builders/createTable.d.ts +49 -0
  115. package/dist/runtime/lib/db/typeInference/builders/createTable.js +1 -0
  116. package/dist/runtime/lib/db/typeInference/builders/createView.d.ts +17 -0
  117. package/dist/runtime/lib/db/typeInference/builders/createView.js +1 -0
  118. package/dist/runtime/lib/db/typeInference/builders/dropTable.d.ts +11 -0
  119. package/dist/runtime/lib/db/typeInference/builders/dropTable.js +1 -0
  120. package/dist/runtime/lib/db/typeInference/builders/dropView.d.ts +12 -0
  121. package/dist/runtime/lib/db/typeInference/builders/dropView.js +1 -0
  122. package/dist/runtime/lib/db/typeInference/builders/schema.d.ts +24 -0
  123. package/dist/runtime/lib/db/typeInference/builders/schema.js +1 -0
  124. package/dist/runtime/lib/db/typeInference/database.d.ts +27 -0
  125. package/dist/runtime/lib/db/typeInference/database.js +1 -0
  126. package/dist/runtime/lib/db/typeInference/typetests/alterTable.typetest.d.ts +1 -0
  127. package/dist/runtime/lib/db/typeInference/typetests/alterTable.typetest.js +360 -0
  128. package/dist/runtime/lib/db/typeInference/typetests/createTable.typetest.d.ts +1 -0
  129. package/dist/runtime/lib/db/typeInference/typetests/createTable.typetest.js +33 -0
  130. package/dist/runtime/lib/db/typeInference/typetests/dropTable.typetest.d.ts +1 -0
  131. package/dist/runtime/lib/db/typeInference/typetests/dropTable.typetest.js +143 -0
  132. package/dist/runtime/lib/db/typeInference/typetests/print.d.ts +3 -0
  133. package/dist/runtime/lib/db/typeInference/typetests/print.js +1 -0
  134. package/dist/runtime/lib/db/typeInference/typetests/testUtils.d.ts +2 -0
  135. package/dist/runtime/lib/db/typeInference/typetests/testUtils.js +1 -0
  136. package/dist/runtime/lib/db/typeInference/typetests/typeInference.typetest.d.ts +1 -0
  137. package/dist/runtime/lib/db/typeInference/typetests/typeInference.typetest.js +17 -0
  138. package/dist/runtime/lib/db/typeInference/utils.d.ts +82 -0
  139. package/dist/runtime/lib/db/typeInference/utils.js +2 -0
  140. package/dist/runtime/lib/debug.d.ts +2 -0
  141. package/dist/runtime/lib/debug.js +36 -0
  142. package/dist/runtime/lib/links.d.ts +14 -0
  143. package/dist/runtime/lib/links.js +38 -0
  144. package/dist/runtime/lib/realtime/client.d.ts +7 -0
  145. package/dist/runtime/lib/realtime/client.js +166 -0
  146. package/dist/runtime/lib/realtime/constants.d.ts +1 -0
  147. package/dist/runtime/lib/realtime/constants.js +1 -0
  148. package/dist/runtime/lib/realtime/durableObject.d.ts +29 -0
  149. package/dist/runtime/lib/realtime/durableObject.js +187 -0
  150. package/dist/runtime/lib/realtime/renderRealtimeClients.d.ts +7 -0
  151. package/dist/runtime/lib/realtime/renderRealtimeClients.js +6 -0
  152. package/dist/runtime/lib/realtime/shared.d.ts +10 -0
  153. package/dist/runtime/lib/realtime/shared.js +10 -0
  154. package/dist/runtime/lib/realtime/validateUpgradeRequest.d.ts +6 -0
  155. package/dist/runtime/lib/realtime/validateUpgradeRequest.js +29 -0
  156. package/dist/runtime/lib/realtime/worker.d.ts +3 -0
  157. package/dist/runtime/lib/realtime/worker.js +16 -0
  158. package/dist/runtime/lib/router.d.ts +56 -0
  159. package/dist/runtime/lib/router.js +210 -0
  160. package/dist/runtime/lib/router.test.d.ts +1 -0
  161. package/dist/runtime/lib/router.test.js +58 -0
  162. package/dist/runtime/lib/streams/consumeEventStream.d.ts +4 -0
  163. package/dist/runtime/lib/streams/consumeEventStream.js +13 -0
  164. package/dist/runtime/lib/turnstile/TurnstileScript.d.ts +1 -0
  165. package/dist/runtime/lib/turnstile/TurnstileScript.js +2 -0
  166. package/dist/runtime/lib/turnstile/turnstile.d.ts +3 -0
  167. package/dist/runtime/lib/turnstile/turnstile.js +3 -0
  168. package/dist/runtime/lib/turnstile/useTurnstile.d.ts +4 -0
  169. package/dist/runtime/lib/turnstile/useTurnstile.js +23 -0
  170. package/dist/runtime/lib/turnstile/verifyTurnstileToken.d.ts +4 -0
  171. package/dist/runtime/lib/turnstile/verifyTurnstileToken.js +15 -0
  172. package/dist/runtime/lib/utils.d.ts +1 -0
  173. package/dist/runtime/lib/utils.js +1 -0
  174. package/dist/runtime/register/client.d.ts +1 -0
  175. package/dist/runtime/register/client.js +5 -0
  176. package/dist/runtime/register/ssr.d.ts +3 -0
  177. package/dist/runtime/register/ssr.js +26 -0
  178. package/dist/runtime/register/worker.d.ts +4 -0
  179. package/dist/runtime/register/worker.js +42 -0
  180. package/dist/runtime/render/createClientManifest.d.ts +1 -0
  181. package/dist/runtime/render/createClientManifest.js +7 -0
  182. package/dist/runtime/render/createModuleMap.d.ts +1 -0
  183. package/dist/runtime/render/createModuleMap.js +13 -0
  184. package/dist/runtime/render/renderRscThenableToHtmlStream.d.ts +9 -0
  185. package/dist/runtime/render/renderRscThenableToHtmlStream.js +49 -0
  186. package/dist/runtime/render/renderToRscStream.d.ts +5 -0
  187. package/dist/runtime/render/renderToRscStream.js +46 -0
  188. package/dist/runtime/render/renderToStream.d.ts +9 -0
  189. package/dist/runtime/render/renderToStream.js +27 -0
  190. package/dist/runtime/render/renderToString.d.ts +7 -0
  191. package/dist/runtime/render/renderToString.js +26 -0
  192. package/dist/runtime/render/transformRscToHtmlStream.d.ts +8 -0
  193. package/dist/runtime/render/transformRscToHtmlStream.js +19 -0
  194. package/dist/runtime/requestInfo/types.d.ts +11 -0
  195. package/dist/runtime/requestInfo/types.js +1 -0
  196. package/dist/runtime/requestInfo/worker.d.ts +5 -0
  197. package/dist/runtime/requestInfo/worker.js +33 -0
  198. package/dist/runtime/script.d.ts +5 -0
  199. package/dist/runtime/script.js +8 -0
  200. package/dist/runtime/ssrBridge.d.ts +2 -0
  201. package/dist/runtime/ssrBridge.js +11 -0
  202. package/dist/runtime/worker.d.ts +18 -0
  203. package/dist/runtime/worker.js +173 -0
  204. package/dist/scripts/__sdk.d.mts +1 -0
  205. package/dist/scripts/__sdk.mjs +14 -0
  206. package/dist/scripts/debug-sync.d.mts +6 -0
  207. package/dist/scripts/debug-sync.mjs +224 -0
  208. package/dist/scripts/dev-init.d.mts +1 -0
  209. package/dist/scripts/dev-init.mjs +25 -0
  210. package/dist/scripts/ensure-deploy-env.d.mts +1 -0
  211. package/dist/scripts/ensure-deploy-env.mjs +271 -0
  212. package/dist/scripts/ensure-env.d.mts +1 -0
  213. package/dist/scripts/ensure-env.mjs +9 -0
  214. package/dist/scripts/migrate-new.d.mts +1 -0
  215. package/dist/scripts/migrate-new.mjs +51 -0
  216. package/dist/scripts/smoke-test.d.mts +1 -0
  217. package/dist/scripts/smoke-test.mjs +166 -0
  218. package/dist/scripts/worker-run.d.mts +1 -0
  219. package/dist/scripts/worker-run.mjs +82 -0
  220. package/dist/vite/checkIsUsingPrisma.d.mts +6 -0
  221. package/dist/vite/checkIsUsingPrisma.mjs +18 -0
  222. package/dist/vite/configPlugin.d.mts +9 -0
  223. package/dist/vite/configPlugin.mjs +169 -0
  224. package/dist/vite/createDirectiveLookupPlugin.d.mts +21 -0
  225. package/dist/vite/createDirectiveLookupPlugin.mjs +231 -0
  226. package/dist/vite/devServerTimingPlugin.d.mts +2 -0
  227. package/dist/vite/devServerTimingPlugin.mjs +24 -0
  228. package/dist/vite/directivesPlugin.d.mts +6 -0
  229. package/dist/vite/directivesPlugin.mjs +200 -0
  230. package/dist/vite/ensureAliasArray.d.mts +2 -0
  231. package/dist/vite/ensureAliasArray.mjs +17 -0
  232. package/dist/vite/findSpecifiers.d.mts +31 -0
  233. package/dist/vite/findSpecifiers.mjs +230 -0
  234. package/dist/vite/findSsrSpecifiers.d.mts +11 -0
  235. package/dist/vite/findSsrSpecifiers.mjs +67 -0
  236. package/dist/vite/hasDirective.d.mts +7 -0
  237. package/dist/vite/hasDirective.mjs +54 -0
  238. package/dist/vite/hasOwnCloudflareVitePlugin.d.mts +3 -0
  239. package/dist/vite/hasOwnCloudflareVitePlugin.mjs +14 -0
  240. package/dist/vite/index.d.mts +1 -0
  241. package/dist/vite/index.mjs +1 -0
  242. package/dist/vite/injectVitePreamblePlugin.d.mts +4 -0
  243. package/dist/vite/injectVitePreamblePlugin.mjs +23 -0
  244. package/dist/vite/invalidateCacheIfPrismaClientChanged.d.mts +3 -0
  245. package/dist/vite/invalidateCacheIfPrismaClientChanged.mjs +27 -0
  246. package/dist/vite/invalidateModule.d.mts +6 -0
  247. package/dist/vite/invalidateModule.mjs +30 -0
  248. package/dist/vite/miniflareHMRPlugin.d.mts +10 -0
  249. package/dist/vite/miniflareHMRPlugin.mjs +209 -0
  250. package/dist/vite/moveStaticAssetsPlugin.d.mts +4 -0
  251. package/dist/vite/moveStaticAssetsPlugin.mjs +12 -0
  252. package/dist/vite/normalizeModulePath.d.mts +1 -0
  253. package/dist/vite/normalizeModulePath.mjs +13 -0
  254. package/dist/vite/prismaPlugin.d.mts +4 -0
  255. package/dist/vite/prismaPlugin.mjs +43 -0
  256. package/dist/vite/reactConditionsResolverPlugin.d.mts +16 -0
  257. package/dist/vite/reactConditionsResolverPlugin.mjs +179 -0
  258. package/dist/vite/redwoodPlugin.d.mts +12 -0
  259. package/dist/vite/redwoodPlugin.mjs +105 -0
  260. package/dist/vite/ssrBridgePlugin.d.mts +7 -0
  261. package/dist/vite/ssrBridgePlugin.mjs +137 -0
  262. package/dist/vite/transformClientComponents.d.mts +12 -0
  263. package/dist/vite/transformClientComponents.mjs +116 -0
  264. package/dist/vite/transformClientComponents.test.d.mts +1 -0
  265. package/dist/vite/transformClientComponents.test.mjs +264 -0
  266. package/dist/vite/transformJsxScriptTagsPlugin.d.mts +8 -0
  267. package/dist/vite/transformJsxScriptTagsPlugin.mjs +315 -0
  268. package/dist/vite/transformJsxScriptTagsPlugin.test.d.mts +1 -0
  269. package/dist/vite/transformJsxScriptTagsPlugin.test.mjs +334 -0
  270. package/dist/vite/transformServerFunctions.d.mts +16 -0
  271. package/dist/vite/transformServerFunctions.mjs +296 -0
  272. package/dist/vite/transformServerFunctions.test.d.mts +1 -0
  273. package/dist/vite/transformServerFunctions.test.mjs +124 -0
  274. package/dist/vite/useClientLookupPlugin.d.mts +5 -0
  275. package/dist/vite/useClientLookupPlugin.mjs +15 -0
  276. package/dist/vite/useServerLookupPlugin.d.mts +5 -0
  277. package/dist/vite/useServerLookupPlugin.mjs +15 -0
  278. package/dist/vite/useServerPlugin.d.mts +1 -0
  279. package/dist/vite/useServerPlugin.mjs +1 -0
  280. package/dist/vite/virtualPlugin.d.mts +2 -0
  281. package/dist/vite/virtualPlugin.mjs +18 -0
  282. package/dist/vite/vitePreamblePlugin.d.mts +1 -0
  283. package/dist/vite/vitePreamblePlugin.mjs +11 -0
  284. package/package.json +1 -1
  285. package/dist/runtime/lib/db/typeInference/builders/table.d.ts +0 -10
  286. package/dist/vite/invalidateClientModule.d.mts +0 -2
  287. package/dist/vite/invalidateClientModule.mjs +0 -8
  288. package/dist/vite/invalidateModule copy.d.mts +0 -2
  289. package/dist/vite/invalidateModule copy.mjs +0 -14
  290. package/dist/vite/invalidateSSRModule.d.mts +0 -2
  291. package/dist/vite/invalidateSSRModule.mjs +0 -7
  292. package/dist/vite/mode.d.mts +0 -5
  293. package/dist/vite/mode.mjs +0 -25
  294. package/dist/vite/modePlugin.d.mts +0 -2
  295. package/dist/vite/modePlugin.mjs +0 -10
  296. /package/dist/{runtime/lib/db/typeInference/builders/table.js → lib/smokeTests/types.mjs} +0 -0
  297. /package/dist/vite/{isJsFile.d.ts → isJsFile.d.mts} +0 -0
  298. /package/dist/vite/{isJsFile.js → isJsFile.mjs} +0 -0
@@ -0,0 +1,315 @@
1
+ import { Project, Node, SyntaxKind } from "ts-morph";
2
+ import { readFile } from "node:fs/promises";
3
+ import { pathExists } from "fs-extra";
4
+ let manifestCache;
5
+ const readManifest = async (manifestPath) => {
6
+ if (manifestCache === undefined) {
7
+ const exists = await pathExists(manifestPath);
8
+ if (!exists) {
9
+ throw new Error(`RedwoodSDK expected client manifest to exist at ${manifestPath}. This is likely a bug. Please report it at https://github.com/redwoodjs/sdk/issues/new`);
10
+ }
11
+ manifestCache = JSON.parse(await readFile(manifestPath, "utf-8"));
12
+ }
13
+ return manifestCache;
14
+ };
15
+ function hasJsxFunctions(text) {
16
+ return (text.includes('jsx("script"') ||
17
+ text.includes("jsx('script'") ||
18
+ text.includes('jsx("link"') ||
19
+ text.includes("jsx('link'") ||
20
+ text.includes('jsxs("script"') ||
21
+ text.includes("jsxs('script'") ||
22
+ text.includes('jsxs("link"') ||
23
+ text.includes("jsxs('link'") ||
24
+ text.includes('jsxDEV("script"') ||
25
+ text.includes("jsxDEV('script'") ||
26
+ text.includes('jsxDEV("link"') ||
27
+ text.includes("jsxDEV('link'"));
28
+ }
29
+ // Transform import statements in script content using ts-morph
30
+ function transformScriptImports(scriptContent, manifest) {
31
+ const scriptProject = new Project({ useInMemoryFileSystem: true });
32
+ try {
33
+ // Wrap in a function to make it valid JavaScript
34
+ const wrappedContent = `function __wrapper() {${scriptContent}}`;
35
+ const scriptFile = scriptProject.createSourceFile("script.js", wrappedContent);
36
+ let hasChanges = false;
37
+ // Find all CallExpressions that look like import("path")
38
+ scriptFile
39
+ .getDescendantsOfKind(SyntaxKind.CallExpression)
40
+ .forEach((callExpr) => {
41
+ const expr = callExpr.getExpression();
42
+ // Check for both "import()" and "await import()" patterns
43
+ const isImport = expr.getText() === "import";
44
+ // Check for await import pattern
45
+ const isAwaitImport = expr.getKind() === SyntaxKind.PropertyAccessExpression &&
46
+ expr.getText().endsWith(".import");
47
+ if (isImport || isAwaitImport) {
48
+ const args = callExpr.getArguments();
49
+ if (args.length > 0 && Node.isStringLiteral(args[0])) {
50
+ const importPath = args[0].getLiteralValue();
51
+ if (importPath.startsWith("/")) {
52
+ const path = importPath.slice(1); // Remove leading slash
53
+ if (manifest[path]) {
54
+ const transformedPath = manifest[path].file;
55
+ args[0].replaceWithText(`"/${transformedPath}"`);
56
+ hasChanges = true;
57
+ }
58
+ }
59
+ }
60
+ }
61
+ });
62
+ if (hasChanges) {
63
+ // Extract the transformed content from inside the wrapper function
64
+ const fullText = scriptFile.getFullText();
65
+ // Find content between the first { and the last }
66
+ const startPos = fullText.indexOf("{") + 1;
67
+ const endPos = fullText.lastIndexOf("}");
68
+ const transformedContent = fullText.substring(startPos, endPos);
69
+ return { content: transformedContent, hasChanges: true };
70
+ }
71
+ // Return the original content when no changes are made
72
+ return { content: scriptContent, hasChanges: false };
73
+ }
74
+ catch (error) {
75
+ // If parsing fails, fall back to the original content
76
+ console.warn("Failed to parse inline script content:", error);
77
+ return { content: undefined, hasChanges: false };
78
+ }
79
+ }
80
+ export async function transformJsxScriptTagsCode(code, manifest = {}) {
81
+ // context(justinvdm, 15 Jun 2025): Optimization to exit early
82
+ // to avoidunnecessary ts-morph parsing
83
+ if (!hasJsxFunctions(code)) {
84
+ return;
85
+ }
86
+ const project = new Project({ useInMemoryFileSystem: true });
87
+ const sourceFile = project.createSourceFile("temp.tsx", code);
88
+ let hasModifications = false;
89
+ let needsRequestInfoImport = false;
90
+ // Check for existing imports up front
91
+ let hasRequestInfoImport = false;
92
+ let sdkWorkerImportDecl;
93
+ // Scan for imports only once
94
+ sourceFile.getImportDeclarations().forEach((importDecl) => {
95
+ const moduleSpecifier = importDecl.getModuleSpecifierValue();
96
+ if (moduleSpecifier === "rwsdk/worker") {
97
+ sdkWorkerImportDecl = importDecl;
98
+ // Check if requestInfo is already imported
99
+ if (importDecl
100
+ .getNamedImports()
101
+ .some((namedImport) => namedImport.getName() === "requestInfo")) {
102
+ hasRequestInfoImport = true;
103
+ }
104
+ }
105
+ });
106
+ // Look for jsx function calls (jsx, jsxs, jsxDEV)
107
+ sourceFile
108
+ .getDescendantsOfKind(SyntaxKind.CallExpression)
109
+ .forEach((callExpr) => {
110
+ const expression = callExpr.getExpression();
111
+ const expressionText = expression.getText();
112
+ // Only process jsx/jsxs/jsxDEV calls
113
+ if (expressionText !== "jsx" &&
114
+ expressionText !== "jsxs" &&
115
+ expressionText !== "jsxDEV") {
116
+ return;
117
+ }
118
+ // Get arguments of the jsx call
119
+ const args = callExpr.getArguments();
120
+ if (args.length < 2)
121
+ return;
122
+ // First argument should be the element type
123
+ const elementType = args[0];
124
+ if (!Node.isStringLiteral(elementType))
125
+ return;
126
+ const tagName = elementType.getLiteralValue();
127
+ // Process script and link tags
128
+ if (tagName === "script" || tagName === "link") {
129
+ // Second argument should be the props object
130
+ const propsArg = args[1];
131
+ // Handle object literals with properties
132
+ if (Node.isObjectLiteralExpression(propsArg)) {
133
+ const properties = propsArg.getProperties();
134
+ // Variables to track script attributes
135
+ let hasDangerouslySetInnerHTML = false;
136
+ let hasNonce = false;
137
+ let hasStringLiteralChildren = false;
138
+ let hasSrc = false;
139
+ // Variables to track link attributes
140
+ let isPreload = false;
141
+ let hrefValue = null;
142
+ for (const prop of properties) {
143
+ if (Node.isPropertyAssignment(prop)) {
144
+ const propName = prop.getName();
145
+ const initializer = prop.getInitializer();
146
+ // Check for existing nonce
147
+ if (propName === "nonce") {
148
+ hasNonce = true;
149
+ }
150
+ // Check for dangerouslySetInnerHTML
151
+ if (propName === "dangerouslySetInnerHTML") {
152
+ hasDangerouslySetInnerHTML = true;
153
+ }
154
+ // Check for src attribute
155
+ if (tagName === "script" && propName === "src") {
156
+ hasSrc = true;
157
+ // Also process src for manifest transformation if needed
158
+ if (Node.isStringLiteral(initializer) ||
159
+ Node.isNoSubstitutionTemplateLiteral(initializer)) {
160
+ const srcValue = initializer.getLiteralValue();
161
+ if (srcValue.startsWith("/") && manifest[srcValue.slice(1)]) {
162
+ const path = srcValue.slice(1); // Remove leading slash
163
+ const transformedSrc = manifest[path].file;
164
+ const originalText = initializer.getText();
165
+ const isTemplateLiteral = Node.isNoSubstitutionTemplateLiteral(initializer);
166
+ const quote = isTemplateLiteral
167
+ ? "`"
168
+ : originalText.charAt(0);
169
+ // Preserve the original quote style
170
+ if (isTemplateLiteral) {
171
+ initializer.replaceWithText(`\`/${transformedSrc}\``);
172
+ }
173
+ else if (quote === '"') {
174
+ initializer.replaceWithText(`"/${transformedSrc}"`);
175
+ }
176
+ else {
177
+ initializer.replaceWithText(`'/${transformedSrc}'`);
178
+ }
179
+ hasModifications = true;
180
+ }
181
+ }
182
+ }
183
+ // Check for string literal children
184
+ if (tagName === "script" &&
185
+ propName === "children" &&
186
+ (Node.isStringLiteral(initializer) ||
187
+ Node.isNoSubstitutionTemplateLiteral(initializer))) {
188
+ hasStringLiteralChildren = true;
189
+ const scriptContent = initializer.getLiteralValue();
190
+ // Transform import statements in script content using ts-morph
191
+ const { content: transformedContent, hasChanges } = transformScriptImports(scriptContent, manifest);
192
+ if (hasChanges && transformedContent) {
193
+ // Get the raw text with quotes to determine the exact format
194
+ const isTemplateLiteral = Node.isNoSubstitutionTemplateLiteral(initializer);
195
+ if (isTemplateLiteral) {
196
+ // Simply wrap the transformed content in backticks
197
+ initializer.replaceWithText("`" + transformedContent + "`");
198
+ }
199
+ else {
200
+ initializer.replaceWithText(JSON.stringify(transformedContent));
201
+ }
202
+ hasModifications = true;
203
+ }
204
+ }
205
+ // For link tags, first check if it's a preload/modulepreload
206
+ if (tagName === "link") {
207
+ if (propName === "rel" &&
208
+ (Node.isStringLiteral(initializer) ||
209
+ Node.isNoSubstitutionTemplateLiteral(initializer))) {
210
+ const relValue = initializer.getLiteralValue();
211
+ if (relValue === "preload" || relValue === "modulepreload") {
212
+ isPreload = true;
213
+ }
214
+ }
215
+ if (propName === "href" &&
216
+ (Node.isStringLiteral(initializer) ||
217
+ Node.isNoSubstitutionTemplateLiteral(initializer))) {
218
+ hrefValue = initializer.getLiteralValue();
219
+ }
220
+ }
221
+ }
222
+ }
223
+ // Add nonce to script tags if needed
224
+ if (tagName === "script" &&
225
+ !hasNonce &&
226
+ !hasDangerouslySetInnerHTML &&
227
+ (hasStringLiteralChildren || hasSrc)) {
228
+ // Add nonce property to the props object
229
+ propsArg.addPropertyAssignment({
230
+ name: "nonce",
231
+ initializer: "requestInfo.rw.nonce",
232
+ });
233
+ if (!hasRequestInfoImport) {
234
+ needsRequestInfoImport = true;
235
+ }
236
+ hasModifications = true;
237
+ }
238
+ // Transform href if this is a preload link
239
+ if (tagName === "link" &&
240
+ isPreload &&
241
+ hrefValue &&
242
+ hrefValue.startsWith("/") &&
243
+ manifest[hrefValue.slice(1)]) {
244
+ const path = hrefValue.slice(1); // Remove leading slash
245
+ for (const prop of properties) {
246
+ if (Node.isPropertyAssignment(prop) &&
247
+ prop.getName() === "href") {
248
+ const initializer = prop.getInitializer();
249
+ if (Node.isStringLiteral(initializer) ||
250
+ Node.isNoSubstitutionTemplateLiteral(initializer)) {
251
+ const transformedHref = manifest[path].file;
252
+ const originalText = initializer.getText();
253
+ const isTemplateLiteral = Node.isNoSubstitutionTemplateLiteral(initializer);
254
+ const quote = isTemplateLiteral
255
+ ? "`"
256
+ : originalText.charAt(0);
257
+ // Preserve the original quote style
258
+ if (isTemplateLiteral) {
259
+ initializer.replaceWithText(`\`/${transformedHref}\``);
260
+ }
261
+ else if (quote === '"') {
262
+ initializer.replaceWithText(`"/${transformedHref}"`);
263
+ }
264
+ else {
265
+ initializer.replaceWithText(`'/${transformedHref}'`);
266
+ }
267
+ hasModifications = true;
268
+ }
269
+ }
270
+ }
271
+ }
272
+ }
273
+ }
274
+ });
275
+ // Add requestInfo import if needed and not already imported
276
+ if (needsRequestInfoImport && hasModifications) {
277
+ if (sdkWorkerImportDecl) {
278
+ // Module is imported but need to add requestInfo
279
+ if (!hasRequestInfoImport) {
280
+ sdkWorkerImportDecl.addNamedImport("requestInfo");
281
+ }
282
+ }
283
+ else {
284
+ // Add new import declaration
285
+ sourceFile.addImportDeclaration({
286
+ moduleSpecifier: "rwsdk/worker",
287
+ namedImports: ["requestInfo"],
288
+ });
289
+ }
290
+ }
291
+ // Return the transformed code only if modifications were made
292
+ if (hasModifications) {
293
+ return {
294
+ code: sourceFile.getFullText(),
295
+ map: null,
296
+ };
297
+ }
298
+ return;
299
+ }
300
+ export const transformJsxScriptTagsPlugin = ({ manifestPath, }) => {
301
+ let isBuild = false;
302
+ return {
303
+ name: "rwsdk:transform-jsx-script-tags",
304
+ configResolved(config) {
305
+ isBuild = config.command === "build";
306
+ },
307
+ async transform(code) {
308
+ if (this.environment.name !== "worker") {
309
+ return;
310
+ }
311
+ const manifest = isBuild ? await readManifest(manifestPath) : {};
312
+ return transformJsxScriptTagsCode(code, manifest);
313
+ },
314
+ };
315
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,334 @@
1
+ import { describe, it, expect } from "vitest";
2
+ import { transformJsxScriptTagsCode } from "./transformJsxScriptTagsPlugin.mjs";
3
+ describe("transformJsxScriptTagsCode", () => {
4
+ const mockManifest = {
5
+ "src/client.tsx": { file: "assets/client-a1b2c3d4.js" },
6
+ "src/entry.js": { file: "assets/entry-e5f6g7h8.js" },
7
+ "src/styles.css": { file: "assets/styles-i9j0k1l2.css" },
8
+ };
9
+ it("transforms script src attributes in JSX", async () => {
10
+ const code = `
11
+ jsx("script", {
12
+ src: "/src/client.tsx",
13
+ type: "module"
14
+ })
15
+ `;
16
+ const result = await transformJsxScriptTagsCode(code, mockManifest);
17
+ expect(result?.code).toEqual(`import { requestInfo } from "rwsdk/worker";
18
+
19
+ jsx("script", {
20
+ src: "/assets/client-a1b2c3d4.js",
21
+ type: "module",
22
+ nonce: requestInfo.rw.nonce
23
+ })
24
+ `);
25
+ });
26
+ it("transforms inline scripts with dynamic imports", async () => {
27
+ const code = `
28
+ jsx("script", {
29
+ type: "module",
30
+ children: "import('/src/client.tsx').then(module => { console.log(module); })"
31
+ })
32
+ `;
33
+ const result = await transformJsxScriptTagsCode(code, mockManifest);
34
+ expect(result?.code).toEqual(`import { requestInfo } from "rwsdk/worker";
35
+
36
+ jsx("script", {
37
+ type: "module",
38
+ children: "import(\\"\/assets\/client-a1b2c3d4.js\\").then(module => { console.log(module); })",
39
+ nonce: requestInfo.rw.nonce
40
+ })
41
+ `);
42
+ });
43
+ it("transforms inline scripts with type=module", async () => {
44
+ const code = `
45
+ jsx("script", { type: "module", children: "import('/src/client.tsx')" })
46
+ `;
47
+ const result = await transformJsxScriptTagsCode(code, mockManifest);
48
+ expect(result?.code).toEqual(`import { requestInfo } from "rwsdk/worker";
49
+
50
+ jsx("script", { type: "module", children: "import(\\"\/assets\/client-a1b2c3d4.js\\")",
51
+ nonce: requestInfo.rw.nonce
52
+ })
53
+ `);
54
+ });
55
+ it("transforms inline scripts with multiline content", async () => {
56
+ const code = `
57
+ jsx("script", {
58
+ type: "module",
59
+ children: \`
60
+ // Some comments here
61
+ const init = async () => {
62
+ await import('/src/entry.js');
63
+ console.log('initialized');
64
+ };
65
+ init();
66
+ \`
67
+ })
68
+ `;
69
+ const result = await transformJsxScriptTagsCode(code, mockManifest);
70
+ expect(result?.code).toEqual(`import { requestInfo } from "rwsdk/worker";
71
+
72
+ jsx("script", {
73
+ type: "module",
74
+ children: \`
75
+ // Some comments here
76
+ const init = async () => {
77
+ await import("/assets/entry-e5f6g7h8.js");
78
+ console.log('initialized');
79
+ };
80
+ init();
81
+ \`,
82
+ nonce: requestInfo.rw.nonce
83
+ })
84
+ `);
85
+ });
86
+ it("transforms multiple imports in the same inline script", async () => {
87
+ const code = `
88
+ jsx("script", {
89
+ type: "module",
90
+ children: \`
91
+ import('/src/client.tsx');
92
+ import('/src/entry.js');
93
+ \`
94
+ })
95
+ `;
96
+ const result = await transformJsxScriptTagsCode(code, mockManifest);
97
+ expect(result?.code).toEqual(`import { requestInfo } from "rwsdk/worker";
98
+
99
+ jsx("script", {
100
+ type: "module",
101
+ children: \`
102
+ import("/assets/client-a1b2c3d4.js");
103
+ import("/assets/entry-e5f6g7h8.js");
104
+ \`,
105
+ nonce: requestInfo.rw.nonce
106
+ })
107
+ `);
108
+ });
109
+ it("transforms link href attributes with preload rel", async () => {
110
+ const code = `
111
+ jsx("link", {
112
+ rel: "preload",
113
+ href: "/src/client.tsx",
114
+ as: "script"
115
+ })
116
+ `;
117
+ const result = await transformJsxScriptTagsCode(code, mockManifest);
118
+ expect(result?.code).toEqual(`
119
+ jsx("link", {
120
+ rel: "preload",
121
+ href: "/assets/client-a1b2c3d4.js",
122
+ as: "script"
123
+ })
124
+ `);
125
+ });
126
+ it("transforms link href attributes with modulepreload rel", async () => {
127
+ const code = `
128
+ jsx("link", {
129
+ href: "/src/client.tsx",
130
+ rel: "modulepreload"
131
+ })
132
+ `;
133
+ const result = await transformJsxScriptTagsCode(code, mockManifest);
134
+ expect(result?.code).toEqual(`
135
+ jsx("link", {
136
+ href: "/assets/client-a1b2c3d4.js",
137
+ rel: "modulepreload"
138
+ })
139
+ `);
140
+ });
141
+ it("transforms real-world Document component example", async () => {
142
+ const code = `
143
+ jsx("html", {
144
+ lang: "en",
145
+ children: [
146
+ jsx("head", {
147
+ children: [
148
+ jsx("meta", { charSet: "utf-8" }),
149
+ jsx("meta", { name: "viewport", content: "width=device-width, initial-scale=1" }),
150
+ jsx("title", { children: "@redwoodjs/starter-standard" }),
151
+ jsx("link", { rel: "modulepreload", href: "/src/client.tsx", as: "script" })
152
+ ]
153
+ }),
154
+ jsx("body", {
155
+ children: [
156
+ jsx("div", { id: "root", children: props.children }),
157
+ jsx("script", { children: 'import("/src/client.tsx")' })
158
+ ]
159
+ })
160
+ ]
161
+ })
162
+ `;
163
+ const result = await transformJsxScriptTagsCode(code, mockManifest);
164
+ expect(result?.code).toEqual(`import { requestInfo } from "rwsdk/worker";
165
+
166
+ jsx("html", {
167
+ lang: "en",
168
+ children: [
169
+ jsx("head", {
170
+ children: [
171
+ jsx("meta", { charSet: "utf-8" }),
172
+ jsx("meta", { name: "viewport", content: "width=device-width, initial-scale=1" }),
173
+ jsx("title", { children: "@redwoodjs/starter-standard" }),
174
+ jsx("link", { rel: "modulepreload", href: "/assets/client-a1b2c3d4.js", as: "script" })
175
+ ]
176
+ }),
177
+ jsx("body", {
178
+ children: [
179
+ jsx("div", { id: "root", children: props.children }),
180
+ jsx("script", { children: "import(\\"\/assets\/client-a1b2c3d4.js\\")",
181
+ nonce: requestInfo.rw.nonce
182
+ })
183
+ ]
184
+ })
185
+ ]
186
+ })
187
+ `);
188
+ });
189
+ it("returns null when no transformations are needed", async () => {
190
+ const code = `
191
+ jsx("div", { children: "No scripts or links here" })
192
+ `;
193
+ const result = await transformJsxScriptTagsCode(code, mockManifest);
194
+ expect(result).toBeUndefined();
195
+ });
196
+ it("handles paths not found in manifest", async () => {
197
+ const code = `
198
+ jsx("script", {
199
+ src: "/src/non-existent.js",
200
+ type: "module"
201
+ })
202
+ `;
203
+ const result = await transformJsxScriptTagsCode(code, mockManifest);
204
+ expect(result?.code).toEqual(`import { requestInfo } from "rwsdk/worker";
205
+
206
+ jsx("script", {
207
+ src: "/src/non-existent.js",
208
+ type: "module",
209
+ nonce: requestInfo.rw.nonce
210
+ })
211
+ `);
212
+ });
213
+ it("adds nonce to script tags with src attribute and imports requestInfo", async () => {
214
+ const code = `
215
+ jsx("script", {
216
+ src: "/src/client.tsx",
217
+ type: "module"
218
+ })
219
+ `;
220
+ const result = await transformJsxScriptTagsCode(code, mockManifest);
221
+ expect(result?.code).toEqual(`import { requestInfo } from "rwsdk/worker";
222
+
223
+ jsx("script", {
224
+ src: "/assets/client-a1b2c3d4.js",
225
+ type: "module",
226
+ nonce: requestInfo.rw.nonce
227
+ })
228
+ `);
229
+ });
230
+ it("adds nonce to script tags with string literal children", async () => {
231
+ const code = `
232
+ jsx("script", {
233
+ type: "module",
234
+ children: "console.log('hello world')"
235
+ })
236
+ `;
237
+ const result = await transformJsxScriptTagsCode(code, {});
238
+ expect(result?.code).toEqual(`import { requestInfo } from "rwsdk/worker";
239
+
240
+ jsx("script", {
241
+ type: "module",
242
+ children: "console.log('hello world')",
243
+ nonce: requestInfo.rw.nonce
244
+ })
245
+ `);
246
+ });
247
+ it("does not add nonce to script tags with dangerouslySetInnerHTML", async () => {
248
+ const code = `
249
+ jsx("script", {
250
+ type: "module",
251
+ dangerouslySetInnerHTML: { __html: "console.log('hello world')" }
252
+ })
253
+ `;
254
+ const result = await transformJsxScriptTagsCode(code, {});
255
+ expect(result?.code).toEqual(undefined);
256
+ });
257
+ it("does not add nonce to script tags that already have nonce", async () => {
258
+ const code = `
259
+ jsx("script", {
260
+ type: "module",
261
+ children: "console.log('hello world')",
262
+ nonce: "existing-nonce"
263
+ })
264
+ `;
265
+ const result = await transformJsxScriptTagsCode(code, {});
266
+ expect(result?.code).toEqual(undefined);
267
+ });
268
+ it("uses existing requestInfo import if already present", async () => {
269
+ const code = `
270
+ import { foo } from 'bar';
271
+ import { requestInfo, someOtherThing } from "rwsdk/worker";
272
+
273
+ jsx("script", {
274
+ type: "module",
275
+ children: "console.log('hello world')"
276
+ })
277
+ `;
278
+ const result = await transformJsxScriptTagsCode(code, {});
279
+ expect(result?.code).toEqual(`
280
+ import { foo } from 'bar';
281
+ import { requestInfo, someOtherThing } from "rwsdk/worker";
282
+
283
+ jsx("script", {
284
+ type: "module",
285
+ children: "console.log('hello world')",
286
+ nonce: requestInfo.rw.nonce
287
+ })
288
+ `);
289
+ // Ensure we didn't duplicate the import
290
+ const importCount = (result?.code.match(/from "rwsdk\/worker"/g) || [])
291
+ .length;
292
+ expect(importCount).toBe(1);
293
+ });
294
+ it("adds requestInfo to existing SDK import if module already imported", async () => {
295
+ const code = `
296
+ import { foo } from 'bar';
297
+ import { someOtherThing } from "rwsdk/worker";
298
+
299
+ jsx("script", {
300
+ type: "module",
301
+ children: "console.log('hello world')"
302
+ })
303
+ `;
304
+ const result = await transformJsxScriptTagsCode(code, {});
305
+ expect(result?.code).toEqual(`
306
+ import { foo } from 'bar';
307
+ import { someOtherThing, requestInfo } from "rwsdk/worker";
308
+
309
+ jsx("script", {
310
+ type: "module",
311
+ children: "console.log('hello world')",
312
+ nonce: requestInfo.rw.nonce
313
+ })
314
+ `);
315
+ });
316
+ it("works in development mode without a manifest", async () => {
317
+ const code = `
318
+ jsx("script", {
319
+ src: "/src/client.tsx",
320
+ type: "module"
321
+ })
322
+ `;
323
+ // Call without providing manifest (simulating dev mode)
324
+ const result = await transformJsxScriptTagsCode(code);
325
+ expect(result?.code).toEqual(`import { requestInfo } from "rwsdk/worker";
326
+
327
+ jsx("script", {
328
+ src: "/src/client.tsx",
329
+ type: "module",
330
+ nonce: requestInfo.rw.nonce
331
+ })
332
+ `);
333
+ });
334
+ });
@@ -0,0 +1,16 @@
1
+ interface TransformResult {
2
+ code: string;
3
+ map?: any;
4
+ }
5
+ type ExportInfoCompat = {
6
+ localFunctions: Set<string>;
7
+ reExports: Array<{
8
+ localName: string;
9
+ originalName: string;
10
+ moduleSpecifier: string;
11
+ }>;
12
+ };
13
+ export declare const findExportedFunctions: (code: string, normalizedId?: string) => Set<string>;
14
+ export declare const findExportInfo: (code: string, normalizedId?: string) => ExportInfoCompat;
15
+ export declare const transformServerFunctions: (code: string, normalizedId: string, environment: "client" | "worker" | "ssr", serverFiles?: Set<string>, addServerModule?: (environment: string, id: string) => void) => TransformResult | undefined;
16
+ export type { TransformResult };