rnxsim 0.1.344 → 0.1.346

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 (211) hide show
  1. package/README.md +59 -31
  2. package/cli/app-fonts.ts +8 -28
  3. package/cli/app-project.ts +12 -184
  4. package/cli/app-splash.ts +3 -17
  5. package/cli/bin.ts +15 -28
  6. package/cli/commands/control.ts +20 -30
  7. package/cli/commands/daemon.ts +19 -44
  8. package/cli/commands/flow.ts +0 -27
  9. package/cli/commands/install-desktop.ts +2 -16
  10. package/cli/commands/login.ts +3 -43
  11. package/cli/commands/logout.ts +0 -7
  12. package/cli/commands/serve.ts +2 -32
  13. package/cli/commands/setup.ts +20 -194
  14. package/cli/commands/telemetry.ts +7 -5
  15. package/cli/commands/upload.ts +1 -48
  16. package/cli/commands/welcome.ts +64 -0
  17. package/cli/outbound-endpoints.ts +586 -0
  18. package/cli/privacy.ts +53 -0
  19. package/cli/runtime-notes.ts +2 -2
  20. package/cli/telemetry.ts +46 -149
  21. package/dist-cli/bin.js +6 -6
  22. package/dist-cli/chunks/{agent-HTSE5FA4.js → agent-U6HZUHAQ.js} +2 -2
  23. package/dist-cli/chunks/{agent-wrapper-L6X2AEZL.js → agent-wrapper-IM2VL6XP.js} +2 -2
  24. package/dist-cli/chunks/{app-fonts-FGF3ETYH.js → app-fonts-LHVTPWCN.js} +2 -2
  25. package/dist-cli/chunks/{assert-HA2ZYVDN.js → assert-UMGCZXWN.js} +2 -2
  26. package/dist-cli/chunks/{auth-HONDAV75.js → auth-PQY57FPY.js} +2 -2
  27. package/dist-cli/chunks/{beta-U7EE4GMR.js → beta-3MMNRHL7.js} +2 -2
  28. package/dist-cli/chunks/{camera-RTKNUTIX.js → camera-UKISEHMH.js} +2 -2
  29. package/dist-cli/chunks/{chunk-CNLPLCO2.js → chunk-36P343FE.js} +2 -2
  30. package/dist-cli/chunks/{chunk-IWR4HFC4.js → chunk-3KPJVR63.js} +2 -2
  31. package/dist-cli/chunks/chunk-54Y5IXWQ.js +15 -0
  32. package/dist-cli/chunks/{chunk-EPEZZ6YS.js → chunk-5KMV7NAJ.js} +2 -2
  33. package/dist-cli/chunks/{chunk-NDGAF5OF.js → chunk-5WIYZI5H.js} +2 -2
  34. package/dist-cli/chunks/{chunk-KBSVSAAE.js → chunk-6GXUQ3DM.js} +2 -2
  35. package/dist-cli/chunks/{chunk-KT6WMCUS.js → chunk-6MUEKKJ4.js} +1 -1
  36. package/dist-cli/chunks/{chunk-TOHQI2II.js → chunk-6Q6S53R7.js} +1 -1
  37. package/dist-cli/chunks/{chunk-63NZGJ4A.js → chunk-6SQCDLTJ.js} +1 -1
  38. package/dist-cli/chunks/{chunk-Q2B6EQPB.js → chunk-6UW6O575.js} +2 -2
  39. package/dist-cli/chunks/chunk-6VH3UUYQ.js +4 -0
  40. package/dist-cli/chunks/{chunk-BGLWR43R.js → chunk-6XJGGFMD.js} +1 -1
  41. package/dist-cli/chunks/{chunk-TZNRKIS3.js → chunk-75LMZXF5.js} +2 -2
  42. package/dist-cli/chunks/{chunk-FZ5DRZJE.js → chunk-7CJNUNQA.js} +3 -3
  43. package/dist-cli/chunks/{chunk-UCVQOQCY.js → chunk-BQDGFR4B.js} +2 -2
  44. package/dist-cli/chunks/{chunk-H4J7EWZC.js → chunk-BSIVS2SQ.js} +1 -1
  45. package/dist-cli/chunks/{chunk-6E6SBYIO.js → chunk-CD2LITQX.js} +1 -1
  46. package/dist-cli/chunks/{chunk-PNMCALX5.js → chunk-DGH3D6WS.js} +2 -2
  47. package/dist-cli/chunks/chunk-EP6XBKPM.js +11 -0
  48. package/dist-cli/chunks/{chunk-OCUXAA6O.js → chunk-EVX6Y7ZM.js} +2 -2
  49. package/dist-cli/chunks/chunk-EYRKIWHE.js +4 -0
  50. package/dist-cli/chunks/{chunk-N5PFDTFL.js → chunk-FSYB2S6Q.js} +17 -17
  51. package/dist-cli/chunks/{chunk-6PEZSVIG.js → chunk-HPCTBEAP.js} +1 -1
  52. package/dist-cli/chunks/chunk-HS2BME6V.js +6 -0
  53. package/dist-cli/chunks/{chunk-G6IPT2PS.js → chunk-I3GUDHG2.js} +2 -2
  54. package/dist-cli/chunks/{chunk-MWUXQIA3.js → chunk-I4HVFKLM.js} +2 -2
  55. package/dist-cli/chunks/{chunk-ZPTFL5FQ.js → chunk-IBNK7SWL.js} +2 -2
  56. package/dist-cli/chunks/chunk-IUG4GWQC.js +25 -0
  57. package/dist-cli/chunks/{chunk-XQFDEY3F.js → chunk-IUIKD2YI.js} +1 -1
  58. package/dist-cli/chunks/{chunk-JFUVWIJT.js → chunk-JPVXLY7X.js} +1 -1
  59. package/dist-cli/chunks/{chunk-JLUEQPEF.js → chunk-K4PZLT2K.js} +1 -1
  60. package/dist-cli/chunks/{chunk-CRWYKW67.js → chunk-KNIKUJPD.js} +1 -1
  61. package/dist-cli/chunks/{chunk-EZLLZDYX.js → chunk-L6GWDWGZ.js} +2 -2
  62. package/dist-cli/chunks/chunk-LAVDDUQR.js +4 -0
  63. package/dist-cli/chunks/{chunk-22WJPMTQ.js → chunk-LPXKPZ4B.js} +1 -1
  64. package/dist-cli/chunks/{chunk-IPC45HTT.js → chunk-LYLK5VRP.js} +2 -2
  65. package/dist-cli/chunks/{chunk-S6LBAUWH.js → chunk-ME46FC4L.js} +1 -1
  66. package/dist-cli/chunks/chunk-NNXSLD76.js +99 -0
  67. package/dist-cli/chunks/{chunk-7V4ULF3U.js → chunk-PNH3YBZ4.js} +2 -2
  68. package/dist-cli/chunks/{chunk-GRX6NSBG.js → chunk-PPEJMNRO.js} +2 -2
  69. package/dist-cli/chunks/{chunk-K3VNCCEJ.js → chunk-SEWGXJG6.js} +3 -3
  70. package/dist-cli/chunks/{chunk-R3UYHE6G.js → chunk-T4JPZI32.js} +1 -1
  71. package/dist-cli/chunks/{chunk-NRTHFEPM.js → chunk-TAQYETRH.js} +2 -2
  72. package/dist-cli/chunks/{chunk-7JEEO33Y.js → chunk-TBVBWJJL.js} +2 -2
  73. package/dist-cli/chunks/{chunk-HRBMD2FS.js → chunk-UA54YLWR.js} +26 -26
  74. package/dist-cli/chunks/{chunk-G3UAFZE2.js → chunk-UV3TXNMG.js} +1 -1
  75. package/dist-cli/chunks/{chunk-EH35QQG4.js → chunk-VZ6YFPIN.js} +45 -45
  76. package/dist-cli/chunks/chunk-W54SRZ5K.js +14 -0
  77. package/dist-cli/chunks/chunk-WAC75WN6.js +4 -0
  78. package/dist-cli/chunks/{chunk-S7CSBQ6G.js → chunk-X2WIEZ7Q.js} +1 -1
  79. package/dist-cli/chunks/{chunk-EN32LN2B.js → chunk-XWTYFWZ3.js} +2 -2
  80. package/dist-cli/chunks/chunk-Y2C3CZVD.js +4 -0
  81. package/dist-cli/chunks/chunk-YM4L2CFB.js +4 -0
  82. package/dist-cli/chunks/{chunk-ZZSBCGHC.js → chunk-YXDR4CAQ.js} +1 -1
  83. package/dist-cli/chunks/{chunk-6NLWKL7Y.js → chunk-Z6P427WC.js} +2 -2
  84. package/dist-cli/chunks/{cleanup-EMYD5WZG.js → cleanup-KXPS5VSK.js} +2 -2
  85. package/dist-cli/chunks/cli-version-LJ6NFLBP.js +4 -0
  86. package/dist-cli/chunks/{compat-W2N5QTVG.js → compat-JWF7N3VO.js} +2 -2
  87. package/dist-cli/chunks/config-M42VJXNK.js +13 -0
  88. package/dist-cli/chunks/{control-4SFBROUE.js → control-HMZDIS6P.js} +2 -2
  89. package/dist-cli/chunks/daemon-MQ4UYKNQ.js +4 -0
  90. package/dist-cli/chunks/{debug-HCR2KFUA.js → debug-F44GWYMF.js} +3 -3
  91. package/dist-cli/chunks/{desktop-T2KS5PBJ.js → desktop-YJMWW6MW.js} +3 -3
  92. package/dist-cli/chunks/{detox-5S7EHINH.js → detox-5B4ASTJO.js} +2 -2
  93. package/dist-cli/chunks/{device-LVM3MZRJ.js → device-2544YZNY.js} +2 -2
  94. package/dist-cli/chunks/{diagnose-WK37XKLI.js → diagnose-LS4245JR.js} +2 -2
  95. package/dist-cli/chunks/{disk-cleanup-X7VJOXMS.js → disk-cleanup-XYL2HQQY.js} +2 -2
  96. package/dist-cli/chunks/drivers-P5CRSKH6.js +4 -0
  97. package/dist-cli/chunks/{film-7KLTI3ER.js → film-LS3TIZRM.js} +3 -3
  98. package/dist-cli/chunks/flow-7V77GXAB.js +4 -0
  99. package/dist-cli/chunks/help-HRESIFZX.js +4 -0
  100. package/dist-cli/chunks/{hidden-runtime-alias-4RVGUVFO.js → hidden-runtime-alias-HGN2EEQR.js} +2 -2
  101. package/dist-cli/chunks/{home-paths-5DHSAEGZ.js → home-paths-T3NTXE4U.js} +2 -2
  102. package/dist-cli/chunks/inspect-UC44UH4M.js +4 -0
  103. package/dist-cli/chunks/install-desktop-RDV66JHG.js +4 -0
  104. package/dist-cli/chunks/login-WVP5H5NQ.js +26 -0
  105. package/dist-cli/chunks/logout-GXX5OY6X.js +4 -0
  106. package/dist-cli/chunks/{maestro-HTRLQDJE.js → maestro-MQMGBNOB.js} +3 -3
  107. package/dist-cli/chunks/{maestro-generate-GX2QNA3F.js → maestro-generate-CO355QV2.js} +3 -3
  108. package/dist-cli/chunks/{mode-GM6KZHQP.js → mode-QFB3M2AA.js} +2 -2
  109. package/dist-cli/chunks/{optional-demo-registry-B4TD7JQP.js → optional-demo-registry-UIPVSBHV.js} +2 -2
  110. package/dist-cli/chunks/{perf-3PRXJQIC.js → perf-TDOSW3LD.js} +2 -2
  111. package/dist-cli/chunks/{permissions-TJZIRF2S.js → permissions-TEVQLCGJ.js} +2 -2
  112. package/dist-cli/chunks/privacy-DVHAMHR6.js +4 -0
  113. package/dist-cli/chunks/{record-LI55DTPE.js → record-OFEQLSWA.js} +3 -3
  114. package/dist-cli/chunks/{report-issue-TBGJVQIQ.js → report-issue-B2UPOERJ.js} +2 -2
  115. package/dist-cli/chunks/reset-XQQYM55B.js +4 -0
  116. package/dist-cli/chunks/runtime-GN6HITVB.js +4 -0
  117. package/dist-cli/chunks/{screenshot-command-BEN7YYIF.js → screenshot-command-NTLAY7QN.js} +3 -3
  118. package/dist-cli/chunks/{screenshot-layers-3IU4KYNO.js → screenshot-layers-BBLKNRQU.js} +2 -2
  119. package/dist-cli/chunks/{screenshots-capture-ZRC54ST6.js → screenshots-capture-6GHIRCTG.js} +2 -2
  120. package/dist-cli/chunks/serve-H6GJ4OHW.js +118 -0
  121. package/dist-cli/chunks/setup-6YLKSMWS.js +30 -0
  122. package/dist-cli/chunks/{skills-GKBR2HQB.js → skills-FUL7D6C7.js} +2 -2
  123. package/dist-cli/chunks/{state-LIHZJSL7.js → state-O2HE7XSR.js} +2 -2
  124. package/dist-cli/chunks/{storage-4TPN3NFB.js → storage-WIZTF7RN.js} +4 -4
  125. package/dist-cli/chunks/store-NJ2MBZC2.js +4 -0
  126. package/dist-cli/chunks/telemetry-BEC6W5WP.js +4 -0
  127. package/dist-cli/chunks/{timeline-EX63UNWU.js → timeline-MA4JT7UJ.js} +2 -2
  128. package/dist-cli/chunks/{upgrade-O6Y6EINE.js → upgrade-H5LSDXBH.js} +2 -2
  129. package/dist-cli/chunks/upload-Q4DWKIA4.js +4 -0
  130. package/dist-cli/chunks/{version-HLNL3NFB.js → version-4UWEEDVP.js} +2 -2
  131. package/dist-cli/chunks/{web-4EDPYPW7.js → web-F3LXRN3K.js} +2 -2
  132. package/dist-cli/chunks/welcome-AZBOSIG2.js +5 -0
  133. package/dist-cli/chunks/{what-happened-77VNUEPK.js → what-happened-6OSNLOAY.js} +2 -2
  134. package/dist-lib/agent-daemon-client.cjs +1 -1
  135. package/dist-lib/agent-events.cjs +1 -1
  136. package/dist-lib/agent-identity.cjs +1 -1
  137. package/dist-lib/agent-sessions.cjs +1 -1
  138. package/dist-lib/attached-projects.cjs +1 -1
  139. package/dist-lib/auth/shared-session.cjs +1 -1
  140. package/dist-lib/backend-origin.cjs +13 -1
  141. package/dist-lib/beta.cjs +1 -1
  142. package/dist-lib/beta.mjs +1 -1
  143. package/dist-lib/bridge-constants.cjs +1 -1
  144. package/dist-lib/bridge-contract.cjs +1 -1
  145. package/dist-lib/cli-constants.cjs +1 -1
  146. package/dist-lib/config.cjs +1 -1
  147. package/dist-lib/detox/index.cjs +1 -1
  148. package/dist-lib/dev-bundle-resolution.cjs +43 -13
  149. package/dist-lib/home-paths.cjs +145 -11
  150. package/dist-lib/host/bridge-host.cjs +326 -78
  151. package/dist-lib/host/fetch-proxy-handler.cjs +1 -1
  152. package/dist-lib/host/fetch-proxy-overrides.cjs +1 -1
  153. package/dist-lib/host/fetch-proxy-overrides.mjs +1 -1
  154. package/dist-lib/host/replacement-module-handler.cjs +71 -4
  155. package/dist-lib/host/websocket-proxy.cjs +1 -1
  156. package/dist-lib/index.cjs +337 -37
  157. package/dist-lib/jump-to-source-babel.cjs +1 -1
  158. package/dist-lib/menu.cjs +1 -1
  159. package/dist-lib/menu.mjs +1 -1
  160. package/dist-lib/metro-production-bundle.cjs +1 -1
  161. package/dist-lib/metro-production-bundle.mjs +1 -1
  162. package/dist-lib/metro.cjs +484 -14
  163. package/dist-lib/profiles.cjs +1 -1
  164. package/dist-lib/public-brand.cjs +1 -1
  165. package/dist-lib/react-native-host-modules.cjs +1 -1
  166. package/dist-lib/react-native-host-modules.mjs +1 -1
  167. package/dist-lib/render-mode.cjs +1 -1
  168. package/dist-lib/scripts/dev-server-scanner.cjs +120 -50
  169. package/dist-lib/sdk.cjs +1 -1
  170. package/dist-lib/sdk.mjs +1 -1
  171. package/dist-lib/skills.cjs +493 -439
  172. package/dist-lib/vite.cjs +193 -37
  173. package/package.json +2 -1
  174. package/scripts/dev-server-scanner.ts +112 -51
  175. package/skills/rnx-test/SKILL.md +4 -0
  176. package/src/backend-origin.ts +15 -1
  177. package/src/dev-bundle-resolution.ts +42 -18
  178. package/src/dev-server-open.ts +197 -0
  179. package/src/home-paths.ts +168 -15
  180. package/src/host/bridge-host.ts +2 -2
  181. package/src/host/replacement-module-handler.ts +68 -2
  182. package/src/metro-plugin.ts +83 -5
  183. package/src/native-dev-bundle-url.ts +22 -0
  184. package/src/vite-plugin-one.ts +42 -28
  185. package/dist-cli/chunks/chunk-3JC7H4PR.js +0 -25
  186. package/dist-cli/chunks/chunk-6DLIC7BZ.js +0 -4
  187. package/dist-cli/chunks/chunk-7TNPO2OJ.js +0 -9
  188. package/dist-cli/chunks/chunk-AMF5KTOI.js +0 -4
  189. package/dist-cli/chunks/chunk-BX5VXTOQ.js +0 -101
  190. package/dist-cli/chunks/chunk-D73H7ACZ.js +0 -4
  191. package/dist-cli/chunks/chunk-DY4O7KYI.js +0 -4
  192. package/dist-cli/chunks/chunk-GU2V4JDG.js +0 -15
  193. package/dist-cli/chunks/chunk-POOCKX5B.js +0 -14
  194. package/dist-cli/chunks/chunk-Z2HMSVSN.js +0 -4
  195. package/dist-cli/chunks/cli-version-CN3NTKLH.js +0 -4
  196. package/dist-cli/chunks/config-SELKGT4F.js +0 -13
  197. package/dist-cli/chunks/daemon-V2SFCU2E.js +0 -4
  198. package/dist-cli/chunks/drivers-3YFTJ5WA.js +0 -4
  199. package/dist-cli/chunks/flow-36ANTMJU.js +0 -4
  200. package/dist-cli/chunks/help-ZGL26SPK.js +0 -4
  201. package/dist-cli/chunks/inspect-R3B55RTS.js +0 -4
  202. package/dist-cli/chunks/install-desktop-TZ3H3VWK.js +0 -4
  203. package/dist-cli/chunks/login-4DFULI7S.js +0 -28
  204. package/dist-cli/chunks/logout-QMCVYMBB.js +0 -4
  205. package/dist-cli/chunks/reset-O6MW6X7X.js +0 -4
  206. package/dist-cli/chunks/runtime-JESXBHRQ.js +0 -4
  207. package/dist-cli/chunks/serve-QGKTWPNF.js +0 -118
  208. package/dist-cli/chunks/setup-3WPWATCX.js +0 -32
  209. package/dist-cli/chunks/store-VBX3L46S.js +0 -4
  210. package/dist-cli/chunks/telemetry-ACNNIQIG.js +0 -4
  211. package/dist-cli/chunks/upload-OD2UQHMM.js +0 -4
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.344 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.346 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __create = Object.create;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.344 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.346 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __defProp = Object.defineProperty;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.344 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.346 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
 
3
3
  // src/host/fetch-proxy-overrides.ts
4
4
  var FETCH_PROXY_BROWSER_USER_AGENT = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/146.0.0.0 Safari/537.36";
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.344 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.346 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __create = Object.create;
@@ -41,6 +41,17 @@ module.exports = __toCommonJS(replacement_module_handler_exports);
41
41
  var import_promises = __toESM(require("node:fs/promises"), 1);
42
42
  var import_node_path = __toESM(require("node:path"), 1);
43
43
  var import_esbuild = require("esbuild");
44
+
45
+ // src/backend-origin.ts
46
+ function normalizeHostname(hostname) {
47
+ return hostname.replace(/^\[|\]$/g, "").toLowerCase();
48
+ }
49
+ function isLoopbackHost(hostname) {
50
+ const normalized = normalizeHostname(hostname);
51
+ return normalized === "localhost" || normalized.endsWith(".localhost") || normalized === "0.0.0.0" || normalized === "::1" || /^127(?:\.\d{1,3}){3}$/.test(normalized);
52
+ }
53
+
54
+ // src/host/replacement-module-handler.ts
44
55
  var REPLACEMENT_MODULE_ROUTE = "/__sootsim-replacement-module";
45
56
  var REPLACEMENT_RUNTIME_PREFIX = "/__sootsim-replacement-runtime";
46
57
  function getReplacementLoader(filePath) {
@@ -141,9 +152,18 @@ export const Appearance = rn.Appearance
141
152
  `;
142
153
  }
143
154
  function sendJavaScript(req, res, source) {
155
+ const origin = req.headers.origin;
156
+ let allowedOrigin;
157
+ if (origin) {
158
+ try {
159
+ if (isLoopbackHost(new URL(origin).hostname)) allowedOrigin = origin;
160
+ } catch {
161
+ }
162
+ }
144
163
  res.writeHead(200, {
145
164
  "Content-Type": "application/javascript; charset=utf-8",
146
- "Cache-Control": "no-cache"
165
+ "Cache-Control": "no-cache",
166
+ ...allowedOrigin ? { "Access-Control-Allow-Origin": allowedOrigin, Vary: "Origin" } : {}
147
167
  });
148
168
  res.end(req.method === "HEAD" ? void 0 : source);
149
169
  }
@@ -164,6 +184,23 @@ async function handleReplacementModuleRequest(req, res, options = {}) {
164
184
  } catch {
165
185
  return false;
166
186
  }
187
+ if (options.requireLoopbackOrigin) {
188
+ const origin = req.headers.origin;
189
+ const remoteAddress = req.socket.remoteAddress?.replace(/^::ffff:/, "");
190
+ let allowed = Boolean(remoteAddress && isLoopbackHost(remoteAddress));
191
+ if (allowed && origin) {
192
+ try {
193
+ allowed = isLoopbackHost(new URL(origin).hostname);
194
+ } catch {
195
+ allowed = false;
196
+ }
197
+ }
198
+ if (!allowed) {
199
+ res.writeHead(403, { "Content-Type": "text/plain; charset=utf-8" });
200
+ res.end("replacement modules are available only to loopback origins");
201
+ return true;
202
+ }
203
+ }
167
204
  if (url.pathname === `${REPLACEMENT_RUNTIME_PREFIX}/react`) {
168
205
  sendJavaScript(req, res, reactRuntimeSource(options.reactBridgeUrl));
169
206
  return true;
@@ -173,6 +210,11 @@ async function handleReplacementModuleRequest(req, res, options = {}) {
173
210
  return true;
174
211
  }
175
212
  if (url.pathname !== REPLACEMENT_MODULE_ROUTE) return false;
213
+ if (options.requestToken && url.searchParams.get("token") !== options.requestToken) {
214
+ res.writeHead(403, { "Content-Type": "text/plain; charset=utf-8" });
215
+ res.end("replacement module request token is invalid");
216
+ return true;
217
+ }
176
218
  const targetPath = url.searchParams.get("path");
177
219
  if (!targetPath) {
178
220
  res.writeHead(400, { "Content-Type": "text/plain; charset=utf-8" });
@@ -185,17 +227,42 @@ async function handleReplacementModuleRequest(req, res, options = {}) {
185
227
  res.end("replacement files must be .js, .jsx, .ts, or .tsx");
186
228
  return true;
187
229
  }
230
+ if (!import_node_path.default.isAbsolute(targetPath)) {
231
+ res.writeHead(400, { "Content-Type": "text/plain; charset=utf-8" });
232
+ res.end("replacement file path must be absolute");
233
+ return true;
234
+ }
235
+ let resolvedProjectRoot;
236
+ if (options.projectRoot) {
237
+ const lexicalProjectRoot = import_node_path.default.resolve(options.projectRoot);
238
+ resolvedProjectRoot = await import_promises.default.realpath(options.projectRoot);
239
+ const lexicalTarget = import_node_path.default.relative(lexicalProjectRoot, targetPath);
240
+ if (lexicalTarget.startsWith("..") || import_node_path.default.isAbsolute(lexicalTarget)) {
241
+ res.writeHead(403, { "Content-Type": "text/plain; charset=utf-8" });
242
+ res.end("replacement file must be inside the project root");
243
+ return true;
244
+ }
245
+ }
246
+ let resolvedTargetPath;
188
247
  try {
189
- await import_promises.default.access(targetPath);
248
+ resolvedTargetPath = await import_promises.default.realpath(targetPath);
190
249
  } catch (error) {
191
250
  const message = error instanceof Error ? error.message : String(error);
192
251
  res.writeHead(404, { "Content-Type": "text/plain; charset=utf-8" });
193
252
  res.end(`replacement file not found: ${message}`);
194
253
  return true;
195
254
  }
255
+ if (resolvedProjectRoot) {
256
+ const relativeTarget = import_node_path.default.relative(resolvedProjectRoot, resolvedTargetPath);
257
+ if (relativeTarget.startsWith("..") || import_node_path.default.isAbsolute(relativeTarget)) {
258
+ res.writeHead(403, { "Content-Type": "text/plain; charset=utf-8" });
259
+ res.end("replacement file must be inside the project root");
260
+ return true;
261
+ }
262
+ }
196
263
  try {
197
264
  const result = await (0, import_esbuild.build)({
198
- entryPoints: [targetPath],
265
+ entryPoints: [resolvedTargetPath],
199
266
  bundle: true,
200
267
  write: false,
201
268
  format: "esm",
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.344 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.346 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __defProp = Object.defineProperty;